diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 6e006423a..cc5ded896 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -5,7 +5,11 @@ "Bash(mkdir:*)", "Bash(./gradlew:*)", "Bash(grep:*)", - "Bash(cat:*)" + "Bash(cat:*)", + "Bash(find:*)", + "Bash(npm test)", + "Bash(npm test:*)", + "Bash(ls:*)" ], "deny": [] } diff --git a/.editorconfig b/.editorconfig index 3f5158dea..5b76408cc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -24,7 +24,7 @@ indent_size = 2 insert_final_newline = false trim_trailing_whitespace = false -[*.js] +[{*.js,*.jsx,*.ts,*.tsx}] indent_size = 2 [*.css] diff --git a/.github/workflows/PR-Auto-Deploy-V2.yml b/.github/workflows/PR-Auto-Deploy-V2.yml new file mode 100644 index 000000000..bd546078d --- /dev/null +++ b/.github/workflows/PR-Auto-Deploy-V2.yml @@ -0,0 +1,504 @@ +name: Auto PR V2 Deployment + +on: + pull_request: + types: [opened, synchronize, reopened, closed] + + +permissions: + contents: read + issues: write + pull-requests: write + +jobs: + check-pr: + if: github.event.action != 'closed' + runs-on: ubuntu-latest + outputs: + should_deploy: ${{ steps.check-conditions.outputs.should_deploy }} + pr_number: ${{ github.event.number }} + pr_repository: ${{ steps.get-pr-info.outputs.repository }} + pr_ref: ${{ steps.get-pr-info.outputs.ref }} + steps: + - name: Harden Runner + uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 + with: + egress-policy: audit + + - name: Check deployment conditions + id: check-conditions + env: + PR_TITLE: ${{ github.event.pull_request.title }} + PR_AUTHOR: ${{ github.event.pull_request.user.login }} + PR_BRANCH: ${{ github.event.pull_request.head.ref }} + run: | + echo "PR Title: $PR_TITLE" + echo "PR Author: $PR_AUTHOR" + echo "PR Branch: $PR_BRANCH" + echo "PR Base Branch: ${{ github.event.pull_request.base.ref }}" + + # Define authorized users + authorized_users=( + "Frooodle" + "sf298" + "Ludy87" + "LaserKaspar" + "sbplat" + "reecebrowne" + "DarioGii" + "ConnorYoh" + "EthanHealy01" + "jbrunton96" + ) + + # Check if author is in the authorized list + is_authorized=false + for user in "${authorized_users[@]}"; do + if [[ "$PR_AUTHOR" == "$user" ]]; then + is_authorized=true + break + fi + done + + # If PR is targeting V2 and user is authorized, deploy unconditionally + PR_BASE_BRANCH="${{ github.event.pull_request.base.ref }}" + if [[ "$PR_BASE_BRANCH" == "V2" && "$is_authorized" == "true" ]]; then + echo "āœ… Deployment forced: PR targets V2 and author is authorized." + echo "should_deploy=true" >> $GITHUB_OUTPUT + exit 0 + fi + + # Otherwise, continue with original keyword checks + has_v2_keyword=false + if [[ "$PR_TITLE" =~ [Vv]2 ]] || [[ "$PR_TITLE" =~ [Vv]ersion.?2 ]] || [[ "$PR_TITLE" =~ [Vv]ersion.?[Tt]wo ]]; then + has_v2_keyword=true + fi + + has_branch_keyword=false + if [[ "$PR_BRANCH" =~ [Vv]2 ]] || [[ "$PR_BRANCH" =~ [Rr]eact ]]; then + has_branch_keyword=true + fi + + if [[ "$is_authorized" == "true" && ( "$has_v2_keyword" == "true" || "$has_branch_keyword" == "true" ) ]]; then + echo "āœ… Deployment conditions met" + echo "should_deploy=true" >> $GITHUB_OUTPUT + else + echo "āŒ Deployment conditions not met" + echo " - Authorized user: $is_authorized" + echo " - Has V2 keyword in title: $has_v2_keyword" + echo " - Has V2/React keyword in branch: $has_branch_keyword" + echo "should_deploy=false" >> $GITHUB_OUTPUT + fi + + - name: Get PR repository and ref + id: get-pr-info + if: steps.check-conditions.outputs.should_deploy == 'true' + run: | + # For forks, use the full repository name, for internal PRs use the current repo + if [[ "${{ github.event.pull_request.head.repo.fork }}" == "true" ]]; then + repository="${{ github.event.pull_request.head.repo.full_name }}" + else + repository="${{ github.repository }}" + fi + + echo "repository=$repository" >> $GITHUB_OUTPUT + echo "ref=${{ github.event.pull_request.head.ref }}" >> $GITHUB_OUTPUT + + deploy-v2-pr: + needs: check-pr + runs-on: ubuntu-latest + if: needs.check-pr.outputs.should_deploy == 'true' + # Concurrency control - only one deployment per PR at a time + concurrency: + group: v2-deploy-pr-${{ needs.check-pr.outputs.pr_number }} + cancel-in-progress: true + permissions: + contents: read + issues: write + pull-requests: write + + steps: + - name: Harden Runner + uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 + with: + egress-policy: audit + + - name: Checkout main repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + repository: ${{ github.repository }} + ref: main + + - name: Setup GitHub App Bot + if: github.actor != 'dependabot[bot]' + id: setup-bot + uses: ./.github/actions/setup-bot + continue-on-error: true + with: + app-id: ${{ secrets.GH_APP_ID }} + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + + - name: Add deployment started comment + id: deployment-started + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + github-token: ${{ steps.setup-bot.outputs.token }} + script: | + const { owner, repo } = context.repo; + const prNumber = ${{ needs.check-pr.outputs.pr_number }}; + + // Delete previous V2 deployment comments to avoid clutter + const { data: comments } = await github.rest.issues.listComments({ + owner, + repo, + issue_number: prNumber, + per_page: 100 + }); + + const v2Comments = comments.filter(comment => + comment.body.includes('šŸš€ **Auto-deploying V2 version**') || + comment.body.includes('## šŸš€ V2 Auto-Deployment Complete!') || + comment.body.includes('āŒ **V2 Auto-deployment failed**') + ); + + for (const comment of v2Comments) { + console.log(`Deleting old V2 comment: ${comment.id}`); + await github.rest.issues.deleteComment({ + owner, + repo, + comment_id: comment.id + }); + } + + // Create new deployment started comment + const { data: newComment } = await github.rest.issues.createComment({ + owner, + repo, + issue_number: prNumber, + body: `šŸš€ **Auto-deploying V2 version** for PR #${prNumber}...\n\n_This is an automated deployment triggered by V2/version2 keywords in the PR title or V2/React keywords in the branch name._\n\nāš ļø **Note:** If new commits are pushed during deployment, this build will be cancelled and replaced with the latest version.` + }); + + return newComment.id; + + - name: Checkout PR + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + repository: ${{ needs.check-pr.outputs.pr_repository }} + ref: ${{ needs.check-pr.outputs.pr_ref }} + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 # Fetch full history for commit hash detection + + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Get version number + id: versionNumber + run: | + VERSION=$(grep "^version =" build.gradle | awk -F'"' '{print $2}') + echo "versionNumber=$VERSION" >> $GITHUB_OUTPUT + + - name: Login to Docker Hub + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_API }} + + - name: Get commit hashes for frontend and backend + id: commit-hashes + run: | + # Get last commit that touched the frontend folder, docker/frontend, or docker/compose + FRONTEND_HASH=$(git log -1 --format="%H" -- frontend/ docker/frontend/ docker/compose/ 2>/dev/null || echo "") + if [ -z "$FRONTEND_HASH" ]; then + FRONTEND_HASH="no-frontend-changes" + fi + + # Get last commit that touched backend code, docker/backend, or docker/compose + BACKEND_HASH=$(git log -1 --format="%H" -- app/ docker/backend/ docker/compose/ 2>/dev/null || echo "") + if [ -z "$BACKEND_HASH" ]; then + BACKEND_HASH="no-backend-changes" + fi + + echo "Frontend hash: $FRONTEND_HASH" + echo "Backend hash: $BACKEND_HASH" + + echo "frontend_hash=$FRONTEND_HASH" >> $GITHUB_OUTPUT + echo "backend_hash=$BACKEND_HASH" >> $GITHUB_OUTPUT + + # Short hashes for tags + if [ "$FRONTEND_HASH" = "no-frontend-changes" ]; then + echo "frontend_short=no-frontend" >> $GITHUB_OUTPUT + else + echo "frontend_short=${FRONTEND_HASH:0:8}" >> $GITHUB_OUTPUT + fi + + if [ "$BACKEND_HASH" = "no-backend-changes" ]; then + echo "backend_short=no-backend" >> $GITHUB_OUTPUT + else + echo "backend_short=${BACKEND_HASH:0:8}" >> $GITHUB_OUTPUT + fi + + - name: Check if frontend image exists + id: check-frontend + run: | + if docker manifest inspect ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-${{ steps.commit-hashes.outputs.frontend_short }} >/dev/null 2>&1; then + echo "exists=true" >> $GITHUB_OUTPUT + echo "Frontend image already exists, skipping build" + else + echo "exists=false" >> $GITHUB_OUTPUT + echo "Frontend image needs to be built" + fi + + - name: Check if backend image exists + id: check-backend + run: | + if docker manifest inspect ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-backend-${{ steps.commit-hashes.outputs.backend_short }} >/dev/null 2>&1; then + echo "exists=true" >> $GITHUB_OUTPUT + echo "Backend image already exists, skipping build" + else + echo "exists=false" >> $GITHUB_OUTPUT + echo "Backend image needs to be built" + fi + + - name: Build and push V2 frontend image + if: steps.check-frontend.outputs.exists == 'false' + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + file: ./docker/frontend/Dockerfile + push: true + tags: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-${{ steps.commit-hashes.outputs.frontend_short }} + build-args: VERSION_TAG=v2-alpha + platforms: linux/amd64 + + - name: Build and push V2 backend image + if: steps.check-backend.outputs.exists == 'false' + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + file: ./docker/backend/Dockerfile + push: true + tags: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-backend-${{ steps.commit-hashes.outputs.backend_short }} + build-args: VERSION_TAG=v2-alpha + platforms: linux/amd64 + + - name: Set up SSH + run: | + mkdir -p ~/.ssh/ + echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key + sudo chmod 600 ../private.key + + - name: Deploy V2 to VPS + id: deploy + run: | + # Use same port strategy as regular PRs - just the PR number + V2_PORT=${{ needs.check-pr.outputs.pr_number }} + BACKEND_PORT=$((V2_PORT + 10000)) # Backend on higher port to avoid conflicts + + # Create docker-compose for V2 with separate frontend and backend + cat > docker-compose.yml << EOF + version: '3.3' + services: + stirling-pdf-v2-backend: + container_name: stirling-pdf-v2-backend-pr-${{ needs.check-pr.outputs.pr_number }} + image: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-backend-${{ steps.commit-hashes.outputs.backend_short }} + ports: + - "${BACKEND_PORT}:8080" # Backend API port + volumes: + - /stirling/V2-PR-${{ needs.check-pr.outputs.pr_number }}/data:/usr/share/tessdata:rw + - /stirling/V2-PR-${{ needs.check-pr.outputs.pr_number }}/config:/configs:rw + - /stirling/V2-PR-${{ needs.check-pr.outputs.pr_number }}/logs:/logs:rw + environment: + DISABLE_ADDITIONAL_FEATURES: "true" + SECURITY_ENABLELOGIN: "false" + SYSTEM_DEFAULTLOCALE: en-GB + UI_APPNAME: "Stirling-PDF V2 PR#${{ needs.check-pr.outputs.pr_number }}" + UI_HOMEDESCRIPTION: "V2 PR#${{ needs.check-pr.outputs.pr_number }} - Frontend/Backend Split Architecture" + UI_APPNAMENAVBAR: "V2 PR#${{ needs.check-pr.outputs.pr_number }}" + SYSTEM_MAXFILESIZE: "100" + METRICS_ENABLED: "true" + SYSTEM_GOOGLEVISIBILITY: "false" + SWAGGER_SERVER_URL: "http://${{ secrets.VPS_HOST }}:${V2_PORT}" + restart: on-failure:5 + + stirling-pdf-v2-frontend: + container_name: stirling-pdf-v2-frontend-pr-${{ needs.check-pr.outputs.pr_number }} + image: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-${{ steps.commit-hashes.outputs.frontend_short }} + ports: + - "${V2_PORT}:80" # Frontend port (same as regular PRs) + environment: + VITE_API_BASE_URL: "http://${{ secrets.VPS_HOST }}:${BACKEND_PORT}" + depends_on: + - stirling-pdf-v2-backend + restart: on-failure:5 + EOF + + # Deploy to VPS + scp -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null docker-compose.yml ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }}:/tmp/docker-compose-v2.yml + + ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << ENDSSH + # Create V2 PR-specific directories + mkdir -p /stirling/V2-PR-${{ needs.check-pr.outputs.pr_number }}/{data,config,logs} + + # Move docker-compose file to correct location + mv /tmp/docker-compose-v2.yml /stirling/V2-PR-${{ needs.check-pr.outputs.pr_number }}/docker-compose.yml + + # Stop any existing container and clean up + cd /stirling/V2-PR-${{ needs.check-pr.outputs.pr_number }} + docker-compose down --remove-orphans 2>/dev/null || true + + # Start the new container + docker-compose pull + docker-compose up -d + + # Clean up unused Docker resources to save space + docker system prune -af --volumes || true + + # Clean up old backend/frontend images (older than 2 weeks) + docker image prune -af --filter "until=336h" --filter "label!=keep=true" || true + ENDSSH + + # Set port for output + echo "v2_port=${V2_PORT}" >> $GITHUB_OUTPUT + + - name: Post V2 deployment URL to PR + if: success() + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + github-token: ${{ steps.setup-bot.outputs.token }} + script: | + const { owner, repo } = context.repo; + const prNumber = ${{ needs.check-pr.outputs.pr_number }}; + const v2Port = ${{ steps.deploy.outputs.v2_port }}; + + // Delete the "deploying..." comment since we're posting the final result + const deploymentStartedId = ${{ steps.deployment-started.outputs.result }}; + if (deploymentStartedId) { + console.log(`Deleting deployment started comment: ${deploymentStartedId}`); + try { + await github.rest.issues.deleteComment({ + owner, + repo, + comment_id: deploymentStartedId + }); + } catch (error) { + console.log(`Could not delete deployment started comment: ${error.message}`); + } + } + + const deploymentUrl = `http://${{ secrets.VPS_HOST }}:${v2Port}`; + const httpsUrl = `https://${v2Port}.ssl.stirlingpdf.cloud`; + + const commentBody = `## šŸš€ V2 Auto-Deployment Complete!\n\n` + + `Your V2 PR with the new frontend/backend split architecture has been deployed!\n\n` + + `šŸ”— **Direct Test URL (non-SSL)** [${deploymentUrl}](${deploymentUrl})\n\n` + + `šŸ” **Secure HTTPS URL**: [${httpsUrl}](${httpsUrl})\n\n` + + `_This deployment will be automatically cleaned up when the PR is closed._\n\n` + + `šŸ”„ **Auto-deployed** because PR title or branch name contains V2/version2/React keywords.`; + + await github.rest.issues.createComment({ + owner, + repo, + issue_number: prNumber, + body: commentBody + }); + + cleanup-v2-deployment: + if: github.event.action == 'closed' + runs-on: ubuntu-latest + permissions: + contents: read + issues: write + pull-requests: write + + steps: + - name: Harden Runner + uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Setup GitHub App Bot + if: github.actor != 'dependabot[bot]' + id: setup-bot + uses: ./.github/actions/setup-bot + continue-on-error: true + with: + app-id: ${{ secrets.GH_APP_ID }} + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + + - name: Clean up V2 deployment comments + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + github-token: ${{ steps.setup-bot.outputs.token }} + script: | + const { owner, repo } = context.repo; + const prNumber = ${{ github.event.pull_request.number }}; + + // Find and delete V2 deployment comments + const { data: comments } = await github.rest.issues.listComments({ + owner, + repo, + issue_number: prNumber + }); + + const v2Comments = comments.filter(c => + c.body?.includes("## šŸš€ V2 Auto-Deployment Complete!") && + c.user?.type === "Bot" + ); + + for (const comment of v2Comments) { + await github.rest.issues.deleteComment({ + owner, + repo, + comment_id: comment.id + }); + console.log(`Deleted V2 deployment comment (ID: ${comment.id})`); + } + + - name: Set up SSH + run: | + mkdir -p ~/.ssh/ + echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key + sudo chmod 600 ../private.key + + - name: Cleanup V2 deployment + run: | + ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << 'ENDSSH' + if [ -d "/stirling/V2-PR-${{ github.event.pull_request.number }}" ]; then + echo "Found V2 PR directory, proceeding with cleanup..." + + # Stop and remove V2 containers + cd /stirling/V2-PR-${{ github.event.pull_request.number }} + docker-compose down || true + + # Go back to root before removal + cd / + + # Remove V2 PR-specific directories + rm -rf /stirling/V2-PR-${{ github.event.pull_request.number }} + + # Clean up V2 containers by name (in case compose cleanup missed them) + docker rm -f stirling-pdf-v2-frontend-pr-${{ github.event.pull_request.number }} || true + docker rm -f stirling-pdf-v2-backend-pr-${{ github.event.pull_request.number }} || true + + echo "V2 cleanup completed" + else + echo "V2 PR directory not found, nothing to clean up" + fi + + # Clean up old unused images (older than 2 weeks) but keep recent ones for reuse + docker image prune -af --filter "until=336h" --filter "label!=keep=true" || true + + # Note: We don't remove the commit-based images since they can be reused across PRs + # Only remove PR-specific containers and directories + ENDSSH + + - name: Cleanup temporary files + if: always() + run: | + rm -f ../private.key + continue-on-error: true + diff --git a/.github/workflows/PR-Demo-Comment-with-react.yml b/.github/workflows/PR-Demo-Comment-with-react.yml index 066d85ef2..a5530fced 100644 --- a/.github/workflows/PR-Demo-Comment-with-react.yml +++ b/.github/workflows/PR-Demo-Comment-with-react.yml @@ -29,6 +29,7 @@ jobs: github.event.comment.user.login == 'reecebrowne' || github.event.comment.user.login == 'DarioGii' || github.event.comment.user.login == 'EthanHealy01' || + github.event.comment.user.login == 'jbrunton96' || github.event.comment.user.login == 'ConnorYoh' ) outputs: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d87e478d3..2d28b669c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,11 +1,9 @@ name: Build and Test Workflow on: - workflow_dispatch: - # push: - # branches: ["main"] pull_request: - branches: ["main"] + branches: ["main", "V2", "V2-gha"] + workflow_dispatch: # cancel in-progress jobs if a new job is triggered # This is useful to avoid running multiple builds for the same branch if a new commit is pushed @@ -27,60 +25,56 @@ jobs: name: detect what files changed runs-on: ubuntu-latest timeout-minutes: 3 - # Map a step output to a job output outputs: build: ${{ steps.changes.outputs.build }} app: ${{ steps.changes.outputs.app }} project: ${{ steps.changes.outputs.project }} openapi: ${{ steps.changes.outputs.openapi }} steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Check for file changes - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + uses: dorny/paths-filter@v3.0.2 id: changes with: - filters: ".github/config/.files.yaml" + filters: .github/config/.files.yaml + build: runs-on: ubuntu-latest - permissions: actions: read security-events: write - strategy: fail-fast: false matrix: jdk-version: [17, 21] spring-security: [true, false] - steps: - name: Harden Runner +<<<<<<< HEAD uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 +======= + uses: step-security/harden-runner@v2.12.2 +>>>>>>> refs/remotes/origin/V2 with: egress-policy: audit - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - + uses: actions/checkout@v4.2.2 - name: Set up JDK ${{ matrix.jdk-version }} - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 + uses: actions/setup-java@v4.7.1 with: java-version: ${{ matrix.jdk-version }} distribution: "temurin" - - name: Setup Gradle - uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1 + uses: gradle/actions/setup-gradle@v4.4.1 with: gradle-version: 8.14 - - name: Build with Gradle and spring security ${{ matrix.spring-security }} - run: ./gradlew clean build + run: ./gradlew clean build -PnoSpotless env: DISABLE_ADDITIONAL_FEATURES: ${{ matrix.spring-security }} - - name: Check Test Reports Exist - id: check-reports if: always() run: | declare -a dirs=( @@ -91,98 +85,113 @@ jobs: "app/proprietary/build/reports/tests/" "app/proprietary/build/test-results/" ) - missing_reports=() for dir in "${dirs[@]}"; do if [ ! -d "$dir" ]; then - missing_reports+=("$dir") + echo "Missing $dir" + exit 1 fi done - if [ ${#missing_reports[@]} -gt 0 ]; then - echo "ERROR: The following required test report directories are missing:" - printf '%s\n' "${missing_reports[@]}" - exit 1 - fi - echo "All required test report directories are present" - - name: Upload Test Reports if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@v4.6.2 with: name: test-reports-jdk-${{ matrix.jdk-version }}-spring-security-${{ matrix.spring-security }} path: | - app/core/build/reports/tests/ - app/core/build/test-results/ - app/core/build/reports/problems/ - app/common/build/reports/tests/ - app/common/build/test-results/ - app/common/build/reports/problems/ - app/proprietary/build/reports/tests/ - app/proprietary/build/test-results/ - app/proprietary/build/reports/problems/ + app/**/build/reports/tests/ + app/**/build/test-results/ + app/**/build/reports/problems/ build/reports/problems/ retention-days: 3 if-no-files-found: warn check-generateOpenApiDocs: if: needs.files-changed.outputs.openapi == 'true' - needs: [files-changed, build] + needs: [files-changed] runs-on: ubuntu-latest steps: - name: Harden Runner +<<<<<<< HEAD uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 +======= + uses: step-security/harden-runner@v2.12.2 +>>>>>>> refs/remotes/origin/V2 with: egress-policy: audit - - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - + - uses: actions/checkout@v4.2.2 - name: Set up JDK 17 - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 + uses: actions/setup-java@v4.7.1 with: java-version: "17" distribution: "temurin" - - - name: Setup Gradle - uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1 - + - uses: gradle/actions/setup-gradle@v4.4.1 - name: Generate OpenAPI documentation run: ./gradlew :stirling-pdf:generateOpenApiDocs +<<<<<<< HEAD +======= +>>>>>>> refs/remotes/origin/V2 - name: Upload OpenAPI Documentation - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@v4.6.2 with: name: openapi-docs path: ./SwaggerDoc.json + frontend-validation: + runs-on: ubuntu-latest + steps: + - name: Harden Runner + uses: step-security/harden-runner@v2.12.2 + with: + egress-policy: audit + - name: Checkout repository + uses: actions/checkout@v4.2.2 + - name: Set up Node.js + uses: actions/setup-node@v4.1.0 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + - name: Install frontend dependencies + run: cd frontend && npm ci + - name: Build frontend + run: cd frontend && npm run build + - name: Run frontend tests + run: cd frontend && npm run test -- --run + - name: Upload frontend build artifacts + uses: actions/upload-artifact@v4.6.2 + with: + name: frontend-build + path: frontend/dist/ + retention-days: 3 + check-licence: if: needs.files-changed.outputs.build == 'true' needs: [files-changed, build] runs-on: ubuntu-latest steps: - name: Harden Runner +<<<<<<< HEAD uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 +======= + uses: step-security/harden-runner@v2.12.2 +>>>>>>> refs/remotes/origin/V2 with: egress-policy: audit - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - + uses: actions/checkout@v4.2.2 - name: Set up JDK 17 - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 + uses: actions/setup-java@v4.7.1 with: java-version: "17" distribution: "temurin" - - name: check the licenses for compatibility run: ./gradlew clean checkLicense - - name: FAILED - check the licenses for compatibility if: failure() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@v4.6.2 with: name: dependencies-without-allowed-license.json - path: | - build/reports/dependency-license/dependencies-without-allowed-license.json + path: build/reports/dependency-license/dependencies-without-allowed-license.json retention-days: 3 docker-compose-tests: @@ -244,6 +253,7 @@ jobs: chmod +x ./testing/test.sh chmod +x ./testing/test_disabledEndpoints.sh ./testing/test.sh +<<<<<<< HEAD test-build-docker-images: if: github.event_name == 'pull_request' && needs.files-changed.outputs.project == 'true' @@ -310,3 +320,5 @@ jobs: build/reports/problems/ retention-days: 3 if-no-files-found: warn +======= +>>>>>>> refs/remotes/origin/V2 diff --git a/.github/workflows/deploy-on-v2-commit.yml b/.github/workflows/deploy-on-v2-commit.yml new file mode 100644 index 000000000..941db40cf --- /dev/null +++ b/.github/workflows/deploy-on-v2-commit.yml @@ -0,0 +1,188 @@ +name: Auto V2 Deploy on Push + +on: + push: + branches: + - V2 + - deploy-on-v2-commit + +permissions: + contents: read + +jobs: + deploy-v2-on-push: + runs-on: ubuntu-latest + concurrency: + group: deploy-v2-push-V2 + cancel-in-progress: true + + steps: + - name: Harden Runner + uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1 + with: + egress-policy: audit + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Get commit hashes for frontend and backend + id: commit-hashes + run: | + # Get last commit that touched the frontend folder, docker/frontend, or docker/compose + FRONTEND_HASH=$(git log -1 --format="%H" -- frontend/ docker/frontend/ docker/compose/ 2>/dev/null || echo "") + if [ -z "$FRONTEND_HASH" ]; then + FRONTEND_HASH="no-frontend-changes" + fi + + # Get last commit that touched backend code, docker/backend, or docker/compose + BACKEND_HASH=$(git log -1 --format="%H" -- app/ docker/backend/ docker/compose/ 2>/dev/null || echo "") + if [ -z "$BACKEND_HASH" ]; then + BACKEND_HASH="no-backend-changes" + fi + + echo "Frontend hash: $FRONTEND_HASH" + echo "Backend hash: $BACKEND_HASH" + + echo "frontend_hash=$FRONTEND_HASH" >> $GITHUB_OUTPUT + echo "backend_hash=$BACKEND_HASH" >> $GITHUB_OUTPUT + + # Short hashes for tags + if [ "$FRONTEND_HASH" = "no-frontend-changes" ]; then + echo "frontend_short=no-frontend" >> $GITHUB_OUTPUT + else + echo "frontend_short=${FRONTEND_HASH:0:8}" >> $GITHUB_OUTPUT + fi + + if [ "$BACKEND_HASH" = "no-backend-changes" ]; then + echo "backend_short=no-backend" >> $GITHUB_OUTPUT + else + echo "backend_short=${BACKEND_HASH:0:8}" >> $GITHUB_OUTPUT + fi + + - name: Check if frontend image exists + id: check-frontend + run: | + if docker manifest inspect ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-${{ steps.commit-hashes.outputs.frontend_short }} >/dev/null 2>&1; then + echo "exists=true" >> $GITHUB_OUTPUT + echo "Frontend image already exists, skipping build" + else + echo "exists=false" >> $GITHUB_OUTPUT + echo "Frontend image needs to be built" + fi + + - name: Check if backend image exists + id: check-backend + run: | + if docker manifest inspect ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-backend-${{ steps.commit-hashes.outputs.backend_short }} >/dev/null 2>&1; then + echo "exists=true" >> $GITHUB_OUTPUT + echo "Backend image already exists, skipping build" + else + echo "exists=false" >> $GITHUB_OUTPUT + echo "Backend image needs to be built" + fi + + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_API }} + + - name: Build and push frontend image + if: steps.check-frontend.outputs.exists == 'false' + uses: docker/build-push-action@v6 + with: + context: . + file: ./docker/frontend/Dockerfile + push: true + tags: | + ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-${{ steps.commit-hashes.outputs.frontend_short }} + ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-latest + build-args: VERSION_TAG=v2-alpha + platforms: linux/amd64 + + - name: Build and push backend image + if: steps.check-backend.outputs.exists == 'false' + uses: docker/build-push-action@v6 + with: + context: . + file: ./docker/backend/Dockerfile + push: true + tags: | + ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-backend-${{ steps.commit-hashes.outputs.backend_short }} + ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-backend-latest + build-args: VERSION_TAG=v2-alpha + platforms: linux/amd64 + + + - name: Set up SSH + run: | + mkdir -p ~/.ssh/ + echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key + chmod 600 ../private.key + + + - name: Deploy to VPS on port 3000 + run: | + export UNIQUE_NAME=docker-compose-v2-$GITHUB_RUN_ID.yml + + cat > $UNIQUE_NAME << EOF + version: '3.3' + services: + backend: + container_name: stirling-v2-backend + image: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-backend-${{ steps.commit-hashes.outputs.backend_short }} + ports: + - "13000:8080" + volumes: + - /stirling/V2/data:/usr/share/tessdata:rw + - /stirling/V2/config:/configs:rw + - /stirling/V2/logs:/logs:rw + environment: + DISABLE_ADDITIONAL_FEATURES: "true" + SECURITY_ENABLELOGIN: "false" + SYSTEM_DEFAULTLOCALE: en-GB + UI_APPNAME: "Stirling-PDF V2" + UI_HOMEDESCRIPTION: "V2 Frontend/Backend Split" + UI_APPNAMENAVBAR: "V2 Deployment" + SYSTEM_MAXFILESIZE: "100" + METRICS_ENABLED: "true" + SYSTEM_GOOGLEVISIBILITY: "false" + SWAGGER_SERVER_URL: "http://${{ secrets.VPS_HOST }}:3000" + restart: on-failure:5 + + frontend: + container_name: stirling-v2-frontend + image: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-${{ steps.commit-hashes.outputs.frontend_short }} + ports: + - "3000:80" + environment: + VITE_API_BASE_URL: "http://${{ secrets.VPS_HOST }}:13000" + depends_on: + - backend + restart: on-failure:5 + EOF + + # Copy to remote with unique name + scp -i ../private.key -o StrictHostKeyChecking=no $UNIQUE_NAME ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }}:/tmp/$UNIQUE_NAME + + # SSH and rename/move atomically to avoid interference + ssh -i ../private.key -o StrictHostKeyChecking=no ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << ENDSSH + mkdir -p /stirling/V2/{data,config,logs} + mv /tmp/$UNIQUE_NAME /stirling/V2/docker-compose.yml + cd /stirling/V2 + docker-compose down || true + docker-compose pull + docker-compose up -d + docker system prune -af --volumes || true + docker image prune -af --filter "until=336h" --filter "label!=keep=true" || true + ENDSSH + + - name: Cleanup temporary files + if: always() + run: | + rm -f ../private.key + diff --git a/.github/workflows/frontend-licenses-update.yml b/.github/workflows/frontend-licenses-update.yml new file mode 100644 index 000000000..ac8676c8a --- /dev/null +++ b/.github/workflows/frontend-licenses-update.yml @@ -0,0 +1,217 @@ +name: Frontend License Report Workflow + +on: + push: + branches: + - V2 + paths: + - "frontend/package.json" + - "frontend/package-lock.json" + - "frontend/scripts/generate-licenses.js" + pull_request: + branches: + - V2 + paths: + - "frontend/package.json" + - "frontend/package-lock.json" + - "frontend/scripts/generate-licenses.js" + +permissions: + contents: read + +jobs: + generate-frontend-license-report: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + repository-projects: write # Required for enabling automerge + steps: + - name: Harden Runner + uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2 + with: + egress-policy: audit + + - name: Check out code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + + - name: Setup GitHub App Bot + id: setup-bot + uses: ./.github/actions/setup-bot + with: + app-id: ${{ secrets.GH_APP_ID }} + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + + - name: Set up Node.js + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: '18' + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + + - name: Install frontend dependencies + working-directory: frontend + run: npm ci + + - name: Generate frontend license report + working-directory: frontend + run: npm run generate-licenses + + - name: Check for license warnings + run: | + if [ -f "frontend/src/assets/license-warnings.json" ]; then + echo "LICENSE_WARNINGS_EXIST=true" >> $GITHUB_ENV + else + echo "LICENSE_WARNINGS_EXIST=false" >> $GITHUB_ENV + fi + + # PR Event: Check licenses and comment on PR + - name: Delete previous license check comments + if: github.event_name == 'pull_request' + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + github-token: ${{ steps.setup-bot.outputs.token }} + script: | + const { owner, repo } = context.repo; + const prNumber = context.issue.number; + + // Get all comments on the PR + const { data: comments } = await github.rest.issues.listComments({ + owner, + repo, + issue_number: prNumber, + per_page: 100 + }); + + // Filter for license check comments + const licenseComments = comments.filter(comment => + comment.body.includes('## āœ… Frontend License Check Passed') || + comment.body.includes('## āŒ Frontend License Check Failed') + ); + + // Delete old license check comments + for (const comment of licenseComments) { + console.log(`Deleting old license check comment: ${comment.id}`); + await github.rest.issues.deleteComment({ + owner, + repo, + comment_id: comment.id + }); + } + + - name: Comment on PR - License Check Results + if: github.event_name == 'pull_request' + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + github-token: ${{ steps.setup-bot.outputs.token }} + script: | + const { owner, repo } = context.repo; + const prNumber = context.issue.number; + const hasWarnings = process.env.LICENSE_WARNINGS_EXIST === 'true'; + + let commentBody; + + if (hasWarnings) { + // Read warnings file to get specific issues + const fs = require('fs'); + let warningDetails = ''; + try { + const warnings = JSON.parse(fs.readFileSync('frontend/src/assets/license-warnings.json', 'utf8')); + warningDetails = warnings.warnings.map(w => `- ${w.message}`).join('\n'); + } catch (e) { + warningDetails = 'Unable to read warning details'; + } + + commentBody = `## āŒ Frontend License Check Failed + + The frontend license check has detected compatibility warnings that require review: + + ${warningDetails} + + **Action Required:** Please review these licenses to ensure they are acceptable for your use case before merging. + + _This check will fail the PR until license issues are resolved._`; + } else { + commentBody = `## āœ… Frontend License Check Passed + + All frontend licenses have been validated and no compatibility warnings were detected. + + The frontend license report has been updated successfully.`; + } + + await github.rest.issues.createComment({ + owner, + repo, + issue_number: prNumber, + body: commentBody + }); + + - name: Fail workflow if license warnings exist (PR only) + if: github.event_name == 'pull_request' && env.LICENSE_WARNINGS_EXIST == 'true' + run: | + echo "āŒ License warnings detected. Failing the workflow." + exit 1 + + # Push Event: Commit license files and create PR + - name: Commit changes (Push only) + if: github.event_name == 'push' + run: | + git add frontend/src/assets/3rdPartyLicenses.json + # Note: Do NOT commit license-warnings.json - it's only for PR review + git diff --staged --quiet || echo "CHANGES_DETECTED=true" >> $GITHUB_ENV + + - name: Prepare PR body (Push only) + if: github.event_name == 'push' + run: | + PR_BODY="Auto-generated by ${{ steps.setup-bot.outputs.app-slug }}[bot] + + This PR updates the frontend license report based on changes to package.json dependencies." + + if [ "${{ env.LICENSE_WARNINGS_EXIST }}" = "true" ]; then + PR_BODY="$PR_BODY + + ## āš ļø License Compatibility Warnings + + The following licenses may require review for corporate compatibility: + + $(cat frontend/src/assets/license-warnings.json | jq -r '.warnings[].message') + + Please review these licenses to ensure they are acceptable for your use case." + fi + + echo "PR_BODY<> $GITHUB_ENV + echo "$PR_BODY" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - name: Create Pull Request (Push only) + id: cpr + if: github.event_name == 'push' && env.CHANGES_DETECTED == 'true' + uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 + with: + token: ${{ steps.setup-bot.outputs.token }} + commit-message: "Update Frontend 3rd Party Licenses" + committer: ${{ steps.setup-bot.outputs.committer }} + author: ${{ steps.setup-bot.outputs.committer }} + signoff: true + branch: update-frontend-3rd-party-licenses + base: V2 + title: "Update Frontend 3rd Party Licenses" + body: ${{ env.PR_BODY }} + labels: Licenses,github-actions,frontend + draft: false + delete-branch: true + sign-commits: true + + - name: Enable Pull Request Automerge (Push only) + if: github.event_name == 'push' && steps.cpr.outputs.pull-request-operation == 'created' && env.LICENSE_WARNINGS_EXIST == 'false' + run: gh pr merge --squash --auto "${{ steps.cpr.outputs.pull-request-number }}" + env: + GH_TOKEN: ${{ steps.setup-bot.outputs.token }} + + - name: Add review required label (Push only) + if: github.event_name == 'push' && steps.cpr.outputs.pull-request-operation == 'created' && env.LICENSE_WARNINGS_EXIST == 'true' + run: gh pr edit "${{ steps.cpr.outputs.pull-request-number }}" --add-label "license-review-required" + env: + GH_TOKEN: ${{ steps.setup-bot.outputs.token }} diff --git a/.gitignore b/.gitignore index 6ebd87c35..37df23f58 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ clientWebUI/ !cucumber/exampleFiles/ !cucumber/exampleFiles/example_html.zip exampleYmlFiles/stirling/ +/stirling/ /testing/file_snapshots SwaggerDoc.json @@ -196,6 +197,8 @@ id_ed25519.pub .pytest_cache .ipynb_checkpoints + + **/jcef-bundle/ # node_modules diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..be4e92201 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,224 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Common Development Commands + +### Build and Test +- **Build project**: `./gradlew clean build` +- **Run locally**: `./gradlew bootRun` +- **Full test suite**: `./test.sh` (builds all Docker variants and runs comprehensive tests) +- **Code formatting**: `./gradlew spotlessApply` (runs automatically before compilation) + +### Docker Development +- **Build ultra-lite**: `docker build -t stirlingtools/stirling-pdf:latest-ultra-lite -f ./Dockerfile.ultra-lite .` +- **Build standard**: `docker build -t stirlingtools/stirling-pdf:latest -f ./Dockerfile .` +- **Build fat version**: `docker build -t stirlingtools/stirling-pdf:latest-fat -f ./Dockerfile.fat .` +- **Example compose files**: Located in `exampleYmlFiles/` directory + +### Security Mode Development +Set `DOCKER_ENABLE_SECURITY=true` environment variable to enable security features during development. This is required for testing the full version locally. + +### Frontend Development +- **Frontend dev server**: `cd frontend && npm run dev` (requires backend on localhost:8080) +- **Tech Stack**: Vite + React + TypeScript + Mantine UI + TailwindCSS +- **Proxy Configuration**: Vite proxies `/api/*` calls to backend (localhost:8080) +- **Build Process**: DO NOT run build scripts manually - builds are handled by CI/CD pipelines +- **Package Installation**: DO NOT run npm install commands - package management handled separately +- **Deployment Options**: + - **Desktop App**: `npm run tauri-build` (native desktop application) + - **Web Server**: `npm run build` then serve dist/ folder + - **Development**: `npm run tauri-dev` for desktop dev mode + +#### Multi-Tool Workflow Architecture +Frontend designed for **stateful document processing**: +- Users upload PDFs once, then chain tools (split → merge → compress → view) +- File state and processing results persist across tool switches +- No file reloading between tools - performance critical for large PDFs (up to 100GB+) + +#### FileContext - Central State Management +**Location**: `src/contexts/FileContext.tsx` +- **Active files**: Currently loaded PDFs and their variants +- **Tool navigation**: Current mode (viewer/pageEditor/fileEditor/toolName) +- **Memory management**: PDF document cleanup, blob URL lifecycle, Web Worker management +- **IndexedDB persistence**: File storage with thumbnail caching +- **Preview system**: Tools can preview results (e.g., Split → Viewer → back to Split) without context pollution + +**Critical**: All file operations go through FileContext. Don't bypass with direct file handling. + +#### Processing Services +- **enhancedPDFProcessingService**: Background PDF parsing and manipulation +- **thumbnailGenerationService**: Web Worker-based with main-thread fallback +- **fileStorage**: IndexedDB with LRU cache management + +#### Memory Management Strategy +**Why manual cleanup exists**: Large PDFs (up to 100GB+) through multiple tools accumulate: +- PDF.js documents that need explicit .destroy() calls +- Blob URLs from tool outputs that need revocation +- Web Workers that need termination +Without cleanup: browser crashes with memory leaks. + +#### Tool Development + +**Architecture**: Modular hook-based system with clear separation of concerns: + +- **useToolOperation** (`frontend/src/hooks/tools/shared/useToolOperation.ts`): Main orchestrator hook + - Coordinates all tool operations with consistent interface + - Integrates with FileContext for operation tracking + - Handles validation, error handling, and UI state management + +- **Supporting Hooks**: + - **useToolState**: UI state management (loading, progress, error, files) + - **useToolApiCalls**: HTTP requests and file processing + - **useToolResources**: Blob URLs, thumbnails, ZIP downloads + +- **Utilities**: + - **toolErrorHandler**: Standardized error extraction and i18n support + - **toolResponseProcessor**: API response handling (single/zip/custom) + - **toolOperationTracker**: FileContext integration utilities + +**Three Tool Patterns**: + +**Pattern 1: Single-File Tools** (Individual processing) +- Backend processes one file per API call +- Set `multiFileEndpoint: false` +- Examples: Compress, Rotate +```typescript +return useToolOperation({ + operationType: 'compress', + endpoint: '/api/v1/misc/compress-pdf', + buildFormData: (params, file: File) => { /* single file */ }, + multiFileEndpoint: false, + filePrefix: 'compressed_' +}); +``` + +**Pattern 2: Multi-File Tools** (Batch processing) +- Backend accepts `MultipartFile[]` arrays in single API call +- Set `multiFileEndpoint: true` +- Examples: Split, Merge, Overlay +```typescript +return useToolOperation({ + operationType: 'split', + endpoint: '/api/v1/general/split-pages', + buildFormData: (params, files: File[]) => { /* all files */ }, + multiFileEndpoint: true, + filePrefix: 'split_' +}); +``` + +**Pattern 3: Complex Tools** (Custom processing) +- Tools with complex routing logic or non-standard processing +- Provide `customProcessor` for full control +- Examples: Convert, OCR +```typescript +return useToolOperation({ + operationType: 'convert', + customProcessor: async (params, files) => { /* custom logic */ }, + filePrefix: 'converted_' +}); +``` + +**Benefits**: +- **No Timeouts**: Operations run until completion (supports 100GB+ files) +- **Consistent**: All tools follow same pattern and interface +- **Maintainable**: Single responsibility hooks, easy to test and modify +- **i18n Ready**: Built-in internationalization support +- **Type Safe**: Full TypeScript support with generic interfaces +- **Memory Safe**: Automatic resource cleanup and blob URL management + +## Architecture Overview + +### Project Structure +- **Backend**: Spring Boot application with Thymeleaf templating +- **Frontend**: React-based SPA in `/frontend` directory (Thymeleaf templates fully replaced) + - **File Storage**: IndexedDB for client-side file persistence and thumbnails + - **Internationalization**: JSON-based translations (converted from backend .properties) +- **PDF Processing**: PDFBox for core PDF operations, LibreOffice for conversions, PDF.js for client-side rendering +- **Security**: Spring Security with optional authentication (controlled by `DOCKER_ENABLE_SECURITY`) +- **Configuration**: YAML-based configuration with environment variable overrides + +### Controller Architecture +- **API Controllers** (`src/main/java/.../controller/api/`): REST endpoints for PDF operations + - Organized by function: converters, security, misc, pipeline + - Follow pattern: `@RestController` + `@RequestMapping("/api/v1/...")` +- **Web Controllers** (`src/main/java/.../controller/web/`): Serve Thymeleaf templates + - Pattern: `@Controller` + return template names + +### Key Components +- **SPDFApplication.java**: Main application class with desktop UI and browser launching logic +- **ConfigInitializer**: Handles runtime configuration and settings files +- **Pipeline System**: Automated PDF processing workflows via `PipelineController` +- **Security Layer**: Authentication, authorization, and user management (when enabled) + +### Component Architecture +- **React Components**: Located in `frontend/src/components/` and `frontend/src/tools/` +- **Static Assets**: CSS, JS, and resources in `src/main/resources/static/` (legacy) + `frontend/public/` (modern) +- **Internationalization**: + - Backend: `messages_*.properties` files + - Frontend: JSON files in `frontend/public/locales/` (converted from .properties) + - Conversion Script: `scripts/convert_properties_to_json.py` + +### Configuration Modes +- **Ultra-lite**: Basic PDF operations only +- **Standard**: Full feature set +- **Fat**: Pre-downloaded dependencies for air-gapped environments +- **Security Mode**: Adds authentication, user management, and enterprise features + +### Testing Strategy +- **Integration Tests**: Cucumber tests in `testing/cucumber/` +- **Docker Testing**: `test.sh` validates all Docker variants +- **Manual Testing**: No unit tests currently - relies on UI and API testing + +## Development Workflow + +1. **Local Development**: + - Backend: `./gradlew bootRun` (runs on localhost:8080) + - Frontend: `cd frontend && npm run dev` (runs on localhost:5173, proxies to backend) +2. **Docker Testing**: Use `./test.sh` before submitting PRs +3. **Code Style**: Spotless enforces Google Java Format automatically +4. **Translations**: + - Backend: Use helper scripts in `/scripts` for multi-language updates + - Frontend: Update JSON files in `frontend/public/locales/` or use conversion script +5. **Documentation**: API docs auto-generated and available at `/swagger-ui/index.html` + +## Frontend Architecture Status + +- **Core Status**: React SPA architecture complete with multi-tool workflow support +- **State Management**: FileContext handles all file operations and tool navigation +- **File Processing**: Production-ready with memory management for large PDF workflows (up to 100GB+) +- **Tool Integration**: Modular hook architecture with `useToolOperation` orchestrator + - Individual hooks: `useToolState`, `useToolApiCalls`, `useToolResources` + - Utilities: `toolErrorHandler`, `toolResponseProcessor`, `toolOperationTracker` + - Pattern: Each tool creates focused operation hook, UI consumes state/actions +- **Preview System**: Tool results can be previewed without polluting file context (Split tool example) +- **Performance**: Web Worker thumbnails, IndexedDB persistence, background processing + +## Important Notes + +- **Java Version**: Minimum JDK 17, supports and recommends JDK 21 +- **Lombok**: Used extensively - ensure IDE plugin is installed +- **Desktop Mode**: Set `STIRLING_PDF_DESKTOP_UI=true` for desktop application mode +- **File Persistence**: + - **Backend**: Designed to be stateless - files are processed in memory/temp locations only + - **Frontend**: Uses IndexedDB for client-side file storage and caching (with thumbnails) +- **Security**: When `DOCKER_ENABLE_SECURITY=false`, security-related classes are excluded from compilation +- **FileContext**: All file operations MUST go through FileContext - never bypass with direct File handling +- **Memory Management**: Manual cleanup required for PDF.js documents and blob URLs - don't remove cleanup code +- **Tool Development**: New tools should follow `useToolOperation` hook pattern (see `useCompressOperation.ts`) +- **Performance Target**: Must handle PDFs up to 100GB+ without browser crashes +- **Preview System**: Tools can preview results without polluting main file context (see Split tool implementation) + +## Communication Style +- Be direct and to the point +- No apologies or conversational filler +- Answer questions directly without preamble +- Explain reasoning concisely when asked +- Avoid unnecessary elaboration + +## Decision Making +- Ask clarifying questions before making assumptions +- Stop and ask when uncertain about project-specific details +- Confirm approach before making structural changes +- Request guidance on preferences (cross-platform vs specific tools, etc.) +- Verify understanding of requirements before proceeding diff --git a/DeveloperGuide.md b/DeveloperGuide.md new file mode 100644 index 000000000..0728a1cdc --- /dev/null +++ b/DeveloperGuide.md @@ -0,0 +1,692 @@ +# Stirling-PDF Developer Guide + +## 1. Introduction + +Stirling-PDF is a robust, locally hosted, web-based PDF manipulation tool. **Stirling 2.0** represents a complete frontend rewrite, replacing the legacy Thymeleaf-based UI with a modern React SPA (Single Page Application). + +This guide focuses on developing for Stirling 2.0, including both the React frontend and Spring Boot backend development workflows. + +## 2. Project Overview + +**Stirling 2.0** is built using: + +**Backend:** +- Spring Boot (Java 17+, JDK 21 recommended) +- PDFBox for core PDF operations +- LibreOffice for document conversions +- qpdf for PDF optimization +- Spring Security (optional, controlled by `DOCKER_ENABLE_SECURITY`) +- Lombok for reducing boilerplate code + +**Frontend (React SPA):** +- React + TypeScript +- Vite for build tooling and development server +- Mantine UI component library +- TailwindCSS for styling +- PDF.js for client-side PDF rendering +- PDF-LIB.js for client-side PDF manipulation +- IndexedDB for client-side file storage and thumbnails +- i18next for internationalization + +**Infrastructure:** +- Docker for containerization +- Gradle for build management + +**Legacy (reference only during development):** +- Thymeleaf templates (being completely replaced in 2.0) + +## 3. Development Environment Setup + +### Prerequisites + +- Docker +- Git +- Java JDK 17 or later (JDK 21 recommended) +- Node.js 18+ and npm (required for frontend development) +- Gradle 7.0 or later (Included within the repo) + +### Setup Steps + +1. Clone the repository: + + ```bash + git clone https://github.com/Stirling-Tools/Stirling-PDF.git + cd Stirling-PDF + ``` + +2. Install Docker and JDK17 if not already installed. + +3. Install a recommended Java IDE such as Eclipse, IntelliJ, or VSCode + 1. Only VSCode + 1. Open VS Code. + 2. When prompted, install the recommended extensions. + 3. Alternatively, open the command palette (`Ctrl + Shift + P` or `Cmd + Shift + P` on macOS) and run: + + ```sh + Extensions: Show Recommended Extensions + ``` + + 4. Install the required extensions from the list. + +4. Lombok Setup +Stirling-PDF uses Lombok to reduce boilerplate code. Some IDEs, like Eclipse, don't support Lombok out of the box. To set up Lombok in your development environment: +Visit the [Lombok website](https://projectlombok.org/setup/) for installation instructions specific to your IDE. + +5. Add environment variable +For local testing, you should generally be testing the full 'Security' version of Stirling PDF. To do this, you must add the environment flag DISABLE_ADDITIONAL_FEATURES=false to your system and/or IDE build/run step. +5. **Frontend Setup (Required for Stirling 2.0)** + Navigate to the frontend directory and install dependencies using npm. + +## 4. Stirling 2.0 Development Workflow + +### Frontend Development (React) +The frontend is a React SPA that runs independently during development: + +1. **Start the backend**: Run the Spring Boot application (serves API endpoints on localhost:8080) +2. **Start the frontend dev server**: Navigate to the frontend directory and run the development server (serves UI on localhost:5173) +3. **Development flow**: The Vite dev server automatically proxies API calls to the backend + +### File Storage Architecture +Stirling 2.0 uses client-side file storage: +- **IndexedDB**: Stores files locally in the browser with automatic thumbnail generation +- **PDF.js**: Handles client-side PDF rendering and processing +- **URL Parameters**: Support for deep linking and tool state persistence + +### Legacy Code Reference +The existing Thymeleaf templates remain in the codebase during development as reference material but will be completely removed for the 2.0 release. + +## 5. Project Structure + +```bash +Stirling-PDF/ +ā”œā”€ā”€ .github/ # GitHub-specific files (workflows, issue templates) +ā”œā”€ā”€ configs/ # Configuration files used by stirling at runtime (generated at runtime) +ā”œā”€ā”€ frontend/ # React SPA frontend (Stirling 2.0) +│ ā”œā”€ā”€ src/ +│ │ ā”œā”€ā”€ components/ # React components +│ │ ā”œā”€ā”€ tools/ # Tool-specific React components +│ │ ā”œā”€ā”€ hooks/ # Custom React hooks +│ │ ā”œā”€ā”€ services/ # API and utility services +│ │ ā”œā”€ā”€ types/ # TypeScript type definitions +│ │ └── utils/ # Utility functions +│ ā”œā”€ā”€ public/ +│ │ └── locales/ # Internationalization files (JSON) +│ ā”œā”€ā”€ package.json # Frontend dependencies +│ └── vite.config.ts # Vite configuration +ā”œā”€ā”€ customFiles/ # Custom static files and templates (generated at runtime used to replace existing files) +ā”œā”€ā”€ docs/ # Documentation files +ā”œā”€ā”€ exampleYmlFiles/ # Example YAML configuration files +ā”œā”€ā”€ images/ # Image assets +ā”œā”€ā”€ pipeline/ # Pipeline-related files (generated at runtime) +ā”œā”€ā”€ scripts/ # Utility scripts +ā”œā”€ā”€ src/ # Source code +│ ā”œā”€ā”€ main/ +│ │ ā”œā”€ā”€ java/ +│ │ │ └── stirling/ +│ │ │ └── software/ +│ │ │ └── SPDF/ +│ │ │ ā”œā”€ā”€ config/ +│ │ │ ā”œā”€ā”€ controller/ +│ │ │ ā”œā”€ā”€ model/ +│ │ │ ā”œā”€ā”€ repository/ +│ │ │ ā”œā”€ā”€ service/ +│ │ │ └── utils/ +│ │ └── resources/ +│ │ ā”œā”€ā”€ static/ # Legacy static assets (reference only) +│ │ │ ā”œā”€ā”€ css/ +│ │ │ ā”œā”€ā”€ js/ +│ │ │ └── pdfjs/ +│ │ └── templates/ # Legacy Thymeleaf templates (reference only) +│ └── test/ +ā”œā”€ā”€ testing/ # Cucumber and integration tests +│ └── cucumber/ # Cucumber test files +ā”œā”€ā”€ build.gradle # Gradle build configuration +ā”œā”€ā”€ Dockerfile # Main Dockerfile +ā”œā”€ā”€ Dockerfile.ultra-lite # Dockerfile for ultra-lite version +ā”œā”€ā”€ Dockerfile.fat # Dockerfile for fat version +ā”œā”€ā”€ docker-compose.yml # Docker Compose configuration +└── test.sh # Test script to deploy all docker versions and run cuke tests +``` + +## 6. Docker-based Development + +Stirling-PDF offers several Docker versions: + +- Full: All features included +- Ultra-Lite: Basic PDF operations only +- Fat: Includes additional libraries and fonts predownloaded + +### Example Docker Compose Files + +Stirling-PDF provides several example Docker Compose files in the `exampleYmlFiles` directory, such as: + +- `docker-compose-latest.yml`: Latest version without login and security features +- `docker-compose-latest-security.yml`: Latest version with login and security features enabled +- `docker-compose-latest-fat-security.yml`: Fat version with login and security features enabled + +These files provide pre-configured setups for different scenarios. For example, here's a snippet from `docker-compose-latest-security.yml`: + +```yaml +services: + stirling-pdf: + container_name: Stirling-PDF-Security + image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest + deploy: + resources: + limits: + memory: 4G + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -q 'Please sign in'"] + interval: 5s + timeout: 10s + retries: 16 + ports: + - "8080:8080" + volumes: + - ./stirling/latest/data:/usr/share/tessdata:rw + - ./stirling/latest/config:/configs:rw + - ./stirling/latest/logs:/logs:rw + environment: + DISABLE_ADDITIONAL_FEATURES: "false" + SECURITY_ENABLELOGIN: "true" + PUID: 1002 + PGID: 1002 + UMASK: "022" + SYSTEM_DEFAULTLOCALE: en-US + UI_APPNAME: Stirling-PDF + UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest with Security + UI_APPNAMENAVBAR: Stirling-PDF Latest + SYSTEM_MAXFILESIZE: "100" + METRICS_ENABLED: "true" + SYSTEM_GOOGLEVISIBILITY: "true" + SHOW_SURVEY: "true" + restart: on-failure:5 +``` + +To use these example files, copy the desired file to your project root and rename it to `docker-compose.yml`, or specify the file explicitly when running Docker Compose: + +```bash +docker-compose -f exampleYmlFiles/docker-compose-latest-security.yml up +``` + +### Building Docker Images + +Stirling-PDF uses different Docker images for various configurations. The build process is controlled by environment variables and uses specific Dockerfile variants. Here's how to build the Docker images: + +1. Set the security environment variable: + + ```bash + export DISABLE_ADDITIONAL_FEATURES=true # or false for to enable login and security features for builds + ``` + +2. Build the project with Gradle: + + ```bash + ./gradlew clean build + ``` + +3. Build the Docker images: + + For the latest version: + + ```bash + docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t stirlingtools/stirling-pdf:latest -f ./Dockerfile . + ``` + + For the ultra-lite version: + + ```bash + docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t stirlingtools/stirling-pdf:latest-ultra-lite -f ./Dockerfile.ultra-lite . + ``` + + For the fat version (with login and security features enabled): + + ```bash + export DISABLE_ADDITIONAL_FEATURES=false + docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t stirlingtools/stirling-pdf:latest-fat -f ./Dockerfile.fat . + ``` + +Note: The `--no-cache` and `--pull` flags ensure that the build process uses the latest base images and doesn't use cached layers, which is useful for testing and ensuring reproducible builds. however to improve build times these can often be removed depending on your usecase + +## 7. Testing + +### Comprehensive Testing Script + +Stirling-PDF provides a `test.sh` script in the root directory. This script builds all versions of Stirling-PDF, checks that each version works, and runs Cucumber tests. It's recommended to run this script before submitting a final pull request. + +To run the test script: + +```bash +./test.sh +``` + +This script performs the following actions: + +1. Builds all Docker images (full, ultra-lite, fat). +2. Runs each version to ensure it starts correctly. +3. Executes Cucumber tests against the main version and ensures feature compatibility. In the event these tests fail, your PR will not be merged. + +Note: The `test.sh` script will run automatically when you raise a PR. However, it's recommended to run it locally first to save resources and catch any issues early. + +### Full Testing with Docker + +1. Build and run the Docker container per the above instructions: + +2. Access the application at `http://localhost:8080` and manually test all features developed. + +### Frontend Development Testing (Stirling 2.0) + +For React frontend development: + +1. Start the backend: Run the Spring Boot application to serve API endpoints on localhost:8080 +2. Start the frontend dev server: Navigate to the frontend directory and run the development server on localhost:5173 +3. The Vite dev server automatically proxies API calls to the backend +4. Test React components, UI interactions, and IndexedDB file operations using browser developer tools + +### Local Testing (Java and UI Components) + +For quick iterations and development of Java backend, JavaScript, and UI components, you can run and test Stirling-PDF locally without Docker. This approach allows you to work on and verify changes to: + +- Java backend logic +- RESTful API endpoints +- JavaScript functionality +- User interface components and styling +- Thymeleaf templates + +To run Stirling-PDF locally: + +1. Compile and run the project using built-in IDE methods or by running: + + ```bash + ./gradlew bootRun + ``` + +2. Access the application at `http://localhost:8080` in your web browser. + +3. Manually test the features you're working on through the UI. + +4. For API changes, use tools like Postman or curl to test endpoints directly. + +Important notes: + +- Local testing doesn't include features that depend on external tools like qpdf, LibreOffice, or Python scripts. +- There are currently no automated unit tests. All testing is done manually through the UI or API calls. (You are welcome to add JUnits!) +- Always verify your changes in the full Docker environment before submitting pull requests, as some integrations and features will only work in the complete setup. + +## 8. Contributing + +1. Fork the repository on GitHub. +2. Create a new branch for your feature or bug fix. +3. Make your changes and commit them with clear, descriptive messages and ensure any documentation is updated related to your changes. +4. Test your changes thoroughly in the Docker environment. +5. Run the `test.sh` script to ensure all versions build correctly and pass the Cucumber tests: + + ```bash + ./test.sh + ``` + +6. Push your changes to your fork. +7. Submit a pull request to the main repository. +8. See additional [contributing guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md). + +When you raise a PR: + +- The `test.sh` script will run automatically against your PR. +- The PR checks will verify versioning and dependency updates. +- Documentation will be automatically updated for dependency changes. +- Security issues will be checked using Snyk and PixeeBot. + +Address any issues that arise from these checks before finalizing your pull request. + +## 9. API Documentation + +API documentation is available at `/swagger-ui/index.html` when running the application. You can also view the latest API documentation [here](https://app.swaggerhub.com/apis-docs/Stirling-Tools/Stirling-PDF/). + +## 10. Customization + +Stirling-PDF can be customized through environment variables or a `settings.yml` file. Key customization options include: + +- Application name and branding +- Security settings +- UI customization +- Endpoint management + +When using Docker, pass environment variables using the `-e` flag or in your `docker-compose.yml` file. + +Example: + +```bash +docker run -p 8080:8080 -e APP_NAME="My PDF Tool" stirling-pdf:full +``` + +Refer to the main README for a full list of customization options. + +## 11. Language Translations + +For managing language translations that affect multiple files, Stirling-PDF provides a helper script: + +```bash +/scripts/replace_translation_line.sh +``` + +This script helps you make consistent replacements across language files. + +When contributing translations: + +1. Use the helper script for multi-file changes. +2. Ensure all language files are updated consistently. +3. The PR checks will verify consistency in language file updates. + +Remember to test your changes thoroughly to ensure they don't break any existing functionality. + +## Code examples + +### React Component Development (Stirling 2.0) + +For Stirling 2.0, new features are built as React components instead of Thymeleaf templates: + +#### Creating a New Tool Component + +1. **Create the React Component:** + ```typescript + // frontend/src/tools/NewTool.tsx + import { useState } from 'react'; + import { Button, FileInput, Container } from '@mantine/core'; + + interface NewToolProps { + params: Record; + updateParams: (updates: Record) => void; + } + + export default function NewTool({ params, updateParams }: NewToolProps) { + const [files, setFiles] = useState([]); + + const handleProcess = async () => { + // Process files using API or client-side logic + }; + + return ( + + + + + ); + } + ``` + +2. **Add API Integration:** + ```typescript + // Use existing API endpoints or create new ones + const response = await fetch('/api/v1/new-tool', { + method: 'POST', + body: formData + }); + ``` + +3. **Register in Tool Picker:** + Update the tool picker component to include the new tool with proper routing and URL parameter support. + +### Legacy Reference: Overview of Thymeleaf + +Thymeleaf is a server-side Java HTML template engine. It is used in Stirling-PDF to render dynamic web pages. Thymeleaf integrates heavily with Spring Boot. + +### Thymeleaf overview + +In Stirling-PDF, Thymeleaf is used to create HTML templates that are rendered on the server side. These templates are located in the `stirling-pdf/src/main/resources/templates` directory. Thymeleaf templates use a combination of HTML and special Thymeleaf attributes to dynamically generate content. + +Some examples of this are: + +```html + +``` +or +```html + +``` + +Where it uses the `th:block`, `th:` indicating it's a special Thymeleaf element to be used server-side in generating the HTML, and block being the actual element type. +In this case, we are inserting the `navbar` entry within the `fragments/navbar.html` fragment into the `th:block` element. + +They can be more complex, such as: + +```html + +``` + +Which is the same as above but passes the parameters title and header into the fragment `common.html` to be used in its HTML generation. + +Thymeleaf can also be used to loop through objects or pass things from the Java side into the HTML side. + +```java + @GetMapping + public String newFeaturePage(Model model) { + model.addAttribute("exampleData", exampleData); + return "new-feature"; + } +``` + +In the above example, if exampleData is a list of plain java objects of class Person and within it, you had id, name, age, etc. You can reference it like so + +```html + + + + + + + + + +``` + +This would generate n entries of tr for each person in exampleData + +### Adding a New Feature to the Backend (API) + +1. **Create a New Controller:** + - Create a new Java class in the `stirling-pdf/src/main/java/stirling/software/SPDF/controller/api` directory. + - Annotate the class with `@RestController` and `@RequestMapping` to define the API endpoint. + - Ensure to add API documentation annotations like `@Tag(name = "General", description = "General APIs")` and `@Operation(summary = "Crops a PDF document", description = "This operation takes an input PDF file and crops it according to the given coordinates. Input:PDF Output:PDF Type:SISO")`. + + ```java + package stirling.software.SPDF.controller.api; + + import org.springframework.web.bind.annotation.GetMapping; + import org.springframework.web.bind.annotation.RequestMapping; + import org.springframework.web.bind.annotation.RestController; + import io.swagger.v3.oas.annotations.Operation; + import io.swagger.v3.oas.annotations.tags.Tag; + + @RestController + @RequestMapping("/api/v1/new-feature") + @Tag(name = "General", description = "General APIs") + public class NewFeatureController { + + @GetMapping + @Operation(summary = "New Feature", description = "This is a new feature endpoint.") + public String newFeature() { + return "NewFeatureResponse"; // This refers to the NewFeatureResponse.html template presenting the user with the generated html from that file when they navigate to /api/v1/new-feature + } + } + ``` + +2. **Define the Service Layer:** (Not required but often useful) + - Create a new service class in the `stirling-pdf/src/main/java/stirling/software/SPDF/service` directory. + - Implement the business logic for the new feature. + + ```java + package stirling.software.SPDF.service; + + import org.springframework.stereotype.Service; + + @Service + public class NewFeatureService { + + public String getNewFeatureData() { + // Implement business logic here + return "New Feature Data"; + } + } + ``` + +2b. **Integrate the Service with the Controller:** + +- Autowire the service class in the controller and use it to handle the API request. + + ```java + package stirling.software.SPDF.controller.api; + + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.web.bind.annotation.GetMapping; + import org.springframework.web.bind.annotation.RequestMapping; + import org.springframework.web.bind.annotation.RestController; + import stirling.software.SPDF.service.NewFeatureService; + import io.swagger.v3.oas.annotations.Operation; + import io.swagger.v3.oas.annotations.tags.Tag; + + @RestController + @RequestMapping("/api/v1/new-feature") + @Tag(name = "General", description = "General APIs") + public class NewFeatureController { + + @Autowired + private NewFeatureService newFeatureService; + + @GetMapping + @Operation(summary = "New Feature", description = "This is a new feature endpoint.") + public String newFeature() { + return newFeatureService.getNewFeatureData(); + } + } + ``` + +### Adding a New Feature to the Frontend (UI) + +1. **Create a New Thymeleaf Template:** + - Create a new HTML file in the `stirling-pdf/src/main/resources/templates` directory. + - Use Thymeleaf attributes to dynamically generate content. + - Use `extract-page.html` as a base example for the HTML template, which is useful to ensure importing of the general layout, navbar, and footer. + + ```html + + + + + + + +
+
+ +

+
+
+
+
+ upload + +
+
+
+ +
+ + +
+ + +
+
+
+
+
+ +
+ + + ``` + +2. **Create a New Controller for the UI:** + - Create a new Java class in the `stirling-pdf/src/main/java/stirling/software/SPDF/controller/ui` directory. + - Annotate the class with `@Controller` and `@RequestMapping` to define the UI endpoint. + + ```java + package stirling.software.SPDF.controller.ui; + + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.stereotype.Controller; + import org.springframework.ui.Model; + import org.springframework.web.bind.annotation.GetMapping; + import org.springframework.web.bind.annotation.RequestMapping; + import stirling.software.SPDF.service.NewFeatureService; + + @Controller + @RequestMapping("/new-feature") + public class NewFeatureUIController { + + @Autowired + private NewFeatureService newFeatureService; + + @GetMapping + public String newFeaturePage(Model model) { + model.addAttribute("newFeatureData", newFeatureService.getNewFeatureData()); + return "new-feature"; + } + } + ``` + +3. **Update the Navigation Bar:** + - Add a link to the new feature page in the navigation bar. + - Update the `stirling-pdf/src/main/resources/templates/fragments/navbar.html` file. + + ```html + + ``` + +## Adding New Translations to Existing Language Files in Stirling-PDF + +When adding a new feature or modifying existing ones in Stirling-PDF, you'll need to add new translation entries to the existing language files. Here's a step-by-step guide: + +### 1. Locate Existing Language Files + +Find the existing `messages.properties` files in the `stirling-pdf/src/main/resources` directory. You'll see files like: + +- `messages.properties` (default, usually English) +- `messages_en_GB.properties` +- `messages_fr_FR.properties` +- `messages_de_DE.properties` +- etc. + +### 2. Add New Translation Entries + +Open each of these files and add your new translation entries. For example, if you're adding a new feature called "PDF Splitter", +Use descriptive, hierarchical keys (e.g., `feature.element.description`) +you might add: + +```properties +pdfSplitter.title=PDF Splitter +pdfSplitter.description=Split your PDF into multiple documents +pdfSplitter.button.split=Split PDF +pdfSplitter.input.pages=Enter page numbers to split +``` + +Add these entries to the default GB language file and any others you wish, translating the values as appropriate for each language. + +### 3. Use Translations in Thymeleaf Templates + +In your Thymeleaf templates, use the `#{key}` syntax to reference the new translations: + +```html +

PDF Splitter

+

Split your PDF into multiple documents

+ + +``` + +Remember, never hard-code text in your templates or Java code. Always use translation keys to ensure proper localization. diff --git a/app/core/src/main/java/stirling/software/SPDF/config/CleanUrlInterceptor.java b/app/core/src/main/java/stirling/software/SPDF/config/CleanUrlInterceptor.java index d37d4bfb6..c33b86948 100644 --- a/app/core/src/main/java/stirling/software/SPDF/config/CleanUrlInterceptor.java +++ b/app/core/src/main/java/stirling/software/SPDF/config/CleanUrlInterceptor.java @@ -45,6 +45,7 @@ public class CleanUrlInterceptor implements HandlerInterceptor { String queryString = request.getQueryString(); if (queryString != null && !queryString.isEmpty()) { + Map allowedParameters = new HashMap<>(); // Keep only the allowed parameters diff --git a/app/core/src/main/java/stirling/software/SPDF/config/OpenApiConfig.java b/app/core/src/main/java/stirling/software/SPDF/config/OpenApiConfig.java index 78d2a3d2b..1a5635baa 100644 --- a/app/core/src/main/java/stirling/software/SPDF/config/OpenApiConfig.java +++ b/app/core/src/main/java/stirling/software/SPDF/config/OpenApiConfig.java @@ -10,6 +10,7 @@ import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.servers.Server; import lombok.RequiredArgsConstructor; @@ -50,17 +51,26 @@ public class OpenApiConfig { .url("https://www.stirlingpdf.com") .email("contact@stirlingpdf.com")) .description(DEFAULT_DESCRIPTION); + + OpenAPI openAPI = new OpenAPI().info(info); + + // Add server configuration from environment variable + String swaggerServerUrl = System.getenv("SWAGGER_SERVER_URL"); + if (swaggerServerUrl != null && !swaggerServerUrl.trim().isEmpty()) { + Server server = new Server().url(swaggerServerUrl).description("API Server"); + openAPI.addServersItem(server); + } + if (!applicationProperties.getSecurity().getEnableLogin()) { - return new OpenAPI().components(new Components()).info(info); + return openAPI.components(new Components()); } else { SecurityScheme apiKeyScheme = new SecurityScheme() .type(SecurityScheme.Type.APIKEY) .in(SecurityScheme.In.HEADER) .name("X-API-KEY"); - return new OpenAPI() + return openAPI .components(new Components().addSecuritySchemes("apiKey", apiKeyScheme)) - .info(info) .addSecurityItem(new SecurityRequirement().addList("apiKey")); } } diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/AnalysisController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/AnalysisController.java index b6419890a..27fff75d2 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/AnalysisController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/AnalysisController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import java.util.*; @@ -29,7 +31,7 @@ public class AnalysisController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(value = "/page-count", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/page-count", consumes = "multipart/form-data") @Operation( summary = "Get PDF page count", description = "Returns total number of pages in PDF. Input:PDF Output:JSON Type:SISO") @@ -39,7 +41,7 @@ public class AnalysisController { } } - @PostMapping(value = "/basic-info", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/basic-info", consumes = "multipart/form-data") @Operation( summary = "Get basic PDF information", description = "Returns page count, version, file size. Input:PDF Output:JSON Type:SISO") @@ -53,7 +55,7 @@ public class AnalysisController { } } - @PostMapping(value = "/document-properties", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/document-properties", consumes = "multipart/form-data") @Operation( summary = "Get PDF document properties", description = "Returns title, author, subject, etc. Input:PDF Output:JSON Type:SISO") @@ -76,7 +78,7 @@ public class AnalysisController { } } - @PostMapping(value = "/page-dimensions", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/page-dimensions", consumes = "multipart/form-data") @Operation( summary = "Get page dimensions for all pages", description = "Returns width and height of each page. Input:PDF Output:JSON Type:SISO") @@ -96,7 +98,7 @@ public class AnalysisController { } } - @PostMapping(value = "/form-fields", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/form-fields", consumes = "multipart/form-data") @Operation( summary = "Get form field information", description = @@ -119,7 +121,7 @@ public class AnalysisController { } } - @PostMapping(value = "/annotation-info", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/annotation-info", consumes = "multipart/form-data") @Operation( summary = "Get annotation information", description = "Returns count and types of annotations. Input:PDF Output:JSON Type:SISO") @@ -143,7 +145,7 @@ public class AnalysisController { } } - @PostMapping(value = "/font-info", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/font-info", consumes = "multipart/form-data") @Operation( summary = "Get font information", description = @@ -165,7 +167,7 @@ public class AnalysisController { } } - @PostMapping(value = "/security-info", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/security-info", consumes = "multipart/form-data") @Operation( summary = "Get security information", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/CropController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/CropController.java index 3a2d16757..f47bd0d0c 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/CropController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/CropController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -33,7 +35,7 @@ public class CropController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(value = "/crop", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/crop", consumes = "multipart/form-data") @Operation( summary = "Crops a PDF document", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/EditTableOfContentsController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/EditTableOfContentsController.java index 6a30e6bb3..2f823695e 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/EditTableOfContentsController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/EditTableOfContentsController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.util.ArrayList; import java.util.HashMap; @@ -44,7 +46,7 @@ public class EditTableOfContentsController { private final CustomPDFDocumentFactory pdfDocumentFactory; private final ObjectMapper objectMapper; - @PostMapping(value = "/extract-bookmarks", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/extract-bookmarks", consumes = "multipart/form-data") @Operation( summary = "Extract PDF Bookmarks", description = "Extracts bookmarks/table of contents from a PDF document as JSON.") @@ -152,7 +154,7 @@ public class EditTableOfContentsController { return bookmark; } - @PostMapping(value = "/edit-table-of-contents", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/edit-table-of-contents", consumes = "multipart/form-data") @Operation( summary = "Edit Table of Contents", description = "Add or edit bookmarks/table of contents in a PDF document.") diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/MergeController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/MergeController.java index 4e05392c8..538b82a90 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/MergeController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/MergeController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -154,7 +156,7 @@ public class MergeController { } } - @PostMapping(consumes = "multipart/form-data", value = "/merge-pdfs") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/merge-pdfs") @Operation( summary = "Merge multiple PDF files into one", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/MultiPageLayoutController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/MultiPageLayoutController.java index c57e3a6c0..d07b5314e 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/MultiPageLayoutController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/MultiPageLayoutController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.*; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -36,7 +38,7 @@ public class MultiPageLayoutController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(value = "/multi-page-layout", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/multi-page-layout", consumes = "multipart/form-data") @Operation( summary = "Merge multiple pages of a PDF document into a single page", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/PdfImageRemovalController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/PdfImageRemovalController.java index d6602351e..5c262ecc6 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/PdfImageRemovalController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/PdfImageRemovalController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -46,7 +48,7 @@ public class PdfImageRemovalController { * content type and filename. * @throws IOException If an error occurs while processing the PDF file. */ - @PostMapping(consumes = "multipart/form-data", value = "/remove-image-pdf") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/remove-image-pdf") @Operation( summary = "Remove images from file to reduce the file size.", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/PdfOverlayController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/PdfOverlayController.java index e6fc2c561..4f90ddac0 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/PdfOverlayController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/PdfOverlayController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -39,7 +41,7 @@ public class PdfOverlayController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(value = "/overlay-pdfs", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/overlay-pdfs", consumes = "multipart/form-data") @Operation( summary = "Overlay PDF files in various modes", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/RearrangePagesPDFController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/RearrangePagesPDFController.java index 717c85016..6254183b0 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/RearrangePagesPDFController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/RearrangePagesPDFController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -38,7 +40,7 @@ public class RearrangePagesPDFController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/remove-pages") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/remove-pages") @Operation( summary = "Remove pages from a PDF file", description = @@ -237,7 +239,7 @@ public class RearrangePagesPDFController { } } - @PostMapping(consumes = "multipart/form-data", value = "/rearrange-pages") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/rearrange-pages") @Operation( summary = "Rearrange pages in a PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/RotationController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/RotationController.java index 58b502cfa..e5a8ae90c 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/RotationController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/RotationController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; @@ -31,7 +33,7 @@ public class RotationController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/rotate-pdf") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/rotate-pdf") @Operation( summary = "Rotate a PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/ScalePagesController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/ScalePagesController.java index 56f6f77fa..abc4c4e46 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/ScalePagesController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/ScalePagesController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.HashMap; @@ -38,7 +40,7 @@ public class ScalePagesController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(value = "/scale-pages", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/scale-pages", consumes = "multipart/form-data") @Operation( summary = "Change the size of a PDF page/document", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/SettingsController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/SettingsController.java index 0e9cd96dc..efa77b54a 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/SettingsController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/SettingsController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import java.util.Map; @@ -31,7 +33,7 @@ public class SettingsController { private final ApplicationProperties applicationProperties; private final EndpointConfiguration endpointConfiguration; - @PostMapping("/update-enable-analytics") + @AutoJobPostMapping("/update-enable-analytics") @Hidden public ResponseEntity updateApiKey(@RequestBody Boolean enabled) throws IOException { if (applicationProperties.getSystem().getEnableAnalytics() != null) { diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPDFController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPDFController.java index f2425ac9a..32691b2d0 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPDFController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPDFController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.Files; @@ -41,7 +43,7 @@ public class SplitPDFController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/split-pages") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/split-pages") @Operation( summary = "Split a PDF file into separate documents", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfByChaptersController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfByChaptersController.java index f0f9fb012..a30b208c9 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfByChaptersController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfByChaptersController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.nio.file.Files; import java.nio.file.Path; @@ -117,7 +119,7 @@ public class SplitPdfByChaptersController { return bookmarks; } - @PostMapping(value = "/split-pdf-by-chapters", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/split-pdf-by-chapters", consumes = "multipart/form-data") @Operation( summary = "Split PDFs by Chapters", description = "Splits a PDF into chapters and returns a ZIP file.") diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySectionsController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySectionsController.java index c2bbd31b5..a27d7f1b9 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySectionsController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySectionsController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.Files; @@ -43,7 +45,7 @@ public class SplitPdfBySectionsController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(value = "/split-pdf-by-sections", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/split-pdf-by-sections", consumes = "multipart/form-data") @Operation( summary = "Split PDF pages into smaller sections", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySizeController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySizeController.java index 0dbbd933c..adfe42b46 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySizeController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySizeController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.Files; @@ -39,7 +41,7 @@ public class SplitPdfBySizeController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(value = "/split-by-size-or-count", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/split-by-size-or-count", consumes = "multipart/form-data") @Operation( summary = "Auto split PDF pages into separate documents based on size or count", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/ToSinglePageController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/ToSinglePageController.java index 104a0f351..e52f1bfef 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/ToSinglePageController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/ToSinglePageController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.geom.AffineTransform; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -33,7 +35,7 @@ public class ToSinglePageController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/pdf-to-single-page") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf-to-single-page") @Operation( summary = "Convert a multi-page PDF into a single long page PDF", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/UIDataController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/UIDataController.java new file mode 100644 index 000000000..3161560ae --- /dev/null +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/UIDataController.java @@ -0,0 +1,301 @@ +package stirling.software.SPDF.controller.api; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Stream; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; + +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import stirling.software.SPDF.model.Dependency; +import stirling.software.SPDF.model.SignatureFile; +import stirling.software.SPDF.service.SignatureService; +import stirling.software.common.configuration.InstallationPathConfig; +import stirling.software.common.configuration.RuntimePathConfig; +import stirling.software.common.model.ApplicationProperties; +import stirling.software.common.service.UserServiceInterface; +import stirling.software.common.util.ExceptionUtils; +import stirling.software.common.util.GeneralUtils; + +@Slf4j +@RestController +@RequestMapping("/api/v1/ui-data") +@Tag(name = "UI Data", description = "APIs for React UI data") +public class UIDataController { + + private final ApplicationProperties applicationProperties; + private final SignatureService signatureService; + private final UserServiceInterface userService; + private final ResourceLoader resourceLoader; + private final RuntimePathConfig runtimePathConfig; + + public UIDataController( + ApplicationProperties applicationProperties, + SignatureService signatureService, + @Autowired(required = false) UserServiceInterface userService, + ResourceLoader resourceLoader, + RuntimePathConfig runtimePathConfig) { + this.applicationProperties = applicationProperties; + this.signatureService = signatureService; + this.userService = userService; + this.resourceLoader = resourceLoader; + this.runtimePathConfig = runtimePathConfig; + } + + @GetMapping("/home") + @Operation(summary = "Get home page data") + public ResponseEntity getHomeData() { + String showSurvey = System.getenv("SHOW_SURVEY"); + boolean showSurveyValue = showSurvey == null || "true".equalsIgnoreCase(showSurvey); + + HomeData data = new HomeData(); + data.setShowSurveyFromDocker(showSurveyValue); + + return ResponseEntity.ok(data); + } + + @GetMapping("/licenses") + @Operation(summary = "Get third-party licenses data") + public ResponseEntity getLicensesData() { + LicensesData data = new LicensesData(); + Resource resource = new ClassPathResource("static/3rdPartyLicenses.json"); + + try { + InputStream is = resource.getInputStream(); + String json = new String(is.readAllBytes(), StandardCharsets.UTF_8); + ObjectMapper mapper = new ObjectMapper(); + Map> licenseData = + mapper.readValue(json, new TypeReference<>() {}); + data.setDependencies(licenseData.get("dependencies")); + } catch (IOException e) { + log.error("Failed to load licenses data", e); + data.setDependencies(Collections.emptyList()); + } + + return ResponseEntity.ok(data); + } + + @GetMapping("/pipeline") + @Operation(summary = "Get pipeline configuration data") + public ResponseEntity getPipelineData() { + PipelineData data = new PipelineData(); + List pipelineConfigs = new ArrayList<>(); + List> pipelineConfigsWithNames = new ArrayList<>(); + + if (new java.io.File(runtimePathConfig.getPipelineDefaultWebUiConfigs()).exists()) { + try (Stream paths = + Files.walk(Paths.get(runtimePathConfig.getPipelineDefaultWebUiConfigs()))) { + List jsonFiles = + paths.filter(Files::isRegularFile) + .filter(p -> p.toString().endsWith(".json")) + .toList(); + + for (Path jsonFile : jsonFiles) { + String content = Files.readString(jsonFile, StandardCharsets.UTF_8); + pipelineConfigs.add(content); + } + + for (String config : pipelineConfigs) { + Map jsonContent = + new ObjectMapper() + .readValue(config, new TypeReference>() {}); + String name = (String) jsonContent.get("name"); + if (name == null || name.length() < 1) { + String filename = + jsonFiles + .get(pipelineConfigs.indexOf(config)) + .getFileName() + .toString(); + name = filename.substring(0, filename.lastIndexOf('.')); + } + Map configWithName = new HashMap<>(); + configWithName.put("json", config); + configWithName.put("name", name); + pipelineConfigsWithNames.add(configWithName); + } + } catch (IOException e) { + log.error("Failed to load pipeline configs", e); + } + } + + if (pipelineConfigsWithNames.isEmpty()) { + Map configWithName = new HashMap<>(); + configWithName.put("json", ""); + configWithName.put("name", "No preloaded configs found"); + pipelineConfigsWithNames.add(configWithName); + } + + data.setPipelineConfigsWithNames(pipelineConfigsWithNames); + data.setPipelineConfigs(pipelineConfigs); + + return ResponseEntity.ok(data); + } + + @GetMapping("/sign") + @Operation(summary = "Get signature form data") + public ResponseEntity getSignData() { + String username = ""; + if (userService != null) { + username = userService.getCurrentUsername(); + } + + List signatures = signatureService.getAvailableSignatures(username); + List fonts = getFontNames(); + + SignData data = new SignData(); + data.setSignatures(signatures); + data.setFonts(fonts); + + return ResponseEntity.ok(data); + } + + @GetMapping("/ocr-pdf") + @Operation(summary = "Get OCR PDF data") + public ResponseEntity getOcrPdfData() { + List languages = getAvailableTesseractLanguages(); + + OcrData data = new OcrData(); + data.setLanguages(languages); + + return ResponseEntity.ok(data); + } + + private List getAvailableTesseractLanguages() { + String tessdataDir = applicationProperties.getSystem().getTessdataDir(); + java.io.File[] files = new java.io.File(tessdataDir).listFiles(); + if (files == null) { + return Collections.emptyList(); + } + return Arrays.stream(files) + .filter(file -> file.getName().endsWith(".traineddata")) + .map(file -> file.getName().replace(".traineddata", "")) + .filter(lang -> !"osd".equalsIgnoreCase(lang)) + .sorted() + .toList(); + } + + private List getFontNames() { + List fontNames = new ArrayList<>(); + fontNames.addAll(getFontNamesFromLocation("classpath:static/fonts/*.woff2")); + fontNames.addAll( + getFontNamesFromLocation( + "file:" + + InstallationPathConfig.getStaticPath() + + "fonts" + + java.io.File.separator + + "*")); + return fontNames; + } + + private List getFontNamesFromLocation(String locationPattern) { + try { + Resource[] resources = + GeneralUtils.getResourcesFromLocationPattern(locationPattern, resourceLoader); + return Arrays.stream(resources) + .map( + resource -> { + try { + String filename = resource.getFilename(); + if (filename != null) { + int lastDotIndex = filename.lastIndexOf('.'); + if (lastDotIndex != -1) { + String name = filename.substring(0, lastDotIndex); + String extension = filename.substring(lastDotIndex + 1); + return new FontResource(name, extension); + } + } + return null; + } catch (Exception e) { + throw ExceptionUtils.createRuntimeException( + "error.fontLoadingFailed", + "Error processing font file", + e); + } + }) + .filter(Objects::nonNull) + .toList(); + } catch (Exception e) { + throw ExceptionUtils.createRuntimeException( + "error.fontDirectoryReadFailed", "Failed to read font directory", e); + } + } + + // Data classes + @Data + public static class HomeData { + private boolean showSurveyFromDocker; + } + + @Data + public static class LicensesData { + private List dependencies; + } + + @Data + public static class PipelineData { + private List> pipelineConfigsWithNames; + private List pipelineConfigs; + } + + @Data + public static class SignData { + private List signatures; + private List fonts; + } + + @Data + public static class OcrData { + private List languages; + } + + @Data + public static class FontResource { + private String name; + private String extension; + private String type; + + public FontResource(String name, String extension) { + this.name = name; + this.extension = extension; + this.type = getFormatFromExtension(extension); + } + + private static String getFormatFromExtension(String extension) { + switch (extension) { + case "ttf": + return "truetype"; + case "woff": + return "woff"; + case "woff2": + return "woff2"; + case "eot": + return "embedded-opentype"; + case "svg": + return "svg"; + default: + return ""; + } + } + } +} diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertEmlToPDF.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertEmlToPDF.java index 0f657cb47..7633dd110 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertEmlToPDF.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertEmlToPDF.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.converters; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -40,7 +42,7 @@ public class ConvertEmlToPDF { private final TempFileManager tempFileManager; private final CustomHtmlSanitizer customHtmlSanitizer; - @PostMapping(consumes = "multipart/form-data", value = "/eml/pdf") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/eml/pdf") @Operation( summary = "Convert EML to PDF", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertHtmlToPDF.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertHtmlToPDF.java index 9a589860e..15abcf50f 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertHtmlToPDF.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertHtmlToPDF.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.converters; +import stirling.software.common.annotations.AutoJobPostMapping; + import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; @@ -36,7 +38,8 @@ public class ConvertHtmlToPDF { private final CustomHtmlSanitizer customHtmlSanitizer; - @PostMapping(consumes = "multipart/form-data", value = "/html/pdf") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/html/pdf") + @Operation( summary = "Convert an HTML or ZIP (containing HTML and CSS) to PDF", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java index 5eff72a4a..39af4a002 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.converters; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; @@ -51,7 +53,7 @@ public class ConvertImgPDFController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/pdf/img") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/img") @Operation( summary = "Convert PDF to image(s)", description = @@ -211,7 +213,7 @@ public class ConvertImgPDFController { } } - @PostMapping(consumes = "multipart/form-data", value = "/img/pdf") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/img/pdf") @Operation( summary = "Convert images to a PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertMarkdownToPdf.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertMarkdownToPdf.java index 945599a93..0bd4cf6dd 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertMarkdownToPdf.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertMarkdownToPdf.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.converters; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.util.List; import java.util.Map; @@ -45,7 +47,8 @@ public class ConvertMarkdownToPdf { private final CustomHtmlSanitizer customHtmlSanitizer; - @PostMapping(consumes = "multipart/form-data", value = "/markdown/pdf") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/markdown/pdf") + @Operation( summary = "Convert a Markdown file to PDF", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertOfficeController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertOfficeController.java index 651444c69..eb1eecc59 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertOfficeController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertOfficeController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.converters; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -97,7 +99,7 @@ public class ConvertOfficeController { return fileExtension.matches(extensionPattern); } - @PostMapping(consumes = "multipart/form-data", value = "/file/pdf") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/file/pdf") @Operation( summary = "Convert a file to a PDF using LibreOffice", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToHtml.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToHtml.java index 9015dee2e..6b47a498b 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToHtml.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToHtml.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.converters; +import stirling.software.common.annotations.AutoJobPostMapping; + import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; @@ -18,7 +20,7 @@ import stirling.software.common.util.PDFToFile; @RequestMapping("/api/v1/convert") public class ConvertPDFToHtml { - @PostMapping(consumes = "multipart/form-data", value = "/pdf/html") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/html") @Operation( summary = "Convert PDF to HTML", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToOffice.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToOffice.java index 585185460..3d133f943 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToOffice.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToOffice.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.converters; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; @@ -34,7 +36,7 @@ public class ConvertPDFToOffice { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/pdf/presentation") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/presentation") @Operation( summary = "Convert PDF to Presentation format", description = @@ -49,7 +51,7 @@ public class ConvertPDFToOffice { return pdfToFile.processPdfToOfficeFormat(inputFile, outputFormat, "impress_pdf_import"); } - @PostMapping(consumes = "multipart/form-data", value = "/pdf/text") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/text") @Operation( summary = "Convert PDF to Text or RTF format", description = @@ -77,7 +79,7 @@ public class ConvertPDFToOffice { } } - @PostMapping(consumes = "multipart/form-data", value = "/pdf/word") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/word") @Operation( summary = "Convert PDF to Word document", description = @@ -91,7 +93,7 @@ public class ConvertPDFToOffice { return pdfToFile.processPdfToOfficeFormat(inputFile, outputFormat, "writer_pdf_import"); } - @PostMapping(consumes = "multipart/form-data", value = "/pdf/xml") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/xml") @Operation( summary = "Convert PDF to XML", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToPDFA.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToPDFA.java index 7c5435aaa..1e77e2b44 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToPDFA.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToPDFA.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.converters; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.Color; import java.io.ByteArrayOutputStream; import java.io.File; @@ -78,7 +80,7 @@ import stirling.software.common.util.WebResponseUtils; @Tag(name = "Convert", description = "Convert APIs") public class ConvertPDFToPDFA { - @PostMapping(consumes = "multipart/form-data", value = "/pdf/pdfa") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/pdfa") @Operation( summary = "Convert a PDF to a PDF/A", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPDF.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPDF.java index a7e194d4f..1b5467587 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPDF.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPDF.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.converters; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -40,7 +42,7 @@ public class ConvertWebsiteToPDF { private final RuntimePathConfig runtimePathConfig; private final ApplicationProperties applicationProperties; - @PostMapping(consumes = "multipart/form-data", value = "/url/pdf") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/url/pdf") @Operation( summary = "Convert a URL to a PDF", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ExtractCSVController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ExtractCSVController.java index 847904b60..2bec58d38 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ExtractCSVController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/converters/ExtractCSVController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.converters; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.StringWriter; @@ -46,7 +48,7 @@ public class ExtractCSVController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(value = "/pdf/csv", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/pdf/csv", consumes = "multipart/form-data") @Operation( summary = "Extracts a CSV document from a PDF", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/filters/FilterController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/filters/FilterController.java index ce9dab8c5..b4e9dc285 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/filters/FilterController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/filters/FilterController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.filters; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; @@ -37,7 +39,7 @@ public class FilterController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/filter-contains-text") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-contains-text") @Operation( summary = "Checks if a PDF contains set text, returns true if does", description = "Input:PDF Output:Boolean Type:SISO") @@ -55,7 +57,7 @@ public class FilterController { } // TODO - @PostMapping(consumes = "multipart/form-data", value = "/filter-contains-image") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-contains-image") @Operation( summary = "Checks if a PDF contains an image", description = "Input:PDF Output:Boolean Type:SISO") @@ -71,7 +73,7 @@ public class FilterController { return null; } - @PostMapping(consumes = "multipart/form-data", value = "/filter-page-count") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-page-count") @Operation( summary = "Checks if a PDF is greater, less or equal to a setPageCount", description = "Input:PDF Output:Boolean Type:SISO") @@ -104,7 +106,7 @@ public class FilterController { return null; } - @PostMapping(consumes = "multipart/form-data", value = "/filter-page-size") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-page-size") @Operation( summary = "Checks if a PDF is of a certain size", description = "Input:PDF Output:Boolean Type:SISO") @@ -147,7 +149,7 @@ public class FilterController { return null; } - @PostMapping(consumes = "multipart/form-data", value = "/filter-file-size") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-file-size") @Operation( summary = "Checks if a PDF is a set file size", description = "Input:PDF Output:Boolean Type:SISO") @@ -180,7 +182,7 @@ public class FilterController { return null; } - @PostMapping(consumes = "multipart/form-data", value = "/filter-page-rotation") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-page-rotation") @Operation( summary = "Checks if a PDF is of a certain rotation", description = "Input:PDF Output:Boolean Type:SISO") diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/AttachmentController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/AttachmentController.java index b36065612..3729af9d8 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/AttachmentController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/AttachmentController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import java.util.List; @@ -34,7 +36,7 @@ public class AttachmentController { private final AttachmentServiceInterface pdfAttachmentService; - @PostMapping(consumes = "multipart/form-data", value = "/add-attachments") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/add-attachments") @Operation( summary = "Add attachments to PDF", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/AutoRenameController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/AutoRenameController.java index 8d803708c..628e0d028 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/AutoRenameController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/AutoRenameController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import java.util.ArrayList; import java.util.Comparator; @@ -38,7 +40,7 @@ public class AutoRenameController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/auto-rename") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/auto-rename") @Operation( summary = "Extract header from PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/AutoSplitPdfController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/AutoSplitPdfController.java index 44d575575..0650481bf 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/AutoSplitPdfController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/AutoSplitPdfController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.image.BufferedImage; import java.awt.image.DataBufferByte; import java.awt.image.DataBufferInt; @@ -102,7 +104,7 @@ public class AutoSplitPdfController { } } - @PostMapping(value = "/auto-split-pdf", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/auto-split-pdf", consumes = "multipart/form-data") @Operation( summary = "Auto split PDF pages into separate documents", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/BlankPageController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/BlankPageController.java index 7d5086b4c..010d6d0bb 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/BlankPageController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/BlankPageController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -69,7 +71,7 @@ public class BlankPageController { return whitePixelPercentage >= whitePercent; } - @PostMapping(consumes = "multipart/form-data", value = "/remove-blanks") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/remove-blanks") @Operation( summary = "Remove blank pages from a PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java index ab8e5b3f8..9b0b43dc1 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; @@ -658,7 +660,7 @@ public class CompressController { }; } - @PostMapping(consumes = "multipart/form-data", value = "/compress-pdf") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/compress-pdf") @Operation( summary = "Optimize PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ConfigController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ConfigController.java new file mode 100644 index 000000000..fb1b7b2ca --- /dev/null +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ConfigController.java @@ -0,0 +1,129 @@ +package stirling.software.SPDF.controller.api.misc; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.context.ApplicationContext; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.tags.Tag; + +import lombok.RequiredArgsConstructor; + +import stirling.software.SPDF.config.EndpointConfiguration; +import stirling.software.common.configuration.AppConfig; +import stirling.software.common.model.ApplicationProperties; + +@RestController +@Tag(name = "Config", description = "Configuration APIs") +@RequestMapping("/api/v1/config") +@RequiredArgsConstructor +@Hidden +public class ConfigController { + + private final ApplicationProperties applicationProperties; + private final ApplicationContext applicationContext; + private final EndpointConfiguration endpointConfiguration; + + @GetMapping("/app-config") + public ResponseEntity> getAppConfig() { + Map configData = new HashMap<>(); + + try { + // Get AppConfig bean + AppConfig appConfig = applicationContext.getBean(AppConfig.class); + + // Extract key configuration values from AppConfig + configData.put("baseUrl", appConfig.getBaseUrl()); + configData.put("contextPath", appConfig.getContextPath()); + configData.put("serverPort", appConfig.getServerPort()); + + // Extract values from ApplicationProperties + configData.put("appName", applicationProperties.getUi().getAppName()); + configData.put("appNameNavbar", applicationProperties.getUi().getAppNameNavbar()); + configData.put("homeDescription", applicationProperties.getUi().getHomeDescription()); + configData.put("languages", applicationProperties.getUi().getLanguages()); + + // Security settings + configData.put("enableLogin", applicationProperties.getSecurity().getEnableLogin()); + + // System settings + configData.put( + "enableAlphaFunctionality", + applicationProperties.getSystem().getEnableAlphaFunctionality()); + configData.put( + "enableAnalytics", applicationProperties.getSystem().getEnableAnalytics()); + + // Premium/Enterprise settings + configData.put("premiumEnabled", applicationProperties.getPremium().isEnabled()); + + // Legal settings + configData.put( + "termsAndConditions", applicationProperties.getLegal().getTermsAndConditions()); + configData.put("privacyPolicy", applicationProperties.getLegal().getPrivacyPolicy()); + configData.put("cookiePolicy", applicationProperties.getLegal().getCookiePolicy()); + configData.put("impressum", applicationProperties.getLegal().getImpressum()); + configData.put( + "accessibilityStatement", + applicationProperties.getLegal().getAccessibilityStatement()); + + // Try to get EEAppConfig values if available + try { + if (applicationContext.containsBean("runningProOrHigher")) { + configData.put( + "runningProOrHigher", + applicationContext.getBean("runningProOrHigher", Boolean.class)); + } + if (applicationContext.containsBean("runningEE")) { + configData.put( + "runningEE", applicationContext.getBean("runningEE", Boolean.class)); + } + if (applicationContext.containsBean("license")) { + configData.put("license", applicationContext.getBean("license", String.class)); + } + if (applicationContext.containsBean("GoogleDriveEnabled")) { + configData.put( + "GoogleDriveEnabled", + applicationContext.getBean("GoogleDriveEnabled", Boolean.class)); + } + if (applicationContext.containsBean("SSOAutoLogin")) { + configData.put( + "SSOAutoLogin", + applicationContext.getBean("SSOAutoLogin", Boolean.class)); + } + } catch (Exception e) { + // EE features not available, continue without them + } + + return ResponseEntity.ok(configData); + + } catch (Exception e) { + // Return basic config if there are any issues + configData.put("error", "Unable to retrieve full configuration"); + return ResponseEntity.ok(configData); + } + } + + @GetMapping("/endpoint-enabled") + public ResponseEntity isEndpointEnabled(@RequestParam(name = "endpoint") String endpoint) { + boolean enabled = endpointConfiguration.isEndpointEnabled(endpoint); + return ResponseEntity.ok(enabled); + } + + @GetMapping("/endpoints-enabled") + public ResponseEntity> areEndpointsEnabled( + @RequestParam(name = "endpoints") String endpoints) { + Map result = new HashMap<>(); + String[] endpointArray = endpoints.split(","); + for (String endpoint : endpointArray) { + String trimmedEndpoint = endpoint.trim(); + result.put(trimmedEndpoint, endpointConfiguration.isEndpointEnabled(trimmedEndpoint)); + } + return ResponseEntity.ok(result); + } +} diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/DecompressPdfController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/DecompressPdfController.java index 5c432ce57..b5fe504c4 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/DecompressPdfController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/DecompressPdfController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -38,7 +40,7 @@ public class DecompressPdfController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(value = "/decompress-pdf", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/decompress-pdf", consumes = "multipart/form-data") @Operation( summary = "Decompress PDF streams", description = "Fully decompresses all PDF streams including text content") diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImageScansController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImageScansController.java index 3992595ab..aa3c40519 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImageScansController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImageScansController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.image.BufferedImage; import java.io.FileOutputStream; import java.io.IOException; @@ -50,7 +52,7 @@ public class ExtractImageScansController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/extract-image-scans") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/extract-image-scans") @Operation( summary = "Extract image scans from an input file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImagesController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImagesController.java index 09486f9e8..2e2968c9c 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImagesController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImagesController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.*; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; @@ -54,7 +56,7 @@ public class ExtractImagesController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/extract-images") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/extract-images") @Operation( summary = "Extract images from a PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/FlattenController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/FlattenController.java index d82a1971a..ecd263c1c 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/FlattenController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/FlattenController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.image.BufferedImage; import java.io.IOException; @@ -38,7 +40,7 @@ public class FlattenController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/flatten") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/flatten") @Operation( summary = "Flatten PDF form fields or full page", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/MetadataController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/MetadataController.java index 1d5196940..37b1c209e 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/MetadataController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/MetadataController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -51,7 +53,7 @@ public class MetadataController { binder.registerCustomEditor(Map.class, "allRequestParams", new StringToMapPropertyEditor()); } - @PostMapping(consumes = "multipart/form-data", value = "/update-metadata") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/update-metadata") @Operation( summary = "Update metadata of a PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/OCRController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/OCRController.java index c1fd4ade1..5cd80384c 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/OCRController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/OCRController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.image.BufferedImage; import java.io.*; import java.nio.file.Files; @@ -76,7 +78,7 @@ public class OCRController { .toList(); } - @PostMapping(consumes = "multipart/form-data", value = "/ocr-pdf") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/ocr-pdf") @Operation( summary = "Process a PDF file with OCR", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/OverlayImageController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/OverlayImageController.java index d50c80967..5b61f66ea 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/OverlayImageController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/OverlayImageController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import org.springframework.http.HttpStatus; @@ -31,7 +33,7 @@ public class OverlayImageController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/add-image") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/add-image") @Operation( summary = "Overlay image onto a PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/PageNumbersController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/PageNumbersController.java index 4233d11e4..d91c30bae 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/PageNumbersController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/PageNumbersController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.List; @@ -37,7 +39,7 @@ public class PageNumbersController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(value = "/add-page-numbers", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/add-page-numbers", consumes = "multipart/form-data") @Operation( summary = "Add page numbers to a PDF document", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/PrintFileController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/PrintFileController.java index fc7b7d298..34ed58540 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/PrintFileController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/PrintFileController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.*; import java.awt.image.BufferedImage; import java.awt.print.PageFormat; @@ -37,7 +39,7 @@ import stirling.software.SPDF.model.api.misc.PrintFileRequest; public class PrintFileController { // TODO - // @PostMapping(value = "/print-file", consumes = "multipart/form-data") + // @AutoJobPostMapping(value = "/print-file", consumes = "multipart/form-data") // @Operation( // summary = "Prints PDF/Image file to a set printer", // description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/RepairController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/RepairController.java index 7cde1d078..e1084a457 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/RepairController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/RepairController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -46,7 +48,7 @@ public class RepairController { return endpointConfiguration.isGroupEnabled("qpdf"); } - @PostMapping(consumes = "multipart/form-data", value = "/repair") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/repair") @Operation( summary = "Repair a PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ReplaceAndInvertColorController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ReplaceAndInvertColorController.java index 85fb7cfc3..b935d59da 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ReplaceAndInvertColorController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ReplaceAndInvertColorController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import org.springframework.core.io.InputStreamResource; @@ -27,7 +29,7 @@ public class ReplaceAndInvertColorController { private final ReplaceAndInvertColorService replaceAndInvertColorService; - @PostMapping(consumes = "multipart/form-data", value = "/replace-invert-pdf") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/replace-invert-pdf") @Operation( summary = "Replace-Invert Color PDF", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ScannerEffectController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ScannerEffectController.java index a94b487b4..a140e9029 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ScannerEffectController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ScannerEffectController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; @@ -52,7 +54,7 @@ public class ScannerEffectController { private static final int MAX_IMAGE_HEIGHT = 8192; private static final long MAX_IMAGE_PIXELS = 16_777_216; // 4096x4096 - @PostMapping(value = "/scanner-effect", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/scanner-effect", consumes = "multipart/form-data") @Operation( summary = "Apply scanner effect to PDF", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ShowJavascript.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ShowJavascript.java index 94e9b57c6..709d8bd09 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ShowJavascript.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/ShowJavascript.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.nio.charset.StandardCharsets; import java.util.Map; @@ -32,7 +34,7 @@ public class ShowJavascript { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/show-javascript") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/show-javascript") @Operation( summary = "Grabs all JS from a PDF and returns a single JS file with all code", description = "desc. Input:PDF Output:JS Type:SISO") diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/StampController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/StampController.java index 2a4a3f665..8193c7a81 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/StampController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/StampController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; @@ -52,7 +54,7 @@ public class StampController { private final CustomPDFDocumentFactory pdfDocumentFactory; private final TempFileManager tempFileManager; - @PostMapping(consumes = "multipart/form-data", value = "/add-stamp") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/add-stamp") @Operation( summary = "Add stamp to a PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/UnlockPDFFormsController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/UnlockPDFFormsController.java index 21fd61d11..d80c35022 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/UnlockPDFFormsController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/UnlockPDFFormsController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.misc; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -37,7 +39,7 @@ public class UnlockPDFFormsController { this.pdfDocumentFactory = pdfDocumentFactory; } - @PostMapping(consumes = "multipart/form-data", value = "/unlock-pdf-forms") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/unlock-pdf-forms") @Operation( summary = "Remove read-only property from form fields", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineController.java index d6b4fa0da..166668db9 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.pipeline; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.HashMap; @@ -46,7 +48,7 @@ public class PipelineController { private final PostHogService postHogService; - @PostMapping(value = "/handleData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @AutoJobPostMapping(value = "/handleData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity handleData(@ModelAttribute HandleDataRequest request) throws JsonMappingException, JsonProcessingException { MultipartFile[] files = request.getFileInput(); diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java index 7675355da..b43d918e8 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.security; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.*; import java.beans.PropertyEditorSupport; import java.io.*; @@ -138,7 +140,7 @@ public class CertSignController { } } - @PostMapping( + @AutoJobPostMapping( consumes = { MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_FORM_URLENCODED_VALUE diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java index f3c0a5e29..436b2ba30 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.security; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -188,7 +190,7 @@ public class GetInfoOnPDF { return false; } - @PostMapping(consumes = "multipart/form-data", value = "/get-info-on-pdf") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/get-info-on-pdf") @Operation(summary = "Summary here", description = "desc. Input:PDF Output:JSON Type:SISO") public ResponseEntity getPdfInfo(@ModelAttribute PDFFile request) throws IOException { MultipartFile inputFile = request.getFileInput(); diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java index ef382ee44..d3e78ef6e 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.security; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; @@ -32,7 +34,7 @@ public class PasswordController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/remove-password") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/remove-password") @Operation( summary = "Remove password from a PDF file", description = @@ -58,7 +60,7 @@ public class PasswordController { } } - @PostMapping(consumes = "multipart/form-data", value = "/add-password") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/add-password") @Operation( summary = "Add password to a PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java index 88d271cfb..23d7e20ad 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.security; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.*; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -56,7 +58,7 @@ public class RedactController { List.class, "redactions", new StringToArrayListPropertyEditor()); } - @PostMapping(value = "/redact", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/redact", consumes = "multipart/form-data") @Operation( summary = "Redacts areas and pages in a PDF document", description = @@ -190,7 +192,7 @@ public class RedactController { return pageNumbers; } - @PostMapping(value = "/auto-redact", consumes = "multipart/form-data") + @AutoJobPostMapping(value = "/auto-redact", consumes = "multipart/form-data") @Operation( summary = "Redacts listOfText in a PDF document", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/RemoveCertSignController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/RemoveCertSignController.java index 79fd18914..8ecfe7cb7 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/RemoveCertSignController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/RemoveCertSignController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.security; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.util.List; import org.apache.pdfbox.pdmodel.PDDocument; @@ -32,7 +34,7 @@ public class RemoveCertSignController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/remove-cert-sign") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/remove-cert-sign") @Operation( summary = "Remove digital signature from PDF", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/SanitizeController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/SanitizeController.java index 47e45c595..5935a5152 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/SanitizeController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/SanitizeController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.security; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.io.IOException; import org.apache.pdfbox.cos.COSDictionary; @@ -46,7 +48,7 @@ public class SanitizeController { private final CustomPDFDocumentFactory pdfDocumentFactory; - @PostMapping(consumes = "multipart/form-data", value = "/sanitize-pdf") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/sanitize-pdf") @Operation( summary = "Sanitize a PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/ValidateSignatureController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/ValidateSignatureController.java index a98f0c0d1..0ed9e98f9 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/ValidateSignatureController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/ValidateSignatureController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.security; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.beans.PropertyEditorSupport; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -69,7 +71,7 @@ public class ValidateSignatureController { description = "Validates the digital signatures in a PDF file against default or custom" + " certificates. Input:PDF Output:JSON Type:SISO") - @PostMapping(value = "/validate-signature", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @AutoJobPostMapping(value = "/validate-signature", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity> validateSignature( @ModelAttribute SignatureValidationRequest request) throws IOException { List results = new ArrayList<>(); diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java index 484a1c116..b3abf2df7 100644 --- a/app/core/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java +++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.controller.api.security; +import stirling.software.common.annotations.AutoJobPostMapping; + import java.awt.*; import java.awt.image.BufferedImage; import java.beans.PropertyEditorSupport; @@ -64,7 +66,7 @@ public class WatermarkController { }); } - @PostMapping(consumes = "multipart/form-data", value = "/add-watermark") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/add-watermark") @Operation( summary = "Add watermark to a PDF file", description = diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/web/ReactRoutingController.java b/app/core/src/main/java/stirling/software/SPDF/controller/web/ReactRoutingController.java new file mode 100644 index 000000000..2d4ad3c97 --- /dev/null +++ b/app/core/src/main/java/stirling/software/SPDF/controller/web/ReactRoutingController.java @@ -0,0 +1,18 @@ +package stirling.software.SPDF.controller.web; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class ReactRoutingController { + + @GetMapping("/{path:^(?!api|static|robots\\.txt|favicon\\.ico)[^\\.]*$}") + public String forwardRootPaths() { + return "forward:/index.html"; + } + + @GetMapping("/{path:^(?!api|static)[^\\.]*}/{subpath:^(?!.*\\.).*$}") + public String forwardNestedPaths() { + return "forward:/index.html"; + } +} diff --git a/app/core/src/main/java/stirling/software/SPDF/model/api/converters/ConvertPDFToMarkdown.java b/app/core/src/main/java/stirling/software/SPDF/model/api/converters/ConvertPDFToMarkdown.java index fbbd4723a..a3ebcfd3d 100644 --- a/app/core/src/main/java/stirling/software/SPDF/model/api/converters/ConvertPDFToMarkdown.java +++ b/app/core/src/main/java/stirling/software/SPDF/model/api/converters/ConvertPDFToMarkdown.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.model.api.converters; +import stirling.software.common.annotations.AutoJobPostMapping; + import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; @@ -18,7 +20,7 @@ import stirling.software.common.util.PDFToFile; @RequestMapping("/api/v1/convert") public class ConvertPDFToMarkdown { - @PostMapping(consumes = "multipart/form-data", value = "/pdf/markdown") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/markdown") @Operation( summary = "Convert PDF to Markdown", description = diff --git a/app/core/src/main/resources/messages_en_GB.properties b/app/core/src/main/resources/messages_en_GB.properties index d6056e856..865acff9a 100644 --- a/app/core/src/main/resources/messages_en_GB.properties +++ b/app/core/src/main/resources/messages_en_GB.properties @@ -1844,22 +1844,6 @@ cookieBanner.preferencesModal.necessary.description=These cookies are essential cookieBanner.preferencesModal.analytics.title=Analytics cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with. -#scannerEffect -scannerEffect.title=Scanner Effect -scannerEffect.header=Scanner Effect -scannerEffect.description=Create a PDF that looks like it was scanned -scannerEffect.selectPDF=Select PDF: -scannerEffect.quality=Scan Quality -scannerEffect.quality.low=Low -scannerEffect.quality.medium=Medium -scannerEffect.quality.high=High -scannerEffect.rotation=Rotation Angle -scannerEffect.rotation.none=None -scannerEffect.rotation.slight=Slight -scannerEffect.rotation.moderate=Moderate -scannerEffect.rotation.severe=Severe -scannerEffect.submit=Create Scanner Effect - #home.scannerEffect home.scannerEffect.title=Scanner Effect home.scannerEffect.desc=Create a PDF that looks like it was scanned @@ -1902,3 +1886,73 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks. editTableOfContents.desc.3=Each bookmark requires a title and target page number. editTableOfContents.submit=Apply Table of Contents + + + + + + + +#################### +# React Frontend # +#################### +# Common UI elements +removeMetadata.submit=Remove Metadata +sidebar.toggle=Toggle Sidebar +theme.toggle=Toggle Theme +view.viewer=Viewer +view.pageEditor=Page Editor +view.fileManager=File Manager + +# File management +fileManager.dragDrop=Drag & Drop files here +fileManager.clickToUpload=Click to upload files +fileManager.selectedFiles=Selected Files +fileManager.clearAll=Clear All +fileManager.storage=Storage +fileManager.filesStored=files stored +fileManager.storageError=Storage error occurred +fileManager.storageLow=Storage is running low. Consider removing old files. +fileManager.uploadError=Failed to upload some files. +fileManager.supportMessage=Powered by browser database storage for unlimited capacity + +# Page Editor +pageEditor.title=Page Editor +pageEditor.save=Save Changes +pageEditor.noPdfLoaded=No PDF loaded. Please upload a PDF to edit. +pageEditor.rotatedLeft=Rotated left: +pageEditor.rotatedRight=Rotated right: +pageEditor.deleted=Deleted: +pageEditor.movedLeft=Moved left: +pageEditor.movedRight=Moved right: +pageEditor.splitAt=Split at: +pageEditor.insertedPageBreak=Inserted page break at: +pageEditor.addFileNotImplemented=Add file not implemented in demo +pageEditor.closePdf=Close PDF + +# Viewer +viewer.noPdfLoaded=No PDF loaded. Click to upload a PDF. +viewer.choosePdf=Choose PDF +viewer.noPagesToDisplay=No pages to display. +viewer.singlePageView=Single Page View +viewer.dualPageView=Dual Page View +viewer.hideSidebars=Hide Sidebars +viewer.showSidebars=Show Sidebars +viewer.zoomOut=Zoom out +viewer.zoomIn=Zoom in + +# Tool Picker +toolPicker.searchPlaceholder=Search tools... +toolPicker.noToolsFound=No tools found +pageEditor.reset=Reset Changes +pageEditor.zoomIn=Zoom In +pageEditor.zoomOut=Zoom Out +pageEditor.fitToWidth=Fit to Width +pageEditor.actualSize=Actual Size + +# Viewer +viewer.previousPage=Previous Page +viewer.nextPage=Next Page +viewer.pageNavigation=Page Navigation +viewer.currentPage=Current Page +viewer.totalPages=Total Pages diff --git a/app/proprietary/src/main/java/stirling/software/proprietary/controller/api/ProprietaryUIDataController.java b/app/proprietary/src/main/java/stirling/software/proprietary/controller/api/ProprietaryUIDataController.java new file mode 100644 index 000000000..f4eb114ef --- /dev/null +++ b/app/proprietary/src/main/java/stirling/software/proprietary/controller/api/ProprietaryUIDataController.java @@ -0,0 +1,484 @@ +package stirling.software.proprietary.controller.api; + +import static stirling.software.common.util.ProviderUtils.validateProvider; + +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.*; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import stirling.software.common.model.ApplicationProperties; +import stirling.software.common.model.ApplicationProperties.Security; +import stirling.software.common.model.ApplicationProperties.Security.OAUTH2; +import stirling.software.common.model.ApplicationProperties.Security.OAUTH2.Client; +import stirling.software.common.model.ApplicationProperties.Security.SAML2; +import stirling.software.common.model.FileInfo; +import stirling.software.common.model.enumeration.Role; +import stirling.software.common.model.oauth2.GitHubProvider; +import stirling.software.common.model.oauth2.GoogleProvider; +import stirling.software.common.model.oauth2.KeycloakProvider; +import stirling.software.proprietary.audit.AuditEventType; +import stirling.software.proprietary.audit.AuditLevel; +import stirling.software.proprietary.config.AuditConfigurationProperties; +import stirling.software.proprietary.model.Team; +import stirling.software.proprietary.model.dto.TeamWithUserCountDTO; +import stirling.software.proprietary.security.config.EnterpriseEndpoint; +import stirling.software.proprietary.security.database.repository.SessionRepository; +import stirling.software.proprietary.security.database.repository.UserRepository; +import stirling.software.proprietary.security.model.Authority; +import stirling.software.proprietary.security.model.SessionEntity; +import stirling.software.proprietary.security.model.User; +import stirling.software.proprietary.security.repository.TeamRepository; +import stirling.software.proprietary.security.saml2.CustomSaml2AuthenticatedPrincipal; +import stirling.software.proprietary.security.service.DatabaseService; +import stirling.software.proprietary.security.service.TeamService; +import stirling.software.proprietary.security.session.SessionPersistentRegistry; + +@Slf4j +@RestController +@RequestMapping("/api/v1/proprietary/ui-data") +@Tag(name = "Proprietary UI Data", description = "APIs for React UI data (Proprietary features)") +@EnterpriseEndpoint +public class ProprietaryUIDataController { + + private final ApplicationProperties applicationProperties; + private final AuditConfigurationProperties auditConfig; + private final SessionPersistentRegistry sessionPersistentRegistry; + private final UserRepository userRepository; + private final TeamRepository teamRepository; + private final SessionRepository sessionRepository; + private final DatabaseService databaseService; + private final boolean runningEE; + private final ObjectMapper objectMapper; + + public ProprietaryUIDataController( + ApplicationProperties applicationProperties, + AuditConfigurationProperties auditConfig, + SessionPersistentRegistry sessionPersistentRegistry, + UserRepository userRepository, + TeamRepository teamRepository, + SessionRepository sessionRepository, + DatabaseService databaseService, + ObjectMapper objectMapper, + @Qualifier("runningEE") boolean runningEE) { + this.applicationProperties = applicationProperties; + this.auditConfig = auditConfig; + this.sessionPersistentRegistry = sessionPersistentRegistry; + this.userRepository = userRepository; + this.teamRepository = teamRepository; + this.sessionRepository = sessionRepository; + this.databaseService = databaseService; + this.objectMapper = objectMapper; + this.runningEE = runningEE; + } + + @GetMapping("/audit-dashboard") + @PreAuthorize("hasRole('ADMIN')") + @Operation(summary = "Get audit dashboard data") + public ResponseEntity getAuditDashboardData() { + AuditDashboardData data = new AuditDashboardData(); + data.setAuditEnabled(auditConfig.isEnabled()); + data.setAuditLevel(auditConfig.getAuditLevel()); + data.setAuditLevelInt(auditConfig.getLevel()); + data.setRetentionDays(auditConfig.getRetentionDays()); + data.setAuditLevels(AuditLevel.values()); + data.setAuditEventTypes(AuditEventType.values()); + + return ResponseEntity.ok(data); + } + + @GetMapping("/login") + @Operation(summary = "Get login page data") + public ResponseEntity getLoginData() { + LoginData data = new LoginData(); + Map providerList = new HashMap<>(); + Security securityProps = applicationProperties.getSecurity(); + OAUTH2 oauth = securityProps.getOauth2(); + + if (oauth != null && oauth.getEnabled()) { + if (oauth.isSettingsValid()) { + String firstChar = String.valueOf(oauth.getProvider().charAt(0)); + String clientName = + oauth.getProvider().replaceFirst(firstChar, firstChar.toUpperCase()); + providerList.put("/oauth2/authorization/" + oauth.getProvider(), clientName); + } + + Client client = oauth.getClient(); + if (client != null) { + GoogleProvider google = client.getGoogle(); + if (validateProvider(google)) { + providerList.put( + "/oauth2/authorization/" + google.getName(), google.getClientName()); + } + + GitHubProvider github = client.getGithub(); + if (validateProvider(github)) { + providerList.put( + "/oauth2/authorization/" + github.getName(), github.getClientName()); + } + + KeycloakProvider keycloak = client.getKeycloak(); + if (validateProvider(keycloak)) { + providerList.put( + "/oauth2/authorization/" + keycloak.getName(), + keycloak.getClientName()); + } + } + } + + SAML2 saml2 = securityProps.getSaml2(); + if (securityProps.isSaml2Active() + && applicationProperties.getSystem().getEnableAlphaFunctionality() + && applicationProperties.getPremium().isEnabled()) { + String samlIdp = saml2.getProvider(); + String saml2AuthenticationPath = "/saml2/authenticate/" + saml2.getRegistrationId(); + + if (!applicationProperties.getPremium().getProFeatures().isSsoAutoLogin()) { + providerList.put(saml2AuthenticationPath, samlIdp + " (SAML 2)"); + } + } + + // Remove null entries + providerList + .entrySet() + .removeIf(entry -> entry.getKey() == null || entry.getValue() == null); + + data.setProviderList(providerList); + data.setLoginMethod(securityProps.getLoginMethod()); + data.setAltLogin(!providerList.isEmpty() && securityProps.isAltLogin()); + + return ResponseEntity.ok(data); + } + + @GetMapping("/admin-settings") + @PreAuthorize("hasRole('ROLE_ADMIN')") + @Operation(summary = "Get admin settings data") + public ResponseEntity getAdminSettingsData(Authentication authentication) { + List allUsers = userRepository.findAllWithTeam(); + Iterator iterator = allUsers.iterator(); + Map roleDetails = Role.getAllRoleDetails(); + + Map userSessions = new HashMap<>(); + Map userLastRequest = new HashMap<>(); + int activeUsers = 0; + int disabledUsers = 0; + + while (iterator.hasNext()) { + User user = iterator.next(); + if (user != null) { + boolean shouldRemove = false; + + // Check if user is an INTERNAL_API_USER + for (Authority authority : user.getAuthorities()) { + if (authority.getAuthority().equals(Role.INTERNAL_API_USER.getRoleId())) { + shouldRemove = true; + roleDetails.remove(Role.INTERNAL_API_USER.getRoleId()); + break; + } + } + + // Check if user is part of the Internal team + if (user.getTeam() != null + && user.getTeam().getName().equals(TeamService.INTERNAL_TEAM_NAME)) { + shouldRemove = true; + } + + if (shouldRemove) { + iterator.remove(); + continue; + } + + // Session status and last request time + int maxInactiveInterval = sessionPersistentRegistry.getMaxInactiveInterval(); + boolean hasActiveSession = false; + Date lastRequest = null; + Optional latestSession = + sessionPersistentRegistry.findLatestSession(user.getUsername()); + + if (latestSession.isPresent()) { + SessionEntity sessionEntity = latestSession.get(); + Date lastAccessedTime = sessionEntity.getLastRequest(); + Instant now = Instant.now(); + Instant expirationTime = + lastAccessedTime + .toInstant() + .plus(maxInactiveInterval, ChronoUnit.SECONDS); + + if (now.isAfter(expirationTime)) { + sessionPersistentRegistry.expireSession(sessionEntity.getSessionId()); + } else { + hasActiveSession = !sessionEntity.isExpired(); + } + lastRequest = sessionEntity.getLastRequest(); + } else { + lastRequest = new Date(0); + } + + userSessions.put(user.getUsername(), hasActiveSession); + userLastRequest.put(user.getUsername(), lastRequest); + + if (hasActiveSession) activeUsers++; + if (!user.isEnabled()) disabledUsers++; + } + } + + // Sort users by active status and last request date + List sortedUsers = + allUsers.stream() + .sorted( + (u1, u2) -> { + boolean u1Active = userSessions.get(u1.getUsername()); + boolean u2Active = userSessions.get(u2.getUsername()); + if (u1Active && !u2Active) return -1; + if (!u1Active && u2Active) return 1; + + Date u1LastRequest = + userLastRequest.getOrDefault( + u1.getUsername(), new Date(0)); + Date u2LastRequest = + userLastRequest.getOrDefault( + u2.getUsername(), new Date(0)); + return u2LastRequest.compareTo(u1LastRequest); + }) + .toList(); + + List allTeams = + teamRepository.findAll().stream() + .filter(team -> !team.getName().equals(TeamService.INTERNAL_TEAM_NAME)) + .toList(); + + AdminSettingsData data = new AdminSettingsData(); + data.setUsers(sortedUsers); + data.setCurrentUsername(authentication.getName()); + data.setRoleDetails(roleDetails); + data.setUserSessions(userSessions); + data.setUserLastRequest(userLastRequest); + data.setTotalUsers(allUsers.size()); + data.setActiveUsers(activeUsers); + data.setDisabledUsers(disabledUsers); + data.setTeams(allTeams); + data.setMaxPaidUsers(applicationProperties.getPremium().getMaxUsers()); + + return ResponseEntity.ok(data); + } + + @GetMapping("/account") + @PreAuthorize("!hasAuthority('ROLE_DEMO_USER')") + @Operation(summary = "Get account page data") + public ResponseEntity getAccountData(Authentication authentication) { + if (authentication == null || !authentication.isAuthenticated()) { + return ResponseEntity.status(401).build(); + } + + Object principal = authentication.getPrincipal(); + String username = null; + boolean isOAuth2Login = false; + boolean isSaml2Login = false; + + if (principal instanceof UserDetails detailsUser) { + username = detailsUser.getUsername(); + } else if (principal instanceof OAuth2User oAuth2User) { + username = oAuth2User.getName(); + isOAuth2Login = true; + } else if (principal instanceof CustomSaml2AuthenticatedPrincipal saml2User) { + username = saml2User.name(); + isSaml2Login = true; + } + + if (username == null) { + return ResponseEntity.status(401).build(); + } + + Optional user = userRepository.findByUsernameIgnoreCaseWithSettings(username); + if (user.isEmpty()) { + return ResponseEntity.status(404).build(); + } + + String settingsJson; + try { + settingsJson = objectMapper.writeValueAsString(user.get().getSettings()); + } catch (JsonProcessingException e) { + log.error("Error converting settings map", e); + return ResponseEntity.status(500).build(); + } + + AccountData data = new AccountData(); + data.setUsername(username); + data.setRole(user.get().getRolesAsString()); + data.setSettings(settingsJson); + data.setChangeCredsFlag(user.get().isFirstLogin()); + data.setOAuth2Login(isOAuth2Login); + data.setSaml2Login(isSaml2Login); + + return ResponseEntity.ok(data); + } + + @GetMapping("/teams") + @PreAuthorize("hasRole('ROLE_ADMIN')") + @Operation(summary = "Get teams list data") + public ResponseEntity getTeamsData() { + List allTeamsWithCounts = teamRepository.findAllTeamsWithUserCount(); + List teamsWithCounts = + allTeamsWithCounts.stream() + .filter(team -> !team.getName().equals(TeamService.INTERNAL_TEAM_NAME)) + .toList(); + + List teamActivities = sessionRepository.findLatestActivityByTeam(); + Map teamLastRequest = new HashMap<>(); + for (Object[] result : teamActivities) { + Long teamId = (Long) result[0]; + Date lastActivity = (Date) result[1]; + teamLastRequest.put(teamId, lastActivity); + } + + TeamsData data = new TeamsData(); + data.setTeamsWithCounts(teamsWithCounts); + data.setTeamLastRequest(teamLastRequest); + + return ResponseEntity.ok(data); + } + + @GetMapping("/teams/{id}") + @PreAuthorize("hasRole('ROLE_ADMIN')") + @Operation(summary = "Get team details data") + public ResponseEntity getTeamDetailsData(@PathVariable("id") Long id) { + Team team = + teamRepository + .findById(id) + .orElseThrow(() -> new RuntimeException("Team not found")); + + if (team.getName().equals(TeamService.INTERNAL_TEAM_NAME)) { + return ResponseEntity.status(403).build(); + } + + List teamUsers = userRepository.findAllByTeamId(id); + List allUsers = userRepository.findAllWithTeam(); + List availableUsers = + allUsers.stream() + .filter( + user -> + (user.getTeam() == null + || !user.getTeam().getId().equals(id)) + && (user.getTeam() == null + || !user.getTeam() + .getName() + .equals( + TeamService + .INTERNAL_TEAM_NAME))) + .toList(); + + List userSessions = sessionRepository.findLatestSessionByTeamId(id); + Map userLastRequest = new HashMap<>(); + for (Object[] result : userSessions) { + String username = (String) result[0]; + Date lastRequest = (Date) result[1]; + userLastRequest.put(username, lastRequest); + } + + TeamDetailsData data = new TeamDetailsData(); + data.setTeam(team); + data.setTeamUsers(teamUsers); + data.setAvailableUsers(availableUsers); + data.setUserLastRequest(userLastRequest); + + return ResponseEntity.ok(data); + } + + @GetMapping("/database") + @PreAuthorize("hasRole('ROLE_ADMIN')") + @Operation(summary = "Get database management data") + public ResponseEntity getDatabaseData() { + List backupList = databaseService.getBackupList(); + String dbVersion = databaseService.getH2Version(); + boolean isVersionUnknown = "Unknown".equalsIgnoreCase(dbVersion); + + DatabaseData data = new DatabaseData(); + data.setBackupFiles(backupList); + data.setDatabaseVersion(dbVersion); + data.setVersionUnknown(isVersionUnknown); + + return ResponseEntity.ok(data); + } + + // Data classes + @Data + public static class AuditDashboardData { + private boolean auditEnabled; + private AuditLevel auditLevel; + private int auditLevelInt; + private int retentionDays; + private AuditLevel[] auditLevels; + private AuditEventType[] auditEventTypes; + } + + @Data + public static class LoginData { + private Map providerList; + private String loginMethod; + private boolean altLogin; + } + + @Data + public static class AdminSettingsData { + private List users; + private String currentUsername; + private Map roleDetails; + private Map userSessions; + private Map userLastRequest; + private int totalUsers; + private int activeUsers; + private int disabledUsers; + private List teams; + private int maxPaidUsers; + } + + @Data + public static class AccountData { + private String username; + private String role; + private String settings; + private boolean changeCredsFlag; + private boolean oAuth2Login; + private boolean saml2Login; + } + + @Data + public static class TeamsData { + private List teamsWithCounts; + private Map teamLastRequest; + } + + @Data + public static class TeamDetailsData { + private Team team; + private List teamUsers; + private List availableUsers; + private Map userLastRequest; + } + + @Data + public static class DatabaseData { + private List backupFiles; + private String databaseVersion; + private boolean versionUnknown; + } +} diff --git a/app/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/EmailController.java b/app/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/EmailController.java index 7fb767573..839c07083 100644 --- a/app/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/EmailController.java +++ b/app/proprietary/src/main/java/stirling/software/proprietary/security/controller/api/EmailController.java @@ -1,5 +1,7 @@ package stirling.software.proprietary.security.controller.api; +import stirling.software.common.annotations.AutoJobPostMapping; + import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -42,7 +44,7 @@ public class EmailController { * attachment. * @return ResponseEntity with success or error message. */ - @PostMapping(consumes = "multipart/form-data", value = "/send-email") + @AutoJobPostMapping(consumes = "multipart/form-data", value = "/send-email") @Operation( summary = "Send an email with an attachment", description = diff --git a/build.gradle b/build.gradle index 2c151d11b..ba051f4fd 100644 --- a/build.gradle +++ b/build.gradle @@ -212,9 +212,17 @@ subprojects { tasks.withType(JavaCompile).configureEach { options.encoding = "UTF-8" - dependsOn "spotlessApply" + if (!project.hasProperty("noSpotless")) { + dependsOn "spotlessApply" + } +} +gradle.taskGraph.whenReady { graph -> + if (project.hasProperty("noSpotless")) { + tasks.matching { it.name.startsWith("spotless") }.configureEach { + enabled = false + } + } } - licenseReport { projects = [project] renderers = [new JsonReportRenderer()] diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 000000000..df07e6b9e --- /dev/null +++ b/docker/README.md @@ -0,0 +1,56 @@ +# Docker Setup for Stirling-PDF + +This directory contains the organized Docker configurations for the split frontend/backend architecture. + +## Directory Structure + +``` +docker/ +ā”œā”€ā”€ backend/ # Backend Docker files +│ ā”œā”€ā”€ Dockerfile # Standard backend +│ ā”œā”€ā”€ Dockerfile.ultra-lite # Minimal backend +│ └── Dockerfile.fat # Full-featured backend +ā”œā”€ā”€ frontend/ # Frontend Docker files +│ ā”œā”€ā”€ Dockerfile # React/Vite frontend with nginx +│ ā”œā”€ā”€ nginx.conf # Nginx configuration +│ └── entrypoint.sh # Dynamic backend URL setup +└── compose/ # Docker Compose files + ā”œā”€ā”€ docker-compose.yml # Standard setup + ā”œā”€ā”€ docker-compose.ultra-lite.yml # Ultra-lite setup + └── docker-compose.fat.yml # Full-featured setup +``` + +## Usage + +### Separate Containers (Recommended) + +From the project root directory: + +```bash +# Standard version +docker-compose -f docker/compose/docker-compose.yml up --build + +# Ultra-lite version +docker-compose -f docker/compose/docker-compose.ultra-lite.yml up --build + +# Fat version +docker-compose -f docker/compose/docker-compose.fat.yml up --build +``` + + +## Access Points + +- **Frontend**: http://localhost:3000 +- **Backend API (debugging)**: http://localhost:8080 (TODO: Remove in production) +- **Backend API (via frontend)**: http://localhost:3000/api/* + +## Configuration + +- **Backend URL**: Set `VITE_API_BASE_URL` environment variable for custom backend locations +- **Custom Ports**: Modify port mappings in docker-compose files +- **Memory Limits**: Adjust memory limits per variant (2G ultra-lite, 4G standard, 6G fat) + +## Development vs Production + +- **Development**: Keep backend port 8080 exposed for debugging +- **Production**: Remove backend port exposure, use only frontend proxy \ No newline at end of file diff --git a/docker/backend/Dockerfile b/docker/backend/Dockerfile new file mode 100644 index 000000000..0178509e9 --- /dev/null +++ b/docker/backend/Dockerfile @@ -0,0 +1,123 @@ +# Backend Dockerfile - Java Spring Boot with all dependencies and build stage +# Build the application +FROM gradle:8.14-jdk21 AS build + +COPY build.gradle . +COPY settings.gradle . +COPY gradlew . +COPY gradle gradle/ +COPY app/core/build.gradle core/. +COPY app/common/build.gradle common/. +COPY app/proprietary/build.gradle proprietary/. +RUN ./gradlew build -x spotlessApply -x spotlessCheck -x test -x sonarqube || return 0 + +# Set the working directory +WORKDIR /app + +# Copy the entire project to the working directory +COPY . . + +# Build the application with DISABLE_ADDITIONAL_FEATURES=false +RUN DISABLE_ADDITIONAL_FEATURES=false \ + STIRLING_PDF_DESKTOP_UI=false \ + ./gradlew clean build -x spotlessApply -x spotlessCheck -x test -x sonarqube + +# Main stage +FROM alpine:3.22.1@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1 + +# Copy necessary files +COPY scripts /scripts +COPY pipeline /pipeline +COPY app/core/src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/ +# first /app directory is for the build stage, second is for the final image +COPY --from=build /app/app/core/build/libs/*.jar app.jar + +ARG VERSION_TAG + +LABEL org.opencontainers.image.title="Stirling-PDF Backend" +LABEL org.opencontainers.image.description="Backend service for Stirling-PDF - Java Spring Boot with PDF processing capabilities" +LABEL org.opencontainers.image.source="https://github.com/Stirling-Tools/Stirling-PDF" +LABEL org.opencontainers.image.licenses="MIT" +LABEL org.opencontainers.image.vendor="Stirling-Tools" +LABEL org.opencontainers.image.url="https://www.stirlingpdf.com" +LABEL org.opencontainers.image.documentation="https://docs.stirlingpdf.com" +LABEL maintainer="Stirling-Tools" +LABEL org.opencontainers.image.authors="Stirling-Tools" +LABEL org.opencontainers.image.version="${VERSION_TAG}" +LABEL org.opencontainers.image.keywords="PDF, manipulation, backend, API, Spring Boot" + +# Set Environment Variables +ENV DISABLE_ADDITIONAL_FEATURES=false \ + VERSION_TAG=$VERSION_TAG \ + JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \ + JAVA_CUSTOM_OPTS="" \ + HOME=/home/stirlingpdfuser \ + PUID=1000 \ + PGID=1000 \ + UMASK=022 \ + PYTHONPATH=/usr/lib/libreoffice/program:/opt/venv/lib/python3.12/site-packages \ + UNO_PATH=/usr/lib/libreoffice/program \ + URE_BOOTSTRAP=file:///usr/lib/libreoffice/program/fundamentalrc \ + PATH=$PATH:/opt/venv/bin \ + STIRLING_TEMPFILES_DIRECTORY=/tmp/stirling-pdf \ + TMPDIR=/tmp/stirling-pdf \ + TEMP=/tmp/stirling-pdf \ + TMP=/tmp/stirling-pdf + +# JDK for app and all dependencies +RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \ + echo "@community https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \ + echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \ + apk upgrade --no-cache -a && \ + apk add --no-cache \ + ca-certificates \ + tzdata \ + tini \ + bash \ + curl \ + shadow \ + su-exec \ + openssl \ + openssl-dev \ + openjdk21-jre \ + # Doc conversion + gcompat \ + libc6-compat \ + libreoffice \ + # pdftohtml + poppler-utils \ + # OCR MY PDF (unpaper for descew and other advanced features) + unpaper \ + tesseract-ocr-data-eng \ + tesseract-ocr-data-chi_sim \ + tesseract-ocr-data-deu \ + tesseract-ocr-data-fra \ + tesseract-ocr-data-por \ + ocrmypdf \ + # CV + py3-opencv \ + python3 \ + py3-pip \ + py3-pillow@testing \ + py3-pdf2image@testing && \ + python3 -m venv /opt/venv && \ + /opt/venv/bin/pip install --upgrade pip setuptools && \ + /opt/venv/bin/pip install --no-cache-dir --upgrade unoserver weasyprint && \ + ln -s /usr/lib/libreoffice/program/uno.py /opt/venv/lib/python3.12/site-packages/ && \ + ln -s /usr/lib/libreoffice/program/unohelper.py /opt/venv/lib/python3.12/site-packages/ && \ + ln -s /usr/lib/libreoffice/program /opt/venv/lib/python3.12/site-packages/LibreOffice && \ + mv /usr/share/tessdata /usr/share/tessdata-original && \ + mkdir -p $HOME /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders /tmp/stirling-pdf && \ + fc-cache -f -v && \ + chmod +x /scripts/* && \ + chmod +x /scripts/init.sh && \ + # User permissions + addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \ + chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline /tmp/stirling-pdf && \ + chown stirlingpdfuser:stirlingpdfgroup /app.jar + +EXPOSE 8080/tcp + +# Set user and run command +ENTRYPOINT ["tini", "--", "/scripts/init.sh"] +CMD ["sh", "-c", "java -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/tmp/stirling-pdf -jar /app.jar & /opt/venv/bin/unoserver --port 2003 --interface 127.0.0.1"] \ No newline at end of file diff --git a/docker/backend/Dockerfile.fat b/docker/backend/Dockerfile.fat new file mode 100644 index 000000000..33468953b --- /dev/null +++ b/docker/backend/Dockerfile.fat @@ -0,0 +1,113 @@ +# Backend fat Dockerfile - Java Spring Boot with all dependencies and build stage +# Build the application +FROM gradle:8.14-jdk21 AS build + +COPY build.gradle . +COPY settings.gradle . +COPY gradlew . +COPY gradle gradle/ +COPY app/core/build.gradle core/. +COPY app/common/build.gradle common/. +COPY app/proprietary/build.gradle proprietary/. +RUN ./gradlew build -x spotlessApply -x spotlessCheck -x test -x sonarqube || return 0 + +# Set the working directory +WORKDIR /app + +# Copy the entire project to the working directory +COPY . . + +# Build the application with DISABLE_ADDITIONAL_FEATURES=false +RUN DISABLE_ADDITIONAL_FEATURES=false \ + STIRLING_PDF_DESKTOP_UI=false \ + ./gradlew clean build -x spotlessApply -x spotlessCheck -x test -x sonarqube + +# Main stage +FROM alpine:3.22.1@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1 + +# Copy necessary files +COPY scripts /scripts +COPY pipeline /pipeline +COPY app/core/src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/ +# first /app directory is for the build stage, second is for the final image +COPY --from=build /app/app/core/build/libs/*.jar app.jar + +ARG VERSION_TAG + +# Set Environment Variables +ENV DISABLE_ADDITIONAL_FEATURES=true \ + VERSION_TAG=$VERSION_TAG \ + JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \ + JAVA_CUSTOM_OPTS="" \ + HOME=/home/stirlingpdfuser \ + PUID=1000 \ + PGID=1000 \ + UMASK=022 \ + FAT_DOCKER=true \ + INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false \ + PYTHONPATH=/usr/lib/libreoffice/program:/opt/venv/lib/python3.12/site-packages \ + UNO_PATH=/usr/lib/libreoffice/program \ + URE_BOOTSTRAP=file:///usr/lib/libreoffice/program/fundamentalrc \ + PATH=$PATH:/opt/venv/bin \ + STIRLING_TEMPFILES_DIRECTORY=/tmp/stirling-pdf \ + TMPDIR=/tmp/stirling-pdf \ + TEMP=/tmp/stirling-pdf \ + TMP=/tmp/stirling-pdf + +# JDK for app +RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \ + echo "@community https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \ + echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \ + apk upgrade --no-cache -a && \ + apk add --no-cache \ + ca-certificates \ + tzdata \ + tini \ + bash \ + curl \ + shadow \ + su-exec \ + openssl \ + openssl-dev \ + openjdk21-jre \ + # Doc conversion + gcompat \ + libc6-compat \ + libreoffice \ + # pdftohtml + poppler-utils \ + # OCR MY PDF (unpaper for descew and other advanced featues) + unpaper \ + tesseract-ocr-data-eng \ + tesseract-ocr-data-chi_sim \ + tesseract-ocr-data-deu \ + tesseract-ocr-data-fra \ + tesseract-ocr-data-por \ + ocrmypdf \ + font-terminus font-dejavu font-noto font-noto-cjk font-awesome font-noto-extra font-liberation font-linux-libertine \ + # CV + py3-opencv \ + python3 \ + py3-pip \ + py3-pillow@testing \ + py3-pdf2image@testing && \ + python3 -m venv /opt/venv && \ + /opt/venv/bin/pip install --upgrade pip setuptools && \ + /opt/venv/bin/pip install --no-cache-dir --upgrade unoserver weasyprint && \ + ln -s /usr/lib/libreoffice/program/uno.py /opt/venv/lib/python3.12/site-packages/ && \ + ln -s /usr/lib/libreoffice/program/unohelper.py /opt/venv/lib/python3.12/site-packages/ && \ + ln -s /usr/lib/libreoffice/program /opt/venv/lib/python3.12/site-packages/LibreOffice && \ + mv /usr/share/tessdata /usr/share/tessdata-original && \ + mkdir -p $HOME /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders /tmp/stirling-pdf && \ + fc-cache -f -v && \ + chmod +x /scripts/* && \ + chmod +x /scripts/init.sh && \ + # User permissions + addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \ + chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline /tmp/stirling-pdf && \ + chown stirlingpdfuser:stirlingpdfgroup /app.jar + +EXPOSE 8080/tcp +# Set user and run command +ENTRYPOINT ["tini", "--", "/scripts/init.sh"] +CMD ["sh", "-c", "java -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/tmp/stirling-pdf -jar /app.jar & /opt/venv/bin/unoserver --port 2003 --interface 127.0.0.1"] \ No newline at end of file diff --git a/docker/backend/Dockerfile.ultra-lite b/docker/backend/Dockerfile.ultra-lite new file mode 100644 index 000000000..426d5b410 --- /dev/null +++ b/docker/backend/Dockerfile.ultra-lite @@ -0,0 +1,78 @@ +# Backend ultra-lite Dockerfile - Java Spring Boot with minimal dependencies and build stage +# Build the application +FROM gradle:8.14-jdk21 AS build + +COPY build.gradle . +COPY settings.gradle . +COPY gradlew . +COPY gradle gradle/ +COPY app/core/build.gradle core/. +COPY app/common/build.gradle common/. +COPY app/proprietary/build.gradle proprietary/. +RUN ./gradlew build -x spotlessApply -x spotlessCheck -x test -x sonarqube || return 0 + +# Set the working directory +WORKDIR /app + +# Copy the entire project to the working directory +COPY . . + +# Build the application with DISABLE_ADDITIONAL_FEATURES=true +RUN DISABLE_ADDITIONAL_FEATURES=true \ + STIRLING_PDF_DESKTOP_UI=false \ + ./gradlew clean build -x spotlessApply -x spotlessCheck -x test -x sonarqube + +# Main stage +FROM alpine:3.22.1@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1 + +ARG VERSION_TAG + +# Set Environment Variables +ENV DISABLE_ADDITIONAL_FEATURES=true \ + HOME=/home/stirlingpdfuser \ + VERSION_TAG=$VERSION_TAG \ + JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \ + JAVA_CUSTOM_OPTS="" \ + PUID=1000 \ + PGID=1000 \ + UMASK=022 \ + STIRLING_TEMPFILES_DIRECTORY=/tmp/stirling-pdf \ + TMPDIR=/tmp/stirling-pdf \ + TEMP=/tmp/stirling-pdf \ + TMP=/tmp/stirling-pdf + +# Copy necessary files +COPY scripts/init-without-ocr.sh /scripts/init-without-ocr.sh +COPY scripts/installFonts.sh /scripts/installFonts.sh +COPY pipeline /pipeline +COPY --from=build /app/app/core/build/libs/*.jar app.jar + +# Set up necessary directories and permissions +RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \ + echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \ + echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \ + apk upgrade --no-cache -a && \ + apk add --no-cache \ + ca-certificates \ + tzdata \ + tini \ + bash \ + curl \ + shadow \ + su-exec \ + openjdk21-jre && \ + # User permissions + mkdir -p /configs /logs /customFiles /usr/share/fonts/opentype/noto /tmp/stirling-pdf && \ + chmod +x /scripts/*.sh && \ + addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \ + chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /configs /customFiles /pipeline /tmp/stirling-pdf && \ + chown stirlingpdfuser:stirlingpdfgroup /app.jar + +# Set environment variables +ENV ENDPOINTS_GROUPS_TO_REMOVE=CLI + +EXPOSE 8080/tcp + +# Run the application +ENTRYPOINT ["tini", "--", "/scripts/init-without-ocr.sh"] +CMD ["java", "-Dfile.encoding=UTF-8", "-Djava.io.tmpdir=/tmp/stirling-pdf", "-jar", "/app.jar"] diff --git a/docker/compose/docker-compose.fat.yml b/docker/compose/docker-compose.fat.yml new file mode 100644 index 000000000..1757782d5 --- /dev/null +++ b/docker/compose/docker-compose.fat.yml @@ -0,0 +1,62 @@ +services: + backend: + build: + context: ../.. + dockerfile: docker/backend/Dockerfile.fat + container_name: stirling-pdf-backend-fat + restart: on-failure:5 + deploy: + resources: + limits: + memory: 6G + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP'"] + interval: 5s + timeout: 10s + retries: 16 + ports: + - "8080:8080" # TODO: Remove in production - for debugging only + expose: + - "8080" + volumes: + - ../../stirling/latest/data:/usr/share/tessdata:rw + - ../../stirling/latest/config:/configs:rw + - ../../stirling/latest/logs:/logs:rw + environment: + DISABLE_ADDITIONAL_FEATURES: "false" + SECURITY_ENABLELOGIN: "false" + FAT_DOCKER: "true" + SYSTEM_DEFAULTLOCALE: en-US + UI_APPNAME: Stirling-PDF + UI_HOMEDESCRIPTION: Full-featured Stirling-PDF with all capabilities + UI_APPNAMENAVBAR: Stirling-PDF Fat + SYSTEM_MAXFILESIZE: "200" + METRICS_ENABLED: "true" + SYSTEM_GOOGLEVISIBILITY: "true" + SHOW_SURVEY: "true" + networks: + - stirling-network + + frontend: + build: + context: ../.. + dockerfile: docker/frontend/Dockerfile + container_name: stirling-pdf-frontend-fat + restart: on-failure:5 + ports: + - "3000:80" + environment: + BACKEND_URL: http://backend:8080 + depends_on: + - backend + networks: + - stirling-network + +networks: + stirling-network: + driver: bridge + +volumes: + stirling-data: + stirling-config: + stirling-logs: diff --git a/docker/compose/docker-compose.ultra-lite.yml b/docker/compose/docker-compose.ultra-lite.yml new file mode 100644 index 000000000..bfbf55861 --- /dev/null +++ b/docker/compose/docker-compose.ultra-lite.yml @@ -0,0 +1,54 @@ +services: + backend: + build: + context: ../.. + dockerfile: docker/backend/Dockerfile.ultra-lite + container_name: stirling-pdf-backend-ultra-lite + restart: on-failure:5 + deploy: + resources: + limits: + memory: 2G + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP'"] + interval: 5s + timeout: 10s + retries: 16 + ports: + - "8080:8080" # TODO: Remove in production - for debugging only + expose: + - "8080" + volumes: + - ../../stirling/latest/config:/configs:rw + - ../../stirling/latest/logs:/logs:rw + environment: + DISABLE_ADDITIONAL_FEATURES: "true" + SECURITY_ENABLELOGIN: "false" + ENDPOINTS_GROUPS_TO_REMOVE: "CLI" + LANGS: "en_GB,en_US" + SYSTEM_DEFAULTLOCALE: en-US + UI_APPNAME: Stirling-PDF + UI_HOMEDESCRIPTION: Ultra-lite version of Stirling-PDF + UI_APPNAMENAVBAR: Stirling-PDF Ultra-lite + SYSTEM_MAXFILESIZE: "50" + networks: + - stirling-network + + frontend: + build: + context: ../.. + dockerfile: docker/frontend/Dockerfile + container_name: stirling-pdf-frontend-ultra-lite + restart: on-failure:5 + ports: + - "3000:80" + environment: + BACKEND_URL: http://backend:8080 + depends_on: + - backend + networks: + - stirling-network + +networks: + stirling-network: + driver: bridge \ No newline at end of file diff --git a/docker/compose/docker-compose.yml b/docker/compose/docker-compose.yml new file mode 100644 index 000000000..b0061f785 --- /dev/null +++ b/docker/compose/docker-compose.yml @@ -0,0 +1,61 @@ +services: + backend: + build: + context: ../.. + dockerfile: docker/backend/Dockerfile + container_name: stirling-pdf-backend + restart: on-failure:5 + deploy: + resources: + limits: + memory: 4G + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP'"] + interval: 5s + timeout: 10s + retries: 16 + ports: + - "8080:8080" # TODO: Remove in production - for debugging only + expose: + - "8080" + volumes: + - ../../stirling/latest/data:/usr/share/tessdata:rw + - ../../stirling/latest/config:/configs:rw + - ../../stirling/latest/logs:/logs:rw + environment: + DISABLE_ADDITIONAL_FEATURES: "true" + SECURITY_ENABLELOGIN: "false" + SYSTEM_DEFAULTLOCALE: en-US + UI_APPNAME: Stirling-PDF + UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest + UI_APPNAMENAVBAR: Stirling-PDF Latest + SYSTEM_MAXFILESIZE: "100" + METRICS_ENABLED: "true" + SYSTEM_GOOGLEVISIBILITY: "true" + SHOW_SURVEY: "true" + networks: + - stirling-network + + frontend: + build: + context: ../.. + dockerfile: docker/frontend/Dockerfile + container_name: stirling-pdf-frontend + restart: on-failure:5 + ports: + - "3000:80" + environment: + BACKEND_URL: http://backend:8080 + depends_on: + - backend + networks: + - stirling-network + +networks: + stirling-network: + driver: bridge + +volumes: + stirling-data: + stirling-config: + stirling-logs: diff --git a/docker/frontend/Dockerfile b/docker/frontend/Dockerfile new file mode 100644 index 000000000..a220782b0 --- /dev/null +++ b/docker/frontend/Dockerfile @@ -0,0 +1,38 @@ +# Frontend Dockerfile - React/Vite application +FROM node:20-alpine AS build + +WORKDIR /app + +# Copy package files +COPY frontend/package*.json ./ + +# Install dependencies +RUN npm ci + +# Copy source code +COPY frontend . + +# Build the application +RUN npm run build + +# Production stage +FROM nginx:alpine + +# Copy built files from build stage +COPY --from=build /app/dist /usr/share/nginx/html + +# Copy nginx configuration and entrypoint +COPY docker/frontend/nginx.conf /etc/nginx/nginx.conf +COPY docker/frontend/entrypoint.sh /entrypoint.sh + +# Make entrypoint executable +RUN chmod +x /entrypoint.sh + +# Expose port 80 (standard HTTP port) +EXPOSE 80 + +# Environment variables for flexibility +ENV VITE_API_BASE_URL=http://backend:8080 + +# Use custom entrypoint +ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file diff --git a/docker/frontend/entrypoint.sh b/docker/frontend/entrypoint.sh new file mode 100644 index 000000000..a81272969 --- /dev/null +++ b/docker/frontend/entrypoint.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# Set default backend URL if not provided +VITE_API_BASE_URL=${VITE_API_BASE_URL:-"http://backend:8080"} + +# Replace the placeholder in nginx.conf with the actual backend URL +sed -i "s|\${VITE_API_BASE_URL}|${VITE_API_BASE_URL}|g" /etc/nginx/nginx.conf + +# Start nginx +exec nginx -g "daemon off;" \ No newline at end of file diff --git a/docker/frontend/nginx.conf b/docker/frontend/nginx.conf new file mode 100644 index 000000000..af4ca85f2 --- /dev/null +++ b/docker/frontend/nginx.conf @@ -0,0 +1,105 @@ +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # Gzip compression + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json; + + server { + listen 80; + server_name _; + root /usr/share/nginx/html; + index index.html index.htm; + + # Global settings for file uploads + client_max_body_size 100m; + + # Handle client-side routing - support subpaths + location / { + try_files $uri $uri/ /index.html; + } + + # Proxy API calls to backend + location /api/ { + proxy_pass ${VITE_API_BASE_URL}/api/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + + # Additional headers for proper API proxying + proxy_set_header Connection ''; + proxy_http_version 1.1; + proxy_buffering off; + proxy_cache off; + + # Timeout settings for large file uploads + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + + # Request size limits for file uploads + client_max_body_size 100m; + proxy_request_buffering off; + } + + # Proxy Swagger UI to backend (including versioned paths) + location ~ ^/swagger-ui(.*)$ { + proxy_pass ${VITE_API_BASE_URL}/swagger-ui$1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + + proxy_set_header Connection ''; + proxy_http_version 1.1; + proxy_buffering off; + proxy_cache off; + } + + # Proxy API docs to backend (with query parameters and sub-paths) + location ~ ^/v3/api-docs(.*)$ { + proxy_pass ${VITE_API_BASE_URL}/v3/api-docs$1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + } + + # Proxy v1 API docs to backend (with query parameters and sub-paths) + location ~ ^/v1/api-docs(.*)$ { + proxy_pass ${VITE_API_BASE_URL}/v1/api-docs$1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + } + + # Cache static assets + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # Security headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + } +} \ No newline at end of file diff --git a/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml b/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml deleted file mode 100644 index 827de1e19..000000000 --- a/exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml +++ /dev/null @@ -1,36 +0,0 @@ - -services: - stirling-pdf: - container_name: Stirling-PDF-Fat-Disable-Endpoints - image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest-fat - deploy: - resources: - limits: - memory: 4G - healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP'"] - interval: 5s - timeout: 10s - retries: 16 - ports: - - 8080:8080 - volumes: - - ./stirling/latest/data:/usr/share/tessdata:rw - - ./stirling/latest/config:/configs:rw - - ./stirling/latest/logs:/logs:rw - - ../testing/allEndpointsRemovedSettings.yml:/configs/settings.yml:rw - environment: - DISABLE_ADDITIONAL_FEATURES: "false" - SECURITY_ENABLELOGIN: "false" - PUID: 1002 - PGID: 1002 - UMASK: "022" - SYSTEM_DEFAULTLOCALE: en-US - UI_APPNAME: Stirling-PDF - UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest-fat with all Endpoints Disabled - UI_APPNAMENAVBAR: Stirling-PDF Latest-fat - SYSTEM_MAXFILESIZE: "100" - METRICS_ENABLED: "true" - SYSTEM_GOOGLEVISIBILITY: "true" - SHOW_SURVEY: "true" - restart: on-failure:5 diff --git a/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml b/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml deleted file mode 100644 index bbf8a2115..000000000 --- a/exampleYmlFiles/docker-compose-latest-fat-security-postgres.yml +++ /dev/null @@ -1,64 +0,0 @@ -services: - stirling-pdf: - container_name: Stirling-PDF-Security-Fat-Postgres - image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest-fat-postgres - deploy: - resources: - limits: - memory: 4G - depends_on: - - db - healthcheck: - test: [ "CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP'" ] - interval: 5s - timeout: 10s - retries: 16 - ports: - - 8080:8080 - volumes: - - ./stirling/latest/data:/usr/share/tessdata:rw - - ./stirling/latest/config:/configs:rw - - ./stirling/latest/logs:/logs:rw - environment: - DISABLE_ADDITIONAL_FEATURES: "false" - SECURITY_ENABLELOGIN: "false" - PUID: 1002 - PGID: 1002 - UMASK: "022" - SYSTEM_DEFAULTLOCALE: en-US - UI_APPNAME: Stirling-PDF - UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest-fat with Security and PostgreSQL - UI_APPNAMENAVBAR: Stirling-PDF Latest-fat-PostgreSQL - SYSTEM_MAXFILESIZE: "100" - METRICS_ENABLED: "true" - SYSTEM_GOOGLEVISIBILITY: "true" - SYSTEM_DATASOURCE_ENABLECUSTOMDATABASE: "true" - SYSTEM_DATASOURCE_CUSTOMDATABASEURL: "jdbc:postgresql://db:5432/stirling_pdf" - SYSTEM_DATASOURCE_USERNAME: "admin" - SYSTEM_DATASOURCE_PASSWORD: "stirling" - SHOW_SURVEY: "true" - restart: on-failure:5 - - db: - image: 'postgres:17.2-alpine' - restart: on-failure:5 - container_name: db - ports: - - "5432:5432" - environment: - POSTGRES_DB: "stirling_pdf" - POSTGRES_USER: "admin" - POSTGRES_PASSWORD: "stirling" - shm_size: "512mb" - deploy: - resources: - limits: - memory: 512m - cpus: "0.5" - healthcheck: - test: [ "CMD-SHELL", "pg_isready -U admin stirling_pdf" ] - interval: 1s - timeout: 5s - retries: 10 - volumes: - - ./stirling/latest/data:/pgdata diff --git a/exampleYmlFiles/docker-compose-latest-fat-security.yml b/exampleYmlFiles/docker-compose-latest-fat-security.yml deleted file mode 100644 index 5b07420ff..000000000 --- a/exampleYmlFiles/docker-compose-latest-fat-security.yml +++ /dev/null @@ -1,34 +0,0 @@ -services: - stirling-pdf: - container_name: Stirling-PDF-Security-Fat - image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest-fat - deploy: - resources: - limits: - memory: 4G - healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP'"] - interval: 5s - timeout: 10s - retries: 16 - ports: - - 8080:8080 - volumes: - - ./stirling/latest/data:/usr/share/tessdata:rw - - ./stirling/latest/config:/configs:rw - - ./stirling/latest/logs:/logs:rw - environment: - DISABLE_ADDITIONAL_FEATURES: "false" - SECURITY_ENABLELOGIN: "false" - PUID: 1002 - PGID: 1002 - UMASK: "022" - SYSTEM_DEFAULTLOCALE: en-US - UI_APPNAME: Stirling-PDF - UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest-fat with Security - UI_APPNAMENAVBAR: Stirling-PDF Latest-fat - SYSTEM_MAXFILESIZE: "100" - METRICS_ENABLED: "true" - SYSTEM_GOOGLEVISIBILITY: "true" - SHOW_SURVEY: "true" - restart: on-failure:5 diff --git a/exampleYmlFiles/docker-compose-latest-security-with-sso.yml b/exampleYmlFiles/docker-compose-latest-security-with-sso.yml deleted file mode 100644 index 55ea0893d..000000000 --- a/exampleYmlFiles/docker-compose-latest-security-with-sso.yml +++ /dev/null @@ -1,42 +0,0 @@ -services: - stirling-pdf: - container_name: Stirling-PDF-Security - image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest - deploy: - resources: - limits: - memory: 4G - healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -q 'Please sign in'"] - interval: 5s - timeout: 10s - retries: 16 - ports: - - "8080:8080" - volumes: - - ./stirling/latest/data:/usr/share/tessdata:rw - - ./stirling/latest/config:/configs:rw - - ./stirling/latest/logs:/logs:rw - environment: - DISABLE_ADDITIONAL_FEATURES: "false" - SECURITY_ENABLELOGIN: "true" - SECURITY_OAUTH2_ENABLED: "true" - SECURITY_OAUTH2_AUTOCREATEUSER: "true" # This is set to true to allow auto-creation of non-existing users in Stirling-PDF - SECURITY_OAUTH2_ISSUER: "https://accounts.google.com" # Change with any other provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) end-point - SECURITY_OAUTH2_CLIENTID: ".apps.googleusercontent.com" # Client ID from your provider - SECURITY_OAUTH2_CLIENTSECRET: "" # Client Secret from your provider - SECURITY_OAUTH2_SCOPES: "openid,profile,email" # Expected OAuth2 Scope - SECURITY_OAUTH2_USEASUSERNAME: "email" # Default is 'email'; custom fields can be used as the username - SECURITY_OAUTH2_PROVIDER: "google" # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak' - PUID: 1002 - PGID: 1002 - UMASK: "022" - SYSTEM_DEFAULTLOCALE: en-US - UI_APPNAME: Stirling-PDF - UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest with Security - UI_APPNAMENAVBAR: Stirling-PDF Latest - SYSTEM_MAXFILESIZE: "100" - METRICS_ENABLED: "true" - SYSTEM_GOOGLEVISIBILITY: "true" - SHOW_SURVEY: "true" - restart: on-failure:5 diff --git a/exampleYmlFiles/docker-compose-latest-security.yml b/exampleYmlFiles/docker-compose-latest-security.yml deleted file mode 100644 index c6589ab9c..000000000 --- a/exampleYmlFiles/docker-compose-latest-security.yml +++ /dev/null @@ -1,34 +0,0 @@ -services: - stirling-pdf: - container_name: Stirling-PDF-Security - image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest - deploy: - resources: - limits: - memory: 4G - healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -q 'Please sign in'"] - interval: 5s - timeout: 10s - retries: 16 - ports: - - "8080:8080" - volumes: - - ./stirling/latest/data:/usr/share/tessdata:rw - - ./stirling/latest/config:/configs:rw - - ./stirling/latest/logs:/logs:rw - environment: - DISABLE_ADDITIONAL_FEATURES: "false" - SECURITY_ENABLELOGIN: "true" - PUID: 1002 - PGID: 1002 - UMASK: "022" - SYSTEM_DEFAULTLOCALE: en-US - UI_APPNAME: Stirling-PDF - UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest with Security - UI_APPNAMENAVBAR: Stirling-PDF Latest - SYSTEM_MAXFILESIZE: "100" - METRICS_ENABLED: "true" - SYSTEM_GOOGLEVISIBILITY: "true" - SHOW_SURVEY: "true" - restart: on-failure:5 diff --git a/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml b/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml deleted file mode 100644 index fe839d941..000000000 --- a/exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml +++ /dev/null @@ -1,31 +0,0 @@ -services: - stirling-pdf: - container_name: Stirling-PDF-Ultra-Lite-Security - image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest-ultra-lite - deploy: - resources: - limits: - memory: 1G - healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -q 'Please sign in'"] - interval: 5s - timeout: 10s - retries: 16 - ports: - - "8080:8080" - volumes: - - ./stirling/latest/data:/usr/share/tessdata:rw - - ./stirling/latest/config:/configs:rw - - ./stirling/latest/logs:/logs:rw - environment: - DISABLE_ADDITIONAL_FEATURES: "false" - SECURITY_ENABLELOGIN: "true" - SYSTEM_DEFAULTLOCALE: en-US - UI_APPNAME: Stirling-PDF-Lite - UI_HOMEDESCRIPTION: Demo site for Stirling-PDF-Lite Latest with Security - UI_APPNAMENAVBAR: Stirling-PDF-Lite Latest - SYSTEM_MAXFILESIZE: "100" - METRICS_ENABLED: "true" - SYSTEM_GOOGLEVISIBILITY: "true" - SHOW_SURVEY: "true" - restart: on-failure:5 diff --git a/exampleYmlFiles/docker-compose-latest.yml b/exampleYmlFiles/docker-compose-latest.yml deleted file mode 100644 index a68da538a..000000000 --- a/exampleYmlFiles/docker-compose-latest.yml +++ /dev/null @@ -1,31 +0,0 @@ -services: - stirling-pdf: - container_name: Stirling-PDF - image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest - deploy: - resources: - limits: - memory: 4G - healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -qv 'Please sign in'"] - interval: 5s - timeout: 10s - retries: 16 - ports: - - "8080:8080" - volumes: - - ./stirling/latest/data:/usr/share/tessdata:rw - - ./stirling/latest/config:/configs:rw - - ./stirling/latest/logs:/logs:rw - environment: - SECURITY_ENABLELOGIN: "false" - LANGS: "en_GB,en_US,ar_AR,de_DE,fr_FR,es_ES,zh_CN,zh_TW,ca_CA,it_IT,sv_SE,pl_PL,ro_RO,ko_KR,pt_BR,ru_RU,el_GR,hi_IN,hu_HU,tr_TR,id_ID" - SYSTEM_DEFAULTLOCALE: en-US - UI_APPNAME: Stirling-PDF - UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest - UI_APPNAMENAVBAR: Stirling-PDF Latest - SYSTEM_MAXFILESIZE: "100" - METRICS_ENABLED: "true" - SYSTEM_GOOGLEVISIBILITY: "true" - SHOW_SURVEY: "true" - restart: on-failure:5 diff --git a/exampleYmlFiles/test_cicd.yml b/exampleYmlFiles/test_cicd.yml deleted file mode 100644 index 31e24da48..000000000 --- a/exampleYmlFiles/test_cicd.yml +++ /dev/null @@ -1,34 +0,0 @@ -services: - stirling-pdf: - container_name: Stirling-PDF-Security-Fat-with-login - image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest-fat - deploy: - resources: - limits: - memory: 4G - healthcheck: - test: ["CMD-SHELL", "curl -f -H 'X-API-KEY: 123456789' http://localhost:8080/api/v1/info/status | grep -q 'UP'"] - interval: 5s - timeout: 10s - retries: 16 - ports: - - 8080:8080 - volumes: - - ./stirling/latest/data:/usr/share/tessdata:rw - - ./stirling/latest/config:/configs:rw - - ./stirling/latest/logs:/logs:rw - environment: - DISABLE_ADDITIONAL_FEATURES: "false" - SECURITY_ENABLELOGIN: "true" - PUID: 1002 - PGID: 1002 - UMASK: "022" - SYSTEM_DEFAULTLOCALE: en-US - UI_APPNAME: Stirling-PDF - UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest-fat with Security - UI_APPNAMENAVBAR: Stirling-PDF Latest-fat - SYSTEM_MAXFILESIZE: "100" - METRICS_ENABLED: "true" - SYSTEM_GOOGLEVISIBILITY: "true" - SECURITY_CUSTOMGLOBALAPIKEY: "123456789" - restart: on-failure:5 diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 000000000..8b055b7a6 --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,27 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build +/dist + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +playwright-report +test-results \ No newline at end of file diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 000000000..115fcca84 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,74 @@ +# Getting Started with Create React App + +This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). + +## Docker Setup + +For Docker deployments and configuration, see the [Docker README](../docker/README.md). + +## Available Scripts + +In the project directory, you can run: + +### `npm start` + +Runs the app in the development mode.\ +Open [http://localhost:3000](http://localhost:3000) to view it in your browser. + +The page will reload when you make changes.\ +You may also see any lint errors in the console. + +### `npm test` + +Launches the test runner in the interactive watch mode.\ +See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. + +### `npm run build` + +Builds the app for production to the `build` folder.\ +It correctly bundles React in production mode and optimizes the build for the best performance. + +The build is minified and the filenames include the hashes.\ +Your app is ready to be deployed! + +See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. + +### `npm run eject` + +**Note: this is a one-way operation. Once you `eject`, you can't go back!** + +If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. + +Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. + +You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. + +## Learn More + +You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). + +To learn React, check out the [React documentation](https://reactjs.org/). + +### Code Splitting + +This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) + +### Analyzing the Bundle Size + +This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) + +### Making a Progressive Web App + +This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) + +### Advanced Configuration + +This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) + +### Deployment + +This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) + +### `npm run build` fails to minify + +This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 000000000..c4a808349 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,22 @@ + + + + + + + + + + + + Stirling PDF + + + +
+ + + diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 000000000..060a51d64 --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,8965 @@ +{ + "name": "frontend", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "0.1.0", + "license": "SEE LICENSE IN https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/proprietary/LICENSE", + "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", + "@mantine/core": "^8.0.1", + "@mantine/dropzone": "^8.0.1", + "@mantine/hooks": "^8.0.1", + "@mui/icons-material": "^7.1.0", + "@mui/material": "^7.1.0", + "@tailwindcss/postcss": "^4.1.8", + "@testing-library/dom": "^10.4.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.3.0", + "@testing-library/user-event": "^13.5.0", + "autoprefixer": "^10.4.21", + "axios": "^1.9.0", + "i18next": "^25.2.1", + "i18next-browser-languagedetector": "^8.1.0", + "i18next-http-backend": "^3.0.2", + "jszip": "^3.10.1", + "material-symbols": "^0.33.0", + "pdf-lib": "^1.17.1", + "pdfjs-dist": "^3.11.174", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "react-i18next": "^15.5.2", + "react-router-dom": "^7.6.0", + "tailwindcss": "^4.1.8", + "web-vitals": "^2.1.4" + }, + "devDependencies": { + "@playwright/test": "^1.40.0", + "@types/react": "^19.1.4", + "@types/react-dom": "^19.1.5", + "@vitejs/plugin-react": "^4.5.0", + "@vitest/coverage-v8": "^1.0.0", + "jsdom": "^23.0.0", + "license-checker": "^25.0.1", + "postcss": "^8.5.3", + "postcss-cli": "^11.0.1", + "postcss-preset-mantine": "^1.17.0", + "postcss-simple-vars": "^7.0.1", + "typescript": "^5.8.3", + "vite": "^6.3.5", + "vitest": "^1.0.0" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.2.tgz", + "integrity": "sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==", + "license": "MIT" + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-2.0.2.tgz", + "integrity": "sha512-x1KXOatwofR6ZAYzXRBL5wrdV0vwNxlTCK9NCuLqAzQYARqGcvFwiJA6A1ERuh+dgeA4Dxm3JBYictIes+SqUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bidi-js": "^1.0.3", + "css-tree": "^2.3.1", + "is-potential-custom-element-name": "^1.0.1" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.3.tgz", + "integrity": "sha512-V42wFfx1ymFte+ecf6iXghnnP8kWTO+ZLXIyZq+1LAXHHvTZdVxicn4yiVYdYMGaCO3tmqub11AorKkv+iodqw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.3.tgz", + "integrity": "sha512-hyrN8ivxfvJ4i0fIJuV4EOlV0WDMz5Ui4StRTgVaAvWeiRCilXgwVvxJKtFQ3TKtHgJscB2YiXKGNJuVwhQMtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.3", + "@babel/parser": "^7.27.3", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.27.3", + "@babel/types": "^7.27.3", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.3.tgz", + "integrity": "sha512-xnlJYj5zepml8NXtjkG0WquFUv8RskFqyFcVgTBp5k+NaA/8uw/K+OSVf8AMGw5e9HKP2ETd5xpK5MLZQD6b4Q==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.3", + "@babel/types": "^7.27.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.3.tgz", + "integrity": "sha512-h/eKy9agOya1IGuLaZ9tEUgz+uIRXcbtOhRtUyyMf8JFmn1iT13vnl/IGVWSkdOCG/pC57U4S1jnAabAavTMwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.3.tgz", + "integrity": "sha512-xyYxRj6+tLNDTWi0KCBcZ9V7yg3/lwL9DWh9Uwh/RIVlIfFidggcgxKX3GCXwCiswwcGRawBKbEg2LG/Y8eJhw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz", + "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.3.tgz", + "integrity": "sha512-lId/IfN/Ye1CIu8xG7oKBHXd2iNb2aW1ilPszzGcJug6M8RCKfVNcYhpI5+bMvFYjK7lXIM0R+a+6r8xhHp2FQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/parser": "^7.27.3", + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.3", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.3.tgz", + "integrity": "sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@csstools/color-helpers": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", + "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.10.tgz", + "integrity": "sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.0.2", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.3.3", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz", + "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.0.tgz", + "integrity": "sha512-FRdBLykrPPA6P76GGGqlex/e7fbe0F1ykgxHYNXQsH/iTEtjMj/f9bpY5oQqbjt5VgZvgz/uKXbGuROijh3VLA==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.0.tgz", + "integrity": "sha512-lGTor4VlXcesUMh1cupTUTDoCxMb0V6bm3CnxHzQcw8Eaf1jQbgQX4i02fYgT0vJ82tb5MZ4CZk1LRGkktJCzg==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.0", + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.28", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.28.tgz", + "integrity": "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.1.2", + "@floating-ui/utils": "^0.2.8", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", + "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", + "license": "MIT" + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mantine/core": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-8.0.1.tgz", + "integrity": "sha512-4ezaxKjChSPtawamQ3KrJq+x506uTouXlL0Z5fP+t105KnyxMrAJUENhbh2ivD4pq9Zh1BFiD9IWzyu3IXFR8w==", + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.26.28", + "clsx": "^2.1.1", + "react-number-format": "^5.4.3", + "react-remove-scroll": "^2.6.2", + "react-textarea-autosize": "8.5.9", + "type-fest": "^4.27.0" + }, + "peerDependencies": { + "@mantine/hooks": "8.0.1", + "react": "^18.x || ^19.x", + "react-dom": "^18.x || ^19.x" + } + }, + "node_modules/@mantine/dropzone": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@mantine/dropzone/-/dropzone-8.0.1.tgz", + "integrity": "sha512-8PH5yrtA/ebCIwjs0m4J9qOvEyS/P4XmNlHrw0E389/qq64Ol7+/ZH7Xtiq64IaY8kvsMW1XHaV0c+bdYrijiA==", + "license": "MIT", + "dependencies": { + "react-dropzone": "14.3.8" + }, + "peerDependencies": { + "@mantine/core": "8.0.1", + "@mantine/hooks": "8.0.1", + "react": "^18.x || ^19.x", + "react-dom": "^18.x || ^19.x" + } + }, + "node_modules/@mantine/hooks": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-8.0.1.tgz", + "integrity": "sha512-GvLdM4Ro3QcDyIgqrdXsUZmeeKye2TNL/k3mEr9JhM5KacHQjr83JPp0u9eLobn7kiyBqpLTYmVYAbmjJdCxHw==", + "license": "MIT", + "peerDependencies": { + "react": "^18.x || ^19.x" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.1.0.tgz", + "integrity": "sha512-E0OqhZv548Qdc0PwWhLVA2zmjJZSTvaL4ZhoswmI8NJEC1tpW2js6LLP827jrW9MEiXYdz3QS6+hask83w74yQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.1.0.tgz", + "integrity": "sha512-1mUPMAZ+Qk3jfgL5ftRR06ATH/Esi0izHl1z56H+df6cwIlCWG66RXciUqeJCttbOXOQ5y2DCjLZI/4t3Yg3LA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^7.1.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.1.0.tgz", + "integrity": "sha512-ahUJdrhEv+mCp4XHW+tHIEYzZMSRLg8z4AjUOsj44QpD1ZaMxQoVOG2xiHvLFdcsIPbgSRx1bg1eQSheHBgvtg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1", + "@mui/core-downloads-tracker": "^7.1.0", + "@mui/system": "^7.1.0", + "@mui/types": "^7.4.2", + "@mui/utils": "^7.1.0", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.12", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^19.1.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material-pigment-css": "^7.1.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@mui/material-pigment-css": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.1.0.tgz", + "integrity": "sha512-4Kck4jxhqF6YxNwJdSae1WgDfXVg0lIH6JVJ7gtuFfuKcQCgomJxPvUEOySTFRPz1IZzwz5OAcToskRdffElDA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1", + "@mui/utils": "^7.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.1.0.tgz", + "integrity": "sha512-m0mJ0c6iRC+f9hMeRe0W7zZX1wme3oUX0+XTVHjPG7DJz6OdQ6K/ggEOq7ZdwilcpdsDUwwMfOmvO71qDkYd2w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1", + "@emotion/cache": "^11.13.5", + "@emotion/serialize": "^1.3.3", + "@emotion/sheet": "^1.4.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.1.0.tgz", + "integrity": "sha512-iedAWgRJMCxeMHvkEhsDlbvkK+qKf9me6ofsf7twk/jfT4P1ImVf7Rwb5VubEA0sikrVL+1SkoZM41M4+LNAVA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1", + "@mui/private-theming": "^7.1.0", + "@mui/styled-engine": "^7.1.0", + "@mui/types": "^7.4.2", + "@mui/utils": "^7.1.0", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.2.tgz", + "integrity": "sha512-edRc5JcLPsrlNFYyTPxds+d5oUovuUxnnDtpJUbP6WMeV4+6eaX/mqai1ZIWT62lCOe0nlrON0s9HDiv5en5bA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.1.0.tgz", + "integrity": "sha512-/OM3S8kSHHmWNOP+NH9xEtpYSG10upXeQ0wLZnfDgmgadTAk5F4MQfFLyZ5FCRJENB3eRzltMmaNl6UtDnPovw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.1", + "@mui/types": "^7.4.2", + "@types/prop-types": "^15.7.14", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.1.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pdf-lib/standard-fonts": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz", + "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==", + "dependencies": { + "pako": "^1.0.6" + } + }, + "node_modules/@pdf-lib/upng": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz", + "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==", + "dependencies": { + "pako": "^1.0.10" + } + }, + "node_modules/@playwright/test": { + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.54.1.tgz", + "integrity": "sha512-FS8hQ12acieG2dYSksmLOF7BNxnVf2afRJdCuM1eMSxj6QTSE6G4InGF7oApGgDb65MX7AwMVlIkpru0yZA4Xw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.54.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.9", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.9.tgz", + "integrity": "sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.1.tgz", + "integrity": "sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.1.tgz", + "integrity": "sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.1.tgz", + "integrity": "sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.1.tgz", + "integrity": "sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.1.tgz", + "integrity": "sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.1.tgz", + "integrity": "sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.1.tgz", + "integrity": "sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.1.tgz", + "integrity": "sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.1.tgz", + "integrity": "sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.1.tgz", + "integrity": "sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.1.tgz", + "integrity": "sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.1.tgz", + "integrity": "sha512-3mr3Xm+gvMX+/8EKogIZSIEF0WUu0HL9di+YWlJpO8CQBnoLAEL/roTCxuLncEdgcfJcvA4UMOf+2dnjl4Ut1A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.1.tgz", + "integrity": "sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.1.tgz", + "integrity": "sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.1.tgz", + "integrity": "sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.1.tgz", + "integrity": "sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.1.tgz", + "integrity": "sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.1.tgz", + "integrity": "sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.1.tgz", + "integrity": "sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.1.tgz", + "integrity": "sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.8.tgz", + "integrity": "sha512-OWwBsbC9BFAJelmnNcrKuf+bka2ZxCE2A4Ft53Tkg4uoiE67r/PMEYwCsourC26E+kmxfwE0hVzMdxqeW+xu7Q==", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "enhanced-resolve": "^5.18.1", + "jiti": "^2.4.2", + "lightningcss": "1.30.1", + "magic-string": "^0.30.17", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.8" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.8.tgz", + "integrity": "sha512-d7qvv9PsM5N3VNKhwVUhpK6r4h9wtLkJ6lz9ZY9aeZgrUWk1Z8VPyqyDT9MZlem7GTGseRQHkeB1j3tC7W1P+A==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.4.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.8", + "@tailwindcss/oxide-darwin-arm64": "4.1.8", + "@tailwindcss/oxide-darwin-x64": "4.1.8", + "@tailwindcss/oxide-freebsd-x64": "4.1.8", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.8", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.8", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.8", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.8", + "@tailwindcss/oxide-linux-x64-musl": "4.1.8", + "@tailwindcss/oxide-wasm32-wasi": "4.1.8", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.8", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.8" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.8.tgz", + "integrity": "sha512-Fbz7qni62uKYceWYvUjRqhGfZKwhZDQhlrJKGtnZfuNtHFqa8wmr+Wn74CTWERiW2hn3mN5gTpOoxWKk0jRxjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.8.tgz", + "integrity": "sha512-RdRvedGsT0vwVVDztvyXhKpsU2ark/BjgG0huo4+2BluxdXo8NDgzl77qh0T1nUxmM11eXwR8jA39ibvSTbi7A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.8.tgz", + "integrity": "sha512-t6PgxjEMLp5Ovf7uMb2OFmb3kqzVTPPakWpBIFzppk4JE4ix0yEtbtSjPbU8+PZETpaYMtXvss2Sdkx8Vs4XRw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.8.tgz", + "integrity": "sha512-g8C8eGEyhHTqwPStSwZNSrOlyx0bhK/V/+zX0Y+n7DoRUzyS8eMbVshVOLJTDDC+Qn9IJnilYbIKzpB9n4aBsg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.8.tgz", + "integrity": "sha512-Jmzr3FA4S2tHhaC6yCjac3rGf7hG9R6Gf2z9i9JFcuyy0u79HfQsh/thifbYTF2ic82KJovKKkIB6Z9TdNhCXQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.8.tgz", + "integrity": "sha512-qq7jXtO1+UEtCmCeBBIRDrPFIVI4ilEQ97qgBGdwXAARrUqSn/L9fUrkb1XP/mvVtoVeR2bt/0L77xx53bPZ/Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.8.tgz", + "integrity": "sha512-O6b8QesPbJCRshsNApsOIpzKt3ztG35gfX9tEf4arD7mwNinsoCKxkj8TgEE0YRjmjtO3r9FlJnT/ENd9EVefQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.8.tgz", + "integrity": "sha512-32iEXX/pXwikshNOGnERAFwFSfiltmijMIAbUhnNyjFr3tmWmMJWQKU2vNcFX0DACSXJ3ZWcSkzNbaKTdngH6g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.8.tgz", + "integrity": "sha512-s+VSSD+TfZeMEsCaFaHTaY5YNj3Dri8rST09gMvYQKwPphacRG7wbuQ5ZJMIJXN/puxPcg/nU+ucvWguPpvBDg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.8.tgz", + "integrity": "sha512-CXBPVFkpDjM67sS1psWohZ6g/2/cd+cq56vPxK4JeawelxwK4YECgl9Y9TjkE2qfF+9/s1tHHJqrC4SS6cVvSg==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@emnapi/wasi-threads": "^1.0.2", + "@napi-rs/wasm-runtime": "^0.2.10", + "@tybys/wasm-util": "^0.9.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.8.tgz", + "integrity": "sha512-7GmYk1n28teDHUjPlIx4Z6Z4hHEgvP5ZW2QS9ygnDAdI/myh3HTHjDqtSqgu1BpRoI4OiLx+fThAyA1JePoENA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.8.tgz", + "integrity": "sha512-fou+U20j+Jl0EHwK92spoWISON2OBnCazIc038Xj2TdweYV33ZRkS9nwqiUi2d/Wba5xg5UoHfvynnb/UB49cQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.8.tgz", + "integrity": "sha512-vB/vlf7rIky+w94aWMw34bWW1ka6g6C3xIOdICKX2GC0VcLtL6fhlLiafF0DVIwa9V6EHz8kbWMkS2s2QvvNlw==", + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.1.8", + "@tailwindcss/oxide": "4.1.8", + "postcss": "^8.4.41", + "tailwindcss": "4.1.8" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz", + "integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==", + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.0.tgz", + "integrity": "sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@testing-library/user-event": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", + "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", + "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.1.4", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.4.tgz", + "integrity": "sha512-EB1yiiYdvySuIITtD5lhW4yPyJ31RkJkkDw794LaQYrxCSaQV/47y5o1FMC4zF9ZyjUjzJMZwbovEnT5yHTW6g==", + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.5.tgz", + "integrity": "sha512-CMCjrWucUBZvohgZxkjd6S9h0nZxXjzus6yDfUb+xLxYM7VvjKNH1tQrE9GWLql1XoOP4/Ds3bwFqShHUYraGg==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.5.0.tgz", + "integrity": "sha512-JuLWaEqypaJmOJPLWwO335Ig6jSgC1FTONCWAxnqcQthLTK/Yc9aH6hr9z/87xciejbQcnP3GnA1FWUSWeXaeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.26.10", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@rolldown/pluginutils": "1.0.0-beta.9", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.6.1.tgz", + "integrity": "sha512-6YeRZwuO4oTGKxD3bijok756oktHSIm3eczVVzNe3scqzuhLwltIF3S9ZL/vwOVIpURmU6SnZhziXXAfw8/Qlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@bcoe/v8-coverage": "^0.2.3", + "debug": "^4.3.4", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.4", + "istanbul-reports": "^3.1.6", + "magic-string": "^0.30.5", + "magicast": "^0.3.3", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "test-exclude": "^6.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "1.6.1" + } + }, + "node_modules/@vitest/expect": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.1.tgz", + "integrity": "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "1.6.1", + "@vitest/utils": "1.6.1", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.1.tgz", + "integrity": "sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "1.6.1", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.1.tgz", + "integrity": "sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@vitest/snapshot/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@vitest/snapshot/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/spy": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.1.tgz", + "integrity": "sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.1.tgz", + "integrity": "sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@vitest/utils/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@vitest/utils/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "devOptional": true, + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "license": "ISC", + "optional": true + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/attr-accept": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz", + "integrity": "sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axios": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz", + "integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001716", + "electron-to-chromium": "^1.5.149", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001718", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz", + "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/canvas": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz", + "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "nan": "^2.17.0", + "simple-get": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "license": "ISC", + "optional": true, + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "license": "ISC", + "optional": true + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "license": "MIT" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssstyle": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", + "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cssstyle/node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "license": "MIT", + "optional": true + }, + "node_modules/dependency-graph": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", + "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "license": "MIT" + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.159", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.159.tgz", + "integrity": "sha512-CEvHptWAMV5p6GJ0Lq8aheyvVbfzVrv5mmidu1D3pidoVNkB3tTBsTMVtPJ+rzRK5oV229mCLz9Zj/hNvU8GBA==", + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-selector": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-2.1.2.tgz", + "integrity": "sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==", + "license": "MIT", + "dependencies": { + "tslib": "^2.7.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "license": "ISC", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC", + "optional": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "devOptional": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "devOptional": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "license": "ISC", + "optional": true + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "dependencies": { + "void-elements": "3.1.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-agent/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/i18next": { + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.2.1.tgz", + "integrity": "sha512-+UoXK5wh+VlE1Zy5p6MjcvctHXAhRwQKCxiJD8noKZzIXmnAX8gdHX5fLPA3MEVxEN4vbZkQFy8N0LyD9tUqPw==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "dependencies": { + "@babel/runtime": "^7.27.1" + }, + "peerDependencies": { + "typescript": "^5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/i18next-browser-languagedetector": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.1.0.tgz", + "integrity": "sha512-mHZxNx1Lq09xt5kCauZ/4bsXOEA2pfpwSoU11/QTJB+pD94iONFwp+ohqi///PwiFvjFOxe1akYCdHyFo1ng5Q==", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/i18next-http-backend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-3.0.2.tgz", + "integrity": "sha512-PdlvPnvIp4E1sYi46Ik4tBYh/v/NbYfFFgTjkwFl0is8A18s7/bx9aXqsrOax9WUbeNS6mD2oix7Z0yGGf6m5g==", + "dependencies": { + "cross-fetch": "4.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "devOptional": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsdom": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.2.0.tgz", + "integrity": "sha512-L88oL7D/8ufIES+Zjz7v0aes+oBMh2Xnh3ygWvL0OaICOomKEPKuPnIfBJekiXr+BHbbMjrWn/xqrDQuxFTeyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/dom-selector": "^2.0.1", + "cssstyle": "^4.0.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.3", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.16.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/jsdom/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/license-checker": { + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/license-checker/-/license-checker-25.0.1.tgz", + "integrity": "sha512-mET5AIwl7MR2IAKYYoVBBpV0OnkKQ1xGj2IMMeEFIs42QAkEVjRtFZGWmQ28WeU7MP779iAgOaOy93Mn44mn6g==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "debug": "^3.1.0", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "read-installed": "~4.0.3", + "semver": "^5.5.0", + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-satisfies": "^4.0.0", + "treeify": "^1.1.0" + }, + "bin": { + "license-checker": "bin/license-checker" + } + }, + "node_modules/license-checker/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/license-checker/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/license-checker/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/license-checker/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/license-checker/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/license-checker/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/license-checker/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/license-checker/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/license-checker/node_modules/nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/license-checker/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/license-checker/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/local-pkg": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "license": "MIT", + "optional": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/material-symbols": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/material-symbols/-/material-symbols-0.33.0.tgz", + "integrity": "sha512-t9/Gz+14fClRgN7oVOt5CBuwsjFLxSNP9BRDyMrI5el3IZNvoD94IDGJha0YYivyAow24rCS0WOkAv4Dp+YjNg==", + "license": "Apache-2.0" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "devOptional": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "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, + "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", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "license": "MIT", + "optional": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC", + "optional": true + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mlly": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" + } + }, + "node_modules/mlly/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nan": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz", + "integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==", + "license": "MIT", + "optional": true + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "license": "MIT" + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "optional": true, + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "devOptional": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "deprecated": "This package is no longer supported.", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path2d-polyfill": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path2d-polyfill/-/path2d-polyfill-2.0.1.tgz", + "integrity": "sha512-ad/3bsalbbWhmBo0D6FZ4RNMwsLsPpL6gnvhuSaU5Vm7b06Kr5ubSltQQ0T7YKsiJQO+g22zJ4dJKNTXIyOXtA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/pdf-lib": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz", + "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==", + "dependencies": { + "@pdf-lib/standard-fonts": "^1.0.0", + "@pdf-lib/upng": "^1.0.1", + "pako": "^1.0.11", + "tslib": "^1.11.1" + } + }, + "node_modules/pdf-lib/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/pdfjs-dist": { + "version": "3.11.174", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz", + "integrity": "sha512-TdTZPf1trZ8/UFu5Cx/GXB7GZM30LT+wWUNfsi6Bq8ePLnb+woNKtDymI2mxZYBpMbonNFqKmiz684DIfnd8dA==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "canvas": "^2.11.2", + "path2d-polyfill": "^2.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/pkg-types/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/playwright": { + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.54.1.tgz", + "integrity": "sha512-peWpSwIBmSLi6aW2auvrUtf2DqY16YYcCMO8rTVx486jKmDTJg7UAhyrraP98GB8BoPURZP8+nxO7TSd4cPr5g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.54.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.54.1.tgz", + "integrity": "sha512-Nbjs2zjj0htNhzgiy5wu+3w09YetDx5pkrpI/kZotDlDUaYk0HVA5xrBVPdow4SAUIlhgKcJeJg4GRKW6xHusA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-cli": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-11.0.1.tgz", + "integrity": "sha512-0UnkNPSayHKRe/tc2YGW6XnSqqOA9eqpiRMgRlV1S6HdGi16vwJBx7lviARzbV1HpQHqLLRH3o8vTcB0cLc+5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.3.0", + "dependency-graph": "^1.0.0", + "fs-extra": "^11.0.0", + "picocolors": "^1.0.0", + "postcss-load-config": "^5.0.0", + "postcss-reporter": "^7.0.0", + "pretty-hrtime": "^1.0.3", + "read-cache": "^1.0.0", + "slash": "^5.0.0", + "tinyglobby": "^0.2.12", + "yargs": "^17.0.0" + }, + "bin": { + "postcss": "index.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-cli/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/postcss-cli/node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/postcss-cli/node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-cli/node_modules/postcss-load-config": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-5.1.0.tgz", + "integrity": "sha512-G5AJ+IX0aD0dygOE0yFZQ/huFFMSNneyfp0e3/bT05a8OfPC5FUoZRPfGijUdGOJNMewJiwzcHJXFafFzeKFVA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1", + "yaml": "^2.4.2" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + } + } + }, + "node_modules/postcss-cli/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss-cli/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/postcss-cli/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-mixins": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/postcss-mixins/-/postcss-mixins-9.0.4.tgz", + "integrity": "sha512-XVq5jwQJDRu5M1XGkdpgASqLk37OqkH4JCFDXl/Dn7janOJjCTEKL+36cnRVy7bMtoBzALfO7bV7nTIsFnUWLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "^3.2.11", + "postcss-js": "^4.0.0", + "postcss-simple-vars": "^7.0.0", + "sugarss": "^4.0.1" + }, + "engines": { + "node": ">=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-preset-mantine": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/postcss-preset-mantine/-/postcss-preset-mantine-1.17.0.tgz", + "integrity": "sha512-ji1PMDBUf2Vsx/HE5faMSs1+ff6qE6YRulTr4Ja+6HD3gop8rSMTCYdpN7KrdsEg079kfBKkO/PaKhG9uR0zwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-mixins": "^9.0.4", + "postcss-nested": "^6.0.1" + }, + "peerDependencies": { + "postcss": ">=8.0.0" + } + }, + "node_modules/postcss-reporter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.1.0.tgz", + "integrity": "sha512-/eoEylGWyy6/DOiMP5lmFRdmDKThqgn7D6hP2dXKJI/0rJSO1ADFNngZfDzxL0YAxFvws+Rtpuji1YIHj4mySA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "thenby": "^1.3.4" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-simple-vars": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-simple-vars/-/postcss-simple-vars-7.0.1.tgz", + "integrity": "sha512-5GLLXaS8qmzHMOjVxqkk1TZPf1jMqesiI7qLhnlyERalG0sMbHIbJqrcnrpmZdKCLglHnRHoEBB61RtGTsj++A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.1" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "license": "MIT" + }, + "node_modules/pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, + "node_modules/react-dropzone": { + "version": "14.3.8", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.3.8.tgz", + "integrity": "sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==", + "license": "MIT", + "dependencies": { + "attr-accept": "^2.2.4", + "file-selector": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "react": ">= 16.8 || 18.0.0" + } + }, + "node_modules/react-i18next": { + "version": "15.5.2", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.5.2.tgz", + "integrity": "sha512-ePODyXgmZQAOYTbZXQn5rRsSBu3Gszo69jxW6aKmlSgxKAI1fOhDwSu6bT4EKHciWPKQ7v7lPrjeiadR6Gi+1A==", + "dependencies": { + "@babel/runtime": "^7.25.0", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 23.2.3", + "react": ">= 16.8.0", + "typescript": "^5" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/react-is": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.0.tgz", + "integrity": "sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==", + "license": "MIT" + }, + "node_modules/react-number-format": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-5.4.4.tgz", + "integrity": "sha512-wOmoNZoOpvMminhifQYiYSTCLUDOiUbBunrMrMjA+dV52sY+vck1S4UhR6PkgnoCquvvMSeJjErXZ4qSaWCliA==", + "license": "MIT", + "peerDependencies": { + "react": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz", + "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-router": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.0.tgz", + "integrity": "sha512-GGufuHIVCJDbnIAXP3P9Sxzq3UUsddG3rrI3ut1q6m0FI6vxVBF3JoPQ38+W/blslLH4a5Yutp8drkEpXoddGQ==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.6.0.tgz", + "integrity": "sha512-DYgm6RDEuKdopSyGOWZGtDfSm7Aofb8CCzgkliTjtu/eDuB0gcsv6qdFhhi8HdtmA+KHkt5MfZ5K2PdzjugYsA==", + "license": "MIT", + "dependencies": { + "react-router": "7.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-textarea-autosize": { + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.9.tgz", + "integrity": "sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.20.13", + "use-composed-ref": "^1.3.0", + "use-latest": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/read-installed": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz", + "integrity": "sha512-O03wg/IYuV/VtnK2h/KXEt9VIbMUFbk3ERG0Iu4FhLZw0EP0T9znqrYDGn6ncbEsXUFaUjiVAWXHzxwt3lhRPQ==", + "deprecated": "This package is no longer supported.", + "dev": true, + "dependencies": { + "debuglog": "^1.0.1", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.2" + } + }, + "node_modules/read-installed/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-package-json": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz", + "integrity": "sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==", + "deprecated": "This package is no longer supported. Please use @npmcli/package-json instead.", + "dev": true, + "dependencies": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdir-scoped-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", + "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "dependencies": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.41.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.41.1.tgz", + "integrity": "sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.7" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.41.1", + "@rollup/rollup-android-arm64": "4.41.1", + "@rollup/rollup-darwin-arm64": "4.41.1", + "@rollup/rollup-darwin-x64": "4.41.1", + "@rollup/rollup-freebsd-arm64": "4.41.1", + "@rollup/rollup-freebsd-x64": "4.41.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.41.1", + "@rollup/rollup-linux-arm-musleabihf": "4.41.1", + "@rollup/rollup-linux-arm64-gnu": "4.41.1", + "@rollup/rollup-linux-arm64-musl": "4.41.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.41.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.41.1", + "@rollup/rollup-linux-riscv64-gnu": "4.41.1", + "@rollup/rollup-linux-riscv64-musl": "4.41.1", + "@rollup/rollup-linux-s390x-gnu": "4.41.1", + "@rollup/rollup-linux-x64-gnu": "4.41.1", + "@rollup/rollup-linux-x64-musl": "4.41.1", + "@rollup/rollup-win32-arm64-msvc": "4.41.1", + "@rollup/rollup-win32-ia32-msvc": "4.41.1", + "@rollup/rollup-win32-x64-msvc": "4.41.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "devOptional": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "license": "ISC", + "optional": true + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC", + "optional": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz", + "integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.2", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true + }, + "node_modules/spdx-ranges": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz", + "integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==", + "dev": true + }, + "node_modules/spdx-satisfies": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-4.0.1.tgz", + "integrity": "sha512-WVzZ/cXAzoNmjCWiEluEA3BjHp5tiUmmhn9MK+X0tBbR9sOqtC6UQwmgCNrAIZvNlMuBUYAaHYfb2oqlF9SwKA==", + "dev": true, + "dependencies": { + "spdx-compare": "^1.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "dev": true, + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-literal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.1.tgz", + "integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, + "node_modules/sugarss": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-4.0.1.tgz", + "integrity": "sha512-WCjS5NfuVJjkQzK10s8WOBY+hhDxxNt/N6ZaGwxFZ+wN3/lKKFSaaKUNecULcTTvE4urLcKaZFQD8vO0mOZujw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "license": "MIT" + }, + "node_modules/tailwindcss": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.8.tgz", + "integrity": "sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og==", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "license": "ISC", + "optional": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "license": "MIT", + "optional": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC", + "optional": true + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/thenby": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/thenby/-/thenby-1.3.4.tgz", + "integrity": "sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinypool": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/treeify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", + "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-composed-ref": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.4.0.tgz", + "integrity": "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.0.tgz", + "integrity": "sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-latest": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.3.0.tgz", + "integrity": "sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==", + "license": "MIT", + "dependencies": { + "use-isomorphic-layout-effect": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/util-extend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", + "integrity": "sha512-mLs5zAK+ctllYBj+iAQvlDCwoxU/WDOUaJkcFudeiAX6OajC6BKXJUa9a+tbtkC11dz2Ufb7h0lyvIOVn4LADA==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vite": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.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 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.1.tgz", + "integrity": "sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/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-node/node_modules/vite": { + "version": "5.4.19", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", + "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==", + "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/node_modules/fdir": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.5.tgz", + "integrity": "sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.1.tgz", + "integrity": "sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "1.6.1", + "@vitest/runner": "1.6.1", + "@vitest/snapshot": "1.6.1", + "@vitest/spy": "1.6.1", + "@vitest/utils": "1.6.1", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.3", + "vite": "^5.0.0", + "vite-node": "1.6.1", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.6.1", + "@vitest/ui": "1.6.1", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/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/vitest/node_modules/vite": { + "version": "5.4.19", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", + "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==", + "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/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/web-vitals": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", + "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==", + "license": "Apache-2.0" + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "license": "ISC", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "devOptional": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz", + "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 000000000..4ff3484b3 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,82 @@ +{ + "name": "frontend", + "version": "0.1.0", + "private": true, + "license": "SEE LICENSE IN https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/proprietary/LICENSE", + "proxy": "http://localhost:8080", + "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", + "@mantine/core": "^8.0.1", + "@mantine/dropzone": "^8.0.1", + "@mantine/hooks": "^8.0.1", + "@mui/icons-material": "^7.1.0", + "@mui/material": "^7.1.0", + "@tailwindcss/postcss": "^4.1.8", + "@testing-library/dom": "^10.4.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.3.0", + "@testing-library/user-event": "^13.5.0", + "autoprefixer": "^10.4.21", + "axios": "^1.9.0", + "i18next": "^25.2.1", + "i18next-browser-languagedetector": "^8.1.0", + "i18next-http-backend": "^3.0.2", + "jszip": "^3.10.1", + "material-symbols": "^0.33.0", + "pdf-lib": "^1.17.1", + "pdfjs-dist": "^3.11.174", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "react-i18next": "^15.5.2", + "react-router-dom": "^7.6.0", + "tailwindcss": "^4.1.8", + "web-vitals": "^2.1.4" + }, + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "generate-licenses": "node scripts/generate-licenses.js", + "test": "vitest", + "test:watch": "vitest --watch", + "test:coverage": "vitest --coverage", + "test:e2e": "playwright test", + "test:e2e:ui": "playwright test --ui", + "test:e2e:install": "playwright install" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "devDependencies": { + "@playwright/test": "^1.40.0", + "@types/react": "^19.1.4", + "@types/react-dom": "^19.1.5", + "@vitejs/plugin-react": "^4.5.0", + "@vitest/coverage-v8": "^1.0.0", + "jsdom": "^23.0.0", + "license-checker": "^25.0.1", + "postcss": "^8.5.3", + "postcss-cli": "^11.0.1", + "postcss-preset-mantine": "^1.17.0", + "postcss-simple-vars": "^7.0.1", + "typescript": "^5.8.3", + "vite": "^6.3.5", + "vitest": "^1.0.0" + } +} diff --git a/frontend/playwright.config.ts b/frontend/playwright.config.ts new file mode 100644 index 000000000..26a94f00b --- /dev/null +++ b/frontend/playwright.config.ts @@ -0,0 +1,75 @@ +import { defineConfig, devices } from '@playwright/test'; + +/** + * @see https://playwright.dev/docs/test-configuration + */ +export default defineConfig({ + testDir: './src/tests', + testMatch: '**/*.spec.ts', + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'html', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: 'http://localhost:5173', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { + ...devices['Desktop Chrome'], + viewport: { width: 1920, height: 1080 } + }, + }, + + { + name: 'firefox', + use: { ...devices['Desktop Firefox'] }, + }, + + { + name: 'webkit', + use: { ...devices['Desktop Safari'] }, + }, + + /* Test against mobile viewports. */ + // { + // name: 'Mobile Chrome', + // use: { ...devices['Pixel 5'] }, + // }, + // { + // name: 'Mobile Safari', + // use: { ...devices['iPhone 12'] }, + // }, + + /* Test against branded browsers. */ + // { + // name: 'Microsoft Edge', + // use: { ...devices['Desktop Edge'], channel: 'msedge' }, + // }, + // { + // name: 'Google Chrome', + // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, + // }, + ], + + /* Run your local dev server before starting the tests */ + webServer: { + command: 'npm run dev', + url: 'http://localhost:5173', + reuseExistingServer: !process.env.CI, + }, +}); \ No newline at end of file diff --git a/frontend/postcss.config.js b/frontend/postcss.config.js new file mode 100644 index 000000000..57e730c99 --- /dev/null +++ b/frontend/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: [ + require('@tailwindcss/postcss'), + require('autoprefixer'), + ], +}; diff --git a/frontend/public/branding/StirlingPDFLogoBlackText.svg b/frontend/public/branding/StirlingPDFLogoBlackText.svg new file mode 100644 index 000000000..a4a1a1f87 --- /dev/null +++ b/frontend/public/branding/StirlingPDFLogoBlackText.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/public/branding/StirlingPDFLogoGreyText.svg b/frontend/public/branding/StirlingPDFLogoGreyText.svg new file mode 100644 index 000000000..deac1ee16 --- /dev/null +++ b/frontend/public/branding/StirlingPDFLogoGreyText.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/public/branding/StirlingPDFLogoNoTextDark.svg b/frontend/public/branding/StirlingPDFLogoNoTextDark.svg new file mode 100644 index 000000000..6c99f5001 --- /dev/null +++ b/frontend/public/branding/StirlingPDFLogoNoTextDark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/public/branding/StirlingPDFLogoNoTextLight.svg b/frontend/public/branding/StirlingPDFLogoNoTextLight.svg new file mode 100644 index 000000000..a0fa9cee5 --- /dev/null +++ b/frontend/public/branding/StirlingPDFLogoNoTextLight.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/public/branding/StirlingPDFLogoWhiteText.svg b/frontend/public/branding/StirlingPDFLogoWhiteText.svg new file mode 100644 index 000000000..ade693787 --- /dev/null +++ b/frontend/public/branding/StirlingPDFLogoWhiteText.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/public/favicon.ico b/frontend/public/favicon.ico new file mode 100644 index 000000000..6d6c8521c Binary files /dev/null and b/frontend/public/favicon.ico differ diff --git a/frontend/public/locales/ar-AR/translation.json b/frontend/public/locales/ar-AR/translation.json new file mode 100644 index 000000000..e6b5b13cb --- /dev/null +++ b/frontend/public/locales/ar-AR/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "rtl" + }, + "addPageNumbers": { + "fontSize": "حجم الخط", + "fontName": "اسم الخط", + "title": "؄ضافة أرقام الصفحات", + "header": "؄ضافة أرقام الصفحات", + "selectText": { + "1": "Ų­ŲÆŲÆ ملف PDF:", + "2": "حجم الهامؓ", + "3": "Ų§Ł„Ł…ŁˆŁ‚Ų¹", + "4": "الرقم Ų§Ł„Ų£ŁˆŁ„ŁŠ", + "5": "الصفحات المراد ŲŖŲ±Ł‚ŁŠŁ…Ł‡Ų§", + "6": "نص Ł…Ų®ŲµŲµ" + }, + "customTextDesc": "نص Ł…Ų®ŲµŲµ", + "numberPagesDesc": "أي الصفحات المراد ŲŖŲ±Ł‚ŁŠŁ…Ł‡Ų§ŲŒ Ų§Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ 'Ų§Ł„ŁƒŁ„'، ŁŠŁ‚ŲØŁ„ Ų£ŁŠŲ¶Ł‹Ų§ 1-5 أو 2,5,9 ؄لخ", + "customNumberDesc": "Ų§Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ Ł‡Łˆ {n}، ŁŠŁ‚ŲØŁ„ Ų£ŁŠŲ¶Ł‹Ų§ 'الصفحة {n} من {total}'، 'نص-{n}'، '{filename}-{n}", + "submit": "؄ضافة أرقام الصفحات" + }, + "pdfPrompt": "Ų§Ų®ŲŖŲ± PDF", + "multiPdfPrompt": "Ų§Ų®ŲŖŲ± ملفات PDF (2+)", + "multiPdfDropPrompt": "Ų­ŲÆŲÆ (أو Ų§Ų³Ų­ŲØ ŁˆŲ£ŁŁ„ŲŖ) Ų¬Ł…ŁŠŲ¹ ملفات PDF Ų§Ł„ŲŖŁŠ تحتاجها", + "imgPrompt": "Ų§Ų®ŲŖŲ± صورة", + "genericSubmit": "Ų„Ų±Ų³Ų§Ł„", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "تحذير: ŁŠŁ…ŁƒŁ† أن تستغرق هذه Ų§Ł„Ų¹Ł…Ł„ŁŠŲ© Ł…Ų§ ŁŠŲµŁ„ ؄لى ŲÆŁ‚ŁŠŁ‚Ų© Ų­Ų³ŲØ حجم الملف", + "pageOrderPrompt": "ترتيب الصفحات (أدخل قائمة بأرقام الصفحات Ł…ŁŲµŁˆŁ„Ų© ŲØŁŁˆŲ§ŲµŁ„):", + "pageSelectionPrompt": "اختيار الصفحات المخصص (أدخل قائمة بأرقام الصفحات Ł…ŁŲµŁˆŁ„Ų© ŲØŁŁˆŲ§ŲµŁ„ 1،5،6 أو ŲÆŁˆŲ§Ł„ Ł…Ų«Ł„ 2n+1):", + "goToPage": "اذهب", + "true": "صحيح", + "false": "Ų®Ų·Ų£", + "unknown": "غير Ł…Ų¹Ų±ŁˆŁ", + "save": "حفظ", + "saveToBrowser": "حفظ في المتصفح", + "close": "؄غلاق", + "filesSelected": "الملفات المحددة", + "noFavourites": "لم ŲŖŲŖŁ… ؄ضافة أي مفضلات", + "downloadComplete": "Ų„ŁƒŲŖŁ…Ł„ Ų§Ł„ŲŖŲ­Ł…ŁŠŁ„", + "bored": "الانتظار ŲØŲ§Ł„Ł…Ł„Ł„ŲŸ", + "alphabet": "Ų§Ł„Ų£ŲØŲ¬ŲÆŁŠŲ©", + "downloadPdf": "ŲŖŁ†Ų²ŁŠŁ„ PDF", + "text": "نص", + "font": "الخط", + "selectFillter": "- Ų­ŲÆŲÆ -", + "pageNum": "رقم الصفحة", + "sizes": { + "small": "صغير", + "medium": "وسط", + "large": "كبير", + "x-large": "كبير Ų¬ŲÆŲ§" + }, + "error": { + "pdfPassword": "ملف PDF Ł…Ų­Ł…ŁŠ ŲØŁƒŁ„Ł…Ų© Ł…Ų±ŁˆŲ± ŁˆŁ„Ł… ŁŠŲŖŁ… ŲŖŁ‚ŲÆŁŠŁ… ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± أو ŁƒŲ§Ł†ŲŖ غير صحيحة", + "_value": "Ų®Ų·Ų£", + "sorry": "نأسف على Ų§Ł„Ł…Ų“ŁƒŁ„Ų©!", + "needHelp": "هل ŲŖŲ­ŲŖŲ§Ų¬ ؄لى Ł…Ų³Ų§Ų¹ŲÆŲ© / وجدت Ł…Ų“ŁƒŁ„Ų©ŲŸ", + "contactTip": "Ų„Ų°Ų§ ŁƒŁ†ŲŖ Ł…Ų§ زلت ŲŖŁˆŲ§Ų¬Ł‡ صعوبة، لا ŲŖŲŖŲ±ŲÆŲÆ في Ų§Ł„ŲŖŁˆŲ§ŲµŁ„ معنا Ł„Ł„Ų­ŲµŁˆŁ„ على المساعدة. ŁŠŁ…ŁƒŁ†Łƒ Ų„Ų±Ų³Ų§Ł„ تذكرة على صفحة GitHub الخاصة بنا أو الاتصال بنا Ų¹ŲØŲ± Discord:", + "404": { + "head": "404 - الصفحة غير Ł…ŁˆŲ¬ŁˆŲÆŲ© | Ų¹Ų°Ų±Ł‹Ų§ŲŒ لقد تعثرنا في Ų§Ł„ŁƒŁˆŲÆ!", + "1": "لا ŁŠŁ…ŁƒŁ†Ł†Ų§ Ų§Ł„Ų¹Ų«ŁˆŲ± على الصفحة Ų§Ł„ŲŖŁŠ ŲŖŲØŲ­Ų« عنها.", + "2": "Ų­ŲÆŲ« Ų®Ų·Ų£ Ł…Ų§" + }, + "github": "Ų„Ų±Ų³Ų§Ł„ تذكرة على GitHub", + "showStack": "؄ظهار ŲŖŲŖŲØŲ¹ Ų§Ł„Ł…ŁƒŲÆŲ³", + "copyStack": "نسخ ŲŖŲŖŲØŲ¹ Ų§Ł„Ł…ŁƒŲÆŲ³", + "githubSubmit": "GitHub - Ų„Ų±Ų³Ų§Ł„ تذكرة", + "discordSubmit": "Discord - Ų„Ų±Ų³Ų§Ł„ Ł…Ł†Ų“ŁˆŲ± دعم" + }, + "delete": "حذف", + "username": "اسم المستخدم", + "password": "ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ±", + "welcome": "Ł…Ų±Ų­ŲØŲ§", + "property": "Ų§Ł„Ų®Ų§ŲµŁŠŲ©", + "black": "أسود", + "white": "أبيض", + "red": "Ų£Ų­Ł…Ų±", + "green": "Ų£Ų®Ų¶Ų±", + "blue": "أزرق", + "custom": "Ł…Ų®ŲµŲµ...", + "WorkInProgess": "العمل Ł‚ŁŠŲÆ Ų§Ł„ŲŖŁ‚ŲÆŁ…ŲŒ قد لا ŁŠŲ¹Ł…Ł„ أو يحتوي على أخطاؔ، ŁŠŲ±Ų¬Ł‰ ال؄بلاغ عن أي Ł…Ų“Ų§ŁƒŁ„!", + "poweredBy": "Ł…ŲÆŲ¹ŁˆŁ… بواسطة", + "yes": "نعم", + "no": "لا", + "changedCredsMessage": "ŲŖŁ… تغيير ŲØŁŠŲ§Ł†Ų§ŲŖ الاعتماد!", + "notAuthenticatedMessage": "المستخدم غير Ł…ŲµŲ§ŲÆŁ‚ Ų¹Ł„ŁŠŁ‡.", + "userNotFoundMessage": "لم ŁŠŲŖŁ… Ų§Ł„Ų¹Ų«ŁˆŲ± على المستخدم.", + "incorrectPasswordMessage": "ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± Ų§Ł„Ų­Ų§Ł„ŁŠŲ© غير صحيحة.", + "usernameExistsMessage": "اسم المستخدم Ų§Ł„Ų¬ŲÆŁŠŲÆ Ł…ŁˆŲ¬ŁˆŲÆ بالفعل.", + "invalidUsernameMessage": "اسم المستخدم غير ŲµŲ§Ł„Ų­ŲŒ ŁŠŁ…ŁƒŁ† أن يحتوي فقط على أحرف ŁˆŲ£Ų±Ł‚Ų§Ł… ŁˆŲ§Ł„Ų±Ł…ŁˆŲ² الخاصة Ų§Ł„ŲŖŲ§Ł„ŁŠŲ© @._+- أو يجب أن ŁŠŁƒŁˆŁ† Ų¹Ł†ŁˆŲ§Ł† بريد Ų„Ł„ŁƒŲŖŲ±ŁˆŁ†ŁŠ صالح.", + "invalidPasswordMessage": "ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± يجب ألا ŲŖŁƒŁˆŁ† فارغة ويجب ألا تحتوي على مسافات في Ų§Ł„ŲØŲÆŲ§ŁŠŲ© أو Ų§Ł„Ł†Ł‡Ų§ŁŠŲ©.", + "confirmPasswordErrorMessage": "ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± Ų§Ł„Ų¬ŲÆŁŠŲÆŲ© وتأكيد ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± Ų§Ł„Ų¬ŲÆŁŠŲÆŲ© يجب أن تتطابقا.", + "deleteCurrentUserMessage": "لا ŁŠŁ…ŁƒŁ† حذف المستخدم المسجل Ų­Ų§Ł„ŁŠŁ‹Ų§.", + "deleteUsernameExistsMessage": "اسم المستخدم غير Ł…ŁˆŲ¬ŁˆŲÆ ŁˆŁ„Ų§ ŁŠŁ…ŁƒŁ† حذفه.", + "downgradeCurrentUserMessage": "لا ŁŠŁ…ŁƒŁ† خفض دور المستخدم Ų§Ł„Ų­Ų§Ł„ŁŠ", + "disabledCurrentUserMessage": "لا ŁŠŁ…ŁƒŁ† ŲŖŲ¹Ų·ŁŠŁ„ المستخدم Ų§Ł„Ų­Ų§Ł„ŁŠ", + "downgradeCurrentUserLongMessage": "لا ŁŠŁ…ŁƒŁ† تخفيض دور المستخدم Ų§Ł„Ų­Ų§Ł„ŁŠ. ŁˆŲØŲ§Ł„ŲŖŲ§Ł„ŁŠŲŒ لن ŁŠŲøŁ‡Ų± المستخدم Ų§Ł„Ų­Ų§Ł„ŁŠ.", + "userAlreadyExistsOAuthMessage": "المستخدم Ł…ŁˆŲ¬ŁˆŲÆ بالفعل ŁƒŁ…Ų³ŲŖŲ®ŲÆŁ… OAuth2.", + "userAlreadyExistsWebMessage": "المستخدم Ł…ŁˆŲ¬ŁˆŲÆ بالفعل ŁƒŁ…Ų³ŲŖŲ®ŲÆŁ… ويب.", + "oops": "عذرًا!", + "help": "Ł…Ų³Ų§Ų¹ŲÆŲ©", + "goHomepage": "الى الصفحة Ų§Ł„Ų±Ų¦ŁŠŲ³ŁŠŲ©", + "joinDiscord": "انضم ؄لى Ų®Ų§ŲÆŁ… Discord الخاص بنا", + "seeDockerHub": "انظر Docker Hub", + "visitGithub": "زيارة Ł…Ų³ŲŖŁˆŲÆŲ¹ Github", + "donate": "ŲŖŲØŲ±Ų¹", + "color": "Ł„ŁˆŁ†", + "sponsor": "Ų±Ų§Ų¹Ł", + "info": "Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖ", + "pro": "محترف", + "page": "صفحة", + "pages": "صفحات", + "loading": "Ų¬Ų§Ų±Ł Ų§Ł„ŲŖŲ­Ł…ŁŠŁ„...", + "addToDoc": "؄ضافة ؄لى المستند", + "reset": "Ų„Ų¹ŲÆŲ§Ų© Ų¶ŲØŲ·", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "سياسة Ų§Ł„Ų®ŲµŁˆŲµŁŠŲ©", + "terms": "ؓروط الاستخدام", + "accessibility": "Ų„Ł…ŁƒŲ§Ł†ŁŠŲ© Ų§Ł„ŁˆŲµŁˆŁ„", + "cookie": "سياسة ملفات تعريف الارتباط", + "impressum": "ŲØŁŠŲ§Ł† Ų§Ł„Ł‡ŁˆŁŠŲ©", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "قائمة Ų®Ų· Ų§Ł„Ų£Ł†Ų§ŲØŁŠŲØ (تجريبي)", + "uploadButton": "ŲŖŲ­Ł…ŁŠŁ„ Ł…Ų®ŲµŲµ", + "configureButton": "ŲŖŁƒŁˆŁŠŁ†", + "defaultOption": "Ł…Ų®ŲµŲµ", + "submitButton": "Ų„Ų±Ų³Ų§Ł„", + "help": "Ł…Ų³Ų§Ų¹ŲÆŲ© Ų®Ų· Ų§Ł„Ų£Ł†Ų§ŲØŁŠŲØ", + "scanHelp": "Ł…Ų³Ų§Ų¹ŲÆŲ© Ł…Ų³Ų­ المجلد", + "deletePrompt": "هل أنت Ł…ŲŖŲ£ŁƒŲÆ Ų£Ł†Łƒ تريد حذف Ų®Ų· Ų§Ł„Ų£Ł†Ų§ŲØŁŠŲØ", + "tags": "Ų£ŲŖŁ…ŲŖŲ©,تسلسل,مبرمج,معالجة دفعات", + "title": "Ų®Ų· Ų§Ł„Ų£Ł†Ų§ŲØŁŠŲØ" + }, + "pipelineOptions": { + "header": "ŲŖŁƒŁˆŁŠŁ† Ų®Ų· Ų§Ł„Ų£Ł†Ų§ŲØŁŠŲØ", + "pipelineNameLabel": "اسم Ų®Ų· Ų§Ł„Ų£Ł†Ų§ŲØŁŠŲØ", + "saveSettings": "حفظ Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ Ų§Ł„Ų¹Ł…Ł„ŁŠŲ©", + "pipelineNamePrompt": "أدخل اسم Ų®Ų· Ų§Ł„Ų£Ł†Ų§ŲØŁŠŲØ هنا", + "selectOperation": "Ų§Ų®ŲŖŲ± Ų§Ł„Ų¹Ł…Ł„ŁŠŲ©", + "addOperationButton": "؄ضافة Ų¹Ł…Ł„ŁŠŲ©", + "pipelineHeader": "Ų®Ų· Ų§Ł„Ų£Ł†Ų§ŲØŁŠŲØ:", + "saveButton": "ŲŖŁ†Ų²ŁŠŁ„", + "validateButton": "تحقق" + }, + "enterpriseEdition": { + "button": "ŲŖŲ±Ł‚ŁŠŲ© ؄لى محترف", + "warning": "هذه Ų§Ł„Ų®Ų§ŲµŁŠŲ© Ł…ŲŖŁˆŁŲ±Ų© فقط Ł„Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŁŠŁ† Ų§Ł„Ł…Ų­ŲŖŲ±ŁŁŠŁ†.", + "yamlAdvert": "ŁŠŲÆŲ¹Ł… Stirling PDF Pro ملفات ال؄عدادات YAML ŁˆŁ…ŁŠŲ²Ų§ŲŖ SSO أخرى", + "ssoAdvert": "هل ŲŖŲØŲ­Ų« عن Ų§Ł„Ł…Ų²ŁŠŲÆ من Ł…ŁŠŲ²Ų§ŲŖ Ų„ŲÆŲ§Ų±Ų© Ų§Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŁŠŁ†ŲŸ اطلع على Stirling PDF Pro" + }, + "analytics": { + "title": "هل تريد ŲŖŲ­Ų³ŁŠŁ† Stirling PDF؟", + "paragraph1": "Stirling PDF يحتوي على ؄حصائيات Ł…Ų®ŲŖŲµŲ© للمساعدة في ŲŖŲ­Ų³ŁŠŁ† المنتج. لا نتبع أي Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖ ؓخصية أو Ł…Ų­ŲŖŁˆŁ‰ الملفات.", + "paragraph2": "ŁŠŲ±Ų¬Ł‰ Ł…Ų±Ų§Ų¹Ų§Ų© ŲŖŁŲ¹ŁŠŁ„ Ų§Ł„Ų„Ų­ŲµŲ§Ų¦ŁŠŲ§ŲŖ لمساعدتنا على Ł†Ł…Łˆ Stirling-PDF وتوفير فهم أفضل Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŁŠŁ†Ų§.", + "enable": "ŲŖŁŲ¹ŁŠŁ„ Ų§Ł„Ų„Ų­ŲµŲ§Ų¦ŁŠŲ§ŲŖ", + "disable": "ŲŖŲ¹Ų·ŁŠŁ„ Ų§Ł„Ų„Ų­ŲµŲ§Ų¦ŁŠŲ§ŲŖ", + "settings": "ŁŠŁ…ŁƒŁ†Łƒ تغيير Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ Ų§Ł„Ų„Ų­ŲµŲ§Ų¦ŁŠŲ§ŲŖ في ملف config/settings.yml" + }, + "navbar": { + "favorite": "المفضلة", + "recent": "New and recently updated", + "darkmode": "Ų§Ł„ŁˆŲ¶Ų¹ Ų§Ł„ŲÆŲ§ŁƒŁ†", + "language": "اللغات", + "settings": "Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ", + "allTools": "أدوات", + "multiTool": "أدوات Ł…ŲŖŲ¹ŲÆŲÆŲ©", + "search": "البحث", + "sections": { + "organize": "ŲŖŁ†ŲøŁŠŁ…", + "convertTo": "ŲŖŲ­ŁˆŁŠŁ„ الى PDF", + "convertFrom": "ŲŖŲ­ŁˆŁŠŁ„ من PDF", + "security": "Ų§Ł„ŲŖŁˆŁ‚ŁŠŲ¹ ŁˆŲ§Ł„Ų£Ł…Ų§Ł†", + "advance": "متقدم", + "edit": "Ų¹Ų±Ų¶ ŁˆŲŖŲ¹ŲÆŁŠŁ„", + "popular": "المفضل" + } + }, + "settings": { + "title": "ال؄عدادات", + "update": "Ų§Ł„ŲŖŲ­ŲÆŁŠŲ« Ł…ŲŖŲ§Ų­", + "updateAvailable": "{0} Ł‡Łˆ ال؄صدار المثبت Ų­Ų§Ł„ŁŠŁ‹Ų§. Ų„ŲµŲÆŲ§Ų± جديد ({1}) Ł…ŲŖŲ§Ų­.", + "appVersion": "Ų„ŲµŲÆŲ§Ų± Ų§Ł„ŲŖŲ·ŲØŁŠŁ‚:", + "downloadOption": { + "title": "تحديد خيار Ų§Ł„ŲŖŁ†Ų²ŁŠŁ„ (Ł„Ł„ŲŖŁ†Ų²ŁŠŁ„Ų§ŲŖ Ų°Ų§ŲŖ الملف Ų§Ł„ŁˆŲ§Ų­ŲÆ غير Ų§Ł„Ł…Ų¶ŲŗŁˆŲ·):", + "1": "فتح في نفس النافذة", + "2": "فتح في نافذة جديدة", + "3": "ŲŖŁ†Ų²ŁŠŁ„ الملف" + }, + "zipThreshold": "ملفات Ł…Ų¶ŲŗŁˆŲ·Ų© عند تجاوز Ų¹ŲÆŲÆ الملفات Ų§Ł„ŲŖŁŠ ŲŖŁ… ŲŖŁ†Ų²ŁŠŁ„Ł‡Ų§", + "signOut": "ŲŖŲ³Ų¬ŁŠŁ„ Ų§Ł„Ų®Ų±ŁˆŲ¬", + "accountSettings": "Ų§Ų¹ŲÆŲ§ŲÆŲ§ŲŖ الحساب", + "bored": { + "help": "ŲŖŁ…ŁƒŁŠŁ† لعبة Ų§Ł„ŲØŁŠŲ¶Ų© Ų§Ł„Ł…Ų®ŁŁŠŲ©" + }, + "cacheInputs": { + "name": "حفظ ؄دخالات Ų§Ł„Ł†Ł…ŁˆŲ°Ų¬", + "help": "ŲŖŁ…ŁƒŁŠŁ† Ł„ŲŖŲ®Ų²ŁŠŁ† ال؄دخالات المستخدمة سابقًا Ł„Ł„ŲŖŲ“ŲŗŁŠŁ„Ų§ŲŖ Ų§Ł„Ł…Ų³ŲŖŁ‚ŲØŁ„ŁŠŲ©" + } + }, + "changeCreds": { + "title": "تغيير ŲØŁŠŲ§Ł†Ų§ŲŖ الاعتماد", + "header": "تحديث ŲŖŁŲ§ŲµŁŠŁ„ حسابك", + "changePassword": "أنت ŲŖŲ³ŲŖŲ®ŲÆŁ… ŲØŁŠŲ§Ł†Ų§ŲŖ ŲŖŲ³Ų¬ŁŠŁ„ Ų§Ł„ŲÆŲ®ŁˆŁ„ Ų§Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠŲ©. ŁŠŲ±Ų¬Ł‰ Ų„ŲÆŲ®Ų§Ł„ ŁƒŁ„Ł…Ų© Ł…Ų±ŁˆŲ± جديدة", + "newUsername": "اسم المستخدم Ų§Ł„Ų¬ŲÆŁŠŲÆ", + "oldPassword": "ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± Ų§Ł„Ų­Ų§Ł„ŁŠŲ©", + "newPassword": "ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± Ų§Ł„Ų¬ŲÆŁŠŲÆŲ©", + "confirmNewPassword": "تأكيد ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± Ų§Ł„Ų¬ŲÆŁŠŲÆŲ©", + "submit": "Ų„Ų±Ų³Ų§Ł„ Ų§Ł„ŲŖŲŗŁŠŁŠŲ±Ų§ŲŖ" + }, + "account": { + "title": "Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ الحساب", + "accountSettings": "Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ الحساب", + "adminSettings": "Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ Ų§Ł„Ł…Ų³Ų¤ŁˆŁ„ - Ų¹Ų±Ų¶ و؄ضافة Ų§Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŁŠŁ†", + "userControlSettings": "Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ Ų§Ł„ŲŖŲ­ŁƒŁ… في المستخدم", + "changeUsername": "تغيير اسم المستخدم", + "newUsername": "اسم المستخدم Ų§Ł„Ų¬ŲÆŁŠŲÆ", + "password": "ŁƒŁ„Ł…Ų© Ł…Ų±ŁˆŲ± Ų§Ł„ŲŖŲ£ŁƒŁŠŲÆ", + "oldPassword": "ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± Ų§Ł„Ł‚ŲÆŁŠŁ…Ų©", + "newPassword": "ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± Ų§Ł„Ų¬ŲÆŁŠŲÆŲ©", + "changePassword": "تغيير ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ±", + "confirmNewPassword": "تأكيد ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± Ų§Ł„Ų¬ŲÆŁŠŲÆŲ©", + "signOut": "ŲŖŲ³Ų¬ŁŠŁ„ Ų§Ł„Ų®Ų±ŁˆŲ¬", + "yourApiKey": "مفتاح API الخاص بك", + "syncTitle": "مزامنة Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ المتصفح Ł…Ų¹ الحساب", + "settingsCompare": "مقارنة ال؄عدادات:", + "property": "Ų§Ł„Ų®Ų§ŲµŁŠŲ©", + "webBrowserSettings": "Ų„Ų¹ŲÆŲ§ŲÆ متصفح Ų§Ł„ŁˆŁŠŲØ", + "syncToBrowser": "مزامنة الحساب -> المتصفح", + "syncToAccount": "مزامنة الحساب <- المتصفح" + }, + "adminUserSettings": { + "title": "Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ Ų§Ł„ŲŖŲ­ŁƒŁ… في المستخدم", + "header": "Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ Ų§Ł„ŲŖŲ­ŁƒŁ… في المستخدم Ł„Ł„Ł…Ų³Ų¤ŁˆŁ„", + "admin": "Ł…Ų³Ų¤ŁˆŁ„", + "user": "Ł…Ų³ŲŖŲ®ŲÆŁ…", + "addUser": "؄ضافة Ł…Ų³ŲŖŲ®ŲÆŁ… جديد", + "deleteUser": "حذف المستخدم", + "confirmDeleteUser": "هل يجب حذف Ų§Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŲŸ", + "confirmChangeUserStatus": "هل يجب ŲŖŲ¹Ų·ŁŠŁ„/ŲŖŁ…ŁƒŁŠŁ† Ų§Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŲŸ", + "usernameInfo": "ŁŠŁ…ŁƒŁ† أن يحتوي اسم المستخدم فقط على أحرف ŁˆŲ£Ų±Ł‚Ų§Ł… ŁˆŲ§Ł„Ų±Ł…ŁˆŲ² الخاصة Ų§Ł„ŲŖŲ§Ł„ŁŠŲ© @._+- أو يجب أن ŁŠŁƒŁˆŁ† Ų¹Ł†ŁˆŲ§Ł† بريد Ų„Ł„ŁƒŲŖŲ±ŁˆŁ†ŁŠ صالح.", + "roles": "Ų§Ł„Ų£ŲÆŁˆŲ§Ų±", + "role": "Ų§Ł„ŲÆŁˆŲ±", + "actions": "ال؄جراؔات", + "apiUser": "Ł…Ų³ŲŖŲ®ŲÆŁ… API Ł…Ų­ŲÆŁˆŲÆ", + "extraApiUser": "Ł…Ų³ŲŖŲ®ŲÆŁ… API Ł…Ų­ŲÆŁˆŲÆ ؄ضافي", + "webOnlyUser": "Ł…Ų³ŲŖŲ®ŲÆŁ… Ų§Ł„ŁˆŁŠŲØ فقط", + "demoUser": "Ł…Ų³ŲŖŲ®ŲÆŁ… تجريبي (ŲØŲÆŁˆŁ† Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ Ł…Ų®ŲµŲµŲ©)", + "internalApiUser": "Ł…Ų³ŲŖŲ®ŲÆŁ… API ŲÆŲ§Ų®Ł„ŁŠ", + "forceChange": "Ų„Ų¬ŲØŲ§Ų± المستخدم على تغيير ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± عند ŲŖŲ³Ų¬ŁŠŁ„ Ų§Ł„ŲÆŲ®ŁˆŁ„", + "submit": "حفظ المستخدم", + "changeUserRole": "تغيير دور المستخدم", + "authenticated": "ŲŖŁ…ŲŖ المصادقة", + "editOwnProfil": "ŲŖŲ¹ŲÆŁŠŁ„ الملف Ų§Ł„Ų“Ų®ŲµŁŠ الخاص", + "enabledUser": "Ł…Ų³ŲŖŲ®ŲÆŁ… مفعل", + "disabledUser": "Ł…Ų³ŲŖŲ®ŲÆŁ… Ł…Ų¹Ų·Ł„", + "activeUsers": "Ų§Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŁŠŁ† Ų§Ł„Ł†Ų“Ų·ŁŠŁ†:", + "disabledUsers": "Ų§Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŁŠŁ† Ų§Ł„Ł…Ų¹Ų·Ł„ŁŠŁ†:", + "totalUsers": "Ų„Ų¬Ł…Ų§Ł„ŁŠ Ų§Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŁŠŁ†:", + "lastRequest": "Ų¢Ų®Ų± طلب", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "استيراد/تصدير قاعدة Ų§Ł„ŲØŁŠŲ§Ł†Ų§ŲŖ", + "header": "استيراد/تصدير قاعدة Ų§Ł„ŲØŁŠŲ§Ł†Ų§ŲŖ", + "fileName": "اسم الملف", + "creationDate": "تاريخ ال؄نؓاؔ", + "fileSize": "حجم الملف", + "deleteBackupFile": "حذف ملف النسخ Ų§Ł„Ų§Ų­ŲŖŁŠŲ§Ų·ŁŠ", + "importBackupFile": "استيراد ملف النسخ Ų§Ł„Ų§Ų­ŲŖŁŠŲ§Ų·ŁŠ", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "ŲŖŁ†Ų²ŁŠŁ„ ملف النسخ Ų§Ł„Ų§Ų­ŲŖŁŠŲ§Ų·ŁŠ", + "info_1": "عند استيراد Ų§Ł„ŲØŁŠŲ§Ł†Ų§ŲŖŲŒ من Ų§Ł„Ų¶Ų±ŁˆŲ±ŁŠ ضمان Ų§Ł„Ł‡ŁŠŁƒŁ„ Ų§Ł„ŲµŲ­ŁŠŲ­. Ų„Ų°Ų§ ŁƒŁ†ŲŖ غير Ł…ŲŖŲ£ŁƒŲÆ Ł…Ł…Ų§ ŲŖŁŲ¹Ł„Ł‡ŲŒ اطلب Ų§Ł„Ł…Ų“ŁˆŲ±Ų© ŁˆŲ§Ł„ŲÆŲ¹Ł… من محترف. ŁŠŁ…ŁƒŁ† أن يؤدي الخطأ في Ų§Ł„Ł‡ŁŠŁƒŁ„ ؄لى حدوث Ų£Ų¹Ų·Ų§Ł„ في Ų§Ł„ŲŖŲ·ŲØŁŠŁ‚ŲŒ حتى Ų¹ŲÆŁ… القدرة على ŲŖŲ“ŲŗŁŠŁ„ Ų§Ł„ŲŖŲ·ŲØŁŠŁ‚ ŲØŲ§Ł„ŁƒŲ§Ł…Ł„.", + "info_2": "لا ŁŠŁ‡Ł… اسم الملف عند Ų§Ł„ŲŖŲ­Ł…ŁŠŁ„. Ų³ŁŠŲŖŁ… Ų„Ų¹Ų§ŲÆŲ© ŲŖŲ³Ł…ŁŠŲŖŁ‡ ŲØŲ¹ŲÆ Ų°Ł„Łƒ لاتباع Ų§Ł„ŲŖŁ†Ų³ŁŠŁ‚ backup_user_yyyyMMddHHmm.sql، Ł…Ł…Ų§ ŁŠŲ¶Ł…Ł† Ų§ŲŖŲ³Ų§Ł‚ ŲŖŲ³Ł…ŁŠŲ© متناسق.", + "submit": "استيراد النسخة Ų§Ł„Ų§Ų­ŲŖŁŠŲ§Ų·ŁŠŲ©", + "importIntoDatabaseSuccessed": "ŲŖŁ… استيراد قاعدة Ų§Ł„ŲØŁŠŲ§Ł†Ų§ŲŖ بنجاح", + "backupCreated": "Database backup successful", + "fileNotFound": "لم ŁŠŲŖŁ… Ų§Ł„Ų¹Ų«ŁˆŲ± على الملف", + "fileNullOrEmpty": "يجب ألا ŁŠŁƒŁˆŁ† الملف فارغًا أو Ų®Ų§Ł„ŁŠŁ‹Ų§", + "failedImportFile": "فؓل استيراد الملف", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "لقد انتهت Ų¬Ł„Ų³ŲŖŁƒ. ŁŠŲ±Ų¬Ł‰ تحديث الصفحة ŁˆŲ§Ł„Ł…Ų­Ų§ŁˆŁ„Ų© Ł…Ų±Ų© أخرى", + "refreshPage": "تحديث الصفحة" + }, + "home": { + "desc": "Ł…ŲŖŲ¬Ų±Łƒ الؓامل المستضاف Ł…Ų­Ł„ŁŠŁ‹Ų§ Ł„Ų¬Ł…ŁŠŲ¹ احتياجات PDF الخاصة بك.", + "searchBar": "البحث عن Ų§Ł„Ł…ŁŠŲ²Ų§ŲŖ...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Ų¹Ų±Ų¶ ŁˆŲŖŲ¹Ł„ŁŠŁ‚ و؄ضافة نص أو صور" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "Ų£ŲÆŲ§Ų© Ł…ŲŖŲ¹ŲÆŲÆŲ© PDF", + "desc": "ŲÆŁ…Ų¬ الصفحات ŁˆŲŖŲÆŁˆŁŠŲ±Ł‡Ų§ و؄عادة ŲŖŲ±ŲŖŁŠŲØŁ‡Ų§ ŁˆŲ„Ų²Ų§Ł„ŲŖŁ‡Ų§" + }, + "merge": { + "title": "ŲÆŁ…Ų¬ ملفات", + "desc": "ŲÆŁ…Ų¬ ملفات PDF Ł…ŲŖŲ¹ŲÆŲÆŲ© في ملف واحد ŲØŲ³Ł‡ŁˆŁ„Ų©." + }, + "split": { + "title": "ŲŖŁ‚Ų³ŁŠŁ… ملفات", + "desc": "ŲŖŁ‚Ų³ŁŠŁ… ملفات PDF ؄لى مستندات Ł…ŲŖŲ¹ŲÆŲÆŲ©" + }, + "rotate": { + "title": "تدوير ملفات", + "desc": "قم بتدوير ملفات PDF الخاصة بك ŲØŲ³Ł‡ŁˆŁ„Ų©." + }, + "imageToPdf": { + "title": "صورة ؄لى PDF", + "desc": "ŲŖŲ­ŁˆŁŠŁ„ Ų§Ł„ŲµŁˆŲ± (PNG ، JPEG ، GIF) ؄لى PDF." + }, + "pdfToImage": { + "title": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى صورة", + "desc": "ŲŖŲ­ŁˆŁŠŁ„ ملف PDF ؄لى صورة. (PNG ، JPEG ، GIF)" + }, + "pdfOrganiser": { + "title": "منظم", + "desc": "؄زالة / Ų„Ų¹Ų§ŲÆŲ© ترتيب الصفحات بأي ترتيب" + }, + "addImage": { + "title": "؄ضافة صورة ؄لى ملف PDF", + "desc": "؄ضافة صورة ؄لى Ł…ŁˆŁ‚Ų¹ Ł…Ų¹ŁŠŁ† في PDF (العمل Ł‚ŁŠŲÆ التقدم)" + }, + "watermark": { + "title": "؄ضافة علامة Ł…Ų§Ų¦ŁŠŲ©", + "desc": "أضف علامة Ł…Ų§Ų¦ŁŠŲ© Ł…Ų®ŲµŲµŲ© ؄لى مستند PDF الخاص بك." + }, + "permissions": { + "title": "تغيير Ų§Ł„Ų£Ų°ŁˆŁ†Ų§ŲŖ", + "desc": "قم بتغيير Ų£Ų°ŁˆŁ†Ų§ŲŖ مستند PDF الخاص بك" + }, + "removePages": { + "title": "؄زالة الصفحات", + "desc": "حذف الصفحات غير Ų§Ł„Ł…Ų±ŲŗŁˆŲØ ŁŁŠŁ‡Ų§ من مستند PDF الخاص بك." + }, + "addPassword": { + "title": "؄ضافة ŁƒŁ„Ł…Ų© Ł…Ų±ŁˆŲ±", + "desc": "تؓفير مستند PDF الخاص بك ŲØŁƒŁ„Ł…Ų© Ł…Ų±ŁˆŲ±." + }, + "removePassword": { + "title": "؄زالة ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ±", + "desc": "؄زالة Ų§Ł„Ų­Ł…Ų§ŁŠŲ© ŲØŁƒŁ„Ł…Ų© Ł…Ų±ŁˆŲ± من مستند PDF الخاص بك." + }, + "compressPdfs": { + "title": "Ų¶ŲŗŲ· ملفات", + "desc": "Ų¶ŲŗŲ· ملفات PDF Ł„ŲŖŁ‚Ł„ŁŠŁ„ حجم الملف." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "تغيير Ų§Ł„ŲØŁŠŲ§Ł†Ų§ŲŖ Ų§Ł„ŁˆŲµŁŁŠŲ©", + "desc": "تغيير / ؄زالة / ؄ضافة ŲØŁŠŲ§Ł†Ų§ŲŖ Ų£ŁˆŁ„ŁŠŲ© من مستند PDF" + }, + "fileToPDF": { + "title": "ŲŖŲ­ŁˆŁŠŁ„ الملف ؄لى PDF", + "desc": "ŲŖŲ­ŁˆŁŠŁ„ أي ملف ŲŖŁ‚Ų±ŁŠŲØŲ§ ؄لى PDF (DOCX وPNG وXLS وPPT وTXT ŁˆŲ§Ł„Ł…Ų²ŁŠŲÆ)" + }, + "ocr": { + "title": "ŲŖŲ“ŲŗŁŠŁ„ OCR على PDF و / أو Ł…Ų³Ų­ ضوئي", + "desc": "ŁŠŁ‚ŁˆŁ… برنامج Ų§Ł„ŲŖŁ†ŲøŁŠŁ ŲØŁ…Ų³Ų­ واكتؓاف النص من Ų§Ł„ŲµŁˆŲ± داخل ملف PDF ويعيد ؄ضافته ŁƒŁ†Ųµ" + }, + "extractImages": { + "title": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ Ų§Ł„ŲµŁˆŲ±", + "desc": "يستخرج Ų¬Ł…ŁŠŲ¹ Ų§Ł„ŲµŁˆŲ± من ملف PDF ŁˆŁŠŲ­ŁŲøŁ‡Ų§ في الرمز Ų§Ł„ŲØŲ±ŁŠŲÆŁŠ" + }, + "pdfToPDFA": { + "title": "ŲŖŲ­ŁˆŁŠŁ„ ملفات PDF ؄لى PDF / A", + "desc": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى PDF / A Ł„Ł„ŲŖŲ®Ų²ŁŠŁ† Ų·ŁˆŁŠŁ„ المدى" + }, + "PDFToWord": { + "title": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى Word", + "desc": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى ŲŖŁ†Ų³ŁŠŁ‚Ų§ŲŖ Word (DOC و DOCX و ODT)" + }, + "PDFToPresentation": { + "title": "PDF للعرض Ų§Ł„ŲŖŁ‚ŲÆŁŠŁ…ŁŠ", + "desc": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى ŲŖŁ†Ų³ŁŠŁ‚Ų§ŲŖ Ų¹Ų±Ų¶ ŲŖŁ‚ŲÆŁŠŁ…ŁŠ (PPT و PPTX و ODP)" + }, + "PDFToText": { + "title": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى نص / RTF", + "desc": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى ŲŖŁ†Ų³ŁŠŁ‚ نص أو RTF" + }, + "PDFToHTML": { + "title": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى HTML", + "desc": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى ŲŖŁ†Ų³ŁŠŁ‚ HTML" + }, + "PDFToXML": { + "title": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى XML", + "desc": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى ŲŖŁ†Ų³ŁŠŁ‚ XML" + }, + "ScannerImageSplit": { + "title": "كؓف / انقسام Ų§Ł„ŲµŁˆŲ± Ų§Ł„Ł…Ł…Ų³ŁˆŲ­Ų© Ų¶ŁˆŲ¦ŁŠŁ‹Ų§", + "desc": "ŲŖŁ‚Ų³ŁŠŁ… Ų¹ŲÆŲ© صور من داخل صورة / ملف PDF" + }, + "sign": { + "title": "ŲŖŁˆŁ‚ŁŠŲ¹", + "desc": "؄ضافة Ų§Ł„ŲŖŁˆŁ‚ŁŠŲ¹ ؄لى PDF عن Ų·Ų±ŁŠŁ‚ الرسم أو النص أو Ų§Ł„ŲµŁˆŲ±Ų©" + }, + "flatten": { + "title": "تسطيح", + "desc": "قم ب؄زالة كافة العناصر ŁˆŲ§Ł„Ł†Ł…Ų§Ų°Ų¬ Ų§Ł„ŲŖŁŲ§Ų¹Ł„ŁŠŲ© من ملف PDF" + }, + "repair": { + "title": "؄صلاح", + "desc": "ŁŠŲ­Ų§ŁˆŁ„ ؄صلاح ملف PDF تالف / Ł…Ų¹Ų·Ł„" + }, + "removeBlanks": { + "title": "؄زالة الصفحات الفارغة", + "desc": "يكتؓف ŁˆŁŠŲ²ŁŠŁ„ الصفحات الفارغة من المستند" + }, + "removeAnnotations": { + "title": "؄زالة Ų§Ł„ŲŖŲ¹Ł„ŁŠŁ‚Ų§ŲŖ Ų§Ł„ŲŖŁˆŲ¶ŁŠŲ­ŁŠŲ©", + "desc": "ŁŠŲ²ŁŠŁ„ Ų¬Ł…ŁŠŲ¹ Ų§Ł„ŲŖŲ¹Ł„ŁŠŁ‚Ų§ŲŖ/Ų§Ł„ŲŖŲ¹Ł„ŁŠŁ‚Ų§ŲŖ Ų§Ł„ŲŖŁˆŲ¶ŁŠŲ­ŁŠŲ© من ملف PDF" + }, + "compare": { + "title": "مقارنة", + "desc": "ŁŠŁ‚Ų§Ų±Ł† ŁˆŁŠŲøŁ‡Ų± الاختلافات ŲØŁŠŁ† Ł…Ų³ŲŖŁ†ŲÆŁŠŁ† PDF" + }, + "certSign": { + "title": "Ų§Ł„ŲŖŁˆŁ‚ŁŠŲ¹ بالؓهادة", + "desc": "ŁŠŁˆŁ‚Ų¹ ملف PDF بؓهادة/مفتاح (PEM/P12)" + }, + "removeCertSign": { + "title": "؄زالة ŲŖŁˆŁ‚ŁŠŲ¹ الؓهادة", + "desc": "؄زالة ŲŖŁˆŁ‚ŁŠŲ¹ الؓهادة من ملف PDF" + }, + "pageLayout": { + "title": "تخطيط Ł…ŲŖŲ¹ŲÆŲÆ الصفحات", + "desc": "ŲÆŁ…Ų¬ صفحات Ł…ŲŖŲ¹ŲÆŲÆŲ© من مستند PDF في صفحة واحدة" + }, + "scalePages": { + "title": "Ų¶ŲØŲ· حجم/Ł…Ł‚ŁŠŲ§Ų³ الصفحة", + "desc": "تغيير حجم/Ł…Ł‚ŁŠŲ§Ų³ الصفحة و/أو Ł…Ų­ŲŖŁˆŲ§Ł‡Ų§." + }, + "pipeline": { + "title": "Ų®Ų· Ų§Ł„Ų£Ł†Ų§ŲØŁŠŲØ", + "desc": "ŲŖŲ“ŲŗŁŠŁ„ Ų„Ų¬Ų±Ų§Ų”Ų§ŲŖ Ł…ŲŖŲ¹ŲÆŲÆŲ© على ملفات PDF عن Ų·Ų±ŁŠŁ‚ تحديد Ł†ŲµŁˆŲµ Ų®Ų· Ų§Ł„Ų£Ł†Ų§ŲØŁŠŲØ" + }, + "add-page-numbers": { + "title": "؄ضافة أرقام الصفحات", + "desc": "؄ضافة أرقام الصفحات في Ų¬Ł…ŁŠŲ¹ أنحاؔ المستند في Ł…ŁˆŁ‚Ų¹ Ł…Ų­ŲÆŲÆ" + }, + "auto-rename": { + "title": "Ų„Ų¹Ų§ŲÆŲ© ŲŖŲ³Ł…ŁŠŲ© ملف PDF ŲŖŁ„Ł‚Ų§Ų¦ŁŠŁ‹Ų§", + "desc": "Ų„Ų¹Ų§ŲÆŲ© ŲŖŲ³Ł…ŁŠŲ© ملف PDF ŲŖŁ„Ł‚Ų§Ų¦ŁŠŁ‹Ų§ بناًؔ على الرأس Ų§Ł„Ł…ŁƒŲŖŲ“Ł" + }, + "adjust-contrast": { + "title": "Ų¶ŲØŲ· Ų§Ł„Ų£Ł„ŁˆŲ§Ł†/Ų§Ł„ŲŖŲØŲ§ŁŠŁ†", + "desc": "Ų¶ŲØŲ· Ų§Ł„ŲŖŲØŲ§ŁŠŁ† ŁˆŲ§Ł„ŲŖŲ“ŲØŲ¹ ŁˆŲ§Ł„Ų³Ų·ŁˆŲ¹ لملف PDF" + }, + "crop": { + "title": "اقتصاص PDF", + "desc": "اقتصاص ملف PDF Ł„ŲŖŁ‚Ł„ŁŠŁ„ حجمه (Ł…Ų¹ الحفاظ على النص!)" + }, + "autoSplitPDF": { + "title": "ŲŖŁ‚Ų³ŁŠŁ… الصفحات ŲŖŁ„Ł‚Ų§Ų¦ŁŠŁ‹Ų§", + "desc": "ŲŖŁ‚Ų³ŁŠŁ… PDF Ų§Ł„Ł…Ł…Ų³ŁˆŲ­ Ų¶ŁˆŲ¦ŁŠŁ‹Ų§ ŲŖŁ„Ł‚Ų§Ų¦ŁŠŁ‹Ų§ ŲØŲ§Ų³ŲŖŲ®ŲÆŲ§Ł… رمز QR Ł„ŲŖŁ‚Ų³ŁŠŁ… الصفحات Ų§Ł„Ł…Ł…Ų³ŁˆŲ­Ų© Ų¶ŁˆŲ¦ŁŠŁ‹Ų§ ŁŲ¹Ł„ŁŠŁ‹Ų§" + }, + "sanitizePdf": { + "title": "ŲŖŁ†ŲøŁŠŁ", + "desc": "؄زالة البرامج Ų§Ł„Ł†ŲµŁŠŲ© ŁˆŲ§Ł„Ų¹Ł†Ų§ŲµŲ± الأخرى من ملفات PDF" + }, + "URLToPDF": { + "title": "URL/Ł…ŁˆŁ‚Ų¹ ويب ؄لى PDF", + "desc": "ŁŠŲ­ŁˆŁ„ أي Ų¹Ł†ŁˆŲ§Ł† URL للـ http(s) ؄لى PDF" + }, + "HTMLToPDF": { + "title": "HTML ؄لى PDF", + "desc": "ŁŠŲ­ŁˆŁ„ أي ملف HTML أو ملف Ł…Ų¶ŲŗŁˆŲ· يحتوي" + }, + "MarkdownToPDF": { + "title": "Markdown ؄لى PDF", + "desc": "ŁŠŲ­ŁˆŁ„ أي ملف Markdown ؄لى PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "Ų§Ł„Ų­ŲµŁˆŁ„ على Ų¬Ł…ŁŠŲ¹ Ų§Ł„Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖ عن PDF", + "desc": "ŁŠŲ¬Ł…Ų¹ أي ŁˆŁƒŁ„ Ų§Ł„Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖ Ų§Ł„Ł…Ł…ŁƒŁ†Ų© عن ملفات PDF" + }, + "extractPage": { + "title": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ الصفحة (الصفحات)", + "desc": "يستخرج صفحات Ł…Ų­ŲÆŲÆŲ© من PDF" + }, + "PdfToSinglePage": { + "title": "PDF ؄لى صفحة واحدة كبيرة", + "desc": "ŁŠŲÆŁ…Ų¬ Ų¬Ł…ŁŠŲ¹ صفحات PDF في صفحة واحدة كبيرة" + }, + "showJS": { + "title": "؄ظهار جافا سكريبت", + "desc": "يبحث ويعرض أي جافا سكريبت Ł…ŲÆŲ±Ų¬ في PDF" + }, + "autoRedact": { + "title": "Ų­Ų¬ŲØ ŲŖŁ„Ł‚Ų§Ų¦ŁŠ", + "desc": "يحجب (يسود) النص في PDF ŲŖŁ„Ł‚Ų§Ų¦ŁŠŁ‹Ų§ بناًؔ على النص المدخل" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF ؄لى CSV", + "desc": "يستخرج Ų§Ł„Ų¬ŲÆŲ§ŁˆŁ„ من PDF ŁˆŁŠŲ­ŁˆŁ„Ł‡Ų§ ؄لى CSV" + }, + "autoSizeSplitPDF": { + "title": "ŲŖŁ‚Ų³ŁŠŁ… ŲŖŁ„Ł‚Ų§Ų¦ŁŠ Ų­Ų³ŲØ الحجم/العدد", + "desc": "ŲŖŁ‚Ų³ŁŠŁ… ملف PDF واحد ؄لى مستندات Ł…ŲŖŲ¹ŲÆŲÆŲ© بناًؔ على الحجم أو Ų¹ŲÆŲÆ الصفحات أو Ų¹ŲÆŲÆ المستندات" + }, + "overlay-pdfs": { + "title": "تراكب ملفات PDF", + "desc": "يضع ملفات PDF ŁŁˆŁ‚ ملف PDF Ų¢Ų®Ų±" + }, + "split-by-sections": { + "title": "ŲŖŁ‚Ų³ŁŠŁ… PDF Ų­Ų³ŲØ الأقسام", + "desc": "ŲŖŁ‚Ų³ŁŠŁ… ŁƒŁ„ صفحة من PDF ؄لى أقسام Ų£ŁŁ‚ŁŠŲ© ŁˆŲ¹Ł…ŁˆŲÆŁŠŲ© Ų£ŲµŲŗŲ±" + }, + "AddStampRequest": { + "title": "؄ضافة Ų®ŲŖŁ… ؄لى PDF", + "desc": "؄ضافة نص أو ؄ضافة Ų£Ų®ŲŖŲ§Ł… Ų§Ł„ŲµŁˆŲ± في Ł…ŁˆŲ§Ł‚Ų¹ Ł…Ų­ŲÆŲÆŲ©" + }, + "removeImagePdf": { + "title": "؄زالة Ų§Ł„ŲµŁˆŲ±Ų©", + "desc": "؄زالة Ų§Ł„ŲµŁˆŲ±Ų© من PDF Ł„ŲŖŁ‚Ł„ŁŠŁ„ حجم الملف" + }, + "splitPdfByChapters": { + "title": "ŲŖŲ¬Ų²Ų¦Ų© المستندات PDF Ų­Ų³ŲØ Ų§Ł„ŁŲµŁˆŁ„", + "desc": "قسم مستند PDF ؄لى ملفات Ł…ŲŖŲ¹ŲÆŲÆŲ© بناًؔ على Ł‡ŁŠŁƒŁ„ ŁŲµŁˆŁ„Ł‡." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "replaceColorPdf": { + "title": "Ų„Ų³ŲŖŲØŲÆŲ§Ł„ و عكس Ų§Ł„Ų£Ł„ŁˆŲ§Ł†", + "desc": "Ų§Ų³ŲŖŲØŲÆŲ§Ł„ Ų§Ł„Ų£Ł„ŁˆŲ§Ł† Ł„Ł„Ł†ŲµŁˆŲµ ŁˆŲ§Ł„Ų®Ł„ŁŁŠŲ§ŲŖ في المستندات PDF ŁˆŲ„Ł„ŲŗŲ§Ų” تعكير Ų§Ł„Ł„ŁˆŁ† Ų§Ł„ŁƒŲ§Ł…Ł„ للمستند Ł„ŲŖŁ‚Ł„ŁŠŁ„ حجم الملف" + } + }, + "viewPdf": { + "tags": "Ų¹Ų±Ų¶,قراؔة,ŲŖŲ¹Ł„ŁŠŁ‚,نص,صورة", + "title": "View/Edit PDF", + "header": "Ų¹Ų±Ų¶ PDF" + }, + "multiTool": { + "tags": "Ų£ŲÆŲ§Ų© Ł…ŲŖŲ¹ŲÆŲÆŲ©,Ų¹Ł…Ł„ŁŠŲ© Ł…ŲŖŲ¹ŲÆŲÆŲ©,ŁˆŲ§Ų¬Ł‡Ų© Ł…Ų³ŲŖŲ®ŲÆŁ…,النقر ŁˆŲ§Ł„Ų³Ų­ŲØ,ŁˆŲ§Ų¬Ł‡Ų© Ų£Ł…Ų§Ł…ŁŠŲ©,جانب Ų§Ł„Ų¹Ł…ŁŠŁ„", + "title": "Ų£ŲÆŲ§Ų© Ł…ŲŖŲ¹ŲÆŲÆŲ© PDF", + "header": "Ų£ŲÆŲ§Ų© Ł…ŲŖŲ¹ŲÆŲÆŲ© PDF", + "uploadPrompts": "اسم الملف", + "selectAll": "تحديد Ų§Ł„ŁƒŁ„", + "deselectAll": "؄لغاؔ تحديد Ų§Ł„ŁƒŁ„", + "selectPages": "تحديد الصفحة", + "selectedPages": "الصفحات المحددة", + "page": "صفحة", + "deleteSelected": "حذف المحدد", + "downloadAll": "تصدير", + "downloadSelected": "تصدير المحدد", + "insertPageBreak": "Ų„ŲÆŲ±Ų§Ų¬ فاصل صفحات", + "addFile": "؄ضافة ملف", + "rotateLeft": "تدوير ؄لى Ų§Ł„ŁŠŲ³Ų§Ų±", + "rotateRight": "تدوير ؄لى Ų§Ł„ŁŠŁ…ŁŠŁ†", + "split": "ŲŖŁ‚Ų³ŁŠŁ…", + "moveLeft": "تحريك ؄لى Ų§Ł„ŁŠŲ³Ų§Ų±", + "moveRight": "تحريك ؄لى Ų§Ł„ŁŠŁ…ŁŠŁ†", + "delete": "حذف", + "dragDropMessage": "الصفحات المحددة", + "undo": "ŲŖŲ±Ų§Ų¬Ų¹", + "redo": "Ų„Ų¹Ų§ŲÆŲ© Ų„Ų¬Ų±Ų§Ų”" + }, + "merge": { + "tags": "ŲÆŁ…Ų¬,Ų¹Ł…Ł„ŁŠŲ§ŲŖ الصفحة,Ų§Ł„Ų®Ł„ŁŁŠŲ©,جانب الخادم", + "title": "ŲÆŁ…Ų¬", + "header": "ŲÆŁ…Ų¬ ملفات PDF Ł…ŲŖŲ¹ŲÆŲÆŲ© (2+)", + "sortByName": "Ų§Ł„ŲŖŲ±ŲŖŁŠŲØ Ų­Ų³ŲØ الاسم", + "sortByDate": "Ų§Ł„ŲŖŲ±ŲŖŁŠŲØ Ų­Ų³ŲØ Ų§Ł„ŲŖŲ§Ų±ŁŠŲ®", + "removeCertSign": "؄زالة Ų§Ł„ŲŖŁˆŁ‚ŁŠŲ¹ Ų§Ł„Ų±Ł‚Ł…ŁŠ في الملف Ų§Ł„Ł…ŲÆŁ…Ų¬ŲŸ", + "submit": "ŲÆŁ…Ų¬" + }, + "split": { + "tags": "Ų¹Ł…Ł„ŁŠŲ§ŲŖ الصفحة,ŲŖŁ‚Ų³ŁŠŁ…,صفحات Ł…ŲŖŲ¹ŲÆŲÆŲ©,قص,جانب الخادم", + "title": "ŲŖŁ‚Ų³ŁŠŁ… PDF", + "header": "ŲŖŁ‚Ų³ŁŠŁ… PDF", + "desc": { + "1": "الأرقام Ų§Ł„ŲŖŁŠ تحددها Ł‡ŁŠ رقم الصفحة Ų§Ł„ŲŖŁŠ تريد ŲŖŁ‚Ų³ŁŠŁ…Ł‡Ų§", + "2": "على هذا Ų§Ł„Ł†Ų­ŁˆŲŒ سيؤدي تحديد 1،3،7-9 ؄لى ŲŖŁ‚Ų³ŁŠŁ… مستند من 10 صفحات ؄لى 6 PDFS منفصلة Ł…Ų¹:", + "3": "المستند رقم 1: الصفحة 1", + "4": "المستند رقم 2: الصفحتان 2 و 3", + "5": "المستند رقم 3: الصفحة 4 و 5 و 6 و 7", + "6": "المستند رقم 4: الصفحة 8", + "7": "المستند رقم 5: الصفحة 9", + "8": "المستند رقم 6: الصفحة 10" + }, + "splitPages": "أدخل الصفحات المراد ŲŖŁ‚Ų³ŁŠŁ…Ł‡Ų§:", + "submit": "ŲŖŁ‚Ų³ŁŠŁ…" + }, + "rotate": { + "tags": "جانب الخادم", + "title": "تدوير PDF", + "header": "تدوير PDF", + "selectAngle": "Ų­ŲÆŲÆ زاوية Ų§Ł„ŲÆŁˆŲ±Ų§Ł† (بمضاعفات 90 ŲÆŲ±Ų¬Ų©):", + "submit": "تدوير" + }, + "imageToPdf": { + "tags": "ŲŖŲ­ŁˆŁŠŁ„,صورة,jpg,صورة,صورة فوتوغرافية" + }, + "pdfToImage": { + "tags": "ŲŖŲ­ŁˆŁŠŁ„,صورة,jpg,صورة,صورة فوتوغرافية", + "title": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى صورة", + "header": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى صورة", + "selectText": "ŲŖŁ†Ų³ŁŠŁ‚ Ų§Ł„ŲµŁˆŲ±Ų©", + "singleOrMultiple": "Ł†ŁˆŲ¹ Ł†ŲŖŁŠŲ¬Ų© Ų§Ł„ŲµŁˆŲ±Ų©", + "single": "صورة واحدة كبيرة", + "multi": "صور Ł…ŲŖŲ¹ŲÆŲÆŲ©", + "colorType": "Ł†ŁˆŲ¹ Ų§Ł„Ł„ŁˆŁ†", + "color": "Ų§Ł„Ł„ŁˆŁ†", + "grey": "ŲŖŲÆŲ±Ų¬ Ų§Ł„Ų±Ł…Ų§ŲÆŁŠ", + "blackwhite": "أبيض وأسود (قد ŁŠŁŁ‚ŲÆ Ų§Ł„ŲØŁŠŲ§Ł†Ų§ŲŖ!)", + "submit": "ŲŖŲ­ŁˆŁŠŁ„", + "info": "Python غير Ł…Ų«ŲØŲŖ. Ł…Ų·Ł„ŁˆŲØ Ł„ŲŖŲ­ŁˆŁŠŁ„ WebP.", + "placeholder": "(Ł…Ų«Ų§Ł„: 1,2,8 أو 4,7,12-16 أو 2n-1)" + }, + "pdfOrganiser": { + "tags": "Ł…Ų²ŲÆŁˆŲ¬,زوجي,فردي,ترتيب,نقل", + "title": "منظم الصفحة", + "header": "منظم صفحات PDF", + "submit": "Ų„Ų¹Ų§ŲÆŲ© ترتيب الصفحات", + "mode": { + "_value": "Ų§Ł„ŁˆŲ¶Ų¹", + "1": "ترتيب الصفحات المخصص", + "2": "ترتيب عكسي", + "3": "فرز Ł…Ų²ŲÆŁˆŲ¬", + "4": "فرز Ų§Ł„ŁƒŲŖŁŠŲØ", + "5": "فرز كتيب Ų§Ł„Ų®ŁŠŲ§Ų·Ų© Ų§Ł„Ų¬Ų§Ł†ŲØŁŠŲ©", + "6": "ŲŖŁ‚Ų³ŁŠŁ… فردي-زوجي", + "7": "؄زالة Ų§Ł„Ų£ŁˆŁ„", + "8": "؄زالة Ų§Ł„Ų£Ų®ŁŠŲ±", + "9": "؄زالة", + "10": "ŲÆŁ…Ų¬ فردي-زوجي", + "11": "Duplicate all pages" + }, + "placeholder": "(Ł…Ų«Ų§Ł„: 1,3,2 أو 4-8,2,10-12 أو 2n-1)" + }, + "addImage": { + "tags": "صورة,jpg,صورة,صورة فوتوغرافية", + "title": "؄ضافة صورة", + "header": "؄ضافة صورة ؄لى PDF", + "everyPage": "ŁƒŁ„ صفحة؟", + "upload": "؄ضافة صورة", + "submit": "؄ضافة صورة" + }, + "watermark": { + "tags": "نص,تكرار,ŲŖŲ³Ł…ŁŠŲ©,Ų®Ų§Ųµ,Ų­Ł‚ŁˆŁ‚ النؓر,علامة تجارية,صورة,jpg,صورة,صورة فوتوغرافية", + "title": "؄ضافة علامة Ł…Ų§Ų¦ŁŠŲ©", + "header": "؄ضافة علامة Ł…Ų§Ų¦ŁŠŲ©", + "customColor": "Ł„ŁˆŁ† نص Ł…Ų®ŲµŲµ", + "selectText": { + "1": "Ų­ŲÆŲÆ PDF ل؄ضافة العلامة Ų§Ł„Ł…Ų§Ų¦ŁŠŲ© Ų„Ł„ŁŠŁ‡:", + "2": "نص العلامة Ų§Ł„Ł…Ų§Ų¦ŁŠŲ©:", + "3": "حجم الخط:", + "4": "ŲÆŁˆŲ±Ų§Ł† (0-360):", + "5": "المباعدة Ų§Ł„Ų£ŁŁ‚ŁŠŲ© (مسافة ŲØŁŠŁ† ŁƒŁ„ علامة Ł…Ų§Ų¦ŁŠŲ© Ų£ŁŁ‚ŁŠŁ‹Ų§):", + "6": "المباعدة Ų§Ł„Ų¹Ł…ŁˆŲÆŁŠŲ© (مسافة ŲØŁŠŁ† ŁƒŁ„ علامة Ł…Ų§Ų¦ŁŠŲ© Ų¹Ł…ŁˆŲÆŁŠŁ‹Ų§):", + "7": "Ų§Ł„Ų“ŁŲ§ŁŁŠŲ© (0ŁŖ - 100ŁŖ):", + "8": "Ł†ŁˆŲ¹ العلامة Ų§Ł„Ł…Ų§Ų¦ŁŠŲ©:", + "9": "صورة العلامة Ų§Ł„Ł…Ų§Ų¦ŁŠŲ©:", + "10": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى صورة PDF" + }, + "submit": "؄ضافة علامة Ł…Ų§Ų¦ŁŠŲ©", + "type": { + "1": "نص", + "2": "صورة" + } + }, + "permissions": { + "tags": "قراؔة,كتابة,تحرير,Ų·ŲØŲ§Ų¹Ų©", + "title": "تغيير Ų§Ł„Ų£Ų°ŁˆŁ†Ų§ŲŖ", + "header": "تغيير Ų§Ł„Ų£Ų°ŁˆŁ†Ų§ŲŖ", + "warning": "تحذير من أن ŲŖŁƒŁˆŁ† هذه Ų§Ł„Ų£Ų°ŁˆŁ†Ų§ŲŖ غير قابلة Ł„Ł„ŲŖŲŗŁŠŁŠŲ±ŲŒ ŁŠŁˆŲµŁ‰ ŲØŲŖŲ¹ŁŠŁŠŁ†Ł‡Ų§ ŲØŁƒŁ„Ł…Ų© Ł…Ų±ŁˆŲ± Ų¹ŲØŲ± صفحة ؄ضافة ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ±", + "selectText": { + "1": "Ų­ŲÆŲÆ ملف PDF Ł„ŲŖŲŗŁŠŁŠŲ± Ų§Ł„Ų£Ų°ŁˆŁ†Ų§ŲŖ", + "2": "Ų£Ų°ŁˆŁ†Ų§ŲŖ Ł„ŲŖŲ¹ŁŠŁŠŁ†Ł‡Ų§", + "3": "منع ŲŖŲ¬Ł…ŁŠŲ¹ المستند", + "4": "منع Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ Ų§Ł„Ł…Ų­ŲŖŁˆŁ‰", + "5": "منع الاستخراج Ł„Ł„ŁˆŲµŁˆŁ„", + "6": "منع ملؔ Ų§Ł„Ł†Ł…ŁˆŲ°Ų¬", + "7": "منع Ų§Ł„ŲŖŲ¹ŲÆŁŠŁ„", + "8": "منع ŲŖŲ¹ŲÆŁŠŁ„ Ų§Ł„ŲŖŲ¹Ł„ŁŠŁ‚ Ų§Ł„ŲŖŁˆŲ¶ŁŠŲ­ŁŠ", + "9": "منع الطباعة", + "10": "منع Ų·ŲØŲ§Ų¹Ų© Ų§Ł„ŲŖŁ†Ų³ŁŠŁ‚Ų§ŲŖ المختلفة" + }, + "submit": "تغيير" + }, + "removePages": { + "tags": "؄زالة الصفحات,حذف الصفحات" + }, + "addPassword": { + "tags": "ŲŖŲ£Ł…ŁŠŁ†,أمان", + "title": "؄ضافة ŁƒŁ„Ł…Ų© Ł…Ų±ŁˆŲ±", + "header": "؄ضافة ŁƒŁ„Ł…Ų© Ł…Ų±ŁˆŲ± (تؓفير)", + "selectText": { + "1": "Ų­ŲÆŲÆ ملف PDF Ł„Ł„ŲŖŲ“ŁŁŠŲ±", + "2": "ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ±", + "3": "Ų·ŁˆŁ„ مفتاح Ų§Ł„ŲŖŲ“ŁŁŠŲ±", + "4": "Ų§Ł„Ł‚ŁŠŁ… الأعلى ŲŖŁƒŁˆŁ† Ų£Ł‚ŁˆŁ‰ŲŒ Ł„ŁƒŁ† Ų§Ł„Ł‚ŁŠŁ… الأقل لها ŲŖŁˆŲ§ŁŁ‚ أفضل.", + "5": "Ų£Ų°ŁˆŁ†Ų§ŲŖ Ł„Ł„ŲŖŲ¹ŁŠŁŠŁ†", + "6": "منع ŲŖŲ¬Ł…ŁŠŲ¹ المستند", + "7": "منع Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ Ų§Ł„Ł…Ų­ŲŖŁˆŁ‰", + "8": "منع الاستخراج Ł„Ł„ŁˆŲµŁˆŁ„", + "9": "منع ملؔ Ų§Ł„Ł†Ł…ŁˆŲ°Ų¬", + "10": "منع Ų§Ł„ŲŖŲ¹ŲÆŁŠŁ„", + "11": "منع ŲŖŲ¹ŲÆŁŠŁ„ Ų§Ł„ŲŖŲ¹Ł„ŁŠŁ‚Ų§ŲŖ Ų§Ł„ŲŖŁˆŲ¶ŁŠŲ­ŁŠŲ©", + "12": "منع الطباعة", + "13": "منع Ų·ŲØŲ§Ų¹Ų© ŲŖŁ†Ų³ŁŠŁ‚Ų§ŲŖ مختلفة", + "14": "ŁƒŁ„Ł…Ų© Ł…Ų±ŁˆŲ± Ų§Ł„Ł…Ų§Ł„Łƒ", + "15": "ŁŠŁ‚ŁŠŲÆ Ł…Ų§ ŁŠŁ…ŁƒŁ† Ų§Ł„Ł‚ŁŠŲ§Ł… به بالمستند ŲØŁ…Ų¬Ų±ŲÆ فتحه (غير Ł…ŲÆŲ¹ŁˆŁ… من قبل Ų¬Ł…ŁŠŲ¹ القراؔ)", + "16": "ŁŠŁ‚ŁŠŲÆ فتح المستند نفسه" + }, + "submit": "تؓفير" + }, + "removePassword": { + "tags": "ŲŖŲ£Ł…ŁŠŁ†,فك Ų§Ł„ŲŖŲ“ŁŁŠŲ±,أمان,؄زالة ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ±,حذف ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ±", + "title": "؄زالة ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ±", + "header": "؄زالة ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± (فك Ų§Ł„ŲŖŲ“ŁŁŠŲ±)", + "selectText": { + "1": "Ų­ŲÆŲÆ PDF Ł„ŁŁƒ Ų§Ł„ŲŖŲ“ŁŁŠŲ±", + "2": "ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ±" + }, + "submit": "؄زالة" + }, + "compressPdfs": { + "tags": "Ų¶ŲŗŲ·,صغير,Ų¶Ų¦ŁŠŁ„" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Ų¹Ł†ŁˆŲ§Ł†,مؤلف,تاريخ,؄نؓاؔ,ŁˆŁ‚ŲŖ,ناؓر,منتج,؄حصائيات", + "title": "Ų§Ł„Ų¹Ł†ŁˆŲ§Ł†:", + "header": "تغيير Ų§Ł„ŲØŁŠŲ§Ł†Ų§ŲŖ Ų§Ł„ŁˆŲµŁŁŠŲ©", + "selectText": { + "1": "ŁŠŲ±Ų¬Ł‰ ŲŖŲ¹ŲÆŁŠŁ„ Ų§Ł„Ł…ŲŖŲŗŁŠŲ±Ų§ŲŖ Ų§Ł„ŲŖŁŠ ŲŖŲ±ŲŗŲØ في ŲŖŲŗŁŠŁŠŲ±Ł‡Ų§", + "2": "حذف ŁƒŁ„ Ų§Ł„ŲØŁŠŲ§Ł†Ų§ŲŖ Ų§Ł„Ų£ŁˆŁ„ŁŠŲ©", + "3": "؄ظهار Ų§Ł„ŲØŁŠŲ§Ł†Ų§ŲŖ Ų§Ł„Ų£ŁˆŁ„ŁŠŲ© المخصصة:", + "4": "ŲØŁŠŲ§Ł†Ų§ŲŖ وصفية أخرى:", + "5": "؄ضافة Ų„ŲÆŲ®Ų§Ł„ ŲØŁŠŲ§Ł†Ų§ŲŖ Ų£ŁˆŁ„ŁŠŲ© Ł…Ų®ŲµŲµ" + }, + "author": "المؤلف:", + "creationDate": "تاريخ ال؄نؓاؔ (yyyy/MM/dd HH:mm:ss):", + "creator": "المنؓئ:", + "keywords": "Ų§Ł„ŁƒŁ„Ł…Ų§ŲŖ Ų§Ł„Ų±Ų¦ŁŠŲ³ŁŠŲ©:", + "modDate": "تاريخ Ų§Ł„ŲŖŲ¹ŲÆŁŠŁ„ (yyyy/MM/dd HH:mm:ss):", + "producer": "المنتج:", + "subject": "Ų§Ł„Ł…ŁˆŲ¶ŁˆŲ¹:", + "trapped": "Ł…Ų­Ų§ŲµŲ±:", + "submit": "تغيير" + }, + "fileToPDF": { + "tags": "ŲŖŲ­ŁˆŁŠŁ„,ŲŖŁ†Ų³ŁŠŁ‚,مستند,صورة,ؓريحة,نص,ŲŖŲ­ŁˆŁŠŁ„,Ł…ŁƒŲŖŲØ,مستندات,وورد,Ų„ŁƒŲ³Ł„,ŲØŲ§ŁˆŲ±ŲØŁˆŁŠŁ†ŲŖ", + "title": "ملف ؄لى PDF", + "header": "ŲŖŲ­ŁˆŁŠŁ„ أي ملف ؄لى PDF", + "credit": "ŲŖŲ³ŲŖŲ®ŲÆŁ… هذه الخدمة LibreOffice و Unoconv Ł„ŲŖŲ­ŁˆŁŠŁ„ الملفات.", + "supportedFileTypesInfo": "Ų£Ł†ŁˆŲ§Ų¹ الملفات Ų§Ł„Ł…ŲÆŲ¹ŁˆŁ…Ų©", + "supportedFileTypes": "يجب أن تتضمن Ų£Ł†ŁˆŲ§Ų¹ الملفات Ų§Ł„Ł…ŲÆŲ¹ŁˆŁ…Ų© Ł…Ų§ ŁŠŁ„ŁŠŲŒ ŁˆŁ„ŁƒŁ† Ł„Ł„Ų­ŲµŁˆŁ„ على قائمة Ł…Ų­ŲÆŲ«Ų© ŁƒŲ§Ł…Ł„Ų© ŲØŲ§Ł„ŲŖŁ†Ų³ŁŠŁ‚Ų§ŲŖ Ų§Ł„Ł…ŲÆŲ¹ŁˆŁ…Ų©ŲŒ ŁŠŲ±Ų¬Ł‰ Ų§Ł„Ų±Ų¬ŁˆŲ¹ ؄لى ŁˆŲ«Ų§Ų¦Ł‚ LibreOffice", + "submit": "ŲŖŲ­ŁˆŁŠŁ„ ؄لى PDF" + }, + "ocr": { + "tags": "تعرف,نص,صورة,Ł…Ų³Ų­,قراؔة,تحديد,كؓف,قابل Ł„Ł„ŲŖŲ­Ų±ŁŠŲ±", + "title": "التعرف Ų§Ł„Ų¶ŁˆŲ¦ŁŠ على Ų§Ł„Ų­Ų±ŁˆŁ / ŲŖŁ†ŲøŁŠŁ المسح Ų§Ł„Ų¶ŁˆŲ¦ŁŠ", + "header": "Ł…Ų³Ų­ المسح Ų§Ł„Ų¶ŁˆŲ¦ŁŠ / التعرف Ų§Ł„Ų¶ŁˆŲ¦ŁŠ على Ų§Ł„Ų­Ų±ŁˆŁ (OCR)", + "selectText": { + "1": "Ų­ŲÆŲÆ اللغات Ų§Ł„ŲŖŁŠ Ų³ŁŠŲŖŁ… Ų§ŁƒŲŖŲ“Ų§ŁŁ‡Ų§ داخل ملف PDF (اللغات المدرجة Ł‡ŁŠ ŲŖŁ„Łƒ Ų§Ł„ŲŖŁŠ ŲŖŁ… Ų§ŁƒŲŖŲ“Ų§ŁŁ‡Ų§ Ų­Ų§Ł„ŁŠŁ‹Ų§):", + "2": "؄نتاج ملف Ł†ŲµŁŠ يحتوي على نص OCR بجانب ملف PDF Ų§Ł„Ų°ŁŠ ŲŖŁ… ؄عداده بواسطة OCR", + "3": "تصحيح الصفحات Ų§Ł„Ł…Ł…Ų³ŁˆŲ­Ų© Ų¶ŁˆŲ¦ŁŠŁ‹Ų§ بزاوية منحرفة عن Ų·Ų±ŁŠŁ‚ ŲŖŲÆŁˆŁŠŲ±Ł‡Ų§ Ł…Ų±Ų© أخرى في Ł…ŁƒŲ§Ł†Ł‡Ų§", + "4": "ŲŖŁ†ŲøŁŠŁ الصفحة بحيث من غير المحتمل أن يجد OCR نصًا في ضوضاؔ Ų§Ł„Ų®Ł„ŁŁŠŲ©. (لا يوجد تغيير في ال؄خراج)", + "5": "ŲŖŁ†ŲøŁŠŁ Ų§Ł„ŲµŁŲ­Ų©ŲŒ بحيث من غير المحتمل أن يجد OCR نصًا في ضوضاؔ Ų§Ł„Ų®Ł„ŁŁŠŲ©ŲŒ ويحافظ على Ų§Ł„ŲŖŁ†ŲøŁŠŁ في ال؄خراج.", + "6": "تجاهل الصفحات Ų§Ł„ŲŖŁŠ تحتوي على نص ŲŖŁŲ§Ų¹Ł„ŁŠŲŒ فقط صفحات OCR Ų§Ł„ŲŖŁŠ Ł‡ŁŠ صور", + "7": "فرض التعرف Ų§Ł„Ų¶ŁˆŲ¦ŁŠ على Ų§Ł„Ų­Ų±ŁˆŁŲŒ سيؤدي التعرف Ų§Ł„Ų¶ŁˆŲ¦ŁŠ على Ų§Ł„Ų­Ų±ŁˆŁ على ŁƒŁ„ صفحة ؄لى ؄زالة Ų¬Ł…ŁŠŲ¹ عناصر النص Ų§Ł„Ų£ŲµŁ„ŁŠ", + "8": "عادي (Ų®Ų·Ų£ Ų„Ų°Ų§ ŁƒŲ§Ł† PDF يحتوي على نص)", + "9": "Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ ؄ضافية", + "10": "وضع التعرف Ų§Ł„Ų¶ŁˆŲ¦ŁŠ على Ų§Ł„Ų­Ų±ŁˆŁ", + "11": "؄زالة Ų§Ł„ŲµŁˆŲ± ŲØŲ¹ŲÆ التعرف Ų§Ł„Ų¶ŁˆŲ¦ŁŠ على Ų§Ł„Ų­Ų±ŁˆŁ (ŁŠŲ²ŁŠŁ„ ŁƒŁ„ Ų§Ł„ŲµŁˆŲ±ŲŒ ŁŠŁƒŁˆŁ† Ł…ŁŁŠŲÆŁ‹Ų§ فقط Ų„Ų°Ų§ ŁƒŲ§Ł† جزًؔا من خطوة Ų§Ł„ŲŖŲ­ŁˆŁŠŁ„)", + "12": "Ł†ŁˆŲ¹ العرض (متقدم)" + }, + "help": "ŁŠŲ±Ų¬Ł‰ قراؔة هذه Ų§Ł„ŁˆŲ«Ų§Ų¦Ł‚ Ų­ŁˆŁ„ كيفية Ų§Ų³ŲŖŲ®ŲÆŲ§Ł… هذا للغات أخرى و/أو الاستخدام Ł„ŁŠŲ³ في Docker", + "credit": "ŲŖŲ³ŲŖŲ®ŲÆŁ… هذه الخدمة qpdf و Tesseract للتعرف Ų§Ł„Ų¶ŁˆŲ¦ŁŠ على Ų§Ł„Ų­Ų±ŁˆŁ.", + "submit": "معالجة PDF ŲØŲ§Ų³ŲŖŲ®ŲÆŲ§Ł… OCR" + }, + "extractImages": { + "tags": "صورة,صورة فوتوغرافية,حفظ,أرؓيف,ملف Ł…Ų¶ŲŗŁˆŲ·,التقاط,انتزاع", + "title": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ Ų§Ł„ŲµŁˆŲ±", + "header": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ Ų§Ł„ŲµŁˆŲ±", + "selectText": "Ų­ŲÆŲÆ ŲŖŁ†Ų³ŁŠŁ‚ Ų§Ł„ŲµŁˆŲ±Ų© Ł„ŲŖŲ­ŁˆŁŠŁ„ Ų§Ł„ŲµŁˆŲ± المستخرجة Ų„Ł„ŁŠŁ‡", + "allowDuplicates": "حفظ Ų§Ł„ŲµŁˆŲ± Ų§Ł„Ł…ŁƒŲ±Ų±Ų©", + "submit": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬" + }, + "pdfToPDFA": { + "tags": "أرؓيف,Ų·ŁˆŁŠŁ„ الأجل,Ł…Ų¹ŁŠŲ§Ų±,ŲŖŲ­ŁˆŁŠŁ„,ŲŖŲ®Ų²ŁŠŁ†,حفظ", + "title": "PDF ؄لى PDF/A", + "header": "PDF ؄لى PDF/A", + "credit": "ŲŖŲ³ŲŖŲ®ŲÆŁ… هذه الخدمة libreoffice Ł„ŲŖŲ­ŁˆŁŠŁ„ PDF/A.", + "submit": "ŲŖŲ­ŁˆŁŠŁ„", + "tip": "لا ŁŠŲ¹Ł…Ł„ Ų­Ų§Ł„ŁŠŁ‹Ų§ لمدخلات Ł…ŲŖŲ¹ŲÆŲÆŲ© في ŁˆŁ‚ŲŖ واحد", + "outputFormat": "ŲŖŁ†Ų³ŁŠŁ‚ ال؄خراج", + "pdfWithDigitalSignature": "يحتوي PDF على ŲŖŁˆŁ‚ŁŠŲ¹ Ų±Ł‚Ł…ŁŠ. Ų³ŁŠŲŖŁ… ؄زالة هذا في Ų§Ł„Ų®Ų·ŁˆŲ© Ų§Ł„ŲŖŲ§Ł„ŁŠŲ©." + }, + "PDFToWord": { + "tags": "doc,docx,odt,وورد,ŲŖŲ­ŁˆŁŠŁ„,ŲŖŁ†Ų³ŁŠŁ‚,ŲŖŲ­ŁˆŁŠŁ„,Ł…ŁƒŲŖŲØ,Ł…Ų§ŁŠŁƒŲ±ŁˆŲ³ŁˆŁŲŖ,ملف المستند", + "title": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى Word", + "header": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى Word", + "selectText": { + "1": "ŲŖŁ†Ų³ŁŠŁ‚ ملف ال؄خراج" + }, + "credit": "ŲŖŲ³ŲŖŲ®ŲÆŁ… هذه الخدمة LibreOffice Ł„ŲŖŲ­ŁˆŁŠŁ„ الملفات.", + "submit": "ŲŖŲ­ŁˆŁŠŁ„" + }, + "PDFToPresentation": { + "tags": "Ų“Ų±Ų§Ų¦Ų­,Ų¹Ų±Ų¶,Ł…ŁƒŲŖŲØ,Ł…Ų§ŁŠŁƒŲ±ŁˆŲ³ŁˆŁŲŖ", + "title": "PDF للعرض Ų§Ł„ŲŖŁ‚ŲÆŁŠŁ…ŁŠ", + "header": "PDF للعرض Ų§Ł„ŲŖŁ‚ŲÆŁŠŁ…ŁŠ", + "selectText": { + "1": "ŲŖŁ†Ų³ŁŠŁ‚ ملف ال؄خراج" + }, + "credit": "ŲŖŲ³ŲŖŲ®ŲÆŁ… هذه الخدمة LibreOffice Ł„ŲŖŲ­ŁˆŁŠŁ„ الملف.", + "submit": "ŲŖŲ­ŁˆŁŠŁ„" + }, + "PDFToText": { + "tags": "ŲŖŁ†Ų³ŁŠŁ‚ نص ŲŗŁ†ŁŠ,ŲŖŁ†Ų³ŁŠŁ‚ نص ŲŗŁ†ŁŠ,ŲŖŁ†Ų³ŁŠŁ‚ نص ŲŗŁ†ŁŠ", + "title": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى نص / RTF", + "header": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى نص / RTF", + "selectText": { + "1": "ŲŖŁ†Ų³ŁŠŁ‚ ملف ال؄خراج" + }, + "credit": "ŲŖŲ³ŲŖŲ®ŲÆŁ… هذه الخدمة LibreOffice Ł„ŲŖŲ­ŁˆŁŠŁ„ الملفات.", + "submit": "ŲŖŲ­ŁˆŁŠŁ„" + }, + "PDFToHTML": { + "tags": "Ł…Ų­ŲŖŁˆŁ‰ Ų§Ł„ŁˆŁŠŲØ,Ł…ŲŖŁˆŲ§ŁŁ‚ Ł…Ų¹ المتصفح", + "title": "PDF ؄لى HTML", + "header": "PDF ؄لى HTML", + "credit": "ŲŖŲ³ŲŖŲ®ŲÆŁ… هذه الخدمة pdftohtml Ł„ŲŖŲ­ŁˆŁŠŁ„ الملفات.", + "submit": "ŲŖŲ­ŁˆŁŠŁ„" + }, + "PDFToXML": { + "tags": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ Ų§Ł„ŲØŁŠŲ§Ł†Ų§ŲŖ,Ł…Ų­ŲŖŁˆŁ‰ منظم,ŲŖŲ“ŲŗŁŠŁ„ ŲØŁŠŁ†ŁŠ,ŲŖŲ­ŁˆŁŠŁ„,ŲŖŲ­ŁˆŁŠŁ„", + "title": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى XML", + "header": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى XML", + "credit": "ŲŖŲ³ŲŖŲ®ŲÆŁ… هذه الخدمة LibreOffice Ł„ŲŖŲ­ŁˆŁŠŁ„ الملفات.", + "submit": "ŲŖŲ­ŁˆŁŠŁ„" + }, + "ScannerImageSplit": { + "tags": "فصل,كؓف ŲŖŁ„Ł‚Ų§Ų¦ŁŠ,Ł…Ų³Ų­ ضوئي,صور Ł…ŲŖŲ¹ŲÆŲÆŲ©,ŲŖŁ†ŲøŁŠŁ…", + "selectText": { + "1": "Ų¹ŲŖŲØŲ© Ų§Ł„Ų²Ų§ŁˆŁŠŲ©:", + "2": "ŲŖŲ¹ŁŠŁŠŁ† الحد الأدنى Ł„Ł„Ų²Ų§ŁˆŁŠŲ© المطلقة Ų§Ł„Ł…Ų·Ł„ŁˆŲØŲ© Ł„ŲŖŲÆŁˆŁŠŲ± Ų§Ł„ŲµŁˆŲ±Ų© (Ų§Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ: 10).", + "3": "التسامح:", + "4": "يحدد نطاق ŲŖŲØŲ§ŁŠŁ† Ų§Ł„Ł„ŁˆŁ† Ų­ŁˆŁ„ Ł„ŁˆŁ† Ų§Ł„Ų®Ł„ŁŁŠŲ© المقدر (Ų§Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ: 30).", + "5": "أدنى Ł…Ų³Ų§Ų­Ų©:", + "6": "ŲŖŲ¹ŁŠŁŠŁ† الحد الأدنى لمنطقة Ų§Ł„ŲµŁˆŲ±Ų© (Ų§Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ: 10000).", + "7": "الحد الأدنى لمنطقة Ų§Ł„Ł…Ų­ŁŠŲ·:", + "8": "ŲŖŲ¹ŁŠŁŠŁ† الحد الأدنى لمنطقة Ų§Ł„Ł…Ų­ŁŠŲ· Ł„Ł„ŲµŁˆŲ±Ų©", + "9": "حجم Ų§Ł„Ų­ŲÆŁˆŲÆ:", + "10": "يضبط حجم Ų§Ł„Ų­ŲÆŁˆŲÆ المضافة ŁˆŲ§Ł„Ł…Ų²Ų§Ł„Ų© لمنع Ų§Ł„Ų­ŲÆŁˆŲÆ Ų§Ł„ŲØŁŠŲ¶Ų§Ų” في ال؄خراج (Ų§Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ: 1)." + }, + "info": "Python غير Ł…Ų«ŲØŲŖ. Ł…Ų·Ł„ŁˆŲØ Ł„Ł„ŲŖŲ“ŲŗŁŠŁ„." + }, + "sign": { + "tags": "ŲŖŲ®ŁˆŁŠŁ„,الأحرف Ų§Ł„Ų£ŁˆŁ„Ł‰,ŲŖŁˆŁ‚ŁŠŲ¹ Ł…Ų±Ų³ŁˆŁ…,ŲŖŁˆŁ‚ŁŠŲ¹ Ł†ŲµŁŠ,ŲŖŁˆŁ‚ŁŠŲ¹ ŲØŲ§Ł„ŲµŁˆŲ±Ų©", + "title": "ŲŖŁˆŁ‚ŁŠŲ¹", + "header": "ŲŖŁˆŁ‚ŁŠŲ¹ ملفات PDF", + "upload": "ŲŖŲ­Ł…ŁŠŁ„ Ų§Ł„ŲµŁˆŲ±Ų©", + "draw": "رسم Ų§Ł„ŲŖŁˆŁ‚ŁŠŲ¹", + "text": "Ų„ŲÆŲ®Ų§Ł„ النص", + "clear": "Ł…Ų³Ų­", + "add": "؄ضافة", + "saved": "ŲŖŁˆŁ‚ŁŠŲ¹Ų§ŲŖ ŲŖŁ… حفظها", + "save": "حفظ ŲŖŁˆŁ‚ŁŠŲ¹", + "personalSigs": "ŲŖŁˆŁ‚ŁŠŲ¹Ų§ŲŖ ؓخصية", + "sharedSigs": "ŲŖŁˆŁ‚ŁŠŲ¹Ų§ŲŖ Ł…Ų“ŲŖŲ±ŁƒŲ©", + "noSavedSigs": "لم ŁŠŲŖŁ… Ų§Ł„Ų¹Ų«ŁˆŲ± على ŲŖŁˆŁ‚ŁŠŲ¹Ų§ŲŖ Ł…Ų­ŁŁˆŲøŲ©", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "Ų«Ų§ŲØŲŖ,؄لغاؔ Ų§Ł„ŲŖŁ†Ų“ŁŠŲ·,غير ŲŖŁŲ§Ų¹Ł„ŁŠ,تبسيط", + "title": "تسطيح", + "header": "تسطيح ملفات PDF", + "flattenOnlyForms": "تسطيح النماذج فقط", + "submit": "تسطيح" + }, + "repair": { + "tags": "؄صلاح,Ų§Ų³ŲŖŲ¹Ų§ŲÆŲ©,تصحيح,Ų§Ų³ŲŖŲ±ŲÆŲ§ŲÆ", + "title": "؄صلاح", + "header": "؄صلاح ملفات PDF", + "submit": "؄صلاح" + }, + "removeBlanks": { + "tags": "ŲŖŁ†ŲøŁŠŁ,تبسيط,ŲØŲÆŁˆŁ† Ł…Ų­ŲŖŁˆŁ‰,ŲŖŁ†ŲøŁŠŁ…", + "title": "؄زالة الفراغات", + "header": "؄زالة الصفحات الفارغة", + "threshold": "العتبة:", + "thresholdDesc": "الحد الفاصل Ł„ŲŖŲ­ŲÆŁŠŲÆ مدى بياض Ų§Ł„ŲØŁƒŲ³Ł„ Ų§Ł„Ų£ŲØŁŠŲ¶", + "whitePercent": "نسبة Ų§Ł„Ų£ŲØŁŠŲ¶ (%):", + "whitePercentDesc": "النسبة Ų§Ł„Ł…Ų¦ŁˆŁŠŲ© للصفحة Ų§Ł„ŲŖŁŠ يجب أن ŲŖŁƒŁˆŁ† بيضاؔ لتتم ؄زالتها", + "submit": "؄زالة الفراغات" + }, + "removeAnnotations": { + "tags": "ŲŖŲ¹Ł„ŁŠŁ‚Ų§ŲŖ,ŲŖŲøŁ„ŁŠŁ„,ملاحظات,علامات,؄زالة", + "title": "؄زالة Ų§Ł„ŲŖŲ¹Ł„ŁŠŁ‚Ų§ŲŖ Ų§Ł„ŲŖŁˆŲ¶ŁŠŲ­ŁŠŲ©", + "header": "؄زالة Ų§Ł„ŲŖŲ¹Ł„ŁŠŁ‚Ų§ŲŖ Ų§Ł„ŲŖŁˆŲ¶ŁŠŲ­ŁŠŲ©", + "submit": "؄زالة" + }, + "compare": { + "tags": "ŲŖŁ…ŁŠŁŠŲ² الاختلافات,مقارنة,تغييرات,ŲŖŲ­Ł„ŁŠŁ„", + "title": "مقارنة", + "header": "مقارنة ملفات PDF", + "highlightColor": { + "1": "Ł„ŁˆŁ† Ų§Ł„ŲŖŲøŁ„ŁŠŁ„ 1:", + "2": "Ł„ŁˆŁ† Ų§Ł„ŲŖŲøŁ„ŁŠŁ„ 2:" + }, + "document": { + "1": "المستند 1", + "2": "المستند 2" + }, + "submit": "مقارنة", + "complex": { + "message": "أو ŁƒŁ„Ų§ Ų§Ł„Ł…Ų³ŲŖŁ†ŲÆŁŠŁ† Ų§Ł„Ł…Ł‚ŲÆŁ…ŁŠŁ† ŁƒŲØŁŠŲ±Ų§Ł† Ų­Ų¬Ł…Ł‹Ų§ŲŒ Ł…Ł…Ų§ يؤدي ؄لى ŲŖŁ‚Ł„ŁŠŁ„ دقة المقارنة" + }, + "large": { + "file": { + "message": "أو ŁƒŁ„Ų§ Ų§Ł„Ł…Ų³ŲŖŁ†ŲÆŁŠŁ† Ų§Ł„Ł…Ł‚ŲÆŁ…ŁŠŁ† كبيرة حجمهما للتعامل معهما" + } + }, + "no": { + "text": { + "message": "Ų£Ų­ŲÆ أو ŁƒŁ„ŁŠ المستندات Ų§Ł„Ł…Ų±Ų¬ŁˆŲ© للمقارنة لا يحتوي على Ł…Ų­ŲŖŁˆŁ‰ Ł†ŲµŁŠ. ŁŠŲ±Ų¬Ł‰ اختيار مستندات تحتوي على نص لم ŁŠŲŖŁ… التعرف Ų¹Ł„ŁŠŁ‡." + } + } + }, + "certSign": { + "tags": "مصادقة,PEM,P12,Ų±Ų³Ł…ŁŠ,تؓفير", + "title": "ŲŖŁˆŁ‚ŁŠŲ¹ الؓهادة", + "header": "قم ŲØŲŖŁˆŁ‚ŁŠŲ¹ ملف PDF ŲØŲ“Ł‡Ų§ŲÆŲŖŁƒ (العمل Ł‚ŁŠŲÆ التقدم)", + "selectPDF": "Ų­ŲÆŲÆ ملف PDF Ł„Ł„ŲŖŁˆŁ‚ŁŠŲ¹:", + "jksNote": "ملاحظة: Ų„Ų°Ų§ لم ŁŠŁƒŁ† Ł†ŁˆŲ¹ Ų“Ł‡Ų§ŲÆŲŖŁƒ مدرجًا Ų£ŲÆŁ†Ų§Ł‡ŲŒ ŁŠŲ±Ų¬Ł‰ ŲŖŲ­ŁˆŁŠŁ„Ł‡Ų§ ؄لى ملف مخزن Ł…ŁŲ§ŲŖŁŠŲ­ جافا (.jks) ŲØŲ§Ų³ŲŖŲ®ŲÆŲ§Ł… Ų£ŲÆŲ§Ų© Ų³Ų·Ų± Ų§Ł„Ų£ŁˆŲ§Ł…Ų± keytool. Ų«Ł… Ų§Ų®ŲŖŲ± خيار ملف .jks أدناه.", + "selectKey": "Ų­ŲÆŲÆ ملف المفتاح الخاص (ŲŖŁ†Ų³ŁŠŁ‚ PKCS # 8 ، ŁŠŁ…ŁƒŁ† أن ŁŠŁƒŁˆŁ† .pem أو .der):", + "selectCert": "Ų­ŲÆŲÆ ملف الؓهادة الخاص بك (ŲŖŁ†Ų³ŁŠŁ‚ X.509 ، ŁŠŁ…ŁƒŁ† أن ŁŠŁƒŁˆŁ† .pem أو .der):", + "selectP12": "Ų­ŲÆŲÆ ملف ŲŖŲ®Ų²ŁŠŁ† Ų§Ł„Ł…ŁŲ§ŲŖŁŠŲ­ PKCS # 12 (.p12 أو .pfx) (اختياري ، Ų„Ų°Ų§ ŲŖŁ… ŲŖŁˆŁŁŠŲ±Ł‡ ، يجب أن يحتوي على Ł…ŁŲŖŲ§Ų­Łƒ الخاص ŁˆŲ“Ł‡Ų§ŲÆŲŖŁƒ):", + "selectJKS": "Ų­ŲÆŲÆ ملف مخزن Ł…ŁŲ§ŲŖŁŠŲ­ جافا الخاص بك (.jks أو .keystore):", + "certType": "Ł†ŁˆŲ¹ الؓهادة", + "password": "أدخل ŁƒŁ„Ł…Ų© Ł…Ų±ŁˆŲ± مخزن Ų§Ł„Ł…ŁŲ§ŲŖŁŠŲ­ أو المفتاح الخاص (؄ن وجدت):", + "showSig": "؄ظهار Ų§Ł„ŲŖŁˆŁ‚ŁŠŲ¹", + "reason": "السبب", + "location": "Ų§Ł„Ł…ŁˆŁ‚Ų¹", + "name": "الاسم", + "showLogo": "Ų¹Ų±Ų¶ الؓعار", + "submit": "ŲŖŁˆŁ‚ŁŠŲ¹ PDF" + }, + "removeCertSign": { + "tags": "مصادقة,PEM,P12,Ų±Ų³Ł…ŁŠ,فك Ų§Ł„ŲŖŲ“ŁŁŠŲ±", + "title": "؄زالة ŲŖŁˆŁ‚ŁŠŲ¹ الؓهادة", + "header": "؄زالة الؓهادة Ų§Ł„Ų±Ł‚Ł…ŁŠŲ© من PDF", + "selectPDF": "Ų­ŲÆŲÆ ملف PDF:", + "submit": "؄زالة Ų§Ł„ŲŖŁˆŁ‚ŁŠŲ¹" + }, + "pageLayout": { + "tags": "ŲÆŁ…Ų¬,Ł…Ų±ŁƒŲØ,Ų¹Ų±Ų¶ واحد,ŲŖŁ†ŲøŁŠŁ…", + "title": "تخطيط Ł…ŲŖŲ¹ŲÆŲÆ الصفحات", + "header": "تخطيط Ł…ŲŖŲ¹ŲÆŲÆ الصفحات", + "pagesPerSheet": "الصفحات Ł„ŁƒŁ„ ŁˆŲ±Ł‚Ų©:", + "addBorder": "؄ضافة حدود", + "submit": "Ų„Ų±Ų³Ų§Ł„" + }, + "scalePages": { + "tags": "تغيير الحجم,ŲŖŲ¹ŲÆŁŠŁ„,الأبعاد,تكييف", + "title": "Ų¶ŲØŲ· Ł…Ł‚ŁŠŲ§Ų³ الصفحة", + "header": "Ų¶ŲØŲ· Ł…Ł‚ŁŠŲ§Ų³ الصفحة", + "pageSize": "حجم صفحة المستند.", + "keepPageSize": "الحجم Ų§Ł„Ų£ŲµŁ„ŁŠ", + "scaleFactor": "Ł…Ų³ŲŖŁˆŁ‰ Ų§Ł„ŲŖŁƒŲØŁŠŲ± (الاقتصاص) للصفحة.", + "submit": "Ų„Ų±Ų³Ų§Ł„" + }, + "add-page-numbers": { + "tags": "ŲŖŲ±Ł‚ŁŠŁ…,ŲŖŲ³Ł…ŁŠŲ©,ŲŖŁ†ŲøŁŠŁ…,فهرسة" + }, + "auto-rename": { + "tags": "كؓف ŲŖŁ„Ł‚Ų§Ų¦ŁŠ,Ł…ŲØŁ†ŁŠ على الرأس,ŲŖŁ†ŲøŁŠŁ…,Ų„Ų¹Ų§ŲÆŲ© ŲŖŲ³Ł…ŁŠŲ©", + "title": "Ų„Ų¹Ų§ŲÆŲ© ŲŖŲ³Ł…ŁŠŲ© ŲŖŁ„Ł‚Ų§Ų¦ŁŠŲ©", + "header": "Ų„Ų¹Ų§ŲÆŲ© ŲŖŲ³Ł…ŁŠŲ© PDF ŲŖŁ„Ł‚Ų§Ų¦ŁŠŁ‹Ų§", + "submit": "Ų„Ų¹Ų§ŲÆŲ© ŲŖŲ³Ł…ŁŠŲ© ŲŖŁ„Ł‚Ų§Ų¦ŁŠŲ©" + }, + "adjust-contrast": { + "tags": "تصحيح Ų§Ł„Ų£Ł„ŁˆŲ§Ł†,Ų¶ŲØŲ·,ŲŖŲ¹ŲÆŁŠŁ„,ŲŖŲ­Ų³ŁŠŁ†" + }, + "crop": { + "tags": "ŲŖŁ‚Ł„ŁŠŁ…,ŲŖŁ‚Ł„ŁŠŲµ,تحرير,ŲŖŲ“ŁƒŁŠŁ„", + "title": "اقتصاص", + "header": "اقتصاص PDF", + "submit": "Ų„Ų±Ų³Ų§Ł„" + }, + "autoSplitPDF": { + "tags": "Ł…ŲØŁ†ŁŠ على QR,فصل,ŲŖŁ‚Ų³ŁŠŁ… المسح Ų§Ł„Ų¶ŁˆŲ¦ŁŠ,ŲŖŁ†ŲøŁŠŁ…", + "title": "ŲŖŁ‚Ų³ŁŠŁ… PDF ŲŖŁ„Ł‚Ų§Ų¦ŁŠŁ‹Ų§", + "header": "ŲŖŁ‚Ų³ŁŠŁ… PDF ŲŖŁ„Ł‚Ų§Ų¦ŁŠŁ‹Ų§", + "description": "Ų§Ų·ŲØŲ¹ ŁˆŲ£ŲÆŲ®Ł„ ŁˆŲ§Ł…Ų³Ų­ Ų¶ŁˆŲ¦ŁŠŁ‹Ų§ وارفع، ŁˆŲÆŲ¹Ł†Ų§ نفصل Ł…Ų³ŲŖŁ†ŲÆŲ§ŲŖŁƒ ŲŖŁ„Ł‚Ų§Ų¦ŁŠŁ‹Ų§. لا Ų­Ų§Ų¬Ų© للفرز Ų§Ł„ŁŠŲÆŁˆŁŠ.", + "selectText": { + "1": "Ų§Ų·ŲØŲ¹ ŲØŲ¹Ų¶ Ų£ŁˆŲ±Ų§Ł‚ الفاصل من أدناه (Ų§Ł„Ų£ŲØŁŠŲ¶ ŁˆŲ§Ł„Ų£Ų³ŁˆŲÆ جيد).", + "2": "Ų§Ł…Ų³Ų­ Ų¬Ł…ŁŠŲ¹ Ł…Ų³ŲŖŁ†ŲÆŲ§ŲŖŁƒ دفعة واحدة عن Ų·Ų±ŁŠŁ‚ Ų„ŲÆŲ®Ų§Ł„ ŁˆŲ±Ł‚Ų© الفاصل ŲØŁŠŁ†Ł‡Ų§.", + "3": "ارفع ملف PDF Ų§Ł„Ł…Ł…Ų³ŁˆŲ­ Ų¶ŁˆŲ¦ŁŠŁ‹Ų§ Ų§Ł„ŁƒŲØŁŠŲ± Ų§Ł„ŁˆŲ§Ų­ŲÆ ودع Stirling PDF ŁŠŲŖŁˆŁ„Ł‰ Ų§Ł„ŲØŲ§Ł‚ŁŠ.", + "4": "ŁŠŲŖŁ… اكتؓاف صفحات الفاصل ŲŖŁ„Ł‚Ų§Ų¦ŁŠŁ‹Ų§ ŁˆŲ„Ų²Ų§Ł„ŲŖŁ‡Ų§ŲŒ Ł…Ł…Ų§ ŁŠŲ¶Ł…Ł† مستندًا Ł†Ł‡Ų§Ų¦ŁŠŁ‹Ų§ Ł†ŲøŁŠŁŁ‹Ų§." + }, + "formPrompt": "أرسل ملف PDF يحتوي على ŁŁˆŲ§ŲµŁ„ صفحات Stirling-PDF:", + "duplexMode": "وضع الطباعة على Ų§Ł„ŁˆŲ¬Ł‡ŁŠŁ† (المسح Ų§Ł„Ų¶ŁˆŲ¦ŁŠ Ł„Ł„ŁˆŲ¬Ł‡ Ų§Ł„Ų£Ł…Ų§Ł…ŁŠ ŁˆŲ§Ł„Ų®Ł„ŁŁŠ)", + "dividerDownload2": "ŲŖŁ†Ų²ŁŠŁ„ 'فاصل Ų§Ł„ŲŖŁ‚Ų³ŁŠŁ… Ų§Ł„ŲŖŁ„Ł‚Ų§Ų¦ŁŠ (Ł…Ų¹ Ų§Ł„ŲŖŲ¹Ł„ŁŠŁ…Ų§ŲŖ).pdf'", + "submit": "Ų„Ų±Ų³Ų§Ł„" + }, + "sanitizePdf": { + "tags": "ŲŖŁ†ŲøŁŠŁ,ŲŖŲ£Ł…ŁŠŁ†,آمن,؄زالة Ų§Ł„ŲŖŁ‡ŲÆŁŠŲÆŲ§ŲŖ" + }, + "URLToPDF": { + "tags": "التقاط Ų§Ł„ŁˆŁŠŲØ,حفظ الصفحة,ŲŖŲ­ŁˆŁŠŁ„ Ų§Ł„ŁˆŁŠŲØ ؄لى مستند,أرؓفة", + "title": "URL ؄لى PDF", + "header": "URL ؄لى PDF", + "submit": "ŲŖŲ­ŁˆŁŠŁ„", + "credit": "ŁŠŲ³ŲŖŲ®ŲÆŁ… WeasyPrint" + }, + "HTMLToPDF": { + "tags": "لغة Ų§Ł„ŲŖŲ±Ł…ŁŠŲ²,Ł…Ų­ŲŖŁˆŁ‰ Ų§Ł„ŁˆŁŠŲØ,ŲŖŲ­ŁˆŁŠŁ„,ŲŖŲ­ŁˆŁŠŁ„", + "title": "HTML ؄لى PDF", + "header": "HTML ؄لى PDF", + "help": "ŁŠŁ‚ŲØŁ„ ملفات HTML ŁˆŁ…Ł„ŁŲ§ŲŖ ZIP تحتوي على html/css/صور ŁˆŁ…Ų§ ؄لى Ų°Ł„Łƒ Ų§Ł„Ł…Ų·Ł„ŁˆŲØŲ©", + "submit": "ŲŖŲ­ŁˆŁŠŁ„", + "credit": "ŁŠŲ³ŲŖŲ®ŲÆŁ… WeasyPrint", + "zoom": "Ł…Ų³ŲŖŁˆŁ‰ Ų§Ł„ŲŖŁƒŲØŁŠŲ± لعرض Ų§Ł„Ł…ŁˆŁ‚Ų¹.", + "pageWidth": "Ų¹Ų±Ų¶ الصفحة ŲØŲ§Ł„Ų³Ł†ŲŖŁŠŁ…ŲŖŲ±. (فارغ Ł„Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ)", + "pageHeight": "ارتفاع الصفحة ŲØŲ§Ł„Ų³Ł†ŲŖŁŠŁ…ŲŖŲ±. (فارغ Ł„Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ)", + "marginTop": "الهامؓ Ų§Ł„Ų¹Ł„ŁˆŁŠ للصفحة ŲØŲ§Ł„Ł…Ł„ŁŠŁ…ŲŖŲ±. (فارغ Ł„Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ)", + "marginBottom": "الهامؓ Ų§Ł„Ų³ŁŁ„ŁŠ للصفحة ŲØŲ§Ł„Ł…Ł„ŁŠŁ…ŲŖŲ±. (فارغ Ł„Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ)", + "marginLeft": "الهامؓ Ų§Ł„Ų£ŁŠŲ³Ų± للصفحة ŲØŲ§Ł„Ł…Ł„ŁŠŁ…ŲŖŲ±. (فارغ Ł„Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ)", + "marginRight": "الهامؓ Ų§Ł„Ų£ŁŠŁ…Ł† للصفحة ŲØŲ§Ł„Ł…Ł„ŁŠŁ…ŲŖŲ±. (فارغ Ł„Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ)", + "printBackground": "Ų¹Ų±Ų¶ Ų®Ł„ŁŁŠŲ© Ų§Ł„Ł…ŁˆŲ§Ł‚Ų¹.", + "defaultHeader": "ŲŖŁ…ŁƒŁŠŁ† الرأس Ų§Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠ (الاسم ŁˆŲ±Ł‚Ł… الصفحة)", + "cssMediaType": "تغيير Ł†ŁˆŲ¹ وسائط CSS للصفحة.", + "none": "ŲØŲÆŁˆŁ†", + "print": "Ų·ŲØŲ§Ų¹Ų©", + "screen": "Ų“Ų§Ų“Ų©" + }, + "MarkdownToPDF": { + "tags": "لغة Ų§Ł„ŲŖŲ±Ł…ŁŠŲ²,Ł…Ų­ŲŖŁˆŁ‰ Ų§Ł„ŁˆŁŠŲØ,ŲŖŲ­ŁˆŁŠŁ„,ŲŖŲ­ŁˆŁŠŁ„", + "title": "Markdown ؄لى PDF", + "header": "Markdown ؄لى PDF", + "submit": "ŲŖŲ­ŁˆŁŠŁ„", + "help": "العمل Ł‚ŁŠŲÆ التقدم", + "credit": "ŁŠŲ³ŲŖŲ®ŲÆŁ… WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖ,ŲØŁŠŲ§Ł†Ų§ŲŖ,؄حصائيات,Ų„Ų­ŲµŲ§Ų”Ų§ŲŖ", + "title": "Ų§Ł„Ų­ŲµŁˆŁ„ على Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖ عن PDF", + "header": "Ų§Ł„Ų­ŲµŁˆŁ„ على Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖ عن PDF", + "submit": "Ų§Ł„Ų­ŲµŁˆŁ„ على Ų§Ł„Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖ", + "downloadJson": "ŲŖŲ­Ł…ŁŠŁ„ JSON" + }, + "extractPage": { + "tags": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬" + }, + "PdfToSinglePage": { + "tags": "صفحة واحدة" + }, + "showJS": { + "tags": "جافا سكريبت", + "title": "؄ظهار جافا سكريبت", + "header": "؄ظهار جافا سكريبت", + "downloadJS": "ŲŖŁ†Ų²ŁŠŁ„ جافا سكريبت", + "submit": "؄ظهار" + }, + "autoRedact": { + "tags": "Ų­Ų¬ŲØ,؄خفاؔ,تسويد,أسود,علامة,Ł…Ų®ŁŁŠ", + "title": "Ų­Ų¬ŲØ ŲŖŁ„Ł‚Ų§Ų¦ŁŠ", + "header": "Ų­Ų¬ŲØ ŲŖŁ„Ł‚Ų§Ų¦ŁŠ", + "colorLabel": "Ų§Ł„Ł„ŁˆŁ†", + "textsToRedactLabel": "النص المراد حجبه (Ł…ŁŲµŁˆŁ„ ŲØŲ£Ų³Ų·Ų±)", + "textsToRedactPlaceholder": "Ł…Ų«Ų§Ł„: \\nسري \\nسري Ł„Ł„ŲŗŲ§ŁŠŲ©", + "useRegexLabel": "Ų§Ų³ŲŖŲ®ŲÆŲ§Ł… Ų§Ł„ŲŖŲ¹ŲØŁŠŲ±Ų§ŲŖ Ų§Ł„Ų¹Ų§ŲÆŁŠŲ©", + "wholeWordSearchLabel": "ŲØŲ­Ų« Ų§Ł„ŁƒŁ„Ł…Ų© Ų§Ł„ŁƒŲ§Ł…Ł„Ų©", + "customPaddingLabel": "حؓو ؄ضافي Ł…Ų®ŲµŲµ", + "convertPDFToImageLabel": "ŲŖŲ­ŁˆŁŠŁ„ PDF ؄لى صورة PDF (ŁŠŲ³ŲŖŲ®ŲÆŁ… ل؄زالة النص خلف المربع)", + "submitButton": "Ų„Ų±Ų³Ų§Ł„" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ Ų§Ł„Ų¬ŲÆŁˆŁ„,Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬,ŲŖŲ­ŁˆŁŠŁ„" + }, + "autoSizeSplitPDF": { + "tags": "pdf,ŲŖŁ‚Ų³ŁŠŁ…,مستند,ŲŖŁ†ŲøŁŠŁ…" + }, + "overlay-pdfs": { + "tags": "تراكب", + "header": "تراكب ملفات PDF", + "baseFile": { + "label": "Ų§Ų®ŲŖŲ± ملف PDF Ų§Ł„Ų£Ų³Ų§Ų³ŁŠ" + }, + "overlayFiles": { + "label": "Ų§Ų®ŲŖŲ± ملفات PDF Ł„Ł„ŲŖŲ±Ų§ŁƒŲØ" + }, + "mode": { + "label": "Ų§Ų®ŲŖŲ± وضع Ų§Ł„ŲŖŲ±Ų§ŁƒŲØ", + "sequential": "تراكب متسلسل", + "interleaved": "تراكب متداخل", + "fixedRepeat": "تراكب تكرار Ų«Ų§ŲØŲŖ" + }, + "counts": { + "label": "Ų¹ŲÆŲÆ Ų§Ł„ŲŖŲ±Ų§ŁƒŲØŲ§ŲŖ (Ł„ŁˆŲ¶Ų¹ Ų§Ł„ŲŖŁƒŲ±Ų§Ų± الثابت)", + "placeholder": "أدخل الأعداد Ł…ŁŲµŁˆŁ„Ų© ŲØŁŁˆŲ§ŲµŁ„ (Ł…Ų«Ł„ 2,3,1)" + }, + "position": { + "label": "Ų§Ų®ŲŖŲ± Ł…ŁˆŲ¶Ų¹ Ų§Ł„ŲŖŲ±Ų§ŁƒŲØ", + "foreground": "المقدمة", + "background": "Ų§Ł„Ų®Ł„ŁŁŠŲ©" + }, + "submit": "Ų„Ų±Ų³Ų§Ł„" + }, + "split-by-sections": { + "tags": "ŲŖŁ‚Ų³ŁŠŁ… القسم, ŲŖŁ‚Ų³ŁŠŁ…, تخصيص", + "title": "ŲŖŁ‚Ų³ŁŠŁ… PDF Ų­Ų³ŲØ الأقسام", + "header": "ŲŖŁ‚Ų³ŁŠŁ… PDF ؄لى أقسام", + "horizontal": { + "label": "Ų§Ł„ŲŖŁ‚Ų³ŁŠŁ…Ų§ŲŖ Ų§Ł„Ų£ŁŁ‚ŁŠŲ©", + "placeholder": "أدخل Ų¹ŲÆŲÆ Ų§Ł„ŲŖŁ‚Ų³ŁŠŁ…Ų§ŲŖ Ų§Ł„Ų£ŁŁ‚ŁŠŲ©" + }, + "vertical": { + "label": "Ų§Ł„ŲŖŁ‚Ų³ŁŠŁ…Ų§ŲŖ Ų§Ł„Ų¹Ł…ŁˆŲÆŁŠŲ©", + "placeholder": "أدخل Ų¹ŲÆŲÆ Ų§Ł„ŲŖŁ‚Ų³ŁŠŁ…Ų§ŲŖ Ų§Ł„Ų¹Ł…ŁˆŲÆŁŠŲ©" + }, + "submit": "ŲŖŁ‚Ų³ŁŠŁ… PDF", + "merge": "ŲÆŁ…Ų¬ في ملف PDF واحد" + }, + "AddStampRequest": { + "tags": "Ų®ŲŖŁ…, ؄ضافة صورة, صورة وسط, علامة Ł…Ų§Ų¦ŁŠŲ©, PDF, ŲŖŲ¶Ł…ŁŠŁ†, تخصيص", + "header": "Ų®ŲŖŁ… PDF", + "title": "Ų®ŲŖŁ… PDF", + "stampType": "Ł†ŁˆŲ¹ الختم", + "stampText": "نص الختم", + "stampImage": "صورة الختم", + "alphabet": "Ų§Ł„Ų£ŲØŲ¬ŲÆŁŠŲ©", + "fontSize": "حجم الخط/Ų§Ł„ŲµŁˆŲ±Ų©", + "rotation": "ŲÆŁˆŲ±Ų§Ł†", + "opacity": "Ų§Ł„Ų“ŁŲ§ŁŁŠŲ©", + "position": "Ų§Ł„Ł…ŁˆŁ‚Ų¹", + "overrideX": "تجاوز Ų§Ł„Ų„Ų­ŲÆŲ§Ų«ŁŠ X", + "overrideY": "تجاوز Ų§Ł„Ų„Ų­ŲÆŲ§Ų«ŁŠ Y", + "customMargin": "هامؓ Ł…Ų®ŲµŲµ", + "customColor": "Ł„ŁˆŁ† نص Ł…Ų®ŲµŲµ", + "submit": "Ų„Ų±Ų³Ų§Ł„" + }, + "removeImagePdf": { + "tags": "؄زالة Ų§Ł„ŲµŁˆŲ±Ų©,Ų¹Ł…Ł„ŁŠŲ§ŲŖ الصفحة,Ų§Ł„Ų®Ł„ŁŁŠŲ©,جانب الخادم" + }, + "splitPdfByChapters": { + "tags": "تجزئة، ŁŲµŁˆŁ„ŲŒ علامات تبويب، ŲŖŁ†ŲøŁŠŁ…" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Ų„Ų³ŲŖŲØŲÆŲ§Ł„-عكس Ų§Ł„Ł„ŁˆŁ†", + "header": "Ų§Ų³ŲŖŲØŲÆŲ§Ł„-عكس Ł„ŁˆŁ† PDF", + "selectText": { + "1": "خيارات Ų§Ų³ŲŖŲØŲÆŲ§Ł„ أو عكس Ų§Ł„Ų£Ł„ŁˆŲ§Ł†", + "2": "افتراضي(Ų£Ł„ŁˆŲ§Ł† Ų§Ł„ŲŖŲØŲ§ŁŠŁ† Ų§Ł„Ų¹Ų§Ł„ŁŠ Ų§Ł„Ų§ŁŲŖŲ±Ų§Ų¶ŁŠŲ©)", + "3": "خصيصة (Ų£Ł„ŁˆŲ§Ł† ؓخصية)", + "4": "عكس ŁƒŲ§Ł…Ł„(عكس Ų¬Ł…ŁŠŲ¹ Ų§Ł„Ų£Ł„ŁˆŲ§Ł†)", + "5": "خيارات Ų£Ł„ŁˆŲ§Ł† Ų§Ł„ŲŖŲØŲ§ŁŠŁ† Ų§Ł„Ų¹Ų§Ł„ŁŠ", + "6": "نص أبيض على Ų®Ł„ŁŁŠŲ© سوداؔ", + "7": "نص أسود على Ų®Ł„ŁŁŠŲ© بيضاؔ", + "8": "نص صفرة على Ų®Ł„ŁŁŠŲ© سوداؔ", + "9": "نص Ų£Ų®Ų¶Ų± على Ų®Ł„ŁŁŠŲ© سوداؔ", + "10": "Ų§Ų®ŲŖŲ± Ł„ŁˆŁ† النص", + "11": "Ų§Ų®ŲŖŲ± Ł„ŁˆŁ† Ų§Ł„Ų®Ł„ŁŁŠŲ©" + }, + "submit": "Ų§Ų³ŲŖŲØŲÆŲ§Ł„" + }, + "replaceColorPdf": { + "tags": "Ų§Ų³ŲŖŲØŲÆŲ§Ł„ Ų§Ł„Ł„ŁˆŁ†ŲŒ Ų¹Ł…Ł„ŁŠŲ§ŲŖ Ų§Ł„ŲµŁŲ­Ų©ŲŒ Ų§Ł„Ų®Ł„ŁŁŠŲ©ŲŒ جانب الخادم" + }, + "login": { + "title": "ŲŖŲ³Ų¬ŁŠŁ„ Ų§Ł„ŲÆŲ®ŁˆŁ„", + "header": "ŲŖŲ³Ų¬ŁŠŁ„ Ų§Ł„ŲÆŲ®ŁˆŁ„", + "signin": "ŲŖŲ³Ų¬ŁŠŁ„ Ų§Ł„ŲÆŲ®ŁˆŁ„", + "rememberme": "ŲŖŲ°ŁƒŲ±Ł†ŁŠ", + "invalid": "اسم المستخدم أو ŁƒŁ„Ł…Ų© Ų§Ł„Ł…Ų±ŁˆŲ± غير صالحة.", + "locked": "ŲŖŁ… قفل حسابك.", + "signinTitle": "الرجاؔ ŲŖŲ³Ų¬ŁŠŁ„ Ų§Ł„ŲÆŲ®ŁˆŁ„", + "ssoSignIn": "ŲŖŲ³Ų¬ŁŠŁ„ Ų§Ł„ŲÆŲ®ŁˆŁ„ Ų¹ŲØŲ± ŲŖŲ³Ų¬ŁŠŁ„ Ų§Ł„ŲÆŲ®ŁˆŁ„ Ų§Ł„Ų£Ų­Ų§ŲÆŁŠ", + "oAuth2AutoCreateDisabled": "ŲŖŁ… ŲŖŲ¹Ų·ŁŠŁ„ ال؄نؓاؔ Ų§Ł„ŲŖŁ„Ł‚Ų§Ų¦ŁŠ لمستخدم OAuth2", + "oAuth2AdminBlockedUser": "ŲŖŁ… Ų­ŲøŲ± ŲŖŲ³Ų¬ŁŠŁ„ أو ŲŖŲ³Ų¬ŁŠŁ„ ŲÆŲ®ŁˆŁ„ Ų§Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŁŠŁ† غير Ų§Ł„Ł…Ų³Ų¬Ł„ŁŠŁ† Ų­Ų§Ł„ŁŠŁ‹Ų§. ŁŠŲ±Ų¬Ł‰ الاتصال ŲØŲ§Ł„Ł…Ų³Ų¤ŁˆŁ„.", + "oauth2RequestNotFound": "لم ŁŠŲŖŁ… Ų§Ł„Ų¹Ų«ŁˆŲ± على طلب Ų§Ł„ŲŖŁŁˆŁŠŲ¶", + "oauth2InvalidUserInfoResponse": "Ų§Ų³ŲŖŲ¬Ų§ŲØŲ© Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖ المستخدم غير صالحة", + "oauth2invalidRequest": "طلب غير صالح", + "oauth2AccessDenied": "ŲŖŁ… رفض Ų§Ł„ŁˆŲµŁˆŁ„", + "oauth2InvalidTokenResponse": "Ų§Ų³ŲŖŲ¬Ų§ŲØŲ© الرمز Ų§Ł„Ł…Ł…ŁŠŲ² غير صالحة", + "oauth2InvalidIdToken": "رمز Ų§Ł„Ł‡ŁˆŁŠŲ© غير صالح", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "ŲŖŁ… ŲŖŲ¹Ų·ŁŠŁ„ Ų§Ł„Ł…Ų³ŲŖŲ®ŲÆŁ…ŲŒ ŲŖŁ… Ų­ŲøŲ± ŲŖŲ³Ų¬ŁŠŁ„ Ų§Ł„ŲÆŲ®ŁˆŁ„ Ų­Ų§Ł„ŁŠŁ‹Ų§ ŲØŲ§Ų³ŲŖŲ®ŲÆŲ§Ł… اسم المستخدم هذا. ŁŠŲ±Ų¬Ł‰ الاتصال ŲØŲ§Ł„Ł…Ų³Ų¤ŁˆŁ„.", + "alreadyLoggedIn": "لقد تسجل ŲÆŲ®ŁˆŁ„Ł‹Ų§ ؄لى", + "alreadyLoggedIn2": "أجهزة أخرى. ŁŠŲ±Ų¬Ł‰ ŲŖŲ³Ų¬ŁŠŁ„ Ų§Ł„Ų®Ų±ŁˆŲ¬ من الأجهزة ŁˆŲ­Ų§ŁˆŁ„ Ł…Ų±Ų© أخرى.", + "toManySessions": "Ł„ŲÆŁŠŁƒ Ų¹ŲÆŲ© جلسات نؓطة", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF ؄لى صفحة واحدة", + "header": "PDF ؄لى صفحة واحدة", + "submit": "ŲŖŲ­ŁˆŁŠŁ„ ؄لى صفحة واحدة" + }, + "pageExtracter": { + "title": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ الصفحات", + "header": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ الصفحات", + "submit": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬", + "placeholder": "(Ł…Ų«Ų§Ł„: 1,2,8 أو 4,7,12-16 أو 2n-1)" + }, + "sanitizePDF": { + "title": "ŲŖŁ†ŲøŁŠŁ PDF", + "header": "ŲŖŁ†ŲøŁŠŁ ملف PDF", + "selectText": { + "1": "؄زالة Ų„Ų¬Ų±Ų§Ų”Ų§ŲŖ جافا سكريبت", + "2": "؄زالة الملفات المضمنة", + "3": "Remove XMP metadata", + "4": "؄زالة Ų§Ł„Ų±ŁˆŲ§ŲØŲ·", + "5": "؄زالة Ų§Ł„Ų®Ų·ŁˆŲ·", + "6": "Remove Document Info Metadata" + }, + "submit": "ŲŖŁ†ŲøŁŠŁ PDF" + }, + "adjustContrast": { + "title": "Ų¶ŲØŲ· Ų§Ł„ŲŖŲØŲ§ŁŠŁ†", + "header": "Ų¶ŲØŲ· Ų§Ł„ŲŖŲØŲ§ŁŠŁ†", + "contrast": "Ų§Ł„ŲŖŲØŲ§ŁŠŁ†:", + "brightness": "Ų§Ł„Ų³Ų·ŁˆŲ¹:", + "saturation": "التؓبع:", + "download": "ŲŖŁ†Ų²ŁŠŁ„" + }, + "compress": { + "title": "Ų¶ŲŗŲ·", + "header": "Ų¶ŲŗŲ· ملف PDF", + "credit": "ŲŖŲ³ŲŖŲ®ŲÆŁ… هذه الخدمة qpdf لضغط / ŲŖŲ­Ų³ŁŠŁ† PDF.", + "grayscale": { + "label": "ŲŖŲ·ŲØŁŠŁ‚ التدرج Ų§Ł„Ų±Ł…Ų§ŲÆŁŠ للضغط" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Ł…Ų³ŲŖŁˆŁ‰ Ų§Ł„ŲŖŲ­Ų³ŁŠŁ†:", + "4": "Ų§Ł„ŁˆŲ¶Ų¹ Ų§Ł„ŲŖŁ„Ł‚Ų§Ų¦ŁŠ - يضبط Ų§Ł„Ų¬ŁˆŲÆŲ© ŲŖŁ„Ł‚Ų§Ų¦ŁŠŁ‹Ų§ Ł„Ł„Ų­ŲµŁˆŁ„ على ملف PDF بالحجم المحدد", + "5": "حجم PDF Ų§Ł„Ł…ŲŖŁˆŁ‚Ų¹ (على Ų³ŲØŁŠŁ„ المثال 25 Ł…ŁŠŲ¬Ų§ بايت، 10.8 Ł…ŁŠŲ¬Ų§ بايت، 25 ŁƒŁŠŁ„Łˆ بايت)" + }, + "submit": "Ų¶ŲŗŲ·" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "هذه Ų§Ł„Ł…ŁŠŲ²Ų© Ł…ŲŖŁˆŁŲ±Ų© في صفحة Ų§Ł„Ų£ŲÆŁˆŲ§ŲŖ المتعددة Ł„ŲÆŁŠŁ†Ų§. اطلع Ų¹Ł„ŁŠŁ‡Ų§ Ł„Ł„Ų­ŲµŁˆŁ„ على ŁˆŲ§Ų¬Ł‡Ų© Ł…Ų³ŲŖŲ®ŲÆŁ… محسّنة Ł„ŁƒŁ„ صفحة ŁˆŁ…ŁŠŲ²Ų§ŲŖ ؄ضافية!" + }, + "pageRemover": { + "title": "Ł…Ų²ŁŠŁ„ الصفحة", + "header": "Ł…Ų²ŁŠŁ„ صفحة PDF", + "pagesToDelete": "الصفحات المراد حذفها (أدخل قائمة بأرقام الصفحات Ł…ŁŲµŁˆŁ„Ų© ŲØŁŁˆŲ§ŲµŁ„):", + "submit": "حذف الصفحات", + "placeholder": "(Ł…Ų«Ų§Ł„: 1,2,6 أو 1-10,15-30)" + }, + "imageToPDF": { + "title": "صورة ؄لى PDF", + "header": "صورة ؄لى PDF", + "submit": "ŲŖŲ­ŁˆŁŠŁ„", + "selectLabel": "خيارات ملاؔمة Ų§Ł„ŲµŁˆŲ±Ų©", + "fillPage": "ملؔ الصفحة", + "fitDocumentToImage": "ملاؔمة الصفحة Ł„Ł„ŲµŁˆŲ±Ų©", + "maintainAspectRatio": "الحفاظ على نسب الأبعاد", + "selectText": { + "2": "تدوير PDF ŲŖŁ„Ł‚Ų§Ų¦ŁŠŁ‹Ų§", + "3": "المنطق المتعدد للملفات (مفعل فقط Ų„Ų°Ų§ ŁƒŁ†ŲŖ تعمل Ł…Ų¹ صور Ł…ŲŖŲ¹ŲÆŲÆŲ©)", + "4": "ŲÆŁ…Ų¬ في ملف PDF واحد", + "5": "ŲŖŲ­ŁˆŁŠŁ„ ؄لى ملفات PDF منفصلة" + } + }, + "PDFToCSV": { + "title": "PDF ؄لى CSV", + "header": "PDF ؄لى CSV", + "prompt": "Ų§Ų®ŲŖŲ± الصفحة لاستخراج Ų§Ł„Ų¬ŲÆŁˆŁ„", + "submit": "ŲŖŲ­ŁˆŁŠŁ„" + }, + "split-by-size-or-count": { + "title": "ŲŖŁ‚Ų³ŁŠŁ… PDF Ų­Ų³ŲØ الحجم أو العدد", + "header": "ŲŖŁ‚Ų³ŁŠŁ… PDF Ų­Ų³ŲØ الحجم أو العدد", + "type": { + "label": "Ų§Ų®ŲŖŲ± Ł†ŁˆŲ¹ Ų§Ł„ŲŖŁ‚Ų³ŁŠŁ…", + "size": "Ų­Ų³ŲØ الحجم", + "pageCount": "Ų­Ų³ŲØ Ų¹ŲÆŲÆ الصفحات", + "docCount": "Ų­Ų³ŲØ Ų¹ŲÆŲÆ المستندات" + }, + "value": { + "label": "أدخل Ų§Ł„Ł‚ŁŠŁ…Ų©", + "placeholder": "أدخل الحجم (Ł…Ų«Ł„ 2MB أو 3KB) أو العدد (Ł…Ų«Ł„ 5)" + }, + "submit": "Ų„Ų±Ų³Ų§Ł„" + }, + "printFile": { + "title": "Ų·ŲØŲ§Ų¹Ų© ملف", + "header": "Ų·ŲØŲ§Ų¹Ų© ملف بالطابعة", + "selectText": { + "1": "تحديد ملف للطباعة", + "2": "ادخل اسم الطابعة" + }, + "submit": "Ų·ŲØŲ§Ų¹Ų©" + }, + "licenses": { + "nav": "Ų§Ł„ŲŖŲ±Ų§Ų®ŁŠŲµ", + "title": "تراخيص الطرف الثالث", + "header": "تراخيص الطرف الثالث", + "module": "Ų§Ł„ŁˆŲ­ŲÆŲ©", + "version": "ال؄صدار", + "license": "Ų§Ł„ŲŖŲ±Ų®ŁŠŲµ" + }, + "survey": { + "nav": "استطلاع", + "title": "استطلاع Stirling-PDF", + "description": "Stirling-PDF لا يحتوي على ŲŖŲŖŲØŲ¹ لذا Ł†Ų±ŁŠŲÆ أن نسمع من Ł…Ų³ŲŖŲ®ŲÆŁ…ŁŠŁ†Ų§ Ł„ŲŖŲ­Ų³ŁŠŁ† Stirling-PDF!", + "changes": "تحديث Stirling-PDF منذ Ų¢Ų®Ų± Ų§Ų³ŲŖŲØŁŠŲ§Ł†! Ł„Ł„Ų­ŲµŁˆŁ„ على Ų§Ł„Ł…Ų²ŁŠŲÆ من Ų§Ł„Ł…Ų¹Ł„ŁˆŁ…Ų§ŲŖ الرجاؔ زيارة مقالتنا في Ų§Ł„Ł…ŲÆŁˆŁ†Ų© هنا:", + "changes2": "Ł…Ų¹ هذه Ų§Ł„ŲŖŲ­ŲÆŁŠŲ«Ų§ŲŖŲŒ Ł†Ų³ŲŖŁŁŠŲÆ من الدعم Ų§Ł„Ų¹Ł…Ł„ŁŠ ŁˆŲ§Ł„Ł…Ł†Ų­Ų© Ų§Ł„Ł…Ų§Ł„ŁŠŲ©", + "please": "ŁŠŲ±Ų¬Ł‰ النظر في Ų§Ł„Ł…Ų“Ų§Ų±ŁƒŲ© في استطلاعنا!", + "disabled": "(Ų³ŁŠŲŖŁ… ŲŖŲ¹Ų·ŁŠŁ„ النافذة المنبثقة للاستطلاع في Ų§Ł„ŲŖŲ­ŲÆŁŠŲ«Ų§ŲŖ Ų§Ł„ŲŖŲ§Ł„ŁŠŲ© ŁˆŁ„ŁƒŁ†Ł‡Ų§ Ų³ŲŖŁƒŁˆŁ† Ł…ŲŖŲ§Ų­Ų© في أسفل الصفحة)", + "button": "Ų§Ł„Ł…Ų“Ų§Ų±ŁƒŲ© في الاستطلاع", + "dontShowAgain": "Ų¹ŲÆŁ… ال؄ظهار Ł…Ų±Ų© أخرى", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "؄زالة Ų§Ł„ŲµŁˆŲ±Ų©", + "header": "؄زالة Ų§Ł„ŲµŁˆŲ±Ų©", + "removeImage": "؄زالة Ų§Ł„ŲµŁˆŲ±Ų©", + "submit": "؄زالة Ų§Ł„ŲµŁˆŲ±Ų©" + }, + "splitByChapters": { + "title": "ŲŖŲ¬Ų²Ų¦Ų© المستند Ų­Ų³ŲØ Ų§Ł„ŁŲµŁˆŁ„", + "header": "ŲŖŲ¬Ų²Ų¦Ų© المستند Ų­Ų³ŲØ Ų§Ł„ŁŲµŁˆŁ„", + "bookmarkLevel": "Ł…Ų³ŲŖŁˆŁ‰ العلامات Ų§Ł„ŲŖŲ°ŁƒŲ§Ų±ŁŠŲ©", + "includeMetadata": "Ų“Ų§Ł…Ł„ Ų§Ł„ŲØŁŠŲ§Ł†Ų§ŲŖ المرفقة", + "allowDuplicates": "السماح ŲØŲ§Ł„ŲŖŁƒŲ±Ų§Ų±", + "desc": { + "1": "هذه الأداة ŲŖŁ‚ŁˆŁ… ŲØŲŖŁ‚Ų³ŁŠŁ… ملف PDF ؄لى Ų¹ŲÆŲ© ملفات PDF استناداً ؄لى ŲØŁ†ŁŠŲ© ŁŲµŁˆŁ„Ł‡", + "2": "Ł…Ų³ŲŖŁˆŁ‰ ال؄ؓارة Ų§Ł„Ł…Ų±Ų¬Ų¹ŁŠŲ©: Ų§Ų®ŲŖŲ± Ł…Ų³ŲŖŁˆŁ‰ ال؄ؓارات Ų§Ł„Ł…Ų±Ų¬Ų¹ŁŠŲ© Ų§Ł„ŲŖŁŠ تريد استخدامها Ł„Ł„ŲŖŁ‚Ų³ŁŠŁ… (0 Ł„Ł„Ł…Ų³ŲŖŁˆŁ‰ Ų§Ł„Ų£Ų¹Ł„Ł‰ŲŒ 1 Ł„Ł„Ł…Ų³ŲŖŁˆŁ‰ Ų§Ł„Ų«Ų§Ł†ŁŠŲŒ ŁˆŁ…Ų§ ؄لى Ų°Ł„Łƒ)", + "3": "ŲŖŁ…Ų«ŁŠŁ„ Ų§Ł„ŲØŁŠŲ§Ł†Ų§ŲŖ Ų§Ł„Ų£ŲµŁ„ŁŠŲ©: Ų„Ų°Ų§ ŲŖŁ… Ų§Ų®ŲŖŁŠŲ§Ų±Ł‡Ų§ŲŒ سترمز Ų§Ł„ŲØŁŠŲ§Ł†Ų§ŲŖ Ų§Ł„Ł…Ų±Ų¬Ų¹ŁŠŲ© Ų§Ł„Ų£ŲµŁ„ŁŠŲ© ؄لى ŁƒŁ„ PDF Ł…Ų¬Ų²Ų£.", + "4": "سماح ŲØŲ§Ł„ŲŖŁƒŲ±Ų§Ų±: Ų„Ų°Ų§ ŲŖŁ… Ų§Ų®ŲŖŁŠŲ§Ų±Ł‡ŲŒ ŁŠŲ³Ł…Ų­ بوجود Ł…Ų¹Ų§ŁŠŁ†Ų§ŲŖ Ł…ŲŖŲ¹ŲÆŲÆŲ© في الصفحة نفسها لخلق ملفات PDF منفصلة." + }, + "submit": "ŲŖŁ‚Ų·ŁŠŲ¹ ملف PDF" + }, + "fileChooser": { + "click": "انقر هنا", + "or": "أو", + "dragAndDrop": "قم ŲØŲ³Ų­ŲØ الملفات ŁˆŲ„ŁŁ„Ų§ŲŖŁ‡Ų§", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "قم ŲØŲ³Ų­ŲØ المفات ŁˆŲ„ŁŁ„Ų§ŲŖŁ‡Ų§ هنا", + "extractPDF": "جاري الاستخراج..." + }, + "releases": { + "footer": "Releases", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Current Release" + }, + "note": "Release notes are only available in English" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/az-AZ/translation.json b/frontend/public/locales/az-AZ/translation.json new file mode 100644 index 000000000..28daecd5c --- /dev/null +++ b/frontend/public/locales/az-AZ/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Şrift Ɩlçüsü", + "fontName": "Şrift Adı", + "title": "Səhifə Nƶmrələri əlavə edin", + "header": "Səhifə Nƶmrələri əlavə edin", + "selectText": { + "1": "PDF faylını seƧin:", + "2": "Margin Ɩlçüsü", + "3": "Mƶvqe", + "4": "Başlanğıc nƶmrəsi", + "5": "Səhifələrə nƶmrə əlavə edin", + "6": "Fərdi Mətn" + }, + "customTextDesc": "Fərdi Mətn", + "numberPagesDesc": "Hansı səhifələrin nƶmrələnəcəyini seƧin, default 'all', və ya 1-5, 2,5,9 kimi yazılış qəbul olunur", + "customNumberDesc": "Defolt olaraq {n}, və ya 'Page {n} of {total}', 'Text-{n}', '{filename}-{n}", + "submit": "Səhifə Nƶmrələri əlavə edin" + }, + "pdfPrompt": "PDF(lər)i SeƧ", + "multiPdfPrompt": "PDFləri SeƧ (2+)", + "multiPdfDropPrompt": "Ehtiyacınız olan bütün PDFləri seƧin (və ya sürükləyib buraxın)", + "imgPrompt": "Şəkil(lər)i SeƧ", + "genericSubmit": "Təsdiq Et", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Xəbərdarlıq: Bu proses fayl ƶlçüsündən asılı olaraq bir dəqiqəyə qədər vaxt ala bilər", + "pageOrderPrompt": "Xüsusi Səhifə Ardıcıllığı (Vergüllə ayrılmış səhifə nƶmrələri listini və ya 2n+1 tərzində Funksiyalar daxil edin) :", + "pageSelectionPrompt": "Xüsusi Səhifə SeƧimi (1, 5, 6 tərzində vergüllə ayrılmış səhifə nƶmrələri listini və ya 2n+1 tərzində Funksiyalar daxil edin) :", + "goToPage": "Get", + "true": "Doğru", + "false": "Yanlış", + "unknown": "Bilinməyən", + "save": "Saxla", + "saveToBrowser": "Brauzerdə Saxla", + "close": "Bağla", + "filesSelected": "seƧilmiş fayllar", + "noFavourites": "Sevimlilər əlavə edilmədi", + "downloadComplete": "Yükləmə Tamamlandı", + "bored": "Gƶzləməkdən Sıxıldınız?", + "alphabet": "ʏlifba", + "downloadPdf": "PDF Yüklə", + "text": "Yazı", + "font": "Şrift", + "selectFillter": "-- SeƧ --", + "pageNum": "Səhifə nƶmrəsi", + "sizes": { + "small": "KiƧik", + "medium": "Orta", + "large": "Bƶyük", + "x-large": "Ekstra Bƶyük" + }, + "error": { + "pdfPassword": "PDF sənədi şifrlənmişdir və şifr təmin edilməmişdir və ya yanlışdır.", + "_value": "Xəta", + "sorry": "Problem üçün üzr istəyirik!", + "needHelp": "Kƶmək lazımdır / Problem tapdınız?", + "contactTip": "ʏgər hələ də problem yaşayırsınızsa, kƶmək üçün bizə müraciət etməkdən Ƨəkinməyin. GitHub səhifəmizdə bilet təqdim edə və ya Discord vasitəsilə bizimlə əlaqə saxlaya bilərsiniz:", + "404": { + "head": "404 - Səhifə tapılmadı | Ups, kodu səhv saldıq!", + "1": "Axtardığınız səhifəni tapa bilmirik.", + "2": "Xəta baş verdi" + }, + "github": "GitHub-da bilet təqdim edin", + "showStack": "Yığın İzini gƶstərin", + "copyStack": "Stack Trace-i kopyalayın", + "githubSubmit": "GitHub - Bilet təqdim edin", + "discordSubmit": "Discord - Dəstək postunu gƶndərin" + }, + "delete": "Sil", + "username": "İstifadəƧi Adı", + "password": "Şifr", + "welcome": "Xoş gəldiniz", + "property": "Xüsusiyyət", + "black": "Qara", + "white": "Ağ", + "red": "Qırmızı", + "green": "Yaşıl", + "blue": "Mavi", + "custom": "Xüsusi...", + "WorkInProgess": "İş davam edir, İşləməyə bilər və ya xətalarla üzləşə bilərsiniz, Zəhmət olmasa problemləri bildirin!", + "poweredBy": "Təchiz edilmişdir", + "yes": "Bəli", + "no": "Xeyr", + "changedCredsMessage": "Etibarnamələr dəyişdirildi!", + "notAuthenticatedMessage": "İstifadəƧinin kimliyi təsdiqlənməyib.", + "userNotFoundMessage": "İstifadəƧi tapılmadı.", + "incorrectPasswordMessage": "Cari şifr yanlışdır.", + "usernameExistsMessage": "İstifadəƧi adı mƶvcuddur.", + "invalidUsernameMessage": "Yanlış istifadəƧi adı, istifadəƧi adı sadəcə hərflərdən, rəqəmlərdən və @._+- xüsusi simvollarından ibarət ola bilər və ya düzgün email ünvanı olmalıdır.", + "invalidPasswordMessage": "Şifr boş olmamalıdır, başlanğıc və sonunda boşluqdan istifadə edilməməlidir.", + "confirmPasswordErrorMessage": "Yeni Şifr və Yeni Şifri Doğrula uyğun olmalıdır.", + "deleteCurrentUserMessage": "Hazırda daxil olmuş istifadəƧini silmək mümkün deyil.", + "deleteUsernameExistsMessage": "İstifadəƧi adı mƶvcud deyildir və silinə bilməz.", + "downgradeCurrentUserMessage": "Cari istifadəƧinin rolunu aşağı salmaq mümkün deyil", + "disabledCurrentUserMessage": "Cari istifadəƧi deaktivləşdirilə bilməz", + "downgradeCurrentUserLongMessage": "Cari istifadəƧinin rolunu aşağı salmaq mümkün deyil. Deməli, cari istifadəƧi gƶstərilməyəcək.", + "userAlreadyExistsOAuthMessage": "İstifadəƧi OAuth2 istifadəƧisi olaraq mƶvcuddur.", + "userAlreadyExistsWebMessage": "İstifadəƧi veb istifadəƧisi olaraq mƶvcuddur.", + "oops": "Oops!", + "help": "Yardım", + "goHomepage": "Ana səhifəyə get", + "joinDiscord": "Discord serverimizə qatıl", + "seeDockerHub": "Docker Hub-a bax", + "visitGithub": "Github Repository-ə Baş Ƈək", + "donate": "İanə Ver", + "color": "Rəng", + "sponsor": "Sponsor", + "info": "Məlumat", + "pro": "Pro", + "page": "Səhifə", + "pages": "Səhifələr", + "loading": "Yüklənir...", + "addToDoc": "Sənədə ʏlavə Et", + "reset": "Sıfırla", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Məxfilik Siyasəti", + "terms": "Qaydalar və Şərtlər", + "accessibility": "ʏlƧatanlıq", + "cookie": "Kuki Siyasəti", + "impressum": "Təəssürat", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Pipeline Menyusu (Beta)", + "uploadButton": "Fərdi Yüklə", + "configureButton": "Konfiqurasiya Et", + "defaultOption": "Fərdi", + "submitButton": "Təsdiqlə", + "help": "Pipeline Kƶməyi", + "scanHelp": "Qovluq Skanlama Kƶməyi", + "deletePrompt": "Pipeline-ı silmək istədiyinizə əminsiniz?", + "tags": "avtomatlaşdır,ardıcıllıq,skriptlənmiş,kütləvi-proses", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Pipeline Konfiqurasiyası", + "pipelineNameLabel": "Pipeline Adı", + "saveSettings": "ʏməliyyat Parametrlərini Saxla", + "pipelineNamePrompt": "Pipeline adını bura daxil et", + "selectOperation": "ʏməliyyat seƧ", + "addOperationButton": "ʏməliyyat əlavə et", + "pipelineHeader": "Pipeline:", + "saveButton": "Endir", + "validateButton": "Doğrula" + }, + "enterpriseEdition": { + "button": "Pro versiyaya keƧ", + "warning": "Bu xüsusiyyət yalnız pro istifadəƧilər üçün əlƧatandır.", + "yamlAdvert": "Stirling PDF Pro YAML konfiqurasiya fayllarını və digər SSO xüsusiyyətlərini dəstəkləyir.", + "ssoAdvert": "Daha Ƨox istifadəƧi-idarəetmə xüsusiyyətləri axtarırsınız? Stirling PDF Pro-nu nəzərdən keƧirin" + }, + "analytics": { + "title": "Stirling PDF-i daha yaxşı etmək istəyirsinizmi?", + "paragraph1": "Stirling PDF bizə məhsulu inkişaf etdirməyə kƶmək etmək üçün analitikaya üstünlük verib. Biz heƧ bir şəxsi məlumatı və ya fayl məzmununu izləmirik.", + "paragraph2": "Zəhmət olmasa, Stringling-PDF-ə inkişaf etməkdə və istifadəƧilərimizi daha yaxşı anlamaqda yardım etmək üçün analitikanı aktivləşdirməyi nəzərə alın.", + "enable": "Analitikanı aktivləşdir", + "disable": "Analitikanı deaktivləşdir", + "settings": "Analitikanın parametrlərini config/settings.yml faylından dəyişə bilərsiniz." + }, + "navbar": { + "favorite": "Sevimlilər", + "recent": "New and recently updated", + "darkmode": "Qaranlıq Tema", + "language": "Dillər", + "settings": "Parametrlər", + "allTools": "Alətlər", + "multiTool": "Multi-Alət", + "search": "Axtar", + "sections": { + "organize": "Təşkil et", + "convertTo": "PDF-ə Ƈevir", + "convertFrom": "PDF-dən Ƈevir", + "security": "İmza & Təhlükəsizlik", + "advance": "Qabaqcıl", + "edit": "Bax & Redaktə et", + "popular": "Populyar" + } + }, + "settings": { + "title": "Parametrlər", + "update": "Yeniləmə mƶvcuddur", + "updateAvailable": "{0} cari quraşdırılmış versiyadır. Yeni ({1}) versiyası mƶvcuddur.", + "appVersion": "Proqram Versiyası:", + "downloadOption": { + "title": "Yükləmə versiyasını seƧin (Tək fayllı zip olmayan yükləmələr üçün):", + "1": "Eyni pəncərədə aƧın", + "2": "Yeni pəncərədə aƧın", + "3": "Faylı endirin" + }, + "zipThreshold": "Yüklənmiş faylların sayı artıq olduqda zip faylları", + "signOut": "Ƈıxın", + "accountSettings": "Hesab Parametrləri", + "bored": { + "help": "Easter egg oyununu aktivləşdirir" + }, + "cacheInputs": { + "name": "Formada daxil edilən bilgiləri yadda saxlayın", + "help": "Gələcək əməliyyatlar üçün əvvəllər istifadə edilmiş daxil edilmiş bilgiləri saxlamağa imkan verin" + } + }, + "changeCreds": { + "title": "Məlumatları dəyişdirin", + "header": "Hesab Məlumatlarınızı Yeniləyin", + "changePassword": "Siz standart giriş məlumatlarından istifadə edirsiniz. Zəhmət olmasa, yeni şifr daxil edin", + "newUsername": "Yeni İstifadəƧi Adı", + "oldPassword": "Cari Şifr", + "newPassword": "Yeni Şifr", + "confirmNewPassword": "Yeni Şifri Təsdiqləyin", + "submit": "Dəyişiklikləri Təsdiqlə" + }, + "account": { + "title": "Hesab Parametrləri", + "accountSettings": "Hesab Parametrləri", + "adminSettings": "Admin Paramterləri - İstifadəƧilər ʏlavə Et və Onlara Bax", + "userControlSettings": "İstifadəƧi İdarəetmə Parametrləri", + "changeUsername": "İstifadəƧi Adını Dəyiş", + "newUsername": "Yeni İstifadəƧi Adı", + "password": "Təsdiqləmə Şifri", + "oldPassword": "KeƧmiş Şifr", + "newPassword": "Yeni Şifr", + "changePassword": "Şifri Dəyiş", + "confirmNewPassword": "Yeni Şifri Təsdiqlə", + "signOut": "Ƈıxış", + "yourApiKey": "Sizin API AƧarınız", + "syncTitle": "Brauzer parametrlərini hesabla sinxronlaşdırın", + "settingsCompare": "Parametrlərin müqayisəsi:", + "property": "Xüsusiyyət", + "webBrowserSettings": "Veb Brauzer Parametrləri", + "syncToBrowser": "Hesabı Sinxronlaşdır -> Brauzer", + "syncToAccount": "Hesabı Sinxronlaşdır <- Brauzer" + }, + "adminUserSettings": { + "title": "İstifadəƧi İdarəetmə Parametrləri", + "header": "Admin İstifadəƧi Nəzarəti Parametrləri", + "admin": "Admin", + "user": "İstifadəƧi", + "addUser": "Yeni İstifadəƧi ʏlavə Et", + "deleteUser": "İstifadəƧi Sil", + "confirmDeleteUser": "İstifadəƧi silinməlidirmi?", + "confirmChangeUserStatus": "İstifadəƧi aktivləşdirilməli/deaktivləşdirilməlidirmi?", + "usernameInfo": "İstifadəƧi adı sadəcə hərflərdən, rəqəmlərdən və @._+- xüsusi simvollarından ibarət ola bilər və ya düzgün email ünvanı olmalıdır.", + "roles": "Rollar", + "role": "Rol", + "actions": "Fəaliyyətlər", + "apiUser": "Məhdudlaşdırılmış API İstifadəƧisi", + "extraApiUser": "ʏlavə Məhdudlaşdırılmış API İstifadəƧisi", + "webOnlyUser": "Yalnız Veb İstifadəƧisi", + "demoUser": "Demo İstifadəƧisi (Fərdi parametrlər yoxdur)", + "internalApiUser": "Daxili API İstifadəƧisi", + "forceChange": "İstifadəƧini giriş zamanı parolu dəyişməyə məcbur et", + "submit": "İstifadəƧini Saxla", + "changeUserRole": "İstifadəƧinin rolunu dəyişdir", + "authenticated": "Doğrulanmış", + "editOwnProfil": "Ɩz profilini redaktə et", + "enabledUser": "aktivləşdirilmiş istifadəƧi", + "disabledUser": "deaktivləşdirilmiş istifadəƧi", + "activeUsers": "Aktiv İstifadəƧilər:", + "disabledUsers": "Deaktiv İstifadəƧilər:", + "totalUsers": "Ümumi İstifadəƧilər:", + "lastRequest": "Son sorğu", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Verilənlər bazasını Daxil/Xaric Et", + "header": "Verilənlər bazasını Daxil/Xaric Et", + "fileName": "Fayl Adı", + "creationDate": "Yaradılma tarixi", + "fileSize": "Fayl Ɩlçüsü", + "deleteBackupFile": "Yedək Faylını Sil", + "importBackupFile": "Yedək Faylını Daxil Et", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Yedək Faylını Yüklə", + "info_1": "Məlumatı daxil edərkən doğru strukturun mƶvcudluğundan əmin olmaq vacibdir. ʏgər nə etdiyinizdən əmin deyilsinizsə, professional birindən məsləhət və yardım alın. Strukturdakı xəta proqramdakı nasazlıqlardan proqramı Ƨalışdırma qabiliyyətinin tamamilə aradan qalxmasına qədər bir sıra problemlərə səbəb ola bilər.", + "info_2": "Faylın adı fayl yüklənərkən ƶnəmli deyildir. Faylın adı sonradan sabit adlandırmanın varlığından əmin olmaq məqsədilə backup_user_yyyyMMddHHmm.sql tərzində formata dəyişdiriləcəkdir.", + "submit": "Yedəkləməni Daxil Et", + "importIntoDatabaseSuccessed": "Verilənlər bazasına daxil etmə uğurla nəticələndi", + "backupCreated": "Database backup successful", + "fileNotFound": "Fayl Tapılmadı", + "fileNullOrEmpty": "Fayl boş və ya \"null\" olmamalıdır", + "failedImportFile": "Faylı daxil etmək alınmadı", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "Sessiyanızın vaxtı bitdi. Səhifəni yeniləyin və yenidən cəhd edin.", + "refreshPage": "Səhifəni Yenilə" + }, + "home": { + "desc": "Bütün PDF ehtiyaclarınız üçün lokal-host edilən biraddımlıq həll.", + "searchBar": "Xüsusiyyətləri axtar...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Bax, sitat gƶtür, mətn və ya şəkil əlavə et" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "PDF Multi-alət", + "desc": "Səhifələri Birləşdir, Ƈevir, Yenidən Sırala, Bƶl və Sil" + }, + "merge": { + "title": "Birləşdir", + "desc": "Bir neƧə PDF-i asanlıqla bir PDF-də birləşdir." + }, + "split": { + "title": "Bƶl", + "desc": "PDF-ləri bir neƧə sənədə bƶl" + }, + "rotate": { + "title": "Ƈevir", + "desc": "PDF-lərinizi asanlıqla Ƨevirin." + }, + "imageToPdf": { + "title": "Şəkildən PDF-ə", + "desc": "Şəkli (PNG, JPEG, GIF) PDF-ə Ƈevir." + }, + "pdfToImage": { + "title": "PDF-dən Şəkilə", + "desc": "PDF-i Şəkilə Ƈevir. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Səhifələri Sırala", + "desc": "Səhifələri Sil/Sırasını Dəyiş" + }, + "addImage": { + "title": "Şəkil əlavə et", + "desc": "PDF-də təyin edilmiş yerə şəkil əlavə edir" + }, + "watermark": { + "title": "Watermark əlavə et", + "desc": "PDF sənədinə fərdi watermark əlavə et." + }, + "permissions": { + "title": "İcazəni Dəyiş", + "desc": "PDF Sənədinin icazələrini dəyiş" + }, + "removePages": { + "title": "Sil", + "desc": "PDF Sənədindən istəmədiyin şəkilləri sil." + }, + "addPassword": { + "title": "Şifr ʏlavə Et", + "desc": "Sənədini şifr ilə kilidlə." + }, + "removePassword": { + "title": "Şifri Sil", + "desc": "PDF Sənədindən şifr qorumasını gƶtür." + }, + "compressPdfs": { + "title": "Sıx", + "desc": "PDF fayllarını sıxaraq onların ƶlçüsünü azalt." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Metadatanı Dəyiş", + "desc": "PDF sənədindəki Metadatanı Dəyiş/Sil/ʏlavə et" + }, + "fileToPDF": { + "title": "Faylı PDF-ə Ƈevir", + "desc": "Hardasa bütün faylları PDF-ə Ƨevir (DOCX, PNG, XLS, PPT, TXT və daha Ƨox)" + }, + "ocr": { + "title": "OCR / Skanları Təmizlə", + "desc": "Skanları təmizləyir və PDF-in iƧərisindəki şəkillərdəki yazını tapıb mətn olaraq əlavə edir." + }, + "extractImages": { + "title": "Şəkilləri Xaric Et", + "desc": "PDF-dəki şəkilləri xaric edib onları zip faylında saxlayır" + }, + "pdfToPDFA": { + "title": "PDF-dən PDF/A-a", + "desc": "PDF faylını uzunmüddətli saxlama üçün PDF/A-a Ƨevir" + }, + "PDFToWord": { + "title": "PDF-dən Word-ə", + "desc": "PDF-i Word formatlarına Ƨevir (DOC, DOCX və ODT)" + }, + "PDFToPresentation": { + "title": "PDF-dən Təqdimata", + "desc": "PDF-i Təqdimat formatlarına Ƨevir (PPT, PPTX və ODP)" + }, + "PDFToText": { + "title": "PDF-də RTF-ə (Mətn)", + "desc": "PDF-i mətn və ya RTF formatına Ƨevir" + }, + "PDFToHTML": { + "title": "PDF-dən HTML-ə", + "desc": "PDF-i HTML-ə Ƨevir" + }, + "PDFToXML": { + "title": "PDF-dən XML-ə", + "desc": "PDF-i XML Formatına Ƈevir" + }, + "ScannerImageSplit": { + "title": "Skan Edilmiş Şəkilləri Detektə et/Ayır", + "desc": "Şəkil/PDF-dən Ƨoxlu şəkilləri ayırır" + }, + "sign": { + "title": "İmzala", + "desc": "Mətn, şəkil və ya əllə Ƨəkmə üsulu ilə PDF-ə imza əlavə edir" + }, + "flatten": { + "title": "Sadələşdir", + "desc": "Bütün interaktiv elementləri və anketləri PDF-dən sil" + }, + "repair": { + "title": "Bərpa Et", + "desc": "Pozulmuş PDF-i Bərpa Etməyə Ƈalışır" + }, + "removeBlanks": { + "title": "Boş Səhifələri Sil", + "desc": "Sənəddə boş səhifələri tapır və silir" + }, + "removeAnnotations": { + "title": "Sitatları Sil", + "desc": "PDF-dən bütün şərhləri və sitatları silir" + }, + "compare": { + "title": "Müqayisə Et", + "desc": "2 PDF Sənədini müqayisə edir və fərqləri gƶstərir" + }, + "certSign": { + "title": "Sertifikat İlə İmzala", + "desc": "PDF-i Sertifikat/AƧar (PEM/P12) ilə imzalayır" + }, + "removeCertSign": { + "title": "Sertifikat İmzasını Sil", + "desc": "PDF-dən Sertifikat imzasını gƶtür" + }, + "pageLayout": { + "title": "Ƈoxsəhifəli Tərtibat", + "desc": "PDF-in birdən Ƨox səhifəsini bir səhifədə birləşdir" + }, + "scalePages": { + "title": "Səhifə ƶlçüsünü/Miqyasını Dəyiş", + "desc": "Səhifənin və/və ya onun məzmununun ƶlçüsünü və miqyasını dəyiş" + }, + "pipeline": { + "title": "Pipeline", + "desc": "Pipeline Skriptləri təyin edərək PDF-lər üzərində bir neƧə prosesi eyni vaxtda reallaşdırın." + }, + "add-page-numbers": { + "title": "Səhifələri Nƶmrələ", + "desc": "Sənədin səhifələrinə təyin edilmiş yerdə nƶmrələr əlavə edin" + }, + "auto-rename": { + "title": "PDF Faylını Avtomatik Yenidən Adlandır", + "desc": "Tapılmış başlığa əsasən PDF faylının adını dəyişir" + }, + "adjust-contrast": { + "title": "Rəngləri/Kontrastı Tənzimlə", + "desc": "PDF-in kontrastını, parlaqlığını, rəng doyğunluğunu tənzimlə" + }, + "crop": { + "title": "PDF-i Kəs", + "desc": "Ɩlçüsünü azaltmaq üçün PDF-i kəs (mətni saxlayır!)" + }, + "autoSplitPDF": { + "title": "Səhifələri Avtomatik Ayır", + "desc": "Fiziki skan olunmuş səhifələri QR koda əsasən ayır" + }, + "sanitizePdf": { + "title": "Təmizlə", + "desc": "Skriptləri və digər elementləri PDF faylından sil" + }, + "URLToPDF": { + "title": "URL/Veb-Sayt-dan PDF-ə", + "desc": "Hər hansı http(s)URL-i PDF-ə Ƨevirir" + }, + "HTMLToPDF": { + "title": "HTML-dən PDF-ə", + "desc": "Hər hansı HTML faylını və ya ZİP-i PDF-ə Ƨevirir" + }, + "MarkdownToPDF": { + "title": "Markdown-dan PDF-ə", + "desc": "Hər hansı Markdown faylını PDF-ə Ƨevirir" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "PDF-in Bütün Məlumatları", + "desc": "PDF barədə mümkün olan bütün məlumatları əldə edir" + }, + "extractPage": { + "title": "Səhifə(lər)i xaric et", + "desc": "SeƧilmiş səhifələri PDF-dən xaric edərək əldə et" + }, + "PdfToSinglePage": { + "title": "PDF-dən 1 Bƶyük Səhifəyə", + "desc": "Bütün PDF səhifələrini bir bƶyük səhifəyə Ƨevirir" + }, + "showJS": { + "title": "Javascript-i Gƶstər", + "desc": "PDF-in tərkibinə əlavə edilmiş JS-i axtarır və gƶstərir" + }, + "autoRedact": { + "title": "Avtomatik Gizlətmə", + "desc": "Daxil edilmiş data əsasında PDF-dəki müəyyən mətn hissəsini qara qutu ilə gizlədir" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF-dən CSV-ə", + "desc": "PDF-dən cədvəlləri CSV-ə Ƨevirərək xaric edir" + }, + "autoSizeSplitPDF": { + "title": "Say/Ɩlçüyə ʏsasən Avtomatik Ayır", + "desc": "PDF-i ƶlçüyə, səhifə sayına və ya sənəd sayına əsasən bir neƧə PDF-ə ayır." + }, + "overlay-pdfs": { + "title": "Üst-Üstə Qoy", + "desc": "Bir PDF-i digərinin üstünə qoyur" + }, + "split-by-sections": { + "title": "PDF-i Hissələrə ʏsasən Bƶl", + "desc": "PDF-in hər səhifəsini daha kiƧik üfuqi və şaquli hissələrə bƶl" + }, + "AddStampRequest": { + "title": "PDF-i Mƶhürlə", + "desc": "Təyin edilmiş hissələrə mətn və ya şəkil mƶhürləri əlavə edin" + }, + "removeImagePdf": { + "title": "Şəkli Sil", + "desc": "Fayl ƶlçüsünü azaltmaq üçün PDF-dən şəkil sil" + }, + "splitPdfByChapters": { + "title": "PDF-i Fəsillərə ʏsasən Bƶl", + "desc": "Fəsil strukturuna əsasən PDF-i bir neƧə fayla bƶl." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "replaceColorPdf": { + "title": "Qabaqcıl Rəng SeƧimləri", + "desc": "Replace color for text and background in PDF and invert full color of pdf to reduce file size" + } + }, + "viewPdf": { + "tags": "bax,oxu,sitat gƶtür,mətn,şəkil", + "title": "View/Edit PDF", + "header": "PDF-ə baxın" + }, + "multiTool": { + "tags": "Multi-alət,Ƈoxlu əməliyyat,UI,tut-sürüşdür,front end,istifadəƧi-tərəf,interaktiv,qarşılıqlı,yerini dəyiş,sil,köçür,bƶl", + "title": "PDF Multi-Alət", + "header": "PDF Multi-Alət", + "uploadPrompts": "Fayl Adı", + "selectAll": "Hamısını SeƧ", + "deselectAll": "Hamısını SeƧməni Ləğv Et", + "selectPages": "Səhifə SeƧimi", + "selectedPages": "SeƧilmiş Səhifələr", + "page": "Səhifə", + "deleteSelected": "SeƧilmişi Sil", + "downloadAll": "İxrac Et", + "downloadSelected": "SeƧilmişi İxrac Et", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "SeƧilmiş Səhifə(lər)", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "birləşdir,Səhifə əməliyyatları,Back end,server-tərəf", + "title": "Birləşdirin", + "header": "Ƈoxsaylı PDF-ləri birləşdirin (2+)", + "sortByName": "Ada gƶrə Ƨeşidləyin", + "sortByDate": "Tarixə gƶrə Ƨeşidləyin", + "removeCertSign": "Birləşdirilmiş faylda rəqəmsal imza silinsin?", + "submit": "Birləşdirin" + }, + "split": { + "tags": "Səhifə əməliyyarları,bƶl,Ƈoxlu Səhifə,kəs,server-tərəf", + "title": "PDF-i Bƶlün", + "header": "PDF-i Bƶlün", + "desc": { + "1": "SeƧdiyiniz Nƶmrələr Bƶlmək İstədiyiniz Səhifə Nƶmrəsidir", + "2": "Beləliklə, 1,3,7-9 SeƧimi 10 Səhifəlik Sənədi 6 Ayrı PDF-ə Bƶləcək:", + "3": "Sənəd #1: Səhifə 1", + "4": "Sənəd #2: Səhifə 2 və 3", + "5": "Sənəd #3: Səhifə 4, 5, 6 və 7", + "6": "Sənəd #4: Səhifə 8", + "7": "Sənəd #5: Səhifə 9", + "8": "Sənəd #6: Səhifə 10" + }, + "splitPages": "Bƶlünəcək Səhifələri Daxil Edin:", + "submit": "Bƶlün" + }, + "rotate": { + "tags": "server-tərəf", + "title": "PDF fırladın", + "header": "PDF fırladın", + "selectAngle": "Fırlanma bucağını seƧin (90 dərəcə ilə):", + "submit": "Fırladın" + }, + "imageToPdf": { + "tags": "Ƨevirmə,şəkil,jpg,fotoşəkil,foto" + }, + "pdfToImage": { + "tags": "Ƨevirmə,şəkil,jpg,fotoşəkil,foto", + "title": "PDF-i Şəklə", + "header": "PDF-i Şəklə", + "selectText": "Şəkil Formatı", + "singleOrMultiple": "Nəticə Şəkil Tipi", + "single": "Bütün Səhifələri birləşdirən Tək Bƶyük Şəkil", + "multi": "Ƈoxlu Şəkil, Səhifə Başına Bir Şəkil", + "colorType": "Rəng Tipi", + "color": "Rəng", + "grey": "Boz Tonlama", + "blackwhite": "Qara və Ağ (Data İtə Bilər)", + "submit": "Ƈevir", + "info": "Python Yüklü Deyil.WebP Ƈevirməsi Üçün Vacibdir", + "placeholder": "(məsələn, 1,2,8 və ya 4,7,12-16 və ya 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,tək,cüt,sırala,yerini dəyiş", + "title": "Səhifə Tənzimləyicisi", + "header": "PDF Səhifə Tənzimləyicisi", + "submit": "Səhifələri Yenidən Təşkil Edin", + "mode": { + "_value": "Rejim", + "1": "Fərdi Səhifə Düzülüşü", + "2": "Tərs Düzülüş", + "3": "İkitərəfli Ƈeşidləmə", + "4": "KitabƧa Ƈeşidləmə", + "5": "Yan Tikiş KitabƧasının Ƈeşidlənməsi", + "6": "Tək-Cüt Bƶlünmə", + "7": "Birincini Sil", + "8": "Sonuncunu Sil", + "9": "Birinci və Sonuncunu Sil", + "10": "Tək-Cüt Birləşdirmə", + "11": "Duplicate all pages" + }, + "placeholder": "(məs., 1,3,2 və ya 4-8,2,10-12 və ya 2n-1)" + }, + "addImage": { + "tags": "şəkil,jpg,fotoşəkil,foto", + "title": "Şəkli ʏlavə Et", + "header": "Şəkli PDF-ə ʏlavə Et", + "everyPage": "Bütün Səhifələr?", + "upload": "Şəkli ʏlavə Et", + "submit": "Şəkli ʏlavə Et" + }, + "watermark": { + "tags": "Mətn,təkrarlanan,nişan,sahib olmaq,müəllif hüquqları,əmtəə nişanı,şəkil,jpg,fotoşəkil,foto", + "title": "Watermark ʏlavə Et", + "header": "Watermark ʏlavə Et", + "customColor": "Fərdi Mətn Rəngi", + "selectText": { + "1": "Watermark əlavə olunacaq PDF-i seƧ", + "2": "Watermark Mətni:", + "3": "Şrift Ɩlçüsü:", + "4": "Fırlatma (0-360):", + "5": "enBoşluq (Üfuqi olaraq watermark-lar arasındakı məsafə):", + "6": "uzunluqBoşluq (Şaquli olaraq watermark-lar arasındakı məsafə):", + "7": "Şəffaflıq (0% - 100%):", + "8": "Watermark Tipi:", + "9": "Watermark Şəkili:", + "10": "PDF-i PDF-Şəkil-ə Ƨevir" + }, + "submit": "Watermark ʏlavə Et", + "type": { + "1": "Mətn", + "2": "Şəkil" + } + }, + "permissions": { + "tags": "oxu,yaz,redaktə et,Ƨap et", + "title": "İcazələri Dəyişdir", + "header": "İcazələri Dəyişdir", + "warning": "Bu İcazələrin Dəyişməz Olması İlə Bağlı Xəbərdarlıq Edərək, Onları Parol ʏlavə Et Səhifəsi Vasitəsilə Parolla Təyin Etmək Tƶvsiyə Olunur.", + "selectText": { + "1": "İcazələri Dəyişdirmək Üçün PDF-i SeƧ", + "2": "Tənzimlənmiş İcazələr", + "3": "Sənədin Yığılmasının Qarşısını Al", + "4": "Məzmunun Ƈıxarılmasının Qarşısını Al", + "5": "ʏlƧatanlıq Üçün Ƈıxarılmasının Qarşısını Alın", + "6": "Formanın Doldurulmasının Qarşısını Alır", + "7": "Modifikasiyanın Qarşısını Al", + "8": "Annotasiyanın Dəyişdirilməsinin Qarşısını Almaq", + "9": "Ƈapın Qarşısını Al", + "10": "Fərqli Formatlarda Ƈapın Qarşısını Al" + }, + "submit": "Dəyiş" + }, + "removePages": { + "tags": "Səhifələri təmizlə,səhifələri sil" + }, + "addPassword": { + "tags": "təhlükəsiz,təhlükəsizlik", + "title": "Şifr ʏlavə Et", + "header": "Şifr ʏlavə Et (Şifrləmə)", + "selectText": { + "1": "Şifrlənəcək PDF-i seƧ", + "2": "İstifadəƧi Şifri", + "3": "Şifrləmə AƧarı Uzunluğu", + "4": "Bƶyük dəyərlər daha güclüdür, lakin kiƧik dəyərlərin uyğunluğu yüksəkdir.", + "5": "Təyin olunacaq icazə (Sahib (Owner) Şifri ilə birgə istifadə olunması tƶvsiyə olunur.)", + "6": "Sənədin strukturunun dəyişilməsinin qarşısını al", + "7": "Məzmun xaric edilməsinin qarşısını al", + "8": "ʏlƧatanlıq üçün xaricetmənin qarşısını al", + "9": "Anketin doldurulmasının qarşısını al", + "10": "Modifikasiyanın qarşısını al", + "11": "Sitat modifikasiyasının qarşısını al", + "12": "Ƈap etmənin qarşısını al", + "13": "Müxtəlif formatların Ƨap edilməsinin qarşısını al", + "14": "Sahib Şifri", + "15": "Sənəd aƧıldıqdan sonra onunla nə edilə biləcəyini limitləndir (Bütün oxuyucular dəstəkləmir)", + "16": "Sənədin ƶzünün aƧılmağını limitləndirir" + }, + "submit": "Şifrlə" + }, + "removePassword": { + "tags": "təhlükəsiz,deşifr,təhlükəsizlik,kodu aƧ,kodu sil", + "title": "Şifri Sil", + "header": "Şifri Sil (Deşifr)", + "selectText": { + "1": "Deşifr Üçün PDF-i SeƧ", + "2": "Şifr" + }, + "submit": "Sil" + }, + "compressPdfs": { + "tags": "sıx,balaca,kiƧik" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Başlıq,müəllif,tarix,yaradılış,zaman,yayımƧı,istehsalƧı,statistika", + "title": "Metadata-nı Dəyiş", + "header": "Metadata-nı Dəyiş", + "selectText": { + "1": "Dəyişmək istədiyiniz dəyişənləri redaktə edin", + "2": "Bütün Metadata-nı Sil", + "3": "Fərdi Metadatanı gƶstərin:", + "4": "Digər Metadata:", + "5": "Xüsusi Metadata girişi əlavə edin" + }, + "author": "Müəllif:", + "creationDate": "Yaradılma Tarixi (yyyy/MM/dd HH:mm:ss):", + "creator": "Yaradıcı:", + "keywords": "AƧar Sƶzlər:", + "modDate": "Dəyişiklik Tarixi (yyyy/MM/dd HH:mm:ss):", + "producer": "İstehsalƧı:", + "subject": "Mƶvzu:", + "trapped": "Tələ:", + "submit": "Dəyiş" + }, + "fileToPDF": { + "tags": "Ƨevirmə,format,sənəd,şəkil,slayd,mətn,Ƨevirmə,ofis,docs,word,excel,powerpoint", + "title": "Faylı PDF-ə", + "header": "Hər Hansı Bir Faylı PDF-ə Ƈevir", + "credit": "Bu Servis Fayl Ƈevirmək Üçün LibreOffice və Unoconv İşlədir", + "supportedFileTypesInfo": "Dəstəklənən Fayl Tipləri", + "supportedFileTypes": "Dəstəklənən Fayl Tipləri Aşagıdakıları Təşkil Etməlidir,ancaq Dəstəklənmiş Faylların Hamısının Yenilənmiş Siyahısı Üçün LibreOffice Sənədlərinə Baş Ƈəkin", + "submit": "PDF-ə Ƈevir" + }, + "ocr": { + "tags": "tanıma,mətn,şəkil,skan,oxu,tanı,təyin et,redaktəediləbilən", + "title": "OST (OCR) / Skan Təmizləmə", + "header": "Skanları Təmizlə / OST (Optik Simvol Tanınması)", + "selectText": { + "1": "PDF-də aşkar olunacaq dilləri seƧin (Gƶstərilmiş dillər hazırda aşkar olunmuşlardır):", + "2": "OST-lənmiş PDF ilə yanaşı daxilində OST edilmiş mətn olan PDF yaradın", + "3": "ʏyri skan olunmuş səhifələri yerinə fırladaraq düzəldin", + "4": "OST-in arxaplandakı artıq mətni aşkar etməsinin qarşısını almaq üçün səhifəni təmizləyin. (Ƈıxış dəyişmir)", + "5": "OST-in arxaplandakı artıq mətni aşkar etməsinin qarşısını almaq üçün səhifəni təmizləyin, təmizləməni Ƨıxışa verilən faylda saxlayır.", + "6": "Üzərində interaktiv yazı olan səhifələri nəzərə almır, yalnız şəkil olan səhifələri OST edir.", + "7": "OST-ə məcbur et, bütün orijinal mətn elementlərini silərək hər səhifəni OST edir", + "8": "Normal (PDF-də mətn varsa, xəta verəcək)", + "9": "ʏlavə Parametrlər", + "10": "OST (OCR) Rejimi", + "11": "OST-dən sonra şəkilləri sil (BÜTÜN şəkilləri silir, ancaq Ƨevirmə prosesinin bir hissəsi olduqda işə yarayır)", + "12": "Render Tipi (Qabaqcıl)" + }, + "help": "Bunu digər dillər üçün necə istifadə etmək və/və ya docker-də istifadə etməmək üçün bu dokumentasiyanı oxuyun", + "credit": "Bu servis OST (OCR) üçün \"OCRmyPDF\" və \"Tesseract\" istifadə edir.", + "submit": "PDF-i OST ilə işlə" + }, + "extractImages": { + "tags": "şəkil,foto,saxla,arxiv,zip,Ƨək,gƶtür", + "title": "Şəkilləri Ƨıxarın", + "header": "Şəkilləri Ƨıxarın", + "selectText": "Ƈıxarılan şəkilləri Ƨevirmək üçün şəkil formatını seƧin", + "allowDuplicates": "Dublikat şəkilləri yadda saxlayın", + "submit": "Ƈıxarış" + }, + "pdfToPDFA": { + "tags": "arxiv,uzunmüddətli,standard,Ƨevirmə,yaddaş,saxlama", + "title": "PDF-i PDF/A-ya", + "header": "PDF-i PDF/A-ya", + "credit": "Bu Servis PDF/A Ƈevirmək Üçün libreoffice İşlədir", + "submit": "Ƈevir", + "tip": "Hazırda Birdən Ƈox Giriş Üçün İşləmir", + "outputFormat": "Ƈıxış Formatı", + "pdfWithDigitalSignature": "PDF Rəqəmsal İmza Ehtiva Edir.Bu, nƶvbəti addımda silinəcək." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,dəyişmə,format,Ƨevirmə,ofis,microsoft,docfile", + "title": "PDF-i Word-ə", + "header": "PDF-i Word-ə", + "selectText": { + "1": "Ƈıxış Fayl Formatı" + }, + "credit": "Bu Servis Fayl Ƈevirmək Üçün LibreOffice İşlədir", + "submit": "Ƈevir" + }, + "PDFToPresentation": { + "tags": "slaydlar,şou,ofis,microsoft", + "title": "PDF-i Təqdimata", + "header": "PDF-i Təqdimata", + "selectText": { + "1": "Ƈıxış Fayl Formatı" + }, + "credit": "Bu Servis Fayl Ƈevirmək Üçün LibreOffice İşlədir", + "submit": "Ƈevir" + }, + "PDFToText": { + "tags": "richformat,richtextformat,zəngin mətn formatı", + "title": "PDF-i RTF (Mətn)-ə", + "header": "PDF-i RTF (Mətn)-ə", + "selectText": { + "1": "Ƈıxış Fayl Formatı" + }, + "credit": "Bu Servis Fayl Ƈevirmək Üçün LibreOffice İşlədir", + "submit": "Ƈevir" + }, + "PDFToHTML": { + "tags": "veb-məzmun,brauzerə uyğun", + "title": "PDF-i HTML-ə", + "header": "PDF-i HTML-ə", + "credit": "Bu Servis Fayl Ƈevirmək Üçün pdftohtml İşlədir", + "submit": "Ƈevir" + }, + "PDFToXML": { + "tags": "data-xaricetmə,strukturlu-məzmun,interop,Ƨevirmə,dəyişmə", + "title": "PDF-i XML-ə", + "header": "PDF-i XML-ə", + "credit": "Bu Servis Fayl Ƈevirmək Üçün LibreOffice İşlədir", + "submit": "Ƈevir" + }, + "ScannerImageSplit": { + "tags": "ayır,avtodetektə,skan,Ƨoxlu şəkil,nizamla", + "selectText": { + "1": "Bucaq Aşağı Limiti:", + "2": "Şəklin fırladılması üçün lazım olan minimal mütləq bucağı təyin edir (defolt: 10).", + "3": "Rəng Toleransı:", + "4": "Təxmin olunan arxaplan rənginin ətrafındakı rəng fərqliliyi intervalını təyin edir (defolt: 30).", + "5": "Minimal Sahə:", + "6": "Foto üçün minimal sahənin aşağı limitini təyin edir (defolt: 10000).", + "7": "Minimal Kontur Sahəsi:", + "8": "Fotonun kontur sahəsi üçün minimal aşağı limiti təyin edir", + "9": "Sərhəd Ɩlçüsü:", + "10": "Faylda ağ sərhədlərin olmasının qarşısını almaq üçün əlavə ediləcək sərhədin ƶlçüsünü təyin edir (defolt: 1)." + }, + "info": "Python yüklənməyib. İşə salmaq üçün Python lazımdır." + }, + "sign": { + "tags": "təsdiqlə,baş hərflər,Ƨəkilmiş-imza,mətn-imza,şəkil-imza", + "title": "İmza", + "header": "PDF sənədlərini imzalayın", + "upload": "Şəkil Yüklə", + "draw": "İmza Ƨəkmək", + "text": "Mətn daxil etmə", + "clear": "Təmizləmək", + "add": "ʏlavə et", + "saved": "Saxlanan İmzalar", + "save": "İmzanı yadda Saxla", + "personalSigs": "Şəxsi İmzalar", + "sharedSigs": "Paylaşılan İmzalar", + "noSavedSigs": "Saxlanmış imza tapılmadı", + "addToAll": "Bütün səhiflərə əlavə et", + "delete": "Sil", + "first": "İlk səhifə", + "last": "Son səhifə", + "next": "Nƶvbəti səhifə", + "previous": "ʏvvəlki səhifə", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "statik,deaktiv,qeyri-interaktiv,streamline", + "title": "Düzləşdirin", + "header": "PDF-i düzləşdirin", + "flattenOnlyForms": "Yalnız formaları düzəldin", + "submit": "Düzləşdirin" + }, + "repair": { + "tags": "düzəlt,bərpa et,korreksiya et,geri qaytar", + "title": "Bərpa Et", + "header": "PDFləri Bərpa Et", + "submit": "Bərpa Et" + }, + "removeBlanks": { + "tags": "təmizləmə,streamline,qeyri-məzmun,nizamla", + "title": "Boş Səhifələri Sil", + "header": "Boş Sʏhifələri Silir", + "threshold": "Minimal Piksel Bəyazlığı:", + "thresholdDesc": "Pikselin \"Ağ\" hesab olunması üçün minimal nə qədər bəyaz olmalı olduğunu təyin edin. 0 = Qara, 255 Ağappaq.", + "whitePercent": "Bəyaz Faizi (%):", + "whitePercentDesc": "Silinmək üçün səhifənin neƧə faizi \"ağ\" piksellərdən təşkil olunmalıdır", + "submit": "Boş Səhifələri Sil" + }, + "removeAnnotations": { + "tags": "şərhlər,ƶnə Ƨıxanlar,qeydlər,işarələmə,sil", + "title": "Annotasiyaları silin", + "header": "Annotasiyaları silin", + "submit": "Sil" + }, + "compare": { + "tags": "fərqləndir,təzad yarat,dəyişikliklər,analiz", + "title": "Müqayisə Et", + "header": "PDF-ləri Müqayisə Et", + "highlightColor": { + "1": "Ɩnə Ƈıxarma Rəngi 1:", + "2": "Ɩnə Ƈıxarma Rəngi 2:" + }, + "document": { + "1": "Sənəd 1", + "2": "Sənəd 2" + }, + "submit": "Müqayisə Et", + "complex": { + "message": "Fayllardan biri və ya ikisi də bƶyük fayldır. Müqayisə effektivliyi azala bilər." + }, + "large": { + "file": { + "message": "Fayllardan biri və ya ikisi də işləmək üçün Ƨox bƶyükdür." + } + }, + "no": { + "text": { + "message": "Fayllardan birində və ya ikisində də mətn məzmunu yoxdur. Zəhmət olmasa, müqayisə üçün mətn məzmunlu PDF seƧin." + } + } + }, + "certSign": { + "tags": "Doğrula,PEM,P12,rəsmi,şifrlə", + "title": "Sertifikatla İmzala", + "header": "PDF-i Sertifikatınızla İmzalayın (İşlənilir)", + "selectPDF": "İmzalamaq üçün PDF Faylı seƧin:", + "jksNote": "Note: ʏgər sertifikatınızın tipi aşağıda gƶstərilməyibsə, zəhmət olmasa \"Keytool command line tool\" istifadə edərək onu \"Java Keystroke\" (.jks) faylına Ƨevirin. Sonra, aşağıdan .jks faylını seƧin.", + "selectKey": "Şəxsi AƧar faylınızı seƧin (PKCS#8 format, .pem və ya .der ola bilər):", + "selectCert": "Sertifikat faylınızı seƧin (X.509 format, .pem və ya .der ola bilər):", + "selectP12": "PKCS#12 Keystore Faylınızı seƧin (.p12 və ya .pfx) (İstəyə bağlı, əgər təmin olunarsa, şəxsi aƧar və sertifikatınızı ehtiva etməlidir):", + "selectJKS": "Java Keystore Faylınızı seƧin (.jks və ya .keystore):", + "certType": "Sertifikat Tipi", + "password": "Keystore və ya Şəxsi AƧar daxil edin (ʏgər varsa):", + "showSig": "İmzanı Gƶstər", + "reason": "Səbəb", + "location": "Məkan", + "name": "Ad", + "showLogo": "Loqonu Gƶstər", + "submit": "PDF-i İmzala" + }, + "removeCertSign": { + "tags": "Doğrula,PEM,P12,rəsmi,deşifr", + "title": "Sertifikat İmzasını Sil", + "header": "Rəqəmsal sertifikatı PDF-dən Ƨıxarın", + "selectPDF": "PDF faylı seƧin:", + "submit": "İmzanı silin" + }, + "pageLayout": { + "tags": "birləşdir,sintez,tək-baxış,nizamla", + "title": "Ƈoxsəhifəli Tərtibat", + "header": "Ƈoxsəhifəli Tərtibat", + "pagesPerSheet": "Vərəqdəki Səhifə Sayı:", + "addBorder": "ƇərƧivə ʏlavə Et", + "submit": "Təsdiq et" + }, + "scalePages": { + "tags": "ƶlçüsünü dəyiş,modifikasiya et,ƶlçülər,uyğunlaş", + "title": "Səhifə miqyasını tənzimləyin", + "header": "Səhifə miqyasını tənzimləyin", + "pageSize": "Sənədin bir səhifəsinin ƶlçüsü.", + "keepPageSize": "Orijinal Ɩlçü", + "scaleFactor": "Səhifənin bƶyütmə səviyyəsi (kəsmə).", + "submit": "Təsdiq edin" + }, + "add-page-numbers": { + "tags": "nƶmrələ,taq,səliqələ,indeks" + }, + "auto-rename": { + "tags": "avtodetektə,başlıq-əsaslı,səliqələ,yenidən adlandır", + "title": "Avtomatik Yenidən Adlandır", + "header": "Pdf-in Adını Avtomatik Yenidən Adlandır", + "submit": "Avtomatik Yenidən Adlandır" + }, + "adjust-contrast": { + "tags": "rəng-tənzimləmə,kƶklə,modifikasiya et,yaxşılaşdır" + }, + "crop": { + "tags": "kəs,kiƧilt,redaktə et,forma", + "title": "Kəs", + "header": "Pdf-ləri Kəs", + "submit": "Təsdiq Et" + }, + "autoSplitPDF": { + "tags": "QR-əsaslı,ayrı,skan-seqment,nizamla", + "title": "PDF-i avtomatik bƶlmə", + "header": "PDF-i avtomatik bƶlmə", + "description": "Sənədlərinizi Ƨap edin, daxil edin, skan edin, yükləyin və bizə icazə verin. ʏl işinin Ƨeşidlənməsinə ehtiyac yoxdur.", + "selectText": { + "1": "Aşağıdan bəzi ayırıcı vərəqləri Ƨap edin (qara və ağ yaxşıdır).", + "2": "Aralarına ayırıcı vərəq daxil edərək bütün sənədlərinizi bir anda skan edin.", + "3": "Tək bƶyük skan edilmiş PDF faylını yükləyin və Stirling PDF-in qalanını idarə etməsinə icazə verin.", + "4": "Ayırıcı səhifələr avtomatik aşkarlanır və silinir, səliqəli yekun sənədə zəmanət verir." + }, + "formPrompt": "Stirling-PDF ə Səhifə bƶlücüləri olan PDF-i təqdim edin:", + "duplexMode": "Dupleks rejimi (Ɩn və arxa skanlama)", + "dividerDownload2": "'Auto Splitter Divider (with instructions).pdf'-ı yükləyin", + "submit": "Təsdiq edin" + }, + "sanitizePdf": { + "tags": "təmiz,təhlükəsiz,güvənli,sil" + }, + "URLToPDF": { + "tags": "veb,səhifəni-saxla,webdən-sənədə,arxiv", + "title": "URL-i PDF-ə", + "header": "URL-i PDF-ə", + "submit": "Ƈevir", + "credit": "WeasyPrint İstifadə Edir" + }, + "HTMLToPDF": { + "tags": "işarələmə,veb-məzmun,Ƨevirmə,dəyişmə", + "title": "HTML-dən PDF-ə", + "header": "HTML-dən PDF-ə", + "help": "HTML fayllarını və tərkibində mütləq html/css/images və s. olan ZIP fayllarını qəbul edir", + "submit": "Ƈevir", + "credit": "WeasyPrint İstifadə Edir", + "zoom": "Vebsaytı gƶstərmək üçün yaxınlaşdırma dərəcəsi.", + "pageWidth": "Səhifənin eninin santimetrlərlə ƶlçüsü. (Standart üçün boş buraxın)", + "pageHeight": "Səhifənin hündürlüyünün santimetrlərlə ƶlçüsü. (Standart üçün boş buraxın)", + "marginTop": "Səhifənin yuxarı kənarının millimetrlə ƶlçüsü. (Standart üçün boş buraxın)", + "marginBottom": "Səhifənin alt kənarının millimetrlə ƶlçüsü. (Standart üçün boş buraxın)", + "marginLeft": "Səhifənin sol kənarının millimetrlə ƶlçüsü. (Standart üçün boş buraxın)", + "marginRight": "Səhifənin sağ kənarının millimetrlə ƶlçüsü. (Standart üçün boş buraxın)", + "printBackground": "Vebsaytların arxa fonunu renderlə.", + "defaultHeader": "Standart Başlığı Aktivləşdir (Ad və səhifə nƶmrəsi)", + "cssMediaType": "Səhifənin CSS media nƶvünü dəyişdir.", + "none": "HeƧ biri", + "print": "Ƈap et", + "screen": "Ekran" + }, + "MarkdownToPDF": { + "tags": "işarələmə,web-məzmun,dəyişmə,Ƨevirmə", + "title": "Markdown-dan PDF-ə", + "header": "Markdown-dan PDF-ə", + "submit": "Ƈevir", + "help": "İş davam edir", + "credit": "WeasyPrint İstifadə Edir" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "informasiy,data,məlumatlar,statistika", + "title": "PDF Barəsində Məlumat ʏldə Et", + "header": "PDF Barəsində Məlumat ʏldə Et", + "submit": "Məlumat ʏldə Et", + "downloadJson": "JSON yüklə" + }, + "extractPage": { + "tags": "Ƨıxar" + }, + "PdfToSinglePage": { + "tags": "tək səhifə" + }, + "showJS": { + "tags": "JS", + "title": "Javascripti Gƶstər", + "header": "Javascripti Gƶstər", + "downloadJS": "Javascripti Endir", + "submit": "Gƶstər" + }, + "autoRedact": { + "tags": "Qarala,gizlət,sil,qara,marker,gizli", + "title": "Avtomatik Gizlətmə", + "header": "Avtomatik Gizlətmə", + "colorLabel": "Rəng", + "textsToRedactLabel": "Gizlədiləcək Mətn (Yeni sətirlə ayrılmış)", + "textsToRedactPlaceholder": "e.g. \\nKonfidensial \\nTam-Məxfi", + "useRegexLabel": "Regex İstifadə Et", + "wholeWordSearchLabel": "Bütƶv Sƶz Axtar", + "customPaddingLabel": "Fərdi ʏlavə Başlıq", + "convertPDFToImageLabel": "PDF-i PDF-Şəkil-ə Ƨevir (Qutunun arxasındakı yazını silmək üçün istifadə edilir)", + "submitButton": "Təsdiqlə" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,Cədvəl xaricetmə,xaric et,Ƨevir" + }, + "autoSizeSplitPDF": { + "tags": "pdf,ayır,sənəd,nizamla" + }, + "overlay-pdfs": { + "tags": "üst-üstə", + "header": "Overlay PDF faylları", + "baseFile": { + "label": "ʏsas PDF faylını seƧin" + }, + "overlayFiles": { + "label": "Overlay PDF fayllarını seƧin" + }, + "mode": { + "label": "Overlay Modu seƧin", + "sequential": "Sequential Overlay", + "interleaved": "Interleaved Overlay", + "fixedRepeat": "Sabit Təkrar Yerləşdirmə" + }, + "counts": { + "label": "Overlay Sayları (Sabit Təkrar Rejimi üçün)", + "placeholder": "Sayları vergüllə ayrılmış şəkildə daxil edin (məsələn, 2,3,1)" + }, + "position": { + "label": "Overlay Position seƧin", + "foreground": "Ɩn plan", + "background": "Arxa plan" + }, + "submit": "Təsdiq et" + }, + "split-by-sections": { + "tags": "Hissə Bƶlgüsü, Ayır, Fərdiləşdir", + "title": "PDF-i hissələrə bƶlün", + "header": "PDF-i hissələrə bƶlün", + "horizontal": { + "label": "Üfüqi bƶlmələr", + "placeholder": "Üfüqi bƶlmələrin sayını daxil edin" + }, + "vertical": { + "label": "Şaquli bƶlmələr", + "placeholder": "Şaquli bƶlmələrin sayını daxil edin" + }, + "submit": "Pdf-i bƶlmək", + "merge": "Bir PDF-ə birləşdirin" + }, + "AddStampRequest": { + "tags": "Mƶhür, Şəkil əlavə et, şəkli ortala, Watermark, PDF, Embed, Fərdiləşdir", + "header": "PDF-i Mƶhürlə", + "title": "PDF-i Mƶhürlə", + "stampType": "Mƶhür Tipi", + "stampText": "Mƶhür Yazısı", + "stampImage": "Mƶhür Fotosu", + "alphabet": "ʏlifba", + "fontSize": "Font/Şəkil Ɩlçüsü", + "rotation": "İstiqamət", + "opacity": "Şəffaflıq", + "position": "Yerləşmə", + "overrideX": "X Koordinatının Üstünə Yaz", + "overrideY": "Y Koordinatının Üstünə Yaz", + "customMargin": "Fərdi Boşluq Ɩlçüsü", + "customColor": "Fərdi Mətn Rəngi", + "submit": "Təsdiqlə" + }, + "removeImagePdf": { + "tags": "Şəkil Sil,Səhifə ʏməliyyatları,Back end,server-tərəf" + }, + "splitPdfByChapters": { + "tags": "bƶl,fəsillər,əlfəcinlər,nizamla" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Qabaqcıl Rəng SeƧimləri", + "header": "PDF-də Rəngləri Dəyiş-Tərsinə Ƈevir", + "selectText": { + "1": "Rəngi dəyişmə və tərsinə Ƨevirmə seƧimləri", + "2": "Defolt(Defolt yüksək kontrastlı rənglər)", + "3": "Fərdi(Fərdiləşdirilmiş rənglər)", + "4": "Bütƶv Tərsinə Ƈevir(Bütün rəngləri tərsinə Ƨevir)", + "5": "Yüksək kontrastlı rəng seƧimləri", + "6": "Qara arxaplanda ağ mətn", + "7": "Ağ arxaplanda qara mətn", + "8": "Qara arxaplanda sarı mətn", + "9": "Qara arxaplanda yaşıl mətn", + "10": "Mətn rəngi seƧ", + "11": "Arxaplan rəngi seƧ" + }, + "submit": "ʏvəzlə" + }, + "replaceColorPdf": { + "tags": "Rəngləri Dəyiş,Səhifə əməliyyatları,Back end,server-tərəf" + }, + "login": { + "title": "Daxil olun", + "header": "Daxil olun", + "signin": "Daxil olun", + "rememberme": "Məni xatırla", + "invalid": "Etibarsız istifadəƧi adı və ya şifr.", + "locked": "Sizin hesabınız kilidlənmişdir.", + "signinTitle": "Zəhmət olmasa, daxil olun", + "ssoSignIn": "Single Sign-on vasitəsilə daxil olun", + "oAuth2AutoCreateDisabled": "OAUTH2 Auto-Create İstifadəƧisi Deaktivləşdirilmişdir", + "oAuth2AdminBlockedUser": "Qeydiyyatdan keƧməmiş istifadəƧilərin qeydiyyatı və daxil olması hal-hazırda bloklanmışdır. Zəhmət olmasa, administratorla əlaqə saxlayın.", + "oauth2RequestNotFound": "Təsdiqlənmə sorğusu tapılmadı", + "oauth2InvalidUserInfoResponse": "Yanlış İstifadəƧi Məlumatı Cavabı", + "oauth2invalidRequest": "Etibarsız Sorğu", + "oauth2AccessDenied": "Giriş rədd edildi", + "oauth2InvalidTokenResponse": "Etibarsız Token Cavabı", + "oauth2InvalidIdToken": "Etibarsız Id Token", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "İstifadəƧi deaktivləşdirilmişdir, bu istifadəƧi adı ilə giriş hal-hazırda bloklanmışdır. Zəhmət olmasa, administratorla əlaqə saxlayın.", + "alreadyLoggedIn": "Siz artıq daxil olmusunuz", + "alreadyLoggedIn2": "cihazlar. Zəhmət olmasa, cihazlardan Ƨıxış edin və yenidən cəhd edin.", + "toManySessions": "Həddindən artıq aktiv sessiyanız var", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF-dən Tək Səhifəyə", + "header": "PDF-dən Tək Səhifəyə", + "submit": "Tək Səhifəyə Ƈevir" + }, + "pageExtracter": { + "title": "Səhifələri Ƨıxar", + "header": "Səhifələri Ƨıxar", + "submit": "Ƈıxar", + "placeholder": "(məsələn, 1,2,8 və ya 4,7,12-16 və ya 2n-1)" + }, + "sanitizePDF": { + "title": "PDF-i Təmizlə", + "header": "PDF Faylını Təmizlə", + "selectText": { + "1": "JavaScript Fəaliyyətlərini Sil", + "2": "Daxil Edilmiş Faylları Sil", + "3": "Remove XMP metadata", + "4": "Linkləri Sil", + "5": "Şriftləri Sil", + "6": "Remove Document Info Metadata" + }, + "submit": "PDF-i Təmizlə" + }, + "adjustContrast": { + "title": "Kontrastı tənzimləyin", + "header": "Kontrastı tənzimləyin", + "contrast": "Kontrast:", + "brightness": "Parlaqlıq:", + "saturation": "Doyma:", + "download": "Yüklə" + }, + "compress": { + "title": "Sıxışdır", + "header": "PDF-i Sıxışdır", + "credit": "Bu servis PDF sıxışdırılması/Optimizasiyası üçün Ghostscript istifadə edir.", + "grayscale": { + "label": "Sıxma üçün Boz Rəng Tətbiq Edin" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Optimizasiya səviyyəsi:", + "4": "Avto mod - PDF-in dəqiq ƶlçüsünü əldə etmək üçün keyfiyyəti avtomatik tənzimləyir", + "5": "Gƶzlənilən PDF Ɩlçüsü (məsələn, 25MB, 10.8MB, 25KB)" + }, + "submit": "Sıxışdır" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "Bu xüsusiyyət bizim multi-alət səhifəmizdə də mƶvcuddur. ʏlavə xüsusiyyətlər və səhifə-səhifə interfeys üçün sınaqdan keƧirin!" + }, + "pageRemover": { + "title": "Səhifə Silici", + "header": "PDF səhifə silici", + "pagesToDelete": "Silinəcək səhifələr (Səhifə nƶmrələrinin vergüllə ayrılmış siyahısını daxil edin):", + "submit": "Səhifələri Sil", + "placeholder": "(məsələn, 1,2,6 və ya 1-10,15-30)" + }, + "imageToPDF": { + "title": "Şəkli PDF-ə", + "header": "Şəkli PDF-ə", + "submit": "Ƈevir", + "selectLabel": "Şəkil Uyğunluğu SeƧimləri", + "fillPage": "Səhifəni Doldur", + "fitDocumentToImage": "Şəklə Uyğun Səhifə", + "maintainAspectRatio": "Aspekt Nisbətlərini Qoruyun", + "selectText": { + "2": "PDF-i Avtomatik Fırlat", + "3": "Ƈoxsaylı Fayl Məntiqi (Yalnız Birdən Ƈox Şəkil İlə İşləyərkən Aktivdir)", + "4": "Tək Bir PDF-ə Birləşdir", + "5": "Ayrı PDF-lərə Ƈevirin" + } + }, + "PDFToCSV": { + "title": "PDF-i CSV-ə", + "header": "PDF-i CSV-ə", + "prompt": "Ƈıxartmaq Üçün Səhifə SeƧ", + "submit": "Ƈıxart" + }, + "split-by-size-or-count": { + "title": "PDF-i Ɩlçü və ya Sayına gƶrə bƶlün", + "header": "PDF-i Ɩlçü və ya Sayına gƶrə bƶlün", + "type": { + "label": "Bƶlmə nƶvünü seƧin", + "size": "Ɩlçüyə gƶrə", + "pageCount": "Səhifə sayına gƶrə", + "docCount": "Sənədlərin sayına gƶrə" + }, + "value": { + "label": "Dəyəri daxil edin", + "placeholder": "Ɩlçü daxil edin (məsələn, 2MB və ya 3 KB) və ya sayın daxil edin (məsələn, 5)" + }, + "submit": "Təsdiq et" + }, + "printFile": { + "title": "Faylı Ƨap edin", + "header": "Faylı printerdə Ƨap edin", + "selectText": { + "1": "Ƈap etmək üçün Fayl seƧin", + "2": "Printer adını daxil edin" + }, + "submit": "Ƈap et" + }, + "licenses": { + "nav": "Lisenziya", + "title": "3-cü Tərəf Lisenziyalar", + "header": "3-cü Tərəf Lisenziyalar", + "module": "Modul", + "version": "Versiya", + "license": "Lisenziya" + }, + "survey": { + "nav": "Sorğu", + "title": "Stirling-PDF sorğusu", + "description": "Stirling-PDF-də izləmə yoxdur, ona gƶrə də Stirling-PDF-ni təkmilləşdirmək üçün istifadəƧilərimizi eşitmək istəyirik!", + "changes": "Stirling-PDF son sorğudan bəri dəyişdi! Daha Ƨox məlumat əldə etmək üçün lütfən, buradakı blog yazımızı yoxlayın:", + "changes2": "Bu dəyişikliklərlə biz ƶdənişli biznes dəstəyi və maliyyə alırıq", + "please": "Lütfən, Stirling-PDF-nin gələcəyi ilə bağlı məlumat əldə etmək üçün sorğumuzda iştirak edin!", + "disabled": "(Sorğu pop-up nƶvbəti yeniləmələrdə deaktiv ediləcək, lakin səhifənin altında mƶvcuddur)", + "button": "Sorğuda iştirak edin", + "dontShowAgain": "Bir daha gƶstərmə", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Şəkli silin", + "header": "Şəkli silin", + "removeImage": "Şəkli silin", + "submit": "Şəkli silin" + }, + "splitByChapters": { + "title": "PDF-i hissələrə bƶlün", + "header": "PDF-i hissələrə bƶlün", + "bookmarkLevel": "Bookmark Səviyyəsi", + "includeMetadata": "Metadata daxil edin", + "allowDuplicates": "Dublikatlara icazə verin", + "desc": { + "1": "Bu alət fəsil strukturuna əsasən bir PDF faylını Ƨoxlu PDF-lərə bƶlür.", + "2": "Bookmark Səviyyəsi: Bƶlmə üçün istifadə ediləcək Bookmark səviyyəsini seƧin (üst səviyyə üçün 0, ikinci səviyyə üçün 1 və s.).", + "3": "Metadatanı daxil edin: ʏgər yoxlanılıbsa, orijinal PDF-in metadatası hər bir bƶlünmüş PDF-ə daxil ediləcək.", + "4": "Allow Duplicates: Dublikatlara icazə verin: ʏgər işarələnərsə, eyni səhifədə birdən Ƨox bookmarka ayrı-ayrı PDF sənədləri yaratmağa icazə verin." + }, + "submit": "PDF-i Ayır" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Buraxılışlar", + "title": "Buraxılış Qeydləri", + "header": "Buraxılış Qeydləri", + "current": { + "version": "Hazırki Buraxılış" + }, + "note": "Buraxılış Qeydləri yalnız ingiliscə mƶvcuddur" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/bg-BG/translation.json b/frontend/public/locales/bg-BG/translation.json new file mode 100644 index 000000000..17f6a0639 --- /dev/null +++ b/frontend/public/locales/bg-BG/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Размер на ŃˆŃ€ŠøŃ„Ń‚", + "fontName": "Име на ŃˆŃ€ŠøŃ„Ń‚", + "title": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на номера на страници", + "header": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на номера на страници", + "selectText": { + "1": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ PDF файл:", + "2": "Размер на полето", + "3": "ŠŸŠ¾Š·ŠøŃ†ŠøŃ", + "4": "ŠŠ°Ń‡Š°Š»ŠµŠ½ номер", + "5": "Дтраници към номер", + "6": "ŠŸŠµŃ€ŃŠ¾Š½Š°Š»ŠøŠ·ŠøŃ€Š°Š½ текст" + }, + "customTextDesc": "ŠŸŠµŃ€ŃŠ¾Š½Š°Š»ŠøŠ·ŠøŃ€Š°Š½ текст", + "numberPagesDesc": "Кои страници Га номерирате, по поГразбиране 'всички', ŃŃŠŃ‰Š¾ приема 1-5 или 2,5,9 Šø т.н.", + "customNumberDesc": "По поГразбиране е {n}, ŃŃŠŃ‰Š¾ приема 'Дтраница {n} от {total}', 'Текст-{n}', '{filename}-{n}", + "submit": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на номера на страници" + }, + "pdfPrompt": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ PDF(Šø)", + "multiPdfPrompt": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ PDF (2+)", + "multiPdfDropPrompt": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ (или ŠæŠ»ŃŠŠ·Š½ŠµŃ‚Šµ Šø ŠæŃƒŃŠ½ŠµŃ‚Šµ) всички PDF файлове, от които се Š½ŃƒŠ¶Š“аете", + "imgPrompt": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ изображение(я)", + "genericSubmit": "ŠŸŠ¾Š“Š°Š¹Ń‚Šµ", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "ŠŸŃ€ŠµŠ“ŃƒŠæŃ€ŠµŠ¶Š“ŠµŠ½ŠøŠµ: Този процес може Га отнеме Го Š¼ŠøŠ½ŃƒŃ‚а в зависимост от размера на файла", + "pageOrderPrompt": "ŠŸŠµŃ€ŃŠ¾Š½Š°Š»ŠøŠ·ŠøŃ€Š°Š½ реГ на страниците (Š’ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ разГелен със запетаи списък с номера на страници или Ń„ŃƒŠ½ŠŗŃ†ŠøŠø като 2n+1):", + "pageSelectionPrompt": "ŠŸŠµŃ€ŃŠ¾Š½Š°Š»ŠøŠ·ŠøŃ€Š°Š½ избор на страница (Š’ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ списък с номера на страници 1,5,6, разГелени със Š·Š°ŠæŠµŃ‚Š°Ń, или Ń„ŃƒŠ½ŠŗŃ†ŠøŠø като 2n+1) :", + "goToPage": "Давай", + "true": "Š’ŃŃ€Š½Š¾", + "false": "ŠŠµŠ²ŃŃ€Š½Š¾", + "unknown": "ŠŠµŠæŠ¾Š·Š½Š°Ń‚", + "save": "Š”ŃŠŃ…Ń€Š°Š½ŠµŃ‚Šµ", + "saveToBrowser": "Š”ŃŠŃ…Ń€Š°Š½ŃŠ²Š°Š½Šµ в Š±Ń€Š°ŃƒŠ·ŃŠŃ€Š°", + "close": "Затворете", + "filesSelected": "избрани файлове", + "noFavourites": "ŠŃŠ¼Š° Гобавени Š»ŃŽŠ±ŠøŠ¼Šø", + "downloadComplete": "Š”Š²Š°Š»ŃŠ½ŠµŃ‚Š¾ Š·Š°Š²ŃŠŃ€ŃˆŠµŠ½Š¾", + "bored": "ŠžŃ‚ŠµŠŗŃ‡ŠµŠ½Šø сте Га чакате?", + "alphabet": "Азбука", + "downloadPdf": "Š˜Š·Ń‚ŠµŠ³Š»ŠµŃ‚Šµ PDF", + "text": "Текст", + "font": "Шрифт", + "selectFillter": "-- Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ --", + "pageNum": "Брой страница", + "sizes": { + "small": "Малък", + "medium": "ДреГен", + "large": "Š“Š¾Š»ŃŠ¼", + "x-large": "X-Š“Š¾Š»ŃŠ¼" + }, + "error": { + "pdfPassword": "PDF Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ŃŠŃ‚ е с парола Šø или паролата не е преГоставена, или е неправилна", + "_value": "Š“Ń€ŠµŃˆŠŗŠ°", + "sorry": "Š˜Š·Š²ŠøŠ½ŠµŃ‚Šµ за проблема!", + "needHelp": "ŠŃƒŠ¶Š“Š°ŠµŃ‚Šµ се от помощ / ŠžŃ‚ŠŗŃ€ŠøŃ…Ń‚Šµ проблем?", + "contactTip": "Ако все още имате проблеми, не се колебайте Га се ŃŠ²ŃŠŃ€Š¶ŠµŃ‚Šµ с нас за помощ. ŠœŠ¾Š¶ŠµŃ‚Šµ Га изпратите запитване на Š½Š°ŃˆŠ°Ń‚а страница в GitHub или Га се ŃŠ²ŃŠŃ€Š¶ŠµŃ‚Šµ с нас чрез Discord:", + "404": { + "head": "404 - Дтраницата не е намерена | ŠžŠæŠ°! Š”ŠæŃŠŠ½Š°Ń…Š¼Šµ се в коГа!", + "1": "ИзглежГа не можем Га намерим страницата, ŠŗŠ¾ŃŃ‚Š¾ Ń‚ŃŠŃ€ŃŠøŃ‚Šµ.", + "2": "ŠŠµŃ‰Š¾ се Š¾Š±ŃŠŃ€ŠŗŠ°" + }, + "github": "Š˜Š·ŠæŃ€Š°Ń‚ŠµŃ‚Šµ запитване в GitHub", + "showStack": "Покажи ŠæŃ€Š¾ŃŠ»ŠµŠ“ŃŠ²Š°Š½Šµ на стека", + "copyStack": "ŠšŠ¾ŠæŠøŃ€Š°Š½Šµ на ŠæŃ€Š¾ŃŠ»ŠµŠ“ŃŠ²Š°Š½Šµ на стека", + "githubSubmit": "GitHub - Š˜Š·ŠæŃ€Š°Ń‚ŠµŃ‚Šµ запитване", + "discordSubmit": "Discord - Š˜Š·ŠæŃ€Š°Ń‚ŠµŃ‚Šµ запитване за ŠæŠ¾Š“Š“Ń€ŃŠŠ¶ŠŗŠ°" + }, + "delete": "Š˜Š·Ń‚Ń€ŠøŠ¹", + "username": "ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŠŗŠ¾ име", + "password": "ŠŸŠ°Ń€Š¾Š»Š°", + "welcome": "Добре Гошли", + "property": "Двойство", + "black": "Черно", + "white": "Š‘ŃŠ»Š¾", + "red": "Червено", + "green": "Зелено", + "blue": "Диньо", + "custom": "ŠŸŠµŃ€ŃŠ¾Š½Š°Š»ŠøŠ·ŠøŃ€Š°Š½Šµ...", + "WorkInProgess": "Работата е в хоГ, може Га не работи или Га има Š³Ń€ŠµŃˆŠŗŠø, Š¼Š¾Š»Ń, ГоклаГвайте за проблеми!", + "poweredBy": "ЗаГвижван чрез", + "yes": "Да", + "no": "ŠŠµ", + "changedCredsMessage": "Š˜Š“ŠµŠ½Ń‚ŠøŃ„ŠøŠŗŠ°Ń†ŠøŠ¾Š½Š½ŠøŃ‚Šµ Ганни са променени!", + "notAuthenticatedMessage": "ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŃ‚ не е автентикиран.", + "userNotFoundMessage": "ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŃ‚ не е намерен", + "incorrectPasswordMessage": "Š¢ŠµŠŗŃƒŃ‰Š°Ń‚Š° парола е неправилна.", + "usernameExistsMessage": "ŠŠ¾Š²ŠøŃŃ‚ потребител вече ŃŃŠŃ‰ŠµŃŃ‚Š²ŃƒŠ²Š°.", + "invalidUsernameMessage": "ŠŠµŠ²Š°Š»ŠøŠ“Š½Š¾ потребителско име, потребителското име може Га ŃŃŠŠ“ŃŠŃ€Š¶Š° само букви, цифри Šø слеГните специални знаци @._+- или Ń‚Ń€ŃŠ±Š²Š° Га е валиГен имейл аГрес.", + "invalidPasswordMessage": "ŠŸŠ°Ń€Š¾Š»Š°Ń‚Š° не Ń‚Ń€ŃŠ±Š²Š° Га е празна Šø не Ń‚Ń€ŃŠ±Š²Š° Га има интервали в началото или в ŠŗŃ€Š°Ń.", + "confirmPasswordErrorMessage": "ŠŠ¾Š²Š° парола Šø ŠŸŠ¾Ń‚Š²ŃŠŃ€Š¶Š“Š°Š²Š°Š½Šµ на новата парола Ń‚Ń€ŃŠ±Š²Š° Га ŃŃŠŠ²ŠæŠ°Š“Š°Ń‚.", + "deleteCurrentUserMessage": "ŠŠµ може Га се изтрие Š²ŠæŠøŃŠ°Š½ŠøŃ в момента потребител.", + "deleteUsernameExistsMessage": "ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŠŗŠ¾Ń‚Š¾ име не ŃŃŠŃ‰ŠµŃŃ‚Š²ŃƒŠ²Š° Šø не може Га бъГе изтрито.", + "downgradeCurrentUserMessage": "ŠŠµ може Га се понижи Ń€Š¾Š»ŃŃ‚Š° на Ń‚ŠµŠŗŃƒŃ‰ŠøŃ потребител", + "disabledCurrentUserMessage": "Š¢ŠµŠŗŃƒŃ‰ŠøŃŃ‚ потребител не може Га бъГе Геактивиран", + "downgradeCurrentUserLongMessage": "ŠŠµ може Га се понижи Ń€Š¾Š»ŃŃ‚Š° на Ń‚ŠµŠŗŃƒŃ‰ŠøŃ потребител. ДлеГователно Ń‚ŠµŠŗŃƒŃ‰ŠøŃŃ‚ потребител Š½ŃŠ¼Š° Га бъГе показан.", + "userAlreadyExistsOAuthMessage": "ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŃ‚ вече ŃŃŠŃ‰ŠµŃŃ‚Š²ŃƒŠ²Š° като OAuth2 потребител.", + "userAlreadyExistsWebMessage": "ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŃ‚ вече ŃŃŠŃ‰ŠµŃŃ‚Š²ŃƒŠ²Š° като уеб-потребител.", + "oops": "ŠžŠæŠ°Š°!", + "help": "ŠŸŠ¾Š¼Š¾Ń‰", + "goHomepage": "ŠžŃ‚ŠøŠ“ŠµŃ‚Šµ на началната страница", + "joinDiscord": "ŠŸŃ€ŠøŃŃŠŠµŠ“ŠøŠ½ŠµŃ‚Šµ се към Š½Š°ŃˆŠøŃ Discord ŃŃŠŃ€Š²ŃŠŃ€", + "seeDockerHub": "ŠŸŠ¾Š³Š»ŠµŠ“Š½ŠµŃ‚Šµ Docker Hub", + "visitGithub": "ŠŸŠ¾ŃŠµŃ‚ŠµŃ‚Šµ Github Repository", + "donate": "ŠŠ°ŠæŃ€Š°Š²ŠµŃ‚Šµ Гарение", + "color": "Š¦Š²ŃŃ‚", + "sponsor": "Дпонсор", + "info": "Š˜Š½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ", + "pro": "Pro", + "page": "Дтраница", + "pages": "Дтраници", + "loading": "ЗарежГане на...", + "addToDoc": "Š”Š¾Š±Š°Š²ŃŠ½Šµ към Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚", + "reset": "ŠŃƒŠ»ŠøŃ€Š°Š½Šµ", + "apply": "ŠŸŃ€ŠøŠ»Š¾Š¶Šø", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "ŠŸŠ¾Š»ŠøŃ‚ŠøŠŗŠ° за поверителност", + "terms": "ŠŸŃ€Š°Š²ŠøŠ»Š° Šø ŃƒŃŠ»Š¾Š²ŠøŃ", + "accessibility": "Š”Š¾ŃŃ‚ŃŠŠæŠ½Š¾ŃŃ‚", + "cookie": "ŠŸŠ¾Š»ŠøŃ‚ŠøŠŗŠ° за бисквитки", + "impressum": "ŠžŃ‚ŠæŠµŃ‡Š°Ń‚ŃŠŠŗ", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Pipeline ŠœŠµŠ½ŃŽ (Бета)", + "uploadButton": "ŠšŠ°Ń‡Š²Š°Š½Šµ на персонализиран", + "configureButton": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ°", + "defaultOption": "ŠŸŠµŃ€ŃŠ¾Š½Š°Š»ŠøŠ·ŠøŃ€Š°Š½", + "submitButton": "ŠŸŠ¾Š“Š°Š¹Ń‚Šµ", + "help": "Pipeline ŠŸŠ¾Š¼Š¾Ń‰", + "scanHelp": "ŠŸŠ¾Š¼Š¾Ń‰ за сканиране на папки", + "deletePrompt": "Š”ŠøŠ³ŃƒŃ€Š½Šø ли сте, че искате Га изтриете pipeline", + "tags": "автоматизиране,послеГователност,чрез скриптове,пакетен процес", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Pipeline ŠšŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†ŠøŃ", + "pipelineNameLabel": "Pipeline име", + "saveSettings": "Запазете настройките за работа", + "pipelineNamePrompt": "Š’ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ името на pipeline Ń‚ŃƒŠŗ", + "selectOperation": "Š˜Š·Š±Š¾Ń€ на Š¾ŠæŠµŃ€Š°Ń†ŠøŃ", + "addOperationButton": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на Š¾ŠæŠµŃ€Š°Ń†ŠøŃ", + "pipelineHeader": "Pipeline:", + "saveButton": "Š˜Š·Ń‚ŠµŠ³Š»Šø", + "validateButton": "ВалиГирай" + }, + "enterpriseEdition": { + "button": "ŠŠ°ŠæŃ€Š°Š²ŠµŃ‚Šµ наГстройка Го Pro Š²ŠµŃ€ŃŠøŃŃ‚Š°", + "warning": "Тази Ń„ŃƒŠ½ŠŗŃ†ŠøŃ е Š“Š¾ŃŃ‚ŃŠŠæŠ½Š° само за потребители на Pro Š²ŠµŃ€ŃŠøŃŃ‚Š°.", + "yamlAdvert": "Stirling PDF Pro ŠæŠ¾Š“Š“ŃŠŃ€Š¶Š° YAML ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†ŠøŠ¾Š½Š½Šø файлове Šø Š“Ń€ŃƒŠ³Šø SSO Ń„ŃƒŠ½ŠŗŃ†ŠøŠø.", + "ssoAdvert": "Š¢ŃŠŃ€ŃŠøŃ‚Šµ повече Ń„ŃƒŠ½ŠŗŃ†ŠøŠø за ŃƒŠæŃ€Š°Š²Š»ŠµŠ½ŠøŠµ на потребителите? ŠŸŠ¾Š³Š»ŠµŠ“Š½ŠµŃ‚Šµ за Stirling PDF Pro" + }, + "analytics": { + "title": "Š˜ŃŠŗŠ°Ń‚Šµ ли Га поГобрите Stirling PDF?", + "paragraph1": "Stirling PDF Š²ŠŗŠ»ŃŽŃ‡Š²Š° анализи, за Га ни помогне Га поГобрим ŠæŃ€Š¾Š“ŃƒŠŗŃ‚Š°. ŠŠøŠµ не ŠæŃ€Š¾ŃŠ»ŠµŠ“ŃŠ²Š°Š¼Šµ лична ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ или ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ на файлове.", + "paragraph2": "ŠœŠ¾Š»Ń, обмислете Š²ŃŠŠ·Š¼Š¾Š¶Š½Š¾ŃŃ‚та за анализ, за ​​Га помогнете на Stirling-PDF Га расте Šø Га ни позволи Га разберем по-Гобре Š½Š°ŃˆŠøŃ‚е потребители.", + "enable": "Активиране на анализа", + "disable": "Деактивиране на анализа", + "settings": "ŠœŠ¾Š¶ŠµŃ‚Šµ Га промените настройките за анализ във config/settings.yml файла" + }, + "navbar": { + "favorite": "Š›ŃŽŠ±ŠøŠ¼Šø", + "recent": "ŠŠ¾Š²Šø Šø наскоро Š°ŠŗŃ‚ŃƒŠ°Š»ŠøŠ·ŠøŃ€Š°Š½Šø", + "darkmode": "Тъмна тема", + "language": "Езици", + "settings": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø", + "allTools": "Š˜Š½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚Šø", + "multiTool": "ŠœŃƒŠ»Ń‚Šø ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚Šø", + "search": "Š¢ŃŠŃ€ŃŠµŠ½Šµ", + "sections": { + "organize": "ŠžŃ€Š³Š°Š½ŠøŠ·ŠøŃ€Š°Š¹Ń‚Šµ", + "convertTo": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ в PDF", + "convertFrom": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ от PDF", + "security": "ПоГписване Šø ŃŠøŠ³ŃƒŃ€Š½Š¾ŃŃ‚", + "advance": "Š Š°Š·ŃˆŠøŃ€ŠµŠ½Š¾", + "edit": "ŠŸŃ€ŠµŠ³Š»ŠµŠ“ Šø реГактиране", + "popular": "ŠŸŠ¾ŠæŃƒŠ»ŃŃ€Š½Šø" + } + }, + "settings": { + "title": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø", + "update": "ŠŠ°Š»ŠøŃ‡Š½Š° Š°ŠŗŃ‚ŃƒŠ°Š»ŠøŠ·Š°Ń†ŠøŃ", + "updateAvailable": "{0} е Ń‚ŠµŠŗŃƒŃ‰Š°Ń‚Š° инсталирана Š²ŠµŃ€ŃŠøŃ. ŠŠ°Š»ŠøŃ‡Š½Š° е нова Š²ŠµŃ€ŃŠøŃ ({1}).", + "appVersion": "Š’ŠµŃ€ŃŠøŃ на приложението:", + "downloadOption": { + "title": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ Š¾ŠæŃ†ŠøŃ за ŠøŠ·Ń‚ŠµŠ³Š»ŃŠ½Šµ (за ŠøŠ·Ń‚ŠµŠ³Š»ŃŠ½ŠøŃ на еГин файл без Га е архивиран):", + "1": "ŠžŃ‚Š²Š°Ń€ŃŠ½Šµ в ŃŃŠŃ‰ŠøŃ прозорец", + "2": "ŠžŃ‚Š²Š°Ń€ŃŠ½Šµ в нов прозорец", + "3": "Š˜Š·Ń‚ŠµŠ³Š»Šø файл" + }, + "zipThreshold": "Архивирайте файловете, когато Š±Ń€Š¾ŃŃ‚ на изтеглените файлове наГвишава", + "signOut": "Š˜Š·Ń…Š¾Š“", + "accountSettings": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø на Š°ŠŗŠ°ŃƒŠ½Ń‚а", + "bored": { + "help": "Активира игра с великГенски ŃŠ¹Ń†Š°" + }, + "cacheInputs": { + "name": "Запазете Š²ŃŠŠ²ŠµŠ“ените Ń„Š¾Ń€Š¼ŃƒŠ»ŃŃ€Šø", + "help": "Активирайте за ŃŃŠŃ…Ń€Š°Š½ŃŠ²Š°Š½Šµ на ŠæŃ€ŠµŠ“ŠøŃˆŠ½Šø използвани въвеГени Ганни за Š±ŃŠŠ“ещи ŠøŠ·ŠæŃŠŠ»Š½ŠµŠ½ŠøŃ" + } + }, + "changeCreds": { + "title": "ŠŸŃ€Š¾Š¼ŃŠ½Š° на иГентификационните Ганни", + "header": "ŠŠŗŃ‚ŃƒŠ°Š»ŠøŠ·ŠøŃ€Š°Š¹Ń‚Šµ Ганните за Š°ŠŗŠ°ŃƒŠ½Ń‚а си", + "changePassword": "Š˜Š·ŠæŠ¾Š»Š·Š²Š°Ń‚Šµ иГентификационни Ганни за вхоГ по поГразбиране. ŠœŠ¾Š»Ń, Š²ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ нова парола", + "newUsername": "ŠŠ¾Š²Š¾ потребителско име", + "oldPassword": "Š¢ŠµŠŗŃƒŃ‰Š° парола", + "newPassword": "ŠŠ¾Š²Š° парола", + "confirmNewPassword": "ŠŸŠ¾Š“Ń‚Š²ŃŠŃ€Š“ŠµŃ‚Šµ новата парола", + "submit": "Š˜Š·ŠæŃ€Š°Ń‰Š°Š½Šµ на промените" + }, + "account": { + "title": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø на Š°ŠŗŠ°ŃƒŠ½Ń‚а", + "accountSettings": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø на Š°ŠŗŠ°ŃƒŠ½Ń‚а", + "adminSettings": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø на аГминистратора - ŠŸŃ€ŠµŠ³Š»ŠµŠ“ Šø Š“Š¾Š±Š°Š²ŃŠ½Šµ на потребители", + "userControlSettings": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø за потребителски контрол", + "changeUsername": "ŠŸŃ€Š¾Š¼ŠµŠ½Šø потребител", + "newUsername": "ŠŠ¾Š²Š¾ потребителско име", + "password": "ŠŸŠ°Ń€Š¾Š»Š° за ŠæŠ¾Ń‚Š²ŃŠŃ€Š¶Š“ŠµŠ½ŠøŠµ", + "oldPassword": "Дтара парола", + "newPassword": "ŠŠ¾Š²Š° парола", + "changePassword": "ŠŸŃ€Š¾Š¼ŠµŠ½Šø паролата", + "confirmNewPassword": "ŠŸŠ¾Ń‚Š²ŃŠŃ€Š“ŠµŃ‚Šµ новата парола", + "signOut": "Š˜Š·Ń…Š¾Š“", + "yourApiKey": "Š’Š°ŃˆŠøŃŃ‚ API ŠŗŠ»ŃŽŃ‡", + "syncTitle": "Динхронизиране на настройките на Š±Ń€Š°ŃƒŠ·ŃŠŃ€Š° с Š°ŠŗŠ°ŃƒŠ½Ń‚Š°", + "settingsCompare": "Š”Ń€Š°Š²Š½ŃŠ²Š°Š½Šµ на настройките:", + "property": "Двойство", + "webBrowserSettings": "Уеб-Š±Ń€Š°ŃƒŠ·ŃŠŃ€ настройки", + "syncToBrowser": "Динхронизиране на Š°ŠŗŠ°ŃƒŠ½Ń‚ -> Š‘Ń€Š°ŃƒŠ·ŃŠŃ€", + "syncToAccount": "Динхронизиране на Š°ŠŗŠ°ŃƒŠ½Ń‚ <- Š‘Ń€Š°ŃƒŠ·ŃŠŃ€" + }, + "adminUserSettings": { + "title": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø за потребителски контрол", + "header": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø за аГминистраторски потребителски контрол", + "admin": "АГминистратор", + "user": "ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»", + "addUser": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на нов потребител", + "deleteUser": "Š˜Š·Ń‚Ń€ŠøŠ²Š°Š½Šµ на потребител", + "confirmDeleteUser": "Š¢Ń€ŃŠ±Š²Š° ли ŠæŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŃ‚ Га бъГе изтрит?", + "confirmChangeUserStatus": "Š¢Ń€ŃŠ±Š²Š° ли ŠæŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŃ‚ Га бъГе Геактивиран/активиран?", + "usernameInfo": "ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŠŗŠ¾Ń‚Š¾ име може Га ŃŃŠŠ“ŃŠŃ€Š¶Š° само букви, цифри Šø слеГните специални символи @._+- или Ń‚Ń€ŃŠ±Š²Š° Га е валиГен имейл аГрес.", + "roles": "Роли", + "role": "Š Š¾Š»Ń", + "actions": "Š”ŠµŠ¹ŃŃ‚Š²ŠøŃ", + "apiUser": "ŠžŠ³Ń€Š°Š½ŠøŃ‡ŠµŠ½ API потребител", + "extraApiUser": "Š”Š¾ŠæŃŠŠ»Š½ŠøŃ‚ŠµŠ»ŠµŠ½ ограничен API потребител", + "webOnlyUser": "Дамо за уеб-потребител", + "demoUser": "Демо потребител (без персонализирани настройки)", + "internalApiUser": "Š’ŃŠŃ‚Ń€ŠµŃˆŠµŠ½ API потребител", + "forceChange": "ŠŸŃ€ŠøŠ½ŃƒŠ“ŠµŃ‚Šµ ŠæŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»Ń Га промени потребителското име/парола при влизане", + "submit": "Š”ŃŠŃ…Ń€Š°Š½ŠµŃ‚Šµ ŠæŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»Ń", + "changeUserRole": "ŠŸŃ€Š¾Š¼ŃŠ½Š° на Ń€Š¾Š»ŃŃ‚Š° на ŠæŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»Ń", + "authenticated": "УГостоверен", + "editOwnProfil": "РеГактиране на собствен профил", + "enabledUser": "активиран потребител", + "disabledUser": "Геактивиран потребител", + "activeUsers": "Активни потребители:", + "disabledUsers": "Деактивирани потребители:", + "totalUsers": "ŠžŠ±Ń‰Š¾ потребители:", + "lastRequest": "ПослеГна Š·Š°ŃŠ²ŠŗŠ°", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Š˜Š¼ŠæŠ¾Ń€Ń‚/Експорт на база Ганни", + "header": "Š˜Š¼ŠæŠ¾Ń€Ń‚/Експорт на база Ганни", + "fileName": "Име на файл", + "creationDate": "Дата на съзГаване", + "fileSize": "Размер на файла", + "deleteBackupFile": "Š˜Š·Ń‚Ń€ŠøŠ²Š°Š½Šµ на архивен файл", + "importBackupFile": "Š˜Š¼ŠæŠ¾Ń€Ń‚ŠøŃ€Š°Š½Šµ на архивен файл", + "createBackupFile": "ДъзГаване на файл с резервно копие", + "downloadBackupFile": "Š˜Š·Ń‚ŠµŠ³Š»ŠµŃ‚Šµ архивен файл", + "info_1": "ŠšŠ¾Š³Š°Ń‚Š¾ импортирате Ганни, е от Ń€ŠµŃˆŠ°Š²Š°Ń‰Š¾ значение Га Š¾ŃŠøŠ³ŃƒŃ€ŠøŃ‚е правилната ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Š°. Ако не сте ŃŠøŠ³ŃƒŃ€Š½Šø в това, което правите, ŠæŠ¾Ń‚ŃŠŃ€ŃŠµŃ‚Šµ ŃŃŠŠ²ŠµŃ‚ Šø поГкрепа от професионалист. Š“Ń€ŠµŃˆŠŗŠ° в ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Š°Ń‚Š° може Га причини неизправност на приложението, Š²ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŠµŠ»Š½Š¾ пълна Š½ŠµŠ²ŃŠŠ·Š¼Š¾Š¶Š½Š¾ŃŃ‚ за стартиране на приложението.", + "info_2": "Š˜Š¼ŠµŃ‚Š¾ на файла Š½ŃŠ¼Š° значение при качване. ДлеГ това ще бъГе ŠæŃ€ŠµŠøŠ¼ŠµŠ½ŃƒŠ²Š°Š½, за Га слеГва формата backup_user_yyyyMMddHHmm.sql, Š¾ŃŠøŠ³ŃƒŃ€ŃŠ²Š°Š¹ŠŗŠø послеГователна ŠŗŠ¾Š½Š²ŠµŠ½Ń†ŠøŃ за именуване.", + "submit": "Š˜Š¼ŠæŠ¾Ń€Ń‚ŠøŃ€Š°Š½Šµ на резервно копие", + "importIntoDatabaseSuccessed": "Š˜Š¼ŠæŠ¾Ń€Ń‚ŠøŃ€Š°Š½ŠµŃ‚Š¾ в базата Ганни бе успешно", + "backupCreated": "Успешно архивиране на базата Ганни", + "fileNotFound": "Š¤Š°Š¹Š»ŃŠŃ‚ не е намерен", + "fileNullOrEmpty": "Š¤Š°Š¹Š»ŃŠŃ‚ не Ń‚Ń€ŃŠ±Š²Š° Га е нулев или празен", + "failedImportFile": "ŠŠµŃƒŃŠæŠµŃˆŠ½Š¾ импортиране на файл", + "notSupported": "Тази Ń„ŃƒŠ½ŠŗŃ†ŠøŃ не е налична за Š²Š°ŃˆŠ°Ń‚а Š²Ń€ŃŠŠ·ŠŗŠ° с база Ганни." + }, + "session": { + "expired": "Š’Š°ŃˆŠ°Ń‚Š° ŃŠµŃŠøŃ е изтекла. ŠœŠ¾Š»Ń, опреснете страницата Šø опитайте отново.", + "refreshPage": "ŠŸŃ€ŠµŠ·Š°Ń€ŠµŠ¶Š“Š°Š½Šµ на страницата" + }, + "home": { + "desc": "Š’Š°ŃˆŠµŃ‚Š¾ локално хоствано обслужване на еГно Š¼ŃŃŃ‚о за всички ваши PDF нужГи.", + "searchBar": "Š¢ŃŠŃ€ŃŠµŠ½Šµ на Ń„ŃƒŠ½ŠŗŃ†ŠøŠø...", + "viewPdf": { + "title": "ŠŸŃ€ŠµŠ³Š»ŠµŠ“/РеГактиране PDF", + "desc": "ŠŸŃ€ŠµŠ³Š»ŠµŠ¶Š“Š°Š¹Ń‚Šµ, коментирайте, Š“Š¾Š±Š°Š²ŃŠ¹Ń‚Šµ текст или ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ" + }, + "setFavorites": "ЗаГаване на преГпочитани", + "hideFavorites": "Дкриване на преГпочитани", + "showFavorites": "Покажи преГпочитани", + "legacyHomepage": "Дтара начална страница", + "newHomePage": "ŠžŠæŠøŃ‚Š°Š¹Ń‚Šµ новата ни начална страница!", + "alphabetical": "По Š°Š·Š±ŃƒŃ‡ŠµŠ½ реГ", + "globalPopularity": "Дветовна ŠæŠ¾ŠæŃƒŠ»ŃŃ€Š½Š¾ŃŃ‚", + "sortBy": "Дортиране по:", + "multiTool": { + "title": "PDF ŠœŃƒŠ»Ń‚Šø ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚", + "desc": "ŠžŠ±ŠµŠ“ŠøŠ½ŃŠ²Š°Š½Šµ, Š·Š°Š²ŃŠŃ€Ń‚Š°Š½Šµ, пренарежГане Šø премахване на страници" + }, + "merge": { + "title": "ŠžŠ±ŠµŠ“ŠøŠ½ŃŠ²Š°Š½Šµ", + "desc": "Лесно обеГинете множество PDF файлове в еГин." + }, + "split": { + "title": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ", + "desc": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ на PDF файлове на множество Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šø" + }, + "rotate": { + "title": "Š—Š°Š²ŃŠŃ€Ń‚Š°Š½Šµ", + "desc": "Лесно Š·Š°Š²ŃŠŃ€Ń‚ете Š²Š°ŃˆŠøŃ‚е PDF файлове." + }, + "imageToPdf": { + "title": "Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ към PDF", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ на изображение (PNG, JPEG, GIF) към PDF." + }, + "pdfToImage": { + "title": "PDF към изображение", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ на PDF към изображение. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "ŠžŃ€Š³Š°Š½ŠøŠ·ŠøŃ€Š°Š½Šµ", + "desc": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ/пренарежГане на страници към произволен реГ" + }, + "addImage": { + "title": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на изображение", + "desc": "Š”Š¾Š±Š°Š²Ń изображение към заГаГено Š¼ŃŃŃ‚о към PDF файла" + }, + "watermark": { + "title": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на воГен знак", + "desc": "Добавете персонализиран воГен знак към Š²Š°ŃˆŠøŃ PDF Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚." + }, + "permissions": { + "title": "ŠŸŃ€Š¾Š¼ŃŠ½Š° на правата", + "desc": "ŠŸŃ€Š¾Š¼ŠµŠ½ŠµŃ‚Šµ правата на Š²Š°ŃˆŠøŃ PDF Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚" + }, + "removePages": { + "title": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ", + "desc": "Š˜Š·Ń‚Ń€ŠøŠ¹Ń‚Šµ нежеланите страници от Š²Š°ŃˆŠøŃ PDF Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚." + }, + "addPassword": { + "title": "Добавете парола", + "desc": "Шифровайте Š²Š°ŃˆŠøŃ PDF Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ с парола." + }, + "removePassword": { + "title": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на парола", + "desc": "ŠŸŃ€ŠµŠ¼Š°Ń…Š½ŠµŃ‚Šµ защитата с парола от Š²Š°ŃˆŠøŃ PDF Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚." + }, + "compressPdfs": { + "title": "ŠšŠ¾Š¼ŠæŃ€ŠµŃŠøŃ€Š°Š½Šµ", + "desc": "ŠšŠ¾Š¼ŠæŃ€ŠµŃŠøŃ€Š°Š¹Ń‚Šµ PDF файлове, за Га намалите размера на файла." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "ŠŸŃ€Š¾Š¼ŃŠ½Š° на метаГанни", + "desc": "ŠŸŃ€Š¾Š¼ŃŠ½Š°/ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ/Š”Š¾Š±Š°Š²ŃŠ½Šµ на метаГанни от PDF Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚" + }, + "fileToPDF": { + "title": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ на файл към PDF", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ почти всеки файл към PDF (DOCX, PNG, XLS, PPT, TXT Šø Š“Ń€ŃƒŠ³Šø)" + }, + "ocr": { + "title": "OCR / ŠŸŠ¾Ń‡ŠøŃŃ‚Š²Š°Ń‰Šø ŃŠŗŠ°Š½ŠøŃ€Š°Š½ŠøŃ", + "desc": "ŠŸŠ¾Ń‡ŠøŃŃ‚Š²Š°, сканира Šø открива текст от ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ в PDF Šø го Š“Š¾Š±Š°Š²Ń отново като текст." + }, + "extractImages": { + "title": "Š˜Š·Š²Š»ŠøŃ‡Š°Š½Šµ на ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "desc": "Š˜Š·Š²Š»ŠøŃ‡Š° всички ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ от PDF Šø ги записва към архив" + }, + "pdfToPDFA": { + "title": "PDF към PDF/A", + "desc": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŠøŃ€Š°Š¹Ń‚Šµ PDF към PDF/A за Š“ŃŠŠ»Š³Š¾ŃŃ€Š¾Ń‡Š½Š¾ ŃŃŠŃ…Ń€Š°Š½ŠµŠ½ŠøŠµ" + }, + "PDFToWord": { + "title": "PDF към Word", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ на PDF към Word формати (DOC, DOCX Šø ODT)" + }, + "PDFToPresentation": { + "title": "PDF към ŠæŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†ŠøŃ", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ на PDF във формати за ŠæŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†ŠøŃ (PPT, PPTX Šø ODP)" + }, + "PDFToText": { + "title": "PDF към RTF (Текст)", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ PDF към Text или RTF формат" + }, + "PDFToHTML": { + "title": "PDF към HTML", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ PDF към HTML формат" + }, + "PDFToXML": { + "title": "PDF към XML", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ на PDF към XML формат" + }, + "ScannerImageSplit": { + "title": "ŠžŃ‚ŠŗŃ€ŠøŠ²Š°Š½Šµ/Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ на сканирани снимки", + "desc": "Š Š°Š·Š“ŠµŠ»Ń множество снимки от еГна снимка/PDF" + }, + "sign": { + "title": "ŠŸŠ¾Š“ŠæŠøŃˆŠµŃ‚Šµ", + "desc": "Š”Š¾Š±Š°Š²Ń поГпис към PDF чрез Ń€ŠøŃŃƒŠ½ŠŗŠ°, текст или изображение" + }, + "flatten": { + "title": "Š˜Š·Ń€Š°Š²Š½ŃŠ²Š°Š½Šµ", + "desc": "ŠŸŃ€ŠµŠ¼Š°Ń…Š½ŠµŃ‚Šµ всички интерактивни елементи Šø Ń„Š¾Ń€Š¼ŃƒŠ»ŃŃ€Šø от PDF" + }, + "repair": { + "title": "ŠŸŠ¾ŠæŃ€Š°Š²Šø", + "desc": "ŠžŠæŠøŃ‚Š²Š° се Га поправи повреГен PDF" + }, + "removeBlanks": { + "title": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на празни страници", + "desc": "ŠžŃ‚ŠŗŃ€ŠøŠ²Š° Šø премахва празни страници от Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚" + }, + "removeAnnotations": { + "title": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на анотации", + "desc": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š° всички коментари/анотации от PDF" + }, + "compare": { + "title": "Дравнете", + "desc": "Š”Ń€Š°Š²Š½ŃŠ²Š° Šø показва разликите межГу 2 PDF Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°" + }, + "certSign": { + "title": "ŠŸŠ¾Š“ŠæŠøŃˆŠµŃ‚Šµ със сертификат", + "desc": "ПоГписва PDF със сертификат/ŠŗŠ»ŃŽŃ‡ (PEM/P12)" + }, + "removeCertSign": { + "title": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на знака за сертификат", + "desc": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на поГпис на сертификат от PDF" + }, + "pageLayout": { + "title": "ŠžŃ„Š¾Ń€Š¼Š»ŠµŠ½ŠøŠµ с Š½ŃŠŗŠ¾Š»ŠŗŠ¾ страници", + "desc": "Длейте Š½ŃŠŗŠ¾Š»ŠŗŠ¾ страници от PDF Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ в еГна страница" + }, + "scalePages": { + "title": "ŠšŠ¾Ń€ŠøŠ³ŠøŃ€Š°Š¹Ń‚Šµ размера/мащаба на страницата", + "desc": "ŠŸŃ€Š¾Š¼ŃŠ½Š° на размера/мащаба на страница Šø/или нейното ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ." + }, + "pipeline": { + "title": "Pipeline (Š Š°Š·ŃˆŠøŃ€ŠµŠ½Š¾)", + "desc": "Š˜Š·ŠæŃŠŠ»Š½ŃŠ²Š°Š¹Ń‚Šµ множество Š“ŠµŠ¹ŃŃ‚Š²ŠøŃ Š²ŃŠŃ€Ń…Ńƒ PDF файлове чрез Гефиниране на конвейерни скриптове" + }, + "add-page-numbers": { + "title": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на номера на страници", + "desc": "Добавете номера на страници в Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ на опреГелено Š¼ŃŃŃ‚о" + }, + "auto-rename": { + "title": "Автоматично ŠæŃ€ŠµŠøŠ¼ŠµŠ½ŃƒŠ²Š°Š½Šµ на PDF файл", + "desc": "Автоматично ŠæŃ€ŠµŠøŠ¼ŠµŠ½ŃƒŠ²Š° PDF файл въз основа на откритата му заглавка" + }, + "adjust-contrast": { + "title": "ŠšŠ¾Ń€ŠøŠ³ŠøŃ€Š°Š½Šµ на цветове/контраст", + "desc": "ŠšŠ¾Ń€ŠøŠ³ŠøŃ€Š°Š½Šµ на контраста, наситеността Šø ŃŃ€ŠŗŠ¾ŃŃ‚Ń‚Š° на PDF" + }, + "crop": { + "title": "Š˜Š·Ń€ŃŠ·Š²Š°Š½Šµ на PDF", + "desc": "Š˜Š·Ń€ŠµŠ¶ŠµŃ‚Šµ PDF, за Га намалите размера му (ŠæŠ¾Š“Š“ŃŠŃ€Š¶Š° текст!)" + }, + "autoSplitPDF": { + "title": "Автоматично Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ на страници", + "desc": "Автоматично Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ на сканиран PDF файл с QR коГ за Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ на физически сканирани страници" + }, + "sanitizePdf": { + "title": "ŠžŠ±ŠµŠ·Š·Š°Ń€Š°Š·ŃŠ²Š°Š½Šµ", + "desc": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на скриптове Šø Š“Ń€ŃƒŠ³Šø елементи от PDF файлове" + }, + "URLToPDF": { + "title": "URL/уеб-сайт към PDF", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š° всеки http(s) URL към PDF" + }, + "HTMLToPDF": { + "title": "HTML към PDF", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š° всеки HTML файл или архив към PDF" + }, + "MarkdownToPDF": { + "title": "Markdown към PDF", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š° всеки Markdown файл към PDF" + }, + "PDFToMarkdown": { + "title": "PDF към Markdown", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š° всеки PDF файл в Markdown" + }, + "getPdfInfo": { + "title": "Вземете ЦЯЛАТА ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ от PDF", + "desc": "Взима Š²ŃŃŠŗŠ° възможна ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ от PDF файлове" + }, + "extractPage": { + "title": "Š˜Š·Š²Š»ŠøŃ‡Š°Š½Šµ на страница(Šø)", + "desc": "Š˜Š·Š²Š»ŠøŃ‡Š° избрани страници от PDF" + }, + "PdfToSinglePage": { + "title": "PDF към еГна Š³Š¾Š»ŃŠ¼Š° страница", + "desc": "ŠžŠ±ŠµŠ“ŠøŠ½ŃŠ²Š° всички PDF страници в еГна Š³Š¾Š»ŃŠ¼Š° страница" + }, + "showJS": { + "title": "Показване на Javascript", + "desc": "Š¢ŃŠŃ€ŃŠø Šø показва всеки JS, инжектиран в PDF" + }, + "autoRedact": { + "title": "Автоматично реГактиране", + "desc": "Автоматично реГактира (Š·Š°Ń‡ŠµŃ€Š½ŃŠ²Š°) текст в PDF въз основа на въвеГен текст" + }, + "redact": { + "title": "Š ŃŠŃ‡Š½Š¾ реГактиране", + "desc": "РеГактиране на PDF файл въз основа на избран текст, Š½Š°Ń€ŠøŃŃƒŠ²Š°Š½Šø форми Šø/или избрана страница(Šø)" + }, + "tableExtraxt": { + "title": "PDF към CSV", + "desc": "Š˜Š·Š²Š»ŠøŃ‡Š° таблици от PDF, като ги конвертира в CSV" + }, + "autoSizeSplitPDF": { + "title": "Автоматично Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ по размер/брой", + "desc": "РазГелете еГин PDF на множество Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šø въз основа на размер, брой страници или брой Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šø" + }, + "overlay-pdfs": { + "title": "ŠŠ°ŃŠ»Š°Š³Š²Š°Š½Šµ PDF-Šø", + "desc": "ŠŠ°ŃŠ»Š°Š³Š²Š° PDF файлове Š²ŃŠŃ€Ń…Ńƒ Š“Ń€ŃƒŠ³ PDF" + }, + "split-by-sections": { + "title": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ на PDF по секции", + "desc": "РазГелете Š²ŃŃŠŗŠ° страница от PDF на по-малки хоризонтални Šø вертикални секции" + }, + "AddStampRequest": { + "title": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на печат към PDF", + "desc": "Добавете текст или Гобавете печати с ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ на опреГелени места" + }, + "removeImagePdf": { + "title": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на изображение", + "desc": "ŠŸŃ€ŠµŠ¼Š°Ń…Š½ŠµŃ‚Šµ изображението от PDF, за Га намалите размера на файла" + }, + "splitPdfByChapters": { + "title": "РазГелете PDF по глави", + "desc": "РазГелете PDF на множество файлове въз основа на неговата ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Š° на глави." + }, + "validateSignature": { + "title": "ВалиГиране на PDF поГпис", + "desc": "ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° на цифрови поГписи Šø сертификати в PDF Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šø" + }, + "replaceColorPdf": { + "title": "Š—Š°Š¼ŃŠ½Š° Šø Š¾Š±Ń€ŃŠŃ‰Š°Š½Šµ на Ń†Š²ŃŃ‚", + "desc": "Заменете цвета на текста Šø фона в PDF Šø Š¾Š±ŃŠŃ€Š½ŠµŃ‚Šµ ŠæŃŠŠ»Š½ŠøŃ Ń†Š²ŃŃ‚ на PDF, за Га намалите размера на файла" + } + }, + "viewPdf": { + "tags": "преглеГ,четене,анотиране,текст,изображение", + "title": "ŠŸŃ€ŠµŠ³Š»ŠµŠ“/РеГактиране на PDF", + "header": "ŠŸŃ€ŠµŠ³Š»ŠµŠ“ на PDF" + }, + "multiTool": { + "tags": "ŠœŃƒŠ»Ń‚ŠøŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚,ŠœŃƒŠ»Ń‚Šø операции,UI,плъзгане с щракване,потребителска част,страна на клиента,интерактивен,Š½ŠµŃ€Š°Š·Ń€ŠµŃˆŠøŠ¼,преместване", + "title": "PDF ŠœŃƒŠ»Ń‚Šø ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚", + "header": "PDF ŠœŃƒŠ»Ń‚Šø ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚", + "uploadPrompts": "Име на файл", + "selectAll": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ всички", + "deselectAll": "ŠžŃ‚Š¼ŃŠ½Š° на избора на всички", + "selectPages": "Š˜Š·Š±Š¾Ń€ на страница", + "selectedPages": "Š˜Š·Š±Ń€Š°Š½Šø страници", + "page": "Дтраница", + "deleteSelected": "Š˜Š·Ń‚Ń€ŠøŠ²Š°Š½Šµ на избраното", + "downloadAll": "Експорт", + "downloadSelected": "Š˜Š·Š±Ń€Š°Š½Š¾ за експортиране", + "insertPageBreak": "Š’Š¼ŃŠŠŗŠ²Š°Š½Šµ на ŠæŃ€ŠµŠŗŃŠŃŠ²Š°Š½Šµ на страница", + "addFile": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на файл", + "rotateLeft": "Š—Š°Š²ŃŠŃ€Ń‚ŠµŃ‚Šµ Š½Š°Š»ŃŠ²Š¾", + "rotateRight": "Š—Š°Š²ŃŠŃ€Ń‚ŠµŃ‚Šµ Š½Š°Š“ŃŃŠ½Š¾", + "split": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ", + "moveLeft": "ŠŸŃ€ŠµŠ¼ŠµŃŃ‚Š²Š°Š½Šµ Š½Š°Š»ŃŠ²Š¾", + "moveRight": "ŠŸŃ€ŠµŠ¼ŠµŃŃ‚Š²Š°Š½Šµ Š½Š°Š“ŃŃŠ½Š¾", + "delete": "Š˜Š·Ń‚Ń€ŠøŠ¹", + "dragDropMessage": "Š˜Š·Š±Ń€Š°Š½(Šø) страница(/Šø)", + "undo": "ŠžŃ‚Š¼ŃŠ½Š° на", + "redo": "ŠŸŠ¾Š²Ń‚Š¾Ń€Šø" + }, + "merge": { + "tags": "сливане,операции на страници,аГминистраторска зона,от страна на ŃŃŠŃ€Š²ŃŠŃ€Š°", + "title": "ŠžŠ±ŠµŠ“ŠøŠ½ŃŠ²Š°Š½Šµ", + "header": "ŠžŠ±ŠµŠ“ŠøŠ½ŃŠ²Š°Š½Šµ на множество PDF файлове (2+)", + "sortByName": "Дортиране по име", + "sortByDate": "Дортиране по Гата", + "removeCertSign": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на Ń†ŠøŃ„Ń€Š¾Š²ŠøŃ поГпис в Š¾Š±ŠµŠ“ŠøŠ½ŠµŠ½ŠøŃ файл?", + "submit": "ŠžŠ±ŠµŠ“ŠøŠ½ŃŠ²Š°Š½Šµ" + }, + "split": { + "tags": "ŠžŠæŠµŃ€Š°Ń†ŠøŠø на страницата,Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ,ŠœŠ½Š¾Š¶ŠµŃŃ‚Š²Š¾ страници,ŠøŠ·Ń€ŃŠ·Š²Š°Š½Šµ,ŃŃŠŃ€Š²ŃŠŃ€Š½Š° страна", + "title": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ на PDF", + "header": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ на PDF", + "desc": { + "1": "Числата, които избирате, са номера на страницата, на ŠŗŠ¾ŃŃ‚о искате Га направите Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ", + "2": "Така че избирането на 1,3,7-9 ще разГели Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ от 10 страници на 6 отГелни PDF файла с:", + "3": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #1: Дтраница 1", + "4": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #2: Дтраница 2 Šø 3", + "5": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #3: Дтраница 4, 5, 6 Šø 7", + "6": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #4: Дтраница 8", + "7": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #5: Дтраница 9", + "8": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #6: Дтраница 10" + }, + "splitPages": "Š’ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ страници за Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ:", + "submit": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ" + }, + "rotate": { + "tags": "от страната на ŃŃŠŃ€Š²ŃŠŃ€Š°", + "title": "Š—Š°Š²ŃŠŃ€Ń‚Š°Š½Šµ на PDF", + "header": "Š—Š°Š²ŃŠŃ€Ń‚Š°Š½Šµ на PDF", + "selectAngle": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ ъгъл на Š²ŃŠŃ€Ń‚ене (кратно на 90 Š³Ń€Š°Š“ŃƒŃŠ°):", + "submit": "Š—Š°Š²ŃŠŃ€Ń‚Š°Š½Šµ" + }, + "imageToPdf": { + "tags": "ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ,img,jpg,изображение,снимка" + }, + "pdfToImage": { + "tags": "ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ,img,jpg,изображение,снимка", + "title": "PDF към Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ", + "header": "PDF към Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ", + "selectText": "Формат на изображението", + "singleOrMultiple": "Тип Ń€ŠµŠ·ŃƒŠ»Ń‚Š°Ń‚ от страница към изображение", + "single": "ЕГинично Š³Š¾Š»ŃŠ¼Š¾ изображение комбиниране на всички страници", + "multi": "ŠœŠ½Š¾Š¶ŠµŃŃ‚Š²Š¾ ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ, по еГно изображение на страница", + "colorType": "Тип Ń†Š²ŃŃ‚", + "color": "Š¦Š²ŃŃ‚", + "grey": "Дкала на сивото", + "blackwhite": "Черно Šø Š±ŃŠ»Š¾ (може Га Š·Š°Š³ŃƒŠ±ŠøŃ‚е Ганни!)", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ", + "info": "Python не е инсталиран. Изисква се за конвертиране на WebP.", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "pdfOrganiser": { + "tags": "Гуплекс,четно,нечетно,сортиране,преместване", + "title": "ŠžŃ€Š³Š°Š½ŠøŠ·Š°Ń‚Š¾Ń€ на страници", + "header": "ŠžŃ€Š³Š°Š½ŠøŠ·Š°Ń‚Š¾Ń€ на PDF страници", + "submit": "ŠŸŃ€ŠµŠ½Š°Ń€ŠµŠ¶Š“Š°Š½Šµ на страниците", + "mode": { + "_value": "Режим", + "1": "ŠŸŠµŃ€ŃŠ¾Š½Š°Š»ŠøŠ·ŠøŃ€Š°Š½ реГ на страниците", + "2": "ŠžŠ±ŃŠŃ€Š½Š°Ń‚ реГ", + "3": "Š”Š²ŃƒŃŃ‚Ń€Š°Š½Š½Š¾ сортиране", + "4": "Дортиране на Š±Ń€Š¾ŃˆŃƒŃ€Šø", + "5": "Дортиране на Š±Ń€Š¾ŃˆŃƒŃ€Šø със страничен шев", + "6": "Четно-нечетно Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ", + "7": "ŠŸŃ€ŠµŠ¼Š°Ń…Š½Šø ŠæŃŠŃ€Š²Š¾", + "8": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на ŠæŠ¾ŃŠ»ŠµŠ“Š½ŠøŃ", + "9": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на ŠæŃŠŃ€Š²ŠøŃ Šø ŠæŠ¾ŃŠ»ŠµŠ“Š½ŠøŃ", + "10": "ŠžŠ±ŠµŠ“ŠøŠ½ŃŠ²Š°Š½Šµ на четно Šø нечетно", + "11": "Š”ŃƒŠ±Š»ŠøŃ€Š°Š½Šµ на всички страници" + }, + "placeholder": "(напр. 1,3,2 или 4-8,2,10-12 или 2n-1)" + }, + "addImage": { + "tags": "img,jpg,изображение,снимка", + "title": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на изображение", + "header": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на изображение към PDF", + "everyPage": "Š’ŃŃŠŗŠ° страница?", + "upload": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на изображение", + "submit": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на изображение" + }, + "watermark": { + "tags": "Текст,ŠæŠ¾Š²Ń‚Š°Ń€ŃŃ‰ се,етикет,собствено,авторско право,Ń‚ŃŠŃ€Š³Š¾Š²ŃŠŗŠ° марка,img,jpg,изображение,снимка", + "title": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на воГен знак", + "header": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на воГен знак", + "customColor": "ŠŸŠµŃ€ŃŠ¾Š½Š°Š»ŠøŠ·ŠøŃ€Š°Š½ Ń†Š²ŃŃ‚ на текста", + "selectText": { + "1": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ PDF, към който Га Гобавите воГен знак:", + "2": "Текст на воГен знак:", + "3": "Размер на ŃˆŃ€ŠøŃ„Ń‚Š°:", + "4": "Š—Š°Š²ŃŠŃ€Ń‚Š°Š½Šµ (0-360):", + "5": "ŃˆŠøŃ€ŠøŠ½Š°Spacer (Š Š°Š·ŃŃ‚Š¾ŃŠ½ŠøŠµ межГу всеки воГен знак хоризонтално):", + "6": "ГължинаSpacer (Š Š°Š·ŃŃ‚Š¾ŃŠ½ŠøŠµ межГу всеки воГен знак вертикално):", + "7": "ŠŠµŠæŃ€Š¾Š·Ń€Š°Ń‡Š½Š¾ŃŃ‚ (0% - 100%):", + "8": "Тип воГен знак:", + "9": "Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ за воГен знак:", + "10": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŠøŃ€Š°Š¹Ń‚Šµ PDF в PDF-изображение" + }, + "submit": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на воГен знак", + "type": { + "1": "Текст", + "2": "Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ" + } + }, + "permissions": { + "tags": "четене,писане,реГактиране,печат", + "title": "ŠŸŃ€Š¾Š¼ŃŠ½Š° на правата", + "header": "ŠŸŃ€Š¾Š¼ŠµŠ½Šø правата", + "warning": "ŠŸŃ€ŠµŠ“ŃƒŠæŃ€ŠµŠ¶Š“ŠµŠ½ŠøŠµ, че тези Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŃ са непроменими, ŠæŃ€ŠµŠæŠ¾Ń€ŃŠŃ‡Š²Š° се Га ги заГаГете с парола чрез страницата за Š“Š¾Š±Š°Š²ŃŠ½Šµ на парола", + "selectText": { + "1": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ PDF, за Га промените правата", + "2": "Š Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŃ за заГаване", + "3": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŃŠ²Š°Š½Šµ на ŃŠ³Š»Š¾Š±ŃŠ²Š°Š½ŠµŃ‚Š¾ на Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚", + "4": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŠµŃ‚Šµ извличането на ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ", + "5": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŠµŃ‚Šµ извличането за Š“Š¾ŃŃ‚ŃŠŠæŠ½Š¾ŃŃ‚", + "6": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŃŠ²Š°Š½Šµ на попълване на Ń„Š¾Ń€Š¼ŃƒŠ»ŃŃ€", + "7": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŃŠ²Š°Š½Šµ на Š¼Š¾Š“ŠøŃ„ŠøŠŗŠ°Ń†ŠøŃ", + "8": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŃŠ²Š°Š½Šµ на Š¼Š¾Š“ŠøŃ„ŠøŠŗŠ°Ń†ŠøŃ на Š°Š½Š¾Ń‚Š°Ń†ŠøŃ", + "9": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŃŠ²Š°Š¼ на отпечатването", + "10": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŠµŃ‚Šµ отпечатването на различни формати" + }, + "submit": "ŠŸŃ€Š¾Š¼ŠµŠ½Šø" + }, + "removePages": { + "tags": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на страници,изтриване на страници" + }, + "addPassword": { + "tags": "ŃŠøŠ³ŃƒŃ€ŠµŠ½,ŃŠøŠ³ŃƒŃ€Š½Š¾ŃŃ‚", + "title": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на парола", + "header": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на парола (Шифроване)", + "selectText": { + "1": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ PDF, който Га ŃˆŠøŃ„Ń€Š¾Š²Š°Ń‚Šµ", + "2": "ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŠŗŠ° парола", + "3": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŃŠ²Š°Š½Šµ на ŃŠ³Š»Š¾Š±ŃŠ²Š°Š½ŠµŃ‚Š¾ на Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚", + "4": "По-високите стойности са по-силни, но по-ниските стойности имат по-Гобра ŃŃŠŠ²Š¼ŠµŃŃ‚ŠøŠ¼Š¾ŃŃ‚.", + "5": "Š Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŃ за заГаване (ŠæŃ€ŠµŠæŠ¾Ń€ŃŠŃ‡Š²Š° се Га се използва заеГно с паролата на собственика)", + "6": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŃŠ²Š°Š½Šµ на ŃŠ³Š»Š¾Š±ŃŠ²Š°Š½ŠµŃ‚Š¾ на Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚", + "7": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŠµŃ‚Šµ извличането на ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ", + "8": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŠµŃ‚Šµ извличането за Š“Š¾ŃŃ‚ŃŠŠæŠ½Š¾ŃŃ‚", + "9": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŃŠ²Š°Š½Šµ на попълване на Ń„Š¾Ń€Š¼ŃƒŠ»ŃŃ€", + "10": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŃŠ²Š°Š½Šµ на промени", + "11": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŃŠ²Š°Š½Šµ на промени на Š°Š½Š¾Ń‚Š°Ń†ŠøŃ", + "12": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŃŠ²Š°Š½Šµ на печат", + "13": "ŠŸŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‚ŠµŃ‚Šµ отпечатването в различни формати", + "14": "ŠŸŠ°Ń€Š¾Š»Š° на собственика", + "15": "ŠžŠ³Ń€Š°Š½ŠøŃ‡Š°Š²Š° какво може Га се прави с Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°, слеГ като бъГе отворен (не се ŠæŠ¾Š“Š“ŃŠŃ€Š¶Š° от всички четци)", + "16": "ŠžŠ³Ń€Š°Š½ŠøŃ‡Š°Š²Š° Š¾Ń‚Š²Š°Ń€ŃŠ½ŠµŃ‚Š¾ на ŃŠ°Š¼ŠøŃ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚" + }, + "submit": "Шифроване" + }, + "removePassword": { + "tags": "ŃŠøŠ³ŃƒŃ€Š½Š¾,Гекриптиране,ŃŠøŠ³ŃƒŃ€Š½Š¾ŃŃ‚,Š¾Ń‚Š¼ŃŠ½Š° на парола,изтриване на парола", + "title": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на паролата", + "header": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на паролата (Декриптиране)", + "selectText": { + "1": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ PDF за Декриптиране", + "2": "ŠŸŠ°Ń€Š¾Š»Š°" + }, + "submit": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ" + }, + "compressPdfs": { + "tags": "мачкам,малък,Š¼ŃŠŠ½ŠøŃ‡ŃŠŠŗ" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Заглавие,автор,Гата,съзГаване,час,изГател,ŠæŃ€Š¾Š“ŃƒŃ†ŠµŠ½Ń‚,статистика", + "title": "Заглавие:", + "header": "ŠŸŃ€Š¾Š¼ŠµŠ½Šø метаГанните", + "selectText": { + "1": "ŠœŠ¾Š»Ń, реГактирайте променливите, които искате Га промените", + "2": "Š˜Š·Ń‚Ń€ŠøŠ¹ всички метаГанни", + "3": "Покажи персонализирани метаГанни:", + "4": "Š”Ń€ŃƒŠ³Šø метаГанни:", + "5": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на персонализиране метаГанни" + }, + "author": "Автор:", + "creationDate": "Дата на съзГаване (гггг/ММ/ГГ ЧЧ:мм:сс):", + "creator": "Š”ŃŠŠ·Š“Š°Ń‚ŠµŠ»:", + "keywords": "ŠšŠ»ŃŽŃ‡Š¾Š²Šø Гуми:", + "modDate": "Дата на ŠæŃ€Š¾Š¼ŃŠ½Š° (гггг/ММ/ГГ ЧЧ:мм:сс):", + "producer": "ŠŸŃ€Š¾Š“ŃƒŃ†ŠµŠ½Ń‚:", + "subject": "Тема:", + "trapped": "Š’ капан:", + "submit": "ŠŸŃ€Š¾Š¼ŠµŠ½Šø" + }, + "fileToPDF": { + "tags": "Ń‚Ń€Š°Š½ŃŃ„Š¾Ń€Š¼Š°Ń†ŠøŃ,формат,Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚,изображение,слайГ,текст,ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ,офис,Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šø,word,excel,powerpoint", + "title": "Файл към PDF", + "header": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŠøŃ€Š°Š¹Ń‚Šµ всеки файл към PDF", + "credit": "Тази услуга използва LibreOffice Šø Unoconv за ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ на файлове.", + "supportedFileTypesInfo": "ŠŸŠ¾Š“Š“ŃŠŃ€Š¶Š°Š½ŠøŠµ файлови типове", + "supportedFileTypes": "ŠŸŠ¾Š“Š“ŃŠŃ€Š¶Š°Š½ŠøŃ‚Šµ типове файлове Ń‚Ń€ŃŠ±Š²Š° Га Š²ŠŗŠ»ŃŽŃ‡Š²Š°Ń‚ по-Голу, но за пълен Š°ŠŗŃ‚ŃƒŠ°Š»ŠøŠ·ŠøŃ€Š°Š½ списък на ŠæŠ¾Š“Š“ŃŠŃ€Š¶Š°Š½ŠøŃ‚Šµ формати, Š¼Š¾Š»Ń, вижте Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃŃ‚Š° на LibreOffice", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ към PDF" + }, + "ocr": { + "tags": "разпознаване,текст,изображение,сканиране,четене,иГентифициране,откриване,реГактиране", + "title": "OCR / ŠŸŠ¾Ń‡ŠøŃŃ‚Š²Š°Š½Šµ на сканиране", + "header": "ŠŸŠ¾Ń‡ŠøŃŃ‚Š²Š°Ń‰Šø ŃŠŗŠ°Š½ŠøŃ€Š°Š½ŠøŃ / OCR (оптично разпознаване на знаци)", + "selectText": { + "1": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ езици, които Га Š±ŃŠŠ“ат открити в рамките на PDF (изброените са откритите към момента):", + "2": "ДъзГаване на текстов файл, ŃŃŠŠ“ŃŠŃ€Š¶Š°Ń‰ OCR текст заеГно с OCR PDF", + "3": "ŠŸŃ€Š°Š²ŠøŠ»Š½ŠøŃ‚Šµ страници Š±ŃŃ…а сканирани поГ изкривен ъгъл чрез Š·Š°Š²ŃŠŃ€Ń‚ането им обратно на Š¼ŃŃŃ‚ото им", + "4": "Чиста страница, така че е по-малко Š²ŠµŃ€Š¾ŃŃ‚но OCR Га намери текст във фонов шум. (Без ŠæŃ€Š¾Š¼ŃŠ½Š° на изхоГа)", + "5": "Чиста страница, така че е по-малко Š²ŠµŃ€Š¾ŃŃ‚но OCR Га намери текст във фонов шум, ŠæŠ¾Š“Š“ŃŠŃ€Š¶Š° почистване към изхоГа.", + "6": "Š˜Š³Š½Š¾Ń€ŠøŃ€Š° страници, които имат интерактивен текст, само OCR страници, които са ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "7": "ŠŸŃ€ŠøŠ½ŃƒŠ“ŠøŃ‚ŠµŠ»Š½Š¾ OCR, ще премахва чрез OCR на Š²ŃŃŠŗŠ° страница всички оригинални текстови елементи", + "8": "ŠŠ¾Ń€Š¼Š°Š»Š½Š¾ (Ще има Š³Ń€ŠµŃˆŠŗŠ°, ако PDF ŃŃŠŠ“ŃŠŃ€Š¶Š° текст)", + "9": "Š”Š¾ŠæŃŠŠ»Š½ŠøŃ‚ŠµŠ»Š½Šø настройки", + "10": "OCR режим", + "11": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ слеГ OCR (ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š° Š’Š”Š˜Š§ŠšŠ˜ ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ, полезно само ако е част от ŃŃ‚ŃŠŠæŠŗŠ°Ń‚Š° на ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ)", + "12": "Тип ŠøŠ·Š¾Š±Ń€Š°Š·ŃŠ²Š°Š½Šµ (Š Š°Š·ŃˆŠøŃ€ŠµŠ½)" + }, + "help": "ŠœŠ¾Š»Ń, прочетете тази Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃ за това как Га използвате това за Š“Ń€ŃƒŠ³Šø езици Šø/или Га не използвате в docker", + "credit": "Тази услуга използва qpdf Šø Tesseract за OCR.", + "submit": "ŠžŠ±Ń€Š°Š±Š¾Ń‚ŠŗŠ° на PDF чрез OCR" + }, + "extractImages": { + "tags": "изображение,снимка,запазване,архивиране,архив,заснемане,грабване", + "title": "Š˜Š·Š²Š»ŠøŃ‡Š°Š½Šµ на ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "header": "Š˜Š·Š²Š»ŠøŃ‡Š°Š½Šµ на ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "selectText": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ формат на изображението, в който Га ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Ń‚е извлечените ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "allowDuplicates": "Запазване на Š“ŃƒŠ±Š»ŠøŃ€Š°Š½Šø ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "submit": "Š˜Š·Š²Š»ŠøŃ‡Š°Š½Šµ" + }, + "pdfToPDFA": { + "tags": "архив,Š“ŃŠŠ»Š³Š¾Ń‚Ń€Š°ŠµŠ½,станГартен,ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ,ŃŃŠŃ…Ń€Š°Š½ŠµŠ½ŠøŠµ,консервиране", + "title": "PDF към PDF/A", + "header": "PDF към PDF/A", + "credit": "Тази услуга използва libreoffice за PDF/A ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ.", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ", + "tip": "Š’ момента не работи за Š½ŃŠŗŠ¾Š»ŠŗŠ¾ вхоГа навеГнъж", + "outputFormat": "Š˜Š·Ń…Š¾Š“ŠµŠ½ формат", + "pdfWithDigitalSignature": "PDF Ń„Š°Š¹Š»ŃŠŃ‚ ŃŃŠŠ“ŃŠŃ€Š¶Š° цифров поГпис. Това ще бъГе премахнато в слеГващата ŃŃ‚ŃŠŠæŠŗŠ°." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,Ń‚Ń€Š°Š½ŃŃ„Š¾Ń€Š¼Š°Ń†ŠøŃ,формат,ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ,офис,microsoft,docfile", + "title": "PDF към Word", + "header": "PDF към Word", + "selectText": { + "1": "Š˜Š·Ń…Š¾Š“ŠµŠ½ файлов формат" + }, + "credit": "Тази услуга използва LibreOffice за ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ на файлове.", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ" + }, + "PDFToPresentation": { + "tags": "слайГове,покажи,офис,microsoft", + "title": "PDF към ŠŸŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†ŠøŃ", + "header": "PDF към ŠŸŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†ŠøŃ", + "selectText": { + "1": "Š˜Š·Ń…Š¾Š“ŠµŠ½ файлов формат" + }, + "credit": "Тази услуга използва LibreOffice за ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ на файлове.", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ" + }, + "PDFToText": { + "tags": "richformat,richtextformat,богат текстов формат", + "title": "PDF към RTF (Текст)", + "header": "PDF към RTF (Текст)", + "selectText": { + "1": "Š˜Š·Ń…Š¾Š“ŠµŠ½ файлов формат" + }, + "credit": "Тази услуга използва LibreOffice за ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ на файлове.", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ" + }, + "PDFToHTML": { + "tags": "уеб-ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ,уГобен за Š±Ń€Š°ŃƒŠ·ŃŠŃ€", + "title": "PDF към HTML", + "header": "PDF към HTML", + "credit": "Тази услуга използва pdftohtml за ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ на файлове.", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ" + }, + "PDFToXML": { + "tags": "извличане на Ганни,ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€ŠøŃ€Š°Š½Š¾ ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ,взаимоГействие,Ń‚Ń€Š°Š½ŃŃ„Š¾Ń€Š¼Š°Ń†ŠøŃ,ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ", + "title": "PDF към XML", + "header": "PDF към XML", + "credit": "Тази услуга използва LibreOffice за ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ на файлове.", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ" + }, + "ScannerImageSplit": { + "tags": "Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ,автоматично откриване,сканиране,много снимки,организиране", + "selectText": { + "1": "ŠŸŃ€Š°Š³ на ъгъла:", + "2": "ЗаГава Š¼ŠøŠ½ŠøŠ¼Š°Š»Š½ŠøŃ Š°Š±ŃŠ¾Š»ŃŽŃ‚ŠµŠ½ ъгъл, необхоГим за Š·Š°Š²ŃŠŃ€Ń‚ане на изображението (по поГразбиране: 10).", + "3": "Толеранс:", + "4": "ŠžŠæŃ€ŠµŠ“ŠµŠ»Ń обхвата на цветовата Š²Š°Ń€ŠøŠ°Ń†ŠøŃ около ŠæŃ€ŠµŠ“ŠæŠ¾Š»Š°Š³Š°ŠµŠ¼ŠøŃ фонов Ń†Š²ŃŃ‚ (по поГразбиране: 30).", + "5": "Минимална площ:", + "6": "ЗаГава Š¼ŠøŠ½ŠøŠ¼Š°Š»Š½ŠøŃ праг на площ за изображение (по поГразбиране: 10000).", + "7": "Минимална ŠŗŠ¾Š½Ń‚ŃƒŃ€Š½Š° площ:", + "8": "ЗаГава Š¼ŠøŠ½ŠøŠ¼Š°Š»Š½ŠøŃ праг на ŠŗŠ¾Š½Ń‚ŃƒŃ€Š½Š°Ń‚Š° площ за изображение", + "9": "Размер на рамката:", + "10": "ЗаГава размера на Гобавената Šø премахната граница, за Га преГотврати бели граници към изхоГа (по поГразбиране: 1)." + }, + "info": "Python не е инсталиран. Изисква се Га се ŠøŠ·ŠæŃŠŠ»Š½ŃŠ²Š°." + }, + "sign": { + "tags": "ŃƒŠæŃŠŠ»Š½Š¾Š¼Š¾Ń‰Š°Š²Š°Š½Šµ,инициали,Š½Š°Ń€ŠøŃŃƒŠ²Š°Š½-поГпис,текстов-знак,изображение-поГпис", + "title": "ŠŸŠ¾Š“ŠæŠøŃˆŠµŃ‚Šµ", + "header": "ŠŸŠ¾Š“ŠæŠøŃˆŠµŃ‚Šµ PDF-Šø", + "upload": "ŠšŠ°Ń‡Šø изображение", + "draw": "ŠŠ°Ń‡ŠµŃ€Ń‚Š°Š¹Ń‚Šµ поГпис", + "text": "Š’ŃŠŠ²ŠµŠ¶Š“Š°Š½Šµ на текст", + "clear": "Š˜Š·Ń‡ŠøŃŃ‚Šø", + "add": "Добави", + "saved": "Š”ŃŠŃ…Ń€Š°Š½ŠµŠ½Šø поГписи", + "save": "Запазване на поГпис", + "personalSigs": "Лични поГписи", + "sharedSigs": "ДпоГелени поГписи", + "noSavedSigs": "ŠŠµ са намерени запазени поГписи", + "addToAll": "Дибави към всички страници", + "delete": "Š˜Š·Ń‚Ń€ŠøŠ¹", + "first": "ŠŸŃŠŃ€Š²Š° страница", + "last": "ПослеГна страница", + "next": "ДлеГваща страница", + "previous": "ŠŸŃ€ŠµŠ“ŠøŃˆŠ½Š° стараница", + "maintainRatio": "ŠŸŃ€ŠµŠ²ŠŗŠ»ŃŽŃ‡Š²Š°Š½Šµ за ŠæŠ¾Š“Š“ŃŠŃ€Š¶Š°Š½Šµ на ŃŃŠŠ¾Ń‚Š½Š¾ŃˆŠµŠ½ŠøŠµŃ‚Š¾ на страните", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "статичен,Геактивиран,неинтерактивен,рационализиран", + "title": "Š˜Š·Ń€Š°Š²Š½ŠµŃ‚Šµ", + "header": "Š˜Š·Ń€Š°Š²Š½ŠµŃ‚Šµ PDF-Šø", + "flattenOnlyForms": "Š˜Š·Ń€Š°Š²Š½ŠµŃ‚Šµ само форми", + "submit": "Š˜Š·Ń€Š°Š²Š½ŠµŃ‚Šµ" + }, + "repair": { + "tags": "поправка,Š²ŃŠŠ·ŃŃ‚Š°Š½Š¾Š²ŃŠ²Š°Š½Šµ,ŠŗŠ¾Ń€ŠµŠŗŃ†ŠøŃ,Š²ŃŠŠ·ŃŃ‚Š°Š½Š¾Š²ŃŠ²Š°Š½Šµ", + "title": "ŠŸŠ¾ŠæŃ€Š°Š²Šø", + "header": "ŠŸŠ¾ŠæŃ€Š°Š²Šø PDF-Šø", + "submit": "ŠŸŠ¾ŠæŃ€Š°Š²Šø" + }, + "removeBlanks": { + "tags": "почистване,рационализиране,без ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ,организиране", + "title": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на празни места", + "header": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на празни страници", + "threshold": "ŠŸŃ€Š°Š³ на белота на пикселите:", + "thresholdDesc": "ŠŸŃ€Š°Š³ за Š¾ŠæŃ€ŠµŠ“ŠµŠ»ŃŠ½Šµ колко Š±ŃŠ» Ń‚Ń€ŃŠ±Š²Š° Га бъГе еГин Š±ŃŠ» пиксел, за Га бъГе класифициран като 'Š±ŃŠ»'. 0 = черно, 255 чисто Š±ŃŠ»Š¾.", + "whitePercent": "ŠŸŃ€Š¾Ń†ŠµŠ½Ń‚ Š±ŃŠ»Š¾ (%):", + "whitePercentDesc": "ŠŸŃ€Š¾Ń†ŠµŠ½Ń‚ от страницата, ŠŗŠ¾ŃŃ‚Š¾ Ń‚Ń€ŃŠ±Š²Š° Га бъГе в 'бели' пиксели, които Га Š±ŃŠŠ“ат премахнати", + "submit": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на празни места" + }, + "removeAnnotations": { + "tags": "коментари, маркиране, бележки, маркиране, премахване", + "title": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на анотации", + "header": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на анотации", + "submit": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ" + }, + "compare": { + "tags": "разграничаване,контраст,промени,анализ", + "title": "Š”Ń€Š°Š²Š½ŃŠ²Š°Š¹", + "header": "Š”Ń€Š°Š²Š½ŃŠ²Š°Š¹ PDF-Šø", + "highlightColor": { + "1": "Š¦Š²ŃŃ‚ на маркирането 1:", + "2": "Š¦Š²ŃŃ‚ на маркирането 2:" + }, + "document": { + "1": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ 1", + "2": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ 2" + }, + "submit": "Š”Ń€Š°Š²Š½ŃŠ²Š°Š¹", + "complex": { + "message": "ЕГин или Šø Гвата преГоставени Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° са големи файлове, точността на сравнението може Га бъГе намалена." + }, + "large": { + "file": { + "message": "ЕГин или Šø Гвата преГоставени Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° са Ń‚Š²ŃŠŃ€Š“Šµ големи за обработка" + } + }, + "no": { + "text": { + "message": "ЕГин или Šø Гвата избрани PDF файла Š½ŃŠ¼Š°Ń‚ текстово ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ. ŠœŠ¾Š»Ń, изберете PDF файлове с текст за сравнение." + } + } + }, + "certSign": { + "tags": "ŃƒŠ“Š¾ŃŃ‚Š¾Š²ŠµŃ€ŃŠ²Š°Š½Šµ,PEM,P12,официален,ŃˆŠøŃ„Ń€Š¾Š²Š°Š½Šµ", + "title": "ПоГписване със сертификат", + "header": "ŠŸŠ¾Š“ŠæŠøŃˆŠµŃ‚Šµ PDF с Š²Š°ŃˆŠøŃ сертификат (Š’ процес на работа)", + "selectPDF": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ PDF файл за поГписване:", + "jksNote": "Забележка: Ако Š²Š°ŃˆŠøŃŃ‚ тип сертификат не е в списъка по-Голу, Š¼Š¾Š»Ń, конвертирайте го във файл на Java Keystore (.jks) с помощта на ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚Š° за команГен реГ keytool. ДлеГ това изберете Š¾ŠæŃ†ŠøŃŃ‚а за .jks файл по-Голу.", + "selectKey": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ Š²Š°ŃˆŠøŃ файл с личен ŠŗŠ»ŃŽŃ‡ (формат PKCS#8, може Га бъГе .pem или .der):", + "selectCert": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ Š²Š°ŃˆŠøŃ файл със сертификат (формат X.509, може Га бъГе .pem или .der):", + "selectP12": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ Š²Š°ŃˆŠøŃ PKCS#12 Keystore файл (.p12 или .pfx) (По избор, ако е преГоставен, Ń‚Ń€ŃŠ±Š²Š° Га ŃŃŠŠ“ŃŠŃ€Š¶Š° Š²Š°ŃˆŠøŃ личен ŠŗŠ»ŃŽŃ‡ Šø сертификат):", + "selectJKS": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ Š’Š°ŃˆŠøŃ Java Keystore Файл (.jks или .keystore):", + "certType": "Тип сертификат", + "password": "Š’ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ Š²Š°ŃˆŠ°Ń‚Š° парола за Keystore за ŠŗŠ»ŃŽŃ‡Š¾Š²Šµ или частен ŠŗŠ»ŃŽŃ‡ (ако има):", + "showSig": "Показване на поГпис", + "reason": "ŠŸŃ€ŠøŃ‡ŠøŠ½Š°", + "location": "ŠœŠµŃŃ‚Š¾ŠæŠ¾Š»Š¾Š¶ŠµŠ½ŠøŠµ", + "name": "Име", + "showLogo": "Покажи лого", + "submit": "ŠŸŠ¾Š“ŠæŠøŃˆŠµŃ‚Šµ PDF" + }, + "removeCertSign": { + "tags": "ŃƒŠ“Š¾ŃŃ‚Š¾Š²ŠµŃ€ŃŠ²Š°Š½Šµ,PEM,P12,официален,Гекриптиране", + "title": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на поГписа на сертификата", + "header": "ŠŸŃ€ŠµŠ¼Š°Ń…Š½ŠµŃ‚Šµ Ń†ŠøŃ„Ń€Š¾Š²ŠøŃ сертификат от PDF", + "selectPDF": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ PDF файл:", + "submit": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на поГпис" + }, + "pageLayout": { + "tags": "сливане,комбиниран,еГиничен изглеГ,организиране", + "title": "ŠœŠ½Š¾Š³Š¾ŃŃ‚Ń€Š°Š½ŠøŃ‡Š½Š¾ оформление", + "header": "ŠžŃ„Š¾Ń€Š¼Š»ŠµŠ½ŠøŠµ на Š½ŃŠŗŠ¾Š»ŠŗŠ¾ страници", + "pagesPerSheet": "Дтраници на лист:", + "addBorder": "Š”Š¾Š±Š°Š²ŃŠ½Šµ на граници", + "submit": "ŠŸŠ¾Š“Š°Š¹Ń‚Šµ" + }, + "scalePages": { + "tags": "ŠæŃ€ŠµŠ¾Ń€Š°Š·Š¼ŠµŃ€ŃŠ²Š°Š½Šµ,ŠæŃ€Š¾Š¼ŃŠ½Š°,размер,аГаптиране", + "title": "ŠšŠ¾Ń€ŠøŠ³ŠøŃ€Š°Š½Šµ на мащаба на страницата", + "header": "ŠšŠ¾Ń€ŠøŠ³ŠøŃ€Š°Š½Šµ на мащаба на страницата", + "pageSize": "Размер на страница от Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°.", + "keepPageSize": "ŠžŃ€ŠøŠ³ŠøŠ½Š°Š»ŠµŠ½ размер", + "scaleFactor": "ŠŠøŠ²Š¾ на мащабиране (ŠøŠ·Ń€ŃŠ·Š²Š°Š½Šµ) на страница.", + "submit": "ŠŸŠ¾Š“Š°Š¹Ń‚Šµ" + }, + "add-page-numbers": { + "tags": "страничен, етикетиране, организиране, инГексиране" + }, + "auto-rename": { + "tags": "автоматично откриване,базирано на заглавка,организиране,преетикетиране", + "title": "Автоматично ŠæŃ€ŠµŠøŠ¼ŠµŠ½ŃƒŠ²Š°Š½Šµ", + "header": "Автоматично ŠæŃ€ŠµŠøŠ¼ŠµŠ½ŃƒŠ²Š°Š½Šµ на PDF", + "submit": "Автоматично ŠæŃ€ŠµŠøŠ¼ŠµŠ½ŃƒŠ²Š°Š½Šµ" + }, + "adjust-contrast": { + "tags": "ŠŗŠ¾Ń€ŠµŠŗŃ†ŠøŃ на цвета,настройте,моГифицирайте,поГобрете" + }, + "crop": { + "tags": "ŠøŠ·Ń€ŃŠ·Š²Š°Š½Šµ,свиване,реГактиране,Š¾Ń„Š¾Ń€Š¼ŃŠ½Šµ", + "title": "Š˜Š·Ń€ŃŠ·Š²Š°Š½Šµ", + "header": "Š˜Š·Ń€ŃŠ·Š²Š°Š½Šµ на PDF", + "submit": "ŠŸŠ¾Š“Š°Š¹Ń‚Šµ" + }, + "autoSplitPDF": { + "tags": "QR-базиран,отГелен,сканиране-сегмент,организиране", + "title": "Автоматично Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ на PDF", + "header": "Автоматично Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ на PDF", + "description": "ŠŸŠµŃ‡Š°Ń‚Š°Š¹Ń‚Šµ, Š²Š¼ŃŠŠŗŠ²Š°Š¹Ń‚Šµ, сканирайте, качвайте Šø ни позволете Га разГелим автоматично Š²Š°ŃˆŠøŃ‚е Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šø. ŠŠµ е необхоГимо Ń€ŃŠŃ‡Š½Š¾ сортиране.", + "selectText": { + "1": "ŠžŃ‚ŠæŠµŃ‡Š°Ń‚Š°Š¹Ń‚Šµ Š½ŃŠŗŠ¾Šø разГелителни листове Š¾Ń‚Š“Š¾Š»Ńƒ (Черно-Š±ŃŠ»Š¾Ń‚Š¾ е Гобре).", + "2": "Дканирайте всичките си Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šø навеГнъж, като поставите Ń€Š°Š·Š“ŠµŠ»ŠøŃ‚ŠµŠ»Š½ŠøŃ лист межГу тях.", + "3": "ŠšŠ°Ń‡ŠµŃ‚Šµ ŠµŠ“ŠøŠ½ŃŃ‚Š²ŠµŠ½ŠøŃ Š³Š¾Š»ŃŠ¼ сканиран PDF файл Šø оставете Stirling PDF Га се справи с останалото.", + "4": "РазГелителните страници се откриват Šø премахват автоматично, което гарантира чист краен Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚." + }, + "formPrompt": "Š˜Š·ŠæŃ€Š°Ń‚ŠµŃ‚Šµ PDF, ŃŃŠŠ“ŃŠŃ€Š¶Š°Ń‰ разГелители на страници на Stirling-PDF:", + "duplexMode": "Š”ŃƒŠæŠ»ŠµŠŗŃŠµŠ½ режим (сканиране отпреГ Šø отзаГ)", + "dividerDownload2": "Š˜Š·Ń‚ŠµŠ³Š»ŠµŃ‚Šµ 'Автоматичен сплитер разГелител (с ŠøŠ½ŃŃ‚Ń€ŃƒŠŗŃ†ŠøŠø).pdf'", + "submit": "ŠŸŠ¾Š“Š°Š¹Ń‚Šµ" + }, + "sanitizePdf": { + "tags": "чисти,ŃŠøŠ³ŃƒŃ€Š½Šø,безопасни,премахване-заплахи" + }, + "URLToPDF": { + "tags": "уеб-заснемане,запазване на страница,уеб към Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚,архив", + "title": "URL към PDF", + "header": "URL към PDF", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ", + "credit": "Използва WeasyPrint" + }, + "HTMLToPDF": { + "tags": "маркиране,уеб-ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ,Ń‚Ń€Š°Š½ŃŃ„Š¾Ń€Š¼Š°Ń†ŠøŃ,ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ", + "title": "HTML към PDF", + "header": "HTML към PDF", + "help": "ŠŸŃ€ŠøŠµŠ¼Š°Š½Šµ на HTML файлове Šø ZIP файлове, ŃŃŠŠ“ŃŠŃ€Š¶Š°Ń‰Šø html/css/ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ Šø т.н.", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ", + "credit": "Използва WeasyPrint", + "zoom": "ŠŠøŠ²Š¾ на мащабиране за показване на ŃƒŠµŠ±ŃŠ°Š¹Ń‚Š°.", + "pageWidth": "Ширина на страницата в сантиметри. (ŠŸŃ€Š°Š·Š½Š¾ по поГразбиране)", + "pageHeight": "Височина на страницата в сантиметри. (ŠŸŃ€Š°Š·Š½Š¾ по поГразбиране)", + "marginTop": "Горно поле на страницата в милиметри. (ŠŸŃ€Š°Š·Š½Š¾ по поГразбиране)", + "marginBottom": "Долно поле на страницата в милиметри. (ŠŸŃ€Š°Š·Š½Š¾ по поГразбиране)", + "marginLeft": "Š›ŃŠ²Š¾ поле на страницата в милиметри. (ŠŸŃ€Š°Š·Š½Š¾ по поГразбиране)", + "marginRight": "Š”ŃŃŠ½Š¾ поле на страницата в милиметри. (ŠŸŃ€Š°Š·Š½Š¾ по поГразбиране)", + "printBackground": "Š˜Š·Š¾Š±Ń€Š°Š·ŠµŃ‚Šµ фона на ŃƒŠµŠ±ŃŠ°Š¹Ń‚Š¾Š²Šµ.", + "defaultHeader": "Активиране на Š³Š¾Ń€Š½ŠøŃ ŠŗŠ¾Š»Š¾Š½Ń‚ŠøŃ‚ŃƒŠ» по поГразбиране (име Šø номер на страница)", + "cssMediaType": "ŠŸŃ€Š¾Š¼ŠµŠ½ŠµŃ‚Šµ CSS Š¼ŠµŠ“ŠøŠ¹Š½ŠøŃ тип на страницата.", + "none": "ŠŃŠ¼Š°", + "print": "ŠŸŠµŃ‡Š°Ń‚", + "screen": "Екран" + }, + "MarkdownToPDF": { + "tags": "маркиране,уеб-ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ,Ń‚Ń€Š°Š½ŃŃ„Š¾Ń€Š¼Š°Ń†ŠøŃ,ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ", + "title": "Markdown към PDF", + "header": "Markdown към PDF", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ", + "help": "Работата е в хоГ", + "credit": "Използва WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "маркиране, уеб-ŃŃŠŠ“ŃŠŃ€Š¶Š°Š½ŠøŠµ, Ń‚Ń€Š°Š½ŃŃ„Š¾Ń€Š¼Š°Ń†ŠøŃ, конвертиране, MD", + "title": "PDF към Markdown", + "header": "PDF към Markdown", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ" + }, + "getPdfInfo": { + "tags": "ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ,Ганни,статистики,статистика", + "title": "Вземете ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ за PDF", + "header": "Вземете ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ за PDF", + "submit": "Вземете ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ", + "downloadJson": "Š˜Š·Ń‚ŠµŠ³Š»ŠµŃ‚Šµ JSON" + }, + "extractPage": { + "tags": "извличане" + }, + "PdfToSinglePage": { + "tags": "еГинична страница" + }, + "showJS": { + "tags": "JS", + "title": "Покажи Javascript", + "header": "Покажи Javascript", + "downloadJS": "Š˜Š·Ń‚ŠµŠ³Š»Šø Javascript", + "submit": "Покажи" + }, + "autoRedact": { + "tags": "РеГактиране,Дкриване,Š·Š°Ń‚ŃŠŠ¼Š½ŃŠ²Š°Š½Šµ,черен,маркер,скрит", + "title": "Автоматично реГактиране", + "header": "Автоматично реГактиране", + "colorLabel": "Š¦Š²ŃŃ‚", + "textsToRedactLabel": "Текст за реГактиране (разГелен с реГове)", + "textsToRedactPlaceholder": "например: \\nŠŸŠ¾Š²ŠµŃ€ŠøŃ‚ŠµŠ»Š½Š¾ \\nДтрого секретно", + "useRegexLabel": "Използване на Regex", + "wholeWordSearchLabel": "Š¢ŃŠŃ€ŃŠµŠ½Šµ на Ń†ŃŠ»Š°Ń‚Š° Гума", + "customPaddingLabel": "ŠŸŠµŃ€ŃŠ¾Š½Š°Š»ŠøŠ·ŠøŃ€Š°Š½Š° Š“Š¾ŠæŃŠŠ»Š½ŠøŃ‚ŠµŠ»Š½Š° поГложка", + "convertPDFToImageLabel": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ на PDF към PDF-изображение (използва се за премахване на текст заГ полето)", + "submitButton": "Š˜Š·ŠæŃ€Š°Ń‰Š°Š½Šµ" + }, + "redact": { + "tags": "РеГактиране, скриване, Š·Š°Ń‚ŃŠŠ¼Š½ŠµŠ½ŠøŠµ, черно, маркер, скрито, Ń€ŃŠŃ‡Š½Š¾", + "title": "Š ŃŠŃ‡Š½Š¾ реГактиране", + "header": "Š ŃŠŃ‡Š½Š¾ реГактиране", + "submit": "РеГактиране", + "textBasedRedaction": "РеГактиране на базата на текст", + "pageBasedRedaction": "РеГактиране на базата на страници", + "convertPDFToImageLabel": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŠøŃ€Š°Š½Šµ на PDF в PDF-изображение (използва се за премахване на текста заГ полето)", + "pageRedactionNumbers": { + "title": "Дтраници", + "placeholder": "(напр. 1,2,8 или 4,7,12-16 или 2n-1)" + }, + "redactionColor": { + "title": "Š¦Š²ŃŃ‚ на реГактиране" + }, + "export": "Експорт", + "upload": "ŠšŠ°Ń‡Š²Š°Š½Šµ", + "boxRedaction": "РеГактиране на Ń€ŠøŃŃƒŠ½ŠŗŠ°Ń‚Š° в кваГратчето", + "zoom": "Увеличаване", + "zoomIn": "Увеличаване на мащаба", + "zoomOut": "ŠŠ°Š¼Š°Š»ŃŠ²Š°Š½Šµ на мащаба", + "nextPage": "ДлеГваща страница", + "previousPage": "ŠŸŃ€ŠµŠ“ŠøŃˆŠ½Š° страница", + "toggleSidebar": "ŠŸŃ€ŠµŠ²ŠŗŠ»ŃŽŃ‡Š²Š°Š½Šµ на страничната лента", + "showThumbnails": "Показване на Š¼ŠøŠ½ŠøŠ°Ń‚ŃŽŃ€Šø", + "showDocumentOutline": "Показване на ŠŗŠ¾Š½Ń‚ŃƒŃ€Š° на Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° (кликнете Гва ŠæŃŠŃ‚Šø, за Га Ń€Š°Š·Š³ŃŠŠ½ŠµŃ‚Šµ/свиете всички елементи)", + "showAttatchments": "Показване на прикачени файлове", + "showLayers": "Показване на слоеве (щракнете Гва ŠæŃŠŃ‚Šø, за Га Š²ŃŠŃ€Š½ŠµŃ‚е всички слоеве в ŃŃŠŃŃ‚Š¾ŃŠ½ŠøŠµ по поГразбиране)", + "colourPicker": "Š˜Š·Š±Š¾Ń€ на Ń†Š²ŃŃ‚", + "findCurrentOutlineItem": "ŠŠ°Š¼ŠøŃ€Š°Š½Šµ на Ń‚ŠµŠŗŃƒŃ‰ŠøŃ елемент от ŠŗŠ¾Š½Ń‚ŃƒŃ€Š°", + "applyChanges": "ŠŸŃ€ŠøŠ»Š°Š³Š°Š½Šµ на промените" + }, + "tableExtraxt": { + "tags": "CSV,извличане на таблица,извличане,конвертиране" + }, + "autoSizeSplitPDF": { + "tags": "pdf,Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ,Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚,Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ" + }, + "overlay-pdfs": { + "tags": "ŠŠ°ŃŠ»Š°Š³Š²Š°Š½Šµ", + "header": "ŠŠ°ŃŠ»Š°Š³Š²Š°Š½Šµ на PDF файлове", + "baseFile": { + "label": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ ŠžŃŠ½Š¾Š²ŠµŠ½ PDF файл" + }, + "overlayFiles": { + "label": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ наслагване на PDF файлове" + }, + "mode": { + "label": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ режим на наслагване", + "sequential": "ŠŸŠ¾ŃŠ»ŠµŠ“Š¾Š²Š°Ń‚ŠµŠ»Š½Š¾ наслагване", + "interleaved": "ŠŸŃ€ŠµŠæŠ»ŠµŃ‚ŠµŠ½Š¾ наслагване", + "fixedRepeat": "Фиксирано наслагване при повторение" + }, + "counts": { + "label": "Брой Š½Š°ŃŠ»Š°Š³Š²Š°Š½ŠøŃ (за режим на фиксирано повторение)", + "placeholder": "Š’ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ Š±Ń€Š¾Ń, разГелени със Š·Š°ŠæŠµŃ‚Š°Ń (напр. 2,3,1)" + }, + "position": { + "label": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ ŠæŠ¾Š·ŠøŃ†ŠøŃ на наслагване", + "foreground": "ŠŸŃ€ŠµŠ“ŠµŠ½ план", + "background": "Фон" + }, + "submit": "Š˜Š·ŠæŃ€Š°Ń‰Š°Š½Šµ" + }, + "split-by-sections": { + "tags": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ на ŃŠµŠŗŃ†ŠøŃ,Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ,ŠŸŠµŃ€ŃŠ¾Š½Š°Š»ŠøŠ·ŠøŃ€Š°Š½Šµ", + "title": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ на PDF по секции", + "header": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ на PDF на секции", + "horizontal": { + "label": "Єоризонтални Ń€Š°Š·Š“ŠµŠ»ŠµŠ½ŠøŃ", + "placeholder": "Š’ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ брой хоризонтални Š“ŠµŠ»ŠµŠ½ŠøŃ" + }, + "vertical": { + "label": "Вертикални Ń€Š°Š·Š“ŠµŠ»ŠµŠ½ŠøŃ", + "placeholder": "Š’ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ брой вертикални Š“ŠµŠ»ŠµŠ½ŠøŃ" + }, + "submit": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ на PDF", + "merge": "Дливане в еГин PDF" + }, + "AddStampRequest": { + "tags": "ŠŸŠµŃ‡Š°Ń‚,Š“Š¾Š±Š°Š²ŃŠ½Šµ на изображение,централно изображение,воГен знак,PDF,вгражГане,персонализиране", + "header": "ŠŸŠ¾ŃŃ‚Š°Š²ŃŠ½Šµ на печат на PDF", + "title": "ŠŸŠ¾ŃŃ‚Š°Š²ŃŠ½Šµ на печат на PDF", + "stampType": "Тип печат", + "stampText": "ŠŸŠ¾ŃŃ‚Š°Š²ŃŠ½Šµ на текст", + "stampImage": "Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ с печат", + "alphabet": "Азбука", + "fontSize": "Размер на ŃˆŃ€ŠøŃ„Ń‚Š°/изображението", + "rotation": "Š Š¾Ń‚Š°Ń†ŠøŃ", + "opacity": "ŠŠµŠæŃ€Š¾Š·Ń€Š°Ń‡Š½Š¾ŃŃ‚", + "position": "ŠŸŠ¾Š·ŠøŃ†ŠøŃ", + "overrideX": "Š—Š°Š¼ŃŠ½Š° на X коорГината", + "overrideY": "Š—Š°Š¼ŃŠ½Š° на Y коорГината", + "customMargin": "ŠŸŠµŃ€ŃŠ¾Š½Š°Š»ŠøŠ·ŠøŃ€Š°Š½ марж", + "customColor": "ŠŸŠµŃ€ŃŠ¾Š½Š°Š»ŠøŠ·ŠøŃ€Š°Š½ Ń†Š²ŃŃ‚ на текста", + "submit": "Š˜Š·ŠæŃ€Š°Ń‰Š°Š½Šµ" + }, + "removeImagePdf": { + "tags": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на изображение, операции на страници, аГмин страна, страна на ŃŃŠŃ€Š²ŃŠŃ€Š°" + }, + "splitPdfByChapters": { + "tags": "Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ, глави, отметки, организиране" + }, + "validateSignature": { + "tags": "поГпис,проверка,валиГиране,pdf,сертификат,цифров поГпис,валиГиране на поГпис,валиГиране на сертификат", + "title": "Š£Š“Š¾ŃŃ‚Š¾Š²ŠµŃ€ŃŠ²Š°Š½Šµ на PDF поГписи", + "header": "ŠŸŠ¾Ń‚Š²ŃŠŃ€Š¶Š“Š°Š²Š°Š½Šµ на цифрови поГписи", + "selectPDF": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ ŠæŠ¾Š“ŠæŠøŃŠ°Š½ŠøŃ PDF файл", + "submit": "ŠŸŠ¾Ń‚Š²ŃŠŃ€Š¶Š“Š°Š²Š°Š½Šµ на поГписите", + "results": "Š ŠµŠ·ŃƒŠ»Ń‚Š°Ń‚Šø от валиГирането", + "status": { + "_value": "Š”Ń‚Š°Ń‚ŃƒŃ", + "valid": "ВалиГен", + "invalid": "ŠŠµŠ²Š°Š»ŠøŠ“ŠµŠ½" + }, + "signer": "ŠŸŠ¾Š“ŠæŠøŃŠ²Š°Ń‰", + "date": "Дата", + "reason": "ŠŸŃ€ŠøŃ‡ŠøŠ½Š°", + "location": "ŠœŠµŃŃ‚Š¾ŠæŠ¾Š»Š¾Š¶ŠµŠ½ŠøŠµ", + "noSignatures": "Š’ този Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ не са открити цифрови поГписи", + "chain": { + "invalid": "Š£Š“Š¾ŃŃ‚Š¾Š²ŠµŃ€ŃŠ²Š°Š½ŠµŃ‚Š¾ на веригата на сертификата е неуспешно - не може Га се провери самоличността на ŠæŠ¾Š“ŠæŠøŃŠ²Š°Ń‰ŠøŃ" + }, + "trust": { + "invalid": "Š”ŠµŃ€Ń‚ŠøŃ„ŠøŠŗŠ°Ń‚ŃŠŃ‚ не е в хранилището за Говерие - ŠøŠ·Ń‚Š¾Ń‡Š½ŠøŠŗŃŠŃ‚ не може Га бъГе проверен" + }, + "cert": { + "expired": "Š”ŠµŃ€Ń‚ŠøŃ„ŠøŠŗŠ°Ń‚ŃŠŃ‚ е ŠøŠ·Ń‚ŠµŠŗŃŠŠ»", + "revoked": "Š”ŠµŃ€Ń‚ŠøŃ„ŠøŠŗŠ°Ń‚ŃŠŃ‚ е отменен", + "info": "ŠŸŠ¾Š“Ń€Š¾Š±Š½Š¾ŃŃ‚Šø за сертификата", + "issuer": "Š˜Š·Š“Š°Ń‚ŠµŠ»", + "subject": "Тема", + "serialNumber": "Дериен номер", + "validFrom": "ВалиГен от", + "validUntil": "ВалиГен Го", + "algorithm": "ŠŠ»Š³Š¾Ń€ŠøŃ‚ŃŠŠ¼", + "keySize": "Размер на ŠŗŠ»ŃŽŃ‡", + "version": "Š’ŠµŃ€ŃŠøŃ", + "keyUsage": "ŠŸŃ€ŠµŠ“Š½Š°Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ на ŠŗŠ»ŃŽŃ‡Š° за използване", + "selfSigned": "Š”Š°Š¼Š¾ŃŃ‚Š¾ŃŃ‚ŠµŠ»Š½Š¾ поГписан", + "bits": "битове" + }, + "signature": { + "info": "Š˜Š½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ за поГписа", + "_value": "ПоГпис", + "mathValid": "ŠŸŠ¾Š“ŠæŠøŃŃŠŃ‚ е математически валиГен, ŠŠž:" + }, + "selectCustomCert": "Файл със сертификат X.509 по ŠæŠ¾Ń€ŃŠŃ‡ŠŗŠ° (по избор)" + }, + "replace-color": { + "title": "Замени-инвертиране-на-Ń†Š²ŃŃ‚", + "header": "Š—Š°Š¼ŃŠ½Š°-инвертиране на Ń†Š²ŃŃ‚ PDF", + "selectText": { + "1": "ŠžŠæŃ†ŠøŠø за Š·Š°Š¼ŃŠ½Š° или инвертиране на Ń†Š²ŃŃ‚", + "2": "По поГразбиране (цветове с висок контраст по поГразбиране)", + "3": "По избор (персонализирани цветове)", + "4": "Пълно инвертиране (Š˜Š½Š²ŠµŃ€Ń‚ŠøŃ€Š°Š½Šµ на всички цветове)", + "5": "Цветови опции с висок контраст", + "6": "Š‘ŃŠ» текст на черен фон", + "7": "Черен текст на Š±ŃŠ» фон", + "8": "Š–ŃŠŠ»Ń‚ текст на черен фон", + "9": "Зелен текст на черен фон", + "10": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ Ń†Š²ŃŃ‚ на текста", + "11": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ Ń†Š²ŃŃ‚ на фона" + }, + "submit": "Замени" + }, + "replaceColorPdf": { + "tags": "Š—Š°Š¼ŃŠ½Š° на Ń†Š²ŃŃ‚, операции на страници, заГен край, страна на ŃŃŠŃ€Š²ŃŠŃ€Š°" + }, + "login": { + "title": "ВхоГ", + "header": "ВхоГ", + "signin": "Š’ŠæŠøŃˆŠµŃ‚Šµ се", + "rememberme": "Запомни ме", + "invalid": "ŠŠµŠ²Š°Š»ŠøŠ“Š½Š¾ потребителско име или парола.", + "locked": "Š’Š°ŃˆŠøŃŃ‚ Š°ŠŗŠ°ŃƒŠ½Ń‚ е Š·Š°ŠŗŠ»ŃŽŃ‡ŠµŠ½.", + "signinTitle": "ŠœŠ¾Š»Ń Š²ŠæŠøŃˆŠµŃ‚Šµ се", + "ssoSignIn": "Влизане чрез еГнократно влизане", + "oAuth2AutoCreateDisabled": "OAUTH2 Автоматично съзГаване на потребител е Геактивирано", + "oAuth2AdminBlockedUser": "Š ŠµŠ³ŠøŃŃ‚Ń€Š°Ń†ŠøŃŃ‚Š° или влизането на нерегистрирани потребители в момента е блокирано. ŠœŠ¾Š»Ń, ŃŠ²ŃŠŃ€Š¶ŠµŃ‚Šµ се с аГминистратора.", + "oauth2RequestNotFound": "Š—Š°ŃŠ²ŠŗŠ°Ń‚Š° за Š¾Ń‚Š¾Ń€ŠøŠ·Š°Ń†ŠøŃ не е намерена", + "oauth2InvalidUserInfoResponse": "ŠŠµŠ²Š°Š»ŠøŠ“Š½Š° ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ за ŠæŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»Ń", + "oauth2invalidRequest": "ŠŠµŠ²Š°Š»ŠøŠ“Š½Š° Š·Š°ŃŠ²ŠŗŠ°", + "oauth2AccessDenied": "ŠžŃ‚ŠŗŠ°Š·Š°Š½ Š“Š¾ŃŃ‚ŃŠŠæ", + "oauth2InvalidTokenResponse": "ŠŠµŠ²Š°Š»ŠøŠ“ŠµŠ½ отговор на токена", + "oauth2InvalidIdToken": "ŠŠµŠ²Š°Š»ŠøŠ“ŠµŠ½ токен за иГентификатор", + "relyingPartyRegistrationNotFound": "ŠŠµ е открита Ń€ŠµŠ³ŠøŃŃ‚Ń€Š°Ń†ŠøŃ на Š“Š¾Š²ŠµŃ€ŃŠ²Š°Ń‰Š° се страна", + "userIsDisabled": "ŠŸŠ¾Ń‚Ń€ŠµŠ±ŠøŃ‚ŠµŠ»ŃŃ‚ е Геактивиран, влизането в момента е блокирано с това потребителско име. ŠœŠ¾Š»Ń, ŃŠ²ŃŠŃ€Š¶ŠµŃ‚Šµ се с аГминистратора.", + "alreadyLoggedIn": "Вече сте влезли в", + "alreadyLoggedIn2": "ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š°. ŠœŠ¾Š»Ń, излезте от ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š°Ń‚Š° Šø опитайте отново.", + "toManySessions": "Š˜Š¼Š°Ń‚Šµ Ń‚Š²ŃŠŃ€Š“Šµ много активни сесии", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF към еГинична страница", + "header": "PDF към еГинична страница", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ към еГинична страница" + }, + "pageExtracter": { + "title": "Š˜Š·Š²Š»ŠøŃ‡Š°Š½Šµ на страници", + "header": "Š˜Š·Š²Š»ŠøŃ‡Š°Š½Šµ на страници", + "submit": "Š˜Š·Š²Š»ŠøŃ‡Š°Š½Šµ", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "sanitizePDF": { + "title": "Дезинфектирай PDF", + "header": "Дезинфектира PDF файл", + "selectText": { + "1": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š° JavaScript Š“ŠµŠ¹ŃŃ‚Š²ŠøŃ", + "2": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š° вграГени файлове", + "3": "Remove XMP metadata", + "4": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š° линкове", + "5": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š° ŃˆŃ€ŠøŃ„Ń‚Š¾Š²Šµ", + "6": "Remove Document Info Metadata" + }, + "submit": "Дезинфектирай PDF" + }, + "adjustContrast": { + "title": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ° на контраста", + "header": "ŠšŠ¾Ń€ŠøŠ³ŠøŃ€Š°Š½Šµ на контраста", + "contrast": "ŠšŠ¾Š½Ń‚Ń€Š°ŃŃ‚:", + "brightness": "Яркост:", + "saturation": "ŠŠ°ŃŠøŃ‚ŠµŠ½Š¾ŃŃ‚:", + "download": "Š˜Š·Ń‚ŠµŠ³Š»Šø" + }, + "compress": { + "title": "ŠšŠ¾Š¼ŠæŃ€ŠµŃŠøŃ€Š°Š½Šµ", + "header": "ŠšŠ¾Š¼ŠæŃ€ŠµŃŠøŃ€Š°Š½Šµ на PDF", + "credit": "Тази услуга използва qpdf за PDF компресиране/оптимизиране.", + "grayscale": { + "label": "ŠŸŃ€ŠøŠ»Š¾Š¶Šø сива скала за компресиране" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "ŠŠøŠ²Š¾ на Š¾ŠæŃ‚ŠøŠ¼ŠøŠ·Š°Ń†ŠøŃ:", + "4": "Автоматичен режим - Автоматично настройва качеството, за Га ŠæŠ¾Š»ŃƒŃ‡Šø PDF с точен размер", + "5": "ŠžŃ‡Š°ŠŗŠ²Š°Š½ PDF размер (напр. 25ŠœŠ‘, 10.8ŠœŠ‘, 25ŠšŠ‘)" + }, + "submit": "ŠšŠ¾Š¼ŠæŃ€ŠµŃŠøŃ€Š°Š½Šµ" + }, + "decrypt": { + "passwordPrompt": "Този файл е защитен с парола. ŠœŠ¾Š»Ń, Š²ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ паролата:", + "cancelled": "ŠžŠæŠµŃ€Š°Ń†ŠøŃŃ‚Š° за PDF е отменена: {0}", + "noPassword": "ŠŠµ е преГоставена парола за ŃˆŠøŃ„Ń€ŠøŃ€Š°Š½ŠøŃ PDF: {0}", + "invalidPassword": "ŠœŠ¾Š»Ń, опитайте отново с правилната парола.", + "invalidPasswordHeader": "ŠŠµŠæŃ€Š°Š²ŠøŠ»Š½Š° парола или Š½ŠµŠæŠ¾Š“Š“ŃŠŃ€Š¶Š°Š½Š¾ криптиране за PDF: {0}", + "unexpectedError": "Š’ŃŠŠ·Š½ŠøŠŗŠ½Š° Š³Ń€ŠµŃˆŠŗŠ° при обработката на файла. ŠœŠ¾Š»Ń, опитайте отново.", + "serverError": "Š“Ń€ŠµŃˆŠŗŠ° в работата на ŃŃŠŃ€Š²ŃŠŃ€Š° повреме на Š“ŠµŃˆŠøŃ„Ń€ŠøŃ€Š°Š½Šµ: {0}", + "success": "Š¤Š°Š¹Š»ŃŠŃ‚ е успешно Š“ŠµŃˆŠøŃ„Ń€ŠøŃ€Š°Š½." + }, + "multiTool-advert": { + "message": "Тази Ń„ŃƒŠ½ŠŗŃ†ŠøŃ е налична Šø в Š½Š°ŃˆŠ°Ń‚а страница с множество ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚Šø. ŠŸŃ€Š¾Š²ŠµŃ€ŠµŃ‚Šµ го за поГобрен потребителски интерфейс страница по страница Šø Š“Š¾ŠæŃŠŠ»Š½ŠøŃ‚ŠµŠ»Š½Šø Ń„ŃƒŠ½ŠŗŃ†ŠøŠø!" + }, + "pageRemover": { + "title": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на страници", + "header": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на PDF страници", + "pagesToDelete": "Дтраници за изтриване (Š’ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ списък с номера на страници, разГелени със Š·Š°ŠæŠµŃ‚Š°Ń) :", + "submit": "Š˜Š·Ń‚Ń€ŠøŠ²Š°Š½Šµ на страници", + "placeholder": "(e.g. 1,2,6 or 1-10,15-30)" + }, + "imageToPDF": { + "title": "Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ към PDF", + "header": "Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ към PDF", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ", + "selectLabel": "ŠžŠæŃ†ŠøŠø за ŠæŃ€ŠøŠ»ŃŠ³Š°Š½Šµ на изображението", + "fillPage": "Попълване на страница", + "fitDocumentToImage": "ŠŸŠ¾Š±ŠøŃ€Š°Š½Šµ на страницата в изображението", + "maintainAspectRatio": "ŠŸŠ¾Š“Š“ŃŠŃ€Š¶Š°Š½Šµ на пропорции", + "selectText": { + "2": "Автоматично Š·Š°Š²ŃŠŃ€Ń‚ане на PDF", + "3": "Файлова логика с много (Активирано само ако работите с множество ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ)", + "4": "Дливане към еГин PDF", + "5": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ към отГелни PDF файлове" + } + }, + "PDFToCSV": { + "title": "PDF към CSV", + "header": "PDF към CSV", + "prompt": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ страница за извличане на таблица", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ²Š°Š½Šµ" + }, + "split-by-size-or-count": { + "title": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ на PDF по размер или брой", + "header": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ на PDF по размер или брой", + "type": { + "label": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ тип Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ", + "size": "По размер", + "pageCount": "По брой страници", + "docCount": "По брой Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šø" + }, + "value": { + "label": "Š’ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ стойност", + "placeholder": "Š’ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ размер (напр. 2ŠœŠ‘ или 3ŠšŠ‘) или брой (напр. 5)" + }, + "submit": "Š˜Š·ŠæŃ€Š°Ń‰Š°Š½Šµ" + }, + "printFile": { + "title": "ŠŸŠµŃ‡Š°Ń‚ на файл", + "header": "ŠŸŠµŃ‡Š°Ń‚ на файл на принтер", + "selectText": { + "1": "Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ файл за печат", + "2": "Š’ŃŠŠ²ŠµŠ“ŠµŃ‚Šµ име на принтер" + }, + "submit": "ŠŸŠµŃ‡Š°Ń‚" + }, + "licenses": { + "nav": "Лицензи", + "title": "Лицензи на трети страни", + "header": "Лицензи на трети страни", + "module": "МоГул", + "version": "Š’ŠµŃ€ŃŠøŃ", + "license": "Лиценз" + }, + "survey": { + "nav": "Анкета", + "title": "Stirling-PDF Анкета", + "description": "Stirling-PDF Š½ŃŠ¼Š° ŠæŃ€Š¾ŃŠ»ŠµŠ“ŃŠ²Š°Š½Šµ, така че искаме Га Ń‡ŃƒŠµŠ¼ мнението на Š½Š°ŃˆŠøŃ‚е потребители за ŠæŠ¾Š“Š¾Š±Ń€ŃŠ²Š°Š½Šµ на Stirling-PDF!", + "changes": "Stirling-PDF се промени от послеГното ŠæŃ€Š¾ŃƒŃ‡Š²Š°Š½Šµ! За Га Š½Š°ŃƒŃ‡ŠøŃ‚е повече, Š¼Š¾Š»Ń, проверете ŠæŃƒŠ±Š»ŠøŠŗŠ°Ń†ŠøŃŃ‚а в Š½Š°ŃˆŠøŃ блог Ń‚ŃƒŠŗ:", + "changes2": "Š” тези промени ŠæŠ¾Š»ŃƒŃ‡Š°Š²Š°Š¼Šµ платена бизнес поГкрепа Šø финансиране", + "please": "ŠœŠ¾Š»Ń, помислете Гали Га не ŃƒŃ‡Š°ŃŃ‚Š²Š°Ń‚Šµ в Š½Š°ŃˆŠ°Ń‚а анкета!", + "disabled": "(Š˜Š·ŃŠŗŠ°Ń‡Š°Ń‰ŠøŃŃ‚ прозорец с анкетата ще бъГе Геактивиран при слеГващите Š°ŠŗŃ‚ŃƒŠ°Š»ŠøŠ·Š°Ń†ŠøŠø, но ще бъГе наличен в Голната част на страницата)", + "button": "Участвайте в анкетата", + "dontShowAgain": "ŠŠµ показвай повече", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на изображението", + "header": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на изображението", + "removeImage": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на изображението", + "submit": "ŠŸŃ€ŠµŠ¼Š°Ń…Š²Š°Š½Šµ на изображението" + }, + "splitByChapters": { + "title": "РазГелете PDF по глави", + "header": "РазГелете PDF по глави", + "bookmarkLevel": "ŠŠøŠ²Š¾ на отметка", + "includeMetadata": "Š’ŠŗŠ»ŃŽŃ‡ŠµŃ‚Šµ метаГанни", + "allowDuplicates": "Š Š°Š·Ń€ŠµŃˆŠ°Š²Š°Š½Šµ на Š“ŃƒŠ±Š»ŠøŠŗŠ°Ń‚Šø", + "desc": { + "1": "Този ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚ Ń€Š°Š·Š“ŠµŠ»Ń PDF файл на множество PDF файлове въз основа на неговата ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Š° на глави.", + "2": "ŠŠøŠ²Š¾ на отметка: Š˜Š·Š±ŠµŃ€ŠµŃ‚Šµ нивото на отметките, които Га използвате за Ń€Š°Š·Š“ŠµŠ»ŃŠ½Šµ (0 за най-високо ниво, 1 за второ ниво Šø т.н.).", + "3": "Š’ŠŗŠ»ŃŽŃ‡Š²Š°Š½Šµ на метаГанни: Ако е отметнато, метаГанните на Š¾Ń€ŠøŠ³ŠøŠ½Š°Š»Š½ŠøŃ PDF ще Š±ŃŠŠ“ат Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Šø във всеки разГелен PDF.", + "4": "Š Š°Š·Ń€ŠµŃˆŠ°Š²Š°Š½Šµ на Š“ŃƒŠ±Š»ŠøŠŗŠ°Ń‚Šø: Ако е отметнато, ŠæŠ¾Š·Š²Š¾Š»ŃŠ²Š° множество отметки на еГна Šø ŃŃŠŃ‰Š° страница за съзГаване на отГелни PDF файлове." + }, + "submit": "Š Š°Š·Š“ŠµŠ»ŃŠ½Šµ на PDF" + }, + "fileChooser": { + "click": "Щракнете", + "or": "или", + "dragAndDrop": "Влачете Šø ŠæŃƒŃŠ½ŠµŃ‚Šµ", + "dragAndDropPDF": "Влачете Šø ŠæŃƒŃŠ½ŠµŃ‚Šµ PDF файл", + "dragAndDropImage": "Влачете Šø ŠæŃƒŃŠ½ŠµŃ‚Šµ изображение", + "hoveredDragAndDrop": "Влачете Šø ŠæŃƒŃŠ½ŠµŃ‚Šµ файл(ове) Ń‚ŃƒŠŗ", + "extractPDF": "Š˜Š·Š²Š»ŠøŃ‡Š°Š½Šµ..." + }, + "releases": { + "footer": "Версии", + "title": "Бележки към версиите", + "header": "Бележки към версиите", + "current": { + "version": "Š¢ŠµŠŗŃƒŃ‰Š° Š²ŠµŃ€ŃŠøŃ" + }, + "note": "Бележките към изГанието са налични само на английски език" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/ca-CA/translation.json b/frontend/public/locales/ca-CA/translation.json new file mode 100644 index 000000000..da8236b95 --- /dev/null +++ b/frontend/public/locales/ca-CA/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Mida del tipus de lletra", + "fontName": "Nom del tipus de lletra", + "title": "Afegir NĆŗmeros de PĆ gina", + "header": "Afegir NĆŗmeros de PĆ gina", + "selectText": { + "1": "Selecciona PDF:", + "2": "Mida del Marge", + "3": "Posició", + "4": "NĆŗmero Inicial", + "5": "PĆ gines a Enumerar", + "6": "Text Personalitzat" + }, + "customTextDesc": "Text Personalitzat", + "numberPagesDesc": "PĆ gines a enumerar, per defecte 'totes', accepta 1-5 o 2,5,9, etc.", + "customNumberDesc": "Per defecte {n}, accepta 'PĆ gina {n} de {total}', 'Text-{n}', '{filename}-{n}'", + "submit": "Afegir NĆŗmeros de PĆ gina" + }, + "pdfPrompt": "Selecciona PDF(s)", + "multiPdfPrompt": "Selecciona PDFs (2+)", + "multiPdfDropPrompt": "Selecciona (o arrossega) els documents PDF", + "imgPrompt": "Selecciona Imatge(s)", + "genericSubmit": "Envia", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Alerta: Aquest procĆ©s pot tardar 1 minut depenent de la mida de l'arxiu", + "pageOrderPrompt": "Ordre de PĆ gines (Llista separada per comes) :", + "pageSelectionPrompt": "Selecció de pĆ gines personalitzada (Introdueix una llista separada per comes de nĆŗmeros de pĆ gina, 1,5,6 o funcions com 2n+1):", + "goToPage": "Anar", + "true": "Verdader", + "false": "Fals", + "unknown": "Desconegut", + "save": "Desa", + "saveToBrowser": "Desa al navegador", + "close": "Tanca", + "filesSelected": "fitxers seleccionats", + "noFavourites": "No s'ha afegit cap favorit", + "downloadComplete": "Descarrega completa", + "bored": "Avorrit esperant?", + "alphabet": "Alfabet", + "downloadPdf": "Descarregueu PDF", + "text": "Text", + "font": "Tipus de lletra", + "selectFillter": "-- Selecciona --", + "pageNum": "NĆŗmero de pĆ gina", + "sizes": { + "small": "Petit", + "medium": "MitjĆ ", + "large": "Llarg", + "x-large": "X-Large" + }, + "error": { + "pdfPassword": "El PDF estĆ  protegit o bĆ© el password Ć©s incorrecte", + "_value": "Error", + "sorry": "Ho sentim pel problema!", + "needHelp": "Necessites ajuda / Has trobat un problema?", + "contactTip": "Si encara tens problemes, no dubtis a contactar-nos per a ajuda. Pots enviar una solĀ·licitud a la nostra pĆ gina de GitHub o contactar-nos a travĆ©s de Discord:", + "404": { + "head": "404 - PĆ gina No Trovada | Ooops, hem fet un error en el codi!", + "1": "Semblem no poder trobar la pĆ gina que estĆ s buscant.", + "2": "Alguna cosa ha anat malament" + }, + "github": "Envia una solĀ·licitud a GitHub", + "showStack": "Mostra la Pila d'Errors", + "copyStack": "Copia la Pila d'Errors", + "githubSubmit": "GitHub - Envia una solĀ·licitud", + "discordSubmit": "Discord - Envia una solĀ·licitud d'ajuda" + }, + "delete": "Esborra", + "username": "Usuari", + "password": "Contrasenya", + "welcome": "Benvingut", + "property": "Propietat", + "black": "Negre", + "white": "Blanc", + "red": "Vermell", + "green": "Verd", + "blue": "Blau", + "custom": "Personalitzat...", + "WorkInProgess": "En desenvolupament, pot no funcionar o contenir errors. Si us plau, informa de qualsevol problema!", + "poweredBy": "Impulsat per", + "yes": "Si", + "no": "No", + "changedCredsMessage": "Credencials canviades!", + "notAuthenticatedMessage": "Usuari no autenticat.", + "userNotFoundMessage": "Usuari no trobat.", + "incorrectPasswordMessage": "La contrasenya actual Ć©s incorrecta.", + "usernameExistsMessage": "El nou nom d’usuari ja existeix.", + "invalidUsernameMessage": "Nom d’usuari no vĆ lid, nomĆ©s pot contenir lletres, nĆŗmeros i els següents carĆ cters especials @._+- o ha de ser una adreƧa de correu electrònic vĆ lida.", + "invalidPasswordMessage": "La contrasenya no pot estar buida ni tenir espais al principi o al final.", + "confirmPasswordErrorMessage": "La contrasenya no pot estar buida ni tenir espais al principi o al final.", + "deleteCurrentUserMessage": "No es pot eliminar l’usuari actualment connectat.", + "deleteUsernameExistsMessage": "El nom d’usuari no existeix i no es pot eliminar.", + "downgradeCurrentUserMessage": "No es pot reduir la funció de l'usuari actual", + "disabledCurrentUserMessage": "L’usuari actual no pot ser deshabilitat", + "downgradeCurrentUserLongMessage": "No es pot baixar la funció de l'usuari actual. Per tant, no es mostrarĆ  l'usuari actual.", + "userAlreadyExistsOAuthMessage": "L’usuari ja existeix com a usuari OAuth2.", + "userAlreadyExistsWebMessage": "L’usuari ja existeix com a usuari web.", + "oops": "Oops!", + "help": "Ajuda", + "goHomepage": "VĆ©s a la pĆ gina principal", + "joinDiscord": "Uneix-te al nostre servidor de Discord", + "seeDockerHub": "Veure Docker Hub", + "visitGithub": "Visita el repositori de GitHub", + "donate": "Fes una donació", + "color": "Color", + "sponsor": "Patrocinador", + "info": "Informació", + "pro": "Pro", + "page": "PĆ gina", + "pages": "PĆ gines", + "loading": "Carregant...", + "addToDoc": "Afegeix al document", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "PolĆ­tica de Privacitat", + "terms": "Termes i condicions", + "accessibility": "Accessibilitat", + "cookie": "PolĆ­tica de galetes", + "impressum": "AvĆ­s Legal", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "MenĆŗ de Processos (Beta)", + "uploadButton": "CĆ rrega personalitzada", + "configureButton": "Configura", + "defaultOption": "Personalitzat", + "submitButton": "Envia-ho", + "help": "Ajuda de Processos", + "scanHelp": "Ajuda per a l’Escaneig de Carpetes", + "deletePrompt": "EstĆ s segur que vols eliminar els processos?", + "tags": "automatitzar,seqüència,scriptat,procĆ©s per lots", + "title": "ProcĆ©s" + }, + "pipelineOptions": { + "header": "Configuració del ProcĆ©s", + "pipelineNameLabel": "Nom del ProcĆ©s", + "saveSettings": "Desa la configuració de l'operació", + "pipelineNamePrompt": "Introdueix el nom del procĆ©s aquĆ­", + "selectOperation": "Selecciona Operació", + "addOperationButton": "Afegeix operació", + "pipelineHeader": "ProcĆ©s:", + "saveButton": "Descarrega", + "validateButton": "Valida" + }, + "enterpriseEdition": { + "button": "Actualitza a Pro", + "warning": "Aquesta funció nomĆ©s estĆ  disponible per a usuaris Pro.", + "yamlAdvert": "Stirling PDF Pro admet fitxers de configuració YAML i altres funcions d'SSO.", + "ssoAdvert": "Busques mĆ©s funcions de gestió d'usuaris? Consulta Stirling PDF Pro" + }, + "analytics": { + "title": "Vols ajudar a millorar Stirling PDF?", + "paragraph1": "Stirling PDF tĆ© analĆ­tiques opcionals per ajudar-nos a millorar el producte. No recopilem cap informació personal ni el contingut dels fitxers.", + "paragraph2": "Si us plau, considera habilitar les analĆ­tiques per ajudar Stirling PDF a crĆ©ixer i permetre'ns entendre millor els nostres usuaris.", + "enable": "Habilita analĆ­tiques", + "disable": "Desactiva analĆ­tiques", + "settings": "Pots canviar la configuració de les analĆ­tiques al fitxer config/settings.yml" + }, + "navbar": { + "favorite": "Favorits", + "recent": "Nou i recentment actualitzat", + "darkmode": "Mode Fosc", + "language": "Idiomes", + "settings": "Opcions", + "allTools": "Eines", + "multiTool": "Multi Tool", + "search": "Search", + "sections": { + "organize": "Organitzar", + "convertTo": "Convertir a PDF", + "convertFrom": "Convertir des de PDF", + "security": "Signatura i Seguretat", + "advance": "AvanƧat", + "edit": "Visualitzar i Editar", + "popular": "Popular" + } + }, + "settings": { + "title": "Opcions", + "update": "Actualització Disponible", + "updateAvailable": "La versió actual instalĀ·lada Ć©s {0}. Una nova versió ({1}) estĆ  disponible.", + "appVersion": "Versió de l'App:", + "downloadOption": { + "title": "Trieu l'opció de descĆ rrega (per a descĆ rregues d'un sol fitxer no comprimit):", + "1": "Obre en la mateixa finestra", + "2": "Obre en una finestra nova", + "3": "Descarrega fitxer" + }, + "zipThreshold": "Comprimiu els fitxers quan el nombre de fitxers baixats superi", + "signOut": "Sortir", + "accountSettings": "Configuració del Compte", + "bored": { + "help": "Activa un joc ocult" + }, + "cacheInputs": { + "name": "Desa els valors del formulari", + "help": "Habilita per guardar els valors utilitzats prĆØviament per a futures execucions" + } + }, + "changeCreds": { + "title": "Canvia les Credencials", + "header": "Actualitza les Dades del Compte", + "changePassword": "EstĆ s utilitzant les credencials d'inici de sessió per defecte. Si us plau, introdueix una nova contrasenya", + "newUsername": "Nou Nom d'Usuari", + "oldPassword": "Contrasenya Actual", + "newPassword": "Nova Contrasenya", + "confirmNewPassword": "Confirma la Nova Contrasenya", + "submit": "Envia els Canvis" + }, + "account": { + "title": "Opcions del compte", + "accountSettings": "Opcions del compte", + "adminSettings": "Opcions d'Administrador - Veure i afegir usuaris", + "userControlSettings": "Opcions de Control d'Usuari", + "changeUsername": "Canvia el nom d'usuari", + "newUsername": "Nom d'usuari nou", + "password": "Confirma contrasenya", + "oldPassword": "Contrasenya Antiga", + "newPassword": "Nova Contrasenya", + "changePassword": "Canvia la contrasenya", + "confirmNewPassword": "Confirma la Nova Contrasenya", + "signOut": "Sortir", + "yourApiKey": "Clau API", + "syncTitle": "Sincronitza les opcions del navegador amb el compte", + "settingsCompare": "Comparador d'Opcions:", + "property": "Propietat:", + "webBrowserSettings": "Opcions del Navegador", + "syncToBrowser": "Sincronitza Compte -> Navegador", + "syncToAccount": "Sincronitza Compte <- Navegador" + }, + "adminUserSettings": { + "title": "Opcions de Control d'Usuari", + "header": "Opcions de Control d'Usuari Admin", + "admin": "Admin", + "user": "Usuari", + "addUser": "Afegir Usuari", + "deleteUser": "Elimina Usuari", + "confirmDeleteUser": "Vols eliminar aquest usuari?", + "confirmChangeUserStatus": "Vols deshabilitar/habilitar aquest usuari?", + "usernameInfo": "El nom d'usuari nomĆ©s pot contenir lletres, nĆŗmeros i els següents carĆ cters especials: @._+- o ha de ser una adreƧa de correu electrònic vĆ lida.", + "roles": "Rols", + "role": "Rol", + "actions": "Accions", + "apiUser": "Usuari amb API limitada", + "extraApiUser": "Usuari Addicional amb API limitada", + "webOnlyUser": "Usuari nomĆ©s WEB", + "demoUser": "Usuari de Demo (Sense configuracions personalitzades)", + "internalApiUser": "Usuari d'API Interna", + "forceChange": "ForƧa l'usuari a canviar la contrasenya en iniciar sessió", + "submit": "Desa Usuari", + "changeUserRole": "Canvia el rol de l'usuari", + "authenticated": "Autenticat", + "editOwnProfil": "Edita el propi perfil", + "enabledUser": "usuari habilitat", + "disabledUser": "usuari deshabilitat", + "activeUsers": "Usuaris Actius:", + "disabledUsers": "Usuaris Deshabilitats:", + "totalUsers": "Total d'Usuaris:", + "lastRequest": "Darrera SolĀ·licitud", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Importació/Exportació de Base de Dades", + "header": "Importació/Exportació de Base de Dades", + "fileName": "Nom del Fitxer", + "creationDate": "Data de Creació", + "fileSize": "Mida del Fitxer", + "deleteBackupFile": "Elimina el Fitxer de Còpia de Seguretat", + "importBackupFile": "Importa el Fitxer de Còpia de Seguretat", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Descarrega el Fitxer de Còpia de Seguretat", + "info_1": "Quan importis dades, Ć©s crucial assegurar-se que l'estructura sigui correcta. Si no estĆ s segur del que fas, busca l'assessorament d'un professional. Un error en l'estructura pot causar malfuncionaments de l'aplicació, fins i tot impossibilitar-ne l'execució.", + "info_2": "El nom del fitxer no importa quan es puja. Es renombrarĆ  desprĆ©s per seguir el format backup_user_yyyyMMddHHmm.sql, assegurant una convenció de nomenclatura consistent.", + "submit": "Importa la Còpia de Seguretat", + "importIntoDatabaseSuccessed": "Importació a la base de dades completada amb ĆØxit", + "backupCreated": "Database backup successful", + "fileNotFound": "Fitxer no trobat", + "fileNullOrEmpty": "El fitxer no ha de ser nul o buit", + "failedImportFile": "Error en la importació del fitxer", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "La teva sessió ha expirat. Si us plau, actualitza la pĆ gina i torna a intentar-ho.", + "refreshPage": "Actualitza la pĆ gina" + }, + "home": { + "desc": "L'eina allotjada localment per a necessitats de PDF.", + "searchBar": "Cerca funcions...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Visualitza, anota, afegeix text o imatges" + }, + "setFavorites": "Configura els favorits", + "hideFavorites": "Amaga els favorits", + "showFavorites": "Mostra els favorits", + "legacyHomepage": "PĆ gina d'inici antiga", + "newHomePage": "Prova la nostra nova pĆ gina d'inici!", + "alphabetical": "AlfabĆØtic", + "globalPopularity": "Popularitat global", + "sortBy": "Ordena per:", + "multiTool": { + "title": "Eina Multifunció de PDF", + "desc": "Fusiona, Rota, Reorganitza i Esborra pĆ gines" + }, + "merge": { + "title": "Fusiona", + "desc": "Fusiona fĆ cilment pĆ gines en una sola." + }, + "split": { + "title": "Divideix", + "desc": "Divideix PDFs en mĆŗltiples documents" + }, + "rotate": { + "title": "Rota", + "desc": "Rota els PDFs." + }, + "imageToPdf": { + "title": "Imatge a PDF", + "desc": "Converteix imatge (PNG, JPEG, GIF) a PDF." + }, + "pdfToImage": { + "title": "PDF a Imatge", + "desc": "Converteix PDF a imatge (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Organitza", + "desc": "Elimina/reorganitza pĆ gines en qualsevol ordre" + }, + "addImage": { + "title": "Afegir imatge a PDF", + "desc": "Afegeix una imatge en un PDF (en progrĆ©s)" + }, + "watermark": { + "title": "Afegir Marca d'aigua", + "desc": "Afegir una marca d'aigua personalitzada en un PDF" + }, + "permissions": { + "title": "Canvia permisos", + "desc": "Canvia els permisos del document PDF" + }, + "removePages": { + "title": "Elimina", + "desc": "Elimina pĆ gines del document PDF." + }, + "addPassword": { + "title": "Afegir Contrasenya", + "desc": "Xifra el document PDF amb contrasenya." + }, + "removePassword": { + "title": "Elimina Contrasenya", + "desc": "Elimina la contrasenya del document PDF." + }, + "compressPdfs": { + "title": "Comprimeix", + "desc": "Comprimeix PDFs per reduir-ne la mida." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Canvia Metadades", + "desc": "Canvia/Treu/Afegeix metadades al document PDF." + }, + "fileToPDF": { + "title": "Converteix arxiu a PDF", + "desc": "Converteix qualsevol arxiu a PDF (DOCX, PNG, XLS, PPT, TXT i mĆ©s)" + }, + "ocr": { + "title": "Executa OCR i neteja escaneigs", + "desc": "Neteja escanejats i detecta text d'imatges dins d'un PDF, tornant-lo a afegir com a text." + }, + "extractImages": { + "title": "Extreu Imatges", + "desc": "Extreu les imatges del PDF i desa-les en un arxiu zip" + }, + "pdfToPDFA": { + "title": "PDF a PDF/A", + "desc": "Converteix PDF a PDF/A per a l'emmagatzematge a llarg termini." + }, + "PDFToWord": { + "title": "PDF a Word", + "desc": "Converteix PDF a formats de Word (DOC, DOCX i ODT)" + }, + "PDFToPresentation": { + "title": "PDF a Presentació", + "desc": "Converteix PDF a formats de presentació (PPT, PPTX i ODP)" + }, + "PDFToText": { + "title": "PDF a Text/RTF", + "desc": "Converteix PDF a text o format RTF" + }, + "PDFToHTML": { + "title": "PDF a HTML", + "desc": "Converteix PDF a format HTML" + }, + "PDFToXML": { + "title": "PDF a XML", + "desc": "Converteix PDF a format XML" + }, + "ScannerImageSplit": { + "title": "Detecta/Divideix fotos escanejades", + "desc": "Divideix mĆŗltiples fotos dins del PDF/foto" + }, + "sign": { + "title": "Signa", + "desc": "Afegeix signatura al PDF mitjanƧant dibuix, text o imatge" + }, + "flatten": { + "title": "Aplanar", + "desc": "Elimina tots els elements i formularis interactius d'un PDF" + }, + "repair": { + "title": "Reparar", + "desc": "Intenta reparar un PDF danyat o trencat" + }, + "removeBlanks": { + "title": "Elimina les pĆ gines en blanc", + "desc": "Detecta i elimina les pĆ gines en blanc d'un document" + }, + "removeAnnotations": { + "title": "Elimina Anotacions", + "desc": "Elimina tots els comentaris/anotacions d'un PDF" + }, + "compare": { + "title": "Compara", + "desc": "Compara i mostra les diferĆØncies entre 2 documents PDF" + }, + "certSign": { + "title": "Signa amb Certificat", + "desc": "Signa un PDF amb Certificat/Clau (PEM/P12)" + }, + "removeCertSign": { + "title": "Elimina Signatura de Certificat", + "desc": "Elimina la signatura de certificat d'un PDF" + }, + "pageLayout": { + "title": "Disposició Multi-PĆ gina", + "desc": "Fusiona diverses pĆ gines d'un document PDF en una sola pĆ gina" + }, + "scalePages": { + "title": "Ajusta la mida/escala de la pĆ gina", + "desc": "Canvia la mida/escala de la pĆ gina i/o del seu contingut." + }, + "pipeline": { + "title": "ProcĆ©s", + "desc": "Executa mĆŗltiples accions en PDFs definint scripts de procĆ©s" + }, + "add-page-numbers": { + "title": "Afegir NĆŗmeros de PĆ gina", + "desc": "Afegir nĆŗmeros de pĆ gina en una localització" + }, + "auto-rename": { + "title": "Canvia AutomĆ ticament el Nom del Fitxer PDF", + "desc": "Canvia automĆ ticament el nom d'un fitxer PDF en funció de la capƧalera detectada" + }, + "adjust-contrast": { + "title": "Ajusta Colors/Contrast", + "desc": "Ajusta colors/contrast, saturació i brillantor" + }, + "crop": { + "title": "Talla PDF", + "desc": "Talla PDF per reduir la mida (mantĆ© el text!)" + }, + "autoSplitPDF": { + "title": "Divisió AutomĆ tica de PĆ gines", + "desc": "Divideix automĆ ticament un PDF escanejat amb un codi QR de separació de pĆ gines escanejades" + }, + "sanitizePdf": { + "title": "Neteja", + "desc": "Elimina scripts i altres elements dels fitxers PDF" + }, + "URLToPDF": { + "title": "URL/Lloc Web a PDF", + "desc": "Converteix qualsevol URL http(s) a PDF" + }, + "HTMLToPDF": { + "title": "HTML a PDF", + "desc": "Converteix qualsevol fitxer HTML o arxiu comprimit a PDF" + }, + "MarkdownToPDF": { + "title": "Markdown a PDF", + "desc": "Converteix qualsevol fitxer Markdown a PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "Obteniu Tota la Informació sobre el PDF", + "desc": "Recupera tota la informació possible sobre els PDFs" + }, + "extractPage": { + "title": "Extreu pĆ gina(es)", + "desc": "Extreu pĆ gines seleccionades d'un PDF" + }, + "PdfToSinglePage": { + "title": "PDF a Una Sola PĆ gina Gran", + "desc": "Fusiona totes les pĆ gines d'un PDF en una sola pĆ gina gran" + }, + "showJS": { + "title": "Mostra Javascript", + "desc": "Cerca i mostra qualsevol JS injectat en un PDF" + }, + "autoRedact": { + "title": "Redacció AutomĆ tica", + "desc": "Redacta automĆ ticament (enfosqueix) text en un PDF basat en el text introduĆÆt" + }, + "redact": { + "title": "Redacció manual", + "desc": "Redacta un PDF segons el text seleccionat, les formes dibuixades i/o les pĆ gines seleccionades" + }, + "tableExtraxt": { + "title": "PDF a CSV", + "desc": "Extreu taules d'un PDF convertint-les a CSV" + }, + "autoSizeSplitPDF": { + "title": "Divisió AutomĆ tica per Mida/Quantitat", + "desc": "Divideix un Ćŗnic PDF en mĆŗltiples documents basant-se en la mida, el nombre de pĆ gines o el nombre de documents" + }, + "overlay-pdfs": { + "title": "Superposar PDFs", + "desc": "Superposa PDFs sobre un altre PDF" + }, + "split-by-sections": { + "title": "Divideix PDF per Seccions", + "desc": "Divideix cada pĆ gina d'un PDF en seccions horitzontals i verticals mĆ©s petites" + }, + "AddStampRequest": { + "title": "Afegeix segell al PDF", + "desc": "Afegeix segells de text o imatge en ubicacions establertes" + }, + "removeImagePdf": { + "title": "Elimina imatge", + "desc": "Elimina imatges d'un PDF per reduir la mida del fitxer" + }, + "splitPdfByChapters": { + "title": "Divideix PDF per CapĆ­tols", + "desc": "Divideix un PDF en mĆŗltiples fitxers segons la seva estructura de capĆ­tols." + }, + "validateSignature": { + "title": "Validar Signatura PDF", + "desc": "Verifica les signatures digitals i els certificats en documents PDF" + }, + "replaceColorPdf": { + "title": "ReemplaƧa i Inverteix Color", + "desc": "ReemplaƧa el color del text i el fons en un PDF i inverteix tot el color del PDF per reduir la mida del fitxer" + } + }, + "viewPdf": { + "tags": "veure,llegir,anotar,text,imatge", + "title": "View/Edit PDF", + "header": "Visualitza PDF" + }, + "multiTool": { + "tags": "Eina Multifunció,operacions mĆŗltiples,UI,clic i arrossega,costat frontal,client", + "title": "Eina multifunció de PDF", + "header": "Eina multifunció de PDF", + "uploadPrompts": "Nom del fitxer", + "selectAll": "Selecciona-ho tot", + "deselectAll": "Desselecciona-ho tot", + "selectPages": "Selecció de pĆ gines", + "selectedPages": "PĆ gines seleccionades", + "page": "PĆ gina", + "deleteSelected": "Suprimeix seleccionades", + "downloadAll": "Exporta", + "downloadSelected": "Exporta seleccionades", + "insertPageBreak": "Insereix un salt de pĆ gina", + "addFile": "Afegeix fitxer", + "rotateLeft": "Gira a l'esquerra", + "rotateRight": "Gira a la dreta", + "split": "Divideix", + "moveLeft": "Mou a l'esquerra", + "moveRight": "Mou a la dreta", + "delete": "Suprimeix", + "dragDropMessage": "PĆ gina(es) seleccionada(es)", + "undo": "DesfĆ©s", + "redo": "RefĆ©s" + }, + "merge": { + "tags": "fusió,operacions de pĆ gina,backend,servidor", + "title": "Fusiona", + "header": "Fusiona mĆŗltiples PDFs (2+)", + "sortByName": "Ordena per nom", + "sortByDate": "Ordena per data", + "removeCertSign": "Eliminar la signatura digital en el fitxer fusionat?", + "submit": "Fusiona" + }, + "split": { + "tags": "operacions de pĆ gina,divideix,Multi-PĆ gina,talla,servidor", + "title": "Divideix PDF", + "header": "Divideix PDF", + "desc": { + "1": "Els nĆŗmeros seleccionats indiquen les pĆ gines on vols realitzar la divisió", + "2": "Per exemple, seleccionant 1,3,7-9 dividiries un document de 10 pĆ gines en 6 PDFs separats amb:", + "3": "Document #1: PĆ gina 1", + "4": "Document #2: PĆ gina 2 i 3", + "5": "Document #3: PĆ gina 4, 5, 6 i 7", + "6": "Document #4: PĆ gina 8", + "7": "Document #5: PĆ gina 9", + "8": "Document #6: PĆ gina 10" + }, + "splitPages": "Introdueix les pĆ gines per dividir-les:", + "submit": "Divideix" + }, + "rotate": { + "tags": "servidor", + "title": "Rota PDF", + "header": "Rota PDF", + "selectAngle": "Selecciona l'angle de gir (en mĆŗltiples de 90 graus):", + "submit": "Rota" + }, + "imageToPdf": { + "tags": "conversió,img,jpg,imatge,foto" + }, + "pdfToImage": { + "tags": "conversió,img,jpg,imatge,foto", + "title": "PDF a Imatge", + "header": "PDF a Imatge", + "selectText": "Format d'Imatge", + "singleOrMultiple": "Tipus d'Imatge Resultant", + "single": "Única Imatge Gran", + "multi": "MĆŗltiples Imatges", + "colorType": "Tipus de Color", + "color": "Color", + "grey": "Escala de Grisos", + "blackwhite": "Blanc i Negre (Pot perdre dades!)", + "submit": "Converteix", + "info": "Python no estĆ  instalĀ·lat. Ɖs necessari per a la conversió a WebP.", + "placeholder": "(p. ex. 1,2,8 o 4,7,12-16 o 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,parells,senars,ordenar,moure", + "title": "Organitzador de PĆ gines", + "header": "Organitzador de PĆ gines PDF", + "submit": "Reorganitza PĆ gines", + "mode": { + "_value": "Mode", + "1": "Ordre Personalitzat de PĆ gines", + "2": "Ordre Invertit", + "3": "Classificació DĆŗplex", + "4": "Classificació en Llibret", + "5": "Classificació en Llibret de Puntada Lateral", + "6": "Divisió Parells-Senars", + "7": "Eliminar Primer", + "8": "Eliminar Últim", + "9": "Eliminar Primer i Últim", + "10": "Fusionar Parells-Senars", + "11": "Duplicate all pages" + }, + "placeholder": "(p. ex. 1,3,2 o 4-8,2,10-12 o 2n-1)" + }, + "addImage": { + "tags": "img,jpg,imatge,foto", + "title": "Afegir Imatge", + "header": "Afegir Imatge a PDF (en construcció)", + "everyPage": "Totes les pĆ gines?", + "upload": "Afegir Imatge", + "submit": "Afegir Imatge" + }, + "watermark": { + "tags": "text,repetició,etiqueta,propia,copyright,marca registrada,img,jpg,imatge,foto", + "title": "Afegir Marca d'Aigua", + "header": "Afegir Marca d'Aigua", + "customColor": "Color de Text Personalitzat", + "selectText": { + "1": "Selecciona el PDF per afegir la Marca d'Aigua:", + "2": "Text de la Marca d'Aigua", + "3": "Mida de la Font:", + "4": "Rotació (0-360):", + "5": "Separació d'amplada (Espai horitzontal entre cada Marca d'Aigua):", + "6": "Separació d'alƧada (Espai vertical entre cada Marca d'Aigua):", + "7": "Opacitat (0% - 100%):", + "8": "Tipus de Marca d'Aigua:", + "9": "Imatge de la Marca d'Aigua:", + "10": "Converteix PDF a PDF-Image" + }, + "submit": "Afegir Marca d'Aigua", + "type": { + "1": "Text", + "2": "Imatge" + } + }, + "permissions": { + "tags": "lectura,escriptura,editar,imprimir", + "title": "Canviar Permissos", + "header": "Canviar Permissos", + "warning": "AdvertĆØncia: per fer que aquests permisos siguin inalterables, es recomana establir-los amb una contrasenya a travĆ©s de la pĆ gina d'afegir contrasenya", + "selectText": { + "1": "Selecciona el PDF per Canviar Permissos", + "2": "Permissos a canviar", + "3": "Evita el muntatge del document", + "4": "Evita l'extracció de contingut", + "5": "Evita l'extracció de contingut per accessibilitat", + "6": "Evita emplenar formularis", + "7": "Evita modificacions", + "8": "Evita modificacions d'annotacions", + "9": "Evita impressió", + "10": "Evita impressió en diferents formats" + }, + "submit": "Canviar Permissos" + }, + "removePages": { + "tags": "eliminar pĆ gines,suprimir pĆ gines" + }, + "addPassword": { + "tags": "segur,seguretat", + "title": "Afegir Contrasenya", + "header": "Afegir contrasenya (Encriptat)", + "selectText": { + "1": "PDF a encriptar", + "2": "Contrasenya", + "3": "Longitud de la clau de xifratge", + "4": "Valors mĆ©s alts són mĆ©s forts, però els valors mĆ©s baixos tenen una millor compatibilitat.", + "5": "Permissos a Establir", + "6": "Evita el muntatge del document", + "7": "Evita l'extracció de contingut", + "8": "Evita l'extracció per accessibilitat", + "9": "Evita emplenar formularis", + "10": "Evita modificacions", + "11": "Evita modificacions d'annotacions", + "12": "Evita impressió", + "13": "Evita impressió en diferents formats", + "14": "Contrasenya d'Administrador", + "15": "Restringeix el que es pot fer amb el document un cop obert (No compatible amb tots els lectors)", + "16": "Restringeix l'obertura del document" + }, + "submit": "Encripta" + }, + "removePassword": { + "tags": "segur,desencripta,seguretat,eliminar contrasenya,suprimir contrasenya", + "title": "Eliminar Contrasenya", + "header": "Eliminar Contrasenya (Desxifrar)", + "selectText": { + "1": "Selecciona el PDF a Desxifrar", + "2": "Contrasenya" + }, + "submit": "Eliminar Contrasenya" + }, + "compressPdfs": { + "tags": "estrĆØnyer,petit,minĆŗscul" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "TĆ­tol,autor,data,creació,hora,editor,productor,estadĆ­stiques", + "title": "TĆ­tol:", + "header": "Canvia Metadades", + "selectText": { + "1": "Edita les variables a canviar", + "2": "Neteja totes les metadades", + "3": "Mostra Metadades Personalitzades:", + "4": "Altres Metadades:", + "5": "Afegir entrada personalitzada" + }, + "author": "Autor:", + "creationDate": "Data de Creació (yyyy/MM/dd HH:mm:ss):", + "creator": "Creador:", + "keywords": "Paraules clau:", + "modDate": "Data de Modificació (yyyy/MM/dd HH:mm:ss):", + "producer": "Productor:", + "subject": "Assumpte:", + "trapped": "Atrapat:", + "submit": "Canvia" + }, + "fileToPDF": { + "tags": "transformació,format,document,imatge,diapositiva,text,conversió,oficina,docs,word,excel,powerpoint", + "title": "Arxiu a PDF", + "header": "Converteix arxiu a PDF", + "credit": "Utilitza LibreOffice i Unoconv per a la conversió.", + "supportedFileTypesInfo": "Tipus de fitxers admesos", + "supportedFileTypes": "Els tipus de fitxers admesos haurien d'incloure els següents, però per obtenir una llista completa actualitzada dels formats compatibles, consulteu la documentació de LibreOffice", + "submit": "Converteix a PDF" + }, + "ocr": { + "tags": "reconeixement,text,imatge,escaneig,lectura,identificació,detecció,editable", + "title": "OCR / Neteja Escanejats", + "header": "Neteja Escanejats / OCR (Reconeixement ƒptic de CarĆ cters)", + "selectText": { + "1": "Selecciona els idiomes que s'han de detectar dins del PDF (els que s'indiquen són els detectats):", + "2": "Genera un fitxer de text que contingui el text OCR juntament amb el PDF editat per OCR", + "3": "Corregeix pĆ gines escanejades amb un angle esbiaixat girant-les a la seva posició correcta", + "4": "Neteja la pĆ gina, de manera que Ć©s menys probable que l'OCR trobi soroll de text de fons. (Sense canvis en la sortida)", + "5": "Neteja la pĆ gina, de manera que Ć©s menys probable que l'OCR trobi text en el soroll de fons, mantenint la neteja en la sortida.", + "6": "Ignora les pĆ gines que tenen text interactiu, nomĆ©s les pĆ gines OCR que són imatges", + "7": "ForƧa OCR, l'OCR de cada pĆ gina elimina tots els elements de text originals", + "8": "Normal (error si el PDF contĆ© text)", + "9": "Opcions Addicionals", + "10": "Mode OCR", + "11": "Elimina Imatges desprĆ©s de l'OCR (Elimina TOTES les imatges, Ćŗtil si forma part d'un procĆ©s de conversió)", + "12": "Tipus de Renderització (AvanƧat)" + }, + "help": "Llegeix aquesta documentació sobre com utilitzar-la per a altres idiomes i/o no utilitzar-la a Docker", + "credit": "Aquest servei fa servir qpdf i Tesseract per a OCR.", + "submit": "Processa PDF amb OCR" + }, + "extractImages": { + "tags": "imatge,foto,desa,arxiva,zip,captura,agafa", + "title": "Extreu Imatges", + "header": "Extreu Imatges", + "selectText": "Selecciona el format d'imatge al qual convertir les imatges extretes", + "allowDuplicates": "Desa imatges duplicades", + "submit": "Extreu" + }, + "pdfToPDFA": { + "tags": "arxiu,llarg termini,estĆ ndard,conversió,emmagatzematge,preservació", + "title": "PDF a PDF/A", + "header": "PDF a PDF/A", + "credit": "Utilitza libreoffice per a la conversió a PDF/A", + "submit": "Converteix", + "tip": "Actualment no funciona per a mĆŗltiples entrades al mateix temps", + "outputFormat": "Format de sortida", + "pdfWithDigitalSignature": "El PDF contĆ© una signatura digital. Aquesta serĆ  eliminada en el següent pas." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformació,format,conversió,oficina,microsoft,fitxer doc", + "title": "PDF a Word", + "header": "PDF a Word", + "selectText": { + "1": "Format d'Arxiu de Sortida" + }, + "credit": "Utilitza LibreOffice per a la conversió d'Arxius.", + "submit": "Converteix" + }, + "PDFToPresentation": { + "tags": "diapositives,presentació,oficina,microsoft", + "title": "PDF a Presentació", + "header": "PDF a Presentació", + "selectText": { + "1": "Format d'Arxiu de Sortida" + }, + "credit": "Utilitza LibreOffice per a la conversió d'Arxius.", + "submit": "Converteix" + }, + "PDFToText": { + "tags": "format ric,format de text ric,format de text enriquit", + "title": "PDF a Text/RTF", + "header": "PDF a Text/RTF", + "selectText": { + "1": "Format d'Arxiu de Sortida" + }, + "credit": "Utilitza LibreOffice per a la conversió d'Arxius.", + "submit": "Converteix" + }, + "PDFToHTML": { + "tags": "contingut web,compatible amb navegadors", + "title": "PDF a HTML", + "header": "PDF a HTML", + "credit": "Utilitza pdftohtml per a la conversió d'Arxius.", + "submit": "Converteix" + }, + "PDFToXML": { + "tags": "extracció de dades,contingut estructurat,interop,transformació,convertir", + "title": "PDF a XML", + "header": "PDF a XML", + "credit": "Utilitza LibreOffice per a la conversió d'Arxius.", + "submit": "Converteix" + }, + "ScannerImageSplit": { + "tags": "separa,detecció automĆ tica,escaneigs,multifoto,organitzar", + "selectText": { + "1": "Llindar d'angle:", + "2": "Estableix l'angle mĆ­nim absolut necessari perquĆØ la imatge es giri (per defecte: 10).", + "3": "TolerĆ ncia:", + "4": "Determina l'interval de variació de color al voltant del color de fons estimat (per defecte: 30).", + "5": "ƀrea MĆ­nima:", + "6": "Estableix el llindar d'Ć rea mĆ­nima per a una foto (per defecte: 10000).", + "7": "ƀrea de contorn mĆ­nima:", + "8": "Estableix el llindar mĆ­nim de l'Ć rea de contorn per a una foto", + "9": "Mida de Vora:", + "10": "Estableix la mida de la vora afegida i eliminada per evitar vores blanques a la sortida (per defecte: 1)." + }, + "info": "Python no estĆ  instalĀ·lat. Ɖs necessari per executar-ho." + }, + "sign": { + "tags": "autoritza,inicis,signatura dibuixada,signatura de text,signatura amb imatge", + "title": "Signa", + "header": "Signa els PDF", + "upload": "Penja la imatge", + "draw": "Dibuixa la signatura", + "text": "Entrada de text", + "clear": "Esborra", + "add": "Afegeix", + "saved": "Signatures Desades", + "save": "Desa Signatura", + "personalSigs": "Signatures Personals", + "sharedSigs": "Signatures Compartides", + "noSavedSigs": "No s'han trobat signatures desades", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "estĆ tic,desactivar,no interactiu,simplifica", + "title": "Aplanar", + "header": "Aplana els PDF", + "flattenOnlyForms": "Aplana nomĆ©s els formularis", + "submit": "Aplanar" + }, + "repair": { + "tags": "repara,restaura,correcció,recupera", + "title": "Reparar", + "header": "Repara els PDF", + "submit": "Reparar" + }, + "removeBlanks": { + "tags": "neteja,simplifica,sense contingut,organitza", + "title": "Elimina els espais en blanc", + "header": "Elimina les pĆ gines en blanc", + "threshold": "Llindar:", + "thresholdDesc": "Llindar per determinar el nivell de blanc que ha de tenir un pĆ­xel per considerar-lo blanc", + "whitePercent": "Percentatge de blanc (%):", + "whitePercentDesc": "Percentatge de la pĆ gina que ha de ser blanca per eliminar-la", + "submit": "Elimina els espais en blanc" + }, + "removeAnnotations": { + "tags": "comentaris,ressalta,notes,marcatge,elimina", + "title": "Elimina Anotacions", + "header": "Elimina Anotacions", + "submit": "Elimina" + }, + "compare": { + "tags": "diferencia,contrasta,canvis,anĆ lisi", + "title": "Comparar", + "header": "Compara PDF", + "highlightColor": { + "1": "Color de Ressaltat 1:", + "2": "Color de Ressaltat 2:" + }, + "document": { + "1": "Document 1", + "2": "Document 2" + }, + "submit": "Comparar", + "complex": { + "message": "Un o tots dos documents proporcionats són fitxers grans; la precisió de la comparació pot veure's reduĆÆda." + }, + "large": { + "file": { + "message": "Un o tots dos documents proporcionats són massa grans per ser processats." + } + }, + "no": { + "text": { + "message": "Un o tots dos dels PDFs seleccionats no tenen contingut de text. Si us plau, trieu PDFs amb text per a la comparació." + } + } + }, + "certSign": { + "tags": "autentica,PEM,P12,oficial,encripta", + "title": "Signatura amb Certificat", + "header": "Signa un PDF amb el teu certificat (Treball en curs)", + "selectPDF": "Seleccioneu un fitxer PDF per signar:", + "jksNote": "Nota: Si el vostre tipus de certificat no es troba a la llista, convertiu-lo a un fitxer de Java Keystore (.jks) utilitzant l'eina de lĆ­nia de comandes keytool. A continuació, trieu l'opció de fitxer .jks mĆ©s avall.", + "selectKey": "Seleccioneu el vostre fitxer de clau privada (format PKCS#8, podria ser .pem o .der):", + "selectCert": "Seleccioneu el vostre fitxer de certificat (format X.509, podria ser .pem o .der):", + "selectP12": "Seleccioneu el vostre fitxer de magatzem de claus PKCS#12 (.p12 o .pfx) (Opcional, si es proporciona, hauria de contenir la vostra clau privada i certificat):", + "selectJKS": "Seleccioneu el vostre fitxer de Java Keystore (.jks o .keystore):", + "certType": "Tipus de certificat", + "password": "IntroduĆÆu la contrasenya del vostre magatzem de claus o clau privada (si n'hi ha):", + "showSig": "Mostra la signatura", + "reason": "Motiu", + "location": "Ubicació", + "name": "Nom", + "showLogo": "Mostra el logotip", + "submit": "Signa PDF" + }, + "removeCertSign": { + "tags": "autentica,PEM,P12,oficial,desencripta", + "title": "Elimina la Signatura del Certificat", + "header": "Elimina el certificat digital del PDF", + "selectPDF": "Seleccioneu un fitxer PDF:", + "submit": "Elimina Signatura" + }, + "pageLayout": { + "tags": "fusió,composició,vista Ćŗnica,organitzar", + "title": "Disposició de MĆŗltiples PĆ gines", + "header": "Disposició de MĆŗltiples PĆ gines", + "pagesPerSheet": "PĆ gines per full:", + "addBorder": "Afegeix Marcs", + "submit": "Envia" + }, + "scalePages": { + "tags": "redimensionar,modificar,dimensió,adaptar", + "title": "Ajusta l'escala de la pĆ gina", + "header": "Ajusta l'escala de la pĆ gina", + "pageSize": "Mida d'una pĆ gina del document.", + "keepPageSize": "Mida Original", + "scaleFactor": "Nivell de zoom (retall) d'una pĆ gina.", + "submit": "Envia" + }, + "add-page-numbers": { + "tags": "pĆ gina,etiqueta,organitza,indexa" + }, + "auto-rename": { + "tags": "autodetect,basat en capƧalera,organitzar,reetiquetar", + "title": "Canvi de Nom AutomĆ tic", + "header": "Canvi de Nom AutomĆ tic de PDF", + "submit": "Canvi de Nom AutomĆ tic" + }, + "adjust-contrast": { + "tags": "correcció de color,ajustar,modificar,millorar" + }, + "crop": { + "tags": "retallar,reduir,editar,donar forma", + "title": "Talla", + "header": "Talla PDF", + "submit": "Envia" + }, + "autoSplitPDF": { + "tags": "basat en QR,separar,segmentació d'escaneig,organitzar", + "title": "Divisió AutomĆ tica de PDF", + "header": "Divisió AutomĆ tica de PDF", + "description": "Imprimeix, insereix, escaneja, puja i deixa que el sistema separi automĆ ticament els teus documents. No cal ordenar manualment.", + "selectText": { + "1": "Imprimeix algunes fulles divisòries de les opcions següents (en blanc i negre estĆ  bĆ©).", + "2": "Escaneja tots els teus documents alhora inserint una fulla divisòria entre cada document.", + "3": "Puja el fitxer PDF escanejat gran i deixa que Stirling PDF faci la resta.", + "4": "Les pĆ gines divisòries es detecten i eliminen automĆ ticament, garantint un document final ordenat." + }, + "formPrompt": "Envia un PDF que contingui les pĆ gines divisòries de Stirling-PDF:", + "duplexMode": "Mode DĆŗplex (Escaneig de davant i darrere)", + "dividerDownload2": "Descarrega 'Divisor AutomĆ tic (amb instruccions).pdf'", + "submit": "Envia" + }, + "sanitizePdf": { + "tags": "netejar,segur,sense riscos,eliminar amenaces" + }, + "URLToPDF": { + "tags": "captura web,desa pĆ gina,web a document,arxiu", + "title": "URL a PDF", + "header": "URL a PDF", + "submit": "Converteix", + "credit": "Utilitza WeasyPrint" + }, + "HTMLToPDF": { + "tags": "marcatge,contingut web,transformació,convertir", + "title": "HTML a PDF", + "header": "HTML a PDF", + "help": "Accepta fitxers HTML i arxius ZIP que contenen html/css/imatges, etc. necessaris", + "submit": "Converteix", + "credit": "Utilitza WeasyPrint", + "zoom": "Nivell de zoom per mostrar el lloc web.", + "pageWidth": "Amplada de la pĆ gina en centĆ­metres. (En blanc per defecte)", + "pageHeight": "AlƧada de la pĆ gina en centĆ­metres. (En blanc per defecte)", + "marginTop": "Margen superior de la pĆ gina en milĀ·lĆ­metres. (En blanc per defecte)", + "marginBottom": "Marge inferior de la pĆ gina en milĀ·lĆ­metres. (En blanc per defecte)", + "marginLeft": "Marge esquerre de la pĆ gina en milĀ·lĆ­metres. (En blanc per defecte)", + "marginRight": "Marge dret de la pĆ gina en milĀ·lĆ­metres. (En blanc per defecte)", + "printBackground": "Renderitza el fons dels llocs web.", + "defaultHeader": "Habilita la CapƧalera per Defecte (Nom i nĆŗmero de pĆ gina)", + "cssMediaType": "Canvia el tipus de mitjĆ  CSS de la pĆ gina.", + "none": "Cap", + "print": "Imprimir", + "screen": "Pantalla" + }, + "MarkdownToPDF": { + "tags": "marcatge,contingut web,transformació,convertir", + "title": "Markdown To PDF", + "header": "Markdown To PDF", + "submit": "Converteix", + "help": "Treball en curs", + "credit": "Utilitza WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "marcatge,contingut web,transformació,convertir,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "informació,dades,estadĆ­stiques,estadĆ­stiques", + "title": "Obteniu Informació del PDF", + "header": "Obteniu Informació del PDF", + "submit": "Obteniu Informació", + "downloadJson": "Descarrega JSON" + }, + "extractPage": { + "tags": "extreure" + }, + "PdfToSinglePage": { + "tags": "pĆ gina Ćŗnica" + }, + "showJS": { + "tags": "JS", + "title": "Mostra Javascript", + "header": "Mostra Javascript", + "downloadJS": "Descarrega Javascript", + "submit": "Mostra" + }, + "autoRedact": { + "tags": "Redactar,Amagar,ressaltar en negre,negre,marcador,ocult", + "title": "Redacció AutomĆ tica", + "header": "Redacció AutomĆ tica", + "colorLabel": "Color", + "textsToRedactLabel": "Text a Redactar (separat per lĆ­nies)", + "textsToRedactPlaceholder": "p. ex. \\nConfidencial \\nMolt Secret", + "useRegexLabel": "Utilitza Regex", + "wholeWordSearchLabel": "Cerca de Paraula Completa", + "customPaddingLabel": "Espai Extra Personalitzat", + "convertPDFToImageLabel": "Converteix PDF a Imatge PDF (S'utilitza per eliminar text darrere del quadre)", + "submitButton": "Envia" + }, + "redact": { + "tags": "Redactar,Amagar,ressaltar en negre,negre,marcador,ocult,manual", + "title": "Redacció manual", + "header": "Redacció manual", + "submit": "Redacta", + "textBasedRedaction": "Redacció basada en text", + "pageBasedRedaction": "Redacció basada en pĆ gines", + "convertPDFToImageLabel": "Converteix PDF a PDF-imatge (utilitzat per eliminar text darrere del quadre)", + "pageRedactionNumbers": { + "title": "PĆ gines", + "placeholder": "(p. ex. 1,2,8 o 4,7,12-16 o 2n-1)" + }, + "redactionColor": { + "title": "Color de redacció" + }, + "export": "Exporta", + "upload": "Puja", + "boxRedaction": "Redacció amb dibuix de quadre", + "zoom": "Zoom", + "zoomIn": "Apropa", + "zoomOut": "Allunya", + "nextPage": "PĆ gina següent", + "previousPage": "PĆ gina anterior", + "toggleSidebar": "Commuta la barra lateral", + "showThumbnails": "Mostra miniatures", + "showDocumentOutline": "Mostra l'esquema del document (doble clic per expandir/contraure tots els elements)", + "showAttatchments": "Mostra els adjunts", + "showLayers": "Mostra les capes (doble clic per restablir totes les capes a l'estat per defecte)", + "colourPicker": "Selector de colors", + "findCurrentOutlineItem": "Troba l'element actual de l'esquema", + "applyChanges": "Aplica els canvis" + }, + "tableExtraxt": { + "tags": "CSV,Extracció de taules,extreure,convertir" + }, + "autoSizeSplitPDF": { + "tags": "pdf,dividir,document,organització" + }, + "overlay-pdfs": { + "tags": "Superposició", + "header": "Superposar Fitxers PDF", + "baseFile": { + "label": "Selecciona el Fitxer PDF Base" + }, + "overlayFiles": { + "label": "Selecciona els Fitxers PDF a Superposar" + }, + "mode": { + "label": "Selecciona el Mode de Superposició", + "sequential": "Superposició Seqüencial", + "interleaved": "Superposició Intercalada", + "fixedRepeat": "Superposició de Repte Fix" + }, + "counts": { + "label": "Nombre de Superposicions (per al Mode de Repte Fix)", + "placeholder": "Introdueix els nombres separats per comes (p. ex., 2,3,1)" + }, + "position": { + "label": "Selecciona la Posició de la Superposició", + "foreground": "Primer pla", + "background": "Fons" + }, + "submit": "Envia" + }, + "split-by-sections": { + "tags": "Divisió per seccions,Divideix,Personalitza", + "title": "Divideix PDF per Seccions", + "header": "Divideix el PDF en Seccions", + "horizontal": { + "label": "Divisions Horitzontals", + "placeholder": "Introdueix el nombre de divisions horitzontals" + }, + "vertical": { + "label": "Divisions Verticals", + "placeholder": "Introdueix el nombre de divisions verticals" + }, + "submit": "Divideix PDF", + "merge": "Fusiona en un sol PDF" + }, + "AddStampRequest": { + "tags": "Segell, Afegeix imatge, Centra imatge, Marca d'aigua, PDF, Insereix, Personalitza", + "header": "Segella PDF", + "title": "Segella PDF", + "stampType": "Tipus de Segell", + "stampText": "Text del Segell", + "stampImage": "Imatge del Segell", + "alphabet": "Alfabet", + "fontSize": "Mida de la Font/Imatge", + "rotation": "Rotació", + "opacity": "Opacitat", + "position": "Posició", + "overrideX": "Modifica la Coordenada X", + "overrideY": "Modifica la Coordenada Y", + "customMargin": "Marge Personalitzat", + "customColor": "Color de Text Personalitzat", + "submit": "Envia" + }, + "removeImagePdf": { + "tags": "Elimina imatge,Operacions de pĆ gina,Back-end,Servidor" + }, + "splitPdfByChapters": { + "tags": "dividir,capĆ­tols,marcadors,organitza" + }, + "validateSignature": { + "tags": "signatura,verifica,valida,pdf,certificat,signatura digital,Validar signatura,Validar certificat", + "title": "Validar Signatures PDF", + "header": "Validar Signatures Digitals", + "selectPDF": "Selecciona fitxer PDF signat", + "submit": "Validar Signatures", + "results": "Resultats de Validació", + "status": { + "_value": "Estat", + "valid": "VĆ lid", + "invalid": "InvĆ lid" + }, + "signer": "Signant", + "date": "Data", + "reason": "Motiu", + "location": "Ubicació", + "noSignatures": "No s'han trobat signatures digitals en aquest document", + "chain": { + "invalid": "La validació de la cadena de certificats ha fallat - no es pot verificar la identitat del signant" + }, + "trust": { + "invalid": "El certificat no es troba en el magatzem de confianƧa - no es pot verificar la font" + }, + "cert": { + "expired": "El certificat ha expirat", + "revoked": "El certificat ha estat revocat", + "info": "Detalls del Certificat", + "issuer": "Emissor", + "subject": "Assumpte", + "serialNumber": "NĆŗmero de sĆØrie", + "validFrom": "VĆ lid des de", + "validUntil": "VĆ lid fins a", + "algorithm": "Algorisme", + "keySize": "Mida de la clau", + "version": "Versió", + "keyUsage": "Ús de la clau", + "selfSigned": "Autofirmat", + "bits": "bits" + }, + "signature": { + "info": "Informació de la Signatura", + "_value": "Signatura", + "mathValid": "La signatura Ć©s matemĆ ticament vĆ lida, PERƒ:" + }, + "selectCustomCert": "Fitxer de Certificat Personalitzat X.509 (Opcional)" + }, + "replace-color": { + "title": "ReemplaƧa-Inverteix-Color", + "header": "ReemplaƧa-Inverteix Color en PDF", + "selectText": { + "1": "Opcions per ReemplaƧar o Invertir color", + "2": "Per defecte (Colors d'alt contrast per defecte)", + "3": "Personalitzat (Colors personalitzats)", + "4": "Inversió completa (Inverteix tots els colors)", + "5": "Opcions de color d'alt contrast", + "6": "Text blanc sobre fons negre", + "7": "Text negre sobre fons blanc", + "8": "Text groc sobre fons negre", + "9": "Text verd sobre fons negre", + "10": "Tria el color del text", + "11": "Tria el color del fons" + }, + "submit": "ReemplaƧa" + }, + "replaceColorPdf": { + "tags": "ReemplaƧa Color,Operacions de pĆ gina,Back end,Costat servidor" + }, + "login": { + "title": "Accedir", + "header": "Accedir", + "signin": "Accedir", + "rememberme": "Recordar", + "invalid": "Nom d'usuari/contrasenya no vĆ lid", + "locked": "Compte bloquejat", + "signinTitle": "Autenticat", + "ssoSignIn": "Inicia sessió mitjanƧant inici de sessió Ćŗnic", + "oAuth2AutoCreateDisabled": "La creació automĆ tica d'usuaris OAUTH2 estĆ  desactivada", + "oAuth2AdminBlockedUser": "El registre o inici de sessió d'usuaris no registrats estĆ  actualment bloquejat. Si us plau, contacta amb l'administrador.", + "oauth2RequestNotFound": "SolĀ·licitud d'autorització no trobada", + "oauth2InvalidUserInfoResponse": "Resposta d'informació d'usuari no vĆ lida", + "oauth2invalidRequest": "SolĀ·licitud no vĆ lida", + "oauth2AccessDenied": "AccĆ©s denegat", + "oauth2InvalidTokenResponse": "Resposta de token no vĆ lida", + "oauth2InvalidIdToken": "ID Token no vĆ lid", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "L'usuari estĆ  desactivat, l'inici de sessió estĆ  actualment bloquejat amb aquest nom d'usuari. Si us plau, contacta amb l'administrador.", + "alreadyLoggedIn": "Ja has iniciat sessió a", + "alreadyLoggedIn2": "dispositius. Si us plau, tanca la sessió en els dispositius i torna-ho a intentar.", + "toManySessions": "Tens massa sessions actives", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF a PĆ gina Única", + "header": "PDF a PĆ gina Única", + "submit": "Converteix a PĆ gina Única" + }, + "pageExtracter": { + "title": "Extreu PĆ gines", + "header": "Extreu PĆ gines", + "submit": "Extreu", + "placeholder": "(p. ex. 1,2,8 o 4,7,12-16 o 2n-1)" + }, + "sanitizePDF": { + "title": "Neteja PDF", + "header": "Neteja un fitxer PDF", + "selectText": { + "1": "Elimina accions JavaScript", + "2": "Elimina fitxers incrustats", + "3": "Remove XMP metadata", + "4": "Elimina enllaƧos", + "5": "Elimina fonts", + "6": "Remove Document Info Metadata" + }, + "submit": "Neteja PDF" + }, + "adjustContrast": { + "title": "Ajusta el Contrast", + "header": "Ajusta el Contrast", + "contrast": "Contrast:", + "brightness": "Brillantor:", + "saturation": "Saturació:", + "download": "Descarrega" + }, + "compress": { + "title": "Comprimir", + "header": "Comprimir PDF", + "credit": "Aquest servei utilitza qpdf per a la compressió/optimització de PDF.", + "grayscale": { + "label": "Aplicar escala de grisos per a la compressió" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Nivell d'optimització:", + "4": "Mode automĆ tic: ajusta automĆ ticament la qualitat perquĆØ el PDF tingui la mida exacta", + "5": "Mida esperada del PDF (p. ex. 25 MB, 10,8 MB, 25 KB)" + }, + "submit": "Comprimir" + }, + "decrypt": { + "passwordPrompt": "Aquest fitxer estĆ  protegit amb contrasenya. Si us plau, introdueix la contrasenya:", + "cancelled": "Operació cancelĀ·lada per al PDF: {0}", + "noPassword": "No s'ha proporcionat cap contrasenya per al PDF xifrat: {0}", + "invalidPassword": "Si us plau, torna-ho a intentar amb la contrasenya correcta.", + "invalidPasswordHeader": "Contrasenya incorrecta o xifratge no compatible per al PDF: {0}", + "unexpectedError": "S'ha produĆÆt un error en processar el fitxer. Si us plau, torna-ho a intentar.", + "serverError": "Error del servidor en desxifrar: {0}", + "success": "Fitxer desxifrat correctament." + }, + "multiTool-advert": { + "message": "Aquesta funcionalitat tambĆ© estĆ  disponible a la nostra pĆ gina d'eines mĆŗltiples. Fes-hi una ullada per obtenir una interfĆ­cie millorada per pĆ gina i funcions addicionals!" + }, + "pageRemover": { + "title": "Eliminació de PĆ gines", + "header": "Eliminació de PĆ gines PDF", + "pagesToDelete": "PĆ gines a eliminar (NĆŗmeros de pĆ gines):", + "submit": "Esborra PĆ gines", + "placeholder": "(p. ex. 1,2,6 o 1-10,15-30)" + }, + "imageToPDF": { + "title": "Imatge a PDF", + "header": "Imatge a PDF", + "submit": "Converteix", + "selectLabel": "Opcions d'Ajust de la Imatge", + "fillPage": "Omple la PĆ gina", + "fitDocumentToImage": "Ajusta la PĆ gina a la Imatge", + "maintainAspectRatio": "MantĆ© la Proporció de la Imatge", + "selectText": { + "2": "Rota automĆ ticament el PDF", + "3": "Lògica de diversos fitxers (nomĆ©s estĆ  activada si es treballa amb diverses imatges)", + "4": "Combina en un Ćŗnic PDF", + "5": "Converteix per separar els PDFs" + } + }, + "PDFToCSV": { + "title": "PDF a CSV", + "header": "PDF a CSV", + "prompt": "Selecciona la pĆ gina per extreure la taula", + "submit": "Extreu" + }, + "split-by-size-or-count": { + "title": "Divideix PDF per Mida o Nombre", + "header": "Divideix PDF per Mida o Nombre", + "type": { + "label": "Selecciona el Tipus de Divisió", + "size": "Per Mida", + "pageCount": "Per Nombre de PĆ gines", + "docCount": "Per Nombre de Documents" + }, + "value": { + "label": "Introdueix el Valor", + "placeholder": "Introdueix la mida (p. ex., 2MB o 3KB) o el nombre (p. ex., 5)" + }, + "submit": "Envia" + }, + "printFile": { + "title": "Imprimir Fitxer", + "header": "Imprimir Fitxer a la Impresora", + "selectText": { + "1": "Selecciona el Fitxer per Imprimir", + "2": "Introdueix el Nom de la Impresora" + }, + "submit": "Imprimir" + }, + "licenses": { + "nav": "LlicĆØncies", + "title": "LlicĆØncies de Tercers", + "header": "LlicĆØncies de Tercers", + "module": "Mòdul", + "version": "Versió", + "license": "LlicĆØncia" + }, + "survey": { + "nav": "Enquesta", + "title": "Enquesta Stirling-PDF", + "description": "Stirling-PDF no fa seguiment, aixĆ­ que volem escoltar els nostres usuaris per millorar Stirling-PDF!", + "changes": "Stirling-PDF ha canviat des de l'Ćŗltima enquesta! Per saber-ne mĆ©s, consulta la nostra publicació al blog aquĆ­:", + "changes2": "Amb aquests canvis, estem rebent suport empresarial i finanƧament", + "please": "Si us plau, considera fer la nostra enquesta!", + "disabled": "(El popup de l'enquesta es desactivarĆ  en les següents actualitzacions, però estarĆ  disponible al peu de la pĆ gina)", + "button": "Fes l'Enquesta", + "dontShowAgain": "No mostrar mĆ©s", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Eliminar imatge", + "header": "Eliminar imatge", + "removeImage": "Eliminar imatge", + "submit": "Eliminar imatge" + }, + "splitByChapters": { + "title": "Divideix PDF per CapĆ­tols", + "header": "Divideix PDF per CapĆ­tols", + "bookmarkLevel": "Nivell de Marcadors", + "includeMetadata": "Incloure Metadades", + "allowDuplicates": "Permetre Duplicats", + "desc": { + "1": "Aquesta eina divideix un fitxer PDF en diversos PDFs segons l'estructura dels seus capĆ­tols.", + "2": "Nivell de Marcadors: Tria el nivell de marcadors que s'utilitzarĆ  per dividir (0 per al nivell superior, 1 per al segon nivell, etc.).", + "3": "Incloure Metadades: Si estĆ  marcat, les metadades del PDF original s'inclouran en cada PDF dividit.", + "4": "Permetre Duplicats: Si estĆ  marcat, permet diversos marcadors a la mateixa pĆ gina per crear PDFs separats." + }, + "submit": "Divideix PDF" + }, + "fileChooser": { + "click": "Clica", + "or": "o", + "dragAndDrop": "Arrossega i deixa anar", + "dragAndDropPDF": "Arrossega i deixa anar un fitxer PDF", + "dragAndDropImage": "Arrossega i deixa anar un fitxer d'imatge", + "hoveredDragAndDrop": "Arrossega i deixa anar fitxer(s) aquĆ­", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "LlanƧaments", + "title": "Notes de LlanƧament", + "header": "Notes de LlanƧament", + "current": { + "version": "LlanƧament Actual" + }, + "note": "Les notes de llanƧament nomĆ©s estan disponibles en anglĆØs" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/cs-CZ/translation.json b/frontend/public/locales/cs-CZ/translation.json new file mode 100644 index 000000000..799b422e6 --- /dev/null +++ b/frontend/public/locales/cs-CZ/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Velikost pĆ­sma", + "fontName": "NĆ”zev pĆ­sma", + "title": "Přidat čƭsla strĆ”nek", + "header": "Přidat čƭsla strĆ”nek", + "selectText": { + "1": "Vyberte PDF soubor:", + "2": "Velikost okraje", + "3": "Pozice", + "4": "PoÄĆ”tečnĆ­ čƭslo", + "5": "StrĆ”nky k čƭslovĆ”nĆ­", + "6": "VlastnĆ­ text" + }, + "customTextDesc": "VlastnĆ­ text", + "numberPagesDesc": "KterĆ© strĆ”nky čƭslovat, výchozĆ­ je 'vÅ”echny', takĆ© přijĆ­mĆ” 1-5 nebo 2,5,9 atd.", + "customNumberDesc": "VýchozĆ­ je {n}, takĆ© přijĆ­mĆ” 'StrĆ”nka {n} z {total}', 'Text-{n}', '{filename}-{n}'", + "submit": "Přidat čƭsla strĆ”nek" + }, + "pdfPrompt": "Vyberte PDF soubor(y)", + "multiPdfPrompt": "Vyberte PDF soubory (2+)", + "multiPdfDropPrompt": "Vyberte (nebo přetĆ”hněte) vÅ”echny požadovanĆ© PDF soubory", + "imgPrompt": "Vyberte obrĆ”zek(y)", + "genericSubmit": "Odeslat", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "UpozorněnĆ­: Tento proces může trvat až minutu v zĆ”vislosti na velikosti souboru", + "pageOrderPrompt": "VlastnĆ­ pořadĆ­ strĆ”nek (Zadejte seznam čƭsel strĆ”nek oddělených ÄĆ”rkou nebo funkci jako např. 2n+1):", + "pageSelectionPrompt": "VlastnĆ­ výběr strĆ”nek (Zadejte seznam čƭsel strĆ”nek oddělených ÄĆ”rkou jako 1,5,6 nebo funkci jako např. 2n+1):", + "goToPage": "PřejĆ­t", + "true": "Ano", + "false": "Ne", + "unknown": "NeznĆ”mý", + "save": "Uložit", + "saveToBrowser": "Uložit do prohlížeče", + "close": "Zavřít", + "filesSelected": "vybraných souborÅÆ", + "noFavourites": "ŽÔdnĆ© oblĆ­benĆ© položky nebyly přidĆ”ny", + "downloadComplete": "StahovĆ”nĆ­ dokončeno", + "bored": "NudĆ­te se při čekĆ”nĆ­?", + "alphabet": "Abeceda", + "downloadPdf": "StĆ”hnout PDF", + "text": "Text", + "font": "PĆ­smo", + "selectFillter": "-- Vybrat --", + "pageNum": "Číslo strĆ”nky", + "sizes": { + "small": "MalĆ©", + "medium": "StřednĆ­", + "large": "VelkĆ©", + "x-large": "Extra velkĆ©" + }, + "error": { + "pdfPassword": "PDF dokument je chrĆ”něn heslem a buď heslo nebylo zadĆ”no, nebo bylo nesprĆ”vnĆ©", + "_value": "Chyba", + "sorry": "OmlouvĆ”me se za problĆ©m!", + "needHelp": "Potřebujete pomoc / NaÅ”li jste problĆ©m?", + "contactTip": "Pokud stĆ”le mĆ”te potíže, nevĆ”hejte nĆ”s kontaktovat. Můžete podat ticket na naÅ”em GitHubu nebo nĆ”s kontaktovat přes Discord:", + "404": { + "head": "404 - StrĆ”nka nenalezena | Ups, zakopli jsme v kódu!", + "1": "Nemůžeme najĆ­t strĆ”nku, kterou hledĆ”te.", + "2": "Něco se pokazilo" + }, + "github": "Podat ticket na GitHubu", + "showStack": "Zobrazit trasovĆ”nĆ­ zĆ”sobnĆ­ku", + "copyStack": "KopĆ­rovat trasovĆ”nĆ­ zĆ”sobnĆ­ku", + "githubSubmit": "GitHub - Podat ticket", + "discordSubmit": "Discord - Podat příspěvek podpory" + }, + "delete": "Smazat", + "username": "UživatelskĆ© jmĆ©no", + "password": "Heslo", + "welcome": "VĆ­tejte", + "property": "Vlastnost", + "black": "ČernĆ”", + "white": "BĆ­lĆ”", + "red": "ČervenĆ”", + "green": "ZelenĆ”", + "blue": "ModrĆ”", + "custom": "VlastnĆ­...", + "WorkInProgess": "PrĆ”ce probĆ­hĆ”, nemusĆ­ fungovat nebo může obsahovat chyby. ProsĆ­m, nahlaste případnĆ© problĆ©my!", + "poweredBy": "VyužívĆ”", + "yes": "Ano", + "no": "Ne", + "changedCredsMessage": "PřihlaÅ”ovacĆ­ Ćŗdaje byly změněny!", + "notAuthenticatedMessage": "Uživatel nenĆ­ přihlÔŔen.", + "userNotFoundMessage": "Uživatel nebyl nalezen.", + "incorrectPasswordMessage": "SoučasnĆ© heslo nenĆ­ sprĆ”vnĆ©.", + "usernameExistsMessage": "NovĆ© uživatelskĆ© jmĆ©no již existuje.", + "invalidUsernameMessage": "NeplatnĆ© uživatelskĆ© jmĆ©no, může obsahovat pouze pĆ­smena, čƭslice a nĆ”sledujĆ­cĆ­ speciĆ”lnĆ­ znaky @._+- nebo musĆ­ být platnĆ” e-mailovĆ” adresa.", + "invalidPasswordMessage": "Heslo nesmĆ­ být prĆ”zdnĆ© a nesmĆ­ obsahovat mezery na zaÄĆ”tku nebo konci.", + "confirmPasswordErrorMessage": "NovĆ© heslo a potvrzenĆ­ novĆ©ho hesla se musĆ­ shodovat.", + "deleteCurrentUserMessage": "Nelze smazat prĆ”vě přihlÔŔenĆ©ho uživatele.", + "deleteUsernameExistsMessage": "UživatelskĆ© jmĆ©no neexistuje a nelze ho smazat.", + "downgradeCurrentUserMessage": "Nelze snížit roli současnĆ©ho uživatele", + "disabledCurrentUserMessage": "Současný uživatel nemůže být deaktivovĆ”n", + "downgradeCurrentUserLongMessage": "Nelze snížit roli současnĆ©ho uživatele. Proto současný uživatel nebude zobrazen.", + "userAlreadyExistsOAuthMessage": "Uživatel již existuje jako OAuth2 uživatel.", + "userAlreadyExistsWebMessage": "Uživatel již existuje jako webový uživatel.", + "oops": "Jejda!", + "help": "NĆ”pověda", + "goHomepage": "PřejĆ­t na domovskou strĆ”nku", + "joinDiscord": "Připojte se k naÅ”emu Discord serveru", + "seeDockerHub": "ProhlĆ©dněte si Docker Hub", + "visitGithub": "NavÅ”tivte Github repozitÔř", + "donate": "Přispějte", + "color": "Barva", + "sponsor": "Sponzor", + "info": "Informace", + "pro": "Pro", + "page": "StrĆ”nka", + "pages": "StrĆ”nky", + "loading": "NačƭtĆ”nĆ­...", + "addToDoc": "Přidat do dokumentu", + "reset": "Obnovit", + "apply": "Použít", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "ZĆ”sady ochrany osobnĆ­ch ĆŗdajÅÆ", + "terms": "PodmĆ­nky použitĆ­", + "accessibility": "Přístupnost", + "cookie": "ZĆ”sady používĆ”nĆ­ cookies", + "impressum": "TirÔž", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Menu Pipeline (Beta)", + "uploadButton": "NahrĆ”t vlastnĆ­", + "configureButton": "Konfigurovat", + "defaultOption": "VlastnĆ­", + "submitButton": "Odeslat", + "help": "NĆ”pověda k pipeline", + "scanHelp": "NĆ”pověda ke skenovĆ”nĆ­ složek", + "deletePrompt": "Opravdu chcete smazat tento pipeline?", + "tags": "automatizovat,sekvence,skriptovanĆ©,dĆ”vkovĆ©-zpracovĆ”nĆ­", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Konfigurace pipeline", + "pipelineNameLabel": "NĆ”zev pipeline", + "saveSettings": "Uložit nastavenĆ­ operace", + "pipelineNamePrompt": "Zde zadejte nĆ”zev pipeline", + "selectOperation": "Vybrat operaci", + "addOperationButton": "Přidat operaci", + "pipelineHeader": "Pipeline:", + "saveButton": "StĆ”hnout", + "validateButton": "Ověřit" + }, + "enterpriseEdition": { + "button": "Upgradovat na Pro", + "warning": "Tato funkce je dostupnĆ” pouze pro uživatele Pro.", + "yamlAdvert": "Stirling PDF Pro podporuje konfiguračnĆ­ soubory YAML a dalŔí funkce SSO.", + "ssoAdvert": "HledĆ”te vĆ­ce funkcĆ­ pro sprĆ”vu uživatelÅÆ? PodĆ­vejte se na Stirling PDF Pro" + }, + "analytics": { + "title": "Chcete pomoci vylepÅ”it Stirling PDF?", + "paragraph1": "Stirling PDF nabĆ­zĆ­ volitelnou analytiku, kterĆ” nĆ”m pomĆ”hĆ” zlepÅ”ovat produkt. Nesledujeme žÔdnĆ© osobnĆ­ Ćŗdaje ani obsah souborÅÆ.", + "paragraph2": "Zvažte prosĆ­m povolenĆ­ analytiky, abyste pomohli rÅÆstu Stirling-PDF a umožnili nĆ”m lĆ©pe porozumět naÅ”im uživatelÅÆm.", + "enable": "Povolit analytiku", + "disable": "ZakĆ”zat analytiku", + "settings": "NastavenĆ­ analytiky můžete změnit v souboru config/settings.yml" + }, + "navbar": { + "favorite": "OblĆ­benĆ©", + "recent": "New and recently updated", + "darkmode": "Tmavý režim", + "language": "Jazyky", + "settings": "NastavenĆ­", + "allTools": "NĆ”stroje", + "multiTool": "VĆ­ce nĆ”strojÅÆ", + "search": "Hledat", + "sections": { + "organize": "UspořÔdat", + "convertTo": "PřevĆ©st do PDF", + "convertFrom": "PřevĆ©st z PDF", + "security": "Podpis a zabezpečenĆ­", + "advance": "PokročilĆ©", + "edit": "Zobrazit a upravit", + "popular": "OblĆ­benĆ©" + } + }, + "settings": { + "title": "NastavenĆ­", + "update": "K dispozici je aktualizace", + "updateAvailable": "{0} je aktuĆ”lně nainstalovanĆ” verze. Je k dispozici novĆ” verze ({1}).", + "appVersion": "Verze aplikace:", + "downloadOption": { + "title": "Vyberte možnost stahovĆ”nĆ­ (Pro stahovĆ”nĆ­ jednoho souboru bez zipu):", + "1": "Otevřít ve stejnĆ©m okně", + "2": "Otevřít v novĆ©m okně", + "3": "StĆ”hnout soubor" + }, + "zipThreshold": "Zazipovat soubory, když počet stahovaných souborÅÆ přesĆ”hne", + "signOut": "OdhlĆ”sit se", + "accountSettings": "NastavenĆ­ ĆŗÄtu", + "bored": { + "help": "PovolĆ­ velikonočnĆ­ vajƭčko hry" + }, + "cacheInputs": { + "name": "UklĆ”dat vstupy formulÔřů", + "help": "PovolĆ­ uklĆ”dĆ”nĆ­ dříve použitých vstupÅÆ pro budoucĆ­ použitĆ­" + } + }, + "changeCreds": { + "title": "Změnit přihlaÅ”ovacĆ­ Ćŗdaje", + "header": "Aktualizovat Ćŗdaje vaÅ”eho ĆŗÄtu", + "changePassword": "PoužívĆ”te výchozĆ­ přihlaÅ”ovacĆ­ Ćŗdaje. Zadejte prosĆ­m novĆ© heslo", + "newUsername": "NovĆ© uživatelskĆ© jmĆ©no", + "oldPassword": "SoučasnĆ© heslo", + "newPassword": "NovĆ© heslo", + "confirmNewPassword": "Potvrdit novĆ© heslo", + "submit": "Potvrdit změny" + }, + "account": { + "title": "NastavenĆ­ ĆŗÄtu", + "accountSettings": "NastavenĆ­ ĆŗÄtu", + "adminSettings": "NastavenĆ­ sprĆ”vce - Zobrazit a přidat uživatele", + "userControlSettings": "NastavenĆ­ ovlĆ”dĆ”nĆ­ uživatelÅÆ", + "changeUsername": "Změnit uživatelskĆ© jmĆ©no", + "newUsername": "NovĆ© uživatelskĆ© jmĆ©no", + "password": "PotvrzovacĆ­ heslo", + "oldPassword": "StarĆ© heslo", + "newPassword": "NovĆ© heslo", + "changePassword": "Změnit heslo", + "confirmNewPassword": "Potvrdit novĆ© heslo", + "signOut": "OdhlĆ”sit se", + "yourApiKey": "VÔŔ API klƭč", + "syncTitle": "Synchronizovat nastavenĆ­ prohlížeče s ĆŗÄtem", + "settingsCompare": "PorovnĆ”nĆ­ nastavenĆ­:", + "property": "Vlastnost", + "webBrowserSettings": "NastavenĆ­ webovĆ©ho prohlížeče", + "syncToBrowser": "Synchronizovat ĆŗÄet -> prohlížeč", + "syncToAccount": "Synchronizovat ĆŗÄet <- prohlížeč" + }, + "adminUserSettings": { + "title": "NastavenĆ­ sprĆ”vy uživatelÅÆ", + "header": "NastavenĆ­ sprĆ”vy uživatelÅÆ", + "admin": "SprĆ”vce", + "user": "Uživatel", + "addUser": "Přidat novĆ©ho uživatele", + "deleteUser": "Smazat uživatele", + "confirmDeleteUser": "MĆ” být uživatel smazĆ”n?", + "confirmChangeUserStatus": "MĆ” být uživatel deaktivovĆ”n/aktivovĆ”n?", + "usernameInfo": "UživatelskĆ© jmĆ©no může obsahovat pouze pĆ­smena, čƭslice a nĆ”sledujĆ­cĆ­ speciĆ”lnĆ­ znaky @._+- nebo musĆ­ být platnĆ” e-mailovĆ” adresa.", + "roles": "Role", + "role": "Role", + "actions": "Akce", + "apiUser": "Omezený API uživatel", + "extraApiUser": "DalŔí omezený API uživatel", + "webOnlyUser": "Pouze webový uživatel", + "demoUser": "Demo uživatel (Bez vlastnĆ­ch nastavenĆ­)", + "internalApiUser": "InternĆ­ API uživatel", + "forceChange": "Vynutit změnu hesla při přihlÔŔenĆ­", + "submit": "Uložit uživatele", + "changeUserRole": "Změnit roli uživatele", + "authenticated": "Ověřen", + "editOwnProfil": "Upravit vlastnĆ­ profil", + "enabledUser": "aktivovaný uživatel", + "disabledUser": "deaktivovaný uživatel", + "activeUsers": "AktivnĆ­ uživatelĆ©:", + "disabledUsers": "DeaktivovanĆ­ uživatelĆ©:", + "totalUsers": "Celkem uživatelÅÆ:", + "lastRequest": "PoslednĆ­ požadavek", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Import/Export databĆ”ze", + "header": "Import/Export databĆ”ze", + "fileName": "NĆ”zev souboru", + "creationDate": "Datum vytvořenĆ­", + "fileSize": "Velikost souboru", + "deleteBackupFile": "Smazat zĆ”ložnĆ­ soubor", + "importBackupFile": "Importovat zĆ”ložnĆ­ soubor", + "createBackupFile": "Vytvořit zĆ”ložnĆ­ soubor", + "downloadBackupFile": "StĆ”hnout zĆ”ložnĆ­ soubor", + "info_1": "Při importu dat je zĆ”sadnĆ­ zajistit sprĆ”vnou strukturu. Pokud si nejste jisti, co dělĆ”te, vyhledejte odbornou radu a podporu. Chyba ve struktuře může zpÅÆsobit poruchy aplikace, až po Ćŗplnou nefunkčnost aplikace.", + "info_2": "NĆ”zev souboru při nahrĆ”vĆ”nĆ­ nenĆ­ dÅÆležitý. Bude nĆ”sledně přejmenovĆ”n podle formĆ”tu backup_user_yyyyMMddHHmm.sql, což zajiŔńuje konzistentnĆ­ konvenci pojmenovĆ”nĆ­.", + "submit": "Importovat zĆ”lohu", + "importIntoDatabaseSuccessed": "Import do databĆ”ze byl ĆŗspěŔný", + "backupCreated": "ZĆ”loha databĆ”ze byla ĆŗspěŔnĆ”", + "fileNotFound": "Soubor nebyl nalezen", + "fileNullOrEmpty": "Soubor nesmĆ­ být prĆ”zdný", + "failedImportFile": "Import souboru selhal", + "notSupported": "Tato funkce nenĆ­ pro vaÅ”e připojenĆ­ k databĆ”zi k dispozici." + }, + "session": { + "expired": "VaÅ”e relace vyprÅ”ela. Obnovte prosĆ­m strĆ”nku a zkuste to znovu.", + "refreshPage": "Obnovit strĆ”nku" + }, + "home": { + "desc": "VaÅ”e lokĆ”lně hostovanĆ© řeÅ”enĆ­ pro vÅ”echny vaÅ”e potřeby PDF.", + "searchBar": "Hledat funkce...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Zobrazit, anotovat, přidat text nebo obrĆ”zky" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "PDF Multi nĆ”stroj", + "desc": "Sloučit, otočit, přeuspořÔdat, rozdělit a odstranit strĆ”nky" + }, + "merge": { + "title": "Sloučit", + "desc": "Snadno sloučit vĆ­ce PDF do jednoho." + }, + "split": { + "title": "Rozdělit", + "desc": "Rozdělit PDF do vĆ­ce dokumentÅÆ" + }, + "rotate": { + "title": "Otočit", + "desc": "Snadno otočit vaÅ”e PDF." + }, + "imageToPdf": { + "title": "ObrĆ”zek na PDF", + "desc": "PřevĆ©st obrĆ”zek (PNG, JPEG, GIF) na PDF." + }, + "pdfToImage": { + "title": "PDF na obrĆ”zek", + "desc": "PřevĆ©st PDF na obrĆ”zek. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "UspořÔdat", + "desc": "Odstranit/přeuspořÔdat strĆ”nky v libovolnĆ©m pořadĆ­" + }, + "addImage": { + "title": "Přidat obrĆ”zek", + "desc": "PřidĆ” obrĆ”zek na určenĆ© mĆ­sto v PDF" + }, + "watermark": { + "title": "Přidat vodoznak", + "desc": "Přidat vlastnĆ­ vodoznak do vaÅ”eho PDF dokumentu." + }, + "permissions": { + "title": "Změnit oprĆ”vněnĆ­", + "desc": "Změnit oprĆ”vněnĆ­ vaÅ”eho PDF dokumentu" + }, + "removePages": { + "title": "Odstranit", + "desc": "Smazat nežÔdoucĆ­ strĆ”nky z vaÅ”eho PDF dokumentu." + }, + "addPassword": { + "title": "Přidat heslo", + "desc": "ZaÅ”ifrovat vÔŔ PDF dokument heslem." + }, + "removePassword": { + "title": "Odstranit heslo", + "desc": "Odstranit ochranu heslem z vaÅ”eho PDF dokumentu." + }, + "compressPdfs": { + "title": "Komprimovat", + "desc": "Komprimovat PDF pro zmenÅ”enĆ­ jejich velikosti." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Změnit metadata", + "desc": "Změnit/odstranit/přidat metadata z PDF dokumentu" + }, + "fileToPDF": { + "title": "PřevĆ©st soubor na PDF", + "desc": "PřevĆ©st tĆ©měř jakýkoliv soubor na PDF (DOCX, PNG, XLS, PPT, TXT a dalŔí)" + }, + "ocr": { + "title": "OCR / VyčiÅ”těnĆ­ skenÅÆ", + "desc": "VyčistĆ­ skeny a detekuje text z obrĆ”zkÅÆ v PDF a znovu ho přidĆ” jako text." + }, + "extractImages": { + "title": "Extrahovat obrĆ”zky", + "desc": "Extrahuje vÅ”echny obrĆ”zky z PDF a uloží je do zipu" + }, + "pdfToPDFA": { + "title": "PDF na PDF/A", + "desc": "PřevĆ©st PDF na PDF/A pro dlouhodobĆ© uchovĆ”vĆ”nĆ­" + }, + "PDFToWord": { + "title": "PDF na Word", + "desc": "PřevĆ©st PDF na formĆ”ty Word (DOC, DOCX a ODT)" + }, + "PDFToPresentation": { + "title": "PDF na prezentaci", + "desc": "PřevĆ©st PDF na formĆ”ty prezentacĆ­ (PPT, PPTX a ODP)" + }, + "PDFToText": { + "title": "PDF na RTF (Text)", + "desc": "PřevĆ©st PDF na textový nebo RTF formĆ”t" + }, + "PDFToHTML": { + "title": "PDF na HTML", + "desc": "PřevĆ©st PDF na HTML formĆ”t" + }, + "PDFToXML": { + "title": "PDF na XML", + "desc": "PřevĆ©st PDF na XML formĆ”t" + }, + "ScannerImageSplit": { + "title": "Detekovat/Rozdělit naskenovanĆ© fotografie", + "desc": "RozdělĆ­ vĆ­ce fotografiĆ­ z jednĆ© fotografie/PDF" + }, + "sign": { + "title": "Podepsat", + "desc": "PřidĆ” podpis do PDF kreslenĆ­m, textem nebo obrĆ”zkem" + }, + "flatten": { + "title": "ZploÅ”tit", + "desc": "Odstranit vÅ”echny interaktivnĆ­ prvky a formulÔře z PDF" + }, + "repair": { + "title": "Opravit", + "desc": "PokusĆ­ se opravit poÅ”kozený/rozbitý PDF" + }, + "removeBlanks": { + "title": "Odstranit prĆ”zdnĆ© strĆ”nky", + "desc": "Detekuje a odstranĆ­ prĆ”zdnĆ© strĆ”nky z dokumentu" + }, + "removeAnnotations": { + "title": "Odstranit poznĆ”mky", + "desc": "OdstranĆ­ vÅ”echny komentÔře/poznĆ”mky z PDF" + }, + "compare": { + "title": "Porovnat", + "desc": "PorovnĆ” a zobrazĆ­ rozdĆ­ly mezi 2 PDF dokumenty" + }, + "certSign": { + "title": "Podepsat certifikĆ”tem", + "desc": "PodepĆ­Å”e PDF certifikĆ”tem/klƭčem (PEM/P12)" + }, + "removeCertSign": { + "title": "Odstranit podpis certifikĆ”tu", + "desc": "Odstranit podpis certifikĆ”tu z PDF" + }, + "pageLayout": { + "title": "RozvrženĆ­ vĆ­ce strĆ”nek", + "desc": "Sloučit vĆ­ce strĆ”nek PDF dokumentu do jednĆ© strĆ”nky" + }, + "scalePages": { + "title": "Upravit velikost/měřítko strĆ”nky", + "desc": "Změnit velikost/měřítko strĆ”nky a/nebo jejĆ­ho obsahu." + }, + "pipeline": { + "title": "Pipeline", + "desc": "Spustit vĆ­ce akcĆ­ na PDF definovĆ”nĆ­m pipeline skriptÅÆ" + }, + "add-page-numbers": { + "title": "Přidat čƭsla strĆ”nek", + "desc": "Přidat čƭsla strĆ”nek v celĆ©m dokumentu na určenĆ©m mĆ­stě" + }, + "auto-rename": { + "title": "Automaticky přejmenovat PDF soubor", + "desc": "Automaticky přejmenuje PDF soubor podle detekovanĆ© hlavičky" + }, + "adjust-contrast": { + "title": "Upravit barvy/kontrast", + "desc": "Upravit kontrast, sytost a jas PDF" + }, + "crop": { + "title": "Oříznout PDF", + "desc": "Oříznout PDF pro zmenÅ”enĆ­ jeho velikosti (zachovĆ” text!)" + }, + "autoSplitPDF": { + "title": "Automaticky rozdělit strĆ”nky", + "desc": "Automaticky rozdělit naskenovanĆ© PDF s fyzickým QR kódem pro rozdělenĆ­ strĆ”nek" + }, + "sanitizePdf": { + "title": "Sanitizovat", + "desc": "Odstranit skripty a dalŔí prvky z PDF souborÅÆ" + }, + "URLToPDF": { + "title": "URL/Web na PDF", + "desc": "PřevĆ”dĆ­ libovolnou http(s) URL na PDF" + }, + "HTMLToPDF": { + "title": "HTML na PDF", + "desc": "PřevĆ”dĆ­ libovolný HTML soubor nebo zip na PDF" + }, + "MarkdownToPDF": { + "title": "Markdown na PDF", + "desc": "PřevĆ”dĆ­ libovolný Markdown soubor na PDF" + }, + "PDFToMarkdown": { + "title": "PDF na Markdown", + "desc": "PřevĆ”dĆ­ libovolnĆ© PDF na Markdown" + }, + "getPdfInfo": { + "title": "ZĆ­skat VÅ ECHNY informace o PDF", + "desc": "ZĆ­skĆ” vÅ”echny možnĆ© informace o PDF" + }, + "extractPage": { + "title": "Extrahovat strĆ”nky", + "desc": "Extrahuje vybranĆ© strĆ”nky z PDF" + }, + "PdfToSinglePage": { + "title": "Jedna velkĆ” strĆ”nka", + "desc": "Sloučƭ vÅ”echny strĆ”nky PDF do jednĆ© velkĆ© strĆ”nky" + }, + "showJS": { + "title": "Zobrazit Javascript", + "desc": "VyhledĆ” a zobrazĆ­ jakýkoliv JS vložený do PDF" + }, + "autoRedact": { + "title": "AutomatickĆ© začerněnĆ­", + "desc": "Automaticky začernĆ­ text v PDF na zĆ”kladě vstupnĆ­ho textu" + }, + "redact": { + "title": "RučnĆ­ začerněnĆ­", + "desc": "ZačernĆ­ PDF na zĆ”kladě vybranĆ©ho textu, nakreslených tvarÅÆ a/nebo vybraných strĆ”nek" + }, + "tableExtraxt": { + "title": "PDF na CSV", + "desc": "Extrahuje tabulky z PDF a převĆ”dĆ­ je na CSV" + }, + "autoSizeSplitPDF": { + "title": "Automaticky rozdělit podle velikosti/počtu", + "desc": "RozdělĆ­ jeden PDF na vĆ­ce dokumentÅÆ podle velikosti, počtu strĆ”nek nebo počtu dokumentÅÆ" + }, + "overlay-pdfs": { + "title": "Překrýt PDF", + "desc": "Překryje PDF nad jiným PDF" + }, + "split-by-sections": { + "title": "Rozdělit PDF podle sekcĆ­", + "desc": "RozdělĆ­ každou strĆ”nku PDF na menŔí horizontĆ”lnĆ­ a vertikĆ”lnĆ­ sekce" + }, + "AddStampRequest": { + "title": "Přidat razĆ­tko do PDF", + "desc": "PřidĆ” textovĆ” nebo obrĆ”zkovĆ© razĆ­tka na určenĆ” mĆ­sta" + }, + "removeImagePdf": { + "title": "Odstranit obrĆ”zek", + "desc": "Odstranit obrĆ”zek z PDF pro zmenÅ”enĆ­ velikosti souboru" + }, + "splitPdfByChapters": { + "title": "Rozdělit PDF podle kapitol", + "desc": "RozdělĆ­ PDF do vĆ­ce souborÅÆ podle jeho struktury kapitol." + }, + "validateSignature": { + "title": "Ověřit podpis PDF", + "desc": "Ověřit digitĆ”lnĆ­ podpisy a certifikĆ”ty v PDF dokumentech" + }, + "replaceColorPdf": { + "title": "NahrazenĆ­ a inverze barev", + "desc": "Úprava barev textu a pozadĆ­ v PDF nebo jejich inverze ke sníženĆ­ velikosti souboru" + } + }, + "viewPdf": { + "tags": "zobrazit,čƭst,anotovat,text,obrĆ”zek", + "title": "View/Edit PDF", + "header": "Zobrazit PDF" + }, + "multiTool": { + "tags": "Multi nĆ”stroj,VĆ­ce operacĆ­,UI,kliknutĆ­ a přetaženĆ­,přednĆ­ strana,klientskĆ” strana,interaktivnĆ­,pohyb,smazat,přesunout,rozdělit", + "title": "PDF Multi nĆ”stroj", + "header": "PDF Multi nĆ”stroj", + "uploadPrompts": "NĆ”zev souboru", + "selectAll": "Vybrat vÅ”e", + "deselectAll": "ZruÅ”it výběr vÅ”eho", + "selectPages": "Vybrat strĆ”nku", + "selectedPages": "VybranĆ© strĆ”nky", + "page": "StrĆ”nka", + "deleteSelected": "Smazat vybranĆ©", + "downloadAll": "Exportovat", + "downloadSelected": "Exportovat vybranĆ©", + "insertPageBreak": "Vložit zalomenĆ­ strĆ”nky", + "addFile": "Přidat soubor", + "rotateLeft": "Otočit doleva", + "rotateRight": "Otočit doprava", + "split": "Rozdělit", + "moveLeft": "Přesunout doleva", + "moveRight": "Přesunout doprava", + "delete": "Smazat", + "dragDropMessage": "VybranĆ”/Ć© strĆ”nka/y", + "undo": "Zpět", + "redo": "Znovu" + }, + "merge": { + "tags": "sloučit,Operace se strĆ”nkami,ZadnĆ­ strana,serverovĆ” strana", + "title": "Sloučit", + "header": "Sloučit vĆ­ce PDF (2+)", + "sortByName": "Seřadit podle nĆ”zvu", + "sortByDate": "Seřadit podle data", + "removeCertSign": "Odstranit digitĆ”lnĆ­ podpis v sloučenĆ©m souboru?", + "submit": "Sloučit" + }, + "split": { + "tags": "Operace se strĆ”nkami,rozdělit,VĆ­ce strĆ”nek,vyjmout,serverovĆ” strana", + "title": "Rozdělit PDF", + "header": "Rozdělit PDF", + "desc": { + "1": "Čísla, kterĆ” vyberete, jsou čƭsla strĆ”nek, na kterých chcete provĆ©st rozdělenĆ­", + "2": "Tak například výběr 1,3,7-9 by rozdělil 10strĆ”nkový dokument na 6 samostatných PDF s:", + "3": "Dokument #1: StrĆ”nka 1", + "4": "Dokument #2: StrĆ”nky 2 a 3", + "5": "Dokument #3: StrĆ”nky 4, 5, 6 a 7", + "6": "Dokument #4: StrĆ”nka 8", + "7": "Dokument #5: StrĆ”nka 9", + "8": "Dokument #6: StrĆ”nka 10" + }, + "splitPages": "Zadejte strĆ”nky pro rozdělenĆ­:", + "submit": "Rozdělit" + }, + "rotate": { + "tags": "serverovĆ” strana", + "title": "Otočit PDF", + "header": "Otočit PDF", + "selectAngle": "Vyberte Ćŗhel otočenĆ­ (v nĆ”sobcĆ­ch 90 stupňů):", + "submit": "Otočit" + }, + "imageToPdf": { + "tags": "převod,img,jpg,obrĆ”zek,fotka" + }, + "pdfToImage": { + "tags": "převod,img,jpg,obrĆ”zek,fotka", + "title": "PDF na obrĆ”zek", + "header": "PDF na obrĆ”zek", + "selectText": "FormĆ”t obrĆ”zku", + "singleOrMultiple": "Typ výsledku obrĆ”zku", + "single": "Jeden velký obrĆ”zek", + "multi": "VĆ­ce obrĆ”zkÅÆ", + "colorType": "Typ barev", + "color": "Barevný", + "grey": "Stupně Å”edi", + "blackwhite": "ČernobĆ­lý (Může dojĆ­t ke ztrĆ”tě dat!)", + "submit": "PřevĆ©st", + "info": "Python nenĆ­ nainstalovĆ”n. VyžadovĆ”n pro konverzi do WebP.", + "placeholder": "(např. 1,2,8 nebo 4,7,12-16 nebo 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,sudý,lichý,seřadit,přesunout", + "title": "OrganizĆ”tor strĆ”nek", + "header": "OrganizĆ”tor strĆ”nek PDF", + "submit": "PřeuspořÔdat strĆ”nky", + "mode": { + "_value": "Režim", + "1": "VlastnĆ­ pořadĆ­ strĆ”nek", + "2": "ObrĆ”cenĆ© pořadĆ­", + "3": "DuplexnĆ­ řazenĆ­", + "4": "ŘazenĆ­ do brožury", + "5": "ŘazenĆ­ do bočnĆ­ brožury", + "6": "RozdělenĆ­ sudĆ©-lichĆ©", + "7": "Odstranit prvnĆ­", + "8": "Odstranit poslednĆ­", + "9": "Odstranit prvnĆ­ a poslednĆ­", + "10": "SloučenĆ­ sudĆ©-lichĆ©", + "11": "Duplicate all pages" + }, + "placeholder": "(např. 1,3,2 nebo 4-8,2,10-12 nebo 2n-1)" + }, + "addImage": { + "tags": "img,jpg,obrĆ”zek,fotka", + "title": "Přidat obrĆ”zek", + "header": "Přidat obrĆ”zek do PDF", + "everyPage": "KaždĆ” strĆ”nka?", + "upload": "Přidat obrĆ”zek", + "submit": "Přidat obrĆ”zek" + }, + "watermark": { + "tags": "Text,opakujĆ­cĆ­ se,popisek,vlastnĆ­,copyright,ochrannĆ” znĆ”mka,img,jpg,obrĆ”zek,fotka", + "title": "Přidat vodoznak", + "header": "Přidat vodoznak", + "customColor": "VlastnĆ­ barva textu", + "selectText": { + "1": "Vyberte PDF pro přidĆ”nĆ­ vodoznaku:", + "2": "Text vodoznaku:", + "3": "Velikost pĆ­sma:", + "4": "OtočenĆ­ (0-360):", + "5": "HorizontĆ”lnĆ­ mezera (Mezera mezi vodoznaky horizontĆ”lně):", + "6": "VertikĆ”lnĆ­ mezera (Mezera mezi vodoznaky vertikĆ”lně):", + "7": "PrÅÆhlednost (0% - 100%):", + "8": "Typ vodoznaku:", + "9": "ObrĆ”zek vodoznaku:", + "10": "PřevĆ©st PDF na PDF-obrĆ”zek" + }, + "submit": "Přidat vodoznak", + "type": { + "1": "Text", + "2": "ObrĆ”zek" + } + }, + "permissions": { + "tags": "čƭst,psĆ”t,upravit,tisknout", + "title": "Změnit oprĆ”vněnĆ­", + "header": "Změnit oprĆ”vněnĆ­", + "warning": "UpozorněnĆ­: Pro nezměnitelnost těchto oprĆ”vněnĆ­ je doporučeno nastavit je s heslem přes strĆ”nku přidĆ”nĆ­ hesla", + "selectText": { + "1": "Vyberte PDF ke změně oprĆ”vněnĆ­", + "2": "OprĆ”vněnĆ­ k nastavenĆ­", + "3": "ZabrĆ”nit sestavenĆ­ dokumentu", + "4": "ZabrĆ”nit extrakci obsahu", + "5": "ZabrĆ”nit extrakci pro přístupnost", + "6": "ZabrĆ”nit vyplňovĆ”nĆ­ formulÔřů", + "7": "ZabrĆ”nit ĆŗpravĆ”m", + "8": "ZabrĆ”nit ĆŗpravĆ”m poznĆ”mek", + "9": "ZabrĆ”nit tisku", + "10": "ZabrĆ”nit tisku v rÅÆzných formĆ”tech" + }, + "submit": "Změnit" + }, + "removePages": { + "tags": "Odstranit strĆ”nky,smazat strĆ”nky" + }, + "addPassword": { + "tags": "zabezpečit,bezpečnost", + "title": "Přidat heslo", + "header": "Přidat heslo (ZaÅ”ifrovat)", + "selectText": { + "1": "Vyberte PDF k zaÅ”ifrovĆ”nĆ­", + "2": "UživatelskĆ© heslo", + "3": "DĆ©lka Å”ifrovacĆ­ho klƭče", + "4": "VyŔŔí hodnoty jsou silnějŔí, ale nižŔí hodnoty majĆ­ lepŔí kompatibilitu.", + "5": "OprĆ”vněnĆ­ k nastavenĆ­ (Doporučeno používat společně s heslem vlastnĆ­ka)", + "6": "ZabrĆ”nit sestavenĆ­ dokumentu", + "7": "ZabrĆ”nit extrakci obsahu", + "8": "ZabrĆ”nit extrakci pro přístupnost", + "9": "ZabrĆ”nit vyplňovĆ”nĆ­ formulÔřů", + "10": "ZabrĆ”nit ĆŗpravĆ”m", + "11": "ZabrĆ”nit ĆŗpravĆ”m poznĆ”mek", + "12": "ZabrĆ”nit tisku", + "13": "ZabrĆ”nit tisku v rÅÆzných formĆ”tech", + "14": "Heslo vlastnĆ­ka", + "15": "Omezuje, co lze s dokumentem dělat po jeho otevřenĆ­ (NenĆ­ podporovĆ”no vÅ”emi čtečkami)", + "16": "Omezuje samotnĆ© otevřenĆ­ dokumentu" + }, + "submit": "ZaÅ”ifrovat" + }, + "removePassword": { + "tags": "zabezpečit,deÅ”ifrovat,bezpečnost,odstranit heslo,smazat heslo", + "title": "Odstranit heslo", + "header": "Odstranit heslo (DeÅ”ifrovat)", + "selectText": { + "1": "Vyberte PDF k deÅ”ifrovĆ”nĆ­", + "2": "Heslo" + }, + "submit": "Odstranit" + }, + "compressPdfs": { + "tags": "stlačit,malý,drobný" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "NĆ”zev,autor,datum,vytvořenĆ­,čas,vydavatel,producent,statistiky", + "title": "Změnit metadata", + "header": "Změnit metadata", + "selectText": { + "1": "Upravte proměnnĆ©, kterĆ© chcete změnit", + "2": "Smazat vÅ”echna metadata", + "3": "Zobrazit vlastnĆ­ metadata:", + "4": "OstatnĆ­ metadata:", + "5": "Přidat vlastnĆ­ položku metadat" + }, + "author": "Autor:", + "creationDate": "Datum vytvořenĆ­ (rrrr/MM/dd HH:mm:ss):", + "creator": "TvÅÆrce:", + "keywords": "KlƭčovĆ” slova:", + "modDate": "Datum Ćŗpravy (rrrr/MM/dd HH:mm:ss):", + "producer": "Producent:", + "subject": "Předmět:", + "trapped": "Zachyceno:", + "submit": "Změnit" + }, + "fileToPDF": { + "tags": "transformace,formĆ”t,dokument,obrĆ”zek,prezentace,text,převod,office,docs,word,excel,powerpoint", + "title": "Soubor na PDF", + "header": "PřevĆ©st libovolný soubor na PDF", + "credit": "Tato služba používĆ” LibreOffice a Unoconv pro konverzi souborÅÆ.", + "supportedFileTypesInfo": "PodporovanĆ© typy souborÅÆ", + "supportedFileTypes": "PodporovanĆ© typy souborÅÆ by měly zahrnovat níže uvedenĆ©, pro Ćŗplný aktualizovaný seznam podporovaných formĆ”tÅÆ vÅ”ak prosĆ­m nahlĆ©dněte do dokumentace LibreOffice", + "submit": "PřevĆ©st na PDF" + }, + "ocr": { + "tags": "rozpoznĆ”nĆ­,text,obrĆ”zek,sken,čƭst,identifikovat,detekce,upravitelný", + "title": "OCR / ČiÅ”těnĆ­ skenÅÆ", + "header": "ČiÅ”těnĆ­ skenÅÆ / OCR (OptickĆ© rozpoznĆ”vĆ”nĆ­ znakÅÆ)", + "selectText": { + "1": "Vyberte jazyky, kterĆ© majĆ­ být detekovĆ”ny v PDF (UvedenĆ© jsou aktuĆ”lně detekovanĆ©):", + "2": "Vytvořit textový soubor obsahujĆ­cĆ­ OCR text spolu s OCR PDF", + "3": "Opravit strĆ”nky, kterĆ© byly naskenovĆ”ny pod Ćŗhlem, jejich otočenĆ­m zpět na mĆ­sto", + "4": "Vyčistit strĆ”nku, aby bylo mĆ©ně pravděpodobnĆ©, že OCR najde text v Å”umu pozadĆ­. (ŽÔdnĆ” změna výstupu)", + "5": "Vyčistit strĆ”nku, aby bylo mĆ©ně pravděpodobnĆ©, že OCR najde text v Å”umu pozadĆ­, zachovĆ” čistý výstup.", + "6": "Ignorovat strĆ”nky, kterĆ© majĆ­ interaktivnĆ­ text, provĆ©st OCR pouze na strĆ”nkĆ”ch, kterĆ© jsou obrĆ”zky", + "7": "Vynutit OCR, provede OCR na každĆ© strĆ”nce a odstranĆ­ vÅ”echny pÅÆvodnĆ­ textovĆ© prvky", + "8": "NormĆ”lnĆ­ (VyvolĆ” chybu, pokud PDF obsahuje text)", + "9": "DalŔí nastavenĆ­", + "10": "Režim OCR", + "11": "Odstranit obrĆ”zky po OCR (OdstranĆ­ VÅ ECHNY obrĆ”zky, užitečnĆ© pouze jako souÄĆ”st kroku konverze)", + "12": "Typ vykreslenĆ­ (PokročilĆ©)" + }, + "help": "Přečtěte si prosĆ­m tuto dokumentaci o použitĆ­ pro jinĆ© jazyky a/nebo použitĆ­ mimo Docker", + "credit": "Tato služba používĆ” qpdf a Tesseract pro OCR.", + "submit": "Zpracovat PDF pomocĆ­ OCR" + }, + "extractImages": { + "tags": "obrĆ”zek,fotka,uložit,archiv,zip,zachytit,zĆ­skat", + "title": "Extrahovat obrĆ”zky", + "header": "Extrahovat obrĆ”zky", + "selectText": "Vyberte formĆ”t obrĆ”zku pro převod extrahovaných obrĆ”zkÅÆ", + "allowDuplicates": "Uložit duplicitnĆ­ obrĆ”zky", + "submit": "Extrahovat" + }, + "pdfToPDFA": { + "tags": "archiv,dlouhodobý,standard,převod,ĆŗložiÅ”tě,uchovĆ”nĆ­", + "title": "PDF na PDF/A", + "header": "PDF na PDF/A", + "credit": "Tato služba používĆ” libreoffice pro konverzi do PDF/A", + "submit": "PřevĆ©st", + "tip": "MomentĆ”lně nefunguje pro vĆ­ce vstupÅÆ najednou", + "outputFormat": "VýstupnĆ­ formĆ”t", + "pdfWithDigitalSignature": "PDF obsahuje digitĆ”lnĆ­ podpis, který bude v dalŔím kroku odstraněn." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformace,formĆ”t,převod,office,microsoft,docfile", + "title": "PDF na Word", + "header": "PDF na Word", + "selectText": { + "1": "FormĆ”t výstupnĆ­ho souboru" + }, + "credit": "Tato služba používĆ” LibreOffice pro konverzi souborÅÆ.", + "submit": "PřevĆ©st" + }, + "PDFToPresentation": { + "tags": "snĆ­mky,prezentace,office,microsoft", + "title": "PDF na prezentaci", + "header": "PDF na prezentaci", + "selectText": { + "1": "FormĆ”t výstupnĆ­ho souboru" + }, + "credit": "Tato služba používĆ” LibreOffice pro konverzi souborÅÆ.", + "submit": "PřevĆ©st" + }, + "PDFToText": { + "tags": "formĆ”t bohatĆ©ho textu,formĆ”t rtf,formĆ”t bohatĆ©ho textu", + "title": "PDF na RTF (Text)", + "header": "PDF na RTF (Text)", + "selectText": { + "1": "FormĆ”t výstupnĆ­ho souboru" + }, + "credit": "Tato služba používĆ” LibreOffice pro konverzi souborÅÆ.", + "submit": "PřevĆ©st" + }, + "PDFToHTML": { + "tags": "webový obsah,přívětivý pro prohlížeč", + "title": "PDF na HTML", + "header": "PDF na HTML", + "credit": "Tato služba používĆ” pdftohtml pro konverzi souborÅÆ.", + "submit": "PřevĆ©st" + }, + "PDFToXML": { + "tags": "extrakce-dat,strukturovaný-obsah,interoperabilita,transformace,převod", + "title": "PDF na XML", + "header": "PDF na XML", + "credit": "Tato služba používĆ” LibreOffice pro konverzi souborÅÆ.", + "submit": "PřevĆ©st" + }, + "ScannerImageSplit": { + "tags": "oddělit,auto-detekce,skeny,vĆ­ce-fotek,uspořÔdat", + "selectText": { + "1": "PrahovĆ” hodnota Ćŗhlu:", + "2": "NastavĆ­ minimĆ”lnĆ­ absolutnĆ­ Ćŗhel požadovaný pro otočenĆ­ obrĆ”zku (výchozĆ­: 10).", + "3": "Tolerance:", + "4": "Určuje rozsah barevnĆ© variace kolem odhadovanĆ© barvy pozadĆ­ (výchozĆ­: 30).", + "5": "MinimĆ”lnĆ­ plocha:", + "6": "NastavĆ­ minimĆ”lnĆ­ prahovou hodnotu plochy pro fotografii (výchozĆ­: 10000).", + "7": "MinimĆ”lnĆ­ plocha obrysu:", + "8": "NastavĆ­ minimĆ”lnĆ­ prahovou hodnotu plochy obrysu pro fotografii", + "9": "Velikost okraje:", + "10": "NastavĆ­ velikost okraje přidanĆ©ho a odebranĆ©ho k zabrĆ”něnĆ­ bĆ­lých okrajÅÆ ve výstupu (výchozĆ­: 1)." + }, + "info": "Python nenĆ­ nainstalovĆ”n. Je vyžadovĆ”n pro spuÅ”těnĆ­." + }, + "sign": { + "tags": "autorizovat,iniciĆ”ly,kreslený-podpis,textový-podpis,obrĆ”zkový-podpis", + "title": "Podepsat", + "header": "Podepsat PDF", + "upload": "NahrĆ”t obrĆ”zek", + "draw": "Nakreslit podpis", + "text": "Textový vstup", + "clear": "Vymazat", + "add": "Přidat", + "saved": "UloženĆ© podpisy", + "save": "Uložit podpis", + "personalSigs": "OsobnĆ­ podpisy", + "sharedSigs": "SdĆ­lenĆ© podpisy", + "noSavedSigs": "Nebyly nalezeny žÔdnĆ© uloženĆ© podpisy", + "addToAll": "Přidat na vÅ”echny strĆ”nky", + "delete": "Smazat", + "first": "PrvnĆ­ strĆ”nka", + "last": "PoslednĆ­ strĆ”nka", + "next": "DalŔí strĆ”nka", + "previous": "PředchozĆ­ strĆ”nka", + "maintainRatio": "Přepnout zachovĆ”nĆ­ poměru stran", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "statický,deaktivovat,neinteraktivnĆ­,zjednoduÅ”it", + "title": "ZploÅ”tit", + "header": "ZploÅ”tit PDF", + "flattenOnlyForms": "ZploÅ”tit pouze formulÔře", + "submit": "ZploÅ”tit" + }, + "repair": { + "tags": "opravit,obnovit,korekce,obnovit", + "title": "Opravit", + "header": "Opravit PDF", + "submit": "Opravit" + }, + "removeBlanks": { + "tags": "vyčistit,zjednoduÅ”it,bez-obsahu,uspořÔdat", + "title": "Odstranit prĆ”zdnĆ© strĆ”nky", + "header": "Odstranit prĆ”zdnĆ© strĆ”nky", + "threshold": "PrĆ”h bělosti pixelÅÆ:", + "thresholdDesc": "PrĆ”h pro určenĆ­, jak bĆ­lý musĆ­ pixel být, aby byl klasifikovĆ”n jako 'bĆ­lý'. 0 = černĆ”, 255 čistě bĆ­lĆ”.", + "whitePercent": "Procento bĆ­lĆ© (%):", + "whitePercentDesc": "Procento strĆ”nky, kterĆ© musĆ­ být 'bĆ­lĆ©' pixely, aby byla odstraněna", + "submit": "Odstranit prĆ”zdnĆ©" + }, + "removeAnnotations": { + "tags": "komentÔře,zvýrazněnĆ­,poznĆ”mky,značky,odstranit", + "title": "Odstranit poznĆ”mky", + "header": "Odstranit poznĆ”mky", + "submit": "Odstranit" + }, + "compare": { + "tags": "rozliÅ”it,kontrast,změny,analýza", + "title": "Porovnat", + "header": "Porovnat PDF", + "highlightColor": { + "1": "ZvýrazňovacĆ­ barva 1:", + "2": "ZvýrazňovacĆ­ barva 2:" + }, + "document": { + "1": "Dokument 1", + "2": "Dokument 2" + }, + "submit": "Porovnat", + "complex": { + "message": "Jeden nebo oba poskytnutĆ© dokumenty jsou velkĆ© soubory, přesnost porovnĆ”nĆ­ může být snížena" + }, + "large": { + "file": { + "message": "Jeden nebo oba poskytnutĆ© dokumenty jsou příliÅ” velkĆ© na zpracovĆ”nĆ­" + } + }, + "no": { + "text": { + "message": "Jeden nebo oba vybranĆ© PDF soubory neobsahujĆ­ textový obsah. ProsĆ­m vyberte PDF soubory s textem pro porovnĆ”nĆ­." + } + } + }, + "certSign": { + "tags": "ověřit,PEM,P12,oficiĆ”lnĆ­,Å”ifrovat", + "title": "PodepisovĆ”nĆ­ certifikĆ”tem", + "header": "Podepsat PDF certifikĆ”tem (PrĆ”ce probĆ­hĆ”)", + "selectPDF": "Vyberte PDF soubor k podepsĆ”nĆ­:", + "jksNote": "PoznĆ”mka: Pokud typ vaÅ”eho certifikĆ”tu nenĆ­ uveden níže, převeďte jej prosĆ­m na Java Keystore (.jks) soubor pomocĆ­ nĆ”stroje keytool příkazovĆ© řÔdky. PotĆ© vyberte možnost .jks níže.", + "selectKey": "Vyberte soubor s vaŔím privĆ”tnĆ­m klƭčem (formĆ”t PKCS#8, může být .pem nebo .der):", + "selectCert": "Vyberte soubor s vaŔím certifikĆ”tem (formĆ”t X.509, může být .pem nebo .der):", + "selectP12": "Vyberte soubor s vaŔím PKCS#12 ĆŗložiÅ”těm klĆ­ÄÅÆ (.p12 nebo .pfx) (VolitelnĆ©, pokud je uvedeno, mělo by obsahovat vÔŔ privĆ”tnĆ­ klƭč a certifikĆ”t):", + "selectJKS": "Vyberte soubor s vaŔím Java ĆŗložiÅ”těm klĆ­ÄÅÆ (.jks nebo .keystore):", + "certType": "Typ certifikĆ”tu", + "password": "Zadejte heslo k vaÅ”emu ĆŗložiÅ”ti klĆ­ÄÅÆ nebo privĆ”tnĆ­mu klƭči (pokud existuje):", + "showSig": "Zobrazit podpis", + "reason": "DÅÆvod", + "location": "UmĆ­stěnĆ­", + "name": "JmĆ©no", + "showLogo": "Zobrazit logo", + "submit": "Podepsat PDF" + }, + "removeCertSign": { + "tags": "ověřit,PEM,P12,oficiĆ”lnĆ­,deÅ”ifrovat", + "title": "Odstranit podpis certifikĆ”tu", + "header": "Odstranit digitĆ”lnĆ­ certifikĆ”t z PDF", + "selectPDF": "Vyberte PDF soubor:", + "submit": "Odstranit podpis" + }, + "pageLayout": { + "tags": "sloučit,kompozitnĆ­,jedno-zobrazenĆ­,uspořÔdat", + "title": "RozvrženĆ­ vĆ­ce strĆ”nek", + "header": "RozvrženĆ­ vĆ­ce strĆ”nek", + "pagesPerSheet": "StrĆ”nek na list:", + "addBorder": "Přidat okraje", + "submit": "Odeslat" + }, + "scalePages": { + "tags": "změnit velikost,upravit,rozměr,přizpÅÆsobit", + "title": "Upravit měřítko strĆ”nky", + "header": "Upravit měřítko strĆ”nky", + "pageSize": "Velikost strĆ”nky dokumentu.", + "keepPageSize": "PÅÆvodnĆ­ velikost", + "scaleFactor": "Úroveň přiblíženĆ­ (oříznutĆ­) strĆ”nky.", + "submit": "Odeslat" + }, + "add-page-numbers": { + "tags": "čƭslovĆ”nĆ­,popisek,uspořÔdat,rejstřík" + }, + "auto-rename": { + "tags": "auto-detekce,podle-hlavičky,uspořÔdat,přejmenovat", + "title": "AutomatickĆ© přejmenovĆ”nĆ­", + "header": "AutomatickĆ© přejmenovĆ”nĆ­ PDF", + "submit": "Automaticky přejmenovat" + }, + "adjust-contrast": { + "tags": "korekce-barev,ladit,upravit,vylepÅ”it" + }, + "crop": { + "tags": "oříznout,zmenÅ”it,upravit,tvar", + "title": "Oříznout", + "header": "Oříznout PDF", + "submit": "Odeslat" + }, + "autoSplitPDF": { + "tags": "QR-kód,oddělit,sken-segment,uspořÔdat", + "title": "AutomatickĆ© rozdělenĆ­ PDF", + "header": "AutomatickĆ© rozdělenĆ­ PDF", + "description": "Vytiskněte, vložte, naskenujte, nahrajte a nechte nĆ”s automaticky oddělit vaÅ”e dokumenty. NenĆ­ potřeba žÔdnĆ© ručnĆ­ tříděnĆ­.", + "selectText": { + "1": "Vytiskněte některĆ© oddělovacĆ­ listy z níže uvedených (černobĆ­lĆ© je v pořÔdku).", + "2": "Naskenujte vÅ”echny svĆ© dokumenty najednou vloženĆ­m oddělovacĆ­ho listu mezi ně.", + "3": "Nahrajte jediný velký naskenovaný PDF soubor a nechte Stirling PDF udělat zbytek.", + "4": "OddělovacĆ­ strĆ”nky jsou automaticky detekovĆ”ny a odstraněny, což zaručuje čistý finĆ”lnĆ­ dokument." + }, + "formPrompt": "Odeslat PDF obsahujĆ­cĆ­ Stirling-PDF oddělovače strĆ”nek:", + "duplexMode": "DuplexnĆ­ režim (skenovĆ”nĆ­ přednĆ­ a zadnĆ­ strany)", + "dividerDownload2": "StĆ”hnout 'Automatický oddělovač (s instrukcemi).pdf'", + "submit": "Odeslat" + }, + "sanitizePdf": { + "tags": "vyčistit,zabezpečit,bezpečný,odstranit-hrozby" + }, + "URLToPDF": { + "tags": "zachytit-web,uložit-strĆ”nku,web-na-dok,archivovat", + "title": "URL na PDF", + "header": "URL na PDF", + "submit": "PřevĆ©st", + "credit": "VyužívĆ” WeasyPrint" + }, + "HTMLToPDF": { + "tags": "značkovĆ”nĆ­,webový-obsah,transformace,převod", + "title": "HTML na PDF", + "header": "HTML na PDF", + "help": "PřijĆ­mĆ” HTML soubory a ZIP soubory obsahujĆ­cĆ­ html/css/obrĆ”zky atd.", + "submit": "PřevĆ©st", + "credit": "VyužívĆ” WeasyPrint", + "zoom": "Úroveň přiblíženĆ­ pro zobrazenĆ­ webovĆ© strĆ”nky.", + "pageWidth": "Å Ć­Å™ka strĆ”nky v centimetrech. (PrĆ”zdnĆ© pro výchozĆ­)", + "pageHeight": "VýŔka strĆ”nky v centimetrech. (PrĆ”zdnĆ© pro výchozĆ­)", + "marginTop": "HornĆ­ okraj strĆ”nky v milimetrech. (PrĆ”zdnĆ© pro výchozĆ­)", + "marginBottom": "DolnĆ­ okraj strĆ”nky v milimetrech. (PrĆ”zdnĆ© pro výchozĆ­)", + "marginLeft": "Levý okraj strĆ”nky v milimetrech. (PrĆ”zdnĆ© pro výchozĆ­)", + "marginRight": "Pravý okraj strĆ”nky v milimetrech. (PrĆ”zdnĆ© pro výchozĆ­)", + "printBackground": "Vykreslit pozadĆ­ webových strĆ”nek.", + "defaultHeader": "Povolit výchozĆ­ zĆ”hlavĆ­ (nĆ”zev a čƭslo strĆ”nky)", + "cssMediaType": "Změnit typ CSS mĆ©dia strĆ”nky.", + "none": "ŽÔdný", + "print": "Tisk", + "screen": "Obrazovka" + }, + "MarkdownToPDF": { + "tags": "značkovĆ”nĆ­,webový-obsah,transformace,převod,md", + "title": "Markdown na PDF", + "header": "Markdown na PDF", + "submit": "PřevĆ©st", + "help": "PrĆ”ce probĆ­hĆ”", + "credit": "VyužívĆ” WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "značkovĆ”nĆ­,webový-obsah,transformace,převod,md", + "title": "PDF na Markdown", + "header": "PDF na Markdown", + "submit": "PřevĆ©st" + }, + "getPdfInfo": { + "tags": "informace,data,statistiky,statistiky", + "title": "ZĆ­skat informace o PDF", + "header": "ZĆ­skat informace o PDF", + "submit": "ZĆ­skat informace", + "downloadJson": "StĆ”hnout JSON" + }, + "extractPage": { + "tags": "extrahovat" + }, + "PdfToSinglePage": { + "tags": "jedna strĆ”nka" + }, + "showJS": { + "tags": "JS", + "title": "Zobrazit Javascript", + "header": "Zobrazit Javascript", + "downloadJS": "StĆ”hnout Javascript", + "submit": "Zobrazit" + }, + "autoRedact": { + "tags": "Začernit,Skrýt,začernit,černĆ”,značka,skrytý", + "title": "AutomatickĆ© začerněnĆ­", + "header": "AutomatickĆ© začerněnĆ­", + "colorLabel": "Barva", + "textsToRedactLabel": "Text k začerněnĆ­ (oddělený řÔdky)", + "textsToRedactPlaceholder": "např. \\nDÅÆvěrnĆ© \\nPřísně tajnĆ©", + "useRegexLabel": "Použít regulĆ”rnĆ­ výraz", + "wholeWordSearchLabel": "Hledat celĆ” slova", + "customPaddingLabel": "VlastnĆ­ dodatečnĆ© odsazenĆ­", + "convertPDFToImageLabel": "PřevĆ©st PDF na PDF-obrĆ”zek (PoužívĆ” se k odstraněnĆ­ textu za rĆ”mečkem)", + "submitButton": "Odeslat" + }, + "redact": { + "tags": "Začernit,Skrýt,začernit,černĆ”,značka,skrytý,ručnĆ­", + "title": "RučnĆ­ začerněnĆ­", + "header": "RučnĆ­ začerněnĆ­", + "submit": "Začernit", + "textBasedRedaction": "ZačerněnĆ­ založenĆ© na textu", + "pageBasedRedaction": "ZačerněnĆ­ založenĆ© na strĆ”nkĆ”ch", + "convertPDFToImageLabel": "PřevĆ©st PDF na PDF-obrĆ”zek (PoužívĆ” se k odstraněnĆ­ textu za rĆ”mečkem)", + "pageRedactionNumbers": { + "title": "StrĆ”nky", + "placeholder": "(např. 1,2,8 nebo 4,7,12-16 nebo 2n-1)" + }, + "redactionColor": { + "title": "Barva začerněnĆ­" + }, + "export": "Exportovat", + "upload": "NahrĆ”t", + "boxRedaction": "ZačerněnĆ­ kreslenĆ­m rĆ”mečku", + "zoom": "PřiblíženĆ­", + "zoomIn": "Přiblížit", + "zoomOut": "OddĆ”lit", + "nextPage": "DalŔí strĆ”nka", + "previousPage": "PředchozĆ­ strĆ”nka", + "toggleSidebar": "Přepnout postrannĆ­ panel", + "showThumbnails": "Zobrazit miniatury", + "showDocumentOutline": "Zobrazit osnovu dokumentu (dvojklik pro rozbalenĆ­/sbalenĆ­ vÅ”ech položek)", + "showAttatchments": "Zobrazit přílohy", + "showLayers": "Zobrazit vrstvy (dvojklik pro obnovenĆ­ vÅ”ech vrstev do výchozĆ­ho stavu)", + "colourPicker": "Výběr barvy", + "findCurrentOutlineItem": "NajĆ­t aktuĆ”lnĆ­ položku osnovy", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,Extrakce tabulek,extrahovat,převĆ©st" + }, + "autoSizeSplitPDF": { + "tags": "pdf,rozdělit,dokument,organizace" + }, + "overlay-pdfs": { + "tags": "Překrýt", + "header": "Překrýt PDF soubory", + "baseFile": { + "label": "Vyberte zĆ”kladnĆ­ PDF soubor" + }, + "overlayFiles": { + "label": "Vyberte PDF soubory pro překrytĆ­" + }, + "mode": { + "label": "Vyberte režim překrytĆ­", + "sequential": "SekvenčnĆ­ překrytĆ­", + "interleaved": "ProklĆ”danĆ© překrytĆ­", + "fixedRepeat": "PevnĆ© opakovanĆ© překrytĆ­" + }, + "counts": { + "label": "Počty překrytĆ­ (pro režim pevnĆ©ho opakovĆ”nĆ­)", + "placeholder": "Zadejte počty oddělenĆ© ÄĆ”rkami (např. 2,3,1)" + }, + "position": { + "label": "Vyberte pozici překrytĆ­", + "foreground": "PopředĆ­", + "background": "PozadĆ­" + }, + "submit": "Odeslat" + }, + "split-by-sections": { + "tags": "SekčnĆ­ dělenĆ­,Rozdělit,PřizpÅÆsobit", + "title": "Rozdělit PDF podle sekcĆ­", + "header": "Rozdělit PDF do sekcĆ­", + "horizontal": { + "label": "HorizontĆ”lnĆ­ dělenĆ­", + "placeholder": "Zadejte počet horizontĆ”lnĆ­ch dělenĆ­" + }, + "vertical": { + "label": "VertikĆ”lnĆ­ dělenĆ­", + "placeholder": "Zadejte počet vertikĆ”lnĆ­ch dělenĆ­" + }, + "submit": "Rozdělit PDF", + "merge": "Sloučit do jednoho PDF" + }, + "AddStampRequest": { + "tags": "RazĆ­tko,Přidat obrĆ”zek,centrovat obrĆ”zek,Vodoznak,PDF,Vložit,PřizpÅÆsobit", + "header": "RazĆ­tko PDF", + "title": "RazĆ­tko PDF", + "stampType": "Typ razĆ­tka", + "stampText": "Text razĆ­tka", + "stampImage": "ObrĆ”zek razĆ­tka", + "alphabet": "Abeceda", + "fontSize": "Velikost pĆ­sma/obrĆ”zku", + "rotation": "OtočenĆ­", + "opacity": "PrÅÆhlednost", + "position": "Pozice", + "overrideX": "Přepsat souřadnici X", + "overrideY": "Přepsat souřadnici Y", + "customMargin": "VlastnĆ­ okraj", + "customColor": "VlastnĆ­ barva textu", + "submit": "Odeslat" + }, + "removeImagePdf": { + "tags": "Odstranit obrĆ”zek,Operace strĆ”nek,zadnĆ­ strana,serverovĆ” strana" + }, + "splitPdfByChapters": { + "tags": "rozdělit,kapitoly,zĆ”ložky,uspořÔdat" + }, + "validateSignature": { + "tags": "podpis,ověřit,validovat,pdf,certifikĆ”t,digitĆ”lnĆ­ podpis,Ověřit podpis,Ověřit certifikĆ”t", + "title": "Ověřit podpisy PDF", + "header": "Ověřit digitĆ”lnĆ­ podpisy", + "selectPDF": "Vyberte podepsaný PDF soubor", + "submit": "Ověřit podpisy", + "results": "Výsledky ověřenĆ­", + "status": { + "_value": "Stav", + "valid": "Platný", + "invalid": "Neplatný" + }, + "signer": "PodepisujĆ­cĆ­", + "date": "Datum", + "reason": "DÅÆvod", + "location": "UmĆ­stěnĆ­", + "noSignatures": "V tomto dokumentu nebyly nalezeny žÔdnĆ© digitĆ”lnĆ­ podpisy", + "chain": { + "invalid": "OvěřenĆ­ řetězce certifikĆ”tÅÆ selhalo - nelze ověřit identitu podepisujĆ­cĆ­ho" + }, + "trust": { + "invalid": "CertifikĆ”t nenĆ­ v ĆŗložiÅ”ti dÅÆvěryhodných certifikĆ”tÅÆ - zdroj nelze ověřit" + }, + "cert": { + "expired": "CertifikĆ”t vyprÅ”el", + "revoked": "CertifikĆ”t byl zruÅ”en", + "info": "Detaily certifikĆ”tu", + "issuer": "Vydavatel", + "subject": "Předmět", + "serialNumber": "SĆ©riovĆ© čƭslo", + "validFrom": "Platný od", + "validUntil": "Platný do", + "algorithm": "Algoritmus", + "keySize": "Velikost klƭče", + "version": "Verze", + "keyUsage": "PoužitĆ­ klƭče", + "selfSigned": "Podepsaný sĆ”m sebou", + "bits": "bitÅÆ" + }, + "signature": { + "info": "Informace o podpisu", + "_value": "Podpis", + "mathValid": "Podpis je matematicky platný, ALE:" + }, + "selectCustomCert": "VlastnĆ­ certifikĆ”t X.509 (VolitelnĆ©)" + }, + "replace-color": { + "title": "Nahradit a invertovat barvy", + "header": "Nahradit a invertovat barvy v PDF", + "selectText": { + "1": "Možnosti nahrazenĆ­ nebo inverze barev", + "2": "VýchozĆ­ (přednastavenĆ© kontrastnĆ­ barvy)", + "3": "VlastnĆ­ (uživatelsky definovanĆ© barvy)", + "4": "ÚplnĆ” inverze (invertovat vÅ”echny barvy)", + "5": "Možnosti vysokĆ©ho kontrastu", + "6": "BĆ­lý text na černĆ©m pozadĆ­", + "7": "Černý text na bĆ­lĆ©m pozadĆ­", + "8": "Žlutý text na černĆ©m pozadĆ­", + "9": "Zelený text na černĆ©m pozadĆ­", + "10": "Vybrat barvu textu", + "11": "Vybrat barvu pozadĆ­" + }, + "submit": "Nahradit" + }, + "replaceColorPdf": { + "tags": "nahrazenĆ­ barev,Ćŗprava strĆ”nek,zpracovĆ”nĆ­,serverovĆ” ÄĆ”st" + }, + "login": { + "title": "PřihlÔŔenĆ­", + "header": "PřihlÔŔenĆ­", + "signin": "PřihlĆ”sit se", + "rememberme": "Zapamatovat si mě", + "invalid": "NeplatnĆ© uživatelskĆ© jmĆ©no nebo heslo.", + "locked": "VÔŔ ĆŗÄet byl uzamčen.", + "signinTitle": "ProsĆ­m přihlaste se", + "ssoSignIn": "PřihlĆ”sit se přes Single Sign-on", + "oAuth2AutoCreateDisabled": "AutomatickĆ© vytvÔřenĆ­ OAUTH2 uživatelÅÆ je zakĆ”zĆ”no", + "oAuth2AdminBlockedUser": "Registrace nebo přihlÔŔenĆ­ neregistrovaných uživatelÅÆ je momentĆ”lně blokovĆ”no. Kontaktujte prosĆ­m sprĆ”vce.", + "oauth2RequestNotFound": "Požadavek na autorizaci nebyl nalezen", + "oauth2InvalidUserInfoResponse": "NeplatnĆ” odpověď s informacemi o uživateli", + "oauth2invalidRequest": "Neplatný požadavek", + "oauth2AccessDenied": "Přístup odepřen", + "oauth2InvalidTokenResponse": "NeplatnĆ” odpověď tokenu", + "oauth2InvalidIdToken": "Neplatný Id Token", + "relyingPartyRegistrationNotFound": "Nebyla nalezena žÔdnĆ” registrace spolĆ©hajĆ­cĆ­ se strany", + "userIsDisabled": "Uživatel je deaktivovĆ”n, přihlÔŔenĆ­ je momentĆ”lně pro toto uživatelskĆ© jmĆ©no blokovĆ”no. Kontaktujte prosĆ­m sprĆ”vce.", + "alreadyLoggedIn": "Již jste přihlÔŔeni na", + "alreadyLoggedIn2": "zařízenĆ­ch. Odhlaste se prosĆ­m z těchto zařízenĆ­ a zkuste to znovu.", + "toManySessions": "MĆ”te příliÅ” mnoho aktivnĆ­ch relacĆ­", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF na jednu strĆ”nku", + "header": "PDF na jednu strĆ”nku", + "submit": "PřevĆ©st na jednu strĆ”nku" + }, + "pageExtracter": { + "title": "Extrahovat strĆ”nky", + "header": "Extrahovat strĆ”nky", + "submit": "Extrahovat", + "placeholder": "(např. 1,2,8 nebo 4,7,12-16 nebo 2n-1)" + }, + "sanitizePDF": { + "title": "Sanitizovat PDF", + "header": "Sanitizovat PDF soubor", + "selectText": { + "1": "Odstranit JavaScript akce", + "2": "Odstranit vloženĆ© soubory", + "3": "Remove XMP metadata", + "4": "Odstranit odkazy", + "5": "Odstranit pĆ­sma", + "6": "Remove Document Info Metadata" + }, + "submit": "Sanitizovat PDF" + }, + "adjustContrast": { + "title": "Upravit kontrast", + "header": "Upravit kontrast", + "contrast": "Kontrast:", + "brightness": "Jas:", + "saturation": "Sytost:", + "download": "StĆ”hnout" + }, + "compress": { + "title": "Komprimovat", + "header": "Komprimovat PDF", + "credit": "Tato služba používĆ” qpdf pro kompresi/optimalizaci PDF.", + "grayscale": { + "label": "Použít stupnici Å”edi pro kompresi" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Úroveň optimalizace:", + "4": "Automatický režim - Automaticky upravuje kvalitu pro dosaženĆ­ přesnĆ© velikosti PDF", + "5": "OčekĆ”vanĆ” velikost PDF (např. 25MB, 10.8MB, 25KB)" + }, + "submit": "Komprimovat" + }, + "decrypt": { + "passwordPrompt": "Tento soubor je chrĆ”něn heslem. Zadejte prosĆ­m heslo:", + "cancelled": "Operace byla zruÅ”ena pro PDF: {0}", + "noPassword": "Nebylo zadĆ”no heslo pro zaÅ”ifrovanĆ© PDF: {0}", + "invalidPassword": "Zkuste to prosĆ­m znovu se sprĆ”vným heslem.", + "invalidPasswordHeader": "NesprĆ”vnĆ© heslo nebo nepodporovanĆ© Å”ifrovĆ”nĆ­ pro PDF: {0}", + "unexpectedError": "Při zpracovĆ”nĆ­ souboru doÅ”lo k chybě. Zkuste to prosĆ­m znovu.", + "serverError": "Chyba serveru při deÅ”ifrovĆ”nĆ­: {0}", + "success": "Soubor byl ĆŗspěŔně deÅ”ifrovĆ”n." + }, + "multiTool-advert": { + "message": "Tato funkce je takĆ© k dispozici na naŔí strĆ”nce multi-nĆ”stroje. PodĆ­vejte se na ni pro vylepÅ”enĆ© rozhranĆ­ pro prĆ”ci se strĆ”nkami a dalŔí funkce!" + }, + "pageRemover": { + "title": "OdstraněnĆ­ strĆ”nek", + "header": "OdstraněnĆ­ strĆ”nek z PDF", + "pagesToDelete": "StrĆ”nky k odstraněnĆ­ (Zadejte seznam čƭsel strĆ”nek oddělených ÄĆ”rkami):", + "submit": "Smazat strĆ”nky", + "placeholder": "(např. 1,2,6 nebo 1-10,15-30)" + }, + "imageToPDF": { + "title": "ObrĆ”zek na PDF", + "header": "ObrĆ”zek na PDF", + "submit": "PřevĆ©st", + "selectLabel": "Možnosti přizpÅÆsobenĆ­ obrĆ”zku", + "fillPage": "Vyplnit strĆ”nku", + "fitDocumentToImage": "PřizpÅÆsobit strĆ”nku obrĆ”zku", + "maintainAspectRatio": "Zachovat poměr stran", + "selectText": { + "2": "Automaticky otočit PDF", + "3": "Logika pro vĆ­ce souborÅÆ (Povoleno pouze při prĆ”ci s vĆ­ce obrĆ”zky)", + "4": "Sloučit do jednoho PDF", + "5": "PřevĆ©st na samostatnĆ© PDF" + } + }, + "PDFToCSV": { + "title": "PDF na CSV", + "header": "PDF na CSV", + "prompt": "Vyberte strĆ”nku pro extrakci tabulky", + "submit": "Extrahovat" + }, + "split-by-size-or-count": { + "title": "Rozdělit PDF podle velikosti nebo počtu", + "header": "Rozdělit PDF podle velikosti nebo počtu", + "type": { + "label": "Vyberte typ rozdělenĆ­", + "size": "Podle velikosti", + "pageCount": "Podle počtu strĆ”nek", + "docCount": "Podle počtu dokumentÅÆ" + }, + "value": { + "label": "Zadejte hodnotu", + "placeholder": "Zadejte velikost (např. 2MB nebo 3KB) nebo počet (např. 5)" + }, + "submit": "Odeslat" + }, + "printFile": { + "title": "Tisk souboru", + "header": "Tisk souboru na tiskĆ”rně", + "selectText": { + "1": "Vyberte soubor k tisku", + "2": "Zadejte nĆ”zev tiskĆ”rny" + }, + "submit": "Tisknout" + }, + "licenses": { + "nav": "Licence", + "title": "Licence třetĆ­ch stran", + "header": "Licence třetĆ­ch stran", + "module": "Modul", + "version": "Verze", + "license": "Licence" + }, + "survey": { + "nav": "PrÅÆzkum", + "title": "PrÅÆzkum Stirling-PDF", + "description": "Stirling-PDF nemĆ” sledovĆ”nĆ­, proto chceme slyÅ”et od naÅ”ich uživatelÅÆ, abychom mohli Stirling-PDF vylepÅ”it!", + "changes": "Stirling-PDF se od poslednĆ­ho prÅÆzkumu změnil! Pro vĆ­ce informacĆ­ se podĆ­vejte na nÔŔ blogový příspěvek zde:", + "changes2": "S těmito změnami zĆ­skĆ”vĆ”me placenou obchodnĆ­ podporu a financovĆ”nĆ­", + "please": "Zvažte prosĆ­m ĆŗÄast v naÅ”em prÅÆzkumu!", + "disabled": "(VyskakovacĆ­ okno prÅÆzkumu bude v nĆ”sledujĆ­cĆ­ch aktualizacĆ­ch zakĆ”zĆ”no, ale zÅÆstane dostupnĆ© v zĆ”patĆ­ strĆ”nky)", + "button": "ZĆŗÄastnit se prÅÆzkumu", + "dontShowAgain": "Již nezobrazovat", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Odstranit obrĆ”zek", + "header": "Odstranit obrĆ”zek", + "removeImage": "Odstranit obrĆ”zek", + "submit": "Odstranit obrĆ”zek" + }, + "splitByChapters": { + "title": "Rozdělit PDF podle kapitol", + "header": "Rozdělit PDF podle kapitol", + "bookmarkLevel": "Úroveň zĆ”ložek", + "includeMetadata": "Zahrnout metadata", + "allowDuplicates": "Povolit duplicity", + "desc": { + "1": "Tento nĆ”stroj rozdělĆ­ PDF soubor na vĆ­ce PDF podle struktury kapitol.", + "2": "Úroveň zĆ”ložek: Vyberte Ćŗroveň zĆ”ložek pro rozdělenĆ­ (0 pro nejvyŔŔí Ćŗroveň, 1 pro druhou Ćŗroveň atd.).", + "3": "Zahrnout metadata: Pokud je zaÅ”krtnuto, metadata pÅÆvodnĆ­ho PDF budou zahrnuta v každĆ©m rozdělenĆ©m PDF.", + "4": "Povolit duplicity: Pokud je zaÅ”krtnuto, umožňuje vytvořenĆ­ samostatných PDF z vĆ­ce zĆ”ložek na stejnĆ© strĆ”nce." + }, + "submit": "Rozdělit PDF" + }, + "fileChooser": { + "click": "Kliknout", + "or": "nebo", + "dragAndDrop": "PřetĆ”hnout", + "dragAndDropPDF": "PřetĆ”hnout PDF soubor", + "dragAndDropImage": "PřetĆ”hnout obrĆ”zek", + "hoveredDragAndDrop": "PřetĆ”hněte soubor(y) sem", + "extractPDF": "ExtrahovĆ”nĆ­..." + }, + "releases": { + "footer": "VydĆ”nĆ­", + "title": "PoznĆ”mky k vydĆ”nĆ­", + "header": "PoznĆ”mky k vydĆ”nĆ­", + "current": { + "version": "AktuĆ”lnĆ­ vydĆ”nĆ­" + }, + "note": "PoznĆ”mky k vydĆ”nĆ­ jsou dostupnĆ© pouze v angličtině" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/da-DK/translation.json b/frontend/public/locales/da-DK/translation.json new file mode 100644 index 000000000..668a3f56f --- /dev/null +++ b/frontend/public/locales/da-DK/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "SkriftstĆørrelse", + "fontName": "Skriftnavn", + "title": "TilfĆøj Sidenumre", + "header": "TilfĆøj Sidenumre", + "selectText": { + "1": "VƦlg PDF-fil:", + "2": "MarginstĆørrelse", + "3": "Plassering", + "4": "Startnummer", + "5": "Sider at nummerere", + "6": "Brugerdefineret Tekst" + }, + "customTextDesc": "Brugerdefineret Tekst", + "numberPagesDesc": "Hvilke sider der skal nummereres, standard 'alle', accepterer ogsĆ„ 1-5 eller 2,5,9 osv.", + "customNumberDesc": "Standard er {n}, accepterer ogsĆ„ 'Side {n} af {total}', 'Tekst-{n}', '{filnavn}-{n}", + "submit": "TilfĆøj Sidenumre" + }, + "pdfPrompt": "VƦlg PDF-fil(er)", + "multiPdfPrompt": "VƦlg PDF-filerne (2+)", + "multiPdfDropPrompt": "VƦlg (eller drag & drop) alle PDF-filerne du skal bruge", + "imgPrompt": "VƦlg Billede(r)", + "genericSubmit": "Indsend", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Advarsel: Denne proces kan tage op til et helt minut, alt efter stĆørrelsen pĆ„ filen", + "pageOrderPrompt": "Brugerdefineret siderƦkkefĆølge (Indtast en kommasepareret liste af sidenumre eller funktioner som 2n+1) :", + "pageSelectionPrompt": "Brugerdefineret sidevalg (Indtast en kommasepareret liste af sidenumre 1,5,6 eller funktioner som 2n+1) :", + "goToPage": "GĆ„", + "true": "Sandt", + "false": "Falsk", + "unknown": "Ukendt", + "save": "Gem", + "saveToBrowser": "Gem til browser", + "close": "Luk", + "filesSelected": "Filer valgt", + "noFavourites": "Ingen favoritter tilfĆøjet", + "downloadComplete": "Download fuldfĆørt", + "bored": "TrƦt af at vente?", + "alphabet": "Alfabet", + "downloadPdf": "Download PDF", + "text": "Tekst", + "font": "Skrifttype", + "selectFillter": "-- VƦlg --", + "pageNum": "Sidenummer", + "sizes": { + "small": "Lille", + "medium": "Mellem", + "large": "Stor", + "x-large": "X-Stor" + }, + "error": { + "pdfPassword": "PDF-dokumentet er beskyttet med adgangskode, og enten blev adgangskoden ikke angivet eller var forkert", + "_value": "Fejl", + "sorry": "Beklager fejlen!", + "needHelp": "Brug for hjƦlp / Fundet et problem?", + "contactTip": "Hvis du stadig har problemer, skal du endelig tage kontakt til os, for at fĆ„ hjƦlp. Du kan oprette en ticket pĆ„ vores Github-side eller tage kontakt til os via Discord:", + "404": { + "head": "404 - Siden ikke fundet | Ups, vi er viklet helt ind i kode!", + "1": "Vi kan ikke finde siden du leder efter.", + "2": "Noget gik galt" + }, + "github": "Indsend en ticket pĆ„ GitHub", + "showStack": "Vis Stack Trace", + "copyStack": "Kopier Stack Trace", + "githubSubmit": "GitHub - Indsend en ticket", + "discordSubmit": "Discord - Indsend Support post" + }, + "delete": "Slet", + "username": "Brugernavn", + "password": "Adgangskode", + "welcome": "Velkommen", + "property": "Egenskab", + "black": "Sort", + "white": "Hvid", + "red": "RĆød", + "green": "GrĆøn", + "blue": "BlĆ„", + "custom": "Brugerdefineret...", + "WorkInProgess": "Arbejde i gang, Kan muligvis ikke virke eller have fejl, RapportĆ©r venligst eventuelle problemer!", + "poweredBy": "Drevet af", + "yes": "Ja", + "no": "Nej", + "changedCredsMessage": "Legitimationsoplysninger Ʀndret!", + "notAuthenticatedMessage": "Bruger ikke autoriseret.", + "userNotFoundMessage": "Bruger ikke fundet.", + "incorrectPasswordMessage": "NuvƦrende adgangskode er forkert.", + "usernameExistsMessage": "Nyt brugernavn findes allerede.", + "invalidUsernameMessage": "Ugyldigt brugernavn, brugernavn mĆ„ kun indeholde bogstaver, tal og fĆølgende specialtegn @._+- eller skal vƦre en gyldig e-mailadresse.", + "invalidPasswordMessage": "Adgangskoden mĆ„ ikke vƦre tom og mĆ„ ikke have mellemrum i begyndelsen eller slutningen.", + "confirmPasswordErrorMessage": "Ny adgangskode og BekrƦft ny adgangskode skal matche.", + "deleteCurrentUserMessage": "Kan ikke slette den aktuelt indloggede bruger.", + "deleteUsernameExistsMessage": "Brugernavnet eksisterer ikke og kan ikke slettes.", + "downgradeCurrentUserMessage": "Kan ikke nedgradere den aktuelle brugers rolle", + "disabledCurrentUserMessage": "Den aktuelle bruger kan ikke deaktiveres", + "downgradeCurrentUserLongMessage": "Kan ikke nedgradere den aktuelle brugers rolle. Derfor vil den aktuelle bruger ikke blive vist.", + "userAlreadyExistsOAuthMessage": "Brugeren eksisterer allerede som en OAuth2-bruger.", + "userAlreadyExistsWebMessage": "Brugeren eksisterer allerede som en webbruger.", + "oops": "Ups!", + "help": "HjƦlp", + "goHomepage": "GĆ„ til hovedsiden", + "joinDiscord": "Deltag i vores Discord-server", + "seeDockerHub": "Se Docker Hub", + "visitGithub": "BesĆøg Github Repository", + "donate": "DonĆ©r", + "color": "Farve", + "sponsor": "Sponsorer", + "info": "Info", + "pro": "Pro", + "page": "Sidenummer", + "pages": "Sideantal", + "loading": "Laster...", + "addToDoc": "TilfĆøj til Dokument", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Privacy Policy", + "terms": "VilkĆ„r og betingelser", + "accessibility": "AdgangsnƦvnteglen", + "cookie": "Cokiebelejring", + "impressum": "Angivelse af ansvar", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Pipeline Menu (Beta)", + "uploadButton": "Upload Brugerdefineret", + "configureButton": "KonfigurĆ©r", + "defaultOption": "Brugerdefineret", + "submitButton": "Indsend", + "help": "Pipeline HjƦlp", + "scanHelp": "Mappe Scanning HjƦlp", + "deletePrompt": "Er du sikker pĆ„, at du vil slette pipeline", + "tags": "automatisĆ©r,sekvens,scriptet,batch-proces", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Pipeline Konfiguration", + "pipelineNameLabel": "Pipeline Navn", + "saveSettings": "Gem Operationsindstillinger", + "pipelineNamePrompt": "Indtast pipeline navn her", + "selectOperation": "VƦlg Operation", + "addOperationButton": "TilfĆøj operation", + "pipelineHeader": "Pipeline:", + "saveButton": "Download", + "validateButton": "ValidĆ©r" + }, + "enterpriseEdition": { + "button": "Opgrader til Pro", + "warning": "Denne funktion er kun tilgƦngelig for Pro-brugere.", + "yamlAdvert": "Stirling PDF Pro understĆøtter YAML-konfigurationsfiler og andre SSO-funktioner.", + "ssoAdvert": "sĆøger du flere funktioner til brugerstyring? PrĆøv Stirling PDF Pro" + }, + "analytics": { + "title": "Vil du gĆøre Stirling PDF bedre?", + "paragraph1": "Stirling PDF har indsat analytics for at hjƦlpe os med at forbedre produktet. Vi fĆølger ikke nogen personoplysninger eller filinhold.", + "paragraph2": "BevƦgelsesmƦssigt aktiver du analytics for at hjƦlpe Stirling-PDF med at vokse og til atstĆ„ os bedre at forstĆ„ vores brugere.", + "enable": "AktivĆ©r analytics", + "disable": "Deaktiver analytics", + "settings": "Du kan Ʀndre analytics-indstillingerne i config/settings.yml-filen" + }, + "navbar": { + "favorite": "Favoritter", + "recent": "New and recently updated", + "darkmode": "MĆørk Tilstand", + "language": "Sprog", + "settings": "Indstillinger", + "allTools": "VƦrktĆøjer", + "multiTool": "Multi VƦrktĆøjer", + "search": "Search", + "sections": { + "organize": "OrganisĆ©r", + "convertTo": "KonvertĆ©r til PDF", + "convertFrom": "KonvertĆ©r fra PDF", + "security": "SignĆ©r & Sikkerhed", + "advance": "Avanceret", + "edit": "Vis & RedigĆ©r", + "popular": "PopulƦre" + } + }, + "settings": { + "title": "Indstillinger", + "update": "Opdatering tilgƦngelig", + "updateAvailable": "{0} er den aktuelt installerede version. En ny version ({1}) er tilgƦngelig.", + "appVersion": "App Version:", + "downloadOption": { + "title": "VƦlg download mulighed (For enkelt fil ikke-zip downloads):", + "1": "ƅbn i samme vindue", + "2": "ƅbn i nyt vindue", + "3": "Download fil" + }, + "zipThreshold": "Zip filer nĆ„r antallet af downloadede filer overstiger", + "signOut": "Log ud", + "accountSettings": "Kontoindstillinger", + "bored": { + "help": "Aktiverer pĆ„skeƦg spil" + }, + "cacheInputs": { + "name": "Gem formularinput", + "help": "AktivĆ©r for at gemme tidligere anvendte input til fremtidige kĆørsler" + } + }, + "changeCreds": { + "title": "Skift Legitimationsoplysninger", + "header": "Opdater Dine Kontooplysninger", + "changePassword": "Du bruger standard loginoplysninger. Indtast venligst en ny adgangskode", + "newUsername": "Nyt Brugernavn", + "oldPassword": "NuvƦrende Adgangskode", + "newPassword": "Ny Adgangskode", + "confirmNewPassword": "BekrƦft Ny Adgangskode", + "submit": "Indsend Ɔndringer" + }, + "account": { + "title": "Kontoindstillinger", + "accountSettings": "Kontoindstillinger", + "adminSettings": "Administratorindstillinger - Se og TilfĆøj Brugere", + "userControlSettings": "Brugerkontrolindstillinger", + "changeUsername": "Skift Brugernavn", + "newUsername": "Nyt Brugernavn", + "password": "BekrƦftelsesadgangskode", + "oldPassword": "Gammel adgangskode", + "newPassword": "Ny Adgangskode", + "changePassword": "Skift Adgangskode", + "confirmNewPassword": "BekrƦft Ny Adgangskode", + "signOut": "Log ud", + "yourApiKey": "Din API-nĆøgle", + "syncTitle": "Synkroniser browserindstillinger med Konto", + "settingsCompare": "Indstillinger Sammenligning:", + "property": "Egenskab", + "webBrowserSettings": "Webbrowser Indstilling", + "syncToBrowser": "Synkroniser Konto -> Browser", + "syncToAccount": "Synkroniser Konto <- Browser" + }, + "adminUserSettings": { + "title": "Brugerkontrolindstillinger", + "header": "Admin Brugerkontrolindstillinger", + "admin": "Administrer", + "user": "Bruger", + "addUser": "TilfĆøj Ny Bruger", + "deleteUser": "Slet Bruger", + "confirmDeleteUser": "Skal brugeren slettes?", + "confirmChangeUserStatus": "Skal brugeren deaktiveres/aktiveres?", + "usernameInfo": "Brugernavn mĆ„ kun indeholde bogstaver, tal og fĆølgende specialtegn @._+- eller skal vƦre en gyldig e-mailadresse.", + "roles": "Roller", + "role": "Rolle", + "actions": "Handlinger", + "apiUser": "BegrƦnset API-bruger", + "extraApiUser": "Yderligere BegrƦnset API-bruger", + "webOnlyUser": "Kun Web-bruger", + "demoUser": "Demo-bruger (Ingen brugerdefinerede indstillinger)", + "internalApiUser": "Intern API-bruger", + "forceChange": "Tving bruger til at Ʀndre adgangskode ved login", + "submit": "Gem Bruger", + "changeUserRole": "Ɔndre Brugerens Rolle", + "authenticated": "Autentificeret", + "editOwnProfil": "Rediger egen profil", + "enabledUser": "aktiveret bruger", + "disabledUser": "deaktiveret bruger", + "activeUsers": "Aktive Brugere:", + "disabledUsers": "Deaktiverede Brugere:", + "totalUsers": "Samlet Antal Brugere:", + "lastRequest": "Seneste Anmodning", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Database Import/Eksport", + "header": "Database Import/Eksport", + "fileName": "Filnavn", + "creationDate": "Oprettelsesdato", + "fileSize": "FilstĆørrelse", + "deleteBackupFile": "Slet Backup-fil", + "importBackupFile": "ImportĆ©r Backup-fil", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Download Backup-fil", + "info_1": "Ved import af data er det afgĆørende at sikre den korrekte struktur. Hvis du er usikker pĆ„, hvad du gĆør, sĆøg rĆ„d og stĆøtte fra en professionel. En fejl i strukturen kan forĆ„rsage applikationsfejl, op til og med fuldstƦndig manglende evne til at kĆøre applikationen.", + "info_2": "Filnavnet er ligegyldigt ved upload. Det vil blive omdĆøbt bagefter for at fĆølge formatet backup_user_yyyyMMddHHmm.sql, hvilket sikrer en konsistent navngivningskonvention.", + "submit": "ImportĆ©r Backup", + "importIntoDatabaseSuccessed": "Import i database lykkedes", + "backupCreated": "Database backup successful", + "fileNotFound": "Fil ikke fundet", + "fileNullOrEmpty": "Fil mĆ„ ikke vƦre null eller tom", + "failedImportFile": "Kunne ikke importere fil", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "Din sesions tid har udlĆøbet. Genlad siden og prĆøv igen.", + "refreshPage": "Refresh Page" + }, + "home": { + "desc": "Dit lokalt hostede one-stop-shop for alle dine PDF-behov.", + "searchBar": "SĆøg efter funktioner...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Se, annotĆ©r, tilfĆøj tekst eller billeder" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "PDF Multi VƦrktĆøj", + "desc": "Flet, RotĆ©r, OmarrangĆ©r og Fjern sider" + }, + "merge": { + "title": "Flet", + "desc": "Flet nemt flere PDF'er til Ć©n." + }, + "split": { + "title": "Opdel", + "desc": "Opdel PDF'er i flere dokumenter" + }, + "rotate": { + "title": "RotĆ©r", + "desc": "RotĆ©r nemt dine PDF'er." + }, + "imageToPdf": { + "title": "Billede til PDF", + "desc": "KonvertĆ©r et billede (PNG, JPEG, GIF) til PDF." + }, + "pdfToImage": { + "title": "PDF til Billede", + "desc": "KonvertĆ©r en PDF til et billede. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "OrganisĆ©r", + "desc": "Fjern/OmarrangĆ©r sider i vilkĆ„rlig rƦkkefĆølge" + }, + "addImage": { + "title": "TilfĆøj billede", + "desc": "TilfĆøjer et billede pĆ„ en bestemt placering pĆ„ PDF'en" + }, + "watermark": { + "title": "TilfĆøj VandmƦrke", + "desc": "TilfĆøj et brugerdefineret vandmƦrke til dit PDF-dokument." + }, + "permissions": { + "title": "Ɔndre Tilladelser", + "desc": "Ɔndre tilladelserne for dit PDF-dokument" + }, + "removePages": { + "title": "Fjern", + "desc": "Slet uĆønskede sider fra dit PDF-dokument." + }, + "addPassword": { + "title": "TilfĆøj Adgangskode", + "desc": "KryptĆ©r dit PDF-dokument med en adgangskode." + }, + "removePassword": { + "title": "Fjern Adgangskode", + "desc": "Fjern adgangskodebeskyttelse fra dit PDF-dokument." + }, + "compressPdfs": { + "title": "Komprimer", + "desc": "Komprimer PDF'er for at reducere deres filstĆørrelse." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Ɔndre Metadata", + "desc": "Ɔndre/Fjern/TilfĆøj metadata fra et PDF-dokument" + }, + "fileToPDF": { + "title": "KonvertĆ©r fil til PDF", + "desc": "KonvertĆ©r nƦsten enhver fil til PDF (DOCX, PNG, XLS, PPT, TXT og mere)" + }, + "ocr": { + "title": "OCR / Oprydning af scanninger", + "desc": "Oprydning af scanninger og genkender tekst fra billeder i en PDF og tilfĆøjer den igen som tekst." + }, + "extractImages": { + "title": "UdtrƦk Billeder", + "desc": "UdtrƦkker alle billeder fra en PDF og gemmer dem som zip" + }, + "pdfToPDFA": { + "title": "PDF til PDF/A", + "desc": "KonvertĆ©r PDF til PDF/A for langtidsopbevaring" + }, + "PDFToWord": { + "title": "PDF til Word", + "desc": "KonvertĆ©r PDF til Word-formater (DOC, DOCX og ODT)" + }, + "PDFToPresentation": { + "title": "PDF til PrƦsentation", + "desc": "KonvertĆ©r PDF til PrƦsentationsformater (PPT, PPTX og ODP)" + }, + "PDFToText": { + "title": "PDF til RTF (Tekst)", + "desc": "KonvertĆ©r PDF til Tekst eller RTF-format" + }, + "PDFToHTML": { + "title": "PDF til HTML", + "desc": "KonvertĆ©r PDF til HTML-format" + }, + "PDFToXML": { + "title": "PDF til XML", + "desc": "KonvertĆ©r PDF til XML-format" + }, + "ScannerImageSplit": { + "title": "DetektĆ©r/Opdel Scannede fotosb", + "desc": "Opdeler flere fotos fra et enkelt foto/PDF" + }, + "sign": { + "title": "Underskriv", + "desc": "TilfĆøjer underskrift til PDF ved tegning, tekst eller billede" + }, + "flatten": { + "title": "UdjƦvn", + "desc": "Fjern alle interaktive elementer og formularer fra en PDF" + }, + "repair": { + "title": "ReparĆ©r", + "desc": "ForsĆøger at reparere en korrupt/Ćødelagt PDF" + }, + "removeBlanks": { + "title": "Fjern Tomme sider", + "desc": "Detekterer og fjerner tomme sider fra et dokument" + }, + "removeAnnotations": { + "title": "Fjern AnmƦrkninger", + "desc": "Fjerner alle kommentarer/anmƦrkninger fra en PDF" + }, + "compare": { + "title": "Sammenlign", + "desc": "Sammenligner og viser forskellene mellem 2 PDF-dokumenter" + }, + "certSign": { + "title": "Underskriv med Certifikat", + "desc": "Underskriver en PDF med et Certifikat/NĆøgle (PEM/P12)" + }, + "removeCertSign": { + "title": "Fjern Certifikatunderskrift", + "desc": "Fjern certifikatunderskrift fra PDF" + }, + "pageLayout": { + "title": "Multi-Side Layout", + "desc": "Flet flere sider af et PDF-dokument til en enkelt side" + }, + "scalePages": { + "title": "JustĆ©r sidestĆørrelse/skala", + "desc": "Ɔndre stĆørrelsen/skalaen af en side og/eller dens indhold." + }, + "pipeline": { + "title": "Pipeline (Avanceret)", + "desc": "KĆør flere handlinger pĆ„ PDF'er ved at definere pipeline-scripts" + }, + "add-page-numbers": { + "title": "TilfĆøj Sidenumre", + "desc": "TilfĆøj Sidenumre gennem hele dokumentet pĆ„ et bestemt sted" + }, + "auto-rename": { + "title": "Auto OmdĆøb PDF-fil", + "desc": "Auto omdĆøber en PDF-fil baseret pĆ„ dens detekterede overskrift" + }, + "adjust-contrast": { + "title": "JustĆ©r Farver/Kontrast", + "desc": "JustĆ©r Kontrast, MƦtning og Lysstyrke af en PDF" + }, + "crop": { + "title": "BeskƦr PDF", + "desc": "BeskƦr en PDF for at reducere dens stĆørrelse (bevarer tekst!)" + }, + "autoSplitPDF": { + "title": "Auto Opdel Sider", + "desc": "Auto Opdel Scannede PDF'er med fysisk scannet side-splitter QR-kode" + }, + "sanitizePdf": { + "title": "Rens", + "desc": "Fjern scripts og andre elementer fra PDF-filer" + }, + "URLToPDF": { + "title": "URL/Hjemmeside Til PDF", + "desc": "Konverterer enhver http(s)URL til PDF" + }, + "HTMLToPDF": { + "title": "HTML til PDF", + "desc": "Konverterer enhver HTML-fil eller zip til PDF" + }, + "MarkdownToPDF": { + "title": "Markdown til PDF", + "desc": "Konverterer enhver Markdown-fil til PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "FĆ„ ALLE Oplysninger om PDF", + "desc": "Henter alle mulige oplysninger om PDF'er" + }, + "extractPage": { + "title": "UdtrƦk side(r)", + "desc": "UdtrƦkker udvalgte sider fra PDF" + }, + "PdfToSinglePage": { + "title": "PDF til Enkelt Stor Side", + "desc": "Fletter alle PDF-sider til Ć©n stor enkelt side" + }, + "showJS": { + "title": "Vis Javascript", + "desc": "SĆøger og viser eventuelt JS indsprĆøjtet i en PDF" + }, + "autoRedact": { + "title": "Auto Rediger", + "desc": "Auto Redigerer (SvƦrter) tekst i en PDF baseret pĆ„ input tekst" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF til CSV", + "desc": "UdtrƦkker Tabeller fra en PDF og konverterer dem til CSV" + }, + "autoSizeSplitPDF": { + "title": "Auto Opdel efter StĆørrelse/Antal", + "desc": "Opdel en enkelt PDF i flere dokumenter baseret pĆ„ stĆørrelse, sideantal eller dokumentantal" + }, + "overlay-pdfs": { + "title": "Overlejr PDF'er", + "desc": "Overlejrer PDF'er oven pĆ„ en anden PDF" + }, + "split-by-sections": { + "title": "Opdel PDF efter Sektioner", + "desc": "Opdel hver side af en PDF i mindre horisontale og vertikale sektioner" + }, + "AddStampRequest": { + "title": "TilfĆøj Stempel til PDF", + "desc": "TilfĆøj tekst eller tilfĆøj billedstempel pĆ„ bestemte placeringer" + }, + "removeImagePdf": { + "title": "Fjern billede", + "desc": "Fjern billede fra PDF for at reducere filstĆørrelse" + }, + "splitPdfByChapters": { + "title": "Partitioner PDF efter kapitler", + "desc": "Partitioner en PDF i flere filer baseret pĆ„ dens kapitelstruktur." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "replaceColorPdf": { + "title": "Replace and Invert Color", + "desc": "Erstatt farve for tekst og baggrund i en PDF og omgivende farve til fuld farve af PDF for at redusere filstĆørrelsen." + } + }, + "viewPdf": { + "tags": "se,lƦs,annotĆ©r,tekst,billede", + "title": "View/Edit PDF", + "header": "Se PDF" + }, + "multiTool": { + "tags": "Multi VƦrktĆøj,Multi operation,UI,klik trƦk,front end,klient side,interaktiv,interagerbar,flyt", + "title": "PDF Multi VƦrktĆøj", + "header": "PDF Multi VƦrktĆøj", + "uploadPrompts": "Filnavn", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "selectPages": "Page Select", + "selectedPages": "Selected Pages", + "page": "Page", + "deleteSelected": "Delete Selected", + "downloadAll": "Export", + "downloadSelected": "Export Selected", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "Page(s) Selected", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "flet,Sideoperationer,Back end,server side", + "title": "Flet", + "header": "Flet flere PDF'er (2+)", + "sortByName": "SortĆ©r efter navn", + "sortByDate": "SortĆ©r efter dato", + "removeCertSign": "Fjern digital signatur i den flettede fil?", + "submit": "Flet" + }, + "split": { + "tags": "Sideoperationer,opdel,Multi Side,klip,server side", + "title": "Opdel PDF", + "header": "Opdel PDF", + "desc": { + "1": "De tal, du vƦlger, er det sidenummer, du Ćønsker at foretage en opdeling pĆ„", + "2": "Som sĆ„dan ville valg af 1,3,7-9 opdele et 10-siders dokument i 6 separate PDF'er med:", + "3": "Dokument #1: Side 1", + "4": "Dokument #2: Side 2 og 3", + "5": "Dokument #3: Side 4, 5, 6 og 7", + "6": "Dokument #4: Side 8", + "7": "Dokument #5: Side 9", + "8": "Dokument #6: Side 10" + }, + "splitPages": "Indtast sider at opdele pĆ„:", + "submit": "Opdel" + }, + "rotate": { + "tags": "server side", + "title": "RotĆ©r PDF", + "header": "RotĆ©r PDF", + "selectAngle": "VƦlg rotationsvinkel (i multipla af 90 grader):", + "submit": "RotĆ©r" + }, + "imageToPdf": { + "tags": "konvertering,img,jpg,billede,foto" + }, + "pdfToImage": { + "tags": "konvertering,img,jpg,billede,foto", + "title": "PDF til Billede", + "header": "PDF til Billede", + "selectText": "Billedformat", + "singleOrMultiple": "Side til Billede resultattype", + "single": "Enkelt Stort Billede Kombinerer alle sider", + "multi": "Flere Billeder, et billede pr. side", + "colorType": "Farvetype", + "color": "Farve", + "grey": "GrĆ„tone", + "blackwhite": "Sort og Hvid (Kan miste data!)", + "submit": "KonvertĆ©r", + "info": "Python er ikke installeret. PĆ„krƦvet for WebP-konvertering.", + "placeholder": "(f.eks. 1,2,8 eller 4,7,12-16 eller 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,lige,ulige,sortĆ©r,flyt", + "title": "Side Organisator", + "header": "PDF Side Organisator", + "submit": "OmarrangĆ©r Sider", + "mode": { + "_value": "Tilstand", + "1": "Brugerdefineret SiderƦkkefĆølge", + "2": "Omvendt RƦkkefĆølge", + "3": "Duplex Sortering", + "4": "HƦfte Sortering", + "5": "SidehƦftet HƦfte Sortering", + "6": "Ulige-Lige Opdeling", + "7": "Fjern FĆørste", + "8": "Fjern Sidste", + "9": "Fjern FĆørste og Sidste", + "10": "Ulige-Lige SammenfĆøjning", + "11": "Duplicate all pages" + }, + "placeholder": "(f.eks. 1,3,2 eller 4-8,2,10-12 eller 2n-1)" + }, + "addImage": { + "tags": "img,jpg,billede,foto", + "title": "TilfĆøj Billede", + "header": "TilfĆøj billede til PDF", + "everyPage": "Hver Side?", + "upload": "TilfĆøj billede", + "submit": "TilfĆøj billede" + }, + "watermark": { + "tags": "Tekst,gentagne,etiket,egen,ophavsret,varemƦrke,img,jpg,billede,foto", + "title": "TilfĆøj VandmƦrke", + "header": "TilfĆøj VandmƦrke", + "customColor": "Brugerdefineret Tekstfarve", + "selectText": { + "1": "VƦlg PDF til at tilfĆøje vandmƦrke:", + "2": "VandmƦrketekst:", + "3": "SkriftstĆørrelse:", + "4": "Vendt Side (0-360):", + "5": "breddeAfstand (Afstand mellem hvert vandmƦrke vandret):", + "6": "hĆøjdeAfstand (Afstand mellem hvert vandmƦrke lodret):", + "7": "Gennemsigtighed (0% - 100%):", + "8": "VandmƦrketype:", + "9": "VandmƦrkebillede:", + "10": "KonvertĆ©r PDF til PDF-Billede" + }, + "submit": "TilfĆøj VandmƦrke", + "type": { + "1": "Tekst", + "2": "Billede" + } + }, + "permissions": { + "tags": "lƦs,skriv,redigĆ©r,print", + "title": "Ɔndre Tilladelser", + "header": "Ɔndre Tilladelser", + "warning": "Advarsel for at gĆøre disse tilladelser uƦndrede anbefales det at indstille dem med en adgangskode via tilfĆøj-adgangskode siden", + "selectText": { + "1": "VƦlg PDF for at Ʀndre tilladelser", + "2": "Tilladelser at indstille", + "3": "Forhindre samling af dokument", + "4": "Forhindre indholdsudtrƦkning", + "5": "Forhindre udtrƦkning for tilgƦngelighed", + "6": "Forhindre udfyldning af formular", + "7": "Forhindre Ʀndring", + "8": "Forhindre anmƦrkningsƦndring", + "9": "Forhindre udskrivning", + "10": "Forhindre udskrivning af forskellige formater" + }, + "submit": "Ɔndre" + }, + "removePages": { + "tags": "Fjern sider,slet sider" + }, + "addPassword": { + "tags": "sikker,sikkerhed", + "title": "TilfĆøj Adgangskode", + "header": "TilfĆøj adgangskode (KryptĆ©r)", + "selectText": { + "1": "VƦlg PDF til kryptering", + "2": "Brugeradgangskode", + "3": "KrypteringsnĆøglelƦngde", + "4": "HĆøjere vƦrdier er stƦrkere, men lavere vƦrdier har bedre kompatibilitet.", + "5": "Tilladelser at indstille (Anbefales at bruges sammen med Ejer adgangskode)", + "6": "Forhindre samling af dokument", + "7": "Forhindre indholdsudtrƦkning", + "8": "Forhindre udtrƦkning for tilgƦngelighed", + "9": "Forhindre udfyldning af formular", + "10": "Forhindre Ʀndring", + "11": "Forhindre anmƦrkningsƦndring", + "12": "Forhindre udskrivning", + "13": "Forhindre udskrivning af forskellige formater", + "14": "Ejer Adgangskode", + "15": "BegrƦnser hvad der kan gĆøres med dokumentet, nĆ„r det er Ć„bnet (UnderstĆøttes ikke af alle lƦsere)", + "16": "BegrƦnser Ć„bningen af selve dokumentet" + }, + "submit": "KryptĆ©r" + }, + "removePassword": { + "tags": "sikker,DekryptĆ©r,sikkerhed,fjern adgangskode,slet adgangskode", + "title": "Fjern adgangskode", + "header": "Fjern adgangskode (DekryptĆ©r)", + "selectText": { + "1": "VƦlg PDF til Dekryptering", + "2": "Adgangskode" + }, + "submit": "Fjern" + }, + "compressPdfs": { + "tags": "klem,lille,tiny" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Titel,forfatter,dato,oprettelse,tid,udgiver,producent,statistik", + "title": "Ɔndre Metadata", + "header": "Ɔndre Metadata", + "selectText": { + "1": "Rediger venligst de variabler, du Ćønsker at Ʀndre", + "2": "Slet al metadata", + "3": "Vis Brugerdefineret Metadata:", + "4": "Anden Metadata:", + "5": "TilfĆøj Brugerdefineret Metadata Post" + }, + "author": "Forfatter:", + "creationDate": "Oprettelsesdato (ƄƄƄƄ/MM/dd TT:mm:ss):", + "creator": "Skaber:", + "keywords": "NĆøgleord:", + "modDate": "Ɔndringsdato (ƄƄƄƄ/MM/dd TT:mm:ss):", + "producer": "Producent:", + "subject": "Emne:", + "trapped": "Fanget:", + "submit": "Ɔndre" + }, + "fileToPDF": { + "tags": "transformation,format,dokument,billede,dias,tekst,konvertering,kontor,docs,word,excel,powerpoint", + "title": "Fil til PDF", + "header": "KonvertĆ©r enhver fil til PDF", + "credit": "Denne tjeneste bruger LibreOffice og Unoconv til filkonvertering.", + "supportedFileTypesInfo": "UnderstĆøttede Filtyper", + "supportedFileTypes": "UnderstĆøttede filtyper bĆør inkludere nedenstĆ„ende, men for en fuld opdateret liste over understĆøttede formater, se venligst LibreOffice-dokumentationen", + "submit": "KonvertĆ©r til PDF" + }, + "ocr": { + "tags": "genkendelse,tekst,billede,scan,lƦs,identificĆ©r,detektion,redigerbar", + "title": "OCR / Scan Oprydning", + "header": "Oprydning af Scanninger / OCR (Optisk Karaktergenkendelse)", + "selectText": { + "1": "VƦlg sprog, der skal detekteres i PDF'en (De angivne er dem, der i Ćøjeblikket er registreret):", + "2": "ProducĆ©r tekstfil indeholdende OCR-tekst sammen med den OCR'ede PDF", + "3": "KorrigĆ©r sider, der blev scannet i en skƦv vinkel ved at rotere dem tilbage pĆ„ plads", + "4": "Rens siden, sĆ„ det er mindre sandsynligt, at OCR finder tekst i baggrundsstĆøj. (Ingen Ʀndring i output)", + "5": "Rens siden, sĆ„ det er mindre sandsynligt, at OCR finder tekst i baggrundsstĆøj, bevarer oprydning i output.", + "6": "Ignorerer sider, der har interaktiv tekst pĆ„ dem, OCR'er kun sider, der er billeder", + "7": "Tving OCR, vil OCR'e hver side og fjerne alle originale tekstelementer", + "8": "Normal (Vil give fejl, hvis PDF'en indeholder tekst)", + "9": "Yderligere Indstillinger", + "10": "OCR-tilstand", + "11": "Fjern billeder efter OCR (Fjerner ALLE billeder, kun nyttigt hvis det er en del af konverteringstrinnet)", + "12": "Renderingstype (Avanceret)" + }, + "help": "LƦs venligst denne dokumentation om, hvordan man bruger dette til andre sprog og/eller brug uden for docker", + "credit": "Denne tjeneste bruger qpdf og Tesseract til OCR.", + "submit": "Behandl PDF med OCR" + }, + "extractImages": { + "tags": "billede,foto,gem,arkiv,zip,fang,grib", + "title": "UdtrƦk Billeder", + "header": "UdtrƦk Billeder", + "selectText": "VƦlg billedformat til at konvertere udtrukne billeder til", + "allowDuplicates": "Gem duplikerede billeder", + "submit": "UdtrƦk" + }, + "pdfToPDFA": { + "tags": "arkiv,langtids,standard,konvertering,opbevaring,bevaring", + "title": "PDF Til PDF/A", + "header": "PDF Til PDF/A", + "credit": "Denne tjeneste bruger libreoffice til PDF/A-konvertering", + "submit": "KonvertĆ©r", + "tip": "Fungerer i Ćøjeblikket ikke for flere input pĆ„ Ć©n gang", + "outputFormat": "Outputformat", + "pdfWithDigitalSignature": "PDF'en indeholder en digital signatur. Dette vil blive fjernet i nƦste trin." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformation,format,konvertering,kontor,microsoft,docfil", + "title": "PDF til Word", + "header": "PDF til Word", + "selectText": { + "1": "Output filformat" + }, + "credit": "Denne tjeneste bruger LibreOffice til filkonvertering.", + "submit": "KonvertĆ©r" + }, + "PDFToPresentation": { + "tags": "dias,show,kontor,microsoft", + "title": "PDF til PrƦsentation", + "header": "PDF til PrƦsentation", + "selectText": { + "1": "Output filformat" + }, + "credit": "Denne tjeneste bruger LibreOffice til filkonvertering.", + "submit": "KonvertĆ©r" + }, + "PDFToText": { + "tags": "richtextformat,rich text format", + "title": "PDF til RTF (Tekst)", + "header": "PDF til RTF (Tekst)", + "selectText": { + "1": "Output filformat" + }, + "credit": "Denne tjeneste bruger LibreOffice til filkonvertering.", + "submit": "KonvertĆ©r" + }, + "PDFToHTML": { + "tags": "webindhold,browservenlig", + "title": "PDF til HTML", + "header": "PDF til HTML", + "credit": "Denne tjeneste bruger pdftohtml til filkonvertering.", + "submit": "KonvertĆ©r" + }, + "PDFToXML": { + "tags": "dataudtrƦk,struktureret-indhold,interop,transformation,konvertĆ©r", + "title": "PDF til XML", + "header": "PDF til XML", + "credit": "Denne tjeneste bruger LibreOffice til filkonvertering.", + "submit": "KonvertĆ©r" + }, + "ScannerImageSplit": { + "tags": "adskil,auto-detektĆ©r,scanninger,multi-foto,organisĆ©r", + "selectText": { + "1": "VinkeltƦrskel:", + "2": "Indstiller den minimale absolutte vinkel, der krƦves for at billedet roteres (standard: 10).", + "3": "Tolerancen:", + "4": "Bestemmer omrĆ„det for farvevariation omkring den estimerede baggrundsfarve (standard: 30).", + "5": "Minimum Areal:", + "6": "Indstiller den minimale arealtƦrskel for et foto (standard: 10000).", + "7": "Minimum Kontur Areal:", + "8": "Indstiller den minimale kontur arealtƦrskel for et foto", + "9": "KantstĆørrelse:", + "10": "Indstiller stĆørrelsen pĆ„ kanten, der tilfĆøjes og fjernes for at forhindre hvide kanter i outputtet (standard: 1)." + }, + "info": "Python er ikke installeret. Det er nĆødvendigt for at kĆøre." + }, + "sign": { + "tags": "autorisĆ©r,initialer,tegnet-underskrift,tekst-underskrift,billede-underskrift", + "title": "Underskriv", + "header": "Underskriv PDF'er", + "upload": "Upload Billede", + "draw": "Tegn Underskrift", + "text": "Tekstinput", + "clear": "Ryd", + "add": "TilfĆøj", + "saved": "Gemte Signaturer", + "save": "Gem Signatur", + "personalSigs": "Personlige Signaturer", + "sharedSigs": "Delte Signaturer", + "noSavedSigs": "Ingen Gemte Signaturer Fundet", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "statisk,deaktivĆ©r,ikke-interaktiv,strĆømlinje", + "title": "UdjƦvn", + "header": "UdjƦvn PDF", + "flattenOnlyForms": "UdjƦvn kun formularer", + "submit": "UdjƦvn" + }, + "repair": { + "tags": "fix,gendan,korrektion,genvind", + "title": "ReparĆ©r", + "header": "ReparĆ©r PDF'er", + "submit": "ReparĆ©r" + }, + "removeBlanks": { + "tags": "oprydning,strĆømlinje,ikke-indhold,organisĆ©r", + "title": "Fjern Tomme Sider", + "header": "Fjern Tomme Sider", + "threshold": "Pixel HvidhedstƦrskel:", + "thresholdDesc": "TƦrskel for at bestemme, hvor hvid en hvid pixel skal vƦre for at blive klassificeret som 'Hvid'. 0 = Sort, 255 ren hvid.", + "whitePercent": "Hvid Procent (%):", + "whitePercentDesc": "Procent af siden, der skal vƦre 'hvide' pixels for at blive fjernet", + "submit": "Fjern Tomme Sider" + }, + "removeAnnotations": { + "tags": "kommentarer,fremhƦv,noter,markup,fjern", + "title": "Fjern AnmƦrkninger", + "header": "Fjern AnmƦrkninger", + "submit": "Fjern" + }, + "compare": { + "tags": "differentier,kontrast,Ʀndringer,analyse", + "title": "Sammenlign", + "header": "Sammenlign PDF'er", + "highlightColor": { + "1": "FremhƦvningsfarve 1:", + "2": "FremhƦvningsfarve 2:" + }, + "document": { + "1": "Dokument 1", + "2": "Dokument 2" + }, + "submit": "Sammenlign", + "complex": { + "message": "Et eller begge af de angivne dokumenter er store filer, prƦcisionen ved sammenligningen kan geminse." + }, + "large": { + "file": { + "message": "Et eller Begge af de Angivne Dokumenter Er For Store At Behandle" + } + }, + "no": { + "text": { + "message": "Et eller Begge Af de VƦlgede PDFs Har Ingen Tekstindhold. VƦlg Vores PDFs Med Tekst for Sammenligning." + } + } + }, + "certSign": { + "tags": "autentificĆ©r,PEM,P12,officiel,kryptĆ©r", + "title": "Certifikat Underskrivning", + "header": "Underskriv en PDF med dit certifikat (Arbejde i gang)", + "selectPDF": "VƦlg en PDF-fil til underskrivning:", + "jksNote": "BemƦrk: Hvis din certifikattype ikke er angivet nedenfor, skal du konvertere det til en Java Keystore (.jks) fil ved hjƦlp af keytool kommandolinjevƦrktĆøjet. VƦlg derefter .jks fil muligheden nedenfor.", + "selectKey": "VƦlg Din Private NĆøglefil (PKCS#8 format, kan vƦre .pem eller .der):", + "selectCert": "VƦlg Din Certifikatfil (X.509 format, kan vƦre .pem eller .der):", + "selectP12": "VƦlg Din PKCS#12 Keystore Fil (.p12 eller .pfx) (Valgfrit, Hvis angivet, skal den indeholde din private nĆøgle og certifikat):", + "selectJKS": "VƦlg Din Java Keystore Fil (.jks eller .keystore):", + "certType": "Certifikattype", + "password": "Indtast Din Keystore eller Private NĆøgle Adgangskode (Hvis nogen):", + "showSig": "Vis Underskrift", + "reason": "ƅrsag", + "location": "Placering", + "name": "Navn", + "showLogo": "Vis Logo", + "submit": "Underskriv PDF" + }, + "removeCertSign": { + "tags": "autentificĆ©r,PEM,P12,officiel,dekryptĆ©r", + "title": "Fjern Certifikat Underskrift", + "header": "Fjern det digitale certifikat fra PDF'en", + "selectPDF": "VƦlg en PDF-fil:", + "submit": "Fjern Underskrift" + }, + "pageLayout": { + "tags": "flet,sammensƦt,enkelt-visning,organisĆ©r", + "title": "Multi-Side Layout", + "header": "Multi-Side Layout", + "pagesPerSheet": "Sider pr. ark:", + "addBorder": "TilfĆøj Kanter", + "submit": "Indsend" + }, + "scalePages": { + "tags": "Ʀndre stĆørrelse,modificĆ©r,dimension,tilpas", + "title": "JustĆ©r sidestĆørrelse", + "header": "JustĆ©r sidestĆørrelse", + "pageSize": "StĆørrelse pĆ„ en side i dokumentet.", + "keepPageSize": "Original Size", + "scaleFactor": "Zoom-niveau (beskƦring) af en side.", + "submit": "Indsend" + }, + "add-page-numbers": { + "tags": "nummerĆ©r,etiket,organisĆ©r,indeks" + }, + "auto-rename": { + "tags": "auto-detektĆ©r,overskrift-baseret,organisĆ©r,omdĆøb", + "title": "Auto OmdĆøb", + "header": "Auto OmdĆøb PDF", + "submit": "Auto OmdĆøb" + }, + "adjust-contrast": { + "tags": "farvekorrektion,juster,modificĆ©r,forbedre" + }, + "crop": { + "tags": "trim,formindsk,redigĆ©r,form", + "title": "BeskƦr", + "header": "BeskƦr PDF", + "submit": "Indsend" + }, + "autoSplitPDF": { + "tags": "QR-baseret,adskil,scan-segment,organisĆ©r", + "title": "Auto Opdel PDF", + "header": "Auto Opdel PDF", + "description": "Udskriv, IndsƦt, Scan, upload, og lad os auto-adskille dine dokumenter. Intet manuelt arbejde med sortering nĆødvendigt.", + "selectText": { + "1": "Udskriv nogle skilleark fra nedenfor (Sort og hvid er fint).", + "2": "Scan alle dine dokumenter pĆ„ Ć©n gang ved at indsƦtte skillearket mellem dem.", + "3": "Upload den enkelte store scannede PDF-fil og lad Stirling PDF hĆ„ndtere resten.", + "4": "Skillesider detekteres automatisk og fjernes, hvilket garanterer et pƦnt endeligt dokument." + }, + "formPrompt": "Indsend PDF indeholdende Stirling-PDF Sideopdelere:", + "duplexMode": "Duplex-tilstand (For- og bagside scanning)", + "dividerDownload2": "Download 'Auto Splitter Divider (med instruktioner).pdf'", + "submit": "Indsend" + }, + "sanitizePdf": { + "tags": "rens,sikker,sikker,fjern-trusler" + }, + "URLToPDF": { + "tags": "web-fangst,gem-side,web-til-dok,arkivĆ©r", + "title": "URL Til PDF", + "header": "URL Til PDF", + "submit": "KonvertĆ©r", + "credit": "Bruger WeasyPrint" + }, + "HTMLToPDF": { + "tags": "markup,webindhold,transformation,konvertĆ©r", + "title": "HTML Til PDF", + "header": "HTML Til PDF", + "help": "Accepterer HTML-filer og ZIP'er indeholdende html/css/billeder osv. der krƦves", + "submit": "KonvertĆ©r", + "credit": "Bruger WeasyPrint", + "zoom": "Zoom-niveau for visning af hjemmesiden.", + "pageWidth": "Bredde af siden i centimeter. (Tom for standard)", + "pageHeight": "HĆøjde af siden i centimeter. (Tom for standard)", + "marginTop": "Top margin af siden i millimeter. (Tom for standard)", + "marginBottom": "Bund margin af siden i millimeter. (Tom for standard)", + "marginLeft": "Venstre margin af siden i millimeter. (Tom for standard)", + "marginRight": "HĆøjre margin af siden i millimeter. (Tom for standard)", + "printBackground": "Render baggrunden af hjemmesider.", + "defaultHeader": "AktivĆ©r Standard Header (Navn og sidenummerAS", + "cssMediaType": "Ɔndre CSS-medietypen for siden.", + "none": "Ingen", + "print": "Skriv ud", + "screen": "SkƦrm" + }, + "MarkdownToPDF": { + "tags": "markup,webindhold,transformation,konvertĆ©r", + "title": "Markdown Til PDF", + "header": "Markdown Til PDF", + "submit": "KonvertĆ©r", + "help": "Arbejde i gang", + "credit": "Bruger WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "information,data,statistik,statistikker", + "title": "FĆ„ Info om PDF", + "header": "FĆ„ Info om PDF", + "submit": "FĆ„ Info", + "downloadJson": "Download JSON" + }, + "extractPage": { + "tags": "udtrƦk" + }, + "PdfToSinglePage": { + "tags": "enkelt side" + }, + "showJS": { + "tags": "JS", + "title": "Vis Javascript", + "header": "Vis Javascript", + "downloadJS": "Last ned Javascript", + "submit": "Vis" + }, + "autoRedact": { + "tags": "Rediger,Skjul,svƦrte,sort,markĆør,skjult", + "title": "Auto Rediger", + "header": "Auto Rediger", + "colorLabel": "Farve", + "textsToRedactLabel": "Tekst der skal redigeres (linje-adskilt)", + "textsToRedactPlaceholder": "f.eks. \\nFortroligt \\nTop-Hemmelig", + "useRegexLabel": "Brug Regex", + "wholeWordSearchLabel": "Hele Ord SĆøgning", + "customPaddingLabel": "Brugerdefineret Ekstra Polstring", + "convertPDFToImageLabel": "KonvertĆ©r PDF til PDF-Billede (Bruges til at fjerne tekst bag boksen)", + "submitButton": "Indsend" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,TabeludtrƦkning,udtrƦk,konvertĆ©r" + }, + "autoSizeSplitPDF": { + "tags": "pdf,opdel,dokument,organisation" + }, + "overlay-pdfs": { + "tags": "Overlejr", + "header": "Overlejr PDF-filer", + "baseFile": { + "label": "VƦlg Base PDF-fil" + }, + "overlayFiles": { + "label": "VƦlg Overlejrings PDF-filer" + }, + "mode": { + "label": "VƦlg Overlejringstilstand", + "sequential": "Sekventiel Overlejring", + "interleaved": "Flettet Overlejring", + "fixedRepeat": "Fast Gentaget Overlejring" + }, + "counts": { + "label": "Antal overlejringer (for Fast Gentaget tilstand)", + "placeholder": "Indtast kommaseparerede tƦllinger (f.eks. 2,3,1)" + }, + "position": { + "label": "VƦlg overlejringsposition", + "foreground": "Forgrund", + "background": "Baggrund" + }, + "submit": "Indsend" + }, + "split-by-sections": { + "tags": "Sektionsopdeling, Opdel, Tilpas", + "title": "Del PDF i Sektioner", + "header": "Del PDF ind i Sektioner", + "horizontal": { + "label": "Horisontal Deling", + "placeholder": "Indtast antal horisontale delinger" + }, + "vertical": { + "label": "Vertikal Deling", + "placeholder": "Indtast antal af vertikale delinger" + }, + "submit": "Del PDF", + "merge": "SlĆ„ sammen til Ć©n PDF" + }, + "AddStampRequest": { + "tags": "Stempel, TilfĆøj billede, centrer billede, VandmƦrke, PDF, Indlejr, Tilpas", + "header": "Stempel PDF", + "title": "Stempel PDF", + "stampType": "Stempeltype", + "stampText": "Stempeltekst", + "stampImage": "Stempelbillede", + "alphabet": "Alfabet", + "fontSize": "Skrift/BilledstĆørrelse", + "rotation": "Vendelse", + "opacity": "Gennemsigtighed", + "position": "Plassering", + "overrideX": "TilsidesƦt X-koordinat", + "overrideY": "TilsidesƦt Y-koordinat", + "customMargin": "Brugerdefineret Margin", + "customColor": "Brugerdefineret Tekstfarve", + "submit": "Indsend" + }, + "removeImagePdf": { + "tags": "Fjern Billede,Sideoperationer,Back end,server side" + }, + "splitPdfByChapters": { + "tags": "partitionering,kapitler,merker,organisering" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Replace-Invert-Color", + "header": "Erstat-omgivende Farve PDF", + "selectText": { + "1": "Erstatt eller omgivende Farvemuligheder", + "2": "Standard (hĆøj kontrastfarver)", + "3": "Brugerdefineret (anpassede farver)", + "4": "Inverter alle farver", + "5": "HĆøj kontrastfarveindstillinger", + "6": "Hvid tekst pĆ„ sort baggrund", + "7": "Sort tekst pĆ„ hvid baggrund", + "8": "Gul tekst pĆ„ sort baggrund", + "9": "GrĆøn tekst pĆ„ sort baggrund", + "10": "VƦlg tekstfarve", + "11": "VƦlg baggrundsfarve" + }, + "submit": "Erstat" + }, + "replaceColorPdf": { + "tags": "Erstat Farve,Side operationer,Behandling,server side" + }, + "login": { + "title": "Log ind", + "header": "Log ind", + "signin": "Log ind", + "rememberme": "Husk mig", + "invalid": "Ugyldigt brugernavn eller adgangskode.", + "locked": "Din konto er blevet lĆ„st.", + "signinTitle": "Log venligst ind", + "ssoSignIn": "Log ind via Single Sign-on", + "oAuth2AutoCreateDisabled": "OAUTH2 Auto-Opret Bruger Deaktiveret", + "oAuth2AdminBlockedUser": "Registrering eller login af ikke-registrerede brugere er i Ćøjeblikket blokeret. Kontakt venligst administratoren.", + "oauth2RequestNotFound": "Autorisationsanmodning ikke fundet", + "oauth2InvalidUserInfoResponse": "Ugyldigt Brugerinfo Svar", + "oauth2invalidRequest": "Ugyldig Anmodning", + "oauth2AccessDenied": "Adgang NƦgtet", + "oauth2InvalidTokenResponse": "Ugyldigt Token Svar", + "oauth2InvalidIdToken": "Ugyldigt Id Token", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "Bruger er deaktiveret, login er i Ćøjeblikket blokeret med dette brugernavn. Kontakt venligst administratoren.", + "alreadyLoggedIn": "Du er allerede logget ind pĆ„", + "alreadyLoggedIn2": "enheder. Log ud af disse enheder og prĆøv igen.", + "toManySessions": "Du har for mange aktive sessoner", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF Til Enkelt Side", + "header": "PDF Til Enkelt Side", + "submit": "KonvertĆ©r Til Enkelt Side" + }, + "pageExtracter": { + "title": "UdtrƦk Sider", + "header": "UdtrƦk Sider", + "submit": "UdtrƦk", + "placeholder": "(f.eks. 1,2,8 eller 4,7,12-16 eller 2n-1)" + }, + "sanitizePDF": { + "title": "Rens PDF", + "header": "Rens en PDF-fil", + "selectText": { + "1": "Fjern JavaScript-handlinger", + "2": "Fjern indlejrede filer", + "3": "Remove XMP metadata", + "4": "Fjern links", + "5": "Fjern skrifttyper", + "6": "Remove Document Info Metadata" + }, + "submit": "Rens PDF" + }, + "adjustContrast": { + "title": "JustĆ©r Kontrast", + "header": "JustĆ©r Kontrast", + "contrast": "Kontrast:", + "brightness": "Lysstyrke:", + "saturation": "MƦtning:", + "download": "Download" + }, + "compress": { + "title": "Komprimer", + "header": "Komprimer PDF", + "credit": "Denne tjeneste bruger qpdf til PDF Komprimering/Optimering.", + "grayscale": { + "label": "Anvend grĆ„skala til komprimering" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Optimeringsniveau:", + "4": "Auto tilstand - Justerer automatisk kvaliteten for at fĆ„ PDF'en til en prƦcis stĆørrelse", + "5": "Forventet PDF-stĆørrelse (f.eks. 25MB, 10.8MB, 25KB)" + }, + "submit": "Komprimer" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "Side Fjerner", + "header": "PDF Side fjerner", + "pagesToDelete": "Sider der skal slettes (Indtast en kommasepareret liste af sidenumre) :", + "submit": "Slet Sider", + "placeholder": "(f.eks. 1,2,6 eller 1-10,15-30)" + }, + "imageToPDF": { + "title": "Billede til PDF", + "header": "Billede til PDF", + "submit": "KonvertĆ©r", + "selectLabel": "Billedtilpasningsindstillinger", + "fillPage": "Udfyld Side", + "fitDocumentToImage": "Tilpas Side til Billede", + "maintainAspectRatio": "Bevar Aspektforhold", + "selectText": { + "2": "Auto rotĆ©r PDF", + "3": "Multi-fil logik (Kun aktiveret ved arbejde med flere billeder)", + "4": "Flet til enkelt PDF", + "5": "KonvertĆ©r til separate PDF'er" + } + }, + "PDFToCSV": { + "title": "PDF til CSV", + "header": "PDF til CSV", + "prompt": "VƦlg side til at udtrƦkke tabel", + "submit": "UdtrƦk" + }, + "split-by-size-or-count": { + "title": "Opdel PDF efter StĆørrelse eller Antal", + "header": "Opdel PDF efter StĆørrelse eller Antal", + "type": { + "label": "VƦlg Opdelingstype", + "size": "Efter StĆørrelse", + "pageCount": "Efter Sideantal", + "docCount": "Efter Dokumentantal" + }, + "value": { + "label": "Indtast VƦrdi", + "placeholder": "Indtast stĆørrelse (f.eks. 2MB eller 3KB) eller antal (f.eks. 5)" + }, + "submit": "Indsend" + }, + "printFile": { + "title": "Udskriv Fil", + "header": "Udskriv Fil til Printer", + "selectText": { + "1": "VƦlg Fil som skal Udskrives", + "2": "Indtast printernavn" + }, + "submit": "Udskriv" + }, + "licenses": { + "nav": "Licenser", + "title": "Trejdepartslicenser", + "header": "Trejdepartslicenser", + "module": "Modul", + "version": "Version", + "license": "License" + }, + "survey": { + "nav": "UndersĆøgelse", + "title": "Stirling-PDF UndersĆøgelse", + "description": "Stirling-PDF har ingen sporing, sĆ„ vi vil gerne hĆøre fra vores brugere for at forbedre Stirling-PDF!", + "changes": "Stirling-PDF Har Endtes Sidst Ganger du Foresatte En Kig! For At LƦre Mere, Se Vores Blog IndlƦg Her:", + "changes2": "Med Disse Endringer Er Vi Kommet I Betalende ForretningsstĆøtte og Finansiering", + "please": "Overvej venligst at deltage i vores undersĆøgelse!", + "disabled": "(UndersĆøgelsespop-up vil blive deaktiveret i fĆølgende opdateringer, men vil vƦre tilgƦngelig i bunden af siden)", + "button": "Tag UndersĆøgelsen", + "dontShowAgain": "Vis ikke igen", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Fjern billede", + "header": "Fjern billede", + "removeImage": "Fjern billede", + "submit": "Fjern" + }, + "splitByChapters": { + "title": "Del PDF ved Kapitler", + "header": "Splitter PDF efter kapitel", + "bookmarkLevel": "BogmƦrke niveau", + "includeMetadata": "Inkluder metadata", + "allowDuplicates": "Tillad duplikater", + "desc": { + "1": "Denne vƦrktĆøj splitter en PDF-fil op i flere PDF'er baseret pĆ„ dens kapitelstruktur.", + "2": "BogmƦrke niveau: VƦlg nivĆ„et af bogmƦrker, der skal bruges til at splittere (0 for hovedniveau, 1 for anden niveau osv.).", + "3": "Inkluder metadata: Hvis markeret, vil den originale PDF's metadata inkluderes i hver splitterdels PDF.", + "4": "Tillad duplikater: Hvis markeret, tillader det flere bogmƦrker pĆ„ samme side til at oprette separate PDF'er." + }, + "submit": "Splitter PDF" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Releases", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Current Release" + }, + "note": "Release notes are only available in English" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/de-DE/translation.json b/frontend/public/locales/de-DE/translation.json new file mode 100644 index 000000000..c5127bd14 --- /dev/null +++ b/frontend/public/locales/de-DE/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Schriftgröße", + "fontName": "Schriftart", + "title": "Seitenzahlen hinzufügen", + "header": "Seitenzahlen hinzufügen", + "selectText": { + "1": "PDF-Datei auswƤhlen:", + "2": "Margin Größe", + "3": "Position", + "4": "Startnummer", + "5": "Seiten zu nummerieren", + "6": "Benutzerdefinierter Text" + }, + "customTextDesc": "Benutzerdefinierter Text", + "numberPagesDesc": "Welche Seiten nummeriert werden sollen, Standardeinstellung 'alle' ('all'), akzeptiert auch 1-5 oder 2,5,9 usw.", + "customNumberDesc": "Standardmäßig {n}, akzeptiert auch 'Seite {n} von {total}', 'Text-{n}', '{filename}-{n}'", + "submit": "Seitenzahlen hinzufügen" + }, + "pdfPrompt": "PDF(s) auswƤhlen", + "multiPdfPrompt": "PDFs auswƤhlen(2+)", + "multiPdfDropPrompt": "WƤhlen Sie alle gewünschten PDFs aus (oder ziehen Sie sie per Drag & Drop hierhin)", + "imgPrompt": "WƤhlen Sie ein Bild", + "genericSubmit": "Absenden", + "uploadLimit": "Maximale Dateigröße:", + "uploadLimitExceededSingular": "ist zu groß. Die maximal zulƤssige Größe ist", + "uploadLimitExceededPlural": "sind zu groß. Die maximal zulƤssige Größe ist", + "processTimeWarning": "Achtung: AbhƤngig von der Dateigröße kann dieser Prozess bis zu einer Minute dauern", + "pageOrderPrompt": "Seitenreihenfolge (Geben Sie eine durch Komma getrennte Liste von Seitenzahlen ein):", + "pageSelectionPrompt": "Benutzerdefinierte Seitenauswahl (Geben Sie eine durch Kommas getrennte Liste von Seitenzahlen 1,5,6 oder Funktionen wie 2n+1 ein):", + "goToPage": "Los", + "true": "Wahr", + "false": "Falsch", + "unknown": "Unbekannt", + "save": "Speichern", + "saveToBrowser": "Im Browser speichern", + "close": "Schließen", + "filesSelected": "Dateien ausgewƤhlt", + "noFavourites": "Keine Favoriten hinzugefügt", + "downloadComplete": "Download abgeschlossen", + "bored": "Langeweile beim Warten?", + "alphabet": "Alphabet", + "downloadPdf": "PDF herunterladen", + "text": "Text", + "font": "Schriftart", + "selectFillter": "-- AuswƤhlen --", + "pageNum": "Seitenzahl", + "sizes": { + "small": "Klein", + "medium": "Mittel", + "large": "Groß", + "x-large": "Extra Groß" + }, + "error": { + "pdfPassword": "Das PDF-Dokument ist passwortgeschützt und das Passwort wurde entweder nicht angegeben oder war falsch", + "_value": "Fehler", + "sorry": "Entschuldigung für das Problem!", + "needHelp": "Brauchst du Hilfe / Ein Problem gefunden?", + "contactTip": "Wenn du weiterhin Probleme hast, zƶgere nicht, uns um Hilfe zu bitten. Du kannst ein Ticket auf unserer GitHub-Seite einreichen oder uns über Discord kontaktieren:", + "404": { + "head": "404 - Seite nicht gefunden | Ups, wir sind im Code gestolpert!", + "1": "Wir kƶnnen die gesuchte Seite nicht finden.", + "2": "Etwas ist schiefgelaufen" + }, + "github": "Ein Ticket auf GitHub einreichen", + "showStack": "Stack-Trace anzeigen", + "copyStack": "Stack-Trace kopieren", + "githubSubmit": "GitHub - Ein Ticket einreichen", + "discordSubmit": "Discord - Unterstützungsbeitrag einreichen" + }, + "delete": "Lƶschen", + "username": "Benutzername", + "password": "Passwort", + "welcome": "Willkommen", + "property": "Eigenschaft", + "black": "Schwarz", + "white": "Weiß", + "red": "Rot", + "green": "Grün", + "blue": "Blau", + "custom": "benutzerdefiniert...", + "WorkInProgess": "In Arbeit, funktioniert mƶglicherweise nicht oder ist fehlerhaft. Bitte melden Sie alle Probleme!", + "poweredBy": "Unterstützt von", + "yes": "Ja", + "no": "Nein", + "changedCredsMessage": "Anmeldedaten geƤndert!", + "notAuthenticatedMessage": "Benutzer nicht authentifiziert.", + "userNotFoundMessage": "Benutzer nicht gefunden.", + "incorrectPasswordMessage": "Das Passwort ist falsch.", + "usernameExistsMessage": "Neuer Benutzername existiert bereits.", + "invalidUsernameMessage": "Ungültiger Benutzername. Der Benutzername darf nur Buchstaben, Zahlen und die folgenden Sonderzeichen @._+- enthalten oder muss eine gültige E-Mail-Adresse sein.", + "invalidPasswordMessage": "Das Passwort darf nicht leer sein und kein Leerzeichen am Anfang und Ende haben.", + "confirmPasswordErrorMessage": "ā€žNeues Passwortā€œ und ā€žNeues Passwort bestƤtigenā€œ müssen übereinstimmen.", + "deleteCurrentUserMessage": "Der aktuell angemeldete Benutzer kann nicht gelƶscht werden.", + "deleteUsernameExistsMessage": "Der Benutzername existiert nicht und kann nicht gelƶscht werden.", + "downgradeCurrentUserMessage": "Die Rolle des aktuellen Benutzers kann nicht herabgestuft werden", + "disabledCurrentUserMessage": "Der aktuelle Benutzer kann nicht deaktiviert werden", + "downgradeCurrentUserLongMessage": "Die Rolle des aktuellen Benutzers kann nicht herabgestuft werden. Daher wird der aktuelle Benutzer nicht angezeigt.", + "userAlreadyExistsOAuthMessage": "Der Benutzer ist bereits als OAuth2-Benutzer vorhanden.", + "userAlreadyExistsWebMessage": "Der Benutzer ist bereits als Webbenutzer vorhanden.", + "oops": "Hoppla!", + "help": "Hilfe", + "goHomepage": "Zur Startseite gehen", + "joinDiscord": "Unserem Discord-Server beitreten", + "seeDockerHub": "Docker Hub ansehen", + "visitGithub": "GitHub-Repository besuchen", + "donate": "Spenden", + "color": "Farbe", + "sponsor": "Sponsor", + "info": "Informationen", + "pro": "Pro", + "page": "Seite", + "pages": "Seiten", + "loading": "Laden...", + "addToDoc": "In Dokument hinzufügen", + "reset": "Zurücksetzen", + "apply": "Anwenden", + "noFileSelected": "Keine Datei ausgewƤhlt. Bitte laden Sie eine hoch.", + "legal": { + "privacy": "Datenschutz", + "terms": "AGB", + "accessibility": "Barrierefreiheit", + "cookie": "Cookie-Richtlinie", + "impressum": "Impressum", + "showCookieBanner": "Cookie Einstellungen" + }, + "pipeline": { + "header": "Pipeline-Menü (Beta)", + "uploadButton": "Benutzerdefinierter Upload", + "configureButton": "Konfigurieren", + "defaultOption": "Benutzerdefiniert", + "submitButton": "Ausführen", + "help": "Hilfe für Pipeline", + "scanHelp": "Hilfe zum Ordnerscan", + "deletePrompt": "Mƶchten Sie die Pipeline wirklich lƶschen?", + "tags": "automatisieren,sequenzieren,skriptgesteuert,batch prozess", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Pipeline-Konfiguration", + "pipelineNameLabel": "Pipeline-Name", + "saveSettings": "Operations-Einstellungen speichern", + "pipelineNamePrompt": "Geben Sie hier den Namen der Pipeline ein", + "selectOperation": "Vorgang auswƤhlen", + "addOperationButton": "Vorgang hinzufügen", + "pipelineHeader": "Pipeline:", + "saveButton": "Herunterladen", + "validateButton": "Validieren" + }, + "enterpriseEdition": { + "button": "Auf Pro-Version umsteigen", + "warning": "Diese Funktion ist nur für Pro-Nutzer verfügbar.", + "yamlAdvert": "Stirling-PDF Pro unterstützt YAML Konfigurationsdateien, SSO und weitere Funktionen.", + "ssoAdvert": "Suchen Sie weitere Funktionen in der Benutzerverwaltung? Steigen Sie auf die Pro-Version um" + }, + "analytics": { + "title": "Mƶchten Sie Stirling-PDF verbessern?", + "paragraph1": "Stirling-PDF verfügt über Opt-in-Analytics, die uns helfen, das Produkt zu verbessern. Wir zeichnen keine persƶnlichen Informationen oder Dateiinhalte auf.", + "paragraph2": "Bitte erwƤgen Sie die Analytics zu aktivieren, um Stirling-PDF beim Wachsen zu helfen und um unsere User besser zu verstehen.", + "enable": "Analytics aktivieren", + "disable": "Analytics deaktivieren", + "settings": "Sie kƶnnen die Einstellungen für die Analytics in der config/settings.yml Datei bearbeiten" + }, + "navbar": { + "favorite": "Favoriten", + "recent": "Neu und kürzlich aktualisiert", + "darkmode": "Dunkler Modus", + "language": "Sprachen", + "settings": "Einstellungen", + "allTools": "Werkzeuge", + "multiTool": "Multitools", + "search": "Suche", + "sections": { + "organize": "Organisieren", + "convertTo": "In PDF konvertieren", + "convertFrom": "Konvertieren von PDF", + "security": "Signieren und Sicherheit", + "advance": "Erweiterte Funktionen", + "edit": "Anzeigen und Bearbeiten", + "popular": "Beliebt" + } + }, + "settings": { + "title": "Einstellungen", + "update": "Update verfügbar", + "updateAvailable": "{0} ist die aktuelle installierte Version. Eine neue Version ({1}) ist verfügbar.", + "appVersion": "App-Version:", + "downloadOption": { + "title": "Download-Option wƤhlen (für einzelne Dateien, die keine Zip-Downloads sind):", + "1": "Im selben Fenster ƶffnen", + "2": "In neuem Fenster ƶffnen", + "3": "Datei herunterladen" + }, + "zipThreshold": "Dateien komprimieren, wenn die Anzahl der heruntergeladenen Dateien überschritten wird", + "signOut": "Abmelden", + "accountSettings": "Kontoeinstellungen", + "bored": { + "help": "Aktiviert das Easter-Egg-Spiel" + }, + "cacheInputs": { + "name": "Formulareingaben speichern", + "help": "Aktivieren, um zuvor verwendete Eingaben für zukünftige DurchlƤufe zu speichern" + } + }, + "changeCreds": { + "title": "Anmeldeinformationen Ƥndern", + "header": "Aktualisieren Sie Ihre Kontodaten", + "changePassword": "Sie verwenden die Standard-Zugangsdaten. Bitte geben Sie ein neues Passwort ein.", + "newUsername": "Neuer Benutzername", + "oldPassword": "Aktuelles Passwort", + "newPassword": "Neues Passwort", + "confirmNewPassword": "Neues Passwort bestƤtigen", + "submit": "Ƅnderung speichern" + }, + "account": { + "title": "Kontoeinstellungen", + "accountSettings": "Kontoeinstellungen", + "adminSettings": "Admin Einstellungen - Benutzer anzeigen und hinzufügen", + "userControlSettings": "Benutzerkontrolle", + "changeUsername": "Benutzername Ƥndern", + "newUsername": "Neuer Benutzername", + "password": "BestƤtigungspasswort", + "oldPassword": "Altes Passwort", + "newPassword": "Neues Passwort", + "changePassword": "Passwort Ƥndern", + "confirmNewPassword": "Neues Passwort bestƤtigen", + "signOut": "Abmelden", + "yourApiKey": "Dein API-Schlüssel", + "syncTitle": "Browsereinstellungen mit Konto synchronisieren", + "settingsCompare": "Einstellungen vergleichen:", + "property": "Eigenschaft", + "webBrowserSettings": "Webbrowser-Einstellung", + "syncToBrowser": "Synchronisiere Konto -> Browser", + "syncToAccount": "Synchronisiere Konto <- Browser" + }, + "adminUserSettings": { + "title": "Benutzerkontrolle", + "header": "Administrator-Benutzerkontrolle", + "admin": "Administrator", + "user": "Benutzer", + "addUser": "Neuen Benutzer hinzufügen", + "deleteUser": "Benutzer lƶschen", + "confirmDeleteUser": "Soll der Benutzer gelƶscht werden?", + "confirmChangeUserStatus": "Soll der Benutzer deaktiviert/aktiviert werden?", + "usernameInfo": "Der Benutzername darf nur Buchstaben, Zahlen und die folgenden Sonderzeichen @._+- enthalten oder muss eine gültige E-Mail-Adresse sein.", + "roles": "Rollen", + "role": "Rolle", + "actions": "Aktions", + "apiUser": "EingeschrƤnkter API-Benutzer", + "extraApiUser": "ZusƤtzlicher eingeschrƤnkter API-Benutzer", + "webOnlyUser": "Nur Web-Benutzer", + "demoUser": "Demo-Benutzer (Keine benutzerdefinierten Einstellungen)", + "internalApiUser": "Interner API-Benutzer", + "forceChange": "Benutzer dazu zwingen, Benutzernamen/Passwort bei der Anmeldung zu Ƥndern", + "submit": "Benutzer speichern", + "changeUserRole": "Benutzerrolle Ƥndern", + "authenticated": "Authentifiziert", + "editOwnProfil": "Eigenes Profil bearbeiten", + "enabledUser": "aktivierter Benutzer", + "disabledUser": "deaktivierter Benutzer", + "activeUsers": "Aktive Benutzer:", + "disabledUsers": "Deaktivierte Benutzer:", + "totalUsers": "Gesamtzahl der Benutzer:", + "lastRequest": "Letzte Anfrage", + "usage": "Statistiken" + }, + "endpointStatistics": { + "title": "Endpunktstatistik", + "header": "Endpunktstatistik", + "top10": "Top 10", + "top20": "Top 20", + "all": "Alle", + "refresh": "Aktualisieren", + "includeHomepage": "Startseite ('/') einschließen", + "includeLoginPage": "Anmeldeseite einschließen ('/login')", + "totalEndpoints": "Gesamtendpunkte", + "totalVisits": "Gesamtbesuche", + "showing": "Zeigen", + "selectedVisits": "AusgewƤhlte Besuche", + "endpoint": "Endpunkt", + "visits": "Besuche", + "percentage": "Prozentsatz", + "loading": "Laden...", + "failedToLoad": "Endpunktdaten nicht geladen, bitte aktualisieren Sie die Seite.", + "home": "Startseite", + "login": "Anmeldeseite", + "top": "Spitze", + "numberOfVisits": "Anzahl der Besuche", + "visitsTooltip": "Besuche: {0} ({1}% des Gesamten)", + "retry": "Wiederholen" + }, + "database": { + "title": "Datenbank Import/Export", + "header": "Datenbank Import/Export", + "fileName": "Dateiname", + "creationDate": "Erstellungsdatum", + "fileSize": "Dateigröße", + "deleteBackupFile": "Sicherungsdatei lƶschen", + "importBackupFile": "Sicherungsdatei importieren", + "createBackupFile": "Sicherungsdatei erstellen", + "downloadBackupFile": "Sicherungsdatei herunterladen", + "info_1": "Beim Importieren der Daten ist es von größter Bedeutung, die korrekte Struktur zu gewƤhrleisten. Wenn Sie nicht sicher sind, was Sie tun, suchen Sie Rat und Unterstützung von einem Fachmann. Ein Fehler in der Struktur kann zu Fehlfunktionen der Anwendung führen, bis hin zur vollstƤndigen Nicht-LauffƤhigkeit der Anwendung.", + "info_2": "Der Dateiname spielt beim Hochladen keine Rolle. Dieser wird nachtrƤglich in das Format backup_user_yyyyMMddHHmm.sql geƤndert, um eine einheitliche Benennung zu gewƤhrleisten.", + "submit": "Sicherungsdatei importieren", + "importIntoDatabaseSuccessed": "Import in die Datenbank erfolgreich", + "backupCreated": "Datenbanksicherung erfolgreich", + "fileNotFound": "Datei nicht gefunden", + "fileNullOrEmpty": "Datei darf nicht null oder leer sein", + "failedImportFile": "Dateiimport fehlgeschlagen", + "notSupported": "Diese Funktion ist für deine Datenbankverbindung nicht verfügbar." + }, + "session": { + "expired": "Ihre Sitzung ist abgelaufen. Bitte laden Sie die Seite neu und versuchen Sie es erneut.", + "refreshPage": "Seite aktualisieren" + }, + "home": { + "desc": "Ihr lokal gehosteter One-Stop-Shop für alle Ihre PDF-Anforderungen.", + "searchBar": "Suche nach Funktionen...", + "viewPdf": { + "title": "PDF anzeigen/bearbeiten", + "desc": "Anzeigen, Kommentieren, Text oder Bilder hinzufügen" + }, + "setFavorites": "Favoriten festlegen", + "hideFavorites": "Favoriten ausblenden", + "showFavorites": "Favoriten anzeigen", + "legacyHomepage": "Alte Homepage", + "newHomePage": "Probieren Sie unsere neue Homepage aus!", + "alphabetical": "Alphabetisch", + "globalPopularity": "Beliebtheit", + "sortBy": "Sortieren nach:", + "multiTool": { + "title": "PDF-Multitool", + "desc": "Seiten zusammenführen, drehen, neu anordnen und entfernen" + }, + "merge": { + "title": "Zusammenführen", + "desc": "Mehrere PDF-Dateien zu einer einzigen zusammenführen" + }, + "split": { + "title": "Aufteilen", + "desc": "PDFs in mehrere Dokumente aufteilen" + }, + "rotate": { + "title": "Drehen", + "desc": "Drehen Sie Ihre PDFs ganz einfach" + }, + "imageToPdf": { + "title": "Bild zu PDF", + "desc": "Konvertieren Sie ein Bild (PNG, JPEG, GIF) in ein PDF" + }, + "pdfToImage": { + "title": "PDF zu Bild", + "desc": "Konvertieren Sie ein PDF in ein Bild (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Organisieren", + "desc": "Seiten entfernen und Seitenreihenfolge Ƥndern" + }, + "addImage": { + "title": "Bild einfügen", + "desc": "Fügt ein Bild an eine bestimmte Stelle im PDF ein (in Arbeit)" + }, + "watermark": { + "title": "Wasserzeichen hinzufügen", + "desc": "Fügen Sie ein eigenes Wasserzeichen zu Ihrem PDF hinzu" + }, + "permissions": { + "title": "Berechtigungen Ƥndern", + "desc": "Die Berechtigungen für Ihr PDF-Dokument verƤndern" + }, + "removePages": { + "title": "Entfernen", + "desc": "Ungewollte Seiten aus dem PDF entfernen" + }, + "addPassword": { + "title": "Passwort hinzufügen", + "desc": "Das PDF mit einem Passwort verschlüsseln" + }, + "removePassword": { + "title": "Passwort entfernen", + "desc": "Den Passwortschutz eines PDFs entfernen" + }, + "compressPdfs": { + "title": "Komprimieren", + "desc": "PDF komprimieren um die Dateigröße zu reduzieren" + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Metadaten Ƥndern", + "desc": "Ƅndern/Entfernen/Hinzufügen von Metadaten aus einem PDF-Dokument" + }, + "fileToPDF": { + "title": "Datei in PDF konvertieren", + "desc": "Konvertieren Sie nahezu jede Datei in PDF (DOCX, PNG, XLS, PPT, TXT und mehr)" + }, + "ocr": { + "title": "Führe OCR/Cleanup-Scans aus", + "desc": "Cleanup scannt und erkennt Text aus Bildern in einer PDF-Datei und fügt ihn erneut als Text hinzu" + }, + "extractImages": { + "title": "Bilder extrahieren", + "desc": "Extrahiert alle Bilder aus einer PDF-Datei und speichert sie als Zip-Archiv" + }, + "pdfToPDFA": { + "title": "PDF zu PDF/A konvertieren", + "desc": "PDF zu PDF/A für Langzeitarchivierung konvertieren" + }, + "PDFToWord": { + "title": "PDF zu Word", + "desc": "PDF in Word-Formate konvertieren (DOC, DOCX und ODT)" + }, + "PDFToPresentation": { + "title": "PDF zu PrƤsentation", + "desc": "PDF in PrƤsentationsformate konvertieren (PPT, PPTX und ODP)" + }, + "PDFToText": { + "title": "PDF in Text/RTF", + "desc": "PDF in Text- oder RTF-Format konvertieren" + }, + "PDFToHTML": { + "title": "PDF in HTML", + "desc": "PDF in HTML-Format konvertieren" + }, + "PDFToXML": { + "title": "PDF in XML", + "desc": "PDF in XML-Format konvertieren" + }, + "ScannerImageSplit": { + "title": "Gescannte Fotos erkennen/aufteilen", + "desc": "Teilt mehrere Fotos innerhalb eines Fotos/PDF" + }, + "sign": { + "title": "Signieren", + "desc": "Fügt PDF-Signaturen durch Zeichnung, Text oder Bild hinzu" + }, + "flatten": { + "title": "Abflachen", + "desc": "Alle interaktiven Elemente und Formulare aus einem PDF entfernen" + }, + "repair": { + "title": "Reparatur", + "desc": "Versucht, ein beschƤdigtes/kaputtes PDF zu reparieren" + }, + "removeBlanks": { + "title": "Leere Seiten entfernen", + "desc": "Erkennt und entfernt leere Seiten aus einem Dokument" + }, + "removeAnnotations": { + "title": "Anmerkungen entfernen", + "desc": "Entfernt alle Kommentare/Anmerkungen aus einem PDF" + }, + "compare": { + "title": "Vergleichen", + "desc": "Vergleicht und zeigt die Unterschiede zwischen zwei PDF-Dokumenten an" + }, + "certSign": { + "title": "Mit Zertifikat signieren", + "desc": "Ein PDF mit einem Zertifikat/Schlüssel (PEM/P12) signieren" + }, + "removeCertSign": { + "title": "Zertifikatsignatur entfernen", + "desc": "Zertifikatsignatur aus PDF entfernen" + }, + "pageLayout": { + "title": "Mehrseitiges Layout", + "desc": "Mehrere Seiten eines PDF zu einer Seite zusammenführen" + }, + "scalePages": { + "title": "Seitengröße/Skalierung anpassen", + "desc": "Größe/Skalierung der Seite und/oder des Inhalts Ƥndern" + }, + "pipeline": { + "title": "Pipeline", + "desc": "Mehrere Aktionen auf ein PDF anwenden, definiert durch ein Pipeline Skript" + }, + "add-page-numbers": { + "title": "Seitenzahlen hinzufügen", + "desc": "Hinzufügen von Seitenzahlen an einer bestimmten Stelle" + }, + "auto-rename": { + "title": "PDF automatisch umbenennen", + "desc": "PDF-Datei anhand von erkannten Kopfzeilen umbenennen" + }, + "adjust-contrast": { + "title": "Farben/Kontrast anpassen", + "desc": "Kontrast, SƤttigung und Helligkeit einer PDF anpassen" + }, + "crop": { + "title": "PDF zuschneiden", + "desc": "PDF zuschneiden um die Größe zu verƤndern (Text bleibt erhalten!)" + }, + "autoSplitPDF": { + "title": "PDF automatisch teilen", + "desc": "Physisch gescannte PDF anhand von Splitter-Seiten und QR-Codes aufteilen" + }, + "sanitizePdf": { + "title": "PDF Bereinigen", + "desc": "Entfernen von Skripten und anderen Elementen aus PDF-Dateien" + }, + "URLToPDF": { + "title": "URL/Website zu PDF", + "desc": "Konvertiert jede http(s)URL zu PDF" + }, + "HTMLToPDF": { + "title": "HTML zu PDF", + "desc": "Konvertiert jede HTML-Datei oder Zip-Archiv zu PDF" + }, + "MarkdownToPDF": { + "title": "Markdown zu PDF", + "desc": "Konvertiert jede Markdown-Datei zu PDF" + }, + "PDFToMarkdown": { + "title": "PDF zu Markdown", + "desc": "Konvertiert jedes PDF in Markdown" + }, + "getPdfInfo": { + "title": "Alle Informationen anzeigen", + "desc": "Erfasst alle mƶglichen Informationen in einer PDF" + }, + "extractPage": { + "title": "Seite(n) extrahieren", + "desc": "Extrahiert ausgewƤhlte Seiten aus einer PDF" + }, + "PdfToSinglePage": { + "title": "PDF zu einer Seite zusammenfassen", + "desc": "Fügt alle PDF-Seiten zu einer einzigen großen Seite zusammen" + }, + "showJS": { + "title": "Javascript anzeigen", + "desc": "Alle Javascript Funktionen in einer PDF anzeigen" + }, + "autoRedact": { + "title": "Automatisch zensieren/schwƤrzen", + "desc": "Automatisches Zensieren (SchwƤrzen) von Text in einer PDF-Datei basierend auf dem eingegebenen Text" + }, + "redact": { + "title": "Manuell zensieren/schwƤrzen", + "desc": "Zensiere (SchwƤrze) eine PDF-Datei durch AuswƤhlen von Text, gezeichneten Formen und/oder ausgewƤhlten Seite(n)" + }, + "tableExtraxt": { + "title": "Tabelle extrahieren", + "desc": "Tabelle aus PDF in CSV extrahieren" + }, + "autoSizeSplitPDF": { + "title": "Teilen nach Größe/Anzahl", + "desc": "Teilen Sie ein einzelnes PDF basierend auf Größe, Seitenanzahl oder Dokumentanzahl in mehrere Dokumente auf" + }, + "overlay-pdfs": { + "title": "PDF mit Overlay versehen", + "desc": "Überlagert eine PDF über eine andere PDF" + }, + "split-by-sections": { + "title": "PDF in Abschnitte teilen", + "desc": "Teilen Sie jede Seite einer PDF-Datei in kleinere horizontale und vertikale Abschnitte auf" + }, + "AddStampRequest": { + "title": "Stempel zu PDF hinzufügen", + "desc": "Fügen Sie an festgelegten Stellen Text oder Bildstempel hinzu" + }, + "removeImagePdf": { + "title": "Bild entfernen", + "desc": "Bild aus PDF entfernen, um die Dateigröße zu verringern" + }, + "splitPdfByChapters": { + "title": "PDF-Datei nach Kapiteln aufteilen", + "desc": "Aufteilung einer PDF-Datei in mehrere Dateien auf Basis der Kapitelstruktur." + }, + "validateSignature": { + "title": "PDF-Signatur überprüfen", + "desc": "Digitale Signaturen und Zertifikate in PDF-Dokumenten überprüfen" + }, + "replaceColorPdf": { + "title": "Farbe ersetzen und invertieren", + "desc": "Ersetzen Sie die Farbe des Texts und Hintergrund der PDF-Datei und invertieren Sie die komplette Farbe der PDF-Datei, um die Dateigröße zu reduzieren" + } + }, + "viewPdf": { + "tags": "anzeigen,lesen,kommentieren,text,bild", + "title": "PDF anzeigen/bearbeiten", + "header": "PDF anzeigen" + }, + "multiTool": { + "tags": "Multi Tool,Multi operation,UI,click drag,front end,client side", + "title": "PDF-Multitool", + "header": "PDF-Multitool", + "uploadPrompts": "Dateiname", + "selectAll": "Alle auswƤhlen", + "deselectAll": "Auswahl aufheben", + "selectPages": "Seiten auswƤhlen", + "selectedPages": "AusgewƤhlte Seiten", + "page": "Seite", + "deleteSelected": "Auswahl lƶschen", + "downloadAll": "Downloaden", + "downloadSelected": "Auswahl downloaden", + "insertPageBreak": "Seitenumbruch einfügen", + "addFile": "Datei hinzufügen", + "rotateLeft": "Nach links drehen", + "rotateRight": "Nach rechts drehen", + "split": "Teilen", + "moveLeft": "Nach links verschieben", + "moveRight": "Nach rechts verschieben", + "delete": "Lƶschen", + "dragDropMessage": "AusgewƤhlte Seite(n)", + "undo": "RückgƤngig machen", + "redo": "Wiederherstellen" + }, + "merge": { + "tags": "zusammenführen,seitenvorgƤnge,back end,serverseitig", + "title": "Zusammenführen", + "header": "Mehrere PDFs zusammenführen (2+)", + "sortByName": "Nach Namen sortieren", + "sortByDate": "Nach Datum sortieren", + "removeCertSign": "Digitale Signatur in der zusammengeführten Datei entfernen?", + "submit": "Zusammenführen" + }, + "split": { + "tags": "seitenoperationen,teilen,mehrseitig,ausschneiden,serverseitig", + "title": "PDF aufteilen", + "header": "PDF aufteilen", + "desc": { + "1": "Die Nummern, die Sie auswƤhlen, sind die Seitenzahlen, an denen Sie aufteilen mƶchten.", + "2": "So würde die Auswahl von 1,3,7-9 ein 10-seitiges Dokument in 6 separate PDFs aufteilen, mit:", + "3": "Dokument #1: Seite 1", + "4": "Dokument #2: Seite 2 und 3", + "5": "Dokument #3: Seite 4, 5, 6 und 7", + "6": "Dokument #4: Seite 8", + "7": "Dokument #5: Seite 9", + "8": "Dokument #6: Seite 10" + }, + "splitPages": "Geben Sie die Seiten an, an denen aufgeteilt werden soll:", + "submit": "Aufteilen" + }, + "rotate": { + "tags": "serverseitig", + "title": "PDF drehen", + "header": "PDF drehen", + "selectAngle": "WƤhlen Sie den Winkel (in Vielfachen von 90 Grad):", + "submit": "Herunterladen" + }, + "imageToPdf": { + "tags": "konvertierung,img,jpg,bild,foto" + }, + "pdfToImage": { + "tags": "konvertierung,img,jpg,bild,foto", + "title": "PDF zu Bild", + "header": "PDF zu Bild", + "selectText": "Bildformat", + "singleOrMultiple": "Bildergebnistyp", + "single": "Einzelnes großes Bild", + "multi": "Mehrere Bilder", + "colorType": "Farbtyp", + "color": "Farbe", + "grey": "Graustufen", + "blackwhite": "Schwarzweiß (Datenverlust mƶglich!)", + "submit": "Umwandeln", + "info": "Python ist nicht installiert. Erforderlich für die WebP-Konvertierung.", + "placeholder": "(z.B. 1,2,8 oder 4,7,12-16 oder 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,gerade,ungerade,sortieren,verschieben", + "title": "Seiten anordnen", + "header": "PDF Seitenorganisation", + "submit": "Seiten anordnen", + "mode": { + "_value": "Modus", + "1": "Benutzerdefinierte Seitenreihenfolge", + "2": "Umgekehrte Reihenfolge", + "3": "Duplex-Sortierung", + "4": "Heftsortierung", + "5": "Seitenheftungs-Heftsortierung", + "6": "Ungerade-Gerade-Teilung", + "7": "Erste entfernen", + "8": "Letzte entfernen", + "9": "Erste und letzte entfernen", + "10": "Ungerade-Gerade-Zusammenführung", + "11": "Alle Seiten duplizieren" + }, + "placeholder": "(z.B. 1,3,2 oder 4-8,2,10-12 oder 2n-1)" + }, + "addImage": { + "tags": "img,jpg,bild,foto", + "title": "Bild hinzufügen", + "header": "Ein Bild einfügen", + "everyPage": "In jede Seite einfügen?", + "upload": "Bild hinzufügen", + "submit": "Bild hinzufügen" + }, + "watermark": { + "tags": "text,wiederholend,beschriftung,besitzen,urheberrecht,marke,img,jpg,bild,foto", + "title": "Wasserzeichen hinzufügen", + "header": "Wasserzeichen hinzufügen", + "customColor": "Benutzerdefinierte Textfarbe", + "selectText": { + "1": "PDF auswƤhlen, dem ein Wasserzeichen hinzugefügt werden soll:", + "2": "Wasserzeichen Text:", + "3": "Schriftgröße:", + "4": "Drehung (0-360):", + "5": "breiteSpacer (horizontaler Abstand zwischen den einzelnen Wasserzeichen):", + "6": "hƶheSpacer (vertikaler Abstand zwischen den einzelnen Wasserzeichen):", + "7": "Deckkraft (0% - 100 %):", + "8": "Wasserzeichen Typ:", + "9": "Wasserzeichen-Bild:", + "10": "PDF in PDF-Bild konvertieren" + }, + "submit": "Wasserzeichen hinzufügen", + "type": { + "1": "Text", + "2": "Bild" + } + }, + "permissions": { + "tags": "lesen,schreiben,bearbeiten,drucken", + "title": "Berechtigungen Ƥndern", + "header": "Berechtigungen Ƥndern", + "warning": "Achtung: Damit diese Berechtigungen nicht geƤndert werden kƶnnen, wird empfohlen, sie über die \"Passwort hinzufügen\"-Seite mit einem Passwort zu versehen", + "selectText": { + "1": "Das zu Ƥndernde PDF auswƤhlen", + "2": "Zu setzende Berechtigungen", + "3": "Das zusammensetzen des PDFs verhindern", + "4": "Inhaltsextrahierung verhindern", + "5": "Inhaltsextrahierung zur Barrierefreiheit verhindern", + "6": "Ausfüllen des Formulars verhindern", + "7": "Modifizierung verhindern", + "8": "Ƅndern von Kommentaren verhindern", + "9": "Drucken verhindern", + "10": "Drucken verschiedener Formate verhindern" + }, + "submit": "Ƅndern" + }, + "removePages": { + "tags": "seiten entfernen,seiten lƶschen" + }, + "addPassword": { + "tags": "sicher,sicherheit", + "title": "Passwort hinzufügen", + "header": "Passwort hinzufügen (Verschlüsseln)", + "selectText": { + "1": "Das zu verschlüsselnde PDF auswƤhlen", + "2": "Passwort", + "3": "LƤnge des Schlüssels", + "4": "Größere Werte sind stƤrker, aber niedrigere Werte sind besser kompatibel.", + "5": "Zu setzende Berechtigungen", + "6": "Das zusammensetzen des PDFs verhindern", + "7": "Inhaltsextrahierung verhindern", + "8": "Inhaltsextrahierung zur Barrierefreiheit verhindern", + "9": "Ausfüllen des Formulars verhindern", + "10": "Modifizierung verhindern", + "11": "Ƅndern von Kommentaren verhindern", + "12": "Drucken verhindern", + "13": "Drucken verschiedener Formate verhindern", + "14": "Passwort des Besitzers", + "15": "SchrƤnkt ein, was mit dem Dokument gemacht werden kann, sobald es geƶffnet ist (wird nicht von allen Leseprogrammen unterstützt)", + "16": "SchrƤnkt das Ɩffnen des Dokuments selbst ein" + }, + "submit": "Verschlüsseln" + }, + "removePassword": { + "tags": "sichern,entschlüsseln,sicherheit,passwort aufheben,passwort lƶschen", + "title": "Passwort entfernen", + "header": "Passwort entfernen (Entschlüsseln)", + "selectText": { + "1": "Das zu entschlüsselnde PDF auswƤhlen", + "2": "Passwort" + }, + "submit": "Entfernen" + }, + "compressPdfs": { + "tags": "komprimieren,verkleinern,minimieren" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "titel,autor,datum,erstellung,uhrzeit,herausgeber,produzent,statistiken", + "title": "Titel:", + "header": "Metadaten Ƥndern", + "selectText": { + "1": "Bitte bearbeiten Sie die Variablen, die Sie Ƥndern mƶchten", + "2": "Alle Metadaten lƶschen", + "3": "Benutzerdefinierte Metadaten anzeigen:", + "4": "Andere Metadaten:", + "5": "Benutzerdefinierten Metadateneintrag hinzufügen" + }, + "author": "Autor:", + "creationDate": "Erstellungsdatum (JJJJ/MM/TT HH:mm:ss):", + "creator": "Ersteller:", + "keywords": "Schlüsselwƶrter:", + "modDate": "Ƅnderungsdatum (JJJJ/MM/TT HH:mm:ss):", + "producer": "Produzent:", + "subject": "Betreff:", + "trapped": "Gefangen:", + "submit": "Ƅndern" + }, + "fileToPDF": { + "tags": "transformation,format,dokument,bild,folie,text,konvertierung,büro,dokumente,word,excel,powerpoint", + "title": "Datei in PDF", + "header": "Beliebige Dateien in PDF konvertieren", + "credit": "Dieser Dienst verwendet LibreOffice und Unoconv für die Dateikonvertierung.", + "supportedFileTypesInfo": "Unterstützte Dateitypen", + "supportedFileTypes": "Unterstützte Dateitypen sollten die folgenden enthalten, eine vollstƤndige aktualisierte Liste der unterstützten Formate finden Sie jedoch in der LibreOffice-Dokumentation", + "submit": "In PDF konvertieren" + }, + "ocr": { + "tags": "erkennung,text,bild,scannen,lesen,identifizieren,erkennung,bearbeitbar", + "title": "OCR / Scan-Bereinigung", + "header": "Scans bereinigen / OCR (Optical Character Recognition)", + "selectText": { + "1": "Sprachen auswƤhlen, die im PDF erkannt werden sollen (die aufgelisteten sind die aktuell erkannten):", + "2": "Textdatei erzeugen, die OCR-Text neben dem OCR-bearbeiteten PDF enthƤlt", + "3": "Korrekte Seiten wurden in einem schiefen Winkel gescannt, indem sie wieder an ihren Platz gedreht wurden", + "4": "Seite sƤubern, daher ist es weniger wahrscheinlich, dass OCR Text im Hintergrundrauschen findet. (Keine AusgangsƤnderung)", + "5": "Seite sƤubern, sodass es weniger wahrscheinlich ist, dass OCR Text im Hintergrundrauschen findet, Bereinigung der Ausgabe wird beibehalten.", + "6": "Ignoriert Seiten mit interaktivem Text, nur OCR-Seiten, die Bilder sind", + "7": "OCR erzwingen, OCR wird jede Seite entfernen und alle ursprünglichen Textelemente entfernen", + "8": "Normal (Fehler, wenn PDF Text enthƤlt)", + "9": "ZusƤtzliche Einstellungen", + "10": "OCR-Modus", + "11": "Bilder nach OCR entfernen (Entfernt ALLE Bilder, nur sinnvoll, wenn Teil des Konvertierungsschritts)", + "12": "Rendertyp (Erweitert)" + }, + "help": "Bitte lesen Sie diese Dokumentation, um zu erfahren, wie Sie dies für andere Sprachen verwenden und/oder nicht in Docker verwenden kƶnnen", + "credit": "Dieser Dienst verwendet qpdf und Tesseract für OCR.", + "submit": "PDF mit OCR verarbeiten" + }, + "extractImages": { + "tags": "bild,foto,speichern,archivieren,zippen,erfassen,greifen", + "title": "Bilder extrahieren", + "header": "Bilder extrahieren", + "selectText": "WƤhlen Sie das Bildformat aus, in das extrahierte Bilder konvertiert werden sollen", + "allowDuplicates": "Doppelte Bilder speichern", + "submit": "Extrahieren" + }, + "pdfToPDFA": { + "tags": "archiv,langfristig,standard,konvertierung,speicherung,aufbewahrung", + "title": "PDF zu PDF/A", + "header": "PDF zu PDF/A", + "credit": "Dieser Dienst verwendet libreoffice für die PDF/A-Konvertierung", + "submit": "Konvertieren", + "tip": "Dieser Dienst kann nur einzelne Eingangsdateien verarbeiten.", + "outputFormat": "Ausgabeformat", + "pdfWithDigitalSignature": "Das PDF enthƤlt eine digitale Signatur. Sie wird im nƤchsten Schritt entfernt." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformation,format,konvertierung,office,microsoft,docfile", + "title": "PDF zu Word", + "header": "PDF zu Word", + "selectText": { + "1": "Ausgabedateiformat" + }, + "credit": "Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.", + "submit": "Konvertieren" + }, + "PDFToPresentation": { + "tags": "folien,show,büro,microsoft", + "title": "PDF zu PrƤsentation", + "header": "PDF zu PrƤsentation", + "selectText": { + "1": "Ausgabedateiformat" + }, + "credit": "Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.", + "submit": "Konvertieren" + }, + "PDFToText": { + "tags": "richformat,richtextformat,rich text format", + "title": "PDF in Text/RTF", + "header": "PDF in Text/RTF", + "selectText": { + "1": "Ausgabedateiformat" + }, + "credit": "Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.", + "submit": "Konvertieren" + }, + "PDFToHTML": { + "tags": "webinhalte,browserfreundlich", + "title": "PDF zu HTML", + "header": "PDF zu HTML", + "credit": "Dieser Dienst verwendet pdftohtml für die Dateikonvertierung.", + "submit": "Konvertieren" + }, + "PDFToXML": { + "tags": "datenextraktion,strukturierter inhalt,interop,transformation,konvertierung", + "title": "PDF zu XML", + "header": "PDF zu XML", + "credit": "Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.", + "submit": "Konvertieren" + }, + "ScannerImageSplit": { + "tags": "separat,automatische erkennung,scans,mehrere fotos,organisieren", + "selectText": { + "1": "Winkelschwelle:", + "2": "Legt den minimalen absoluten Winkel fest, der erforderlich ist, damit das Bild gedreht werden kann (Standard: 10).", + "3": "Toleranz:", + "4": "Bestimmt den Bereich der Farbvariation um die geschƤtzte Hintergrundfarbe herum (Standard: 30).", + "5": "Mindestbereich:", + "6": "Legt den minimalen Bereichsschwellenwert für ein Foto fest (Standard: 10000).", + "7": "Minimaler Konturbereich:", + "8": "Legt den minimalen Konturbereichsschwellenwert für ein Foto fest", + "9": "Randgröße:", + "10": "Legt die Größe des hinzugefügten und entfernten Randes fest, um weiße RƤnder in der Ausgabe zu verhindern (Standard: 1)." + }, + "info": "Python ist nicht installiert. Es ist zum Ausführen erforderlich." + }, + "sign": { + "tags": "autorisieren,initialen,gezeichnete signatur,textzeichen,bildsignatur", + "title": "Signieren", + "header": "PDFs signieren", + "upload": "Bild hochladen", + "draw": "Signatur zeichnen", + "text": "Texteingabe", + "clear": "Leeren", + "add": "Signieren", + "saved": "Gespeicherte Signaturen", + "save": "Signature speichern", + "personalSigs": "Persƶnliche Signaturen", + "sharedSigs": "Geteilte Signaturen", + "noSavedSigs": "Es wurden keine gespeicherten Signaturen gefunden", + "addToAll": "Zu allen Seiten hinzufügen", + "delete": "Lƶschen", + "first": "Erste Seite", + "last": "Letzte Seite", + "next": "NƤchste Seite", + "previous": "Vorherige Seite", + "maintainRatio": "SeitenverhƤltnis beibehalten ein-/ausschalten", + "undo": "RückgƤngig", + "redo": "Wiederherstellen" + }, + "flatten": { + "tags": "statisch,deaktivieren,nicht interaktiv,optimieren", + "title": "Abflachen", + "header": "PDFs reduzieren", + "flattenOnlyForms": "Nur Formulare abflachen", + "submit": "Abflachen" + }, + "repair": { + "tags": "reparieren,wiederherstellen,korrigieren,wiederherstellen", + "title": "Reparieren", + "header": "PDFs reparieren", + "submit": "Reparieren" + }, + "removeBlanks": { + "tags": "aufrƤumen,rationalisieren,nicht inhaltsreich,organisieren", + "title": "Leere Seiten entfernen", + "header": "Leere Seiten entfernen", + "threshold": "Schwellenwert:", + "thresholdDesc": "Schwellenwert zur Bestimmung, wie weiß ein weißer Pixel sein muss", + "whitePercent": "Weißprozentsatz (%):", + "whitePercentDesc": "Prozentsatz der Seite, die weiß sein muss, um entfernt zu werden", + "submit": "Leere Seiten entfernen" + }, + "removeAnnotations": { + "tags": "kommentare,hervorheben,notizen,markieren,entfernen", + "title": "Kommentare entfernen", + "header": "Kommentare entfernen", + "submit": "Entfernen" + }, + "compare": { + "tags": "differenzieren,kontrastieren,verƤndern,analysieren", + "title": "Vergleichen", + "header": "PDFs vergleichen", + "highlightColor": { + "1": "Highlight-Farbe 1:", + "2": "Highlight-Farbe 2:" + }, + "document": { + "1": "Dokument 1", + "2": "Dokument 2" + }, + "submit": "Vergleichen", + "complex": { + "message": "Eines oder beide Dokumente sind sehr groß, dadurch kann die Genauigkeit des Vergleichs kann beeintrƤchtigt werden." + }, + "large": { + "file": { + "message": "Eines oder beide Dokumente sind zu groß, um verarbeitet zu werden" + } + }, + "no": { + "text": { + "message": "Ein oder beide ausgewƤhlten PDFs enthalten keine Textinhalt. WƤhlen Sie bitte PDFs mit Text für die Vergleichsanalyse." + } + } + }, + "certSign": { + "tags": "authentifizieren,pem,p12,offiziell,verschlüsseln", + "title": "Zertifikatsignierung", + "header": "Signieren Sie ein PDF mit Ihrem Zertifikat (in Arbeit)", + "selectPDF": "WƤhlen Sie eine PDF-Datei zum Signieren aus:", + "jksNote": "Hinweis: Wenn Ihr Zertifikatstyp unten nicht aufgeführt ist, konvertieren Sie ihn bitte mit dem Befehlszeilentool keytool in eine Java Keystore-Datei (.jks). WƤhlen Sie dann unten die Option ā€ž.jks-Dateiā€œ aus.", + "selectKey": "WƤhlen Sie Ihre private Schlüsseldatei aus (PKCS#8-Format, kƶnnte .pem oder .der sein):", + "selectCert": "WƤhlen Sie Ihre Zertifikatsdatei aus (X.509-Format, kƶnnte .pem oder .der sein):", + "selectP12": "WƤhlen Sie Ihre PKCS#12-Keystore-Datei (.p12 oder .pfx) aus (optional, falls angegeben, sollte sie Ihren privaten Schlüssel und Ihr Zertifikat enthalten):", + "selectJKS": "WƤhlen Sie Ihre Java Keystore-Datei (.jks oder .keystore):", + "certType": "Zertifikattyp", + "password": "Geben Sie Ihr Keystore- oder Private-Key-Passwort ein (falls vorhanden):", + "showSig": "Signatur anzeigen", + "reason": "Grund", + "location": "Standort", + "name": "Name", + "showLogo": "Logo anzeigen", + "submit": "PDF signieren" + }, + "removeCertSign": { + "tags": "authentifizieren,PEM,P12,offiziell,entschlüsseln", + "title": "Zertifikatsignatur entfernen", + "header": "Digitales Zertifikat aus dem PDF entfernen", + "selectPDF": "PDF-Datei auswƤhlen:", + "submit": "Signatur entfernen" + }, + "pageLayout": { + "tags": "zusammenführen,zusammensetzen,einzelansicht,organisieren", + "title": "Mehrseitiges Layout", + "header": "Mehrseitiges Layout", + "pagesPerSheet": "Seiten pro Blatt:", + "addBorder": "RƤnder hinzufügen", + "submit": "Abschicken" + }, + "scalePages": { + "tags": "größe Ƥndern,Ƥndern,dimensionieren,anpassen", + "title": "Seitengröße anpassen", + "header": "Seitengröße anpassen", + "pageSize": "Format der Seiten des Dokuments", + "keepPageSize": "Originalgröße beibehalten", + "scaleFactor": "Zoomstufe (Ausschnitt) einer Seite", + "submit": "Abschicken" + }, + "add-page-numbers": { + "tags": "paginieren,beschriften,organisieren,indizieren" + }, + "auto-rename": { + "tags": "automatisch erkennen,header basiert,organisieren,neu kennzeichnen", + "title": "PDF automatisch umbenennen", + "header": "PDF automatisch umbenennen", + "submit": "Automatisch umbenennen" + }, + "adjust-contrast": { + "tags": "farbkorrektur,abstimmung,Ƥnderung,verbesserung" + }, + "crop": { + "tags": "trimmen,verkleinern,bearbeiten,formen", + "title": "Zuschneiden", + "header": "PDF zuschneiden", + "submit": "Abschicken" + }, + "autoSplitPDF": { + "tags": "qr basiert,trennen,segment scannen,organisieren", + "title": "PDF automatisch teilen", + "header": "PDF automatisch teilen", + "description": "Drucken Sie, fügen Sie ein, scannen Sie, laden Sie hoch und lassen Sie uns Ihre Dokumente automatisch trennen. Kein manuelles Sortieren erforderlich.", + "selectText": { + "1": "Drucken Sie einige TrennblƤtter aus (schwarz/weiß ist ausreichend).", + "2": "Scannen Sie alle Dokumente auf einmal, indem Sie das Trennblatt zwischen die Dokumente einlegen.", + "3": "Laden Sie die einzelne große gescannte PDF-Datei hoch und überlassen Sie Stirling-PDF den Rest.", + "4": "Trennseiten werden automatisch erkannt und entfernt, so dass ein sauberes Enddokument garantiert ist." + }, + "formPrompt": "PDF mit Stirling-PDF Seitentrennern hochladen:", + "duplexMode": "Duplex-Modus (Scannen von Vorder- und Rückseite)", + "dividerDownload2": "Download 'Auto Splitter Divider (mit Anleitung).pdf'", + "submit": "Aufteilen" + }, + "sanitizePdf": { + "tags": "sauber,sicher,sicher,bedrohungen entfernen" + }, + "URLToPDF": { + "tags": "web capture,seite speichern,web to doc,archiv", + "title": "URL zu PDF", + "header": "URL zu PDF", + "submit": "Konvertieren", + "credit": "Verwendet WeasyPrint" + }, + "HTMLToPDF": { + "tags": "markup,webinhalt,transformation,konvertierung", + "title": "HTML zu PDF", + "header": "HTML zu PDF", + "help": "Akzeptiert HTML-Dateien und ZIPs mit html/css/images etc.", + "submit": "Konvertieren", + "credit": "Verwendet WeasyPrint", + "zoom": "Zoomstufe zur Darstellung der Website", + "pageWidth": "Breite der Seite in Zentimetern (Leer auf Standard)", + "pageHeight": "Hƶhe der Seite in Zentimetern (Leer auf Standard)", + "marginTop": "Oberer Rand der Seite in Millimetern (Leer auf Standard)", + "marginBottom": "Unterer Rand der Seite in Millimetern (Leer auf Standard)", + "marginLeft": "Linker Rand der Seite in Millimetern (Leer auf Standard)", + "marginRight": "Linker Rand der Seite in Millimetern (Leer auf Standard)", + "printBackground": "Den Hintergrund der Website rendern", + "defaultHeader": "Standardkopfzeile aktivieren (Name und Seitenzahl)", + "cssMediaType": "CSS-Medientyp der Seite Ƥndern", + "none": "Keine", + "print": "Drucken", + "screen": "Bildschirm" + }, + "MarkdownToPDF": { + "tags": "markup,web-content,transformation,konvertieren", + "title": "Markdown zu PDF", + "header": "Markdown zu PDF", + "submit": "Konvertieren", + "help": "In Arbeit", + "credit": "Verwendet WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web inhalt,transformation,konvertieren,md", + "title": "PDF zu Markdown", + "header": "PDF zu Markdown", + "submit": "Konvertieren" + }, + "getPdfInfo": { + "tags": "infomation,daten,statistik", + "title": "Alle Informationen anzeigen", + "header": "Alle Informationen anzeigen", + "submit": "Informationen anzeigen", + "downloadJson": "Als JSON herunterladen" + }, + "extractPage": { + "tags": "extrahieren,seite" + }, + "PdfToSinglePage": { + "tags": "einzelseite,zusammenfassen" + }, + "showJS": { + "tags": "js,javascript", + "title": "Javascript anzeigen", + "header": "Javascript anzeigen", + "downloadJS": "Javascript herunterladen", + "submit": "Anzeigen" + }, + "autoRedact": { + "tags": "zensieren,schwƤrzen", + "title": "Automatisch zensieren/schwƤrzen", + "header": "Automatisch zensieren/schwƤrzen", + "colorLabel": "Farbe", + "textsToRedactLabel": "Zu zensierender Text (einer pro Zeile)", + "textsToRedactPlaceholder": "z.B. \\nVertraulich \\nStreng geheim", + "useRegexLabel": "Regex verwenden", + "wholeWordSearchLabel": "Ganzes Wort suchen", + "customPaddingLabel": "Zensierten Bereich vergrößern", + "convertPDFToImageLabel": "PDF in PDF-Bild konvertieren (zum Entfernen von Text hinter dem Kasten)", + "submitButton": "Zensieren" + }, + "redact": { + "tags": "zensieren,schwƤrzen,verstecken,verdunkeln,schwarz,markieren,verbergen,manuell", + "title": "Manuelles Zensieren (SchwƤrzen)", + "header": "Manuelles Zensieren (SchwƤrzen)", + "submit": "Zensieren", + "textBasedRedaction": "Textbasiertes Zensieren", + "pageBasedRedaction": "Seitenweises Zensieren", + "convertPDFToImageLabel": "Konvertiere PDF zu einem Bild (Zum Entfernen von Text hinter der Box verwenden)", + "pageRedactionNumbers": { + "title": "Seiten", + "placeholder": "(z.B. 1,2,8 oder 4,7,12-16 oder 2n-1)" + }, + "redactionColor": { + "title": "Zensurfarbe" + }, + "export": "Exportieren", + "upload": "Hochladen", + "boxRedaction": "Rechteck zeichnen zum zensieren", + "zoom": "Zoom", + "zoomIn": "Vergrößern", + "zoomOut": "Verkleinern", + "nextPage": "NƤchste Seite", + "previousPage": "Vorherige Seite", + "toggleSidebar": "Seitenleiste umschalten", + "showThumbnails": "Vorschau anzeigen", + "showDocumentOutline": "Dokumentübersicht anzeigen (Doppelklick zum Auf/Einklappen aller Elemente)", + "showAttatchments": "Zeige AnhƤnge", + "showLayers": "Ebenen anzeigen (Doppelklick, um alle Ebenen auf den Standardzustand zurückzusetzen)", + "colourPicker": "Farbauswahl", + "findCurrentOutlineItem": "Aktuell gewƤhltes Element finden", + "applyChanges": "Ƅnderungen übernehmen" + }, + "tableExtraxt": { + "tags": "CSV,tabelle,extrahieren" + }, + "autoSizeSplitPDF": { + "tags": "pdf,teilen,dokument,organisation" + }, + "overlay-pdfs": { + "tags": "overlay,überlagern", + "header": "PDF mit Overlay versehen", + "baseFile": { + "label": "Basis-PDF-Datei auswƤhlen" + }, + "overlayFiles": { + "label": "Overlay-PDF-Datei auswƤhlen" + }, + "mode": { + "label": "Overlay-Modus auswƤhlen", + "sequential": "Sequentielles Overlay", + "interleaved": "Verschachteltes Overlay", + "fixedRepeat": "Feste-Wiederholung Overlay" + }, + "counts": { + "label": "Overlay Anzahl (für Feste-Wiederholung)", + "placeholder": "Komma-separierte Anzahl eingeben (z.B.: 2,3,1)" + }, + "position": { + "label": "Overlay Position auswƤhlen", + "foreground": "Vordergrund", + "background": "Hintergrund" + }, + "submit": "Erstellen" + }, + "split-by-sections": { + "tags": "abschnitte,teilen,bearbeiten", + "title": "PDF in Abschnitte teilen", + "header": "PDF in Abschnitte teilen", + "horizontal": { + "label": "Horizontale Teiler", + "placeholder": "Anzahl horizontaler Teiler eingeben" + }, + "vertical": { + "label": "Vertikale Teiler", + "placeholder": "Anzahl vertikaler Teiler eingeben" + }, + "submit": "PDF teilen", + "merge": "In eine PDF zusammenfügen" + }, + "AddStampRequest": { + "tags": "stempeln,bild hinzufügen,bild zentrieren,wasserzeichen,pdf,einbetten,anpassen", + "header": "PDF Stempel", + "title": "PDF Stempel", + "stampType": "Stempeltyp", + "stampText": "Stempeltext", + "stampImage": "Stampelbild", + "alphabet": "Alphabet", + "fontSize": "Schriftart/Bildgröße", + "rotation": "Drehung", + "opacity": "Deckkraft", + "position": "Position", + "overrideX": "X-Koordinate überschreiben", + "overrideY": "Y-Koordinate überschreiben", + "customMargin": "Benutzerdefinierter Rand", + "customColor": "Benutzerdefinierte Textfarbe", + "submit": "Abschicken" + }, + "removeImagePdf": { + "tags": "bild entfernen,seitenoperationen,back end,server side" + }, + "splitPdfByChapters": { + "tags": "aufteilen,kapitel,lesezeichen,organisieren" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,digitale signatur,signatur validieren,überprüfen,Zertifikat,cert", + "title": "PDF-Signaturen überprüfen", + "header": "Digitale Signaturen überprüfen", + "selectPDF": "Signierte PDF-Datei auswƤhlen", + "submit": "Signaturen überprüfen", + "results": "Gültigkeitsprüfungsergebnisse", + "status": { + "_value": "Status", + "valid": "Gültig", + "invalid": "Ungültig" + }, + "signer": "Unterzeichner", + "date": "Datum", + "reason": "Grund", + "location": "Ort", + "noSignatures": "Keine digitalen Signaturen in diesem Dokument gefunden", + "chain": { + "invalid": "Zertifikatskettenprüfung fehlgeschlagen - kann die IdentitƤt des Unterzeichners nicht verifizieren" + }, + "trust": { + "invalid": "Zertifikat nicht im Truststore - Quelle kann nicht verifiziert werden" + }, + "cert": { + "expired": "Zertifikat ist abgelaufen", + "revoked": "Zertifikat wurde widerrufen", + "info": "Zertifikat Details", + "issuer": "Aussteller", + "subject": "Betreff", + "serialNumber": "Seriennummer", + "validFrom": "Gültig von", + "validUntil": "Gültig bis", + "algorithm": "Algorithmus", + "keySize": "Schlüsselgröße", + "version": "Version", + "keyUsage": "Schlüsselverwendung", + "selfSigned": "Selbstsigniert", + "bits": "bits" + }, + "signature": { + "info": "Signaturinformationen", + "_value": "Signatur", + "mathValid": "Signatur ist mathematisch gültig ABER:" + }, + "selectCustomCert": "Benutzerdefinierte Zertifikatsdatei X.509 (Optional)" + }, + "replace-color": { + "title": "Farbe Ersetzen-Invertieren", + "header": "Farb-PDF Ersetzen-Invertieren", + "selectText": { + "1": "Ersetzen oder Invertieren von Farboptionen", + "2": "Standard(Standardfarben mit hohem Kontrast)", + "3": "Benutzerdefiniert(Benutzerdefinierte Farben)", + "4": "Vollinvertierung(Invertierung aller Farben)", + "5": "Farboptionen mit hohem Kontrast", + "6": "Weißer Text auf schwarzem Hintergrund", + "7": "Schwarzer Text auf weißem Hintergrund", + "8": "Gelber Text auf schwarzem Hintergrund", + "9": "Grüner Text auf schwarzem Hintergrund", + "10": "Textfarbe auswƤhlen", + "11": "Hintergrundfarbe auswƤhlen" + }, + "submit": "Ersetzen" + }, + "replaceColorPdf": { + "tags": "Farbe ersetzen,Seiteneinstellungen,Backend,Serverseite" + }, + "login": { + "title": "Anmelden", + "header": "Anmelden", + "signin": "Anmelden", + "rememberme": "Angemeldet bleiben", + "invalid": "Benutzername oder Passwort ungültig.", + "locked": "Ihr Konto wurde gesperrt.", + "signinTitle": "Bitte melden Sie sich an.", + "ssoSignIn": "Anmeldung per Single Sign-On", + "oAuth2AutoCreateDisabled": "OAUTH2 Benutzer automatisch erstellen deaktiviert", + "oAuth2AdminBlockedUser": "Die Registrierung bzw. das anmelden von nicht registrierten Benutzern ist derzeit gesperrt. Bitte wenden Sie sich an den Administrator.", + "oauth2RequestNotFound": "Autorisierungsanfrage nicht gefunden", + "oauth2InvalidUserInfoResponse": "Ungültige Benutzerinformationsantwort", + "oauth2invalidRequest": "ungültige Anfrage", + "oauth2AccessDenied": "Zugriff abgelehnt", + "oauth2InvalidTokenResponse": "Ungültige Token-Antwort", + "oauth2InvalidIdToken": "Ungültiges ID-Token", + "relyingPartyRegistrationNotFound": "Keine Relying-Party-Registrierung gefunden", + "userIsDisabled": "Benutzer ist deaktiviert, die Anmeldung ist mit diesem Benutzernamen derzeit gesperrt. Bitte wenden Sie sich an den Administrator.", + "alreadyLoggedIn": "Sie sind bereits an", + "alreadyLoggedIn2": "GerƤten angemeldet. Bitte melden Sie sich dort ab und versuchen es dann erneut.", + "toManySessions": "Sie haben zu viele aktive Sitzungen", + "logoutMessage": "Sie wurden erfolgreich abgemeldet." + }, + "pdfToSinglePage": { + "title": "PDF zu einer Seite zusammenfassen", + "header": "PDF zu einer Seite zusammenfassen", + "submit": "Zusammenfassen" + }, + "pageExtracter": { + "title": "Seiten extrahieren", + "header": "Seiten extrahieren", + "submit": "Extrahieren", + "placeholder": "(z.B. 1,2,8 oder 4,7,12-16 oder 2n-1)" + }, + "sanitizePDF": { + "title": "PDF Bereinigen", + "header": "PDF Bereinigen", + "selectText": { + "1": "Javascript-Aktionen entfernen", + "2": "Eingebettete Dateien entfernen", + "3": "XMP-Metadaten entfernen", + "4": "Links entfernen", + "5": "Schriftarten entfernen", + "6": "Dokumenten-Metadaten entfernen" + }, + "submit": "Bereinigen" + }, + "adjustContrast": { + "title": "Kontrast anpassen", + "header": "Farben/Kontrast anpassen", + "contrast": "Kontrast:", + "brightness": "Helligkeit:", + "saturation": "SƤttigung:", + "download": "Herunterladen" + }, + "compress": { + "title": "Komprimieren", + "header": "PDF komprimieren", + "credit": "Dieser Dienst verwendet qpdf für die PDF-Komprimierung/-Optimierung.", + "grayscale": { + "label": "Graustufen für Komprimierung anwenden" + }, + "selectText": { + "1": { + "_value": "Kompressionseinstellungen", + "1": "1-3 PDF-Komprimierung,
4-6 Leichte Bildkomprimierung,
7-9 Intensive Bildkomprimierung verringert die BildqualitƤt dramatisch" + }, + "2": "Optimierungsstufe:", + "4": "Automatischer Modus – Passt die QualitƤt automatisch an, um das PDF auf die exakte Größe zu bringen", + "5": "Erwartete PDF-Größe (z.B. 25 MB, 10,8 MB, 25 KB)" + }, + "submit": "Komprimieren" + }, + "decrypt": { + "passwordPrompt": "Diese Datei ist passwortgeschützt. Bitte geben Sie das Passwort ein:", + "cancelled": "Vorgang für PDF abgebrochen: {0}", + "noPassword": "Kein Passwort für verschlüsseltes PDF angegeben: {0}", + "invalidPassword": "Bitte versuchen Sie es erneut mit dem richtigen Passwort.", + "invalidPasswordHeader": "Falsches Passwort oder nicht unterstützte Verschlüsselung für PDF: {0}", + "unexpectedError": "Bei der Verarbeitung der Datei ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.", + "serverError": "Serverfehler beim Entschlüsseln: {0}", + "success": "Datei erfolgreich entschlüsselt." + }, + "multiTool-advert": { + "message": "Diese Funktion ist auch auf unserer PDF-Multitool-Seite verfügbar. Probieren Sie sie aus, denn sie bietet eine verbesserte BenutzeroberflƤche und zusƤtzliche Funktionen!" + }, + "pageRemover": { + "title": "Seiten entfernen", + "header": "PDF Seiten entfernen", + "pagesToDelete": "Seiten zu entfernen (geben Sie eine Kommagetrennte Liste der Seitenzahlen an):", + "submit": "Seiten lƶschen", + "placeholder": "(z.B. 1,2,6 oder 1-10,15-30)" + }, + "imageToPDF": { + "title": "Bild zu PDF", + "header": "Bild zu PDF", + "submit": "Umwandeln", + "selectLabel": "Bild anpassen", + "fillPage": "Seite füllen", + "fitDocumentToImage": "Seite an Bild anpassen", + "maintainAspectRatio": "SeitenverhƤltnisse beibehalten", + "selectText": { + "2": "PDF automatisch drehen", + "3": "Mehrere Dateien verarbeiten (nur aktiv, wenn Sie mit mehreren Bildern arbeiten)", + "4": "In ein einziges PDF zusammenführen", + "5": "In separate PDFs konvertieren" + } + }, + "PDFToCSV": { + "title": "PDF zu CSV", + "header": "PDF zu CSV", + "prompt": "Seite mit der zu extrahierenden Tabelle wƤhlen", + "submit": "Extrahieren" + }, + "split-by-size-or-count": { + "title": "PDF nach Größe oder Anzahl teilen", + "header": "PDF nach Größe oder Anzahl teilen", + "type": { + "label": "Teil-Modus wƤhlen", + "size": "Nach Größe", + "pageCount": "Nach Anzahl Seiten", + "docCount": "Nach Anzahl Dokumenten" + }, + "value": { + "label": "Wert eingeben", + "placeholder": "Größe eingeben (z.B.: 2MB oder 3KB) oder Anzahl (z.B.: 5)" + }, + "submit": "Erstellen" + }, + "printFile": { + "title": "Datei drucken", + "header": "Datei an Drucker senden", + "selectText": { + "1": "WƤhle die auszudruckende Datei", + "2": "Druckernamen eingeben" + }, + "submit": "Drucken" + }, + "licenses": { + "nav": "Lizenzen", + "title": "Lizenzen von Drittanbietern", + "header": "Lizenzen von Drittanbietern", + "module": "Modul", + "version": "Version", + "license": "Lizenz" + }, + "survey": { + "nav": "Umfrage", + "title": "Stirling-PDF-Umfrage", + "description": "Stirling-PDF hat kein Tracking, daher mƶchten wir von unseren Benutzern hƶren, wie wir Stirling-PDF verbessern kƶnnen!", + "changes": "Stirling-PDF hat sich seit der letzten Umfrage verƤndert! Mehr Informationen finden Sie bitte in unserem Blog-Beitrag hier:", + "changes2": "Mit diesen Ƅnderungen erhalten wir beauftragte GeschƤftsunterstützung und Finanzierung", + "please": "Bitte nehmen Sie an unserer Umfrage teil!", + "disabled": "(Das Umfrage-Popup wird in folgenden Updates deaktiviert, ist aber am Fuß der Seite verfügbar.)", + "button": "Umfrage durchführen", + "dontShowAgain": "Nicht mehr anzeigen", + "meeting": { + "1": "Wenn Sie Stirling PDF bei der Arbeit verwenden, würden wir gerne mit Ihnen sprechen. Wir bieten technische Supportsitzungen im Austausch für eine 15-minütige Benutzereinführungssitzung an.", + "2": "Ihr Vorteil:", + "3": "Sie erhalten Hilfe bei der Bereitstellung, Integration oder Fehlerbehebung", + "4": "Sie kƶnnen direktes Feedback zu Leistung, RandfƤllen und Funktionslücken geben", + "5": "Sie helfen Stirling PDF für den Einsatz in Unternehmen zu verbessern", + "6": "Bei Interesse kƶnnen Sie direkt einen Termin bei unserem Team buchen. (Nur englischsprachig)", + "7": "Ich freue mich darauf, mich mit Ihren AnwendungsfƤllen zu befassen und Stirling PDF noch besser zu machen!", + "notInterested": "Sie sind kein Unternehmen und/oder an einem Treffen interessiert?", + "button": "Besprechung buchen" + } + }, + "removeImage": { + "title": "Bild entfernen", + "header": "Bild entfernen", + "removeImage": "Bild entfernen", + "submit": "Bild entfernen" + }, + "splitByChapters": { + "title": "PDF nach Kapiteln aufteilen", + "header": "PDF nach Kapiteln aufteilen", + "bookmarkLevel": "Lesezeichenebene", + "includeMetadata": "Metadaten einschließen", + "allowDuplicates": "Duplikate erlauben", + "desc": { + "1": "Dieses Werkzeug teilt eine PDF-Datei auf der Grundlage ihrer Kapitelstruktur in mehrere PDF-Dateien auf.", + "2": "Lesezeichenebene: WƤhlen Sie die Ebene der Lesezeichen, die für die Aufteilung verwendet werden soll (0 für die erste Ebene, 1 für die zweite Ebene usw.).", + "3": "Metadaten einschließen: Wenn diese Option aktiviert ist, werden die Metadaten der ursprünglichen PDF-Datei in jede aufgeteilte PDF-Datei übernommen.", + "4": "Duplikate erlauben: Wenn diese Option aktiviert ist, kƶnnen mehrere Lesezeichen auf derselben Seite separate PDF Dateien erstellen." + }, + "submit": "PDF teilen" + }, + "fileChooser": { + "click": "Klicken", + "or": "oder", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF-Datei", + "dragAndDropImage": "Drag & Drop Bilddatei", + "hoveredDragAndDrop": "Datei(en) hierhin Ziehen & Fallenlassen", + "extractPDF": "Extrahiere..." + }, + "releases": { + "footer": "Verƶffentlichungen", + "title": "Versionshinweise", + "header": "Versionshinweise", + "current": { + "version": "Aktuelle Version" + }, + "note": "Versionshinweise sind nur auf Englisch verfügbar" + }, + "cookieBanner": { + "popUp": { + "title": "Wie wir Cookies verwenden", + "description": { + "1": "Wir verwenden Cookies und andere Technologien, damit Stirling PDF für Sie besser funktioniert. Dies hilft uns dabei, unsere Tools zu verbessern und weiterhin Funktionen zu entwickeln, die Ihnen gefallen werden.", + "2": "Wenn Sie dies nicht mƶchten, klicken Sie auf ā€žNein, Dankeā€œ. Dadurch werden nur die unbedingt erforderlichen Cookies aktiviert, die für einen reibungslosen Ablauf erforderlich sind." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "Nein Danke", + "showPreferencesBtn": "Einstellungen verwalten" + }, + "preferencesModal": { + "title": "Einwilligungszentrum", + "acceptAllBtn": "Akzeptiere alle", + "acceptNecessaryBtn": "Alle ablehnen", + "savePreferencesBtn": "Einstellungen speichern", + "closeIconLabel": "Anzeige schließen", + "serviceCounterLabel": "Service | Dienstleistungen", + "subtitle": "Cookie-Nutzung", + "description": { + "1": "Stirling PDF verwendet Cookies und Ƥhnliche Technologien, um Ihr Erlebnis zu verbessern und den Einsatz unserer Tools zu verstehen. Dies hilft uns, die Leistung zu verbessern, die für Sie wichtigen Funktionen zu entwickeln und unseren Nutzern kontinuierlichen Support zu bieten.", + "2": "Stirling PDF kann und wird niemals den Inhalt der von Ihnen verwendeten Dokumente verfolgen oder darauf zugreifen.", + "3": "Ihre PrivatsphƤre und Ihr Vertrauen stehen bei uns im Mittelpunkt." + }, + "necessary": { + "title": { + "1": "Streng notwendige Cookies", + "2": "Immer aktiviert" + }, + "description": "Diese Cookies sind für das ordnungsgemäße Funktionieren der Website unerlƤsslich. Sie ermƶglichen grundlegende Funktionen wie das Festlegen Ihrer Datenschutzeinstellungen, das Anmelden und das Ausfüllen von Formularen. Daher kƶnnen sie nicht deaktiviert werden." + }, + "analytics": { + "title": "Analyse", + "description": "Diese Cookies helfen uns zu verstehen, wie unsere Tools genutzt werden, damit wir uns darauf konzentrieren kƶnnen, die Funktionen zu entwickeln, die unserer Community am meisten am Herzen liegen. Seien Sie beruhigt – Stirling PDF kann und wird niemals den Inhalt der Dokumente verfolgen, mit denen Sie arbeiten." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/el-GR/translation.json b/frontend/public/locales/el-GR/translation.json new file mode 100644 index 000000000..e4a7d1954 --- /dev/null +++ b/frontend/public/locales/el-GR/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "ĪœĪ­Ī³ĪµĪøĪæĻ‚ Ī³ĻĪ±Ī¼Ī¼Ī±Ļ„ĪæĻƒĪµĪ¹ĻĪ¬Ļ‚", + "fontName": "Όνομα Ī³ĻĪ±Ī¼Ī¼Ī±Ļ„ĪæĻƒĪµĪ¹ĻĪ¬Ļ‚", + "title": "Προσθήκη Ī±ĻĪ¹ĪøĪ¼ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "header": "Προσθήκη Ī±ĻĪ¹ĪøĪ¼ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "selectText": { + "1": "Επιλέξτε αρχείο PDF:", + "2": "ĪœĪ­Ī³ĪµĪøĪæĻ‚ περιθωρίου", + "3": "Θέση", + "4": "Ī‘ĻĪ¹ĪøĪ¼ĻŒĻ‚ έναρξης", + "5": "ΣελίΓες προς αρίθμηση", + "6": "Προσαρμοσμένο κείμενο" + }, + "customTextDesc": "Προσαρμοσμένο κείμενο", + "numberPagesDesc": "Ποιες ĻƒĪµĪ»ĪÆĪ“ĪµĻ‚ να Ī±ĻĪ¹ĪøĪ¼Ī·ĪøĪæĻĪ½, προεπιλογή 'all', Γέχεται ĪµĻ€ĪÆĻƒĪ·Ļ‚ 1-5 Ī® 2,5,9 κλπ", + "customNumberDesc": "Προεπιλογή σε {n}, Γέχεται ĪµĻ€ĪÆĻƒĪ·Ļ‚ 'ΣελίΓα {n} Ī±Ļ€ĻŒ {total}', 'Κείμενο-{n}', '{filename}-{n}", + "submit": "Προσθήκη Ī±ĻĪ¹ĪøĪ¼ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½" + }, + "pdfPrompt": "Επιλέξτε PDF(s)", + "multiPdfPrompt": "Επιλέξτε PDFs (2+)", + "multiPdfDropPrompt": "Επιλέξτε (Ī® ĻƒĻĻĪµĻ„Īµ & Ī±Ļ†Ī®ĻƒĻ„Īµ) όλα τα PDF που Ļ‡ĻĪµĪ¹Ī¬Ī¶ĪµĻƒĻ„Īµ", + "imgPrompt": "Επιλέξτε εικόνα(ες)", + "genericSubmit": "΄ποβολή", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Ī ĻĪæĪµĪ¹Ī“ĪæĻ€ĪæĪÆĪ·ĻƒĪ·: Αυτή Ī· ΓιαΓικασία μπορεί να Γιαρκέσει έως ένα Ī»ĪµĻ€Ļ„ĻŒ ανάλογα με το μέγεθος του αρχείου", + "pageOrderPrompt": "Προσαρμοσμένη σειρά ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ (Ī•Ī¹ĻƒĪ¬Ī³ĪµĻ„Īµ μια Ī»ĪÆĻƒĻ„Ī± Ī±ĻĪ¹ĪøĪ¼ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼Ī­Ī½Ī· με ĪŗĻŒĪ¼Ī¼Ī±Ļ„Ī± Ī® ĻƒĻ…Ī½Ī±ĻĻ„Ī®ĻƒĪµĪ¹Ļ‚ ĻŒĻ€Ļ‰Ļ‚ 2n+1):", + "pageSelectionPrompt": "Προσαρμοσμένη επιλογή ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ (Ī•Ī¹ĻƒĪ¬Ī³ĪµĻ„Īµ μια Ī»ĪÆĻƒĻ„Ī± Ī±ĻĪ¹ĪøĪ¼ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼Ī­Ī½Ī· με ĪŗĻŒĪ¼Ī¼Ī±Ļ„Ī± 1,5,6 Ī® ĻƒĻ…Ī½Ī±ĻĻ„Ī®ĻƒĪµĪ¹Ļ‚ ĻŒĻ€Ļ‰Ļ‚ 2n+1):", + "goToPage": "ĪœĪµĻ„Ī¬Ī²Ī±ĻƒĪ·", + "true": "Αληθές", + "false": "ΨευΓές", + "unknown": "Ī†Ī³Ī½Ļ‰ĻƒĻ„Īæ", + "save": "Ī‘Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ·", + "saveToBrowser": "Ī‘Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ· ĻƒĻ„ĪæĪ½ περιηγητή", + "close": "Κλείσιμο", + "filesSelected": "αρχεία επιλεγμένα", + "noFavourites": "Δεν έχουν Ļ€ĻĪæĻƒĻ„ĪµĪøĪµĪÆ αγαπημένα", + "downloadComplete": "Ī— λήψη ĪæĪ»ĪæĪŗĪ»Ī·ĻĻŽĪøĪ·ĪŗĪµ", + "bored": "Ī’Ī±ĻĪ¹Ī­ĻƒĻ„Īµ την αναμονή;", + "alphabet": "Αλφάβητο", + "downloadPdf": "Ī›Ī®ĻˆĪ· PDF", + "text": "Κείμενο", + "font": "Ī“ĻĪ±Ī¼Ī¼Ī±Ļ„ĪæĻƒĪµĪ¹ĻĪ¬", + "selectFillter": "-- Επιλέξτε --", + "pageNum": "Ī‘ĻĪ¹ĪøĪ¼ĻŒĻ‚ ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚", + "sizes": { + "small": "Μικρό", + "medium": "Μεσαίο", + "large": "Μεγάλο", + "x-large": "Ī ĪæĪ»Ļ μεγάλο" + }, + "error": { + "pdfPassword": "Το PDF έχει Ļ€ĻĪæĻƒĻ„Ī±ĻƒĪÆĪ± ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ και είτε Γεν Γόθηκε ĪŗĻ‰Ī“Ī¹ĪŗĻŒĻ‚ Ī® ήταν Ī»Ī±Ī½ĪøĪ±ĻƒĪ¼Ī­Ī½ĪæĻ‚", + "_value": "Σφάλμα", + "sorry": "Ī£Ļ…Ī³Ī³Ī½ĻŽĪ¼Ī· για το Ļ€ĻĻŒĪ²Ī»Ī·Ī¼Ī±!", + "needHelp": "Ī§ĻĪµĪ¹Ī¬Ī¶ĪµĻƒĻ„Īµ βοήθεια / Βρήκατε Ļ€ĻĻŒĪ²Ī»Ī·Ī¼Ī±;", + "contactTip": "Εάν εξακολουθείτε να αντιμετωπίζετε προβλήματα, μη Ī“Ī¹ĻƒĻ„Ī¬ĻƒĪµĻ„Īµ να ĪµĻ€Ī¹ĪŗĪæĪ¹Ī½Ļ‰Ī½Ī®ĻƒĪµĻ„Īµ μαζί μας για βοήθεια. ĪœĻ€ĪæĻĪµĪÆĻ„Īµ να υποβάλετε ένα ticket ĻƒĻ„Ī· σελίΓα μας ĻƒĻ„Īæ GitHub Ī® να ĪµĻ€Ī¹ĪŗĪæĪ¹Ī½Ļ‰Ī½Ī®ĻƒĪµĻ„Īµ μαζί μας Ī¼Ī­ĻƒĻ‰ Discord:", + "404": { + "head": "404 - Ī— σελίΓα Γεν βρέθηκε | Ωχ, ĻƒĪŗĪæĪ½Ļ„Ī¬ĻˆĪ±Ī¼Īµ ĻƒĻ„ĪæĪ½ ĪŗĻŽĪ“Ī¹ĪŗĪ±!", + "1": "Δεν Ī¼Ļ€ĪæĻĪæĻĪ¼Īµ να Ī²ĻĪæĻĪ¼Īµ τη σελίΓα που ĻˆĪ¬Ļ‡Ī½ĪµĻ„Īµ.", + "2": "ĪšĪ¬Ļ„Ī¹ πήγε ĻƒĻ„ĻĪ±Ī²Ī¬" + }, + "github": "΄ποβολή ticket ĻƒĻ„Īæ GitHub", + "showStack": "Ī•Ī¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· ίχνους ĻƒĻ„ĪæĪÆĪ²Ī±Ļ‚", + "copyStack": "Αντιγραφή ίχνους ĻƒĻ„ĪæĪÆĪ²Ī±Ļ‚", + "githubSubmit": "GitHub - ΄ποβολή ticket", + "discordSubmit": "Discord - ΄ποβολή αιτήματος Ļ…Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī·Ļ‚" + }, + "delete": "Διαγραφή", + "username": "Όνομα Ļ‡ĻĪ®ĻƒĻ„Ī·", + "password": "ĪšĻ‰Ī“Ī¹ĪŗĻŒĻ‚", + "welcome": "ĪšĪ±Ī»ĻŽĻ‚ ήρθατε", + "property": "Ī™Ī“Ī¹ĻŒĻ„Ī·Ļ„Ī±", + "black": "ĪœĪ±ĻĻĪæ", + "white": "Ī›ĪµĻ…ĪŗĻŒ", + "red": "Κόκκινο", + "green": "Πράσινο", + "blue": "ĪœĻ€Ī»Īµ", + "custom": "Προσαρμογή...", + "WorkInProgess": "Ī•ĻĪ³Ī±ĻƒĪÆĪ± σε εξέλιξη, μπορεί να μην λειτουργεί Ī® να έχει ĻƒĻ†Ī¬Ī»Ī¼Ī±Ļ„Ī±, Ļ€Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ αναφέρετε Ļ„Ļ…Ļ‡ĻŒĪ½ προβλήματα!", + "poweredBy": "Με την Ļ…Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī· του", + "yes": "ĪĪ±Ī¹", + "no": "ĪŒĻ‡Ī¹", + "changedCredsMessage": "Τα Ī“Ī¹Ī±Ļ€Ī¹ĻƒĻ„ĪµĻ…Ļ„Ī®ĻĪ¹Ī± άλλαξαν!", + "notAuthenticatedMessage": "Ο Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚ Γεν έχει Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·ĪøĪµĪÆ.", + "userNotFoundMessage": "Ο Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚ Γεν βρέθηκε.", + "incorrectPasswordMessage": "Ο τρέχων ĪŗĻ‰Ī“Ī¹ĪŗĻŒĻ‚ είναι Ī»Ī±Ī½ĪøĪ±ĻƒĪ¼Ī­Ī½ĪæĻ‚.", + "usernameExistsMessage": "Το νέο όνομα Ļ‡ĻĪ®ĻƒĻ„Ī· υπάρχει ήΓη.", + "invalidUsernameMessage": "Μη έγκυρο όνομα Ļ‡ĻĪ®ĻƒĻ„Ī·, το όνομα Ļ‡ĻĪ®ĻƒĻ„Ī· μπορεί να περιέχει μόνο γράμματα, Ī±ĻĪ¹ĪøĪ¼ĪæĻĻ‚ και τους ĪµĪ¹Ī“Ī¹ĪŗĪæĻĻ‚ χαρακτήρες @._+- Ī® πρέπει να είναι έγκυρη Ī“Ī¹ĪµĻĪøĻ…Ī½ĻƒĪ· email.", + "invalidPasswordMessage": "Ο ĪŗĻ‰Ī“Ī¹ĪŗĻŒĻ‚ Γεν μπορεί να είναι ĪŗĪµĪ½ĻŒĻ‚ και Γεν μπορεί να έχει κενά ĻƒĻ„Ī·Ī½ αρχή Ī® ĻƒĻ„Īæ τέλος.", + "confirmPasswordErrorMessage": "Ο νέος ĪŗĻ‰Ī“Ī¹ĪŗĻŒĻ‚ και Ī· ĪµĻ€Ī¹Ī²ĪµĪ²Ī±ĪÆĻ‰ĻƒĪ· νέου ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ πρέπει να ταιριάζουν.", + "deleteCurrentUserMessage": "Δεν είναι Γυνατή Ī· Γιαγραφή του τρέχοντος ĻƒĻ…Ī½Ī“ĪµĪ“ĪµĪ¼Ī­Ī½ĪæĻ… Ļ‡ĻĪ®ĻƒĻ„Ī·.", + "deleteUsernameExistsMessage": "Το όνομα Ļ‡ĻĪ®ĻƒĻ„Ī· Γεν υπάρχει και Γεν μπορεί να Γιαγραφεί.", + "downgradeCurrentUserMessage": "Δεν είναι Γυνατή Ī· Ļ…Ļ€ĪæĪ²Ī¬ĪøĪ¼Ī¹ĻƒĪ· του ĻĻŒĪ»ĪæĻ… του τρέχοντος Ļ‡ĻĪ®ĻƒĻ„Ī·", + "disabledCurrentUserMessage": "Ο τρέχων Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚ Γεν μπορεί να απενεργοποιηθεί", + "downgradeCurrentUserLongMessage": "Δεν είναι Γυνατή Ī· Ļ…Ļ€ĪæĪ²Ī¬ĪøĪ¼Ī¹ĻƒĪ· του ĻĻŒĪ»ĪæĻ… του τρέχοντος Ļ‡ĻĪ®ĻƒĻ„Ī·. Επομένως, Īæ τρέχων Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚ Γεν θα εμφανίζεται.", + "userAlreadyExistsOAuthMessage": "Ο Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚ υπάρχει ήΓη ως Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚ OAuth2.", + "userAlreadyExistsWebMessage": "Ο Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚ υπάρχει ήΓη ως Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚ web.", + "oops": "Ωχ!", + "help": "Βοήθεια", + "goHomepage": "ĪœĪµĻ„Ī¬Ī²Ī±ĻƒĪ· ĻƒĻ„Ī·Ī½ αρχική σελίΓα", + "joinDiscord": "Συμμετοχή ĻƒĻ„ĪæĪ½ Discord server μας", + "seeDockerHub": "Δείτε το Docker Hub", + "visitGithub": "Ī•Ļ€Ī¹ĻƒĪŗĪµĻ†ĪøĪµĪÆĻ„Īµ το αποθετήριο GitHub", + "donate": "Δωρεά", + "color": "Ī§ĻĻŽĪ¼Ī±", + "sponsor": "Ī§ĪæĻĪ·Ī³ĻŒĻ‚", + "info": "Πληροφορίες", + "pro": "Pro", + "page": "ΣελίΓα", + "pages": "ΣελίΓες", + "loading": "Ī¦ĻŒĻĻ„Ļ‰ĻƒĪ·...", + "addToDoc": "Προσθήκη ĻƒĻ„Īæ έγγραφο", + "reset": "Επαναφορά", + "apply": "Εφαρμογή", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Πολιτική απορρήτου", + "terms": "Όροι και Ļ€ĻĪæĻ‹Ļ€ĪæĪøĪ­ĻƒĪµĪ¹Ļ‚", + "accessibility": "Ī ĻĪæĻƒĪ²Ī±ĻƒĪ¹Ī¼ĻŒĻ„Ī·Ļ„Ī±", + "cookie": "Πολιτική cookies", + "impressum": "Ī¤Ī±Ļ…Ļ„ĻŒĻ„Ī·Ļ„Ī±", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "ĪœĪµĪ½ĪæĻ Pipeline (Beta)", + "uploadButton": "ĪœĪµĻ„Ī±Ļ†ĻŒĻĻ„Ļ‰ĻƒĪ· Ļ€ĻĪæĻƒĪ±ĻĪ¼ĪæĻƒĪ¼Ī­Ī½ĪæĻ…", + "configureButton": "Ī”Ī¹Ī±Ī¼ĻŒĻĻ†Ļ‰ĻƒĪ·", + "defaultOption": "Προσαρμογή", + "submitButton": "΄ποβολή", + "help": "Βοήθεια Pipeline", + "scanHelp": "Βοήθεια ĻƒĪ¬ĻĻ‰ĻƒĪ·Ļ‚ φακέλων", + "deletePrompt": "Ī•ĪÆĻƒĻ„Īµ βέβαιοι ĻŒĻ„Ī¹ θέλετε να Ī“Ī¹Ī±Ī³ĻĪ¬ĻˆĪµĻ„Īµ το pipeline;", + "tags": "Ī±Ļ…Ļ„ĪæĪ¼Ī±Ļ„ĪæĻ€ĪæĪÆĪ·ĻƒĪ·,ακολουθία,Ļ€ĻĪæĪ³ĻĪ±Ī¼Ī¼Ī±Ļ„Ī¹ĻƒĪ¼Ī­Ī½Īæ,ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĪÆĪ±-παρτίΓας", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Ī”Ī¹Ī±Ī¼ĻŒĻĻ†Ļ‰ĻƒĪ· Pipeline", + "pipelineNameLabel": "Όνομα Pipeline", + "saveSettings": "Ī‘Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ· ĻĻ…ĪøĪ¼ĪÆĻƒĪµĻ‰Ī½ λειτουργίας", + "pipelineNamePrompt": "Ī•Ī¹ĻƒĪ¬Ī³ĪµĻ„Īµ όνομα pipeline ĪµĪ“ĻŽ", + "selectOperation": "Επιλογή λειτουργίας", + "addOperationButton": "Προσθήκη λειτουργίας", + "pipelineHeader": "Pipeline:", + "saveButton": "Ī›Ī®ĻˆĪ·", + "validateButton": "Ī•Ļ€Ī¹ĪŗĻĻĻ‰ĻƒĪ·" + }, + "enterpriseEdition": { + "button": "Ī‘Ī½Ī±Ī²Ī¬ĪøĪ¼Ī¹ĻƒĪ· σε Pro", + "warning": "Αυτή Ī· λειτουργία είναι Γιαθέσιμη μόνο για Ļ‡ĻĪ®ĻƒĻ„ĪµĻ‚ Pro.", + "yamlAdvert": "Το Stirling PDF Pro Ļ…Ļ€ĪæĻƒĻ„Ī·ĻĪÆĪ¶ĪµĪ¹ αρχεία ĻĻ…ĪøĪ¼ĪÆĻƒĪµĻ‰Ī½ YAML και άλλες λειτουργίες SSO.", + "ssoAdvert": "Ψάχνετε για Ļ€ĪµĻĪ¹ĻƒĻƒĻŒĻ„ĪµĻĪµĻ‚ λειτουργίες Ī“Ī¹Ī±Ļ‡ĪµĪÆĻĪ¹ĻƒĪ·Ļ‚ Ļ‡ĻĪ·ĻƒĻ„ĻŽĪ½; Δείτε το Stirling PDF Pro" + }, + "analytics": { + "title": "Ī˜Ī­Ī»ĪµĻ„Īµ να κάνετε το Stirling PDF ĪŗĪ±Ī»ĻĻ„ĪµĻĪæ;", + "paragraph1": "Το Stirling PDF Γιαθέτει προαιρετικά analytics για να μας βοηθήσει να Ī²ĪµĪ»Ļ„Ī¹ĻŽĻƒĪæĻ…Ī¼Īµ το Ļ€ĻĪæĻŠĻŒĪ½. Δεν Ļ€Ī±ĻĪ±ĪŗĪæĪ»ĪæĻ…ĪøĪæĻĪ¼Īµ Ļ€ĻĪæĻƒĻ‰Ļ€Ī¹ĪŗĪ­Ļ‚ πληροφορίες Ī® Ļ€ĪµĻĪ¹ĪµĻ‡ĻŒĪ¼ĪµĪ½Īæ αρχείων.", + "paragraph2": "Ī Ī±ĻĪ±ĪŗĪ±Ī»ĪæĻĪ¼Īµ ĻƒĪŗĪµĻ†Ļ„ĪµĪÆĻ„Īµ να ĪµĪ½ĪµĻĪ³ĪæĻ€ĪæĪ¹Ī®ĻƒĪµĻ„Īµ τα analytics για να Ī²ĪæĪ·ĪøĪ®ĻƒĪµĻ„Īµ το Stirling-PDF να αναπτυχθεί και να μας ĪµĻ€Ī¹Ļ„ĻĪ­ĻˆĪµĻ„Īµ να ĪŗĪ±Ļ„Ī±Ī½ĪæĪ®ĻƒĪæĻ…Ī¼Īµ ĪŗĪ±Ī»ĻĻ„ĪµĻĪ± τους Ļ‡ĻĪ®ĻƒĻ„ĪµĻ‚ μας.", + "enable": "Ī•Ī½ĪµĻĪ³ĪæĻ€ĪæĪÆĪ·ĻƒĪ· analytics", + "disable": "Ī‘Ļ€ĪµĪ½ĪµĻĪ³ĪæĻ€ĪæĪÆĪ·ĻƒĪ· analytics", + "settings": "ĪœĻ€ĪæĻĪµĪÆĻ„Īµ να αλλάξετε τις ĻĻ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚ για τα analytics ĻƒĻ„Īæ αρχείο config/settings.yml" + }, + "navbar": { + "favorite": "Αγαπημένα", + "recent": "New and recently updated", + "darkmode": "Σκοτεινή λειτουργία", + "language": "Ī“Ī»ĻŽĻƒĻƒĪµĻ‚", + "settings": "Ī”Ļ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚", + "allTools": "Εργαλεία", + "multiTool": "Πολλαπλά εργαλεία", + "search": "Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ·", + "sections": { + "organize": "ĪŸĻĪ³Ī¬Ī½Ļ‰ĻƒĪ·", + "convertTo": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® σε PDF", + "convertFrom": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® Ī±Ļ€ĻŒ PDF", + "security": "΄πογραφή & Ī‘ĻƒĻ†Ī¬Ī»ĪµĪ¹Ī±", + "advance": "Προχωρημένα", + "edit": "Προβολή & Ī•Ļ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĪÆĪ±", + "popular": "Δημοφιλή" + } + }, + "settings": { + "title": "Ī”Ļ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚", + "update": "Ī”Ī¹Ī±ĪøĪ­ĻƒĪ¹Ī¼Ī· ĪµĪ½Ī·Ī¼Ī­ĻĻ‰ĻƒĪ·", + "updateAvailable": "{0} είναι Ī· Ļ„ĻĪ­Ļ‡ĪæĻ…ĻƒĪ± ĪµĪ³ĪŗĪ±Ļ„ĪµĻƒĻ„Ī·Ī¼Ī­Ī½Ī· έκΓοση. Μια νέα έκΓοση ({1}) είναι Γιαθέσιμη.", + "appVersion": "ΈκΓοση εφαρμογής:", + "downloadOption": { + "title": "Επιλογή Ī»Ī®ĻˆĪ·Ļ‚ (Για μεμονωμένη λήψη αρχείων χωρίς ĻƒĻ…Ī¼Ļ€ĪÆĪµĻƒĪ·):", + "1": "Άνοιγμα ĻƒĻ„Īæ ίΓιο παράθυρο", + "2": "Άνοιγμα σε νέο παράθυρο", + "3": "Ī›Ī®ĻˆĪ· αρχείου" + }, + "zipThreshold": "Ī£Ļ…Ī¼Ļ€ĪÆĪµĻƒĪ· αρχείων ĻŒĻ„Ī±Ī½ Īæ Ī±ĻĪ¹ĪøĪ¼ĻŒĻ‚ των ληφθέντων αρχείων υπερβαίνει", + "signOut": "Ī‘Ļ€ĪæĻƒĻĪ½Ī“ĪµĻƒĪ·", + "accountSettings": "Ī”Ļ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚ Ī»ĪæĪ³Ī±ĻĪ¹Ī±ĻƒĪ¼ĪæĻ", + "bored": { + "help": "Ī•Ī½ĪµĻĪ³ĪæĻ€ĪæĪÆĪ·ĻƒĪ· Ļ€Ī±Ī¹Ļ‡Ī½Ī¹Ī“Ī¹ĪæĻ easter egg" + }, + "cacheInputs": { + "name": "Ī‘Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ· ĪµĪ¹ĻƒĻŒĪ“Ļ‰Ī½ Ļ†ĻŒĻĪ¼Ī±Ļ‚", + "help": "Ī•Ī½ĪµĻĪ³ĪæĻ€ĪæĪÆĪ·ĻƒĪ· για Ī±Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ· Ļ€ĻĪæĪ·Ī³ĪæĻĪ¼ĪµĪ½Ļ‰Ī½ ĪµĪ¹ĻƒĻŒĪ“Ļ‰Ī½ για μελλοντική Ļ‡ĻĪ®ĻƒĪ·" + } + }, + "changeCreds": { + "title": "Αλλαγή Ī“Ī¹Ī±Ļ€Ī¹ĻƒĻ„ĪµĻ…Ļ„Ī·ĻĪÆĻ‰Ī½", + "header": "Ī•Ī½Ī·Ī¼Ī­ĻĻ‰ĻƒĪ· ĻƒĻ„ĪæĪ¹Ļ‡ĪµĪÆĻ‰Ī½ Ī»ĪæĪ³Ī±ĻĪ¹Ī±ĻƒĪ¼ĪæĻ", + "changePassword": "Ī§ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆĻ„Īµ προεπιλεγμένα Ī“Ī¹Ī±Ļ€Ī¹ĻƒĻ„ĪµĻ…Ļ„Ī®ĻĪ¹Ī± ĻƒĻĪ½Ī“ĪµĻƒĪ·Ļ‚. Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ ĪµĪ¹ĻƒĪ¬Ī³ĪµĻ„Īµ νέο ĪŗĻ‰Ī“Ī¹ĪŗĻŒ", + "newUsername": "ĪĪ­Īæ όνομα Ļ‡ĻĪ®ĻƒĻ„Ī·", + "oldPassword": "Τρέχων ĪŗĻ‰Ī“Ī¹ĪŗĻŒĻ‚", + "newPassword": "ĪĪ­ĪæĻ‚ ĪŗĻ‰Ī“Ī¹ĪŗĻŒĻ‚", + "confirmNewPassword": "Ī•Ļ€Ī¹Ī²ĪµĪ²Ī±ĪÆĻ‰ĻƒĪ· νέου ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ", + "submit": "΄ποβολή Ī±Ī»Ī»Ī±Ī³ĻŽĪ½" + }, + "account": { + "title": "Ī”Ļ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚ Ī»ĪæĪ³Ī±ĻĪ¹Ī±ĻƒĪ¼ĪæĻ", + "accountSettings": "Ī”Ļ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚ Ī»ĪæĪ³Ī±ĻĪ¹Ī±ĻƒĪ¼ĪæĻ", + "adminSettings": "Ī”Ļ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚ Ī“Ī¹Ī±Ļ‡ĪµĪ¹ĻĪ¹ĻƒĻ„Ī® - Προβολή και Ļ€ĻĪæĻƒĪøĪ®ĪŗĪ· Ļ‡ĻĪ·ĻƒĻ„ĻŽĪ½", + "userControlSettings": "Ī”Ļ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚ ελέγχου Ļ‡ĻĪ·ĻƒĻ„ĻŽĪ½", + "changeUsername": "Αλλαγή ĪæĪ½ĻŒĪ¼Ī±Ļ„ĪæĻ‚ Ļ‡ĻĪ®ĻƒĻ„Ī·", + "newUsername": "ĪĪ­Īæ όνομα Ļ‡ĻĪ®ĻƒĻ„Ī·", + "password": "ĪšĻ‰Ī“Ī¹ĪŗĻŒĻ‚ ĪµĻ€Ī¹Ī²ĪµĪ²Ī±ĪÆĻ‰ĻƒĪ·Ļ‚", + "oldPassword": "Ī Ī±Ī»Ī¹ĻŒĻ‚ ĪŗĻ‰Ī“Ī¹ĪŗĻŒĻ‚", + "newPassword": "ĪĪ­ĪæĻ‚ ĪŗĻ‰Ī“Ī¹ĪŗĻŒĻ‚", + "changePassword": "Αλλαγή ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ", + "confirmNewPassword": "Ī•Ļ€Ī¹Ī²ĪµĪ²Ī±ĪÆĻ‰ĻƒĪ· νέου ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ", + "signOut": "Ī‘Ļ€ĪæĻƒĻĪ½Ī“ĪµĻƒĪ·", + "yourApiKey": "Το κλειΓί API ĻƒĪ±Ļ‚", + "syncTitle": "Ī£Ļ…Ī³Ļ‡ĻĪæĪ½Ī¹ĻƒĪ¼ĻŒĻ‚ ĻĻ…ĪøĪ¼ĪÆĻƒĪµĻ‰Ī½ περιηγητή με λογαριασμό", + "settingsCompare": "Ī£ĻĪ³ĪŗĻĪ¹ĻƒĪ· ĻĻ…ĪøĪ¼ĪÆĻƒĪµĻ‰Ī½:", + "property": "Ī™Ī“Ī¹ĻŒĻ„Ī·Ļ„Ī±", + "webBrowserSettings": "Ī”ĻĪøĪ¼Ī¹ĻƒĪ· περιηγητή", + "syncToBrowser": "Ī£Ļ…Ī³Ļ‡ĻĪæĪ½Ī¹ĻƒĪ¼ĻŒĻ‚ Ī»ĪæĪ³Ī±ĻĪ¹Ī±ĻƒĪ¼ĪæĻ -> περιηγητή", + "syncToAccount": "Ī£Ļ…Ī³Ļ‡ĻĪæĪ½Ī¹ĻƒĪ¼ĻŒĻ‚ Ī»ĪæĪ³Ī±ĻĪ¹Ī±ĻƒĪ¼ĪæĻ <- περιηγητή" + }, + "adminUserSettings": { + "title": "Ī”Ļ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚ ελέγχου Ļ‡ĻĪ®ĻƒĻ„Ī·", + "header": "Ī”Ļ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚ ελέγχου Ī“Ī¹Ī±Ļ‡ĪµĪ¹ĻĪ¹ĻƒĻ„Ī® Ļ‡ĻĪ®ĻƒĻ„Ī·", + "admin": "Ī”Ī¹Ī±Ļ‡ĪµĪ¹ĻĪ¹ĻƒĻ„Ī®Ļ‚", + "user": "Ī§ĻĪ®ĻƒĻ„Ī·Ļ‚", + "addUser": "Προσθήκη νέου Ļ‡ĻĪ®ĻƒĻ„Ī·", + "deleteUser": "Διαγραφή Ļ‡ĻĪ®ĻƒĻ„Ī·", + "confirmDeleteUser": "Ī˜Ī­Ī»ĪµĻ„Īµ να Γιαγραφεί Īæ Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚;", + "confirmChangeUserStatus": "Ī˜Ī­Ī»ĪµĻ„Īµ να απενεργοποιηθεί/ενεργοποιηθεί Īæ Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚;", + "usernameInfo": "Το όνομα Ļ‡ĻĪ®ĻƒĻ„Ī· μπορεί να περιέχει μόνο γράμματα, Ī±ĻĪ¹ĪøĪ¼ĪæĻĻ‚ και τους ĪµĪ¹Ī“Ī¹ĪŗĪæĻĻ‚ χαρακτήρες @._+- Ī® πρέπει να είναι έγκυρη Ī“Ī¹ĪµĻĪøĻ…Ī½ĻƒĪ· email.", + "roles": "Δόλοι", + "role": "Ī”ĻŒĪ»ĪæĻ‚", + "actions": "Ενέργειες", + "apiUser": "Ī ĪµĻĪ¹ĪæĻĪ¹ĻƒĪ¼Ī­Ī½ĪæĻ‚ Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚ API", + "extraApiUser": "Επιπλέον Ļ€ĪµĻĪ¹ĪæĻĪ¹ĻƒĪ¼Ī­Ī½ĪæĻ‚ Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚ API", + "webOnlyUser": "Ī§ĻĪ®ĻƒĻ„Ī·Ļ‚ μόνο web", + "demoUser": "Ī”ĪæĪŗĪ¹Ī¼Ī±ĻƒĻ„Ī¹ĪŗĻŒĻ‚ Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚ (Χωρίς Ļ€ĻĪæĻƒĪ±ĻĪ¼ĪæĻƒĪ¼Ī­Ī½ĪµĻ‚ ĻĻ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚)", + "internalApiUser": "Ī•ĻƒĻ‰Ļ„ĪµĻĪ¹ĪŗĻŒĻ‚ Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚ API", + "forceChange": "΄ποχρεωτική αλλαγή ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ κατά τη ĻƒĻĪ½Ī“ĪµĻƒĪ·", + "submit": "Ī‘Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ· Ļ‡ĻĪ®ĻƒĻ„Ī·", + "changeUserRole": "Αλλαγή ĻĻŒĪ»ĪæĻ… Ļ‡ĻĪ®ĻƒĻ„Ī·", + "authenticated": "Ī Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ī¼Ī­Ī½ĪæĻ‚", + "editOwnProfil": "Ī•Ļ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĪÆĪ± Ļ€ĻĪæĻƒĻ‰Ļ€Ī¹ĪŗĪæĻ προφίλ", + "enabledUser": "ενεργοποιημένος Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚", + "disabledUser": "απενεργοποιημένος Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚", + "activeUsers": "Ενεργοί Ļ‡ĻĪ®ĻƒĻ„ĪµĻ‚:", + "disabledUsers": "Απενεργοποιημένοι Ļ‡ĻĪ®ĻƒĻ„ĪµĻ‚:", + "totalUsers": "Συνολικοί Ļ‡ĻĪ®ĻƒĻ„ĪµĻ‚:", + "lastRequest": "Τελευταίο αίτημα", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Ī•Ī¹ĻƒĪ±Ī³Ļ‰Ī³Ī®/Εξαγωγή Ī²Ī¬ĻƒĪ·Ļ‚ ΓεΓομένων", + "header": "Ī•Ī¹ĻƒĪ±Ī³Ļ‰Ī³Ī®/Εξαγωγή Ī²Ī¬ĻƒĪ·Ļ‚ ΓεΓομένων", + "fileName": "Όνομα αρχείου", + "creationDate": "Ημερομηνία Γημιουργίας", + "fileSize": "ĪœĪ­Ī³ĪµĪøĪæĻ‚ αρχείου", + "deleteBackupFile": "Διαγραφή αρχείου αντιγράφου Ī±ĻƒĻ†Ī±Ī»ĪµĪÆĪ±Ļ‚", + "importBackupFile": "Ī•Ī¹ĻƒĪ±Ī³Ļ‰Ī³Ī® αρχείου αντιγράφου Ī±ĻƒĻ†Ī±Ī»ĪµĪÆĪ±Ļ‚", + "createBackupFile": "Δημιουργία αρχείου αντιγράφου Ī±ĻƒĻ†Ī±Ī»ĪµĪÆĪ±Ļ‚", + "downloadBackupFile": "Ī›Ī®ĻˆĪ· αρχείου αντιγράφου Ī±ĻƒĻ†Ī±Ī»ĪµĪÆĪ±Ļ‚", + "info_1": "ĪšĪ±Ļ„Ī¬ την ĪµĪ¹ĻƒĪ±Ī³Ļ‰Ī³Ī® ΓεΓομένων, είναι ĻƒĪ·Ī¼Ī±Ī½Ļ„Ī¹ĪŗĻŒ να Ī“Ī¹Ī±ĻƒĻ†Ī±Ī»Ī¹ĻƒĻ„ĪµĪÆ Ī· ĻƒĻ‰ĻƒĻ„Ī® Γομή. Εάν Γεν ĪµĪÆĻƒĻ„Īµ ĻƒĪÆĪ³ĪæĻ…ĻĪæĪ¹ για το τι κάνετε, Ī¶Ī·Ļ„Ī®ĻƒĻ„Īµ ĻƒĻ…Ī¼Ī²ĪæĻ…Ī»Ī­Ļ‚ και Ļ…Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī· Ī±Ļ€ĻŒ έναν επαγγελματία. Ένα ĻƒĻ†Ī¬Ī»Ī¼Ī± ĻƒĻ„Ī· Γομή μπορεί να Ļ€ĻĪæĪŗĪ±Ī»Ī­ĻƒĪµĪ¹ Ī“Ļ…ĻƒĪ»ĪµĪ¹Ļ„ĪæĻ…ĻĪ³ĪÆĪµĻ‚ εφαρμογής, έως και πλήρη αΓυναμία ĪµĪŗĻ„Ī­Ī»ĪµĻƒĪ·Ļ‚ της εφαρμογής.", + "info_2": "Το όνομα αρχείου Γεν έχει σημασία κατά τη Ī¼ĪµĻ„Ī±Ļ†ĻŒĻĻ„Ļ‰ĻƒĪ·. Θα Ī¼ĪµĻ„ĪæĪ½ĪæĪ¼Ī±ĻƒĻ„ĪµĪÆ Ī±ĻĪ³ĻŒĻ„ĪµĻĪ± Ī±ĪŗĪæĪ»ĪæĻ…ĪøĻŽĪ½Ļ„Ī±Ļ‚ τη μορφή backup_user_yyyyMMddHHmm.sql, Ī“Ī¹Ī±ĻƒĻ†Ī±Ī»ĪÆĪ¶ĪæĪ½Ļ„Ī±Ļ‚ μια ĻƒĻ…Ī½ĪµĻ€Ī® ĻƒĻĪ¼Ī²Ī±ĻƒĪ· ĪæĪ½ĪæĪ¼Ī±ĻƒĪÆĪ±Ļ‚.", + "submit": "Ī•Ī¹ĻƒĪ±Ī³Ļ‰Ī³Ī® αντιγράφου Ī±ĻƒĻ†Ī±Ī»ĪµĪÆĪ±Ļ‚", + "importIntoDatabaseSuccessed": "Επιτυχής ĪµĪ¹ĻƒĪ±Ī³Ļ‰Ī³Ī® ĻƒĻ„Ī· βάση ΓεΓομένων", + "backupCreated": "Επιτυχής Γημιουργία αντιγράφου Ī±ĻƒĻ†Ī±Ī»ĪµĪÆĪ±Ļ‚ Ī²Ī¬ĻƒĪ·Ļ‚ ΓεΓομένων", + "fileNotFound": "Το αρχείο Γεν βρέθηκε", + "fileNullOrEmpty": "Το αρχείο Γεν πρέπει να είναι κενό", + "failedImportFile": "Αποτυχία ĪµĪ¹ĻƒĪ±Ī³Ļ‰Ī³Ī®Ļ‚ αρχείου", + "notSupported": "Αυτή Ī· λειτουργία Γεν είναι Γιαθέσιμη για τη ĻƒĻĪ½Ī“ĪµĻƒĪ· της Ī²Ī¬ĻƒĪ·Ļ‚ ΓεΓομένων ĻƒĪ±Ļ‚." + }, + "session": { + "expired": "Ī— ĻƒĻ…Ī½ĪµĪ“ĻĪÆĪ± ĻƒĪ±Ļ‚ έληξε. Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ Ī±Ī½Ī±Ī½ĪµĻŽĻƒĻ„Īµ τη σελίΓα και Ļ€ĻĪæĻƒĻ€Ī±ĪøĪ®ĻƒĻ„Īµ ξανά.", + "refreshPage": "Ī‘Ī½Ī±Ī½Ī­Ļ‰ĻƒĪ· ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚" + }, + "home": { + "desc": "Ο τοπικά Ļ†Ī¹Ī»ĪæĪ¾ĪµĪ½ĪæĻĪ¼ĪµĪ½ĪæĻ‚ Ļ€ĻĪæĪæĻĪ¹ĻƒĪ¼ĻŒĻ‚ ĻƒĪ±Ļ‚ για ĻŒĪ»ĪµĻ‚ τις ανάγκες ĻƒĪ±Ļ‚ σε PDF.", + "searchBar": "Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· Ī»ĪµĪ¹Ļ„ĪæĻ…ĻĪ³Ī¹ĻŽĪ½...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Προβολή, ĻƒĻ‡ĪæĪ»Ī¹Ī±ĻƒĪ¼ĻŒĻ‚, Ļ€ĻĪæĻƒĪøĪ®ĪŗĪ· κειμένου Ī® ĪµĪ¹ĪŗĻŒĪ½Ļ‰Ī½" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "Πολυεργαλείο PDF", + "desc": "Ī£Ļ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ·, Ī ĪµĻĪ¹ĻƒĻ„ĻĪæĻ†Ī®, ΑναΓιάταξη, Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ και Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½" + }, + "merge": { + "title": "Ī£Ļ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ·", + "desc": "Ī•ĻĪŗĪæĪ»Ī· ĻƒĻ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ· Ļ€ĪæĪ»Ī»ĻŽĪ½ PDF σε ένα." + }, + "split": { + "title": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚", + "desc": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF σε πολλαπλά έγγραφα" + }, + "rotate": { + "title": "Ī ĪµĻĪ¹ĻƒĻ„ĻĪæĻ†Ī®", + "desc": "Ī•ĻĪŗĪæĪ»Ī· Ļ€ĪµĻĪ¹ĻƒĻ„ĻĪæĻ†Ī® των PDF ĻƒĪ±Ļ‚." + }, + "imageToPdf": { + "title": "Ī•Ī¹ĪŗĻŒĪ½Ī± σε PDF", + "desc": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚ (PNG, JPEG, GIF) σε PDF." + }, + "pdfToImage": { + "title": "PDF σε εικόνα", + "desc": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® PDF σε εικόνα. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "ĪŸĻĪ³Ī¬Ī½Ļ‰ĻƒĪ·", + "desc": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ·/ΑναΓιάταξη ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ σε οποιαΓήποτε σειρά" + }, + "addImage": { + "title": "Προσθήκη ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "desc": "Προσθήκη ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚ σε ĻƒĻ…Ī³ĪŗĪµĪŗĻĪ¹Ī¼Ī­Ī½Ī· θέση ĻƒĻ„Īæ PDF" + }, + "watermark": { + "title": "Προσθήκη υΓατογραφήματος", + "desc": "Προσθήκη Ļ€ĻĪæĻƒĪ±ĻĪ¼ĪæĻƒĪ¼Ī­Ī½ĪæĻ… υΓατογραφήματος ĻƒĻ„Īæ έγγραφο PDF." + }, + "permissions": { + "title": "Αλλαγή Γικαιωμάτων", + "desc": "Αλλαγή των Γικαιωμάτων του εγγράφου PDF" + }, + "removePages": { + "title": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ·", + "desc": "Διαγραφή Ī±Ī½ĪµĻ€Ī¹ĪøĻĪ¼Ī·Ļ„Ļ‰Ī½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ Ī±Ļ€ĻŒ το έγγραφο PDF." + }, + "addPassword": { + "title": "Προσθήκη ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ", + "desc": "ĪšĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ¬Ļ†Ī·ĻƒĪ· του εγγράφου PDF με ĪŗĻ‰Ī“Ī¹ĪŗĻŒ." + }, + "removePassword": { + "title": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ", + "desc": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· Ļ€ĻĪæĻƒĻ„Ī±ĻƒĪÆĪ±Ļ‚ ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ Ī±Ļ€ĻŒ το έγγραφο PDF." + }, + "compressPdfs": { + "title": "Ī£Ļ…Ī¼Ļ€ĪÆĪµĻƒĪ·", + "desc": "Ī£Ļ…Ī¼Ļ€ĪÆĪµĻƒĪ· PDF για Ī¼ĪµĪÆĻ‰ĻƒĪ· του μεγέθους αρχείου." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Αλλαγή μεταΓεΓομένων", + "desc": "Αλλαγή/Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ·/Προσθήκη μεταΓεΓομένων Ī±Ļ€ĻŒ ένα έγγραφο PDF" + }, + "fileToPDF": { + "title": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® αρχείου σε PDF", + "desc": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® ĻƒĻ‡ĪµĪ“ĻŒĪ½ οποιουΓήποτε αρχείου σε PDF (DOCX, PNG, XLS, PPT, TXT και άλλα)" + }, + "ocr": { + "title": "OCR / ĪšĪ±ĪøĪ±ĻĪ¹ĻƒĪ¼ĻŒĻ‚ ĻƒĪ±ĻĻŽĻƒĪµĻ‰Ī½", + "desc": "ĪšĪ±ĪøĪ±ĻĪ¹ĻƒĪ¼ĻŒĻ‚ ĻƒĪ±ĻĻŽĻƒĪµĻ‰Ī½ και Ī±Ī½ĪÆĻ‡Ī½ĪµĻ…ĻƒĪ· κειμένου Ī±Ļ€ĻŒ ĪµĪ¹ĪŗĻŒĪ½ĪµĻ‚ μέσα σε PDF και ĪµĻ€Ī±Ī½Ī±Ļ€ĻĪæĻƒĪøĪ®ĪŗĪ· ως κείμενο." + }, + "extractImages": { + "title": "Εξαγωγή ĪµĪ¹ĪŗĻŒĪ½Ļ‰Ī½", + "desc": "Εξαγωγή ĻŒĪ»Ļ‰Ī½ των ĪµĪ¹ĪŗĻŒĪ½Ļ‰Ī½ Ī±Ļ€ĻŒ PDF και Ī±Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ· σε zip" + }, + "pdfToPDFA": { + "title": "PDF σε PDF/A", + "desc": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® PDF σε PDF/A για Ī¼Ī±ĪŗĻĪæĻ‡ĻĻŒĪ½Ī¹Ī± Ī±Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ·" + }, + "PDFToWord": { + "title": "PDF σε Word", + "desc": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® PDF σε μορφές Word (DOC, DOCX και ODT)" + }, + "PDFToPresentation": { + "title": "PDF σε Ī Ī±ĻĪæĻ…ĻƒĪÆĪ±ĻƒĪ·", + "desc": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® PDF σε μορφές Ļ€Ī±ĻĪæĻ…ĻƒĪÆĪ±ĻƒĪ·Ļ‚ (PPT, PPTX και ODP)" + }, + "PDFToText": { + "title": "PDF σε RTF (Κείμενο)", + "desc": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® PDF σε μορφή κειμένου Ī® RTF" + }, + "PDFToHTML": { + "title": "PDF σε HTML", + "desc": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® PDF σε μορφή HTML" + }, + "PDFToXML": { + "title": "PDF σε XML", + "desc": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® PDF σε μορφή XML" + }, + "ScannerImageSplit": { + "title": "Ī‘Ī½ĪÆĻ‡Ī½ĪµĻ…ĻƒĪ·/Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ ĻƒĪ±ĻĻ‰Ī¼Ī­Ī½Ļ‰Ī½ Ļ†Ļ‰Ļ„ĪæĪ³ĻĪ±Ļ†Ī¹ĻŽĪ½", + "desc": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ Ļ€ĪæĪ»Ī»Ī±Ļ€Ī»ĻŽĪ½ Ļ†Ļ‰Ļ„ĪæĪ³ĻĪ±Ļ†Ī¹ĻŽĪ½ Ī±Ļ€ĻŒ μια φωτογραφία/PDF" + }, + "sign": { + "title": "΄πογραφή", + "desc": "Προσθήκη υπογραφής σε PDF με ĻƒĻ‡ĪµĪ“ĪÆĪ±ĻƒĪ·, κείμενο Ī® εικόνα" + }, + "flatten": { + "title": "Ī™ĻƒĪæĻ€Ī­Ī“Ļ‰ĻƒĪ·", + "desc": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĻŒĪ»Ļ‰Ī½ των Ī“Ī¹Ī±Ī“ĻĪ±ĻƒĻ„Ī¹ĪŗĻŽĪ½ ĻƒĻ„ĪæĪ¹Ļ‡ĪµĪÆĻ‰Ī½ και Ļ†ĪæĻĪ¼ĻŽĪ½ Ī±Ļ€ĻŒ ένα PDF" + }, + "repair": { + "title": "Ī•Ļ€Ī¹Ī“Ī¹ĻŒĻĪøĻ‰ĻƒĪ·", + "desc": "Ī ĻĪæĻƒĻ€Ī¬ĪøĪµĪ¹Ī± ĪµĻ€Ī¹Ī“Ī¹ĻŒĻĪøĻ‰ĻƒĪ·Ļ‚ ĪŗĪ±Ļ„ĪµĻƒĻ„ĻĪ±Ī¼Ī¼Ī­Ī½ĪæĻ…/Ļ‡Ī±Ī»Ī±ĻƒĪ¼Ī­Ī½ĪæĻ… PDF" + }, + "removeBlanks": { + "title": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪŗĪµĪ½ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "desc": "Ī‘Ī½ĪÆĻ‡Ī½ĪµĻ…ĻƒĪ· και Ī±Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪŗĪµĪ½ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ Ī±Ļ€ĻŒ ένα έγγραφο" + }, + "removeAnnotations": { + "title": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĻƒĻ‡ĪæĪ»ĪÆĻ‰Ī½", + "desc": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĻŒĪ»Ļ‰Ī½ των ĻƒĻ‡ĪæĪ»ĪÆĻ‰Ī½/ĪµĻ€Ī¹ĻƒĪ·Ī¼Ī¬Ī½ĻƒĪµĻ‰Ī½ Ī±Ļ€ĻŒ ένα PDF" + }, + "compare": { + "title": "Ī£ĻĪ³ĪŗĻĪ¹ĻƒĪ·", + "desc": "Ī£ĻĪ³ĪŗĻĪ¹ĻƒĪ· και ĪµĪ¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· Ī“Ī¹Ī±Ļ†ĪæĻĻŽĪ½ Ī¼ĪµĻ„Ī±Ī¾Ļ 2 εγγράφων PDF" + }, + "certSign": { + "title": "΄πογραφή με Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĻŒ", + "desc": "΄πογραφή PDF με Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĻŒ/κλειΓί (PEM/P12)" + }, + "removeCertSign": { + "title": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· υπογραφής Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĪæĻ", + "desc": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· υπογραφής Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĪæĻ Ī±Ļ€ĻŒ PDF" + }, + "pageLayout": { + "title": "Διάταξη Ļ€ĪæĪ»Ī»Ī±Ļ€Ī»ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "desc": "Ī£Ļ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ· Ļ€ĪæĪ»Ī»Ī±Ļ€Ī»ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ ĪµĪ½ĻŒĻ‚ εγγράφου PDF σε μία σελίΓα" + }, + "scalePages": { + "title": "Προσαρμογή μεγέθους/κλίμακας ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚", + "desc": "Αλλαγή του μεγέθους/κλίμακας μιας ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ και/Ī® του περιεχομένου της." + }, + "pipeline": { + "title": "Pipeline", + "desc": "Ī•ĪŗĻ„Ī­Ī»ĪµĻƒĪ· Ļ€ĪæĪ»Ī»Ī±Ļ€Ī»ĻŽĪ½ ĪµĪ½ĪµĻĪ³ĪµĪ¹ĻŽĪ½ σε PDF ορίζοντας scripts pipeline" + }, + "add-page-numbers": { + "title": "Προσθήκη Ī±ĻĪ¹ĪøĪ¼ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "desc": "Προσθήκη Ī±ĻĪ¹ĪøĪ¼ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ σε όλο το έγγραφο σε ĻƒĻ…Ī³ĪŗĪµĪŗĻĪ¹Ī¼Ī­Ī½Ī· θέση" + }, + "auto-rename": { + "title": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· Ī¼ĪµĻ„ĪæĪ½ĪæĪ¼Ī±ĻƒĪÆĪ± αρχείου PDF", + "desc": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· Ī¼ĪµĻ„ĪæĪ½ĪæĪ¼Ī±ĻƒĪÆĪ± ĪµĪ½ĻŒĻ‚ PDF με βάση την ανιχνευμένη κεφαλίΓα" + }, + "adjust-contrast": { + "title": "Προσαρμογή χρωμάτων/Ī±Ī½Ļ„ĪÆĪøĪµĻƒĪ·Ļ‚", + "desc": "Προσαρμογή Ī±Ī½Ļ„ĪÆĪøĪµĻƒĪ·Ļ‚, ĪŗĪæĻĪµĻƒĪ¼ĪæĻ και Ļ†Ļ‰Ļ„ĪµĪ¹Ī½ĻŒĻ„Ī·Ļ„Ī±Ļ‚ ĪµĪ½ĻŒĻ‚ PDF" + }, + "crop": { + "title": "Περικοπή PDF", + "desc": "Περικοπή PDF για Ī¼ĪµĪÆĻ‰ĻƒĪ· του μεγέθους του (Γιατηρεί το κείμενο!)" + }, + "autoSplitPDF": { + "title": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„ĪæĻ‚ Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "desc": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„ĪæĻ‚ Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ ĻƒĪ±ĻĻ‰Ī¼Ī­Ī½ĪæĻ… PDF με Ļ†Ļ…ĻƒĪ¹ĪŗĻŒ ĻƒĪ±ĻĻ‰Ī¼Ī­Ī½Īæ Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĻ„Ī® ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ QR Code" + }, + "sanitizePdf": { + "title": "Ī•Ī¾Ļ…Ī³ĪÆĪ±Ī½ĻƒĪ·", + "desc": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· scripts και άλλων ĻƒĻ„ĪæĪ¹Ļ‡ĪµĪÆĻ‰Ī½ Ī±Ļ€ĻŒ αρχεία PDF" + }, + "URLToPDF": { + "title": "URL/Ī™ĻƒĻ„ĪæĻƒĪµĪ»ĪÆĪ“Ī± σε PDF", + "desc": "ĪœĪµĻ„Ī±Ļ„ĻĪ­Ļ€ĪµĪ¹ οποιοΓήποτε http(s)URL σε PDF" + }, + "HTMLToPDF": { + "title": "HTML σε PDF", + "desc": "ĪœĪµĻ„Ī±Ļ„ĻĪ­Ļ€ĪµĪ¹ οποιοΓήποτε αρχείο HTML Ī® zip σε PDF" + }, + "MarkdownToPDF": { + "title": "Markdown σε PDF", + "desc": "ĪœĪµĻ„Ī±Ļ„ĻĪ­Ļ€ĪµĪ¹ οποιοΓήποτε αρχείο Markdown σε PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "Ī›Ī®ĻˆĪ· ĪŸĪ›Ī©Ī των Ļ€Ī»Ī·ĻĪæĻ†ĪæĻĪ¹ĻŽĪ½ του PDF", + "desc": "Ī›Ī®ĻˆĪ· ĻŒĪ»Ļ‰Ī½ των Ī“Ļ…Ī½Ī±Ļ„ĻŽĪ½ Ļ€Ī»Ī·ĻĪæĻ†ĪæĻĪ¹ĻŽĪ½ για τα PDF" + }, + "extractPage": { + "title": "Εξαγωγή ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚(ων)", + "desc": "Εξαγωγή επιλεγμένων ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ Ī±Ļ€ĻŒ PDF" + }, + "PdfToSinglePage": { + "title": "Ενιαία μεγάλη σελίΓα", + "desc": "Ī£Ļ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ· ĻŒĪ»Ļ‰Ī½ των ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ PDF σε μία μεγάλη σελίΓα" + }, + "showJS": { + "title": "Ī•Ī¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· Javascript", + "desc": "Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· και ĪµĪ¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· οποιουΓήποτε JS ĪµĪ½ĻƒĻ‰Ī¼Ī±Ļ„Ļ‰Ī¼Ī­Ī½ĪæĻ… σε PDF" + }, + "autoRedact": { + "title": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· Ī±Ļ€ĻŒĪŗĻĻ…ĻˆĪ·", + "desc": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· Ī±Ļ€ĻŒĪŗĻĻ…ĻˆĪ· (Ī¼Ī±ĻĻĪ¹ĻƒĪ¼Ī±) κειμένου σε PDF βάσει ĪµĪ¹ĻƒĪ±Ī³ĻŒĪ¼ĪµĪ½ĪæĻ… κειμένου" + }, + "redact": { + "title": "Χειροκίνητη Ī±Ļ€ĻŒĪŗĻĻ…ĻˆĪ·", + "desc": "Ī‘Ļ€ĻŒĪŗĻĻ…ĻˆĪ· σε PDF βάσει επιλεγμένου κειμένου, ĻƒĻ‡ĪµĪ“Ī¹Ī±ĻƒĪ¼Ī­Ī½Ļ‰Ī½ ĻƒĻ‡Ī·Ī¼Ī¬Ļ„Ļ‰Ī½ και/Ī® επιλεγμένων ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½" + }, + "tableExtraxt": { + "title": "PDF σε CSV", + "desc": "Εξαγωγή πινάκων Ī±Ļ€ĻŒ PDF και μετατροπή σε CSV" + }, + "autoSizeSplitPDF": { + "title": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„ĪæĻ‚ Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ ανά μέγεθος/πλήθος", + "desc": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ ĪµĪ½ĻŒĻ‚ PDF σε πολλαπλά έγγραφα βάσει μεγέθους, Ī±ĻĪ¹ĪøĪ¼ĪæĻ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ Ī® Ī±ĻĪ¹ĪøĪ¼ĪæĻ εγγράφων" + }, + "overlay-pdfs": { + "title": "Ī•Ļ€Ī¹ĪŗĪ¬Ī»Ļ…ĻˆĪ· PDF", + "desc": "Ī•Ļ€Ī¹ĪŗĪ¬Ī»Ļ…ĻˆĪ· PDF πάνω σε άλλο PDF" + }, + "split-by-sections": { + "title": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF ανά ĪµĪ½ĻŒĻ„Ī·Ļ„ĪµĻ‚", + "desc": "Ī”Ī¹Ī±ĪÆĻĪµĻƒĪ· κάθε ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ ĪµĪ½ĻŒĻ‚ PDF σε Ī¼Ī¹ĪŗĻĻŒĻ„ĪµĻĪµĻ‚ ĪæĻĪ¹Ī¶ĻŒĪ½Ļ„Ī¹ĪµĻ‚ και κάθετες ĪµĪ½ĻŒĻ„Ī·Ļ„ĪµĻ‚" + }, + "AddStampRequest": { + "title": "Προσθήκη ĻƒĻ†ĻĪ±Ī³ĪÆĪ“Ī±Ļ‚ σε PDF", + "desc": "Προσθήκη κειμένου Ī® ĪµĪ¹ĪŗĻŒĪ½Ļ‰Ī½ ĻƒĻ†ĻĪ±Ī³ĪÆĪ“Ī±Ļ‚ σε ĪŗĪ±ĪøĪæĻĪ¹ĻƒĪ¼Ī­Ī½ĪµĻ‚ ĪøĪ­ĻƒĪµĪ¹Ļ‚" + }, + "removeImagePdf": { + "title": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "desc": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚ Ī±Ļ€ĻŒ PDF για Ī¼ĪµĪÆĻ‰ĻƒĪ· μεγέθους αρχείου" + }, + "splitPdfByChapters": { + "title": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF ανά κεφάλαια", + "desc": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ ĪµĪ½ĻŒĻ‚ PDF σε πολλαπλά αρχεία βάσει της Γομής κεφαλαίων." + }, + "validateSignature": { + "title": "Ī•Ļ€Ī¹ĪŗĻĻĻ‰ĻƒĪ· υπογραφής PDF", + "desc": "Ī•Ļ€Ī±Ī»Ī®ĪøĪµĻ…ĻƒĪ· ĻˆĪ·Ļ†Ī¹Ī±ĪŗĻŽĪ½ Ļ…Ļ€ĪæĪ³ĻĪ±Ļ†ĻŽĪ½ και Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĻŽĪ½ σε έγγραφα PDF" + }, + "replaceColorPdf": { + "title": "Ī‘Ī½Ļ„Ī¹ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· και Ī±Ī½Ī±ĻƒĻ„ĻĪæĻ†Ī® Ļ‡ĻĻŽĪ¼Ī±Ļ„ĪæĻ‚", + "desc": "Ī‘Ī½Ļ„Ī¹ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· Ļ‡ĻĻŽĪ¼Ī±Ļ„ĪæĻ‚ για κείμενο και Ļ†ĻŒĪ½Ļ„Īæ σε PDF και Ī±Ī½Ī±ĻƒĻ„ĻĪæĻ†Ī® πλήρους Ļ‡ĻĻŽĪ¼Ī±Ļ„ĪæĻ‚ για Ī¼ĪµĪÆĻ‰ĻƒĪ· μεγέθους αρχείου" + } + }, + "viewPdf": { + "tags": "προβολή,Ī±Ī½Ī¬Ī³Ī½Ļ‰ĻƒĪ·,ĻƒĻ‡ĪæĪ»Ī¹Ī±ĻƒĪ¼ĻŒĻ‚,κείμενο,εικόνα", + "title": "View/Edit PDF", + "header": "Προβολή PDF" + }, + "multiTool": { + "tags": "Πολυεργαλείο,Πολλαπλές λειτουργίες,UI,κλικ και ĻƒĻĻĻƒĪ¹Ī¼Īæ,frontend,πλευρά πελάτη,Ī“Ī¹Ī±Ī“ĻĪ±ĻƒĻ„Ī¹ĪŗĻŒ,Ī“Ī¹Ī±Ļ‡ĪµĪ¹ĻĪÆĻƒĪ¹Ī¼Īæ,Ī¼ĪµĻ„Ī±ĪŗĪÆĪ½Ī·ĻƒĪ·,Γιαγραφή,Ī¼ĪµĻ„Ī±Ī½Ī¬ĻƒĻ„ĪµĻ…ĻƒĪ·,Γιαίρεση", + "title": "Πολυεργαλείο PDF", + "header": "Πολυεργαλείο PDF", + "uploadPrompts": "Όνομα αρχείου", + "selectAll": "Επιλογή ĻŒĪ»Ļ‰Ī½", + "deselectAll": "Αποεπιλογή ĻŒĪ»Ļ‰Ī½", + "selectPages": "Επιλογή ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚", + "selectedPages": "Επιλεγμένες ĻƒĪµĪ»ĪÆĪ“ĪµĻ‚", + "page": "ΣελίΓα", + "deleteSelected": "Διαγραφή επιλεγμένων", + "downloadAll": "Εξαγωγή", + "downloadSelected": "Εξαγωγή επιλεγμένων", + "insertPageBreak": "Ī•Ī¹ĻƒĪ±Ī³Ļ‰Ī³Ī® αλλαγής ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚", + "addFile": "Προσθήκη αρχείου", + "rotateLeft": "Ī ĪµĻĪ¹ĻƒĻ„ĻĪæĻ†Ī® Ī±ĻĪ¹ĻƒĻ„ĪµĻĪ¬", + "rotateRight": "Ī ĪµĻĪ¹ĻƒĻ„ĻĪæĻ†Ī® Γεξιά", + "split": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚", + "moveLeft": "ĪœĪµĻ„Ī±ĪŗĪÆĪ½Ī·ĻƒĪ· Ī±ĻĪ¹ĻƒĻ„ĪµĻĪ¬", + "moveRight": "ĪœĪµĻ„Ī±ĪŗĪÆĪ½Ī·ĻƒĪ· Γεξιά", + "delete": "Διαγραφή", + "dragDropMessage": "Επιλεγμένη(ες) σελίΓα(ες)", + "undo": "Ī‘Ī½Ī±ĪÆĻĪµĻƒĪ·", + "redo": "Ī•Ļ€Ī±Ī½Ī¬Ī»Ī·ĻˆĪ·" + }, + "merge": { + "tags": "ĻƒĻ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ·,λειτουργίες ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½,backend,πλευρά Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī®", + "title": "Ī£Ļ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ·", + "header": "Ī£Ļ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ· Ļ€ĪæĪ»Ī»Ī±Ļ€Ī»ĻŽĪ½ PDF (2+)", + "sortByName": "Ταξινόμηση κατά όνομα", + "sortByDate": "Ταξινόμηση κατά ημερομηνία", + "removeCertSign": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĻˆĪ·Ļ†Ī¹Ī±ĪŗĪ®Ļ‚ υπογραφής ĻƒĻ„Īæ ĻƒĻ…Ī³Ļ‡Ļ‰Ī½ĪµĻ…Ī¼Ī­Ī½Īæ αρχείο;", + "submit": "Ī£Ļ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ·" + }, + "split": { + "tags": "λειτουργίες ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½,Γιαίρεση,πολλαπλές ĻƒĪµĪ»ĪÆĪ“ĪµĻ‚,κοπή,πλευρά Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī®", + "title": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF", + "header": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF", + "desc": { + "1": "Οι αριθμοί που επιλέγετε είναι Īæ Ī±ĻĪ¹ĪøĪ¼ĻŒĻ‚ ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ ĻƒĻ„Ī·Ī½ οποία θέλετε να κάνετε Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒ", + "2": "ĪˆĻ„ĻƒĪ¹, επιλέγοντας 1,3,7-9 θα Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪÆĻƒĪµĪ¹ ένα έγγραφο 10 ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ σε 6 Ī¾ĪµĻ‡Ļ‰ĻĪ¹ĻƒĻ„Ī¬ PDF με:", + "3": "ĪˆĪ³Ī³ĻĪ±Ļ†Īæ #1: ΣελίΓα 1", + "4": "ĪˆĪ³Ī³ĻĪ±Ļ†Īæ #2: ΣελίΓα 2 και 3", + "5": "ĪˆĪ³Ī³ĻĪ±Ļ†Īæ #3: ΣελίΓα 4, 5, 6 και 7", + "6": "ĪˆĪ³Ī³ĻĪ±Ļ†Īæ #4: ΣελίΓα 8", + "7": "ĪˆĪ³Ī³ĻĪ±Ļ†Īæ #5: ΣελίΓα 9", + "8": "ĪˆĪ³Ī³ĻĪ±Ļ†Īæ #6: ΣελίΓα 10" + }, + "splitPages": "Ī•Ī¹ĻƒĪ¬Ī³ĪµĻ„Īµ ĻƒĪµĪ»ĪÆĪ“ĪµĻ‚ για Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒ:", + "submit": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚" + }, + "rotate": { + "tags": "πλευρά Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī®", + "title": "Ī ĪµĻĪ¹ĻƒĻ„ĻĪæĻ†Ī® PDF", + "header": "Ī ĪµĻĪ¹ĻƒĻ„ĻĪæĻ†Ī® PDF", + "selectAngle": "Επιλέξτε γωνία Ļ€ĪµĻĪ¹ĻƒĻ„ĻĪæĻ†Ī®Ļ‚ (σε Ļ€ĪæĪ»Ī»Ī±Ļ€Ī»Ī¬ĻƒĪ¹Ī± των 90 Ī¼ĪæĪ¹ĻĻŽĪ½):", + "submit": "Ī ĪµĻĪ¹ĻƒĻ„ĻĪæĻ†Ī®" + }, + "imageToPdf": { + "tags": "μετατροπή,εικόνα,jpg,φωτογραφία" + }, + "pdfToImage": { + "tags": "μετατροπή,εικόνα,jpg,φωτογραφία", + "title": "PDF σε εικόνα", + "header": "PDF σε εικόνα", + "selectText": "ĪœĪæĻĻ†Ī® ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "singleOrMultiple": "Ī¤ĻĻ€ĪæĻ‚ Ī±Ļ€ĪæĻ„ĪµĪ»Ī­ĻƒĪ¼Ī±Ļ„ĪæĻ‚ ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "single": "Μία μεγάλη εικόνα", + "multi": "Πολλαπλές ĪµĪ¹ĪŗĻŒĪ½ĪµĻ‚", + "colorType": "Ī¤ĻĻ€ĪæĻ‚ Ļ‡ĻĻŽĪ¼Ī±Ļ„ĪæĻ‚", + "color": "ĪˆĪ³Ļ‡ĻĻ‰Ī¼Īæ", + "grey": "Κλίμακα του γκρι", + "blackwhite": "Ī‘ĻƒĻ€ĻĻŒĪ¼Ī±Ļ…ĻĪæ (ĪœĻ€ĪæĻĪµĪÆ να Ļ‡Ī±ĪøĪæĻĪ½ ΓεΓομένα!)", + "submit": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī®", + "info": "Ī— Python Γεν είναι ĪµĪ³ĪŗĪ±Ļ„ĪµĻƒĻ„Ī·Ī¼Ī­Ī½Ī·. Απαιτείται για μετατροπή WebP.", + "placeholder": "(Ļ€.χ. 1,2,8 Ī® 4,7,12-16 Ī® 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,Ī¶Ļ…Ī³ĻŒĻ‚,Ī¼ĪæĪ½ĻŒĻ‚,Ļ„Ī±Ī¾Ī¹Ī½ĻŒĪ¼Ī·ĻƒĪ·,Ī¼ĪµĻ„Ī±ĪŗĪÆĪ½Ī·ĻƒĪ·", + "title": "ĪŸĻĪ³Ī¬Ī½Ļ‰ĻƒĪ· ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "header": "ĪŸĻĪ³Ī¬Ī½Ļ‰ĻƒĪ· ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ PDF", + "submit": "ΑναΓιάταξη ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "mode": { + "_value": "Λειτουργία", + "1": "Προσαρμοσμένη σειρά ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "2": "Ī‘Ī½Ļ„ĪÆĻƒĻ„ĻĪæĻ†Ī· σειρά", + "3": "Ταξινόμηση Γιπλής ĻŒĻˆĪ·Ļ‚", + "4": "Ταξινόμηση φυλλαΓίου", + "5": "Ταξινόμηση φυλλαΓίου πλευρικής ĻƒĻ…ĻĻĪ±Ļ†Ī®Ļ‚", + "6": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ Ī¼ĪæĪ½ĻŽĪ½-Ī¶Ļ…Ī³ĻŽĪ½", + "7": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· Ļ€ĻĻŽĻ„Ī·Ļ‚", + "8": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· τελευταίας", + "9": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· Ļ€ĻĻŽĻ„Ī·Ļ‚ και τελευταίας", + "10": "Ī£Ļ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ· Ī¼ĪæĪ½ĻŽĪ½-Ī¶Ļ…Ī³ĻŽĪ½", + "11": "Duplicate all pages" + }, + "placeholder": "(Ļ€.χ. 1,3,2 Ī® 4-8,2,10-12 Ī® 2n-1)" + }, + "addImage": { + "tags": "εικόνα,jpg,φωτογραφία", + "title": "Προσθήκη ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "header": "Προσθήκη ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚ σε PDF", + "everyPage": "Κάθε σελίΓα;", + "upload": "Προσθήκη ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "submit": "Προσθήκη ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚" + }, + "watermark": { + "tags": "κείμενο,ĪµĻ€Ī±Ī½Ī±Ī»Ī±Ī¼Ī²Ī±Ī½ĻŒĪ¼ĪµĪ½Īæ,ετικέτα,Ī¹Ī“Ī¹ĪæĪŗĻ„Ī·ĻƒĪÆĪ±,πνευματικά Ī“Ī¹ĪŗĪ±Ī¹ĻŽĪ¼Ī±Ļ„Ī±,ĪµĪ¼Ļ€ĪæĻĪ¹ĪŗĻŒ σήμα,εικόνα,jpg,φωτογραφία", + "title": "Προσθήκη υΓατογραφήματος", + "header": "Προσθήκη υΓατογραφήματος", + "customColor": "Προσαρμοσμένο Ļ‡ĻĻŽĪ¼Ī± κειμένου", + "selectText": { + "1": "Επιλέξτε PDF για Ļ€ĻĪæĻƒĪøĪ®ĪŗĪ· υΓατογραφήματος:", + "2": "Κείμενο υΓατογραφήματος:", + "3": "ĪœĪ­Ī³ĪµĪøĪæĻ‚ Ī³ĻĪ±Ī¼Ī¼Ī±Ļ„ĪæĻƒĪµĪ¹ĻĪ¬Ļ‚:", + "4": "Ī ĪµĻĪ¹ĻƒĻ„ĻĪæĻ†Ī® (0-360):", + "5": "ĪŸĻĪ¹Ī¶ĻŒĪ½Ļ„Ī¹Īæ Ī“Ī¹Ī¬ĻƒĻ„Ī·Ī¼Ī± (Κενό Ī¼ĪµĻ„Ī±Ī¾Ļ κάθε υΓατογραφήματος ĪæĻĪ¹Ī¶ĻŒĪ½Ļ„Ī¹Ī±):", + "6": "ĪšĪ¬ĪøĪµĻ„Īæ Ī“Ī¹Ī¬ĻƒĻ„Ī·Ī¼Ī± (Κενό Ī¼ĪµĻ„Ī±Ī¾Ļ κάθε υΓατογραφήματος κάθετα):", + "7": "Διαφάνεια (0% - 100%):", + "8": "Ī¤ĻĻ€ĪæĻ‚ υΓατογραφήματος:", + "9": "Ī•Ī¹ĪŗĻŒĪ½Ī± υΓατογραφήματος:", + "10": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® PDF σε PDF-Ī•Ī¹ĪŗĻŒĪ½Ī±" + }, + "submit": "Προσθήκη υΓατογραφήματος", + "type": { + "1": "Κείμενο", + "2": "Ī•Ī¹ĪŗĻŒĪ½Ī±" + } + }, + "permissions": { + "tags": "Ī±Ī½Ī¬Ī³Ī½Ļ‰ĻƒĪ·,εγγραφή,ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĪÆĪ±,ĪµĪŗĻ„ĻĻ€Ļ‰ĻƒĪ·", + "title": "Αλλαγή Γικαιωμάτων", + "header": "Αλλαγή Γικαιωμάτων", + "warning": "Ī ĻĪæĪµĪ¹Ī“ĪæĻ€ĪæĪÆĪ·ĻƒĪ·: για να ĪŗĪ±Ļ„Ī±ĻƒĻ„ĪæĻĪ½ αυτά τα Ī“Ī¹ĪŗĪ±Ī¹ĻŽĪ¼Ī±Ļ„Ī± αμετάβλητα, ĻƒĻ…Ī½Ī¹ĻƒĻ„Ī¬Ļ„Ī±Ī¹ να τα ĪæĻĪÆĻƒĪµĻ„Īµ με ĪŗĻ‰Ī“Ī¹ĪŗĻŒ Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ·Ļ‚ Ī¼Ī­ĻƒĻ‰ της ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ Ļ€ĻĪæĻƒĪøĪ®ĪŗĪ·Ļ‚ ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ", + "selectText": { + "1": "Επιλέξτε PDF για αλλαγή Γικαιωμάτων", + "2": "Ī”Ī¹ĪŗĪ±Ī¹ĻŽĪ¼Ī±Ļ„Ī± προς ορισμό", + "3": "Αποτροπή ĻƒĻ…Ī½Ī±ĻĪ¼ĪæĪ»ĻŒĪ³Ī·ĻƒĪ·Ļ‚ εγγράφου", + "4": "Αποτροπή εξαγωγής περιεχομένου", + "5": "Αποτροπή εξαγωγής για Ļ€ĻĪæĻƒĪ²Ī±ĻƒĪ¹Ī¼ĻŒĻ„Ī·Ļ„Ī±", + "6": "Αποτροπή ĻƒĻ…Ī¼Ļ€Ī»Ī®ĻĻ‰ĻƒĪ·Ļ‚ Ļ†ĻŒĻĪ¼Ī±Ļ‚", + "7": "Αποτροπή Ļ„ĻĪæĻ€ĪæĻ€ĪæĪÆĪ·ĻƒĪ·Ļ‚", + "8": "Αποτροπή Ļ„ĻĪæĻ€ĪæĻ€ĪæĪÆĪ·ĻƒĪ·Ļ‚ ĻƒĻ‡ĪæĪ»Ī¹Ī±ĻƒĪ¼ĻŽĪ½", + "9": "Αποτροπή ĪµĪŗĻ„ĻĻ€Ļ‰ĻƒĪ·Ļ‚", + "10": "Αποτροπή ĪµĪŗĻ„ĻĻ€Ļ‰ĻƒĪ·Ļ‚ σε Γιαφορετικές μορφές" + }, + "submit": "Αλλαγή" + }, + "removePages": { + "tags": "Ī±Ļ†Ī±ĪÆĻĪµĻƒĪ· ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½,Γιαγραφή ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½" + }, + "addPassword": { + "tags": "Ī±ĻƒĻ†Ī¬Ī»ĪµĪ¹Ī±,Ī±ĻƒĻ†Ī¬Ī»ĪµĪ¹Ī±", + "title": "Προσθήκη ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ", + "header": "Προσθήκη ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ (ĪšĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ¬Ļ†Ī·ĻƒĪ·)", + "selectText": { + "1": "Επιλέξτε PDF για ĪŗĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ¬Ļ†Ī·ĻƒĪ·", + "2": "ĪšĻ‰Ī“Ī¹ĪŗĻŒĻ‚ Ļ‡ĻĪ®ĻƒĻ„Ī·", + "3": "ĪœĪ®ĪŗĪæĻ‚ ĪŗĪ»ĪµĪ¹Ī“Ī¹ĪæĻ ĪŗĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ¬Ļ†Ī·ĻƒĪ·Ļ‚", + "4": "Οι Ļ…ĻˆĪ·Ī»ĻŒĻ„ĪµĻĪµĻ‚ τιμές είναι Ī¹ĻƒĻ‡Ļ…ĻĻŒĻ„ĪµĻĪµĻ‚, αλλά οι Ļ‡Ī±Ī¼Ī·Ī»ĻŒĻ„ĪµĻĪµĻ‚ τιμές έχουν ĪŗĪ±Ī»ĻĻ„ĪµĻĪ· ĻƒĻ…Ī¼Ī²Ī±Ļ„ĻŒĻ„Ī·Ļ„Ī±.", + "5": "Ī”Ī¹ĪŗĪ±Ī¹ĻŽĪ¼Ī±Ļ„Ī± προς ορισμό (Ī£Ļ…Ī½Ī¹ĻƒĻ„Ī¬Ļ„Ī±Ī¹ να Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆĻ„Ī±Ī¹ μαζί με ĪŗĻ‰Ī“Ī¹ĪŗĻŒ ιΓιοκτήτη)", + "6": "Αποτροπή ĻƒĻ…Ī½Ī±ĻĪ¼ĪæĪ»ĻŒĪ³Ī·ĻƒĪ·Ļ‚ εγγράφου", + "7": "Αποτροπή εξαγωγής περιεχομένου", + "8": "Αποτροπή εξαγωγής για Ļ€ĻĪæĻƒĪ²Ī±ĻƒĪ¹Ī¼ĻŒĻ„Ī·Ļ„Ī±", + "9": "Αποτροπή ĻƒĻ…Ī¼Ļ€Ī»Ī®ĻĻ‰ĻƒĪ·Ļ‚ Ļ†ĻŒĻĪ¼Ī±Ļ‚", + "10": "Αποτροπή Ļ„ĻĪæĻ€ĪæĻ€ĪæĪÆĪ·ĻƒĪ·Ļ‚", + "11": "Αποτροπή Ļ„ĻĪæĻ€ĪæĻ€ĪæĪÆĪ·ĻƒĪ·Ļ‚ ĻƒĻ‡ĪæĪ»Ī¹Ī±ĻƒĪ¼ĻŽĪ½", + "12": "Αποτροπή ĪµĪŗĻ„ĻĻ€Ļ‰ĻƒĪ·Ļ‚", + "13": "Αποτροπή ĪµĪŗĻ„ĻĻ€Ļ‰ĻƒĪ·Ļ‚ σε Γιαφορετικές μορφές", + "14": "ĪšĻ‰Ī“Ī¹ĪŗĻŒĻ‚ ιΓιοκτήτη", + "15": "Περιορίζει τι μπορεί να γίνει με το έγγραφο μετά το άνοιγμά του (Δεν Ļ…Ļ€ĪæĻƒĻ„Ī·ĻĪÆĪ¶ĪµĻ„Ī±Ī¹ Ī±Ļ€ĻŒ όλα τα προγράμματα Ī±Ī½Ī¬Ī³Ī½Ļ‰ĻƒĪ·Ļ‚)", + "16": "Περιορίζει το άνοιγμα του ίΓιου του εγγράφου" + }, + "submit": "ĪšĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ¬Ļ†Ī·ĻƒĪ·" + }, + "removePassword": { + "tags": "Ī±ĻƒĻ†Ī¬Ī»ĪµĪ¹Ī±,Ī±Ļ€ĪæĪŗĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ¬Ļ†Ī·ĻƒĪ·,Ī±ĻƒĻ†Ī¬Ī»ĪµĪ¹Ī±,Ī±Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ,Γιαγραφή ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ", + "title": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ", + "header": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪŗĻ‰Ī“Ī¹ĪŗĪæĻ (Ī‘Ļ€ĪæĪŗĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ¬Ļ†Ī·ĻƒĪ·)", + "selectText": { + "1": "Επιλέξτε PDF για Ī±Ļ€ĪæĪŗĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ¬Ļ†Ī·ĻƒĪ·", + "2": "ĪšĻ‰Ī“Ī¹ĪŗĻŒĻ‚" + }, + "submit": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ·" + }, + "compressPdfs": { + "tags": "ĻƒĻ…Ī¼Ļ€ĪÆĪµĻƒĪ·,μικρό,Ī¼Ī¹ĪŗĻĪæĻƒĪŗĪæĻ€Ī¹ĪŗĻŒ" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "τίτλος,ĻƒĻ…Ī³Ī³ĻĪ±Ļ†Ī­Ī±Ļ‚,ημερομηνία,Γημιουργία,Ļ‡ĻĻŒĪ½ĪæĻ‚,ĪµĪŗĪ“ĻŒĻ„Ī·Ļ‚,Ļ€Ī±ĻĪ±Ī³Ļ‰Ī³ĻŒĻ‚,ĻƒĻ„Ī±Ļ„Ī¹ĻƒĻ„Ī¹ĪŗĪ¬", + "title": "Τίτλος:", + "header": "Αλλαγή μεταΓεΓομένων", + "selectText": { + "1": "Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĻ„ĪµĪÆĻ„Īµ τις μεταβλητές που επιθυμείτε να αλλάξετε", + "2": "Διαγραφή ĻŒĪ»Ļ‰Ī½ των μεταΓεΓομένων", + "3": "Ī•Ī¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· Ļ€ĻĪæĻƒĪ±ĻĪ¼ĪæĻƒĪ¼Ī­Ī½Ļ‰Ī½ μεταΓεΓομένων:", + "4": "Άλλα μεταΓεΓομένα:", + "5": "Προσθήκη Ļ€ĻĪæĻƒĪ±ĻĪ¼ĪæĻƒĪ¼Ī­Ī½Ī·Ļ‚ ĪŗĪ±Ļ„Ī±Ļ‡ĻŽĻĪ·ĻƒĪ·Ļ‚ μεταΓεΓομένων" + }, + "author": "Συγγραφέας:", + "creationDate": "Ημερομηνία Γημιουργίας (yyyy/MM/dd HH:mm:ss):", + "creator": "Ī”Ī·Ī¼Ī¹ĪæĻ…ĻĪ³ĻŒĻ‚:", + "keywords": "Λέξεις-κλειΓιά:", + "modDate": "Ημερομηνία Ļ„ĻĪæĻ€ĪæĻ€ĪæĪÆĪ·ĻƒĪ·Ļ‚ (yyyy/MM/dd HH:mm:ss):", + "producer": "Ī Ī±ĻĪ±Ī³Ļ‰Ī³ĻŒĻ‚:", + "subject": "Θέμα:", + "trapped": "ΠαγιΓευμένο:", + "submit": "Αλλαγή" + }, + "fileToPDF": { + "tags": "μετατροπή,μορφή,έγγραφο,εικόνα,Ļ€Ī±ĻĪæĻ…ĻƒĪÆĪ±ĻƒĪ·,κείμενο,μετατροπή,γραφείο,έγγραφα,word,excel,powerpoint", + "title": "Αρχείο σε PDF", + "header": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® οποιουΓήποτε αρχείου σε PDF", + "credit": "Αυτή Ī· Ļ…Ļ€Ī·ĻĪµĻƒĪÆĪ± Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ LibreOffice και Unoconv για μετατροπή αρχείων.", + "supportedFileTypesInfo": "Ī„Ļ€ĪæĻƒĻ„Ī·ĻĪ¹Ī¶ĻŒĪ¼ĪµĪ½ĪæĪ¹ Ļ„ĻĻ€ĪæĪ¹ αρχείων", + "supportedFileTypes": "Οι Ļ…Ļ€ĪæĻƒĻ„Ī·ĻĪ¹Ī¶ĻŒĪ¼ĪµĪ½ĪæĪ¹ Ļ„ĻĻ€ĪæĪ¹ αρχείων θα πρέπει να περιλαμβάνουν τα παρακάτω, Ļ‰ĻƒĻ„ĻŒĻƒĪæ για μια πλήρη ενημερωμένη Ī»ĪÆĻƒĻ„Ī± Ļ…Ļ€ĪæĻƒĻ„Ī·ĻĪ¹Ī¶ĻŒĪ¼ĪµĪ½Ļ‰Ī½ Ī¼ĪæĻĻ†ĻŽĪ½, ανατρέξτε ĻƒĻ„Ī·Ī½ Ļ„ĪµĪŗĪ¼Ī·ĻĪÆĻ‰ĻƒĪ· του LibreOffice", + "submit": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® σε PDF" + }, + "ocr": { + "tags": "Ī±Ī½Ī±Ī³Ī½ĻŽĻĪ¹ĻƒĪ·,κείμενο,εικόνα,ĻƒĪ¬ĻĻ‰ĻƒĪ·,Ī±Ī½Ī¬Ī³Ī½Ļ‰ĻƒĪ·,Ī±Ī½Ī±Ī³Ī½ĻŽĻĪ¹ĻƒĪ·,Ī±Ī½ĪÆĻ‡Ī½ĪµĻ…ĻƒĪ·,ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī¬ĻƒĪ¹Ī¼Īæ", + "title": "OCR / ĪšĪ±ĪøĪ±ĻĪ¹ĻƒĪ¼ĻŒĻ‚ ĻƒĪ±ĻĻŽĻƒĪµĻ‰Ī½", + "header": "ĪšĪ±ĪøĪ±ĻĪ¹ĻƒĪ¼ĻŒĻ‚ ĻƒĪ±ĻĻŽĻƒĪµĻ‰Ī½ / OCR (ĪŸĻ€Ļ„Ī¹ĪŗĪ® Ī±Ī½Ī±Ī³Ī½ĻŽĻĪ¹ĻƒĪ· χαρακτήρων)", + "selectText": { + "1": "Επιλέξτε Ī³Ī»ĻŽĻƒĻƒĪµĻ‚ που θα Ī±Ī½Ī¹Ļ‡Ī½ĪµĻ…ĪøĪæĻĪ½ μέσα ĻƒĻ„Īæ PDF (Αυτές που εμφανίζονται είναι αυτές που Ī±Ī½Ī¹Ļ‡Ī½ĪµĻĪæĪ½Ļ„Ī±Ī¹ αυτή τη ĻƒĻ„Ī¹Ī³Ī¼Ī®):", + "2": "Δημιουργία αρχείου κειμένου που περιέχει το κείμενο OCR μαζί με το PDF που έχει Ļ…Ļ€ĪæĻƒĻ„ĪµĪÆ OCR", + "3": "Ī”Ī¹ĻŒĻĪøĻ‰ĻƒĪ· ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ που ĻƒĪ±ĻĻŽĪøĪ·ĪŗĪ±Ī½ με κλίση Ļ€ĪµĻĪ¹ĻƒĻ„ĻĪ­Ļ†ĪæĪ½Ļ„Ī¬Ļ‚ τες Ļ€ĪÆĻƒĻ‰ ĻƒĻ„Ī· θέση τους", + "4": "ĪšĪ±ĪøĪ±ĻĪ¹ĻƒĪ¼ĻŒĻ‚ ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ ĻŽĻƒĻ„Īµ να είναι Ī»Ī¹Ī³ĻŒĻ„ĪµĻĪæ Ļ€Ī¹ĪøĪ±Ī½ĻŒ το OCR να βρει κείμενο ĻƒĻ„Īæ ĪøĻŒĻĻ…Ī²Īæ Ļ†ĻŒĪ½Ļ„ĪæĻ…. (Καμία αλλαγή ĻƒĻ„Ī·Ī½ έξοΓο)", + "5": "ĪšĪ±ĪøĪ±ĻĪ¹ĻƒĪ¼ĻŒĻ‚ ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ ĻŽĻƒĻ„Īµ να είναι Ī»Ī¹Ī³ĻŒĻ„ĪµĻĪæ Ļ€Ī¹ĪøĪ±Ī½ĻŒ το OCR να βρει κείμενο ĻƒĻ„Īæ ĪøĻŒĻĻ…Ī²Īæ Ļ†ĻŒĪ½Ļ„ĪæĻ…, Γιατηρεί τον καθαρισμό ĻƒĻ„Ī·Ī½ έξοΓο.", + "6": "Αγνοεί ĻƒĪµĪ»ĪÆĪ“ĪµĻ‚ που έχουν Ī“Ī¹Ī±Ī“ĻĪ±ĻƒĻ„Ī¹ĪŗĻŒ κείμενο, εκτελεί OCR μόνο σε ĻƒĪµĪ»ĪÆĪ“ĪµĻ‚ που είναι ĪµĪ¹ĪŗĻŒĪ½ĪµĻ‚", + "7": "Ī•Ī¾Ī±Ī½Ī±Ī³ĪŗĪ±ĻƒĪ¼ĻŒĻ‚ OCR, θα ĪµĪŗĻ„ĪµĪ»Ī­ĻƒĪµĪ¹ OCR σε κάθε σελίΓα Ī±Ļ†Ī±Ī¹ĻĻŽĪ½Ļ„Ī±Ļ‚ όλα τα αρχικά ĻƒĻ„ĪæĪ¹Ļ‡ĪµĪÆĪ± κειμένου", + "8": "Κανονικό (Θα ĪµĪ¼Ļ†Ī±Ī½ĪÆĻƒĪµĪ¹ ĻƒĻ†Ī¬Ī»Ī¼Ī± εάν το PDF περιέχει κείμενο)", + "9": "Ī ĻĻŒĻƒĪøĪµĻ„ĪµĻ‚ ĻĻ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚", + "10": "Λειτουργία OCR", + "11": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪµĪ¹ĪŗĻŒĪ½Ļ‰Ī½ μετά το OCR (Αφαιρεί ĪŸĪ›Ī•Ī£ τις ĪµĪ¹ĪŗĻŒĪ½ĪµĻ‚, Ļ‡ĻĪ®ĻƒĪ¹Ī¼Īæ μόνο εάν είναι μέρος βήματος μετατροπής)", + "12": "Ī¤ĻĻ€ĪæĻ‚ Ī±Ļ€ĻŒĪ“ĪæĻƒĪ·Ļ‚ (Για προχωρημένους)" + }, + "help": "Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ Ī“Ī¹Ī±Ī²Ī¬ĻƒĻ„Īµ αυτή την Ļ„ĪµĪŗĪ¼Ī·ĻĪÆĻ‰ĻƒĪ· για το Ļ€ĻŽĻ‚ να το Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī®ĻƒĪµĻ„Īµ για άλλες Ī³Ī»ĻŽĻƒĻƒĪµĻ‚ Ī®/και Ļ‡ĻĪ®ĻƒĪ· ĪµĪŗĻ„ĻŒĻ‚ docker", + "credit": "Αυτή Ī· Ļ…Ļ€Ī·ĻĪµĻƒĪÆĪ± Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ qpdf και Tesseract για OCR.", + "submit": "Ī•Ļ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĪÆĪ± PDF με OCR" + }, + "extractImages": { + "tags": "εικόνα,φωτογραφία,Ī±Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ·,αρχείο,zip,ĻƒĻĪ»Ī»Ī·ĻˆĪ·,λήψη", + "title": "Εξαγωγή ĪµĪ¹ĪŗĻŒĪ½Ļ‰Ī½", + "header": "Εξαγωγή ĪµĪ¹ĪŗĻŒĪ½Ļ‰Ī½", + "selectText": "Επιλέξτε μορφή ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚ για μετατροπή των ĪµĪ¾Ī±Ī³ĻŒĪ¼ĪµĪ½Ļ‰Ī½ ĪµĪ¹ĪŗĻŒĪ½Ļ‰Ī½", + "allowDuplicates": "Ī‘Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ· Ī“Ī¹Ļ€Ī»ĻŒĻ„Ļ…Ļ€Ļ‰Ī½ ĪµĪ¹ĪŗĻŒĪ½Ļ‰Ī½", + "submit": "Εξαγωγή" + }, + "pdfToPDFA": { + "tags": "αρχείο,Ī¼Ī±ĪŗĻĪæĻ‡ĻĻŒĪ½Ī¹Īæ,Ļ€ĻĻŒĻ„Ļ…Ļ€Īæ,μετατροπή,Ī±Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ·,Ī“Ī¹Ī±Ļ„Ī®ĻĪ·ĻƒĪ·", + "title": "PDF σε PDF/A", + "header": "PDF σε PDF/A", + "credit": "Αυτή Ī· Ļ…Ļ€Ī·ĻĪµĻƒĪÆĪ± Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ libreoffice για μετατροπή PDF/A", + "submit": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī®", + "tip": "Προς το Ļ€Ī±ĻĻŒĪ½ Γεν λειτουργεί για πολλαπλές ĪµĪ¹ĻƒĻŒĪ“ĪæĻ…Ļ‚ Ļ„Ī±Ļ…Ļ„ĻŒĻ‡ĻĪæĪ½Ī±", + "outputFormat": "ĪœĪæĻĻ†Ī® ĪµĪ¾ĻŒĪ“ĪæĻ…", + "pdfWithDigitalSignature": "Το PDF περιέχει ĻˆĪ·Ļ†Ī¹Ī±ĪŗĪ® υπογραφή. Αυτή θα αφαιρεθεί ĻƒĻ„Īæ ĪµĻ€ĻŒĪ¼ĪµĪ½Īæ βήμα." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,μετατροπή,μορφή,μετατροπή,γραφείο,microsoft,docfile", + "title": "PDF σε Word", + "header": "PDF σε Word", + "selectText": { + "1": "ĪœĪæĻĻ†Ī® αρχείου ĪµĪ¾ĻŒĪ“ĪæĻ…" + }, + "credit": "Αυτή Ī· Ļ…Ļ€Ī·ĻĪµĻƒĪÆĪ± Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ το LibreOffice για μετατροπή αρχείων.", + "submit": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī®" + }, + "PDFToPresentation": { + "tags": "Γιαφάνειες,Ļ€Ī±ĻĪæĻ…ĻƒĪÆĪ±ĻƒĪ·,γραφείο,microsoft", + "title": "PDF σε Ļ€Ī±ĻĪæĻ…ĻƒĪÆĪ±ĻƒĪ·", + "header": "PDF σε Ļ€Ī±ĻĪæĻ…ĻƒĪÆĪ±ĻƒĪ·", + "selectText": { + "1": "ĪœĪæĻĻ†Ī® αρχείου ĪµĪ¾ĻŒĪ“ĪæĻ…" + }, + "credit": "Αυτή Ī· Ļ…Ļ€Ī·ĻĪµĻƒĪÆĪ± Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ το LibreOffice για μετατροπή αρχείων.", + "submit": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī®" + }, + "PDFToText": { + "tags": "μορφή ĪµĪ¼Ļ€Ī»ĪæĻ…Ļ„Ī¹ĻƒĪ¼Ī­Ī½ĪæĻ… κειμένου,μορφή rtf,ĪµĪ¼Ļ€Ī»ĪæĻ…Ļ„Ī¹ĻƒĪ¼Ī­Ī½Īæ κείμενο", + "title": "PDF σε RTF (κείμενο)", + "header": "PDF σε RTF (κείμενο)", + "selectText": { + "1": "ĪœĪæĻĻ†Ī® αρχείου ĪµĪ¾ĻŒĪ“ĪæĻ…" + }, + "credit": "Αυτή Ī· Ļ…Ļ€Ī·ĻĪµĻƒĪÆĪ± Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ το LibreOffice για μετατροπή αρχείων.", + "submit": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī®" + }, + "PDFToHTML": { + "tags": "Ļ€ĪµĻĪ¹ĪµĻ‡ĻŒĪ¼ĪµĪ½Īæ web,Ļ†Ī¹Ī»Ī¹ĪŗĻŒ προς τον browser", + "title": "PDF σε HTML", + "header": "PDF σε HTML", + "credit": "Αυτή Ī· Ļ…Ļ€Ī·ĻĪµĻƒĪÆĪ± Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ το pdftohtml για μετατροπή αρχείων.", + "submit": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī®" + }, + "PDFToXML": { + "tags": "εξαγωγή-ΓεΓομένων,Γομημένο-Ļ€ĪµĻĪ¹ĪµĻ‡ĻŒĪ¼ĪµĪ½Īæ,Ī“Ī¹Ī±Ī»ĪµĪ¹Ļ„ĪæĻ…ĻĪ³Ī¹ĪŗĻŒĻ„Ī·Ļ„Ī±,μετατροπή", + "title": "PDF σε XML", + "header": "PDF σε XML", + "credit": "Αυτή Ī· Ļ…Ļ€Ī·ĻĪµĻƒĪÆĪ± Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ το LibreOffice για μετατροπή αρχείων.", + "submit": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī®" + }, + "ScannerImageSplit": { + "tags": "Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚,Ī±Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī·-Ī±Ī½ĪÆĻ‡Ī½ĪµĻ…ĻƒĪ·,ĻƒĪ±ĻĻŽĻƒĪµĪ¹Ļ‚,πολλαπλές-φωτογραφίες,ĪæĻĪ³Ī¬Ī½Ļ‰ĻƒĪ·", + "selectText": { + "1": "Όριο γωνίας:", + "2": "Ορίζει την ĪµĪ»Ī¬Ļ‡Ī¹ĻƒĻ„Ī· Ī±Ļ€ĻŒĪ»Ļ…Ļ„Ī· γωνία που απαιτείται για την Ļ€ĪµĻĪ¹ĻƒĻ„ĻĪæĻ†Ī® της ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚ (προεπιλογή: 10).", + "3": "Ανοχή:", + "4": "Καθορίζει το ĪµĻĻĪæĻ‚ της χρωματικής Ī“Ī¹Ī±ĪŗĻĪ¼Ī±Ī½ĻƒĪ·Ļ‚ Ī³ĻĻĻ‰ Ī±Ļ€ĻŒ το ĪµĪŗĻ„Ī¹Ī¼ĻŽĪ¼ĪµĪ½Īæ Ļ‡ĻĻŽĪ¼Ī± Ļ†ĻŒĪ½Ļ„ĪæĻ… (προεπιλογή: 30).", + "5": "Ī•Ī»Ī¬Ļ‡Ī¹ĻƒĻ„Ī· περιοχή:", + "6": "Ορίζει το ĪµĪ»Ī¬Ļ‡Ī¹ĻƒĻ„Īæ όριο περιοχής για μια φωτογραφία (προεπιλογή: 10000).", + "7": "Ī•Ī»Ī¬Ļ‡Ī¹ĻƒĻ„Ī· περιοχή περιγράμματος:", + "8": "Ορίζει το ĪµĪ»Ī¬Ļ‡Ī¹ĻƒĻ„Īæ όριο περιοχής περιγράμματος για μια φωτογραφία", + "9": "ĪœĪ­Ī³ĪµĪøĪæĻ‚ περιγράμματος:", + "10": "Ορίζει το μέγεθος του περιγράμματος που Ļ€ĻĪæĻƒĻ„ĪÆĪøĪµĻ„Ī±Ī¹ και αφαιρείται για την αποφυγή Ī»ĪµĻ…ĪŗĻŽĪ½ περιγραμμάτων ĻƒĻ„Īæ Ī±Ļ€ĪæĻ„Ī­Ī»ĪµĻƒĪ¼Ī± (προεπιλογή: 1)." + }, + "info": "Ī— Python Γεν είναι ĪµĪ³ĪŗĪ±Ļ„ĪµĻƒĻ„Ī·Ī¼Ī­Ī½Ī·. Απαιτείται για ĪµĪŗĻ„Ī­Ī»ĪµĻƒĪ·." + }, + "sign": { + "tags": "ĪµĪ¾ĪæĻ…ĻƒĪ¹ĪæĪ“ĻŒĻ„Ī·ĻƒĪ·,αρχικά,ĻƒĻ‡ĪµĪ“Ī¹Ī±ĻƒĪ¼Ī­Ī½Ī·-υπογραφή,υπογραφή-κειμένου,υπογραφή-ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "title": "΄πογραφή", + "header": "΄πογραφή PDF", + "upload": "ĪœĪµĻ„Ī±Ļ†ĻŒĻĻ„Ļ‰ĻƒĪ· ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "draw": "Ī£Ļ‡ĪµĪ“ĪÆĪ±ĻƒĪ· υπογραφής", + "text": "Ī•Ī¹ĻƒĪ±Ī³Ļ‰Ī³Ī® κειμένου", + "clear": "ĪšĪ±ĪøĪ±ĻĪ¹ĻƒĪ¼ĻŒĻ‚", + "add": "Προσθήκη", + "saved": "Αποθηκευμένες υπογραφές", + "save": "Ī‘Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ· υπογραφής", + "personalSigs": "Ī ĻĪæĻƒĻ‰Ļ€Ī¹ĪŗĪ­Ļ‚ υπογραφές", + "sharedSigs": "ĪšĪæĪ¹Ī½ĻŒĻ‡ĻĪ·ĻƒĻ„ĪµĻ‚ υπογραφές", + "noSavedSigs": "Δεν βρέθηκαν αποθηκευμένες υπογραφές", + "addToAll": "Προσθήκη σε ĻŒĪ»ĪµĻ‚ τις ĻƒĪµĪ»ĪÆĪ“ĪµĻ‚", + "delete": "Διαγραφή", + "first": "Ī ĻĻŽĻ„Ī· σελίΓα", + "last": "Τελευταία σελίΓα", + "next": "Ī•Ļ€ĻŒĪ¼ĪµĪ½Ī· σελίΓα", + "previous": "Ī ĻĪæĪ·Ī³ĪæĻĪ¼ĪµĪ½Ī· σελίΓα", + "maintainRatio": "Εναλλαγή Ī“Ī¹Ī±Ļ„Ī®ĻĪ·ĻƒĪ·Ļ‚ αναλογίας Ī“Ī¹Ī±ĻƒĻ„Ī¬ĻƒĪµĻ‰Ī½", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "ĻƒĻ„Ī±Ļ„Ī¹ĪŗĻŒ,Ī±Ļ€ĪµĪ½ĪµĻĪ³ĪæĻ€ĪæĪÆĪ·ĻƒĪ·,μη-Ī“Ī¹Ī±Ī“ĻĪ±ĻƒĻ„Ī¹ĪŗĻŒ,Ī±Ļ€Ī»ĪæĻ€ĪæĪÆĪ·ĻƒĪ·", + "title": "Ī™ĻƒĪæĻ€Ī­Ī“Ļ‰ĻƒĪ·", + "header": "Ī™ĻƒĪæĻ€Ī­Ī“Ļ‰ĻƒĪ· PDF", + "flattenOnlyForms": "Ī™ĻƒĪæĻ€Ī­Ī“Ļ‰ĻƒĪ· μόνο Ļ†ĪæĻĪ¼ĻŽĪ½", + "submit": "Ī™ĻƒĪæĻ€Ī­Ī“Ļ‰ĻƒĪ·" + }, + "repair": { + "tags": "ĪµĻ€Ī¹Ī“Ī¹ĻŒĻĪøĻ‰ĻƒĪ·,Ī±Ļ€ĪæĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ·,Ī“Ī¹ĻŒĻĪøĻ‰ĻƒĪ·,Ī±Ī½Ī¬ĪŗĻ„Ī·ĻƒĪ·", + "title": "Ī•Ļ€Ī¹Ī“Ī¹ĻŒĻĪøĻ‰ĻƒĪ·", + "header": "Ī•Ļ€Ī¹Ī“Ī¹ĻŒĻĪøĻ‰ĻƒĪ· PDF", + "submit": "Ī•Ļ€Ī¹Ī“Ī¹ĻŒĻĪøĻ‰ĻƒĪ·" + }, + "removeBlanks": { + "tags": "ĪŗĪ±ĪøĪ±ĻĪ¹ĻƒĪ¼ĻŒĻ‚,Ī±Ļ€Ī»ĪæĻ€ĪæĪÆĪ·ĻƒĪ·,χωρίς-Ļ€ĪµĻĪ¹ĪµĻ‡ĻŒĪ¼ĪµĪ½Īæ,ĪæĻĪ³Ī¬Ī½Ļ‰ĻƒĪ·", + "title": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪŗĪµĪ½ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "header": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪŗĪµĪ½ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "threshold": "Όριο Ī»ĪµĻ…ĪŗĻŒĻ„Ī·Ļ„Ī±Ļ‚ ĪµĪ¹ĪŗĪæĪ½ĪæĻƒĻ„ĪæĪ¹Ļ‡ĪµĪÆĻ‰Ī½:", + "thresholdDesc": "Όριο για τον Ļ€ĻĪæĻƒĪ“Ī¹ĪæĻĪ¹ĻƒĪ¼ĻŒ Ļ€ĻŒĻƒĪæ Ī»ĪµĻ…ĪŗĻŒ πρέπει να είναι ένα ĪµĪ¹ĪŗĪæĪ½ĪæĻƒĻ„ĪæĪ¹Ļ‡ĪµĪÆĪæ για να θεωρηθεί 'Ī›ĪµĻ…ĪŗĻŒ'. 0 = ĪœĪ±ĻĻĪæ, 255 καθαρό Ī»ĪµĻ…ĪŗĻŒ.", + "whitePercent": "Ī ĪæĻƒĪæĻƒĻ„ĻŒ Ī»ĪµĻ…ĪŗĪæĻ (%):", + "whitePercentDesc": "Ī ĪæĻƒĪæĻƒĻ„ĻŒ της ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ που πρέπει να είναι 'λευκά' ĪµĪ¹ĪŗĪæĪ½ĪæĻƒĻ„ĪæĪ¹Ļ‡ĪµĪÆĪ± για να αφαιρεθεί", + "submit": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪŗĪµĪ½ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½" + }, + "removeAnnotations": { + "tags": "ĻƒĻ‡ĻŒĪ»Ī¹Ī±,ĪµĻ€Ī¹ĻƒĪ®Ī¼Ī±Ī½ĻƒĪ·,ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚,ĪµĻ€Ī¹ĻƒĪ·Ī¼Ī¬Ī½ĻƒĪµĪ¹Ļ‚,Ī±Ļ†Ī±ĪÆĻĪµĻƒĪ·", + "title": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĻƒĻ‡ĪæĪ»ĪÆĻ‰Ī½", + "header": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĻƒĻ‡ĪæĪ»ĪÆĻ‰Ī½", + "submit": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ·" + }, + "compare": { + "tags": "Ī“Ī¹Ī±Ļ†ĪæĻĪæĻ€ĪæĪÆĪ·ĻƒĪ·,αντιπαραβολή,αλλαγές,Ī±Ī½Ī¬Ī»Ļ…ĻƒĪ·", + "title": "Ī£ĻĪ³ĪŗĻĪ¹ĻƒĪ·", + "header": "Ī£ĻĪ³ĪŗĻĪ¹ĻƒĪ· PDF", + "highlightColor": { + "1": "Ī§ĻĻŽĪ¼Ī± ĪµĻ€Ī¹ĻƒĪ®Ī¼Ī±Ī½ĻƒĪ·Ļ‚ 1:", + "2": "Ī§ĻĻŽĪ¼Ī± ĪµĻ€Ī¹ĻƒĪ®Ī¼Ī±Ī½ĻƒĪ·Ļ‚ 2:" + }, + "document": { + "1": "ĪˆĪ³Ī³ĻĪ±Ļ†Īæ 1", + "2": "ĪˆĪ³Ī³ĻĪ±Ļ†Īæ 2" + }, + "submit": "Ī£ĻĪ³ĪŗĻĪ¹ĻƒĪ·", + "complex": { + "message": "Ένα Ī® και τα Ī“ĻĪæ Ļ€Ī±ĻĪµĻ‡ĻŒĪ¼ĪµĪ½Ī± έγγραφα είναι μεγάλα αρχεία, Ī· ακρίβεια της ĻƒĻĪ³ĪŗĻĪ¹ĻƒĪ·Ļ‚ μπορεί να μειωθεί" + }, + "large": { + "file": { + "message": "Ένα Ī® και τα Ī“ĻĪæ Ļ€Ī±ĻĪµĻ‡ĻŒĪ¼ĪµĪ½Ī± έγγραφα είναι Ļ€ĪæĪ»Ļ μεγάλα για ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĪÆĪ±" + } + }, + "no": { + "text": { + "message": "Ένα Ī® και τα Ī“ĻĪæ επιλεγμένα PDF Γεν έχουν Ļ€ĪµĻĪ¹ĪµĻ‡ĻŒĪ¼ĪµĪ½Īæ κειμένου. Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ επιλέξτε PDF με κείμενο για ĻƒĻĪ³ĪŗĻĪ¹ĻƒĪ·." + } + } + }, + "certSign": { + "tags": "Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪÆĪ·ĻƒĪ·,PEM,P12,ĪµĻ€ĪÆĻƒĪ·Ī¼Īæ,ĪŗĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ¬Ļ†Ī·ĻƒĪ·", + "title": "΄πογραφή με Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĻŒ", + "header": "΄πογραφή PDF με το Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĻŒ ĻƒĪ±Ļ‚ (Σε εξέλιξη)", + "selectPDF": "Επιλέξτε αρχείο PDF για υπογραφή:", + "jksNote": "Ī£Ī·Ī¼ĪµĪÆĻ‰ĻƒĪ·: Εάν Īæ Ļ„ĻĻ€ĪæĻ‚ του Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĪæĻ ĻƒĪ±Ļ‚ Γεν αναφέρεται παρακάτω, Ļ€Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ Ī¼ĪµĻ„Ī±Ļ„ĻĪ­ĻˆĻ„Īµ το σε αρχείο Java Keystore (.jks) Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĻŽĪ½Ļ„Ī±Ļ‚ το εργαλείο γραμμής ĪµĪ½Ļ„ĪæĪ»ĻŽĪ½ keytool. Στη ĻƒĻ…Ī½Ī­Ļ‡ĪµĪ¹Ī±, επιλέξτε την επιλογή αρχείου .jks παρακάτω.", + "selectKey": "Επιλέξτε το αρχείο Ī¹Ī“Ī¹Ļ‰Ļ„Ī¹ĪŗĪæĻ ĪŗĪ»ĪµĪ¹Ī“Ī¹ĪæĻ ĻƒĪ±Ļ‚ (μορφή PKCS#8, μπορεί να είναι .pem Ī® .der):", + "selectCert": "Επιλέξτε το αρχείο Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĪæĻ ĻƒĪ±Ļ‚ (μορφή X.509, μπορεί να είναι .pem Ī® .der):", + "selectP12": "Επιλέξτε το αρχείο PKCS#12 Keystore (.p12 Ī® .pfx) (Ī ĻĪæĪ±Ī¹ĻĪµĻ„Ī¹ĪŗĻŒ, εάν παρέχεται, θα πρέπει να περιέχει το Ī¹Ī“Ī¹Ļ‰Ļ„Ī¹ĪŗĻŒ κλειΓί και το Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĻŒ ĻƒĪ±Ļ‚):", + "selectJKS": "Επιλέξτε το αρχείο Java Keystore (.jks Ī® .keystore):", + "certType": "Ī¤ĻĻ€ĪæĻ‚ Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĪæĻ", + "password": "Ī•Ī¹ĻƒĪ¬Ī³ĪµĻ„Īµ τον ĪŗĻ‰Ī“Ī¹ĪŗĻŒ Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ·Ļ‚ του Keystore Ī® του Ī¹Ī“Ī¹Ļ‰Ļ„Ī¹ĪŗĪæĻ ĪŗĪ»ĪµĪ¹Ī“Ī¹ĪæĻ (εάν υπάρχει):", + "showSig": "Ī•Ī¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· υπογραφής", + "reason": "Αιτία", + "location": "Ī¤ĪæĻ€ĪæĪøĪµĻƒĪÆĪ±", + "name": "Όνομα", + "showLogo": "Ī•Ī¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· Ī»ĪæĪ³ĻŒĻ„Ļ…Ļ€ĪæĻ…", + "submit": "΄πογραφή PDF" + }, + "removeCertSign": { + "tags": "Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪÆĪ·ĻƒĪ·,PEM,P12,ĪµĻ€ĪÆĻƒĪ·Ī¼Īæ,Ī±Ļ€ĪæĪŗĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ¬Ļ†Ī·ĻƒĪ·", + "title": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· υπογραφής Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĪæĻ", + "header": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· της ĻˆĪ·Ļ†Ī¹Ī±ĪŗĪ®Ļ‚ υπογραφής Ī±Ļ€ĻŒ το PDF", + "selectPDF": "Επιλέξτε ένα αρχείο PDF:", + "submit": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· υπογραφής" + }, + "pageLayout": { + "tags": "ĻƒĻ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ·,ĻƒĻĪ½ĪøĪµĻƒĪ·,ενιαία-προβολή,ĪæĻĪ³Ī¬Ī½Ļ‰ĻƒĪ·", + "title": "Διάταξη Ļ€ĪæĪ»Ī»Ī±Ļ€Ī»ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "header": "Διάταξη Ļ€ĪæĪ»Ī»Ī±Ļ€Ī»ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "pagesPerSheet": "ΣελίΓες ανά Ļ†ĻĪ»Ī»Īæ:", + "addBorder": "Προσθήκη περιγραμμάτων", + "submit": "΄ποβολή" + }, + "scalePages": { + "tags": "αλλαγή μεγέθους,Ļ„ĻĪæĻ€ĪæĻ€ĪæĪÆĪ·ĻƒĪ·,Ī“Ī¹Ī¬ĻƒĻ„Ī±ĻƒĪ·,Ļ€ĻĪæĻƒĪ±ĻĪ¼ĪæĪ³Ī®", + "title": "Προσαρμογή κλίμακας ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚", + "header": "Προσαρμογή κλίμακας ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚", + "pageSize": "ĪœĪ­Ī³ĪµĪøĪæĻ‚ ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ του εγγράφου.", + "keepPageSize": "Ī‘ĻĻ‡Ī¹ĪŗĻŒ μέγεθος", + "scaleFactor": "ΕπίπεΓο ζουμ (περικοπή) ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚.", + "submit": "΄ποβολή" + }, + "add-page-numbers": { + "tags": "αρίθμηση,ετικέτα,ĪæĻĪ³Ī¬Ī½Ļ‰ĻƒĪ·,ευρετήριο" + }, + "auto-rename": { + "tags": "Ī±Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī·-Ī±Ī½ĪÆĻ‡Ī½ĪµĻ…ĻƒĪ·,βάσει-κεφαλίΓας,ĪæĻĪ³Ī¬Ī½Ļ‰ĻƒĪ·,επανετικέτα", + "title": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· Ī¼ĪµĻ„ĪæĪ½ĪæĪ¼Ī±ĻƒĪÆĪ±", + "header": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· Ī¼ĪµĻ„ĪæĪ½ĪæĪ¼Ī±ĻƒĪÆĪ± PDF", + "submit": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· Ī¼ĪµĻ„ĪæĪ½ĪæĪ¼Ī±ĻƒĪÆĪ±" + }, + "adjust-contrast": { + "tags": "Ī“Ī¹ĻŒĻĪøĻ‰ĻƒĪ·-χρωμάτων,ĻƒĻ…Ī½Ļ„ĪæĪ½Ī¹ĻƒĪ¼ĻŒĻ‚,Ļ„ĻĪæĻ€ĪæĻ€ĪæĪÆĪ·ĻƒĪ·,Ī²ĪµĪ»Ļ„ĪÆĻ‰ĻƒĪ·" + }, + "crop": { + "tags": "περικοπή,ĻƒĻ…ĻĻĪÆĪŗĪ½Ļ‰ĻƒĪ·,ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĪÆĪ±,ĻƒĻ‡Ī®Ī¼Ī±", + "title": "Περικοπή", + "header": "Περικοπή PDF", + "submit": "΄ποβολή" + }, + "autoSplitPDF": { + "tags": "QR-based,Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚,ĻƒĪ¬ĻĻ‰ĻƒĪ·-τμήματος,ĪæĻĪ³Ī¬Ī½Ļ‰ĻƒĪ·", + "title": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„ĪæĻ‚ Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF", + "header": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„ĪæĻ‚ Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF", + "description": "Ī•ĪŗĻ„Ļ…Ļ€ĻŽĻƒĻ„Īµ, ĪµĪ¹ĻƒĪ¬Ī³ĪµĻ„Īµ, ĻƒĪ±ĻĻŽĻƒĻ„Īµ, Ī¼ĪµĻ„Ī±Ļ†ĪæĻĻ„ĻŽĻƒĻ„Īµ και Ī±Ļ†Ī®ĻƒĻ„Īµ μας να Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪÆĻƒĪæĻ…Ī¼Īµ Ī±Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī± τα έγγραφά ĻƒĪ±Ļ‚. Δεν απαιτείται χειροκίνητη Ļ„Ī±Ī¾Ī¹Ī½ĻŒĪ¼Ī·ĻƒĪ·.", + "selectText": { + "1": "Ī•ĪŗĻ„Ļ…Ļ€ĻŽĻƒĻ„Īµ μερικά Ļ†ĻĪ»Ī»Ī± Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĪæĻ Ī±Ļ€ĻŒ παρακάτω (Αρκεί και Ī±ĻƒĻ€ĻĻŒĪ¼Ī±Ļ…ĻĪ· ĪµĪŗĻ„ĻĻ€Ļ‰ĻƒĪ·).", + "2": "Ī£Ī±ĻĻŽĻƒĻ„Īµ όλα τα έγγραφά ĻƒĪ±Ļ‚ Ļ„Ī±Ļ…Ļ„ĻŒĻ‡ĻĪæĪ½Ī± Ļ„ĪæĻ€ĪæĪøĪµĻ„ĻŽĪ½Ļ„Ī±Ļ‚ το Ļ†ĻĪ»Ī»Īæ Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĪæĻ ανάμεσά τους.", + "3": "ĪœĪµĻ„Ī±Ļ†ĪæĻĻ„ĻŽĻƒĻ„Īµ το ενιαίο μεγάλο ĻƒĪ±ĻĻ‰Ī¼Ī­Ī½Īæ αρχείο PDF και Ī±Ļ†Ī®ĻƒĻ„Īµ το Stirling PDF να Ļ‡ĪµĪ¹ĻĪ¹ĻƒĻ„ĪµĪÆ τα Ļ…Ļ€ĻŒĪ»ĪæĪ¹Ļ€Ī±.", + "4": "Οι ĻƒĪµĪ»ĪÆĪ“ĪµĻ‚ Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĪæĻ Ī±Ī½Ī¹Ļ‡Ī½ĪµĻĪæĪ½Ļ„Ī±Ī¹ και Ī±Ļ†Ī±Ī¹ĻĪæĻĪ½Ļ„Ī±Ī¹ Ī±Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī±, ĪµĪ¾Ī±ĻƒĻ†Ī±Ī»ĪÆĪ¶ĪæĪ½Ļ„Ī±Ļ‚ ένα καθαρό Ļ„ĪµĪ»Ī¹ĪŗĻŒ έγγραφο." + }, + "formPrompt": "΄ποβολή PDF που περιέχει Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĻ„Ī­Ļ‚ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ Stirling-PDF:", + "duplexMode": "Λειτουργία Γιπλής ĻŒĻˆĪ·Ļ‚ (Ī£Ī¬ĻĻ‰ĻƒĪ· μπρος και Ļ€ĪÆĻƒĻ‰)", + "dividerDownload2": "Ī›Ī®ĻˆĪ· 'Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„ĪæĻ‚ Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĻ„Ī®Ļ‚ (με οΓηγίες).pdf'", + "submit": "΄ποβολή" + }, + "sanitizePdf": { + "tags": "ĪŗĪ±ĪøĪ±ĻĪ¹ĻƒĪ¼ĻŒĻ‚,Ī±ĻƒĻ†Ī¬Ī»ĪµĪ¹Ī±,Ī±ĻƒĻ†Ī±Ī»Ī­Ļ‚,Ī±Ļ†Ī±ĪÆĻĪµĻƒĪ·-Ī±Ļ€ĪµĪ¹Ī»ĻŽĪ½" + }, + "URLToPDF": { + "tags": "λήψη-Ī¹ĻƒĻ„ĪæĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚,Ī±Ļ€ĪæĪøĪ®ĪŗĪµĻ…ĻƒĪ·-ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚,web-σε-έγγραφο,Ī±ĻĻ‡ĪµĪ¹ĪæĪøĪ­Ļ„Ī·ĻƒĪ·", + "title": "URL σε PDF", + "header": "URL σε PDF", + "submit": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī®", + "credit": "Ī§ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ το WeasyPrint" + }, + "HTMLToPDF": { + "tags": "markup,Ļ€ĪµĻĪ¹ĪµĻ‡ĻŒĪ¼ĪµĪ½Īæ-web,μετατροπή,μετατροπή", + "title": "HTML σε PDF", + "header": "HTML σε PDF", + "help": "Δέχεται αρχεία HTML και ZIP που περιέχουν html/css/ĪµĪ¹ĪŗĻŒĪ½ĪµĻ‚ κλπ που Ī±Ļ€Ī±Ī¹Ļ„ĪæĻĪ½Ļ„Ī±Ī¹", + "submit": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī®", + "credit": "Ī§ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ το WeasyPrint", + "zoom": "ΕπίπεΓο ζουμ για την ĪµĪ¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· της Ī¹ĻƒĻ„ĪæĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚.", + "pageWidth": "Πλάτος ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ σε ĪµĪŗĪ±Ļ„ĪæĻƒĻ„Ī¬. (Κενό για προεπιλογή)", + "pageHeight": "ĪŽĻˆĪæĻ‚ ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ σε ĪµĪŗĪ±Ļ„ĪæĻƒĻ„Ī¬. (Κενό για προεπιλογή)", + "marginTop": "Πάνω Ļ€ĪµĻĪ¹ĪøĻŽĻĪ¹Īæ ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ σε Ļ‡Ī¹Ī»Ī¹ĪæĻƒĻ„Ī¬. (Κενό για προεπιλογή)", + "marginBottom": "ĪšĪ¬Ļ„Ļ‰ Ļ€ĪµĻĪ¹ĪøĻŽĻĪ¹Īæ ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ σε Ļ‡Ī¹Ī»Ī¹ĪæĻƒĻ„Ī¬. (Κενό για προεπιλογή)", + "marginLeft": "Ī‘ĻĪ¹ĻƒĻ„ĪµĻĻŒ Ļ€ĪµĻĪ¹ĪøĻŽĻĪ¹Īæ ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ σε Ļ‡Ī¹Ī»Ī¹ĪæĻƒĻ„Ī¬. (Κενό για προεπιλογή)", + "marginRight": "Δεξί Ļ€ĪµĻĪ¹ĪøĻŽĻĪ¹Īæ ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ σε Ļ‡Ī¹Ī»Ī¹ĪæĻƒĻ„Ī¬. (Κενό για προεπιλογή)", + "printBackground": "Ī‘Ļ€ĻŒĪ“ĪæĻƒĪ· Ļ†ĻŒĪ½Ļ„ĪæĻ… Ī¹ĻƒĻ„ĪæĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½.", + "defaultHeader": "Ī•Ī½ĪµĻĪ³ĪæĻ€ĪæĪÆĪ·ĻƒĪ· προεπιλεγμένης κεφαλίΓας (Όνομα και Ī±ĻĪ¹ĪøĪ¼ĻŒĻ‚ ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚)", + "cssMediaType": "Αλλαγή του Ļ„ĻĻ€ĪæĻ… Ī¼Ī­ĻƒĪæĻ… CSS της ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚.", + "none": "Κανένα", + "print": "Ī•ĪŗĻ„ĻĻ€Ļ‰ĻƒĪ·", + "screen": "Οθόνη" + }, + "MarkdownToPDF": { + "tags": "markup,Ļ€ĪµĻĪ¹ĪµĻ‡ĻŒĪ¼ĪµĪ½Īæ-web,μετατροπή,μετατροπή", + "title": "Markdown σε PDF", + "header": "Markdown σε PDF", + "submit": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī®", + "help": "Ī•ĻĪ³Ī±ĻƒĪÆĪ± σε εξέλιξη", + "credit": "Ī§ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ το WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "πληροφορίες,ΓεΓομένα,ĻƒĻ„Ī±Ļ„Ī¹ĻƒĻ„Ī¹ĪŗĪ¬,ĻƒĻ„Ī±Ļ„Ī¹ĻƒĻ„Ī¹ĪŗĪ®", + "title": "Ī›Ī®ĻˆĪ· Ļ€Ī»Ī·ĻĪæĻ†ĪæĻĪ¹ĻŽĪ½ PDF", + "header": "Ī›Ī®ĻˆĪ· Ļ€Ī»Ī·ĻĪæĻ†ĪæĻĪ¹ĻŽĪ½ PDF", + "submit": "Ī›Ī®ĻˆĪ· Ļ€Ī»Ī·ĻĪæĻ†ĪæĻĪ¹ĻŽĪ½", + "downloadJson": "Ī›Ī®ĻˆĪ· JSON" + }, + "extractPage": { + "tags": "εξαγωγή" + }, + "PdfToSinglePage": { + "tags": "ενιαία σελίΓα" + }, + "showJS": { + "tags": "JS", + "title": "Ī•Ī¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· Javascript", + "header": "Ī•Ī¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· Javascript", + "downloadJS": "Ī›Ī®ĻˆĪ· Javascript", + "submit": "Ī•Ī¼Ļ†Ī¬Ī½Ī¹ĻƒĪ·" + }, + "autoRedact": { + "tags": "Ī±Ļ€ĻŒĪŗĻĻ…ĻˆĪ·,ĪŗĻĻĻˆĪ¹Ī¼Īæ,Ī¼Ī±ĻĻĪ¹ĻƒĪ¼Ī±,Ī¼Ī±ĻĻĪæ,Ī¼Ī±ĻĪŗĪ±Ī“ĻŒĻĪæĻ‚,κρυμμένο", + "title": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· Ī±Ļ€ĻŒĪŗĻĻ…ĻˆĪ·", + "header": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· Ī±Ļ€ĻŒĪŗĻĻ…ĻˆĪ·", + "colorLabel": "Ī§ĻĻŽĪ¼Ī±", + "textsToRedactLabel": "Κείμενο προς Ī±Ļ€ĻŒĪŗĻĻ…ĻˆĪ· (Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼Ī­Ī½Īæ ανά γραμμή)", + "textsToRedactPlaceholder": "Ļ€.χ. \\nĪ•Ī¼Ļ€Ī¹ĻƒĻ„ĪµĻ…Ļ„Ī¹ĪŗĻŒ \\nΆκρως Ī±Ļ€ĻŒĻĻĪ·Ļ„Īæ", + "useRegexLabel": "Χρήση Regex", + "wholeWordSearchLabel": "Ī‘Ī½Ī±Ī¶Ī®Ļ„Ī·ĻƒĪ· ĪæĪ»ĻŒĪŗĪ»Ī·ĻĪ·Ļ‚ λέξης", + "customPaddingLabel": "Προσαρμοσμένο επιπλέον Ļ€ĪµĻĪ¹ĪøĻŽĻĪ¹Īæ", + "convertPDFToImageLabel": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® PDF σε PDF-Ī•Ī¹ĪŗĻŒĪ½Ī± (Ī§ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆĻ„Ī±Ī¹ για την Ī±Ļ†Ī±ĪÆĻĪµĻƒĪ· κειμένου Ļ€ĪÆĻƒĻ‰ Ī±Ļ€ĻŒ το Ļ€Ī»Ī±ĪÆĻƒĪ¹Īæ)", + "submitButton": "΄ποβολή" + }, + "redact": { + "tags": "Ī±Ļ€ĻŒĪŗĻĻ…ĻˆĪ·,ĪŗĻĻĻˆĪ¹Ī¼Īæ,Ī¼Ī±ĻĻĪ¹ĻƒĪ¼Ī±,Ī¼Ī±ĻĻĪæ,Ī¼Ī±ĻĪŗĪ±Ī“ĻŒĻĪæĻ‚,κρυμμένο,χειροκίνητο", + "title": "Χειροκίνητη Ī±Ļ€ĻŒĪŗĻĻ…ĻˆĪ·", + "header": "Χειροκίνητη Ī±Ļ€ĻŒĪŗĻĻ…ĻˆĪ·", + "submit": "Ī‘Ļ€ĻŒĪŗĻĻ…ĻˆĪ·", + "textBasedRedaction": "Ī‘Ļ€ĻŒĪŗĻĻ…ĻˆĪ· βάσει κειμένου", + "pageBasedRedaction": "Ī‘Ļ€ĻŒĪŗĻĻ…ĻˆĪ· βάσει ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚", + "convertPDFToImageLabel": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® PDF σε PDF-Ī•Ī¹ĪŗĻŒĪ½Ī± (Ī§ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆĻ„Ī±Ī¹ για την Ī±Ļ†Ī±ĪÆĻĪµĻƒĪ· κειμένου Ļ€ĪÆĻƒĻ‰ Ī±Ļ€ĻŒ το Ļ€Ī»Ī±ĪÆĻƒĪ¹Īæ)", + "pageRedactionNumbers": { + "title": "ΣελίΓες", + "placeholder": "(Ļ€.χ. 1,2,8 Ī® 4,7,12-16 Ī® 2n-1)" + }, + "redactionColor": { + "title": "Ī§ĻĻŽĪ¼Ī± Ī±Ļ€ĻŒĪŗĻĻ…ĻˆĪ·Ļ‚" + }, + "export": "Εξαγωγή", + "upload": "ĪœĪµĻ„Ī±Ļ†ĻŒĻĻ„Ļ‰ĻƒĪ·", + "boxRedaction": "Ī£Ļ‡ĪµĪ“ĪÆĪ±ĻƒĪ· Ļ€Ī»Ī±Ī¹ĻƒĪÆĪæĻ… Ī±Ļ€ĻŒĪŗĻĻ…ĻˆĪ·Ļ‚", + "zoom": "Ζουμ", + "zoomIn": "ĪœĪµĪ³Ī­ĪøĻ…Ī½ĻƒĪ·", + "zoomOut": "Ī£Ī¼ĪÆĪŗĻĻ…Ī½ĻƒĪ·", + "nextPage": "Ī•Ļ€ĻŒĪ¼ĪµĪ½Ī· σελίΓα", + "previousPage": "Ī ĻĪæĪ·Ī³ĪæĻĪ¼ĪµĪ½Ī· σελίΓα", + "toggleSidebar": "Εναλλαγή πλευρικής μπάρας", + "showThumbnails": "Ī•Ī¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· Ī¼Ī¹ĪŗĻĪæĪ³ĻĪ±Ļ†Ī¹ĻŽĪ½", + "showDocumentOutline": "Ī•Ī¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· περιγράμματος εγγράφου (Ī“Ī¹Ļ€Ī»ĻŒ κλικ για ανάπτυξη/ĻƒĻĪ¼Ļ€Ļ„Ļ…Ī¾Ī· ĻŒĪ»Ļ‰Ī½ των ĻƒĻ„ĪæĪ¹Ļ‡ĪµĪÆĻ‰Ī½)", + "showAttatchments": "Ī•Ī¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· ĻƒĻ…Ī½Ī·Ī¼Ī¼Ī­Ī½Ļ‰Ī½", + "showLayers": "Ī•Ī¼Ļ†Ī¬Ī½Ī¹ĻƒĪ· επιπέΓων (Ī“Ī¹Ļ€Ī»ĻŒ κλικ για επαναφορά ĻŒĪ»Ļ‰Ī½ των επιπέΓων ĻƒĻ„Ī·Ī½ προεπιλεγμένη ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ·)", + "colourPicker": "Επιλογέας Ļ‡ĻĻŽĪ¼Ī±Ļ„ĪæĻ‚", + "findCurrentOutlineItem": "Ī•ĻĻĪµĻƒĪ· τρέχοντος ĻƒĻ„ĪæĪ¹Ļ‡ĪµĪÆĪæĻ… περιγράμματος", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,εξαγωγή πίνακα,εξαγωγή,μετατροπή" + }, + "autoSizeSplitPDF": { + "tags": "pdf,Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚,έγγραφο,ĪæĻĪ³Ī¬Ī½Ļ‰ĻƒĪ·" + }, + "overlay-pdfs": { + "tags": "ĪµĻ€Ī¹ĪŗĪ¬Ī»Ļ…ĻˆĪ·", + "header": "Ī•Ļ€Ī¹ĪŗĪ¬Ī»Ļ…ĻˆĪ· αρχείων PDF", + "baseFile": { + "label": "Επιλέξτε βασικό αρχείο PDF" + }, + "overlayFiles": { + "label": "Επιλέξτε αρχεία PDF ĪµĻ€Ī¹ĪŗĪ¬Ī»Ļ…ĻˆĪ·Ļ‚" + }, + "mode": { + "label": "Επιλέξτε λειτουργία ĪµĻ€Ī¹ĪŗĪ¬Ī»Ļ…ĻˆĪ·Ļ‚", + "sequential": "ΔιαΓοχική ĪµĻ€Ī¹ĪŗĪ¬Ī»Ļ…ĻˆĪ·", + "interleaved": "Ī•Ī½Ī±Ī»Ī»Ī±ĻƒĻƒĻŒĪ¼ĪµĪ½Ī· ĪµĻ€Ī¹ĪŗĪ¬Ī»Ļ…ĻˆĪ·", + "fixedRepeat": "Σταθερή ĪµĻ€Ī±Ī½Ī±Ī»Ī±Ī¼Ī²Ī±Ī½ĻŒĪ¼ĪµĪ½Ī· ĪµĻ€Ī¹ĪŗĪ¬Ī»Ļ…ĻˆĪ·" + }, + "counts": { + "label": "Πλήθος ĪµĻ€Ī¹ĪŗĪ±Ī»ĻĻˆĪµĻ‰Ī½ (για λειτουργία ĻƒĻ„Ī±ĪøĪµĻĪ®Ļ‚ ĪµĻ€Ī±Ī½Ī¬Ī»Ī·ĻˆĪ·Ļ‚)", + "placeholder": "Ī•Ī¹ĻƒĪ¬Ī³ĪµĻ„Īµ πλήθη Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼Ī­Ī½Ī± με κόμμα (Ļ€.χ. 2,3,1)" + }, + "position": { + "label": "Επιλέξτε θέση ĪµĻ€Ī¹ĪŗĪ¬Ī»Ļ…ĻˆĪ·Ļ‚", + "foreground": "Προσκήνιο", + "background": "Ī¦ĻŒĪ½Ļ„Īæ" + }, + "submit": "΄ποβολή" + }, + "split-by-sections": { + "tags": "Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ ενοτήτων,Γιαίρεση,Ļ€ĻĪæĻƒĪ±ĻĪ¼ĪæĪ³Ī®", + "title": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF ανά ĪµĪ½ĻŒĻ„Ī·Ļ„ĪµĻ‚", + "header": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF σε ĪµĪ½ĻŒĻ„Ī·Ļ„ĪµĻ‚", + "horizontal": { + "label": "ĪŸĻĪ¹Ī¶ĻŒĪ½Ļ„Ī¹ĪµĻ‚ Ī“Ī¹Ī±Ī¹ĻĪ­ĻƒĪµĪ¹Ļ‚", + "placeholder": "Ī•Ī¹ĻƒĪ¬Ī³ĪµĻ„Īµ αριθμό ĪæĻĪ¹Ī¶ĻŒĪ½Ļ„Ī¹Ļ‰Ī½ Ī“Ī¹Ī±Ī¹ĻĪ­ĻƒĪµĻ‰Ī½" + }, + "vertical": { + "label": "ĪšĪ¬ĪøĪµĻ„ĪµĻ‚ Ī“Ī¹Ī±Ī¹ĻĪ­ĻƒĪµĪ¹Ļ‚", + "placeholder": "Ī•Ī¹ĻƒĪ¬Ī³ĪµĻ„Īµ αριθμό κάθετων Ī“Ī¹Ī±Ī¹ĻĪ­ĻƒĪµĻ‰Ī½" + }, + "submit": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF", + "merge": "Ī£Ļ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ· σε ένα PDF" + }, + "AddStampRequest": { + "tags": "ĻƒĻ†ĻĪ±Ī³ĪÆĪ“Ī±,Ļ€ĻĪæĻƒĪøĪ®ĪŗĪ· ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚,ĪŗĪµĪ½Ļ„ĻĪ¬ĻĪ¹ĻƒĪ¼Ī± ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚,υΓατογράφημα,PDF,ĪµĪ½ĻƒĻ‰Ī¼Ī¬Ļ„Ļ‰ĻƒĪ·,Ļ€ĻĪæĻƒĪ±ĻĪ¼ĪæĪ³Ī®", + "header": "Ī£Ļ†ĻĪ¬Ī³Ī¹ĻƒĪ¼Ī± PDF", + "title": "Ī£Ļ†ĻĪ¬Ī³Ī¹ĻƒĪ¼Ī± PDF", + "stampType": "Ī¤ĻĻ€ĪæĻ‚ ĻƒĻ†ĻĪ±Ī³ĪÆĪ“Ī±Ļ‚", + "stampText": "Κείμενο ĻƒĻ†ĻĪ±Ī³ĪÆĪ“Ī±Ļ‚", + "stampImage": "Ī•Ī¹ĪŗĻŒĪ½Ī± ĻƒĻ†ĻĪ±Ī³ĪÆĪ“Ī±Ļ‚", + "alphabet": "Αλφάβητο", + "fontSize": "ĪœĪ­Ī³ĪµĪøĪæĻ‚ Ī³ĻĪ±Ī¼Ī¼Ī±Ļ„ĪæĻƒĪµĪ¹ĻĪ¬Ļ‚/ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "rotation": "Ī ĪµĻĪ¹ĻƒĻ„ĻĪæĻ†Ī®", + "opacity": "Διαφάνεια", + "position": "Θέση", + "overrideX": "Παράκαμψη ĻƒĻ…Ī½Ļ„ĪµĻ„Ī±Ī³Ī¼Ī­Ī½Ī·Ļ‚ X", + "overrideY": "Παράκαμψη ĻƒĻ…Ī½Ļ„ĪµĻ„Ī±Ī³Ī¼Ī­Ī½Ī·Ļ‚ Y", + "customMargin": "Προσαρμοσμένο Ļ€ĪµĻĪ¹ĪøĻŽĻĪ¹Īæ", + "customColor": "Προσαρμοσμένο Ļ‡ĻĻŽĪ¼Ī± κειμένου", + "submit": "΄ποβολή" + }, + "removeImagePdf": { + "tags": "Ī±Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚,λειτουργίες ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚,backend,server side" + }, + "splitPdfByChapters": { + "tags": "Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚,κεφάλαια,ĻƒĪµĪ»Ī¹Ī“ĪæĪ“ĪµĪÆĪŗĻ„ĪµĻ‚,ĪæĻĪ³Ī¬Ī½Ļ‰ĻƒĪ·" + }, + "validateSignature": { + "tags": "υπογραφή,ĪµĻ€Ī±Ī»Ī®ĪøĪµĻ…ĻƒĪ·,ĪµĻ€Ī¹ĪŗĻĻĻ‰ĻƒĪ·,pdf,Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĻŒ,ĻˆĪ·Ļ†Ī¹Ī±ĪŗĪ® υπογραφή,ĪµĻ€Ī¹ĪŗĻĻĻ‰ĻƒĪ· υπογραφής,ĪµĻ€Ī¹ĪŗĻĻĻ‰ĻƒĪ· Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĪæĻ", + "title": "Ī•Ļ€Ī¹ĪŗĻĻĻ‰ĻƒĪ· Ļ…Ļ€ĪæĪ³ĻĪ±Ļ†ĻŽĪ½ PDF", + "header": "Ī•Ļ€Ī¹ĪŗĻĻĻ‰ĻƒĪ· ĻˆĪ·Ļ†Ī¹Ī±ĪŗĻŽĪ½ Ļ…Ļ€ĪæĪ³ĻĪ±Ļ†ĻŽĪ½", + "selectPDF": "Επιλέξτε υπογεγραμμένο αρχείο PDF", + "submit": "Ī•Ļ€Ī¹ĪŗĻĻĻ‰ĻƒĪ· Ļ…Ļ€ĪæĪ³ĻĪ±Ļ†ĻŽĪ½", + "results": "Ī‘Ļ€ĪæĻ„ĪµĪ»Ī­ĻƒĪ¼Ī±Ļ„Ī± ĪµĻ€Ī¹ĪŗĻĻĻ‰ĻƒĪ·Ļ‚", + "status": { + "_value": "ĪšĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ·", + "valid": "ĪˆĪ³ĪŗĻ…ĻĪ·", + "invalid": "Μη έγκυρη" + }, + "signer": "΄πογράφων", + "date": "Ημερομηνία", + "reason": "Αιτία", + "location": "Ī¤ĪæĻ€ĪæĪøĪµĻƒĪÆĪ±", + "noSignatures": "Δεν βρέθηκαν ĻˆĪ·Ļ†Ī¹Ī±ĪŗĪ­Ļ‚ υπογραφές σε Ī±Ļ…Ļ„ĻŒ το έγγραφο", + "chain": { + "invalid": "Ī— ĪµĻ€Ī¹ĪŗĻĻĻ‰ĻƒĪ· Ī±Ī»Ļ…ĻƒĪÆĪ“Ī±Ļ‚ Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĻŽĪ½ απέτυχε - Γεν είναι Γυνατή Ī· ĪµĻ€Ī±Ī»Ī®ĪøĪµĻ…ĻƒĪ· της Ļ„Ī±Ļ…Ļ„ĻŒĻ„Ī·Ļ„Ī±Ļ‚ του υπογράφοντος" + }, + "trust": { + "invalid": "Το Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĻŒ Γεν Ī²ĻĪÆĻƒĪŗĪµĻ„Ī±Ī¹ ĻƒĻ„Īæ αποθετήριο ĪµĪ¼Ļ€Ī¹ĻƒĻ„ĪæĻƒĻĪ½Ī·Ļ‚ - Γεν είναι Γυνατή Ī· ĪµĻ€Ī±Ī»Ī®ĪøĪµĻ…ĻƒĪ· της πηγής" + }, + "cert": { + "expired": "Το Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĻŒ έχει λήξει", + "revoked": "Το Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĻŒ έχει ανακληθεί", + "info": "Λεπτομέρειες Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĪæĻ", + "issuer": "Ī•ĪŗĪ“ĻŒĻ„Ī·Ļ‚", + "subject": "Θέμα", + "serialNumber": "Ī£ĪµĪ¹ĻĪ¹Ī±ĪŗĻŒĻ‚ Ī±ĻĪ¹ĪøĪ¼ĻŒĻ‚", + "validFrom": "ĪˆĪ³ĪŗĻ…ĻĪæ Ī±Ļ€ĻŒ", + "validUntil": "ĪˆĪ³ĪŗĻ…ĻĪæ έως", + "algorithm": "Ī‘Ī»Ī³ĻŒĻĪ¹ĪøĪ¼ĪæĻ‚", + "keySize": "ĪœĪ­Ī³ĪµĪøĪæĻ‚ ĪŗĪ»ĪµĪ¹Ī“Ī¹ĪæĻ", + "version": "ΈκΓοση", + "keyUsage": "Χρήση ĪŗĪ»ĪµĪ¹Ī“Ī¹ĪæĻ", + "selfSigned": "Αυτο-υπογεγραμμένο", + "bits": "bits" + }, + "signature": { + "info": "Πληροφορίες υπογραφής", + "_value": "΄πογραφή", + "mathValid": "Ī— υπογραφή είναι μαθηματικά έγκυρη ΑΛΛΑ:" + }, + "selectCustomCert": "Προσαρμοσμένο αρχείο Ļ€Ī¹ĻƒĻ„ĪæĻ€ĪæĪ¹Ī·Ļ„Ī¹ĪŗĪæĻ X.509 (Ī ĻĪæĪ±Ī¹ĻĪµĻ„Ī¹ĪŗĻŒ)" + }, + "replace-color": { + "title": "Ī‘Ī½Ļ„Ī¹ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ·-Ī‘Ī½Ī±ĻƒĻ„ĻĪæĻ†Ī® Ļ‡ĻĻŽĪ¼Ī±Ļ„ĪæĻ‚", + "header": "Ī‘Ī½Ļ„Ī¹ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ·-Ī‘Ī½Ī±ĻƒĻ„ĻĪæĻ†Ī® Ļ‡ĻĻŽĪ¼Ī±Ļ„ĪæĻ‚ PDF", + "selectText": { + "1": "Επιλογές Ī±Ī½Ļ„Ī¹ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ·Ļ‚ Ī® Ī±Ī½Ī±ĻƒĻ„ĻĪæĻ†Ī®Ļ‚ Ļ‡ĻĻŽĪ¼Ī±Ļ„ĪæĻ‚", + "2": "Προεπιλογή (Προεπιλεγμένα Ļ‡ĻĻŽĪ¼Ī±Ļ„Ī± Ļ…ĻˆĪ·Ī»Ī®Ļ‚ Ī±Ī½Ļ„ĪÆĪøĪµĻƒĪ·Ļ‚)", + "3": "Προσαρμογή (Προσαρμοσμένα Ļ‡ĻĻŽĪ¼Ī±Ļ„Ī±)", + "4": "Πλήρης Ī±Ī½Ī±ĻƒĻ„ĻĪæĻ†Ī® (Ī‘Ī½Ī±ĻƒĻ„ĻĪæĻ†Ī® ĻŒĪ»Ļ‰Ī½ των χρωμάτων)", + "5": "Επιλογές χρωμάτων Ļ…ĻˆĪ·Ī»Ī®Ļ‚ Ī±Ī½Ļ„ĪÆĪøĪµĻƒĪ·Ļ‚", + "6": "Ī›ĪµĻ…ĪŗĻŒ κείμενο σε Ī¼Ī±ĻĻĪæ Ļ†ĻŒĪ½Ļ„Īæ", + "7": "ĪœĪ±ĻĻĪæ κείμενο σε Ī»ĪµĻ…ĪŗĻŒ Ļ†ĻŒĪ½Ļ„Īæ", + "8": "ĪšĪÆĻ„ĻĪ¹Ī½Īæ κείμενο σε Ī¼Ī±ĻĻĪæ Ļ†ĻŒĪ½Ļ„Īæ", + "9": "Πράσινο κείμενο σε Ī¼Ī±ĻĻĪæ Ļ†ĻŒĪ½Ļ„Īæ", + "10": "Επιλογή Ļ‡ĻĻŽĪ¼Ī±Ļ„ĪæĻ‚ κειμένου", + "11": "Επιλογή Ļ‡ĻĻŽĪ¼Ī±Ļ„ĪæĻ‚ Ļ†ĻŒĪ½Ļ„ĪæĻ…" + }, + "submit": "Ī‘Ī½Ļ„Ī¹ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ·" + }, + "replaceColorPdf": { + "tags": "Ī±Ī½Ļ„Ī¹ĪŗĪ±Ļ„Ī¬ĻƒĻ„Ī±ĻƒĪ· Ļ‡ĻĻŽĪ¼Ī±Ļ„ĪæĻ‚,λειτουργίες ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚,backend,server side" + }, + "login": { + "title": "Ī£ĻĪ½Ī“ĪµĻƒĪ·", + "header": "Ī£ĻĪ½Ī“ĪµĻƒĪ·", + "signin": "Ī£ĻĪ½Ī“ĪµĻƒĪ·", + "rememberme": "ĪĪ± με ĪøĻ…Ī¼Ī¬ĻƒĪ±Ī¹", + "invalid": "Μη έγκυρο όνομα Ļ‡ĻĪ®ĻƒĻ„Ī· Ī® ĪŗĻ‰Ī“Ī¹ĪŗĻŒĻ‚.", + "locked": "Ο Ī»ĪæĪ³Ī±ĻĪ¹Ī±ĻƒĪ¼ĻŒĻ‚ ĻƒĪ±Ļ‚ έχει κλειΓωθεί.", + "signinTitle": "Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ ĻƒĻ…Ī½Ī“ĪµĪøĪµĪÆĻ„Īµ", + "ssoSignIn": "Ī£ĻĪ½Ī“ĪµĻƒĪ· Ī¼Ī­ĻƒĻ‰ Single Sign-on", + "oAuth2AutoCreateDisabled": "Ī— Ī±Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· Γημιουργία Ļ‡ĻĪ®ĻƒĻ„Ī· OAUTH2 είναι απενεργοποιημένη", + "oAuth2AdminBlockedUser": "Ī— εγγραφή Ī® ĻƒĻĪ½Ī“ĪµĻƒĪ· μη εγγεγραμμένων Ļ‡ĻĪ·ĻƒĻ„ĻŽĪ½ είναι προς το Ļ€Ī±ĻĻŒĪ½ Ī±Ļ€ĪæĪŗĪ»ĪµĪ¹ĻƒĪ¼Ī­Ī½Ī·. Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ ĪµĻ€Ī¹ĪŗĪæĪ¹Ī½Ļ‰Ī½Ī®ĻƒĻ„Īµ με τον Ī“Ī¹Ī±Ļ‡ĪµĪ¹ĻĪ¹ĻƒĻ„Ī®.", + "oauth2RequestNotFound": "Το αίτημα ĪµĪ¾ĪæĻ…ĻƒĪ¹ĪæĪ“ĻŒĻ„Ī·ĻƒĪ·Ļ‚ Γεν βρέθηκε", + "oauth2InvalidUserInfoResponse": "Μη έγκυρη Ī±Ļ€ĻŒĪŗĻĪ¹ĻƒĪ· Ļ€Ī»Ī·ĻĪæĻ†ĪæĻĪ¹ĻŽĪ½ Ļ‡ĻĪ®ĻƒĻ„Ī·", + "oauth2invalidRequest": "Μη έγκυρο αίτημα", + "oauth2AccessDenied": "Ī†ĻĪ½Ī·ĻƒĪ· Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ·Ļ‚", + "oauth2InvalidTokenResponse": "Μη έγκυρη Ī±Ļ€ĻŒĪŗĻĪ¹ĻƒĪ· Ī“Ī¹Ī±ĪŗĻĪ¹Ļ„Ī¹ĪŗĪæĻ", + "oauth2InvalidIdToken": "Μη έγκυρο Ī“Ī¹Ī±ĪŗĻĪ¹Ļ„Ī¹ĪŗĻŒ Ļ„Ī±Ļ…Ļ„ĻŒĻ„Ī·Ļ„Ī±Ļ‚", + "relyingPartyRegistrationNotFound": "Δεν βρέθηκε εγγραφή Ī±Ī¾Ī¹ĻŒĻ€Ī¹ĻƒĻ„ĪæĻ… μέρους", + "userIsDisabled": "Ο Ļ‡ĻĪ®ĻƒĻ„Ī·Ļ‚ είναι απενεργοποιημένος, Ī· ĻƒĻĪ½Ī“ĪµĻƒĪ· είναι προς το Ļ€Ī±ĻĻŒĪ½ Ī±Ļ€ĪæĪŗĪ»ĪµĪ¹ĻƒĪ¼Ī­Ī½Ī· με Ī±Ļ…Ļ„ĻŒ το όνομα Ļ‡ĻĪ®ĻƒĻ„Ī·. Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ ĪµĻ€Ī¹ĪŗĪæĪ¹Ī½Ļ‰Ī½Ī®ĻƒĻ„Īµ με τον Ī“Ī¹Ī±Ļ‡ĪµĪ¹ĻĪ¹ĻƒĻ„Ī®.", + "alreadyLoggedIn": "Ī•ĪÆĻƒĻ„Īµ ήΓη ĻƒĻ…Ī½Ī“ĪµĪ“ĪµĪ¼Ī­Ī½ĪæĪ¹ σε", + "alreadyLoggedIn2": "ĻƒĻ…ĻƒĪŗĪµĻ…Ī­Ļ‚. Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ Ī±Ļ€ĪæĻƒĻ…Ī½Ī“ĪµĪøĪµĪÆĻ„Īµ Ī±Ļ€ĻŒ τις ĻƒĻ…ĻƒĪŗĪµĻ…Ī­Ļ‚ και Ļ€ĻĪæĻƒĻ€Ī±ĪøĪ®ĻƒĻ„Īµ ξανά.", + "toManySessions": "ĪˆĻ‡ĪµĻ„Īµ πάρα πολλές ενεργές ĻƒĻ…Ī½ĪµĪ“ĻĪÆĪµĻ‚", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF σε μία σελίΓα", + "header": "PDF σε μία σελίΓα", + "submit": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® σε μία σελίΓα" + }, + "pageExtracter": { + "title": "Εξαγωγή ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "header": "Εξαγωγή ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "submit": "Εξαγωγή", + "placeholder": "(Ļ€.χ. 1,2,8 Ī® 4,7,12-16 Ī® 2n-1)" + }, + "sanitizePDF": { + "title": "Ī•Ī¾Ļ…Ī³ĪÆĪ±Ī½ĻƒĪ· PDF", + "header": "Ī•Ī¾Ļ…Ī³ĪÆĪ±Ī½ĻƒĪ· αρχείου PDF", + "selectText": { + "1": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪµĪ½ĪµĻĪ³ĪµĪ¹ĻŽĪ½ JavaScript", + "2": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪµĪ½ĻƒĻ‰Ī¼Ī±Ļ„Ļ‰Ī¼Ī­Ī½Ļ‰Ī½ αρχείων", + "3": "Remove XMP metadata", + "4": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĻƒĻ…Ī½Ī“Ī­ĻƒĪ¼Ļ‰Ī½", + "5": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· Ī³ĻĪ±Ī¼Ī¼Ī±Ļ„ĪæĻƒĪµĪ¹ĻĻŽĪ½", + "6": "Remove Document Info Metadata" + }, + "submit": "Ī•Ī¾Ļ…Ī³ĪÆĪ±Ī½ĻƒĪ· PDF" + }, + "adjustContrast": { + "title": "Προσαρμογή Ī±Ī½Ļ„ĪÆĪøĪµĻƒĪ·Ļ‚", + "header": "Προσαρμογή Ī±Ī½Ļ„ĪÆĪøĪµĻƒĪ·Ļ‚", + "contrast": "Ī‘Ī½Ļ„ĪÆĪøĪµĻƒĪ·:", + "brightness": "Ī¦Ļ‰Ļ„ĪµĪ¹Ī½ĻŒĻ„Ī·Ļ„Ī±:", + "saturation": "ĪšĪæĻĪµĻƒĪ¼ĻŒĻ‚:", + "download": "Ī›Ī®ĻˆĪ·" + }, + "compress": { + "title": "Ī£Ļ…Ī¼Ļ€ĪÆĪµĻƒĪ·", + "header": "Ī£Ļ…Ī¼Ļ€ĪÆĪµĻƒĪ· PDF", + "credit": "Αυτή Ī· Ļ…Ļ€Ī·ĻĪµĻƒĪÆĪ± Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ qpdf για ĻƒĻ…Ī¼Ļ€ĪÆĪµĻƒĪ·/Ī²ĪµĪ»Ļ„Ī¹ĻƒĻ„ĪæĻ€ĪæĪÆĪ·ĻƒĪ· PDF.", + "grayscale": { + "label": "Εφαρμογή κλίμακας του γκρι για ĻƒĻ…Ī¼Ļ€ĪÆĪµĻƒĪ·" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "ΕπίπεΓο Ī²ĪµĪ»Ļ„Ī¹ĻƒĻ„ĪæĻ€ĪæĪÆĪ·ĻƒĪ·Ļ‚:", + "4": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· λειτουργία - Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· Ļ€ĻĪæĻƒĪ±ĻĪ¼ĪæĪ³Ī® Ļ€ĪæĪ¹ĻŒĻ„Ī·Ļ„Ī±Ļ‚ για επίτευξη Ī±ĪŗĻĪ¹Ī²ĪæĻĻ‚ μεγέθους PDF", + "5": "Ī‘Ī½Ī±Ī¼ĪµĪ½ĻŒĪ¼ĪµĪ½Īæ μέγεθος PDF (Ļ€.χ. 25MB, 10.8MB, 25KB)" + }, + "submit": "Ī£Ļ…Ī¼Ļ€ĪÆĪµĻƒĪ·" + }, + "decrypt": { + "passwordPrompt": "Ī‘Ļ…Ļ„ĻŒ το αρχείο Ļ€ĻĪæĻƒĻ„Ī±Ļ„ĪµĻĪµĻ„Ī±Ī¹ με ĪŗĻ‰Ī“Ī¹ĪŗĻŒ Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ·Ļ‚. Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ ĪµĪ¹ĻƒĪ¬Ī³ĪµĻ„Īµ τον ĪŗĻ‰Ī“Ī¹ĪŗĻŒ:", + "cancelled": "Ī— λειτουργία Ī±ĪŗĻ…ĻĻŽĪøĪ·ĪŗĪµ για το PDF: {0}", + "noPassword": "Δεν Γόθηκε ĪŗĻ‰Ī“Ī¹ĪŗĻŒĻ‚ Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ·Ļ‚ για το κρυπτογραφημένο PDF: {0}", + "invalidPassword": "Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ Ļ€ĻĪæĻƒĻ€Ī±ĪøĪ®ĻƒĻ„Īµ ξανά με τον ĻƒĻ‰ĻƒĻ„ĻŒ ĪŗĻ‰Ī“Ī¹ĪŗĻŒ Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ·Ļ‚.", + "invalidPasswordHeader": "Ī›Ī±Ī½ĪøĪ±ĻƒĪ¼Ī­Ī½ĪæĻ‚ ĪŗĻ‰Ī“Ī¹ĪŗĻŒĻ‚ Ļ€ĻĻŒĻƒĪ²Ī±ĻƒĪ·Ļ‚ Ī® μη Ļ…Ļ€ĪæĻƒĻ„Ī·ĻĪ¹Ī¶ĻŒĪ¼ĪµĪ½Ī· ĪŗĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ¬Ļ†Ī·ĻƒĪ· για το PDF: {0}", + "unexpectedError": "΄πήρξε ĻƒĻ†Ī¬Ī»Ī¼Ī± κατά την ĪµĻ€ĪµĪ¾ĪµĻĪ³Ī±ĻƒĪÆĪ± του αρχείου. Ī Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ Ļ€ĻĪæĻƒĻ€Ī±ĪøĪ®ĻƒĻ„Īµ ξανά.", + "serverError": "Σφάλμα Ī“Ī¹Ī±ĪŗĪæĪ¼Ī¹ĻƒĻ„Ī® κατά την Ī±Ļ€ĪæĪŗĻĻ…Ļ€Ļ„ĪæĪ³ĻĪ¬Ļ†Ī·ĻƒĪ·: {0}", + "success": "Το αρχείο αποκρυπτογραφήθηκε με επιτυχία." + }, + "multiTool-advert": { + "message": "Αυτή Ī· λειτουργία είναι ĪµĻ€ĪÆĻƒĪ·Ļ‚ Γιαθέσιμη ĻƒĻ„Ī· σελίΓα πολυεργαλείου μας. Δείτε την για βελτιωμένο περιβάλλον Ļ‡ĻĪ®ĻƒĻ„Ī· σελίΓα-προς-σελίΓα και επιπλέον λειτουργίες!" + }, + "pageRemover": { + "title": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚", + "header": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ PDF", + "pagesToDelete": "ΣελίΓες προς Γιαγραφή (Ī•Ī¹ĻƒĪ¬Ī³ĪµĻ„Īµ μια Ī»ĪÆĻƒĻ„Ī± Ī±ĻĪ¹ĪøĪ¼ĻŽĪ½ ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½ Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼Ī­Ī½Ī· με ĪŗĻŒĪ¼Ī¼Ī±Ļ„Ī±):", + "submit": "Διαγραφή ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "placeholder": "(Ļ€.χ. 1,2,6 Ī® 1-10,15-30)" + }, + "imageToPDF": { + "title": "Ī•Ī¹ĪŗĻŒĪ½Ī± σε PDF", + "header": "Ī•Ī¹ĪŗĻŒĪ½Ī± σε PDF", + "submit": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī®", + "selectLabel": "Επιλογές Ļ€ĻĪæĻƒĪ±ĻĪ¼ĪæĪ³Ī®Ļ‚ ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "fillPage": "Ī“Ī­Ī¼Ī¹ĻƒĪ¼Ī± ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚", + "fitDocumentToImage": "Προσαρμογή ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚ ĻƒĻ„Ī·Ī½ εικόνα", + "maintainAspectRatio": "Ī”Ī¹Ī±Ļ„Ī®ĻĪ·ĻƒĪ· Ī±Ī½Ī±Ī»ĪæĪ³Ī¹ĻŽĪ½", + "selectText": { + "2": "Ī‘Ļ…Ļ„ĻŒĪ¼Ī±Ļ„Ī· Ļ€ĪµĻĪ¹ĻƒĻ„ĻĪæĻ†Ī® PDF", + "3": "Λογική Ļ€ĪæĪ»Ī»Ī±Ļ€Ī»ĻŽĪ½ αρχείων (Ενεργοποιείται μόνο ĻŒĻ„Ī±Ī½ ĪµĻĪ³Ī¬Ī¶ĪµĻƒĻ„Īµ με πολλαπλές ĪµĪ¹ĪŗĻŒĪ½ĪµĻ‚)", + "4": "Ī£Ļ…Ī³Ļ‡ĻŽĪ½ĪµĻ…ĻƒĪ· σε ένα PDF", + "5": "ĪœĪµĻ„Ī±Ļ„ĻĪæĻ€Ī® σε Ī¾ĪµĻ‡Ļ‰ĻĪ¹ĻƒĻ„Ī¬ PDF" + } + }, + "PDFToCSV": { + "title": "PDF σε CSV", + "header": "PDF σε CSV", + "prompt": "Επιλέξτε σελίΓα για εξαγωγή πίνακα", + "submit": "Εξαγωγή" + }, + "split-by-size-or-count": { + "title": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF ανά μέγεθος Ī® πλήθος", + "header": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF ανά μέγεθος Ī® πλήθος", + "type": { + "label": "Επιλέξτε Ļ„ĻĻ€Īæ Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĪæĻ", + "size": "Ανά μέγεθος", + "pageCount": "Ανά πλήθος ĻƒĪµĪ»ĪÆĪ“Ļ‰Ī½", + "docCount": "Ανά πλήθος εγγράφων" + }, + "value": { + "label": "Ī•Ī¹ĻƒĪ¬Ī³ĪµĻ„Īµ τιμή", + "placeholder": "Ī•Ī¹ĻƒĪ¬Ī³ĪµĻ„Īµ μέγεθος (Ļ€.χ. 2MB Ī® 3KB) Ī® πλήθος (Ļ€.χ. 5)" + }, + "submit": "΄ποβολή" + }, + "printFile": { + "title": "Ī•ĪŗĻ„ĻĻ€Ļ‰ĻƒĪ· αρχείου", + "header": "Ī•ĪŗĻ„ĻĻ€Ļ‰ĻƒĪ· αρχείου σε εκτυπωτή", + "selectText": { + "1": "Επιλέξτε αρχείο προς ĪµĪŗĻ„ĻĻ€Ļ‰ĻƒĪ·", + "2": "Ī•Ī¹ĻƒĪ¬Ī³ĪµĻ„Īµ όνομα εκτυπωτή" + }, + "submit": "Ī•ĪŗĻ„ĻĻ€Ļ‰ĻƒĪ·" + }, + "licenses": { + "nav": "ΆΓειες", + "title": "ΆΓειες τρίτων", + "header": "ΆΓειες τρίτων", + "module": "Ī•Ī½ĻŒĻ„Ī·Ļ„Ī±", + "version": "ΈκΓοση", + "license": "ΆΓεια" + }, + "survey": { + "nav": "ĪˆĻĪµĻ…Ī½Ī±", + "title": "ĪˆĻĪµĻ…Ī½Ī± Stirling-PDF", + "description": "Το Stirling-PDF Γεν έχει Ļ€Ī±ĻĪ±ĪŗĪæĪ»ĪæĻĪøĪ·ĻƒĪ·, ĪæĻ€ĻŒĻ„Īµ θέλουμε να Ī±ĪŗĪæĻĻƒĪæĻ…Ī¼Īµ Ī±Ļ€ĻŒ τους Ļ‡ĻĪ®ĻƒĻ„ĪµĻ‚ μας για να Ī²ĪµĪ»Ļ„Ī¹ĻŽĻƒĪæĻ…Ī¼Īµ το Stirling-PDF!", + "changes": "Το Stirling-PDF έχει αλλάξει Ī±Ļ€ĻŒ την τελευταία έρευνα! Για να μάθετε Ļ€ĪµĻĪ¹ĻƒĻƒĻŒĻ„ĪµĻĪ±, Ļ€Ī±ĻĪ±ĪŗĪ±Ī»ĻŽ ελέγξτε το blog post μας ĪµĪ“ĻŽ:", + "changes2": "Με αυτές τις αλλαγές λαμβάνουμε επαγγελματική Ļ…Ļ€ĪæĻƒĻ„Ī®ĻĪ¹Ī¾Ī· και Ļ‡ĻĪ·Ī¼Ī±Ļ„ĪæĪ“ĻŒĻ„Ī·ĻƒĪ·", + "please": "Ī Ī±ĻĪ±ĪŗĪ±Ī»ĪæĻĪ¼Īµ ĻƒĪŗĪµĻ†Ļ„ĪµĪÆĻ„Īµ να ĻƒĻ…Ī¼Ī¼ĪµĻ„Ī¬ĻƒĻ‡ĪµĻ„Īµ ĻƒĻ„Ī·Ī½ έρευνά μας!", + "disabled": "(Το Ī±Ī½Ī±Ī“Ļ…ĻŒĪ¼ĪµĪ½Īæ παράθυρο έρευνας θα απενεργοποιηθεί ĻƒĻ„Ī¹Ļ‚ ĪµĻ€ĻŒĪ¼ĪµĪ½ĪµĻ‚ ĪµĪ½Ī·Ī¼ĪµĻĻŽĻƒĪµĪ¹Ļ‚ αλλά θα είναι Γιαθέσιμο ĻƒĻ„Īæ Ļ…Ļ€ĪæĻƒĪ­Ī»Ī¹Ī“Īæ της ĻƒĪµĪ»ĪÆĪ“Ī±Ļ‚)", + "button": "Συμμετοχή ĻƒĻ„Ī·Ī½ έρευνα", + "dontShowAgain": "ĪĪ± μην ĪµĪ¼Ļ†Ī±Ī½Ī¹ĻƒĻ„ĪµĪÆ ξανά", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "header": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "removeImage": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "submit": "Ī‘Ļ†Ī±ĪÆĻĪµĻƒĪ· ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚" + }, + "splitByChapters": { + "title": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF ανά κεφάλαια", + "header": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF ανά κεφάλαια", + "bookmarkLevel": "ΕπίπεΓο ĻƒĪµĪ»Ī¹Ī“ĪæĪ“ĪµĪÆĪŗĻ„Ī·", + "includeMetadata": "Ī£Ļ…Ī¼Ļ€ĪµĻĪÆĪ»Ī·ĻˆĪ· μεταΓεΓομένων", + "allowDuplicates": "Επιτρέπονται Ī“Ī¹Ļ€Ī»ĻŒĻ„Ļ…Ļ€Ī±", + "desc": { + "1": "Ī‘Ļ…Ļ„ĻŒ το εργαλείο Γιαχωρίζει ένα αρχείο PDF σε πολλαπλά PDF βάσει της Γομής κεφαλαίων του.", + "2": "ΕπίπεΓο ĻƒĪµĪ»Ī¹Ī“ĪæĪ“ĪµĪÆĪŗĻ„Ī·: Επιλέξτε το επίπεΓο ĻƒĪµĪ»Ī¹Ī“ĪæĪ“ĪµĪ¹ĪŗĻ„ĻŽĪ½ για Ļ‡ĻĪ®ĻƒĪ· ĻƒĻ„Īæ Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒ (0 για Ī±Ī½ĻŽĻ„Ī±Ļ„Īæ επίπεΓο, 1 για Ī“ĪµĻĻ„ĪµĻĪæ επίπεΓο, κλπ.).", + "3": "Ī£Ļ…Ī¼Ļ€ĪµĻĪÆĪ»Ī·ĻˆĪ· μεταΓεΓομένων: Εάν επιλεγεί, τα μεταΓεΓομένα του Ī±ĻĻ‡Ī¹ĪŗĪæĻ PDF θα ĻƒĻ…Ī¼Ļ€ĪµĻĪ¹Ī»Ī·Ļ†ĪøĪæĻĪ½ σε κάθε Ī“Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼Ī­Ī½Īæ PDF.", + "4": "Επιτρέπονται Ī“Ī¹Ļ€Ī»ĻŒĻ„Ļ…Ļ€Ī±: Εάν επιλεγεί, επιτρέπει Ļ€ĪæĪ»Ī»Ī±Ļ€Ī»ĪæĻĻ‚ ĻƒĪµĪ»Ī¹Ī“ĪæĪ“ĪµĪÆĪŗĻ„ĪµĻ‚ ĻƒĻ„Ī·Ī½ ίΓια σελίΓα να Ī“Ī·Ī¼Ī¹ĪæĻ…ĻĪ³Ī®ĻƒĪæĻ…Ī½ Ī¾ĪµĻ‡Ļ‰ĻĪ¹ĻƒĻ„Ī¬ PDF." + }, + "submit": "Ī”Ī¹Ī±Ļ‡Ļ‰ĻĪ¹ĻƒĪ¼ĻŒĻ‚ PDF" + }, + "fileChooser": { + "click": "Κλικ", + "or": "Ī®", + "dragAndDrop": "Ī£ĻĻĪµĻ„Īµ & Ī±Ļ†Ī®ĻƒĻ„Īµ", + "dragAndDropPDF": "Ī£ĻĻĪµĻ„Īµ & Ī±Ļ†Ī®ĻƒĻ„Īµ αρχείο PDF", + "dragAndDropImage": "Ī£ĻĻĪµĻ„Īµ & Ī±Ļ†Ī®ĻƒĻ„Īµ αρχείο ĪµĪ¹ĪŗĻŒĪ½Ī±Ļ‚", + "hoveredDragAndDrop": "Ī£ĻĻĪµĻ„Īµ & Ī±Ļ†Ī®ĻƒĻ„Īµ αρχείο(α) ĪµĪ“ĻŽ", + "extractPDF": "Εξαγωγή..." + }, + "releases": { + "footer": "Ī•ĪŗĪ“ĻŒĻƒĪµĪ¹Ļ‚", + "title": "Ī£Ī·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ Ī­ĪŗĪ“ĪæĻƒĪ·Ļ‚", + "header": "Ī£Ī·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ Ī­ĪŗĪ“ĪæĻƒĪ·Ļ‚", + "current": { + "version": "Ī¤ĻĪ­Ļ‡ĪæĻ…ĻƒĪ± έκΓοση" + }, + "note": "Οι ĻƒĪ·Ī¼ĪµĪ¹ĻŽĻƒĪµĪ¹Ļ‚ Ī­ĪŗĪ“ĪæĻƒĪ·Ļ‚ είναι Ī“Ī¹Ī±ĪøĪ­ĻƒĪ¹Ī¼ĪµĻ‚ μόνο ĻƒĻ„Ī± Αγγλικά" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/en-GB/translation.json b/frontend/public/locales/en-GB/translation.json new file mode 100644 index 000000000..ed3942172 --- /dev/null +++ b/frontend/public/locales/en-GB/translation.json @@ -0,0 +1,1765 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Font Size", + "fontName": "Font Name", + "title": "Add Page Numbers", + "header": "Add Page Numbers", + "selectText": { + "1": "Select PDF file:", + "2": "Margin Size", + "3": "Position", + "4": "Starting Number", + "5": "Pages to Number", + "6": "Custom Text" + }, + "customTextDesc": "Custom Text", + "numberPagesDesc": "Which pages to number, default 'all', also accepts 1-5 or 2,5,9 etc", + "customNumberDesc": "Defaults to {n}, also accepts 'Page {n} of {total}', 'Text-{n}', '{filename}-{n}", + "submit": "Add Page Numbers" + }, + "pdfPrompt": "Select PDF(s)", + "multiPdfPrompt": "Select PDFs (2+)", + "multiPdfDropPrompt": "Select (or drag & drop) all PDFs you require", + "imgPrompt": "Select Image(s)", + "genericSubmit": "Submit", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Warning: This process can take up to a minute depending on file-size", + "pageOrderPrompt": "Custom Page Order (Enter a comma-separated list of page numbers or Functions like 2n+1) :", + "pageSelectionPrompt": "Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :", + "goToPage": "Go", + "true": "True", + "false": "False", + "unknown": "Unknown", + "save": "Save", + "saveToBrowser": "Save to Browser", + "close": "Close", + "filesSelected": "files selected", + "noFavourites": "No favourites added", + "downloadComplete": "Download Complete", + "bored": "Bored Waiting?", + "alphabet": "Alphabet", + "downloadPdf": "Download PDF", + "text": "Text", + "font": "Font", + "selectFillter": "-- Select --", + "pageNum": "Page Number", + "sizes": { + "small": "Small", + "medium": "Medium", + "large": "Large", + "x-large": "X-Large" + }, + "error": { + "pdfPassword": "The PDF Document is passworded and either the password was not provided or was incorrect", + "_value": "Error", + "sorry": "Sorry for the issue!", + "needHelp": "Need help / Found an issue?", + "contactTip": "If you're still having trouble, don't hesitate to reach out to us for help. You can submit a ticket on our GitHub page or contact us through Discord:", + "404": { + "head": "404 - Page Not Found | Oops, we tripped in the code!", + "1": "We can't seem to find the page you're looking for.", + "2": "Something went wrong" + }, + "github": "Submit a ticket on GitHub", + "showStack": "Show Stack Trace", + "copyStack": "Copy Stack Trace", + "githubSubmit": "GitHub - Submit a ticket", + "discordSubmit": "Discord - Submit Support post" + }, + "delete": "Delete", + "username": "Username", + "password": "Password", + "welcome": "Welcome", + "property": "Property", + "black": "Black", + "white": "White", + "red": "Red", + "green": "Green", + "blue": "Blue", + "custom": "Custom...", + "WorkInProgess": "Work in progress, May not work or be buggy, Please report any problems!", + "poweredBy": "Powered by", + "yes": "Yes", + "no": "No", + "changedCredsMessage": "Credentials changed!", + "notAuthenticatedMessage": "User not authenticated.", + "userNotFoundMessage": "User not found.", + "incorrectPasswordMessage": "Current password is incorrect.", + "usernameExistsMessage": "New Username already exists.", + "invalidUsernameMessage": "Invalid username, username can only contain letters, numbers and the following special characters @._+- or must be a valid email address.", + "invalidPasswordMessage": "The password must not be empty and must not have spaces at the beginning or end.", + "confirmPasswordErrorMessage": "New Password and Confirm New Password must match.", + "deleteCurrentUserMessage": "Cannot delete currently logged in user.", + "deleteUsernameExistsMessage": "The username does not exist and cannot be deleted.", + "downgradeCurrentUserMessage": "Cannot downgrade current user's role", + "disabledCurrentUserMessage": "The current user cannot be disabled", + "downgradeCurrentUserLongMessage": "Cannot downgrade current user's role. Hence, current user will not be shown.", + "userAlreadyExistsOAuthMessage": "The user already exists as an OAuth2 user.", + "userAlreadyExistsWebMessage": "The user already exists as an web user.", + "oops": "Oops!", + "help": "Help", + "goHomepage": "Go to Homepage", + "joinDiscord": "Join our Discord server", + "seeDockerHub": "See Docker Hub", + "visitGithub": "Visit Github Repository", + "donate": "Donate", + "color": "Colour", + "sponsor": "Sponsor", + "info": "Info", + "pro": "Pro", + "page": "Page", + "pages": "Pages", + "loading": "Loading...", + "addToDoc": "Add to Document", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Privacy Policy", + "terms": "Terms and Conditions", + "accessibility": "Accessibility", + "cookie": "Cookie Policy", + "impressum": "Impressum", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Pipeline Menu (Beta)", + "uploadButton": "Upload Custom", + "configureButton": "Configure", + "defaultOption": "Custom", + "submitButton": "Submit", + "help": "Pipeline Help", + "scanHelp": "Folder Scanning Help", + "deletePrompt": "Are you sure you want to delete pipeline", + "tags": "automate,sequence,scripted,batch-process", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Pipeline Configuration", + "pipelineNameLabel": "Pipeline Name", + "saveSettings": "Save Operation Settings", + "pipelineNamePrompt": "Enter pipeline name here", + "selectOperation": "Select Operation", + "addOperationButton": "Add operation", + "pipelineHeader": "Pipeline:", + "saveButton": "Download", + "validateButton": "Validate" + }, + "enterpriseEdition": { + "button": "Upgrade to Pro", + "warning": "This feature is only available to Pro users.", + "yamlAdvert": "Stirling PDF Pro supports YAML configuration files and other SSO features.", + "ssoAdvert": "Looking for more user management features? Check out Stirling PDF Pro" + }, + "analytics": { + "title": "Do you want make Stirling PDF better?", + "paragraph1": "Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.", + "paragraph2": "Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.", + "enable": "Enable analytics", + "disable": "Disable analytics", + "settings": "You can change the settings for analytics in the config/settings.yml file" + }, + "navbar": { + "favorite": "Favorites", + "recent": "New and recently updated", + "darkmode": "Dark Mode", + "language": "Languages", + "settings": "Settings", + "allTools": "Tools", + "multiTool": "Multi Tool", + "search": "Search", + "sections": { + "organize": "Organize", + "convertTo": "Convert to PDF", + "convertFrom": "Convert from PDF", + "security": "Sign & Security", + "advance": "Advanced", + "edit": "View & Edit", + "popular": "Popular" + } + }, + "settings": { + "title": "Settings", + "update": "Update available", + "updateAvailable": "{0} is the current installed version. A new version ({1}) is available.", + "appVersion": "App Version:", + "downloadOption": { + "title": "Choose download option (For single file non zip downloads):", + "1": "Open in same window", + "2": "Open in new window", + "3": "Download file" + }, + "zipThreshold": "Zip files when the number of downloaded files exceeds", + "signOut": "Sign Out", + "accountSettings": "Account Settings", + "bored": { + "help": "Enables easter egg game" + }, + "cacheInputs": { + "name": "Save form inputs", + "help": "Enable to store previously used inputs for future runs" + } + }, + "changeCreds": { + "title": "Change Credentials", + "header": "Update Your Account Details", + "changePassword": "You are using default login credentials. Please enter a new password", + "newUsername": "New Username", + "oldPassword": "Current Password", + "newPassword": "New Password", + "confirmNewPassword": "Confirm New Password", + "submit": "Submit Changes" + }, + "account": { + "title": "Account Settings", + "accountSettings": "Account Settings", + "adminSettings": "Admin Settings - View and Add Users", + "userControlSettings": "User Control Settings", + "changeUsername": "Change Username", + "newUsername": "New Username", + "password": "Confirmation Password", + "oldPassword": "Old password", + "newPassword": "New Password", + "changePassword": "Change Password", + "confirmNewPassword": "Confirm New Password", + "signOut": "Sign Out", + "yourApiKey": "Your API Key", + "syncTitle": "Sync browser settings with Account", + "settingsCompare": "Settings Comparison:", + "property": "Property", + "webBrowserSettings": "Web Browser Setting", + "syncToBrowser": "Sync Account -> Browser", + "syncToAccount": "Sync Account <- Browser" + }, + "adminUserSettings": { + "title": "User Control Settings", + "header": "Admin User Control Settings", + "admin": "Admin", + "user": "User", + "addUser": "Add New User", + "deleteUser": "Delete User", + "confirmDeleteUser": "Should the user be deleted?", + "confirmChangeUserStatus": "Should the user be disabled/enabled?", + "usernameInfo": "Username can only contain letters, numbers and the following special characters @._+- or must be a valid email address.", + "roles": "Roles", + "role": "Role", + "actions": "Actions", + "apiUser": "Limited API User", + "extraApiUser": "Additional Limited API User", + "webOnlyUser": "Web Only User", + "demoUser": "Demo User (No custom settings)", + "internalApiUser": "Internal API User", + "forceChange": "Force user to change password on login", + "submit": "Save User", + "changeUserRole": "Change User's Role", + "authenticated": "Authenticated", + "editOwnProfil": "Edit own profile", + "enabledUser": "enabled user", + "disabledUser": "disabled user", + "activeUsers": "Active Users:", + "disabledUsers": "Disabled Users:", + "totalUsers": "Total Users:", + "lastRequest": "Last Request", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Database Import/Export", + "header": "Database Import/Export", + "fileName": "File Name", + "creationDate": "Creation Date", + "fileSize": "File Size", + "deleteBackupFile": "Delete Backup File", + "importBackupFile": "Import Backup File", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Download Backup File", + "info_1": "When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.", + "info_2": "The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.", + "submit": "Import Backup", + "importIntoDatabaseSuccessed": "Import into database successed", + "backupCreated": "Database backup successful", + "fileNotFound": "File not found", + "fileNullOrEmpty": "File must not be null or empty", + "failedImportFile": "Failed to import file", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "Your session has expired. Please refresh the page and try again.", + "refreshPage": "Refresh Page" + }, + "home": { + "desc": "Your locally hosted one-stop-shop for all your PDF needs.", + "searchBar": "Search for features...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "View, annotate, draw, add text or images" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "PDF Multi Tool", + "desc": "Merge, Rotate, Rearrange, Split, and Remove pages" + }, + "merge": { + "title": "Merge", + "desc": "Easily merge multiple PDFs into one." + }, + "split": { + "title": "Split", + "desc": "Split PDFs into multiple documents" + }, + "rotate": { + "title": "Rotate", + "desc": "Easily rotate your PDFs." + }, + "convert": { + "title": "Convert", + "desc": "Convert files between different formats" + }, + "imageToPdf": { + "title": "Image to PDF", + "desc": "Convert a image (PNG, JPEG, GIF) to PDF." + }, + "pdfToImage": { + "title": "PDF to Image", + "desc": "Convert a PDF to a image. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Organise", + "desc": "Remove/Rearrange pages in any order" + }, + "addImage": { + "title": "Add image", + "desc": "Adds a image onto a set location on the PDF" + }, + "watermark": { + "title": "Add Watermark", + "desc": "Add a custom watermark to your PDF document." + }, + "permissions": { + "title": "Change Permissions", + "desc": "Change the permissions of your PDF document" + }, + "removePages": { + "title": "Remove", + "desc": "Delete unwanted pages from your PDF document." + }, + "addPassword": { + "title": "Add Password", + "desc": "Encrypt your PDF document with a password." + }, + "removePassword": { + "title": "Remove Password", + "desc": "Remove password protection from your PDF document." + }, + "compressPdfs": { + "title": "Compress", + "desc": "Compress PDFs to reduce their file size." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Change Metadata", + "desc": "Change/Remove/Add metadata from a PDF document" + }, + "fileToPDF": { + "title": "Convert file to PDF", + "desc": "Convert nearly any file to PDF (DOCX, PNG, XLS, PPT, TXT and more)" + }, + "ocr": { + "title": "OCR / Cleanup scans", + "desc": "Cleanup scans and detects text from images within a PDF and re-adds it as text." + }, + "extractImages": { + "title": "Extract Images", + "desc": "Extracts all images from a PDF and saves them to zip" + }, + "pdfToPDFA": { + "title": "PDF to PDF/A", + "desc": "Convert PDF to PDF/A for long-term storage" + }, + "PDFToWord": { + "title": "PDF to Word", + "desc": "Convert PDF to Word formats (DOC, DOCX and ODT)" + }, + "PDFToPresentation": { + "title": "PDF to Presentation", + "desc": "Convert PDF to Presentation formats (PPT, PPTX and ODP)" + }, + "PDFToText": { + "title": "PDF to RTF (Text)", + "desc": "Convert PDF to Text or RTF format" + }, + "PDFToHTML": { + "title": "PDF to HTML", + "desc": "Convert PDF to HTML format" + }, + "PDFToXML": { + "title": "PDF to XML", + "desc": "Convert PDF to XML format" + }, + "ScannerImageSplit": { + "title": "Detect/Split Scanned photos", + "desc": "Splits multiple photos from within a photo/PDF" + }, + "sign": { + "title": "Sign", + "desc": "Adds signature to PDF by drawing, text or image" + }, + "flatten": { + "title": "Flatten", + "desc": "Remove all interactive elements and forms from a PDF" + }, + "repair": { + "title": "Repair", + "desc": "Tries to repair a corrupt/broken PDF" + }, + "removeBlanks": { + "title": "Remove Blank pages", + "desc": "Detects and removes blank pages from a document" + }, + "removeAnnotations": { + "title": "Remove Annotations", + "desc": "Removes all comments/annotations from a PDF" + }, + "compare": { + "title": "Compare", + "desc": "Compares and shows the differences between 2 PDF Documents" + }, + "certSign": { + "title": "Sign with Certificate", + "desc": "Signs a PDF with a Certificate/Key (PEM/P12)" + }, + "removeCertSign": { + "title": "Remove Certificate Sign", + "desc": "Remove certificate signature from PDF" + }, + "pageLayout": { + "title": "Multi-Page Layout", + "desc": "Merge multiple pages of a PDF document into a single page" + }, + "scalePages": { + "title": "Adjust page size/scale", + "desc": "Change the size/scale of a page and/or its contents." + }, + "pipeline": { + "title": "Pipeline", + "desc": "Run multiple actions on PDFs by defining pipeline scripts" + }, + "add-page-numbers": { + "title": "Add Page Numbers", + "desc": "Add Page numbers throughout a document in a set location" + }, + "auto-rename": { + "title": "Auto Rename PDF File", + "desc": "Auto renames a PDF file based on its detected header" + }, + "adjust-contrast": { + "title": "Adjust Colours/Contrast", + "desc": "Adjust Contrast, Saturation and Brightness of a PDF" + }, + "crop": { + "title": "Crop PDF", + "desc": "Crop a PDF to reduce its size (maintains text!)" + }, + "autoSplitPDF": { + "title": "Auto Split Pages", + "desc": "Auto Split Scanned PDF with physical scanned page splitter QR Code" + }, + "sanitizePdf": { + "title": "Sanitize", + "desc": "Remove scripts and other elements from PDF files" + }, + "URLToPDF": { + "title": "URL/Website To PDF", + "desc": "Converts any http(s)URL to PDF" + }, + "HTMLToPDF": { + "title": "HTML to PDF", + "desc": "Converts any HTML file or zip to PDF" + }, + "MarkdownToPDF": { + "title": "Markdown to PDF", + "desc": "Converts any Markdown file to PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "Get ALL Info on PDF", + "desc": "Grabs any and all information possible on PDFs" + }, + "extractPage": { + "title": "Extract page(s)", + "desc": "Extracts select pages from PDF" + }, + "PdfToSinglePage": { + "title": "PDF to Single Large Page", + "desc": "Merges all PDF pages into one large single page" + }, + "showJS": { + "title": "Show Javascript", + "desc": "Searches and displays any JS injected into a PDF" + }, + "autoRedact": { + "title": "Auto Redact", + "desc": "Auto Redacts(Blacks out) text in a PDF based on input text" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF to CSV", + "desc": "Extracts Tables from a PDF converting it to CSV" + }, + "autoSizeSplitPDF": { + "title": "Auto Split by Size/Count", + "desc": "Split a single PDF into multiple documents based on size, page count, or document count" + }, + "overlay-pdfs": { + "title": "Overlay PDFs", + "desc": "Overlays PDFs on-top of another PDF" + }, + "split-by-sections": { + "title": "Split PDF by Sections", + "desc": "Divide each page of a PDF into smaller horizontal and vertical sections" + }, + "AddStampRequest": { + "title": "Add Stamp to PDF", + "desc": "Add text or add image stamps at set locations" + }, + "removeImagePdf": { + "title": "Remove image", + "desc": "Remove image from PDF to reduce file size" + }, + "splitPdfByChapters": { + "title": "Split PDF by Chapters", + "desc": "Split a PDF into multiple files based on its chapter structure." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "swagger": { + "title": "API Documentation", + "desc": "View API documentation and test endpoints" + }, + "replaceColorPdf": { + "title": "Advanced Colour options", + "desc": "Replace colour for text and background in PDF and invert full colour of pdf to reduce file size" + } + }, + "viewPdf": { + "tags": "view,read,annotate,text,image,highlight,edit", + "title": "View/Edit PDF", + "header": "View PDF" + }, + "multiTool": { + "tags": "Multi Tool,Multi operation,UI,click drag,front end,client side,interactive,intractable,move,delete,migrate,divide", + "title": "PDF Multi Tool", + "header": "PDF Multi Tool", + "uploadPrompts": "File Name", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "selectPages": "Page Select", + "selectedPages": "Selected Pages", + "page": "Page", + "deleteSelected": "Delete Selected", + "downloadAll": "Export", + "downloadSelected": "Export Selected", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "Page(s) Selected", + "undo": "Undo (CTRL + Z)", + "redo": "Redo (CTRL + Y)" + }, + "merge": { + "tags": "merge,Page operations,Back end,server side", + "title": "Merge", + "header": "Merge multiple PDFs (2+)", + "sortByName": "Sort by name", + "sortByDate": "Sort by date", + "removeCertSign": "Remove digital signature in the merged file?", + "submit": "Merge" + }, + "split": { + "tags": "Page operations,divide,Multi Page,cut,server side", + "title": "Split PDF", + "header": "Split PDF", + "desc": { + "1": "The numbers you select are the page number you wish to do a split on", + "2": "As such selecting 1,3,7-9 would split a 10 page document into 6 separate PDFS with:", + "3": "Document #1: Page 1", + "4": "Document #2: Page 2 and 3", + "5": "Document #3: Page 4, 5, 6 and 7", + "6": "Document #4: Page 8", + "7": "Document #5: Page 9", + "8": "Document #6: Page 10" + }, + "splitPages": "Enter pages to split on:", + "submit": "Split" + }, + "rotate": { + "tags": "server side", + "title": "Rotate PDF", + "header": "Rotate PDF", + "selectAngle": "Select rotation angle (in multiples of 90 degrees):", + "submit": "Rotate" + }, + "convert": { + "title": "Convert", + "desc": "Convert files between different formats", + "files": "Files", + "selectFilesPlaceholder": "Select files in the main view to get started", + "settings": "Settings", + "conversionCompleted": "Conversion completed", + "results": "Results", + "defaultFilename": "converted_file", + "conversionResults": "Conversion Results", + "convertFrom": "Convert from", + "convertTo": "Convert to", + "sourceFormatPlaceholder": "Source format", + "targetFormatPlaceholder": "Target format", + "selectSourceFormatFirst": "Select a source format first", + "outputOptions": "Output Options", + "pdfOptions": "PDF Options", + "imageOptions": "Image Options", + "colorType": "Colour Type", + "color": "Colour", + "greyscale": "Greyscale", + "blackwhite": "Black & White", + "dpi": "DPI", + "output": "Output", + "single": "Single", + "multiple": "Multiple", + "fitOption": "Fit Option", + "maintainAspectRatio": "Maintain Aspect Ratio", + "fitDocumentToPage": "Fit Document to Page", + "fillPage": "Fill Page", + "autoRotate": "Auto Rotate", + "autoRotateDescription": "Automatically rotate images to better fit the PDF page", + "combineImages": "Combine Images", + "combineImagesDescription": "Combine all images into one PDF, or create separate PDFs for each image", + "webOptions": "Web to PDF Options", + "zoomLevel": "Zoom Level", + "emailOptions": "Email to PDF Options", + "includeAttachments": "Include email attachments", + "maxAttachmentSize": "Maximum attachment size (MB)", + "includeAllRecipients": "Include CC and BCC recipients in header", + "downloadHtml": "Download HTML intermediate file instead of PDF", + "pdfaOptions": "PDF/A Options", + "outputFormat": "Output Format", + "pdfaNote": "PDF/A-1b is more compatible, PDF/A-2b supports more features.", + "pdfaDigitalSignatureWarning": "The PDF contains a digital signature. This will be removed in the next step.", + "fileFormat": "File Format", + "wordDoc": "Word Document", + "wordDocExt": "Word Document (.docx)", + "odtExt": "OpenDocument Text (.odt)", + "pptExt": "PowerPoint (.pptx)", + "odpExt": "OpenDocument Presentation (.odp)", + "txtExt": "Plain Text (.txt)", + "rtfExt": "Rich Text Format (.rtf)", + "selectedFiles": "Selected files", + "noFileSelected": "No file selected. Use the file panel to add files.", + "convertFiles": "Convert Files", + "converting": "Converting...", + "downloadConverted": "Download Converted File", + "errorNoFiles": "Please select at least one file to convert.", + "errorNoFormat": "Please select both source and target formats.", + "errorNotSupported": "Conversion from {{from}} to {{to}} is not supported.", + "images": "Images", + "officeDocs": "Office Documents (Word, Excel, PowerPoint)", + "imagesExt": "Images (JPG, PNG, etc.)", + "markdown": "Markdown", + "textRtf": "Text/RTF" + }, + "imageToPdf": { + "tags": "conversion,img,jpg,picture,photo" + }, + "pdfToImage": { + "tags": "conversion,img,jpg,picture,photo", + "title": "PDF to Image", + "header": "PDF to Image", + "selectText": "Image Format", + "singleOrMultiple": "Page to Image result type", + "single": "Single Big Image Combing all pages", + "multi": "Multiple Images, one image per page", + "colorType": "Colour type", + "color": "Colour", + "grey": "Greyscale", + "blackwhite": "Black and White (May lose data!)", + "submit": "Convert", + "info": "Python is not installed. Required for WebP conversion.", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,even,odd,sort,move", + "title": "Page Organiser", + "header": "PDF Page Organiser", + "submit": "Rearrange Pages", + "mode": { + "_value": "Mode", + "1": "Custom Page Order", + "2": "Reverse Order", + "3": "Duplex Sort", + "4": "Booklet Sort", + "5": "Side Stitch Booklet Sort", + "6": "Odd-Even Split", + "7": "Remove First", + "8": "Remove Last", + "9": "Remove First and Last", + "10": "Odd-Even Merge", + "11": "Duplicate all pages" + }, + "placeholder": "(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)" + }, + "addImage": { + "tags": "img,jpg,picture,photo", + "title": "Add Image", + "header": "Add image to PDF", + "everyPage": "Every Page?", + "upload": "Add image", + "submit": "Add image" + }, + "watermark": { + "tags": "Text,repeating,label,own,copyright,trademark,img,jpg,picture,photo", + "title": "Add Watermark", + "header": "Add Watermark", + "customColor": "Custom Text Colour", + "selectText": { + "1": "Select PDF to add watermark to:", + "2": "Watermark Text:", + "3": "Font Size:", + "4": "Rotation (0-360):", + "5": "Width Spacer (Space between each watermark horizontally):", + "6": "Height Spacer (Space between each watermark vertically):", + "7": "Opacity (0% - 100%):", + "8": "Watermark Type:", + "9": "Watermark Image:", + "10": "Convert PDF to PDF-Image" + }, + "submit": "Add Watermark", + "type": { + "1": "Text", + "2": "Image" + } + }, + "permissions": { + "tags": "read,write,edit,print", + "title": "Change Permissions", + "header": "Change Permissions", + "warning": "Warning to have these permissions be unchangeable it is recommended to set them with a password via the add-password page", + "selectText": { + "1": "Select PDF to change permissions", + "2": "Permissions to set", + "3": "Prevent assembly of document", + "4": "Prevent content extraction", + "5": "Prevent extraction for accessibility", + "6": "Prevent filling in form", + "7": "Prevent modification", + "8": "Prevent annotation modification", + "9": "Prevent printing", + "10": "Prevent printing different formats" + }, + "submit": "Change" + }, + "removePages": { + "tags": "Remove pages,delete pages" + }, + "addPassword": { + "tags": "secure,security", + "title": "Add Password", + "header": "Add password (Encrypt)", + "selectText": { + "1": "Select PDF to encrypt", + "2": "User Password", + "3": "Encryption Key Length", + "4": "Higher values are stronger, but lower values have better compatibility.", + "5": "Permissions to set (Recommended to be used along with Owner password)", + "6": "Prevent assembly of document", + "7": "Prevent content extraction", + "8": "Prevent extraction for accessibility", + "9": "Prevent filling in form", + "10": "Prevent modification", + "11": "Prevent annotation modification", + "12": "Prevent printing", + "13": "Prevent printing different formats", + "14": "Owner Password", + "15": "Restricts what can be done with the document once it is opened (Not supported by all readers)", + "16": "Restricts the opening of the document itself" + }, + "submit": "Encrypt" + }, + "removePassword": { + "tags": "secure,Decrypt,security,unpassword,delete password", + "title": "Remove password", + "header": "Remove password (Decrypt)", + "selectText": { + "1": "Select PDF to Decrypt", + "2": "Password" + }, + "submit": "Remove" + }, + "compressPdfs": { + "tags": "squish,small,tiny" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Title,author,date,creation,time,publisher,producer,stats", + "title": "Change Metadata", + "header": "Change Metadata", + "selectText": { + "1": "Please edit the variables you wish to change", + "2": "Delete all metadata", + "3": "Show Custom Metadata:", + "4": "Other Metadata:", + "5": "Add Custom Metadata Entry" + }, + "author": "Author:", + "creationDate": "Creation Date (yyyy/MM/dd HH:mm:ss):", + "creator": "Creator:", + "keywords": "Keywords:", + "modDate": "Modification Date (yyyy/MM/dd HH:mm:ss):", + "producer": "Producer:", + "subject": "Subject:", + "trapped": "Trapped:", + "submit": "Change" + }, + "fileToPDF": { + "tags": "transformation,format,document,picture,slide,text,conversion,office,docs,word,excel,powerpoint", + "title": "File to PDF", + "header": "Convert any file to PDF", + "credit": "This service uses LibreOffice and Unoconv for file conversion.", + "supportedFileTypesInfo": "Supported File types", + "supportedFileTypes": "Supported file types should include the below however for a full updated list of supported formats, please refer to the LibreOffice documentation", + "submit": "Convert to PDF" + }, + "ocr": { + "tags": "recognition,text,image,scan,read,identify,detection,editable", + "title": "OCR / Scan Cleanup", + "header": "Cleanup Scans / OCR (Optical Character Recognition)", + "selectText": { + "1": "Select languages that are to be detected within the PDF (Ones listed are the ones currently detected):", + "2": "Produce text file containing OCR text alongside the OCR'ed PDF", + "3": "Correct pages were scanned at a skewed angle by rotating them back into place", + "4": "Clean page so its less likely that OCR will find text in background noise. (No output change)", + "5": "Clean page so its less likely that OCR will find text in background noise, maintains cleanup in output.", + "6": "Ignores pages that have interactive text on them, only OCRs pages that are images", + "7": "Force OCR, will OCR Every page removing all original text elements", + "8": "Normal (Will error if PDF contains text)", + "9": "Additional Settings", + "10": "OCR Mode", + "11": "Remove images after OCR (Removes ALL images, only useful if part of conversion step)", + "12": "Render Type (Advanced)" + }, + "help": "Please read this documentation on how to use this for other languages and/or use not in docker", + "credit": "This service uses qpdf and Tesseract for OCR.", + "submit": "Process PDF with OCR" + }, + "extractImages": { + "tags": "picture,photo,save,archive,zip,capture,grab", + "title": "Extract Images", + "header": "Extract Images", + "selectText": "Select image format to convert extracted images to", + "allowDuplicates": "Save duplicate images", + "submit": "Extract" + }, + "pdfToPDFA": { + "tags": "archive,long-term,standard,conversion,storage,preservation", + "title": "PDF To PDF/A", + "header": "PDF To PDF/A", + "credit": "This service uses libreoffice for PDF/A conversion", + "submit": "Convert", + "tip": "Currently does not work for multiple inputs at once", + "outputFormat": "Output format", + "pdfWithDigitalSignature": "The PDF contains a digital signature. This will be removed in the next step." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformation,format,conversion,office,microsoft,docfile", + "title": "PDF to Word", + "header": "PDF to Word", + "selectText": { + "1": "Output file format" + }, + "credit": "This service uses LibreOffice for file conversion.", + "submit": "Convert" + }, + "PDFToPresentation": { + "tags": "slides,show,office,microsoft", + "title": "PDF to Presentation", + "header": "PDF to Presentation", + "selectText": { + "1": "Output file format" + }, + "credit": "This service uses LibreOffice for file conversion.", + "submit": "Convert" + }, + "PDFToText": { + "tags": "richformat,richtextformat,rich text format", + "title": "PDF to RTF (Text)", + "header": "PDF to RTF (Text)", + "selectText": { + "1": "Output file format" + }, + "credit": "This service uses LibreOffice for file conversion.", + "submit": "Convert" + }, + "PDFToHTML": { + "tags": "web content,browser friendly", + "title": "PDF to HTML", + "header": "PDF to HTML", + "credit": "This service uses pdftohtml for file conversion.", + "submit": "Convert" + }, + "PDFToXML": { + "tags": "data-extraction,structured-content,interop,transformation,convert", + "title": "PDF to XML", + "header": "PDF to XML", + "credit": "This service uses LibreOffice for file conversion.", + "submit": "Convert" + }, + "ScannerImageSplit": { + "tags": "separate,auto-detect,scans,multi-photo,organize", + "selectText": { + "1": "Angle Threshold:", + "2": "Sets the minimum absolute angle required for the image to be rotated (default: 10).", + "3": "Tolerance:", + "4": "Determines the range of colour variation around the estimated background colour (default: 30).", + "5": "Minimum Area:", + "6": "Sets the minimum area threshold for a photo (default: 10000).", + "7": "Minimum Contour Area:", + "8": "Sets the minimum contour area threshold for a photo", + "9": "Border Size:", + "10": "Sets the size of the border added and removed to prevent white borders in the output (default: 1)." + }, + "info": "Python is not installed. It is required to run." + }, + "sign": { + "tags": "authorize,initials,drawn-signature,text-sign,image-signature", + "title": "Sign", + "header": "Sign PDFs", + "upload": "Upload Image", + "draw": "Draw Signature", + "text": "Text Input", + "clear": "Clear", + "add": "Add", + "saved": "Saved Signatures", + "save": "Save Signature", + "personalSigs": "Personal Signatures", + "sharedSigs": "Shared Signatures", + "noSavedSigs": "No saved signatures found", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "static,deactivate,non-interactive,streamline", + "title": "Flatten", + "header": "Flatten PDF", + "flattenOnlyForms": "Flatten only forms", + "submit": "Flatten" + }, + "repair": { + "tags": "fix,restore,correction,recover", + "title": "Repair", + "header": "Repair PDFs", + "submit": "Repair" + }, + "removeBlanks": { + "tags": "cleanup,streamline,non-content,organize", + "title": "Remove Blanks", + "header": "Remove Blank Pages", + "threshold": "Pixel Whiteness Threshold:", + "thresholdDesc": "Threshold for determining how white a white pixel must be to be classed as 'White'. 0 = Black, 255 pure white.", + "whitePercent": "White Percent (%):", + "whitePercentDesc": "Percent of page that must be 'white' pixels to be removed", + "submit": "Remove Blanks" + }, + "removeAnnotations": { + "tags": "comments,highlight,notes,markup,remove", + "title": "Remove Annotations", + "header": "Remove Annotations", + "submit": "Remove" + }, + "compare": { + "tags": "differentiate,contrast,changes,analysis", + "title": "Compare", + "header": "Compare PDFs", + "highlightColor": { + "1": "Highlight Colour 1:", + "2": "Highlight Colour 2:" + }, + "document": { + "1": "Document 1", + "2": "Document 2" + }, + "submit": "Compare", + "complex": { + "message": "One or both of the provided documents are large files, accuracy of comparison may be reduced" + }, + "large": { + "file": { + "message": "One or Both of the provided documents are too large to process" + } + }, + "no": { + "text": { + "message": "One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison." + } + } + }, + "certSign": { + "tags": "authenticate,PEM,P12,official,encrypt", + "title": "Certificate Signing", + "header": "Sign a PDF with your certificate (Work in progress)", + "selectPDF": "Select a PDF File for Signing:", + "jksNote": "Note: If your certificate type is not listed below, please convert it to a Java Keystore (.jks) file using the keytool command line tool. Then, choose the .jks file option below.", + "selectKey": "Select Your Private Key File (PKCS#8 format, could be .pem or .der):", + "selectCert": "Select Your Certificate File (X.509 format, could be .pem or .der):", + "selectP12": "Select Your PKCS#12 Keystore File (.p12 or .pfx) (Optional, If provided, it should contain your private key and certificate):", + "selectJKS": "Select Your Java Keystore File (.jks or .keystore):", + "certType": "Certificate Type", + "password": "Enter Your Keystore or Private Key Password (If Any):", + "showSig": "Show Signature", + "reason": "Reason", + "location": "Location", + "name": "Name", + "showLogo": "Show Logo", + "submit": "Sign PDF" + }, + "removeCertSign": { + "tags": "authenticate,PEM,P12,official,decrypt", + "title": "Remove Certificate Signature", + "header": "Remove the digital certificate from the PDF", + "selectPDF": "Select a PDF file:", + "submit": "Remove Signature" + }, + "pageLayout": { + "tags": "merge,composite,single-view,organize", + "title": "Multi Page Layout", + "header": "Multi Page Layout", + "pagesPerSheet": "Pages per sheet:", + "addBorder": "Add Borders", + "submit": "Submit" + }, + "scalePages": { + "tags": "resize,modify,dimension,adapt", + "title": "Adjust page-scale", + "header": "Adjust page-scale", + "pageSize": "Size of a page of the document.", + "keepPageSize": "Original Size", + "scaleFactor": "Zoom level (crop) of a page.", + "submit": "Submit" + }, + "add-page-numbers": { + "tags": "paginate,label,organize,index" + }, + "auto-rename": { + "tags": "auto-detect,header-based,organize,relabel", + "title": "Auto Rename", + "header": "Auto Rename PDF", + "submit": "Auto Rename" + }, + "adjust-contrast": { + "tags": "color-correction,tune,modify,enhance,colour-correction" + }, + "crop": { + "tags": "trim,shrink,edit,shape", + "title": "Crop", + "header": "Crop PDF", + "submit": "Submit" + }, + "autoSplitPDF": { + "tags": "QR-based,separate,scan-segment,organize", + "title": "Auto Split PDF", + "header": "Auto Split PDF", + "description": "Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.", + "selectText": { + "1": "Print out some divider sheets from below (Black and white is fine).", + "2": "Scan all your documents at once by inserting the divider sheet between them.", + "3": "Upload the single large scanned PDF file and let Stirling PDF handle the rest.", + "4": "Divider pages are automatically detected and removed, guaranteeing a neat final document." + }, + "formPrompt": "Submit PDF containing Stirling-PDF Page dividers:", + "duplexMode": "Duplex Mode (Front and back scanning)", + "dividerDownload2": "Download 'Auto Splitter Divider (with instructions).pdf'", + "submit": "Submit" + }, + "sanitizePdf": { + "tags": "clean,secure,safe,remove-threats" + }, + "URLToPDF": { + "tags": "web-capture,save-page,web-to-doc,archive", + "title": "URL To PDF", + "header": "URL To PDF", + "submit": "Convert", + "credit": "Uses WeasyPrint" + }, + "HTMLToPDF": { + "tags": "markup,web-content,transformation,convert", + "title": "HTML To PDF", + "header": "HTML To PDF", + "help": "Accepts HTML files and ZIPs containing html/css/images etc required", + "submit": "Convert", + "credit": "Uses WeasyPrint", + "zoom": "Zoom level for displaying the website.", + "pageWidth": "Width of the page in centimeters. (Blank to default)", + "pageHeight": "Height of the page in centimeters. (Blank to default)", + "marginTop": "Top margin of the page in millimeters. (Blank to default)", + "marginBottom": "Bottom margin of the page in millimeters. (Blank to default)", + "marginLeft": "Left margin of the page in millimeters. (Blank to default)", + "marginRight": "Right margin of the page in millimeters. (Blank to default)", + "printBackground": "Render the background of websites.", + "defaultHeader": "Enable Default Header (Name and page number)", + "cssMediaType": "Change the CSS media type of the page.", + "none": "None", + "print": "Print", + "screen": "Screen" + }, + "MarkdownToPDF": { + "tags": "markup,web-content,transformation,convert,md", + "title": "Markdown To PDF", + "header": "Markdown To PDF", + "submit": "Convert", + "help": "Work in progress", + "credit": "Uses WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "infomation,data,stats,statistics", + "title": "Get Info on PDF", + "header": "Get Info on PDF", + "submit": "Get Info", + "downloadJson": "Download JSON" + }, + "extractPage": { + "tags": "extract" + }, + "PdfToSinglePage": { + "tags": "single page" + }, + "showJS": { + "tags": "JS", + "title": "Show Javascript", + "header": "Show Javascript", + "downloadJS": "Download Javascript", + "submit": "Show" + }, + "autoRedact": { + "tags": "Redact,Hide,black out,black,marker,hidden", + "title": "Auto Redact", + "header": "Auto Redact", + "colorLabel": "Colour", + "textsToRedactLabel": "Text to Redact (line-separated)", + "textsToRedactPlaceholder": "e.g. \\nConfidential \\nTop-Secret", + "useRegexLabel": "Use Regex", + "wholeWordSearchLabel": "Whole Word Search", + "customPaddingLabel": "Custom Extra Padding", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "submitButton": "Submit" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,Table Extraction,extract,convert" + }, + "autoSizeSplitPDF": { + "tags": "pdf,split,document,organization" + }, + "overlay-pdfs": { + "tags": "Overlay", + "header": "Overlay PDF Files", + "baseFile": { + "label": "Select Base PDF File" + }, + "overlayFiles": { + "label": "Select Overlay PDF Files" + }, + "mode": { + "label": "Select Overlay Mode", + "sequential": "Sequential Overlay", + "interleaved": "Interleaved Overlay", + "fixedRepeat": "Fixed Repeat Overlay" + }, + "counts": { + "label": "Overlay Counts (for Fixed Repeat Mode)", + "placeholder": "Enter comma-separated counts (e.g., 2,3,1)" + }, + "position": { + "label": "Select Overlay Position", + "foreground": "Foreground", + "background": "Background" + }, + "submit": "Submit" + }, + "split-by-sections": { + "tags": "Section Split, Divide, Customize,Customise", + "title": "Split PDF by Sections", + "header": "Split PDF into Sections", + "horizontal": { + "label": "Horizontal Divisions", + "placeholder": "Enter number of horizontal divisions" + }, + "vertical": { + "label": "Vertical Divisions", + "placeholder": "Enter number of vertical divisions" + }, + "submit": "Split PDF", + "merge": "Merge Into One PDF" + }, + "AddStampRequest": { + "tags": "Stamp, Add image, center image, Watermark, PDF, Embed, Customize,Customise", + "header": "Stamp PDF", + "title": "Stamp PDF", + "stampType": "Stamp Type", + "stampText": "Stamp Text", + "stampImage": "Stamp Image", + "alphabet": "Alphabet", + "fontSize": "Font/Image Size", + "rotation": "Rotation", + "opacity": "Opacity", + "position": "Position", + "overrideX": "Override X Coordinate", + "overrideY": "Override Y Coordinate", + "customMargin": "Custom Margin", + "customColor": "Custom Text Colour", + "submit": "Submit" + }, + "removeImagePdf": { + "tags": "Remove Image,Page operations,Back end,server side" + }, + "splitPdfByChapters": { + "tags": "split,chapters,bookmarks,organize" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Advanced Colour options", + "header": "Replace-Invert Colour PDF", + "selectText": { + "1": "Replace or Invert colour Options", + "2": "Default(Default high contrast colours)", + "3": "Custom(Customised colours)", + "4": "Full-Invert(Invert all colours)", + "5": "High contrast colour options", + "6": "white text on black background", + "7": "Black text on white background", + "8": "Yellow text on black background", + "9": "Green text on black background", + "10": "Choose text Colour", + "11": "Choose background Colour" + }, + "submit": "Replace" + }, + "replaceColorPdf": { + "tags": "Replace Colour,Page operations,Back end,server side" + }, + "login": { + "title": "Sign in", + "header": "Sign in", + "signin": "Sign in", + "rememberme": "Remember me", + "invalid": "Invalid username or password.", + "locked": "Your account has been locked.", + "signinTitle": "Please sign in", + "ssoSignIn": "Login via Single Sign-on", + "oAuth2AutoCreateDisabled": "OAUTH2 Auto-Create User Disabled", + "oAuth2AdminBlockedUser": "Registration or logging in of non-registered users is currently blocked. Please contact the administrator.", + "oauth2RequestNotFound": "Authorization request not found", + "oauth2InvalidUserInfoResponse": "Invalid User Info Response", + "oauth2invalidRequest": "Invalid Request", + "oauth2AccessDenied": "Access Denied", + "oauth2InvalidTokenResponse": "Invalid Token Response", + "oauth2InvalidIdToken": "Invalid Id Token", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "User is deactivated, login is currently blocked with this username. Please contact the administrator.", + "alreadyLoggedIn": "You are already logged in to", + "alreadyLoggedIn2": "devices. Please log out of the devices and try again.", + "toManySessions": "You have too many active sessions", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF To Single Page", + "header": "PDF To Single Page", + "submit": "Convert To Single Page" + }, + "pageExtracter": { + "title": "Extract Pages", + "header": "Extract Pages", + "submit": "Extract", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "sanitizePDF": { + "title": "Sanitize PDF", + "header": "Sanitize a PDF file", + "selectText": { + "1": "Remove JavaScript actions", + "2": "Remove embedded files", + "3": "Remove XMP metadata", + "4": "Remove links", + "5": "Remove fonts", + "6": "Remove Document Info Metadata" + }, + "submit": "Sanitize PDF" + }, + "adjustContrast": { + "title": "Adjust Contrast", + "header": "Adjust Contrast", + "contrast": "Contrast:", + "brightness": "Brightness:", + "saturation": "Saturation:", + "download": "Download" + }, + "compress": { + "title": "Compress", + "header": "Compress PDF", + "credit": "This service uses qpdf for PDF Compress/Optimisation.", + "grayscale": { + "label": "Apply Grayscale for Compression" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Optimisation level:", + "4": "Auto mode - Auto adjusts quality to get PDF to exact size", + "5": "Expected PDF Size (e.g. 25MB, 10.8MB, 25KB)" + }, + "submit": "Compress" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "Page Remover", + "header": "PDF Page remover", + "pagesToDelete": "Pages to delete (Enter a comma-separated list of page numbers) :", + "submit": "Delete Pages", + "placeholder": "(e.g. 1,2,6 or 1-10,15-30)" + }, + "imageToPDF": { + "title": "Image to PDF", + "header": "Image to PDF", + "submit": "Convert", + "selectLabel": "Image Fit Options", + "fillPage": "Fill Page", + "fitDocumentToImage": "Fit Page to Image", + "maintainAspectRatio": "Maintain Aspect Ratios", + "selectText": { + "2": "Auto rotate PDF", + "3": "Multi file logic (Only enabled if working with multiple images)", + "4": "Merge into single PDF", + "5": "Convert to separate PDFs" + } + }, + "PDFToCSV": { + "title": "PDF to CSV", + "header": "PDF to CSV", + "prompt": "Choose page to extract table", + "submit": "Extract" + }, + "split-by-size-or-count": { + "title": "Split PDF by Size or Count", + "header": "Split PDF by Size or Count", + "type": { + "label": "Select Split Type", + "size": "By Size", + "pageCount": "By Page Count", + "docCount": "By Document Count" + }, + "value": { + "label": "Enter Value", + "placeholder": "Enter size (e.g., 2MB or 3KB) or count (e.g., 5)" + }, + "submit": "Submit" + }, + "printFile": { + "title": "Print File", + "header": "Print File to Printer", + "selectText": { + "1": "Select File to Print", + "2": "Enter Printer Name" + }, + "submit": "Print" + }, + "licenses": { + "nav": "Licences", + "title": "3rd Party Licences", + "header": "3rd Party Licences", + "module": "Module", + "version": "Version", + "license": "Licence" + }, + "survey": { + "nav": "Survey", + "title": "Stirling-PDF Survey", + "description": "Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!", + "changes": "Stirling-PDF has changed since the last survey! To find out more please check our blog post here:", + "changes2": "With these changes we are getting paid business support and funding", + "please": "Please consider taking our survey to have input on the future of Stirling-PDF!", + "disabled": "(Survey popup will be disabled in following updates but available at foot of page)", + "button": "Take Survey", + "dontShowAgain": "Don't show again", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Remove image", + "header": "Remove image", + "removeImage": "Remove image", + "submit": "Remove image" + }, + "splitByChapters": { + "title": "Split PDF by Chapters", + "header": "Split PDF by Chapters", + "bookmarkLevel": "Bookmark Level", + "includeMetadata": "Include Metadata", + "allowDuplicates": "Allow Duplicates", + "desc": { + "1": "This tool splits a PDF file into multiple PDFs based on its chapter structure.", + "2": "Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).", + "3": "Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.", + "4": "Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs." + }, + "submit": "Split PDF" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Releases", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Current Release" + }, + "note": "Release notes are only available in English" + }, + "swagger": { + "title": "API Documentation", + "header": "API Documentation", + "desc": "View and test the Stirling PDF API endpoints", + "tags": "api,documentation,swagger,endpoints,development" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + }, + "removeMetadata": { + "submit": "Remove Metadata" + }, + "sidebar": { + "toggle": "Toggle Sidebar" + }, + "theme": { + "toggle": "Toggle Theme" + }, + "view": { + "viewer": "Viewer", + "pageEditor": "Page Editor", + "fileManager": "File Manager" + }, + "pageEditor": { + "title": "Page Editor", + "save": "Save Changes", + "noPdfLoaded": "No PDF loaded. Please upload a PDF to edit.", + "rotatedLeft": "Rotated left:", + "rotatedRight": "Rotated right:", + "deleted": "Deleted:", + "movedLeft": "Moved left:", + "movedRight": "Moved right:", + "splitAt": "Split at:", + "insertedPageBreak": "Inserted page break at:", + "addFileNotImplemented": "Add file not implemented in demo", + "closePdf": "Close PDF", + "reset": "Reset Changes", + "zoomIn": "Zoom In", + "zoomOut": "Zoom Out", + "fitToWidth": "Fit to Width", + "actualSize": "Actual Size" + }, + "viewer": { + "noPdfLoaded": "No PDF loaded. Click to upload a PDF.", + "choosePdf": "Choose PDF", + "noPagesToDisplay": "No pages to display.", + "singlePageView": "Single Page View", + "dualPageView": "Dual Page View", + "hideSidebars": "Hide Sidebars", + "showSidebars": "Show Sidebars", + "zoomOut": "Zoom out", + "zoomIn": "Zoom in", + "previousPage": "Previous Page", + "nextPage": "Next Page", + "pageNavigation": "Page Navigation", + "currentPage": "Current Page", + "totalPages": "Total Pages" + }, + "toolPicker": { + "searchPlaceholder": "Search tools...", + "noToolsFound": "No tools found" + }, + "fileUpload": { + "selectFile": "Select a file", + "selectFiles": "Select files", + "selectPdfToView": "Select a PDF to view", + "selectPdfToEdit": "Select a PDF to edit", + "chooseFromStorage": "Choose a file from storage or upload a new PDF", + "chooseFromStorageMultiple": "Choose files from storage or upload new PDFs", + "loadFromStorage": "Load from Storage", + "filesAvailable": "files available", + "loading": "Loading...", + "or": "or", + "dropFileHere": "Drop file here or click to upload", + "dropFilesHere": "Drop files here or click to upload", + "pdfFilesOnly": "PDF files only", + "supportedFileTypes": "Supported file types", + "uploadFile": "Upload File", + "uploadFiles": "Upload Files", + "noFilesInStorage": "No files available in storage. Upload some files first.", + "selectFromStorage": "Select from Storage", + "backToTools": "Back to Tools" + }, + "fileManager": { + "title": "Upload PDF Files", + "subtitle": "Add files to your storage for easy access across tools", + "filesSelected": "files selected", + "clearSelection": "Clear Selection", + "openInFileEditor": "Open in File Editor", + "uploadError": "Failed to upload some files.", + "failedToOpen": "Failed to open file. It may have been removed from storage.", + "failedToLoad": "Failed to load file to active set.", + "storageCleared": "Browser cleared storage. Files have been removed. Please re-upload.", + "clearAll": "Clear All", + "reloadFiles": "Reload Files", + "dragDrop": "Drag & Drop files here", + "clickToUpload": "Click to upload files", + "selectedFiles": "Selected Files", + "storage": "Storage", + "filesStored": "files stored", + "storageError": "Storage error occurred", + "storageLow": "Storage is running low. Consider removing old files.", + "supportMessage": "Powered by browser database storage for unlimited capacity", + "noFileSelected": "No files selected", + "searchFiles": "Search files...", + "recent": "Recent", + "localFiles": "Local Files", + "googleDrive": "Google Drive", + "googleDriveShort": "Drive", + "myFiles": "My Files", + "noRecentFiles": "No recent files found", + "dropFilesHint": "Drop files here to upload", + "googleDriveNotAvailable": "Google Drive integration not available", + "openFiles": "Open Files", + "openFile": "Open File", + "details": "File Details", + "fileName": "Name", + "fileFormat": "Format", + "fileSize": "Size", + "fileVersion": "Version", + "totalSelected": "Total Selected", + "dropFilesHere": "Drop files here" + }, + "storage": { + "temporaryNotice": "Files are stored temporarily in your browser and may be cleared automatically", + "storageLimit": "Storage limit", + "storageUsed": "Temporary Storage used", + "storageFull": "Storage is nearly full. Consider removing some files.", + "fileTooLarge": "File too large. Maximum size per file is", + "storageQuotaExceeded": "Storage quota exceeded. Please remove some files before uploading more.", + "approximateSize": "Approximate size" + } +} \ No newline at end of file diff --git a/frontend/public/locales/en-US/translation.json b/frontend/public/locales/en-US/translation.json new file mode 100644 index 000000000..56279f8b4 --- /dev/null +++ b/frontend/public/locales/en-US/translation.json @@ -0,0 +1,1617 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Font Size", + "fontName": "Font Name", + "title": "Add Page Numbers", + "header": "Add Page Numbers", + "selectText": { + "1": "Select PDF file:", + "2": "Margin Size", + "3": "Position", + "4": "Starting Number", + "5": "Pages to Number", + "6": "Custom Text" + }, + "customTextDesc": "Custom Text", + "numberPagesDesc": "Which pages to number, default 'all', also accepts 1-5 or 2,5,9 etc", + "customNumberDesc": "Defaults to {n}, also accepts 'Page {n} of {total}', 'Text-{n}', '{filename}-{n}", + "submit": "Add Page Numbers" + }, + "pdfPrompt": "Select PDF(s)", + "multiPdfPrompt": "Select PDFs (2+)", + "multiPdfDropPrompt": "Select (or drag & drop) all PDFs you require", + "imgPrompt": "Select Image(s)", + "genericSubmit": "Submit", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Warning: This process can take up to a minute depending on file-size", + "pageOrderPrompt": "Custom Page Order (Enter a comma-separated list of page numbers or Functions like 2n+1) :", + "pageSelectionPrompt": "Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :", + "goToPage": "Go", + "true": "True", + "false": "False", + "unknown": "Unknown", + "save": "Save", + "saveToBrowser": "Save to Browser", + "close": "Close", + "filesSelected": "files selected", + "noFavourites": "No favorites added", + "downloadComplete": "Download Complete", + "bored": "Bored Waiting?", + "alphabet": "Alphabet", + "downloadPdf": "Download PDF", + "text": "Text", + "font": "Font", + "selectFillter": "-- Select --", + "pageNum": "Page Number", + "sizes": { + "small": "Small", + "medium": "Medium", + "large": "Large", + "x-large": "X-Large" + }, + "error": { + "pdfPassword": "The PDF Document is passworded and either the password was not provided or was incorrect", + "_value": "Error", + "sorry": "Sorry for the issue!", + "needHelp": "Need help / Found an issue?", + "contactTip": "If you're still having trouble, don't hesitate to reach out to us for help. You can submit a ticket on our GitHub page or contact us through Discord:", + "404": { + "head": "404 - Page Not Found | Oops, we tripped in the code!", + "1": "We can't seem to find the page you're looking for.", + "2": "Something went wrong" + }, + "github": "Submit a ticket on GitHub", + "showStack": "Show Stack Trace", + "copyStack": "Copy Stack Trace", + "githubSubmit": "GitHub - Submit a ticket", + "discordSubmit": "Discord - Submit Support post" + }, + "delete": "Delete", + "username": "Username", + "password": "Password", + "welcome": "Welcome", + "property": "Property", + "black": "Black", + "white": "White", + "red": "Red", + "green": "Green", + "blue": "Blue", + "custom": "Custom...", + "WorkInProgess": "Work in progress, May not work or be buggy, Please report any problems!", + "poweredBy": "Powered by", + "yes": "Yes", + "no": "No", + "changedCredsMessage": "Credentials changed!", + "notAuthenticatedMessage": "User not authenticated.", + "userNotFoundMessage": "User not found.", + "incorrectPasswordMessage": "Current password is incorrect.", + "usernameExistsMessage": "New Username already exists.", + "invalidUsernameMessage": "Invalid username, username can only contain letters, numbers and the following special characters @._+- or must be a valid email address.", + "invalidPasswordMessage": "The password must not be empty and must not have spaces at the beginning or end.", + "confirmPasswordErrorMessage": "New Password and Confirm New Password must match.", + "deleteCurrentUserMessage": "Cannot delete currently logged in user.", + "deleteUsernameExistsMessage": "The username does not exist and cannot be deleted.", + "downgradeCurrentUserMessage": "Cannot downgrade current user's role", + "disabledCurrentUserMessage": "The current user cannot be disabled", + "downgradeCurrentUserLongMessage": "Cannot downgrade current user's role. Hence, current user will not be shown.", + "userAlreadyExistsOAuthMessage": "The user already exists as an OAuth2 user.", + "userAlreadyExistsWebMessage": "The user already exists as an web user.", + "oops": "Oops!", + "help": "Help", + "goHomepage": "Go to Homepage", + "joinDiscord": "Join our Discord server", + "seeDockerHub": "See Docker Hub", + "visitGithub": "Visit Github Repository", + "donate": "Donate", + "color": "Color", + "sponsor": "Sponsor", + "info": "Info", + "pro": "Pro", + "page": "Page", + "pages": "Pages", + "loading": "Loading...", + "addToDoc": "Add to Document", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Privacy Policy", + "terms": "Terms and Conditions", + "accessibility": "Accessibility", + "cookie": "Cookie Policy", + "impressum": "Impressum", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Pipeline Menu (Beta)", + "uploadButton": "Upload Custom", + "configureButton": "Configure", + "defaultOption": "Custom", + "submitButton": "Submit", + "help": "Pipeline Help", + "scanHelp": "Folder Scanning Help", + "deletePrompt": "Are you sure you want to delete pipeline", + "tags": "automate,sequence,scripted,batch-process", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Pipeline Configuration", + "pipelineNameLabel": "Pipeline Name", + "saveSettings": "Save Operation Settings", + "pipelineNamePrompt": "Enter pipeline name here", + "selectOperation": "Select Operation", + "addOperationButton": "Add operation", + "pipelineHeader": "Pipeline:", + "saveButton": "Download", + "validateButton": "Validate" + }, + "enterpriseEdition": { + "button": "Upgrade to Pro", + "warning": "This feature is only available to Pro users.", + "yamlAdvert": "Stirling PDF Pro supports YAML configuration files and other SSO features.", + "ssoAdvert": "Looking for more user management features? Check out Stirling PDF Pro" + }, + "analytics": { + "title": "Do you want make Stirling PDF better?", + "paragraph1": "Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.", + "paragraph2": "Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.", + "enable": "Enable analytics", + "disable": "Disable analytics", + "settings": "You can change the settings for analytics in the config/settings.yml file" + }, + "navbar": { + "favorite": "Favorites", + "recent": "New and recently updated", + "darkmode": "Dark Mode", + "language": "Languages", + "settings": "Settings", + "allTools": "Tools", + "multiTool": "Multi Tool", + "search": "Search", + "sections": { + "organize": "Organize", + "convertTo": "Convert to PDF", + "convertFrom": "Convert from PDF", + "security": "Sign & Security", + "advance": "Advanced", + "edit": "View & Edit", + "popular": "Popular" + } + }, + "settings": { + "title": "Settings", + "update": "Update available", + "updateAvailable": "{0} is the current installed version. A new version ({1}) is available.", + "appVersion": "App Version:", + "downloadOption": { + "title": "Choose download option (For single file non zip downloads):", + "1": "Open in same window", + "2": "Open in new window", + "3": "Download file" + }, + "zipThreshold": "Zip files when the number of downloaded files exceeds", + "signOut": "Sign Out", + "accountSettings": "Account Settings", + "bored": { + "help": "Enables easter egg game" + }, + "cacheInputs": { + "name": "Save form inputs", + "help": "Enable to store previously used inputs for future runs" + } + }, + "changeCreds": { + "title": "Change Credentials", + "header": "Update Your Account Details", + "changePassword": "You are using default login credentials. Please enter a new password", + "newUsername": "New Username", + "oldPassword": "Current Password", + "newPassword": "New Password", + "confirmNewPassword": "Confirm New Password", + "submit": "Submit Changes" + }, + "account": { + "title": "Account Settings", + "accountSettings": "Account Settings", + "adminSettings": "Admin Settings - View and Add Users", + "userControlSettings": "User Control Settings", + "changeUsername": "Change Username", + "newUsername": "New Username", + "password": "Confirmation Password", + "oldPassword": "Old password", + "newPassword": "New Password", + "changePassword": "Change Password", + "confirmNewPassword": "Confirm New Password", + "signOut": "Sign Out", + "yourApiKey": "Your API Key", + "syncTitle": "Sync browser settings with Account", + "settingsCompare": "Settings Comparison:", + "property": "Property", + "webBrowserSettings": "Web Browser Setting", + "syncToBrowser": "Sync Account -> Browser", + "syncToAccount": "Sync Account <- Browser" + }, + "adminUserSettings": { + "title": "User Control Settings", + "header": "Admin User Control Settings", + "admin": "Admin", + "user": "User", + "addUser": "Add New User", + "deleteUser": "Delete User", + "confirmDeleteUser": "Should the user be deleted?", + "confirmChangeUserStatus": "Should the user be disabled/enabled?", + "usernameInfo": "Username can only contain letters, numbers and the following special characters @._+- or must be a valid email address.", + "roles": "Roles", + "role": "Role", + "actions": "Actions", + "apiUser": "Limited API User", + "extraApiUser": "Additional Limited API User", + "webOnlyUser": "Web Only User", + "demoUser": "Demo User (No custom settings)", + "internalApiUser": "Internal API User", + "forceChange": "Force user to change password on login", + "submit": "Save User", + "changeUserRole": "Change User's Role", + "authenticated": "Authenticated", + "editOwnProfil": "Edit own profile", + "enabledUser": "enabled user", + "disabledUser": "disabled user", + "activeUsers": "Active Users:", + "disabledUsers": "Disabled Users:", + "totalUsers": "Total Users:", + "lastRequest": "Last Request", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Database Import/Export", + "header": "Database Import/Export", + "fileName": "File Name", + "creationDate": "Creation Date", + "fileSize": "File Size", + "deleteBackupFile": "Delete Backup File", + "importBackupFile": "Import Backup File", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Download Backup File", + "info_1": "When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.", + "info_2": "The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.", + "submit": "Import Backup", + "importIntoDatabaseSuccessed": "Import into database successed", + "backupCreated": "Database backup successful", + "fileNotFound": "File not Found", + "fileNullOrEmpty": "File must not be null or empty", + "failedImportFile": "Failed Import File", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "Your session has expired. Please refresh the page and try again.", + "refreshPage": "Refresh Page" + }, + "home": { + "desc": "Your locally hosted one-stop-shop for all your PDF needs.", + "searchBar": "Search for features...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "View, annotate, draw, add text or images" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "PDF Multi Tool", + "desc": "Merge, Rotate, Rearrange, Split, and Remove pages" + }, + "merge": { + "title": "Merge", + "desc": "Easily merge multiple PDFs into one." + }, + "split": { + "title": "Split", + "desc": "Split PDFs into multiple documents" + }, + "rotate": { + "title": "Rotate", + "desc": "Easily rotate your PDFs." + }, + "imageToPdf": { + "title": "Image to PDF", + "desc": "Convert a image (PNG, JPEG, GIF) to PDF." + }, + "pdfToImage": { + "title": "PDF to Image", + "desc": "Convert a PDF to a image. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Organize", + "desc": "Remove/Rearrange pages in any order" + }, + "addImage": { + "title": "Add image", + "desc": "Adds a image onto a set location on the PDF" + }, + "watermark": { + "title": "Add Watermark", + "desc": "Add a custom watermark to your PDF document." + }, + "permissions": { + "title": "Change Permissions", + "desc": "Change the permissions of your PDF document" + }, + "removePages": { + "title": "Remove", + "desc": "Delete unwanted pages from your PDF document." + }, + "addPassword": { + "title": "Add Password", + "desc": "Encrypt your PDF document with a password." + }, + "removePassword": { + "title": "Remove Password", + "desc": "Remove password protection from your PDF document." + }, + "compressPdfs": { + "title": "Compress", + "desc": "Compress PDFs to reduce their file size." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Change Metadata", + "desc": "Change/Remove/Add metadata from a PDF document" + }, + "fileToPDF": { + "title": "Convert file to PDF", + "desc": "Convert nearly any file to PDF (DOCX, PNG, XLS, PPT, TXT and more)" + }, + "ocr": { + "title": "OCR / Cleanup scans", + "desc": "Cleanup scans and detects text from images within a PDF and re-adds it as text." + }, + "extractImages": { + "title": "Extract Images", + "desc": "Extracts all images from a PDF and saves them to zip" + }, + "pdfToPDFA": { + "title": "PDF to PDF/A", + "desc": "Convert PDF to PDF/A for long-term storage" + }, + "PDFToWord": { + "title": "PDF to Word", + "desc": "Convert PDF to Word formats (DOC, DOCX and ODT)" + }, + "PDFToPresentation": { + "title": "PDF to Presentation", + "desc": "Convert PDF to Presentation formats (PPT, PPTX and ODP)" + }, + "PDFToText": { + "title": "PDF to RTF (Text)", + "desc": "Convert PDF to Text or RTF format" + }, + "PDFToHTML": { + "title": "PDF to HTML", + "desc": "Convert PDF to HTML format" + }, + "PDFToXML": { + "title": "PDF to XML", + "desc": "Convert PDF to XML format" + }, + "ScannerImageSplit": { + "title": "Detect/Split Scanned photos", + "desc": "Splits multiple photos from within a photo/PDF" + }, + "sign": { + "title": "Sign", + "desc": "Adds signature to PDF by drawing, text or image" + }, + "flatten": { + "title": "Flatten", + "desc": "Remove all interactive elements and forms from a PDF" + }, + "repair": { + "title": "Repair", + "desc": "Tries to repair a corrupt/broken PDF" + }, + "removeBlanks": { + "title": "Remove Blank pages", + "desc": "Detects and removes blank pages from a document" + }, + "removeAnnotations": { + "title": "Remove Annotations", + "desc": "Removes all comments/annotations from a PDF" + }, + "compare": { + "title": "Compare", + "desc": "Compares and shows the differences between 2 PDF Documents" + }, + "certSign": { + "title": "Sign with Certificate", + "desc": "Signs a PDF with a Certificate/Key (PEM/P12)" + }, + "removeCertSign": { + "title": "Remove Certificate Sign", + "desc": "Remove certificate signature from PDF" + }, + "pageLayout": { + "title": "Multi-Page Layout", + "desc": "Merge multiple pages of a PDF document into a single page" + }, + "scalePages": { + "title": "Adjust page size/scale", + "desc": "Change the size/scale of a page and/or its contents." + }, + "pipeline": { + "title": "Pipeline", + "desc": "Run multiple actions on PDFs by defining pipeline scripts" + }, + "add-page-numbers": { + "title": "Add Page Numbers", + "desc": "Add Page numbers throughout a document in a set location" + }, + "auto-rename": { + "title": "Auto Rename PDF File", + "desc": "Auto renames a PDF file based on its detected header" + }, + "adjust-contrast": { + "title": "Adjust Colors/Contrast", + "desc": "Adjust Contrast, Saturation and Brightness of a PDF" + }, + "crop": { + "title": "Crop PDF", + "desc": "Crop a PDF to reduce its size (maintains text!)" + }, + "autoSplitPDF": { + "title": "Auto Split Pages", + "desc": "Auto Split Scanned PDF with physical scanned page splitter QR Code" + }, + "sanitizePdf": { + "title": "Sanitize", + "desc": "Remove scripts and other elements from PDF files" + }, + "URLToPDF": { + "title": "URL/Website To PDF", + "desc": "Converts any http(s)URL to PDF" + }, + "HTMLToPDF": { + "title": "HTML to PDF", + "desc": "Converts any HTML file or zip to PDF" + }, + "MarkdownToPDF": { + "title": "Markdown to PDF", + "desc": "Converts any Markdown file to PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "Get ALL Info on PDF", + "desc": "Grabs any and all information possible on PDFs" + }, + "extractPage": { + "title": "Extract page(s)", + "desc": "Extracts select pages from PDF" + }, + "PdfToSinglePage": { + "title": "Single Large Page", + "desc": "Merges all PDF pages into one large single page" + }, + "showJS": { + "title": "Show Javascript", + "desc": "Searches and displays any JS injected into a PDF" + }, + "autoRedact": { + "title": "Auto Redact", + "desc": "Auto Redacts(Blacks out) text in a PDF based on input text" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF to CSV", + "desc": "Extracts Tables from a PDF converting it to CSV" + }, + "autoSizeSplitPDF": { + "title": "Auto Split by Size/Count", + "desc": "Split a single PDF into multiple documents based on size, page count, or document count" + }, + "overlay-pdfs": { + "title": "Overlay PDFs", + "desc": "Overlays PDFs on-top of another PDF" + }, + "split-by-sections": { + "title": "Split PDF by Sections", + "desc": "Divide each page of a PDF into smaller horizontal and vertical sections" + }, + "AddStampRequest": { + "title": "Add Stamp to PDF", + "desc": "Add text or add image stamps at set locations" + }, + "removeImagePdf": { + "title": "Remove image", + "desc": "Remove image from PDF to reduce file size" + }, + "splitPdfByChapters": { + "title": "Split PDF by Chapters", + "desc": "Split a PDF into multiple files based on its chapter structure." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "swagger": { + "title": "API Documentation", + "desc": "View API documentation and test endpoints" + }, + "replaceColorPdf": { + "title": "Replace and Invert Color", + "desc": "Replace color for text and background in PDF and invert full color of pdf to reduce file size" + } + }, + "viewPdf": { + "tags": "view,read,annotate,text,image,highlight,edit", + "title": "View/Edit PDF", + "header": "View PDF" + }, + "multiTool": { + "tags": "Multi Tool,Multi operation,UI,click drag,front end,client side,interactive,intractable,move,delete,migrate,divide", + "title": "PDF Multi Tool", + "header": "PDF Multi Tool", + "uploadPrompts": "File Name", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "selectPages": "Page Select", + "selectedPages": "Selected Pages", + "page": "Page", + "deleteSelected": "Delete Selected", + "downloadAll": "Export", + "downloadSelected": "Export Selected", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "Page(s) Selected", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "merge,Page operations,Back end,server side", + "title": "Merge", + "header": "Merge multiple PDFs (2+)", + "sortByName": "Sort by name", + "sortByDate": "Sort by date", + "removeCertSign": "Remove digital signature in the merged file?", + "submit": "Merge" + }, + "split": { + "tags": "Page operations,divide,Multi Page,cut,server side", + "title": "Split PDF", + "header": "Split PDF", + "desc": { + "1": "The numbers you select are the page number you wish to do a split on", + "2": "As such selecting 1,3,7-9 would split a 10 page document into 6 separate PDFS with:", + "3": "Document #1: Page 1", + "4": "Document #2: Page 2 and 3", + "5": "Document #3: Page 4, 5, 6, 7", + "6": "Document #4: Page 8", + "7": "Document #5: Page 9", + "8": "Document #6: Page 10" + }, + "splitPages": "Enter pages to split on:", + "submit": "Split" + }, + "rotate": { + "tags": "server side", + "title": "Rotate PDF", + "header": "Rotate PDF", + "selectAngle": "Select rotation angle (in multiples of 90 degrees):", + "submit": "Rotate" + }, + "imageToPdf": { + "tags": "conversion,img,jpg,picture,photo" + }, + "pdfToImage": { + "tags": "conversion,img,jpg,picture,photo", + "title": "PDF to Image", + "header": "PDF to Image", + "selectText": "Image Format", + "singleOrMultiple": "Image result type", + "single": "Single Big Image", + "multi": "Multiple Images", + "colorType": "Color type", + "color": "Color", + "grey": "Grayscale", + "blackwhite": "Black and White (May lose data!)", + "submit": "Convert", + "info": "Python is not installed. Required for WebP conversion.", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,even,odd,sort,move", + "title": "Page Organizer", + "header": "PDF Page Organizer", + "submit": "Rearrange Pages", + "mode": { + "_value": "Mode", + "1": "Custom Page Order", + "2": "Reverse Order", + "3": "Duplex Sort", + "4": "Booklet Sort", + "5": "Side Stitch Booklet Sort", + "6": "Odd-Even Split", + "7": "Remove First", + "8": "Remove Last", + "9": "Remove First and Last", + "10": "Odd-Even Merge", + "11": "Duplicate all pages" + }, + "placeholder": "(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)" + }, + "addImage": { + "tags": "img,jpg,picture,photo", + "title": "Add Image", + "header": "Add image to PDF", + "everyPage": "Every Page?", + "upload": "Add image", + "submit": "Add image" + }, + "watermark": { + "tags": "Text,repeating,label,own,copyright,trademark,img,jpg,picture,photo", + "title": "Add Watermark", + "header": "Add Watermark", + "customColor": "Custom Text Color", + "selectText": { + "1": "Select PDF to add watermark to:", + "2": "Watermark Text:", + "3": "Font Size:", + "4": "Rotation (0-360):", + "5": "Width Spacer (Space between each watermark horizontally):", + "6": "Height Spacer (Space between each watermark vertically):", + "7": "Opacity (0% - 100%):", + "8": "Watermark Type:", + "9": "Watermark Image:", + "10": "Convert PDF to PDF-Image" + }, + "submit": "Add Watermark", + "type": { + "1": "Text", + "2": "Image" + } + }, + "permissions": { + "tags": "read,write,edit,print", + "title": "Change Permissions", + "header": "Change Permissions", + "warning": "Warning to have these permissions be unchangeable it is recommended to set them with a password via the add-password page", + "selectText": { + "1": "Select PDF to change permissions", + "2": "Permissions to set", + "3": "Prevent assembly of document", + "4": "Prevent content extraction", + "5": "Prevent extraction for accessibility", + "6": "Prevent filling in form", + "7": "Prevent modification", + "8": "Prevent annotation modification", + "9": "Prevent printing", + "10": "Prevent printing different formats" + }, + "submit": "Change" + }, + "removePages": { + "tags": "Remove pages,delete pages" + }, + "addPassword": { + "tags": "secure,security", + "title": "Add Password", + "header": "Add password (Encrypt)", + "selectText": { + "1": "Select PDF to encrypt", + "2": "User Password", + "3": "Encryption Key Length", + "4": "Higher values are stronger, but lower values have better compatibility.", + "5": "Permissions to set (Recommended to be used along with Owner password)", + "6": "Prevent assembly of document", + "7": "Prevent content extraction", + "8": "Prevent extraction for accessibility", + "9": "Prevent filling in form", + "10": "Prevent modification", + "11": "Prevent annotation modification", + "12": "Prevent printing", + "13": "Prevent printing different formats", + "14": "Owner Password", + "15": "Restricts what can be done with the document once it is opened (Not supported by all readers)", + "16": "Restricts the opening of the document itself" + }, + "submit": "Encrypt" + }, + "removePassword": { + "tags": "secure,Decrypt,security,unpassword,delete password", + "title": "Remove password", + "header": "Remove password (Decrypt)", + "selectText": { + "1": "Select PDF to Decrypt", + "2": "Password" + }, + "submit": "Remove" + }, + "compressPdfs": { + "tags": "squish,small,tiny" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Title,author,date,creation,time,publisher,producer,stats", + "title": "Title:", + "header": "Change Metadata", + "selectText": { + "1": "Please edit the variables you wish to change", + "2": "Delete all metadata", + "3": "Show Custom Metadata:", + "4": "Other Metadata:", + "5": "Add Custom Metadata Entry" + }, + "author": "Author:", + "creationDate": "Creation Date (yyyy/MM/dd HH:mm:ss):", + "creator": "Creator:", + "keywords": "Keywords:", + "modDate": "Modification Date (yyyy/MM/dd HH:mm:ss):", + "producer": "Producer:", + "subject": "Subject:", + "trapped": "Trapped:", + "submit": "Change" + }, + "fileToPDF": { + "tags": "transformation,format,document,picture,slide,text,conversion,office,docs,word,excel,powerpoint", + "title": "File to PDF", + "header": "Convert any file to PDF", + "credit": "This service uses LibreOffice and Unoconv for file conversion.", + "supportedFileTypesInfo": "Supported File types", + "supportedFileTypes": "Supported file types should include the below however for a full updated list of supported formats, please refer to the LibreOffice documentation", + "submit": "Convert to PDF" + }, + "ocr": { + "tags": "recognition,text,image,scan,read,identify,detection,editable", + "title": "OCR / Scan Cleanup", + "header": "Cleanup Scans / OCR (Optical Character Recognition)", + "selectText": { + "1": "Select languages that are to be detected within the PDF (Ones listed are the ones currently detected):", + "2": "Produce text file containing OCR text alongside the OCR'ed PDF", + "3": "Correct pages were scanned at a skewed angle by rotating them back into place", + "4": "Clean page so its less likely that OCR will find text in background noise. (No output change)", + "5": "Clean page so its less likely that OCR will find text in background noise, maintains cleanup in output.", + "6": "Ignores pages that have interactive text on them, only OCRs pages that are images", + "7": "Force OCR, will OCR Every page removing all original text elements", + "8": "Normal (Will error if PDF contains text)", + "9": "Additional Settings", + "10": "OCR Mode", + "11": "Remove images after OCR (Removes ALL images, only useful if part of conversion step)", + "12": "Render Type (Advanced)" + }, + "help": "Please read this documentation on how to use this for other languages and/or use not in docker", + "credit": "This service uses qpdf and Tesseract for OCR.", + "submit": "Process PDF with OCR" + }, + "extractImages": { + "tags": "picture,photo,save,archive,zip,capture,grab", + "title": "Extract Images", + "header": "Extract Images", + "selectText": "Select image format to convert extracted images to", + "allowDuplicates": "Save duplicate images", + "submit": "Extract" + }, + "pdfToPDFA": { + "tags": "archive,long-term,standard,conversion,storage,preservation", + "title": "PDF To PDF/A", + "header": "PDF To PDF/A", + "credit": "This service uses libreoffice for PDF/A conversion", + "submit": "Convert", + "tip": "Currently does not work for multiple inputs at once", + "outputFormat": "Output format", + "pdfWithDigitalSignature": "The PDF contains a digital signature. This will be removed in the next step." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformation,format,conversion,office,microsoft,docfile", + "title": "PDF to Word", + "header": "PDF to Word", + "selectText": { + "1": "Output file format" + }, + "credit": "This service uses LibreOffice for file conversion.", + "submit": "Convert" + }, + "PDFToPresentation": { + "tags": "slides,show,office,microsoft", + "title": "PDF to Presentation", + "header": "PDF to Presentation", + "selectText": { + "1": "Output file format" + }, + "credit": "This service uses LibreOffice for file conversion.", + "submit": "Convert" + }, + "PDFToText": { + "tags": "richformat,richtextformat,rich text format", + "title": "PDF to RTF (Text)", + "header": "PDF to RTF (Text)", + "selectText": { + "1": "Output file format" + }, + "credit": "This service uses LibreOffice for file conversion.", + "submit": "Convert" + }, + "PDFToHTML": { + "tags": "web content,browser friendly", + "title": "PDF to HTML", + "header": "PDF to HTML", + "credit": "This service uses pdftohtml for file conversion.", + "submit": "Convert" + }, + "PDFToXML": { + "tags": "data-extraction,structured-content,interop,transformation,convert", + "title": "PDF to XML", + "header": "PDF to XML", + "credit": "This service uses LibreOffice for file conversion.", + "submit": "Convert" + }, + "ScannerImageSplit": { + "tags": "separate,auto-detect,scans,multi-photo,organize", + "selectText": { + "1": "Angle Threshold:", + "2": "Sets the minimum absolute angle required for the image to be rotated (default: 10).", + "3": "Tolerance:", + "4": "Determines the range of color variation around the estimated background color (default: 30).", + "5": "Minimum Area:", + "6": "Sets the minimum area threshold for a photo (default: 10000).", + "7": "Minimum Contour Area:", + "8": "Sets the minimum contour area threshold for a photo", + "9": "Border Size:", + "10": "Sets the size of the border added and removed to prevent white borders in the output (default: 1)." + }, + "info": "Python is not installed. It is required to run." + }, + "sign": { + "tags": "authorize,initials,drawn-signature,text-sign,image-signature", + "title": "Sign", + "header": "Sign PDFs", + "upload": "Upload Image", + "draw": "Draw Signature", + "text": "Text Input", + "clear": "Clear", + "add": "Add", + "saved": "Saved Signatures", + "save": "Save Signature", + "personalSigs": "Personal Signatures", + "sharedSigs": "Shared Signatures", + "noSavedSigs": "No saved signatures found", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "static,deactivate,non-interactive,streamline", + "title": "Flatten", + "header": "Flatten PDFs", + "flattenOnlyForms": "Flatten only forms", + "submit": "Flatten" + }, + "repair": { + "tags": "fix,restore,correction,recover", + "title": "Repair", + "header": "Repair PDFs", + "submit": "Repair" + }, + "removeBlanks": { + "tags": "cleanup,streamline,non-content,organize", + "title": "Remove Blanks", + "header": "Remove Blank Pages", + "threshold": "Pixel Whiteness Threshold:", + "thresholdDesc": "Threshold for determining how white a white pixel must be to be classed as 'White'. 0 = Black, 255 pure white.", + "whitePercent": "White Percent (%):", + "whitePercentDesc": "Percent of page that must be 'white' pixels to be removed", + "submit": "Remove Blanks" + }, + "removeAnnotations": { + "tags": "comments,highlight,notes,markup,remove", + "title": "Remove Annotations", + "header": "Remove Annotations", + "submit": "Remove" + }, + "compare": { + "tags": "differentiate,contrast,changes,analysis", + "title": "Compare", + "header": "Compare PDFs", + "highlightColor": { + "1": "Highlight Color 1:", + "2": "Highlight Color 2:" + }, + "document": { + "1": "Document 1", + "2": "Document 2" + }, + "submit": "Compare", + "complex": { + "message": "One or both of the provided documents are large files, accuracy of comparison may be reduced" + }, + "large": { + "file": { + "message": "One or Both of the provided documents are too large to process" + } + }, + "no": { + "text": { + "message": "One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison." + } + } + }, + "certSign": { + "tags": "authenticate,PEM,P12,official,encrypt", + "title": "Certificate Signing", + "header": "Sign a PDF with your certificate (Work in progress)", + "selectPDF": "Select a PDF File for Signing:", + "jksNote": "Note: If your certificate type is not listed below, please convert it to a Java Keystore (.jks) file using the keytool command line tool. Then, choose the .jks file option below.", + "selectKey": "Select Your Private Key File (PKCS#8 format, could be .pem or .der):", + "selectCert": "Select Your Certificate File (X.509 format, could be .pem or .der):", + "selectP12": "Select Your PKCS#12 Keystore File (.p12 or .pfx) (Optional, If provided, it should contain your private key and certificate):", + "selectJKS": "Select Your Java Keystore File (.jks or .keystore):", + "certType": "Certificate Type", + "password": "Enter Your Keystore or Private Key Password (If Any):", + "showSig": "Show Signature", + "reason": "Reason", + "location": "Location", + "name": "Name", + "showLogo": "Show Logo", + "submit": "Sign PDF" + }, + "removeCertSign": { + "tags": "authenticate,PEM,P12,official,decrypt", + "title": "Remove Certificate Signature", + "header": "Remove the digital certificate from the PDF", + "selectPDF": "Select a PDF file:", + "submit": "Remove Signature" + }, + "pageLayout": { + "tags": "merge,composite,single-view,organize", + "title": "Multi Page Layout", + "header": "Multi Page Layout", + "pagesPerSheet": "Pages per sheet:", + "addBorder": "Add Borders", + "submit": "Submit" + }, + "scalePages": { + "tags": "resize,modify,dimension,adapt", + "title": "Adjust page-scale", + "header": "Adjust page-scale", + "pageSize": "Size of a page of the document.", + "keepPageSize": "Original Size", + "scaleFactor": "Zoom level (crop) of a page.", + "submit": "Submit" + }, + "add-page-numbers": { + "tags": "paginate,label,organize,index" + }, + "auto-rename": { + "tags": "auto-detect,header-based,organize,relabel", + "title": "Auto Rename", + "header": "Auto Rename PDF", + "submit": "Auto Rename" + }, + "adjust-contrast": { + "tags": "color-correction,tune,modify,enhance" + }, + "crop": { + "tags": "trim,shrink,edit,shape", + "title": "Crop", + "header": "Crop PDF", + "submit": "Submit" + }, + "autoSplitPDF": { + "tags": "QR-based,separate,scan-segment,organize", + "title": "Auto Split PDF", + "header": "Auto Split PDF", + "description": "Print, Insert, Scan, upload, and let us auto-separate your documents. No manual work sorting needed.", + "selectText": { + "1": "Print out some divider sheets from below (Black and white is fine).", + "2": "Scan all your documents at once by inserting the divider sheet between them.", + "3": "Upload the single large scanned PDF file and let Stirling PDF handle the rest.", + "4": "Divider pages are automatically detected and removed, guaranteeing a neat final document." + }, + "formPrompt": "Submit PDF containing Stirling-PDF Page dividers:", + "duplexMode": "Duplex Mode (Front and back scanning)", + "dividerDownload2": "Download 'Auto Splitter Divider (with instructions).pdf'", + "submit": "Submit" + }, + "sanitizePdf": { + "tags": "clean,secure,safe,remove-threats" + }, + "URLToPDF": { + "tags": "web-capture,save-page,web-to-doc,archive", + "title": "URL To PDF", + "header": "URL To PDF", + "submit": "Convert", + "credit": "Uses WeasyPrint" + }, + "HTMLToPDF": { + "tags": "markup,web-content,transformation,convert", + "title": "HTML To PDF", + "header": "HTML To PDF", + "help": "Accepts HTML files and ZIPs containing html/css/images etc required", + "submit": "Convert", + "credit": "Uses WeasyPrint", + "zoom": "Zoom level for displaying the website.", + "pageWidth": "Width of the page in centimeters. (Blank to default)", + "pageHeight": "Height of the page in centimeters. (Blank to default)", + "marginTop": "Top margin of the page in millimeters. (Blank to default)", + "marginBottom": "Bottom margin of the page in millimeters. (Blank to default)", + "marginLeft": "Left margin of the page in millimeters. (Blank to default)", + "marginRight": "Right margin of the page in millimeters. (Blank to default)", + "printBackground": "Render the background of websites.", + "defaultHeader": "Enable Default Header (Name and page number)", + "cssMediaType": "Change the CSS media type of the page.", + "none": "None", + "print": "Print", + "screen": "Screen" + }, + "MarkdownToPDF": { + "tags": "markup,web-content,transformation,convert,md", + "title": "Markdown To PDF", + "header": "Markdown To PDF", + "submit": "Convert", + "help": "Work in progress", + "credit": "Uses WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "infomation,data,stats,statistics", + "title": "Get Info on PDF", + "header": "Get Info on PDF", + "submit": "Get Info", + "downloadJson": "Download JSON" + }, + "extractPage": { + "tags": "extract" + }, + "PdfToSinglePage": { + "tags": "single page" + }, + "showJS": { + "tags": "JS", + "title": "Show Javascript", + "header": "Show Javascript", + "downloadJS": "Download Javascript", + "submit": "Show" + }, + "autoRedact": { + "tags": "Redact,Hide,black out,black,marker,hidden", + "title": "Auto Redact", + "header": "Auto Redact", + "colorLabel": "Color", + "textsToRedactLabel": "Text to Redact (line-separated)", + "textsToRedactPlaceholder": "e.g. \\nConfidential \\nTop-Secret", + "useRegexLabel": "Use Regex", + "wholeWordSearchLabel": "Whole Word Search", + "customPaddingLabel": "Custom Extra Padding", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "submitButton": "Submit" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,Table Extraction,extract,convert" + }, + "autoSizeSplitPDF": { + "tags": "pdf,split,document,organization" + }, + "overlay-pdfs": { + "tags": "Overlay", + "header": "Overlay PDF Files", + "baseFile": { + "label": "Select Base PDF File" + }, + "overlayFiles": { + "label": "Select Overlay PDF Files" + }, + "mode": { + "label": "Select Overlay Mode", + "sequential": "Sequential Overlay", + "interleaved": "Interleaved Overlay", + "fixedRepeat": "Fixed Repeat Overlay" + }, + "counts": { + "label": "Overlay Counts (for Fixed Repeat Mode)", + "placeholder": "Enter comma-separated counts (e.g., 2,3,1)" + }, + "position": { + "label": "Select Overlay Position", + "foreground": "Foreground", + "background": "Background" + }, + "submit": "Submit" + }, + "split-by-sections": { + "tags": "Section Split, Divide, Customize", + "title": "Split PDF by Sections", + "header": "Split PDF into Sections", + "horizontal": { + "label": "Horizontal Divisions", + "placeholder": "Enter number of horizontal divisions" + }, + "vertical": { + "label": "Vertical Divisions", + "placeholder": "Enter number of vertical divisions" + }, + "submit": "Split PDF", + "merge": "Merge Into One PDF" + }, + "AddStampRequest": { + "tags": "Stamp, Add image, center image, Watermark, PDF, Embed, Customize", + "header": "Stamp PDF", + "title": "Stamp PDF", + "stampType": "Stamp Type", + "stampText": "Stamp Text", + "stampImage": "Stamp Image", + "alphabet": "Alphabet", + "fontSize": "Font/Image Size", + "rotation": "Rotation", + "opacity": "Opacity", + "position": "Position", + "overrideX": "Override X Coordinate", + "overrideY": "Override Y Coordinate", + "customMargin": "Custom Margin", + "customColor": "Custom Text Color", + "submit": "Submit" + }, + "removeImagePdf": { + "tags": "Remove Image,Page operations,Back end,server side" + }, + "splitPdfByChapters": { + "tags": "split,chapters,bookmarks,organize" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Replace-Invert-Color", + "header": "Replace-Invert Color PDF", + "selectText": { + "1": "Replace or Invert color Options", + "2": "Default(Default high contrast colors)", + "3": "Custom(Customized colors)", + "4": "Full-Invert(Invert all colors)", + "5": "High contrast color options", + "6": "white text on black background", + "7": "Black text on white background", + "8": "Yellow text on black background", + "9": "Green text on black background", + "10": "Choose text Color", + "11": "Choose background Color" + }, + "submit": "Replace" + }, + "replaceColorPdf": { + "tags": "Replace Color,Page operations,Back end,server side" + }, + "login": { + "title": "Sign in", + "header": "Sign in", + "signin": "Sign in", + "rememberme": "Remember me", + "invalid": "Invalid username or password.", + "locked": "Your account has been locked.", + "signinTitle": "Please sign in", + "ssoSignIn": "Login via Single Sign-on", + "oAuth2AutoCreateDisabled": "OAUTH2 Auto-Create User Disabled", + "oAuth2AdminBlockedUser": "Registration or logging in of non-registered users is currently blocked. Please contact the administrator.", + "oauth2RequestNotFound": "Authorization request not found", + "oauth2InvalidUserInfoResponse": "Invalid User Info Response", + "oauth2invalidRequest": "Invalid Request", + "oauth2AccessDenied": "Access Denied", + "oauth2InvalidTokenResponse": "Invalid Token Response", + "oauth2InvalidIdToken": "Invalid Id Token", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "User is deactivated, login is currently blocked with this username. Please contact the administrator.", + "alreadyLoggedIn": "You are already logged in to", + "alreadyLoggedIn2": "devices. Please log out of the devices and try again.", + "toManySessions": "You have too many active sessions", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF To Single Page", + "header": "PDF To Single Page", + "submit": "Convert To Single Page" + }, + "pageExtracter": { + "title": "Extract Pages", + "header": "Extract Pages", + "submit": "Extract", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "sanitizePDF": { + "title": "Sanitize PDF", + "header": "Sanitize a PDF file", + "selectText": { + "1": "Remove JavaScript actions", + "2": "Remove embedded files", + "3": "Remove XMP metadata", + "4": "Remove links", + "5": "Remove fonts", + "6": "Remove Document Info Metadata" + }, + "submit": "Sanitize PDF" + }, + "adjustContrast": { + "title": "Adjust Contrast", + "header": "Adjust Contrast", + "contrast": "Contrast:", + "brightness": "Brightness:", + "saturation": "Saturation:", + "download": "Download" + }, + "compress": { + "title": "Compress", + "header": "Compress PDF", + "credit": "This service uses qpdf for PDF Compress/Optimisation.", + "grayscale": { + "label": "Apply Grayscale for Compression" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Optimization level:", + "4": "Auto mode - Auto adjusts quality to get PDF to exact size", + "5": "Expected PDF Size (e.g. 25MB, 10.8MB, 25KB)" + }, + "submit": "Compress" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "Page Remover", + "header": "PDF Page remover", + "pagesToDelete": "Pages to delete (Enter a comma-separated list of page numbers) :", + "submit": "Delete Pages", + "placeholder": "(e.g. 1,2,6 or 1-10,15-30)" + }, + "imageToPDF": { + "title": "Image to PDF", + "header": "Image to PDF", + "submit": "Convert", + "selectLabel": "Image Fit Options", + "fillPage": "Fill Page", + "fitDocumentToImage": "Fit Page to Image", + "maintainAspectRatio": "Maintain Aspect Ratios", + "selectText": { + "2": "Auto rotate PDF", + "3": "Multi file logic (Only enabled if working with multiple images)", + "4": "Merge into single PDF", + "5": "Convert to separate PDFs" + } + }, + "PDFToCSV": { + "title": "PDF to CSV", + "header": "PDF to CSV", + "prompt": "Choose page to extract table", + "submit": "Extract" + }, + "split-by-size-or-count": { + "title": "Split PDF by Size or Count", + "header": "Split PDF by Size or Count", + "type": { + "label": "Select Split Type", + "size": "By Size", + "pageCount": "By Page Count", + "docCount": "By Document Count" + }, + "value": { + "label": "Enter Value", + "placeholder": "Enter size (e.g., 2MB or 3KB) or count (e.g., 5)" + }, + "submit": "Submit" + }, + "printFile": { + "title": "Print File", + "header": "Print File to Printer", + "selectText": { + "1": "Select File to Print", + "2": "Enter Printer Name" + }, + "submit": "Print" + }, + "licenses": { + "nav": "Licenses", + "title": "3rd Party Licenses", + "header": "3rd Party Licenses", + "module": "Module", + "version": "Version", + "license": "License" + }, + "survey": { + "nav": "Survey", + "title": "Stirling-PDF Survey", + "description": "Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!", + "changes": "Stirling-PDF has changed since the last survey! To find out more please check our blog post here:", + "changes2": "With these changes we are getting paid business support and funding", + "please": "Please consider taking our survey!", + "disabled": "(Survey popup will be disabled in following updates but available at foot of page)", + "button": "Take Survey", + "dontShowAgain": "Don't show again", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Remove image", + "header": "Remove image", + "removeImage": "Remove image", + "submit": "Remove image" + }, + "splitByChapters": { + "title": "Split PDF by Chapters", + "header": "Split PDF by Chapters", + "bookmarkLevel": "Bookmark Level", + "includeMetadata": "Include Metadata", + "allowDuplicates": "Allow Duplicates", + "desc": { + "1": "This tool splits a PDF file into multiple PDFs based on its chapter structure.", + "2": "Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).", + "3": "Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.", + "4": "Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs." + }, + "submit": "Split PDF" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Releases", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Current Release" + }, + "note": "Release notes are only available in English" + }, + "swagger": { + "title": "API Documentation", + "header": "API Documentation", + "desc": "View and test the Stirling PDF API endpoints", + "tags": "api,documentation,swagger,endpoints,development" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + }, + "convert": { + "files": "Files", + "selectFilesPlaceholder": "Select files in the main view to get started", + "settings": "Settings", + "conversionCompleted": "Conversion completed", + "results": "Results", + "defaultFilename": "converted_file", + "conversionResults": "Conversion Results", + "converting": "Converting...", + "convertFiles": "Convert Files", + "downloadConverted": "Download Converted File", + "convertFrom": "Convert from", + "convertTo": "Convert to", + "sourceFormatPlaceholder": "Source format", + "targetFormatPlaceholder": "Target format", + "selectSourceFormatFirst": "Select a source format first", + "imageOptions": "Image Options", + "colorType": "Color Type", + "color": "Color", + "greyscale": "Greyscale", + "blackwhite": "Black & White", + "dpi": "DPI", + "output": "Output", + "single": "Single", + "multiple": "Multiple", + "pdfOptions": "PDF Options", + "fitOption": "Fit Option", + "maintainAspectRatio": "Maintain Aspect Ratio", + "fitDocumentToPage": "Fit Document to Page", + "fillPage": "Fill Page", + "autoRotate": "Auto Rotate", + "autoRotateDescription": "Automatically rotate images to better fit the PDF page", + "combineImages": "Combine Images", + "combineImagesDescription": "Combine all images into one PDF, or create separate PDFs for each image", + "webOptions": "Web to PDF Options", + "zoomLevel": "Zoom Level", + "emailOptions": "Email to PDF Options", + "includeAttachments": "Include email attachments", + "maxAttachmentSize": "Maximum attachment size (MB)", + "includeAllRecipients": "Include CC and BCC recipients in header", + "downloadHtml": "Download HTML intermediate file instead of PDF", + "pdfaOptions": "PDF/A Options", + "outputFormat": "Output Format", + "pdfaNote": "PDF/A-1b is more compatible, PDF/A-2b supports more features.", + "pdfaDigitalSignatureWarning": "The PDF contains a digital signature. This will be removed in the next step." + } +} \ No newline at end of file diff --git a/frontend/public/locales/en/translation.json b/frontend/public/locales/en/translation.json new file mode 100644 index 000000000..8dc3e4f90 --- /dev/null +++ b/frontend/public/locales/en/translation.json @@ -0,0 +1,29 @@ +{ + "convert": { + "selectSourceFormat": "Select source file format", + "selectTargetFormat": "Select target file format", + "selectFirst": "Select a source format first", + "imageOptions": "Image Options:", + "emailOptions": "Email Options:", + "colorType": "Color Type", + "dpi": "DPI", + "singleOrMultiple": "Output", + "emailNote": "Email attachments and embedded images will be included" + }, + "common": { + "color": "Color", + "grayscale": "Grayscale", + "blackWhite": "Black & White", + "single": "Single Image", + "multiple": "Multiple Images" + }, + "groups": { + "document": "Document", + "spreadsheet": "Spreadsheet", + "presentation": "Presentation", + "image": "Image", + "web": "Web", + "text": "Text", + "email": "Email" + } +} \ No newline at end of file diff --git a/frontend/public/locales/es-ES/translation.json b/frontend/public/locales/es-ES/translation.json new file mode 100644 index 000000000..ba16c683d --- /dev/null +++ b/frontend/public/locales/es-ES/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "TamaƱo de Letra", + "fontName": "Nombre de Letra", + "title": "AƱadir NĆŗmeros de PĆ”gina", + "header": "AƱadir NĆŗmeros de PĆ”gina", + "selectText": { + "1": "Seleccionar archivo PDF:", + "2": "TamaƱo del margen", + "3": "Posición", + "4": "NĆŗmero de inicio", + "5": "PĆ”ginas a numerar", + "6": "Texto personalizado" + }, + "customTextDesc": "Texto personalizado", + "numberPagesDesc": "QuĆ© pĆ”ginas numerar, por defecto 'todas', tambiĆ©n acepta 1-5 o 2,5,9 etc", + "customNumberDesc": "Por defecto a {n}, tambiĆ©n acepta 'PĆ”gina {n} de {total}', 'Texto-{n}', '{filename}-{n}", + "submit": "AƱadir NĆŗmeros de PĆ”gina" + }, + "pdfPrompt": "Seleccionar PDF(s)", + "multiPdfPrompt": "Seleccionar PDFs (2+)", + "multiPdfDropPrompt": "Seleccione (o arrastre y suelte) todos los PDFs que quiera", + "imgPrompt": "Seleccionar Imagen(es)", + "genericSubmit": "Enviar", + "uploadLimit": "TamaƱo mĆ”ximo de archivo:", + "uploadLimitExceededSingular": "es demasiado grande. El tamaƱo mĆ”ximo permitido es", + "uploadLimitExceededPlural": "son demasiado grandes. El tamaƱo mĆ”ximo permitido es", + "processTimeWarning": "Advertencia: este proceso puede tardar hasta un minuto dependiendo del tamaƱo del archivo", + "pageOrderPrompt": "Orden de pĆ”ginas (Introduzca una lista de nĆŗmeros de pĆ”gina separados por coma):", + "pageSelectionPrompt": "Selección de pĆ”gina personalizada (Introduzca una lista de nĆŗmeros de pĆ”gina separados por comas 1,5,6 o funciones como 2n+1):", + "goToPage": "Ir a", + "true": "Verdadero", + "false": "Falso", + "unknown": "Desconocido", + "save": "Guardar", + "saveToBrowser": "Guardar en el navegador", + "close": "Cerrar", + "filesSelected": "archivos seleccionados", + "noFavourites": "No se agregaron favoritos", + "downloadComplete": "Descarga finalizada", + "bored": "ĀæCansado de esperar?", + "alphabet": "Alfabeto", + "downloadPdf": "Descargar PDF", + "text": "Texto", + "font": "Fuente", + "selectFillter": "-- Seleccionar --", + "pageNum": "NĆŗmero de pĆ”gina", + "sizes": { + "small": "PequeƱo", + "medium": "Mediano", + "large": "Grande", + "x-large": "Extra grande" + }, + "error": { + "pdfPassword": "El documento PDF estĆ” protegido con contraseƱa y no se ha proporcionado o es incorrecta", + "_value": "Error", + "sorry": "Ā”Perdón por el fallo!", + "needHelp": "ĀæNecesita ayuda / Encontró un fallo?", + "contactTip": "Si sigue experimentando errores, no dude en contactarnos para solicitar soporte. Puede enviarnos un ticket en la pĆ”gina de GitHub o contactarnos mediante Discord:", + "404": { + "head": "404 - PĆ”gina no encontrada | Ups, Ā”algo salió mal!", + "1": "Parece que no podemos encontrar la pĆ”gina que estĆ” buscando.", + "2": "Algo salió mal" + }, + "github": "EnvĆ­e un ticket en GitHub", + "showStack": "Mostrar seguimiento de pila", + "copyStack": "Mostrar seguimiento de pila", + "githubSubmit": "GitHub - Enviar un ticket", + "discordSubmit": "Discord - Enviar mensaje de soporte" + }, + "delete": "Borrar", + "username": "Nombre de usuario", + "password": "ContraseƱa", + "welcome": "Bienvenido", + "property": "Propietario", + "black": "Negro", + "white": "Blanco", + "red": "Rojo", + "green": "Verde", + "blue": "Azul", + "custom": "Personalizado...", + "WorkInProgess": "Tarea en progreso, puede no funcionar o ralentizarse; Ā”por favor, informe de cualquier problema!", + "poweredBy": "Desarrollado por", + "yes": "SĆ­", + "no": "No", + "changedCredsMessage": "Ā”Se cambiaron las credenciales!", + "notAuthenticatedMessage": "Usuario no autentificado.", + "userNotFoundMessage": "Usuario no encontrado.", + "incorrectPasswordMessage": "La contraseƱa actual no es correcta.", + "usernameExistsMessage": "El nuevo nombre de usuario estĆ” en uso.", + "invalidUsernameMessage": "Nombre de usuario no vĆ”lido, el nombre de usuario solo puede contener letras, nĆŗmeros y los siguientes caracteres especiales @._+- o debe ser una dirección de correo electrónico vĆ”lida.", + "invalidPasswordMessage": "La contraseƱa no puede dejarse en blanco y no puede empezar ni terminar con espacios.", + "confirmPasswordErrorMessage": "Deben coincidir Nueva ContraseƱa y Confirmar Nueva ContraseƱa.", + "deleteCurrentUserMessage": "No puede eliminar el usuario que tiene la sesión actualmente en uso.", + "deleteUsernameExistsMessage": "El usuario no existe y no puede eliminarse.", + "downgradeCurrentUserMessage": "No se puede degradar el rol del usuario actual", + "disabledCurrentUserMessage": "El usuario actual no se puede deshabilitar", + "downgradeCurrentUserLongMessage": "No se puede degradar el rol del usuario actual. Por lo tanto, el usuario actual no se mostrarĆ”.", + "userAlreadyExistsOAuthMessage": "La usuario ya existe como usuario de OAuth2.", + "userAlreadyExistsWebMessage": "El usuario ya existe como usuario web.", + "oops": "Ā”Ups!", + "help": "Ayuda", + "goHomepage": "Ir a la pĆ”gina principal", + "joinDiscord": "Únase a nuestro servidor Discord", + "seeDockerHub": "Ver Docker Hub", + "visitGithub": "Visitar Repositorio de Github", + "donate": "Donar", + "color": "Color", + "sponsor": "Patrocinador", + "info": "Información", + "pro": "Pro", + "page": "PĆ”gina", + "pages": "PĆ”ginas", + "loading": "Cargando...", + "addToDoc": "Agregar al Documento", + "reset": "Restablecer", + "apply": "Aplicar", + "noFileSelected": "No ha seleccionado ningĆŗn archivo. Por favor, cargue uno.", + "legal": { + "privacy": "PolĆ­tica de Privacidad", + "terms": "TĆ©rminos y Condiciones", + "accessibility": "Accesibilidad", + "cookie": "PolĆ­tica de Cookies", + "impressum": "Impresión", + "showCookieBanner": "Preferencias de cookies" + }, + "pipeline": { + "header": "MenĆŗ de automatización (Alfa)", + "uploadButton": "Cargar personalización", + "configureButton": "Configurar", + "defaultOption": "Personalizar", + "submitButton": "Enviar", + "help": "Ayuda de automatización", + "scanHelp": "Ayuda de escaneado de carpetas", + "deletePrompt": "ĀæSeguro que quiere eliminar la automatización?", + "tags": "automatizar,secuencia,con script,proceso por lotes", + "title": "Automatización" + }, + "pipelineOptions": { + "header": "Configuración de la automatización", + "pipelineNameLabel": "Nombre de la automatización", + "saveSettings": "Guardar configuración de la automatización", + "pipelineNamePrompt": "Introduzca aquĆ­ el nombre de la automatización", + "selectOperation": "Seleccione la operación", + "addOperationButton": "AƱadir operación", + "pipelineHeader": "Automatización:", + "saveButton": "Descargar", + "validateButton": "Validar" + }, + "enterpriseEdition": { + "button": "Actualiza a Pro", + "warning": "Esta caracterĆ­stica estĆ” Ćŗnicamente disponible para usuarios Pro.", + "yamlAdvert": "Stirling PDF Pro soporta configuración de ficheros YAML y otras caracterĆ­sticas SSO.", + "ssoAdvert": "ĀæBusca mĆ”s funciones de administración de usuarios? Consulte Stirling PDF Pro" + }, + "analytics": { + "title": "ĀæQuieres mejorar Stirling PDF?", + "paragraph1": "Stirling PDF ha optado por analĆ­ticas para ayudarnos a mejorar el producto. No rastreamos ninguna información personal ni contenido de archivos.", + "paragraph2": "Considere habilitar analĆ­ticas para ayudar a Stirling-PDF a crecer y permitirnos comprender mejor a nuestros usuarios.", + "enable": "Habilitar analĆ­ticas", + "disable": "Deshabilitar analĆ­ticas", + "settings": "Puede cambiar la configuración de analĆ­ticas en el archivo config/settings.yml" + }, + "navbar": { + "favorite": "Favoritos", + "recent": "Nuevo y recientemente actualizado", + "darkmode": "Modo oscuro", + "language": "Idiomas", + "settings": "Configuración", + "allTools": "Herramientas", + "multiTool": "Multi-herramientas", + "search": "Buscar", + "sections": { + "organize": "Organizar", + "convertTo": "Convertir a PDF", + "convertFrom": "Convertir desde PDF", + "security": "SeƱalización y seguridad", + "advance": "Avanzado", + "edit": "Ver y Editar", + "popular": "Populares" + } + }, + "settings": { + "title": "Configuración", + "update": "Actualización disponible", + "updateAvailable": "{0} es la versión instalada. Hay disponible una versión nueva ({1}).", + "appVersion": "Versión de la aplicación:", + "downloadOption": { + "title": "Elegir la opción de descarga (para descargas de un solo archivo sin ZIP):", + "1": "Abrir en la misma ventana", + "2": "Abrir en una nueva ventana", + "3": "Descargar el archivo" + }, + "zipThreshold": "Archivos ZIP cuando excede el nĆŗmero de archivos descargados", + "signOut": "Desconectar", + "accountSettings": "Configuración de la cuenta", + "bored": { + "help": "Habilita el juego del huevo de pascua" + }, + "cacheInputs": { + "name": "Guardar entradas del formulario", + "help": "Habilitar guardar entradas previamente utilizadas para futuras acciones" + } + }, + "changeCreds": { + "title": "Cambiar Credenciales", + "header": "Actualice los detalles de su cuenta", + "changePassword": "EstĆ” usando las credenciales de inicio de sesión por defecto. Por favor, introduzca una contraseƱa nueva", + "newUsername": "Nuevo usuario", + "oldPassword": "ContraseƱa actual", + "newPassword": "Nueva contraseƱa", + "confirmNewPassword": "Confirme la nueva contraseƱa", + "submit": "Enviar cambios" + }, + "account": { + "title": "Configuración de la cuenta", + "accountSettings": "Configuración de la cuenta", + "adminSettings": "Configuración de Administrador - Ver y AƱadir Usuarios", + "userControlSettings": "Configuración de control de usuario", + "changeUsername": "Cambiar nombre de usuario", + "newUsername": "nuevo nombre de usuario", + "password": "Confirmar contraseƱa", + "oldPassword": "ContraseƱa anterior", + "newPassword": "Nueva ContraseƱa", + "changePassword": "Cambiar ContraseƱa", + "confirmNewPassword": "Confirmar Nueva ContraseƱa", + "signOut": "Cerrar sesión", + "yourApiKey": "Su clave API", + "syncTitle": "Sincronizar la configuración del navegador con la cuenta", + "settingsCompare": "Comparación de configuraciones:", + "property": "Propiedad", + "webBrowserSettings": "Configuración del navegador", + "syncToBrowser": "Sincronizar cuenta -> Navegador", + "syncToAccount": "Sincronizar cuenta <- Navegador" + }, + "adminUserSettings": { + "title": "Configuración de control de usuario", + "header": "Configuración de control de usuario administrador", + "admin": "Administrador", + "user": "Usuario", + "addUser": "AƱadir Nuevo Usuario", + "deleteUser": "Eliminar Usuario", + "confirmDeleteUser": "ĀæSe debe eliminar al usuario?", + "confirmChangeUserStatus": "ĀæSe debe habilitar/deshabilitar el usuario?", + "usernameInfo": "El nombre de usuario solo puede contener letras, nĆŗmeros y los siguientes caracteres especiales @._+- o debe ser una dirección de correo electrónico vĆ”lida.", + "roles": "Roles", + "role": "Rol", + "actions": "Acciones", + "apiUser": "Usuario limitado de API", + "extraApiUser": "Otro usuario limitado de API", + "webOnlyUser": "Usuario solo web", + "demoUser": "Usuario Demo (Sin ajustes personalizados)", + "internalApiUser": "Usuario interno de API", + "forceChange": "Forzar usuario a cambiar usuario/contraseƱa en el acceso", + "submit": "Guardar Usuario", + "changeUserRole": "Cambiar rol de usuario", + "authenticated": "Autenticado", + "editOwnProfil": "Editar el perfil actual", + "enabledUser": "usuario habilitado", + "disabledUser": "usuario deshabilitado", + "activeUsers": "Usuarios Activos:", + "disabledUsers": "Usuarios deshabilitados:", + "totalUsers": "Usuarios totales:", + "lastRequest": "Última petición", + "usage": "Ver uso" + }, + "endpointStatistics": { + "title": "EstadĆ­sticas de funciones", + "header": "EstadĆ­sticas de funciones", + "top10": "Top 10", + "top20": "Top 20", + "all": "Todas", + "refresh": "Refrescar", + "includeHomepage": "Incluir pĆ”gina de inicio ('/')", + "includeLoginPage": "Incluir pĆ”gina de inicio de sesión ('/login')", + "totalEndpoints": "Funciones totales", + "totalVisits": "Visitas totales", + "showing": "Mostrando", + "selectedVisits": "Visitas seleccionadas", + "endpoint": "Funciones", + "visits": "Visitas", + "percentage": "Porcentaje", + "loading": "Cargando...", + "failedToLoad": "Falló la carga de los datos de funciones. Por favor, recargue para volver a intentarlo.", + "home": "Inicio", + "login": "Inicio de sesión", + "top": "Lo mĆ”s usado", + "numberOfVisits": "NĆŗmero de visitas", + "visitsTooltip": "Visitas: {0} ({1}% del total)", + "retry": "Reintentar" + }, + "database": { + "title": "Base de Datos Importar/Exportar", + "header": "Base de Datos Importar/Exportar", + "fileName": "Nombre de Archivo", + "creationDate": "Fecha de creación", + "fileSize": "TamaƱo de archivo", + "deleteBackupFile": "Eliminar archivo de copia de seguridad", + "importBackupFile": "Importar archivo de copia de seguridad", + "createBackupFile": "Crear archivo de copia de seguridad", + "downloadBackupFile": "Descargar archivo de copia de seguridad", + "info_1": "Al importar datos, es fundamental garantizar la estructura correcta. Si no estĆ” seguro de lo que estĆ” haciendo, busque consejo y apoyo de un profesional. Un error en la estructura puede causar un mal funcionamiento de la aplicación, incluyendo la imposibilidad total de ejecutar la aplicación.", + "info_2": "El nombre del archivo no importa al cargarlo. Posteriormente se le cambiarĆ” el nombre para que siga el formato backup_user_yyyyMMddHHmm.sql, lo que garantiza una convención de nomenclatura coherente.", + "submit": "Importar Copia de Seguridad", + "importIntoDatabaseSuccessed": "La importación a la base de datos ha sido exitosa", + "backupCreated": "Respaldo de la Base de Datos exitoso", + "fileNotFound": "Archivo no encontrado", + "fileNullOrEmpty": "El archivo no puede ser nulo o vacĆ­o.", + "failedImportFile": "Archivo de importación fallido", + "notSupported": "Esta función no esta disponible para su conexión de Base de Datos" + }, + "session": { + "expired": "Su sesión ha caducado. Actualice la pĆ”gina e intĆ©ntelo de nuevo.", + "refreshPage": "Refrescar PĆ”gina" + }, + "home": { + "desc": "Su ventanilla Ćŗnica autohospedada para todas sus necesidades PDF", + "searchBar": "Buscar caracterĆ­sticas...", + "viewPdf": { + "title": "Ver/Editar PDF", + "desc": "Ver, anotar, aƱadir texto o imĆ”genes" + }, + "setFavorites": "Agregar Favoritos", + "hideFavorites": "Ocultar Favoritos", + "showFavorites": "Mostrar Favoritos", + "legacyHomepage": "PĆ”gina de inicio anterior", + "newHomePage": "Ā”Prueba nuestra nueva pĆ”gina de inicio!", + "alphabetical": "AlfabĆ©tico", + "globalPopularity": "Las mĆ”s populares", + "sortBy": "Ordenado por:", + "multiTool": { + "title": "Multi-herramienta PDF", + "desc": "Combinar, rotar, reorganizar y eliminar pĆ”ginas" + }, + "merge": { + "title": "Unir", + "desc": "Unir fĆ”cilmente mĆŗltiples PDFs en uno" + }, + "split": { + "title": "Dividir", + "desc": "Dividir PDFs en mĆŗltiples documentos" + }, + "rotate": { + "title": "Rotar", + "desc": "Rotar fĆ”cilmente sus PDFs" + }, + "imageToPdf": { + "title": "Imagen a PDF", + "desc": "Convertir una imagen (PNG, JPEG, GIF) a PDF" + }, + "pdfToImage": { + "title": "PDF a Imagen", + "desc": "Convertir un PDF a una imagen (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Organizador", + "desc": "Eliminar/Reorganizar pĆ”ginas en cualquier orden" + }, + "addImage": { + "title": "Agregar imagen al PDF", + "desc": "Agregar una imagen en el PDF en una ubicación establecida (en desarrollo)" + }, + "watermark": { + "title": "AƱadir marca de agua", + "desc": "AƱadir una marca de agua predefinida al documento PDF" + }, + "permissions": { + "title": "Cambiar permisos", + "desc": "Cambiar los permisos del documento PDF" + }, + "removePages": { + "title": "Eliminar", + "desc": "Eliminar pĆ”ginas no deseadas del documento PDF" + }, + "addPassword": { + "title": "AƱadir contraseƱa", + "desc": "Encriptar el documento PDF con una contraseƱa" + }, + "removePassword": { + "title": "Eliminar contraseƱa", + "desc": "Eliminar la contraseƱa del documento PDF" + }, + "compressPdfs": { + "title": "Comprimir", + "desc": "Comprimir PDFs para reducir el tamaƱo del archivo" + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Cambiar metadatos", + "desc": "Cambiar/Eliminar/AƱadir metadatos al documento PDF" + }, + "fileToPDF": { + "title": "Convertir archivo a PDF", + "desc": "Convertir casi cualquier archivo a PDF (DOCX, PNG, XLS, PPT, TXT y mĆ”s)" + }, + "ocr": { + "title": "Ejecutar OCR en PDF y/o tareas de limpieza", + "desc": "Tareas de limpieza y detectar texto en imĆ”genes dentro de un PDF y volver a incrustarlo como texto" + }, + "extractImages": { + "title": "Extraer imĆ”genes", + "desc": "Extraer todas las imĆ”genes de un PDF y guardarlas en ZIP" + }, + "pdfToPDFA": { + "title": "Convertir PDF a PDF/A", + "desc": "Convertir PDF a PDF/A para almacenamiento a largo plazo" + }, + "PDFToWord": { + "title": "PDF a Word", + "desc": "Convertir formatos PDF a Word (DOC, DOCX y ODT)" + }, + "PDFToPresentation": { + "title": "PDF a presentación", + "desc": "Convertir PDF a formatos de presentación (PPT, PPTX y ODP)" + }, + "PDFToText": { + "title": "PDF a TXT o RTF", + "desc": "Convertir PDF a formato TXT o RTF" + }, + "PDFToHTML": { + "title": "PDF a HTML", + "desc": "Convertir PDF a formato HTML" + }, + "PDFToXML": { + "title": "PDF a XML", + "desc": "Convertir PDF a formato XML" + }, + "ScannerImageSplit": { + "title": "Detectar/Dividir fotos escaneadas", + "desc": "Dividir varias fotos dentro de una foto/PDF" + }, + "sign": { + "title": "Firmar", + "desc": "AƱadir firma a PDF mediante dibujo, texto o imagen" + }, + "flatten": { + "title": "Aplanar", + "desc": "Eliminar todos los elementos y formularios interactivos de un PDF" + }, + "repair": { + "title": "Reparar", + "desc": "Intentar reparar un PDF corrupto/roto" + }, + "removeBlanks": { + "title": "Eliminar pĆ”ginas en blanco", + "desc": "Detectar y eliminar pĆ”ginas en blanco de un documento" + }, + "removeAnnotations": { + "title": "Eliminar Anotaciones", + "desc": "Eliminar todos los comentarios/anotaciones de un PDF" + }, + "compare": { + "title": "Comparar", + "desc": "Comparar y mostrar las diferencias entre 2 documentos PDF" + }, + "certSign": { + "title": "Firmar con certificado", + "desc": "Firmar un PDF con un Certificado/Clave (PEM/P12)" + }, + "removeCertSign": { + "title": "Quitar signo de certificado", + "desc": "Eliminar firma de certificado de PDF" + }, + "pageLayout": { + "title": "DiseƱo de varias pĆ”ginas", + "desc": "Unir varias pĆ”ginas de un documento PDF en una sola pĆ”gina" + }, + "scalePages": { + "title": "Escalar/ajustar tamaƱo de pĆ”gina", + "desc": "Escalar/cambiar el tamaƱo de una pagina y/o su contenido" + }, + "pipeline": { + "title": "Automatización", + "desc": "Ejecutar varias tareas a PDFs definiendo una secuencia de comandos" + }, + "add-page-numbers": { + "title": "AƱadir nĆŗmeros de pĆ”gina", + "desc": "AƱadir nĆŗmeros de pĆ”gina en un documento en una ubicación concreta" + }, + "auto-rename": { + "title": "Renombrar archivo PDF automĆ”ticamente", + "desc": "Renombrar automĆ”ticamente un archivo PDF segĆŗn el encabezamiento detectado" + }, + "adjust-contrast": { + "title": "Ajustar Color/Contraste", + "desc": "Ajustar Contraste, Saturación y Brillo de un PDF" + }, + "crop": { + "title": "Recortar PDF", + "desc": "Recortar un PDF para reducir su tamaƱo (Ā”conservando el texto!)" + }, + "autoSplitPDF": { + "title": "Auto Dividir PĆ”ginas", + "desc": "Auto Dividir PDF escaneado con código QR divsor de pĆ”gina escaneada fĆ­sicamente" + }, + "sanitizePdf": { + "title": "Desinfectar", + "desc": "Eliminar scripts y otros elementos de los archivos PDF" + }, + "URLToPDF": { + "title": "URL/PĆ”gina web a PDF", + "desc": "Convierte cualquier dirección http(s) a PDF" + }, + "HTMLToPDF": { + "title": "HTML a PDF", + "desc": "Convierte cualquier archivo HTML o ZIP a PDF" + }, + "MarkdownToPDF": { + "title": "Markdown a PDF", + "desc": "Convierte cualquier archivo Markdown a PDF" + }, + "PDFToMarkdown": { + "title": "PDF a Markdown", + "desc": "Convierte cualquier PDF a Markdown" + }, + "getPdfInfo": { + "title": "Obtener toda la información en PDF", + "desc": "Obtiene toda la información posible de archivos PDF" + }, + "extractPage": { + "title": "Extraer pĆ”gina(s)", + "desc": "Extraer las pĆ”ginas seleccionadas del PDF" + }, + "PdfToSinglePage": { + "title": "PDF a una sola pĆ”gina", + "desc": "Unir todas las pĆ”ginas del PDF en una sola pĆ”gina" + }, + "showJS": { + "title": "Mostrar Javascript", + "desc": "Busca y muestra cualquier JS contenido en un PDF" + }, + "autoRedact": { + "title": "Auto Redactar", + "desc": "Redactar automĆ”ticamente (ocultar) texto en un PDF segĆŗn el texto introducido" + }, + "redact": { + "title": "Redacción Manual", + "desc": "Redacta un PDF basado en el texto seleccionado, dibuja formas y/o pĆ”gina(s) selecionada(s)" + }, + "tableExtraxt": { + "title": "PDF a CSV", + "desc": "Extraer Tablas de un PDF convirtiĆ©ndolas a CSV" + }, + "autoSizeSplitPDF": { + "title": "Auto dividir por tamaƱo/conteo", + "desc": "Divide un solo PDF en mĆŗltiples documentos segĆŗn su tamaƱo, nĆŗmero de pĆ”ginas, o nĆŗmero de documento" + }, + "overlay-pdfs": { + "title": "Superponer PDFs", + "desc": "Superponer PDFs encima de otro PDF" + }, + "split-by-sections": { + "title": "Dividir PDF por Secciones", + "desc": "Dividir cada pĆ”gina de un PDF en secciones verticales y horizontales mĆ”s pequeƱas" + }, + "AddStampRequest": { + "title": "AƱadir Sello a PDF", + "desc": "AƱadir texto o sello de imagen en ubicaciones especĆ­ficas" + }, + "removeImagePdf": { + "title": "Eliminar imagen", + "desc": "Eliminar imagen del PDF> para reducir el tamaƱo de archivo" + }, + "splitPdfByChapters": { + "title": "Dividir PDF por capĆ­tulos", + "desc": "Divida un PDF en varios archivos segĆŗn su estructura de capĆ­tulos." + }, + "validateSignature": { + "title": "Validar firma del PDF", + "desc": "Verifica firmas digitales y certificados en los documentos PDF" + }, + "replaceColorPdf": { + "title": "Reemplazar e Invertir Color", + "desc": "Reemplaza el color del texto y el fondo en el PDF e invierte el color completo del PDF para reducir el tamaƱo del archivo" + } + }, + "viewPdf": { + "tags": "ver,leer,anotar,texto,imagen", + "title": "Ver/Editar PDF", + "header": "Ver PDF" + }, + "multiTool": { + "tags": "Multi-herramienta,Multi-operación,Interfaz de usuario,Arrastrar con un click,front end,lado del cliente", + "title": "Multi-herramienta PDF", + "header": "Multi-herramienta PDF", + "uploadPrompts": "Nombre del archivo", + "selectAll": "Seleccionar Todo", + "deselectAll": "Deseleccionar Todo", + "selectPages": "Seleccionar pĆ”gina(s)", + "selectedPages": "PĆ”gina(s) Selecccionada(s)", + "page": "PĆ”gina", + "deleteSelected": "Borrar selecionado(s)", + "downloadAll": "Exportar", + "downloadSelected": "Exportar selecionado(s)", + "insertPageBreak": "Insertar salto pĆ”gina", + "addFile": "Agregar Archivo", + "rotateLeft": "Rotar a la izquierda", + "rotateRight": "Rotar a la derecha", + "split": "Dividir", + "moveLeft": "Mover a la izquierda", + "moveRight": "Mover a la derecha", + "delete": "Borrar", + "dragDropMessage": "PĆ”gina(s) Selecccionada(s)", + "undo": "Deshacer", + "redo": "Rehacer" + }, + "merge": { + "tags": "Unir,Operaciones de pĆ”gina,Back end,Backend", + "title": "Unir", + "header": "Unir mĆŗltiples PDFs (2+)", + "sortByName": "Ordenar por nombre", + "sortByDate": "Ordenar por fecha", + "removeCertSign": "ĀæEliminar la firma digital en el archivo unido?", + "submit": "Unir" + }, + "split": { + "tags": "Operaciones de pĆ”gina,dividir,Multi-pĆ”gina,cortar,Backend", + "title": "Dividir PDF", + "header": "Dividir PDF", + "desc": { + "1": "Los nĆŗmeros que seleccione son el nĆŗmero de pĆ”gina en el que desea hacer una división", + "2": "Como tal, seleccionar 1,3,7-9 dividirĆ­a un documento de 10 pĆ”ginas en 6 archivos PDF separados con:", + "3": "Documento #1: PĆ”gina 1", + "4": "Documento #2: PĆ”ginas 2 y 3", + "5": "Documento #3: PĆ”ginas 4, 5, 6 y 7", + "6": "Documento #4: PĆ”gina 8", + "7": "Documento #5: PĆ”gina 9", + "8": "Documento #6: PĆ”gina 10" + }, + "splitPages": "Introducir las pĆ”ginas para dividir:", + "submit": "Dividir" + }, + "rotate": { + "tags": "Backend", + "title": "Rotar PDF", + "header": "Rotar PDF", + "selectAngle": "Seleccionar Ć”ngulo de rotación (en mĆŗltiplos de 90 grados):", + "submit": "Rotar" + }, + "imageToPdf": { + "tags": "conversión,img,jpg,imagen,fotografĆ­a" + }, + "pdfToImage": { + "tags": "conversión,img,jpg,imagen,fotografĆ­a", + "title": "PDF a Imagen", + "header": "PDF a Imagen", + "selectText": "Formato de Imagen", + "singleOrMultiple": "Tipo resultante de imagen", + "single": "Una Ćŗnica imagen grande", + "multi": "MĆŗltiples imĆ”genes", + "colorType": "Tipo de color", + "color": "Color", + "grey": "Escala de grises", + "blackwhite": "Blanco y Negro (Ā”Puede perder datos!)", + "submit": "Convertir", + "info": "Python no estĆ” instalado. Se requiere para la conversión WebP.", + "placeholder": "(por ejemplo 1,2,8 o 4,7,12-16 o 2n-1)" + }, + "pdfOrganiser": { + "tags": "doble cara,pares,impares,ordenar,mover", + "title": "Organizador de pĆ”ginas", + "header": "Organizador de pĆ”ginas PDF", + "submit": "Organizar pĆ”ginas", + "mode": { + "_value": "Modo", + "1": "Orden de pĆ”ginas personalizado", + "2": "Orden inverso", + "3": "Ordenar dĆŗplex", + "4": "Ordenar folleto", + "5": "Orden de folleto de encuadernado lateral", + "6": "División par-impar", + "7": "Quitar primera", + "8": "Quitar Ćŗltima", + "9": "Quitar primera y Ćŗltima", + "10": "Unir impar-par", + "11": "Duplicar todas las pĆ”ginas" + }, + "placeholder": "(por ejemplo, 1,3,2 o 4-8,2,10-12 o 2n-1)" + }, + "addImage": { + "tags": "img,jpg,imagen,fotografĆ­a", + "title": "AƱadir imagen", + "header": "AƱadir imagen de PDF", + "everyPage": "ĀæTodas las pĆ”ginas?", + "upload": "AƱadir imagen", + "submit": "Enviar imagen" + }, + "watermark": { + "tags": "Texto,repetir,etiquetar,propietario,copyright,marca comercial,img,jpg,imagen,fotografĆ­a", + "title": "AƱadir marca de agua", + "header": "AƱadir marca de agua", + "customColor": "Personalizar color de texto", + "selectText": { + "1": "Seleccionar PDF para aƱadir marca de agua:", + "2": "Texto de la marca de agua:", + "3": "TamaƱo de la Fuente:", + "4": "Rotación (0-360):", + "5": "Ancho (Espacio entre cada marca de agua horizontalmente):", + "6": "Alto (Espacio entre cada marca de agua verticalmente):", + "7": "Opacidad (0% - 100%):", + "8": "Tipo de marca de agua:", + "9": "Imagen de marca de agua:", + "10": "Convertir PDF a imagen PDF" + }, + "submit": "AƱadir marca de agua", + "type": { + "1": "Texto", + "2": "Imagen" + } + }, + "permissions": { + "tags": "leer,escribir,editar,imprimir", + "title": "Cambiar permisos", + "header": "Cambiar permisos", + "warning": "Advertencia: para que estos permisos no se puedan cambiar, se recomienda configurarlos con una contraseƱa a travĆ©s de la pĆ”gina de cambio de contraseƱa", + "selectText": { + "1": "Seleccionar PDF para cambiar los permisos", + "2": "Permisos a establecer", + "3": "Impedir el ensamblaje del documento", + "4": "Impedir la extracción de contenido", + "5": "Impedir la extracción para la accesibilidad", + "6": "Impedir rellenar formulario", + "7": "Impedir modificación", + "8": "Impedir modificación de anotaciones", + "9": "Impedir imprimir", + "10": "Impedir imprimir diferentes formatos" + }, + "submit": "Cambiar" + }, + "removePages": { + "tags": "Borrar pĆ”ginas,eliminar pĆ”ginas" + }, + "addPassword": { + "tags": "seguro,seguridad", + "title": "AƱadir contraseƱa", + "header": "AƱadir contraseƱa (encriptar)", + "selectText": { + "1": "Seleccionar PDF para encriptar", + "2": "ContraseƱa", + "3": "Longitud de la clave de cifrado", + "4": "Valores altos son mĆ”s fuertes, pero valores bajos tienen mejor compatibilidad", + "5": "Permisos para establecer", + "6": "Impedir el ensamblaje del documento", + "7": "Impedir la extracción de contenido", + "8": "Impedir la extracción para la accesibilidad", + "9": "Impedir rellenar formulario", + "10": "Impedir modificación", + "11": "Impedir modificación de anotaciones", + "12": "Impedir imprimir", + "13": "Impedir imprimir diferentes formatos", + "14": "ContraseƱa", + "15": "Restringir quĆ© se puede hacer con el documento una vez abierto (no soportado por todos los lectores)", + "16": "Restringir la apertura del propio documento" + }, + "submit": "Encriptar" + }, + "removePassword": { + "tags": "seguro,Desencriptar,seguridad,quitar contraseƱa,eliminar contraseƱa", + "title": "Eliminar contraseƱa", + "header": "Eliminar contraseƱa (desencriptar)", + "selectText": { + "1": "Seleccionar PDF para desencriptar", + "2": "ContraseƱa" + }, + "submit": "Eliminar" + }, + "compressPdfs": { + "tags": "aplastar,pequeƱo,diminuto" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "tĆ­tulo,autor,fecha,creación,hora,editorial,productor,estadĆ­sticas", + "title": "TĆ­tulo:", + "header": "Cambiar metadatos", + "selectText": { + "1": "Editar las variables que desea cambiar", + "2": "Eliminar todos los metadatos", + "3": "Mostrar metadatos personalizados:", + "4": "Otros Metadatos:", + "5": "Agregar entrada de metadatos personalizados" + }, + "author": "Autor:", + "creationDate": "Fecha de creación (aaaa/MM/dd HH:mm:ss):", + "creator": "Creador:", + "keywords": "Palabras clave:", + "modDate": "Fecha de modificación (aaaa/MM/dd HH:mm:ss):", + "producer": "Productor:", + "subject": "Asunto:", + "trapped": "Capturado:", + "submit": "Cambiar" + }, + "fileToPDF": { + "tags": "transformación,formato,documento,imagen,diapositiva,texto,conversión,office,docs,word,excel,powerpoint", + "title": "Archivo a PDF", + "header": "Convertir cualquier archivo a PDF", + "credit": "Este servicio usa LibreOffice y Unoconv para la conversión de archivos", + "supportedFileTypesInfo": "Tipos de archivos admitidos", + "supportedFileTypes": "Los tipos de archivo soportados deben incluir los indicados a continuación; sin embargo, para una completa y acutualizada lista de formatos soportados, por favor consulte la documentación de LibreOffice", + "submit": "Convertir a PDF" + }, + "ocr": { + "tags": "reconocimiento,texto,imagen,escanear,leer,identificar,detección,editable", + "title": "OCR / Escaneo de limpieza", + "header": "Escaneos de limpieza / OCR (Reconocimiento óptico de caracteres)", + "selectText": { + "1": "Seleccionar los idiomas que se detectarĆ”n en el PDF (Los enumerados son los detectados actualmente):", + "2": "Producir un archivo de texto que contenga texto OCR junto con el PDF editado con OCR", + "3": "Corregir las pĆ”ginas que se escanearon en un Ć”ngulo torcido girĆ”ndolas nuevamente a su lugar", + "4": "Limpiar la pĆ”gina para que sea menos probable que el OCR encuentre texto en el ruido de fondo (Sin cambio de salida)", + "5": "Limpiar la pĆ”gina para que sea menos probable que el OCR encuentre texto en el ruido de fondo, mantiene la limpieza en la salida.", + "6": "Ignorar las pĆ”ginas que tienen texto interactivo, solo las pĆ”ginas OCR que son imĆ”genes", + "7": "Forzar OCR, OCR eliminarĆ” en cada pĆ”gina todo el texto original", + "8": "Normal (se producirĆ” un error si el PDF contiene texto)", + "9": "Ajustes adicionales", + "10": "Modo OCR", + "11": "Eliminar imĆ”genes despuĆ©s de OCR (Elimina TODAS las imĆ”genes, solo es Ćŗtil si es parte del paso de conversión)", + "12": "Tipo de procesamiento (avanzado)" + }, + "help": "Lea esta documentación sobre cómo usar esto para otros idiomas y/o no usarlo en Docker", + "credit": "Este servicio utiliza qpdf y Tesseract para OCR", + "submit": "Procesar PDF con OCR" + }, + "extractImages": { + "tags": "imagen,fotografĆ­a,guardar,archivo,zip,capturar,coger", + "title": "Extraer imĆ”genes", + "header": "Extraer imĆ”genes", + "selectText": "Seleccionar el formato de imagen para convertir las imĆ”genes extraĆ­das", + "allowDuplicates": "Guardar imĆ”genes duplicadas", + "submit": "Extraer" + }, + "pdfToPDFA": { + "tags": "archivo,largo plazo,estĆ”ndar,conversión,almacenamiento,conservación", + "title": "PDF a PDF/A", + "header": "PDF a PDF/A", + "credit": "Este servicio usa libreoffice para la conversión a PDF/A", + "submit": "Convertir", + "tip": "Actualmente no funciona para mĆŗltiples entrada a la vez", + "outputFormat": "Formato de salida", + "pdfWithDigitalSignature": "El PDF contiene una firma digital. Ɖsta se eliminarĆ” en el siguiente paso." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformación,formato,conversión,office,microsoft,archivo del documento", + "title": "PDF a Word", + "header": "PDF a Word", + "selectText": { + "1": "Formato de archivo de salida" + }, + "credit": "Este servicio utiliza LibreOffice para la conversión de archivos", + "submit": "Convertir" + }, + "PDFToPresentation": { + "tags": "diapositivas,mostrar,office,microsoft", + "title": "PDF a presentación", + "header": "PDF a presentación", + "selectText": { + "1": "Formato de archivo de salida" + }, + "credit": "Este servicio utiliza LibreOffice para la conversión de archivos", + "submit": "Convertir" + }, + "PDFToText": { + "tags": "formato enriquecido,formato de texto enriquecido,formato de texto enriquecido", + "title": "PDF a TXT/RTF", + "header": "PDF a TXT/RTF", + "selectText": { + "1": "Formato de archivo de salida" + }, + "credit": "Este servicio utiliza LibreOffice para la conversión de archivos", + "submit": "Convertir" + }, + "PDFToHTML": { + "tags": "contenido web,amigable para navegador", + "title": "PDF a HTML", + "header": "PDF a HTML", + "credit": "Este servicio utiliza pdftohtml para la conversión de archivos", + "submit": "Convertir" + }, + "PDFToXML": { + "tags": "extracción de datos,contenido estructurado,interopersabilidad,transformación,convertir", + "title": "PDF a XML", + "header": "PDF a XML", + "credit": "Este servicio utiliza LibreOffice para la conversión de archivos", + "submit": "Convertir" + }, + "ScannerImageSplit": { + "tags": "separar,auto-detectar,escaneos,multi-foto,organizar", + "selectText": { + "1": "Umbral de Ć”ngulo:", + "2": "Establecer el Ć”ngulo absoluto mĆ­nimo requerido para rotar la imagen (predeterminado: 10).", + "3": "Tolerancia:", + "4": "Determinar el rango de variación de color alrededor del color de fondo estimado (predeterminado: 30).", + "5": "Ɓrea mĆ­nima:", + "6": "Establecer el umbral mĆ­nimo de Ć”rea para una foto (predeterminado: 10000).", + "7": "Ɓrea mĆ­nima de contorno:", + "8": "Establecer el umbral mĆ­nimo del Ć”rea de contorno para una foto", + "9": "TamaƱo del borde:", + "10": "Establece el tamaƱo del borde agregado y eliminado para evitar bordes blancos en la salida (predeterminado: 1)." + }, + "info": "Python no estĆ” instalado. Se requiere para funcionar." + }, + "sign": { + "tags": "autorizar,iniciales,firma manuscrita,texto de firma,imagen de firma", + "title": "Firmar", + "header": "Firmar archivos PDF", + "upload": "Subir imagen", + "draw": "Dibujar firma", + "text": "Entrada de texto", + "clear": "Borrar", + "add": "Agregar", + "saved": "firmas guardadas", + "save": "Guardar Firma", + "personalSigs": "Firmas Personales", + "sharedSigs": "Firmas compartidas", + "noSavedSigs": "No se encontraron firmas guardadas", + "addToAll": "Agregar a todas las pĆ”ginas", + "delete": "Eliminar", + "first": "Primera pĆ”gina", + "last": "Última pĆ”gina", + "next": "Siguiente pĆ”gina", + "previous": "PĆ”gina anterior", + "maintainRatio": "Activar/desactivar la relación de aspecto", + "undo": "Deshacer", + "redo": "Rehacer" + }, + "flatten": { + "tags": "estĆ”tica,desactivar,no interactiva,etiqueta dinĆ”mica", + "title": "Aplanar", + "header": "Acoplar archivos PDF", + "flattenOnlyForms": "Aplanar sólo formularios", + "submit": "Aplanar" + }, + "repair": { + "tags": "reparar,restaurar,corregir,recuperar", + "title": "Reparar", + "header": "Reparar archivos PDF", + "submit": "Reparar" + }, + "removeBlanks": { + "tags": "limpieza,dinĆ”mica,sin contenido,organizar", + "title": "Eliminar espacios en blanco", + "header": "Eliminar pĆ”ginas en blanco", + "threshold": "Umbral:", + "thresholdDesc": "Umbral para determinar cuĆ”n blanco debe ser un pĆ­xel blanco", + "whitePercent": "Porcentaje de blanco (%):", + "whitePercentDesc": "Porcentaje de pĆ”gina que debe ser blanca para ser eliminada", + "submit": "Eliminar espacios en blanco" + }, + "removeAnnotations": { + "tags": "comentarios,subrayar,notas,margen,eliminar", + "title": "Eliminar anotaciones", + "header": "Eliminar anotaciones", + "submit": "Eliminar" + }, + "compare": { + "tags": "diferenciar,contrastar,cambios,anĆ”lisis", + "title": "Comparar", + "header": "Comparar archivos PDF", + "highlightColor": { + "1": "Color resaltado 1:", + "2": "Color resaltado 2:" + }, + "document": { + "1": "Documento 1", + "2": "Documento 2" + }, + "submit": "Comparar", + "complex": { + "message": "Uno o ambos de los documentos proporcionados son archivos grandes; la precisión de la comparación puede disminuir." + }, + "large": { + "file": { + "message": "Uno o ambos de los documentos proporcionados son demasiado grandes para procesarse." + } + }, + "no": { + "text": { + "message": "Uno o ambos de los PDF seleccionados no contienen contenido de texto. Por favor, elija PDFs con texto para la comparación." + } + } + }, + "certSign": { + "tags": "autentificar,PEM,P12,oficial,encriptar", + "title": "Firma con certificado", + "header": "Firmar un PDF con su certificado (en desarrollo)", + "selectPDF": "Seleccione un archivo PDF para firmar:", + "jksNote": "Nota: si el tipo de certificado no estĆ” enla lista de abajo, por favor conviĆ©rtalo a un archivo almacĆ©n de claves de Java Java KeyStore (.jks) utilizando la herramienta lĆ­nea de comandos. Posteriormente, seleccione en el listado de abajo la opción archivo .jks.", + "selectKey": "Seleccione su archivo de clave privada (formato PKCS#8, podrĆ­a ser .pem o .der):", + "selectCert": "Seleccione su archivo de certificado (formato X.509, podrĆ­a ser .pem o .der):", + "selectP12": "Seleccione su archivo de almacĆ©n de claves PKCS#12 (.p12 o .pfx) (Opcional, si se proporciona, debe contener su clave privada y certificado):", + "selectJKS": "Seleccione su archivo de almacĆ©n de claves Java KeyStore (.jks or .keystore):", + "certType": "Tipo de certificado", + "password": "Introduzca su almacĆ©n de claves o contraseƱa de clave privada (si corresponde):", + "showSig": "Mostrar firma", + "reason": "Razón", + "location": "Ubicación", + "name": "Nombre", + "showLogo": "Mostrar Logotipo", + "submit": "Firmar PDF" + }, + "removeCertSign": { + "tags": "autenticar,PEM,P12,oficial,desencriptar", + "title": "Eliminar firma del certificado", + "header": "Quitar el certificado digital del PDF", + "selectPDF": "Seleccione un archivo PDF:", + "submit": "Eliminar firma" + }, + "pageLayout": { + "tags": "unir,compuesto,vista Ćŗnica,organizar", + "title": "DiseƱo de varias pĆ”ginas", + "header": "DiseƱo de varias pĆ”ginas", + "pagesPerSheet": "PĆ”ginas por hoja:", + "addBorder": "AƱadir bordes", + "submit": "Entregar" + }, + "scalePages": { + "tags": "cambiar tamaƱo,modificar,dimensionar,adaptar", + "title": "Ajustar escala de la pĆ”gina", + "header": "Adjustar escala de la pĆ”gina", + "pageSize": "TamaƱo de la pĆ”gina del documento", + "keepPageSize": "TamaƱo Original", + "scaleFactor": "Nivel de zoom (recorte) de la pĆ”gina", + "submit": "Entregar" + }, + "add-page-numbers": { + "tags": "paginar,etiquetar,organizar,indexar" + }, + "auto-rename": { + "tags": "auto-detectar,basado en el encabezamiento,organizar,re-etiquetar", + "title": "Renombrar automĆ”ticamente", + "header": "Renombrar PDF automĆ”ticamente", + "submit": "Renombrar automĆ”ticamente" + }, + "adjust-contrast": { + "tags": "corrección de color,sintonizar color,modificar,mejorar" + }, + "crop": { + "tags": "recortar,contraer,editar,forma", + "title": "Recortar", + "header": "Recortar PDF", + "submit": "Entregar" + }, + "autoSplitPDF": { + "tags": "Marcado por QR,separar,segmento de escaneo,organizar", + "title": "Dividir PDF automĆ”ticamente", + "header": "Dividir PDF automĆ”ticamente", + "description": "Imprimir, Insertar, Escanear, cargar, y dĆ©jenos sepsrar automĆ”ticamente sus documentos. No se necesita clasificación manual.", + "selectText": { + "1": "Imprimir algunas hojas divisorias desde la parte inferior (Blanco y negro estĆ” bien).", + "2": "Escanee todos sus documentos a la vez insertando la hoja divisoria entre ellos.", + "3": "Cargue un Ćŗnico archivo PDF escaneado de gran tamaƱo y deje que Stirling PDF se encargue del resto.", + "4": "Las pĆ”ginas divisorias son automĆ”ticamente detectadas y eliminadas, garantizando un buen documento final." + }, + "formPrompt": "Entregar PDF conteniendo divisores de pĆ”gina de Stirling-PDF:", + "duplexMode": "Modo DĆŗplex (Escaneado de ambas caras)", + "dividerDownload2": "Descargar 'Divisor automĆ”tico (con instrucciones).pdf'", + "submit": "Entregar" + }, + "sanitizePdf": { + "tags": "limpiar,asegurar,seguro,quitar amenazas" + }, + "URLToPDF": { + "tags": "captura web,guardar pĆ”gina,web a documento,archivo", + "title": "URL a PDF", + "header": "URL a PDF", + "submit": "Convertir", + "credit": "Utiliza WeasyPrint" + }, + "HTMLToPDF": { + "tags": "margen,contenido web,transformación,convertir", + "title": "HTML a PDF", + "header": "HTML a PDF", + "help": "Acepta archivos HTML y ZIPs conteniendo los html/css/imĆ”genes, etc, requeridas", + "submit": "Convertir", + "credit": "Utiliza WeasyPrint", + "zoom": "Nivel de zoom para mostrar la pĆ”gina web.", + "pageWidth": "Ancho de la pĆ”gina en centĆ­metros. (Dejar en blanco por defecto)", + "pageHeight": "Alto de la pĆ”gina en centĆ­metros. (Dejar en blanco por defecto)", + "marginTop": "Margen superior de la pĆ”gina en milĆ­metros. (Dejar en blanco por defecto)", + "marginBottom": "Margen inferior de la pĆ”gina en milĆ­metros. (Dejar en blanco por defecto)", + "marginLeft": "Margen izquierdo de la pĆ”gina en milĆ­metros. (Dejar en blanco por defecto)", + "marginRight": "Margen derecho de la pĆ”gina en milĆ­metros. (Dejar en blanco por defecto)", + "printBackground": "Renderizar el fondo de las pĆ”ginas web.", + "defaultHeader": "Habilitar encabezado predeterminado (Nombre y nĆŗmero de pĆ”gina)", + "cssMediaType": "Cambiar el tipo de medio CSS de la pĆ”gina.", + "none": "Ninguno", + "print": "Imprimir", + "screen": "Pantalla" + }, + "MarkdownToPDF": { + "tags": "margen,contenido web,transformación,convertir", + "title": "Markdown a PDF", + "header": "Markdown a PDF", + "submit": "Convertir", + "help": "Tarea en proceso", + "credit": "Usa WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,contenido web,transformación,convertir,md", + "title": "PDF a Markdown", + "header": "PDF a Markdown", + "submit": "Convertir" + }, + "getPdfInfo": { + "tags": "información,datos,estadĆ­sticas,estadĆ­sticas", + "title": "Obtener Información del PDF", + "header": "Obtener Información del PDF", + "submit": "Obtener Información", + "downloadJson": "Descargar JSON" + }, + "extractPage": { + "tags": "extraer" + }, + "PdfToSinglePage": { + "tags": "pĆ”gina Ćŗnica" + }, + "showJS": { + "tags": "JS", + "title": "Mostrar Javascript", + "header": "Mostrar Javascript", + "downloadJS": "Descargar Javascript", + "submit": "Mostrar" + }, + "autoRedact": { + "tags": "Redactar,Ocultar,ocultar,negro,subrayador,oculto", + "title": "Auto Censurar Texto", + "header": "Auto Censurar Texto", + "colorLabel": "Color", + "textsToRedactLabel": "Texto para Censurar (separado por lĆ­neas)", + "textsToRedactPlaceholder": "por ej. \\nConfidencial \\nAlto-Secreto", + "useRegexLabel": "Usar Regex", + "wholeWordSearchLabel": "BĆŗsqueda por palabra completa", + "customPaddingLabel": "Espaciado adicional personalizado", + "convertPDFToImageLabel": "Convertir PDF a imagen PDF (Utilizado para eliminar el texto detrĆ”s del cajetĆ­n de censura)", + "submitButton": "Enviar" + }, + "redact": { + "tags": "Redactar,Ocultar,oscurece,negro,marcador,oculto,manual", + "title": "Censurar texto Manualmente", + "header": "Censurar texto Manualmente", + "submit": "Enviar", + "textBasedRedaction": "Censura basada en texto", + "pageBasedRedaction": "Censura basada en la pĆ”gina", + "convertPDFToImageLabel": "Convertir PDF a PDF-Imagen (Utilizado para eliminar el texto detrĆ”s del cajetĆ­n de censura)", + "pageRedactionNumbers": { + "title": "PĆ”ginas", + "placeholder": "(por ejemplo 1,2,8 o 4,7,12-16 o 2n-1)" + }, + "redactionColor": { + "title": "Color del cajetĆ­n" + }, + "export": "Exportar", + "upload": "Cargar", + "boxRedaction": "Dibujar cajetĆ­n de censura", + "zoom": "Zoom", + "zoomIn": "Acercar", + "zoomOut": "Alejar", + "nextPage": "PĆ”gina siguiente", + "previousPage": "Pagina anterior", + "toggleSidebar": "Activar/desactivar barra lateral", + "showThumbnails": "Mostrar Miniaturas", + "showDocumentOutline": "Mostrar esquema del documento (doble clic para expandir/contraer elementos)", + "showAttatchments": "Mostrar Adjuntos", + "showLayers": "Mostrar Capas (doble clic para restablecer las capas a su estado inicial)", + "colourPicker": "Selector de color", + "findCurrentOutlineItem": "Resaltar el marcador", + "applyChanges": "Aplicar cambios" + }, + "tableExtraxt": { + "tags": "CSV,Extraer tabla,extraer,convertir" + }, + "autoSizeSplitPDF": { + "tags": "pdf,dividir,documento,organización" + }, + "overlay-pdfs": { + "tags": "Superponer", + "header": "Superponer archivos PDF", + "baseFile": { + "label": "Seleccione archivo PDF de base" + }, + "overlayFiles": { + "label": "Seleccione archivos PDF a superponer" + }, + "mode": { + "label": "Seleccione modo de superposición", + "sequential": "Superposición Sequencial", + "interleaved": "Superposición Intercalada", + "fixedRepeat": "Superposición de repetición fija" + }, + "counts": { + "label": "Recuento de superposición (para Modo de Repetición Fija)", + "placeholder": "Introduzca recuento separado por comas (p.ej., 2,3,1)" + }, + "position": { + "label": "Seleccione Posición de Superposición", + "foreground": "Arriba", + "background": "Fondo" + }, + "submit": "Enviar" + }, + "split-by-sections": { + "tags": "Dividir sección, Dividir, Personalizar", + "title": "Dividir PDF por Secciones", + "header": "Dividir PDF por Secciones", + "horizontal": { + "label": "Divisiones Horizontales", + "placeholder": "Introduzca el nĆŗmero de divisiones horizontales" + }, + "vertical": { + "label": "Divisiones Verticales", + "placeholder": "Introduzca el nĆŗmero de divisiones verticales" + }, + "submit": "Dividir PDF", + "merge": "Unir en Un PDF" + }, + "AddStampRequest": { + "tags": "Sello, AƱadir imagen, centrar imagen, Marca de agua, PDF, Incrustar, Personalizar", + "header": "Sellar PDF", + "title": "Sellar PDF", + "stampType": "Tipo de sello", + "stampText": "Texto del sello", + "stampImage": "Imagen de sello", + "alphabet": "Alfabeto", + "fontSize": "TamaƱo de fuente/imagen", + "rotation": "Rotación", + "opacity": "Opacidad", + "position": "Posición", + "overrideX": "Forzar coordenada X", + "overrideY": "Forzar coordenada Y", + "customMargin": "Personalizar margen", + "customColor": "Personalizar color de texto", + "submit": "Enviar" + }, + "removeImagePdf": { + "tags": "Eliminar imagen,Operaciones de pĆ”gina,Back end,Backend" + }, + "splitPdfByChapters": { + "tags": "dividir,capĆ­tulos,marcadores,organizar" + }, + "validateSignature": { + "tags": "firma,verificar,validar,pdf,certificado,firma digital,validar firma,validar certificado", + "title": "Validar firmas del PDF", + "header": "Validar firmas del PDF", + "selectPDF": "Seleccione el archivo PDF firmado", + "submit": "Validar firmas", + "results": "Resultados de la validación", + "status": { + "_value": "Estado de la validación", + "valid": "VĆ”lido", + "invalid": "InvĆ”lido" + }, + "signer": "Firmante", + "date": "Fecha", + "reason": "Motivo", + "location": "Ubicación", + "noSignatures": "No se encontraron firmas digiales en este documento", + "chain": { + "invalid": "Error en la validación de la cadena de certificados: no se puede verificar la identidad del firmante" + }, + "trust": { + "invalid": "El certificado no se encuentra en los almacenes de confianza: no se puede verificar la fuente" + }, + "cert": { + "expired": "Certificado expiredo", + "revoked": "Certificado fue revocado", + "info": "Detalles Certificado", + "issuer": "Emisor", + "subject": "Asunto", + "serialNumber": "NĆŗmero de Serie", + "validFrom": "VĆ”lido desde", + "validUntil": "VĆ”lido hasta", + "algorithm": "Algoritmo", + "keySize": "TamaƱo de la clave", + "version": "Versión", + "keyUsage": "Uso de la clave", + "selfSigned": "Autofirmado", + "bits": "bits" + }, + "signature": { + "info": "Información de la firma", + "_value": "Firma", + "mathValid": "La firma es matemĆ”ticamente vĆ”lida aunque:" + }, + "selectCustomCert": "Archivo de certificado personalizado X.509 (opcional)" + }, + "replace-color": { + "title": "Reemplazar-Invertir-Color", + "header": "Reemplazar-Invertir Color en PDF", + "selectText": { + "1": "Opciones para Reemplazar o Invertir color", + "2": "Predeterminado (Colores de alto contraste predeterminados)", + "3": "Personalizado (Colores personalizados)", + "4": "Invertir Completo (Invertir todos los colores)", + "5": "Opciones de color de alto contraste", + "6": "Texto blanco sobre fondo negro", + "7": "Texto negro sobre fondo blanco", + "8": "Texto amarillo sobre fondo negro", + "9": "Texto verde sobre fondo negro", + "10": "Elegir Color de Texto", + "11": "Elegir Color de Fondo" + }, + "submit": "Reemplazar" + }, + "replaceColorPdf": { + "tags": "Reemplazar Color,Operaciones de PĆ”gina,Back end,Backend" + }, + "login": { + "title": "Iniciar sesión", + "header": "Iniciar sesión", + "signin": "Iniciar sesión", + "rememberme": "Recordarme", + "invalid": "Nombre de usuario o contraseƱa erróneos.", + "locked": "Su cuenta se ha bloqueado.", + "signinTitle": "Por favor, inicie sesión", + "ssoSignIn": "Iniciar sesión a travĆ©s del inicio de sesión Ćŗnico", + "oAuth2AutoCreateDisabled": "Usuario de creación automĆ”tica de OAUTH2 DESACTIVADO", + "oAuth2AdminBlockedUser": "El registro o inicio de sesión de usuarios no registrados estĆ” actualmente bloqueado. Por favor, póngase en contacto con el administrador.", + "oauth2RequestNotFound": "Solicitud de autorización no encontrada", + "oauth2InvalidUserInfoResponse": "Respuesta de información de usuario no vĆ”lida", + "oauth2invalidRequest": "Solicitud no vĆ”lida", + "oauth2AccessDenied": "Acceso denegado", + "oauth2InvalidTokenResponse": "Respuesta de token no vĆ”lida", + "oauth2InvalidIdToken": "Token de identificación no vĆ”lido", + "relyingPartyRegistrationNotFound": "No hay registro de terceros confiables", + "userIsDisabled": "El usuario estĆ” desactivado, actualmente el acceso estĆ” bloqueado para ese nombre de usuario. Por favor, póngase en contacto con el administrador.", + "alreadyLoggedIn": "Ya ha iniciado sesión en", + "alreadyLoggedIn2": "dispositivos. Cierre sesión en los dispositivos y vuelva a intentarlo.", + "toManySessions": "Tiene demasiadas sesiones activas", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF a pĆ”gina Ćŗnica", + "header": "PDF a pĆ”gina Ćŗnica", + "submit": "Convertir a pĆ”gina Ćŗnica" + }, + "pageExtracter": { + "title": "Extraer PĆ”ginas", + "header": "Extraer PĆ”ginas", + "submit": "Extraer", + "placeholder": "(por ejemplo, 1,2,8 o 4,7,12-16 o 2n-1)" + }, + "sanitizePDF": { + "title": "Limpiar archivo PDF", + "header": "Limpiar un archivo PDF", + "selectText": { + "1": "Eliminar código JavaScript", + "2": "Eliminar archivos incrustados", + "3": "Eliminar metadatos XMP", + "4": "Eliminar enlaces", + "5": "Eliminar fuentes", + "6": "Eliminar metadatos asociados al documento" + }, + "submit": "Limpiar PDF" + }, + "adjustContrast": { + "title": "Ajustar Contraste", + "header": "Ajustar Contraste", + "contrast": "Contraste:", + "brightness": "Brillo:", + "saturation": "Saturación:", + "download": "Descargar" + }, + "compress": { + "title": "Comprimir", + "header": "Comprimir PDF", + "credit": "Este servicio utiliza qpdf para compresión/optimización de PDF", + "grayscale": { + "label": "Aplicar escala de grises para compresión" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 compresión PDF,
4-6 compresión de imagen suave,
7-9 compresión de imĆ”genes intensa reducirĆ” drĆ”sticamente la calidad de imagen" + }, + "2": "Nivel de optimización:", + "4": "Modo automĆ”tico: ajusta automĆ”ticamente la calidad para que el PDF tenga el tamaƱo exacto", + "5": "TamaƱo esperado del PDF (por ejemplo, 25 MB, 10.8 MB, 25 KB)" + }, + "submit": "Comprimir" + }, + "decrypt": { + "passwordPrompt": "Este archivo estĆ” protegido con contraseƱa. IntrodĆŗzca la contraseƱa:", + "cancelled": "Operación cancelada para el PDF: {0}", + "noPassword": "No se proporcionó contraseƱa para PDF cifrado: {0}", + "invalidPassword": "Por favor, intĆ©ntelo de nuevo con la contraseƱa correcta.", + "invalidPasswordHeader": "ContraseƱa incorrecta o cifrado no compatible para PDF: {0}", + "unexpectedError": "Se produjo un error al procesar el archivo. IntĆ©ntalo nuevamente.", + "serverError": "Error del servidor al descifrar: {0}", + "success": "Archivo descifrado exitosamente." + }, + "multiTool-advert": { + "message": "Esta función tambiĆ©n estĆ” disponible en nuestra pĆ”gina de herramientas mĆŗltiples. Ӄchale un vistazo para ver una interfaz de usuario pĆ”gina por pĆ”gina mejorada y funciones adicionales!" + }, + "pageRemover": { + "title": "Eliminador de pĆ”ginas", + "header": "Eliminador de pĆ”ginas PDF", + "pagesToDelete": "PĆ”ginas a eliminar (introducir una lista de nĆŗmeros de pĆ”gina separados por coma):", + "submit": "Eliminar PĆ”ginas", + "placeholder": "(por ejemplo 1,2,6 o 1-10,15-30)" + }, + "imageToPDF": { + "title": "Imagen a PDF", + "header": "Imagen a PDF", + "submit": "Convertir", + "selectLabel": "Opciones de ajuste de imagen", + "fillPage": "Ocupar toda la pĆ”gina", + "fitDocumentToImage": "Ajustar pĆ”gina a imagen", + "maintainAspectRatio": "Mantener relación de aspecto", + "selectText": { + "2": "Rotación automĆ”tica del PDF", + "3": "Lógica de archivos mĆŗltiples (Ćŗnicamente activado si funciona con multiples imĆ”genes)", + "4": "Unir en un Ćŗnico archivo PDF", + "5": "Convertir a PDFs separados" + } + }, + "PDFToCSV": { + "title": "PDF a CSV", + "header": "PDF a CSV", + "prompt": "Elija una pĆ”gina para extraer la tabla", + "submit": "Extraer" + }, + "split-by-size-or-count": { + "title": "Dividir PDF por tamaƱo o cantidad", + "header": "Dividir PDF por tamaƱo o nĆŗmero", + "type": { + "label": "Seleccionar tipo de división", + "size": "Por tamaƱo", + "pageCount": "Por nĆŗmero de pĆ”ginas", + "docCount": "por recuento de documentos" + }, + "value": { + "label": "Introduzca valor", + "placeholder": "Introduzca tamaƱo (p.ej., 2MB o 3KB) or recuento (p.ej., 5)" + }, + "submit": "Enviar" + }, + "printFile": { + "title": "Imprimir archivo", + "header": "Imprimir archivo en la impresora", + "selectText": { + "1": "Seleccionar archivo para imprimir", + "2": "Introducir nombre de la impresora" + }, + "submit": "Imprimir" + }, + "licenses": { + "nav": "Licencias", + "title": "Licencias de terceros", + "header": "Licencias de terceros", + "module": "Módulo", + "version": "Versión", + "license": "Licencia" + }, + "survey": { + "nav": "Encuesta", + "title": "Encuesta Stirling-PDF", + "description": "Stirling-PDF no tiene seguimiento, por lo que queremos escuchar a nuestros usuarios para mejorar Stirling-PDF.", + "changes": "Ā”Stirling-PDF ha cambiado desde la Ćŗltima encuesta! Para obtener mĆ”s información, revise nuestro artĆ­culo de blog aquĆ­:", + "changes2": "Con estos cambios estamos obteniendo apoyo y financiamiento empresarial", + "please": "Ā”Considere realizar nuestra encuesta!", + "disabled": "(La ventana emergente de la encuesta se desactivarĆ” en las siguientes actualizaciones, pero estarĆ” disponible al pie de la pĆ”gina.)", + "button": "Realizar encuesta", + "dontShowAgain": "No volver a mostrar", + "meeting": { + "1": "Si estĆ” utilizando Stirling-PDF en el trabajo, nos encantarĆ­a hablar con usted. Ofrecemos sesiones de soporte tĆ©cnico a cambio de una sesión de descubrimiento de usuario de 15 minutos.", + "2": "Es una oportunidad para:", + "3": "Obtenga ayuda con la implementación, integraciones o solución de problemas", + "4": "Brinde comentarios directos sobre el rendimiento, casos extremos y carencia de funciones", + "5": "AyĆŗdenos a mejorar Stirling-PDF para su uso en entornos empresariales reales", + "6": "Si estĆ” interesado, puede agendar una reunión con nuestro equipo directamente. (Sólo en inglĆ©s)", + "7": "Ā”Esperamos conocer sus casos de uso y mejorar aĆŗn mĆ”s Stirling-PDF!", + "notInterested": "ĀæNo es una empresa o no estĆ” interesado en una reunión?", + "button": "Reservar reunión" + } + }, + "removeImage": { + "title": "Eliminar imagen", + "header": "Eliminar imagen", + "removeImage": "Eliminar imagen", + "submit": "Eliminar imagen" + }, + "splitByChapters": { + "title": "Dividir PDF por CapĆ­tulos", + "header": "Dividir PDF por CapĆ­tulos", + "bookmarkLevel": "Nivel de Marcador", + "includeMetadata": "Incluir Metadatos", + "allowDuplicates": "Permitir Duplicados", + "desc": { + "1": "Esta herramienta divide un archivo PDF en mĆŗltiples archivos PDF segĆŗn su estructura de capĆ­tulos.", + "2": "Nivel de Marcador: Elige el nivel de marcadores para dividir (0 para el nivel superior, 1 para el segundo nivel, etc.).", + "3": "Incluir Metadatos: Si estĆ” seleccionado, los metadatos del PDF original se incluirĆ”n en cada PDF dividido.", + "4": "Permitir Duplicados: Si estĆ” seleccionado, permite que mĆŗltiples marcadores en la misma pĆ”gina creen archivos PDF separados." + }, + "submit": "Dividir PDF" + }, + "fileChooser": { + "click": "Click", + "or": "o", + "dragAndDrop": "Arrastrar & Soltar", + "dragAndDropPDF": "Arrastrar & Soltar archivo PDF", + "dragAndDropImage": "Arrastrar & Soltar archivo de Imagen", + "hoveredDragAndDrop": "Arrastrar & Soltar archivos(s) aquĆ­", + "extractPDF": "Extrayendo..." + }, + "releases": { + "footer": "Versiones", + "title": "Notas de la versión", + "header": "Notas de la versión", + "current": { + "version": "versión Actual" + }, + "note": "Las notas de la versión solo estĆ”n disponibles en InglĆ©s" + }, + "cookieBanner": { + "popUp": { + "title": "Cómo usamos las cookies", + "description": { + "1": "Usamos cookies y otras tecnologĆ­as para optimizar el funcionamiento de Stirling PDF, lo que contribuye a mejorar nuestras herramientas y a seguir desarrollando funciones que serĆ”n de su interĆ©s.", + "2": "Si prefiere no hacerlo, al hacer clic en 'No gracias' se activarĆ”n Ćŗnicamente las cookies esenciales necesarias para que todo funcione correctamente." + }, + "acceptAllBtn": "De acuerdo", + "acceptNecessaryBtn": "No, gracias", + "showPreferencesBtn": "Gestionar preferencias" + }, + "preferencesModal": { + "title": "Centro de Preferencias de Consentimiento", + "acceptAllBtn": "Aceptar todo", + "acceptNecessaryBtn": "Rechazar todo", + "savePreferencesBtn": "Guardar preferencias", + "closeIconLabel": "Cerrar diĆ”logo", + "serviceCounterLabel": "Servicio|Servicios", + "subtitle": "Uso de cookies", + "description": { + "1": "Stirling PDF utiliza cookies y tecnologĆ­as similares para mejorar su experiencia y entender cómo se usan nuestras herramientas. Esto nos ayuda a mejorar el rendimiento, desarrollar las funciones que le interesan y proporcionar soporte continuo a nuestros usuarios.", + "2": "Stirling PDF no puede—y nunca podrÔ—rastrear ni acceder al contenido de los documentos que utiliza.", + "3": "Su privacidad y confianza son el nĆŗcleo de lo que hacemos." + }, + "necessary": { + "title": { + "1": "Cookies estrictsamente necesarias", + "2": "Siempre activado" + }, + "description": "Estas cookies son esenciales para que el sitio web funcione correctamente. Permiten funciones bĆ”sicas como configurar sus preferencias de privacidad, iniciar sesión y completar formularios, por lo que no se pueden desactivar." + }, + "analytics": { + "title": "AnĆ”lisis", + "description": "Estas cookies nos ayudan a entender cómo se estĆ”n utilizando nuestras herramientas, para que podamos centrarnos en desarrollar las funciones que nuestra comunidad valora mĆ”s. Tenga la seguridad de que Stirling PDF no puede y nunca podrĆ” rastrear el contenido de los documentos con los que trabaja." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/eu-ES/translation.json b/frontend/public/locales/eu-ES/translation.json new file mode 100644 index 000000000..19ffcd85b --- /dev/null +++ b/frontend/public/locales/eu-ES/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Font Size", + "fontName": "Font Name", + "title": "Gehitu orrialde-zenbakiak", + "header": "Gehitu orrialde-zenbakiak", + "selectText": { + "1": "Aukeratu PDF fitxategia:", + "2": "Marjinaren tamaina", + "3": "Posizioa", + "4": "Hasiera-zenbakia", + "5": "Orrialde kopurua", + "6": "Testu pertsonalizatua" + }, + "customTextDesc": "Testu pertsonalizatua", + "numberPagesDesc": "Zein orri numeratu, lehenetsita 'denak', 1-5 edo 2,5,9 etab onartzen ditu", + "customNumberDesc": "Lehenetsoa {n}-ra, '{n} orria {total}-tik', 'Text-{n}', '{filename}-{n}' ere onartzen du", + "submit": "Gehitu orrialde-zenbakiak" + }, + "pdfPrompt": "Hautatu PDFa(k)", + "multiPdfPrompt": "Hautatu PDFak (2+)", + "multiPdfDropPrompt": "Hautatu (edo arrastatu eta jaregin) nahi dituzun PDFak", + "imgPrompt": "Hautatu Irudia(k)", + "genericSubmit": "Bidali", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Oharra: prozesu honetarako minutu bat ere beharko da fitxategiaren tamaiaren arabera", + "pageOrderPrompt": "Orrialdeen ordena (sartu komaz bereizitako orrialde-zenbakien zerrenda)", + "pageSelectionPrompt": "Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :", + "goToPage": "Joan", + "true": "Egiazkoa", + "false": "Faltsua", + "unknown": "Ezezaguna", + "save": "Gorde", + "saveToBrowser": "Save to Browser", + "close": "Itxi", + "filesSelected": "Hautatutako fitxategiak", + "noFavourites": "Ez dira gogokoak gehitu", + "downloadComplete": "Download Complete", + "bored": "Itxaroten aspertuta?", + "alphabet": "Alfabetoa", + "downloadPdf": "PDFa deskargatu", + "text": "Testua", + "font": "Letra-tipoa", + "selectFillter": "-- Aukeratu filtroa --", + "pageNum": "Orrialde-zenbakia", + "sizes": { + "small": "Txikia", + "medium": "Erdikoa", + "large": "Handia", + "x-large": "Oso handia" + }, + "error": { + "pdfPassword": "PDF dokumentua pasahitzarekin babestuta dago eta pasahitza ez da sartu edo okerra da", + "_value": "Error", + "sorry": "Sorry for the issue!", + "needHelp": "Need help / Found an issue?", + "contactTip": "If you're still having trouble, don't hesitate to reach out to us for help. You can submit a ticket on our GitHub page or contact us through Discord:", + "404": { + "head": "404 - Page Not Found | Oops, we tripped in the code!", + "1": "We can't seem to find the page you're looking for.", + "2": "Something went wrong" + }, + "github": "Submit a ticket on GitHub", + "showStack": "Show Stack Trace", + "copyStack": "Copy Stack Trace", + "githubSubmit": "GitHub - Submit a ticket", + "discordSubmit": "Discord - Submit Support post" + }, + "delete": "ezabatu", + "username": "Erabiltzaile izena", + "password": "Pasahitza", + "welcome": "Ongi etorria", + "property": "Propietate", + "black": "Beltza", + "white": "Txuria", + "red": "Gorria", + "green": "Berdea", + "blue": "Urdina", + "custom": "Pertsonalizatu...", + "WorkInProgess": "Work in progress, May not work or be buggy, Please report any problems!", + "poweredBy": "Powered by", + "yes": "Yes", + "no": "No", + "changedCredsMessage": "Credentials changed!", + "notAuthenticatedMessage": "User not authenticated.", + "userNotFoundMessage": "User not found.", + "incorrectPasswordMessage": "Current password is incorrect.", + "usernameExistsMessage": "New Username already exists.", + "invalidUsernameMessage": "Invalid username, username can only contain letters, numbers and the following special characters @._+- or must be a valid email address.", + "invalidPasswordMessage": "The password must not be empty and must not have spaces at the beginning or end.", + "confirmPasswordErrorMessage": "New Password and Confirm New Password must match.", + "deleteCurrentUserMessage": "Cannot delete currently logged in user.", + "deleteUsernameExistsMessage": "The username does not exist and cannot be deleted.", + "downgradeCurrentUserMessage": "Ezin da uneko erabiltzailearen rola jaitsi", + "disabledCurrentUserMessage": "The current user cannot be disabled", + "downgradeCurrentUserLongMessage": "Ezin da uneko erabiltzailearen rola jaitsi. Beraz, oraingo erabiltzailea ez da erakutsiko.", + "userAlreadyExistsOAuthMessage": "The user already exists as an OAuth2 user.", + "userAlreadyExistsWebMessage": "The user already exists as an web user.", + "oops": "Oops!", + "help": "Help", + "goHomepage": "Go to Homepage", + "joinDiscord": "Join our Discord server", + "seeDockerHub": "See Docker Hub", + "visitGithub": "Visit Github Repository", + "donate": "Donate", + "color": "Color", + "sponsor": "Sponsor", + "info": "Info", + "pro": "Pro", + "page": "Page", + "pages": "Pages", + "loading": "Loading...", + "addToDoc": "Add to Document", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Privacy Policy", + "terms": "Terms and Conditions", + "accessibility": "Accessibility", + "cookie": "Cookie Policy", + "impressum": "Impressum", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Pipeline Menu (Beta)", + "uploadButton": "Upload Custom", + "configureButton": "Configure", + "defaultOption": "Custom", + "submitButton": "Submit", + "help": "Pipeline Help", + "scanHelp": "Folder Scanning Help", + "deletePrompt": "Are you sure you want to delete pipeline", + "tags": "automate,sequence,scripted,batch-process", + "title": "Hodia" + }, + "pipelineOptions": { + "header": "Pipeline Configuration", + "pipelineNameLabel": "Pipeline Name", + "saveSettings": "Save Operation Settings", + "pipelineNamePrompt": "Enter pipeline name here", + "selectOperation": "Select Operation", + "addOperationButton": "Add operation", + "pipelineHeader": "Pipeline:", + "saveButton": "Download", + "validateButton": "Validate" + }, + "enterpriseEdition": { + "button": "Upgrade to Pro", + "warning": "This feature is only available to Pro users.", + "yamlAdvert": "Stirling PDF Pro supports YAML configuration files and other SSO features.", + "ssoAdvert": "Looking for more user management features? Check out Stirling PDF Pro" + }, + "analytics": { + "title": "Do you want make Stirling PDF better?", + "paragraph1": "Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.", + "paragraph2": "Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.", + "enable": "Enable analytics", + "disable": "Disable analytics", + "settings": "You can change the settings for analytics in the config/settings.yml file" + }, + "navbar": { + "favorite": "Favorites", + "recent": "New and recently updated", + "darkmode": "Modu iluna", + "language": "Languages", + "settings": "Ezarpenak", + "allTools": "Tools", + "multiTool": "Multi Tools", + "search": "Search", + "sections": { + "organize": "Organize", + "convertTo": "Convert to PDF", + "convertFrom": "Convert from PDF", + "security": "Sign & Security", + "advance": "Advanced", + "edit": "View & Edit", + "popular": "Popular" + } + }, + "settings": { + "title": "Ezarpenak", + "update": "Eguneratze eskuragarria", + "updateAvailable": "{0} is the current installed version. A new version ({1}) is available.", + "appVersion": "Aplikazioaren bertsioa:", + "downloadOption": { + "title": "Hautatu deskargatzeko aukera (fitxategi bakarra deskargatzeko ZIP gabe):", + "1": "Ireki leiho berean", + "2": "Ireki leiho berrian", + "3": "Deskargatu fitxategia" + }, + "zipThreshold": "ZIP fitxategiak deskargatutako fitxategi kopurua gainditzen denean", + "signOut": "Saioa itxi", + "accountSettings": "Kontuaren ezarpenak", + "bored": { + "help": "Enables easter egg game" + }, + "cacheInputs": { + "name": "Save form inputs", + "help": "Enable to store previously used inputs for future runs" + } + }, + "changeCreds": { + "title": "Change Credentials", + "header": "Update Your Account Details", + "changePassword": "You are using default login credentials. Please enter a new password", + "newUsername": "New Username", + "oldPassword": "Current Password", + "newPassword": "New Password", + "confirmNewPassword": "Confirm New Password", + "submit": "Submit Changes" + }, + "account": { + "title": "Kontuaren ezarpenak", + "accountSettings": "Kontuaren ezarpenak", + "adminSettings": "Admin ezarpenak - Ikusi eta gehitu Erabiltzaileak", + "userControlSettings": "Erabiltzaile ezarpen kontrolak", + "changeUsername": "Aldatu erabiltzaile izena", + "newUsername": "Erabiltzaile izen berria", + "password": "Konfirmatu pasahitza", + "oldPassword": "Pasahitz zaharra", + "newPassword": "Pasahitz berria", + "changePassword": "Aldatu pasahitza", + "confirmNewPassword": "Konfirmatu pasahitz berria", + "signOut": "Saioa itxi", + "yourApiKey": "Zure API Key", + "syncTitle": "Sinkronizatu nabigatzailearen ezarpenak zure kontuarekin", + "settingsCompare": "Ezarpenen konparaketa:", + "property": "Propietatea", + "webBrowserSettings": "Web nabigatzailearen ezarpenak", + "syncToBrowser": "Sync Kontua -> Nabigatzailea", + "syncToAccount": "Sync Kontua <- Nabigatzailea" + }, + "adminUserSettings": { + "title": "Erabiltzailearen Ezarpenen Kontrolak", + "header": "Admin Erabiltzailearen Ezarpenen Kontrolak", + "admin": "Admin", + "user": "Erabiltzaile", + "addUser": "Erabiltzaile berria", + "deleteUser": "Delete User", + "confirmDeleteUser": "Should the user be deleted?", + "confirmChangeUserStatus": "Should the user be disabled/enabled?", + "usernameInfo": "Username can only contain letters, numbers and the following special characters @._+- or must be a valid email address.", + "roles": "Rolak", + "role": "Rol", + "actions": "Ekintzak", + "apiUser": "APIren erabiltzaile mugatua", + "extraApiUser": "Additional Limited API User", + "webOnlyUser": "Web-erabiltzailea bakarrik", + "demoUser": "Demo User (No custom settings)", + "internalApiUser": "Internal API User", + "forceChange": "Force user to change password on login", + "submit": "Gorde Erabiltzailea", + "changeUserRole": "Erabiltzailearen rola aldatu", + "authenticated": "Authenticated", + "editOwnProfil": "Edit own profile", + "enabledUser": "enabled user", + "disabledUser": "disabled user", + "activeUsers": "Active Users:", + "disabledUsers": "Disabled Users:", + "totalUsers": "Total Users:", + "lastRequest": "Last Request", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Database Import/Export", + "header": "Database Import/Export", + "fileName": "File Name", + "creationDate": "Creation Date", + "fileSize": "File Size", + "deleteBackupFile": "Delete Backup File", + "importBackupFile": "Import Backup File", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Download Backup File", + "info_1": "When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.", + "info_2": "The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.", + "submit": "Import Backup", + "importIntoDatabaseSuccessed": "Import into database successed", + "backupCreated": "Database backup successful", + "fileNotFound": "File not Found", + "fileNullOrEmpty": "File must not be null or empty", + "failedImportFile": "Failed Import File", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "Your session has expired. Please refresh the page and try again.", + "refreshPage": "Refresh Page" + }, + "home": { + "desc": "Zure leihatila bakarra autoostatatua zure PDF behar guztietarako", + "searchBar": "Search for features...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "View, annotate, add text or images" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "Erabilera anitzeko tresna PDF", + "desc": "Orriak konbinatu, biratu, berrantolatu eta ezabatu" + }, + "merge": { + "title": "Elkartu", + "desc": "Elkartu zenbait PDF dokumentu bakar batean modu errazean" + }, + "split": { + "title": "Zatitu", + "desc": "Zatitu PDFak zenbait dokumentutan" + }, + "rotate": { + "title": "Biratu", + "desc": "Biratu PDFak modu errazean" + }, + "imageToPdf": { + "title": "Irudia PDF bihurtu", + "desc": "Irudi bat(PNG, JPEG, GIF)PDF bihurtu" + }, + "pdfToImage": { + "title": "PDFa irudi bihurtu", + "desc": "PDF bat irudi (PNG, JPEG, GIF) bihurtu" + }, + "pdfOrganiser": { + "title": "Antolatzailea", + "desc": "Ezabatu/Berrantolatu orrialdeak edozein ordenatan" + }, + "addImage": { + "title": "Gehitu irudia PDFari", + "desc": "Gehitu irudi bat PDFan ezarritako kokaleku batean (lanean)" + }, + "watermark": { + "title": "Gehitu ur-marka", + "desc": "Gehitu aurrez zehaztutako ur-marka bat PFD dokumentuari" + }, + "permissions": { + "title": "Aldatu baimenak", + "desc": "Aldatu PDF dokumentuaren baimenak" + }, + "removePages": { + "title": "Ezabatu", + "desc": "Ezabatu nahi ez dituzun orrialdeak PDF dokumentutik" + }, + "addPassword": { + "title": "Gehitu pasahitza", + "desc": "Enkriptatu PDF dokumentua pasahitz batekin" + }, + "removePassword": { + "title": "Ezabatu pasahitza", + "desc": "Ezabatu pasahitza PDF dokumentutik" + }, + "compressPdfs": { + "title": "Konprimatu", + "desc": "Konprimatu PDFak fitxategiaren tamaina murrizteko" + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Aldatu metadatuak", + "desc": "Aldatu/Ezabatu/Gehitu metadatuak PDF dokumentuari" + }, + "fileToPDF": { + "title": "Fitxategia PDF bihurtu", + "desc": "PDF bihurtu ia edozein fitxategi (DOCX, PNG, XLS, PPT, TXT eta gehiago)" + }, + "ocr": { + "title": "OCR exekutatu PDFan eta/edo garbiketa-eskaneatzeak", + "desc": "Garbiketa-eskaneatzeak eta irudi-testuak detektatu PDF baten barruan eta berriz ere gehitu testu gisa" + }, + "extractImages": { + "title": "Atera irudiak", + "desc": "Atera irudi guztiak PDF batetik eta ZIPen gorde" + }, + "pdfToPDFA": { + "title": "PDFa PDF/A bihurtu", + "desc": "PDFa PDF/A bihurtu luzaro biltegiratzeko" + }, + "PDFToWord": { + "title": "PDFa Word Bihurtu", + "desc": "PDF formatuak Word bihurtu (DOC, DOCX y ODT)" + }, + "PDFToPresentation": { + "title": "PDFa aurkezpen bihurtu", + "desc": "PDFa aurkezpen formatu bihurtu (PPT, PPTX y ODP)" + }, + "PDFToText": { + "title": "PDFa TXT edo RTF bihurtu", + "desc": "PDFa TXT edo RTF formatu bihurtu" + }, + "PDFToHTML": { + "title": "PDFa HTML bihurtu", + "desc": "PDFa HTML formatu bihurtu" + }, + "PDFToXML": { + "title": "PDFa XML bihurtu", + "desc": "PDFa XML formatu bihurtu" + }, + "ScannerImageSplit": { + "title": "Detektatu/Zatitu argazki eskaneatuak", + "desc": "Hainbat argazki zatitu argazki/PDF baten barruan" + }, + "sign": { + "title": "Sinatu", + "desc": "Gehitu sinadura PDFari marrazki, testu edo irudi bidez" + }, + "flatten": { + "title": "Lautu", + "desc": "PDF batetik elementu eta inprimaki interaktibo guztiak ezabatu" + }, + "repair": { + "title": "Konpondu", + "desc": "Saiatu PDF hondatu/kaltetu bat konpontzen" + }, + "removeBlanks": { + "title": "Ezabatu orrialde zuriak", + "desc": "Detektatu orrialde zuriak eta dokumentutik ezabatu" + }, + "removeAnnotations": { + "title": "Remove Annotations", + "desc": "Removes all comments/annotations from a PDF" + }, + "compare": { + "title": "Konparatu", + "desc": "Konparatu eta erakutsi 2 PDF dokumenturen aldeak" + }, + "certSign": { + "title": "Sinatu ziurtagiriarekin", + "desc": "Sinatu PDF bat Ziurtagiri/Gako batekin (PEM/P12)" + }, + "removeCertSign": { + "title": "Remove Certificate Sign", + "desc": "Remove certificate signature from PDF" + }, + "pageLayout": { + "title": "Zenbait orrialderen diseinua", + "desc": "Elkartu orri bakar batean PDF dokumentu baten zenbait orrialde" + }, + "scalePages": { + "title": "Eskalatu/Doitu orrialdearen tamaina", + "desc": "Eskalatu/Aldatu orrialde baten tamaina eta/edo edukia" + }, + "pipeline": { + "title": "Hodia (Aurreratua)", + "desc": "Egin hainbat ekintza PDFn, hodi-script-ak definituz" + }, + "add-page-numbers": { + "title": "Gehitu orrialde-zenbakiak", + "desc": "Gehitu orrialde-zenbakiak dokumentu batean, kokapen jakin batean" + }, + "auto-rename": { + "title": "Auto Aldatu PDF fitxategiaren izena", + "desc": "Automatikoki izena ematen dio detektatutako goiburuan oinarritutako PDF fitxategi bati" + }, + "adjust-contrast": { + "title": "Koloreak/kontrastea doitu", + "desc": "PDF baten kontrastea, saturazioa eta distira doitzea" + }, + "crop": { + "title": "Moztu PDF", + "desc": "Egin klik PDFn tamaina txikitzeko (textua mantentzen du!)" + }, + "autoSplitPDF": { + "title": "Orriak automatikoki banandu", + "desc": "Auto Split Scanned PDF with physical scanned page splitter QR Code" + }, + "sanitizePdf": { + "title": "Desinfektatu", + "desc": "Ezabatu script-ak eta PDF fitxategietako beste elementu batzuk" + }, + "URLToPDF": { + "title": "URL/Website PDF pdf bihurtu", + "desc": "Bihurtu edozein URL PDF fitxategian" + }, + "HTMLToPDF": { + "title": "HTML PDF-ra", + "desc": "Bihurtu edozein HTML edo zip fitxategi PDFra" + }, + "MarkdownToPDF": { + "title": "Markdown PDF-ra", + "desc": "Bihurtu Markdown fitxategi guztiak PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "Lortu informazio guztia PDF-tik", + "desc": "Eskuratu PDF fitxategiko Informazio guztia" + }, + "extractPage": { + "title": "Orria(k) atera", + "desc": "Aukeratutako orriak PDF fitxategitik atera" + }, + "PdfToSinglePage": { + "title": "PDF fitxategia, orrialde handi bakar batera", + "desc": "PDF orri guztiak orri handi bakar batean konbinatzen ditu" + }, + "showJS": { + "title": "Javascript erakutsi", + "desc": "Bilatu eta erakutsi PDF batean injektatutako edozein JS" + }, + "autoRedact": { + "title": "Auto Idatzi", + "desc": "Auto Idatzi testua pdf fitxategian sarrerako testuan oinarritua" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF to CSV", + "desc": "Extracts Tables from a PDF converting it to CSV" + }, + "autoSizeSplitPDF": { + "title": "Auto Split by Size/Count", + "desc": "Split a single PDF into multiple documents based on size, page count, or document count" + }, + "overlay-pdfs": { + "title": "Overlay PDFs", + "desc": "Overlays PDFs on-top of another PDF" + }, + "split-by-sections": { + "title": "Split PDF by Sections", + "desc": "Divide each page of a PDF into smaller horizontal and vertical sections" + }, + "AddStampRequest": { + "title": "Add Stamp to PDF", + "desc": "Add text or add image stamps at set locations" + }, + "removeImagePdf": { + "title": "Remove image", + "desc": "Remove image from PDF to reduce file size" + }, + "splitPdfByChapters": { + "title": "Split PDF by Chapters", + "desc": "Split a PDF into multiple files based on its chapter structure." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "replaceColorPdf": { + "title": "Replace and Invert Color", + "desc": "Replace color for text and background in PDF and invert full color of pdf to reduce file size" + } + }, + "viewPdf": { + "tags": "view,read,annotate,text,image", + "title": "View/Edit PDF", + "header": "View PDF" + }, + "multiTool": { + "tags": "Multi Tool,Multi operation,UI,click drag,front end,client side", + "title": "PDF erabilera anitzeko tresna", + "header": "PDF erabilera anitzeko tresna", + "uploadPrompts": "File Name", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "selectPages": "Page Select", + "selectedPages": "Selected Pages", + "page": "Page", + "deleteSelected": "Delete Selected", + "downloadAll": "Export", + "downloadSelected": "Export Selected", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "Page(s) Selected", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "merge,Page operations,Back end,server side", + "title": "Elkartu", + "header": "Elkartu zenbait PDF (2+)", + "sortByName": "Sort by nameOrdenatu izenaren arabera", + "sortByDate": "Ordenatu dataren arabera", + "removeCertSign": "Remove digital signature in the merged file?", + "submit": "Elkartu" + }, + "split": { + "tags": "Page operations,divide,Multi Page,cut,server side", + "title": "Zatitu PDFa", + "header": "Zatitu PDFa", + "desc": { + "1": "Hautatzen dituzun zenbakiak zatiketa egin nahi duzun orrialde-zenbakiak dira", + "2": "Beraz, 1,3,7-9 hautatzean 10 orrialdeko dokumentua zatituko luke 6 PDF fitxategi bereizituetan", + "3": "#1 Dokumentua: 1. orrialdea", + "4": "#2 Dokumentua: 2. eta 3. orrialdeak", + "5": "#3 Dokumentua: 4., 5., 6. eta 7. orrialdeak", + "6": "#4 Dokumentua: 8. orrialdea", + "7": "#5 Dokumentua: 9. orrialdea", + "8": "#6 Dokumentua: 10. orrialdeak" + }, + "splitPages": "Sartu orrialdeak zatitzeko:", + "submit": "Zatitu" + }, + "rotate": { + "tags": "server side", + "title": "Biratu PDFa", + "header": "Biratu PDFa", + "selectAngle": "Hautatu errotazio-angelua (90 graduko multiploetan):", + "submit": "Biratu" + }, + "imageToPdf": { + "tags": "conversion,img,jpg,picture,photo" + }, + "pdfToImage": { + "tags": "conversion,img,jpg,picture,photo", + "title": "PDFa irudi bihurtu", + "header": "PDFa irudi bihurtu", + "selectText": "Irudi-formatua", + "singleOrMultiple": "Ondoriozko irudi-mota", + "single": "Irudi handi bakarra", + "multi": "Zenbait irudi", + "colorType": "Kolore-mota", + "color": "Kolorea", + "grey": "Gris-eskala", + "blackwhite": "Zuria eta Beltza (Datuak galdu ditzake!)", + "submit": "Bihurtu", + "info": "Python is not installed. Required for WebP conversion.", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,even,odd,sort,move", + "title": "Orrialdeen antolatzailea", + "header": "PDF orrialdeen antolatzailea", + "submit": "Antolatu orrialdeak", + "mode": { + "_value": "Mode", + "1": "Custom Page Order", + "2": "Reverse Order", + "3": "Duplex Sort", + "4": "Booklet Sort", + "5": "Side Stitch Booklet Sort", + "6": "Odd-Even Split", + "7": "Remove First", + "8": "Remove Last", + "9": "Remove First and Last", + "10": "Odd-Even Merge", + "11": "Duplicate all pages" + }, + "placeholder": "(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)" + }, + "addImage": { + "tags": "img,jpg,picture,photo", + "title": "Gehitu irudia", + "header": "Gehitu PDF-irudia", + "everyPage": "Orrialde guztiak?", + "upload": "Gehitu irudia", + "submit": "Gehitu irudia" + }, + "watermark": { + "tags": "Text,repeating,label,own,copyright,trademark,img,jpg,picture,photo", + "title": "Gehitu ur-marka", + "header": "Gehitu ur-marka", + "customColor": "Custom Text Color", + "selectText": { + "1": "Hautatu PDFa ur-marka gehitzeko:", + "2": "Ur-markaren testua:", + "3": "Letra-tipoaren tamaina:", + "4": "Errotazioa (0-360):", + "5": "Zabalera (ur-marka bakoitzaren arteko espazioa horizontalean):", + "6": "Altuera (ur-marka bakoitzaren arteko espazioa bertikalean):", + "7": "Opakutasuna (0% - 100%):", + "8": "Watermark Type:", + "9": "Watermark Image:", + "10": "Convert PDF to PDF-Image" + }, + "submit": "Gehitu ur-marka", + "type": { + "1": "Text", + "2": "Image" + } + }, + "permissions": { + "tags": "read,write,edit,print", + "title": "Aldatu baimenak", + "header": "Aldatu baimenak", + "warning": "Oharra: baimen hauek aldatzea ezinezkoa izan dadin, gomendatzen da pasahitz batekin konfiguratzea pasahitza aldatzeko orriaren bitartez", + "selectText": { + "1": "Hautatu PDFa baimenak aldatzeko", + "2": "Baimenak, ezarri beharrekoak", + "3": "Galarazi dokumentuaren mihiztaketa", + "4": "Galarazi edukia ateratzea", + "5": "Galarazi ateratzea irisgarritasunerako", + "6": "Galarazi inprimakia betetzea", + "7": "Galarazi aldaketak egitea", + "8": "Galarazi oharrak aldatzea", + "9": "Galarazi inprimatzea", + "10": "Galarazi zenbait formatu inprimatzea" + }, + "submit": "Aldatu" + }, + "removePages": { + "tags": "Remove pages,delete pages" + }, + "addPassword": { + "tags": "secure,security", + "title": "Gehitu pasahitza", + "header": "Gehitu pasahitza (enkriptatu)", + "selectText": { + "1": "Hautatu PDFa enkriptatzeko", + "2": "Pasahitza", + "3": "Gakoaren luzera", + "4": "Balio altuak sendoagoak dira, baina balio baxuek bateragarritasun hobea dute", + "5": "Ezartzeko baimenak", + "6": "Galarazi dokumentuaren mihiztaketa", + "7": "Galarazi edukia ateratzea", + "8": "Galarazi ateratzea irisgarritasunerako", + "9": "Galarazi inprimakia betetzea", + "10": "Galarazi aldaketak egitea", + "11": "Galarazi oharrak aldatzea", + "12": "Galarazi inprimatzea", + "13": "Galarazi zenbait formatu inprimatzea", + "14": "Pasahitza", + "15": "Mugatu zer egin daitekeen dokumentuarekin behin zabalduta (Irakurle guztiek onartu gabe)", + "16": "Mugatu dokumentu bera zabaltzeko aukera" + }, + "submit": "Enkriptatu" + }, + "removePassword": { + "tags": "secure,Decrypt,security,unpassword,delete password", + "title": "Ezabatu pasahitza", + "header": "Ezabatu pasahitza (desenkriptatu)", + "selectText": { + "1": "Hautatu PDFa desenkriptatzeko", + "2": "Pasahitza" + }, + "submit": "Ezabatu" + }, + "compressPdfs": { + "tags": "squish,small,tiny" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Title,author,date,creation,time,publisher,producer,stats", + "title": "Izenburua:", + "header": "Aldatu metadatuak", + "selectText": { + "1": "Editatu aldatu nahi dituzun aldagaiak", + "2": "Ezabatu metadatu guztiak", + "3": "Erakutsi metadatu pertsonalizatuak:", + "4": "Beste metadatu batzuk:", + "5": "Gehitu metadatu pertsonalizatuen sarrera" + }, + "author": "Egilea:", + "creationDate": "Sortze-data (aaaa/MM/dd HH:mm:ss):", + "creator": "Sortzailea:", + "keywords": "Gako-hitzak:", + "modDate": "Aldatze-data (aaaa/MM/dd HH:mm:ss):", + "producer": "Ekoizlea:", + "subject": "Gaia:", + "trapped": "Trapped:", + "submit": "Aldatu" + }, + "fileToPDF": { + "tags": "transformation,format,document,picture,slide,text,conversion,office,docs,word,excel,powerpoint", + "title": "Fitxategia PDF bihurtu", + "header": "Edozein fitxategi PDF bihurtu", + "credit": "Zerbitzu honek LibreOffice eta Unoconv erabiltzen ditu fitxategiak bihurtzeko", + "supportedFileTypesInfo": "Supported File types", + "supportedFileTypes": "Jasandako fitxategi-motek behekoak barne hartu behar dituzte; hala ere, jasandako formatuen zerrenda osoa eta eguneratua izateko, kontsultatu, mesedez, LibreOffice-en dokumentazioa", + "submit": "PDF bihurtu" + }, + "ocr": { + "tags": "recognition,text,image,scan,read,identify,detection,editable", + "title": "OCR / Garbiketa-eskaneatzea", + "header": "Garbiketa-eskaneatzea / OCR (Karaktere-ezagutze optikoa)", + "selectText": { + "1": "Hautatu PDFan detektatuko diren hizkuntzak (zerrendatutakoak gaur egun detektatzen dituenak dira):", + "2": "Sortu OCR testua duen testu-fitxategi bat OCR-ren bidez editatutako PDFarekin batera", + "3": "Zuzendu angelu okertu batean eskaneatu ziren orrialdeak berriro beren lekura biratuta", + "4": "Garbitu orrialdea OCRk hondoko zaratan testua aurkitzeko probabilitate txikiagoa izan dezan (Irteeran aldatu gabe)", + "5": "Garbitu orrialdea OCRk hondoko zaratan testua aurkitzeko probabilitate txikiagoa izan dezan, irteeran garbi mantentzen du.", + "6": "Alde batera utzi testu interaktiboa duten orrialdeak, bakarrik irudi diren OCR orrialdeak", + "7": "OCR behartu, OCRk orrialde bakoitzean jatorrizko testu guztia ezabatuko du", + "8": "Normala (Errorea gertatuko da PDFak testua baldin badu)", + "9": "Ezarpen gehigarriak", + "10": "OCR modua", + "11": "Irudiak ezabatu OCR-ren ondoren (Irudi GUZTIAK ezabatzen ditu, bakarrik da erabilgarri bihurketa urratsaren parte baldin bada)", + "12": "Prozesaketa-mota (aurreratua)" + }, + "help": "Irakurri honen erabilerari buruzko dokumentazioa beste hizkuntza batzuetarako eta/edo ez erabili Docker-en", + "credit": "Zerbitzu honek qpdf eta OCR-rako Tesseract erabiltzen ditu", + "submit": "PDF prozesatu OCR-rekin" + }, + "extractImages": { + "tags": "picture,photo,save,archive,zip,capture,grab", + "title": "Atera irudiak", + "header": "Atera irudiak", + "selectText": "Hautatu irudi-formatua ateratako irudiak bihurtzeko", + "allowDuplicates": "Save duplicate images", + "submit": "Atera" + }, + "pdfToPDFA": { + "tags": "archive,long-term,standard,conversion,storage,preservation", + "title": "PDFa PDF/A bihurtu", + "header": "PDFa PDF/A bihurtu", + "credit": "Zerbitzu honek libreoffice erabiltzen du PDFak PDF/A bihurtzeko", + "submit": "Bihurtu", + "tip": "Currently does not work for multiple inputs at once", + "outputFormat": "Output format", + "pdfWithDigitalSignature": "The PDF contains a digital signature. This will be removed in the next step." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformation,format,conversion,office,microsoft,docfile", + "title": "PDFa Word bihurtu", + "header": "PDFa Word bihurtu", + "selectText": { + "1": "Irteerako fitxategiaren formatua" + }, + "credit": "Zerbitzu honek LibreOffice erabiltzen du fitxategiak bihurtzeko", + "submit": "Bihurtu" + }, + "PDFToPresentation": { + "tags": "slides,show,office,microsoft", + "title": "PDFa aurkezpen bihurtu", + "header": "PDFa aurkezpen bihurtu", + "selectText": { + "1": "Irteerako fitxategiaren formatua" + }, + "credit": "Zerbitzu honek LibreOffice erabiltzen du fitxategiak bihurtzeko", + "submit": "Bihurtu" + }, + "PDFToText": { + "tags": "richformat,richtextformat,rich text format", + "title": "PDFa TXT/RTF bihurtu", + "header": "PDFa TXT/RTF bihurtu", + "selectText": { + "1": "Irteerako fitxategiaren formatua" + }, + "credit": "Zerbitzu honek LibreOffice erabiltzen du fitxategiak bihurtzeko", + "submit": "Bihurtu" + }, + "PDFToHTML": { + "tags": "web content,browser friendly", + "title": "PDFa HTML bihurtu", + "header": "PDFa HTML bihurtu", + "credit": "Zerbitzu honek pdftohtml erabiltzen du fitxategiak bihurtzeko", + "submit": "Bihurtu" + }, + "PDFToXML": { + "tags": "data-extraction,structured-content,interop,transformation,convert", + "title": "PDFa XML bihurtu", + "header": "PDFa XML bihurtu", + "credit": "Zerbitzu honek LibreOffice erabiltzen du fitxategiak bihurtzeko", + "submit": "Bihurtu" + }, + "ScannerImageSplit": { + "tags": "separate,auto-detect,scans,multi-photo,organize", + "selectText": { + "1": "Angeluaren gutxieneko balioa:", + "2": "Ezarri eskatutako gutxieneko angelu absolutua irudia biratzeko (lehenetsia: 10).", + "3": "Tolerantzia:", + "4": "Ezarri kalkulatutako atzeko kolorearen inguruko kolorearen aldakuntza tartea (lehenetsia: 30).", + "5": "Gutxieneko area:", + "6": "Ezarri arearen gutxieneko balioa argazki batentzat (lehenetsia: 10000).", + "7": "Inguruko area gutxienekoa:", + "8": "Ezarri inguruko arearen gutxieneko balioa argazki batentzat", + "9": "Ertzaren tamaina:", + "10": "Ezarri gehitutako eta ezabatutako ertzaren tamaina irteeran ertz zuriak saihesteko (lehenetsia: 1)." + }, + "info": "Python is not installed. It is required to run." + }, + "sign": { + "tags": "authorize,initials,drawn-signature,text-sign,image-signature", + "title": "Sinatu", + "header": "Sinatu PDF fitxategiak", + "upload": "Igo irudia", + "draw": "Marraztu sinadura", + "text": "Testua sartzea", + "clear": "Garbitu", + "add": "Gehitu", + "saved": "Saved Signatures", + "save": "Save Signature", + "personalSigs": "Personal Signatures", + "sharedSigs": "Shared Signatures", + "noSavedSigs": "No saved signatures found", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "static,deactivate,non-interactive,streamline", + "title": "Lautu", + "header": "Akoplatu PDF fitxategiak", + "flattenOnlyForms": "Flatten only forms", + "submit": "Lautu" + }, + "repair": { + "tags": "fix,restore,correction,recover", + "title": "Konpondu", + "header": "Konpondu PDF fitxategiak", + "submit": "Konpondu" + }, + "removeBlanks": { + "tags": "cleanup,streamline,non-content,organize", + "title": "Ezabatu zuriuneak", + "header": "Ezabatu orrialde zuriak", + "threshold": "Gutxieneko balioa:", + "thresholdDesc": "Pixel bat zeinen zuri izan behar den ezartzeko gutxieneko balioa", + "whitePercent": "Zuriaren protzentajea (%):", + "whitePercentDesc": "Zuria izan behar den orriaren ehunekoa ezabatua izan dadin", + "submit": "Ezabatu zuriuneak" + }, + "removeAnnotations": { + "tags": "comments,highlight,notes,markup,remove", + "title": "Remove Annotations", + "header": "Remove Annotations", + "submit": "Remove" + }, + "compare": { + "tags": "differentiate,contrast,changes,analysis", + "title": "Konparatu", + "header": "Konparatu PDF fitxategiak", + "highlightColor": { + "1": "Highlight Color 1:", + "2": "Highlight Color 2:" + }, + "document": { + "1": "1. dokumentua", + "2": "2. dokumentua" + }, + "submit": "Konparatu", + "complex": { + "message": "One or both of the provided documents are large files, accuracy of comparison may be reduced" + }, + "large": { + "file": { + "message": "One or Both of the provided documents are too large to process" + } + }, + "no": { + "text": { + "message": "One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison." + } + } + }, + "certSign": { + "tags": "authenticate,PEM,P12,official,encrypt", + "title": "Ziurtagiriaren sinadura", + "header": "Sinatu PDF bat haren ziurtagiriarekin (lanean)", + "selectPDF": "Hautatu PDF fitxategi bat sinatzeko:", + "jksNote": "Note: If your certificate type is not listed below, please convert it to a Java Keystore (.jks) file using the keytool command line tool. Then, choose the .jks file option below.", + "selectKey": "Hautatu gako pribatuko fitxategia (PKCS#8 formatua, .pem edo .der izan liteke):", + "selectCert": "Hautatu ziurtagiridun fitxategia (X.509 formatua, .pem edo .der izan liteke):", + "selectP12": "Hautatu gakoak gordetzeko fitxategia PKCS#12 (.p12 o .pfx) (Aukerakoa, ematen bada, gako pribatua eta ziurtagiria izan beharko ditu):", + "selectJKS": "Select Your Java Keystore File (.jks or .keystore):", + "certType": "Ziurtagiri-mota", + "password": "Sartu zure gakoen biltegia edo gako pribatuko pasahitza (hala badagokio):", + "showSig": "Erakutsi sinadura", + "reason": "Arrazoia", + "location": "Kokalekua", + "name": "Izena", + "showLogo": "Show Logo", + "submit": "Sinatu PDFa" + }, + "removeCertSign": { + "tags": "authenticate,PEM,P12,official,decrypt", + "title": "Remove Certificate Signature", + "header": "Remove the digital certificate from the PDF", + "selectPDF": "Select a PDF file:", + "submit": "Remove Signature" + }, + "pageLayout": { + "tags": "merge,composite,single-view,organize", + "title": "Hainbat orrialderen diseinua", + "header": "Hainbat orrialderen diseinua", + "pagesPerSheet": "Orrialdeak orriko:", + "addBorder": "Add Borders", + "submit": "Entregatu" + }, + "scalePages": { + "tags": "resize,modify,dimension,adapt", + "title": "Doitu orrialdearen eskala", + "header": "Doitu orrialdearen eskala", + "pageSize": "Dokumentuaren orrialdearen tamaina", + "keepPageSize": "Original Size", + "scaleFactor": "Orriaren zoom maila (moztea)", + "submit": "Entregatu" + }, + "add-page-numbers": { + "tags": "paginate,label,organize,index" + }, + "auto-rename": { + "tags": "auto-detect,header-based,organize,relabel", + "title": "Aldatu izena", + "header": "PDF Aldatu izena", + "submit": "Aldatu izena" + }, + "adjust-contrast": { + "tags": "color-correction,tune,modify,enhance" + }, + "crop": { + "tags": "trim,shrink,edit,shape", + "title": "Moztu", + "header": "Moztu PDF", + "submit": "Bidali" + }, + "autoSplitPDF": { + "tags": "QR-based,separate,scan-segment,organize", + "title": "Auto Zatitu PDFa", + "header": "Auto Zatitu PDFa", + "description": "Inprimatu, txertatu, eskaneatu, igo eta utzi guri automatikoki bereizten zure dokumentuak. Ez da laneko eskuzko hautaketarik behar.", + "selectText": { + "1": "Inprimatu beheko zatitze-orri batzuk (beltza eta zuria ondo dago).", + "2": "Eskaneatu dokumentu guztiak batera, eta sartu banalerroa haien artean.", + "3": "Igo eskaneatutako PDF artxibo handia, eta utzi Stirling PDFri gainerakoak maneiatzen.", + "4": "Orrialde zatitzaileak automatikoki detektatu eta kentzen dira, eta azken dokumentu ordenatua bermatzen da." + }, + "formPrompt": "Submit PDF containing Stirling-PDF Page dividers:", + "duplexMode": "Duplex Mode (Front and back scanning)Duplex modua (aurreko eta atzeko azterketa)", + "dividerDownload2": "Deskargatu 'Auto Splitter Divider (with instructions).pdf'", + "submit": "Bidali" + }, + "sanitizePdf": { + "tags": "clean,secure,safe,remove-threats" + }, + "URLToPDF": { + "tags": "web-capture,save-page,web-to-doc,archive", + "title": "URL bat PDF-ra", + "header": "URL bat PDF-ra", + "submit": "Bihurty", + "credit": "WeasyPrint darabil" + }, + "HTMLToPDF": { + "tags": "markup,web-content,transformation,convert", + "title": "HTML bat PDF-ra", + "header": "HTML bat PDF-ra", + "help": "Html/css/images etab dituen HTML eta Zip fitxategiak onartzen ditu", + "submit": "Bihurtu", + "credit": "WeasyPrint darabil", + "zoom": "Zoom level for displaying the website.", + "pageWidth": "Width of the page in centimeters. (Blank to default)", + "pageHeight": "Height of the page in centimeters. (Blank to default)", + "marginTop": "Top margin of the page in millimeters. (Blank to default)", + "marginBottom": "Bottom margin of the page in millimeters. (Blank to default)", + "marginLeft": "Left margin of the page in millimeters. (Blank to default)", + "marginRight": "Right margin of the page in millimeters. (Blank to default)", + "printBackground": "Render the background of websites.", + "defaultHeader": "Enable Default Header (Name and page number)", + "cssMediaType": "Change the CSS media type of the page.", + "none": "None", + "print": "Print", + "screen": "Screen" + }, + "MarkdownToPDF": { + "tags": "markup,web-content,transformation,convert", + "title": "Markdown PDFra", + "header": "Markdown PDFra", + "submit": "Bihurtu", + "help": "Lanean", + "credit": "WeasyPrint darabil" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "infomation,data,stats,statistics", + "title": "Lortu informazioa PDFn", + "header": "Lortu informazioa PDFn", + "submit": "Lortu informazioa", + "downloadJson": "Deskargatu JSON" + }, + "extractPage": { + "tags": "extract" + }, + "PdfToSinglePage": { + "tags": "single page" + }, + "showJS": { + "tags": "JS", + "title": "Javascript erakutsi", + "header": "Javascript erakutsi", + "downloadJS": "Javascript deskargatu", + "submit": "Erakutsi" + }, + "autoRedact": { + "tags": "Redact,Hide,black out,black,marker,hidden", + "title": "Auto Idatzi", + "header": "Auto Idatzi", + "colorLabel": "Kolorea", + "textsToRedactLabel": "Idazteko testua (lerro bidez bereizia)", + "textsToRedactPlaceholder": "adib. \\nKonfidentziala \\nTop-Secret", + "useRegexLabel": "Regex erabili", + "wholeWordSearchLabel": "Hitz osoen bilaketa", + "customPaddingLabel": "Custom Extra Padding", + "convertPDFToImageLabel": "Bihurtu PDF fitxategi bat PDF-Irudi-ra (kaxaren atzean testua ezabatzeko erabilia)", + "submitButton": "Bidali" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,Table Extraction,extract,convert" + }, + "autoSizeSplitPDF": { + "tags": "pdf,split,document,organization" + }, + "overlay-pdfs": { + "tags": "Overlay", + "header": "Overlay PDF Files", + "baseFile": { + "label": "Select Base PDF File" + }, + "overlayFiles": { + "label": "Select Overlay PDF Files" + }, + "mode": { + "label": "Select Overlay Mode", + "sequential": "Sequential Overlay", + "interleaved": "Interleaved Overlay", + "fixedRepeat": "Fixed Repeat Overlay" + }, + "counts": { + "label": "Overlay Counts (for Fixed Repeat Mode)", + "placeholder": "Enter comma-separated counts (e.g., 2,3,1)" + }, + "position": { + "label": "Select Overlay Position", + "foreground": "Foreground", + "background": "Background" + }, + "submit": "Submit" + }, + "split-by-sections": { + "tags": "Section Split, Divide, Customize", + "title": "Split PDF by Sections", + "header": "Split PDF into Sections", + "horizontal": { + "label": "Horizontal Divisions", + "placeholder": "Enter number of horizontal divisions" + }, + "vertical": { + "label": "Vertical Divisions", + "placeholder": "Enter number of vertical divisions" + }, + "submit": "Split PDF", + "merge": "Merge Into One PDF" + }, + "AddStampRequest": { + "tags": "Stamp, Add image, center image, Watermark, PDF, Embed, Customize", + "header": "Stamp PDF", + "title": "Stamp PDF", + "stampType": "Stamp Type", + "stampText": "Stamp Text", + "stampImage": "Stamp Image", + "alphabet": "Alphabet", + "fontSize": "Font/Image Size", + "rotation": "Rotation", + "opacity": "Opacity", + "position": "Position", + "overrideX": "Override X Coordinate", + "overrideY": "Override Y Coordinate", + "customMargin": "Custom Margin", + "customColor": "Custom Text Color", + "submit": "Submit" + }, + "removeImagePdf": { + "tags": "Remove Image,Page operations,Back end,server side" + }, + "splitPdfByChapters": { + "tags": "split,chapters,bookmarks,organize" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Replace-Invert-Color", + "header": "Replace-Invert Color PDF", + "selectText": { + "1": "Replace or Invert color Options", + "2": "Default(Default high contrast colors)", + "3": "Custom(Customized colors)", + "4": "Full-Invert(Invert all colors)", + "5": "High contrast color options", + "6": "white text on black background", + "7": "Black text on white background", + "8": "Yellow text on black background", + "9": "Green text on black background", + "10": "Choose text Color", + "11": "Choose background Color" + }, + "submit": "Replace" + }, + "replaceColorPdf": { + "tags": "Replace Color,Page operations,Back end,server side" + }, + "login": { + "title": "Saioa hasi", + "header": "Saioa hasi", + "signin": "Saioa hasi", + "rememberme": "Oroitu nazazu", + "invalid": "Okerreko erabiltzaile izena edo pasahitza.", + "locked": "Zure kontua blokeatu egin da.", + "signinTitle": "Mesedez, hasi saioa", + "ssoSignIn": "Hasi saioa Saioa hasteko modu bakarraren bidez", + "oAuth2AutoCreateDisabled": "OAUTH2 Sortu automatikoki erabiltzailea desgaituta dago", + "oAuth2AdminBlockedUser": "Registration or logging in of non-registered users is currently blocked. Please contact the administrator.", + "oauth2RequestNotFound": "Authorization request not found", + "oauth2InvalidUserInfoResponse": "Invalid User Info Response", + "oauth2invalidRequest": "Invalid Request", + "oauth2AccessDenied": "Access Denied", + "oauth2InvalidTokenResponse": "Invalid Token Response", + "oauth2InvalidIdToken": "Invalid Id Token", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "User is deactivated, login is currently blocked with this username. Please contact the administrator.", + "alreadyLoggedIn": "You are already logged in to", + "alreadyLoggedIn2": "devices. Please log out of the devices and try again.", + "toManySessions": "You have too many active sessions", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF Orrialde bakarrera", + "header": "PDF Orrialde bakarrera", + "submit": "Orrialde bakarrera bihurtu" + }, + "pageExtracter": { + "title": "Atera orriak", + "header": "Atera orriak", + "submit": "Atera", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "sanitizePDF": { + "title": "PDF-a desinfektatu", + "header": "PDF fitxategi bat desinfektatu", + "selectText": { + "1": "Ezabatu JavaScript akzioak", + "2": "Ezabatu embedded fitxategiak", + "3": "Remove XMP metadata", + "4": "Ezabatu esketak", + "5": "Ezabatu iturri letrak", + "6": "Remove Document Info Metadata" + }, + "submit": "Desinfektatu PDF" + }, + "adjustContrast": { + "title": "Doitu kontrastea", + "header": "Doitu kontrastea", + "contrast": "Kontrastea:", + "brightness": "Distira:", + "saturation": "Asetasuna:", + "download": "Distira" + }, + "compress": { + "title": "Konprimatu", + "header": "PDFa konprimatu", + "credit": "Zerbitzu honek qpdf erabiltzen du PDFak komprimatzeko/optimizatzeko", + "grayscale": { + "label": "Aplikatu grisezko eskala konpresiorako" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Optimizazio maila:", + "4": "Automatikoa: automatikoki egokitzen du kalitatea PDFak tamaina doi-doia izan dezan", + "5": "PDFaren espero den tamaina (adibidez, 25 MB, 10.8 MB, 25 KB)" + }, + "submit": "Konprimatu" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "Orrialdeen ezabatzailea", + "header": "PDF orrialdeen ezabatzailea", + "pagesToDelete": "Ezabatu beharreko orrialdeak (sartu komaz bereizitako orrialde-zenbakien zerrenda):", + "submit": "Ezabatu orrialdeak", + "placeholder": "(e.g. 1,2,6 or 1-10,15-30)" + }, + "imageToPDF": { + "title": "Irudia PDF bihurtu", + "header": "Irudia PDF bihurtu", + "submit": "Bihurtu", + "selectLabel": "Image Fit Options", + "fillPage": "Fill Page", + "fitDocumentToImage": "Fit Page to Image", + "maintainAspectRatio": "Maintain Aspect Ratios", + "selectText": { + "2": "PDFaren errotazio automatikoa", + "3": "Fitxategi askoren logika (gaituta bakarrik zenbait irudirekin ari denean)", + "4": "Elkartu PDF bakar batean", + "5": "Bihurtu eta PDF bereizituak sortu" + } + }, + "PDFToCSV": { + "title": "PDF a CSV", + "header": "PDF a CSV", + "prompt": "Choose page to extract table", + "submit": "Extracto" + }, + "split-by-size-or-count": { + "title": "Split PDF by Size or Count", + "header": "Split PDF by Size or Count", + "type": { + "label": "Select Split Type", + "size": "By Size", + "pageCount": "By Page Count", + "docCount": "By Document Count" + }, + "value": { + "label": "Enter Value", + "placeholder": "Enter size (e.g., 2MB or 3KB) or count (e.g., 5)" + }, + "submit": "Submit" + }, + "printFile": { + "title": "Print File", + "header": "Print File to Printer", + "selectText": { + "1": "Select File to Print", + "2": "Enter Printer Name" + }, + "submit": "Print" + }, + "licenses": { + "nav": "Licenses", + "title": "3rd Party Licenses", + "header": "3rd Party Licenses", + "module": "Module", + "version": "Version", + "license": "License" + }, + "survey": { + "nav": "Survey", + "title": "Stirling-PDF Survey", + "description": "Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!", + "changes": "Stirling-PDF has changed since the last survey! To find out more please check our blog post here:", + "changes2": "With these changes we are getting paid business support and funding", + "please": "Please consider taking our survey!", + "disabled": "(Survey popup will be disabled in following updates but available at foot of page)", + "button": "Take Survey", + "dontShowAgain": "Don't show again", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Remove image", + "header": "Remove image", + "removeImage": "Remove image", + "submit": "Remove image" + }, + "splitByChapters": { + "title": "Split PDF by Chapters", + "header": "Split PDF by Chapters", + "bookmarkLevel": "Bookmark Level", + "includeMetadata": "Include Metadata", + "allowDuplicates": "Allow Duplicates", + "desc": { + "1": "This tool splits a PDF file into multiple PDFs based on its chapter structure.", + "2": "Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).", + "3": "Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.", + "4": "Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs." + }, + "submit": "Split PDF" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Releases", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Current Release" + }, + "note": "Release notes are only available in English" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/fa-IR/translation.json b/frontend/public/locales/fa-IR/translation.json new file mode 100644 index 000000000..d0af02fe2 --- /dev/null +++ b/frontend/public/locales/fa-IR/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "rtl" + }, + "addPageNumbers": { + "fontSize": "اندازه ŁŁˆŁ†ŲŖ", + "fontName": "نام ŁŁˆŁ†ŲŖ", + "title": "Ų§ŁŲ²ŁˆŲÆŁ† ؓماره صفحات", + "header": "Ų§ŁŲ²ŁˆŲÆŁ† ؓماره صفحات", + "selectText": { + "1": "انتخاب ŁŲ§ŪŒŁ„ PDF:", + "2": "اندازه Ų­Ų§Ų“ŪŒŁ‡", + "3": "Ł…ŁˆŁ‚Ų¹ŪŒŲŖ", + "4": "ؓماره ؓروع", + "5": "صفحات برای Ų“Ł…Ų§Ų±Ł‡ā€ŒŚÆŲ°Ų§Ų±ŪŒ", + "6": "متن سفارؓی" + }, + "customTextDesc": "متن سفارؓی", + "numberPagesDesc": "کدام صفحات Ų“Ł…Ų§Ų±Ł‡ā€ŒŚÆŲ°Ų§Ų±ŪŒ Ų“ŁˆŁ†ŲÆŲŒ Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶ 'همه'، Ł‡Ł…Ś†Ł†ŪŒŁ† Ł…ŪŒā€ŒŲŖŁˆŲ§Ł†ŪŒŲÆ 1-5 یا 2,5,9 Ų±Ų§ وارد Ś©Ł†ŪŒŲÆ.", + "customNumberDesc": "ŲØŁ‡ā€ŒŲ·ŁˆŲ± Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶ {n}، Ł‡Ł…Ś†Ł†ŪŒŁ† Ł…ŪŒā€ŒŲŖŁˆŲ§Ł†ŪŒŲÆ 'صفحه {n} Ų§Ų² {total}'، 'متن-{n}'، '{filename}-{n}' Ų±Ų§ وارد Ś©Ł†ŪŒŲÆ.", + "submit": "اضافه کردن ؓماره صفحات" + }, + "pdfPrompt": "انتخاب ŁŲ§ŪŒŁ„(Ł‡Ų§ŪŒ) PDF", + "multiPdfPrompt": "انتخاب ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ PDF (دو یا بیؓتر)", + "multiPdfDropPrompt": "انتخاب (یا Ś©Ų“ŪŒŲÆŁ† و رها کردن) ŲŖŁ…Ų§Ł… ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ PDF Ł…ŁˆŲ±ŲÆ Ł†ŪŒŲ§Ų²", + "imgPrompt": "انتخاب تصویر(ها)", + "genericSubmit": "Ų§Ų±Ų³Ų§Ł„", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "هؓدار: Ų§ŪŒŁ† ŁŲ±Ų¢ŪŒŁ†ŲÆ ممکن Ų§Ų³ŲŖ بسته به اندازه ŁŲ§ŪŒŁ„ ŲŖŲ§ یک ŲÆŁ‚ŪŒŁ‚Ł‡ Ų·ŁˆŁ„ بکؓد", + "pageOrderPrompt": "ترتیب صفحات سفارؓی (یک Ł„ŪŒŲ³ŲŖ Ų§Ų² ؓماره صفحات به صورت Ų¬ŲÆŲ§ ؓده ŲØŲ§ کاما وارد Ś©Ł†ŪŒŲÆ یا Ų§Ų² توابعی مانند 2n+1 استفاده Ś©Ł†ŪŒŲÆ):", + "pageSelectionPrompt": "انتخاب صفحات سفارؓی (یک Ł„ŪŒŲ³ŲŖ Ų§Ų² ؓماره صفحات به صورت Ų¬ŲÆŲ§ ؓده ŲØŲ§ کاما وارد Ś©Ł†ŪŒŲÆ مانند 1,5,6 یا Ų§Ų² توابعی مانند 2n+1 استفاده Ś©Ł†ŪŒŲÆ):", + "goToPage": "برو", + "true": "ŲÆŲ±Ų³ŲŖ", + "false": "غلط", + "unknown": "Ł†Ų§Ł…Ų¹Ł„ŁˆŁ…", + "save": "Ų°Ų®ŪŒŲ±Ł‡", + "saveToBrowser": "Ų°Ų®ŪŒŲ±Ł‡ ŲÆŲ± Ł…Ų±ŁˆŲ±ŚÆŲ±", + "close": "بستن", + "filesSelected": "ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ انتخاب ؓدند", + "noFavourites": "Ł‡ŪŒŚ† Ł…ŁˆŲ±ŲÆ ŲÆŁ„Ų®ŁˆŲ§Ł‡ŪŒ اضافه نؓده Ų§Ų³ŲŖ", + "downloadComplete": "ŲÆŲ§Ł†Ł„ŁˆŲÆ کامل Ų“ŲÆ", + "bored": "منتظر ماندن Ų®Ų³ŲŖŁ‡ā€ŒŚ©Ł†Ł†ŲÆŁ‡ است؟", + "alphabet": "حروف الفبا", + "downloadPdf": "ŲÆŲ§Ł†Ł„ŁˆŲÆ PDF", + "text": "متن", + "font": "ŁŁˆŁ†ŲŖ", + "selectFillter": "-- انتخاب Ś©Ł†ŪŒŲÆ --", + "pageNum": "ؓماره صفحه", + "sizes": { + "small": "Ś©ŁˆŚ†Ś©", + "medium": "Ł…ŲŖŁˆŲ³Ų·", + "large": "بزرگ", + "x-large": "Ų®ŪŒŁ„ŪŒ بزرگ" + }, + "error": { + "pdfPassword": "سند PDF دارای رمز عبور Ų§Ų³ŲŖ و یا رمز عبور وارد نؓده یا نادرست Ų§Ų³ŲŖ", + "_value": "Ų®Ų·Ų§", + "sorry": "Ł…ŲŖŲ£Ų³ŁŪŒŁ… برای مؓکل Ł…ŁˆŲ¬ŁˆŲÆ!", + "needHelp": "Ł†ŪŒŲ§Ų² به کمک / ŪŒŲ§ŁŲŖŁ† Ł…Ų“Ś©Ł„ŪŒŲŸ", + "contactTip": "Ų§ŚÆŲ± Ł‡Ł†ŁˆŲ² Ł…Ų“Ś©Ł„ŪŒ دارید، دریغ Ł†Ś©Ł†ŪŒŲÆ که ŲØŲ§ Ł…Ų§ ŲŖŁ…Ų§Ų³ بگیرید. Ł…ŪŒā€ŒŲŖŁˆŲ§Ł†ŪŒŲÆ یک تیکت ŲÆŲ± صفحه GitHub Ł…Ų§ Ų§Ų±Ų³Ų§Ł„ Ś©Ł†ŪŒŲÆ یا Ų§Ų² Ų·Ų±ŪŒŁ‚ Discord ŲØŲ§ Ł…Ų§ ŲŖŁ…Ų§Ų³ بگیرید:", + "404": { + "head": "Ū“Ū°Ū“ - صفحه پیدا نؓد | Ų§ŁˆŁ‡ŲŒ ŲÆŲ± کد Ł„ŲŗŲ²ŪŒŲÆŪŒŁ…!", + "1": "به نظر Ł†Ł…ŪŒā€ŒŲ±Ų³ŲÆ ŲØŲŖŁˆŲ§Ł†ŪŒŁ… ŲµŁŲ­Ł‡ā€ŒŲ§ŪŒ Ų±Ų§ که دنبالؓ Ł‡Ų³ŲŖŪŒŲÆ پیدا Ś©Ł†ŪŒŁ….", + "2": "Ł…Ų“Ś©Ł„ŪŒ پیؓ آمده Ų§Ų³ŲŖ" + }, + "github": "Ų§Ų±Ų³Ų§Ł„ تیکت ŲÆŲ± GitHub", + "showStack": "Ł†Ł…Ų§ŪŒŲ“ Trace Stack", + "copyStack": "کپی Trace Stack", + "githubSubmit": "GitHub - Ų§Ų±Ų³Ų§Ł„ تیکت", + "discordSubmit": "Discord - Ų§Ų±Ų³Ų§Ł„ پست Ł¾Ų“ŲŖŪŒŲØŲ§Ł†ŪŒ" + }, + "delete": "حذف", + "username": "نام کاربری", + "password": "رمز عبور", + "welcome": "خوؓ Ų¢Ł…ŲÆŪŒŲÆ", + "property": "ویژگی", + "black": "Ų³ŪŒŲ§Ł‡", + "white": "سفید", + "red": "قرمز", + "green": "Ų³ŲØŲ²", + "blue": "آبی", + "custom": "سفارؓی...", + "WorkInProgess": "کار ŲÆŲ± Ų­Ų§Ł„ پیؓرفت است، ممکن Ų§Ų³ŲŖ کار نکند یا دارای اؓکال باؓد، لطفاً هر Ł…Ų“Ś©Ł„ŪŒ Ų±Ų§ ŚÆŲ²Ų§Ų±Ų“ ŲÆŁ‡ŪŒŲÆ!", + "poweredBy": "قدرت گرفته Ų§Ų²", + "yes": "بله", + "no": "خیر", + "changedCredsMessage": "Ł…Ų“Ų®ŲµŲ§ŲŖ تغییر یافت!", + "notAuthenticatedMessage": "کاربر تأیید نؓده Ų§Ų³ŲŖ.", + "userNotFoundMessage": "کاربر یافت نؓد.", + "incorrectPasswordMessage": "رمز عبور ŁŲ¹Ł„ŪŒ نادرست Ų§Ų³ŲŖ.", + "usernameExistsMessage": "نام کاربری جدید قبلاً وجود ŲÆŲ§Ų±ŲÆ.", + "invalidUsernameMessage": "نام کاربری نامعتبر است، نام کاربری فقط Ł…ŪŒā€ŒŲŖŁˆŲ§Ł†ŲÆ Ų“Ų§Ł…Ł„ حروف، Ų§Ų¹ŲÆŲ§ŲÆ و Ś©Ų§Ų±Ų§Ś©ŲŖŲ±Ł‡Ų§ŪŒ Ų®Ų§Ųµ @._+- ŲØŲ§Ų“ŲÆ یا باید یک Ų¢ŲÆŲ±Ų³ Ų§ŪŒŁ…ŪŒŁ„ Ł…Ų¹ŲŖŲØŲ± ŲØŲ§Ų“ŲÆ.", + "invalidPasswordMessage": "رمز عبور Ł†ŲØŲ§ŪŒŲÆ Ų®Ų§Ł„ŪŒ ŲØŲ§Ų“ŲÆ و Ł†ŲØŲ§ŪŒŲÆ ŲÆŲ± Ų§ŲØŲŖŲÆŲ§ یا انتها فاصله داؓته ŲØŲ§Ų“ŲÆ.", + "confirmPasswordErrorMessage": "رمز عبور جدید و تأیید رمز عبور جدید باید ŪŒŚ©Ų³Ų§Ł† باؓند.", + "deleteCurrentUserMessage": "Ł†Ł…ŪŒā€ŒŲŖŁˆŲ§Ł† کاربر ŁŲ¹Ł„ŪŒ Ų±Ų§ حذف کرد.", + "deleteUsernameExistsMessage": "نام کاربری وجود ندارد و Ł†Ł…ŪŒā€ŒŲŖŁˆŲ§Ł† آن Ų±Ų§ حذف کرد.", + "downgradeCurrentUserMessage": "Ł†Ł…ŪŒā€ŒŲŖŁˆŲ§Ł† نقؓ کاربر ŁŲ¹Ł„ŪŒ Ų±Ų§ کاهؓ ŲÆŲ§ŲÆ", + "disabledCurrentUserMessage": "کاربر ŁŲ¹Ł„ŪŒ Ł†Ł…ŪŒā€ŒŲŖŁˆŲ§Ł†ŲÆ ŲŗŪŒŲ±ŁŲ¹Ų§Ł„ ؓود", + "downgradeCurrentUserLongMessage": "Ł†Ł…ŪŒā€ŒŲŖŁˆŲ§Ł† نقؓ کاربر ŁŲ¹Ł„ŪŒ Ų±Ų§ کاهؓ ŲÆŲ§ŲÆ. ŲØŁ†Ų§ŲØŲ±Ų§ŪŒŁ†ŲŒ کاربر ŁŲ¹Ł„ŪŒ نؓان داده Ł†Ų®ŁˆŲ§Ł‡ŲÆ Ų“ŲÆ.", + "userAlreadyExistsOAuthMessage": "Ų§ŪŒŁ† کاربر قبلاً به Ų¹Ł†ŁˆŲ§Ł† یک کاربر OAuth2 وجود ŲÆŲ§Ų±ŲÆ.", + "userAlreadyExistsWebMessage": "Ų§ŪŒŁ† کاربر قبلاً به Ų¹Ł†ŁˆŲ§Ł† یک کاربر وب وجود ŲÆŲ§Ų±ŲÆ.", + "oops": "اوپس!", + "help": "راهنما", + "goHomepage": "رفتن به صفحه Ų§ŲµŁ„ŪŒ", + "joinDiscord": "به سرور دیسکورد Ł…Ų§ ŲØŁ¾ŪŒŁˆŁ†ŲÆŪŒŲÆ", + "seeDockerHub": "مؓاهده Docker Hub", + "visitGithub": "مؓاهده مخزن ŚÆŪŒŲŖā€ŒŁ‡Ų§ŲØ", + "donate": "اهدا Ś©Ł†ŪŒŲÆ", + "color": "رنگ", + "sponsor": "Ų­Ł…Ų§ŪŒŲŖ Ł…Ų§Ł„ŪŒ", + "info": "اطلاعات", + "pro": "نسخه Ų­Ų±ŁŁ‡ā€ŒŲ§ŪŒ", + "page": "صفحه", + "pages": "صفحات", + "loading": "ŲÆŲ± Ų­Ų§Ł„ بارگذاری...", + "addToDoc": "اضافه کردن به سند", + "reset": "ŲŖŁ†ŲøŪŒŁ… Ł…Ų¬ŲÆŲÆ", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "سیاست حفظ Ų­Ų±ŪŒŁ… خصوصی", + "terms": "ؓرایط و ضوابط", + "accessibility": "دسترسی", + "cookie": "سیاست Ś©ŁˆŚ©ŪŒā€ŒŁ‡Ų§", + "impressum": "توضیحات Ł‚Ų§Ł†ŁˆŁ†ŪŒ", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Ł…Ł†ŁˆŪŒ Ł¾Ų§ŪŒŁ¾Ł„Ų§ŪŒŁ† (نسخه ŲØŲŖŲ§)", + "uploadButton": "Ų¢Ł¾Ł„ŁˆŲÆ سفارؓی", + "configureButton": "Ł¾ŪŒŚ©Ų±ŲØŁ†ŲÆŪŒ", + "defaultOption": "سفارؓی", + "submitButton": "Ų§Ų±Ų³Ų§Ł„", + "help": "Ų±Ų§Ł‡Ł†Ł…Ų§ŪŒ Ł¾Ų§ŪŒŁ¾Ł„Ų§ŪŒŁ†", + "scanHelp": "Ų±Ų§Ł‡Ł†Ł…Ų§ŪŒ اسکن Ł¾ŁˆŲ“Ł‡", + "deletePrompt": "آیا مطمئن Ł‡Ų³ŲŖŪŒŲÆ که Ł…ŪŒā€ŒŲ®ŁˆŲ§Ł‡ŪŒŲÆ Ł¾Ų§ŪŒŁ¾Ł„Ų§ŪŒŁ† Ų±Ų§ حذف Ś©Ł†ŪŒŲÆŲŸ", + "tags": "Ų§ŲŖŁˆŁ…Ų§Ų³ŪŒŁˆŁ†ŲŒŲŖŲ±ŲŖŪŒŲØŲŒŲ§Ų³Ś©Ų±ŪŒŁ¾ŲŖā€ŒŲ“ŲÆŁ‡ŲŒŁ¾Ų±ŲÆŲ§Ų²Ų“ ŲÆŲ³ŲŖŁ‡ā€ŒŲ§ŪŒ", + "title": "Ų®Ų· Ł„ŁˆŁ„Ł‡" + }, + "pipelineOptions": { + "header": "Ł¾ŪŒŚ©Ų±ŲØŁ†ŲÆŪŒ Ł¾Ų§ŪŒŁ¾Ł„Ų§ŪŒŁ†", + "pipelineNameLabel": "نام Ł¾Ų§ŪŒŁ¾Ł„Ų§ŪŒŁ†", + "saveSettings": "Ų°Ų®ŪŒŲ±Ł‡ ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ Ų¹Ł…Ł„ŪŒŲ§ŲŖ", + "pipelineNamePrompt": "نام Ł¾Ų§ŪŒŁ¾Ł„Ų§ŪŒŁ† Ų±Ų§ Ų§ŪŒŁ†Ų¬Ų§ وارد Ś©Ł†ŪŒŲÆ", + "selectOperation": "Ų¹Ł…Ł„ŪŒŲ§ŲŖ Ų±Ų§ انتخاب Ś©Ł†ŪŒŲÆ", + "addOperationButton": "اضافه کردن Ų¹Ł…Ł„ŪŒŲ§ŲŖ", + "pipelineHeader": "Ł¾Ų§ŪŒŁ¾Ł„Ų§ŪŒŁ†:", + "saveButton": "ŲÆŲ§Ł†Ł„ŁˆŲÆ", + "validateButton": "Ų§Ų¹ŲŖŲØŲ§Ų±Ų³Ł†Ų¬ŪŒ" + }, + "enterpriseEdition": { + "button": "ارتقا به نسخه Ų­Ų±ŁŁ‡ā€ŒŲ§ŪŒ", + "warning": "Ų§ŪŒŁ† ویژگی فقط برای کاربران Ų­Ų±ŁŁ‡ā€ŒŲ§ŪŒ ŲÆŲ± ŲÆŲ³ŲŖŲ±Ų³ Ų§Ų³ŲŖ.", + "yamlAdvert": "Stirling PDF Pro Ų§Ų² ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ Ł¾ŪŒŚ©Ų±ŲØŁ†ŲÆŪŒ YAML و دیگر ŁˆŪŒŚ˜ŚÆŪŒā€ŒŁ‡Ų§ŪŒ SSO Ł¾Ų“ŲŖŪŒŲØŲ§Ł†ŪŒ Ł…ŪŒā€ŒŚ©Ł†ŲÆ.", + "ssoAdvert": "به دنبال ŁˆŪŒŚ˜ŚÆŪŒā€ŒŁ‡Ų§ŪŒ بیؓتر برای Ł…ŲÆŪŒŲ±ŪŒŲŖ کاربران Ł‡Ų³ŲŖŪŒŲÆŲŸ Stirling PDF Pro Ų±Ų§ بررسی Ś©Ł†ŪŒŲÆ" + }, + "analytics": { + "title": "آیا Ł…ŪŒā€ŒŲ®ŁˆŲ§Ł‡ŪŒŲÆ Stirling PDF Ų±Ų§ بهتر Ś©Ł†ŪŒŲÆŲŸ", + "paragraph1": "Stirling PDF Ų§Ų² ŲŖŲ­Ł„ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ اختیاری استفاده Ł…ŪŒā€ŒŚ©Ł†ŲÆ ŲŖŲ§ به Ł…Ų§ ŲÆŲ± ŲØŁ‡ŲØŁˆŲÆ Ł…Ų­ŲµŁˆŁ„ کمک کند. Ł…Ų§ Ł‡ŪŒŚ† اطلاعات ؓخصی یا Ł…Ų­ŲŖŁˆŲ§ŪŒ ŁŲ§ŪŒŁ„ Ų±Ų§ ردیابی Ł†Ł…ŪŒā€ŒŚ©Ł†ŪŒŁ….", + "paragraph2": "لطفاً ŲÆŲ± نظر بگیرید که ŲŖŲ­Ł„ŪŒŁ„ā€ŒŁ‡Ų§ Ų±Ų§ فعال Ś©Ł†ŪŒŲÆ ŲŖŲ§ به Ų±Ų“ŲÆ Stirling PDF کمک کرده و Ł…Ų§ Ų±Ų§ ŲÆŲ± درک بهتر کاربران یاری Ś©Ł†ŪŒŲÆ.", + "enable": "فعال کردن ŲŖŲ­Ł„ŪŒŁ„ā€ŒŁ‡Ų§", + "disable": "ŲŗŪŒŲ±ŁŲ¹Ų§Ł„ کردن ŲŖŲ­Ł„ŪŒŁ„ā€ŒŁ‡Ų§", + "settings": "Ł…ŪŒā€ŒŲŖŁˆŲ§Ł†ŪŒŲÆ ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ Ł…Ų±ŲØŁˆŲ· به ŲŖŲ­Ł„ŪŒŁ„ā€ŒŁ‡Ų§ Ų±Ų§ ŲÆŲ± ŁŲ§ŪŒŁ„ config/settings.yml تغییر ŲÆŁ‡ŪŒŲÆ" + }, + "navbar": { + "favorite": "Ų¹Ł„Ų§Ł‚Ł‡ā€ŒŁ…Ł†ŲÆŪŒā€ŒŁ‡Ų§", + "recent": "New and recently updated", + "darkmode": "حالت تاریک", + "language": "Ų²ŲØŲ§Ł†ā€ŒŁ‡Ų§", + "settings": "ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ", + "allTools": "ابزارها", + "multiTool": "چند Ų§ŲØŲ²Ų§Ų±", + "search": "جستجو", + "sections": { + "organize": "Ų³Ų§Ų²Ł…Ų§Ł†ŲÆŁ‡ŪŒ", + "convertTo": "ŲŖŲØŲÆŪŒŁ„ به PDF", + "convertFrom": "ŲŖŲØŲÆŪŒŁ„ Ų§Ų² PDF", + "security": "Ų§Ł…Ų¶Ų§ و Ų§Ł…Ł†ŪŒŲŖ", + "advance": "Ł¾ŪŒŲ“Ų±ŁŲŖŁ‡", + "edit": "مؓاهده و ویرایؓ", + "popular": "Ł…Ų­ŲØŁˆŲØ" + } + }, + "settings": { + "title": "ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ", + "update": "ŲØŁ‡ā€ŒŲ±ŁˆŲ²Ų±Ų³Ų§Ł†ŪŒ Ł…ŁˆŲ¬ŁˆŲÆ Ų§Ų³ŲŖ", + "updateAvailable": "{0} نسخه نصب ؓده ŁŲ¹Ł„ŪŒ Ų§Ų³ŲŖ. یک نسخه جدید ({1}) Ł…ŁˆŲ¬ŁˆŲÆ Ų§Ų³ŲŖ.", + "appVersion": "نسخه برنامه:", + "downloadOption": { + "title": "ŚÆŲ²ŪŒŁ†Ł‡ ŲÆŲ§Ł†Ł„ŁˆŲÆ Ų±Ų§ انتخاب Ś©Ł†ŪŒŲÆ (برای ŲÆŲ§Ł†Ł„ŁˆŲÆ یک ŁŲ§ŪŒŁ„ غیر فؓرده):", + "1": "ŲØŲ§Ų² کردن ŲÆŲ± همان پنجره", + "2": "ŲØŲ§Ų² کردن ŲÆŲ± پنجره جدید", + "3": "ŲÆŲ§Ł†Ł„ŁˆŲÆ ŁŲ§ŪŒŁ„" + }, + "zipThreshold": "فؓرده کردن ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ ŁˆŁ‚ŲŖŪŒ ŲŖŲ¹ŲÆŲ§ŲÆ ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ ŲÆŲ§Ł†Ł„ŁˆŲÆ ؓده بیؓتر ؓود Ų§Ų²", + "signOut": "خروج", + "accountSettings": "ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ Ų­Ų³Ų§ŲØ کاربری", + "bored": { + "help": "فعال کردن بازی Ł…Ų®ŁŪŒ" + }, + "cacheInputs": { + "name": "Ų°Ų®ŪŒŲ±Ł‡ ŁˆŲ±ŁˆŲÆŪŒā€ŒŁ‡Ų§ŪŒ فرم", + "help": "فعال کردن برای Ų°Ų®ŪŒŲ±Ł‡ ŁˆŲ±ŁˆŲÆŪŒā€ŒŁ‡Ų§ŪŒ Ł‚ŲØŁ„ŪŒ برای اجرای بعدی" + } + }, + "changeCreds": { + "title": "تغییر Ł…Ų“Ų®ŲµŲ§ŲŖ", + "header": "ŲØŁ‡ā€ŒŲ±ŁˆŲ²Ų±Ų³Ų§Ł†ŪŒ جزئیات Ų­Ų³Ų§ŲØ کاربری", + "changePassword": "Ų“Ł…Ų§ Ų§Ų² Ł…Ų“Ų®ŲµŲ§ŲŖ Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶ ورود استفاده Ł…ŪŒā€ŒŚ©Ł†ŪŒŲÆ. لطفاً یک رمز عبور جدید وارد Ś©Ł†ŪŒŲÆ", + "newUsername": "نام کاربری جدید", + "oldPassword": "رمز عبور ŁŲ¹Ł„ŪŒ", + "newPassword": "رمز عبور جدید", + "confirmNewPassword": "تأیید رمز عبور جدید", + "submit": "Ų«ŲØŲŖ تغییرات" + }, + "account": { + "title": "ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ Ų­Ų³Ų§ŲØ", + "accountSettings": "ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ Ų­Ų³Ų§ŲØ", + "adminSettings": "ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ Ų§ŲÆŁ…ŪŒŁ† - مؓاهده و اضافه کردن کاربران", + "userControlSettings": "ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ کنترل کاربران", + "changeUsername": "تغییر نام کاربری", + "newUsername": "نام کاربری جدید", + "password": "رمز عبور ŲŖŲ£ŪŒŪŒŲÆŪŒŁ‡", + "oldPassword": "رمز عبور Ł‚ŲÆŪŒŁ…ŪŒ", + "newPassword": "رمز عبور جدید", + "changePassword": "تغییر رمز عبور", + "confirmNewPassword": "تأیید رمز عبور جدید", + "signOut": "خروج", + "yourApiKey": "Ś©Ł„ŪŒŲÆ API Ų“Ł…Ų§", + "syncTitle": "Ł‡Ł…ŚÆŲ§Ł…ā€ŒŲ³Ų§Ų²ŪŒ ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ Ł…Ų±ŁˆŲ±ŚÆŲ± ŲØŲ§ Ų­Ų³Ų§ŲØ", + "settingsCompare": "Ł…Ł‚Ų§ŪŒŲ³Ł‡ ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ:", + "property": "ویژگی", + "webBrowserSettings": "ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ Ł…Ų±ŁˆŲ±ŚÆŲ± وب", + "syncToBrowser": "Ł‡Ł…ŚÆŲ§Ł…ā€ŒŲ³Ų§Ų²ŪŒ Ų­Ų³Ų§ŲØ -> Ł…Ų±ŁˆŲ±ŚÆŲ±", + "syncToAccount": "Ł‡Ł…ŚÆŲ§Ł…ā€ŒŲ³Ų§Ų²ŪŒ Ų­Ų³Ų§ŲØ <- Ł…Ų±ŁˆŲ±ŚÆŲ±" + }, + "adminUserSettings": { + "title": "ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ کنترل کاربران", + "header": "ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ کنترل کاربران توسط Ų§ŲÆŁ…ŪŒŁ†", + "admin": "Ų§ŲÆŁ…ŪŒŁ†", + "user": "کاربر", + "addUser": "اضافه کردن کاربر جدید", + "deleteUser": "حذف کاربر", + "confirmDeleteUser": "آیا باید کاربر حذف ؓود؟", + "confirmChangeUserStatus": "آیا باید وضعیت کاربر ŲŗŪŒŲ±ŁŲ¹Ų§Ł„/فعال ؓود؟", + "usernameInfo": "نام کاربری فقط Ł…ŪŒā€ŒŲŖŁˆŲ§Ł†ŲÆ Ų“Ų§Ł…Ł„ حروف، Ų§Ų¹ŲÆŲ§ŲÆ و Ś©Ų§Ų±Ų§Ś©ŲŖŲ±Ł‡Ų§ŪŒ Ų®Ų§Ųµ @._+- ŲØŲ§Ų“ŲÆ یا باید یک Ų¢ŲÆŲ±Ų³ Ų§ŪŒŁ…ŪŒŁ„ Ł…Ų¹ŲŖŲØŲ± ŲØŲ§Ų“ŲÆ.", + "roles": "Ł†Ł‚Ų“ā€ŒŁ‡Ų§", + "role": "نقؓ", + "actions": "اقدامات", + "apiUser": "کاربر Ł…Ų­ŲÆŁˆŲÆ API", + "extraApiUser": "کاربر Ł…Ų­ŲÆŁˆŲÆ اضافی API", + "webOnlyUser": "فقط کاربر وب", + "demoUser": "کاربر ŲÆŁ…Łˆ (ŲØŲÆŁˆŁ† ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ سفارؓی)", + "internalApiUser": "کاربر ŲÆŲ§Ų®Ł„ŪŒ API", + "forceChange": "Ł…Ų¬ŲØŁˆŲ± کردن کاربر به تغییر رمز عبور هنگام ورود", + "submit": "Ų°Ų®ŪŒŲ±Ł‡ کاربر", + "changeUserRole": "تغییر نقؓ کاربر", + "authenticated": "Ų§Ų­Ų±Ų§Ų² Ł‡ŁˆŪŒŲŖ ؓده", + "editOwnProfil": "ویرایؓ Ł†Ł…Ų§ŪŒŁ‡ خود", + "enabledUser": "کاربر فعال", + "disabledUser": "کاربر ŲŗŪŒŲ±ŁŲ¹Ų§Ł„", + "activeUsers": "کاربران فعال:", + "disabledUsers": "کاربران ŲŗŪŒŲ±ŁŲ¹Ų§Ł„:", + "totalUsers": "کل کاربران:", + "lastRequest": "Ų¢Ų®Ų±ŪŒŁ† درخواست", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "وارد کردن/ŲµŲ§ŲÆŲ± کردن Ł¾Ų§ŪŒŚÆŲ§Ł‡ داده", + "header": "وارد کردن/ŲµŲ§ŲÆŲ± کردن Ł¾Ų§ŪŒŚÆŲ§Ł‡ داده", + "fileName": "نام ŁŲ§ŪŒŁ„", + "creationDate": "تاریخ ایجاد", + "fileSize": "اندازه ŁŲ§ŪŒŁ„", + "deleteBackupFile": "حذف ŁŲ§ŪŒŁ„ Ł¾Ų“ŲŖŪŒŲØŲ§Ł†", + "importBackupFile": "وارد کردن ŁŲ§ŪŒŁ„ Ł¾Ų“ŲŖŪŒŲØŲ§Ł†", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "ŲÆŲ§Ł†Ł„ŁˆŲÆ ŁŲ§ŪŒŁ„ Ł¾Ų“ŲŖŪŒŲØŲ§Ł†", + "info_1": "هنگام وارد کردن ŲÆŲ§ŲÆŁ‡ā€ŒŁ‡Ų§ŲŒ Ų§Ų·Ł…ŪŒŁ†Ų§Ł† Ų§Ų² Ų³Ų§Ų®ŲŖŲ§Ų± صحیح ضروری Ų§Ų³ŲŖ. Ų§ŚÆŲ± مطمئن Ł†ŪŒŲ³ŲŖŪŒŲÆ چه کاری انجام Ł…ŪŒā€ŒŲÆŁ‡ŪŒŲÆŲŒ Ų§Ų² یک Ł…ŲŖŲ®ŲµŲµ Ł…Ų“Ų§ŁˆŲ±Ł‡ و Ł¾Ų“ŲŖŪŒŲØŲ§Ł†ŪŒ دریافت Ś©Ł†ŪŒŲÆ. Ų®Ų·Ų§ ŲÆŲ± Ų³Ų§Ų®ŲŖŲ§Ų± Ł…ŪŒā€ŒŲŖŁˆŲ§Ł†ŲÆ ŲØŲ§Ų¹Ų« اختلالات برنامه ؓود، حتی ŲŖŲ§ حدی که برنامه به طور کامل قادر به Ų§Ų¬Ų±Ų§ نباؓد.", + "info_2": "نام ŁŲ§ŪŒŁ„ هنگام Ų¢Ł¾Ł„ŁˆŲÆ مهم Ł†ŪŒŲ³ŲŖ. پس Ų§Ų² آن برای پیروی Ų§Ų² قالب backup_user_yyyyMMddHHmm.sql تغییر نام داده Ł…ŪŒā€ŒŲ“ŁˆŲÆ ŲŖŲ§ یک قرارداد Ł†Ų§Ł…ā€ŒŚÆŲ°Ų§Ų±ŪŒ Ų«Ų§ŲØŲŖ Ų±Ų§ ŲŖŲ¶Ł…ŪŒŁ† کند.", + "submit": "وارد کردن Ł¾Ų“ŲŖŪŒŲØŲ§Ł†", + "importIntoDatabaseSuccessed": "وارد کردن ŲÆŲ± Ł¾Ų§ŪŒŚÆŲ§Ł‡ داده Ł…ŁˆŁŁ‚ŪŒŲŖā€ŒŲ¢Ł…ŪŒŲ² بود", + "backupCreated": "Database backup successful", + "fileNotFound": "ŁŲ§ŪŒŁ„ پیدا نؓد", + "fileNullOrEmpty": "ŁŲ§ŪŒŁ„ Ł†ŲØŲ§ŪŒŲÆ Ų®Ų§Ł„ŪŒ یا ŲŖŁ‡ŪŒ ŲØŲ§Ų“ŲÆ", + "failedImportFile": "وارد کردن ŁŲ§ŪŒŁ„ Ł†Ų§Ł…ŁˆŁŁ‚ بود", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "نؓست Ų“Ł…Ų§ به Ł¾Ų§ŪŒŲ§Ł† Ų±Ų³ŪŒŲÆŁ‡ Ų§Ų³ŲŖ. لطفاً صفحه Ų±Ų§ ŲŖŲ§Ų²Ł‡ā€ŒŲ³Ų§Ų²ŪŒ کرده و ŲÆŁˆŲØŲ§Ų±Ł‡ تلاؓ Ś©Ł†ŪŒŲÆ.", + "refreshPage": "ŲŖŲ§Ų²Ł‡ā€ŒŲ³Ų§Ų²ŪŒ صفحه" + }, + "home": { + "desc": "Ł…ŲŗŲ§Ų²Ł‡ā€Œ Ł‡Ł…Ł‡ā€ŒŚ©Ų§Ų±Ł‡ Ł…ŪŒŲ²ŲØŲ§Ł†ŪŒā€ŒŲ“ŲÆŁ‡ به صورت Ł…Ų­Ł„ŪŒ برای ŲŖŁ…Ų§Ł… Ł†ŪŒŲ§Ų²Ł‡Ų§ŪŒ PDF Ų“Ł…Ų§.", + "searchBar": "جستجو برای ŁˆŪŒŚ˜ŚÆŪŒā€ŒŁ‡Ų§...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Ł…Ų“Ų§Ł‡ŲÆŁ‡ŲŒ Ų­Ų§Ų“ŪŒŁ‡ā€ŒŁ†ŁˆŪŒŲ³ŪŒŲŒ Ų§ŁŲ²ŁˆŲÆŁ† متن یا تصاویر" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "Ų§ŲØŲ²Ų§Ų± چندگانه PDF", + "desc": "ترکیب، Ś†Ų±Ų®Ų“ŲŒ بازآرایی، ŲŖŁ‚Ų³ŪŒŁ… و حذف صفحات" + }, + "merge": { + "title": "ترکیب", + "desc": "ترکیب آسان Ś†Ł†ŲÆŪŒŁ† ŁŲ§ŪŒŁ„ PDF ŲÆŲ± یک ŁŲ§ŪŒŁ„." + }, + "split": { + "title": "ŲŖŁ‚Ų³ŪŒŁ…", + "desc": "ŲŖŁ‚Ų³ŪŒŁ… ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ PDF به اسناد چندگانه" + }, + "rotate": { + "title": "چرخؓ", + "desc": "چرخؓ آسان ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ PDF." + }, + "imageToPdf": { + "title": "تصویر به PDF", + "desc": "ŲŖŲØŲÆŪŒŁ„ یک تصویر (PNG، JPEG، GIF) به PDF." + }, + "pdfToImage": { + "title": "PDF به تصویر", + "desc": "ŲŖŲØŲÆŪŒŁ„ یک ŁŲ§ŪŒŁ„ PDF به یک تصویر. (PNG، JPEG، GIF)" + }, + "pdfOrganiser": { + "title": "Ų³Ų§Ų²Ł…Ų§Ł†ŲÆŁ‡ŪŒ", + "desc": "حذف/بازآرایی صفحات به ترتیب ŲÆŁ„Ų®ŁˆŲ§Ł‡" + }, + "addImage": { + "title": "Ų§ŁŲ²ŁˆŲÆŁ† تصویر", + "desc": "Ų§ŁŲ²ŁˆŲÆŁ† یک تصویر به یک مکان Ł…Ų“Ų®Ųµ ŲÆŲ± PDF" + }, + "watermark": { + "title": "Ų§ŁŲ²ŁˆŲÆŁ† ŁˆŲ§ŲŖŲ±Ł…Ų§Ų±Ś©", + "desc": "Ų§ŁŲ²ŁˆŲÆŁ† یک ŁˆŲ§ŲŖŲ±Ł…Ų§Ų±Ś© سفارؓی به سند PDF." + }, + "permissions": { + "title": "تغییر Ł…Ų¬ŁˆŲ²Ł‡Ų§", + "desc": "تغییر Ł…Ų¬ŁˆŲ²Ł‡Ų§ŪŒ سند PDF Ų“Ł…Ų§" + }, + "removePages": { + "title": "حذف", + "desc": "حذف صفحات Ł†Ų§Ų®ŁˆŲ§Ų³ŲŖŁ‡ Ų§Ų² سند PDF Ų“Ł…Ų§." + }, + "addPassword": { + "title": "Ų§ŁŲ²ŁˆŲÆŁ† رمز عبور", + "desc": "Ų±Ł…Ų²ŚÆŲ°Ų§Ų±ŪŒ سند PDF Ų“Ł…Ų§ ŲØŲ§ رمز عبور." + }, + "removePassword": { + "title": "حذف رمز عبور", + "desc": "حذف حفاظت رمز عبور Ų§Ų² سند PDF Ų“Ł…Ų§." + }, + "compressPdfs": { + "title": "ŁŲ“Ų±ŲÆŁ‡ā€ŒŲ³Ų§Ų²ŪŒ", + "desc": "ŁŲ“Ų±ŲÆŁ‡ā€ŒŲ³Ų§Ų²ŪŒ ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ PDF برای کاهؓ اندازه Ų¢Ł†ā€ŒŁ‡Ų§." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "تغییر متاداده", + "desc": "تغییر/حذف/Ų§ŁŲ²ŁˆŲÆŁ† متاداده به یک سند PDF" + }, + "fileToPDF": { + "title": "ŲŖŲØŲÆŪŒŁ„ ŁŲ§ŪŒŁ„ به PDF", + "desc": "ŲŖŲØŲÆŪŒŁ„ ŲŖŁ‚Ų±ŪŒŲØŲ§Ł‹ هر ŁŲ§ŪŒŁ„ به PDF (DOCX، PNG، XLS، PPT، TXT و بیؓتر)" + }, + "ocr": { + "title": "OCR / پاکسازی Ų§Ų³Ś©Ł†ā€ŒŁ‡Ų§", + "desc": "پاکسازی Ų§Ų³Ś©Ł†ā€ŒŁ‡Ų§ و تؓخیص متن Ų§Ų² تصاویر ŲÆŲ±ŁˆŁ† یک ŁŲ§ŪŒŁ„ PDF و ŲØŲ§Ų²Ų§ŁŲ²ŁˆŲÆŁ† آن به Ų¹Ł†ŁˆŲ§Ł† متن." + }, + "extractImages": { + "title": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ تصاویر", + "desc": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ ŲŖŁ…Ų§Ł… تصاویر Ų§Ų² یک PDF و Ų°Ų®ŪŒŲ±Ł‡ Ų¢Ł†ā€ŒŁ‡Ų§ به صورت ŁŲ§ŪŒŁ„ زیپ" + }, + "pdfToPDFA": { + "title": "PDF به PDF/A", + "desc": "ŲŖŲØŲÆŪŒŁ„ PDF به PDF/A برای Ų°Ų®ŪŒŲ±Ł‡ā€ŒŲ³Ų§Ų²ŪŒ بلندمدت" + }, + "PDFToWord": { + "title": "PDF به ورد", + "desc": "ŲŖŲØŲÆŪŒŁ„ PDF به ŁŲ±Ł…ŲŖā€ŒŁ‡Ų§ŪŒ ورد (DOC، DOCX و ODT)" + }, + "PDFToPresentation": { + "title": "PDF به ارائه", + "desc": "ŲŖŲØŲÆŪŒŁ„ PDF به ŁŲ±Ł…ŲŖā€ŒŁ‡Ų§ŪŒ ارائه (PPT، PPTX و ODP)" + }, + "PDFToText": { + "title": "PDF به RTF (متن)", + "desc": "ŲŖŲØŲÆŪŒŁ„ PDF به فرمت متن یا RTF" + }, + "PDFToHTML": { + "title": "PDF به HTML", + "desc": "ŲŖŲØŲÆŪŒŁ„ PDF به فرمت HTML" + }, + "PDFToXML": { + "title": "PDF به XML", + "desc": "ŲŖŲØŲÆŪŒŁ„ PDF به فرمت XML" + }, + "ScannerImageSplit": { + "title": "تؓخیص/ŲŖŁ‚Ų³ŪŒŁ… تصاویر Ų§Ų³Ś©Ł†ā€ŒŲ“ŲÆŁ‡", + "desc": "ŲŖŁ‚Ų³ŪŒŁ… Ś†Ł†ŲÆŪŒŁ† تصویر Ų§Ų² ŲÆŲ±ŁˆŁ† یک تصویر/PDF" + }, + "sign": { + "title": "Ų§Ł…Ų¶Ų§", + "desc": "Ų§ŁŲ²ŁˆŲÆŁ† Ų§Ł…Ų¶Ų§ به PDF ŲØŲ§ Ś©Ų“ŪŒŲÆŁ†ŲŒ متن یا تصویر" + }, + "flatten": { + "title": "تسطیح", + "desc": "حذف ŲŖŁ…Ų§Ł… عناصر ŲŖŲ¹Ų§Ł…Ł„ŪŒ و ŁŲ±Ł…ā€ŒŁ‡Ų§ Ų§Ų² یک PDF" + }, + "repair": { + "title": "ŲŖŲ±Ł…ŪŒŁ…", + "desc": "تلاؓ برای ŲŖŲ±Ł…ŪŒŁ… یک PDF Ų®Ų±Ų§ŲØ/ؓکسته" + }, + "removeBlanks": { + "title": "حذف صفحات Ų®Ų§Ł„ŪŒ", + "desc": "تؓخیص و حذف صفحات Ų®Ų§Ł„ŪŒ Ų§Ų² یک سند" + }, + "removeAnnotations": { + "title": "حذف Ų­Ų§Ų“ŪŒŁ‡ā€ŒŁ†ŁˆŪŒŲ³ŪŒā€ŒŁ‡Ų§", + "desc": "حذف ŲŖŁ…Ų§Ł… نظرات/Ų­Ų§Ų“ŪŒŁ‡ā€ŒŁ†ŁˆŪŒŲ³ŪŒā€ŒŁ‡Ų§ Ų§Ų² یک PDF" + }, + "compare": { + "title": "Ł…Ł‚Ų§ŪŒŲ³Ł‡", + "desc": "Ł…Ł‚Ų§ŪŒŲ³Ł‡ و Ł†Ł…Ų§ŪŒŲ“ ŲŖŁŲ§ŁˆŲŖā€ŒŁ‡Ų§ ŲØŪŒŁ† 2 سند PDF" + }, + "certSign": { + "title": "Ų§Ł…Ų¶Ų§ ŲØŲ§ ŚÆŁˆŲ§Ł‡ŪŒŁ†Ų§Ł…Ł‡", + "desc": "Ų§Ł…Ų¶Ų§ŪŒ یک PDF ŲØŲ§ ŚÆŁˆŲ§Ł‡ŪŒŁ†Ų§Ł…Ł‡/Ś©Ł„ŪŒŲÆ (PEM/P12)" + }, + "removeCertSign": { + "title": "حذف Ų§Ł…Ų¶Ų§ŪŒ ŚÆŁˆŲ§Ł‡ŪŒŁ†Ų§Ł…Ł‡", + "desc": "حذف Ų§Ł…Ų¶Ų§ŪŒ ŚÆŁˆŲ§Ł‡ŪŒŁ†Ų§Ł…Ł‡ Ų§Ų² PDF" + }, + "pageLayout": { + "title": "Ų·Ų±Ų­ā€ŒŲØŁ†ŲÆŪŒ چند ŲµŁŲ­Ł‡ā€ŒŲ§ŪŒ", + "desc": "Ų§ŲÆŲŗŲ§Ł… Ś†Ł†ŲÆŪŒŁ† صفحه یک سند PDF ŲÆŲ± یک صفحه واحد" + }, + "scalePages": { + "title": "ŲŖŁ†ŲøŪŒŁ… اندازه/Ł…Ł‚ŪŒŲ§Ų³ صفحه", + "desc": "تغییر اندازه/Ł…Ł‚ŪŒŲ§Ų³ یک صفحه و/یا Ł…Ų­ŲŖŁˆŲ§ŪŒ آن." + }, + "pipeline": { + "title": "Ų®Ų· Ł„ŁˆŁ„Ł‡", + "desc": "اجرای Ś†Ł†ŲÆŪŒŁ† Ų¹Ł…Ł„ŪŒŲ§ŲŖ ŲØŲ± روی PDFها ŲØŲ§ تعریف Ų§Ų³Ś©Ų±ŪŒŁ¾ŲŖā€ŒŁ‡Ų§ŪŒ Ų®Ų· Ł„ŁˆŁ„Ł‡" + }, + "add-page-numbers": { + "title": "Ų§ŁŲ²ŁˆŲÆŁ† ؓماره صفحات", + "desc": "Ų§ŁŲ²ŁˆŲÆŁ† ؓماره صفحات به ŲŖŁ…Ų§Ł… سند ŲÆŲ± یک مکان Ł…Ų“Ų®Ųµ" + }, + "auto-rename": { + "title": "تغییر نام خودکار ŁŲ§ŪŒŁ„ PDF", + "desc": "تغییر نام خودکار یک ŁŲ§ŪŒŁ„ PDF ŲØŲ± Ų§Ų³Ų§Ų³ سربرگ تؓخیص ŲÆŲ§ŲÆŁ‡ā€ŒŲ“ŲÆŁ‡ آن" + }, + "adjust-contrast": { + "title": "ŲŖŁ†ŲøŪŒŁ… Ų±Ł†ŚÆā€ŒŁ‡Ų§/کنتراست", + "desc": "ŲŖŁ†ŲøŪŒŁ… Ś©Ł†ŲŖŲ±Ų§Ų³ŲŖŲŒ Ų§Ų“ŲØŲ§Ų¹ و Ų±ŁˆŲ“Ł†Ų§ŪŒŪŒ یک PDF" + }, + "crop": { + "title": "ŲØŲ±Ų“ PDF", + "desc": "ŲØŲ±Ų“ یک PDF برای کاهؓ اندازه آن (متن Ų±Ų§ حفظ Ł…ŪŒā€ŒŚ©Ł†ŲÆ!)" + }, + "autoSplitPDF": { + "title": "ŲŖŁ‚Ų³ŪŒŁ… خودکار صفحات", + "desc": "ŲŖŁ‚Ų³ŪŒŁ… خودکار ŁŲ§ŪŒŁ„ Ų§Ų³Ś©Ł†ā€ŒŲ“ŲÆŁ‡ PDF ŲØŲ§ استفاده Ų§Ų² کد QR ŲŖŁ‚Ų³ŪŒŁ…ā€ŒŚ©Ł†Ł†ŲÆŁ‡ فیزیکی" + }, + "sanitizePdf": { + "title": "پاکسازی", + "desc": "حذف Ų§Ų³Ś©Ų±ŪŒŁ¾ŲŖā€ŒŁ‡Ų§ و سایر عناصر Ų§Ų² ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ PDF" + }, + "URLToPDF": { + "title": "URL/ŁˆŲØā€ŒŲ³Ų§ŪŒŲŖ به PDF", + "desc": "ŲŖŲØŲÆŪŒŁ„ هر http(s)URL به PDF" + }, + "HTMLToPDF": { + "title": "HTML به PDF", + "desc": "ŲŖŲØŲÆŪŒŁ„ هر ŁŲ§ŪŒŁ„ HTML یا زیپ به PDF" + }, + "MarkdownToPDF": { + "title": "Ł…Ų§Ų±Ś©ā€ŒŲÆŲ§ŁˆŁ† به PDF", + "desc": "ŲŖŲØŲÆŪŒŁ„ هر ŁŲ§ŪŒŁ„ Ł…Ų§Ų±Ś©ā€ŒŲÆŲ§ŁˆŁ† به PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "دریافت ŲŖŁ…Ų§Ł… اطلاعات ŲÆŲ± Ł…ŁˆŲ±ŲÆ PDF", + "desc": "گرفتن هر اطلاعات ممکن ŲÆŲ± Ł…ŁˆŲ±ŲÆ PDF" + }, + "extractPage": { + "title": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ صفحه(ها)", + "desc": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ صفحات Ų§Ł†ŲŖŲ®Ų§ŲØŪŒ Ų§Ų² PDF" + }, + "PdfToSinglePage": { + "title": "صفحه بزرگ واحد", + "desc": "Ų§ŲÆŲŗŲ§Ł… ŲŖŁ…Ų§Ł… صفحات PDF ŲÆŲ± یک صفحه بزرگ واحد" + }, + "showJS": { + "title": "Ł†Ł…Ų§ŪŒŲ“ جاوااسکریپت", + "desc": "جستجو و Ł†Ł…Ų§ŪŒŲ“ هر جاوااسکریپت ŲŖŲ²Ų±ŪŒŁ‚ ؓده به PDF" + }, + "autoRedact": { + "title": "Ų³Ų§Ł†Ų³ŁˆŲ± خودکار", + "desc": "Ł…ŲŖŁ†ā€ŒŁ‡Ų§ŪŒ Ł…Ų“Ų®Ųµ ؓده ŲÆŲ± PDF Ų±Ų§ ŲØŁ‡ā€ŒŲ·ŁˆŲ± خودکار Ų³Ų§Ł†Ų³ŁˆŲ± (Ų³ŪŒŲ§Ł‡) Ł…ŪŒā€ŒŚ©Ł†ŲÆ" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF به CSV", + "desc": "Ų¬ŲÆŲ§ŁˆŁ„ Ų±Ų§ Ų§Ų² PDF Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ کرده و به CSV ŲŖŲØŲÆŪŒŁ„ Ł…ŪŒā€ŒŚ©Ł†ŲÆ" + }, + "autoSizeSplitPDF": { + "title": "ŲŖŁ‚Ų³ŪŒŁ… خودکار ŲØŲ± Ų§Ų³Ų§Ų³ اندازه/ŲŖŲ¹ŲÆŲ§ŲÆ", + "desc": "ŲŖŁ‚Ų³ŪŒŁ… یک PDF به چند سند ŲØŲ± Ų§Ų³Ų§Ų³ Ų§Ł†ŲÆŲ§Ų²Ł‡ŲŒ ŲŖŲ¹ŲÆŲ§ŲÆ صفحات، یا ŲŖŲ¹ŲÆŲ§ŲÆ اسناد" + }, + "overlay-pdfs": { + "title": "Ł‡Ł…ā€ŒŁ¾ŁˆŲ“Ų§Ł†ŪŒ PDFā€ŒŁ‡Ų§", + "desc": "PDFā€ŒŁ‡Ų§ Ų±Ų§ ŲØŲ± روی PDF دیگری Ł‡Ł…ā€ŒŁ¾ŁˆŲ“Ų§Ł†ŪŒ Ł…ŪŒā€ŒŚ©Ł†ŲÆ" + }, + "split-by-sections": { + "title": "ŲŖŁ‚Ų³ŪŒŁ… PDF ŲØŲ± Ų§Ų³Ų§Ų³ ŲØŲ®Ų“ā€ŒŁ‡Ų§", + "desc": "هر صفحه Ų§Ų² PDF Ų±Ų§ به ŲØŲ®Ų“ā€ŒŁ‡Ų§ŪŒ Ų§ŁŁ‚ŪŒ و Ų¹Ł…ŁˆŲÆŪŒ Ś©ŁˆŚ†Ś©ā€ŒŲŖŲ± ŲŖŁ‚Ų³ŪŒŁ… Ł…ŪŒā€ŒŚ©Ł†ŲÆ" + }, + "AddStampRequest": { + "title": "Ų§ŁŲ²ŁˆŲÆŁ† مهر به PDF", + "desc": "Ų§ŁŲ²ŁˆŲÆŁ† مهر Ł…ŲŖŁ†ŪŒ یا تصویری ŲÆŲ± Ł…Ś©Ų§Ł†ā€ŒŁ‡Ų§ŪŒ Ł…Ų“Ų®Ųµ" + }, + "removeImagePdf": { + "title": "حذف تصویر", + "desc": "حذف تصاویر Ų§Ų² PDF برای کاهؓ حجم ŁŲ§ŪŒŁ„" + }, + "splitPdfByChapters": { + "title": "ŲŖŁ‚Ų³ŪŒŁ… PDF ŲØŲ± Ų§Ų³Ų§Ų³ ŁŲµŁ„ā€ŒŁ‡Ų§", + "desc": "ŲŖŁ‚Ų³ŪŒŁ… PDF به چند ŁŲ§ŪŒŁ„ ŲØŲ± Ų§Ų³Ų§Ų³ Ų³Ų§Ų®ŲŖŲ§Ų± ŁŲµŁ„ā€ŒŁ‡Ų§" + }, + "validateSignature": { + "title": "Ų§Ų¹ŲŖŲØŲ§Ų±Ų³Ł†Ų¬ŪŒ Ų§Ł…Ų¶Ų§ŪŒ PDF", + "desc": "تأیید امضاها و ŚÆŁˆŲ§Ł‡ŪŒā€ŒŁ‡Ų§ŪŒ ŲÆŪŒŲ¬ŪŒŲŖŲ§Ł„ ŲÆŲ± اسناد PDF" + }, + "replaceColorPdf": { + "title": "Ų¬Ų§ŪŒŚÆŲ²ŪŒŁ†ŪŒ و Ł…Ų¹Ś©ŁˆŲ³ کردن رنگ", + "desc": "Ų¬Ų§ŪŒŚÆŲ²ŪŒŁ†ŪŒ رنگ متن و Ł¾Ų³ā€ŒŲ²Ł…ŪŒŁ†Ł‡ ŲÆŲ± PDF و Ł…Ų¹Ś©ŁˆŲ³ کردن کل Ų±Ł†ŚÆā€ŒŁ‡Ų§ برای کاهؓ حجم ŁŲ§ŪŒŁ„" + } + }, + "viewPdf": { + "tags": "Ł…Ų“Ų§Ł‡ŲÆŁ‡ŲŒŲ®ŁˆŲ§Ł†ŲÆŁ†ŲŒŲ­Ų§Ų“ŪŒŁ‡ā€ŒŁ†ŁˆŪŒŲ³ŪŒŲŒŁ…ŲŖŁ†ŲŒŲŖŲµŁˆŪŒŲ±", + "title": "View/Edit PDF", + "header": "مؓاهده PDF" + }, + "multiTool": { + "tags": "Ų§ŲØŲ²Ų§Ų± Ś†Ł†ŲÆŚÆŲ§Ł†Ł‡ŲŒŲ¹Ł…Ł„ŪŒŲ§ŲŖ Ś†Ł†ŲÆŚÆŲ§Ł†Ł‡ŲŒŁˆŲ§Ų³Ų· Ś©Ų§Ų±ŲØŲ±ŪŒŲŒŚ©Ł„ŪŒŚ© و Ś©Ų“ŪŒŲÆŁ†ŲŒŁŲ±Ų§Ł†ŲŖā€ŒŲ§Ł†ŲÆŲŒŚ©Ų§Ų±ŲØŲ±ŲÆŪŒŲŒŁ‚Ų§ŲØŁ„ ŲŖŲ¹Ų§Ł…Ł„ŲŒŲ¬Ų§ŲØŲ¬Ų§ŪŒŪŒŲŒŲ­Ų°ŁŲŒŲŖŁ‚Ų³ŪŒŁ…", + "title": "Ų§ŲØŲ²Ų§Ų± چندگانه PDF", + "header": "Ų§ŲØŲ²Ų§Ų± چندگانه PDF", + "uploadPrompts": "نام ŁŲ§ŪŒŁ„", + "selectAll": "انتخاب همه", + "deselectAll": "Ł„ŲŗŁˆ انتخاب همه", + "selectPages": "انتخاب صفحه", + "selectedPages": "صفحات انتخاب ؓده", + "page": "صفحه", + "deleteSelected": "حذف انتخاب Ų“ŲÆŁ‡ā€ŒŁ‡Ų§", + "downloadAll": "ŲµŲ§ŲÆŲ± کردن", + "downloadSelected": "ŲµŲ§ŲÆŲ± کردن انتخاب Ų“ŲÆŁ‡ā€ŒŁ‡Ų§", + "insertPageBreak": "ŲÆŲ±Ų¬ ؓکست صفحه", + "addFile": "Ų§ŁŲ²ŁˆŲÆŁ† ŁŲ§ŪŒŁ„", + "rotateLeft": "چرخاندن به چپ", + "rotateRight": "چرخاندن به Ų±Ų§Ų³ŲŖ", + "split": "ŲŖŁ‚Ų³ŪŒŁ…", + "moveLeft": "جابجایی به چپ", + "moveRight": "جابجایی به Ų±Ų§Ų³ŲŖ", + "delete": "حذف", + "dragDropMessage": "صفحه(ها) انتخاب Ų“ŲÆŁ‡ā€ŒŲ§Ł†ŲÆ", + "undo": "واگرد", + "redo": "بازگرداندن" + }, + "merge": { + "tags": "ŲŖŲ±Ś©ŪŒŲØŲŒŲ¹Ł…Ł„ŪŒŲ§ŲŖ ŲµŁŲ­Ų§ŲŖŲŒŲØŚ©ā€ŒŲ§Ł†ŲÆŲŒŲ³Ł…ŲŖ سرور", + "title": "Ų§ŲÆŲŗŲ§Ł…", + "header": "Ų§ŲÆŲŗŲ§Ł… Ś†Ł†ŲÆŪŒŁ† PDF (Ū²+)", + "sortByName": "Ł…Ų±ŲŖŲØā€ŒŲ³Ų§Ų²ŪŒ ŲØŲ± Ų§Ų³Ų§Ų³ نام", + "sortByDate": "Ł…Ų±ŲŖŲØā€ŒŲ³Ų§Ų²ŪŒ ŲØŲ± Ų§Ų³Ų§Ų³ تاریخ", + "removeCertSign": "حذف Ų§Ł…Ų¶Ų§ŪŒ ŲÆŪŒŲ¬ŪŒŲŖŲ§Ł„ ŲÆŲ± ŁŲ§ŪŒŁ„ Ų§ŲÆŲŗŲ§Ł…ā€ŒŲ“ŲÆŁ‡ŲŸ", + "submit": "Ų§ŲÆŲŗŲ§Ł…" + }, + "split": { + "tags": "Ų¹Ł…Ł„ŪŒŲ§ŲŖ ŲµŁŲ­Ų§ŲŖŲŒŲŖŁ‚Ų³ŪŒŁ…ŲŒŚ†Ł†ŲÆ ŲµŁŲ­Ł‡ŲŒŲØŲ±Ų“ŲŒŲ³Ł…ŲŖ سرور", + "title": "ŲŖŁ‚Ų³ŪŒŁ… PDF", + "header": "ŲŖŁ‚Ų³ŪŒŁ… PDF", + "desc": { + "1": "اعدادی که انتخاب Ł…ŪŒā€ŒŚ©Ł†ŪŒŲÆ ؓماره ŲµŁŲ­Ł‡ā€ŒŁ‡Ų§ŪŒŪŒ هستند که Ł…ŪŒā€ŒŲ®ŁˆŲ§Ł‡ŪŒŲÆ ŲØŲ± روی آنها ŲŖŁ‚Ų³ŪŒŁ… انجام ŲÆŁ‡ŪŒŲÆ", + "2": "ŲØŁ†Ų§ŲØŲ±Ų§ŪŒŁ† انتخاب Ū±,Ū³,Ū·-Ū¹ یک سند Ū±Ū° ŲµŁŲ­Ł‡ā€ŒŲ§ŪŒ Ų±Ų§ به Ū¶ PDF جداگانه ŲŖŁ‚Ų³ŪŒŁ… Ł…ŪŒā€ŒŚ©Ł†ŲÆ ŲØŲ§:", + "3": "سند #1: صفحه Ū±", + "4": "سند #2: صفحه Ū² و Ū³", + "5": "سند #3: صفحه ۓ، ۵، ۶، Ū·", + "6": "سند #4: صفحه Ūø", + "7": "سند #5: صفحه Ū¹", + "8": "سند #6: صفحه Ū±Ū°" + }, + "splitPages": "صفحات برای ŲŖŁ‚Ų³ŪŒŁ… Ų±Ų§ وارد Ś©Ł†ŪŒŲÆ:", + "submit": "ŲŖŁ‚Ų³ŪŒŁ…" + }, + "rotate": { + "tags": "سمت سرور", + "title": "چرخؓ PDF", + "header": "چرخؓ PDF", + "selectAngle": "Ų²Ų§ŁˆŪŒŁ‡ چرخؓ Ų±Ų§ انتخاب Ś©Ł†ŪŒŲÆ (به Ł…Ų¶Ų±ŲØā€ŒŁ‡Ų§ŪŒ Ū¹Ū° درجه):", + "submit": "چرخؓ" + }, + "imageToPdf": { + "tags": "ŲŖŲØŲÆŪŒŁ„ŲŒŲ¹Ś©Ų³ŲŒjpg،تصویر،عکس" + }, + "pdfToImage": { + "tags": "ŲŖŲØŲÆŪŒŁ„ŲŒŲ¹Ś©Ų³ŲŒjpg،تصویر،عکس", + "title": "PDF به تصویر", + "header": "PDF به تصویر", + "selectText": "فرمت تصویر", + "singleOrMultiple": "Ł†ŁˆŲ¹ Ł†ŲŖŪŒŲ¬Ł‡ تصویر", + "single": "یک تصویر بزرگ", + "multi": "Ś†Ł†ŲÆŪŒŁ† تصویر", + "colorType": "Ł†ŁˆŲ¹ رنگ", + "color": "رنگ", + "grey": "خاکستری", + "blackwhite": "Ų³ŪŒŲ§Ł‡ و سفید (ممکن Ų§Ų³ŲŖ اطلاعات Ų§Ų² ŲÆŲ³ŲŖ برود!)", + "submit": "ŲŖŲØŲÆŪŒŁ„", + "info": "Ł¾Ų§ŪŒŲŖŁˆŁ† نصب نؓده Ų§Ų³ŲŖ. برای ŲŖŲØŲÆŪŒŁ„ WebP لازم Ų§Ų³ŲŖ.", + "placeholder": "(Ł…Ų«Ų§Ł„: 1,2,8 یا 4,7,12-16 یا 2n-1)" + }, + "pdfOrganiser": { + "tags": "ŲÆŁˆŲ·Ų±ŁŁ‡ŲŒŲ²ŁˆŲ¬ŲŒŁŲ±ŲÆŲŒŁ…Ų±ŲŖŲØā€ŒŲ³Ų§Ų²ŪŒŲŒŲ¬Ų§ŲØŲ¬Ų§ŪŒŪŒ", + "title": "Ų³Ų§Ų²Ł…Ų§Ł†ŲÆŁ‡ŪŒ صفحات", + "header": "Ų³Ų§Ų²Ł…Ų§Ł†ŲÆŁ‡ŪŒ صفحات PDF", + "submit": "بازآرایی صفحات", + "mode": { + "_value": "حالت", + "1": "ترتیب سفارؓی صفحات", + "2": "ترتیب Ł…Ų¹Ś©ŁˆŲ³", + "3": "Ł…Ų±ŲŖŲØā€ŒŲ³Ų§Ų²ŪŒ ŲÆŁˆŲ·Ų±ŁŁ‡", + "4": "Ł…Ų±ŲŖŲØā€ŒŲ³Ų§Ų²ŪŒ Ś©ŲŖŲ§ŲØŚ†Ł‡ā€ŒŲ§ŪŒ", + "5": "Ł…Ų±ŲŖŲØā€ŒŲ³Ų§Ų²ŪŒ Ś©ŲŖŲ§ŲØŚ†Ł‡ā€ŒŲ§ŪŒ سیدی Ų§Ų³ŲŖŪŒŚ†", + "6": "جداسازی فرد و زوج", + "7": "حذف Ų§ŁˆŁ„ŪŒŁ†", + "8": "حذف Ų¢Ų®Ų±ŪŒŁ†", + "9": "حذف Ų§ŁˆŁ„ و Ų¢Ų®Ų±", + "10": "Ų§ŲÆŲŗŲ§Ł… فرد-زوج", + "11": "Duplicate all pages" + }, + "placeholder": "(Ł…Ų«Ų§Ł„: Ū±,Ū³,Ū² یا Ū“-Ūø,Ū²,Ū±Ū°-Ū±Ū² یا 2n-1)" + }, + "addImage": { + "tags": "تصویر،jpg،عکس", + "title": "Ų§ŁŲ²ŁˆŲÆŁ† تصویر", + "header": "Ų§ŁŲ²ŁˆŲÆŁ† تصویر به PDF", + "everyPage": "هر ŲµŁŲ­Ł‡ŲŸ", + "upload": "Ų§ŁŲ²ŁˆŲÆŁ† تصویر", + "submit": "Ų§ŁŲ²ŁˆŲÆŁ† تصویر" + }, + "watermark": { + "tags": "Ł…ŲŖŁ†ŲŒŲŖŚ©Ų±Ų§Ų±ŪŒŲŒŲØŲ±Ś†Ų³ŲØŲŒŲ®ŁˆŲÆŲŒŚ©Ł¾ŪŒā€ŒŲ±Ų§ŪŒŲŖŲŒŲ¹Ł„Ų§Ł…ŲŖ تجاری،تصویر،jpg،عکس", + "title": "Ų§ŁŲ²ŁˆŲÆŁ† ŁˆŲ§ŲŖŲ±Ł…Ų§Ų±Ś©", + "header": "Ų§ŁŲ²ŁˆŲÆŁ† ŁˆŲ§ŲŖŲ±Ł…Ų§Ų±Ś©", + "customColor": "رنگ متن سفارؓی", + "selectText": { + "1": "PDFی که Ł…ŪŒā€ŒŲ®ŁˆŲ§Ł‡ŪŒŲÆ به آن ŁˆŲ§ŲŖŲ±Ł…Ų§Ų±Ś© اضافه Ś©Ł†ŪŒŲÆ Ų±Ų§ انتخاب Ś©Ł†ŪŒŲÆ:", + "2": "متن ŁˆŲ§ŲŖŲ±Ł…Ų§Ų±Ś©:", + "3": "اندازه ŁŁˆŁ†ŲŖ:", + "4": "چرخؓ (Ū°-Ū³Ū¶Ū°):", + "5": "فاصله عرضی (فاصله ŲØŪŒŁ† هر ŁˆŲ§ŲŖŲ±Ł…Ų§Ų±Ś© به صورت Ų§ŁŁ‚ŪŒ):", + "6": "فاصله ارتفاعی (فاصله ŲØŪŒŁ† هر ŁˆŲ§ŲŖŲ±Ł…Ų§Ų±Ś© به صورت Ų¹Ł…ŁˆŲÆŪŒ):", + "7": "ؓفافیت (Ū°ŁŖ - Ū±Ū°Ū°ŁŖ):", + "8": "Ł†ŁˆŲ¹ ŁˆŲ§ŲŖŲ±Ł…Ų§Ų±Ś©:", + "9": "تصویر ŁˆŲ§ŲŖŲ±Ł…Ų§Ų±Ś©:", + "10": "ŲŖŲØŲÆŪŒŁ„ PDF به PDF-Image" + }, + "submit": "Ų§ŁŲ²ŁˆŲÆŁ† ŁˆŲ§ŲŖŲ±Ł…Ų§Ų±Ś©", + "type": { + "1": "متن", + "2": "تصویر" + } + }, + "permissions": { + "tags": "Ų®ŁˆŲ§Ł†ŲÆŁ†ŲŒŁ†ŁˆŲ“ŲŖŁ†ŲŒŁˆŪŒŲ±Ų§ŪŒŲ“ŲŒŚ†Ų§Ł¾", + "title": "تغییر Ł…Ų¬ŁˆŲ²Ł‡Ų§", + "header": "تغییر Ł…Ų¬ŁˆŲ²Ł‡Ų§", + "warning": "برای Ų§ŪŒŁ†Ś©Ł‡ Ų§ŪŒŁ† Ł…Ų¬ŁˆŲ²Ł‡Ų§ ŲŗŪŒŲ±Ł‚Ų§ŲØŁ„ تغییر ŲØŲ§Ų“Ł†ŲÆŲŒ ŲŖŁˆŲµŪŒŁ‡ Ł…ŪŒā€ŒŲ“ŁˆŲÆ آنها Ų±Ų§ ŲØŲ§ ŚÆŲ°Ų±ŁˆŲ§Ś˜Ł‡ Ų§Ų² Ų·Ų±ŪŒŁ‚ صفحه Ų§ŁŲ²ŁˆŲÆŁ† ŚÆŲ°Ų±ŁˆŲ§Ś˜Ł‡ ŲŖŁ†ŲøŪŒŁ… Ś©Ł†ŪŒŲÆ", + "selectText": { + "1": "PDFی Ų±Ų§ برای تغییر Ł…Ų¬ŁˆŲ²Ł‡Ų§ انتخاب Ś©Ł†ŪŒŲÆ", + "2": "Ł…Ų¬ŁˆŲ²Ł‡Ų§ŪŒŪŒ که باید ŲŖŁ†ŲøŪŒŁ… Ų“ŁˆŁ†ŲÆ", + "3": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² Ł…ŁˆŁ†ŲŖŲ§Ś˜ سند", + "4": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ Ł…Ų­ŲŖŁˆŲ§", + "5": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ برای ŲÆŲ³ŲŖŲ±Ų³ŪŒā€ŒŁ¾Ų°ŪŒŲ±ŪŒ", + "6": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² پرکردن فرم", + "7": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² اصلاح", + "8": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² اصلاح Ų­Ų§Ų“ŪŒŁ‡ā€ŒŁ†ŁˆŪŒŲ³ŪŒ", + "9": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² چاپ", + "10": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² چاپ ŁŲ±Ł…ŲŖā€ŒŁ‡Ų§ŪŒ مختلف" + }, + "submit": "تغییر" + }, + "removePages": { + "tags": "حذف صفحات،پاک کردن صفحات" + }, + "addPassword": { + "tags": "Ų§Ł…Ł†ŲŒŲ§Ł…Ł†ŪŒŲŖ", + "title": "Ų§ŁŲ²ŁˆŲÆŁ† ŚÆŲ°Ų±ŁˆŲ§Ś˜Ł‡", + "header": "Ų§ŁŲ²ŁˆŲÆŁ† ŚÆŲ°Ų±ŁˆŲ§Ś˜Ł‡ (Ų±Ł…Ų²Ł†ŚÆŲ§Ų±ŪŒ)", + "selectText": { + "1": "انتخاب PDF برای Ų±Ł…Ų²Ł†ŚÆŲ§Ų±ŪŒ", + "2": "ŚÆŲ°Ų±ŁˆŲ§Ś˜Ł‡ کاربر", + "3": "Ų·ŁˆŁ„ Ś©Ł„ŪŒŲÆ Ų±Ł…Ų²Ł†ŚÆŲ§Ų±ŪŒ", + "4": "Ł…Ł‚Ų§ŲÆŪŒŲ± بالاتر Ł‚ŁˆŪŒā€ŒŲŖŲ±Ł†ŲÆŲŒ Ų§Ł…Ų§ Ł…Ł‚Ų§ŲÆŪŒŲ± Ł¾Ų§ŪŒŪŒŁ†ā€ŒŲŖŲ± بهتر سازگارند.", + "5": "Ł…Ų¬ŁˆŲ²Ł‡Ų§ŪŒŪŒ که باید ŲŖŁ†ŲøŪŒŁ… Ų“ŁˆŁ†ŲÆ (ŲŖŁˆŲµŪŒŁ‡ Ł…ŪŒā€ŒŲ“ŁˆŲÆ همراه ŲØŲ§ ŚÆŲ°Ų±ŁˆŲ§Ś˜Ł‡ مالک استفاده ؓود)", + "6": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² Ł…ŁˆŁ†ŲŖŲ§Ś˜ سند", + "7": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ Ł…Ų­ŲŖŁˆŲ§", + "8": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ برای ŲÆŲ³ŲŖŲ±Ų³ŪŒā€ŒŁ¾Ų°ŪŒŲ±ŪŒ", + "9": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² پرکردن فرم", + "10": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² اصلاح", + "11": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² اصلاح Ų­Ų§Ų“ŪŒŁ‡ā€ŒŁ†ŁˆŪŒŲ³ŪŒ", + "12": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² چاپ", + "13": "Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² چاپ ŁŲ±Ł…ŲŖā€ŒŁ‡Ų§ŪŒ مختلف", + "14": "ŚÆŲ°Ų±ŁˆŲ§Ś˜Ł‡ مالک", + "15": "Ł…Ų­ŲÆŁˆŲÆŪŒŲŖā€ŒŁ‡Ų§ŪŒŪŒ که Ł…ŪŒā€ŒŲŖŁˆŲ§Ł† ŲØŲ± روی سند اعمال کرد Ł‡Ł†ŚÆŲ§Ł…ŪŒ که ŲØŲ§Ų² Ų§Ų³ŲŖ (Ł¾Ų“ŲŖŪŒŲØŲ§Ł†ŪŒā€ŒŲ“ŲÆŁ‡ توسط همه Ų®ŁˆŲ§Ł†Ł†ŲÆŚÆŲ§Ł† Ł†ŪŒŲ³ŲŖ)", + "16": "Ł…Ų­ŲÆŁˆŲÆŪŒŲŖā€ŒŁ‡Ų§ŪŒ ŲØŲ§Ų² ؓدن خود سند" + }, + "submit": "Ų±Ł…Ų²Ł†ŚÆŲ§Ų±ŪŒ" + }, + "removePassword": { + "tags": "Ų§Ł…Ł†ŲŒŲ±Ł…Ų²ŚÆŲ“Ų§ŪŒŪŒŲŒŲ§Ł…Ł†ŪŒŲŖŲŒŲ­Ų°Ł رمز عبور", + "title": "حذف ŚÆŲ°Ų±ŁˆŲ§Ś˜Ł‡", + "header": "حذف ŚÆŲ°Ų±ŁˆŲ§Ś˜Ł‡ (Ų±Ł…Ų²ŚÆŲ“Ų§ŪŒŪŒ)", + "selectText": { + "1": "PDFی Ų±Ų§ برای Ų±Ł…Ų²ŚÆŲ“Ų§ŪŒŪŒ انتخاب Ś©Ł†ŪŒŲÆ", + "2": "ŚÆŲ°Ų±ŁˆŲ§Ś˜Ł‡" + }, + "submit": "حذف" + }, + "compressPdfs": { + "tags": "ŁŲ“Ų±ŲÆŁ‡ŲŒŚ©ŁˆŚ†Ś©ŲŒŲ±ŪŒŲ²" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Ų¹Ł†ŁˆŲ§Ł†ŲŒŁ†ŁˆŪŒŲ³Ł†ŲÆŁ‡ŲŒŲŖŲ§Ų±ŪŒŲ®ŲŒŲ§ŪŒŲ¬Ų§ŲÆŲŒŲ²Ł…Ų§Ł†ŲŒŁ†Ų§Ų“Ų±ŲŒŲŖŁˆŁ„ŪŒŲÆŚ©Ł†Ł†ŲÆŁ‡ŲŒŲ¢Ł…Ų§Ų±", + "title": "Ų¹Ł†ŁˆŲ§Ł†:", + "header": "تغییر Ł…ŲŖŲ§ŲÆŲ§ŲÆŁ‡ā€ŒŁ‡Ų§", + "selectText": { + "1": "لطفاً Ł…ŲŖŲŗŪŒŲ±Ł‡Ų§ŪŒŪŒ که Ł…Ų§ŪŒŁ„ به تغییر آنها Ł‡Ų³ŲŖŪŒŲÆ Ų±Ų§ ویرایؓ Ś©Ł†ŪŒŲÆ", + "2": "حذف همه Ł…ŲŖŲ§ŲÆŲ§ŲÆŁ‡ā€ŒŁ‡Ų§", + "3": "Ł†Ł…Ų§ŪŒŲ“ متاداده سفارؓی:", + "4": "سایر Ł…ŲŖŲ§ŲÆŲ§ŲÆŁ‡ā€ŒŁ‡Ų§:", + "5": "Ų§ŁŲ²ŁˆŲÆŁ† ورودی متاداده سفارؓی" + }, + "author": "Ł†ŁˆŪŒŲ³Ł†ŲÆŁ‡:", + "creationDate": "تاریخ ایجاد (yyyy/MM/dd HH:mm:ss):", + "creator": "خالق:", + "keywords": "کلمات Ś©Ł„ŪŒŲÆŪŒ:", + "modDate": "تاریخ اصلاح (yyyy/MM/dd HH:mm:ss):", + "producer": "ŲŖŁˆŁ„ŪŒŲÆ کننده:", + "subject": "Ł…ŁˆŲ¶ŁˆŲ¹:", + "trapped": "گیر افتاده:", + "submit": "تغییر" + }, + "fileToPDF": { + "tags": "ŲŖŲØŲÆŪŒŁ„ŲŒŁŲ±Ł…ŲŖŲŒŲ³Ł†ŲÆŲŒŲŖŲµŁˆŪŒŲ±ŲŒŲ§Ų³Ł„Ų§ŪŒŲÆŲŒŁ…ŲŖŁ†ŲŒŲŖŲØŲÆŪŒŁ„ŲŒŲÆŁŲŖŲ±ŲŒŲ§Ų³Ł†Ų§ŲÆŲŒŁˆŲ±ŲÆŲŒŲ§Ś©Ų³Ł„ŲŒŁ¾Ų§ŁˆŲ±Ł¾ŁˆŪŒŁ†ŲŖ", + "title": "ŁŲ§ŪŒŁ„ به PDF", + "header": "ŲŖŲØŲÆŪŒŁ„ هر ŁŲ§ŪŒŁ„ به PDF", + "credit": "Ų§ŪŒŁ† سرویس Ų§Ų² LibreOffice و Unoconv برای ŲŖŲØŲÆŪŒŁ„ ŁŲ§ŪŒŁ„ استفاده Ł…ŪŒā€ŒŚ©Ł†ŲÆ.", + "supportedFileTypesInfo": "ŁŲ±Ł…ŲŖā€ŒŁ‡Ų§ŪŒ ŁŲ§ŪŒŁ„ Ł¾Ų“ŲŖŪŒŲØŲ§Ł†ŪŒ ؓده", + "supportedFileTypes": "ŁŲ±Ł…ŲŖā€ŒŁ‡Ų§ŪŒ ŁŲ§ŪŒŁ„ Ł¾Ų“ŲŖŪŒŲØŲ§Ł†ŪŒ ؓده باید Ų“Ų§Ł…Ł„ Ł…ŁˆŲ§Ų±ŲÆ زیر باؓند Ų§Ł…Ų§ برای فهرست کامل و ŲØŲ±ŁˆŲ²Ų±Ų³Ų§Ł†ŪŒ ؓده ŁŲ±Ł…ŲŖā€ŒŁ‡Ų§ŪŒ Ł¾Ų“ŲŖŪŒŲØŲ§Ł†ŪŒ Ų“ŲÆŁ‡ŲŒ لطفاً به مستندات LibreOffice مراجعه Ś©Ł†ŪŒŲÆ", + "submit": "ŲŖŲØŲÆŪŒŁ„ به PDF" + }, + "ocr": { + "tags": "ŲŖŲ“Ų®ŪŒŲµŲŒŁ…ŲŖŁ†ŲŒŲŖŲµŁˆŪŒŲ±ŲŒŲ§Ų³Ś©Ł†ŲŒŲ®ŁˆŲ§Ł†ŲÆŁ†ŲŒŲ“Ł†Ų§Ų³Ų§ŪŒŪŒŲŒŲ¢Ų“Ś©Ų§Ų±Ų³Ų§Ų²ŪŒŲŒŁ‚Ų§ŲØŁ„ ویرایؓ", + "title": "OCR / Ł…Ų±ŲŖŲØā€ŒŲ³Ų§Ų²ŪŒ Ų§Ų³Ś©Ł†ā€ŒŁ‡Ų§", + "header": "Ł…Ų±ŲŖŲØā€ŒŲ³Ų§Ų²ŪŒ Ų§Ų³Ś©Ł†ā€ŒŁ‡Ų§ / OCR (ŲØŲ§Ų²Ų“Ł†Ų§Ų³ŪŒ Ł†ŁˆŪŒŲ³Ł‡ Ł†ŁˆŲ±ŪŒ)", + "selectText": { + "1": "Ų²ŲØŲ§Ł†ā€ŒŁ‡Ų§ŪŒŪŒ Ų±Ų§ که باید ŲÆŲ± PDF Ų“Ł†Ų§Ų³Ų§ŪŒŪŒ Ų“ŁˆŁ†ŲÆ انتخاب Ś©Ł†ŪŒŲÆ (Ł…ŁˆŲ§Ų±ŲÆ فهرست ؓده Ų²ŲØŲ§Ł†ā€ŒŁ‡Ų§ŪŒŪŒ هستند که ŲÆŲ± Ų­Ų§Ł„ Ų­Ų§Ų¶Ų± Ų“Ł†Ų§Ų³Ų§ŪŒŪŒ Ų“ŲÆŁ‡ā€ŒŲ§Ł†ŲÆ):", + "2": "ŲŖŁˆŁ„ŪŒŲÆ ŁŲ§ŪŒŁ„ Ł…ŲŖŁ†ŪŒ Ų“Ų§Ł…Ł„ OCR همراه ŲØŲ§ PDF OCR ؓده", + "3": "صفحات اسکن ؓده ŲØŲ§ Ų²Ų§ŁˆŪŒŁ‡ کج Ų±Ų§ ŲØŲ§ چرخاندن به مکان ŲÆŲ±Ų³ŲŖ اصلاح Ś©Ł†ŪŒŲÆ", + "4": "صفحه Ų±Ų§ ŲŖŁ…ŪŒŲ² Ś©Ł†ŪŒŲÆ ŲŖŲ§ کمتر Ų§Ų­ŲŖŁ…Ų§Ł„ پیدا کردن متن توسط OCR ŲÆŲ± Ł†ŁˆŪŒŲ² Ł¾Ų³ā€ŒŲ²Ł…ŪŒŁ†Ł‡ ŲØŲ§Ų“ŲÆ. (ŲØŲÆŁˆŁ† تغییر ŲÆŲ± خروجی)", + "5": "صفحه Ų±Ų§ ŲŖŁ…ŪŒŲ² Ś©Ł†ŪŒŲÆ ŲŖŲ§ کمتر Ų§Ų­ŲŖŁ…Ų§Ł„ پیدا کردن متن توسط OCR ŲÆŲ± Ł†ŁˆŪŒŲ² Ł¾Ų³ā€ŒŲ²Ł…ŪŒŁ†Ł‡ باؓد، ŲŖŁ…ŪŒŲ² کردن ŲÆŲ± خروجی حفظ Ł…ŪŒā€ŒŲ“ŁˆŲÆ.", + "6": "صفحاتی که دارای متن ŲŖŲ¹Ų§Ł…Ł„ŪŒ هستند Ų±Ų§ Ł†Ų§ŲÆŪŒŲÆŁ‡ گرفته و فقط صفحاتی Ų±Ų§ که تصاویر هستند OCR کند", + "7": "Ų§Ų¬ŲØŲ§Ų± OCR، ŲŖŁ…Ų§Ł…ŪŒ صفحات Ų±Ų§ OCR کرده و ŲŖŁ…Ų§Ł… عناصر متن Ų§ŲµŁ„ŪŒ Ų±Ų§ حذف Ł…ŪŒā€ŒŚ©Ł†ŲÆ", + "8": "عادی (ŲÆŲ± صورتی که PDF حاوی متن ŲØŲ§Ų“ŲÆ Ų®Ų·Ų§ Ų®ŁˆŲ§Ł‡ŲÆ ŲÆŲ§ŲÆ)", + "9": "ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ اضافی", + "10": "حالت OCR", + "11": "حذف تصاویر ŲØŲ¹ŲÆ Ų§Ų² OCR (ŲŖŁ…Ų§Ł…ŪŒ تصاویر Ų±Ų§ حذف Ł…ŪŒā€ŒŚ©Ł†ŲÆŲŒ فقط ŲÆŲ± صورت Ł…ŁŪŒŲÆ ŲØŁˆŲÆŁ† بخؓی Ų§Ų² ŚÆŲ§Ł… ŲŖŲØŲÆŪŒŁ„)", + "12": "Ł†ŁˆŲ¹ رندر (Ł¾ŪŒŲ“Ų±ŁŲŖŁ‡)" + }, + "help": "لطفاً Ų§ŪŒŁ† مستندات Ų±Ų§ ŲØŲ®ŁˆŲ§Ł†ŪŒŲÆ ŲŖŲ§ Ł†Ų­ŁˆŁ‡ استفاده Ų§Ų² Ų§ŪŒŁ† سرویس برای Ų²ŲØŲ§Ł†ā€ŒŁ‡Ų§ŪŒ دیگر و/یا استفاده Ų§Ų² آن که ŲÆŲ± داخل داکر Ł†ŪŒŲ³ŲŖ Ų±Ų§ ŲØŲÆŲ§Ł†ŪŒŲÆ", + "credit": "Ų§ŪŒŁ† سرویس Ų§Ų² qpdf و Tesseract برای OCR استفاده Ł…ŪŒā€ŒŚ©Ł†ŲÆ.", + "submit": "پردازؓ PDF ŲØŲ§ OCR" + }, + "extractImages": { + "tags": "Ų¹Ś©Ų³ŲŒŲ¹Ś©Ų³ŲŒŲ°Ų®ŪŒŲ±Ł‡ŲŒŲ¢Ų±Ų“ŪŒŁˆŲŒŲ²ŪŒŁ¾ŲŒŚÆŲ±ŁŲŖŁ†ŲŒŲØŲ±ŲÆŲ§Ų“ŲŖŁ†", + "title": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ تصاویر", + "header": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ تصاویر", + "selectText": "فرمت تصویری Ų±Ų§ که تصاویر Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ ؓده به آن ŲŖŲØŲÆŪŒŁ„ Ų“ŁˆŁ†ŲÆ انتخاب Ś©Ł†ŪŒŲÆ", + "allowDuplicates": "Ų°Ų®ŪŒŲ±Ł‡ تصاویر تکراری", + "submit": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬" + }, + "pdfToPDFA": { + "tags": "Ų¢Ų±Ų“ŪŒŁˆŲŒŲ°Ų®ŪŒŲ±Ł‡ā€ŒŲ³Ų§Ų²ŪŒ ŲØŁ„Ł†ŲÆŁ…ŲÆŲŖŲŒŲ§Ų³ŲŖŲ§Ł†ŲÆŲ§Ų±ŲÆŲŒŲŖŲØŲÆŪŒŁ„ŲŒŲ°Ų®ŪŒŲ±Ł‡ā€ŒŲ³Ų§Ų²ŪŒŲŒŲ­ŁŲø", + "title": "PDF به PDF/A", + "header": "PDF به PDF/A", + "credit": "Ų§ŪŒŁ† سرویس Ų§Ų² libreoffice برای ŲŖŲØŲÆŪŒŁ„ PDF/A استفاده Ł…ŪŒā€ŒŚ©Ł†ŲÆ", + "submit": "ŲŖŲØŲÆŪŒŁ„", + "tip": "ŲÆŲ± Ų­Ų§Ł„ Ų­Ų§Ų¶Ų± برای Ś†Ł†ŲÆŪŒŁ† ورودی به طور همزمان کار Ł†Ł…ŪŒā€ŒŚ©Ł†ŲÆ", + "outputFormat": "فرمت خروجی", + "pdfWithDigitalSignature": "PDF حاوی یک Ų§Ł…Ų¶Ų§ŪŒ ŲÆŪŒŲ¬ŪŒŲŖŲ§Ł„ Ų§Ų³ŲŖ. Ų§ŪŒŁ† ŲÆŲ± مرحله ŲØŲ¹ŲÆ حذف Ų®ŁˆŲ§Ł‡ŲÆ Ų“ŲÆ." + }, + "PDFToWord": { + "tags": "doc،docx،odtŲŒŁˆŲ±ŲÆŲŒŲŖŲØŲÆŪŒŁ„ŲŒŁŲ±Ł…ŲŖŲŒŲŖŲØŲÆŪŒŁ„ŲŒŲÆŁŲŖŲ±ŲŒŁ…Ų§ŪŒŚ©Ų±ŁˆŲ³Ų§ŁŲŖŲŒŁŲ§ŪŒŁ„ ورد", + "title": "PDF به ورد", + "header": "PDF به ورد", + "selectText": { + "1": "فرمت ŁŲ§ŪŒŁ„ خروجی" + }, + "credit": "Ų§ŪŒŁ† سرویس Ų§Ų² LibreOffice برای ŲŖŲØŲÆŪŒŁ„ ŁŲ§ŪŒŁ„ استفاده Ł…ŪŒā€ŒŚ©Ł†ŲÆ.", + "submit": "ŲŖŲØŲÆŪŒŁ„" + }, + "PDFToPresentation": { + "tags": "Ų§Ų³Ł„Ų§ŪŒŲÆŁ‡Ų§ŲŒŲ§Ų±Ų§Ų¦Ł‡ŲŒŲÆŁŲŖŲ±ŲŒŁ…Ų§ŪŒŚ©Ų±ŁˆŲ³Ų§ŁŲŖ", + "title": "PDF به ارائه", + "header": "PDF به ارائه", + "selectText": { + "1": "فرمت ŁŲ§ŪŒŁ„ خروجی" + }, + "credit": "Ų§ŪŒŁ† سرویس Ų§Ų² LibreOffice برای ŲŖŲØŲÆŪŒŁ„ ŁŲ§ŪŒŁ„ استفاده Ł…ŪŒā€ŒŚ©Ł†ŲÆ.", + "submit": "ŲŖŲØŲÆŪŒŁ„" + }, + "PDFToText": { + "tags": "فرمت ŲŗŁ†ŪŒŲŒŁŲ±Ł…ŲŖ متن ŲŗŁ†ŪŒ", + "title": "PDF به RTF (متن)", + "header": "PDF به RTF (متن)", + "selectText": { + "1": "فرمت ŁŲ§ŪŒŁ„ خروجی" + }, + "credit": "Ų§ŪŒŁ† سرویس Ų§Ų² LibreOffice برای ŲŖŲØŲÆŪŒŁ„ ŁŲ§ŪŒŁ„ استفاده Ł…ŪŒā€ŒŚ©Ł†ŲÆ.", + "submit": "ŲŖŲØŲÆŪŒŁ„" + }, + "PDFToHTML": { + "tags": "Ł…Ų­ŲŖŁˆŲ§ŪŒ وب،سازگار ŲØŲ§ Ł…Ų±ŁˆŲ±ŚÆŲ±", + "title": "PDF به HTML", + "header": "PDF به HTML", + "credit": "Ų§ŪŒŁ† سرویس Ų§Ų² pdftohtml برای ŲŖŲØŲÆŪŒŁ„ ŁŲ§ŪŒŁ„ استفاده Ł…ŪŒā€ŒŚ©Ł†ŲÆ.", + "submit": "ŲŖŲØŲÆŪŒŁ„" + }, + "PDFToXML": { + "tags": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ ŲÆŲ§ŲÆŁ‡ŲŒŁ…Ų­ŲŖŁˆŲ§ŪŒ Ų³Ų§Ų®ŲŖŲ§Ų±ŪŒŲ§ŁŲŖŁ‡ŲŒŲŖŲÆŲ§Ų®Ł„ŲŒŲŖŲØŲÆŪŒŁ„", + "title": "PDF به XML", + "header": "PDF به XML", + "credit": "Ų§ŪŒŁ† سرویس Ų§Ų² LibreOffice برای ŲŖŲØŲÆŪŒŁ„ ŁŲ§ŪŒŁ„ استفاده Ł…ŪŒā€ŒŚ©Ł†ŲÆ.", + "submit": "ŲŖŲØŲÆŪŒŁ„" + }, + "ScannerImageSplit": { + "tags": "تفکیک،تؓخیص Ų®ŁˆŲÆŚ©Ų§Ų±ŲŒŲ§Ų³Ś©Ł†ā€ŒŁ‡Ų§ŲŒŚ†Ł†ŲÆ ŲŖŲµŁˆŪŒŲ±ŲŒŲ³Ų§Ų²Ł…Ų§Ł†ŲÆŁ‡ŪŒ", + "selectText": { + "1": "آستانه Ų²Ų§ŁˆŪŒŁ‡:", + "2": "حداقل Ų²Ų§ŁˆŪŒŁ‡ مطلق Ł…ŁˆŲ±ŲÆ Ł†ŪŒŲ§Ų² برای چرخاندن تصویر Ų±Ų§ ŲŖŁ†ŲøŪŒŁ… Ł…ŪŒā€ŒŚ©Ł†ŲÆ (Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶: Ū±Ū°).", + "3": "ŲŖŲ­Ł…Ł„ā€ŒŁ¾Ų°ŪŒŲ±ŪŒ:", + "4": "دامنه تغییر رنگ ŲÆŲ± اطراف رنگ Ł¾Ų³ā€ŒŲ²Ł…ŪŒŁ†Ł‡ ŲŖŲ®Ł…ŪŒŁ†ā€ŒŲ²ŲÆŁ‡ā€ŒŲ“ŲÆŁ‡ Ų±Ų§ ŲŖŲ¹ŪŒŪŒŁ† Ł…ŪŒā€ŒŚ©Ł†ŲÆ (Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶: Ū³Ū°).", + "5": "حداقل Ł†Ų§Ų­ŪŒŁ‡:", + "6": "آستانه حداقل Ł†Ų§Ų­ŪŒŁ‡ برای یک عکس Ų±Ų§ ŲŖŁ†ŲøŪŒŁ… Ł…ŪŒā€ŒŚ©Ł†ŲÆ (Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶: Ū±Ū°Ū°Ū°Ū°).", + "7": "حداقل Ł†Ų§Ų­ŪŒŁ‡ Ś©Ų§Ł†ŲŖŁˆŲ±:", + "8": "آستانه حداقل Ł†Ų§Ų­ŪŒŁ‡ Ś©Ų§Ł†ŲŖŁˆŲ± برای یک عکس Ų±Ų§ ŲŖŁ†ŲøŪŒŁ… Ł…ŪŒā€ŒŚ©Ł†ŲÆ", + "9": "اندازه Ų­Ų§Ų“ŪŒŁ‡:", + "10": "اندازه Ų­Ų§Ų“ŪŒŁ‡ Ų§Ų¶Ų§ŁŁ‡ā€ŒŲ“ŲÆŁ‡ و Ų­Ų°Łā€ŒŲ“ŲÆŁ‡ برای Ų¬Ł„ŁˆŚÆŪŒŲ±ŪŒ Ų§Ų² Ų­Ų§Ų“ŪŒŁ‡ā€ŒŁ‡Ų§ŪŒ سفید ŲÆŲ± خروجی Ų±Ų§ ŲŖŁ†ŲøŪŒŁ… Ł…ŪŒā€ŒŚ©Ł†ŲÆ (Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶: Ū±)." + }, + "info": "Ł¾Ų§ŪŒŲŖŁˆŁ† نصب نؓده Ų§Ų³ŲŖ. برای Ų§Ų¬Ų±Ų§ Ł†ŪŒŲ§Ų² Ų§Ų³ŲŖ." + }, + "sign": { + "tags": "تایید،حروف Ų§ŲØŲŖŲÆŲ§ŪŒŪŒŲŒŲ§Ł…Ų¶Ų§ŪŒ Ś©Ų“ŪŒŲÆŁ‡ŲŒŲ§Ł…Ų¶Ų§ŪŒ Ł…ŲŖŁ†ŪŒŲŒŲ§Ł…Ų¶Ų§ŪŒ تصویری", + "title": "Ų§Ł…Ų¶Ų§", + "header": "Ų§Ł…Ų¶Ų§ŪŒ PDFها", + "upload": "بارگذاری تصویر", + "draw": "Ś©Ų“ŪŒŲÆŁ† Ų§Ł…Ų¶Ų§", + "text": "ورودی متن", + "clear": "پاک کردن", + "add": "اضافه کردن", + "saved": "Ų§Ł…Ų¶Ų§Ł‡Ų§ŪŒ Ų°Ų®ŪŒŲ±Ł‡ā€ŒŲ“ŲÆŁ‡", + "save": "Ų°Ų®ŪŒŲ±Ł‡ Ų§Ł…Ų¶Ų§", + "personalSigs": "Ų§Ł…Ų¶Ų§Ł‡Ų§ŪŒ ؓخصی", + "sharedSigs": "Ų§Ł…Ų¶Ų§Ł‡Ų§ŪŒ به Ų§Ų“ŲŖŲ±Ų§Ś© ŚÆŲ°Ų§Ų“ŲŖŁ‡ā€ŒŲ“ŲÆŁ‡", + "noSavedSigs": "Ł‡ŪŒŚ† Ų§Ł…Ų¶Ų§ŪŒ Ų°Ų®ŪŒŲ±Ł‡ā€ŒŲ“ŲÆŁ‡ā€ŒŲ§ŪŒ یافت نؓد", + "addToAll": "اضافه کردن به همه صفحات", + "delete": "حذف", + "first": "صفحه Ų§ŁˆŁ„", + "last": "صفحه Ų¢Ų®Ų±", + "next": "صفحه بعدی", + "previous": "صفحه Ł‚ŲØŁ„ŪŒ", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "Ų§ŪŒŲ³ŲŖŲ§ŲŒŲŗŪŒŲ±ŁŲ¹Ų§Ł„ŲŒŲŗŪŒŲ±ŲŖŲ¹Ų§Ł…Ł„ŪŒŲŒŲØŁ‡ŪŒŁ†Ł‡ā€ŒŲ³Ų§Ų²ŪŒ", + "title": "ŪŒŚ©Ł¾Ų§Ų±Ś†Ł‡ā€ŒŲ³Ų§Ų²ŪŒ", + "header": "ŪŒŚ©Ł¾Ų§Ų±Ś†Ł‡ā€ŒŲ³Ų§Ų²ŪŒ PDFها", + "flattenOnlyForms": "فقط ŁŲ±Ł…ā€ŒŁ‡Ų§ Ų±Ų§ ŪŒŚ©Ł¾Ų§Ų±Ś†Ł‡ کن", + "submit": "ŪŒŚ©Ł¾Ų§Ų±Ś†Ł‡ā€ŒŲ³Ų§Ų²ŪŒ" + }, + "repair": { + "tags": "ŲŖŲ±Ł…ŪŒŁ…ŲŒŲØŲ§Ų²ŪŒŲ§ŲØŪŒŲŒŲ§ŲµŁ„Ų§Ų­ŲŒŲØŲ§Ų²ŪŒŲ§ŲØŪŒ", + "title": "ŲŖŲ¹Ł…ŪŒŲ±", + "header": "ŲŖŲ¹Ł…ŪŒŲ± PDFها", + "submit": "ŲŖŲ¹Ł…ŪŒŲ±" + }, + "removeBlanks": { + "tags": "Ł¾Ų§Ś©Ų³Ų§Ų²ŪŒŲŒŲØŁ‡ŪŒŁ†Ł‡ā€ŒŲ³Ų§Ų²ŪŒŲŒŲØŲÆŁˆŁ† Ł…Ų­ŲŖŁˆŲ§ŲŒŲ³Ų§Ų²Ł…Ų§Ł†ŲÆŁ‡ŪŒ", + "title": "حذف صفحات Ų®Ų§Ł„ŪŒ", + "header": "حذف صفحات Ų®Ų§Ł„ŪŒ", + "threshold": "آستانه سفیدی Ł¾ŪŒŚ©Ų³Ł„:", + "thresholdDesc": "Ų¢Ų³ŲŖŲ§Ł†Ł‡ā€ŒŲ§ŪŒ که ŲŖŲ¹ŪŒŪŒŁ† Ł…ŪŒā€ŒŚ©Ł†ŲÆ Ł¾ŪŒŚ©Ų³Ł„ چقدر باید سفید ŲØŲ§Ų“ŲÆ ŲŖŲ§ به Ų¹Ł†ŁˆŲ§Ł† 'سفید' ؓناخته ؓود. 0 = Ų³ŪŒŲ§Ł‡ŲŒ 255 کاملاً سفید.", + "whitePercent": "ŲÆŲ±ŲµŲÆ سفیدی (%):", + "whitePercentDesc": "ŲÆŲ±ŲµŲÆ ŲµŁŲ­Ł‡ā€ŒŲ§ŪŒ که باید Ł¾ŪŒŚ©Ų³Ł„ā€ŒŁ‡Ų§ŪŒ 'سفید' ŲØŲ§Ų“ŲÆ برای حذف", + "submit": "حذف صفحات Ų®Ų§Ł„ŪŒ" + }, + "removeAnnotations": { + "tags": "Ł†ŲøŲ±Ų§ŲŖŲŒŁ‡Ų§ŪŒŁ„Ų§ŪŒŲŖŲŒŪŒŲ§ŲÆŲÆŲ§Ų“ŲŖā€ŒŁ‡Ų§ŲŒŁ†Ų“Ų§Ł†Ł‡ā€ŒŚÆŲ°Ų§Ų±ŪŒŲŒŲ­Ų°Ł", + "title": "حذف توضیحات", + "header": "حذف توضیحات", + "submit": "حذف" + }, + "compare": { + "tags": "ŲŖŁŲ§ŁˆŲŖā€ŒŚÆŲ°Ų§Ų±ŪŒŲŒŚ©Ł†ŲŖŲ±Ų§Ų³ŲŖŲŒŲŖŲŗŪŒŪŒŲ±Ų§ŲŖŲŒŲŖŲ­Ł„ŪŒŁ„", + "title": "Ł…Ł‚Ų§ŪŒŲ³Ł‡", + "header": "Ł…Ł‚Ų§ŪŒŲ³Ł‡ PDFها", + "highlightColor": { + "1": "رنگ برجسته Ū±:", + "2": "رنگ برجسته Ū²:" + }, + "document": { + "1": "سند Ū±", + "2": "سند Ū²" + }, + "submit": "Ł…Ł‚Ų§ŪŒŲ³Ł‡", + "complex": { + "message": "یکی یا هر دو Ų§Ų² اسناد ارائه ؓده ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ بزرگی Ł‡Ų³ŲŖŁ†ŲÆŲŒ دقت Ł…Ł‚Ų§ŪŒŲ³Ł‡ ممکن Ų§Ų³ŲŖ کاهؓ یابد" + }, + "large": { + "file": { + "message": "یکی یا هر دو Ų§Ų² اسناد ارائه ؓده برای پردازؓ بسیار بزرگ هستند" + } + }, + "no": { + "text": { + "message": "یکی یا هر دو Ų§Ų² PDFŁ‡Ų§ŪŒ انتخاب ؓده Ł…Ų­ŲŖŁˆŲ§ŪŒ Ł…ŲŖŁ†ŪŒ ندارند. لطفاً PDFŁ‡Ų§ŪŒŪŒ ŲØŲ§ متن برای Ł…Ł‚Ų§ŪŒŲ³Ł‡ انتخاب Ś©Ł†ŪŒŲÆ." + } + } + }, + "certSign": { + "tags": "تایید،PEM،P12ŲŒŲ±Ų³Ł…ŪŒŲŒŲ±Ł…Ų²ŚÆŲ°Ų§Ų±ŪŒ", + "title": "Ų§Ł…Ų¶Ų§ŪŒ ŚÆŁˆŲ§Ł‡ŪŒ", + "header": "Ų§Ł…Ų¶Ų§ کردن PDF ŲØŲ§ ŚÆŁˆŲ§Ł‡ŪŒ خود (ŲÆŲ± Ų­Ų§Ł„ پیؓرفت)", + "selectPDF": "انتخاب ŁŲ§ŪŒŁ„ PDF برای Ų§Ł…Ų¶Ų§:", + "jksNote": "یادداؓت: Ų§ŚÆŲ± Ł†ŁˆŲ¹ ŚÆŁˆŲ§Ł‡ŪŒ Ų“Ł…Ų§ ŲÆŲ± زیر ذکر نؓده است، لطفاً آن Ų±Ų§ به یک ŁŲ§ŪŒŁ„ Java Keystore (.jks) ŲØŲ§ استفاده Ų§Ų² Ų§ŲØŲ²Ų§Ų± Ų®Ų· فرمان keytool ŲŖŲØŲÆŪŒŁ„ Ś©Ł†ŪŒŲÆ. سپس، ŚÆŲ²ŪŒŁ†Ł‡ ŁŲ§ŪŒŁ„ .jks Ų±Ų§ ŲÆŲ± زیر انتخاب Ś©Ł†ŪŒŲÆ.", + "selectKey": "ŁŲ§ŪŒŁ„ Ś©Ł„ŪŒŲÆ خصوصی خود Ų±Ų§ انتخاب Ś©Ł†ŪŒŲÆ (فرمت PKCS#8، Ł…ŪŒā€ŒŲŖŁˆŲ§Ł†ŲÆ .pem یا .der ŲØŲ§Ų“ŲÆ):", + "selectCert": "ŁŲ§ŪŒŁ„ ŚÆŁˆŲ§Ł‡ŪŒ خود Ų±Ų§ انتخاب Ś©Ł†ŪŒŲÆ (فرمت X.509، Ł…ŪŒā€ŒŲŖŁˆŲ§Ł†ŲÆ .pem یا .der ŲØŲ§Ų“ŲÆ):", + "selectP12": "ŁŲ§ŪŒŁ„ Keystore PKCS#12 خود Ų±Ų§ انتخاب Ś©Ł†ŪŒŲÆ (.p12 یا .pfx) (اختیاری، ŲÆŲ± صورت Ų§Ų±Ų§Ų¦Ł‡ŲŒ باید Ų“Ų§Ł…Ł„ Ś©Ł„ŪŒŲÆ خصوصی و ŚÆŁˆŲ§Ł‡ŪŒ Ų“Ł…Ų§ ŲØŲ§Ų“ŲÆ):", + "selectJKS": "ŁŲ§ŪŒŁ„ Java Keystore خود Ų±Ų§ انتخاب Ś©Ł†ŪŒŲÆ (.jks یا .keystore):", + "certType": "Ł†ŁˆŲ¹ ŚÆŁˆŲ§Ł‡ŪŒ", + "password": "رمز عبور Keystore یا Ś©Ł„ŪŒŲÆ خصوصی خود Ų±Ų§ وارد Ś©Ł†ŪŒŲÆ (ŲÆŲ± صورت وجود):", + "showSig": "Ł†Ł…Ų§ŪŒŲ“ Ų§Ł…Ų¶Ų§", + "reason": "ŲÆŁ„ŪŒŁ„", + "location": "Ł…ŁˆŁ‚Ų¹ŪŒŲŖ", + "name": "نام", + "showLogo": "Ł†Ł…Ų§ŪŒŲ“ Ł„ŁˆŚÆŁˆ", + "submit": "Ų§Ł…Ų¶Ų§ کردن PDF" + }, + "removeCertSign": { + "tags": "تایید،PEM،P12ŲŒŲ±Ų³Ł…ŪŒŲŒŲ±Ł…Ų²ŚÆŲ“Ų§ŪŒŪŒ", + "title": "حذف Ų§Ł…Ų¶Ų§ŪŒ ŚÆŁˆŲ§Ł‡ŪŒ", + "header": "حذف ŚÆŁˆŲ§Ł‡ŪŒ ŲÆŪŒŲ¬ŪŒŲŖŲ§Ł„ Ų§Ų² PDF", + "selectPDF": "یک ŁŲ§ŪŒŁ„ PDF Ų±Ų§ انتخاب Ś©Ł†ŪŒŲÆ:", + "submit": "حذف Ų§Ł…Ų¶Ų§" + }, + "pageLayout": { + "tags": "Ų§ŲÆŲŗŲ§Ł…ŲŒŲŖŲ±Ś©ŪŒŲØŲŒŁ†Ł…Ų§ŪŒ ŁˆŲ§Ų­ŲÆŲŒŲ³Ų§Ų²Ł…Ų§Ł†ŲÆŁ‡ŪŒ", + "title": "Ų·Ų±Ų­ā€ŒŲØŁ†ŲÆŪŒ چند ŲµŁŲ­Ł‡ā€ŒŲ§ŪŒ", + "header": "Ų·Ų±Ų­ā€ŒŲØŁ†ŲÆŪŒ چند ŲµŁŲ­Ł‡ā€ŒŲ§ŪŒ", + "pagesPerSheet": "صفحات ŲÆŲ± هر ؓیت:", + "addBorder": "اضافه کردن مرزها", + "submit": "Ų§Ų±Ų³Ų§Ł„" + }, + "scalePages": { + "tags": "تغییر Ų§Ł†ŲÆŲ§Ų²Ł‡ŲŒŁˆŪŒŲ±Ų§ŪŒŲ“ŲŒŲ§ŲØŲ¹Ų§ŲÆŲŒŲ³Ų§Ų²ŚÆŲ§Ų±ŪŒ", + "title": "ŲŖŁ†ŲøŪŒŁ… Ł…Ł‚ŪŒŲ§Ų³ صفحه", + "header": "ŲŖŁ†ŲøŪŒŁ… Ł…Ł‚ŪŒŲ§Ų³ صفحه", + "pageSize": "اندازه صفحه سند.", + "keepPageSize": "اندازه Ų§ŲµŁ„ŪŒ", + "scaleFactor": "Ų³Ų·Ų­ Ų²ŁˆŁ… (ŲØŲ±Ų“) یک صفحه.", + "submit": "Ų§Ų±Ų³Ų§Ł„" + }, + "add-page-numbers": { + "tags": "Ų“Ł…Ų§Ų±Ł‡ā€ŒŚÆŲ°Ų§Ų±ŪŒŲŒŲØŲ±Ś†Ų³ŲØā€ŒŚÆŲ°Ų§Ų±ŪŒŲŒŲ³Ų§Ų²Ł…Ų§Ł†ŲÆŁ‡ŪŒŲŒŁŁ‡Ų±Ų³ŲŖ" + }, + "auto-rename": { + "tags": "تؓخیص خودکار،بر Ų§Ų³Ų§Ų³ Ų³Ų±ŲØŲ±ŚÆŲŒŲ³Ų§Ų²Ł…Ų§Ł†ŲÆŁ‡ŪŒŲŒŲŖŲŗŪŒŪŒŲ± نام", + "title": "تغییر نام خودکار", + "header": "تغییر نام خودکار PDF", + "submit": "تغییر نام خودکار" + }, + "adjust-contrast": { + "tags": "تصحیح Ų±Ł†ŚÆŲŒŲŖŁ†ŲøŪŒŁ…ŲŒŁˆŪŒŲ±Ų§ŪŒŲ“ŲŒŲØŁ‡ŲØŁˆŲÆ" + }, + "crop": { + "tags": "ŲØŲ±Ų“ŲŒŚ©Ų§Ł‡Ų“ Ų§Ł†ŲÆŲ§Ų²Ł‡ŲŒŁˆŪŒŲ±Ų§ŪŒŲ“ŲŒŲ“Ś©Ł„ā€ŒŲÆŁ‡ŪŒ", + "title": "ŲØŲ±Ų“ دادن", + "header": "ŲØŲ±Ų“ PDF", + "submit": "Ų§Ų±Ų³Ų§Ł„" + }, + "autoSplitPDF": { + "tags": "ŲØŲ± Ų§Ų³Ų§Ų³ QRŲŒŲ¬ŲÆŲ§Ų³Ų§Ų²ŪŒŲŒŲŖŁ‚Ų³ŪŒŁ… Ų§Ų³Ś©Ł†ā€ŒŲ“ŲÆŁ‡ŲŒŲ³Ų§Ų²Ł…Ų§Ł†ŲÆŁ‡ŪŒ", + "title": "Ų¬ŲÆŲ§ سازی خودکار PDF", + "header": "Ų¬ŲÆŲ§ سازی خودکار PDF", + "description": "Ś†Ų§Ł¾ŲŒ درج، Ų§Ų³Ś©Ł†ŲŒ بارگذاری و بگذارید اسناد Ų“Ł…Ų§ به صورت خودکار Ų¬ŲÆŲ§ Ų“ŁˆŁ†ŲÆ. Ł†ŪŒŲ§Ų²ŪŒ به Ł…Ų±ŲŖŲØā€ŒŲ³Ų§Ų²ŪŒ دستی Ł†ŪŒŲ³ŲŖ.", + "selectText": { + "1": "Ų§Ų² زیر ŲØŲ±ŚÆŁ‡ā€ŒŁ‡Ų§ŪŒ Ł…ŁˆŁ‚ŲŖ Ł¾Ų±ŪŒŁ†ŲŖ Ś©Ł†ŪŒŲÆ (Ų³ŪŒŲ§Ł‡ و سفید کافی Ų§Ų³ŲŖ).", + "2": "همه مدارک خود Ų±Ų§ ŲØŲ§ قرار دادن ŲØŲ±ŚÆŁ‡ā€ŒŁ‡Ų§ŪŒ Ł…ŁˆŁ‚ŲŖ ŲØŪŒŁ† آنها یکجا اسکن Ś©Ł†ŪŒŲÆ.", + "3": "ŁŲ§ŪŒŁ„ PDF بزرگ اسکن ؓده Ų±Ų§ بارگذاری Ś©Ł†ŪŒŲÆ و بگذارید Stirling PDF ŲØŁ‚ŪŒŁ‡ کار Ų±Ų§ انجام دهد.", + "4": "صفحات جداکننده به طور خودکار تؓخیص داده و حذف Ł…ŪŒā€ŒŲ“ŁˆŁ†ŲÆŲŒ ŲŖŲ¶Ł…ŪŒŁ†ā€ŒŚ©Ł†Ł†ŲÆŁ‡ یک سند Ł†Ł‡Ų§ŪŒŪŒ منظم." + }, + "formPrompt": "PDF حاوی Ų¬ŲÆŲ§Ś©Ł†Ł†ŲÆŁ‡ā€ŒŁ‡Ų§ŪŒ Stirling-PDF Ų±Ų§ Ų§Ų±Ų³Ų§Ł„ Ś©Ł†ŪŒŲÆ:", + "duplexMode": "حالت ŲÆŁˆŲØŁ„Ś©Ų³ (اسکن Ų¬Ł„Łˆ و عقب)", + "dividerDownload2": "ŲÆŲ§Ł†Ł„ŁˆŲÆ 'Auto Splitter Divider (with instructions).pdf'", + "submit": "Ų§Ų±Ų³Ų§Ł„" + }, + "sanitizePdf": { + "tags": "Ł¾Ų§Ś©Ų³Ų§Ų²ŪŒŲŒŲ§Ł…Ł†ŲŒŲ§ŪŒŁ…Ł†ŲŒŲ­Ų°Ł ŲŖŁ‡ŲÆŪŒŲÆŁ‡Ų§" + }, + "URLToPDF": { + "tags": "Ų°Ų®ŪŒŲ±Ł‡ صفحه ŁˆŲØŲŒŲŖŲØŲÆŪŒŁ„ وب به Ų³Ł†ŲÆŲŒŲ¢Ų±Ų“ŪŒŁˆ", + "title": "URL به PDF", + "header": "URL به PDF", + "submit": "ŲŖŲØŲÆŪŒŁ„", + "credit": "Ų§Ų² WeasyPrint استفاده Ł…ŪŒā€ŒŚ©Ł†ŲÆ" + }, + "HTMLToPDF": { + "tags": "Ł…Ų§Ų±Ś©ā€ŒŲ¢Ł¾ŲŒŁ…Ų­ŲŖŁˆŲ§ŪŒ ŁˆŲØŲŒŲŖŲØŲÆŪŒŁ„ŲŒŲŖŲŗŪŒŪŒŲ±", + "title": "HTML به PDF", + "header": "HTML به PDF", + "help": "پذیرؓ ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ HTML و ZIP Ų“Ų§Ł…Ł„ html/css/تصاویر و ŲŗŪŒŲ±Ł‡", + "submit": "ŲŖŲØŲÆŪŒŁ„", + "credit": "Ų§Ų² WeasyPrint استفاده Ł…ŪŒā€ŒŚ©Ł†ŲÆ", + "zoom": "Ų³Ų·Ų­ ŲØŲ²Ų±ŚÆŁ†Ł…Ų§ŪŒŪŒ برای Ł†Ł…Ų§ŪŒŲ“ ŁˆŲØā€ŒŲ³Ų§ŪŒŲŖ.", + "pageWidth": "Ų¹Ų±Ų¶ صفحه به Ų³Ų§Ł†ŲŖŪŒā€ŒŁ…ŲŖŲ±. (Ų®Ų§Ł„ŪŒ برای Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶)", + "pageHeight": "ارتفاع صفحه به Ų³Ų§Ł†ŲŖŪŒā€ŒŁ…ŲŖŲ±. (Ų®Ų§Ł„ŪŒ برای Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶)", + "marginTop": "Ų­Ų§Ų“ŪŒŁ‡ بالا به Ł…ŪŒŁ„ŪŒā€ŒŁ…ŲŖŲ±. (Ų®Ų§Ł„ŪŒ برای Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶)", + "marginBottom": "Ų­Ų§Ų“ŪŒŁ‡ Ł¾Ų§ŪŒŪŒŁ† به Ł…ŪŒŁ„ŪŒā€ŒŁ…ŲŖŲ±. (Ų®Ų§Ł„ŪŒ برای Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶)", + "marginLeft": "Ų­Ų§Ų“ŪŒŁ‡ چپ به Ł…ŪŒŁ„ŪŒā€ŒŁ…ŲŖŲ±. (Ų®Ų§Ł„ŪŒ برای Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶)", + "marginRight": "Ų­Ų§Ų“ŪŒŁ‡ Ų±Ų§Ų³ŲŖ به Ł…ŪŒŁ„ŪŒā€ŒŁ…ŲŖŲ±. (Ų®Ų§Ł„ŪŒ برای Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶)", + "printBackground": "Ł†Ł…Ų§ŪŒŲ“ Ł¾Ų³ā€ŒŲ²Ł…ŪŒŁ†Ł‡ ŁˆŲØā€ŒŲ³Ų§ŪŒŲŖā€ŒŁ‡Ų§.", + "defaultHeader": "فعال کردن هدر Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶ (نام و ؓماره صفحه)", + "cssMediaType": "تغییر Ł†ŁˆŲ¹ رسانه CSS صفحه.", + "none": "Ł‡ŪŒŚ†ā€ŒŚ©ŲÆŲ§Ł…", + "print": "چاپ", + "screen": "Ł†Ł…Ų§ŪŒŲ“ŚÆŲ±" + }, + "MarkdownToPDF": { + "tags": "Ł…Ų§Ų±Ś©ā€ŒŲ¢Ł¾ŲŒŁ…Ų­ŲŖŁˆŲ§ŪŒ ŁˆŲØŲŒŲŖŲØŲÆŪŒŁ„ŲŒŲŖŲŗŪŒŪŒŲ±", + "title": "Markdown به PDF", + "header": "Markdown به PDF", + "submit": "ŲŖŲØŲÆŪŒŁ„", + "help": "ŲÆŲ± Ų­Ų§Ł„ پیؓرفت", + "credit": "Ų§Ų² WeasyPrint استفاده Ł…ŪŒā€ŒŚ©Ł†ŲÆ" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "Ų§Ų·Ł„Ų§Ų¹Ų§ŲŖŲŒŲÆŲ§ŲÆŁ‡ŲŒŲ¢Ł…Ų§Ų±ŲŒŲ¢Ł…Ų§Ų±Ł‡Ų§", + "title": "اطلاعات PDF Ų±Ų§ دریافت Ś©Ł†ŪŒŲÆ", + "header": "اطلاعات PDF Ų±Ų§ دریافت Ś©Ł†ŪŒŲÆ", + "submit": "دریافت اطلاعات", + "downloadJson": "ŲÆŲ§Ł†Ł„ŁˆŲÆ JSON" + }, + "extractPage": { + "tags": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬" + }, + "PdfToSinglePage": { + "tags": "صفحه واحد" + }, + "showJS": { + "tags": "جاوااسکریپت", + "title": "Ł†Ł…Ų§ŪŒŲ“ جاوااسکریپت", + "header": "Ł†Ł…Ų§ŪŒŲ“ جاوااسکریپت", + "downloadJS": "ŲÆŲ§Ł†Ł„ŁˆŲÆ جاوااسکریپت", + "submit": "Ł†Ł…Ų§ŪŒŲ“" + }, + "autoRedact": { + "tags": "Ų³Ų§Ł†Ų³ŁˆŲ±ŲŒ Ł…Ų®ŁŪŒ Ś©Ų±ŲÆŁ†ŲŒ Ų³ŪŒŲ§Ł‡ Ś©Ų±ŲÆŁ†ŲŒ پنهان", + "title": "Ų³Ų§Ł†Ų³ŁˆŲ± خودکار", + "header": "Ų³Ų§Ł†Ų³ŁˆŲ± خودکار", + "colorLabel": "رنگ", + "textsToRedactLabel": "متن برای Ų³Ų§Ł†Ų³ŁˆŲ± (هر Ų®Ų· جداگانه)", + "textsToRedactPlaceholder": "Ł…Ų«Ų§Ł„: \\nمحرمانه \\nŁŁˆŁ‚ā€ŒŲ³Ų±ŪŒ", + "useRegexLabel": "استفاده Ų§Ų² Regex", + "wholeWordSearchLabel": "جستجوی کلمه کامل", + "customPaddingLabel": "Ų§ŁŲ²ŁˆŲÆŁ† فاصله اضافی", + "convertPDFToImageLabel": "ŲŖŲØŲÆŪŒŁ„ PDF به PDF-تصویر (برای حذف متن پؓت جعبه استفاده Ł…ŪŒā€ŒŲ“ŁˆŲÆ)", + "submitButton": "Ų§Ų±Ų³Ų§Ł„" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV، Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ Ų¬ŲÆŁˆŁ„ŲŒ استخراج، ŲŖŲØŲÆŪŒŁ„" + }, + "autoSizeSplitPDF": { + "tags": "PDF، ŲŖŁ‚Ų³ŪŒŁ…ŲŒ Ų³Ł†ŲÆŲŒ Ų³Ų§Ų²Ł…Ų§Ł†ŲÆŁ‡ŪŒ" + }, + "overlay-pdfs": { + "tags": "Ł‡Ł…ā€ŒŁ¾ŁˆŲ“Ų§Ł†ŪŒ", + "header": "ترکیب ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ PDF", + "baseFile": { + "label": "انتخاب ŁŲ§ŪŒŁ„ Ł¾Ų§ŪŒŁ‡ PDF" + }, + "overlayFiles": { + "label": "انتخاب ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ ترکیبی PDF" + }, + "mode": { + "label": "انتخاب حالت ترکیب", + "sequential": "ترکیب ترتیبی", + "interleaved": "ترکیب درهم", + "fixedRepeat": "ترکیب ŲØŲ§ تکرار Ų«Ų§ŲØŲŖ" + }, + "counts": { + "label": "ŲŖŲ¹ŲÆŲ§ŲÆ ŲŖŚ©Ų±Ų§Ų±Ł‡Ų§ŪŒ ترکیب (برای حالت تکرار Ų«Ų§ŲØŲŖ)", + "placeholder": "Ł…Ł‚Ų§ŲÆŪŒŲ± ŲŖŲ¹ŲÆŲ§ŲÆ Ų±Ų§ ŲØŲ§ کاما Ų¬ŲÆŲ§ Ś©Ł†ŪŒŲÆ (مثلاً Ū²,Ū³,Ū±)" + }, + "position": { + "label": "انتخاب Ł…ŁˆŁ‚Ų¹ŪŒŲŖ ترکیب", + "foreground": "Ł¾ŪŒŲ“ā€ŒŲ²Ł…ŪŒŁ†Ł‡", + "background": "Ł¾Ų³ā€ŒŲ²Ł…ŪŒŁ†Ł‡" + }, + "submit": "Ų§Ų±Ų³Ų§Ł„" + }, + "split-by-sections": { + "tags": "ŲŖŁ‚Ų³ŪŒŁ… بخؓ، Ų³ŁŲ§Ų±Ų“ŪŒā€ŒŲ³Ų§Ų²ŪŒ", + "title": "ŲŖŁ‚Ų³ŪŒŁ… PDF به ŲØŲ®Ų“ā€ŒŁ‡Ų§", + "header": "ŲŖŁ‚Ų³ŪŒŁ… PDF به ŲØŲ®Ų“ā€ŒŁ‡Ų§", + "horizontal": { + "label": "ŲŖŁ‚Ų³ŪŒŁ…Ų§ŲŖ Ų§ŁŁ‚ŪŒ", + "placeholder": "ŲŖŲ¹ŲÆŲ§ŲÆ ŲŖŁ‚Ų³ŪŒŁ…Ų§ŲŖ Ų§ŁŁ‚ŪŒ Ų±Ų§ وارد Ś©Ł†ŪŒŲÆ" + }, + "vertical": { + "label": "ŲŖŁ‚Ų³ŪŒŁ…Ų§ŲŖ Ų¹Ł…ŁˆŲÆŪŒ", + "placeholder": "ŲŖŲ¹ŲÆŲ§ŲÆ ŲŖŁ‚Ų³ŪŒŁ…Ų§ŲŖ Ų¹Ł…ŁˆŲÆŪŒ Ų±Ų§ وارد Ś©Ł†ŪŒŲÆ" + }, + "submit": "ŲŖŁ‚Ų³ŪŒŁ… PDF", + "merge": "Ų§ŲÆŲŗŲ§Ł… به یک PDF" + }, + "AddStampRequest": { + "tags": "Ł…Ł‡Ų±ŲŒ Ų§ŁŲ²ŁˆŲÆŁ† تصویر، ŁˆŲ§ŲŖŲ±Ł…Ų§Ų±Ś©ŲŒ PDF، Ų³ŁŲ§Ų±Ų“ŪŒā€ŒŲ³Ų§Ų²ŪŒ", + "header": "مهر زدن به PDF", + "title": "مهر زدن به PDF", + "stampType": "Ł†ŁˆŲ¹ مهر", + "stampText": "متن مهر", + "stampImage": "تصویر مهر", + "alphabet": "الفبا", + "fontSize": "اندازه ŁŁˆŁ†ŲŖ/تصویر", + "rotation": "چرخؓ", + "opacity": "ؓفافیت", + "position": "Ł…ŁˆŁ‚Ų¹ŪŒŲŖ", + "overrideX": "تغییر Ł…Ų®ŲŖŲµŲ§ŲŖ X", + "overrideY": "تغییر Ł…Ų®ŲŖŲµŲ§ŲŖ Y", + "customMargin": "Ų­Ų§Ų“ŪŒŁ‡ سفارؓی", + "customColor": "رنگ متن سفارؓی", + "submit": "Ų§Ų±Ų³Ų§Ł„" + }, + "removeImagePdf": { + "tags": "حذف تصویر، Ų¹Ł…Ł„ŪŒŲ§ŲŖ ŲµŁŲ­Ł‡ŲŒ سرور" + }, + "splitPdfByChapters": { + "tags": "ŲŖŁ‚Ų³ŪŒŁ…ŲŒ ŁŲµŁ„ā€ŒŁ‡Ų§ŲŒ Ł†Ų“Ų§Ł†Ł‡ā€ŒŚÆŲ°Ų§Ų±ŪŒŲŒ Ų³Ų§Ų²Ł…Ų§Ł†ŲÆŁ‡ŪŒ" + }, + "validateSignature": { + "tags": "Ų§Ł…Ų¶Ų§ŲŒ تأیید، Ų§Ų¹ŲŖŲØŲ§Ų±Ų³Ł†Ų¬ŪŒŲŒ PDF، ŚÆŁˆŲ§Ł‡ŪŒā€ŒŁ†Ų§Ł…Ł‡ŲŒ Ų§Ł…Ų¶Ų§ŪŒ ŲÆŪŒŲ¬ŪŒŲŖŲ§Ł„", + "title": "Ų§Ų¹ŲŖŲØŲ§Ų±Ų³Ł†Ų¬ŪŒ Ų§Ł…Ų¶Ų§Ł‡Ų§ŪŒ PDF", + "header": "Ų§Ų¹ŲŖŲØŲ§Ų±Ų³Ł†Ų¬ŪŒ Ų§Ł…Ų¶Ų§ŪŒ ŲÆŪŒŲ¬ŪŒŲŖŲ§Ł„", + "selectPDF": "ŁŲ§ŪŒŁ„ PDF امضاؓده Ų±Ų§ انتخاب Ś©Ł†ŪŒŲÆ", + "submit": "Ų§Ų¹ŲŖŲØŲ§Ų±Ų³Ł†Ų¬ŪŒ امضاها", + "results": "Ł†ŲŖŲ§ŪŒŲ¬ Ų§Ų¹ŲŖŲØŲ§Ų±Ų³Ł†Ų¬ŪŒ", + "status": { + "_value": "وضعیت", + "valid": "Ł…Ų¹ŲŖŲØŲ±", + "invalid": "نامعتبر" + }, + "signer": "امضاکننده", + "date": "تاریخ", + "reason": "ŲÆŁ„ŪŒŁ„", + "location": "مکان", + "noSignatures": "Ł‡ŪŒŚ† Ų§Ł…Ų¶Ų§ŪŒ ŲÆŪŒŲ¬ŪŒŲŖŲ§Ł„ŪŒ ŲÆŲ± Ų§ŪŒŁ† سند یافت نؓد", + "chain": { + "invalid": "Ų§Ų¹ŲŖŲØŲ§Ų±Ų³Ł†Ų¬ŪŒ Ų²Ł†Ų¬ŪŒŲ±Ł‡ ŚÆŁˆŲ§Ł‡ŪŒ Ł†Ų§Ł…ŁˆŁŁ‚ بود - Ł‡ŁˆŪŒŲŖ امضاکننده قابل تأیید Ł†ŪŒŲ³ŲŖ" + }, + "trust": { + "invalid": "ŚÆŁˆŲ§Ł‡ŪŒ ŲÆŲ± مخزن Ų§Ų¹ŲŖŁ…Ų§ŲÆ Ł†ŪŒŲ³ŲŖ - منبع قابل تأیید Ł†ŪŒŲ³ŲŖ" + }, + "cert": { + "expired": "ŚÆŁˆŲ§Ł‡ŪŒ Ł…Ł†Ł‚Ų¶ŪŒ ؓده Ų§Ų³ŲŖ", + "revoked": "ŚÆŁˆŲ§Ł‡ŪŒ Ł„ŲŗŁˆ ؓده Ų§Ų³ŲŖ", + "info": "جزئیات ŚÆŁˆŲ§Ł‡ŪŒ", + "issuer": "صادرکننده", + "subject": "Ł…ŁˆŲ¶ŁˆŲ¹", + "serialNumber": "ؓماره Ų³Ų±ŪŒŲ§Ł„", + "validFrom": "Ł…Ų¹ŲŖŲØŲ± Ų§Ų²", + "validUntil": "Ł…Ų¹ŲŖŲØŲ± ŲŖŲ§", + "algorithm": "Ų§Ł„ŚÆŁˆŲ±ŪŒŲŖŁ…", + "keySize": "اندازه Ś©Ł„ŪŒŲÆ", + "version": "نسخه", + "keyUsage": "کاربرد Ś©Ł„ŪŒŲÆ", + "selfSigned": "ŲØŲ§ Ų§Ł…Ų¶Ų§ŪŒ خود", + "bits": "ŲØŪŒŲŖā€ŒŁ‡Ų§" + }, + "signature": { + "info": "اطلاعات Ų§Ł…Ų¶Ų§", + "_value": "Ų§Ł…Ų¶Ų§", + "mathValid": "Ų§Ł…Ų¶Ų§ Ų§Ų² لحاظ ریاضی Ł…Ų¹ŲŖŲØŲ± Ų§Ų³ŲŖ Ų§Ł…Ų§:" + }, + "selectCustomCert": "ŁŲ§ŪŒŁ„ ŚÆŁˆŲ§Ł‡ŪŒ سفارؓی X.509 (اختیاری)" + }, + "replace-color": { + "title": "Ų¬Ų§ŪŒŚÆŲ²ŪŒŁ†ŪŒ/Ł…Ų¹Ś©ŁˆŲ³ کردن رنگ", + "header": "Ų¬Ų§ŪŒŚÆŲ²ŪŒŁ†ŪŒ/Ł…Ų¹Ś©ŁˆŲ³ کردن رنگ PDF", + "selectText": { + "1": "ŚÆŲ²ŪŒŁ†Ł‡ā€ŒŁ‡Ų§ŪŒ Ų¬Ų§ŪŒŚÆŲ²ŪŒŁ†ŪŒ یا Ł…Ų¹Ś©ŁˆŲ³ کردن رنگ", + "2": "Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶ (Ų±Ł†ŚÆā€ŒŁ‡Ų§ŪŒ Ł¾ŪŒŲ“ā€ŒŁŲ±Ų¶ ŲØŲ§ کنتراست بالا)", + "3": "سفارؓی (Ų±Ł†ŚÆā€ŒŁ‡Ų§ŪŒ Ų³ŁŲ§Ų±Ų“ŪŒā€ŒŲ³Ų§Ų²ŪŒ ؓده)", + "4": "Ł…Ų¹Ś©ŁˆŲ³ کامل (Ł…Ų¹Ś©ŁˆŲ³ کردن ŲŖŁ…Ų§Ł… Ų±Ł†ŚÆā€ŒŁ‡Ų§)", + "5": "ŚÆŲ²ŪŒŁ†Ł‡ā€ŒŁ‡Ų§ŪŒ رنگ ŲØŲ§ کنتراست بالا", + "6": "متن سفید روی Ł¾Ų³ā€ŒŲ²Ł…ŪŒŁ†Ł‡ Ų³ŪŒŲ§Ł‡", + "7": "متن Ų³ŪŒŲ§Ł‡ روی Ł¾Ų³ā€ŒŲ²Ł…ŪŒŁ†Ł‡ سفید", + "8": "متن Ų²Ų±ŲÆ روی Ł¾Ų³ā€ŒŲ²Ł…ŪŒŁ†Ł‡ Ų³ŪŒŲ§Ł‡", + "9": "متن Ų³ŲØŲ² روی Ł¾Ų³ā€ŒŲ²Ł…ŪŒŁ†Ł‡ Ų³ŪŒŲ§Ł‡", + "10": "انتخاب رنگ متن", + "11": "انتخاب رنگ Ł¾Ų³ā€ŒŲ²Ł…ŪŒŁ†Ł‡" + }, + "submit": "Ų¬Ų§ŪŒŚÆŲ²ŪŒŁ†ŪŒ" + }, + "replaceColorPdf": { + "tags": "Ų¬Ų§ŪŒŚÆŲ²ŪŒŁ†ŪŒ Ų±Ł†ŚÆŲŒ Ų¹Ł…Ł„ŪŒŲ§ŲŖ ŲµŁŲ­Ł‡ŲŒ سرور" + }, + "login": { + "title": "ورود", + "header": "ورود", + "signin": "ورود", + "rememberme": "Ł…Ų±Ų§ به Ų®Ų§Ų·Ų± بسپار", + "invalid": "نام کاربری یا رمز عبور اؓتباه Ų§Ų³ŲŖ.", + "locked": "Ų­Ų³Ų§ŲØ Ų“Ł…Ų§ قفل ؓده Ų§Ų³ŲŖ.", + "signinTitle": "لطفاً وارد ؓوید", + "ssoSignIn": "ورود Ų§Ų² Ų·Ų±ŪŒŁ‚ Single Sign-on", + "oAuth2AutoCreateDisabled": "ایجاد خودکار کاربر ŲØŲ§ OAUTH2 ŲŗŪŒŲ±ŁŲ¹Ų§Ł„ Ų§Ų³ŲŖ", + "oAuth2AdminBlockedUser": "Ų«ŲØŲŖā€ŒŁ†Ų§Ł… یا ورود کاربران Ų«ŲØŲŖā€ŒŁ†Ų“ŲÆŁ‡ ŲÆŲ± Ų­Ų§Ł„ Ų­Ų§Ų¶Ų± Ł…Ų³ŲÆŁˆŲÆ Ų§Ų³ŲŖ. لطفاً ŲØŲ§ Ł…ŲÆŪŒŲ± ŲŖŁ…Ų§Ų³ بگیرید.", + "oauth2RequestNotFound": "درخواست Ų§Ų­Ų±Ų§Ų² Ł‡ŁˆŪŒŲŖ پیدا نؓد", + "oauth2InvalidUserInfoResponse": "پاسخ اطلاعات کاربری نامعتبر Ų§Ų³ŲŖ", + "oauth2invalidRequest": "درخواست نامعتبر", + "oauth2AccessDenied": "دسترسی Ł…Ł…Ł†ŁˆŲ¹", + "oauth2InvalidTokenResponse": "پاسخ ŲŖŁˆŚ©Ł† نامعتبر Ų§Ų³ŲŖ", + "oauth2InvalidIdToken": "ŲŖŁˆŚ©Ł† ؓناسه نامعتبر Ų§Ų³ŲŖ", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "کاربر ŲŗŪŒŲ±ŁŲ¹Ų§Ł„ ؓده است، ورود ŲØŲ§ Ų§ŪŒŁ† نام کاربری ŲÆŲ± Ų­Ų§Ł„ Ų­Ų§Ų¶Ų± Ł…Ų³ŲÆŁˆŲÆ Ų§Ų³ŲŖ. لطفاً ŲØŲ§ Ł…ŲÆŪŒŲ± ŲŖŁ…Ų§Ų³ بگیرید.", + "alreadyLoggedIn": "Ų“Ł…Ų§ قبلاً وارد Ų“ŲÆŁ‡ā€ŒŲ§ŪŒŲÆ ŲÆŲ±", + "alreadyLoggedIn2": "ŲÆŲ³ŲŖŚÆŲ§Ł‡ā€ŒŁ‡Ų§. لطفاً Ų§Ų² ŲÆŲ³ŲŖŚÆŲ§Ł‡ā€ŒŁ‡Ų§ Ų®Ų§Ų±Ų¬ ؓده و ŲÆŁˆŲØŲ§Ų±Ł‡ تلاؓ Ś©Ł†ŪŒŲÆ.", + "toManySessions": "Ų“Ł…Ų§ ŲŖŲ¹ŲÆŲ§ŲÆ زیادی نؓست فعال دارید.", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF به یک صفحه", + "header": "PDF به یک صفحه", + "submit": "ŲŖŲØŲÆŪŒŁ„ به یک صفحه" + }, + "pageExtracter": { + "title": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ صفحات", + "header": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ صفحات", + "submit": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬", + "placeholder": "(Ł…Ų«Ų§Ł„: 1,2,8 یا 4,7,12-16 یا 2n-1)" + }, + "sanitizePDF": { + "title": "پاکسازی PDF", + "header": "پاکسازی یک ŁŲ§ŪŒŁ„ PDF", + "selectText": { + "1": "حذف Ų¹Ł…Ł„ŪŒŲ§ŲŖ جاوااسکریپت", + "2": "حذف ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ جاسازی ؓده", + "3": "Remove XMP metadata", + "4": "حذف Ł„ŪŒŁ†Ś©ā€ŒŁ‡Ų§", + "5": "حذف ŁŁˆŁ†ŲŖā€ŒŁ‡Ų§", + "6": "Remove Document Info Metadata" + }, + "submit": "پاکسازی PDF" + }, + "adjustContrast": { + "title": "ŲŖŁ†ŲøŪŒŁ… کنتراست", + "header": "ŲŖŁ†ŲøŪŒŁ… کنتراست", + "contrast": "کنتراست:", + "brightness": "Ų±ŁˆŲ“Ł†Ų§ŪŒŪŒ:", + "saturation": "Ų§Ų“ŲØŲ§Ų¹:", + "download": "ŲÆŲ§Ł†Ł„ŁˆŲÆ" + }, + "compress": { + "title": "ŁŲ“Ų±ŲÆŁ‡ā€ŒŲ³Ų§Ų²ŪŒ", + "header": "ŁŲ“Ų±ŲÆŁ‡ā€ŒŲ³Ų§Ų²ŪŒ PDF", + "credit": "Ų§ŪŒŁ† سرویس Ų§Ų² qpdf برای ŁŲ“Ų±ŲÆŁ‡ā€ŒŲ³Ų§Ų²ŪŒ / ŲØŁ‡ŪŒŁ†Ł‡ā€ŒŲ³Ų§Ų²ŪŒ PDF استفاده Ł…ŪŒā€ŒŚ©Ł†ŲÆ.", + "grayscale": { + "label": "اعمال Ł…Ł‚ŪŒŲ§Ų³ خاکستری برای ŁŲ“Ų±ŲÆŁ‡ā€ŒŲ³Ų§Ų²ŪŒ" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Ų³Ų·Ų­ ŲØŁ‡ŪŒŁ†Ł‡ā€ŒŲ³Ų§Ų²ŪŒ:", + "4": "حالت خودکار - کیفیت Ų±Ų§ به طور خودکار ŲŖŁ†ŲøŪŒŁ… Ł…ŪŒā€ŒŚ©Ł†ŲÆ ŲŖŲ§ PDF به اندازه ŲÆŁ‚ŪŒŁ‚ ŲØŲ±Ų³ŲÆ", + "5": "اندازه PDF Ł…ŁˆŲ±ŲÆ انتظار (مثلاً Ū²ŪµMB، Ū±Ū°.ŪøMB، Ū²ŪµKB)" + }, + "submit": "ŁŲ“Ų±ŲÆŁ‡ā€ŒŲ³Ų§Ų²ŪŒ" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "Ų§ŪŒŁ† ویژگی Ł‡Ł…Ś†Ł†ŪŒŁ† ŲÆŲ± صفحه Ų§ŲØŲ²Ų§Ų± چندگانه Ł…Ų§ Ł…ŁˆŲ¬ŁˆŲÆ Ų§Ų³ŲŖ. برای Ų±Ų§ŲØŲ· کاربری صفحه به صفحه Ł¾ŪŒŲ“Ų±ŁŲŖŁ‡ و ŁˆŪŒŚ˜ŚÆŪŒā€ŒŁ‡Ų§ŪŒ اضافی بررسی Ś©Ł†ŪŒŲÆ!" + }, + "pageRemover": { + "title": "حذف صفحات", + "header": "حذف صفحات PDF", + "pagesToDelete": "صفحات برای حذف (یک Ł„ŪŒŲ³ŲŖ Ų§Ų² Ų§Ų¹ŲÆŲ§ŲÆ صفحه Ų¬ŲÆŲ§ ؓده ŲØŲ§ کاما وارد Ś©Ł†ŪŒŲÆ):", + "submit": "حذف صفحات", + "placeholder": "(Ł…Ų«Ų§Ł„: Ū±,Ū²,Ū¶ یا Ū±-Ū±Ū°,Ū±Ūµ-Ū³Ū°)" + }, + "imageToPDF": { + "title": "ŲŖŲØŲÆŪŒŁ„ تصویر به PDF", + "header": "ŲŖŲØŲÆŪŒŁ„ تصویر به PDF", + "submit": "ŲŖŲØŲÆŪŒŁ„", + "selectLabel": "ŚÆŲ²ŪŒŁ†Ł‡ā€ŒŁ‡Ų§ŪŒ تناسب تصویر", + "fillPage": "پر کردن صفحه", + "fitDocumentToImage": "تناسب صفحه ŲØŲ§ تصویر", + "maintainAspectRatio": "حفظ Ł†Ų³ŲØŲŖā€ŒŁ‡Ų§ŪŒ Ų§ŲØŲ¹Ų§ŲÆ", + "selectText": { + "2": "چرخؓ خودکار PDF", + "3": "منطق چند ŁŲ§ŪŒŁ„ (فقط ŲÆŲ± صورت کار ŲØŲ§ Ś†Ł†ŲÆŪŒŁ† تصویر فعال Ų§Ų³ŲŖ)", + "4": "Ų§ŲÆŲŗŲ§Ł… ŲÆŲ± یک PDF واحد", + "5": "ŲŖŲØŲÆŪŒŁ„ به PDF Ł‡Ų§ŪŒ جداگانه" + } + }, + "PDFToCSV": { + "title": "PDF به CSV", + "header": "PDF به CSV", + "prompt": "ŲµŁŲ­Ł‡ā€ŒŲ§ŪŒ که Ł…ŪŒā€ŒŲ®ŁˆŲ§Ł‡ŪŒŲÆ Ų¬ŲÆŁˆŁ„ Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬ ؓود Ų±Ų§ انتخاب Ś©Ł†ŪŒŲÆ", + "submit": "Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬" + }, + "split-by-size-or-count": { + "title": "ŲŖŁ‚Ų³ŪŒŁ… PDF ŲØŲ± Ų§Ų³Ų§Ų³ اندازه یا ŲŖŲ¹ŲÆŲ§ŲÆ", + "header": "ŲŖŁ‚Ų³ŪŒŁ… PDF ŲØŲ± Ų§Ų³Ų§Ų³ اندازه یا ŲŖŲ¹ŲÆŲ§ŲÆ", + "type": { + "label": "انتخاب Ł†ŁˆŲ¹ ŲŖŁ‚Ų³ŪŒŁ…", + "size": "ŲØŲ± Ų§Ų³Ų§Ų³ اندازه", + "pageCount": "ŲØŲ± Ų§Ų³Ų§Ų³ ŲŖŲ¹ŲÆŲ§ŲÆ صفحات", + "docCount": "ŲØŲ± Ų§Ų³Ų§Ų³ ŲŖŲ¹ŲÆŲ§ŲÆ اسناد" + }, + "value": { + "label": "وارد کردن مقدار", + "placeholder": "اندازه Ų±Ų§ وارد Ś©Ł†ŪŒŲÆ (مثلاً Ū²MB یا Ū³KB) یا ŲŖŲ¹ŲÆŲ§ŲÆ (مثلاً Ūµ)" + }, + "submit": "Ų§Ų±Ų³Ų§Ł„" + }, + "printFile": { + "title": "چاپ ŁŲ§ŪŒŁ„", + "header": "چاپ ŁŲ§ŪŒŁ„ به چاپگر", + "selectText": { + "1": "انتخاب ŁŲ§ŪŒŁ„ برای چاپ", + "2": "نام چاپگر Ų±Ų§ وارد Ś©Ł†ŪŒŲÆ" + }, + "submit": "چاپ" + }, + "licenses": { + "nav": "Ł…Ų¬ŁˆŲ²Ł‡Ų§", + "title": "Ł…Ų¬ŁˆŲ²Ł‡Ų§ŪŒ Ų“Ų®Ųµ ثالث", + "header": "Ł…Ų¬ŁˆŲ²Ł‡Ų§ŪŒ Ų“Ų®Ųµ ثالث", + "module": "Ł…Ų§Ś˜ŁˆŁ„", + "version": "نسخه", + "license": "Ł…Ų¬ŁˆŲ²" + }, + "survey": { + "nav": "Ł†ŲøŲ±Ų³Ł†Ų¬ŪŒ", + "title": "Ł†ŲøŲ±Ų³Ł†Ų¬ŪŒ Stirling-PDF", + "description": "Stirling-PDF Ł‡ŪŒŚ† ردیابی Ł†ŲÆŲ§Ų±ŲÆŲŒ ŲØŁ†Ų§ŲØŲ±Ų§ŪŒŁ† Ł…Ų§ Ł…ŪŒā€ŒŲ®ŁˆŲ§Ł‡ŪŒŁ… Ų§Ų² کاربران خود ŲØŲ“Ł†ŁˆŪŒŁ… ŲŖŲ§ Stirling-PDF Ų±Ų§ ŲØŁ‡ŲØŁˆŲÆ ŲÆŁ‡ŪŒŁ…!", + "changes": "Stirling-PDF Ų§Ų² زمان Ų¢Ų®Ų±ŪŒŁ† Ł†ŲøŲ±Ų³Ł†Ų¬ŪŒ تغییر کرده Ų§Ų³ŲŖ! برای کسب اطلاعات بیؓتر لطفاً پست ŁˆŲØŁ„Ų§ŚÆ Ł…Ų§ Ų±Ų§ Ų§ŪŒŁ†Ų¬Ų§ بررسی Ś©Ł†ŪŒŲÆ:", + "changes2": "ŲØŲ§ Ų§ŪŒŁ† تغییرات، Ł…Ų§ Ų­Ł…Ų§ŪŒŲŖ و ŲŖŲ£Ł…ŪŒŁ† Ł…Ų§Ł„ŪŒ تجاری دریافت Ł…ŪŒā€ŒŚ©Ł†ŪŒŁ…", + "please": "لطفاً ŲÆŲ± نظر بگیرید که ŲÆŲ± Ł†ŲøŲ±Ų³Ł†Ų¬ŪŒ Ł…Ų§ ؓرکت Ś©Ł†ŪŒŲÆ!", + "disabled": "(پنجره Ł†ŲøŲ±Ų³Ł†Ų¬ŪŒ ŲÆŲ± ŲØŲ±ŁˆŲ²Ų±Ų³Ų§Ł†ŪŒā€ŒŁ‡Ų§ŪŒ Ų¢ŪŒŁ†ŲÆŁ‡ ŲŗŪŒŲ±ŁŲ¹Ų§Ł„ Ų®ŁˆŲ§Ł‡ŲÆ Ų“ŲÆ Ų§Ł…Ų§ ŲÆŲ± Ł¾Ų§ŪŒŪŒŁ† صفحه ŲÆŲ± ŲÆŲ³ŲŖŲ±Ų³ Ų®ŁˆŲ§Ł‡ŲÆ بود)", + "button": "ؓرکت ŲÆŲ± Ł†ŲøŲ±Ų³Ł†Ų¬ŪŒ", + "dontShowAgain": "دیگر نؓان نده", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "حذف تصویر", + "header": "حذف تصویر", + "removeImage": "حذف تصویر", + "submit": "حذف تصویر" + }, + "splitByChapters": { + "title": "ŲŖŁ‚Ų³ŪŒŁ… PDF ŲØŲ± Ų§Ų³Ų§Ų³ ŁŲµŁ„ā€ŒŁ‡Ų§", + "header": "ŲŖŁ‚Ų³ŪŒŁ… PDF ŲØŲ± Ų§Ų³Ų§Ų³ ŁŲµŁ„ā€ŒŁ‡Ų§", + "bookmarkLevel": "Ų³Ų·Ų­ نؓانک", + "includeMetadata": "Ų“Ų§Ł…Ł„ Ł…ŲŖŲ§ŲÆŪŒŲŖŲ§", + "allowDuplicates": "Ų§Ų¬Ų§Ų²Ł‡ā€ŒŪŒ تکرار", + "desc": { + "1": "Ų§ŪŒŁ† Ų§ŲØŲ²Ų§Ų± یک ŁŲ§ŪŒŁ„ PDF Ų±Ų§ ŲØŲ± Ų§Ų³Ų§Ų³ Ų³Ų§Ų®ŲŖŲ§Ų± ŁŲµŁ„ā€ŒŲ§Ų“ به Ś†Ł†ŲÆŪŒŁ† ŁŲ§ŪŒŁ„ PDF ŲŖŁ‚Ų³ŪŒŁ… Ł…ŪŒā€ŒŚ©Ł†ŲÆ.", + "2": "Ų³Ų·Ų­ نؓانک: Ų³Ų·Ų­ Ł†Ų“Ų§Ł†Ś©ā€ŒŁ‡Ų§ Ų±Ų§ برای استفاده ŲÆŲ± ŲŖŁ‚Ų³ŪŒŁ… انتخاب Ś©Ł†ŪŒŲÆ (0 برای Ų³Ų·Ų­ ŲØŲ§Ł„Ų§ŲŒ 1 برای Ų³Ų·Ų­ ŲÆŁˆŁ… و ŲŗŪŒŲ±Ł‡).", + "3": "Ų“Ų§Ł…Ł„ Ł…ŲŖŲ§ŲÆŪŒŲŖŲ§: Ų§ŚÆŲ± انتخاب Ų“ŲÆŁ‡ŲŒ Ł…ŲŖŲ§ŲÆŪŒŲŖŲ§ŪŒ ŁŲ§ŪŒŁ„ PDF Ų§ŲµŁ„ŪŒ ŲÆŲ± هر ŁŲ§ŪŒŁ„ ŲŖŁ‚Ų³ŪŒŁ…ā€ŒŲ“ŲÆŁ‡ گنجانده Ų®ŁˆŲ§Ł‡ŲÆ Ų“ŲÆ.", + "4": "Ų§Ų¬Ų§Ų²Ł‡ā€ŒŪŒ تکرار: Ų§ŚÆŲ± انتخاب ؓده باؓد، اجازه Ł…ŪŒā€ŒŲÆŁ‡ŲÆ Ł†Ų“Ų§Ł†Ś©ā€ŒŁ‡Ų§ŪŒ Ł…ŲŖŲ¹ŲÆŲÆ ŲÆŲ± یک ŲµŁŲ­Ł‡ŲŒ ŁŲ§ŪŒŁ„ā€ŒŁ‡Ų§ŪŒ PDF جداگانه ایجاد کنند." + }, + "submit": "ŲŖŁ‚Ų³ŪŒŁ… PDF" + }, + "fileChooser": { + "click": "Ś©Ł„ŪŒŚ© Ś©Ł†ŪŒŲÆ", + "or": "یا", + "dragAndDrop": "بکؓید و رها Ś©Ł†ŪŒŲÆ", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "ŁŲ§ŪŒŁ„(Ł‡Ų§ŪŒ) خود Ų±Ų§ Ų§ŪŒŁ†Ų¬Ų§ بکؓید و رها Ś©Ł†ŪŒŲÆ", + "extractPDF": "ŲÆŲ± Ų­Ų§Ł„ Ų§Ų³ŲŖŲ®Ų±Ų§Ų¬..." + }, + "releases": { + "footer": "Ł†Ų³Ų®Ł‡ā€ŒŁ‡Ų§", + "title": "ŪŒŲ§ŲÆŲÆŲ§Ų“ŲŖā€ŒŁ‡Ų§ŪŒ نسخه", + "header": "ŪŒŲ§ŲÆŲÆŲ§Ų“ŲŖā€ŒŁ‡Ų§ŪŒ نسخه", + "current": { + "version": "نسخه ŁŲ¹Ł„ŪŒ" + }, + "note": "ŪŒŲ§ŲÆŲÆŲ§Ų“ŲŖā€ŒŁ‡Ų§ŪŒ نسخه فقط به زبان Ų§Ł†ŚÆŁ„ŪŒŲ³ŪŒ Ł…ŁˆŲ¬ŁˆŲÆ Ų§Ų³ŲŖ" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/fr-FR/translation.json b/frontend/public/locales/fr-FR/translation.json new file mode 100644 index 000000000..6d88493ca --- /dev/null +++ b/frontend/public/locales/fr-FR/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Taille de Police", + "fontName": "Nom de la Police", + "title": "Ajouter des numĆ©ros de page", + "header": "Ajouter des numĆ©ros de page", + "selectText": { + "1": "SĆ©lectionnez le fichier PDF", + "2": "Taille de la marge", + "3": "Position", + "4": "NumĆ©ro de dĆ©part", + "5": "Pages Ć  numĆ©roter", + "6": "Texte personnalisĆ©" + }, + "customTextDesc": "Texte personnalisĆ©", + "numberPagesDesc": "Quelles pages numĆ©roter, par dĆ©faut 'all' (toutes les pages), accepte Ć©galement 1-5 ou 2,5,9, etc.", + "customNumberDesc": "La valeur par dĆ©faut est '{n}', accepte Ć©galement 'Page {n} sur {total}', 'Texte-{n}', '{filename}-{n}'", + "submit": "Ajouter les numĆ©ros de page" + }, + "pdfPrompt": "SĆ©lectionnez le(s) PDF", + "multiPdfPrompt": "SĆ©lectionnez les PDF", + "multiPdfDropPrompt": "SĆ©lectionnez (ou glissez-dĆ©posez) tous les PDF dont vous avez besoin", + "imgPrompt": "Choisir une image", + "genericSubmit": "Envoyer", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Attention, ce processus peut prendre jusqu'Ć  une minute en fonction de la taille du fichier.", + "pageOrderPrompt": "Ordre des pages (entrez une liste de numĆ©ros de page sĆ©parĆ©s par des virgules ou des fonctions telles que 2n+1)Ā :", + "pageSelectionPrompt": "SĆ©lection des pages (entrez une liste de numĆ©ros de page sĆ©parĆ©s par des virgules ou des fonctions telles que 2n+1)Ā :", + "goToPage": "Aller", + "true": "Vrai", + "false": "Faux", + "unknown": "Inconnu", + "save": "Enregistrer", + "saveToBrowser": "Enregistrer dans le navigateur", + "close": "Fermer", + "filesSelected": "fichiers sĆ©lectionnĆ©s", + "noFavourites": "Aucun favori ajoutĆ©", + "downloadComplete": "TĆ©lĆ©chargement terminĆ©", + "bored": "Marre d'attendreĀ ?", + "alphabet": "Alphabet", + "downloadPdf": "TĆ©lĆ©charger le PDF", + "text": "Texte", + "font": "Police", + "selectFillter": "-- SĆ©lectionnez --", + "pageNum": "NumĆ©ro de page", + "sizes": { + "small": "Petit", + "medium": "Moyen", + "large": "Grand", + "x-large": "TrĆØs grand" + }, + "error": { + "pdfPassword": "Le document PDF est protĆ©gĆ© par un mot de passe qui n'a pas Ć©tĆ© fourni ou Ć©tait incorrect", + "_value": "Erreur", + "sorry": "DĆ©solĆ© pour ce problĆØme !", + "needHelp": "Besoin d'aide / Vous avez trouvĆ© un problĆØme ?", + "contactTip": "Si vous avez encore des problĆØmes, n'hĆ©sitez pas Ć  nous contacter pour obtenir de l'aide. Vous pouvez soumettre un ticket sur notre page GitHub ou nous contacter via Discord :", + "404": { + "head": "404 - Page non trouvĆ©e | oups on s'est foirĆ© !", + "1": "Nous ne parvenons pas Ć  trouver la page que vous recherchez.", + "2": "Quelque chose n'a pas fonctionnĆ©" + }, + "github": "CrĆ©er un ticket sur GitHub", + "showStack": "Afficher la Stack Trace", + "copyStack": "Copier la Stack Trace", + "githubSubmit": "GitHub - CrĆ©er un ticket", + "discordSubmit": "Discord - Poster un message de demande d'assistance" + }, + "delete": "Supprimer", + "username": "Nom d'utilisateur", + "password": "Mot de passe", + "welcome": "Bienvenue", + "property": "PropriĆ©tĆ©", + "black": "Noir", + "white": "Blanc", + "red": "Rouge", + "green": "Vert", + "blue": "Bleu", + "custom": "Personnalisé…", + "WorkInProgess": "En cours de dĆ©veloppement, merci de nous remonter les problĆØmes que vous pourriez constater!", + "poweredBy": "PropulsĆ© par", + "yes": "Oui", + "no": "Non", + "changedCredsMessage": "Les identifiants ont Ć©tĆ© mis Ć  jourĀ !", + "notAuthenticatedMessage": "Utilisateur non authentifiĆ©.", + "userNotFoundMessage": "Utilisateur non trouvĆ©.", + "incorrectPasswordMessage": "Le mot de passe actuel est incorrect.", + "usernameExistsMessage": "Le nouveau nom d'utilisateur existe dĆ©jĆ .", + "invalidUsernameMessage": "Nom d'utilisateur invalide, le nom d'utilisateur ne peut contenir que des lettres, des chiffres et les caractĆØres spĆ©ciaux suivants @._+- ou doit ĆŖtre une adresse e-mail valide.", + "invalidPasswordMessage": "Le mot de passe ne peut pas ĆŖtre vide et ne doit pas contenir d'espaces au dĆ©but ou Ć  la fin.", + "confirmPasswordErrorMessage": "Le nouveau mot de passe et sa confirmation doivent ĆŖtre identiques.", + "deleteCurrentUserMessage": "Impossible de supprimer l'utilisateur actuellement connectĆ©.", + "deleteUsernameExistsMessage": "Le nom d'utilisateur n'existe pas et ne peut pas ĆŖtre supprimĆ©.", + "downgradeCurrentUserMessage": "Impossible de rĆ©trograder le rĆ“le de l'utilisateur actuel.", + "disabledCurrentUserMessage": "L'utilisateur actuel ne peut pas ĆŖtre dĆ©sactivĆ©", + "downgradeCurrentUserLongMessage": "Impossible de rĆ©trograder le rĆ“le de l'utilisateur actuel. Par consĆ©quent, l'utilisateur actuel ne sera pas affichĆ©.", + "userAlreadyExistsOAuthMessage": "L'utilisateur existe dĆ©jĆ  en tant qu'utilisateur OAuth2.", + "userAlreadyExistsWebMessage": "L'utilisateur existe dĆ©jĆ  en tant qu'utilisateur Web.", + "oops": "OupsĀ !", + "help": "Aide", + "goHomepage": "Aller Ć  la page d'accueil", + "joinDiscord": "Rejoignez notre serveur Discord", + "seeDockerHub": "Consulter le Docker Hub", + "visitGithub": "Visiter le dĆ©pĆ“t Github", + "donate": "Faire un don", + "color": "Couleur", + "sponsor": "Sponsoriser", + "info": "Informations", + "pro": "Pro", + "page": "Page", + "pages": "Pages", + "loading": "Chargement...", + "addToDoc": "Ajouter au Document", + "reset": "RĆ©initialiser", + "apply": "Appliquer", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Politique de ConfidentialitĆ©", + "terms": "Conditions GĆ©nĆ©rales", + "accessibility": "AccessibilitĆ©", + "cookie": "Politique des Cookies", + "impressum": "Mentions LĆ©gales", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Menu Pipeline (Beta)", + "uploadButton": "Charger une personnalisation", + "configureButton": "Configurer", + "defaultOption": "Personnaliser", + "submitButton": "Soumettre", + "help": "Aide Pipeline", + "scanHelp": "Aide analyse de dossier", + "deletePrompt": "Êtes-vous sĆ»r de vouloir supprimer le pipeline ?", + "tags": "automatiser,sĆ©quencer,automate,sequence,scripted,batch-process", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Configuration du pipeline", + "pipelineNameLabel": "Nom du pipeline", + "saveSettings": "Sauvegarder la configuration", + "pipelineNamePrompt": "Entrez ici le nom du pipeline", + "selectOperation": "SĆ©lectionner une opĆ©ration", + "addOperationButton": "Ajouter une opĆ©ration", + "pipelineHeader": "Pipeline :", + "saveButton": "TĆ©lĆ©charger", + "validateButton": "Valider" + }, + "enterpriseEdition": { + "button": "Passer Ć  Pro", + "warning": "Cette fonctionnalitĆ© est uniquement disponible pour les utilisateurs Pro.", + "yamlAdvert": "Stirling PDF Pro prend en charge les fichiers de configuration YAML et d'autres fonctionnalitĆ©s SSO.", + "ssoAdvert": "Vous cherchez plus de fonctionnalitĆ©s de gestion des utilisateurs ? DĆ©couvrez Stirling PDF Pro" + }, + "analytics": { + "title": "Souhaitez-vous amĆ©liorer Stirling PDF ?", + "paragraph1": "Stirling PDF utilise des analyses volontaires pour nous aider Ć  amĆ©liorer le produit. Nous ne suivons aucune information personnelle ni le contenu des fichiers.", + "paragraph2": "Veuillez envisager d'activer les analyses pour aider Stirling-PDF Ć  se dĆ©velopper et pour nous permettre de mieux comprendre nos utilisateurs.", + "enable": "Activer les analyses", + "disable": "DĆ©sactiver les analyses", + "settings": "Vous pouvez modifier les paramĆØtres des analyses dans le fichier config/settings.yml" + }, + "navbar": { + "favorite": "Favoris", + "recent": "Nouveau et mise Ć  jour", + "darkmode": "Mode sombre", + "language": "Langues", + "settings": "ParamĆØtres", + "allTools": "Outils", + "multiTool": "Outils Multiples", + "search": "Rechercher", + "sections": { + "organize": "Organisation", + "convertTo": "Convertir en PDF", + "convertFrom": "Convertir depuis PDF", + "security": "Signature et sĆ©curitĆ©", + "advance": "Mode avancĆ©", + "edit": "Voir et modifier", + "popular": "Populaire" + } + }, + "settings": { + "title": "ParamĆØtres", + "update": "Mise Ć  jour disponible", + "updateAvailable": "{0} est la version actuellement installĆ©e. Une nouvelle version ({1}) est disponible.", + "appVersion": "Version de l'applicationĀ :", + "downloadOption": { + "title": "Choisissez l'option de tĆ©lĆ©chargement (pour les tĆ©lĆ©chargements Ć  fichier unique non ZIP)Ā :", + "1": "Ouvrir dans la mĆŖme fenĆŖtre", + "2": "Ouvrir dans une nouvelle fenĆŖtre", + "3": "TĆ©lĆ©charger le fichier" + }, + "zipThreshold": "Compresser les fichiers en ZIP lorsque le nombre de fichiers tĆ©lĆ©chargĆ©s dĆ©passe", + "signOut": "DĆ©connexion", + "accountSettings": "ParamĆØtres du compte", + "bored": { + "help": "Activer les jeux cachĆ©s" + }, + "cacheInputs": { + "name": "Sauvegarder les entrĆ©es du formulaire", + "help": "Permet de stocker les entrĆ©es prĆ©cĆ©demment utilisĆ©es pour les exĆ©cutions futures" + } + }, + "changeCreds": { + "title": "Modifiez vos identifiants", + "header": "Mettez Ć  jour vos identifiants de connexion", + "changePassword": "Vous utilisez les identifiants de connexion par dĆ©faut. Veuillez saisir un nouveau mot de passe", + "newUsername": "Nouveau nom d'utilisateur", + "oldPassword": "Mot de passe actuel", + "newPassword": "Nouveau mot de passe", + "confirmNewPassword": "Confirmer le nouveau mot de passe", + "submit": "Soumettre les modifications" + }, + "account": { + "title": "ParamĆØtres du compte", + "accountSettings": "ParamĆØtres du compte", + "adminSettings": "ParamĆØtres d'administration – Voir et ajouter des utilisateurs", + "userControlSettings": "ContrĆ“le des paramĆØtres des utilisateurs", + "changeUsername": "Modifier le nom d'utilisateur", + "newUsername": "Nouveau nom d'utilisateur", + "password": "Mot de passe de confirmation", + "oldPassword": "Ancien mot de passe", + "newPassword": "Nouveau mot de passe", + "changePassword": "Modifier le mot de passe", + "confirmNewPassword": "Confirmer votre nouveau mot de passe", + "signOut": "DĆ©connexion", + "yourApiKey": "Votre clĆ© API", + "syncTitle": "Synchroniser les paramĆØtres du navigateur avec le compte", + "settingsCompare": "Comparaison des paramĆØtres", + "property": "PropriĆ©tĆ©", + "webBrowserSettings": "ParamĆØtres du navigateur", + "syncToBrowser": "SynchroniserĀ : Compte → Navigateur", + "syncToAccount": "SynchroniserĀ : Compte ← Navigateur" + }, + "adminUserSettings": { + "title": "Administration des paramĆØtres des utilisateurs", + "header": "Administration des paramĆØtres des utilisateurs", + "admin": "Administateur", + "user": "Utilisateur", + "addUser": "Ajouter un utilisateur", + "deleteUser": "Supprimer l'utilisateur", + "confirmDeleteUser": "Voulez vous vraiment supprimer l'utilisateur ?", + "confirmChangeUserStatus": "Voulez vous vraiment dĆ©activer/rĆ©activer l'utilisateur ?", + "usernameInfo": "Le nom d'utilisateur ne peut contenir que des lettres, des chiffres et les caractĆØres spĆ©ciaux suivants @._+- ou doit ĆŖtre une adresse e-mail valide.", + "roles": "RĆ“les", + "role": "RĆ“le", + "actions": "Actions", + "apiUser": "Utilisateur API limitĆ©", + "extraApiUser": "Utilisateur limitĆ© supplĆ©mentaire de l'API", + "webOnlyUser": "Utilisateur Web uniquement", + "demoUser": "Demo User (ParamĆØtres par dĆ©faut)", + "internalApiUser": "Utilisateur de l'API interne", + "forceChange": "Forcer l'utilisateur Ć  changer son nom d'utilisateur/mot de passe lors de la connexion", + "submit": "Ajouter", + "changeUserRole": "Changer le rĆ“le de l'utilisateur", + "authenticated": "AuthentifiĆ©", + "editOwnProfil": "Ɖditer son propre profil", + "enabledUser": "Utilisateur activĆ©", + "disabledUser": "Utilisateur dĆ©sactivĆ©", + "activeUsers": "Utilisateurs actifs :", + "disabledUsers": "Utilisateurs dĆ©sactivĆ©s :", + "totalUsers": "Utilisateurs au total :", + "lastRequest": "DerniĆØre requĆŖte", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Import/Export de la Base de DonnĆ©es", + "header": "Import/Export de la Base de DonnĆ©es", + "fileName": "Nom du Fichier", + "creationDate": "Date de CrĆ©ation", + "fileSize": "Taille du Fichier", + "deleteBackupFile": "Supprimer le fichier de sauvegarde", + "importBackupFile": "Importer le fichier de sauvegarde", + "createBackupFile": "CrĆ©er un fichier de sauvegarde", + "downloadBackupFile": "TĆ©lĆ©charger le fichier de sauvegarde", + "info_1": "Lors de l'importation des donnĆ©es, il est crucial de garantir la structure correcte. Si vous n'ĆŖtes pas sĆ»r de ce que vous faites, sollicitez un avis et un soutien d'un professionnel. Une erreur dans la structure peut entraĆ®ner des dysfonctionnements de l'application, allant jusqu'Ć  l'incapacitĆ© totale d'exĆ©cuter l'application.", + "info_2": "Le nom du fichier ne fait pas de diffĆ©rence lors de l'upload. Il sera renommĆ© ultĆ©rieurement selon le format backup_user_yyyyMMddHHmm.sql, assurant ainsi une convention de nommage cohĆ©rente.", + "submit": "Importer la sauvegarde", + "importIntoDatabaseSuccessed": "Importation dans la base de donnĆ©es rĆ©ussie", + "backupCreated": "Sauvegarde de la base de donnĆ©e rĆ©ussie", + "fileNotFound": "Fichier introuvable", + "fileNullOrEmpty": "Fichier ne peut pas ĆŖtre null ou vide", + "failedImportFile": "Ɖchec de l'imporation du fichier", + "notSupported": "Cette fonctionnalitĆ© n'est pas supportĆ©e avec votre base de donnĆ©e" + }, + "session": { + "expired": "Votre session a expirĆ©. Veuillez recharger la page et rĆ©essayer.", + "refreshPage": "Rafraichir la page" + }, + "home": { + "desc": "Votre application Web hĆ©bergĆ©e localement pour rĆ©pondre Ć  tous vos besoins PDF.", + "searchBar": "Rechercher des fonctionnalitĆ©s...", + "viewPdf": { + "title": "Visionner/Modifier des PDF", + "desc": "Visionner, annoter, ajouter du texte ou des images." + }, + "setFavorites": "Ajouter des favoris", + "hideFavorites": "Cacher les favoris", + "showFavorites": "Montrer les favoris", + "legacyHomepage": "Ancienne Homepage", + "newHomePage": "Essayez notre nouvelle Homepage !", + "alphabetical": "AlphabĆ©tique", + "globalPopularity": "PopularitĆ© globale", + "sortBy": "Trier par :", + "multiTool": { + "title": "Outil multifonction PDF", + "desc": "Fusionnez, faites pivoter, rĆ©organisez et supprimez des pages." + }, + "merge": { + "title": "Fusionner", + "desc": "Fusionnez facilement plusieurs PDF en un seul." + }, + "split": { + "title": "Diviser", + "desc": "Divisez un PDF en plusieurs documents." + }, + "rotate": { + "title": "Pivoter", + "desc": "Faites pivoter facilement vos PDF." + }, + "imageToPdf": { + "title": "Image en PDF", + "desc": "Convertissez une image (PNG, JPEG, GIF) en PDF." + }, + "pdfToImage": { + "title": "PDF en image", + "desc": "Convertissez un PDF en image (PNG, JPEG, GIF)." + }, + "pdfOrganiser": { + "title": "Organiser", + "desc": "Supprimez ou rĆ©organisez les pages dans n'importe quel ordre." + }, + "addImage": { + "title": "Ajouter une image", + "desc": "Ajoutez une image Ć  un emplacement dĆ©fini sur un PDF." + }, + "watermark": { + "title": "Ajouter un filigrane", + "desc": "Ajoutez un filigrane personnalisĆ© Ć  votre PDF." + }, + "permissions": { + "title": "Modifier les permissions", + "desc": "Modifiez les permissions de votre PDF." + }, + "removePages": { + "title": "Supprimer", + "desc": "Supprimez les pages inutiles de votre PDF." + }, + "addPassword": { + "title": "Ajouter un mot de passe", + "desc": "Chiffrez votre PDF avec un mot de passe." + }, + "removePassword": { + "title": "Supprimer le mot de passe", + "desc": "Supprimez la protection par mot de passe de votre PDF." + }, + "compressPdfs": { + "title": "Compresser", + "desc": "Compressez les PDF pour rĆ©duire leur tailles." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Modifier les mĆ©tadonnĆ©es", + "desc": "Modifiez, supprimez ou ajoutez des mĆ©tadonnĆ©es Ć  un PDF." + }, + "fileToPDF": { + "title": "Fichier en PDF", + "desc": "Convertissez presque n'importe quel fichier en PDF (DOCX, PNG, XLS, PPT, TXT, etc.)." + }, + "ocr": { + "title": "OCR / Nettoyage des numĆ©risations", + "desc": "Utilisez l'OCR pour analyser et dĆ©tecter le texte des images d'un PDF et le rajouter en tant que tel." + }, + "extractImages": { + "title": "Extraire les images", + "desc": "Extrayez toutes les images d'un PDF et enregistrez-les dans un ZIP." + }, + "pdfToPDFA": { + "title": "PDF en PDF/A", + "desc": "Convertir un PDF en PDF/A pour un stockage Ć  long terme." + }, + "PDFToWord": { + "title": "PDF en Word", + "desc": "Convertissez un PDF en Word (DOC, DOCX et ODT)." + }, + "PDFToPresentation": { + "title": "PDF en formats de prĆ©sentation", + "desc": "Convertissez un PDF en format de prĆ©sentation (PPT, PPTX et ODP)." + }, + "PDFToText": { + "title": "PDF en RTF (texte)", + "desc": "Convertissez un PDF au format RTF (texte)." + }, + "PDFToHTML": { + "title": "PDF en HTML", + "desc": "Convertissez un PDF au format HTML." + }, + "PDFToXML": { + "title": "PDF en XML", + "desc": "Convertissez un PDF au format XML." + }, + "ScannerImageSplit": { + "title": "Diviser les photos numĆ©risĆ©es", + "desc": "Divisez plusieurs photos Ć  partir d'une photo ou d'un PDF." + }, + "sign": { + "title": "Signer", + "desc": "Ajoutez une signature au PDF avec un dessin, du texte ou une image." + }, + "flatten": { + "title": "Rendre inerte", + "desc": "Supprimez tous les Ć©lĆ©ments et formulaires interactifs d'un PDF." + }, + "repair": { + "title": "RĆ©parer", + "desc": "Essayez de rĆ©parer un PDF corrompu ou cassĆ©." + }, + "removeBlanks": { + "title": "Supprimer les pages vierges", + "desc": "DĆ©tectez et supprimez les pages vierges d'un PDF." + }, + "removeAnnotations": { + "title": "Supprimer les annotations", + "desc": "Supprimer tous les commentaires/annotations d'un PDF." + }, + "compare": { + "title": "Comparer", + "desc": "Comparez et visualisez les diffĆ©rences entre deux PDF." + }, + "certSign": { + "title": "Signer avec un certificat", + "desc": "Signez un PDF avec un certificat ou une clĆ© (PEM/P12)." + }, + "removeCertSign": { + "title": "Supprimer la signature par certificat", + "desc": "Supprimez la signature par certificat d'un PDF" + }, + "pageLayout": { + "title": "Fusionner des pages", + "desc": "Fusionnez plusieurs pages d'un PDF en une seule." + }, + "scalePages": { + "title": "Ajuster l'Ć©chelle ou la taille", + "desc": "Modifiez la taille ou l'Ć©chelle d'une page et/ou de son contenu." + }, + "pipeline": { + "title": "Pipeline", + "desc": "ExĆ©cutez plusieurs actions sur les PDF en dĆ©finissant des scripts de pipeline." + }, + "add-page-numbers": { + "title": "Ajouter des numĆ©ros de page", + "desc": "Ajoutez des numĆ©ros de page dans un PDF Ć  un emplacement dĆ©fini." + }, + "auto-rename": { + "title": "Renommer automatiquement", + "desc": "Renommez automatiquement un fichier PDF en fonction de son en-tĆŖte dĆ©tectĆ©." + }, + "adjust-contrast": { + "title": "Ajuster les couleurs", + "desc": "Ajustez le contraste, la saturation et la luminositĆ© d'un PDF." + }, + "crop": { + "title": "Redimensionner", + "desc": "Redimensionnez un PDF pour rĆ©duire sa taille (en conservant le texteĀ !)." + }, + "autoSplitPDF": { + "title": "SĆ©parer automatiquement les pages", + "desc": "SĆ©parez automatiquement le PDF numĆ©risĆ© avec le code QR du diviseur de page numĆ©risĆ©." + }, + "sanitizePdf": { + "title": "Assainir", + "desc": "Supprimez les scripts et autres Ć©lĆ©ments des PDF." + }, + "URLToPDF": { + "title": "URL en PDF", + "desc": "Convertissez n'importe quelle URL http(s) en PDF." + }, + "HTMLToPDF": { + "title": "HTML en PDF", + "desc": "Convertissez n'importe quel fichier HTML ou ZIP en PDF." + }, + "MarkdownToPDF": { + "title": "Markdown en PDF", + "desc": "Convertissez n'importe quel fichier Markdown en PDF." + }, + "PDFToMarkdown": { + "title": "PDF en Markdown", + "desc": "Convertissez n'importe quel fichier PDF en Markdown." + }, + "getPdfInfo": { + "title": "RĆ©cupĆ©rer les informations", + "desc": "RĆ©cupĆ©rez toutes les informations possibles sur un PDF." + }, + "extractPage": { + "title": "Extraire des pages", + "desc": "Extrayez certaines pages du PDF." + }, + "PdfToSinglePage": { + "title": "Fusionner en une seule page", + "desc": "Fusionnez toutes les pages PDF en une seule grande page." + }, + "showJS": { + "title": "Afficher le JavaScript", + "desc": "Recherche et affiche tout JavaScript injectĆ© dans un PDF." + }, + "autoRedact": { + "title": "Caviardage automatique", + "desc": "Caviardez automatiquement les informations sensibles d'un PDF." + }, + "redact": { + "title": "Caviardage manuel", + "desc": "Caviarder un PDF en fonction de texte sĆ©lectionnĆ©, formes dessinĆ©es et/ou des pages sĆ©lectionnĆ©es." + }, + "tableExtraxt": { + "title": "PDF en CSV", + "desc": "Extrait les tableaux d'un PDF et les transforme en CSV." + }, + "autoSizeSplitPDF": { + "title": "SĆ©parer automatiquement par taille/nombre", + "desc": "SĆ©parer un PDF unique en plusieurs documents en fonction de la taille, du nombre de pages ou du nombre de documents." + }, + "overlay-pdfs": { + "title": "Incrustation de PDF", + "desc": "Incrustation d'un PDF sur un autre PDF." + }, + "split-by-sections": { + "title": "SĆ©parer un PDF en sections", + "desc": "Diviser chaque page d'un PDF en sections horizontales/verticales plus petites." + }, + "AddStampRequest": { + "title": "Ajouter un tampon sur un PDF", + "desc": "Ajouter un texte ou l'image d'un tampon Ć  un emplacement dĆ©fini." + }, + "removeImagePdf": { + "title": "Supprimer les images", + "desc": "Supprimez les images d'un PDF pour rĆ©duire sa taille" + }, + "splitPdfByChapters": { + "title": "SĆ©parer un PDF par chapitres", + "desc": "SĆ©parez un PDF en fichiers multiples en fonction de sa structure par chapitres." + }, + "validateSignature": { + "title": "Valider la signature du fichier PDF", + "desc": "VĆ©rifier les signatures numĆ©riques et les certificats des documents PDF" + }, + "replaceColorPdf": { + "title": "Remplacer et Inverser Couleur", + "desc": "Remplacer la couleur pour le texte et l'arriĆØre-plan dans le PDF et inverser la couleur complĆØte du PDF pour rĆ©duire la taille du fichier" + } + }, + "viewPdf": { + "tags": "visualiser,lire,annoter,texte,image", + "title": "View/Edit PDF", + "header": "Visualiser un PDF" + }, + "multiTool": { + "tags": "outil multifonction,opĆ©ration multifonction,interface utilisateur,glisser dĆ©poser,front-end,client side,interactif,intransigeant,dĆ©placer,multi tool", + "title": "Outil multifonction PDF", + "header": "Outil multifonction PDF", + "uploadPrompts": "Nom du fichier", + "selectAll": "Tout sĆ©lectionner", + "deselectAll": "Tout dĆ©selectionner", + "selectPages": "SĆ©lection des pages", + "selectedPages": "Pages sĆ©lectionnĆ©es", + "page": "Page", + "deleteSelected": "Supprimer la sĆ©lection", + "downloadAll": "Exporter", + "downloadSelected": "Exporter la sĆ©lection", + "insertPageBreak": "InsĆ©rer un saut de page", + "addFile": "Ajouter un fichier", + "rotateLeft": "Rotation vers la gauche", + "rotateRight": "Rotation vers la droite", + "split": "Diviser", + "moveLeft": "DĆ©placer vers la gauche", + "moveRight": "DĆ©placer vers la droite", + "delete": "Supprimer", + "dragDropMessage": "Page(s) sĆ©lectionnĆ©es", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "fusionner,opĆ©rations sur les pages,backend,server side,merge", + "title": "Fusionner", + "header": "Fusionner plusieurs PDF", + "sortByName": "Trier par nom", + "sortByDate": "Trier par date", + "removeCertSign": "Supprimer la signature numĆ©rique dans le fichier fusionnĆ© ?", + "submit": "Fusionner" + }, + "split": { + "tags": "opĆ©rations sur les pages,diviser,plusieurs pages,cut,server side,divide", + "title": "Diviser", + "header": "Diviser", + "desc": { + "1": "Les numĆ©ros que vous sĆ©lectionnez sont le numĆ©ro de page sur lequel vous souhaitez faire une division", + "2": "Ainsi, la sĆ©lection de 1,3,7-9 diviserait un document de 10 pages en 6 PDF distincts avecĀ :", + "3": "Document #1: Page 1", + "4": "Document #2: Page 2 et 3", + "5": "Document #3: Page 4, 5, 6 et 7", + "6": "Document #4: Page 8", + "7": "Document #5: Page 9", + "8": "Document #6: Page 10" + }, + "splitPages": "Pages sur lesquelles diviser", + "submit": "Diviser" + }, + "rotate": { + "tags": "pivoter,server side,rotate", + "title": "Pivoter", + "header": "Pivoter", + "selectAngle": "Angle de rotation (par multiples de 90 degrĆ©s)", + "submit": "Pivoter" + }, + "imageToPdf": { + "tags": "pdf,conversion,img,jpg,image,photo" + }, + "pdfToImage": { + "tags": "conversion,img,jpg,image,photo", + "title": "PDF en Image", + "header": "PDF en Image", + "selectText": "Format d'image", + "singleOrMultiple": "Type de rĆ©sultat", + "single": "Une seule grande image", + "multi": "Plusieurs images", + "colorType": "Type d'impression", + "color": "Couleur", + "grey": "Niveaux de gris", + "blackwhite": "Noir et blanc (peut engendrer une perte de donnĆ©esĀ !)", + "submit": "Convertir", + "info": "Python n’est pas installĆ©. NĆ©cessaire pour la conversion WebP.", + "placeholder": "(par exemple : 1,2,8 ou 4,7,12-16 ou 2n-1)" + }, + "pdfOrganiser": { + "tags": "organiser,recto-verso,duplex,even,odd,sort,move", + "title": "Organiser", + "header": "Organiser les pages", + "submit": "Organiser", + "mode": { + "_value": "Mode", + "1": "Ordre des pages personnalisĆ©", + "2": "Ordre inverse", + "3": "Tri recto verso", + "4": "Tri des livrets", + "5": "Tri de livrets Ć  points latĆ©raux", + "6": "Partage impair-pair", + "7": "Supprimer le premier", + "8": "Supprimer le dernier", + "9": "Supprimer le premier et le dernier", + "10": "MĆ©ger Impair-Pair", + "11": "Duplicate all pages" + }, + "placeholder": "(par exemple 1,3,2 ou 4-8,2,10-12 ou 2n-1)" + }, + "addImage": { + "tags": "img,jpg,image,photo", + "title": "Ajouter une image", + "header": "Ajouter une image", + "everyPage": "Toutes les pagesĀ ?", + "upload": "TĆ©lĆ©charger une image", + "submit": "Ajouter une image" + }, + "watermark": { + "tags": "texte,filigrane,label,propriĆ©tĆ©,droit d'auteur,marque dĆ©posĆ©e,img,jpg,image,photo,copyright,trademark", + "title": "Ajouter un filigrane", + "header": "Ajouter un filigrane", + "customColor": "Couleur de texte personnalisĆ©e", + "selectText": { + "1": "PDF auquel ajouter un filigrane", + "2": "Texte du filigrane", + "3": "Taille de police", + "4": "Rotation (de 0 Ć  360 degrĆ©s)", + "5": "Width Spacer (espace entre chaque filigrane horizontalement)", + "6": "Height Spacer (espace entre chaque filigrane verticalement)", + "7": "OpacitĆ© (de 0% Ć  100%)", + "8": "Type de filigrane", + "9": "Image du filigrane", + "10": "Convertir le PDF en PDF-Image" + }, + "submit": "Ajouter un filigrane", + "type": { + "1": "Texte", + "2": "Image" + } + }, + "permissions": { + "tags": "permissions,lire,Ć©crire,modifier,imprimer,read,write,edit,print", + "title": "Modifier les permissions", + "header": "Modifier les permissions", + "warning": "Attention, pour que ces permissions soient immuables il est recommandĆ© de les paramĆ©trer avec un mot de passe via la page Ajouter un mot de passe.", + "selectText": { + "1": "SĆ©lectionnez le PDF", + "2": "Permissions Ć  dĆ©finir", + "3": "EmpĆŖcher l'assemblage du document", + "4": "EmpĆŖcher l'extraction de contenu", + "5": "EmpĆŖcher l'extraction pour l'accessibilitĆ©", + "6": "EmpĆŖcher de remplir les formulaires", + "7": "EmpĆŖcher la modification", + "8": "EmpĆŖcher la modification des annotations", + "9": "EmpĆŖcher l'impression", + "10": "EmpĆŖcher l'impression des diffĆ©rents formats" + }, + "submit": "Modifier" + }, + "removePages": { + "tags": "supprimer,remove,delete" + }, + "addPassword": { + "tags": "ajouter,sĆ©curitĆ©,mot de passe,secure,security", + "title": "Ajouter un mot de passe", + "header": "Ajouter un mot de passe", + "selectText": { + "1": "PDF Ć  chiffrer", + "2": "Mot de passe de l'utilisateur", + "3": "Longueur de la clĆ© de chiffrement", + "4": "Les valeurs plus Ć©levĆ©es sont plus fortes, mais les valeurs plus faibles ont une meilleure compatibilitĆ©.", + "5": "Autorisations Ć  dĆ©finir (utilisation recommandĆ©e avec le mot de passe du propriĆ©taire)", + "6": "EmpĆŖcher l'assemblage du document", + "7": "EmpĆŖcher l'extraction de contenu", + "8": "EmpĆŖcher l'extraction pour l'accessibilitĆ©", + "9": "EmpĆŖcher de remplir les formulaires", + "10": "EmpĆŖcher la modification", + "11": "EmpĆŖcher la modification des annotations", + "12": "EmpĆŖcher l'impression", + "13": "EmpĆŖcher l'impression des diffĆ©rents formats", + "14": "Mot de passe du propriĆ©taire", + "15": "Restreint ce qui peut ĆŖtre fait avec le document une fois qu'il est ouvert (non pris en charge par tous les lecteurs).", + "16": "Restreint l'ouverture du document lui-mĆŖme." + }, + "submit": "Chiffrer" + }, + "removePassword": { + "tags": "supprimer,sĆ©curitĆ©,mot de passe,secure,decrypt,security,unpassword,delete password", + "title": "Supprimer le mot de passe", + "header": "Supprimer le mot de passe", + "selectText": { + "1": "SĆ©lectionnez le PDF", + "2": "Mot de passe" + }, + "submit": "Supprimer" + }, + "compressPdfs": { + "tags": "compresser,rĆ©duire,taille,squish,small,tiny" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "mĆ©tadonnĆ©es,titre,auteur,date,crĆ©ation,heure,Ć©diteur,statistiques,title,author,date,creation,time,publisher,producer,stats,metadata", + "title": "Titre", + "header": "Modifier les mĆ©tadonnĆ©es", + "selectText": { + "1": "Veuillez modifier les variables que vous souhaitez modifier.", + "2": "Supprimer toutes les mĆ©tadonnĆ©es", + "3": "Afficher des mĆ©tadonnĆ©es personnalisĆ©es", + "4": "Autres mĆ©tadonnĆ©es", + "5": "Ajouter une entrĆ©e de mĆ©tadonnĆ©es personnalisĆ©e" + }, + "author": "Auteur", + "creationDate": "Date de crĆ©ation (yyyy/MM/dd HH:mm:ss)", + "creator": "CrĆ©ateur", + "keywords": "Mots clĆ©s", + "modDate": "Date de modification (yyyy/MM/dd HH:mm:ss)", + "producer": "Producteur", + "subject": "Sujet", + "trapped": "Recouvrement (technique d'impression)", + "submit": "Modifier" + }, + "fileToPDF": { + "tags": "convertion,transformation,format,document,image,slide,texte,conversion,office,docs,word,excel,powerpoint", + "title": "Fichier en PDF", + "header": "Convertir un fichier en PDF", + "credit": "Ce service utilise LibreOffice et Unoconv pour la conversion de fichiers.", + "supportedFileTypesInfo": "Types de fichiers pris en charge", + "supportedFileTypes": "Les types de fichiers pris en charge doivent inclure les Ć©lĆ©ments ci-dessous, mais pour une liste complĆØte et mise Ć  jour des formats pris en charge, veuillez vous reporter Ć  la documentation de LibreOffice.", + "submit": "Convertir" + }, + "ocr": { + "tags": "ocr,reconnaissance,texte,image,numĆ©risation,scan,read,identify,detection,editable", + "title": "OCR / Nettoyage des numĆ©risations", + "header": "OCR (Reconnaissance optique de caractĆØres) / Nettoyage des numĆ©risations", + "selectText": { + "1": "Langues Ć  dĆ©tecter dans le PDF (celles listĆ©es sont celles actuellement dĆ©tectĆ©es)", + "2": "Produire un fichier texte contenant le texte dĆ©tectĆ© Ć  cĆ“tĆ© du PDF", + "3": "Corriger les pages qui ont Ć©tĆ© numĆ©risĆ©es Ć  un angle oblique en les remettant en place", + "4": "Nettoyer la page afin qu'il soit moins probable que l'OCR trouve du texte dans le bruit de fond, sans modifier la sortie", + "5": "Nettoyer la page afin qu'il soit moins probable que l'OCR trouve du texte dans le bruit de fond, en modifiant la sortie", + "6": "Ignorer les pages contenant du texte interactif, n'analyser que les pages qui sont des images", + "7": "Forcer l'OCR, analyser chaque page et supprimer tous les Ć©lĆ©ments de texte d'origine", + "8": "Normal (gĆ©nĆØre une erreur si le PDF contient du texte)", + "9": "ParamĆØtres additionnels", + "10": "Mode OCR", + "11": "Supprimer les images aprĆØs l'OCR (Supprime TOUTES les images, utile uniquement si elles font partie de l'Ć©tape de conversion)", + "12": "Type de rendu (avancĆ©)" + }, + "help": "Veuillez lire cette documentation pour savoir comment utiliser l'OCR pour d'autres langues ou une utilisation hors DockerĀ :", + "credit": "Ce service utilise qpdf et Tesseract pour l'OCR.", + "submit": "Traiter" + }, + "extractImages": { + "tags": "image,photo,save,archive,zip,capture,grab", + "title": "Extraire les images", + "header": "Extraire les images", + "selectText": "Format d'image dans lequel convertir les images extraites", + "allowDuplicates": "Enregistrer les images dupliquĆ©es", + "submit": "Extraire" + }, + "pdfToPDFA": { + "tags": "convertion,archive,long-term,standard,conversion,storage,prĆ©servation,preservation", + "title": "PDF en PDF/A", + "header": "PDF en PDF/A", + "credit": "Ce service utilise libreoffice pour la conversion en PDF/A.", + "submit": "Convertir", + "tip": "Ne fonctionne actuellement pas pour plusieurs entrĆ©es Ć  la fois", + "outputFormat": "Format de sortie", + "pdfWithDigitalSignature": "Le PDF contient une signature numĆ©rique. Elle sera supprimĆ©e dans l'Ć©tape suivante." + }, + "PDFToWord": { + "tags": "doc, docx, odt, word, transformation, format, conversion, office, microsoft, docfile", + "title": "PDF en Word", + "header": "PDF en Word", + "selectText": { + "1": "Format du fichier de sortie" + }, + "credit": "Ce service utilise LibreOffice pour la conversion de fichiers.", + "submit": "Convertir" + }, + "PDFToPresentation": { + "tags": "prĆ©sentation,slides,show,office,microsoft", + "title": "PDF en formats de prĆ©sentation", + "header": "PDF en formats de prĆ©sentation", + "selectText": { + "1": "Format du fichier de sortie" + }, + "credit": "Ce service utilise LibreOffice pour la conversion de fichiers.", + "submit": "Convertir" + }, + "PDFToText": { + "tags": "format riche, format de texte riche, format de texte enrichi", + "title": "PDF en RTF (texte)", + "header": "PDF en RTF (texte)", + "selectText": { + "1": "Format du fichier de sortie" + }, + "credit": "Ce service utilise LibreOffice pour la conversion de fichiers.", + "submit": "Convertir" + }, + "PDFToHTML": { + "tags": "html,web content,browser friendly", + "title": "PDF en HTML", + "header": "PDF en HTML", + "credit": "Ce service utilise pdftohtml pour la conversion de fichiers.", + "submit": "Convertir" + }, + "PDFToXML": { + "tags": "xml,extraction de donnĆ©es,contenu structurĆ©,interopĆ©rabilitĆ©,data-extraction,structured-content,interop,transformation,convert", + "title": "PDF en XML", + "header": "PDF en XML", + "credit": "Ce service utilise LibreOffice pour la conversion de fichiers.", + "submit": "Convertir" + }, + "ScannerImageSplit": { + "tags": "diviser,dĆ©tecter automatiquement,numĆ©riser,separate,auto-detect,scans,multi-photo,organize", + "selectText": { + "1": "Seuil de rotation", + "2": "DĆ©finit l'angle absolu minimum requis pour la rotation de l'image (par dĆ©fautĀ : 10).", + "3": "TolĆ©rance", + "4": "DĆ©termine la plage de variation de couleur autour de la couleur d'arriĆØre-plan estimĆ©e (par dĆ©fautĀ : 20).", + "5": "Surface minimale", + "6": "DĆ©finit la surface minimale pour une photo (par dĆ©fautĀ : 8 000).", + "7": "Surface de contour minimale", + "8": "DĆ©finit la surface de contour minimale pour une photo (par dĆ©fautĀ : 500).", + "9": "Taille de la bordure", + "10": "DĆ©finit la taille de la bordure ajoutĆ©e et supprimĆ©e pour Ć©viter les bordures blanches dans la sortie (par dĆ©fautĀ : 1)." + }, + "info": "Python n'est pas installĆ©. Il est nĆ©cessaire pour le fonctionnement." + }, + "sign": { + "tags": "signer,authorize,initials,drawn-signature,text-sign,image-signature", + "title": "Signer", + "header": "Signer", + "upload": "TĆ©lĆ©charger une image", + "draw": "Dessiner une signature", + "text": "Saisir de texte", + "clear": "Effacer", + "add": "Ajouter", + "saved": "Sceaux enregistrĆ©es", + "save": "Enregistrer le sceau", + "personalSigs": "Sceaux personnels", + "sharedSigs": "Sceaux partagĆ©s", + "noSavedSigs": "Aucun sceau enregistrĆ© trouvĆ©", + "addToAll": "Ajouter Ć  toutes les pages", + "delete": "Supprimer", + "first": "PremiĆØre page", + "last": "DerniĆØre page", + "next": "Page suivante", + "previous": "Page prĆ©cĆ©dente", + "maintainRatio": "Conserver les proportions", + "undo": "DĆ©faire", + "redo": "Refaire" + }, + "flatten": { + "tags": "inerte,static,deactivate,non-interactive,streamline", + "title": "Rendre inerte", + "header": "Rendre inerte", + "flattenOnlyForms": "Aplatir uniquement les formulaires", + "submit": "Rendre inerte" + }, + "repair": { + "tags": "rĆ©parer,restaurer,corriger,rĆ©cupĆ©rer,fix,restore,correction,recover", + "title": "RĆ©parer", + "header": "RĆ©parer", + "submit": "RĆ©parer" + }, + "removeBlanks": { + "tags": "pages vierges,supprimer,nettoyer,cleanup,streamline,non-content,organize", + "title": "Supprimer les pages vierges", + "header": "Supprimer les pages vierges", + "threshold": "Seuil de blancheur des pixels", + "thresholdDesc": "Seuil pour dĆ©terminer Ć  quel point un pixel blanc doit ĆŖtre blanc pour ĆŖtre classĆ© comme « blancĀ Ā» (0 = noir, 255 = blanc pur).", + "whitePercent": "Pourcentage de blanc", + "whitePercentDesc": "Pourcentage de la page qui doit contenir des pixels Ā« blancs Ā» Ć  supprimer.", + "submit": "Supprimer les pages vierges" + }, + "removeAnnotations": { + "tags": "commentaires,supprimer,annotations,highlight,notes,markup,remove", + "title": "Supprimer les annotations", + "header": "Supprimer les annotations", + "submit": "Supprimer" + }, + "compare": { + "tags": "comparer,analyser,differentiate,contrast,changes,analysis", + "title": "Comparer", + "header": "Comparer", + "highlightColor": { + "1": "Couleur de mise en Ć©vidence 1 :", + "2": "Couleur de mise en Ć©vidence 2 :" + }, + "document": { + "1": "Document 1", + "2": "Document 2" + }, + "submit": "Comparer", + "complex": { + "message": "Un ou les deux documents fournis sont des fichiers volumineux, l'exactitude de la comparaison peut ĆŖtre rĆ©duite" + }, + "large": { + "file": { + "message": "Un ou les deux documents fournis sont trop volumineux pour ĆŖtre traitĆ©s" + } + }, + "no": { + "text": { + "message": "L'un ou les deux documents PDF sĆ©lectionnĆ©s ne contiennent aucun contenu textuel. Veuillez choisir des documents PDF avec du texte pour la comparaison." + } + } + }, + "certSign": { + "tags": "signer,chiffrer,certificat,authenticate,PEM,P12,official,encrypt", + "title": "Signer avec un certificat", + "header": "Signer avec un certificat (Travail en cours)", + "selectPDF": "PDF Ć  signer", + "jksNote": "Note: Si votre type de certificat n'est pas listĆ© ci-dessous, merci de le convertir en fichier Java Keystore (.jks) en utilisant l'outil en ligne de commande keytool. Puis choisissez l'option Fichier .jks ci-dessous.", + "selectKey": "Fichier de clĆ© privĆ©e (format PKCS#8, peut ĆŖtre .pem ou .der)", + "selectCert": "Fichier de certificat (format X.509, peut ĆŖtre .pem ou .der)", + "selectP12": "Fichier keystore de clĆ©s PKCS#12 (.p12 ou .pfx) (facultatif, s'il n'est fourni, il doit contenir votre clĆ© privĆ©e et votre certificat)", + "selectJKS": "SĆ©lectionner votre fichier Java Keystore File (.jks or .keystore):", + "certType": "Type de certificat", + "password": "Mot de passe keystore ou clĆ© privĆ©e le cas Ć©chĆ©ant", + "showSig": "Afficher la signature", + "reason": "Raison", + "location": "Emplacement", + "name": "Nom", + "showLogo": "Afficher le logo", + "submit": "Signer" + }, + "removeCertSign": { + "tags": "signer,chiffrer,certificat,authenticate,PEM,P12,official,decrypt", + "title": "Supprimer la Signature de Certificat", + "header": "Supprimer le certificat numĆ©rique du PDF", + "selectPDF": "SĆ©lectionnez un fichier PDF :", + "submit": "Supprimer la Signature" + }, + "pageLayout": { + "tags": "fusionner,merge,composite,single-view,organize", + "title": "Fusionner des pages", + "header": "Fusionner des pages", + "pagesPerSheet": "Pages par feuille", + "addBorder": "Ajouter des bordures", + "submit": "Fusionner" + }, + "scalePages": { + "tags": "ajuster,redimensionner,resize,modify,dimension,adapt", + "title": "Ajuster la taille ou l'Ć©chelle", + "header": "Ajuster la taille ou l'Ć©chelle", + "pageSize": "Taille d'une page du document", + "keepPageSize": "Taille d'origine", + "scaleFactor": "Niveau de zoom (recadrage) d'une page", + "submit": "Ajuster" + }, + "add-page-numbers": { + "tags": "paginer,numĆ©ros,Ć©tiqueter,paginate,label,organize,index" + }, + "auto-rename": { + "tags": "renommer,dĆ©tection automatique,rƩƩtiqueter,auto-detect,header-based,organize,relabel", + "title": "Renommer automatiquement", + "header": "Renommer automatiquement", + "submit": "Renommer automatiquement" + }, + "adjust-contrast": { + "tags": "ajuster,couleurs,amĆ©lioration,color-correction,tune,modify,enhance" + }, + "crop": { + "tags": "redimensionner,trim,shrink,edit,shape", + "title": "Redimensionner", + "header": "Redimensionner", + "submit": "Envoyer" + }, + "autoSplitPDF": { + "tags": "sĆ©parer,QR-based,separate,scan-segment,organize", + "title": "SĆ©parer automatiquement les pages", + "header": "SĆ©parer automatiquement les pages", + "description": "Imprimez, insĆ©rez, numĆ©risez, tĆ©lĆ©chargez et laissez-nous sĆ©parer automatiquement vos documents. Aucun travail de tri manuel nĆ©cessaire.", + "selectText": { + "1": "Imprimez des feuilles de sĆ©paration ci-dessous (le mode noir et blanc convient).", + "2": "NumĆ©risez tous vos documents en une seule fois en insĆ©rant les feuilles intercalaires entre eux.", + "3": "TĆ©lĆ©chargez le fichier PDF numĆ©risĆ© et laissez Stirling PDF s'occuper du reste.", + "4": "Les feuilles de sĆ©paration sont automatiquement dĆ©tectĆ©es et supprimĆ©es, garantissant un document final soignĆ©." + }, + "formPrompt": "PDF contenant des feuilles de sĆ©paration de Stirling PDFĀ :", + "duplexMode": "Mode recto-verso", + "dividerDownload2": "Auto Splitter Divider (with instructions).pdf", + "submit": "SĆ©parer" + }, + "sanitizePdf": { + "tags": "assainir,sĆ©curisĆ©,clean,secure,safe,remove-threats" + }, + "URLToPDF": { + "tags": "pdf,contenu Web,save-page,web-to-doc,archive", + "title": "URL en PDF", + "header": "URL en PDF", + "submit": "Convertir", + "credit": "Utilise WeasyPrint." + }, + "HTMLToPDF": { + "tags": "html,markup,contenu Web,transformation,convert", + "title": "HTML en PDF", + "header": "HTML en PDF", + "help": "Accepte les fichiers HTML et les ZIP contenant du HTML, du CSS, des images, etc. (requis).", + "submit": "Convertir", + "credit": "Utilise WeasyPrint.", + "zoom": "Niveau de zoom pour l'affichage du site web.", + "pageWidth": "Largeur de la page en centimĆØtres. (Vide par dĆ©faut)", + "pageHeight": "Hauteur de la page en centimĆØtres. (Vide par dĆ©faut)", + "marginTop": "Marge supĆ©rieure de la page en millimĆØtres. (Vide par dĆ©faut)", + "marginBottom": "Marge infĆ©rieure de la page en millimĆØtres. (Vide par dĆ©faut)", + "marginLeft": "Marge gauche de la page en millimĆØtres. (Vide par dĆ©faut)", + "marginRight": "Marge droite de la page en millimĆØtres. (Vide par dĆ©faut)", + "printBackground": "Restituer l'image de fond des sites web.", + "defaultHeader": "Activer l'entĆŖte par dĆ©faut (Nom et numĆ©ro de page)", + "cssMediaType": "Modifier le type de mĆ©dia CSS de la page.", + "none": "Aucun", + "print": "Imprimer", + "screen": "Ɖcran" + }, + "MarkdownToPDF": { + "tags": "markdown,markup,contenu Web,transformation,convert", + "title": "Markdown en PDF", + "header": "Markdown en PDF", + "submit": "Convertir", + "help": "(Travail en cours).", + "credit": "Utilise WeasyPrint." + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "rĆ©cupĆ©rer,infomation,data,stats,statistics", + "title": "RĆ©cupĆ©rer les informations", + "header": "RĆ©cupĆ©rer les informations", + "submit": "RĆ©cupĆ©rer les informations", + "downloadJson": "TĆ©lĆ©charger le JSON" + }, + "extractPage": { + "tags": "extraire,extract" + }, + "PdfToSinglePage": { + "tags": "fusionner,merge,une seule page,single page" + }, + "showJS": { + "tags": "JS", + "title": "Afficher le JavaScript", + "header": "Afficher le JavaScript", + "downloadJS": "TĆ©lĆ©charger le JavaScript", + "submit": "Afficher" + }, + "autoRedact": { + "tags": "caviarder,redact,auto,Masquer,noircir,noir,marqueur,cachĆ©,rĆ©diger,censurer", + "title": "Caviarder automatiquement", + "header": "Caviarder automatiquement", + "colorLabel": "Couleur", + "textsToRedactLabel": "Texte Ć  caviarder (sĆ©parĆ© par des lignes)", + "textsToRedactPlaceholder": "ex. \\nConfidentiel \\nTop secret", + "useRegexLabel": "Utiliser une Regex", + "wholeWordSearchLabel": "Recherche de mots entiers", + "customPaddingLabel": "Marge intĆ©rieure supplĆ©mentaire", + "convertPDFToImageLabel": "Convertir un PDF en PDF-Image (utilisĆ© pour supprimer le texte en arriĆØre-plan)", + "submitButton": "Caviarder" + }, + "redact": { + "tags": "Caviarder,Redact,Masquer,noircir,noir,marqueur,cachĆ©,rĆ©diger,censurer", + "title": "Caviardage manuel", + "header": "Caviardage manuel", + "submit": "Caviarder", + "textBasedRedaction": "Caviarder du texte", + "pageBasedRedaction": "Caviarder des pages", + "convertPDFToImageLabel": "Convertir en PDF-Image (pour supprimer le texte derriĆØre le rectangle)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(ex: 1,2,8 ou 4,7,12-16 ou 2n-1)" + }, + "redactionColor": { + "title": "Couleur" + }, + "export": "Exporter", + "upload": "TĆ©lĆ©verser", + "boxRedaction": "Tracer le rectangle Ć  caviarder", + "zoom": "Zoom", + "zoomIn": "Zoom avant", + "zoomOut": "Zoom arriĆØre", + "nextPage": "Page suivante", + "previousPage": "Page prĆ©cĆ©dente", + "toggleSidebar": "Montrer la barre latĆ©rale", + "showThumbnails": "Afficher les miniatures", + "showDocumentOutline": "Montrer les contours du document (double-click pour agrandir/rĆ©duire tous les Ć©lĆ©ments)", + "showAttatchments": "Montrer les Ć©lĆ©ments attachĆ©s", + "showLayers": "Montrer les calques (double-click pour rĆ©initialiser tous les calques Ć  l'Ć©tat par dĆ©faut)", + "colourPicker": "SĆ©lection de couleur", + "findCurrentOutlineItem": "Trouver l'Ć©lĆ©ment de contour courrant", + "applyChanges": "Appliquer les changements" + }, + "tableExtraxt": { + "tags": "CSV, Extraction de table, extraction, conversion" + }, + "autoSizeSplitPDF": { + "tags": "pdf, dĆ©coupage, document, organisation" + }, + "overlay-pdfs": { + "tags": "Overlay,incrustation", + "header": "Incrustation de PDF", + "baseFile": { + "label": "SĆ©lectionner le fichier PDF de base" + }, + "overlayFiles": { + "label": "SĆ©lectionner les fichiers PDF Ć  superposer" + }, + "mode": { + "label": "SĆ©lectionner le mode d'incrustation", + "sequential": "Superposition sĆ©quentielle", + "interleaved": "Superposition entrelacĆ©e", + "fixedRepeat": "Superposition Ć  rĆ©pĆ©tition fixe" + }, + "counts": { + "label": "Nombre de superpositions (pour le mode de rĆ©pĆ©tition fixe)", + "placeholder": "Compteurs (sĆ©parĆ©s par des virgules, exemple : 2,3,1)" + }, + "position": { + "label": "DĆ©finir la position de l'incrustation", + "foreground": "Premier plan", + "background": "ArriĆØre-plan" + }, + "submit": "Soumettre" + }, + "split-by-sections": { + "tags": "Sections,Diviser,Section Split, Divide, Customize", + "title": "Diviser le PDF en sections", + "header": "Diviser le PDF en sections", + "horizontal": { + "label": "Divisions horizontales", + "placeholder": "Saisir le nombre de divisions horizontales" + }, + "vertical": { + "label": "Divisions verticales", + "placeholder": "Entrer le nombre de divisions verticales" + }, + "submit": "Diviser le PDF", + "merge": "Fusionner en un seul PDF" + }, + "AddStampRequest": { + "tags": "Tampon,Ajouter,Stamp,Add image,center image,Watermark,PDF,Embed,Customize", + "header": "Tampon PDF", + "title": "Tampon PDF", + "stampType": "Type de tampon", + "stampText": "Tampon texte", + "stampImage": "Tampon image", + "alphabet": "Alphabet", + "fontSize": "Taille de fonte/image", + "rotation": "Rotation", + "opacity": "OpacitĆ©", + "position": "Position", + "overrideX": "DĆ©finir coordonnĆ©es X", + "overrideY": "DĆ©finir coordonnĆ©es Y", + "customMargin": "Marge personnalisĆ©e", + "customColor": "Couleur de texte personnalisĆ©e", + "submit": "Soumettre" + }, + "removeImagePdf": { + "tags": "Images,Remove Image,Page operations,Back end,server side" + }, + "splitPdfByChapters": { + "tags": "sĆ©parer,chapitres,split,chapters,bookmarks,organize" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Valider les signatures PDF", + "header": "Valider les signatures numĆ©riques", + "selectPDF": "SĆ©lectionnez un fichier PDF signĆ©", + "submit": "Valider les signatures", + "results": "RĆ©sultats de la validation", + "status": { + "_value": "Statut", + "valid": "Valide", + "invalid": "Invalide" + }, + "signer": "Signataire", + "date": "Date", + "reason": "Raison", + "location": "Localisation", + "noSignatures": "Aucune signature numĆ©rique trouvĆ©e dans ce document", + "chain": { + "invalid": "La validation de la chaĆ®ne de certificats a Ć©chouĆ© - impossible de vĆ©rifier l'identitĆ© du signataire" + }, + "trust": { + "invalid": "Le certificat n'est pas dans le magasin de confiance - la source ne peut pas ĆŖtre vĆ©rifiĆ©e" + }, + "cert": { + "expired": "Le certificat a expirĆ©", + "revoked": "Le certificat a Ć©tĆ© rĆ©voquĆ©", + "info": "DĆ©tails du certificat", + "issuer": "Ɖmetteur", + "subject": "Sujet", + "serialNumber": "NumĆ©ro de sĆ©rie", + "validFrom": "Valide Ć  partir du", + "validUntil": "Valide jusqu'au", + "algorithm": "Algorithme", + "keySize": "Taille de la clĆ©", + "version": "Version", + "keyUsage": "Usage de la clĆ©", + "selfSigned": "Auto-signĆ©", + "bits": "bits" + }, + "signature": { + "info": "Informations sur la signature", + "_value": "Signature", + "mathValid": "La signature est mathĆ©matiquement valide MAIS :" + }, + "selectCustomCert": "Fichier de certificat personnalisĆ© X.509 (Optionnel)" + }, + "replace-color": { + "title": "Remplacer-Inverser-Couleur", + "header": "Remplacer-Inverser Couleur PDF", + "selectText": { + "1": "Options de Remplacement ou d'Inversion de Couleur", + "2": "Par dĆ©faut (Couleurs Ć  fort contraste par dĆ©faut)", + "3": "PersonnalisĆ© (Couleurs personnalisĆ©es)", + "4": "Inversion complĆØte (Inverser toutes les couleurs)", + "5": "Options de couleur Ć  fort contraste", + "6": "Texte blanc sur fond noir", + "7": "Texte noir sur fond blanc", + "8": "Texte jaune sur fond noir", + "9": "Texte vert sur fond noir", + "10": "Choisir la couleur du texte", + "11": "Choisir la couleur de l'arriĆØre-plan" + }, + "submit": "Remplacer" + }, + "replaceColorPdf": { + "tags": "Remplacer Couleur,OpĆ©rations de Page,Back-end,CĆ“tĆ© serveur" + }, + "login": { + "title": "Connexion", + "header": "Connexion", + "signin": "Connexion", + "rememberme": "Se souvenir de moi", + "invalid": "Nom d'utilisateur ou mot de passe invalide.", + "locked": "Votre compte a Ć©tĆ© verrouillĆ©.", + "signinTitle": "Veuillez vous connecter", + "ssoSignIn": "Se connecter via l'authentification unique", + "oAuth2AutoCreateDisabled": "OAUTH2 CrĆ©ation automatique d'utilisateur dĆ©sactivĆ©e", + "oAuth2AdminBlockedUser": "La crĆ©ation ou l'authentification d'utilisateurs non enregistrĆ©s est actuellement bloquĆ©e. Veuillez contacter l'administrateur.", + "oauth2RequestNotFound": "Demande d'autorisation introuvable", + "oauth2InvalidUserInfoResponse": "RĆ©ponse contenant les informations de l'utilisateur est invalide", + "oauth2invalidRequest": "RequĆŖte invalide", + "oauth2AccessDenied": "AccĆØs refusĆ©", + "oauth2InvalidTokenResponse": "RĆ©ponse contenant le jeton est invalide", + "oauth2InvalidIdToken": "Jeton d'identification invalide", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "L'utilisateur est dĆ©sactivĆ©, la connexion est actuellement bloquĆ©e avec ce nom d'utilisateur. Veuillez contacter l'administrateur.", + "alreadyLoggedIn": "Vous ĆŖtes dĆ©jĆ  connectĆ© sur", + "alreadyLoggedIn2": "appareils. Veuillez vous dĆ©connecter des appareils et rĆ©essayer.", + "toManySessions": "Vous avez trop de sessions actives.", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "Fusionner les pages", + "header": "Fusionner les pages", + "submit": "Convertir en une seule page" + }, + "pageExtracter": { + "title": "Extraire des pages", + "header": "Extraire des pages", + "submit": "Extraire", + "placeholder": "(par exemple : 1,2,8 ou 4,7,12-16 ou 2n-1)" + }, + "sanitizePDF": { + "title": "Assainir", + "header": "Assainir", + "selectText": { + "1": "Supprimer les actions JavaScript", + "2": "Supprimer les fichiers intĆ©grĆ©s", + "3": "Remove XMP metadata", + "4": "Supprimer les liens", + "5": "Supprimer les polices", + "6": "Remove Document Info Metadata" + }, + "submit": "Assainir" + }, + "adjustContrast": { + "title": "Ajuster les couleurs", + "header": "Ajuster les couleurs", + "contrast": "Contraste", + "brightness": "LuminositĆ©", + "saturation": "Saturation", + "download": "TĆ©lĆ©charger" + }, + "compress": { + "title": "Compresser un PDF", + "header": "Compresser un PDF (lorsque c'est possible!)", + "credit": "Ce service utilise qpdf pour la compression et l'optimisation des PDF.", + "grayscale": { + "label": "Appliquer l'Ć©chelle de gris pour la compression" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Niveau d'optimisation", + "4": "Mode automatique – ajuste automatiquement la qualitĆ© pour obtenir le PDF Ć  la taille exacte", + "5": "Taille PDF attendue (par exemple, 25 MB, 10,8 MB, 25 KB)" + }, + "submit": "Compresser" + }, + "decrypt": { + "passwordPrompt": "Ce fichier est protĆ©gĆ© par un mot de passe. Veuillez saisir le mot de passe :", + "cancelled": "Operation annulĆ©e pour le PDF: {0}", + "noPassword": "Pas de mot de passe fourni pour le PDF chiffrĆ© : {0}", + "invalidPassword": "Veuillez rĆ©essayer avec le bon mot de passe", + "invalidPasswordHeader": "Mauvais mot de passe ou chiffrement non supportĆ© pour le PDF : {0}", + "unexpectedError": "Une erreur est survenue lors de traitement du fichier. Veuillez essayer de nouveau.", + "serverError": "Erreur du serveur lors du dĆ©chiffrement : {0}", + "success": "Fichier dĆ©chiffrĆ© avec succĆØs." + }, + "multiTool-advert": { + "message": "Cette fonctionnalitĆ© est aussi disponible dans la page de l'outil multifonction. Allez-y pour une interface page par page amĆ©liorĆ©e et des fonctionnalitĆ©s additionnelles !" + }, + "pageRemover": { + "title": "Supprimer des pages", + "header": "Supprimer des pages", + "pagesToDelete": "Pages Ć  supprimer (entrez une liste de numĆ©ros de pages sĆ©parĆ©s par des virgules)Ā :", + "submit": "Supprimer les pages", + "placeholder": "(par exemple 1,2,6 ou 1-10,15-30)" + }, + "imageToPDF": { + "title": "Image en PDF", + "header": "Image en PDF", + "submit": "Convertir", + "selectLabel": "Options d'ajustement de l'image", + "fillPage": "Remplir la page", + "fitDocumentToImage": "Ajuster la page Ć  l'image", + "maintainAspectRatio": "Maintenir les proportions", + "selectText": { + "2": "Rotation automatique du PDF", + "3": "Logique multi-fichiers (uniquement activĆ©e si vous travaillez avec plusieurs images)", + "4": "Fusionner en un seul PDF", + "5": "Convertir en PDF sĆ©parĆ©s" + } + }, + "PDFToCSV": { + "title": "PDF en CSV", + "header": "PDF en CSV", + "prompt": "Choisir la page pour en extraire le tableau", + "submit": "Extrait" + }, + "split-by-size-or-count": { + "title": "SĆ©parer le PDF par taille ou par nombre", + "header": "SĆ©parer le PDF par taille ou par nombre", + "type": { + "label": "SĆ©lectionner le type de division", + "size": "Par taille", + "pageCount": "Par nombre de pages", + "docCount": "Par nombre de documents" + }, + "value": { + "label": "Entrer la valeur", + "placeholder": "Saisir la taille (par exemple, 2MB ou 3KB) ou le nombre (par exemple, 5)" + }, + "submit": "SĆ©parer" + }, + "printFile": { + "title": "Imprimer le fichier", + "header": "Imprimer le fichier sur l'imprimante", + "selectText": { + "1": "SĆ©lectionner le fichier Ć  imprimer", + "2": "Entrez le nom de l'imprimante" + }, + "submit": "Imprimer" + }, + "licenses": { + "nav": "Licences", + "title": "Licences tierces", + "header": "Licences tierces", + "module": "Module", + "version": "Version", + "license": "Licence" + }, + "survey": { + "nav": "EnquĆŖte", + "title": "EnquĆŖte Stirling-PDF", + "description": "Stirling-PDF n'a pas de suivi, donc nous voulons entendre nos utilisateurs pour amĆ©liorer Stirling-PDF !", + "changes": "Stirling-PDF a changĆ© depuis la derniĆØre enquĆŖte ! Pour en savoir plus, veuillez consulter notre article de blog ici :", + "changes2": "Avec ces changements, nous obtenons un soutien commercial rĆ©munĆ©rĆ© et un financement", + "please": "Veuillez envisager de rĆ©pondre Ć  notre enquĆŖte !", + "disabled": "(La fenĆŖtre contextuelle de l'enquĆŖte sera dĆ©sactivĆ©e dans les mises Ć  jour suivantes mais sera disponible en bas de page)", + "button": "RĆ©pondre Ć  l'enquĆŖte", + "dontShowAgain": "Ne plus afficher", + "meeting": { + "1": "Si vous utilisez Stirling PDF au travail, nous aimerions en discuter avec vous. Nous offrons des sessions de support technique en Ć©chante d'une discussion de 15 minutes pour dĆ©couvrir nos utilisateurs.", + "2": "C'est l'occasion de :", + "3": "Obtenir de l'aide pour le dĆ©ploiement, l'intĆ©gration ou rĆ©soudre des problĆØmes", + "4": "Fournir un retour direct sur les performances, les cas limites, les fonctionnalitĆ©s demandĆ©es", + "5": "Nous aider Ć  adapter Stirling PDF aux usages rĆ©els en entreprise", + "6": "Si vous ĆŖtes intĆ©ressĆ©, prenez rendez-vous avec notre Ć©quipe (en anglias uniquement)", + "7": "Nous avons hĆ¢te de dĆ©couvrir vos cas d'usage et d'amĆ©liorer encore Stirling PDF !", + "notInterested": "Bous n'ĆŖtes pas une entreprise et/ou n'ĆŖtes pas intĆ©ressĆ© par une discussion ?", + "button": "Prendre rendez-vous" + } + }, + "removeImage": { + "title": "Supprimer l'image", + "header": "Supprimer l'image", + "removeImage": "Supprimer l'image", + "submit": "Supprimer l'image" + }, + "splitByChapters": { + "title": "Diviser un PDF par Chapitres", + "header": "Diviser un PDF par Chapitres", + "bookmarkLevel": "Niveau de Signet", + "includeMetadata": "Inclure les MĆ©tadonnĆ©es", + "allowDuplicates": "Autoriser les Doublons", + "desc": { + "1": "Cet outil divise un fichier PDF en plusieurs PDF en fonction de sa structure de chapitres.", + "2": "Niveau de Signet : Choisissez le niveau de signets Ć  utiliser pour la division (0 pour le niveau supĆ©rieur, 1 pour le deuxiĆØme niveau, etc...).", + "3": "Inclure les MĆ©tadonnĆ©es : Si cochĆ©, les mĆ©tadonnĆ©es du PDF original seront incluses dans chaque PDF divisĆ©.", + "4": "Autoriser les Doublons : Si cochĆ©, permet Ć  plusieurs signets sur la mĆŖme page de crĆ©er des PDF sĆ©parĆ©s." + }, + "submit": "Diviser le PDF" + }, + "fileChooser": { + "click": "Cliquez", + "or": "ou", + "dragAndDrop": "Glisser & DĆ©poser", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Glisser & DĆ©poser le(s) fichier(s) ici", + "extractPDF": "Extraction en cours..." + }, + "releases": { + "footer": "Versions", + "title": "Notes de version", + "header": "Notes de version", + "current": { + "version": "Version actuelle" + }, + "note": "Les notes de version sont uniquement disponibles en anglais" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/ga-IE/translation.json b/frontend/public/locales/ga-IE/translation.json new file mode 100644 index 000000000..917cd9bea --- /dev/null +++ b/frontend/public/locales/ga-IE/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "MĆ©id an Chló", + "fontName": "Ainm Cló", + "title": "Cuir Uimhreacha Leathanaigh leis", + "header": "Cuir Uimhreacha Leathanaigh leis", + "selectText": { + "1": "Roghnaigh comhad PDF:", + "2": "MĆ©id Imeall", + "3": "Post", + "4": "Uimhir Tosaigh", + "5": "Leathanaigh go hUimhir", + "6": "TĆ©acs Saincheaptha" + }, + "customTextDesc": "TĆ©acs Saincheaptha", + "numberPagesDesc": "CĆ© na leathanaigh le huimhriĆŗ, rĆ©amhshocraithe 'gach duine', a ghlacann freisin 1-5 nó 2,5,9 etc", + "customNumberDesc": "RĆ©amhshocrĆŗ go {n}, glacann sĆ© freisin le 'Leathanach {n} de {total}', 'Text-{n}', '{filename}-{n}", + "submit": "Cuir Uimhreacha Leathanaigh leis" + }, + "pdfPrompt": "Roghnaigh PDF(anna)", + "multiPdfPrompt": "Roghnaigh PDFs (2+)", + "multiPdfDropPrompt": "Roghnaigh (nó tarraing & scaoil) gach PDF atĆ” uait", + "imgPrompt": "Roghnaigh ƍomhĆ”(Ć­)", + "genericSubmit": "Cuir isteach", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Rabhadh: FĆ©adfaidh an próiseas seo suas le nóimĆ©ad a ghlacadh ag brath ar mhĆ©id an chomhaid", + "pageOrderPrompt": "OrdĆŗ Leathanach Saincheaptha (IontrĆ”il liosta uimhreacha leathanaigh nó Feidhmeanna ar nós 2n+1 le camóga deighilte):", + "pageSelectionPrompt": "RoghnĆŗ Leathanach Saincheaptha (IontrĆ”il liosta leathanach scartha le camóg d'uimhreacha 1,5,6 nó Feidhmeanna ar nós 2n+1):", + "goToPage": "TĆ©igh", + "true": "FĆ­or", + "false": "BrĆ©agach", + "unknown": "Anaithnid", + "save": "SĆ”bhĆ”il", + "saveToBrowser": "SĆ”bhĆ”il go BrabhsĆ”laĆ­", + "close": "DĆŗn", + "filesSelected": "comhaid roghnaithe", + "noFavourites": "NĆ­or cuireadh aon cheanĆ”in leis", + "downloadComplete": "ƍosluchtaigh CrĆ­ochnaithe", + "bored": "Leamh Ag Feitheamh?", + "alphabet": "AibĆ­tir", + "downloadPdf": "ƍoslódĆ”il PDF", + "text": "TĆ©acs", + "font": "Cló", + "selectFillter": "-- Roghnaigh --", + "pageNum": "Uimhir an Leathanaigh", + "sizes": { + "small": "Beaga", + "medium": "MheĆ”n", + "large": "Mór", + "x-large": "X-Mór" + }, + "error": { + "pdfPassword": "TĆ” pasfhocal ar an DoicimĆ©ad PDF agus nĆ­or solĆ”thraĆ­odh an pasfhocal nó bhĆ­ sĆ© mĆ­cheart", + "_value": "EarrĆ”id", + "sorry": "Gabh mo leithscĆ©al as an gceist!", + "needHelp": "Cabhair uait / Ar aimsĆ­odh fadhb?", + "contactTip": "MĆ” tĆ” trioblóid agat fós, nĆ” bĆ­odh leisce ort teagmhĆ”il a dhĆ©anamh linn le haghaidh cabhrach. Is fĆ©idir leat ticĆ©ad a chur isteach ar Ć”r leathanach GitHub nó dĆ©an teagmhĆ”il linn trĆ­ Discord:", + "404": { + "head": "404 - Leathanach Gan AimsiĆŗ | Úps, thuislĆ­omar sa chód!", + "1": "Is cosĆŗil nach fĆ©idir linn teacht ar an leathanach atĆ” uait.", + "2": "Chuaigh rud eigin mĆ­cheart" + }, + "github": "Cuir ticĆ©ad isteach ar GitHub", + "showStack": "TaispeĆ”in Stack Trace", + "copyStack": "CóipeĆ”il Stack Trace", + "githubSubmit": "GitHub - Cuir ticĆ©ad isteach", + "discordSubmit": "Discord - Cuir post TacaĆ­ochta" + }, + "delete": "Scrios", + "username": "Ainm ĆŗsĆ”ideora", + "password": "Pasfhocal", + "welcome": "FĆ”ilte", + "property": "Maoin", + "black": "Dubh", + "white": "BĆ”n", + "red": "Dearg", + "green": "Glas", + "blue": "Gorm", + "custom": "Saincheaptha...", + "WorkInProgess": "Obair idir lĆ”mha, B’fhĆ©idir nach n-oibreoidh sĆ­ nó nach mbeidh bugaĆ­ ann, Tuairiscigh aon fhadhbanna le do thoil!", + "poweredBy": "Cumhachtaithe ag", + "yes": "TĆ”", + "no": "NĆ­l", + "changedCredsMessage": "DintiĆŗir athraithe!", + "notAuthenticatedMessage": "ÚsĆ”ideoir gan fĆ­ordheimhniĆŗ.", + "userNotFoundMessage": "ÚsĆ”ideoir gan aimsiĆŗ.", + "incorrectPasswordMessage": "TĆ” an pasfhocal reatha mĆ­cheart.", + "usernameExistsMessage": "TĆ” Ainm ÚsĆ”ideora Nua ann cheana fĆ©in.", + "invalidUsernameMessage": "Ainm ĆŗsĆ”ideora neamhbhailĆ­, nĆ­ fĆ©idir ach litreacha, uimhreacha agus na carachtair speisialta seo a leanas @._+- a bheith san ainm ĆŗsĆ”ideora nó nĆ­ mór gur seoladh rĆ­omhphoist bailĆ­ Ć©.", + "invalidPasswordMessage": "NĆ­or cheart go mbeadh an pasfhocal folamh agus nĆ­or cheart go mbeadh spĆ”sanna ag an tĆŗs nó ag an deireadh.", + "confirmPasswordErrorMessage": "NĆ­ mór Pasfhocal Nua agus Deimhnigh Pasfhocal Nua a bheith ag teacht leis.", + "deleteCurrentUserMessage": "NĆ­ fĆ©idir an t-ĆŗsĆ”ideoir atĆ” logĆ”ilte isteach faoi lĆ”thair a scriosadh.", + "deleteUsernameExistsMessage": "NĆ­l an t-ainm ĆŗsĆ”ideora ann agus nĆ­ fĆ©idir Ć© a scriosadh.", + "downgradeCurrentUserMessage": "NĆ­ fĆ©idir ról an ĆŗsĆ”ideora reatha a Ć­osghrĆ”dĆŗ", + "disabledCurrentUserMessage": "NĆ­ fĆ©idir an t-ĆŗsĆ”ideoir reatha a dhĆ­chumasĆŗ", + "downgradeCurrentUserLongMessage": "NĆ­ fĆ©idir ról an ĆŗsĆ”ideora reatha a Ć­osghrĆ”dĆŗ. Mar sin, nĆ­ thaispeĆ”nfar an t-ĆŗsĆ”ideoir reatha.", + "userAlreadyExistsOAuthMessage": "TĆ” an t-ĆŗsĆ”ideoir ann cheana mar ĆŗsĆ”ideoir OAuth2.", + "userAlreadyExistsWebMessage": "TĆ” an t-ĆŗsĆ”ideoir ann cheana fĆ©in mar ĆŗsĆ”ideoir grĆ©asĆ”in.", + "oops": "Úps!", + "help": "CabhrĆŗ", + "goHomepage": "TĆ©igh go Leathanach Baile", + "joinDiscord": "ClĆ”raigh lenĆ”r bhfreastalaĆ­ Discord", + "seeDockerHub": "FĆ©ach Docker Hub", + "visitGithub": "Tabhair cuairt ar Github Stór", + "donate": "SĆ­ntiĆŗis", + "color": "Dath", + "sponsor": "Urraitheoir", + "info": "Eolas", + "pro": "Pro", + "page": "Leathanach", + "pages": "Leathanaigh", + "loading": "Ɓ lódĆ”il...", + "addToDoc": "Cuir le DoicimĆ©ad", + "reset": "Athshocraigh", + "apply": "Cuir i bhFeidhm", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "PolasaĆ­ PrĆ­obhĆ”ideachta", + "terms": "TĆ©armaĆ­ agus CoinnĆ­ollacha", + "accessibility": "Inrochtaineacht", + "cookie": "PolasaĆ­ FianĆ”n", + "impressum": "Impressum", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "RoghchlĆ”r PĆ­blĆ­ne (Beta)", + "uploadButton": "UaslódĆ”il Saincheaptha", + "configureButton": "Cumraigh", + "defaultOption": "Saincheaptha", + "submitButton": "Cuir isteach", + "help": "Cabhair PĆ­blĆ­ne", + "scanHelp": "Cabhair Scanadh FillteĆ”n", + "deletePrompt": "An bhfuil tĆŗ cinnte gur mhaith leat pĆ­blĆ­ne a scriosadh", + "tags": "uathoibriĆŗ, seicheamh, scriptithe, baisc-phróiseas", + "title": "PĆ­blĆ­ne" + }, + "pipelineOptions": { + "header": "CumraĆ­ocht PĆ­blĆ­ne", + "pipelineNameLabel": "Ainm PĆ­blĆ­ne", + "saveSettings": "SĆ”bhĆ”il Socruithe OibriĆŗchĆ”in", + "pipelineNamePrompt": "Cuir isteach ainm na pĆ­blĆ­ne anseo", + "selectOperation": "Roghnaigh OibrĆ­ocht", + "addOperationButton": "Cuir oibrĆ­ocht leis", + "pipelineHeader": "PĆ­blĆ­ne:", + "saveButton": "ƍosluchtaigh", + "validateButton": "BailĆ­ochtaigh" + }, + "enterpriseEdition": { + "button": "UasghrĆ”dĆŗ go Pro", + "warning": "NĆ­l an ghnĆ© seo ar fĆ”il ach d'ĆŗsĆ”ideoirĆ­ Pro.", + "yamlAdvert": "TacaĆ­onn Stirling PDF Pro le comhaid cumraĆ­ochta YAML agus gnĆ©ithe SSO eile.", + "ssoAdvert": "TĆ” tuilleadh gnĆ©ithe bainistĆ­ochta ĆŗsĆ”ideoirĆ­ Ć” lorg? SeiceĆ”il Stirling PDF Pro" + }, + "analytics": { + "title": "An bhfuil fonn ort PDF Stirling a fheabhsĆŗ?", + "paragraph1": "TĆ” rogha an diĆŗltaithe ag PDF Stirling chun cabhrĆŗ linn an tĆ”irge a fheabhsĆŗ. NĆ­ rianaimid aon fhaisnĆ©is phearsanta nó Ć”bhar comhaid.", + "paragraph2": "Smaoinigh le do thoil ar anailĆ­sĆ­ocht a chumasĆŗ chun cabhrĆŗ le Stirling-PDF fĆ”s agus chun ligean dĆŗinn Ć”r n-ĆŗsĆ”ideoirĆ­ a thuiscint nĆ­os fearr.", + "enable": "Cumasaigh anailĆ­sĆ­ocht", + "disable": "DĆ­chumasaigh anailĆ­sĆ­ocht", + "settings": "Is fĆ©idir leat na socruithe don anailĆ­sĆ­ocht a athrĆŗ sa chomhad config/settings.yml" + }, + "navbar": { + "favorite": "CeanĆ”in", + "recent": "New and recently updated", + "darkmode": "Mód Dorcha", + "language": "Teangacha", + "settings": "Socruithe", + "allTools": "UirlisĆ­", + "multiTool": "UirlisĆ­ Il", + "search": "Cuardach", + "sections": { + "organize": "Eagraigh", + "convertTo": "Tiontaigh go PDF", + "convertFrom": "Tiontaigh ó PDF", + "security": "Comhartha & SlĆ”ndĆ”il", + "advance": "Casta", + "edit": "FĆ©ach ar & Cuir in Eagar", + "popular": "Coitianta" + } + }, + "settings": { + "title": "Socruithe", + "update": "NuashonrĆŗ ar fĆ”il", + "updateAvailable": "Is Ć© {0} an leagan suiteĆ”ilte reatha. TĆ” leagan nua ({1}) ar fĆ”il.", + "appVersion": "Leagan Aipe:", + "downloadOption": { + "title": "Roghnaigh rogha Ć­oslódĆ”la (Le haghaidh Ć­oslódĆ”lacha comhad amhĆ”in seachas zip):", + "1": "Oscail sa bhfuinneog chĆ©anna", + "2": "Oscail i bhfuinneog nua", + "3": "ƍoslódĆ”il an comhad" + }, + "zipThreshold": "Comhaid zip nuair a shĆ”raĆ­onn lĆ­on na gcomhad Ć­oslódĆ”la", + "signOut": "LogĆ”il Amach", + "accountSettings": "Socruithe cuntas", + "bored": { + "help": "CumasaĆ­onn sĆ© cluiche uibheacha CĆ”sca" + }, + "cacheInputs": { + "name": "SĆ”bhĆ”il ionchuir fhoirm", + "help": "Cumasaigh ionchuir a ĆŗsĆ”ideadh roimhe seo a stórĆ”il le haghaidh ritheanna amach anseo" + } + }, + "changeCreds": { + "title": "Athraigh DintiĆŗir", + "header": "Nuashonraigh SonraĆ­ do Chuntais", + "changePassword": "TĆ” dintiĆŗir rĆ©amhshocraithe logĆ”il isteach Ć” ĆŗsĆ”id agat. Cuir isteach pasfhocal nua le do thoil", + "newUsername": "Ainm ÚsĆ”ideora Nua", + "oldPassword": "Pasfhocal reatha", + "newPassword": "Focal Faire Nua", + "confirmNewPassword": "Deimhnigh Pasfhocal Nua", + "submit": "Cuir Athruithe isteach" + }, + "account": { + "title": "Socruithe cuntas", + "accountSettings": "Socruithe cuntas", + "adminSettings": "Socruithe RiarachĆ”in - FĆ©ach ar agus Cuir ÚsĆ”ideoirĆ­ Leis", + "userControlSettings": "Socruithe Rialaithe ÚsĆ”ideora", + "changeUsername": "Athraigh Ainm ÚsĆ”ideora", + "newUsername": "Ainm ÚsĆ”ideora Nua", + "password": "Pasfhocal Deimhnithe", + "oldPassword": "Sean Pasfhocal", + "newPassword": "Focal Faire Nua", + "changePassword": "Athraigh do phasfhocal", + "confirmNewPassword": "Deimhnigh Pasfhocal Nua", + "signOut": "LogĆ”il Amach", + "yourApiKey": "D'Eochair API", + "syncTitle": "Sioncronaigh socruithe brabhsĆ”laĆ­ leis an gCuntas", + "settingsCompare": "ComparĆ”id Socruithe:", + "property": "Maoin", + "webBrowserSettings": "SocrĆŗ BrabhsĆ”laĆ­ GrĆ©asĆ”in", + "syncToBrowser": "Cuntas Sync -> BrabhsĆ”laĆ­", + "syncToAccount": "Cuntas Sioncronaigh <- BrabhsĆ”laĆ­" + }, + "adminUserSettings": { + "title": "Socruithe Rialaithe ÚsĆ”ideora", + "header": "Socruithe Rialaithe ÚsĆ”ideoir RiarachĆ”in", + "admin": "RiarachĆ”n", + "user": "ÚsĆ”ideoir", + "addUser": "Cuir ÚsĆ”ideoir Nua leis", + "deleteUser": "Scrios ÚsĆ”ideoir", + "confirmDeleteUser": "Ar cheart an t-ĆŗsĆ”ideoir a scriosadh?", + "confirmChangeUserStatus": "Ar cheart an t-ĆŗsĆ”ideoir a dhĆ­chumasĆŗ/a chumasĆŗ?", + "usernameInfo": "NĆ­ fĆ©idir ach litreacha, uimhreacha agus na carachtair speisialta seo a leanas @._+- a bheith san ainm ĆŗsĆ”ideora nó nĆ­ mór gur seoladh rĆ­omhphoist bailĆ­ Ć©.", + "roles": "Róil", + "role": "Ról", + "actions": "GnĆ­omhartha", + "apiUser": "ÚsĆ”ideoir API Teoranta", + "extraApiUser": "ÚsĆ”ideoir API Teoranta breise", + "webOnlyUser": "ÚsĆ”ideoir GrĆ©asĆ”in AmhĆ”in", + "demoUser": "ÚsĆ”ideoir TaispeĆ”na (Gan socruithe saincheaptha)", + "internalApiUser": "ÚsĆ”ideoir API InmheĆ”nach", + "forceChange": "Cuir iallach ar an ĆŗsĆ”ideoir pasfhocal a athrĆŗ ar logĆ”il isteach", + "submit": "SĆ”bhĆ”il ÚsĆ”ideoir", + "changeUserRole": "Athraigh Ról an ÚsĆ”ideora", + "authenticated": "FĆ­ordheimhnithe", + "editOwnProfil": "Cuir a phróifĆ­l fĆ©in in eagar", + "enabledUser": "ĆŗsĆ”ideoir cumasaithe", + "disabledUser": "ĆŗsĆ”ideoir faoi mhĆ­chumas", + "activeUsers": "ÚsĆ”ideoirĆ­ GnĆ­omhacha:", + "disabledUsers": "ÚsĆ”ideoirĆ­ faoi mhĆ­chumas:", + "totalUsers": "ÚsĆ”ideoirĆ­ IomlĆ”n:", + "lastRequest": "Iarratas Deiridh", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "IompórtĆ”il/EaspórtĆ”il Bunachar SonraĆ­", + "header": "IompórtĆ”il/EaspórtĆ”il Bunachar SonraĆ­", + "fileName": "Ainm comhaid", + "creationDate": "DĆ”ta Cruthaithe", + "fileSize": "MĆ©id an Chomhaid", + "deleteBackupFile": "Scrios Comhad CĆŗltaca", + "importBackupFile": "IompórtĆ”il Comhad CĆŗltaca", + "createBackupFile": "Cruthaigh Comhad CĆŗltaca", + "downloadBackupFile": "ƍoslódĆ”il an comhad cĆŗltaca", + "info_1": "Agus sonraĆ­ Ć” n-allmhairiĆŗ, tĆ” sĆ© rĆ­thĆ”bhachtach an struchtĆŗr ceart a chinntiĆŗ. Mura bhfuil tĆŗ cinnte faoina bhfuil ar siĆŗl agat, iarr comhairle agus tacaĆ­ocht ó ghairmĆ­. FĆ©adfaidh earrĆ”id sa struchtĆŗr a bheith ina chĆŗis le mĆ­fheidhmeanna iarratais, suas go dtĆ­ agus lena n-Ć”irĆ­tear an neamhĆ”baltacht iomlĆ”n an t-iarratas a rith.", + "info_2": "NĆ­ hionann ainm an chomhaid agus Ć© Ć” uaslódĆ”il. DĆ©anfar Ć© a athainmniĆŗ ina dhiaidh sin chun an fhormĆ”id backup_user_yyyyMMddHHmm.sql a leanĆŗint, ag cinntiĆŗ go bhfuil coinbhinsiĆŗn ainmniĆŗchĆ”in comhsheasmhach ann.", + "submit": "IompórtĆ”il CĆŗltaca", + "importIntoDatabaseSuccessed": "D'Ć©irigh leis an allmhairiĆŗ isteach sa bhunachar sonraĆ­", + "backupCreated": "D'Ć©irigh le cĆŗltaca bunachar sonraĆ­", + "fileNotFound": "Comhad gan aimsiĆŗ", + "fileNullOrEmpty": "NĆ­or cheart go mbeadh an comhad ar neamhnĆ­ nó folamh", + "failedImportFile": "Theip ar iompórtĆ”il an chomhaid", + "notSupported": "NĆ­l an fheidhm seo ar fĆ”il do nasc bunachar sonraĆ­." + }, + "session": { + "expired": "TĆ” do sheisiĆŗn imithe in Ć©ag. Athnuaigh an leathanach agus bain triail eile as.", + "refreshPage": "Athnuaigh an Leathanach" + }, + "home": { + "desc": "Do shiopa ilfhreastail arna óstĆ”il go hĆ”itiĆŗil do do riachtanais PDF go lĆ©ir.", + "searchBar": "Cuardaigh gnĆ©ithe...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "FĆ©ach ar, nótĆ”il, cuir tĆ©acs nó Ć­omhĆ”nna leis" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "Il-uirlis PDF", + "desc": "Cumaisc, Rothlaigh, Atheagraigh, agus Bain leathanaigh" + }, + "merge": { + "title": "Cumaisc", + "desc": "Go hĆ©asca chumasadh go leor PDFanna isteach i gceann amhĆ”in." + }, + "split": { + "title": "Scoilt", + "desc": "Scoilt comhaid PDF isteach i ndoicimĆ©id iolracha" + }, + "rotate": { + "title": "Rothlaigh", + "desc": "Rothlaigh do PDFanna go hĆ©asca." + }, + "imageToPdf": { + "title": "ƍomhĆ” go PDF", + "desc": "Tiontaigh Ć­omhĆ” (PNG, JPEG, GIF) go PDF." + }, + "pdfToImage": { + "title": "PDF go Ć­omhĆ”", + "desc": "Tiontaigh PDF a Ć­omhĆ”. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Eagraigh", + "desc": "Bain/Atheagraigh na leathanaigh in ord ar bith" + }, + "addImage": { + "title": "Cuir Ć­omhĆ” leis", + "desc": "Cuireann sĆ© Ć­omhĆ” ar shuĆ­omh socraithe ar an PDF" + }, + "watermark": { + "title": "Cuir Uisce leis", + "desc": "Cuir comhartha uisce saincheaptha le do dhoicimĆ©ad PDF." + }, + "permissions": { + "title": "AthrĆŗ Ceadanna", + "desc": "Athraigh ceadanna do dhoicimĆ©ad PDF" + }, + "removePages": { + "title": "Bain", + "desc": "Scrios leathanaigh nach dteastaĆ­onn ó do dhoicimĆ©ad PDF." + }, + "addPassword": { + "title": "Cuir Pasfhocal leis", + "desc": "Criptigh do dhoicimĆ©ad PDF le focal faire." + }, + "removePassword": { + "title": "Bain Pasfhocal", + "desc": "Bain cosaint phasfhocal ó do dhoicimĆ©ad PDF." + }, + "compressPdfs": { + "title": "ComhbhrĆŗigh", + "desc": "ComhbhrĆŗigh PDFanna chun a mĆ©id comhaid a laghdĆŗ." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Athraigh MeiteashonraĆ­", + "desc": "Athraigh/Bain/Cuir meiteashonraĆ­ ó dhoicimĆ©ad PDF" + }, + "fileToPDF": { + "title": "Comhad a thiontĆŗ go PDF", + "desc": "Tiontaigh beagnach aon chomhad go PDF (DOCX, PNG, XLS, PPT, TXT agus go leor eile)" + }, + "ocr": { + "title": "OCR / Scananna glanta", + "desc": "Scanann glantachĆ”n agus aimsĆ­onn sĆ© tĆ©acs ó Ć­omhĆ”nna laistigh de PDF agus cuireann sĆ© isteach arĆ­s Ć© mar thĆ©acs." + }, + "extractImages": { + "title": "Sliocht ƍomhĆ”nna", + "desc": "Sliochtann sĆ© gach Ć­omhĆ” ó PDF agus sĆ”bhĆ”lann sĆ© iad a zip" + }, + "pdfToPDFA": { + "title": "PDF go PDF/A", + "desc": "Tiontaigh PDF go PDF/A le haghaidh stórĆ”la fadtĆ©armach" + }, + "PDFToWord": { + "title": "PDF a thiontĆŗ go Word", + "desc": "Tiontaigh PDF go formĆ”idĆ­ Word (DOC, DOCX agus ODT)" + }, + "PDFToPresentation": { + "title": "PDF a chur i lĆ”thair", + "desc": "Tiontaigh PDF go formĆ”idĆ­ LĆ©irithe (PPT, PPTX agus ODP)" + }, + "PDFToText": { + "title": "PDF go RTF (TĆ©acs)", + "desc": "Tiontaigh PDF go TĆ©acs nó formĆ”id RTF" + }, + "PDFToHTML": { + "title": "PDF go HTML", + "desc": "Tiontaigh HTML i bhformĆ”id PDF" + }, + "PDFToXML": { + "title": "PDF go XML", + "desc": "Tiontaigh PDF i bhformĆ”id XML" + }, + "ScannerImageSplit": { + "title": "Braith / Scoilt grianghraif Scanta", + "desc": "Scoilteann sĆ© grianghraif iolracha ó laistigh de ghrianghraf/PDF" + }, + "sign": { + "title": "Comhartha", + "desc": "Cuireann sĆ­niĆŗ le PDF trĆ­ lĆ­nĆ­ocht, tĆ©acs nó Ć­omhĆ”" + }, + "flatten": { + "title": "Comhcheangail", + "desc": "Bain gach eilimint agus foirm idirghnĆ­omhach as PDF" + }, + "repair": { + "title": "DeisiĆŗchĆ”n", + "desc": "DĆ©anann sĆ© iarracht PDF truaillithe/briste a dheisiĆŗ" + }, + "removeBlanks": { + "title": "Bain leathanaigh BhĆ”na", + "desc": "AimsĆ­onn agus baintear leathanaigh bhĆ”na de dhoicimĆ©ad" + }, + "removeAnnotations": { + "title": "Bain AnótĆ”lacha", + "desc": "Baintear gach trĆ”cht/nóta de PDF" + }, + "compare": { + "title": "DĆ©an comparĆ”id idir", + "desc": "DĆ©anann sĆ© na difrĆ­ochtaĆ­ idir 2 DhoicimĆ©ad PDF a chur i gcomparĆ”id agus a thaispeĆ”int" + }, + "certSign": { + "title": "SĆ­nigh le DeimhniĆŗ", + "desc": "SĆ­nĆ­onn sĆ© PDF le DeimhniĆŗ/Eochair (PEM/P12)" + }, + "removeCertSign": { + "title": "Bain Comhartha Teastais", + "desc": "Bain sĆ­niĆŗ teastas ó PDF" + }, + "pageLayout": { + "title": "Leagan Amach Illeathanaigh", + "desc": "Cumaisc leathanaigh iolracha de dhoicimĆ©ad PDF isteach i leathanach amhĆ”in" + }, + "scalePages": { + "title": "Coigeartaigh mĆ©id/scĆ”la an leathanaigh", + "desc": "Athraigh mĆ©id/scĆ”la leathanaigh agus/nó a bhfuil ann." + }, + "pipeline": { + "title": "PĆ­blĆ­ne (ArdleibhĆ©al)", + "desc": "Rith gnĆ­omhartha iolracha ar PDFanna trĆ­ scripteanna pĆ­blĆ­ne a shainiĆŗ" + }, + "add-page-numbers": { + "title": "Cuir Uimhreacha Leathanaigh leis", + "desc": "Cuir uimhreacha Leathanach leis an doicimĆ©ad i suĆ­omh socraithe" + }, + "auto-rename": { + "title": "Comhad PDF a athainmniĆŗ go huathoibrĆ­och", + "desc": "AthainmnĆ­onn Auto comhad PDF bunaithe ar a cheanntĆ”sc braite" + }, + "adjust-contrast": { + "title": "Coigeartaigh Dathanna/Codarsnacht", + "desc": "Coigeartaigh Codarsnacht, SĆ”ithiĆŗ agus Gile PDF" + }, + "crop": { + "title": "PDF a ghearradh", + "desc": "Bearr PDF chun a mhĆ©id a laghdĆŗ (coimeĆ”dann an tĆ©acs!)" + }, + "autoSplitPDF": { + "title": "Leathanaigh Scoilte UathoibrĆ­och", + "desc": "Auto Scoilt PDF Scanta le Cód QR scoilteoir leathanach scanadh fisiciĆŗil" + }, + "sanitizePdf": { + "title": "SlĆ”intĆ­ocht", + "desc": "Bain scripteanna agus gnĆ©ithe eile ó chomhaid PDF" + }, + "URLToPDF": { + "title": "URL/LĆ”ithreĆ”n GrĆ©asĆ”in go PDF", + "desc": "TiontaĆ­onn aon http(s) URL go PDF" + }, + "HTMLToPDF": { + "title": "HTML go PDF", + "desc": "TiontaĆ­onn aon chomhad HTML nó zip go PDF" + }, + "MarkdownToPDF": { + "title": "MarcĆ”il sĆ­os go PDF", + "desc": "TiontaĆ­onn aon chomhad Markdown go PDF" + }, + "PDFToMarkdown": { + "title": "PDF chuig Markdown", + "desc": "TiontaĆ­onn PDF ar bith go Markdown" + }, + "getPdfInfo": { + "title": "Faigh GACH Eolas ar PDF", + "desc": "Grab aon fhaisnĆ©is agus is fĆ©idir ar PDFs" + }, + "extractPage": { + "title": "Sliocht leathanach(eacha)", + "desc": "Sleachta roghnaigh leathanaigh ó PDF" + }, + "PdfToSinglePage": { + "title": "PDF go leathanach mór amhĆ”in", + "desc": "Cumasc gach leathanach PDF isteach i leathanach mór amhĆ”in" + }, + "showJS": { + "title": "TaispeĆ”in Javascript", + "desc": "DĆ©anann sĆ© cuardach agus taispeĆ”int ar aon JS a instealladh isteach i PDF" + }, + "autoRedact": { + "title": "Auto Redact", + "desc": "Auto Redacts (Blacks out) tĆ©acs i PDF bunaithe ar an tĆ©acs ionchuir" + }, + "redact": { + "title": "AthchóiriĆŗ de LĆ”imh", + "desc": "RĆ©iteann sĆ© PDF bunaithe ar thĆ©acs roghnaithe, cruthanna tarraingthe agus/nó leathanaigh roghnaithe" + }, + "tableExtraxt": { + "title": "Ɠ CSV go PDF", + "desc": "Sleachta TĆ”blaĆ­ ó PDF agus Ć© a thiontĆŗ go CSV" + }, + "autoSizeSplitPDF": { + "title": "Auto Scoilte de rĆ©ir MĆ©id/Comhaireamh", + "desc": "Scoilt PDF amhĆ”in i ndoicimĆ©id iolracha bunaithe ar mhĆ©id, lĆ­on na leathanach, nó comhaireamh doicimĆ©ad" + }, + "overlay-pdfs": { + "title": "Forleagan PDF", + "desc": "Forleagain PDF ar bharr PDF eile" + }, + "split-by-sections": { + "title": "Scoilt PDF de rĆ©ir ailt", + "desc": "Roinn gach leathanach de PDF i gcodanna cothromĆ”nacha agus ingearacha nĆ­os lĆŗ" + }, + "AddStampRequest": { + "title": "Cuir Stampa go PDF", + "desc": "Cuir tĆ©acs leis nó cuir stampaĆ­ Ć­omhĆ” leis ag lĆ”ithreacha socraithe" + }, + "removeImagePdf": { + "title": "Bain Ć­omhĆ”", + "desc": "Bain Ć­omhĆ” de PDF chun mĆ©id comhaid a laghdĆŗ" + }, + "splitPdfByChapters": { + "title": "Scoil PDF ar ChaibidlĆ­", + "desc": "Scoilt PDF ina chomhaid iolracha bunaithe ar a struchtĆŗr caibidle." + }, + "validateSignature": { + "title": "BailĆ­ochtaigh SĆ­niĆŗ PDF", + "desc": "FĆ­oraigh sĆ­nithe digiteacha agus teastais i gcĆ”ipĆ©isĆ­ PDF" + }, + "replaceColorPdf": { + "title": "Athchuir agus InbhĆ©artaigh Dath", + "desc": "Athchuir dath an tĆ©acs agus an chĆŗlra i bhformĆ”id PDF agus inbhĆ©artaigh dath iomlĆ”n pdf chun mĆ©id comhaid a laghdĆŗ" + } + }, + "viewPdf": { + "tags": "amharc, lĆ©amh, anótĆ”il, tĆ©acs, Ć­omhĆ”", + "title": "View/Edit PDF", + "header": "FĆ©ach PDF" + }, + "multiTool": { + "tags": "Il-Uirlis, IloibrĆ­ocht, ChomhĆ©adain, cliceĆ”il tarraing, ceann tosaigh, taobh an chliaint, idirghnĆ­omhach, intractable, bog", + "title": "Il-uirlis PDF", + "header": "Il-uirlis PDF", + "uploadPrompts": "Ainm comhaid", + "selectAll": "Roghnaigh Uile", + "deselectAll": "DĆ­roghnaigh Uile", + "selectPages": "Roghnaigh Leathanach", + "selectedPages": "Leathanaigh Roghnaithe", + "page": "Leathanach", + "deleteSelected": "Scrios Roghnaithe", + "downloadAll": "EaspórtĆ”il", + "downloadSelected": "EaspórtĆ”il Roghnaithe", + "insertPageBreak": "IonsĆ”igh Sos Leathanaigh", + "addFile": "Cuir Comhad Leis", + "rotateLeft": "Rothlaigh ar ChlĆ©", + "rotateRight": "Rothlaigh ar Dheis", + "split": "Scoil", + "moveLeft": "Bog ar ChlĆ©", + "moveRight": "Bog ar Dheis", + "delete": "Scrios", + "dragDropMessage": "Leathanach(leathanaigh) roghnaithe", + "undo": "Cealaigh", + "redo": "AthdhĆ©an" + }, + "merge": { + "tags": "chumasadh,OibrĆ­ochtaĆ­ Leathanaigh,CĆŗl-deireadh,taobh freastalaĆ­", + "title": "Cumaisc", + "header": "Cumaisc PDFanna iolracha (2+)", + "sortByName": "SórtĆ”il de rĆ©ir ainm", + "sortByDate": "SórtĆ”il de rĆ©ir dĆ”ta", + "removeCertSign": "Bain sĆ­niĆŗ digiteach sa chomhad cumaiscthe?", + "submit": "Cumaisc" + }, + "split": { + "tags": "OibrĆ­ochtaĆ­ leathanach, roinnt, Leathanach Il, gearrtha, taobh freastalaĆ­", + "title": "Scoilt PDF", + "header": "Scoilt PDF", + "desc": { + "1": "Is iad na huimhreacha a roghnaĆ­onn tĆŗ an uimhir leathanaigh ar mian leat scoilt a dhĆ©anamh air", + "2": "DĆ” bhrĆ­ sin, dĆ” roghnófaĆ­ 1,3,7-9, roinnfĆ­ doicimĆ©ad 10 leathanach ina 6 PDF ar leith le:", + "3": "DoicimĆ©ad #1: Leathanach 1", + "4": "DoicimĆ©ad #2: Leathanach 2 agus 3", + "5": "DoicimĆ©ad #3: Leathanach 4, 5, 6 agus 7", + "6": "DoicimĆ©ad #4: Leathanach 8", + "7": "DoicimĆ©ad #5: Leathanach 9", + "8": "DoicimĆ©ad #6: Leathanach 10" + }, + "splitPages": "IontrĆ”il leathanaigh le scoilt ar:", + "submit": "Scoilt" + }, + "rotate": { + "tags": "taobh freastalaĆ­", + "title": "Rothlaigh PDF", + "header": "Rothlaigh PDF", + "selectAngle": "Roghnaigh uillinn rothlaithe (i iolraĆ­ de 90 cĆ©im):", + "submit": "Rothlaigh" + }, + "imageToPdf": { + "tags": "comhshó, img, jpg, pictiĆŗr, grianghraf" + }, + "pdfToImage": { + "tags": "comhshó, img, jpg, pictiĆŗr, grianghraf", + "title": "PDF go Ć­omhĆ”", + "header": "PDF go Ć­omhĆ”", + "selectText": "FormĆ”id ƍomhĆ”", + "singleOrMultiple": "CineĆ”l toraidh Leathanach go hƍomhĆ”", + "single": "Mhór Aonair a ChomhcheanglaĆ­onn gach leathanach", + "multi": "IlĆ­omhĆ”nna, Ć­omhĆ” amhĆ”in in aghaidh an leathanaigh", + "colorType": "CineĆ”l dath", + "color": "Dath", + "grey": "ScĆ”la Liath", + "blackwhite": "Dubh agus BĆ”n (D’fhĆ©adfadh sonraĆ­ a chailleadh!)", + "submit": "Tiontaigh", + "info": "NĆ­l Python suiteĆ”ilte. Ag teastĆ”il le haghaidh comhshó WebP.", + "placeholder": "(m.sh. 1,2,8 nó 4,7,12-16 nó 2n-1)" + }, + "pdfOrganiser": { + "tags": "dĆ©phlĆ©acsacha, cothrom, corr, sórtĆ”il, bogadh", + "title": "Eagraigh Leathanach", + "header": "EagraĆ­ leathanach PDF", + "submit": "AthshocrĆŗ Leathanaigh", + "mode": { + "_value": "Mód", + "1": "OrdĆŗ Leathanach Saincheaptha", + "2": "OrdĆŗ Droim ar Ais", + "3": "SórtĆ”il Duplex", + "4": "SórtĆ”il LeabhrĆ”n", + "5": "SórtĆ”il LeabhrĆ”n Stitch Taobh", + "6": "Scoilt Corr-FiĆŗ", + "7": "Bain Ar dtĆŗs", + "8": "Bain Last", + "9": "Bain An ChĆ©ad agus an Deireadh", + "10": "Corr-FiĆŗ Cumaisc", + "11": "Duplicate all pages" + }, + "placeholder": "(m.sh. 1,3,2 nó 4-8,2,10-12 nó 2n-1)" + }, + "addImage": { + "tags": "img, jpg, pictiĆŗr, grianghraf", + "title": "Cuir ƍomhĆ” leis", + "header": "Cuir Ć­omhĆ” i bhformĆ”id PDF", + "everyPage": "Gach Leathanach?", + "upload": "Cuir Ć­omhĆ” leis", + "submit": "Cuir Ć­omhĆ” leis" + }, + "watermark": { + "tags": "TĆ©acs, athrĆ”, lipĆ©ad, ĆŗinĆ©ireacht, cóipcheart, trĆ”dmharc, img, jpg, pictiĆŗr, grianghraf", + "title": "Cuir Uisce leis", + "header": "Cuir Uisce leis", + "customColor": "Dath TĆ©acs Saincheaptha", + "selectText": { + "1": "Roghnaigh PDF chun comhartha uisce a chur leis:", + "2": "TĆ©acs Comhartha Uisce:", + "3": "MĆ©id cló:", + "4": "RothlĆŗ (0-360):", + "5": "SpĆ”saire Leithead (SpĆ”s idir gach comhartha uisce go cothromĆ”nach):", + "6": "SpĆ”saire Airde (SpĆ”s idir gach comhartha uisce go hingearach):", + "7": "Teimhneacht (0% - 100%):", + "8": "CineĆ”l Comhartha Uisce:", + "9": "ƍomhĆ” Comhartha Uisce:", + "10": "Tiontaigh PDF go PDF-ƍomhĆ”" + }, + "submit": "Cuir Uisce leis", + "type": { + "1": "TĆ©acs", + "2": "ƍomha" + } + }, + "permissions": { + "tags": "lĆ©amh, scrĆ­obh, cuir in eagar, priontĆ”il", + "title": "AthrĆŗ Ceadanna", + "header": "AthrĆŗ Ceadanna", + "warning": "MĆ” thugtar rabhadh nach fĆ©idir na ceadanna seo a athrĆŗ, moltar pasfhocal a shocrĆŗ dóibh trĆ­ leathanach an bhreiseĆ”in phasfhocal", + "selectText": { + "1": "Roghnaigh PDF chun ceadanna a athrĆŗ", + "2": "Ceadanna a shocrĆŗ", + "3": "Cosc a chur le chĆ©ile doicimĆ©ad", + "4": "Cosc a chur ar eastóscadh Ć”bhar", + "5": "Cosc a chur ar eastóscadh le haghaidh inrochtaineachta", + "6": "Cosc ar fhoirm a lĆ­onadh", + "7": "Cosc a chur ar mhodhnĆŗ", + "8": "Cosc a chur ar mhodhnĆŗ anótĆ”la", + "9": "Cosc a chur ar phriontĆ”il", + "10": "Cosc a chur ar phriontĆ”il bhformĆ”idĆ­ Ć©agsĆŗla" + }, + "submit": "AthrĆŗ" + }, + "removePages": { + "tags": "Bain leathanaigh, scrios leathanaigh" + }, + "addPassword": { + "tags": "slĆ”n, slĆ”ndĆ”il", + "title": "Cuir Pasfhocal leis", + "header": "Cuir pasfhocal leis (Criptigh)", + "selectText": { + "1": "Roghnaigh PDF le criptiĆŗ", + "2": "Pasfhocal ÚsĆ”ideora", + "3": "Fad Eochracha Criptithe", + "4": "TĆ” luachanna nĆ­os airde nĆ­os lĆ”idre, ach tĆ” comhoiriĆŗnacht nĆ­os fearr ag luachanna nĆ­os Ć­sle.", + "5": "Ceadanna le socrĆŗ (Moltar iad a ĆŗsĆ”id in Ć©ineacht le pasfhocal an ÚinĆ©ara)", + "6": "Cosc a chur le chĆ©ile doicimĆ©ad", + "7": "Cosc a chur ar eastóscadh Ć”bhar", + "8": "Cosc a chur ar eastóscadh le haghaidh inrochtaineachta", + "9": "Cosc ar fhoirm a lĆ­onadh", + "10": "Cosc a chur ar mhodhnĆŗ", + "11": "Cosc a chur ar mhodhnĆŗ anótĆ”la", + "12": "Cosc a chur ar phriontĆ”il", + "13": "Cosc a chur ar phriontĆ”il bhformĆ”idĆ­ Ć©agsĆŗla", + "14": "Pasfhocal ÚinĆ©ir", + "15": "Cuireann sĆ© srian lenar fĆ©idir a dhĆ©anamh leis an doicimĆ©ad nuair a osclaĆ­tear Ć© (NĆ­ thacaĆ­onn gach lĆ©itheoir leis)", + "16": "Cuireann sĆ© srian le hoscailt an doicimĆ©id fĆ©in" + }, + "submit": "Criptigh" + }, + "removePassword": { + "tags": "slĆ”n, DĆ­chriptiĆŗ, slĆ”ndĆ”il, Unpassword, scrios pasfhocal", + "title": "Bain pasfhocal", + "header": "Bain pasfhocal (DĆ­chriptigh)", + "selectText": { + "1": "Roghnaigh PDF le DĆ­chriptiĆŗ", + "2": "Pasfhocal" + }, + "submit": "Bain" + }, + "compressPdfs": { + "tags": "squish, beag, beag bĆ­deach" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Teideal,Ćŗdar, dĆ”ta, cruthĆŗ, am, foilsitheoir, lĆ©iritheoir, staitisticĆ­", + "title": "Athraigh MeiteashonraĆ­", + "header": "Athraigh MeiteashonraĆ­", + "selectText": { + "1": "Cuir na hathróga is mian leat a athrĆŗ in eagar", + "2": "Scrios na meiteashonraĆ­ go lĆ©ir", + "3": "TaispeĆ”in MeiteashonraĆ­ Saincheaptha:", + "4": "MeiteashonraĆ­ Eile:", + "5": "Cuir IontrĆ”il MeiteashonraĆ­ Saincheaptha leis" + }, + "author": "Údar:", + "creationDate": "DĆ”ta Cruthaithe (bbbb/MM/ll HH:mm:ss):", + "creator": "Cruthaitheoir:", + "keywords": "Eochairfhocail:", + "modDate": "DĆ”ta Mionathraithe (bbbb/MM/ll HH:mm:ss):", + "producer": "lĆ©iritheoir:", + "subject": "Ɓbhar:", + "trapped": "Gafa:", + "submit": "AthrĆŗ" + }, + "fileToPDF": { + "tags": "claochlĆŗ, formĆ”id, doicimĆ©ad, pictiĆŗr, sleamhnĆ”n, tĆ©acs, comhshó, oifig, docs, focal, excel, powerpoint", + "title": "Comhad go PDF", + "header": "Tiontaigh aon chomhad go PDF", + "credit": "ÚsĆ”ideann an tseirbhĆ­s seo LibreOffice agus Unoconv chun comhaid a thiontĆŗ.", + "supportedFileTypesInfo": "CineĆ”lacha Comhaid Tacaithe", + "supportedFileTypes": "Ba cheart go n-Ć”ireofaĆ­ na cineĆ”lacha comhaid a dtacaĆ­tear leo thĆ­os, Ć”fach, le haghaidh liosta nuashonraithe iomlĆ”n de na formĆ”idĆ­ a dtacaĆ­tear leo, fĆ©ach le do thoil ar dhoicimĆ©adĆŗ LibreOffice", + "submit": "Tiontaigh go PDF" + }, + "ocr": { + "tags": "aithint, tĆ©acs, Ć­omhĆ”, scanadh, lĆ©amh, a aithint, a bhrath, in eagar", + "title": "OCR / Glanta Scan", + "header": "Scananna Glanta / OCR (Aithint OptĆŗil Carachtair)", + "selectText": { + "1": "Roghnaigh teangacha atĆ” le brath laistigh den PDF (Is iad na cinn a liostaĆ­tear na cinn a aimsĆ­tear faoi lĆ”thair):", + "2": "Comhad tĆ©acs a thĆ”irgeadh ina bhfuil tĆ©acs OCR taobh leis an PDF a cuireadh le OCR", + "3": "Scanadh leathanaigh chearta ag uillinn sceabhach trĆ­na rothlĆŗ ar ais ina n-Ć”it", + "4": "Glan an leathanach ionas gur lĆŗ an seans go bhfaighidh OCR tĆ©acs i torann cĆŗlra. (Gan athrĆŗ aschuir)", + "5": "Glan an leathanach ionas gur lĆŗ an seans go bhfaighidh OCR tĆ©acs le torann cĆŗlra, go gcoimeĆ”dann sĆ© glantachĆ”n san aschur.", + "6": "DĆ©anann sĆ© neamhaird ar leathanaigh a bhfuil tĆ©acs idirghnĆ­omhach orthu, agus ar leathanaigh OCR amhĆ”in ar Ć­omhĆ”nna iad", + "7": "Fórsa OCR, bainfidh OCR Gach leathanach ag baint na buneilimintĆ­ tĆ©acs uile", + "8": "GnĆ”th (Tharla earrĆ”id mĆ” tĆ” tĆ©acs sa PDF)", + "9": "Socruithe Breise", + "10": "Mód OCR", + "11": "Bain Ć­omhĆ”nna tar Ć©is OCR (Bain GACH Ć­omhĆ”, nĆ­ ĆŗsĆ”ideach ach amhĆ”in mĆ” tĆ” siad mar chuid den chĆ©im tiontaithe)", + "12": "CineĆ”l RindreĆ”la (ArdleibhĆ©al)" + }, + "help": "LĆ©igh le do thoil an doicimĆ©adĆŗ seo ar conas Ć© seo a ĆŗsĆ”id do theangacha eile agus/nó ĆŗsĆ”id nach bhfuil i ndugairĆ­", + "credit": "ÚsĆ”ideann an tseirbhĆ­s seo qpdf agus Tesseract le haghaidh OCR.", + "submit": "PróiseĆ”il PDF le OCR" + }, + "extractImages": { + "tags": "pictiĆŗr, grianghraf, shĆ”bhĆ”il, cartlann, zip, gabhĆ”il, grab", + "title": "Sliocht ƍomhĆ”nna", + "header": "Sliocht ƍomhĆ”nna", + "selectText": "Roghnaigh formĆ”id Ć­omhĆ” chun Ć­omhĆ”nna bainte a thiontĆŗ go", + "allowDuplicates": "SĆ”bhĆ”il Ć­omhĆ”nna dĆŗblacha", + "submit": "Sliocht" + }, + "pdfToPDFA": { + "tags": "cartlann, fadtĆ©armach, caighdeĆ”nach, comhshó, stórĆ”il, caomhnĆŗ", + "title": "PDF Go PDF/A", + "header": "PDF Go PDF/A", + "credit": "ÚsĆ”ideann an tseirbhĆ­s seo libreoffice chun PDF/A a thiontĆŗ", + "submit": "Tiontaigh", + "tip": "Faoi lĆ”thair nĆ­ oibrĆ­onn sĆ© le haghaidh ionchuir iolracha ag an am cĆ©anna", + "outputFormat": "FormĆ”id aschuir", + "pdfWithDigitalSignature": "TĆ” sĆ­niĆŗ digiteach ar an PDF. Bainfear Ć© seo sa chĆ©ad chĆ©im eile." + }, + "PDFToWord": { + "tags": "doc, docx, odt, focal, claochlĆŗ, formĆ”id, comhshó, oifig, microsoft, docfile", + "title": "PDF a thiontĆŗ go word", + "header": "PDF a thiontĆŗ go word", + "selectText": { + "1": "FormĆ”id comhaid aschuir" + }, + "credit": "ÚsĆ”ideann an tseirbhĆ­s seo LibreOffice chun comhaid a thiontĆŗ.", + "submit": "Tiontaigh" + }, + "PDFToPresentation": { + "tags": "sleamhnĆ”in, seó, oifig, microsoft", + "title": "PDF a chur i lĆ”thair", + "header": "PDF a chur i lĆ”thair", + "selectText": { + "1": "FormĆ”id comhaid aschuir" + }, + "credit": "ÚsĆ”ideann an tseirbhĆ­s seo LibreOffice chun comhaid a thiontĆŗ.", + "submit": "Tiontaigh" + }, + "PDFToText": { + "tags": "richformat, richtextformat, formĆ”id tĆ©acs saibhir", + "title": "PDF go RTF (TĆ©acs)", + "header": "PDF go RTF (TĆ©acs)", + "selectText": { + "1": "FormĆ”id comhaid aschuir" + }, + "credit": "ÚsĆ”ideann an tseirbhĆ­s seo LibreOffice chun comhaid a thiontĆŗ.", + "submit": "Tiontaigh" + }, + "PDFToHTML": { + "tags": "Ć”bhar grĆ©asĆ”in, cairdiĆŗil don bhrabhsĆ”laĆ­", + "title": "Ɠ HTML go PDF", + "header": "Ɠ HTML go PDF", + "credit": "ÚsĆ”ideann an tseirbhĆ­s seo PDF go html chun comhaid a thiontĆŗ.", + "submit": "Tiontaigh" + }, + "PDFToXML": { + "tags": "asbhaint sonraĆ­, Ć”bhar struchtĆŗrtha, idirghabhĆ”la, claochlĆŗ, thiontĆŗ", + "title": "Ɠ XML go PDF", + "header": "Ɠ XML go PDF", + "credit": "ÚsĆ”ideann an tseirbhĆ­s seo LibreOffice chun comhaid a thiontĆŗ.", + "submit": "Tiontaigh" + }, + "ScannerImageSplit": { + "tags": "ar leithligh, a bhrath go huathoibrĆ­och, scanadh, il-grianghraf, eagrĆŗ", + "selectText": { + "1": "Tairseach Uillinn:", + "2": "SocraĆ­onn sĆ© an uillinn iomlĆ”n Ć­osta a theastaĆ­onn chun an Ć­omhĆ” a rothlĆŗ (rĆ©amhshocraithe: 10).", + "3": "Caoinfhulaingt:", + "4": "Cinneann an raon Ć©agsĆŗlachta dath timpeall an dath cĆŗlra measta (rĆ©amhshocraithe: 30).", + "5": "Achar ƍosta:", + "6": "SocraĆ­onn sĆ© an tairseach achair Ć­osta le haghaidh grianghraf (rĆ©amhshocraithe: 10000).", + "7": "ƍos-LimistĆ©ar Comhrianta:", + "8": "SocraĆ­onn sĆ© an tairseach Ć­osta achar comhrianta le haghaidh grianghraf", + "9": "MĆ©id na Teorann:", + "10": "SocraĆ­onn sĆ© mĆ©id na teorann a chuirtear leis agus a bhaintear chun teorainneacha bĆ”n a chosc san aschur (rĆ©amhshocraithe: 1)." + }, + "info": "NĆ­l Python suiteĆ”ilte. TĆ” sĆ© ag teastĆ”il a rith." + }, + "sign": { + "tags": "ĆŗdarĆŗ, tosaigh, sĆ­niĆŗ tarraingthe, comhartha tĆ©acs, Ć­omhĆ”-shĆ­niĆŗ", + "title": "Comhartha", + "header": "SĆ­nigh comhaid PDF", + "upload": "UaslódĆ”il ƍomhĆ”", + "draw": "Tarraing SĆ­niĆŗ", + "text": "Ionchur TĆ©acs", + "clear": "Glan", + "add": "Cuir", + "saved": "SĆ­nithe SĆ­nithe", + "save": "SĆ”bhĆ”il an SĆ­niĆŗ", + "personalSigs": "SĆ­nithe Pearsanta", + "sharedSigs": "SĆ­nithe Roinnte", + "noSavedSigs": "NĆ­or aimsĆ­odh aon sĆ­niĆŗ sĆ”bhĆ”ilte", + "addToAll": "Cuir le gach leathanach", + "delete": "Scrios", + "first": "An chĆ©ad leathanach", + "last": "An leathanach deiridh", + "next": "An chĆ©ad leathanach eile", + "previous": "Leathanach roimhe seo", + "maintainRatio": "ScorĆ”naigh, coinnigh an cóimheas gnĆ©", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "statach, dĆ­ghnĆ­omhachtĆŗ, neamh-idirghnĆ­omhach, sruthlĆ­niĆŗ", + "title": "Flatten", + "header": "PDF cothromĆŗ", + "flattenOnlyForms": "Flatten foirmeacha amhĆ”in", + "submit": "Flatten" + }, + "repair": { + "tags": "deisiĆŗ, athchóiriĆŗ, ceartĆŗ, aisghabhĆ”il", + "title": "DeisiĆŗchĆ”n", + "header": "PDF a dheisiĆŗ", + "submit": "DeisiĆŗchĆ”n" + }, + "removeBlanks": { + "tags": "glanta, sruthlĆ­niĆŗ, neamhĆ”bhar, eagrĆŗ", + "title": "Bain BearnaĆ­", + "header": "Bain Leathanaigh BhĆ”na", + "threshold": "Tairseach BĆ”nachta picteilĆ­nĆ­:", + "thresholdDesc": "An tairseach chun a chinneadh cĆ© chomh bĆ”n is gĆ” picteilĆ­n bĆ”n a bheith le rangĆŗ mar 'BĆ”n'. 0", + "whitePercent": "CĆ©atadĆ”n BĆ”n (%):", + "whitePercentDesc": "CĆ©atadĆ”n an leathanaigh a chaithfidh picteilĆ­nĆ­ 'bĆ”n' a bheith ann lena bhaint", + "submit": "Bain BearnaĆ­" + }, + "removeAnnotations": { + "tags": "tuairimĆ­, aibhsiĆŗ, nótaĆ­, marcĆ”il, bain", + "title": "Bain AnótĆ”lacha", + "header": "Bain AnótĆ”lacha", + "submit": "Bain" + }, + "compare": { + "tags": "idirdhealĆŗ, codarsnacht, athruithe, anailĆ­s", + "title": "DĆ©an comparĆ”id idir", + "header": "DĆ©an comparĆ”id idir comhaid PDF", + "highlightColor": { + "1": "Dath Aibhsithe 1:", + "2": "Dath Aibhsithe 2:" + }, + "document": { + "1": "DoicimĆ©ad 1", + "2": "DoicimĆ©ad 2" + }, + "submit": "DĆ©an comparĆ”id idir", + "complex": { + "message": "Is comhaid mhóra ceann amhĆ”in nó an dĆ” cheann de na doicimĆ©id a solĆ”thraĆ­odh, d'fhĆ©adfaĆ­ cruinneas na comparĆ”ide a laghdĆŗ" + }, + "large": { + "file": { + "message": "TĆ” ceann amhĆ”in de na doicimĆ©id nó an dĆ” cheann rómhór le próiseĆ”il" + } + }, + "no": { + "text": { + "message": "NĆ­l aon Ć”bhar tĆ©acs i gceann amhĆ”in nó sa dĆ” cheann de na PDF roghnaithe. Roghnaigh PDF le do thoil le tĆ©acs chun comparĆ”id a dhĆ©anamh." + } + } + }, + "certSign": { + "tags": "fĆ­ordheimhnigh, PEM, P12, oifigiĆŗil, criptigh", + "title": "SĆ­niĆŗ Teastais", + "header": "SĆ­nigh PDF le do theastas (Obair ar siĆŗl)", + "selectPDF": "Roghnaigh Comhad PDF le sĆ­niĆŗ:", + "jksNote": "Nóta: Mura bhfuil do chineĆ”l teastais liostaithe thĆ­os, le do thoil Ć© a thiontĆŗ go comhad Java Keystore (.jks) ag baint ĆŗsĆ”ide as an uirlis lĆ­ne ordaithe keytool. Ansin, roghnaigh an rogha comhad .jks thĆ­os.", + "selectKey": "Roghnaigh Do Chomhad Eochracha PrĆ­obhĆ”idĆ­ (FormĆ”id PKCS#8, b'fhĆ©idir .pem nó .der):", + "selectCert": "Roghnaigh Do Chomhad Teastais (formĆ”id X.509, d'fhĆ©adfadh sĆ© a bheith .pem nó .der):", + "selectP12": "Roghnaigh Do Chomhad Siopa Eochracha PKCS#12 (.p12 nó .pfx) (Roghnach, MĆ” chuirtear ar fĆ”il Ć©, ba cheart go mbeadh d'eochair phrĆ­obhĆ”ideach agus teastas ann):", + "selectJKS": "Roghnaigh Do Chomhad Keystore Java (.jks nó .keystore):", + "certType": "CineĆ”l Teastais", + "password": "Cuir isteach do Phasfhocal Stórais Eochracha nó Eochracha PrĆ­obhĆ”idĆ­ (mĆ”s ann dó):", + "showSig": "TaispeĆ”in SĆ­niĆŗ", + "reason": "CĆŗis", + "location": "SuĆ­omh", + "name": "Ainm", + "showLogo": "TaispeĆ”in Lógó", + "submit": "SĆ­nigh PDF" + }, + "removeCertSign": { + "tags": "fĆ­ordheimhnigh, PEM, P12, oifigiĆŗil, dhĆ­chriptiĆŗ", + "title": "Bain SĆ­niĆŗ Teastais", + "header": "Bain an deimhniĆŗ digiteach ó PDF", + "selectPDF": "Roghnaigh comhad PDF:", + "submit": "Bain SĆ­niĆŗ" + }, + "pageLayout": { + "tags": "chumasc, ilchodach, aon-amharc, a eagrĆŗ", + "title": "Leagan Amach Illeathanaigh", + "header": "Leagan Amach Illeathanaigh", + "pagesPerSheet": "Leathanaigh in aghaidh na bileoige:", + "addBorder": "Cuir Teorainneacha leis", + "submit": "Cuir isteach" + }, + "scalePages": { + "tags": "athraigh, modhnaigh, toise, cuir in oiriĆŗint", + "title": "Coigeartaigh scĆ”la an leathanaigh", + "header": "Coigeartaigh scĆ”la an leathanaigh", + "pageSize": "MĆ©id leathanach den doicimĆ©ad.", + "keepPageSize": "MĆ©id Bunaidh", + "scaleFactor": "LeibhĆ©al sĆŗmĆ”il (barr) de leathanach.", + "submit": "Cuir isteach" + }, + "add-page-numbers": { + "tags": "leathanach, lipĆ©ad, eagraigh, innĆ©acs" + }, + "auto-rename": { + "tags": "auto-bhrath, ceanntĆ”sc-bhunaithe, a eagrĆŗ, a athlipĆ©adĆŗ", + "title": "Athainmnigh Uathainm", + "header": "Auto Athainmnigh PDF", + "submit": "Athainmnigh Uathainm" + }, + "adjust-contrast": { + "tags": "dath-cheartĆŗ, tune, a mhodhnĆŗ, a fheabhsĆŗ" + }, + "crop": { + "tags": "Baile Ɓtha Troim, Laghdaigh, Cuir in eagar, Cruth", + "title": "BarraĆ­", + "header": "PDF a ghearradh", + "submit": "Cuir isteach" + }, + "autoSplitPDF": { + "tags": "QR-bhunaithe, ar leith, scanadh-deighleog, eagrĆŗ", + "title": "Auto Scoilt PDF", + "header": "Auto Scoilt PDF", + "description": "PriontĆ”il, IonsĆ”igh, Scan, uaslódĆ”il, agus lig dĆŗinn do dhoicimĆ©id a scaradh go huathoibrĆ­och. NĆ­l gĆ” le sórtĆ”il obair lĆ”imhe.", + "selectText": { + "1": "PriontĆ”il roinnt bileoga roinnteoirĆ­ thĆ­os (tĆ” dubh agus bĆ”n go breĆ”).", + "2": "Scan do dhoicimĆ©id go lĆ©ir ag an am cĆ©anna trĆ­d an leathĆ”n roinnteora a chur isteach eatarthu.", + "3": "UaslódĆ”il an comhad PDF mór scanta amhĆ”in agus lig do Stirling PDF an chuid eile a lĆ”imhseĆ”il.", + "4": "DĆ©antar leathanaigh roinnteoirĆ­ a bhrath agus a bhaint go huathoibrĆ­och, rud a rĆ”thaĆ­onn doicimĆ©ad deiridh nĆ©ata." + }, + "formPrompt": "Cuir PDF isteach ina bhfuil roinnteoirĆ­ Leathanaigh Stirling-PDF:", + "duplexMode": "Mód Duplex (scanadh tosaigh agus cĆŗil)", + "dividerDownload2": "ƍoslódĆ”il 'Auto Splitter Divider (le treoracha).pdf'", + "submit": "Cuir isteach" + }, + "sanitizePdf": { + "tags": "glan, slĆ”n, sĆ”bhĆ”ilte, bain bagairtĆ­" + }, + "URLToPDF": { + "tags": "grĆ©asĆ”n a ghabhĆ”il, a shĆ”bhĆ”il-leathanach, grĆ©asĆ”n-go-doc, cartlann", + "title": "URL go PDF", + "header": "URL go PDF", + "submit": "Tiontaigh", + "credit": "ÚsĆ”ideann WeasyPrint" + }, + "HTMLToPDF": { + "tags": "marcĆ”il, Ć”bhar grĆ©asĆ”in, claochlĆŗ, tiontĆŗ", + "title": "HTML go PDF", + "header": "HTML go PDF", + "help": "Glacann sĆ© le comhaid HTML agus ZIPs ina bhfuil html/css/Ć­omhĆ”nna srl riachtanach", + "submit": "Tiontaigh", + "credit": "ÚsĆ”ideann WeasyPrint", + "zoom": "LeibhĆ©al sĆŗmĆ”il chun an suĆ­omh GrĆ©asĆ”in a thaispeĆ”int.", + "pageWidth": "Leithead an leathanaigh i ceintimĆ©adar. (BĆ”n go rĆ©amhshocrĆŗ)", + "pageHeight": "Airde an leathanaigh i ceintimĆ©adar. (BĆ”n go rĆ©amhshocrĆŗ)", + "marginTop": "Imeall barr an leathanaigh i millimĆ©adair. (BĆ”n go rĆ©amhshocrĆŗ)", + "marginBottom": "Imeall bun an leathanaigh i millimĆ©adair. (BĆ”n go rĆ©amhshocrĆŗ)", + "marginLeft": "Imeall clĆ© an leathanaigh i millimĆ©adair. (BĆ”n go rĆ©amhshocrĆŗ)", + "marginRight": "Imeall ceart an leathanaigh i millimĆ©adair. (BĆ”n go rĆ©amhshocrĆŗ)", + "printBackground": "ƍosluchtaigh cĆŗlra do lĆ”ithreĆ”in ghrĆ©asĆ”in.", + "defaultHeader": "Cumasaigh CeanntĆ”sc RĆ©amhshocraithe (Ainm agus uimhir an leathanaigh)", + "cssMediaType": "Athraigh cineĆ”l meĆ”in CSS an leathanaigh.", + "none": "Dada", + "print": "PriontĆ”il", + "screen": "ScĆ”ileĆ”n" + }, + "MarkdownToPDF": { + "tags": "marcĆ”il, Ć”bhar grĆ©asĆ”in, claochlĆŗ, tiontĆŗ", + "title": "MarcĆ”il sĆ­os go PDF", + "header": "MarcĆ”il sĆ­os go PDF", + "submit": "Tiontaigh", + "help": "Obair idir lĆ”mha", + "credit": "ÚsĆ”ideann WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "marcĆ”il, Ć”bhar GrĆ©asĆ”in, claochlĆŗ, tiontĆŗ, md", + "title": "PDF Chuig MarcĆ”il", + "header": "PDF Go MarcĆ”il", + "submit": "Tiontaigh" + }, + "getPdfInfo": { + "tags": "faisnĆ©is, sonraĆ­, staitisticĆ­, staitisticĆ­", + "title": "Faigh eolas ar PDF", + "header": "Faigh eolas ar PDF", + "submit": "Faigh Eolas", + "downloadJson": "ƍosluchtaigh ceol JSON" + }, + "extractPage": { + "tags": "sliocht" + }, + "PdfToSinglePage": { + "tags": "leathanach amhĆ”in" + }, + "showJS": { + "tags": "JS", + "title": "TaispeĆ”in Javascript", + "header": "TaispeĆ”in Javascript", + "downloadJS": "ƍosluchtaigh Javascript", + "submit": "TaispeĆ”in" + }, + "autoRedact": { + "tags": "Dearg, Folaigh, dubh amach, dubh, marcóir, i bhfolach", + "title": "Auto Redact", + "header": "Auto Redact", + "colorLabel": "Dath", + "textsToRedactLabel": "TĆ©acs go Deighilt (lĆ­nescartha)", + "textsToRedactPlaceholder": "e.g. \\nRĆŗnda \\nTrĆ­-rĆŗnda", + "useRegexLabel": "Bain ĆŗsĆ”id as Regex", + "wholeWordSearchLabel": "Cuardach Focal IomlĆ”n", + "customPaddingLabel": "StuĆ”il Breise Saincheaptha", + "convertPDFToImageLabel": "Tiontaigh PDF go PDF-Image (ÚsĆ”idte chun tĆ©acs a bhaint taobh thiar den bhosca)", + "submitButton": "Cuir isteach" + }, + "redact": { + "tags": "RĆ©iteach, Folaigh, dubh amach, dubh, marcóir, i bhfolach, lĆ”mhleabhar", + "title": "AthchóiriĆŗ de LĆ”imh", + "header": "AthchóiriĆŗ de LĆ”imh", + "submit": "RĆ©iteach", + "textBasedRedaction": "AthrĆŗ TĆ©acsbhunaithe", + "pageBasedRedaction": "AthrĆŗ bunaithe ar Leathanaigh", + "convertPDFToImageLabel": "Tiontaigh PDF go PDF-Image (ÚsĆ”idte chun tĆ©acs a bhaint taobh thiar den bhosca)", + "pageRedactionNumbers": { + "title": "Leathanaigh", + "placeholder": "(m.sh. 1,2,8 nó 4,7,12-16 nó 2n-1)" + }, + "redactionColor": { + "title": "Dath Athbhreithnithe" + }, + "export": "EaspórtĆ”il", + "upload": "UaslódĆ”il", + "boxRedaction": "dearadh tarraingthe an bhosca", + "zoom": "SĆŗmĆ”il", + "zoomIn": "SĆŗmĆ”il isteach", + "zoomOut": "SĆŗmĆ”il amach", + "nextPage": "An ChĆ©ad Leathanach Eile", + "previousPage": "Leathanach Roimhe Seo", + "toggleSidebar": "ScorĆ”naigh an Barra Taoibh", + "showThumbnails": "TaispeĆ”in Mionsamhlacha", + "showDocumentOutline": "TaispeĆ”in ImlĆ­ne an DoicimĆ©id (cliceĆ”il faoi dhó chun gach mĆ­r a leathnĆŗ/laghdĆŗ)", + "showAttatchments": "TaispeĆ”in CeangaltĆ”in", + "showLayers": "TaispeĆ”in Sraitheanna (cliceĆ”il faoi dhó chun gach sraith a athshocrĆŗ go dtĆ­ an staid rĆ©amhshocraithe)", + "colourPicker": "Roghnóir Dathanna", + "findCurrentOutlineItem": "Faigh imlĆ­ne reatha", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV, Eastóscadh TĆ”bla, sliocht, tiontĆŗ" + }, + "autoSizeSplitPDF": { + "tags": "pdf, scoilt, doicimĆ©ad, eagraĆ­ocht" + }, + "overlay-pdfs": { + "tags": "Forleagan", + "header": "Forleagan comhaid PDF", + "baseFile": { + "label": "Roghnaigh Bonn Comhad PDF" + }, + "overlayFiles": { + "label": "Roghnaigh Forleagan Comhaid PDF" + }, + "mode": { + "label": "Roghnaigh Mód Forleagan", + "sequential": "Forleagan Seicheamhach", + "interleaved": "Forleagan Interleaved", + "fixedRepeat": "Forleagan AthdhĆ©anta Seasta" + }, + "counts": { + "label": "Ɓireamh Forleagan (do Mhód AthdhĆ©anta Seasta)", + "placeholder": "Cuir isteach comhairimh scartha le camóga (m.sh., 2,3,1)" + }, + "position": { + "label": "Roghnaigh Post Forleagan", + "foreground": "Tulra", + "background": "CĆŗlra" + }, + "submit": "Cuir isteach" + }, + "split-by-sections": { + "tags": "Roinn Scoilt, Roinn, Saincheap", + "title": "Scoilt PDF de rĆ©ir ailt", + "header": "Scoilt PDF i gcodanna", + "horizontal": { + "label": "RannĆ”in ChothromĆ”nacha", + "placeholder": "Cuir isteach lĆ­on na rannĆ”n cothromĆ”nach" + }, + "vertical": { + "label": "RannĆ”in Ingearach", + "placeholder": "Cuir isteach lĆ­on na rannĆ”in ingearacha" + }, + "submit": "Scoilt PDF", + "merge": "Chumasadh i gceann PDF" + }, + "AddStampRequest": { + "tags": "Stampa, Cuir Ć­omhĆ”, Ć­omhĆ” lĆ”r, Uisce, PDF, LeabĆŗ, Saincheap", + "header": "Stampa PDF", + "title": "Stampa PDF", + "stampType": "CineĆ”l Stampa", + "stampText": "TĆ©acs Stampa", + "stampImage": "ƍomhĆ” Stampa", + "alphabet": "AibĆ­tir", + "fontSize": "Cló/MĆ©id na hƍomhĆ”", + "rotation": "RothlĆŗ", + "opacity": "Teimhneacht", + "position": "Post", + "overrideX": "SĆ”raigh X ComhordanĆ”id", + "overrideY": "SĆ”raigh Y ComhordanĆ”id", + "customMargin": "Imeall an Chustaim", + "customColor": "Dath TĆ©acs Saincheaptha", + "submit": "Cuir isteach" + }, + "removeImagePdf": { + "tags": "Bain ƍomhĆ”, OibrĆ­ochtaĆ­ Leathanaigh, CĆŗl, taobh an fhreastalaĆ­" + }, + "splitPdfByChapters": { + "tags": "scoilt, caibidlĆ­, leabharmharcanna, eagraigh" + }, + "validateSignature": { + "tags": "sĆ­niĆŗ, fĆ­oraigh, deimhnigh, pdf, teastas, sĆ­niĆŗ digiteach, SĆ­niĆŗ BailĆ­ochtaigh, BailĆ­ochtaigh teastas", + "title": "BailĆ­ochtaigh SĆ­nithe PDF", + "header": "BailĆ­ochtaigh SĆ­nithe Digiteacha", + "selectPDF": "Roghnaigh comhad PDF sĆ­nithe", + "submit": "BailĆ­ochtaigh SĆ­nithe", + "results": "TorthaĆ­ BailĆ­ochtaithe", + "status": { + "_value": "StĆ”das", + "valid": "BailĆ­", + "invalid": "NeamhbhailĆ­" + }, + "signer": "SĆ­nitheoir", + "date": "DĆ”ta", + "reason": "CĆŗis", + "location": "SuĆ­omh", + "noSignatures": "NĆ­or aimsĆ­odh sĆ­niĆŗ digiteach ar bith sa doicimĆ©ad seo", + "chain": { + "invalid": "Theip ar bhailĆ­ochtĆŗ slabhra an teastais - nĆ­ fĆ©idir aitheantas an tsĆ­nitheora a fhĆ­orĆŗ" + }, + "trust": { + "invalid": "NĆ­l an teastas sa stór muinĆ­ne - nĆ­ fĆ©idir an fhoinse a fhĆ­orĆŗ" + }, + "cert": { + "expired": "TĆ” an teastas imithe in Ć©ag", + "revoked": "TĆ” an teastas cĆŗlghairthe", + "info": "SonraĆ­ an Teastais", + "issuer": "Eisitheoir", + "subject": "Ɓbhar", + "serialNumber": "Sraithuimhir", + "validFrom": "BailĆ­ Ɠ", + "validUntil": "BailĆ­ Go dtĆ­", + "algorithm": "Algartam", + "keySize": "MĆ©id na hEochrach", + "version": "Leagan", + "keyUsage": "ÚsĆ”id Eochrach", + "selfSigned": "FĆ©in-SĆ­nithe", + "bits": "giotĆ”in" + }, + "signature": { + "info": "Eolas SĆ­nithe", + "_value": "SĆ­niĆŗ", + "mathValid": "TĆ” an sĆ­niĆŗ bailĆ­ go matamaiticiĆŗil ACH:" + }, + "selectCustomCert": "Comhad Teastais Saincheaptha X.509 (Roghnach)" + }, + "replace-color": { + "title": "Athchuir-InbhĆ©artaigh-Dath", + "header": "Athchuir-InbhĆ©artaigh Dath PDF", + "selectText": { + "1": "Athchuir nó InbhĆ©artaigh Roghanna datha", + "2": "RĆ©amhshocrĆŗ(RĆ©amhshocrĆŗ dathanna ardchodarsnachta)", + "3": "Saincheaptha(dathanna saincheaptha)", + "4": "Iompaithe LĆ”n(InbhĆ©artaigh gach dath)", + "5": "Roghanna dathanna ardchodarsnachta", + "6": "tĆ©acs bĆ”n ar chĆŗlra dubh", + "7": "TĆ©acs dubh ar chĆŗlra bĆ”n", + "8": "TĆ©acs buĆ­ ar chĆŗlra dubh", + "9": "TĆ©acs glas ar chĆŗlra dubh", + "10": "Roghnaigh Dath an tĆ©acs", + "11": "Roghnaigh Dath an ChĆŗlra" + }, + "submit": "Ionadaigh" + }, + "replaceColorPdf": { + "tags": "Athchuir Dath,OibrĆ­ochtaĆ­ Leathanaigh,CĆŗl,taobh an fhreastalaĆ­" + }, + "login": { + "title": "SĆ­nigh isteach", + "header": "SĆ­nigh isteach", + "signin": "SĆ­nigh isteach", + "rememberme": "Cuimhnigh orm", + "invalid": "Ainm ĆŗsĆ”ideora nó pasfhocal neamhbhailĆ­.", + "locked": "TĆ” do chuntas glasĆ”ilte.", + "signinTitle": "SĆ­nigh isteach le do thoil", + "ssoSignIn": "LogĆ”il isteach trĆ­ ChlĆ”rĆŗ Aonair", + "oAuth2AutoCreateDisabled": "OAUTH2 Uath-Chruthaigh ÚsĆ”ideoir faoi MhĆ­chumas", + "oAuth2AdminBlockedUser": "TĆ” bac faoi lĆ”thair ar chlĆ”rĆŗ nó logĆ”il isteach ĆŗsĆ”ideoirĆ­ neamhchlĆ”raithe. DĆ©an teagmhĆ”il leis an riarthóir le do thoil.", + "oauth2RequestNotFound": "NĆ­or aimsĆ­odh iarratas Ćŗdaraithe", + "oauth2InvalidUserInfoResponse": "Freagra NeamhbhailĆ­ FaisnĆ©ise ÚsĆ”ideora", + "oauth2invalidRequest": "Iarratas NeamhbhailĆ­", + "oauth2AccessDenied": "Rochtain DiĆŗltaithe", + "oauth2InvalidTokenResponse": "Freagra Comhartha NeamhbhailĆ­", + "oauth2InvalidIdToken": "Comhartha Aitheantais NeamhbhailĆ­", + "relyingPartyRegistrationNotFound": "NĆ­or aimsĆ­odh clĆ”rĆŗ pĆ”irtĆ­ spleĆ”ch", + "userIsDisabled": "ÚsĆ”ideoir dĆ­ghnĆ­omhachtaithe, tĆ” bac ar logĆ”il isteach leis an ainm ĆŗsĆ”ideora seo faoi lĆ”thair. DĆ©an teagmhĆ”il leis an riarthóir le do thoil.", + "alreadyLoggedIn": "TĆ” tĆŗ logĆ”ilte isteach cheana", + "alreadyLoggedIn2": "glĆ©asanna. LogĆ”il amach as na glĆ©asanna agus bain triail eile as.", + "toManySessions": "TĆ” an iomarca seisiĆŗn gnĆ­omhach agat", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF go leathanach amhĆ”in", + "header": "PDF go leathanach amhĆ”in", + "submit": "Tiontaigh go Leathanach Aonair" + }, + "pageExtracter": { + "title": "Leathanaigh Sliocht", + "header": "Leathanaigh Sliocht", + "submit": "Sliocht", + "placeholder": "(m.sh. 1,2,8 nó 4,7,12-16 nó 2n-1)" + }, + "sanitizePDF": { + "title": "PDF slĆ”intĆ­ocht", + "header": "Glanadh comhad PDF", + "selectText": { + "1": "Bain gnĆ­omhartha JavaScript", + "2": "Bain comhaid leabaithe", + "3": "Remove XMP metadata", + "4": "Bain naisc", + "5": "Bain clónna", + "6": "Remove Document Info Metadata" + }, + "submit": "PDF slĆ”intĆ­ocht" + }, + "adjustContrast": { + "title": "Coigeartaigh Codarsnacht", + "header": "Coigeartaigh Codarsnacht", + "contrast": "Codarsnacht:", + "brightness": "Gile:", + "saturation": "SĆ”ithiĆŗ:", + "download": "ƍosluchtaigh" + }, + "compress": { + "title": "ComhbhrĆŗigh", + "header": "ComhbhrĆŗigh PDF", + "credit": "ÚsĆ”ideann an tseirbhĆ­s seo qpdf le haghaidh ComhbhrĆŗ/Optimization PDF.", + "grayscale": { + "label": "Cuir ScĆ”la Liath i bhFeidhm le ComhbhrĆŗ" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "LeibhĆ©al optamaithe:", + "4": "Mód uathoibrĆ­och - CoigeartaĆ­onn Auto cĆ”ilĆ­ocht chun PDF a fhĆ”il go dtĆ­ an mĆ©id cruinn", + "5": "MĆ©id PDF a bhfuiltear ag sĆŗil leis (m.sh. 25MB, 10.8MB, 25KB)" + }, + "submit": "ComhbhrĆŗigh" + }, + "decrypt": { + "passwordPrompt": "TĆ” an comhad seo cosanta ag pasfhocal. Cuir isteach an pasfhocal le do thoil:", + "cancelled": "CealaĆ­odh an oibrĆ­ocht le haghaidh PDF: {0}", + "noPassword": "NĆ­or solĆ”thraĆ­odh focal faire don PDF criptithe: {0}", + "invalidPassword": "DĆ©an iarracht eile leis an bhfocal faire ceart.", + "invalidPasswordHeader": "Focal faire mĆ­cheart nó criptiĆŗchĆ”n PDF nach dtacaĆ­tear leis: {0}", + "unexpectedError": "Tharla earrĆ”id agus an comhad Ć” phróiseĆ”il. Bain triail eile as.", + "serverError": "EarrĆ”id fhreastalaĆ­ agus Ć© dĆ­chriptiĆŗ: {0}", + "success": "D'Ć©irigh le dĆ­chriptiĆŗ an chomhaid." + }, + "multiTool-advert": { + "message": "TĆ” an ghnĆ© seo ar fĆ”il inĆ”r leathanach il-uirlisĆ­ freisin. SeiceĆ”il Ć© le haghaidh ChomhĆ©adain leathanach ar leathanach feabhsaithe agus gnĆ©ithe breise!" + }, + "pageRemover": { + "title": "Bainteoir Leathanach", + "header": "PDF leathanach remover", + "pagesToDelete": "Leathanaigh le scriosadh (Cuir isteach liosta uimhreacha leathanaigh atĆ” deighilte le camóga): :", + "submit": "Scrios Leathanaigh", + "placeholder": "(m.sh. 1,2,6 nó 1-10,15-30)" + }, + "imageToPDF": { + "title": "ƍomhĆ” go PDF", + "header": "ƍomhĆ” go PDF", + "submit": "Tiontaigh", + "selectLabel": "Roghanna OiriĆŗnĆŗ ƍomhĆ”", + "fillPage": "LĆ­on Leathanach", + "fitDocumentToImage": "Fit Leathanach don ƍomhĆ”", + "maintainAspectRatio": "Cóimheasa GnĆ©is a chothabhĆ”il", + "selectText": { + "2": "PDF rothlĆŗ uathoibrĆ­och", + "3": "Loighic ilchomhad (cumasaithe ach amhĆ”in mĆ” oibrĆ­onn tĆŗ le hĆ­omhĆ”nna iolracha)", + "4": "Chumasadh go PDF amhĆ”in", + "5": "Tiontaigh go PDF ar leith" + } + }, + "PDFToCSV": { + "title": "Ɠ CSV go PDF", + "header": "Ɠ CSV go PDF", + "prompt": "Roghnaigh leathanach chun tĆ”bla a bhaint as", + "submit": "Sliocht" + }, + "split-by-size-or-count": { + "title": "Scoilt PDF de rĆ©ir MĆ©id nó Comhairimh", + "header": "Scoilt PDF de rĆ©ir MĆ©id nó Comhairimh", + "type": { + "label": "Roghnaigh CineĆ”l Scoilt", + "size": "De rĆ©ir MĆ©id", + "pageCount": "De rĆ©ir Comhaireamh Leathanaigh", + "docCount": "De rĆ©ir LĆ­on na nDoicimĆ©ad" + }, + "value": { + "label": "Cuir isteach Luach", + "placeholder": "Cuir isteach mĆ©id (m.sh., 2MB nó 3KB) nó comhaireamh (m.sh., 5)" + }, + "submit": "Cuir isteach" + }, + "printFile": { + "title": "PriontĆ”il Comhad", + "header": "PriontĆ”il an Comhad go PrintĆ©ir", + "selectText": { + "1": "Roghnaigh Comhad le PriontĆ”il", + "2": "Cuir isteach Ainm an PhrintĆ©ara" + }, + "submit": "PriontĆ”il" + }, + "licenses": { + "nav": "CeadĆŗnais", + "title": "CeadĆŗnais 3Ćŗ PĆ”irtĆ­", + "header": "CeadĆŗnais 3Ćŗ PĆ”irtĆ­", + "module": "ModĆŗl", + "version": "Leagan", + "license": "CeadĆŗnas" + }, + "survey": { + "nav": "SuirbhĆ©", + "title": "SuirbhĆ© Stirling-PDF", + "description": "NĆ­l aon rian ar Stirling-PDF agus mar sin ba mhaith linn cloisteĆ”il ónĆ”r n-ĆŗsĆ”ideoirĆ­ chun feabhas a chur ar Stirling-PDF!", + "changes": "TĆ” Stirling-PDF athraithe ón suirbhĆ© deireanach! Le tuilleadh a fhĆ”il amach fĆ©ach ar Ć”r mblagphost anseo:", + "changes2": "De bharr na n-athruithe seo tĆ”imid ag fĆ”il tacaĆ­ochta gnó agus maoiniĆŗ Ć­octha", + "please": "Smaoinigh ar Ć”r suirbhĆ© a dhĆ©anamh le do thoil!", + "disabled": "(DĆ­chumasófar anĆ­os an tsuirbhĆ© sna nuashonruithe seo a leanas ach beidh siad ar fĆ”il ag bun an leathanaigh)", + "button": "Tóg SuirbhĆ©", + "dontShowAgain": "NĆ” taispeĆ”in arĆ­s", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Bain Ć­omhĆ”", + "header": "Bain Ć­omhĆ”", + "removeImage": "Bain Ć­omhĆ”", + "submit": "Bain Ć­omhĆ”" + }, + "splitByChapters": { + "title": "Scoil PDF de rĆ©ir CaibidlĆ­", + "header": "Scoil PDF de rĆ©ir CaibidlĆ­", + "bookmarkLevel": "LeibhĆ©al Leabharmharc", + "includeMetadata": "Cuir meiteashonraĆ­ san Ć”ireamh", + "allowDuplicates": "Ceadaigh do DhĆŗblaigh", + "desc": { + "1": "Scann an uirlis seo comhad PDF ina PDFanna iolracha bunaithe ar a struchtĆŗr caibidle.", + "2": "LeibhĆ©al Leabharmharc: Roghnaigh leibhĆ©al na leabharmharcanna le hĆŗsĆ”id don scoilteadh (0 don bharrleibhĆ©al, 1 don dara leibhĆ©al, etc.).", + "3": "Cuir MeiteashonraĆ­ san Ć”ireamh: MĆ” dhĆ©antar iad a sheiceĆ”il, cuirfear meiteashonraĆ­ an PDF bhunaidh san Ć”ireamh i ngach PDF scoilte.", + "4": "Ceadaigh do DhĆŗblaigh: MĆ” dhĆ©antar iad a sheiceĆ”il, ceadaĆ­tear go leor leabharmharcanna ar an leathanach cĆ©anna chun PDFanna ar leith a chruthĆŗ." + }, + "submit": "Scoil PDF" + }, + "fileChooser": { + "click": "CliceĆ”il", + "or": "nó", + "dragAndDrop": "Tarraing & Scaoil", + "dragAndDropPDF": "Tarraing & Scaoil comhad PDF", + "dragAndDropImage": "Tarraing & Scaoil comhad ƍomhĆ”", + "hoveredDragAndDrop": "Tarraing agus scaoil comhad(Ć­) anseo", + "extractPDF": "Ag AistriĆŗ..." + }, + "releases": { + "footer": "EisiĆŗintĆ­", + "title": "NótaĆ­ EisiĆŗna", + "header": "NótaĆ­ EisiĆŗna", + "current": { + "version": "EisiĆŗna Reatha" + }, + "note": "TĆ” nótaĆ­ eisiĆŗna ar fĆ”il i mBĆ©arla amhĆ”in" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/hi-IN/translation.json b/frontend/public/locales/hi-IN/translation.json new file mode 100644 index 000000000..5b0a2d68b --- /dev/null +++ b/frontend/public/locales/hi-IN/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "ą¤«ą¤¼ą„‰ą¤Øą„ą¤Ÿ आकार", + "fontName": "ą¤«ą¤¼ą„‰ą¤Øą„ą¤Ÿ नाम", + "title": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "header": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "selectText": { + "1": "PDF फ़ाइल ą¤šą„ą¤Øą„‡ą¤‚:", + "2": "ą¤®ą¤¾ą¤°ą„ą¤œą¤æą¤Ø आकार", + "3": "ą¤øą„ą¤„ą¤æą¤¤ą¤æ", + "4": "ą¤Ŗą„ą¤°ą¤¾ą¤°ą¤‚ą¤­ą¤æą¤• ą¤øą¤‚ą¤–ą„ą¤Æą¤¾", + "5": "ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ą¤‚ą¤•ą¤æą¤¤ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Ŗą„ƒą¤·ą„ą¤ ", + "6": "ą¤•ą¤øą„ą¤Ÿą¤® ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ" + }, + "customTextDesc": "ą¤•ą¤øą„ą¤Ÿą¤® ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ", + "numberPagesDesc": "ą¤•ą„Œą¤Ø ą¤øą„‡ ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ą¤‚ą¤•ą¤æą¤¤ ą¤•ą¤°ą¤Øą„‡ ą¤¹ą„ˆą¤‚, ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ 'ą¤øą¤­ą„€', 1-5 या 2,5,9 आदि ą¤­ą„€ ą¤øą„ą¤µą„€ą¤•ą¤¾ą¤° करता ą¤¹ą„ˆ", + "customNumberDesc": "ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ {n}, 'ą¤Ŗą„ƒą¤·ą„ą¤  {n} ą¤•ą„ą¤² {total}', 'ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ-{n}', '{filename}-{n}' ą¤­ą„€ ą¤øą„ą¤µą„€ą¤•ą¤¾ą¤° करता ą¤¹ą„ˆ", + "submit": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚" + }, + "pdfPrompt": "ą¤Ŗą„€ą¤”ą„€ą¤ą¤« फ़ाइल(ą„‡ą¤‚) ą¤šą„ą¤Øą„‡ą¤‚", + "multiPdfPrompt": "ą¤Ŗą„€ą¤”ą„€ą¤ą¤« ą¤«ą¤¼ą¤¾ą¤‡ą¤²ą„‡ą¤‚ ą¤šą„ą¤Øą„‡ą¤‚ (2+)", + "multiPdfDropPrompt": "ą¤†ą¤µą¤¶ą„ą¤Æą¤• ą¤øą¤­ą„€ ą¤Ŗą„€ą¤”ą„€ą¤ą¤« ą¤«ą¤¼ą¤¾ą¤‡ą¤²ą„‹ą¤‚ ą¤•ą„‹ ą¤šą„ą¤Øą„‡ą¤‚ (या ą¤–ą„€ą¤‚ą¤š कर ą¤›ą„‹ą¤”ą¤¼ą„‡ą¤‚)", + "imgPrompt": "छवि(यां) ą¤šą„ą¤Øą„‡ą¤‚", + "genericSubmit": "जमा ą¤•ą¤°ą„‡ą¤‚", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "ą¤šą„‡ą¤¤ą¤¾ą¤µą¤Øą„€: फ़ाइल ą¤•ą„‡ आकार ą¤•ą„‡ आधार पर यह ą¤Ŗą„ą¤°ą¤•ą„ą¤°ą¤æą¤Æą¤¾ ą¤ą¤• मिनट तक ą¤²ą„‡ ą¤øą¤•ą¤¤ą„€ ą¤¹ą„ˆ", + "pageOrderPrompt": "ą¤•ą¤øą„ą¤Ÿą¤® ą¤Ŗą„ƒą¤·ą„ą¤  ą¤•ą„ą¤°ą¤® (ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ą¤“ą¤‚ ą¤•ą„€ ą¤…ą¤²ą„ą¤Ŗą¤µą¤æą¤°ą¤¾ą¤® ą¤øą„‡ अलग ą¤øą„‚ą¤šą„€ या 2n+1 ą¤œą„ˆą¤øą„‡ ą¤«ą¤¼ą¤‚ą¤•ą„ą¤¶ą¤Ø ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚):", + "pageSelectionPrompt": "ą¤•ą¤øą„ą¤Ÿą¤® ą¤Ŗą„ƒą¤·ą„ą¤  चयन (ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ą¤“ą¤‚ 1,5,6 या 2n+1 ą¤œą„ˆą¤øą„‡ ą¤«ą¤¼ą¤‚ą¤•ą„ą¤¶ą¤Ø ą¤•ą„€ ą¤…ą¤²ą„ą¤Ŗą¤µą¤æą¤°ą¤¾ą¤® ą¤øą„‡ अलग ą¤øą„‚ą¤šą„€ ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚):", + "goToPage": "ą¤œą¤¾ą¤ą¤‚", + "true": "हाँ", + "false": "ą¤Øą¤¹ą„€ą¤‚", + "unknown": "ą¤…ą¤œą„ą¤žą¤¾ą¤¤", + "save": "ą¤øą¤¹ą„‡ą¤œą„‡ą¤‚", + "saveToBrowser": "ą¤¬ą„ą¤°ą¤¾ą¤‰ą¤œą¤¼ą¤° ą¤®ą„‡ą¤‚ ą¤øą¤¹ą„‡ą¤œą„‡ą¤‚", + "close": "बंद ą¤•ą¤°ą„‡ą¤‚", + "filesSelected": "ą¤«ą¤¼ą¤¾ą¤‡ą¤²ą„‡ą¤‚ चयनित", + "noFavourites": "ą¤•ą„‹ą¤ˆ ą¤Ŗą¤øą¤‚ą¤¦ą„€ą¤¦ą¤¾ ą¤Øą¤¹ą„€ą¤‚ ą¤œą„‹ą¤”ą¤¼ą¤¾ गया", + "downloadComplete": "ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤Ŗą„‚ą¤°ą„ą¤£", + "bored": "ą¤‡ą¤‚ą¤¤ą¤œą¤¼ą¤¾ą¤° ą¤•ą¤°ą¤¤ą„‡ ą¤¹ą„ą¤ ą¤¬ą„‹ą¤° ą¤¹ą„‹ ą¤°ą¤¹ą„‡ ą¤¹ą„ˆą¤‚?", + "alphabet": "ą¤µą¤°ą„ą¤£ą¤®ą¤¾ą¤²ą¤¾", + "downloadPdf": "ą¤Ŗą„€ą¤”ą„€ą¤ą¤« ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚", + "text": "ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ", + "font": "ą¤«ą¤¼ą„‰ą¤Øą„ą¤Ÿ", + "selectFillter": "-- ą¤šą„ą¤Øą„‡ą¤‚ --", + "pageNum": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą¤‚ą¤–ą„ą¤Æą¤¾", + "sizes": { + "small": "ą¤›ą„‹ą¤Ÿą¤¾", + "medium": "ą¤®ą¤§ą„ą¤Æą¤®", + "large": "बऔ़ा", + "x-large": "ą¤¬ą¤¹ą„ą¤¤ बऔ़ा" + }, + "error": { + "pdfPassword": "ą¤Ŗą„€ą¤”ą„€ą¤ą¤« ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤øą„‡ ą¤øą„ą¤°ą¤•ą„ą¤·ą¤æą¤¤ ą¤¹ą„ˆ और या ą¤¤ą„‹ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤Øą¤¹ą„€ą¤‚ दिया गया ऄा या गलत ऄा", + "_value": "ą¤¤ą„ą¤°ą„ą¤Ÿą¤æ", + "sorry": "ą¤øą¤®ą¤øą„ą¤Æą¤¾ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤–ą„‡ą¤¦ ą¤¹ą„ˆ!", + "needHelp": "मदद ą¤šą¤¾ą¤¹ą¤æą¤ / ą¤•ą„‹ą¤ˆ ą¤øą¤®ą¤øą„ą¤Æą¤¾ ą¤®ą¤æą¤²ą„€?", + "contactTip": "यदि आप ą¤…ą¤­ą„€ ą¤­ą„€ ą¤øą¤®ą¤øą„ą¤Æą¤¾ą¤“ą¤‚ का सामना कर ą¤°ą¤¹ą„‡ ą¤¹ą„ˆą¤‚, ą¤¤ą„‹ मदद ą¤•ą„‡ ą¤²ą¤æą¤ ą¤¹ą¤®ą¤øą„‡ ą¤øą¤‚ą¤Ŗą¤°ą„ą¤• ą¤•ą¤°ą¤Øą„‡ ą¤®ą„‡ą¤‚ ą¤øą¤‚ą¤•ą„‹ą¤š न ą¤•ą¤°ą„‡ą¤‚ą„¤ आप ą¤¹ą¤®ą¤¾ą¤°ą„‡ GitHub ą¤Ŗą„ƒą¤·ą„ą¤  पर ą¤Ÿą¤æą¤•ą¤Ÿ जमा कर ą¤øą¤•ą¤¤ą„‡ ą¤¹ą„ˆą¤‚ या Discord ą¤•ą„‡ ą¤®ą¤¾ą¤§ą„ą¤Æą¤® ą¤øą„‡ ą¤¹ą¤®ą¤øą„‡ ą¤øą¤‚ą¤Ŗą¤°ą„ą¤• कर ą¤øą¤•ą¤¤ą„‡ ą¤¹ą„ˆą¤‚:", + "404": { + "head": "404 - ą¤Ŗą„ƒą¤·ą„ą¤  ą¤Øą¤¹ą„€ą¤‚ मिला | उफ़, हम ą¤•ą„‹ą¤” ą¤®ą„‡ą¤‚ ą¤ ą„‹ą¤•ą¤° खा ą¤—ą¤!", + "1": "हम वह ą¤Ŗą„ƒą¤·ą„ą¤  ą¤Øą¤¹ą„€ą¤‚ ą¤¢ą„‚ą¤‚ą¤¢ पा ą¤°ą¤¹ą„‡ ą¤¹ą„ˆą¤‚ ą¤œą¤æą¤øą„‡ आप ą¤–ą„‹ą¤œ ą¤°ą¤¹ą„‡ ą¤¹ą„ˆą¤‚ą„¤", + "2": "ą¤•ą„ą¤› गलत ą¤¹ą„‹ गया" + }, + "github": "GitHub पर ą¤Ÿą¤æą¤•ą¤Ÿ जमा ą¤•ą¤°ą„‡ą¤‚", + "showStack": "ą¤øą„ą¤Ÿą„ˆą¤• ą¤Ÿą„ą¤°ą„‡ą¤ø ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚", + "copyStack": "ą¤øą„ą¤Ÿą„ˆą¤• ą¤Ÿą„ą¤°ą„‡ą¤ø ą¤•ą„‰ą¤Ŗą„€ ą¤•ą¤°ą„‡ą¤‚", + "githubSubmit": "GitHub - ą¤øą¤®ą¤øą„ą¤Æą¤¾ ą¤Ÿą¤æą¤•ą¤Ÿ जमा ą¤•ą¤°ą„‡ą¤‚", + "discordSubmit": "Discord - सहायता ą¤…ą¤Øą„ą¤°ą„‹ą¤§ जमा ą¤•ą¤°ą„‡ą¤‚" + }, + "delete": "ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "username": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ नाम", + "password": "ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤”", + "welcome": "ą¤øą„ą¤µą¤¾ą¤—ą¤¤ ą¤¹ą„ˆ", + "property": "ą¤øą¤‚ą¤Ŗą¤¤ą„ą¤¤ą¤æ", + "black": "काला", + "white": "ą¤øą¤«ą„‡ą¤¦", + "red": "लाल", + "green": "हरा", + "blue": "ą¤Øą„€ą¤²ą¤¾", + "custom": "ą¤•ą¤øą„ą¤Ÿą¤®...", + "WorkInProgess": "ą¤•ą¤¾ą¤°ą„ą¤Æ ą¤Ŗą„ą¤°ą¤—ą¤¤ą¤æ पर ą¤¹ą„ˆ, काम ą¤Øą¤¹ą„€ą¤‚ कर सकता ą¤¹ą„ˆ या बग ą¤¹ą„‹ ą¤øą¤•ą¤¤ą„‡ ą¤¹ą„ˆą¤‚, ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤•ą¤æą¤øą„€ ą¤­ą„€ ą¤øą¤®ą¤øą„ą¤Æą¤¾ ą¤•ą„€ ą¤°ą¤æą¤Ŗą„‹ą¤°ą„ą¤Ÿ ą¤•ą¤°ą„‡ą¤‚!", + "poweredBy": "ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ ą¤øą¤‚ą¤šą¤¾ą¤²ą¤æą¤¤", + "yes": "हाँ", + "no": "ą¤Øą¤¹ą„€ą¤‚", + "changedCredsMessage": "ą¤•ą„ą¤°ą„‡ą¤”ą„‡ą¤‚ą¤¶ą¤æą¤Æą¤²ą„ą¤ø बदल ą¤¦ą¤æą¤ ą¤—ą¤!", + "notAuthenticatedMessage": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤æą¤¤ ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„ˆą„¤", + "userNotFoundMessage": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤Øą¤¹ą„€ą¤‚ ą¤®ą¤æą¤²ą¤¾ą„¤", + "incorrectPasswordMessage": "ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” गलत ą¤¹ą„ˆą„¤", + "usernameExistsMessage": "नया ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ नाम ą¤Ŗą¤¹ą¤²ą„‡ ą¤øą„‡ ą¤®ą„Œą¤œą„‚ą¤¦ ą¤¹ą„ˆą„¤", + "invalidUsernameMessage": "ą¤…ą¤®ą¤¾ą¤Øą„ą¤Æ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ नाम, ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ नाम ą¤®ą„‡ą¤‚ ą¤•ą„‡ą¤µą¤² ą¤…ą¤•ą„ą¤·ą¤°, ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ą¤ą¤‚ और ą¤Øą¤æą¤®ą„ą¤Øą¤²ą¤æą¤–ą¤æą¤¤ ą¤µą¤æą¤¶ą„‡ą¤· ą¤µą¤°ą„ą¤£ @._+- ą¤¹ą„‹ ą¤øą¤•ą¤¤ą„‡ ą¤¹ą„ˆą¤‚ या ą¤ą¤• ą¤µą„ˆą¤§ ą¤ˆą¤®ą„‡ą¤² पता ą¤¹ą„‹ą¤Øą¤¾ ą¤šą¤¾ą¤¹ą¤æą¤ą„¤", + "invalidPasswordMessage": "ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤–ą¤¾ą¤²ą„€ ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„‹ सकता ą¤¹ą„ˆ और ą¤¶ą„ą¤°ą„ą¤†ą¤¤ या अंत ą¤®ą„‡ą¤‚ ą¤øą„ą¤Ŗą„‡ą¤ø ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„‹ ą¤øą¤•ą¤¤ą„‡ą„¤", + "confirmPasswordErrorMessage": "नया ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” और ą¤Ŗą„ą¤·ą„ą¤Ÿą¤æ नया ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤®ą„‡ą¤² ą¤–ą¤¾ą¤Øą„‡ ą¤šą¤¾ą¤¹ą¤æą¤ą„¤", + "deleteCurrentUserMessage": "ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤²ą„‰ą¤— इन ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤•ą„‹ हटा ą¤Øą¤¹ą„€ą¤‚ ą¤øą¤•ą¤¤ą„‡ą„¤", + "deleteUsernameExistsMessage": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ नाम ą¤®ą„Œą¤œą„‚ą¤¦ ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„ˆ और ą¤‡ą¤øą„‡ हटाया ą¤Øą¤¹ą„€ą¤‚ जा ą¤øą¤•ą¤¤ą¤¾ą„¤", + "downgradeCurrentUserMessage": "ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤•ą„€ ą¤­ą„‚ą¤®ą¤æą¤•ą¤¾ ą¤•ą„‹ ą¤”ą¤¾ą¤‰ą¤Øą¤—ą„ą¤°ą„‡ą¤” ą¤Øą¤¹ą„€ą¤‚ किया जा सकता", + "disabledCurrentUserMessage": "ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤•ą„‹ ą¤…ą¤•ą„ą¤·ą¤® ą¤Øą¤¹ą„€ą¤‚ किया जा सकता", + "downgradeCurrentUserLongMessage": "ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤•ą„€ ą¤­ą„‚ą¤®ą¤æą¤•ą¤¾ ą¤•ą„‹ ą¤”ą¤¾ą¤‰ą¤Øą¤—ą„ą¤°ą„‡ą¤” ą¤Øą¤¹ą„€ą¤‚ किया जा ą¤øą¤•ą¤¤ą¤¾ą„¤ ą¤‡ą¤øą¤²ą¤æą¤, ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤Øą¤¹ą„€ą¤‚ दिखाया ą¤œą¤¾ą¤ą¤—ą¤¾ą„¤", + "userAlreadyExistsOAuthMessage": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤Ŗą¤¹ą¤²ą„‡ ą¤øą„‡ ą¤¹ą„€ OAuth2 ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤•ą„‡ ą¤°ą„‚ą¤Ŗ ą¤®ą„‡ą¤‚ ą¤®ą„Œą¤œą„‚ą¤¦ ą¤¹ą„ˆą„¤", + "userAlreadyExistsWebMessage": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤Ŗą¤¹ą¤²ą„‡ ą¤øą„‡ ą¤¹ą„€ ą¤µą„‡ą¤¬ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤•ą„‡ ą¤°ą„‚ą¤Ŗ ą¤®ą„‡ą¤‚ ą¤®ą„Œą¤œą„‚ą¤¦ ą¤¹ą„ˆą„¤", + "oops": "उफ़!", + "help": "सहायता", + "goHomepage": "ą¤®ą„ą¤–ą„ą¤Æ ą¤Ŗą„ƒą¤·ą„ą¤  पर ą¤œą¤¾ą¤ą¤‚", + "joinDiscord": "ą¤¹ą¤®ą¤¾ą¤°ą„‡ Discord ą¤øą¤°ą„ą¤µą¤° ą¤®ą„‡ą¤‚ शामिल ą¤¹ą„‹ą¤‚", + "seeDockerHub": "Docker Hub ą¤¦ą„‡ą¤–ą„‡ą¤‚", + "visitGithub": "GitHub ą¤°ą¤æą¤Ŗą„‰ą¤œą¤æą¤Ÿą¤°ą„€ पर ą¤œą¤¾ą¤ą¤‚", + "donate": "दान ą¤•ą¤°ą„‡ą¤‚", + "color": "रंग", + "sponsor": "ą¤Ŗą„ą¤°ą¤¾ą¤Æą„‹ą¤œą¤•", + "info": "ą¤œą¤¾ą¤Øą¤•ą¤¾ą¤°ą„€", + "pro": "ą¤Ŗą„ą¤°ą„‹", + "page": "ą¤Ŗą„ƒą¤·ą„ą¤ ", + "pages": "ą¤Ŗą„ƒą¤·ą„ą¤ ", + "loading": "ą¤²ą„‹ą¤” ą¤¹ą„‹ रहा ą¤¹ą„ˆ...", + "addToDoc": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤®ą„‡ą¤‚ ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "reset": "ą¤°ą„€ą¤øą„‡ą¤Ÿ", + "apply": "ą¤²ą¤¾ą¤—ą„‚ ą¤•ą¤°ą„‡ą¤‚", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤¤ą¤¾ ą¤Øą„€ą¤¤ą¤æ", + "terms": "नियम और ą¤¶ą¤°ą„ą¤¤ą„‡ą¤‚", + "accessibility": "ą¤øą„ą¤²ą¤­ą¤¤ą¤¾", + "cookie": "ą¤•ą„ą¤•ą„€ ą¤Øą„€ą¤¤ą¤æ", + "impressum": "ą¤‡ą¤®ą„ą¤Ŗą„ą¤°ą„‡ą¤øą¤®", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "पाइपलाइन ą¤®ą„‡ą¤Øą„‚ (ą¤¬ą„€ą¤Ÿą¤¾)", + "uploadButton": "ą¤•ą¤øą„ą¤Ÿą¤® ą¤…ą¤Ŗą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚", + "configureButton": "ą¤•ą„‰ą¤Øą„ą¤«ą¤¼ą¤æą¤—ą¤° ą¤•ą¤°ą„‡ą¤‚", + "defaultOption": "ą¤•ą¤øą„ą¤Ÿą¤®", + "submitButton": "जमा ą¤•ą¤°ą„‡ą¤‚", + "help": "पाइपलाइन सहायता", + "scanHelp": "ą¤«ą¤¼ą„‹ą¤²ą„ą¤”ą¤° ą¤øą„ą¤•ą„ˆą¤Øą¤æą¤‚ą¤— सहायता", + "deletePrompt": "ą¤•ą„ą¤Æą¤¾ आप ą¤µą¤¾ą¤•ą¤ˆ पाइपलाइन ą¤•ą„‹ हटाना ą¤šą¤¾ą¤¹ą¤¤ą„‡ ą¤¹ą„ˆą¤‚?", + "tags": "ą¤øą„ą¤µą¤šą¤¾ą¤²ą¤æą¤¤,ą¤•ą„ą¤°ą¤®,ą¤øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿą„‡ą¤”,ą¤¬ą„ˆą¤š-ą¤Ŗą„ą¤°ą„‹ą¤øą„‡ą¤ø", + "title": "पाइपलाइन" + }, + "pipelineOptions": { + "header": "पाइपलाइन ą¤•ą„‰ą¤Øą„ą¤«ą¤¼ą¤æą¤—ą¤°ą„‡ą¤¶ą¤Ø", + "pipelineNameLabel": "पाइपलाइन नाम", + "saveSettings": "ą¤‘ą¤Ŗą¤°ą„‡ą¤¶ą¤Ø ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø ą¤øą¤¹ą„‡ą¤œą„‡ą¤‚", + "pipelineNamePrompt": "यहाँ पाइपलाइन नाम ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚", + "selectOperation": "ą¤‘ą¤Ŗą¤°ą„‡ą¤¶ą¤Ø ą¤šą„ą¤Øą„‡ą¤‚", + "addOperationButton": "ą¤‘ą¤Ŗą¤°ą„‡ą¤¶ą¤Ø ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "pipelineHeader": "पाइपलाइन:", + "saveButton": "ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚", + "validateButton": "ą¤®ą¤¾ą¤Øą„ą¤Æ ą¤•ą¤°ą„‡ą¤‚" + }, + "enterpriseEdition": { + "button": "ą¤Ŗą„ą¤°ą„‹ ą¤®ą„‡ą¤‚ ą¤…ą¤Ŗą¤—ą„ą¤°ą„‡ą¤” ą¤•ą¤°ą„‡ą¤‚", + "warning": "यह ą¤øą„ą¤µą¤æą¤§ą¤¾ ą¤•ą„‡ą¤µą¤² ą¤Ŗą„ą¤°ą„‹ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ą¤“ą¤‚ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤‰ą¤Ŗą¤²ą¤¬ą„ą¤§ ą¤¹ą„ˆą„¤", + "yamlAdvert": "Stirling PDF ą¤Ŗą„ą¤°ą„‹ YAML ą¤•ą„‰ą¤Øą„ą¤«ą¤¼ą¤æą¤—ą¤°ą„‡ą¤¶ą¤Ø ą¤«ą¤¼ą¤¾ą¤‡ą¤²ą„‹ą¤‚ और ą¤…ą¤Øą„ą¤Æ SSO ą¤øą„ą¤µą¤æą¤§ą¤¾ą¤“ą¤‚ का ą¤øą¤®ą¤°ą„ą¤„ą¤Ø करता ą¤¹ą„ˆą„¤", + "ssoAdvert": "और अधिक ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤Ŗą„ą¤°ą¤¬ą¤‚ą¤§ą¤Ø ą¤øą„ą¤µą¤æą¤§ą¤¾ą¤“ą¤‚ ą¤•ą„€ तलाश ą¤®ą„‡ą¤‚? Stirling PDF ą¤Ŗą„ą¤°ą„‹ ą¤œą¤¾ą¤‚ą¤šą„‡ą¤‚" + }, + "analytics": { + "title": "ą¤•ą„ą¤Æą¤¾ आप Stirling PDF ą¤•ą„‹ ą¤¬ą„‡ą¤¹ą¤¤ą¤° बनाना ą¤šą¤¾ą¤¹ą¤¤ą„‡ ą¤¹ą„ˆą¤‚?", + "paragraph1": "Stirling PDF ą¤®ą„‡ą¤‚ ą¤‰ą¤¤ą„ą¤Ŗą¤¾ą¤¦ ą¤•ą„‹ ą¤¬ą„‡ą¤¹ą¤¤ą¤° ą¤¬ą¤Øą¤¾ą¤Øą„‡ ą¤®ą„‡ą¤‚ मदद ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤µą¤æą¤•ą¤²ą„ą¤Ŗ ą¤µą¤æą¤¶ą„ą¤²ą„‡ą¤·ą¤£ ą¤¹ą„ˆą„¤ हम ą¤•ą¤æą¤øą„€ ą¤­ą„€ ą¤µą„ą¤Æą¤•ą„ą¤¤ą¤æą¤—ą¤¤ ą¤œą¤¾ą¤Øą¤•ą¤¾ą¤°ą„€ या फ़ाइल ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€ ą¤•ą„‹ ą¤Ÿą„ą¤°ą„ˆą¤• ą¤Øą¤¹ą„€ą¤‚ ą¤•ą¤°ą¤¤ą„‡ ą¤¹ą„ˆą¤‚ą„¤", + "paragraph2": "ą¤•ą„ƒą¤Ŗą¤Æą¤¾ Stirling-PDF ą¤•ą„‹ ą¤¬ą¤¢ą¤¼ą¤Øą„‡ ą¤®ą„‡ą¤‚ मदद ą¤•ą¤°ą¤Øą„‡ और ą¤¹ą¤®ą„‡ą¤‚ ą¤…ą¤Ŗą¤Øą„‡ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ą¤“ą¤‚ ą¤•ą„‹ ą¤¬ą„‡ą¤¹ą¤¤ą¤° ą¤øą¤®ą¤ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤µą¤æą¤¶ą„ą¤²ą„‡ą¤·ą¤£ ą¤øą¤•ą„ą¤·ą¤® ą¤•ą¤°ą¤Øą„‡ पर विचार ą¤•ą¤°ą„‡ą¤‚ą„¤", + "enable": "ą¤µą¤æą¤¶ą„ą¤²ą„‡ą¤·ą¤£ ą¤øą¤•ą„ą¤·ą¤® ą¤•ą¤°ą„‡ą¤‚", + "disable": "ą¤µą¤æą¤¶ą„ą¤²ą„‡ą¤·ą¤£ ą¤…ą¤•ą„ą¤·ą¤® ą¤•ą¤°ą„‡ą¤‚", + "settings": "आप config/settings.yml फ़ाइल ą¤®ą„‡ą¤‚ ą¤µą¤æą¤¶ą„ą¤²ą„‡ą¤·ą¤£ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø बदल ą¤øą¤•ą¤¤ą„‡ ą¤¹ą„ˆą¤‚" + }, + "navbar": { + "favorite": "ą¤Ŗą¤øą¤‚ą¤¦ą„€ą¤¦ą¤¾", + "recent": "New and recently updated", + "darkmode": "ą¤”ą¤¾ą¤°ą„ą¤• ą¤®ą„‹ą¤”", + "language": "ą¤­ą¤¾ą¤·ą¤¾ą¤ą¤‚", + "settings": "ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø", + "allTools": "उपकरण", + "multiTool": "ą¤®ą¤²ą„ą¤Ÿą„€ ą¤Ÿą„‚ą¤²", + "search": "ą¤–ą„‹ą¤œą„‡ą¤‚", + "sections": { + "organize": "ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "convertTo": "PDF ą¤®ą„‡ą¤‚ ą¤Ŗą¤°ą¤æą¤µą¤°ą„ą¤¤ą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "convertFrom": "PDF ą¤øą„‡ ą¤Ŗą¤°ą¤æą¤µą¤°ą„ą¤¤ą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "security": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° और ą¤øą„ą¤°ą¤•ą„ą¤·ą¤¾", + "advance": "ą¤‰ą¤Øą„ą¤Øą¤¤", + "edit": "ą¤¦ą„‡ą¤–ą„‡ą¤‚ और संपादित ą¤•ą¤°ą„‡ą¤‚", + "popular": "ą¤²ą„‹ą¤•ą¤Ŗą„ą¤°ą¤æą¤Æ" + } + }, + "settings": { + "title": "ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø", + "update": "ą¤…ą¤Ŗą¤”ą„‡ą¤Ÿ ą¤‰ą¤Ŗą¤²ą¤¬ą„ą¤§ ą¤¹ą„ˆ", + "updateAvailable": "{0} ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤øą„ą¤„ą¤¾ą¤Ŗą¤æą¤¤ ą¤øą¤‚ą¤øą„ą¤•ą¤°ą¤£ ą¤¹ą„ˆą„¤ ą¤ą¤• नया ą¤øą¤‚ą¤øą„ą¤•ą¤°ą¤£ ({1}) ą¤‰ą¤Ŗą¤²ą¤¬ą„ą¤§ ą¤¹ą„ˆą„¤", + "appVersion": "ऐप ą¤øą¤‚ą¤øą„ą¤•ą¤°ą¤£:", + "downloadOption": { + "title": "ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤µą¤æą¤•ą¤²ą„ą¤Ŗ ą¤šą„ą¤Øą„‡ą¤‚ (ą¤ą¤•ą¤² फ़ाइल ą¤—ą„ˆą¤°-ज़िप ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą„‡ ą¤²ą¤æą¤):", + "1": "ą¤‰ą¤øą„€ ą¤µą¤æą¤‚ą¤”ą„‹ ą¤®ą„‡ą¤‚ ą¤–ą„‹ą¤²ą„‡ą¤‚", + "2": "नई ą¤µą¤æą¤‚ą¤”ą„‹ ą¤®ą„‡ą¤‚ ą¤–ą„‹ą¤²ą„‡ą¤‚", + "3": "फ़ाइल ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚" + }, + "zipThreshold": "ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą„€ ą¤—ą¤ˆ ą¤«ą¤¼ą¤¾ą¤‡ą¤²ą„‹ą¤‚ ą¤•ą„€ ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ ą¤‡ą¤øą¤øą„‡ अधिक ą¤¹ą„‹ą¤Øą„‡ पर ज़िप ą¤•ą¤°ą„‡ą¤‚", + "signOut": "साइन ą¤†ą¤‰ą¤Ÿ", + "accountSettings": "खाता ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø", + "bored": { + "help": "ą¤ˆą¤øą„ą¤Ÿą¤° ą¤ą¤— ą¤—ą„‡ą¤® ą¤øą¤•ą„ą¤·ą¤® करता ą¤¹ą„ˆ" + }, + "cacheInputs": { + "name": "ą¤«ą¤¼ą„‰ą¤°ą„ą¤® ą¤‡ą¤Øą¤Ŗą„ą¤Ÿ ą¤øą¤¹ą„‡ą¤œą„‡ą¤‚", + "help": "ą¤­ą¤µą¤æą¤·ą„ą¤Æ ą¤•ą„‡ ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Ŗą¤¹ą¤²ą„‡ ą¤øą„‡ ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤æą¤ ą¤—ą¤ ą¤‡ą¤Øą¤Ŗą„ą¤Ÿ ą¤•ą„‹ ą¤øą„ą¤Ÿą„‹ą¤° ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤øą¤•ą„ą¤·ą¤® ą¤•ą¤°ą„‡ą¤‚" + } + }, + "changeCreds": { + "title": "ą¤•ą„ą¤°ą„‡ą¤”ą„‡ą¤‚ą¤¶ą¤æą¤Æą¤²ą„ą¤ø ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "header": "अपना खाता विवरण ą¤…ą¤Ŗą¤”ą„‡ą¤Ÿ ą¤•ą¤°ą„‡ą¤‚", + "changePassword": "आप ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ ą¤²ą„‰ą¤—ą¤æą¤Ø ą¤•ą„ą¤°ą„‡ą¤”ą„‡ą¤‚ą¤¶ą¤æą¤Æą¤²ą„ą¤ø का ą¤‰ą¤Ŗą¤Æą„‹ą¤— कर ą¤°ą¤¹ą„‡ ą¤¹ą„ˆą¤‚ą„¤ ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤ą¤• नया ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚", + "newUsername": "नया ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ नाम", + "oldPassword": "ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤”", + "newPassword": "नया ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤”", + "confirmNewPassword": "ą¤Øą¤ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤•ą„€ ą¤Ŗą„ą¤·ą„ą¤Ÿą¤æ ą¤•ą¤°ą„‡ą¤‚", + "submit": "ą¤Ŗą¤°ą¤æą¤µą¤°ą„ą¤¤ą¤Ø जमा ą¤•ą¤°ą„‡ą¤‚" + }, + "account": { + "title": "खाता ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø", + "accountSettings": "खाता ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø", + "adminSettings": "ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤¾ą¤Ŗą¤• ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø - ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ą¤“ą¤‚ ą¤•ą„‹ ą¤¦ą„‡ą¤–ą„‡ą¤‚ और ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "userControlSettings": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤Øą¤æą¤Æą¤‚ą¤¤ą„ą¤°ą¤£ ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø", + "changeUsername": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ नाम ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "newUsername": "नया ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ नाम", + "password": "ą¤Ŗą„ą¤·ą„ą¤Ÿą¤æą¤•ą¤°ą¤£ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤”", + "oldPassword": "ą¤Ŗą„ą¤°ą¤¾ą¤Øą¤¾ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤”", + "newPassword": "नया ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤”", + "changePassword": "ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "confirmNewPassword": "ą¤Øą¤ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤•ą„€ ą¤Ŗą„ą¤·ą„ą¤Ÿą¤æ ą¤•ą¤°ą„‡ą¤‚", + "signOut": "साइन ą¤†ą¤‰ą¤Ÿ", + "yourApiKey": "ą¤†ą¤Ŗą¤•ą„€ API ą¤•ą„ą¤‚ą¤œą„€", + "syncTitle": "ą¤–ą¤¾ą¤¤ą„‡ ą¤•ą„‡ साऄ ą¤¬ą„ą¤°ą¤¾ą¤‰ą¤œą¤¼ą¤° ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø सिंक ą¤•ą¤°ą„‡ą¤‚", + "settingsCompare": "ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø ą¤¤ą„ą¤²ą¤Øą¤¾:", + "property": "ą¤øą¤‚ą¤Ŗą¤¤ą„ą¤¤ą¤æ", + "webBrowserSettings": "ą¤µą„‡ą¤¬ ą¤¬ą„ą¤°ą¤¾ą¤‰ą¤œą¤¼ą¤° ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—", + "syncToBrowser": "सिंक खाता -> ą¤¬ą„ą¤°ą¤¾ą¤‰ą¤œą¤¼ą¤°", + "syncToAccount": "सिंक खाता <- ą¤¬ą„ą¤°ą¤¾ą¤‰ą¤œą¤¼ą¤°" + }, + "adminUserSettings": { + "title": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤Øą¤æą¤Æą¤‚ą¤¤ą„ą¤°ą¤£ ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø", + "header": "ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤¾ą¤Ŗą¤• ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤Øą¤æą¤Æą¤‚ą¤¤ą„ą¤°ą¤£ ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø", + "admin": "ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤¾ą¤Ŗą¤•", + "user": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾", + "addUser": "नया ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "deleteUser": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "confirmDeleteUser": "ą¤•ą„ą¤Æą¤¾ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤•ą„‹ हटा दिया ą¤œą¤¾ą¤?", + "confirmChangeUserStatus": "ą¤•ą„ą¤Æą¤¾ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤•ą„‹ ą¤…ą¤•ą„ą¤·ą¤®/ą¤øą¤•ą„ą¤·ą¤® किया ą¤œą¤¾ą¤?", + "usernameInfo": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ नाम ą¤®ą„‡ą¤‚ ą¤•ą„‡ą¤µą¤² ą¤…ą¤•ą„ą¤·ą¤°, ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ą¤ą¤‚ और ą¤Øą¤æą¤®ą„ą¤Øą¤²ą¤æą¤–ą¤æą¤¤ ą¤µą¤æą¤¶ą„‡ą¤· ą¤µą¤°ą„ą¤£ @._+- ą¤¹ą„‹ ą¤øą¤•ą¤¤ą„‡ ą¤¹ą„ˆą¤‚ या ą¤ą¤• ą¤µą„ˆą¤§ ą¤ˆą¤®ą„‡ą¤² पता ą¤¹ą„‹ą¤Øą¤¾ ą¤šą¤¾ą¤¹ą¤æą¤ą„¤", + "roles": "ą¤­ą„‚ą¤®ą¤æą¤•ą¤¾ą¤ą¤‚", + "role": "ą¤­ą„‚ą¤®ą¤æą¤•ą¤¾", + "actions": "ą¤•ą¤¾ą¤°ą„ą¤°ą¤µą¤¾ą¤‡ą¤Æą¤¾ą¤‚", + "apiUser": "ą¤øą„€ą¤®ą¤æą¤¤ API ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾", + "extraApiUser": "ą¤…ą¤¤ą¤æą¤°ą¤æą¤•ą„ą¤¤ ą¤øą„€ą¤®ą¤æą¤¤ API ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾", + "webOnlyUser": "ą¤•ą„‡ą¤µą¤² ą¤µą„‡ą¤¬ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾", + "demoUser": "ą¤”ą„‡ą¤®ą„‹ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ (ą¤•ą„‹ą¤ˆ ą¤•ą¤øą„ą¤Ÿą¤® ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø ą¤Øą¤¹ą„€ą¤‚)", + "internalApiUser": "आंतरिक API ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾", + "forceChange": "ą¤²ą„‰ą¤—ą¤æą¤Ø पर ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤•ą„‹ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤¬ą¤¦ą¤²ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤®ą¤œą¤¬ą„‚ą¤° ą¤•ą¤°ą„‡ą¤‚", + "submit": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤øą¤¹ą„‡ą¤œą„‡ą¤‚", + "changeUserRole": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤•ą„€ ą¤­ą„‚ą¤®ą¤æą¤•ą¤¾ ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "authenticated": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤æą¤¤", + "editOwnProfil": "ą¤…ą¤Ŗą¤Øą„€ ą¤Ŗą„ą¤°ą„‹ą¤«ą¤¼ą¤¾ą¤‡ą¤² संपादित ą¤•ą¤°ą„‡ą¤‚", + "enabledUser": "ą¤øą¤•ą„ą¤·ą¤® ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾", + "disabledUser": "ą¤…ą¤•ą„ą¤·ą¤® ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾", + "activeUsers": "ą¤øą¤•ą„ą¤°ą¤æą¤Æ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾:", + "disabledUsers": "ą¤…ą¤•ą„ą¤·ą¤® ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾:", + "totalUsers": "ą¤•ą„ą¤² ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾:", + "lastRequest": "अंतिम ą¤…ą¤Øą„ą¤°ą„‹ą¤§", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "ą¤”ą„‡ą¤Ÿą¤¾ą¤¬ą„‡ą¤ø आयात/ą¤Øą¤æą¤°ą„ą¤Æą¤¾ą¤¤", + "header": "ą¤”ą„‡ą¤Ÿą¤¾ą¤¬ą„‡ą¤ø आयात/ą¤Øą¤æą¤°ą„ą¤Æą¤¾ą¤¤", + "fileName": "फ़ाइल नाम", + "creationDate": "ą¤Øą¤æą¤°ą„ą¤®ą¤¾ą¤£ तिऄि", + "fileSize": "फ़ाइल आकार", + "deleteBackupFile": "ą¤¬ą„ˆą¤•ą¤…ą¤Ŗ फ़ाइल ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "importBackupFile": "ą¤¬ą„ˆą¤•ą¤…ą¤Ŗ फ़ाइल आयात ą¤•ą¤°ą„‡ą¤‚", + "createBackupFile": "ą¤¬ą„ˆą¤•ą¤…ą¤Ŗ फ़ाइल ą¤¬ą¤Øą¤¾ą¤ą¤‚", + "downloadBackupFile": "ą¤¬ą„ˆą¤•ą¤…ą¤Ŗ फ़ाइल ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚", + "info_1": "ą¤”ą„‡ą¤Ÿą¤¾ आयात ą¤•ą¤°ą¤¤ą„‡ समय, ą¤øą¤¹ą„€ ą¤øą¤‚ą¤°ą¤šą¤Øą¤¾ ą¤øą„ą¤Øą¤æą¤¶ą„ą¤šą¤æą¤¤ करना ą¤®ą¤¹ą¤¤ą„ą¤µą¤Ŗą„‚ą¤°ą„ą¤£ ą¤¹ą„ˆą„¤ यदि आप ą¤…ą¤Øą¤æą¤¶ą„ą¤šą¤æą¤¤ ą¤¹ą„ˆą¤‚ कि आप ą¤•ą„ą¤Æą¤¾ कर ą¤°ą¤¹ą„‡ ą¤¹ą„ˆą¤‚, ą¤¤ą„‹ ą¤•ą¤æą¤øą„€ ą¤Ŗą„‡ą¤¶ą„‡ą¤µą¤° ą¤øą„‡ सलाह और ą¤øą¤®ą¤°ą„ą¤„ą¤Ø ą¤²ą„‡ą¤‚ą„¤ ą¤øą¤‚ą¤°ą¤šą¤Øą¤¾ ą¤®ą„‡ą¤‚ ą¤¤ą„ą¤°ą„ą¤Ÿą¤æ ą¤ą¤Ŗą„ą¤²ą¤æą¤•ą„‡ą¤¶ą¤Ø ą¤–ą¤°ą¤¾ą¤¬ą„€ का कारण बन ą¤øą¤•ą¤¤ą„€ ą¤¹ą„ˆ, यहां तक कि ą¤ą¤Ŗą„ą¤²ą¤æą¤•ą„‡ą¤¶ą¤Ø ą¤•ą„‹ ą¤šą¤²ą¤¾ą¤Øą„‡ ą¤•ą„€ ą¤Ŗą„‚ą¤°ą„ą¤£ ą¤…ą¤•ą„ą¤·ą¤®ą¤¤ą¤¾ ą¤­ą„€ ą¤¹ą„‹ ą¤øą¤•ą¤¤ą„€ ą¤¹ą„ˆą„¤", + "info_2": "ą¤…ą¤Ŗą¤²ą„‹ą¤” ą¤•ą¤°ą¤¤ą„‡ समय फ़ाइल नाम ą¤®ą¤¾ą¤Æą¤Øą„‡ ą¤Øą¤¹ą„€ą¤‚ ą¤°ą¤–ą¤¤ą¤¾ą„¤ ą¤‡ą¤øą„‡ बाद ą¤®ą„‡ą¤‚ backup_user_yyyyMMddHHmm.sql ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ का पालन ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Ŗą„ą¤Øą¤°ą„ą¤Øą¤¾ą¤®ą¤æą¤¤ किया ą¤œą¤¾ą¤ą¤—ą¤¾, ą¤œą„‹ ą¤ą¤• ą¤øą„ą¤øą¤‚ą¤—ą¤¤ नामकरण ą¤øą¤®ą„ą¤®ą„‡ą¤²ą¤Ø ą¤øą„ą¤Øą¤æą¤¶ą„ą¤šą¤æą¤¤ करता ą¤¹ą„ˆą„¤", + "submit": "ą¤¬ą„ˆą¤•ą¤…ą¤Ŗ आयात ą¤•ą¤°ą„‡ą¤‚", + "importIntoDatabaseSuccessed": "ą¤”ą„‡ą¤Ÿą¤¾ą¤¬ą„‡ą¤ø ą¤®ą„‡ą¤‚ आयात सफल", + "backupCreated": "ą¤”ą„‡ą¤Ÿą¤¾ą¤¬ą„‡ą¤ø ą¤¬ą„ˆą¤•ą¤…ą¤Ŗ सफल", + "fileNotFound": "फ़ाइल ą¤Øą¤¹ą„€ą¤‚ ą¤®ą¤æą¤²ą„€", + "fileNullOrEmpty": "फ़ाइल ą¤–ą¤¾ą¤²ą„€ या ą¤¶ą„‚ą¤Øą„ą¤Æ ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„‹ ą¤øą¤•ą¤¤ą„€", + "failedImportFile": "फ़ाइल आयात विफल", + "notSupported": "यह ą¤«ą¤¼ą¤‚ą¤•ą„ą¤¶ą¤Ø ą¤†ą¤Ŗą¤•ą„‡ ą¤”ą„‡ą¤Ÿą¤¾ą¤¬ą„‡ą¤ø ą¤•ą¤Øą„‡ą¤•ą„ą¤¶ą¤Ø ą¤•ą„‡ ą¤²ą¤æą¤ ą¤‰ą¤Ŗą¤²ą¤¬ą„ą¤§ ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„ˆą„¤" + }, + "session": { + "expired": "आपका ą¤øą¤¤ą„ą¤° ą¤øą¤®ą¤¾ą¤Ŗą„ą¤¤ ą¤¹ą„‹ गया ą¤¹ą„ˆą„¤ ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤Ŗą„ƒą¤·ą„ą¤  ą¤•ą„‹ ą¤°ą¤æą¤«ą„ą¤°ą„‡ą¤¶ ą¤•ą¤°ą„‡ą¤‚ और ą¤Ŗą„ą¤Ø: ą¤Ŗą„ą¤°ą¤Æą¤¾ą¤ø ą¤•ą¤°ą„‡ą¤‚ą„¤", + "refreshPage": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤°ą¤æą¤«ą„ą¤°ą„‡ą¤¶ ą¤•ą¤°ą„‡ą¤‚" + }, + "home": { + "desc": "ą¤†ą¤Ŗą¤•ą„€ ą¤øą¤­ą„€ PDF ą¤†ą¤µą¤¶ą„ą¤Æą¤•ą¤¤ą¤¾ą¤“ą¤‚ ą¤•ą„‡ ą¤²ą¤æą¤ आपका ą¤øą„ą¤„ą¤¾ą¤Øą„€ą¤Æ ą¤°ą„‚ą¤Ŗ ą¤øą„‡ ą¤¹ą„‹ą¤øą„ą¤Ÿ किया गया ą¤ą¤•-ą¤øą„ą¤Ÿą„‰ą¤Ŗ-ą¤¶ą„‰ą¤Ŗą„¤", + "searchBar": "ą¤øą„ą¤µą¤æą¤§ą¤¾ą¤ą¤‚ ą¤–ą„‹ą¤œą„‡ą¤‚...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "ą¤¦ą„‡ą¤–ą„‡ą¤‚, ą¤Ÿą¤æą¤Ŗą„ą¤Ŗą¤£ą„€ ą¤•ą¤°ą„‡ą¤‚, ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ या छवियां ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "PDF ą¤®ą¤²ą„ą¤Ÿą„€ ą¤Ÿą„‚ą¤²", + "desc": "ą¤®ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚, ą¤˜ą„ą¤®ą¤¾ą¤ą¤‚, ą¤Ŗą„ą¤Øą¤°ą„ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚ और ą¤Ŗą„ƒą¤·ą„ą¤  ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "merge": { + "title": "ą¤®ą¤°ą„ą¤œ", + "desc": "ą¤•ą¤ˆ PDF ą¤•ą„‹ ą¤†ą¤øą¤¾ą¤Øą„€ ą¤øą„‡ ą¤ą¤• ą¤®ą„‡ą¤‚ ą¤®ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚ą„¤" + }, + "split": { + "title": "विभाजित", + "desc": "PDF ą¤•ą„‹ ą¤•ą¤ˆ ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą„‹ą¤‚ ą¤®ą„‡ą¤‚ विभाजित ą¤•ą¤°ą„‡ą¤‚" + }, + "rotate": { + "title": "ą¤˜ą„ą¤®ą¤¾ą¤ą¤‚", + "desc": "ą¤…ą¤Ŗą¤Øą„€ PDF ą¤•ą„‹ ą¤†ą¤øą¤¾ą¤Øą„€ ą¤øą„‡ ą¤˜ą„ą¤®ą¤¾ą¤ą¤‚ą„¤" + }, + "imageToPdf": { + "title": "छवि ą¤øą„‡ PDF", + "desc": "छवि (PNG, JPEG, GIF) ą¤•ą„‹ PDF ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚ą„¤" + }, + "pdfToImage": { + "title": "PDF ą¤øą„‡ छवि", + "desc": "PDF ą¤•ą„‹ छवि ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚ą„¤ (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "desc": "ą¤•ą¤æą¤øą„€ ą¤­ą„€ ą¤•ą„ą¤°ą¤® ą¤®ą„‡ą¤‚ ą¤Ŗą„ƒą¤·ą„ą¤  ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚/ą¤Ŗą„ą¤Øą¤°ą„ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚" + }, + "addImage": { + "title": "छवि ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "desc": "PDF पर ą¤ą¤• ą¤Øą¤æą¤°ą„ą¤§ą¤¾ą¤°ą¤æą¤¤ ą¤øą„ą¤„ą¤¾ą¤Ø पर छवि ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚" + }, + "watermark": { + "title": "ą¤µą„‰ą¤Ÿą¤°ą¤®ą¤¾ą¤°ą„ą¤• ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "desc": "ą¤…ą¤Ŗą¤Øą„‡ PDF ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œ ą¤®ą„‡ą¤‚ ą¤•ą¤øą„ą¤Ÿą¤® ą¤µą„‰ą¤Ÿą¤°ą¤®ą¤¾ą¤°ą„ą¤• ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚ą„¤" + }, + "permissions": { + "title": "ą¤…ą¤Øą„ą¤®ą¤¤ą¤æą¤Æą¤¾ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "desc": "ą¤…ą¤Ŗą¤Øą„‡ PDF ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œ ą¤•ą„€ ą¤…ą¤Øą„ą¤®ą¤¤ą¤æą¤Æą¤¾ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "removePages": { + "title": "ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚", + "desc": "ą¤…ą¤Ŗą¤Øą„‡ PDF ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œ ą¤øą„‡ अवांछित ą¤Ŗą„ƒą¤·ą„ą¤  ą¤¹ą¤Ÿą¤¾ą¤ą¤‚ą„¤" + }, + "addPassword": { + "title": "ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "desc": "ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤•ą„‡ साऄ ą¤…ą¤Ŗą¤Øą„‡ PDF ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œ ą¤•ą„‹ ą¤ą¤Øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ ą¤•ą¤°ą„‡ą¤‚ą„¤" + }, + "removePassword": { + "title": "ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "desc": "ą¤…ą¤Ŗą¤Øą„‡ PDF ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œ ą¤øą„‡ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤øą„ą¤°ą¤•ą„ą¤·ą¤¾ ą¤¹ą¤Ÿą¤¾ą¤ą¤‚ą„¤" + }, + "compressPdfs": { + "title": "ą¤•ą¤®ą„ą¤Ŗą„ą¤°ą„‡ą¤ø", + "desc": "PDF ą¤•ą„‹ ą¤•ą¤®ą„ą¤Ŗą„ą¤°ą„‡ą¤ø ą¤•ą¤°ą„‡ą¤‚ ताकि उनका फ़ाइल आकार कम ą¤¹ą„‹ ą¤œą¤¾ą¤ą„¤" + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "ą¤®ą„‡ą¤Ÿą¤¾ą¤”ą„‡ą¤Ÿą¤¾ ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "desc": "PDF ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œ ą¤øą„‡ ą¤®ą„‡ą¤Ÿą¤¾ą¤”ą„‡ą¤Ÿą¤¾ ą¤¬ą¤¦ą¤²ą„‡ą¤‚/ą¤¹ą¤Ÿą¤¾ą¤ą¤‚/ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚" + }, + "fileToPDF": { + "title": "फ़ाइल ą¤•ą„‹ PDF ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "desc": "लगभग ą¤•ą¤æą¤øą„€ ą¤­ą„€ फ़ाइल ą¤•ą„‹ PDF ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚ (DOCX, PNG, XLS, PPT, TXT और अधिक)" + }, + "ocr": { + "title": "OCR / ą¤øą„ą¤•ą„ˆą¤Ø साफ ą¤•ą¤°ą„‡ą¤‚", + "desc": "ą¤øą„ą¤•ą„ˆą¤Ø ą¤•ą„‹ साफ ą¤•ą¤°ą„‡ą¤‚ और PDF ą¤•ą„‡ अंदर ą¤›ą¤µą¤æą¤Æą„‹ą¤‚ ą¤øą„‡ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ का पता ą¤²ą¤—ą¤¾ą¤ą¤‚ और ą¤‰ą¤øą„‡ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤•ą„‡ ą¤°ą„‚ą¤Ŗ ą¤®ą„‡ą¤‚ फिर ą¤øą„‡ ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚ą„¤" + }, + "extractImages": { + "title": "छवियां ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚", + "desc": "PDF ą¤øą„‡ ą¤øą¤­ą„€ ą¤›ą¤µą¤æą¤Æą„‹ą¤‚ ą¤•ą„‹ ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚ और ą¤‰ą¤Øą„ą¤¹ą„‡ą¤‚ ज़िप ą¤®ą„‡ą¤‚ ą¤øą¤¹ą„‡ą¤œą„‡ą¤‚" + }, + "pdfToPDFA": { + "title": "PDF ą¤øą„‡ PDF/A", + "desc": "ą¤²ą¤‚ą¤¬ą„€ अवधि ą¤•ą„‡ भंऔारण ą¤•ą„‡ ą¤²ą¤æą¤ PDF ą¤•ą„‹ PDF/A ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "PDFToWord": { + "title": "PDF ą¤øą„‡ Word", + "desc": "PDF ą¤•ą„‹ Word ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗą„‹ą¤‚ ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚ (DOC, DOCX और ODT)" + }, + "PDFToPresentation": { + "title": "PDF ą¤øą„‡ ą¤Ŗą„ą¤°ą¤øą„ą¤¤ą„ą¤¤ą¤æ", + "desc": "PDF ą¤•ą„‹ ą¤Ŗą„ą¤°ą¤øą„ą¤¤ą„ą¤¤ą¤æ ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗą„‹ą¤‚ ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚ (PPT, PPTX और ODP)" + }, + "PDFToText": { + "title": "PDF ą¤øą„‡ RTF (ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ)", + "desc": "PDF ą¤•ą„‹ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ या RTF ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "PDFToHTML": { + "title": "PDF ą¤øą„‡ HTML", + "desc": "PDF ą¤•ą„‹ HTML ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "PDFToXML": { + "title": "PDF ą¤øą„‡ XML", + "desc": "PDF ą¤•ą„‹ XML ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "ScannerImageSplit": { + "title": "ą¤øą„ą¤•ą„ˆą¤Ø ą¤•ą„€ ą¤—ą¤ˆ ą¤«ą„‹ą¤Ÿą„‹ का पता ą¤²ą¤—ą¤¾ą¤ą¤‚/विभाजित ą¤•ą¤°ą„‡ą¤‚", + "desc": "ą¤«ą„‹ą¤Ÿą„‹/PDF ą¤•ą„‡ अंदर ą¤øą„‡ ą¤•ą¤ˆ ą¤«ą„‹ą¤Ÿą„‹ ą¤•ą„‹ विभाजित ą¤•ą¤°ą„‡ą¤‚" + }, + "sign": { + "title": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤•ą¤°ą„‡ą¤‚", + "desc": "ą¤šą¤æą¤¤ą„ą¤° बनाकर, ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ या छवि ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ PDF ą¤®ą„‡ą¤‚ ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚" + }, + "flatten": { + "title": "समतल ą¤•ą¤°ą„‡ą¤‚", + "desc": "PDF ą¤øą„‡ ą¤øą¤­ą„€ ą¤‡ą¤‚ą¤Ÿą¤°ą„ˆą¤•ą„ą¤Ÿą¤æą¤µ ą¤¤ą¤¤ą„ą¤µą„‹ą¤‚ और ą¤«ą„‰ą¤°ą„ą¤® ą¤•ą„‹ ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "repair": { + "title": "ą¤®ą¤°ą¤®ą„ą¤®ą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "desc": "खराब/ą¤Ÿą„‚ą¤Ÿą„€ ą¤¹ą„ą¤ˆ PDF ą¤•ą„‹ ą¤ ą„€ą¤• ą¤•ą¤°ą¤Øą„‡ का ą¤Ŗą„ą¤°ą¤Æą¤¾ą¤ø ą¤•ą¤°ą„‡ą¤‚" + }, + "removeBlanks": { + "title": "ą¤–ą¤¾ą¤²ą„€ ą¤Ŗą„ƒą¤·ą„ą¤  ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "desc": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤øą„‡ ą¤–ą¤¾ą¤²ą„€ ą¤Ŗą„ƒą¤·ą„ą¤ ą„‹ą¤‚ का पता ą¤²ą¤—ą¤¾ą¤ą¤‚ और ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "removeAnnotations": { + "title": "ą¤Ÿą¤æą¤Ŗą„ą¤Ŗą¤£ą¤æą¤Æą¤¾ą¤‚ ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "desc": "PDF ą¤øą„‡ ą¤øą¤­ą„€ ą¤Ÿą¤æą¤Ŗą„ą¤Ŗą¤£ą¤æą¤Æą¤¾ą¤‚/ą¤ą¤Øą„‹ą¤Ÿą„‡ą¤¶ą¤Ø ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "compare": { + "title": "ą¤¤ą„ą¤²ą¤Øą¤¾ ą¤•ą¤°ą„‡ą¤‚", + "desc": "2 PDF ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą„‹ą¤‚ ą¤•ą„‡ ą¤¬ą„€ą¤š अंतर ą¤•ą„€ ą¤¤ą„ą¤²ą¤Øą¤¾ ą¤•ą¤°ą„‡ą¤‚ और ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚" + }, + "certSign": { + "title": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤øą„‡ ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤•ą¤°ą„‡ą¤‚", + "desc": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤°/ą¤•ą„ą¤‚ą¤œą„€ (PEM/P12) ą¤øą„‡ PDF पर ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤•ą¤°ą„‡ą¤‚" + }, + "removeCertSign": { + "title": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "desc": "PDF ą¤øą„‡ ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "pageLayout": { + "title": "ą¤®ą¤²ą„ą¤Ÿą„€-ą¤Ŗą„‡ą¤œ ą¤²ą„‡ą¤†ą¤‰ą¤Ÿ", + "desc": "PDF ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œ ą¤•ą„‡ ą¤•ą¤ˆ ą¤Ŗą„ƒą¤·ą„ą¤ ą„‹ą¤‚ ą¤•ą„‹ ą¤ą¤• ą¤Ŗą„ƒą¤·ą„ą¤  ą¤®ą„‡ą¤‚ ą¤®ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚" + }, + "scalePages": { + "title": "ą¤Ŗą„ƒą¤·ą„ą¤  आकार/ą¤øą„ą¤•ą„‡ą¤² ą¤øą¤®ą¤¾ą¤Æą„‹ą¤œą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "desc": "ą¤Ŗą„ƒą¤·ą„ą¤  और/या ą¤‰ą¤øą¤•ą„€ ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€ का आकार/ą¤øą„ą¤•ą„‡ą¤² ą¤¬ą¤¦ą¤²ą„‡ą¤‚ą„¤" + }, + "pipeline": { + "title": "पाइपलाइन", + "desc": "पाइपलाइन ą¤øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ परिभाषित ą¤•ą¤°ą¤•ą„‡ PDF पर ą¤•ą¤ˆ ą¤•ą¤¾ą¤°ą„ą¤Æ ą¤•ą¤°ą„‡ą¤‚" + }, + "add-page-numbers": { + "title": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "desc": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤®ą„‡ą¤‚ ą¤ą¤• ą¤Øą¤æą¤°ą„ą¤§ą¤¾ą¤°ą¤æą¤¤ ą¤øą„ą¤„ą¤¾ą¤Ø पर ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚" + }, + "auto-rename": { + "title": "ą¤øą„ą¤µą¤¤ą¤ƒ PDF फ़ाइल का नाम ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "desc": "ą¤Ŗą¤¾ą¤ ą¤—ą¤ ą¤¹ą„‡ą¤”ą¤° ą¤•ą„‡ आधार पर PDF फ़ाइल का नाम ą¤øą„ą¤µą¤šą¤¾ą¤²ą¤æą¤¤ ą¤°ą„‚ą¤Ŗ ą¤øą„‡ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "adjust-contrast": { + "title": "रंग/ą¤•ą¤‚ą¤Ÿą„ą¤°ą¤¾ą¤øą„ą¤Ÿ ą¤øą¤®ą¤¾ą¤Æą„‹ą¤œą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "desc": "PDF का ą¤•ą¤‚ą¤Ÿą„ą¤°ą¤¾ą¤øą„ą¤Ÿ, ą¤øą¤‚ą¤¤ą„ƒą¤Ŗą„ą¤¤ą¤æ और ą¤šą¤®ą¤• ą¤øą¤®ą¤¾ą¤Æą„‹ą¤œą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚" + }, + "crop": { + "title": "PDF ą¤•ą„ą¤°ą„‰ą¤Ŗ ą¤•ą¤°ą„‡ą¤‚", + "desc": "आकार कम ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ PDF ą¤•ą„‹ ą¤•ą„ą¤°ą„‰ą¤Ŗ ą¤•ą¤°ą„‡ą¤‚ (ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤¬ą¤Øą¤¾ą¤ ą¤°ą¤–ą„‡ą¤‚!)" + }, + "autoSplitPDF": { + "title": "ą¤øą„ą¤µą¤¤ą¤ƒ ą¤Ŗą„ƒą¤·ą„ą¤  विभाजित ą¤•ą¤°ą„‡ą¤‚", + "desc": "ą¤­ą„Œą¤¤ą¤æą¤• ą¤øą„ą¤•ą„ˆą¤Ø ą¤•ą¤æą¤ ą¤—ą¤ ą¤Ŗą„ƒą¤·ą„ą¤  ą¤µą¤æą¤­ą¤¾ą¤œą¤• QR ą¤•ą„‹ą¤” ą¤•ą„‡ साऄ ą¤øą„ą¤•ą„ˆą¤Ø ą¤•ą„€ ą¤—ą¤ˆ PDF ą¤•ą„‹ ą¤øą„ą¤µą¤¤ą¤ƒ विभाजित ą¤•ą¤°ą„‡ą¤‚" + }, + "sanitizePdf": { + "title": "ą¤øą„ˆą¤Øą¤æą¤Ÿą¤¾ą¤‡ą¤œą¤¼", + "desc": "PDF ą¤«ą¤¼ą¤¾ą¤‡ą¤²ą„‹ą¤‚ ą¤øą„‡ ą¤øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ और ą¤…ą¤Øą„ą¤Æ ą¤¤ą¤¤ą„ą¤µą„‹ą¤‚ ą¤•ą„‹ ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "URLToPDF": { + "title": "URL/ą¤µą„‡ą¤¬ą¤øą¤¾ą¤‡ą¤Ÿ ą¤øą„‡ PDF", + "desc": "ą¤•ą¤æą¤øą„€ ą¤­ą„€ http(s) URL ą¤•ą„‹ PDF ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "HTMLToPDF": { + "title": "HTML ą¤øą„‡ PDF", + "desc": "ą¤•ą¤æą¤øą„€ ą¤­ą„€ HTML फ़ाइल या zip ą¤•ą„‹ PDF ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "MarkdownToPDF": { + "title": "Markdown ą¤øą„‡ PDF", + "desc": "ą¤•ą¤æą¤øą„€ ą¤­ą„€ Markdown फ़ाइल ą¤•ą„‹ PDF ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "PDF ą¤•ą„€ ą¤øą¤­ą„€ ą¤œą¤¾ą¤Øą¤•ą¤¾ą¤°ą„€ ą¤Ŗą„ą¤°ą¤¾ą¤Ŗą„ą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "desc": "PDF ą¤øą„‡ संभव ą¤øą¤­ą„€ ą¤œą¤¾ą¤Øą¤•ą¤¾ą¤°ą„€ ą¤Ŗą„ą¤°ą¤¾ą¤Ŗą„ą¤¤ ą¤•ą¤°ą„‡ą¤‚" + }, + "extractPage": { + "title": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚", + "desc": "PDF ą¤øą„‡ चयनित ą¤Ŗą„ƒą¤·ą„ą¤ ą„‹ą¤‚ ą¤•ą„‹ ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚" + }, + "PdfToSinglePage": { + "title": "ą¤ą¤• बऔ़ा ą¤Ŗą„ƒą¤·ą„ą¤ ", + "desc": "ą¤øą¤­ą„€ PDF ą¤Ŗą„ƒą¤·ą„ą¤ ą„‹ą¤‚ ą¤•ą„‹ ą¤ą¤• ą¤¬ą¤”ą¤¼ą„‡ ą¤ą¤•ą¤² ą¤Ŗą„ƒą¤·ą„ą¤  ą¤®ą„‡ą¤‚ ą¤®ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚" + }, + "showJS": { + "title": "ą¤œą¤¾ą¤µą¤¾ą¤øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚", + "desc": "PDF ą¤®ą„‡ą¤‚ ą¤‡ą¤‚ą¤œą„‡ą¤•ą„ą¤Ÿ ą¤•ą¤æą¤ ą¤—ą¤ ą¤•ą¤æą¤øą„€ ą¤­ą„€ ą¤œą¤¾ą¤µą¤¾ą¤øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ ą¤•ą„‹ ą¤–ą„‹ą¤œą„‡ą¤‚ और ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚" + }, + "autoRedact": { + "title": "ą¤øą„ą¤µą¤¤ą¤ƒ ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą¤°ą¤£", + "desc": "ą¤‡ą¤Øą¤Ŗą„ą¤Ÿ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤•ą„‡ आधार पर PDF ą¤®ą„‡ą¤‚ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤•ą„‹ ą¤øą„ą¤µą¤¤ą¤ƒ ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą„ƒą¤¤ ą¤•ą¤°ą„‡ą¤‚ (काला ą¤•ą¤°ą„‡ą¤‚)" + }, + "redact": { + "title": "ą¤®ą„ˆą¤Øą„ą¤…ą¤² ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą¤°ą¤£", + "desc": "चयनित ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ, बनाई ą¤—ą¤ˆ ą¤†ą¤•ą„ƒą¤¤ą¤æą¤Æą„‹ą¤‚ और/या चयनित ą¤Ŗą„ƒą¤·ą„ą¤ ą„‹ą¤‚ ą¤•ą„‡ आधार पर PDF ą¤•ą„‹ ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą„ƒą¤¤ ą¤•ą¤°ą„‡ą¤‚" + }, + "tableExtraxt": { + "title": "PDF ą¤øą„‡ CSV", + "desc": "PDF ą¤øą„‡ तालिकाओं ą¤•ą„‹ निकालकर CSV ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "autoSizeSplitPDF": { + "title": "आकार/ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ ą¤•ą„‡ आधार पर ą¤øą„ą¤µą¤¤ą¤ƒ विभाजित ą¤•ą¤°ą„‡ą¤‚", + "desc": "ą¤ą¤• PDF ą¤•ą„‹ आकार, ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą¤‚ą¤–ą„ą¤Æą¤¾, या ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ ą¤•ą„‡ आधार पर ą¤•ą¤ˆ ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ą„‹ą¤‚ ą¤®ą„‡ą¤‚ विभाजित ą¤•ą¤°ą„‡ą¤‚" + }, + "overlay-pdfs": { + "title": "PDF ą¤“ą¤µą¤°ą¤²ą„‡ ą¤•ą¤°ą„‡ą¤‚", + "desc": "PDF ą¤•ą„‹ ą¤¦ą„‚ą¤øą¤°ą„€ PDF ą¤•ą„‡ ऊपर ą¤“ą¤µą¤°ą¤²ą„‡ ą¤•ą¤°ą„‡ą¤‚" + }, + "split-by-sections": { + "title": "ą¤–ą¤‚ą¤”ą„‹ą¤‚ ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ PDF विभाजित ą¤•ą¤°ą„‡ą¤‚", + "desc": "PDF ą¤•ą„‡ ą¤Ŗą„ą¤°ą¤¤ą„ą¤Æą„‡ą¤• ą¤Ŗą„ƒą¤·ą„ą¤  ą¤•ą„‹ ą¤›ą„‹ą¤Ÿą„‡ ą¤•ą„ą¤·ą„ˆą¤¤ą¤æą¤œ और ą¤Šą¤°ą„ą¤§ą„ą¤µą¤¾ą¤§ą¤° ą¤–ą¤‚ą¤”ą„‹ą¤‚ ą¤®ą„‡ą¤‚ विभाजित ą¤•ą¤°ą„‡ą¤‚" + }, + "AddStampRequest": { + "title": "PDF ą¤®ą„‡ą¤‚ ą¤øą„ą¤Ÿą„ˆą¤®ą„ą¤Ŗ ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "desc": "ą¤Øą¤æą¤°ą„ą¤§ą¤¾ą¤°ą¤æą¤¤ ą¤øą„ą¤„ą¤¾ą¤Øą„‹ą¤‚ पर ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ या छवि ą¤øą„ą¤Ÿą„ˆą¤®ą„ą¤Ŗ ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚" + }, + "removeImagePdf": { + "title": "छवि ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "desc": "फ़ाइल आकार कम ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ PDF ą¤øą„‡ छवि ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "splitPdfByChapters": { + "title": "ą¤…ą¤§ą„ą¤Æą¤¾ą¤Æą„‹ą¤‚ ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ PDF विभाजित ą¤•ą¤°ą„‡ą¤‚", + "desc": "PDF ą¤•ą„‹ ą¤‰ą¤øą¤•ą„€ ą¤…ą¤§ą„ą¤Æą¤¾ą¤Æ ą¤øą¤‚ą¤°ą¤šą¤Øą¤¾ ą¤•ą„‡ आधार पर ą¤•ą¤ˆ ą¤«ą¤¼ą¤¾ą¤‡ą¤²ą„‹ą¤‚ ą¤®ą„‡ą¤‚ विभाजित ą¤•ą¤°ą„‡ą¤‚ą„¤" + }, + "validateSignature": { + "title": "PDF ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤øą¤¤ą„ą¤Æą¤¾ą¤Ŗą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "desc": "PDF ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą„‹ą¤‚ ą¤®ą„‡ą¤‚ औिजिटल ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° और ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤°ą„‹ą¤‚ ą¤•ą„‹ ą¤øą¤¤ą„ą¤Æą¤¾ą¤Ŗą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚" + }, + "replaceColorPdf": { + "title": "रंग ą¤¬ą¤¦ą¤²ą„‡ą¤‚ और ą¤‰ą¤²ą„ą¤Ÿą¤¾ ą¤•ą¤°ą„‡ą¤‚", + "desc": "PDF ą¤®ą„‡ą¤‚ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ और ą¤Ŗą„ƒą¤·ą„ą¤ ą¤­ą„‚ą¤®ą¤æ ą¤•ą„‡ ą¤²ą¤æą¤ रंग ą¤¬ą¤¦ą¤²ą„‡ą¤‚ और फ़ाइल आकार कम ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Ŗą„‚ą¤°ą„ą¤£ रंग ą¤•ą„‹ ą¤‰ą¤²ą„ą¤Ÿą¤¾ ą¤•ą¤°ą„‡ą¤‚" + } + }, + "viewPdf": { + "tags": "ą¤¦ą„‡ą¤–ą„‡ą¤‚,ą¤Ŗą¤¢ą¤¼ą„‡ą¤‚,ą¤Ÿą¤æą¤Ŗą„ą¤Ŗą¤£ą„€,ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ,छवि", + "title": "View/Edit PDF", + "header": "PDF ą¤¦ą„‡ą¤–ą„‡ą¤‚" + }, + "multiTool": { + "tags": "ą¤®ą¤²ą„ą¤Ÿą„€ ą¤Ÿą„‚ą¤²,ą¤®ą¤²ą„ą¤Ÿą„€ ą¤‘ą¤Ŗą¤°ą„‡ą¤¶ą¤Ø,UI,ą¤•ą„ą¤²ą¤æą¤• ą¤”ą„ą¤°ą„ˆą¤—,ą¤«ą„ą¤°ą¤‚ą¤Ÿ ą¤ą¤‚ą¤”,ą¤•ą„ą¤²ą¤¾ą¤‡ą¤‚ą¤Ÿ साइऔ,ą¤‡ą¤‚ą¤Ÿą¤°ą„ˆą¤•ą„ą¤Ÿą¤æą¤µ,ą¤‡ą¤‚ą¤Ÿą¤°ą„ˆą¤•ą„ą¤Ÿą„‡ą¤¬ą¤²,ą¤®ą„‚ą¤µ,ą¤”ą¤æą¤²ą„€ą¤Ÿ,ą¤®ą¤¾ą¤‡ą¤—ą„ą¤°ą„‡ą¤Ÿ,औिवाइऔ", + "title": "PDF ą¤®ą¤²ą„ą¤Ÿą„€ ą¤Ÿą„‚ą¤²", + "header": "PDF ą¤®ą¤²ą„ą¤Ÿą„€ ą¤Ÿą„‚ą¤²", + "uploadPrompts": "फ़ाइल नाम", + "selectAll": "ą¤øą¤­ą„€ ą¤šą„ą¤Øą„‡ą¤‚", + "deselectAll": "ą¤øą¤­ą„€ ą¤…ą¤šą¤Æą¤Øą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "selectPages": "ą¤Ŗą„ƒą¤·ą„ą¤  चयन", + "selectedPages": "चयनित ą¤Ŗą„ƒą¤·ą„ą¤ ", + "page": "ą¤Ŗą„ƒą¤·ą„ą¤ ", + "deleteSelected": "चयनित ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "downloadAll": "ą¤Øą¤æą¤°ą„ą¤Æą¤¾ą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "downloadSelected": "चयनित ą¤Øą¤æą¤°ą„ą¤Æą¤¾ą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "insertPageBreak": "ą¤Ŗą„ƒą¤·ą„ą¤  विराम ą¤”ą¤¾ą¤²ą„‡ą¤‚", + "addFile": "फ़ाइल ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "rotateLeft": "ą¤¬ą¤¾ą¤ą¤‚ ą¤˜ą„ą¤®ą¤¾ą¤ą¤‚", + "rotateRight": "ą¤¦ą¤¾ą¤ą¤‚ ą¤˜ą„ą¤®ą¤¾ą¤ą¤‚", + "split": "विभाजित ą¤•ą¤°ą„‡ą¤‚", + "moveLeft": "ą¤¬ą¤¾ą¤ą¤‚ ą¤²ą„‡ ą¤œą¤¾ą¤ą¤‚", + "moveRight": "ą¤¦ą¤¾ą¤ą¤‚ ą¤²ą„‡ ą¤œą¤¾ą¤ą¤‚", + "delete": "ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "dragDropMessage": "ą¤Ŗą„ƒą¤·ą„ą¤  चयनित", + "undo": "ą¤Ŗą„‚ą¤°ą„ą¤µą¤µą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "redo": "ą¤Ŗą„ą¤Øą¤ƒ ą¤•ą¤°ą„‡ą¤‚" + }, + "merge": { + "tags": "ą¤®ą¤°ą„ą¤œ,ą¤Ŗą„‡ą¤œ ą¤‘ą¤Ŗą¤°ą„‡ą¤¶ą¤Øą„ą¤ø,ą¤¬ą„ˆą¤• ą¤ą¤‚ą¤”,ą¤øą¤°ą„ą¤µą¤° साइऔ", + "title": "ą¤®ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚", + "header": "ą¤•ą¤ˆ PDF ą¤®ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚ (2+)", + "sortByName": "नाम ą¤øą„‡ ą¤•ą„ą¤°ą¤®ą¤¬ą¤¦ą„ą¤§ ą¤•ą¤°ą„‡ą¤‚", + "sortByDate": "तिऄि ą¤øą„‡ ą¤•ą„ą¤°ą¤®ą¤¬ą¤¦ą„ą¤§ ą¤•ą¤°ą„‡ą¤‚", + "removeCertSign": "ą¤®ą¤°ą„ą¤œ ą¤•ą„€ ą¤—ą¤ˆ फ़ाइल ą¤®ą„‡ą¤‚ औिजिटल ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤¹ą¤Ÿą¤¾ą¤ą¤‚?", + "submit": "ą¤®ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚" + }, + "split": { + "tags": "ą¤Ŗą„‡ą¤œ ą¤‘ą¤Ŗą¤°ą„‡ą¤¶ą¤Øą„ą¤ø,औिवाइऔ,ą¤®ą¤²ą„ą¤Ÿą„€ ą¤Ŗą„‡ą¤œ,ą¤•ą¤Ÿ,ą¤øą¤°ą„ą¤µą¤° साइऔ", + "title": "PDF विभाजित ą¤•ą¤°ą„‡ą¤‚", + "header": "PDF विभाजित ą¤•ą¤°ą„‡ą¤‚", + "desc": { + "1": "ą¤†ą¤Ŗą¤•ą„‡ ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ ą¤šą„ą¤Øą„‡ ą¤—ą¤ नंबर ą¤µą„‡ ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ą¤ą¤‚ ą¤¹ą„ˆą¤‚ ą¤œą¤¹ą¤¾ą¤‚ आप विभाजन करना ą¤šą¤¾ą¤¹ą¤¤ą„‡ ą¤¹ą„ˆą¤‚", + "2": "ą¤‡ą¤øą¤²ą¤æą¤ 1,3,7-9 का चयन ą¤•ą¤°ą¤Øą„‡ ą¤øą„‡ 10 ą¤Ŗą„ƒą¤·ą„ą¤ ą„‹ą¤‚ ą¤µą¤¾ą¤²ą„‡ ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤•ą„‹ 6 अलग-अलग PDF ą¤®ą„‡ą¤‚ विभाजित कर ą¤¦ą„‡ą¤—ą¤¾:", + "3": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ #1: ą¤Ŗą„ƒą¤·ą„ą¤  1", + "4": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ #2: ą¤Ŗą„ƒą¤·ą„ą¤  2 और 3", + "5": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ #3: ą¤Ŗą„ƒą¤·ą„ą¤  4, 5, 6, 7", + "6": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ #4: ą¤Ŗą„ƒą¤·ą„ą¤  8", + "7": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ #5: ą¤Ŗą„ƒą¤·ą„ą¤  9", + "8": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ #6: ą¤Ŗą„ƒą¤·ą„ą¤  10" + }, + "splitPages": "विभाजन ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Ŗą„ƒą¤·ą„ą¤  ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚:", + "submit": "विभाजित ą¤•ą¤°ą„‡ą¤‚" + }, + "rotate": { + "tags": "ą¤øą¤°ą„ą¤µą¤° साइऔ", + "title": "PDF ą¤˜ą„ą¤®ą¤¾ą¤ą¤‚", + "header": "PDF ą¤˜ą„ą¤®ą¤¾ą¤ą¤‚", + "selectAngle": "ą¤˜ą„ą¤®ą¤¾ą¤Øą„‡ का ą¤•ą„‹ą¤£ ą¤šą„ą¤Øą„‡ą¤‚ (90 ą¤”ą¤æą¤—ą„ą¤°ą„€ ą¤•ą„‡ ą¤—ą„ą¤£ą¤•ą„‹ą¤‚ ą¤®ą„‡ą¤‚):", + "submit": "ą¤˜ą„ą¤®ą¤¾ą¤ą¤‚" + }, + "imageToPdf": { + "tags": "ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£,img,jpg,ą¤šą¤æą¤¤ą„ą¤°,ą¤«ą„‹ą¤Ÿą„‹" + }, + "pdfToImage": { + "tags": "ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£,img,jpg,ą¤šą¤æą¤¤ą„ą¤°,ą¤«ą„‹ą¤Ÿą„‹", + "title": "PDF ą¤øą„‡ छवि", + "header": "PDF ą¤øą„‡ छवि", + "selectText": "छवि ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ", + "singleOrMultiple": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą„‡ छवि परिणाम ą¤Ŗą„ą¤°ą¤•ą¤¾ą¤°", + "single": "ą¤ą¤•ą¤² ą¤¬ą¤”ą¤¼ą„€ छवि", + "multi": "ą¤•ą¤ˆ छवियां", + "colorType": "रंग ą¤Ŗą„ą¤°ą¤•ą¤¾ą¤°", + "color": "रंग", + "grey": "ą¤—ą„ą¤°ą„‡ą¤øą„ą¤•ą„‡ą¤²", + "blackwhite": "काला और ą¤øą¤«ą„‡ą¤¦ (ą¤”ą„‡ą¤Ÿą¤¾ ą¤–ą„‹ सकता ą¤¹ą„ˆ!)", + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "info": "Python ą¤øą„ą¤„ą¤¾ą¤Ŗą¤æą¤¤ ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„ˆą„¤ WebP ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤†ą¤µą¤¶ą„ą¤Æą¤• ą¤¹ą„ˆą„¤", + "placeholder": "(ą¤œą„ˆą¤øą„‡ 1,2,8 या 4,7,12-16 या 2n-1)" + }, + "pdfOrganiser": { + "tags": "ą¤”ą„ą¤Ŗą„ą¤²ą„‡ą¤•ą„ą¤ø,सम,विषम,ą¤•ą„ą¤°ą¤®ą¤¬ą¤¦ą„ą¤§ ą¤•ą¤°ą„‡ą¤‚,ą¤®ą„‚ą¤µ", + "title": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤¾ą¤Ŗą¤•", + "header": "PDF ą¤Ŗą„ƒą¤·ą„ą¤  ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤¾ą¤Ŗą¤•", + "submit": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤Ŗą„ą¤Øą¤°ą„ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "mode": { + "_value": "ą¤®ą„‹ą¤”", + "1": "ą¤•ą¤øą„ą¤Ÿą¤® ą¤Ŗą„ƒą¤·ą„ą¤  ą¤•ą„ą¤°ą¤®", + "2": "ą¤‰ą¤²ą„ą¤Ÿą¤¾ ą¤•ą„ą¤°ą¤®", + "3": "ą¤”ą„ą¤Ŗą„ą¤²ą„‡ą¤•ą„ą¤ø ą¤•ą„ą¤°ą¤®ą¤¬ą¤¦ą„ą¤§ą¤Ø", + "4": "ą¤Ŗą„ą¤øą„ą¤¤ą¤æą¤•ą¤¾ ą¤•ą„ą¤°ą¤®ą¤¬ą¤¦ą„ą¤§ą¤Ø", + "5": "साइऔ ą¤øą„ą¤Ÿą¤æą¤š ą¤Ŗą„ą¤øą„ą¤¤ą¤æą¤•ą¤¾ ą¤•ą„ą¤°ą¤®ą¤¬ą¤¦ą„ą¤§ą¤Ø", + "6": "विषम-सम विभाजन", + "7": "ą¤Ŗą„ą¤°ą¤„ą¤® ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "8": "अंतिम ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "9": "ą¤Ŗą„ą¤°ą¤„ą¤® और अंतिम ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "10": "विषम-सम ą¤®ą¤°ą„ą¤œ", + "11": "Duplicate all pages" + }, + "placeholder": "(ą¤œą„ˆą¤øą„‡ 1,3,2 या 4-8,2,10-12 या 2n-1)" + }, + "addImage": { + "tags": "img,jpg,ą¤šą¤æą¤¤ą„ą¤°,ą¤«ą„‹ą¤Ÿą„‹", + "title": "छवि ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "header": "PDF ą¤®ą„‡ą¤‚ छवि ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "everyPage": "हर ą¤Ŗą„ƒą¤·ą„ą¤ ?", + "upload": "छवि ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "submit": "छवि ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚" + }, + "watermark": { + "tags": "ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ,ą¤¦ą„‹ą¤¹ą¤°ą¤¾ą¤µ,ą¤²ą„‡ą¤¬ą¤²,ą¤øą„ą¤µą¤Æą¤‚,ą¤•ą„‰ą¤Ŗą„€ą¤°ą¤¾ą¤‡ą¤Ÿ,ą¤Ÿą„ą¤°ą„‡ą¤”ą¤®ą¤¾ą¤°ą„ą¤•,img,jpg,ą¤šą¤æą¤¤ą„ą¤°,ą¤«ą„‹ą¤Ÿą„‹", + "title": "ą¤µą„‰ą¤Ÿą¤°ą¤®ą¤¾ą¤°ą„ą¤• ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "header": "ą¤µą„‰ą¤Ÿą¤°ą¤®ą¤¾ą¤°ą„ą¤• ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "customColor": "ą¤•ą¤øą„ą¤Ÿą¤® ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ रंग", + "selectText": { + "1": "ą¤µą„‰ą¤Ÿą¤°ą¤®ą¤¾ą¤°ą„ą¤• ą¤œą„‹ą¤”ą¤¼ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ PDF ą¤šą„ą¤Øą„‡ą¤‚:", + "2": "ą¤µą„‰ą¤Ÿą¤°ą¤®ą¤¾ą¤°ą„ą¤• ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ:", + "3": "ą¤«ą¤¼ą„‰ą¤Øą„ą¤Ÿ आकार:", + "4": "ą¤˜ą„ą¤®ą¤¾ą¤µ (0-360):", + "5": "ą¤šą„Œą¤”ą¤¼ą¤¾ą¤ˆ ą¤øą„ą¤Ŗą„‡ą¤øą¤° (ą¤Ŗą„ą¤°ą¤¤ą„ą¤Æą„‡ą¤• ą¤µą„‰ą¤Ÿą¤°ą¤®ą¤¾ą¤°ą„ą¤• ą¤•ą„‡ ą¤¬ą„€ą¤š ą¤•ą„ą¤·ą„ˆą¤¤ą¤æą¤œ अंतर):", + "6": "ą¤Šą¤‚ą¤šą¤¾ą¤ˆ ą¤øą„ą¤Ŗą„‡ą¤øą¤° (ą¤Ŗą„ą¤°ą¤¤ą„ą¤Æą„‡ą¤• ą¤µą„‰ą¤Ÿą¤°ą¤®ą¤¾ą¤°ą„ą¤• ą¤•ą„‡ ą¤¬ą„€ą¤š ą¤Šą¤°ą„ą¤§ą„ą¤µą¤¾ą¤§ą¤° अंतर):", + "7": "ą¤…ą¤Ŗą¤¾ą¤°ą¤¦ą¤°ą„ą¤¶ą¤æą¤¤ą¤¾ (0% - 100%):", + "8": "ą¤µą„‰ą¤Ÿą¤°ą¤®ą¤¾ą¤°ą„ą¤• ą¤Ŗą„ą¤°ą¤•ą¤¾ą¤°:", + "9": "ą¤µą„‰ą¤Ÿą¤°ą¤®ą¤¾ą¤°ą„ą¤• छवि:", + "10": "PDF ą¤•ą„‹ PDF-छवि ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "submit": "ą¤µą„‰ą¤Ÿą¤°ą¤®ą¤¾ą¤°ą„ą¤• ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "type": { + "1": "ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ", + "2": "छवि" + } + }, + "permissions": { + "tags": "ą¤Ŗą¤¢ą¤¼ą„‡ą¤‚,ą¤²ą¤æą¤–ą„‡ą¤‚,संपादित ą¤•ą¤°ą„‡ą¤‚,ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿ", + "title": "ą¤…ą¤Øą„ą¤®ą¤¤ą¤æą¤Æą¤¾ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "header": "ą¤…ą¤Øą„ą¤®ą¤¤ą¤æą¤Æą¤¾ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "warning": "ą¤šą„‡ą¤¤ą¤¾ą¤µą¤Øą„€: इन ą¤…ą¤Øą„ą¤®ą¤¤ą¤æą¤Æą„‹ą¤‚ ą¤•ą„‹ ą¤…ą¤Ŗą¤°ą¤æą¤µą¤°ą„ą¤¤ą¤Øą„€ą¤Æ ą¤¬ą¤Øą¤¾ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤, ą¤‡ą¤Øą„ą¤¹ą„‡ą¤‚ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤œą„‹ą¤”ą¤¼ą¤Øą„‡ ą¤µą¤¾ą¤²ą„‡ ą¤Ŗą„ƒą¤·ą„ą¤  ą¤•ą„‡ ą¤®ą¤¾ą¤§ą„ą¤Æą¤® ą¤øą„‡ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤•ą„‡ साऄ ą¤øą„‡ą¤Ÿ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„€ सिफारिश ą¤•ą„€ ą¤œą¤¾ą¤¤ą„€ ą¤¹ą„ˆ", + "selectText": { + "1": "ą¤…ą¤Øą„ą¤®ą¤¤ą¤æą¤Æą¤¾ą¤‚ ą¤¬ą¤¦ą¤²ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ PDF ą¤šą„ą¤Øą„‡ą¤‚", + "2": "ą¤øą„‡ą¤Ÿ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤…ą¤Øą„ą¤®ą¤¤ą¤æą¤Æą¤¾ą¤‚", + "3": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤…ą¤øą„‡ą¤‚ą¤¬ą¤²ą„€ ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "4": "ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€ ą¤Øą¤æą¤·ą„ą¤•ą¤°ą„ą¤·ą¤£ ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "5": "ą¤Ŗą¤¹ą„ą¤‚ą¤š ą¤Æą„‹ą¤—ą„ą¤Æą¤¤ą¤¾ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Øą¤æą¤·ą„ą¤•ą¤°ą„ą¤·ą¤£ ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "6": "ą¤«ą„‰ą¤°ą„ą¤® ą¤­ą¤°ą¤Øą„‡ ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "7": "ą¤øą¤‚ą¤¶ą„‹ą¤§ą¤Ø ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "8": "ą¤Ÿą¤æą¤Ŗą„ą¤Ŗą¤£ą„€ ą¤øą¤‚ą¤¶ą„‹ą¤§ą¤Ø ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "9": "ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿą¤æą¤‚ą¤— ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "10": "ą¤µą¤æą¤­ą¤æą¤Øą„ą¤Ø ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗą„‹ą¤‚ ą¤®ą„‡ą¤‚ ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿą¤æą¤‚ą¤— ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚" + }, + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "removePages": { + "tags": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚,ą¤Ŗą„ƒą¤·ą„ą¤  ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "addPassword": { + "tags": "ą¤øą„ą¤°ą¤•ą„ą¤·ą¤æą¤¤,ą¤øą„ą¤°ą¤•ą„ą¤·ą¤¾", + "title": "ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "header": "ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚ (ą¤ą¤Øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ)", + "selectText": { + "1": "ą¤ą¤Øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ PDF ą¤šą„ą¤Øą„‡ą¤‚", + "2": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤”", + "3": "ą¤ą¤Øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤¶ą¤Ø ą¤•ą„ą¤‚ą¤œą„€ ą¤²ą¤‚ą¤¬ą¤¾ą¤ˆ", + "4": "ą¤‰ą¤šą„ą¤š मान अधिक ą¤®ą¤œą¤¬ą„‚ą¤¤ ą¤¹ą„ˆą¤‚, ą¤²ą„‡ą¤•ą¤æą¤Ø ą¤Øą¤æą¤®ą„ą¤Ø मान ą¤¬ą„‡ą¤¹ą¤¤ą¤° संगतता ą¤°ą¤–ą¤¤ą„‡ ą¤¹ą„ˆą¤‚ą„¤", + "5": "ą¤øą„‡ą¤Ÿ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤…ą¤Øą„ą¤®ą¤¤ą¤æą¤Æą¤¾ą¤‚ (ą¤øą„ą¤µą¤¾ą¤®ą„€ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤•ą„‡ साऄ ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤Øą„‡ ą¤•ą„€ सिफारिश ą¤•ą„€ ą¤œą¤¾ą¤¤ą„€ ą¤¹ą„ˆ)", + "6": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤…ą¤øą„‡ą¤‚ą¤¬ą¤²ą„€ ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "7": "ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€ ą¤Øą¤æą¤·ą„ą¤•ą¤°ą„ą¤·ą¤£ ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "8": "ą¤Ŗą¤¹ą„ą¤‚ą¤š ą¤Æą„‹ą¤—ą„ą¤Æą¤¤ą¤¾ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Øą¤æą¤·ą„ą¤•ą¤°ą„ą¤·ą¤£ ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "9": "ą¤«ą„‰ą¤°ą„ą¤® ą¤­ą¤°ą¤Øą„‡ ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "10": "ą¤øą¤‚ą¤¶ą„‹ą¤§ą¤Ø ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "11": "ą¤Ÿą¤æą¤Ŗą„ą¤Ŗą¤£ą„€ ą¤øą¤‚ą¤¶ą„‹ą¤§ą¤Ø ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "12": "ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿą¤æą¤‚ą¤— ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "13": "ą¤µą¤æą¤­ą¤æą¤Øą„ą¤Ø ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗą„‹ą¤‚ ą¤®ą„‡ą¤‚ ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿą¤æą¤‚ą¤— ą¤•ą„‹ ą¤°ą„‹ą¤•ą„‡ą¤‚", + "14": "ą¤øą„ą¤µą¤¾ą¤®ą„€ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤”", + "15": "ą¤ą¤• बार ą¤–ą„ą¤²ą¤Øą„‡ ą¤•ą„‡ बाद ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤•ą„‡ साऄ ą¤•ą„ą¤Æą¤¾ किया जा सकता ą¤¹ą„ˆ ą¤•ą„‹ ą¤Ŗą„ą¤°ą¤¤ą¤æą¤¬ą¤‚ą¤§ą¤æą¤¤ करता ą¤¹ą„ˆ (ą¤øą¤­ą„€ ą¤Ŗą¤¾ą¤ ą¤•ą„‹ą¤‚ ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ ą¤øą¤®ą¤°ą„ą¤„ą¤æą¤¤ ą¤Øą¤¹ą„€ą¤‚)", + "16": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤•ą„‹ ą¤–ą„‹ą¤²ą¤Øą„‡ ą¤•ą„‹ ą¤Ŗą„ą¤°ą¤¤ą¤æą¤¬ą¤‚ą¤§ą¤æą¤¤ करता ą¤¹ą„ˆ" + }, + "submit": "ą¤ą¤Øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ ą¤•ą¤°ą„‡ą¤‚" + }, + "removePassword": { + "tags": "ą¤øą„ą¤°ą¤•ą„ą¤·ą¤æą¤¤,ą¤”ą¤æą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ,ą¤øą„ą¤°ą¤•ą„ą¤·ą¤¾,ą¤…ą¤Øą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤”,ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "title": "ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "header": "ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤¹ą¤Ÿą¤¾ą¤ą¤‚ (ą¤”ą¤æą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ)", + "selectText": { + "1": "ą¤”ą¤æą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ PDF ą¤šą„ą¤Øą„‡ą¤‚", + "2": "ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤”" + }, + "submit": "ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "compressPdfs": { + "tags": "ą¤•ą¤®ą„ą¤Ŗą„ą¤°ą„‡ą¤ø,ą¤›ą„‹ą¤Ÿą¤¾,ą¤›ą„‹ą¤Ÿą¤¾" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "ą¤¶ą„€ą¤°ą„ą¤·ą¤•,ą¤²ą„‡ą¤–ą¤•,तिऄि,ą¤Øą¤æą¤°ą„ą¤®ą¤¾ą¤£,समय,ą¤Ŗą„ą¤°ą¤•ą¤¾ą¤¶ą¤•,ą¤Øą¤æą¤°ą„ą¤®ą¤¾ą¤¤ą¤¾,ą¤†ą¤‚ą¤•ą¤”ą¤¼ą„‡", + "title": "ą¤¶ą„€ą¤°ą„ą¤·ą¤•:", + "header": "ą¤®ą„‡ą¤Ÿą¤¾ą¤”ą„‡ą¤Ÿą¤¾ ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "selectText": { + "1": "ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤µą„‡ चर संपादित ą¤•ą¤°ą„‡ą¤‚ ą¤œą¤æą¤Øą„ą¤¹ą„‡ą¤‚ आप बदलना ą¤šą¤¾ą¤¹ą¤¤ą„‡ ą¤¹ą„ˆą¤‚", + "2": "ą¤øą¤­ą„€ ą¤®ą„‡ą¤Ÿą¤¾ą¤”ą„‡ą¤Ÿą¤¾ ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "3": "ą¤•ą¤øą„ą¤Ÿą¤® ą¤®ą„‡ą¤Ÿą¤¾ą¤”ą„‡ą¤Ÿą¤¾ ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚:", + "4": "ą¤…ą¤Øą„ą¤Æ ą¤®ą„‡ą¤Ÿą¤¾ą¤”ą„‡ą¤Ÿą¤¾:", + "5": "ą¤•ą¤øą„ą¤Ÿą¤® ą¤®ą„‡ą¤Ÿą¤¾ą¤”ą„‡ą¤Ÿą¤¾ ą¤Ŗą„ą¤°ą¤µą¤æą¤·ą„ą¤Ÿą¤æ ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚" + }, + "author": "ą¤²ą„‡ą¤–ą¤•:", + "creationDate": "ą¤Øą¤æą¤°ą„ą¤®ą¤¾ą¤£ तिऄि (yyyy/MM/dd HH:mm:ss):", + "creator": "ą¤Øą¤æą¤°ą„ą¤®ą¤¾ą¤¤ą¤¾:", + "keywords": "ą¤•ą„€ą¤µą¤°ą„ą¤”ą„ą¤ø:", + "modDate": "ą¤øą¤‚ą¤¶ą„‹ą¤§ą¤Ø तिऄि (yyyy/MM/dd HH:mm:ss):", + "producer": "ą¤Ŗą„ą¤°ą„‹ą¤”ą„ą¤Æą„‚ą¤øą¤°:", + "subject": "विषय:", + "trapped": "ą¤Ÿą„ą¤°ą„ˆą¤Ŗą„ą¤”:", + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "fileToPDF": { + "tags": "ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£,ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ,ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œ,ą¤šą¤æą¤¤ą„ą¤°,ą¤øą„ą¤²ą¤¾ą¤‡ą¤”,ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ,ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£,ą¤•ą¤¾ą¤°ą„ą¤Æą¤¾ą¤²ą¤Æ,ą¤”ą„‰ą¤•ą„ą¤ø,ą¤µą¤°ą„ą¤”,ą¤ą¤•ą„ą¤øą„‡ą¤²,ą¤Ŗą¤¾ą¤µą¤°ą¤Ŗą„‰ą¤‡ą¤‚ą¤Ÿ", + "title": "फ़ाइल ą¤øą„‡ PDF", + "header": "ą¤•ą¤æą¤øą„€ ą¤­ą„€ फ़ाइल ą¤•ą„‹ PDF ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "credit": "यह ą¤øą„‡ą¤µą¤¾ फ़ाइल ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£ ą¤•ą„‡ ą¤²ą¤æą¤ LibreOffice और Unoconv का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤¤ą„€ ą¤¹ą„ˆą„¤", + "supportedFileTypesInfo": "ą¤øą¤®ą¤°ą„ą¤„ą¤æą¤¤ फ़ाइल ą¤Ŗą„ą¤°ą¤•ą¤¾ą¤°", + "supportedFileTypes": "ą¤øą¤®ą¤°ą„ą¤„ą¤æą¤¤ फ़ाइल ą¤Ŗą„ą¤°ą¤•ą¤¾ą¤°ą„‹ą¤‚ ą¤®ą„‡ą¤‚ ą¤Øą¤æą¤®ą„ą¤Øą¤²ą¤æą¤–ą¤æą¤¤ शामिल ą¤¹ą„‹ą¤Øą„‡ ą¤šą¤¾ą¤¹ą¤æą¤, हालांकि ą¤øą¤®ą¤°ą„ą¤„ą¤æą¤¤ ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗą„‹ą¤‚ ą¤•ą„€ ą¤Ŗą„‚ą¤°ą„ą¤£ ą¤…ą¤¦ą„ą¤Æą¤¤ą¤Ø ą¤øą„‚ą¤šą„€ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤•ą„ƒą¤Ŗą¤Æą¤¾ LibreOffice ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ą„€ą¤•ą¤°ą¤£ ą¤¦ą„‡ą¤–ą„‡ą¤‚", + "submit": "PDF ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "ocr": { + "tags": "पहचान,ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ,छवि,ą¤øą„ą¤•ą„ˆą¤Ø,ą¤Ŗą¤¢ą¤¼ą„‡ą¤‚,ą¤Ŗą¤¹ą¤šą¤¾ą¤Øą„‡ą¤‚,पहचान,संपादन ą¤Æą„‹ą¤—ą„ą¤Æ", + "title": "OCR / ą¤øą„ą¤•ą„ˆą¤Ø साफ ą¤•ą¤°ą„‡ą¤‚", + "header": "ą¤øą„ą¤•ą„ˆą¤Ø साफ ą¤•ą¤°ą„‡ą¤‚ / OCR (ą¤‘ą¤Ŗą„ą¤Ÿą¤æą¤•ą¤² ą¤•ą„ˆą¤°ą„‡ą¤•ą„ą¤Ÿą¤° ą¤°ą¤æą¤•ą¤—ą„ą¤Øą¤æą¤¶ą¤Ø)", + "selectText": { + "1": "PDF ą¤®ą„‡ą¤‚ पता ą¤²ą¤—ą¤¾ą¤ ą¤œą¤¾ą¤Øą„‡ ą¤µą¤¾ą¤²ą„€ ą¤­ą¤¾ą¤·ą¤¾ą¤ą¤‚ ą¤šą„ą¤Øą„‡ą¤‚ (ą¤œą„‹ ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤®ą„‡ą¤‚ पता ą¤²ą¤—ą¤¾ą¤ˆ ą¤—ą¤ˆ ą¤¹ą„ˆą¤‚ ą¤‰ą¤Øą„ą¤¹ą„‡ą¤‚ ą¤øą„‚ą¤šą„€ą¤¬ą¤¦ą„ą¤§ किया गया ą¤¹ą„ˆ):", + "2": "OCR ą¤•ą¤æą¤ ą¤—ą¤ PDF ą¤•ą„‡ साऄ OCR ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤Æą„ą¤•ą„ą¤¤ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ फ़ाइल ą¤¬ą¤Øą¤¾ą¤ą¤‚", + "3": "ą¤Ÿą„‡ą¤¢ą¤¼ą„‡ ą¤•ą„‹ą¤£ पर ą¤øą„ą¤•ą„ˆą¤Ø ą¤•ą¤æą¤ ą¤—ą¤ ą¤Ŗą„ƒą¤·ą„ą¤ ą„‹ą¤‚ ą¤•ą„‹ ą¤‰ą¤Øą„ą¤¹ą„‡ą¤‚ वापस ą¤øą„ą¤„ą¤¾ą¤Ø पर ą¤˜ą„ą¤®ą¤¾ą¤•ą¤° ą¤øą¤¹ą„€ ą¤•ą¤°ą„‡ą¤‚", + "4": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤•ą„‹ साफ ą¤•ą¤°ą„‡ą¤‚ ताकि OCR ą¤Ŗą„ƒą¤·ą„ą¤ ą¤­ą„‚ą¤®ą¤æ ą¤¶ą„‹ą¤° ą¤®ą„‡ą¤‚ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤¢ą„‚ą¤‚ą¤¢ą¤Øą„‡ ą¤•ą„€ संभावना कम ą¤¹ą„‹ą„¤ (ą¤•ą„‹ą¤ˆ ą¤†ą¤‰ą¤Ÿą¤Ŗą„ą¤Ÿ ą¤Ŗą¤°ą¤æą¤µą¤°ą„ą¤¤ą¤Ø ą¤Øą¤¹ą„€ą¤‚)", + "5": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤•ą„‹ साफ ą¤•ą¤°ą„‡ą¤‚ ताकि OCR ą¤Ŗą„ƒą¤·ą„ą¤ ą¤­ą„‚ą¤®ą¤æ ą¤¶ą„‹ą¤° ą¤®ą„‡ą¤‚ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤¢ą„‚ą¤‚ą¤¢ą¤Øą„‡ ą¤•ą„€ संभावना कम ą¤¹ą„‹, ą¤†ą¤‰ą¤Ÿą¤Ŗą„ą¤Ÿ ą¤®ą„‡ą¤‚ सफाई ą¤¬ą¤Øą¤¾ą¤ ą¤°ą¤–ą„‡ą¤‚ą„¤", + "6": "ą¤‡ą¤‚ą¤Ÿą¤°ą„ˆą¤•ą„ą¤Ÿą¤æą¤µ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤µą¤¾ą¤²ą„‡ ą¤Ŗą„ƒą¤·ą„ą¤ ą„‹ą¤‚ ą¤•ą„‹ ą¤›ą„‹ą¤”ą¤¼ ą¤¦ą„‡ą¤‚, ą¤•ą„‡ą¤µą¤² छवि ą¤µą¤¾ą¤²ą„‡ ą¤Ŗą„ƒą¤·ą„ą¤ ą„‹ą¤‚ पर OCR ą¤•ą¤°ą„‡ą¤‚", + "7": "बल OCR, ą¤Ŗą„ą¤°ą¤¤ą„ą¤Æą„‡ą¤• ą¤Ŗą„ƒą¤·ą„ą¤  पर OCR ą¤•ą¤°ą„‡ą¤—ą¤¾ ą¤øą¤­ą„€ ą¤®ą„‚ą¤² ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤¤ą¤¤ą„ą¤µą„‹ą¤‚ ą¤•ą„‹ हटा ą¤¦ą„‡ą¤—ą¤¾", + "8": "ą¤øą¤¾ą¤®ą¤¾ą¤Øą„ą¤Æ (यदि PDF ą¤®ą„‡ą¤‚ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤¹ą„ˆ ą¤¤ą„‹ ą¤¤ą„ą¤°ą„ą¤Ÿą¤æ ą¤¹ą„‹ą¤—ą„€)", + "9": "ą¤…ą¤¤ą¤æą¤°ą¤æą¤•ą„ą¤¤ ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø", + "10": "OCR ą¤®ą„‹ą¤”", + "11": "OCR ą¤•ą„‡ बाद छवियां ą¤¹ą¤Ÿą¤¾ą¤ą¤‚ (ą¤øą¤­ą„€ छवियां ą¤¹ą¤Ÿą¤¾ą¤ą¤‚, ą¤•ą„‡ą¤µą¤² ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£ चरण का ą¤¹ą¤æą¤øą„ą¤øą¤¾ ą¤¹ą„‹ą¤Øą„‡ पर ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą„€)", + "12": "ą¤°ą„‡ą¤‚ą¤”ą¤° ą¤Ŗą„ą¤°ą¤•ą¤¾ą¤° (ą¤‰ą¤Øą„ą¤Øą¤¤)" + }, + "help": "ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤…ą¤Øą„ą¤Æ भाषाओं ą¤•ą„‡ ą¤²ą¤æą¤ ą¤‰ą¤Ŗą¤Æą„‹ą¤— और/या ą¤”ą„‰ą¤•ą¤° ą¤®ą„‡ą¤‚ ą¤‰ą¤Ŗą¤Æą„‹ą¤— न ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤¬ą¤¾ą¤°ą„‡ ą¤®ą„‡ą¤‚ यह ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ą„€ą¤•ą¤°ą¤£ ą¤Ŗą¤¢ą¤¼ą„‡ą¤‚", + "credit": "यह ą¤øą„‡ą¤µą¤¾ OCR ą¤•ą„‡ ą¤²ą¤æą¤ qpdf और Tesseract का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤¤ą„€ ą¤¹ą„ˆą„¤", + "submit": "OCR ą¤•ą„‡ साऄ PDF ą¤Ŗą„ą¤°ą„‹ą¤øą„‡ą¤ø ą¤•ą¤°ą„‡ą¤‚" + }, + "extractImages": { + "tags": "ą¤šą¤æą¤¤ą„ą¤°,ą¤«ą„‹ą¤Ÿą„‹,ą¤øą¤¹ą„‡ą¤œą„‡ą¤‚,ą¤øą¤‚ą¤—ą„ą¤°ą¤¹,ज़िप,ą¤•ą„ˆą¤Ŗą„ą¤šą¤°,ą¤—ą„ą¤°ą„ˆą¤¬", + "title": "छवियां ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚", + "header": "छवियां ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚", + "selectText": "ą¤Øą¤æą¤•ą¤¾ą¤²ą„€ ą¤—ą¤ˆ ą¤›ą¤µą¤æą¤Æą„‹ą¤‚ ą¤•ą„‹ ą¤¬ą¤¦ą¤²ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ छवि ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ ą¤šą„ą¤Øą„‡ą¤‚", + "allowDuplicates": "ą¤”ą„ą¤Ŗą„ą¤²ą¤æą¤•ą„‡ą¤Ÿ छवियां ą¤øą¤¹ą„‡ą¤œą„‡ą¤‚", + "submit": "ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚" + }, + "pdfToPDFA": { + "tags": "ą¤øą¤‚ą¤—ą„ą¤°ą¤¹,ą¤²ą¤‚ą¤¬ą„€ अवधि,मानक,ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£,भंऔारण,ą¤øą¤‚ą¤°ą¤•ą„ą¤·ą¤£", + "title": "PDF ą¤øą„‡ PDF/A", + "header": "PDF ą¤øą„‡ PDF/A", + "credit": "यह ą¤øą„‡ą¤µą¤¾ PDF/A ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£ ą¤•ą„‡ ą¤²ą¤æą¤ libreoffice का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤¤ą„€ ą¤¹ą„ˆ", + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "tip": "ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤®ą„‡ą¤‚ ą¤ą¤• बार ą¤®ą„‡ą¤‚ ą¤•ą¤ˆ ą¤‡ą¤Øą¤Ŗą„ą¤Ÿ ą¤•ą„‡ ą¤²ą¤æą¤ काम ą¤Øą¤¹ą„€ą¤‚ करता", + "outputFormat": "ą¤†ą¤‰ą¤Ÿą¤Ŗą„ą¤Ÿ ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ", + "pdfWithDigitalSignature": "PDF ą¤®ą„‡ą¤‚ ą¤ą¤• औिजिटल ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤¹ą„ˆą„¤ यह ą¤…ą¤—ą¤²ą„‡ चरण ą¤®ą„‡ą¤‚ हटा दिया ą¤œą¤¾ą¤ą¤—ą¤¾ą„¤" + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£,ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ,ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£,ą¤•ą¤¾ą¤°ą„ą¤Æą¤¾ą¤²ą¤Æ,ą¤®ą¤¾ą¤‡ą¤•ą„ą¤°ą„‹ą¤øą„‰ą¤«ą„ą¤Ÿ,docfile", + "title": "PDF ą¤øą„‡ Word", + "header": "PDF ą¤øą„‡ Word", + "selectText": { + "1": "ą¤†ą¤‰ą¤Ÿą¤Ŗą„ą¤Ÿ फ़ाइल ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ" + }, + "credit": "यह ą¤øą„‡ą¤µą¤¾ फ़ाइल ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£ ą¤•ą„‡ ą¤²ą¤æą¤ LibreOffice का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤¤ą„€ ą¤¹ą„ˆą„¤", + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "PDFToPresentation": { + "tags": "ą¤øą„ą¤²ą¤¾ą¤‡ą¤”ą„ą¤ø,ą¤¶ą„‹,ą¤•ą¤¾ą¤°ą„ą¤Æą¤¾ą¤²ą¤Æ,ą¤®ą¤¾ą¤‡ą¤•ą„ą¤°ą„‹ą¤øą„‰ą¤«ą„ą¤Ÿ", + "title": "PDF ą¤øą„‡ ą¤Ŗą„ą¤°ą¤øą„ą¤¤ą„ą¤¤ą¤æ", + "header": "PDF ą¤øą„‡ ą¤Ŗą„ą¤°ą¤øą„ą¤¤ą„ą¤¤ą¤æ", + "selectText": { + "1": "ą¤†ą¤‰ą¤Ÿą¤Ŗą„ą¤Ÿ फ़ाइल ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ" + }, + "credit": "यह ą¤øą„‡ą¤µą¤¾ फ़ाइल ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£ ą¤•ą„‡ ą¤²ą¤æą¤ LibreOffice का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤¤ą„€ ą¤¹ą„ˆą„¤", + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "PDFToText": { + "tags": "रिच ą¤«ą„‰ą¤°ą„ą¤®ą„‡ą¤Ÿ,रिच ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤«ą„‰ą¤°ą„ą¤®ą„‡ą¤Ÿ,रिच ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤«ą„‰ą¤°ą„ą¤®ą„‡ą¤Ÿ", + "title": "PDF ą¤øą„‡ RTF (ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ)", + "header": "PDF ą¤øą„‡ RTF (ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ)", + "selectText": { + "1": "ą¤†ą¤‰ą¤Ÿą¤Ŗą„ą¤Ÿ फ़ाइल ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ" + }, + "credit": "यह ą¤øą„‡ą¤µą¤¾ फ़ाइल ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£ ą¤•ą„‡ ą¤²ą¤æą¤ LibreOffice का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤¤ą„€ ą¤¹ą„ˆą„¤", + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "PDFToHTML": { + "tags": "ą¤µą„‡ą¤¬ ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€,ą¤¬ą„ą¤°ą¤¾ą¤‰ą¤œą¤¼ą¤° ą¤…ą¤Øą„ą¤•ą„‚ą¤²", + "title": "PDF ą¤øą„‡ HTML", + "header": "PDF ą¤øą„‡ HTML", + "credit": "यह ą¤øą„‡ą¤µą¤¾ फ़ाइल ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£ ą¤•ą„‡ ą¤²ą¤æą¤ pdftohtml का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤¤ą„€ ą¤¹ą„ˆą„¤", + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "PDFToXML": { + "tags": "ą¤”ą„‡ą¤Ÿą¤¾-ą¤Øą¤æą¤·ą„ą¤•ą¤°ą„ą¤·ą¤£,ą¤øą¤‚ą¤°ą¤šą¤æą¤¤-ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€,अंतर-ą¤øą¤‚ą¤šą¤¾ą¤²ą¤Ø,ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£,ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "title": "PDF ą¤øą„‡ XML", + "header": "PDF ą¤øą„‡ XML", + "credit": "यह ą¤øą„‡ą¤µą¤¾ फ़ाइल ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£ ą¤•ą„‡ ą¤²ą¤æą¤ LibreOffice का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤¤ą„€ ą¤¹ą„ˆą„¤", + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "ScannerImageSplit": { + "tags": "अलग ą¤•ą¤°ą„‡ą¤‚,ą¤øą„ą¤µą¤¤:-पहचान,ą¤øą„ą¤•ą„ˆą¤Ø-खंऔ,ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "selectText": { + "1": "ą¤•ą„‹ą¤£ ą¤øą„€ą¤®ą¤¾:", + "2": "छवि ą¤•ą„‹ ą¤˜ą„ą¤®ą¤¾ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤†ą¤µą¤¶ą„ą¤Æą¤• ą¤Øą„ą¤Æą„‚ą¤Øą¤¤ą¤® ą¤øą¤¾ą¤Ŗą„‡ą¤•ą„ą¤· ą¤•ą„‹ą¤£ ą¤Øą¤æą¤°ą„ą¤§ą¤¾ą¤°ą¤æą¤¤ करता ą¤¹ą„ˆ (ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ: 10)ą„¤", + "3": "ą¤Ÿą„‰ą¤²ą¤°ą„‡ą¤‚ą¤ø:", + "4": "ą¤…ą¤Øą„ą¤®ą¤¾ą¤Øą¤æą¤¤ ą¤Ŗą„ƒą¤·ą„ą¤ ą¤­ą„‚ą¤®ą¤æ रंग ą¤•ą„‡ आसपास रंग विविधता ą¤•ą„€ ą¤øą„€ą¤®ą¤¾ ą¤Øą¤æą¤°ą„ą¤§ą¤¾ą¤°ą¤æą¤¤ करता ą¤¹ą„ˆ (ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ: 30)ą„¤", + "5": "ą¤Øą„ą¤Æą„‚ą¤Øą¤¤ą¤® ą¤•ą„ą¤·ą„‡ą¤¤ą„ą¤°:", + "6": "ą¤ą¤• ą¤«ą„‹ą¤Ÿą„‹ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Øą„ą¤Æą„‚ą¤Øą¤¤ą¤® ą¤•ą„ą¤·ą„‡ą¤¤ą„ą¤° ą¤øą„€ą¤®ą¤¾ ą¤Øą¤æą¤°ą„ą¤§ą¤¾ą¤°ą¤æą¤¤ करता ą¤¹ą„ˆ (ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ: 10000)ą„¤", + "7": "ą¤Øą„ą¤Æą„‚ą¤Øą¤¤ą¤® ą¤•ą¤‚ą¤Ÿą„‚ą¤° ą¤•ą„ą¤·ą„‡ą¤¤ą„ą¤°:", + "8": "ą¤ą¤• ą¤«ą„‹ą¤Ÿą„‹ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Øą„ą¤Æą„‚ą¤Øą¤¤ą¤® ą¤•ą¤‚ą¤Ÿą„‚ą¤° ą¤•ą„ą¤·ą„‡ą¤¤ą„ą¤° ą¤øą„€ą¤®ą¤¾ ą¤Øą¤æą¤°ą„ą¤§ą¤¾ą¤°ą¤æą¤¤ करता ą¤¹ą„ˆ", + "9": "ą¤¬ą„‰ą¤°ą„ą¤”ą¤° आकार:", + "10": "ą¤†ą¤‰ą¤Ÿą¤Ŗą„ą¤Ÿ ą¤®ą„‡ą¤‚ ą¤¶ą„ą¤µą„‡ą¤¤ ą¤¬ą„‰ą¤°ą„ą¤”ą¤° ą¤•ą„‹ ą¤°ą„‹ą¤•ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤œą„‹ą¤”ą¤¼ą„‡ और ą¤¹ą¤Ÿą¤¾ą¤ ą¤—ą¤ ą¤¬ą„‰ą¤°ą„ą¤”ą¤° का आकार ą¤Øą¤æą¤°ą„ą¤§ą¤¾ą¤°ą¤æą¤¤ करता ą¤¹ą„ˆ (ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ: 1)ą„¤" + }, + "info": "Python ą¤øą„ą¤„ą¤¾ą¤Ŗą¤æą¤¤ ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„ˆą„¤ ą¤šą¤²ą¤¾ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤†ą¤µą¤¶ą„ą¤Æą¤• ą¤¹ą„ˆą„¤" + }, + "sign": { + "tags": "ą¤…ą¤§ą¤æą¤•ą„ƒą¤¤,ą¤†ą¤¦ą„ą¤Æą¤¾ą¤•ą„ą¤·ą¤°,ą¤šą¤æą¤¤ą„ą¤°ą¤æą¤¤-ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°,ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ-ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°,छवि-ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°", + "title": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°", + "header": "PDF पर ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤•ą¤°ą„‡ą¤‚", + "upload": "छवि ą¤…ą¤Ŗą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚", + "draw": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤¬ą¤Øą¤¾ą¤ą¤‚", + "text": "ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤‡ą¤Øą¤Ŗą„ą¤Ÿ", + "clear": "साफ़ ą¤•ą¤°ą„‡ą¤‚", + "add": "ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "saved": "ą¤øą¤¹ą„‡ą¤œą„‡ ą¤—ą¤ ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°", + "save": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤øą¤¹ą„‡ą¤œą„‡ą¤‚", + "personalSigs": "ą¤µą„ą¤Æą¤•ą„ą¤¤ą¤æą¤—ą¤¤ ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°", + "sharedSigs": "ą¤øą¤¾ą¤ą¤¾ ą¤•ą¤æą¤ ą¤—ą¤ ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°", + "noSavedSigs": "ą¤•ą„‹ą¤ˆ ą¤øą¤¹ą„‡ą¤œą¤¾ गया ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤Øą¤¹ą„€ą¤‚ मिला", + "addToAll": "ą¤øą¤­ą„€ ą¤Ŗą„ƒą¤·ą„ą¤ ą„‹ą¤‚ ą¤®ą„‡ą¤‚ ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "delete": "ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "first": "पहला ą¤Ŗą„ƒą¤·ą„ą¤ ", + "last": "अंतिम ą¤Ŗą„ƒą¤·ą„ą¤ ", + "next": "अगला ą¤Ŗą„ƒą¤·ą„ą¤ ", + "previous": "पिछला ą¤Ŗą„ƒą¤·ą„ą¤ ", + "maintainRatio": "ą¤†ą¤Øą„ą¤Ŗą¤¾ą¤¤ą¤æą¤• ą¤…ą¤Øą„ą¤Ŗą¤¾ą¤¤ ą¤¬ą¤Øą¤¾ą¤ ą¤°ą¤–ą„‡ą¤‚ ą¤Ÿą„‰ą¤—ą¤² ą¤•ą¤°ą„‡ą¤‚", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "ą¤øą„ą¤„ą¤æą¤°,ą¤Øą¤æą¤·ą„ą¤•ą„ą¤°ą¤æą¤Æ,ą¤—ą„ˆą¤°-ą¤‡ą¤‚ą¤Ÿą¤°ą„ˆą¤•ą„ą¤Ÿą¤æą¤µ,ą¤øą¤°ą¤²ą„€ą¤•ą„ƒą¤¤", + "title": "समतल ą¤•ą¤°ą„‡ą¤‚", + "header": "PDF समतल ą¤•ą¤°ą„‡ą¤‚", + "flattenOnlyForms": "ą¤•ą„‡ą¤µą¤² ą¤«ą¤¼ą„‰ą¤°ą„ą¤® समतल ą¤•ą¤°ą„‡ą¤‚", + "submit": "समतल ą¤•ą¤°ą„‡ą¤‚" + }, + "repair": { + "tags": "ą¤ ą„€ą¤• ą¤•ą¤°ą„‡ą¤‚,ą¤Ŗą„ą¤Øą¤°ą„ą¤øą„ą¤„ą¤¾ą¤Ŗą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚,ą¤øą„ą¤§ą¤¾ą¤°,ą¤Ŗą„ą¤Øą¤°ą„ą¤Ŗą„ą¤°ą¤¾ą¤Ŗą„ą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "title": "ą¤®ą¤°ą¤®ą„ą¤®ą¤¤", + "header": "PDF ą¤®ą¤°ą¤®ą„ą¤®ą¤¤", + "submit": "ą¤®ą¤°ą¤®ą„ą¤®ą¤¤" + }, + "removeBlanks": { + "tags": "साफ ą¤•ą¤°ą„‡ą¤‚,ą¤øą¤°ą¤²ą„€ą¤•ą„ƒą¤¤ ą¤•ą¤°ą„‡ą¤‚,ą¤—ą„ˆą¤°-ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€,ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "title": "ą¤–ą¤¾ą¤²ą„€ ą¤Ŗą„ƒą¤·ą„ą¤  ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "header": "ą¤–ą¤¾ą¤²ą„€ ą¤Ŗą„ƒą¤·ą„ą¤  ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "threshold": "ą¤Ŗą¤æą¤•ą„ą¤øą„‡ą¤² ą¤¶ą„ą¤µą„‡ą¤¤ą¤¤ą¤¾ ą¤øą„€ą¤®ą¤¾:", + "thresholdDesc": "ą¤ą¤• ą¤¶ą„ą¤µą„‡ą¤¤ ą¤Ŗą¤æą¤•ą„ą¤øą„‡ą¤² ą¤•ą„‹ 'ą¤¶ą„ą¤µą„‡ą¤¤' ą¤µą¤°ą„ą¤—ą„€ą¤•ą„ƒą¤¤ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ कितना ą¤¶ą„ą¤µą„‡ą¤¤ ą¤¹ą„‹ą¤Øą¤¾ ą¤šą¤¾ą¤¹ą¤æą¤ यह ą¤Øą¤æą¤°ą„ą¤§ą¤¾ą¤°ą¤æą¤¤ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤øą„€ą¤®ą¤¾ą„¤ 0 = काला, 255 ą¤Ŗą„‚ą¤°ą„ą¤£ ą¤¶ą„ą¤µą„‡ą¤¤ą„¤", + "whitePercent": "ą¤¶ą„ą¤µą„‡ą¤¤ ą¤Ŗą„ą¤°ą¤¤ą¤æą¤¶ą¤¤ (%):", + "whitePercentDesc": "ą¤¹ą¤Ÿą¤¾ą¤ ą¤œą¤¾ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Ŗą„ƒą¤·ą„ą¤  का कितना ą¤Ŗą„ą¤°ą¤¤ą¤æą¤¶ą¤¤ 'ą¤¶ą„ą¤µą„‡ą¤¤' ą¤Ŗą¤æą¤•ą„ą¤øą„‡ą¤² ą¤¹ą„‹ą¤Øą¤¾ ą¤šą¤¾ą¤¹ą¤æą¤", + "submit": "ą¤–ą¤¾ą¤²ą„€ ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "removeAnnotations": { + "tags": "ą¤Ÿą¤æą¤Ŗą„ą¤Ŗą¤£ą¤æą¤Æą¤¾ą¤‚,ą¤¹ą¤¾ą¤‡ą¤²ą¤¾ą¤‡ą¤Ÿ,ą¤Øą„‹ą¤Ÿą„ą¤ø,ą¤®ą¤¾ą¤°ą„ą¤•ą¤…ą¤Ŗ,ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "title": "ą¤Ÿą¤æą¤Ŗą„ą¤Ŗą¤£ą¤æą¤Æą¤¾ą¤‚ ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "header": "ą¤Ÿą¤æą¤Ŗą„ą¤Ŗą¤£ą¤æą¤Æą¤¾ą¤‚ ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "submit": "ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "compare": { + "tags": "अंतर,ą¤¤ą„ą¤²ą¤Øą¤¾,ą¤Ŗą¤°ą¤æą¤µą¤°ą„ą¤¤ą¤Ø,ą¤µą¤æą¤¶ą„ą¤²ą„‡ą¤·ą¤£", + "title": "ą¤¤ą„ą¤²ą¤Øą¤¾ ą¤•ą¤°ą„‡ą¤‚", + "header": "PDF ą¤¤ą„ą¤²ą¤Øą¤¾ ą¤•ą¤°ą„‡ą¤‚", + "highlightColor": { + "1": "ą¤¹ą¤¾ą¤‡ą¤²ą¤¾ą¤‡ą¤Ÿ रंग 1:", + "2": "ą¤¹ą¤¾ą¤‡ą¤²ą¤¾ą¤‡ą¤Ÿ रंग 2:" + }, + "document": { + "1": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ 1", + "2": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ 2" + }, + "submit": "ą¤¤ą„ą¤²ą¤Øą¤¾ ą¤•ą¤°ą„‡ą¤‚", + "complex": { + "message": "ą¤Ŗą„ą¤°ą¤¦ą¤¾ą¤Ø ą¤•ą¤æą¤ ą¤—ą¤ ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą„‹ą¤‚ ą¤®ą„‡ą¤‚ ą¤øą„‡ ą¤ą¤• या ą¤¦ą„‹ą¤Øą„‹ą¤‚ ą¤¬ą¤”ą¤¼ą„‡ फ़ाइल ą¤¹ą„ˆą¤‚, ą¤¤ą„ą¤²ą¤Øą¤¾ ą¤•ą„€ ą¤øą¤Ÿą„€ą¤•ą¤¤ą¤¾ कम ą¤¹ą„‹ ą¤øą¤•ą¤¤ą„€ ą¤¹ą„ˆ" + }, + "large": { + "file": { + "message": "ą¤Ŗą„ą¤°ą¤¦ą¤¾ą¤Ø ą¤•ą¤æą¤ ą¤—ą¤ ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą„‹ą¤‚ ą¤®ą„‡ą¤‚ ą¤øą„‡ ą¤ą¤• या ą¤¦ą„‹ą¤Øą„‹ą¤‚ ą¤Ŗą„ą¤°ą¤•ą„ą¤°ą¤æą¤Æą¤¾ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤¬ą¤¹ą„ą¤¤ ą¤¬ą¤”ą¤¼ą„‡ ą¤¹ą„ˆą¤‚" + } + }, + "no": { + "text": { + "message": "चयनित PDF ą¤®ą„‡ą¤‚ ą¤øą„‡ ą¤ą¤• या ą¤¦ą„‹ą¤Øą„‹ą¤‚ ą¤®ą„‡ą¤‚ ą¤•ą„‹ą¤ˆ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€ ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„ˆą„¤ ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤¤ą„ą¤²ą¤Øą¤¾ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤µą¤¾ą¤²ą„‡ PDF ą¤šą„ą¤Øą„‡ą¤‚ą„¤" + } + } + }, + "certSign": { + "tags": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą„€ą¤•ą¤°ą¤£,PEM,P12,आधिकारिक,ą¤ą¤Øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ", + "title": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°", + "header": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤øą„‡ ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤•ą¤°ą„‡ą¤‚ (ą¤•ą¤¾ą¤°ą„ą¤Æ ą¤Ŗą„ą¤°ą¤—ą¤¤ą¤æ पर ą¤¹ą„ˆ)", + "selectPDF": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤•ą„‡ ą¤²ą¤æą¤ PDF फ़ाइल ą¤šą„ą¤Øą„‡ą¤‚:", + "jksNote": "ą¤Øą„‹ą¤Ÿ: यदि ą¤†ą¤Ŗą¤•ą„‡ ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° का ą¤Ŗą„ą¤°ą¤•ą¤¾ą¤° ą¤Øą„€ą¤šą„‡ ą¤øą„‚ą¤šą„€ą¤¬ą¤¦ą„ą¤§ ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„ˆ, ą¤¤ą„‹ ą¤•ą„ƒą¤Ŗą¤Æą¤¾ keytool कमांऔ लाइन ą¤Ÿą„‚ą¤² का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤•ą„‡ ą¤‡ą¤øą„‡ Java Keystore (.jks) फ़ाइल ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚ą„¤ फिर ą¤Øą„€ą¤šą„‡ .jks फ़ाइल ą¤µą¤æą¤•ą¤²ą„ą¤Ŗ ą¤šą„ą¤Øą„‡ą¤‚ą„¤", + "selectKey": "ą¤…ą¤Ŗą¤Øą„€ ą¤Øą¤æą¤œą„€ ą¤•ą„ą¤‚ą¤œą„€ फ़ाइल ą¤šą„ą¤Øą„‡ą¤‚ (PKCS#8 ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ, .pem या .der ą¤¹ą„‹ ą¤øą¤•ą¤¤ą„€ ą¤¹ą„ˆ):", + "selectCert": "अपना ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° फ़ाइल ą¤šą„ą¤Øą„‡ą¤‚ (X.509 ą¤Ŗą„ą¤°ą¤¾ą¤°ą„‚ą¤Ŗ, .pem या .der ą¤¹ą„‹ ą¤øą¤•ą¤¤ą„€ ą¤¹ą„ˆ):", + "selectP12": "ą¤…ą¤Ŗą¤Øą„€ PKCS#12 ą¤•ą„€ą¤øą„ą¤Ÿą„‹ą¤° फ़ाइल ą¤šą„ą¤Øą„‡ą¤‚ (.p12 या .pfx) (ą¤µą„ˆą¤•ą¤²ą„ą¤Ŗą¤æą¤•, यदि ą¤Ŗą„ą¤°ą¤¦ą¤¾ą¤Ø ą¤•ą„€ ą¤—ą¤ˆ ą¤¹ą„ˆ, ą¤¤ą„‹ ą¤‡ą¤øą¤®ą„‡ą¤‚ ą¤†ą¤Ŗą¤•ą„€ ą¤Øą¤æą¤œą„€ ą¤•ą„ą¤‚ą¤œą„€ और ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤¹ą„‹ą¤Øą¤¾ ą¤šą¤¾ą¤¹ą¤æą¤):", + "selectJKS": "ą¤…ą¤Ŗą¤Øą„€ Java Keystore फ़ाइल (.jks या .keystore) ą¤šą„ą¤Øą„‡ą¤‚:", + "certType": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤Ŗą„ą¤°ą¤•ą¤¾ą¤°", + "password": "ą¤…ą¤Ŗą¤Øą„€ ą¤•ą„€ą¤øą„ą¤Ÿą„‹ą¤° या ą¤Øą¤æą¤œą„€ ą¤•ą„ą¤‚ą¤œą„€ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚ (यदि ą¤•ą„‹ą¤ˆ ą¤¹ą„‹):", + "showSig": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚", + "reason": "कारण", + "location": "ą¤øą„ą¤„ą¤¾ą¤Ø", + "name": "नाम", + "showLogo": "ą¤²ą„‹ą¤—ą„‹ ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚", + "submit": "PDF पर ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤•ą¤°ą„‡ą¤‚" + }, + "removeCertSign": { + "tags": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą„€ą¤•ą¤°ą¤£,PEM,P12,आधिकारिक,ą¤”ą¤æą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ", + "title": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "header": "PDF ą¤øą„‡ औिजिटल ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "selectPDF": "PDF फ़ाइल ą¤šą„ą¤Øą„‡ą¤‚:", + "submit": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "pageLayout": { + "tags": "ą¤®ą¤°ą„ą¤œ,ą¤øą¤‚ą¤Æą„‹ą¤œą¤æą¤¤,ą¤ą¤•ą¤²-ą¤¦ą„ƒą¤¶ą„ą¤Æ,ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤", + "title": "ą¤®ą¤²ą„ą¤Ÿą„€ ą¤Ŗą„‡ą¤œ ą¤²ą„‡ą¤†ą¤‰ą¤Ÿ", + "header": "ą¤®ą¤²ą„ą¤Ÿą„€ ą¤Ŗą„‡ą¤œ ą¤²ą„‡ą¤†ą¤‰ą¤Ÿ", + "pagesPerSheet": "ą¤Ŗą„ą¤°ą¤¤ą¤æ ą¤¶ą„€ą¤Ÿ ą¤Ŗą„ƒą¤·ą„ą¤ :", + "addBorder": "ą¤¬ą„‰ą¤°ą„ą¤”ą¤° ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚", + "submit": "जमा ą¤•ą¤°ą„‡ą¤‚" + }, + "scalePages": { + "tags": "आकार ą¤¬ą¤¦ą¤²ą„‡ą¤‚,ą¤øą¤‚ą¤¶ą„‹ą¤§ą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚,आयाम,ą¤…ą¤Øą„ą¤•ą„‚ą¤² ą¤•ą¤°ą„‡ą¤‚", + "title": "ą¤Ŗą„ƒą¤·ą„ą¤ -ą¤øą„ą¤•ą„‡ą¤² ą¤øą¤®ą¤¾ą¤Æą„‹ą¤œą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "header": "ą¤Ŗą„ƒą¤·ą„ą¤ -ą¤øą„ą¤•ą„‡ą¤² ą¤øą¤®ą¤¾ą¤Æą„‹ą¤œą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "pageSize": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤•ą„‡ ą¤ą¤• ą¤Ŗą„ƒą¤·ą„ą¤  का ą¤†ą¤•ą¤¾ą¤°ą„¤", + "keepPageSize": "ą¤®ą„‚ą¤² आकार", + "scaleFactor": "ą¤ą¤• ą¤Ŗą„ƒą¤·ą„ą¤  का ą¤œą¤¼ą„‚ą¤® ą¤øą„ą¤¤ą¤° (ą¤•ą„ą¤°ą„‰ą¤Ŗ)ą„¤", + "submit": "जमा ą¤•ą¤°ą„‡ą¤‚" + }, + "add-page-numbers": { + "tags": "ą¤Ŗą„ƒą¤·ą„ą¤ ą¤¾ą¤‚ą¤•ą¤Ø,ą¤²ą„‡ą¤¬ą¤²,ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤,ą¤…ą¤Øą„ą¤•ą„ą¤°ą¤®ą¤£ą¤æą¤•ą¤¾" + }, + "auto-rename": { + "tags": "ą¤øą„ą¤µą¤¤ą¤ƒ-पहचान,ą¤¹ą„‡ą¤”ą¤°-आधारित,ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤,ą¤Ŗą„ą¤Øą¤°ą„ą¤Øą¤¾ą¤®ą¤¾ą¤‚ą¤•ą¤Ø", + "title": "ą¤øą„ą¤µą¤¤ą¤ƒ नाम ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "header": "ą¤øą„ą¤µą¤¤ą¤ƒ PDF नाम ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "submit": "ą¤øą„ą¤µą¤¤ą¤ƒ नाम ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "adjust-contrast": { + "tags": "रंग-ą¤øą„ą¤§ą¤¾ą¤°,ą¤Ÿą„ą¤Æą„‚ą¤Ø,ą¤øą¤‚ą¤¶ą„‹ą¤§ą¤æą¤¤,ą¤¬ą¤¢ą¤¼ą¤¾ą¤ą¤‚" + }, + "crop": { + "tags": "ą¤Ÿą„ą¤°ą¤æą¤®,ą¤øą¤æą¤•ą„‹ą¤”ą¤¼ą„‡ą¤‚,संपादित ą¤•ą¤°ą„‡ą¤‚,आकार", + "title": "ą¤•ą„ą¤°ą„‰ą¤Ŗ ą¤•ą¤°ą„‡ą¤‚", + "header": "PDF ą¤•ą„ą¤°ą„‰ą¤Ŗ ą¤•ą¤°ą„‡ą¤‚", + "submit": "जमा ą¤•ą¤°ą„‡ą¤‚" + }, + "autoSplitPDF": { + "tags": "QR-आधारित,अलग ą¤•ą¤°ą„‡ą¤‚,ą¤øą„ą¤•ą„ˆą¤Ø-खंऔ,ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "title": "ą¤øą„ą¤µą¤¤ą¤ƒ PDF विभाजित ą¤•ą¤°ą„‡ą¤‚", + "header": "ą¤øą„ą¤µą¤¤ą¤ƒ PDF विभाजित ą¤•ą¤°ą„‡ą¤‚", + "description": "ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿ ą¤•ą¤°ą„‡ą¤‚, ą¤”ą¤¾ą¤²ą„‡ą¤‚, ą¤øą„ą¤•ą„ˆą¤Ø ą¤•ą¤°ą„‡ą¤‚, ą¤…ą¤Ŗą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚, और ą¤¹ą¤®ą„‡ą¤‚ ą¤†ą¤Ŗą¤•ą„‡ ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą„‹ą¤‚ ą¤•ą„‹ ą¤øą„ą¤µą¤šą¤¾ą¤²ą¤æą¤¤ ą¤°ą„‚ą¤Ŗ ą¤øą„‡ अलग ą¤•ą¤°ą¤Øą„‡ ą¤¦ą„‡ą¤‚ą„¤ ą¤•ą„‹ą¤ˆ ą¤®ą„ˆą¤Øą„ą¤…ą¤² ą¤•ą„ą¤°ą¤®ą¤¬ą¤¦ą„ą¤§ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„€ ą¤†ą¤µą¤¶ą„ą¤Æą¤•ą¤¤ą¤¾ ą¤Øą¤¹ą„€ą¤‚ą„¤", + "selectText": { + "1": "ą¤Øą„€ą¤šą„‡ ą¤øą„‡ ą¤•ą„ą¤› ą¤µą¤æą¤­ą¤¾ą¤œą¤• ą¤¶ą„€ą¤Ÿą„ą¤ø ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿ ą¤•ą¤°ą„‡ą¤‚ (ą¤¶ą„ą¤Æą¤¾ą¤® और ą¤¶ą„ą¤µą„‡ą¤¤ ą¤ ą„€ą¤• ą¤¹ą„ˆ)ą„¤", + "2": "ą¤…ą¤Ŗą¤Øą„‡ ą¤øą¤­ą„€ ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą„‹ą¤‚ ą¤•ą„‹ ą¤ą¤• साऄ ą¤øą„ą¤•ą„ˆą¤Ø ą¤•ą¤°ą„‡ą¤‚, ą¤‰ą¤Øą¤•ą„‡ ą¤¬ą„€ą¤š ą¤µą¤æą¤­ą¤¾ą¤œą¤• ą¤¶ą„€ą¤Ÿ ą¤”ą¤¾ą¤²ą„‡ą¤‚ą„¤", + "3": "ą¤ą¤• ą¤¬ą¤”ą¤¼ą„€ ą¤øą„ą¤•ą„ˆą¤Ø ą¤•ą„€ ą¤—ą¤ˆ PDF फ़ाइल ą¤…ą¤Ŗą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚ और Stirling PDF ą¤•ą„‹ ą¤¬ą¤¾ą¤•ą„€ काम ą¤•ą¤°ą¤Øą„‡ ą¤¦ą„‡ą¤‚ą„¤", + "4": "ą¤µą¤æą¤­ą¤¾ą¤œą¤• ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą„ą¤µą¤šą¤¾ą¤²ą¤æą¤¤ ą¤°ą„‚ą¤Ŗ ą¤øą„‡ ą¤Ŗą¤¹ą¤šą¤¾ą¤Øą„‡ ą¤œą¤¾ą¤¤ą„‡ ą¤¹ą„ˆą¤‚ और हटा ą¤¦ą¤æą¤ ą¤œą¤¾ą¤¤ą„‡ ą¤¹ą„ˆą¤‚, ą¤ą¤• साफ अंतिम ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤øą„ą¤Øą¤æą¤¶ą„ą¤šą¤æą¤¤ ą¤•ą¤°ą¤¤ą„‡ ą¤¹ą„ˆą¤‚ą„¤" + }, + "formPrompt": "Stirling-PDF ą¤Ŗą„ƒą¤·ą„ą¤  ą¤µą¤æą¤­ą¤¾ą¤œą¤• ą¤µą¤¾ą¤²ą„€ PDF जमा ą¤•ą¤°ą„‡ą¤‚:", + "duplexMode": "ą¤”ą„ą¤Ŗą„ą¤²ą„‡ą¤•ą„ą¤ø ą¤®ą„‹ą¤” (ą¤øą¤¾ą¤®ą¤Øą„‡ और ą¤Ŗą„€ą¤›ą„‡ ą¤øą„ą¤•ą„ˆą¤Øą¤æą¤‚ą¤—)", + "dividerDownload2": "'ą¤øą„ą¤µą¤¤ą¤ƒ ą¤µą¤æą¤­ą¤¾ą¤œą¤• (ą¤Øą¤æą¤°ą„ą¤¦ą„‡ą¤¶ą„‹ą¤‚ ą¤•ą„‡ साऄ).pdf' ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚", + "submit": "जमा ą¤•ą¤°ą„‡ą¤‚" + }, + "sanitizePdf": { + "tags": "साफ,ą¤øą„ą¤°ą¤•ą„ą¤·ą¤æą¤¤,ą¤øą„ą¤°ą¤•ą„ą¤·ą¤¾,ą¤–ą¤¤ą¤°ą„‡-ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "URLToPDF": { + "tags": "ą¤µą„‡ą¤¬-ą¤•ą„ˆą¤Ŗą„ą¤šą¤°,ą¤Ŗą„‡ą¤œ-ą¤øą¤¹ą„‡ą¤œą„‡ą¤‚,ą¤µą„‡ą¤¬-ą¤øą„‡-ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼,ą¤øą¤‚ą¤—ą„ą¤°ą¤¹", + "title": "URL ą¤øą„‡ PDF", + "header": "URL ą¤øą„‡ PDF", + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "credit": "WeasyPrint का ą¤‰ą¤Ŗą¤Æą„‹ą¤— करता ą¤¹ą„ˆ" + }, + "HTMLToPDF": { + "tags": "ą¤®ą¤¾ą¤°ą„ą¤•ą¤…ą¤Ŗ,ą¤µą„‡ą¤¬-ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€,ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£,ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "title": "HTML ą¤øą„‡ PDF", + "header": "HTML ą¤øą„‡ PDF", + "help": "HTML ą¤«ą¤¼ą¤¾ą¤‡ą¤²ą„‡ą¤‚ और ą¤†ą¤µą¤¶ą„ą¤Æą¤• html/css/images आदि ą¤µą¤¾ą¤²ą„‡ ZIP ą¤øą„ą¤µą„€ą¤•ą¤¾ą¤° करता ą¤¹ą„ˆ", + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "credit": "WeasyPrint का ą¤‰ą¤Ŗą¤Æą„‹ą¤— करता ą¤¹ą„ˆ", + "zoom": "ą¤µą„‡ą¤¬ą¤øą¤¾ą¤‡ą¤Ÿ ą¤Ŗą„ą¤°ą¤¦ą¤°ą„ą¤¶ą¤Ø ą¤•ą„‡ ą¤²ą¤æą¤ ą¤œą¤¼ą„‚ą¤® ą¤øą„ą¤¤ą¤°ą„¤", + "pageWidth": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤•ą„€ ą¤šą„Œą¤”ą¤¼ą¤¾ą¤ˆ ą¤øą„‡ą¤‚ą¤Ÿą„€ą¤®ą„€ą¤Ÿą¤° ą¤®ą„‡ą¤‚ą„¤ (ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤–ą¤¾ą¤²ą„€)", + "pageHeight": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤•ą„€ ą¤Šą¤‚ą¤šą¤¾ą¤ˆ ą¤øą„‡ą¤‚ą¤Ÿą„€ą¤®ą„€ą¤Ÿą¤° ą¤®ą„‡ą¤‚ą„¤ (ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤–ą¤¾ą¤²ą„€)", + "marginTop": "ą¤Ŗą„ƒą¤·ą„ą¤  का ą¤¶ą„€ą¤°ą„ą¤· ą¤®ą¤¾ą¤°ą„ą¤œą¤æą¤Ø ą¤®ą¤æą¤²ą„€ą¤®ą„€ą¤Ÿą¤° ą¤®ą„‡ą¤‚ą„¤ (ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤–ą¤¾ą¤²ą„€)", + "marginBottom": "ą¤Ŗą„ƒą¤·ą„ą¤  का निचला ą¤®ą¤¾ą¤°ą„ą¤œą¤æą¤Ø ą¤®ą¤æą¤²ą„€ą¤®ą„€ą¤Ÿą¤° ą¤®ą„‡ą¤‚ą„¤ (ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤–ą¤¾ą¤²ą„€)", + "marginLeft": "ą¤Ŗą„ƒą¤·ą„ą¤  का बायां ą¤®ą¤¾ą¤°ą„ą¤œą¤æą¤Ø ą¤®ą¤æą¤²ą„€ą¤®ą„€ą¤Ÿą¤° ą¤®ą„‡ą¤‚ą„¤ (ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤–ą¤¾ą¤²ą„€)", + "marginRight": "ą¤Ŗą„ƒą¤·ą„ą¤  का दायां ą¤®ą¤¾ą¤°ą„ą¤œą¤æą¤Ø ą¤®ą¤æą¤²ą„€ą¤®ą„€ą¤Ÿą¤° ą¤®ą„‡ą¤‚ą„¤ (ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤–ą¤¾ą¤²ą„€)", + "printBackground": "ą¤µą„‡ą¤¬ą¤øą¤¾ą¤‡ą¤Ÿ ą¤•ą„€ ą¤Ŗą„ƒą¤·ą„ą¤ ą¤­ą„‚ą¤®ą¤æ ą¤°ą„‡ą¤‚ą¤”ą¤° ą¤•ą¤°ą„‡ą¤‚ą„¤", + "defaultHeader": "ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ ą¤¹ą„‡ą¤”ą¤° ą¤øą¤•ą„ą¤·ą¤® ą¤•ą¤°ą„‡ą¤‚ (नाम और ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą¤‚ą¤–ą„ą¤Æą¤¾)", + "cssMediaType": "ą¤Ŗą„ƒą¤·ą„ą¤  का CSS ą¤®ą„€ą¤”ą¤æą¤Æą¤¾ ą¤Ŗą„ą¤°ą¤•ą¤¾ą¤° ą¤¬ą¤¦ą¤²ą„‡ą¤‚ą„¤", + "none": "ą¤•ą„‹ą¤ˆ ą¤Øą¤¹ą„€ą¤‚", + "print": "ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿ", + "screen": "ą¤øą„ą¤•ą„ą¤°ą„€ą¤Ø" + }, + "MarkdownToPDF": { + "tags": "ą¤®ą¤¾ą¤°ą„ą¤•ą¤…ą¤Ŗ,ą¤µą„‡ą¤¬-ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€,ą¤°ą„‚ą¤Ŗą¤¾ą¤‚ą¤¤ą¤°ą¤£,ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "title": "Markdown ą¤øą„‡ PDF", + "header": "Markdown ą¤øą„‡ PDF", + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "help": "ą¤•ą¤¾ą¤°ą„ą¤Æ ą¤Ŗą„ą¤°ą¤—ą¤¤ą¤æ पर ą¤¹ą„ˆ", + "credit": "WeasyPrint का ą¤‰ą¤Ŗą¤Æą„‹ą¤— करता ą¤¹ą„ˆ" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "ą¤œą¤¾ą¤Øą¤•ą¤¾ą¤°ą„€,ą¤”ą„‡ą¤Ÿą¤¾,ą¤†ą¤ą¤•ą¤”ą¤¼ą„‡,ą¤øą¤¾ą¤‚ą¤–ą„ą¤Æą¤æą¤•ą„€", + "title": "PDF ą¤•ą„€ ą¤œą¤¾ą¤Øą¤•ą¤¾ą¤°ą„€ ą¤Ŗą„ą¤°ą¤¾ą¤Ŗą„ą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "header": "PDF ą¤•ą„€ ą¤œą¤¾ą¤Øą¤•ą¤¾ą¤°ą„€ ą¤Ŗą„ą¤°ą¤¾ą¤Ŗą„ą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "submit": "ą¤œą¤¾ą¤Øą¤•ą¤¾ą¤°ą„€ ą¤Ŗą„ą¤°ą¤¾ą¤Ŗą„ą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "downloadJson": "JSON ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚" + }, + "extractPage": { + "tags": "ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚" + }, + "PdfToSinglePage": { + "tags": "ą¤ą¤•ą¤² ą¤Ŗą„ƒą¤·ą„ą¤ " + }, + "showJS": { + "tags": "JS", + "title": "ą¤œą¤¾ą¤µą¤¾ą¤øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚", + "header": "ą¤œą¤¾ą¤µą¤¾ą¤øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚", + "downloadJS": "ą¤œą¤¾ą¤µą¤¾ą¤øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚", + "submit": "ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚" + }, + "autoRedact": { + "tags": "ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą¤°ą¤£,ą¤›ą¤æą¤Ŗą¤¾ą¤ą¤‚,काला ą¤•ą¤°ą„‡ą¤‚,काला,ą¤®ą¤¾ą¤°ą„ą¤•ą¤°,छिपा ą¤¹ą„ą¤†", + "title": "ą¤øą„ą¤µą¤¤ą¤ƒ ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą¤°ą¤£", + "header": "ą¤øą„ą¤µą¤¤ą¤ƒ ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą¤°ą¤£", + "colorLabel": "रंग", + "textsToRedactLabel": "ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą„ƒą¤¤ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ (लाइन-अलग)", + "textsToRedactPlaceholder": "उदाहरण \\ną¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æ \\ną¤Ÿą„‰ą¤Ŗ-ą¤øą„€ą¤•ą„ą¤°ą„‡ą¤Ÿ", + "useRegexLabel": "ą¤°ą„‡ą¤—ą„‡ą¤•ą„ą¤ø का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą„‡ą¤‚", + "wholeWordSearchLabel": "ą¤Ŗą„‚ą¤°ą„ą¤£ ą¤¶ą¤¬ą„ą¤¦ ą¤–ą„‹ą¤œ", + "customPaddingLabel": "ą¤•ą¤øą„ą¤Ÿą¤® ą¤…ą¤¤ą¤æą¤°ą¤æą¤•ą„ą¤¤ ą¤Ŗą„ˆą¤”ą¤æą¤‚ą¤—", + "convertPDFToImageLabel": "PDF ą¤•ą„‹ PDF-छवि ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚ (ą¤¬ą„‰ą¤•ą„ą¤ø ą¤•ą„‡ ą¤Ŗą„€ą¤›ą„‡ ą¤•ą„‡ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤•ą„‹ ą¤¹ą¤Ÿą¤¾ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤‰ą¤Ŗą¤Æą„‹ą¤— किया जाता ą¤¹ą„ˆ)", + "submitButton": "जमा ą¤•ą¤°ą„‡ą¤‚" + }, + "redact": { + "tags": "ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą¤°ą¤£,ą¤›ą¤æą¤Ŗą¤¾ą¤ą¤‚,काला ą¤•ą¤°ą„‡ą¤‚,काला,ą¤®ą¤¾ą¤°ą„ą¤•ą¤°,छिपा ą¤¹ą„ą¤†,ą¤®ą„ˆą¤Øą„ą¤…ą¤²", + "title": "ą¤®ą„ˆą¤Øą„ą¤…ą¤² ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą¤°ą¤£", + "header": "ą¤®ą„ˆą¤Øą„ą¤…ą¤² ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą¤°ą¤£", + "submit": "ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą„ƒą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "textBasedRedaction": "ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ आधारित ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą¤°ą¤£", + "pageBasedRedaction": "ą¤Ŗą„ƒą¤·ą„ą¤ -आधारित ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą¤°ą¤£", + "convertPDFToImageLabel": "PDF ą¤•ą„‹ PDF-छवि ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚ (ą¤¬ą„‰ą¤•ą„ą¤ø ą¤•ą„‡ ą¤Ŗą„€ą¤›ą„‡ का ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ ą¤¹ą¤Ÿą¤¾ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤‰ą¤Ŗą¤Æą„‹ą¤— किया जाता ą¤¹ą„ˆ)", + "pageRedactionNumbers": { + "title": "ą¤Ŗą„ƒą¤·ą„ą¤ ", + "placeholder": "(उदाहरण 1,2,8 या 4,7,12-16 या 2n-1)" + }, + "redactionColor": { + "title": "ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą¤°ą¤£ रंग" + }, + "export": "ą¤Øą¤æą¤°ą„ą¤Æą¤¾ą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "upload": "ą¤…ą¤Ŗą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚", + "boxRedaction": "ą¤¬ą„‰ą¤•ą„ą¤ø ą¤”ą„ą¤°ą„‰ ą¤—ą„‹ą¤Ŗą¤Øą„€ą¤Æą¤•ą¤°ą¤£", + "zoom": "ą¤œą¤¼ą„‚ą¤®", + "zoomIn": "ą¤œą¤¼ą„‚ą¤® इन ą¤•ą¤°ą„‡ą¤‚", + "zoomOut": "ą¤œą¤¼ą„‚ą¤® ą¤†ą¤‰ą¤Ÿ ą¤•ą¤°ą„‡ą¤‚", + "nextPage": "अगला ą¤Ŗą„ƒą¤·ą„ą¤ ", + "previousPage": "पिछला ą¤Ŗą„ƒą¤·ą„ą¤ ", + "toggleSidebar": "साइऔबार ą¤Ÿą„‰ą¤—ą¤² ą¤•ą¤°ą„‡ą¤‚", + "showThumbnails": "ą¤„ą¤‚ą¤¬ą¤Øą„‡ą¤² ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚", + "showDocumentOutline": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤†ą¤‰ą¤Ÿą¤²ą¤¾ą¤‡ą¤Ø ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚ (ą¤øą¤­ą„€ ą¤†ą¤‡ą¤Ÿą¤® ą¤µą¤æą¤øą„ą¤¤ą„ƒą¤¤/ą¤øą¤‚ą¤•ą„ą¤·ą¤æą¤Ŗą„ą¤¤ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ औबल-ą¤•ą„ą¤²ą¤æą¤• ą¤•ą¤°ą„‡ą¤‚)", + "showAttatchments": "ą¤…ą¤Ÿą„ˆą¤šą¤®ą„‡ą¤‚ą¤Ÿ ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚", + "showLayers": "ą¤²ą„‡ą¤Æą¤°ą„ą¤ø ą¤¦ą¤æą¤–ą¤¾ą¤ą¤‚ (ą¤øą¤­ą„€ ą¤²ą„‡ą¤Æą¤°ą„ą¤ø ą¤•ą„‹ ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ ą¤øą„ą¤„ą¤æą¤¤ą¤æ ą¤®ą„‡ą¤‚ ą¤°ą„€ą¤øą„‡ą¤Ÿ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ औबल-ą¤•ą„ą¤²ą¤æą¤• ą¤•ą¤°ą„‡ą¤‚)", + "colourPicker": "रंग ą¤šą¤Æą¤Øą¤•ą¤°ą„ą¤¤ą¤¾", + "findCurrentOutlineItem": "ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤†ą¤‰ą¤Ÿą¤²ą¤¾ą¤‡ą¤Ø ą¤†ą¤‡ą¤Ÿą¤® ą¤–ą„‹ą¤œą„‡ą¤‚", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,तालिका ą¤Øą¤æą¤·ą„ą¤•ą¤°ą„ą¤·ą¤£,ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚,ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "autoSizeSplitPDF": { + "tags": "pdf,विभाजन,ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼,ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤¾" + }, + "overlay-pdfs": { + "tags": "ą¤“ą¤µą¤°ą¤²ą„‡", + "header": "PDF ą¤«ą¤¼ą¤¾ą¤‡ą¤²ą„‡ą¤‚ ą¤“ą¤µą¤°ą¤²ą„‡ ą¤•ą¤°ą„‡ą¤‚", + "baseFile": { + "label": "ą¤¬ą„‡ą¤ø PDF फ़ाइल ą¤šą„ą¤Øą„‡ą¤‚" + }, + "overlayFiles": { + "label": "ą¤“ą¤µą¤°ą¤²ą„‡ PDF ą¤«ą¤¼ą¤¾ą¤‡ą¤²ą„‡ą¤‚ ą¤šą„ą¤Øą„‡ą¤‚" + }, + "mode": { + "label": "ą¤“ą¤µą¤°ą¤²ą„‡ ą¤®ą„‹ą¤” ą¤šą„ą¤Øą„‡ą¤‚", + "sequential": "ą¤•ą„ą¤°ą¤®ą¤æą¤• ą¤“ą¤µą¤°ą¤²ą„‡", + "interleaved": "ą¤‡ą¤‚ą¤Ÿą¤°ą¤²ą„€ą¤µą„ą¤” ą¤“ą¤µą¤°ą¤²ą„‡", + "fixedRepeat": "ą¤Øą¤æą¤¶ą„ą¤šą¤æą¤¤ ą¤¦ą„‹ą¤¹ą¤°ą¤¾ą¤µ ą¤“ą¤µą¤°ą¤²ą„‡" + }, + "counts": { + "label": "ą¤“ą¤µą¤°ą¤²ą„‡ ą¤—ą¤æą¤Øą¤¤ą„€ (ą¤Øą¤æą¤¶ą„ą¤šą¤æą¤¤ ą¤¦ą„‹ą¤¹ą¤°ą¤¾ą¤µ ą¤®ą„‹ą¤” ą¤•ą„‡ ą¤²ą¤æą¤)", + "placeholder": "ą¤…ą¤²ą„ą¤Ŗą¤µą¤æą¤°ą¤¾ą¤® ą¤øą„‡ अलग ą¤—ą¤æą¤Øą¤¤ą„€ ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚ (ą¤œą„ˆą¤øą„‡ 2,3,1)" + }, + "position": { + "label": "ą¤“ą¤µą¤°ą¤²ą„‡ ą¤øą„ą¤„ą¤æą¤¤ą¤æ ą¤šą„ą¤Øą„‡ą¤‚", + "foreground": "ą¤…ą¤—ą„ą¤°ą¤­ą„‚ą¤®ą¤æ", + "background": "ą¤Ŗą„ƒą¤·ą„ą¤ ą¤­ą„‚ą¤®ą¤æ" + }, + "submit": "जमा ą¤•ą¤°ą„‡ą¤‚" + }, + "split-by-sections": { + "tags": "खंऔ विभाजन, विभाजित ą¤•ą¤°ą„‡ą¤‚, ą¤…ą¤Øą„ą¤•ą„‚ą¤²ą¤æą¤¤", + "title": "ą¤–ą¤‚ą¤”ą„‹ą¤‚ ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ PDF विभाजित ą¤•ą¤°ą„‡ą¤‚", + "header": "PDF ą¤•ą„‹ ą¤–ą¤‚ą¤”ą„‹ą¤‚ ą¤®ą„‡ą¤‚ विभाजित ą¤•ą¤°ą„‡ą¤‚", + "horizontal": { + "label": "ą¤•ą„ą¤·ą„ˆą¤¤ą¤æą¤œ विभाजन", + "placeholder": "ą¤•ą„ą¤·ą„ˆą¤¤ą¤æą¤œ ą¤µą¤æą¤­ą¤¾ą¤œą¤Øą„‹ą¤‚ ą¤•ą„€ ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚" + }, + "vertical": { + "label": "ą¤Šą¤°ą„ą¤§ą„ą¤µą¤¾ą¤§ą¤° विभाजन", + "placeholder": "ą¤Šą¤°ą„ą¤§ą„ą¤µą¤¾ą¤§ą¤° ą¤µą¤æą¤­ą¤¾ą¤œą¤Øą„‹ą¤‚ ą¤•ą„€ ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚" + }, + "submit": "PDF विभाजित ą¤•ą¤°ą„‡ą¤‚", + "merge": "ą¤ą¤• PDF ą¤®ą„‡ą¤‚ ą¤®ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚" + }, + "AddStampRequest": { + "tags": "ą¤øą„ą¤Ÿą„ˆą¤®ą„ą¤Ŗ, छवि ą¤œą„‹ą¤”ą¤¼ą„‡ą¤‚, ą¤•ą„‡ą¤‚ą¤¦ą„ą¤° छवि, ą¤µą„‰ą¤Ÿą¤°ą¤®ą¤¾ą¤°ą„ą¤•, PDF, ą¤ą¤®ą„ą¤¬ą„‡ą¤”, ą¤…ą¤Øą„ą¤•ą„‚ą¤²ą¤æą¤¤", + "header": "PDF ą¤øą„ą¤Ÿą„ˆą¤®ą„ą¤Ŗ ą¤•ą¤°ą„‡ą¤‚", + "title": "PDF ą¤øą„ą¤Ÿą„ˆą¤®ą„ą¤Ŗ ą¤•ą¤°ą„‡ą¤‚", + "stampType": "ą¤øą„ą¤Ÿą„ˆą¤®ą„ą¤Ŗ ą¤Ŗą„ą¤°ą¤•ą¤¾ą¤°", + "stampText": "ą¤øą„ą¤Ÿą„ˆą¤®ą„ą¤Ŗ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ", + "stampImage": "ą¤øą„ą¤Ÿą„ˆą¤®ą„ą¤Ŗ छवि", + "alphabet": "ą¤µą¤°ą„ą¤£ą¤®ą¤¾ą¤²ą¤¾", + "fontSize": "ą¤«ą¤¼ą„‰ą¤Øą„ą¤Ÿ/छवि आकार", + "rotation": "ą¤˜ą„ą¤®ą¤¾ą¤µ", + "opacity": "ą¤…ą¤Ŗą¤¾ą¤°ą¤¦ą¤°ą„ą¤¶ą¤æą¤¤ą¤¾", + "position": "ą¤øą„ą¤„ą¤æą¤¤ą¤æ", + "overrideX": "X ą¤Øą¤æą¤°ą„ą¤¦ą„‡ą¤¶ą¤¾ą¤‚ą¤• ओवरराइऔ ą¤•ą¤°ą„‡ą¤‚", + "overrideY": "Y ą¤Øą¤æą¤°ą„ą¤¦ą„‡ą¤¶ą¤¾ą¤‚ą¤• ओवरराइऔ ą¤•ą¤°ą„‡ą¤‚", + "customMargin": "ą¤•ą¤øą„ą¤Ÿą¤® ą¤®ą¤¾ą¤°ą„ą¤œą¤æą¤Ø", + "customColor": "ą¤•ą¤øą„ą¤Ÿą¤® ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ रंग", + "submit": "जमा ą¤•ą¤°ą„‡ą¤‚" + }, + "removeImagePdf": { + "tags": "छवि ą¤¹ą¤Ÿą¤¾ą¤ą¤‚,ą¤Ŗą„ƒą¤·ą„ą¤  ą¤•ą¤¾ą¤°ą„ą¤Æ,ą¤¬ą„ˆą¤• ą¤ą¤‚ą¤”,ą¤øą¤°ą„ą¤µą¤° साइऔ" + }, + "splitPdfByChapters": { + "tags": "विभाजन,ą¤…ą¤§ą„ą¤Æą¤¾ą¤Æ,ą¤¬ą„ą¤•ą¤®ą¤¾ą¤°ą„ą¤•,ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚" + }, + "validateSignature": { + "tags": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°,ą¤øą¤¤ą„ą¤Æą¤¾ą¤Ŗą¤æą¤¤,ą¤®ą¤¾ą¤Øą„ą¤Æ,pdf,ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤°,औिजिटल ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°,ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤øą¤¤ą„ą¤Æą¤¾ą¤Ŗą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚,ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤øą¤¤ą„ą¤Æą¤¾ą¤Ŗą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "title": "PDF ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤øą¤¤ą„ą¤Æą¤¾ą¤Ŗą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "header": "औिजिटल ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤øą¤¤ą„ą¤Æą¤¾ą¤Ŗą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "selectPDF": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°ą¤æą¤¤ PDF फ़ाइल ą¤šą„ą¤Øą„‡ą¤‚", + "submit": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤øą¤¤ą„ą¤Æą¤¾ą¤Ŗą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "results": "ą¤øą¤¤ą„ą¤Æą¤¾ą¤Ŗą¤Ø परिणाम", + "status": { + "_value": "ą¤øą„ą¤„ą¤æą¤¤ą¤æ", + "valid": "ą¤®ą¤¾ą¤Øą„ą¤Æ", + "invalid": "ą¤…ą¤®ą¤¾ą¤Øą„ą¤Æ" + }, + "signer": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°ą¤•ą¤°ą„ą¤¤ą¤¾", + "date": "तिऄि", + "reason": "कारण", + "location": "ą¤øą„ą¤„ą¤¾ą¤Ø", + "noSignatures": "इस ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤®ą„‡ą¤‚ ą¤•ą„‹ą¤ˆ औिजिटल ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤Øą¤¹ą„€ą¤‚ मिला", + "chain": { + "invalid": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤¶ą„ą¤°ą„ƒą¤‚ą¤–ą¤²ą¤¾ ą¤øą¤¤ą„ą¤Æą¤¾ą¤Ŗą¤Ø विफल - ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤•ą„€ पहचान ą¤øą¤¤ą„ą¤Æą¤¾ą¤Ŗą¤æą¤¤ ą¤Øą¤¹ą„€ą¤‚ कर ą¤øą¤•ą¤¤ą„‡" + }, + "trust": { + "invalid": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤Ÿą„ą¤°ą¤øą„ą¤Ÿ ą¤øą„ą¤Ÿą„‹ą¤° ą¤®ą„‡ą¤‚ ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„ˆ - ą¤øą„ą¤°ą„‹ą¤¤ ą¤øą¤¤ą„ą¤Æą¤¾ą¤Ŗą¤æą¤¤ ą¤Øą¤¹ą„€ą¤‚ किया जा सकता" + }, + "cert": { + "expired": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤øą¤®ą¤¾ą¤Ŗą„ą¤¤ ą¤¹ą„‹ गया ą¤¹ą„ˆ", + "revoked": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° ą¤°ą¤¦ą„ą¤¦ कर दिया गया ą¤¹ą„ˆ", + "info": "ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° विवरण", + "issuer": "ą¤œą¤¾ą¤°ą„€ą¤•ą¤°ą„ą¤¤ą¤¾", + "subject": "विषय", + "serialNumber": "ą¤•ą„ą¤°ą¤® ą¤øą¤‚ą¤–ą„ą¤Æą¤¾", + "validFrom": "ą¤øą„‡ ą¤®ą¤¾ą¤Øą„ą¤Æ", + "validUntil": "तक ą¤®ą¤¾ą¤Øą„ą¤Æ", + "algorithm": "ą¤ą¤²ą„ą¤—ą„‹ą¤°ą¤æą¤„ą„ą¤®", + "keySize": "ą¤•ą„ą¤‚ą¤œą„€ आकार", + "version": "ą¤øą¤‚ą¤øą„ą¤•ą¤°ą¤£", + "keyUsage": "ą¤•ą„ą¤‚ą¤œą„€ ą¤‰ą¤Ŗą¤Æą„‹ą¤—", + "selfSigned": "ą¤øą„ą¤µ-ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°ą¤æą¤¤", + "bits": "ą¤¬ą¤æą¤Ÿą„ą¤ø" + }, + "signature": { + "info": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤œą¤¾ą¤Øą¤•ą¤¾ą¤°ą„€", + "_value": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤°", + "mathValid": "ą¤¹ą¤øą„ą¤¤ą¤¾ą¤•ą„ą¤·ą¤° ą¤—ą¤£ą¤æą¤¤ą„€ą¤Æ ą¤°ą„‚ą¤Ŗ ą¤øą„‡ ą¤®ą¤¾ą¤Øą„ą¤Æ ą¤¹ą„ˆ ą¤²ą„‡ą¤•ą¤æą¤Ø:" + }, + "selectCustomCert": "ą¤•ą¤øą„ą¤Ÿą¤® ą¤Ŗą„ą¤°ą¤®ą¤¾ą¤£ą¤Ŗą¤¤ą„ą¤° फ़ाइल X.509 (ą¤µą„ˆą¤•ą¤²ą„ą¤Ŗą¤æą¤•)" + }, + "replace-color": { + "title": "रंग ą¤¬ą¤¦ą¤²ą„‡ą¤‚-ą¤‰ą¤²ą„ą¤Ÿą¤¾ ą¤•ą¤°ą„‡ą¤‚", + "header": "रंग ą¤¬ą¤¦ą¤²ą„‡ą¤‚-ą¤‰ą¤²ą„ą¤Ÿą¤¾ ą¤•ą¤°ą„‡ą¤‚ PDF", + "selectText": { + "1": "रंग ą¤¬ą¤¦ą¤²ą„‡ą¤‚ या ą¤‰ą¤²ą„ą¤Ÿą¤¾ ą¤•ą¤°ą„‡ą¤‚ ą¤µą¤æą¤•ą¤²ą„ą¤Ŗ", + "2": "ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ (ą¤”ą¤æą¤«ą¤¼ą„‰ą¤²ą„ą¤Ÿ ą¤‰ą¤šą„ą¤š ą¤•ą¤‚ą¤Ÿą„ą¤°ą¤¾ą¤øą„ą¤Ÿ रंग)", + "3": "ą¤•ą¤øą„ą¤Ÿą¤® (ą¤…ą¤Øą„ą¤•ą„‚ą¤²ą¤æą¤¤ रंग)", + "4": "ą¤Ŗą„‚ą¤°ą„ą¤£-ą¤‰ą¤²ą„ą¤Ÿą¤¾ (ą¤øą¤­ą„€ ą¤°ą¤‚ą¤—ą„‹ą¤‚ ą¤•ą„‹ ą¤‰ą¤²ą„ą¤Ÿą¤¾ ą¤•ą¤°ą„‡ą¤‚)", + "5": "ą¤‰ą¤šą„ą¤š ą¤•ą¤‚ą¤Ÿą„ą¤°ą¤¾ą¤øą„ą¤Ÿ रंग ą¤µą¤æą¤•ą¤²ą„ą¤Ŗ", + "6": "ą¤•ą¤¾ą¤²ą„€ ą¤Ŗą„ƒą¤·ą„ą¤ ą¤­ą„‚ą¤®ą¤æ पर ą¤øą¤«ą„‡ą¤¦ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ", + "7": "ą¤øą¤«ą„‡ą¤¦ ą¤Ŗą„ƒą¤·ą„ą¤ ą¤­ą„‚ą¤®ą¤æ पर काला ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ", + "8": "ą¤•ą¤¾ą¤²ą„€ ą¤Ŗą„ƒą¤·ą„ą¤ ą¤­ą„‚ą¤®ą¤æ पर ą¤Ŗą„€ą¤²ą¤¾ ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ", + "9": "ą¤•ą¤¾ą¤²ą„€ ą¤Ŗą„ƒą¤·ą„ą¤ ą¤­ą„‚ą¤®ą¤æ पर हरा ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ", + "10": "ą¤Ÿą„‡ą¤•ą„ą¤øą„ą¤Ÿ रंग ą¤šą„ą¤Øą„‡ą¤‚", + "11": "ą¤Ŗą„ƒą¤·ą„ą¤ ą¤­ą„‚ą¤®ą¤æ रंग ą¤šą„ą¤Øą„‡ą¤‚" + }, + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "replaceColorPdf": { + "tags": "रंग ą¤¬ą¤¦ą¤²ą„‡ą¤‚,ą¤Ŗą„ƒą¤·ą„ą¤  ą¤•ą¤¾ą¤°ą„ą¤Æ,ą¤¬ą„ˆą¤• ą¤ą¤‚ą¤”,ą¤øą¤°ą„ą¤µą¤° साइऔ" + }, + "login": { + "title": "साइन इन ą¤•ą¤°ą„‡ą¤‚", + "header": "साइन इन ą¤•ą¤°ą„‡ą¤‚", + "signin": "साइन इन ą¤•ą¤°ą„‡ą¤‚", + "rememberme": "ą¤®ą„ą¤ą„‡ याद ą¤°ą¤–ą„‡ą¤‚", + "invalid": "ą¤…ą¤®ą¤¾ą¤Øą„ą¤Æ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ नाम या ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤”ą„¤", + "locked": "आपका खाता ą¤²ą„‰ą¤• कर दिया गया ą¤¹ą„ˆą„¤", + "signinTitle": "ą¤•ą„ƒą¤Ŗą¤Æą¤¾ साइन इन ą¤•ą¤°ą„‡ą¤‚", + "ssoSignIn": "सिंगल साइन-ऑन ą¤•ą„‡ ą¤®ą¤¾ą¤§ą„ą¤Æą¤® ą¤øą„‡ ą¤²ą„‰ą¤—ą¤æą¤Ø ą¤•ą¤°ą„‡ą¤‚", + "oAuth2AutoCreateDisabled": "OAUTH2 ą¤øą„ą¤µą¤¤ą¤ƒ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤Øą¤æą¤°ą„ą¤®ą¤¾ą¤£ ą¤…ą¤•ą„ą¤·ą¤® ą¤¹ą„ˆ", + "oAuth2AdminBlockedUser": "ą¤—ą„ˆą¤°-ą¤Ŗą¤‚ą¤œą„€ą¤•ą„ƒą¤¤ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ą¤“ą¤‚ का ą¤Ŗą¤‚ą¤œą„€ą¤•ą¤°ą¤£ या ą¤²ą„‰ą¤—ą¤æą¤Ø ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤®ą„‡ą¤‚ ą¤…ą¤µą¤°ą„ą¤¦ą„ą¤§ ą¤¹ą„ˆą„¤ ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤¾ą¤Ŗą¤• ą¤øą„‡ ą¤øą¤‚ą¤Ŗą¤°ą„ą¤• ą¤•ą¤°ą„‡ą¤‚ą„¤", + "oauth2RequestNotFound": "ą¤Ŗą„ą¤°ą¤¾ą¤§ą¤æą¤•ą¤°ą¤£ ą¤…ą¤Øą„ą¤°ą„‹ą¤§ ą¤Øą¤¹ą„€ą¤‚ मिला", + "oauth2InvalidUserInfoResponse": "ą¤…ą¤®ą¤¾ą¤Øą„ą¤Æ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤œą¤¾ą¤Øą¤•ą¤¾ą¤°ą„€ ą¤Ŗą„ą¤°ą¤¤ą¤æą¤•ą„ą¤°ą¤æą¤Æą¤¾", + "oauth2invalidRequest": "ą¤…ą¤®ą¤¾ą¤Øą„ą¤Æ ą¤…ą¤Øą„ą¤°ą„‹ą¤§", + "oauth2AccessDenied": "ą¤Ŗą¤¹ą„ą¤‚ą¤š ą¤…ą¤øą„ą¤µą„€ą¤•ą„ƒą¤¤", + "oauth2InvalidTokenResponse": "ą¤…ą¤®ą¤¾ą¤Øą„ą¤Æ ą¤Ÿą„‹ą¤•ą¤Ø ą¤Ŗą„ą¤°ą¤¤ą¤æą¤•ą„ą¤°ą¤æą¤Æą¤¾", + "oauth2InvalidIdToken": "ą¤…ą¤®ą¤¾ą¤Øą„ą¤Æ Id ą¤Ÿą„‹ą¤•ą¤Ø", + "relyingPartyRegistrationNotFound": "ą¤•ą„‹ą¤ˆ ą¤Øą¤æą¤°ą„ą¤­ą¤° ą¤Ŗą¤¾ą¤°ą„ą¤Ÿą„€ ą¤Ŗą¤‚ą¤œą„€ą¤•ą¤°ą¤£ ą¤Øą¤¹ą„€ą¤‚ मिला", + "userIsDisabled": "ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ ą¤Øą¤æą¤·ą„ą¤•ą„ą¤°ą¤æą¤Æ ą¤¹ą„ˆ, ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤®ą„‡ą¤‚ इस ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ नाम ą¤øą„‡ ą¤²ą„‰ą¤—ą¤æą¤Ø ą¤…ą¤µą¤°ą„ą¤¦ą„ą¤§ ą¤¹ą„ˆą„¤ ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤µą„ą¤Æą¤µą¤øą„ą¤„ą¤¾ą¤Ŗą¤• ą¤øą„‡ ą¤øą¤‚ą¤Ŗą¤°ą„ą¤• ą¤•ą¤°ą„‡ą¤‚ą„¤", + "alreadyLoggedIn": "आप ą¤Ŗą¤¹ą¤²ą„‡ ą¤øą„‡ ą¤¹ą„€", + "alreadyLoggedIn2": "ą¤‰ą¤Ŗą¤•ą¤°ą¤£ą„‹ą¤‚ ą¤®ą„‡ą¤‚ ą¤²ą„‰ą¤— इन ą¤¹ą„ˆą¤‚ą„¤ ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤‰ą¤Ŗą¤•ą¤°ą¤£ą„‹ą¤‚ ą¤øą„‡ ą¤²ą„‰ą¤— ą¤†ą¤‰ą¤Ÿ ą¤•ą¤°ą„‡ą¤‚ और ą¤Ŗą„ą¤Øą¤ƒ ą¤Ŗą„ą¤°ą¤Æą¤¾ą¤ø ą¤•ą¤°ą„‡ą¤‚ą„¤", + "toManySessions": "ą¤†ą¤Ŗą¤•ą„‡ ą¤¬ą¤¹ą„ą¤¤ ą¤øą¤¾ą¤°ą„‡ ą¤øą¤•ą„ą¤°ą¤æą¤Æ ą¤øą¤¤ą„ą¤° ą¤¹ą„ˆą¤‚", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF ą¤•ą„‹ ą¤ą¤•ą¤² ą¤Ŗą„ƒą¤·ą„ą¤  ą¤®ą„‡ą¤‚", + "header": "PDF ą¤•ą„‹ ą¤ą¤•ą¤² ą¤Ŗą„ƒą¤·ą„ą¤  ą¤®ą„‡ą¤‚", + "submit": "ą¤ą¤•ą¤² ą¤Ŗą„ƒą¤·ą„ą¤  ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + }, + "pageExtracter": { + "title": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚", + "header": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚", + "submit": "ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚", + "placeholder": "(उदाहरण 1,2,8 या 4,7,12-16 या 2n-1)" + }, + "sanitizePDF": { + "title": "PDF ą¤øą„ˆą¤Øą¤æą¤Ÿą¤¾ą¤‡ą¤œą¤¼ ą¤•ą¤°ą„‡ą¤‚", + "header": "PDF फ़ाइल ą¤øą„ˆą¤Øą¤æą¤Ÿą¤¾ą¤‡ą¤œą¤¼ ą¤•ą¤°ą„‡ą¤‚", + "selectText": { + "1": "ą¤œą¤¾ą¤µą¤¾ą¤øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ ą¤•ą„ą¤°ą¤æą¤Æą¤¾ą¤ą¤‚ ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "2": "ą¤ą¤®ą„ą¤¬ą„‡ą¤”ą„‡ą¤” ą¤«ą¤¼ą¤¾ą¤‡ą¤²ą„‡ą¤‚ ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "3": "Remove XMP metadata", + "4": "लिंक ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "5": "ą¤«ą¤¼ą„‰ą¤Øą„ą¤Ÿą„ą¤ø ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "6": "Remove Document Info Metadata" + }, + "submit": "PDF ą¤øą„ˆą¤Øą¤æą¤Ÿą¤¾ą¤‡ą¤œą¤¼ ą¤•ą¤°ą„‡ą¤‚" + }, + "adjustContrast": { + "title": "ą¤•ą¤‚ą¤Ÿą„ą¤°ą¤¾ą¤øą„ą¤Ÿ ą¤øą¤®ą¤¾ą¤Æą„‹ą¤œą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "header": "ą¤•ą¤‚ą¤Ÿą„ą¤°ą¤¾ą¤øą„ą¤Ÿ ą¤øą¤®ą¤¾ą¤Æą„‹ą¤œą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚", + "contrast": "ą¤•ą¤‚ą¤Ÿą„ą¤°ą¤¾ą¤øą„ą¤Ÿ:", + "brightness": "ą¤šą¤®ą¤•:", + "saturation": "ą¤øą¤‚ą¤¤ą„ƒą¤Ŗą„ą¤¤ą¤æ:", + "download": "ą¤”ą¤¾ą¤‰ą¤Øą¤²ą„‹ą¤” ą¤•ą¤°ą„‡ą¤‚" + }, + "compress": { + "title": "ą¤•ą¤®ą„ą¤Ŗą„ą¤°ą„‡ą¤ø", + "header": "PDF ą¤•ą¤®ą„ą¤Ŗą„ą¤°ą„‡ą¤ø ą¤•ą¤°ą„‡ą¤‚", + "credit": "यह ą¤øą„‡ą¤µą¤¾ PDF ą¤•ą¤®ą„ą¤Ŗą„ą¤°ą„‡ą¤ø/ą¤…ą¤Øą„ą¤•ą„‚ą¤²ą¤Ø ą¤•ą„‡ ą¤²ą¤æą¤ qpdf का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤¤ą„€ ą¤¹ą„ˆą„¤", + "grayscale": { + "label": "ą¤øą¤‚ą¤Ŗą„€ą¤”ą¤¼ą¤Ø ą¤•ą„‡ ą¤²ą¤æą¤ ą¤—ą„ą¤°ą„‡ą¤øą„ą¤•ą„‡ą¤² ą¤²ą¤¾ą¤—ą„‚ ą¤•ą¤°ą„‡ą¤‚" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "ą¤…ą¤Øą„ą¤•ą„‚ą¤²ą¤Ø ą¤øą„ą¤¤ą¤°:", + "4": "ą¤øą„ą¤µą¤¤ą¤ƒ ą¤®ą„‹ą¤” - PDF ą¤•ą„‹ ą¤øą¤Ÿą„€ą¤• आकार ą¤Ŗą„ą¤°ą¤¾ą¤Ŗą„ą¤¤ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤—ą„ą¤£ą¤µą¤¤ą„ą¤¤ą¤¾ ą¤•ą„‹ ą¤øą„ą¤µą¤¤ą¤ƒ ą¤øą¤®ą¤¾ą¤Æą„‹ą¤œą¤æą¤¤ करता ą¤¹ą„ˆ", + "5": "ą¤…ą¤Ŗą„‡ą¤•ą„ą¤·ą¤æą¤¤ PDF आकार (ą¤œą„ˆą¤øą„‡ 25MB, 10.8MB, 25KB)" + }, + "submit": "ą¤•ą¤®ą„ą¤Ŗą„ą¤°ą„‡ą¤ø ą¤•ą¤°ą„‡ą¤‚" + }, + "decrypt": { + "passwordPrompt": "यह फ़ाइल ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤øą„‡ ą¤øą„ą¤°ą¤•ą„ą¤·ą¤æą¤¤ ą¤¹ą„ˆą„¤ ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚:", + "cancelled": "PDF ą¤•ą„‡ ą¤²ą¤æą¤ ą¤•ą¤¾ą¤°ą„ą¤°ą¤µą¤¾ą¤ˆ ą¤°ą¤¦ą„ą¤¦ ą¤•ą„€ ą¤—ą¤ˆ: {0}", + "noPassword": "ą¤ą¤Øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿą„‡ą¤” PDF ą¤•ą„‡ ą¤²ą¤æą¤ ą¤•ą„‹ą¤ˆ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤Øą¤¹ą„€ą¤‚ दिया गया: {0}", + "invalidPassword": "ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤øą¤¹ą„€ ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” ą¤•ą„‡ साऄ ą¤Ŗą„ą¤Øą¤ƒ ą¤Ŗą„ą¤°ą¤Æą¤¾ą¤ø ą¤•ą¤°ą„‡ą¤‚ą„¤", + "invalidPasswordHeader": "गलत ą¤Ŗą¤¾ą¤øą¤µą¤°ą„ą¤” या ą¤…ą¤øą¤®ą¤°ą„ą¤„ą¤æą¤¤ ą¤ą¤Øą„ą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤¶ą¤Ø PDF ą¤•ą„‡ ą¤²ą¤æą¤: {0}", + "unexpectedError": "फ़ाइल ą¤Ŗą„ą¤°ą„‹ą¤øą„‡ą¤ø ą¤•ą¤°ą¤Øą„‡ ą¤®ą„‡ą¤‚ ą¤¤ą„ą¤°ą„ą¤Ÿą¤æ ą¤¹ą„ą¤ˆą„¤ ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤Ŗą„ą¤Øą¤ƒ ą¤Ŗą„ą¤°ą¤Æą¤¾ą¤ø ą¤•ą¤°ą„‡ą¤‚ą„¤", + "serverError": "ą¤”ą¤æą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ ą¤•ą¤°ą¤¤ą„‡ समय ą¤øą¤°ą„ą¤µą¤° ą¤¤ą„ą¤°ą„ą¤Ÿą¤æ: {0}", + "success": "फ़ाइल ą¤øą¤«ą¤²ą¤¤ą¤¾ą¤Ŗą„‚ą¤°ą„ą¤µą¤• ą¤”ą¤æą¤•ą„ą¤°ą¤æą¤Ŗą„ą¤Ÿ ą¤•ą„€ ą¤—ą¤ˆą„¤" + }, + "multiTool-advert": { + "message": "यह ą¤øą„ą¤µą¤æą¤§ą¤¾ ą¤¹ą¤®ą¤¾ą¤°ą„‡ ą¤®ą¤²ą„ą¤Ÿą„€-ą¤Ÿą„‚ą¤² ą¤Ŗą„ƒą¤·ą„ą¤  ą¤®ą„‡ą¤‚ ą¤­ą„€ ą¤‰ą¤Ŗą¤²ą¤¬ą„ą¤§ ą¤¹ą„ˆą„¤ ą¤¬ą„‡ą¤¹ą¤¤ą¤° ą¤Ŗą„ƒą¤·ą„ą¤ -दर-ą¤Ŗą„ƒą¤·ą„ą¤  UI और ą¤…ą¤¤ą¤æą¤°ą¤æą¤•ą„ą¤¤ ą¤øą„ą¤µą¤æą¤§ą¤¾ą¤“ą¤‚ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤‡ą¤øą„‡ ą¤¦ą„‡ą¤–ą„‡ą¤‚!" + }, + "pageRemover": { + "title": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤¹ą¤Ÿą¤¾ą¤Øą„‡ वाला", + "header": "PDF ą¤Ŗą„ƒą¤·ą„ą¤  ą¤¹ą¤Ÿą¤¾ą¤Øą„‡ वाला", + "pagesToDelete": "ą¤¹ą¤Ÿą¤¾ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Ŗą„ƒą¤·ą„ą¤  (ą¤Ŗą„ƒą¤·ą„ą¤  ą¤øą¤‚ą¤–ą„ą¤Æą¤¾ą¤“ą¤‚ ą¤•ą„€ ą¤…ą¤²ą„ą¤Ŗą¤µą¤æą¤°ą¤¾ą¤® ą¤øą„‡ अलग ą¤øą„‚ą¤šą„€ ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚):", + "submit": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "placeholder": "(ą¤œą„ˆą¤øą„‡ 1,2,6 या 1-10,15-30)" + }, + "imageToPDF": { + "title": "छवि ą¤øą„‡ PDF", + "header": "छवि ą¤øą„‡ PDF", + "submit": "ą¤¬ą¤¦ą¤²ą„‡ą¤‚", + "selectLabel": "छवि फिट ą¤µą¤æą¤•ą¤²ą„ą¤Ŗ", + "fillPage": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤­ą¤°ą„‡ą¤‚", + "fitDocumentToImage": "छवि ą¤•ą„‡ ą¤…ą¤Øą„ą¤øą¤¾ą¤° ą¤Ŗą„ƒą¤·ą„ą¤  फिट ą¤•ą¤°ą„‡ą¤‚", + "maintainAspectRatio": "ą¤†ą¤Øą„ą¤Ŗą¤¾ą¤¤ą¤æą¤• ą¤…ą¤Øą„ą¤Ŗą¤¾ą¤¤ ą¤¬ą¤Øą¤¾ą¤ ą¤°ą¤–ą„‡ą¤‚", + "selectText": { + "2": "PDF ą¤øą„ą¤µą¤¤ą¤ƒ ą¤˜ą„ą¤®ą¤¾ą¤ą¤‚", + "3": "ą¤¬ą¤¹ą„ फ़ाइल ą¤¤ą¤°ą„ą¤• (ą¤•ą„‡ą¤µą¤² ą¤•ą¤ˆ ą¤›ą¤µą¤æą¤Æą„‹ą¤‚ ą¤•ą„‡ साऄ काम ą¤•ą¤°ą¤¤ą„‡ समय ą¤øą¤•ą„ą¤·ą¤®)", + "4": "ą¤ą¤•ą¤² PDF ą¤®ą„‡ą¤‚ ą¤®ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚", + "5": "अलग-अलग PDF ą¤®ą„‡ą¤‚ ą¤¬ą¤¦ą¤²ą„‡ą¤‚" + } + }, + "PDFToCSV": { + "title": "PDF ą¤øą„‡ CSV", + "header": "PDF ą¤øą„‡ CSV", + "prompt": "तालिका ą¤Øą¤æą¤•ą¤¾ą¤²ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤Ŗą„ƒą¤·ą„ą¤  ą¤šą„ą¤Øą„‡ą¤‚", + "submit": "ą¤Øą¤æą¤•ą¤¾ą¤²ą„‡ą¤‚" + }, + "split-by-size-or-count": { + "title": "आकार या ą¤—ą¤æą¤Øą¤¤ą„€ ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ PDF विभाजित ą¤•ą¤°ą„‡ą¤‚", + "header": "आकार या ą¤—ą¤æą¤Øą¤¤ą„€ ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ PDF विभाजित ą¤•ą¤°ą„‡ą¤‚", + "type": { + "label": "विभाजन ą¤Ŗą„ą¤°ą¤•ą¤¾ą¤° ą¤šą„ą¤Øą„‡ą¤‚", + "size": "आकार ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾", + "pageCount": "ą¤Ŗą„ƒą¤·ą„ą¤  ą¤—ą¤æą¤Øą¤¤ą„€ ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾", + "docCount": "ą¤¦ą¤øą„ą¤¤ą¤¾ą¤µą„‡ą¤œą¤¼ ą¤—ą¤æą¤Øą¤¤ą„€ ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾" + }, + "value": { + "label": "मान ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚", + "placeholder": "आकार (ą¤œą„ˆą¤øą„‡ 2MB या 3KB) या ą¤—ą¤æą¤Øą¤¤ą„€ (ą¤œą„ˆą¤øą„‡ 5) ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚" + }, + "submit": "जमा ą¤•ą¤°ą„‡ą¤‚" + }, + "printFile": { + "title": "फ़ाइल ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿ ą¤•ą¤°ą„‡ą¤‚", + "header": "ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿą¤° पर फ़ाइल ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿ ą¤•ą¤°ą„‡ą¤‚", + "selectText": { + "1": "ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ फ़ाइल ą¤šą„ą¤Øą„‡ą¤‚", + "2": "ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿą¤° नाम ą¤¦ą¤°ą„ą¤œ ą¤•ą¤°ą„‡ą¤‚" + }, + "submit": "ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿ ą¤•ą¤°ą„‡ą¤‚" + }, + "licenses": { + "nav": "ą¤²ą¤¾ą¤‡ą¤øą„‡ą¤‚ą¤ø", + "title": "ą¤¤ą„ƒą¤¤ą„€ą¤Æ-ą¤Ŗą¤•ą„ą¤· ą¤²ą¤¾ą¤‡ą¤øą„‡ą¤‚ą¤ø", + "header": "ą¤¤ą„ƒą¤¤ą„€ą¤Æ-ą¤Ŗą¤•ą„ą¤· ą¤²ą¤¾ą¤‡ą¤øą„‡ą¤‚ą¤ø", + "module": "ą¤®ą„‰ą¤”ą„ą¤Æą„‚ą¤²", + "version": "ą¤øą¤‚ą¤øą„ą¤•ą¤°ą¤£", + "license": "ą¤²ą¤¾ą¤‡ą¤øą„‡ą¤‚ą¤ø" + }, + "survey": { + "nav": "ą¤øą¤°ą„ą¤µą„‡ą¤•ą„ą¤·ą¤£", + "title": "Stirling-PDF ą¤øą¤°ą„ą¤µą„‡ą¤•ą„ą¤·ą¤£", + "description": "Stirling PDF ą¤®ą„‡ą¤‚ ą¤•ą„‹ą¤ˆ ą¤Ÿą„ą¤°ą„ˆą¤•ą¤æą¤‚ą¤— ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„ˆ ą¤‡ą¤øą¤²ą¤æą¤ हम Stirling-PDF ą¤•ą„‹ ą¤¬ą„‡ą¤¹ą¤¤ą¤° ą¤¬ą¤Øą¤¾ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤…ą¤Ŗą¤Øą„‡ ą¤‰ą¤Ŗą¤Æą„‹ą¤—ą¤•ą¤°ą„ą¤¤ą¤¾ą¤“ą¤‚ ą¤øą„‡ ą¤øą„ą¤Øą¤Øą¤¾ ą¤šą¤¾ą¤¹ą¤¤ą„‡ ą¤¹ą„ˆą¤‚!", + "changes": "ą¤Ŗą¤æą¤›ą¤²ą„‡ ą¤øą¤°ą„ą¤µą„‡ą¤•ą„ą¤·ą¤£ ą¤•ą„‡ बाद ą¤øą„‡ Stirling-PDF बदल गया ą¤¹ą„ˆ! अधिक ą¤œą¤¾ą¤Øą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤¹ą¤®ą¤¾ą¤°ą„€ ą¤¬ą„ą¤²ą„‰ą¤— ą¤Ŗą„‹ą¤øą„ą¤Ÿ यहाँ ą¤¦ą„‡ą¤–ą„‡ą¤‚:", + "changes2": "इन ą¤Ŗą¤°ą¤æą¤µą¤°ą„ą¤¤ą¤Øą„‹ą¤‚ ą¤•ą„‡ साऄ हम ą¤­ą„ą¤—ą¤¤ą¤¾ą¤Ø ą¤•ą¤æą¤ ą¤—ą¤ ą¤µą„ą¤Æą¤¾ą¤µą¤øą¤¾ą¤Æą¤æą¤• ą¤øą¤®ą¤°ą„ą¤„ą¤Ø और ą¤µą¤æą¤¤ą„ą¤¤ ą¤Ŗą„‹ą¤·ą¤£ ą¤Ŗą„ą¤°ą¤¾ą¤Ŗą„ą¤¤ कर ą¤°ą¤¹ą„‡ ą¤¹ą„ˆą¤‚", + "please": "ą¤•ą„ƒą¤Ŗą¤Æą¤¾ ą¤¹ą¤®ą¤¾ą¤°ą„‡ ą¤øą¤°ą„ą¤µą„‡ą¤•ą„ą¤·ą¤£ ą¤®ą„‡ą¤‚ भाग ą¤²ą„‡ą¤‚!", + "disabled": "(ą¤øą¤°ą„ą¤µą„‡ą¤•ą„ą¤·ą¤£ ą¤Ŗą„‰ą¤Ŗą¤…ą¤Ŗ ą¤†ą¤—ą¤¾ą¤®ą„€ ą¤…ą¤Ŗą¤”ą„‡ą¤Ÿ ą¤®ą„‡ą¤‚ ą¤…ą¤•ą„ą¤·ą¤® कर दिया ą¤œą¤¾ą¤ą¤—ą¤¾ ą¤²ą„‡ą¤•ą¤æą¤Ø ą¤Ŗą„ƒą¤·ą„ą¤  ą¤•ą„‡ पाद ą¤®ą„‡ą¤‚ ą¤‰ą¤Ŗą¤²ą¤¬ą„ą¤§ ą¤°ą¤¹ą„‡ą¤—ą¤¾)", + "button": "ą¤øą¤°ą„ą¤µą„‡ą¤•ą„ą¤·ą¤£ ą¤®ą„‡ą¤‚ भाग ą¤²ą„‡ą¤‚", + "dontShowAgain": "फिर मत दिखाना", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "छवियां ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "header": "छवियां ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "removeImage": "छवियां ą¤¹ą¤Ÿą¤¾ą¤ą¤‚", + "submit": "छवियां ą¤¹ą¤Ÿą¤¾ą¤ą¤‚" + }, + "splitByChapters": { + "title": "ą¤…ą¤§ą„ą¤Æą¤¾ą¤Æą„‹ą¤‚ ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ PDF विभाजित ą¤•ą¤°ą„‡ą¤‚", + "header": "ą¤…ą¤§ą„ą¤Æą¤¾ą¤Æą„‹ą¤‚ ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ PDF विभाजित ą¤•ą¤°ą„‡ą¤‚", + "bookmarkLevel": "ą¤¬ą„ą¤•ą¤®ą¤¾ą¤°ą„ą¤• ą¤øą„ą¤¤ą¤°", + "includeMetadata": "ą¤®ą„‡ą¤Ÿą¤¾ą¤”ą„‡ą¤Ÿą¤¾ शामिल ą¤•ą¤°ą„‡ą¤‚", + "allowDuplicates": "ą¤”ą„ą¤Ŗą„ą¤²ą¤æą¤•ą„‡ą¤Ÿ ą¤•ą„€ ą¤…ą¤Øą„ą¤®ą¤¤ą¤æ ą¤¦ą„‡ą¤‚", + "desc": { + "1": "यह ą¤Ÿą„‚ą¤² PDF फ़ाइल ą¤•ą„‹ ą¤‰ą¤øą¤•ą„€ ą¤…ą¤§ą„ą¤Æą¤¾ą¤Æ ą¤øą¤‚ą¤°ą¤šą¤Øą¤¾ ą¤•ą„‡ आधार पर ą¤•ą¤ˆ PDF ą¤®ą„‡ą¤‚ विभाजित करता ą¤¹ą„ˆą„¤", + "2": "ą¤¬ą„ą¤•ą¤®ą¤¾ą¤°ą„ą¤• ą¤øą„ą¤¤ą¤°: विभाजन ą¤•ą„‡ ą¤²ą¤æą¤ ą¤¬ą„ą¤•ą¤®ą¤¾ą¤°ą„ą¤• का ą¤øą„ą¤¤ą¤° ą¤šą„ą¤Øą„‡ą¤‚ (ą¤¶ą„€ą¤°ą„ą¤· ą¤øą„ą¤¤ą¤° ą¤•ą„‡ ą¤²ą¤æą¤ 0, ą¤¦ą„‚ą¤øą¤°ą„‡ ą¤øą„ą¤¤ą¤° ą¤•ą„‡ ą¤²ą¤æą¤ 1, ą¤‡ą¤¤ą„ą¤Æą¤¾ą¤¦ą¤æ)ą„¤", + "3": "ą¤®ą„‡ą¤Ÿą¤¾ą¤”ą„‡ą¤Ÿą¤¾ शामिल ą¤•ą¤°ą„‡ą¤‚: यदि चयनित ą¤¹ą„ˆ, ą¤¤ą„‹ ą¤®ą„‚ą¤² PDF का ą¤®ą„‡ą¤Ÿą¤¾ą¤”ą„‡ą¤Ÿą¤¾ ą¤Ŗą„ą¤°ą¤¤ą„ą¤Æą„‡ą¤• विभाजित PDF ą¤®ą„‡ą¤‚ शामिल किया ą¤œą¤¾ą¤ą¤—ą¤¾ą„¤", + "4": "ą¤”ą„ą¤Ŗą„ą¤²ą¤æą¤•ą„‡ą¤Ÿ ą¤•ą„€ ą¤…ą¤Øą„ą¤®ą¤¤ą¤æ ą¤¦ą„‡ą¤‚: यदि चयनित ą¤¹ą„ˆ, ą¤¤ą„‹ ą¤ą¤• ą¤¹ą„€ ą¤Ŗą„ƒą¤·ą„ą¤  पर ą¤•ą¤ˆ ą¤¬ą„ą¤•ą¤®ą¤¾ą¤°ą„ą¤• ą¤•ą„‹ अलग PDF ą¤¬ą¤Øą¤¾ą¤Øą„‡ ą¤•ą„€ ą¤…ą¤Øą„ą¤®ą¤¤ą¤æ ą¤¦ą„‡ą¤¤ą¤¾ ą¤¹ą„ˆą„¤" + }, + "submit": "PDF विभाजित ą¤•ą¤°ą„‡ą¤‚" + }, + "fileChooser": { + "click": "ą¤•ą„ą¤²ą¤æą¤• ą¤•ą¤°ą„‡ą¤‚", + "or": "या", + "dragAndDrop": "ą¤–ą„€ą¤‚ą¤šą„‡ą¤‚ और ą¤›ą„‹ą¤”ą¤¼ą„‡ą¤‚", + "dragAndDropPDF": "PDF फ़ाइल ą¤–ą„€ą¤‚ą¤šą„‡ą¤‚ और ą¤›ą„‹ą¤”ą¤¼ą„‡ą¤‚", + "dragAndDropImage": "छवि फ़ाइल ą¤–ą„€ą¤‚ą¤šą„‡ą¤‚ और ą¤›ą„‹ą¤”ą¤¼ą„‡ą¤‚", + "hoveredDragAndDrop": "फ़ाइल(ą„‡ą¤‚) यहाँ ą¤–ą„€ą¤‚ą¤šą„‡ą¤‚ और ą¤›ą„‹ą¤”ą¤¼ą„‡ą¤‚", + "extractPDF": "निकालना..." + }, + "releases": { + "footer": "ą¤°ą¤æą¤²ą„€ą¤œą¤¼", + "title": "ą¤°ą¤æą¤²ą„€ą¤œą¤¼ ą¤Øą„‹ą¤Ÿą„ą¤ø", + "header": "ą¤°ą¤æą¤²ą„€ą¤œą¤¼ ą¤Øą„‹ą¤Ÿą„ą¤ø", + "current": { + "version": "ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤°ą¤æą¤²ą„€ą¤œą¤¼" + }, + "note": "ą¤°ą¤æą¤²ą„€ą¤œą¤¼ ą¤Øą„‹ą¤Ÿą„ą¤ø ą¤•ą„‡ą¤µą¤² ą¤…ą¤‚ą¤—ą„ą¤°ą„‡ą¤œą„€ ą¤®ą„‡ą¤‚ ą¤‰ą¤Ŗą¤²ą¤¬ą„ą¤§ ą¤¹ą„ˆą¤‚" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/hr-HR/translation.json b/frontend/public/locales/hr-HR/translation.json new file mode 100644 index 000000000..d5bb80545 --- /dev/null +++ b/frontend/public/locales/hr-HR/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Veličina pisma", + "fontName": "Ime pisma", + "title": "Dodavanje brojeva stranica", + "header": "Dodavanje brojeva stranica", + "selectText": { + "1": "Odaberi PDF datoteku:", + "2": "Veličina margine", + "3": "Položaj", + "4": "Početni broj", + "5": "Brojanje stranica", + "6": "Prilagođeni tekst" + }, + "customTextDesc": "Prilagođeni tekst", + "numberPagesDesc": "Koje stranice numerirati, zadano je 'sve', također prihvaća 1-5 ili 2,5,9 itd.", + "customNumberDesc": "Zadano je {n}, također prihvaća 'Stranica {n} od {total}', 'Tekst-{n}', '{ime datoteke}-{n}'", + "submit": "Dodaj brojeve stranica" + }, + "pdfPrompt": "Odaberi PDF(ove)", + "multiPdfPrompt": "Odaberi PDF-ove (2+)", + "multiPdfDropPrompt": "Odaberi (ili povuci i ispusti) sve potrebne PDF-ove", + "imgPrompt": "Odaberi sliku (slike)", + "genericSubmit": "PoÅ”alji", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Upozorenje: Ovaj proces može trajati i do minutu, u zavisnosti od veličine dokumenta", + "pageOrderPrompt": "Prilagođeni redoslijed stranica (unesi listu brojeva stranica ili funkcija, kao Å”to su 2n+1, razdvojene zarezima) :", + "pageSelectionPrompt": "Prilagođeni odabir stranica (unesi listu brojeva stranica ili funkcija, kao Å”to su 2n+1, razdvojene zarezima) :", + "goToPage": "Idi na stranicu", + "true": "Točno", + "false": "Netočno", + "unknown": "Nepoznato", + "save": "Spremi", + "saveToBrowser": "spremi u Preglednik", + "close": "Zatvori", + "filesSelected": "odabrane datoteke", + "noFavourites": "Nema dodanih favorita", + "downloadComplete": "Preuzimanje zavrÅ”eno", + "bored": "Dosađujete se čekajući?", + "alphabet": "Abeceda", + "downloadPdf": "Preuzmi PDF", + "text": "Tekst", + "font": "Pismo", + "selectFillter": "-- Odaberi --", + "pageNum": "Broj stranice", + "sizes": { + "small": "Malo", + "medium": "Srednje", + "large": "Veliko", + "x-large": "Jako veliko" + }, + "error": { + "pdfPassword": "PDF dokument je Å”ifriran i zaporka nije dana ili je netočna", + "_value": "GreÅ”ka", + "sorry": "Oprostite zbog problema!", + "needHelp": "Trebate pomoć / PronaÅ”li ste problem?", + "contactTip": "Ako i dalje imate problema, ne ustručavajte se obratiti nam se za pomoć. Tiket možete poslati na naÅ”oj GitHub stranici ili nas kontaktirati putem Discorda:", + "404": { + "head": "404 - Stranica nije pronađena | Ups, spotaknuli smo se u kodu!", + "1": "Čini se da ne možemo pronaći stranicu koju tražite.", + "2": "NeÅ”to je poÅ”lo po zlu" + }, + "github": "PoÅ”aljite ticket na GitHub", + "showStack": "Prikaži Stack Trace", + "copyStack": "Kopiraj Stack Trace", + "githubSubmit": "GitHub - PoÅ”aljite ticket", + "discordSubmit": "Discord - PoÅ”alji objavu podrÅ”ke" + }, + "delete": "IzbriÅ”i", + "username": "Korisničko ime", + "password": "Zaporka", + "welcome": "DobrodoÅ”li", + "property": "Svojstvo", + "black": "Crno", + "white": "Bijelo", + "red": "Crveno", + "green": "Zeleno", + "blue": "Plavo", + "custom": "Prilagođeno...", + "WorkInProgess": "Radovi u tijeku, u slučaju greÅ”aka molimo prijavite probleme!", + "poweredBy": "Pokreće", + "yes": "Da", + "no": "Ne", + "changedCredsMessage": "Podaci za prijavu uspjeÅ”no promijenjeni!", + "notAuthenticatedMessage": "Korisnik nije autentificiran.", + "userNotFoundMessage": "Korisnik nije pronađen.", + "incorrectPasswordMessage": "Kriva zaporka.", + "usernameExistsMessage": "Korisničko ime već postoji", + "invalidUsernameMessage": "Nevažeće korisničko ime, korisničko ime može sadržavati samo slova, brojke i sljedeće posebne znakove @._+- ili mora biti važeća adresa e-poÅ”te.", + "invalidPasswordMessage": "Lozinka ne smije biti prazna i ne smije počinjati ni zavrÅ”avati sa razmakom.", + "confirmPasswordErrorMessage": "Nova lozinka i potvrda nove lozinke moraju biti identične.", + "deleteCurrentUserMessage": "Nije moguće izbrisati trenutno prijavljenog korisnika.", + "deleteUsernameExistsMessage": "Korisničko ime ne postoji i ne može se izbrisati.", + "downgradeCurrentUserMessage": "Nije moguće vratiti unazad ulogu trenutnog korisnika", + "disabledCurrentUserMessage": "Trenutni korisnik ne može biti onemogućen", + "downgradeCurrentUserLongMessage": "Nije moguće vratiti unazad ulogu trenutnog korisnika. Dakle, trenutni korisnik neće biti prikazan.", + "userAlreadyExistsOAuthMessage": "Korisnik već postoji kao OAuth2 korisnik.", + "userAlreadyExistsWebMessage": "Korisnik već postoji kao web korisnik.", + "oops": "Ups!", + "help": "Pomoć", + "goHomepage": "Idi na početnu stranicu", + "joinDiscord": "Pridruži se naÅ”em Discord serveru", + "seeDockerHub": "Vidi Docker Hub", + "visitGithub": "Posjeti Github Repository", + "donate": "Doniraj", + "color": "Boja", + "sponsor": "Sponzor", + "info": "Informacije", + "pro": "Pro", + "page": "Stranica", + "pages": "Stranice", + "loading": "Učitavanje...", + "addToDoc": "Dodaj u dokument", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Politika privatnosti", + "terms": "Uspe sodržine", + "accessibility": "Dostupnost", + "cookie": "Politika kolačića", + "impressum": "Vedro ishoda", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Pipeline Meni (Beta)", + "uploadButton": "Prenesi prilagođeno", + "configureButton": "Konfigurirati", + "defaultOption": "Prilagođeno", + "submitButton": "PoÅ”alji", + "help": "Pipeline Pomoć", + "scanHelp": "Pomoć za skeniranje mapa", + "deletePrompt": "Jeste li sigurni da želite obrisati pipeline?", + "tags": "automatizacija,sekvenciranje,skriptirano,batch-process", + "title": "Tok rada" + }, + "pipelineOptions": { + "header": "Pipeline Konfiguracija", + "pipelineNameLabel": "Pipeline Ime", + "saveSettings": "Spremi Postavke", + "pipelineNamePrompt": "Unesite naziv pipeline-a ovdje", + "selectOperation": "Odaberite Operaciju", + "addOperationButton": "Dodajte operaciju", + "pipelineHeader": "Pipeline:", + "saveButton": "Preuzmi datoteku", + "validateButton": "Potvrdi" + }, + "enterpriseEdition": { + "button": "Ažurirajte na Pro", + "warning": "Ova funkcija je dostupna samo pro korisnicima.", + "yamlAdvert": "Stirling PDF Pro podrzava konfiguiracione datoteke u formati YAML i druga osobine SSO.", + "ssoAdvert": "Tražite joÅ” funkcija za upravljanje korisnicima? Razmotrite Stirling PDF Pro" + }, + "analytics": { + "title": "Želite li da stvarate Stirling PDF bolji?", + "paragraph1": "Stirling PDF ima uključene analitike koje nam pomažu da proizvod poboljÅ”amo. Niste pratili nikakva osobna informacija ni sadržaj datoteka.", + "paragraph2": "Razmotrite omogućivanje analitičkih podataka kako biste stvorili Stirling-PDF veće i da bismo bolje razumeli naÅ”ih korisnika.", + "enable": "Omogući analitike", + "disable": "Onemogući analitike", + "settings": "Možete promijeniti postavke za analitike u datoteci config/settings.yml" + }, + "navbar": { + "favorite": "Favoriti", + "recent": "New and recently updated", + "darkmode": "Tamni Način Rada", + "language": "Jezici", + "settings": "Postavke", + "allTools": "Alati", + "multiTool": "Multi Tools (Alati)", + "search": "Search", + "sections": { + "organize": "Organizirati", + "convertTo": "Pretvori u PDF", + "convertFrom": "Pretvori iz PDF", + "security": "Potpis & sigurnost", + "advance": "Napredno", + "edit": "Pregled & Uređivanje", + "popular": "Popularno" + } + }, + "settings": { + "title": "Postavke", + "update": "Dostupno ažuriranje", + "updateAvailable": "{0} je trenutno instalirana verzija. Dostupna je nova verzija ({1}).", + "appVersion": "Verzija aplikacije:", + "downloadOption": { + "title": "Odaberite opciju preuzimanja (Za preuzimanje pojedinačnih datoteka bez zip formata):", + "1": "Otvori u istom prozoru", + "2": "Otvori u novom prozoru", + "3": "Preuzmi datoteku" + }, + "zipThreshold": "Spremi .zip datoteku kada broj preuzetih datoteka pređe", + "signOut": "Odjava", + "accountSettings": "Postavke računa", + "bored": { + "help": "Omogućuje \"easter egg\" igru" + }, + "cacheInputs": { + "name": "Spremi unose obrazaca", + "help": "omogućiti pohranjivanje prethodno koriÅ”tenih ulaza za buduća izvođenja" + } + }, + "changeCreds": { + "title": "Promijeni pristupne podatke", + "header": "Ažurirajte korisničke podatke", + "changePassword": "Koristite zadanu lozinku za prijavu. Unesite novu lozinku", + "newUsername": "Novo korisničko ime", + "oldPassword": "Trenutna zaporka", + "newPassword": "Nova zaporka", + "confirmNewPassword": "Potvrdite novu lozinku", + "submit": "Potvrdi" + }, + "account": { + "title": "Postavke računa", + "accountSettings": "Postavke računa", + "adminSettings": "Admin Postavka - Pregled i dodavanje korisnika", + "userControlSettings": "Postavke kontrole korisnika", + "changeUsername": "Promijeni korisničko ime", + "newUsername": "Novo korisničko ime", + "password": "Potvrda lozinke", + "oldPassword": "Stara zaporka", + "newPassword": "Nova zaporka", + "changePassword": "Promijeni lozinku", + "confirmNewPassword": "Potvrdi novu lozinku", + "signOut": "Odjava", + "yourApiKey": "Tvoj API ključ", + "syncTitle": "Sinkronizirajte postavke preglednika s računom", + "settingsCompare": "Usporedba postavki:", + "property": "Svojstvo", + "webBrowserSettings": "Postavka web-preglednika", + "syncToBrowser": "Sinkronizacija Račun -> Preglednik", + "syncToAccount": "Sinkronizacija Račun <- Preglednik" + }, + "adminUserSettings": { + "title": "Postavka kontrole korisnika", + "header": "Postavka kontrole korisnika za administratora", + "admin": "Administrator", + "user": "Korisnik", + "addUser": "Dodaj novog korisnika", + "deleteUser": "ObriÅ”i korisnika", + "confirmDeleteUser": "Treba li obračunati ovaj korisnika?", + "confirmChangeUserStatus": "Treba li isključiti/uključiti ovog korisnika?", + "usernameInfo": "Korisničko ime može sadržavati samo slova, brojke i sljedeće posebne znakove @._+- ili mora biti važeća adresa e-poÅ”te.", + "roles": "Uloge", + "role": "Uloga", + "actions": "Akcije", + "apiUser": "Korisnik s ograničenim API pristupom", + "extraApiUser": "Dodatni korisnik s ograničenim API pristupom", + "webOnlyUser": "Web Korisnik", + "demoUser": "Demo korisnik (Bez prilagođenih Postavki)", + "internalApiUser": "Interni API Korisnik", + "forceChange": "Prisiliti korisnika da promijeni lozinku prilikom prijave", + "submit": "Spremi korisnika", + "changeUserRole": "Promijenite korisničku ulogu", + "authenticated": "Autentificirano", + "editOwnProfil": "Uredi vlastit profil", + "enabledUser": "Omotljiv korisnik", + "disabledUser": "Onemogućen korisnik", + "activeUsers": "Aktivni korisnici:", + "disabledUsers": "Isključeni korisnici:", + "totalUsers": "Ukupan broj korisnika:", + "lastRequest": "Zadnji zahtjev", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Database Import/Export", + "header": "Database Import/Export", + "fileName": "Ime datoteke", + "creationDate": "Datum stvaranja", + "fileSize": "Veličina datoteke", + "deleteBackupFile": "ObriÅ”i zadao sažeto datoteke", + "importBackupFile": "Uvezi sažeto datoteku", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Preuzmi sažeto datoteku", + "info_1": "Kada uvažavate podatke, je ključno sigurno imati ispravan struktur. Ako niste sigurni Å”ta uradite, tražite savjet i podrÅ”ku od professionala. GreÅ”ka u strukturi može uzrokovati greÅ”ke u aplikaciji, do i uključujući potpunu nevjerojatnost funkcionalnosti aplikacije.", + "info_2": "Ime datoteke nije relevantno prijevezi. Buduće bit će ponovno oznaceno za određeni format backup_user_yyyyMMddHHmm.sql, čime se osigurava konzistentna nazivnica.", + "submit": "Uvezi sažeto", + "importIntoDatabaseSuccessed": "Uvez u bazu podataka uspio", + "backupCreated": "Database backup successful", + "fileNotFound": "File not Found", + "fileNullOrEmpty": "Datoteka ne smije biti null ili prazna", + "failedImportFile": "Failed Import File", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "VaÅ” sesija je istekla. Molim vas da osvježite stranicu i pokuÅ”ate ponovno.", + "refreshPage": "Refresh Page" + }, + "home": { + "desc": "Sve na jednom mjestu za sve vaÅ”e PDF potrebe.", + "searchBar": "Pretraži funkcije...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Pregledaj, komentiraj, dodaj tekst ili slike" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "PDF ViÅ”estruki alat", + "desc": "Spajanje, rotiranje, preuređivanje i uklanjanje stranica" + }, + "merge": { + "title": "Spajanje", + "desc": "Jednostavno spojite viÅ”e PDF-ova u jedan." + }, + "split": { + "title": "Razdvajanje", + "desc": "Razdvojite PDF-ove u viÅ”e dokumenata" + }, + "rotate": { + "title": "Rotacija", + "desc": "Jednostavno rotirajte vaÅ”e PDF-ove." + }, + "imageToPdf": { + "title": "Slika u PDF", + "desc": "Pretvorite sliku (PNG, JPEG, GIF) u PDF." + }, + "pdfToImage": { + "title": "PDF u Sliku", + "desc": "Pretvorite PDF u sliku. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Organiziranje", + "desc": "Uklonite/preuredite stranice bilo kojim redoslijedom" + }, + "addImage": { + "title": "Dodaj sliku", + "desc": "Dodaje sliku na zadano mjesto u PDF-u" + }, + "watermark": { + "title": "Dodaj vodeni žig", + "desc": "DDodajte prilagođeni vodeni žig svom PDF dokumentu." + }, + "permissions": { + "title": "Promjena dopuÅ”tenja", + "desc": "Promijenite dopuÅ”tenja svog PDF dokumenta" + }, + "removePages": { + "title": "Ukloniti", + "desc": "IzbriÅ”ite neželjene stranice iz svog PDF dokumenta." + }, + "addPassword": { + "title": "Dodaj lozinku", + "desc": "Å ifrirajte svoj PDF dokument lozinkom.." + }, + "removePassword": { + "title": "Ukloni lozinku", + "desc": "Uklonite zaÅ”titu lozinkom sa svog PDF dokumenta.." + }, + "compressPdfs": { + "title": "Komprimiraj", + "desc": "Komprimirajte PDF-ove kako biste smanjili njihovu veličinu." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Promjena metapodataka", + "desc": "Promjeni/Ukloni/Dodaj metapodatke iz PDF dokumenta" + }, + "fileToPDF": { + "title": "Pretvori datoteku u PDF", + "desc": "Pretvorite gotovo sve datoteke u PDF (DOCX, PNG, XLS, PPT, TXT i viÅ”e)" + }, + "ocr": { + "title": "OCR / ČiŔćenje skeniranih dokumenata", + "desc": "ČiŔćenje skenira i otkriva tekst sa slika unutar PDF-a i ponovno ga dodaje kao tekst." + }, + "extractImages": { + "title": "Ekstrakt slika", + "desc": "Izdvaja sve slike iz PDF-a i sprema ih u zip format" + }, + "pdfToPDFA": { + "title": "PDF u PDF/A", + "desc": "Pretvorite PDF u PDF/A za dugoročnu pohranu" + }, + "PDFToWord": { + "title": "PDF u Word", + "desc": "Pretvorite PDF u Word formate (DOC, DOCX i ODT)" + }, + "PDFToPresentation": { + "title": "PDF u Prezentaciju", + "desc": "Pretvorite PDF u formate za prezentaciju (PPT, PPTX i ODP)" + }, + "PDFToText": { + "title": "PDF u RTF (Tekst)", + "desc": "Pretvorite PDF u tekst ili RTF format" + }, + "PDFToHTML": { + "title": "PDF u HTML", + "desc": "Pretvorite PDF u HTML format" + }, + "PDFToXML": { + "title": "PDF u XML", + "desc": "Pretvorite PDF u XML format" + }, + "ScannerImageSplit": { + "title": "Otkrij/razdvoji skenirane fotografije", + "desc": "Razdvaja viÅ”e fotografija iz fotografije/PDF-a" + }, + "sign": { + "title": "Potpisati", + "desc": "Dodaje potpis u PDF crtežom, tekstom ili slikom" + }, + "flatten": { + "title": "Ravnanje (Flatten)", + "desc": "Uklonite sve interaktivne elemente i obrasce iz PDF-a" + }, + "repair": { + "title": "Popravi", + "desc": "PokuÅ”ava popraviti oÅ”tećeni/pokvareni PDF" + }, + "removeBlanks": { + "title": "Ukloni prazne stranice", + "desc": "Otkriva i uklanja prazne stranice iz dokumenta" + }, + "removeAnnotations": { + "title": "Ukloni komentare", + "desc": "Uklanja sve komentare/anotacije iz PDF-a" + }, + "compare": { + "title": "Uporedi", + "desc": "Uspoređuje i pokazuje razlike između 2 PDF dokumenta" + }, + "certSign": { + "title": "PotpiÅ”ite s certifikatom", + "desc": "Potpisuje PDF s certifikatom/ključem (PEM/P12)" + }, + "removeCertSign": { + "title": "Ukloni potpis sertifikata", + "desc": "Uklonite potpis sertifikata iz PDF-a" + }, + "pageLayout": { + "title": "Izgled s viÅ”e stranica", + "desc": "Spojite viÅ”e stranica PDF dokumenta u jednu stranicu" + }, + "scalePages": { + "title": "Prilagodite veličinu/razmjer stranice", + "desc": "Promijenite veličinu/razmjer stranice i/ili njezin sadržaj." + }, + "pipeline": { + "title": "Pipeline", + "desc": "IzvrÅ”ite viÅ”e radnji na PDF-ovima definiranjem skripti u pipeline-u" + }, + "add-page-numbers": { + "title": "Dodaj brojeve stranica", + "desc": "Dodajte brojeve stranica kroz dokument na određeno mjesto" + }, + "auto-rename": { + "title": "Automatsko preimenovanje PDF datoteka", + "desc": "Automatski preimenuje PDF datoteku na temelju otkrivenog zaglavlja" + }, + "adjust-contrast": { + "title": "Podesi boje/kontrast", + "desc": "Podesite kontrast, zasićenost i svjetlinu PDF-a" + }, + "crop": { + "title": "Izrežite PDF", + "desc": "Izrežite PDF kako biste smanjili njegovu veličinu (zadržava tekst!)" + }, + "autoSplitPDF": { + "title": "Automatsko dijeljenje stranica", + "desc": "Automatsko dijeljenje skeniranog PDF-a s fizičkim QR kodom za dijeljenje stranica" + }, + "sanitizePdf": { + "title": "Dezinficirati (Sanitize)", + "desc": "Uklonite skripte i druge elemente iz PDF datoteka" + }, + "URLToPDF": { + "title": "URL/Webstranica u PDF", + "desc": "Pretvara bilo koji http(s)URL u PDF" + }, + "HTMLToPDF": { + "title": "HTML u PDF", + "desc": "Pretvara bilo koji HTML datoteku ili zip u PDF" + }, + "MarkdownToPDF": { + "title": "Markdown u PDF", + "desc": "Pretvara bilo koju Markdown datoteku u PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "Dohvati SVE informacije o PDF-u", + "desc": "Dohvaća sve moguće informacije o PDF-ovima" + }, + "extractPage": { + "title": "Izdvoji stranicu(e)", + "desc": "Izdvaja odabrane stranice iz PDF-a" + }, + "PdfToSinglePage": { + "title": "PDF u Jednu Veliku Stranicu", + "desc": "Spaja sve PDF stranice u jednu veliku stranicu" + }, + "showJS": { + "title": "Prikaži JavaScript", + "desc": "Pretražuje i prikazuje bilo koji JavaScript umetnut u PDF" + }, + "autoRedact": { + "title": "Automatsko uređivanje", + "desc": "Automatski redigira (zacrni) tekst u PDF-u na temelju unosa teksta" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF u CSV", + "desc": "Izdvaja tablice iz PDF-a pretvarajući ga u CSV" + }, + "autoSizeSplitPDF": { + "title": "Automatska podjela po veličini/broju", + "desc": "Podijelite jedan PDF na viÅ”e dokumenata na temelju veličine, broja stranica ili broja dokumenata" + }, + "overlay-pdfs": { + "title": "Preklapanje PDF-ova", + "desc": "Preklapa PDF-ove na drugi PDF" + }, + "split-by-sections": { + "title": "Podijeli PDF po odjeljcima", + "desc": "Svaku stranicu PDF-a podijelite na manje vodoravne i okomite dijelove" + }, + "AddStampRequest": { + "title": "Dodaj pečat u PDF", + "desc": "Dodajte tekst ili dodajte slikovne oznake na postavljenim mjestima" + }, + "removeImagePdf": { + "title": "Ukloni sliku", + "desc": "Ukloni sliku iz PDF-a kako bi se smanjio veličina datoteke" + }, + "splitPdfByChapters": { + "title": "Podijeli PDF prema glavama", + "desc": "Podijeli PDF na viÅ”e datoteka prema njegovom strukturnom obliku glava." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "replaceColorPdf": { + "title": "Replace and Invert Color", + "desc": "Zamenite boju teksta i pozadine u PDF-u te inverzirajte cijeli PDF kako bi se smanjila veličina datoteke." + } + }, + "viewPdf": { + "tags": "pregled,čitanje,komentiranje,tekst,slika", + "title": "View/Edit PDF", + "header": "Pogledaj PDF" + }, + "multiTool": { + "tags": "ViÅ”estruki alat, viÅ”e operacija, korisničko sučelje, povlačenje klikom, prednji kraj, strana klijenta, interaktivno, nepopravljivo, pomicanje", + "title": "PDF ViÅ”enamjenski alat", + "header": "PDF ViÅ”enamjenski alat", + "uploadPrompts": "Naziv datoteke", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "selectPages": "Page Select", + "selectedPages": "Selected Pages", + "page": "Page", + "deleteSelected": "Delete Selected", + "downloadAll": "Export", + "downloadSelected": "Export Selected", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "Page(s) Selected", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "spajanje,Operacije sa stranicama,Backend,poslužiteljska strana", + "title": "Spajanje", + "header": "Spajanje viÅ”e PDF-ova (2+)", + "sortByName": "Poredaj po imenu", + "sortByDate": "Poredaj po datumu", + "removeCertSign": "Ukloniti digitalni potpis u kombiniranom datoteku?", + "submit": "Spajanje" + }, + "split": { + "tags": "Operacije stranice, dijeljenje, viÅ”e stranica, rezanje,poslužiteljska strana", + "title": "Razdvajanje PDF-a", + "header": "Razdvajanje PDF-a", + "desc": { + "1": "Brojevi koje odaberete su brojevi stranica na kojima želite napraviti podjelu", + "2": "s takvim odabirom 1,3,7-9 bi se dokument od 10 stranica podijelio u 6 zasebnih PDF-ova sa:", + "3": "Dokument #1: Stranica 1", + "4": "Dokument #2: Stranice 2 i 3", + "5": "Dokument #3: Stranice 4, 5, 6 i 7", + "6": "Dokument #4: Stranica 8", + "7": "Dokument #5: Stranica 9", + "8": "Dokument #6: Stranice 10" + }, + "splitPages": "Unesite stranice za razdvajanje:", + "submit": "Razdvoji" + }, + "rotate": { + "tags": "poslužiteljska strana", + "title": "Zakreni PDF", + "header": "Zakreni PDF", + "selectAngle": "Odaberite kut rotacije (u umnoÅ”cima od 90 stupnjeva):", + "submit": "Zakreni" + }, + "imageToPdf": { + "tags": "konverzija,pretvaranje,img,jpg,slika,foto" + }, + "pdfToImage": { + "tags": "konverzija,img,jpg,slika,foto", + "title": "PDF u sliku", + "header": "PDF u sliku", + "selectText": "Format slike", + "singleOrMultiple": "Vrsta rezultata Stranica u sliku", + "single": "Jedna velika slika koja sadrži sve stranice", + "multi": "ViÅ”e slika, jedna slika po stranici", + "colorType": "Tip boje", + "color": "Boja", + "grey": "Sivi tonovi", + "blackwhite": "Crno-bijelo (mogu se izgubiti podaci!)", + "submit": "Pretvori", + "info": "Python nije instaliran. Treba je za konverziju na WebP.", + "placeholder": "(t.j. 1,2,8 ili 4,7,12-16 ili 2n-1)" + }, + "pdfOrganiser": { + "tags": "dvostrana,parne,neparni,prikupljanje,prebacivanje", + "title": "Organizator stranica", + "header": "Organizator stranica u PDF-u", + "submit": "preuredite stranice", + "mode": { + "_value": "Način rada", + "1": "Prilagođeni redoslijed stranica", + "2": "Obrnuti redoslijed", + "3": "Duplex sortiranje", + "4": "Booklet sortiranje", + "5": "Knjižica s bočnim ubodom", + "6": "Par-Nepar Podjela", + "7": "Ukloni Prvu", + "8": "Ukloni Zadnju", + "9": "Ukloni Prvu i Zadnju", + "10": "Neparno-parna kombinacija", + "11": "Duplicate all pages" + }, + "placeholder": "(npr. 1,3,2 ili 4-8,2,10-12 ili 2n-1)" + }, + "addImage": { + "tags": "img,jpg,slika,foto", + "title": "Dodaj sliku", + "header": "Dodaj sliku u PDF", + "everyPage": "Na svakoj stranici?", + "upload": "Dodaj sliku", + "submit": "Dodaj sliku" + }, + "watermark": { + "tags": "Tekst,ponavljanje,etiketa,vlastiti,autorsko pravo,zaÅ”tita, img,jpg,slika,foto", + "title": "Dodaj vodeni žig", + "header": "Dodaj vodeni žig", + "customColor": "Prilagođena boja teksta", + "selectText": { + "1": "Izaberite PDF za dodavanje vodenog žiga:", + "2": "Tekst vodenog žiga:", + "3": "Veličina fonta:", + "4": "Rotacija (0-360):", + "5": "Å irina razmaka (Razmak između svakog vodenog žiga vodoravno):", + "6": "Visina razmaka (Razmak između svakog vodenog žiga okomito):", + "7": "Neprozirnost (0% - 100%):", + "8": "Vrsta vodenog žiga:", + "9": "Slika vodenog žiga:", + "10": "Konvertiraj PDF u PDF-Sliku" + }, + "submit": "Dodaj vodeni žig", + "type": { + "1": "Tekst", + "2": "Slika" + } + }, + "permissions": { + "tags": "čitanje,pisanje,izmjena,print", + "title": "Promjena dopuÅ”tenja", + "header": "Promjena dopuÅ”tenja", + "warning": "Upozorenje: da ove dozvole budu nepromjenjive, preporuča se da ih postavite lozinkom putem stranice za dodavanje lozinke", + "selectText": { + "1": "Odaberite PDF za promjenu dopuÅ”tenja", + "2": "DopuÅ”tenja za postavljanje", + "3": "Spriječiti sastavljanje dokumenta", + "4": "Spriječiti izdvajanje sadržaja", + "5": "Spriječite izvlačenje radi pristupačnosti", + "6": "Spriječiti ispunjavanje obrasca", + "7": "Spriječiti izmjene", + "8": "Spriječi modificiranje napomena", + "9": "Spriječiti ispis", + "10": "Spriječite ispis različitih formata" + }, + "submit": "Promijeniti" + }, + "removePages": { + "tags": "Ukloni stranice,izbriÅ”i stranice" + }, + "addPassword": { + "tags": "sigurno, sigurnost", + "title": "Dodajte zaporku", + "header": "Dodajte zaporku (kriptiraj)", + "selectText": { + "1": "Odaberite PDF za Å”ifriranje", + "2": "Korisnička Zaporka", + "3": "Dužina ključa Å”ifriranja", + "4": "ViÅ”e vrijednosti su jače, ali niže vrijednosti imaju bolju kompatibilnost.", + "5": "DopuÅ”tenja za postavljanje (preporučuje se koriÅ”tenje uz vlasničku lozinku)", + "6": "Spriječiti sastavljanje dokumenta", + "7": "Spriječite izdvajanje sadržaja", + "8": "Spriječite izvlačenje radi pristupačnosti", + "9": "Spriječiti ispunjavanje obrasca", + "10": "Spriječiti izmjene", + "11": "Spriječi modificiranje napomena", + "12": "Spriječiti ispis", + "13": "Spriječite ispis različitih formata", + "14": "Zaporka vlasnika", + "15": "Ograničava Å”to se može učiniti s dokumentom nakon Å”to se otvori (ne podržavaju svi čitači)", + "16": "Ograničava otvaranje samog dokumenta" + }, + "submit": "Å ifriraj" + }, + "removePassword": { + "tags": "sigurno, deÅ”ifriranje, sigurnost, poniÅ”ti lozinku, izbriÅ”i lozinku", + "title": "Ukloni zaporku", + "header": "Ukloni zaporku (dekriptiraj)", + "selectText": { + "1": "Odaberite PDF za dekriptiranje", + "2": "Zaporka" + }, + "submit": "Ukloniti" + }, + "compressPdfs": { + "tags": "squish, mali, maleni" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Naslov,autor,datum,kreacije,vrijeme,izdavač,proizvođač,statistike", + "title": "Promjena metapodataka", + "header": "Promjena metapodataka", + "selectText": { + "1": "Uredite varijable koje želite promijeniti", + "2": "IzbriÅ”i sve metapodatke", + "3": "Prikaži prilagođene metapodatke:", + "4": "Ostali metapodaci:", + "5": "Dodaj prilagođeni unos metapodataka" + }, + "author": "Autor:", + "creationDate": "Datum stvaranja (gggg/MM/dd HH:mm:ss):", + "creator": "Kreator:", + "keywords": "Ključne riječi:", + "modDate": "Datum izmjene (gggg/MM/dd HH:mm:ss):", + "producer": "Proizvođač:", + "subject": "Predmet:", + "trapped": "Zarobljen:", + "submit": "Promijeniti" + }, + "fileToPDF": { + "tags": "transformacija,format,dokument,slika,slajd,tekst,konverzija,office,docs,word,excel,powerpoint", + "title": "datoteku u PDF", + "header": "Pretvori bilo koji datoteku u PDF", + "credit": "Ova usluga koristi LibreOffice i Unoconv za pretvaranje datoteka.", + "supportedFileTypesInfo": "Podržane vrste datoteka", + "supportedFileTypes": "Podržane vrste datoteka trebale bi uključivati dolje, no za potpuni ažurirani popis podržanih formata pogledajte dokumentaciju LibreOfficea", + "submit": "Pretvori u PDF" + }, + "ocr": { + "tags": "prepoznavanje,tekst,slika,sken,čitanje,identifikacija,detektiranje,uređivanje", + "title": "OCR / čiŔćenje skeniranja", + "header": "ČiŔćenje skeniranja / OCR (optičko prepoznavanje znakova)", + "selectText": { + "1": "Odaberite jezike koji će se otkriti unutar PDF-a (navedeni su oni koji su trenutno otkriveni):", + "2": "Izradite tekstualnu datoteku koja sadrži OCR tekst uz OCR-ovani PDF", + "3": "Ispravne stranice su skenirane pod nagnutim kutom rotiranjem na mjesto", + "4": "Očistite stranicu tako da je manja vjerojatnost da će OCR pronaći tekst u pozadinskoj buci. (Bez promjene izlaza)", + "5": "Očisti stranicu tako da je manja vjerojatnost da će OCR pronaći tekst u pozadinskoj buci, održava čiŔćenje u izlazu.", + "6": "Ignorira stranice koje na sebi imaju interaktivni tekst, samo OCR stranice koje su slike", + "7": "Prinudni OCR, OCR će za svaku stranicu ukloniti sve izvorne elemente teksta", + "8": "Normalno (Bit će pogreÅ”ka ako PDF sadrži tekst)", + "9": "Dodatne postavke", + "10": "OCR način", + "11": "Ukloni slike nakon OCR-a (Uklanja SVE slike, korisno samo ako je dio koraka konverzije)", + "12": "Vrsta iscrtavanja (napredno)" + }, + "help": "Pročitajte ovu dokumentaciju o tome kako ovo koristiti za druge jezike i/ili koristiti ne u dockeru", + "credit": "Ova usluga koristi qpdf i Tesseract za OCR.", + "submit": "Obradi PDF sa OCR-om" + }, + "extractImages": { + "tags": "slika, fotografija, spremanje, arhiva, zip, snimanje, zgrabi", + "title": "Ekstrakt slika", + "header": "Ekstrakt slika", + "selectText": "Odaberite format slike za pretvaranje izdvojenih slika", + "allowDuplicates": "Sačuvaj duplikate slike", + "submit": "Izdvajanje" + }, + "pdfToPDFA": { + "tags": "arhiva,dugoročno,standardno,konverzija,čuvanje,čuvanje", + "title": "PDF u PDF/A", + "header": "PDF u PDF/A", + "credit": "Ova usluga koristi libreoffice za PDF/A pretvorbu", + "submit": "Pretvoriti", + "tip": "Trenutno ne radi za viÅ”e unosa odjednom", + "outputFormat": "Izlazni format", + "pdfWithDigitalSignature": "PDF sadrži digitalni potpis. U sledećem koraku će biti uklonjen." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformacija,format,konverzija,office,microsoft,docfile", + "title": "PDF u Word", + "header": "PDF u Word", + "selectText": { + "1": "Format izlazne datoteke" + }, + "credit": "Ova usluga koristi LibreOffice za konverziju datoteka.", + "submit": "Pretvoriti" + }, + "PDFToPresentation": { + "tags": "slajdovi,prikaz,office,microsoft", + "title": "PDF u Prezentaciju", + "header": "PDF u Prezentaciju", + "selectText": { + "1": "Format izlazne datoteke" + }, + "credit": "Ova usluga koristi LibreOffice za konverziju datoteka.", + "submit": "Pretvoriti" + }, + "PDFToText": { + "tags": "bojaformata,tjedentextformat,sadržanotekstformat", + "title": "PDF u RTF (Tekst)", + "header": "PDF u RTF (Tekst)", + "selectText": { + "1": "Format izlazne datoteke" + }, + "credit": "Ova usluga koristi LibreOffice za konverziju datoteka.", + "submit": "Pretvoriti" + }, + "PDFToHTML": { + "tags": "web sadržaj,prijateljski za pretraživače", + "title": "PDF u HTML", + "header": "PDF u HTML", + "credit": "Ova usluga koristi pdftohtml za konverziju datoteka.", + "submit": "Pretvoriti" + }, + "PDFToXML": { + "tags": "izdvajanje-podataka,strukturirani-sadržaj,interop,transformacija,konvertiranje", + "title": "PDF u XML", + "header": "PDF u XML", + "credit": "Ova usluga koristi LibreOffice za konverziju datoteka.", + "submit": "Pretvoriti" + }, + "ScannerImageSplit": { + "tags": "razdvoji,auto-detekcija,skeniranja,viÅ”estruke fotografije,organizacija", + "selectText": { + "1": "Kutni prag:", + "2": "Postavlja minimalni apsolutni kut potreban za rotiranje slike (zadano: 10).", + "3": "Tolerancija:", + "4": "Određuje raspon varijacije boje oko procijenjene boje pozadine (zadano: 30).", + "5": "Minimalna povrÅ”ina:", + "6": "Postavlja minimalni prag povrÅ”ine za fotografiju (zadano: 10000).", + "7": "Minimalna konturna povrÅ”ina:", + "8": "Postavlja minimalni prag povrÅ”ine konture za fotografiju", + "9": "Veličina obruba:", + "10": "Postavlja veličinu obruba koji se dodaje i uklanja kako bi se spriječili bijeli obrubi u ispisu (zadano: 1)." + }, + "info": "Python nije instaliran. Treba je za izvrÅ”enje." + }, + "sign": { + "tags": "autorizacija,inicijali,crtani-potpis,tekstualni-potpis,slikovni-potpis", + "title": "PotpiÅ”ite", + "header": "PotpiÅ”ite PDF-ove", + "upload": "Učitaj sliku", + "draw": "Nacrtaj potpis", + "text": "Tekstualni unos", + "clear": "ObriÅ”i", + "add": "Dodaj", + "saved": "Sacuvane potpisne oznake", + "save": "Sačuvaj potpisnu oznaku", + "personalSigs": "Osobni potpisi", + "sharedSigs": "Dijeljeni potpisi", + "noSavedSigs": "Nema sacuvanih potpisa pronađenih", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "statično,deaktivirati,neinteraktivno,usmjeriti", + "title": "Izravnati", + "header": "Izravnati pdf", + "flattenOnlyForms": "Izravnati samo obrasce", + "submit": "Izravnati" + }, + "repair": { + "tags": "popravi,vrati,korekcija,obnovi", + "title": "Popravi", + "header": "Popravi PDF datoteku", + "submit": "Popravi" + }, + "removeBlanks": { + "tags": "čiŔćenje,usmjeriti,ne-sadržaj,organizacija", + "title": "Uklonite prazne stranice", + "header": "Uklonite prazne stranice", + "threshold": "Prag bjeline piksela:", + "thresholdDesc": "Prag za određivanje koliko bijeli piksel mora biti bijel da bi bio klasificiran kao 'bijeli'. 0 = crno, 255 čisto bijelo.", + "whitePercent": "Postotak bijele boje (%):", + "whitePercentDesc": "Postotak stranice koji mora biti \"bijeli\" piksel da bi se uklonio", + "submit": "Uklonite prazne stranice" + }, + "removeAnnotations": { + "tags": "komentari,isticanje,biljeÅ”ke,oznake,ukloni", + "title": "Ukloni komentare", + "header": "Ukloni komentare", + "submit": "Ukloni" + }, + "compare": { + "tags": "razlikovati,kontrast,izmjene,analiza", + "title": "Uporedite", + "header": "Usporedite PDF-ove", + "highlightColor": { + "1": "Boja osvetljenja 1:", + "2": "Boja osvetljenja 2:" + }, + "document": { + "1": "Dokument 1", + "2": "Dokument 2" + }, + "submit": "Uporedi", + "complex": { + "message": "Jedan ili oba unesena dokumenta su veliki datoteke, to može smanjiti preciznost usporedbi" + }, + "large": { + "file": { + "message": "Jedan ili oba unesena dokumenta su prevelike za obradu" + } + }, + "no": { + "text": { + "message": "Jedan ili oba odabrana PDF-a nema tekst. Odaberite PDF-ove s tekstom za usporedbu." + } + } + }, + "certSign": { + "tags": "autentifikacija,PEM,P12,zvanično,Å”ifriranje", + "title": "Potpisivanje Certifikatom", + "header": "PotpiÅ”ite PDF svojim certifikatom (Rad u tijeku)", + "selectPDF": "Odaberite PDF datoteku za potpisivanje:", + "jksNote": "Napomena: Ako vrsta vaÅ”eg certifikata nije navedena u nastavku, pretvorite ga u datoteku Java Keystore (.jks) pomoću alata naredbenog retka keytool. Zatim odaberite opciju .jks datoteke u nastavku.", + "selectKey": "Odaberite svoju datoteku privatnog ključa (format PKCS#8, može biti .pem ili .der):", + "selectCert": "Odaberite svoju datoteku certifikata (format X.509, može biti .pem ili .der):", + "selectP12": "Odaberite svoju PKCS#12 datoteku pohrane ključeva (.p12 ili .pfx) (neobavezno, ako je dostupna, trebala bi sadržavati vaÅ” privatni ključ i certifikat):", + "selectJKS": "Odaberite datoteku Java Keystore (.jks ili .keystore):", + "certType": "Tip certifikata", + "password": "Unesite svoju lozinku za skladiÅ”te ključeva ili privatni ključ (ako postoji):", + "showSig": "Prikaži potpis", + "reason": "Razlog", + "location": "Mjesto", + "name": "Ime", + "showLogo": "Prikaži logo", + "submit": "PotpiÅ”i PDF" + }, + "removeCertSign": { + "tags": "autentičiranje,PEM,P12,djelomičan deÅ”ifriranje", + "title": "Ukloni digitalno potpisano dokazilo", + "header": "Uklonite digitalni potpis iz PDF-a", + "selectPDF": "Odaberite datoteku PDF:", + "submit": "Ukloni potpisi" + }, + "pageLayout": { + "tags": "spajanje,kompozitni,pojedinačan-prikaz,organizacija", + "title": "Izgled s viÅ”e stranica", + "header": "Izgled s viÅ”e stranica", + "pagesPerSheet": "Broj stranica po listu:", + "addBorder": "Dodajte granice dokumenta", + "submit": "Potvrdi" + }, + "scalePages": { + "tags": "izmjena,modifikacija,dimenzija,adaptacija", + "title": "Podesite veličinu stranice", + "header": "Podesite veličinu stranice", + "pageSize": "Veličina stranice dokumenta.", + "keepPageSize": "Originalna veličina", + "scaleFactor": "Razina zumiranja (obrezivanje) stranice.", + "submit": "Potvrdi" + }, + "add-page-numbers": { + "tags": "paginirati, označiti, organizirati, indeksirati" + }, + "auto-rename": { + "tags": "auto-detekcija,zaglavlje-bazirano,organizacija,preimenovanje", + "title": "Automatski preimenuj", + "header": "Automatski preimenuj PDF", + "submit": "Automatski preimenuj" + }, + "adjust-contrast": { + "tags": "korekcija boje, ugađanje, modificiranje, poboljÅ”anje" + }, + "crop": { + "tags": "obrezivanje, smanjivanje, uređivanje, oblikovanje", + "title": "Izreži", + "header": "Izreži sliku", + "submit": "Potvrdi" + }, + "autoSplitPDF": { + "tags": "QR-bazirano,razdvoji,segment-skeniranja,organizacija", + "title": "Automatsko dijeljenje PDF-a", + "header": "Automatsko dijeljenje PDF-a", + "description": "IspiÅ”ite, umetnite, skenirajte, učitajte i dopustite nam da automatski odvojimo vaÅ”e dokumente. Nije potrebno ručno sortiranje.", + "selectText": { + "1": "IspiÅ”ite nekoliko razdjelnih listova odozdo (crno-bijelo je u redu).", + "2": "Skenirajte sve dokumente odjednom umetanjem razdjelnog lista između njih.", + "3": "Prenesite jednu veliku skeniranu PDF datoteku i pustite naÅ”em PDF-u da se pobrine za ostalo.", + "4": "Razdjelne stranice automatski se otkrivaju i uklanjaju, jamčeći uredan konačni dokument." + }, + "formPrompt": "PoÅ”aljite PDF koji sadrži naÅ”e razdjelnike stranica:", + "duplexMode": "Obostrani način rada (skeniranje s prednje i stražnje strane)", + "dividerDownload2": "Preuzmite 'Auto Splitter Divider (s uputama).pdf'", + "submit": "Potvrdi" + }, + "sanitizePdf": { + "tags": "čisto, sigurno, sigurno, uklanjanje prijetnji" + }, + "URLToPDF": { + "tags": "uhvati-web,sačuvaj-stranicu,web-u-doc,arhiva", + "title": "URL u PDF", + "header": "URL u PDF", + "submit": "Pretvori", + "credit": "Koristi WeasyPrint" + }, + "HTMLToPDF": { + "tags": "oznake,web-sadržaj,transformacija,konvertiranje", + "title": "HTML u PDF", + "header": "HTML u PDF", + "help": "Prihvaća HTML datoteke i ZIP-ove koji sadrže html/css/slike itd. potrebno", + "submit": "Pretvori", + "credit": "Koristi WeasyPrint", + "zoom": "Razina zumiranja za prikaz web stranice.", + "pageWidth": "Å irina stranice u centimetrima. (Prazno u Zadano)", + "pageHeight": "Visina stranice u centimetrima. (Prazno u Zadano)", + "marginTop": "Gornja margina stranice u milimetrima. (Prazno u Zadano)", + "marginBottom": "Donja margina stranice u milimetrima. (Prazno u Zadano)", + "marginLeft": "Lijeva margina stranice u milimetrima. (Prazno u Zadano)", + "marginRight": "Desna margina stranice u milimetrima. (Prazno u Zadano)", + "printBackground": "Prikaz pozadine web stranica.", + "defaultHeader": "Omogući zadano zaglavlje (Ime i broj stranice)", + "cssMediaType": "Promijenite vrstu CSS medija stranice.", + "none": "Nijedan", + "print": "Ispis", + "screen": "Zaslon" + }, + "MarkdownToPDF": { + "tags": "oznake,web-sadržaj,transformacija,konvertiranje", + "title": "Markdown u PDF", + "header": "Markdown u PDF", + "submit": "Pretvori", + "help": "Rad u toku", + "credit": "Koristi WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "informacije,podaci,statistike", + "title": "Informacije o PDF-u", + "header": "Informacije o PDF-u", + "submit": "Informacije", + "downloadJson": "Preuzmite JSON" + }, + "extractPage": { + "tags": "izdvajanje" + }, + "PdfToSinglePage": { + "tags": "jedna-stranica" + }, + "showJS": { + "tags": "JS", + "title": "Prikaži Javascript", + "header": "Prikaži Javascript", + "downloadJS": "Preuzmite Javascript", + "submit": "Prikaži" + }, + "autoRedact": { + "tags": "Cenzura,Sakrij,prekrivanje,crna,marker,skriveno", + "title": "Automatsko uređivanje", + "header": "Automatsko uređivanje", + "colorLabel": "Boja", + "textsToRedactLabel": "Tekst za uređivanje (razdvojen linijama)", + "textsToRedactPlaceholder": "npr. \\nPovjerljivo \\nStrogo čuvana tajna", + "useRegexLabel": "Koristi Regex", + "wholeWordSearchLabel": "Pretraživanje cijelih riječi", + "customPaddingLabel": "Dodatni prazan prostor", + "convertPDFToImageLabel": "Pretvorite PDF u PDF-sliku (koristi se za uklanjanje teksta iza okvira)", + "submitButton": "Potvrdi" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,Izdvajanje tabela,izdvajanje,pretvaranje" + }, + "autoSizeSplitPDF": { + "tags": "pdf,podjela,dokumenti,organizacija" + }, + "overlay-pdfs": { + "tags": "Preklapanje", + "header": "Prekrivanje PDF datoteka", + "baseFile": { + "label": "Odaberite Osnovnu PDF datoteka" + }, + "overlayFiles": { + "label": "Izaberite PDF datoteke za prekrivanje" + }, + "mode": { + "label": "Odaberite način preklapanja", + "sequential": "Sekvencijalno preklapanje", + "interleaved": "Isprepleteni sloj", + "fixedRepeat": "Popravljeni sloj ponavljanja" + }, + "counts": { + "label": "Brojevi preklapanja (za način fiksnog ponavljanja)", + "placeholder": "Unesite brojeve odvojene zarezima (npr. 2,3,1)" + }, + "position": { + "label": "Odaberite položaj preklapanja", + "foreground": "Prednji plan", + "background": "Pozadina" + }, + "submit": "Potvrditi" + }, + "split-by-sections": { + "tags": "Dijeljenje odjeljaka,Dijeljenje,Postavke", + "title": "Podijeli PDF po odjeljcima", + "header": "Podijeli PDF u odjeljke", + "horizontal": { + "label": "Vodoravne podjele", + "placeholder": "Unesite broj vodoravnih podjela" + }, + "vertical": { + "label": "Okomite podjele", + "placeholder": "Unesite broj okomitih podjela" + }, + "submit": "Razdvojiti PDF", + "merge": "Spoji u jedan PDF" + }, + "AddStampRequest": { + "tags": "Pečat, dodavanje slike, srediÅ”nja slika, vodeni žig, PDF, ugradnja, prilagodba", + "header": "Pečat PDF", + "title": "Pečat PDF", + "stampType": "Pečat Tip", + "stampText": "Pečat Tekst", + "stampImage": "Pečat Slika", + "alphabet": "Abeceda", + "fontSize": "Veličina fonta/slike", + "rotation": "Rotacija", + "opacity": "Neprozirnost", + "position": "Položaj", + "overrideX": "PoniÅ”ti X koordinatu", + "overrideY": "PoniÅ”ti Y koordinatu", + "customMargin": "Prilagođena margina", + "customColor": "Prilagođena boja teksta", + "submit": "PoÅ”alji" + }, + "removeImagePdf": { + "tags": "Ukloni sliku, Rad sa stranicama, Back end, server strana" + }, + "splitPdfByChapters": { + "tags": "podjela, glave, markere, organizacija" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Replace-Invert-Color", + "header": "Zameni-inverziranje boja u PDF-u", + "selectText": { + "1": "Optije za zamenu ili inverziranje boja", + "2": "Standardno (standarske visoko kontrastne boje)", + "3": "Napčno (prilagođene boje)", + "4": "Cijelo-inverzirajte (inverzirajte sve boje)", + "5": "Optije visoko kontrastne boje", + "6": "Crna tekst na bijelu pozadini", + "7": "Bijeli tekst na crvenoj pozadini", + "8": "Žutni tekst na crnoj pozadini", + "9": "Zeleni tekst na crnoj pozadini", + "10": "Izaberite boju teksta", + "11": "Izaberite pozadinu boju" + }, + "submit": "Zamijeni" + }, + "replaceColorPdf": { + "tags": "Zameni boju, Rad sa stranicama, Back end, server strana" + }, + "login": { + "title": "Prijavite se", + "header": "Prijavite se", + "signin": "Prijavite se", + "rememberme": "Zapamti me", + "invalid": "Neispravno korisničko ime ili zaporka.", + "locked": "VaÅ” račun je zaključan.", + "signinTitle": "Molimo vas da se prijavite", + "ssoSignIn": "Prijavite se putem jedinstvene prijave", + "oAuth2AutoCreateDisabled": "OAUTH2 automatsko kreiranje korisnika je onemogućeno", + "oAuth2AdminBlockedUser": "Registracija ili prijava nekadreguiranih korisnika trenutno su blokirane. Molimo Vas da kontaktirate administratora.", + "oauth2RequestNotFound": "Zahtjev za autorizaciju nije pronađen", + "oauth2InvalidUserInfoResponse": "Nevažeće informacije o korisniku", + "oauth2invalidRequest": "Neispravan zahtjev", + "oauth2AccessDenied": "Pristup odbijen", + "oauth2InvalidTokenResponse": "Nevažeći odgovor tokena", + "oauth2InvalidIdToken": "Nevažeći ID token", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "Korisnik je deaktiviran, prijava sa ovim korisničkim imenom je trenutno zakazana. Molimo Vas da kontaktirate administratorske osobe.", + "alreadyLoggedIn": "Već ste se prijavili na", + "alreadyLoggedIn2": "ure. Odjavite se s ure i pokuÅ”ajte ponovo.", + "toManySessions": "Imate preko mrežne sesije aktivnih", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF u Jednu Stranicu", + "header": "PDF u Jednu Stranicu", + "submit": "Pretvori u Jednu Stranicu" + }, + "pageExtracter": { + "title": "Izdvojiti stranice", + "header": "Izdvojiti stranice", + "submit": "Izdvoji", + "placeholder": "(t.j. 1,2,8 ili 4,7,12-16 ili 2n-1)" + }, + "sanitizePDF": { + "title": "Sanirajte PDF", + "header": "Sanirajte PDF datoteku", + "selectText": { + "1": "Ukloni JavaScript akcije", + "2": "Ukloni ugrađene datoteke", + "3": "Remove XMP metadata", + "4": "Ukloni poveznice", + "5": "Uklonite fontove", + "6": "Remove Document Info Metadata" + }, + "submit": "Sanirajte PDF" + }, + "adjustContrast": { + "title": "Podesite kontrast", + "header": "Podesite kontrast", + "contrast": "Kontrast:", + "brightness": "Osvjetljenje:", + "saturation": "Zasićenje:", + "download": "Preuzmi" + }, + "compress": { + "title": "Komprimirajte", + "header": "Komprimirajte PDF", + "credit": "Ova usluga koristi qpdf za komprimiranje / optimizaciju PDF-a.", + "grayscale": { + "label": "Primijeni sivinu za kompresiju" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Nivo optimizacije:", + "4": "Automatski način - Automatski prilagođava kvalitetu kako bi PDF dobio točnu veličinu", + "5": "Očekivana veličina PDF-a (npr. 25 MB, 10,8 MB, 25 KB)" + }, + "submit": "Kompresiraj" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "Uklanjanje stranica", + "header": "Uklanjanje stranica iz PDF-a", + "pagesToDelete": "Stranice za brisanje (Unesite listu brojeva stranica odvojenih zarezima) :", + "submit": "ObriÅ”i stranice", + "placeholder": "(npr. 1,2,6 ili 1-10,15-30)" + }, + "imageToPDF": { + "title": "Slika u PDF", + "header": "Slika u PDF", + "submit": "Pretvori", + "selectLabel": "Opcije prilagodbe slike", + "fillPage": "Ispuni stranicu", + "fitDocumentToImage": "Prilagodi stranicu slici", + "maintainAspectRatio": "Sačuvaj omjere slike", + "selectText": { + "2": "Automatsko zaktretanje PDF-a", + "3": "Logika viÅ”e datoteka (omogućeno samo ako radite s viÅ”e slika)", + "4": "Spojite u jedan PDF", + "5": "Pretvori u zasebne PDF-ove" + } + }, + "PDFToCSV": { + "title": "PDF u CSV", + "header": "PDF u CSV", + "prompt": "Odaberite stranicu za izdvajanje tablice", + "submit": "Izvuci" + }, + "split-by-size-or-count": { + "title": "Podijeli PDF prema veličini ili broju", + "header": "Podijeli PDF prema veličini ili broju", + "type": { + "label": "Odaberite vrstu dijeljenja", + "size": "Po veličini", + "pageCount": "Po broju stranica", + "docCount": "Po broju dokumenata" + }, + "value": { + "label": "Unesite vrijednost", + "placeholder": "Unesite veličinu (npr. 2MB ili 3KB) ili broj (npr. 5)" + }, + "submit": "Potvrdite" + }, + "printFile": { + "title": "Ispis datoteke", + "header": "Ispis datoteke na pisač", + "selectText": { + "1": "Odaberite Datoteku za ispis", + "2": "Unesite naziv pisača" + }, + "submit": "Ispis" + }, + "licenses": { + "nav": "Licence", + "title": "Licence treće strane", + "header": "Licence treće strane", + "module": "Modul", + "version": "Verzija", + "license": "Licenca" + }, + "survey": { + "nav": "Upitnica", + "title": "Stirling-PDF Upitnica", + "description": "Stirling-PDF nema praćenje pa želimo svesnost korisnika da bi poboljÅ”ali Stirling-PDF!", + "changes": "Stirling-PDF je promenjen od poslednje upitnice! Za viÅ”e informacija, proverite naÅ” blog ovdje:", + "changes2": "S ovim promenama dobivamo platnu podrÅ”ku i financiranje poslovnim aktivnostima", + "please": "Please consider taking our survey!", + "disabled": "(Upitnica popup će biti onemogućena u sljedećim ažuracanjima aliće se nalaziti na dnu stranice)", + "button": "Izvrsi upitnicu", + "dontShowAgain": "Ne prikazujući ponovo", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Ukloni sliku", + "header": "Ukloni sliku", + "removeImage": "Ukloni sliku", + "submit": "IzbriÅ”i sliku" + }, + "splitByChapters": { + "title": "Podijeli PDF naoglazdene glave", + "header": "Podijeli PDF naoglazdene glave", + "bookmarkLevel": "Nivo oznaka", + "includeMetadata": "Uključi metapodatke", + "allowDuplicates": "DopuÅ”taj duplikate", + "desc": { + "1": "Ova alatka podijeli PDF datoteku u viÅ”e PDFa na teme njene strukture glava.", + "2": "Nivo oznaka: Odaberite nivo oznaka koji će se koristiti za podjelu (0 za prvi nivo, 1 za drugi nivo itd.).", + "3": "Uključi metapodatke: Ako je pokuÅ”ano, metapodaci iz originalne PDF datoteke će biti uključeni u svaku podijeljenu PDF datoteku.", + "4": "DopuÅ”taj duplikate: Ako je ova opcija zaÅ”tićena, dozvoljava se da se na istoj strani mogu stvoriti posebne PDF datoteke s viÅ”e oznaka." + }, + "submit": "Podijeli PDF" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Releases", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Current Release" + }, + "note": "Release notes are only available in English" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/hu-HU/translation.json b/frontend/public/locales/hu-HU/translation.json new file mode 100644 index 000000000..886811a76 --- /dev/null +++ b/frontend/public/locales/hu-HU/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "BetűmĆ©ret", + "fontName": "BetűtĆ­pus", + "title": "OldalszĆ”mozĆ”s hozzĆ”adĆ”sa", + "header": "OldalszĆ”mozĆ”s hozzĆ”adĆ”sa", + "selectText": { + "1": "PDF fĆ”jl kivĆ”lasztĆ”sa:", + "2": "Margó mĆ©rete", + "3": "PozĆ­ció", + "4": "Kezdő szĆ”m", + "5": "SzĆ”mozandó oldalak", + "6": "Egyedi szƶveg" + }, + "customTextDesc": "Egyedi szƶveg", + "numberPagesDesc": "Mely oldalakat szĆ”mozzuk, alapĆ©rtelmezett 'mind', elfogad 1-5 vagy 2,5,9 formĆ”tumot is", + "customNumberDesc": "AlapĆ©rtelmezett {n}, elfogad 'Oldal {n} / {total}', 'Szƶveg-{n}', '{filename}-{n}' formĆ”tumot", + "submit": "OldalszĆ”mozĆ”s hozzĆ”adĆ”sa" + }, + "pdfPrompt": "PDF-fĆ”jl kivĆ”lasztĆ”sa", + "multiPdfPrompt": "PDF-fĆ”jlok kivĆ”lasztĆ”sa (2+)", + "multiPdfDropPrompt": "VĆ”lassza ki (vagy hĆŗzza ide) az ƶsszes szüksĆ©ges PDF-fĆ”jlt", + "imgPrompt": "KĆ©p kivĆ”lasztĆ”sa", + "genericSubmit": "KüldĆ©s", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "tĆŗl nagy. A maximĆ”lisan megengedett mĆ©ret", + "uploadLimitExceededPlural": "tĆŗl nagyok. A maximĆ”lisan megengedett mĆ©retek", + "processTimeWarning": "FigyelmeztetĆ©s: A folyamat akĆ”r egy percig is eltarthat a fĆ”jlmĆ©rettől függően", + "pageOrderPrompt": "Egyedi oldalsorrend (Adja meg az oldalszĆ”mokat vesszővel elvĆ”lasztva vagy hasznĆ”ljon függvĆ©nyeket, pl. 2n+1):", + "pageSelectionPrompt": "Egyedi oldalvĆ”lasztĆ”s (Adja meg az oldalszĆ”mokat vesszővel elvĆ”lasztva, pl. 1,5,6 vagy hasznĆ”ljon függvĆ©nyeket, pl. 2n+1):", + "goToPage": "UgrĆ”s", + "true": "Igen", + "false": "Nem", + "unknown": "Ismeretlen", + "save": "MentĆ©s", + "saveToBrowser": "MentĆ©s bƶngĆ©szőbe", + "close": "BezĆ”rĆ”s", + "filesSelected": "fĆ”jl kivĆ”lasztva", + "noFavourites": "Nincsenek kedvencek", + "downloadComplete": "LetƶltĆ©s befejezve", + "bored": "Unatkozik vĆ”rakozĆ”s kƶzben?", + "alphabet": "ABC", + "downloadPdf": "PDF letƶltĆ©se", + "text": "Szƶveg", + "font": "BetűtĆ­pus", + "selectFillter": "-- VĆ”lasszon --", + "pageNum": "OldalszĆ”m", + "sizes": { + "small": "Kicsi", + "medium": "Kƶzepes", + "large": "Nagy", + "x-large": "Extra nagy" + }, + "error": { + "pdfPassword": "A PDF-dokumentum jelszóval vĆ©dett, Ć©s vagy nem adott meg jelszót, vagy helytelen jelszót adott meg", + "_value": "Hiba", + "sorry": "SajnĆ”ljuk a kellemetlensĆ©get!", + "needHelp": "SegĆ­tsĆ©gre van szüksĆ©ge / HibĆ”t talĆ”lt?", + "contactTip": "Ha tovĆ”bbra is problĆ©mĆ”kba ütkƶzik, ne habozzon segĆ­tsĆ©get kĆ©rni. Bejelenthet hibĆ”t GitHub oldalunkon vagy felkereshet minket Discordon:", + "404": { + "head": "404 - Az oldal nem talĆ”lható | HoppĆ”, eltĆ©vedtünk a kódban!", + "1": "A keresett oldal nem talĆ”lható.", + "2": "Valami hiba tƶrtĆ©nt" + }, + "github": "Hiba bejelentĆ©se GitHubon", + "showStack": "Stacktrace megjelenĆ­tĆ©se", + "copyStack": "Stacktrace mĆ”solĆ”sa", + "githubSubmit": "GitHub - Hiba bejelentĆ©se", + "discordSubmit": "Discord - TĆ”mogatĆ”si poszt lĆ©trehozĆ”sa" + }, + "delete": "TƶrlĆ©s", + "username": "FelhasznĆ”lónĆ©v", + "password": "Jelszó", + "welcome": "Üdvƶzƶljük", + "property": "TulajdonsĆ”g", + "black": "Fekete", + "white": "FehĆ©r", + "red": "Piros", + "green": "Zƶld", + "blue": "KĆ©k", + "custom": "EgyĆ©ni...", + "WorkInProgess": "FejlesztĆ©s alatt Ć”lló funkció, hibĆ”k előfordulhatnak. KĆ©rjük, jelezze a problĆ©mĆ”kat!", + "poweredBy": "Üzemelteti:", + "yes": "Igen", + "no": "Nem", + "changedCredsMessage": "A hitelesĆ­tĆ©si adatok megvĆ”ltoztak!", + "notAuthenticatedMessage": "A felhasznĆ”ló nincs hitelesĆ­tve.", + "userNotFoundMessage": "A felhasznĆ”ló nem talĆ”lható.", + "incorrectPasswordMessage": "A jelenlegi jelszó helytelen.", + "usernameExistsMessage": "Ez a felhasznĆ”lónĆ©v mĆ”r lĆ©tezik.", + "invalidUsernameMessage": "ƉrvĆ©nytelen felhasznĆ”lónĆ©v. A felhasznĆ”lónĆ©v csak betűket, szĆ”mokat Ć©s a kƶvetkező speciĆ”lis karaktereket tartalmazhatja: @._+- vagy Ć©rvĆ©nyes e-mail cĆ­mnek kell lennie.", + "invalidPasswordMessage": "A jelszó nem lehet üres, Ć©s nem tartalmazhat szókƶzt az elejĆ©n vagy vĆ©gĆ©n.", + "confirmPasswordErrorMessage": "Az Ćŗj jelszó Ć©s a jelszó megerősĆ­tĆ©se nem egyezik.", + "deleteCurrentUserMessage": "A jelenleg bejelentkezett felhasznĆ”ló nem tƶrƶlhető.", + "deleteUsernameExistsMessage": "A felhasznĆ”lónĆ©v nem lĆ©tezik, ezĆ©rt nem tƶrƶlhető.", + "downgradeCurrentUserMessage": "A jelenlegi felhasznĆ”ló jogosultsĆ”gi szintje nem csƶkkenthető", + "disabledCurrentUserMessage": "A jelenlegi felhasznĆ”ló nem tiltható le", + "downgradeCurrentUserLongMessage": "A jelenlegi felhasznĆ”ló jogosultsĆ”gi szintje nem csƶkkenthető. EzĆ©rt a jelenlegi felhasznĆ”ló nem jelenik meg.", + "userAlreadyExistsOAuthMessage": "A felhasznĆ”ló mĆ”r lĆ©tezik OAuth2 felhasznĆ”lókĆ©nt.", + "userAlreadyExistsWebMessage": "A felhasznĆ”ló mĆ”r lĆ©tezik webes felhasznĆ”lókĆ©nt.", + "oops": "HoppĆ”!", + "help": "SĆŗgó", + "goHomepage": "Kezdőlap", + "joinDiscord": "Csatlakozzon Discord szerverünkhƶz", + "seeDockerHub": "Docker Hub megtekintĆ©se", + "visitGithub": "GitHub tĆ”roló megtekintĆ©se", + "donate": "TĆ”mogatĆ”s", + "color": "SzĆ­n", + "sponsor": "TĆ”mogató", + "info": "InformĆ”ció", + "pro": "Pro", + "page": "Oldal", + "pages": "Oldal", + "loading": "BetƶltĆ©s...", + "addToDoc": "HozzĆ”adĆ”s a dokumentumhoz", + "reset": "VisszaĆ”llĆ­tĆ”s", + "apply": "Alkalmaz", + "noFileSelected": "Nincs fĆ”jl kivĆ”lasztva. KĆ©rjük, tƶltsƶn fel egyet.", + "legal": { + "privacy": "AdatvĆ©delmi irĆ”nyelvek", + "terms": "FelhasznĆ”lĆ”si feltĆ©telek", + "accessibility": "AkadĆ”lymentesĆ­tĆ©si nyilatkozat", + "cookie": "Süti szabĆ”lyzat", + "impressum": "Impresszum", + "showCookieBanner": "Süti beĆ”llĆ­tĆ”sok" + }, + "pipeline": { + "header": "Pipeline menü (BĆ©ta)", + "uploadButton": "EgyĆ©ni feltƶltĆ©s", + "configureButton": "BeĆ”llĆ­tĆ”s", + "defaultOption": "EgyĆ©ni", + "submitButton": "KüldĆ©s", + "help": "Pipeline sĆŗgó", + "scanHelp": "MappafigyelĆ©s sĆŗgó", + "deletePrompt": "Biztosan tƶrli a pipeline-t?", + "tags": "automatizĆ”lĆ”s,szekvencia,szkriptelt,kƶtegelt feldolgozĆ”s", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Pipeline beĆ”llĆ­tĆ”sok", + "pipelineNameLabel": "Pipeline neve", + "saveSettings": "Műveleti beĆ”llĆ­tĆ”sok mentĆ©se", + "pipelineNamePrompt": "Adja meg a pipeline nevĆ©t", + "selectOperation": "Művelet kivĆ”lasztĆ”sa", + "addOperationButton": "Művelet hozzĆ”adĆ”sa", + "pipelineHeader": "Pipeline:", + "saveButton": "LetƶltĆ©s", + "validateButton": "EllenőrzĆ©s" + }, + "enterpriseEdition": { + "button": "VĆ”ltĆ”s Pro verzióra", + "warning": "Ez a funkció csak Pro felhasznĆ”lók szĆ”mĆ”ra Ć©rhető el.", + "yamlAdvert": "A Stirling PDF Pro tĆ”mogatja a YAML konfigurĆ”ciós fĆ”jlokat Ć©s egyĆ©b SSO funkciókat.", + "ssoAdvert": "Tƶbb felhasznĆ”lókezelĆ©si funkcióra van szüksĆ©ge? Tekintse meg a Stirling PDF Pro verziójĆ”t!" + }, + "analytics": { + "title": "Szeretne hozzĆ”jĆ”rulni a Stirling PDF fejlesztĆ©sĆ©hez?", + "paragraph1": "A Stirling PDF opcionĆ”lis analitikai adatgyűjtĆ©st kĆ­nĆ”l a termĆ©k fejlesztĆ©sĆ©nek tĆ”mogatĆ”sĆ”hoz. Nem gyűjtünk szemĆ©lyes informĆ”ciókat vagy fĆ”jltartalmakat.", + "paragraph2": "KĆ©rjük, fontolja meg az analitika engedĆ©lyezĆ©sĆ©t, hogy segĆ­tse a Stirling-PDF nƶvekedĆ©sĆ©t Ć©s jobban megĆ©rthessük felhasznĆ”lóink igĆ©nyeit.", + "enable": "Analitika engedĆ©lyezĆ©se", + "disable": "Analitika letiltĆ”sa", + "settings": "Az analitikai beĆ”llĆ­tĆ”sokat a config/settings.yml fĆ”jlban módosĆ­thatja" + }, + "navbar": { + "favorite": "Kedvencek", + "recent": "New and recently updated", + "darkmode": "SƶtĆ©t mód", + "language": "Nyelvek", + "settings": "BeĆ”llĆ­tĆ”sok", + "allTools": "Eszkƶzƶk", + "multiTool": "Tƶbbfunkciós eszkƶz", + "search": "KeresĆ©s", + "sections": { + "organize": "RendszerezĆ©s", + "convertTo": "KonvertĆ”lĆ”s PDF-be", + "convertFrom": "KonvertĆ”lĆ”s PDF-ből", + "security": "AlƔƭrĆ”s Ć©s biztonsĆ”g", + "advance": "Haladó", + "edit": "MegtekintĆ©s Ć©s szerkesztĆ©s", + "popular": "NĆ©pszerű" + } + }, + "settings": { + "title": "BeĆ”llĆ­tĆ”sok", + "update": "FrissĆ­tĆ©s elĆ©rhető", + "updateAvailable": "A jelenlegi telepĆ­tett verzió: {0}. Új verzió ({1}) Ć©rhető el.", + "appVersion": "AlkalmazĆ”s verziója:", + "downloadOption": { + "title": "LetƶltĆ©si beĆ”llĆ­tĆ”s (egyetlen fĆ”jl, nem tƶmƶrĆ­tett letƶltĆ©sek esetĆ©n):", + "1": "MegnyitĆ”s ugyanabban az ablakban", + "2": "MegnyitĆ”s Ćŗj ablakban", + "3": "FĆ”jl letƶltĆ©se" + }, + "zipThreshold": "FĆ”jlok tƶmƶrĆ­tĆ©se, ha a letƶltƶtt fĆ”jlok szĆ”ma meghaladja:", + "signOut": "KijelentkezĆ©s", + "accountSettings": "FiókbeĆ”llĆ­tĆ”sok", + "bored": { + "help": "Easter egg jĆ”tĆ©k engedĆ©lyezĆ©se" + }, + "cacheInputs": { + "name": "Űrlapmezők mentĆ©se", + "help": "EngedĆ©lyezĆ©se esetĆ©n menti a korĆ”bban hasznĆ”lt Ć©rtĆ©keket a kĆ©sőbbi hasznĆ”lathoz" + } + }, + "changeCreds": { + "title": "HitelesĆ­tĆ©si adatok módosĆ­tĆ”sa", + "header": "Fiókadatok frissĆ­tĆ©se", + "changePassword": "Az alapĆ©rtelmezett bejelentkezĆ©si adatokat hasznĆ”lja. KĆ©rjük, adjon meg Ćŗj jelszót", + "newUsername": "Új felhasznĆ”lónĆ©v", + "oldPassword": "Jelenlegi jelszó", + "newPassword": "Új jelszó", + "confirmNewPassword": "Új jelszó megerősĆ­tĆ©se", + "submit": "VĆ”ltoztatĆ”sok mentĆ©se" + }, + "account": { + "title": "FiókbeĆ”llĆ­tĆ”sok", + "accountSettings": "FiókbeĆ”llĆ­tĆ”sok", + "adminSettings": "Rendszergazdai beĆ”llĆ­tĆ”sok - FelhasznĆ”lók kezelĆ©se", + "userControlSettings": "FelhasznĆ”lói jogosultsĆ”gok", + "changeUsername": "FelhasznĆ”lónĆ©v módosĆ­tĆ”sa", + "newUsername": "Új felhasznĆ”lónĆ©v", + "password": "Jelszó megerősĆ­tĆ©se", + "oldPassword": "RĆ©gi jelszó", + "newPassword": "Új jelszó", + "changePassword": "Jelszó módosĆ­tĆ”sa", + "confirmNewPassword": "Új jelszó megerősĆ­tĆ©se", + "signOut": "KijelentkezĆ©s", + "yourApiKey": "Az Ɩn API kulcsa", + "syncTitle": "BƶngĆ©szőbeĆ”llĆ­tĆ”sok szinkronizĆ”lĆ”sa a fiókkal", + "settingsCompare": "BeĆ”llĆ­tĆ”sok ƶsszehasonlĆ­tĆ”sa:", + "property": "TulajdonsĆ”g", + "webBrowserSettings": "BƶngĆ©szőbeĆ”llĆ­tĆ”sok", + "syncToBrowser": "SzinkronizĆ”lĆ”s: Fiók -> BƶngĆ©sző", + "syncToAccount": "SzinkronizĆ”lĆ”s: BƶngĆ©sző -> Fiók" + }, + "adminUserSettings": { + "title": "FelhasznĆ”lókezelĆ©s", + "header": "Rendszergazdai felhasznĆ”lókezelĆ©s", + "admin": "Rendszergazda", + "user": "FelhasznĆ”ló", + "addUser": "Új felhasznĆ”ló", + "deleteUser": "FelhasznĆ”ló tƶrlĆ©se", + "confirmDeleteUser": "Biztosan tƶrli a felhasznĆ”lót?", + "confirmChangeUserStatus": "Biztosan módosĆ­tja a felhasznĆ”ló Ć”llapotĆ”t?", + "usernameInfo": "A felhasznĆ”lónĆ©v csak betűket, szĆ”mokat Ć©s a kƶvetkező speciĆ”lis karaktereket tartalmazhatja: @._+- vagy Ć©rvĆ©nyes e-mail cĆ­mnek kell lennie.", + "roles": "Szerepkƶrƶk", + "role": "Szerepkƶr", + "actions": "Műveletek", + "apiUser": "KorlĆ”tozott API felhasznĆ”ló", + "extraApiUser": "TovĆ”bbi korlĆ”tozott API felhasznĆ”ló", + "webOnlyUser": "Csak webes felhasznĆ”ló", + "demoUser": "Demo felhasznĆ”ló (egyedi beĆ”llĆ­tĆ”sok nĆ©lkül)", + "internalApiUser": "Belső API felhasznĆ”ló", + "forceChange": "JelszóvĆ”ltoztatĆ”s kikĆ©nyszerĆ­tĆ©se bejelentkezĆ©skor", + "submit": "FelhasznĆ”ló mentĆ©se", + "changeUserRole": "FelhasznĆ”lói szerepkƶr módosĆ­tĆ”sa", + "authenticated": "HitelesĆ­tett", + "editOwnProfil": "SajĆ”t profil szerkesztĆ©se", + "enabledUser": "AktĆ­v felhasznĆ”ló", + "disabledUser": "Letiltott felhasznĆ”ló", + "activeUsers": "AktĆ­v felhasznĆ”lók:", + "disabledUsers": "Letiltott felhasznĆ”lók:", + "totalUsers": "Ɩsszes felhasznĆ”ló:", + "lastRequest": "Utolsó kĆ©rĆ©s", + "usage": "HasznĆ”lat megtekintĆ©se" + }, + "endpointStatistics": { + "title": "VĆ©gpont Statisztika", + "header": "VĆ©gpont Statisztika", + "top10": "Top 10", + "top20": "Top 20", + "all": "Ɩsszes", + "refresh": "FrissĆ­tĆ©s", + "includeHomepage": "Tartalmazza a honlapot ('/')", + "includeLoginPage": "Tartalmazza a bejelentkezĆ©si oldat ('/login')", + "totalEndpoints": "Ɩsszes vĆ©gpont", + "totalVisits": "Ɩsszes megtekintĆ©s", + "showing": "MutatĆ”s", + "selectedVisits": "KivĆ”lasztott megtekintĆ©sek", + "endpoint": "VĆ©gpont", + "visits": "MegtekintĆ©sek", + "percentage": "SzĆ”zalĆ©k", + "loading": "BetƶltĆ©s...", + "failedToLoad": "Nem sikerült betƶlteni a vĆ©gpont adatokat. PróbĆ”lja meg frissĆ­teni.", + "home": "Kezdőlap", + "login": "BejelentkezĆ©s", + "top": "LegnĆ©pszerűbb", + "numberOfVisits": "MegtekintĆ©sek szĆ”ma", + "visitsTooltip": "MegtekintĆ©sek: {0} ({1}% az ƶsszes megtekintĆ©sből)", + "retry": "ÚjrapróbĆ”lĆ”s" + }, + "database": { + "title": "AdatbĆ”zis importĆ”lĆ”s/exportĆ”lĆ”s", + "header": "AdatbĆ”zis importĆ”lĆ”s/exportĆ”lĆ”s", + "fileName": "FĆ”jlnĆ©v", + "creationDate": "LĆ©trehozĆ”s dĆ”tuma", + "fileSize": "FĆ”jlmĆ©ret", + "deleteBackupFile": "BiztonsĆ”gi mentĆ©s tƶrlĆ©se", + "importBackupFile": "BiztonsĆ”gi mentĆ©s importĆ”lĆ”sa", + "createBackupFile": "BiztonsĆ”gi mentĆ©s lĆ©trehozĆ”sa", + "downloadBackupFile": "BiztonsĆ”gi mentĆ©s letƶltĆ©se", + "info_1": "Az adatok importĆ”lĆ”sakor kritikus fontossĆ”gĆŗ a helyes struktĆŗra biztosĆ­tĆ”sa. Ha nem biztos a dolgĆ”ban, kĆ©rjen szakĆ©rtői segĆ­tsĆ©get. A helytelen struktĆŗra alkalmazĆ”shibĆ”kat okozhat, akĆ”r az alkalmazĆ”s teljes műkƶdĆ©skĆ©ptelensĆ©gĆ©t is eredmĆ©nyezheti.", + "info_2": "A fĆ”jl neve feltƶltĆ©skor nem lĆ©nyeges. KĆ©sőbb Ć”tnevezĆ©sre kerül az egysĆ©ges backup_user_yyyyMMddHHmm.sql formĆ”tumra.", + "submit": "BiztonsĆ”gi mentĆ©s importĆ”lĆ”sa", + "importIntoDatabaseSuccessed": "Az adatbĆ”zis importĆ”lĆ”sa sikeres", + "backupCreated": "AdatbĆ”zis biztonsĆ”gi mentĆ©se sikeres", + "fileNotFound": "A fĆ”jl nem talĆ”lható", + "fileNullOrEmpty": "A fĆ”jl nem lehet üres", + "failedImportFile": "A fĆ”jl importĆ”lĆ”sa sikertelen", + "notSupported": "Ez a funkció nem Ć©rhető el az adatbĆ”zis-kapcsolatĆ”hoz." + }, + "session": { + "expired": "A munkamenet lejĆ”rt. KĆ©rjük, frissĆ­tse az oldalt Ć©s próbĆ”lja Ćŗjra.", + "refreshPage": "Oldal frissĆ­tĆ©se" + }, + "home": { + "desc": "Az Ɩn helyi PDF-szüksĆ©gleteinek teljes kƶrű megoldĆ”sa.", + "searchBar": "Funkciók keresĆ©se...", + "viewPdf": { + "title": "PDF MegtekintĆ©se/SzerkesztĆ©se", + "desc": "MegtekintĆ©s, jegyzetelĆ©s, szƶveg vagy kĆ©pek hozzĆ”adĆ”sa" + }, + "setFavorites": "Kedvencek beĆ”llĆ­tĆ”sa", + "hideFavorites": "Kedvencek elrejtĆ©se", + "showFavorites": "Kedvencek megjelenĆ­tĆ©se", + "legacyHomepage": "RĆ©gi kezdőlap", + "newHomePage": "PróbĆ”lja ki Ćŗj kezdőlapunkat!", + "alphabetical": "ABC sorrend", + "globalPopularity": "Teljes nĆ©pszerűsĆ©g", + "sortBy": "RendezĆ©s:", + "multiTool": { + "title": "PDF tƶbbfunkciós eszkƶz", + "desc": "EgyesĆ­tĆ©s, forgatĆ”s, Ć”trendezĆ©s Ć©s oldalak eltĆ”volĆ­tĆ”sa" + }, + "merge": { + "title": "EgyesĆ­tĆ©s", + "desc": "PDF-ek egyszerű egyesĆ­tĆ©se." + }, + "split": { + "title": "FelosztĆ”s", + "desc": "PDF-ek felosztĆ”sa tƶbb dokumentumra" + }, + "rotate": { + "title": "ForgatĆ”s", + "desc": "PDF-ek egyszerű forgatĆ”sa." + }, + "imageToPdf": { + "title": "KĆ©p PDF-be", + "desc": "KĆ©p (PNG, JPEG, GIF) konvertĆ”lĆ”sa PDF-fĆ©." + }, + "pdfToImage": { + "title": "PDF kĆ©ppĆ©", + "desc": "PDF konvertĆ”lĆ”sa kĆ©ppĆ© (PNG, JPEG, GIF)." + }, + "pdfOrganiser": { + "title": "RendszerezĆ©s", + "desc": "Oldalak eltĆ”volĆ­tĆ”sa/Ć”trendezĆ©se tetszőleges sorrendben" + }, + "addImage": { + "title": "KĆ©p hozzĆ”adĆ”sa", + "desc": "KĆ©p hozzĆ”adĆ”sa a PDF megadott helyĆ©re" + }, + "watermark": { + "title": "VĆ­zjel hozzĆ”adĆ”sa", + "desc": "Egyedi vĆ­zjel hozzĆ”adĆ”sa PDF dokumentumhoz" + }, + "permissions": { + "title": "JogosultsĆ”gok módosĆ­tĆ”sa", + "desc": "PDF dokumentum jogosultsĆ”gainak módosĆ­tĆ”sa" + }, + "removePages": { + "title": "EltĆ”volĆ­tĆ”s", + "desc": "Felesleges oldalak tƶrlĆ©se a PDF dokumentumból." + }, + "addPassword": { + "title": "Jelszó hozzĆ”adĆ”sa", + "desc": "PDF dokumentum jelszavas vĆ©delme" + }, + "removePassword": { + "title": "Jelszó eltĆ”volĆ­tĆ”sa", + "desc": "Jelszavas vĆ©delem eltĆ”volĆ­tĆ”sa a PDF dokumentumból" + }, + "compressPdfs": { + "title": "TƶmƶrĆ­tĆ©s", + "desc": "PDF-ek tƶmƶrĆ­tĆ©se a fĆ”jlmĆ©ret csƶkkentĆ©se Ć©rdekĆ©ben" + }, + "unlockPDFForms": { + "title": "PDF űrlapok feloldĆ”sa", + "desc": "PDF dokumentumban lĆ©vő űrlapmezők Ć­rĆ”svĆ©dettsĆ©gĆ©nek eltĆ”volĆ­tĆ”sa." + }, + "changeMetadata": { + "title": "Metaadatok módosĆ­tĆ”sa", + "desc": "PDF dokumentum metaadatainak módosĆ­tĆ”sa/tƶrlĆ©se/hozzĆ”adĆ”sa" + }, + "fileToPDF": { + "title": "FĆ”jl konvertĆ”lĆ”sa PDF-be", + "desc": "Szinte bĆ”rmilyen fĆ”jl konvertĆ”lĆ”sa PDF-be (DOCX, PNG, XLS, PPT, TXT Ć©s egyebek)" + }, + "ocr": { + "title": "OCR / Szkennelt dokumentumok tisztĆ­tĆ”sa", + "desc": "Szkennelt dokumentumok tisztĆ­tĆ”sa Ć©s szƶvegfelismerĆ©s kĆ©pekből, majd visszaadĆ”sa szerkeszthető szƶvegkĆ©nt" + }, + "extractImages": { + "title": "KĆ©pek kinyerĆ©se", + "desc": "Minden kĆ©p kinyerĆ©se a PDF-ből Ć©s mentĆ©se ZIP fĆ”jlba" + }, + "pdfToPDFA": { + "title": "PDF konvertĆ”lĆ”sa PDF/A formĆ”tumba", + "desc": "PDF konvertĆ”lĆ”sa PDF/A formĆ”tumba hosszĆŗ tĆ”vĆŗ tĆ”rolĆ”shoz" + }, + "PDFToWord": { + "title": "PDF konvertĆ”lĆ”sa Word formĆ”tumba", + "desc": "PDF konvertĆ”lĆ”sa Word formĆ”tumokba (DOC, DOCX Ć©s ODT)" + }, + "PDFToPresentation": { + "title": "PDF konvertĆ”lĆ”sa prezentĆ”cióvĆ”", + "desc": "PDF konvertĆ”lĆ”sa prezentĆ”ciós formĆ”tumokba (PPT, PPTX Ć©s ODP)" + }, + "PDFToText": { + "title": "PDF konvertĆ”lĆ”sa RTF szƶveggĆ©", + "desc": "PDF konvertĆ”lĆ”sa szƶveg vagy RTF formĆ”tumba" + }, + "PDFToHTML": { + "title": "PDF konvertĆ”lĆ”sa HTML-be", + "desc": "PDF konvertĆ”lĆ”sa HTML formĆ”tumba" + }, + "PDFToXML": { + "title": "PDF konvertĆ”lĆ”sa XML-be", + "desc": "PDF konvertĆ”lĆ”sa XML formĆ”tumba" + }, + "ScannerImageSplit": { + "title": "Szkennelt kĆ©pek felismerĆ©se/szĆ©tvĆ”lasztĆ”sa", + "desc": "Tƶbb fotó szĆ©tvĆ”lasztĆ”sa egy kĆ©pből/PDF-ből" + }, + "sign": { + "title": "AlƔƭrĆ”s", + "desc": "AlƔƭrĆ”s hozzĆ”adĆ”sa PDF-hez rajzolĆ”ssal, szƶveggel vagy kĆ©ppel" + }, + "flatten": { + "title": "LapĆ­tĆ”s", + "desc": "Minden interaktĆ­v elem Ć©s űrlap eltĆ”volĆ­tĆ”sa a PDF-ből" + }, + "repair": { + "title": "JavĆ­tĆ”s", + "desc": "SĆ©rült/hibĆ”s PDF javĆ­tĆ”sa" + }, + "removeBlanks": { + "title": "Üres oldalak eltĆ”volĆ­tĆ”sa", + "desc": "Üres oldalak felismerĆ©se Ć©s eltĆ”volĆ­tĆ”sa a dokumentumból" + }, + "removeAnnotations": { + "title": "MegjegyzĆ©sek eltĆ”volĆ­tĆ”sa", + "desc": "Minden megjegyzĆ©s/annotĆ”ció eltĆ”volĆ­tĆ”sa a PDF-ből" + }, + "compare": { + "title": "ƖsszehasonlĆ­tĆ”s", + "desc": "KĆ©t PDF dokumentum ƶsszehasonlĆ­tĆ”sa Ć©s külƶnbsĆ©gek megjelenĆ­tĆ©se" + }, + "certSign": { + "title": "TanĆŗsĆ­tvĆ”nnyal alƔƭrĆ”s", + "desc": "PDF alƔƭrĆ”sa tanĆŗsĆ­tvĆ”nnyal/kulccsal (PEM/P12)" + }, + "removeCertSign": { + "title": "TanĆŗsĆ­tvĆ”nyos alƔƭrĆ”s eltĆ”volĆ­tĆ”sa", + "desc": "TanĆŗsĆ­tvĆ”nyos alƔƭrĆ”s eltĆ”volĆ­tĆ”sa PDF-ből" + }, + "pageLayout": { + "title": "Tƶbboldalas elrendezĆ©s", + "desc": "PDF dokumentum tƶbb oldalĆ”nak egyesĆ­tĆ©se egyetlen oldalra" + }, + "scalePages": { + "title": "OldalmĆ©ret/mĆ©retarĆ”ny beĆ”llĆ­tĆ”sa", + "desc": "Oldal Ć©s/vagy tartalom mĆ©retĆ©nek/mĆ©retarĆ”nyĆ”nak módosĆ­tĆ”sa" + }, + "pipeline": { + "title": "Pipeline", + "desc": "Tƶbb művelet vĆ©grehajtĆ”sa PDF-eken pipeline szkriptek definiĆ”lĆ”sĆ”val" + }, + "add-page-numbers": { + "title": "OldalszĆ”mozĆ”s hozzĆ”adĆ”sa", + "desc": "OldalszĆ”mok hozzĆ”adĆ”sa a dokumentumhoz meghatĆ”rozott helyen" + }, + "auto-rename": { + "title": "PDF automatikus Ć”tnevezĆ©se", + "desc": "PDF fĆ”jl automatikus Ć”tnevezĆ©se a felismert fejlĆ©c alapjĆ”n" + }, + "adjust-contrast": { + "title": "SzĆ­nek/kontraszt beĆ”llĆ­tĆ”sa", + "desc": "PDF kontraszt, telĆ­tettsĆ©g Ć©s fĆ©nyerő beĆ”llĆ­tĆ”sa" + }, + "crop": { + "title": "PDF vĆ”gĆ”sa", + "desc": "PDF vĆ”gĆ”sa a mĆ©ret csƶkkentĆ©se Ć©rdekĆ©ben (a szƶveg megmarad!)" + }, + "autoSplitPDF": { + "title": "Automatikus oldalfelosztĆ”s", + "desc": "Szkennelt PDF automatikus felosztĆ”sa QR-kód alapĆŗ oldalelvĆ”lasztóval" + }, + "sanitizePdf": { + "title": "TisztĆ­tĆ”s", + "desc": "Szkriptek Ć©s egyĆ©b elemek eltĆ”volĆ­tĆ”sa PDF fĆ”jlokból" + }, + "URLToPDF": { + "title": "URL/Weboldal PDF-be", + "desc": "BĆ”rmely http(s) URL konvertĆ”lĆ”sa PDF-be" + }, + "HTMLToPDF": { + "title": "HTML konvertĆ”lĆ”sa PDF-be", + "desc": "HTML fĆ”jl vagy ZIP konvertĆ”lĆ”sa PDF-be" + }, + "MarkdownToPDF": { + "title": "Markdown konvertĆ”lĆ”sa PDF-be", + "desc": "Markdown fĆ”jl konvertĆ”lĆ”sa PDF-be" + }, + "PDFToMarkdown": { + "title": "PDF konvertĆ”lĆ”sa Markdown-ba", + "desc": "AkĆ”rmilyen PDF konvertĆ”lĆ”sa Markdown-ba" + }, + "getPdfInfo": { + "title": "PDF ƶsszes informĆ”ciójĆ”nak lekĆ©rĆ©se", + "desc": "Minden elĆ©rhető informĆ”ció lekĆ©rĆ©se PDF-ekről" + }, + "extractPage": { + "title": "Oldalak kinyerĆ©se", + "desc": "KivĆ”lasztott oldalak kinyerĆ©se PDF-ből" + }, + "PdfToSinglePage": { + "title": "Egyoldalas nagy PDF", + "desc": "Minden PDF oldal egyesĆ­tĆ©se egyetlen nagy oldalba" + }, + "showJS": { + "title": "JavaScript megjelenĆ­tĆ©se", + "desc": "PDF-be injektĆ”lt JavaScript kód keresĆ©se Ć©s megjelenĆ­tĆ©se" + }, + "autoRedact": { + "title": "Automatikus kitakarĆ”s", + "desc": "Szƶveg automatikus kitakarĆ”sa (feketĆ©vel) PDF-ben megadott szƶveg alapjĆ”n" + }, + "redact": { + "title": "KĆ©zi kitakarĆ”s", + "desc": "PDF kitakarĆ”sa kivĆ”lasztott szƶveg, rajzolt alakzatok Ć©s/vagy kivĆ”lasztott oldalak alapjĆ”n" + }, + "tableExtraxt": { + "title": "PDF konvertĆ”lĆ”sa CSV-be", + "desc": "TĆ”blĆ”zatok kinyerĆ©se PDF-ből Ć©s konvertĆ”lĆ”sa CSV formĆ”tumba" + }, + "autoSizeSplitPDF": { + "title": "Automatikus felosztĆ”s mĆ©ret/darabszĆ”m szerint", + "desc": "Egyetlen PDF felosztĆ”sa tƶbb dokumentumra mĆ©ret, oldalszĆ”m vagy dokumentumszĆ”m alapjĆ”n" + }, + "overlay-pdfs": { + "title": "PDF-ek egymĆ”sra helyezĆ©se", + "desc": "PDF-ek egymĆ”sra helyezĆ©se egy mĆ”sik PDF-en" + }, + "split-by-sections": { + "title": "PDF felosztĆ”sa szakaszokra", + "desc": "PDF oldalainak felosztĆ”sa kisebb vĆ­zszintes Ć©s függőleges szakaszokra" + }, + "AddStampRequest": { + "title": "PecsĆ©t hozzĆ”adĆ”sa PDF-hez", + "desc": "Szƶveges vagy kĆ©pes pecsĆ©t hozzĆ”adĆ”sa megadott helyekre" + }, + "removeImagePdf": { + "title": "KĆ©pek eltĆ”volĆ­tĆ”sa", + "desc": "KĆ©pek eltĆ”volĆ­tĆ”sa PDF-ből a fĆ”jlmĆ©ret csƶkkentĆ©se Ć©rdekĆ©ben" + }, + "splitPdfByChapters": { + "title": "PDF felosztĆ”sa fejezetek szerint", + "desc": "PDF felosztĆ”sa tƶbb fĆ”jlra a fejezetstruktĆŗra alapjĆ”n" + }, + "validateSignature": { + "title": "PDF alƔƭrĆ”s ellenőrzĆ©se", + "desc": "DigitĆ”lis alƔƭrĆ”sok Ć©s tanĆŗsĆ­tvĆ”nyok ellenőrzĆ©se PDF dokumentumokban" + }, + "replaceColorPdf": { + "title": "SzĆ­nek cserĆ©je Ć©s invertĆ”lĆ”sa", + "desc": "PDF szƶveg Ć©s hĆ”ttĆ©rszĆ­neinek cserĆ©je Ć©s teljes szĆ­ninvertĆ”lĆ”s a fĆ”jlmĆ©ret csƶkkentĆ©se Ć©rdekĆ©ben" + } + }, + "viewPdf": { + "tags": "megtekintĆ©s,olvasĆ”s,jegyzetelĆ©s,szƶveg,kĆ©p", + "title": "PDF megtekintĆ©se/szerkesztĆ©se", + "header": "PDF megtekintĆ©se" + }, + "multiTool": { + "tags": "Tƶbbfunkciós eszkƶz,Tƶbb művelet,UI,hĆŗzd Ć©s ejtsd,frontend,kliens oldali,interaktĆ­v,kezelhető,mozgatĆ”s", + "title": "PDF tƶbbfunkciós eszkƶz", + "header": "PDF tƶbbfunkciós eszkƶz", + "uploadPrompts": "FĆ”jlnĆ©v", + "selectAll": "Ɩsszes kijelƶlĆ©se", + "deselectAll": "KijelƶlĆ©s megszüntetĆ©se", + "selectPages": "Oldal kivĆ”lasztĆ”sa", + "selectedPages": "KivĆ”lasztott oldalak", + "page": "Oldal", + "deleteSelected": "Kijelƶltek tƶrlĆ©se", + "downloadAll": "ExportĆ”lĆ”s", + "downloadSelected": "Kijelƶltek exportĆ”lĆ”sa", + "insertPageBreak": "OldaltƶrĆ©s beszĆŗrĆ”sa", + "addFile": "FĆ”jl hozzĆ”adĆ”sa", + "rotateLeft": "ForgatĆ”s balra", + "rotateRight": "ForgatĆ”s jobbra", + "split": "FelosztĆ”s", + "moveLeft": "MozgatĆ”s balra", + "moveRight": "MozgatĆ”s jobbra", + "delete": "TƶrlĆ©s", + "dragDropMessage": "Oldal(ak) kivĆ”lasztva", + "undo": "VisszavonĆ”s", + "redo": "Újra" + }, + "merge": { + "tags": "egyesĆ­tĆ©s,Oldalműveletek,Backend,szerver oldali", + "title": "EgyesĆ­tĆ©s", + "header": "Tƶbb PDF egyesĆ­tĆ©se (2+)", + "sortByName": "RendezĆ©s nĆ©v szerint", + "sortByDate": "RendezĆ©s dĆ”tum szerint", + "removeCertSign": "DigitĆ”lis alƔƭrĆ”s eltĆ”volĆ­tĆ”sa az egyesĆ­tett fĆ”jlban?", + "submit": "EgyesĆ­tĆ©s" + }, + "split": { + "tags": "Oldalműveletek,felosztĆ”s,Tƶbb oldal,vĆ”gĆ”s,szerver oldali", + "title": "PDF felosztĆ”sa", + "header": "PDF felosztĆ”sa", + "desc": { + "1": "A kivĆ”lasztott szĆ”mok a felosztĆ”si pontokat jelƶlik", + "2": "PĆ©ldĆ”ul az 1,3,7-9 kivĆ”lasztĆ”sa egy 10 oldalas dokumentumot 6 külƶn PDF-re oszt:", + "3": "1. dokumentum: 1. oldal", + "4": "2. dokumentum: 2-3. oldal", + "5": "3. dokumentum: 4-7. oldal", + "6": "4. dokumentum: 8. oldal", + "7": "5. dokumentum: 9. oldal", + "8": "6. dokumentum: 10. oldal" + }, + "splitPages": "Adja meg a felosztĆ”si pontokat:", + "submit": "FelosztĆ”s" + }, + "rotate": { + "tags": "szerver oldali", + "title": "PDF forgatĆ”sa", + "header": "PDF forgatĆ”sa", + "selectAngle": "VĆ”lassza ki a forgatĆ”si szƶget (90 fok tƶbbszƶrƶsei):", + "submit": "ForgatĆ”s" + }, + "imageToPdf": { + "tags": "konverzió,kĆ©p,jpg,fotó,fĆ©nykĆ©p" + }, + "pdfToImage": { + "tags": "konverzió,kĆ©p,jpg,fotó,fĆ©nykĆ©p", + "title": "PDF kĆ©ppĆ© alakĆ­tĆ”sa", + "header": "PDF kĆ©ppĆ© alakĆ­tĆ”sa", + "selectText": "KĆ©pformĆ”tum", + "singleOrMultiple": "Kimeneti tĆ­pus", + "single": "Egyetlen nagy kĆ©p", + "multi": "Tƶbb kĆ©p, oldalankĆ©nt egy", + "colorType": "SzĆ­ntĆ­pus", + "color": "SzĆ­nes", + "grey": "SzürkeĆ”rnyalatos", + "blackwhite": "Fekete-fehĆ©r (adatvesztĆ©ssel jĆ”rhat!)", + "submit": "KonvertĆ”lĆ”s", + "info": "Python nincs telepĆ­tve. WebP konverzióhoz szüksĆ©ges.", + "placeholder": "(pl. 1,2,8 vagy 4,7,12-16 vagy 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,pĆ”ros,pĆ”ratlan,rendezĆ©s,mozgatĆ”s", + "title": "Oldalszervező", + "header": "PDF oldalszervező", + "submit": "Oldalak Ć”trendezĆ©se", + "mode": { + "_value": "Mód", + "1": "Egyedi oldalsorrend", + "2": "FordĆ­tott sorrend", + "3": "Duplex rendezĆ©s", + "4": "Füzet rendezĆ©s", + "5": "Oldalról fűzƶtt füzet rendezĆ©s", + "6": "PĆ”ros-pĆ”ratlan szĆ©tvĆ”lasztĆ”s", + "7": "Első oldal eltĆ”volĆ­tĆ”sa", + "8": "Utolsó oldal eltĆ”volĆ­tĆ”sa", + "9": "Első Ć©s utolsó oldal eltĆ”volĆ­tĆ”sa", + "10": "PĆ”ros-pĆ”ratlan egyesĆ­tĆ©s", + "11": "Minden oldal megkettőzĆ©se" + }, + "placeholder": "(pl. 1,3,2 vagy 4-8,2,10-12 vagy 2n-1)" + }, + "addImage": { + "tags": "kĆ©p,jpg,fotó,fĆ©nykĆ©p", + "title": "KĆ©p hozzĆ”adĆ”sa", + "header": "KĆ©p hozzĆ”adĆ”sa PDF-hez", + "everyPage": "Minden oldalra?", + "upload": "KĆ©p hozzĆ”adĆ”sa", + "submit": "KĆ©p hozzĆ”adĆ”sa" + }, + "watermark": { + "tags": "Szƶveg,ismĆ©tlődő,cĆ­mke,egyedi,szerzői jog,vĆ©djegy,kĆ©p,jpg,fotó,fĆ©nykĆ©p", + "title": "VĆ­zjel hozzĆ”adĆ”sa", + "header": "VĆ­zjel hozzĆ”adĆ”sa", + "customColor": "Egyedi szƶvegszĆ­n", + "selectText": { + "1": "VĆ”lassza ki a PDF-et a vĆ­zjel hozzĆ”adĆ”sĆ”hoz:", + "2": "VĆ­zjel szƶvege:", + "3": "BetűmĆ©ret:", + "4": "ForgatĆ”s (0-360):", + "5": "VĆ­zszintes tĆ©rkƶz (VĆ­zjelek kƶzƶtti vĆ­zszintes tĆ”volsĆ”g):", + "6": "Függőleges tĆ©rkƶz (VĆ­zjelek kƶzƶtti függőleges tĆ”volsĆ”g):", + "7": "ƁtlĆ”tszósĆ”g (0% - 100%):", + "8": "VĆ­zjel tĆ­pusa:", + "9": "VĆ­zjel kĆ©pe:", + "10": "PDF konvertĆ”lĆ”sa PDF-kĆ©ppĆ©" + }, + "submit": "VĆ­zjel hozzĆ”adĆ”sa", + "type": { + "1": "Szƶveg", + "2": "KĆ©p" + } + }, + "permissions": { + "tags": "olvasĆ”s,Ć­rĆ”s,szerkesztĆ©s,nyomtatĆ”s", + "title": "JogosultsĆ”gok módosĆ­tĆ”sa", + "header": "JogosultsĆ”gok módosĆ­tĆ”sa", + "warning": "Figyelem: A jogosultsĆ”gok vĆ©glegesĆ­tĆ©sĆ©hez ajĆ”nlott jelszavas vĆ©delmet beĆ”llĆ­tani a jelszó hozzĆ”adĆ”sa funkción keresztül", + "selectText": { + "1": "VĆ”lassza ki a módosĆ­tandó PDF-et", + "2": "BeĆ”llĆ­tandó jogosultsĆ”gok", + "3": "Dokumentum egyesĆ­tĆ©sĆ©nek megakadĆ”lyozĆ”sa", + "4": "Tartalom kinyerĆ©sĆ©nek megakadĆ”lyozĆ”sa", + "5": "AkadĆ”lymentesĆ­tĆ©si cĆ©lĆŗ kinyerĆ©s megakadĆ”lyozĆ”sa", + "6": "ŰrlapkitƶltĆ©s megakadĆ”lyozĆ”sa", + "7": "MódosĆ­tĆ”s megakadĆ”lyozĆ”sa", + "8": "MegjegyzĆ©sek módosĆ­tĆ”sĆ”nak megakadĆ”lyozĆ”sa", + "9": "NyomtatĆ”s megakadĆ”lyozĆ”sa", + "10": "Külƶnbƶző formĆ”tumĆŗ nyomtatĆ”s megakadĆ”lyozĆ”sa" + }, + "submit": "MódosĆ­tĆ”s" + }, + "removePages": { + "tags": "Oldalak eltĆ”volĆ­tĆ”sa,oldalak tƶrlĆ©se" + }, + "addPassword": { + "tags": "biztonsĆ”g,vĆ©delem", + "title": "Jelszó hozzĆ”adĆ”sa", + "header": "Jelszó hozzĆ”adĆ”sa (TitkosĆ­tĆ”s)", + "selectText": { + "1": "VĆ”lassza ki a titkosĆ­tandó PDF-et", + "2": "FelhasznĆ”lói jelszó", + "3": "TitkosĆ­tĆ”si kulcs hossza", + "4": "A magasabb Ć©rtĆ©kek erősebbek, de az alacsonyabb Ć©rtĆ©kek jobb kompatibilitĆ”st biztosĆ­tanak.", + "5": "BeĆ”llĆ­tandó jogosultsĆ”gok (Tulajdonosi jelszóval ajĆ”nlott hasznĆ”lni)", + "6": "Dokumentum egyesĆ­tĆ©sĆ©nek megakadĆ”lyozĆ”sa", + "7": "Tartalom kinyerĆ©sĆ©nek megakadĆ”lyozĆ”sa", + "8": "AkadĆ”lymentesĆ­tĆ©si cĆ©lĆŗ kinyerĆ©s megakadĆ”lyozĆ”sa", + "9": "ŰrlapkitƶltĆ©s megakadĆ”lyozĆ”sa", + "10": "MódosĆ­tĆ”s megakadĆ”lyozĆ”sa", + "11": "MegjegyzĆ©sek módosĆ­tĆ”sĆ”nak megakadĆ”lyozĆ”sa", + "12": "NyomtatĆ”s megakadĆ”lyozĆ”sa", + "13": "Külƶnbƶző formĆ”tumĆŗ nyomtatĆ”s megakadĆ”lyozĆ”sa", + "14": "Tulajdonos jelszó", + "15": "KorlĆ”tozza, hogy mi vĆ©gezhető el a dokumentum megnyitĆ”sa utĆ”n (Nem minden olvasó tĆ”mogatja)", + "16": "KorlĆ”tozza a dokumentum megnyithatsĆ”gĆ”t" + }, + "submit": "TitkosĆ­tĆ”s" + }, + "removePassword": { + "tags": "biztonsĆ”g,feloldĆ”s,vĆ©delem,jelszó tƶrlĆ©se", + "title": "Jelszó eltĆ”volĆ­tĆ”sa", + "header": "Jelszó eltĆ”volĆ­tĆ”sa (VisszafejtĆ©s)", + "selectText": { + "1": "VĆ”lassza ki a visszafejtendő PDF-et", + "2": "Jelszó" + }, + "submit": "EltĆ”volĆ­tĆ”s" + }, + "compressPdfs": { + "tags": "tƶmƶrĆ­tĆ©s,kicsi,kompakt" + }, + "unlockPDFForms": { + "tags": "eltĆ”volĆ­tĆ”s,tƶrlĆ©s,űrlap,mező,Ć­rĆ”svĆ©dett", + "title": "ƍrĆ”svĆ©dettsĆ©g eltĆ”volĆ­tĆ”sa az űrlapmezőkről", + "header": "PDF űrlapok feloldĆ”sa", + "submit": "EltĆ”volĆ­tĆ”s" + }, + "changeMetadata": { + "tags": "CĆ­m,szerző,dĆ”tum,lĆ©trehozĆ”s,idő,kiadó,kĆ©szĆ­tő,statisztika", + "title": "CĆ­m:", + "header": "Metaadatok módosĆ­tĆ”sa", + "selectText": { + "1": "MódosĆ­tsa a kĆ­vĆ”nt mezőket", + "2": "Minden metaadat tƶrlĆ©se", + "3": "EgyĆ©ni metaadatok megjelenĆ­tĆ©se:", + "4": "EgyĆ©b metaadatok:", + "5": "EgyĆ©ni metaadat hozzĆ”adĆ”sa" + }, + "author": "Szerző:", + "creationDate": "LĆ©trehozĆ”s dĆ”tuma (yyyy/MM/dd HH:mm:ss):", + "creator": "LĆ©trehozó:", + "keywords": "Kulcsszavak:", + "modDate": "MódosĆ­tĆ”s dĆ”tuma (yyyy/MM/dd HH:mm:ss):", + "producer": "KĆ©szĆ­tő:", + "subject": "TĆ”rgy:", + "trapped": "BeleĆ©rtve:", + "submit": "MódosĆ­tĆ”s" + }, + "fileToPDF": { + "tags": "Ć”talakĆ­tĆ”s,formĆ”tum,dokumentum,kĆ©p,prezentĆ”ció,szƶveg,konvertĆ”lĆ”s,iroda,dokumentumok,word,excel,powerpoint", + "title": "FĆ”jl konvertĆ”lĆ”sa PDF-be", + "header": "BĆ”rmilyen fĆ”jl konvertĆ”lĆ”sa PDF-be", + "credit": "Ez a szolgĆ”ltatĆ”s a LibreOffice Ć©s Unoconv hasznĆ”latĆ”val műkƶdik.", + "supportedFileTypesInfo": "TĆ”mogatott fĆ”jltĆ­pusok", + "supportedFileTypes": "A tĆ”mogatott fĆ”jltĆ­pusok kƶzƶtt szerepelnek az alĆ”bbiak, de a teljes, naprakĆ©sz listƔƩrt tekintse meg a LibreOffice dokumentĆ”ciójĆ”t", + "submit": "KonvertĆ”lĆ”s PDF-be" + }, + "ocr": { + "tags": "felismerĆ©s,szƶveg,kĆ©p,szkennelĆ©s,olvasĆ”s,azonosĆ­tĆ”s,Ć©szlelĆ©s,szerkeszthető", + "title": "OCR / SzkennelĆ©s tisztĆ­tĆ”sa", + "header": "SzkennelĆ©s tisztĆ­tĆ”sa / OCR (Optikai karakterfelismerĆ©s)", + "selectText": { + "1": "VĆ”lassza ki a PDF-ben felismerendő nyelveket (a felsoroltak jelenleg felismerhetők):", + "2": "OCR szƶveget tartalmazó szƶvegfĆ”jl lĆ©trehozĆ”sa az OCR-ezett PDF mellett", + "3": "FerdĆ©n szkennelt oldalak kijavĆ­tĆ”sa Ć©s visszaforgatĆ”sa", + "4": "Oldal tisztĆ­tĆ”sa, hogy az OCR kevĆ©sbĆ© talĆ”ljon szƶveget a hĆ”ttĆ©rzajban. (Nincs kimeneti vĆ”ltozĆ”s)", + "5": "Oldal tisztĆ­tĆ”sa, hogy az OCR kevĆ©sbĆ© talĆ”ljon szƶveget a hĆ”ttĆ©rzajban, a tisztĆ­tĆ”s megmarad a kimenetben.", + "6": "InteraktĆ­v szƶveget tartalmazó oldalak kihagyĆ”sa, csak kĆ©poldalak OCR-ezĆ©se", + "7": "OCR kĆ©nyszerĆ­tĆ©se, minden oldal OCR-ezĆ©se az eredeti szƶvegelemek eltĆ”volĆ­tĆ”sĆ”val", + "8": "NormĆ”l (Hiba, ha a PDF szƶveget tartalmaz)", + "9": "TovĆ”bbi beĆ”llĆ­tĆ”sok", + "10": "OCR mód", + "11": "KĆ©pek eltĆ”volĆ­tĆ”sa OCR utĆ”n (MINDEN kĆ©p eltĆ”volĆ­tĆ”sa, csak konverziós lĆ©pĆ©skĆ©nt hasznos)", + "12": "RenderelĆ©si tĆ­pus (Haladó)" + }, + "help": "KĆ©rjük, olvassa el ezt a dokumentĆ”ciót mĆ”s nyelvek hasznĆ”latĆ”ról Ć©s/vagy nem Docker kƶrnyezetben való hasznĆ”latról", + "credit": "Ez a szolgĆ”ltatĆ”s a qpdf Ć©s Tesseract OCR hasznĆ”latĆ”val műkƶdik.", + "submit": "PDF feldolgozĆ”sa OCR-rel" + }, + "extractImages": { + "tags": "kĆ©p,fotó,mentĆ©s,archĆ­vum,tƶmƶrĆ­tĆ©s,kinyerĆ©s,gyűjtĆ©s", + "title": "KĆ©pek kinyerĆ©se", + "header": "KĆ©pek kinyerĆ©se", + "selectText": "VĆ”lassza ki a kinyert kĆ©pek konvertĆ”lĆ”si formĆ”tumĆ”t", + "allowDuplicates": "IsmĆ©tlődő kĆ©pek mentĆ©se", + "submit": "KinyerĆ©s" + }, + "pdfToPDFA": { + "tags": "archĆ­vum,hosszĆŗ tĆ”vĆŗ,szabvĆ”ny,konvertĆ”lĆ”s,tĆ”rolĆ”s,megőrzĆ©s", + "title": "PDF konvertĆ”lĆ”sa PDF/A formĆ”tumba", + "header": "PDF konvertĆ”lĆ”sa PDF/A formĆ”tumba", + "credit": "Ez a szolgĆ”ltatĆ”s a libreoffice hasznĆ”latĆ”val vĆ©gzi a PDF/A konverziót", + "submit": "KonvertĆ”lĆ”s", + "tip": "Jelenleg nem tĆ”mogatja a tƶbb fĆ”jl egyidejű feldolgozĆ”sĆ”t", + "outputFormat": "Kimeneti formĆ”tum", + "pdfWithDigitalSignature": "A PDF digitĆ”lis alƔƭrĆ”st tartalmaz. Ez a kƶvetkező lĆ©pĆ©sben eltĆ”volĆ­tĆ”sra kerül." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,Ć”talakĆ­tĆ”s,formĆ”tum,konvertĆ”lĆ”s,iroda,microsoft,docfile", + "title": "PDF konvertĆ”lĆ”sa Word formĆ”tumba", + "header": "PDF konvertĆ”lĆ”sa Word formĆ”tumba", + "selectText": { + "1": "Kimeneti fĆ”jlformĆ”tum" + }, + "credit": "Ez a szolgĆ”ltatĆ”s a LibreOffice hasznĆ”latĆ”val vĆ©gzi a konverziót.", + "submit": "KonvertĆ”lĆ”s" + }, + "PDFToPresentation": { + "tags": "dia,bemutató,iroda,microsoft", + "title": "PDF konvertĆ”lĆ”sa prezentĆ”cióvĆ”", + "header": "PDF konvertĆ”lĆ”sa prezentĆ”cióvĆ”", + "selectText": { + "1": "Kimeneti fĆ”jlformĆ”tum" + }, + "credit": "Ez a szolgĆ”ltatĆ”s a LibreOffice hasznĆ”latĆ”val vĆ©gzi a konverziót.", + "submit": "KonvertĆ”lĆ”s" + }, + "PDFToText": { + "tags": "formĆ”zott szƶveg,rtf,szƶvegformĆ”tum", + "title": "PDF konvertĆ”lĆ”sa RTF (szƶveg) formĆ”tumba", + "header": "PDF konvertĆ”lĆ”sa RTF (szƶveg) formĆ”tumba", + "selectText": { + "1": "Kimeneti fĆ”jlformĆ”tum" + }, + "credit": "Ez a szolgĆ”ltatĆ”s a LibreOffice hasznĆ”latĆ”val vĆ©gzi a konverziót.", + "submit": "KonvertĆ”lĆ”s" + }, + "PDFToHTML": { + "tags": "webtartalom,bƶngĆ©szőbarĆ”t", + "title": "PDF konvertĆ”lĆ”sa HTML-be", + "header": "PDF konvertĆ”lĆ”sa HTML-be", + "credit": "Ez a szolgĆ”ltatĆ”s a pdftohtml hasznĆ”latĆ”val vĆ©gzi a konverziót.", + "submit": "KonvertĆ”lĆ”s" + }, + "PDFToXML": { + "tags": "adatkinyerĆ©s,strukturĆ”lt tartalom,interoperabilitĆ”s,konvertĆ”lĆ”s", + "title": "PDF konvertĆ”lĆ”sa XML-be", + "header": "PDF konvertĆ”lĆ”sa XML-be", + "credit": "Ez a szolgĆ”ltatĆ”s a LibreOffice hasznĆ”latĆ”val vĆ©gzi a konverziót.", + "submit": "KonvertĆ”lĆ”s" + }, + "ScannerImageSplit": { + "tags": "szĆ©tvĆ”lasztĆ”s,automatikus felismerĆ©s,szkennelĆ©s,tƶbb fotó,rendszerezĆ©s", + "selectText": { + "1": "Szƶg küszƶbĆ©rtĆ©k:", + "2": "A kĆ©p forgatĆ”sĆ”hoz szüksĆ©ges minimĆ”lis abszolĆŗt szƶg beĆ”llĆ­tĆ”sa (alapĆ©rtelmezett: 10).", + "3": "Tolerancia:", + "4": "A becsült hĆ”ttĆ©rszĆ­n kƶrüli szĆ­nvĆ”ltozĆ”si tartomĆ”ny meghatĆ”rozĆ”sa (alapĆ©rtelmezett: 30).", + "5": "MinimĆ”lis terület:", + "6": "A fotó minimĆ”lis területĆ©nek küszƶbĆ©rtĆ©ke (alapĆ©rtelmezett: 10000).", + "7": "MinimĆ”lis kontĆŗr terület:", + "8": "A fotó minimĆ”lis kontĆŗr területĆ©nek küszƶbĆ©rtĆ©ke", + "9": "Keret mĆ©rete:", + "10": "A hozzĆ”adott Ć©s eltĆ”volĆ­tott keret mĆ©retĆ©nek beĆ”llĆ­tĆ”sa a fehĆ©r keretek elkerülĆ©se Ć©rdekĆ©ben (alapĆ©rtelmezett: 1)." + }, + "info": "Python nincs telepĆ­tve. A futtatĆ”shoz szüksĆ©ges." + }, + "sign": { + "tags": "hitelesĆ­tĆ©s,rƶvidĆ­tĆ©s,rajzolt alƔƭrĆ”s,szƶveges alƔƭrĆ”s,kĆ©pes alƔƭrĆ”s", + "title": "AlƔƭrĆ”s", + "header": "PDF-ek alƔƭrĆ”sa", + "upload": "KĆ©p feltƶltĆ©se", + "draw": "AlƔƭrĆ”s rajzolĆ”sa", + "text": "Szƶveg bevitele", + "clear": "TƶrlĆ©s", + "add": "HozzĆ”adĆ”s", + "saved": "Mentett alƔƭrĆ”sok", + "save": "AlƔƭrĆ”s mentĆ©se", + "personalSigs": "SzemĆ©lyes alƔƭrĆ”sok", + "sharedSigs": "Megosztott alƔƭrĆ”sok", + "noSavedSigs": "Nincsenek mentett alƔƭrĆ”sok", + "addToAll": "HozzĆ”adĆ”s minden oldalhoz", + "delete": "TƶrlĆ©s", + "first": "Első oldal", + "last": "Utolsó oldal", + "next": "Kƶvetkező oldal", + "previous": "Előző oldal", + "maintainRatio": "KĆ©parĆ”ny fenntartĆ”sa vĆ”ltĆ”sa", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "statikus,deaktivĆ”lĆ”s,nem interaktĆ­v,egyszerűsĆ­tĆ©s", + "title": "LapĆ­tĆ”s", + "header": "PDF-ek lapĆ­tĆ”sa", + "flattenOnlyForms": "Csak űrlapok lapĆ­tĆ”sa", + "submit": "LapĆ­tĆ”s" + }, + "repair": { + "tags": "javĆ­tĆ”s,helyreĆ”llĆ­tĆ”s,korrekció,visszaĆ”llĆ­tĆ”s", + "title": "JavĆ­tĆ”s", + "header": "PDF-ek javĆ­tĆ”sa", + "submit": "JavĆ­tĆ”s" + }, + "removeBlanks": { + "tags": "tisztĆ­tĆ”s,egyszerűsĆ­tĆ©s,tartalommentes,rendszerezĆ©s", + "title": "Üres oldalak eltĆ”volĆ­tĆ”sa", + "header": "Üres oldalak eltĆ”volĆ­tĆ”sa", + "threshold": "Pixel fehĆ©rsĆ©g küszƶbĆ©rtĆ©ke:", + "thresholdDesc": "KüszƶbĆ©rtĆ©k annak meghatĆ”rozĆ”sĆ”hoz, hogy egy fehĆ©r pixel mennyire legyen fehĆ©r. 0 = fekete, 255 = tiszta fehĆ©r.", + "whitePercent": "FehĆ©r szĆ”zalĆ©k (%):", + "whitePercentDesc": "Az oldal hĆ”ny szĆ”zalĆ©kĆ”nak kell 'fehĆ©r' pixelnek lennie az eltĆ”volĆ­tĆ”shoz", + "submit": "Üres oldalak eltĆ”volĆ­tĆ”sa" + }, + "removeAnnotations": { + "tags": "megjegyzĆ©sek,kiemelĆ©s,jegyzetek,jelƶlĆ©sek,eltĆ”volĆ­tĆ”s", + "title": "MegjegyzĆ©sek eltĆ”volĆ­tĆ”sa", + "header": "MegjegyzĆ©sek eltĆ”volĆ­tĆ”sa", + "submit": "EltĆ”volĆ­tĆ”s" + }, + "compare": { + "tags": "külƶnbsĆ©g,kontraszt,vĆ”ltozĆ”sok,elemzĆ©s", + "title": "ƖsszehasonlĆ­tĆ”s", + "header": "PDF-ek ƶsszehasonlĆ­tĆ”sa", + "highlightColor": { + "1": "Kiemelő szĆ­n 1:", + "2": "Kiemelő szĆ­n 2:" + }, + "document": { + "1": "1. dokumentum", + "2": "2. dokumentum" + }, + "submit": "ƖsszehasonlĆ­tĆ”s", + "complex": { + "message": "Az egyik vagy mindkĆ©t dokumentum nagy mĆ©retű, az ƶsszehasonlĆ­tĆ”s pontossĆ”ga csƶkkenhet" + }, + "large": { + "file": { + "message": "Az egyik vagy mindkĆ©t dokumentum tĆŗl nagy a feldolgozĆ”shoz" + } + }, + "no": { + "text": { + "message": "Az egyik vagy mindkĆ©t PDF nem tartalmaz szƶveget. KĆ©rjük, vĆ”lasszon szƶveget tartalmazó PDF-eket az ƶsszehasonlĆ­tĆ”shoz." + } + } + }, + "certSign": { + "tags": "hitelesĆ­tĆ©s,PEM,P12,hivatalos,titkosĆ­tĆ”s", + "title": "TanĆŗsĆ­tvĆ”nnyal alƔƭrĆ”s", + "header": "PDF alƔƭrĆ”sa tanĆŗsĆ­tvĆ”nnyal (fejlesztĆ©s alatt)", + "selectPDF": "VĆ”lasszon alƔƭrandó PDF fĆ”jlt:", + "jksNote": "MegjegyzĆ©s: Ha a tanĆŗsĆ­tvĆ”nytĆ­pusa nem szerepel a listĆ”ban, konvertĆ”lja Java Keystore (.jks) formĆ”tumba a keytool parancssorral. EzutĆ”n vĆ”lassza a .jks fĆ”jl opciót.", + "selectKey": "VĆ”lassza ki a privĆ”t kulcs fĆ”jlt (PKCS#8 formĆ”tum, .pem vagy .der):", + "selectCert": "VĆ”lassza ki a tanĆŗsĆ­tvĆ”ny fĆ”jlt (X.509 formĆ”tum, .pem vagy .der):", + "selectP12": "VĆ”lassza ki a PKCS#12 kulcstĆ”r fĆ”jlt (.p12 vagy .pfx) (OpcionĆ”lis, ha megadja, tartalmaznia kell a privĆ”t kulcsot Ć©s tanĆŗsĆ­tvĆ”nyt):", + "selectJKS": "VĆ”lassza ki a Java Keystore fĆ”jlt (.jks vagy .keystore):", + "certType": "TanĆŗsĆ­tvĆ”ny tĆ­pusa", + "password": "Adja meg a kulcstĆ”r vagy privĆ”t kulcs jelszavĆ”t (ha van):", + "showSig": "AlƔƭrĆ”s megjelenĆ­tĆ©se", + "reason": "Ok", + "location": "Hely", + "name": "NĆ©v", + "showLogo": "Logó megjelenĆ­tĆ©se", + "submit": "PDF alƔƭrĆ”sa" + }, + "removeCertSign": { + "tags": "hitelesĆ­tĆ©s,PEM,P12,hivatalos,visszafejtĆ©s", + "title": "TanĆŗsĆ­tvĆ”nyos alƔƭrĆ”s eltĆ”volĆ­tĆ”sa", + "header": "DigitĆ”lis tanĆŗsĆ­tvĆ”ny eltĆ”volĆ­tĆ”sa a PDF-ből", + "selectPDF": "PDF fĆ”jl kivĆ”lasztĆ”sa:", + "submit": "AlƔƭrĆ”s eltĆ”volĆ­tĆ”sa" + }, + "pageLayout": { + "tags": "egyesĆ­tĆ©s,kompozit,egyoldalas nĆ©zet,rendszerezĆ©s", + "title": "Tƶbboldalas elrendezĆ©s", + "header": "Tƶbboldalas elrendezĆ©s", + "pagesPerSheet": "Oldalak laponkĆ©nt:", + "addBorder": "Keret hozzĆ”adĆ”sa", + "submit": "KüldĆ©s" + }, + "scalePages": { + "tags": "Ć”tmĆ©retezĆ©s,módosĆ­tĆ”s,dimenzió,igazĆ­tĆ”s", + "title": "OldalmĆ©ret beĆ”llĆ­tĆ”sa", + "header": "OldalmĆ©ret beĆ”llĆ­tĆ”sa", + "pageSize": "A dokumentum oldalmĆ©rete.", + "keepPageSize": "Eredeti mĆ©ret", + "scaleFactor": "Oldal nagyĆ­tĆ”si szintje (vĆ”gĆ”s).", + "submit": "KüldĆ©s" + }, + "add-page-numbers": { + "tags": "szĆ”mozĆ”s,cĆ­mke,rendszerezĆ©s,index" + }, + "auto-rename": { + "tags": "automatikus felismerĆ©s,fejlĆ©c alapĆŗ,rendszerezĆ©s,ĆŗjracĆ­mkĆ©zĆ©s", + "title": "Automatikus Ć”tnevezĆ©s", + "header": "PDF automatikus Ć”tnevezĆ©se", + "submit": "Automatikus Ć”tnevezĆ©s" + }, + "adjust-contrast": { + "tags": "szĆ­nkorrekció,hangolĆ”s,módosĆ­tĆ”s,javĆ­tĆ”s" + }, + "crop": { + "tags": "vĆ”gĆ”s,kicsinyĆ­tĆ©s,szerkesztĆ©s,forma", + "title": "VĆ”gĆ”s", + "header": "PDF vĆ”gĆ”sa", + "submit": "KüldĆ©s" + }, + "autoSplitPDF": { + "tags": "QR-alapĆŗ,szĆ©tvĆ”lasztĆ”s,szkennelt szekció,rendszerezĆ©s", + "title": "Automatikus PDF felosztĆ”s", + "header": "Automatikus PDF felosztĆ”s", + "description": "Nyomtasson, illesszen be, szkenneljen, tƶltsƶn fel, Ć©s hagyja, hogy a dokumentumok automatikusan szĆ©tvĆ”ljanak. Nincs szüksĆ©g kĆ©zi rendezĆ©sre.", + "selectText": { + "1": "Nyomtasson elvĆ”lasztólapokat alĆ”bb (fekete-fehĆ©r is megfelel).", + "2": "Szkennelje be az ƶsszes dokumentumot egyszerre, az elvĆ”lasztólapokat kƶzĆ©jük helyezve.", + "3": "Tƶltse fel az egyetlen nagy szkennelt PDF fĆ”jlt, Ć©s hagyja, hogy a Stirling PDF elvĆ©gezze a tƶbbit.", + "4": "Az elvĆ”lasztólapokat automatikusan felismeri Ć©s eltĆ”volĆ­tja, garantĆ”lva a rendezett vĆ©geredmĆ©nyt." + }, + "formPrompt": "Tƶltse fel a Stirling-PDF oldalelvĆ”lasztókat tartalmazó PDF-et:", + "duplexMode": "Duplex mód (Elő- Ć©s hĆ”toldali szkennelĆ©s)", + "dividerDownload2": "'Automatikus elvĆ”lasztó (utasĆ­tĆ”sokkal).pdf' letƶltĆ©se", + "submit": "KüldĆ©s" + }, + "sanitizePdf": { + "tags": "tisztĆ­tĆ”s,biztonsĆ”g,vĆ©delem,veszĆ©lyek eltĆ”volĆ­tĆ”sa" + }, + "URLToPDF": { + "tags": "webmentĆ©s,oldal mentĆ©se,web-dokumentum,archivĆ”lĆ”s", + "title": "URL konvertĆ”lĆ”sa PDF-be", + "header": "URL konvertĆ”lĆ”sa PDF-be", + "submit": "KonvertĆ”lĆ”s", + "credit": "WeasyPrint hasznĆ”latĆ”val" + }, + "HTMLToPDF": { + "tags": "jelƶlőnyelv,webtartalom,Ć”talakĆ­tĆ”s,konvertĆ”lĆ”s", + "title": "HTML konvertĆ”lĆ”sa PDF-be", + "header": "HTML konvertĆ”lĆ”sa PDF-be", + "help": "HTML fĆ”jlokat Ć©s szüksĆ©ges html/css/kĆ©peket tartalmazó ZIP-eket fogad el", + "submit": "KonvertĆ”lĆ”s", + "credit": "WeasyPrint hasznĆ”latĆ”val", + "zoom": "Weboldal megjelenĆ­tĆ©si nagyĆ­tĆ”sa.", + "pageWidth": "OldalszĆ©lessĆ©g centimĆ©terben. (Üresen hagyva alapĆ©rtelmezett)", + "pageHeight": "OldalmagassĆ”g centimĆ©terben. (Üresen hagyva alapĆ©rtelmezett)", + "marginTop": "Felső margó millimĆ©terben. (Üresen hagyva alapĆ©rtelmezett)", + "marginBottom": "Alsó margó millimĆ©terben. (Üresen hagyva alapĆ©rtelmezett)", + "marginLeft": "Bal margó millimĆ©terben. (Üresen hagyva alapĆ©rtelmezett)", + "marginRight": "Jobb margó millimĆ©terben. (Üresen hagyva alapĆ©rtelmezett)", + "printBackground": "Weboldalak hĆ”tterĆ©nek renderelĆ©se.", + "defaultHeader": "AlapĆ©rtelmezett fejlĆ©c engedĆ©lyezĆ©se (NĆ©v Ć©s oldalszĆ”m)", + "cssMediaType": "Oldal CSS mĆ©diatĆ­pusĆ”nak módosĆ­tĆ”sa.", + "none": "Nincs", + "print": "NyomtatĆ”s", + "screen": "KĆ©pernyő" + }, + "MarkdownToPDF": { + "tags": "jelƶlőnyelv,webtartalom,Ć”talakĆ­tĆ”s,konvertĆ”lĆ”s", + "title": "Markdown konvertĆ”lĆ”sa PDF-be", + "header": "Markdown konvertĆ”lĆ”sa PDF-be", + "submit": "KonvertĆ”lĆ”s", + "help": "FejlesztĆ©s alatt", + "credit": "WeasyPrint hasznĆ”latĆ”val" + }, + "PDFToMarkdown": { + "tags": "markup,webtartalom,Ć”talakĆ­tĆ”s,konvertĆ”lĆ”s,md", + "title": "PDF fĆ”jl konvertĆ”lĆ”sa Markdown fĆ”jlba", + "header": "PDF fĆ”jl konvertĆ”lĆ”sa Markdown fĆ”jlba", + "submit": "KonvertĆ”lĆ”s" + }, + "getPdfInfo": { + "tags": "informĆ”ció,adat,statisztika,rĆ©szletek", + "title": "PDF informĆ”ciók lekĆ©rĆ©se", + "header": "PDF informĆ”ciók lekĆ©rĆ©se", + "submit": "InformĆ”ciók lekĆ©rĆ©se", + "downloadJson": "JSON letƶltĆ©se" + }, + "extractPage": { + "tags": "kinyerĆ©s" + }, + "PdfToSinglePage": { + "tags": "egyoldalas" + }, + "showJS": { + "tags": "JS", + "title": "JavaScript megjelenĆ­tĆ©se", + "header": "JavaScript megjelenĆ­tĆ©se", + "downloadJS": "JavaScript letƶltĆ©se", + "submit": "MegjelenĆ­tĆ©s" + }, + "autoRedact": { + "tags": "KitakarĆ”s,ElrejtĆ©s,fekete kitakarĆ”s,fekete,jelƶlő,rejtett", + "title": "Automatikus kitakarĆ”s", + "header": "Automatikus kitakarĆ”s", + "colorLabel": "SzĆ­n", + "textsToRedactLabel": "Kitakarandó szƶvegek (soronkĆ©nt)", + "textsToRedactPlaceholder": "pĆ©ldĆ”ul \\nBizalmas \\nSzigorĆŗan titkos", + "useRegexLabel": "RegulĆ”ris kifejezĆ©s hasznĆ”lata", + "wholeWordSearchLabel": "Teljes szó keresĆ©se", + "customPaddingLabel": "Egyedi extra kitƶltĆ©s", + "convertPDFToImageLabel": "PDF konvertĆ”lĆ”sa PDF-kĆ©ppĆ© (a doboz mƶgƶtti szƶveg eltĆ”volĆ­tĆ”sĆ”hoz)", + "submitButton": "KüldĆ©s" + }, + "redact": { + "tags": "KitakarĆ”s,ElrejtĆ©s,fekete kitakarĆ”s,fekete,jelƶlő,rejtett,kĆ©zi", + "title": "KĆ©zi kitakarĆ”s", + "header": "KĆ©zi kitakarĆ”s", + "submit": "KitakarĆ”s", + "textBasedRedaction": "Szƶveg alapĆŗ kitakarĆ”s", + "pageBasedRedaction": "Oldal alapĆŗ kitakarĆ”s", + "convertPDFToImageLabel": "PDF konvertĆ”lĆ”sa kĆ©ppĆ© (a doboz mƶgƶtti szƶveg eltĆ”volĆ­tĆ”sĆ”hoz)", + "pageRedactionNumbers": { + "title": "OldalszĆ”mok", + "placeholder": "(pĆ©ldĆ”ul 1,2,8 vagy 4,7,12-16 vagy 2n-1)" + }, + "redactionColor": { + "title": "KitakarĆ”s szĆ­ne" + }, + "export": "ExportĆ”lĆ”s", + "upload": "FeltƶltĆ©s", + "boxRedaction": "KivĆ”lasztott doboz kitakarĆ”sa", + "zoom": "NagyĆ­tĆ”s/kicsinyĆ­tĆ©s", + "zoomIn": "NagyĆ­tĆ”s", + "zoomOut": "KicsinyĆ­tĆ©s", + "nextPage": "Kƶvetkező oldal", + "previousPage": "Előző oldal", + "toggleSidebar": "OldalsĆ”v megjelenĆ­tĆ©se/elrejtĆ©se", + "showThumbnails": "ElőnĆ©zet megjelenĆ­tĆ©se", + "showDocumentOutline": "DokumentumvĆ”zlat megjelenĆ­tĆ©se (dupla kattintĆ”s a kibővĆ­tĆ©shez/ƶsszecsukĆ”shoz)", + "showAttatchments": "MellĆ©kletek megjelenĆ­tĆ©se", + "showLayers": "RĆ©tegek megjelenĆ­tĆ©se (dupla kattintĆ”s az ƶsszes rĆ©teg alaphelyzetbe Ć”llĆ­tĆ”sĆ”hoz)", + "colourPicker": "SzĆ­nvĆ”lasztó", + "findCurrentOutlineItem": "KeresĆ©s a jelenlegi vĆ”zlatban", + "applyChanges": "VĆ”ltoztatĆ”sok mentĆ©se" + }, + "tableExtraxt": { + "tags": "CSV,TĆ”blĆ”zat kinyerĆ©se,kinyerĆ©s,konvertĆ”lĆ”s" + }, + "autoSizeSplitPDF": { + "tags": "pdf,felosztĆ”s,dokumentum,rendszerezĆ©s" + }, + "overlay-pdfs": { + "tags": "ƁtfedĆ©s", + "header": "PDF-ek egymĆ”sra helyezĆ©se", + "baseFile": { + "label": "VĆ”lassza ki az alap PDF fĆ”jlt" + }, + "overlayFiles": { + "label": "VĆ”lassza ki a rĆ”helyezendő PDF fĆ”jlokat" + }, + "mode": { + "label": "VĆ”lassza ki az egymĆ”sra helyezĆ©s módjĆ”t", + "sequential": "SzekvenciĆ”lis egymĆ”sra helyezĆ©s", + "interleaved": "VĆ”ltakozó egymĆ”sra helyezĆ©s", + "fixedRepeat": "RƶgzĆ­tett ismĆ©tlődő egymĆ”sra helyezĆ©s" + }, + "counts": { + "label": "IsmĆ©tlĆ©sek szĆ”ma (rƶgzĆ­tett ismĆ©tlődő módhoz)", + "placeholder": "Adja meg a vesszővel elvĆ”lasztott szĆ”mokat (pl. 2,3,1)" + }, + "position": { + "label": "VĆ”lassza ki az egymĆ”sra helyezĆ©s pozĆ­ciójĆ”t", + "foreground": "ElőtĆ©r", + "background": "HĆ”ttĆ©r" + }, + "submit": "KüldĆ©s" + }, + "split-by-sections": { + "tags": "Szakaszos felosztĆ”s,FelosztĆ”s,TestreszabĆ”s", + "title": "PDF felosztĆ”sa szakaszokra", + "header": "PDF felosztĆ”sa szakaszokra", + "horizontal": { + "label": "VĆ­zszintes felosztĆ”sok", + "placeholder": "Adja meg a vĆ­zszintes felosztĆ”sok szĆ”mĆ”t" + }, + "vertical": { + "label": "Függőleges felosztĆ”sok", + "placeholder": "Adja meg a függőleges felosztĆ”sok szĆ”mĆ”t" + }, + "submit": "PDF felosztĆ”sa", + "merge": "EgyesĆ­tĆ©s egy PDF-be" + }, + "AddStampRequest": { + "tags": "PecsĆ©t,KĆ©p hozzĆ”adĆ”sa,kƶzĆ©pre igazĆ­tĆ”s,VĆ­zjel,PDF,BeĆ”gyazĆ”s,TestreszabĆ”s", + "header": "PDF pecsĆ©telĆ©se", + "title": "PDF pecsĆ©telĆ©se", + "stampType": "PecsĆ©t tĆ­pusa", + "stampText": "PecsĆ©t szƶvege", + "stampImage": "PecsĆ©t kĆ©pe", + "alphabet": "ƁbĆ©cĆ©", + "fontSize": "Betű/KĆ©p mĆ©rete", + "rotation": "ForgatĆ”s", + "opacity": "ƁtlĆ”tszósĆ”g", + "position": "PozĆ­ció", + "overrideX": "X koordinĆ”ta felülĆ­rĆ”sa", + "overrideY": "Y koordinĆ”ta felülĆ­rĆ”sa", + "customMargin": "Egyedi margó", + "customColor": "Egyedi szƶvegszĆ­n", + "submit": "KüldĆ©s" + }, + "removeImagePdf": { + "tags": "KĆ©pek eltĆ”volĆ­tĆ”sa,Oldalműveletek,Backend,szerver oldali" + }, + "splitPdfByChapters": { + "tags": "felosztĆ”s,fejezetek,kƶnyvjelzők,rendszerezĆ©s" + }, + "validateSignature": { + "tags": "alƔƭrĆ”s,ellenőrzĆ©s,validĆ”lĆ”s,pdf,tanĆŗsĆ­tvĆ”ny,digitĆ”lis alƔƭrĆ”s,AlƔƭrĆ”s ellenőrzĆ©se,TanĆŗsĆ­tvĆ”ny ellenőrzĆ©se", + "title": "PDF alƔƭrĆ”sok ellenőrzĆ©se", + "header": "DigitĆ”lis alƔƭrĆ”sok ellenőrzĆ©se", + "selectPDF": "VĆ”lassza ki az alƔƭrt PDF fĆ”jlt", + "submit": "AlƔƭrĆ”sok ellenőrzĆ©se", + "results": "EllenőrzĆ©s eredmĆ©nye", + "status": { + "_value": "Ɓllapot", + "valid": "ƉrvĆ©nyes", + "invalid": "ƉrvĆ©nytelen" + }, + "signer": "AlƔƭró", + "date": "DĆ”tum", + "reason": "Ok", + "location": "Hely", + "noSignatures": "A dokumentumban nem talĆ”lható digitĆ”lis alƔƭrĆ”s", + "chain": { + "invalid": "TanĆŗsĆ­tvĆ”nylĆ”nc ellenőrzĆ©se sikertelen - az alƔƭró szemĆ©lyazonossĆ”ga nem ellenőrizhető" + }, + "trust": { + "invalid": "A tanĆŗsĆ­tvĆ”ny nincs a megbĆ­zható tĆ”rolóban - a forrĆ”s nem ellenőrizhető" + }, + "cert": { + "expired": "A tanĆŗsĆ­tvĆ”ny lejĆ”rt", + "revoked": "A tanĆŗsĆ­tvĆ”ny visszavonĆ”sra került", + "info": "TanĆŗsĆ­tvĆ”ny rĆ©szletei", + "issuer": "KibocsĆ”tó", + "subject": "Alany", + "serialNumber": "SorozatszĆ”m", + "validFrom": "ƉrvĆ©nyessĆ©g kezdete", + "validUntil": "ƉrvĆ©nyessĆ©g vĆ©ge", + "algorithm": "Algoritmus", + "keySize": "KulcsmĆ©ret", + "version": "Verzió", + "keyUsage": "KulcshasznĆ”lat", + "selfSigned": "ƖnalƔƭrt", + "bits": "bit" + }, + "signature": { + "info": "AlƔƭrĆ”s informĆ”ció", + "_value": "AlƔƭrĆ”s", + "mathValid": "Az alƔƭrĆ”s matematikailag Ć©rvĆ©nyes, DE:" + }, + "selectCustomCert": "EgyĆ©ni X.509 tanĆŗsĆ­tvĆ”nyfĆ”jl (OpcionĆ”lis)" + }, + "replace-color": { + "title": "SzĆ­ncsere-InvertĆ”lĆ”s", + "header": "PDF szĆ­nek cserĆ©je-invertĆ”lĆ”sa", + "selectText": { + "1": "SzĆ­ncsere vagy -invertĆ”lĆ”s beĆ”llĆ­tĆ”sai", + "2": "AlapĆ©rtelmezett (AlapĆ©rtelmezett kontrasztos szĆ­nek)", + "3": "EgyĆ©ni (EgyĆ©ni szĆ­nek)", + "4": "Teljes invertĆ”lĆ”s (Minden szĆ­n invertĆ”lĆ”sa)", + "5": "Magas kontrasztĆŗ szĆ­nbeĆ”llĆ­tĆ”sok", + "6": "fehĆ©r szƶveg fekete hĆ”ttĆ©ren", + "7": "fekete szƶveg fehĆ©r hĆ”ttĆ©ren", + "8": "sĆ”rga szƶveg fekete hĆ”ttĆ©ren", + "9": "zƶld szƶveg fekete hĆ”ttĆ©ren", + "10": "SzƶvegszĆ­n kivĆ”lasztĆ”sa", + "11": "HĆ”ttĆ©rszĆ­n kivĆ”lasztĆ”sa" + }, + "submit": "Csere" + }, + "replaceColorPdf": { + "tags": "SzĆ­ncsere,Oldalműveletek,Backend,szerver oldali" + }, + "login": { + "title": "BejelentkezĆ©s", + "header": "BejelentkezĆ©s", + "signin": "BejelentkezĆ©s", + "rememberme": "EmlĆ©kezzen rĆ”m", + "invalid": "ƉrvĆ©nytelen felhasznĆ”lónĆ©v vagy jelszó.", + "locked": "A fiókja zĆ”rolva van.", + "signinTitle": "KĆ©rjük, jelentkezzen be", + "ssoSignIn": "BejelentkezĆ©s egyszeri bejelentkezĆ©ssel", + "oAuth2AutoCreateDisabled": "OAuth2 automatikus felhasznĆ”lólĆ©trehozĆ”s letiltva", + "oAuth2AdminBlockedUser": "A nem regisztrĆ”lt felhasznĆ”lók regisztrĆ”ciója vagy bejelentkezĆ©se jelenleg le van tiltva. KĆ©rjük, forduljon a rendszergazdĆ”hoz.", + "oauth2RequestNotFound": "A hitelesĆ­tĆ©si kĆ©rĆ©s nem talĆ”lható", + "oauth2InvalidUserInfoResponse": "ƉrvĆ©nytelen felhasznĆ”lói informĆ”ció vĆ”lasz", + "oauth2invalidRequest": "ƉrvĆ©nytelen kĆ©rĆ©s", + "oauth2AccessDenied": "HozzĆ”fĆ©rĆ©s megtagadva", + "oauth2InvalidTokenResponse": "ƉrvĆ©nytelen token vĆ”lasz", + "oauth2InvalidIdToken": "ƉrvĆ©nytelen azonosĆ­tó token", + "relyingPartyRegistrationNotFound": "Kliens regisztrĆ”ció nem talĆ”lható", + "userIsDisabled": "A felhasznĆ”ló letiltva, a bejelentkezĆ©s jelenleg nem lehetsĆ©ges ezzel a felhasznĆ”lónĆ©vvel. KĆ©rjük, forduljon a rendszergazdĆ”hoz.", + "alreadyLoggedIn": "MĆ”r be van jelentkezve", + "alreadyLoggedIn2": "eszkƶzƶn. KĆ©rjük, jelentkezzen ki az eszkƶzƶkről Ć©s próbĆ”lja Ćŗjra.", + "toManySessions": "TĆŗl sok aktĆ­v munkamenet", + "logoutMessage": "Sikeresen kijelentkezett." + }, + "pdfToSinglePage": { + "title": "PDF egyoldalassĆ” alakĆ­tĆ”sa", + "header": "PDF egyoldalassĆ” alakĆ­tĆ”sa", + "submit": "KonvertĆ”lĆ”s egyoldalassĆ”" + }, + "pageExtracter": { + "title": "Oldalak kinyerĆ©se", + "header": "Oldalak kinyerĆ©se", + "submit": "KinyerĆ©s", + "placeholder": "(pl. 1,2,8 vagy 4,7,12-16 vagy 2n-1)" + }, + "sanitizePDF": { + "title": "PDF tisztĆ­tĆ”sa", + "header": "PDF fĆ”jl tisztĆ­tĆ”sa", + "selectText": { + "1": "JavaScript műveletek eltĆ”volĆ­tĆ”sa", + "2": "BeĆ”gyazott fĆ”jlok eltĆ”volĆ­tĆ”sa", + "3": "XMP metaadatok eltĆ”volĆ­tĆ”sa", + "4": "HivatkozĆ”sok eltĆ”volĆ­tĆ”sa", + "5": "BetűtĆ­pusok eltĆ”volĆ­tĆ”sa", + "6": "Dokumentum metainformĆ”ciók eltĆ”volĆ­tĆ”sa" + }, + "submit": "PDF tisztĆ­tĆ”sa" + }, + "adjustContrast": { + "title": "Kontraszt beĆ”llĆ­tĆ”sa", + "header": "Kontraszt beĆ”llĆ­tĆ”sa", + "contrast": "Kontraszt:", + "brightness": "FĆ©nyerő:", + "saturation": "TelĆ­tettsĆ©g:", + "download": "LetƶltĆ©s" + }, + "compress": { + "title": "TƶmƶrĆ­tĆ©s", + "header": "PDF tƶmƶrĆ­tĆ©se", + "credit": "Ez a szolgĆ”ltatĆ”s a qpdf hasznĆ”latĆ”val vĆ©gzi a PDF tƶmƶrĆ­tĆ©sĆ©t/optimalizĆ”lĆ”sĆ”t.", + "grayscale": { + "label": "SzürkeĆ”rnyalatok alkalmazĆ”sa tƶmƶrĆ­tĆ©shez" + }, + "selectText": { + "1": { + "_value": "TƶmƶrĆ­tĆ©si beĆ”llĆ­tĆ”sok", + "1": "1-3 PDF tƶmƶrĆ­tĆ©s,
4-6 enyhe kƩp tƶmƶrƭtƩs,
7-9 intenzĆ­v kĆ©p tƶmƶrĆ­tĆ©s Jelentősen csƶkkenti a kĆ©p minősĆ©gĆ©t" + }, + "2": "OptimalizĆ”lĆ”si szint:", + "4": "Automatikus mód - Automatikusan Ć”llĆ­tja a minősĆ©get a megadott PDF mĆ©ret elĆ©rĆ©sĆ©hez", + "5": "KĆ­vĆ”nt PDF mĆ©ret (pl. 25MB, 10.8MB, 25KB)" + }, + "submit": "TƶmƶrĆ­tĆ©s" + }, + "decrypt": { + "passwordPrompt": "Ez a fĆ”jl jelszóval vĆ©dett. KĆ©rjük, adja meg a jelszót:", + "cancelled": "Művelet megszakĆ­tva a PDF-nĆ©l: {0}", + "noPassword": "Nincs megadva jelszó a titkosĆ­tott PDF-hez: {0}", + "invalidPassword": "KĆ©rjük, próbĆ”lja Ćŗjra a helyes jelszóval.", + "invalidPasswordHeader": "Helytelen jelszó vagy nem tĆ”mogatott titkosĆ­tĆ”s a PDF-nĆ©l: {0}", + "unexpectedError": "Hiba tƶrtĆ©nt a fĆ”jl feldolgozĆ”sa sorĆ”n. KĆ©rjük, próbĆ”lja Ćŗjra.", + "serverError": "Szerveroldali hiba a visszafejtĆ©s sorĆ”n: {0}", + "success": "A fĆ”jl visszafejtĆ©se sikeres." + }, + "multiTool-advert": { + "message": "Ez a funkció elĆ©rhető a tƶbbfunkciós eszkƶz oldalon is. NĆ©zze meg a fejlett oldalankĆ©nti felületet Ć©s tovĆ”bbi funkciókat!" + }, + "pageRemover": { + "title": "OldaleltĆ”volĆ­tó", + "header": "PDF oldaleltĆ”volĆ­tó", + "pagesToDelete": "Tƶrlendő oldalak (adja meg az oldalszĆ”mok vesszővel elvĆ”lasztott listĆ”jĆ”t):", + "submit": "Oldalak tƶrlĆ©se", + "placeholder": "(pl. 1,2,6 vagy 1-10,15-30)" + }, + "imageToPDF": { + "title": "KĆ©p PDF-be", + "header": "KĆ©p PDF-be", + "submit": "KonvertĆ”lĆ”s", + "selectLabel": "KĆ©p illesztĆ©si beĆ”llĆ­tĆ”sok", + "fillPage": "Oldal kitƶltĆ©se", + "fitDocumentToImage": "Oldal igazĆ­tĆ”sa a kĆ©phez", + "maintainAspectRatio": "KĆ©parĆ”ny megtartĆ”sa", + "selectText": { + "2": "PDF automatikus forgatĆ”sa", + "3": "Tƶbb fĆ”jl kezelĆ©se (csak tƶbb kĆ©p esetĆ©n engedĆ©lyezett)", + "4": "EgyesĆ­tĆ©s egy PDF-be", + "5": "KonvertĆ”lĆ”s külƶn PDF-ekbe" + } + }, + "PDFToCSV": { + "title": "PDF konvertĆ”lĆ”sa CSV-be", + "header": "PDF konvertĆ”lĆ”sa CSV-be", + "prompt": "VĆ”lassza ki az oldalt a tĆ”blĆ”zat kinyerĆ©sĆ©hez", + "submit": "KinyerĆ©s" + }, + "split-by-size-or-count": { + "title": "PDF felosztĆ”sa mĆ©ret vagy darabszĆ”m szerint", + "header": "PDF felosztĆ”sa mĆ©ret vagy darabszĆ”m szerint", + "type": { + "label": "VĆ”lassza ki a felosztĆ”s tĆ­pusĆ”t", + "size": "MĆ©ret szerint", + "pageCount": "OldalszĆ”m szerint", + "docCount": "DokumentumszĆ”m szerint" + }, + "value": { + "label": "Adja meg az Ć©rtĆ©ket", + "placeholder": "Adja meg a mĆ©retet (pl. 2MB vagy 3KB) vagy a szĆ”mot (pl. 5)" + }, + "submit": "KüldĆ©s" + }, + "printFile": { + "title": "FĆ”jl nyomtatĆ”sa", + "header": "FĆ”jl nyomtatĆ”sa nyomtatóra", + "selectText": { + "1": "VĆ”lassza ki a nyomtatandó fĆ”jlt", + "2": "Adja meg a nyomtató nevĆ©t" + }, + "submit": "NyomtatĆ”s" + }, + "licenses": { + "nav": "Licencek", + "title": "Külső licencek", + "header": "Külső licencek", + "module": "Modul", + "version": "Verzió", + "license": "Licenc" + }, + "survey": { + "nav": "KĆ©rdőív", + "title": "Stirling-PDF kĆ©rdőív", + "description": "A Stirling PDF nem vĆ©gez kƶvetĆ©st, ezĆ©rt szeretnĆ©nk hallani felhasznĆ”lóinktól, hogy javĆ­thassunk a termĆ©ken!", + "changes": "A Stirling PDF vĆ”ltozott az utolsó felmĆ©rĆ©s óta! TovĆ”bbi informĆ”cióért tekintse meg blogbejegyzĆ©sünket:", + "changes2": "Ezekkel a vĆ”ltoztatĆ”sokkal üzleti tĆ”mogatĆ”st Ć©s finanszĆ­rozĆ”st kapunk", + "please": "KĆ©rjük, vegyen rĆ©szt felmĆ©rĆ©sünkben!", + "disabled": "(A kĆ©rdőív felugró ablaka a kƶvetkező frissĆ­tĆ©sekben letiltĆ”sra kerül, de tovĆ”bbra is elĆ©rhető lesz a lap aljĆ”n)", + "button": "KĆ©rdőív kitƶltĆ©se", + "dontShowAgain": "Ne jelenjen meg Ćŗjra", + "meeting": { + "1": "Ha a Stirling PDF-t munkahelyĆ©n hasznĆ”lja, szĆ­vesen beszĆ©lgetnĆ©nk Ɩnnel. 15 perces felhasznĆ”lói felfedező konzultĆ”cióért cserĆ©be technikai tĆ”mogatĆ”si ülĆ©seket kĆ­nĆ”lunk.", + "2": "Ez egy lehetősĆ©g arra, hogy:", + "3": "SegĆ­tsĆ©get kapjon a telepĆ­tĆ©shez, integrĆ”ciókhoz vagy hibaelhĆ”rĆ­tĆ”shoz", + "4": "Adjon kƶzvetlen visszajelzĆ©st a teljesĆ­tmĆ©nyről, hatĆ”resetekről Ć©s hiĆ”nyzó funkciókról", + "5": "SegĆ­tsen nekünk finomĆ­tani a Stirling PDF-et a valós vĆ”llalati hasznĆ”latra", + "6": "Amennyiben Ć©rdekli, kƶzvetlenül foglalhat időpontot csapatunkkal. (Csak angol nyelven)", + "7": "VĆ”rjuk, hogy megismerhessük az Ɩn felhasznĆ”lĆ”si eseteit Ć©s mĆ©g jobbĆ” tehessük a Stirling PDF-et!", + "notInterested": "Nem üzleti felhasznĆ”ló Ć©s/vagy nem Ć©rdekli a konzultĆ”ció", + "button": "KonzultĆ”ció foglalĆ”sa" + } + }, + "removeImage": { + "title": "KĆ©p eltĆ”volĆ­tĆ”sa", + "header": "KĆ©p eltĆ”volĆ­tĆ”sa", + "removeImage": "KĆ©p eltĆ”volĆ­tĆ”sa", + "submit": "KĆ©p eltĆ”volĆ­tĆ”sa" + }, + "splitByChapters": { + "title": "PDF felosztĆ”sa fejezetek szerint", + "header": "PDF felosztĆ”sa fejezetek szerint", + "bookmarkLevel": "Kƶnyvjelzőszint", + "includeMetadata": "Metaadatok megtartĆ”sa", + "allowDuplicates": "DuplikĆ”tumok engedĆ©lyezĆ©se", + "desc": { + "1": "Ez az eszkƶz fejezetstruktĆŗra alapjĆ”n osztja fel a PDF-et tƶbb fĆ”jlra.", + "2": "Kƶnyvjelzőszint: VĆ”lassza ki a felosztĆ”shoz hasznĆ”lt kƶnyvjelzőszintet (0 a legfelső szint, 1 a mĆ”sodik szint, stb.).", + "3": "Metaadatok megtartĆ”sa: Ha be van jelƶlve, az eredeti PDF metaadatai megmaradnak minden lĆ©trehozott PDF-ben.", + "4": "DuplikĆ”tumok engedĆ©lyezĆ©se: Ha be van jelƶlve, lehetővĆ© teszi tƶbb külƶnĆ”lló PDF lĆ©trehozĆ”sĆ”t ugyanazon az oldalon lĆ©vő tƶbb kƶnyvjelzőből." + }, + "submit": "PDF felosztĆ”sa" + }, + "fileChooser": { + "click": "Kattintson", + "or": "vagy", + "dragAndDrop": "HĆŗzza ide", + "dragAndDropPDF": "HĆŗzza ide a PDF fĆ”jlt", + "dragAndDropImage": "HĆŗzza ide a kĆ©pfĆ”jlt", + "hoveredDragAndDrop": "HĆŗzza ide a fĆ”jl(oka)t", + "extractPDF": "KinyerĆ©s..." + }, + "releases": { + "footer": "KiadĆ”si jegyzĆ©k", + "title": "KiadĆ”si jegyzetek", + "header": "KiadĆ”si jegyzetek", + "current": { + "version": "Jelenlegi kiadĆ”s" + }, + "note": "A kiadĆ”si jegyzetek csak angol nyelven Ć©rhetők el" + }, + "cookieBanner": { + "popUp": { + "title": "Hogy hasznĆ”ljuk a sütiket", + "description": { + "1": "Sütiket Ć©s egyĆ©b technológiĆ”kat hasznĆ”lunk, hogy a Stirling PDF jobban műkƶdjƶn az Ɩn szĆ”mĆ”ra, segĆ­tve minket abban, hogy javĆ­tsuk eszkƶzeinket Ć©s olyan funkciókat fejlesszünk, amelyeket szeretni fog", + "2": "Ha inkĆ”bb nem szeretnĆ©, a 'Nem, kƶszƶnƶm' gombra kattintva csak azok az alapvető sütik lesznek engedĆ©lyezve, amelyek a zavartalan műkƶdĆ©shez szüksĆ©gesek." + }, + "acceptAllBtn": "Elfogadom", + "acceptNecessaryBtn": "Nem, kƶszƶnƶm", + "showPreferencesBtn": "PreferenciĆ”k kezelĆ©se" + }, + "preferencesModal": { + "title": "BeleegyezĆ©si preferenciĆ”k kƶzpontja", + "acceptAllBtn": "Minden süti elfogadĆ”sa", + "acceptNecessaryBtn": "Csak a szüksĆ©ges sütik elfogadĆ”sa", + "savePreferencesBtn": "PreferenciĆ”k mentĆ©se", + "closeIconLabel": "BezĆ”rĆ”s", + "serviceCounterLabel": "SzolgĆ”ltatĆ”s|SzolgĆ”ltatĆ”sok", + "subtitle": "Süti hasznĆ”lat", + "description": { + "1": "A Stirling PDF sütiket Ć©s hasonló technológiĆ”kat hasznĆ”l az Ɩn Ć©lmĆ©nyĆ©nek javĆ­tĆ”sa, valamint eszkƶzeink hasznĆ”latĆ”nak megĆ©rtĆ©se Ć©rdekĆ©ben. Ez segĆ­t nekünk abban, hogy javĆ­tsuk a teljesĆ­tmĆ©nyt, fejlesszük az Ɩn szĆ”mĆ”ra fontos funkciókat, Ć©s folyamatos tĆ”mogatĆ”st nyĆŗjtsunk felhasznĆ”lóinknak.", + "2": "A Stirling PDF nem kĆ©pes-Ć©s soha nem is fog-nyomon kƶvetni vagy hozzĆ”fĆ©rni az Ɩn Ć”ltal hasznĆ”lt dokumentumok tartalmĆ”hoz.", + "3": "Az Ɩn bizalma Ć©s adatainak vĆ©delme a tevĆ©kenysĆ©günk kƶzĆ©ppontjĆ”ban Ć”ll." + }, + "necessary": { + "title": { + "1": "SzüksĆ©ges sütik", + "2": "Mindig aktĆ­v" + }, + "description": "Ezek a sütik elengedhetetlenek a weboldal megfelelő műkƶdĆ©sĆ©hez. Olyan alapvető funkciókat tesznek lehetővĆ©, mint az adatvĆ©delmi beĆ”llĆ­tĆ”sok megadĆ”sa, a bejelentkezĆ©s Ć©s az űrlapok kitƶltĆ©se-ezĆ©rt nem kapcsolhatók ki." + }, + "analytics": { + "title": "AdatelemzĆ©sek", + "description": "Ezek a sütik segĆ­tenek megĆ©rteni, hogyan hasznĆ”ljĆ”k eszkƶzeinket, Ć­gy a kƶzƶssĆ©günk Ć”ltal leginkĆ”bb Ć©rtĆ©kelt funkciókra ƶsszpontosĆ­thatunk. Nyugodt lehet-a Stirling PDF nem kĆ©pes Ć©s soha nem is fog nyomon kƶvetni az Ɩn Ć”ltal hasznĆ”lt dokumentumok tartalmĆ”t." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/id-ID/translation.json b/frontend/public/locales/id-ID/translation.json new file mode 100644 index 000000000..9690a6b2d --- /dev/null +++ b/frontend/public/locales/id-ID/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Ukuran Fonta", + "fontName": "Nama Fonta", + "title": "Tambahkan Nomor Halaman", + "header": "Tambahkan Nomor Halaman", + "selectText": { + "1": "Pilih berkas PDF:", + "2": "Ukuran Margin", + "3": "Posisi", + "4": "Nomor Awal", + "5": "Halaman ke Nomor", + "6": "Teks Khusus" + }, + "customTextDesc": "Teks Khusus", + "numberPagesDesc": "Halaman mana yang akan diberi nomor, default 'semua', juga menerima 1-5 atau 2,5,9, dll.", + "customNumberDesc": "Default untuk {n}, juga menerima 'Halaman {n} dari {total}', 'Teks-{n}', '{nama berkas}-{n}'", + "submit": "Tambahkan Nomor Halaman" + }, + "pdfPrompt": "Pilih PDF", + "multiPdfPrompt": "Pilih PDF (2+)", + "multiPdfDropPrompt": "Pilih (atau seret & letakkan)) semua PDF yang Anda butuhkan", + "imgPrompt": "Pilih Gambar", + "genericSubmit": "Kirim", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Peringatan: Proses ini dapat memakan waktu hingga satu menit, tergantung pada ukuran berkas", + "pageOrderPrompt": "Urutan Halaman Khusus (Masukkan daftar nomor halaman yang dipisahkan dengan koma atau Fungsi seperti 2n + 1) :", + "pageSelectionPrompt": "Pemilihan Halaman Kustom (Masukkan daftar nomor halaman dipisahkan dengan koma 1,5,6 atau Fungsi seperti 2n+1) :", + "goToPage": "Ke", + "true": "Benar", + "false": "Salah", + "unknown": "Tidak diketahui", + "save": "Simpan", + "saveToBrowser": "Simpan ke Peramban", + "close": "Tutup", + "filesSelected": "berkas dipilih", + "noFavourites": "Tidak ada favorit yang ditambahkan", + "downloadComplete": "Unduhan Lengkap", + "bored": "Bosan Menunggu?", + "alphabet": "Abjad", + "downloadPdf": "Unduh PDF", + "text": "Teks", + "font": "Jenis huruf", + "selectFillter": "-- Pilih --", + "pageNum": "Nomor Halaman", + "sizes": { + "small": "Kecil", + "medium": "Sedang", + "large": "Besar", + "x-large": "Sangat Besar" + }, + "error": { + "pdfPassword": "Dokumen PDF disandikan dan kata sandi tidak diberikan atau kata sandi salah", + "_value": "Kesalahan", + "sorry": "Maaf atas masalah ini!", + "needHelp": "Butuh bantuan / Menemukan masalah?", + "contactTip": "Jika Anda masih mengalami kesulitan, jangan ragu untuk menghubungi kami untuk bantuan. Anda dapat mengirim tiket di halaman GitHub kami atau menghubungi kami melalui Discord:", + "404": { + "head": "404 - Halaman Tidak Ditemukan | Ups, kami tersandung dalam kode!", + "1": "Kami tidak dapat menemukan halaman yang Anda cari.", + "2": "Terjadi kesalahan" + }, + "github": "Kirim tiket di GitHub", + "showStack": "Tampilkan Stack Trace", + "copyStack": "Salin Stack Trace", + "githubSubmit": "GitHub - Kirim tiket", + "discordSubmit": "Discord - Kirim pos dukungan" + }, + "delete": "Hapus", + "username": "Nama pengguna", + "password": "Kata sandi", + "welcome": "Selamat Datang", + "property": "Properti", + "black": "Hitam", + "white": "Putih", + "red": "Merah", + "green": "Hijau", + "blue": "Biru", + "custom": "Kustom...", + "WorkInProgess": "Pekerjaan sedang diproses, Mungkin tidak berfungsi atau terdapat kutu, Silakan laporkan masalah apa pun!", + "poweredBy": "Ditenagai oleh", + "yes": "Ya", + "no": "Tidak", + "changedCredsMessage": "Kredensial berubah!!", + "notAuthenticatedMessage": "Pengguna tidak ter-autentikasi.", + "userNotFoundMessage": "Pengguna tidak ditemukan.", + "incorrectPasswordMessage": "Kata sandi saat ini salah.", + "usernameExistsMessage": "Nama pengguna baru sudah ada.", + "invalidUsernameMessage": "Nama pengguna tidak valid, nama pengguna hanya boleh mengandung huruf, angka, dan karakter khusus berikut @._+- atau harus berupa alamat email yang valid.", + "invalidPasswordMessage": "Kata sandi tidak boleh kosong dan tidak boleh memiliki spasi di awal atau akhir.", + "confirmPasswordErrorMessage": "Kata Sandi Baru dan Konfirmasi Kata Sandi Baru harus sama.", + "deleteCurrentUserMessage": "Pengguna yang sedang masuk tidak dapat dihapus.", + "deleteUsernameExistsMessage": "Nama pengguna tidak ada dan tidak dapat dihapus.", + "downgradeCurrentUserMessage": "Tidak dapat menurunkan peran pengguna saat ini", + "disabledCurrentUserMessage": "Pengguna saat ini tidak dapat dinonaktifkan", + "downgradeCurrentUserLongMessage": "Tidak dapat menurunkan peran pengguna saat ini. Oleh karena itu, pengguna saat ini tidak akan ditampilkan.", + "userAlreadyExistsOAuthMessage": "Pengguna sudah ada sebagai pengguna OAuth2.", + "userAlreadyExistsWebMessage": "Pengguna sudah ada sebagai pengguna web.", + "oops": "Ups!", + "help": "Bantuan", + "goHomepage": "Kembali ke Beranda", + "joinDiscord": "Bergabung dengan server Discord kami", + "seeDockerHub": "Lihat Docker Hub", + "visitGithub": "Kunjungi Repositori Github", + "donate": "Donasi", + "color": "Warna", + "sponsor": "Pembantu", + "info": "Informasi", + "pro": "Pro", + "page": "Halaman", + "pages": "Halaman-halaman", + "loading": "Mengambil data...", + "addToDoc": "Tambahkan ke Dokumen", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Kebijakan Privasi", + "terms": "Syarat dan Ketentuan", + "accessibility": "Aksesibilitas", + "cookie": "Kebijakan Kuki", + "impressum": "Impresum", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Menu Pipeline (Beta)", + "uploadButton": "Unggah Kustom", + "configureButton": "Konfigurasi", + "defaultOption": "Kustom", + "submitButton": "Kirim", + "help": "Bantuan Pipeline", + "scanHelp": "Bantuan Pemindaian Folder", + "deletePrompt": "Apakah Anda yakin ingin menghapus pipeline", + "tags": "mengotomatiskan, mengurutkan, menulis, proses batch", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Konfigurasi Pipeline", + "pipelineNameLabel": "Nama Pipeline", + "saveSettings": "Simpan Pengaturan Operasi", + "pipelineNamePrompt": "Masukkan nama pipeline di sini", + "selectOperation": "Pilih Operasi", + "addOperationButton": "Tambah operasi", + "pipelineHeader": "Pipeline:", + "saveButton": "Unduh", + "validateButton": "Validasi" + }, + "enterpriseEdition": { + "button": "Upgrade ke Pro", + "warning": "Fitur ini hanya tersedia untuk pengguna Pro.", + "yamlAdvert": "Stirling PDF Pro mendukung berkas konfigurasi YAML dan fitur SSO lainnya.", + "ssoAdvert": "Mencari lebih banyak fitur manajemen pengguna? Lihat Stirling PDF Pro" + }, + "analytics": { + "title": "Apakah Anda ingin membuat Stirling PDF lebih baik?", + "paragraph1": "Stirling PDF memiliki analitik yang dapat diaktifkan untuk membantu kami meningkatkan produk. Kami tidak melacak informasi pribadi atau konten berkas.", + "paragraph2": "Silakan pertimbangkan untuk mengaktifkan analitik agar Stirling PDF dapat berkembang dan untuk memungkinkan kami memahami pengguna kami dengan lebih baik.", + "enable": "Aktifkan analitik", + "disable": "Nonaktifkan analitik", + "settings": "Anda dapat mengubah pengaturan untuk analitik di berkas config/settings.yml" + }, + "navbar": { + "favorite": "Favorit", + "recent": "New and recently updated", + "darkmode": "Mode Gelap", + "language": "Bahasa", + "settings": "Pengaturan", + "allTools": "Alat", + "multiTool": "Alat Multi", + "search": "Search", + "sections": { + "organize": "Atur", + "convertTo": "Konversi ke PDF", + "convertFrom": "Konversi dari PDF", + "security": "Tanda Tangan & Keamanan", + "advance": "Langkah Lanjut", + "edit": "Melihat & Mengedit", + "popular": "Populer" + } + }, + "settings": { + "title": "Pengaturan", + "update": "Pembaruan tersedia", + "updateAvailable": "{0} adalah versi yang terpasang saat ini. Versi baru ({1}) tersedia.", + "appVersion": "Versi Aplikasi:", + "downloadOption": { + "title": "Pilih opsi unduhan (Untuk unduhan berkas tunggal non zip):", + "1": "Buka di jendela yang sama", + "2": "Buka di jendela baru", + "3": "Unduh berkas" + }, + "zipThreshold": "Berkas zip ketika jumlah berkas yang diunduh melebihi", + "signOut": "Keluar", + "accountSettings": "Pengaturan Akun", + "bored": { + "help": "Mengaktifkan permainan telur paskah" + }, + "cacheInputs": { + "name": "Simpan input formulir", + "help": "Aktifkan untuk menyimpan input yang pernah digunakan untuk menjalankan di masa depan" + } + }, + "changeCreds": { + "title": "Ubah Kredensial", + "header": "Perbarui Detail Akun Anda", + "changePassword": "Anda menggunakan kredensial login default. Silakan masukkan kata sandi baru", + "newUsername": "Nama Pengguna Baru", + "oldPassword": "Kata Sandi Saat Ini", + "newPassword": "Kata Sandi Baru", + "confirmNewPassword": "Konfirmasi Kata Sandi Baru", + "submit": "Kirim Perubahan" + }, + "account": { + "title": "Pengaturan Akun", + "accountSettings": "Pengaturan Akun", + "adminSettings": "Pengaturan Admin - Melihat dan Menambahkan Pengguna", + "userControlSettings": "Pengaturan Kontrol Pengguna", + "changeUsername": "Ubah Nama Pengguna", + "newUsername": "Nama pengguna baru", + "password": "Konfirmasi Kata sandi", + "oldPassword": "Kata sandi lama", + "newPassword": "Kata Sandi Baru", + "changePassword": "Ubah Kata Sandi", + "confirmNewPassword": "Konfirmasi Kata Sandi Baru", + "signOut": "Keluar", + "yourApiKey": "API Key Anda", + "syncTitle": "Menyinkronkan pengaturan browser dengan Akun", + "settingsCompare": "Perbandingan Pengaturan:", + "property": "Properti", + "webBrowserSettings": "Pengaturan Peramban Web", + "syncToBrowser": "Sinkronisasi Akun -> Browser", + "syncToAccount": "Sinkronisasi Akun <- Browser" + }, + "adminUserSettings": { + "title": "Pengaturan Kontrol Pengguna", + "header": "Pengaturan Kontrol Admin", + "admin": "Administrator", + "user": "Pengguna", + "addUser": "Tambahkan Pengguna Baru", + "deleteUser": "Hapus Pengguna", + "confirmDeleteUser": "Haruskah pengguna dihapus?", + "confirmChangeUserStatus": "Haruskah pengguna dinonaktifkan/diaktifkan?", + "usernameInfo": "Nama pengguna hanya boleh mengandung huruf, angka, dan karakter khusus berikut @._+- atau harus berupa alamat email yang valid.", + "roles": "Peran", + "role": "Peran", + "actions": "Tindakan", + "apiUser": "Pengguna API Terbatas", + "extraApiUser": "Pengguna API Terbatas Tambahan", + "webOnlyUser": "Pengguna Khusus Web", + "demoUser": "Pengguna Demo (Tanpa pengaturan kustom)", + "internalApiUser": "Pengguna API Internal", + "forceChange": "Memaksa pengguna untuk mengubah nama pengguna/kata sandi saat masuk", + "submit": "Simpan Pengguna", + "changeUserRole": "Ubah Peran Pengguna", + "authenticated": "Terautentikasi", + "editOwnProfil": "Edit profil sendiri", + "enabledUser": "Pengguna diaktifkan", + "disabledUser": "Pengguna dinonaktifkan", + "activeUsers": "Pengguna Aktif:", + "disabledUsers": "Pengguna Dinonaktifkan:", + "totalUsers": "Total Pengguna:", + "lastRequest": "Permintaan Terakhir", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Impor/Ekspor Database", + "header": "Impor/Ekspor Database", + "fileName": "Nama Berkas", + "creationDate": "Tanggal Pembuatan", + "fileSize": "Ukuran Berkas", + "deleteBackupFile": "Hapus Berkas Cadangan", + "importBackupFile": "Impor Berkas Cadangan", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Unduh Berkas Cadangan", + "info_1": "Ketika mengimpor data, sangat penting untuk memastikan struktur yang benar. Jika Anda tidak yakin dengan apa yang Anda lakukan, cari nasihat dan dukungan dari seorang profesional. Kesalahan dalam struktur dapat menyebabkan malfungsi aplikasi, bahkan hingga tidak dapat menjalankan aplikasi sama sekali.", + "info_2": "Nama berkas tidak menjadi masalah saat mengunggah. Nama berkas akan diubah setelahnya mengikuti format backup_user_yyyyMMddHHmm.sql, memastikan konsistensi dalam penamaan.", + "submit": "Impor Cadangan", + "importIntoDatabaseSuccessed": "Impor ke database berhasil", + "backupCreated": "Database backup successful", + "fileNotFound": "Berkas tidak Ditemukan", + "fileNullOrEmpty": "Berkas tidak boleh null atau kosong", + "failedImportFile": "Impor Berkas Gagal", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "Sesi Anda telah kedaluwarsa. Silakan muat ulang halaman dan coba lagi.", + "refreshPage": "Refresh Page" + }, + "home": { + "desc": "Semua kebutuhan PDF Anda, langsung dari komputer lokal Anda.", + "searchBar": "Mencari fitur...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Melihat, membuat anotasi, menambahkan teks atau gambar" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "Alat Multi PDF", + "desc": "Menggabungkan, Memutar, Mengatur Ulang, dan Menghapus halaman" + }, + "merge": { + "title": "Menggabungkan", + "desc": "Gabungkan beberapa PDF dengan mudah menjadi satu." + }, + "split": { + "title": "Membagi", + "desc": "Membagi PDF menjadi beberapa dokumen" + }, + "rotate": { + "title": "Putar", + "desc": "Memutar PDF Anda dengan mudah." + }, + "imageToPdf": { + "title": "Gambar ke PDF", + "desc": "Mengonversi gambar (PNG, JPEG, GIF) ke PDF." + }, + "pdfToImage": { + "title": "PDF ke Gambar", + "desc": "Mengonversi PDF ke gambar. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Mengatur", + "desc": "Menghapus/Mengatur ulang halaman dalam urutan apa pun" + }, + "addImage": { + "title": "Tambahkan gambar", + "desc": "Menambahkan gambar ke lokasi yang ditentukan pada PDF" + }, + "watermark": { + "title": "Tambahkan watermark", + "desc": "Menambahkan watermark khusus ke dokumen PDF Anda." + }, + "permissions": { + "title": "Izin Perubahan", + "desc": "Mengubah izin dokumen PDF Anda" + }, + "removePages": { + "title": "Menghapus", + "desc": "Menghapus halaman yang tidak diinginkan dari dokumen PDF Anda." + }, + "addPassword": { + "title": "Tambahkan Kata Sandi", + "desc": "Enkripsi dokumen PDF Anda dengan kata sandi." + }, + "removePassword": { + "title": "Hapus Kata Sandi", + "desc": "Menghapus perlindungan kata sandi dari dokumen PDF Anda." + }, + "compressPdfs": { + "title": "Kompres", + "desc": "Kompres PDF untuk mengurangi ukuran berkas." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Ubah Metadata", + "desc": "Mengubah/Menghapus/Menambahkan metadata dari dokumen PDF" + }, + "fileToPDF": { + "title": "Mengonversi berkas ke PDF", + "desc": "Mengonversi hampir semua berkas ke PDF (DOCX, PNG, XLS, PPT, TXT dan lain-lain)" + }, + "ocr": { + "title": "Pemindaian/Pembersihan OCR", + "desc": "Memindai dan mendeteksi teks dari gambar di dalam PDF dan menambahkannya kembali sebagai teks." + }, + "extractImages": { + "title": "Ekstrak Gambar", + "desc": "Mengekstrak semua gambar dari PDF dan menyimpannya ke zip" + }, + "pdfToPDFA": { + "title": "PDF ke PDF/A", + "desc": "Konversi PDF ke PDF/A untuk penyimpanan jangka panjang" + }, + "PDFToWord": { + "title": "PDF ke Word", + "desc": "Mengonversi format PDF ke Word (DOC, DOCX, dan ODT)" + }, + "PDFToPresentation": { + "title": "PDF ke Presentasi", + "desc": "Mengonversi PDF ke format Presentasi (PPT, PPTX, dan ODP)" + }, + "PDFToText": { + "title": "PDF ke RTF (Teks)", + "desc": "Konversi PDF ke format Teks atau RTF" + }, + "PDFToHTML": { + "title": "PDF ke HTML", + "desc": "Mengonversi PDF ke format HTML" + }, + "PDFToXML": { + "title": "PDF ke XML", + "desc": "Mengonversi PDF ke format XML" + }, + "ScannerImageSplit": { + "title": "Mendeteksi/Memisahkan foto yang dipindai", + "desc": "Memisahkan beberapa foto dari dalam sebuah foto/PDF" + }, + "sign": { + "title": "Tanda Tangan", + "desc": "Menambahkan tanda tangan ke PDF dengan gambar, teks, atau gambar" + }, + "flatten": { + "title": "Meratakan", + "desc": "Menghapus semua elemen dan formulir interaktif dari PDF" + }, + "repair": { + "title": "Perbaikan", + "desc": "Melakukan perbaikan PDF yang rusak/rusak" + }, + "removeBlanks": { + "title": "Menghapus halaman kosong", + "desc": "Mendeteksi dan menghapus halaman kosong dari dokumen" + }, + "removeAnnotations": { + "title": "Menghapus Anotasi", + "desc": "Menghapus semua komentar/anotasi dari PDF" + }, + "compare": { + "title": "Bandingkan", + "desc": "Membandingkan dan menunjukkan perbedaan antara 2 Dokumen PDF" + }, + "certSign": { + "title": "Tanda tangani dengan Sertifikat", + "desc": "Menandatangani PDF dengan Certificate/Key (PEM/P12)" + }, + "removeCertSign": { + "title": "Hapus Tanda Tangan Sertifikat", + "desc": "Hapus tanda tangan sertifikat dari PDF" + }, + "pageLayout": { + "title": "Tata Letak Multi-Halaman", + "desc": "Menggabungkan beberapa halaman dokumen PDF menjadi satu halaman" + }, + "scalePages": { + "title": "Menyesuaikan ukuran/skala halaman", + "desc": "Mengubah ukuran/skala halaman dan/atau isinya." + }, + "pipeline": { + "title": "Pipeline", + "desc": "Menjalankan beberapa tindakan pada PDF dengan mendefinisikan skrip pipeline" + }, + "add-page-numbers": { + "title": "Tambahkan Nomor Halaman", + "desc": "Menambahkan nomor Halaman di seluruh dokumen di lokasi yang ditetapkan" + }, + "auto-rename": { + "title": "Ubah Nama Berkas PDF Secara Otomatis", + "desc": "Mengganti nama berkas PDF secara otomatis berdasarkan tajuk yang terdeteksi" + }, + "adjust-contrast": { + "title": "Menyesuaikan Warna/Kontras", + "desc": "Sesuaikan Kontras, Saturasi, dan Kecerahan PDF" + }, + "crop": { + "title": "Pangkas PDF", + "desc": "Pangkas PDF untuk memperkecil ukurannya (mempertahankan teks!)" + }, + "autoSplitPDF": { + "title": "Membagi Halaman Secara Otomatis", + "desc": "Membagi PDF yang dipindai secara otomatis dengan Kode QR pembagi halaman yang dipindai secara fisik" + }, + "sanitizePdf": { + "title": "Sanitasi", + "desc": "Menghapus skrip dan elemen lain dari file PDF" + }, + "URLToPDF": { + "title": "URL/Situs Web ke PDF", + "desc": "Mengonversi URL http apa pun ke PDF" + }, + "HTMLToPDF": { + "title": "HTML ke PDF", + "desc": "Mengonversi berkas HTML atau zip ke PDF" + }, + "MarkdownToPDF": { + "title": "Penurunan harga ke PDF", + "desc": "Mengonversi berkas Markdown apa pun ke PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "Dapatkan Semua Info tentang PDF", + "desc": "Mengambil setiap dan semua informasi yang mungkin ada pada PDF" + }, + "extractPage": { + "title": "Ekstrak halaman", + "desc": "Mengekstrak halaman tertentu dari PDF" + }, + "PdfToSinglePage": { + "title": "PDF ke Satu Halaman Besar", + "desc": "Menggabungkan semua halaman PDF menjadi satu halaman besar" + }, + "showJS": { + "title": "Tampilkan Javascript", + "desc": "Mencari dan menampilkan JS apa pun yang disuntikkan ke dalam PDF" + }, + "autoRedact": { + "title": "Redaksional Otomatis", + "desc": "Menyunting Otomatis (Menghitamkan) teks dalam PDF berdasarkan teks masukan" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF ke CSV", + "desc": "Mengekstrak Tabel dari PDF yang mengonversinya menjadi CSV" + }, + "autoSizeSplitPDF": { + "title": "Pemisahan Otomatis berdasarkan Ukuran/Hitungan", + "desc": "Membagi satu PDF menjadi beberapa dokumen berdasarkan ukuran, jumlah halaman, atau jumlah dokumen" + }, + "overlay-pdfs": { + "title": "Tumpuk PDF", + "desc": "Menumpuk PDF di atas PDF lain" + }, + "split-by-sections": { + "title": "Membagi PDF berdasarkan Bagian", + "desc": "Membagi setiap halaman PDF menjadi beberapa bagian horizontal dan vertikal yang lebih kecil" + }, + "AddStampRequest": { + "title": "Tambahkan Tanda Tangan ke PDF", + "desc": "Tambahkan teks atau gambar tanda tangan di lokasi yang ditentukan" + }, + "removeImagePdf": { + "title": "Hapus Gambar", + "desc": "Hapus gambar dari PDF untuk mengurangi ukuran file" + }, + "splitPdfByChapters": { + "title": "Pisahkan PDF berdasarkan Bab", + "desc": "Memisahkan PDF menjadi beberapa file berdasarkan struktur babnya." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "replaceColorPdf": { + "title": "Ganti dan Inversi Warna", + "desc": "Ganti warna untuk teks dan latar belakang dalam PDF dan inversi seluruh warna PDF untuk mengurangi ukuran file" + } + }, + "viewPdf": { + "tags": "melihat,membaca,membuat anotasi,teks,gambar", + "title": "View/Edit PDF", + "header": "Lihat PDF" + }, + "multiTool": { + "tags": "Alat multi,Operasi multi,UI,klik seret,front end,sisi klien,interaktif,sulit diatur,pindah", + "title": "Alat Multi PDF", + "header": "Alat Multi PDF", + "uploadPrompts": "Nama Berkas", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "selectPages": "Page Select", + "selectedPages": "Selected Pages", + "page": "Page", + "deleteSelected": "Delete Selected", + "downloadAll": "Export", + "downloadSelected": "Export Selected", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "Page(s) Selected", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "menggabungkan,Pengoperasian halaman,Back end,sisi server", + "title": "Gabungkan", + "header": "Gabungkan beberapa PDFs (2+)", + "sortByName": "Sortir berdasarkan nama", + "sortByDate": "Sortir berdasrkan tanggal", + "removeCertSign": "Hapus tanda tangan digital dalam file yang dicampur?", + "submit": "Gabungkan" + }, + "split": { + "tags": "Pengoperasian halaman,membagi,Multi Halaman,memotong,sisi server", + "title": "Membagi PDF", + "header": "Membagi PDF", + "desc": { + "1": "Angka yang Anda pilih adalah nomor halaman yang ingin Anda pisahkan", + "2": "Dengan demikian, memilih 1,3,7-9 akan membagi dokumen 10 halaman menjadi 6 PDF terpisah:", + "3": "Dokumen #1: Halaman 1", + "4": "Dokumen #2: Halaman 2 dan 3", + "5": "Dokumen #3: Halaman 4, 5, 6 dan 7", + "6": "Dokumen #4: Halaman 8", + "7": "Dokumen #5: Halaman 9", + "8": "Dokumen #6: Halaman 10" + }, + "splitPages": "Masukkan halaman yang akan dipisah:", + "submit": "Pisahkan" + }, + "rotate": { + "tags": "sisi server", + "title": "Rotasi PDF", + "header": "Rotasi PDF", + "selectAngle": "Pilih sudut rotasi (dalam kelipatan 90 derajat):", + "submit": "Rotasi" + }, + "imageToPdf": { + "tags": "konversi,img,jpg,gambar,foto" + }, + "pdfToImage": { + "tags": "konversi,img,jpg,gambar,foto", + "title": "PDF ke Gambar", + "header": "PDF ke Gambar", + "selectText": "Format Gambar", + "singleOrMultiple": "Tipe hasil halaman ke gambar", + "single": "Gambar Besar Tunggal Menggabungkan semua halaman", + "multi": "Beberapa Gambar, satu gambar per halaman", + "colorType": "Tipe warna", + "color": "Warna", + "grey": "Skala abu-abu", + "blackwhite": "Black and White (Bisa kehilangan data!)", + "submit": "Konversi", + "info": "Python tidak terinstal. Diperlukan untuk konversi WebP.", + "placeholder": "(misalnya 1,2,8 atau 4,7,12-16 atau 2n-1)" + }, + "pdfOrganiser": { + "tags": "dupleks,genap,ganjil,sortir,pindah", + "title": "Pengaturan Halaman", + "header": "Pengaturan Halaman PDF", + "submit": "Susun ulang halaman", + "mode": { + "_value": "Mode", + "1": "Urutan Halaman Kustom", + "2": "Urutan Terbalik", + "3": "Sortir Duplex", + "4": "Sortir Buku", + "5": "Sortir Buku Jahitan Samping", + "6": "Pemisahan Genap-Ganjil", + "7": "Hapus Pertama", + "8": "Hapus Terakhir", + "9": "Hapus Pertama dan Terakhir", + "10": "Penggabungan Genap-Ganjil", + "11": "Duplicate all pages" + }, + "placeholder": "(misalnya 1,3,2 atau 4-8,2,10-12 atau 2n-1)" + }, + "addImage": { + "tags": "img,jpg,gambar,foto", + "title": "Tambahkan Gambar", + "header": "Tambahkan Gambar ke PDF", + "everyPage": "Setiap Halaman?", + "upload": "Tambahkan Gambar", + "submit": "Tambahkan Gambar" + }, + "watermark": { + "tags": "Teks,berulang,label,sendiri,hak cipta,watermark,img,jpg,picture,photo", + "title": "Tambahkan Watermark", + "header": "Tambahkan Watermark", + "customColor": "Warna Teks Kustom", + "selectText": { + "1": "Pilih PDF untuk menambahkan watermark:", + "2": "Text Watermark:", + "3": "Ukuran Huruf:", + "4": "Rotasi (0-360):", + "5": "Width Spacer (Spasi diantara setiap watermark horisontal):", + "6": "Height Spacer (Spasi diantara setiap watermark vertikal):", + "7": "Kejernihan (0% - 100%):", + "8": "Tipe Watermark:", + "9": "Gambar Watermark:", + "10": "Konversi PDF ke PDF-Image" + }, + "submit": "Tambahkan Watermark", + "type": { + "1": "Teks", + "2": "Gambar" + } + }, + "permissions": { + "tags": "baca,tulis,sunting,cetak", + "title": "Ganti Perizinan", + "header": "Ganti Perizinan", + "warning": "Peringatan untuk menyetel izin yang tidak dapat diubah, disarankan untuk menyetel izin dengan kata sandi melalui halaman tambah kata sandi", + "selectText": { + "1": "Pilih PDF untuk mengubah izin", + "2": "Perizinan untuk diubah", + "3": "Pencegahan untuk penyusunan dokumen", + "4": "Pencegahan untuk ekstraksi konten", + "5": "Pencegahan ekstraksi untuk aksesibilitas", + "6": "Pencegahan untuk mengisi formulir", + "7": "Pencegahan untuk pengubahan", + "8": "Pencegahan untuk perubahan anotasi", + "9": "Pencegahan untuk mencetak", + "10": "Pencegahan untuk mencetak format yang berbeda" + }, + "submit": "Ganti" + }, + "removePages": { + "tags": "Menghapus halaman,menghapus halaman" + }, + "addPassword": { + "tags": "aman,Keamanan", + "title": "Tambahkan kata sandi", + "header": "Tambahkan kata sandi (Enkrip)", + "selectText": { + "1": "Pilih PDF untuk enkripsi", + "2": "Kata sandi Pengguna", + "3": "Panjang kunci enkripsi", + "4": "Nilai yang lebih tinggi lebih kuat, tetapi nilai yang lebih rendah memiliki kompatibilitas yang lebih baik.", + "5": "Perizinan untuk diubah (Disarankan untuk digunakan bersama dengan kata sandi Pemilik)", + "6": "Pencegahan untuk penyusunan dokumen", + "7": "Pencegahan untuk ekstraksi konten", + "8": "Pencegahan ekstraksi untuk aksesibilitas", + "9": "Pencegahan untuk mengisi formulir", + "10": "Pencegahan untuk pengubahan", + "11": "Pencegahan untuk perubahan anotasi", + "12": "Pencegahan untuk mencetak", + "13": "Pencegahan untuk mencetak format yang berbeda", + "14": "Kata sandi Pemilik", + "15": "Membatasi apa yang dapat dilakukan dengan dokumen setelah dibuka (Tidak didukung oleh semua pembaca)", + "16": "Membatasi pembukaan dokumen itu sendiri" + }, + "submit": "Enkripsi" + }, + "removePassword": { + "tags": "aman,Dekripsi,keamanan,buka kata sandi,hapus kata sandi", + "title": "Hapus kata sandi", + "header": "Hapus kata sandi (Dekrip)", + "selectText": { + "1": "Pilih PDF yang akan di Dekrip", + "2": "Kata Sandi" + }, + "submit": "Hapus" + }, + "compressPdfs": { + "tags": "remas, kecil, mini" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Judul,penulis,tanggal,pembuatan,waktu,penerbit,produser,statistik", + "title": "Judul:", + "header": "Ganti Metadata", + "selectText": { + "1": "Silakan edit variabel yang ingin Anda ubah", + "2": "Hapus semua metadata", + "3": "Tampilkan Metadata Khusus:", + "4": "Metadata Lain-lain:", + "5": "Tambahkan Metadata Khusus" + }, + "author": "Penulis:", + "creationDate": "Tanggal Dibuat (yyyy/MM/dd HH:mm:ss):", + "creator": "Pencipta:", + "keywords": "Kata kunci:", + "modDate": "Tangal Diperbarui (yyyy/MM/dd HH:mm:ss):", + "producer": "Produser:", + "subject": "Subjek:", + "trapped": "Terperangkap:", + "submit": "Ganti" + }, + "fileToPDF": { + "tags": "transformasi,format,dokumen,gambar,slide,text,konversi,office,docs,word,excel,powerpoint", + "title": "Berkas ke PDF", + "header": "Mengonversi berkas apa pun ke PDF", + "credit": "Layanan ini menggunakan LibreOffice dan Unoconv untuk konversi berkas.", + "supportedFileTypesInfo": "Jenis File Dukungan", + "supportedFileTypes": "Jenis berkas yang didukung harus mencakup yang di bawah ini, namun untuk daftar lengkap format yang didukung, silakan lihat dokumentasi LibreOffice", + "submit": "Konversi ke PDF" + }, + "ocr": { + "tags": "rekognisi,teks,gambar,pindai,baca,identifikasi,deteksi,dapat diedit", + "title": "OCR / Pembersihan Pindaian", + "header": "Pemindaian Pembersihan / OCR (Pengenalan Karakter Optik)", + "selectText": { + "1": "Pilih bahasa yang akan dideteksi di dalam PDF (Bahasa yang terdaftar adalah bahasa yang saat ini terdeteksi):", + "2": "Menghasilkan berkas teks yang berisi teks OCR di samping PDF yang di-OCR", + "3": "Halaman yang benar dipindai pada sudut miring dengan memutarnya kembali ke tempatnya", + "4": "Halaman yang bersih sehingga kecil kemungkinan OCR akan menemukan teks dalam kebisingan latar belakang. (Tidak ada perubahan output)", + "5": "Bersihkan halaman sehingga kecil kemungkinan OCR akan menemukan teks dalam kebisingan latar belakang, mempertahankan pembersihan pada keluaran.", + "6": "Mengabaikan halaman yang memiliki teks interaktif, hanya halaman OCR yang berupa gambar", + "7": "Memaksa OCR, akan meng-OCR setiap halaman dengan menghapus semua elemen teks asli", + "8": "Normal (Akan terjadi kesalahan jika PDF berisi teks)", + "9": "Pengaturan Tambahan", + "10": "Mode OCR", + "11": "Hapus gambar setelah OCR (Menghapus Semua gambar, hanya berguna jika merupakan bagian dari langkah konversi)", + "12": "Jenis Render (Lanjutan)" + }, + "help": "Silakan baca dokumentasi ini tentang cara menggunakan ini untuk bahasa lain dan/atau penggunaan yang tidak ada di docker", + "credit": "Layanan ini menggunakan qpdf dan Tesseract untuk OCR.", + "submit": "Memproses PDF dengan OCR" + }, + "extractImages": { + "tags": "gambar, foto, simpan, arsip, zip, tangkap, ambil", + "title": "Ekstrak Gambar", + "header": "Mengekstrak Gambar", + "selectText": "Pilih format gambar yang akan dikonversi", + "allowDuplicates": "Simpan Gambar Duplikat", + "submit": "Ekstrak" + }, + "pdfToPDFA": { + "tags": "arsip, jangka panjang, standar, konversi, penyimpanan, pelestarian", + "title": "PDF Ke PDF/A", + "header": "PDF ke PDF/A", + "credit": "Layanan ini menggunakan libreoffice untuk konversi PDF/A.", + "submit": "Konversi", + "tip": "Saat ini tidak dapat digunakan untuk beberapa input sekaligus", + "outputFormat": "Format keluaran", + "pdfWithDigitalSignature": "PDF ini mengandung tanda tangan digital. Ini akan dihapus pada langkah berikutnya." + }, + "PDFToWord": { + "tags": "doc, docx, odt, kata, transformasi, format, konversi, kantor, microsoft, docfile", + "title": "PDF ke Word", + "header": "PDF ke Word", + "selectText": { + "1": "Hasil format berkas" + }, + "credit": "Layanan ini menggunakan LibreOffice untuk konversi berkas.", + "submit": "Konversi" + }, + "PDFToPresentation": { + "tags": "slide, pertunjukan, kantor, microsoft", + "title": "PDF Ke Presentation", + "header": "PDF ke Presentation", + "selectText": { + "1": "Hasil format berkas" + }, + "credit": "Layanan ini menggunakan LibreOffice untuk konversi berkas.", + "submit": "Konversi" + }, + "PDFToText": { + "tags": "format kaya, format teks kaya, format teks kaya", + "title": "PDF ke RTF (Text)", + "header": "PDF ke RTF (Text)", + "selectText": { + "1": "Hasil format berkas" + }, + "credit": "Layanan ini menggunakan LibreOffice untuk konversi berkas.", + "submit": "Konversi" + }, + "PDFToHTML": { + "tags": "konten web, ramah browser", + "title": "PDF ke HTML", + "header": "PDF ke HTML", + "credit": "Layanan ini menggunakan pdftohtml untuk konversi berkas.", + "submit": "Konversi" + }, + "PDFToXML": { + "tags": "ekstraksi data, konten terstruktur, interop, transformasi, konversi", + "title": "PDF ke XML", + "header": "PDF ke XML", + "credit": "Layanan ini menggunakan LibreOffice untuk konversi berkas.", + "submit": "Konversi" + }, + "ScannerImageSplit": { + "tags": "pisahkan, deteksi otomatis, pindai, multi-foto, atur", + "selectText": { + "1": "Ambang Batas Sudut:", + "2": "Menetapkan sudut absolut minimum yang diperlukan agar gambar dapat diputar (default: 10).", + "3": "Toleransi:", + "4": "Menentukan kisaran variasi warna di sekitar perkiraan warna latar belakang (default: 30).", + "5": "Area Minimum:", + "6": "Menetapkan ambang batas area minimum untuk foto (default: 10000).", + "7": "Area Kontur Minimum:", + "8": "Menetapkan ambang batas area kontur minimum untuk foto", + "9": "Ukuran Batas:", + "10": "Menetapkan ukuran batas yang ditambahkan dan dihapus untuk mencegah batas putih pada output (default: 1)." + }, + "info": "Python tidak terinstal. Ini diperlukan untuk menjalankan." + }, + "sign": { + "tags": "mengesahkan, inisial, tanda tangan yang digambar, tanda tangan teks, tanda tangan gambar", + "title": "Tanda", + "header": "Tandatangani PDF", + "upload": "Unggah Gambar", + "draw": "Gambar Tanda Tangan", + "text": "Masukan Teks", + "clear": "Hapus", + "add": "Tambah", + "saved": "Tanda Tangan Disimpan", + "save": "Simpan Tanda Tangan", + "personalSigs": "Tanda Tangan Pribadi", + "sharedSigs": "Tanda Tangan Berbagi", + "noSavedSigs": "Tidak ditemukan tanda tangan yang disimpan", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "statis, nonaktif, non-interaktif, ramping", + "title": "Ratakan", + "header": "Ratakan PDF", + "flattenOnlyForms": "Ratakan hanya formulir", + "submit": "Ratakan" + }, + "repair": { + "tags": "perbaiki, pulihkan, koreksi, pulihkan", + "title": "Perbaiki", + "header": "Perbaiki PDF", + "submit": "Perbaiki" + }, + "removeBlanks": { + "tags": "membersihkan, merampingkan, non-konten, mengatur", + "title": "Hapus yang Kosong", + "header": "Hapus Halaman Kosong", + "threshold": "Ambang Batas Keputihan Piksel:", + "thresholdDesc": "Ambang batas untuk menentukan seberapa putih piksel putih yang harus diklasifikasikan sebagai 'Putih'. 0=Hitam, 255 putih murni.", + "whitePercent": "Persen Putih (%):", + "whitePercentDesc": "Persentase halaman yang harus berupa piksel 'putih' yang akan dihapus", + "submit": "Hapus Kosong" + }, + "removeAnnotations": { + "tags": "komentar, sorot, catatan, markup, hapus", + "title": "Hapus Anotasi", + "header": "Hapus Anotasi", + "submit": "Hapus" + }, + "compare": { + "tags": "membedakan, kontras, perubahan, analisis", + "title": "Bandingkan", + "header": "Bandingkan PDF", + "highlightColor": { + "1": "Warna Sorotan 1:", + "2": "Warna Sorotan 2:" + }, + "document": { + "1": "Dokumen 1", + "2": "Dokumen 2" + }, + "submit": "Bandingkan", + "complex": { + "message": "Satu atau kedua dokumen yang disediakan adalah file besar, keakuratan perbandingan mungkin berkurang" + }, + "large": { + "file": { + "message": "Satu atau Kedua dokumen yang disediakan terlalu besar untuk diproses" + } + }, + "no": { + "text": { + "message": "Satu atau kedua PDF yang dipilih tidak memiliki konten teks. Pilih PDF dengan teks untuk perbandingan." + } + } + }, + "certSign": { + "tags": "mengotentikasi, PEM, P12, resmi, mengenkripsi", + "title": "Penandatanganan Sertifikat", + "header": "Menandatangani PDF dengan sertifikat Anda (Sedang dalam proses)", + "selectPDF": "Pilih Berkas PDF untuk Penandatanganan:", + "jksNote": "Catatan: Jika tipe sertifikat Anda tidak terdaftar di bawah, silakan konversi ke file Java Keystore (.jks) menggunakan alat baris perintah keytool. Kemudian, pilih opsi file .jks di bawah.", + "selectKey": "Pilih Berkas Kunci Pribadi Anda (format PKCS # 8, bisa .pem atau .der):", + "selectCert": "Pilih Berkas Sertifikat Anda (format X.509, bisa .pem atau .der):", + "selectP12": "Pilih Berkas Keystore PKCS #12 Anda (.p12 atau .pfx) (Opsional, Jika disediakan, berkas tersebut harus berisi kunci pribadi dan sertifikat Anda):", + "selectJKS": "Pilih Berkas Java Keystore File (.jks atau .keystore):", + "certType": "Jenis Sertifikat", + "password": "Masukkan Kata Sandi Kunci atau Kunci Pribadi Anda (Jika Ada):", + "showSig": "Tampilkan Tanda Tangan", + "reason": "Alasan", + "location": "Lokasi", + "name": "Nama", + "showLogo": "Tampilkan Logo", + "submit": "Tanda tangani PDF" + }, + "removeCertSign": { + "tags": "otentikasi, PEM, P12, resmi, dekripsi", + "title": "Hapus Tanda Tangan Sertifikat", + "header": "Hapus sertifikat digital dari PDF", + "selectPDF": "Pilih file PDF:", + "submit": "Hapus Tanda Tangan" + }, + "pageLayout": { + "tags": "menggabungkan, komposit, tampilan tunggal, mengatur", + "title": "Tata Letak Multi Halaman", + "header": "Tata Letak Multi Halaman", + "pagesPerSheet": "Halaman per lembar:", + "addBorder": "Menambahkan Batas", + "submit": "Kirim" + }, + "scalePages": { + "tags": "mengubah ukuran, memodifikasi, dimensi, mengadaptasi", + "title": "Sesuaikan skala halaman", + "header": "Sesuaikan skala halaman", + "pageSize": "Ukuran halaman dokumen.", + "keepPageSize": "Ukuran Asli", + "scaleFactor": "Tingkat zoom (potong) halaman.", + "submit": "Kirim" + }, + "add-page-numbers": { + "tags": "beri halaman, beri label, atur, indeks" + }, + "auto-rename": { + "tags": "deteksi otomatis, berbasis tajuk, atur, beri label ulang", + "title": "Ganti Nama Otomatis", + "header": "Ganti Nama PDF Otomatis", + "submit": "Ganti Nama Otomatis" + }, + "adjust-contrast": { + "tags": "koreksi warna, menyetel, memodifikasi, meningkatkan" + }, + "crop": { + "tags": "memangkas, mengecilkan, mengedit, membentuk", + "title": "Pangkas", + "header": "Pangkas PDF", + "submit": "Kirim" + }, + "autoSplitPDF": { + "tags": "Berbasis QR, pisahkan, pindai segmen, atur", + "title": "PDF Pisah Otomatis", + "header": "Pisahkan PDF secara otomatis", + "description": "Cetak, Sisipkan, Pindai, unggah, dan biarkan kami memisahkan dokumen Anda secara otomatis. Tidak perlu menyortir secara manual.", + "selectText": { + "1": "Cetak beberapa lembar pembatas dari bawah (Hitam putih tidak masalah).", + "2": "Pindai semua dokumen Anda sekaligus dengan memasukkan lembar pembatas di antaranya.", + "3": "Unggah satu berkas PDF besar yang dipindai dan biarkan Stirling PDF menangani sisanya.", + "4": "Halaman pembatas secara otomatis terdeteksi dan dihapus, menjamin dokumen akhir yang rapi." + }, + "formPrompt": "Kirimkan PDF yang berisi pembagi Halaman Stirling-PDF:", + "duplexMode": "Mode Dupleks (Pemindaian depan dan belakang)", + "dividerDownload2": "Unduh 'Pembagi Pembagi Otomatis (dengan instruksi).pdf'", + "submit": "Kirim" + }, + "sanitizePdf": { + "tags": "bersih, terlindungi, aman, menghilangkan ancaman" + }, + "URLToPDF": { + "tags": "tangkap web, simpan halaman, web-ke-dok, arsip", + "title": "URL ke PDF", + "header": "URL Ke PDF", + "submit": "Konversi", + "credit": "Menggunakan WeasyPrint" + }, + "HTMLToPDF": { + "tags": "markup, konten web, transformasi, konversi", + "title": "HTML Ke PDF", + "header": "HTML Ke PDF", + "help": "Menerima berkas HTML dan ZIP yang berisi html / css / gambar, dll yang diperlukan", + "submit": "Konversi", + "credit": "Menggunakan WeasyPrint", + "zoom": "Tingkat perbersan untuk menampilkan situs web.", + "pageWidth": "Lebar halaman dalam sentimeter. (Kosong untuk default)", + "pageHeight": "Tinggi halaman dalam sentimeter. (Kosong untuk default)", + "marginTop": "Margin atas halaman dalam milimeter. (Kosong untuk default)", + "marginBottom": "Margin bawah halaman dalam milimeter. (Kosong untuk default)", + "marginLeft": "Margin kiri halaman dalam milimeter. (Kosong untuk default)", + "marginRight": "Margin kanan halaman dalam milimeter. (Kosong untuk default)", + "printBackground": "Render latar belakang situs web.", + "defaultHeader": "Aktifkan Header Default (Nama dan nomor halaman)", + "cssMediaType": "Ubah jenis media CSS halaman.", + "none": "Tidak ada", + "print": "Cetak", + "screen": "Layar" + }, + "MarkdownToPDF": { + "tags": "markup, konten web, transformasi, konversi", + "title": "Markdown ke PDF", + "header": "Markdown Ke PDF", + "submit": "Konversi", + "help": "Pekerjaan sedang berlangsung", + "credit": "Menggunakan WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "informasi, data, statistik, statistik", + "title": "Dapatkan Info tentang PDF", + "header": "Dapatkan Info tentang PDF", + "submit": "Dapatkan Info", + "downloadJson": "Unduh JSON" + }, + "extractPage": { + "tags": "ekstrak" + }, + "PdfToSinglePage": { + "tags": "halaman tunggal" + }, + "showJS": { + "tags": "JS", + "title": "Tampilkan Javascript", + "header": "Tampilkan Javascript", + "downloadJS": "Unduh Javascript", + "submit": "Tampilkan" + }, + "autoRedact": { + "tags": "Hapus, Sembunyikan, padamkan, hitam, hitam, penanda, tersembunyi", + "title": "Redaksional Otomatis", + "header": "Redaksional Otomatis", + "colorLabel": "Warna", + "textsToRedactLabel": "Teks untuk Disunting (dipisahkan baris)", + "textsToRedactPlaceholder": "misalnya \\nRahasia \\nRahasia Tertinggi", + "useRegexLabel": "Gunakan Regex", + "wholeWordSearchLabel": "Pencarian Seluruh Kata", + "customPaddingLabel": "Padding Ekstra Kustom", + "convertPDFToImageLabel": "Konversi PDF ke PDF-Gambar (Digunakan untuk menghapus teks di belakang kotak)", + "submitButton": "Kirim" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV, Ekstraksi Tabel, ekstrak, konversi" + }, + "autoSizeSplitPDF": { + "tags": "pdf, membagi, dokumen, organisasi" + }, + "overlay-pdfs": { + "tags": "Overlays", + "header": "Hamparan berkas PDF", + "baseFile": { + "label": "Pilih basis berkas PDF" + }, + "overlayFiles": { + "label": "Pilih hamparan berkas PDF" + }, + "mode": { + "label": "Pilih Mode Hamparan", + "sequential": "Hamparan Sequential", + "interleaved": "Hamparan Interleaved", + "fixedRepeat": "Hamparan Fixed Repeat" + }, + "counts": { + "label": "Jumlah Overlay (Untuk hamparan fixed repeat)", + "placeholder": "Masukkan hitungan yang dipisahkan oleh koma (e.g., 2,3,1)" + }, + "position": { + "label": "Pilih posisi hamparan", + "foreground": "Latar depan", + "background": "Latar belakang" + }, + "submit": "Kirim" + }, + "split-by-sections": { + "tags": "Membagi Bagian, Membagi, Menyesuaikan", + "title": "Pisahkan PDF berdasarkan bagian", + "header": "Pisahkan PDF menjadi beberapa bagian", + "horizontal": { + "label": "Pembagian Horizontal", + "placeholder": "Input angka untuk pembagian horizontal" + }, + "vertical": { + "label": "Pembagian Vertikal", + "placeholder": "Input angka untuk pembagian vertikal" + }, + "submit": "Pisahkan PDF", + "merge": "Gabung Menjadi Berkas PDF Tunggal" + }, + "AddStampRequest": { + "tags": "Tanda tangan, tambahkan gambar, posisikan gambar di tengah, air tinta, PDF, embedding, customisasi", + "header": "Stampel PDF", + "title": "Stampel PDF", + "stampType": "Jenis Stampel", + "stampText": "Teks Stampel", + "stampImage": "Gambar Stampel", + "alphabet": "Alfabet", + "fontSize": "Ukuran Font/Gambar", + "rotation": "Rotasi", + "opacity": "Transparansi", + "position": "Posisi", + "overrideX": "Timpa Koordinat X", + "overrideY": "Timpa Koordinat Y", + "customMargin": "Margin Kustom", + "customColor": "Warna Teks Kustom", + "submit": "Kirim" + }, + "removeImagePdf": { + "tags": "Hapus Gambar,Operasi Halaman,Backend,server side" + }, + "splitPdfByChapters": { + "tags": "pemisahan,bab,bookmark,atur" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Ganti-Inversi-Warna", + "header": "Ganti-Inversi Warna PDF", + "selectText": { + "1": "Opsi Ganti atau Inversi warna", + "2": "Default(Warna kontras tinggi default)", + "3": "Kustom(Warna yang disesuaikan)", + "4": "Full-Inversi(Inversi semua warna)", + "5": "Opsi warna kontras tinggi", + "6": "teks putih di latar belakang hitam", + "7": "teks hitam di latar belakang putih", + "8": "teks kuning di latar belakang hitam", + "9": "teks hijau di latar belakang hitam", + "10": "Pilih warna teks", + "11": "Pilih warna latar belakang" + }, + "submit": "Ganti" + }, + "replaceColorPdf": { + "tags": "Ganti Warna,Operasi Halaman,Backend,server side" + }, + "login": { + "title": "Masuk", + "header": "Masuk", + "signin": "Masuk", + "rememberme": "Ingat saya", + "invalid": "Nama pengguna atau kata sandi tidak valid.", + "locked": "Akun Anda telah dikunci.", + "signinTitle": "Silakan masuk", + "ssoSignIn": "Masuk melalui Single Sign - on", + "oAuth2AutoCreateDisabled": "OAUTH2 Buat Otomatis Pengguna Dinonaktifkan", + "oAuth2AdminBlockedUser": "Registrasi atau login pengguna yang tidak terdaftar saat ini diblokir. Silakan hubungi administrator.", + "oauth2RequestNotFound": "Permintaan otorisasi tidak ditemukan", + "oauth2InvalidUserInfoResponse": "Respons Info Pengguna Tidak Valid", + "oauth2invalidRequest": "Permintaan Tidak Valid", + "oauth2AccessDenied": "Akses Ditolak", + "oauth2InvalidTokenResponse": "Respons Token Tidak Valid", + "oauth2InvalidIdToken": "Token ID Tidak Valid", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "Pengguna dinonaktifkan, login saat ini diblokir dengan nama pengguna ini. Silakan hubungi administrator.", + "alreadyLoggedIn": "Anda sudah login ke", + "alreadyLoggedIn2": "perangkat. Silakan keluar dari perangkat dan coba lagi.", + "toManySessions": "Anda memiliki terlalu banyak sesi aktif", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF Ke Halaman Tunggal", + "header": "PDF Ke Halaman Tunggal", + "submit": "Konversi ke Halaman Tunggal" + }, + "pageExtracter": { + "title": "Ekstrak Halaman", + "header": "Ekstrak Halaman", + "submit": "Ekstrak", + "placeholder": "(misalnya 1,2,8 atau 4,7,12-16 atau 2n-1)" + }, + "sanitizePDF": { + "title": "Bersihkan PDF", + "header": "Membersihkan berkas PDF", + "selectText": { + "1": "Hapus tindakan JavaScript", + "2": "Hapus berkas yang disematkan", + "3": "Remove XMP metadata", + "4": "Hapus tautan", + "5": "Hapus font", + "6": "Remove Document Info Metadata" + }, + "submit": "Membersihkan PDF" + }, + "adjustContrast": { + "title": "Sesuaikan Kontras", + "header": "Sesuaikan Kontras", + "contrast": "Kontras:", + "brightness": "Kecerahan:", + "saturation": "Saturasi:", + "download": "Unduh" + }, + "compress": { + "title": "Kompres", + "header": "Kompres PDF", + "credit": "Layanan ini menggunakan qpdf untuk Kompresi/Optimalisasi PDF.", + "grayscale": { + "label": "Terapkan Skala Abu-Abu untuk Kompresi" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Tingkat Optimalisasi:", + "4": "Mode Otomatis - Menyesuaikan kualitas secara otomatis untuk mendapatkan PDF dengan ukuran yang tepat", + "5": "Ukuran PDF yang diharapkan (mis. 25MB, 10,8MB, 25KB)" + }, + "submit": "Kompres" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "Penghapus Halaman", + "header": "Penghapus Halaman PDF", + "pagesToDelete": "Halaman yang akan dihapus (Masukkan daftar nomor halaman yang dipisahkan dengan koma) :", + "submit": "Hapus Halaman", + "placeholder": "(misalnya 1,2,6 atau 1-10,15-30)" + }, + "imageToPDF": { + "title": "Gambar ke PDF", + "header": "Gambar ke PDF", + "submit": "Konversi", + "selectLabel": "Opsi Kesesuaian Gambar", + "fillPage": "Isi Halaman", + "fitDocumentToImage": "Isi Dokumen dengan Gambar", + "maintainAspectRatio": "Pertahankan aspek rasio", + "selectText": { + "2": "Putar PDF secara otomatis", + "3": "Logika multi berkas (Hanya diaktifkan jika bekerja dengan banyak gambar)", + "4": "Gabungkan menjadi satu PDF", + "5": "Mengonversi ke PDF yang terpisah" + } + }, + "PDFToCSV": { + "title": "PDF ke CSV", + "header": "PDF ke CSV", + "prompt": "Pilih halaman untuk mengambil tabel", + "submit": "Ektraksi" + }, + "split-by-size-or-count": { + "title": "Pisahkan PDF berdasarkan ukuran atau jumlah", + "header": "Pisahkan PDF berdasarkan ukuran atau jumlah", + "type": { + "label": "Pilih Tipe Split", + "size": "Berdasarkan Ukuran", + "pageCount": "Berdasarkan Jumlah Halaman", + "docCount": "Berdasarkan Jumlah Dokumen" + }, + "value": { + "label": "Masukkan Jumlah", + "placeholder": "Masukkan ukuran (e.g., 2MB or 3KB) atau hitungan (e.g., 5)" + }, + "submit": "Kirim" + }, + "printFile": { + "title": "Cetak File", + "header": "Cetak File ke Printer", + "selectText": { + "1": "Pilih File untuk Dicetak", + "2": "Masukkan Nama Printer" + }, + "submit": "Cetak" + }, + "licenses": { + "nav": "Lisensi", + "title": "Lisensi Pihak Ketiga", + "header": "Lisensi Pihak Ketiga", + "module": "Modul", + "version": "Versi", + "license": "Lisensi" + }, + "survey": { + "nav": "Survei", + "title": "Survei Stirling-PDF", + "description": "Stirling-PDF tidak memiliki pelacakan, jadi kami ingin mendengar dari pengguna kami untuk meningkatkan Stirling-PDF!", + "changes": "Stirling-PDF telah berubah sejak survei terakhir! Untuk mengetahui lebih lanjut, silakan periksa posting blog kami di sini:", + "changes2": "Dengan perubahan ini, kami mendapatkan dukungan bisnis yang dibayar dan pendanaan", + "please": "Silakan pertimbangkan untuk mengikuti survei kami!", + "disabled": "(Popup survei akan dinonaktifkan dalam pembaruan berikutnya tetapi tersedia di bagian bawah halaman)", + "button": "Ikuti Survei", + "dontShowAgain": "Jangan tampilkan lagi", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Hapus gambar", + "header": "Hapus gambar", + "removeImage": "Hapus gambar", + "submit": "Hapus gambar" + }, + "splitByChapters": { + "title": "Pecah PDF berdasarkan Bab", + "header": "Pecah PDF berdasarkan Bab", + "bookmarkLevel": "Tingkatan Markah", + "includeMetadata": "Termasuk Metadata", + "allowDuplicates": "Izinkan Duplikat", + "desc": { + "1": "Alat ini membagi file PDF menjadi beberapa PDF berdasarkan struktur babnya.", + "2": "Tingkatan Markah: Pilih tingkatan markah yang digunakan untuk membagi (0 untuk tingkat atas, 1 untuk tingkat kedua, dll.).", + "3": "Termasuk Metadata: Jika dicentang, metadata asli PDF akan disertakan dalam setiap PDF yang dibagi.", + "4": "Izinkan Duplikat: Jika dicentang, mengizinkan beberapa markah pada halaman yang sama untuk membuat PDF terpisah." + }, + "submit": "Pecah PDF" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Releases", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Current Release" + }, + "note": "Release notes are only available in English" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/it-IT/translation.json b/frontend/public/locales/it-IT/translation.json new file mode 100644 index 000000000..c61e49e13 --- /dev/null +++ b/frontend/public/locales/it-IT/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Dimensione del font", + "fontName": "Nome del font", + "title": "Aggiungi numeri di pagina", + "header": "Aggiungi numeri di pagina", + "selectText": { + "1": "Seleziona il file PDF:", + "2": "Dimensione margine", + "3": "Posizione", + "4": "Numero di partenza", + "5": "Pagine da numerare", + "6": "Testo personalizzato" + }, + "customTextDesc": "Testo personalizzato", + "numberPagesDesc": "Quali pagine numerare, impostazione predefinita \"tutte\", accetta anche 1-5 o 2,5,9 ecc", + "customNumberDesc": "Il valore predefinito ĆØ {n}, accetta anche 'Pagina {n} di {total}', 'Testo-{n}', '{filename}-{n}", + "submit": "Aggiungi numeri di pagina" + }, + "pdfPrompt": "Scegli PDF", + "multiPdfPrompt": "Scegli 2 o più PDF", + "multiPdfDropPrompt": "Scegli (o trascina e rilascia) uno o più PDF", + "imgPrompt": "Scegli immagine/i", + "genericSubmit": "Invia", + "uploadLimit": "Dimensione massima del file:", + "uploadLimitExceededSingular": "ĆØ troppo grande. La dimensione massima consentita ĆØ", + "uploadLimitExceededPlural": "sono troppo grandi. La dimensione massima consentita ĆØ", + "processTimeWarning": "Nota: Questo processo potrebbe richiedere fino a un minuto in base alla dimensione dei file", + "pageOrderPrompt": "Ordine delle pagine (inserisci una lista di numeri separati da virgola):", + "pageSelectionPrompt": "Selezione pagina personalizzata (inserisci un elenco separato da virgole di numeri di pagina 1,5,6 o funzioni come 2n+1) :", + "goToPage": "Vai", + "true": "Vero", + "false": "Falso", + "unknown": "Sconosciuto", + "save": "Salva", + "saveToBrowser": "Salva nel browser", + "close": "Chiudi", + "filesSelected": "file selezionati", + "noFavourites": "Nessun preferito", + "downloadComplete": "Download completo", + "bored": "Stanco di aspettare?", + "alphabet": "Alfabeto", + "downloadPdf": "Scarica PDF", + "text": "Testo", + "font": "Font", + "selectFillter": "-- Seleziona --", + "pageNum": "Numero pagina", + "sizes": { + "small": "Piccolo", + "medium": "Medio", + "large": "Grande", + "x-large": "Extra-Large" + }, + "error": { + "pdfPassword": "Il documento PDF ĆØ protetto da password e la password non ĆØ stata fornita oppure non era corretta", + "_value": "Errore", + "sorry": "Ci scusiamo per il problema!", + "needHelp": "Hai bisogno di aiuto / trovato un problema?", + "contactTip": "Se i problemi persistono, non esitare a contattarci per chiedere aiuto. Puoi aprire un ticket sulla nostra pagina GitHub o contattarci tramite Discord:", + "404": { + "head": "404 - Pagina non trovata | Spiacenti, siamo inciampati nel codice!", + "1": "Non riusciamo a trovare la pagina che stai cercando.", + "2": "Qualcosa ĆØ andato storto" + }, + "github": "Apri un ticket su GitHub", + "showStack": "Mostra traccia dello stack", + "copyStack": "Copia traccia dello stack", + "githubSubmit": "GitHub: apri un ticket", + "discordSubmit": "Discord: invia post di supporto" + }, + "delete": "Elimina", + "username": "Nome utente", + "password": "Password", + "welcome": "Benvenuto", + "property": "ProprietĆ ", + "black": "Nero", + "white": "Bianco", + "red": "Rosso", + "green": "Verde", + "blue": "Blu", + "custom": "Personalizzato", + "WorkInProgess": "Lavori in corso, potrebbe non funzionare o essere difettoso, segnalare eventuali problemi!", + "poweredBy": "Alimentato da", + "yes": "Si", + "no": "No", + "changedCredsMessage": "Credenziali modificate!", + "notAuthenticatedMessage": "Utente non autenticato.", + "userNotFoundMessage": "Utente non trovato.", + "incorrectPasswordMessage": "La password attuale non ĆØ corretta.", + "usernameExistsMessage": "Il nuovo nome utente esiste giĆ .", + "invalidUsernameMessage": "Nome utente non valido, il nome utente può contenere solo lettere, numeri e i seguenti caratteri speciali @._+- o deve essere un indirizzo email valido.", + "invalidPasswordMessage": "La password non deve essere vuota e non deve contenere spazi all'inizio o alla fine.", + "confirmPasswordErrorMessage": "La nuova password e la conferma della nuova password devono corrispondere.", + "deleteCurrentUserMessage": "Impossibile eliminare l'utente attualmente connesso.", + "deleteUsernameExistsMessage": "Il nome utente non esiste e non può essere eliminato.", + "downgradeCurrentUserMessage": "Impossibile declassare il ruolo dell'utente corrente", + "disabledCurrentUserMessage": "L'utente corrente non può essere disabilitato", + "downgradeCurrentUserLongMessage": "Impossibile declassare il ruolo dell'utente corrente. Pertanto, l'utente corrente non verrĆ  visualizzato.", + "userAlreadyExistsOAuthMessage": "L'utente esiste giĆ  come utente OAuth2.", + "userAlreadyExistsWebMessage": "L'utente esiste giĆ  come utente web.", + "oops": "Oops!", + "help": "Aiuto", + "goHomepage": "Vai alla Homepage", + "joinDiscord": "Unisciti al nostro server Discord", + "seeDockerHub": "Vedi DockerHub", + "visitGithub": "Visita il repository Github", + "donate": "Donazione", + "color": "Colore", + "sponsor": "Sponsor", + "info": "Info", + "pro": "Pro", + "page": "Pagina", + "pages": "Pagine", + "loading": "Caricamento...", + "addToDoc": "Aggiungi al documento", + "reset": "Resetta", + "apply": "Applica", + "noFileSelected": "Nessun file selezionato. Caricane uno.", + "legal": { + "privacy": "Informativa sulla privacy", + "terms": "Termini e Condizioni", + "accessibility": "AccessibilitĆ ", + "cookie": "Informativa sui cookie", + "impressum": "Informazioni legali", + "showCookieBanner": "Preferenze sui cookie" + }, + "pipeline": { + "header": "Menù pipeline (Beta)", + "uploadButton": "Caricamento personalizzato", + "configureButton": "Configura", + "defaultOption": "Personalizzato", + "submitButton": "Invia", + "help": "Aiuto sulla pipeline", + "scanHelp": "Aiuto per la scansione delle cartelle", + "deletePrompt": "Sei sicuro di voler eliminare la pipeline?", + "tags": "automatizzare,sequenziare,scriptare,elaborare in batch", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Configurazione Pipeline", + "pipelineNameLabel": "Nome della Pipeline", + "saveSettings": "Salva Impostazioni", + "pipelineNamePrompt": "Inserisci qui il nome della pipeline", + "selectOperation": "Seleziona operazione", + "addOperationButton": "Aggiungi operazione", + "pipelineHeader": "Pipeline:", + "saveButton": "Salva", + "validateButton": "Convalidare" + }, + "enterpriseEdition": { + "button": "Aggiorna alla versione Pro", + "warning": "Questa funzionalitĆ  ĆØ disponibile solo per gli utenti Pro.", + "yamlAdvert": "Stirling PDF Pro supporta i file di configurazione YAML e altre funzionalitĆ  SSO.", + "ssoAdvert": "Cerchi altre funzionalitĆ  di gestione degli utenti? Dai un'occhiata a Stirling PDF Pro" + }, + "analytics": { + "title": "Vuoi migliorare Stirling PDF?", + "paragraph1": "Stirling PDF ha opt-in analytics per aiutarci a migliorare il prodotto. Non tracciamo alcuna informazione personale o contenuto di file.", + "paragraph2": "Si prega di prendere in considerazione l'attivazione dell'analytics per aiutare Stirling-PDF a crescere e consentirci di comprendere meglio i nostri utenti.", + "enable": "Abilita analytics", + "disable": "Disabilita analytics", + "settings": "ƈ possibile modificare le impostazioni per analitycs nel file config/settings.yml" + }, + "navbar": { + "favorite": "Preferiti", + "recent": "Nuovo e aggiornato di recente", + "darkmode": "ModalitĆ  Scura", + "language": "Lingue", + "settings": "Impostazioni", + "allTools": "Strumenti", + "multiTool": "Strumenti multipli", + "search": "Cerca", + "sections": { + "organize": "Organizza", + "convertTo": "Converti in PDF", + "convertFrom": "Converti da PDF", + "security": "Firma & Sicurezza", + "advance": "Avanzate", + "edit": "Visualizza & Modifica", + "popular": "Popolare" + } + }, + "settings": { + "title": "Impostazioni", + "update": "Aggiornamento disponibile", + "updateAvailable": "{0} ĆØ la versione attualmente installata. Una nuova versione ({1}) ĆØ disponibile.", + "appVersion": "Versione App:", + "downloadOption": { + "title": "Scegli opzione di download (Per file singoli non compressi):", + "1": "Apri in questa finestra", + "2": "Apri in una nuova finestra", + "3": "Scarica file" + }, + "zipThreshold": "Comprimi file in .zip quando il numero di download supera", + "signOut": "Logout", + "accountSettings": "Impostazioni Account", + "bored": { + "help": "Abilita easter egg game" + }, + "cacheInputs": { + "name": "Salva gli input del modulo", + "help": "Abilitare per memorizzare gli input utilizzati in precedenza per esecuzioni future" + } + }, + "changeCreds": { + "title": "Cambia credenziali", + "header": "Aggiorna i dettagli del tuo account", + "changePassword": "Stai utilizzando le credenziali di accesso predefinite. Inserisci una nuova password", + "newUsername": "Nuovo nome utente", + "oldPassword": "Password attuale", + "newPassword": "Nuova Password", + "confirmNewPassword": "Conferma nuova Password", + "submit": "Invia modifiche" + }, + "account": { + "title": "Impostazioni Account", + "accountSettings": "Impostazioni Account", + "adminSettings": "Impostazioni Admin - Aggiungi e Vedi Utenti", + "userControlSettings": "Impostazioni Utente", + "changeUsername": "Cambia nome utente", + "newUsername": "Nuovo nome utente", + "password": "Conferma Password", + "oldPassword": "Vecchia Password", + "newPassword": "Nuova Password", + "changePassword": "Cambia Password", + "confirmNewPassword": "Conferma Nuova Password", + "signOut": "Logout", + "yourApiKey": "La tua API Key", + "syncTitle": "Sincronizza le impostazioni del browser con l'account", + "settingsCompare": "Confronto delle impostazioni:", + "property": "ProprietĆ ", + "webBrowserSettings": "Impostazione del browser web", + "syncToBrowser": "Sincronizza account -> Browser", + "syncToAccount": "Sincronizza account <- Browser" + }, + "adminUserSettings": { + "title": "Impostazioni di controllo utente", + "header": "Impostazioni di controllo utente amministratore", + "admin": "Amministratore", + "user": "Utente", + "addUser": "Aggiungi un nuovo Utente", + "deleteUser": "Elimina utente", + "confirmDeleteUser": "L'utente deve essere eliminato?", + "confirmChangeUserStatus": "L'utente dovrebbe essere disabilitato/abilitato?", + "usernameInfo": "Il nome utente può contenere solo lettere, numeri e i seguenti caratteri speciali @._+- oppure deve essere un indirizzo email valido.", + "roles": "Ruoli", + "role": "Ruolo", + "actions": "Azioni", + "apiUser": "Utente API limitato", + "extraApiUser": "API utente limitato aggiuntivo", + "webOnlyUser": "Utente solo Web", + "demoUser": "Utente demo (nessuna impostazione personalizzata)", + "internalApiUser": "API utente interna", + "forceChange": "Forza l'utente a cambiare nome utente/password all'accesso", + "submit": "Salva utente", + "changeUserRole": "Cambia il ruolo dell'utente", + "authenticated": "Autenticato", + "editOwnProfil": "Modifica il tuo profilo", + "enabledUser": "utente abilitato", + "disabledUser": "utente disabilitato", + "activeUsers": "Utenti attivi:", + "disabledUsers": "Utenti disabili:", + "totalUsers": "Utenti totali:", + "lastRequest": "Ultima richiesta", + "usage": "Visualizza utilizzo" + }, + "endpointStatistics": { + "title": "Statistiche degli endpoint", + "header": "Statistiche degli endpoint", + "top10": "I migliori 10", + "top20": "I migliori 20", + "all": "Tutto", + "refresh": "Aggiorna", + "includeHomepage": "Includi homepage ('/')", + "includeLoginPage": "Includi pagina di login ('/login')", + "totalEndpoints": "Endpoint totali", + "totalVisits": "Visite totali", + "showing": "Mostrare", + "selectedVisits": "Visite selezionate", + "endpoint": "Endpoint", + "visits": "Visite", + "percentage": "Percentuale", + "loading": "Caricamento...", + "failedToLoad": "Impossibile caricare i dati dell'endpoint. Prova ad aggiornare.", + "home": "Home", + "login": "Login", + "top": "Migliore", + "numberOfVisits": "Numero di visite", + "visitsTooltip": "Visite: {0} ({1}% del totale)", + "retry": "Riprovare" + }, + "database": { + "title": "Importazione/Esportazione database", + "header": "Importazione/esportazione database", + "fileName": "Nome file", + "creationDate": "Data di creazione", + "fileSize": "Dimensione", + "deleteBackupFile": "Elimina file di backup", + "importBackupFile": "Importa file di backup", + "createBackupFile": "Crea file di backup", + "downloadBackupFile": "Scarica il file di backup", + "info_1": "Quando si importano i dati, ĆØ fondamentale garantire la struttura corretta. Se non sei sicuro di quello che stai facendo, chiedi consiglio e supporto a un professionista. Un errore nella struttura può causare malfunzionamenti dell'applicazione, fino alla completa impossibilitĆ  di eseguire l'applicazione.", + "info_2": "Il nome del file non ha importanza durante il caricamento. VerrĆ  rinominato in seguito per seguire il formato backup_user__yyyyMMddHHmm.sql,garantendo una convenzione di denominazione coerente.", + "submit": "Importa Backup", + "importIntoDatabaseSuccessed": "L'importazione nel database ĆØ avvenuta con successo", + "backupCreated": "Backup del database riuscito", + "fileNotFound": "File non trovato", + "fileNullOrEmpty": "Il file non deve essere nullo o vuoto", + "failedImportFile": "Importazione file non riuscita", + "notSupported": "Questa funzione non ĆØ disponibile per la connessione al database." + }, + "session": { + "expired": "La tua sessione ĆØ scaduta. Aggiorna la pagina e riprova.", + "refreshPage": "Aggiorna pagina" + }, + "home": { + "desc": "La tua pagina auto-gestita per modificare qualsiasi PDF.", + "searchBar": "Cerca funzionalitĆ ...", + "viewPdf": { + "title": "Visualizza/Modifica PDF", + "desc": "Visualizza, annota, aggiungi testo o immagini" + }, + "setFavorites": "Imposta preferiti", + "hideFavorites": "Nascondi i preferiti", + "showFavorites": "Mostra preferiti", + "legacyHomepage": "Vecchia homepage", + "newHomePage": "Prova la nostra nuova homepage!", + "alphabetical": "Alfabetico", + "globalPopularity": "PopolaritĆ ", + "sortBy": "Ordinamento:", + "multiTool": { + "title": "Multifunzione PDF", + "desc": "Unisci, Ruota, Riordina, e Rimuovi pagine" + }, + "merge": { + "title": "Unisci", + "desc": "Unisci facilmente più PDF in uno." + }, + "split": { + "title": "Dividi", + "desc": "Dividi un singolo PDF in più documenti." + }, + "rotate": { + "title": "Ruota", + "desc": "Ruota un PDF." + }, + "imageToPdf": { + "title": "Da immagine a PDF", + "desc": "Converti un'immagine (PNG, JPEG, GIF) in PDF." + }, + "pdfToImage": { + "title": "Da PDF a immagine", + "desc": "Converti un PDF in un'immagine. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Organizza", + "desc": "Rimuovi/Riordina le pagine in qualsiasi ordine." + }, + "addImage": { + "title": "Aggiungi Immagine", + "desc": "Aggiungi un'immagine in un punto specifico del PDF (Lavori in corso)" + }, + "watermark": { + "title": "Aggiungi Filigrana", + "desc": "Aggiungi una filigrana al tuo PDF." + }, + "permissions": { + "title": "Cambia Permessi", + "desc": "Cambia i permessi del tuo PDF." + }, + "removePages": { + "title": "Rimuovi", + "desc": "Elimina alcune pagine dal PDF." + }, + "addPassword": { + "title": "Aggiungi Password", + "desc": "Crittografa il tuo PDF con una password." + }, + "removePassword": { + "title": "Rimuovi Password", + "desc": "Rimuovi la password dal tuo PDF." + }, + "compressPdfs": { + "title": "Comprimi", + "desc": "Comprimi PDF per ridurne le dimensioni." + }, + "unlockPDFForms": { + "title": "Sblocca moduli PDF", + "desc": "Rimuovi la proprietĆ  di sola lettura dei campi del modulo in un documento PDF." + }, + "changeMetadata": { + "title": "Modifica ProprietĆ ", + "desc": "Modifica/Aggiungi/Rimuovi le proprietĆ  di un documento PDF." + }, + "fileToPDF": { + "title": "Converti file in PDF", + "desc": "Converti quasi ogni file in PDF (DOCX, PNG, XLS, PPT, TXT e altro)" + }, + "ocr": { + "title": "OCR / Pulisci scansioni", + "desc": "Pulisci scansioni ed estrai testo da immagini, convertendo le immagini in testo puro." + }, + "extractImages": { + "title": "Estrai immagini", + "desc": "Estrai tutte le immagini da un PDF e salvale come zip." + }, + "pdfToPDFA": { + "title": "Converti in PDF/A", + "desc": "Converti un PDF nel formato PDF/A per archiviazione a lungo termine." + }, + "PDFToWord": { + "title": "Da PDF a Word", + "desc": "Converti un PDF nei formati Word (DOC, DOCX e ODT)" + }, + "PDFToPresentation": { + "title": "Da PDF a presentazioni", + "desc": "Converti un PDF in presentazioni (PPT, PPTX and ODP)" + }, + "PDFToText": { + "title": "Da PDF a testo/RTF", + "desc": "Converti un PDF in testo o RTF." + }, + "PDFToHTML": { + "title": "Da PDF ad HTML", + "desc": "Converti un PDF in HTML." + }, + "PDFToXML": { + "title": "Da PDF a XML", + "desc": "Converti un PDF in XML." + }, + "ScannerImageSplit": { + "title": "Trova/Dividi foto scansionate", + "desc": "Estrai più foto da una singola foto o PDF." + }, + "sign": { + "title": "Firma", + "desc": "Aggiungi una firma al PDF da disegno, testo o immagine." + }, + "flatten": { + "title": "Appiattisci", + "desc": "Rimuovi tutti gli elementi interattivi e moduli da un PDF." + }, + "repair": { + "title": "Ripara", + "desc": "Prova a riparare un PDF corrotto." + }, + "removeBlanks": { + "title": "Rimuovi pagine vuote", + "desc": "Trova e rimuovi pagine vuote da un PDF." + }, + "removeAnnotations": { + "title": "Rimuovi annotazioni", + "desc": "Rimuove tutti i commenti/annotazioni da un PDF" + }, + "compare": { + "title": "Compara", + "desc": "Vedi e compara le differenze tra due PDF." + }, + "certSign": { + "title": "Firma con certificato", + "desc": "Firma un PDF con un certificato/chiave (PEM/P12)" + }, + "removeCertSign": { + "title": "Rimuovere firma dal certificato", + "desc": "Rimuovi la firma del certificato dal PDF" + }, + "pageLayout": { + "title": "Layout multipagina", + "desc": "Unisci più pagine di un documento PDF in un'unica pagina" + }, + "scalePages": { + "title": "Regola le dimensioni/scala della pagina", + "desc": "Modificare le dimensioni/scala della pagina e/o dei suoi contenuti." + }, + "pipeline": { + "title": "Pipeline", + "desc": "Esegui più azioni sui PDF definendo script di pipeline" + }, + "add-page-numbers": { + "title": "Aggiungi numeri di pagina", + "desc": "Aggiungi numeri di pagina in tutto un documento in una posizione prestabilita" + }, + "auto-rename": { + "title": "Rinomina automaticamente il file PDF", + "desc": "Rinomina automaticamente un file PDF in base all'intestazione rilevata" + }, + "adjust-contrast": { + "title": "Regola colori/contrasto", + "desc": "Regola contrasto, saturazione e luminositĆ  di un PDF" + }, + "crop": { + "title": "Ritaglia PDF", + "desc": "Ritaglia un PDF per ridurne le dimensioni (mantiene il testo!)" + }, + "autoSplitPDF": { + "title": "Pagine divise automaticamente", + "desc": "Dividi automaticamente il PDF scansionato con il codice QR dello divisore di pagina fisico scansionato" + }, + "sanitizePdf": { + "title": "Pulire", + "desc": "Rimuovi script e altri elementi dai file PDF" + }, + "URLToPDF": { + "title": "URL/sito Web in PDF", + "desc": "Converte qualsiasi URL http(s) in PDF" + }, + "HTMLToPDF": { + "title": "Da HTML a PDF", + "desc": "Converte qualsiasi file HTML o zip in PDF" + }, + "MarkdownToPDF": { + "title": "Markdown in PDF", + "desc": "Converte qualsiasi file Markdown in PDF" + }, + "PDFToMarkdown": { + "title": "PDF in Markdown", + "desc": "Converte qualsiasi PDF in Markdown" + }, + "getPdfInfo": { + "title": "Ottieni TUTTE le informazioni in PDF", + "desc": "Raccogli tutte le informazioni possibili sui PDF" + }, + "extractPage": { + "title": "Estrai pagina/e", + "desc": "Estrae le pagine selezionate dal PDF" + }, + "PdfToSinglePage": { + "title": "PDF in un'unica pagina di grandi dimensioni", + "desc": "Unisce tutte le pagine PDF in un'unica grande pagina" + }, + "showJS": { + "title": "Mostra Javascript", + "desc": "Cerca e visualizza qualsiasi JS inserito in un PDF" + }, + "autoRedact": { + "title": "Redazione automatica", + "desc": "Redige automaticamente (oscura) il testo in un PDF in base al testo immesso" + }, + "redact": { + "title": "Redazione manuale", + "desc": "Redige un PDF in base al testo selezionato, alle forme disegnate e/o alle pagina selezionata(e)" + }, + "tableExtraxt": { + "title": "Da PDF a CSV", + "desc": "Estrae tabelle da un PDF convertendolo in CSV" + }, + "autoSizeSplitPDF": { + "title": "Divisione automatica per dimensione/numero", + "desc": "Dividi un singolo PDF in più documenti in base alle dimensioni, al numero di pagine o al numero di documenti" + }, + "overlay-pdfs": { + "title": "Sovrapposizione di PDF", + "desc": "Sovrappone i PDF sopra un altro PDF" + }, + "split-by-sections": { + "title": "Dividi PDF per sezioni", + "desc": "Dividi ciascuna pagina di un PDF in sezioni orizzontali e verticali più piccole" + }, + "AddStampRequest": { + "title": "Aggiungi timbro al PDF", + "desc": "Aggiungi testo o aggiungi timbri immagine nelle posizioni prestabilite" + }, + "removeImagePdf": { + "title": "Rimuovi immagine", + "desc": "Rimuovi le immagini dal PDF per ridurre la dimensione del file" + }, + "splitPdfByChapters": { + "title": "Dividi PDF per capitoli", + "desc": "Dividi un PDF in più file in base alla struttura dei capitoli." + }, + "validateSignature": { + "title": "Convalida la firma PDF", + "desc": "Verificare le firme digitali e i certificati nei documenti PDF" + }, + "replaceColorPdf": { + "title": "Sostituisci e inverti il colore", + "desc": "Sostituisci il colore del testo e dello sfondo nel PDF e inverti il ​​colore completo del PDF per ridurre le dimensioni del file" + } + }, + "viewPdf": { + "tags": "visualizzare,leggere,annotare,testo,immagine", + "title": "Visualizza/Modifica PDF", + "header": "Visualizza PDF" + }, + "multiTool": { + "tags": "Strumento multiplo,operazione multipla,interfaccia utente,trascinamento clic,front-end,lato client", + "title": "Multifunzione PDF", + "header": "Multifunzione PDF", + "uploadPrompts": "Nome file", + "selectAll": "Seleziona tutto", + "deselectAll": "Deseleziona tutto", + "selectPages": "Seleziona pagina", + "selectedPages": "Seleziona pagine", + "page": "Pagina", + "deleteSelected": "Elimina selezionata", + "downloadAll": "Esporta", + "downloadSelected": "Esporta selezionata", + "insertPageBreak": "Inserisci interruzione di pagina", + "addFile": "Aggiungi file", + "rotateLeft": "Ruota a sinistra", + "rotateRight": "Ruota a destra", + "split": "Dividi", + "moveLeft": "Sposta a sinistra", + "moveRight": "Sposta a destra", + "delete": "Elimina", + "dragDropMessage": "Pagina(e) selezionata(e)", + "undo": "Annulla", + "redo": "Rifai" + }, + "merge": { + "tags": "unione,operazioni sulla pagina,back-end,lato server", + "title": "Unisci", + "header": "Unisci 2 o più PDF", + "sortByName": "Ordina per nome", + "sortByDate": "Ordina per data", + "removeCertSign": "Rimuovere la firma digitale nel file unito?", + "submit": "Unisci" + }, + "split": { + "tags": "Operazioni sulla pagina,divisione,multi pagina,taglio,lato server", + "title": "Dividi PDF", + "header": "Dividi PDF", + "desc": { + "1": "I numeri che scegli sono le pagine a cui desideri dividere il documento", + "2": "Per esempio inserendo 1,3,7-9 separeresti un documento di 10 pagine in 6 diversi PDF con:", + "3": "Documento #1: Pagina 1", + "4": "Documento #2: Pagine 2 e 3", + "5": "Documento #3: Pagine 4, 5, 6 e 7", + "6": "Documento #4: Pagina 8", + "7": "Documento #5: Pagina 9", + "8": "Documento #6: Pagine 10" + }, + "splitPages": "Inserisci pagine a cui dividere:", + "submit": "Dividi" + }, + "rotate": { + "tags": "lato server", + "title": "Ruota PDF", + "header": "Ruota PDF", + "selectAngle": "Scegli angolo di rotazione (in multipli di 90 gradi):", + "submit": "Ruota" + }, + "imageToPdf": { + "tags": "conversione,img,jpg,immagine,foto" + }, + "pdfToImage": { + "tags": "conversione,img,jpg,immagine,foto", + "title": "PDF a immagine", + "header": "PDF a immagine", + "selectText": "Formato immagini", + "singleOrMultiple": "Tipo di immagine", + "single": "Unica immagine larga", + "multi": "Più immagini", + "colorType": "Tipo di colore", + "color": "A colori", + "grey": "Scala di grigi", + "blackwhite": "Bianco e Nero (potresti perdere dettagli!)", + "submit": "Converti", + "info": "Python non ĆØ installato.ƈ richiesto per la conversione WebP.", + "placeholder": "(es. 1,2,8 o 4,7,12-16 o 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,pari,dispari,ordinamento,spostamento", + "title": "Organizza pagine", + "header": "Organizza le pagine di un PDF", + "submit": "Riordina pagine", + "mode": { + "_value": "ModalitĆ ", + "1": "Ordine delle pagine personalizzato", + "2": "Ordine inverso", + "3": "Ordinamento fronte-retro", + "4": "Ordinamento a libretto", + "5": "Ordinamento libretto con cucitura laterale", + "6": "Divisione pari-dispari", + "7": "Rimuovi prima", + "8": "Rimuovi ultima", + "9": "Rimuovi la prima e l'ultima", + "10": "Unione pari-dispari", + "11": "Duplica tutte le pagine" + }, + "placeholder": "(ad es. 1,3,2 o 4-8,2,10-12 o 2n-1)" + }, + "addImage": { + "tags": "img,jpg,immagine,foto", + "title": "Aggiungi Immagine", + "header": "Aggiungi un'immagine ad un PDF", + "everyPage": "Ogni pagina?", + "upload": "Aggiungi immagine", + "submit": "Aggiungi immagine" + }, + "watermark": { + "tags": "Testo,ripetizione,etichetta,proprio,copyright,marchio,img,jpg,immagine,foto", + "title": "Aggiungi Filigrana", + "header": "Aggiungi filigrana", + "customColor": "Colore testo personalizzato", + "selectText": { + "1": "Seleziona PDF a cui aggiungere la filigrana:", + "2": "Testo:", + "3": "Dimensione carattere:", + "4": "Rotazione (0-360):", + "5": "spazio orizzontale (tra ogni filigrana):", + "6": "spazio verticale (tra ogni filigrana):", + "7": "OpacitĆ  (0% - 100%):", + "8": "Tipo di filigrana:", + "9": "Immagine filigrana:", + "10": "Converti PDF in PDF-Immagine" + }, + "submit": "Aggiungi Filigrana", + "type": { + "1": "Testo", + "2": "Immagine" + } + }, + "permissions": { + "tags": "leggere,scrivere,modificare,stampare", + "title": "Cambia Permessi", + "header": "Cambia permessi", + "warning": "Attenzione: per avere questi permessi non modificabili ĆØ raccomandabile impostarli attraverso una password", + "selectText": { + "1": "Seleziona PDF a cui cambiare permessi", + "2": "Permessi da impostare", + "3": "Previeni assemblaggio del documento", + "4": "Previeni estrazione del contenuto", + "5": "Previeni estrazione per accessibilitĆ ", + "6": "Previeni compilazione dei moduli", + "7": "Previeni modifiche", + "8": "Previeni annotazioni", + "9": "Previeni stampa", + "10": "Previeni stampa in diversi formati" + }, + "submit": "Cambia Permessi" + }, + "removePages": { + "tags": "Rimuovere pagine,eliminare pagine" + }, + "addPassword": { + "tags": "sicuro,sicurezza", + "title": "Aggiungi Password", + "header": "Aggiungi password (crittografa)", + "selectText": { + "1": "Seleziona PDF da crittografare", + "2": "Password", + "3": "Lunghezza chiave", + "4": "Valori più grandi sono più sicuri, ma valori più piccoli offrono una compatibilitĆ  maggiore.", + "5": "Permessi", + "6": "Previeni assemblaggio del documento", + "7": "Previeni estrazione del contenuto", + "8": "Previeni estrazione per accessibilitĆ ", + "9": "Previeni compilazione dei moduli", + "10": "Previeni modifiche", + "11": "Previeni annotazioni", + "12": "Previeni stampa", + "13": "Previeni stampa in diversi formati", + "14": "Password del proprietario", + "15": "Limita le operazioni eseguibili con il documento una volta aperto (non supportato da tutti i lettori)", + "16": "Limita l'apertura del documento stesso" + }, + "submit": "Crittografa" + }, + "removePassword": { + "tags": "Decriptare,proteggere,rimuovere la password,eliminare la password", + "title": "Rimuovi Password", + "header": "Rimuovi password (de-crittografa)", + "selectText": { + "1": "Seleziona PDF da decrittare", + "2": "Password" + }, + "submit": "Rimuovi Password" + }, + "compressPdfs": { + "tags": "comprimere,piccolo,minuscolo" + }, + "unlockPDFForms": { + "tags": "rimuovi,elimina,modulo,campo,sola lettura", + "title": "Rimuovi la sola lettura dai campi del modulo", + "header": "Sbloccare i moduli PDF", + "submit": "Rimuovi" + }, + "changeMetadata": { + "tags": "Titolo,autore,data,creazione,ora,editore,produttore,statistiche", + "title": "Titolo:", + "header": "Cambia ProprietĆ ", + "selectText": { + "1": "Imposta i dati che vuoi cambiare", + "2": "Cancella tutte le proprietĆ ", + "3": "Visualizza proprietĆ  personalizzate:", + "4": "Altre proprietĆ :", + "5": "Aggiungi proprietĆ  personalizzata:" + }, + "author": "Autore:", + "creationDate": "Data di creazione (yyyy/MM/dd HH:mm:ss):", + "creator": "Creatore:", + "keywords": "Parole chiave:", + "modDate": "Data di modifica (yyyy/MM/dd HH:mm:ss):", + "producer": "Produttore:", + "subject": "Oggetto:", + "trapped": "Recuperato:", + "submit": "Cambia proprietĆ " + }, + "fileToPDF": { + "tags": "trasformazione,formato,documento,immagine,diapositiva,testo,conversione,ufficio,documenti,parola,excel,powerpoint", + "title": "Converti file in PDF", + "header": "Converti qualsiasi file in PDF", + "credit": "Questo servizio utilizza LibreOffice e Unoconv per la conversione dei file.", + "supportedFileTypesInfo": "Tipi di file supportati", + "supportedFileTypes": "I formati file supportati dovrebbero includere quelli sottostanti. Tuttavia, per una lista aggiornata controlla la documentazione di LibreOffice", + "submit": "Converti in PDF" + }, + "ocr": { + "tags": "riconoscimento,testo,immagine,scansione,lettura,identificazione,rilevamento,modificabile", + "title": "OCR / Pulisci scansioni", + "header": "Pulisci scansioni / OCR (riconoscimento testo)", + "selectText": { + "1": "Scegli lingue da usare per il riconoscimento testo (L'elenco contiene quelle attualmente disponibili):", + "2": "Crea file di testo contenente il testo estratto oltre al PDF originale", + "3": "Sistema le pagine che sono state scansionate storte ruotandole in posizione corretta.", + "4": "Pulisci il foglio in modo da evitare errori nella lettura. (non cambia il risultato)", + "5": "Pulisci il foglio in modo da evitare errori nella lettura. (cambia il risultato)", + "6": "Ignora pagine che contengono testo interattivo, scansiona solo pagine che contengono immagini", + "7": "Forza scansione, scansiona ogni pagina rimuovendo gli elementi originali", + "8": "Normale (DarĆ  errore se il PDF contiene testo)", + "9": "Impostazioni extra", + "10": "ModalitĆ  OCR", + "11": "Rimuovi immagini dopo la scansione (Rimuove TUTTE le immagini, utile solo come parte del processo di conversione)", + "12": "ModalitĆ  di rendering (avanzato)" + }, + "help": "Per favore leggi la documentazione su come usare il programma per altri linguaggi e/o uso non in Docker", + "credit": "Questo servizio utilizza Qpdf e Tesseract per l'OCR.", + "submit": "Scansiona testo nel PDF con OCR" + }, + "extractImages": { + "tags": "immagine,foto,salva,archivio,zip,catturare,prendere", + "title": "Estrai immagini", + "header": "Estrai immagini", + "selectText": "Seleziona il formato in cui salvare le immagini estratte", + "allowDuplicates": "Salva le immagini duplicate", + "submit": "Estrai" + }, + "pdfToPDFA": { + "tags": "archivio,a lungo termine,standard,conversione,archiviazione,conservazione", + "title": "Da PDF a PDF/A", + "header": "Da PDF a PDF/A", + "credit": "Questo servizio utilizza libreoffice per la conversione in PDF/A.", + "submit": "Converti", + "tip": "Attualmente non funziona per più input contemporaneamente", + "outputFormat": "Formato di output", + "pdfWithDigitalSignature": "Il PDF contiene una firma digitale. Questo verrĆ  rimosso nel passaggio successivo." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,trasformazione,formato,conversione,office,microsoft,filedoc", + "title": "Da PDF a Word", + "header": "Da PDF a Word", + "selectText": { + "1": "Formato file di output" + }, + "credit": "Questo servizio utilizza LibreOffice per la conversione.", + "submit": "Converti" + }, + "PDFToPresentation": { + "tags": "diapositive,mostra,office,microsoft", + "title": "Da PDF a presentazione", + "header": "Da PDF a presentazione", + "selectText": { + "1": "Formato file di output" + }, + "credit": "Questo servizio utilizza LibreOffice per la conversione.", + "submit": "Converti" + }, + "PDFToText": { + "tags": "Microsoft Rich Format,formato Rich Text,formato Rich Text", + "title": "Da PDF a testo/RTF", + "header": "Da PDF a testo/RTF", + "selectText": { + "1": "Formato file di output" + }, + "credit": "Questo servizio utilizza LibreOffice per la conversione.", + "submit": "Converti" + }, + "PDFToHTML": { + "tags": "contenuto web,facile da usare per il browser", + "title": "Da PDF a HTML", + "header": "Da PDF a HTML", + "credit": "Questo servizio utilizza pdftohtml per la conversione.", + "submit": "Converti" + }, + "PDFToXML": { + "tags": "estrazione dati,contenuto strutturato,interoperabilitĆ ,trasformazione,conversione", + "title": "Da PDF a XML", + "header": "Da PDF a XML", + "credit": "Questo servizio utilizza LibreOffice per la conversione.", + "submit": "Converti" + }, + "ScannerImageSplit": { + "tags": "separa,rileva automaticamente,scansiona,multi-foto,organizza", + "selectText": { + "1": "Soglia angolo:", + "2": "Imposta il minimo angolo richiesto perchĆ© l'immagine venga ruotata (default: 10).", + "3": "Tolleranza:", + "4": "Imposta lo spettro di colori attorno al colore di sfondo stimato (default: 30).", + "5": "Area minima:", + "6": "Imposta l'area minima di una foto (default: 10000).", + "7": "Area di contorno minima:", + "8": "Imposta l'area minima del contorno di una foto", + "9": "Spessore bordo:", + "10": "Imposta lo spessore del bordo aggiunto o rimosso per prevenire bordi bianchi nel risultato (predefinito: 1)." + }, + "info": "Python non ĆØ installato. ƈ necessario per l'esecuzione." + }, + "sign": { + "tags": "autorizza,iniziali,firma-tracciata,firma-testo,firma-immagine", + "title": "Firma", + "header": "Firma PDF", + "upload": "Carica immagine", + "draw": "Disegna Firma", + "text": "Testo", + "clear": "Cancella", + "add": "Aggiungi", + "saved": "Firme salvate", + "save": "Firma salvata", + "personalSigs": "Firme personali", + "sharedSigs": "Firme condivise", + "noSavedSigs": "Nessuna firma salvata trovata", + "addToAll": "Aggiungi a tutte le pagine", + "delete": "Elimina", + "first": "Prima pagina", + "last": "Ultima pagina", + "next": "Prossima pagina", + "previous": "Pagina precedente", + "maintainRatio": "Attiva il mantenimento delle proporzioni", + "undo": "Annulla", + "redo": "Rifare" + }, + "flatten": { + "tags": "statico,disattivato,non interattivo,ottimizzato", + "title": "Appiattire", + "header": "Appiattisci PDF", + "flattenOnlyForms": "Appiattisci solo i moduli", + "submit": "Appiattisci" + }, + "repair": { + "tags": "aggiustare,ripristinare,correggere,recuperare", + "title": "Ripara", + "header": "Ripara PDF", + "submit": "Ripara" + }, + "removeBlanks": { + "tags": "pulire,semplificare,non contenere contenuti,organizzare", + "title": "Rimuovi spazi vuoti", + "header": "Rimuovi pagine vuote", + "threshold": "Soglia:", + "thresholdDesc": "Soglia che determina un pixel 'bianco'", + "whitePercent": "Percentuale di bianco (%):", + "whitePercentDesc": "Percentuale della pagina che deve essere bianca per venire rimossa", + "submit": "Rimuovi" + }, + "removeAnnotations": { + "tags": "commenti,evidenziazioni,note,markup,rimozione", + "title": "Rimuovi Annotazioni", + "header": "Rimuovi Annotazioni", + "submit": "Rimuovi" + }, + "compare": { + "tags": "differenziare,contrastare,cambiare,analisi", + "title": "Compara", + "header": "Compara PDF", + "highlightColor": { + "1": "Evidenzia colore 1:", + "2": "Evidenzia colore 2:" + }, + "document": { + "1": "Documento 1", + "2": "Documento 2" + }, + "submit": "Compara", + "complex": { + "message": "Uno o entrambi i documenti forniti sono file di grandi dimensioni, l'accuratezza del confronto potrebbe risultare ridotta" + }, + "large": { + "file": { + "message": "Uno o entrambi i documenti forniti sono troppo grandi per essere elaborati" + } + }, + "no": { + "text": { + "message": "Uno o entrambi i PDF selezionati non hanno contenuto di testo. Si prega di scegliere PDF con testo per il confronto." + } + } + }, + "certSign": { + "tags": "autenticare,PEM,P12,ufficiale,crittografare", + "title": "Firma del certificato", + "header": "Firma un PDF con il tuo certificato (Lavoro in corso)", + "selectPDF": "Seleziona un file PDF per la firma:", + "jksNote": "Nota: se il tipo di certificato non ĆØ elencato di seguito, convertilo in un file Java Keystore (.jks) utilizzando lo strumento da riga di comando keytool. Quindi, scegli l'opzione del file .jks di seguito.", + "selectKey": "Seleziona il file della tua chiave privata (formato PKCS#8, potrebbe essere .pem o .der):", + "selectCert": "Seleziona il tuo file di certificato (formato X.509, potrebbe essere .pem o .der):", + "selectP12": "Selezionare il file keystore PKCS#12 (.p12 o .pfx) (facoltativo, se fornito, dovrebbe contenere la chiave privata e il certificato):", + "selectJKS": "Seleziona il tuo file Java Keystore (.jks o .keystore):", + "certType": "Tipo di certificato", + "password": "Inserisci la tua password dell'archivio chiavi o della chiave privata (se presente):", + "showSig": "Mostra firma", + "reason": "Motivo", + "location": "Posizione", + "name": "Nome", + "showLogo": "Mostra Logo", + "submit": "Firma PDF" + }, + "removeCertSign": { + "tags": "autenticare,PEM,P12,ufficiale,decifrare", + "title": "Rimuovi certificato della firma", + "header": "Rimuovere il certificato digitale dal PDF", + "selectPDF": "Seleziona un file PDF:", + "submit": "Rimuovi firma" + }, + "pageLayout": { + "tags": "unire,comporre,visualizzazione singola,organizzare", + "title": "Layout multipagina", + "header": "Layout multipagina", + "pagesPerSheet": "Pagine per foglio:", + "addBorder": "Aggiungi bordi", + "submit": "Invia" + }, + "scalePages": { + "tags": "ridimensionare,modificare,dimensionare,adattare", + "title": "Regola la scala della pagina", + "header": "Regola la scala della pagina", + "pageSize": "Dimensione di una pagina del documento.", + "keepPageSize": "Dimensione originale", + "scaleFactor": "Livello di zoom (ritaglio) di una pagina.", + "submit": "Invia" + }, + "add-page-numbers": { + "tags": "impaginare,etichettare,organizzare,indicizzare" + }, + "auto-rename": { + "tags": "rilevamento automatico,basato su intestazione,organizzazione,rietichettatura", + "title": "Rinomina automatica", + "header": "Rinomina automatica PDF", + "submit": "Rinomina automatica" + }, + "adjust-contrast": { + "tags": "correzione del colore,messa a punto,modifica,miglioramento" + }, + "crop": { + "tags": "tagliare,ridurre,modificare,modellare", + "title": "Ritaglia", + "header": "Ritaglia PDF", + "submit": "Invia" + }, + "autoSplitPDF": { + "tags": "Basato su QR,separato,scansiona segmenti,organizza", + "title": "PDF diviso automaticamente", + "header": "PDF diviso automaticamente", + "description": "Stampa, inserisci, scansiona, carica e lasciaci separare automaticamente i tuoi documenti. Non ĆØ necessario alcuno smistamento manuale.", + "selectText": { + "1": "Stampa alcuni fogli divisori dal basso (il bianco e nero va bene).", + "2": "Scansiona tutti i tuoi documenti contemporaneamente inserendo il foglio divisorio tra di loro.", + "3": "Carica il singolo file PDF scansionato di grandi dimensioni e lascia che Stirling PDF gestisca il resto.", + "4": "Le pagine divisorie vengono rilevate e rimosse automaticamente, garantendo un documento finale ordinato." + }, + "formPrompt": "Invia PDF contenente divisori di pagina Stirling-PDF:", + "duplexMode": "ModalitĆ  duplex (scansione fronte e retro)", + "dividerDownload2": "Scarica 'Divisore automatico (con istruzioni).pdf'", + "submit": "Invia" + }, + "sanitizePdf": { + "tags": "pulire,proteggere,rimuovere le minacce" + }, + "URLToPDF": { + "tags": "acquisizione web,salvataggio pagina,web-to-doc,archivio", + "title": "URL a PDF", + "header": "URL a PDF", + "submit": "Converti", + "credit": "Utilizza WeasyPrint" + }, + "HTMLToPDF": { + "tags": "markup,contenuto web,trasformazione,conversione", + "title": "HTML a PDF", + "header": "HTML a PDF", + "help": "Accetta file HTML e ZIP contenenti html/css/immagini ecc. richiesti", + "submit": "Converti", + "credit": "Utilizza WeasyPrint", + "zoom": "Livello di zoom per la visualizzazione del sito web.", + "pageWidth": "Larghezza della pagina in centimetri. (Vuoto per impostazione predefinita)", + "pageHeight": "Altezza della pagina in centimetri. (Vuoto per impostazione predefinita)", + "marginTop": "Margine superiore della pagina in millimetri. (Vuoto per impostazione predefinita)", + "marginBottom": "Margine inferiore della pagina in millimetri. (Vuoto per impostazione predefinita)", + "marginLeft": "Margine sinistro della pagina in millimetri. (Vuoto per impostazione predefinita)", + "marginRight": "Margine destro della pagina in millimetri. (Vuoto per impostazione predefinita)", + "printBackground": "Rendering dello sfondo dei siti Web.", + "defaultHeader": "Abilita intestazione predefinita (nome e numero di pagina)", + "cssMediaType": "Cambia il tipo di supporto CSS della pagina.", + "none": "Nessuno", + "print": "Stampa", + "screen": "Schermo" + }, + "MarkdownToPDF": { + "tags": "markup,contenuto web,trasformazione,conversione", + "title": "Markdown in PDF", + "header": "Markdown in PDF", + "submit": "Converti", + "help": "Conversione in corso", + "credit": "Utilizza WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,contenuto-web,trasformazione,convertire,md", + "title": "PDF in Markdown", + "header": "PDF in Markdown", + "submit": "Converti" + }, + "getPdfInfo": { + "tags": "informazioni,dati,stati,statistiche", + "title": "Ottieni informazioni in PDF", + "header": "Ottieni informazioni in PDF", + "submit": "Ottieni informazioni", + "downloadJson": "Scarica JSON" + }, + "extractPage": { + "tags": "estrarre" + }, + "PdfToSinglePage": { + "tags": "pagina singola" + }, + "showJS": { + "tags": "JS", + "title": "Mostra Javascript", + "header": "Mostra Javascript", + "downloadJS": "Scarica Javascript", + "submit": "Mostra" + }, + "autoRedact": { + "tags": "Redigere,nascondere,oscurare,nero,pennarello,nascosto", + "title": "Redazione automatica", + "header": "Redazione automatica", + "colorLabel": "Colore", + "textsToRedactLabel": "Testo da oscurare (separato da righe)", + "textsToRedactPlaceholder": "per esempio. \\nConfidenziale \\nTop-Secret", + "useRegexLabel": "Usa Regex", + "wholeWordSearchLabel": "Ricerca di parole intere", + "customPaddingLabel": "Padding extra personalizzato", + "convertPDFToImageLabel": "Converti PDF in immagine PDF (utilizzato per rimuovere il testo dietro la casella)", + "submitButton": "Invia" + }, + "redact": { + "tags": "Redigere,nascondere,oscurare,nero,pennarello,nascosto,manuale", + "title": "Redazione manuale", + "header": "Redazione manuale", + "submit": "Redazione", + "textBasedRedaction": "Redazione basata sul testo", + "pageBasedRedaction": "Redazione basata sulla pagina", + "convertPDFToImageLabel": "Converti PDF in immagine PDF (utilizzato per rimuovere il testo dietro la casella)", + "pageRedactionNumbers": { + "title": "Pagine", + "placeholder": "(es. 1,2,8 o 4,7,12-16 o 2n-1)" + }, + "redactionColor": { + "title": "Colore di redazione" + }, + "export": "Esporta", + "upload": "Caricamento", + "boxRedaction": "Redazione del disegno della casella", + "zoom": "Zoom", + "zoomIn": "Ingrandisci", + "zoomOut": "Rimpicciolisci", + "nextPage": "Pagina successiva", + "previousPage": "Pagina precedente", + "toggleSidebar": "Attiva barra laterale", + "showThumbnails": "Mostra miniature", + "showDocumentOutline": "Mostra struttura documento (fare doppio clic per espandere/comprimere tutti gli elementi)", + "showAttatchments": "Mostra allegati", + "showLayers": "Mostra livelli (fare doppio clic per ripristinare tutti i livelli allo stato predefinito)", + "colourPicker": "Selettore colore", + "findCurrentOutlineItem": "Trova l'elemento di contorno corrente", + "applyChanges": "Applica modifiche" + }, + "tableExtraxt": { + "tags": "CSV,Estrazione tabella,estrai,converti" + }, + "autoSizeSplitPDF": { + "tags": "pdf,diviso,documento,organizzazione" + }, + "overlay-pdfs": { + "tags": "Sovrapponi", + "header": "Invia file PDF in sovrapposizione", + "baseFile": { + "label": "Seleziona File PDF di base" + }, + "overlayFiles": { + "label": "Seleziona sovrapposizione file PDF" + }, + "mode": { + "label": "Seleziona la modalitĆ  di sovrapposizione", + "sequential": "Sovrapposizione sequenziale", + "interleaved": "Sovrapposizione interfogliata", + "fixedRepeat": "Risolto il problema con la ripetizione della sovrapposizione" + }, + "counts": { + "label": "Numeri sovrapposti (per la modalitĆ  di ripetizione fissa)", + "placeholder": "Inserisci i numeri separati da virgole (ad esempio, 2,3,1)" + }, + "position": { + "label": "Seleziona posizione di sovrapposizione", + "foreground": "Primo piano", + "background": "Sfondo" + }, + "submit": "Sovrapponi" + }, + "split-by-sections": { + "tags": "Dividi sezione,dividi,personalizza", + "title": "Dividi PDF per sezioni", + "header": "Dividi il PDF in sezioni", + "horizontal": { + "label": "Divisioni orizzontali", + "placeholder": "Inserire il numero di divisioni orizzontali" + }, + "vertical": { + "label": "Divisioni verticali", + "placeholder": "Inserire il numero di divisioni verticali" + }, + "submit": "Dividi PDF", + "merge": "Unisci in un unico PDF" + }, + "AddStampRequest": { + "tags": "Timbro,Aggiungi immagine,Centra immagine,Filigrana,PDF,Incorpora,Personalizza", + "header": "Timbro PDF", + "title": "Timbro PDF", + "stampType": "Tipo di timbro", + "stampText": "Testo del timbro", + "stampImage": "Immagine del timbro", + "alphabet": "Alfabeto", + "fontSize": "Dimensione carattere/immagine", + "rotation": "Rotazione", + "opacity": "OpacitĆ ", + "position": "Posizione", + "overrideX": "Sostituisci la coordinata X", + "overrideY": "Sostituisci la coordinata Y", + "customMargin": "Margine personalizzato", + "customColor": "Colore testo personalizzato", + "submit": "Invia" + }, + "removeImagePdf": { + "tags": "Rimuovi immagine,operazioni sulla pagina,back-end,lato server" + }, + "splitPdfByChapters": { + "tags": "dividi,capitoli,segnalibri,organizza" + }, + "validateSignature": { + "tags": "firma,verifica,convalida,pdf,certificato,firma digitale,convalida firma,convalida certificato", + "title": "Validare le firme PDF", + "header": "Convalidare le firme digitali", + "selectPDF": "Seleziona il file PDF firmato", + "submit": "Convalida firme", + "results": "Risultati di convalida", + "status": { + "_value": "Stato", + "valid": "Valida", + "invalid": "Invalida" + }, + "signer": "Firmatario", + "date": "Data", + "reason": "Ragione", + "location": "Posizione", + "noSignatures": "Nessuna firma digitale trovata in questo documento", + "chain": { + "invalid": "Convalida della catena di certificati non riuscita: impossibile verificare l'identitĆ  del firmatario" + }, + "trust": { + "invalid": "Certificato non presente nell'archivio attendibile: la fonte non può essere verificata" + }, + "cert": { + "expired": "Il certificato ĆØ scaduto", + "revoked": "Il certificato ĆØ stato revocato", + "info": "Dettagli del certificato", + "issuer": "Emittente", + "subject": "Soggetto", + "serialNumber": "Numero di serie", + "validFrom": "Valido da", + "validUntil": "Valido fino a", + "algorithm": "Algoritmo", + "keySize": "Dimensione chiave", + "version": "Versione", + "keyUsage": "Utilizzo della chiave", + "selfSigned": "Autofirmato", + "bits": "bit" + }, + "signature": { + "info": "Informazioni sulla firma", + "_value": "Firma", + "mathValid": "La firma ĆØ matematicamente valida MA:" + }, + "selectCustomCert": "File di certificato personalizzato X.509 (opzionale)" + }, + "replace-color": { + "title": "Sostituisci-Inverti-Colore", + "header": "Sostituisci-Inverti colore PDF", + "selectText": { + "1": "Sostituisci o inverti le opzioni del colore", + "2": "Predefinito (colori ad alto contrasto predefiniti)", + "3": "Personalizzato (colori personalizzati)", + "4": "Inversione completa (inverte tutti i colori)", + "5": "Opzioni di colore ad alto contrasto", + "6": "testo bianco su sfondo nero", + "7": "Testo nero su sfondo bianco", + "8": "Testo giallo su sfondo nero", + "9": "Testo verde su sfondo nero", + "10": "Scegli il colore del testo", + "11": "Scegli il colore di sfondo" + }, + "submit": "Sostituisci" + }, + "replaceColorPdf": { + "tags": "Sostituisci colore, Operazioni di pagina, Back-end, lato server" + }, + "login": { + "title": "Accedi", + "header": "Accedi", + "signin": "Accedi", + "rememberme": "Ricordami", + "invalid": "Nome utente o password errati.", + "locked": "Il tuo account ĆØ stato bloccato.", + "signinTitle": "Per favore accedi", + "ssoSignIn": "Accedi tramite Single Sign-on", + "oAuth2AutoCreateDisabled": "Creazione automatica utente OAUTH2 DISABILITATA", + "oAuth2AdminBlockedUser": "La registrazione o l'accesso degli utenti non registrati ĆØ attualmente bloccata. Si prega di contattare l'amministratore.", + "oauth2RequestNotFound": "Richiesta di autorizzazione non trovata", + "oauth2InvalidUserInfoResponse": "Risposta relativa alle informazioni utente non valida", + "oauth2invalidRequest": "Richiesta non valida", + "oauth2AccessDenied": "Accesso negato", + "oauth2InvalidTokenResponse": "Risposta token non valida", + "oauth2InvalidIdToken": "Id Token non valido", + "relyingPartyRegistrationNotFound": "Nessuna registrazione di parte affidabile trovata", + "userIsDisabled": "L'utente ĆØ disattivato, l'accesso ĆØ attualmente bloccato con questo nome utente. Si prega di contattare l'amministratore.", + "alreadyLoggedIn": "Hai giĆ  effettuato l'accesso a", + "alreadyLoggedIn2": "dispositivi. Esci dai dispositivi e riprova.", + "toManySessions": "Hai troppe sessioni attive", + "logoutMessage": "Sei stato disconnesso." + }, + "pdfToSinglePage": { + "title": "PDF a pagina singola", + "header": "PDF a pagina singola", + "submit": "Converti in pagina singola" + }, + "pageExtracter": { + "title": "Estrai pagine", + "header": "Estrai pagine", + "submit": "Estrai", + "placeholder": "(es. 1,2,8 o 4,7,12-16 o 2n-1)" + }, + "sanitizePDF": { + "title": "Pulire PDF", + "header": "Pulisci un file PDF", + "selectText": { + "1": "Rimuovi le azioni JavaScript", + "2": "Rimuovi i file incorporati", + "3": "Rimuovi i metadati XMP", + "4": "Rimuovi collegamenti", + "5": "Rimuovi i font", + "6": "Rimuovi metadati delle informazioni del documento" + }, + "submit": "Pulisci PDF" + }, + "adjustContrast": { + "title": "Regola il contrasto", + "header": "Regola il contrasto", + "contrast": "Contrasto:", + "brightness": "LuminositĆ :", + "saturation": "Saturazione:", + "download": "Download" + }, + "compress": { + "title": "Comprimi", + "header": "Comprimi PDF", + "credit": "Questo servizio utilizza qpdf per la compressione/ottimizzazione dei PDF.", + "grayscale": { + "label": "Applica scala di grigio per la compressione" + }, + "selectText": { + "1": { + "_value": "Impostazioni di compressione", + "1": "1-3 Compressione PDF,
4-6 Compressione immagine leggera,
7-9 Compressione immagine intensa RidurrĆ  drasticamente la qualitĆ  dell'immagine" + }, + "2": "Livello di ottimizzazione:", + "4": "ModalitĆ  automatica - Regola automaticamente la qualitĆ  per ottenere le dimensioni esatte del PDF", + "5": "Dimensioni PDF previste (ad es. 25 MB, 10,8 MB, 25 KB)" + }, + "submit": "Comprimi" + }, + "decrypt": { + "passwordPrompt": "Questo file ĆØ protetto da password. Inserisci la password:", + "cancelled": "Operazione annullata per il PDF: {0}", + "noPassword": "Nessuna password fornita per il PDF crittografato: {0}", + "invalidPassword": "Riprova con la password corretta.", + "invalidPasswordHeader": "Password errata o crittografia non supportata per il PDF: {0}", + "unexpectedError": "Si ĆØ verificato un errore durante l'elaborazione del file. Riprova..", + "serverError": "Errore del server durante la decrittazione: {0}", + "success": "File decrittografato con successo." + }, + "multiTool-advert": { + "message": "Questa funzione ĆØ disponibile anche nella nostra pagina multi-strumento. Scoprila per un'interfaccia utente pagina per pagina migliorata e funzionalitĆ  aggiuntive!" + }, + "pageRemover": { + "title": "Rimuovi pagine", + "header": "Rimuovi pagine da un PDF", + "pagesToDelete": "Pagine da eliminare (inserisci una lista di numeri separati da virgola):", + "submit": "Rimuovi pagine", + "placeholder": "(es. 1,2,6 o 1-10,15-30)" + }, + "imageToPDF": { + "title": "Immagine a PDF", + "header": "Immagine a PDF", + "submit": "Converti", + "selectLabel": "Opzioni di adattamento immagine", + "fillPage": "Riempi la pagina", + "fitDocumentToImage": "Adatta la pagina all'immagine", + "maintainAspectRatio": "Mantieni le proporzioni", + "selectText": { + "2": "Ruota automaticamente PDF", + "3": "Logica multi-file (funziona solo se ci sono più immagini)", + "4": "Unisci in un unico PDF", + "5": "Converti in PDF separati" + } + }, + "PDFToCSV": { + "title": "Da PDF a CSV", + "header": "Da PDF a CSV", + "prompt": "Scegli la pagina per estrarre la tabella", + "submit": "Estrai" + }, + "split-by-size-or-count": { + "title": "Dividi il PDF per dimensione o numero", + "header": "Dividi il PDF per dimensione o numero", + "type": { + "label": "Seleziona il tipo di divisione", + "size": "Per dimensione", + "pageCount": "Per numero di pagine", + "docCount": "Per numero di documento" + }, + "value": { + "label": "Inserire il valore", + "placeholder": "Inserisci la dimensione (ad esempio, 2 MB o 3 KB) o il numero (ad esempio, 5)" + }, + "submit": "Separa" + }, + "printFile": { + "title": "Stampa file", + "header": "Stampa file su stampante", + "selectText": { + "1": "Seleziona file da stampare", + "2": "Inserire il nome della stampante" + }, + "submit": "Stampare" + }, + "licenses": { + "nav": "Licenze", + "title": "Licenze di terze parti", + "header": "Licenze di terze parti", + "module": "Modulo", + "version": "Versione", + "license": "Licenza" + }, + "survey": { + "nav": "Sondaggio", + "title": "Sondaggio Stirling-PDF", + "description": "Stirling-PDF non fa tracciamento, quindi vogliamo sentire i nostri utenti per migliorare Stirling-PDF!", + "changes": "Stirling-PDF ĆØ cambiato dall'ultimo sondaggio! Per saperne di più, consulta il nostro blog qui:", + "changes2": "Con questi cambiamenti stiamo ricevendo supporto aziendale e finanziamenti retribuiti", + "please": "Ti invitiamo a prendere in considerazione la possibilitĆ  di partecipare al nostro sondaggio!", + "disabled": "(Il popup del sondaggio verrĆ  disabilitato nei prossimi aggiornamenti ma sarĆ  disponibile a piĆØ di pagina)", + "button": "Partecipa al sondaggio", + "dontShowAgain": "Non mostrare più", + "meeting": { + "1": "Se utilizzi Stirling PDF al lavoro, saremo lieti di parlare con te. Offriamo sessioni di supporto tecnico in cambio di una sessione di individuazione dell'utente di 15 minuti.", + "2": "Questa ĆØ un'opportunitĆ  per:", + "3": "Ottenere assistenza per la distribuzione, le integrazioni o la risoluzione dei problemi", + "4": "Fornire feedback diretto su prestazioni, casi limite e lacune nelle funzionalitĆ ", + "5": "Aiutaci a perfezionare Stirling PDF per un utilizzo aziendale nel mondo reale", + "6": "Se sei interessato, puoi prenotare un appuntamento direttamente con il nostro team. (Solo in inglese)", + "7": "Non vediamo l'ora di approfondire i tuoi casi d'uso e di migliorare ulteriormente Stirling PDF!", + "notInterested": "Non sei un'azienda e/o sei interessato a un incontro?", + "button": "Prenota un incontro" + } + }, + "removeImage": { + "title": "Rimuovere immagine", + "header": "Rimuovi immagine", + "removeImage": "Rimuovi immagine", + "submit": "Rimuovi immagine" + }, + "splitByChapters": { + "title": "Dividere PDF per capitoli", + "header": "Dividi PDF per capitoli", + "bookmarkLevel": "Livello segnalibro", + "includeMetadata": "Includi Metadati", + "allowDuplicates": "Consenti duplicati", + "desc": { + "1": "Questo strumento divide un file PDF in più PDF in base alla struttura dei capitoli.", + "2": "Livello segnalibro: seleziona il livello dei segnalibri da utilizzare per la suddivisione (0 per il livello superiore, 1 per il secondo livello, ecc.).", + "3": "Includi metadati: se selezionato, i metadati del PDF originale verranno inclusi in ogni PDF diviso.", + "4": "Consenti duplicati: se selezionata, consente più segnalibri sulla stessa pagina per creare PDF separati." + }, + "submit": "Dividi PDF" + }, + "fileChooser": { + "click": "Clicca", + "or": "o", + "dragAndDrop": "Trascina & Rilascia", + "dragAndDropPDF": "Trascina & rilascia il file PDF", + "dragAndDropImage": "Trascina & rilascia il file immagine", + "hoveredDragAndDrop": "Trascina & rilascia i file qui", + "extractPDF": "Estraendo..." + }, + "releases": { + "footer": "Rilasci", + "title": "Note di rilascio", + "header": "Note di rilascio", + "current": { + "version": "Rilascio corrente" + }, + "note": "Le note di rilascio sono disponibili solo in inglese" + }, + "cookieBanner": { + "popUp": { + "title": "Come utilizziamo i cookie", + "description": { + "1": "Utilizziamo cookie e altre tecnologie per migliorare l'esperienza utente di Stirling PDF, aiutandoci a perfezionare i nostri strumenti e a continuare a sviluppare funzionalitĆ  che amerai.", + "2": "Se preferisci non farlo, cliccando su \"No grazie\" verranno abilitati solo i cookie essenziali, necessari per il corretto funzionamento del sito." + }, + "acceptAllBtn": "Acconsento", + "acceptNecessaryBtn": "No grazie", + "showPreferencesBtn": "Gestisci preferenze" + }, + "preferencesModal": { + "title": "Gestore delle preferenze per il consenso", + "acceptAllBtn": "Accetta tutto", + "acceptNecessaryBtn": "Rifiuta tutto", + "savePreferencesBtn": "Salva preferenze", + "closeIconLabel": "Chiusura modale", + "serviceCounterLabel": "Servizio|Servizi", + "subtitle": "Utilizzo dei cookie", + "description": { + "1": "Stirling PDF utilizza cookie e tecnologie simili per migliorare la tua esperienza e comprendere come vengono utilizzati i nostri strumenti. Questo ci aiuta a migliorare le prestazioni, a sviluppare le funzionalitĆ  che ti interessano e a fornire supporto continuo ai nostri utenti.", + "2": "Stirling PDF non può e non potrĆ  mai tracciare o accedere al contenuto dei documenti che utilizzi.", + "3": "La tua privacy e la tua fiducia sono al centro del nostro operato." + }, + "necessary": { + "title": { + "1": "Cookie strettamente necessari", + "2": "Sempre abilitati" + }, + "description": "Questi cookie sono essenziali per il corretto funzionamento del sito web. Abilitano funzionalitĆ  fondamentali come l'impostazione delle preferenze sulla privacy, l'accesso e la compilazione di moduli, motivo per cui non possono essere disattivati." + }, + "analytics": { + "title": "Analytics", + "description": "Questi cookie ci aiutano a capire come vengono utilizzati i nostri strumenti, cosƬ possiamo concentrarci sullo sviluppo delle funzionalitĆ  che la nostra community apprezza di più. Non preoccuparti: Stirling PDF non può e non traccerĆ  mai il contenuto dei documenti con cui lavori." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/ja-JP/translation.json b/frontend/public/locales/ja-JP/translation.json new file mode 100644 index 000000000..76b1bb87b --- /dev/null +++ b/frontend/public/locales/ja-JP/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "ćƒ•ć‚©ćƒ³ćƒˆć‚µć‚¤ć‚ŗ", + "fontName": "ćƒ•ć‚©ćƒ³ćƒˆå", + "title": "ćƒšćƒ¼ć‚øē•Ŗå·ć®čæ½åŠ ", + "header": "ćƒšćƒ¼ć‚øē•Ŗå·ć®čæ½åŠ ", + "selectText": { + "1": "PDFćƒ•ć‚”ć‚¤ćƒ«ć‚’éøęŠž:", + "2": "余白サイズ", + "3": "ä½ē½®", + "4": "é–‹å§‹ē•Ŗå·", + "5": "ē•Ŗå·ć‚’ć¤ć‘ć‚‹ćƒšćƒ¼ć‚ø", + "6": "ć‚«ć‚¹ć‚æćƒ ćƒ†ć‚­ć‚¹ćƒˆ" + }, + "customTextDesc": "ć‚«ć‚¹ć‚æćƒ ćƒ†ć‚­ć‚¹ćƒˆ", + "numberPagesDesc": "ē•Ŗå·ć‚’ć¤ć‘ć‚‹ćƒšćƒ¼ć‚øć€ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆćÆ'all'态 1-5 悄 2,5,9 など", + "customNumberDesc": "ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆćÆ{n}态'{n} ļ¼ {total} ćƒšćƒ¼ć‚ø'态'ćƒ†ć‚­ć‚¹ćƒˆ-{n}'态'{filename}-{n}など'", + "submit": "ćƒšćƒ¼ć‚øē•Ŗå·ć®čæ½åŠ " + }, + "pdfPrompt": "PDFć‚’éøęŠž", + "multiPdfPrompt": "PDFć‚’éøęŠž (2つ仄上)", + "multiPdfDropPrompt": "PDFć‚’éøęŠž (åˆćÆćƒ‰ćƒ©ćƒƒć‚°&惉惭惃惗)", + "imgPrompt": "ē”»åƒć‚’éøęŠž", + "genericSubmit": "送俔", + "uploadLimit": "ęœ€å¤§ćƒ•ć‚”ć‚¤ćƒ«ć‚µć‚¤ć‚ŗ:", + "uploadLimitExceededSingular": "ć®ć‚µć‚¤ć‚ŗćŒå¤§ćć™ćŽć¾ć™ć€‚čØ±åÆć•ć‚ŒćŸęœ€å¤§ć‚µć‚¤ć‚ŗćÆ", + "uploadLimitExceededPlural": "ć®ć‚µć‚¤ć‚ŗćŒå¤§ćć™ćŽć¾ć™ć€‚čØ±åÆć•ć‚ŒćŸęœ€å¤§ć‚µć‚¤ć‚ŗćÆ", + "processTimeWarning": "č­¦å‘Š:ć“ć®å‡¦ē†ćÆćƒ•ć‚”ć‚¤ćƒ«ć‚µć‚¤ć‚ŗć«ć‚ˆć£ć¦1åˆ†ēØ‹åŗ¦ć‹ć‹ć‚‹ć“ćØćŒć‚ć‚Šć¾ć™", + "pageOrderPrompt": "ćƒšćƒ¼ć‚øé †åŗ (ćƒšćƒ¼ć‚øē•Ŗå·ć‚’ć‚«ćƒ³ćƒžåŒŗåˆ‡ć‚ŠåˆćÆ2n+1ć®ć‚ˆć†ćŖé–¢ę•°ć§å…„åŠ›):", + "pageSelectionPrompt": "ć‚«ć‚¹ć‚æćƒ ćƒšćƒ¼ć‚øéøęŠž(ćƒšćƒ¼ć‚øē•Ŗå·1态5态6または2n + 1ćŖć©ć®é–¢ę•°ć®ć‚³ćƒ³ćƒžåŒŗåˆ‡ć‚ŠćƒŖć‚¹ćƒˆć‚’å…„åŠ›ć—ć¾ć™):", + "goToPage": "移動", + "true": "真", + "false": "偽", + "unknown": "äøę˜Ž", + "save": "äæå­˜", + "saveToBrowser": "ćƒ–ćƒ©ć‚¦ć‚¶ćøäæå­˜", + "close": "閉恘悋", + "filesSelected": "éøęŠžć•ć‚ŒćŸćƒ•ć‚”ć‚¤ćƒ«", + "noFavourites": "ćŠę°—ć«å…„ć‚ŠćÆć‚ć‚Šć¾ć›ć‚“", + "downloadComplete": "ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰å®Œäŗ†", + "bored": "å¾…ć”ę™‚é–“ćŒé€€å±ˆ", + "alphabet": "ć‚¢ćƒ«ćƒ•ć‚”ćƒ™ćƒƒćƒˆ", + "downloadPdf": "PDFć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰", + "text": "ćƒ†ć‚­ć‚¹ćƒˆ", + "font": "ćƒ•ć‚©ćƒ³ćƒˆ", + "selectFillter": "-- éøęŠž --", + "pageNum": "ćƒšćƒ¼ć‚øē•Ŗå·", + "sizes": { + "small": "小", + "medium": "äø­", + "large": "大", + "x-large": "特大" + }, + "error": { + "pdfPassword": "PDFć«ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ćŒčØ­å®šć•ć‚Œć¦ć¾ć™ćŒć€ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ćŒå…„åŠ›ć•ć‚Œć¦ćŖć„ć‹é–“é•ć£ć¦ć¾ć™ć€‚", + "_value": "ć‚Øćƒ©ćƒ¼", + "sorry": "å•é”ŒćŒē™ŗē”Ÿć—ćŸć“ćØć‚’ćŠč©«ć³ē”³ć—äøŠć’ć¾ć™ļ¼", + "needHelp": "åŠ©ć‘ćŒåæ…č¦/å•é”ŒćŒč¦‹ć¤ć‹ć‚Šć¾ć—ćŸć‹ļ¼Ÿ", + "contactTip": "ć¾ć å•é”ŒćŒč§£ę±ŗć—ć¦ć„ćŖć„å “åˆćÆć€ćŠę‰‹ę•°ć§ć™ćŒć€GitHubćƒšćƒ¼ć‚øć§ćƒć‚±ćƒƒćƒˆć‚’ęå‡ŗć™ć‚‹ć‹ć€Discordć§ē§ćŸć”ć«é€£ēµ”ć—ć¦ćć ć•ć„ļ¼š", + "404": { + "head": "404 - ćƒšćƒ¼ć‚øćŒč¦‹ć¤ć‹ć‚Šć¾ć›ć‚“ | ćŠć£ćØć€ć‚³ćƒ¼ćƒ‰ć§ć¤ć¾ćšćć¾ć—ćŸļ¼", + "1": "ć‚ćŖćŸćŒęŽ¢ć—ć¦ć„ć‚‹ćƒšćƒ¼ć‚øćŒč¦‹ć¤ć‹ć‚Šć¾ć›ć‚“ć€‚", + "2": "ä½•ć‹å•é”ŒćŒē™ŗē”Ÿć—ć¾ć—ćŸ" + }, + "github": "GitHubć§ćƒć‚±ćƒƒćƒˆć‚’ęå‡ŗ", + "showStack": "ć‚¹ć‚æćƒƒć‚Æćƒˆćƒ¬ćƒ¼ć‚¹ć‚’č”Øē¤ŗ", + "copyStack": "ć‚¹ć‚æćƒƒć‚Æćƒˆćƒ¬ćƒ¼ć‚¹ć‚’ć‚³ćƒ”ćƒ¼", + "githubSubmit": "GitHub - ćƒć‚±ćƒƒćƒˆć‚’ęå‡ŗ", + "discordSubmit": "Discord - ć‚µćƒćƒ¼ćƒˆęŠ•ēØæć‚’ęå‡ŗ" + }, + "delete": "削除", + "username": "ćƒ¦ćƒ¼ć‚¶ćƒ¼å", + "password": "ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰", + "welcome": "悈恆恓恝", + "property": "ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£", + "black": "黒", + "white": "白", + "red": "赤", + "green": "ē·‘", + "blue": "青", + "custom": "ć‚«ć‚¹ć‚æćƒ ...", + "WorkInProgess": "ä½œę„­äø­ć§ć™ć€‚å‹•ä½œć—ćŖć„ć¾ćŸćÆćƒć‚°ćŒć‚ć‚‹åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚å•é”ŒćŒć‚ć‚Œć°å ±å‘Šć—ć¦ćć ć•ć„ļ¼", + "poweredBy": "Powered by", + "yes": "はい", + "no": "恄恄恈", + "changedCredsMessage": "č³‡ę ¼ęƒ…å ±ćŒå¤‰ę›“ć•ć‚Œć¾ć—ćŸļ¼", + "notAuthenticatedMessage": "ćƒ¦ćƒ¼ć‚¶ćƒ¼ćŒčŖčØ¼ć•ć‚Œć¦ć„ć¾ć›ć‚“ć€‚", + "userNotFoundMessage": "ćƒ¦ćƒ¼ć‚¶ćƒ¼ćŒč¦‹ć¤ć‹ć‚Šć¾ć›ć‚“ć€‚", + "incorrectPasswordMessage": "ē¾åœØć®ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ćŒę­£ć—ćć‚ć‚Šć¾ć›ć‚“ć€‚", + "usernameExistsMessage": "ę–°ć—ć„ćƒ¦ćƒ¼ć‚¶ćƒ¼åćÆć™ć§ć«å­˜åœØć—ć¾ć™ć€‚", + "invalidUsernameMessage": "ćƒ¦ćƒ¼ć‚¶ćƒ¼åćŒē„”åŠ¹ć§ć™ć€‚ćƒ¦ćƒ¼ć‚¶ćƒ¼åć«ćÆę–‡å­—ć€ę•°å­—ć€ćŠć‚ˆć³ćć‚Œć«ē¶šćē‰¹ę®Šę–‡å­— @._+- ć®ćæć‚’å«ć‚ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ć¾ćŸćÆć€ęœ‰åŠ¹ćŖé›»å­ćƒ”ćƒ¼ćƒ« ć‚¢ćƒ‰ćƒ¬ć‚¹ć§ć‚ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚", + "invalidPasswordMessage": "ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ćÆē©ŗć«ć™ć‚‹ć“ćØćÆć§ćć¾ć›ć‚“ć€‚ć¾ćŸć€å…ˆé ­ćƒ»ęœ«å°¾ć«ć‚¹ćƒšćƒ¼ć‚¹ć‚’å«ć‚ć‚‹ć“ćØć‚‚ć§ćć¾ć›ć‚“ć€‚", + "confirmPasswordErrorMessage": "ę–°ć—ć„ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ćØę–°ć—ć„ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć®ē¢ŗčŖćÆäø€č‡“ć™ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚", + "deleteCurrentUserMessage": "ē¾åœØćƒ­ć‚°ć‚¤ćƒ³ć—ć¦ć„ć‚‹ćƒ¦ćƒ¼ć‚¶ćƒ¼ćÆå‰Šé™¤ć§ćć¾ć›ć‚“ć€‚", + "deleteUsernameExistsMessage": "ćć®ćƒ¦ćƒ¼ć‚¶ćƒ¼åćÆå­˜åœØć—ćŖć„ćŸć‚å‰Šé™¤ć§ćć¾ć›ć‚“ć€‚", + "downgradeCurrentUserMessage": "ē¾åœØć®ćƒ¦ćƒ¼ć‚¶ćƒ¼ć®å½¹å‰²ć‚’ćƒ€ć‚¦ćƒ³ć‚°ćƒ¬ćƒ¼ćƒ‰ć§ćć¾ć›ć‚“", + "disabledCurrentUserMessage": "ē¾åœØć®ćƒ¦ćƒ¼ć‚¶ćƒ¼ć‚’ē„”åŠ¹ć«ć™ć‚‹ć“ćØćÆć§ćć¾ć›ć‚“", + "downgradeCurrentUserLongMessage": "ē¾åœØć®ćƒ¦ćƒ¼ć‚¶ćƒ¼ć®å½¹å‰²ć‚’ćƒ€ć‚¦ćƒ³ć‚°ćƒ¬ćƒ¼ćƒ‰ć§ćć¾ć›ć‚“ć€‚ć—ćŸćŒć£ć¦ć€ē¾åœØć®ćƒ¦ćƒ¼ć‚¶ćƒ¼ćÆč”Øē¤ŗć•ć‚Œć¾ć›ć‚“ć€‚", + "userAlreadyExistsOAuthMessage": "ćƒ¦ćƒ¼ć‚¶ćƒ¼ćÆę—¢ć«OAuth2ćƒ¦ćƒ¼ć‚¶ćƒ¼ćØć—ć¦å­˜åœØć—ć¾ć™ć€‚", + "userAlreadyExistsWebMessage": "ćƒ¦ćƒ¼ć‚¶ćƒ¼ćÆę—¢ć«Webćƒ¦ćƒ¼ć‚¶ćƒ¼ćØć—ć¦å­˜åœØć—ć¾ć™ć€‚", + "oops": "おっと!", + "help": "ćƒ˜ćƒ«ćƒ—", + "goHomepage": "ćƒ›ćƒ¼ćƒ ćƒšćƒ¼ć‚øćøē§»å‹•", + "joinDiscord": "Discordć‚µćƒ¼ćƒćƒ¼ć«å‚åŠ ć™ć‚‹", + "seeDockerHub": "Docker Hub悒見悋", + "visitGithub": "GithubćƒŖćƒć‚øćƒˆćƒŖć‚’čØŖå•ć™ć‚‹", + "donate": "åÆ„ä»˜ć™ć‚‹", + "color": "色", + "sponsor": "ć‚¹ćƒćƒ³ć‚µćƒ¼", + "info": "ęƒ…å ±", + "pro": "Pro", + "page": "ćƒšćƒ¼ć‚ø", + "pages": "ćƒšćƒ¼ć‚ø", + "loading": "読込中...", + "addToDoc": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć«čæ½åŠ ", + "reset": "ćƒŖć‚»ćƒƒćƒˆ", + "apply": "適用", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "ćƒ—ćƒ©ć‚¤ćƒć‚·ćƒ¼ćƒćƒŖć‚·ćƒ¼", + "terms": "åˆ©ē”Øč¦ē“„", + "accessibility": "ć‚¢ć‚Æć‚»ć‚·ćƒ“ćƒŖćƒ†ć‚£", + "cookie": "CookiećƒćƒŖć‚·ćƒ¼", + "impressum": "č‘—ä½œęØ©åˆ©č€…ęƒ…å ±", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "ćƒ‘ć‚¤ćƒ—ćƒ©ć‚¤ćƒ³ćƒ”ćƒ‹ćƒ„ćƒ¼ (Beta)", + "uploadButton": "ć‚«ć‚¹ć‚æćƒ ć®ć‚¢ćƒƒćƒ—ćƒ­ćƒ¼ćƒ‰", + "configureButton": "設定", + "defaultOption": "ć‚«ć‚¹ć‚æćƒ ", + "submitButton": "送俔", + "help": "ćƒ‘ć‚¤ćƒ—ćƒ©ć‚¤ćƒ³ć®ćƒ˜ćƒ«ćƒ—", + "scanHelp": "ćƒ•ć‚©ćƒ«ćƒ€ ć‚¹ć‚­ćƒ£ćƒ³ć®ćƒ˜ćƒ«ćƒ—", + "deletePrompt": "ćƒ‘ć‚¤ćƒ—ćƒ©ć‚¤ćƒ³ć‚’å‰Šé™¤ć—ć¦ć‚‚ć‚ˆć‚ć—ć„ć§ć™ć‹", + "tags": "automate,sequence,scripted,batch-process", + "title": "ćƒ‘ć‚¤ćƒ—ćƒ©ć‚¤ćƒ³" + }, + "pipelineOptions": { + "header": "ćƒ‘ć‚¤ćƒ—ćƒ©ć‚¤ćƒ³čØ­å®š", + "pipelineNameLabel": "ćƒ‘ć‚¤ćƒ—ćƒ©ć‚¤ćƒ³å", + "saveSettings": "å‹•ä½œčØ­å®šć®äæå­˜", + "pipelineNamePrompt": "ć“ć“ć«ćƒ‘ć‚¤ćƒ—ćƒ©ć‚¤ćƒ³åć‚’å…„åŠ›", + "selectOperation": "å‹•ä½œć®éøęŠž", + "addOperationButton": "å‹•ä½œć®čæ½åŠ ", + "pipelineHeader": "ćƒ‘ć‚¤ćƒ—ćƒ©ć‚¤ćƒ³:", + "saveButton": "ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰", + "validateButton": "検証" + }, + "enterpriseEdition": { + "button": "Proć«ć‚¢ćƒƒćƒ—ć‚°ćƒ¬ćƒ¼ćƒ‰", + "warning": "ć“ć®ę©Ÿčƒ½ćÆProćƒ¦ćƒ¼ć‚¶ćƒ¼ć®ćæćŒåˆ©ē”Øć§ćć¾ć™ć€‚", + "yamlAdvert": "Stirling PDF Proは、YAMLę§‹ęˆćƒ•ć‚”ć‚¤ćƒ«ć‚„ćć®ä»–ć®SSOę©Ÿčƒ½ć‚’ć‚µćƒćƒ¼ćƒˆć—ć¦ć„ć¾ć™ć€‚", + "ssoAdvert": "ć‚ˆć‚Šå¤šćć®ćƒ¦ćƒ¼ć‚¶ćƒ¼ē®”ē†ę©Ÿčƒ½ć‚’ćŠęŽ¢ć—ć§ć™ć‹ļ¼Ÿ Stirling PDF Proć‚’ć”č¦§ćć ć•ć„" + }, + "analytics": { + "title": "Stirling PDFć‚’ć‚‚ć£ćØč‰Æćć—ćŸć„ć§ć™ć‹ļ¼Ÿ", + "paragraph1": "Stirling PDFć§ćÆć€č£½å“ć®ę”¹å–„ć«å½¹ē«‹ć¤åˆ†ęžę©Ÿčƒ½ć‚’ć‚Ŗćƒ—ćƒˆć‚¤ćƒ³ć—ć¦ć„ć¾ć™ć€‚å€‹äŗŗęƒ…å ±ć‚„ćƒ•ć‚”ć‚¤ćƒ«ć®å†…å®¹ć‚’čæ½č·”ć™ć‚‹ć“ćØćÆć‚ć‚Šć¾ć›ć‚“ć€‚", + "paragraph2": "Stirling-PDFć®ęˆé•·ć‚’ę”Æę“ć—ćƒ¦ćƒ¼ć‚¶ćƒ¼ć‚’ć‚ˆć‚Šę·±ćē†č§£ć§ćć‚‹ć‚ˆć†ć«åˆ†ęžć‚’ęœ‰åŠ¹ć«ć™ć‚‹ć“ćØć‚’ę¤œčØŽć—ć¦ćć ć•ć„ć€‚", + "enable": "åˆ†ęžć‚’ęœ‰åŠ¹ć«ć™ć‚‹", + "disable": "åˆ†ęžć‚’ē„”åŠ¹ć«ć™ć‚‹", + "settings": "config/settings.ymlćƒ•ć‚”ć‚¤ćƒ«ć§ć‚¢ćƒŠćƒŖćƒ†ć‚£ć‚Æć‚¹ć®čØ­å®šć‚’å¤‰ę›“ć§ćć¾ć™ć€‚" + }, + "navbar": { + "favorite": "ćŠę°—ć«å…„ć‚Š", + "recent": "ę–°ē€ćƒ»ęœ€ę–°ć®ę›“ę–°", + "darkmode": "ćƒ€ćƒ¼ć‚Æćƒ¢ćƒ¼ćƒ‰", + "language": "čØ€čŖž", + "settings": "設定", + "allTools": "ćƒ„ćƒ¼ćƒ«", + "multiTool": "ćƒžćƒ«ćƒćƒ„ćƒ¼ćƒ«", + "search": "検瓢", + "sections": { + "organize": "敓理", + "convertTo": "PDFćøå¤‰ę›", + "convertFrom": "PDFć‹ć‚‰å¤‰ę›", + "security": "ē½²åćØć‚»ć‚­ćƒ„ćƒŖćƒ†ć‚£", + "advance": "ć‚¢ćƒ‰ćƒćƒ³ć‚¹ćƒ‰", + "edit": "閲覧と編集", + "popular": "äŗŗę°—" + } + }, + "settings": { + "title": "設定", + "update": "åˆ©ē”ØåÆčƒ½ćŖć‚¢ćƒƒćƒ—ćƒ‡ćƒ¼ćƒˆ", + "updateAvailable": "ćƒćƒ¼ć‚øćƒ§ćƒ³ {0} ćŒć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć•ć‚Œć¦ć„ć¾ć™ć€‚ ę–°ć—ć„ćƒćƒ¼ć‚øćƒ§ćƒ³ ({1}) ćŒåˆ©ē”ØåÆčƒ½ć§ć™ć€‚", + "appVersion": "Appćƒćƒ¼ć‚øćƒ§ćƒ³:", + "downloadOption": { + "title": "ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ (zipä»„å¤–ć®å˜äø€ćƒ•ć‚”ć‚¤ćƒ«):", + "1": "åŒć˜ć‚¦ć‚£ćƒ³ćƒ‰ć‚¦ć§é–‹ć", + "2": "ę–°ć—ć„ć‚¦ć‚£ćƒ³ćƒ‰ć‚¦ć§é–‹ć", + "3": "ćƒ•ć‚”ć‚¤ćƒ«ć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰" + }, + "zipThreshold": "ć“ć®ćƒ•ć‚”ć‚¤ćƒ«ę•°ć‚’č¶…ćˆćŸćØćć«ćƒ•ć‚”ć‚¤ćƒ«ć‚’åœ§ēø®ć™ć‚‹", + "signOut": "ć‚µć‚¤ćƒ³ć‚¢ć‚¦ćƒˆ", + "accountSettings": "ć‚¢ć‚«ć‚¦ćƒ³ćƒˆčØ­å®š", + "bored": { + "help": "ć‚¤ćƒ¼ć‚¹ć‚æćƒ¼ć‚Øćƒƒć‚°ć‚²ćƒ¼ćƒ ć‚’ęœ‰åŠ¹ć«ć™ć‚‹" + }, + "cacheInputs": { + "name": "ćƒ•ć‚©ćƒ¼ćƒ ć®å…„åŠ›ć‚’äæå­˜ć™ć‚‹", + "help": "ä»„å‰ä½æē”Øć—ćŸå…„åŠ›ć‚’äæå­˜ć—ć€ę¬”å›žć‹ć‚‰ä½æē”Øć§ćć‚‹ć‚ˆć†ć«ć™ć‚‹ć€‚" + } + }, + "changeCreds": { + "title": "č³‡ę ¼ęƒ…å ±ć®å¤‰ę›“", + "header": "ć‚¢ć‚«ć‚¦ćƒ³ćƒˆć®č©³ē“°ć‚’ę›“ę–°ć™ć‚‹", + "changePassword": "ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®ćƒ­ć‚°ć‚¤ćƒ³čŖčØ¼ęƒ…å ±ć‚’ä½æē”Øć—ć¦ć„ć¾ć™ć€‚ę–°ć—ć„ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć‚’å…„åŠ›ć—ć¦ćć ć•ć„", + "newUsername": "ę–°ć—ć„ćƒ¦ćƒ¼ć‚¶ćƒ¼å", + "oldPassword": "ē¾åœØć®ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰", + "newPassword": "ę–°ć—ć„ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰", + "confirmNewPassword": "ę–°ć—ć„ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć®ē¢ŗčŖ", + "submit": "変曓を送俔" + }, + "account": { + "title": "ć‚¢ć‚«ć‚¦ćƒ³ćƒˆčØ­å®š", + "accountSettings": "ć‚¢ć‚«ć‚¦ćƒ³ćƒˆčØ­å®š", + "adminSettings": "ē®”ē†č€…čØ­å®š - ćƒ¦ćƒ¼ć‚¶ćƒ¼ć®č”Øē¤ŗćØčæ½åŠ ", + "userControlSettings": "ćƒ¦ćƒ¼ć‚¶ćƒ¼åˆ¶å¾”čØ­å®š", + "changeUsername": "ćƒ¦ćƒ¼ć‚¶ćƒ¼åć‚’å¤‰ę›“", + "newUsername": "ę–°ć—ć„ćƒ¦ćƒ¼ć‚¶ćƒ¼ćƒćƒ¼ćƒ ", + "password": "ē¢ŗčŖē”Øćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰", + "oldPassword": "ę—§ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰", + "newPassword": "ę–°ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰", + "changePassword": "ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć®å¤‰ę›“", + "confirmNewPassword": "ę–°ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć®ē¢ŗčŖ", + "signOut": "ć‚µć‚¤ćƒ³ć‚¢ć‚¦ćƒˆ", + "yourApiKey": "ć‚ćŖćŸć®APIć‚­ćƒ¼", + "syncTitle": "ćƒ–ćƒ©ć‚¦ć‚¶čØ­å®šć‚’ć‚¢ć‚«ć‚¦ćƒ³ćƒˆćØåŒęœŸć™ć‚‹", + "settingsCompare": "čØ­å®šęÆ”č¼ƒ:", + "property": "ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£", + "webBrowserSettings": "Webćƒ–ćƒ©ć‚¦ć‚¶čØ­å®š", + "syncToBrowser": "ć‚¢ć‚«ć‚¦ćƒ³ćƒˆć®åŒęœŸ -> ćƒ–ćƒ©ć‚¦ć‚¶", + "syncToAccount": "ć‚¢ć‚«ć‚¦ćƒ³ćƒˆć®åŒęœŸ <- ćƒ–ćƒ©ć‚¦ć‚¶" + }, + "adminUserSettings": { + "title": "ćƒ¦ćƒ¼ć‚¶ćƒ¼åˆ¶å¾”čØ­å®š", + "header": "ē®”ē†č€…ćƒ¦ćƒ¼ć‚¶ćƒ¼åˆ¶å¾”čØ­å®š", + "admin": "箔理者", + "user": "ćƒ¦ćƒ¼ć‚¶ćƒ¼", + "addUser": "ę–°ć—ć„ćƒ¦ćƒ¼ć‚¶ć‚’čæ½åŠ ", + "deleteUser": "ćƒ¦ćƒ¼ć‚¶ć®å‰Šé™¤", + "confirmDeleteUser": "ćƒ¦ćƒ¼ć‚¶ć‚’ęœ¬å½“ć«å‰Šé™¤ć—ć¾ć™ć‹ļ¼Ÿ", + "confirmChangeUserStatus": "ćƒ¦ćƒ¼ć‚¶ćƒ¼ć‚’ē„”åŠ¹/ęœ‰åŠ¹ć«ć™ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć‹ļ¼Ÿ", + "usernameInfo": "ćƒ¦ćƒ¼ć‚¶ćƒ¼åć«ćÆć€ę–‡å­—ć€ę•°å­—ć€ćŠć‚ˆć³ę¬”ć®ē‰¹ę®Šę–‡å­— @._+- ć®ćæć‚’å«ć‚ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ć¾ćŸćÆć€ęœ‰åŠ¹ćŖé›»å­ćƒ”ćƒ¼ćƒ« ć‚¢ćƒ‰ćƒ¬ć‚¹ć§ć‚ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚", + "roles": "役割", + "role": "役割", + "actions": "ć‚¢ć‚Æć‚·ćƒ§ćƒ³", + "apiUser": "é™å®šć•ć‚ŒćŸAPIćƒ¦ćƒ¼ć‚¶ćƒ¼", + "extraApiUser": "čæ½åŠ ć®åˆ¶é™ä»˜ćAPIćƒ¦ćƒ¼ć‚¶ćƒ¼", + "webOnlyUser": "ć‚¦ć‚§ćƒ–å°‚ē”Øćƒ¦ćƒ¼ć‚¶ćƒ¼", + "demoUser": "ćƒ‡ćƒ¢ćƒ¦ćƒ¼ć‚¶ćƒ¼ (ć‚«ć‚¹ć‚æćƒ čØ­å®šćŖć—)", + "internalApiUser": "å†…éƒØAPIćƒ¦ćƒ¼ć‚¶ćƒ¼", + "forceChange": "ćƒ­ć‚°ć‚¤ćƒ³ę™‚ć«ćƒ¦ćƒ¼ć‚¶ćƒ¼å/ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć‚’å¼·åˆ¶ēš„ć«å¤‰ę›“ć™ć‚‹", + "submit": "ćƒ¦ćƒ¼ć‚¶ćƒ¼ć®äæå­˜", + "changeUserRole": "ćƒ¦ćƒ¼ć‚¶ćƒ¼ć®å½¹å‰²ć‚’å¤‰ę›“ć™ć‚‹", + "authenticated": "čŖčØ¼ęøˆ", + "editOwnProfil": "ćƒ—ćƒ­ćƒ•ć‚£ćƒ¼ćƒ«ć®ē·Øé›†", + "enabledUser": "ęœ‰åŠ¹ćŖćƒ¦ćƒ¼ć‚¶ćƒ¼", + "disabledUser": "ē„”åŠ¹ćŖćƒ¦ćƒ¼ć‚¶ćƒ¼", + "activeUsers": "ć‚¢ć‚Æćƒ†ć‚£ćƒ–ćƒ¦ćƒ¼ć‚¶ćƒ¼:", + "disabledUsers": "ē„”åŠ¹ćŖćƒ¦ćƒ¼ć‚¶ćƒ¼:", + "totalUsers": "ćƒ¦ćƒ¼ć‚¶ćƒ¼åˆčØˆ:", + "lastRequest": "ęœ€å¾Œć®ćƒŖć‚Æć‚Øć‚¹ćƒˆ", + "usage": "ä½æē”ØēŠ¶ę³ć‚’č”Øē¤ŗ" + }, + "endpointStatistics": { + "title": "ć‚Øćƒ³ćƒ‰ćƒć‚¤ćƒ³ćƒˆēµ±čØˆ", + "header": "ć‚Øćƒ³ćƒ‰ćƒć‚¤ćƒ³ćƒˆēµ±čØˆ", + "top10": "惈惃惗10", + "top20": "惈惃惗20", + "all": "すべて", + "refresh": "ꛓꖰ", + "includeHomepage": "ćƒ›ćƒ¼ćƒ ćƒšćƒ¼ć‚øć‚’å«ć‚ć‚‹ ('/')", + "includeLoginPage": "ćƒ­ć‚°ć‚¤ćƒ³ćƒšćƒ¼ć‚øć‚’å«ć‚ć‚‹ ('/login')", + "totalEndpoints": "ć‚Øćƒ³ćƒ‰ćƒć‚¤ćƒ³ćƒˆåˆčØˆ", + "totalVisits": "ē·čØŖå•ę•°", + "showing": "蔨示", + "selectedVisits": "éøęŠžć•ć‚ŒćŸčØŖå•å…ˆ", + "endpoint": "ć‚Øćƒ³ćƒ‰ćƒć‚¤ćƒ³ćƒˆ", + "visits": "čØŖå•", + "percentage": "ęÆ”ēŽ‡", + "loading": "読込中...", + "failedToLoad": "ć‚Øćƒ³ćƒ‰ćƒć‚¤ćƒ³ćƒˆćƒ‡ćƒ¼ć‚æć®ćƒ­ćƒ¼ćƒ‰ć«å¤±ę•—ć—ć¾ć—ćŸć€‚ę›“ę–°ć—ć¦ćæć¦ćć ć•ć„ć€‚", + "home": "ćƒ›ćƒ¼ćƒ ", + "login": "ćƒ­ć‚°ć‚¤ćƒ³", + "top": "惈惃惗", + "numberOfVisits": "čØŖå•å›žę•°", + "visitsTooltip": "čØŖå•ę•°: {0} (合計の{1}%)", + "retry": "å†č©¦č”Œ" + }, + "database": { + "title": "ćƒ‡ćƒ¼ć‚æćƒ™ćƒ¼ć‚¹ć®ć‚¤ćƒ³ćƒćƒ¼ćƒˆ/ć‚Øć‚Æć‚¹ćƒćƒ¼ćƒˆ", + "header": "ćƒ‡ćƒ¼ć‚æćƒ™ćƒ¼ć‚¹ć®ć‚¤ćƒ³ćƒćƒ¼ćƒˆ/ć‚Øć‚Æć‚¹ćƒćƒ¼ćƒˆ", + "fileName": "ćƒ•ć‚”ć‚¤ćƒ«å", + "creationDate": "ä½œęˆę—„", + "fileSize": "ćƒ•ć‚”ć‚¤ćƒ«ć‚µć‚¤ć‚ŗ", + "deleteBackupFile": "ćƒćƒƒć‚Æć‚¢ćƒƒćƒ—ćƒ•ć‚”ć‚¤ćƒ«ć®å‰Šé™¤", + "importBackupFile": "ćƒćƒƒć‚Æć‚¢ćƒƒćƒ—ćƒ•ć‚”ć‚¤ćƒ«ć‚’ć‚¤ćƒ³ćƒćƒ¼ćƒˆ", + "createBackupFile": "ćƒćƒƒć‚Æć‚¢ćƒƒćƒ—ćƒ•ć‚”ć‚¤ćƒ«ć®ä½œęˆ", + "downloadBackupFile": "ćƒćƒƒć‚Æć‚¢ćƒƒćƒ—ćƒ•ć‚”ć‚¤ćƒ«ć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰", + "info_1": "ćƒ‡ćƒ¼ć‚æć‚’ć‚¤ćƒ³ćƒćƒ¼ćƒˆć™ć‚‹éš›ć«ćÆć€ę­£ć—ć„ę§‹é€ ć‚’ē¢ŗäæć™ć‚‹ć“ćØćŒę„µć‚ć¦é‡č¦ć§ć™ć€‚äøę˜ŽćŖē‚¹ćŒć‚ć‚‹å “åˆćÆć€å°‚é–€å®¶ć®ć‚¢ćƒ‰ćƒć‚¤ć‚¹ć‚„ć‚µćƒćƒ¼ćƒˆć‚’å—ć‘ć¦ćć ć•ć„ć€‚ę§‹é€ äøŠć®ć‚Øćƒ©ćƒ¼ćÆć€ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć®čŖ¤å‹•ä½œć‚’å¼•ćčµ·ć“ć™åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚", + "info_2": "ćƒ•ć‚”ć‚¤ćƒ«åćÆć‚¢ćƒƒćƒ—ćƒ­ćƒ¼ćƒ‰ę™‚ć«ćÆé–¢äæ‚ć‚ć‚Šć¾ć›ć‚“ć€‚ć‚¢ćƒƒćƒ—ćƒ­ćƒ¼ćƒ‰å¾Œć«backup_user_yyyyMMddHHmm.sqlćØć„ć†å½¢å¼ć«ćƒŖćƒćƒ¼ćƒ ć•ć‚Œć€äø€č²«ć—ćŸå‘½åč¦å‰‡ćŒäæčØ¼ć•ć‚Œć¾ć™ć€‚", + "submit": "ćƒćƒƒć‚Æć‚¢ćƒƒćƒ—ć‚’ć‚¤ćƒ³ćƒćƒ¼ćƒˆ", + "importIntoDatabaseSuccessed": "ćƒ‡ćƒ¼ć‚æćƒ™ćƒ¼ć‚¹ćøć®ć‚¤ćƒ³ćƒćƒ¼ćƒˆć«ęˆåŠŸ", + "backupCreated": "ćƒ‡ćƒ¼ć‚æćƒ™ćƒ¼ć‚¹ć®ćƒćƒƒć‚Æć‚¢ćƒƒćƒ—ć«ęˆåŠŸć—ć¾ć—ćŸ", + "fileNotFound": "ćƒ•ć‚”ć‚¤ćƒ«ćŒč¦‹ć¤ć‹ć‚Šć¾ć›ć‚“", + "fileNullOrEmpty": "ćƒ•ć‚”ć‚¤ćƒ«ćÆnullć¾ćŸćÆē©ŗć§ć‚ć£ć¦ćÆćŖć‚Šć¾ć›ć‚“", + "failedImportFile": "ćƒ•ć‚”ć‚¤ćƒ«ć®ć‚¤ćƒ³ćƒćƒ¼ćƒˆć«å¤±ę•—", + "notSupported": "ć“ć®ę©Ÿčƒ½ćÆćƒ‡ćƒ¼ć‚æćƒ™ćƒ¼ć‚¹ęŽ„ē¶šć§ćÆä½æē”Øć§ćć¾ć›ć‚“ć€‚" + }, + "session": { + "expired": "ć‚»ćƒƒć‚·ćƒ§ćƒ³ćŒęœŸé™åˆ‡ć‚Œć§ć™ć€‚ćƒšćƒ¼ć‚øć‚’ę›“ę–°ć—ć¦ć‚‚ć†äø€åŗ¦ćŠč©¦ć—ćć ć•ć„ć€‚", + "refreshPage": "ćƒšćƒ¼ć‚øć‚’ę›“ę–°" + }, + "home": { + "desc": "PDFć®ć‚ć‚‰ć‚†ć‚‹ćƒ‹ćƒ¼ć‚ŗć«åÆ¾åæœć™ć‚‹ćƒ­ćƒ¼ć‚«ćƒ«ćƒ›ć‚¹ćƒ†ć‚£ćƒ³ć‚°ć•ć‚ŒćŸē·åˆēŖ“å£ć§ć™ć€‚", + "searchBar": "機能検瓢...", + "viewPdf": { + "title": "PDFの蔨示/編集", + "desc": "č”Øē¤ŗć€ę³Øé‡ˆć€ćƒ†ć‚­ć‚¹ćƒˆć‚„ē”»åƒć®čæ½åŠ " + }, + "setFavorites": "ćŠę°—ć«å…„ć‚Šć‚’čØ­å®š", + "hideFavorites": "ćŠę°—ć«å…„ć‚Šć‚’éš ć™", + "showFavorites": "ćŠę°—ć«å…„ć‚Šć‚’č”Øē¤ŗ", + "legacyHomepage": "ę—§ćƒ›ćƒ¼ćƒ ćƒšćƒ¼ć‚ø", + "newHomePage": "ę–°ć—ć„ćƒ›ćƒ¼ćƒ ćƒšćƒ¼ć‚øć‚’č©¦ć—ć¦ćć ć•ć„ļ¼", + "alphabetical": "ć‚¢ćƒ«ćƒ•ć‚”ćƒ™ćƒƒćƒˆé †", + "globalPopularity": "ć‚°ćƒ­ćƒ¼ćƒćƒ«äŗŗę°—", + "sortBy": "ć‚½ćƒ¼ćƒˆé †:", + "multiTool": { + "title": "PDFćƒžćƒ«ćƒćƒ„ćƒ¼ćƒ«", + "desc": "ćƒšćƒ¼ć‚øć®ēµåˆć€å›žč»¢ć€äø¦ć¹ę›æćˆć€å‰Šé™¤ć—ć¾ć™ć€‚" + }, + "merge": { + "title": "結合", + "desc": "複ꕰ恮PDF悒1ć¤ć«ēµåˆć—ć¾ć™ć€‚" + }, + "split": { + "title": "分割", + "desc": "PDFć‚’č¤‡ę•°ć®ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć«åˆ†å‰²ć—ć¾ć™ć€‚" + }, + "rotate": { + "title": "å›žč»¢", + "desc": "PDFć‚’å›žč»¢ć—ć¾ć™ć€‚" + }, + "imageToPdf": { + "title": "ē”»åƒć‚’PDFć«å¤‰ę›", + "desc": "ē”»åƒ (PNG, JPEG, GIF) 悒PDFć«å¤‰ę›ć—ć¾ć™ć€‚" + }, + "pdfToImage": { + "title": "PDFć‚’ē”»åƒć«å¤‰ę›", + "desc": "PDFć‚’ē”»åƒ (PNG, JPEG, GIF) ć«å¤‰ę›ć—ć¾ć™ć€‚" + }, + "pdfOrganiser": { + "title": "敓理", + "desc": "ćƒšćƒ¼ć‚øć®å‰Šé™¤/äø¦ć¹ę›æćˆć—ć¾ć™ć€‚" + }, + "addImage": { + "title": "ē”»åƒć®čæ½åŠ ", + "desc": "PDFäøŠć®ä»»ę„ć®å “ę‰€ć«ē”»åƒć‚’čæ½åŠ ć—ć¾ć™ć€‚" + }, + "watermark": { + "title": "é€ć‹ć—ć®čæ½åŠ ", + "desc": "PDFć«ē‹¬č‡Ŗć®é€ć‹ć—ć‚’čæ½åŠ ć—ć¾ć™ć€‚" + }, + "permissions": { + "title": "権限の変曓", + "desc": "PDFの権限を変曓します。" + }, + "removePages": { + "title": "削除", + "desc": "PDFć‹ć‚‰äøč¦ćŖćƒšćƒ¼ć‚øć‚’å‰Šé™¤ć—ć¾ć™ć€‚" + }, + "addPassword": { + "title": "ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć®čæ½åŠ ", + "desc": "PDFć‚’ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć§ęš—å·åŒ–ć—ć¾ć™ć€‚" + }, + "removePassword": { + "title": "ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć®å‰Šé™¤", + "desc": "PDFć‹ć‚‰ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć®å‰Šé™¤ć—ć¾ć™ć€‚" + }, + "compressPdfs": { + "title": "圧縮", + "desc": "PDFć‚’åœ§ēø®ć—ć¦ćƒ•ć‚”ć‚¤ćƒ«ć‚µć‚¤ć‚ŗć‚’å°ć•ćć—ć¾ć™ć€‚" + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "ćƒ”ć‚æćƒ‡ćƒ¼ć‚æć®å¤‰ę›“", + "desc": "PDFć®ćƒ”ć‚æćƒ‡ćƒ¼ć‚æć‚’å¤‰ę›“/削除/čæ½åŠ ć—ć¾ć™ć€‚" + }, + "fileToPDF": { + "title": "ćƒ•ć‚”ć‚¤ćƒ«ć‚’PDFć«å¤‰ę›", + "desc": "ć»ć¼ć™ć¹ć¦ć®ćƒ•ć‚”ć‚¤ćƒ«ć‚’PDFć«å¤‰ę›ć—ć¾ć™ć€‚ (DOCX, PNG, XLS, PPT, TXTなど)" + }, + "ocr": { + "title": "OCR / ć‚ÆćƒŖćƒ¼ćƒ³ć‚¢ćƒƒćƒ—", + "desc": "ć‚ÆćƒŖćƒ¼ćƒ³ć‚¢ćƒƒćƒ—ćÆPDFå†…ć®ē”»åƒć‹ć‚‰ćƒ†ć‚­ć‚¹ćƒˆć‚’ę¤œå‡ŗć—ć¦ćƒ†ć‚­ć‚¹ćƒˆćØć—ć¦å†čæ½åŠ ć—ć¾ć™ć€‚" + }, + "extractImages": { + "title": "ē”»åƒć®ęŠ½å‡ŗ", + "desc": "PDFć‹ć‚‰ć™ć¹ć¦ć®ē”»åƒć‚’ęŠ½å‡ŗć—ć¦zipć§äæå­˜ć—ć¾ć™ć€‚" + }, + "pdfToPDFA": { + "title": "PDF悒PDF/Ać«å¤‰ę›", + "desc": "é•·ęœŸäæå­˜ć®ćŸć‚ć«PDF悒PDF/Ać«å¤‰ę›ć€‚" + }, + "PDFToWord": { + "title": "PDF悒Wordć«å¤‰ę›", + "desc": "PDF悒Wordå½¢å¼ć«å¤‰ę›ć—ć¾ć™ć€‚ (DOC, DOCX ćŠć‚ˆć³ ODT)" + }, + "PDFToPresentation": { + "title": "PDFć‚’ćƒ—ćƒ¬ć‚¼ćƒ³ćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć«å¤‰ę›", + "desc": "PDFć‚’ćƒ—ćƒ¬ć‚¼ćƒ³ćƒ†ćƒ¼ć‚·ćƒ§ćƒ³å½¢å¼ć«å¤‰ę›ć—ć¾ć™ć€‚ (PPT, PPTX ćŠć‚ˆć³ ODP)" + }, + "PDFToText": { + "title": "PDF悒Text/RTFć«å¤‰ę›", + "desc": "PDF悒TextまたはRTFå½¢å¼ć«å¤‰ę›ć—ć¾ć™ć€‚" + }, + "PDFToHTML": { + "title": "PDF悒HTMLć«å¤‰ę›", + "desc": "PDF悒HTMLå½¢å¼ć«å¤‰ę›ć—ć¾ć™ć€‚" + }, + "PDFToXML": { + "title": "PDF悒XMLć«å¤‰ę›", + "desc": "PDF悒XMLå½¢å¼ć«å¤‰ę›ć—ć¾ć™ć€‚" + }, + "ScannerImageSplit": { + "title": "ć‚¹ć‚­ćƒ£ćƒ³ć•ć‚ŒćŸē”»åƒć®ę¤œå‡ŗ/分割", + "desc": "1ęžšć®ē”»åƒ/PDFć‹ć‚‰č¤‡ę•°ć®å†™ēœŸć‚’åˆ†å‰²ć—ć¾ć™ć€‚" + }, + "sign": { + "title": "ē½²å", + "desc": "ę‰‹ę›øćć€ćƒ†ć‚­ć‚¹ćƒˆć¾ćŸćÆē”»åƒć«ć‚ˆć£ć¦PDFć«ē½²åć‚’čæ½åŠ ć—ć¾ć™ć€‚" + }, + "flatten": { + "title": "平坦化", + "desc": "PDFć‹ć‚‰ć‚¤ćƒ³ć‚æćƒ©ć‚Æćƒ†ć‚£ćƒ–ćŖč¦ē“ ćØćƒ•ć‚©ćƒ¼ćƒ ć‚’ć™ć¹ć¦å‰Šé™¤ć—ć¾ć™ć€‚" + }, + "repair": { + "title": "修復", + "desc": "ē “ęć—ćŸPDFの修復を試みます。" + }, + "removeBlanks": { + "title": "ē©ŗē™½ćƒšćƒ¼ć‚øć®å‰Šé™¤", + "desc": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‹ć‚‰ē©ŗē™½ćƒšćƒ¼ć‚øć‚’ę¤œå‡ŗć—ć¦å‰Šé™¤ć—ć¾ć™ć€‚" + }, + "removeAnnotations": { + "title": "ę³Øé‡ˆć®å‰Šé™¤", + "desc": "PDFć‹ć‚‰ć™ć¹ć¦ć®ć‚³ćƒ”ćƒ³ćƒˆćƒ»ę³Øé‡ˆć‚’å‰Šé™¤ć—ć¾ć™ć€‚" + }, + "compare": { + "title": "ęÆ”č¼ƒ", + "desc": "2恤恮PDFć‚’ęÆ”č¼ƒć—ć¦č”Øē¤ŗć—ć¾ć™ć€‚" + }, + "certSign": { + "title": "čØ¼ę˜Žę›øć«ć‚ˆć‚‹ē½²å", + "desc": "čØ¼ę˜Žę›ø/ć‚­ćƒ¼ć‚’ä½æē”Øć—ć¦PDFć«ē½²åć—ć¾ć™ć€‚ (PEM/P12)" + }, + "removeCertSign": { + "title": "čØ¼ę˜Žę›øć®ē½²åć‚’å‰Šé™¤ć™ć‚‹", + "desc": "PDFć‹ć‚‰čØ¼ę˜Žę›øē½²åć‚’å‰Šé™¤ć™ć‚‹" + }, + "pageLayout": { + "title": "ćƒžćƒ«ćƒćƒšćƒ¼ć‚øćƒ¬ć‚¤ć‚¢ć‚¦ćƒˆ", + "desc": "PDFć®č¤‡ę•°ć®ćƒšćƒ¼ć‚øć‚’1ćƒšćƒ¼ć‚øć«ēµåˆć—ć¾ć™ć€‚" + }, + "scalePages": { + "title": "ćƒšćƒ¼ć‚øć®ēø®å°ŗć®čŖæę•“", + "desc": "ćƒšćƒ¼ć‚øć‚„ć‚³ćƒ³ćƒ†ćƒ³ćƒ„ć®ēø®å°ŗć‚’å¤‰ę›“ć—ć¾ć™ć€‚" + }, + "pipeline": { + "title": "ćƒ‘ć‚¤ćƒ—ćƒ©ć‚¤ćƒ³", + "desc": "ćƒ‘ć‚¤ćƒ—ćƒ©ć‚¤ćƒ³ć‚¹ć‚ÆćƒŖćƒ—ćƒˆć‚’å®šē¾©ć—ć¦PDFäøŠć§č¤‡ę•°ć®ć‚¢ć‚Æć‚·ćƒ§ćƒ³ć‚’å®Ÿč”Œć—ć¾ć™ć€‚" + }, + "add-page-numbers": { + "title": "ćƒšćƒ¼ć‚øē•Ŗå·ć®čæ½åŠ ", + "desc": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆå…Øä½“ć®čØ­å®šć•ć‚ŒćŸå “ę‰€ć«ćƒšćƒ¼ć‚øē•Ŗå·ć‚’čæ½åŠ ć—ć¾ć™ć€‚" + }, + "auto-rename": { + "title": "PDFćƒ•ć‚”ć‚¤ćƒ«åć®č‡Ŗå‹•å¤‰ę›“", + "desc": "ę¤œå‡ŗć•ć‚ŒćŸćƒ˜ćƒƒćƒ€ćƒ¼ć«åŸŗć„ć„ć¦PDFćƒ•ć‚”ć‚¤ćƒ«ć®åå‰ć‚’č‡Ŗå‹•ēš„ć«å¤‰ę›“ć—ć¾ć™ć€‚" + }, + "adjust-contrast": { + "title": "色/ć‚³ćƒ³ćƒˆćƒ©ć‚¹ćƒˆć®čŖæę•“", + "desc": "PDFć®ć‚³ćƒ³ćƒˆćƒ©ć‚¹ćƒˆć€å½©åŗ¦ć€ę˜Žć‚‹ć•ć‚’čŖæę•“ć—ć¾ć™ć€‚" + }, + "crop": { + "title": "PDFć®ćƒˆćƒŖćƒŸćƒ³ć‚°", + "desc": "PDFć‚’ćƒˆćƒŖćƒŸćƒ³ć‚°ć—ć¦ć‚µć‚¤ć‚ŗć‚’ēø®å°ć—ć¾ć™ (ćƒ†ć‚­ć‚¹ćƒˆćÆē¶­ęŒć—ć¾ć™ļ¼)怂" + }, + "autoSplitPDF": { + "title": "ćƒšćƒ¼ć‚øć®č‡Ŗå‹•åˆ†å‰²", + "desc": "ćƒšćƒ¼ć‚øåˆ†å‰²ē”ØQRć‚³ćƒ¼ćƒ‰ć‚’ä½æē”Øć—ćŸć‚¹ć‚­ćƒ£ćƒ³ć—ćŸPDFć‚’č‡Ŗå‹•åˆ†å‰²ć—ć¾ć™ć€‚" + }, + "sanitizePdf": { + "title": "ć‚µćƒ‹ć‚æć‚¤ć‚ŗ", + "desc": "PDFćƒ•ć‚”ć‚¤ćƒ«ć‹ć‚‰ć‚¹ć‚ÆćƒŖćƒ—ćƒˆć‚„ćć®ä»–ć®č¦ē“ ć‚’å‰Šé™¤ć—ć¾ć™ć€‚" + }, + "URLToPDF": { + "title": "URL/Webć‚µć‚¤ćƒˆć‚’PDFć«å¤‰ę›", + "desc": "恂悉悆悋http(s)URL悒PDFć«å¤‰ę›ć—ć¾ć™ć€‚" + }, + "HTMLToPDF": { + "title": "HTML悒PDFć«å¤‰ę›", + "desc": "HTMLćƒ•ć‚”ć‚¤ćƒ«ć¾ćŸćÆzip悒PDFć«å¤‰ę›ć—ć¾ć™ć€‚" + }, + "MarkdownToPDF": { + "title": "Markdown悒PDFć«å¤‰ę›", + "desc": "恂悉悆悋Markdownćƒ•ć‚”ć‚¤ćƒ«ć‚’PDFć«å¤‰ę›ć—ć¾ć™ć€‚" + }, + "PDFToMarkdown": { + "title": "PDF悒Markdownć«å¤‰ę›", + "desc": "恂悉悆悋PDF悒Markdownć«å¤‰ę›ć—ć¾ć™ć€‚" + }, + "getPdfInfo": { + "title": "PDFć®ć™ć¹ć¦ć®ęƒ…å ±ć‚’å…„ę‰‹", + "desc": "PDFć®ć‚ć‚‰ć‚†ć‚‹ęƒ…å ±ć‚’å–å¾—ć—ć¾ć™ć€‚" + }, + "extractPage": { + "title": "ćƒšćƒ¼ć‚øć®ęŠ½å‡ŗ", + "desc": "PDFć‹ć‚‰éøęŠžć—ćŸćƒšćƒ¼ć‚øć‚’ęŠ½å‡ŗć—ć¾ć™ć€‚" + }, + "PdfToSinglePage": { + "title": "PDFć‚’å˜äø€ć®å¤§ććŖćƒšćƒ¼ć‚øć«å¤‰ę›", + "desc": "PDFć®ć™ć¹ć¦ć®ćƒšćƒ¼ć‚øć‚’1ć¤ć®å¤§ććŖå˜äø€ćƒšćƒ¼ć‚øć«ēµåˆć—ć¾ć™" + }, + "showJS": { + "title": "JavaScriptを蔨示", + "desc": "PDFć«ęŒæå…„ć•ć‚ŒćŸJavaScriptć‚’ę¤œē“¢ć—ć¦č”Øē¤ŗć—ć¾ć™ć€‚" + }, + "autoRedact": { + "title": "č‡Ŗå‹•å¢Øę¶ˆć—", + "desc": "å…„åŠ›ć—ćŸćƒ†ć‚­ć‚¹ćƒˆć«åŸŗć„ć„ć¦PDFå†…ć®ćƒ†ć‚­ć‚¹ćƒˆć‚’č‡Ŗå‹•ć§å¢Øę¶ˆć—(é»’å”—ć‚Š)ます。" + }, + "redact": { + "title": "ę‰‹å‹•å¢Øę¶ˆć—", + "desc": "éøęŠžć—ćŸćƒ†ć‚­ć‚¹ćƒˆć€ęē”»ć—ćŸå›³å½¢ć€éøęŠžć—ćŸćƒšćƒ¼ć‚øć«åŸŗć„ć„ć¦PDFć‚’å¢Øę¶ˆć—ć¾ć™ć€‚" + }, + "tableExtraxt": { + "title": "PDF悒CSVć«å¤‰ę›", + "desc": "PDFć‹ć‚‰č”Øć‚’ęŠ½å‡ŗć—CSVć«å¤‰ę›ć—ć¾ć™ć€‚" + }, + "autoSizeSplitPDF": { + "title": "ć‚µć‚¤ć‚ŗćƒ»ę•°ć«ć‚ˆć‚‹č‡Ŗå‹•åˆ†å‰²", + "desc": "ć‚µć‚¤ć‚ŗćƒ»ćƒšćƒ¼ć‚øę•°ć¾ćŸćÆćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆę•°ć«åŸŗć„ć„ć¦ć€1恤恮PDFć‚’č¤‡ę•°ć®ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć«åˆ†å‰²ć—ć¾ć™ć€‚" + }, + "overlay-pdfs": { + "title": "PDFć®ć‚Ŗćƒ¼ćƒćƒ¼ćƒ¬ć‚¤", + "desc": "PDFの上に刄のPDFć‚’é‡ć­ć¾ć™ć€‚" + }, + "split-by-sections": { + "title": "PDFć‚’ć‚»ć‚Æć‚·ćƒ§ćƒ³ć§åˆ†å‰²", + "desc": "PDFć®å„ćƒšćƒ¼ć‚øć‚’ēø¦ęØŖć«åˆ†å‰²ć—ć¾ć™ć€‚" + }, + "AddStampRequest": { + "title": "PDFć«ć‚¹ć‚æćƒ³ćƒ—ć‚’čæ½åŠ ", + "desc": "čØ­å®šć—ćŸä½ē½®ć«ćƒ†ć‚­ć‚¹ćƒˆć‚„ē”»åƒć®ć‚¹ć‚æćƒ³ćƒ—ć‚’čæ½åŠ ć§ćć¾ć™" + }, + "removeImagePdf": { + "title": "ē”»åƒć®å‰Šé™¤", + "desc": "PDFć‹ć‚‰ē”»åƒć‚’å‰Šé™¤ć—ć¦ćƒ•ć‚”ć‚¤ćƒ«ć‚µć‚¤ć‚ŗć‚’å°ć•ćć—ć¾ć™" + }, + "splitPdfByChapters": { + "title": "PDFć‚’ćƒćƒ£ćƒ—ć‚æćƒ¼ć”ćØć«åˆ†å‰²", + "desc": "ćƒćƒ£ćƒ—ć‚æćƒ¼ć®ę§‹é€ ć«åŸŗć„ć„ć¦PDFć‚’č¤‡ę•°ć®ćƒ•ć‚”ć‚¤ćƒ«ć«åˆ†å‰²ć—ć¾ć™" + }, + "validateSignature": { + "title": "PDFē½²åć®ę¤œčØ¼", + "desc": "PDFę–‡ę›øć®ćƒ‡ć‚øć‚æćƒ«ē½²åćØčØ¼ę˜Žę›øć‚’ę¤œčØ¼ć—ć¾ć™" + }, + "replaceColorPdf": { + "title": "č‰²ć®ē½®ę›ćØåč»¢", + "desc": "PDFå†…ć®ćƒ†ć‚­ć‚¹ćƒˆćØčƒŒę™Æć®č‰²ć‚’ē½®ćę›ćˆć€PDFć®ćƒ•ćƒ«ć‚«ćƒ©ćƒ¼ć‚’åč»¢ć—ć¦ćƒ•ć‚”ć‚¤ćƒ«ć‚µć‚¤ć‚ŗć‚’ēø®å°ć—ć¾ć™ć€‚" + } + }, + "viewPdf": { + "tags": "view,read,annotate,text,image", + "title": "PDFの蔨示/編集", + "header": "PDFを蔨示" + }, + "multiTool": { + "tags": "Multi Tool,Multi operation,UI,click drag,front end,client side,interactive,intractable,move,delete,migrate,divide", + "title": "PDFćƒžćƒ«ćƒćƒ„ćƒ¼ćƒ«", + "header": "PDFćƒžćƒ«ćƒćƒ„ćƒ¼ćƒ«", + "uploadPrompts": "ćƒ•ć‚”ć‚¤ćƒ«å", + "selectAll": "ć™ć¹ć¦éøęŠž", + "deselectAll": "éøęŠžć‚’č§£é™¤", + "selectPages": "ćƒšćƒ¼ć‚øéøęŠž", + "selectedPages": "éøęŠžć—ćŸćƒšćƒ¼ć‚ø", + "page": "ćƒšćƒ¼ć‚ø", + "deleteSelected": "éøęŠžé …ē›®ć‚’å‰Šé™¤", + "downloadAll": "ć‚Øć‚Æć‚¹ćƒćƒ¼ćƒˆ", + "downloadSelected": "éøęŠžé …ē›®ć‚’ć‚Øć‚Æć‚¹ćƒćƒ¼ćƒˆ", + "insertPageBreak": "ę”¹ćƒšćƒ¼ć‚øć‚’ęŒæå…„", + "addFile": "ćƒ•ć‚”ć‚¤ćƒ«ć‚’čæ½åŠ ", + "rotateLeft": "å·¦å›žč»¢", + "rotateRight": "å³å›žč»¢", + "split": "分割", + "moveLeft": "左に移動", + "moveRight": "å³ć«ē§»å‹•", + "delete": "削除", + "dragDropMessage": "éøęŠžć•ć‚ŒćŸćƒšćƒ¼ć‚ø", + "undo": "å…ƒć«ęˆ»ć™", + "redo": "ć‚„ć‚Šē›“ć™" + }, + "merge": { + "tags": "merge,Page operations,Back end,server side", + "title": "結合", + "header": "複ꕰ恮PDFć‚’ēµåˆ (2ćƒ•ć‚”ć‚¤ćƒ«ä»„äøŠ)", + "sortByName": "åå‰ć§äø¦ć¹ę›æćˆ", + "sortByDate": "ę—„ä»˜ć§äø¦ć¹ę›æćˆ", + "removeCertSign": "ēµåˆć•ć‚ŒćŸćƒ•ć‚”ć‚¤ćƒ«å†…ć®ćƒ‡ć‚øć‚æćƒ«ē½²åć‚’å‰Šé™¤ć—ć¾ć™ć‹ļ¼Ÿ", + "submit": "結合" + }, + "split": { + "tags": "Page operations,divide,Multi Page,cut,server side", + "title": "PDFć®åˆ†å‰²", + "header": "PDFć®åˆ†å‰²", + "desc": { + "1": "éøęŠžć™ć‚‹ē•Ŗå·ćÆåˆ†å‰²ć™ć‚‹ćƒšćƒ¼ć‚øē•Ŗå·ć§ć™ć€‚", + "2": "ć—ćŸćŒć£ć¦ć€1,3,7-9ć‚’éøęŠžć™ć‚‹ćØć€10ćƒšćƒ¼ć‚øć®ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆćŒä»„äø‹ć®ć‚ˆć†ć«6恤恮PDFć«åˆ†å‰²ć•ć‚Œć‚‹ć“ćØć«ćŖć‚Šć¾ć™ć€‚", + "3": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ #1: ćƒšćƒ¼ć‚ø 1", + "4": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ #2: ćƒšćƒ¼ć‚ø 2, 3", + "5": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ #3: ćƒšćƒ¼ć‚ø 4, 5, 6, 7", + "6": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ #4: ćƒšćƒ¼ć‚ø 8", + "7": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ #5: ćƒšćƒ¼ć‚ø 9", + "8": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ #6: ćƒšćƒ¼ć‚ø 10" + }, + "splitPages": "åˆ†å‰²ć™ć‚‹ćƒšćƒ¼ć‚øē•Ŗå·ć‚’å…„åŠ›:", + "submit": "分割" + }, + "rotate": { + "tags": "server side", + "title": "PDFć®å›žč»¢", + "header": "PDFć®å›žč»¢", + "selectAngle": "å›žč»¢č§’åŗ¦ć‚’éøęŠž (90åŗ¦ć®å€ę•°):", + "submit": "å›žč»¢" + }, + "imageToPdf": { + "tags": "conversion,img,jpg,picture,photo" + }, + "pdfToImage": { + "tags": "conversion,img,jpg,picture,photo", + "title": "PDFć‚’ē”»åƒć«å¤‰ę›", + "header": "PDFć‚’ē”»åƒć«å¤‰ę›", + "selectText": "ē”»åƒć®å½¢å¼", + "singleOrMultiple": "ē”»åƒå‡ŗåŠ›ć‚æć‚¤ćƒ—", + "single": "å˜äø€ć®å¤§ććŖē”»åƒ", + "multi": "č¤‡ę•°ć®ē”»åƒ", + "colorType": "ć‚«ćƒ©ćƒ¼ćƒ¢ćƒ¼ćƒ‰", + "color": "ć‚«ćƒ©ćƒ¼", + "grey": "ć‚°ćƒ¬ćƒ¼ć‚¹ć‚±ćƒ¼ćƒ«", + "blackwhite": "白黒 (ćƒ‡ćƒ¼ć‚æćŒå¤±ć‚ć‚Œć‚‹åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ļ¼)", + "submit": "å¤‰ę›", + "info": "PythonćŒć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć•ć‚Œć¦ć„ć¾ć›ć‚“ć€‚WebPć®å¤‰ę›ć«åæ…č¦ć§ć™ć€‚", + "placeholder": "(例:1,2,8态4,7,12-16态2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,even,odd,sort,move", + "title": "敓理", + "header": "PDFćƒšćƒ¼ć‚øć®ę•“ē†", + "submit": "ćƒšćƒ¼ć‚øć®ę•“ē†", + "mode": { + "_value": "ćƒ¢ćƒ¼ćƒ‰", + "1": "ć‚«ć‚¹ć‚æćƒ ćƒšćƒ¼ć‚øé †åŗ", + "2": "逆順", + "3": "ćƒ‡ćƒ„ćƒ—ćƒ¬ćƒƒć‚Æć‚¹ć‚½ćƒ¼ćƒˆ", + "4": "å°å†Šå­ć‚½ćƒ¼ćƒˆ", + "5": "ć‚µć‚¤ćƒ‰ć‚¹ćƒ†ćƒƒćƒå°å†Šå­ć‚½ćƒ¼ćƒˆ", + "6": "儇数-å¶ę•°åˆ†å‰²", + "7": "ęœ€åˆć«å‰Šé™¤", + "8": "ęœ€å¾Œć‚’å‰Šé™¤", + "9": "ęœ€åˆćØęœ€å¾Œć‚’å‰Šé™¤", + "10": "儇数-å¶ę•°ć®ēµåˆ", + "11": "ć™ć¹ć¦ć®ćƒšćƒ¼ć‚øć‚’č¤‡č£½" + }, + "placeholder": "(例:1,3,2または4-8,2,10-12または2n-1)" + }, + "addImage": { + "tags": "img,jpg,picture,photo", + "title": "ē”»åƒć®čæ½åŠ ", + "header": "PDFć«ē”»åƒć‚’čæ½åŠ ", + "everyPage": "å…Øćƒšćƒ¼ć‚øļ¼Ÿ", + "upload": "ē”»åƒć®čæ½åŠ ", + "submit": "ē”»åƒć®čæ½åŠ " + }, + "watermark": { + "tags": "Text,repeating,label,own,copyright,trademark,img,jpg,picture,photo", + "title": "é€ć‹ć—ć®čæ½åŠ ", + "header": "é€ć‹ć—ć®čæ½åŠ ", + "customColor": "ę–‡å­—č‰²ć®ć‚«ć‚¹ć‚æćƒ ", + "selectText": { + "1": "é€ć‹ć—ć‚’čæ½åŠ ć™ć‚‹PDFć‚’éøęŠž:", + "2": "é€ć‹ć—ć®ćƒ†ć‚­ć‚¹ćƒˆ:", + "3": "文字サイズ:", + "4": "å›žč»¢ (0-360):", + "5": "å¹…ć‚¹ćƒšćƒ¼ć‚¹ (å„é€ć‹ć—é–“ć®ę°“å¹³ę–¹å‘ć®ć‚¹ćƒšćƒ¼ć‚¹):", + "6": "é«˜ć•ć‚¹ćƒšćƒ¼ć‚¹ (å„é€ć‹ć—é–“ć®åž‚ē›“ę–¹å‘ć®ć‚¹ćƒšćƒ¼ć‚¹):", + "7": "äøé€ę˜Žåŗ¦ (0% - 100%):", + "8": "é€ć‹ć—ć®ēØ®é”ž:", + "9": "é€ć‹ć—ć®ē”»åƒ:", + "10": "PDF悒PDFć‚¤ćƒ”ćƒ¼ć‚øć«å¤‰ę›ć™ć‚‹" + }, + "submit": "é€ć‹ć—ć‚’čæ½åŠ ", + "type": { + "1": "ćƒ†ć‚­ć‚¹ćƒˆ", + "2": "ē”»åƒ" + } + }, + "permissions": { + "tags": "read,write,edit,print", + "title": "権限の変曓", + "header": "権限の変曓", + "warning": "č­¦å‘Šć€ć“ć‚Œć‚‰ć®ęØ©é™ć‚’å¤‰ę›“ć§ććŖć„ć‚ˆć†ć«ć™ć‚‹ćŸć‚ć€ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć®čæ½åŠ ćƒšćƒ¼ć‚øć§ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć‚’čØ­å®šć™ć‚‹ć“ćØć‚’ęŽØå„Øć—ć¾ć™ć€‚", + "selectText": { + "1": "権限を変曓するPDFć‚’éøęŠž", + "2": "ęØ©é™ć®čØ­å®š", + "3": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć®ēµ„ē«‹ć‚’ē¦ę­¢", + "4": "ć‚³ćƒ³ćƒ†ćƒ³ćƒ„ć®ęŠ½å‡ŗć‚’ē¦ę­¢", + "5": "ć‚¢ć‚Æć‚»ć‚·ćƒ“ćƒŖćƒ†ć‚£ć®ćŸć‚ć®ęŠ½å‡ŗć‚’ē¦ę­¢", + "6": "ćƒ•ć‚©ćƒ¼ćƒ ćøć®å…„åŠ›ć‚’ē¦ę­¢", + "7": "変曓を禁止", + "8": "ę³Øé‡ˆć®å¤‰ę›“ć‚’ē¦ę­¢", + "9": "å°åˆ·ć‚’ē¦ę­¢", + "10": "ē•°ćŖć‚‹å½¢å¼ć®å°åˆ·ć‚’ē¦ę­¢" + }, + "submit": "変曓" + }, + "removePages": { + "tags": "Remove pages,delete pages" + }, + "addPassword": { + "tags": "secure,security", + "title": "ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć®čæ½åŠ ", + "header": "ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć®čæ½åŠ  (ęš—å·åŒ–)", + "selectText": { + "1": "ęš—å·åŒ–ć™ć‚‹PDFć‚’éøęŠž", + "2": "ćƒ¦ćƒ¼ć‚¶ćƒ¼ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰", + "3": "ęš—å·åŒ–ć‚­ćƒ¼ć®é•·ć•", + "4": "å€¤ćŒå¤§ćć„ć»ć©å¼·åŠ›ć§ć™ćŒć€å€¤ćŒå°ć•ć„ć»ć©äŗ’ę›ę€§ćŒé«˜ććŖć‚Šć¾ć™ć€‚", + "5": "ęØ©é™ć®čØ­å®š (ę‰€ęœ‰č€…ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ćØć®ä½µē”Øć‚’ćŠć™ć™ć‚ć—ć¾ć™)", + "6": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć®ēµ„ē«‹ć‚’ē¦ę­¢", + "7": "ć‚³ćƒ³ćƒ†ćƒ³ćƒ„ć®ęŠ½å‡ŗć‚’ē¦ę­¢", + "8": "ć‚¢ć‚Æć‚»ć‚·ćƒ“ćƒŖćƒ†ć‚£ć®ćŸć‚ć®ęŠ½å‡ŗć‚’ē¦ę­¢", + "9": "ćƒ•ć‚©ćƒ¼ćƒ ćøć®å…„åŠ›ć‚’ē¦ę­¢", + "10": "変曓を禁止", + "11": "ę³Øé‡ˆć®å¤‰ę›“ć‚’ē¦ę­¢", + "12": "å°åˆ·ć‚’ē¦ę­¢", + "13": "ē•°ćŖć‚‹å½¢å¼ć®å°åˆ·ć‚’ē¦ę­¢", + "14": "ę‰€ęœ‰č€…ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰", + "15": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’é–‹ć„ćŸå¾Œć«å®Ÿč”Œć§ćć‚‹ę“ä½œć‚’åˆ¶é™ć—ć¾ć™ (ć™ć¹ć¦ć®ćƒŖćƒ¼ćƒ€ćƒ¼ć§ć‚µćƒćƒ¼ćƒˆć•ć‚Œć¦ć„ć‚‹ć‚ć‘ć§ćÆć‚ć‚Šć¾ć›ć‚“)", + "16": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’é–‹ćć“ćØć‚’åˆ¶é™ć—ć¾ć™" + }, + "submit": "ęš—å·åŒ–" + }, + "removePassword": { + "tags": "secure,Decrypt,security,unpassword,delete password", + "title": "ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć®å‰Šé™¤", + "header": "ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć®å‰Šé™¤ (復号化)", + "selectText": { + "1": "å¾©å·åŒ–ć™ć‚‹PDFć‚’éøęŠž", + "2": "ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰" + }, + "submit": "削除" + }, + "compressPdfs": { + "tags": "squish,small,tiny" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Title,author,date,creation,time,publisher,producer,stats", + "title": "ć‚æć‚¤ćƒˆćƒ«:", + "header": "ćƒ”ć‚æćƒ‡ćƒ¼ć‚æć®å¤‰ę›“", + "selectText": { + "1": "å¤‰ę›“ć—ćŸć„å¤‰ę•°ć‚’ē·Øé›†ć—ć¦ćć ć•ć„", + "2": "ć™ć¹ć¦ć®ćƒ”ć‚æćƒ‡ćƒ¼ć‚æć‚’å‰Šé™¤", + "3": "ć‚«ć‚¹ć‚æćƒ ćƒ”ć‚æćƒ‡ćƒ¼ć‚æć‚’č”Øē¤ŗ", + "4": "ćć®ä»–ć®ćƒ”ć‚æćƒ‡ćƒ¼ć‚æ:", + "5": "ć‚«ć‚¹ć‚æćƒ ćƒ”ć‚æćƒ‡ćƒ¼ć‚æć®čæ½åŠ " + }, + "author": "著者:", + "creationDate": "ä½œęˆę—„ (yyyy/MM/dd HH:mm:ss):", + "creator": "ä½œęˆč€…:", + "keywords": "ć‚­ćƒ¼ćƒÆćƒ¼ćƒ‰:", + "modDate": "変曓旄 (yyyy/MM/dd HH:mm:ss):", + "producer": "ćƒ—ćƒ­ćƒ‡ćƒ„ćƒ¼ć‚µćƒ¼:", + "subject": "主锌:", + "trapped": "ćƒˆćƒ©ćƒƒćƒ”ćƒ³ć‚°:", + "submit": "変曓" + }, + "fileToPDF": { + "tags": "transformation,format,document,picture,slide,text,conversion,office,docs,word,excel,powerpoint", + "title": "ćƒ•ć‚”ć‚¤ćƒ«ć‚’PDFć«å¤‰ę›", + "header": "ć‚ć‚‰ć‚†ć‚‹ćƒ•ć‚”ć‚¤ćƒ«ć‚’PDFć«å¤‰ę›", + "credit": "ęœ¬ć‚µćƒ¼ćƒ“ć‚¹ćÆćƒ•ć‚”ć‚¤ćƒ«å¤‰ę›ć«LibreOfficeとUnoconvを使用しています。", + "supportedFileTypesInfo": "ć‚µćƒćƒ¼ćƒˆć•ć‚Œć‚‹ćƒ•ć‚”ć‚¤ćƒ«å½¢å¼", + "supportedFileTypes": "ć‚µćƒćƒ¼ćƒˆć•ć‚Œć‚‹ćƒ•ć‚”ć‚¤ćƒ«å½¢å¼ć«ćÆä»„äø‹ćŒå«ć¾ć‚Œć¾ć™ćŒć€å®Œå…ØćŖę›“ę–°ćƒŖć‚¹ćƒˆć«ć¤ć„ć¦ćÆLibreOfficeć®ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚", + "submit": "PDFć‚’å¤‰ę›" + }, + "ocr": { + "tags": "recognition,text,image,scan,read,identify,detection,editable", + "title": "OCR / ć‚ÆćƒŖćƒ¼ćƒ³ć‚¢ćƒƒćƒ—", + "header": "ć‚ÆćƒŖćƒ¼ćƒ³ć‚¢ćƒƒćƒ— / OCR (å…‰å­¦å¼ę–‡å­—čŖč­˜)", + "selectText": { + "1": "PDFå†…ć§ę¤œå‡ŗć•ć‚Œć‚‹čØ€čŖžć‚’éøęŠž (ćƒŖć‚¹ćƒˆć•ć‚Œć¦ć„ć‚‹ć‚‚ć®ćÆē¾åœØę¤œå‡ŗć•ć‚Œć¦ć„ć‚‹ć‚‚ć®ć§ć™):", + "2": "OCRå‡¦ē†ć•ć‚ŒćŸPDFと一緒に、OCRć—ćŸćƒ†ć‚­ć‚¹ćƒˆć‚’å«ć‚€ćƒ†ć‚­ć‚¹ćƒˆćƒ•ć‚”ć‚¤ćƒ«ć‚’ä½œęˆć™ć‚‹", + "3": "ę–œć‚ć«ć‚¹ć‚­ćƒ£ćƒ³ć•ć‚ŒćŸćƒšćƒ¼ć‚øć‚’å›žč»¢ć•ć›ć¦äæ®ę­£ć™ć‚‹", + "4": "ćƒšćƒ¼ć‚øć‚’ćć‚Œć„ć«ć—ć¦čƒŒę™ÆćƒŽć‚¤ć‚ŗć®äø­ć‹ć‚‰ćƒ†ć‚­ć‚¹ćƒˆć‚’ę¤œå‡ŗć—ć«ććć™ć‚‹ć€‚(å‡ŗåŠ›ćÆå¤‰ć‚ć‚Šć¾ć›ć‚“)", + "5": "ćƒšćƒ¼ć‚øć‚’ćć‚Œć„ć«ć—ć¦čƒŒę™ÆćƒŽć‚¤ć‚ŗć®äø­ć‹ć‚‰ćƒ†ć‚­ć‚¹ćƒˆć‚’ę¤œå‡ŗć—ć«ććć—ć€å‡ŗåŠ›ćÆć‚ÆćƒŖćƒ¼ćƒ³ć‚¢ćƒƒćƒ—ć‚’ē¶­ęŒć™ć‚‹ć€‚", + "6": "ć‚¤ćƒ³ć‚æćƒ©ć‚Æćƒ†ć‚£ćƒ–ćŖćƒ†ć‚­ć‚¹ćƒˆć‚’å«ć‚€ćƒšćƒ¼ć‚øć‚’ē„”č¦–ć—ć€ē”»åƒćƒšćƒ¼ć‚øć®ćæć‚’OCR恙悋", + "7": "強制OCRć€å…Øć¦ć®ćƒšćƒ¼ć‚øć§å…ƒć®ćƒ†ć‚­ć‚¹ćƒˆč¦ē“ ć‚’å…Øć¦å‰Šé™¤ć—ć¦OCR恙悋", + "8": "ćƒŽćƒ¼ćƒžćƒ« (PDFć«ćƒ†ć‚­ć‚¹ćƒˆćŒå«ć¾ć‚Œć¦ć„ć‚‹å “åˆćÆć‚Øćƒ©ćƒ¼ć«ćŖć‚Šć¾ć™ć€‚)", + "9": "追加設定", + "10": "OCRćƒ¢ćƒ¼ćƒ‰", + "11": "OCRå¾Œć«ē”»åƒć‚’å‰Šé™¤ć™ć‚‹ (ć™ć¹ć¦ć®ē”»åƒć‚’å‰Šé™¤ć—ć¾ć™ć€‚å¤‰ę›ć‚¹ćƒ†ćƒƒćƒ—ć®äø€éƒØć§ć‚ć‚‹å “åˆć«ć®ćæęœ‰åŠ¹ć§ć™)怂", + "12": "ćƒ¬ćƒ³ćƒ€ćƒŖćƒ³ć‚°ć‚æć‚¤ćƒ— (高度)" + }, + "help": "ä»–ć®čØ€čŖžć§ć“ć‚Œć‚’ä½æē”Øć™ć‚‹ę–¹ę³•ć‚„Dockerä»„å¤–ć§ä½æē”Øć™ć‚‹ę–¹ę³•ć«ć¤ć„ć¦ćÆć“ć®ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’ćŠčŖ­ćæćć ć•ć„ć€‚", + "credit": "ęœ¬ć‚µćƒ¼ćƒ“ć‚¹ć«ćÆOCR恫qpdfとTesseractを使用しています。", + "submit": "OCR恧PDFを処理する" + }, + "extractImages": { + "tags": "picture,photo,save,archive,zip,capture,grab", + "title": "ē”»åƒć®ęŠ½å‡ŗ", + "header": "ē”»åƒć®ęŠ½å‡ŗ", + "selectText": "ęŠ½å‡ŗć—ćŸē”»åƒć®ćƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆć‚’éøęŠž", + "allowDuplicates": "é‡č¤‡ć—ćŸē”»åƒć‚’äæå­˜ć™ć‚‹", + "submit": "ęŠ½å‡ŗ" + }, + "pdfToPDFA": { + "tags": "archive,long-term,standard,conversion,storage,preservation", + "title": "PDF悒PDF/Ać«å¤‰ę›", + "header": "PDF悒PDF/Ać«å¤‰ę›", + "credit": "ęœ¬ć‚µćƒ¼ćƒ“ć‚¹ćÆPDF/Ać®å¤‰ę›ć«libreofficeを使用しています。", + "submit": "å¤‰ę›", + "tip": "ē¾åœØć€äø€åŗ¦ć«č¤‡ę•°ć®å…„åŠ›ć«åÆ¾ć—ć¦ę©Ÿčƒ½ć—ć¾ć›ć‚“", + "outputFormat": "å‡ŗåŠ›å½¢å¼", + "pdfWithDigitalSignature": "PDFć«ćÆćƒ‡ć‚øć‚æćƒ«ē½²åćŒå«ć¾ć‚Œć¦ć„ć¾ć™ć€‚ć“ć‚ŒćÆę¬”ć®ę‰‹é †ć§å‰Šé™¤ć•ć‚Œć¾ć™ć€‚" + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformation,format,conversion,office,microsoft,docfile", + "title": "PDF悒Wordć«å¤‰ę›", + "header": "PDF悒Wordć«å¤‰ę›", + "selectText": { + "1": "å‡ŗåŠ›ćƒ•ć‚”ć‚¤ćƒ«å½¢å¼" + }, + "credit": "ęœ¬ć‚µćƒ¼ćƒ“ć‚¹ćÆćƒ•ć‚”ć‚¤ćƒ«å¤‰ę›ć«LibreOfficeを使用しています。", + "submit": "å¤‰ę›" + }, + "PDFToPresentation": { + "tags": "slides,show,office,microsoft", + "title": "PDFć‚’ćƒ—ćƒ¬ć‚¼ćƒ³ćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć«å¤‰ę›", + "header": "PDFć‚’ćƒ—ćƒ¬ć‚¼ćƒ³ćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć«å¤‰ę›", + "selectText": { + "1": "å‡ŗåŠ›ćƒ•ć‚”ć‚¤ćƒ«å½¢å¼" + }, + "credit": "ęœ¬ć‚µćƒ¼ćƒ“ć‚¹ćÆćƒ•ć‚”ć‚¤ćƒ«å¤‰ę›ć«LibreOfficeを使用しています。", + "submit": "å¤‰ę›" + }, + "PDFToText": { + "tags": "richformat,richtextformat,rich text format", + "title": "PDF悒Text/RTFć«å¤‰ę›", + "header": "PDF悒Text/RTFć«å¤‰ę›", + "selectText": { + "1": "å‡ŗåŠ›ćƒ•ć‚”ć‚¤ćƒ«å½¢å¼" + }, + "credit": "ęœ¬ć‚µćƒ¼ćƒ“ć‚¹ćÆćƒ•ć‚”ć‚¤ćƒ«å¤‰ę›ć«LibreOfficeを使用しています。", + "submit": "å¤‰ę›" + }, + "PDFToHTML": { + "tags": "web content,browser friendly", + "title": "PDF悒HTMLć«å¤‰ę›", + "header": "PDF悒HTMLć«å¤‰ę›", + "credit": "ęœ¬ć‚µćƒ¼ćƒ“ć‚¹ćÆćƒ•ć‚”ć‚¤ćƒ«å¤‰ę›ć«pdftohtmlを使用しています。", + "submit": "å¤‰ę›" + }, + "PDFToXML": { + "tags": "data-extraction,structured-content,interop,transformation,convert", + "title": "PDF悒XMLć«å¤‰ę›", + "header": "PDF悒XMLć«å¤‰ę›", + "credit": "ęœ¬ć‚µćƒ¼ćƒ“ć‚¹ćÆćƒ•ć‚”ć‚¤ćƒ«å¤‰ę›ć«LibreOfficeを使用しています。", + "submit": "å¤‰ę›" + }, + "ScannerImageSplit": { + "tags": "separate,auto-detect,scans,multi-photo,organize", + "selectText": { + "1": "č§’åŗ¦ć®ć—ćć„å€¤:", + "2": "ē”»åƒć‚’å›žč»¢ć•ć›ć‚‹ćŸć‚ć«åæ…č¦ćŖēµ¶åÆ¾č§’åŗ¦ć®ęœ€å°å€¤ć‚’čØ­å®š (åˆęœŸå€¤:10)怂", + "3": "許容範囲:", + "4": "ęŽØå®šć•ć‚ŒćŸčƒŒę™Æč‰²å‘Øč¾ŗć®ć‚«ćƒ©ćƒ¼ćƒćƒŖć‚Øćƒ¼ć‚·ćƒ§ćƒ³ć®ēÆ„å›²ć‚’ę±ŗå®š (åˆęœŸå€¤:30)怂", + "5": "ęœ€å°é¢ē©:", + "6": "ē”»åƒć®ęœ€å°é¢ē©ć®ć—ćć„å€¤ć‚’čØ­å®š (åˆęœŸå€¤:10000)怂", + "7": "ęœ€å°č¼Ŗéƒ­é¢ē©:", + "8": "ē”»åƒć®ęœ€å°ć®č¼Ŗéƒ­é¢ē©ć®ć—ćć„å€¤ć‚’čØ­å®šć€‚", + "9": "å¢ƒē•Œē·šć‚µć‚¤ć‚ŗ:", + "10": "å‡ŗåŠ›ć«ē™½ć„ēøå–ć‚ŠćŒå‡ŗćŖć„ć‚ˆć†ć«čæ½åŠ ćƒ»å‰Šé™¤ć•ć‚Œć‚‹å¢ƒē•Œē·šć®å¤§ćć•ć‚’čØ­å®š (åˆęœŸå€¤:1)怂" + }, + "info": "PythonćŒć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć•ć‚Œć¦ć„ć¾ć›ć‚“ć€‚å®Ÿč”Œć™ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚" + }, + "sign": { + "tags": "authorize,initials,drawn-signature,text-sign,image-signature", + "title": "ē½²å", + "header": "PDFć«ē½²å", + "upload": "ē”»åƒć‚’ć‚¢ćƒƒćƒ—ćƒ­ćƒ¼ćƒ‰", + "draw": "ē½²åć‚’ę›øć", + "text": "ćƒ†ć‚­ć‚¹ćƒˆå…„åŠ›", + "clear": "ć‚ÆćƒŖć‚¢", + "add": "追加", + "saved": "äæå­˜ć•ć‚ŒćŸē½²å", + "save": "ē½²åć‚’äæå­˜", + "personalSigs": "å€‹äŗŗē½²å", + "sharedSigs": "å…±ęœ‰ē½²å", + "noSavedSigs": "äæå­˜ć•ć‚ŒćŸē½²åćŒč¦‹ć¤ć‹ć‚Šć¾ć›ć‚“", + "addToAll": "ć™ć¹ć¦ć®ćƒšćƒ¼ć‚øć«čæ½åŠ ", + "delete": "削除", + "first": "ęœ€åˆć®ćƒšćƒ¼ć‚ø", + "last": "ęœ€å¾Œć®ćƒšćƒ¼ć‚ø", + "next": "ę¬”ć®ćƒšćƒ¼ć‚ø", + "previous": "å‰ć®ćƒšćƒ¼ć‚ø", + "maintainRatio": "ć‚¢ć‚¹ćƒšć‚ÆćƒˆęÆ”ć‚’ē¶­ęŒć‚’åˆ‡ę›æćˆ", + "undo": "å…ƒć«ęˆ»ć™", + "redo": "ć‚„ć‚Šē›“ć™" + }, + "flatten": { + "tags": "static,deactivate,non-interactive,streamline", + "title": "平坦化", + "header": "PDFć‚’å¹³å¦åŒ–ć™ć‚‹", + "flattenOnlyForms": "ćƒ•ć‚©ćƒ¼ćƒ ć®ćæć‚’å¹³å¦ć«ć™ć‚‹", + "submit": "平坦化" + }, + "repair": { + "tags": "fix,restore,correction,recover", + "title": "修復", + "header": "PDFを修復", + "submit": "修復" + }, + "removeBlanks": { + "tags": "cleanup,streamline,non-content,organize", + "title": "ē©ŗē™½ć®å‰Šé™¤", + "header": "ē©ŗē™½ćƒšćƒ¼ć‚øć®å‰Šé™¤", + "threshold": "ć—ćć„å€¤ :", + "thresholdDesc": "ē™½č‰²ćƒ”ć‚Æć‚»ćƒ«ć®ē™½ć•ć‚’ę±ŗć‚ć‚‹ćŸć‚ć®ć—ćć„å€¤", + "whitePercent": "ē™½ęÆ”ēŽ‡", + "whitePercentDesc": "å‰Šé™¤ć™ć‚‹ćƒšćƒ¼ć‚øć®ē™½ć®å‰²åˆ", + "submit": "ē©ŗē™½ćƒšćƒ¼ć‚øć®å‰Šé™¤" + }, + "removeAnnotations": { + "tags": "comments,highlight,notes,markup,remove", + "title": "ę³Øé‡ˆć®å‰Šé™¤", + "header": "ę³Øé‡ˆć®å‰Šé™¤", + "submit": "削除" + }, + "compare": { + "tags": "differentiate,contrast,changes,analysis", + "title": "ęÆ”č¼ƒ", + "header": "PDFć®ęÆ”č¼ƒ", + "highlightColor": { + "1": "ćƒć‚¤ćƒ©ć‚¤ćƒˆć‚«ćƒ©ćƒ¼ 1:", + "2": "ćƒć‚¤ćƒ©ć‚¤ćƒˆć‚«ćƒ©ćƒ¼ 2:" + }, + "document": { + "1": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ 1", + "2": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ 2" + }, + "submit": "ęÆ”č¼ƒ", + "complex": { + "message": "ęä¾›ć•ć‚ŒćŸę–‡ę›øć®äø€ę–¹ć¾ćŸćÆäø”ę–¹ćŒå¤§ććŖćƒ•ć‚”ć‚¤ćƒ«ć§ć‚ć‚‹ćŸć‚ć€ęÆ”č¼ƒć®ē²¾åŗ¦ćŒä½Žäø‹ć™ć‚‹åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚" + }, + "large": { + "file": { + "message": "ęä¾›ć•ć‚ŒćŸę–‡ę›øć®1ć¤ć¾ćŸćÆäø”ę–¹ćŒå¤§ćć™ćŽć¦å‡¦ē†ć§ćć¾ć›ć‚“" + } + }, + "no": { + "text": { + "message": "éøęŠžć—ćŸPDF恮1ć¤ć¾ćŸćÆäø”ę–¹ć«ćƒ†ć‚­ć‚¹ćƒˆć‚³ćƒ³ćƒ†ćƒ³ćƒ„ćŒć‚ć‚Šć¾ć›ć‚“ć€‚ęÆ”č¼ƒć™ć‚‹ć«ćÆć€ćƒ†ć‚­ć‚¹ćƒˆć‚’å«ć‚€PDFć‚’éøęŠžć—ć¦ćć ć•ć„ć€‚" + } + } + }, + "certSign": { + "tags": "authenticate,PEM,P12,official,encrypt", + "title": "čØ¼ę˜Žę›øć«ć‚ˆć‚‹ē½²å", + "header": "čØ¼ę˜Žę›øć‚’ä½æē”Øć—ć¦PDFć«ē½²åć—ć¾ć™ć€‚ (制作中)", + "selectPDF": "ē½²åć™ć‚‹PDFćƒ•ć‚”ć‚¤ćƒ«ć‚’éøęŠž:", + "jksNote": "注: čØ¼ę˜Žę›øć®ć‚æć‚¤ćƒ—ćŒä»„äø‹ć«ćƒŖć‚¹ćƒˆć•ć‚Œć¦ć„ćŖć„å “åˆćÆć€keytoolć‚³ćƒžćƒ³ćƒ‰ćƒ©ć‚¤ćƒ³ćƒ„ćƒ¼ćƒ«ć‚’ä½æē”Øć—ć¦čØ¼ę˜Žę›øć‚’Javać‚­ćƒ¼ć‚¹ćƒˆć‚¢(.jks)ćƒ•ć‚”ć‚¤ćƒ«ć«å¤‰ę›ć—ć¦ćć ć•ć„ć€‚ę¬”ć«ä»„äø‹ć®.jksćƒ•ć‚”ć‚¤ćƒ« ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć‚’éøęŠžć—ć¾ć™ć€‚", + "selectKey": "ē§˜åÆ†ć‚­ćƒ¼ćƒ•ć‚”ć‚¤ćƒ«ć‚’éøęŠž (PKCS#8å½¢å¼ć€.pemまたは.der) :", + "selectCert": "čØ¼ę˜Žę›øćƒ•ć‚”ć‚¤ćƒ«ć‚’éøęŠž (X.509å½¢å¼ć€.pemまたは.der) :", + "selectP12": "PKCS#12ć‚­ćƒ¼ć‚¹ćƒˆć‚¢ćƒ•ć‚”ć‚¤ćƒ«ć‚’éøęŠž (.p12または.pfx) (ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć€‚ęŒ‡å®šć™ć‚‹å “åˆćÆē§˜åÆ†ć‚­ćƒ¼ćØčØ¼ę˜Žę›øćŒå«ć¾ć‚Œć¦ć„ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚):", + "selectJKS": "Javać‚­ćƒ¼ć‚¹ćƒˆć‚¢ćƒ•ć‚”ć‚¤ćƒ«ć‚’éøęŠž (.jks or .keystore):", + "certType": "čØ¼ę˜Žę›øć®ēØ®é”ž", + "password": "ć‚­ćƒ¼ć‚¹ćƒˆć‚¢ć¾ćŸćÆē§˜åÆ†ć‚­ćƒ¼ć®ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć‚’å…„åŠ› (ć‚ć‚‹å “åˆ) :", + "showSig": "ē½²åć‚’č”Øē¤ŗ", + "reason": "理由", + "location": "堓所", + "name": "名前", + "showLogo": "ćƒ­ć‚“ć‚’č”Øē¤ŗ", + "submit": "PDFć«ē½²å" + }, + "removeCertSign": { + "tags": "authenticate,PEM,P12,official,decrypt", + "title": "čØ¼ę˜Žę›øē½²åć®å‰Šé™¤", + "header": "PDFć‹ć‚‰é›»å­čØ¼ę˜Žę›øć‚’å‰Šé™¤ć™ć‚‹", + "selectPDF": "PDFćƒ•ć‚”ć‚¤ćƒ«ć®éøęŠž:", + "submit": "ē½²åć®å‰Šé™¤" + }, + "pageLayout": { + "tags": "merge,composite,single-view,organize", + "title": "ćƒžćƒ«ćƒćƒšćƒ¼ć‚øćƒ¬ć‚¤ć‚¢ć‚¦ćƒˆ", + "header": "ćƒžćƒ«ćƒćƒšćƒ¼ć‚øćƒ¬ć‚¤ć‚¢ć‚¦ćƒˆ", + "pagesPerSheet": "1ęžšć‚ćŸć‚Šć®ćƒšćƒ¼ć‚øę•°:", + "addBorder": "å¢ƒē•Œē·šć‚’čæ½åŠ ", + "submit": "送俔" + }, + "scalePages": { + "tags": "resize,modify,dimension,adapt", + "title": "ćƒšćƒ¼ć‚øć®ēø®å°ŗć®čŖæę•“", + "header": "ćƒšćƒ¼ć‚øć®ēø®å°ŗć®čŖæę•“", + "pageSize": "1ćƒšćƒ¼ć‚øć®ć‚µć‚¤ć‚ŗ", + "keepPageSize": "å…ƒć®ć‚µć‚¤ć‚ŗ", + "scaleFactor": "1ćƒšćƒ¼ć‚øć®ę‹”å¤§ćƒ¬ćƒ™ćƒ« (ćƒˆćƒŖćƒŸćƒ³ć‚°)怂", + "submit": "送俔" + }, + "add-page-numbers": { + "tags": "paginate,label,organize,index" + }, + "auto-rename": { + "tags": "auto-detect,header-based,organize,relabel", + "title": "ćƒ•ć‚”ć‚¤ćƒ«åć®č‡Ŗå‹•å¤‰ę›“", + "header": "PDFåć®č‡Ŗå‹•å¤‰ę›“", + "submit": "č‡Ŗå‹•ćƒŖćƒćƒ¼ćƒ " + }, + "adjust-contrast": { + "tags": "color-correction,tune,modify,enhance" + }, + "crop": { + "tags": "trim,shrink,edit,shape", + "title": "åˆ‡ć‚ŠęŠœć", + "header": "PDFć®ćƒˆćƒŖćƒŸćƒ³ć‚°", + "submit": "送俔" + }, + "autoSplitPDF": { + "tags": "QR-based,separate,scan-segment,organize", + "title": "PDFć®č‡Ŗå‹•åˆ†å‰²", + "header": "PDFć®č‡Ŗå‹•åˆ†å‰²", + "description": "å°åˆ·ć€ęŒæå…„ć€ć‚¹ć‚­ćƒ£ćƒ³ć€ć‚¢ćƒƒćƒ—ćƒ­ćƒ¼ćƒ‰ć€ćŠć‚ˆć³ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’č‡Ŗå‹•åˆ†é›¢ć—ć¾ć™ć€‚ę‰‹å‹•ć§ć®ä»•åˆ†ć‘ć®åæ…č¦ć‚ć‚Šć¾ć›ć‚“ć€‚", + "selectText": { + "1": "äø‹ć‹ć‚‰ä»•åˆ‡ć‚Šē”Øē“™ć‚’å°åˆ·ć—ć¾ć™(ē™½é»’ć§å•é”Œć‚ć‚Šć¾ć›ć‚“)怂", + "2": "åŽŸēØæć®é–“ć«ä»•åˆ‡ć‚Šē”Øē“™ć‚’ęŒæå…„ć—ć€ć™ć¹ć¦ć®åŽŸēØæć‚’ć¾ćØć‚ć¦ć‚¹ć‚­ćƒ£ćƒ³ć—ć¾ć™ć€‚", + "3": "ć‚¹ć‚­ćƒ£ćƒ³ć—ćŸPDFćƒ•ć‚”ć‚¤ćƒ«ć‚’ć‚¢ćƒƒćƒ—ćƒ­ćƒ¼ćƒ‰ć—Stirling PDFに任せます。", + "4": "ä»•åˆ‡ć‚Šćƒšćƒ¼ć‚øćÆč‡Ŗå‹•ēš„ć«ę¤œå‡ŗć€å‰Šé™¤ć•ć‚Œć‚‹ć®ć§ć€ęœ€ēµ‚ēš„ćŖę–‡ę›øćÆćć‚Œć„ć«ä»•äøŠćŒć‚Šć¾ć™ć€‚" + }, + "formPrompt": "Stirling-PDFä»•åˆ‡ć‚Šē”Øē“™ć‚’å«ć‚€PDFを送俔:", + "duplexMode": "äø”é¢ćƒ¢ćƒ¼ćƒ‰ (č”Øč£ć‚¹ć‚­ćƒ£ćƒ³)", + "dividerDownload2": "ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰ 'č‡Ŗå‹•ä»•åˆ‡ć‚Šē”Øē“™ (ę‰‹é †ę›øä»˜ć).pdf'", + "submit": "送俔" + }, + "sanitizePdf": { + "tags": "clean,secure,safe,remove-threats" + }, + "URLToPDF": { + "tags": "web-capture,save-page,web-to-doc,archive", + "title": "URL悒PDFć«å¤‰ę›", + "header": "URL悒PDFć«å¤‰ę›", + "submit": "å¤‰ę›", + "credit": "WeasyPrintを使用" + }, + "HTMLToPDF": { + "tags": "markup,web-content,transformation,convert", + "title": "HTML悒PDFć«å¤‰ę›", + "header": "HTML悒PDFć«å¤‰ę›", + "help": "HTMLćƒ•ć‚”ć‚¤ćƒ«ćØåæ…č¦ćŖhtml/css/ē”»åƒćŖć©ć‚’å«ć‚€ZIPć‚’å—ć‘å…„ć‚Œć¾ć™", + "submit": "å¤‰ę›", + "credit": "WeasyPrintを使用", + "zoom": "Webć‚µć‚¤ćƒˆć‚’č”Øē¤ŗć™ć‚‹ćŸć‚ć®ć‚ŗćƒ¼ćƒ ćƒ¬ćƒ™ćƒ«ć€‚", + "pageWidth": "ćƒšćƒ¼ć‚øå¹… (cm)怂 (ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć§ćÆē©ŗē™½)", + "pageHeight": "ćƒšćƒ¼ć‚øé«˜ć• (cm)怂 (ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć§ćÆē©ŗē™½)", + "marginTop": "ćƒšćƒ¼ć‚øäøŠć®ä½™ē™½ (mm)怂 (ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć§ćÆē©ŗē™½)", + "marginBottom": "ćƒšćƒ¼ć‚øäø‹ć®ä½™ē™½ (mm)怂 (ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć§ćÆē©ŗē™½)", + "marginLeft": "ćƒšćƒ¼ć‚øå·¦ć®ä½™ē™½ (mm)怂 (ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć§ćÆē©ŗē™½)", + "marginRight": "ćƒšćƒ¼ć‚øå³ć®ä½™ē™½ (mm)怂 (ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć§ćÆē©ŗē™½)", + "printBackground": "Webć‚µć‚¤ćƒˆć®čƒŒę™Æć‚’ćƒ¬ćƒ³ćƒ€ćƒŖćƒ³ć‚°ć—ć¾ć™ć€‚", + "defaultHeader": "ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®ćƒ˜ćƒƒćƒ€ćƒ¼ (åå‰ćØćƒšćƒ¼ć‚øē•Ŗå·) ć‚’ęœ‰åŠ¹ć«ć™ć‚‹", + "cssMediaType": "ćƒšćƒ¼ć‚øć®CSSćƒ”ćƒ‡ć‚£ć‚¢ć‚æć‚¤ćƒ—ć‚’å¤‰ę›“ć—ć¾ć™ć€‚", + "none": "なし", + "print": "印刷", + "screen": "ē”»é¢" + }, + "MarkdownToPDF": { + "tags": "markup,web-content,transformation,convert", + "title": "Markdown悒PDFć«å¤‰ę›", + "header": "Markdown悒PDFć«å¤‰ę›", + "submit": "å¤‰ę›", + "help": "処理中", + "credit": "WeasyPrintを使用" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF悒Markdownć«å¤‰ę›", + "header": "PDF悒Markdownć«å¤‰ę›", + "submit": "å¤‰ę›" + }, + "getPdfInfo": { + "tags": "infomation,data,stats,statistics", + "title": "PDFć®ęƒ…å ±ć‚’å…„ę‰‹", + "header": "PDFć®ęƒ…å ±ć‚’å…„ę‰‹", + "submit": "ęƒ…å ±ć‚’å…„ę‰‹", + "downloadJson": "JSONć§ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰" + }, + "extractPage": { + "tags": "extract" + }, + "PdfToSinglePage": { + "tags": "single page" + }, + "showJS": { + "tags": "JS", + "title": "Javascriptを蔨示", + "header": "Javascriptを蔨示", + "downloadJS": "Javascriptć‚’ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰", + "submit": "蔨示" + }, + "autoRedact": { + "tags": "Redact,Hide,black out,black,marker,hidden", + "title": "č‡Ŗå‹•å¢Øę¶ˆć—", + "header": "č‡Ŗå‹•å¢Øę¶ˆć—", + "colorLabel": "ć‚«ćƒ©ćƒ¼", + "textsToRedactLabel": "ē·Øé›†ć™ć‚‹ćƒ†ć‚­ć‚¹ćƒˆļ¼ˆč”ŒåŒŗåˆ‡ć‚Šļ¼‰", + "textsToRedactPlaceholder": "例: \\nę©ŸåÆ† \\n愵秘", + "useRegexLabel": "ę­£č¦č”Øē¾ć‚’ä½æē”Øć™ć‚‹", + "wholeWordSearchLabel": "å˜čŖžå˜ä½ć®ę¤œē“¢", + "customPaddingLabel": "čæ½åŠ ć®ä½™ē™½", + "convertPDFToImageLabel": "PDF悒PDFē”»åƒć«å¤‰ę› (å¢Øę¶ˆć—ć®å¾Œć‚ć®ćƒ†ć‚­ć‚¹ćƒˆć‚’å‰Šé™¤ć™ć‚‹ćŸć‚ć«ä½æē”Ø)", + "submitButton": "送俔" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "ę‰‹å‹•å¢Øę¶ˆć—", + "header": "ę‰‹å‹•å¢Øę¶ˆć—", + "submit": "編集", + "textBasedRedaction": "ćƒ†ć‚­ć‚¹ćƒˆćƒ™ćƒ¼ć‚¹ć®å¢Øę¶ˆć—", + "pageBasedRedaction": "ćƒšćƒ¼ć‚øćƒ™ćƒ¼ć‚¹ć®å¢Øę¶ˆć—", + "convertPDFToImageLabel": "PDF悒PDFē”»åƒć«å¤‰ę›ć—ć¾ć™ (ćƒœćƒƒć‚Æć‚¹ć®čƒŒå¾Œć®ćƒ†ć‚­ć‚¹ćƒˆć‚’å‰Šé™¤ć™ć‚‹ćŸć‚ć«ä½æē”Øć—ć¾ć™)", + "pageRedactionNumbers": { + "title": "ćƒšćƒ¼ć‚ø", + "placeholder": "(例:1,2,8态4,7,12-16态2n-1)" + }, + "redactionColor": { + "title": "編集色" + }, + "export": "å‡ŗåŠ›", + "upload": "ć‚¢ćƒƒćƒ—ćƒ­ćƒ¼ćƒ‰", + "boxRedaction": "ćƒœćƒƒć‚Æć‚¹ęē”»ć®å¢Øę¶ˆć—", + "zoom": "ć‚ŗćƒ¼ćƒ ", + "zoomIn": "拔大", + "zoomOut": "ēø®å°", + "nextPage": "ę¬”ć®ćƒšćƒ¼ć‚ø", + "previousPage": "å‰ć®ćƒšćƒ¼ć‚ø", + "toggleSidebar": "ć‚µć‚¤ćƒ‰ćƒćƒ¼ć‚’åˆ‡ę›æćˆ", + "showThumbnails": "ć‚µćƒ ćƒć‚¤ćƒ«ć‚’č”Øē¤ŗ", + "showDocumentOutline": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć®ć‚¢ć‚¦ćƒˆćƒ©ć‚¤ćƒ³ć‚’č”Øē¤ŗ (ćƒ€ćƒ–ćƒ«ć‚ÆćƒŖćƒƒć‚Æć™ć‚‹ćØć™ć¹ć¦ć®é …ē›®ć‚’å±•é–‹/ęŠ˜ć‚ŠćŸćŸć‚€ć“ćØćŒć§ćć¾ć™)", + "showAttatchments": "ę·»ä»˜ćƒ•ć‚”ć‚¤ćƒ«ć‚’č”Øē¤ŗ", + "showLayers": "ćƒ¬ć‚¤ćƒ¤ćƒ¼ć‚’č”Øē¤ŗļ¼ˆćƒ€ćƒ–ćƒ«ć‚ÆćƒŖćƒƒć‚Æć™ć‚‹ćØć™ć¹ć¦ć®ćƒ¬ć‚¤ćƒ¤ćƒ¼ćŒćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®ēŠ¶ę…‹ć«ćƒŖć‚»ćƒƒćƒˆć•ć‚Œć¾ć™ļ¼‰", + "colourPicker": "ć‚«ćƒ©ćƒ¼éøęŠž", + "findCurrentOutlineItem": "ē¾åœØć®ć‚¢ć‚¦ćƒˆćƒ©ć‚¤ćƒ³é …ē›®ć‚’ę¤œē“¢", + "applyChanges": "変曓を適用" + }, + "tableExtraxt": { + "tags": "CSV,Table Extraction,extract,convert" + }, + "autoSizeSplitPDF": { + "tags": "pdf,split,document,organization" + }, + "overlay-pdfs": { + "tags": "Overlay", + "header": "PDFć®ć‚Ŗćƒ¼ćƒćƒ¼ćƒ¬ć‚¤", + "baseFile": { + "label": "ćƒ™ćƒ¼ć‚¹ć®PDFć‚’éøęŠž" + }, + "overlayFiles": { + "label": "重恭悋PDFć‚’éøęŠž" + }, + "mode": { + "label": "ć‚Ŗćƒ¼ćƒćƒ¼ćƒ¬ć‚¤ćƒ¢ćƒ¼ćƒ‰ć®éøęŠž", + "sequential": "ć‚·ćƒ¼ć‚±ćƒ³ć‚·ćƒ£ćƒ«ćƒ»ć‚Ŗćƒ¼ćƒćƒ¼ćƒ¬ć‚¤", + "interleaved": "ć‚¤ćƒ³ć‚æćƒ¼ćƒŖćƒ¼ćƒ–ćƒ»ć‚Ŗćƒ¼ćƒćƒ¼ćƒ¬ć‚¤", + "fixedRepeat": "å›ŗå®šćƒŖćƒ”ćƒ¼ćƒˆćƒ»ć‚Ŗćƒ¼ćƒćƒ¼ćƒ¬ć‚¤" + }, + "counts": { + "label": "ć‚Ŗćƒ¼ćƒćƒ¼ćƒ¬ć‚¤å›žę•° (å›ŗå®šćƒŖćƒ”ćƒ¼ćƒˆćƒ¢ćƒ¼ćƒ‰ē”Ø)", + "placeholder": "ć‚«ćƒ³ćƒžåŒŗåˆ‡ć‚Šć§ć‚«ć‚¦ćƒ³ćƒˆć‚’å…„åŠ› (例:2,3,1)" + }, + "position": { + "label": "é‡ć­ä½ē½®ć®éøęŠž", + "foreground": "前面", + "background": "čƒŒé¢" + }, + "submit": "重恭悋" + }, + "split-by-sections": { + "tags": "Section Split, Divide, Customize,Customise", + "title": "ć‚»ć‚Æć‚·ćƒ§ćƒ³ć”ćØć«PDFć‚’åˆ†å‰²ć™ć‚‹", + "header": "PDFć‚’ć‚»ć‚Æć‚·ćƒ§ćƒ³ć«åˆ†å‰²", + "horizontal": { + "label": "氓平方向", + "placeholder": "ę°“å¹³ę–¹å‘ć®åˆ†å‰²ę•°ć‚’éøęŠž" + }, + "vertical": { + "label": "åž‚ē›“ę–¹å‘", + "placeholder": "åž‚ē›“ę–¹å‘ć®åˆ†å‰²ę•°ć‚’éøęŠž" + }, + "submit": "分割", + "merge": "1 恤恮 PDF ć«ēµåˆć™ć‚‹ć‹ć©ć†ć‹" + }, + "AddStampRequest": { + "tags": "Stamp, Add image, center image, Watermark, PDF, Embed, Customize,Customise", + "header": "PDFć«ć‚¹ć‚æćƒ³ćƒ—ć‚’ęŠ¼ć™", + "title": "PDFć«ć‚¹ć‚æćƒ³ćƒ—ć‚’ęŠ¼ć™", + "stampType": "ć‚¹ć‚æćƒ³ćƒ—ć®ēØ®é”ž", + "stampText": "ć‚¹ć‚æćƒ³ćƒ—ć™ć‚‹ę–‡ē« ", + "stampImage": "ć‚¹ć‚æćƒ³ćƒ—ć™ć‚‹ē”»åƒ", + "alphabet": "文字", + "fontSize": "ćƒ•ć‚©ćƒ³ćƒˆ/ē”»åƒ サイズ", + "rotation": "å›žč»¢", + "opacity": "äøé€ę˜Žåŗ¦", + "position": "ä½ē½®", + "overrideX": "Xåŗ§ęØ™ć®ć‚Ŗćƒ¼ćƒćƒ¼ćƒ©ć‚¤ćƒ‰", + "overrideY": "Yåŗ§ęØ™ć®ć‚Ŗćƒ¼ćƒćƒ¼ćƒ©ć‚¤ćƒ‰", + "customMargin": "ä½™ē™½ć®ć‚«ć‚¹ć‚æćƒ ", + "customColor": "ę–‡å­—č‰²ć®ć‚«ć‚¹ć‚æćƒ ", + "submit": "送俔" + }, + "removeImagePdf": { + "tags": "Remove Image,Page operations,Back end,server side" + }, + "splitPdfByChapters": { + "tags": "split,chapters,bookmarks,organize" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "PDFē½²åć®ę¤œčØ¼", + "header": "ćƒ‡ć‚øć‚æćƒ«ē½²åć®ę¤œčØ¼", + "selectPDF": "ē½²åęøˆćæPDFćƒ•ć‚”ć‚¤ćƒ«ć‚’éøęŠž", + "submit": "ē½²åć®ę¤œčØ¼", + "results": "ę¤œčØ¼ēµęžœ", + "status": { + "_value": "ēŠ¶ę…‹", + "valid": "ęœ‰åŠ¹", + "invalid": "ē„”åŠ¹" + }, + "signer": "ē½²åč€…", + "date": "ę—„ä»˜", + "reason": "理由", + "location": "堓所", + "noSignatures": "ć“ć®ę–‡ę›øć«ćÆćƒ‡ć‚øć‚æćƒ«ē½²åćŒč¦‹ć¤ć‹ć‚Šć¾ć›ć‚“", + "chain": { + "invalid": "čØ¼ę˜Žę›øćƒć‚§ćƒ¼ćƒ³ć®ę¤œčØ¼ć«å¤±ę•—ć—ć¾ć—ćŸ - ē½²åč€…ć®čŗ«å…ƒć‚’ē¢ŗčŖć§ćć¾ć›ć‚“" + }, + "trust": { + "invalid": "čØ¼ę˜Žę›øćŒäæ”é ¼ć‚¹ćƒˆć‚¢ć«ć‚ć‚Šć¾ć›ć‚“ - ć‚½ćƒ¼ć‚¹ć‚’ę¤œčØ¼ć§ćć¾ć›ć‚“" + }, + "cert": { + "expired": "čØ¼ę˜Žę›øć®ęœ‰åŠ¹ęœŸé™ćŒåˆ‡ć‚Œć¦ć„ć¾ć™", + "revoked": "čØ¼ę˜Žę›øćÆå–ć‚Šę¶ˆć•ć‚Œć¾ć—ćŸ", + "info": "čØ¼ę˜Žę›øć®č©³ē“°", + "issuer": "ē™ŗč”Œč€…", + "subject": "主锌", + "serialNumber": "ć‚·ćƒŖć‚¢ćƒ«ćƒŠćƒ³ćƒćƒ¼", + "validFrom": "ęœ‰åŠ¹é–‹å§‹ę—„", + "validUntil": "ęœ‰åŠ¹ęœŸé™", + "algorithm": "ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ", + "keySize": "ć‚­ćƒ¼ć‚µć‚¤ć‚ŗ", + "version": "ćƒćƒ¼ć‚øćƒ§ćƒ³", + "keyUsage": "ć‚­ćƒ¼ć®ä½æē”Øę³•", + "selfSigned": "č‡Ŗå·±ē½²å", + "bits": "惓惃惈" + }, + "signature": { + "info": "ē½²åęƒ…å ±", + "_value": "ē½²å", + "mathValid": "ē½²åćÆę•°å­¦ēš„ć«ćÆęœ‰åŠ¹ć§ć™ćŒ:" + }, + "selectCustomCert": "ć‚«ć‚¹ć‚æćƒ čØ¼ę˜Žę›øćƒ•ć‚”ć‚¤ćƒ« X.509 (ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³)" + }, + "replace-color": { + "title": "č‰²ć®ē½®ę›ćƒ»åč»¢", + "header": "PDFć®č‰²ć®ē½®ę›ćƒ»åč»¢", + "selectText": { + "1": "č‰²ć®ē½®ę›ć¾ćŸćÆåč»¢ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³", + "2": "ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆ(ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®é«˜ć‚³ćƒ³ćƒˆćƒ©ć‚¹ćƒˆč‰²)", + "3": "ć‚«ć‚¹ć‚æćƒ ļ¼ˆć‚«ć‚¹ć‚æćƒžć‚¤ć‚ŗć•ć‚ŒćŸč‰²ļ¼‰", + "4": "ćƒ•ćƒ«åč»¢(ć™ć¹ć¦ć®č‰²ć‚’åč»¢)", + "5": "é«˜ć‚³ćƒ³ćƒˆćƒ©ć‚¹ćƒˆć‚«ćƒ©ćƒ¼ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³", + "6": "é»’čƒŒę™Æć«ē™½ę–‡å­—", + "7": "ē™½čƒŒę™Æć«é»’ę–‡å­—", + "8": "é»’čƒŒę™Æć«é»„č‰²ę–‡å­—", + "9": "é»’čƒŒę™Æć«ē·‘ę–‡å­—", + "10": "ćƒ†ć‚­ć‚¹ćƒˆć®č‰²ć‚’éøęŠž", + "11": "čƒŒę™Æč‰²ć‚’éøęŠž" + }, + "submit": "ē½®ę›" + }, + "replaceColorPdf": { + "tags": "č‰²ć®ē½®ćę›ćˆć€ćƒšćƒ¼ć‚øę“ä½œć€ćƒćƒƒć‚Æć‚Øćƒ³ćƒ‰ć€ć‚µćƒ¼ćƒćƒ¼å“" + }, + "login": { + "title": "ć‚µć‚¤ćƒ³ć‚¤ćƒ³", + "header": "ć‚µć‚¤ćƒ³ć‚¤ćƒ³", + "signin": "ć‚µć‚¤ćƒ³ć‚¤ćƒ³", + "rememberme": "ć‚µć‚¤ćƒ³ć‚¤ćƒ³ēŠ¶ę…‹ć‚’čØ˜ę†¶ć™ć‚‹", + "invalid": "ćƒ¦ćƒ¼ć‚¶ćƒ¼åć‹ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ćŒē„”åŠ¹ć§ć™ć€‚", + "locked": "ć‚ćŖćŸć®ć‚¢ć‚«ć‚¦ćƒ³ćƒˆćÆćƒ­ćƒƒć‚Æć•ć‚Œć¦ć„ć¾ć™ć€‚", + "signinTitle": "ć‚µć‚¤ćƒ³ć‚¤ćƒ³ć—ć¦ćć ć•ć„", + "ssoSignIn": "ć‚·ćƒ³ć‚°ćƒ«ć‚µć‚¤ćƒ³ć‚Ŗćƒ³ć§ćƒ­ć‚°ć‚¤ćƒ³", + "oAuth2AutoCreateDisabled": "OAuth 2č‡Ŗå‹•ä½œęˆćƒ¦ćƒ¼ć‚¶ćƒ¼ćŒē„”åŠ¹", + "oAuth2AdminBlockedUser": "ē¾åœØć€ęœŖē™»éŒ²ćƒ¦ćƒ¼ć‚¶ćƒ¼ć®ē™»éŒ²ć¾ćŸćÆćƒ­ć‚°ć‚¤ćƒ³ćÆćƒ–ćƒ­ćƒƒć‚Æć•ć‚Œć¦ć„ć¾ć™ć€‚ē®”ē†č€…ć«ćŠå•ć„åˆć‚ć›ćć ć•ć„ć€‚", + "oauth2RequestNotFound": "čŖčØ¼ćƒŖć‚Æć‚Øć‚¹ćƒˆćŒč¦‹ć¤ć‹ć‚Šć¾ć›ć‚“", + "oauth2InvalidUserInfoResponse": "ē„”åŠ¹ćŖćƒ¦ćƒ¼ć‚¶ćƒ¼ęƒ…å ±ć®åæœē­”", + "oauth2invalidRequest": "ē„”åŠ¹ćŖćƒŖć‚Æć‚Øć‚¹ćƒˆ", + "oauth2AccessDenied": "アクセス拒否", + "oauth2InvalidTokenResponse": "ē„”åŠ¹ćŖćƒˆćƒ¼ć‚Æćƒ³åæœē­”", + "oauth2InvalidIdToken": "ē„”åŠ¹ćŖIDćƒˆćƒ¼ć‚Æćƒ³", + "relyingPartyRegistrationNotFound": "ćƒŖćƒ©ć‚¤ćƒ³ć‚°ćƒ‘ćƒ¼ćƒ†ć‚£ćƒ¼ć®ē™»éŒ²ćŒč¦‹ć¤ć‹ć‚Šć¾ć›ć‚“", + "userIsDisabled": "ćƒ¦ćƒ¼ć‚¶ćƒ¼ćÆéžć‚¢ć‚Æćƒ†ć‚£ćƒ–åŒ–ć•ć‚Œć¦ćŠć‚Šć€ē¾åœØć“ć®ćƒ¦ćƒ¼ć‚¶ćƒ¼åć§ć®ćƒ­ć‚°ć‚¤ćƒ³ćÆćƒ–ćƒ­ćƒƒć‚Æć•ć‚Œć¦ć„ć¾ć™ć€‚ē®”ē†č€…ć«é€£ēµ”ć—ć¦ćć ć•ć„ć€‚", + "alreadyLoggedIn": "ć™ć§ć«ćƒ­ć‚°ć‚¤ćƒ³ć—ć¦ć„ć¾ć™", + "alreadyLoggedIn2": "ćƒ‡ćƒć‚¤ć‚¹ć‹ć‚‰ćƒ­ć‚°ć‚¢ć‚¦ćƒˆć—ć¦ć‚‚ć†äø€åŗ¦ćŠč©¦ć—ćć ć•ć„ć€‚", + "toManySessions": "ć‚¢ć‚Æćƒ†ć‚£ćƒ–ćŖć‚»ćƒƒć‚·ćƒ§ćƒ³ćŒå¤šć™ćŽć¾ć™", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDFć‚’å˜äø€ćƒšćƒ¼ć‚øć«å¤‰ę›", + "header": "PDFć‚’å˜äø€ćƒšćƒ¼ć‚øć«å¤‰ę›", + "submit": "å˜äø€ćƒšćƒ¼ć‚øć«å¤‰ę›" + }, + "pageExtracter": { + "title": "ćƒšćƒ¼ć‚øć®ęŠ½å‡ŗ", + "header": "ćƒšćƒ¼ć‚øć®ęŠ½å‡ŗ", + "submit": "ęŠ½å‡ŗ", + "placeholder": "(例:1,2,8态4,7,12-16态2n-1)" + }, + "sanitizePDF": { + "title": "PDFć‚’ć‚µćƒ‹ć‚æć‚¤ć‚ŗ", + "header": "PDFćƒ•ć‚”ć‚¤ćƒ«ć‚’ć‚µćƒ‹ć‚æć‚¤ć‚ŗ", + "selectText": { + "1": "JavaScriptć‚¢ć‚Æć‚·ćƒ§ćƒ³ć‚’å‰Šé™¤", + "2": "åŸ‹ć‚č¾¼ćæćƒ•ć‚”ć‚¤ćƒ«ć‚’å‰Šé™¤", + "3": "XMPćƒ”ć‚æćƒ‡ćƒ¼ć‚æć‚’å‰Šé™¤", + "4": "ćƒŖćƒ³ć‚Æć‚’å‰Šé™¤", + "5": "ćƒ•ć‚©ćƒ³ćƒˆć‚’å‰Šé™¤", + "6": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆęƒ…å ±ć®ćƒ”ć‚æćƒ‡ćƒ¼ć‚æć‚’å‰Šé™¤" + }, + "submit": "PDFć‚’ć‚µćƒ‹ć‚æć‚¤ć‚ŗć™ć‚‹" + }, + "adjustContrast": { + "title": "ć‚³ćƒ³ćƒˆćƒ©ć‚¹ćƒˆć®čŖæę•“", + "header": "ć‚³ćƒ³ćƒˆćƒ©ć‚¹ćƒˆć®čŖæę•“", + "contrast": "ć‚³ćƒ³ćƒˆćƒ©ć‚¹ćƒˆ:", + "brightness": "ę˜Žåŗ¦:", + "saturation": "彩度:", + "download": "ćƒ€ć‚¦ćƒ³ćƒ­ćƒ¼ćƒ‰" + }, + "compress": { + "title": "圧縮", + "header": "PDFć‚’åœ§ēø®", + "credit": "ęœ¬ć‚µćƒ¼ćƒ“ć‚¹ćÆPDFの圧縮/ęœ€é©åŒ–ć«qpdfを使用しています。", + "grayscale": { + "label": "åœ§ēø®ć«ć‚°ćƒ¬ćƒ¼ć‚¹ć‚±ćƒ¼ćƒ«ć‚’é©ē”Øć™ć‚‹" + }, + "selectText": { + "1": { + "_value": "圧縮設定", + "1": "1-3 PDFåœ§ēø®ć€
4-6 å¼±ć„ē”»åƒåœ§ēø®ć€
7-9 å¼·ć„ē”»åƒåœ§ēø®ć«ć‚ˆć‚Šē”»č³ŖćŒå¤§å¹…ć«ä½Žäø‹ć—ć¾ć™" + }, + "2": "å“č³Ŗćƒ¬ćƒ™ćƒ«:", + "4": "č‡Ŗå‹•ćƒ¢ćƒ¼ćƒ‰ - PDFć‚’ę­£ē¢ŗćŖć‚µć‚¤ć‚ŗć«ć™ć‚‹ćŸć‚ć«å“č³Ŗć‚’č‡Ŗå‹•čŖæę•“ć™ć‚‹ć€‚", + "5": "PDFサイズ (例:25MB, 10.8MB, 25KB)" + }, + "submit": "圧縮" + }, + "decrypt": { + "passwordPrompt": "ć“ć®ćƒ•ć‚”ć‚¤ćƒ«ćÆćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć§äæč­·ć•ć‚Œć¦ć„ć¾ć™ć€‚ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć‚’å…„åŠ›ć—ć¦ćć ć•ć„:", + "cancelled": "PDFć®ę“ä½œćŒć‚­ćƒ£ćƒ³ć‚»ćƒ«ć•ć‚Œć¾ć—ćŸ: {0}", + "noPassword": "ęš—å·åŒ–ć•ć‚ŒćŸPDFć«ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ćŒęŒ‡å®šć•ć‚Œć¦ć„ć¾ć›ć‚“: {0}", + "invalidPassword": "ę­£ć—ć„ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć§ć‚‚ć†äø€åŗ¦ćŠč©¦ć—ćć ć•ć„ć€‚", + "invalidPasswordHeader": "PDFć®ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ćŒę­£ć—ććŖć„ć‹ć€ęš—å·åŒ–ćŒć‚µćƒćƒ¼ćƒˆć•ć‚Œć¦ć„ć¾ć›ć‚“: {0}", + "unexpectedError": "ćƒ•ć‚”ć‚¤ćƒ«ć®å‡¦ē†äø­ć«ć‚Øćƒ©ćƒ¼ćŒē™ŗē”Ÿć—ć¾ć—ćŸć€‚ć‚‚ć†äø€åŗ¦ćŠč©¦ć—ćć ć•ć„ć€‚", + "serverError": "å¾©å·åŒ–äø­ć«ć‚µćƒ¼ćƒćƒ¼ć‚Øćƒ©ćƒ¼ćŒē™ŗē”Ÿć—ć¾ć—ćŸ: {0}", + "success": "ćƒ•ć‚”ć‚¤ćƒ«ć®ęš—å·åŒ–ćŒę­£åøøć«å®Œäŗ†ć—ć¾ć—ćŸć€‚" + }, + "multiTool-advert": { + "message": "ć“ć®ę©Ÿčƒ½ćÆć€ćƒžćƒ«ćƒćƒ„ćƒ¼ćƒ«ć§ć‚‚ć”åˆ©ē”Øć„ćŸć ć‘ć¾ć™ć€‚å¼·åŒ–ć•ć‚ŒćŸćƒšćƒ¼ć‚øć”ćØć®UIćØčæ½åŠ ę©Ÿčƒ½ć«ć¤ć„ć¦ćÆć“ć”ć‚‰ć‚’ć”č¦§ćć ć•ć„ć€‚" + }, + "pageRemover": { + "title": "ćƒšćƒ¼ć‚øå‰Šé™¤", + "header": "PDFćƒšćƒ¼ć‚øå‰Šé™¤", + "pagesToDelete": "å‰Šé™¤ć™ć‚‹ćƒšćƒ¼ć‚ø (ćƒšćƒ¼ć‚øē•Ŗå·ć®ć‚«ćƒ³ćƒžåŒŗåˆ‡ć‚ŠćƒŖć‚¹ćƒˆć‚’å…„åŠ›ć—ć¦ćć ć•ć„):", + "submit": "ćƒšćƒ¼ć‚øå‰Šé™¤", + "placeholder": "(例:1,2,6または1-10,15-30)" + }, + "imageToPDF": { + "title": "ē”»åƒć‚’PDFć«å¤‰ę›", + "header": "ē”»åƒć‚’PDFć«å¤‰ę›", + "submit": "å¤‰ę›", + "selectLabel": "ē”»åƒćƒ•ć‚£ćƒƒćƒˆć‚Ŗćƒ—ć‚·ćƒ§ćƒ³", + "fillPage": "ćƒ•ćƒ«ćƒšćƒ¼ć‚ø", + "fitDocumentToImage": "ćƒšćƒ¼ć‚øć‚’ē”»åƒć«åˆć‚ć›ć‚‹", + "maintainAspectRatio": "ć‚¢ć‚¹ćƒšć‚ÆćƒˆęÆ”ć‚’ē¶­ęŒć™ć‚‹", + "selectText": { + "2": "PDFć®č‡Ŗå‹•å›žč»¢", + "3": "ćƒžćƒ«ćƒćƒ•ć‚”ć‚¤ćƒ«ć®å‡¦ē† (č¤‡ę•°ć®ē”»åƒć‚’ę“ä½œć™ć‚‹å “åˆć«ęœ‰åŠ¹ć«ćŖć‚Šć¾ć™)", + "4": "1恤恮PDFに結合", + "5": "å€‹åˆ„ć®PDFć«å¤‰ę›" + } + }, + "PDFToCSV": { + "title": "PDF悒CSVć«å¤‰ę›", + "header": "PDF悒CSVć«å¤‰ę›", + "prompt": "č”Øć‚’ęŠ½å‡ŗć™ć‚‹ćƒšćƒ¼ć‚øć‚’éøęŠž", + "submit": "å¤‰ę›" + }, + "split-by-size-or-count": { + "title": "ć‚µć‚¤ć‚ŗć¾ćŸćÆę•°ć§åˆ†å‰²", + "header": "ć‚µć‚¤ć‚ŗć¾ćŸćÆę•°ć§åˆ†å‰²", + "type": { + "label": "åˆ†å‰²ć‚æć‚¤ćƒ—ć®éøęŠž", + "size": "サイズ", + "pageCount": "ćƒšćƒ¼ć‚øę•°", + "docCount": "ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆę•°" + }, + "value": { + "label": "å€¤ć®å…„åŠ›", + "placeholder": "サイズ (例:2MB または 3KB) ć¾ćŸćÆę•°å€¤ (例:5) ć‚’å…„åŠ›" + }, + "submit": "分割" + }, + "printFile": { + "title": "ćƒ•ć‚”ć‚¤ćƒ«ć®å°åˆ·", + "header": "ćƒ•ć‚”ć‚¤ćƒ«ć‚’ćƒ—ćƒŖćƒ³ć‚æć§å°åˆ·", + "selectText": { + "1": "å°åˆ·ć™ć‚‹ćƒ•ć‚”ć‚¤ćƒ«ć‚’éøęŠž", + "2": "ćƒ—ćƒŖćƒ³ć‚æåć‚’å…„åŠ›" + }, + "submit": "ćƒ—ćƒŖćƒ³ćƒˆ" + }, + "licenses": { + "nav": "ćƒ©ć‚¤ć‚»ćƒ³ć‚¹", + "title": "ć‚µćƒ¼ćƒ‰ćƒ‘ćƒ¼ćƒ†ć‚£ćƒ©ć‚¤ć‚»ćƒ³ć‚¹", + "header": "ć‚µćƒ¼ćƒ‰ćƒ‘ćƒ¼ćƒ†ć‚£ćƒ©ć‚¤ć‚»ćƒ³ć‚¹", + "module": "ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«", + "version": "ćƒćƒ¼ć‚øćƒ§ćƒ³", + "license": "ćƒ©ć‚¤ć‚»ćƒ³ć‚¹" + }, + "survey": { + "nav": "ć‚¢ćƒ³ć‚±ćƒ¼ćƒˆ", + "title": "Stirling-PDFć®ć‚¢ćƒ³ć‚±ćƒ¼ćƒˆ", + "description": "Stirling-PDFć«ćÆčæ½č·”ę©Ÿčƒ½ćŒćŖć„ćŸć‚ć€Stirling-PDFć‚’ć‚ˆć‚Šč‰Æćć™ć‚‹ćŸć‚ć«ēš†ę§˜ć®ę„č¦‹ć‚’čžć‹ć›ć¦ćć ć•ć„ļ¼", + "changes": "Stirling-PDFćÆå‰å›žć®čŖæęŸ»ć‹ć‚‰å¤‰ę›“ć•ć‚Œć¾ć—ćŸć€‚č©³ē“°ć«ć¤ć„ć¦ćÆć“ć”ć‚‰ć®ćƒ–ćƒ­ć‚°ęŠ•ēØæć‚’ć”č¦§ćć ć•ć„ć€‚", + "changes2": "ć“ć‚Œć‚‰ć®å¤‰ę›“ć«ć‚ˆć‚Šē§ćŸć”ćÆęœ‰å„Ÿć®ćƒ“ć‚øćƒć‚¹ć‚µćƒćƒ¼ćƒˆćØč³‡é‡‘ę“åŠ©ć‚’å—ć‘ć¦ć„ć¾ć™", + "please": "ć‚¢ćƒ³ć‚±ćƒ¼ćƒˆć«ć”å”åŠ›ćć ć•ć„ļ¼", + "disabled": "ļ¼ˆć‚¢ćƒ³ć‚±ćƒ¼ćƒˆć®ćƒćƒƒćƒ—ć‚¢ćƒƒćƒ—ćÆć€ę¬”ć®ę›“ę–°ć§ćÆē„”åŠ¹ć«ćŖć‚Šć¾ć™ćŒć€ćƒšćƒ¼ć‚øć®äø‹éƒØć«č”Øē¤ŗć•ć‚Œć¾ć™ć€‚ļ¼‰", + "button": "ć‚¢ćƒ³ć‚±ćƒ¼ćƒˆć«ē­”ćˆć‚‹", + "dontShowAgain": "å†ć³č”Øē¤ŗć—ćŖć„", + "meeting": { + "1": "職堓でStirling PDFć‚’ć”åˆ©ē”Øć®å “åˆćÆćœć²ć”é€£ēµ”ćć ć•ć„ć€‚15åˆ†é–“ć®ćƒ¦ćƒ¼ć‚¶ćƒ¼ ćƒ‡ć‚£ć‚¹ć‚«ćƒćƒŖćƒ¼ć‚»ćƒƒć‚·ćƒ§ćƒ³ćØå¼•ćę›ćˆć«ćƒ†ć‚Æćƒ‹ć‚«ćƒ«ć‚µćƒćƒ¼ćƒˆć‚»ćƒƒć‚·ćƒ§ćƒ³ć‚’ć”ęä¾›ć—ć¦ć„ć¾ć™ć€‚", + "2": "ć“ć‚ŒćÆćƒćƒ£ćƒ³ć‚¹ć§ć™:", + "3": "å±•é–‹ć€ēµ±åˆć€ć¾ćŸćÆćƒˆćƒ©ćƒ–ćƒ«ć‚·ćƒ„ćƒ¼ćƒ†ć‚£ćƒ³ć‚°ć«é–¢ć™ć‚‹ćƒ˜ćƒ«ćƒ—ć‚’å–å¾—ć—ć¾ć™", + "4": "ćƒ‘ćƒ•ć‚©ćƒ¼ćƒžćƒ³ć‚¹ć€ć‚Øćƒƒć‚øć‚±ćƒ¼ć‚¹ć€ę©Ÿčƒ½ć®ć‚®ćƒ£ćƒƒćƒ—ć«é–¢ć™ć‚‹ē›“ęŽ„ēš„ćŖćƒ•ć‚£ćƒ¼ćƒ‰ćƒćƒƒć‚Æć‚’ęä¾›ć™ć‚‹", + "5": "Stirling PDFć‚’ä¼ę„­ć§å®Ÿéš›ć«ä½æē”Øć§ćć‚‹ć‚ˆć†ć«ę”¹č‰Æć«ć”å”åŠ›ćć ć•ć„", + "6": "čˆˆå‘³ćŒć‚ć‚Šć¾ć—ćŸć‚‰ć€å¼Šē¤¾ć®ćƒćƒ¼ćƒ ć«ē›“ęŽ„ć”äŗˆē“„ćć ć•ć„ć€‚ļ¼ˆč‹±čŖžć®ćæļ¼‰", + "7": "ēš†ć•ć‚“ć®ćƒ¦ćƒ¼ć‚¹ć‚±ćƒ¼ć‚¹ć‚’ęŽ˜ć‚Šäø‹ć’ć¦Stirling PDFをさらに改善することを愽しみにしています。", + "notInterested": "ćƒ“ć‚øćƒć‚¹ć§ćÆćŖć„ć€ć¾ćŸćÆä¼šč­°ć«čˆˆå‘³ćŒć‚ć‚Šć¾ć›ć‚“ć‹ļ¼Ÿ", + "button": "ćƒ–ćƒƒć‚ÆćƒŸćƒ¼ćƒ†ć‚£ćƒ³ć‚°" + } + }, + "removeImage": { + "title": "ē”»åƒć®å‰Šé™¤", + "header": "ē”»åƒć®å‰Šé™¤", + "removeImage": "ē”»åƒć®å‰Šé™¤", + "submit": "ē”»åƒć‚’å‰Šé™¤" + }, + "splitByChapters": { + "title": "PDFć‚’ćƒćƒ£ćƒ—ć‚æćƒ¼ć”ćØć«åˆ†å‰²", + "header": "PDFć‚’ćƒćƒ£ćƒ—ć‚æćƒ¼ć”ćØć«åˆ†å‰²", + "bookmarkLevel": "ćƒ–ćƒƒć‚Æćƒžćƒ¼ć‚Æćƒ¬ćƒ™ćƒ«", + "includeMetadata": "ćƒ”ć‚æćƒ‡ćƒ¼ć‚æć‚’å«ć‚ć‚‹", + "allowDuplicates": "é‡č¤‡ć‚’čØ±åÆć™ć‚‹", + "desc": { + "1": "ć“ć®ćƒ„ćƒ¼ćƒ«ćÆć€ćƒćƒ£ćƒ—ć‚æćƒ¼ę§‹é€ ć«åŸŗć„ć„ć¦PDFćƒ•ć‚”ć‚¤ćƒ«ć‚’č¤‡ę•°ć®PDFć«åˆ†å‰²ć—ć¾ć™ć€‚", + "2": "ćƒ–ćƒƒć‚Æćƒžćƒ¼ć‚Æćƒ¬ćƒ™ćƒ«:åˆ†å‰²ć«ä½æē”Øć™ć‚‹ćƒ–ćƒƒć‚Æćƒžćƒ¼ć‚Æć®ćƒ¬ćƒ™ćƒ«ć‚’éøęŠžć—ć¾ć™ļ¼ˆęœ€äøŠä½ćƒ¬ćƒ™ćƒ«ć®å “åˆćÆ0、第2ćƒ¬ćƒ™ćƒ«ć®å “åˆćÆ1など)。", + "3": "ćƒ”ć‚æćƒ‡ćƒ¼ć‚æć‚’å«ć‚ć‚‹:ćƒć‚§ćƒƒć‚Æć™ć‚‹ćØć€å…ƒć®PDFć®ćƒ”ć‚æćƒ‡ćƒ¼ć‚æćŒå„åˆ†å‰²PDFć«å«ć¾ć‚Œć¾ć™ć€‚", + "4": "é‡č¤‡ć‚’čØ±åÆ:ćƒć‚§ćƒƒć‚Æć™ć‚‹ćØåŒć˜ćƒšćƒ¼ć‚øäøŠć®č¤‡ę•°ć®ćƒ–ćƒƒć‚Æćƒžćƒ¼ć‚Æć‹ć‚‰å€‹åˆ„ć®PDFć‚’ä½œęˆć§ćć¾ć™ć€‚" + }, + "submit": "PDFć‚’åˆ†å‰²" + }, + "fileChooser": { + "click": "ć‚ÆćƒŖćƒƒć‚Æ", + "or": "または", + "dragAndDrop": "ćƒ‰ćƒ©ćƒƒć‚°ļ¼†ćƒ‰ćƒ­ćƒƒćƒ—", + "dragAndDropPDF": "PDFćƒ•ć‚”ć‚¤ćƒ«ć‚’ćƒ‰ćƒ©ćƒƒć‚°ļ¼†ćƒ‰ćƒ­ćƒƒćƒ—", + "dragAndDropImage": "ē”»åƒćƒ•ć‚”ć‚¤ćƒ«ć‚’ćƒ‰ćƒ©ćƒƒć‚°ļ¼†ćƒ‰ćƒ­ćƒƒćƒ—", + "hoveredDragAndDrop": "ćƒ•ć‚”ć‚¤ćƒ«ć‚’ć“ć“ć«ćƒ‰ćƒ©ćƒƒć‚°ļ¼†ćƒ‰ćƒ­ćƒƒćƒ—", + "extractPDF": "ęŠ½å‡ŗäø­..." + }, + "releases": { + "footer": "ćƒŖćƒŖćƒ¼ć‚¹", + "title": "ćƒŖćƒŖćƒ¼ć‚¹ćƒŽćƒ¼ćƒˆ", + "header": "ćƒŖćƒŖćƒ¼ć‚¹ćƒŽćƒ¼ćƒˆ", + "current": { + "version": "ē¾åœØć®ćƒŖćƒŖćƒ¼ć‚¹" + }, + "note": "ćƒŖćƒŖćƒ¼ć‚¹ćƒŽćƒ¼ćƒˆćÆč‹±čŖžć§ć®ćæć§ęä¾›ć•ć‚Œć¦ć„ć¾ć™" + }, + "cookieBanner": { + "popUp": { + "title": "ć‚Æćƒƒć‚­ćƒ¼ć®ä½æē”Øę–¹ę³•", + "description": { + "1": "私たごはStirling PDFć‚’ć‚ˆć‚Šåæ«é©ć«ć”åˆ©ē”Øć„ćŸć ć‘ć‚‹ć‚ˆć†Cookieć‚„ćć®ä»–ć®ćƒ†ć‚ÆćƒŽćƒ­ć‚øćƒ¼ć‚’ä½æē”Øć—ć¦ć„ć¾ć™ć€‚ć“ć‚Œć«ć‚ˆć‚Šćƒ„ćƒ¼ćƒ«ć®ę”¹å–„ć‚„ćŠę°—ć«å…„ć‚Šć®ę©Ÿčƒ½ć®ę§‹ēÆ‰ć‚’ē¶™ē¶šć§ćć¾ć™ć€‚", + "2": "åøŒęœ›ć—ćŖć„å “åˆćÆć€Œć„ć„ćˆć€ć‚’ć‚ÆćƒŖćƒƒć‚Æć™ć‚‹ćØć€ć‚¹ćƒ ćƒ¼ć‚ŗć«å‹•ä½œć™ć‚‹ćŸć‚ć«åæ…č¦ćŖCookieć®ćæćŒęœ‰åŠ¹ć«ćŖć‚Šć¾ć™ć€‚" + }, + "acceptAllBtn": "Ok", + "acceptNecessaryBtn": "恄恄恈", + "showPreferencesBtn": "čØ­å®šć®ē®”ē†" + }, + "preferencesModal": { + "title": "åŒę„ē®”ē†ć‚»ćƒ³ć‚æćƒ¼", + "acceptAllBtn": "ć™ć¹ć¦å—ć‘å…„ć‚Œć‚‹", + "acceptNecessaryBtn": "すべて拒否する", + "savePreferencesBtn": "ē’°å¢ƒčØ­å®šć®äæå­˜", + "closeIconLabel": "ćƒ¢ćƒ¼ćƒ€ćƒ«ć‚’é–‰ć˜ć‚‹", + "serviceCounterLabel": "ć‚µćƒ¼ćƒ“ć‚¹", + "subtitle": "Cookieの使用", + "description": { + "1": "Stirling PDFćÆćŠå®¢ę§˜ć®ä½“éØ“ć®å‘äøŠć€ćƒ„ćƒ¼ćƒ«ć®åˆ©ē”ØēŠ¶ę³ć‚’ęŠŠę”ć™ć‚‹ćŸć‚ć«CookiećŖć©ć®ćƒ†ć‚ÆćƒŽćƒ­ć‚øćƒ¼ć‚’ä½æē”Øć—ć¦ć„ć¾ć™ć€‚ć“ć‚Œć«ć‚ˆć‚Šćƒ‘ćƒ•ć‚©ćƒ¼ćƒžćƒ³ć‚¹ć®å‘äøŠć€ćŠå®¢ę§˜ćŒę±‚ć‚ć‚‹ę©Ÿčƒ½ć®é–‹ē™ŗć€ćć—ć¦ćƒ¦ćƒ¼ć‚¶ćƒ¼ćøć®ē¶™ē¶šēš„ćŖć‚µćƒćƒ¼ćƒˆć®ęä¾›ćŒåÆčƒ½ć«ćŖć‚Šć¾ć™ć€‚", + "2": "Stirling PDFćÆćƒ¦ćƒ¼ć‚¶ćƒ¼ćŒä½æē”Øć™ć‚‹ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć®å†…å®¹ć‚’čæ½č·”ć—ćŸć‚Šć‚¢ć‚Æć‚»ć‚¹ć—ćŸć‚Šć™ć‚‹ć“ćØćÆć§ćć¾ć›ć‚“ć€‚", + "3": "ćŠå®¢ę§˜ć®ćƒ—ćƒ©ć‚¤ćƒć‚·ćƒ¼ćØäæ”é ¼ćÆå½“ē¤¾ć®ę“»å‹•ć®äø­ę øć§ć™ć€‚" + }, + "necessary": { + "title": { + "1": "åŽ³åÆ†ć«åæ…č¦ćŖCookie", + "2": "åøøć«ęœ‰åŠ¹" + }, + "description": "ć“ć‚Œć‚‰ć®CookiećÆć‚¦ć‚§ćƒ–ć‚µć‚¤ćƒˆćŒę­£åøøć«ę©Ÿčƒ½ć™ć‚‹ćŸć‚ć«äøåÆę¬ ć§ć™ć€‚ćƒ—ćƒ©ć‚¤ćƒć‚·ćƒ¼čØ­å®šć€ćƒ­ć‚°ć‚¤ćƒ³ć€ćƒ•ć‚©ćƒ¼ćƒ ćøć®å…„åŠ›ćØć„ć£ćŸć‚³ć‚¢ę©Ÿčƒ½ć‚’ęœ‰åŠ¹ć«ć™ć‚‹ćŸć‚ć€ē„”åŠ¹ć«ć™ć‚‹ć“ćØćÆć§ćć¾ć›ć‚“ć€‚" + }, + "analytics": { + "title": "åˆ†ęž", + "description": "ć“ć‚Œć‚‰ć®CookiećÆćƒ„ćƒ¼ćƒ«ćŒć©ć®ć‚ˆć†ć«ä½æē”Øć•ć‚Œć¦ć„ć‚‹ć‹ć‚’ęŠŠę”ć™ć‚‹ć®ć«å½¹ē«‹ć”ć¾ć™ć€‚ć“ć‚Œć«ć‚ˆć‚Šć‚³ćƒŸćƒ„ćƒ‹ćƒ†ć‚£ćŒęœ€ć‚‚é‡č¦–ć™ć‚‹ę©Ÿčƒ½ć®é–‹ē™ŗć«é›†äø­ć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ć”å®‰åæƒćć ć•ć„ć€‚Stirling PDFćÆćŠå®¢ę§˜ćŒę“ä½œć™ć‚‹ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć®å†…å®¹ć‚’čæ½č·”ć™ć‚‹ć“ćØćÆę±ŗć—ć¦ć‚ć‚Šć¾ć›ć‚“ć€‚" + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/ko-KR/translation.json b/frontend/public/locales/ko-KR/translation.json new file mode 100644 index 000000000..0552d717f --- /dev/null +++ b/frontend/public/locales/ko-KR/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "글꼓 크기", + "fontName": "글꼓 ģ“ė¦„", + "title": "ķŽ˜ģ“ģ§€ 번호 추가", + "header": "ķŽ˜ģ“ģ§€ 번호 추가", + "selectText": { + "1": "PDF ķŒŒģ¼ ģ„ ķƒ:", + "2": "여백 크기", + "3": "ģœ„ģ¹˜", + "4": "ģ‹œģž‘ 번호", + "5": "번호넼 매길 ķŽ˜ģ“ģ§€", + "6": "ģ‚¬ģš©ģž 지정 ķ…ģŠ¤ķŠø" + }, + "customTextDesc": "ģ‚¬ģš©ģž 지정 ķ…ģŠ¤ķŠø", + "numberPagesDesc": "번호넼 매길 ķŽ˜ģ“ģ§€, źø°ė³øź°’ 'all', 1-5 ė˜ėŠ” 2,5,9 ė“±ė„ ź°€ėŠ„", + "customNumberDesc": "źø°ė³øź°’ģ€ {n}, 'ķŽ˜ģ“ģ§€ {n} / {total}', 'ķ…ģŠ¤ķŠø-{n}', '{filename}-{n}' ė“±ė„ ź°€ėŠ„", + "submit": "ķŽ˜ģ“ģ§€ 번호 추가" + }, + "pdfPrompt": "PDF ģ„ ķƒ", + "multiPdfPrompt": "PDF ģ„ ķƒ (2개 ģ“ģƒ)", + "multiPdfDropPrompt": "ķ•„ģš”ķ•œ ėŖØė“  PDF넼 ģ„ ķƒ(ė˜ėŠ” ėŒģ–“ė‹¤ 놓기)ķ•˜ģ„øģš”", + "imgPrompt": "ģ“ėÆøģ§€ ģ„ ķƒ", + "genericSubmit": "제출", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "경고: ģ“ ź³¼ģ •ģ€ ķŒŒģ¼ 크기에 ė”°ė¼ ģµœėŒ€ 1ė¶„ģ“ ģ†Œģš”ė  수 ģžˆģŠµė‹ˆė‹¤", + "pageOrderPrompt": "ģ‚¬ģš©ģž 지정 ķŽ˜ģ“ģ§€ ģˆœģ„œ (ģ‰¼ķ‘œė”œ źµ¬ė¶„ėœ ķŽ˜ģ“ģ§€ 번호 ėŖ©ė” ė˜ėŠ” 2n+1ź³¼ ź°™ģ€ ķ•Øģˆ˜ ģž…ė „):", + "pageSelectionPrompt": "ģ‚¬ģš©ģž 지정 ķŽ˜ģ“ģ§€ ģ„ ķƒ (ķŽ˜ģ“ģ§€ 번호 1,5,6 ė˜ėŠ” 2n+1ź³¼ ź°™ģ€ ķ•Øģˆ˜ė„¼ ģ‰¼ķ‘œė”œ źµ¬ė¶„ķ•˜ģ—¬ ėŖ©ė” ģž…ė „):", + "goToPage": "ģ“ė™", + "true": "ģ°ø", + "false": "ź±°ģ§“", + "unknown": "ģ•Œ 수 ģ—†ģŒ", + "save": "ģ €ģž„", + "saveToBrowser": "ėøŒė¼ģš°ģ €ģ— ģ €ģž„", + "close": "ė‹«źø°", + "filesSelected": "ź°œģ˜ ķŒŒģ¼ģ“ ģ„ ķƒėØ", + "noFavourites": "즐겨찾기가 ģ¶”ź°€ė˜ģ§€ ģ•Šģ•˜ģŠµė‹ˆė‹¤", + "downloadComplete": "ė‹¤ģš“ė”œė“œ ģ™„ė£Œ", + "bored": "źø°ė‹¤ė¦¬ėŠ” ź²ƒģ“ ģ§€ė£Øķ•˜ģ‹ ź°€ģš”?", + "alphabet": "ģ•ŒķŒŒė²³", + "downloadPdf": "PDF ė‹¤ģš“ė”œė“œ", + "text": "ķ…ģŠ¤ķŠø", + "font": "글꼓", + "selectFillter": "-- ģ„ ķƒ --", + "pageNum": "ķŽ˜ģ“ģ§€ 번호", + "sizes": { + "small": "ģž‘ź²Œ", + "medium": "중간", + "large": "크게", + "x-large": "매우 크게" + }, + "error": { + "pdfPassword": "PDF ė¬øģ„œź°€ ė¹„ė°€ė²ˆķ˜øė”œ ė³“ķ˜øė˜ģ–“ ģžˆģœ¼ė©°, ė¹„ė°€ė²ˆķ˜øź°€ ģ œź³µė˜ģ§€ ģ•Šģ•˜ź±°ė‚˜ ģ˜¬ė°”ė„“ģ§€ ģ•ŠģŠµė‹ˆė‹¤", + "_value": "오넘", + "sorry": "ė¬øģ œź°€ ė°œģƒķ•“ ģ£„ģ†”ķ•©ė‹ˆė‹¤!", + "needHelp": "ė„ģ›€ģ“ ķ•„ģš”ķ•˜ģ‹ ź°€ģš” / 문제넼 ė°œź²¬ķ•˜ģ…Øė‚˜ģš”?", + "contactTip": "ģ—¬ģ „ķžˆ ė¬øģ œź°€ ģžˆė‹¤ė©“ ģ£¼ģ €ķ•˜ģ§€ ė§ˆģ‹œź³  ė„ģ›€ģ„ ģš”ģ²­ķ•˜ģ„øģš”. GitHub ķŽ˜ģ“ģ§€ģ—ģ„œ ķ‹°ģ¼“ģ„ ģ œģ¶œķ•˜ź±°ė‚˜ Discord넼 통핓 ģ—°ė½ķ•˜ģ‹¤ 수 ģžˆģŠµė‹ˆė‹¤:", + "404": { + "head": "404 - ķŽ˜ģ“ģ§€ė„¼ ģ°¾ģ„ 수 ģ—†ģŠµė‹ˆė‹¤ | ģ“ėŸ°, ģ½”ė“œģ—ģ„œ źøøģ„ ģžƒģ—ˆė„¤ģš”!", + "1": "ģ°¾ģœ¼ģ‹œėŠ” ķŽ˜ģ“ģ§€ė„¼ ģ°¾ģ„ 수 ģ—†ģŠµė‹ˆė‹¤.", + "2": "ė¬øģ œź°€ ė°œģƒķ–ˆģŠµė‹ˆė‹¤" + }, + "github": "GitHubģ—ģ„œ 티켓 제출", + "showStack": "ģŠ¤ķƒ 추적 ķ‘œģ‹œ", + "copyStack": "ģŠ¤ķƒ 추적 복사", + "githubSubmit": "GitHub - 티켓 제출", + "discordSubmit": "Discord - 지원 ź²Œģ‹œė¬¼ ģž‘ģ„±" + }, + "delete": "ģ‚­ģ œ", + "username": "ģ‚¬ģš©ģž ģ“ė¦„", + "password": "ė¹„ė°€ė²ˆķ˜ø", + "welcome": "ķ™˜ģ˜ķ•©ė‹ˆė‹¤", + "property": "ģ†ģ„±", + "black": "검정", + "white": "ķ°ģƒ‰", + "red": "빨강", + "green": "ģ“ˆė”", + "blue": "ķŒŒėž‘", + "custom": "ģ‚¬ģš©ģž 지정...", + "WorkInProgess": "ģž‘ģ—… ģ§„ķ–‰ 중, ģž‘ė™ķ•˜ģ§€ ģ•Šź±°ė‚˜ 버그가 ģžˆģ„ 수 ģžˆģŠµė‹ˆė‹¤. ė¬øģ œź°€ ģžˆģœ¼ė©“ ģ‹ ź³ ķ•“ ģ£¼ģ„øģš”!", + "poweredBy": "제공", + "yes": "예", + "no": "ģ•„ė‹ˆģ˜¤", + "changedCredsMessage": "ģžź²© ģ¦ėŖ…ģ“ ė³€ź²½ė˜ģ—ˆģŠµė‹ˆė‹¤!", + "notAuthenticatedMessage": "ģ‚¬ģš©ģžź°€ ģøģ¦ė˜ģ§€ ģ•Šģ•˜ģŠµė‹ˆė‹¤.", + "userNotFoundMessage": "ģ‚¬ģš©ģžė„¼ ģ°¾ģ„ 수 ģ—†ģŠµė‹ˆė‹¤.", + "incorrectPasswordMessage": "ķ˜„ģž¬ ė¹„ė°€ė²ˆķ˜øź°€ ģ˜¬ė°”ė„“ģ§€ ģ•ŠģŠµė‹ˆė‹¤.", + "usernameExistsMessage": "새 ģ‚¬ģš©ģž ģ“ė¦„ģ“ ģ“ėÆø ģ”“ģž¬ķ•©ė‹ˆė‹¤.", + "invalidUsernameMessage": "ģž˜ėŖ»ėœ ģ‚¬ģš©ģž ģ“ė¦„ģž…ė‹ˆė‹¤. ģ‚¬ģš©ģž ģ“ė¦„ģ€ ė¬øģž, ģˆ«ģž ė° @._+- ķŠ¹ģˆ˜ė¬øģžė§Œ ķ¬ķ•Øķ•˜ź±°ė‚˜ ģœ ķšØķ•œ ģ“ė©”ģ¼ ģ£¼ģ†Œģ—¬ģ•¼ ķ•©ė‹ˆė‹¤.", + "invalidPasswordMessage": "ė¹„ė°€ė²ˆķ˜øėŠ” 비얓 ģžˆģœ¼ė©“ ģ•ˆ 되며 ģ‹œģž‘ź³¼ ėģ— ź³µė°±ģ“ ģžˆģœ¼ė©“ ģ•ˆ ė©ė‹ˆė‹¤.", + "confirmPasswordErrorMessage": "새 ė¹„ė°€ė²ˆķ˜øģ™€ 새 ė¹„ė°€ė²ˆķ˜ø ķ™•ģøģ“ ģ¼ģ¹˜ķ•“ģ•¼ ķ•©ė‹ˆė‹¤.", + "deleteCurrentUserMessage": "ķ˜„ģž¬ ė”œź·øģøėœ ģ‚¬ģš©ģžė„¼ ģ‚­ģ œķ•  수 ģ—†ģŠµė‹ˆė‹¤.", + "deleteUsernameExistsMessage": "ģ”“ģž¬ķ•˜ģ§€ ģ•ŠėŠ” ģ‚¬ģš©ģž ģ“ė¦„ģ€ ģ‚­ģ œķ•  수 ģ—†ģŠµė‹ˆė‹¤.", + "downgradeCurrentUserMessage": "ķ˜„ģž¬ ģ‚¬ģš©ģžģ˜ ģ—­ķ• ģ„ 강등할 수 ģ—†ģŠµė‹ˆė‹¤", + "disabledCurrentUserMessage": "ķ˜„ģž¬ ģ‚¬ģš©ģžė„¼ ė¹„ķ™œģ„±ķ™”ķ•  수 ģ—†ģŠµė‹ˆė‹¤", + "downgradeCurrentUserLongMessage": "ķ˜„ģž¬ ģ‚¬ģš©ģžģ˜ ģ—­ķ• ģ„ 강등할 수 ģ—†ģŠµė‹ˆė‹¤. ė”°ė¼ģ„œ ķ˜„ģž¬ ģ‚¬ģš©ģžėŠ” ķ‘œģ‹œė˜ģ§€ ģ•ŠģŠµė‹ˆė‹¤.", + "userAlreadyExistsOAuthMessage": "핓당 ģ‚¬ģš©ģžėŠ” ģ“ėÆø OAuth2 ģ‚¬ģš©ģžė”œ ģ”“ģž¬ķ•©ė‹ˆė‹¤.", + "userAlreadyExistsWebMessage": "핓당 ģ‚¬ģš©ģžėŠ” ģ“ėÆø 웹 ģ‚¬ģš©ģžė”œ ģ”“ģž¬ķ•©ė‹ˆė‹¤.", + "oops": "ģ“ėŸ°!", + "help": "ė„ģ›€ė§", + "goHomepage": "ķ™ˆķŽ˜ģ“ģ§€ė”œ ģ“ė™", + "joinDiscord": "Discord ģ„œė²„ ź°€ģž…ķ•˜źø°", + "seeDockerHub": "Docker Hub 볓기", + "visitGithub": "Github ģ €ģž„ģ†Œ 방문", + "donate": "źø°ė¶€ķ•˜źø°", + "color": "ģƒ‰ģƒ", + "sponsor": "후원", + "info": "정볓", + "pro": "ķ”„ė”œ", + "page": "ķŽ˜ģ“ģ§€", + "pages": "ķŽ˜ģ“ģ§€", + "loading": "ė”œė”© 중...", + "addToDoc": "ė¬øģ„œģ— 추가", + "reset": "ģ“ˆźø°ķ™”", + "apply": "적용", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "ź°œģøģ •ė³“ 처리방침", + "terms": "ģ“ģš©ģ•½ź“€", + "accessibility": "접근성", + "cookie": "쿠키 ģ •ģ±…", + "impressum": "법적 ź³ ģ§€", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "ķŒŒģ“ķ”„ė¼ģø 메뉓 (ė² ķƒ€)", + "uploadButton": "ģ‚¬ģš©ģž 지정 ģ—…ė”œė“œ", + "configureButton": "구성", + "defaultOption": "ģ‚¬ģš©ģž 지정", + "submitButton": "제출", + "help": "ķŒŒģ“ķ”„ė¼ģø ė„ģ›€ė§", + "scanHelp": "ķ“ė” ģŠ¤ģŗ” ė„ģ›€ė§", + "deletePrompt": "ķŒŒģ“ķ”„ė¼ģøģ„ ģ‚­ģ œķ•˜ģ‹œź² ģŠµė‹ˆź¹Œ?", + "tags": "ģžė™ķ™”,ģˆœģ„œ,스크립트,ģ¼ź“„-처리", + "title": "ķŒŒģ“ķ”„ė¼ģø" + }, + "pipelineOptions": { + "header": "ķŒŒģ“ķ”„ė¼ģø 구성", + "pipelineNameLabel": "ķŒŒģ“ķ”„ė¼ģø ģ“ė¦„", + "saveSettings": "ģž‘ģ—… 설정 ģ €ģž„", + "pipelineNamePrompt": "여기에 ķŒŒģ“ķ”„ė¼ģø ģ“ė¦„ ģž…ė „", + "selectOperation": "ģž‘ģ—… ģ„ ķƒ", + "addOperationButton": "ģž‘ģ—… 추가", + "pipelineHeader": "ķŒŒģ“ķ”„ė¼ģø:", + "saveButton": "ė‹¤ģš“ė”œė“œ", + "validateButton": "ź²€ģ¦" + }, + "enterpriseEdition": { + "button": "ķ”„ė”œ ė²„ģ „ģœ¼ė”œ ģ—…ź·øė ˆģ“ė“œ", + "warning": "ģ“ źø°ėŠ„ģ€ ķ”„ė”œ ģ‚¬ģš©ģžė§Œ ģ“ģš©ķ•  수 ģžˆģŠµė‹ˆė‹¤.", + "yamlAdvert": "Stirling PDF ķ”„ė”œėŠ” YAML 구성 ķŒŒģ¼ź³¼ źø°ķƒ€ SSO źø°ėŠ„ģ„ ģ§€ģ›ķ•©ė‹ˆė‹¤.", + "ssoAdvert": "ė” ė§Žģ€ ģ‚¬ģš©ģž ꓀리 źø°ėŠ„ģ„ 찾고 ź³„ģ‹ ź°€ģš”? Stirling PDF Pro넼 ķ™•ģøķ•“ė³“ģ„øģš”" + }, + "analytics": { + "title": "Stirling PDF넼 ė” ģ¢‹ź²Œ ė§Œė“¤ź³  ģ‹¶ģœ¼ģ‹ ź°€ģš”?", + "paragraph1": "Stirling PDFėŠ” ģ œķ’ˆ ź°œģ„ ģ„ ģœ„ķ•œ ģ„ ķƒģ  ė¶„ģ„ źø°ėŠ„ģ“ ģžˆģŠµė‹ˆė‹¤. ź°œģøģ •ė³“ė‚˜ ķŒŒģ¼ ė‚“ģš©ģ€ ģ¶”ģ ķ•˜ģ§€ ģ•ŠģŠµė‹ˆė‹¤.", + "paragraph2": "Stirling-PDFģ˜ ģ„±ģž„ģ„ ė•ź³  ģ‚¬ģš©ģžė„¼ ė” ģž˜ ģ“ķ•“ķ•  수 ģžˆė„ė” ė¶„ģ„ 기늄 ķ™œģ„±ķ™”ė„¼ ź³ ė ¤ķ•“ģ£¼ģ„øģš”.", + "enable": "ė¶„ģ„ ķ™œģ„±ķ™”", + "disable": "ė¶„ģ„ ė¹„ķ™œģ„±ķ™”", + "settings": "config/settings.yml ķŒŒģ¼ģ—ģ„œ ė¶„ģ„ ģ„¤ģ •ģ„ 변경할 수 ģžˆģŠµė‹ˆė‹¤" + }, + "navbar": { + "favorite": "즐겨찾기", + "recent": "New and recently updated", + "darkmode": "다크 ėŖØė“œ", + "language": "ģ–øģ–“", + "settings": "설정", + "allTools": "ė„źµ¬", + "multiTool": "멀티 ė„źµ¬", + "search": "ź²€ģƒ‰", + "sections": { + "organize": "구성", + "convertTo": "PDF딜 ė³€ķ™˜", + "convertFrom": "PDFģ—ģ„œ ė³€ķ™˜", + "security": "ģ„œėŖ… & ė³“ģ•ˆ", + "advance": "ź³ źø‰", + "edit": "볓기 & ķŽøģ§‘", + "popular": "ģøźø°" + } + }, + "settings": { + "title": "설정", + "update": "ģ—…ė°ģ“ķŠø ź°€ėŠ„", + "updateAvailable": "{0}ģ€(ėŠ”) ķ˜„ģž¬ ģ„¤ģ¹˜ėœ ė²„ģ „ģž…ė‹ˆė‹¤. 새 버전({1})ģ“ ģ‚¬ģš© ź°€ėŠ„ķ•©ė‹ˆė‹¤.", + "appVersion": "앱 버전:", + "downloadOption": { + "title": "ė‹¤ģš“ė”œė“œ ģ˜µģ…˜ ģ„ ķƒ (ė‹Øģ¼ ķŒŒģ¼ 비압축 ė‹¤ģš“ė”œė“œģš©):", + "1": "ź°™ģ€ ģ°½ģ—ģ„œ ģ—“źø°", + "2": "새 ģ°½ģ—ģ„œ ģ—“źø°", + "3": "ķŒŒģ¼ ė‹¤ģš“ė”œė“œ" + }, + "zipThreshold": "ė‹¤ģš“ė”œė“œ ķŒŒģ¼ ģˆ˜ź°€ ė‹¤ģŒģ„ ģ“ˆź³¼ķ•  ė•Œ ZIP으딜 ģ••ģ¶•", + "signOut": "ė”œź·øģ•„ģ›ƒ", + "accountSettings": "계정 설정", + "bored": { + "help": "ģ“ģŠ¤ķ„°ģ—ź·ø ź²Œģž„ ķ™œģ„±ķ™”" + }, + "cacheInputs": { + "name": "ģž…ė „ ģ–‘ģ‹ ģ €ģž„", + "help": "ė‹¤ģŒ ģ‹¤ķ–‰ģ„ ģœ„ķ•“ ģ“ģ „ģ— ģ‚¬ģš©ķ•œ ģž…ė „ģ„ ģ €ģž„ķ•˜ė„ė” ķ™œģ„±ķ™”" + } + }, + "changeCreds": { + "title": "ģžź²© ģ¦ėŖ… 변경", + "header": "계정 정볓 ģ—…ė°ģ“ķŠø", + "changePassword": "źø°ė³ø ė”œź·øģø ģžź²© ģ¦ėŖ…ģ„ ģ‚¬ģš© ģ¤‘ģž…ė‹ˆė‹¤. 새 ė¹„ė°€ė²ˆķ˜øė„¼ ģž…ė „ķ•˜ģ„øģš”", + "newUsername": "새 ģ‚¬ģš©ģž ģ“ė¦„", + "oldPassword": "ķ˜„ģž¬ ė¹„ė°€ė²ˆķ˜ø", + "newPassword": "새 ė¹„ė°€ė²ˆķ˜ø", + "confirmNewPassword": "새 ė¹„ė°€ė²ˆķ˜ø ķ™•ģø", + "submit": "변경 사항 제출" + }, + "account": { + "title": "계정 설정", + "accountSettings": "계정 설정", + "adminSettings": "ź“€ė¦¬ģž 설정 - ģ‚¬ģš©ģž 볓기 ė° 추가", + "userControlSettings": "ģ‚¬ģš©ģž ģ œģ–“ 설정", + "changeUsername": "ģ‚¬ģš©ģž ģ“ė¦„ 변경", + "newUsername": "새 ģ‚¬ģš©ģž ģ“ė¦„", + "password": "ķ™•ģø ė¹„ė°€ė²ˆķ˜ø", + "oldPassword": "ģ“ģ „ ė¹„ė°€ė²ˆķ˜ø", + "newPassword": "새 ė¹„ė°€ė²ˆķ˜ø", + "changePassword": "ė¹„ė°€ė²ˆķ˜ø 변경", + "confirmNewPassword": "새 ė¹„ė°€ė²ˆķ˜ø ķ™•ģø", + "signOut": "ė”œź·øģ•„ģ›ƒ", + "yourApiKey": "API 키", + "syncTitle": "ėøŒė¼ģš°ģ € ģ„¤ģ •ģ„ 계정과 ė™źø°ķ™”", + "settingsCompare": "설정 비교:", + "property": "ģ†ģ„±", + "webBrowserSettings": "웹 ėøŒė¼ģš°ģ € 설정", + "syncToBrowser": "ė™źø°ķ™” 계정 -> ėøŒė¼ģš°ģ €", + "syncToAccount": "ė™źø°ķ™” 계정 <- ėøŒė¼ģš°ģ €" + }, + "adminUserSettings": { + "title": "ģ‚¬ģš©ģž ģ œģ–“ 설정", + "header": "ź“€ė¦¬ģž ģ‚¬ģš©ģž ģ œģ–“ 설정", + "admin": "ź“€ė¦¬ģž", + "user": "ģ‚¬ģš©ģž", + "addUser": "새 ģ‚¬ģš©ģž 추가", + "deleteUser": "ģ‚¬ģš©ģž ģ‚­ģ œ", + "confirmDeleteUser": "ģ‚¬ģš©ģžė„¼ ģ‚­ģ œķ•˜ģ‹œź² ģŠµė‹ˆź¹Œ?", + "confirmChangeUserStatus": "ģ‚¬ģš©ģžė„¼ ė¹„ķ™œģ„±ķ™”/ķ™œģ„±ķ™”ķ•˜ģ‹œź² ģŠµė‹ˆź¹Œ?", + "usernameInfo": "ģ‚¬ģš©ģž ģ“ė¦„ģ€ ė¬øģž, ģˆ«ģž ė° @._+- ķŠ¹ģˆ˜ė¬øģžė§Œ ķ¬ķ•Øķ•˜ź±°ė‚˜ ģœ ķšØķ•œ ģ“ė©”ģ¼ ģ£¼ģ†Œģ—¬ģ•¼ ķ•©ė‹ˆė‹¤.", + "roles": "ģ—­ķ• ", + "role": "ģ—­ķ• ", + "actions": "ģž‘ģ—…", + "apiUser": "ģ œķ•œėœ API ģ‚¬ģš©ģž", + "extraApiUser": "추가 ģ œķ•œėœ API ģ‚¬ģš©ģž", + "webOnlyUser": "웹 ģ „ģš© ģ‚¬ģš©ģž", + "demoUser": "ė°ėŖØ ģ‚¬ģš©ģž (ģ‚¬ģš©ģž 지정 설정 ģ—†ģŒ)", + "internalApiUser": "ė‚“ė¶€ API ģ‚¬ģš©ģž", + "forceChange": "ė”œź·øģø ģ‹œ ģ‚¬ģš©ģž ė¹„ė°€ė²ˆķ˜ø 변경 ź°•ģ œ", + "submit": "ģ‚¬ģš©ģž ģ €ģž„", + "changeUserRole": "ģ‚¬ģš©ģž ģ—­ķ•  변경", + "authenticated": "ģøģ¦ėØ", + "editOwnProfil": "ģžģ‹ ģ˜ ķ”„ė”œķ•„ ķŽøģ§‘", + "enabledUser": "ķ™œģ„±ķ™”ėœ ģ‚¬ģš©ģž", + "disabledUser": "ė¹„ķ™œģ„±ķ™”ėœ ģ‚¬ģš©ģž", + "activeUsers": "ķ™œģ„± ģ‚¬ģš©ģž:", + "disabledUsers": "ė¹„ķ™œģ„±ķ™”ėœ ģ‚¬ģš©ģž:", + "totalUsers": "전첓 ģ‚¬ģš©ģž:", + "lastRequest": "ė§ˆģ§€ė§‰ ģš”ģ²­", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "ė°ģ“ķ„°ė² ģ“ģŠ¤ ź°€ģ øģ˜¤źø°/낓볓낓기", + "header": "ė°ģ“ķ„°ė² ģ“ģŠ¤ ź°€ģ øģ˜¤źø°/낓볓낓기", + "fileName": "ķŒŒģ¼ ģ“ė¦„", + "creationDate": "ģƒģ„± ė‚ ģ§œ", + "fileSize": "ķŒŒģ¼ 크기", + "deleteBackupFile": "백업 ķŒŒģ¼ ģ‚­ģ œ", + "importBackupFile": "백업 ķŒŒģ¼ ź°€ģ øģ˜¤źø°", + "createBackupFile": "백업 ķŒŒģ¼ ģƒģ„±", + "downloadBackupFile": "백업 ķŒŒģ¼ ė‹¤ģš“ė”œė“œ", + "info_1": "ė°ģ“ķ„°ė„¼ ź°€ģ øģ˜¬ ė•ŒėŠ” ģ˜¬ė°”ė„ø 구씰가 ģ¤‘ģš”ķ•©ė‹ˆė‹¤. ė¬“ģ—‡ģ„ ķ•˜ź³  ģžˆėŠ”ģ§€ ķ™•ģ‹¤ķ•˜ģ§€ ģ•Šė‹¤ė©“ ģ „ė¬øź°€ģ˜ ģ”°ģ–øź³¼ ģ§€ģ›ģ„ ė°›ģœ¼ģ„øģš”. 구씰에 ģ˜¤ė„˜ź°€ ģžˆģœ¼ė©“ ģ• ķ”Œė¦¬ģ¼€ģ“ģ…˜ ģ˜¤ģž‘ė™ģ“ė‚˜ ģ™„ģ „ķ•œ 실행 ė¶ˆėŠ„ź¹Œģ§€ ė°œģƒķ•  수 ģžˆģŠµė‹ˆė‹¤.", + "info_2": "ģ—…ė”œė“œķ•  ė•Œ ķŒŒģ¼ ģ“ė¦„ģ€ ģ¤‘ģš”ķ•˜ģ§€ ģ•ŠģŠµė‹ˆė‹¤. ģ¼ź“€ėœ ģ“ė¦„ 지정 ź·œģ¹™ģ„ ģœ„ķ•“ backup_user_yyyyMMddHHmm.sql ķ˜•ģ‹ģœ¼ė”œ ģ“ė¦„ģ“ ė³€ź²½ė©ė‹ˆė‹¤.", + "submit": "백업 ź°€ģ øģ˜¤źø°", + "importIntoDatabaseSuccessed": "ė°ģ“ķ„°ė² ģ“ģŠ¤ė”œ ź°€ģ øģ˜¤źø° 성공", + "backupCreated": "ė°ģ“ķ„°ė² ģ“ģŠ¤ 백업 성공", + "fileNotFound": "ķŒŒģ¼ģ„ ģ°¾ģ„ 수 ģ—†ģŒ", + "fileNullOrEmpty": "ķŒŒģ¼ģ€ nullģ“ź±°ė‚˜ 비얓 ģžˆģœ¼ė©“ ģ•ˆ ė©ė‹ˆė‹¤", + "failedImportFile": "ķŒŒģ¼ ź°€ģ øģ˜¤źø° ģ‹¤ķŒØ", + "notSupported": "ģ“ źø°ėŠ„ģ€ ķ˜„ģž¬ ė°ģ“ķ„°ė² ģ“ģŠ¤ ģ—°ź²°ģ—ģ„œ ģ‚¬ģš©ķ•  수 ģ—†ģŠµė‹ˆė‹¤." + }, + "session": { + "expired": "ģ„øģ…˜ģ“ ė§Œė£Œė˜ģ—ˆģŠµė‹ˆė‹¤. ķŽ˜ģ“ģ§€ė„¼ 새딜 ź³ ģ¹Øķ•˜ź³  ė‹¤ģ‹œ ģ‹œė„ķ•˜ģ„øģš”.", + "refreshPage": "ķŽ˜ģ“ģ§€ 새딜 고침" + }, + "home": { + "desc": "PDF ꓀련 ėŖØė“  ģž‘ģ—…ģ„ ģœ„ķ•œ 딜컬 ķ˜øģŠ¤ķŒ… ģ›ģŠ¤ķ†± ģ†”ė£Øģ…˜ģž…ė‹ˆė‹¤.", + "searchBar": "기늄 ź²€ģƒ‰...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "볓기, ģ£¼ģ„ 달기, ķ…ģŠ¤ķŠø ė˜ėŠ” ģ“ėÆøģ§€ 추가" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "PDF 멀티 ė„źµ¬", + "desc": "병합, ķšŒģ „, ģž¬ė°°ģ¹˜, ė¶„ķ•  ė° ķŽ˜ģ“ģ§€ 제거" + }, + "merge": { + "title": "병합", + "desc": "ģ—¬ėŸ¬ PDF넼 ķ•˜ė‚˜ė”œ ģ‰½ź²Œ ė³‘ķ•©ķ•©ė‹ˆė‹¤." + }, + "split": { + "title": "ė¶„ķ• ", + "desc": "PDF넼 ģ—¬ėŸ¬ ė¬øģ„œė”œ ė¶„ķ• " + }, + "rotate": { + "title": "ķšŒģ „", + "desc": "PDF넼 ģ‰½ź²Œ ķšŒģ „ķ•©ė‹ˆė‹¤." + }, + "imageToPdf": { + "title": "ģ“ėÆøģ§€ė„¼ PDF딜", + "desc": "ģ“ėÆøģ§€(PNG, JPEG, GIF)넼 PDF딜 ė³€ķ™˜ķ•©ė‹ˆė‹¤." + }, + "pdfToImage": { + "title": "PDF넼 ģ“ėÆøģ§€ė”œ", + "desc": "PDF넼 ģ“ėÆøģ§€ė”œ ė³€ķ™˜ķ•©ė‹ˆė‹¤. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "정리", + "desc": "ģ›ķ•˜ėŠ” ģˆœģ„œė”œ ķŽ˜ģ“ģ§€ 제거/ģž¬ė°°ģ¹˜" + }, + "addImage": { + "title": "ģ“ėÆøģ§€ 추가", + "desc": "PDFģ˜ ģ§€ģ •ėœ ģœ„ģ¹˜ģ— ģ“ėÆøģ§€ 추가" + }, + "watermark": { + "title": "ģ›Œķ„°ė§ˆķ¬ 추가", + "desc": "PDF ė¬øģ„œģ— ģ‚¬ģš©ģž 지정 ģ›Œķ„°ė§ˆķ¬ė„¼ ģ¶”ź°€ķ•©ė‹ˆė‹¤." + }, + "permissions": { + "title": "ź¶Œķ•œ 변경", + "desc": "PDF ė¬øģ„œģ˜ ź¶Œķ•œģ„ ė³€ź²½ķ•©ė‹ˆė‹¤" + }, + "removePages": { + "title": "제거", + "desc": "PDF ė¬øģ„œģ—ģ„œ ģ›ķ•˜ģ§€ ģ•ŠėŠ” ķŽ˜ģ“ģ§€ė„¼ ģ‚­ģ œķ•©ė‹ˆė‹¤." + }, + "addPassword": { + "title": "ė¹„ė°€ė²ˆķ˜ø 추가", + "desc": "PDF ė¬øģ„œė„¼ ė¹„ė°€ė²ˆķ˜øė”œ ģ•”ķ˜øķ™”ķ•©ė‹ˆė‹¤." + }, + "removePassword": { + "title": "ė¹„ė°€ė²ˆķ˜ø 제거", + "desc": "PDF ė¬øģ„œģ—ģ„œ ė¹„ė°€ė²ˆķ˜ø 볓호넼 ģ œź±°ķ•©ė‹ˆė‹¤." + }, + "compressPdfs": { + "title": "ģ••ģ¶•", + "desc": "PDF넼 ģ••ģ¶•ķ•˜ģ—¬ ķŒŒģ¼ 크기넼 ģ¤„ģž…ė‹ˆė‹¤." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "ė©”ķƒ€ė°ģ“ķ„° 변경", + "desc": "PDF ė¬øģ„œģ—ģ„œ ė©”ķƒ€ė°ģ“ķ„° 변경/제거/추가" + }, + "fileToPDF": { + "title": "ķŒŒģ¼ģ„ PDF딜 ė³€ķ™˜", + "desc": "ź±°ģ˜ ėŖØė“  ķŒŒģ¼ģ„ PDF딜 ė³€ķ™˜ķ•©ė‹ˆė‹¤(DOCX, PNG, XLS, PPT, TXT 등)" + }, + "ocr": { + "title": "OCR / ģŠ¤ģŗ” 정리", + "desc": "ģŠ¤ģŗ”ģ„ ģ •ė¦¬ķ•˜ź³  PDF ė‚“ ģ“ėÆøģ§€ģ—ģ„œ ķ…ģŠ¤ķŠøė„¼ ź°ģ§€ķ•˜ģ—¬ ė‹¤ģ‹œ ķ…ģŠ¤ķŠøė”œ ģ¶”ź°€ķ•©ė‹ˆė‹¤." + }, + "extractImages": { + "title": "ģ“ėÆøģ§€ ģ¶”ģ¶œ", + "desc": "PDFģ—ģ„œ ėŖØė“  ģ“ėÆøģ§€ė„¼ ģ¶”ģ¶œķ•˜ģ—¬ zip으딜 ģ €ģž„" + }, + "pdfToPDFA": { + "title": "PDF넼 PDF/A딜", + "desc": "ģž„źø° ė³“ź“€ģ„ ģœ„ķ•“ PDF넼 PDF/A딜 ė³€ķ™˜" + }, + "PDFToWord": { + "title": "PDF넼 Word딜", + "desc": "PDF넼 Word ķ˜•ģ‹ģœ¼ė”œ ė³€ķ™˜ (DOC, DOCX ė° ODT)" + }, + "PDFToPresentation": { + "title": "PDF넼 ķ”„ė ˆģ  ķ…Œģ“ģ…˜ģœ¼ė”œ", + "desc": "PDF넼 ķ”„ė ˆģ  ķ…Œģ“ģ…˜ ķ˜•ģ‹ģœ¼ė”œ ė³€ķ™˜ (PPT, PPTX ė° ODP)" + }, + "PDFToText": { + "title": "PDF넼 RTF(ķ…ģŠ¤ķŠø)딜", + "desc": "PDF넼 ķ…ģŠ¤ķŠø ė˜ėŠ” RTF ķ˜•ģ‹ģœ¼ė”œ ė³€ķ™˜" + }, + "PDFToHTML": { + "title": "PDF넼 HTML딜", + "desc": "PDF넼 HTML ķ˜•ģ‹ģœ¼ė”œ ė³€ķ™˜" + }, + "PDFToXML": { + "title": "PDF넼 XML딜", + "desc": "PDF넼 XML ķ˜•ģ‹ģœ¼ė”œ ė³€ķ™˜" + }, + "ScannerImageSplit": { + "title": "ģŠ¤ģŗ”ķ•œ 사진 감지/ė¶„ķ• ", + "desc": "사진/PDF ė‚“ģ˜ ģ—¬ėŸ¬ ģ‚¬ģ§„ģ„ ė¶„ķ• ķ•©ė‹ˆė‹¤" + }, + "sign": { + "title": "ģ„œėŖ…", + "desc": "그리기, ķ…ģŠ¤ķŠø ė˜ėŠ” ģ“ėÆøģ§€ė”œ PDF에 ģ„œėŖ… 추가" + }, + "flatten": { + "title": "ķ‰ė©“ķ™”", + "desc": "PDFģ—ģ„œ ėŖØė“  ėŒ€ķ™”ķ˜• ģš”ģ†Œģ™€ ģ–‘ģ‹ 제거" + }, + "repair": { + "title": "복구", + "desc": "ģ†ģƒ/깨진 PDF넼 복구 ģ‹œė„" + }, + "removeBlanks": { + "title": "빈 ķŽ˜ģ“ģ§€ 제거", + "desc": "ė¬øģ„œģ—ģ„œ 빈 ķŽ˜ģ“ģ§€ė„¼ ź°ģ§€ķ•˜ź³  ģ œź±°ķ•©ė‹ˆė‹¤" + }, + "removeAnnotations": { + "title": "ģ£¼ģ„ 제거", + "desc": "PDFģ—ģ„œ ėŖØė“  ģ£¼ģ„/메모넼 ģ œź±°ķ•©ė‹ˆė‹¤" + }, + "compare": { + "title": "비교", + "desc": "2ź°œģ˜ PDF ė¬øģ„œė„¼ ė¹„źµķ•˜ź³  ģ°Øģ“ģ ģ„ ė³“ģ—¬ģ¤ė‹ˆė‹¤" + }, + "certSign": { + "title": "ģøģ¦ģ„œė”œ ģ„œėŖ…", + "desc": "ģøģ¦ģ„œ/키(PEM/P12)딜 PDF에 ģ„œėŖ…" + }, + "removeCertSign": { + "title": "ģøģ¦ģ„œ ģ„œėŖ… 제거", + "desc": "PDFģ—ģ„œ ģøģ¦ģ„œ ģ„œėŖ… 제거" + }, + "pageLayout": { + "title": "다중 ķŽ˜ģ“ģ§€ ė ˆģ“ģ•„ģ›ƒ", + "desc": "PDF ė¬øģ„œģ˜ ģ—¬ėŸ¬ ķŽ˜ģ“ģ§€ė„¼ ķ•˜ė‚˜ģ˜ ķŽ˜ģ“ģ§€ė”œ 병합" + }, + "scalePages": { + "title": "ķŽ˜ģ“ģ§€ 크기/배율 ģ”°ģ •", + "desc": "ķŽ˜ģ“ģ§€ ė° ė‚“ģš©ģ˜ 크기/ė°°ģœØģ„ ė³€ź²½ķ•©ė‹ˆė‹¤." + }, + "pipeline": { + "title": "ķŒŒģ“ķ”„ė¼ģø", + "desc": "ķŒŒģ“ķ”„ė¼ģø 스크립트넼 ģ •ģ˜ķ•˜ģ—¬ PDFģ—ģ„œ ģ—¬ėŸ¬ ģž‘ģ—… 실행" + }, + "add-page-numbers": { + "title": "ķŽ˜ģ“ģ§€ 번호 추가", + "desc": "ė¬øģ„œ 전첓에 ģ§€ģ •ėœ ģœ„ģ¹˜ģ— ķŽ˜ģ“ģ§€ 번호 추가" + }, + "auto-rename": { + "title": "PDF ķŒŒģ¼ ģžė™ ģ“ė¦„ 변경", + "desc": "ź°ģ§€ėœ ķ—¤ė”ė„¼ 기반으딜 PDF ķŒŒģ¼ ģ“ė¦„ ģžė™ 변경" + }, + "adjust-contrast": { + "title": "ģƒ‰ģƒ/ėŒ€ė¹„ ģ”°ģ •", + "desc": "PDFģ˜ ėŒ€ė¹„, ģ±„ė„ ė° ė°źø° ģ”°ģ •" + }, + "crop": { + "title": "PDF ģžė„“źø°", + "desc": "PDF넼 ģž˜ė¼ģ„œ 크기 ģ¤„ģ“źø°(ķ…ģŠ¤ķŠø ģœ ģ§€!)" + }, + "autoSplitPDF": { + "title": "ģžė™ ķŽ˜ģ“ģ§€ ė¶„ķ• ", + "desc": "물리적 ģŠ¤ģŗ” ķŽ˜ģ“ģ§€ ė¶„ķ• źø° QR ģ½”ė“œź°€ ģžˆėŠ” ģŠ¤ģŗ”ėœ PDF ģžė™ ė¶„ķ• " + }, + "sanitizePdf": { + "title": "정리", + "desc": "PDF ķŒŒģ¼ģ—ģ„œ 스크립트 ė° źø°ķƒ€ ģš”ģ†Œ 제거" + }, + "URLToPDF": { + "title": "URL/ģ›¹ģ‚¬ģ“ķŠøė„¼ PDF딜", + "desc": "http(s) URLģ„ PDF딜 ė³€ķ™˜" + }, + "HTMLToPDF": { + "title": "HTMLģ„ PDF딜", + "desc": "HTML ķŒŒģ¼ģ“ė‚˜ zipģ„ PDF딜 ė³€ķ™˜" + }, + "MarkdownToPDF": { + "title": "Markdownģ„ PDF딜", + "desc": "Markdown ķŒŒģ¼ģ„ PDF딜 ė³€ķ™˜" + }, + "PDFToMarkdown": { + "title": "PDF넼 Markdown으딜", + "desc": "PDF넼 Markdown으딜 ė³€ķ™˜" + }, + "getPdfInfo": { + "title": "PDF ėŖØė“  정볓 ź°€ģ øģ˜¤źø°", + "desc": "PDFģ—ģ„œ ź°€ėŠ„ķ•œ ėŖØė“  정볓 ź°€ģ øģ˜¤źø°" + }, + "extractPage": { + "title": "ķŽ˜ģ“ģ§€ ģ¶”ģ¶œ", + "desc": "PDFģ—ģ„œ ģ„ ķƒķ•œ ķŽ˜ģ“ģ§€ ģ¶”ģ¶œ" + }, + "PdfToSinglePage": { + "title": "ė‹Øģ¼ 큰 ķŽ˜ģ“ģ§€", + "desc": "ėŖØė“  PDF ķŽ˜ģ“ģ§€ė„¼ ķ•˜ė‚˜ģ˜ 큰 ė‹Øģ¼ ķŽ˜ģ“ģ§€ė”œ 병합" + }, + "showJS": { + "title": "JavaScript 볓기", + "desc": "PDF에 ģ‚½ģž…ėœ JavaScript ź²€ģƒ‰ ė° ķ‘œģ‹œ" + }, + "autoRedact": { + "title": "ģžė™ 검엓", + "desc": "ģž…ė „ ķ…ģŠ¤ķŠøė„¼ 기반으딜 PDFģ˜ ķ…ģŠ¤ķŠø ģžė™ 검엓(가림)" + }, + "redact": { + "title": "ģˆ˜ė™ 검엓", + "desc": "ģ„ ķƒķ•œ ķ…ģŠ¤ķŠø, 그린 ė„ķ˜• ė°/ė˜ėŠ” ģ„ ķƒķ•œ ķŽ˜ģ“ģ§€ė„¼ 기반으딜 PDF 검엓" + }, + "tableExtraxt": { + "title": "PDF넼 CSV딜", + "desc": "PDFģ—ģ„œ ķ‘œė„¼ ģ¶”ģ¶œķ•˜ģ—¬ CSV딜 ė³€ķ™˜" + }, + "autoSizeSplitPDF": { + "title": "크기/ź°œģˆ˜ė³„ ģžė™ ė¶„ķ• ", + "desc": "ė‹Øģ¼ PDF넼 크기, ķŽ˜ģ“ģ§€ 수 ė˜ėŠ” ė¬øģ„œ 수넼 źø°ģ¤€ģœ¼ė”œ ģ—¬ėŸ¬ ė¬øģ„œė”œ ė¶„ķ• " + }, + "overlay-pdfs": { + "title": "PDF ģ˜¤ė²„ė ˆģ“", + "desc": "PDF넼 다넸 PDF ģœ„ģ— ģ˜¤ė²„ė ˆģ“" + }, + "split-by-sections": { + "title": "ģ„¹ģ…˜ė³„ PDF ė¶„ķ• ", + "desc": "PDFģ˜ 각 ķŽ˜ģ“ģ§€ė„¼ ė” ģž‘ģ€ ź°€ė”œ ė° ģ„øė”œ ģ„¹ģ…˜ģœ¼ė”œ ė¶„ķ• " + }, + "AddStampRequest": { + "title": "PDF에 ģŠ¤ķƒ¬ķ”„ 추가", + "desc": "ģ§€ģ •ėœ ģœ„ģ¹˜ģ— ķ…ģŠ¤ķŠø ė˜ėŠ” ģ“ėÆøģ§€ ģŠ¤ķƒ¬ķ”„ 추가" + }, + "removeImagePdf": { + "title": "ģ“ėÆøģ§€ 제거", + "desc": "ķŒŒģ¼ 크기넼 ģ¤„ģ“źø° ģœ„ķ•“ PDFģ—ģ„œ ģ“ėÆøģ§€ 제거" + }, + "splitPdfByChapters": { + "title": "챕터별 PDF ė¶„ķ• ", + "desc": "PDF넼 챕터 구씰에 ė”°ė¼ ģ—¬ėŸ¬ ķŒŒģ¼ė”œ ė¶„ķ• ķ•©ė‹ˆė‹¤." + }, + "validateSignature": { + "title": "PDF ģ„œėŖ… ź²€ģ¦", + "desc": "PDF ė¬øģ„œģ˜ 디지털 ģ„œėŖ…ź³¼ ģøģ¦ģ„œ ź²€ģ¦" + }, + "replaceColorPdf": { + "title": "ģƒ‰ģƒ 교첓 ė° ė°˜ģ „", + "desc": "PDFģ—ģ„œ ķ…ģŠ¤ķŠøģ™€ ė°°ź²½ģ˜ ģƒ‰ģƒģ„ źµģ²“ķ•˜ź³  ķŒŒģ¼ 크기넼 ģ¤„ģ“źø° ģœ„ķ•“ 전첓 PDF ģƒ‰ģƒģ„ ė°˜ģ „" + } + }, + "viewPdf": { + "tags": "볓기,ģ½źø°,ģ£¼ģ„,ķ…ģŠ¤ķŠø,ģ“ėÆøģ§€", + "title": "View/Edit PDF", + "header": "PDF 볓기" + }, + "multiTool": { + "tags": "멀티 ė„źµ¬,다중 ģž‘ģ—…,UI,큓릭 ė“œėž˜ź·ø,ķ”„ė” ķŠøģ—”ė“œ,ķ“ė¼ģ“ģ–øķŠø ģ‚¬ģ“ė“œ,ėŒ€ķ™”ķ˜•,ģƒķ˜øģž‘ģš©,ģ“ė™,ģ‚­ģ œ,ė§ˆģ“ź·øė ˆģ“ģ…˜,ė¶„ķ• ", + "title": "PDF 멀티 ė„źµ¬", + "header": "PDF 멀티 ė„źµ¬", + "uploadPrompts": "ķŒŒģ¼ ģ“ė¦„", + "selectAll": "모두 ģ„ ķƒ", + "deselectAll": "모두 ģ„ ķƒ ķ•“ģ œ", + "selectPages": "ķŽ˜ģ“ģ§€ ģ„ ķƒ", + "selectedPages": "ģ„ ķƒėœ ķŽ˜ģ“ģ§€", + "page": "ķŽ˜ģ“ģ§€", + "deleteSelected": "ģ„ ķƒ ķ•­ėŖ© ģ‚­ģ œ", + "downloadAll": "낓볓낓기", + "downloadSelected": "ģ„ ķƒ ķ•­ėŖ© 낓볓낓기", + "insertPageBreak": "ķŽ˜ģ“ģ§€ ė‚˜ėˆ„źø° ģ‚½ģž…", + "addFile": "ķŒŒģ¼ 추가", + "rotateLeft": "ģ™¼ģŖ½ģœ¼ė”œ ķšŒģ „", + "rotateRight": "오넸쪽으딜 ķšŒģ „", + "split": "ė¶„ķ• ", + "moveLeft": "ģ™¼ģŖ½ģœ¼ė”œ ģ“ė™", + "moveRight": "오넸쪽으딜 ģ“ė™", + "delete": "ģ‚­ģ œ", + "dragDropMessage": "ķŽ˜ģ“ģ§€ ģ„ ķƒėØ", + "undo": "실행 ģ·Øģ†Œ", + "redo": "ė‹¤ģ‹œ 실행" + }, + "merge": { + "tags": "병합,ķŽ˜ģ“ģ§€ ģž‘ģ—…,ė°±ģ—”ė“œ,ģ„œė²„ ģ‚¬ģ“ė“œ", + "title": "병합", + "header": "ģ—¬ėŸ¬ PDF 병합 (2개 ģ“ģƒ)", + "sortByName": "ģ“ė¦„ģœ¼ė”œ ģ •ė ¬", + "sortByDate": "ė‚ ģ§œė”œ ģ •ė ¬", + "removeCertSign": "ė³‘ķ•©ėœ ķŒŒģ¼ģ—ģ„œ 디지털 ģ„œėŖ…ģ„ ģ œź±°ķ•˜ģ‹œź² ģŠµė‹ˆź¹Œ?", + "submit": "병합" + }, + "split": { + "tags": "ķŽ˜ģ“ģ§€ ģž‘ģ—…,ė‚˜ėˆ„źø°,멀티 ķŽ˜ģ“ģ§€,ģžė„“źø°,ģ„œė²„ ģ‚¬ģ“ė“œ", + "title": "PDF ė¶„ķ• ", + "header": "PDF ė¶„ķ• ", + "desc": { + "1": "ģ„ ķƒķ•œ ģˆ«ģžėŠ” ė¶„ķ• ķ•˜ė ¤ėŠ” ķŽ˜ģ“ģ§€ ė²ˆķ˜øģž…ė‹ˆė‹¤", + "2": "예넼 들얓 1,3,7-9넼 ģ„ ķƒķ•˜ė©“ 10ķŽ˜ģ“ģ§€ ė¬øģ„œź°€ ė‹¤ģŒź³¼ ź°™ģ“ 6ź°œģ˜ ė³„ė„ PDF딜 ė¶„ķ• ė©ė‹ˆė‹¤:", + "3": "ė¬øģ„œ #1: 1ķŽ˜ģ“ģ§€", + "4": "ė¬øģ„œ #2: 2-3ķŽ˜ģ“ģ§€", + "5": "ė¬øģ„œ #3: 4-7ķŽ˜ģ“ģ§€", + "6": "ė¬øģ„œ #4: 8ķŽ˜ģ“ģ§€", + "7": "ė¬øģ„œ #5: 9ķŽ˜ģ“ģ§€", + "8": "ė¬øģ„œ #6: 10ķŽ˜ģ“ģ§€" + }, + "splitPages": "ė¶„ķ• ķ•  ķŽ˜ģ“ģ§€ ģž…ė „:", + "submit": "ė¶„ķ• " + }, + "rotate": { + "tags": "ģ„œė²„ ģ‚¬ģ“ė“œ", + "title": "PDF ķšŒģ „", + "header": "PDF ķšŒģ „", + "selectAngle": "ķšŒģ „ ź°ė„ ģ„ ķƒ (90ė„ ė‹Øģœ„):", + "submit": "ķšŒģ „" + }, + "imageToPdf": { + "tags": "ė³€ķ™˜,ģ“ėÆøģ§€,jpg,사진" + }, + "pdfToImage": { + "tags": "ė³€ķ™˜,ģ“ėÆøģ§€,jpg,사진", + "title": "PDF넼 ģ“ėÆøģ§€ė”œ", + "header": "PDF넼 ģ“ėÆøģ§€ė”œ", + "selectText": "ģ“ėÆøģ§€ ķ˜•ģ‹", + "singleOrMultiple": "ģ“ėÆøģ§€ ź²°ź³¼ ģœ ķ˜•", + "single": "ė‹Øģ¼ 큰 ģ“ėÆøģ§€", + "multi": "ģ—¬ėŸ¬ ģ“ėÆøģ§€", + "colorType": "ģƒ‰ģƒ ģœ ķ˜•", + "color": "컬러", + "grey": "ź·øė ˆģ“ģŠ¤ģ¼€ģ¼", + "blackwhite": "ķ‘ė°± (ė°ģ“ķ„° 손실 ź°€ėŠ„ģ„± ģžˆģŒ!)", + "submit": "ė³€ķ™˜", + "info": "WebP ė³€ķ™˜ģ—ėŠ” Pythonģ“ ķ•„ģš”ķ•©ė‹ˆė‹¤. Pythonģ“ ģ„¤ģ¹˜ė˜ģ§€ ģ•Šģ•˜ģŠµė‹ˆė‹¤.", + "placeholder": "(예: 1,2,8 ė˜ėŠ” 4,7,12-16 ė˜ėŠ” 2n-1)" + }, + "pdfOrganiser": { + "tags": "ģ–‘ė©“,ģ§ģˆ˜,ķ™€ģˆ˜,ģ •ė ¬,ģ“ė™", + "title": "ķŽ˜ģ“ģ§€ 정리", + "header": "PDF ķŽ˜ģ“ģ§€ 정리", + "submit": "ķŽ˜ģ“ģ§€ ģž¬ė°°ģ¹˜", + "mode": { + "_value": "ėŖØė“œ", + "1": "ģ‚¬ģš©ģž 지정 ķŽ˜ģ“ģ§€ ģˆœģ„œ", + "2": "ģ—­ģˆœ", + "3": "ģ–‘ė©“ ģ •ė ¬", + "4": "ģ†Œģ±…ģž ģ •ė ¬", + "5": "츔멓 ģŠ¤ķ‹°ģ¹˜ ģ†Œģ±…ģž ģ •ė ¬", + "6": "ķ™€ģˆ˜-ģ§ģˆ˜ ė¶„ķ• ", + "7": "첫 ķŽ˜ģ“ģ§€ 제거", + "8": "ė§ˆģ§€ė§‰ ķŽ˜ģ“ģ§€ 제거", + "9": "첫 ķŽ˜ģ“ģ§€ģ™€ ė§ˆģ§€ė§‰ ķŽ˜ģ“ģ§€ 제거", + "10": "ķ™€ģˆ˜-ģ§ģˆ˜ 병합", + "11": "Duplicate all pages" + }, + "placeholder": "(예: 1,3,2 ė˜ėŠ” 4-8,2,10-12 ė˜ėŠ” 2n-1)" + }, + "addImage": { + "tags": "ģ“ėÆøģ§€,jpg,사진", + "title": "ģ“ėÆøģ§€ 추가", + "header": "PDF에 ģ“ėÆøģ§€ 추가", + "everyPage": "ėŖØė“  ķŽ˜ģ“ģ§€?", + "upload": "ģ“ėÆøģ§€ 추가", + "submit": "ģ“ėÆøģ§€ 추가" + }, + "watermark": { + "tags": "ķ…ģŠ¤ķŠø,반복,ė ˆģ“ėø”,ģ†Œģœ ,ģ €ģž‘ź¶Œ,ģƒķ‘œ,ģ“ėÆøģ§€,jpg,사진", + "title": "ģ›Œķ„°ė§ˆķ¬ 추가", + "header": "ģ›Œķ„°ė§ˆķ¬ 추가", + "customColor": "ģ‚¬ģš©ģž 지정 ķ…ģŠ¤ķŠø ģƒ‰ģƒ", + "selectText": { + "1": "ģ›Œķ„°ė§ˆķ¬ė„¼ 추가할 PDF ģ„ ķƒ:", + "2": "ģ›Œķ„°ė§ˆķ¬ ķ…ģŠ¤ķŠø:", + "3": "글꼓 크기:", + "4": "ķšŒģ „ (0-360):", + "5": "ź°€ė”œ 간격 (각 ģ›Œķ„°ė§ˆķ¬ ģ‚¬ģ“ģ˜ ź°€ė”œ 간격):", + "6": "ģ„øė”œ 간격 (각 ģ›Œķ„°ė§ˆķ¬ ģ‚¬ģ“ģ˜ ģ„øė”œ 간격):", + "7": "ė¶ˆķˆ¬ėŖ…ė„ (0% - 100%):", + "8": "ģ›Œķ„°ė§ˆķ¬ ģœ ķ˜•:", + "9": "ģ›Œķ„°ė§ˆķ¬ ģ“ėÆøģ§€:", + "10": "PDF넼 PDF-ģ“ėÆøģ§€ė”œ ė³€ķ™˜" + }, + "submit": "ģ›Œķ„°ė§ˆķ¬ 추가", + "type": { + "1": "ķ…ģŠ¤ķŠø", + "2": "ģ“ėÆøģ§€" + } + }, + "permissions": { + "tags": "ģ½źø°,ģ“°źø°,ķŽøģ§‘,ģøģ‡„", + "title": "ź¶Œķ•œ 변경", + "header": "ź¶Œķ•œ 변경", + "warning": "ģ“ėŸ¬ķ•œ ź¶Œķ•œģ„ 변경할 수 ģ—†ź²Œ ķ•˜ė ¤ė©“ ė¹„ė°€ė²ˆķ˜ø 추가 ķŽ˜ģ“ģ§€ģ—ģ„œ ė¹„ė°€ė²ˆķ˜øģ™€ ķ•Øź»˜ ģ„¤ģ •ķ•˜ėŠ” ź²ƒģ“ ģ¢‹ģŠµė‹ˆė‹¤", + "selectText": { + "1": "ź¶Œķ•œģ„ 변경할 PDF ģ„ ķƒ", + "2": "설정할 ź¶Œķ•œ", + "3": "ė¬øģ„œ 씰립 ė°©ģ§€", + "4": "ģ½˜ķ…ģø  ģ¶”ģ¶œ ė°©ģ§€", + "5": "ģ ‘ź·¼ģ„±ģ„ ģœ„ķ•œ ģ¶”ģ¶œ ė°©ģ§€", + "6": "ģ–‘ģ‹ ģž‘ģ„± ė°©ģ§€", + "7": "ģˆ˜ģ • ė°©ģ§€", + "8": "ģ£¼ģ„ ģˆ˜ģ • ė°©ģ§€", + "9": "ģøģ‡„ ė°©ģ§€", + "10": "다넸 ķ˜•ģ‹ģœ¼ė”œ ģøģ‡„ ė°©ģ§€" + }, + "submit": "변경" + }, + "removePages": { + "tags": "ķŽ˜ģ“ģ§€ 제거,ķŽ˜ģ“ģ§€ ģ‚­ģ œ" + }, + "addPassword": { + "tags": "ė³“ģ•ˆ,ė³“ģ•ˆ", + "title": "ė¹„ė°€ė²ˆķ˜ø 추가", + "header": "ė¹„ė°€ė²ˆķ˜ø 추가 (ģ•”ķ˜øķ™”)", + "selectText": { + "1": "ģ•”ķ˜øķ™”ķ•  PDF ģ„ ķƒ", + "2": "ģ‚¬ģš©ģž ė¹„ė°€ė²ˆķ˜ø", + "3": "ģ•”ķ˜øķ™” 키 źøøģ“", + "4": "ė†’ģ€ ź°’ģ“ ė” ź°•ė „ķ•˜ģ§€ė§Œ ė‚®ģ€ ź°’ģ“ ė” ė‚˜ģ€ ķ˜øķ™˜ģ„±ģ„ ģ œź³µķ•©ė‹ˆė‹¤.", + "5": "설정할 ź¶Œķ•œ (ģ†Œģœ ģž ė¹„ė°€ė²ˆķ˜øģ™€ ķ•Øź»˜ ģ‚¬ģš© ź¶Œģž„)", + "6": "ė¬øģ„œ 씰립 ė°©ģ§€", + "7": "ģ½˜ķ…ģø  ģ¶”ģ¶œ ė°©ģ§€", + "8": "ģ ‘ź·¼ģ„±ģ„ ģœ„ķ•œ ģ¶”ģ¶œ ė°©ģ§€", + "9": "ģ–‘ģ‹ ģž‘ģ„± ė°©ģ§€", + "10": "ģˆ˜ģ • ė°©ģ§€", + "11": "ģ£¼ģ„ ģˆ˜ģ • ė°©ģ§€", + "12": "ģøģ‡„ ė°©ģ§€", + "13": "다넸 ķ˜•ģ‹ģœ¼ė”œ ģøģ‡„ ė°©ģ§€", + "14": "ģ†Œģœ ģž ė¹„ė°€ė²ˆķ˜ø", + "15": "ė¬øģ„œź°€ 엓린 후 ģˆ˜ķ–‰ķ•  수 ģžˆėŠ” ģž‘ģ—… ģ œķ•œ (ėŖØė“  ė¦¬ė”ģ—ģ„œ ģ§€ģ›ė˜ģ§€ ģ•ŠģŒ)", + "16": "ė¬øģ„œ ģžģ²“ ģ—“źø° ģ œķ•œ" + }, + "submit": "ģ•”ķ˜øķ™”" + }, + "removePassword": { + "tags": "ė³“ģ•ˆ,ģ•”ķ˜ø ķ•“ģ œ,ė³“ģ•ˆ,ė¹„ė°€ė²ˆķ˜ø ķ•“ģ œ,ė¹„ė°€ė²ˆķ˜ø ģ‚­ģ œ", + "title": "ė¹„ė°€ė²ˆķ˜ø 제거", + "header": "ė¹„ė°€ė²ˆķ˜ø 제거 (ė³µķ˜øķ™”)", + "selectText": { + "1": "ė³µķ˜øķ™”ķ•  PDF ģ„ ķƒ", + "2": "ė¹„ė°€ė²ˆķ˜ø" + }, + "submit": "제거" + }, + "compressPdfs": { + "tags": "ģ••ģ¶•,ģž‘ź²Œ,매우 ģž‘ź²Œ" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "제목,ģ €ģž,ė‚ ģ§œ,ģƒģ„±,ģ‹œź°„,ģ¶œķŒģ‚¬,ģ œģž‘ģž,통계", + "title": "제목:", + "header": "ė©”ķƒ€ė°ģ“ķ„° 변경", + "selectText": { + "1": "ė³€ź²½ķ•˜ė ¤ėŠ” ė³€ģˆ˜ė„¼ ķŽøģ§‘ķ•˜ģ„øģš”", + "2": "ėŖØė“  ė©”ķƒ€ė°ģ“ķ„° ģ‚­ģ œ", + "3": "ģ‚¬ģš©ģž 지정 ė©”ķƒ€ė°ģ“ķ„° ķ‘œģ‹œ:", + "4": "źø°ķƒ€ ė©”ķƒ€ė°ģ“ķ„°:", + "5": "ģ‚¬ģš©ģž 지정 ė©”ķƒ€ė°ģ“ķ„° ķ•­ėŖ© 추가" + }, + "author": "ģ €ģž:", + "creationDate": "ģƒģ„± ė‚ ģ§œ (yyyy/MM/dd HH:mm:ss):", + "creator": "ģž‘ģ„±ģž:", + "keywords": "ķ‚¤ģ›Œė“œ:", + "modDate": "ģˆ˜ģ • ė‚ ģ§œ (yyyy/MM/dd HH:mm:ss):", + "producer": "ģ œģž‘ģž:", + "subject": "제목:", + "trapped": "ķŠøėž©:", + "submit": "변경" + }, + "fileToPDF": { + "tags": "ė³€ķ™˜,ķ˜•ģ‹,ė¬øģ„œ,사진,ģŠ¬ė¼ģ“ė“œ,ķ…ģŠ¤ķŠø,ė³€ķ™˜,ģ˜¤ķ”¼ģŠ¤,ė¬øģ„œ,ģ›Œė“œ,ģ—‘ģ…€,ķŒŒģ›Œķ¬ģøķŠø", + "title": "ķŒŒģ¼ģ„ PDF딜", + "header": "ėŖØė“  ķŒŒģ¼ģ„ PDF딜 ė³€ķ™˜", + "credit": "ģ“ ģ„œė¹„ģŠ¤ėŠ” ķŒŒģ¼ ė³€ķ™˜ģ„ ģœ„ķ•“ LibreOffice와 Unoconv넼 ģ‚¬ģš©ķ•©ė‹ˆė‹¤.", + "supportedFileTypesInfo": "ģ§€ģ›ė˜ėŠ” ķŒŒģ¼ ķ˜•ģ‹", + "supportedFileTypes": "ģ§€ģ›ė˜ėŠ” ķŒŒģ¼ ķ˜•ģ‹ģ€ ģ•„ėž˜ģ™€ ź°™ģ§€ė§Œ 전첓 ģ—…ė°ģ“ķŠøėœ 지원 ķ˜•ģ‹ ėŖ©ė”ģ€ LibreOffice ė¬øģ„œė„¼ ģ°øģ”°ķ•˜ģ„øģš”", + "submit": "PDF딜 ė³€ķ™˜" + }, + "ocr": { + "tags": "ģøģ‹,ķ…ģŠ¤ķŠø,ģ“ėÆøģ§€,ģŠ¤ģŗ”,ģ½źø°,ģ‹ė³„,감지,ķŽøģ§‘ ź°€ėŠ„", + "title": "OCR / ģŠ¤ģŗ” 정리", + "header": "ģŠ¤ģŗ” 정리 / OCR (ź“‘ķ•™ ė¬øģž ģøģ‹)", + "selectText": { + "1": "PDFģ—ģ„œ 감지할 ģ–øģ–“ ģ„ ķƒ (ķ˜„ģž¬ ź°ģ§€ėœ ģ–øģ–“ź°€ ė‚˜ģ—“ėØ):", + "2": "OCR된 PDF와 ķ•Øź»˜ OCR ķ…ģŠ¤ķŠøź°€ ķ¬ķ•Øėœ ķ…ģŠ¤ķŠø ķŒŒģ¼ ģƒģ„±", + "3": "źø°ģšøģ–“ģ§„ ź°ė„ė”œ ģŠ¤ģŗ”ėœ ķŽ˜ģ“ģ§€ė„¼ ģ˜¬ė°”ė„ø ģœ„ģ¹˜ė”œ ķšŒģ „", + "4": "OCRģ“ ė°°ź²½ ė…øģ“ģ¦ˆģ—ģ„œ ķ…ģŠ¤ķŠøė„¼ ģ°¾ģ„ ź°€ėŠ„ģ„±ģ„ ģ¤„ģ“ė„ė” ķŽ˜ģ“ģ§€ 정리 (출렄 변경 ģ—†ģŒ)", + "5": "OCRģ“ ė°°ź²½ ė…øģ“ģ¦ˆģ—ģ„œ ķ…ģŠ¤ķŠøė„¼ ģ°¾ģ„ ź°€ėŠ„ģ„±ģ„ ģ¤„ģ“ė„ė” ķŽ˜ģ“ģ§€ 정리, ģ¶œė „ģ—ģ„œ 정리 ģœ ģ§€", + "6": "ėŒ€ķ™”ķ˜• ķ…ģŠ¤ķŠøź°€ ģžˆėŠ” ķŽ˜ģ“ģ§€ėŠ” ė¬“ģ‹œķ•˜ź³  ģ“ėÆøģ§€ ķŽ˜ģ“ģ§€ė§Œ OCR", + "7": "ź°•ģ œ OCR, ėŖØė“  원본 ķ…ģŠ¤ķŠø ģš”ģ†Œė„¼ ģ œź±°ķ•˜ź³  ėŖØė“  ķŽ˜ģ“ģ§€ė„¼ OCR", + "8": "ģ¼ė°˜ (PDF에 ķ…ģŠ¤ķŠøź°€ ģžˆģœ¼ė©“ 오넘 ė°œģƒ)", + "9": "추가 설정", + "10": "OCR ėŖØė“œ", + "11": "OCR 후 ģ“ėÆøģ§€ 제거 (ėŖØė“  ģ“ėÆøģ§€ 제거, ė³€ķ™˜ ė‹Øź³„ģ˜ ģ¼ė¶€ģø ź²½ģš°ģ—ė§Œ 유용)", + "12": "ė Œė”ė§ ģœ ķ˜• (ź³ źø‰)" + }, + "help": "다넸 ģ–øģ–“ ģ‚¬ģš© 방법 ė°/ė˜ėŠ” Dockerģ—ģ„œ ģ‚¬ģš©ķ•˜ģ§€ ģ•ŠėŠ” 방법에 ėŒ€ķ•œ ė¬øģ„œė„¼ ģ½ģ–“ė³“ģ„øģš”", + "credit": "ģ“ ģ„œė¹„ģŠ¤ėŠ” OCRģ„ ģœ„ķ•“ qpdf와 Tesseract넼 ģ‚¬ģš©ķ•©ė‹ˆė‹¤.", + "submit": "OCR딜 PDF 처리" + }, + "extractImages": { + "tags": "사진,ģ €ģž„,ģ•„ģ¹“ģ“ėøŒ,zip,캔처,ź°€ģ øģ˜¤źø°", + "title": "ģ“ėÆøģ§€ ģ¶”ģ¶œ", + "header": "ģ“ėÆøģ§€ ģ¶”ģ¶œ", + "selectText": "ģ¶”ģ¶œėœ ģ“ėÆøģ§€ė„¼ ė³€ķ™˜ķ•  ģ“ėÆøģ§€ ķ˜•ģ‹ ģ„ ķƒ", + "allowDuplicates": "중복 ģ“ėÆøģ§€ ģ €ģž„", + "submit": "ģ¶”ģ¶œ" + }, + "pdfToPDFA": { + "tags": "ģ•„ģ¹“ģ“ėøŒ,ģž„źø°,ķ‘œģ¤€,ė³€ķ™˜,ģ €ģž„,볓씓", + "title": "PDF넼 PDF/A딜", + "header": "PDF넼 PDF/A딜", + "credit": "ģ“ ģ„œė¹„ģŠ¤ėŠ” PDF/A ė³€ķ™˜ģ„ ģœ„ķ•“ libreoffice넼 ģ‚¬ģš©ķ•©ė‹ˆė‹¤", + "submit": "ė³€ķ™˜", + "tip": "ķ˜„ģž¬ ģ—¬ėŸ¬ ģž…ė „ģ„ ķ•œ ė²ˆģ— ģ²˜ė¦¬ķ•  수 ģ—†ģŠµė‹ˆė‹¤", + "outputFormat": "출렄 ķ˜•ģ‹", + "pdfWithDigitalSignature": "PDF에 디지털 ģ„œėŖ…ģ“ ķ¬ķ•Øė˜ģ–“ ģžˆģŠµė‹ˆė‹¤. ė‹¤ģŒ ė‹Øź³„ģ—ģ„œ ģ œź±°ė©ė‹ˆė‹¤." + }, + "PDFToWord": { + "tags": "doc,docx,odt,ģ›Œė“œ,ė³€ķ™˜,ķ˜•ģ‹,ė³€ķ™˜,ģ˜¤ķ”¼ģŠ¤,ė§ˆģ“ķ¬ė”œģ†Œķ”„ķŠø,docfile", + "title": "PDF넼 Word딜", + "header": "PDF넼 Word딜", + "selectText": { + "1": "출렄 ķŒŒģ¼ ķ˜•ģ‹" + }, + "credit": "ģ“ ģ„œė¹„ģŠ¤ėŠ” ķŒŒģ¼ ė³€ķ™˜ģ„ ģœ„ķ•“ LibreOffice넼 ģ‚¬ģš©ķ•©ė‹ˆė‹¤.", + "submit": "ė³€ķ™˜" + }, + "PDFToPresentation": { + "tags": "ģŠ¬ė¼ģ“ė“œ,쇼,ģ˜¤ķ”¼ģŠ¤,ė§ˆģ“ķ¬ė”œģ†Œķ”„ķŠø", + "title": "PDF넼 ķ”„ė ˆģ  ķ…Œģ“ģ…˜ģœ¼ė”œ", + "header": "PDF넼 ķ”„ė ˆģ  ķ…Œģ“ģ…˜ģœ¼ė”œ", + "selectText": { + "1": "출렄 ķŒŒģ¼ ķ˜•ģ‹" + }, + "credit": "ģ“ ģ„œė¹„ģŠ¤ėŠ” ķŒŒģ¼ ė³€ķ™˜ģ„ ģœ„ķ•“ LibreOffice넼 ģ‚¬ģš©ķ•©ė‹ˆė‹¤.", + "submit": "ė³€ķ™˜" + }, + "PDFToText": { + "tags": "ģ„œģ‹ģžˆėŠ”ķ˜•ģ‹,ģ„œģ‹ģžˆėŠ”ķ…ģŠ¤ķŠøķ˜•ģ‹,ģ„œģ‹ģžˆėŠ” ķ…ģŠ¤ķŠø ķ˜•ģ‹", + "title": "PDF넼 RTF(ķ…ģŠ¤ķŠø)딜", + "header": "PDF넼 RTF(ķ…ģŠ¤ķŠø)딜", + "selectText": { + "1": "출렄 ķŒŒģ¼ ķ˜•ģ‹" + }, + "credit": "ģ“ ģ„œė¹„ģŠ¤ėŠ” ķŒŒģ¼ ė³€ķ™˜ģ„ ģœ„ķ•“ LibreOffice넼 ģ‚¬ģš©ķ•©ė‹ˆė‹¤.", + "submit": "ė³€ķ™˜" + }, + "PDFToHTML": { + "tags": "웹 ģ½˜ķ…ģø ,ėøŒė¼ģš°ģ € ģ¹œķ™”ģ ", + "title": "PDF넼 HTML딜", + "header": "PDF넼 HTML딜", + "credit": "ģ“ ģ„œė¹„ģŠ¤ėŠ” ķŒŒģ¼ ė³€ķ™˜ģ„ ģœ„ķ•“ pdftohtmlģ„ ģ‚¬ģš©ķ•©ė‹ˆė‹¤.", + "submit": "ė³€ķ™˜" + }, + "PDFToXML": { + "tags": "ė°ģ“ķ„°-ģ¶”ģ¶œ,구씰화-ģ½˜ķ…ģø ,ģƒķ˜øģš“ģš©ģ„±,ė³€ķ™˜,ė³€ķ™˜", + "title": "PDF넼 XML딜", + "header": "PDF넼 XML딜", + "credit": "ģ“ ģ„œė¹„ģŠ¤ėŠ” ķŒŒģ¼ ė³€ķ™˜ģ„ ģœ„ķ•“ LibreOffice넼 ģ‚¬ģš©ķ•©ė‹ˆė‹¤.", + "submit": "ė³€ķ™˜" + }, + "ScannerImageSplit": { + "tags": "분리,ģžė™-감지,ģŠ¤ģŗ”,다중-사진,정리", + "selectText": { + "1": "ź°ė„ ģž„ź³„ź°’:", + "2": "ģ“ėÆøģ§€ ķšŒģ „ģ— ķ•„ģš”ķ•œ ģµœģ†Œ ģ ˆėŒ€ ź°ė„ė„¼ ģ„¤ģ •ķ•©ė‹ˆė‹¤(źø°ė³øź°’: 10).", + "3": "ķ—ˆģš© 오차:", + "4": "예상 ė°°ź²½ģƒ‰ ģ£¼ė³€ģ˜ ģƒ‰ģƒ 변화 ė²”ģœ„ė„¼ ź²°ģ •ķ•©ė‹ˆė‹¤(źø°ė³øź°’: 30).", + "5": "ģµœģ†Œ ģ˜ģ—­:", + "6": "ģ‚¬ģ§„ģ˜ ģµœģ†Œ ģ˜ģ—­ ģž„ź³„ź°’ģ„ ģ„¤ģ •ķ•©ė‹ˆė‹¤(źø°ė³øź°’: 10000).", + "7": "ģµœģ†Œ 윤곽 ģ˜ģ—­:", + "8": "ģ‚¬ģ§„ģ˜ ģµœģ†Œ ģœ¤ź³½ģ„  ģ˜ģ—­ ģž„ź³„ź°’ģ„ ģ„¤ģ •ķ•©ė‹ˆė‹¤", + "9": "ķ…Œė‘ė¦¬ 크기:", + "10": "ģ¶œė „ģ—ģ„œ ķ°ģƒ‰ ķ…Œė‘ė¦¬ė„¼ ė°©ģ§€ķ•˜źø° ģœ„ķ•“ 추가 ė° ģ œź±°ė˜ėŠ” ķ…Œė‘ė¦¬ģ˜ 크기넼 ģ„¤ģ •ķ•©ė‹ˆė‹¤(źø°ė³øź°’: 1)." + }, + "info": "Pythonģ“ ģ„¤ģ¹˜ė˜ģ–“ ģžˆģ§€ ģ•ŠģŠµė‹ˆė‹¤. ģ‹¤ķ–‰ķ•˜ėŠ” ė° ķ•„ģš”ķ•©ė‹ˆė‹¤." + }, + "sign": { + "tags": "ģŠ¹ģø,ģ“ė‹ˆģ…œ,그린-ģ„œėŖ…,ķ…ģŠ¤ķŠø-ģ„œėŖ…,ģ“ėÆøģ§€-ģ„œėŖ…", + "title": "ģ„œėŖ…", + "header": "PDF ģ„œėŖ…", + "upload": "ģ“ėÆøģ§€ ģ—…ė”œė“œ", + "draw": "ģ„œėŖ… 그리기", + "text": "ķ…ģŠ¤ķŠø ģž…ė „", + "clear": "ģ§€ģš°źø°", + "add": "추가", + "saved": "ģ €ģž„ėœ ģ„œėŖ…", + "save": "ģ„œėŖ… ģ €ģž„", + "personalSigs": "ź°œģø ģ„œėŖ…", + "sharedSigs": "공유 ģ„œėŖ…", + "noSavedSigs": "ģ €ģž„ėœ ģ„œėŖ…ģ“ ģ—†ģŠµė‹ˆė‹¤", + "addToAll": "ėŖØė“  ķŽ˜ģ“ģ§€ģ— 추가", + "delete": "ģ‚­ģ œ", + "first": "첫 ķŽ˜ģ“ģ§€", + "last": "ė§ˆģ§€ė§‰ ķŽ˜ģ“ģ§€", + "next": "ė‹¤ģŒ ķŽ˜ģ“ģ§€", + "previous": "ģ“ģ „ ķŽ˜ģ“ģ§€", + "maintainRatio": "ģ¢…ķš”ė¹„ ģœ ģ§€ 토글", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "정적,ė¹„ķ™œģ„±ķ™”,ė¹„ėŒ€ķ™”ķ˜•,ź°„ģ†Œķ™”", + "title": "ķ‰ė©“ķ™”", + "header": "PDF ķ‰ė©“ķ™”", + "flattenOnlyForms": "ģ–‘ģ‹ė§Œ ķ‰ė©“ķ™”", + "submit": "ķ‰ė©“ķ™”" + }, + "repair": { + "tags": "ģˆ˜ģ •,복원,교정,복구", + "title": "복구", + "header": "PDF 복구", + "submit": "복구" + }, + "removeBlanks": { + "tags": "정리,ź°„ģ†Œķ™”,ė¹„ģ½˜ķ…ģø ,정리", + "title": "빈 ķŽ˜ģ“ģ§€ 제거", + "header": "빈 ķŽ˜ģ“ģ§€ 제거", + "threshold": "픽셀 ķ°ģƒ‰ė„ ģž„ź³„ź°’:", + "thresholdDesc": "ķ°ģƒ‰ ķ”½ģ…€ģ“ ģ–¼ė§ˆė‚˜ ķ°ģƒ‰ģ“ģ–“ģ•¼ 'ķ°ģƒ‰'으딜 ė¶„ė„˜ė ģ§€ ź²°ģ •ķ•˜ėŠ” ģž„ź³„ź°’. 0 = 검정, 255 순수 ķ°ģƒ‰.", + "whitePercent": "ķ°ģƒ‰ ė¹„ģœØ (%):", + "whitePercentDesc": "제거되기 ģœ„ķ•“ ķ•„ģš”ķ•œ 'ķ°ģƒ‰' ķ”½ģ…€ģ˜ ķŽ˜ģ“ģ§€ ė¹„ģœØ", + "submit": "빈 ķŽ˜ģ“ģ§€ 제거" + }, + "removeAnnotations": { + "tags": "ėŒ“źø€,ķ•˜ģ“ė¼ģ“ķŠø,ė…øķŠø,ė§ˆķ¬ģ—…,제거", + "title": "ģ£¼ģ„ 제거", + "header": "ģ£¼ģ„ 제거", + "submit": "제거" + }, + "compare": { + "tags": "ģ°Øģ“,ėŒ€ģ”°,변경,ė¶„ģ„", + "title": "비교", + "header": "PDF 비교", + "highlightColor": { + "1": "ķ•˜ģ“ė¼ģ“ķŠø ģƒ‰ģƒ 1:", + "2": "ķ•˜ģ“ė¼ģ“ķŠø ģƒ‰ģƒ 2:" + }, + "document": { + "1": "ė¬øģ„œ 1", + "2": "ė¬øģ„œ 2" + }, + "submit": "비교", + "complex": { + "message": "제공된 ė¬øģ„œ 중 ķ•˜ė‚˜ ģ“ģƒģ“ 큰 ķŒŒģ¼ģ“ėÆ€ė”œ ė¹„źµģ˜ ģ •ķ™•ė„ź°€ ė–Øģ–“ģ§ˆ 수 ģžˆģŠµė‹ˆė‹¤" + }, + "large": { + "file": { + "message": "제공된 ė¬øģ„œ 중 ķ•˜ė‚˜ ģ“ģƒģ“ ģ²˜ė¦¬ķ•˜źø°ģ— ė„ˆė¬“ ķ½ė‹ˆė‹¤" + } + }, + "no": { + "text": { + "message": "ģ„ ķƒķ•œ PDF 중 ķ•˜ė‚˜ ģ“ģƒģ— ķ…ģŠ¤ķŠø ė‚“ģš©ģ“ ģ—†ģŠµė‹ˆė‹¤. 비교넼 ģœ„ķ•“ ķ…ģŠ¤ķŠøź°€ ģžˆėŠ” PDF넼 ģ„ ķƒķ•˜ģ„øģš”." + } + } + }, + "certSign": { + "tags": "ģøģ¦,PEM,P12,ź³µģ‹,ģ•”ķ˜øķ™”", + "title": "ģøģ¦ģ„œ ģ„œėŖ…", + "header": "ģøģ¦ģ„œė”œ PDF ģ„œėŖ… (개발 중)", + "selectPDF": "ģ„œėŖ…ķ•  PDF ķŒŒģ¼ ģ„ ķƒ:", + "jksNote": "ģ°øź³ : ģøģ¦ģ„œ ģœ ķ˜•ģ“ ģ•„ėž˜ģ— ė‚˜ģ—“ė˜ģ§€ ģ•Šģ€ 경우 keytool 명령줄 ė„źµ¬ė„¼ ģ‚¬ģš©ķ•˜ģ—¬ Java ķ‚¤ģŠ¤ķ† ģ–“(.jks) ķŒŒģ¼ė”œ ė³€ķ™˜ķ•œ ė‹¤ģŒ ģ•„ėž˜ģ˜ .jks ķŒŒģ¼ ģ˜µģ…˜ģ„ ģ„ ķƒķ•˜ģ„øģš”.", + "selectKey": "ź°œģø 키 ķŒŒģ¼ ģ„ ķƒ (PKCS#8 ķ˜•ģ‹, .pem ė˜ėŠ” .der):", + "selectCert": "ģøģ¦ģ„œ ķŒŒģ¼ ģ„ ķƒ (X.509 ķ˜•ģ‹, .pem ė˜ėŠ” .der):", + "selectP12": "PKCS#12 ķ‚¤ģŠ¤ķ† ģ–“ ķŒŒģ¼ ģ„ ķƒ (.p12 ė˜ėŠ” .pfx) (ģ„ ķƒ 사항, ģ œź³µķ•˜ėŠ” 경우 ź°œģø 키와 ģøģ¦ģ„œ ķ¬ķ•Ø):", + "selectJKS": "Java ķ‚¤ģŠ¤ķ† ģ–“ ķŒŒģ¼ ģ„ ķƒ (.jks ė˜ėŠ” .keystore):", + "certType": "ģøģ¦ģ„œ ģœ ķ˜•", + "password": "ķ‚¤ģŠ¤ķ† ģ–“ ė˜ėŠ” ź°œģø 키 ė¹„ė°€ė²ˆķ˜ø ģž…ė „ (ģžˆėŠ” 경우):", + "showSig": "ģ„œėŖ… ķ‘œģ‹œ", + "reason": "ģ‚¬ģœ ", + "location": "ģœ„ģ¹˜", + "name": "ģ“ė¦„", + "showLogo": "딜고 ķ‘œģ‹œ", + "submit": "PDF ģ„œėŖ…" + }, + "removeCertSign": { + "tags": "ģøģ¦,PEM,P12,ź³µģ‹,ė³µķ˜øķ™”", + "title": "ģøģ¦ģ„œ ģ„œėŖ… 제거", + "header": "PDFģ—ģ„œ 디지털 ģ„œėŖ… 제거", + "selectPDF": "PDF ķŒŒģ¼ ģ„ ķƒ:", + "submit": "ģ„œėŖ… 제거" + }, + "pageLayout": { + "tags": "병합,합성,ė‹Øģ¼-볓기,정리", + "title": "다중 ķŽ˜ģ“ģ§€ ė ˆģ“ģ•„ģ›ƒ", + "header": "다중 ķŽ˜ģ“ģ§€ ė ˆģ“ģ•„ģ›ƒ", + "pagesPerSheet": "ģ‹œķŠøė‹¹ ķŽ˜ģ“ģ§€ 수:", + "addBorder": "ķ…Œė‘ė¦¬ 추가", + "submit": "제출" + }, + "scalePages": { + "tags": "크기씰정,ģˆ˜ģ •,치수,ģ”°ģ •", + "title": "ķŽ˜ģ“ģ§€ 크기 ģ”°ģ •", + "header": "ķŽ˜ģ“ģ§€ 크기 ģ”°ģ •", + "pageSize": "ė¬øģ„œ ķŽ˜ģ“ģ§€ģ˜ ķ¬źø°ģž…ė‹ˆė‹¤.", + "keepPageSize": "원본 크기", + "scaleFactor": "ķŽ˜ģ“ģ§€ģ˜ ķ™•ėŒ€/ģ¶•ģ†Œ 레벨(ģž˜ė¼ė‚“źø°).", + "submit": "제출" + }, + "add-page-numbers": { + "tags": "ķŽ˜ģ“ģ§€ė§¤ź¹€,ė ˆģ“ėø”,정리,ģƒ‰ģø" + }, + "auto-rename": { + "tags": "ģžė™-감지,ķ—¤ė”-기반,정리,ģž¬ė ˆģ“ėø”ė§", + "title": "ģžė™ ģ“ė¦„ 변경", + "header": "PDF ģžė™ ģ“ė¦„ 변경", + "submit": "ģžė™ ģ“ė¦„ 변경" + }, + "adjust-contrast": { + "tags": "ģƒ‰ģƒ-볓정,ģ”°ģ •,ģˆ˜ģ •,ķ–„ģƒ" + }, + "crop": { + "tags": "트림,ģ¶•ģ†Œ,ķŽøģ§‘,ėŖØģ–‘", + "title": "ģžė„“źø°", + "header": "PDF ģžė„“źø°", + "submit": "제출" + }, + "autoSplitPDF": { + "tags": "QR-기반,분리,ģŠ¤ģŗ”-ģ„øź·øėØ¼ķŠø,정리", + "title": "ģžė™ PDF ė¶„ķ• ", + "header": "ģžė™ PDF ė¶„ķ• ", + "description": "ģøģ‡„ķ•˜ź³ , ģ‚½ģž…ķ•˜ź³ , ģŠ¤ģŗ”ķ•˜ź³ , ģ—…ė”œė“œķ•˜ė©“ ė‚˜ėØøģ§€ėŠ” ģžė™ģœ¼ė”œ ģ²˜ė¦¬ė©ė‹ˆė‹¤. ģˆ˜ė™ ģ •ė ¬ ģž‘ģ—…ģ“ ķ•„ģš” ģ—†ģŠµė‹ˆė‹¤.", + "selectText": { + "1": "ģ•„ėž˜ģ—ģ„œ źµ¬ė¶„ģž ģ‹œķŠøė„¼ ģøģ‡„ķ•˜ģ„øģš” (ķ‘ė°±ė„ ź“œģ°®ģŠµė‹ˆė‹¤).", + "2": "ė¬øģ„œ ģ‚¬ģ“ģ— źµ¬ė¶„ģž ģ‹œķŠøė„¼ 넣고 ķ•œ ė²ˆģ— ėŖØė“  ė¬øģ„œė„¼ ģŠ¤ģŗ”ķ•˜ģ„øģš”.", + "3": "ģŠ¤ģŗ”ķ•œ ė‹Øģ¼ PDF ķŒŒģ¼ģ„ ģ—…ė”œė“œķ•˜ź³  ė‚˜ėØøģ§€ėŠ” Stirling PDFź°€ ģ²˜ė¦¬ķ•©ė‹ˆė‹¤.", + "4": "źµ¬ė¶„ģž ķŽ˜ģ“ģ§€ėŠ” ģžė™ģœ¼ė”œ ź°ģ§€ė˜ź³  ģ œź±°ė˜ģ–“ ź¹”ė”ķ•œ ģµœģ¢… ė¬øģ„œė„¼ ė³“ģž„ķ•©ė‹ˆė‹¤." + }, + "formPrompt": "Stirling-PDF ķŽ˜ģ“ģ§€ źµ¬ė¶„ģžź°€ ķ¬ķ•Øėœ PDF 제출:", + "duplexMode": "ģ–‘ė©“ ėŖØė“œ (ģ•žė’·ė©“ ģŠ¤ģŗ”)", + "dividerDownload2": "'ģžė™ ė¶„ķ•  źµ¬ė¶„ģž (설명 ķ¬ķ•Ø)' PDF ė‹¤ģš“ė”œė“œ", + "submit": "제출" + }, + "sanitizePdf": { + "tags": "ģ²­ģ†Œ,ė³“ģ•ˆ,ģ•ˆģ „,ģœ„ķ˜‘-제거" + }, + "URLToPDF": { + "tags": "웹-캔처,ķŽ˜ģ“ģ§€-ģ €ģž„,웹-ė¬øģ„œ,ģ•„ģ¹“ģ“ėøŒ", + "title": "URLģ„ PDF딜", + "header": "URLģ„ PDF딜", + "submit": "ė³€ķ™˜", + "credit": "WeasyPrint ģ‚¬ģš©" + }, + "HTMLToPDF": { + "tags": "ė§ˆķ¬ģ—…,웹-ģ½˜ķ…ģø ,ė³€ķ™˜,ė³€ķ™˜", + "title": "HTMLģ„ PDF딜", + "header": "HTMLģ„ PDF딜", + "help": "HTML ķŒŒģ¼ź³¼ html/css/ģ“ėÆøģ§€ ė“±ģ“ ķ¬ķ•Øėœ ZIPģ„ ķ—ˆģš©ķ•©ė‹ˆė‹¤", + "submit": "ė³€ķ™˜", + "credit": "WeasyPrint ģ‚¬ģš©", + "zoom": "ģ›¹ģ‚¬ģ“ķŠø ķ‘œģ‹œė„¼ ģœ„ķ•œ ķ™•ėŒ€/ģ¶•ģ†Œ ė ˆė²Øģž…ė‹ˆė‹¤.", + "pageWidth": "ķŽ˜ģ“ģ§€ ė„ˆė¹„ - 센티미터 ė‹Øģœ„ (źø°ė³øź°’ģ€ ė¹„ģ›Œė‘źø°)", + "pageHeight": "ķŽ˜ģ“ģ§€ ė†’ģ“ - 센티미터 ė‹Øģœ„ (źø°ė³øź°’ģ€ ė¹„ģ›Œė‘źø°)", + "marginTop": "ķŽ˜ģ“ģ§€ ģƒė‹Ø 여백 - 밀리미터 ė‹Øģœ„ (źø°ė³øź°’ģ€ ė¹„ģ›Œė‘źø°)", + "marginBottom": "ķŽ˜ģ“ģ§€ ķ•˜ė‹Ø 여백 - 밀리미터 ė‹Øģœ„ (źø°ė³øź°’ģ€ ė¹„ģ›Œė‘źø°)", + "marginLeft": "ķŽ˜ģ“ģ§€ 왼쪽 여백 - 밀리미터 ė‹Øģœ„ (źø°ė³øź°’ģ€ ė¹„ģ›Œė‘źø°)", + "marginRight": "ķŽ˜ģ“ģ§€ 오넸쪽 여백 - 밀리미터 ė‹Øģœ„ (źø°ė³øź°’ģ€ ė¹„ģ›Œė‘źø°)", + "printBackground": "ģ›¹ģ‚¬ģ“ķŠøģ˜ ė°°ź²½ģ„ ė Œė”ė§ķ•©ė‹ˆė‹¤.", + "defaultHeader": "źø°ė³ø ķ—¤ė” ķ™œģ„±ķ™” (ģ“ė¦„ ė° ķŽ˜ģ“ģ§€ 번호)", + "cssMediaType": "ķŽ˜ģ“ģ§€ģ˜ CSS 미디얓 ģœ ķ˜•ģ„ ė³€ź²½ķ•©ė‹ˆė‹¤.", + "none": "ģ—†ģŒ", + "print": "ģøģ‡„", + "screen": "화멓" + }, + "MarkdownToPDF": { + "tags": "ė§ˆķ¬ģ—…,웹-ģ½˜ķ…ģø ,ė³€ķ™˜,ė³€ķ™˜,md", + "title": "Markdownģ„ PDF딜", + "header": "Markdownģ„ PDF딜", + "submit": "ė³€ķ™˜", + "help": "ģž‘ģ—… ģ§„ķ–‰ 중", + "credit": "WeasyPrint ģ‚¬ģš©" + }, + "PDFToMarkdown": { + "tags": "ė§ˆķ¬ģ—…,웹-ģ½˜ķ…ģø ,ė³€ķ™˜,ė³€ķ™˜,md", + "title": "PDF넼 Markdown으딜", + "header": "PDF넼 Markdown으딜", + "submit": "ė³€ķ™˜" + }, + "getPdfInfo": { + "tags": "정볓,ė°ģ“ķ„°,통계,통계", + "title": "PDF 정볓 ź°€ģ øģ˜¤źø°", + "header": "PDF 정볓 ź°€ģ øģ˜¤źø°", + "submit": "정볓 ź°€ģ øģ˜¤źø°", + "downloadJson": "JSON ė‹¤ģš“ė”œė“œ" + }, + "extractPage": { + "tags": "ģ¶”ģ¶œ" + }, + "PdfToSinglePage": { + "tags": "ė‹Øģ¼ ķŽ˜ģ“ģ§€" + }, + "showJS": { + "tags": "JS", + "title": "JavaScript 볓기", + "header": "JavaScript 볓기", + "downloadJS": "JavaScript ė‹¤ģš“ė”œė“œ", + "submit": "볓기" + }, + "autoRedact": { + "tags": "검엓,ģˆØź¹€,ź²€ź²Œ-가림,ź²€ģ€ģƒ‰,마커,ģˆØź¹€", + "title": "ģžė™ 검엓", + "header": "ģžė™ 검엓", + "colorLabel": "ģƒ‰ģƒ", + "textsToRedactLabel": "검엓할 ķ…ģŠ¤ķŠø (줄 ė‹Øģœ„ė”œ 구분)", + "textsToRedactPlaceholder": "예: \\nźø°ė°€ \\n최고 źø°ė°€", + "useRegexLabel": "ģ •ź·œģ‹ ģ‚¬ģš©", + "wholeWordSearchLabel": "전첓 단얓 ź²€ģƒ‰", + "customPaddingLabel": "ģ‚¬ģš©ģž 지정 여백", + "convertPDFToImageLabel": "PDF넼 PDF-Image딜 ė³€ķ™˜ (ė°•ģŠ¤ ė’¤ģ˜ ķ…ģŠ¤ķŠø ģ œź±°ģ— ģ‚¬ģš©)", + "submitButton": "제출" + }, + "redact": { + "tags": "검엓,ģˆØź¹€,ź²€ź²Œ-가림,ź²€ģ€ģƒ‰,마커,ģˆØź¹€,ģˆ˜ė™", + "title": "ģˆ˜ė™ 검엓", + "header": "ģˆ˜ė™ 검엓", + "submit": "검엓", + "textBasedRedaction": "ķ…ģŠ¤ķŠø 기반 검엓", + "pageBasedRedaction": "ķŽ˜ģ“ģ§€ 기반 검엓", + "convertPDFToImageLabel": "PDF넼 PDF-ģ“ėÆøģ§€ė”œ ė³€ķ™˜ (ė°•ģŠ¤ ė’¤ģ˜ ķ…ģŠ¤ķŠø ģ œź±°ģ— ģ‚¬ģš©)", + "pageRedactionNumbers": { + "title": "ķŽ˜ģ“ģ§€", + "placeholder": "(예: 1,2,8 ė˜ėŠ” 4,7,12-16 ė˜ėŠ” 2n-1)" + }, + "redactionColor": { + "title": "검엓 ģƒ‰ģƒ" + }, + "export": "낓볓낓기", + "upload": "ģ—…ė”œė“œ", + "boxRedaction": "ė°•ģŠ¤ 그리기 검엓", + "zoom": "ķ™•ėŒ€/ģ¶•ģ†Œ", + "zoomIn": "ķ™•ėŒ€", + "zoomOut": "ģ¶•ģ†Œ", + "nextPage": "ė‹¤ģŒ ķŽ˜ģ“ģ§€", + "previousPage": "ģ“ģ „ ķŽ˜ģ“ģ§€", + "toggleSidebar": "ģ‚¬ģ“ė“œė°” 토글", + "showThumbnails": "ģøė„¤ģ¼ 볓기", + "showDocumentOutline": "ė¬øģ„œ ź°œģš” 볓기 (ė”ėø”ķ“ė¦­ķ•˜ģ—¬ ėŖØė“  ķ•­ėŖ© ķ™•ģž„/ģ¶•ģ†Œ)", + "showAttatchments": "첨부 ķŒŒģ¼ 볓기", + "showLayers": "ė ˆģ“ģ–“ 볓기 (ė”ėø”ķ“ė¦­ķ•˜ģ—¬ ėŖØė“  ė ˆģ“ģ–“ė„¼ źø°ė³ø 상태딜 ģž¬ģ„¤ģ •)", + "colourPicker": "ģƒ‰ģƒ ģ„ ķƒźø°", + "findCurrentOutlineItem": "ķ˜„ģž¬ ź°œģš” ķ•­ėŖ© 찾기", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,ķ…Œģ“ėø”-ģ¶”ģ¶œ,ģ¶”ģ¶œ,ė³€ķ™˜" + }, + "autoSizeSplitPDF": { + "tags": "pdf,ė¶„ķ• ,ė¬øģ„œ,정리" + }, + "overlay-pdfs": { + "tags": "ģ˜¤ė²„ė ˆģ“", + "header": "PDF ķŒŒģ¼ ģ˜¤ė²„ė ˆģ“", + "baseFile": { + "label": "źø°ė³ø PDF ķŒŒģ¼ ģ„ ķƒ" + }, + "overlayFiles": { + "label": "ģ˜¤ė²„ė ˆģ“ PDF ķŒŒģ¼ ģ„ ķƒ" + }, + "mode": { + "label": "ģ˜¤ė²„ė ˆģ“ ėŖØė“œ ģ„ ķƒ", + "sequential": "순차 ģ˜¤ė²„ė ˆģ“", + "interleaved": "ģøķ„°ė¦¬ėøŒ ģ˜¤ė²„ė ˆģ“", + "fixedRepeat": "ź³ ģ • 반복 ģ˜¤ė²„ė ˆģ“" + }, + "counts": { + "label": "ģ˜¤ė²„ė ˆģ“ 횟수 (ź³ ģ • 반복 ėŖØė“œģš©)", + "placeholder": "ģ‰¼ķ‘œė”œ źµ¬ė¶„ėœ 횟수 ģž…ė „ (예: 2,3,1)" + }, + "position": { + "label": "ģ˜¤ė²„ė ˆģ“ ģœ„ģ¹˜ ģ„ ķƒ", + "foreground": "ģ „ź²½", + "background": "ė°°ź²½" + }, + "submit": "제출" + }, + "split-by-sections": { + "tags": "ģ„¹ģ…˜ ė¶„ķ• ,ė‚˜ėˆ„źø°,ģ‚¬ģš©ģž 지정", + "title": "ģ„¹ģ…˜ė³„ PDF ė¶„ķ• ", + "header": "PDF넼 ģ„¹ģ…˜ģœ¼ė”œ ė¶„ķ• ", + "horizontal": { + "label": "ģˆ˜ķ‰ ė¶„ķ• ", + "placeholder": "ģˆ˜ķ‰ ė¶„ķ•  수 ģž…ė „" + }, + "vertical": { + "label": "수직 ė¶„ķ• ", + "placeholder": "수직 ė¶„ķ•  수 ģž…ė „" + }, + "submit": "PDF ė¶„ķ• ", + "merge": "ķ•˜ė‚˜ģ˜ PDF딜 병합" + }, + "AddStampRequest": { + "tags": "ģŠ¤ķƒ¬ķ”„,ģ“ėÆøģ§€ 추가,중앙 ģ“ėÆøģ§€,ģ›Œķ„°ė§ˆķ¬,PDF,ģ‚½ģž…,ģ‚¬ģš©ģž 지정", + "header": "PDF ģŠ¤ķƒ¬ķ”„", + "title": "PDF ģŠ¤ķƒ¬ķ”„", + "stampType": "ģŠ¤ķƒ¬ķ”„ ģœ ķ˜•", + "stampText": "ģŠ¤ķƒ¬ķ”„ ķ…ģŠ¤ķŠø", + "stampImage": "ģŠ¤ķƒ¬ķ”„ ģ“ėÆøģ§€", + "alphabet": "ģ•ŒķŒŒė²³", + "fontSize": "글꼓/ģ“ėÆøģ§€ 크기", + "rotation": "ķšŒģ „", + "opacity": "ė¶ˆķˆ¬ėŖ…ė„", + "position": "ģœ„ģ¹˜", + "overrideX": "X ģ¢Œķ‘œ ģž¬ģ •ģ˜", + "overrideY": "Y ģ¢Œķ‘œ ģž¬ģ •ģ˜", + "customMargin": "ģ‚¬ģš©ģž 지정 여백", + "customColor": "ģ‚¬ģš©ģž 지정 ķ…ģŠ¤ķŠø ģƒ‰ģƒ", + "submit": "제출" + }, + "removeImagePdf": { + "tags": "ģ“ėÆøģ§€ 제거,ķŽ˜ģ“ģ§€ ģž‘ģ—…,ė°±ģ—”ė“œ,ģ„œė²„ ģ‚¬ģ“ė“œ" + }, + "splitPdfByChapters": { + "tags": "ė¶„ķ• ,챕터,북마크,정리" + }, + "validateSignature": { + "tags": "ģ„œėŖ…,ķ™•ģø,ź²€ģ¦,pdf,ģøģ¦ģ„œ,디지털 ģ„œėŖ…,ģ„œėŖ… ź²€ģ¦,ģøģ¦ģ„œ ź²€ģ¦", + "title": "PDF ģ„œėŖ… ź²€ģ¦", + "header": "디지털 ģ„œėŖ… ź²€ģ¦", + "selectPDF": "ģ„œėŖ…ėœ PDF ķŒŒģ¼ ģ„ ķƒ", + "submit": "ģ„œėŖ… ź²€ģ¦", + "results": "ź²€ģ¦ ź²°ź³¼", + "status": { + "_value": "상태", + "valid": "ģœ ķšØķ•Ø", + "invalid": "ģœ ķšØķ•˜ģ§€ ģ•ŠģŒ" + }, + "signer": "ģ„œėŖ…ģž", + "date": "ė‚ ģ§œ", + "reason": "ģ‚¬ģœ ", + "location": "ģœ„ģ¹˜", + "noSignatures": "ģ“ ė¬øģ„œģ—ģ„œ 디지털 ģ„œėŖ…ģ„ ģ°¾ģ„ 수 ģ—†ģŠµė‹ˆė‹¤", + "chain": { + "invalid": "ģøģ¦ģ„œ ģ²“ģø ź²€ģ¦ ģ‹¤ķŒØ - ģ„œėŖ…ģžģ˜ ģ‹ ģ›ģ„ ķ™•ģøķ•  수 ģ—†ģŒ" + }, + "trust": { + "invalid": "ģøģ¦ģ„œź°€ 신뢰 ģ €ģž„ģ†Œģ— ģ—†ģŒ - 출처넼 ķ™•ģøķ•  수 ģ—†ģŒ" + }, + "cert": { + "expired": "ģøģ¦ģ„œź°€ 만료됨", + "revoked": "ģøģ¦ģ„œź°€ ģ·Øģ†ŒėØ", + "info": "ģøģ¦ģ„œ 세부 정볓", + "issuer": "ė°œźø‰ģž", + "subject": "주첓", + "serialNumber": "ģ¼ė Øė²ˆķ˜ø", + "validFrom": "유효 źø°ź°„ ģ‹œģž‘", + "validUntil": "유효 źø°ź°„ ģ¢…ė£Œ", + "algorithm": "ģ•Œź³ ė¦¬ģ¦˜", + "keySize": "키 크기", + "version": "버전", + "keyUsage": "키 ģš©ė„", + "selfSigned": "ģžģ²“ ģ„œėŖ…", + "bits": "ė¹„ķŠø" + }, + "signature": { + "info": "ģ„œėŖ… 정볓", + "_value": "ģ„œėŖ…", + "mathValid": "ģ„œėŖ…ģ“ ģˆ˜ķ•™ģ ģœ¼ė”œėŠ” ģœ ķšØķ•˜ģ§€ė§Œ:" + }, + "selectCustomCert": "ģ‚¬ģš©ģž 지정 ģøģ¦ģ„œ ķŒŒģ¼ X.509 (ģ„ ķƒģ‚¬ķ•­)" + }, + "replace-color": { + "title": "ģƒ‰ģƒ 교첓-ė°˜ģ „", + "header": "PDF ģƒ‰ģƒ 교첓-ė°˜ģ „", + "selectText": { + "1": "ģƒ‰ģƒ 교첓 ė˜ėŠ” ė°˜ģ „ ģ˜µģ…˜", + "2": "źø°ė³øź°’(źø°ė³ø ź³ ėŒ€ė¹„ ģƒ‰ģƒ)", + "3": "ģ‚¬ģš©ģž 지정(ģ‚¬ģš©ģž 지정 ģƒ‰ģƒ)", + "4": "전첓 ė°˜ģ „(ėŖØė“  ģƒ‰ģƒ ė°˜ģ „)", + "5": "ź³ ėŒ€ė¹„ ģƒ‰ģƒ ģ˜µģ…˜", + "6": "검정 배경에 ķ°ģƒ‰ ķ…ģŠ¤ķŠø", + "7": "ķ°ģƒ‰ 배경에 검정 ķ…ģŠ¤ķŠø", + "8": "검정 배경에 ė…øėž€ģƒ‰ ķ…ģŠ¤ķŠø", + "9": "검정 배경에 ģ“ˆė”ģƒ‰ ķ…ģŠ¤ķŠø", + "10": "ķ…ģŠ¤ķŠø ģƒ‰ģƒ ģ„ ķƒ", + "11": "ė°°ź²½ ģƒ‰ģƒ ģ„ ķƒ" + }, + "submit": "교첓" + }, + "replaceColorPdf": { + "tags": "ģƒ‰ģƒ 교첓,ķŽ˜ģ“ģ§€ ģž‘ģ—…,ė°±ģ—”ė“œ,ģ„œė²„ ģ‚¬ģ“ė“œ" + }, + "login": { + "title": "ė”œź·øģø", + "header": "ė”œź·øģø", + "signin": "ė”œź·øģø", + "rememberme": "ė”œź·øģø ģœ ģ§€", + "invalid": "ģ‚¬ģš©ģž ģ“ė¦„ ė˜ėŠ” ė¹„ė°€ė²ˆķ˜øź°€ ģž˜ėŖ»ė˜ģ—ˆģŠµė‹ˆė‹¤.", + "locked": "ź³„ģ •ģ“ ģž ź²¼ģŠµė‹ˆė‹¤.", + "signinTitle": "ė”œź·øģøķ•“ ģ£¼ģ„øģš”", + "ssoSignIn": "ė‹Øģ¼ ė”œź·øģøģœ¼ė”œ ė”œź·øģø", + "oAuth2AutoCreateDisabled": "OAuth2 ģ‚¬ģš©ģž ģžė™ ģƒģ„±ģ“ ė¹„ķ™œģ„±ķ™”ė˜ģ—ˆģŠµė‹ˆė‹¤", + "oAuth2AdminBlockedUser": "ķ˜„ģž¬ ėÆøė“±ė” ģ‚¬ģš©ģžģ˜ ė“±ė” ė˜ėŠ” ė”œź·øģøģ“ ģ°Øė‹Øė˜ģ–“ ģžˆģŠµė‹ˆė‹¤. ź“€ė¦¬ģžģ—ź²Œ ė¬øģ˜ķ•˜ģ„øģš”.", + "oauth2RequestNotFound": "ģøģ¦ ģš”ģ²­ģ„ ģ°¾ģ„ 수 ģ—†ģŠµė‹ˆė‹¤", + "oauth2InvalidUserInfoResponse": "ģž˜ėŖ»ėœ ģ‚¬ģš©ģž 정볓 ģ‘ė‹µ", + "oauth2invalidRequest": "ģž˜ėŖ»ėœ ģš”ģ²­", + "oauth2AccessDenied": "ģ ‘ź·¼ 거부됨", + "oauth2InvalidTokenResponse": "ģž˜ėŖ»ėœ 토큰 ģ‘ė‹µ", + "oauth2InvalidIdToken": "ģž˜ėŖ»ėœ ID 토큰", + "relyingPartyRegistrationNotFound": "신뢰 ė‹¹ģ‚¬ģž ė“±ė”ģ„ ģ°¾ģ„ 수 ģ—†ģŠµė‹ˆė‹¤", + "userIsDisabled": "ģ‚¬ģš©ģžź°€ ė¹„ķ™œģ„±ķ™”ė˜ģ–“ ģžˆģ–“ ķ˜„ģž¬ ģ“ ģ‚¬ģš©ģž ģ“ė¦„ģœ¼ė”œ ė”œź·øģøķ•  수 ģ—†ģŠµė‹ˆė‹¤. ź“€ė¦¬ģžģ—ź²Œ ė¬øģ˜ķ•˜ģ„øģš”.", + "alreadyLoggedIn": "ģ“ėÆø ė‹¤ģŒģ— ė”œź·øģøė˜ģ–“ ģžˆģŠµė‹ˆė‹¤", + "alreadyLoggedIn2": "ź°œģ˜ źø°źø°. 핓당 źø°źø°ģ—ģ„œ ė”œź·øģ•„ģ›ƒķ•œ 후 ė‹¤ģ‹œ ģ‹œė„ķ•˜ģ„øģš”.", + "toManySessions": "ķ™œģ„± ģ„øģ…˜ģ“ ė„ˆė¬“ ė§ŽģŠµė‹ˆė‹¤", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "ė‹Øģ¼ ķŽ˜ģ“ģ§€ė”œ ė³€ķ™˜", + "header": "ė‹Øģ¼ ķŽ˜ģ“ģ§€ė”œ ė³€ķ™˜", + "submit": "ė‹Øģ¼ ķŽ˜ģ“ģ§€ė”œ ė³€ķ™˜" + }, + "pageExtracter": { + "title": "ķŽ˜ģ“ģ§€ ģ¶”ģ¶œ", + "header": "ķŽ˜ģ“ģ§€ ģ¶”ģ¶œ", + "submit": "ģ¶”ģ¶œ", + "placeholder": "(예: 1,2,8 ė˜ėŠ” 4,7,12-16 ė˜ėŠ” 2n-1)" + }, + "sanitizePDF": { + "title": "PDF 정리", + "header": "PDF ķŒŒģ¼ 정리", + "selectText": { + "1": "JavaScript ģž‘ģ—… 제거", + "2": "ģž„ė² ė””ė“œ ķŒŒģ¼ 제거", + "3": "Remove XMP metadata", + "4": "링크 제거", + "5": "글꼓 제거", + "6": "Remove Document Info Metadata" + }, + "submit": "PDF 정리" + }, + "adjustContrast": { + "title": "ėŒ€ė¹„ ģ”°ģ •", + "header": "ėŒ€ė¹„ ģ”°ģ •", + "contrast": "ėŒ€ė¹„:", + "brightness": "ė°źø°:", + "saturation": "ģ±„ė„:", + "download": "ė‹¤ģš“ė”œė“œ" + }, + "compress": { + "title": "ģ••ģ¶•", + "header": "PDF ģ••ģ¶•", + "credit": "ģ“ ģ„œė¹„ģŠ¤ėŠ” PDF ģ••ģ¶•/ģµœģ ķ™”ė„¼ ģœ„ķ•“ qpdf넼 ģ‚¬ģš©ķ•©ė‹ˆė‹¤.", + "grayscale": { + "label": "ģ••ģ¶•ģ„ ģœ„ķ•“ ź·øė ˆģ“ģŠ¤ģ¼€ģ¼ 적용" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "ģµœģ ķ™” 레벨:", + "4": "ģžė™ ėŖØė“œ - PDF넼 ģ •ķ™•ķ•œ 크기딜 ė§Œė“¤źø° ģœ„ķ•“ ķ’ˆģ§ˆ ģžė™ ģ”°ģ •", + "5": "예상 PDF 크기 (예: 25MB, 10.8MB, 25KB)" + }, + "submit": "ģ••ģ¶•" + }, + "decrypt": { + "passwordPrompt": "ģ“ ķŒŒģ¼ģ€ ė¹„ė°€ė²ˆķ˜øė”œ ė³“ķ˜øė˜ģ–“ ģžˆģŠµė‹ˆė‹¤. ė¹„ė°€ė²ˆķ˜øė„¼ ģž…ė „ķ•˜ģ„øģš”:", + "cancelled": "PDF ģž‘ģ—…ģ“ ģ·Øģ†Œė˜ģ—ˆģŠµė‹ˆė‹¤: {0}", + "noPassword": "ģ•”ķ˜øķ™”ėœ PDFģ˜ ė¹„ė°€ė²ˆķ˜øź°€ ģ œź³µė˜ģ§€ ģ•Šģ•˜ģŠµė‹ˆė‹¤: {0}", + "invalidPassword": "ģ˜¬ė°”ė„ø ė¹„ė°€ė²ˆķ˜øė”œ ė‹¤ģ‹œ ģ‹œė„ķ•˜ģ„øģš”.", + "invalidPasswordHeader": "ģž˜ėŖ»ėœ ė¹„ė°€ė²ˆķ˜ø ė˜ėŠ” ģ§€ģ›ė˜ģ§€ ģ•ŠėŠ” ģ•”ķ˜øķ™”ģž…ė‹ˆė‹¤. PDF: {0}", + "unexpectedError": "ķŒŒģ¼ 처리 중 ģ˜¤ė„˜ź°€ ė°œģƒķ–ˆģŠµė‹ˆė‹¤. ė‹¤ģ‹œ ģ‹œė„ķ•˜ģ„øģš”.", + "serverError": "ė³µķ˜øķ™” 중 ģ„œė²„ 오넘 ė°œģƒ: {0}", + "success": "ķŒŒģ¼ģ“ ģ„±ź³µģ ģœ¼ė”œ ė³µķ˜øķ™”ė˜ģ—ˆģŠµė‹ˆė‹¤." + }, + "multiTool-advert": { + "message": "ģ“ źø°ėŠ„ģ€ 멀티 ė„źµ¬ ķŽ˜ģ“ģ§€ģ—ģ„œė„ ģ‚¬ģš©ķ•  수 ģžˆģŠµė‹ˆė‹¤. ķ–„ģƒėœ ķŽ˜ģ“ģ§€ė³„ UI와 추가 źø°ėŠ„ģ„ ķ™•ģøķ•“ė³“ģ„øģš”!" + }, + "pageRemover": { + "title": "ķŽ˜ģ“ģ§€ 제거기", + "header": "PDF ķŽ˜ģ“ģ§€ 제거기", + "pagesToDelete": "ģ‚­ģ œķ•  ķŽ˜ģ“ģ§€ (ģ‰¼ķ‘œė”œ źµ¬ė¶„ėœ ķŽ˜ģ“ģ§€ 번호 ėŖ©ė” ģž…ė „) :", + "submit": "ķŽ˜ģ“ģ§€ ģ‚­ģ œ", + "placeholder": "(예: 1,2,6 ė˜ėŠ” 1-10,15-30)" + }, + "imageToPDF": { + "title": "ģ“ėÆøģ§€ė„¼ PDF딜", + "header": "ģ“ėÆøģ§€ė„¼ PDF딜", + "submit": "ė³€ķ™˜", + "selectLabel": "ģ“ėÆøģ§€ ė§žģ¶¤ ģ˜µģ…˜", + "fillPage": "ķŽ˜ģ“ģ§€ ģ±„ģš°źø°", + "fitDocumentToImage": "ģ“ėÆøģ§€ģ— ė§žź²Œ ķŽ˜ģ“ģ§€ ģ”°ģ •", + "maintainAspectRatio": "ģ¢…ķš”ė¹„ ģœ ģ§€", + "selectText": { + "2": "PDF ģžė™ ķšŒģ „", + "3": "다중 ķŒŒģ¼ 딜직 (ģ—¬ėŸ¬ ģ“ėÆøģ§€ ģž‘ģ—… ģ‹œģ—ė§Œ ķ™œģ„±ķ™”)", + "4": "ė‹Øģ¼ PDF딜 병합", + "5": "ė³„ė„ģ˜ PDF딜 ė³€ķ™˜" + } + }, + "PDFToCSV": { + "title": "PDF넼 CSV딜", + "header": "PDF넼 CSV딜", + "prompt": "ķ‘œė„¼ ģ¶”ģ¶œķ•  ķŽ˜ģ“ģ§€ ģ„ ķƒ", + "submit": "ģ¶”ģ¶œ" + }, + "split-by-size-or-count": { + "title": "크기 ė˜ėŠ” 개수딜 PDF ė¶„ķ• ", + "header": "크기 ė˜ėŠ” 개수딜 PDF ė¶„ķ• ", + "type": { + "label": "ė¶„ķ•  ģœ ķ˜• ģ„ ķƒ", + "size": "크기별", + "pageCount": "ķŽ˜ģ“ģ§€ ģˆ˜ė³„", + "docCount": "ė¬øģ„œ ģˆ˜ė³„" + }, + "value": { + "label": "ź°’ ģž…ė „", + "placeholder": "크기(예: 2MB ė˜ėŠ” 3KB) ė˜ėŠ” 개수(예: 5) ģž…ė „" + }, + "submit": "제출" + }, + "printFile": { + "title": "ķŒŒģ¼ ģøģ‡„", + "header": "ķ”„ė¦°ķ„°ė”œ ķŒŒģ¼ ģøģ‡„", + "selectText": { + "1": "ģøģ‡„ķ•  ķŒŒģ¼ ģ„ ķƒ", + "2": "프린터 ģ“ė¦„ ģž…ė „" + }, + "submit": "ģøģ‡„" + }, + "licenses": { + "nav": "ė¼ģ“ģ„ ģŠ¤", + "title": "제3ģž ė¼ģ“ģ„ ģŠ¤", + "header": "제3ģž ė¼ģ“ģ„ ģŠ¤", + "module": "ėŖØė“ˆ", + "version": "버전", + "license": "ė¼ģ“ģ„ ģŠ¤" + }, + "survey": { + "nav": "설문씰사", + "title": "Stirling-PDF 설문씰사", + "description": "Stirling-PDFėŠ” 추적 źø°ėŠ„ģ“ ģ—†ģ–“ģ„œ ģ‚¬ģš©ģžģ˜ ģ˜ź²¬ģ„ 듣고 Stirling-PDF넼 ź°œģ„ ķ•˜ź³ ģž ķ•©ė‹ˆė‹¤!", + "changes": "ė§ˆģ§€ė§‰ 설문씰사 ģ“ķ›„ Stirling-PDFź°€ ė³€ź²½ė˜ģ—ˆģŠµė‹ˆė‹¤! ģžģ„øķ•œ ė‚“ģš©ģ€ ģ—¬źø°ģ—ģ„œ ėø”ė”œź·ø ķ¬ģŠ¤ķŠøė„¼ ķ™•ģøķ•˜ģ„øģš”:", + "changes2": "ģ“ėŸ¬ķ•œ ė³€ź²½ģœ¼ė”œ 유료 ė¹„ģ¦ˆė‹ˆģŠ¤ 지원과 ģžźøˆģ„ 받고 ģžˆģŠµė‹ˆė‹¤", + "please": "설문씰사에 참여핓 ģ£¼ģ„øģš”!", + "disabled": "(설문씰사 ķŒģ—…ģ€ ė‹¤ģŒ ģ—…ė°ģ“ķŠøģ—ģ„œ ė¹„ķ™œģ„±ķ™”ė˜ģ§€ė§Œ ķŽ˜ģ“ģ§€ ķ•˜ė‹Øģ—ģ„œ ź³„ģ† ģ‚¬ģš©ķ•  수 ģžˆģŠµė‹ˆė‹¤)", + "button": "설문씰사 ģ°øģ—¬", + "dontShowAgain": "ė‹¤ģ‹œ ķ‘œģ‹œķ•˜ģ§€ ģ•ŠģŒ", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "ģ“ėÆøģ§€ 제거", + "header": "ģ“ėÆøģ§€ 제거", + "removeImage": "ģ“ėÆøģ§€ 제거", + "submit": "ģ“ėÆøģ§€ 제거" + }, + "splitByChapters": { + "title": "챕터별 PDF ė¶„ķ• ", + "header": "챕터별 PDF ė¶„ķ• ", + "bookmarkLevel": "북마크 레벨", + "includeMetadata": "ė©”ķƒ€ė°ģ“ķ„° ķ¬ķ•Ø", + "allowDuplicates": "중복 ķ—ˆģš©", + "desc": { + "1": "ģ“ ė„źµ¬ėŠ” PDF ķŒŒģ¼ģ„ 챕터 구씰넼 기반으딜 ģ—¬ėŸ¬ PDF딜 ė¶„ķ• ķ•©ė‹ˆė‹¤.", + "2": "북마크 레벨: 분할에 ģ‚¬ģš©ķ•  북마크 ė ˆė²Øģ„ ģ„ ķƒķ•˜ģ„øģš” (0ģ€ ģµœģƒģœ„ 레벨, 1ģ€ 두 번째 레벨 등).", + "3": "ė©”ķƒ€ė°ģ“ķ„° ķ¬ķ•Ø: ģ²“ķ¬ķ•˜ė©“ 원본 PDFģ˜ ė©”ķƒ€ė°ģ“ķ„°ź°€ 각 ė¶„ķ• ėœ PDF에 ķ¬ķ•Øė©ė‹ˆė‹¤.", + "4": "중복 ķ—ˆģš©: ģ²“ķ¬ķ•˜ė©“ ė™ģ¼ķ•œ ķŽ˜ģ“ģ§€ģ˜ ģ—¬ėŸ¬ ė¶ė§ˆķ¬ź°€ ė³„ė„ģ˜ PDF넼 ģƒģ„±ķ•  수 ģžˆģŠµė‹ˆė‹¤." + }, + "submit": "PDF ė¶„ķ• " + }, + "fileChooser": { + "click": "큓릭", + "or": "ė˜ėŠ”", + "dragAndDrop": "ė“œėž˜ź·ø 앤 ė“œė”­", + "dragAndDropPDF": "PDF ķŒŒģ¼ģ„ ė“œėž˜ź·ø 앤 ė“œė”­", + "dragAndDropImage": "ģ“ėÆøģ§€ ķŒŒģ¼ģ„ ė“œėž˜ź·ø 앤 ė“œė”­", + "hoveredDragAndDrop": "여기에 ķŒŒģ¼ģ„ ė“œėž˜ź·ø 앤 ė“œė”­ķ•˜ģ„øģš”", + "extractPDF": "ģ¶”ģ¶œ 중..." + }, + "releases": { + "footer": "릓리스", + "title": "릓리스 ė…øķŠø", + "header": "릓리스 ė…øķŠø", + "current": { + "version": "ķ˜„ģž¬ 릓리스" + }, + "note": "릓리스 ė…øķŠøėŠ” ģ˜ģ–“ė”œė§Œ ģ œź³µė©ė‹ˆė‹¤" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/ml-ML/translation.json b/frontend/public/locales/ml-ML/translation.json new file mode 100644 index 000000000..79ca47b00 --- /dev/null +++ b/frontend/public/locales/ml-ML/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "ą“…ą“•ąµą“·ą“° ą“µą“²ąµą“Ŗąµą“Ŗą“‚", + "fontName": "ą“…ą“•ąµą“·ą“°ą“¤ąµą“¤ą“æą“Øąµą“±ąµ† ą“Ŗąµ‡ą“°ąµ", + "title": "ą“Ŗąµ‡ą“œąµ ą“Øą“®ąµą“Ŗą“±ąµą“•ąµ¾ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "header": "ą“Ŗąµ‡ą“œąµ ą“Øą“®ąµą“Ŗą“±ąµą“•ąµ¾ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "selectText": { + "1": "PDF ą“«ą“Æąµ½ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•:", + "2": "ą“®ą“¾ąµ¼ą“œą“æąµ» ą“µą“²ąµą“Ŗąµą“Ŗą“‚", + "3": "ą“øąµą“„ą“¾ą“Øą“‚", + "4": "ą“†ą“°ą“‚ą“­ą“æą“•ąµą“•ąµą“Øąµą“Ø ą“Øą“®ąµą“Ŗąµ¼", + "5": "ą“Øą“®ąµą“Ŗąµ¼ ą“šąµ†ą“Æąµą“Æąµ‡ą“£ąµą“Ÿ ą“Ŗąµ‡ą“œąµą“•ąµ¾", + "6": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ" + }, + "customTextDesc": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ", + "numberPagesDesc": "ą“ą“¤ąµ ą“Ŗąµ‡ą“œąµą“•ą“³ą“¾ą“£ąµ ą“Øą“®ąµą“Ŗąµ¼ ą“šąµ†ą“Æąµą“Æąµ‡ą“£ąµą“Ÿą“¤ąµ, ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æ 'ą“Žą“²ąµą“²ą“¾ą“‚', 1-5 ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ 2,5,9 ą“¤ąµą“Ÿą“™ąµą“™ą“æą“Æą“µą“Æąµą“‚ ą“øąµą“µąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ", + "customNumberDesc": "ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æą“Æą“¾ą“Æą“æ {n}, 'ą“Ŗąµ‡ą“œąµ {n} / {total}', 'ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ-{n}', '{filename}-{n}' ą“Žą“Øąµą“Øą“æą“µą“Æąµą“‚ ą“øąµą“µąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ", + "submit": "ą“Ŗąµ‡ą“œąµ ą“Øą“®ąµą“Ŗą“±ąµą“•ąµ¾ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•" + }, + "pdfPrompt": "PDF(ą“•ąµ¾) ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "multiPdfPrompt": "PDF-ą“•ąµ¾ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“• (2+)", + "multiPdfDropPrompt": "ą“Øą“æą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“†ą“µą“¶ąµą“Æą“®ąµą“³ąµą“³ ą“Žą“²ąµą“²ą“¾ PDF-ą“•ą“³ąµą“‚ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“• (ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“µą“²ą“æą“šąµą“šą“æą“Ÿąµą“•)", + "imgPrompt": "ą“šą“æą“¤ąµą“°ą“‚(ą“™ąµą“™ąµ¾) ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "genericSubmit": "ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•", + "uploadLimit": "ą“Ŗą“°ą“®ą“¾ą“µą“§ą“æ ą“«ą“Æąµ½ ą“µą“²ąµą“Ŗąµą“Ŗą“‚:", + "uploadLimitExceededSingular": "ą“µą“³ą“°ąµ† ą“µą“²ąµą“¤ą“¾ą“£ąµ. ą“…ą“Øąµą“µą“¦ą“Øąµ€ą“Æą“®ą“¾ą“Æ ą“Ŗą“°ą“®ą“¾ą“µą“§ą“æ ą“µą“²ąµą“Ŗąµą“Ŗą“‚", + "uploadLimitExceededPlural": "ą“µą“³ą“°ąµ† ą“µą“²ąµą“¤ą“¾ą“£ąµ. ą“…ą“Øąµą“µą“¦ą“Øąµ€ą“Æą“®ą“¾ą“Æ ą“Ŗą“°ą“®ą“¾ą“µą“§ą“æ ą“µą“²ąµą“Ŗąµą“Ŗą“‚", + "processTimeWarning": "ą“®ąµą“Øąµą“Øą“±ą“æą“Æą“æą“Ŗąµą“Ŗąµ: ą“«ą“Æąµ½ ą“µą“²ąµą“Ŗąµą“Ŗą“¤ąµą“¤ą“æą“Øą“Øąµą“øą“°ą“æą“šąµą“šąµ ą“ˆ ą“Ŗąµą“°ą“•ąµą“°ą“æą“Æ ą“’ą“°ąµ ą“®ą“æą“Øą“æą“±ąµą“±ąµ ą“µą“°ąµ† ą“Žą“Ÿąµą“¤ąµą“¤ąµ‡ą“•ąµą“•ą“¾ą“‚", + "pageOrderPrompt": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“Ŗąµ‡ą“œąµ ą“•ąµą“°ą“®ą“‚ (ą“Ŗąµ‡ą“œąµ ą“Øą“®ąµą“Ŗą“±ąµą“•ą“³ąµą“Ÿąµ† ą“•ąµ‹ą“®ą“Æą“¾ąµ½ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“š ą“²ą“æą“øąµą“±ąµą“±ąµ ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ 2n+1 ą“Ŗąµ‹ą“²ąµą“³ąµą“³ ą“«ą“‚ą“—ąµą“·ą“Øąµą“•ąµ¾ ą“Øąµ½ą“•ąµą“•) :", + "pageSelectionPrompt": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“Ŗąµ‡ą“œąµ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµ½ (ą“Ŗąµ‡ą“œąµ ą“Øą“®ąµą“Ŗą“±ąµą“•ą“³ąµą“Ÿąµ† ą“•ąµ‹ą“®ą“Æą“¾ąµ½ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“š ą“²ą“æą“øąµą“±ąµą“±ąµ 1,5,6 ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ 2n+1 ą“Ŗąµ‹ą“²ąµą“³ąµą“³ ą“«ą“‚ą“—ąµą“·ą“Øąµą“•ąµ¾ ą“Øąµ½ą“•ąµą“•) :", + "goToPage": "ą“Ŗąµ‹ą“•ąµą“•", + "true": "ą“¶ą“°ą“æ", + "false": "ą“¤ąµ†ą“±ąµą“±ąµ", + "unknown": "ą“…ą“œąµą“žą“¾ą“¤ą“‚", + "save": "ą“øąµ‡ą“µąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "saveToBrowser": "ą“¬ąµą“°ąµ—ą“øą“±ą“æąµ½ ą“øąµ‡ą“µąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "close": "ą“…ą“Ÿą“Æąµą“•ąµą“•ąµą“•", + "filesSelected": "ą“«ą“Æą“²ąµą“•ąµ¾ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“¤ąµą“¤ąµ", + "noFavourites": "ą“Ŗąµą“°ą“æą“Æą“Ŗąµą“Ŗąµ†ą“Ÿąµą“Ÿą“µ ą“šąµ‡ąµ¼ą“¤ąµą“¤ą“æą“Ÿąµą“Ÿą“æą“²ąµą“²", + "downloadComplete": "ą“”ąµ—ąµŗą“²ąµ‹ą“”ąµ ą“Ŗąµ‚ąµ¼ą“¤ąµą“¤ą“æą“Æą“¾ą“Æą“æ", + "bored": "ą“•ą“¾ą“¤ąµą“¤ą“æą“°ąµą“Øąµą“Øąµ ą“®ąµą“·ą“æą“žąµą“žąµ‹?", + "alphabet": "ą“…ą“•ąµą“·ą“°ą“®ą“¾ą“²", + "downloadPdf": "PDF ą“”ąµ—ąµŗą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "text": "ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ", + "font": "ą“…ą“•ąµą“·ą“°ą“‚", + "selectFillter": "-- ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“• --", + "pageNum": "ą“Ŗąµ‡ą“œąµ ą“Øą“®ąµą“Ŗąµ¼", + "sizes": { + "small": "ą“šąµ†ą“±ąµą“¤ąµ", + "medium": "ą“‡ą“Ÿą“¤ąµą“¤ą“°ą“‚", + "large": "ą“µą“²ąµą“¤ąµ", + "x-large": "ą“•ąµ‚ą“Ÿąµą“¤ąµ½ ą“µą“²ąµą“¤ąµ" + }, + "error": { + "pdfPassword": "PDF ą“”ąµ‹ą“•ąµą“Æąµą“®ąµ†ą“Øąµą“±ąµ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµ ą“øą“‚ą“°ą“•ąµą“·ą“æą“šąµą“šą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ, ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“Øąµ½ą“•ą“æą“Æą“æą“Ÿąµą“Ÿą“æą“²ąµą“² ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“¤ąµ†ą“±ąµą“±ą“¾ą“Æą“æą“°ąµą“Øąµą“Øąµ", + "_value": "ą“Ŗą“æą“¶ą“•ąµ", + "sorry": "ą“Ŗąµą“°ą“¶ąµą“Øą“¤ąµą“¤ą“æą“Øąµ ą“•ąµą“·ą“®ą“æą“•ąµą“•ąµą“•!", + "needHelp": "ą“øą“¹ą“¾ą“Æą“‚ ą“µąµ‡ą“£ąµ‹ / ą“’ą“°ąµ ą“Ŗąµą“°ą“¶ąµą“Øą“‚ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ą“æą“Æąµ‹?", + "contactTip": "ą“Øą“æą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“‡ą“Ŗąµą“Ŗąµ‹ą““ąµą“‚ ą“Ŗąµą“°ą“¶ąµā€Œą“Øą“®ąµą“£ąµą“Ÿąµ†ą“™ąµą“•ą“æąµ½, ą“øą“¹ą“¾ą“Æą“¤ąµą“¤ą“æą“Øą“¾ą“Æą“æ ą“žą“™ąµą“™ą“³ąµ† ą“¬ą“Øąµą“§ą“Ŗąµą“Ŗąµ†ą“Ÿą“¾ąµ» ą“®ą“Ÿą“æą“•ąµą“•ą“°ąµą“¤ąµ. ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† GitHub ą“Ŗąµ‡ą“œą“æąµ½ ą“Øą“æą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“’ą“°ąµ ą“Ÿą“æą“•ąµą“•ą“±ąµą“±ąµ ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ą“¾ą“‚ ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ Discord ą“µą““ą“æ ą“žą“™ąµą“™ą“³ąµ† ą“¬ą“Øąµą“§ą“Ŗąµą“Ŗąµ†ą“Ÿą“¾ą“‚:", + "404": { + "head": "404 - ą“Ŗąµ‡ą“œąµ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ą“æą“Æą“æą“²ąµą“² | ą“…ą“Æąµą“Æąµ‹, ą“žą“™ąµą“™ąµ¾ ą“•ąµ‹ą“”ą“æąµ½ ą“¤ą“Ÿąµą“Ÿą“æ ą“µąµ€ą“£ąµ!", + "1": "ą“Øą“æą“™ąµą“™ąµ¾ ą“¤ą“æą“°ą“Æąµą“Øąµą“Ø ą“Ŗąµ‡ą“œąµ ą“žą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ą“¾ąµ» ą“•ą““ą“æą“Æąµą“Øąµą“Øą“æą“²ąµą“².", + "2": "ą“Žą“Øąµą“¤ąµ‹ ą“•ąµą““ą“Ŗąµą“Ŗą“‚ ą“øą“‚ą“­ą“µą“æą“šąµą“šąµ" + }, + "github": "GitHub-ąµ½ ą“’ą“°ąµ ą“Ÿą“æą“•ąµą“•ą“±ąµą“±ąµ ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•", + "showStack": "ą“øąµą“±ąµą“±ą“¾ą“•ąµą“•ąµ ą“Ÿąµą“°ąµ‡ą“øąµ ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“•", + "copyStack": "ą“øąµą“±ąµą“±ą“¾ą“•ąµą“•ąµ ą“Ÿąµą“°ąµ‡ą“øąµ ą“Ŗą“•ąµ¼ą“¤ąµą“¤ąµą“•", + "githubSubmit": "GitHub - ą“’ą“°ąµ ą“Ÿą“æą“•ąµą“•ą“±ąµą“±ąµ ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•", + "discordSubmit": "Discord - ą“Ŗą“æą“Øąµą“¤ąµą“£ą“¾ ą“Ŗąµ‹ą“øąµą“±ąµą“±ąµ ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•" + }, + "delete": "ą“®ą“¾ą“Æąµą“•ąµą“•ąµą“•", + "username": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒą“Øą“¾ą“®ą“‚", + "password": "ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ", + "welcome": "ą“øąµą“µą“¾ą“—ą“¤ą“‚", + "property": "ą“Ŗąµą“°ąµ‹ą“Ŗąµą“Ŗąµ¼ą“Ÿąµą“Ÿą“æ", + "black": "ą“•ą“±ąµą“Ŗąµą“Ŗąµ", + "white": "ą“µąµ†ą“³ąµą“³", + "red": "ą“šąµą“µą“Ŗąµą“Ŗąµ", + "green": "ą“Ŗą“šąµą“š", + "blue": "ą“Øąµ€ą“²", + "custom": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ą“‚...", + "WorkInProgess": "ą“Øą“æąµ¼ą“®ąµą“®ą“¾ą“£ą“¤ąµą“¤ą“æą“²ą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ, ą“¶ą“°ą“æą“Æą“¾ą“Æą“æ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“šąµą“šąµ‡ą“•ąµą“•ą“æą“²ąµą“² ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“¬ą“—ąµą“—ąµą“•ąµ¾ ą“‰ą“£ąµą“Ÿą“¾ą“•ą“¾ą“‚, ą“¦ą“Æą“µą“¾ą“Æą“æ ą“Ŗąµą“°ą“¶ąµą“Øą“™ąµą“™ąµ¾ ą“…ą“±ą“æą“Æą“æą“•ąµą“•ąµą“•!", + "poweredBy": "ą“øą“¹ą“¾ą“Æą“¤ąµą“¤ąµ‹ą“Ÿąµ†", + "yes": "ą“…ą“¤ąµ†", + "no": "ą“‡ą“²ąµą“²", + "changedCredsMessage": "ą“µą“æą“µą“°ą“™ąµą“™ąµ¾ ą“®ą“¾ą“±ąµą“±ą“æ!", + "notAuthenticatedMessage": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµ† ą“øąµą“„ą“æą“°ąµ€ą“•ą“°ą“æą“šąµą“šą“æą“Ÿąµą“Ÿą“æą“²ąµą“².", + "userNotFoundMessage": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµ† ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ą“æą“Æą“æą“²ąµą“².", + "incorrectPasswordMessage": "ą“Øą“æą“²ą“µą“æą“²ąµ† ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“¤ąµ†ą“±ąµą“±ą“¾ą“£ąµ.", + "usernameExistsMessage": "ą“Ŗąµą“¤ą“æą“Æ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒą“Øą“¾ą“®ą“‚ ą“‡ą“¤ą“æą“Øą“•ą“‚ ą“Øą“æą“²ą“µą“æą“²ąµą“£ąµą“Ÿąµ.", + "invalidUsernameMessage": "ą“…ą“øą“¾ą“§ąµą“µą“¾ą“Æ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒą“Øą“¾ą“®ą“‚, ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒą“Øą“¾ą“®ą“¤ąµą“¤ą“æąµ½ ą“…ą“•ąµą“·ą“°ą“™ąµą“™ąµ¾, ą“…ą“•ąµą“•ą“™ąµą“™ąµ¾, ą“¤ą“¾ą““ąµ† ą“Ŗą“±ą“Æąµą“Øąµą“Ø ą“Ŗąµą“°ą“¤ąµą“Æąµ‡ą“• ą“Ŗąµą“°ą“¤ąµ€ą“•ą“™ąµą“™ąµ¾ @._+- ą“Žą“Øąµą“Øą“æą“µ ą“®ą“¾ą“¤ąµą“°ą“®ąµ‡ ą“‰ą“£ąµą“Ÿą“¾ą“•ą“¾ą“µąµ‚ ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“øą“¾ą“§ąµą“µą“¾ą“Æ ą“’ą“°ąµ ą“‡ą“®ąµ†ą“Æą“æąµ½ ą“µą“æą“²ą“¾ą“øą“‚ ą“†ą“Æą“æą“°ą“æą“•ąµą“•ą“£ą“‚.", + "invalidPasswordMessage": "ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“¶ąµ‚ą“Øąµą“Æą“®ą“¾ą“Æą“æą“°ą“æą“•ąµą“•ą“°ąµą“¤ąµ, ą“¤ąµą“Ÿą“•ąµą“•ą“¤ąµą“¤ą“æą“²ąµ‹ ą“…ą“µą“øą“¾ą“Øą“¤ąµą“¤ą“æą“²ąµ‹ ą“øąµą“Ŗąµ‡ą“øąµą“•ąµ¾ ą“‰ą“£ąµą“Ÿą“¾ą“•ą“°ąµą“¤ąµ.", + "confirmPasswordErrorMessage": "ą“Ŗąµą“¤ą“æą“Æ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµą“‚ ą“Ŗąµą“¤ą“æą“Æ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“øąµą“„ą“æą“°ąµ€ą“•ą“°ą“£ą“µąµą“‚ ą“ŖąµŠą“°ąµą“¤ąµą“¤ą“Ŗąµą“Ŗąµ†ą“Ÿą“£ą“‚.", + "deleteCurrentUserMessage": "ą“Øą“æą“²ą“µą“æąµ½ ą“²ąµ‹ą“—ą“æąµ» ą“šąµ†ą“Æąµą“¤ą“æą“Ÿąµą“Ÿąµą“³ąµą“³ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµ† ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ą“¾ąµ» ą“•ą““ą“æą“Æą“æą“²ąµą“².", + "deleteUsernameExistsMessage": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒą“Øą“¾ą“®ą“‚ ą“Øą“æą“²ą“µą“æą“²ą“æą“²ąµą“², ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ą“¾ąµ» ą“•ą““ą“æą“Æą“æą“²ąµą“².", + "downgradeCurrentUserMessage": "ą“Øą“æą“²ą“µą“æą“²ąµ† ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµą“±ąµ† ą“±ąµ‹ąµ¾ ą“¤ą“¾ą““ąµą“¤ąµą“¤ą“¾ąµ» ą“•ą““ą“æą“Æą“æą“²ąµą“²", + "disabledCurrentUserMessage": "ą“Øą“æą“²ą“µą“æą“²ąµ† ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµ† ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“°ą“¹ą“æą“¤ą“®ą“¾ą“•ąµą“•ą“¾ąµ» ą“•ą““ą“æą“Æą“æą“²ąµą“²", + "downgradeCurrentUserLongMessage": "ą“Øą“æą“²ą“µą“æą“²ąµ† ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµą“±ąµ† ą“±ąµ‹ąµ¾ ą“¤ą“¾ą““ąµą“¤ąµą“¤ą“¾ąµ» ą“•ą““ą“æą“Æą“æą“²ąµą“². ą“…ą“¤ą“æą“Øą“¾ąµ½, ą“Øą“æą“²ą“µą“æą“²ąµ† ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµ† ą“•ą“¾ą“£ą“æą“•ąµą“•ą“æą“²ąµą“².", + "userAlreadyExistsOAuthMessage": "ą“ˆ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µąµ ą“‡ą“¤ą“æą“Øą“•ą“‚ ą“’ą“°ąµ OAuth2 ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“¾ą“Æą“æ ą“Øą“æą“²ą“µą“æą“²ąµą“£ąµą“Ÿąµ.", + "userAlreadyExistsWebMessage": "ą“ˆ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µąµ ą“‡ą“¤ą“æą“Øą“•ą“‚ ą“’ą“°ąµ ą“µąµ†ą“¬ąµ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“¾ą“Æą“æ ą“Øą“æą“²ą“µą“æą“²ąµą“£ąµą“Ÿąµ.", + "oops": "ą“…ą“Æąµą“Æąµ‹!", + "help": "ą“øą“¹ą“¾ą“Æą“‚", + "goHomepage": "ą“¹ąµ‹ą“‚ą“Ŗąµ‡ą“œą“æą“²ąµ‡ą“•ąµą“•ąµ ą“Ŗąµ‹ą“•ąµą“•", + "joinDiscord": "ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† ą“”ą“æą“øąµą“•ąµ‹ąµ¼ą“”ąµ ą“øąµ†ąµ¼ą“µą“±ą“æąµ½ ą“šąµ‡ą“°ąµą“•", + "seeDockerHub": "ą“”ąµ‹ą“•ąµą“•ąµ¼ ą“¹ą“¬ąµ ą“•ą“¾ą“£ąµą“•", + "visitGithub": "ą“—ą“æą“±ąµą“±ąµą“¹ą“¬ąµ ą“±ą“æą“Ŗąµą“Ŗąµ‹ą“øą“æą“±ąµą“±ą“±ą“æ ą“øą“Øąµą“¦ąµ¼ą“¶ą“æą“•ąµą“•ąµą“•", + "donate": "ą“øą“‚ą“­ą“¾ą“µą“Ø ą“šąµ†ą“Æąµą“Æąµą“•", + "color": "ą“Øą“æą“±ą“‚", + "sponsor": "ą“øąµą“Ŗąµ‹ąµŗą“øąµ¼ ą“šąµ†ą“Æąµą“Æąµą“•", + "info": "ą“µą“æą“µą“°ą“‚", + "pro": "ą“Ŗąµą“°ąµ‹", + "page": "ą“Ŗąµ‡ą“œąµ", + "pages": "ą“Ŗąµ‡ą“œąµą“•ąµ¾", + "loading": "ą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ...", + "addToDoc": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "reset": "ą“Ŗąµą“Øą“ƒą“øą“œąµą“œą“®ą“¾ą“•ąµą“•ąµą“•", + "apply": "ą“Ŗąµą“°ą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“•", + "noFileSelected": "ą“«ą“Æą“²ąµŠą“Øąµą“Øąµą“‚ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“¤ąµą“¤ą“æą“Ÿąµą“Ÿą“æą“²ąµą“². ą“¦ą“Æą“µą“¾ą“Æą“æ ą“’ą“°ąµ†ą“£ąµą“£ą“‚ ą“…ą“Ŗąµā€Œą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•.", + "legal": { + "privacy": "ą“øąµą“µą“•ą“¾ą“°ąµą“Æą“¤ą“¾ ą“Øą“Æą“‚", + "terms": "ą“Øą“æą“¬ą“Øąµą“§ą“Øą“•ą“³ąµą“‚ ą“µąµą“Æą“µą“øąµą“„ą“•ą“³ąµą“‚", + "accessibility": "ą“²ą“­ąµą“Æą“¤", + "cookie": "ą“•ąµą“•ąµą“•ą“æ ą“Øą“Æą“‚", + "impressum": "ą“‡ą“‚ą“Ŗąµą“°ąµ†ą“øąµą“øą“‚", + "showCookieBanner": "ą“•ąµą“•ąµą“•ą“æ ą“®ąµąµ»ą“—ą“£ą“Øą“•ąµ¾" + }, + "pipeline": { + "header": "ą“Ŗąµˆą“Ŗąµą“Ŗąµą“²ąµˆąµ» ą“®ąµ†ą“Øąµ (ą“¬ąµ€ą“±ąµą“±)", + "uploadButton": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ą“‚ ą“…ą“Ŗąµā€Œą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "configureButton": "ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "defaultOption": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ą“‚", + "submitButton": "ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•", + "help": "ą“Ŗąµˆą“Ŗąµą“Ŗąµą“²ąµˆąµ» ą“øą“¹ą“¾ą“Æą“‚", + "scanHelp": "ą“«ąµ‹ąµ¾ą“”ąµ¼ ą“øąµą“•ą“¾ą“Øą“æą“‚ą“—ąµ ą“øą“¹ą“¾ą“Æą“‚", + "deletePrompt": "ą“Ŗąµˆą“Ŗąµą“Ŗąµą“²ąµˆąµ» ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ą“¾ąµ» ą“Øą“æą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“‰ą“±ą“Ŗąµą“Ŗą“¾ą“£ąµ‹", + "tags": "ą““ą“Ÿąµą“Ÿąµ‹ą“®ąµ‡ą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“•,ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•,ą“øąµą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“¤,ą“¬ą“¾ą“šąµą“šąµ-ą“Ŗąµą“°ąµ‹ą“øą“øąµą“øąµ", + "title": "ą“Ŗąµˆą“Ŗąµą“Ŗąµą“²ąµˆąµ»" + }, + "pipelineOptions": { + "header": "ą“Ŗąµˆą“Ŗąµą“Ŗąµą“²ąµˆąµ» ą“•ąµ‹ąµŗą“«ą“æą“—ą“±ąµ‡ą“·ąµ»", + "pipelineNameLabel": "ą“Ŗąµˆą“Ŗąµą“Ŗąµą“²ąµˆąµ» ą“Ŗąµ‡ą“°ąµ", + "saveSettings": "ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Ø ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾ ą“øą“‚ą“°ą“•ąµą“·ą“æą“•ąµą“•ąµą“•", + "pipelineNamePrompt": "ą“Ŗąµˆą“Ŗąµą“Ŗąµą“²ąµˆąµ» ą“Ŗąµ‡ą“°ąµ ą“‡ą“µą“æą“Ÿąµ† ą“Øąµ½ą“•ąµą“•", + "selectOperation": "ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "addOperationButton": "ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "pipelineHeader": "ą“Ŗąµˆą“Ŗąµą“Ŗąµą“²ąµˆąµ»:", + "saveButton": "ą“”ąµ—ąµŗą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "validateButton": "ą“øąµą“„ą“æą“°ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•" + }, + "enterpriseEdition": { + "button": "ą“Ŗąµą“°ąµ‹ą“Æą“æą“²ąµ‡ą“•ąµą“•ąµ ą“…ą“Ŗąµā€Œą“—ąµą“°ąµ‡ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "warning": "ą“ˆ ą“«ąµ€ą“šąµą“šąµ¼ ą“Ŗąµą“°ąµ‹ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“•ąµą“•ąµ¾ą“•ąµą“•ąµ ą“®ą“¾ą“¤ąµą“°ą“®ąµ‡ ą“²ą“­ąµą“Æą“®ą“¾ą“•ąµ‚.", + "yamlAdvert": "ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ PDF ą“Ŗąµą“°ąµ‹ YAML ą“•ąµ‹ąµŗą“«ą“æą“—ą“±ąµ‡ą“·ąµ» ą“«ą“Æą“²ąµą“•ą“³ąµ†ą“Æąµą“‚ ą“®ą“±ąµą“±ąµ SSO ą“øą“µą“æą“¶ąµ‡ą“·ą“¤ą“•ą“³ąµ†ą“Æąµą“‚ ą“Ŗą“æą“Øąµą“¤ąµą“£ą“Æąµą“•ąµą“•ąµą“Øąµą“Øąµ.", + "ssoAdvert": "ą“•ąµ‚ą“Ÿąµą“¤ąµ½ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒ ą“®ą“¾ą“Øąµ‡ą“œąµą“®ąµ†ą“Øąµą“±ąµ ą“øą“µą“æą“¶ąµ‡ą“·ą“¤ą“•ąµ¾ą“•ąµą“•ą“¾ą“Æą“æ ą“¤ą“æą“°ą“Æąµą“•ą“Æą“¾ą“£ąµ‹? ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ PDF ą“Ŗąµą“°ąµ‹ ą“Ŗą“°ą“æą“¶ąµ‹ą“§ą“æą“•ąµą“•ąµą“•" + }, + "analytics": { + "title": "ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ PDF ą“®ą“æą“•ą“šąµą“šą“¤ą“¾ą“•ąµą“•ą“¾ąµ» ą“Øą“æą“™ąµą“™ąµ¾ ą“†ą“—ąµą“°ą“¹ą“æą“•ąµą“•ąµą“Øąµą“Øąµą“£ąµą“Ÿąµ‹?", + "paragraph1": "ą“‰ąµ½ą“Ŗąµą“Ŗą“Øąµą“Øą“‚ ą“®ąµ†ą“šąµą“šą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ą“¾ąµ» ą“žą“™ąµą“™ą“³ąµ† ą“øą“¹ą“¾ą“Æą“æą“•ąµą“•ąµą“Øąµą“Øą“¤ą“æą“Øąµ ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ PDF-ąµ½ ą““ą“Ŗąµą“±ąµą“±ąµ-ą“‡ąµ» ą“…ą“Øą“²ą“æą“±ąµą“±ą“æą“•ąµą“øąµ ą“‰ą“£ąµą“Ÿąµ. ą“žą“™ąµą“™ąµ¾ ą“µąµą“Æą“•ąµą“¤ą“æą“—ą“¤ ą“µą“æą“µą“°ą“™ąµą“™ą“³ąµ‹ ą“«ą“Æąµ½ ą“‰ą“³ąµą“³ą“Ÿą“•ąµą“•ą“™ąµą“™ą“³ąµ‹ ą“Ÿąµą“°ą“¾ą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øą“æą“²ąµą“².", + "paragraph2": "ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ-PDF ą“µą“³ą“°ą“¾ą“Øąµą“‚ ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“•ąµą“•ą“³ąµ† ą“Øą“Øąµą“Øą“¾ą“Æą“æ ą“®ą“Øą“øąµą“øą“æą“²ą“¾ą“•ąµą“•ą“¾ą“Øąµą“‚ ą“…ą“Øą“²ą“æą“±ąµą“±ą“æą“•ąµą“øąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“•ąµą“·ą“®ą“®ą“¾ą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“Ŗą“°ą“æą“—ą“£ą“æą“•ąµą“•ąµą“•.", + "enable": "ą“…ą“Øą“²ą“æą“±ąµą“±ą“æą“•ąµą“øąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“•ąµą“·ą“®ą“®ą“¾ą“•ąµą“•ąµą“•", + "disable": "ą“…ą“Øą“²ą“æą“±ąµą“±ą“æą“•ąµą“øąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“°ą“¹ą“æą“¤ą“®ą“¾ą“•ąµą“•ąµą“•", + "settings": "config/settings.yml ą“«ą“Æą“²ą“æąµ½ ą“Øą“æą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“…ą“Øą“²ą“æą“±ąµą“±ą“æą“•ąµą“øą“æą“Øą“¾ą“Æąµą“³ąµą“³ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾ ą“®ą“¾ą“±ąµą“±ą“¾ąµ» ą“•ą““ą“æą“Æąµą“‚" + }, + "navbar": { + "favorite": "ą“Ŗąµą“°ą“æą“Æą“Ŗąµą“Ŗąµ†ą“Ÿąµą“Ÿą“µ", + "recent": "ą“Ŗąµą“¤ą“æą“Æą“¤ąµą“‚ ą“…ą“Ÿąµą“¤ąµą“¤ą“æą“Ÿąµ† ą“…ą“Ŗąµā€Œą“”ąµ‡ą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“¤ą“¤ąµą“‚", + "darkmode": "ą“”ą“¾ąµ¼ą“•ąµą“•ąµ ą“®ąµ‹ą“”ąµ", + "language": "ą“­ą“¾ą“·ą“•ąµ¾", + "settings": "ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾", + "allTools": "ą“‰ą“Ŗą“•ą“°ą“£ą“™ąµą“™ąµ¾", + "multiTool": "ą“®ąµ¾ą“Ÿąµą“Ÿą“æ ą“Ÿąµ‚ąµ¾", + "search": "ą“¤ą“æą“°ą“Æąµą“•", + "sections": { + "organize": "ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "convertTo": "PDF-ą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•", + "convertFrom": "PDF-ąµ½ ą“Øą“æą“Øąµą“Øąµ ą“®ą“¾ą“±ąµą“±ąµą“•", + "security": "ą“’ą“Ŗąµą“Ŗąµą“‚ ą“øąµą“°ą“•ąµą“·ą“Æąµą“‚", + "advance": "ą“µą“æą“Ŗąµą“²ą“®ą“¾ą“Æą“¤ąµ", + "edit": "ą“•ą“¾ą“£ąµą“• & ą“¤ą“æą“°ąµą“¤ąµą“¤ąµą“•", + "popular": "ą“œą“Øą“Ŗąµą“°ą“æą“Æą“‚" + } + }, + "settings": { + "title": "ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾", + "update": "ą“…ą“Ŗąµā€Œą“”ąµ‡ą“±ąµą“±ąµ ą“²ą“­ąµą“Æą“®ą“¾ą“£ąµ", + "updateAvailable": "{0} ą“Øą“æą“²ą“µą“æąµ½ ą“‡ąµ»ą“øąµą“±ąµą“±ą“¾ąµ¾ ą“šąµ†ą“Æąµą“¤ ą“Ŗą“¤ą“æą“Ŗąµą“Ŗą“¾ą“£ąµ. ą“’ą“°ąµ ą“Ŗąµą“¤ą“æą“Æ ą“Ŗą“¤ą“æą“Ŗąµą“Ŗąµ ({1}) ą“²ą“­ąµą“Æą“®ą“¾ą“£ąµ.", + "appVersion": "ą“†ą“Ŗąµą“Ŗąµ ą“Ŗą“¤ą“æą“Ŗąµą“Ŗąµ:", + "downloadOption": { + "title": "ą“”ąµ—ąµŗą“²ąµ‹ą“”ąµ ą““ą“Ŗąµą“·ąµ» ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“• (ą“øą“æą“‚ą“—ą“æąµ¾ ą“«ą“Æąµ½ ą“Øąµ‹ąµŗ-ą“øą“æą“Ŗąµą“Ŗąµ ą“”ąµ—ąµŗą“²ąµ‹ą“”ąµą“•ąµ¾ą“•ąµą“•ąµ):", + "1": "ą“’ą“°ąµ‡ ą“µą“æąµ»ą“”ąµ‹ą“Æą“æąµ½ ą“¤ąµą“±ą“•ąµą“•ąµą“•", + "2": "ą“Ŗąµą“¤ą“æą“Æ ą“µą“æąµ»ą“”ąµ‹ą“Æą“æąµ½ ą“¤ąµą“±ą“•ąµą“•ąµą“•", + "3": "ą“«ą“Æąµ½ ą“”ąµ—ąµŗą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "zipThreshold": "ą“”ąµ—ąµŗą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“¤ ą“«ą“Æą“²ąµą“•ą“³ąµą“Ÿąµ† ą“Žą“£ąµą“£ą“‚ ą“•ą“µą“æą“Æąµą“®ąµą“Ŗąµ‹ąµ¾ ą“«ą“Æą“²ąµą“•ąµ¾ ą“øą“æą“Ŗąµą“Ŗąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "signOut": "ą“øąµˆąµ» ą“”ą“Ÿąµą“Ÿąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "accountSettings": "ą“…ą“•ąµą“•ąµ—ą“£ąµą“Ÿąµ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾", + "bored": { + "help": "ą“ˆą“øąµą“±ąµą“±ąµ¼ ą“Žą“—ąµ ą“—ąµ†ą“Æą“æą“‚ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“•ąµą“·ą“®ą“®ą“¾ą“•ąµą“•ąµą“Øąµą“Øąµ" + }, + "cacheInputs": { + "name": "ą“«ąµ‹ą“‚ ą“‡ąµ»ą“Ŗąµą“Ÿąµą“Ÿąµą“•ąµ¾ ą“øą“‚ą“°ą“•ąµą“·ą“æą“•ąµą“•ąµą“•", + "help": "ą“­ą“¾ą“µą“æą“Æą“æą“²ąµ† ą“‰ą“Ŗą“Æąµ‹ą“—ą“¤ąµą“¤ą“æą“Øą“¾ą“Æą“æ ą“®ąµą“®ąµą“Ŗąµ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“š ą“‡ąµ»ą“Ŗąµą“Ÿąµą“Ÿąµą“•ąµ¾ ą“øą“‚ą“­ą“°ą“æą“•ąµą“•ą“¾ąµ» ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“•ąµą“·ą“®ą“®ą“¾ą“•ąµą“•ąµą“•" + } + }, + "changeCreds": { + "title": "ą“µą“æą“µą“°ą“™ąµą“™ąµ¾ ą“®ą“¾ą“±ąµą“±ąµą“•", + "header": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“…ą“•ąµą“•ąµ—ą“£ąµą“Ÿąµ ą“µą“æą“µą“°ą“™ąµą“™ąµ¾ ą“…ą“Ŗąµā€Œą“”ąµ‡ą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "changePassword": "ą“Øą“æą“™ąµą“™ąµ¾ ą“øąµą“„ą“æą“° ą“²ąµ‹ą“—ą“æąµ» ą“µą“æą“µą“°ą“™ąµą“™ą“³ą“¾ą“£ąµ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ. ą“¦ą“Æą“µą“¾ą“Æą“æ ą“’ą“°ąµ ą“Ŗąµą“¤ą“æą“Æ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“Øąµ½ą“•ąµą“•", + "newUsername": "ą“Ŗąµą“¤ą“æą“Æ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒą“Øą“¾ą“®ą“‚", + "oldPassword": "ą“Øą“æą“²ą“µą“æą“²ąµ† ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ", + "newPassword": "ą“Ŗąµą“¤ą“æą“Æ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ", + "confirmNewPassword": "ą“Ŗąµą“¤ą“æą“Æ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“øąµą“„ą“æą“°ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "submit": "ą“®ą“¾ą“±ąµą“±ą“™ąµą“™ąµ¾ ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•" + }, + "account": { + "title": "ą“…ą“•ąµą“•ąµ—ą“£ąµą“Ÿąµ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾", + "accountSettings": "ą“…ą“•ąµą“•ąµ—ą“£ąµą“Ÿąµ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾", + "adminSettings": "ą“…ą“”ąµą“®ą“æąµ» ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾ - ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“•ąµą“•ą“³ąµ† ą“•ą“¾ą“£ąµą“•, ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "userControlSettings": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒ ą“Øą“æą“Æą“Øąµą“¤ąµą“°ą“£ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾", + "changeUsername": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒą“Øą“¾ą“®ą“‚ ą“®ą“¾ą“±ąµą“±ąµą“•", + "newUsername": "ą“Ŗąµą“¤ą“æą“Æ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒą“Øą“¾ą“®ą“‚", + "password": "ą“øąµą“„ą“æą“°ąµ€ą“•ą“°ą“£ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ", + "oldPassword": "ą“Ŗą““ą“Æ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ", + "newPassword": "ą“Ŗąµą“¤ą“æą“Æ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ", + "changePassword": "ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“®ą“¾ą“±ąµą“±ąµą“•", + "confirmNewPassword": "ą“Ŗąµą“¤ą“æą“Æ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“øąµą“„ą“æą“°ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "signOut": "ą“øąµˆąµ» ą“”ą“Ÿąµą“Ÿąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "yourApiKey": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† API ą“•ąµ€", + "syncTitle": "ą“¬ąµą“°ąµ—ą“øąµ¼ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾ ą“…ą“•ąµą“•ąµ—ą“£ąµą“Ÿąµą“®ą“¾ą“Æą“æ ą“øą“®ą“Øąµą“µą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•", + "settingsCompare": "ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ ą“¤ą“¾ą“°ą“¤ą“®ąµą“Æą“‚:", + "property": "ą“Ŗąµą“°ąµ‹ą“Ŗąµą“Ŗąµ¼ą“Ÿąµą“Ÿą“æ", + "webBrowserSettings": "ą“µąµ†ą“¬ąµ ą“¬ąµą“°ąµ—ą“øąµ¼ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“‚", + "syncToBrowser": "ą“…ą“•ąµą“•ąµ—ą“£ąµą“Ÿąµ ą“øą“®ą“Øąµą“µą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“• -> ą“¬ąµą“°ąµ—ą“øąµ¼", + "syncToAccount": "ą“…ą“•ąµą“•ąµ—ą“£ąµą“Ÿąµ ą“øą“®ą“Øąµą“µą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“• <- ą“¬ąµą“°ąµ—ą“øąµ¼" + }, + "adminUserSettings": { + "title": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒ ą“Øą“æą“Æą“Øąµą“¤ąµą“°ą“£ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾", + "header": "ą“…ą“”ąµą“®ą“æąµ» ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒ ą“Øą“æą“Æą“Øąµą“¤ąµą“°ą“£ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾", + "admin": "ą“…ą“”ąµą“®ą“æąµ»", + "user": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µąµ", + "addUser": "ą“Ŗąµą“¤ą“æą“Æ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµ† ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "deleteUser": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµ† ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ąµą“•", + "confirmDeleteUser": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµ† ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ą“£ąµ‹?", + "confirmChangeUserStatus": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµ† ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“°ą“¹ą“æą“¤ą“®ą“¾ą“•ąµą“•ąµą“•ą“Æąµ‹/ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“•ąµą“·ą“®ą“®ą“¾ą“•ąµą“•ąµą“•ą“Æąµ‹ ą“šąµ†ą“Æąµą“Æą“£ąµ‹?", + "usernameInfo": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒą“Øą“¾ą“®ą“¤ąµą“¤ą“æąµ½ ą“…ą“•ąµą“·ą“°ą“™ąµą“™ąµ¾, ą“…ą“•ąµą“•ą“™ąµą“™ąµ¾, ą“¤ą“¾ą““ąµ† ą“Ŗą“±ą“Æąµą“Øąµą“Ø ą“Ŗąµą“°ą“¤ąµą“Æąµ‡ą“• ą“Ŗąµą“°ą“¤ąµ€ą“•ą“™ąµą“™ąµ¾ @._+- ą“Žą“Øąµą“Øą“æą“µ ą“®ą“¾ą“¤ąµą“°ą“®ąµ‡ ą“‰ą“£ąµą“Ÿą“¾ą“•ą“¾ą“µąµ‚ ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“øą“¾ą“§ąµą“µą“¾ą“Æ ą“’ą“°ąµ ą“‡ą“®ąµ†ą“Æą“æąµ½ ą“µą“æą“²ą“¾ą“øą“‚ ą“†ą“Æą“æą“°ą“æą“•ąµą“•ą“£ą“‚.", + "roles": "ą“±ąµ‹ą“³ąµą“•ąµ¾", + "role": "ą“±ąµ‹ąµ¾", + "actions": "ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“™ąµą“™ąµ¾", + "apiUser": "ą“Ŗą“°ą“æą“®ą“æą“¤ą“®ą“¾ą“Æ API ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µąµ", + "extraApiUser": "ą“…ą“§ą“æą“• ą“Ŗą“°ą“æą“®ą“æą“¤ą“®ą“¾ą“Æ API ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µąµ", + "webOnlyUser": "ą“µąµ†ą“¬ąµ ą“®ą“¾ą“¤ąµą“°ą“‚ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µąµ", + "demoUser": "ą“”ąµ†ą“®ąµ‹ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µąµ (ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ą“³ą“æą“²ąµą“²)", + "internalApiUser": "ą“†ą“Øąµą“¤ą“°ą“æą“• API ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µąµ", + "forceChange": "ą“²ąµ‹ą“—ą“æąµ» ą“šąµ†ą“Æąµą“Æąµą“®ąµą“Ŗąµ‹ąµ¾ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“®ą“¾ą“±ąµą“±ą“¾ąµ» ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµ† ą“Øą“æąµ¼ą“¬ą“Øąµą“§ą“æą“•ąµą“•ąµą“•", + "submit": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµ† ą“øą“‚ą“°ą“•ąµą“·ą“æą“•ąµą“•ąµą“•", + "changeUserRole": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µą“æą“Øąµą“±ąµ† ą“±ąµ‹ąµ¾ ą“®ą“¾ą“±ąµą“±ąµą“•", + "authenticated": "ą“øąµą“„ą“æą“°ąµ€ą“•ą“°ą“æą“šąµą“šąµ", + "editOwnProfil": "ą“øąµą“µą“Øąµą“¤ą“‚ ą“Ŗąµą“°ąµŠą“«ąµˆąµ½ ą“¤ą“æą“°ąµą“¤ąµą“¤ąµą“•", + "enabledUser": "ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“•ąµą“·ą“®ą“®ą“¾ą“•ąµą“•ą“æą“Æ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µąµ", + "disabledUser": "ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“°ą“¹ą“æą“¤ą“®ą“¾ą“•ąµą“•ą“æą“Æ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µąµ", + "activeUsers": "ą“øą“œąµ€ą“µ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“•ąµą“•ąµ¾:", + "disabledUsers": "ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“°ą“¹ą“æą“¤ą“®ą“¾ą“•ąµą“•ą“æą“Æ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“•ąµą“•ąµ¾:", + "totalUsers": "ą“†ą“•ąµ† ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“•ąµą“•ąµ¾:", + "lastRequest": "ą“…ą“µą“øą“¾ą“Ø ą“…ą“­ąµą“Æąµ¼ą“¤ąµą“„ą“Ø", + "usage": "ą“‰ą“Ŗą“Æąµ‹ą“—ą“‚ ą“•ą“¾ą“£ąµą“•" + }, + "endpointStatistics": { + "title": "ą“Žąµ»ą“”ąµā€Œą“Ŗąµ‹ą“Æą“æą“Øąµą“±ąµ ą“øąµą“„ą“æą“¤ą“æą“µą“æą“µą“°ą“•ąµą“•ą“£ą“•ąµą“•ąµą“•ąµ¾", + "header": "ą“Žąµ»ą“”ąµā€Œą“Ŗąµ‹ą“Æą“æą“Øąµą“±ąµ ą“øąµą“„ą“æą“¤ą“æą“µą“æą“µą“°ą“•ąµą“•ą“£ą“•ąµą“•ąµą“•ąµ¾", + "top10": "ą“®ą“æą“•ą“šąµą“š 10", + "top20": "ą“®ą“æą“•ą“šąµą“š 20", + "all": "ą“Žą“²ąµą“²ą“¾ą“‚", + "refresh": "ą“Ŗąµą“¤ąµą“•ąµą“•ąµą“•", + "includeHomepage": "ą“¹ąµ‹ą“‚ą“Ŗąµ‡ą“œąµ ą“‰ąµ¾ą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ąµą“• ('/')", + "includeLoginPage": "ą“²ąµ‹ą“—ą“æąµ» ą“Ŗąµ‡ą“œąµ ą“‰ąµ¾ą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ąµą“• ('/login')", + "totalEndpoints": "ą“†ą“•ąµ† ą“Žąµ»ą“”ąµā€Œą“Ŗąµ‹ą“Æą“æą“Øąµą“±ąµą“•ąµ¾", + "totalVisits": "ą“†ą“•ąµ† ą“øą“Øąµą“¦ąµ¼ą“¶ą“Øą“™ąµą“™ąµ¾", + "showing": "ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“Øąµą“Øąµ", + "selectedVisits": "ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“¤ąµą“¤ ą“øą“Øąµą“¦ąµ¼ą“¶ą“Øą“™ąµą“™ąµ¾", + "endpoint": "ą“Žąµ»ą“”ąµā€Œą“Ŗąµ‹ą“Æą“æą“Øąµą“±ąµ", + "visits": "ą“øą“Øąµą“¦ąµ¼ą“¶ą“Øą“™ąµą“™ąµ¾", + "percentage": "ą“¶ą“¤ą“®ą“¾ą“Øą“‚", + "loading": "ą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ...", + "failedToLoad": "ą“Žąµ»ą“”ąµā€Œą“Ŗąµ‹ą“Æą“æą“Øąµą“±ąµ ą“”ą“¾ą“±ąµą“± ą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øą“¤ą“æąµ½ ą“Ŗą“°ą“¾ą“œą“Æą“Ŗąµą“Ŗąµ†ą“Ÿąµą“Ÿąµ. ą“¦ą“Æą“µą“¾ą“Æą“æ ą“Ŗąµą“¤ąµą“•ąµą“•ą“¾ąµ» ą“¶ąµą“°ą“®ą“æą“•ąµą“•ąµą“•.", + "home": "ą“¹ąµ‹ą“‚", + "login": "ą“²ąµ‹ą“—ą“æąµ»", + "top": "ą“®ą“æą“•ą“šąµą“š", + "numberOfVisits": "ą“øą“Øąµą“¦ąµ¼ą“¶ą“Øą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Žą“£ąµą“£ą“‚", + "visitsTooltip": "ą“øą“Øąµą“¦ąµ¼ą“¶ą“Øą“™ąµą“™ąµ¾: {0} (ą“†ą“•ąµ†ą“Æąµą“³ąµą“³ą“¤ą“æą“Øąµą“±ąµ† {1}%)", + "retry": "ą“µąµ€ą“£ąµą“Ÿąµą“‚ ą“¶ąµą“°ą“®ą“æą“•ąµą“•ąµą“•" + }, + "database": { + "title": "ą“”ą“¾ą“±ąµą“±ą“¾ą“¬ąµ‡ą“øąµ ą“‡ą“±ą“•ąµą“•ąµą“®ą“¤ą“æ/ą“•ą“Æą“±ąµą“±ąµą“®ą“¤ą“æ", + "header": "ą“”ą“¾ą“±ąµą“±ą“¾ą“¬ąµ‡ą“øąµ ą“‡ą“±ą“•ąµą“•ąµą“®ą“¤ą“æ/ą“•ą“Æą“±ąµą“±ąµą“®ą“¤ą“æ", + "fileName": "ą“«ą“Æą“²ą“æą“Øąµą“±ąµ† ą“Ŗąµ‡ą“°ąµ", + "creationDate": "ą“øąµƒą“·ąµą“Ÿą“æą“šąµą“š ą“¤ąµ€ą“Æą“¤ą“æ", + "fileSize": "ą“«ą“Æąµ½ ą“µą“²ąµą“Ŗąµą“Ŗą“‚", + "deleteBackupFile": "ą“¬ą“¾ą“•ąµą“•ą“Ŗąµą“Ŗąµ ą“«ą“Æąµ½ ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ąµą“•", + "importBackupFile": "ą“¬ą“¾ą“•ąµą“•ą“Ŗąµą“Ŗąµ ą“«ą“Æąµ½ ą“‡ą“±ą“•ąµą“•ąµą“®ą“¤ą“æ ą“šąµ†ą“Æąµą“Æąµą“•", + "createBackupFile": "ą“¬ą“¾ą“•ąµą“•ą“Ŗąµą“Ŗąµ ą“«ą“Æąµ½ ą“øąµƒą“·ąµą“Ÿą“æą“•ąµą“•ąµą“•", + "downloadBackupFile": "ą“¬ą“¾ą“•ąµą“•ą“Ŗąµą“Ŗąµ ą“«ą“Æąµ½ ą“”ąµ—ąµŗą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "info_1": "ą“”ą“¾ą“±ąµą“± ą“‡ą“±ą“•ąµą“•ąµą“®ą“¤ą“æ ą“šąµ†ą“Æąµą“Æąµą“®ąµą“Ŗąµ‹ąµ¾, ą“¶ą“°ą“æą“Æą“¾ą“Æ ą“˜ą“Ÿą“Ø ą“‰ą“±ą“Ŗąµą“Ŗą“¾ą“•ąµą“•ąµ‡ą“£ąµą“Ÿą“¤ąµ ą“Ŗąµą“°ą“§ą“¾ą“Øą“®ą“¾ą“£ąµ. ą“Øą“æą“™ąµą“™ąµ¾ ą“Žą“Øąµą“¤ą“¾ą“£ąµ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øą“¤ąµ†ą“Øąµą“Øąµ ą“Øą“æą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“‰ą“±ą“Ŗąµą“Ŗą“æą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½, ą“’ą“°ąµ ą“Ŗąµą“°ąµŠą“«ą“·ą“£ą“²ą“æąµ½ ą“Øą“æą“Øąµą“Øąµ ą“‰ą“Ŗą“¦ąµ‡ą“¶ą“µąµą“‚ ą“Ŗą“æą“Øąµą“¤ąµą“£ą“Æąµą“‚ ą“¤ąµ‡ą“Ÿąµą“•. ą“˜ą“Ÿą“Øą“Æą“æą“²ąµ† ą“’ą“°ąµ ą“Ŗą“æą“¶ą“•ąµ ą“†ą“Ŗąµą“²ą“æą“•ąµą“•ąµ‡ą“·ąµ» ą“¤ą“•ą“°ą“¾ą“±ąµą“•ąµ¾ą“•ąµą“•ąµ ą“•ą“¾ą“°ą“£ą“®ą“¾ą“•ąµą“‚, ą“†ą“Ŗąµą“²ą“æą“•ąµą“•ąµ‡ą“·ąµ» ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ą“¾ąµ» ą“•ą““ą“æą“Æą“¾ą“¤ąµą“¤ ą“…ą“µą“øąµą“„ ą“µą“°ąµ†.", + "info_2": "ą“…ą“Ŗąµā€Œą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“®ąµą“Ŗąµ‹ąµ¾ ą“«ą“Æą“²ą“æą“Øąµą“±ąµ† ą“Ŗąµ‡ą“°ąµ ą“Ŗąµą“°ą“¶ąµą“Øą“®ą“²ąµą“². ą“øąµą“„ą“æą“°ą“®ą“¾ą“Æ ą“Øą“¾ą“®ą“•ą“°ą“£ ą“•ąµŗą“µąµ†ąµ»ą“·ąµ» ą“‰ą“±ą“Ŗąµą“Ŗą“¾ą“•ąµą“•ąµą“Øąµą“Øą“¤ą“æą“Øąµ, backup_user_yyyyMMddHHmm.sql ą“Žą“Øąµą“Ø ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ ą“Ŗą“æą“Øąµą“¤ąµą“Ÿą“°ą“¾ąµ» ą“‡ą“¤ąµ ą“Ŗą“æą“Øąµą“Øąµ€ą“Ÿąµ ą“Ŗąµą“Øąµ¼ą“Øą“¾ą“®ą“•ą“°ą“£ą“‚ ą“šąµ†ą“Æąµą“Æą“Ŗąµą“Ŗąµ†ą“Ÿąµą“‚.", + "submit": "ą“¬ą“¾ą“•ąµą“•ą“Ŗąµą“Ŗąµ ą“‡ą“±ą“•ąµą“•ąµą“®ą“¤ą“æ ą“šąµ†ą“Æąµą“Æąµą“•", + "importIntoDatabaseSuccessed": "ą“”ą“¾ą“±ąµą“±ą“¾ą“¬ąµ‡ą“øą“æą“²ąµ‡ą“•ąµą“•ąµą“³ąµą“³ ą“‡ą“±ą“•ąµą“•ąµą“®ą“¤ą“æ ą“µą“æą“œą“Æą“æą“šąµą“šąµ", + "backupCreated": "ą“”ą“¾ą“±ąµą“±ą“¾ą“¬ąµ‡ą“øąµ ą“¬ą“¾ą“•ąµą“•ą“Ŗąµą“Ŗąµ ą“µą“æą“œą“Æą“•ą“°ą“‚", + "fileNotFound": "ą“«ą“Æąµ½ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ą“æą“Æą“æą“²ąµą“²", + "fileNullOrEmpty": "ą“«ą“Æąµ½ ą“¶ąµ‚ą“Øąµą“Æą“®ą“¾ą“Æą“æą“°ą“æą“•ąµą“•ą“°ąµą“¤ąµ", + "failedImportFile": "ą“‡ą“±ą“•ąµą“•ąµą“®ą“¤ą“æ ą“«ą“Æąµ½ ą“Ŗą“°ą“¾ą“œą“Æą“Ŗąµą“Ŗąµ†ą“Ÿąµą“Ÿąµ", + "notSupported": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“”ą“¾ą“±ąµą“±ą“¾ą“¬ąµ‡ą“øąµ ą“•ą“£ą“•ąµą“·ą“Øą“¾ą“Æą“æ ą“ˆ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“²ą“­ąµą“Æą“®ą“²ąµą“²." + }, + "session": { + "expired": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“øąµ†ą“·ąµ» ą“•ą“¾ą“²ą“¹ą“°ą“£ą“Ŗąµą“Ŗąµ†ą“Ÿąµą“Ÿąµ. ą“¦ą“Æą“µą“¾ą“Æą“æ ą“Ŗąµ‡ą“œąµ ą“Ŗąµą“¤ąµą“•ąµą“•ą“æ ą“µąµ€ą“£ąµą“Ÿąµą“‚ ą“¶ąµą“°ą“®ą“æą“•ąµą“•ąµą“•.", + "refreshPage": "ą“Ŗąµ‡ą“œąµ ą“Ŗąµą“¤ąµą“•ąµą“•ąµą“•" + }, + "home": { + "desc": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Žą“²ąµą“²ą“¾ PDF ą“†ą“µą“¶ąµą“Æą“™ąµą“™ąµ¾ą“•ąµą“•ąµą“®ąµą“³ąµą“³ ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Ŗąµą“°ą“¾ą“¦ąµ‡ą“¶ą“æą“•ą“®ą“¾ą“Æą“æ ą“¹ąµ‹ą“øąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“¤ ą“ą“•ą“œą“¾ą“²ą“• ą“·ąµ‹ą“Ŗąµą“Ŗąµ.", + "searchBar": "ą“øą“µą“æą“¶ąµ‡ą“·ą“¤ą“•ąµ¾ą“•ąµą“•ą“¾ą“Æą“æ ą“¤ą“æą“°ą“Æąµą“•...", + "viewPdf": { + "title": "PDF ą“•ą“¾ą“£ąµą“•/ą“¤ą“æą“°ąµą“¤ąµą“¤ąµą“•", + "desc": "ą“•ą“¾ą“£ąµą“•, ą“µąµą“Æą“¾ą“–ąµą“Æą“¾ą“Øą“æą“•ąµą“•ąµą“•, ą“µą“°ą“Æąµą“•ąµą“•ąµą“•, ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“šą“æą“¤ąµą“°ą“™ąµą“™ąµ¾ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•" + }, + "setFavorites": "ą“Ŗąµą“°ą“æą“Æą“Ŗąµą“Ŗąµ†ą“Ÿąµą“Ÿą“µ ą“øą“œąµą“œą“®ą“¾ą“•ąµą“•ąµą“•", + "hideFavorites": "ą“Ŗąµą“°ą“æą“Æą“Ŗąµą“Ŗąµ†ą“Ÿąµą“Ÿą“µ ą“®ą“±ą“Æąµą“•ąµą“•ąµą“•", + "showFavorites": "ą“Ŗąµą“°ą“æą“Æą“Ŗąµą“Ŗąµ†ą“Ÿąµą“Ÿą“µ ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“•", + "legacyHomepage": "ą“Ŗą““ą“Æ ą“¹ąµ‹ą“‚ą“Ŗąµ‡ą“œąµ", + "newHomePage": "ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Ŗąµą“¤ą“æą“Æ ą“¹ąµ‹ą“‚ą“Ŗąµ‡ą“œąµ ą“Ŗą“°ąµ€ą“•ąµą“·ą“æą“•ąµą“•ąµą“•!", + "alphabetical": "ą“…ą“•ąµą“·ą“°ą“®ą“¾ą“²ą“¾ą“•ąµą“°ą“®ą“¤ąµą“¤ą“æąµ½", + "globalPopularity": "ą“†ą“—ąµ‹ą“³ ą“œą“Øą“Ŗąµą“°ąµ€ą“¤ą“æ", + "sortBy": "ą“‡ą“¤ą“Øąµą“øą“°ą“æą“šąµą“šąµ ą“…ą“Ÿąµą“•ąµą“•ąµą“•:", + "multiTool": { + "title": "PDF ą“®ąµ¾ą“Ÿąµą“Ÿą“æ ą“Ÿąµ‚ąµ¾", + "desc": "ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“²ą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•, ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“•, ą“Ŗąµą“Øą“ƒą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•, ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•, ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "merge": { + "title": "ą“²ą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•", + "desc": "ą“’ą“Øąµą“Øą“æą“²ą“§ą“æą“•ą“‚ PDF-ą“•ąµ¾ ą“Žą“³ąµą“Ŗąµą“Ŗą“¤ąµą“¤ą“æąµ½ ą“’ą“Øąµą“Øą“æą“²ąµ‡ą“•ąµą“•ąµ ą“²ą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•." + }, + "split": { + "title": "ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "desc": "PDF-ą“•ąµ¾ ą“’ą“Øąµą“Øą“æą“²ą“§ą“æą“•ą“‚ ą“Ŗąµą“°ą“®ą“¾ą“£ą“™ąµą“™ą“³ą“¾ą“Æą“æ ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•" + }, + "rotate": { + "title": "ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“•", + "desc": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† PDF-ą“•ąµ¾ ą“Žą“³ąµą“Ŗąµą“Ŗą“¤ąµą“¤ą“æąµ½ ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“•." + }, + "imageToPdf": { + "title": "ą“šą“æą“¤ąµą“°ą“‚ PDF-ą“²ąµ‡ą“•ąµą“•ąµ", + "desc": "ą“’ą“°ąµ ą“šą“æą“¤ąµą“°ą“‚ (PNG, JPEG, GIF) PDF-ą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•." + }, + "pdfToImage": { + "title": "PDF ą“šą“æą“¤ąµą“°ą“¤ąµą“¤ą“æą“²ąµ‡ą“•ąµą“•ąµ", + "desc": "ą“’ą“°ąµ PDF ą“šą“æą“¤ąµą“°ą“¤ąµą“¤ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "desc": "ą“ą“¤ąµ ą“•ąµą“°ą“®ą“¤ąµą“¤ą“æą“²ąµą“‚ ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•/ą“Ŗąµą“Øą“ƒą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•" + }, + "addImage": { + "title": "ą“šą“æą“¤ąµą“°ą“‚ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "desc": "PDF-ąµ½ ą“’ą“°ąµ ą“Øą“æą“¶ąµą“šą“æą“¤ ą“øąµą“„ą“¾ą“Øą“¤ąµą“¤ąµ ą“’ą“°ąµ ą“šą“æą“¤ąµą“°ą“‚ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“Øąµą“Øąµ" + }, + "watermark": { + "title": "ą“µą“¾ą“Ÿąµą“Ÿąµ¼ą“®ą“¾ąµ¼ą“•ąµą“•ąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "desc": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† PDF ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“’ą“°ąµ ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“µą“¾ą“Ÿąµą“Ÿąµ¼ą“®ą“¾ąµ¼ą“•ąµą“•ąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•." + }, + "permissions": { + "title": "ą“…ą“Øąµą“®ą“¤ą“æą“•ąµ¾ ą“®ą“¾ą“±ąµą“±ąµą“•", + "desc": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† PDF ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æą“Øąµą“±ąµ† ą“…ą“Øąµą“®ą“¤ą“æą“•ąµ¾ ą“®ą“¾ą“±ąµą“±ąµą“•" + }, + "removePages": { + "title": "ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† PDF ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æąµ½ ą“Øą“æą“Øąµą“Øąµ ą“†ą“µą“¶ąµą“Æą“®ą“æą“²ąµą“²ą“¾ą“¤ąµą“¤ ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ąµą“•." + }, + "addPassword": { + "title": "ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "desc": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† PDF ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ ą“’ą“°ąµ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµ ą“Žąµ»ą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“•." + }, + "removePassword": { + "title": "ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† PDF ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æąµ½ ą“Øą“æą“Øąµą“Øąµ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“øą“‚ą“°ą“•ąµą“·ą“£ą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•." + }, + "compressPdfs": { + "title": "ą“•ą“‚ą“Ŗąµą“°ą“øąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "ą“«ą“Æąµ½ ą“µą“²ąµą“Ŗąµą“Ŗą“‚ ą“•ąµą“±ą“Æąµą“•ąµą“•ąµą“Øąµą“Øą“¤ą“æą“Øąµ PDF-ą“•ąµ¾ ą“•ą“‚ą“Ŗąµą“°ą“øąµ ą“šąµ†ą“Æąµą“Æąµą“•." + }, + "unlockPDFForms": { + "title": "PDF ą“«ąµ‹ą“®ąµą“•ąµ¾ ą“…ąµŗą“²ąµ‹ą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "ą“’ą“°ąµ PDF ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æą“²ąµ† ą“«ąµ‹ą“‚ ą“«ąµ€ąµ½ą“”ąµą“•ą“³ąµą“Ÿąµ† ą“±ąµ€ą“”ąµ-ą“’ąµŗą“²ą“æ ą“Ŗąµą“°ąµ‹ą“Ŗąµą“Ŗąµ¼ą“Ÿąµą“Ÿą“æ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•." + }, + "changeMetadata": { + "title": "ą“®ąµ†ą“±ąµą“±ą“¾ą“”ą“¾ą“±ąµą“± ą“®ą“¾ą“±ąµą“±ąµą“•", + "desc": "ą“’ą“°ąµ PDF ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æąµ½ ą“Øą“æą“Øąµą“Øąµ ą“®ąµ†ą“±ąµą“±ą“¾ą“”ą“¾ą“±ąµą“± ą“®ą“¾ą“±ąµą“±ąµą“•/ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•/ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•" + }, + "fileToPDF": { + "title": "ą“«ą“Æąµ½ PDF-ą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•", + "desc": "ą“ą“•ą“¦ąµ‡ą“¶ą“‚ ą“ą“¤ąµ ą“«ą“Æą“²ąµą“‚ PDF-ą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“• (DOCX, PNG, XLS, PPT, TXT ą“Žą“Øąµą“Øą“æą“µą“Æąµą“‚ ą“…ą“¤ą“æąµ½ ą“•ąµ‚ą“Ÿąµą“¤ą“²ąµą“‚)" + }, + "ocr": { + "title": "OCR / ą“øąµą“•ą“¾ą“Øąµą“•ąµ¾ ą“µąµƒą“¤ąµą“¤ą“æą“Æą“¾ą“•ąµą“•ąµą“•", + "desc": "ą“øąµą“•ą“¾ą“Øąµą“•ąµ¾ ą“µąµƒą“¤ąµą“¤ą“æą“Æą“¾ą“•ąµą“•ąµą“•ą“Æąµą“‚ ą“’ą“°ąµ PDF-ą“Øąµą“³ąµą“³ą“æą“²ąµ† ą“šą“æą“¤ąµą“°ą“™ąµą“™ą“³ą“æąµ½ ą“Øą“æą“Øąµą“Øąµ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ąµą“•ą“Æąµą“‚ ą“…ą“¤ąµ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ą“¾ą“Æą“æ ą“µąµ€ą“£ąµą“Ÿąµą“‚ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•ą“Æąµą“‚ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ." + }, + "extractImages": { + "title": "ą“šą“æą“¤ąµą“°ą“™ąµą“™ąµ¾ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "desc": "ą“’ą“°ąµ PDF-ąµ½ ą“Øą“æą“Øąµą“Øąµ ą“Žą“²ąµą“²ą“¾ ą“šą“æą“¤ąµą“°ą“™ąµą“™ą“³ąµą“‚ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“¤ąµą“¤ąµ ą“øą“æą“Ŗąµą“Ŗą“æą“²ąµ‡ą“•ąµą“•ąµ ą“øą“‚ą“°ą“•ąµą“·ą“æą“•ąµą“•ąµą“Øąµą“Øąµ" + }, + "pdfToPDFA": { + "title": "PDF PDF/A-ą“²ąµ‡ą“•ąµą“•ąµ", + "desc": "ą“¦ąµ€ąµ¼ą“˜ą“•ą“¾ą“² ą“øą“‚ą“­ą“°ą“£ą“¤ąµą“¤ą“æą“Øą“¾ą“Æą“æ PDF PDF/A-ą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•" + }, + "PDFToWord": { + "title": "PDF ą“µąµ‡ą“”ą“æą“²ąµ‡ą“•ąµą“•ąµ", + "desc": "PDF ą“µąµ‡ą“”ąµ ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµą“•ą“³ą“æą“²ąµ‡ą“•ąµą“•ąµ (DOC, DOCX, ODT) ą“®ą“¾ą“±ąµą“±ąµą“•" + }, + "PDFToPresentation": { + "title": "PDF ą“Ŗąµą“°ą“øą“Øąµą“±ąµ‡ą“·ą“Øą“æą“²ąµ‡ą“•ąµą“•ąµ", + "desc": "PDF ą“Ŗąµą“°ą“øą“Øąµą“±ąµ‡ą“·ąµ» ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµą“•ą“³ą“æą“²ąµ‡ą“•ąµą“•ąµ (PPT, PPTX, ODP) ą“®ą“¾ą“±ąµą“±ąµą“•" + }, + "PDFToText": { + "title": "PDF RTF-ą“²ąµ‡ą“•ąµą“•ąµ (ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ)", + "desc": "PDF ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ RTF ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•" + }, + "PDFToHTML": { + "title": "PDF HTML-ą“²ąµ‡ą“•ąµą“•ąµ", + "desc": "PDF HTML ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•" + }, + "PDFToXML": { + "title": "PDF XML-ą“²ąµ‡ą“•ąµą“•ąµ", + "desc": "PDF XML ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•" + }, + "ScannerImageSplit": { + "title": "ą“øąµą“•ą“¾ąµ» ą“šąµ†ą“Æąµą“¤ ą“«ąµ‹ą“Ÿąµą“Ÿąµ‹ą“•ąµ¾ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ąµą“•/ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "desc": "ą“’ą“°ąµ ą“«ąµ‹ą“Ÿąµą“Ÿąµ‹/PDF-ą“Øąµą“³ąµą“³ą“æąµ½ ą“Øą“æą“Øąµą“Øąµ ą“’ą“Øąµą“Øą“æą“²ą“§ą“æą“•ą“‚ ą“«ąµ‹ą“Ÿąµą“Ÿąµ‹ą“•ąµ¾ ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“Øąµą“Øąµ" + }, + "sign": { + "title": "ą“’ą“Ŗąµą“Ŗą“æą“Ÿąµą“•", + "desc": "ą“µą“°ą“šąµą“šąµ‹, ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµ‹, ą“šą“æą“¤ąµą“°ą“‚ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµ‹ PDF-ąµ½ ą“’ą“Ŗąµą“Ŗąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“Øąµą“Øąµ" + }, + "flatten": { + "title": "ą“Ŗą“°ą“¤ąµą“¤ąµą“•", + "desc": "ą“’ą“°ąµ PDF-ąµ½ ą“Øą“æą“Øąµą“Øąµ ą“Žą“²ąµą“²ą“¾ ą“‡ą“Øąµą“±ą“±ą“¾ą“•ąµą“Ÿąµ€ą“µąµ ą“˜ą“Ÿą“•ą“™ąµą“™ą“³ąµą“‚ ą“«ąµ‹ą“®ąµą“•ą“³ąµą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "repair": { + "title": "ą“Øą“Øąµą“Øą“¾ą“•ąµą“•ąµą“•", + "desc": "ą“•ąµ‡ą“Ÿą“¾ą“Æ/ą“¤ą“•ąµ¼ą“Øąµą“Ø PDF ą“Øą“Øąµą“Øą“¾ą“•ąµą“•ą“¾ąµ» ą“¶ąµą“°ą“®ą“æą“•ąµą“•ąµą“Øąµą“Øąµ" + }, + "removeBlanks": { + "title": "ą“¶ąµ‚ą“Øąµą“Æą“®ą“¾ą“Æ ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "ą“’ą“°ąµ ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æąµ½ ą“Øą“æą“Øąµą“Øąµ ą“¶ąµ‚ą“Øąµą“Æą“®ą“¾ą“Æ ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ąµą“•ą“Æąµą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•ą“Æąµą“‚ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ" + }, + "removeAnnotations": { + "title": "ą“µąµą“Æą“¾ą“–ąµą“Æą“¾ą“Øą“™ąµą“™ąµ¾ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "ą“’ą“°ąµ PDF-ąµ½ ą“Øą“æą“Øąµą“Øąµ ą“Žą“²ąµą“²ą“¾ ą“…ą“­ą“æą“Ŗąµą“°ą“¾ą“Æą“™ąµą“™ą“³ąµą“‚/ą“µąµą“Æą“¾ą“–ąµą“Æą“¾ą“Øą“™ąµą“™ą“³ąµą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ" + }, + "compare": { + "title": "ą“¤ą“¾ą“°ą“¤ą“®ąµą“Æą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "2 PDF ą“Ŗąµą“°ą“®ą“¾ą“£ą“™ąµą“™ąµ¾ ą“¤ą“®ąµą“®ą“æą“²ąµą“³ąµą“³ ą“µąµą“Æą“¤ąµą“Æą“¾ą“øą“™ąµą“™ąµ¾ ą“¤ą“¾ą“°ą“¤ą“®ąµą“Æą“‚ ą“šąµ†ą“Æąµą“Æąµą“•ą“Æąµą“‚ ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“•ą“Æąµą“‚ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ" + }, + "certSign": { + "title": "ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµ ą“’ą“Ŗąµą“Ŗą“æą“Ÿąµą“•", + "desc": "ą“’ą“°ąµ ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ/ą“•ąµ€ (PEM/P12) ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµ ą“’ą“°ąµ PDF ą“’ą“Ŗąµą“Ŗą“æą“Ÿąµą“Øąµą“Øąµ" + }, + "removeCertSign": { + "title": "ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“’ą“Ŗąµą“Ŗąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "PDF-ąµ½ ą“Øą“æą“Øąµą“Øąµ ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“’ą“Ŗąµą“Ŗąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "pageLayout": { + "title": "ą“®ąµ¾ą“Ÿąµą“Ÿą“æ-ą“Ŗąµ‡ą“œąµ ą“²ąµ‡ą“”ą“Ÿąµą“Ÿąµ", + "desc": "ą“’ą“°ąµ PDF ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æą“Øąµą“±ąµ† ą“’ą“Øąµą“Øą“æą“²ą“§ą“æą“•ą“‚ ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“’ą“°ąµŠą“±ąµą“± ą“Ŗąµ‡ą“œą“æą“²ąµ‡ą“•ąµą“•ąµ ą“²ą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•" + }, + "scalePages": { + "title": "ą“Ŗąµ‡ą“œąµ ą“µą“²ąµą“Ŗąµą“Ŗą“‚/ą“øąµą“•ąµ†ą“Æą“æąµ½ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "desc": "ą“’ą“°ąµ ą“Ŗąµ‡ą“œą“æą“Øąµą“±ąµ†ą“Æąµą“‚/ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“…ą“¤ą“æą“Øąµą“±ąµ† ą“‰ą“³ąµą“³ą“Ÿą“•ąµą“•ą“™ąµą“™ą“³ąµą“Ÿąµ†ą“Æąµą“‚ ą“µą“²ąµą“Ŗąµą“Ŗą“‚/ą“øąµą“•ąµ†ą“Æą“æąµ½ ą“®ą“¾ą“±ąµą“±ąµą“•." + }, + "pipeline": { + "title": "ą“Ŗąµˆą“Ŗąµą“Ŗąµą“²ąµˆąµ»", + "desc": "ą“Ŗąµˆą“Ŗąµą“Ŗąµą“²ąµˆąµ» ą“øąµą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµą“•ąµ¾ ą“Øą“æąµ¼ą“µą“šą“æą“šąµą“šąµą“•ąµŠą“£ąµą“Ÿąµ PDF-ą“•ą“³ą“æąµ½ ą“’ą“Øąµą“Øą“æą“²ą“§ą“æą“•ą“‚ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“™ąµą“™ąµ¾ ą“Øą“Ÿą“¤ąµą“¤ąµą“•" + }, + "add-page-numbers": { + "title": "ą“Ŗąµ‡ą“œąµ ą“Øą“®ąµą“Ŗą“±ąµą“•ąµ¾ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "desc": "ą“’ą“°ąµ ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æą“²ąµą“Ÿą“Øąµ€ą“³ą“‚ ą“’ą“°ąµ ą“Øą“æą“¶ąµą“šą“æą“¤ ą“øąµą“„ą“¾ą“Øą“¤ąµą“¤ąµ ą“Ŗąµ‡ą“œąµ ą“Øą“®ąµą“Ŗą“±ąµą“•ąµ¾ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•" + }, + "auto-rename": { + "title": "PDF ą“«ą“Æąµ½ ą“øąµą“µą“Æą“‚ ą“Ŗąµą“Øąµ¼ą“Øą“¾ą“®ą“•ą“°ą“£ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ą“æą“Æ ą“¤ą“²ą“•ąµą“•ąµ†ą“Ÿąµą“Ÿą“æą“Øąµ† ą“…ą“Ÿą“æą“øąµą“„ą“¾ą“Øą“®ą“¾ą“•ąµą“•ą“æ ą“’ą“°ąµ PDF ą“«ą“Æąµ½ ą“øąµą“µą“Æą“‚ ą“Ŗąµą“Øąµ¼ą“Øą“¾ą“®ą“•ą“°ą“£ą“‚ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ" + }, + "adjust-contrast": { + "title": "ą“Øą“æą“±ą“™ąµą“™ąµ¾/ą“•ąµ‹ąµŗą“Ÿąµą“°ą“¾ą“øąµą“±ąµą“±ąµ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "desc": "ą“’ą“°ąµ PDF-ą“Øąµą“±ąµ† ą“•ąµ‹ąµŗą“Ÿąµą“°ą“¾ą“øąµą“±ąµą“±ąµ, ą“øą“¾ą“šąµą“šąµą“±ąµ‡ą“·ąµ», ą“¤ąµ†ą“³ą“æą“šąµą“šą“‚ ą“Žą“Øąµą“Øą“æą“µ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•" + }, + "crop": { + "title": "PDF ą“•ąµą“°ąµ‹ą“Ŗąµą“Ŗąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "ą“µą“²ąµą“Ŗąµą“Ŗą“‚ ą“•ąµą“±ą“Æąµą“•ąµą“•ą“¾ąµ» ą“’ą“°ąµ PDF ą“•ąµą“°ąµ‹ą“Ŗąµą“Ŗąµ ą“šąµ†ą“Æąµą“Æąµą“• (ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“Øą“æą“²ą“Øą“æąµ¼ą“¤ąµą“¤ąµą“Øąµą“Øąµ!)" + }, + "autoSplitPDF": { + "title": "ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“øąµą“µą“Æą“‚ ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "desc": "ą“­ąµ—ą“¤ą“æą“•ą“®ą“¾ą“Æą“æ ą“øąµą“•ą“¾ąµ» ą“šąµ†ą“Æąµą“¤ ą“Ŗąµ‡ą“œąµ ą“øąµą“Ŗąµą“²ą“æą“±ąµą“±ąµ¼ QR ą“•ąµ‹ą“”ąµ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµ ą“øąµą“•ą“¾ąµ» ą“šąµ†ą“Æąµą“¤ PDF ą“øąµą“µą“Æą“‚ ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•" + }, + "sanitizePdf": { + "title": "ą“¶ąµą“¦ąµą“§ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "desc": "PDF ą“«ą“Æą“²ąµą“•ą“³ą“æąµ½ ą“Øą“æą“Øąµą“Øąµ ą“øąµą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµą“•ą“³ąµą“‚ ą“®ą“±ąµą“±ąµ ą“˜ą“Ÿą“•ą“™ąµą“™ą“³ąµą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "URLToPDF": { + "title": "URL/ą“µąµ†ą“¬ąµą“øąµˆą“±ąµą“±ąµ PDF-ą“²ąµ‡ą“•ąµą“•ąµ", + "desc": "ą“ą“¤ąµ http(s)URL-ą“Øąµ†ą“Æąµą“‚ PDF-ą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“Øąµą“Øąµ" + }, + "HTMLToPDF": { + "title": "HTML PDF-ą“²ąµ‡ą“•ąµą“•ąµ", + "desc": "ą“ą“¤ąµ HTML ą“«ą“Æą“²ą“æą“Øąµ†ą“Æąµą“‚ ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“øą“æą“Ŗąµą“Ŗą“æą“Øąµ†ą“Æąµą“‚ PDF-ą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“Øąµą“Øąµ" + }, + "MarkdownToPDF": { + "title": "ą“®ą“¾ąµ¼ą“•ąµą“•ąµą“”ąµ—ąµŗ PDF-ą“²ąµ‡ą“•ąµą“•ąµ", + "desc": "ą“ą“¤ąµ ą“®ą“¾ąµ¼ą“•ąµą“•ąµą“”ąµ—ąµŗ ą“«ą“Æą“²ą“æą“Øąµ†ą“Æąµą“‚ PDF-ą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“Øąµą“Øąµ" + }, + "PDFToMarkdown": { + "title": "PDF ą“®ą“¾ąµ¼ą“•ąµą“•ąµą“”ąµ—ą“£ą“æą“²ąµ‡ą“•ąµą“•ąµ", + "desc": "ą“ą“¤ąµ PDF-ą“Øąµ†ą“Æąµą“‚ ą“®ą“¾ąµ¼ą“•ąµą“•ąµą“”ąµ—ą“£ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“Øąµą“Øąµ" + }, + "getPdfInfo": { + "title": "PDF-ą“Øąµ†ą“•ąµą“•ąµą“±ą“æą“šąµą“šąµą“³ąµą“³ ą“Žą“²ąµą“²ą“¾ ą“µą“æą“µą“°ą“™ąµą“™ą“³ąµą“‚ ą“Øąµ‡ą“Ÿąµą“•", + "desc": "PDF-ą“•ą“³ąµ†ą“•ąµą“•ąµą“±ą“æą“šąµą“šąµą“³ąµą“³ ą“øą“¾ą“§ąµą“Æą“®ą“¾ą“Æ ą“Žą“²ąµą“²ą“¾ ą“µą“æą“µą“°ą“™ąµą“™ą“³ąµą“‚ ą“Øąµ‡ą“Ÿąµą“Øąµą“Øąµ" + }, + "extractPage": { + "title": "ą“Ŗąµ‡ą“œąµ(ą“•ąµ¾) ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "desc": "PDF-ąµ½ ą“Øą“æą“Øąµą“Øąµ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“¤ąµą“¤ ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“Øąµą“Øąµ" + }, + "PdfToSinglePage": { + "title": "ą“’ą“°ąµŠą“±ąµą“± ą“µą“²ą“æą“Æ ą“Ŗąµ‡ą“œąµ", + "desc": "ą“Žą“²ąµą“²ą“¾ PDF ą“Ŗąµ‡ą“œąµą“•ą“³ąµą“‚ ą“’ą“°ąµŠą“±ąµą“± ą“µą“²ą“æą“Æ ą“Ŗąµ‡ą“œą“æą“²ąµ‡ą“•ąµą“•ąµ ą“²ą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“Øąµą“Øąµ" + }, + "showJS": { + "title": "ą“œą“¾ą“µą“¾ą“øąµą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“•", + "desc": "ą“’ą“°ąµ PDF-ąµ½ ą“•ąµą“¤ąµą“¤ą“æą“µą“šąµą“š ą“ą“¤ąµ†ą“™ąµą“•ą“æą“²ąµą“‚ JS ą“¤ą“æą“°ą“Æąµą“•ą“Æąµą“‚ ą“Ŗąµą“°ą“¦ąµ¼ą“¶ą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•ą“Æąµą“‚ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ" + }, + "autoRedact": { + "title": "ą“øąµą“µą“Æą“‚ ą“±ąµ†ą“”ą“¾ą“•ąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "ą“‡ąµ»ą“Ŗąµą“Ÿąµą“Ÿąµ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ą“æą“Øąµ† ą“…ą“Ÿą“æą“øąµą“„ą“¾ą“Øą“®ą“¾ą“•ąµą“•ą“æ ą“’ą“°ąµ PDF-ą“²ąµ† ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“øąµą“µą“Æą“‚ ą“±ąµ†ą“”ą“¾ą“•ąµą“±ąµą“±ąµ (ą“•ą“±ąµą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“Øąµą“Øąµ) ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ" + }, + "redact": { + "title": "ą“øąµą“µą“Æą“‚ ą“±ąµ†ą“”ą“¾ą“•ąµą“·ąµ»", + "desc": "ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“¤ąµą“¤ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ, ą“µą“°ą“šąµą“š ą“°ąµ‚ą“Ŗą“™ąµą“™ąµ¾ ą“•ąµ‚ą“Ÿą“¾ą“¤ąµ†/ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“¤ąµą“¤ ą“Ŗąµ‡ą“œąµ(ą“•ąµ¾) ą“…ą“Ÿą“æą“øąµą“„ą“¾ą“Øą“®ą“¾ą“•ąµą“•ą“æ ą“’ą“°ąµ PDF ą“±ąµ†ą“”ą“¾ą“•ąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ" + }, + "tableExtraxt": { + "title": "PDF CSV-ą“²ąµ‡ą“•ąµą“•ąµ", + "desc": "ą“’ą“°ąµ PDF-ąµ½ ą“Øą“æą“Øąµą“Øąµ ą“Ŗą“Ÿąµą“Ÿą“æą“•ą“•ąµ¾ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“¤ąµą“¤ąµ CSV-ą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“Øąµą“Øąµ" + }, + "autoSizeSplitPDF": { + "title": "ą“µą“²ąµą“Ŗąµą“Ŗą“‚/ą“Žą“£ąµą“£ą“‚ ą“…ą“Øąµą“øą“°ą“æą“šąµą“šąµ ą“øąµą“µą“Æą“‚ ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "desc": "ą“µą“²ąµą“Ŗąµą“Ŗą“‚, ą“Ŗąµ‡ą“œąµ ą“Žą“£ąµą“£ą“‚, ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“Ŗąµą“°ą“®ą“¾ą“£ą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Žą“£ąµą“£ą“‚ ą“Žą“Øąµą“Øą“æą“µ ą“…ą“Ÿą“æą“øąµą“„ą“¾ą“Øą“®ą“¾ą“•ąµą“•ą“æ ą“’ą“°ąµŠą“±ąµą“± PDF ą“’ą“Øąµą“Øą“æą“²ą“§ą“æą“•ą“‚ ą“Ŗąµą“°ą“®ą“¾ą“£ą“™ąµą“™ą“³ą“¾ą“Æą“æ ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•" + }, + "overlay-pdfs": { + "title": "PDF-ą“•ąµ¾ ą““ą“µąµ¼ą“²ąµ‡ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "ą“®ą“±ąµą“±ąµŠą“°ąµ PDF-ą“Øąµ ą“®ąµą“•ą“³ą“æąµ½ PDF-ą“•ąµ¾ ą““ą“µąµ¼ą“²ąµ‡ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ" + }, + "split-by-sections": { + "title": "ą“µą“æą“­ą“¾ą“—ą“™ąµą“™ąµ¾ ą“…ą“Øąµą“øą“°ą“æą“šąµą“šąµ PDF ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "desc": "ą“’ą“°ąµ PDF-ą“Øąµą“±ąµ† ą““ą“°ąµ‹ ą“Ŗąµ‡ą“œąµą“‚ ą“šąµ†ą“±ą“æą“Æ ą“¤ą“æą“°ą“¶ąµą“šąµ€ą“Øą“µąµą“‚ ą“²ą“‚ą“¬ą“µąµą“®ą“¾ą“Æ ą“µą“æą“­ą“¾ą“—ą“™ąµą“™ą“³ą“¾ą“Æą“æ ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•" + }, + "AddStampRequest": { + "title": "PDF-ąµ½ ą“øąµą“±ąµą“±ą“¾ą“®ąµą“Ŗąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "desc": "ą“Øą“æą“¶ąµą“šą“æą“¤ ą“øąµą“„ą“¾ą“Øą“™ąµą“™ą“³ą“æąµ½ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“‡ą“®ąµ‡ą“œąµ ą“øąµą“±ąµą“±ą“¾ą“®ąµą“Ŗąµą“•ąµ¾ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•" + }, + "removeImagePdf": { + "title": "ą“šą“æą“¤ąµą“°ą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "ą“«ą“Æąµ½ ą“µą“²ąµą“Ŗąµą“Ŗą“‚ ą“•ąµą“±ą“Æąµą“•ąµą“•ą“¾ąµ» PDF-ąµ½ ą“Øą“æą“Øąµą“Øąµ ą“šą“æą“¤ąµą“°ą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "splitPdfByChapters": { + "title": "ą“…ą“§ąµą“Æą“¾ą“Æą“™ąµą“™ąµ¾ ą“…ą“Øąµą“øą“°ą“æą“šąµą“šąµ PDF ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "desc": "ą“…ą“¤ą“æą“Øąµą“±ąµ† ą“…ą“§ąµą“Æą“¾ą“Æ ą“˜ą“Ÿą“Øą“Æąµ† ą“…ą“Ÿą“æą“øąµą“„ą“¾ą“Øą“®ą“¾ą“•ąµą“•ą“æ ą“’ą“°ąµ PDF ą“’ą“Øąµą“Øą“æą“²ą“§ą“æą“•ą“‚ ą“«ą“Æą“²ąµą“•ą“³ą“¾ą“Æą“æ ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•." + }, + "validateSignature": { + "title": "PDF ą“’ą“Ŗąµą“Ŗąµ ą“øą“¾ą“§ąµ‚ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "desc": "PDF ą“Ŗąµą“°ą“®ą“¾ą“£ą“™ąµą“™ą“³ą“æą“²ąµ† ą“”ą“æą“œą“æą“±ąµą“±ąµ½ ą“’ą“Ŗąµą“Ŗąµą“•ą“³ąµą“‚ ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµą“•ą“³ąµą“‚ ą“Ŗą“°ą“æą“¶ąµ‹ą“§ą“æą“•ąµą“•ąµą“•" + }, + "replaceColorPdf": { + "title": "ą“Øą“æą“±ą“‚ ą“®ą“¾ą“±ąµą“±ąµą“•ą“Æąµą“‚ ą“µą“æą“Ŗą“°ąµ€ą“¤ą“®ą“¾ą“•ąµą“•ąµą“•ą“Æąµą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "desc": "PDF-ą“²ąµ† ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ą“æą“Øąµą“‚ ą“Ŗą“¶ąµą“šą“¾ą“¤ąµą“¤ą“²ą“¤ąµą“¤ą“æą“Øąµą“‚ ą“Øą“æą“±ą“‚ ą“®ą“¾ą“±ąµą“±ąµą“•ą“Æąµą“‚ ą“«ą“Æąµ½ ą“µą“²ąµą“Ŗąµą“Ŗą“‚ ą“•ąµą“±ą“Æąµą“•ąµą“•ąµą“Øąµą“Øą“¤ą“æą“Øąµ PDF-ą“Øąµą“±ąµ† ą“®ąµą““ąµą“µąµ» ą“Øą“æą“±ą“µąµą“‚ ą“µą“æą“Ŗą“°ąµ€ą“¤ą“®ą“¾ą“•ąµą“•ąµą“•ą“Æąµą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + } + }, + "viewPdf": { + "tags": "ą“•ą“¾ą“£ąµą“•,ą“µą“¾ą“Æą“æą“•ąµą“•ąµą“•,ą“µąµą“Æą“¾ą“–ąµą“Æą“¾ą“Øą“æą“•ąµą“•ąµą“•,ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ,ą“šą“æą“¤ąµą“°ą“‚,ą“¹ąµˆą“²ąµˆą“±ąµą“±ąµ,ą“¤ą“æą“°ąµą“¤ąµą“¤ąµą“•", + "title": "PDF ą“•ą“¾ą“£ąµą“•/ą“¤ą“æą“°ąµą“¤ąµą“¤ąµą“•", + "header": "PDF ą“•ą“¾ą“£ąµą“•" + }, + "multiTool": { + "tags": "ą“®ąµ¾ą“Ÿąµą“Ÿą“æ ą“Ÿąµ‚ąµ¾,ą“®ąµ¾ą“Ÿąµą“Ÿą“æ ą““ą“Ŗąµą“Ŗą“±ąµ‡ą“·ąµ»,ą“Æąµą“,ą“•ąµą“²ą“æą“•ąµą“•ąµ ą“”ąµą“°ą“¾ą“—ąµ,ą“«ąµą“°ą“£ąµą“Ÿąµ ą“Žąµ»ą“”ąµ,ą“•ąµą“²ą“Æą“æą“Øąµą“±ąµ ą“øąµˆą“”ąµ,ą“‡ą“Øąµą“±ą“±ą“¾ą“•ąµą“Ÿąµ€ą“µąµ,ą“…ą“Øą“™ąµą“™ą“¾ą“¤ąµą“¤,ą“Øąµ€ą“•ąµą“•ąµą“•,ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ąµą“•,ą“•ąµˆą“®ą“¾ą“±ąµą“•,ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "title": "PDF ą“®ąµ¾ą“Ÿąµą“Ÿą“æ ą“Ÿąµ‚ąµ¾", + "header": "PDF ą“®ąµ¾ą“Ÿąµą“Ÿą“æ ą“Ÿąµ‚ąµ¾", + "uploadPrompts": "ą“«ą“Æą“²ą“æą“Øąµą“±ąµ† ą“Ŗąµ‡ą“°ąµ", + "selectAll": "ą“Žą“²ąµą“²ą“¾ą“‚ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "deselectAll": "ą“Žą“²ąµą“²ą“¾ą“‚ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ą“¾ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“•", + "selectPages": "ą“Ŗąµ‡ą“œąµ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "selectedPages": "ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“¤ąµą“¤ ą“Ŗąµ‡ą“œąµą“•ąµ¾", + "page": "ą“Ŗąµ‡ą“œąµ", + "deleteSelected": "ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“¤ąµą“¤ą“µ ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ąµą“•", + "downloadAll": "ą“•ą“Æą“±ąµą“±ąµą“®ą“¤ą“æ ą“šąµ†ą“Æąµą“Æąµą“•", + "downloadSelected": "ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“¤ąµą“¤ą“µ ą“•ą“Æą“±ąµą“±ąµą“®ą“¤ą“æ ą“šąµ†ą“Æąµą“Æąµą“•", + "insertPageBreak": "ą“Ŗąµ‡ą“œąµ ą“¬ąµą“°ąµ‡ą“•ąµą“•ąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "addFile": "ą“«ą“Æąµ½ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "rotateLeft": "ą“‡ą“Ÿą“¤ąµą“¤ąµ‡ą“•ąµą“•ąµ ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“•", + "rotateRight": "ą“µą“²ą“¤ąµą“¤ąµ‡ą“•ąµą“•ąµ ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“•", + "split": "ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "moveLeft": "ą“‡ą“Ÿą“¤ąµą“¤ąµ‡ą“•ąµą“•ąµ ą“Øąµ€ą“•ąµą“•ąµą“•", + "moveRight": "ą“µą“²ą“¤ąµą“¤ąµ‡ą“•ąµą“•ąµ ą“Øąµ€ą“•ąµą“•ąµą“•", + "delete": "ą“®ą“¾ą“Æąµą“•ąµą“•ąµą“•", + "dragDropMessage": "ą“Ŗąµ‡ą“œąµ(ą“•ąµ¾) ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“¤ąµą“¤ąµ", + "undo": "ą“Ŗą““ą“Æą“Ŗą“Ÿą“æ ą“†ą“•ąµą“•ąµą“•", + "redo": "ą“µąµ€ą“£ąµą“Ÿąµą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "merge": { + "tags": "ą“²ą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•,ą“Ŗąµ‡ą“œąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“™ąµą“™ąµ¾,ą“¬ą“¾ą“•ąµą“•ąµ ą“Žąµ»ą“”ąµ,ą“øąµ†ąµ¼ą“µąµ¼ ą“øąµˆą“”ąµ", + "title": "ą“²ą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•", + "header": "ą“’ą“Øąµą“Øą“æą“²ą“§ą“æą“•ą“‚ PDF-ą“•ąµ¾ ą“²ą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“• (2+)", + "sortByName": "ą“Ŗąµ‡ą“°ąµ ą“…ą“Øąµą“øą“°ą“æą“šąµą“šąµ ą“…ą“Ÿąµą“•ąµą“•ąµą“•", + "sortByDate": "ą“¤ąµ€ą“Æą“¤ą“æ ą“…ą“Øąµą“øą“°ą“æą“šąµą“šąµ ą“…ą“Ÿąµą“•ąµą“•ąµą“•", + "removeCertSign": "ą“²ą“Æą“æą“Ŗąµą“Ŗą“æą“šąµą“š ą“«ą“Æą“²ą“æą“²ąµ† ą“”ą“æą“œą“æą“±ąµą“±ąµ½ ą“’ą“Ŗąµą“Ŗąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æą“£ąµ‹?", + "submit": "ą“²ą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•" + }, + "split": { + "tags": "ą“Ŗąµ‡ą“œąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“™ąµą“™ąµ¾,ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•,ą“®ąµ¾ą“Ÿąµą“Ÿą“æ ą“Ŗąµ‡ą“œąµ,ą“®ąµą“±ą“æą“•ąµą“•ąµą“•,ą“øąµ†ąµ¼ą“µąµ¼ ą“øąµˆą“”ąµ", + "title": "PDF ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "header": "PDF ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "desc": { + "1": "ą“Øą“æą“™ąµą“™ąµ¾ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“Øąµą“Ø ą“Øą“®ąµą“Ŗą“±ąµą“•ąµ¾ ą“µą“æą“­ą“œą“æą“•ąµą“•ą“¾ąµ» ą“†ą“—ąµą“°ą“¹ą“æą“•ąµą“•ąµą“Øąµą“Ø ą“Ŗąµ‡ą“œąµ ą“Øą“®ąµą“Ŗą“±ą“¾ą“£ąµ", + "2": "ą“…ą“¤ąµą“Ŗąµ‹ą“²ąµ† 1,3,7-9 ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ 10 ą“Ŗąµ‡ą“œąµą“³ąµą“³ ą“’ą“°ąµ ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ąµ† 6 ą“µąµą“Æą“¤ąµą“Æą“øąµą“¤ PDF-ą“•ą“³ą“¾ą“Æą“æ ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“‚:", + "3": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ #1: ą“Ŗąµ‡ą“œąµ 1", + "4": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ #2: ą“Ŗąµ‡ą“œąµ 2, 3", + "5": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ #3: ą“Ŗąµ‡ą“œąµ 4, 5, 6, 7", + "6": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ #4: ą“Ŗąµ‡ą“œąµ 8", + "7": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ #5: ą“Ŗąµ‡ą“œąµ 9", + "8": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ #6: ą“Ŗąµ‡ą“œąµ 10" + }, + "splitPages": "ą“µą“æą“­ą“œą“æą“•ąµą“•ąµ‡ą“£ąµą“Ÿ ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“Øąµ½ą“•ąµą“•:", + "submit": "ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•" + }, + "rotate": { + "tags": "ą“øąµ†ąµ¼ą“µąµ¼ ą“øąµˆą“”ąµ", + "title": "PDF ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“•", + "header": "PDF ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“•", + "selectAngle": "ą“¤ą“æą“°ą“æą“•ąµą“•ąµ‡ą“£ąµą“Ÿ ą“•ąµ‹ąµŗ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“• (90 ą“”ą“æą“—ąµą“°ą“æą“Æąµą“Ÿąµ† ą“—ąµą“£ą“æą“¤ą“™ąµą“™ą“³ą“æąµ½):", + "submit": "ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“•" + }, + "imageToPdf": { + "tags": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚,img,jpg,ą“šą“æą“¤ąµą“°ą“‚,ą“«ąµ‹ą“Ÿąµą“Ÿąµ‹" + }, + "pdfToImage": { + "tags": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚,img,jpg,ą“šą“æą“¤ąµą“°ą“‚,ą“«ąµ‹ą“Ÿąµą“Ÿąµ‹", + "title": "PDF ą“šą“æą“¤ąµą“°ą“¤ąµą“¤ą“æą“²ąµ‡ą“•ąµą“•ąµ", + "header": "PDF ą“šą“æą“¤ąµą“°ą“¤ąµą“¤ą“æą“²ąµ‡ą“•ąµą“•ąµ", + "selectText": "ą“šą“æą“¤ąµą“° ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ", + "singleOrMultiple": "ą“šą“æą“¤ąµą“° ą“«ą“² ą“¤ą“°ą“‚", + "single": "ą“’ą“°ąµŠą“±ąµą“± ą“µą“²ą“æą“Æ ą“šą“æą“¤ąµą“°ą“‚", + "multi": "ą“’ą“Øąµą“Øą“æą“²ą“§ą“æą“•ą“‚ ą“šą“æą“¤ąµą“°ą“™ąµą“™ąµ¾", + "colorType": "ą“Øą“æą“± ą“¤ą“°ą“‚", + "color": "ą“Øą“æą“±ą“‚", + "grey": "ą“—ąµą“°ąµ‡ą“øąµā€Œą“•ąµ†ą“Æą“æąµ½", + "blackwhite": "ą“•ą“±ąµą“Ŗąµą“Ŗąµą“‚ ą“µąµ†ą“³ąµą“Ŗąµą“Ŗąµą“‚ (ą“”ą“¾ą“±ąµą“± ą“Øą“·ąµą“Ÿą“Ŗąµą“Ŗąµ†ą“Ÿąµą“Ÿąµ‡ą“•ąµą“•ą“¾ą“‚!)", + "submit": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "info": "ą“Ŗąµˆą“¤ąµą“¤ąµŗ ą“‡ąµ»ą“øąµą“±ąµą“±ą“¾ąµ¾ ą“šąµ†ą“Æąµą“¤ą“æą“Ÿąµą“Ÿą“æą“²ąµą“². WebP ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“¤ąµą“¤ą“æą“Øąµ ą“†ą“µą“¶ąµą“Æą“®ą“¾ą“£ąµ.", + "placeholder": "(ą“‰ą“¦ą“¾. 1,2,8 ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ 4,7,12-16 ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ 2n-1)" + }, + "pdfOrganiser": { + "tags": "ą“”ąµą“Æąµ‚ą“Ŗąµą“²ąµ†ą“•ąµą“øąµ,ą“‡ą“°ą“Ÿąµą“Ÿ,ą“’ą“±ąµą“±,ą“…ą“Ÿąµą“•ąµą“•ąµą“•,ą“Øąµ€ą“•ąµą“•ąµą“•", + "title": "ą“Ŗąµ‡ą“œąµ ą““ąµ¼ą“—ą“Øąµˆą“øąµ¼", + "header": "PDF ą“Ŗąµ‡ą“œąµ ą““ąµ¼ą“—ą“Øąµˆą“øąµ¼", + "submit": "ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“Ŗąµą“Øą“ƒą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "mode": { + "_value": "ą“®ąµ‹ą“”ąµ", + "1": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“Ŗąµ‡ą“œąµ ą“•ąµą“°ą“®ą“‚", + "2": "ą“µą“æą“Ŗą“°ąµ€ą“¤ ą“•ąµą“°ą“®ą“‚", + "3": "ą“”ąµą“Æąµ‚ą“Ŗąµą“²ąµ†ą“•ąµą“øąµ ą“…ą“Ÿąµą“•ąµą“•ąµ½", + "4": "ą“²ą“˜ąµą“²ąµ‡ą“– ą“…ą“Ÿąµą“•ąµą“•ąµ½", + "5": "ą“øąµˆą“”ąµ ą“øąµą“±ąµą“±ą“æą“šąµą“šąµ ą“²ą“˜ąµą“²ąµ‡ą“– ą“…ą“Ÿąµą“•ąµą“•ąµ½", + "6": "ą“’ą“±ąµą“±-ą“‡ą“°ą“Ÿąµą“Ÿ ą“µą“æą“­ą“œą“Øą“‚", + "7": "ą“†ą“¦ąµą“Æą“¤ąµą“¤ąµ‡ą“¤ąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "8": "ą“…ą“µą“øą“¾ą“Øą“¤ąµą“¤ąµ‡ą“¤ąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "9": "ą“†ą“¦ąµą“Æą“¤ąµą“¤ąµ‡ą“¤ąµą“‚ ą“…ą“µą“øą“¾ą“Øą“¤ąµą“¤ąµ‡ą“¤ąµą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "10": "ą“’ą“±ąµą“±-ą“‡ą“°ą“Ÿąµą“Ÿ ą“²ą“Æą“Øą“‚", + "11": "ą“Žą“²ąµą“²ą“¾ ą“Ŗąµ‡ą“œąµą“•ą“³ąµą“‚ ą“¤ą“Øą“æą“Ŗąµą“Ŗą“•ąµ¼ą“Ŗąµą“Ŗą“¾ą“•ąµą“•ąµą“•" + }, + "placeholder": "(ą“‰ą“¦ą“¾. 1,3,2 ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ 4-8,2,10-12 ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ 2n-1)" + }, + "addImage": { + "tags": "img,jpg,ą“šą“æą“¤ąµą“°ą“‚,ą“«ąµ‹ą“Ÿąµą“Ÿąµ‹", + "title": "ą“šą“æą“¤ąµą“°ą“‚ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "header": "PDF-ą“²ąµ‡ą“•ąµą“•ąµ ą“šą“æą“¤ąµą“°ą“‚ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "everyPage": "ą“Žą“²ąµą“²ą“¾ ą“Ŗąµ‡ą“œą“æą“²ąµą“‚?", + "upload": "ą“šą“æą“¤ąµą“°ą“‚ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "submit": "ą“šą“æą“¤ąµą“°ą“‚ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•" + }, + "watermark": { + "tags": "ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ,ą“†ą“µąµ¼ą“¤ąµą“¤ą“æą“•ąµą“•ąµą“Øąµą“Ø,ą“²ąµ‡ą“¬ąµ½,ą“øąµą“µą“Øąµą“¤ą“‚,ą“Ŗą“•ąµ¼ą“Ŗąµą“Ŗą“µą“•ą“¾ą“¶ą“‚,ą“µąµą“Æą“¾ą“Ŗą“¾ą“°ą“®ąµą“¦ąµą“°,img,jpg,ą“šą“æą“¤ąµą“°ą“‚,ą“«ąµ‹ą“Ÿąµą“Ÿąµ‹", + "title": "ą“µą“¾ą“Ÿąµą“Ÿąµ¼ą“®ą“¾ąµ¼ą“•ąµą“•ąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "header": "ą“µą“¾ą“Ÿąµą“Ÿąµ¼ą“®ą“¾ąµ¼ą“•ąµą“•ąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "customColor": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“Øą“æą“±ą“‚", + "selectText": { + "1": "ą“µą“¾ą“Ÿąµą“Ÿąµ¼ą“®ą“¾ąµ¼ą“•ąµą“•ąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµ‡ą“£ąµą“Ÿ PDF ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•:", + "2": "ą“µą“¾ą“Ÿąµą“Ÿąµ¼ą“®ą“¾ąµ¼ą“•ąµą“•ąµ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ:", + "3": "ą“…ą“•ąµą“·ą“° ą“µą“²ąµą“Ŗąµą“Ŗą“‚:", + "4": "ą“¤ą“æą“°ą“æą“•ąµą“•ąµ½ (0-360):", + "5": "ą“µąµ€ą“¤ą“æ ą“øąµą“Ŗąµ‡ą“øąµ¼ (ą““ą“°ąµ‹ ą“µą“¾ą“Ÿąµą“Ÿąµ¼ą“®ą“¾ąµ¼ą“•ąµą“•ą“æą“Øąµą“‚ ą“‡ą“Ÿą“Æą“æą“²ąµą“³ąµą“³ ą“¤ą“æą“°ą“¶ąµą“šąµ€ą“Øą“®ą“¾ą“Æ ą“øąµą“„ą“²ą“‚):", + "6": "ą“‰ą“Æą“°ą“‚ ą“øąµą“Ŗąµ‡ą“øąµ¼ (ą““ą“°ąµ‹ ą“µą“¾ą“Ÿąµą“Ÿąµ¼ą“®ą“¾ąµ¼ą“•ąµą“•ą“æą“Øąµą“‚ ą“‡ą“Ÿą“Æą“æą“²ąµą“³ąµą“³ ą“²ą“‚ą“¬ą“®ą“¾ą“Æ ą“øąµą“„ą“²ą“‚):", + "7": "ą“…ą“¤ą“¾ą“°ąµą“Æą“¤ (0% - 100%):", + "8": "ą“µą“¾ą“Ÿąµą“Ÿąµ¼ą“®ą“¾ąµ¼ą“•ąµą“•ąµ ą“¤ą“°ą“‚:", + "9": "ą“µą“¾ą“Ÿąµą“Ÿąµ¼ą“®ą“¾ąµ¼ą“•ąµą“•ąµ ą“šą“æą“¤ąµą“°ą“‚:", + "10": "PDF-ą“Øąµ† PDF-ą“šą“æą“¤ąµą“°ą“¤ąµą“¤ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•" + }, + "submit": "ą“µą“¾ą“Ÿąµą“Ÿąµ¼ą“®ą“¾ąµ¼ą“•ąµą“•ąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "type": { + "1": "ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ", + "2": "ą“šą“æą“¤ąµą“°ą“‚" + } + }, + "permissions": { + "tags": "ą“µą“¾ą“Æą“æą“•ąµą“•ąµą“•,ą“Žą““ąµą“¤ąµą“•,ą“¤ą“æą“°ąµą“¤ąµą“¤ąµą“•,ą“…ą“šąµą“šą“Ÿą“æą“•ąµą“•ąµą“•", + "title": "ą“…ą“Øąµą“®ą“¤ą“æą“•ąµ¾ ą“®ą“¾ą“±ąµą“±ąµą“•", + "header": "ą“…ą“Øąµą“®ą“¤ą“æą“•ąµ¾ ą“®ą“¾ą“±ąµą“±ąµą“•", + "warning": "ą“®ąµą“Øąµą“Øą“±ą“æą“Æą“æą“Ŗąµą“Ŗąµ: ą“ˆ ą“…ą“Øąµą“®ą“¤ą“æą“•ąµ¾ ą“®ą“¾ą“±ąµą“±ą“¾ąµ» ą“•ą““ą“æą“Æą“¾ą“¤ąµą“¤ą“¤ą“¾ą“•ąµą“•ą“¾ąµ», ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“• ą“Ŗąµ‡ą“œąµ ą“µą““ą“æ ą“’ą“°ąµ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµ ą“…ą“µ ą“øą“œąµą“œą“®ą“¾ą“•ąµą“•ą“¾ąµ» ą“¶ąµą“Ŗą“¾ąµ¼ą“¶ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ", + "selectText": { + "1": "ą“…ą“Øąµą“®ą“¤ą“æą“•ąµ¾ ą“®ą“¾ą“±ąµą“±ąµ‡ą“£ąµą“Ÿ PDF ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "2": "ą“øą“œąµą“œą“®ą“¾ą“•ąµą“•ąµ‡ą“£ąµą“Ÿ ą“…ą“Øąµą“®ą“¤ą“æą“•ąµ¾", + "3": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ ą“•ąµ‚ą“Ÿąµą“Ÿą“æą“šąµą“šąµ‡ąµ¼ą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“¤ą“Ÿą“Æąµą“•", + "4": "ą“‰ą“³ąµą“³ą“Ÿą“•ąµą“•ą“‚ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“¤ą“Ÿą“Æąµą“•", + "5": "ą“²ą“­ąµą“Æą“¤ą“Æąµą“•ąµą“•ą“¾ą“Æą“æ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“¤ą“Ÿą“Æąµą“•", + "6": "ą“«ąµ‹ą“‚ ą“Ŗąµ‚ą“°ą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“¤ą“Ÿą“Æąµą“•", + "7": "ą“Ŗą“°ą“æą“·ąµą“•ąµą“•ą“°ą“£ą“‚ ą“¤ą“Ÿą“Æąµą“•", + "8": "ą“µąµą“Æą“¾ą“–ąµą“Æą“¾ą“Ø ą“Ŗą“°ą“æą“·ąµą“•ąµą“•ą“°ą“£ą“‚ ą“¤ą“Ÿą“Æąµą“•", + "9": "ą“…ą“šąµą“šą“Ÿą“æ ą“¤ą“Ÿą“Æąµą“•", + "10": "ą“µąµą“Æą“¤ąµą“Æą“øąµą“¤ ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµą“•ą“³ą“æąµ½ ą“…ą“šąµą“šą“Ÿą“æą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“¤ą“Ÿą“Æąµą“•" + }, + "submit": "ą“®ą“¾ą“±ąµą“±ąµą“•" + }, + "removePages": { + "tags": "ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•,ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ąµą“•" + }, + "addPassword": { + "tags": "ą“øąµą“°ą“•ąµą“·ą“æą“¤ą“‚,ą“øąµą“°ą“•ąµą“·", + "title": "ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "header": "ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“• (ą“Žąµ»ą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“•)", + "selectText": { + "1": "ą“Žąµ»ą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµ‡ą“£ąµą“Ÿ PDF ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "2": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ", + "3": "ą“Žąµ»ą“•ąµą“°ą“æą“Ŗąµą“·ąµ» ą“•ąµ€ ą“¦ąµˆąµ¼ą“˜ąµą“Æą“‚", + "4": "ą“‰ą“Æąµ¼ą“Øąµą“Ø ą“®ąµ‚ą“²ąµą“Æą“™ąµą“™ąµ¾ ą“•ąµ‚ą“Ÿąµą“¤ąµ½ ą“¶ą“•ąµą“¤ą“®ą“¾ą“£ąµ, ą“Žą“Øąµą“Øą“¾ąµ½ ą“¤ą“¾ą““ąµą“Øąµą“Ø ą“®ąµ‚ą“²ąµą“Æą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“®ą“æą“•ą“šąµą“š ą“…ą“Øąµą“Æąµ‹ą“œąµą“Æą“¤ą“Æąµą“£ąµą“Ÿąµ.", + "5": "ą“øą“œąµą“œą“®ą“¾ą“•ąµą“•ąµ‡ą“£ąµą“Ÿ ą“…ą“Øąµą“®ą“¤ą“æą“•ąµ¾ (ą“‰ą“Ÿą“®ą“Æąµą“Ÿąµ† ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ą“æą“ØąµŠą“Ŗąµą“Ŗą“‚ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ą“¾ąµ» ą“¶ąµą“Ŗą“¾ąµ¼ą“¶ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ)", + "6": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ ą“•ąµ‚ą“Ÿąµą“Ÿą“æą“šąµą“šąµ‡ąµ¼ą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“¤ą“Ÿą“Æąµą“•", + "7": "ą“‰ą“³ąµą“³ą“Ÿą“•ąµą“•ą“‚ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“¤ą“Ÿą“Æąµą“•", + "8": "ą“²ą“­ąµą“Æą“¤ą“Æąµą“•ąµą“•ą“¾ą“Æą“æ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“¤ą“Ÿą“Æąµą“•", + "9": "ą“«ąµ‹ą“‚ ą“Ŗąµ‚ą“°ą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“¤ą“Ÿą“Æąµą“•", + "10": "ą“Ŗą“°ą“æą“·ąµą“•ąµą“•ą“°ą“£ą“‚ ą“¤ą“Ÿą“Æąµą“•", + "11": "ą“µąµą“Æą“¾ą“–ąµą“Æą“¾ą“Ø ą“Ŗą“°ą“æą“·ąµą“•ąµą“•ą“°ą“£ą“‚ ą“¤ą“Ÿą“Æąµą“•", + "12": "ą“…ą“šąµą“šą“Ÿą“æ ą“¤ą“Ÿą“Æąµą“•", + "13": "ą“µąµą“Æą“¤ąµą“Æą“øąµą“¤ ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµą“•ą“³ą“æąµ½ ą“…ą“šąµą“šą“Ÿą“æą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“¤ą“Ÿą“Æąµą“•", + "14": "ą“‰ą“Ÿą“®ą“Æąµą“Ÿąµ† ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ", + "15": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ ą“¤ąµą“±ą“Øąµą“Øąµą“•ą““ą“æą“žąµą“žą“¾ąµ½ ą“Žą“Øąµą“¤ąµą“šąµ†ą“Æąµą“Æą“¾ąµ» ą“•ą““ą“æą“Æąµą“®ąµ†ą“Øąµą“Øą“¤ąµ ą“Øą“æą“Æą“Øąµą“¤ąµą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ (ą“Žą“²ąµą“²ą“¾ ą“±ąµ€ą“”ą“±ąµą“•ą“³ąµą“‚ ą“Ŗą“æą“Øąµą“¤ąµą“£ą“Æąµą“•ąµą“•ąµą“Øąµą“Øą“æą“²ąµą“²)", + "16": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ ą“¤ą“Øąµą“Øąµ† ą“¤ąµą“±ą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“Øą“æą“Æą“Øąµą“¤ąµą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ" + }, + "submit": "ą“Žąµ»ą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "removePassword": { + "tags": "ą“øąµą“°ą“•ąµą“·ą“æą“¤ą“‚,ą“”ąµ€ą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ,ą“øąµą“°ą“•ąµą“·,ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ąµą“•,ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "title": "ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "header": "ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“• (ą“”ąµ€ą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“•)", + "selectText": { + "1": "ą“”ąµ€ą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµ‡ą“£ąµą“Ÿ PDF ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "2": "ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ" + }, + "submit": "ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "compressPdfs": { + "tags": "ą“šąµą“°ąµą“•ąµą“•ąµą“•,ą“šąµ†ą“±ąµą“¤ąµ,ą“µą“³ą“°ąµ† ą“šąµ†ą“±ąµą“¤ąµ" + }, + "unlockPDFForms": { + "tags": "ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•,ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ąµą“•,ą“«ąµ‹ą“‚,ą“«ąµ€ąµ½ą“”ąµ,ą“±ąµ€ą“”ąµ-ą“’ąµŗą“²ą“æ", + "title": "ą“«ąµ‹ą“‚ ą“«ąµ€ąµ½ą“”ąµą“•ą“³ą“æąµ½ ą“Øą“æą“Øąµą“Øąµ ą“±ąµ€ą“”ąµ-ą“’ąµŗą“²ą“æ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "header": "PDF ą“«ąµ‹ą“®ąµą“•ąµ¾ ą“…ąµŗą“²ąµ‹ą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "submit": "ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "changeMetadata": { + "tags": "ą“¤ą“²ą“•ąµą“•ąµ†ą“Ÿąµą“Ÿąµ,ą“°ą“šą“Æą“æą“¤ą“¾ą“µąµ,ą“¤ąµ€ą“Æą“¤ą“æ,ą“øąµƒą“·ąµą“Ÿą“æ,ą“øą“®ą“Æą“‚,ą“Ŗąµą“°ą“øą“¾ą“§ą“•ąµ»,ą“Øą“æąµ¼ą“®ąµą“®ą“¾ą“¤ą“¾ą“µąµ,ą“øąµą“„ą“æą“¤ą“æą“µą“æą“µą“°ą“•ąµą“•ą“£ą“•ąµą“•ąµą“•ąµ¾", + "title": "ą“¤ą“²ą“•ąµą“•ąµ†ą“Ÿąµą“Ÿąµ:", + "header": "ą“®ąµ†ą“±ąµą“±ą“¾ą“”ą“¾ą“±ąµą“± ą“®ą“¾ą“±ąµą“±ąµą“•", + "selectText": { + "1": "ą“¦ą“Æą“µą“¾ą“Æą“æ ą“Øą“æą“™ąµą“™ąµ¾ ą“®ą“¾ą“±ąµą“±ą“¾ąµ» ą“†ą“—ąµą“°ą“¹ą“æą“•ąµą“•ąµą“Øąµą“Ø ą“µąµ‡ą“°ą“æą“Æą“¬ą“æą“³ąµą“•ąµ¾ ą“¤ą“æą“°ąµą“¤ąµą“¤ąµą“•", + "2": "ą“Žą“²ąµą“²ą“¾ ą“®ąµ†ą“±ąµą“±ą“¾ą“”ą“¾ą“±ąµą“±ą“Æąµą“‚ ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ąµą“•", + "3": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“®ąµ†ą“±ąµą“±ą“¾ą“”ą“¾ą“±ąµą“± ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“•:", + "4": "ą“®ą“±ąµą“±ąµ ą“®ąµ†ą“±ąµą“±ą“¾ą“”ą“¾ą“±ąµą“±:", + "5": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“®ąµ†ą“±ąµą“±ą“¾ą“”ą“¾ą“±ąµą“± ą“Žąµ»ą“Ÿąµą“°ą“æ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•" + }, + "author": "ą“°ą“šą“Æą“æą“¤ą“¾ą“µąµ:", + "creationDate": "ą“øąµƒą“·ąµą“Ÿą“æą“šąµą“š ą“¤ąµ€ą“Æą“¤ą“æ (yyyy/MM/dd HH:mm:ss):", + "creator": "ą“øąµą“°ą“·ąµą“Ÿą“¾ą“µąµ:", + "keywords": "ą“•ąµ€ą“µąµ‡ą“”ąµą“•ąµ¾:", + "modDate": "ą“Ŗą“°ą“æą“·ąµą“•ąµą“•ą“°ą“æą“šąµą“š ą“¤ąµ€ą“Æą“¤ą“æ (yyyy/MM/dd HH:mm:ss):", + "producer": "ą“Øą“æąµ¼ą“®ąµą“®ą“¾ą“¤ą“¾ą“µąµ:", + "subject": "ą“µą“æą“·ą“Æą“‚:", + "trapped": "ą“Ÿąµą“°ą“¾ą“Ŗąµą“Ŗąµą“”ąµ:", + "submit": "ą“®ą“¾ą“±ąµą“±ąµą“•" + }, + "fileToPDF": { + "tags": "ą“°ąµ‚ą“Ŗą“¾ą“Øąµą“¤ą“°ą“‚,ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ,ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚,ą“šą“æą“¤ąµą“°ą“‚,ą“øąµą“²ąµˆą“”ąµ,ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ,ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚,ą““ą“«ąµ€ą“øąµ,ą“”ąµ‹ą“•ąµą“øąµ,ą“µąµ‡ą“”ąµ,ą“Žą“•ąµą“øąµ½,ą“Ŗą“µąµ¼ą“Ŗąµ‹ą“Æą“æą“Øąµą“±ąµ", + "title": "ą“«ą“Æąµ½ PDF-ą“²ąµ‡ą“•ąµą“•ąµ", + "header": "ą“ą“¤ąµ ą“«ą“Æą“²ąµą“‚ PDF-ą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•", + "credit": "ą“ˆ ą“øąµ‡ą“µą“Øą“‚ ą“«ą“Æąµ½ ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“¤ąµą“¤ą“æą“Øą“¾ą“Æą“æ LibreOffice, Unoconv ą“Žą“Øąµą“Øą“æą“µ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ.", + "supportedFileTypesInfo": "ą“Ŗą“æą“Øąµą“¤ąµą“£ą“Æąµą“•ąµą“•ąµą“Øąµą“Ø ą“«ą“Æąµ½ ą“¤ą“°ą“™ąµą“™ąµ¾", + "supportedFileTypes": "ą“Ŗą“æą“Øąµą“¤ąµą“£ą“Æąµą“•ąµą“•ąµą“Øąµą“Ø ą“«ą“Æąµ½ ą“¤ą“°ą“™ąµą“™ą“³ą“æąµ½ ą“¤ą“¾ą““ąµ† ą“Ŗą“±ą“Æąµą“Øąµą“Øą“µ ą“‰ąµ¾ą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ą“£ą“‚, ą“Žą“Øąµą“Øą“æą“°ąµą“Øąµą“Øą“¾ą“²ąµą“‚ ą“Ŗą“æą“Øąµą“¤ąµą“£ą“Æąµą“•ąµą“•ąµą“Øąµą“Ø ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµą“•ą“³ąµą“Ÿąµ† ą“Ŗąµ‚ąµ¼ą“£ąµą“£ą“®ą“¾ą“Æ ą“…ą“Ŗąµā€Œą“”ąµ‡ą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“¤ ą“²ą“æą“øąµą“±ąµą“±ą“æą“Øą“¾ą“Æą“æ, ą“¦ą“Æą“µą“¾ą“Æą“æ LibreOffice ą“”ąµ‹ą“•ąµą“Æąµą“®ąµ†ą“Øąµą“±ąµ‡ą“·ąµ» ą“Ŗą“°ą“æą“¶ąµ‹ą“§ą“æą“•ąµą“•ąµą“•", + "submit": "PDF-ą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•" + }, + "ocr": { + "tags": "ą“¤ą“æą“°ą“æą“šąµą“šą“±ą“æą“Æąµ½,ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ,ą“šą“æą“¤ąµą“°ą“‚,ą“øąµą“•ą“¾ąµ»,ą“µą“¾ą“Æą“æą“•ąµą“•ąµą“•,ą“¤ą“æą“°ą“æą“šąµą“šą“±ą“æą“Æąµą“•,ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ąµ½,ą“¤ą“æą“°ąµą“¤ąµą“¤ą“¾ą“µąµą“Øąµą“Øą“¤ąµ", + "title": "OCR / ą“øąµą“•ą“¾ąµ» ą“µąµƒą“¤ąµą“¤ą“æą“Æą“¾ą“•ąµą“•ąµ½", + "header": "ą“øąµą“•ą“¾ą“Øąµą“•ąµ¾ ą“µąµƒą“¤ąµą“¤ą“æą“Æą“¾ą“•ąµą“•ąµą“• / OCR (ą“’ą“Ŗąµą“±ąµą“±ą“æą“•ąµą“•ąµ½ ą“•ąµą“Æą“¾ą“°ą“•ąµą“Ÿąµ¼ ą“±ąµ†ą“•ąµą“•ą“—ąµą“Øą“æą“·ąµ»)", + "selectText": { + "1": "PDF-ą“Øąµą“³ąµą“³ą“æąµ½ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ąµ‡ą“£ąµą“Ÿ ą“­ą“¾ą“·ą“•ąµ¾ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“• (ą“²ą“æą“øąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“¤ą“æą“Ÿąµą“Ÿąµą“³ąµą“³ą“µ ą“Øą“æą“²ą“µą“æąµ½ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ą“æą“Æą“µą“Æą“¾ą“£ąµ):", + "2": "OCR ą“šąµ†ą“Æąµą“¤ PDF-ą“Øąµ‹ą“ŸąµŠą“Ŗąµą“Ŗą“‚ OCR ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“…ą“Ÿą“™ąµą“™ą“æą“Æ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“«ą“Æąµ½ ą“Øą“æąµ¼ą“®ąµą“®ą“æą“•ąµą“•ąµą“•", + "3": "ą“šą“°ą“æą“žąµą“ž ą“•ąµ‹ą“£ą“æąµ½ ą“øąµą“•ą“¾ąµ» ą“šąµ†ą“Æąµą“¤ ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“¤ą“æą“°ą“æą“•ąµ† ą“øąµą“„ą“¾ą“Øą“¤ąµą“¤ąµ‡ą“•ąµą“•ąµ ą“¤ą“æą“°ą“æą“šąµą“šąµ ą“¶ą“°ą“æą“Æą“¾ą“•ąµą“•ąµą“•", + "4": "ą“Ŗąµ‡ą“œąµ ą“µąµƒą“¤ąµą“¤ą“æą“Æą“¾ą“•ąµą“•ąµą“•, ą“…ą“¤ąµą“µą““ą“æ OCR ą“Ŗą“¶ąµą“šą“¾ą“¤ąµą“¤ą“² ą“¶ą“¬ąµą“¦ą“¤ąµą“¤ą“æąµ½ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ą“¾ą“Øąµą“³ąµą“³ ą“øą“¾ą“§ąµą“Æą“¤ ą“•ąµą“±ą“µą“¾ą“£ąµ. (ą“”ą“Ÿąµą“Ÿąµā€Œą“Ŗąµą“Ÿąµą“Ÿą“æąµ½ ą“®ą“¾ą“±ąµą“±ą“®ą“æą“²ąµą“²)", + "5": "ą“Ŗąµ‡ą“œąµ ą“µąµƒą“¤ąµą“¤ą“æą“Æą“¾ą“•ąµą“•ąµą“•, ą“…ą“¤ąµą“µą““ą“æ OCR ą“Ŗą“¶ąµą“šą“¾ą“¤ąµą“¤ą“² ą“¶ą“¬ąµą“¦ą“¤ąµą“¤ą“æąµ½ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ą“¾ą“Øąµą“³ąµą“³ ą“øą“¾ą“§ąµą“Æą“¤ ą“•ąµą“±ą“µą“¾ą“£ąµ, ą“”ą“Ÿąµą“Ÿąµā€Œą“Ŗąµą“Ÿąµą“Ÿą“æąµ½ ą“µąµƒą“¤ąµą“¤ą“æą“Æą“¾ą“•ąµą“•ąµ½ ą“Øą“æą“²ą“Øą“æąµ¼ą“¤ąµą“¤ąµą“Øąµą“Øąµ.", + "6": "ą“‡ą“Øąµą“±ą“±ą“¾ą“•ąµą“Ÿąµ€ą“µąµ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“‰ą“³ąµą“³ ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“…ą“µą“—ą“£ą“æą“•ąµą“•ąµą“Øąµą“Øąµ, ą“šą“æą“¤ąµą“°ą“™ąµą“™ą“³ą“¾ą“Æ ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“®ą“¾ą“¤ąµą“°ą“‚ OCR ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ", + "7": "OCR ą“Øą“æąµ¼ą“¬ą“Øąµą“§ą“æą“•ąµą“•ąµą“•, ą“Žą“²ąµą“²ą“¾ ą“Æą“„ą“¾ąµ¼ą“¤ąµą“„ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“˜ą“Ÿą“•ą“™ąµą“™ą“³ąµą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“¤ąµą“•ąµŠą“£ąµą“Ÿąµ ą“Žą“²ąµą“²ą“¾ ą“Ŗąµ‡ą“œąµą“•ą“³ąµą“‚ OCR ą“šąµ†ą“Æąµą“Æąµą“‚", + "8": "ą“øą“¾ą“§ą“¾ą“°ą“£ (PDF-ąµ½ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“‰ą“£ąµą“Ÿąµ†ą“™ąµą“•ą“æąµ½ ą“Ŗą“æą“¶ą“•ąµ ą“øą“‚ą“­ą“µą“æą“•ąµą“•ąµą“‚)", + "9": "ą“…ą“§ą“æą“• ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾", + "10": "OCR ą“®ąµ‹ą“”ąµ", + "11": "OCR-ą“Øąµ ą“¶ąµ‡ą“·ą“‚ ą“šą“æą“¤ąµą“°ą“™ąµą“™ąµ¾ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“• (ą“Žą“²ąµą“²ą“¾ ą“šą“æą“¤ąµą“°ą“™ąµą“™ą“³ąµą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ, ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Ø ą“˜ą“Ÿąµą“Ÿą“¤ąµą“¤ą“æą“Øąµą“±ąµ† ą“­ą“¾ą“—ą“®ą“¾ą“£ąµ†ą“™ąµą“•ą“æąµ½ ą“®ą“¾ą“¤ąµą“°ą“‚ ą“‰ą“Ŗą“Æąµ‹ą“—ą“Ŗąµą“°ą“¦ą“‚)", + "12": "ą“±ąµ†ąµ»ą“”ąµ¼ ą“¤ą“°ą“‚ (ą“µą“æą“Ŗąµą“²ą“®ą“¾ą“Æą“¤ąµ)" + }, + "help": "ą“®ą“±ąµą“±ąµ ą“­ą“¾ą“·ą“•ąµ¾ą“•ąµą“•ą“¾ą“Æą“æ ą“‡ą“¤ąµ ą“Žą“™ąµą“™ą“Øąµ† ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ą“¾ą“®ąµ†ą“Øąµą“Øąµą“‚ ą“•ąµ‚ą“Ÿą“¾ą“¤ąµ†/ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“”ąµ‹ą“•ąµą“•ą“±ą“æąµ½ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ą“¾ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øą“¤ą“æą“Øąµ†ą“•ąµą“•ąµą“±ą“æą“šąµą“šąµą“‚ ą“ˆ ą“”ąµ‹ą“•ąµą“Æąµą“®ąµ†ą“Øąµą“±ąµ‡ą“·ąµ» ą“µą“¾ą“Æą“æą“•ąµą“•ąµą“•", + "credit": "ą“ˆ ą“øąµ‡ą“µą“Øą“‚ OCR-ą“Øą“¾ą“Æą“æ qpdf, Tesseract ą“Žą“Øąµą“Øą“æą“µ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ.", + "submit": "OCR ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµ PDF ą“Ŗąµą“°ąµ‹ą“øą“øąµą“øąµ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "extractImages": { + "tags": "ą“šą“æą“¤ąµą“°ą“‚,ą“«ąµ‹ą“Ÿąµą“Ÿąµ‹,ą“øą“‚ą“°ą“•ąµą“·ą“æą“•ąµą“•ąµą“•,ą“†ąµ¼ą“•ąµą“•ąµˆą“µąµ,ą“øą“æą“Ŗąµą“Ŗąµ,ą“Ŗą“æą“Ÿą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“•,ą“Øąµ‡ą“Ÿąµą“•", + "title": "ą“šą“æą“¤ąµą“°ą“™ąµą“™ąµ¾ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "header": "ą“šą“æą“¤ąµą“°ą“™ąµą“™ąµ¾ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "selectText": "ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“¤ąµą“¤ ą“šą“æą“¤ąµą“°ą“™ąµą“™ąµ¾ ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµ‡ą“£ąµą“Ÿ ą“‡ą“®ąµ‡ą“œąµ ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "allowDuplicates": "ą“¤ą“Øą“æą“Ŗąµą“Ŗą“•ąµ¼ą“Ŗąµą“Ŗąµ ą“šą“æą“¤ąµą“°ą“™ąµą“™ąµ¾ ą“øą“‚ą“°ą“•ąµą“·ą“æą“•ąµą“•ąµą“•", + "submit": "ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“•" + }, + "pdfToPDFA": { + "tags": "ą“†ąµ¼ą“•ąµą“•ąµˆą“µąµ,ą“¦ąµ€ąµ¼ą“˜ą“•ą“¾ą“²,ą“®ą“¾ą“Øą“¦ą“£ąµą“”ą“‚,ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚,ą“øą“‚ą“­ą“°ą“£ą“‚,ą“øą“‚ą“°ą“•ąµą“·ą“£ą“‚", + "title": "PDF PDF/A-ą“²ąµ‡ą“•ąµą“•ąµ", + "header": "PDF PDF/A-ą“²ąµ‡ą“•ąµą“•ąµ", + "credit": "ą“ˆ ą“øąµ‡ą“µą“Øą“‚ PDF/A ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“¤ąµą“¤ą“æą“Øą“¾ą“Æą“æ libreoffice ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ", + "submit": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "tip": "ą“Øą“æą“²ą“µą“æąµ½ ą“’ą“°ąµ‡ą“øą“®ą“Æą“‚ ą“’ą“Øąµą“Øą“æą“²ą“§ą“æą“•ą“‚ ą“‡ąµ»ą“Ŗąµą“Ÿąµą“Ÿąµą“•ąµ¾ą“•ąµą“•ą“¾ą“Æą“æ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“•ąµą“•ąµą“Øąµą“Øą“æą“²ąµą“²", + "outputFormat": "ą“”ą“Ÿąµą“Ÿąµā€Œą“Ŗąµą“Ÿąµą“Ÿąµ ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ", + "pdfWithDigitalSignature": "PDF-ąµ½ ą“’ą“°ąµ ą“”ą“æą“œą“æą“±ąµą“±ąµ½ ą“’ą“Ŗąµą“Ŗąµ ą“…ą“Ÿą“™ąµą“™ą“æą“Æą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ. ą“…ą“Ÿąµą“¤ąµą“¤ ą“˜ą“Ÿąµą“Ÿą“¤ąµą“¤ą“æąµ½ ą“‡ą“¤ąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æą“Ŗąµą“Ŗąµ†ą“Ÿąµą“‚." + }, + "PDFToWord": { + "tags": "doc,docx,odt,ą“µąµ‡ą“”ąµ,ą“°ąµ‚ą“Ŗą“¾ą“Øąµą“¤ą“°ą“‚,ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ,ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚,ą““ą“«ąµ€ą“øąµ,ą“®ąµˆą“•ąµą“°ąµ‹ą“øąµ‹ą“«ąµą“±ąµą“±ąµ,ą“”ąµ‹ą“•ąµą“«ą“Æąµ½", + "title": "PDF ą“µąµ‡ą“”ą“æą“²ąµ‡ą“•ąµą“•ąµ", + "header": "PDF ą“µąµ‡ą“”ą“æą“²ąµ‡ą“•ąµą“•ąµ", + "selectText": { + "1": "ą“”ą“Ÿąµą“Ÿąµā€Œą“Ŗąµą“Ÿąµą“Ÿąµ ą“«ą“Æąµ½ ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ" + }, + "credit": "ą“ˆ ą“øąµ‡ą“µą“Øą“‚ ą“«ą“Æąµ½ ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“¤ąµą“¤ą“æą“Øą“¾ą“Æą“æ LibreOffice ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ.", + "submit": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "PDFToPresentation": { + "tags": "ą“øąµą“²ąµˆą“”ąµą“•ąµ¾,ą“·ąµ‹,ą““ą“«ąµ€ą“øąµ,ą“®ąµˆą“•ąµą“°ąµ‹ą“øąµ‹ą“«ąµą“±ąµą“±ąµ", + "title": "PDF ą“Ŗąµą“°ą“øą“Øąµą“±ąµ‡ą“·ą“Øą“æą“²ąµ‡ą“•ąµą“•ąµ", + "header": "PDF ą“Ŗąµą“°ą“øą“Øąµą“±ąµ‡ą“·ą“Øą“æą“²ąµ‡ą“•ąµą“•ąµ", + "selectText": { + "1": "ą“”ą“Ÿąµą“Ÿąµā€Œą“Ŗąµą“Ÿąµą“Ÿąµ ą“«ą“Æąµ½ ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ" + }, + "credit": "ą“ˆ ą“øąµ‡ą“µą“Øą“‚ ą“«ą“Æąµ½ ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“¤ąµą“¤ą“æą“Øą“¾ą“Æą“æ LibreOffice ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ.", + "submit": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "PDFToText": { + "tags": "ą“±ą“æą“šąµą“šąµą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ,ą“±ą“æą“šąµą“šąµā€Œą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ,ą“±ą“æą“šąµą“šąµ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ", + "title": "PDF RTF-ą“²ąµ‡ą“•ąµą“•ąµ (ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ)", + "header": "PDF RTF-ą“²ąµ‡ą“•ąµą“•ąµ (ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ)", + "selectText": { + "1": "ą“”ą“Ÿąµą“Ÿąµā€Œą“Ŗąµą“Ÿąµą“Ÿąµ ą“«ą“Æąµ½ ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ" + }, + "credit": "ą“ˆ ą“øąµ‡ą“µą“Øą“‚ ą“«ą“Æąµ½ ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“¤ąµą“¤ą“æą“Øą“¾ą“Æą“æ LibreOffice ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ.", + "submit": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "PDFToHTML": { + "tags": "ą“µąµ†ą“¬ąµ ą“‰ą“³ąµą“³ą“Ÿą“•ąµą“•ą“‚,ą“¬ąµą“°ąµ—ą“øąµ¼ ą“øąµ—ą“¹ąµƒą“¦ą“‚", + "title": "PDF HTML-ą“²ąµ‡ą“•ąµą“•ąµ", + "header": "PDF HTML-ą“²ąµ‡ą“•ąµą“•ąµ", + "credit": "ą“ˆ ą“øąµ‡ą“µą“Øą“‚ ą“«ą“Æąµ½ ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“¤ąµą“¤ą“æą“Øą“¾ą“Æą“æ pdftohtml ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ.", + "submit": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "PDFToXML": { + "tags": "ą“”ą“¾ą“±ąµą“±-ą“Žą“•ąµą“øąµą“Ÿąµą“°ą“¾ą“•ąµą“·ąµ»,ą“˜ą“Ÿą“Øą“Æąµą“³ąµą“³-ą“‰ą“³ąµą“³ą“Ÿą“•ąµą“•ą“‚,ą“‡ą“Øąµą“±ą“±ąµ‹ą“Ŗąµą“Ŗąµ,ą“°ąµ‚ą“Ŗą“¾ą“Øąµą“¤ą“°ą“‚,ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "title": "PDF XML-ą“²ąµ‡ą“•ąµą“•ąµ", + "header": "PDF XML-ą“²ąµ‡ą“•ąµą“•ąµ", + "credit": "ą“ˆ ą“øąµ‡ą“µą“Øą“‚ ą“«ą“Æąµ½ ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“¤ąµą“¤ą“æą“Øą“¾ą“Æą“æ LibreOffice ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ.", + "submit": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "ScannerImageSplit": { + "tags": "ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“•,ą“øąµą“µą“Æą“‚-ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ąµą“•,ą“øąµą“•ą“¾ą“Øąµą“•ąµ¾,ą“®ąµ¾ą“Ÿąµą“Ÿą“æ-ą“«ąµ‹ą“Ÿąµą“Ÿąµ‹,ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "selectText": { + "1": "ą“•ąµ‹ąµŗ ą“Ŗą“°ą“æą“§ą“æ:", + "2": "ą“šą“æą“¤ąµą“°ą“‚ ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øą“¤ą“æą“Øąµ ą“†ą“µą“¶ąµą“Æą“®ą“¾ą“Æ ą“ą“±ąµą“±ą“µąµą“‚ ą“•ąµą“±ą“žąµą“ž ą“•ąµ‡ą“µą“² ą“•ąµ‹ąµŗ ą“øą“œąµą“œą“®ą“¾ą“•ąµą“•ąµą“Øąµą“Øąµ (ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æ: 10).", + "3": "ą“øą“¹ą“æą“·ąµą“£ąµą“¤:", + "4": "ą“•ą“£ą“•ąµą“•ą“¾ą“•ąµą“•ą“æą“Æ ą“Ŗą“¶ąµą“šą“¾ą“¤ąµą“¤ą“² ą“Øą“æą“±ą“¤ąµą“¤ą“æą“Øąµ ą“šąµą“±ąµą“±ąµą“®ąµą“³ąµą“³ ą“µąµ¼ą“£ąµą“£ ą“µąµą“Æą“¤ą“æą“Æą“¾ą“Øą“¤ąµą“¤ą“æą“Øąµą“±ąµ† ą“Ŗą“°ą“æą“§ą“æ ą“Øą“æąµ¼ą“£ąµą“£ą“Æą“æą“•ąµą“•ąµą“Øąµą“Øąµ (ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æ: 30).", + "5": "ą“•ąµą“±ą“žąµą“ž ą“µą“æą“øąµą“¤ąµ€ąµ¼ą“£ąµą“£ą“‚:", + "6": "ą“’ą“°ąµ ą“«ąµ‹ą“Ÿąµą“Ÿąµ‹ą“Æąµą“•ąµą“•ąµą“³ąµą“³ ą“•ąµą“±ą“žąµą“ž ą“µą“æą“øąµą“¤ąµ€ąµ¼ą“£ąµą“£ ą“Ŗą“°ą“æą“§ą“æ ą“øą“œąµą“œą“®ą“¾ą“•ąµą“•ąµą“Øąµą“Øąµ (ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æ: 10000).", + "7": "ą“•ąµą“±ą“žąµą“ž ą“•ąµ‹ą“£ąµą“Ÿąµ‚ąµ¼ ą“µą“æą“øąµą“¤ąµ€ąµ¼ą“£ąµą“£ą“‚:", + "8": "ą“’ą“°ąµ ą“«ąµ‹ą“Ÿąµą“Ÿąµ‹ą“Æąµą“•ąµą“•ąµą“³ąµą“³ ą“•ąµą“±ą“žąµą“ž ą“•ąµ‹ą“£ąµą“Ÿąµ‚ąµ¼ ą“µą“æą“øąµą“¤ąµ€ąµ¼ą“£ąµą“£ ą“Ŗą“°ą“æą“§ą“æ ą“øą“œąµą“œą“®ą“¾ą“•ąµą“•ąµą“Øąµą“Øąµ", + "9": "ą“…ą“¤ą“æąµ¼ą“¤ąµą“¤ą“æ ą“µą“²ąµą“Ŗąµą“Ŗą“‚:", + "10": "ą“”ą“Ÿąµą“Ÿąµā€Œą“Ŗąµą“Ÿąµą“Ÿą“æąµ½ ą“µąµ†ą“³ąµą“¤ąµą“¤ ą“…ą“¤ą“æą“°ąµą“•ąµ¾ ą“‰ą“£ąµą“Ÿą“¾ą“•ąµą“Øąµą“Øą“¤ąµ ą“¤ą“Ÿą“Æą“¾ąµ» ą“šąµ‡ąµ¼ą“¤ąµą“¤ą“¤ąµą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“¤ą“¤ąµą“®ą“¾ą“Æ ą“…ą“¤ą“æąµ¼ą“¤ąµą“¤ą“æą“Æąµą“Ÿąµ† ą“µą“²ąµą“Ŗąµą“Ŗą“‚ ą“øą“œąµą“œą“®ą“¾ą“•ąµą“•ąµą“Øąµą“Øąµ (ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æ: 1)." + }, + "info": "ą“Ŗąµˆą“¤ąµą“¤ąµŗ ą“‡ąµ»ą“øąµą“±ąµą“±ą“¾ąµ¾ ą“šąµ†ą“Æąµą“¤ą“æą“Ÿąµą“Ÿą“æą“²ąµą“². ą“‡ą“¤ąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ą“¾ąµ» ą“†ą“µą“¶ąµą“Æą“®ą“¾ą“£ąµ." + }, + "sign": { + "tags": "ą“…ą“‚ą“—ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•,ą“†ą“¦ąµą“Æą“¾ą“•ąµą“·ą“°ą“™ąµą“™ąµ¾,ą“µą“°ą“šąµą“š-ą“’ą“Ŗąµą“Ŗąµ,ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ-ą“’ą“Ŗąµą“Ŗąµ,ą“šą“æą“¤ąµą“°-ą“’ą“Ŗąµą“Ŗąµ", + "title": "ą“’ą“Ŗąµą“Ŗą“æą“Ÿąµą“•", + "header": "PDF-ą“•ąµ¾ ą“’ą“Ŗąµą“Ŗą“æą“Ÿąµą“•", + "upload": "ą“šą“æą“¤ąµą“°ą“‚ ą“…ą“Ŗąµā€Œą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "draw": "ą“’ą“Ŗąµą“Ŗąµ ą“µą“°ą“Æąµą“•ąµą“•ąµą“•", + "text": "ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“‡ąµ»ą“Ŗąµą“Ÿąµą“Ÿąµ", + "clear": "ą“®ą“¾ą“Æąµą“•ąµą“•ąµą“•", + "add": "ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "saved": "ą“øą“‚ą“°ą“•ąµą“·ą“æą“šąµą“š ą“’ą“Ŗąµą“Ŗąµą“•ąµ¾", + "save": "ą“’ą“Ŗąµą“Ŗąµ ą“øą“‚ą“°ą“•ąµą“·ą“æą“•ąµą“•ąµą“•", + "personalSigs": "ą“µąµą“Æą“•ąµą“¤ą“æą“—ą“¤ ą“’ą“Ŗąµą“Ŗąµą“•ąµ¾", + "sharedSigs": "ą“Ŗą“™ąµą“•ą“æą“Ÿąµą“Ÿ ą“’ą“Ŗąµą“Ŗąµą“•ąµ¾", + "noSavedSigs": "ą“øą“‚ą“°ą“•ąµą“·ą“æą“šąµą“š ą“’ą“Ŗąµą“Ŗąµą“•ą“³ąµŠą“Øąµą“Øąµą“‚ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ą“æą“Æą“æą“²ąµą“²", + "addToAll": "ą“Žą“²ąµą“²ą“¾ ą“Ŗąµ‡ą“œąµą“•ą“³ą“æą“²ąµ‡ą“•ąµą“•ąµą“‚ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "delete": "ą“®ą“¾ą“Æąµą“•ąµą“•ąµą“•", + "first": "ą“†ą“¦ąµą“Æ ą“Ŗąµ‡ą“œąµ", + "last": "ą“…ą“µą“øą“¾ą“Ø ą“Ŗąµ‡ą“œąµ", + "next": "ą“…ą“Ÿąµą“¤ąµą“¤ ą“Ŗąµ‡ą“œąµ", + "previous": "ą“®ąµą“®ąµą“Ŗą“¤ąµą“¤ąµ† ą“Ŗąµ‡ą“œąµ", + "maintainRatio": "ą“µąµ€ą“•ąµą“·ą“£ą“¾ą“Øąµą“Ŗą“¾ą“¤ą“‚ ą“Øą“æą“²ą“Øą“æąµ¼ą“¤ąµą“¤ąµą“• ą“Ÿąµ‹ą“—ą“æąµ¾ ą“šąµ†ą“Æąµą“Æąµą“•", + "undo": "ą“Ŗą““ą“Æą“Ŗą“Ÿą“æ ą“†ą“•ąµą“•ąµą“•", + "redo": "ą“µąµ€ą“£ąµą“Ÿąµą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "flatten": { + "tags": "ą“øąµą“„ą“æą“°ą“‚,ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“°ą“¹ą“æą“¤ą“®ą“¾ą“•ąµą“•ąµą“•,ą“Øąµ‹ąµŗ-ą“‡ą“Øąµą“±ą“±ą“¾ą“•ąµą“Ÿąµ€ą“µąµ,ą“²ą“˜ąµ‚ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "title": "ą“Ŗą“°ą“¤ąµą“¤ąµą“•", + "header": "PDF-ą“•ąµ¾ ą“Ŗą“°ą“¤ąµą“¤ąµą“•", + "flattenOnlyForms": "ą“«ąµ‹ą“®ąµą“•ąµ¾ ą“®ą“¾ą“¤ąµą“°ą“‚ ą“Ŗą“°ą“¤ąµą“¤ąµą“•", + "submit": "ą“Ŗą“°ą“¤ąµą“¤ąµą“•" + }, + "repair": { + "tags": "ą“Ŗą“°ą“æą“¹ą“°ą“æą“•ąµą“•ąµą“•,ą“Ŗąµą“Øą“ƒą“øąµą“„ą“¾ą“Ŗą“æą“•ąµą“•ąµą“•,ą“¤ą“æą“°ąµą“¤ąµą“¤ąµ½,ą“µąµ€ą“£ąµą“Ÿąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "title": "ą“Øą“Øąµą“Øą“¾ą“•ąµą“•ąµą“•", + "header": "PDF-ą“•ąµ¾ ą“Øą“Øąµą“Øą“¾ą“•ąµą“•ąµą“•", + "submit": "ą“Øą“Øąµą“Øą“¾ą“•ąµą“•ąµą“•" + }, + "removeBlanks": { + "tags": "ą“µąµƒą“¤ąµą“¤ą“æą“Æą“¾ą“•ąµą“•ąµ½,ą“²ą“˜ąµ‚ą“•ą“°ą“æą“•ąµą“•ąµą“•,ą“‰ą“³ąµą“³ą“Ÿą“•ąµą“•ą“®ą“æą“²ąµą“²ą“¾ą“¤ąµą“¤,ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "title": "ą“¶ąµ‚ą“Øąµą“Æą“®ą“¾ą“Æą“µ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "header": "ą“¶ąµ‚ą“Øąµą“Æą“®ą“¾ą“Æ ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "threshold": "ą“Ŗą“æą“•ąµą“øąµ½ ą“µąµ†ą“³ąµą“Ŗąµą“Ŗąµ ą“Ŗą“°ą“æą“§ą“æ:", + "thresholdDesc": "'ą“µąµ†ą“³ąµą“³' ą“Žą“Øąµą“Øąµ ą“¤ą“°ą“‚ą“¤ą“æą“°ą“æą“•ąµą“•ą“¾ąµ» ą“’ą“°ąµ ą“µąµ†ą“³ąµą“¤ąµą“¤ ą“Ŗą“æą“•ąµą“øąµ½ ą“Žą“¤ąµą“° ą“µąµ†ą“³ąµą“¤ąµą“¤ą“¤ą“¾ą“Æą“æą“°ą“æą“•ąµą“•ą“£ą“‚ ą“Žą“Øąµą“Øąµ ą“Øą“æąµ¼ą“£ąµą“£ą“Æą“æą“•ąµą“•ąµą“Øąµą“Øą“¤ą“æą“Øąµą“³ąµą“³ ą“Ŗą“°ą“æą“§ą“æ. 0 = ą“•ą“±ąµą“Ŗąµą“Ŗąµ, 255 ą“¶ąµą“¦ąµą“§ą“®ą“¾ą“Æ ą“µąµ†ą“³ąµą“Ŗąµą“Ŗąµ.", + "whitePercent": "ą“µąµ†ą“³ąµą“Ŗąµą“Ŗąµ ą“¶ą“¤ą“®ą“¾ą“Øą“‚ (%):", + "whitePercentDesc": "ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµ‡ą“£ąµą“Ÿ 'ą“µąµ†ą“³ąµą“¤ąµą“¤' ą“Ŗą“æą“•ąµą“øą“²ąµą“•ąµ¾ ą“…ą“Ÿą“™ąµą“™ą“æą“Æ ą“Ŗąµ‡ą“œą“æą“Øąµą“±ąµ† ą“¶ą“¤ą“®ą“¾ą“Øą“‚", + "submit": "ą“¶ąµ‚ą“Øąµą“Æą“®ą“¾ą“Æą“µ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "removeAnnotations": { + "tags": "ą“…ą“­ą“æą“Ŗąµą“°ą“¾ą“Æą“™ąµą“™ąµ¾,ą“¹ąµˆą“²ąµˆą“±ąµą“±ąµ,ą“•ąµą“±ą“æą“Ŗąµą“Ŗąµą“•ąµ¾,ą“®ą“¾ąµ¼ą“•ąµą“•ąµą“…ą“Ŗąµą“Ŗąµ,ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "title": "ą“µąµą“Æą“¾ą“–ąµą“Æą“¾ą“Øą“™ąµą“™ąµ¾ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "header": "ą“µąµą“Æą“¾ą“–ąµą“Æą“¾ą“Øą“™ąµą“™ąµ¾ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "submit": "ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "compare": { + "tags": "ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“•,ą“µąµą“Æą“¤ąµą“Æą“¾ą“øą“‚,ą“®ą“¾ą“±ąµą“±ą“™ąµą“™ąµ¾,ą“µą“æą“¶ą“•ą“²ą“Øą“‚", + "title": "ą“¤ą“¾ą“°ą“¤ą“®ąµą“Æą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "header": "PDF-ą“•ąµ¾ ą“¤ą“¾ą“°ą“¤ą“®ąµą“Æą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "highlightColor": { + "1": "ą“¹ąµˆą“²ąµˆą“±ąµą“±ąµ ą“Øą“æą“±ą“‚ 1:", + "2": "ą“¹ąµˆą“²ąµˆą“±ąµą“±ąµ ą“Øą“æą“±ą“‚ 2:" + }, + "document": { + "1": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ 1", + "2": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ 2" + }, + "submit": "ą“¤ą“¾ą“°ą“¤ą“®ąµą“Æą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "complex": { + "message": "ą“Øąµ½ą“•ą“æą“Æą“æą“Ÿąµą“Ÿąµą“³ąµą“³ ą“’ą“Øąµą“Øąµ‹ ą“°ą“£ąµą“Ÿąµ‹ ą“Ŗąµą“°ą“®ą“¾ą“£ą“™ąµą“™ąµ¾ ą“µą“²ą“æą“Æ ą“«ą“Æą“²ąµą“•ą“³ą“¾ą“£ąµ, ą“¤ą“¾ą“°ą“¤ą“®ąµą“Æą“¤ąµą“¤ą“æą“Øąµą“±ąµ† ą“•ąµƒą“¤ąµą“Æą“¤ ą“•ąµą“±ą“žąµą“žąµ‡ą“•ąµą“•ą“¾ą“‚" + }, + "large": { + "file": { + "message": "ą“Øąµ½ą“•ą“æą“Æą“æą“Ÿąµą“Ÿąµą“³ąµą“³ ą“’ą“Øąµą“Øąµ‹ ą“°ą“£ąµą“Ÿąµ‹ ą“Ŗąµą“°ą“®ą“¾ą“£ą“™ąµą“™ąµ¾ ą“Ŗąµą“°ąµ‹ą“øą“øąµą“øąµ ą“šąµ†ą“Æąµą“Æą“¾ąµ» ą“•ą““ą“æą“Æą“¾ą“¤ąµą“¤ą“¤ąµą“° ą“µą“²ąµą“¤ą“¾ą“£ąµ" + } + }, + "no": { + "text": { + "message": "ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“¤ąµą“¤ ą“’ą“Øąµą“Øąµ‹ ą“°ą“£ąµą“Ÿąµ‹ PDF-ą“•ą“³ą“æąµ½ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“‰ą“³ąµą“³ą“Ÿą“•ąµą“•ą“®ą“æą“²ąµą“². ą“¤ą“¾ą“°ą“¤ą“®ąµą“Æą“¤ąµą“¤ą“æą“Øą“¾ą“Æą“æ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“‰ą“³ąµą“³ PDF-ą“•ąµ¾ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•." + } + } + }, + "certSign": { + "tags": "ą“øąµą“„ą“æą“°ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•,PEM,P12,ą“”ą“¦ąµą“Æąµ‹ą“—ą“æą“•ą“‚,ą“Žąµ»ą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "title": "ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“’ą“Ŗąµą“Ŗą“æą“Ÿąµ½", + "header": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµ ą“’ą“°ąµ PDF ą“’ą“Ŗąµą“Ŗą“æą“Ÿąµą“• (ą“Øą“æąµ¼ą“®ąµą“®ą“¾ą“£ą“¤ąµą“¤ą“æą“²ą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ)", + "selectPDF": "ą“’ą“Ŗąµą“Ŗą“æą“Ÿąµą“Øąµą“Øą“¤ą“æą“Øą“¾ą“Æą“æ ą“’ą“°ąµ PDF ą“«ą“Æąµ½ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•:", + "jksNote": "ą“¶ąµą“°ą“¦ąµą“§ą“æą“•ąµą“•ąµą“•: ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“¤ą“°ą“‚ ą“¤ą“¾ą““ąµ† ą“²ą“æą“øąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“¤ą“æą“Ÿąµą“Ÿą“æą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½, ą“¦ą“Æą“µą“¾ą“Æą“æ ą“•ąµ€ą“Ÿąµ‚ąµ¾ ą“•ą“®ą“¾ąµ»ą“”ąµ ą“²ąµˆąµ» ą“Ÿąµ‚ąµ¾ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµ ą“…ą“¤ą“æą“Øąµ† ą“’ą“°ąµ ą“œą“¾ą“µ ą“•ąµ€ą“øąµą“±ąµą“±ąµ‹ąµ¼ (.jks) ą“«ą“Æą“²ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•. ą“¤ąµą“Ÿąµ¼ą“Øąµą“Øąµ, ą“¤ą“¾ą““ąµ†ą“Æąµą“³ąµą“³ .jks ą“«ą“Æąµ½ ą““ą“Ŗąµą“·ąµ» ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•.", + "selectKey": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“øąµą“µą“•ą“¾ą“°ąµą“Æ ą“•ąµ€ ą“«ą“Æąµ½ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“• (PKCS#8 ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ, .pem ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ .der ą“†ą“•ą“¾ą“‚):", + "selectCert": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“«ą“Æąµ½ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“• (X.509 ą“«ąµ‹ąµ¼ą“®ą“¾ą“±ąµą“±ąµ, .pem ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ .der ą“†ą“•ą“¾ą“‚):", + "selectP12": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† PKCS#12 ą“•ąµ€ą“øąµą“±ąµą“±ąµ‹ąµ¼ ą“«ą“Æąµ½ (.p12 ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ .pfx) ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“• (ą““ą“Ŗąµą“·ą“£ąµ½, ą“Øąµ½ą“•ą“æą“Æą“æą“Ÿąµą“Ÿąµą“£ąµą“Ÿąµ†ą“™ąµą“•ą“æąµ½, ą“…ą“¤ą“æąµ½ ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“øąµą“µą“•ą“¾ą“°ąµą“Æ ą“•ąµ€ą“Æąµą“‚ ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµą“‚ ą“…ą“Ÿą“™ąµą“™ą“æą“Æą“æą“°ą“æą“•ąµą“•ą“£ą“‚):", + "selectJKS": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“œą“¾ą“µ ą“•ąµ€ą“øąµą“±ąµą“±ąµ‹ąµ¼ ą“«ą“Æąµ½ (.jks ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ .keystore) ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•:", + "certType": "ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“¤ą“°ą“‚", + "password": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“•ąµ€ą“øąµą“±ąµą“±ąµ‹ąµ¼ ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“øąµą“µą“•ą“¾ą“°ąµą“Æ ą“•ąµ€ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“Øąµ½ą“•ąµą“• (ą“‰ą“£ąµą“Ÿąµ†ą“™ąµą“•ą“æąµ½):", + "showSig": "ą“’ą“Ŗąµą“Ŗąµ ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“•", + "reason": "ą“•ą“¾ą“°ą“£ą“‚", + "location": "ą“øąµą“„ą“²ą“‚", + "name": "ą“Ŗąµ‡ą“°ąµ", + "showLogo": "ą“²ąµ‹ą“—ąµ‹ ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“•", + "submit": "PDF ą“’ą“Ŗąµą“Ŗą“æą“Ÿąµą“•" + }, + "removeCertSign": { + "tags": "ą“øąµą“„ą“æą“°ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•,PEM,P12,ą“”ą“¦ąµą“Æąµ‹ą“—ą“æą“•ą“‚,ą“”ąµ€ą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "title": "ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“’ą“Ŗąµą“Ŗąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "header": "PDF-ąµ½ ą“Øą“æą“Øąµą“Øąµ ą“”ą“æą“œą“æą“±ąµą“±ąµ½ ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "selectPDF": "ą“’ą“°ąµ PDF ą“«ą“Æąµ½ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•:", + "submit": "ą“’ą“Ŗąµą“Ŗąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "pageLayout": { + "tags": "ą“²ą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•,ą“øą“‚ą“Æąµ‹ą“œą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•,ą“’ą“±ąµą“±-ą“•ą“¾ą““ąµą“š,ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "title": "ą“®ąµ¾ą“Ÿąµą“Ÿą“æ ą“Ŗąµ‡ą“œąµ ą“²ąµ‡ą“”ą“Ÿąµą“Ÿąµ", + "header": "ą“®ąµ¾ą“Ÿąµą“Ÿą“æ ą“Ŗąµ‡ą“œąµ ą“²ąµ‡ą“”ą“Ÿąµą“Ÿąµ", + "pagesPerSheet": "ą““ą“°ąµ‹ ą“·ąµ€ą“±ąµą“±ą“æą“²ąµ†ą“Æąµą“‚ ą“Ŗąµ‡ą“œąµą“•ąµ¾:", + "addBorder": "ą“…ą“¤ą“æą“°ąµą“•ąµ¾ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•", + "submit": "ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•" + }, + "scalePages": { + "tags": "ą“µą“²ąµą“Ŗąµą“Ŗą“‚ ą“®ą“¾ą“±ąµą“±ąµą“•,ą“Ŗą“°ą“æą“·ąµą“•ąµą“•ą“°ą“æą“•ąµą“•ąµą“•,ą“…ą“³ą“µąµ,ą“…ą“Øąµą“Æąµ‹ą“œąµą“Æą“®ą“¾ą“•ąµą“•ąµą“•", + "title": "ą“Ŗąµ‡ą“œąµ-ą“øąµą“•ąµ†ą“Æą“æąµ½ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "header": "ą“Ŗąµ‡ą“œąµ-ą“øąµą“•ąµ†ą“Æą“æąµ½ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "pageSize": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æą“²ąµ† ą“’ą“°ąµ ą“Ŗąµ‡ą“œą“æą“Øąµą“±ąµ† ą“µą“²ąµą“Ŗąµą“Ŗą“‚.", + "keepPageSize": "ą“Æą“„ą“¾ąµ¼ą“¤ąµą“„ ą“µą“²ąµą“Ŗąµą“Ŗą“‚", + "scaleFactor": "ą“’ą“°ąµ ą“Ŗąµ‡ą“œą“æą“Øąµą“±ąµ† ą“øąµ‚ą“‚ ą“Øą“æą“² (ą“•ąµą“°ąµ‹ą“Ŗąµą“Ŗąµ).", + "submit": "ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•" + }, + "add-page-numbers": { + "tags": "ą“Ŗąµ‡ą“œąµ ą“Øą“®ąµą“Ŗąµ¼ ą“Øąµ½ą“•ąµą“•,ą“²ąµ‡ą“¬ąµ½,ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•,ą“øąµ‚ą“šą“æą“•" + }, + "auto-rename": { + "tags": "ą“øąµą“µą“Æą“‚-ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ąµą“•,ą“¤ą“²ą“•ąµą“•ąµ†ą“Ÿąµą“Ÿąµ-ą“…ą“Ÿą“æą“øąµą“„ą“¾ą“Øą“®ą“¾ą“•ąµą“•ą“æą“Æąµą“³ąµą“³,ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•,ą“Ŗąµą“Øąµ¼ą“²ąµ‡ą“¬ąµ½ ą“šąµ†ą“Æąµą“Æąµą“•", + "title": "ą“øąµą“µą“Æą“‚ ą“Ŗąµą“Øąµ¼ą“Øą“¾ą“®ą“•ą“°ą“£ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "header": "PDF ą“øąµą“µą“Æą“‚ ą“Ŗąµą“Øąµ¼ą“Øą“¾ą“®ą“•ą“°ą“£ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "submit": "ą“øąµą“µą“Æą“‚ ą“Ŗąµą“Øąµ¼ą“Øą“¾ą“®ą“•ą“°ą“£ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "adjust-contrast": { + "tags": "ą“Øą“æą“±ą“‚-ą“¤ą“æą“°ąµą“¤ąµą“¤ąµ½,ą“Ÿąµą“Æąµ‚ąµŗ ą“šąµ†ą“Æąµą“Æąµą“•,ą“Ŗą“°ą“æą“·ąµą“•ąµą“•ą“°ą“æą“•ąµą“•ąµą“•,ą“®ąµ†ą“šąµą“šą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ąµą“•" + }, + "crop": { + "tags": "ą“®ąµą“±ą“æą“•ąµą“•ąµą“•,ą“šąµą“°ąµą“•ąµą“•ąµą“•,ą“¤ą“æą“°ąµą“¤ąµą“¤ąµą“•,ą“°ąµ‚ą“Ŗą“‚", + "title": "ą“•ąµą“°ąµ‹ą“Ŗąµą“Ŗąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "header": "PDF ą“•ąµą“°ąµ‹ą“Ŗąµą“Ŗąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "submit": "ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•" + }, + "autoSplitPDF": { + "tags": "QR-ą“…ą“Ÿą“æą“øąµą“„ą“¾ą“Øą“®ą“¾ą“•ąµą“•ą“æą“Æąµą“³ąµą“³,ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“•,ą“øąµą“•ą“¾ąµ»-ą“øąµ†ą“—ąµą“®ąµ†ą“Øąµą“±ąµ,ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "title": "PDF ą“øąµą“µą“Æą“‚ ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "header": "PDF ą“øąµą“µą“Æą“‚ ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "description": "ą“…ą“šąµą“šą“Ÿą“æą“•ąµą“•ąµą“•, ą“¤ą“æą“°ąµą“•ąµą“•, ą“øąµą“•ą“¾ąµ» ą“šąµ†ą“Æąµą“Æąµą“•, ą“…ą“Ŗąµā€Œą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•, ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Ŗąµą“°ą“®ą“¾ą“£ą“™ąµą“™ąµ¾ ą“žą“™ąµą“™ąµ¾ ą“øąµą“µą“Æą“‚ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“•ąµą“•ą“Ÿąµą“Ÿąµ†. ą“øąµą“µą“Æą“‚ ą“…ą“Ÿąµą“•ąµą“•ąµ‡ą“£ąµą“Ÿ ą“†ą“µą“¶ąµą“Æą“®ą“æą“²ąµą“².", + "selectText": { + "1": "ą“¤ą“¾ą““ąµ† ą“Øą“æą“Øąµą“Øąµ ą“•ąµą“±ą“šąµą“šąµ ą“µą“æą“­ą“œą“Ø ą“·ąµ€ą“±ąµą“±ąµą“•ąµ¾ ą“…ą“šąµą“šą“Ÿą“æą“•ąµą“•ąµą“• (ą“•ą“±ąµą“Ŗąµą“Ŗąµą“‚ ą“µąµ†ą“³ąµą“Ŗąµą“Ŗąµą“‚ ą“®ą“¤ą“æ).", + "2": "ą“…ą“µą“Æąµą“•ąµą“•ą“æą“Ÿą“Æą“æąµ½ ą“µą“æą“­ą“œą“Ø ą“·ąµ€ą“±ąµą“±ąµ ą“¤ą“æą“°ąµą“•ą“æ ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Žą“²ąµą“²ą“¾ ą“Ŗąµą“°ą“®ą“¾ą“£ą“™ąµą“™ą“³ąµą“‚ ą“’ą“°ąµ‡ą“øą“®ą“Æą“‚ ą“øąµą“•ą“¾ąµ» ą“šąµ†ą“Æąµą“Æąµą“•.", + "3": "ą“’ą“°ąµŠą“±ąµą“± ą“µą“²ą“æą“Æ ą“øąµą“•ą“¾ąµ» ą“šąµ†ą“Æąµą“¤ PDF ą“«ą“Æąµ½ ą“…ą“Ŗąµā€Œą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•, ą“¬ą“¾ą“•ąµą“•ą“æą“Æąµą“³ąµą“³ą“µ ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ PDF ą“•ąµˆą“•ą“¾ą“°ąµą“Æą“‚ ą“šąµ†ą“Æąµą“Æą“Ÿąµą“Ÿąµ†.", + "4": "ą“µą“æą“­ą“œą“Ø ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“øąµą“µą“Æą“‚ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ąµą“•ą“Æąµą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•ą“Æąµą“‚ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ, ą“‡ą“¤ąµ ą“µąµƒą“¤ąµą“¤ą“æą“Æąµą“³ąµą“³ ą“…ą“Øąµą“¤ą“æą“® ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚ ą“‰ą“±ą“Ŗąµą“Ŗą“¾ą“•ąµą“•ąµą“Øąµą“Øąµ." + }, + "formPrompt": "ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ-PDF ą“Ŗąµ‡ą“œąµ ą“µą“æą“­ą“œą“Øą“™ąµą“™ąµ¾ ą“…ą“Ÿą“™ąµą“™ą“æą“Æ PDF ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•:", + "duplexMode": "ą“”ąµą“Æąµ‚ą“Ŗąµą“²ąµ†ą“•ąµą“øąµ ą“®ąµ‹ą“”ąµ (ą“®ąµą“Øąµą“Øą“æą“²ąµą“‚ ą“Ŗą“æą“Øąµą“Øą“æą“²ąµą“‚ ą“øąµą“•ą“¾ą“Øą“æą“‚ą“—ąµ)", + "dividerDownload2": "'ą““ą“Ÿąµą“Ÿąµ‹ ą“øąµą“Ŗąµą“²ą“æą“±ąµą“±ąµ¼ ą“”ą“æą“µąµˆą“”ąµ¼ (ą“Øą“æąµ¼ą“¦ąµą“¦ąµ‡ą“¶ą“™ąµą“™ą“³ąµ‹ą“Ÿąµą“•ąµ‚ą“Ÿą“æ).pdf' ą“”ąµ—ąµŗą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "submit": "ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•" + }, + "sanitizePdf": { + "tags": "ą“µąµƒą“¤ąµą“¤ą“æą“Æą“¾ą“•ąµą“•ąµą“•,ą“øąµą“°ą“•ąµą“·ą“æą“¤ą“®ą“¾ą“•ąµą“•ąµą“•,ą“øąµą“°ą“•ąµą“·ą“æą“¤ą“‚,ą“­ąµ€ą“·ą“£ą“æą“•ąµ¾-ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "URLToPDF": { + "tags": "ą“µąµ†ą“¬ąµ-ą“•ąµą“Æą“¾ą“Ŗąµą“šąµ¼,ą“Ŗąµ‡ą“œąµ-ą“øą“‚ą“°ą“•ąµą“·ą“æą“•ąµą“•ąµą“•,ą“µąµ†ą“¬ąµ-ą“Ÿąµ-ą“”ąµ‹ą“•ąµ,ą“†ąµ¼ą“•ąµą“•ąµˆą“µąµ", + "title": "URL PDF-ą“²ąµ‡ą“•ąµą“•ąµ", + "header": "URL PDF-ą“²ąµ‡ą“•ąµą“•ąµ", + "submit": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "credit": "WeasyPrint ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ" + }, + "HTMLToPDF": { + "tags": "ą“®ą“¾ąµ¼ą“•ąµą“•ąµą“…ą“Ŗąµą“Ŗąµ,ą“µąµ†ą“¬ąµ-ą“‰ą“³ąµą“³ą“Ÿą“•ąµą“•ą“‚,ą“°ąµ‚ą“Ŗą“¾ą“Øąµą“¤ą“°ą“‚,ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "title": "HTML PDF-ą“²ąµ‡ą“•ąµą“•ąµ", + "header": "HTML PDF-ą“²ąµ‡ą“•ąµą“•ąµ", + "help": "HTML ą“«ą“Æą“²ąµą“•ą“³ąµą“‚ html/css/ą“šą“æą“¤ąµą“°ą“™ąµą“™ąµ¾ ą“¤ąµą“Ÿą“™ąµą“™ą“æą“Æą“µ ą“…ą“Ÿą“™ąµą“™ą“æą“Æ ZIP-ą“•ą“³ąµą“‚ ą“øąµą“µąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ", + "submit": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "credit": "WeasyPrint ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ", + "zoom": "ą“µąµ†ą“¬ąµą“øąµˆą“±ąµą“±ąµ ą“Ŗąµą“°ą“¦ąµ¼ą“¶ą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“Øąµą“Øą“¤ą“æą“Øąµą“³ąµą“³ ą“øąµ‚ą“‚ ą“Øą“æą“².", + "pageWidth": "ą“Ŗąµ‡ą“œą“æą“Øąµą“±ąµ† ą“µąµ€ą“¤ą“æ ą“øąµ†ą“Øąµą“±ąµ€ą“®ąµ€ą“±ąµą“±ą“±ą“æąµ½. (ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æą“•ąµą“•ą“¾ą“Æą“æ ą“¶ąµ‚ą“Øąµą“Æą“®ą“¾ą“•ąµą“•ąµą“•)", + "pageHeight": "ą“Ŗąµ‡ą“œą“æą“Øąµą“±ąµ† ą“‰ą“Æą“°ą“‚ ą“øąµ†ą“Øąµą“±ąµ€ą“®ąµ€ą“±ąµą“±ą“±ą“æąµ½. (ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æą“•ąµą“•ą“¾ą“Æą“æ ą“¶ąµ‚ą“Øąµą“Æą“®ą“¾ą“•ąµą“•ąµą“•)", + "marginTop": "ą“Ŗąµ‡ą“œą“æą“Øąµą“±ąµ† ą“®ąµą“•ą“³ą“æą“²ąµ† ą“®ą“¾ąµ¼ą“œą“æąµ» ą“®ą“æą“²ąµą“²ą“æą“®ąµ€ą“±ąµą“±ą“±ą“æąµ½. (ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æą“•ąµą“•ą“¾ą“Æą“æ ą“¶ąµ‚ą“Øąµą“Æą“®ą“¾ą“•ąµą“•ąµą“•)", + "marginBottom": "ą“Ŗąµ‡ą“œą“æą“Øąµą“±ąµ† ą“¤ą“¾ą““ą“¤ąµą“¤ąµ† ą“®ą“¾ąµ¼ą“œą“æąµ» ą“®ą“æą“²ąµą“²ą“æą“®ąµ€ą“±ąµą“±ą“±ą“æąµ½. (ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æą“•ąµą“•ą“¾ą“Æą“æ ą“¶ąµ‚ą“Øąµą“Æą“®ą“¾ą“•ąµą“•ąµą“•)", + "marginLeft": "ą“Ŗąµ‡ą“œą“æą“Øąµą“±ąµ† ą“‡ą“Ÿą“¤ąµ ą“®ą“¾ąµ¼ą“œą“æąµ» ą“®ą“æą“²ąµą“²ą“æą“®ąµ€ą“±ąµą“±ą“±ą“æąµ½. (ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æą“•ąµą“•ą“¾ą“Æą“æ ą“¶ąµ‚ą“Øąµą“Æą“®ą“¾ą“•ąµą“•ąµą“•)", + "marginRight": "ą“Ŗąµ‡ą“œą“æą“Øąµą“±ąµ† ą“µą“²ą“¤ąµ ą“®ą“¾ąµ¼ą“œą“æąµ» ą“®ą“æą“²ąµą“²ą“æą“®ąµ€ą“±ąµą“±ą“±ą“æąµ½. (ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æą“•ąµą“•ą“¾ą“Æą“æ ą“¶ąµ‚ą“Øąµą“Æą“®ą“¾ą“•ąµą“•ąµą“•)", + "printBackground": "ą“µąµ†ą“¬ąµą“øąµˆą“±ąµą“±ąµą“•ą“³ąµą“Ÿąµ† ą“Ŗą“¶ąµą“šą“¾ą“¤ąµą“¤ą“²ą“‚ ą“±ąµ†ąµ»ą“”ąµ¼ ą“šąµ†ą“Æąµą“Æąµą“•.", + "defaultHeader": "ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æ ą“¤ą“²ą“•ąµą“•ąµ†ą“Ÿąµą“Ÿąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“•ąµą“·ą“®ą“®ą“¾ą“•ąµą“•ąµą“• (ą“Ŗąµ‡ą“°ąµą“‚ ą“Ŗąµ‡ą“œąµ ą“Øą“®ąµą“Ŗą“±ąµą“‚)", + "cssMediaType": "ą“Ŗąµ‡ą“œą“æą“Øąµą“±ąµ† CSS ą“®ąµ€ą“”ą“æą“Æ ą“¤ą“°ą“‚ ą“®ą“¾ą“±ąµą“±ąµą“•.", + "none": "ą“’ą“Øąµą“Øąµą“®ą“æą“²ąµą“²", + "print": "ą“…ą“šąµą“šą“Ÿą“æą“•ąµą“•ąµą“•", + "screen": "ą“øąµą“•ąµą“°ąµ€ąµ»" + }, + "MarkdownToPDF": { + "tags": "ą“®ą“¾ąµ¼ą“•ąµą“•ąµą“…ą“Ŗąµą“Ŗąµ,ą“µąµ†ą“¬ąµ-ą“‰ą“³ąµą“³ą“Ÿą“•ąµą“•ą“‚,ą“°ąµ‚ą“Ŗą“¾ą“Øąµą“¤ą“°ą“‚,ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•,md", + "title": "ą“®ą“¾ąµ¼ą“•ąµą“•ąµą“”ąµ—ąµŗ PDF-ą“²ąµ‡ą“•ąµą“•ąµ", + "header": "ą“®ą“¾ąµ¼ą“•ąµą“•ąµą“”ąµ—ąµŗ PDF-ą“²ąµ‡ą“•ąµą“•ąµ", + "submit": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "help": "ą“Øą“æąµ¼ą“®ąµą“®ą“¾ą“£ą“¤ąµą“¤ą“æą“²ą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ", + "credit": "WeasyPrint ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ" + }, + "PDFToMarkdown": { + "tags": "ą“®ą“¾ąµ¼ą“•ąµą“•ąµą“…ą“Ŗąµą“Ŗąµ,ą“µąµ†ą“¬ąµ-ą“‰ą“³ąµą“³ą“Ÿą“•ąµą“•ą“‚,ą“°ąµ‚ą“Ŗą“¾ą“Øąµą“¤ą“°ą“‚,ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•,md", + "title": "PDF ą“®ą“¾ąµ¼ą“•ąµą“•ąµą“”ąµ—ą“£ą“æą“²ąµ‡ą“•ąµą“•ąµ", + "header": "PDF ą“®ą“¾ąµ¼ą“•ąµą“•ąµą“”ąµ—ą“£ą“æą“²ąµ‡ą“•ąµą“•ąµ", + "submit": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "getPdfInfo": { + "tags": "ą“µą“æą“µą“°ą“‚,ą“”ą“¾ą“±ąµą“±,ą“øąµą“„ą“æą“¤ą“æą“µą“æą“µą“°ą“•ąµą“•ą“£ą“•ąµą“•ąµą“•ąµ¾,ą“øąµą“„ą“æą“¤ą“æą“µą“æą“µą“°ą“•ąµą“•ą“£ą“•ąµą“•ąµą“•ąµ¾", + "title": "PDF-ą“Øąµ†ą“•ąµą“•ąµą“±ą“æą“šąµą“šąµą“³ąµą“³ ą“µą“æą“µą“°ą“™ąµą“™ąµ¾ ą“Øąµ‡ą“Ÿąµą“•", + "header": "PDF-ą“Øąµ†ą“•ąµą“•ąµą“±ą“æą“šąµą“šąµą“³ąµą“³ ą“µą“æą“µą“°ą“™ąµą“™ąµ¾ ą“Øąµ‡ą“Ÿąµą“•", + "submit": "ą“µą“æą“µą“°ą“™ąµą“™ąµ¾ ą“Øąµ‡ą“Ÿąµą“•", + "downloadJson": "JSON ą“”ąµ—ąµŗą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "extractPage": { + "tags": "ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“•" + }, + "PdfToSinglePage": { + "tags": "ą“’ą“±ąµą“± ą“Ŗąµ‡ą“œąµ" + }, + "showJS": { + "tags": "JS", + "title": "ą“œą“¾ą“µą“¾ą“øąµą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“•", + "header": "ą“œą“¾ą“µą“¾ą“øąµą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“•", + "downloadJS": "ą“œą“¾ą“µą“¾ą“øąµą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“”ąµ—ąµŗą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "submit": "ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“•" + }, + "autoRedact": { + "tags": "ą“±ąµ†ą“”ą“¾ą“•ąµą“±ąµą“±ąµ,ą“®ą“±ą“Æąµą“•ąµą“•ąµą“•,ą“•ą“±ąµą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•,ą“•ą“±ąµą“Ŗąµą“Ŗąµ,ą“®ą“¾ąµ¼ą“•ąµą“•ąµ¼,ą“®ą“±ą“žąµą“žą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Ø", + "title": "ą“øąµą“µą“Æą“‚ ą“±ąµ†ą“”ą“¾ą“•ąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "header": "ą“øąµą“µą“Æą“‚ ą“±ąµ†ą“”ą“¾ą“•ąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "colorLabel": "ą“Øą“æą“±ą“‚", + "textsToRedactLabel": "ą“±ąµ†ą“”ą“¾ą“•ąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµ‡ą“£ąµą“Ÿ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ (ą“µą“°ą“æą“•ą“³ą“¾ąµ½ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šą“¤ąµ)", + "textsToRedactPlaceholder": "ą“‰ą“¦ą“¾. \\ną“°ą“¹ą“øąµą“Æą“‚ \\ną“…ą“¤ąµ€ą“µ-ą“°ą“¹ą“øąµą“Æą“‚", + "useRegexLabel": "ą“±ąµ†ą“—ąµą“²ąµ¼ ą“Žą“•ąµą“øąµą“Ŗąµą“°ą“·ąµ» ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“•", + "wholeWordSearchLabel": "ą“®ąµą““ąµą“µąµ» ą“µą“¾ą“•ąµą“•ąµ ą“¤ą“æą“°ą“Æąµ½", + "customPaddingLabel": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“…ą“§ą“æą“• ą“Ŗą“¾ą“”ą“æą“‚ą“—ąµ", + "convertPDFToImageLabel": "PDF-ą“Øąµ† PDF-ą“šą“æą“¤ąµą“°ą“¤ąµą“¤ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“• (ą“¬ąµ‹ą“•ąµą“øą“æą“Øąµ ą“Ŗą“æą“Øąµą“Øą“æą“²ąµ† ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æą“¾ąµ» ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ)", + "submitButton": "ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•" + }, + "redact": { + "tags": "ą“±ąµ†ą“”ą“¾ą“•ąµą“±ąµą“±ąµ,ą“®ą“±ą“Æąµą“•ąµą“•ąµą“•,ą“•ą“±ąµą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•,ą“•ą“±ąµą“Ŗąµą“Ŗąµ,ą“®ą“¾ąµ¼ą“•ąµą“•ąµ¼,ą“®ą“±ą“žąµą“žą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Ø,ą“øąµą“µą“Æą“‚", + "title": "ą“øąµą“µą“Æą“‚ ą“±ąµ†ą“”ą“¾ą“•ąµą“·ąµ»", + "header": "ą“øąµą“µą“Æą“‚ ą“±ąµ†ą“”ą“¾ą“•ąµą“·ąµ»", + "submit": "ą“±ąµ†ą“”ą“¾ą“•ąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "textBasedRedaction": "ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“…ą“Ÿą“æą“øąµą“„ą“¾ą“Øą“®ą“¾ą“•ąµą“•ą“æą“Æąµą“³ąµą“³ ą“±ąµ†ą“”ą“¾ą“•ąµą“·ąµ»", + "pageBasedRedaction": "ą“Ŗąµ‡ą“œąµ ą“…ą“Ÿą“æą“øąµą“„ą“¾ą“Øą“®ą“¾ą“•ąµą“•ą“æą“Æąµą“³ąµą“³ ą“±ąµ†ą“”ą“¾ą“•ąµą“·ąµ»", + "convertPDFToImageLabel": "PDF-ą“Øąµ† PDF-ą“šą“æą“¤ąµą“°ą“¤ąµą“¤ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“• (ą“¬ąµ‹ą“•ąµą“øą“æą“Øąµ ą“Ŗą“æą“Øąµą“Øą“æą“²ąµ† ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æą“¾ąµ» ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ)", + "pageRedactionNumbers": { + "title": "ą“Ŗąµ‡ą“œąµą“•ąµ¾", + "placeholder": "(ą“‰ą“¦ą“¾. 1,2,8 ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ 4,7,12-16 ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ 2n-1)" + }, + "redactionColor": { + "title": "ą“±ąµ†ą“”ą“¾ą“•ąµą“·ąµ» ą“Øą“æą“±ą“‚" + }, + "export": "ą“•ą“Æą“±ąµą“±ąµą“®ą“¤ą“æ ą“šąµ†ą“Æąµą“Æąµą“•", + "upload": "ą“…ą“Ŗąµā€Œą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "boxRedaction": "ą“¬ąµ‹ą“•ąµą“øąµ ą“µą“°ą“šąµą“šąµ ą“±ąµ†ą“”ą“¾ą“•ąµą“·ąµ»", + "zoom": "ą“øąµ‚ą“‚", + "zoomIn": "ą“øąµ‚ą“‚ ą“‡ąµ»", + "zoomOut": "ą“øąµ‚ą“‚ ą“”ą“Ÿąµą“Ÿąµ", + "nextPage": "ą“…ą“Ÿąµą“¤ąµą“¤ ą“Ŗąµ‡ą“œąµ", + "previousPage": "ą“®ąµą“®ąµą“Ŗą“¤ąµą“¤ąµ† ą“Ŗąµ‡ą“œąµ", + "toggleSidebar": "ą“øąµˆą“”ąµā€Œą“¬ą“¾ąµ¼ ą“Ÿąµ‹ą“—ą“æąµ¾ ą“šąµ†ą“Æąµą“Æąµą“•", + "showThumbnails": "ą“²ą“˜ąµą“šą“æą“¤ąµą“°ą“™ąµą“™ąµ¾ ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“•", + "showDocumentOutline": "ą“Ŗąµą“°ą“®ą“¾ą“£ ą“°ąµ‚ą“Ŗą“°ąµ‡ą“– ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“• (ą“Žą“²ąµą“²ą“¾ ą“‡ą“Øą“™ąµą“™ą“³ąµą“‚ ą“µą“æą“•ą“øą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ą“¾ą“Øąµą“‚/ą“šąµą“°ąµą“•ąµą“•ą“¾ą“Øąµą“‚ ą“‡ą“°ą“Ÿąµą“Ÿ-ą“•ąµą“²ą“æą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“Æąµą“•)", + "showAttatchments": "ą“…ą“±ąµą“±ą“¾ą“šąµą“šąµā€Œą“®ąµ†ą“Øąµą“±ąµą“•ąµ¾ ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“•", + "showLayers": "ą“Ŗą“¾ą“³ą“æą“•ąµ¾ ą“•ą“¾ą“£ą“æą“•ąµą“•ąµą“• (ą“Žą“²ąµą“²ą“¾ ą“Ŗą“¾ą“³ą“æą“•ą“³ąµą“‚ ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æą“Æą“æą“²ąµ‡ą“•ąµą“•ąµ ą“Ŗąµą“Øą“ƒą“øą“œąµą“œą“®ą“¾ą“•ąµą“•ą“¾ąµ» ą“‡ą“°ą“Ÿąµą“Ÿ-ą“•ąµą“²ą“æą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“Æąµą“•)", + "colourPicker": "ą“Øą“æą“±ą“‚ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ą“¾ą“Øąµą“³ąµą“³ ą“‰ą“Ŗą“•ą“°ą“£ą“‚", + "findCurrentOutlineItem": "ą“Øą“æą“²ą“µą“æą“²ąµ† ą“°ąµ‚ą“Ŗą“°ąµ‡ą“–ą“¾ ą“‡ą“Øą“‚ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ąµą“•", + "applyChanges": "ą“®ą“¾ą“±ąµą“±ą“™ąµą“™ąµ¾ ą“Ŗąµą“°ą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“•" + }, + "tableExtraxt": { + "tags": "CSV,ą“Ŗą“Ÿąµą“Ÿą“æą“• ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµ½,ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“•,ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "autoSizeSplitPDF": { + "tags": "pdf,ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•,ą“Ŗąµą“°ą“®ą“¾ą“£ą“‚,ą“øą“‚ą“˜ą“Ÿą“Ø" + }, + "overlay-pdfs": { + "tags": "ą““ą“µąµ¼ą“²ąµ‡", + "header": "PDF ą“«ą“Æą“²ąµą“•ąµ¾ ą““ą“µąµ¼ą“²ąµ‡ ą“šąµ†ą“Æąµą“Æąµą“•", + "baseFile": { + "label": "ą“…ą“Ÿą“æą“øąµą“„ą“¾ą“Ø PDF ą“«ą“Æąµ½ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•" + }, + "overlayFiles": { + "label": "ą““ą“µąµ¼ą“²ąµ‡ PDF ą“«ą“Æą“²ąµą“•ąµ¾ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•" + }, + "mode": { + "label": "ą““ą“µąµ¼ą“²ąµ‡ ą“®ąµ‹ą“”ąµ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "sequential": "ą“•ąµą“°ą“®ąµ€ą“•ąµƒą“¤ ą““ą“µąµ¼ą“²ąµ‡", + "interleaved": "ą“‡ą“Ÿą“•ą“²ąµ¼ą“Øąµą“Ø ą““ą“µąµ¼ą“²ąµ‡", + "fixedRepeat": "ą“Øą“æą“¶ąµą“šą“æą“¤ ą“†ą“µąµ¼ą“¤ąµą“¤ą“Ø ą““ą“µąµ¼ą“²ąµ‡" + }, + "counts": { + "label": "ą““ą“µąµ¼ą“²ąµ‡ ą“Žą“£ąµą“£ą“‚ (ą“Øą“æą“¶ąµą“šą“æą“¤ ą“†ą“µąµ¼ą“¤ąµą“¤ą“Ø ą“®ąµ‹ą“”ą“æą“Øą“¾ą“Æą“æ)", + "placeholder": "ą“•ąµ‹ą“®ą“Æą“¾ąµ½ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“š ą“Žą“£ąµą“£ą“‚ ą“Øąµ½ą“•ąµą“• (ą“‰ą“¦ą“¾., 2,3,1)" + }, + "position": { + "label": "ą““ą“µąµ¼ą“²ąµ‡ ą“øąµą“„ą“¾ą“Øą“‚ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "foreground": "ą“®ąµąµ»ą“­ą“¾ą“—ą“‚", + "background": "ą“Ŗą“¶ąµą“šą“¾ą“¤ąµą“¤ą“²ą“‚" + }, + "submit": "ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•" + }, + "split-by-sections": { + "tags": "ą“µą“æą“­ą“¾ą“—ą“‚ ą“µą“æą“­ą“œą“Øą“‚, ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•, ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ą“®ą“¾ą“•ąµą“•ąµą“•", + "title": "ą“µą“æą“­ą“¾ą“—ą“™ąµą“™ąµ¾ ą“…ą“Øąµą“øą“°ą“æą“šąµą“šąµ PDF ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "header": "PDF ą“µą“æą“­ą“¾ą“—ą“™ąµą“™ą“³ą“¾ą“Æą“æ ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "horizontal": { + "label": "ą“¤ą“æą“°ą“¶ąµą“šąµ€ą“Ø ą“µą“æą“­ą“œą“Øą“™ąµą“™ąµ¾", + "placeholder": "ą“¤ą“æą“°ą“¶ąµą“šąµ€ą“Ø ą“µą“æą“­ą“œą“Øą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Žą“£ąµą“£ą“‚ ą“Øąµ½ą“•ąµą“•" + }, + "vertical": { + "label": "ą“²ą“‚ą“¬ ą“µą“æą“­ą“œą“Øą“™ąµą“™ąµ¾", + "placeholder": "ą“²ą“‚ą“¬ ą“µą“æą“­ą“œą“Øą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Žą“£ąµą“£ą“‚ ą“Øąµ½ą“•ąµą“•" + }, + "submit": "PDF ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "merge": "ą“’ą“°ąµŠą“±ąµą“± PDF-ą“²ąµ‡ą“•ąµą“•ąµ ą“²ą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•" + }, + "AddStampRequest": { + "tags": "ą“øąµą“±ąµą“±ą“¾ą“®ąµą“Ŗąµ, ą“šą“æą“¤ąµą“°ą“‚ ą“šąµ‡ąµ¼ą“•ąµą“•ąµą“•, ą“šą“æą“¤ąµą“°ą“‚ ą“®ą“§ąµą“Æą“¤ąµą“¤ą“æą“²ą“¾ą“•ąµą“•ąµą“•, ą“µą“¾ą“Ÿąµą“Ÿąµ¼ą“®ą“¾ąµ¼ą“•ąµą“•ąµ, PDF, ą“‰ąµ¾ą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ąµą“•, ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ą“®ą“¾ą“•ąµą“•ąµą“•", + "header": "PDF ą“øąµą“±ąµą“±ą“¾ą“®ąµą“Ŗąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "title": "PDF ą“øąµą“±ąµą“±ą“¾ą“®ąµą“Ŗąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "stampType": "ą“øąµą“±ąµą“±ą“¾ą“®ąµą“Ŗąµ ą“¤ą“°ą“‚", + "stampText": "ą“øąµą“±ąµą“±ą“¾ą“®ąµą“Ŗąµ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ", + "stampImage": "ą“øąµą“±ąµą“±ą“¾ą“®ąµą“Ŗąµ ą“šą“æą“¤ąµą“°ą“‚", + "alphabet": "ą“…ą“•ąµą“·ą“°ą“®ą“¾ą“²", + "fontSize": "ą“…ą“•ąµą“·ą“°/ą“šą“æą“¤ąµą“° ą“µą“²ąµą“Ŗąµą“Ŗą“‚", + "rotation": "ą“¤ą“æą“°ą“æą“•ąµą“•ąµ½", + "opacity": "ą“…ą“¤ą“¾ą“°ąµą“Æą“¤", + "position": "ą“øąµą“„ą“¾ą“Øą“‚", + "overrideX": "X ą“•ąµ‹ąµ¼ą“”ą“æą“Øąµ‡ą“±ąµą“±ąµ ą“®ą“¾ą“±ąµą“±ą“æą“Æąµ†ą““ąµą“¤ąµą“•", + "overrideY": "Y ą“•ąµ‹ąµ¼ą“”ą“æą“Øąµ‡ą“±ąµą“±ąµ ą“®ą“¾ą“±ąµą“±ą“æą“Æąµ†ą““ąµą“¤ąµą“•", + "customMargin": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“®ą“¾ąµ¼ą“œą“æąµ»", + "customColor": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“Øą“æą“±ą“‚", + "submit": "ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•" + }, + "removeImagePdf": { + "tags": "ą“šą“æą“¤ąµą“°ą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•,ą“Ŗąµ‡ą“œąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“™ąµą“™ąµ¾,ą“¬ą“¾ą“•ąµą“•ąµ ą“Žąµ»ą“”ąµ,ą“øąµ†ąµ¼ą“µąµ¼ ą“øąµˆą“”ąµ" + }, + "splitPdfByChapters": { + "tags": "ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•,ą“…ą“§ąµą“Æą“¾ą“Æą“™ąµą“™ąµ¾,ą“¬ąµą“•ąµą“•ąµą“®ą“¾ąµ¼ą“•ąµą“•ąµą“•ąµ¾,ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•" + }, + "validateSignature": { + "tags": "ą“’ą“Ŗąµą“Ŗąµ,ą“Ŗą“°ą“æą“¶ąµ‹ą“§ą“æą“•ąµą“•ąµą“•,ą“øą“¾ą“§ąµ‚ą“•ą“°ą“æą“•ąµą“•ąµą“•,pdf,ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ,ą“”ą“æą“œą“æą“±ąµą“±ąµ½ ą“’ą“Ŗąµą“Ŗąµ,ą“’ą“Ŗąµą“Ŗąµ ą“øą“¾ą“§ąµ‚ą“•ą“°ą“æą“•ąµą“•ąµą“•,ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“øą“¾ą“§ąµ‚ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "title": "PDF ą“’ą“Ŗąµą“Ŗąµą“•ąµ¾ ą“øą“¾ą“§ąµ‚ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "header": "ą“”ą“æą“œą“æą“±ąµą“±ąµ½ ą“’ą“Ŗąµą“Ŗąµą“•ąµ¾ ą“øą“¾ą“§ąµ‚ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "selectPDF": "ą“’ą“Ŗąµą“Ŗą“æą“Ÿąµą“Ÿ PDF ą“«ą“Æąµ½ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "submit": "ą“’ą“Ŗąµą“Ŗąµą“•ąµ¾ ą“øą“¾ą“§ąµ‚ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "results": "ą“øą“¾ą“§ąµ‚ą“•ą“°ą“£ ą“«ą“²ą“™ąµą“™ąµ¾", + "status": { + "_value": "ą“øąµą“„ą“æą“¤ą“æ", + "valid": "ą“øą“¾ą“§ąµą“µą“¾ą“£ąµ", + "invalid": "ą“…ą“øą“¾ą“§ąµą“µą“¾ą“£ąµ" + }, + "signer": "ą“’ą“Ŗąµą“Ŗą“æą“Ÿąµą“Ÿą“Æą“¾ąµ¾", + "date": "ą“¤ąµ€ą“Æą“¤ą“æ", + "reason": "ą“•ą“¾ą“°ą“£ą“‚", + "location": "ą“øąµą“„ą“²ą“‚", + "noSignatures": "ą“ˆ ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æąµ½ ą“”ą“æą“œą“æą“±ąµą“±ąµ½ ą“’ą“Ŗąµą“Ŗąµą“•ą“³ąµŠą“Øąµą“Øąµą“‚ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ą“æą“Æą“æą“²ąµą“²", + "chain": { + "invalid": "ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“¶ąµƒą“‚ą“–ą“² ą“øą“¾ą“§ąµ‚ą“•ą“°ą“£ą“‚ ą“Ŗą“°ą“¾ą“œą“Æą“Ŗąµą“Ŗąµ†ą“Ÿąµą“Ÿąµ - ą“’ą“Ŗąµą“Ŗą“æą“Ÿąµą“Ÿą“Æą“¾ą“³ąµą“Ÿąµ† ą“ą“”ą“Øąµą“±ą“æą“±ąµą“±ą“æ ą“Ŗą“°ą“æą“¶ąµ‹ą“§ą“æą“•ąµą“•ą“¾ąµ» ą“•ą““ą“æą“Æą“æą“²ąµą“²" + }, + "trust": { + "invalid": "ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“Ÿąµą“°ą“øąµą“±ąµą“±ąµ ą“øąµą“±ąµą“±ąµ‹ą“±ą“æąµ½ ą“‡ą“²ąµą“² - ą“‰ą“±ą“µą“æą“Ÿą“‚ ą“Ŗą“°ą“æą“¶ąµ‹ą“§ą“æą“•ąµą“•ą“¾ąµ» ą“•ą““ą“æą“Æą“æą“²ąµą“²" + }, + "cert": { + "expired": "ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“•ą“¾ą“²ą“¹ą“°ą“£ą“Ŗąµą“Ŗąµ†ą“Ÿąµą“Ÿąµ", + "revoked": "ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“±ą“¦ąµą“¦ą“¾ą“•ąµą“•ą“æą“Æą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ", + "info": "ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“µą“æą“¶ą“¦ą“¾ą“‚ą“¶ą“™ąµą“™ąµ¾", + "issuer": "ą“Øąµ½ą“•ą“æą“Æą“Æą“¾ąµ¾", + "subject": "ą“µą“æą“·ą“Æą“‚", + "serialNumber": "ą“øąµ€ą“°ą“æą“Æąµ½ ą“Øą“®ąµą“Ŗąµ¼", + "validFrom": "ą“®ąµą“¤ąµ½ ą“øą“¾ą“§ąµą“µą“¾ą“£ąµ", + "validUntil": "ą“µą“°ąµ† ą“øą“¾ą“§ąµą“µą“¾ą“£ąµ", + "algorithm": "ą“…ąµ½ą“—ąµ‹ą“°ą“æą“¤ą“‚", + "keySize": "ą“•ąµ€ ą“µą“²ąµą“Ŗąµą“Ŗą“‚", + "version": "ą“Ŗą“¤ą“æą“Ŗąµą“Ŗąµ", + "keyUsage": "ą“•ąµ€ ą“‰ą“Ŗą“Æąµ‹ą“—ą“‚", + "selfSigned": "ą“øąµą“µą“Æą“‚ ą“’ą“Ŗąµą“Ŗą“æą“Ÿąµą“Ÿą“¤ąµ", + "bits": "ą“¬ą“æą“±ąµą“±ąµą“•ąµ¾" + }, + "signature": { + "info": "ą“’ą“Ŗąµą“Ŗąµ ą“µą“æą“µą“°ą“™ąµą“™ąµ¾", + "_value": "ą“’ą“Ŗąµą“Ŗąµ", + "mathValid": "ą“’ą“Ŗąµą“Ŗąµ ą“—ą“£ą“æą“¤ą“¶ą“¾ą“øąµą“¤ąµą“°ą“Ŗą“°ą“®ą“¾ą“Æą“æ ą“øą“¾ą“§ąµą“µą“¾ą“£ąµ ą“Ŗą“•ąµą“·ąµ‡:" + }, + "selectCustomCert": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ ą“øąµ¼ą“Ÿąµą“Ÿą“æą“«ą“æą“•ąµą“•ą“±ąµą“±ąµ ą“«ą“Æąµ½ X.509 (ą““ą“Ŗąµą“·ą“£ąµ½)" + }, + "replace-color": { + "title": "ą“Øą“æą“±ą“‚-ą“®ą“¾ą“±ąµą“±ąµą“•-ą“µą“æą“Ŗą“°ąµ€ą“¤ą“®ą“¾ą“•ąµą“•ąµą“•", + "header": "PDF-ą“²ąµ† ą“Øą“æą“±ą“‚ ą“®ą“¾ą“±ąµą“±ąµą“•-ą“µą“æą“Ŗą“°ąµ€ą“¤ą“®ą“¾ą“•ąµą“•ąµą“•", + "selectText": { + "1": "ą“Øą“æą“±ą“‚ ą“®ą“¾ą“±ąµą“±ąµą“Øąµą“Øą“¤ą“æą“Øąµ‹ ą“µą“æą“Ŗą“°ąµ€ą“¤ą“®ą“¾ą“•ąµą“•ąµą“Øąµą“Øą“¤ą“æą“Øąµ‹ ą“‰ą“³ąµą“³ ą““ą“Ŗąµą“·ą“Øąµą“•ąµ¾", + "2": "ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æ (ą“øąµą“„ą“æą“°ą“øąµą“„ą“æą“¤ą“æ ą“‰ą“Æąµ¼ą“Øąµą“Ø ą“•ąµ‹ąµŗą“Ÿąµą“°ą“¾ą“øąµą“±ąµą“±ąµ ą“Øą“æą“±ą“™ąµą“™ąµ¾)", + "3": "ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ą“‚ (ą“‡ą“·ąµą“Ÿą“¾ą“Øąµą“øąµƒą“¤ą“®ą“¾ą“•ąµą“•ą“æą“Æ ą“Øą“æą“±ą“™ąµą“™ąµ¾)", + "4": "ą“Ŗąµ‚ąµ¼ą“£ąµą“£-ą“µą“æą“Ŗą“°ąµ€ą“¤ą“‚ (ą“Žą“²ąµą“²ą“¾ ą“Øą“æą“±ą“™ąµą“™ą“³ąµą“‚ ą“µą“æą“Ŗą“°ąµ€ą“¤ą“®ą“¾ą“•ąµą“•ąµą“•)", + "5": "ą“‰ą“Æąµ¼ą“Øąµą“Ø ą“•ąµ‹ąµŗą“Ÿąµą“°ą“¾ą“øąµą“±ąµą“±ąµ ą“µąµ¼ą“£ąµą“£ ą““ą“Ŗąµą“·ą“Øąµą“•ąµ¾", + "6": "ą“•ą“±ąµą“¤ąµą“¤ ą“Ŗą“¶ąµą“šą“¾ą“¤ąµą“¤ą“²ą“¤ąµą“¤ą“æąµ½ ą“µąµ†ą“³ąµą“¤ąµą“¤ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ", + "7": "ą“µąµ†ą“³ąµą“¤ąµą“¤ ą“Ŗą“¶ąµą“šą“¾ą“¤ąµą“¤ą“²ą“¤ąµą“¤ą“æąµ½ ą“•ą“±ąµą“¤ąµą“¤ ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ", + "8": "ą“•ą“±ąµą“¤ąµą“¤ ą“Ŗą“¶ąµą“šą“¾ą“¤ąµą“¤ą“²ą“¤ąµą“¤ą“æąµ½ ą“®ą“žąµą“ž ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ", + "9": "ą“•ą“±ąµą“¤ąµą“¤ ą“Ŗą“¶ąµą“šą“¾ą“¤ąµą“¤ą“²ą“¤ąµą“¤ą“æąµ½ ą“Ŗą“šąµą“š ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ", + "10": "ą“Ÿąµ†ą“•ąµą“øąµą“±ąµą“±ąµ ą“Øą“æą“±ą“‚ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "11": "ą“Ŗą“¶ąµą“šą“¾ą“¤ąµą“¤ą“² ą“Øą“æą“±ą“‚ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•" + }, + "submit": "ą“®ą“¾ą“±ąµą“±ąµą“•" + }, + "replaceColorPdf": { + "tags": "ą“Øą“æą“±ą“‚ ą“®ą“¾ą“±ąµą“±ąµą“•,ą“Ŗąµ‡ą“œąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“™ąµą“™ąµ¾,ą“¬ą“¾ą“•ąµą“•ąµ ą“Žąµ»ą“”ąµ,ą“øąµ†ąµ¼ą“µąµ¼ ą“øąµˆą“”ąµ" + }, + "login": { + "title": "ą“øąµˆąµ» ą“‡ąµ» ą“šąµ†ą“Æąµą“Æąµą“•", + "header": "ą“øąµˆąµ» ą“‡ąµ» ą“šąµ†ą“Æąµą“Æąµą“•", + "signin": "ą“øąµˆąµ» ą“‡ąµ» ą“šąµ†ą“Æąµą“Æąµą“•", + "rememberme": "ą“Žą“Øąµą“Øąµ† ą““ąµ¼ą“•ąµą“•ąµą“•", + "invalid": "ą“…ą“øą“¾ą“§ąµą“µą“¾ą“Æ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒą“Øą“¾ą“®ą“‚ ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ.", + "locked": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“…ą“•ąµą“•ąµ—ą“£ąµą“Ÿąµ ą“²ąµ‹ą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“¤ą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ.", + "signinTitle": "ą“¦ą“Æą“µą“¾ą“Æą“æ ą“øąµˆąµ» ą“‡ąµ» ą“šąµ†ą“Æąµą“Æąµą“•", + "ssoSignIn": "ą“øą“æą“‚ą“—ą“æąµ¾ ą“øąµˆąµ»-ą““ąµŗ ą“µą““ą“æ ą“²ąµ‹ą“—ą“æąµ» ą“šąµ†ą“Æąµą“Æąµą“•", + "oAuth2AutoCreateDisabled": "OAUTH2 ą““ą“Ÿąµą“Ÿąµ‹-ą“•ąµą“°ą“æą“Æąµ‡ą“±ąµą“±ąµ ą“Æąµ‚ą“øąµ¼ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“°ą“¹ą“æą“¤ą“®ą“¾ą“•ąµą“•ą“æ", + "oAuth2AdminBlockedUser": "ą“°ą“œą“æą“øąµą“±ąµą“±ąµ¼ ą“šąµ†ą“Æąµą“Æą“¾ą“¤ąµą“¤ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“•ąµą“•ą“³ąµą“Ÿąµ† ą“°ą“œą“æą“øąµą“Ÿąµą“°ąµ‡ą“·ą“Øąµ‹ ą“²ąµ‹ą“—ą“æąµ» ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øą“¤ąµ‹ ą“Øą“æą“²ą“µą“æąµ½ ą“¤ą“Ÿą“žąµą“žą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ. ą“¦ą“Æą“µą“¾ą“Æą“æ ą“…ą“”ąµą“®ą“æą“Øą“æą“øąµą“Ÿąµą“°ąµ‡ą“±ąµą“±ą“±ąµą“®ą“¾ą“Æą“æ ą“¬ą“Øąµą“§ą“Ŗąµą“Ŗąµ†ą“Ÿąµą“•.", + "oauth2RequestNotFound": "ą“…ą“‚ą“—ąµ€ą“•ą“¾ą“° ą“…ą“­ąµą“Æąµ¼ą“¤ąµą“„ą“Ø ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ą“æą“Æą“æą“²ąµą“²", + "oauth2InvalidUserInfoResponse": "ą“…ą“øą“¾ą“§ąµą“µą“¾ą“Æ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒ ą“µą“æą“µą“° ą“Ŗąµą“°ą“¤ą“æą“•ą“°ą“£ą“‚", + "oauth2invalidRequest": "ą“…ą“øą“¾ą“§ąµą“µą“¾ą“Æ ą“…ą“­ąµą“Æąµ¼ą“¤ąµą“„ą“Ø", + "oauth2AccessDenied": "ą“Ŗąµą“°ą“µąµ‡ą“¶ą“Øą“‚ ą“Øą“æą“·ąµ‡ą“§ą“æą“šąµą“šąµ", + "oauth2InvalidTokenResponse": "ą“…ą“øą“¾ą“§ąµą“µą“¾ą“Æ ą“Ÿąµ‹ą“•ąµą“•ąµŗ ą“Ŗąµą“°ą“¤ą“æą“•ą“°ą“£ą“‚", + "oauth2InvalidIdToken": "ą“…ą“øą“¾ą“§ąµą“µą“¾ą“Æ ą“ą“”ą“æ ą“Ÿąµ‹ą“•ąµą“•ąµŗ", + "relyingPartyRegistrationNotFound": "ą“±ą“æą“²ą“Æą“æą“‚ą“—ąµ ą“Ŗą“¾ąµ¼ą“Ÿąµą“Ÿą“æ ą“°ą“œą“æą“øąµą“Ÿąµą“°ąµ‡ą“·ąµ» ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ą“æą“Æą“æą“²ąµą“²", + "userIsDisabled": "ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“µąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“°ą“¹ą“æą“¤ą“®ą“¾ą“•ąµą“•ą“æ, ą“ˆ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒą“Øą“¾ą“®ą“‚ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµą“³ąµą“³ ą“²ąµ‹ą“—ą“æąµ» ą“Øą“æą“²ą“µą“æąµ½ ą“¤ą“Ÿą“žąµą“žą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ. ą“¦ą“Æą“µą“¾ą“Æą“æ ą“…ą“”ąµą“®ą“æą“Øą“æą“øąµą“Ÿąµą“°ąµ‡ą“±ąµą“±ą“±ąµą“®ą“¾ą“Æą“æ ą“¬ą“Øąµą“§ą“Ŗąµą“Ŗąµ†ą“Ÿąµą“•.", + "alreadyLoggedIn": "ą“Øą“æą“™ąµą“™ąµ¾ ą“‡ą“¤ą“æą“Øą“•ą“‚ ą“²ąµ‹ą“—ą“æąµ» ą“šąµ†ą“Æąµą“¤ą“æą“Ÿąµą“Ÿąµą“£ąµą“Ÿąµ", + "alreadyLoggedIn2": "ą“‰ą“Ŗą“•ą“°ą“£ą“™ąµą“™ą“³ą“æąµ½. ą“¦ą“Æą“µą“¾ą“Æą“æ ą“‰ą“Ŗą“•ą“°ą“£ą“™ąµą“™ą“³ą“æąµ½ ą“Øą“æą“Øąµą“Øąµ ą“²ąµ‹ą“—ąµ ą“”ą“Ÿąµą“Ÿąµ ą“šąµ†ą“Æąµą“¤ąµ ą“µąµ€ą“£ąµą“Ÿąµą“‚ ą“¶ąµą“°ą“®ą“æą“•ąµą“•ąµą“•.", + "toManySessions": "ą“Øą“æą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“µą“³ą“°ąµ†ą“Æą“§ą“æą“•ą“‚ ą“øą“œąµ€ą“µ ą“øąµ†ą“·ą“Øąµą“•ąµ¾ ą“‰ą“£ąµą“Ÿąµ", + "logoutMessage": "ą“Øą“æą“™ąµą“™ąµ¾ ą“²ąµ‹ą“—ąµ ą“”ą“Ÿąµą“Ÿąµ ą“šąµ†ą“Æąµą“¤ąµ." + }, + "pdfToSinglePage": { + "title": "PDF ą“’ą“°ąµŠą“±ąµą“± ą“Ŗąµ‡ą“œą“æą“²ąµ‡ą“•ąµą“•ąµ", + "header": "PDF ą“’ą“°ąµŠą“±ąµą“± ą“Ŗąµ‡ą“œą“æą“²ąµ‡ą“•ąµą“•ąµ", + "submit": "ą“’ą“°ąµŠą“±ąµą“± ą“Ŗąµ‡ą“œą“æą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•" + }, + "pageExtracter": { + "title": "ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "header": "ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "submit": "ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "placeholder": "(ą“‰ą“¦ą“¾. 1,2,8 ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ 4,7,12-16 ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ 2n-1)" + }, + "sanitizePDF": { + "title": "PDF ą“¶ąµą“¦ąµą“§ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "header": "ą“’ą“°ąµ PDF ą“«ą“Æąµ½ ą“¶ąµą“¦ąµą“§ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "selectText": { + "1": "ą“œą“¾ą“µą“¾ą“øąµą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“™ąµą“™ąµ¾ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "2": "ą“‰ąµ¾ą“šąµą“šąµ‡ąµ¼ą“¤ąµą“¤ ą“«ą“Æą“²ąµą“•ąµ¾ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "3": "XMP ą“®ąµ†ą“±ąµą“±ą“¾ą“”ą“¾ą“±ąµą“± ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "4": "ą“²ą“æą“™ąµą“•ąµą“•ąµ¾ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "5": "ą“…ą“•ąµą“·ą“°ą“™ąµą“™ąµ¾ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "6": "ą“Ŗąµą“°ą“®ą“¾ą“£ ą“µą“æą“µą“° ą“®ąµ†ą“±ąµą“±ą“¾ą“”ą“¾ą“±ąµą“± ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "submit": "PDF ą“¶ąµą“¦ąµą“§ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•" + }, + "adjustContrast": { + "title": "ą“•ąµ‹ąµŗą“Ÿąµą“°ą“¾ą“øąµą“±ąµą“±ąµ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "header": "ą“•ąµ‹ąµŗą“Ÿąµą“°ą“¾ą“øąµą“±ąµą“±ąµ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "contrast": "ą“•ąµ‹ąµŗą“Ÿąµą“°ą“¾ą“øąµą“±ąµą“±ąµ:", + "brightness": "ą“¤ąµ†ą“³ą“æą“šąµą“šą“‚:", + "saturation": "ą“øą“¾ą“šąµą“šąµą“±ąµ‡ą“·ąµ»:", + "download": "ą“”ąµ—ąµŗą“²ąµ‹ą“”ąµ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "compress": { + "title": "ą“•ą“‚ą“Ŗąµą“°ą“øąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "header": "PDF ą“•ą“‚ą“Ŗąµą“°ą“øąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "credit": "ą“ˆ ą“øąµ‡ą“µą“Øą“‚ PDF ą“•ą“‚ą“Ŗąµą“°ą“øąµ/ą“’ą“Ŗąµą“±ąµą“±ą“æą“®ąµˆą“øąµ‡ą“·ą“Øą“¾ą“Æą“æ qpdf ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ.", + "grayscale": { + "label": "ą“•ą“‚ą“Ŗąµą“°ą“·ą“Øą“¾ą“Æą“æ ą“—ąµą“°ąµ‡ą“øąµā€Œą“•ąµ†ą“Æą“æąµ½ ą“Ŗąµą“°ą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“•" + }, + "selectText": { + "1": { + "_value": "ą“•ą“‚ą“Ŗąµą“°ą“·ąµ» ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“£ą“™ąµą“™ąµ¾", + "1": "1-3 PDF ą“•ą“‚ą“Ŗąµą“°ą“·ąµ»,
4-6 ą“²ąµˆą“±ąµą“±ąµ ą“‡ą“®ąµ‡ą“œąµ ą“•ą“‚ą“Ŗąµą“°ą“·ąµ»,
7-9 ą“¤ąµ€ą“µąµą“°ą“®ą“¾ą“Æ ą“‡ą“®ąµ‡ą“œąµ ą“•ą“‚ą“Ŗąµą“°ą“·ąµ» ą“šą“æą“¤ąµą“°ą“¤ąµą“¤ą“æą“Øąµą“±ąµ† ą“—ąµą“£ą“Øą“æą“²ą“µą“¾ą“°ą“‚ ą“—ą“£ąµą“Æą“®ą“¾ą“Æą“æ ą“•ąµą“±ą“Æąµą“•ąµą“•ąµą“‚" + }, + "2": "ą“’ą“Ŗąµą“±ąµą“±ą“æą“®ąµˆą“øąµ‡ą“·ąµ» ą“Øą“æą“²:", + "4": "ą““ą“Ÿąµą“Ÿąµ‹ ą“®ąµ‹ą“”ąµ - PDF ą“•ąµƒą“¤ąµą“Æą“®ą“¾ą“Æ ą“µą“²ąµą“Ŗąµą“Ŗą“¤ąµą“¤ą“æąµ½ ą“²ą“­ą“æą“•ąµą“•ąµą“Øąµą“Øą“¤ą“æą“Øąµ ą“—ąµą“£ą“Øą“æą“²ą“µą“¾ą“°ą“‚ ą“øąµą“µą“Æą“‚ ą“•ąµą“°ą“®ąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ", + "5": "ą“Ŗąµą“°ą“¤ąµ€ą“•ąµą“·ą“æą“•ąµą“•ąµą“Øąµą“Ø PDF ą“µą“²ąµą“Ŗąµą“Ŗą“‚ (ą“‰ą“¦ą“¾. 25MB, 10.8MB, 25KB)" + }, + "submit": "ą“•ą“‚ą“Ŗąµą“°ą“øąµ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "decrypt": { + "passwordPrompt": "ą“ˆ ą“«ą“Æąµ½ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµ ą“øą“‚ą“°ą“•ąµą“·ą“æą“šąµą“šą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ. ą“¦ą“Æą“µą“¾ą“Æą“æ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“Øąµ½ą“•ąµą“•:", + "cancelled": "PDF-ą“Øą“¾ą“Æąµą“³ąµą“³ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“±ą“¦ąµą“¦ą“¾ą“•ąµą“•ą“æ: {0}", + "noPassword": "ą“Žąµ»ą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“¤ PDF-ą“Øą“¾ą“Æą“æ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“Øąµ½ą“•ą“æą“Æą“æą“Ÿąµą“Ÿą“æą“²ąµą“²: {0}", + "invalidPassword": "ą“¦ą“Æą“µą“¾ą“Æą“æ ą“¶ą“°ą“æą“Æą“¾ą“Æ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“šąµą“šąµ ą“µąµ€ą“£ąµą“Ÿąµą“‚ ą“¶ąµą“°ą“®ą“æą“•ąµą“•ąµą“•.", + "invalidPasswordHeader": "PDF-ą“Øą“¾ą“Æą“æ ą“¤ąµ†ą“±ąµą“±ą“¾ą“Æ ą“Ŗą“¾ą“øąµā€Œą“µąµ‡ą“”ąµ ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“Ŗą“æą“Øąµą“¤ąµą“£ą“Æąµą“•ąµą“•ą“¾ą“¤ąµą“¤ ą“Žąµ»ą“•ąµą“°ą“æą“Ŗąµą“·ąµ»: {0}", + "unexpectedError": "ą“«ą“Æąµ½ ą“Ŗąµą“°ąµ‹ą“øą“øąµą“øąµ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øą“¤ą“æąµ½ ą“’ą“°ąµ ą“Ŗą“æą“¶ą“•ąµ ą“øą“‚ą“­ą“µą“æą“šąµą“šąµ. ą“¦ą“Æą“µą“¾ą“Æą“æ ą“µąµ€ą“£ąµą“Ÿąµą“‚ ą“¶ąµą“°ą“®ą“æą“•ąµą“•ąµą“•.", + "serverError": "ą“”ąµ€ą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“®ąµą“Ŗąµ‹ąµ¾ ą“øąµ†ąµ¼ą“µąµ¼ ą“Ŗą“æą“¶ą“•ąµ: {0}", + "success": "ą“«ą“Æąµ½ ą“µą“æą“œą“Æą“•ą“°ą“®ą“¾ą“Æą“æ ą“”ąµ€ą“•ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“¤ąµ." + }, + "multiTool-advert": { + "message": "ą“ˆ ą“øą“µą“æą“¶ąµ‡ą“·ą“¤ ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† ą“®ąµ¾ą“Ÿąµą“Ÿą“æ-ą“Ÿąµ‚ąµ¾ ą“Ŗąµ‡ą“œą“æą“²ąµą“‚ ą“²ą“­ąµą“Æą“®ą“¾ą“£ąµ. ą“®ąµ†ą“šąµą“šą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ą“æą“Æ ą“Ŗąµ‡ą“œąµ-ą“¬ąµˆ-ą“Ŗąµ‡ą“œąµ ą“Æąµą“ą“Æąµą“•ąµą“•ąµą“‚ ą“…ą“§ą“æą“• ą“øą“µą“æą“¶ąµ‡ą“·ą“¤ą“•ąµ¾ą“•ąµą“•ąµą“®ą“¾ą“Æą“æ ą“‡ą“¤ąµ ą“Ŗą“°ą“æą“¶ąµ‹ą“§ą“æą“•ąµą“•ąµą“•!" + }, + "pageRemover": { + "title": "ą“Ŗąµ‡ą“œąµ ą“Øąµ€ą“•ąµą“•ą“‚ą“šąµ†ą“Æąµą“Æąµ½ ą“‰ą“Ŗą“•ą“°ą“£ą“‚", + "header": "PDF ą“Ŗąµ‡ą“œąµ ą“Øąµ€ą“•ąµą“•ą“‚ą“šąµ†ą“Æąµą“Æąµ½ ą“‰ą“Ŗą“•ą“°ą“£ą“‚", + "pagesToDelete": "ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ąµ‡ą“£ąµą“Ÿ ą“Ŗąµ‡ą“œąµą“•ąµ¾ (ą“Ŗąµ‡ą“œąµ ą“Øą“®ąµą“Ŗą“±ąµą“•ą“³ąµą“Ÿąµ† ą“•ąµ‹ą“®ą“Æą“¾ąµ½ ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“š ą“²ą“æą“øąµą“±ąµą“±ąµ ą“Øąµ½ą“•ąµą“•) :", + "submit": "ą“Ŗąµ‡ą“œąµą“•ąµ¾ ą“‡ą“²ąµą“²ą“¾ą“¤ą“¾ą“•ąµą“•ąµą“•", + "placeholder": "(ą“‰ą“¦ą“¾. 1,2,6 ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ 1-10,15-30)" + }, + "imageToPDF": { + "title": "ą“šą“æą“¤ąµą“°ą“‚ PDF-ą“²ąµ‡ą“•ąµą“•ąµ", + "header": "ą“šą“æą“¤ąµą“°ą“‚ PDF-ą“²ąµ‡ą“•ąµą“•ąµ", + "submit": "ą“Ŗą“°ą“æą“µąµ¼ą“¤ąµą“¤ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "selectLabel": "ą“šą“æą“¤ąµą“°ą“‚ ą“«ą“æą“±ąµą“±ąµ ą““ą“Ŗąµą“·ą“Øąµą“•ąµ¾", + "fillPage": "ą“Ŗąµ‡ą“œąµ ą“Øą“æą“±ą“Æąµą“•ąµą“•ąµą“•", + "fitDocumentToImage": "ą“Ŗąµ‡ą“œąµ ą“šą“æą“¤ąµą“°ą“¤ąµą“¤ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“«ą“æą“±ąµą“±ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "maintainAspectRatio": "ą“µąµ€ą“•ąµą“·ą“£ą“¾ą“Øąµą“Ŗą“¾ą“¤ą“‚ ą“Øą“æą“²ą“Øą“æąµ¼ą“¤ąµą“¤ąµą“•", + "selectText": { + "2": "PDF ą“øąµą“µą“Æą“‚ ą“¤ą“æą“°ą“æą“•ąµą“•ąµą“•", + "3": "ą“®ąµ¾ą“Ÿąµą“Ÿą“æ ą“«ą“Æąµ½ ą“²ąµ‹ą“œą“æą“•ąµ (ą“’ą“Øąµą“Øą“æą“²ą“§ą“æą“•ą“‚ ą“šą“æą“¤ąµą“°ą“™ąµą“™ą“³ąµą“®ą“¾ą“Æą“æ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“•ąµą“•ąµą“®ąµą“Ŗąµ‹ąµ¾ ą“®ą“¾ą“¤ąµą“°ą“‚ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“•ąµą“·ą“®ą“®ą“¾ą“•ąµą“‚)", + "4": "ą“’ą“°ąµŠą“±ąµą“± PDF-ą“²ąµ‡ą“•ąµą“•ąµ ą“²ą“Æą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•", + "5": "ą“µąµ‡ą“±ą“æą“Ÿąµą“Ÿ PDF-ą“•ą“³ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“®ą“¾ą“±ąµą“±ąµą“•" + } + }, + "PDFToCSV": { + "title": "PDF CSV-ą“²ąµ‡ą“•ąµą“•ąµ", + "header": "PDF CSV-ą“²ąµ‡ą“•ąµą“•ąµ", + "prompt": "ą“Ŗą“Ÿąµą“Ÿą“æą“• ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ą“¾ąµ» ą“Ŗąµ‡ą“œąµ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "submit": "ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“•" + }, + "split-by-size-or-count": { + "title": "ą“µą“²ąµą“Ŗąµą“Ŗą“‚ ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“Žą“£ąµą“£ą“‚ ą“…ą“Øąµą“øą“°ą“æą“šąµą“šąµ PDF ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "header": "ą“µą“²ąµą“Ŗąµą“Ŗą“‚ ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“Žą“£ąµą“£ą“‚ ą“…ą“Øąµą“øą“°ą“æą“šąµą“šąµ PDF ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "type": { + "label": "ą“µą“æą“­ą“œą“Ø ą“¤ą“°ą“‚ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "size": "ą“µą“²ąµą“Ŗąµą“Ŗą“‚ ą“…ą“Øąµą“øą“°ą“æą“šąµą“šąµ", + "pageCount": "ą“Ŗąµ‡ą“œąµ ą“Žą“£ąµą“£ą“‚ ą“…ą“Øąµą“øą“°ą“æą“šąµą“šąµ", + "docCount": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Žą“£ąµą“£ą“‚ ą“…ą“Øąµą“øą“°ą“æą“šąµą“šąµ" + }, + "value": { + "label": "ą“®ąµ‚ą“²ąµą“Æą“‚ ą“Øąµ½ą“•ąµą“•", + "placeholder": "ą“µą“²ąµą“Ŗąµą“Ŗą“‚ (ą“‰ą“¦ą“¾., 2MB ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ 3KB) ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“Žą“£ąµą“£ą“‚ (ą“‰ą“¦ą“¾., 5) ą“Øąµ½ą“•ąµą“•" + }, + "submit": "ą“øą“®ąµ¼ą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“•" + }, + "printFile": { + "title": "ą“«ą“Æąµ½ ą“…ą“šąµą“šą“Ÿą“æą“•ąµą“•ąµą“•", + "header": "ą“Ŗąµą“°ą“æą“Øąµą“±ą“±ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“«ą“Æąµ½ ą“…ą“šąµą“šą“Ÿą“æą“•ąµą“•ąµą“•", + "selectText": { + "1": "ą“…ą“šąµą“šą“Ÿą“æą“•ąµą“•ąµ‡ą“£ąµą“Ÿ ą“«ą“Æąµ½ ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“•", + "2": "ą“Ŗąµą“°ą“æą“Øąµą“±ąµ¼ ą“Ŗąµ‡ą“°ąµ ą“Øąµ½ą“•ąµą“•" + }, + "submit": "ą“…ą“šąµą“šą“Ÿą“æą“•ąµą“•ąµą“•" + }, + "licenses": { + "nav": "ą“²ąµˆą“øąµ»ą“øąµą“•ąµ¾", + "title": "ą“®ąµ‚ą“Øąµą“Øą“¾ą“‚ ą“•ą“•ąµą“·ą“æ ą“²ąµˆą“øąµ»ą“øąµą“•ąµ¾", + "header": "ą“®ąµ‚ą“Øąµą“Øą“¾ą“‚ ą“•ą“•ąµą“·ą“æ ą“²ąµˆą“øąµ»ą“øąµą“•ąµ¾", + "module": "ą“˜ą“Ÿą“•ą“‚", + "version": "ą“Ŗą“¤ą“æą“Ŗąµą“Ŗąµ", + "license": "ą“²ąµˆą“øąµ»ą“øąµ" + }, + "survey": { + "nav": "ą“øąµ¼ą“µąµ‡", + "title": "ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ-PDF ą“øąµ¼ą“µąµ‡", + "description": "ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ-PDF-ą“Øąµ ą“Ÿąµą“°ą“¾ą“•ąµą“•ą“æą“‚ą“—ąµ ą“‡ą“²ąµą“², ą“…ą“¤ą“æą“Øą“¾ąµ½ ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ-PDF ą“®ąµ†ą“šąµą“šą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ąµą“Øąµą“Øą“¤ą“æą“Øąµ ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“•ąµą“•ą“³ą“æąµ½ ą“Øą“æą“Øąµą“Øąµ ą“•ąµ‡ąµ¾ą“•ąµą“•ą“¾ąµ» ą“žą“™ąµą“™ąµ¾ ą“†ą“—ąµą“°ą“¹ą“æą“•ąµą“•ąµą“Øąµą“Øąµ!", + "changes": "ą“…ą“µą“øą“¾ą“Ø ą“øąµ¼ą“µąµ‡ą“Æąµą“•ąµą“•ąµ ą“¶ąµ‡ą“·ą“‚ ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ-PDF ą“®ą“¾ą“±ą“æą“Æą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ! ą“•ąµ‚ą“Ÿąµą“¤ąµ½ ą“µą“æą“µą“°ą“™ąµą“™ąµ¾ą“•ąµą“•ą“¾ą“Æą“æ ą“¦ą“Æą“µą“¾ą“Æą“æ ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† ą“¬ąµą“²ąµ‹ą“—ąµ ą“Ŗąµ‹ą“øąµą“±ąµą“±ąµ ą“‡ą“µą“æą“Ÿąµ† ą“Ŗą“°ą“æą“¶ąµ‹ą“§ą“æą“•ąµą“•ąµą“•:", + "changes2": "ą“ˆ ą“®ą“¾ą“±ąµą“±ą“™ąµą“™ą“³ąµ‹ą“Ÿąµ† ą“žą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“Ŗą“£ą“®ą“Ÿą“šąµą“šąµą“³ąµą“³ ą“¬ą“æą“øą“æą“Øą“øąµ ą“Ŗą“æą“Øąµą“¤ąµą“£ą“Æąµą“‚ ą“«ą“£ąµą“Ÿą“æą“‚ą“—ąµą“‚ ą“²ą“­ą“æą“•ąµą“•ąµą“Øąµą“Øąµ", + "please": "ą“¦ą“Æą“µą“¾ą“Æą“æ ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† ą“øąµ¼ą“µąµ‡ ą“Žą“Ÿąµą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“Ŗą“°ą“æą“—ą“£ą“æą“•ąµą“•ąµą“•!", + "disabled": "(ą“øąµ¼ą“µąµ‡ ą“Ŗąµ‹ą“Ŗąµą“Ŗąµą“…ą“Ŗąµą“Ŗąµ ą“¤ąµą“Ÿąµ¼ą“Øąµą“Øąµą“³ąµą“³ ą“…ą“Ŗąµā€Œą“”ąµ‡ą“±ąµą“±ąµą“•ą“³ą“æąµ½ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“°ą“¹ą“æą“¤ą“®ą“¾ą“•ąµą“•ąµą“‚, ą“Žą“Øąµą“Øą“¾ąµ½ ą“Ŗąµ‡ą“œą“æą“Øąµą“±ąµ† ą“¤ą“¾ą““ąµ† ą“²ą“­ąµą“Æą“®ą“¾ą“•ąµą“‚)", + "button": "ą“øąµ¼ą“µąµ‡ ą“Žą“Ÿąµą“•ąµą“•ąµą“•", + "dontShowAgain": "ą“µąµ€ą“£ąµą“Ÿąµą“‚ ą“•ą“¾ą“£ą“æą“•ąµą“•ą“°ąµą“¤ąµ", + "meeting": { + "1": "ą“Øą“æą“™ąµą“™ąµ¾ ą“œąµ‹ą“²ą“æą“øąµą“„ą“²ą“¤ąµą“¤ąµ ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ PDF ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“•ą“Æą“¾ą“£ąµ†ą“™ąµą“•ą“æąµ½, ą“Øą“æą“™ąµą“™ą“³ąµą“®ą“¾ą“Æą“æ ą“øą“‚ą“øą“¾ą“°ą“æą“•ąµą“•ą“¾ąµ» ą“žą“™ąµą“™ąµ¾ ą“†ą“—ąµą“°ą“¹ą“æą“•ąµą“•ąµą“Øąµą“Øąµ. 15 ą“®ą“æą“Øą“æą“±ąµą“±ąµ ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ąµƒ ą“•ą“£ąµą“Ÿąµ†ą“¤ąµą“¤ąµ½ ą“øąµ†ą“·ą“Øąµ ą“Ŗą“•ą“°ą“®ą“¾ą“Æą“æ ą“žą“™ąµą“™ąµ¾ ą“øą“¾ą“™ąµą“•ąµ‡ą“¤ą“æą“• ą“Ŗą“æą“Øąµą“¤ąµą“£ą“¾ ą“øąµ†ą“·ą“Øąµą“•ąµ¾ ą“µą“¾ą“—ąµą“¦ą“¾ą“Øą“‚ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øąµ.", + "2": "ą“‡ą“¤ąµŠą“°ąµ ą“…ą“µą“øą“°ą“®ą“¾ą“£ąµ:", + "3": "ą“µą“æą“Øąµą“Æą“¾ą“øą“‚, ą“øą“‚ą“Æąµ‹ą“œą“Øą“‚, ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“Ÿąµą“°ą“¬ą“æąµ¾ą“·ąµ‚ą“Ÿąµą“Ÿą“æą“‚ą“—ąµ ą“Žą“Øąµą“Øą“æą“µą“Æą“æąµ½ ą“øą“¹ą“¾ą“Æą“‚ ą“Øąµ‡ą“Ÿąµą“•", + "4": "ą“Ŗąµą“°ą“•ą“Ÿą“Øą“‚, ą“Žą“”ąµą“œąµ ą“•ąµ‡ą“øąµą“•ąµ¾, ą“«ąµ€ą“šąµą“šąµ¼ ą“µą“æą“Ÿą“µąµą“•ąµ¾ ą“Žą“Øąµą“Øą“æą“µą“Æąµ†ą“•ąµą“•ąµą“±ą“æą“šąµą“šąµ ą“Øąµ‡ą“°ą“æą“Ÿąµą“Ÿąµą“³ąµą“³ ą“«ąµ€ą“”ąµā€Œą“¬ą“¾ą“•ąµą“•ąµ ą“Øąµ½ą“•ąµą“•", + "5": "ą“Æą“„ą“¾ąµ¼ą“¤ąµą“„ ą“²ąµ‹ą“• ą“Žą“Øąµą“±ąµ¼ą“Ŗąµą“°ąµˆą“øąµ ą“‰ą“Ŗą“Æąµ‹ą“—ą“¤ąµą“¤ą“æą“Øą“¾ą“Æą“æ ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ PDF ą“Ŗą“°ą“æą“·ąµą“•ą“°ą“æą“•ąµą“•ą“¾ąµ» ą“žą“™ąµą“™ą“³ąµ† ą“øą“¹ą“¾ą“Æą“æą“•ąµą“•ąµą“•", + "6": "ą“Øą“æą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“¤ą“¾ąµ½ą“Ŗąµą“Ŗą“°ąµą“Æą“®ąµą“£ąµą“Ÿąµ†ą“™ąµą“•ą“æąµ½, ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Ÿąµ€ą“®ąµą“®ą“¾ą“Æą“æ ą“Øąµ‡ą“°ą“æą“Ÿąµą“Ÿąµ ą“øą“®ą“Æą“‚ ą“¬ąµą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“Æą“¾ą“‚. (ą“‡ą“‚ą“—ąµą“²ąµ€ą“·ąµ ą“øą“‚ą“øą“¾ą“°ą“æą“•ąµą“•ąµą“Øąµą“Øą“µąµ¼ ą“®ą“¾ą“¤ąµą“°ą“‚)", + "7": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“‰ą“Ŗą“Æąµ‹ą“— ą“•ąµ‡ą“øąµą“•ą“³ą“æą“²ąµ‡ą“•ąµą“•ąµ ą“†ą““ą“¤ąµą“¤ą“æąµ½ ą“‡ą“±ą“™ąµą“™ą“æą“šąµą“šąµ†ą“²ąµą“²ą“¾ą“Øąµą“‚ ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ PDF ą“•ąµ‚ą“Ÿąµą“¤ąµ½ ą“®ą“æą“•ą“šąµą“šą“¤ą“¾ą“•ąµą“•ą“¾ą“Øąµą“‚ ą“žą“™ąµą“™ąµ¾ ą“†ą“•ą“¾ą“‚ą“•ąµą“·ą“Æąµ‹ą“Ÿąµ† ą“•ą“¾ą“¤ąµą“¤ą“æą“°ą“æą“•ąµą“•ąµą“Øąµą“Øąµ!", + "notInterested": "ą“’ą“°ąµ ą“¬ą“æą“øą“æą“Øą“øąµą“øąµ ą“…ą“²ąµą“² ą“•ąµ‚ą“Ÿą“¾ą“¤ąµ†/ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½ ą“’ą“°ąµ ą“®ąµ€ą“±ąµą“±ą“æą“‚ą“—ą“æąµ½ ą“¤ą“¾ąµ½ą“Ŗąµą“Ŗą“°ąµą“Æą“®ą“æą“²ąµą“²ąµ‡?", + "button": "ą“®ąµ€ą“±ąµą“±ą“æą“‚ą“—ąµ ą“¬ąµą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“Æąµą“•" + } + }, + "removeImage": { + "title": "ą“šą“æą“¤ąµą“°ą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "header": "ą“šą“æą“¤ąµą“°ą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "removeImage": "ą“šą“æą“¤ąµą“°ą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•", + "submit": "ą“šą“æą“¤ąµą“°ą“‚ ą“Øąµ€ą“•ąµą“•ą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "splitByChapters": { + "title": "ą“…ą“§ąµą“Æą“¾ą“Æą“™ąµą“™ąµ¾ ą“…ą“Øąµą“øą“°ą“æą“šąµą“šąµ PDF ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "header": "ą“…ą“§ąµą“Æą“¾ą“Æą“™ąµą“™ąµ¾ ą“…ą“Øąµą“øą“°ą“æą“šąµą“šąµ PDF ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•", + "bookmarkLevel": "ą“¬ąµą“•ąµą“•ąµą“®ą“¾ąµ¼ą“•ąµą“•ąµ ą“Øą“æą“²", + "includeMetadata": "ą“®ąµ†ą“±ąµą“±ą“¾ą“”ą“¾ą“±ąµą“± ą“‰ąµ¾ą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ąµą“•", + "allowDuplicates": "ą“¤ą“Øą“æą“Ŗąµą“Ŗą“•ąµ¼ą“Ŗąµą“Ŗąµą“•ąµ¾ ą“…ą“Øąµą“µą“¦ą“æą“•ąµą“•ąµą“•", + "desc": { + "1": "ą“ˆ ą“‰ą“Ŗą“•ą“°ą“£ą“‚ ą“’ą“°ąµ PDF ą“«ą“Æą“²ą“æą“Øąµ† ą“…ą“¤ą“æą“Øąµą“±ąµ† ą“…ą“§ąµą“Æą“¾ą“Æ ą“˜ą“Ÿą“Øą“Æąµ† ą“…ą“Ÿą“æą“øąµą“„ą“¾ą“Øą“®ą“¾ą“•ąµą“•ą“æ ą“’ą“Øąµą“Øą“æą“²ą“§ą“æą“•ą“‚ PDF-ą“•ą“³ą“¾ą“Æą“æ ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“Øąµą“Øąµ.", + "2": "ą“¬ąµą“•ąµą“•ąµą“®ą“¾ąµ¼ą“•ąµą“•ąµ ą“Øą“æą“²: ą“µą“æą“­ą“œą“Øą“¤ąµą“¤ą“æą“Øą“¾ą“Æą“æ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµ‡ą“£ąµą“Ÿ ą“¬ąµą“•ąµą“•ąµą“®ą“¾ąµ¼ą“•ąµą“•ąµą“•ą“³ąµą“Ÿąµ† ą“Øą“æą“² ą“¤ą“æą“°ą“žąµą“žąµ†ą“Ÿąµą“•ąµą“•ąµą“• (ą“‰ą“Øąµą“Øą“¤ ą“Øą“æą“²ą“Æąµą“•ąµą“•ąµ 0, ą“°ą“£ąµą“Ÿą“¾ą“‚ ą“Øą“æą“²ą“Æąµą“•ąµą“•ąµ 1, ą“®ąµą“¤ą“²ą“¾ą“Æą“µ).", + "3": "ą“®ąµ†ą“±ąµą“±ą“¾ą“”ą“¾ą“±ąµą“± ą“‰ąµ¾ą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ąµą“•: ą“šąµ†ą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“¤ą“¾ąµ½, ą“Æą“„ą“¾ąµ¼ą“¤ąµą“„ PDF-ą“Øąµą“±ąµ† ą“®ąµ†ą“±ąµą“±ą“¾ą“”ą“¾ą“±ąµą“± ą““ą“°ąµ‹ ą“µą“æą“­ą“œą“æą“šąµą“š PDF-ą“²ąµą“‚ ą“‰ąµ¾ą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ąµą“‚.", + "4": "ą“¤ą“Øą“æą“Ŗąµą“Ŗą“•ąµ¼ą“Ŗąµą“Ŗąµą“•ąµ¾ ą“…ą“Øąµą“µą“¦ą“æą“•ąµą“•ąµą“•: ą“šąµ†ą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“¤ą“¾ąµ½, ą“’ą“°ąµ‡ ą“Ŗąµ‡ą“œą“æą“²ąµ† ą“’ą“Øąµą“Øą“æą“²ą“§ą“æą“•ą“‚ ą“¬ąµą“•ąµą“•ąµą“®ą“¾ąµ¼ą“•ąµą“•ąµą“•ąµ¾ą“•ąµą“•ąµ ą“Ŗąµą“°ą“¤ąµą“Æąµ‡ą“• PDF-ą“•ąµ¾ ą“øąµƒą“·ąµą“Ÿą“æą“•ąµą“•ą“¾ąµ» ą“…ą“Øąµą“µą“¦ą“æą“•ąµą“•ąµą“Øąµą“Øąµ." + }, + "submit": "PDF ą“µą“æą“­ą“œą“æą“•ąµą“•ąµą“•" + }, + "fileChooser": { + "click": "ą“•ąµą“²ą“æą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“Æąµą“•", + "or": "ą“…ą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½", + "dragAndDrop": "ą“µą“²ą“æą“šąµą“šą“æą“Ÿąµą“•", + "dragAndDropPDF": "PDF ą“«ą“Æąµ½ ą“µą“²ą“æą“šąµą“šą“æą“Ÿąµą“•", + "dragAndDropImage": "ą“šą“æą“¤ąµą“° ą“«ą“Æąµ½ ą“µą“²ą“æą“šąµą“šą“æą“Ÿąµą“•", + "hoveredDragAndDrop": "ą“«ą“Æąµ½(ą“•ąµ¾) ą“‡ą“µą“æą“Ÿąµ† ą“µą“²ą“æą“šąµą“šą“æą“Ÿąµą“•", + "extractPDF": "ą“µąµ‡ąµ¼ą“¤ą“æą“°ą“æą“šąµą“šąµ†ą“Ÿąµą“•ąµą“•ąµą“Øąµą“Øąµ..." + }, + "releases": { + "footer": "ą“±ą“æą“²ąµ€ą“øąµą“•ąµ¾", + "title": "ą“±ą“æą“²ąµ€ą“øąµ ą“•ąµą“±ą“æą“Ŗąµą“Ŗąµą“•ąµ¾", + "header": "ą“±ą“æą“²ąµ€ą“øąµ ą“•ąµą“±ą“æą“Ŗąµą“Ŗąµą“•ąµ¾", + "current": { + "version": "ą“Øą“æą“²ą“µą“æą“²ąµ† ą“±ą“æą“²ąµ€ą“øąµ" + }, + "note": "ą“±ą“æą“²ąµ€ą“øąµ ą“•ąµą“±ą“æą“Ŗąµą“Ŗąµą“•ąµ¾ ą“‡ą“‚ą“—ąµą“²ąµ€ą“·ą“æąµ½ ą“®ą“¾ą“¤ąµą“°ą“®ąµ‡ ą“²ą“­ąµą“Æą“®ą“¾ą“•ąµ‚" + }, + "cookieBanner": { + "popUp": { + "title": "ą“žą“™ąµą“™ąµ¾ ą“•ąµą“•ąµą“•ą“æą“•ąµ¾ ą“Žą“™ąµą“™ą“Øąµ† ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ", + "description": { + "1": "ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ PDF ą“Øą“æą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“®ą“æą“•ą“šąµą“š ą“°ąµ€ą“¤ą“æą“Æą“æąµ½ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“•ąµą“•ą“¾ąµ» ą“žą“™ąµą“™ąµ¾ ą“•ąµą“•ąµą“•ą“æą“•ą“³ąµą“‚ ą“®ą“±ąµą“±ąµ ą“øą“¾ą“™ąµą“•ąµ‡ą“¤ą“æą“•ą“µą“æą“¦ąµą“Æą“•ą“³ąµą“‚ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµā€”ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Ÿąµ‚ą“³ąµą“•ąµ¾ ą“®ąµ†ą“šąµą“šą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ą“¾ą“Øąµą“‚ ą“Øą“æą“™ąµą“™ąµ¾ ą“‡ą“·ąµą“Ÿą“Ŗąµą“Ŗąµ†ą“Ÿąµą“Øąµą“Ø ą“«ąµ€ą“šąµą“šą“±ąµą“•ąµ¾ ą“Øą“æąµ¼ą“®ąµą“®ą“æą“•ąµą“•ąµą“Øąµą“Øą“¤ąµ ą“¤ąµą“Ÿą“°ą“¾ą“Øąµą“‚ ą“‡ą“¤ąµ ą“žą“™ąµą“™ą“³ąµ† ą“øą“¹ą“¾ą“Æą“æą“•ąµą“•ąµą“Øąµą“Øąµ.", + "2": "ą“Øą“æą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“¤ą“¾ąµ½ą“Ŗąµą“Ŗą“°ąµą“Æą“®ą“æą“²ąµą“²ąµ†ą“™ąµą“•ą“æąµ½, 'ą“µąµ‡ą“£ąµą“Ÿ ą“Øą“Øąµą“¦ą“æ' ą“•ąµą“²ą“æą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øą“¤ąµ ą“•ą“¾ą“°ąµą“Æą“™ąµą“™ąµ¾ ą“øąµą“—ą“®ą“®ą“¾ą“Æą“æ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“•ąµą“•ą“¾ąµ» ą“†ą“µą“¶ąµą“Æą“®ą“¾ą“Æ ą“…ą“µą“¶ąµą“Æ ą“•ąµą“•ąµą“•ą“æą“•ąµ¾ ą“®ą“¾ą“¤ąµą“°ą“‚ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“•ąµą“·ą“®ą“®ą“¾ą“•ąµą“•ąµą“‚." + }, + "acceptAllBtn": "ą“¶ą“°ą“æ", + "acceptNecessaryBtn": "ą“µąµ‡ą“£ąµą“Ÿ ą“Øą“Øąµą“¦ą“æ", + "showPreferencesBtn": "ą“®ąµąµ»ą“—ą“£ą“Øą“•ąµ¾ ą“•ąµˆą“•ą“¾ą“°ąµą“Æą“‚ ą“šąµ†ą“Æąµą“Æąµą“•" + }, + "preferencesModal": { + "title": "ą“øą“®ąµą“®ą“¤ ą“®ąµąµ»ą“—ą“£ą“Øą“¾ ą“•ąµ‡ą“Øąµą“¦ąµą“°ą“‚", + "acceptAllBtn": "ą“Žą“²ąµą“²ą“¾ą“‚ ą“øąµą“µąµ€ą“•ą“°ą“æą“•ąµą“•ąµą“•", + "acceptNecessaryBtn": "ą“Žą“²ąµą“²ą“¾ą“‚ ą“Øą“æą“°ą“øą“æą“•ąµą“•ąµą“•", + "savePreferencesBtn": "ą“®ąµąµ»ą“—ą“£ą“Øą“•ąµ¾ ą“øą“‚ą“°ą“•ąµą“·ą“æą“•ąµą“•ąµą“•", + "closeIconLabel": "ą“®ąµ‹ą“”ąµ½ ą“…ą“Ÿą“Æąµą“•ąµą“•ąµą“•", + "serviceCounterLabel": "ą“øąµ‡ą“µą“Øą“‚|ą“øąµ‡ą“µą“Øą“™ąµą“™ąµ¾", + "subtitle": "ą“•ąµą“•ąµą“•ą“æ ą“‰ą“Ŗą“Æąµ‹ą“—ą“‚", + "description": { + "1": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“…ą“Øąµą“­ą“µą“‚ ą“®ąµ†ą“šąµą“šą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ąµą“Øąµą“Øą“¤ą“æą“Øąµą“‚ ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Ÿąµ‚ą“³ąµą“•ąµ¾ ą“Žą“™ąµą“™ą“Øąµ† ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµą“µąµ†ą“Øąµą“Øąµ ą“®ą“Øą“øąµą“øą“æą“²ą“¾ą“•ąµą“•ąµą“Øąµą“Øą“¤ą“æą“Øąµą“‚ ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ PDF ą“•ąµą“•ąµą“•ą“æą“•ą“³ąµą“‚ ą“øą“®ą“¾ą“Ø ą“øą“¾ą“™ąµą“•ąµ‡ą“¤ą“æą“•ą“µą“æą“¦ąµą“Æą“•ą“³ąµą“‚ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµ. ą“Ŗąµą“°ą“•ą“Ÿą“Øą“‚ ą“®ąµ†ą“šąµą“šą“Ŗąµą“Ŗąµ†ą“Ÿąµą“¤ąµą“¤ą“¾ą“Øąµą“‚ ą“Øą“æą“™ąµą“™ąµ¾ ą“µą“æą“²ą“®ą“¤ą“æą“•ąµą“•ąµą“Øąµą“Ø ą“«ąµ€ą“šąµą“šą“±ąµą“•ąµ¾ ą“µą“æą“•ą“øą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ą“¾ą“Øąµą“‚ ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† ą“‰ą“Ŗą“Æąµ‹ą“•ąµą“¤ą“¾ą“•ąµą“•ąµ¾ą“•ąµą“•ąµ ą“¤ąµą“Ÿąµ¼ą“Øąµą“Øąµą“‚ ą“Ŗą“æą“Øąµą“¤ąµą“£ ą“Øąµ½ą“•ą“¾ą“Øąµą“‚ ą“‡ą“¤ąµ ą“žą“™ąµą“™ą“³ąµ† ą“øą“¹ą“¾ą“Æą“æą“•ąµą“•ąµą“Øąµą“Øąµ.", + "2": "ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ PDF-ą“Øąµ ą“Øą“æą“™ąµą“™ąµ¾ ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Ø ą“Ŗąµą“°ą“®ą“¾ą“£ą“™ąµą“™ą“³ąµą“Ÿąµ† ą“‰ą“³ąµą“³ą“Ÿą“•ąµą“•ą“‚ ą“Ÿąµą“°ą“¾ą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“Æą“¾ą“Øąµ‹ ą“†ą“•ąµā€Œą“øą“øąµ ą“šąµ†ą“Æąµą“Æą“¾ą“Øąµ‹ ą“•ą““ą“æą“Æą“æą“²ąµą“²ā€”ą“’ą“°ą“æą“•ąµą“•ą“²ąµą“‚ ą“•ą““ą“æą“Æą“æą“²ąµą“².", + "3": "ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“øąµą“µą“•ą“¾ą“°ąµą“Æą“¤ą“Æąµą“‚ ą“µą“æą“¶ąµą“µą“¾ą“øą“µąµą“®ą“¾ą“£ąµ ą“žą“™ąµą“™ąµ¾ ą“šąµ†ą“Æąµą“Æąµą“Øąµą“Øą“¤ą“æą“Øąµą“±ąµ† ą“•ą“¾ą“¤ąµ½." + }, + "necessary": { + "title": { + "1": "ą“•ąµ¼ą“¶ą“Øą“®ą“¾ą“Æą“æ ą“†ą“µą“¶ąµą“Æą“®ą“¾ą“Æ ą“•ąµą“•ąµą“•ą“æą“•ąµ¾", + "2": "ą“Žą“Ŗąµą“Ŗąµ‹ą““ąµą“‚ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“•ąµą“·ą“®ą“‚" + }, + "description": "ą“µąµ†ą“¬ąµą“øąµˆą“±ąµą“±ąµ ą“¶ą“°ą“æą“Æą“¾ą“Æą“æ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“•ąµą“•ą“¾ąµ» ą“ˆ ą“•ąµą“•ąµą“•ą“æą“•ąµ¾ ą“…ą“¤ąµą“Æą“¾ą“µą“¶ąµą“Æą“®ą“¾ą“£ąµ. ą“Øą“æą“™ąµą“™ą“³ąµą“Ÿąµ† ą“øąµą“µą“•ą“¾ą“°ąµą“Æą“¤ą“¾ ą“®ąµąµ»ą“—ą“£ą“Øą“•ąµ¾ ą“øą“œąµą“œą“®ą“¾ą“•ąµą“•ąµą“•, ą“²ąµ‹ą“—ą“æąµ» ą“šąµ†ą“Æąµą“Æąµą“•, ą“«ąµ‹ą“®ąµą“•ąµ¾ ą“Ŗąµ‚ą“°ą“æą“Ŗąµą“Ŗą“æą“•ąµą“•ąµą“• ą“¤ąµą“Ÿą“™ąµą“™ą“æą“Æ ą“Ŗąµą“°ą“§ą“¾ą“Ø ą“øą“µą“æą“¶ąµ‡ą“·ą“¤ą“•ąµ¾ ą“…ą“µ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“•ąµą“·ą“®ą“®ą“¾ą“•ąµą“•ąµą“Øąµą“Øąµā€”ą“…ą“¤ąµą“•ąµŠą“£ąµą“Ÿą“¾ą“£ąµ ą“…ą“µ ą““ą“«ą“¾ą“•ąµą“•ą“¾ąµ» ą“•ą““ą“æą“Æą“¾ą“¤ąµą“¤ą“¤ąµ." + }, + "analytics": { + "title": "ą“…ą“Øą“²ą“æą“±ąµą“±ą“æą“•ąµą“øąµ", + "description": "ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† ą“Ÿąµ‚ą“³ąµą“•ąµ¾ ą“Žą“™ąµą“™ą“Øąµ† ą“‰ą“Ŗą“Æąµ‹ą“—ą“æą“•ąµą“•ąµą“Øąµą“Øąµą“µąµ†ą“Øąµą“Øąµ ą“®ą“Øą“øąµą“øą“æą“²ą“¾ą“•ąµą“•ą“¾ąµ» ą“ˆ ą“•ąµą“•ąµą“•ą“æą“•ąµ¾ ą“žą“™ąµą“™ą“³ąµ† ą“øą“¹ą“¾ą“Æą“æą“•ąµą“•ąµą“Øąµą“Øąµ, ą“…ą“¤ą“æą“Øą“¾ąµ½ ą“žą“™ąµą“™ą“³ąµą“Ÿąµ† ą“•ą“®ąµą“®ąµą“Æąµ‚ą“£ą“æą“±ąµą“±ą“æ ą“ą“±ąµą“±ą“µąµą“‚ ą“•ąµ‚ą“Ÿąµą“¤ąµ½ ą“µą“æą“²ą“®ą“¤ą“æą“•ąµą“•ąµą“Øąµą“Ø ą“«ąµ€ą“šąµą“šą“±ąµą“•ąµ¾ ą“Øą“æąµ¼ą“®ąµą“®ą“æą“•ąµą“•ąµą“Øąµą“Øą“¤ą“æąµ½ ą“žą“™ąµą“™ąµ¾ą“•ąµą“•ąµ ą“¶ąµą“°ą“¦ąµą“§ ą“•ąµ‡ą“Øąµą“¦ąµą“°ąµ€ą“•ą“°ą“æą“•ąµą“•ą“¾ąµ» ą“•ą““ą“æą“Æąµą“‚. ą“‰ą“±ą“Ŗąµą“Ŗą“¾ą“•ąµą“•ąµą“•ā€”ą“øąµą“±ąµą“±ąµ†ąµ¼ą“²ą“æą“‚ą“—ąµ PDF-ą“Øąµ ą“Øą“æą“™ąµą“™ąµ¾ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“•ąµą“•ąµą“Øąµą“Ø ą“Ŗąµą“°ą“®ą“¾ą“£ą“™ąµą“™ą“³ąµą“Ÿąµ† ą“‰ą“³ąµą“³ą“Ÿą“•ąµą“•ą“‚ ą“Ÿąµą“°ą“¾ą“•ąµą“•ąµ ą“šąµ†ą“Æąµą“Æą“¾ąµ» ą“•ą““ą“æą“Æą“æą“²ąµą“², ą“’ą“°ą“æą“•ąµą“•ą“²ąµą“‚ ą“•ą““ą“æą“Æą“æą“²ąµą“²." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/nl-NL/translation.json b/frontend/public/locales/nl-NL/translation.json new file mode 100644 index 000000000..7f82e8529 --- /dev/null +++ b/frontend/public/locales/nl-NL/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Lettertypegrootte", + "fontName": "Lettertypenaam", + "title": "Paginanummers toevoegen", + "header": "Paginanummers toevoegen", + "selectText": { + "1": "Selecteer PDF-bestand:", + "2": "Margegrootte", + "3": "Positie", + "4": "Startnummer", + "5": "Pagina's om te nummeren", + "6": "Aangepaste tekst" + }, + "customTextDesc": "Aangepaste tekst", + "numberPagesDesc": "Welke pagina's genummerd moeten worden, standaard 'all', accepteert ook 1-5 of 2,5,9 etc", + "customNumberDesc": "Standaard {n}, accepteert ook 'Pagina {n} van {total}', 'Tekst-{n}', '{filename}-{n}", + "submit": "Paginanummers toevoegen" + }, + "pdfPrompt": "Selecteer PDF('s)", + "multiPdfPrompt": "Selecteer PDF's (2+)", + "multiPdfDropPrompt": "Selecteer (of sleep & zet neer) alle PDF's die je nodig hebt", + "imgPrompt": "Selecteer afbeelding(en)", + "genericSubmit": "Indienen", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Waarschuwing: Dit proces kan tot een minuut duren afhankelijk van de bestandsgrootte", + "pageOrderPrompt": "Aangepaste pagina volgorde (Voer een komma-gescheiden lijst van paginanummers of functies in, zoals 2n+1) :", + "pageSelectionPrompt": "Aangepaste pagina selectie (Voer een komma-gescheiden lijst van paginanummer 1,5,6 of functies zoals 2n+1 in) :", + "goToPage": "Ga", + "true": "Waar", + "false": "Onwaar", + "unknown": "Onbekend", + "save": "Opslaan", + "saveToBrowser": "Opslaan in browser", + "close": "Sluiten", + "filesSelected": "Bestanden geselecteerd", + "noFavourites": "Geen favorieten toegevoegd", + "downloadComplete": "Download klaar", + "bored": "Verveeld met wachten?", + "alphabet": "Alfabet", + "downloadPdf": "PDF downloaden", + "text": "Tekst", + "font": "Lettertype", + "selectFillter": "-- Selecteer --", + "pageNum": "Paginanummer", + "sizes": { + "small": "Klein", + "medium": "Gemiddeld", + "large": "Groot", + "x-large": "Extra groot" + }, + "error": { + "pdfPassword": "Het PDF document is beveiligd met een wachtwoord en het wachtwoord is niet ingevoerd of is onjuist", + "_value": "Fout", + "sorry": "Excuses voor het probleem!", + "needHelp": "Hulp nodig / probleem gevonden?", + "contactTip": "Als je nog steeds problemen hebt, schroom niet om contact met ons op te nemen voor hulp. Je kan een ticket op onze Github pagina indienen of ons via Discord bereiken:", + "404": { + "head": "404 - Pagina niet gevonden | Oeps, we struikelden over de code!", + "1": "We kunnen de pagina die je zoek niet vinden.", + "2": "Er ging iets mis." + }, + "github": "Dien een ticket op Github in.", + "showStack": "Geeft tracering weer", + "copyStack": "Kopieer tracering", + "githubSubmit": "GitHub - Dien een ticket in", + "discordSubmit": "Discord - Maak een support post" + }, + "delete": "Verwijderen", + "username": "Gebruikersnaam", + "password": "Wachtwoord", + "welcome": "Welkom", + "property": "Eigenschap", + "black": "Zwart", + "white": "Wit", + "red": "Rood", + "green": "Groen", + "blue": "Blauw", + "custom": "Aangepast...", + "WorkInProgess": "Werk in uitvoering. Werkt mogelijk niet of bevat fouten. Meld eventuele problemen!", + "poweredBy": "Mogelijk gemaakt door", + "yes": "Ja", + "no": "Nee", + "changedCredsMessage": "Inloggegevens gewijzigd!", + "notAuthenticatedMessage": "Gebruiker niet ingelogd.", + "userNotFoundMessage": "Gebruiker niet gevonden.", + "incorrectPasswordMessage": "Huidige wachtwoord is onjuist.", + "usernameExistsMessage": "Nieuwe gebruikersnaam bestaat al.", + "invalidUsernameMessage": "Ongeldige gebruikersnaam, gebruikersnaam kan alleen letters, nummers en de volgende speciale tekens @._+- bevatten of moet een geldig emailadres zijn.", + "invalidPasswordMessage": "Het wachtwoord mag geen spaties ten beginne of einde bevatten en mag niet leeg zijn.", + "confirmPasswordErrorMessage": "Nieuw wachtwoord en bevestig wachtwoord moeten overeenkomen.", + "deleteCurrentUserMessage": "Kan niet een momenteel ingelogde gebruiker verwijderen.", + "deleteUsernameExistsMessage": "De gebruikersnaam bestaat niet en kan niet verwijderd worden.", + "downgradeCurrentUserMessage": "Kan de rol van de huidige gebruiker niet downgraden", + "disabledCurrentUserMessage": "De huidige gebruiker kan niet worden uitgeschakeld", + "downgradeCurrentUserLongMessage": "Kan de rol van de huidige gebruiker niet downgraden. Huidige gebruiker wordt dus niet weergegeven.", + "userAlreadyExistsOAuthMessage": "De gebruiker bestaat al als een OAuth2 gebruiker.", + "userAlreadyExistsWebMessage": "De gebruiker bestaat al als een web gebruiker.", + "oops": "Oeps!", + "help": "Hulp", + "goHomepage": "Ga naar de startpagina", + "joinDiscord": "Word lid van onze Discord server", + "seeDockerHub": "Zie Docker Hub", + "visitGithub": "Ga naar de Github Repository", + "donate": "Doneer", + "color": "Kleur", + "sponsor": "Sponsor", + "info": "Informatie", + "pro": "Pro", + "page": "Pagina", + "pages": "Pagen", + "loading": "Laden...", + "addToDoc": "Toevoegen aan document", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Privacybeleid", + "terms": "Voorwaarden van gebruik", + "accessibility": "Toegankelijkheid", + "cookie": "Cookiesbeleid", + "impressum": "Imprint", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Pijplijn menu (Beta)", + "uploadButton": "Aangepast uploaden", + "configureButton": "Configureren", + "defaultOption": "Aangepast", + "submitButton": "Opslaan", + "help": "Pijplijn help", + "scanHelp": "Map scannen help", + "deletePrompt": "Weet je zeker dat je deze pijplijn wil verwijderen?", + "tags": "automatiseren,volgorde,gescrript,batch-verwerking", + "title": "Pijplijn" + }, + "pipelineOptions": { + "header": "Pijplijn configuratie", + "pipelineNameLabel": "Pijplijn naam", + "saveSettings": "Instellingen voor bewerking opslaan", + "pipelineNamePrompt": "Voer hier de naam van de pijplijn in", + "selectOperation": "Selecteer bewerking", + "addOperationButton": "Bewerking toevoegen", + "pipelineHeader": "Pijplijn:", + "saveButton": "Downloaden", + "validateButton": "Valideren" + }, + "enterpriseEdition": { + "button": "Upgrade to Pro", + "warning": "This feature is only available to Pro users.", + "yamlAdvert": "Stirling PDF Pro supports YAML configuration files and other SSO features.", + "ssoAdvert": "Looking for more user management features? Check out Stirling PDF Pro" + }, + "analytics": { + "title": "Do you want make Stirling PDF better?", + "paragraph1": "Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.", + "paragraph2": "Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.", + "enable": "Enable analytics", + "disable": "Disable analytics", + "settings": "You can change the settings for analytics in the config/settings.yml file" + }, + "navbar": { + "favorite": "Favorieten", + "recent": "New and recently updated", + "darkmode": "Donkere modus", + "language": "Talen", + "settings": "Instellingen", + "allTools": "Tools", + "multiTool": "Multitools", + "search": "Search", + "sections": { + "organize": "Organizeren", + "convertTo": "Converteren naar PDF", + "convertFrom": "Converteren van PDF", + "security": "Ondertekenen & beveiliging", + "advance": "Geavanceerd", + "edit": "Bekijken & wijzigen", + "popular": "Popular" + } + }, + "settings": { + "title": "Instellingen", + "update": "Update beschikbaar", + "updateAvailable": "{0} is de huidig geĆÆnstalleerde versie. Een nieuwe versie ({1}) is beschikbaar.", + "appVersion": "App versie:", + "downloadOption": { + "title": "Kies download optie (Voor enkelvoudige bestanddownloads zonder zip):", + "1": "Open in hetzelfde venster", + "2": "Open in nieuw venster", + "3": "Download bestand" + }, + "zipThreshold": "Bestanden zippen wanneer het aantal gedownloade bestanden meer is dan", + "signOut": "Uitloggen", + "accountSettings": "Account instellingen", + "bored": { + "help": "Schakelt geheim spelletje in" + }, + "cacheInputs": { + "name": "Sla invoer in formulieren op", + "help": "Schakel in om eerdere invoeren op te slaan voor toekomstige uitvoeren" + } + }, + "changeCreds": { + "title": "Inloggegevens wijzigen", + "header": "Werk je accountgegevens bij", + "changePassword": "Je gebruikt de standaard inloggegevens. Voer alstublieft een nieuw wachtwoord in", + "newUsername": "Nieuwe gebruikersnaam", + "oldPassword": "Huidige wachtwoord", + "newPassword": "Nieuw wachtwoord", + "confirmNewPassword": "Bevestig nieuw wachtwoord", + "submit": "Wijzigingen opslaan" + }, + "account": { + "title": "Account instellingen", + "accountSettings": "Account instellingen", + "adminSettings": "Beheerdersinstellingen - Gebruikers bekijken en toevoegen", + "userControlSettings": "Gebruikerscontrole instellingen", + "changeUsername": "Wijzig gebruikersnaam", + "newUsername": "Nieuwe gebruikersnaam", + "password": "Bevestigingswachtwoord", + "oldPassword": "Oud wachtwoord", + "newPassword": "Nieuw wachtwoord", + "changePassword": "Wijzig wachtwoord", + "confirmNewPassword": "Bevestig nieuw wachtwoord", + "signOut": "Uitloggen", + "yourApiKey": "Jouw API sleutel", + "syncTitle": "Synchroniseer browserinstellingen met account", + "settingsCompare": "Instellingen vergelijking:", + "property": "Eigenschap", + "webBrowserSettings": "Webbrowser instelling", + "syncToBrowser": "Synchroniseer account -> browser", + "syncToAccount": "Synchroniseer account <- browser" + }, + "adminUserSettings": { + "title": "Gebruikersbeheer", + "header": "Beheer gebruikers", + "admin": "Beheerder", + "user": "Gebruiker", + "addUser": "Voeg nieuwe gebruiker toe", + "deleteUser": "Verwijder gebruiker", + "confirmDeleteUser": "Moet deze gebruiker verwijderd worden?", + "confirmChangeUserStatus": "Should the user be disabled/enabled?", + "usernameInfo": "Gebruikersnaam kan alleen letters, nummers en de volgende speciale tekens @._+- bevatten of moet een geldig emailadres zijn.", + "roles": "Rollen", + "role": "Rol", + "actions": "Acties", + "apiUser": "Beperkte API gebruiker", + "extraApiUser": "Extra beperkte API gebruiker", + "webOnlyUser": "Alleen web gebruiker", + "demoUser": "Demogebruiker (geen aangepaste instellingen)", + "internalApiUser": "Interne API gebruiker", + "forceChange": "Forceer gebruiker om gebruikersnaam/wachtwoord te wijzigen bij inloggen", + "submit": "Gebruiker opslaan", + "changeUserRole": "De rol van de gebruiker wijzigen", + "authenticated": "Geauthenticeerd", + "editOwnProfil": "Edit own profile", + "enabledUser": "enabled user", + "disabledUser": "disabled user", + "activeUsers": "Active Users:", + "disabledUsers": "Disabled Users:", + "totalUsers": "Total Users:", + "lastRequest": "Laatste aanvraag", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Database Importeer/Exporteer", + "header": "Database Importeer/Exporteer", + "fileName": "Bestandsnaam", + "creationDate": "Creatiedatum", + "fileSize": "Bestandsgrootte", + "deleteBackupFile": "Backupbestand verwijderen", + "importBackupFile": "Backupbestand importeren", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Backupbestand downloaden", + "info_1": "Bij het importeren van gegevens is het cruciaal om de juiste structuur te zorgen voor. Als je niet zeker bent van wat je doet, raadpleeg dan advies en ondersteuning bij een professionele. Een fout in de structuur kan leiden tot toepassingsfouten, waarmee wellicht zelfs de volledige uitvoerbaarheid van de toepassing belemmerd wordt.", + "info_2": "De bestandsnaam maakt geen verschil bij het uploaden. Hij zal later worden herbewoond om de indeling backup_user_yyyyMMddHHmm.sql te volgen, waardoor een consistente bestandsnaamconventie waarborgd wordt.", + "submit": "Backup importeren", + "importIntoDatabaseSuccessed": "Importeer naar database succesvol", + "backupCreated": "Database backup successful", + "fileNotFound": "File not Found", + "fileNullOrEmpty": "Bestand mag niet null of leeg zijn", + "failedImportFile": "Failed Import File", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "Je sessie is verlopen. Voer de pagina opnieuw in en probeer het opnieuw.", + "refreshPage": "Refresh Page" + }, + "home": { + "desc": "Jouw lokaal gehoste one-stop-shop voor al je PDF-behoeften.", + "searchBar": "Zoek naar functies...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Bekijk, annoteer, voeg tekst of afbeeldingen toe" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "PDF multitool", + "desc": "Pagina's samenvoegen, draaien, herschikken en verwijderen" + }, + "merge": { + "title": "Samenvoegen", + "desc": "Voeg eenvoudig meerdere PDF's samen tot ƩƩn." + }, + "split": { + "title": "Splitsen", + "desc": "Splits PDF's in meerdere documenten" + }, + "rotate": { + "title": "Roteren", + "desc": "Roteer eenvoudig je PDF's." + }, + "imageToPdf": { + "title": "Afbeelding naar PDF", + "desc": "Converteer een afbeelding (PNG, JPEG, GIF) naar PDF." + }, + "pdfToImage": { + "title": "PDF naar Afbeelding", + "desc": "Converteer een PDF naar een afbeelding. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Organiseren", + "desc": "Verwijder/herschik pagina's in een volgorde naar keus" + }, + "addImage": { + "title": "Afbeelding toevoegen", + "desc": "Voegt een afbeelding toe op een specifieke locatie in de PDF" + }, + "watermark": { + "title": "Watermerk toevoegen", + "desc": "Voeg een aangepast watermerk toe aan je PDF-document." + }, + "permissions": { + "title": "Permissies wijzigen", + "desc": "Wijzig de permissies van je PDF-document" + }, + "removePages": { + "title": "Verwijderen", + "desc": "Verwijder ongewenste pagina's uit je PDF-document." + }, + "addPassword": { + "title": "Wachtwoord toevoegen", + "desc": "Versleutel je PDF-document met een wachtwoord." + }, + "removePassword": { + "title": "Wachtwoord verwijderen", + "desc": "Verwijder wachtwoordbeveiliging van je PDF-document." + }, + "compressPdfs": { + "title": "Comprimeren", + "desc": "Comprimeer PDF's om hun bestandsgrootte te verkleinen." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Metadata wijzigen", + "desc": "Wijzig/verwijder/voeg metadata toe van een PDF-document" + }, + "fileToPDF": { + "title": "Bestand naar PDF converteren", + "desc": "Converteer bijna ieder bestand naar PDF (DOCX, PNG, XLS, PPT, TXT en meer)" + }, + "ocr": { + "title": "OCR / Scans opruimen", + "desc": "Ruim scans op, detecteert tekst van afbeeldingen in een PDF en voegt deze opnieuw toe als tekst." + }, + "extractImages": { + "title": "Afbeeldingen extraheren", + "desc": "Extraheert alle afbeeldingen uit een PDF en slaat ze op in een zip" + }, + "pdfToPDFA": { + "title": "PDF naar PDF/A", + "desc": "Converteer PDF naar PDF/A voor langdurige opslag" + }, + "PDFToWord": { + "title": "PDF naar Word", + "desc": "Converteer PDF naar Word-formaten (DOC, DOCX en ODT)" + }, + "PDFToPresentation": { + "title": "PDF naar Presentatie", + "desc": "Converteer PDF naar Presentatie formaten (PPT, PPTX en ODP)" + }, + "PDFToText": { + "title": "PDF naar RTF (Tekst)", + "desc": "Converteer PDF naar Tekst of RTF formaat" + }, + "PDFToHTML": { + "title": "PDF naar HTML", + "desc": "Converteer PDF naar HTML formaat" + }, + "PDFToXML": { + "title": "PDF naar XML", + "desc": "Converteer PDF naar XML formaat" + }, + "ScannerImageSplit": { + "title": "Detecteer/Split gescande foto's", + "desc": "Splits meerdere foto's van binnen een foto/PDF" + }, + "sign": { + "title": "Ondertekenen", + "desc": "Voegt handtekening toe aan PDF via tekenen, tekst of afbeelding" + }, + "flatten": { + "title": "Platdrukken", + "desc": "Verwijder alle interactieve elementen en formulieren uit een PDF" + }, + "repair": { + "title": "Repareren", + "desc": "Probeert een corrupt/beschadigd PDF te herstellen" + }, + "removeBlanks": { + "title": "Verwijder lege pagina's", + "desc": "Detecteert en verwijdert lege pagina's uit een document" + }, + "removeAnnotations": { + "title": "Annotaties verwijderen", + "desc": "Verwijdert alle opmerkingen/annotaties uit een PDF" + }, + "compare": { + "title": "Vergelijken", + "desc": "Vergelijkt en toont de verschillen tussen twee PDF-documenten" + }, + "certSign": { + "title": "Ondertekenen met certificaat", + "desc": "Ondertekent een PDF met een certificaat/sleutel (PEM/P12)" + }, + "removeCertSign": { + "title": "Verwijder certificaat", + "desc": "Verwijder certificaat van PDF" + }, + "pageLayout": { + "title": "Multi-pagina indeling", + "desc": "Voeg meerdere pagina's van een PDF-document samen op ƩƩn pagina" + }, + "scalePages": { + "title": "Aanpassen paginaformaat/schaal", + "desc": "Wijzig de grootte/schaal van een pagina en/of de inhoud ervan." + }, + "pipeline": { + "title": "Pijplijn", + "desc": "Voer meerdere acties uit op PDF's door pipelinescripts te definiĆ«ren" + }, + "add-page-numbers": { + "title": "Paginanummers toevoegen", + "desc": "Voeg paginanummers toe binnen het volledige document op een vastgestelde locatie" + }, + "auto-rename": { + "title": "Automatisch hernoemen PDF-bestand", + "desc": "Hernoemt automatisch een PDF-bestand op basis van de gedetecteerde header" + }, + "adjust-contrast": { + "title": "Kleuren/contrast aanpassen", + "desc": "Pas contrast, verzadiging en helderheid van een PDF aan" + }, + "crop": { + "title": "PDF bijsnijden", + "desc": "Snijd een PDF bij om de grootte te verkleinen (behoudt tekst!)" + }, + "autoSplitPDF": { + "title": "Automatisch splitsen pagina's", + "desc": "Automatisch splitsen van gescande PDF met fysieke gescande paginasplitter QR-code" + }, + "sanitizePdf": { + "title": "Opschonen", + "desc": "Verwijder scripts en andere elementen uit PDF-bestanden" + }, + "URLToPDF": { + "title": "URL/website naar PDF", + "desc": "Zet http(s)URL om naar PDF" + }, + "HTMLToPDF": { + "title": "HTML naar PDF", + "desc": "Zet HTML-bestand of zip om naar PDF" + }, + "MarkdownToPDF": { + "title": "Markdown naar PDF", + "desc": "Zet Markdown-bestand om naar PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "Haal ALLE informatie op over PDF", + "desc": "Haalt alle mogelijke informatie op van PDF's" + }, + "extractPage": { + "title": "Pagina('s) extraheren", + "desc": "Extraheert geselecteerde pagina's uit PDF" + }, + "PdfToSinglePage": { + "title": "PDF naar ƩƩn grote pagina", + "desc": "Voegt alle PDF-pagina's samen tot ƩƩn grote pagina" + }, + "showJS": { + "title": "Toon Javascript", + "desc": "Zoekt en toont ieder script dat in een PDF is geĆÆnjecteerd" + }, + "autoRedact": { + "title": "Automatisch censureren", + "desc": "Automatisch censureren (onherkenbaar maken) van tekst in een PDF op basis van ingevoerde tekst" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF naar CSV", + "desc": "Haalt tabellen uit een PDF en converteert ze naar CSV" + }, + "autoSizeSplitPDF": { + "title": "Automatisch splitsen op grootte/aantal", + "desc": "Splits een enkele PDF in meerdere documenten op basis van grootte, aantal pagina's of aantal documenten" + }, + "overlay-pdfs": { + "title": "PDF's overlappen", + "desc": "Plaatst PDF's over een andere PDF heen" + }, + "split-by-sections": { + "title": "PDF in secties splitsen", + "desc": "Verdeel elke pagina van een PDF in kleinere horizontale en verticale secties" + }, + "AddStampRequest": { + "title": "Stempel toevoegen aan PDF", + "desc": "Voeg tekst of afbeeldingsstempels toe op vaste locaties" + }, + "removeImagePdf": { + "title": "Afbeelding verwijderen", + "desc": "Afbeeldingen uit PDF verwijderen om het bestandsgrootte te verminderen" + }, + "splitPdfByChapters": { + "title": "PDF op hoofdstukken splitsen", + "desc": "Splits een PDF op basis van zijn hoofdstukstructuur in meerdere bestanden." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "replaceColorPdf": { + "title": "Replace and Invert Color", + "desc": "Vervang de kleur van tekst en achtergrond in een PDF en omverkeer de volledige kleur van het document om bestandsgrootte te verkleinen." + } + }, + "viewPdf": { + "tags": "bekijken,lezen,annoteren,tekst,afbeelding", + "title": "View/Edit PDF", + "header": "PDF bekijken" + }, + "multiTool": { + "tags": "Multitool,meerdere bewerkingen,UI,klik sleep,voorkant,clientzijde,interactief,beweegbaar,verplaats", + "title": "PDF Multitool", + "header": "PDF Multitool", + "uploadPrompts": "Bestandsnaam", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "selectPages": "Page Select", + "selectedPages": "Selected Pages", + "page": "Page", + "deleteSelected": "Delete Selected", + "downloadAll": "Export", + "downloadSelected": "Export Selected", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "Page(s) Selected", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "samenvoegen,pagina bewerkingen,serverzijde", + "title": "Samenvoegen", + "header": "Meerdere PDF's samenvoegen (2+)", + "sortByName": "Sorteer op naam", + "sortByDate": "Sorteer op datum", + "removeCertSign": "Verwijder digitale handtekening in het samengevoegde bestand?", + "submit": "Samenvoegen" + }, + "split": { + "tags": "Pagina bewerkingen,verdelen,meerdere pagina's,knippen,serverzijde", + "title": "PDF splitsen", + "header": "PDF splitsen", + "desc": { + "1": "De nummers die je kiest zijn de paginanummers waarop je een splitsing wilt uitvoeren", + "2": "Als zodanig selecteren van 1,3,7-9 zou een 10 pagina's tellend document splitsen in 6 aparte PDF's met:", + "3": "Document #1: Pagina 1", + "4": "Document #2: Pagina 2 en 3", + "5": "Document #3: Pagina 4, 5, 6 en 7", + "6": "Document #4: Pagina 8", + "7": "Document #5: Pagina 9", + "8": "Document #6: Pagina 10" + }, + "splitPages": "Voer pagina's in om op te splitsen:", + "submit": "Splitsen" + }, + "rotate": { + "tags": "serverzijde", + "title": "PDF roteren", + "header": "PDF roteren", + "selectAngle": "Selecteer rotatiehoek (in veelvouden van 90 graden):", + "submit": "Roteren" + }, + "imageToPdf": { + "tags": "conversie,img,jpg,foto" + }, + "pdfToImage": { + "tags": "conversie,img,jpg,foto", + "title": "PDF naar afbeelding", + "header": "PDF naar afbeelding", + "selectText": "Afbeeldingsformaat", + "singleOrMultiple": "Resultaattype van pagina naar afbeelding", + "single": "EĆ©n grote afbeelding die alle pagina's combineert", + "multi": "Meerdere afbeeldingen, ƩƩn afbeelding per pagina", + "colorType": "Kleurtype", + "color": "Kleur", + "grey": "Grijstinten", + "blackwhite": "Zwart en wit (kan data verliezen!)", + "submit": "Omzetten", + "info": "Python is niet geĆÆnstalleerd. Vereist voor WebP-conversie.", + "placeholder": "(bijv. 1,2,8 of 4,7,12-16 of 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,even oneven,sorteren,verplaatsen", + "title": "Pagina organisator", + "header": "PDF pagina organisator", + "submit": "Pagina's herschikken", + "mode": { + "_value": "Modus", + "1": "Aangepaste paginavolgorde", + "2": "Omgekeerde volgorde", + "3": "Duplex sorteren", + "4": "Boekje sorteren", + "5": "Zijsteek boekje sorteren", + "6": "Oneven-even splitsen", + "7": "Eerste verwijderen", + "8": "Laatste verwijderen", + "9": "Eerste en laaste verwijderen", + "10": "Oneven-even samenvoeken", + "11": "Duplicate all pages" + }, + "placeholder": "(bijv. 1,3,2 of 4-8,2,10-12 of 2n-1)" + }, + "addImage": { + "tags": "img,jpg,foto", + "title": "Afbeelding toevoegen", + "header": "Afbeelding aan PDF toevoegen", + "everyPage": "Elke pagina?", + "upload": "Afbeelding toevoegen", + "submit": "Afbeelding toevoegen" + }, + "watermark": { + "tags": "Tekst,herhalend,label,eigen,copyright,handelsmerk,img,jpg,foto", + "title": "Watermerk toevoegen", + "header": "Watermerk toevoegen", + "customColor": "Aangepaste tekstkleur", + "selectText": { + "1": "Selecteer PDF om watermerk toe te voegen:", + "2": "Watermerk tekst:", + "3": "Tekengrootte:", + "4": "Rotatie (0-360):", + "5": "breedteSpacer (Ruimte tussen elk watermerk horizontaal):", + "6": "hoogteSpacer (Ruimte tussen elk watermerk verticaal):", + "7": "Transparantie (0% - 100%):", + "8": "Type watermerk:", + "9": "Watermerk afbeelding:", + "10": "PDF omzetten naar PDF-Afbeelding" + }, + "submit": "Watermerk toevoegen", + "type": { + "1": "Tekst", + "2": "Afbeelding" + } + }, + "permissions": { + "tags": "lezen,schrijven,bewerken,printen", + "title": "Rechten wijzigen", + "header": "Rechten wijzigen", + "warning": "Let op: om deze rechten onveranderlijk te maken, wordt aanbevolen om ze met een wachtwoord in te stellen via de add-password pagina.", + "selectText": { + "1": "Selecteer PDF om rechten te wijzigen", + "2": "In te stellen rechten", + "3": "Voorkom samenvoegen van document", + "4": "Voorkom inhoudsextractie", + "5": "Voorkom extractie voor toegankelijkheid", + "6": "Voorkom invullen van formulier", + "7": "Voorkom wijziging", + "8": "Voorkom annotatie wijziging", + "9": "Voorkom afdrukken", + "10": "Voorkom afdrukken in verschillende formaten" + }, + "submit": "Wijzigen" + }, + "removePages": { + "tags": "Pagina's verwijderen" + }, + "addPassword": { + "tags": "veilig,beveiliging", + "title": "Wachtwoord toevoegen", + "header": "Wachtwoord toevoegen (Versleutelen)", + "selectText": { + "1": "Selecteer PDF om te versleutelen", + "2": "Gebruikerswachtwoord", + "3": "Versleutelingssleutellengte", + "4": "Hogere waarden zijn sterker, maar lagere waarden hebben een betere compatibiliteit.", + "5": "In te stellen rechten (Aanbevolen om te gebruiken samen met eigenaarswachtwoord)", + "6": "Voorkomen van documentassemblage", + "7": "Voorkomen van inhoudsextractie", + "8": "Voorkomen van extractie voor toegankelijkheid", + "9": "Voorkomen van invullen van formulier", + "10": "Voorkomen van wijziging", + "11": "Voorkomen van annotatiewijziging", + "12": "Voorkomen van afdrukken", + "13": "Voorkomen van afdrukken in verschillende formaten", + "14": "Eigenaarswachtwoord", + "15": "Beperkt wat gedaan kan worden met het document nadat het is geopend (Niet ondersteund door alle lezers)", + "16": "Beperkt het openen van het document zelf" + }, + "submit": "Versleutelen" + }, + "removePassword": { + "tags": "veilig,ontsleutelen,beveiliging,wachtwoord verwijderen", + "title": "Wachtwoord verwijderen", + "header": "Wachtwoord verwijderen (Decrypteren)", + "selectText": { + "1": "Selecteer PDF om te decrypteren", + "2": "Wachtwoord" + }, + "submit": "Verwijderen" + }, + "compressPdfs": { + "tags": "comprimeren,klein" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Titel,auteur,datum,creatie,tijd,uitgever,producent,statistieken", + "title": "Titel:", + "header": "Metadata wijzigen", + "selectText": { + "1": "Pas de variabelen aan die je wilt wijzigen", + "2": "Verwijder alle metadata", + "3": "Toon aangepaste metadata:", + "4": "Overige metadata:", + "5": "Voeg aangepaste metadata-invoer toe" + }, + "author": "Auteur:", + "creationDate": "Aanmaakdatum (yyyy/MM/dd HH:mm:ss):", + "creator": "Maker:", + "keywords": "Trefwoorden:", + "modDate": "Wijzigingsdatum (yyyy/MM/dd HH:mm:ss):", + "producer": "Producent:", + "subject": "Onderwerp:", + "trapped": "Vastgezet:", + "submit": "Wijzigen" + }, + "fileToPDF": { + "tags": "transformatie,formaat,document,foto,slide,tekst,conversie,kantoor,docs,word,excel,powerpoint", + "title": "Bestand naar PDF", + "header": "Zet elk bestand om naar PDF", + "credit": "Deze service gebruikt LibreOffice en Unoconv voor bestandsconversie.", + "supportedFileTypesInfo": "Gestandaardiseerde Bestandstypen", + "supportedFileTypes": "Ondersteunde bestandstypen zijn hieronder opgenomen, maar raadpleeg voor een volledige lijst met ondersteunde formaten de LibreOffice-documentatie", + "submit": "Omzetten naar PDF" + }, + "ocr": { + "tags": "herkenning,tekst,afbeelding,scan,lezen,identificeren,detectie,bewerkbaar", + "title": "OCR / Scan opruimen", + "header": "Scans opruimen / OCR (Optical Character Recognition)", + "selectText": { + "1": "Selecteer talen die binnen de PDF gedetecteerd moeten worden (De vermelde zijn de momenteel gedetecteerde):", + "2": "Produceer tekstbestand met OCR-tekst naast de OCR'd PDF", + "3": "Corrigeer pagina's die onder een scheve hoek zijn gescand door ze terug te draaien", + "4": "Maak de pagina schoon, zodat het minder waarschijnlijk is dat OCR tekst in achtergrondruis vindt. (Geen uitvoerverandering)", + "5": "Maak de pagina schoon zodat OCR waarschijnlijk geen tekst in achtergrondruis vindt, behoudt opruiming in uitvoer.", + "6": "Negeert pagina's met interactieve tekst, OCR's alleen pagina's die afbeeldingen zijn", + "7": "Forceer OCR, zal elke pagina OCR'en en alle originele tekstelementen verwijderen", + "8": "Normaal (Zal een fout geven als de PDF tekst bevat)", + "9": "Aanvullende instellingen", + "10": "OCR-modus", + "11": "Verwijder afbeeldingen na OCR (Verwijdert ALLE afbeeldingen, alleen nuttig als onderdeel van conversiestap)", + "12": "Weergave Type (Geavanceerd)" + }, + "help": "Lees deze documentatie over hoe dit te gebruiken voor andere talen en/of gebruik buiten docker", + "credit": "Deze dienst maakt gebruik van qpdf en Tesseract voor OCR.", + "submit": "Verwerk PDF met OCR" + }, + "extractImages": { + "tags": "foto,opslaan,archief,zip,vastleggen,plukken", + "title": "Afbeeldingen extraheren", + "header": "Afbeeldingen extraheren", + "selectText": "Selecteer het beeldformaat voor geĆ«xtraheerde afbeeldingen", + "allowDuplicates": "Dubbele afbeeldingen opslaan", + "submit": "Extraheer" + }, + "pdfToPDFA": { + "tags": "archief,langdurig,standaard,conversie,opslag,bewaring", + "title": "PDF naar PDF/A", + "header": "PDF naar PDF/A", + "credit": "Deze service gebruikt libreoffice voor PDF/A-conversie", + "submit": "Converteren", + "tip": "Werkt momenteel niet voor meerdere inputs tegelijkertijd.", + "outputFormat": "Uitvoerindeling", + "pdfWithDigitalSignature": "Dit PDF bestand bevat een digitale handtekening. Deze wordt in de volgende stap verwijderd." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformatie,formaat,conversie,kantoor,microsoft,docfile", + "title": "PDF naar Word", + "header": "PDF naar Word", + "selectText": { + "1": "Uitvoerbestandsformaat" + }, + "credit": "Deze service gebruikt LibreOffice voor bestandsconversie.", + "submit": "Converteren" + }, + "PDFToPresentation": { + "tags": "slides,show,kantoor,microsoft", + "title": "PDF naar Presentatie", + "header": "PDF naar Presentatie", + "selectText": { + "1": "Uitvoerbestandsformaat" + }, + "credit": "Deze service gebruikt LibreOffice voor bestandsconversie.", + "submit": "Converteren" + }, + "PDFToText": { + "tags": "rijkformaat", + "title": "PDF naar RTF (Tekst)", + "header": "PDF naar RTF (Tekst)", + "selectText": { + "1": "Uitvoerbestandsformaat" + }, + "credit": "Deze service gebruikt LibreOffice voor bestandsconversie.", + "submit": "Converteren" + }, + "PDFToHTML": { + "tags": "webinhoud,browser vriendelijk", + "title": "PDF naar HTML", + "header": "PDF naar HTML", + "credit": "Deze service gebruikt pdftohtml voor bestandsconversie.", + "submit": "Converteren" + }, + "PDFToXML": { + "tags": "data-extractie,gestructureerd,code", + "title": "PDF naar XML", + "header": "PDF naar XML", + "credit": "Deze service gebruikt LibreOffice voor bestandsconversie.", + "submit": "Converteren" + }, + "ScannerImageSplit": { + "tags": "scheiden,auto-detecteren,scans,meer-foto,organiseren", + "selectText": { + "1": "Hoek drempel:", + "2": "Stelt de minimale absolute hoek in die nodig is om de afbeelding te roteren (standaard: 10).", + "3": "Tolerantie:", + "4": "Bepaalt het bereik van kleurvariatie rond de geschatte achtergrondkleur (standaard: 30).", + "5": "Minimum oppervlakte:", + "6": "Stelt de minimale oppervlakte drempel in voor een foto (standaard: 10000).", + "7": "Minimum contour oppervlakte:", + "8": "Stelt de minimale contour oppervlakte drempel in voor een foto", + "9": "Randgrootte:", + "10": "Stelt de grootte van de toegevoegde en verwijderde rand in om witte randen in de uitvoer te voorkomen (standaard: 1)." + }, + "info": "Python is niet geĆÆnstalleerd. Het wordt vereist om te worden uitgevoerd." + }, + "sign": { + "tags": "autoriseren,initialen,getekende-handtekening,tekst-handtekening,afbeelding-handtekening", + "title": "Ondertekenen", + "header": "PDF's ondertekenen", + "upload": "Upload afbeelding", + "draw": "Handtekening tekenen", + "text": "Tekstinvoer", + "clear": "Wissen", + "add": "Toevoegen", + "saved": "Gesleutelde handtekeningen opgeslagen", + "save": "Opslaan Signatuur", + "personalSigs": "Persoonlijke Signatuuren", + "sharedSigs": "Gedeelde Signatuuren", + "noSavedSigs": "Geen opgeslagen signatuuren gevonden", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "statisch,deactiveren,niet-interactief,stroomlijnen", + "title": "Afvlakken", + "header": "PDF's afvlakken", + "flattenOnlyForms": "Alleen formulieren afvlakken", + "submit": "Afvlakken" + }, + "repair": { + "tags": "repareren,herstellen,correctie,terughalen", + "title": "Repareren", + "header": "PDF's repareren", + "submit": "Repareren" + }, + "removeBlanks": { + "tags": "opruimen,stroomlijnen,geen-inhoud,organiseren", + "title": "Verwijder blanco's", + "header": "Verwijder lege pagina's", + "threshold": "Pixel witheid drempel:", + "thresholdDesc": "Drempel voor het bepalen hoe wit een witte pixel moet zijn om als 'Wit' te worden geclassificeerd. 0 = Zwart, 255 zuiver wit.", + "whitePercent": "Wit percentage (%):", + "whitePercentDesc": "Percentage van de pagina dat 'witte' pixels moet zijn om verwijderd te worden", + "submit": "Blanco's verwijderen" + }, + "removeAnnotations": { + "tags": "opmerkingen,highlight,notities,opmaak,verwijderen", + "title": "Verwijder annotaties", + "header": "Verwijder annotaties", + "submit": "Verwijderen" + }, + "compare": { + "tags": "onderscheiden,contrasteren,veranderingen,analyse", + "title": "Vergelijken", + "header": "PDF's vergelijken", + "highlightColor": { + "1": "Hervormingskleur 1:", + "2": "Hervormingskleur 2:" + }, + "document": { + "1": "Document 1", + "2": "Document 2" + }, + "submit": "Vergelijken", + "complex": { + "message": "EĆ©n of beide van de bijgewerkte documenten zijn grote bestanden, het vergelijken kan mogelijk minder nauwkeurig zijn." + }, + "large": { + "file": { + "message": "EĆ©n of beiden van de bijgewerkte documenten zijn te groot om verwerkt te worden." + } + }, + "no": { + "text": { + "message": "Een of beide geselecteerde PDF-bestanden bevatten geen tekstinhoud. Kies a.u.b. PDF-bestanden met tekst voor vergelijking." + } + } + }, + "certSign": { + "tags": "authenticeren,PEM,P12,officieel,versleutelen", + "title": "Certificaat ondertekening", + "header": "Onderteken een PDF met je certificaat (in ontwikkeling)", + "selectPDF": "Selecteer een PDF-bestand voor ondertekening:", + "jksNote": "Let op: als het certificaattype hieronder niet staat, converteer het dan naar een Java Keystore (.jks) bestand met de keytool command line tool. Kies vervolgens de .jks bestandsoptie.", + "selectKey": "Selecteer je privĆ©sleutelbestand (PKCS#8 formaat, kan .pem of .der zijn):", + "selectCert": "Selecteer je certificaatbestand (X.509 formaat, kan .pem of .der zijn):", + "selectP12": "Selecteer je PKCS#12 Sleutelopslagbestand (.p12 of .pfx) (Optioneel, indien verstrekt, moet het je privĆ©sleutel en certificaat bevatten):", + "selectJKS": "Selecteer je Java Keystore bestand (.jks of .keystore):", + "certType": "Certificaattype", + "password": "Voer je sleutelopslag of privĆ©sleutel wachtwoord in (indien van toepassing):", + "showSig": "Toon handtekening", + "reason": "Reden", + "location": "Locatie", + "name": "Naam", + "showLogo": "Logotype tonen", + "submit": "PDF ondertekenen" + }, + "removeCertSign": { + "tags": "authenticeren,PEM,P12,officieel,ontsleutelen", + "title": "Verwijder certificaat", + "header": "Verwijder het digitale certificaat van de PDF", + "selectPDF": "Selecteer een PDF bestand:", + "submit": "Verwijder certificaat" + }, + "pageLayout": { + "tags": "samenvoegen,composiet,enkel-zicht,organiseren", + "title": "Meerdere pagina indeling", + "header": "Meerdere pagina indeling", + "pagesPerSheet": "Pagina's per vel:", + "addBorder": "Randen toevoegen", + "submit": "Indienen" + }, + "scalePages": { + "tags": "resize,aanpassen,dimensie,aanpassen", + "title": "Pagina-schaal aanpassen", + "header": "Pagina-schaal aanpassen", + "pageSize": "Grootte van een pagina van het document.", + "keepPageSize": "Oorspronkelijke grootte behouden", + "scaleFactor": "Zoomniveau (uitsnede) van een pagina.", + "submit": "Indienen" + }, + "add-page-numbers": { + "tags": "pagineren,labelen,organiseren,indexeren" + }, + "auto-rename": { + "tags": "auto-detecteren,op-header-gebaseerd,organiseren,herlabelen", + "title": "Automatisch hernoemen", + "header": "PDF automatisch hernoemen", + "submit": "Automatisch hernoemen" + }, + "adjust-contrast": { + "tags": "kleur-correctie,afstemmen,aanpassen,verbeteren" + }, + "crop": { + "tags": "trimmen,verkleinen,bewerken,vorm", + "title": "Bijwerken", + "header": "PDF bijsnijden", + "submit": "Indienen" + }, + "autoSplitPDF": { + "tags": "QR-gebaseerd,scheiden,scan-segment,organiseren", + "title": "PDF automatisch splitsen", + "header": "PDF automatisch splitsen", + "description": "Print, Voeg in, Scan, upload, en laat ons je documenten automatisch scheiden. Geen handmatig sorteerwerk nodig.", + "selectText": { + "1": "Print enkele scheidingsbladen van hieronder (Zwart-wit is prima).", + "2": "Scan al je documenten tegelijk door het scheidingsblad ertussen te plaatsen.", + "3": "Upload het enkele grote gescande PDF-bestand en laat Stirling PDF de rest afhandelen.", + "4": "Scheidingspagina's worden automatisch gedetecteerd en verwijderd, wat een net einddocument garandeert." + }, + "formPrompt": "Dien PDF in met Stirling-PDF Pagina-scheiders:", + "duplexMode": "Duplex Modus (voor- en achterkant scannen)", + "dividerDownload2": "Download 'Auto Splitter Divider (with instructions).pdf'", + "submit": "Indienen" + }, + "sanitizePdf": { + "tags": "schoonmaken,veilig,veilig,bedreigingen verwijderen" + }, + "URLToPDF": { + "tags": "web-capture,pagina opslaan,web-naar-doc,archief", + "title": "URL naar PDF", + "header": "URL naar PDF", + "submit": "Converteren", + "credit": "Gebruikt WeasyPrint" + }, + "HTMLToPDF": { + "tags": "markup,web-inhoud,transformatie,omzetten", + "title": "HTML naar PDF", + "header": "HTML naar PDF", + "help": "Accepteert HTML-bestanden en ZIP's die html/css/afbeeldingen etc. bevatten", + "submit": "Converteren", + "credit": "Gebruikt WeasyPrint", + "zoom": "Zoomniveau voor weergave van de website.", + "pageWidth": "Breedte van de pagina in centimeters. (leeg voor standaard)", + "pageHeight": "Hoogte van de pagina in centimeters. (leeg voor standaard)", + "marginTop": "Marge bovenaan de pagina in millimeters. (leeg voor standaard)", + "marginBottom": "Marge onderaan de pagina in millimeters. (leeg voor standaard)", + "marginLeft": "Marge links van de pagina in millimeters. (leeg voor standaard)", + "marginRight": "Marge rechts van de pagina in millimeters. (leeg voor standaard)", + "printBackground": "De achtergrond van websites weergeven.", + "defaultHeader": "Standaard koptekst weergeven (naam en paginanummer)", + "cssMediaType": "Wijzig het CSS-mediatype van de pagina.", + "none": "Geen", + "print": "Printen", + "screen": "Scherm" + }, + "MarkdownToPDF": { + "tags": "markup,web-inhoud,transformatie,omzetten", + "title": "Markdown naar PDF", + "header": "Markdown naar PDF", + "submit": "Converteren", + "help": "In ontwikkeling", + "credit": "Gebruikt WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "informatie,data,statistieken", + "title": "Informatie over PDF ophalen", + "header": "Informatie over PDF ophalen", + "submit": "Haal informatie op", + "downloadJson": "JSON downloaden" + }, + "extractPage": { + "tags": "extraheren" + }, + "PdfToSinglePage": { + "tags": "ƩƩn pagina" + }, + "showJS": { + "tags": "JS", + "title": "Toon Javascript", + "header": "Toon Javascript", + "downloadJS": "Javascript downloaden", + "submit": "Toon" + }, + "autoRedact": { + "tags": "Verzwakken, Verbergen, Uitroepen, Gekleurd, Verborgen", + "title": "Automatisch censureren", + "header": "Automatisch censureren", + "colorLabel": "Kleur", + "textsToRedactLabel": "Tekst om te censureren (gescheiden door regels)", + "textsToRedactPlaceholder": "bijv.\\Vertrouwelijk \\nTopgeheim", + "useRegexLabel": "Gebruik regex", + "wholeWordSearchLabel": "Zoeken op hele woorden", + "customPaddingLabel": "Aangepaste extra ruimtevulling", + "convertPDFToImageLabel": "Converteer PDF naar PDF-afbeelding (wordt gebruikt om tekst achter het vak te verwijderen)", + "submitButton": "Indienen" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,tabel extractie,extractie,converteren" + }, + "autoSizeSplitPDF": { + "tags": "pdf,splitsen,document,organiseren" + }, + "overlay-pdfs": { + "tags": "Overlappen", + "header": "PDF bestanden overlappen", + "baseFile": { + "label": "Selecteer basis PDF-bestand" + }, + "overlayFiles": { + "label": "Selecteer overlappende PDF-bestanden" + }, + "mode": { + "label": "Selecteer overlappingsmodus", + "sequential": "Sequentieel overlappen", + "interleaved": "GeĆÆnterlinieerd overlappen", + "fixedRepeat": "Overlappen met vaste herhaling" + }, + "counts": { + "label": "Aantal keren overlappen (voor vaste herhalings modus)", + "placeholder": "Voer door komma's gescheiden aantallen in (bijv., 2,3,1)" + }, + "position": { + "label": "Selecteer overlappingspositie", + "foreground": "Voorgrond", + "background": "Achtergrond" + }, + "submit": "Indienen" + }, + "split-by-sections": { + "tags": "Sectie splitsen, Verdelen, Aanpassen", + "title": "PDF in secties splitsen", + "header": "PDF in secties splitsen", + "horizontal": { + "label": "Horizontale secties", + "placeholder": "Voer het aantal horizontale secties in" + }, + "vertical": { + "label": "Verticale secties", + "placeholder": "Voer het aantal verticale secties in" + }, + "submit": "PDF splitsen", + "merge": "Samenvoegen in ƩƩn PDF" + }, + "AddStampRequest": { + "tags": "Stempel, Afbeelding toevoegen, afbeelding centreren, watermerk, PDF, Insluiten, Aanpassen", + "header": "Stempel PDF", + "title": "Stempel PDF", + "stampType": "Soort stempel", + "stampText": "Stempel tekst", + "stampImage": "Stempel afbeelding", + "alphabet": "Alfabet", + "fontSize": "Tekst/afbeelding grootte", + "rotation": "Rotatie", + "opacity": "Transparantie", + "position": "Positie", + "overrideX": "X coƶrdinaat overschrijven", + "overrideY": "Y coƶrdinaat overschrijven", + "customMargin": "Aangepaste marge", + "customColor": "Aangepaste tekstkleur", + "submit": "Indienen" + }, + "removeImagePdf": { + "tags": "Afbeelding verwijderen, Paginabewerkingen, Achterkant, Serverkant" + }, + "splitPdfByChapters": { + "tags": "splitsen, hoofdstukken, bookmarks, organiseren" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Replace-Invert-Color", + "header": "Kleur-instellingen voor PDF's", + "selectText": { + "1": "Vervang of invertere kleure opties", + "2": "Standaard (hoog contrast kleuren)", + "3": "Aangepast (aangepaste kleuren)", + "4": "Volledig inverteren (alle kleuren omverkeren)", + "5": "Opties voor hoog contrast", + "6": "wit tekst op een zwart grondvlak", + "7": "zwarte tekst op wit grondvlak", + "8": "gele tekst op een zwart grondvlak", + "9": "groene tekst op een zwart grondvlak", + "10": "Kies de tekstkleur", + "11": "Kies het achtergrondkleur" + }, + "submit": "Vervang" + }, + "replaceColorPdf": { + "tags": "Kleur vervangen, pagina-acties, achterkant, serverzijde" + }, + "login": { + "title": "Inloggen", + "header": "Inloggen", + "signin": "Inloggen", + "rememberme": "Onthoud mij", + "invalid": "Ongeldige gebruikersnaam of wachtwoord.", + "locked": "Je account is geblokkeerd.", + "signinTitle": "Gelieve in te loggen", + "ssoSignIn": "Inloggen via Single Sign-on", + "oAuth2AutoCreateDisabled": "OAUTH2 Automatisch aanmaken gebruiker uitgeschakeld", + "oAuth2AdminBlockedUser": "Registratie of inloggen van niet-registreerde gebruikers is helaas momenteel geblokkeerd. Neem contact op met de beheerder.", + "oauth2RequestNotFound": "Autorisatieverzoek niet gevonden", + "oauth2InvalidUserInfoResponse": "Ongeldige reactie op gebruikersinfo", + "oauth2invalidRequest": "Ongeldig verzoek", + "oauth2AccessDenied": "Toegang geweigerd", + "oauth2InvalidTokenResponse": "Ongeldige tokenreactie", + "oauth2InvalidIdToken": "Ongeldige ID token", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "De gebruiker is gedesactiveerd, inloggen is momenteel geblokkeerd voor deze gebruikersnaam. Neem contact op met de beheerder.", + "alreadyLoggedIn": "U zit reeds ingelogd bij", + "alreadyLoggedIn2": "apparaten. U moet u a.u.b. uitloggen van de apparaten en opnieuw proberen.", + "toManySessions": "U heeft te veel actieve sessies", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF naar enkele pagina", + "header": "PDF naar enkele pagina", + "submit": "Converteren naar enkele pagina" + }, + "pageExtracter": { + "title": "Pagina's extraheren", + "header": "Pagina's extraheren", + "submit": "Extraheren", + "placeholder": "(bijv. 1,2,8 of 4,7,12-16 of 2n-1)" + }, + "sanitizePDF": { + "title": "PDF opschonen", + "header": "Een PDF-bestand opschonen", + "selectText": { + "1": "Verwijder Javascript-acties", + "2": "Verwijder ingebedde bestanden", + "3": "Remove XMP metadata", + "4": "Verwijder links", + "5": "Verwijder lettertypen", + "6": "Remove Document Info Metadata" + }, + "submit": "PDF opschonen" + }, + "adjustContrast": { + "title": "Contrast aanpassen", + "header": "Contrast aanpassen", + "contrast": "Kehrbrechting:", + "brightness": "Helderheid:", + "saturation": "Verzadiging:", + "download": "Downloaden" + }, + "compress": { + "title": "Comprimeren", + "header": "PDF comprimeren", + "credit": "Deze functie gebruikt qpdf voor PDF Compressie/Optimalisatie.", + "grayscale": { + "label": "Grijsschaal toepassen voor compressie" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Optimalisatieniveau:", + "4": "Automatische modus - Past kwaliteit automatisch aan om PDF naar exacte grootte te krijgen", + "5": "Verwachte PDF-grootte (bijv. 25MB, 10.8MB, 25KB)" + }, + "submit": "Comprimeren" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "Pagina verwijderaar", + "header": "PDF pagina verwijderaar", + "pagesToDelete": "Te verwijderen pagina's (Voer een door komma's gescheiden lijst met paginanummers in):", + "submit": "Pagina's verwijderen", + "placeholder": "(bijv. 1,2,6 of 1-10,15-30)" + }, + "imageToPDF": { + "title": "Afbeelding naar PDF", + "header": "Afbeelding naar PDF", + "submit": "Omzetten", + "selectLabel": "Opties voor afbeelding passend maken", + "fillPage": "Pagina vullen", + "fitDocumentToImage": "Pagina passend maken voor afbeelding", + "maintainAspectRatio": "Beeldverhoudingen behouden", + "selectText": { + "2": "PDF automatisch draaien", + "3": "Meervoudige bestandslogica (Alleen ingeschakeld bij werken met meerdere afbeeldingen)", + "4": "Voeg samen in ƩƩn PDF", + "5": "Zet om naar afzonderlijke PDF's" + } + }, + "PDFToCSV": { + "title": "PDF naar CSV", + "header": "PDF naar CSV", + "prompt": "Kies pagina om tabel te extraheren", + "submit": "Extraheren" + }, + "split-by-size-or-count": { + "title": "PDF splitsen op grootte of aantal", + "header": "PDF splitsen op grootte of aantal", + "type": { + "label": "Selecteer splits type", + "size": "Op grootte", + "pageCount": "Op pagina aantal", + "docCount": "Op document aantal" + }, + "value": { + "label": "Voer waarde in", + "placeholder": "Voer grootte (bijv., 2MB of 3KB) of aantal (bijv., 5)" + }, + "submit": "Indienen" + }, + "printFile": { + "title": "Print bestand", + "header": "Print bestand naar printer", + "selectText": { + "1": "Selecteer bestand om te printen", + "2": "Voer printernaam in" + }, + "submit": "Druk af" + }, + "licenses": { + "nav": "Licenties", + "title": "Licenties van derden", + "header": "Licenties van derden", + "module": "Module", + "version": "Versie", + "license": "Licentie" + }, + "survey": { + "nav": "EnquĆŖte", + "title": "Stirling-PDF EnquĆŖte", + "description": "Stirling-PDF heeft geen tracking, dus we willen van onze gebruikers horen om Stirling-PDF te verbeteren.", + "changes": "Stirling-PDF is sinds de laatste enquĆŖte veranderd! Zie hier onze blogpost voor meer informatie:", + "changes2": "Met deze veranderingen krijgen we betaalde bedrijfsondersteuning en financiering", + "please": "Overweeg alstublieft om onze enquĆŖte in te vullen!", + "disabled": "(EnquĆŖte popup wordt in een toekomstige update weggehaald, maar is beschikbaar aan de onderkant van de pagina.)", + "button": "Vul enquĆŖte in.", + "dontShowAgain": "Niet weer tonen", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Afbeelding verwijderen", + "header": "Afbeelding verwijderen", + "removeImage": "Afbeelding verwijderen", + "submit": "Verwijder afbeelding" + }, + "splitByChapters": { + "title": "PDF splits op hoofdstukken", + "header": "PDF splitsen per hoofdstuk", + "bookmarkLevel": "Boekmarkeer niveau", + "includeMetadata": "Metadata inclusief", + "allowDuplicates": "Dubbele items toestaan", + "desc": { + "1": "Dit hulpmiddel splits een PDF-bestand op in meerdere PDF's gebaseerd op zijn hoofdstukstructuur.", + "2": "Boekmarkeer niveau: Kies het boekmarkeer niveau om te gebruiken voor delen (0 voor topniveau, 1 voor tweedelvou, etc.).", + "3": "Metadata inclusief: Als gecijfeld, de originele PDF's metadata wordt ingevoegd in elk gesplitst PDF-bestand.", + "4": "Dubbele items toestaan: Als gecijfeld, zorgen multiple boekmarkeersymboolen op dezelfde pagina voor het maken van aparte PDF-bestanden." + }, + "submit": "PDF splitsen" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Releases", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Current Release" + }, + "note": "Release notes are only available in English" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/no-NB/translation.json b/frontend/public/locales/no-NB/translation.json new file mode 100644 index 000000000..d50fed454 --- /dev/null +++ b/frontend/public/locales/no-NB/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "SkriftstĆørrelse", + "fontName": "Skrifttype", + "title": "Legg til Sidetall", + "header": "Legg til Sidetall", + "selectText": { + "1": "Velg PDF-fil:", + "2": "MarginstĆørrelse", + "3": "Posisjon", + "4": "Startnummer", + "5": "Sider Ć„ nummerere", + "6": "Tilpasset Tekst" + }, + "customTextDesc": "Tilpasset Tekst", + "numberPagesDesc": "Hvilke sider som skal nummereres, standard 'alle', aksepterer ogsĆ„ 1-5 eller 2,5,9 osv.", + "customNumberDesc": "Standard til {n}, aksepterer ogsĆ„ 'Side {n} av {total}', 'Tekst-{n}', '{filnavn}-{n}", + "submit": "Legg til Sidetall" + }, + "pdfPrompt": "Velg PDF(er)", + "multiPdfPrompt": "Velg PDF-filer (2+)", + "multiPdfDropPrompt": "Velg (eller dra og slipp) alle PDF-ene du trenger", + "imgPrompt": "Velg Bilde(r)", + "genericSubmit": "Send inn", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Denne prosessen kan ta opptil ett minutt avhengig av filstĆørrelse", + "pageOrderPrompt": "Tilpasset side rekkefĆølge (Skriv inn en kommaseparert liste over sidetall eller funksjoner som 2n+1):", + "pageSelectionPrompt": "Tilpasset Sidevalg (Skriv inn en kommaseparert liste over sidetall 1,5,6 eller Funksjoner som 2n+1):", + "goToPage": "GĆ„", + "true": "Sann", + "false": "Usann", + "unknown": "Ukjent", + "save": "Lagre", + "saveToBrowser": "Lagre til Nettleser", + "close": "Lukk", + "filesSelected": "filer valgt", + "noFavourites": "Ingen favoritter lagt til", + "downloadComplete": "Nedlasting FullfĆørt", + "bored": "Lei av Ć„ vente?", + "alphabet": "Alfabet", + "downloadPdf": "Last ned PDF", + "text": "Tekst", + "font": "Skrifttype", + "selectFillter": "-- Velg --", + "pageNum": "Sidenummer", + "sizes": { + "small": "Liten", + "medium": "Middels", + "large": "Stor", + "x-large": "Ekstra Stor" + }, + "error": { + "pdfPassword": "PDF-dokumentet er passordbeskyttet og enten ble passordet ikke oppgitt eller var feil", + "_value": "Feil", + "sorry": "Beklager for problemet!", + "needHelp": "Trenger du hjelp / Har du funnet et problem?", + "contactTip": "Hvis du fortsatt har problemer, ikke nĆøl med Ć„ kontakte oss for hjelp. Du kan sende inn en billett pĆ„ vĆ„r GitHub-side eller kontakte oss via Discord:", + "404": { + "head": "404 - Side ikke funnet | Oops, vi falt i koden!", + "1": "Vi kan ikke finne siden du leter etter.", + "2": "Noe gikk galt" + }, + "github": "Send inn en billett pĆ„ GitHub", + "showStack": "Vis stakksporing", + "copyStack": "Kopier stakksporing", + "githubSubmit": "GitHub - Send inn en billett", + "discordSubmit": "Discord - Send inn stĆøtteinnlegg" + }, + "delete": "Slett", + "username": "Brukernavn", + "password": "Passord", + "welcome": "Velkommen", + "property": "Egenskap", + "black": "Svart", + "white": "Hvit", + "red": "RĆød", + "green": "GrĆønn", + "blue": "BlĆ„", + "custom": "Tilpasset...", + "WorkInProgess": "Arbeid pĆ„gĆ„r, Kan vƦre feil eller buggy, Vennligst rapporter eventuelle problemer!", + "poweredBy": "Drevet av", + "yes": "Ja", + "no": "Nei", + "changedCredsMessage": "Legitimasjon endret!", + "notAuthenticatedMessage": "Bruker ikke autentisert.", + "userNotFoundMessage": "Bruker ikke funnet.", + "incorrectPasswordMessage": "NĆ„vƦrende passord er feil.", + "usernameExistsMessage": "Det nye brukernavnet eksisterer allerede.", + "invalidUsernameMessage": "Ugyldig brukernavn, brukernavnet kan bare inneholde bokstaver, tall og fĆølgende spesialtegn @._+- eller mĆ„ vƦre en gyldig e-postadresse.", + "invalidPasswordMessage": "Passordet kan ikke vƦre tomt og mĆ„ ikke ha mellomrom i begynnelsen eller slutten.", + "confirmPasswordErrorMessage": "Nytt passord og Bekreft nytt passord mĆ„ vƦre like.", + "deleteCurrentUserMessage": "Kan ikke slette den innloggede brukeren.", + "deleteUsernameExistsMessage": "Brukernavnet eksisterer ikke og kan ikke slettes.", + "downgradeCurrentUserMessage": "Kan ikke nedgradere den innloggede brukerens rolle.", + "disabledCurrentUserMessage": "Den pĆ„logga brukeren kan ikke deaktiveres.", + "downgradeCurrentUserLongMessage": "Kan ikke nedgradere den innloggede brukerens rolle. Derfor vil ikke den innloggede brukeren bli vist.", + "userAlreadyExistsOAuthMessage": "Brukeren eksisterer allerede som en OAuth2-bruker.", + "userAlreadyExistsWebMessage": "Brukeren eksisterer allerede som en web-bruker.", + "oops": "Oops!", + "help": "Hjelp", + "goHomepage": "GĆ„ til Hjemmeside", + "joinDiscord": "Bli med pĆ„ vĆ„r Discord-server", + "seeDockerHub": "Se Docker Hub", + "visitGithub": "BesĆøk Github Repository", + "donate": "Doner", + "color": "Farge", + "sponsor": "Sponsor", + "info": "Info", + "pro": "Pro", + "page": "Side", + "pages": "Sider", + "loading": "Laster...", + "addToDoc": "Legg til i dokument", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "PersonvernerklƦring", + "terms": "VilkĆ„r og betingelser", + "accessibility": "Tilgjengelighet", + "cookie": "Informasjonskapsler", + "impressum": "Juridisk informasjon", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Pipeline-meny (Beta)", + "uploadButton": "Last opp tilpasset", + "configureButton": "Konfigurer", + "defaultOption": "Tilpasset", + "submitButton": "Send inn", + "help": "Pipeline hjelp", + "scanHelp": "Mappe skanning hjelp", + "deletePrompt": "Er du sikker pĆ„ at du vil slette denne pipelinen?", + "tags": "automatisere,sekvens,skriptet,batch-prosess", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Pipeline konfigurasjon", + "pipelineNameLabel": "Pipeline navn", + "saveSettings": "Lagre operasjonsinnstillinger", + "pipelineNamePrompt": "Skriv inn pipeline-navn her", + "selectOperation": "Velg operasjon", + "addOperationButton": "Legg til operasjon", + "pipelineHeader": "Pipeline:", + "saveButton": "Last ned", + "validateButton": "Valider" + }, + "enterpriseEdition": { + "button": "Oppgrader til Pro", + "warning": "Denne funksjonen er kun tilgjengelig for Pro-brukere.", + "yamlAdvert": "Stirling PDF Pro stĆøtter YAML-konfigurasjons filer og andre SSO funksjoner.", + "ssoAdvert": "SĆøker du etter flere administrerings funksjoner? Sjekk ut Stirling PDF Pro" + }, + "analytics": { + "title": "Vill du gjĆøre Stirling PDF bedre?", + "paragraph1": "Stirling PDF har valgfri analyse for Ć„ hjelpe oss med Ć„ forbedre produktet. Vi sporer ikke personlig informasjon eller filinnhold.", + "paragraph2": "Vennligst vurder Ć„ aktivere analyse for Ć„ hjelpe Stirling-PDF Ć„ vokse og for Ć„ la oss forstĆ„ brukerne vĆ„re bedre.", + "enable": "Aktiver analyse", + "disable": "Deaktiver analyse", + "settings": "Du kan endre innstillingene for analyse i config/settings.yml filen" + }, + "navbar": { + "favorite": "Favoritter", + "recent": "New and recently updated", + "darkmode": "MĆørk Modus", + "language": "SprĆ„k", + "settings": "Innstillinger", + "allTools": "VerktĆøy", + "multiTool": "Multi VerktĆøy", + "search": "SĆøk", + "sections": { + "organize": "Organisere", + "convertTo": "Konverter til PDF", + "convertFrom": "Konverter fra PDF", + "security": "Signer & Sikkerhet", + "advance": "Avansert", + "edit": "Vis & Rediger", + "popular": "PopulƦrt" + } + }, + "settings": { + "title": "Innstillinger", + "update": "Oppdatering tilgjengelig", + "updateAvailable": "{0} er den nĆ„vƦrende installerte versjonen. En ny versjon ({1}) er tilgjengelig.", + "appVersion": "App Versjon:", + "downloadOption": { + "title": "Velg nedlastingsalternativ (For enkeltfil ikke-zip nedlastinger):", + "1": "ƅpne i samme vindu", + "2": "ƅpne i nytt vindu", + "3": "Last ned fil" + }, + "zipThreshold": "Zip filer nĆ„r antall nedlastede filer overstiger", + "signOut": "Logg ut", + "accountSettings": "Kontoinnstillinger", + "bored": { + "help": "Aktiverer pĆ„skeegg-spill" + }, + "cacheInputs": { + "name": "Lagre skjemainput", + "help": "Aktiver for Ć„ lagre tidligere brukte input for fremtidige kjĆøringer" + } + }, + "changeCreds": { + "title": "Endre Legitimasjon", + "header": "Oppdater Konto Detaljer", + "changePassword": "Du bruker standard pĆ„loggingsdetaljer. Vennligst skriv inn et nytt passord", + "newUsername": "Nytt Brukernavn", + "oldPassword": "NĆ„vƦrende Passord", + "newPassword": "Nytt Passord", + "confirmNewPassword": "Bekreft Nytt Passord", + "submit": "Send Endringer" + }, + "account": { + "title": "Kontoinnstillinger", + "accountSettings": "Kontoinnstillinger", + "adminSettings": "Admin Innstillinger - Vis og Legg til Brukere", + "userControlSettings": "Brukerkontroll Innstillinger", + "changeUsername": "Endre Brukernavn", + "newUsername": "Nytt Brukernavn", + "password": "Bekreftelsespassord", + "oldPassword": "Gammelt Passord", + "newPassword": "Nytt Passord", + "changePassword": "Endre Passord", + "confirmNewPassword": "Bekreft Nytt Passord", + "signOut": "Logg ut", + "yourApiKey": "Din API-nĆøkkel", + "syncTitle": "Synkroniser nettleserinnstillinger med Konto", + "settingsCompare": "Innstillingsammenligning:", + "property": "Egenskap", + "webBrowserSettings": "Nettleserinnstilling", + "syncToBrowser": "Synk Konto -> Nettleser", + "syncToAccount": "Synk Konto <- Nettleser" + }, + "adminUserSettings": { + "title": "Brukerkontroll Innstillinger", + "header": "Admin Brukerkontroll Innstillinger", + "admin": "Admin", + "user": "Bruker", + "addUser": "Legg til Ny Bruker", + "deleteUser": "Slett Bruker", + "confirmDeleteUser": "Skal brukeren slettes?", + "confirmChangeUserStatus": "Skal brukeren deaktiveres/aktiveres?", + "usernameInfo": "Brukernavn kan bare inneholde bokstaver, tall og fĆølgende spesialtegn @._+- eller mĆ„ vƦre en gyldig e-postadresse.", + "roles": "Roller", + "role": "Rolle", + "actions": "Handlinger", + "apiUser": "Begrenset API Bruker", + "extraApiUser": "Ekstra Begrenset API Bruker", + "webOnlyUser": "Kun Web Bruker", + "demoUser": "Demo Bruker (Ingen tilpassede innstillinger)", + "internalApiUser": "Intern API Bruker", + "forceChange": "Tving bruker til Ć„ endre passord ved innlogging", + "submit": "Lagre Bruker", + "changeUserRole": "Endre Brukerens Rolle", + "authenticated": "Autentisert", + "editOwnProfil": "Rediger din profil", + "enabledUser": "aktivert bruker", + "disabledUser": "deaktivert bruker", + "activeUsers": "Aktive brukere:", + "disabledUsers": "Deaktiverte brukere:", + "totalUsers": "Totalt antall brukere:", + "lastRequest": "Siste spĆørring", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Database Import/Eksport", + "header": "Database Import/Eksport", + "fileName": "Fil navn", + "creationDate": "Opprettelsesdato", + "fileSize": "FilstĆørrelse", + "deleteBackupFile": "Slett sikkerhetskopifil", + "importBackupFile": "Importer sikkerhetskopifil", + "createBackupFile": "Lag sikkerhetskopifil", + "downloadBackupFile": "Last ned sikkerhetskopifil", + "info_1": "NĆ„r du importerer data, er det avgjĆørende Ć„ sikre riktig struktur. Hvis du er usikker pĆ„ hva du gjĆør, bĆør du sĆøke rĆ„d og stĆøtte fra en profesjonell. En feil i strukturen kan fĆøre til applikasjonsfeil, inkludert fullstendig manglende evne til Ć„ kjĆøre applikasjonen.", + "info_2": "Filnavnet spiller ingen rolle ved opplasting. Det vil bli omdĆøpt etterpĆ„ for Ć„ fĆølge formatet backup_user_yyyyMMddHHmm.sql, for Ć„ sikre en konsekvent navnekonvensjon.", + "submit": "Importer sikkerhetskopi", + "importIntoDatabaseSuccessed": "Import til database vellykket", + "backupCreated": "Sikkerhetskopiering opprettet", + "fileNotFound": "Fil ikke funnet", + "fileNullOrEmpty": "Fil mĆ„ ikke vƦre tom eller null", + "failedImportFile": "Import av fil mislyktes", + "notSupported": "Denne funksjonen er ikke tilgjengelig for din databasetilkobling." + }, + "session": { + "expired": "Ƙkten din har utlĆøpt. Vennligst oppdater siden og prĆøv igjen.", + "refreshPage": "Oppdater Side" + }, + "home": { + "desc": "Din lokale one-stop-shop for alle dine PDF-behov.", + "searchBar": "SĆøk etter funksjoner...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Vis, annoter, legg til tekst eller bilder" + }, + "setFavorites": "Angi Favoritter", + "hideFavorites": "Skjul Favoritter", + "showFavorites": "Vis Favoritter", + "legacyHomepage": "Gammel hjemmeside", + "newHomePage": "PrĆøv vĆ„r nye hjemmeside!", + "alphabetical": "Alfabetisk", + "globalPopularity": "Global Popularitet", + "sortBy": "Sorter etter:", + "multiTool": { + "title": "PDF Multi VerktĆøy", + "desc": "SlĆ„ sammen, roter, omorganiser og fjern sider" + }, + "merge": { + "title": "SlĆ„ sammen", + "desc": "SlĆ„ enkelt sammen flere PDF-er til Ć©n." + }, + "split": { + "title": "Del opp", + "desc": "Del PDF-er i flere dokumenter" + }, + "rotate": { + "title": "Roter", + "desc": "Roter enkelt dine PDF-er." + }, + "imageToPdf": { + "title": "Bilde til PDF", + "desc": "Konverter et bilde (PNG, JPEG, GIF) til PDF." + }, + "pdfToImage": { + "title": "PDF til Bilde", + "desc": "Konverter en PDF til et bilde. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Organiser", + "desc": "Fjern/omorganiser sider i hvilken som helst rekkefĆølge" + }, + "addImage": { + "title": "Legg til bilde", + "desc": "Legger til et bilde pĆ„ en angitt plassering i PDF-en" + }, + "watermark": { + "title": "Legg til Vannmerke", + "desc": "Legg til et tilpasset vannmerke i din PDF-dokument." + }, + "permissions": { + "title": "Endre Tillatelser", + "desc": "Endre tillatelsene til din PDF-dokument" + }, + "removePages": { + "title": "Fjern", + "desc": "Slett uĆønskede sider fra din PDF-dokument." + }, + "addPassword": { + "title": "Legg til Passord", + "desc": "Krypter din PDF-dokument med et passord." + }, + "removePassword": { + "title": "Fjern Passord", + "desc": "Fjern passordbeskyttelse fra din PDF-dokument." + }, + "compressPdfs": { + "title": "Komprimer", + "desc": "Komprimer PDF-er for Ć„ redusere filstĆørrelsen." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Endre Metadata", + "desc": "Endre/fjern/legg til metadata fra en PDF-dokument" + }, + "fileToPDF": { + "title": "Konverter fil til PDF", + "desc": "Konverter nesten hvilken som helst fil til PDF (DOCX, PNG, XLS, PPT, TXT og mer)" + }, + "ocr": { + "title": "OCR / Rydd opp skanninger", + "desc": "Rydd opp skanninger og oppdag tekst fra bilder i en PDF og legg den til som tekst." + }, + "extractImages": { + "title": "Ekstraher Bilder", + "desc": "Ekstraherer alle bilder fra en PDF og lagrer dem som zip" + }, + "pdfToPDFA": { + "title": "PDF til PDF/A", + "desc": "Konverter PDF til PDF/A for langtidslagring" + }, + "PDFToWord": { + "title": "PDF til Word", + "desc": "Konverter PDF til Word formater (DOC, DOCX og ODT)" + }, + "PDFToPresentation": { + "title": "PDF til Presentasjon", + "desc": "Konverter PDF til presentasjonsformater (PPT, PPTX og ODP)" + }, + "PDFToText": { + "title": "PDF til RTF (Tekst)", + "desc": "Konverter PDF til tekst eller RTF-format" + }, + "PDFToHTML": { + "title": "PDF til HTML", + "desc": "Konverter PDF til HTML-format" + }, + "PDFToXML": { + "title": "PDF til XML", + "desc": "Konverter PDF til XML-format" + }, + "ScannerImageSplit": { + "title": "Oppdag/Del Skannede bilder", + "desc": "Deler flere bilder fra et bilde/PDF" + }, + "sign": { + "title": "Signer", + "desc": "Legger til signatur i PDF ved tegning, tekst eller bilde" + }, + "flatten": { + "title": "GjĆøre flat", + "desc": "Fjern alle interaktive elementer og skjemaer fra en PDF" + }, + "repair": { + "title": "Reparer", + "desc": "ForsĆøker Ć„ reparere en korrupt/Ćødelagt PDF" + }, + "removeBlanks": { + "title": "Fjern Tomme sider", + "desc": "Oppdager og fjerner tomme sider fra et dokument" + }, + "removeAnnotations": { + "title": "Fjern Anmerkninger", + "desc": "Fjerner alle kommentarer/anmerkninger fra en PDF" + }, + "compare": { + "title": "Sammenlign", + "desc": "Sammenligner og viser forskjellene mellom to PDF-dokumenter" + }, + "certSign": { + "title": "Signer med Sertifikat", + "desc": "Signer en PDF med et sertifikat/nĆøkkel (PEM/P12)" + }, + "removeCertSign": { + "title": "Fjern Sertifikatsignering", + "desc": "Fjern sertifikatsignatur fra PDF" + }, + "pageLayout": { + "title": "Flersidig Layout", + "desc": "SlĆ„ sammen flere sider av en PDF-dokument til en enkelt side" + }, + "scalePages": { + "title": "Juster sidestĆørrelse/skala", + "desc": "Endre stĆørrelsen/skalaen til en side og/eller dens innhold." + }, + "pipeline": { + "title": "Pipeline (Avansert)", + "desc": "UtfĆør flere handlinger pĆ„ PDF-er ved Ć„ definere pipelineskripter" + }, + "add-page-numbers": { + "title": "Legg til Sidetall", + "desc": "Legg til sidetall gjennom et dokument pĆ„ en angitt plassering" + }, + "auto-rename": { + "title": "Auto OmdĆøp PDF Fil", + "desc": "OmdĆøper automatisk en PDF-fil basert pĆ„ dens oppdagede overskrift" + }, + "adjust-contrast": { + "title": "Juster Farger/Kontrast", + "desc": "Juster kontrast, metning og lysstyrke i en PDF" + }, + "crop": { + "title": "BeskjƦre PDF", + "desc": "BeskjƦre en PDF for Ć„ redusere stĆørrelsen (beholder tekst!)" + }, + "autoSplitPDF": { + "title": "Auto Del Sider", + "desc": "Auto Del Skannet PDF med fysisk skannet sidesplitter QR-kode" + }, + "sanitizePdf": { + "title": "Sanitiser", + "desc": "Fjern skript og andre elementer fra PDF-filer" + }, + "URLToPDF": { + "title": "URL/Nettsted Til PDF", + "desc": "Konverter hvilken som helst http(s)URL til PDF" + }, + "HTMLToPDF": { + "title": "HTML til PDF", + "desc": "Konverter hvilken som helst HTML-fil eller zip til PDF" + }, + "MarkdownToPDF": { + "title": "Markdown til PDF", + "desc": "Konverter hvilken som helst Markdown-fil til PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "FĆ„ ALL informasjon om PDF", + "desc": "Fanger opp all tilgjengelig informasjon om PDF-er" + }, + "extractPage": { + "title": "Ekstraher side(r)", + "desc": "Ekstraher valgte sider fra PDF" + }, + "PdfToSinglePage": { + "title": "PDF til Enkelt Stor Side", + "desc": "SlĆ„r sammen alle PDF-sider til en stor enkeltside" + }, + "showJS": { + "title": "Vis Javascript", + "desc": "SĆøker og viser eventuelle JS injisert i en PDF" + }, + "autoRedact": { + "title": "Automatisk Sensurering", + "desc": "Automatisk sensurering (sverter ut) tekst i en PDF basert pĆ„ inntastet tekst" + }, + "redact": { + "title": "Manuell Sensurering", + "desc": "Sensurerer en PDF basert pĆ„ valgt tekst, tegnede former og/eller valgte side(r)" + }, + "tableExtraxt": { + "title": "PDF til CSV", + "desc": "Ekstraherer tabeller fra en PDF og konverterer dem til CSV" + }, + "autoSizeSplitPDF": { + "title": "Auto Del etter StĆørrelse/Antall", + "desc": "Del en enkelt PDF i flere dokumenter basert pĆ„ stĆørrelse, antall sider eller dokumenter" + }, + "overlay-pdfs": { + "title": "Overlay PDF-er", + "desc": "Legger PDF-er over hverandre" + }, + "split-by-sections": { + "title": "Del PDF etter Seksjoner", + "desc": "Del hver side av en PDF i mindre horisontale og vertikale seksjoner" + }, + "AddStampRequest": { + "title": "Legg til Stempel i PDF", + "desc": "Legg til tekst eller bilde stempler pĆ„ angitte steder" + }, + "removeImagePdf": { + "title": "Fjern bilde", + "desc": "Fjern bilde fra PDF for Ć„ redusere filstĆørrelsen" + }, + "splitPdfByChapters": { + "title": "Split PDF by Chapters", + "desc": "Split a PDF into multiple files based on its chapter structure." + }, + "validateSignature": { + "title": "Valider PDF-signatur", + "desc": "Verifiser digitale signaturer og sertifikater i PDF-dokumenter" + }, + "replaceColorPdf": { + "title": "Erstatt og Inverter Farge", + "desc": "Erstatt farge for tekst og bakgrunn i PDF og inverter full farge av pdf for Ć„ redusere filstĆørrelsen" + } + }, + "viewPdf": { + "tags": "vis,les,annoter,tekst,bilde", + "title": "View/Edit PDF", + "header": "Vis PDF" + }, + "multiTool": { + "tags": "Multi VerktĆøy,Multi operasjon,UI,klikk dra,frontend,klientside,interaktiv,bevegelig", + "title": "PDF-multiverktĆøy", + "header": "PDF-multiverktĆøy", + "uploadPrompts": "Filnavn", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "selectPages": "Page Select", + "selectedPages": "Selected Pages", + "page": "Page", + "deleteSelected": "Delete Selected", + "downloadAll": "Export", + "downloadSelected": "Export Selected", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "Page(s) Selected", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "sammenslĆ„ing,sideoperasjoner,backend,serverside", + "title": "SlĆ„ sammen", + "header": "SlĆ„ sammen flere PDF-er (2+)", + "sortByName": "Sorter etter navn", + "sortByDate": "Sorter etter dato", + "removeCertSign": "Fjern digital signatur i den sammenslĆ„tte filen?", + "submit": "SlĆ„ sammen" + }, + "split": { + "tags": "sideoperasjoner,del,flersidig,kutt,serverside", + "title": "Del PDF", + "header": "Del PDF", + "desc": { + "1": "De tallene du velger er sidenummeret du Ćønsker Ć„ dele pĆ„", + "2": "SĆ„ledes vil valg av 1,3,7-9 dele et 10-siders dokument inn i 6 separate PDF-er med:", + "3": "Dokument #1: Side 1", + "4": "Dokument #2: Side 2 og 3", + "5": "Dokument #3: Side 4, 5, 6 og 7", + "6": "Dokument #4: Side 8", + "7": "Dokument #5: Side 9", + "8": "Dokument #6: Side 10" + }, + "splitPages": "Skriv inn sidene som skal deles pĆ„:", + "submit": "Del" + }, + "rotate": { + "tags": "serverside", + "title": "Roter PDF", + "header": "Roter PDF", + "selectAngle": "Velg rotasjonsvinkel (i multipler av 90 grader):", + "submit": "Roter" + }, + "imageToPdf": { + "tags": "konvertering,bilde,jpg,foto" + }, + "pdfToImage": { + "tags": "konvertering,bilde,jpg,foto", + "title": "PDF til bilde", + "header": "PDF til bilde", + "selectText": "Bildeformat", + "singleOrMultiple": "Resultattype for side til bilde", + "single": "Enkelt stort bilde som kombinerer alle sider", + "multi": "Flere bilder, ett bilde per side", + "colorType": "Farge type", + "color": "Farge", + "grey": "GrĆ„tone", + "blackwhite": "Svart-hvitt (kan miste data!)", + "submit": "Konverter", + "info": "Python is not installed. Required for WebP conversion.", + "placeholder": "(f.eks. 1,2,8 eller 4,7,12-16 eller 2n-1)" + }, + "pdfOrganiser": { + "tags": "dupleks,par,single,sorter,flytt", + "title": "Sideorganisering", + "header": "PDF-sideorganisering", + "submit": "Omorganiser sider", + "mode": { + "_value": "Modus", + "1": "Egendefinert sideorden", + "2": "Omvendt rekkefĆølge", + "3": "Dupleks sortering", + "4": "Brosjyresortering", + "5": "SidesĆøm brosjyresortering", + "6": "Oddetall-jevntall splitt", + "7": "Fjern fĆørst", + "8": "Fjern sist", + "9": "Fjern fĆørst og sist", + "10": "Partall-Oddetall SammenslĆ„ing", + "11": "Duplicate all pages" + }, + "placeholder": "(f.eks. 1,3,2 eller 4-8,2,10-12 eller 2n-1)" + }, + "addImage": { + "tags": "bilde,jpg,foto", + "title": "Legg til bilde", + "header": "Legg til bilde i PDF", + "everyPage": "PĆ„ hver side?", + "upload": "Legg til bilde", + "submit": "Legg til bilde" + }, + "watermark": { + "tags": "tekst,gjentakende,etikett,egen,opphavsrett,varemerke,bilde,jpg,foto", + "title": "Legg til vannmerke", + "header": "Legg til vannmerke", + "customColor": "Tilpasset Tekstfarge", + "selectText": { + "1": "Velg PDF-fil Ć„ legge til vannmerke pĆ„:", + "2": "Vannmerketekst:", + "3": "SkriftstĆørrelse:", + "4": "Rotasjon (0-360):", + "5": "Breddeavstand (Avstand mellom hvert vannmerke horisontalt):", + "6": "HĆøydeavstand (Avstand mellom hvert vannmerke vertikalt):", + "7": "Opasitet (0% - 100%):", + "8": "Vannmerketype:", + "9": "Vannmerkebilde:", + "10": "Konverter PDF til PDF-Bilde" + }, + "submit": "Legg til vannmerke", + "type": { + "1": "Tekst", + "2": "Bilde" + } + }, + "permissions": { + "tags": "les,skriv,rediger,skriv ut", + "title": "Endre tillatelser", + "header": "Endre tillatelser", + "warning": "Advarsel: For at disse tillatelsene skal vƦre ugjenkallelige, anbefales det Ć„ angi dem med et passord via siden for Ć„ legge til passord", + "selectText": { + "1": "Velg PDF for Ć„ endre tillatelser", + "2": "Tillatelser Ć„ sette", + "3": "Forhindre sammenstilling av dokumentet", + "4": "Forhindre innholdsekstraksjon", + "5": "Forhindre ekstraksjon for tilgjengelighet", + "6": "Forhindre utfylling av skjema", + "7": "Forhindre modifisering", + "8": "Forhindre annotasjonsmodifisering", + "9": "Forhindre utskrift", + "10": "Forhindre utskrift i ulike formater" + }, + "submit": "Endre" + }, + "removePages": { + "tags": "fjern sider,slett sider" + }, + "addPassword": { + "tags": "sikker,trygghet", + "title": "Legg til passord", + "header": "Legg til passord (Krypter)", + "selectText": { + "1": "Velg PDF-fil for kryptering", + "2": "Brukerpassord", + "3": "KrypteringsnĆøkkellengde", + "4": "HĆøyere verdier er sterkere, men lavere verdier har bedre kompatibilitet.", + "5": "Tillatelser Ć„ sette (Anbefales Ć„ brukes sammen med eierpassord)", + "6": "Forhindre sammenstilling av dokumentet", + "7": "Forhindre innholdsekstraksjon", + "8": "Forhindre ekstraksjon for tilgjengelighet", + "9": "Forhindre utfylling av skjema", + "10": "Forhindre modifisering", + "11": "Forhindre annotasjonsmodifisering", + "12": "Forhindre utskrift", + "13": "Forhindre utskrift i ulike formater", + "14": "Eierpassord", + "15": "Begrenser hva som kan gjĆøres med dokumentet nĆ„r det er Ć„pnet (StĆøttes ikke av alle leserprogrammer)", + "16": "Begrenser Ć„pningen av dokumentet selv" + }, + "submit": "Krypter" + }, + "removePassword": { + "tags": "sikker,dekrypter,trygghet,upassord,slett passord", + "title": "Fjern passord", + "header": "Fjern passord (Dekrypter)", + "selectText": { + "1": "Velg PDF for Ć„ dekryptere", + "2": "Passord" + }, + "submit": "Fjern" + }, + "compressPdfs": { + "tags": "komprimer,liten,tiny" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "title,forfatter,dato,opprettelse,tidsstempel,utgiver,produsent,statistikk", + "title": "Endre metadata", + "header": "Endre metadata", + "selectText": { + "1": "Vennligst rediger variablene du Ćønsker Ć„ endre", + "2": "Slett all metadata", + "3": "Vis tilpasset metadata:", + "4": "Annen metadata:", + "5": "Legg til tilpasset metadataoppfĆøring" + }, + "author": "Forfatter:", + "creationDate": "Opprettelsesdato (ƄƄƄƄ/MM/dd HH:mm:ss):", + "creator": "Oppretter:", + "keywords": "NĆøkkelord:", + "modDate": "Endringsdato (ƄƄƄƄ/MM/dd HH:mm:ss):", + "producer": "Produsent:", + "subject": "Emne:", + "trapped": "Fanget:", + "submit": "Endre" + }, + "fileToPDF": { + "tags": "transformasjon,format,dokument,bilde,slide,tekst,konvertering,office,dokumenter,word,excel,powerpoint", + "title": "Fil til PDF", + "header": "Konverter hvilken som helst fil til PDF", + "credit": "Denne tjenesten bruker LibreOffice og Unoconv for filkonvertering.", + "supportedFileTypesInfo": "StĆøttede filtyper", + "supportedFileTypes": "StĆøttede filtyper bĆør inkludere fĆølgende, men for en fullstendig oppdatert liste over stĆøttede formater, vennligst se LibreOffice-dokumentasjonen", + "submit": "Konverter til PDF" + }, + "ocr": { + "tags": "gjenkjenning,tekst,bilde,skann,les,identifisere,deteksjon,redigerbar", + "title": "OCR / Rens av skanning", + "header": "Rens av skanning / OCR (Optisk tegngjenkjenning)", + "selectText": { + "1": "Velg sprĆ„k som skal oppdages innenfor PDF-en (De oppfĆørte er de som for Ćøyeblikket er oppdaget):", + "2": "Produser tekstfil som inneholder OCR-tekst sammen med OCR-ert PDF", + "3": "Korriger sider som ble skannet med skjev vinkel ved Ć„ rotere dem tilbake pĆ„ plass", + "4": "Rens siden slik at det er mindre sannsynlig at OCR vil finne tekst i bakgrunnsstĆøy. (Ingen utdataendring)", + "5": "Rens siden slik at det er mindre sannsynlig at OCR vil finne tekst i bakgrunnsstĆøy, opprettholder rensing i utdataen.", + "6": "Ignorer sider som har interaktiv tekst pĆ„ dem, OCR kun sider som er bilder", + "7": "Tving OCR, vil OCR hver side og fjerne alle originale tekstelementer", + "8": "Normal (Vil gi feil hvis PDF inneholder tekst)", + "9": "Tilleggsinnstillinger", + "10": "OCR-modus", + "11": "Fjern bilder etter OCR (Fjerner ALLE bilder, kun nyttig hvis det er en del av konverteringsprosessen)", + "12": "Renderingstype (Avansert)" + }, + "help": "Vennligst les denne dokumentasjonen for hvordan du bruker dette for andre sprĆ„k og/eller bruk utenfor Docker.", + "credit": "Denne tjenesten bruker qpdf og Tesseract for OCR.", + "submit": "Behandle PDF med OCR" + }, + "extractImages": { + "tags": "bilde,foto,lagre,arkiv,zip,fangst,hent", + "title": "Hent ut bilder", + "header": "Hent ut bilder", + "selectText": "Velg bildeformat for Ć„ konvertere de hentede bildene til", + "allowDuplicates": "Save duplicate images", + "submit": "Hent ut" + }, + "pdfToPDFA": { + "tags": "arkiv,langtidslagring,standard,konvertering,lagring,bevaring", + "title": "PDF til PDF/A", + "header": "PDF til PDF/A", + "credit": "Denne tjenesten bruker libreoffice for PDF/A-konvertering", + "submit": "Konverter", + "tip": "Fungere for Ćøyeblikket ikke for flere innganger samtidig", + "outputFormat": "Utdataformat", + "pdfWithDigitalSignature": "PDFen inneholder en digital signatur. Denne vil bli fjernet i neste steg." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformasjon,format,konvertering,office,microsoft,dokumentfil", + "title": "PDF til Word", + "header": "PDF til Word", + "selectText": { + "1": "Utdatafilformat" + }, + "credit": "Denne tjenesten bruker LibreOffice for filkonvertering.", + "submit": "Konverter" + }, + "PDFToPresentation": { + "tags": "slides,visning,office,microsoft", + "title": "PDF til Presentasjon", + "header": "PDF til Presentasjon", + "selectText": { + "1": "Utdatafilformat" + }, + "credit": "Denne tjenesten bruker LibreOffice for filkonvertering.", + "submit": "Konverter" + }, + "PDFToText": { + "tags": "rikformat,riktekstformat,rik tekst format", + "title": "PDF til RTF (Tekst)", + "header": "PDF til RTF (Tekst)", + "selectText": { + "1": "Utdatafilformat" + }, + "credit": "Denne tjenesten bruker LibreOffice for filkonvertering.", + "submit": "Konverter" + }, + "PDFToHTML": { + "tags": "web-innhold,nettleservennlig", + "title": "PDF til HTML", + "header": "PDF til HTML", + "credit": "Denne tjenesten bruker pdftohtml for filkonvertering.", + "submit": "Konverter" + }, + "PDFToXML": { + "tags": "datauttrekk,strukturert innhold,interop,transformasjon,konverter", + "title": "PDF til XML", + "header": "PDF til XML", + "credit": "Denne tjenesten bruker LibreOffice for filkonvertering.", + "submit": "Konverter" + }, + "ScannerImageSplit": { + "tags": "separere,auto-oppdag,skanninger,flere bilder,organisere", + "selectText": { + "1": "Vinkelgrense:", + "2": "Angir den minimale absolutte vinkelen som kreves for at bildet skal roteres (standard: 10).", + "3": "Toleranse:", + "4": "Bestemmer omrĆ„det for fargevariasjon rundt estimert bakgrunnsfarge (standard: 30).", + "5": "MinimumsomrĆ„de:", + "6": "Angir minimumsomrĆ„de terskel for et bilde (standard: 10000).", + "7": "MinimumskonturomrĆ„de:", + "8": "Angir minimumskonturomrĆ„de terskel for et bilde", + "9": "KantstĆørrelse:", + "10": "Angir stĆørrelsen pĆ„ kanten som legges til og fjernes for Ć„ forhindre hvite kanter i utdataen (standard: 1)." + }, + "info": "Python er ikke installert. Det er pĆ„krevd for Ć„ kjĆøre." + }, + "sign": { + "tags": "autorisere,initialer,tegnet signatur,tekst signatur,bildesignatur", + "title": "Signer", + "header": "Signer PDF-er", + "upload": "Last opp bilde", + "draw": "Tegn signatur", + "text": "Tekstinput", + "clear": "Slett", + "add": "Legg til", + "saved": "Lagrede signaturer", + "save": "Lagre signatur", + "personalSigs": "Personlige signaturer", + "sharedSigs": "Delte signaturer", + "noSavedSigs": "Ingen lagrede signaturer funnet", + "addToAll": "Legg til pĆ„ alle sider", + "delete": "Slett", + "first": "FĆørste side", + "last": "Siste side", + "next": "Neste side", + "previous": "Forrige side", + "maintainRatio": "Bytt behold sideforhold", + "undo": "Angre", + "redo": "GjĆør om" + }, + "flatten": { + "tags": "statisk,deaktiver,ikke-interaktiv,strĆømlinjeformet", + "title": "Utjevning", + "header": "Utjevning av PDf", + "flattenOnlyForms": "Utjevning av kun skjemaer", + "submit": "Utjevn" + }, + "repair": { + "tags": "fiks,gjenopprett,korreksjon,gjenoppretting", + "title": "Reparer", + "header": "Reparer PDF-er", + "submit": "Reparer" + }, + "removeBlanks": { + "tags": "rydde opp,strĆømlinjeformet,ingen-innhold,organisere", + "title": "Fjern Blank Sider", + "header": "Fjern Blank Sider", + "threshold": "Pixel Hvithetsgrense:", + "thresholdDesc": "Grense for Ć„ bestemme hvor hvit en hvit piksel mĆ„ vƦre for Ć„ klassifiseres som 'Hvit'. 0 = Svart, 255 = Ren hvit.", + "whitePercent": "Hvit Prosent (%):", + "whitePercentDesc": "Prosent av siden som mĆ„ vƦre 'hvite' piksler for Ć„ fjernes", + "submit": "Fjern Blank Sider" + }, + "removeAnnotations": { + "tags": "kommentarer,utheving,notater,markering,fjern", + "title": "Fjern Anmerkninger", + "header": "Fjern Anmerkninger", + "submit": "Fjern" + }, + "compare": { + "tags": "differensiere,kontrast,endringer,analyse", + "title": "Sammenlign", + "header": "Sammenlign PDF-er", + "highlightColor": { + "1": "Uthevingsfarge 1:", + "2": "Uthevingsfarge 2:" + }, + "document": { + "1": "Dokument 1", + "2": "Dokument 2" + }, + "submit": "Sammenlign", + "complex": { + "message": "Ett eller begge av de angitte dokumentene er store filer, nĆøyaktigheten av sammenligningen kan bli redusert" + }, + "large": { + "file": { + "message": "Ett eller begge av de angitte dokumentene er for store til Ć„ behandle" + } + }, + "no": { + "text": { + "message": "En eller begge av de valgte PDF-ene har ingen tekstinnhold. Vennligst velg PDF-er med tekst for sammenligning." + } + } + }, + "certSign": { + "tags": "autentisere,PEM,P12,offisiell,krypter", + "title": "Sertifikatsignering", + "header": "Signer en PDF med sertifikatet ditt (Arbeid pĆ„gĆ„r)", + "selectPDF": "Velg en PDF-fil for signering:", + "jksNote": "Merk: Hvis sertifikattypen din ikke er oppfĆørt nedenfor, vennligst konverter den til en Java-keystore (.jks) fil ved Ć„ bruke kommandolinjeverktĆøyet keytool. Deretter velger du .jks-fil-alternativet nedenfor.", + "selectKey": "Velg din private nĆøkkelfil (PKCS#8-format, kan vƦre .pem eller .der):", + "selectCert": "Velg din sertifikatfil (X.509-format, kan vƦre .pem eller .der):", + "selectP12": "Velg din PKCS#12-keystore-fil (.p12 eller .pfx) (Valgfritt, hvis angitt, bĆør den inneholde din private nĆøkkel og sertifikat):", + "selectJKS": "Velg din Java-keystore-fil (.jks eller .keystore):", + "certType": "Sertifikattype", + "password": "Skriv inn passordet for keystore eller privat nĆøkkel (hvis noen):", + "showSig": "Vis signatur", + "reason": "ƅrsak", + "location": "Sted", + "name": "Navn", + "showLogo": "Show Logo", + "submit": "Signer PDF" + }, + "removeCertSign": { + "tags": "autentisere,PEM,P12,offisiell,dechiffrere", + "title": "Fjern Sertifikatsignatur", + "header": "Fjern det digitale sertifikatet fra PDF-en", + "selectPDF": "Velg en PDF-fil:", + "submit": "Fjern Signatur" + }, + "pageLayout": { + "tags": "slĆ„ sammen,kompositt,enkel-visning,organisere", + "title": "Flersideoppsett", + "header": "Flersideoppsett", + "pagesPerSheet": "Sider per ark:", + "addBorder": "Legg til rammer", + "submit": "Send inn" + }, + "scalePages": { + "tags": "endre stĆørrelse,modifisere,dimensjon,tilpasse", + "title": "Juster side-skala", + "header": "Juster side-skala", + "pageSize": "StĆørrelse pĆ„ et ark i dokumentet.", + "keepPageSize": "Original Size", + "scaleFactor": "Zoom-nivĆ„ (beskjƦr) for en side.", + "submit": "Send inn" + }, + "add-page-numbers": { + "tags": "paginere,etikett,organisere,indeks" + }, + "auto-rename": { + "tags": "auto-oppdag,overskrift-basert,organisere,omdĆøp", + "title": "Auto Navngi", + "header": "Auto Navngi PDF", + "submit": "Auto Navngi" + }, + "adjust-contrast": { + "tags": "fargekorrigering,tilpasse,modifisere,forbedre" + }, + "crop": { + "tags": "trim,redusere,redigere,form", + "title": "BeskjƦr", + "header": "BeskjƦr PDF", + "submit": "Send inn" + }, + "autoSplitPDF": { + "tags": "QR-basert,separere,skann-segment,organisere", + "title": "Automatisk Del PDF", + "header": "Automatisk Del PDF", + "description": "Skriv ut, Sett inn, Skann, last opp, og la oss automatisk separere dokumentene dine. Ingen manuell sortering nĆødvendig.", + "selectText": { + "1": "Skriv ut noen delingssider fra alternativene nedenfor (Svart-hvitt er greit).", + "2": "Skann alle dokumentene samtidig ved Ć„ sette inn delingssiden mellom dem.", + "3": "Last opp den enkelte store skannede PDF-filen og la Stirling PDF hĆ„ndtere resten.", + "4": "Delingssidene blir automatisk oppdaget og fjernet, og garanterer et pent endelig dokument." + }, + "formPrompt": "Send inn PDF som inneholder Stirling-PDF-sideskillere:", + "duplexMode": "Dupleksmodus (Front- og bakskanning)", + "dividerDownload2": "Last ned 'Auto Splitter Divider (med instruksjoner).pdf'", + "submit": "Send inn" + }, + "sanitizePdf": { + "tags": "rydde opp,sikker,trygg,fjern trusler" + }, + "URLToPDF": { + "tags": "web-fangst,lagre side,web-til-dokument,arkiv", + "title": "URL Til PDF", + "header": "URL Til PDF", + "submit": "Konverter", + "credit": "Bruker WeasyPrint" + }, + "HTMLToPDF": { + "tags": "markup,web-innhold,transformasjon,konverter", + "title": "HTML Til PDF", + "header": "HTML Til PDF", + "help": "Godtar HTML-filer og ZIP-filer som inneholder html/css/bilder etc. som er nĆødvendige", + "submit": "Konverter", + "credit": "Bruker WeasyPrint", + "zoom": "ZoomnivĆ„ for visning av nettsiden.", + "pageWidth": "Bredde pĆ„ siden i centimeter. (Blank for standard)", + "pageHeight": "HĆøyde pĆ„ siden i centimeter. (Blank for standard)", + "marginTop": "Ƙvre margin pĆ„ siden i millimeter. (Blank for standard)", + "marginBottom": "Nedre margin pĆ„ siden i millimeter. (Blank for standard)", + "marginLeft": "Venstre margin pĆ„ siden i millimeter. (Blank for standard)", + "marginRight": "HĆøyre margin pĆ„ siden i millimeter. (Blank for standard)", + "printBackground": "Vis bakgrunnen til nettsider.", + "defaultHeader": "Aktiver standardtopp (Navn og sidenummer)", + "cssMediaType": "Endre CSS-mediatypen til siden.", + "none": "Ingen", + "print": "Utskrift", + "screen": "Skjerm" + }, + "MarkdownToPDF": { + "tags": "markup,web-innhold,transformasjon,konverter", + "title": "Markdown Til PDF", + "header": "Markdown Til PDF", + "submit": "Konverter", + "help": "Arbeid pĆ„gĆ„r", + "credit": "Bruker WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "informasjon,data,statistikk", + "title": "FĆ„ Info om PDF", + "header": "FĆ„ Info om PDF", + "submit": "FĆ„ Info", + "downloadJson": "Last ned JSON" + }, + "extractPage": { + "tags": "ekstrahere" + }, + "PdfToSinglePage": { + "tags": "enkelside" + }, + "showJS": { + "tags": "JS", + "title": "Vis Javascript", + "header": "Vis Javascript", + "downloadJS": "Last ned Javascript", + "submit": "Vis" + }, + "autoRedact": { + "tags": "Sensurere,Skjule,sverte ut,svart,markĆør,skjult", + "title": "Automatisk Sensurering", + "header": "Automatisk Sensurering", + "colorLabel": "Farge", + "textsToRedactLabel": "Tekst som skal sensureres (linje-separert)", + "textsToRedactPlaceholder": "f.eks. \\nKonfidensiell \\nTopp-hemmelig", + "useRegexLabel": "Bruk Regex", + "wholeWordSearchLabel": "Hele ordsĆøk", + "customPaddingLabel": "Tilpasset ekstra polstring", + "convertPDFToImageLabel": "Konverter PDF til PDF-bilde (Brukes for Ć„ fjerne tekst bak boksen)", + "submitButton": "Send inn" + }, + "redact": { + "tags": "Sensurere,Skjule,sverte ut,svart,markĆør,skjult,manuell", + "title": "Manuell Sensurering", + "header": "Manuell Sensurering", + "submit": "Sensurer", + "textBasedRedaction": "Tekstbasert sensurering", + "pageBasedRedaction": "Sidebasert sensurering", + "convertPDFToImageLabel": "Konverter PDF til PDF-bilde (Brukes for Ć„ fjerne tekst bak boksen)", + "pageRedactionNumbers": { + "title": "Sider", + "placeholder": "(f.eks. 1,2,8 eller 4,7,12-16 eller 2n-1)" + }, + "redactionColor": { + "title": "Sensureringsfarge" + }, + "export": "Eksporter", + "upload": "Last opp", + "boxRedaction": "Tegn sensureringsboks", + "zoom": "Zoom", + "zoomIn": "Zoom inn", + "zoomOut": "Zoom ut", + "nextPage": "Neste side", + "previousPage": "Forrige side", + "toggleSidebar": "Vis/skjul sidepanel", + "showThumbnails": "Vis miniatyrbilder", + "showDocumentOutline": "Vis dokumentstruktur (dobbeltklikk for Ć„ utvide/skjule alle elementer)", + "showAttatchments": "Vis vedlegg", + "showLayers": "Vis lag (dobbeltklikk for Ć„ tilbakestille alle lag til standardtilstand)", + "colourPicker": "Fargevelger", + "findCurrentOutlineItem": "Finn gjeldende punkt i strukturen", + "applyChanges": "Bruk endringer" + }, + "tableExtraxt": { + "tags": "CSV,tabelluttrekk,ekstrahere,konvertere" + }, + "autoSizeSplitPDF": { + "tags": "pdf,del,dokument,organisering" + }, + "overlay-pdfs": { + "tags": "overlay", + "header": "Overlegg PDF-filer", + "baseFile": { + "label": "Velg grunnleggende PDF-fil" + }, + "overlayFiles": { + "label": "Velg overlegg PDF-filer" + }, + "mode": { + "label": "Velg overleggmodus", + "sequential": "Sekvensiell overlegg", + "interleaved": "Interleaved overlegg", + "fixedRepeat": "Fast gjentakende overlegg" + }, + "counts": { + "label": "Antall overlegg (for fast gjentakende modus)", + "placeholder": "Skriv inn komma-separerte tellinger (f.eks. 2,3,1)" + }, + "position": { + "label": "Velg overleggposisjon", + "foreground": "Forgrunn", + "background": "Bakgrunn" + }, + "submit": "Send inn" + }, + "split-by-sections": { + "tags": "seksjonsdeling,del,tilpass", + "title": "Del PDF etter seksjoner", + "header": "Del PDF inn i seksjoner", + "horizontal": { + "label": "Horisontale delinger", + "placeholder": "Skriv inn antall horisontale delinger" + }, + "vertical": { + "label": "Vertikale delinger", + "placeholder": "Skriv inn antall vertikale delinger" + }, + "submit": "Del PDF", + "merge": "SlĆ„ sammen til Ć©n PDF" + }, + "AddStampRequest": { + "tags": "stempel,legg til bilde,senter bilde,vannmerke,PDF,embed,tilpass", + "header": "Stemple PDF", + "title": "Stemple PDF", + "stampType": "Stempeltype", + "stampText": "Stempele tekst", + "stampImage": "Stemplebilde", + "alphabet": "Alfabet", + "fontSize": "Font/Bilde StĆørrelse", + "rotation": "Rotasjon", + "opacity": "Gjennomsiktighet", + "position": "Posisjon", + "overrideX": "Overskriv X-koordinat", + "overrideY": "Overskriv Y-koordinat", + "customMargin": "Tilpasset Margin", + "customColor": "Tilpasset Tekstfarge", + "submit": "Send inn" + }, + "removeImagePdf": { + "tags": "Fjern Bilde,Sideoperasjoner,Backend,serverside" + }, + "splitPdfByChapters": { + "tags": "split,chapters,bookmarks,organize" + }, + "validateSignature": { + "tags": "signatur,verifiser,valider,pdf,sertifikat,digital signatur,Valider signatur,Valider sertifikat", + "title": "Valider PDF-signaturer", + "header": "Valider Digitale Signaturer", + "selectPDF": "Velg signert PDF-fil", + "submit": "Valider Signaturer", + "results": "Valideringsresultater", + "status": { + "_value": "Status", + "valid": "Gyldig", + "invalid": "Ugyldig" + }, + "signer": "Signatar", + "date": "Dato", + "reason": "ƅrsak", + "location": "Sted", + "noSignatures": "Ingen digitale signaturer funnet i dette dokumentet", + "chain": { + "invalid": "Validering av sertifikatkjede feilet - kan ikke verifisere signatarens identitet" + }, + "trust": { + "invalid": "Sertifikatet er ikke i tillitslager - kilden kan ikke verifiseres" + }, + "cert": { + "expired": "Sertifikatet har utlĆøpt", + "revoked": "Sertifikatet har blitt tilbakekalt", + "info": "Sertifikatdetaljer", + "issuer": "Utsteder", + "subject": "Emne", + "serialNumber": "Serienummer", + "validFrom": "Gyldig Fra", + "validUntil": "Gyldig Til", + "algorithm": "Algoritme", + "keySize": "NĆøkkelstĆørrelse", + "version": "Versjon", + "keyUsage": "NĆøkkelbruk", + "selfSigned": "Selv-signert", + "bits": "bits" + }, + "signature": { + "info": "Signaturinformasjon", + "_value": "Signatur", + "mathValid": "Signaturen er matematisk gyldig MEN:" + }, + "selectCustomCert": "Tilpasset Sertifikatfil X.509 (Valgfritt)" + }, + "replace-color": { + "title": "Erstatt-Inverter-Farge", + "header": "Erstatt-Inverter Farge PDF", + "selectText": { + "1": "Erstatt eller Inverter farge alternativer", + "2": "Standard(Standard hĆøy kontrast farger)", + "3": "Tilpasset(Tilpassede farger)", + "4": "Full-Invertering(Inverter alle farger)", + "5": "HĆøy kontrast fargealternativer", + "6": "hvit tekst pĆ„ svart bakgrunn", + "7": "Svart tekst pĆ„ hvit bakgrunn", + "8": "Gul tekst pĆ„ svart bakgrunn", + "9": "GrĆønn tekst pĆ„ svart bakgrunn", + "10": "Velg tekstfarge", + "11": "Velg bakgrunnsfarge" + }, + "submit": "Erstatt" + }, + "replaceColorPdf": { + "tags": "Erstatt Farge,Sideoperasjoner,Backend,serverside" + }, + "login": { + "title": "Logg inn", + "header": "Logg inn", + "signin": "Logg inn", + "rememberme": "Husk meg", + "invalid": "Ugyldig brukernavn eller passord.", + "locked": "Kontoen din har blitt lĆ„st.", + "signinTitle": "Vennligst logg inn", + "ssoSignIn": "Logg inn via Enkel PĆ„logging", + "oAuth2AutoCreateDisabled": "OAUTH2 Auto-Opretting av bruker deaktivert", + "oAuth2AdminBlockedUser": "Registrering eller pĆ„logging for ikke-registrerte brukere er for Ćøyeblikket blokkert. Vennligst kontakt administrator", + "oauth2RequestNotFound": "AutentiseringsforespĆørsel ikke funnet", + "oauth2InvalidUserInfoResponse": "Ugyldig brukerinforespons", + "oauth2invalidRequest": "Ugyldig forespĆørsel", + "oauth2AccessDenied": "Tilgang nektet", + "oauth2InvalidTokenResponse": "Ugyldig tokenrespons", + "oauth2InvalidIdToken": "Ugyldig Id Token", + "relyingPartyRegistrationNotFound": "Ingen konfigurasjon funnet for Relying Party\"", + "userIsDisabled": "Bruker er deaktivert, innlogging er for Ćøyeblikket blokkert med dette brukernavnet. Vennligst kontakt administrator", + "alreadyLoggedIn": "Du er allerede innlogget pĆ„", + "alreadyLoggedIn2": "enheter. Logg ut og forsĆøk igjen", + "toManySessions": "Du har for mange aktive Ćøkter", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF Til Enkelt Side", + "header": "PDF Til Enkelt Side", + "submit": "Konverter til Enkelt Side" + }, + "pageExtracter": { + "title": "Trekk ut Sider", + "header": "Trekk ut Sider", + "submit": "Trekk ut", + "placeholder": "(f.eks. 1,2,8 eller 4,7,12-16 eller 2n-1)" + }, + "sanitizePDF": { + "title": "Rensker PDF", + "header": "Rensker en PDF fil", + "selectText": { + "1": "Fjern JavaScript-handlinger", + "2": "Fjern innebygde filer", + "3": "Remove XMP metadata", + "4": "Fjern lenker", + "5": "Fjern skrifter", + "6": "Remove Document Info Metadata" + }, + "submit": "Rensk PDF" + }, + "adjustContrast": { + "title": "Juster Kontrast", + "header": "Juster Kontrast", + "contrast": "Kontrast:", + "brightness": "Lysstyrke:", + "saturation": "Metning:", + "download": "Last ned" + }, + "compress": { + "title": "Komprimer", + "header": "Komprimer PDF", + "credit": "Denne tjenesten bruker qpdf for PDF-komprimering/optimisering.", + "grayscale": { + "label": "Bruk grĆ„skala for komprimering" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "OptimeringsnivĆ„:", + "4": "Automatisk modus - Justerer automatisk kvaliteten for Ć„ fĆ„ PDF til nĆøyaktig stĆørrelse", + "5": "Forventet PDF-stĆørrelse (f.eks. 25MB, 10.8MB, 25KB)" + }, + "submit": "Komprimer" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "Sletting av sider", + "header": "PDF-sidefjerner", + "pagesToDelete": "Sider som skal slettes (Skriv inn en kommaseparert liste over sidenumre):", + "submit": "Slett sider", + "placeholder": "(f.eks. 1,2,6 eller 1-10,15-30)" + }, + "imageToPDF": { + "title": "Bilde til PDF", + "header": "Bilde til PDF", + "submit": "Konverter", + "selectLabel": "Bildejusteringsalternativer", + "fillPage": "Fyll side", + "fitDocumentToImage": "Pass side til bilde", + "maintainAspectRatio": "Behold sideforhold", + "selectText": { + "2": "Automatisk rotasjon av PDF", + "3": "Flere fillogikk (Bare aktivert ved arbeid med flere bilder)", + "4": "SlĆ„ sammen til en enkelt PDF", + "5": "Konverter til separate PDF-filer" + } + }, + "PDFToCSV": { + "title": "PDF til CSV", + "header": "PDF til CSV", + "prompt": "Velg side for Ć„ trekke ut tabell", + "submit": "Trekke ut" + }, + "split-by-size-or-count": { + "title": "Del PDF etter stĆørrelse eller antall", + "header": "Del PDF etter stĆørrelse eller antall", + "type": { + "label": "Velg delingstype", + "size": "Etter stĆørrelse", + "pageCount": "Etter sidetall", + "docCount": "Etter antall dokumenter" + }, + "value": { + "label": "Skriv inn verdi", + "placeholder": "Skriv inn stĆørrelse (f.eks. 2 MB eller 3 KB) eller antall (f.eks. 5)" + }, + "submit": "Send inn" + }, + "printFile": { + "title": "Skriv ut fil", + "header": "Skriv ut fil til skriver", + "selectText": { + "1": "Velg fil som skal skrives ut", + "2": "Skriv inn skrivernavn" + }, + "submit": "Skriv ut" + }, + "licenses": { + "nav": "Lisenser", + "title": "Tredjeparts lisenser", + "header": "Tredjeparts lisenser", + "module": "Modul", + "version": "Versjon", + "license": "Lisens" + }, + "survey": { + "nav": "Survey", + "title": "Stirling-PDF Survey", + "description": "Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!", + "changes": "Stirling-PDF has changed since the last survey! To find out more please check our blog post here:", + "changes2": "With these changes we are getting paid business support and funding", + "please": "Please consider taking our survey!", + "disabled": "(Survey popup will be disabled in following updates but available at foot of page)", + "button": "Take Survey", + "dontShowAgain": "Don't show again", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Remove image", + "header": "Remove image", + "removeImage": "Remove image", + "submit": "Remove image" + }, + "splitByChapters": { + "title": "Split PDF by Chapters", + "header": "Split PDF by Chapters", + "bookmarkLevel": "Bookmark Level", + "includeMetadata": "Include Metadata", + "allowDuplicates": "Allow Duplicates", + "desc": { + "1": "This tool splits a PDF file into multiple PDFs based on its chapter structure.", + "2": "Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).", + "3": "Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.", + "4": "Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs." + }, + "submit": "Split PDF" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Versjoner", + "title": "Versjonsnotater", + "header": "Versjonsnotater", + "current": { + "version": "Gjeldende Versjon" + }, + "note": "Versjonsnotater er kun tilgjengelige pĆ„ engelsk" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/pl-PL/translation.json b/frontend/public/locales/pl-PL/translation.json new file mode 100644 index 000000000..86eff3348 --- /dev/null +++ b/frontend/public/locales/pl-PL/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Rozmiar Czcionki", + "fontName": "Nazwa Czcionki", + "title": "Dodaj numerację stron", + "header": "Dodaj numerację stron", + "selectText": { + "1": "Wskaż plik PDF:", + "2": "Rozmiar marginesu", + "3": "Pozycja", + "4": "Numer początkowy", + "5": "Ilość stron do ponumerowania", + "6": "Tekst własny" + }, + "customTextDesc": "Tekst własny", + "numberPagesDesc": "Strony do numeracji, wszystkie (all), 1-5, 2, 5, 9", + "customNumberDesc": "Domyślnie do {n}, również akceptuje 'Strona {n} z {total},Teskt-{n},'{filename}-{n}", + "submit": "Dodaj numerację stron" + }, + "pdfPrompt": "Wybierz PDF", + "multiPdfPrompt": "Wybierz PDF (2+)", + "multiPdfDropPrompt": "Wybierz (lub przeciągnij i puść) wszystkie dokumenty PDF", + "imgPrompt": "Wybierz obraz(y)", + "genericSubmit": "Wyślij", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Ostrzeżenie: Ten proces może potrwać do minuty, w zależności od rozmiaru pliku", + "pageOrderPrompt": "Kolejność stron (wprowadÅŗ listę numerów stron oddzielonych przecinkami) :", + "pageSelectionPrompt": "Niestandardowy wybór strony (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :", + "goToPage": "IdÅŗ", + "true": "Tak", + "false": "Nie", + "unknown": "Nieznany", + "save": "Zapisz", + "saveToBrowser": "Zapisz w przeglądarce", + "close": "Zamknij", + "filesSelected": "wybrane pliki", + "noFavourites": "Nie dodano ulubionych", + "downloadComplete": "Pobieranie zakończone", + "bored": "Znudzony czekaniem?", + "alphabet": "Alfabet", + "downloadPdf": "Pobierz PDF", + "text": "Tekst", + "font": "Czcionka", + "selectFillter": "-- Wybierz --", + "pageNum": "Numer strony", + "sizes": { + "small": "mniejszy", + "medium": "średni", + "large": "duży", + "x-large": "bardzo duży" + }, + "error": { + "pdfPassword": "Dokument PDF jest zabezpieczony hasłem, musisz podać prawidłowe hasło.", + "_value": "błąd", + "sorry": "Przykro nam z powodu problemu!", + "needHelp": "Potrzebujesz pomocy/znalazłem usterkę?", + "contactTip": "Jeśli ciągle masz problem, skontakuj się z nami. Wyślij zgłoszenia na naszej stronie GitHub albo za pomocą Discorda:", + "404": { + "head": "404 - Strona nieodnaleziona | Oho, popsuliśmy kod !", + "1": "Nie ma czegoś takiego!", + "2": "Coś się nie udało!" + }, + "github": "Zgłoś problem na GitHub", + "showStack": "Pokaż Stack Trace", + "copyStack": "Kopiuj Stack Trace", + "githubSubmit": "GitHub - wyślij zgłoszenie", + "discordSubmit": "Discord - wyślij posta z prośbą o pomoc" + }, + "delete": "usuń", + "username": "nazwa użytkownika", + "password": "hasło", + "welcome": "Witaj", + "property": "własność", + "black": "czarny", + "white": "biały", + "red": "czerwony", + "green": "zielony", + "blue": "niebieski", + "custom": "Własny...", + "WorkInProgess": "Praca w toku, proszę zgłaszać błędy!", + "poweredBy": "Zasilany", + "yes": "tak", + "no": "nie", + "changedCredsMessage": "Dane logowanie zostały zmienione.", + "notAuthenticatedMessage": "Użytkownik nie jest zalogowany.", + "userNotFoundMessage": "Brak użytkownika.", + "incorrectPasswordMessage": "Nieprawidłowe hasło.", + "usernameExistsMessage": "Taki uzytkownik już istnieje.", + "invalidUsernameMessage": "Niewłaściwa nazwa użytkownika - musi zawierać litery, cyfry i @._+- LUB być adresem email.", + "invalidPasswordMessage": "Hasło nie może być puste i nie może zawierać spacji na początku ani na końcu.", + "confirmPasswordErrorMessage": "Wpisz poprawnie hasło w OBA pola.", + "deleteCurrentUserMessage": "Nie można usunąć zalogowanego użytkownika", + "deleteUsernameExistsMessage": "Nie można usunąć zalogowanego użytkownika", + "downgradeCurrentUserMessage": "Nie można obniżyć roli bieżącego użytkownika", + "disabledCurrentUserMessage": "Nie można wyłączyć bieżącego użytkownika", + "downgradeCurrentUserLongMessage": "Nie można obniżyć roli bieżącego użytkownika. W związku z tym bieżący użytkownik nie zostanie wyświetlony.", + "userAlreadyExistsOAuthMessage": "Takie konto użytkownika istnieje - stworzone za pomocą OAuth2.", + "userAlreadyExistsWebMessage": "Takie konto użytkownika istnieje - stworzone za pomocą przeglądarki.", + "oops": "Ups!", + "help": "Pomoc", + "goHomepage": "IdÅŗ do strony domowej", + "joinDiscord": "Zapraszamy na DISCORD!", + "seeDockerHub": "Docker Hub", + "visitGithub": "OdwiedÅŗ repozytorium GitHub", + "donate": "Podaruj", + "color": "kolor", + "sponsor": "sponsor", + "info": "informacje", + "pro": "Pro", + "page": "Strona", + "pages": "Strony", + "loading": "Ładowanie...", + "addToDoc": "Dodaj do dokumentu", + "reset": "Resetuj", + "apply": "Zastosuj", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Polityka Prywatności", + "terms": "Zasady i Postanowienia", + "accessibility": "Dostępność", + "cookie": "Polityka plików cookie", + "impressum": "Impresja", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Automatyzacja - menu (Beta)", + "uploadButton": "Wrzuć pliki", + "configureButton": "Konfiguracja", + "defaultOption": "Własny", + "submitButton": "Wyślij", + "help": "Pomoc automatyzacji", + "scanHelp": "Pomoc obserwowania folderu", + "deletePrompt": "Na pewno chcesz skasować automatyzacje", + "tags": "automatyzacja, sekwencja, skrypt, przetwarzanie wsadowe", + "title": "Automatyzacja" + }, + "pipelineOptions": { + "header": "Konfiguracja automatyzacji", + "pipelineNameLabel": "Nazwa automatyzacji", + "saveSettings": "Zapisz ustawienia operacji", + "pipelineNamePrompt": "Podaj nazwę automatyzacji", + "selectOperation": "Wybierz operację", + "addOperationButton": "Dodaj operację", + "pipelineHeader": "Automatyzacja", + "saveButton": "Pobierz", + "validateButton": "Waliduj" + }, + "enterpriseEdition": { + "button": "Uaktualnij do wersji Pro", + "warning": "Ta funkcja jest dostępna tylko dla użytkowników Pro.", + "yamlAdvert": "Stirling PDF Pro obsługuje pliki konfiguracyjne YAML i inne funkcje SSO.", + "ssoAdvert": "Szukasz więcej funkcji zarządzania użytkownikami? SprawdÅŗ Stirling PDF Pro" + }, + "analytics": { + "title": "Czy chcesz ulepszyć Stirling PDF?", + "paragraph1": "Stirling PDF ma opcję analizy, która pomaga nam udoskonalać produkt. Nie śledzimy żadnych danych osobowych ani zawartości plików.", + "paragraph2": "Rozważ włączenie funkcji analitycznych, które pomogą w rozwoju Stirling-PDF i pozwolą nam lepiej zrozumieć naszych użytkowników.", + "enable": "Włącz analitykę", + "disable": "Wyłącz analitykę", + "settings": "Możesz zmienić ustawienia analityki w pliku config/settings.yml" + }, + "navbar": { + "favorite": "Ulubione", + "recent": "Nowe i ostatnio zaktualizowane", + "darkmode": "Tryb nocny", + "language": "Języki", + "settings": "Ustawienia", + "allTools": "Narzędzia", + "multiTool": "Narzędzie Wielofunkcyjne", + "search": "Szukaj", + "sections": { + "organize": "Organizuj", + "convertTo": "Przetwórz na PDF", + "convertFrom": "Przetwórz z PDF", + "security": "Podpis i bezpieczeństwo", + "advance": "Zaawansowane", + "edit": "Podgląd i edycja", + "popular": "Popularne" + } + }, + "settings": { + "title": "Ustawienia", + "update": "Dostępna aktualizacja", + "updateAvailable": "Wersja {0} jest obecenia zainstalowana, dostępna jest nowa wersja ({1}).", + "appVersion": "Wersja aplikacji:", + "downloadOption": { + "title": "Wybierz opcję pobierania (w przypadku pobierania pojedynczych plików innych niż ZIP):", + "1": "Otwórz w tym samym oknie", + "2": "Otwórz w nowym oknie", + "3": "Pobierz plik" + }, + "zipThreshold": "Spakuj pliki, gdy liczba pobranych plików przekroczy", + "signOut": "Wyloguj", + "accountSettings": "Ustawienia konta", + "bored": { + "help": "Włącz easter-egg" + }, + "cacheInputs": { + "name": "Zapisz dane formularzy", + "help": "Włącz aby zapisać dane dla przyszłych automatyzacji" + } + }, + "changeCreds": { + "title": "Zmień dane logowania", + "header": "Zmień dane konta", + "changePassword": "Musisz zmienić domyślne dane logowania", + "newUsername": "Nowa nazwa użytkownika", + "oldPassword": "Obecne hasło", + "newPassword": "Nowe hasło", + "confirmNewPassword": "PotwierdÅŗ obecne hasło", + "submit": "Zapisz zmiany" + }, + "account": { + "title": "Ustawienia konta", + "accountSettings": "Ustawienia konta", + "adminSettings": "Admin - kontrola kont", + "userControlSettings": "Kontrola praw użytkownika", + "changeUsername": "Zmień nazwę użytkownika", + "newUsername": "Nowa nazwa użytkownika", + "password": "PotwierdÅŗ hasło", + "oldPassword": "Poprzednie hasło", + "newPassword": "Nowe hasło", + "changePassword": "Zmień hasło", + "confirmNewPassword": "PotwierdÅŗ nowe hasło", + "signOut": "Wyloguj", + "yourApiKey": "Twój klucz API", + "syncTitle": "Zapisz ustawienia konta w przeglądarce", + "settingsCompare": "Porównania uprawnień", + "property": "Własność", + "webBrowserSettings": "Ustawienia przeglądarki", + "syncToBrowser": "Zapisz dane konta w przeglądarce", + "syncToAccount": "Wczytaj dane konta z przeglądarki" + }, + "adminUserSettings": { + "title": "Ustawienia konta użytkownika", + "header": "Ustawienia praw administratora", + "admin": "Administrator", + "user": "Użytkownik", + "addUser": "Dodaj nowego użytkownika", + "deleteUser": "Usuń użytkownika", + "confirmDeleteUser": "Czy na pewno usunąć użytkownika?", + "confirmChangeUserStatus": "Czy użytkownik powinien zostać wyłączony/włączony?", + "usernameInfo": "Niewłaściwa nazwa użytkownika - musi zawierać litery, cyfry i @._+- LUB być adresem email.", + "roles": "Role", + "role": "Rola", + "actions": "Akcje", + "apiUser": "Ograniczony Użytkownik API", + "extraApiUser": "Dodatkowy ograniczony Użytkownik API", + "webOnlyUser": "Użytkownik tylko WEB", + "demoUser": "Użytkownik DEMO", + "internalApiUser": "Wewnętrzny użytkownik API", + "forceChange": "Wymuś zmianę hasło po zalogowaniu", + "submit": "Zapisz użytkownika", + "changeUserRole": "Zmień rolę użytkownika", + "authenticated": "Zalogowany", + "editOwnProfil": "Edytuj własny profil", + "enabledUser": "włączony użytkownik", + "disabledUser": "wyłączony użytkownik", + "activeUsers": "Aktywni Użytkownicy:", + "disabledUsers": "Wyłączeni Użytkownicy:", + "totalUsers": "Łączna Liczba Użytkowników:", + "lastRequest": "Ostatnie Zgłoszenie", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Statystyki Punktów Końcowych", + "header": "Statystyki Punktów Końcowych", + "top10": "Top 10", + "top20": "Top 20", + "all": "Wszystkie", + "refresh": "Odśwież", + "includeHomepage": "Uwzględnij stronę główną ('/')", + "includeLoginPage": "Uwzględnij stronę logowania ('/login')", + "totalEndpoints": "Łączna liczba punktów końcowych", + "totalVisits": "Łączna liczba wizyt", + "showing": "Pokazuje", + "selectedVisits": "Wybrane wizyty", + "endpoint": "Punkt końcowy", + "visits": "Wizyty", + "percentage": "Procent", + "loading": "Ładowanie...", + "failedToLoad": "Nie udało się załadować danych punktów końcowych. Spróbuj odświeżyć.", + "home": "Strona główna", + "login": "Logowanie", + "top": "Top", + "numberOfVisits": "Liczba wizyt", + "visitsTooltip": "Wizyty: {0} ({1}% całości)", + "retry": "Spróbuj ponownie" + }, + "database": { + "title": "Import/Eksport bazy danych", + "header": "Import/Eksport bazy danych", + "fileName": "Nazwa pliku", + "creationDate": "Data utworzenia", + "fileSize": "Rozmiar pliku", + "deleteBackupFile": "Usuń plik kopii zapasowej", + "importBackupFile": "Importuj plik kopii zapasowej", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Pobierz plik kopii zapasowej", + "info_1": "Podczas importowania danych, ważne jest, aby upewnić się, że struktura jest poprawna. Jeśli nie jesteś pewien, co robisz, skontaktuj się z profesjonalistą. Błąd w strukturze może spowodować awarie aplikacji, aż do całkowitej niemożności jej uruchomienia.", + "info_2": "Nazwa pliku nie ma znaczenia podczas przesyłania. Zostanie on później przemianowany, aby przestrzegać formatu backup_user_yyyyMMddHHmm.sql, zapewniając spójną konwencję nazewnictwa.", + "submit": "Importuj kopię zapasową", + "importIntoDatabaseSuccessed": "Import do bazy danych zakończony sukcesem", + "backupCreated": "Kopia zapasowa bazy danych została utworzona pomyślnie", + "fileNotFound": "Plik nie znaleziony", + "fileNullOrEmpty": "Plik nie może być pusty", + "failedImportFile": "Nie udało się zaimportować pliku", + "notSupported": "Ta funkcja nie jest dostępna dla Twojego połączenia z bazą danych" + }, + "session": { + "expired": "Twoja sesja wygasła. Odśwież stronę i spróbuj ponownie.", + "refreshPage": "Odśwież stronę" + }, + "home": { + "desc": "Twoja lokalna aplikacja do kompleksowej obsługi Twoich potrzeb związanych z dokumentami PDF.", + "searchBar": "Szukaj opcji ...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Wyświetl, adnotuj, dodaj tekst lub obrazy" + }, + "setFavorites": "Ustaw ulubione", + "hideFavorites": "Ukryj ulubione", + "showFavorites": "Pokaż ulubione", + "legacyHomepage": "Stara strona główna", + "newHomePage": "Wypróbuj naszą nową stronę główną!", + "alphabetical": "Alfabetycznie", + "globalPopularity": "Globalna popularność", + "sortBy": "Sortuj według:", + "multiTool": { + "title": "Wielofunkcyjne Narzędzie PDF", + "desc": "Łącz, dziel, obracaj, zmieniaj kolejność i usuwaj strony" + }, + "merge": { + "title": "Połącz", + "desc": "Łatwe łączenie wielu dokumentów PDF w jeden." + }, + "split": { + "title": "Podziel", + "desc": "Podziel dokument PDF na wiele dokumentów" + }, + "rotate": { + "title": "Obróć", + "desc": "Łatwo obracaj dokumenty PDF." + }, + "imageToPdf": { + "title": "Obraz na PDF", + "desc": "Konwertuj obraz (PNG, JPEG, GIF) do dokumentu PDF." + }, + "pdfToImage": { + "title": "PDF na Obraz", + "desc": "Konwertuj plik PDF na obraz (PNG, JPEG, GIF)." + }, + "pdfOrganiser": { + "title": "Uporządkuj", + "desc": "Usuń/Zmień kolejność stron w dowolnej kolejności" + }, + "addImage": { + "title": "Dodaj obraz", + "desc": "Dodaje obraz w wybranym miejscu w dokumencie PDF" + }, + "watermark": { + "title": "Dodaj znak wodny", + "desc": "Dodaj niestandardowy znak wodny do dokumentu PDF." + }, + "permissions": { + "title": "Zmień uprawnienia", + "desc": "Zmień uprawnienia dokumentu PDF" + }, + "removePages": { + "title": "Usuń", + "desc": "Usuń niechciane strony z dokumentu PDF." + }, + "addPassword": { + "title": "Dodaj hasło", + "desc": "Zaszyfruj dokument PDF za pomocą hasła." + }, + "removePassword": { + "title": "Usuń hasło", + "desc": "Usuń ochronę hasłem z dokumentu PDF." + }, + "compressPdfs": { + "title": "Kompresuj", + "desc": "Kompresuj dokumenty PDF, aby zmniejszyć ich rozmiar." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Zmień metadane", + "desc": "Zmień/Usuń/Dodaj metadane w dokumencie PDF" + }, + "fileToPDF": { + "title": "Konwertuj plik do PDF", + "desc": "Konwertuj dowolny plik do dokumentu PDF (DOCX, PNG, XLS, PPT, TXT i więcej)" + }, + "ocr": { + "title": "OCR / Zamiana na tekst", + "desc": "OCR skanuje i wykrywa tekst z obrazów w dokumencie PDF i zamienia go na tekst." + }, + "extractImages": { + "title": "Wyodrębnij obrazy", + "desc": "Wyodrębnia wszystkie obrazy z dokumentu PDF i zapisuje je w wybranym formacie" + }, + "pdfToPDFA": { + "title": "PDF na PDF/A", + "desc": "Konwertuj dokument PDF na PDF/A w celu długoterminowego przechowywania" + }, + "PDFToWord": { + "title": "PDF na Word", + "desc": "Konwertuj dokument PDF na formaty Word (DOC, DOCX i ODT)" + }, + "PDFToPresentation": { + "title": "PDF na Prezentację", + "desc": "Konwertuj dokument PDF na formaty prezentacji (PPT, PPTX i ODP)" + }, + "PDFToText": { + "title": "PDF na Tekst/RTF", + "desc": "Konwertuj dokument PDF na tekst lub format RTF" + }, + "PDFToHTML": { + "title": "PDF na HTML", + "desc": "Konwertuj dokument PDF na format HTML" + }, + "PDFToXML": { + "title": "PDF na XML", + "desc": "Konwertuj dokument PDF na format XML" + }, + "ScannerImageSplit": { + "title": "Wykryj/Podziel zeskanowane zdjęcia", + "desc": "Podziel na wiele zdjęć z jednego zdjęcia/PDF" + }, + "sign": { + "title": "Podpis", + "desc": "Dodaje podpis do dokumentu PDF za pomocą rysunku, tekstu lub obrazu" + }, + "flatten": { + "title": "Spłaszcz", + "desc": "Usuń wszystkie interaktywne elementy i formularze z dokumentu PDF" + }, + "repair": { + "title": "Napraw", + "desc": "Spróbuj naprawić uszkodzony dokument PDF" + }, + "removeBlanks": { + "title": "Usuń puste strony", + "desc": "Wykrywa i usuwa puste strony z dokumentu PDF" + }, + "removeAnnotations": { + "title": "Usuń notatki/przypisy", + "desc": "Usuwa wszystkie notatki i przypisy z dokumentu PDF" + }, + "compare": { + "title": "Porównaj", + "desc": "Porównuje i pokazuje różnice między dwoma dokumentami PDF" + }, + "certSign": { + "title": "Podpisz certyfikatem", + "desc": "Podpisz dokument PDF za pomocą certyfikatu/klucza prywatnego (PEM/P12)" + }, + "removeCertSign": { + "title": "Usuń podpis certyfikatem", + "desc": "Usuń podpis certyfikatem z dokumentu PDF" + }, + "pageLayout": { + "title": "Układ wielu stron", + "desc": "Scal wiele stron dokumentu PDF w jedną stronę" + }, + "scalePages": { + "title": "Dopasuj rozmiar stron", + "desc": "Dopasuj rozmiar stron wybranego dokumentu PDF" + }, + "pipeline": { + "title": "Automatyzacja", + "desc": "Wykonaj wiele akcji na dokumentach PDF, tworząc automatyzację" + }, + "add-page-numbers": { + "title": "Dodaj numery stron", + "desc": "Dodaj numery strony w dokumencie PDF w podanej lokalizacji" + }, + "auto-rename": { + "title": "Automatycznie zmień nazwę PDF", + "desc": "Automatycznie zmień nazwę PDF bazując na nagłówku" + }, + "adjust-contrast": { + "title": "Zmień kolor/nasycenie/jasność", + "desc": "Zmień kolor/nasycenie/jasność w dokumencie PDF" + }, + "crop": { + "title": "Przytnij PDF", + "desc": "Przytnij dokument PDF w celu zmniejszenia rozmiaru" + }, + "autoSplitPDF": { + "title": "Automatycznie podziel strony", + "desc": "Automatycznie podziel dokument na strony" + }, + "sanitizePdf": { + "title": "Dezynfekcja", + "desc": "Usuń skrypt i inne elementy z dokumentu PDF" + }, + "URLToPDF": { + "title": "Strona WWW do PDFa", + "desc": "Zapisuje podany adres WWW do PDFa" + }, + "HTMLToPDF": { + "title": "HTML do PDF", + "desc": "Zapisuje podany plik HTML/ZIP do PDF" + }, + "MarkdownToPDF": { + "title": "Markdown do PDF", + "desc": "Zapisuje dokument Markdown do PDF" + }, + "PDFToMarkdown": { + "title": "PDF do Markdown", + "desc": "Konwertuje dowolny plik PDF na Markdown" + }, + "getPdfInfo": { + "title": "Pobierz informacje o pliku PDF", + "desc": "Pobiera wszelkie informacje o pliku PDF" + }, + "extractPage": { + "title": "Wyciągnij stronę z PDF", + "desc": "Wyciąga stronę z dokumentu PDF" + }, + "PdfToSinglePage": { + "title": "PDF do jednej strony", + "desc": "Łączy wszystkie strony PDFa w jedną wielką stronę PDF" + }, + "showJS": { + "title": "Pokaż kod JavaScript", + "desc": "Znajduje i pokazuje załączony kod JS w dokumencie PDF" + }, + "autoRedact": { + "title": "Zaciemnij", + "desc": "Zaciemnia dokument PDF bazując na podanej wartości" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF do CSV", + "desc": "Konwertuje tabele z PDF do pliku CSV" + }, + "autoSizeSplitPDF": { + "title": "Podziel (Rozmiar/Ilość stron)", + "desc": "Rozdziela dokument PDF na wiele dokumentów bazując na podanym rozmiarze, ilości stron bądÅŗ ilości dokumentów" + }, + "overlay-pdfs": { + "title": "Nałóż PDFa", + "desc": "Nakłada dokumenty PDF na siebie" + }, + "split-by-sections": { + "title": "Podziel PDF na sekcje", + "desc": "Podziel strony PDF w mniejsze sekcje" + }, + "AddStampRequest": { + "title": "Dodaj pieczęć", + "desc": "Dodaj pieczęć tekstową/obrazową w wyznaczonej lokalizacji dokumentu" + }, + "removeImagePdf": { + "title": "Usuń obraz", + "desc": "Usuń obraz z pliku PDF, aby zmniejszyć rozmiar pliku" + }, + "splitPdfByChapters": { + "title": "Podziel PDF według rozdziałów", + "desc": "Podział pliku PDF na wiele plików na podstawie struktury rozdziałów." + }, + "validateSignature": { + "title": "SprawdÅŗ poprawność podpisu PDF", + "desc": "Weryfikuj podpisy cyfrowe i certyfikaty w dokumentach PDF" + }, + "replaceColorPdf": { + "title": "Zastąp i Odwróć Kolor", + "desc": "Zastąp kolor tekstu i tła w pliku PDF i odwróć pełen kolor pliku PDF, aby zmniejszyć rozmiar pliku" + } + }, + "viewPdf": { + "tags": "wyświetl,czytaj,adnotuj,tekst,obraz", + "title": "Przeglądaj/Edytuj PDF", + "header": "Podejrzyj PDF" + }, + "multiTool": { + "tags": "Wielofunkcyjne narzędzie, obsługa wielu operacji, interfejs użytkownika, przeciąganie kliknięć, front-end, strona klienta", + "title": "Narzędzie Wielofunkcyjne PDF", + "header": "Narzędzie Wielofunkcyjne PDF", + "uploadPrompts": "Nazwa pliku", + "selectAll": "Zaznacz wszystko", + "deselectAll": "Odznacz wszystko", + "selectPages": "Wybór stron", + "selectedPages": "Wybrane strony", + "page": "Strona", + "deleteSelected": "Usuń zaznaczone", + "downloadAll": "Eksportuj", + "downloadSelected": "Eksportuj zaznaczone", + "insertPageBreak": "Wstaw podział strony", + "addFile": "Dodaj plik", + "rotateLeft": "Obróć w lewo", + "rotateRight": "Obróć w prawo", + "split": "Podziel", + "moveLeft": "Przesuń w lewo", + "moveRight": "Przesuń w prawo", + "delete": "Usuń", + "dragDropMessage": "Wybrana(e) strona(y)", + "undo": "Cofnij", + "redo": "Ponów" + }, + "merge": { + "tags": "scalanie, operacje na stronach, back-end, po stronie serwera", + "title": "Połącz", + "header": "Połącz wiele dokumentów PDF (2+)", + "sortByName": "Sortuj po nazwie", + "sortByDate": "Sortuj po dacie", + "removeCertSign": "Usuń podpis cyfrowy w scalonym pliku?", + "submit": "Połącz" + }, + "split": { + "tags": "Operacje na stronach, dzielenie, wiele stron, cięcie, po stronie serwera", + "title": "Podziel dokument PDF", + "header": "Podziel dokument PDF", + "desc": { + "1": "Wybrane numery to numery stron, na których chcesz dokonać podziału", + "2": "Np. taki wybór 1,3,7-9 podzieliłby 10-stronicowy dokument na 6 oddzielnych plików PDF z:", + "3": "Dokument #1: Strona 1", + "4": "Dokument #2: Strona 2 i 3", + "5": "Dokument #3: Strona 4, 5, 6 i 7", + "6": "Dokument #4: Strona 8", + "7": "Dokument #5: Strona 9", + "8": "Dokument #6: Strona 10" + }, + "splitPages": "WprowadÅŗ strony do podziału na:", + "submit": "Podziel" + }, + "rotate": { + "tags": "strona serwera", + "title": "Obróć dokument PDF", + "header": "Obróć dokument PDF", + "selectAngle": "Wybierz kąt obrotu (domyślnie 90 stopni):", + "submit": "Obróć" + }, + "imageToPdf": { + "tags": "konwersja,img,jpg,obraz,zdjęcie" + }, + "pdfToImage": { + "tags": "konwersja,img,jpg,obraz,zdjęcie", + "title": "PDF na Obraz", + "header": "PDF na Obraz", + "selectText": "Format obrazu", + "singleOrMultiple": "Typ pliku obrazu", + "single": "Pojedynczy duży obraz", + "multi": "Wiele obrazów", + "colorType": "Rodzaj koloru", + "color": "Kolor", + "grey": "Odcień szarości", + "blackwhite": "Czarno-biały (może spowodować utratę danych!)", + "submit": "Konwertuj", + "info": "Python nie został zainstalowany. Jest wymagany do konwersji WebP.", + "placeholder": "(przykład 1,2,8 lub 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,parzyste,nieparzyste,sortuj,przenieś", + "title": "Kolejność stron", + "header": "Kolejność stron PDF", + "submit": "Zmień kolejność stron", + "mode": { + "_value": "Tryb", + "1": "Własna kolejność stron", + "2": "Odwrotny", + "3": "Dwustronny", + "4": "Książki", + "5": "Spiętej książki", + "6": "Rozdziel parzyste-nieparzyste", + "7": "Usuń pierwszą", + "8": "Usuń ostatnią", + "9": "Usuń pierwszą i ostatnią", + "10": "Połącz parzyste i nieparzyste", + "11": "Zduplikuj wszystkie strony" + }, + "placeholder": "(przykład 1,3,2 lub 4-8,2,10-12 lub 2n-1)" + }, + "addImage": { + "tags": "img,jpg,obraz,zdjęcie", + "title": "Dodaj obraz", + "header": "Dodaj obraz do PDF", + "everyPage": "Każda strona?", + "upload": "Dodaj obraz", + "submit": "Dodaj obraz" + }, + "watermark": { + "tags": "Tekst,powtarzanie,etykieta,własne,prawa autorskie,znak wodny,img,jpg,obraz,zdjęcie", + "title": "Dodaj znak wodny", + "header": "Dodaj znak wodny", + "customColor": "Własny kolor tekstu", + "selectText": { + "1": "Wybierz dokument PDF, do którego chcesz dodać znak wodny:", + "2": "Treść znaku wodnego:", + "3": "Rozmiar czcionki:", + "4": "Obrót (0-360):", + "5": "Odstęp w poziomie (odstęp między każdym znakiem wodnym w poziomie):", + "6": "Odstęp w pionie (odstęp między każdym znakiem wodnym w pionie):", + "7": "Nieprzezroczystość (0% - 100%):", + "8": "Typ znaku wodnego:", + "9": "Obraz znaku wodnego:", + "10": "Konwertuj PDF do PDF-Image" + }, + "submit": "Dodaj znak wodny", + "type": { + "1": "Tekst", + "2": "Obraz" + } + }, + "permissions": { + "tags": "odczyt,zapis,edycja,drukowanie", + "title": "Zmień uprawnienia", + "header": "Zmień uprawnienia", + "warning": "Ostrzeżenie, aby te uprawnienia były zablokowane, zaleca się ustawienie hasła na stronie dodawania hasła", + "selectText": { + "1": "Wybierz dokument PDF, aby zmienić uprawnienia", + "2": "Uprawnienia do zmian", + "3": "Zablokuj zmiany w dokumencie", + "4": "Zablokuj zmiany w treści", + "5": "Zablokuj zmiany w celu ułatwienia dostępu", + "6": "Zablokuj wypełnianie formularzy", + "7": "Zablokuj modyfikacje", + "8": "Zablokuj modyfikacje adnotacji", + "9": "Zablokuj drukowanie", + "10": "Zablokuj drukowanie różnych formatów" + }, + "submit": "Zmień" + }, + "removePages": { + "tags": "Usuń strony,usuwaj strony" + }, + "addPassword": { + "tags": "bezpieczeństwo,ochrona", + "title": "Dodaj hasło", + "header": "Dodaj hasło (zaszyfruj)", + "selectText": { + "1": "Wybierz plik PDF do zaszyfrowania", + "2": "Hasło", + "3": "Długość klucza szyfrowania", + "4": "Wyższe wartości są silniejsze, ale niższe wartości zapewniają lepszą kompatybilność.", + "5": "Uprawnienia do zmian", + "6": "Zablokuj zmiany w dokumencie", + "7": "Zablokuj zmiany w treści", + "8": "Zablokuj zmiany w celu ułatwienia dostępu", + "9": "Zablokuj wypełnianie formularzy", + "10": "Zablokuj modyfikacje", + "11": "Zablokuj modyfikacje adnotacji", + "12": "Zablokuj drukowanie", + "13": "Zablokuj drukowanie różnych formatów", + "14": "Hasło właściciela", + "15": "Ogranicza akcje, które można wykonać na dokumencie, kiedy jest otwarty (nie wspierany przez wszystkie przeglądarki)", + "16": "Ogranicza otwarcie dokumentu" + }, + "submit": "Zablokuj" + }, + "removePassword": { + "tags": "zabezpieczenie,odszyfrowanie,bezpieczeństwo,odhasłowanie,usunięcie hasła", + "title": "Usuń hasło", + "header": "Usuń hasło (odszyfruj)", + "selectText": { + "1": "Wybierz dokument PDF do odszyfrowania", + "2": "Hasło" + }, + "submit": "Usuń" + }, + "compressPdfs": { + "tags": "zgniatać,mały,malutki" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Tytuł,autor,data,utworzenie,czas,wydawca,producent,statystyki", + "title": "Tytuł:", + "header": "Zmień metadane", + "selectText": { + "1": "Edytuj zmienne, które chcesz zmienić", + "2": "Usuń wszystkie metadane", + "3": "Pokaż niestandardowe metadane:", + "4": "Inne metadane:", + "5": "Dodaj niestandardowy wpis w metadanych" + }, + "author": "Autor:", + "creationDate": "Data utworzenia (yyyy/MM/dd HH:mm:ss):", + "creator": "Twórca:", + "keywords": "Słowa kluczowe:", + "modDate": "Data modyfikacji (yyyy/MM/dd HH:mm:ss):", + "producer": "Producent:", + "subject": "Temat:", + "trapped": "Zablokowany:", + "submit": "Zmień" + }, + "fileToPDF": { + "tags": "transformacja,format,dokument,obraz,slajd,tekst,konwersja,office,dokumenty,word,excel,powerpoint", + "title": "Plik na PDF", + "header": "Konwertuj dowolny plik na dokument PDF", + "credit": "Ta usługa używa LibreOffice i Unoconv do konwersji plików.", + "supportedFileTypesInfo": "Obsługiwane typy plików", + "supportedFileTypes": "Obsługiwane typy plików powinny być zgodne z poniższymi, jednak pełną zaktualizowaną listę obsługiwanych formatów można znaleźć w dokumentacji LibreOffice", + "submit": "Konwertuj na PDF" + }, + "ocr": { + "tags": "rozpoznawanie, tekst, obraz, skanowanie, odczyt, identyfikacja, wykrywanie, edytowalność", + "title": "OCR / Zamiana na tekst", + "header": "OCR / Zamiana na tekst (optyczne rozpoznawanie znaków)", + "selectText": { + "1": "Wybierz języki, które mają zostać wykryte w dokumencie PDF (te z listy to języki, które są obecnie wykrywane):", + "2": "Utwórz plik tekstowy zawierający tekst OCR oraz dokument PDF z OCR", + "3": "Prawidłowe strony zostały zeskanowane pod przekrzywionym kątem przez obrócenie ich z powrotem na miejsce", + "4": "Wyczyść stronę, więc jest mniej prawdopodobne że OCR znajdzie tekst w obrazie tła. (Brak zmiany wyjścia)", + "5": "Wyczyść stronę, więc jest mniej prawdopodobne że OCR znajdzie tekst w obrazie tła, utrzymuje porządek na wyjściu.", + "6": "Ignoruje strony zawierające interaktywny tekst, tylko strony OCR, które są obrazami", + "7": "Wymuś OCR, każda strona usunie wszystkie oryginalne elementy tekstowe", + "8": "Normalny (wystąpi błąd, jeśli plik PDF zawiera tekst)", + "9": "Dodatkowe ustawienia", + "10": "Tryb OCR", + "11": "Usuń obrazy po OCR (usuwa wszystkie obrazy, przydatne tylko, jeśli jest częścią etapu konwersji)", + "12": "Typ renderowania (zaawansowany)" + }, + "help": "Przeczytaj tę dokumentację, aby dowiedzieć się, jak używać tego w innych językach i/lub nie używać docker", + "credit": "Ta usługa używa qpdf i Tesseract do OCR.", + "submit": "Przetwarzaj PDF za pomocą OCR" + }, + "extractImages": { + "tags": "obraz, zdjęcie, zapisz, archiwum, zip, przechwyć, złap", + "title": "Wyodrębnij obrazy", + "header": "Wyodrębnij obrazy", + "selectText": "Wybierz format obrazu, na który chcesz przekonwertować wyodrębniony obraz.", + "allowDuplicates": "Zapisz zduplikowane obrazy", + "submit": "Wyodrębnij" + }, + "pdfToPDFA": { + "tags": "archiwum, długoterminowe, standardowe, konwersja, przechowywanie, konserwacja", + "title": "PDF na PDF/A", + "header": "PDF na PDF/A", + "credit": "Ta usługa używa libreoffice do konwersji PDF/A", + "submit": "Konwertuj", + "tip": "Tylko jeden plik na raz", + "outputFormat": "Format wyjściowy:", + "pdfWithDigitalSignature": "Dokument zawiera podpis cyfrowy, nie zostanie on wczytany." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word, przekształcenie, transformacja, konwersja, office, microsoft, plik doc", + "title": "PDF na Word", + "header": "PDF na Word", + "selectText": { + "1": "Format pliku wyjściowego" + }, + "credit": "Ta usługa używa LibreOffice do konwersji plików.", + "submit": "Konwertuj" + }, + "PDFToPresentation": { + "tags": "slajdy, pokaz, office, microsoft", + "title": "PDF na Prezentację", + "header": "PDF na Prezentację", + "selectText": { + "1": "Format pliku wyjściowego" + }, + "credit": "Ta usługa używa LibreOffice do konwersji plików.", + "submit": "Konwertuj" + }, + "PDFToText": { + "tags": "format tekstu sformatowanego,rtf format", + "title": "PDF na Tekst/RTF", + "header": "PDF na Tekst/RTF", + "selectText": { + "1": "Format pliku wyjściowego" + }, + "credit": "Ta usługa używa LibreOffice do konwersji plików.", + "submit": "Konwertuj" + }, + "PDFToHTML": { + "tags": "zawartość internetowa, przyjazne dla przeglądarek", + "title": "PDF na HTML", + "header": "PDF na HTML", + "credit": "Ta usługa używa pdftohtml do konwersji plików.", + "submit": "Konwertuj" + }, + "PDFToXML": { + "tags": "ekstrakcja danych, zawartość strukturalna, współdziałanie, transformacja, konwertowanie", + "title": "PDF na XML", + "header": "PDF na XML", + "credit": "Ta usługa używa LibreOffice do konwersji plików.", + "submit": "Konwertuj" + }, + "ScannerImageSplit": { + "tags": "oddzielne, automatyczne wykrywanie, skanowanie, wiele zdjęć, porządkowanie", + "selectText": { + "1": "Próg kąta:", + "2": "Ustawia minimalny kąt bezwzględny wymagany do obrócenia obrazu (domyślnie: 10).", + "3": "Tolerancja:", + "4": "Określa zakres zmienności kolorów wokół szacowanego koloru tła (domyślnie: 30).", + "5": "Minimalna powierzchnia:", + "6": "Ustawia próg minimalnego obszaru dla zdjęcia (domyślnie: 10000).", + "7": "Minimalny obszar konturu:", + "8": "Ustawia próg minimalnego obszaru konturu dla zdjęcia", + "9": "Rozmiar obramowania:", + "10": "Ustawia rozmiar dodawanego i usuwanego obramowania, aby uniknąć białych obramowań na wyjściu (domyślnie: 1)." + }, + "info": "Python nie został zainstalowany. Jest on wymagany do uruchomienia." + }, + "sign": { + "tags": "autoryzacja, inicjały, podpis odręczny, podpis tekstowy, podpis graficzny", + "title": "Podpis", + "header": "Dodaj podpis do dokumentu PDF", + "upload": "Wczytaj opbraz", + "draw": "Narysuj podpis", + "text": "WprowadÅŗ tekst", + "clear": "Wyczyść", + "add": "Dodaj", + "saved": "Zapisane podpisy", + "save": "Zapisany podpis", + "personalSigs": "Podpisy osobiste", + "sharedSigs": "Podpisy współdzielone", + "noSavedSigs": "Nie znaleziono zapisanych podpisów", + "addToAll": "Dodaj do wszystkich stron", + "delete": "Usuń", + "first": "Pierwsza strona", + "last": "Ostatnia strona", + "next": "Następna strona", + "previous": "Poprzednia strona", + "maintainRatio": "Przełącz zachowanie proporcji", + "undo": "Cofnij", + "redo": "Ponów" + }, + "flatten": { + "tags": "statyczny, dezaktywacja, nieinteraktywny, opływowy, streamline", + "title": "Spłaszcz", + "header": "Spłaszcz dokument(y) PDF", + "flattenOnlyForms": "Spłaszcz tylko formularze", + "submit": "Spłaszcz" + }, + "repair": { + "tags": "naprawianie, naprawa, przywracanie, poprawianie, odzyskiwanie", + "title": "Napraw", + "header": "Napraw dokument(y) PDF", + "submit": "Napraw" + }, + "removeBlanks": { + "tags": "czyszczenie, usprawnianie, brak treści, organizowanie", + "title": "Usuń puste", + "header": "Usuń puste strony", + "threshold": "Próg:", + "thresholdDesc": "Próg określający, jak biały musi być biały piksel", + "whitePercent": "Procent białego (%):", + "whitePercentDesc": "Procent strony, która musi być biała, aby została usunięta", + "submit": "Usuń puste" + }, + "removeAnnotations": { + "tags": "komentarze, podświetlanie, notatki, znaczniki, usuwanie", + "title": "Usuń notatki", + "header": "Usuń notatki", + "submit": "Usuń" + }, + "compare": { + "tags": "rozróżnienie, kontrast, zmiany, analiza", + "title": "Porównaj", + "header": "Porównaj PDF(y)", + "highlightColor": { + "1": "Kolor Podświetlenia 1:", + "2": "Kolor Podświetlenia 2:" + }, + "document": { + "1": "Dokument 1", + "2": "Dokument 2" + }, + "submit": "Porównaj", + "complex": { + "message": "Jeden lub oba dostarczone dokumenty są dużymi plikami, dokładność porównania może być zmniejszona" + }, + "large": { + "file": { + "message": "Jeden lub oba dostarczone dokumenty są zbyt duże do przetworzenia" + } + }, + "no": { + "text": { + "message": "Jeden lub oba wybrane pliki PDF nie zawierają treści tekstowej. Wybierz pliki PDF z tekstem do porównania." + } + } + }, + "certSign": { + "tags": "uwierzytelnianie, PEM, P12, oficjalny, szyfrowanie", + "title": "Podpisywanie certyfikatem", + "header": "Podpisz dokument PDF certyfikatem prywatnym (moduł w budowie)", + "selectPDF": "Wybierz dokument PDF do podpisania:", + "jksNote": "Notka: jeśli twój typ certyfikatu nie jest widoczny na liście, skonwertuj go do formatu Java Keystore (.jks) używając polecenia keytool. Następnie wybierz plik .JKS poniżej z listy.", + "selectKey": "Wybierz plik klucza prywatnego (format PKCS#8, może to być .pem lub .der):", + "selectCert": "Wybierz plik certyfikatu (format X.509, może to być .pem lub .der):", + "selectP12": "Wybierz plik magazynu kluczy PKCS#12 (.p12 lub .pfx) (opcjonalnie, jeśli jest podany, powinien zawierać klucz prywatny i certyfikat):", + "selectJKS": "Wybierz plik Java Keystore (.jks lub .keystore):", + "certType": "Typ certyfikatu", + "password": "WprowadÅŗ hasło do magazynu kluczy lub klucza prywatnego (jeśli istnieje):", + "showSig": "Wyświetl podpis", + "reason": "Organizacja", + "location": "Lokalizacja", + "name": "Nazwa", + "showLogo": "Show Logo", + "submit": "Podpisz PDF" + }, + "removeCertSign": { + "tags": "uwierzytelnianie, PEM, P12, oficjalny, odszyfrowywanie", + "title": "Usuń podpis cyfrowy", + "header": "Usuń podpis cyfrowy z dokumentu PDF", + "selectPDF": "Wskaż plik PDF:", + "submit": "Usuń podpis cyfrowy" + }, + "pageLayout": { + "tags": "scalanie, kompozycja, pojedynczy widok, organizowanie, porządkowanie", + "title": "Układ wielu stron", + "header": "Układ wielu stron", + "pagesPerSheet": "Stron na jednym arkuszu:", + "addBorder": "Dodaj granicę", + "submit": "Wykonaj" + }, + "scalePages": { + "tags": "zmiana rozmiaru, modyfikacja, rozmiar, dostosowanie", + "title": "Dopasuj rozmiar stron", + "header": "Dopasuj rozmiar stron", + "pageSize": "Rozmiar stron dokumentu:", + "keepPageSize": "Original Size", + "scaleFactor": "Poziom powiększenia (przycięcia) stron:", + "submit": "Wykonaj" + }, + "add-page-numbers": { + "tags": "stronicowanie, etykieta, organizowanie, indeks, index" + }, + "auto-rename": { + "tags": "automatyczne wykrywanie, oparte na nagłówkach, organizowanie, ponowne etykietowanie", + "title": "Automatyczna zmiana nazwy", + "header": "Automatyczna zmiana nazwy dokumentu PDF", + "submit": "Automatyczna zmiana nazwy" + }, + "adjust-contrast": { + "tags": "Korekcja kolorów, dostrajanie, modyfikacja, ulepszanie" + }, + "crop": { + "tags": "przycinanie, zmniejszanie, edycja, kształtowanie", + "title": "Przytnij", + "header": "Przytnij dokument PDF", + "submit": "Wyślij" + }, + "autoSplitPDF": { + "tags": "Oparty na QR, rozdzielanie, skanowanie, organizowanie", + "title": "Automatycznie podziel PDF", + "header": "Automatycznie podziel PDF", + "description": "Drukuj, wstaw, skanuj, wyślij i pozwól nam automatycznie posortować dokumenty. Bez ręcznego sortowania.", + "selectText": { + "1": "Wydrukuj strony separacji z poniższych wzorów - (mogą być czarno-białe)", + "2": "Skanuj wszystkie swoje dokumenty na raz, wstawiając stronę separator między nie.", + "3": "Wyślij pojedynczy duży plik PDF zawierający skan i pozwól Stirling PDF zająć się resztą.", + "4": "Strony separacji są automatycznie wykrywane i usuwane, gwarantując ładny finalny dokument." + }, + "formPrompt": "Wyślij dokument PDF zawierający strony podziału z Stirling PDF.", + "duplexMode": "Skanowanie dwustronne", + "dividerDownload2": "Pobierz 'Auto Splitter Divider (with instructions).pdf'", + "submit": "Wyślij" + }, + "sanitizePdf": { + "tags": "czyszczenie, ochrona, bezpieczeństwo, usuwanie zagrożeń" + }, + "URLToPDF": { + "tags": "przechwytywanie stron internetowych, zapisywanie strony, strona internetowa do dokumentu, archiwizacja", + "title": "URL do PDF", + "header": "URL do PDF", + "submit": "Konwertuj", + "credit": "Użyj WeasyPrint" + }, + "HTMLToPDF": { + "tags": "znaczniki, treść internetowa, transformacja, konwertowanie", + "title": "HTML do PDF", + "header": "HTML do PDF", + "help": "Akceptuje pliki HTML oraz ZIP zawierające html/css/obrazy", + "submit": "Konwertuj", + "credit": "Użyj WeasyPrint", + "zoom": "Powiększ", + "pageWidth": "Szerokość strony w cm (zostaw puste dla autoskalowania)", + "pageHeight": "Wysokość strony w cm (zostaw puste dla autoskalowania)", + "marginTop": "Górny margines strony w mm (zostaw puste dla autoskalowania)", + "marginBottom": "Dolny margines strony w mm (zostaw puste dla autoskalowania)", + "marginLeft": "Lewy margines strony w mm (zostaw puste dla autoskalowania)", + "marginRight": "Prawy margines strony w mm (zostaw puste dla autoskalowania)", + "printBackground": "Używaj tła stron", + "defaultHeader": "Domyślny nagłówek (Nazwa i numer strony)", + "cssMediaType": "Wskaż CSS dla strony", + "none": "Å»aden", + "print": "Drukuj", + "screen": "Ekran" + }, + "MarkdownToPDF": { + "tags": "znaczniki, treść internetowa, transformacja, konwertowanie", + "title": "Markdown do PDF", + "header": "Markdown do PDF", + "submit": "Konwertuj", + "help": "Prace trwają", + "credit": "Użyj WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "znaczniki,treść internetowa,transformacja,konwersja,md", + "title": "PDF do Markdown", + "header": "PDF do Markdown", + "submit": "Konwertuj" + }, + "getPdfInfo": { + "tags": "informacje, dane, statystyka, statystyki", + "title": "Pobierz informacje o pliku PDF", + "header": "Pobierz informacje o pliku PDF", + "submit": "Pobierz informacje", + "downloadJson": "Pobierz JSON z zawartością" + }, + "extractPage": { + "tags": "wydobycie,separacja,wyciaganie" + }, + "PdfToSinglePage": { + "tags": "pojedyncza strona" + }, + "showJS": { + "tags": "JS", + "title": "Pokaż Javascript", + "header": "Pokaż Javascript", + "downloadJS": "Pobierz Javascript", + "submit": "Pokaż" + }, + "autoRedact": { + "tags": "Redagowanie, ukrywanie, zaciemnianie, zaczernianie, zaznaczanie, ukrywanie", + "title": "Automatyczne zaciemnienie", + "header": "Automatyczne zaciemnienie", + "colorLabel": "Kolor", + "textsToRedactLabel": "Tekst do zaciemnienia (podzielony liniami)", + "textsToRedactPlaceholder": "przykład \\n Poufne \\n Ściśle tajne", + "useRegexLabel": "Użyj RegExp", + "wholeWordSearchLabel": "Szukaj całego słowa", + "customPaddingLabel": "Dodatkowe wypełnienie", + "convertPDFToImageLabel": "Przerób PDF na PDF-obrazowy (usuwa tekst w tle)", + "submitButton": "Wyślij" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Redakcja ręczna", + "header": "Redakcja ręczna", + "submit": "Redaguj", + "textBasedRedaction": "Redakcja oparta na tekście", + "pageBasedRedaction": "Redakcja oparta na stronach", + "convertPDFToImageLabel": "Konwertuj PDF do PDF-Image (służy do usuwania tekstu za polem)", + "pageRedactionNumbers": { + "title": "Strony", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Kolor redakcji" + }, + "export": "Eksport", + "upload": "Prześlij", + "boxRedaction": "Redakcja za pomocą prostokąta", + "zoom": "Powiększenie", + "zoomIn": "Powiększ", + "zoomOut": "Pomniejsz", + "nextPage": "Następna strona", + "previousPage": "Poprzednia strona", + "toggleSidebar": "Przełącz panel boczny", + "showThumbnails": "Pokaż miniatury", + "showDocumentOutline": "Pokaż zarys dokumentu (kliknij dwukrotnie, aby rozwinąć/zwinąć wszystkie elementy)", + "showAttatchments": "Pokaż załączniki", + "showLayers": "Pokaż warstwy (kliknij dwukrotnie, aby przywrócić domyślny stan warstw)", + "colourPicker": "Selektor kolorów", + "findCurrentOutlineItem": "ZnajdÅŗ bieżący element zarysu", + "applyChanges": "Zastosuj zmiany" + }, + "tableExtraxt": { + "tags": "CSV, ekstrakcja tabeli, ekstrakcja, konwersja, wydobywanie" + }, + "autoSizeSplitPDF": { + "tags": "pdf, dzielenie, dokument, organizacja" + }, + "overlay-pdfs": { + "tags": "Nakładka", + "header": "Nałóż pliki PDF", + "baseFile": { + "label": "Wybierz bazowy plik PDF" + }, + "overlayFiles": { + "label": "Wybierz plik(i) nakładane PDF" + }, + "mode": { + "label": "Wybierz tryb nakładania", + "sequential": "Sekwencyjny", + "interleaved": "Przeplatany", + "fixedRepeat": "Ustalona ilośc powtórzeń" + }, + "counts": { + "label": "Ile potwórzeń", + "placeholder": "WprowadÅŗ numerację rozdzieloną przecinkami (2,3,1)" + }, + "position": { + "label": "Wybierz miejsce nakładania", + "foreground": "Przód", + "background": "Tło" + }, + "submit": "Wyślij" + }, + "split-by-sections": { + "tags": "Podział sekcji, dzielenie, dostosowywanie", + "title": "Podziel PDF przez sekcje", + "header": "Podziel PDF w sekcje", + "horizontal": { + "label": "Podział pionowy", + "placeholder": "Podaj ilość podziałów pionowych" + }, + "vertical": { + "label": "Podział poziomy", + "placeholder": "Podaj ilość podziałów poziomych" + }, + "submit": "Podziel PDF", + "merge": "Połącz w jednego PDF" + }, + "AddStampRequest": { + "tags": "Stempel, dodawanie obrazu, wyśrodkowanie obrazu, znak wodny, PDF, osadzanie, dostosowywanie", + "header": "Pieczęć PDF", + "title": "Pieczęć PDF", + "stampType": "Typ pieczęci", + "stampText": "Tekst w pieczęci", + "stampImage": "Obraz w pieczęci", + "alphabet": "Alfabet", + "fontSize": "Rozmiar czcionki/obrazu", + "rotation": "Obrót", + "opacity": "PrzeÅŗroczystość", + "position": "Pozycja", + "overrideX": "Nadpisz koordynatę X", + "overrideY": "Nadpisz koordynatę Y", + "customMargin": "Własny margines", + "customColor": "Własny kolor tekstu", + "submit": "Wyślij" + }, + "removeImagePdf": { + "tags": "Usuń obraz, operacje na stronie, back-end, strona serwera" + }, + "splitPdfByChapters": { + "tags": "podział, rozdziały, zakładki, porządkowanie, organizacja" + }, + "validateSignature": { + "tags": "podpis,weryfikuj,pdf,certyfikat,podpis cyfrowy,weryfikuj podpis,weryfikuj certyfikat", + "title": "Weryfikacja podpisów PDF", + "header": "Weryfikacja podpisów cyfrowych", + "selectPDF": "Wybierz podpisany plik PDF", + "submit": "SprawdÅŗ podpisy", + "results": "Wyniki weryfikacji", + "status": { + "_value": "Status", + "valid": "Poprawny", + "invalid": "Niepoprawny" + }, + "signer": "Podpisujący", + "date": "Data", + "reason": "Powód", + "location": "Lokalizacja", + "noSignatures": "Nie znaleziono podpisów cyfrowych w tym dokumencie", + "chain": { + "invalid": "Weryfikacja łańcucha certyfikatów nie powiodła się – nie można zweryfikować tożsamości podpisującego" + }, + "trust": { + "invalid": "Certyfikat nie znajduje się w magazynie zaufania – Åŗródło nie może zostać zweryfikowane" + }, + "cert": { + "expired": "Certyfikat wygasł", + "revoked": "Certyfikat został unieważniony", + "info": "Szczegóły certyfikatu", + "issuer": "Wystawca", + "subject": "Podmiot", + "serialNumber": "Numer seryjny", + "validFrom": "Ważny od", + "validUntil": "Ważny do", + "algorithm": "Algorytm", + "keySize": "Rozmiar klucza", + "version": "Wersja", + "keyUsage": "Zastosowanie klucza", + "selfSigned": "Samopodpisany", + "bits": "bity" + }, + "signature": { + "info": "Informacje o podpisie", + "_value": "Podpis", + "mathValid": "Podpis jest matematycznie poprawny, ALE:" + }, + "selectCustomCert": "Niestandardowy plik certyfikatu X.509 (Opcjonalne)" + }, + "replace-color": { + "title": "Zamień-Odwróć-Kolor", + "header": "Zamień-Odwróć kolor PDF", + "selectText": { + "1": "Zastąp lub Odwróć opcje kolorów", + "2": "Domyślnie (domyślne kolory o wysokim kontraście)", + "3": "Niestandardowe (kolory niestandardowe)", + "4": "Całkowita-Odwrotność (Odwrócenie wszystkich kolorów)", + "5": "Wysoki kontrast opcji kolorystycznych", + "6": "biały tekst na czarnym tle", + "7": "Czarny tekst na białym tle", + "8": "Żółty tekst na czarnym tle", + "9": "Zielony tekst na czarnym tle", + "10": "Wybierz Kolor tekstu", + "11": "Wybierz Kolor tła" + }, + "submit": "Zamień" + }, + "replaceColorPdf": { + "tags": "Zastąp kolor, operacje na stronach, back-end, strona serwera" + }, + "login": { + "title": "Logowanie", + "header": "Logowanie", + "signin": "Logowanie", + "rememberme": "Zapamiętaj", + "invalid": "Nieprawidłowe dane logowania", + "locked": "Konto jest zablokowane", + "signinTitle": "Zaloguj się", + "ssoSignIn": "Zaloguj się za pomocą logowania jednokrotnego", + "oAuth2AutoCreateDisabled": "Wyłączono automatyczne tworzenie użytkownika OAUTH2", + "oAuth2AdminBlockedUser": "Rejestracja lub logowanie niezarejestrowanych użytkowników jest obecnie zablokowane. Prosimy o kontakt z administratorem.", + "oauth2RequestNotFound": "Błąd logowania OAuth2", + "oauth2InvalidUserInfoResponse": "Niewłaściwe dane logowania", + "oauth2invalidRequest": "Nieprawidłowe żądanie", + "oauth2AccessDenied": "Brak dostępu", + "oauth2InvalidTokenResponse": "Nieprawidłowa odpowiedÅŗ na token", + "oauth2InvalidIdToken": "Nieprawidłowa wartość tokenu", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "Użytkownik jest nieaktywny, logowanie przy użyciu tej nazwy użytkownika jest obecnie zablokowane. Prosimy o kontakt z administratorem.", + "alreadyLoggedIn": "Jesteś już zalogowany na", + "alreadyLoggedIn2": "urządzeniach. Wyloguj się z tych urządzeń i spróbuj ponownie.", + "toManySessions": "Masz zbyt wiele aktywnych sesji", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF do pojedyńczej strony", + "header": "PDF do pojedyńczej strony", + "submit": "Zapisz dokument jako PDF z jedną stroną" + }, + "pageExtracter": { + "title": "Wyciągnij stronę", + "header": "Wyciągnij stronę", + "submit": "Wyciągnij", + "placeholder": "(przykład 1,2,8 lub 2n-1)" + }, + "sanitizePDF": { + "title": "Dezynfekuj PDF", + "header": "Dezynfekuj dokument PDF", + "selectText": { + "1": "Usuń elementy JavaScript", + "2": "Usuń załączone pliki", + "3": "Usuń metadane XMP", + "4": "Usuń linki", + "5": "Usuń czcionki", + "6": "Remove Document Info Metadata" + }, + "submit": "Dezynfekuj PDF" + }, + "adjustContrast": { + "title": "Dopasuj kontrast", + "header": "Dopasuj kontrast", + "contrast": "Kontrast:", + "brightness": "Jasność:", + "saturation": "Nasycenie:", + "download": "Pobierz" + }, + "compress": { + "title": "Kompresuj", + "header": "Kompresuj PDF", + "credit": "Ta usługa używa qpdf do kompresji/optymalizacji PDF.", + "grayscale": { + "label": "Zastosuj skalę szarości do kompresji" + }, + "selectText": { + "1": { + "_value": "Ustawienia kompresji", + "1": "1-3 kompresja PDF,
4-6 lekka kompresja obrazów,
7-9 intensywna kompresja obrazów
Znacznie obniży jakość obrazu" + }, + "2": "Poziom optymalizacji:", + "4": "Tryb automatyczny - Automatycznie dostosowuje jakość, aby uzyskać dokładny rozmiar pliku PDF", + "5": "Oczekiwany rozmiar pliku PDF (np. 25 MB, 10,8 MB, 25 KB)" + }, + "submit": "Kompresuj" + }, + "decrypt": { + "passwordPrompt": "Ten plik jest chroniony hasłem. WprowadÅŗ hasło:", + "cancelled": "Operacja anulowana dla PDF: {0}", + "noPassword": "Nie podano hasła dla zaszyfrowanego PDF: {0}", + "invalidPassword": "Spróbuj ponownie, używając poprawnego hasła.", + "invalidPasswordHeader": "Nieprawidłowe hasło lub nieobsługiwane szyfrowanie dla PDF: {0}", + "unexpectedError": "Wystąpił błąd podczas przetwarzania pliku. Spróbuj ponownie.", + "serverError": "Błąd serwera podczas odszyfrowywania: {0}", + "success": "Plik został pomyślnie odszyfrowany." + }, + "multiTool-advert": { + "message": "Ta funkcja jest również dostępna na naszej stronie narzędzia wielofunkcyjnego. SprawdÅŗ ją, aby uzyskać lepszy interfejs zarządzania stronami i dodatkowe funkcje!" + }, + "pageRemover": { + "title": "Narzędzie do usuwania stron", + "header": "Narzędzie do usuwania stron w dokumentach PDF", + "pagesToDelete": "Strony do usunięcia (wprowadÅŗ listę numerów stron oddzielonych przecinkami):", + "submit": "Usuń strony", + "placeholder": "(przykład 1,3,2 lub 4-8,2,10-12)" + }, + "imageToPDF": { + "title": "Obraz na PDF", + "header": "Obraz na PDF", + "submit": "Konwertuj", + "selectLabel": "Opcje dopasowania", + "fillPage": "Wypełnij stronę", + "fitDocumentToImage": "Dopasuj stronę do obrazu", + "maintainAspectRatio": "Zachowaj proporcje", + "selectText": { + "2": "Automatyczne obracanie PDF", + "3": "Logika wielu plików (dostępna tylko w przypadku pracy z wieloma obrazami)", + "4": "Połącz w jeden dokument PDF", + "5": "Konwertuj na osobne dokumenty PDF" + } + }, + "PDFToCSV": { + "title": "PDF na CSV", + "header": "PDF na CSV", + "prompt": "Wybierz stronę do wyodrębnienia tabeli", + "submit": "ZatwierdÅŗ" + }, + "split-by-size-or-count": { + "title": "Podziel PDF przez ilość stron bądÅŗ rozmiar", + "header": "Podziel PDF przez ilość stron bądÅŗ rozmiar", + "type": { + "label": "Wybierz typ podziału:", + "size": "Rozmiar", + "pageCount": "Ilość stron", + "docCount": "Ilość dokumentów" + }, + "value": { + "label": "Podaj wartość", + "placeholder": "Podaj rozmiar(2MB lub 3KB) albo ilość(1 lub 4 lub 5)" + }, + "submit": "Wyślij" + }, + "printFile": { + "title": "Drukuj plik", + "header": "Drukuj plik za pomocą drukarki", + "selectText": { + "1": "Wskaż plik do wydruku", + "2": "Wskaż drukarkę" + }, + "submit": "Drukuj" + }, + "licenses": { + "nav": "Licencje", + "title": "Licencje stron trzecich", + "header": "Licencje stron trzecich", + "module": "Moduł", + "version": "Wersja", + "license": "Licencja" + }, + "survey": { + "nav": "Ankieta", + "title": "Ankieta Stirling-PDF", + "description": "Stirling-PDF nie śledzi swoich użytkowników, dlatego chciałby poznać ich opinie!", + "changes": "Stirling-PDF zmieniło się od czasu ostatniej ankiety! Aby dowiedzieć się więcej, sprawdÅŗ nasz wpis na blogu tutaj:", + "changes2": "Dzięki tym zmianom otrzymujemy płatne wsparcie biznesowe i finansowanie", + "please": "Prosimy, wypełnij dla nas ankietę!", + "disabled": "(Blokada wyskakującego okienka z ankietą zostanie dodana w następnych aktualizacjach, ale będzie dostępna na dole strony)", + "button": "Wypełnij ankietę", + "dontShowAgain": "Nie pokazuj ponownie.", + "meeting": { + "1": "Jeśli używasz Stirling-PDF w pracy, chętnie z Tobą porozmawiamy. Oferujemy sesje wsparcia technicznego w zamian za 15-minutowe spotkanie odkrywcze z użytkownikiem.", + "2": "To okazja do:", + "3": "Uzyskania pomocy w zakresie wdrożenia, integracji lub rozwiązywania problemów", + "4": "Przekazania bezpośredniej opinii na temat wydajności, nietypowych przypadków i brakujących funkcji", + "5": "Pomocy w dopracowaniu Stirling-PDF do zastosowań w rzeczywistych warunkach biznesowych", + "6": "Jeśli jesteś zainteresowany, możesz bezpośrednio umówić się na spotkanie z naszym zespołem. (Spotkania tylko w języku angielskim)", + "7": "Nie możemy się doczekać, aby poznać Twoje przypadki użycia i uczynić Stirling-PDF jeszcze lepszym!", + "notInterested": "Nie jesteś firmą i/lub nie jesteś zainteresowany spotkaniem?", + "button": "Zarezerwuj spotkanie" + } + }, + "removeImage": { + "title": "Usuń obraz", + "header": "Usuń obraz", + "removeImage": "Usuń obraz", + "submit": "Usuń obraz" + }, + "splitByChapters": { + "title": "Podziel PDF według Rozdziałów", + "header": "Podziel PDF według Rozdziałów", + "bookmarkLevel": "Poziom Zakładek", + "includeMetadata": "Dołącz Metadane", + "allowDuplicates": "Zezwalaj na Duplikaty", + "desc": { + "1": "Narzędzie to dzieli plik PDF na wiele plików PDF w oparciu o strukturę rozdziałów.", + "2": "Poziom Zakładek: Wybierz poziom zakładek, który ma zostać użyty do podziału (0 dla najwyższego poziomu, 1 dla drugiego poziomu itd.).", + "3": "Dołącz Metadane: Jeśli opcja ta jest zaznaczona, metadane oryginalnego pliku PDF zostaną uwzględnione w każdym rozdzielonych plików PDF.", + "4": "Zezwól na Duplikaty: Jeśli ta opcja jest zaznaczona, pozwala na tworzenie oddzielnych plików PDF przez wiele zakładek na tej samej stronie." + }, + "submit": "Podziel PDF" + }, + "fileChooser": { + "click": "Kliknij", + "or": "lub", + "dragAndDrop": "Przeciągnij i upuść", + "dragAndDropPDF": "Przeciągnij i upuść plik PDF", + "dragAndDropImage": "Przeciągnij i upuść plik obrazu", + "hoveredDragAndDrop": "Przeciągnij i upuść plik(i) tutaj", + "extractPDF": "Trwa wyodrębnianie..." + }, + "releases": { + "footer": "Wydania", + "title": "Informacje o wydaniu", + "header": "Informacje o wydaniu", + "current": { + "version": "Obecna wersja" + }, + "note": "Informacje o wydaniu są dostępne tylko w języku angielskim" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/pt-BR/translation.json b/frontend/public/locales/pt-BR/translation.json new file mode 100644 index 000000000..45a2d2d94 --- /dev/null +++ b/frontend/public/locales/pt-BR/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Tamanho da Fonte", + "fontName": "Nome da Fonte", + "title": "Adicionar NĆŗmeros de PĆ”gina", + "header": "Adicionar NĆŗmeros de PĆ”gina", + "selectText": { + "1": "Selecionar arquivo PDF:", + "2": "Tamanho da margem:", + "3": "Posição:", + "4": "NĆŗmero inicial:", + "5": "PĆ”ginas a numerar:", + "6": "Texto personalizado:" + }, + "customTextDesc": "Texto personalizado:", + "numberPagesDesc": "Quais pĆ”ginas numerar, padrĆ£o 'todas', tambĆ©m aceita 1-5 ou 2,5,9,etc.", + "customNumberDesc": "O padrĆ£o Ć© {n}, tambĆ©m aceita 'PĆ”gina {n} de {total}', 'Texto-{n}', '{nome do arquivo}-{n}'", + "submit": "Adicionar NĆŗmeros de PĆ”gina" + }, + "pdfPrompt": "Selecione o(s) PDF(s)", + "multiPdfPrompt": "Selecione os PDFs (2+)", + "multiPdfDropPrompt": "Selecione (ou arraste e solte) todos os PDFs desejados:", + "imgPrompt": "Selecione a(s) Imagem(ns)", + "genericSubmit": "Enviar", + "uploadLimit": "Tamanho mĆ”ximo do arquivo:", + "uploadLimitExceededSingular": "estĆ” acima do limite. Tamanho mĆ”ximo permitido Ć©", + "uploadLimitExceededPlural": "estĆ£o acima do limite. Tamanho mĆ”ximo permitido Ć©", + "processTimeWarning": "Aviso: Este processo pode levar atĆ© um minuto, dependendo do tamanho do arquivo", + "pageOrderPrompt": "Ordem de PĆ”gina Personalizada (Digite uma lista de nĆŗmeros de pĆ”ginas, separadas por vĆ­rgula ou funƧƵes como 2n+1):", + "pageSelectionPrompt": "Seleção de PĆ”gina Personalizada (Digite uma lista de nĆŗmeros de pĆ”ginas, separadas por vĆ­rgula como 1,5,6 ou funƧƵes como 2n+1):", + "goToPage": "Ir", + "true": "Verdadeiro", + "false": "Falso", + "unknown": "Desconhecido", + "save": "Salvar", + "saveToBrowser": "Salvar no Navegador", + "close": "Fechar", + "filesSelected": "Arquivos Selecionados", + "noFavourites": "Nenhum Favorito Adicionado", + "downloadComplete": "Download Completo", + "bored": "Entediado? Clique aqui!", + "alphabet": "Alfabeto", + "downloadPdf": "Baixar PDF", + "text": "Texto", + "font": "Fonte", + "selectFillter": "-- Selecione --", + "pageNum": "NĆŗmero da PĆ”gina", + "sizes": { + "small": "Pequeno", + "medium": "MĆ©dio", + "large": "Grande", + "x-large": "Extra grande" + }, + "error": { + "pdfPassword": "O PDF estĆ” protegido por senha e a senha nĆ£o foi fornecida ou estĆ” incorreta", + "_value": "Erro", + "sorry": "Desculpe pelo problema!", + "needHelp": "Precisa de ajuda / Encontrou um problema?", + "contactTip": "Se vocĆŖ ainda estiver com problemas, nĆ£o hesite em entrar em contato conosco para obter ajuda. VocĆŖ pode enviar um tĆ­quete em nossa pĆ”gina GitHub ou entrar em contato conosco atravĆ©s do Discord:", + "404": { + "head": "404 - PĆ”gina nĆ£o encontrada | Ops, tropeƧamos no código!", + "1": "NĆ£o conseguimos encontrar a pĆ”gina que vocĆŖ estĆ” procurando.", + "2": "Algo deu errado" + }, + "github": "Submeter um tĆ­quete no GitHub", + "showStack": "Mostrar rastreamento de pilha", + "copyStack": "Copiar rastreamento de pilha", + "githubSubmit": "GitHub - Submeter um tĆ­quete", + "discordSubmit": "Discord - Submeter um post de suporte" + }, + "delete": "Apagar", + "username": "UsuĆ”rio", + "password": "Senha", + "welcome": "Bem-vindo", + "property": "Propriedade", + "black": "Preto", + "white": "Branco", + "red": "Vermelho", + "green": "Verde", + "blue": "Azul", + "custom": "Personalizado...", + "WorkInProgess": "Trabalho em progresso, talvez nĆ£o funcione ou apresente erros, Por favor, reporte qualquer problema!", + "poweredBy": "DistribuĆ­do por", + "yes": "Sim", + "no": "NĆ£o", + "changedCredsMessage": "Credenciais alteradas!", + "notAuthenticatedMessage": "UsuĆ”rio nĆ£o autenticado.", + "userNotFoundMessage": "UsuĆ”rio nĆ£o encontrado.", + "incorrectPasswordMessage": "A senha atual estĆ” incorreta.", + "usernameExistsMessage": "Novo UsuĆ”rio jĆ” existe.", + "invalidUsernameMessage": "UsuĆ”rio invĆ”lido, nome de usuĆ”rio só pode conter letras, nĆŗmeros e os seguintes caracteres especiais @._+- ou deve ser um e-mail vĆ”lido.", + "invalidPasswordMessage": "A senha nĆ£o deve estar vazia e nĆ£o deve conter espaƧos no inĆ­cio ou no final.", + "confirmPasswordErrorMessage": "Nova Senha e Confirmar Nova Senha devem ser iguais.", + "deleteCurrentUserMessage": "NĆ£o Ć© possĆ­vel apagar usuĆ”rio conectado no momento.", + "deleteUsernameExistsMessage": "O usuĆ”rio nĆ£o existe e desta forma nĆ£o pode ser apagado.", + "downgradeCurrentUserMessage": "NĆ£o Ć© possĆ­vel fazer downgrade da função do usuĆ”rio conectado no momento.", + "disabledCurrentUserMessage": "O usuĆ”rio atual nĆ£o pode ser desativado.", + "downgradeCurrentUserLongMessage": "NĆ£o Ć© possĆ­vel fazer downgrade da função do usuĆ”rio atual. Portanto, o usuĆ”rio atual nĆ£o serĆ” mostrado.", + "userAlreadyExistsOAuthMessage": "O usuĆ”rio jĆ” existe como um usuĆ”rio OAuth2.", + "userAlreadyExistsWebMessage": "O usuĆ”rio jĆ” existe como um usuĆ”rio Web.", + "oops": "Ops!", + "help": "Ajuda", + "goHomepage": "Ir para a PĆ”gina Inicial", + "joinDiscord": "Junte-se ao nosso servidor Discord", + "seeDockerHub": "Visite nosso Docker Hub", + "visitGithub": "Visite nosso repositório no GitHub", + "donate": "Doar", + "color": "Cor", + "sponsor": "Patrocinador", + "info": "InformaƧƵes", + "pro": "Profissional", + "page": "PĆ”gina", + "pages": "PĆ”ginas", + "loading": "Carregando...", + "addToDoc": "Adicionar ao Documento", + "reset": "Reiniciar", + "apply": "Aplicar", + "noFileSelected": "Nenhum arquivo selecionado. Por favo, envie um arquivo.", + "legal": { + "privacy": "PolĆ­tica de Privacidade", + "terms": "Termos e CondiƧƵes", + "accessibility": "Acessibilidade", + "cookie": "PolĆ­tica de Cookies", + "impressum": "InformaƧƵes legais", + "showCookieBanner": "PreferĆŖncias de Cookies" + }, + "pipeline": { + "header": "Menu do Pipeline (Beta)", + "uploadButton": "Carregar Arquivo Personalizado", + "configureButton": "Configurar", + "defaultOption": "Arquivo Personalizado", + "submitButton": "Enviar", + "help": "Ajuda relacionada ao Pipeline", + "scanHelp": "Ajuda para leitura e processamento de pastas", + "deletePrompt": "Tem certeza de que deseja excluir o pipeline ->", + "tags": "automatizar,sequĆŖncia,scriptado,processo-em-lote", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Configuração do Pipeline", + "pipelineNameLabel": "Nome do Pipeline:", + "saveSettings": "Salvar ConfiguraƧƵes da Operação", + "pipelineNamePrompt": "Insira o nome do pipeline neste campo", + "selectOperation": "Selecione uma Operação:", + "addOperationButton": "Adicione a Operação", + "pipelineHeader": "Pipeline:", + "saveButton": "Baixar (JSON)", + "validateButton": "Validar" + }, + "enterpriseEdition": { + "button": "Atualize para a versĆ£o Pro", + "warning": "Este recurso só estĆ” disponivel para usuĆ”rios da versĆ£o Pro.", + "yamlAdvert": "Stirling PDF Pro suporta arquivos de configuração YAML e outros recursos SSO.", + "ssoAdvert": "Procurando por mais recursos de controle de usuĆ”rios? Veja a versĆ£o Pro do Stirling PDF" + }, + "analytics": { + "title": "VocĆŖ quer melhorar o Stirling PDF?", + "paragraph1": "Stirling PDF possui coleta de dados opcional para ajudar a melhorar o produto. Nós nĆ£o rastreamos nenhuma informação pessoal ou conteĆŗdo dos arquivos.", + "paragraph2": "Por favor considere habilitar a coleta de dados para ajudar Stirling PDF a crescer e nos ajudar a entender melhor nossos usuĆ”rios.", + "enable": "Habilitar coleta de dados", + "disable": "Desabilitar coleta de dados", + "settings": "VocĆŖ pode alterar as configuraƧƵes de coleta de dados no arquivo config/settings.yml" + }, + "navbar": { + "favorite": "Favoritos", + "recent": "Novos e Recentemente Atualizados", + "darkmode": "Modo Escuro", + "language": "Idiomas", + "settings": "ConfiguraƧƵes", + "allTools": "Ferramentas", + "multiTool": "Multiferramentas", + "search": "Pesquisar", + "sections": { + "organize": "Organizar", + "convertTo": "Converter para PDF", + "convertFrom": "Converter de PDF", + "security": "Assinatura & SeguranƧa", + "advance": "AvanƧado", + "edit": "Visualizar & Editar", + "popular": "Populares" + } + }, + "settings": { + "title": "ConfiguraƧƵes", + "update": "Atualização disponĆ­vel", + "updateAvailable": "{0} Ć© a versĆ£o atualmente instalada. Uma nova versĆ£o ({1}) estĆ” disponĆ­vel.", + "appVersion": "VersĆ£o do Aplicativo:", + "downloadOption": { + "title": "Escolha a opção de download (para download de arquivo Ćŗnico, nĆ£o compactados):", + "1": "Abrir na mesma janela", + "2": "Abrir em nova janela", + "3": "Baixar o arquivo" + }, + "zipThreshold": "Compactar os arquivos quando o nĆŗmero baixado exceder:", + "signOut": "Sair", + "accountSettings": "ConfiguraƧƵes da Conta", + "bored": { + "help": "Habilitar jogos secretos" + }, + "cacheInputs": { + "name": "Salvar entradas do formulĆ”rio.", + "help": "Habilitar para armazenar entradas usadas anteriormente para execuƧƵes futuras" + } + }, + "changeCreds": { + "title": "Alterar Credenciais", + "header": "Atualizar Detalhes da Conta", + "changePassword": "VocĆŖ estĆ” usando as credenciais padrƵes. Por favor, insira uma nova senha", + "newUsername": "Novo UsuĆ”rio", + "oldPassword": "Senha Atual", + "newPassword": "Senha Nova", + "confirmNewPassword": "Confirme a Nova Senha", + "submit": "Enviar AlteraƧƵes" + }, + "account": { + "title": "ConfiguraƧƵes da Conta", + "accountSettings": "ConfiguraƧƵes da Conta", + "adminSettings": "ConfiguraƧƵes de Administrador – Visualizar e Adicionar UsuĆ”rios", + "userControlSettings": "ConfiguraƧƵes de Controle de UsuĆ”rio", + "changeUsername": "Alterar UsuĆ”rio", + "newUsername": "Novo UsuĆ”rio", + "password": "Senha de Confirmação", + "oldPassword": "Senha Antiga", + "newPassword": "Senha Nova", + "changePassword": "Alterar a Senha", + "confirmNewPassword": "Confirme a Nova Senha", + "signOut": "Sair", + "yourApiKey": "Sua chave de API", + "syncTitle": "Sincronize as configuraƧƵes do navegador com sua conta:", + "settingsCompare": "Comparação das ConfiguraƧƵes:", + "property": "Propriedade", + "webBrowserSettings": "Configuração do navegador Web", + "syncToBrowser": "Sincronizar Conta -> Navegador", + "syncToAccount": "Sincronizar Conta <- Navegador" + }, + "adminUserSettings": { + "title": "ConfiguraƧƵes de controle de usuĆ”rio", + "header": "ConfiguraƧƵes de controle do usuĆ”rio administrador", + "admin": "Administrador", + "user": "UsuĆ”rio", + "addUser": "Adicionar novo usuĆ”rio", + "deleteUser": "Apagar usuĆ”rio", + "confirmDeleteUser": "O usuĆ”rio deve ser apagado?", + "confirmChangeUserStatus": "O usuĆ”rio deve ser desabilitado/habilitado?", + "usernameInfo": "Nome de usuĆ”rio só pode incluir letras, nĆŗmeros e os seguintes caracteres especiais @._+- ou deve ser um e-mail vĆ”lido.", + "roles": "FunƧƵes", + "role": "Função", + "actions": "AƧƵes", + "apiUser": "UsuĆ”rio de API limitado", + "extraApiUser": "UsuĆ”rio de API limitado adicional", + "webOnlyUser": "UsuĆ”rio web apenas", + "demoUser": "UsuĆ”rio demo (Sem configuraƧƵes personalizadas)", + "internalApiUser": "UsuĆ”rio de API interno", + "forceChange": "ForƧar usuĆ”rio a trocar a senha ao iniciar sessĆ£o", + "submit": "Salvar UsuĆ”rio", + "changeUserRole": "Alterar Função do UsuĆ”rio", + "authenticated": "Autenticado", + "editOwnProfil": "Editar próprio perfil", + "enabledUser": "usuĆ”rio habilitado", + "disabledUser": "usuĆ”rio desabilitado", + "activeUsers": "UsuĆ”rios Ativos:", + "disabledUsers": "UsuĆ”rios Desabilitados:", + "totalUsers": "Total de UsuĆ”rios:", + "lastRequest": "Última solicitação", + "usage": "Ver Utilização" + }, + "endpointStatistics": { + "title": "EstatĆ­sticas de Endpoints", + "header": "EstatĆ­sticas de Endpoints", + "top10": "Top 10", + "top20": "Top 20", + "all": "Todos", + "refresh": "Atualizar", + "includeHomepage": "Incluir PĆ”gina Inicial ('/')", + "includeLoginPage": "Incluir PĆ”gina de Login ('/login')", + "totalEndpoints": "Total de Endpoints", + "totalVisits": "Total de Visitas", + "showing": "Mostrando", + "selectedVisits": "Visitas Selecionadas", + "endpoint": "Endpoint", + "visits": "Visitas", + "percentage": "Percentagem", + "loading": "Carregando...", + "failedToLoad": "Falha ao carregar dados do Endpoint. Por favor, tente atualizar.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "NĆŗmero de Visitas", + "visitsTooltip": "Visitas: {0} ({1}% do total)", + "retry": "Tentar novamente" + }, + "database": { + "title": "Importar/Exportar banco de dados", + "header": "Importar/Exportar banco de dados", + "fileName": "Nome do Arquivo", + "creationDate": "Data de Criação", + "fileSize": "Tamanho do Arquivo", + "deleteBackupFile": "Apagar arquivo de backup", + "importBackupFile": "Importar arquivo de backup", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Baixar arquivo de backup", + "info_1": "Ao importar dados, Ć© crucial garantir a estrutura correta. Se vocĆŖ nĆ£o tem certeza do que estĆ” fazendo procure auxĆ­lio de um profissional. Um erro na estrutura pode ocasionar em mau funcionamento da aplicação, incluindo a impossibilidade da aplicação ser executada.", + "info_2": "O nome do arquivo nĆ£o importa ao enviar. Ele serĆ” renomeado em seguida para seguir o formato backup_usuario_yyyyMMddHHmm.sql, garantindo uma convenção de nomes coerente.", + "submit": "Importar Backup", + "importIntoDatabaseSuccessed": "Importação para o banco de dados bem sucedida", + "backupCreated": "Database backup successful", + "fileNotFound": "Arquivo nĆ£o encontrado", + "fileNullOrEmpty": "O arquivo nĆ£o pode estar nulo ou vazio", + "failedImportFile": "Falha ao importar arquivo", + "notSupported": "Esta função nĆ£o estĆ” disponĆ­vel para sua conexĆ£o de banco de dados." + }, + "session": { + "expired": "Sua sessĆ£o expirou. Por gentileza atualize a pĆ”gina e tente novamente.", + "refreshPage": "Atualizar PĆ”gina" + }, + "home": { + "desc": "Seu tudo-em-um hospedado localmente para tudo relacionado a PDFs", + "searchBar": "Pesquisar funcionalidades...", + "viewPdf": { + "title": "Ver/Editar PDF", + "desc": "Visualizar, anotar, adicionar texto ou imagens ao PDF." + }, + "setFavorites": "Adicionar Favoritos", + "hideFavorites": "Ocultar Favoritos", + "showFavorites": "Mostrar Favoritos", + "legacyHomepage": "PĆ”gina Inicial Antiga", + "newHomePage": "Experimente nossa nova PĆ”gina Inicial!", + "alphabetical": "AlfabĆ©tica", + "globalPopularity": "Popularidade Global", + "sortBy": "Ordenar por:", + "multiTool": { + "title": "Multiferramentas de PDF", + "desc": "Mesclar, girar, reorganizar, dividir, inserir e remover pĆ”ginas." + }, + "merge": { + "title": "Mesclar", + "desc": "Mescle facilmente vĆ”rios PDFs em um só." + }, + "split": { + "title": "Dividir", + "desc": "Dividir PDFs em vĆ”rios documentos/arquivos." + }, + "rotate": { + "title": "Girar", + "desc": "Gire facilmente seus PDFs." + }, + "imageToPdf": { + "title": "Imagem para PDF", + "desc": "Converter uma imagem (PNG, JPG, GIF) em PDF." + }, + "pdfToImage": { + "title": "PDF para Imagem", + "desc": "Converter PDF em uma imagem (PNG, JPG, GIF e outros)." + }, + "pdfOrganiser": { + "title": "Organizar PĆ”ginas", + "desc": "Remover/reorganizar as pĆ”ginas de diversas formas diferentes." + }, + "addImage": { + "title": "Adicionar Imagem", + "desc": "Adicionar imagens em um local definido no PDF." + }, + "watermark": { + "title": "Adicionar Marca d'Ć”gua", + "desc": "Adicionar uma marca d'Ć”gua personalizada ao seu PDF." + }, + "permissions": { + "title": "Alterar PermissƵes", + "desc": "Alterar as permissƵes do seu PDF." + }, + "removePages": { + "title": "Remover PĆ”ginas", + "desc": "Excluir pĆ”ginas indesejadas do seu PDF." + }, + "addPassword": { + "title": "Proteger PDF", + "desc": "Criptografar seu PDF com uma senha podendo realizar alteraƧƵes de permissƵes." + }, + "removePassword": { + "title": "Desproteger PDF", + "desc": "Descriptografar o PDF realizando a remoção da senha." + }, + "compressPdfs": { + "title": "Comprimir", + "desc": "Comprimir PDFs para reduzir o tamanho do arquivo." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Alterar Metadados", + "desc": "Alterar/remover/adicionar metadados de um PDF." + }, + "fileToPDF": { + "title": "Converter Arquivo para PDF", + "desc": "Converter praticamente qualquer arquivo em PDF (DOCX, PNG, XLS, PPT, TXT e outros)." + }, + "ocr": { + "title": "Processamento de OCR", + "desc": "Reconhecimento Ɠptico de Caracteres transforma PDFs com imagens em documentos pesquisĆ”veis e com texto selecionĆ”vel." + }, + "extractImages": { + "title": "Extrair Imagens", + "desc": "Extrair as imagens de um PDF e salvĆ”-las em um arquivo compactado." + }, + "pdfToPDFA": { + "title": "PDF para PDF/A", + "desc": "Converter o PDF para o formato PDF/A, voltado a armazenamento a longo prazo." + }, + "PDFToWord": { + "title": "PDF para Word", + "desc": "Converter PDF para formatos Word (DOC, DOCX e ODT)." + }, + "PDFToPresentation": { + "title": "PDF para Apresentação", + "desc": "Converter PDF para formatos de Apresentação (PPT, PPTX e ODP)." + }, + "PDFToText": { + "title": "PDF para TXT/RTF", + "desc": "Converter PDF em formato de TXT ou RTF." + }, + "PDFToHTML": { + "title": "PDF para HTML", + "desc": "Converter PDF para o formato HTML." + }, + "PDFToXML": { + "title": "PDF para XML", + "desc": "Converter PDF para formato XML." + }, + "ScannerImageSplit": { + "title": "Detectar/Dividir Fotos Digitalizadas", + "desc": "Divide vĆ”rias fotos de dentro de uma imagem/PDF." + }, + "sign": { + "title": "Assinar", + "desc": "Adicionar assinatura ao PDF por desenho, texto ou imagem." + }, + "flatten": { + "title": "Achatar", + "desc": "Combinar todos os elementos e formulĆ”rios interativos de um PDF em uma Ćŗnica camada fixa, nĆ£o editĆ”vel." + }, + "repair": { + "title": "Reparar", + "desc": "Tentar reparar um PDF corrompido/quebrado." + }, + "removeBlanks": { + "title": "Remover PĆ”ginas em Branco", + "desc": "Detectar e remover pĆ”ginas em branco de um PDF." + }, + "removeAnnotations": { + "title": "Remover AnotaƧƵes", + "desc": "Remove todos os comentĆ”rios/anotaƧƵes de um PDF." + }, + "compare": { + "title": "Comparar", + "desc": "Comparar e mostrar as diferenƧas entre dois documentos PDF." + }, + "certSign": { + "title": "Assinar com Certificado", + "desc": "Assinar PDF com um Certificado/Chave (PEM/P12/JKS)." + }, + "removeCertSign": { + "title": "Remover Assinatura com Certificado", + "desc": "Remover assinatura com Certificado/Chave (PEM/P12/JKS) em um PDF." + }, + "pageLayout": { + "title": "Layout de MĆŗltiplas PĆ”ginas", + "desc": "Mesclar vĆ”rias pĆ”ginas de um documento PDF em uma Ćŗnica pĆ”gina." + }, + "scalePages": { + "title": "Ajustar DimensƵes da PĆ”gina", + "desc": "Alterar o tamanho/escala da pĆ”gina e/ou seu conteĆŗdo." + }, + "pipeline": { + "title": "Pipeline", + "desc": "Executar vĆ”rias aƧƵes em PDFs seguindo scripts de operaƧƵes." + }, + "add-page-numbers": { + "title": "Adicionar NĆŗmeros de PĆ”gina", + "desc": "Adicionar nĆŗmeros de pĆ”gina no documento, em um local definido." + }, + "auto-rename": { + "title": "Renomeação AutomĆ”tica do PDF", + "desc": "Renomeia automaticamente o PDF com base no cabeƧalho detectado." + }, + "adjust-contrast": { + "title": "Ajuste Visual do PDF", + "desc": "Ajustar Contraste, Saturação e Brilho de um PDF." + }, + "crop": { + "title": "Recortar", + "desc": "Recortar trecho de um PDF para reduzir o tamanho." + }, + "autoSplitPDF": { + "title": "DivisĆ£o AutomĆ”tica de PĆ”ginas", + "desc": "Dividir automaticamente um PDF digitalizado utilizando um separador de pĆ”ginas fĆ­sico com QR Code." + }, + "sanitizePdf": { + "title": "Higienizar", + "desc": "Remover scripts, links, metadados e outros elementos de um PDF." + }, + "URLToPDF": { + "title": "Converter URL/Site para PDF", + "desc": "Converter qualquer pĆ”gina da internet para um PDF." + }, + "HTMLToPDF": { + "title": "HTML para PDF", + "desc": "Converter qualquer arquivo HTML ou zip para PDF." + }, + "MarkdownToPDF": { + "title": "Markdown para PDF", + "desc": "Converte qualquer arquivo Markdown para PDF." + }, + "PDFToMarkdown": { + "title": "PDF para Markdown", + "desc": "Converte qualquer PDF para Markdown." + }, + "getPdfInfo": { + "title": "Obter InformaƧƵes de um PDF", + "desc": "ObtĆ©m informaƧƵes (metadata) de um PDF." + }, + "extractPage": { + "title": "Extrair PĆ”gina(s)", + "desc": "Extrair determinadas pĆ”ginas de um PDF." + }, + "PdfToSinglePage": { + "title": "PDF para PĆ”gina Única", + "desc": "Combina todas as pĆ”ginas de um PDF em uma Ćŗnica pĆ”gina." + }, + "showJS": { + "title": "Mostrar Javascript", + "desc": "Procura, exibe e extrai qualquer JavaScript injetado em um PDF." + }, + "autoRedact": { + "title": "Ocultação de Texto AutomĆ”tica", + "desc": "Ocultação automĆ”tica (escurecimento) de texto em um PDF com base em texto de entrada." + }, + "redact": { + "title": "Ocultação de Texto Manual", + "desc": "Ocultação de texto manual baseada em um texto selecionado, desenho de formas ou/e pĆ”ginas selecionadas." + }, + "tableExtraxt": { + "title": "PDF para CSV", + "desc": "Extração de tabelas de um PDF convertendo para CSV." + }, + "autoSizeSplitPDF": { + "title": "DivisĆ£o Manual do PDF", + "desc": "Divida um PDF em vĆ”rios, com base no tamanho, contagem de pĆ”ginas ou contagem de documentos." + }, + "overlay-pdfs": { + "title": "Sobrepor PDFs", + "desc": "SobrepƵe PDF sobre outro PDF." + }, + "split-by-sections": { + "title": "Dividir PDF por SeƧƵes", + "desc": "Divida cada pĆ”gina de um PDF em seƧƵes horizontais e/ou verticais menores." + }, + "AddStampRequest": { + "title": "Adicionar Carimbo ao PDF", + "desc": "Adicione texto ou carimbos de imagem em locais definidos." + }, + "removeImagePdf": { + "title": "Remover Imagem", + "desc": "Remova imagens do PDF para reduzir o tamanho do arquivo." + }, + "splitPdfByChapters": { + "title": "Divide PDF por CapĆ­tulos", + "desc": "Divide um PDF em vĆ”rios arquivos baseado na sua estrutura de capĆ­tulos." + }, + "validateSignature": { + "title": "Verificar Assinatura com Certificado", + "desc": "Verifica assinatura digital e certificado em um PDF." + }, + "replaceColorPdf": { + "title": "Substitui e Inverte Cores", + "desc": "Substitui cor do texto e plano de fundo de um PDF e/ou inverte a toda cor do PDF para reduzir o tamanho." + } + }, + "viewPdf": { + "tags": "visualizar,ler,anotar,texto,imagem", + "title": "Ver/Editar PDF", + "header": "Visualizar PDF" + }, + "multiTool": { + "tags": "Multiferramentas,mĆŗltiplas operaƧƵes,Interface do UsuĆ”rio,Clique e arraste,front-end,lado do cliente,interativo,intratĆ”vel,movimento,excluir,migrar,dividir", + "title": "Multiferramentas de PDF", + "header": "Multiferramentas de PDF", + "uploadPrompts": "Nome do Arquivo:", + "selectAll": "Selecionar Tudo", + "deselectAll": "Desselecionar Tudo", + "selectPages": "Selecionar PĆ”ginas", + "selectedPages": "PĆ”ginas Selecionadas", + "page": "PĆ”gina", + "deleteSelected": "Apagar Selecionados", + "downloadAll": "Exportar", + "downloadSelected": "Exportar Selecionados", + "insertPageBreak": "Inserir PĆ”gina em Branco", + "addFile": "Inserir Arquivo", + "rotateLeft": "Girar para Esquerda", + "rotateRight": "Girar para Direita", + "split": "Dividir", + "moveLeft": "Mover para Esquerda", + "moveRight": "Mover para Direita", + "delete": "Apagar", + "dragDropMessage": "PĆ”gina(s) Selecionadas", + "undo": "Desfazer", + "redo": "Refazer" + }, + "merge": { + "tags": "mesclar,OperaƧƵes de PĆ”gina,Back-end,lado do servidor", + "title": "Mesclar", + "header": "Mesclar", + "sortByName": "Classificar por Nome", + "sortByDate": "Classificar por Data", + "removeCertSign": "Remover a assinatura digital do arquivo mesclado?", + "submit": "Mesclar" + }, + "split": { + "tags": "OperaƧƵes de PĆ”gina,dividir,MĆŗltiplas PĆ”ginas,cortar,lado do servidor", + "title": "Dividir", + "header": "Dividir", + "desc": { + "1": "Os nĆŗmeros selecionados correspondem Ć s pĆ”ginas onde vocĆŖ deseja realizar a divisĆ£o.", + "2": "Por exemplo, selecionar 1,3,7-9 dividirĆ” um documento de 11 pĆ”ginas em 6 PDFs separados, da seguinte forma:", + "3": "Documento NĀŗ1: PĆ”gina 1", + "4": "Documento NĀŗ2: PĆ”ginas 2 e 3", + "5": "Documento NĀŗ3: PĆ”ginas 4, 5, 6 e 7", + "6": "Documento NĀŗ4: PĆ”gina 8", + "7": "Documento NĀŗ5: PĆ”gina 9", + "8": "Documento NĀŗ6: PĆ”gina 10 e 11 (e mais se tiver)" + }, + "splitPages": "Digite as pĆ”ginas para a divisĆ£o:", + "submit": "Dividir" + }, + "rotate": { + "tags": "Lado do servidor", + "title": "Girar", + "header": "Girar", + "selectAngle": "Selecione o Ć¢ngulo de rotação (mĆŗltiplos de 90 graus):", + "submit": "Girar" + }, + "imageToPdf": { + "tags": "conversĆ£o,img,jpg,imagem,foto" + }, + "pdfToImage": { + "tags": "conversĆ£o,img,jpg,imagem,foto", + "title": "PDF para Imagem", + "header": "PDF para Imagem", + "selectText": "Formato da imagem:", + "singleOrMultiple": "Resultado da conversĆ£o:", + "single": "Imagem grande Ćŗnica combinando todas as pĆ”ginas do PDF", + "multi": "VĆ”rias imagens, uma imagem por pĆ”gina do PDF", + "colorType": "Cor de saĆ­da:", + "color": "Colorido", + "grey": "Escala de Cinza", + "blackwhite": "Preto e Branco (pode perder informaƧƵes!)", + "submit": "Converter", + "info": "Python nĆ£o estĆ” instalado. NecessĆ”rio para conversĆ£o WebP.", + "placeholder": "(por exemplo 1,2,8 ou 4,7,12-16 ou 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,par,Ć­mpar,ordenar,mover", + "title": "Organizar PĆ”ginas", + "header": "Organizar PĆ”ginas", + "submit": "Reorganizar PĆ”ginas", + "mode": { + "_value": "Modo:", + "1": "Ordem de pĆ”gina personalizada", + "2": "Ordem inversa", + "3": "Classificação duplex", + "4": "Classificação de livreto", + "5": "Classificação de livreto com ponto lateral", + "6": "DivisĆ£o Ć­mpar-par", + "7": "Remover primeiro", + "8": "Remover Ćŗltimo", + "9": "Remover o primeiro e o Ćŗltimo", + "10": "Mesclagem Ć­mpar-par", + "11": "Duplicar todas as pĆ”ginas" + }, + "placeholder": "(por exemplo 1,3,2 ou 4-8,2,10-12 ou 2n-1)" + }, + "addImage": { + "tags": "img,jpg,imagem,foto", + "title": "Adicionar Imagem", + "header": "Adicionar Imagem", + "everyPage": "Para cada pĆ”gina?", + "upload": "Carregar imagem", + "submit": "Adicionar imagem" + }, + "watermark": { + "tags": "Texto,repetindo,rótulo,próprio,direitos autorais,marca registrada,img,jpg,imagem,foto", + "title": "Adicionar marca d'Ć”gua", + "header": "Adicionar marca d'Ć”gua", + "customColor": "Cor de texto personalizada", + "selectText": { + "1": "Selecione PDF para adicionar a marca d'Ć”gua:", + "2": "Texto da marca d'Ć”gua:", + "3": "Tamanho da fonte:", + "4": "Rotação (0-360):", + "5": "EspaƧador de Largura (EspaƧo entre cada marca d'Ć”gua horizontalmente):", + "6": "EspaƧador de Altura (EspaƧo entre cada marca d'Ć”gua verticalmente):", + "7": "Opacidade (0% - 100%):", + "8": "Tipo de marca d'Ć”gua:", + "9": "Imagem da marca d'Ć”gua:", + "10": "Converter PDF em imagem PDF." + }, + "submit": "Adicionar Marca D'Ć”gua", + "type": { + "1": "Texto", + "2": "Imagem" + } + }, + "permissions": { + "tags": "leitura,escrita,edição,impressĆ£o", + "title": "Alterar PermissƵes", + "header": "Alterar PermissƵes", + "warning": "Aviso: para que essas permissƵes sejam imutĆ”veis, Ć© recomendĆ”vel defini-las com uma senha atravĆ©s da pĆ”gina \"Proteger PDF\".", + "selectText": { + "1": "Selecione o PDF para alterar as permissƵes:", + "2": "PermissƵes para definir:", + "3": "Impedir montagem do documento.", + "4": "Impedir extração de conteĆŗdo.", + "5": "Impedir extração para acessibilidade.", + "6": "Impedir preenchimento de formulĆ”rio.", + "7": "Impedir modificaƧƵes.", + "8": "Impedir modificação de anotaƧƵes.", + "9": "Impedir impressĆ£o.", + "10": "Impedir impressĆ£o de formatos diferentes." + }, + "submit": "Alterar" + }, + "removePages": { + "tags": "Remover pĆ”ginas,excluir pĆ”ginas" + }, + "addPassword": { + "tags": "seguro,seguranƧa", + "title": "Proteger PDF", + "header": "Proteger PDF (Criptografar)", + "selectText": { + "1": "Selecione o PDF para Criptografar:", + "2": "Senha de acesso:", + "3": "Tamanho da chave de criptografia:", + "4": "Valores mais altos sĆ£o mais seguros, mas valores mais baixos sĆ£o melhores para compatibilidade.", + "5": "PermissƵes a serem definidas (recomendado para uso junto com a senha do proprietĆ”rio):", + "6": "Impedir a montagem do documento.", + "7": "Impedir a extração de conteĆŗdo.", + "8": "Impedir a extração para acessibilidade.", + "9": "Impedir o preenchimento do formulĆ”rio.", + "10": "Impedir modificação.", + "11": "Impedir modificação de anotaƧƵes.", + "12": "Impedir impressĆ£o.", + "13": "Impedir impressĆ£o de formatos diferentes.", + "14": "Senha do proprietĆ”rio:", + "15": "Restringe o que pode ser feito com o documento depois de aberto (nĆ£o suportado por todos os leitores).", + "16": "Restringe a abertura do próprio documento." + }, + "submit": "Criptografar" + }, + "removePassword": { + "tags": "seguro, descriptografar, seguranƧa, remover senha", + "title": "Desproteger PDF", + "header": "Desproteger PDF (descriptografar)", + "selectText": { + "1": "Selecione o PDF para descriptografar:", + "2": "Senha" + }, + "submit": "Descriptografar" + }, + "compressPdfs": { + "tags": "compactar,pequeno,mĆ­nimo" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "TĆ­tulo,autor,data,criação,hora,editor,produtor,estatĆ­sticas", + "title": "Alterar Metadados", + "header": "Alterar Metadados", + "selectText": { + "1": "Edite as variĆ”veis ​​que deseja alterar.", + "2": "Excluir todos os metadados.", + "3": "Mostrar metadados personalizados.", + "4": "Outros metadados:", + "5": "Adicionar Entrada de Metadados Personalizada" + }, + "author": "Autor:", + "creationDate": "Data de criação (aaaa/mm/dd HH:mm:ss):", + "creator": "Criador:", + "keywords": "Palavras-chave:", + "modDate": "Data de modificação (aaaa/mm/dd HH:mm:ss):", + "producer": "Produtor:", + "subject": "Assunto:", + "trapped": "Metadados trapping:", + "submit": "Alterar" + }, + "fileToPDF": { + "tags": "transformação,formato,documento,imagem,slide,texto,conversĆ£o,escritório,documentos,word,excel,powerpoint", + "title": "Converter Arquivo para PDF", + "header": "Converter Arquivo para PDF", + "credit": "Este serviƧo usa o LibreOffice e o Unoconv realizar a conversĆ£o de arquivos.", + "supportedFileTypesInfo": "Tipos de Arquivos Suportados", + "supportedFileTypes": "A listagem abaixo nĆ£o Ć© exaustiva, para obter uma lista atualizada completa dos formatos suportados, consulte a documentação do LibreOffice.", + "submit": "Converter para PDF" + }, + "ocr": { + "tags": "reconhecimento,texto,imagem,digitalização,leitura,identificação,detecção,editĆ”vel", + "title": "Processamento de OCR", + "header": "Processamento de OCR (Reconhecimento Ɠptico de Caracteres)", + "selectText": { + "1": "Selecione os idiomas a serem detectados no PDF (os listados sĆ£o os atualmente instalados):", + "2": "Criar um arquivo de texto contendo o texto OCR junto do PDF com OCR", + "3": "PĆ”ginas corretamente digitalizadas em um Ć¢ngulo inclinado, gire-as de volta Ć  posição original", + "4": "Limpar a pĆ”gina para reduzir a probabilidade de o OCR encontrar texto no ruĆ­do de fundo (sem alteração na saĆ­da)", + "5": "Limpar a pĆ”gina para reduzir a probabilidade de o OCR encontrar texto no ruĆ­do de fundo, mantendo a limpeza na saĆ­da.", + "6": "Ignorar pĆ”ginas com texto interativo, processar por OCR apenas as pĆ”ginas com imagens", + "7": "ForƧar OCR, executar OCR em todas as pĆ”ginas, removendo todos os elementos de texto originais", + "8": "Normal (gerarĆ” um erro se o PDF jĆ” contiver texto)", + "9": "ConfiguraƧƵes Adicionais", + "10": "Modo OCR:", + "11": "Remover imagens após o OCR (remove TODAS as imagens, Ćŗtil apenas como parte do processo de conversĆ£o)", + "12": "Tipo de renderização (AvanƧado):" + }, + "help": "Por favor, leia a documentação abaixo para saber mais sobre OCR e sua utilização.", + "credit": "Este serviƧo usa Qpdf e Tesseract para OCR.", + "submit": "Processar OCR no PDF" + }, + "extractImages": { + "tags": "imagem,foto,salvar,arquivo,zip,captura,coleta", + "title": "Extrair Imagens", + "header": "Extrair Imagens", + "selectText": "Selecione o formato de saĆ­da das imagens extraĆ­das:", + "allowDuplicates": "Salvar imagens duplicadas.", + "submit": "Extrair" + }, + "pdfToPDFA": { + "tags": "arquivo,longo prazo,padrĆ£o,conversĆ£o,armazenamento,preservação", + "title": "PDF para PDF/A", + "header": "PDF para PDF/A", + "credit": "Este serviƧo usa o LibreOffice para conversĆ£o para PDF/A.", + "submit": "Converter", + "tip": "Atenção, atualmente nĆ£o funciona para mĆŗltiplas entradas ao mesmo tempo.", + "outputFormat": "Formato de saĆ­da:", + "pdfWithDigitalSignature": "O PDF contĆ©m uma assinatura digital. Isso serĆ” removido na próxima etapa." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformação,formato,conversĆ£o,escritório,microsoft,doc", + "title": "PDF para Word", + "header": "PDF para Word", + "selectText": { + "1": "Formato do arquivo de saĆ­da:" + }, + "credit": "Este serviƧo usa o LibreOffice para conversĆ£o de arquivos.", + "submit": "Converter" + }, + "PDFToPresentation": { + "tags": "slides,apresentação,escritório,microsoft", + "title": "PDF para Apresentação", + "header": "PDF para Apresentação", + "selectText": { + "1": "Formato do arquivo de saĆ­da:" + }, + "credit": "Este serviƧo usa o LibreOffice para conversĆ£o de arquivos.", + "submit": "Converter" + }, + "PDFToText": { + "tags": "formato rich,formato richtext,formato rich text", + "title": "PDF para TXT/RTF", + "header": "PDF para TXT/RTF", + "selectText": { + "1": "Formato do arquivo de saĆ­da:" + }, + "credit": "Este serviƧo usa o LibreOffice para conversĆ£o de arquivos.", + "submit": "Converter" + }, + "PDFToHTML": { + "tags": "conteĆŗdo web,compatĆ­vel com navegador", + "title": "PDF para HTML", + "header": "PDF para HTML", + "credit": "Este serviƧo usa o pdftohtml para conversĆ£o de arquivos.", + "submit": "Converter" + }, + "PDFToXML": { + "tags": "extração-de-dados,conteĆŗdo-estruturado,interoperabilidade,transformação,converter", + "title": "PDF para XML", + "header": "PDF para XML", + "credit": "Este serviƧo usa o LibreOffice para conversĆ£o de arquivos.", + "submit": "Converter" + }, + "ScannerImageSplit": { + "tags": "separar,detecção-automĆ”tica,digitalizaƧƵes,fotos-mĆŗltiplas,organizar", + "selectText": { + "1": "Limite de Ć¢ngulo:", + "2": "Define o Ć¢ngulo absoluto mĆ­nimo necessĆ”rio para que a imagem seja girada (padrĆ£o: 10).", + "3": "TolerĆ¢ncia:", + "4": "Determina o intervalo de variação de cor em torno da cor de fundo estimada (padrĆ£o: 30).", + "5": "Ɓrea mĆ­nima:", + "6": "Define o limite mĆ­nimo de Ć”rea para uma foto (padrĆ£o: 10000).", + "7": "Ɓrea mĆ­nima de contorno:", + "8": "Define o limite mĆ­nimo da Ć”rea de contorno para uma foto.", + "9": "Tamanho da borda:", + "10": "Define o tamanho da borda adicionada e removida para evitar bordas brancas na saĆ­da (padrĆ£o: 1)." + }, + "info": "Python nĆ£o estĆ” instalado. Ɖ necessĆ”rio para executar." + }, + "sign": { + "tags": "autorizar,iniciais,assinatura-desenhada,assinatura-de-texto,assinatura-de-imagem", + "title": "Assinar", + "header": "Assinar", + "upload": "Carregar Imagem", + "draw": "Desenhar Assinatura", + "text": "Inserir Texto", + "clear": "Limpar", + "add": "Adicionar", + "saved": "Assinaturas Salvas", + "save": "Salvar Assinatura", + "personalSigs": "Assinaturas Pessoais", + "sharedSigs": "Assinaturas Compartilhadas", + "noSavedSigs": "Nenhuma assinatura salva encontrada.", + "addToAll": "Adicionar em todas pĆ”ginas", + "delete": "Apagar", + "first": "Primeira pĆ”gina", + "last": "Última pĆ”gina", + "next": "Próxima pĆ”gina", + "previous": "PĆ”gina anterior", + "maintainRatio": "Habilitar manter proporção", + "undo": "Desfazer", + "redo": "Refazer" + }, + "flatten": { + "tags": "estĆ”tico,desativar,nĆ£o-interativo,otimizar", + "title": "Achatar", + "header": "Achatar", + "flattenOnlyForms": "Achatar apenas formulĆ”rios interativos.", + "submit": "Achatar" + }, + "repair": { + "tags": "corrigir,restaurar,correção,recuperar", + "title": "Reparar", + "header": "Reparar", + "submit": "Reparar" + }, + "removeBlanks": { + "tags": "limpeza,otimização,sem-conteĆŗdo,organizar", + "title": "Remover PĆ”ginas em Branco", + "header": "Remover PĆ”ginas em Branco", + "threshold": "Limite de brancura de pixel:", + "thresholdDesc": "Limite para determinar o quĆ£o branco um pixel branco deve ser para ser classificado como \"branco\", para remoção. 0 = Preto, 255 = branco puro.", + "whitePercent": "Porcentagem de branco (%):", + "whitePercentDesc": "Porcentagem da pĆ”gina que devem ter pixels classificados como ā€œbrancosā€ para serem removidas.", + "submit": "Remover PĆ”ginas em Branco" + }, + "removeAnnotations": { + "tags": "comentĆ”rios,destaque,notas,marcação,remover", + "title": "Remover AnotaƧƵes", + "header": "Remover AnotaƧƵes", + "submit": "Remover" + }, + "compare": { + "tags": "diferenciar,contraste,mudanƧas,anĆ”lise", + "title": "Comparar", + "header": "Comparar", + "highlightColor": { + "1": "Cor de destaque 1:", + "2": "Cor de destaque 2:" + }, + "document": { + "1": "Documento 1:", + "2": "Documento 2:" + }, + "submit": "Comparar", + "complex": { + "message": "Um ou ambos os documentos fornecidos sĆ£o arquivos grandes, a precisĆ£o da comparação pode ser reduzida." + }, + "large": { + "file": { + "message": "Um ou ambos os documentos fornecidos sĆ£o muito grandes para processar." + } + }, + "no": { + "text": { + "message": "Um ou ambos os PDFs selecionados nĆ£o possuem conteĆŗdo de texto. Por favor, escolha PDFs com texto para comparação." + } + } + }, + "certSign": { + "tags": "autenticar,PEM,P12,oficial,criptografar", + "title": "Assinatura com Certificado", + "header": "Assinatura com Certificado (Em desenvolvimento)", + "selectPDF": "Selecione um arquivo PDF para assinatura:", + "jksNote": "Nota: Se o seu tipo de certificado nĆ£o estiver listado abaixo, converta-o em um arquivo Java Keystore (.jks) usando a ferramenta de linha de comando keytool. Em seguida, escolha a opção de arquivo .jks abaixo.", + "selectKey": "Selecione o seu arquivo de chave privada (formato PKCS#8, pode ser .pem ou .der):", + "selectCert": "Selecione o seu arquivo de certificado (formato X.509, pode ser .pem ou .der):", + "selectP12": "Selecione o seu arquivo de armazenamento de chave PKCS#12 (.p12 ou .pfx) (opcional, se fornecido, deve conter a sua chave privada e certificado):", + "selectJKS": "Selecione seu arquivo Java Keystore (.jks ou .keystore):", + "certType": "Tipo de Certificado:", + "password": "Digite a senha do seu armazenamento de chave ou chave privada (se aplicĆ”vel):", + "showSig": "Mostrar Assinatura.", + "reason": "RazĆ£o", + "location": "Localização", + "name": "Nome", + "showLogo": "Mostrar Logotipo", + "submit": "Assinar PDF" + }, + "removeCertSign": { + "tags": "autenticar,PEM,P12,oficial,descriptografar", + "title": "Remover Assinatura com Certificado", + "header": "Remover Assinatura com Certificado", + "selectPDF": "Selecione um arquivo PDF:", + "submit": "Remover Assinatura" + }, + "pageLayout": { + "tags": "mesclar,composto,vista-Ćŗnica,organizar", + "title": "Layout de MĆŗltiplas PĆ”ginas", + "header": "Layout de MĆŗltiplas PĆ”ginas", + "pagesPerSheet": "PĆ”ginas por folha:", + "addBorder": "Adicionar bordas.", + "submit": "Enviar" + }, + "scalePages": { + "tags": "redimensionar,modificar,dimensĆ£o,adaptar", + "title": "Ajustar DimensƵes da PĆ”gina", + "header": "Ajustar DimensƵes da PĆ”gina", + "pageSize": "Tamanho desejado do documento:", + "keepPageSize": "Tamanho Original", + "scaleFactor": "Fator de zoom (corte) de uma pĆ”gina:", + "submit": "Enviar" + }, + "add-page-numbers": { + "tags": "paginar,rotular,organizar,Ć­ndice" + }, + "auto-rename": { + "tags": "detecção-automĆ”tica,baseado-em-cabeƧalho,organizar,relabel", + "title": "Renomeação AutomĆ”tica do PDF", + "header": "Renomeação AutomĆ”tica do PDF", + "submit": "Renomeação AutomĆ”tica" + }, + "adjust-contrast": { + "tags": "correção-de-cor,ajustar,modificar,realƧar" + }, + "crop": { + "tags": "aparar,encolher,editar,formato", + "title": "Recortar", + "header": "Recortar", + "submit": "Enviar" + }, + "autoSplitPDF": { + "tags": "baseado-em-QR,separar,segmento-de-digitalização,organizar", + "title": "DivisĆ£o AutomĆ”tica de PĆ”ginas", + "header": "DivisĆ£o AutomĆ”tica de PĆ”ginas", + "description": "Imprima, insira, digitalize, faƧa o upload e deixe que a gente divida seus documentos automaticamente.", + "selectText": { + "1": "Imprima algumas folhas divisórias, descritas abaixo (preto e branco ou colorido).", + "2": "Digitalize todos os seus documentos de uma vez, inserindo a folha divisória enre os documentos que deseja separar.", + "3": "FaƧa o upload do arquivo Ćŗnico PDF digitalizado e deixe o Stirling PDF cuidar do resto.", + "4": "As pĆ”ginas divisórias sĆ£o detectadas e removidas automaticamente, garantindo um documento final organizado." + }, + "formPrompt": "Enviar PDF contendo folhas divisórias Stirling-PDF:", + "duplexMode": "Modo Duplex (Digitalização frente e verso).", + "dividerDownload2": "Baixar 'Folha Divisória AutomĆ”tica (com instruƧƵes).pdf'", + "submit": "Enviar" + }, + "sanitizePdf": { + "tags": "limpar,seguro,protegido,remover-ameaƧas" + }, + "URLToPDF": { + "tags": "captura-de-web,salvar-pĆ”gina,web-para-doc,arquivar", + "title": "Converter URL/Site para PDF", + "header": "Converter URL/Site para PDF", + "submit": "Converter", + "credit": "Utiliza o WeasyPrint." + }, + "HTMLToPDF": { + "tags": "marcação,conteĆŗdo-web,transformação,converter", + "title": "HTML para PDF", + "header": "HTML para PDF", + "help": "Aceita arquivos HTML e ZIPs contendo html, css, imagens, etc.", + "submit": "Converter", + "credit": "Utiliza o WeasyPrint.", + "zoom": "NĆ­vel de zoom para exibição do site:", + "pageWidth": "Largura da pĆ”gina em centĆ­metros. (Em branco para padrĆ£o)", + "pageHeight": "Altura da pĆ”gina em centĆ­metros. (Em branco para padrĆ£o)", + "marginTop": "Margem superior da pĆ”gina em milĆ­metros. (Em branco para padrĆ£o)", + "marginBottom": "Margem inferior da pĆ”gina em milĆ­metros. (Em branco para padrĆ£o)", + "marginLeft": "Margem esquerda da pĆ”gina em milĆ­metros. (Em branco para padrĆ£o)", + "marginRight": "Margem direita da pĆ”gina em milĆ­metros. (Em branco para padrĆ£o)", + "printBackground": "Renderize o plano de fundo dos sites.", + "defaultHeader": "Habilitar cabeƧalho padrĆ£o (nome e nĆŗmero da pĆ”gina)", + "cssMediaType": "Altere o tipo de mĆ­dia CSS da pĆ”gina.", + "none": "Nenhum", + "print": "Imprimir", + "screen": "Tela" + }, + "MarkdownToPDF": { + "tags": "marcação,conteĆŗdo-web,transformação,converter", + "title": "Markdown para PDF", + "header": "Markdown para PDF", + "submit": "Converter", + "help": "Em desenvolvimento.", + "credit": "Utiliza o WeasyPrint." + }, + "PDFToMarkdown": { + "tags": "marcação,conteĆŗdo-web,transformação,converter,md", + "title": "PDF para Markdown", + "header": "PDF para Markdown", + "submit": "Converter" + }, + "getPdfInfo": { + "tags": "informaƧƵes,dados,estatĆ­sticas", + "title": "Obter InformaƧƵes do PDF", + "header": "Obter InformaƧƵes do PDF", + "submit": "Obter InformaƧƵes", + "downloadJson": "Baixar JSON" + }, + "extractPage": { + "tags": "extrair" + }, + "PdfToSinglePage": { + "tags": "pĆ”gina Ćŗnica" + }, + "showJS": { + "tags": "JavaScript", + "title": "Mostrar JavaScript", + "header": "Mostrar JavaScript", + "downloadJS": "Baixar JavaScript", + "submit": "Mostrar" + }, + "autoRedact": { + "tags": "Redigir,ocultar,escurecer,preto,marcador,oculto", + "title": "Ocultação de Texto AutomĆ”tica", + "header": "Ocultação de Texto AutomĆ”tica", + "colorLabel": "Cor:", + "textsToRedactLabel": "Texto para ocultar (um por linha):", + "textsToRedactPlaceholder": "Por exemplo: \\nConfidencial \\nSecreto", + "useRegexLabel": "Usar Regex (expressĆ£o regular).", + "wholeWordSearchLabel": "Pesquisa apenas palavras inteiras.", + "customPaddingLabel": "Preenchimento extra personalizado:", + "convertPDFToImageLabel": "Converter PDF em imagem PDF (Usado para remover o texto atrĆ”s da caixa).", + "submitButton": "Ocultar" + }, + "redact": { + "tags": "Redigir,ocultar,escurecer,preto,marcador,oculto,manual", + "title": "Ocultação de Texto Manual", + "header": "Ocultação de Texto Manual", + "submit": "Ocultar", + "textBasedRedaction": "Ocultação baseada em texto", + "pageBasedRedaction": "Ocultação baseada em pĆ”ginas", + "convertPDFToImageLabel": "Converter PDF para PDF-Imagem (Utilizado para remover texto atrĆ”s da seleção)", + "pageRedactionNumbers": { + "title": "PĆ”ginas", + "placeholder": "(p.ex. 1,2,8 ou 4,7,12-16 ou 2n-1)" + }, + "redactionColor": { + "title": "Cor da Ocultação" + }, + "export": "Exportar", + "upload": "Carregar", + "boxRedaction": "Ocultação baseada em formas", + "zoom": "Zoom", + "zoomIn": "Ampliar", + "zoomOut": "Reduzir", + "nextPage": "Proxima PĆ”gina", + "previousPage": "PĆ”gina Anterior", + "toggleSidebar": "Mostrar/Ocultar Barra Lateral", + "showThumbnails": "Mostrar Miniaturas", + "showDocumentOutline": "Mostrar Estrutura do Documento (duplo clique para expandir/recolher todos os itens)", + "showAttatchments": "Mostrar Anexos", + "showLayers": "Mostrar Camadas (duplo clique para restabelecer as camadas para o estado padrĆ£o)", + "colourPicker": "Seletor de Cores", + "findCurrentOutlineItem": "Encontrar item atual", + "applyChanges": "Aplicar AlteraƧƵes" + }, + "tableExtraxt": { + "tags": "CSV,extração de tabela,extrair,converter" + }, + "autoSizeSplitPDF": { + "tags": "pdf,divisĆ£o,documento,organização" + }, + "overlay-pdfs": { + "tags": "Sobreposição", + "header": "Sobrepor PDFs", + "baseFile": { + "label": "Selecione o arquivo PDF base:" + }, + "overlayFiles": { + "label": "Selecione os arquivos PDF para sobreposição:" + }, + "mode": { + "label": "Selecione o modo de sobreposição:", + "sequential": "Sobreposição sequencial", + "interleaved": "Sobreposição intercalada", + "fixedRepeat": "Sobreposição de repetição fixa" + }, + "counts": { + "label": "Contagens de sobreposição (para modo de repetição fixa)", + "placeholder": "Insira contagens separadas por vĆ­rgula (por exemplo, 2,3,1)" + }, + "position": { + "label": "Selecione a posição de sobreposição", + "foreground": "Primeiro plano", + "background": "Plano de fundo" + }, + "submit": "Enviar" + }, + "split-by-sections": { + "tags": "Seção Dividir, Dividir, Personalizar", + "title": "Dividir PDF por SeƧƵes", + "header": "Dividir PDF por SeƧƵes", + "horizontal": { + "label": "DivisƵes Horizontais:", + "placeholder": "Insira o nĆŗmero de divisƵes horizontais" + }, + "vertical": { + "label": "DivisƵes Verticais:", + "placeholder": "Insira o nĆŗmero de divisƵes verticais" + }, + "submit": "Dividir", + "merge": "Mesclar em um PDF." + }, + "AddStampRequest": { + "tags": "Carimbo,Adicionar imagem,centralizar imagem,Marca d'Ć”gua,PDF,Incorporar,Personalizar", + "header": "Adicionar Carimbo ao PDF", + "title": "Adicionar Carimbo ao PDF", + "stampType": "Tipo de carimbo:", + "stampText": "Texto do carimbo:", + "stampImage": "Imagem do carimbo:", + "alphabet": "Alfabeto:", + "fontSize": "Tamanho da fonte/imagem:", + "rotation": "Rotação:", + "opacity": "Opacidade:", + "position": "Posição:", + "overrideX": "Substituir coordenada X:", + "overrideY": "Substituir coordenada Y:", + "customMargin": "Margem personalizada:", + "customColor": "Cor de texto personalizada:", + "submit": "Enviar" + }, + "removeImagePdf": { + "tags": "Remover imagem,operaƧƵes de pĆ”gina,back-end,lado do servidor" + }, + "splitPdfByChapters": { + "tags": "dividir,capĆ­tulos,favoritos,organizar" + }, + "validateSignature": { + "tags": "assinatura,verificação,validação,pdf,certificado,assinatura digital,validar assinatura,validar certificado", + "title": "Verificar Assinatura com Certificado", + "header": "Verificar Assinatura com Certificado", + "selectPDF": "Selecione PDF com assinatura por certificado:", + "submit": "Verificar Assinatura", + "results": "Resultados da Verificação", + "status": { + "_value": "Situação", + "valid": "Valido", + "invalid": "InvĆ”lido" + }, + "signer": "SignatĆ”rio", + "date": "Data", + "reason": "Motivo", + "location": "Localização", + "noSignatures": "Nenhuma assinatura digital encontrada no documento.", + "chain": { + "invalid": "Falha na validação da cadeia de certificados - nĆ£o Ć© possĆ­vel verificar a identidade do signatĆ”rio" + }, + "trust": { + "invalid": "Certificado nĆ£o estĆ” presente no repositório de confianƧa, a fonte nĆ£o pode ser verificada" + }, + "cert": { + "expired": "Certificate expirou", + "revoked": "Certificado foi revogado", + "info": "Detalhes do certificado", + "issuer": "Emissor", + "subject": "Assunto", + "serialNumber": "NĆŗmero de serial", + "validFrom": "Valido de", + "validUntil": "Valido atĆ©", + "algorithm": "Algoritmo", + "keySize": "Tamanho da chave", + "version": "VersĆ£o", + "keyUsage": "Uso da chave", + "selfSigned": "Autoassinados", + "bits": "bits" + }, + "signature": { + "info": "InformaƧƵes da assinatura", + "_value": "Assinatura", + "mathValid": "Assinatura Ć© matematicamente valida PORƉM:" + }, + "selectCustomCert": "Arquivo customizado de certificado X.509 (Opcional)" + }, + "replace-color": { + "title": "Substitui e Inverte Cores", + "header": "Substitui e Inverte Cores", + "selectText": { + "1": "Substituir ou inverter cores OpƧƵes:", + "2": "PadrĆ£o (Cores de alto constraste)", + "3": "Customizado (Cores customizadas)", + "4": "InversĆ£o Completa (Inverte todas cores)", + "5": "OpƧƵes de cores de alto contraste:", + "6": "Texto branco em um plano de fundo preto", + "7": "Texto preto em um plano de fundo branco", + "8": "Texto amarelo em um plano de fundo preto", + "9": "Texto verde em um plano de fundo preto", + "10": "Escolha a cor do texto:", + "11": "Escolha a cor do plano de fundo:" + }, + "submit": "Substituir" + }, + "replaceColorPdf": { + "tags": "Substitui Cor, OperaƧƵes na PĆ”gina, back end, lado do servidor" + }, + "login": { + "title": "Iniciar sessĆ£o", + "header": "Iniciar sessĆ£o", + "signin": "Iniciar sessĆ£o", + "rememberme": "Lembrar de mim", + "invalid": "UsuĆ”rio ou senha invĆ”lidos.", + "locked": "Sua conta foi bloqueada.", + "signinTitle": "Por favor, inicie a sessĆ£o", + "ssoSignIn": "Iniciar sessĆ£o atravĆ©s de login Ćŗnico (SSO)", + "oAuth2AutoCreateDisabled": "Auto-Criar UsuĆ”rio OAUTH2 Desativado", + "oAuth2AdminBlockedUser": "O registro ou login de usuĆ”rios nĆ£o registrados estĆ” atualmente bloqueado. Entre em contato com o administrador.", + "oauth2RequestNotFound": "Solicitação de autorização nĆ£o encontrada", + "oauth2InvalidUserInfoResponse": "Resposta de informação de usuĆ”rio invĆ”lida", + "oauth2invalidRequest": "Requisição InvĆ”lida", + "oauth2AccessDenied": "Acesso Negado", + "oauth2InvalidTokenResponse": "Resposta de Token InvĆ”lida", + "oauth2InvalidIdToken": "Id de Token InvĆ”lido", + "relyingPartyRegistrationNotFound": "Nenhum registro de parte confiĆ”vel (RP) encontrado", + "userIsDisabled": "O usuĆ”rio estĆ” desativado, o login estĆ” atualmente bloqueado com este nome de usuĆ”rio. Entre em contato com o administrador.", + "alreadyLoggedIn": "VocĆŖ jĆ” estĆ” conectado em", + "alreadyLoggedIn2": "aparelhos. Por favor saia dos aparelhos e tente novamente.", + "toManySessions": "VocĆŖ tem muitas sessƵes ativas", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF para PĆ”gina Única", + "header": "PDF para PĆ”gina Única", + "submit": "Converter para PĆ”gina Única" + }, + "pageExtracter": { + "title": "Extrair PĆ”gina(s)", + "header": "Extrair PĆ”ginas(s)", + "submit": "Extrair", + "placeholder": "(por exemplo 1,2,8 or 4,7,12-16 ou 2n-1)" + }, + "sanitizePDF": { + "title": "Higienizar", + "header": "Higienizar", + "selectText": { + "1": "Remover scripts de JavaScript.", + "2": "Remover arquivos embutidos.", + "3": "Remover metadados XMP.", + "4": "Remover links.", + "5": "Remover fontes.", + "6": "Remover metadados de informaƧƵes do documento." + }, + "submit": "Higienizar PDF" + }, + "adjustContrast": { + "title": "Ajuste Visual do PDF", + "header": "Ajuste Visual do PDF", + "contrast": "Contraste:", + "brightness": "Brilho:", + "saturation": "Saturação:", + "download": "Baixar" + }, + "compress": { + "title": "Comprimir", + "header": "Comprimir", + "credit": "Este serviƧo usa o Qpdf para compressĆ£o/otimização de PDF.", + "grayscale": { + "label": "Aplicar escala de cinza para compressĆ£o" + }, + "selectText": { + "1": { + "_value": "ConfiguraƧƵes de CompressĆ£o:", + "1": "1-3: CompressĆ£o do PDF,
4-6: Compressão leve de Imagem,
7-9: CompressĆ£o alta de Imagem. Redução considerĆ”vel de qualidade da imagem." + }, + "2": "NĆ­vel de Otimização:", + "4": "Modo AutomĆ”tico - Ajusta automaticamente a qualidade para atingir o tamanho exato desejado", + "5": "Tamanho esperado do PDF (por exemplo, 25 MB, 10,8 MB, 25 KB):" + }, + "submit": "Comprimir" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "Esta função tambĆ©m estĆ” disponĆ­vel em Multiferramentas de PDF. Com uma interface mais completa e funƧƵes adicionais." + }, + "pageRemover": { + "title": "Remover PĆ”ginas", + "header": "Remover PĆ”ginas", + "pagesToDelete": "PĆ”ginas a serem excluĆ­das (insira uma lista separada por vĆ­rgulas, com os nĆŗmeros de pĆ”ginas):", + "submit": "Excluir PĆ”ginas", + "placeholder": "(por exemplo 1,2,6 ou 1-10,15-30)" + }, + "imageToPDF": { + "title": "Imagem para PDF", + "header": "Imagem para PDF", + "submit": "Converter", + "selectLabel": "OpƧƵes de ajuste da imagem:", + "fillPage": "Preencher a pĆ”gina", + "fitDocumentToImage": "Ajustar pĆ”gina Ć  imagem", + "maintainAspectRatio": "Manter proporƧƵes", + "selectText": { + "2": "Girar automaticamente.", + "3": "Lógica de vĆ”rios arquivos (Ativada apenas ao trabalhar com vĆ”rias imagens):", + "4": "Mesclar em um Ćŗnico PDF", + "5": "Converter em PDFs separados" + } + }, + "PDFToCSV": { + "title": "PDF para CSV", + "header": "PDF para CSV", + "prompt": "Escolha a pĆ”gina para extração da tabela:", + "submit": "Extrair" + }, + "split-by-size-or-count": { + "title": "DivisĆ£o Manual do PDF", + "header": "DivisĆ£o Manual do PDF", + "type": { + "label": "Selecione o tipo de divisĆ£o:", + "size": "Por tamanho", + "pageCount": "Por contagem de pĆ”ginas", + "docCount": "Por contagem de documentos" + }, + "value": { + "label": "Insira o valor:", + "placeholder": "Insira o tamanho (por exemplo, 2 MB ou 3 KB) ou a contagem (por exemplo, 5)" + }, + "submit": "Enviar" + }, + "printFile": { + "title": "Imprimir arquivo", + "header": "Imprimir arquivo na impressora", + "selectText": { + "1": "Selecione o arquivo para imprimir", + "2": "Digite o nome da impressora" + }, + "submit": "Imprimir" + }, + "licenses": { + "nav": "LicenƧas", + "title": "LicenƧas de Terceiros", + "header": "LicenƧas de Terceiros", + "module": "Módulo", + "version": "VersĆ£o", + "license": "LicenƧa" + }, + "survey": { + "nav": "Pesquisa", + "title": "Pesquisa Stirling-PDF", + "description": "Stirling-PDF nĆ£o possui rastreamento, entĆ£o queremos ouvir nossos usuĆ”rios para melhorar o Stirling-PDF!", + "changes": "Stirling-PDF mudou desde sua Ćŗltima pesquisa! Para saber mais acesse nosso blog:", + "changes2": "Com essas mudanƧas estamos implementando suporte empresarial pago e financeamento.", + "please": "Por favor, considere responder Ć  nossa pesquisa!", + "disabled": "(O pop-up da pesquisa serĆ” desativado nas atualizaƧƵes seguintes, mas estarĆ” disponĆ­vel no rodapĆ© da pĆ”gina)", + "button": "Responder a Pesquisa", + "dontShowAgain": "NĆ£o mostre novamente.", + "meeting": { + "1": "Se vocĆŖ estĆ” utilizando o Stirling PDF em ambiente empresarial, nos vamos amar falar com vocĆŖ. Nós estamos oferecendo sessƵes de suporte tĆ©cnico em troca de uma sessĆ£o de descoberta de usuĆ”rios de 15 minutos.", + "2": "Essa Ć© uma chance para:", + "3": "Obter ajuda com implementação, integração ou resolução de problemas", + "4": "Prover feedback sobre desempenho, casos especiais e lacunas de funcionalidades", + "5": "Nos ajude a melhorar o Stirling PDF para uso empresarial no mundo real", + "6": "Se vocĆŖ estĆ” interessado, vocĆŖ pode agendar um horĆ”rio com nosso time diretamente. (Apenas em InglĆŖs)", + "7": "Estamos ansiosos para entender seu uso do software e tornar o Stirling PDF ainda melhor!", + "notInterested": "NĆ£o Ć© uma empresa e/ou nĆ£o tem interesse em uma reuniĆ£o?", + "button": "Agendar ReuniĆ£o" + } + }, + "removeImage": { + "title": "Remover Imagem", + "header": "Remover Imagem", + "removeImage": "Remover Imagem", + "submit": "Remover Imagem" + }, + "splitByChapters": { + "title": "Divide PDF por CapĆ­tulos", + "header": "Divide PDF por CapĆ­tulos", + "bookmarkLevel": "NĆ­vel do Marcador:", + "includeMetadata": "Incluir Metadados.", + "allowDuplicates": "Permitir Cópias.", + "desc": { + "1": "Essa ferramenta divide um arquivo PDF em vĆ”rios arquivos PDFs baseado na estrutura de capĆ­tulos.", + "2": "NĆ­vel do Marcador: Escolha o nĆ­vel do marcador a ser usado para divisĆ£o (0 para o primeiro nĆ­vel, 1 para o segundo nĆ­vel, etc).", + "3": "Incluir Metadados: Se marcado, os metadados do PDF original serĆ£o incluidos em cada arquivo gerado pela divisĆ£o do PDF.", + "4": "Permitir Cópias: Se marcado, habilita vĆ”rios marcadores na mesma pĆ”gina para criar PDFs separados." + }, + "submit": "Dividir" + }, + "fileChooser": { + "click": "Clique", + "or": "ou", + "dragAndDrop": "Arraste & Solte", + "dragAndDropPDF": "Arraste & Solte PDF(s)", + "dragAndDropImage": "Arraste & Solte Imagem(ns)", + "hoveredDragAndDrop": "Arraste & Solte arquivo(s) aqui", + "extractPDF": "Extraindo..." + }, + "releases": { + "footer": "VersƵes", + "title": "Notas de LanƧamento", + "header": "Notas de LanƧamento", + "current": { + "version": "VersĆ£o Atual" + }, + "note": "Notas de LanƧamento estĆ£o disponĆ­veis apenas em InglĆŖs" + }, + "cookieBanner": { + "popUp": { + "title": "Como nós utilizamos Cookies:", + "description": { + "1": "Nós utilizamos cookies e outras tecnologias para melhorar o Stirling PDF, ajude-nos para que possamos desenvolver novas funcionalidades que vocĆŖ irĆ” amar.", + "2": "Se vocĆŖ nĆ£o tiver interesse, clicando em \"NĆ£o, Obrigado\" serĆ” habilitado apenas cookies essenciais, para o site funcionar sem problemas." + }, + "acceptAllBtn": "Aceito", + "acceptNecessaryBtn": "NĆ£o, Obrigado", + "showPreferencesBtn": "Gerenciar PreferĆŖncias" + }, + "preferencesModal": { + "title": "Central de PreferĆŖncias de Consentimento", + "acceptAllBtn": "Aceitar tudo", + "acceptNecessaryBtn": "Rejeitar tudo", + "savePreferencesBtn": "Salvar preferĆŖncias", + "closeIconLabel": "Fechar janela", + "serviceCounterLabel": "ServiƧo|ServiƧos", + "subtitle": "Uso de Cookies", + "description": { + "1": "Stirling PDF utiliza cookies e tecnologias semelhantes para aprimorar sua experiĆŖncia e entender como nossas ferramentas sĆ£o utilizadas. Isso nos ajuda a melhorar o desempenho, desenvolver os recursos de seu interesse e fornecer suporte contĆ­nuo aos nossos usuĆ”rios.", + "2": "O Stirling PDF nĆ£o pode – e nunca irĆ” – rastrear ou acessar o conteĆŗdo dos documentos que vocĆŖ manipula.", + "3": "Sua privacidade e confianƧa sĆ£o prioridades para nós." + }, + "necessary": { + "title": { + "1": "Cookies Estritamente NecessĆ”rios", + "2": "Sempre Ativado" + }, + "description": "Estes cookies sĆ£o essenciais para o bom funcionamento do site. Eles habilitam recursos bĆ”sicos como definir suas preferĆŖncias de privacidade, realizar login e preencher formulĆ”rios – e Ć© por isso que nĆ£o podem ser desativados." + }, + "analytics": { + "title": "Cookies AnalĆ­ticos", + "description": "Estes cookies nos ajudam a entender como nossas ferramentas estĆ£o sendo utilizadas, para que possamos nos concentrar na construção dos recursos que nossa comunidade mais valoriza. Fique tranquilo: o Stirling PDF nĆ£o pode e nunca rastrearĆ” o conteĆŗdo dos documentos com os quais vocĆŖ manipula." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/pt-PT/translation.json b/frontend/public/locales/pt-PT/translation.json new file mode 100644 index 000000000..9ecc39e51 --- /dev/null +++ b/frontend/public/locales/pt-PT/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Tamanho da Fonte", + "fontName": "Nome da Fonte", + "title": "Adicionar NĆŗmeros de PĆ”gina", + "header": "Adicionar NĆŗmeros de PĆ”gina", + "selectText": { + "1": "Selecionar ficheiro PDF:", + "2": "Tamanho da Margem", + "3": "Posição", + "4": "NĆŗmero Inicial", + "5": "PĆ”ginas a Numerar", + "6": "Texto Personalizado" + }, + "customTextDesc": "Texto Personalizado", + "numberPagesDesc": "Quais pĆ”ginas a numerar, predefinição 'todas', tambĆ©m aceita 1-5 ou 2,5,9 etc", + "customNumberDesc": "Predefinição {n}, tambĆ©m aceita 'PĆ”gina {n} de {total}', 'Texto-{n}', '{filename}-{n}", + "submit": "Adicionar NĆŗmeros de PĆ”gina" + }, + "pdfPrompt": "Selecione PDF(s)", + "multiPdfPrompt": "Selecione PDFs (2+)", + "multiPdfDropPrompt": "Selecione (ou arraste e solte) todos os PDFs necessĆ”rios", + "imgPrompt": "Selecione Imagem(ns)", + "genericSubmit": "Submeter", + "uploadLimit": "Tamanho mĆ”ximo de ficheiro:", + "uploadLimitExceededSingular": "Ć© muito grande. O tamanho mĆ”ximo permitido Ć©", + "uploadLimitExceededPlural": "sĆ£o muito grandes. O tamanho mĆ”ximo permitido Ć©", + "processTimeWarning": "Aviso: Este processo pode demorar atĆ© um minuto dependendo do tamanho do ficheiro", + "pageOrderPrompt": "Ordem Personalizada de PĆ”ginas (Insira uma lista de nĆŗmeros de pĆ”gina separados por vĆ­rgulas ou FunƧƵes como 2n+1):", + "pageSelectionPrompt": "Seleção Personalizada de PĆ”ginas (Insira uma lista de nĆŗmeros de pĆ”gina separados por vĆ­rgulas 1,5,6 ou FunƧƵes como 2n+1):", + "goToPage": "Ir", + "true": "Verdadeiro", + "false": "Falso", + "unknown": "Desconhecido", + "save": "Guardar", + "saveToBrowser": "Guardar no Navegador", + "close": "Fechar", + "filesSelected": "ficheiros selecionados", + "noFavourites": "Nenhum favorito adicionado", + "downloadComplete": "Download ConcluĆ­do", + "bored": "Entediado Ć  espera?", + "alphabet": "Alfabeto", + "downloadPdf": "Transferir PDF", + "text": "Texto", + "font": "Tipo de letra", + "selectFillter": "-- Selecionar --", + "pageNum": "NĆŗmero da PĆ”gina", + "sizes": { + "small": "Pequeno", + "medium": "MĆ©dio", + "large": "Grande", + "x-large": "Extra Grande" + }, + "error": { + "pdfPassword": "O documento PDF estĆ” protegido por palavra-passe e ou nĆ£o foi fornecida ou estĆ” incorreta", + "_value": "Erro", + "sorry": "Pedimos desculpa pelo inconveniente!", + "needHelp": "Precisa de ajuda / Encontrou um problema?", + "contactTip": "Se ainda estiver com problemas, nĆ£o hesite em contactar-nos para obter ajuda. Pode submeter um ticket na nossa pĆ”gina GitHub ou contactar-nos atravĆ©s do Discord:", + "404": { + "head": "404 - PĆ”gina NĆ£o Encontrada | Ups, tropeƧƔmos no código!", + "1": "NĆ£o conseguimos encontrar a pĆ”gina que procura.", + "2": "Algo correu mal" + }, + "github": "Submeter um ticket no GitHub", + "showStack": "Mostrar Rastreamento da Pilha", + "copyStack": "Copiar Rastreamento da Pilha", + "githubSubmit": "GitHub - Submeter um ticket", + "discordSubmit": "Discord - Submeter Publicação de Suporte" + }, + "delete": "Eliminar", + "username": "Nome de utilizador", + "password": "Palavra-passe", + "welcome": "Bem-vindo", + "property": "Propriedade", + "black": "Preto", + "white": "Branco", + "red": "Vermelho", + "green": "Verde", + "blue": "Azul", + "custom": "Personalizar...", + "WorkInProgess": "Trabalho em progresso, pode nĆ£o funcionar ou ter erros, Por favor reporte quaisquer problemas!", + "poweredBy": "Desenvolvido por", + "yes": "Sim", + "no": "NĆ£o", + "changedCredsMessage": "Credenciais alteradas!", + "notAuthenticatedMessage": "Utilizador nĆ£o autenticado.", + "userNotFoundMessage": "Utilizador nĆ£o encontrado.", + "incorrectPasswordMessage": "A palavra-passe atual estĆ” incorreta.", + "usernameExistsMessage": "O novo nome de utilizador jĆ” existe.", + "invalidUsernameMessage": "Nome de utilizador invĆ”lido, o nome de utilizador só pode conter letras, nĆŗmeros e os seguintes caracteres especiais @._+- ou deve ser um endereƧo de email vĆ”lido.", + "invalidPasswordMessage": "A palavra-passe nĆ£o pode estar vazia e nĆ£o deve ter espaƧos no inĆ­cio ou no fim.", + "confirmPasswordErrorMessage": "A Nova Palavra-passe e Confirmar Nova Palavra-passe devem coincidir.", + "deleteCurrentUserMessage": "NĆ£o Ć© possĆ­vel eliminar o utilizador atualmente autenticado.", + "deleteUsernameExistsMessage": "O nome de utilizador nĆ£o existe e nĆ£o pode ser eliminado.", + "downgradeCurrentUserMessage": "NĆ£o Ć© possĆ­vel rebaixar a função do utilizador atual", + "disabledCurrentUserMessage": "O utilizador atual nĆ£o pode ser desativado", + "downgradeCurrentUserLongMessage": "NĆ£o Ć© possĆ­vel rebaixar a função do utilizador atual. Por isso, o utilizador atual nĆ£o serĆ” mostrado.", + "userAlreadyExistsOAuthMessage": "O utilizador jĆ” existe como utilizador OAuth2.", + "userAlreadyExistsWebMessage": "O utilizador jĆ” existe como utilizador web.", + "oops": "Ups!", + "help": "Ajuda", + "goHomepage": "Ir para a PĆ”gina Inicial", + "joinDiscord": "Junte-se ao nosso servidor Discord", + "seeDockerHub": "Ver Docker Hub", + "visitGithub": "Visitar Repositório Github", + "donate": "Doar", + "color": "Cor", + "sponsor": "Patrocinar", + "info": "Informação", + "pro": "Pro", + "page": "PĆ”gina", + "pages": "PĆ”ginas", + "loading": "A carregar...", + "addToDoc": "Adicionar ao Documento", + "reset": "Repor", + "apply": "Aplicar", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "PolĆ­tica de Privacidade", + "terms": "Termos e CondiƧƵes", + "accessibility": "Acessibilidade", + "cookie": "PolĆ­tica de Cookies", + "impressum": "Aviso Legal", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Menu Pipeline (Beta)", + "uploadButton": "Carregar Personalizado", + "configureButton": "Configurar", + "defaultOption": "Personalizado", + "submitButton": "Submeter", + "help": "Ajuda Pipeline", + "scanHelp": "Ajuda Digitalização de Pastas", + "deletePrompt": "Tem a certeza que pretende eliminar o pipeline?", + "tags": "automatizar,sequĆŖncia,script,processamento-lote", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Configuração Pipeline", + "pipelineNameLabel": "Nome Pipeline", + "saveSettings": "Guardar DefiniƧƵes da Operação", + "pipelineNamePrompt": "Insira aqui o nome do pipeline", + "selectOperation": "Selecionar Operação", + "addOperationButton": "Adicionar operação", + "pipelineHeader": "Pipeline:", + "saveButton": "Transferir", + "validateButton": "Validar" + }, + "enterpriseEdition": { + "button": "Atualizar para Pro", + "warning": "Esta funcionalidade estĆ” apenas disponĆ­vel para utilizadores Pro.", + "yamlAdvert": "O Stirling PDF Pro suporta ficheiros de configuração YAML e outras funcionalidades SSO.", + "ssoAdvert": "Procura mais funcionalidades de gestĆ£o de utilizadores? Veja o Stirling PDF Pro" + }, + "analytics": { + "title": "Quer tornar o Stirling PDF melhor?", + "paragraph1": "O Stirling PDF tem anĆ”lises opcionais para nos ajudar a melhorar o produto. NĆ£o rastreamos qualquer informação pessoal ou conteĆŗdo de ficheiros.", + "paragraph2": "Por favor considere ativar as anĆ”lises para ajudar o Stirling-PDF a crescer e permitir-nos compreender melhor os nossos utilizadores.", + "enable": "Ativar anĆ”lises", + "disable": "Desativar anĆ”lises", + "settings": "Pode alterar as definiƧƵes para anĆ”lises no ficheiro config/settings.yml" + }, + "navbar": { + "favorite": "Favoritos", + "recent": "New and recently updated", + "darkmode": "Modo Escuro", + "language": "Idiomas", + "settings": "DefiniƧƵes", + "allTools": "Ferramentas", + "multiTool": "Multi Ferramentas", + "search": "Pesquisar", + "sections": { + "organize": "Organizar", + "convertTo": "Converter para PDF", + "convertFrom": "Converter de PDF", + "security": "Assinatura & SeguranƧa", + "advance": "AvanƧado", + "edit": "Ver & Editar", + "popular": "Popular" + } + }, + "settings": { + "title": "DefiniƧƵes", + "update": "Atualização disponĆ­vel", + "updateAvailable": "{0} Ć© a versĆ£o atual instalada. Uma nova versĆ£o ({1}) estĆ” disponĆ­vel.", + "appVersion": "VersĆ£o da Aplicação:", + "downloadOption": { + "title": "Escolha a opção de download (Para downloads de ficheiro Ćŗnico nĆ£o zipado):", + "1": "Abrir na mesma janela", + "2": "Abrir em nova janela", + "3": "Transferir ficheiro" + }, + "zipThreshold": "Comprimir ficheiros quando o nĆŗmero de ficheiros transferidos exceder", + "signOut": "Terminar SessĆ£o", + "accountSettings": "DefiniƧƵes de Conta", + "bored": { + "help": "Ativa jogo easter egg" + }, + "cacheInputs": { + "name": "Guardar inputs do formulĆ”rio", + "help": "Ativar para guardar inputs previamente usados para futuras utilizaƧƵes" + } + }, + "changeCreds": { + "title": "Alterar Credenciais", + "header": "Atualizar os Detalhes da sua Conta", + "changePassword": "EstĆ” a usar credenciais de login padrĆ£o. Por favor insira uma nova palavra-passe", + "newUsername": "Novo Nome de Utilizador", + "oldPassword": "Palavra-passe Atual", + "newPassword": "Nova Palavra-passe", + "confirmNewPassword": "Confirmar Nova Palavra-passe", + "submit": "Submeter AlteraƧƵes" + }, + "account": { + "title": "DefiniƧƵes de Conta", + "accountSettings": "DefiniƧƵes de Conta", + "adminSettings": "DefiniƧƵes de Administrador - Ver e Adicionar Utilizadores", + "userControlSettings": "DefiniƧƵes de Controlo de Utilizador", + "changeUsername": "Alterar Nome de Utilizador", + "newUsername": "Novo Nome de Utilizador", + "password": "Palavra-passe de Confirmação", + "oldPassword": "Palavra-passe antiga", + "newPassword": "Nova Palavra-passe", + "changePassword": "Alterar Palavra-passe", + "confirmNewPassword": "Confirmar Nova Palavra-passe", + "signOut": "Terminar SessĆ£o", + "yourApiKey": "A sua Chave API", + "syncTitle": "Sincronizar definiƧƵes do navegador com Conta", + "settingsCompare": "Comparação de DefiniƧƵes:", + "property": "Propriedade", + "webBrowserSettings": "DefiniƧƵes do Navegador Web", + "syncToBrowser": "Sincronizar Conta -> Navegador", + "syncToAccount": "Sincronizar Conta <- Navegador" + }, + "adminUserSettings": { + "title": "DefiniƧƵes de Controlo de Utilizador", + "header": "DefiniƧƵes de Controlo de Utilizador Admin", + "admin": "Admin", + "user": "Utilizador", + "addUser": "Adicionar Novo Utilizador", + "deleteUser": "Eliminar Utilizador", + "confirmDeleteUser": "Deve o utilizador ser eliminado?", + "confirmChangeUserStatus": "Deve o utilizador ser desativado/ativado?", + "usernameInfo": "O nome de utilizador só pode conter letras, nĆŗmeros e os seguintes caracteres especiais @._+- ou deve ser um endereƧo de email vĆ”lido.", + "roles": "FunƧƵes", + "role": "Função", + "actions": "AƧƵes", + "apiUser": "Utilizador API Limitado", + "extraApiUser": "Utilizador API Limitado Adicional", + "webOnlyUser": "Utilizador Apenas Web", + "demoUser": "Utilizador Demo (Sem DefiniƧƵes Personalizadas)", + "internalApiUser": "Utilizador API Interno", + "forceChange": "ForƧar utilizador a alterar palavra-passe no login", + "submit": "Guardar Utilizador", + "changeUserRole": "Alterar Função do Utilizador", + "authenticated": "Autenticado", + "editOwnProfil": "Editar próprio perfil", + "enabledUser": "utilizador ativado", + "disabledUser": "utilizador desativado", + "activeUsers": "Utilizadores Ativos:", + "disabledUsers": "Utilizadores Desativados:", + "totalUsers": "Total de Utilizadores:", + "lastRequest": "Último Pedido", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Importar/Exportar Base de Dados", + "header": "Importar/Exportar Base de Dados", + "fileName": "Nome do Ficheiro", + "creationDate": "Data de Criação", + "fileSize": "Tamanho do Ficheiro", + "deleteBackupFile": "Eliminar Ficheiro de Backup", + "importBackupFile": "Importar Ficheiro de Backup", + "createBackupFile": "Criar Ficheiro de Backup", + "downloadBackupFile": "Transferir Ficheiro de Backup", + "info_1": "Ao importar dados, Ć© crucial assegurar a estrutura correta. Se nĆ£o tiver certeza do que estĆ” a fazer, procure aconselhamento e suporte de um profissional. Um erro na estrutura pode causar mau funcionamento da aplicação, atĆ© Ć  completa impossibilidade de executar a aplicação.", + "info_2": "O nome do ficheiro nĆ£o importa ao carregar. SerĆ” renomeado depois para seguir o formato backup_user_yyyyMMddHHmm.sql, assegurando uma convenção de nomes consistente.", + "submit": "Importar Backup", + "importIntoDatabaseSuccessed": "Importação para base de dados bem sucedida", + "backupCreated": "Backup da base de dados bem sucedido", + "fileNotFound": "Ficheiro nĆ£o Encontrado", + "fileNullOrEmpty": "O ficheiro nĆ£o pode ser nulo ou vazio", + "failedImportFile": "Falha ao Importar Ficheiro", + "notSupported": "Esta função nĆ£o estĆ” disponĆ­vel para a sua ligação Ć  base de dados." + }, + "session": { + "expired": "A sua sessĆ£o expirou. Por favor atualize a pĆ”gina e tente novamente.", + "refreshPage": "Atualizar PĆ”gina" + }, + "home": { + "desc": "O seu centro local para todas as suas necessidades de PDF.", + "searchBar": "Pesquisar funcionalidades...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Ver, anotar, adicionar texto ou imagens" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "Multi Ferramenta PDF", + "desc": "Juntar, Rodar, Reorganizar, Dividir e Remover pĆ”ginas" + }, + "merge": { + "title": "Juntar", + "desc": "Junte facilmente vĆ”rios PDFs num só." + }, + "split": { + "title": "Dividir", + "desc": "Dividir PDFs em vĆ”rios documentos" + }, + "rotate": { + "title": "Rodar", + "desc": "Rode facilmente os seus PDFs." + }, + "imageToPdf": { + "title": "Imagem para PDF", + "desc": "Converter uma imagem (PNG, JPEG, GIF) para PDF." + }, + "pdfToImage": { + "title": "PDF para Imagem", + "desc": "Converter um PDF para uma imagem. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Organizar", + "desc": "Remover/Reorganizar pĆ”ginas em qualquer ordem" + }, + "addImage": { + "title": "Adicionar imagem", + "desc": "Adiciona uma imagem numa localização definida no PDF" + }, + "watermark": { + "title": "Adicionar Marca de Ɓgua", + "desc": "Adicionar uma marca de Ć”gua personalizada ao seu documento PDF." + }, + "permissions": { + "title": "Alterar PermissƵes", + "desc": "Alterar as permissƵes do seu documento PDF" + }, + "removePages": { + "title": "Remover", + "desc": "Eliminar pĆ”ginas indesejadas do seu documento PDF." + }, + "addPassword": { + "title": "Adicionar Palavra-passe", + "desc": "Encriptar o seu documento PDF com uma palavra-passe." + }, + "removePassword": { + "title": "Remover Palavra-passe", + "desc": "Remover proteção por palavra-passe do seu documento PDF." + }, + "compressPdfs": { + "title": "Comprimir", + "desc": "Comprimir PDFs para reduzir o seu tamanho." + }, + "unlockPDFForms": { + "title": "Desbloquear FormulĆ”rios do PDF", + "desc": "Remover propriedades de apenas leitura dos formulĆ”rios de um PDF" + }, + "changeMetadata": { + "title": "Alterar Metadados", + "desc": "Alterar/Remover/Adicionar metadados de um documento PDF" + }, + "fileToPDF": { + "title": "Converter ficheiro para PDF", + "desc": "Converter quase qualquer ficheiro para PDF (DOCX, PNG, XLS, PPT, TXT e mais)" + }, + "ocr": { + "title": "OCR / Limpeza de digitalizaƧƵes", + "desc": "Limpa digitalizaƧƵes e deteta texto de imagens dentro de um PDF e readiciona-o como texto." + }, + "extractImages": { + "title": "Extrair Imagens", + "desc": "Extrai todas as imagens de um PDF e guarda-as num zip" + }, + "pdfToPDFA": { + "title": "PDF para PDF/A", + "desc": "Converter PDF para PDF/A para armazenamento a longo prazo" + }, + "PDFToWord": { + "title": "PDF para Word", + "desc": "Converter PDF para formatos Word (DOC, DOCX e ODT)" + }, + "PDFToPresentation": { + "title": "PDF para Apresentação", + "desc": "Converter PDF para formatos de Apresentação (PPT, PPTX e ODP)" + }, + "PDFToText": { + "title": "PDF para RTF (Texto)", + "desc": "Converter PDF para formato Texto ou RTF" + }, + "PDFToHTML": { + "title": "PDF para HTML", + "desc": "Converter PDF para formato HTML" + }, + "PDFToXML": { + "title": "PDF para XML", + "desc": "Converter PDF para formato XML" + }, + "ScannerImageSplit": { + "title": "Detetar/Dividir fotos digitalizadas", + "desc": "Divide mĆŗltiplas fotos de dentro de uma foto/PDF" + }, + "sign": { + "title": "Assinar", + "desc": "Adiciona assinatura ao PDF por desenho, texto ou imagem" + }, + "flatten": { + "title": "Achatar", + "desc": "Remover todos os elementos interativos e formulĆ”rios de um PDF" + }, + "repair": { + "title": "Reparar", + "desc": "Tenta reparar um PDF corrompido/danificado" + }, + "removeBlanks": { + "title": "Remover PĆ”ginas em Branco", + "desc": "Deteta e remove pĆ”ginas em branco de um documento" + }, + "removeAnnotations": { + "title": "Remover AnotaƧƵes", + "desc": "Remove todos os comentĆ”rios/anotaƧƵes de um PDF" + }, + "compare": { + "title": "Comparar", + "desc": "Compara e mostra as diferenƧas entre 2 Documentos PDF" + }, + "certSign": { + "title": "Assinar com Certificado", + "desc": "Assina um PDF com um Certificado/Chave (PEM/P12)" + }, + "removeCertSign": { + "title": "Remover Assinatura de Certificado", + "desc": "Remove assinatura de certificado do PDF" + }, + "pageLayout": { + "title": "Layout Multi-PĆ”gina", + "desc": "Juntar mĆŗltiplas pĆ”ginas de um documento PDF numa Ćŗnica pĆ”gina" + }, + "scalePages": { + "title": "Ajustar tamanho/escala de pĆ”gina", + "desc": "Alterar o tamanho/escala de uma pĆ”gina e/ou os seus conteĆŗdos." + }, + "pipeline": { + "title": "Pipeline", + "desc": "Executar mĆŗltiplas aƧƵes em PDFs definindo scripts pipeline" + }, + "add-page-numbers": { + "title": "Adicionar NĆŗmeros de PĆ”gina", + "desc": "Adicionar nĆŗmeros de pĆ”gina ao longo de um documento numa localização definida" + }, + "auto-rename": { + "title": "Renomear Automaticamente Ficheiro PDF", + "desc": "Renomeia automaticamente um ficheiro PDF baseado no cabeƧalho detetado" + }, + "adjust-contrast": { + "title": "Ajustar Cores/Contraste", + "desc": "Ajustar Contraste, Saturação e Brilho de um PDF" + }, + "crop": { + "title": "Recortar PDF", + "desc": "Recortar um PDF para reduzir o seu tamanho (mantĆ©m o texto!)" + }, + "autoSplitPDF": { + "title": "DivisĆ£o AutomĆ”tica de PĆ”ginas", + "desc": "Dividir automaticamente PDF digitalizado com separador de pĆ”ginas fĆ­sico com Código QR" + }, + "sanitizePdf": { + "title": "Sanitizar", + "desc": "Remover scripts e outros elementos de ficheiros PDF" + }, + "URLToPDF": { + "title": "URL/Website Para PDF", + "desc": "Converte qualquer URL http(s) para PDF" + }, + "HTMLToPDF": { + "title": "HTML para PDF", + "desc": "Converte qualquer ficheiro HTML ou zip para PDF" + }, + "MarkdownToPDF": { + "title": "Markdown para PDF", + "desc": "Converte qualquer ficheiro Markdown para PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "Obter TODA Informação sobre PDF", + "desc": "ObtĆ©m qualquer e toda informação possĆ­vel sobre PDFs" + }, + "extractPage": { + "title": "Extrair pĆ”gina(s)", + "desc": "Extrai pĆ”ginas selecionadas do PDF" + }, + "PdfToSinglePage": { + "title": "PĆ”gina Única Grande", + "desc": "Junta todas as pĆ”ginas do PDF numa Ćŗnica pĆ”gina grande" + }, + "showJS": { + "title": "Mostrar Javascript", + "desc": "Procura e mostra qualquer JS injetado num PDF" + }, + "autoRedact": { + "title": "Redação AutomĆ”tica", + "desc": "Redação AutomĆ”tica (Oculta) texto num PDF baseado em texto de entrada" + }, + "redact": { + "title": "Redação Manual", + "desc": "Redacta um PDF baseado em texto selecionado, formas desenhadas e/ou pĆ”gina(s) selecionada(s)" + }, + "tableExtraxt": { + "title": "PDF para CSV", + "desc": "Extrai Tabelas de um PDF convertendo para CSV" + }, + "autoSizeSplitPDF": { + "title": "DivisĆ£o AutomĆ”tica por Tamanho/Contagem", + "desc": "Dividir um Ćŗnico PDF em mĆŗltiplos documentos baseado em tamanho, contagem de pĆ”ginas, ou contagem de documentos" + }, + "overlay-pdfs": { + "title": "Sobrepor PDFs", + "desc": "SobrepƵe PDFs em cima de outro PDF" + }, + "split-by-sections": { + "title": "Dividir PDF por SecƧƵes", + "desc": "Divide cada pĆ”gina de um PDF em secƧƵes horizontais e verticais mais pequenas" + }, + "AddStampRequest": { + "title": "Adicionar Carimbo a PDF", + "desc": "Adicionar carimbos de texto ou adicionar carimbos de imagem em localizaƧƵes definidas" + }, + "removeImagePdf": { + "title": "Remover imagem", + "desc": "Remover imagem do PDF para reduzir tamanho do ficheiro" + }, + "splitPdfByChapters": { + "title": "Dividir PDF por CapĆ­tulos", + "desc": "Dividir um PDF em mĆŗltiplos ficheiros baseado na sua estrutura de capĆ­tulos." + }, + "validateSignature": { + "title": "Validar Assinatura PDF", + "desc": "Verificar assinaturas digitais e certificados em documentos PDF" + }, + "replaceColorPdf": { + "title": "Substituir e Inverter Cor", + "desc": "Substituir cor para texto e fundo em PDF e inverter cor completa do pdf para reduzir tamanho do ficheiro" + } + }, + "viewPdf": { + "tags": "ver,ler,anotar,texto,imagem", + "title": "View/Edit PDF", + "header": "Ver PDF" + }, + "multiTool": { + "tags": "Multi Ferramenta,Multi operação,UI,clicar arrastar,front end,lado cliente,interativo,interagĆ­vel,mover,eliminar,migrar,dividir", + "title": "Multi Ferramenta PDF", + "header": "Multi Ferramenta PDF", + "uploadPrompts": "Nome do Ficheiro", + "selectAll": "Selecionar Tudo", + "deselectAll": "Desselecionar Tudo", + "selectPages": "Selecionar PĆ”gina", + "selectedPages": "PĆ”ginas Selecionadas", + "page": "PĆ”gina", + "deleteSelected": "Eliminar Selecionadas", + "downloadAll": "Exportar", + "downloadSelected": "Exportar Selecionadas", + "insertPageBreak": "Inserir Quebra de PĆ”gina", + "addFile": "Adicionar Ficheiro", + "rotateLeft": "Rodar Ć  Esquerda", + "rotateRight": "Rodar Ć  Direita", + "split": "Dividir", + "moveLeft": "Mover Ć  Esquerda", + "moveRight": "Mover Ć  Direita", + "delete": "Eliminar", + "dragDropMessage": "PĆ”gina(s) Selecionada(s)", + "undo": "Desfazer", + "redo": "Refazer" + }, + "merge": { + "tags": "juntar,OperaƧƵes de pĆ”gina,Back end,lado servidor", + "title": "Juntar", + "header": "Juntar mĆŗltiplos PDFs (2+)", + "sortByName": "Ordenar por nome", + "sortByDate": "Ordenar por data", + "removeCertSign": "Remover assinatura digital no ficheiro junto?", + "submit": "Juntar" + }, + "split": { + "tags": "OperaƧƵes de pĆ”gina,dividir,Multi PĆ”gina,cortar,lado servidor", + "title": "Dividir PDF", + "header": "Dividir PDF", + "desc": { + "1": "Os nĆŗmeros que seleciona sĆ£o o nĆŗmero da pĆ”gina onde deseja fazer uma divisĆ£o", + "2": "Como tal, selecionar 1,3,7-9 iria dividir um documento de 10 pĆ”ginas em 6 PDFs separados com:", + "3": "Documento #1: PĆ”gina 1", + "4": "Documento #2: PĆ”ginas 2 e 3", + "5": "Documento #3: PĆ”ginas 4, 5, 6, 7", + "6": "Documento #4: PĆ”gina 8", + "7": "Documento #5: PĆ”gina 9", + "8": "Documento #6: PĆ”gina 10" + }, + "splitPages": "Introduza pĆ”ginas para dividir:", + "submit": "Dividir" + }, + "rotate": { + "tags": "lado servidor", + "title": "Rodar PDF", + "header": "Rodar PDF", + "selectAngle": "Selecione Ć¢ngulo de rotação (em mĆŗltiplos de 90 graus):", + "submit": "Rodar" + }, + "imageToPdf": { + "tags": "conversĆ£o,img,jpg,imagem,foto" + }, + "pdfToImage": { + "tags": "conversĆ£o,img,jpg,imagem,foto", + "title": "PDF para Imagem", + "header": "PDF para Imagem", + "selectText": "Formato de Imagem", + "singleOrMultiple": "Tipo de resultado da imagem", + "single": "Única Imagem Grande", + "multi": "MĆŗltiplas Imagens", + "colorType": "Tipo de cor", + "color": "Cor", + "grey": "Escala de Cinza", + "blackwhite": "Preto e Branco (Pode perder dados!)", + "submit": "Converter", + "info": "Python nĆ£o estĆ” instalado. NecessĆ”rio para conversĆ£o WebP.", + "placeholder": "(ex. 1,2,8 ou 4,7,12-16 ou 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,par,Ć­mpar,ordenar,mover", + "title": "Organizador de PĆ”ginas", + "header": "Organizador de PĆ”ginas PDF", + "submit": "Reorganizar PĆ”ginas", + "mode": { + "_value": "Modo", + "1": "Ordem de PĆ”gina Personalizada", + "2": "Ordem Inversa", + "3": "Ordenação Duplex", + "4": "Ordenação em Livro", + "5": "Ordenação em Livro com Costura Lateral", + "6": "DivisĆ£o Par-ƍmpar", + "7": "Remover Primeira", + "8": "Remover Última", + "9": "Remover Primeira e Última", + "10": "Junção Par-ƍmpar", + "11": "Duplicate all pages" + }, + "placeholder": "(ex. 1,3,2 ou 4-8,2,10-12 ou 2n-1)" + }, + "addImage": { + "tags": "img,jpg,imagem,foto", + "title": "Adicionar Imagem", + "header": "Adicionar imagem ao PDF", + "everyPage": "Todas as PĆ”ginas?", + "upload": "Adicionar imagem", + "submit": "Adicionar imagem" + }, + "watermark": { + "tags": "Texto,repetindo,etiqueta,próprio,copyright,marca registada,img,jpg,imagem,foto", + "title": "Adicionar Marca de Ɓgua", + "header": "Adicionar Marca de Ɓgua", + "customColor": "Cor de Texto Personalizada", + "selectText": { + "1": "Selecione PDF para adicionar marca de Ć”gua:", + "2": "Texto da Marca de Ɓgua:", + "3": "Tamanho da Fonte:", + "4": "Rotação (0-360):", + "5": "EspaƧador de Largura (EspaƧo entre cada marca de Ć”gua horizontalmente):", + "6": "EspaƧador de Altura (EspaƧo entre cada marca de Ć”gua verticalmente):", + "7": "Opacidade (0% - 100%):", + "8": "Tipo de Marca de Ɓgua:", + "9": "Imagem da Marca de Ɓgua:", + "10": "Converter PDF para PDF-Imagem" + }, + "submit": "Adicionar Marca de Ɓgua", + "type": { + "1": "Texto", + "2": "Imagem" + } + }, + "permissions": { + "tags": "ler,escrever,editar,imprimir", + "title": "Alterar PermissƵes", + "header": "Alterar PermissƵes", + "warning": "Aviso para tornar estas permissƵes inalterĆ”veis Ć© recomendado defini-las com uma palavra-passe atravĆ©s da pĆ”gina adicionar-palavra-passe", + "selectText": { + "1": "Selecione PDF para alterar permissƵes", + "2": "PermissƵes a definir", + "3": "Impedir montagem do documento", + "4": "Impedir extração de conteĆŗdo", + "5": "Impedir extração para acessibilidade", + "6": "Impedir preenchimento de formulĆ”rio", + "7": "Impedir modificação", + "8": "Impedir modificação de anotação", + "9": "Impedir impressĆ£o", + "10": "Impedir impressĆ£o em diferentes formatos" + }, + "submit": "Alterar" + }, + "removePages": { + "tags": "Remover pĆ”ginas,eliminar pĆ”ginas" + }, + "addPassword": { + "tags": "seguro,seguranƧa", + "title": "Adicionar Palavra-passe", + "header": "Adicionar palavra-passe (Encriptar)", + "selectText": { + "1": "Selecione PDF para encriptar", + "2": "Palavra-passe de Utilizador", + "3": "Comprimento da Chave de Encriptação", + "4": "Valores mais altos sĆ£o mais fortes, mas valores mais baixos tĆŖm melhor compatibilidade.", + "5": "PermissƵes a definir (Recomendado usar junto com palavra-passe de ProprietĆ”rio)", + "6": "Impedir montagem do documento", + "7": "Impedir extração de conteĆŗdo", + "8": "Impedir extração para acessibilidade", + "9": "Impedir preenchimento de formulĆ”rio", + "10": "Impedir modificação", + "11": "Impedir modificação de anotação", + "12": "Impedir impressĆ£o", + "13": "Impedir impressĆ£o em diferentes formatos", + "14": "Palavra-passe de ProprietĆ”rio", + "15": "Restringe o que pode ser feito com o documento uma vez aberto (NĆ£o suportado por todos os leitores)", + "16": "Restringe a abertura do próprio documento" + }, + "submit": "Encriptar" + }, + "removePassword": { + "tags": "seguro,Desencriptar,seguranƧa,sem palavra-passe,eliminar palavra-passe", + "title": "Remover palavra-passe", + "header": "Remover palavra-passe (Desencriptar)", + "selectText": { + "1": "Selecione PDF para Desencriptar", + "2": "Palavra-passe" + }, + "submit": "Remover" + }, + "compressPdfs": { + "tags": "comprimir,pequeno,minĆŗsculo" + }, + "unlockPDFForms": { + "tags": "remover,apagar,formulĆ”rio,campo,apenas leitura", + "title": "Desbloquear FormulĆ”rios do PDF", + "header": "Desbloquear FormulĆ”rios do PDF", + "submit": "Remover" + }, + "changeMetadata": { + "tags": "TĆ­tulo,autor,data,criação,tempo,editor,produtor,estatĆ­sticas", + "title": "TĆ­tulo:", + "header": "Alterar Metadados", + "selectText": { + "1": "Por favor edite as variĆ”veis que deseja alterar", + "2": "Eliminar todos os metadados", + "3": "Mostrar Metadados Personalizados:", + "4": "Outros Metadados:", + "5": "Adicionar Entrada de Metadados Personalizada" + }, + "author": "Autor:", + "creationDate": "Data de Criação (aaaa/MM/dd HH:mm:ss):", + "creator": "Criador:", + "keywords": "Palavras-chave:", + "modDate": "Data de Modificação (aaaa/MM/dd HH:mm:ss):", + "producer": "Produtor:", + "subject": "Assunto:", + "trapped": "Capturado:", + "submit": "Alterar" + }, + "fileToPDF": { + "tags": "transformação,formato,documento,imagem,slide,texto,conversĆ£o,escritório,docs,word,excel,powerpoint", + "title": "Ficheiro para PDF", + "header": "Converter qualquer ficheiro para PDF", + "credit": "Este serviƧo usa LibreOffice e Unoconv para conversĆ£o de ficheiros.", + "supportedFileTypesInfo": "Tipos de Ficheiro Suportados", + "supportedFileTypes": "Os tipos de ficheiro suportados devem incluir os abaixo, no entanto para uma lista completa atualizada de formatos suportados, por favor consulte a documentação do LibreOffice", + "submit": "Converter para PDF" + }, + "ocr": { + "tags": "reconhecimento,texto,imagem,digitalização,ler,identificar,deteção,editĆ”vel", + "title": "OCR / Limpeza de digitalizaƧƵes", + "header": "Limpeza de DigitalizaƧƵes / OCR (Reconhecimento Ɠtico de Caracteres)", + "selectText": { + "1": "Selecione idiomas que devem ser detetados dentro do PDF (Os listados sĆ£o os atualmente detetados):", + "2": "Produzir ficheiro de texto contendo texto OCR junto com o PDF processado com OCR", + "3": "Corrigir pĆ”ginas que foram digitalizadas num Ć¢ngulo inclinado rodando-as de volta ao lugar", + "4": "Limpar pĆ”gina para que seja menos provĆ”vel que o OCR encontre texto em ruĆ­do de fundo. (Sem alteração na saĆ­da)", + "5": "Limpar pĆ”gina para que seja menos provĆ”vel que o OCR encontre texto em ruĆ­do de fundo, mantĆ©m a limpeza na saĆ­da.", + "6": "Ignora pĆ”ginas que tĆŖm texto interativo, apenas processa OCR em pĆ”ginas que sĆ£o imagens", + "7": "ForƧar OCR, irĆ” processar OCR em Cada pĆ”gina removendo todos os elementos de texto originais", + "8": "Normal (IrĆ” dar erro se o PDF contiver texto)", + "9": "DefiniƧƵes Adicionais", + "10": "Modo OCR", + "11": "Remover imagens após OCR (Remove TODAS as imagens, apenas Ćŗtil se parte do passo de conversĆ£o)", + "12": "Tipo de Renderização (AvanƧado)" + }, + "help": "Por favor leia esta documentação sobre como usar isto para outros idiomas e/ou usar fora do docker", + "credit": "Este serviƧo usa qpdf e Tesseract para OCR.", + "submit": "Processar PDF com OCR" + }, + "extractImages": { + "tags": "imagem,foto,guardar,arquivo,zip,capturar,extrair", + "title": "Extrair Imagens", + "header": "Extrair Imagens", + "selectText": "Selecione formato de imagem para converter imagens extraĆ­das", + "allowDuplicates": "Guardar imagens duplicadas", + "submit": "Extrair" + }, + "pdfToPDFA": { + "tags": "arquivo,longo prazo,padrĆ£o,conversĆ£o,armazenamento,preservação", + "title": "PDF Para PDF/A", + "header": "PDF Para PDF/A", + "credit": "Este serviƧo usa libreoffice para conversĆ£o PDF/A", + "submit": "Converter", + "tip": "Atualmente nĆ£o funciona para mĆŗltiplas entradas de uma só vez", + "outputFormat": "Formato de saĆ­da", + "pdfWithDigitalSignature": "O PDF contĆ©m uma assinatura digital. Esta serĆ” removida no próximo passo." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformação,formato,conversĆ£o,escritório,microsoft,docfile", + "title": "PDF para Word", + "header": "PDF para Word", + "selectText": { + "1": "Formato do ficheiro de saĆ­da" + }, + "credit": "Este serviƧo usa LibreOffice para conversĆ£o de ficheiros.", + "submit": "Converter" + }, + "PDFToPresentation": { + "tags": "slides,apresentação,escritório,microsoft", + "title": "PDF para Apresentação", + "header": "PDF para Apresentação", + "selectText": { + "1": "Formato do ficheiro de saĆ­da" + }, + "credit": "Este serviƧo usa LibreOffice para conversĆ£o de ficheiros.", + "submit": "Converter" + }, + "PDFToText": { + "tags": "formato rico,formato texto rico,formato texto rico", + "title": "PDF para RTF (Texto)", + "header": "PDF para RTF (Texto)", + "selectText": { + "1": "Formato do ficheiro de saĆ­da" + }, + "credit": "Este serviƧo usa LibreOffice para conversĆ£o de ficheiros.", + "submit": "Converter" + }, + "PDFToHTML": { + "tags": "conteĆŗdo web,compatĆ­vel com navegador", + "title": "PDF para HTML", + "header": "PDF para HTML", + "credit": "Este serviƧo usa pdftohtml para conversĆ£o de ficheiros.", + "submit": "Converter" + }, + "PDFToXML": { + "tags": "extração-dados,conteĆŗdo-estruturado,interop,transformação,converter", + "title": "PDF para XML", + "header": "PDF para XML", + "credit": "Este serviƧo usa LibreOffice para conversĆ£o de ficheiros.", + "submit": "Converter" + }, + "ScannerImageSplit": { + "tags": "separar,auto-detetar,digitalizaƧƵes,multi-foto,organizar", + "selectText": { + "1": "Limiar de Ƃngulo:", + "2": "Define o Ć¢ngulo absoluto mĆ­nimo necessĆ”rio para a imagem ser rodada (predefinição: 10).", + "3": "TolerĆ¢ncia:", + "4": "Determina o intervalo de variação de cor em torno da cor de fundo estimada (predefinição: 30).", + "5": "Ɓrea MĆ­nima:", + "6": "Define o limiar de Ć”rea mĆ­nima para uma foto (predefinição: 10000).", + "7": "Ɓrea MĆ­nima de Contorno:", + "8": "Define o limiar de Ć”rea mĆ­nima de contorno para uma foto", + "9": "Tamanho da Borda:", + "10": "Define o tamanho da borda adicionada e removida para prevenir bordas brancas na saĆ­da (predefinição: 1)." + }, + "info": "Python nĆ£o estĆ” instalado. Ɖ necessĆ”rio para executar." + }, + "sign": { + "tags": "autorizar,iniciais,assinatura-desenhada,assinatura-texto,assinatura-imagem", + "title": "Assinar", + "header": "Assinar PDFs", + "upload": "Carregar Imagem", + "draw": "Desenhar Assinatura", + "text": "Entrada de Texto", + "clear": "Limpar", + "add": "Adicionar", + "saved": "Assinaturas Guardadas", + "save": "Guardar Assinatura", + "personalSigs": "Assinaturas Pessoais", + "sharedSigs": "Assinaturas Partilhadas", + "noSavedSigs": "Nenhuma assinatura guardada encontrada", + "addToAll": "Adicionar a todas as pĆ”ginas", + "delete": "Eliminar", + "first": "Primeira pĆ”gina", + "last": "Última pĆ”gina", + "next": "Próxima pĆ”gina", + "previous": "PĆ”gina anterior", + "maintainRatio": "Alternar manter proporção", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "estĆ”tico,desativar,nĆ£o-interativo,otimizar", + "title": "Achatar", + "header": "Achatar PDFs", + "flattenOnlyForms": "Achatar apenas formulĆ”rios", + "submit": "Achatar" + }, + "repair": { + "tags": "corrigir,restaurar,correção,recuperar", + "title": "Reparar", + "header": "Reparar PDFs", + "submit": "Reparar" + }, + "removeBlanks": { + "tags": "limpeza,otimizar,sem-conteĆŗdo,organizar", + "title": "Remover PĆ”ginas em Branco", + "header": "Remover PĆ”ginas em Branco", + "threshold": "Limiar de Brancura de Pixel:", + "thresholdDesc": "Limiar para determinar quĆ£o branco um pixel branco deve ser para ser classificado como 'Branco'. 0 = Preto, 255 branco puro.", + "whitePercent": "Percentagem de Branco (%):", + "whitePercentDesc": "Percentagem da pĆ”gina que deve ser pixels 'brancos' para ser removida", + "submit": "Remover PĆ”ginas em Branco" + }, + "removeAnnotations": { + "tags": "comentĆ”rios,destaque,notas,marcação,remover", + "title": "Remover AnotaƧƵes", + "header": "Remover AnotaƧƵes", + "submit": "Remover" + }, + "compare": { + "tags": "diferenciar,contrastar,alteraƧƵes,anĆ”lise", + "title": "Comparar", + "header": "Comparar PDFs", + "highlightColor": { + "1": "Cor de Destaque 1:", + "2": "Cor de Destaque 2:" + }, + "document": { + "1": "Documento 1", + "2": "Documento 2" + }, + "submit": "Comparar", + "complex": { + "message": "Um ou ambos os documentos fornecidos sĆ£o ficheiros grandes, a precisĆ£o da comparação pode ser reduzida" + }, + "large": { + "file": { + "message": "Um ou ambos os documentos fornecidos sĆ£o demasiado grandes para processar" + } + }, + "no": { + "text": { + "message": "Um ou ambos os PDFs selecionados nĆ£o tĆŖm conteĆŗdo de texto. Por favor escolha PDFs com texto para comparação." + } + } + }, + "certSign": { + "tags": "autenticar,PEM,P12,oficial,encriptar", + "title": "Assinatura de Certificado", + "header": "Assinar um PDF com o seu certificado (Trabalho em progresso)", + "selectPDF": "Selecione um Ficheiro PDF para Assinar:", + "jksNote": "Nota: Se o seu tipo de certificado nĆ£o estiver listado abaixo, por favor converta-o para um ficheiro Java Keystore (.jks) usando a ferramenta de linha de comando keytool. Depois, escolha a opção de ficheiro .jks abaixo.", + "selectKey": "Selecione o Seu Ficheiro de Chave Privada (formato PKCS#8, pode ser .pem ou .der):", + "selectCert": "Selecione o Seu Ficheiro de Certificado (formato X.509, pode ser .pem ou .der):", + "selectP12": "Selecione o Seu Ficheiro Keystore PKCS#12 (.p12 ou .pfx) (Opcional, Se fornecido, deve conter a sua chave privada e certificado):", + "selectJKS": "Selecione o Seu Ficheiro Java Keystore (.jks ou .keystore):", + "certType": "Tipo de Certificado", + "password": "Introduza a Sua Palavra-passe de Keystore ou Chave Privada (Se Existir):", + "showSig": "Mostrar Assinatura", + "reason": "RazĆ£o", + "location": "Localização", + "name": "Nome", + "showLogo": "Mostrar Logo", + "submit": "Assinar PDF" + }, + "removeCertSign": { + "tags": "autenticar,PEM,P12,oficial,desencriptar", + "title": "Remover Assinatura de Certificado", + "header": "Remover o certificado digital do PDF", + "selectPDF": "Selecione um ficheiro PDF:", + "submit": "Remover Assinatura" + }, + "pageLayout": { + "tags": "juntar,composto,vista-Ćŗnica,organizar", + "title": "Layout Multi-PĆ”gina", + "header": "Layout Multi-PĆ”gina", + "pagesPerSheet": "PĆ”ginas por folha:", + "addBorder": "Adicionar Bordas", + "submit": "Submeter" + }, + "scalePages": { + "tags": "redimensionar,modificar,dimensĆ£o,adaptar", + "title": "Ajustar escala de pĆ”gina", + "header": "Ajustar escala de pĆ”gina", + "pageSize": "Tamanho de uma pĆ”gina do documento.", + "keepPageSize": "Tamanho Original", + "scaleFactor": "NĆ­vel de zoom (recorte) de uma pĆ”gina.", + "submit": "Submeter" + }, + "add-page-numbers": { + "tags": "paginar,etiqueta,organizar,Ć­ndice" + }, + "auto-rename": { + "tags": "auto-deteção,baseado-cabeƧalho,organizar,reetiquetar", + "title": "Renomear AutomĆ”tico", + "header": "Renomear PDF Automaticamente", + "submit": "Renomear AutomĆ”tico" + }, + "adjust-contrast": { + "tags": "correção-cor,afinar,modificar,melhorar" + }, + "crop": { + "tags": "aparar,encolher,editar,forma", + "title": "Recortar", + "header": "Recortar PDF", + "submit": "Submeter" + }, + "autoSplitPDF": { + "tags": "baseado-QR,separar,segmento-digitalização,organizar", + "title": "DivisĆ£o AutomĆ”tica de PDF", + "header": "DivisĆ£o AutomĆ”tica de PDF", + "description": "Imprima, Insira, Digitalize, carregue, e deixe-nos separar automaticamente os seus documentos. Sem necessidade de organização manual.", + "selectText": { + "1": "Imprima algumas folhas separadoras abaixo (Preto e branco Ć© suficiente).", + "2": "Digitalize todos os seus documentos de uma vez inserindo a folha separadora entre eles.", + "3": "Carregue o Ćŗnico ficheiro PDF digitalizado grande e deixe o Stirling PDF tratar do resto.", + "4": "As pĆ”ginas separadoras sĆ£o automaticamente detetadas e removidas, garantindo um documento final organizado." + }, + "formPrompt": "Submeter PDF contendo separadores de pĆ”gina Stirling-PDF:", + "duplexMode": "Modo Duplex (Digitalização frente e verso)", + "dividerDownload2": "Transferir 'Separador de DivisĆ£o AutomĆ”tica (com instruƧƵes).pdf'", + "submit": "Submeter" + }, + "sanitizePdf": { + "tags": "limpar,seguro,seguranƧa,remover-ameaƧas" + }, + "URLToPDF": { + "tags": "captura-web,guardar-pĆ”gina,web-para-doc,arquivo", + "title": "URL Para PDF", + "header": "URL Para PDF", + "submit": "Converter", + "credit": "Usa WeasyPrint" + }, + "HTMLToPDF": { + "tags": "marcação,conteĆŗdo-web,transformação,converter", + "title": "HTML Para PDF", + "header": "HTML Para PDF", + "help": "Aceita ficheiros HTML e ZIPs contendo html/css/imagens etc necessĆ”rios", + "submit": "Converter", + "credit": "Usa WeasyPrint", + "zoom": "NĆ­vel de zoom para mostrar o website.", + "pageWidth": "Largura da pĆ”gina em centĆ­metros. (Em branco para predefinição)", + "pageHeight": "Altura da pĆ”gina em centĆ­metros. (Em branco para predefinição)", + "marginTop": "Margem superior da pĆ”gina em milĆ­metros. (Em branco para predefinição)", + "marginBottom": "Margem inferior da pĆ”gina em milĆ­metros. (Em branco para predefinição)", + "marginLeft": "Margem esquerda da pĆ”gina em milĆ­metros. (Em branco para predefinição)", + "marginRight": "Margem direita da pĆ”gina em milĆ­metros. (Em branco para predefinição)", + "printBackground": "Renderizar o fundo dos websites.", + "defaultHeader": "Ativar CabeƧalho Predefinido (Nome e nĆŗmero de pĆ”gina)", + "cssMediaType": "Alterar o tipo de media CSS da pĆ”gina.", + "none": "Nenhum", + "print": "Imprimir", + "screen": "EcrĆ£" + }, + "MarkdownToPDF": { + "tags": "marcação,conteĆŗdo-web,transformação,converter", + "title": "Markdown Para PDF", + "header": "Markdown Para PDF", + "submit": "Converter", + "help": "Trabalho em progresso", + "credit": "Usa WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "informação,dados,estatĆ­sticas,estatĆ­sticas", + "title": "Obter Informação do PDF", + "header": "Obter Informação do PDF", + "submit": "Obter Informação", + "downloadJson": "Transferir JSON" + }, + "extractPage": { + "tags": "extrair" + }, + "PdfToSinglePage": { + "tags": "pĆ”gina Ćŗnica" + }, + "showJS": { + "tags": "JS", + "title": "Mostrar Javascript", + "header": "Mostrar Javascript", + "downloadJS": "Transferir Javascript", + "submit": "Mostrar" + }, + "autoRedact": { + "tags": "Redação,Ocultar,ocultar,preto,marcador,oculto", + "title": "Redação AutomĆ”tica", + "header": "Redação AutomĆ”tica", + "colorLabel": "Cor", + "textsToRedactLabel": "Texto a redactar (separado por linhas)", + "textsToRedactPlaceholder": "ex. \\nConfidencial \\nTop-Secret", + "useRegexLabel": "Usar Regex", + "wholeWordSearchLabel": "Pesquisa de Palavra Completa", + "customPaddingLabel": "Preenchimento Extra Personalizado", + "convertPDFToImageLabel": "Converter PDF para PDF-Imagem (Usado para remover texto por trĆ”s da caixa)", + "submitButton": "Submeter" + }, + "redact": { + "tags": "Redação,Ocultar,ocultar,preto,marcador,oculto,manual", + "title": "Redação Manual", + "header": "Redação Manual", + "submit": "Redactar", + "textBasedRedaction": "Redação baseada em Texto", + "pageBasedRedaction": "Redação baseada em PĆ”gina", + "convertPDFToImageLabel": "Converter PDF para PDF-Imagem (Usado para remover texto por trĆ”s da caixa)", + "pageRedactionNumbers": { + "title": "PĆ”ginas", + "placeholder": "(ex. 1,2,8 ou 4,7,12-16 ou 2n-1)" + }, + "redactionColor": { + "title": "Cor de Redação" + }, + "export": "Exportar", + "upload": "Carregar", + "boxRedaction": "Redação por desenho de caixa", + "zoom": "Zoom", + "zoomIn": "Aumentar zoom", + "zoomOut": "Diminuir zoom", + "nextPage": "Próxima PĆ”gina", + "previousPage": "PĆ”gina Anterior", + "toggleSidebar": "Alternar Barra Lateral", + "showThumbnails": "Mostrar Miniaturas", + "showDocumentOutline": "Mostrar Esquema do Documento (duplo clique para expandir/colapsar todos os itens)", + "showAttatchments": "Mostrar Anexos", + "showLayers": "Mostrar Camadas (duplo clique para repor todas as camadas para o estado predefinido)", + "colourPicker": "Seletor de Cor", + "findCurrentOutlineItem": "Encontrar item atual do esquema", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,Extração de Tabela,extrair,converter" + }, + "autoSizeSplitPDF": { + "tags": "pdf,dividir,documento,organização" + }, + "overlay-pdfs": { + "tags": "Sobrepor", + "header": "Sobrepor Ficheiros PDF", + "baseFile": { + "label": "Selecione Ficheiro PDF Base" + }, + "overlayFiles": { + "label": "Selecione Ficheiros PDF de Sobreposição" + }, + "mode": { + "label": "Selecione Modo de Sobreposição", + "sequential": "Sobreposição Sequencial", + "interleaved": "Sobreposição Intercalada", + "fixedRepeat": "Sobreposição de Repetição Fixa" + }, + "counts": { + "label": "Contagens de Sobreposição (para Modo de Repetição Fixa)", + "placeholder": "Introduza contagens separadas por vĆ­rgulas (ex., 2,3,1)" + }, + "position": { + "label": "Selecione Posição de Sobreposição", + "foreground": "Primeiro Plano", + "background": "Plano de Fundo" + }, + "submit": "Submeter" + }, + "split-by-sections": { + "tags": "Dividir Secção, Dividir, Personalizar", + "title": "Dividir PDF por SecƧƵes", + "header": "Dividir PDF em SecƧƵes", + "horizontal": { + "label": "DivisƵes Horizontais", + "placeholder": "Introduza nĆŗmero de divisƵes horizontais" + }, + "vertical": { + "label": "DivisƵes Verticais", + "placeholder": "Introduza nĆŗmero de divisƵes verticais" + }, + "submit": "Dividir PDF", + "merge": "Juntar Num Único PDF" + }, + "AddStampRequest": { + "tags": "Carimbo, Adicionar imagem, imagem central, Marca de Ć”gua, PDF, Incorporar, Personalizar", + "header": "Carimbar PDF", + "title": "Carimbar PDF", + "stampType": "Tipo de Carimbo", + "stampText": "Texto do Carimbo", + "stampImage": "Imagem do Carimbo", + "alphabet": "Alfabeto", + "fontSize": "Tamanho da Fonte/Imagem", + "rotation": "Rotação", + "opacity": "Opacidade", + "position": "Posição", + "overrideX": "Sobrepor Coordenada X", + "overrideY": "Sobrepor Coordenada Y", + "customMargin": "Margem Personalizada", + "customColor": "Cor de Texto Personalizada", + "submit": "Submeter" + }, + "removeImagePdf": { + "tags": "Remover Imagem,operaƧƵes de pĆ”gina,lado servidor" + }, + "splitPdfByChapters": { + "tags": "dividir,capĆ­tulos,marcadores,organizar" + }, + "validateSignature": { + "tags": "assinatura,verificar,validar,pdf,certificado,assinatura digital,Validar Assinatura,Validar certificado", + "title": "Validar Assinaturas PDF", + "header": "Validar Assinaturas Digitais", + "selectPDF": "Selecionar ficheiro PDF assinado", + "submit": "Validar Assinaturas", + "results": "Resultados da Validação", + "status": { + "_value": "Estado", + "valid": "VĆ”lida", + "invalid": "InvĆ”lida" + }, + "signer": "Assinante", + "date": "Data", + "reason": "RazĆ£o", + "location": "Localização", + "noSignatures": "Nenhuma assinatura digital encontrada neste documento", + "chain": { + "invalid": "Falha na validação da cadeia de certificados - nĆ£o Ć© possĆ­vel verificar a identidade do assinante" + }, + "trust": { + "invalid": "Certificado nĆ£o estĆ” na loja de confianƧa - a fonte nĆ£o pode ser verificada" + }, + "cert": { + "expired": "O certificado expirou", + "revoked": "O certificado foi revogado", + "info": "Detalhes do Certificado", + "issuer": "Emissor", + "subject": "Assunto", + "serialNumber": "NĆŗmero de SĆ©rie", + "validFrom": "VĆ”lido Desde", + "validUntil": "VĆ”lido AtĆ©", + "algorithm": "Algoritmo", + "keySize": "Tamanho da Chave", + "version": "VersĆ£o", + "keyUsage": "Utilização da Chave", + "selfSigned": "Auto-Assinado", + "bits": "bits" + }, + "signature": { + "info": "Informação da Assinatura", + "_value": "Assinatura", + "mathValid": "A assinatura Ć© matematicamente vĆ”lida MAS:" + }, + "selectCustomCert": "Ficheiro de Certificado Personalizado X.509 (Opcional)" + }, + "replace-color": { + "title": "Substituir-Inverter-Cor", + "header": "Substituir-Inverter Cor PDF", + "selectText": { + "1": "OpƧƵes de Substituir ou Inverter cor", + "2": "Predefinição(Cores de alto contraste predefinidas)", + "3": "Personalizado(Cores personalizadas)", + "4": "InversĆ£o Total(Inverter todas as cores)", + "5": "OpƧƵes de cor de alto contraste", + "6": "texto branco em fundo preto", + "7": "Texto preto em fundo branco", + "8": "Texto amarelo em fundo preto", + "9": "Texto verde em fundo preto", + "10": "Escolher cor do texto", + "11": "Escolher cor do fundo" + }, + "submit": "Substituir" + }, + "replaceColorPdf": { + "tags": "Substituir Cor,operaƧƵes de pĆ”gina,Back end,lado servidor" + }, + "login": { + "title": "Iniciar sessĆ£o", + "header": "Iniciar sessĆ£o", + "signin": "Iniciar sessĆ£o", + "rememberme": "Lembrar-me", + "invalid": "Nome de utilizador ou palavra-passe invĆ”lidos.", + "locked": "A sua conta foi bloqueada.", + "signinTitle": "Por favor inicie sessĆ£o", + "ssoSignIn": "Login via Single Sign-on", + "oAuth2AutoCreateDisabled": "Criação AutomĆ”tica de Utilizador OAUTH2 Desativada", + "oAuth2AdminBlockedUser": "O registo ou login de utilizadores nĆ£o registados estĆ” atualmente bloqueado. Por favor contacte o administrador.", + "oauth2RequestNotFound": "Pedido de autorização nĆ£o encontrado", + "oauth2InvalidUserInfoResponse": "Resposta de Informação de Utilizador InvĆ”lida", + "oauth2invalidRequest": "Pedido InvĆ”lido", + "oauth2AccessDenied": "Acesso Negado", + "oauth2InvalidTokenResponse": "Resposta de Token InvĆ”lida", + "oauth2InvalidIdToken": "Token de Id InvĆ”lido", + "relyingPartyRegistrationNotFound": "Nenhum registo de relying party encontrado", + "userIsDisabled": "O utilizador estĆ” desativado, o login estĆ” atualmente bloqueado com este nome de utilizador. Por favor contacte o administrador.", + "alreadyLoggedIn": "JĆ” tem sessĆ£o iniciada em", + "alreadyLoggedIn2": "dispositivos. Por favor termine sessĆ£o nesses dispositivos e tente novamente.", + "toManySessions": "Tem demasiadas sessƵes ativas", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF Para PĆ”gina Única", + "header": "PDF Para PĆ”gina Única", + "submit": "Converter Para PĆ”gina Única" + }, + "pageExtracter": { + "title": "Extrair PĆ”ginas", + "header": "Extrair PĆ”ginas", + "submit": "Extrair", + "placeholder": "(ex. 1,2,8 ou 4,7,12-16 ou 2n-1)" + }, + "sanitizePDF": { + "title": "Sanitizar PDF", + "header": "Sanitizar um ficheiro PDF", + "selectText": { + "1": "Remover aƧƵes JavaScript", + "2": "Remover ficheiros incorporados", + "3": "Remove XMP metadata", + "4": "Remover ligaƧƵes", + "5": "Remover tipos de letra", + "6": "Remove Document Info Metadata" + }, + "submit": "Sanitizar PDF" + }, + "adjustContrast": { + "title": "Ajustar Contraste", + "header": "Ajustar Contraste", + "contrast": "Contraste:", + "brightness": "Brilho:", + "saturation": "Saturação:", + "download": "Transferir" + }, + "compress": { + "title": "Comprimir", + "header": "Comprimir PDF", + "credit": "Este serviƧo usa qpdf para CompressĆ£o/Otimização de PDF.", + "grayscale": { + "label": "Aplicar escala de cinzentos para compressĆ£o" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "NĆ­vel de otimização:", + "4": "Modo automĆ”tico - Ajusta automaticamente a qualidade para obter o PDF com o tamanho exato", + "5": "Tamanho esperado do PDF (ex. 25MB, 10.8MB, 25KB)" + }, + "submit": "Comprimir" + }, + "decrypt": { + "passwordPrompt": "Este ficheiro estĆ” protegido por palavra-passe. Por favor introduza a palavra-passe:", + "cancelled": "Operação cancelada para PDF: {0}", + "noPassword": "Nenhuma palavra-passe fornecida para PDF encriptado: {0}", + "invalidPassword": "Por favor tente novamente com a palavra-passe correta.", + "invalidPasswordHeader": "Palavra-passe incorreta ou encriptação nĆ£o suportada para PDF: {0}", + "unexpectedError": "Ocorreu um erro ao processar o ficheiro. Por favor tente novamente.", + "serverError": "Erro do servidor ao desencriptar: {0}", + "success": "Ficheiro desencriptado com sucesso." + }, + "multiTool-advert": { + "message": "Esta funcionalidade tambĆ©m estĆ” disponĆ­vel na nossa pĆ”gina multi-ferramenta. Experimente para uma interface melhorada pĆ”gina a pĆ”gina e funcionalidades adicionais!" + }, + "pageRemover": { + "title": "Removedor de PĆ”gina", + "header": "Removedor de PĆ”gina PDF", + "pagesToDelete": "PĆ”ginas a eliminar (Introduza uma lista de nĆŗmeros de pĆ”gina separados por vĆ­rgulas):", + "submit": "Eliminar PĆ”ginas", + "placeholder": "(ex. 1,2,6 ou 1-10,15-30)" + }, + "imageToPDF": { + "title": "Imagem para PDF", + "header": "Imagem para PDF", + "submit": "Converter", + "selectLabel": "OpƧƵes de Ajuste de Imagem", + "fillPage": "Preencher PĆ”gina", + "fitDocumentToImage": "Ajustar PĆ”gina Ć  Imagem", + "maintainAspectRatio": "Manter ProporƧƵes", + "selectText": { + "2": "Rodar PDF automaticamente", + "3": "Lógica de mĆŗltiplos ficheiros (Apenas ativada se trabalhar com mĆŗltiplas imagens)", + "4": "Juntar num Ćŗnico PDF", + "5": "Converter para PDFs separados" + } + }, + "PDFToCSV": { + "title": "PDF para CSV", + "header": "PDF para CSV", + "prompt": "Escolha a pĆ”gina para extrair tabela", + "submit": "Extrair" + }, + "split-by-size-or-count": { + "title": "Dividir PDF por Tamanho ou Contagem", + "header": "Dividir PDF por Tamanho ou Contagem", + "type": { + "label": "Selecione Tipo de DivisĆ£o", + "size": "Por Tamanho", + "pageCount": "Por Contagem de PĆ”ginas", + "docCount": "Por Contagem de Documentos" + }, + "value": { + "label": "Introduzir Valor", + "placeholder": "Introduza tamanho (ex., 2MB ou 3KB) ou contagem (ex., 5)" + }, + "submit": "Submeter" + }, + "printFile": { + "title": "Imprimir Ficheiro", + "header": "Imprimir Ficheiro para Impressora", + "selectText": { + "1": "Selecione Ficheiro para Imprimir", + "2": "Introduza Nome da Impressora" + }, + "submit": "Imprimir" + }, + "licenses": { + "nav": "LicenƧas", + "title": "LicenƧas de Terceiros", + "header": "LicenƧas de Terceiros", + "module": "Módulo", + "version": "VersĆ£o", + "license": "LicenƧa" + }, + "survey": { + "nav": "InquĆ©rito", + "title": "InquĆ©rito Stirling-PDF", + "description": "O Stirling-PDF nĆ£o tem rastreamento por isso queremos ouvir os nossos utilizadores para melhorar o Stirling-PDF!", + "changes": "O Stirling-PDF mudou desde o Ćŗltimo inquĆ©rito! Para saber mais por favor veja a nossa publicação no blog aqui:", + "changes2": "Com estas mudanƧas estamos a receber suporte empresarial pago e financiamento", + "please": "Por favor considere participar no nosso inquĆ©rito!", + "disabled": "(A janela pop-up do inquĆ©rito serĆ” desativada nas atualizaƧƵes seguintes mas estarĆ” disponĆ­vel no rodapĆ© da pĆ”gina)", + "button": "Participar no InquĆ©rito", + "dontShowAgain": "NĆ£o mostrar novamente", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Remover imagem", + "header": "Remover imagem", + "removeImage": "Remover imagem", + "submit": "Remover imagem" + }, + "splitByChapters": { + "title": "Dividir PDF por CapĆ­tulos", + "header": "Dividir PDF por CapĆ­tulos", + "bookmarkLevel": "NĆ­vel de Marcador", + "includeMetadata": "Incluir Metadados", + "allowDuplicates": "Permitir Duplicados", + "desc": { + "1": "Esta ferramenta divide um ficheiro PDF em mĆŗltiplos PDFs baseado na sua estrutura de capĆ­tulos.", + "2": "NĆ­vel de Marcador: Escolha o nĆ­vel de marcadores a usar para dividir (0 para nĆ­vel superior, 1 para segundo nĆ­vel, etc.).", + "3": "Incluir Metadados: Se selecionado, os metadados do PDF original serĆ£o incluĆ­dos em cada PDF dividido.", + "4": "Permitir Duplicados: Se selecionado, permite que mĆŗltiplos marcadores na mesma pĆ”gina criem PDFs separados." + }, + "submit": "Dividir PDF" + }, + "fileChooser": { + "click": "Clicar", + "or": "ou", + "dragAndDrop": "Arrastar e Largar", + "dragAndDropPDF": "Arrastar e Largar ficheiro PDF", + "dragAndDropImage": "Arrastar e Largar ficheiro de Imagem", + "hoveredDragAndDrop": "Arrastar e Largar ficheiro(s) aqui", + "extractPDF": "Extraindo..." + }, + "releases": { + "footer": "LanƧamentos", + "title": "Notas de LanƧamento", + "header": "Notas de LanƧamento", + "current": { + "version": "LanƧamento Atual" + }, + "note": "Notas de lanƧamento apenas disponĆ­veis em InglĆŖs" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/ro-RO/translation.json b/frontend/public/locales/ro-RO/translation.json new file mode 100644 index 000000000..4e22c0cc3 --- /dev/null +++ b/frontend/public/locales/ro-RO/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Dimensiune Font", + "fontName": "Nume Font", + "title": "Adaugă Numere de Pagină", + "header": "Adaugă Numere de Pagină", + "selectText": { + "1": "Selectează fișierul PDF:", + "2": "Dimensiunea Marginii", + "3": "Poziție", + "4": "Număr de Start", + "5": "Pagini de Numerotat", + "6": "Text Personalizat" + }, + "customTextDesc": "Text Personalizat", + "numberPagesDesc": "Ce pagini să numeroteze, implicit 'toate', acceptă și 1-5 sau 2,5,9 etc", + "customNumberDesc": "Implicit la {n}, acceptă și 'Pagina {n} din {total}', 'Text-{n}', '{nume_fisier}-{n}", + "submit": "Adaugă Numere de Pagină" + }, + "pdfPrompt": "Selectează fișiere PDF", + "multiPdfPrompt": "Selectează mai multe fișiere PDF (2+)", + "multiPdfDropPrompt": "Selectează (sau trage și plasează) toate fișierele PDF de care ai nevoie", + "imgPrompt": "Selectează imagini", + "genericSubmit": "Trimite", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Avertisment: Acest proces poate dura pĆ¢nă la un minut Ć®n funcție de dimensiunea fișierului", + "pageOrderPrompt": "Ordinea paginilor (Introdu o listă separată prin virgulă de numere de pagină):", + "pageSelectionPrompt": "Selecție Personalizată de Pagini (Introduceți o listă separată prin virgule a numerelor de pagini 1,5,6 sau funcții precum 2n+1) :", + "goToPage": "Mergi la pagină", + "true": "Adevărat", + "false": "Fals", + "unknown": "Necunoscut", + "save": "Salvează", + "saveToBrowser": "Salvează Ć®n Browser", + "close": "Ǝnchide", + "filesSelected": "fișiere selectate", + "noFavourites": "Niciun favorit adăugat", + "downloadComplete": "Descărcare Completă", + "bored": "Plictisit așteptĆ¢nd?", + "alphabet": "Alfabet", + "downloadPdf": "Descarcă PDF", + "text": "Text", + "font": "Font", + "selectFillter": "-- Selectează --", + "pageNum": "Numărul paginii", + "sizes": { + "small": "Mic", + "medium": "Mediu", + "large": "Mare", + "x-large": "Foarte Mare" + }, + "error": { + "pdfPassword": "Documentul PDF este protejat cu parolă și fie parola nu a fost furnizată, fie a fost incorectă", + "_value": "Eroare", + "sorry": "Ne pare rău pentru problemă!", + "needHelp": "Ai nevoie de ajutor / Ai găsit o problemă?", + "contactTip": "Dacă Ć®ntĆ¢mpini Ć®n continuare dificultăți, nu ezita să ne contactezi pentru ajutor. Poți deschide un tichet pe pagina noastră GitHub sau ne poți contacta prin Discord:", + "404": { + "head": "404 - Pagina nu a fost găsită | Ups, ne-am Ć®mpiedicat Ć®n cod!", + "1": "Nu putem găsi pagina pe care o cauți.", + "2": "Ceva nu a mers bine" + }, + "github": "Deschide un tichet pe GitHub", + "showStack": "Arată Urmărirea Stivei", + "copyStack": "Copiază Urmărirea Stivei", + "githubSubmit": "GitHub - Deschide un tichet", + "discordSubmit": "Discord - Trimite o postare de Suport" + }, + "delete": "Șterge", + "username": "Nume de utilizator", + "password": "Parolă", + "welcome": "Bun venit", + "property": "Proprietate", + "black": "Negru", + "white": "Alb", + "red": "Roșu", + "green": "Verde", + "blue": "Albastru", + "custom": "Personalizat...", + "WorkInProgess": "Lucru Ć®n curs, S-ar putea să nu funcționeze sau să aibă erori, Vă rugăm să raportați orice probleme!", + "poweredBy": "Propulsat de", + "yes": "Da", + "no": "Nu", + "changedCredsMessage": "Credențialele au fost schimbate!", + "notAuthenticatedMessage": "Utilizatorul nu este autentificat.", + "userNotFoundMessage": "Utilizatorul nu a fost găsit.", + "incorrectPasswordMessage": "Parola curentă este incorectă.", + "usernameExistsMessage": "Noul nume de utilizator există deja.", + "invalidUsernameMessage": "Nume de utilizator invalid, numele de utilizator poate conține doar litere, numere și următoarele caractere speciale @._+- sau trebuie să fie o adresă de email validă.", + "invalidPasswordMessage": "Parola nu trebuie să fie goală și nu trebuie să aibă spații la Ć®nceput sau la sfĆ¢rșit.", + "confirmPasswordErrorMessage": "Noua Parolă și Confirmarea Noii Parole trebuie să se potrivească.", + "deleteCurrentUserMessage": "Nu se poate șterge utilizatorul conectat Ć®n prezent.", + "deleteUsernameExistsMessage": "Numele de utilizator nu există și nu poate fi șters.", + "downgradeCurrentUserMessage": "Rolul utilizatorului curent nu poate fi retrogradat", + "disabledCurrentUserMessage": "Utilizatorul curent nu poate fi dezactivat", + "downgradeCurrentUserLongMessage": "Rolul utilizatorului curent nu poate fi retrogradat. Prin urmare, utilizatorul curent nu va fi afișat.", + "userAlreadyExistsOAuthMessage": "Utilizatorul există deja ca utilizator OAuth2.", + "userAlreadyExistsWebMessage": "Utilizatorul există deja ca utilizator web.", + "oops": "Ups!", + "help": "Ajutor", + "goHomepage": "Mergi la Pagina de Start", + "joinDiscord": "Alătură-te serverului nostru Discord", + "seeDockerHub": "Vezi Docker Hub", + "visitGithub": "Vizitează Depozitul Github", + "donate": "Donează", + "color": "Culoare", + "sponsor": "Sponsor", + "info": "Informații", + "pro": "Pro", + "page": "Page", + "pages": "Pages", + "loading": "Loading...", + "addToDoc": "Add to Document", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Privacy Policy", + "terms": "Terms and Conditions", + "accessibility": "Accessibility", + "cookie": "Cookie Policy", + "impressum": "Impressum", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Meniu Pipeline (Beta)", + "uploadButton": "Ǝncarcă Personalizat", + "configureButton": "Configurează", + "defaultOption": "Personalizat", + "submitButton": "Trimite", + "help": "Ajutor Pipeline", + "scanHelp": "Ajutor pentru Scanarea Dosarului", + "deletePrompt": "Sigur doriți să ștergeți pipeline-ul", + "tags": "automatizează,secvență,scriptare,procesare-lot", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Configurare Pipeline", + "pipelineNameLabel": "Nume Pipeline", + "saveSettings": "Salvează Setările Operației", + "pipelineNamePrompt": "Introduceți numele pipeline-ului aici", + "selectOperation": "Selectați Operația", + "addOperationButton": "Adaugă operație", + "pipelineHeader": "Pipeline:", + "saveButton": "Descarcă", + "validateButton": "Validează" + }, + "enterpriseEdition": { + "button": "Upgrade to Pro", + "warning": "This feature is only available to Pro users.", + "yamlAdvert": "Stirling PDF Pro supports YAML configuration files and other SSO features.", + "ssoAdvert": "Looking for more user management features? Check out Stirling PDF Pro" + }, + "analytics": { + "title": "Do you want make Stirling PDF better?", + "paragraph1": "Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.", + "paragraph2": "Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.", + "enable": "Enable analytics", + "disable": "Disable analytics", + "settings": "You can change the settings for analytics in the config/settings.yml file" + }, + "navbar": { + "favorite": "Favorite", + "recent": "New and recently updated", + "darkmode": "Mod Ć®ntunecat", + "language": "Limbi", + "settings": "Setări", + "allTools": "Instrumente", + "multiTool": "Instrumente Multiple", + "search": "Search", + "sections": { + "organize": "Organizează", + "convertTo": "Convertește Ć®n PDF", + "convertFrom": "Convertește din PDF", + "security": "Semnează & Securitate", + "advance": "Avansat", + "edit": "Vizualizează & Editează", + "popular": "Popular" + } + }, + "settings": { + "title": "Setări", + "update": "Actualizare disponibilă", + "updateAvailable": "{0} este versiunea instalată curent. O nouă versiune ({1}) este disponibilă.", + "appVersion": "Versiune aplicație:", + "downloadOption": { + "title": "Alege opțiunea de descărcare (pentru descărcarea unui singur fișier non-zip):", + "1": "Deschide Ć®n aceeași fereastră", + "2": "Deschide Ć®ntr-o fereastră nouă", + "3": "Descarcă fișierul" + }, + "zipThreshold": "Ǝmpachetează fișierele cĆ¢nd numărul de fișiere descărcate depășește", + "signOut": "Deconectare", + "accountSettings": "Setări Cont", + "bored": { + "help": "Activează jocul easter egg" + }, + "cacheInputs": { + "name": "Salvează intrările formularului", + "help": "Activează pentru a stoca intrările utilizate anterior pentru rulări viitoare" + } + }, + "changeCreds": { + "title": "Schimbă Credențialele", + "header": "Actualizează Detaliile Contului Tău", + "changePassword": "Utilizezi credențiale de conectare implicite. Te rugăm să introduci o nouă parolă", + "newUsername": "Nume de Utilizator Nou", + "oldPassword": "Parola Curentă", + "newPassword": "Parolă Nouă", + "confirmNewPassword": "Confirmă Parola Nouă", + "submit": "Trimite Modificările" + }, + "account": { + "title": "Setări Cont", + "accountSettings": "Setări Cont", + "adminSettings": "Setări Admin - Vizualizează și Adaugă Utilizatori", + "userControlSettings": "Setări Control Utilizator", + "changeUsername": "Schimbă Numele de Utilizator", + "newUsername": "Nume de Utilizator Nou", + "password": "Parolă de Confirmare", + "oldPassword": "Parola veche", + "newPassword": "Parolă Nouă", + "changePassword": "Schimbă Parola", + "confirmNewPassword": "Confirmă Parola Nouă", + "signOut": "Deconectare", + "yourApiKey": "Cheia ta API", + "syncTitle": "Sincronizează setările browserului cu Contul", + "settingsCompare": "Comparație Setări:", + "property": "Proprietate", + "webBrowserSettings": "Setare Browser Web", + "syncToBrowser": "Sincronizează Cont -> Browser", + "syncToAccount": "Sincronizează Cont <- Browser" + }, + "adminUserSettings": { + "title": "Setări Control Utilizator", + "header": "Setări Control Utilizator Admin", + "admin": "Admin", + "user": "Utilizator", + "addUser": "Adaugă Utilizator Nou", + "deleteUser": "Șterge Utilizator", + "confirmDeleteUser": "Ar trebui șters utilizatorul?", + "confirmChangeUserStatus": "Ar trebui dezactivat/activat utilizatorul?", + "usernameInfo": "Numele de utilizator poate conține doar litere, numere și următoarele caractere speciale @._+- sau trebuie să fie o adresă de email validă.", + "roles": "Roluri", + "role": "Rol", + "actions": "Acțiuni", + "apiUser": "Utilizator API Limitat", + "extraApiUser": "Utilizator API Limitat Suplimentar", + "webOnlyUser": "Utilizator Doar Web", + "demoUser": "Utilizator Demo (Fără setări personalizate)", + "internalApiUser": "Utilizator API Intern", + "forceChange": "Forțează utilizatorul să schimbe parola la conectare", + "submit": "Salvează Utilizator", + "changeUserRole": "Schimbă rolul utilizatorului", + "authenticated": "Autentificat", + "editOwnProfil": "Editează propriul profil", + "enabledUser": "utilizator activat", + "disabledUser": "utilizator dezactivat", + "activeUsers": "Utilizatori Activi:", + "disabledUsers": "Utilizatori Dezactivați:", + "totalUsers": "Total Utilizatori:", + "lastRequest": "Ultima Cerere", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Import/Export Bază de Date", + "header": "Import/Export Bază de Date", + "fileName": "Nume Fișier", + "creationDate": "Data Creării", + "fileSize": "Dimensiune Fișier", + "deleteBackupFile": "Șterge Fișier de Backup", + "importBackupFile": "Importă Fișier de Backup", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Descarcă Fișier de Backup", + "info_1": "CĆ¢nd importați date, este crucial să vă asigurați de structura corectă. Dacă nu sunteți sigur de ceea ce faceți, cereți sfaturi și suport de la un profesionist. O eroare Ć®n structură poate cauza defecțiuni ale aplicației, pĆ¢nă la incapacitatea completă de a rula aplicația.", + "info_2": "Numele fișierului nu contează la Ć®ncărcare. Va fi redenumit ulterior pentru a urma formatul backup_user_aaaallzzoomm.sql, asigurĆ¢nd o convenție de denumire consecventă.", + "submit": "Importă Backup", + "importIntoDatabaseSuccessed": "Importul Ć®n baza de date a reușit", + "backupCreated": "Database backup successful", + "fileNotFound": "Fișierul nu a fost găsit", + "fileNullOrEmpty": "Fișierul nu trebuie să fie nul sau gol", + "failedImportFile": "Importul Fișierului a Eșuat", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "Your session has expired. Please refresh the page and try again.", + "refreshPage": "Refresh Page" + }, + "home": { + "desc": "Un singur punct de oprire găzduit local pentru toate nevoile tale legate de fișiere PDF.", + "searchBar": "Caută funcționalități...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Vizualizează, adnotează, adaugă text sau imagini" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "Instrument multiplu PDF", + "desc": "Unifică, rotește, rearanjează și elimină pagini" + }, + "merge": { + "title": "Unifică", + "desc": "Unifică cu ușurință mai multe fișiere PDF Ć®ntr-unul singur." + }, + "split": { + "title": "Desparte", + "desc": "Desparte fișierele PDF Ć®n mai multe documente." + }, + "rotate": { + "title": "Rotește", + "desc": "Rotește cu ușurință fișierele PDF." + }, + "imageToPdf": { + "title": "Imagine Ć®n PDF", + "desc": "Convertește o imagine (PNG, JPEG, GIF) Ć®n PDF." + }, + "pdfToImage": { + "title": "PDF Ć®n Imagine", + "desc": "Convertește un fișier PDF Ć®n imagine (PNG, JPEG, GIF)." + }, + "pdfOrganiser": { + "title": "Organizează", + "desc": "Elimină/rearanjează pagini Ć®n orice ordine" + }, + "addImage": { + "title": "Adaugă imagine", + "desc": "Adaugă o imagine Ć®ntr-o locație specifică pe PDF (Ć®n curs de dezvoltare)" + }, + "watermark": { + "title": "Adaugă Filigran", + "desc": "Adaugă un filigran personalizat la documentul PDF." + }, + "permissions": { + "title": "Schimbă permisiuni", + "desc": "Schimbă permisiunile documentului PDF" + }, + "removePages": { + "title": "Elimină", + "desc": "Șterge paginile nedorite din documentul PDF." + }, + "addPassword": { + "title": "Adaugă Parolă", + "desc": "Criptează documentul PDF cu o parolă." + }, + "removePassword": { + "title": "Elimină Parola", + "desc": "Elimină protecția cu parolă din documentul PDF." + }, + "compressPdfs": { + "title": "Comprimă", + "desc": "Comprimă fișierele PDF pentru a reduce dimensiunea lor." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Schimbă Metadatele", + "desc": "Schimbă/Elimină/Adaugă metadate Ć®ntr-un document PDF." + }, + "fileToPDF": { + "title": "Convertește fișierul Ć®n PDF", + "desc": "Convertește aproape orice fișier Ć®n format PDF (DOCX, PNG, XLS, PPT, TXT și altele)." + }, + "ocr": { + "title": "OCR / Curățare scanări", + "desc": "Curăță scanările și detectează textul din imaginile dintr-un PDF și Ć®l adaugă ca text." + }, + "extractImages": { + "title": "Extrage Imagini", + "desc": "Extrage toate imaginile dintr-un PDF și le salvează Ć®ntr-un fișier zip." + }, + "pdfToPDFA": { + "title": "PDF Ć®n PDF/A", + "desc": "Convertește un document PDF Ć®n format PDF/A pentru stocare pe termen lung." + }, + "PDFToWord": { + "title": "PDF Ć®n Word", + "desc": "Convertește un document PDF Ć®n formate Word (DOC, DOCX și ODT)." + }, + "PDFToPresentation": { + "title": "PDF Ć®n Prezentare", + "desc": "Convertește un document PDF Ć®n formate de prezentare (PPT, PPTX și ODP)." + }, + "PDFToText": { + "title": "PDF Ć®n Text/RTF", + "desc": "Convertește un document PDF Ć®n format Text sau RTF." + }, + "PDFToHTML": { + "title": "PDF Ć®n HTML", + "desc": "Convertește un document PDF Ć®n format HTML." + }, + "PDFToXML": { + "title": "PDF Ć®n XML", + "desc": "Convertește un document PDF Ć®n format XML." + }, + "ScannerImageSplit": { + "title": "Detectează/Ǝmparte poze scanate", + "desc": "Ǝmparte mai multe poze dintr-o poză/PDF." + }, + "sign": { + "title": "Semnează", + "desc": "Adaugă o semnătură la documentul PDF prin desenare, text sau imagine." + }, + "flatten": { + "title": "Nivelare", + "desc": "Elimină toate elementele interactive și formularele dintr-un PDF." + }, + "repair": { + "title": "Repară", + "desc": "Ǝncearcă să repare un document PDF corupt/defect." + }, + "removeBlanks": { + "title": "Elimină pagini goale", + "desc": "Detectează și elimină paginile goale dintr-un document." + }, + "removeAnnotations": { + "title": "Elimină Adnotările", + "desc": "Elimină toate comentariile/adnotările dintr-un PDF" + }, + "compare": { + "title": "Compară", + "desc": "Compară și arată diferențele dintre 2 documente PDF." + }, + "certSign": { + "title": "Semnare cu certificat", + "desc": "Semnează un PDF cu un certificat/cheie (PEM/P12)" + }, + "removeCertSign": { + "title": "Elimină Semnătura cu Certificat", + "desc": "Elimină semnătura cu certificat din PDF" + }, + "pageLayout": { + "title": "Aspect Multi-Pagină", + "desc": "Ǝmbină mai multe pagini ale unui document PDF Ć®ntr-o singură pagină" + }, + "scalePages": { + "title": "Ajustează dimensiunea/scala paginii", + "desc": "Modifică dimensiunea/scala paginii și/sau a conținutului său." + }, + "pipeline": { + "title": "Pipeline (Avansat)", + "desc": "Rulează multiple acțiuni pe PDF-uri definind scripturi pipeline" + }, + "add-page-numbers": { + "title": "Adaugă Numere de Pagină", + "desc": "Adaugă numere de pagină Ć®n tot documentul Ć®ntr-o locație setată" + }, + "auto-rename": { + "title": "Redenumire Automată Fișier PDF", + "desc": "Redenumește automat un fișier PDF bazat pe antetul detectat" + }, + "adjust-contrast": { + "title": "Ajustează Culorile/Contrastul", + "desc": "Ajustează Contrastul, Saturația și Luminozitatea unui PDF" + }, + "crop": { + "title": "Decupează PDF", + "desc": "Decupează un PDF pentru a-i reduce dimensiunea (menține textul!)" + }, + "autoSplitPDF": { + "title": "Desparte Automat Paginile", + "desc": "Desparte Automat PDF-ul Scanat cu separator fizic de pagini scanate cu Cod QR" + }, + "sanitizePdf": { + "title": "Igienizează", + "desc": "Elimină scripturile și alte elemente din fișierele PDF" + }, + "URLToPDF": { + "title": "URL/Website Ć®n PDF", + "desc": "Convertește orice URL http(s) Ć®n PDF" + }, + "HTMLToPDF": { + "title": "HTML Ć®n PDF", + "desc": "Convertește orice fișier HTML sau zip Ć®n PDF" + }, + "MarkdownToPDF": { + "title": "Markdown Ć®n PDF", + "desc": "Convertește orice fișier Markdown Ć®n PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "Obține TOATE Informațiile despre PDF", + "desc": "Extrage orice și toate informațiile posibile despre PDF-uri" + }, + "extractPage": { + "title": "Extrage pagină(i)", + "desc": "Extrage paginile selectate din PDF" + }, + "PdfToSinglePage": { + "title": "PDF Ć®ntr-o Singură Pagină Mare", + "desc": "Ǝmbină toate paginile PDF Ć®ntr-o singură pagină mare" + }, + "showJS": { + "title": "Arată Javascript", + "desc": "Caută și afișează orice JS injectat Ć®ntr-un PDF" + }, + "autoRedact": { + "title": "Redactare Automată", + "desc": "Redactează automat (Ć®nnegrește) text Ć®ntr-un PDF bazat pe textul de intrare" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF Ć®n CSV", + "desc": "Extrage Tabelele dintr-un PDF convertindu-l Ć®n CSV" + }, + "autoSizeSplitPDF": { + "title": "Despărțire Automată după Dimensiune/Număr", + "desc": "Ǝmparte un singur PDF Ć®n mai multe documente bazat pe dimensiune, număr de pagini sau număr de documente" + }, + "overlay-pdfs": { + "title": "Suprapune PDF-uri", + "desc": "Suprapune PDF-uri peste alt PDF" + }, + "split-by-sections": { + "title": "Ǝmparte PDF pe Secțiuni", + "desc": "Ǝmparte fiecare pagină a unui PDF Ć®n secțiuni mai mici orizontale și verticale" + }, + "AddStampRequest": { + "title": "Adaugă Ștampilă la PDF", + "desc": "Adaugă text sau adaugă ștampile imagine Ć®n locații setate" + }, + "removeImagePdf": { + "title": "Elimină imagine", + "desc": "Elimină imaginea din PDF pentru a reduce dimensiunea fișierului" + }, + "splitPdfByChapters": { + "title": "Split PDF by Chapters", + "desc": "Split a PDF into multiple files based on its chapter structure." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "replaceColorPdf": { + "title": "Replace and Invert Color", + "desc": "Replace color for text and background in PDF and invert full color of pdf to reduce file size" + } + }, + "viewPdf": { + "tags": "vizualizare,citește,adnotează,text,imagine", + "title": "View/Edit PDF", + "header": "Vizualizează PDF" + }, + "multiTool": { + "tags": "Instrument Multiplu,Operație multiplă,UI,clic tragere,front end,client side", + "title": "Instrument PDF multiplu", + "header": "Instrument PDF multiplu", + "uploadPrompts": "Nume Fișier", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "selectPages": "Page Select", + "selectedPages": "Selected Pages", + "page": "Page", + "deleteSelected": "Delete Selected", + "downloadAll": "Export", + "downloadSelected": "Export Selected", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "Page(s) Selected", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "unificare,Operații pagină,Back end,server side", + "title": "Unire", + "header": "Unirea mai multor PDF-uri (2+)", + "sortByName": "Sortează după nume", + "sortByDate": "Sortează după dată", + "removeCertSign": "Elimină semnătura digitală Ć®n fișierul unificat?", + "submit": "Unire" + }, + "split": { + "tags": "Operații pagină,divizare,Pagină Multiplă,tăiere,server side", + "title": "Ǝmparte PDF", + "header": "Ǝmparte PDF", + "desc": { + "1": "Numerele pe care le selectați reprezintă numărul paginii pe care doriți să o Ć®mpărțiți", + "2": "Prin urmare, selectĆ¢nd 1,3,7-9, un document cu 10 pagini va fi Ć®mpărțit Ć®n 6 PDF-uri separate, astfel:", + "3": "Documentul #1: Pagina 1", + "4": "Documentul #2: Paginile 2 și 3", + "5": "Documentul #3: Paginile 4, 5, 6 și 7", + "6": "Documentul #4: Pagina 8", + "7": "Documentul #5: Pagina 9", + "8": "Documentul #6: Pagina 10" + }, + "splitPages": "Introduceți paginile pe care să le Ć®mpărțiți:", + "submit": "Ǝmparte" + }, + "rotate": { + "tags": "server side", + "title": "Rotește PDF", + "header": "Rotește PDF", + "selectAngle": "Selectați un unghi de rotație (Ć®n multiplicate de 90 de grade):", + "submit": "Rotește" + }, + "imageToPdf": { + "tags": "conversie,img,jpg,poză,fotografie" + }, + "pdfToImage": { + "tags": "conversie,img,jpg,poză,fotografie", + "title": "PDF Ć®n Imagine", + "header": "PDF Ć®n Imagine", + "selectText": "Format imagine", + "singleOrMultiple": "Tip rezultat imagine", + "single": "O singură imagine mare", + "multi": "Mai multe imagini", + "colorType": "Tip culoare", + "color": "Culoare", + "grey": "Scală de gri", + "blackwhite": "Alb și negru (Poate pierde date!)", + "submit": "Convertește", + "info": "Python nu este instalat. Necesar pentru conversia WebP.", + "placeholder": "(ex. 1,2,8 sau 4,7,12-16 sau 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,par,impar,sortează,mută", + "title": "Organizator de pagini", + "header": "Organizator de pagini PDF", + "submit": "Rearanjați paginile", + "mode": { + "_value": "Mod", + "1": "Ordine Personalizată a Paginilor", + "2": "Ordine Inversă", + "3": "Sortare Duplex", + "4": "Sortare Broșură", + "5": "Sortare Broșură cu Coasere Laterală", + "6": "Separare Impar-Par", + "7": "Elimină Prima", + "8": "Elimină Ultima", + "9": "Elimină Prima și Ultima", + "10": "Ǝmbinare Impar-Par", + "11": "Duplicate all pages" + }, + "placeholder": "(ex. 1,3,2 sau 4-8,2,10-12 sau 2n-1)" + }, + "addImage": { + "tags": "img,jpg,poză,fotografie", + "title": "Adăugare imagine", + "header": "Adăugare imagine Ć®n PDF", + "everyPage": "Pe fiecare pagină?", + "upload": "Adăugare imagine", + "submit": "Adăugare imagine" + }, + "watermark": { + "tags": "Text,repetitiv,etichetă,propriu,drepturi de autor,marcă comercială,img,jpg,poză,fotografie", + "title": "Adaugă Filigran", + "header": "Adaugă Filigran", + "customColor": "Culoare Text Personalizată", + "selectText": { + "1": "Selectează PDF-ul la care să adaugi filigranul:", + "2": "Textul Filigranului:", + "3": "Mărimea fontului:", + "4": "Rotire (0-360):", + "5": "Spațiere lățime (Spațiu Ć®ntre fiecare filigran pe orizontală):", + "6": "Spațiere Ć®nălțime (Spațiu Ć®ntre fiecare filigran pe verticală):", + "7": "Opacitate (0% - 100%):", + "8": "Tip Filigran:", + "9": "Imagine Filigran:", + "10": "Convertește PDF Ć®n PDF-Imagine" + }, + "submit": "Adaugă Filigran", + "type": { + "1": "Text", + "2": "Imagine" + } + }, + "permissions": { + "tags": "citește,scrie,editează,tipărește", + "title": "Schimbă Permisiunile", + "header": "Schimbă Permisiunile", + "warning": "Pentru a face aceste permisiuni neschimbabile, se recomandă să le setezi cu o parolă prin intermediul paginii de adăugare a parolei", + "selectText": { + "1": "Selectează PDF-ul pentru a schimba permisiunile", + "2": "Permisiunile de setat", + "3": "Previne asamblarea documentului", + "4": "Previne extragerea conținutului", + "5": "Previne extragerea pentru accesibilitate", + "6": "Previne completarea formularului", + "7": "Previne modificarea", + "8": "Previne modificarea adnotărilor", + "9": "Previne tipărirea", + "10": "Previne tipărirea Ć®n formate diferite" + }, + "submit": "Schimbă" + }, + "removePages": { + "tags": "Elimină pagini,șterge pagini" + }, + "addPassword": { + "tags": "securizează,securitate", + "title": "Adaugă parolă", + "header": "Adaugă o parolă (Criptare)", + "selectText": { + "1": "Selectează PDF-ul pentru criptare", + "2": "Parolă", + "3": "Lungime cheie de criptare", + "4": "Valori mai mari sunt mai puternice, dar valorile mai mici au o compatibilitate mai bună.", + "5": "Permisiuni de setare", + "6": "Previne asamblarea documentului", + "7": "Previne extragerea conținutului", + "8": "Previne extragerea pentru accesibilitate", + "9": "Previne completarea formularului", + "10": "Previne modificarea", + "11": "Previne modificarea adnotărilor", + "12": "Previne tipărirea", + "13": "Previne tipărirea Ć®n formate diferite", + "14": "Parolă Proprietar", + "15": "Restricționează ce se poate face cu documentul odată ce este deschis (Nu este suportat de toate programele de citire)", + "16": "Restricționează deschiderea documentului Ć®n sine" + }, + "submit": "Criptează" + }, + "removePassword": { + "tags": "securizează,Decriptează,securitate,elimină parola,șterge parola", + "title": "Elimină parola", + "header": "Elimină parola (Decodifică)", + "selectText": { + "1": "Selectează PDF-ul pentru decodificare", + "2": "Parolă" + }, + "submit": "Elimină" + }, + "compressPdfs": { + "tags": "comprimă,mic,minuscul" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Titlu,autor,dată,creare,timp,editor", + "title": "Titlu:", + "header": "Schimbă Metadatele", + "selectText": { + "1": "Te rugăm să editezi variabilele pe care dorești să le schimbi", + "2": "Șterge toate metadatele", + "3": "Afișează Metadatele Personalizate:", + "4": "Alte Metadate:", + "5": "Adaugă Intrare Metadate Personalizate" + }, + "author": "Autor:", + "creationDate": "Data creării (aaaa/LL/zz OO:mm:ss):", + "creator": "Creator:", + "keywords": "Cuvinte cheie:", + "modDate": "Data modificării (aaaa/LL/zz OO:mm:ss):", + "producer": "Producător:", + "subject": "Subiect:", + "trapped": "Blocat:", + "submit": "Schimbă" + }, + "fileToPDF": { + "tags": "transformare,format,document,poză,diapozitiv,text,conversie,office,docs,word,excel,powerpoint", + "title": "Fișier Ć®n PDF", + "header": "Convertiți orice fișier Ć®n PDF", + "credit": "Acest serviciu utilizează LibreOffice și Unoconv pentru conversia fișierelor.", + "supportedFileTypesInfo": "Tipuri de fișiere suportate", + "supportedFileTypes": "Tipurile de fișiere suportate ar trebui să includă cele de mai jos. Pentru o listă completă și actualizată a formatelor suportate, consultați documentația LibreOffice.", + "submit": "Convertiți Ć®n PDF" + }, + "ocr": { + "tags": "recunoaștere,text,imagine,scanare,citește,identifică,detectare,editabil", + "title": "OCR / Curățare scanare", + "header": "Curățare scanări / OCR (Recunoaștere optică a caracterelor)", + "selectText": { + "1": "Selectați limbile care trebuie detectate Ć®n PDF (Cele listate sunt cele detectate Ć®n prezent):", + "2": "Produceți un fișier text care conține textul OCR Ć®mpreună cu PDF-ul OCR", + "3": "Corectați paginile care au fost scanate Ć®n unghi Ć®nclinat prin rotirea lor Ć®n poziție corectă", + "4": "Curățați pagina astfel Ć®ncĆ¢t să fie mai puțin probabil ca OCR-ul să găsească text Ć®n zgomotul de fundal. (Nu se schimbă rezultatul)", + "5": "Curățați pagina astfel Ć®ncĆ¢t să fie mai puțin probabil ca OCR-ul să găsească text Ć®n zgomotul de fundal, menține curățarea Ć®n rezultat.", + "6": "Ignorați paginile care conțin text interactiv, OCR-ul se aplică doar paginilor care sunt imagini", + "7": "Forțează OCR-ul, va aplica OCR pe fiecare pagină, Ć®nlăturĆ¢nd toate elementele de text originale", + "8": "Normal (Va genera eroare dacă PDF-ul conține text)", + "9": "Setări suplimentare", + "10": "Mod OCR", + "11": "Elimină imaginile după OCR (Elimină TOATE imaginile, util doar Ć®n etapa de conversie)", + "12": "Tip de redare (Avansat)" + }, + "help": "Citiți documentația pentru a afla cum să utilizați acest serviciu pentru alte limbi și/sau Ć®n afara mediului Docker", + "credit": "Acest serviciu utilizează qpdf și Tesseract pentru OCR.", + "submit": "Procesează PDF-ul cu OCR" + }, + "extractImages": { + "tags": "poză,fotografie,salvează,arhivă,zip,captură,extrage", + "title": "Extrage Imagini", + "header": "Extrage Imagini", + "selectText": "Selectați formatul imaginii Ć®n care să se convertească imaginile extrase", + "allowDuplicates": "Salvează imaginile duplicate", + "submit": "Extrage" + }, + "pdfToPDFA": { + "tags": "arhivă,termen-lung,standard,conversie,stocare,conservare", + "title": "PDF către PDF/A", + "header": "PDF către PDF/A", + "credit": "Acest serviciu utilizează libreoffice pentru conversia Ć®n PDF/A", + "submit": "Convertește", + "tip": "Ǝn prezent nu funcționează pentru mai multe intrări simultan", + "outputFormat": "Format de ieșire", + "pdfWithDigitalSignature": "PDF-ul conține o semnătură digitală. Aceasta va fi eliminată Ć®n pasul următor." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformare,format,conversie,office,microsoft,fișier doc", + "title": "PDF către Word", + "header": "PDF către Word", + "selectText": { + "1": "Format fișier de ieșire" + }, + "credit": "Acest serviciu utilizează LibreOffice pentru conversia fișierului.", + "submit": "Convertește" + }, + "PDFToPresentation": { + "tags": "diapozitive,prezentare,office,microsoft", + "title": "PDF către Prezentare", + "header": "PDF către Prezentare", + "selectText": { + "1": "Format fișier de ieșire" + }, + "credit": "Acest serviciu utilizează LibreOffice pentru conversia fișierului.", + "submit": "Convertește" + }, + "PDFToText": { + "tags": "format bogat,format text bogat,format text Ć®mbogățit", + "title": "PDF către Text/RTF", + "header": "PDF către Text/RTF", + "selectText": { + "1": "Format fișier de ieșire" + }, + "credit": "Acest serviciu utilizează LibreOffice pentru conversia fișierului.", + "submit": "Convertește" + }, + "PDFToHTML": { + "tags": "conținut web,compatibil cu browser", + "title": "PDF către HTML", + "header": "PDF către HTML", + "credit": "Acest serviciu utilizează pdftohtml pentru conversia fișierului.", + "submit": "Convertește" + }, + "PDFToXML": { + "tags": "extragere-date,conținut-structurat,interoperabilitate,transformare,convertește", + "title": "PDF către XML", + "header": "PDF către XML", + "credit": "Acest serviciu utilizează LibreOffice pentru conversia fișierului.", + "submit": "Convertește" + }, + "ScannerImageSplit": { + "tags": "separă,auto-detectare,scanări,multi-foto,organizează", + "selectText": { + "1": "Prag unghi:", + "2": "Stabilește unghiul absolut minim necesar pentru ca imaginea să fie rotită (implicit: 5).", + "3": "Toleranță:", + "4": "Determină intervalul de variație a culorii Ć®n jurul culorii de fundal estimate (implicit: 20).", + "5": "Arie minimă:", + "6": "Stabilește pragul minim de arie pentru o fotografie (implicit: 8000).", + "7": "Arie minimă a conturului:", + "8": "Stabilește pragul minim de arie a conturului pentru o fotografie.", + "9": "Mărimea marginii:", + "10": "Stabilește mărimea marginii adăugate și eliminate pentru a evita marginile albe Ć®n rezultat (implicit: 1)." + }, + "info": "Python nu este instalat. Este necesar pentru a rula." + }, + "sign": { + "tags": "autorizează,inițiale,semnătură-desenată,semnătură-text,semnătură-imagine", + "title": "Semnează", + "header": "Semnează documente PDF", + "upload": "Ǝncarcă Imaginea", + "draw": "Desenează Semnătura", + "text": "Introdu Textul", + "clear": "Curăță", + "add": "Adaugă", + "saved": "Saved Signatures", + "save": "Save Signature", + "personalSigs": "Personal Signatures", + "sharedSigs": "Shared Signatures", + "noSavedSigs": "No saved signatures found", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "static,dezactivează,non-interactiv,simplifică", + "title": "Nivelare", + "header": "Nivelează documente PDF", + "flattenOnlyForms": "Nivelează doar formularele", + "submit": "Nivelează" + }, + "repair": { + "tags": "repară,restaurează,corectare,recuperează", + "title": "Repară", + "header": "Repară documente PDF", + "submit": "Repară" + }, + "removeBlanks": { + "tags": "curățare,simplificare,fără-conținut,organizează", + "title": "Elimină pagini goale", + "header": "Elimină pagini goale", + "threshold": "Prag:", + "thresholdDesc": "Prag pentru determinarea cĆ¢t de alb trebuie să fie un pixel alb", + "whitePercent": "Procent alb (%):", + "whitePercentDesc": "Procentul paginii care trebuie să fie alb pentru a fi eliminată", + "submit": "Elimină pagini goale" + }, + "removeAnnotations": { + "tags": "comentarii,evidențiere,note,marcaje,elimină", + "title": "Elimină Adnotările", + "header": "Elimină Adnotările", + "submit": "Elimină" + }, + "compare": { + "tags": "diferențiază,contrastează,modificări,analiză", + "title": "Compară", + "header": "Compară PDF-uri", + "highlightColor": { + "1": "Culoare Evidențiere 1:", + "2": "Culoare Evidențiere 2:" + }, + "document": { + "1": "Documentul 1", + "2": "Documentul 2" + }, + "submit": "Compară", + "complex": { + "message": "One or both of the provided documents are large files, accuracy of comparison may be reduced" + }, + "large": { + "file": { + "message": "One or Both of the provided documents are too large to process" + } + }, + "no": { + "text": { + "message": "One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison." + } + } + }, + "certSign": { + "tags": "autentifică,PEM,P12,oficial,criptează", + "title": "Semnare certificat", + "header": "Semnează un fișier PDF cu certificatul tău (Ǝn curs de desfășurare)", + "selectPDF": "Selectează un fișier PDF pentru semnare:", + "jksNote": "Notă: Dacă tipul certificatului tău nu este listat mai jos, te rugăm să-l convertești Ć®ntr-un fișier Java Keystore (.jks) folosind instrumentul de linie de comandă keytool. Apoi, alege opțiunea fișier .jks de mai jos.", + "selectKey": "Selectează fișierul cheie privată (format PKCS#8, poate fi .pem sau .der):", + "selectCert": "Selectează fișierul de certificat (format X.509, poate fi .pem sau .der):", + "selectP12": "Selectează fișierul de stocare cheie PKCS#12 (.p12 sau .pfx) (Opțional, dacă este furnizat, ar trebui să conțină cheia privată și certificatul tău):", + "selectJKS": "Selectează Fișierul Java Keystore (.jks sau .keystore):", + "certType": "Tipul certificatului", + "password": "Introdu parola pentru stocarea cheie sau cheia privată (dacă există):", + "showSig": "Afișează semnătura", + "reason": "Motivul", + "location": "Locația", + "name": "Numele", + "showLogo": "Show Logo", + "submit": "Semnează PDF" + }, + "removeCertSign": { + "tags": "autentifică,PEM,P12,oficial,decriptează", + "title": "Elimină Semnătura cu Certificat", + "header": "Elimină certificatul digital din PDF", + "selectPDF": "Selectează un fișier PDF:", + "submit": "Elimină Semnătura" + }, + "pageLayout": { + "tags": "Ć®mbină,compozit,vizualizare-unică,organizează", + "title": "Aspect Multi-Pagină", + "header": "Aspect Multi-Pagină", + "pagesPerSheet": "Pagini per foaie:", + "addBorder": "Adaugă Borduri", + "submit": "Trimite" + }, + "scalePages": { + "tags": "redimensionează,modifică,dimensiune,adaptează", + "title": "Ajustează scala paginii", + "header": "Ajustează scala paginii", + "pageSize": "Dimensiunea unei pagini a documentului.", + "keepPageSize": "Original Size", + "scaleFactor": "Nivel de zoom (decupare) al unei pagini.", + "submit": "Trimite" + }, + "add-page-numbers": { + "tags": "paginează,etichetează,organizează,indexează" + }, + "auto-rename": { + "tags": "auto-detectare,bazat-pe-antet,organizează,reetichetează", + "title": "Redenumire Automată", + "header": "Redenumire Automată PDF", + "submit": "Redenumire Automată" + }, + "adjust-contrast": { + "tags": "corectare-culoare,reglează,modifică,Ć®mbunătățește" + }, + "crop": { + "tags": "taie,micșorează,editează,formă", + "title": "Decupează", + "header": "Decupează PDF", + "submit": "Trimite" + }, + "autoSplitPDF": { + "tags": "bazat-pe-QR,separă,segment-scanat,organizează", + "title": "Ǝmparte Automat PDF", + "header": "Ǝmparte Automat PDF", + "description": "Tipărește, Inserează, Scanează, Ć®ncarcă și lasă-ne să separăm automat documentele tale. Fără muncă manuală de sortare necesară.", + "selectText": { + "1": "Tipărește cĆ¢teva foi separatoare de mai jos (Alb-negru este suficient).", + "2": "Scanează toate documentele tale o dată inserĆ¢nd foaia separatoare Ć®ntre ele.", + "3": "Ǝncarcă fișierul PDF scanat mare și lasă Stirling PDF să se ocupe de rest.", + "4": "Paginile separatoare sunt detectate automat și eliminate, garantĆ¢nd un document final ordonat." + }, + "formPrompt": "Trimite PDF-ul conținĆ¢nd separatoarele de pagini Stirling-PDF:", + "duplexMode": "Mod Duplex (Scanare față-verso)", + "dividerDownload2": "Descarcă 'Separator Auto Splitter (cu instrucțiuni).pdf'", + "submit": "Trimite" + }, + "sanitizePdf": { + "tags": "curăță,securizează,sigur,elimină-amenințări" + }, + "URLToPDF": { + "tags": "captură-web,salvează-pagina,web-Ć®n-document,arhivează", + "title": "URL Ć®n PDF", + "header": "URL Ć®n PDF", + "submit": "Convertește", + "credit": "Folosește WeasyPrint" + }, + "HTMLToPDF": { + "tags": "markup,conținut-web,transformare,convertește", + "title": "HTML Ć®n PDF", + "header": "HTML Ć®n PDF", + "help": "Acceptă fișiere HTML și ZIP-uri care conțin html/css/imagini etc. necesare", + "submit": "Convertește", + "credit": "Folosește WeasyPrint", + "zoom": "Nivel de zoom pentru afișarea site-ului web.", + "pageWidth": "Lățimea paginii Ć®n centimetri. (Gol pentru implicit)", + "pageHeight": "Ǝnălțimea paginii Ć®n centimetri. (Gol pentru implicit)", + "marginTop": "Marginea de sus a paginii Ć®n milimetri. (Gol pentru implicit)", + "marginBottom": "Marginea de jos a paginii Ć®n milimetri. (Gol pentru implicit)", + "marginLeft": "Marginea din stĆ¢nga a paginii Ć®n milimetri. (Gol pentru implicit)", + "marginRight": "Marginea din dreapta a paginii Ć®n milimetri. (Gol pentru implicit)", + "printBackground": "Redă fundalul site-urilor web.", + "defaultHeader": "Activează Antetul Implicit (Nume și număr de pagină)", + "cssMediaType": "Schimbă tipul de media CSS al paginii.", + "none": "Niciunul", + "print": "Tipărire", + "screen": "Ecran" + }, + "MarkdownToPDF": { + "tags": "markup,conținut-web,transformare,convertește", + "title": "Markdown Ć®n PDF", + "header": "Markdown Ć®n PDF", + "submit": "Convertește", + "help": "Lucrare Ć®n curs", + "credit": "Folosește WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "informații,date,statistici,statistici", + "title": "Obține Informații despre PDF", + "header": "Obține Informații despre PDF", + "submit": "Obține Informații", + "downloadJson": "Descarcă JSON" + }, + "extractPage": { + "tags": "extrage" + }, + "PdfToSinglePage": { + "tags": "pagină unică" + }, + "showJS": { + "tags": "JS", + "title": "Arată Javascript", + "header": "Arată Javascript", + "downloadJS": "Descarcă Javascript", + "submit": "Arată" + }, + "autoRedact": { + "tags": "Redactează,Ascunde,Ć®nnegrește,negru,marker,ascuns", + "title": "Redactare Automată", + "header": "Redactare Automată", + "colorLabel": "Culoare", + "textsToRedactLabel": "Text de Redactat (separat pe linii)", + "textsToRedactPlaceholder": "ex. \\nConfidențial \\nSecret de Serviciu", + "useRegexLabel": "Folosește Regex", + "wholeWordSearchLabel": "Căutare CuvĆ¢nt Ǝntreg", + "customPaddingLabel": "Spațiere Suplimentară Personalizată", + "convertPDFToImageLabel": "Convertește PDF Ć®n PDF-Imagine (Folosit pentru a elimina textul din spatele casetei)", + "submitButton": "Trimite" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,Extragere Tabel,extrage,convertește" + }, + "autoSizeSplitPDF": { + "tags": "pdf,Ć®mparte,document,organizare" + }, + "overlay-pdfs": { + "tags": "Suprapune", + "header": "Suprapune Fișiere PDF", + "baseFile": { + "label": "Selectează Fișierul PDF de Bază" + }, + "overlayFiles": { + "label": "Selectează Fișierele PDF de Suprapus" + }, + "mode": { + "label": "Selectează Modul de Suprapunere", + "sequential": "Suprapunere Secvențială", + "interleaved": "Suprapunere Intercalată", + "fixedRepeat": "Suprapunere cu Repetare Fixă" + }, + "counts": { + "label": "Numere de Suprapunere (pentru Modul de Repetare Fixă)", + "placeholder": "Introdu numere separate prin virgulă (ex. 2,3,1)" + }, + "position": { + "label": "Selectează Poziția de Suprapunere", + "foreground": "Prim-plan", + "background": "Fundal" + }, + "submit": "Trimite" + }, + "split-by-sections": { + "tags": "Ǝmpărțire pe Secțiuni, Divizează, Personalizează", + "title": "Ǝmparte PDF Ć®n Secțiuni", + "header": "Ǝmparte PDF Ć®n Secțiuni", + "horizontal": { + "label": "Diviziuni Orizontale", + "placeholder": "Introdu numărul de diviziuni orizontale" + }, + "vertical": { + "label": "Diviziuni Verticale", + "placeholder": "Introdu numărul de diviziuni verticale" + }, + "submit": "Ǝmparte PDF", + "merge": "Ǝmbină Ǝntr-un Singur PDF" + }, + "AddStampRequest": { + "tags": "Ștampilă, Adaugă imagine, centrează imagine, Filigran, PDF, Ǝncorporează, Personalizează", + "header": "Ștampilează PDF", + "title": "Ștampilează PDF", + "stampType": "Tip Ștampilă", + "stampText": "Text Ștampilă", + "stampImage": "Imagine Ștampilă", + "alphabet": "Alfabet", + "fontSize": "Dimensiune Font/Imagine", + "rotation": "Rotație", + "opacity": "Opacitate", + "position": "Poziție", + "overrideX": "Suprascrie Coordonata X", + "overrideY": "Suprascrie Coordonata Y", + "customMargin": "Margine Personalizată", + "customColor": "Culoare Text Personalizată", + "submit": "Trimite" + }, + "removeImagePdf": { + "tags": "Elimină Imagine,Operații pagină,Back end,server side" + }, + "splitPdfByChapters": { + "tags": "split,chapters,bookmarks,organize" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Replace-Invert-Color", + "header": "Replace-Invert Color PDF", + "selectText": { + "1": "Replace or Invert color Options", + "2": "Default(Default high contrast colors)", + "3": "Custom(Customized colors)", + "4": "Full-Invert(Invert all colors)", + "5": "High contrast color options", + "6": "white text on black background", + "7": "Black text on white background", + "8": "Yellow text on black background", + "9": "Green text on black background", + "10": "Choose text Color", + "11": "Choose background Color" + }, + "submit": "Replace" + }, + "replaceColorPdf": { + "tags": "Replace Color,Page operations,Back end,server side" + }, + "login": { + "title": "Autentificare", + "header": "Autentificare", + "signin": "Autentificare", + "rememberme": "Ține-mă minte", + "invalid": "Nume de utilizator sau parolă invalidă.", + "locked": "Contul tău a fost blocat.", + "signinTitle": "Te rugăm să te autentifici", + "ssoSignIn": "Conectare prin conectare unică", + "oAuth2AutoCreateDisabled": "OAUTH2 Creare automată utilizator dezactivată", + "oAuth2AdminBlockedUser": "Ǝnregistrarea sau conectarea utilizatorilor neĆ®nregistrați este Ć®n prezent blocată. Te rugăm să contactezi administratorul.", + "oauth2RequestNotFound": "Cererea de autorizare nu a fost găsită", + "oauth2InvalidUserInfoResponse": "Răspuns Invalid la Informațiile Utilizatorului", + "oauth2invalidRequest": "Cerere Invalidă", + "oauth2AccessDenied": "Acces Refuzat", + "oauth2InvalidTokenResponse": "Răspuns Invalid la Token", + "oauth2InvalidIdToken": "Token de Id Invalid", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "Utilizatorul este dezactivat, conectarea este Ć®n prezent blocată cu acest nume de utilizator. Te rugăm să contactezi administratorul.", + "alreadyLoggedIn": "You are already logged in to", + "alreadyLoggedIn2": "devices. Please log out of the devices and try again.", + "toManySessions": "You have too many active sessions", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF Ć®ntr-o Singură Pagină", + "header": "PDF Ć®ntr-o Singură Pagină", + "submit": "Convertește Ć®ntr-o Singură Pagină" + }, + "pageExtracter": { + "title": "Extrage Pagini", + "header": "Extrage Pagini", + "submit": "Extrage", + "placeholder": "(ex. 1,2,8 sau 4,7,12-16 sau 2n-1)" + }, + "sanitizePDF": { + "title": "Igienizează PDF", + "header": "Igienizează un fișier PDF", + "selectText": { + "1": "Elimină acțiunile JavaScript", + "2": "Elimină fișierele Ć®ncorporate", + "3": "Remove XMP metadata", + "4": "Elimină link-urile", + "5": "Elimină fonturile", + "6": "Remove Document Info Metadata" + }, + "submit": "Igienizează PDF" + }, + "adjustContrast": { + "title": "Ajustează Contrastul", + "header": "Ajustează Contrastul", + "contrast": "Contrast:", + "brightness": "Luminozitate:", + "saturation": "Saturație:", + "download": "Descarcă" + }, + "compress": { + "title": "Comprimare", + "header": "Comprimare PDF", + "credit": "Acest serviciu utilizează qpdf pentru comprimarea/optimizarea PDF-urilor.", + "grayscale": { + "label": "Aplicare scală de gri pentru compresie" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Nivel de optimizare:", + "4": "Mod automat - ajustează automat calitatea pentru a aduce PDF-ul la dimensiunea exactă", + "5": "Dimensiunea PDF așteptată (de ex. 25MB, 10.8MB, 25KB)" + }, + "submit": "Comprimare" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "Ǝnlăturare pagini", + "header": "Ǝnlăturare pagini din PDF", + "pagesToDelete": "Pagini de șters (Introduceți o listă de numere de pagini separate prin virgulă):", + "submit": "Ștergere pagini", + "placeholder": "(ex. 1,2,6 sau 1-10,15-30)" + }, + "imageToPDF": { + "title": "Imagine Ć®n PDF", + "header": "Imagine Ć®n PDF", + "submit": "Convertește", + "selectLabel": "Opțiuni de Potrivire a Imaginii", + "fillPage": "Umple Pagina", + "fitDocumentToImage": "Potrivește Pagina la Imagine", + "maintainAspectRatio": "Menține Raportul de Aspect", + "selectText": { + "2": "Rotire automată a PDF-ului", + "3": "Logica pentru mai multe fișiere (activată numai dacă se lucrează cu mai multe imagini)", + "4": "Unifică Ć®ntr-un singur PDF", + "5": "Convertește Ć®n PDF-uri separate" + } + }, + "PDFToCSV": { + "title": "PDF Ć®n CSV", + "header": "PDF Ć®n CSV", + "prompt": "Alege pagina pentru extragerea tabelului", + "submit": "Extrage" + }, + "split-by-size-or-count": { + "title": "Ǝmparte PDF după Dimensiune sau Număr", + "header": "Ǝmparte PDF după Dimensiune sau Număr", + "type": { + "label": "Selectează Tipul de Ǝmpărțire", + "size": "După Dimensiune", + "pageCount": "După Număr de Pagini", + "docCount": "După Număr de Documente" + }, + "value": { + "label": "Introdu Valoarea", + "placeholder": "Introdu dimensiunea (ex. 2MB sau 3KB) sau numărul (ex. 5)" + }, + "submit": "Trimite" + }, + "printFile": { + "title": "Tipărește Fișier", + "header": "Tipărește Fișier la Imprimantă", + "selectText": { + "1": "Selectează Fișierul de Tipărit", + "2": "Introdu Numele Imprimantei" + }, + "submit": "Tipărește" + }, + "licenses": { + "nav": "Licențe", + "title": "Licențe Terțe Părți", + "header": "Licențe Terțe Părți", + "module": "Modul", + "version": "Versiune", + "license": "Licență" + }, + "survey": { + "nav": "Sondaj", + "title": "Sondaj Stirling-PDF", + "description": "Stirling-PDF nu are urmărire, așa că vrem să auzim de la utilizatorii noștri pentru a Ć®mbunătăți Stirling-PDF!", + "changes": "Stirling-PDF has changed since the last survey! To find out more please check our blog post here:", + "changes2": "With these changes we are getting paid business support and funding", + "please": "Te rugăm să iei Ć®n considerare completarea sondajului nostru!", + "disabled": "(Fereastra pop-up a sondajului va fi dezactivată Ć®n următoarele actualizări, dar va fi disponibilă Ć®n subsolul paginii)", + "button": "Completează Sondajul", + "dontShowAgain": "Nu mai arăta din nou", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Elimină imagine", + "header": "Elimină imagine", + "removeImage": "Elimină imagine", + "submit": "Elimină imagine" + }, + "splitByChapters": { + "title": "Split PDF by Chapters", + "header": "Split PDF by Chapters", + "bookmarkLevel": "Bookmark Level", + "includeMetadata": "Include Metadata", + "allowDuplicates": "Allow Duplicates", + "desc": { + "1": "This tool splits a PDF file into multiple PDFs based on its chapter structure.", + "2": "Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).", + "3": "Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.", + "4": "Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs." + }, + "submit": "Split PDF" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Releases", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Current Release" + }, + "note": "Release notes are only available in English" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/ru-RU/translation.json b/frontend/public/locales/ru-RU/translation.json new file mode 100644 index 000000000..79bfecf9d --- /dev/null +++ b/frontend/public/locales/ru-RU/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Размер ŃˆŃ€ŠøŃ„Ń‚Š°", + "fontName": "ŠŠ°Š·Š²Š°Š½ŠøŠµ ŃˆŃ€ŠøŃ„Ń‚Š°", + "title": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ номера страниц", + "header": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ номера страниц", + "selectText": { + "1": "Выберите PDF-файл:", + "2": "Размер полей", + "3": "ŠŸŠ¾Š·ŠøŃ†ŠøŃ", + "4": "ŠŠ°Ń‡Š°Š»ŃŒŠ½Ń‹Š¹ номер", + "5": "Дтраницы Š“Š»Ń Š½ŃƒŠ¼ŠµŃ€Š°Ń†ŠøŠø", + "6": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠ¹ текст" + }, + "customTextDesc": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠ¹ текст", + "numberPagesDesc": "Какие страницы Š½ŃƒŠ¼ŠµŃ€Š¾Š²Š°Ń‚ŃŒ, по ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ 'все', также принимает 1-5 или 2,5,9 Šø т.Š“.", + "customNumberDesc": "По ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ {n}, также принимает 'Дтраница {n} ŠøŠ· {total}', 'Текст-{n}', '{filename}-{n}'", + "submit": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ номера страниц" + }, + "pdfPrompt": "Выберите PDF-файл(ы)", + "multiPdfPrompt": "Выберите PDF-файлы (2+)", + "multiPdfDropPrompt": "Выберите (или перетащите) все необхоГимые PDF-файлы", + "imgPrompt": "Выберите изображение(я)", + "genericSubmit": "ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Внимание: Данный процесс может Š·Š°Š½ŃŃ‚ŃŒ Го Š¼ŠøŠ½ŃƒŃ‚Ń‹ в зависимости от размера файла", + "pageOrderPrompt": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠ¹ ŠæŠ¾Ń€ŃŠ“Š¾Šŗ страниц (ВвеГите список номеров страниц через Š·Š°ŠæŃŃ‚ŃƒŃŽ или Ń„ŃƒŠ½ŠŗŃ†ŠøŠø типа 2n+1):", + "pageSelectionPrompt": "Выбор страниц (ВвеГите список номеров страниц через Š·Š°ŠæŃŃ‚ŃƒŃŽ 1,5,6 или Ń„ŃƒŠ½ŠŗŃ†ŠøŠø типа 2n+1):", + "goToPage": "ŠŸŠµŃ€ŠµŠ¹Ń‚Šø", + "true": "Да", + "false": "ŠŠµŃ‚", + "unknown": "ŠŠµŠøŠ·Š²ŠµŃŃ‚Š½Š¾", + "save": "Š”Š¾Ń…Ń€Š°Š½ŠøŃ‚ŃŒ", + "saveToBrowser": "Š”Š¾Ń…Ń€Š°Š½ŠøŃ‚ŃŒ в Š±Ń€Š°ŃƒŠ·ŠµŃ€Šµ", + "close": "Š—Š°ŠŗŃ€Ń‹Ń‚ŃŒ", + "filesSelected": "файлов выбрано", + "noFavourites": "ŠŠµŃ‚ избранного", + "downloadComplete": "Š—Š°Š³Ń€ŃƒŠ·ŠŗŠ° Š·Š°Š²ŠµŃ€ŃˆŠµŠ½Š°", + "bored": "Š”ŠŗŃƒŃ‡Š½Š¾ Š¶Š“Š°Ń‚ŃŒ?", + "alphabet": "Алфавит", + "downloadPdf": "Š”ŠŗŠ°Ń‡Š°Ń‚ŃŒ PDF", + "text": "Текст", + "font": "Шрифт", + "selectFillter": "-- Š’Ń‹Š±Ń€Š°Ń‚ŃŒ --", + "pageNum": "ŠŠ¾Š¼ŠµŃ€ страницы", + "sizes": { + "small": "ŠœŠ°Š»Ń‹Š¹", + "medium": "ДреГний", + "large": "Š‘Š¾Š»ŃŒŃˆŠ¾Š¹", + "x-large": "ŠžŃ‡ŠµŠ½ŃŒ большой" + }, + "error": { + "pdfPassword": "PDF-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ защищен паролем, Šø ŠæŠ°Ń€Š¾Š»ŃŒ не был преГоставлен или был неверным", + "_value": "ŠžŃˆŠøŠ±ŠŗŠ°", + "sorry": "Š˜Š·Š²ŠøŠ½ŠøŃ‚Šµ за неполаГки!", + "needHelp": "ŠŃƒŠ¶Š½Š° ŠæŠ¾Š¼Š¾Ń‰ŃŒ / ŠŠ°ŃˆŠ»Šø ŠæŃ€Š¾Š±Š»ŠµŠ¼Ńƒ?", + "contactTip": "Если у вас все еще ŠµŃŃ‚ŃŒ проблемы, не ŃŃ‚ŠµŃŠ½ŃŠ¹Ń‚ŠµŃŃŒ Š¾Š±Ń€Š°Ń‰Š°Ń‚ŃŒŃŃ Šŗ нам за ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ. Š’Ń‹ можете Š¾Ń‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ тикет на нашей странице GitHub или ŃŠ²ŃŠ·Š°Ń‚ŃŒŃŃ с нами через Discord:", + "404": { + "head": "404 - Дтраница не найГена | Упс, мы Š·Š°ŠæŃƒŃ‚Š°Š»ŠøŃŃŒ в коГе!", + "1": "ŠœŃ‹ не можем найти ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ, ŠŗŠ¾Ń‚Š¾Ń€ŃƒŃŽ вы ищете.", + "2": "Что-то пошло не так" + }, + "github": "ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ тикет на GitHub", + "showStack": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚ŃŒ Ń‚Ń€Š°ŃŃŠøŃ€Š¾Š²ŠŗŃƒ стека", + "copyStack": "Š”ŠŗŠ¾ŠæŠøŃ€Š¾Š²Š°Ń‚ŃŒ Ń‚Ń€Š°ŃŃŠøŃ€Š¾Š²ŠŗŃƒ стека", + "githubSubmit": "GitHub - ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ тикет", + "discordSubmit": "Discord - ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ запрос в ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠŗŃƒ" + }, + "delete": "Š£Š“Š°Š»ŠøŃ‚ŃŒ", + "username": "Š˜Š¼Ń ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń", + "password": "ŠŸŠ°Ń€Š¾Š»ŃŒ", + "welcome": "Добро ŠæŠ¾Š¶Š°Š»Š¾Š²Š°Ń‚ŃŒ", + "property": "Двойство", + "black": "Черный", + "white": "Белый", + "red": "ŠšŃ€Š°ŃŠ½Ń‹Š¹", + "green": "Зеленый", + "blue": "Диний", + "custom": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠ¹...", + "WorkInProgess": "Š’ разработке, возможны ошибки Šø сбои, ŠæŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, сообщайте о Š»ŃŽŠ±Ń‹Ń… проблемах!", + "poweredBy": "Работает на", + "yes": "Да", + "no": "ŠŠµŃ‚", + "changedCredsMessage": "Учетные Ганные изменены!", + "notAuthenticatedMessage": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ не ŠæŃ€Š¾ŃˆŠµŠ» Š°ŃƒŃ‚ŠµŠ½Ń‚ŠøŃ„ŠøŠŗŠ°Ń†ŠøŃŽ.", + "userNotFoundMessage": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ не найГен.", + "incorrectPasswordMessage": "Š¢ŠµŠŗŃƒŃ‰ŠøŠ¹ ŠæŠ°Ń€Š¾Š»ŃŒ неверен.", + "usernameExistsMessage": "ŠŠ¾Š²Š¾Šµ ŠøŠ¼Ń ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń уже ŃŃƒŃ‰ŠµŃŃ‚Š²ŃƒŠµŃ‚.", + "invalidUsernameMessage": "ŠŠµŠ“Š¾ŠæŃƒŃŃ‚ŠøŠ¼Š¾Šµ ŠøŠ¼Ń ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń, оно может ŃŠ¾Š“ŠµŃ€Š¶Š°Ń‚ŃŒ Ń‚Š¾Š»ŃŒŠŗŠ¾ Š±ŃƒŠŗŠ²Ń‹, цифры Šø ŃŠ»ŠµŠ“ŃƒŃŽŃ‰ŠøŠµ ŃŠæŠµŃ†ŠøŠ°Š»ŃŒŠ½Ń‹Šµ символы @._+- или Голжно Š±Ń‹Ń‚ŃŒ Š“ŠµŠ¹ŃŃ‚Š²ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Š¼ аГресом ŃŠ»ŠµŠŗŃ‚Ń€Š¾Š½Š½Š¾Š¹ почты.", + "invalidPasswordMessage": "ŠŸŠ°Ń€Š¾Š»ŃŒ не Голжен Š±Ń‹Ń‚ŃŒ ŠæŃƒŃŃ‚Ń‹Š¼ Šø не Голжен ŃŠ¾Š“ŠµŃ€Š¶Š°Ń‚ŃŒ пробелы в начале или конце.", + "confirmPasswordErrorMessage": "ŠŠ¾Š²Ń‹Š¹ ŠæŠ°Ń€Š¾Š»ŃŒ Šø его поГтвержГение Голжны ŃŠ¾Š²ŠæŠ°Š“Š°Ń‚ŃŒ.", + "deleteCurrentUserMessage": "ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŃƒŠ“Š°Š»ŠøŃ‚ŃŒ Ń‚ŠµŠŗŃƒŃ‰ŠµŠ³Š¾ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń.", + "deleteUsernameExistsMessage": "Š˜Š¼Ń ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń не ŃŃƒŃ‰ŠµŃŃ‚Š²ŃƒŠµŃ‚ Šø не может Š±Ń‹Ń‚ŃŒ уГалено.", + "downgradeCurrentUserMessage": "ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š½ŠøŠ·ŠøŃ‚ŃŒ Ń€Š¾Š»ŃŒ Ń‚ŠµŠŗŃƒŃ‰ŠµŠ³Š¾ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń", + "disabledCurrentUserMessage": "Š¢ŠµŠŗŃƒŃ‰ŠøŠ¹ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ не может Š±Ń‹Ń‚ŃŒ Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½", + "downgradeCurrentUserLongMessage": "ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š½ŠøŠ·ŠøŃ‚ŃŒ Ń€Š¾Š»ŃŒ Ń‚ŠµŠŗŃƒŃ‰ŠµŠ³Š¾ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń. Š”Š»ŠµŠ“Š¾Š²Š°Ń‚ŠµŠ»ŃŒŠ½Š¾, Ń‚ŠµŠŗŃƒŃ‰ŠøŠ¹ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ не Š±ŃƒŠ“ет Š¾Ń‚Š¾Š±Ń€Š°Š¶Š°Ń‚ŃŒŃŃ.", + "userAlreadyExistsOAuthMessage": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ уже ŃŃƒŃ‰ŠµŃŃ‚Š²ŃƒŠµŃ‚ как ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ OAuth2.", + "userAlreadyExistsWebMessage": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ уже ŃŃƒŃ‰ŠµŃŃ‚Š²ŃƒŠµŃ‚ как веб-ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ.", + "oops": "Упс!", + "help": "ŠŸŠ¾Š¼Š¾Ń‰ŃŒ", + "goHomepage": "ŠŸŠµŃ€ŠµŠ¹Ń‚Šø на Š³Š»Š°Š²Š½ŃƒŃŽ", + "joinDiscord": "ŠŸŃ€ŠøŃŠ¾ŠµŠ“ŠøŠ½ŠøŃ‚ŃŒŃŃ Šŗ Discord", + "seeDockerHub": "ŠŸŠ¾ŃŠ¼Š¾Ń‚Ń€ŠµŃ‚ŃŒ на Docker Hub", + "visitGithub": "ŠŸŠ¾ŃŠµŃ‚ŠøŃ‚ŃŒ репозиторий GitHub", + "donate": "ŠŸŠ¾Š“Š“ŠµŃ€Š¶Š°Ń‚ŃŒ", + "color": "Цвет", + "sponsor": "Дпонсор", + "info": "Š˜Š½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ", + "pro": "Pro", + "page": "Дтраница", + "pages": "Дтраницы", + "loading": "Š—Š°Š³Ń€ŃƒŠ·ŠŗŠ°...", + "addToDoc": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ в Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚", + "reset": "Š”Š±Ń€Š¾ŃŠøŃ‚ŃŒ", + "apply": "ŠŸŃ€ŠøŠ¼ŠµŠ½ŠøŃ‚ŃŒ", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "ŠŸŠ¾Š»ŠøŃ‚ŠøŠŗŠ° ŠŗŠ¾Š½Ń„ŠøŠ“ŠµŠ½Ń†ŠøŠ°Š»ŃŒŠ½Š¾ŃŃ‚Šø", + "terms": "Š£ŃŠ»Š¾Š²ŠøŃ ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŃ", + "accessibility": "Š”Š¾ŃŃ‚ŃƒŠæŠ½Š¾ŃŃ‚ŃŒ", + "cookie": "ŠŸŠ¾Š»ŠøŃ‚ŠøŠŗŠ° ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŃ файлов cookie", + "impressum": "ВыхоГные Ганные", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "ŠœŠµŠ½ŃŽ конвейера (Beta)", + "uploadButton": "Š—Š°Š³Ń€ŃƒŠ·ŠøŃ‚ŃŒ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠ¹", + "configureButton": "ŠŠ°ŃŃ‚Ń€Š¾ŠøŃ‚ŃŒ", + "defaultOption": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠ¹", + "submitButton": "ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ", + "help": "ŠŸŠ¾Š¼Š¾Ń‰ŃŒ по ŠŗŠ¾Š½Š²ŠµŠ¹ŠµŃ€Ńƒ", + "scanHelp": "ŠŸŠ¾Š¼Š¾Ń‰ŃŒ по ŃŠŗŠ°Š½ŠøŃ€Š¾Š²Š°Š½ŠøŃŽ папок", + "deletePrompt": "Š’Ń‹ ŃƒŠ²ŠµŃ€ŠµŠ½Ń‹, что хотите ŃƒŠ“Š°Š»ŠøŃ‚ŃŒ конвейер?", + "tags": "Š°Š²Ń‚Š¾Š¼Š°Ń‚ŠøŠ·Š°Ń†ŠøŃ,ŠæŠ¾ŃŠ»ŠµŠ“Š¾Š²Š°Ń‚ŠµŠ»ŃŒŠ½Š¾ŃŃ‚ŃŒ,скриптовый,ŠæŠ°ŠŗŠµŃ‚Š½Š°Ń обработка", + "title": "ŠšŠ¾Š½Š²ŠµŠ¹ŠµŃ€" + }, + "pipelineOptions": { + "header": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ° конвейера", + "pipelineNameLabel": "ŠŠ°Š·Š²Š°Š½ŠøŠµ конвейера", + "saveSettings": "Š”Š¾Ń…Ń€Š°Š½ŠøŃ‚ŃŒ настройки операции", + "pipelineNamePrompt": "ВвеГите название конвейера зГесь", + "selectOperation": "Š’Ń‹Š±Ń€Š°Ń‚ŃŒ Š¾ŠæŠµŃ€Š°Ń†ŠøŃŽ", + "addOperationButton": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ Š¾ŠæŠµŃ€Š°Ń†ŠøŃŽ", + "pipelineHeader": "ŠšŠ¾Š½Š²ŠµŠ¹ŠµŃ€:", + "saveButton": "Š”ŠŗŠ°Ń‡Š°Ń‚ŃŒ", + "validateButton": "ŠŸŃ€Š¾Š²ŠµŃ€ŠøŃ‚ŃŒ" + }, + "enterpriseEdition": { + "button": "ŠŸŠµŃ€ŠµŠ¹Ń‚Šø на Pro", + "warning": "Эта Ń„ŃƒŠ½ŠŗŃ†ŠøŃ Š“Š¾ŃŃ‚ŃƒŠæŠ½Š° Ń‚Š¾Š»ŃŒŠŗŠ¾ Š“Š»Ń ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŠµŠ¹ Pro.", + "yamlAdvert": "Stirling PDF Pro поГГерживает файлы ŠŗŠ¾Š½Ń„ŠøŠ³ŃƒŃ€Š°Ń†ŠøŠø YAML Šø Š“Ń€ŃƒŠ³ŠøŠµ Ń„ŃƒŠ½ŠŗŃ†ŠøŠø SSO.", + "ssoAdvert": "Š˜Ń‰ŠµŃ‚Šµ больше возможностей ŃƒŠæŃ€Š°Š²Š»ŠµŠ½ŠøŃ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŠ¼Šø? ŠŸŠ¾ŃŠ¼Š¾Ń‚Ń€ŠøŃ‚Šµ Stirling PDF Pro" + }, + "analytics": { + "title": "Єотите ŃƒŠ»ŃƒŃ‡ŃˆŠøŃ‚ŃŒ Stirling PDF?", + "paragraph1": "Š’ Stirling PDF ŠµŃŃ‚ŃŒ Š¾ŠæŃ†ŠøŠ¾Š½Š°Š»ŃŒŠ½Š°Ń аналитика Š“Š»Ń ŃƒŠ»ŃƒŃ‡ŃˆŠµŠ½ŠøŃ ŠæŃ€Š¾Š“ŃƒŠŗŃ‚Š°. ŠœŃ‹ не отслеживаем Š»ŠøŃ‡Š½ŃƒŃŽ ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃŽ или соГержимое файлов.", + "paragraph2": "ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, рассмотрите Š²Š¾Š·Š¼Š¾Š¶Š½Š¾ŃŃ‚ŃŒ Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½ŠøŃ аналитики, чтобы ŠæŠ¾Š¼Š¾Ń‡ŃŒ Ń€Š°Š·Š²ŠøŃ‚ŠøŃŽ Stirling-PDF Šø ŠæŠ¾Š·Š²Š¾Š»ŠøŃ‚ŃŒ нам Š»ŃƒŃ‡ŃˆŠµ ŠæŠ¾Š½ŠøŠ¼Š°Ń‚ŃŒ Š½Š°ŃˆŠøŃ… ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŠµŠ¹.", + "enable": "Š’ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ Š°Š½Š°Š»ŠøŃ‚ŠøŠŗŃƒ", + "disable": "ŠžŃ‚ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ Š°Š½Š°Š»ŠøŃ‚ŠøŠŗŃƒ", + "settings": "Š’Ń‹ можете ŠøŠ·Š¼ŠµŠ½ŠøŃ‚ŃŒ настройки аналитики в файле config/settings.yml" + }, + "navbar": { + "favorite": "Š˜Š·Š±Ń€Š°Š½Š½Š¾Šµ", + "recent": "ŠŠ¾Š²Š¾Šµ Šø неГавно обновленное", + "darkmode": "Темный режим", + "language": "Языки", + "settings": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø", + "allTools": "Š˜Š½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚Ń‹", + "multiTool": "ŠœŃƒŠ»ŃŒŃ‚ŠøŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚", + "search": "Поиск", + "sections": { + "organize": "ŠžŃ€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ", + "convertTo": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŠøŃ€Š¾Š²Š°Ń‚ŃŒ в PDF", + "convertFrom": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŠøŃ€Š¾Š²Š°Ń‚ŃŒ ŠøŠ· PDF", + "security": "ПоГписи Šø Š±ŠµŠ·Š¾ŠæŠ°ŃŠ½Š¾ŃŃ‚ŃŒ", + "advance": "Š Š°ŃŃˆŠøŃ€ŠµŠ½Š½Ń‹Šµ", + "edit": "ŠŸŃ€Š¾ŃŠ¼Š¾Ń‚Ń€ Šø реГактирование", + "popular": "ŠŸŠ¾ŠæŃƒŠ»ŃŃ€Š½Š¾Šµ" + } + }, + "settings": { + "title": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø", + "update": "Š”Š¾ŃŃ‚ŃƒŠæŠ½Š¾ обновление", + "updateAvailable": "Š¢ŠµŠŗŃƒŃ‰Š°Ń ŃƒŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Š½Š°Ń Š²ŠµŃ€ŃŠøŃ - {0}. Š”Š¾ŃŃ‚ŃƒŠæŠ½Š° Š½Š¾Š²Š°Ń Š²ŠµŃ€ŃŠøŃ ({1}).", + "appVersion": "Š’ŠµŃ€ŃŠøŃ ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ:", + "downloadOption": { + "title": "Выберите вариант Š·Š°Š³Ń€ŃƒŠ·ŠŗŠø (Š“Š»Ń оГиночных файлов без архивации):", + "1": "ŠžŃ‚ŠŗŃ€Ń‹Ń‚ŃŒ в том же окне", + "2": "ŠžŃ‚ŠŗŃ€Ń‹Ń‚ŃŒ в новом окне", + "3": "Š”ŠŗŠ°Ń‡Š°Ń‚ŃŒ файл" + }, + "zipThreshold": "ŠŃ€Ń…ŠøŠ²ŠøŃ€Š¾Š²Š°Ń‚ŃŒ файлы, когГа количество Š·Š°Š³Ń€ŃƒŠ¶Š°ŠµŠ¼Ń‹Ń… файлов ŠæŃ€ŠµŠ²Ń‹ŃˆŠ°ŠµŃ‚", + "signOut": "Выйти", + "accountSettings": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø Š°ŠŗŠŗŠ°ŃƒŠ½Ń‚Š°", + "bored": { + "help": "Š’ŠŗŠ»ŃŽŃ‡Š°ŠµŃ‚ ŠæŠ°ŃŃ…Š°Š»ŠŗŃƒ-ŠøŠ³Ń€Ńƒ" + }, + "cacheInputs": { + "name": "Š”Š¾Ń…Ń€Š°Š½ŃŃ‚ŃŒ Ганные форм", + "help": "Š’ŠŗŠ»ŃŽŃ‡ŠøŃ‚Šµ Š“Š»Ń ŃŠ¾Ń…Ń€Š°Š½ŠµŠ½ŠøŃ ранее ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½Š½Ń‹Ń… Ганных Š“Š»Ń Š±ŃƒŠ“ŃƒŃ‰ŠøŃ… запусков" + } + }, + "changeCreds": { + "title": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ ŃƒŃ‡ŠµŃ‚Š½Ń‹Šµ Ганные", + "header": "ŠžŠ±Š½Š¾Š²ŠøŃ‚ŃŒ Ганные вашей ŃƒŃ‡ŠµŃ‚Š½Š¾Š¹ записи", + "changePassword": "Š’Ń‹ ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚Šµ станГартные ŃƒŃ‡ŠµŃ‚Š½Ń‹Šµ Ганные Š“Š»Ń вхоГа. ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, ввеГите новый ŠæŠ°Ń€Š¾Š»ŃŒ", + "newUsername": "ŠŠ¾Š²Š¾Šµ ŠøŠ¼Ń ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń", + "oldPassword": "Š¢ŠµŠŗŃƒŃ‰ŠøŠ¹ ŠæŠ°Ń€Š¾Š»ŃŒ", + "newPassword": "ŠŠ¾Š²Ń‹Š¹ ŠæŠ°Ń€Š¾Š»ŃŒ", + "confirmNewPassword": "ŠŸŠ¾Š“Ń‚Š²ŠµŃ€Š“ŠøŃ‚Šµ новый ŠæŠ°Ń€Š¾Š»ŃŒ", + "submit": "ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ ŠøŠ·Š¼ŠµŠ½ŠµŠ½ŠøŃ" + }, + "account": { + "title": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø Š°ŠŗŠŗŠ°ŃƒŠ½Ń‚Š°", + "accountSettings": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø Š°ŠŗŠŗŠ°ŃƒŠ½Ń‚Š°", + "adminSettings": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø аГминистратора - ŠŸŃ€Š¾ŃŠ¼Š¾Ń‚Ń€ Šø Гобавление ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŠµŠ¹", + "userControlSettings": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø ŃƒŠæŃ€Š°Š²Š»ŠµŠ½ŠøŃ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŠ¼Šø", + "changeUsername": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ ŠøŠ¼Ń ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń", + "newUsername": "ŠŠ¾Š²Š¾Šµ ŠøŠ¼Ń ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń", + "password": "ŠŸŠ°Ń€Š¾Š»ŃŒ ŠæŠ¾Š“Ń‚Š²ŠµŃ€Š¶Š“ŠµŠ½ŠøŃ", + "oldPassword": "Дтарый ŠæŠ°Ń€Š¾Š»ŃŒ", + "newPassword": "ŠŠ¾Š²Ń‹Š¹ ŠæŠ°Ń€Š¾Š»ŃŒ", + "changePassword": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ ŠæŠ°Ń€Š¾Š»ŃŒ", + "confirmNewPassword": "ŠŸŠ¾Š“Ń‚Š²ŠµŃ€Š“ŠøŃ‚Šµ новый ŠæŠ°Ń€Š¾Š»ŃŒ", + "signOut": "Выйти", + "yourApiKey": "Š’Š°Ńˆ API-ŠŗŠ»ŃŽŃ‡", + "syncTitle": "Š”ŠøŠ½Ń…Ń€Š¾Š½ŠøŠ·ŠøŃ€Š¾Š²Š°Ń‚ŃŒ настройки Š±Ń€Š°ŃƒŠ·ŠµŃ€Š° с Š°ŠŗŠŗŠ°ŃƒŠ½Ń‚Š¾Š¼", + "settingsCompare": "Дравнение настроек:", + "property": "Двойство", + "webBrowserSettings": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø веб-Š±Ń€Š°ŃƒŠ·ŠµŃ€Š°", + "syncToBrowser": "Š”ŠøŠ½Ń…Ń€Š¾Š½ŠøŠ·ŠøŃ€Š¾Š²Š°Ń‚ŃŒ ŠŠŗŠŗŠ°ŃƒŠ½Ń‚ -> Š‘Ń€Š°ŃƒŠ·ŠµŃ€", + "syncToAccount": "Š”ŠøŠ½Ń…Ń€Š¾Š½ŠøŠ·ŠøŃ€Š¾Š²Š°Ń‚ŃŒ ŠŠŗŠŗŠ°ŃƒŠ½Ń‚ <- Š‘Ń€Š°ŃƒŠ·ŠµŃ€" + }, + "adminUserSettings": { + "title": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø ŃƒŠæŃ€Š°Š²Š»ŠµŠ½ŠøŃ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŠ¼Šø", + "header": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø ŃƒŠæŃ€Š°Š²Š»ŠµŠ½ŠøŃ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŠ¼Šø аГминистратора", + "admin": "АГминистратор", + "user": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ", + "addUser": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ нового ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń", + "deleteUser": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń", + "confirmDeleteUser": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń?", + "confirmChangeUserStatus": "ŠžŃ‚ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ/Š²ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń?", + "usernameInfo": "Š˜Š¼Ń ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń может ŃŠ¾Š“ŠµŃ€Š¶Š°Ń‚ŃŒ Ń‚Š¾Š»ŃŒŠŗŠ¾ Š±ŃƒŠŗŠ²Ń‹, цифры Šø ŃŠ»ŠµŠ“ŃƒŃŽŃ‰ŠøŠµ ŃŠæŠµŃ†ŠøŠ°Š»ŃŒŠ½Ń‹Šµ символы @._+- или Голжно Š±Ń‹Ń‚ŃŒ Š“ŠµŠ¹ŃŃ‚Š²ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Š¼ аГресом ŃŠ»ŠµŠŗŃ‚Ń€Š¾Š½Š½Š¾Š¹ почты.", + "roles": "Роли", + "role": "Роль", + "actions": "Š”ŠµŠ¹ŃŃ‚Š²ŠøŃ", + "apiUser": "ŠžŠ³Ń€Š°Š½ŠøŃ‡ŠµŠ½Š½Ń‹Š¹ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ API", + "extraApiUser": "Š”Š¾ŠæŠ¾Š»Š½ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Š¹ ограниченный ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ API", + "webOnlyUser": "Только веб-ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ", + "demoUser": "Демо-ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ (без настраиваемых параметров)", + "internalApiUser": "Š’Š½ŃƒŃ‚Ń€ŠµŠ½Š½ŠøŠ¹ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ API", + "forceChange": "Š¢Ń€ŠµŠ±Š¾Š²Š°Ń‚ŃŒ смену ŠæŠ°Ń€Š¾Š»Ń при вхоГе", + "submit": "Š”Š¾Ń…Ń€Š°Š½ŠøŃ‚ŃŒ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń", + "changeUserRole": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ Ń€Š¾Š»ŃŒ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń", + "authenticated": "ŠŃƒŃ‚ŠµŠ½Ń‚ŠøŃ„ŠøŃ†ŠøŃ€Š¾Š²Š°Š½", + "editOwnProfil": "Š ŠµŠ“Š°ŠŗŃ‚ŠøŃ€Š¾Š²Š°Ń‚ŃŒ свой ŠæŃ€Š¾Ń„ŠøŠ»ŃŒ", + "enabledUser": "активный ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ", + "disabledUser": "Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½Š½Ń‹Š¹ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ", + "activeUsers": "Активные ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Šø:", + "disabledUsers": "ŠžŃ‚ŠŗŠ»ŃŽŃ‡ŠµŠ½Š½Ń‹Šµ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Šø:", + "totalUsers": "Всего ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŠµŠ¹:", + "lastRequest": "ПослеГний запрос", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Дтатистика конечных точек", + "header": "Дтатистика конечных точек", + "top10": "Топ 10", + "top20": "Топ 20", + "all": "Все", + "refresh": "ŠžŠ±Š½Š¾Š²ŠøŃ‚ŃŒ", + "includeHomepage": "Š’ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ Š³Š»Š°Š²Š½ŃƒŃŽ ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ ('/')", + "includeLoginPage": "Š’ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ вхоГа ('/login')", + "totalEndpoints": "Всего конечных точек", + "totalVisits": "Всего посещений", + "showing": "Показано", + "selectedVisits": "Выбранные ŠæŠ¾ŃŠµŃ‰ŠµŠ½ŠøŃ", + "endpoint": "ŠšŠ¾Š½ŠµŃ‡Š½Š°Ń точка", + "visits": "ŠŸŠ¾ŃŠµŃ‰ŠµŠ½ŠøŃ", + "percentage": "ŠŸŃ€Š¾Ń†ŠµŠ½Ń‚", + "loading": "Š—Š°Š³Ń€ŃƒŠ·ŠŗŠ°...", + "failedToLoad": "ŠŠµ уГалось Š·Š°Š³Ń€ŃƒŠ·ŠøŃ‚ŃŒ Ганные конечной точки. ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, ŠæŠ¾ŠæŃ€Š¾Š±ŃƒŠ¹Ń‚Šµ Š¾Š±Š½Š¾Š²ŠøŃ‚ŃŒ.", + "home": "Š“Š»Š°Š²Š½Š°Ń", + "login": "ВхоГ", + "top": "Топ", + "numberOfVisits": "ŠšŠ¾Š»ŠøŃ‡ŠµŃŃ‚Š²Š¾ посещений", + "visitsTooltip": "ŠŸŠ¾ŃŠµŃ‰ŠµŠ½ŠøŃ: {0} ({1}% от общего числа)", + "retry": "ŠŸŠ¾Š²Ń‚Š¾Ń€ŠøŃ‚ŃŒ" + }, + "database": { + "title": "Š˜Š¼ŠæŠ¾Ń€Ń‚/ŃŠŗŃŠæŠ¾Ń€Ń‚ базы Ганных", + "header": "Š˜Š¼ŠæŠ¾Ń€Ń‚/ŃŠŗŃŠæŠ¾Ń€Ń‚ базы Ганных", + "fileName": "Š˜Š¼Ń файла", + "creationDate": "Дата ŃŠ¾Š·Š“Š°Š½ŠøŃ", + "fileSize": "Размер файла", + "deleteBackupFile": "Š£Š“Š°Š»ŠøŃ‚ŃŒ файл резервной копии", + "importBackupFile": "Š˜Š¼ŠæŠ¾Ń€Ń‚ŠøŃ€Š¾Š²Š°Ń‚ŃŒ файл резервной копии", + "createBackupFile": "Š”Š¾Š·Š“Š°Ń‚ŃŒ файл резервной копии", + "downloadBackupFile": "Š”ŠŗŠ°Ń‡Š°Ń‚ŃŒ файл резервной копии", + "info_1": "ŠŸŃ€Šø импорте Ганных важно Š¾Š±ŠµŃŠæŠµŃ‡ŠøŃ‚ŃŒ ŠæŃ€Š°Š²ŠøŠ»ŃŒŠ½ŃƒŃŽ ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Ńƒ. Если вы не ŃƒŠ²ŠµŃ€ŠµŠ½Ń‹ в своих Š“ŠµŠ¹ŃŃ‚Š²ŠøŃŃ…, Š¾Š±Ń€Š°Ń‚ŠøŃ‚ŠµŃŃŒ за ŠæŃ€Š¾Ń„ŠµŃŃŠøŠ¾Š½Š°Š»ŃŒŠ½Š¾Š¹ ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ. ŠžŃˆŠøŠ±ŠŗŠ° в ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Šµ может привести Šŗ ŃŠ±Š¾ŃŠ¼ в работе ŠæŃ€ŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ Š²ŠæŠ»Š¾Ń‚ŃŒ Го полной неработоспособности.", + "info_2": "Š˜Š¼Ń файла при Š·Š°Š³Ń€ŃƒŠ·ŠŗŠµ не имеет Š·Š½Š°Ń‡ŠµŠ½ŠøŃ. ŠžŠ½Š¾ Š±ŃƒŠ“ŠµŃ‚ переименовано в формат backup_user_yyyyMMddHHmm.sql Š“Š»Ń Š¾Š±ŠµŃŠæŠµŃ‡ŠµŠ½ŠøŃ ŠµŠ“ŠøŠ½Š¾Š¾Š±Ń€Š°Š·ŠøŃ наименований.", + "submit": "Š˜Š¼ŠæŠ¾Ń€Ń‚ŠøŃ€Š¾Š²Š°Ń‚ŃŒ Ń€ŠµŠ·ŠµŃ€Š²Š½ŃƒŃŽ ŠŗŠ¾ŠæŠøŃŽ", + "importIntoDatabaseSuccessed": "Š˜Š¼ŠæŠ¾Ń€Ń‚ в базу Ганных выполнен успешно", + "backupCreated": "Резервное копирование базы Ганных выполнено успешно", + "fileNotFound": "Файл не найГен", + "fileNullOrEmpty": "Файл не Голжен Š±Ń‹Ń‚ŃŒ ŠæŃƒŃŃ‚Ń‹Š¼", + "failedImportFile": "ŠŠµ уГалось ŠøŠ¼ŠæŠ¾Ń€Ń‚ŠøŃ€Š¾Š²Š°Ń‚ŃŒ файл", + "notSupported": "Эта Ń„ŃƒŠ½ŠŗŃ†ŠøŃ Š½ŠµŠ“Š¾ŃŃ‚ŃƒŠæŠ½Š° Š“Š»Ń вашего ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½ŠøŃ Šŗ базе Ганных." + }, + "session": { + "expired": "Š’Š°ŃˆŠ° ŃŠµŃŃŠøŃ истекла. ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, обновите ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ Šø ŠæŠ¾ŠæŃ€Š¾Š±ŃƒŠ¹Ń‚Šµ снова.", + "refreshPage": "ŠžŠ±Š½Š¾Š²ŠøŃ‚ŃŒ ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ" + }, + "home": { + "desc": "Š’Š°ŃˆŠµ локальное Ń€ŠµŃˆŠµŠ½ŠøŠµ Š“Š»Ń всех потребностей, ŃŠ²ŃŠ·Š°Š½Š½Ń‹Ń… с PDF.", + "searchBar": "Поиск Ń„ŃƒŠ½ŠŗŃ†ŠøŠ¹...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "ŠŸŃ€Š¾ŃŠ¼Š¾Ń‚Ń€, аннотирование, Гобавление текста или изображений" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "ŠœŃƒŠ»ŃŒŃ‚ŠøŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚ PDF", + "desc": "ŠžŠ±ŃŠŠµŠ“ŠøŠ½ŠµŠ½ŠøŠµ, поворот, ŠæŠµŃ€ŠµŃƒŠæŠ¾Ń€ŃŠ“Š¾Ń‡ŠøŠ²Š°Š½ŠøŠµ Šø уГаление страниц" + }, + "merge": { + "title": "ŠžŠ±ŃŠŠµŠ“ŠøŠ½ŠøŃ‚ŃŒ", + "desc": "Легко Š¾Š±ŃŠŠµŠ“ŠøŠ½ŃŠ¹Ń‚Šµ несколько PDF-файлов в оГин." + }, + "split": { + "title": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ", + "desc": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ PDF на несколько Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š¾Š²" + }, + "rotate": { + "title": "ŠŸŠ¾Š²ŠµŃ€Š½ŃƒŃ‚ŃŒ", + "desc": "Легко поворачивайте ваши PDF-файлы." + }, + "imageToPdf": { + "title": "Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ в PDF", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ (PNG, JPEG, GIF) в PDF." + }, + "pdfToImage": { + "title": "PDF в изображение", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ PDF в изображение (PNG, JPEG, GIF)." + }, + "pdfOrganiser": { + "title": "ŠžŃ€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ", + "desc": "УГаление/ŠæŠµŃ€ŠµŃƒŠæŠ¾Ń€ŃŠ“Š¾Ń‡ŠøŠ²Š°Š½ŠøŠµ страниц в Š»ŃŽŠ±Š¾Š¼ ŠæŠ¾Ń€ŃŠ“ŠŗŠµ" + }, + "addImage": { + "title": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ изображение", + "desc": "Š”Š¾Š±Š°Š²Š»ŃŠµŃ‚ изображение в указанное место PDF" + }, + "watermark": { + "title": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ Š²Š¾Š“ŃŠ½Š¾Š¹ знак", + "desc": "Š”Š¾Š±Š°Š²ŃŒŃ‚Šµ собственный Š²Š¾Š“ŃŠ½Š¾Š¹ знак в ваш PDF-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚." + }, + "permissions": { + "title": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŃ", + "desc": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚Šµ Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŃ вашего PDF-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°" + }, + "removePages": { + "title": "Š£Š“Š°Š»ŠøŃ‚ŃŒ", + "desc": "УГалите Š½ŠµŠ½ŃƒŠ¶Š½Ń‹Šµ страницы ŠøŠ· вашего PDF-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°." + }, + "addPassword": { + "title": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ ŠæŠ°Ń€Š¾Š»ŃŒ", + "desc": "Š—Š°ŃˆŠøŃ„Ń€ŃƒŠ¹Ń‚Šµ ваш PDF-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ паролем." + }, + "removePassword": { + "title": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŠæŠ°Ń€Š¾Š»ŃŒ", + "desc": "УГалите Š·Š°Ń‰ŠøŃ‚Ńƒ паролем ŠøŠ· вашего PDF-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°." + }, + "compressPdfs": { + "title": "Š”Š¶Š°Ń‚ŃŒ", + "desc": "Джимайте PDF-файлы Š“Š»Ń ŃƒŠ¼ŠµŠ½ŃŒŃˆŠµŠ½ŠøŃ ŠøŃ… размера." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ метаГанные", + "desc": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ/ŃƒŠ“Š°Š»ŠøŃ‚ŃŒ/Š“Š¾Š±Š°Š²ŠøŃ‚ŃŒ метаГанные ŠøŠ· PDF-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°" + }, + "fileToPDF": { + "title": "Файл в PDF", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ¹Ń‚Šµ практически Š»ŃŽŠ±Š¾Š¹ файл в PDF (DOCX, PNG, XLS, PPT, TXT Šø Š“Ń€ŃƒŠ³ŠøŠµ)" + }, + "ocr": { + "title": "OCR / ŠžŃ‡ŠøŃŃ‚ŠŗŠ° сканов", + "desc": "ŠžŃ‡ŠøŃŃ‚ŠŗŠ° сканов Šø распознавание текста с изображений в PDF с ŠæŠ¾ŃŠ»ŠµŠ“ŃƒŃŽŃ‰ŠøŠ¼ Гобавлением его как текст." + }, + "extractImages": { + "title": "Š˜Š·Š²Š»ŠµŃ‡ŃŒ ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "desc": "Š˜Š·Š²Š»ŠµŠŗŠ°ŠµŃ‚ все ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ ŠøŠ· PDF Šø ŃŠ¾Ń…Ń€Š°Š½ŃŠµŃ‚ ŠøŃ… в zip-архив" + }, + "pdfToPDFA": { + "title": "PDF в PDF/A", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ PDF в PDF/A Š“Š»Ń Голгосрочного Ń…Ń€Š°Š½ŠµŠ½ŠøŃ" + }, + "PDFToWord": { + "title": "PDF в Word", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ PDF в форматы Word (DOC, DOCX Šø ODT)" + }, + "PDFToPresentation": { + "title": "PDF в ŠæŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†ŠøŃŽ", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ PDF в форматы презентаций (PPT, PPTX Šø ODP)" + }, + "PDFToText": { + "title": "PDF в RTF (текст)", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ PDF в текстовый или RTF формат" + }, + "PDFToHTML": { + "title": "PDF в HTML", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ PDF в формат HTML" + }, + "PDFToXML": { + "title": "PDF в XML", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŠµ PDF в формат XML" + }, + "ScannerImageSplit": { + "title": "ŠžŠ±Š½Š°Ń€ŃƒŠ¶ŠµŠ½ŠøŠµ/разГеление сканированных фото", + "desc": "Š Š°Š·Š“ŠµŠ»ŃŠµŃ‚ несколько фотографий Š²Š½ŃƒŃ‚ри фото/PDF" + }, + "sign": { + "title": "ПоГпись", + "desc": "Š”Š¾Š±Š°Š²Š»ŃŠµŃ‚ поГпись в PDF рисованием, текстом или изображением" + }, + "flatten": { + "title": "ДвеГение", + "desc": "Š£Š“Š°Š»ŃŠµŃ‚ все интерактивные ŃŠ»ŠµŠ¼ŠµŠ½Ń‚Ń‹ Šø формы ŠøŠ· PDF" + }, + "repair": { + "title": "Восстановление", + "desc": "ŠŸŃ‹Ń‚Š°ŠµŃ‚ŃŃ Š²Š¾ŃŃŃ‚Š°Š½Š¾Š²ŠøŃ‚ŃŒ поврежГенный/сломанный PDF" + }, + "removeBlanks": { + "title": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŠæŃƒŃŃ‚Ń‹Šµ страницы", + "desc": "ŠžŠ±Š½Š°Ń€ŃƒŠ¶ŠøŠ²Š°ŠµŃ‚ Šø ŃƒŠ“Š°Š»ŃŠµŃ‚ ŠæŃƒŃŃ‚Ń‹Šµ страницы ŠøŠ· Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°" + }, + "removeAnnotations": { + "title": "Š£Š“Š°Š»ŠøŃ‚ŃŒ аннотации", + "desc": "Š£Š“Š°Š»ŃŠµŃ‚ все комментарии/аннотации ŠøŠ· PDF" + }, + "compare": { + "title": "Š”Ń€Š°Š²Š½ŠøŃ‚ŃŒ", + "desc": "Дравнивает Šø показывает Ń€Š°Š·Š»ŠøŃ‡ŠøŃ межГу 2 PDF-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Š¼Šø" + }, + "certSign": { + "title": "ŠŸŠ¾Š“ŠæŠøŃŠ°Ń‚ŃŒ сертификатом", + "desc": "ŠŸŠ¾Š“ŠæŠøŃŃ‹Š²Š°ŠµŃ‚ PDF сертификатом/ŠŗŠ»ŃŽŃ‡Š¾Š¼ (PEM/P12)" + }, + "removeCertSign": { + "title": "Š£Š“Š°Š»ŠøŃ‚ŃŒ сертификат поГписи", + "desc": "Š£Š“Š°Š»ŃŠµŃ‚ сертификат поГписи ŠøŠ· PDF" + }, + "pageLayout": { + "title": "ŠœŠ½Š¾Š³Š¾ŃŃ‚Ń€Š°Š½ŠøŃ‡Š½Š°Ń компоновка", + "desc": "ŠžŠ±ŃŠŠµŠ“ŠøŠ½ŃŠµŃ‚ несколько страниц PDF-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° в оГну ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ" + }, + "scalePages": { + "title": "ŠŠ°ŃŃ‚Ń€Š¾ŠøŃ‚ŃŒ размер/Š¼Š°ŃŃˆŃ‚Š°Š± страницы", + "desc": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ размер/Š¼Š°ŃŃˆŃ‚Š°Š± страницы Šø/или её соГержимого." + }, + "pipeline": { + "title": "ŠšŠ¾Š½Š²ŠµŠ¹ŠµŃ€", + "desc": "Š’Ń‹ŠæŠ¾Š»Š½ŃŠ¹Ń‚Šµ несколько Гействий с PDF, Š¾ŠæŃ€ŠµŠ“ŠµŠ»ŃŃ сценарии конвейера" + }, + "add-page-numbers": { + "title": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ Š½ŃƒŠ¼ŠµŃ€Š°Ń†ŠøŃŽ страниц", + "desc": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ номера страниц по всему Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ńƒ в указанном месте" + }, + "auto-rename": { + "title": "Автопереименование PDF-файла", + "desc": "Автоматически переименовывает PDF-файл на основе Š¾Š±Š½Š°Ń€ŃƒŠ¶ŠµŠ½Š½Š¾Š³Š¾ заголовка" + }, + "adjust-contrast": { + "title": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ° цветов/контраста", + "desc": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ° контраста, насыщенности Šø ŃŃ€ŠŗŠ¾ŃŃ‚Šø PDF" + }, + "crop": { + "title": "ŠžŠ±Ń€ŠµŠ·Š°Ń‚ŃŒ PDF", + "desc": "ŠžŠ±Ń€ŠµŠ·Š°Ń‚ŃŒ PDF Š“Š»Ń ŃƒŠ¼ŠµŠ½ŃŒŃˆŠµŠ½ŠøŃ его размера (ŃŠ¾Ń…Ń€Š°Š½ŃŠµŃ‚ текст!)" + }, + "autoSplitPDF": { + "title": "АвторазГеление страниц", + "desc": "Автоматическое разГеление сканированного PDF с физическим разГелителем страниц по QR-коГу" + }, + "sanitizePdf": { + "title": "ŠžŃ‡ŠøŃŃ‚ŠŗŠ°", + "desc": "УГаление скриптов Šø Š“Ń€ŃƒŠ³ŠøŃ… ŃŠ»ŠµŠ¼ŠµŠ½Ń‚Š¾Š² ŠøŠ· PDF-файлов" + }, + "URLToPDF": { + "title": "URL/веб-сайт в PDF", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠµŃ‚ Š»ŃŽŠ±Š¾Š¹ http(s)URL в PDF" + }, + "HTMLToPDF": { + "title": "HTML в PDF", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠµŃ‚ Š»ŃŽŠ±Š¾Š¹ HTML-файл или zip в PDF" + }, + "MarkdownToPDF": { + "title": "Markdown в PDF", + "desc": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠµŃ‚ Š»ŃŽŠ±Š¾Š¹ файл Markdown в PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "ŠŸŠ¾Š»ŃƒŃ‡ŠøŃ‚ŃŒ ВДЮ ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃŽ о PDF", + "desc": "Добирает Š²ŃŃŽ Š²Š¾Š·Š¼Š¾Š¶Š½ŃƒŃŽ ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃŽ о PDF" + }, + "extractPage": { + "title": "Š˜Š·Š²Š»ŠµŃ‡ŃŒ ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ(ы)", + "desc": "Š˜Š·Š²Š»ŠµŠŗŠ°ŠµŃ‚ выбранные страницы ŠøŠ· PDF" + }, + "PdfToSinglePage": { + "title": "ŠžŠ“Š½Š° Š±Š¾Š»ŃŒŃˆŠ°Ń страница", + "desc": "ŠžŠ±ŃŠŠµŠ“ŠøŠ½ŃŠµŃ‚ все страницы PDF в оГну Š±Š¾Š»ŃŒŃˆŃƒŃŽ ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ" + }, + "showJS": { + "title": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚ŃŒ Javascript", + "desc": "Š˜Ń‰ŠµŃ‚ Šø отображает Š»ŃŽŠ±Š¾Š¹ JS, внеГрённый в PDF" + }, + "autoRedact": { + "title": "Автоматическое реГактирование", + "desc": "Автоматически Š·Š°ŠŗŃ€Š°ŃˆŠøŠ²Š°ŠµŃ‚ (чернит) текст в PDF на основе вхоГного текста" + }, + "redact": { + "title": "Š ŃƒŃ‡Š½Š¾Šµ реГактирование", + "desc": "Š ŠµŠ“Š°ŠŗŃ‚ŠøŃ€ŃƒŠµŃ‚ PDF на основе выбранного текста, нарисованных форм Šø/или выбранных страниц" + }, + "tableExtraxt": { + "title": "PDF в CSV", + "desc": "Š˜Š·Š²Š»ŠµŠŗŠ°ŠµŃ‚ таблицы ŠøŠ· PDF с преобразованием в CSV" + }, + "autoSizeSplitPDF": { + "title": "АвторазГеление по Ń€Š°Š·Š¼ŠµŃ€Ńƒ/ŠŗŠ¾Š»ŠøŃ‡ŠµŃŃ‚Š²Ńƒ", + "desc": "Š Š°Š·Š“ŠµŠ»ŃŠµŃ‚ оГин PDF на несколько Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š¾Š² на основе размера, количества страниц или количества Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š¾Š²" + }, + "overlay-pdfs": { + "title": "ŠŠ°Š»Š¾Š¶ŠµŠ½ŠøŠµ PDF", + "desc": "ŠŠ°ŠŗŠ»Š°Š“Ń‹Š²Š°ŠµŃ‚ PDF поверх Š“Ń€ŃƒŠ³Š¾Š³Š¾ PDF" + }, + "split-by-sections": { + "title": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ PDF по ŃŠµŠŗŃ†ŠøŃŠ¼", + "desc": "Š Š°Š·Š“ŠµŠ»ŃŠµŃ‚ ŠŗŠ°Š¶Š“ŃƒŃŽ ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ PDF на меньшие Š³Š¾Ń€ŠøŠ·Š¾Š½Ń‚Š°Š»ŃŒŠ½Ń‹Šµ Šø Š²ŠµŃ€Ń‚ŠøŠŗŠ°Š»ŃŒŠ½Ń‹Šµ секции" + }, + "AddStampRequest": { + "title": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ ŃˆŃ‚Š°Š¼Šæ в PDF", + "desc": "Š”Š¾Š±Š°Š²Š»ŃŠµŃ‚ текстовые или графические ŃˆŃ‚Š°Š¼ŠæŃ‹ в ŃƒŠŗŠ°Š·Š°Š½Š½Ń‹Ń… местах" + }, + "removeImagePdf": { + "title": "Š£Š“Š°Š»ŠøŃ‚ŃŒ изображение", + "desc": "Š£Š“Š°Š»ŃŠµŃ‚ ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ ŠøŠ· PDF Š“Š»Ń ŃƒŠ¼ŠµŠ½ŃŒŃˆŠµŠ½ŠøŃ размера файла" + }, + "splitPdfByChapters": { + "title": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ PDF по главам", + "desc": "Š Š°Š·Š“ŠµŠ»ŃŠµŃ‚ PDF на несколько файлов на основе ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Ń‹ его глав" + }, + "validateSignature": { + "title": "ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° поГписи PDF", + "desc": "ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° цифровых поГписей Šø сертификатов в PDF-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń…" + }, + "replaceColorPdf": { + "title": "Замена Šø ŠøŠ½Š²ŠµŃ€ŃŠøŃ цвета", + "desc": "Š—Š°Š¼ŠµŠ½ŃŠµŃ‚ цвет текста Šø фона в PDF Šø ŠøŠ½Š²ŠµŃ€Ń‚ŠøŃ€ŃƒŠµŃ‚ все цвета PDF Š“Š»Ń ŃƒŠ¼ŠµŠ½ŃŒŃˆŠµŠ½ŠøŃ размера файла" + } + }, + "viewPdf": { + "tags": "просмотр,чтение,аннотации,текст,изображение", + "title": "View/Edit PDF", + "header": "ŠŸŃ€Š¾ŃŠ¼Š¾Ń‚Ń€ PDF" + }, + "multiTool": { + "tags": "ŠœŃƒŠ»ŃŒŃ‚ŠøŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚,ŠœŠ½Š¾Š³Š¾Š¾ŠæŠµŃ€Š°Ń†ŠøŠ¾Š½Š½Ń‹Š¹,UI,перетаскивание,ŠŗŠ»ŠøŠµŠ½Ń‚ŃŠŗŠ°Ń Ń‡Š°ŃŃ‚ŃŒ,интерактивный", + "title": "ŠœŃƒŠ»ŃŒŃ‚ŠøŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚ PDF", + "header": "ŠœŃƒŠ»ŃŒŃ‚ŠøŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚ PDF", + "uploadPrompts": "Š˜Š¼Ń файла", + "selectAll": "Š’Ń‹Š±Ń€Š°Ń‚ŃŒ все", + "deselectAll": "ŠžŃ‚Š¼ŠµŠ½ŠøŃ‚ŃŒ выбор всех", + "selectPages": "Выбор страницы", + "selectedPages": "Выбранные страницы", + "page": "Дтраница", + "deleteSelected": "Š£Š“Š°Š»ŠøŃ‚ŃŒ выбранные", + "downloadAll": "Экспорт", + "downloadSelected": "Экспорт выбранных", + "insertPageBreak": "Š’ŃŃ‚Š°Š²ŠøŃ‚ŃŒ разрыв страницы", + "addFile": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ файл", + "rotateLeft": "ŠŸŠ¾Š²ŠµŃ€Š½ŃƒŃ‚ŃŒ влево", + "rotateRight": "ŠŸŠ¾Š²ŠµŃ€Š½ŃƒŃ‚ŃŒ вправо", + "split": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ", + "moveLeft": "ŠŸŠµŃ€ŠµŠ¼ŠµŃŃ‚ŠøŃ‚ŃŒ влево", + "moveRight": "ŠŸŠµŃ€ŠµŠ¼ŠµŃŃ‚ŠøŃ‚ŃŒ вправо", + "delete": "Š£Š“Š°Š»ŠøŃ‚ŃŒ", + "dragDropMessage": "Выбрано страниц", + "undo": "ŠžŃ‚Š¼ŠµŠ½ŠøŃ‚ŃŒ", + "redo": "ŠŸŠ¾Š²Ń‚Š¾Ń€ŠøŃ‚ŃŒ" + }, + "merge": { + "tags": "объеГинение,операции со страницами,ŃŠµŃ€Š²ŠµŃ€Š½Š°Ń Ń‡Š°ŃŃ‚ŃŒ", + "title": "ŠžŠ±ŃŠŠµŠ“ŠøŠ½ŠøŃ‚ŃŒ", + "header": "ŠžŠ±ŃŠŠµŠ“ŠøŠ½ŠµŠ½ŠøŠµ Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠøŃ… PDF (2+)", + "sortByName": "Š”Š¾Ń€Ń‚ŠøŃ€Š¾Š²Š°Ń‚ŃŒ по имени", + "sortByDate": "Š”Š¾Ń€Ń‚ŠøŃ€Š¾Š²Š°Ń‚ŃŒ по Гате", + "removeCertSign": "Š£Š“Š°Š»ŠøŃ‚ŃŒ Ń†ŠøŃ„Ń€Š¾Š²ŃƒŃŽ поГпись в объеГиненном файле?", + "submit": "ŠžŠ±ŃŠŠµŠ“ŠøŠ½ŠøŃ‚ŃŒ" + }, + "split": { + "tags": "операции со страницами,разГеление,многостраничный,вырезание,ŃŠµŃ€Š²ŠµŃ€Š½Š°Ń Ń‡Š°ŃŃ‚ŃŒ", + "title": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ PDF", + "header": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ PDF", + "desc": { + "1": "Числа, которые вы выбираете, ŃŃ‚Š¾ номера страниц, на которых нужно Š²Ń‹ŠæŠ¾Š»Š½ŠøŃ‚ŃŒ разГеление", + "2": "Таким образом, выбор 1,3,7-9 разГелит 10-страничный Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ на 6 Š¾Ń‚Š“ŠµŠ»ŃŒŠ½Ń‹Ń… PDF с:", + "3": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #1: Дтраница 1", + "4": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #2: Дтраницы 2 Šø 3", + "5": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #3: Дтраницы 4, 5, 6 Šø 7", + "6": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #4: Дтраница 8", + "7": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #5: Дтраница 9", + "8": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #6: Дтраница 10" + }, + "splitPages": "ВвеГите страницы Š“Š»Ń Ń€Š°Š·Š“ŠµŠ»ŠµŠ½ŠøŃ:", + "submit": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ" + }, + "rotate": { + "tags": "ŃŠµŃ€Š²ŠµŃ€Š½Š°Ń Ń‡Š°ŃŃ‚ŃŒ", + "title": "ŠŸŠ¾Š²ŠµŃ€Š½ŃƒŃ‚ŃŒ PDF", + "header": "ŠŸŠ¾Š²ŠµŃ€Š½ŃƒŃ‚ŃŒ PDF", + "selectAngle": "Выберите угол поворота (кратный 90 Š³Ń€Š°Š“ŃƒŃŠ°Š¼):", + "submit": "ŠŸŠ¾Š²ŠµŃ€Š½ŃƒŃ‚ŃŒ" + }, + "imageToPdf": { + "tags": "ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†ŠøŃ,изображение,jpg,картинка,фото" + }, + "pdfToImage": { + "tags": "ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†ŠøŃ,изображение,jpg,картинка,фото", + "title": "PDF в изображение", + "header": "PDF в изображение", + "selectText": "Формат ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "singleOrMultiple": "Тип Ń€ŠµŠ·ŃƒŠ»ŃŒŃ‚Š°Ń‚Š° ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "single": "ŠžŠ“Š½Š¾ большое изображение", + "multi": "ŠŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ изображений", + "colorType": "Тип цвета", + "color": "Цветной", + "grey": "ŠžŃ‚Ń‚ŠµŠ½ŠŗŠø серого", + "blackwhite": "Черно-белый (возможна ŠæŠ¾Ń‚ŠµŃ€Ń Ганных!)", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ", + "info": "Python не ŃƒŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½. Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ŃŃ Š“Š»Ń конвертации в WebP.", + "placeholder": "(например, 1,2,8 или 4,7,12-16 или 2n-1)" + }, + "pdfOrganiser": { + "tags": "Š“Š²ŃƒŃŃ‚Š¾Ń€Š¾Š½Š½ŃŃ ŠæŠµŃ‡Š°Ń‚ŃŒ,четные,нечетные,сортировка,перемещение", + "title": "ŠžŃ€Š³Š°Š½ŠøŠ·Š°Ń‚Š¾Ń€ страниц", + "header": "ŠžŃ€Š³Š°Š½ŠøŠ·Š°Ń‚Š¾Ń€ страниц PDF", + "submit": "ŠŸŠµŃ€ŠµŃƒŠæŠ¾Ń€ŃŠ“Š¾Ń‡ŠøŃ‚ŃŒ страницы", + "mode": { + "_value": "Режим", + "1": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠ¹ ŠæŠ¾Ń€ŃŠ“Š¾Šŗ страниц", + "2": "ŠžŠ±Ń€Š°Ń‚Š½Ń‹Š¹ ŠæŠ¾Ń€ŃŠ“Š¾Šŗ", + "3": "Дортировка Гуплекса", + "4": "Дортировка Š±ŃƒŠŗŠ»ŠµŃ‚а", + "5": "Дортировка Š±ŃƒŠŗŠ»ŠµŃ‚а с боковым сшиванием", + "6": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ на четные-нечетные", + "7": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŠæŠµŃ€Š²ŃƒŃŽ", + "8": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŠæŠ¾ŃŠ»ŠµŠ“Š½ŃŽŃŽ", + "9": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŠæŠµŃ€Š²ŃƒŃŽ Šø ŠæŠ¾ŃŠ»ŠµŠ“Š½ŃŽŃŽ", + "10": "ŠžŠ±ŃŠŠµŠ“ŠøŠ½ŠµŠ½ŠøŠµ четных-нечетных", + "11": "Duplicate all pages" + }, + "placeholder": "(например, 1,3,2 или 4-8,2,10-12 или 2n-1)" + }, + "addImage": { + "tags": "изображение,jpg,картинка,фото", + "title": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ изображение", + "header": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ изображение в PDF", + "everyPage": "ŠšŠ°Š¶Š“Š°Ń страница?", + "upload": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ изображение", + "submit": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ изображение" + }, + "watermark": { + "tags": "текст,ŠæŠ¾Š²Ń‚Š¾Ń€ŃŃŽŃ‰ŠøŠ¹ŃŃ,метка,собственный,авторское право,Ń‚Š¾Ń€Š³Š¾Š²Š°Ń марка,изображение,jpg,картинка,фото", + "title": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ Š²Š¾Š“ŃŠ½Š¾Š¹ знак", + "header": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ Š²Š¾Š“ŃŠ½Š¾Š¹ знак", + "customColor": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠ¹ цвет текста", + "selectText": { + "1": "Выберите PDF Š“Š»Ń Š“Š¾Š±Š°Š²Š»ŠµŠ½ŠøŃ Š²Š¾Š“ŃŠ½Š¾Š³Š¾ знака:", + "2": "Текст Š²Š¾Š“ŃŠ½Š¾Š³Š¾ знака:", + "3": "Размер ŃˆŃ€ŠøŃ„Ń‚Š°:", + "4": "ŠŸŠ¾Š²Š¾Ń€Š¾Ń‚ (0-360):", + "5": "Š“Š¾Ń€ŠøŠ·Š¾Š½Ń‚Š°Š»ŃŒŠ½Ń‹Š¹ интервал (Ń€Š°ŃŃŃ‚Š¾ŃŠ½ŠøŠµ межГу Š²Š¾Š“ŃŠ½Ń‹Š¼Šø знаками по горизонтали):", + "6": "Š’ŠµŃ€Ń‚ŠøŠŗŠ°Š»ŃŒŠ½Ń‹Š¹ интервал (Ń€Š°ŃŃŃ‚Š¾ŃŠ½ŠøŠµ межГу Š²Š¾Š“ŃŠ½Ń‹Š¼Šø знаками по вертикали):", + "7": "ŠŸŃ€Š¾Š·Ń€Š°Ń‡Š½Š¾ŃŃ‚ŃŒ (0% - 100%):", + "8": "Тип Š²Š¾Š“ŃŠ½Š¾Š³Š¾ знака:", + "9": "Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ Š²Š¾Š“ŃŠ½Š¾Š³Š¾ знака:", + "10": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ PDF в PDF-изображение" + }, + "submit": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ Š²Š¾Š“ŃŠ½Š¾Š¹ знак", + "type": { + "1": "Текст", + "2": "Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ" + } + }, + "permissions": { + "tags": "чтение,запись,реГактирование,ŠæŠµŃ‡Š°Ń‚ŃŒ", + "title": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŃ", + "header": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŃ", + "warning": "Внимание: Š“Š»Ń Š½ŠµŠøŠ·Š¼ŠµŠ½ŃŠµŠ¼Š¾ŃŃ‚Šø ŃŃ‚ŠøŃ… Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŠ¹ Ń€ŠµŠŗŠ¾Š¼ŠµŠ½Š“ŃƒŠµŃ‚ŃŃ ŃƒŃŃ‚Š°Š½Š°Š²Š»ŠøŠ²Š°Ń‚ŃŒ ŠøŃ… с паролем через ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ Š“Š¾Š±Š°Š²Š»ŠµŠ½ŠøŃ ŠæŠ°Ń€Š¾Š»Ń", + "selectText": { + "1": "Выберите PDF Š“Š»Ń ŠøŠ·Š¼ŠµŠ½ŠµŠ½ŠøŃ Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŠ¹", + "2": "Устанавливаемые Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŃ", + "3": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ компоновку Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°", + "4": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ извлечение соГержимого", + "5": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ извлечение Š“Š»Ń ŃŠæŠµŃ†ŠøŠ°Š»ŃŒŠ½Ń‹Ń… возможностей", + "6": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ заполнение форм", + "7": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ Š¼Š¾Š“ŠøŃ„ŠøŠŗŠ°Ń†ŠøŃŽ", + "8": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ Š¼Š¾Š“ŠøŃ„ŠøŠŗŠ°Ń†ŠøŃŽ аннотаций", + "9": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ ŠæŠµŃ‡Š°Ń‚ŃŒ", + "10": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ ŠæŠµŃ‡Š°Ń‚ŃŒ в высоком качестве" + }, + "submit": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ" + }, + "removePages": { + "tags": "Š£Š“Š°Š»ŠøŃ‚ŃŒ страницы,уГаление страниц" + }, + "addPassword": { + "tags": "Š±ŠµŠ·Š¾ŠæŠ°ŃŠ½Š¾ŃŃ‚ŃŒ,защита", + "title": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ ŠæŠ°Ń€Š¾Š»ŃŒ", + "header": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ ŠæŠ°Ń€Š¾Š»ŃŒ (Шифрование)", + "selectText": { + "1": "Выберите PDF Š“Š»Ń ŃˆŠøŃ„Ń€Š¾Š²Š°Š½ŠøŃ", + "2": "ŠŸŠ°Ń€Š¾Š»ŃŒ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń", + "3": "Длина ŠŗŠ»ŃŽŃ‡Š° ŃˆŠøŃ„Ń€Š¾Š²Š°Š½ŠøŃ", + "4": "Более высокие Š·Š½Š°Ń‡ŠµŠ½ŠøŃ сильнее, но более низкие Š·Š½Š°Ń‡ŠµŠ½ŠøŃ Š¾Š±ŠµŃŠæŠµŃ‡ŠøŠ²Š°ŃŽŃ‚ Š»ŃƒŃ‡ŃˆŃƒŃŽ ŃŠ¾Š²Š¼ŠµŃŃ‚ŠøŠ¼Š¾ŃŃ‚ŃŒ.", + "5": "Устанавливаемые Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŃ (Š ŠµŠŗŠ¾Š¼ŠµŠ½Š“ŃƒŠµŃ‚ŃŃ ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ вместе с паролем Š²Š»Š°Š“ŠµŠ»ŃŒŃ†Š°)", + "6": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ компоновку Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°", + "7": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ извлечение соГержимого", + "8": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ извлечение Š“Š»Ń ŃŠæŠµŃ†ŠøŠ°Š»ŃŒŠ½Ń‹Ń… возможностей", + "9": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ заполнение форм", + "10": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ Š¼Š¾Š“ŠøŃ„ŠøŠŗŠ°Ń†ŠøŃŽ", + "11": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ Š¼Š¾Š“ŠøŃ„ŠøŠŗŠ°Ń†ŠøŃŽ аннотаций", + "12": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ ŠæŠµŃ‡Š°Ń‚ŃŒ", + "13": "Š—Š°ŠæŃ€ŠµŃ‚ŠøŃ‚ŃŒ ŠæŠµŃ‡Š°Ń‚ŃŒ в высоком качестве", + "14": "ŠŸŠ°Ń€Š¾Š»ŃŒ Š²Š»Š°Š“ŠµŠ»ŃŒŃ†Š°", + "15": "ŠžŠ³Ń€Š°Š½ŠøŃ‡ŠøŠ²Š°ŠµŃ‚ Š“ŠµŠ¹ŃŃ‚Š²ŠøŃ с Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š¾Š¼ после его Š¾Ń‚ŠŗŃ€Ń‹Ń‚ŠøŃ (ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ŃŃ не всеми программами Ń‡Ń‚ŠµŠ½ŠøŃ)", + "16": "ŠžŠ³Ń€Š°Š½ŠøŃ‡ŠøŠ²Š°ŠµŃ‚ само открытие Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°" + }, + "submit": "Š—Š°ŃˆŠøŃ„Ń€Š¾Š²Š°Ń‚ŃŒ" + }, + "removePassword": { + "tags": "Š±ŠµŠ·Š¾ŠæŠ°ŃŠ½Š¾ŃŃ‚ŃŒ,Ń€Š°ŃŃˆŠøŃ„Ń€Š¾Š²ŠŗŠ°,защита,уГаление ŠæŠ°Ń€Š¾Š»Ń", + "title": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŠæŠ°Ń€Š¾Š»ŃŒ", + "header": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŠæŠ°Ń€Š¾Š»ŃŒ (Š Š°ŃŃˆŠøŃ„Ń€Š¾Š²Š°Ń‚ŃŒ)", + "selectText": { + "1": "Выберите PDF Š“Š»Ń Ń€Š°ŃŃˆŠøŃ„Ń€Š¾Š²ŠŗŠø", + "2": "ŠŸŠ°Ń€Š¾Š»ŃŒ" + }, + "submit": "Š£Š“Š°Š»ŠøŃ‚ŃŒ" + }, + "compressPdfs": { + "tags": "сжатие,маленький,ŠŗŃ€Š¾ŃˆŠµŃ‡Š½Ń‹Š¹" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "заголовок,автор,Гата,созГание,Š²Ń€ŠµŠ¼Ń,ŠøŠ·Š“Š°Ń‚ŠµŠ»ŃŒ,ŠæŃ€Š¾ŠøŠ·Š²Š¾Š“ŠøŃ‚ŠµŠ»ŃŒ,статистика", + "title": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ метаГанные", + "header": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ метаГанные", + "selectText": { + "1": "ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, Š¾Ń‚Ń€ŠµŠ“Š°ŠŗŃ‚ŠøŃ€ŃƒŠ¹Ń‚Šµ переменные, которые хотите ŠøŠ·Š¼ŠµŠ½ŠøŃ‚ŃŒ", + "2": "Š£Š“Š°Š»ŠøŃ‚ŃŒ все метаГанные", + "3": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚ŃŒ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠµ метаГанные:", + "4": "Š”Ń€ŃƒŠ³ŠøŠµ метаГанные:", + "5": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŃƒŃŽ запись метаГанных" + }, + "author": "Автор:", + "creationDate": "Дата ŃŠ¾Š·Š“Š°Š½ŠøŃ (yyyy/MM/dd HH:mm:ss):", + "creator": "Š”Š¾Š·Š“Š°Ń‚ŠµŠ»ŃŒ:", + "keywords": "ŠšŠ»ŃŽŃ‡ŠµŠ²Ń‹Šµ слова:", + "modDate": "Дата ŠøŠ·Š¼ŠµŠ½ŠµŠ½ŠøŃ (yyyy/MM/dd HH:mm:ss):", + "producer": "ŠŸŃ€Š¾ŠøŠ·Š²Š¾Š“ŠøŃ‚ŠµŠ»ŃŒ:", + "subject": "Тема:", + "trapped": "Trapped:", + "submit": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ" + }, + "fileToPDF": { + "tags": "преобразование,формат,Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚,картинка,ŠæŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†ŠøŃ,текст,ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†ŠøŃ,офис,Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ń‹,word,excel,powerpoint", + "title": "Файл в PDF", + "header": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ Š»ŃŽŠ±Š¾Š¹ файл в PDF", + "credit": "Этот сервис ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ LibreOffice Šø Unoconv Š“Š»Ń ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŃ файлов.", + "supportedFileTypesInfo": "ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŠ¼Ń‹Šµ типы файлов", + "supportedFileTypes": "ŠŸŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŠ¼Ń‹Šµ типы файлов Голжны Š²ŠŗŠ»ŃŽŃ‡Š°Ń‚ŃŒ перечисленные ниже, оГнако Š“Š»Ń ŠæŠ¾Š»ŃƒŃ‡ŠµŠ½ŠøŃ полного Š°ŠŗŃ‚ŃƒŠ°Š»ŃŒŠ½Š¾Š³Š¾ списка поГГерживаемых форматов Š¾Š±Ń€Š°Ń‚ŠøŃ‚ŠµŃŃŒ Šŗ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŠø LibreOffice", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ в PDF" + }, + "ocr": { + "tags": "распознавание,текст,изображение,сканирование,чтение,ŠøŠ“ŠµŠ½Ń‚ŠøŃ„ŠøŠŗŠ°Ń†ŠøŃ,Š¾Š±Š½Š°Ń€ŃƒŠ¶ŠµŠ½ŠøŠµ,Ń€ŠµŠ“Š°ŠŗŃ‚ŠøŃ€ŃƒŠµŠ¼Ń‹Š¹", + "title": "OCR / ŠžŃ‡ŠøŃŃ‚ŠŗŠ° сканов", + "header": "ŠžŃ‡ŠøŃŃ‚ŠŗŠ° сканов / OCR (оптическое распознавание символов)", + "selectText": { + "1": "Выберите ŃŠ·Ń‹ŠŗŠø, которые Голжны Š±Ń‹Ń‚ŃŒ Š¾Š±Š½Š°Ń€ŃƒŠ¶ŠµŠ½Ń‹ в PDF (перечислены те, которые Š¾Š±Š½Š°Ń€ŃƒŠ¶ŠµŠ½Ń‹ в Ганный момент):", + "2": "Š”Š¾Š·Š“Š°Ń‚ŃŒ текстовый файл с OCR-текстом вместе с OCR-обработанным PDF", + "3": "Š˜ŃŠæŃ€Š°Š²ŠøŃ‚ŃŒ страницы, отсканированные поГ углом, ŠæŃƒŃ‚ŠµŠ¼ ŠøŃ… поворота в ŠæŃ€Š°Š²ŠøŠ»ŃŒŠ½Š¾Šµ положение", + "4": "ŠžŃ‡ŠøŃŃ‚ŠøŃ‚ŃŒ ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ, чтобы ŃƒŠ¼ŠµŠ½ŃŒŃˆŠøŃ‚ŃŒ Š²ŠµŃ€Š¾ŃŃ‚Š½Š¾ŃŃ‚ŃŒ Š½Š°Ń…Š¾Š¶Š“ŠµŠ½ŠøŃ OCR текста в фоновом шуме. (Без ŠøŠ·Š¼ŠµŠ½ŠµŠ½ŠøŃ вывоГа)", + "5": "ŠžŃ‡ŠøŃŃ‚ŠøŃ‚ŃŒ ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ, чтобы ŃƒŠ¼ŠµŠ½ŃŒŃˆŠøŃ‚ŃŒ Š²ŠµŃ€Š¾ŃŃ‚Š½Š¾ŃŃ‚ŃŒ Š½Š°Ń…Š¾Š¶Š“ŠµŠ½ŠøŃ OCR текста в фоновом шуме, с сохранением очистки в вывоГе.", + "6": "Š˜Š³Š½Š¾Ń€ŠøŃ€Š¾Š²Š°Ń‚ŃŒ страницы с интерактивным текстом, Š¾Š±Ń€Š°Š±Š°Ń‚Ń‹Š²Š°Ń‚ŃŒ OCR Ń‚Š¾Š»ŃŒŠŗŠ¾ Š“Š»Ń страниц с ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃŠ¼Šø", + "7": "ŠŸŃ€ŠøŠ½ŃƒŠ“ŠøŃ‚ŠµŠ»ŃŒŠ½Š¾Šµ OCR, Š±ŃƒŠ“ŠµŃ‚ Š¾Š±Ń€Š°Š±Š°Ń‚Ń‹Š²Š°Ń‚ŃŒ ŠŗŠ°Š¶Š“ŃƒŃŽ ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ, ŃƒŠ“Š°Š»ŃŃ все исхоГные текстовые ŃŠ»ŠµŠ¼ŠµŠ½Ń‚Ń‹", + "8": "ŠžŠ±Ń‹Ń‡Š½Ń‹Š¹ (выГаст ошибку, если PDF соГержит текст)", + "9": "Š”Š¾ŠæŠ¾Š»Š½ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Šµ настройки", + "10": "Режим OCR", + "11": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ после OCR (ŃƒŠ“Š°Š»ŃŠµŃ‚ ВДЕ ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ, полезно Ń‚Š¾Š»ŃŒŠŗŠ¾ как Ń‡Š°ŃŃ‚ŃŒ шага ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŃ)", + "12": "Тип ренГеринга (ŠæŃ€Š¾Š“Š²ŠøŠ½ŃƒŃ‚Ń‹Š¹)" + }, + "help": "ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, прочтите эту Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†ŠøŃŽ о том, как ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ ŃŃ‚Š¾ Š“Š»Ń Š“Ń€ŃƒŠ³ŠøŃ… ŃŠ·Ń‹ŠŗŠ¾Š² Šø/или ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ не в Docker", + "credit": "Этот сервис ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ qpdf Šø Tesseract Š“Š»Ń OCR.", + "submit": "ŠžŠ±Ń€Š°Š±Š¾Ń‚Š°Ń‚ŃŒ PDF с OCR" + }, + "extractImages": { + "tags": "картинка,фото,сохранение,архив,zip,захват,извлечение", + "title": "Š˜Š·Š²Š»ŠµŃ‡ŃŒ ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "header": "Š˜Š·Š²Š»ŠµŃ‡ŃŒ ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "selectText": "Выберите формат ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ Š“Š»Ń ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŃ извлеченных изображений", + "allowDuplicates": "Š”Š¾Ń…Ń€Š°Š½ŃŃ‚ŃŒ Š“ŃƒŠ±Š»ŠøŠŗŠ°Ń‚Ń‹ изображений", + "submit": "Š˜Š·Š²Š»ŠµŃ‡ŃŒ" + }, + "pdfToPDFA": { + "tags": "архив,Голгосрочный,станГарт,ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†ŠøŃ,хранение,сохранение", + "title": "PDF в PDF/A", + "header": "PDF в PDF/A", + "credit": "Этот сервис ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ libreoffice Š“Š»Ń ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŃ в PDF/A", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ", + "tip": "Š’ Š½Š°ŃŃ‚Š¾ŃŃ‰ŠµŠµ Š²Ń€ŠµŠ¼Ń не работает с несколькими вхоГными файлами оГновременно", + "outputFormat": "Формат вывоГа", + "pdfWithDigitalSignature": "PDF соГержит Ń†ŠøŃ„Ń€Š¾Š²ŃƒŃŽ поГпись. ŠžŠ½Š° Š±ŃƒŠ“ŠµŃ‚ уГалена на ŃŠ»ŠµŠ“ŃƒŃŽŃ‰ŠµŠ¼ шаге." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,преобразование,формат,ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†ŠøŃ,офис,microsoft,docfile", + "title": "PDF в Word", + "header": "PDF в Word", + "selectText": { + "1": "Формат выхоГного файла" + }, + "credit": "Этот сервис ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ LibreOffice Š“Š»Ń ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŃ файлов.", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ" + }, + "PDFToPresentation": { + "tags": "слайГы,показ,офис,microsoft", + "title": "PDF в ŠæŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†ŠøŃŽ", + "header": "PDF в ŠæŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†ŠøŃŽ", + "selectText": { + "1": "Формат выхоГного файла" + }, + "credit": "Этот сервис ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ LibreOffice Š“Š»Ń ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŃ файлов.", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ" + }, + "PDFToText": { + "tags": "richformat,richtextformat,rich text format", + "title": "PDF в RTF (текст)", + "header": "PDF в RTF (текст)", + "selectText": { + "1": "Формат выхоГного файла" + }, + "credit": "Этот сервис ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ LibreOffice Š“Š»Ń ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŃ файлов.", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ" + }, + "PDFToHTML": { + "tags": "веб-контент,Š±Ń€Š°ŃƒŠ·ŠµŃ€Š½Ń‹Š¹ формат", + "title": "PDF в HTML", + "header": "PDF в HTML", + "credit": "Этот сервис ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ pdftohtml Š“Š»Ń ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŃ файлов.", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ" + }, + "PDFToXML": { + "tags": "извлечение Ганных,ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€ŠøŃ€Š¾Š²Š°Š½Š½Ń‹Š¹ контент,взаимоГействие,преобразование,ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†ŠøŃ", + "title": "PDF в XML", + "header": "PDF в XML", + "credit": "Этот сервис ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ LibreOffice Š“Š»Ń ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Š½ŠøŃ файлов.", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ" + }, + "ScannerImageSplit": { + "tags": "разГеление,автоопреГеление,сканы,Š¼ŃƒŠ»ŃŒŃ‚Šø-фото,Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ", + "selectText": { + "1": "ŠŸŠ¾Ń€Š¾Š³Š¾Š²Ń‹Š¹ угол:", + "2": "Устанавливает Š¼ŠøŠ½ŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ Š°Š±ŃŠ¾Š»ŃŽŃ‚Š½Ń‹Š¹ угол, необхоГимый Š“Š»Ń поворота ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ (по ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ: 10).", + "3": "Š”Š¾ŠæŃƒŃŠŗ:", + "4": "ŠžŠæŃ€ŠµŠ“ŠµŠ»ŃŠµŃ‚ Гиапазон ŠøŠ·Š¼ŠµŠ½ŠµŠ½ŠøŃ цвета Š²Š¾ŠŗŃ€ŃƒŠ³ преГполагаемого фонового цвета (по ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ: 30).", + "5": "ŠœŠøŠ½ŠøŠ¼Š°Š»ŃŒŠ½Š°Ń ŠæŠ»Š¾Ń‰Š°Š“ŃŒ:", + "6": "Устанавливает Š¼ŠøŠ½ŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ порог площаГи Š“Š»Ń фотографии (по ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ: 10000).", + "7": "ŠœŠøŠ½ŠøŠ¼Š°Š»ŃŒŠ½Š°Ń ŠæŠ»Š¾Ń‰Š°Š“ŃŒ ŠŗŠ¾Š½Ń‚ŃƒŃ€Š°:", + "8": "Устанавливает Š¼ŠøŠ½ŠøŠ¼Š°Š»ŃŒŠ½Ń‹Š¹ порог площаГи ŠŗŠ¾Š½Ń‚ŃƒŃ€Š° Š“Š»Ń фотографии", + "9": "Размер границы:", + "10": "Устанавливает размер Š“Š¾Š±Š°Š²Š»ŃŠµŠ¼Š¾Š¹ Šø ŃƒŠ“Š°Š»ŃŠµŠ¼Š¾Š¹ границы Š“Š»Ń ŠæŃ€ŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‰ŠµŠ½ŠøŃ белых границ в вывоГе (по ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ: 1)." + }, + "info": "Python не ŃƒŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½. ŠžŠ½ необхоГим Š“Š»Ń работы." + }, + "sign": { + "tags": "Š°Š²Ń‚Š¾Ń€ŠøŠ·Š°Ń†ŠøŃ,инициалы,Š½Š°Ń€ŠøŃŠ¾Š²Š°Š½Š½Š°Ń поГпись,Ń‚ŠµŠŗŃŃ‚Š¾Š²Š°Ń поГпись,поГпись изображением", + "title": "ПоГпись", + "header": "ŠŸŠ¾Š“ŠæŠøŃŠ°Ń‚ŃŒ PDF", + "upload": "Š—Š°Š³Ń€ŃƒŠ·ŠøŃ‚ŃŒ изображение", + "draw": "ŠŠ°Ń€ŠøŃŠ¾Š²Š°Ń‚ŃŒ поГпись", + "text": "Текстовый ввоГ", + "clear": "ŠžŃ‡ŠøŃŃ‚ŠøŃ‚ŃŒ", + "add": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ", + "saved": "Дохраненные поГписи", + "save": "Š”Š¾Ń…Ń€Š°Š½ŠøŃ‚ŃŒ поГпись", + "personalSigs": "Личные поГписи", + "sharedSigs": "ŠžŠ±Ń‰ŠøŠµ поГписи", + "noSavedSigs": "Дохраненные поГписи не найГены", + "addToAll": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ на все страницы", + "delete": "Š£Š“Š°Š»ŠøŃ‚ŃŒ", + "first": "ŠŸŠµŃ€Š²Š°Ń страница", + "last": "ŠŸŠ¾ŃŠ»ŠµŠ“Š½ŃŃ страница", + "next": "Š”Š»ŠµŠ“ŃƒŃŽŃ‰Š°Ń страница", + "previous": "ŠŸŃ€ŠµŠ“Ń‹Š“ŃƒŃ‰Š°Ń страница", + "maintainRatio": "ŠŸŠµŃ€ŠµŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ сохранение пропорций", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "статический,Š“ŠµŠ°ŠŗŃ‚ŠøŠ²Š°Ń†ŠøŃ,неинтерактивный,ŃƒŠæŃ€Š¾Ń‰ŠµŠ½ŠøŠµ", + "title": "ДвеГение", + "header": "ДвеГение PDF", + "flattenOnlyForms": "Двести Ń‚Š¾Š»ŃŒŠŗŠ¾ формы", + "submit": "Двести" + }, + "repair": { + "tags": "исправление,восстановление,ŠŗŠ¾Ń€Ń€ŠµŠŗŃ†ŠøŃ,возврат", + "title": "Восстановление", + "header": "Восстановление PDF", + "submit": "Š’Š¾ŃŃŃ‚Š°Š½Š¾Š²ŠøŃ‚ŃŒ" + }, + "removeBlanks": { + "tags": "очистка,ŃƒŠæŃ€Š¾Ń‰ŠµŠ½ŠøŠµ,без соГержимого,Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ", + "title": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŠæŃƒŃŃ‚Ń‹Šµ страницы", + "header": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŠæŃƒŃŃ‚Ń‹Šµ страницы", + "threshold": "ŠŸŠ¾Ń€Š¾Š³ белизны пикселей:", + "thresholdDesc": "ŠŸŠ¾Ń€Š¾Š³ Š¾ŠæŃ€ŠµŠ“ŠµŠ»ŠµŠ½ŠøŃ, насколько белым Голжен Š±Ń‹Ń‚ŃŒ пиксель, чтобы ŃŃ‡ŠøŃ‚Š°Ń‚ŃŒŃŃ 'белым'. 0 = черный, 255 = чисто белый.", + "whitePercent": "ŠŸŃ€Š¾Ń†ŠµŠ½Ń‚ белого (%):", + "whitePercentDesc": "ŠŸŃ€Š¾Ń†ŠµŠ½Ń‚ страницы, который Голжен Š±Ń‹Ń‚ŃŒ 'белыми' ŠæŠøŠŗŃŠµŠ»ŃŠ¼Šø Š“Š»Ń ŃƒŠ“Š°Š»ŠµŠ½ŠøŃ", + "submit": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŠæŃƒŃŃ‚Ń‹Šµ" + }, + "removeAnnotations": { + "tags": "комментарии,выГеление,заметки,разметка,уГаление", + "title": "Š£Š“Š°Š»ŠøŃ‚ŃŒ аннотации", + "header": "Š£Š“Š°Š»ŠøŃ‚ŃŒ аннотации", + "submit": "Š£Š“Š°Š»ŠøŃ‚ŃŒ" + }, + "compare": { + "tags": "различие,контраст,ŠøŠ·Š¼ŠµŠ½ŠµŠ½ŠøŃ,анализ", + "title": "Š”Ń€Š°Š²Š½ŠøŃ‚ŃŒ", + "header": "Š”Ń€Š°Š²Š½ŠøŃ‚ŃŒ PDF", + "highlightColor": { + "1": "Цвет Š²Ń‹Š“ŠµŠ»ŠµŠ½ŠøŃ 1:", + "2": "Цвет Š²Ń‹Š“ŠµŠ»ŠµŠ½ŠøŃ 2:" + }, + "document": { + "1": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ 1", + "2": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ 2" + }, + "submit": "Š”Ń€Š°Š²Š½ŠøŃ‚ŃŒ", + "complex": { + "message": "ŠžŠ“ŠøŠ½ или оба преГоставленных Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° ŃŠ²Š»ŃŃŽŃ‚ŃŃ большими файлами, Ń‚Š¾Ń‡Š½Š¾ŃŃ‚ŃŒ ŃŃ€Š°Š²Š½ŠµŠ½ŠøŃ может Š±Ń‹Ń‚ŃŒ снижена" + }, + "large": { + "file": { + "message": "ŠžŠ“ŠøŠ½ или оба преГоставленных Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° слишком велики Š“Š»Ń обработки" + } + }, + "no": { + "text": { + "message": "Выбранные PDF-файлы не соГержат текстового соГержимого. ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, выберите PDF-файлы с текстом Š“Š»Ń ŃŃ€Š°Š²Š½ŠµŠ½ŠøŃ." + } + } + }, + "certSign": { + "tags": "Š°ŃƒŃ‚ŠµŠ½Ń‚ŠøŃ„ŠøŠŗŠ°Ń†ŠøŃ,PEM,P12,Š¾Ń„ŠøŃ†ŠøŠ°Š»ŃŒŠ½Ń‹Š¹,ŃˆŠøŃ„Ń€Š¾Š²Š°Š½ŠøŠµ", + "title": "ПоГписание сертификатом", + "header": "ŠŸŠ¾Š“ŠæŠøŃˆŠøŃ‚Šµ PDF вашим сертификатом (в разработке)", + "selectPDF": "Выберите PDF-файл Š“Š»Ń ŠæŠ¾Š“ŠæŠøŃŠ°Š½ŠøŃ:", + "jksNote": "ŠŸŃ€ŠøŠ¼ŠµŃ‡Š°Š½ŠøŠµ: Если тип вашего сертификата не указан ниже, ŠæŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, ŠæŃ€ŠµŠ¾Š±Ń€Š°Š·ŃƒŠ¹Ń‚Šµ его в файл хранилища ŠŗŠ»ŃŽŃ‡ŠµŠ¹ Java (.jks) с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ ŃƒŃ‚ŠøŠ»ŠøŃ‚Ń‹ команГной строки keytool. Затем выберите Š¾ŠæŃ†ŠøŃŽ .jks файла ниже.", + "selectKey": "Выберите файл закрытого ŠŗŠ»ŃŽŃ‡Š° (формат PKCS#8, может Š±Ń‹Ń‚ŃŒ .pem или .der):", + "selectCert": "Выберите файл сертификата (формат X.509, может Š±Ń‹Ń‚ŃŒ .pem или .der):", + "selectP12": "Выберите файл хранилища ŠŗŠ»ŃŽŃ‡ŠµŠ¹ PKCS#12 (.p12 или .pfx) (Š½ŠµŠ¾Š±ŃŠ·Š°Ń‚ŠµŠ»ŃŒŠ½Š¾, если преГоставлен, Голжен ŃŠ¾Š“ŠµŃ€Š¶Š°Ń‚ŃŒ ваш закрытый ŠŗŠ»ŃŽŃ‡ Šø сертификат):", + "selectJKS": "Выберите файл хранилища ŠŗŠ»ŃŽŃ‡ŠµŠ¹ Java (.jks или .keystore):", + "certType": "Тип сертификата", + "password": "ВвеГите ŠæŠ°Ń€Š¾Š»ŃŒ хранилища ŠŗŠ»ŃŽŃ‡ŠµŠ¹ или закрытого ŠŗŠ»ŃŽŃ‡Š° (если ŠµŃŃ‚ŃŒ):", + "showSig": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚ŃŒ поГпись", + "reason": "ŠŸŃ€ŠøŃ‡ŠøŠ½Š°", + "location": "ŠœŠµŃŃ‚Š¾ŠæŠ¾Š»Š¾Š¶ŠµŠ½ŠøŠµ", + "name": "Š˜Š¼Ń", + "showLogo": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚ŃŒ логотип", + "submit": "ŠŸŠ¾Š“ŠæŠøŃŠ°Ń‚ŃŒ PDF" + }, + "removeCertSign": { + "tags": "Š°ŃƒŃ‚ŠµŠ½Ń‚ŠøŃ„ŠøŠŗŠ°Ń†ŠøŃ,PEM,P12,Š¾Ń„ŠøŃ†ŠøŠ°Š»ŃŒŠ½Ń‹Š¹,Ń€Š°ŃŃˆŠøŃ„Ń€Š¾Š²ŠŗŠ°", + "title": "Š£Š“Š°Š»ŠøŃ‚ŃŒ сертификат поГписи", + "header": "Š£Š“Š°Š»ŠøŃ‚ŃŒ цифровой сертификат ŠøŠ· PDF", + "selectPDF": "Выберите PDF-файл:", + "submit": "Š£Š“Š°Š»ŠøŃ‚ŃŒ поГпись" + }, + "pageLayout": { + "tags": "объеГинение,ŠŗŠ¾Š¼ŠæŠ¾Š·ŠøŃ†ŠøŃ,еГиный виГ,Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ", + "title": "ŠœŠ½Š¾Š³Š¾ŃŃ‚Ń€Š°Š½ŠøŃ‡Š½Š°Ń компоновка", + "header": "ŠœŠ½Š¾Š³Š¾ŃŃ‚Ń€Š°Š½ŠøŃ‡Š½Š°Ń компоновка", + "pagesPerSheet": "Дтраниц на лист:", + "addBorder": "Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ границы", + "submit": "ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ" + }, + "scalePages": { + "tags": "изменение размера,Š¼Š¾Š“ŠøŃ„ŠøŠŗŠ°Ń†ŠøŃ,размеры,Š°Š“Š°ŠæŃ‚Š°Ń†ŠøŃ", + "title": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ° Š¼Š°ŃŃˆŃ‚Š°Š±Š° страницы", + "header": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ° Š¼Š°ŃŃˆŃ‚Š°Š±Š° страницы", + "pageSize": "Размер страницы Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°.", + "keepPageSize": "Š˜ŃŃ…Š¾Š“Š½Ń‹Š¹ размер", + "scaleFactor": "ŠšŠ¾ŃŃ„Ń„ŠøŃ†ŠøŠµŠ½Ń‚ Š¼Š°ŃŃˆŃ‚Š°Š±ŠøŃ€Š¾Š²Š°Š½ŠøŃ (обрезки) страницы.", + "submit": "ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ" + }, + "add-page-numbers": { + "tags": "Š½ŃƒŠ¼ŠµŃ€Š°Ń†ŠøŃ,метка,Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ,инГекс" + }, + "auto-rename": { + "tags": "Š°Š²Ń‚Š¾Š¾Š±Š½Š°Ń€ŃƒŠ¶ŠµŠ½ŠøŠµ,на основе заголовка,Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ,переименование", + "title": "Автопереименование", + "header": "Автопереименование PDF", + "submit": "Автопереименование" + }, + "adjust-contrast": { + "tags": "Ń†Š²ŠµŃ‚Š¾ŠŗŠ¾Ń€Ń€ŠµŠŗŃ†ŠøŃ,настройка,Š¼Š¾Š“ŠøŃ„ŠøŠŗŠ°Ń†ŠøŃ,ŃƒŠ»ŃƒŃ‡ŃˆŠµŠ½ŠøŠµ" + }, + "crop": { + "tags": "обрезка,уменьшение,реГактирование,форма", + "title": "ŠžŠ±Ń€ŠµŠ·ŠŗŠ°", + "header": "ŠžŠ±Ń€ŠµŠ·ŠŗŠ° PDF", + "submit": "ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ" + }, + "autoSplitPDF": { + "tags": "QR-коГ,разГеление,скан-сегмент,Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ", + "title": "Автоматическое разГеление PDF", + "header": "Автоматическое разГеление PDF", + "description": "ŠŸŠµŃ‡Š°Ń‚Š°Š¹Ń‚Šµ, Š²ŃŃ‚Š°Š²Š»ŃŠ¹Ń‚Šµ, ŃŠŗŠ°Š½ŠøŃ€ŃƒŠ¹Ń‚Šµ, Š·Š°Š³Ń€ŃƒŠ¶Š°Š¹Ń‚Šµ Šø ŠæŠ¾Š·Š²Š¾Š»ŃŒŃ‚Šµ нам автоматически Ń€Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ ваши Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ń‹. ŠŠµ Ń‚Ń€ŠµŠ±ŃƒŠµŃ‚ŃŃ Ń€ŃƒŃ‡Š½Š°Ń сортировка.", + "selectText": { + "1": "Распечатайте несколько Ń€Š°Š·Š“ŠµŠ»ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Ń… листов (поГойГет черно-Š±ŠµŠ»Š°Ń ŠæŠµŃ‡Š°Ń‚ŃŒ).", + "2": "ŠžŃ‚ŃŠŗŠ°Š½ŠøŃ€ŃƒŠ¹Ń‚Šµ все ваши Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ń‹ за раз, вставив Ń€Š°Š·Š“ŠµŠ»ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Šµ листы межГу ними.", + "3": "Š—Š°Š³Ń€ŃƒŠ·ŠøŃ‚Šµ оГин большой отсканированный PDF-файл Šø ŠæŠ¾Š·Š²Š¾Š»ŃŒŃ‚Šµ Stirling PDF ŃŠ“ŠµŠ»Š°Ń‚ŃŒ все Š¾ŃŃ‚Š°Š»ŃŒŠ½Š¾Šµ.", + "4": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Šµ страницы автоматически Š¾Š±Š½Š°Ń€ŃƒŠ¶ŠøŠ²Š°ŃŽŃ‚ся Šø ŃƒŠ“Š°Š»ŃŃŽŃ‚ŃŃ, Š³Š°Ń€Š°Š½Ń‚ŠøŃ€ŃƒŃ Š°ŠŗŠŗŃƒŃ€Š°Ń‚Š½Ń‹Š¹ конечный Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚." + }, + "formPrompt": "ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ PDF, соГержащий разГелители страниц Stirling-PDF:", + "duplexMode": "Š”Š²ŃƒŃŃ‚Š¾Ń€Š¾Š½Š½ŠøŠ¹ режим (сканирование с Š“Š²ŃƒŃ… сторон)", + "dividerDownload2": "Š”ŠŗŠ°Ń‡Š°Ń‚ŃŒ 'Автоматический Ń€Š°Š·Š“ŠµŠ»ŠøŃ‚ŠµŠ»ŃŒ (с ŠøŠ½ŃŃ‚Ń€ŃƒŠŗŃ†ŠøŃŠ¼Šø).pdf'", + "submit": "ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ" + }, + "sanitizePdf": { + "tags": "очистка,Š±ŠµŠ·Š¾ŠæŠ°ŃŠ½Š¾ŃŃ‚ŃŒ,защита,уГаление ŃƒŠ³Ń€Š¾Š·" + }, + "URLToPDF": { + "tags": "веб-захват,сохранение страницы,веб в Гок,Š°Ń€Ń…ŠøŠ²Š°Ń†ŠøŃ", + "title": "URL в PDF", + "header": "URL в PDF", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ", + "credit": "Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ WeasyPrint" + }, + "HTMLToPDF": { + "tags": "разметка,веб-контент,преобразование,ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†ŠøŃ", + "title": "HTML в PDF", + "header": "HTML в PDF", + "help": "ŠŸŃ€ŠøŠ½ŠøŠ¼Š°ŠµŃ‚ HTML-файлы Šø ZIP-архивы, соГержащие html/css/ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ Šø т.Š“.", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ", + "credit": "Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ WeasyPrint", + "zoom": "Š£Ń€Š¾Š²ŠµŠ½ŃŒ Š¼Š°ŃŃˆŃ‚Š°Š±ŠøŃ€Š¾Š²Š°Š½ŠøŃ Š“Š»Ń Š¾Ń‚Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ веб-сайта.", + "pageWidth": "Ширина страницы в сантиметрах. (ŠŸŃƒŃŃ‚Š¾ Š“Š»Ń Š·Š½Š°Ń‡ŠµŠ½ŠøŃ по ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ)", + "pageHeight": "Высота страницы в сантиметрах. (ŠŸŃƒŃŃ‚Š¾ Š“Š»Ń Š·Š½Š°Ń‡ŠµŠ½ŠøŃ по ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ)", + "marginTop": "Верхнее поле страницы в миллиметрах. (ŠŸŃƒŃŃ‚Š¾ Š“Š»Ń Š·Š½Š°Ń‡ŠµŠ½ŠøŃ по ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ)", + "marginBottom": "ŠŠøŠ¶Š½ŠµŠµ поле страницы в миллиметрах. (ŠŸŃƒŃŃ‚Š¾ Š“Š»Ń Š·Š½Š°Ń‡ŠµŠ½ŠøŃ по ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ)", + "marginLeft": "Левое поле страницы в миллиметрах. (ŠŸŃƒŃŃ‚Š¾ Š“Š»Ń Š·Š½Š°Ń‡ŠµŠ½ŠøŃ по ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ)", + "marginRight": "ŠŸŃ€Š°Š²Š¾Šµ поле страницы в миллиметрах. (ŠŸŃƒŃŃ‚Š¾ Š“Š»Ń Š·Š½Š°Ń‡ŠµŠ½ŠøŃ по ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ)", + "printBackground": "ŠžŃ‚Š¾Š±Ń€Š°Š¶Š°Ń‚ŃŒ фон веб-сайтов.", + "defaultHeader": "Š’ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ заголовок по ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ (ŠøŠ¼Ń Šø номер страницы)", + "cssMediaType": "Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ тип Š½Š¾ŃŠøŃ‚ŠµŠ»Ń CSS страницы.", + "none": "ŠŠµŃ‚", + "print": "ŠŸŠµŃ‡Š°Ń‚ŃŒ", + "screen": "Экран" + }, + "MarkdownToPDF": { + "tags": "разметка,веб-контент,преобразование,ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†ŠøŃ", + "title": "Markdown в PDF", + "header": "Markdown в PDF", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ", + "help": "Š’ разработке", + "credit": "Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ,Ганные,статистика,параметры", + "title": "ŠŸŠ¾Š»ŃƒŃ‡ŠøŃ‚ŃŒ ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃŽ о PDF", + "header": "ŠŸŠ¾Š»ŃƒŃ‡ŠøŃ‚ŃŒ ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃŽ о PDF", + "submit": "ŠŸŠ¾Š»ŃƒŃ‡ŠøŃ‚ŃŒ ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃŽ", + "downloadJson": "Š”ŠŗŠ°Ń‡Š°Ń‚ŃŒ JSON" + }, + "extractPage": { + "tags": "извлечение" + }, + "PdfToSinglePage": { + "tags": "оГна страница" + }, + "showJS": { + "tags": "JS", + "title": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚ŃŒ Javascript", + "header": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚ŃŒ Javascript", + "downloadJS": "Š”ŠŗŠ°Ń‡Š°Ń‚ŃŒ Javascript", + "submit": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚ŃŒ" + }, + "autoRedact": { + "tags": "РеГактирование,Дкрытие,зачернение,чёрный,маркер,скрытый", + "title": "Автоматическое реГактирование", + "header": "Автоматическое реГактирование", + "colorLabel": "Цвет", + "textsToRedactLabel": "Текст Š“Š»Ń Ń€ŠµŠ“Š°ŠŗŃ‚ŠøŃ€Š¾Š²Š°Š½ŠøŃ (построчно)", + "textsToRedactPlaceholder": "например \\nŠšŠ¾Š½Ń„ŠøŠ“ŠµŠ½Ń†ŠøŠ°Š»ŃŒŠ½Š¾ \\nŠ”Š¾Š²ŠµŃ€ŃˆŠµŠ½Š½Š¾ секретно", + "useRegexLabel": "Š˜ŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ Ń€ŠµŠ³ŃƒŠ»ŃŃ€Š½Ń‹Šµ Š²Ń‹Ń€Š°Š¶ŠµŠ½ŠøŃ", + "wholeWordSearchLabel": "Поиск целых слов", + "customPaddingLabel": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠµ Š¾Ń‚ŃŃ‚ŃƒŠæŃ‹", + "convertPDFToImageLabel": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ PDF в PDF-изображение (ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ŃŃ Š“Š»Ń ŃƒŠ“Š°Š»ŠµŠ½ŠøŃ текста за рамкой)", + "submitButton": "ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ" + }, + "redact": { + "tags": "РеГактирование,Дкрытие,зачернение,чёрный,маркер,скрытый,Ń€ŃƒŃ‡Š½Š¾Š¹", + "title": "Š ŃƒŃ‡Š½Š¾Šµ реГактирование", + "header": "Š ŃƒŃ‡Š½Š¾Šµ реГактирование", + "submit": "Š ŠµŠ“Š°ŠŗŃ‚ŠøŃ€Š¾Š²Š°Ń‚ŃŒ", + "textBasedRedaction": "РеГактирование на основе текста", + "pageBasedRedaction": "РеГактирование на основе страниц", + "convertPDFToImageLabel": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ PDF в PDF-изображение (ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ŃŃ Š“Š»Ń ŃƒŠ“Š°Š»ŠµŠ½ŠøŃ текста за рамкой)", + "pageRedactionNumbers": { + "title": "Дтраницы", + "placeholder": "(например, 1,2,8 или 4,7,12-16 или 2n-1)" + }, + "redactionColor": { + "title": "Цвет Ń€ŠµŠ“Š°ŠŗŃ‚ŠøŃ€Š¾Š²Š°Š½ŠøŃ" + }, + "export": "Экспорт", + "upload": "Š—Š°Š³Ń€ŃƒŠ·ŠøŃ‚ŃŒ", + "boxRedaction": "РеГактирование рисованием рамки", + "zoom": "ŠœŠ°ŃŃˆŃ‚Š°Š±", + "zoomIn": "Š£Š²ŠµŠ»ŠøŃ‡ŠøŃ‚ŃŒ", + "zoomOut": "Š£Š¼ŠµŠ½ŃŒŃˆŠøŃ‚ŃŒ", + "nextPage": "Š”Š»ŠµŠ“ŃƒŃŽŃ‰Š°Ń страница", + "previousPage": "ŠŸŃ€ŠµŠ“Ń‹Š“ŃƒŃ‰Š°Ń страница", + "toggleSidebar": "ŠŸŠµŃ€ŠµŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ Š±Š¾ŠŗŠ¾Š²ŃƒŃŽ панель", + "showThumbnails": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚ŃŒ Š¼ŠøŠ½ŠøŠ°Ń‚ŃŽŃ€Ń‹", + "showDocumentOutline": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚ŃŒ ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Ńƒ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° (Гвойной щелчок Š“Š»Ń Ń€Š°Š·Š²ŠµŃ€Ń‚Ń‹Š²Š°Š½ŠøŃ/ŃŠ²ŠµŃ€Ń‚Ń‹Š²Š°Š½ŠøŃ всех ŃŠ»ŠµŠ¼ŠµŠ½Ń‚Š¾Š²)", + "showAttatchments": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚ŃŒ Š²Š»Š¾Š¶ŠµŠ½ŠøŃ", + "showLayers": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚ŃŒ слои (Гвойной щелчок Š“Š»Ń сброса всех слоев Šŗ ŃŠ¾ŃŃ‚Š¾ŃŠ½ŠøŃŽ по ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ)", + "colourPicker": "Выбор цвета", + "findCurrentOutlineItem": "ŠŠ°Š¹Ń‚Šø Ń‚ŠµŠŗŃƒŃ‰ŠøŠ¹ ŃŠ»ŠµŠ¼ŠµŠ½Ń‚ ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Ń‹", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,Š˜Š·Š²Š»ŠµŃ‡ŠµŠ½ŠøŠµ таблиц,извлечение,ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†ŠøŃ" + }, + "autoSizeSplitPDF": { + "tags": "pdf,разГеление,Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚,Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ" + }, + "overlay-pdfs": { + "tags": "ŠŠ°Š»Š¾Š¶ŠµŠ½ŠøŠµ", + "header": "ŠŠ°Š»Š¾Š¶ŠµŠ½ŠøŠµ PDF-файлов", + "baseFile": { + "label": "Выберите базовый PDF-файл" + }, + "overlayFiles": { + "label": "Выберите наклаГываемые PDF-файлы" + }, + "mode": { + "label": "Выберите режим Š½Š°Š»Š¾Š¶ŠµŠ½ŠøŃ", + "sequential": "ŠŸŠ¾ŃŠ»ŠµŠ“Š¾Š²Š°Ń‚ŠµŠ»ŃŒŠ½Š¾Šµ наложение", + "interleaved": "Š§ŠµŃ€ŠµŠ“ŃƒŃŽŃ‰ŠµŠµŃŃ наложение", + "fixedRepeat": "Фиксированное ŠæŠ¾Š²Ń‚Š¾Ń€ŃŃŽŃ‰ŠµŠµŃŃ наложение" + }, + "counts": { + "label": "ŠšŠ¾Š»ŠøŃ‡ŠµŃŃ‚Š²Š¾ наложений (Š“Š»Ń режима фиксированного ŠæŠ¾Š²Ń‚Š¾Ń€ŠµŠ½ŠøŃ)", + "placeholder": "ВвеГите количество через Š·Š°ŠæŃŃ‚ŃƒŃŽ (например, 2,3,1)" + }, + "position": { + "label": "Выберите ŠæŠ¾Š·ŠøŃ†ŠøŃŽ Š½Š°Š»Š¾Š¶ŠµŠ½ŠøŃ", + "foreground": "ŠŠ° переГнем плане", + "background": "ŠŠ° заГнем плане" + }, + "submit": "ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ" + }, + "split-by-sections": { + "tags": "РазГеление по ŃŠµŠŗŃ†ŠøŃŠ¼,Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ,ŠŠ°ŃŃ‚Ń€Š¾ŠøŃ‚ŃŒ", + "title": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ PDF по ŃŠµŠŗŃ†ŠøŃŠ¼", + "header": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ PDF на секции", + "horizontal": { + "label": "Š“Š¾Ń€ŠøŠ·Š¾Š½Ń‚Š°Š»ŃŒŠ½Ń‹Šµ разГелы", + "placeholder": "ВвеГите количество Š³Š¾Ń€ŠøŠ·Š¾Š½Ń‚Š°Š»ŃŒŠ½Ń‹Ń… разГелов" + }, + "vertical": { + "label": "Š’ŠµŃ€Ń‚ŠøŠŗŠ°Š»ŃŒŠ½Ń‹Šµ разГелы", + "placeholder": "ВвеГите количество Š²ŠµŃ€Ń‚ŠøŠŗŠ°Š»ŃŒŠ½Ń‹Ń… разГелов" + }, + "submit": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ PDF", + "merge": "ŠžŠ±ŃŠŠµŠ“ŠøŠ½ŠøŃ‚ŃŒ в оГин PDF" + }, + "AddStampRequest": { + "tags": "Штамп,Š”Š¾Š±Š°Š²ŠøŃ‚ŃŒ изображение,Ń†ŠµŠ½Ń‚Ń€ŠøŃ€Š¾Š²Š°Ń‚ŃŒ изображение,Š’Š¾Š“ŃŠ½Š¾Š¹ знак,PDF,Встраивание,ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ°", + "header": "Штамп PDF", + "title": "Штамп PDF", + "stampType": "Тип ŃˆŃ‚Š°Š¼ŠæŠ°", + "stampText": "Текст ŃˆŃ‚Š°Š¼ŠæŠ°", + "stampImage": "Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ ŃˆŃ‚Š°Š¼ŠæŠ°", + "alphabet": "Алфавит", + "fontSize": "Размер ŃˆŃ€ŠøŃ„Ń‚Š°/ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "rotation": "ŠŸŠ¾Š²Š¾Ń€Š¾Ń‚", + "opacity": "ŠŸŃ€Š¾Š·Ń€Š°Ń‡Š½Š¾ŃŃ‚ŃŒ", + "position": "ŠŸŠ¾Š·ŠøŃ†ŠøŃ", + "overrideX": "ŠŸŠµŃ€ŠµŠ¾ŠæŃ€ŠµŠ“ŠµŠ»ŠøŃ‚ŃŒ ŠŗŠ¾Š¾Ń€Š“ŠøŠ½Š°Ń‚Ńƒ X", + "overrideY": "ŠŸŠµŃ€ŠµŠ¾ŠæŃ€ŠµŠ“ŠµŠ»ŠøŃ‚ŃŒ ŠŗŠ¾Š¾Ń€Š“ŠøŠ½Š°Ń‚Ńƒ Y", + "customMargin": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠµ ŠæŠ¾Š»Ń", + "customColor": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠ¹ цвет текста", + "submit": "ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ" + }, + "removeImagePdf": { + "tags": "УГаление ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ,операции со страницами,Š”ŠµŃ€Š²ŠµŃ€Š½Š°Ń Ń‡Š°ŃŃ‚ŃŒ" + }, + "splitPdfByChapters": { + "tags": "разГеление,главы,заклаГки,Š¾Ń€Š³Š°Š½ŠøŠ·Š°Ń†ŠøŃ" + }, + "validateSignature": { + "tags": "поГпись,проверка,Š²Š°Š»ŠøŠ“Š°Ń†ŠøŃ,pdf,сертификат,Ń†ŠøŃ„Ń€Š¾Š²Š°Ń поГпись,ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° поГписи,ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° сертификата", + "title": "ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° поГписей PDF", + "header": "ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° цифровых поГписей", + "selectPDF": "Выберите поГписанный PDF-файл", + "submit": "ŠŸŃ€Š¾Š²ŠµŃ€ŠøŃ‚ŃŒ поГписи", + "results": "Š ŠµŠ·ŃƒŠ»ŃŒŃ‚Š°Ń‚Ń‹ проверки", + "status": { + "_value": "Š”Ń‚Š°Ń‚ŃƒŃ", + "valid": "Š”ŠµŠ¹ŃŃ‚Š²ŠøŃ‚ŠµŠ»ŃŒŠ½Š°", + "invalid": "ŠŠµŠ“ŠµŠ¹ŃŃ‚Š²ŠøŃ‚ŠµŠ»ŃŒŠ½Š°" + }, + "signer": "ŠŸŠ¾Š“ŠæŠøŃŠ°Š½Ń‚", + "date": "Дата", + "reason": "ŠŸŃ€ŠøŃ‡ŠøŠ½Š°", + "location": "ŠœŠµŃŃ‚Š¾ŠæŠ¾Š»Š¾Š¶ŠµŠ½ŠøŠµ", + "noSignatures": "Š’ ŃŃ‚Š¾Š¼ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šµ не найГено цифровых поГписей", + "chain": { + "invalid": "ŠŸŃ€Š¾Š²ŠµŃ€ŠŗŠ° цепочки сертификатов не уГалась - невозможно ŠæŃ€Š¾Š²ŠµŃ€ŠøŃ‚ŃŒ Š»ŠøŃ‡Š½Š¾ŃŃ‚ŃŒ поГписанта" + }, + "trust": { + "invalid": "Дертификат Š¾Ń‚ŃŃƒŃ‚ŃŃ‚Š²ŃƒŠµŃ‚ в Говеренном хранилище - источник не может Š±Ń‹Ń‚ŃŒ проверен" + }, + "cert": { + "expired": "Дрок Š“ŠµŠ¹ŃŃ‚Š²ŠøŃ сертификата истек", + "revoked": "Дертификат был отозван", + "info": "Š”Š²ŠµŠ“ŠµŠ½ŠøŃ о сертификате", + "issuer": "Š˜Š·Š“Š°Ń‚ŠµŠ»ŃŒ", + "subject": "Š”ŃƒŠ±ŃŠŠµŠŗŃ‚", + "serialNumber": "Дерийный номер", + "validFrom": "Действителен с", + "validUntil": "Действителен Го", + "algorithm": "Алгоритм", + "keySize": "Размер ŠŗŠ»ŃŽŃ‡Š°", + "version": "Š’ŠµŃ€ŃŠøŃ", + "keyUsage": "Использование ŠŗŠ»ŃŽŃ‡Š°", + "selfSigned": "ДамопоГписанный", + "bits": "бит" + }, + "signature": { + "info": "Š˜Š½Ń„Š¾Ń€Š¼Š°Ń†ŠøŃ о поГписи", + "_value": "ПоГпись", + "mathValid": "ПоГпись математически корректна, ŠŠž:" + }, + "selectCustomCert": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠ¹ файл сертификата X.509 (ŠŠµŠ¾Š±ŃŠ·Š°Ń‚ŠµŠ»ŃŒŠ½Š¾)" + }, + "replace-color": { + "title": "Замена-Š˜Š½Š²ŠµŃ€ŃŠøŃ цвета", + "header": "Замена-Š˜Š½Š²ŠµŃ€ŃŠøŃ цвета PDF", + "selectText": { + "1": "ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€Ń‹ замены или инверсии цвета", + "2": "По ŃƒŠ¼Š¾Š»Ń‡Š°Š½ŠøŃŽ (цвета высокого контраста)", + "3": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒŃŠŗŠøŠµ (настраиваемые цвета)", + "4": "ŠŸŠ¾Š»Š½Š°Ń ŠøŠ½Š²ŠµŃ€ŃŠøŃ (ŠøŠ½Š²ŠµŃ€Ń‚ŠøŃ€Š¾Š²Š°Ń‚ŃŒ все цвета)", + "5": "ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€Ń‹ высокого контраста", + "6": "белый текст на чёрном фоне", + "7": "чёрный текст на белом фоне", + "8": "жёлтый текст на чёрном фоне", + "9": "зелёный текст на чёрном фоне", + "10": "Š’Ń‹Š±Ń€Š°Ń‚ŃŒ цвет текста", + "11": "Š’Ń‹Š±Ń€Š°Ń‚ŃŒ цвет фона" + }, + "submit": "Š—Š°Š¼ŠµŠ½ŠøŃ‚ŃŒ" + }, + "replaceColorPdf": { + "tags": "Замена цвета,операции со страницами,Š”ŠµŃ€Š²ŠµŃ€Š½Š°Ń Ń‡Š°ŃŃ‚ŃŒ" + }, + "login": { + "title": "ВхоГ", + "header": "ВхоГ", + "signin": "Войти", + "rememberme": "Š—Š°ŠæŠ¾Š¼Š½ŠøŃ‚ŃŒ Š¼ŠµŠ½Ń", + "invalid": "ŠŠµŠ²ŠµŃ€Š½Š¾Šµ ŠøŠ¼Ń ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń или ŠæŠ°Ń€Š¾Š»ŃŒ.", + "locked": "Š’Š°ŃˆŠ° ŃƒŃ‡ŠµŃ‚Š½Š°Ń запись заблокирована.", + "signinTitle": "ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, войГите", + "ssoSignIn": "ВхоГ через еГиный вхоГ", + "oAuth2AutoCreateDisabled": "Автоматическое созГание ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŠµŠ¹ OAuth2 Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾", + "oAuth2AdminBlockedUser": "Š ŠµŠ³ŠøŃŃ‚Ń€Š°Ń†ŠøŃ или вхоГ незарегистрированных ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŠµŠ¹ в Š½Š°ŃŃ‚Š¾ŃŃ‰ŠµŠµ Š²Ń€ŠµŠ¼Ń заблокированы. ŠžŠ±Ń€Š°Ń‚ŠøŃ‚ŠµŃŃŒ Šŗ Š°Š“Š¼ŠøŠ½ŠøŃŃ‚Ń€Š°Ń‚Š¾Ń€Ńƒ.", + "oauth2RequestNotFound": "Запрос авторизации не найГен", + "oauth2InvalidUserInfoResponse": "ŠŠµŠ“ŠµŠ¹ŃŃ‚Š²ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Š¹ ответ с информацией о ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Šµ", + "oauth2invalidRequest": "ŠŠµŠ“ŠµŠ¹ŃŃ‚Š²ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Š¹ запрос", + "oauth2AccessDenied": "Š”Š¾ŃŃ‚ŃƒŠæ запрещен", + "oauth2InvalidTokenResponse": "ŠŠµŠ“ŠµŠ¹ŃŃ‚Š²ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Š¹ ответ токена", + "oauth2InvalidIdToken": "ŠŠµŠ“ŠµŠ¹ŃŃ‚Š²ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Š¹ иГентификационный токен", + "relyingPartyRegistrationNotFound": "Š ŠµŠ³ŠøŃŃ‚Ń€Š°Ń†ŠøŃ Š“Š¾Š²ŠµŃ€ŃŃŽŃ‰ŠµŠ¹ стороны не найГена", + "userIsDisabled": "ŠŸŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŃŒ Геактивирован, вхоГ с ŃŃ‚ŠøŠ¼ именем ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»Ń в Š½Š°ŃŃ‚Š¾ŃŃ‰ŠµŠµ Š²Ń€ŠµŠ¼Ń заблокирован. ŠžŠ±Ń€Š°Ń‚ŠøŃ‚ŠµŃŃŒ Šŗ Š°Š“Š¼ŠøŠ½ŠøŃŃ‚Ń€Š°Ń‚Š¾Ń€Ńƒ.", + "alreadyLoggedIn": "Š’Ń‹ уже вошли в", + "alreadyLoggedIn2": "ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²(а). ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, выйГите ŠøŠ· ŃŃ‚ŠøŃ… ŃƒŃŃ‚Ń€Š¾Š¹ŃŃ‚Š² Šø ŠæŠ¾ŠæŃ€Š¾Š±ŃƒŠ¹Ń‚Šµ снова.", + "toManySessions": "Š£ вас слишком много активных сессий", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF в оГну ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ", + "header": "PDF в оГну ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ в оГну ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ" + }, + "pageExtracter": { + "title": "Š˜Š·Š²Š»ŠµŃ‡ŃŒ страницы", + "header": "Š˜Š·Š²Š»ŠµŃ‡ŃŒ страницы", + "submit": "Š˜Š·Š²Š»ŠµŃ‡ŃŒ", + "placeholder": "(например, 1,2,8 или 4,7,12-16 или 2n-1)" + }, + "sanitizePDF": { + "title": "ŠžŃ‡ŠøŃŃ‚ŠøŃ‚ŃŒ PDF", + "header": "ŠžŃ‡ŠøŃŃ‚ŠøŃ‚ŃŒ PDF-файл", + "selectText": { + "1": "Š£Š“Š°Š»ŠøŃ‚ŃŒ JavaScript-Š“ŠµŠ¹ŃŃ‚Š²ŠøŃ", + "2": "Š£Š“Š°Š»ŠøŃ‚ŃŒ встроенные файлы", + "3": "Remove XMP metadata", + "4": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ссылки", + "5": "Š£Š“Š°Š»ŠøŃ‚ŃŒ ŃˆŃ€ŠøŃ„Ń‚Ń‹", + "6": "Remove Document Info Metadata" + }, + "submit": "ŠžŃ‡ŠøŃŃ‚ŠøŃ‚ŃŒ PDF" + }, + "adjustContrast": { + "title": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ° контраста", + "header": "ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ° контраста", + "contrast": "ŠšŠ¾Š½Ń‚Ń€Š°ŃŃ‚:", + "brightness": "ŠÆŃ€ŠŗŠ¾ŃŃ‚ŃŒ:", + "saturation": "ŠŠ°ŃŃ‹Ń‰ŠµŠ½Š½Š¾ŃŃ‚ŃŒ:", + "download": "Š”ŠŗŠ°Ń‡Š°Ń‚ŃŒ" + }, + "compress": { + "title": "Š”Š¶Š°Ń‚ŃŒ", + "header": "Š”Š¶Š°Ń‚ŃŒ PDF", + "credit": "Этот сервис ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ qpdf Š“Š»Ń ŃŠ¶Š°Ń‚ŠøŃ/оптимизации PDF.", + "grayscale": { + "label": "ŠŸŃ€ŠøŠ¼ŠµŠ½ŠøŃ‚ŃŒ шкалу серого Š“Š»Ń ŃŠ¶Š°Ń‚ŠøŃ" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Š£Ń€Š¾Š²ŠµŠ½ŃŒ оптимизации:", + "4": "Автоматический режим - автоматически настраивает качество Š“Š»Ń ŠæŠ¾Š»ŃƒŃ‡ŠµŠ½ŠøŃ точного размера PDF", + "5": "ŠžŠ¶ŠøŠ“Š°ŠµŠ¼Ń‹Š¹ размер PDF (например, 25MB, 10.8MB, 25KB)" + }, + "submit": "Š”Š¶Š°Ń‚ŃŒ" + }, + "decrypt": { + "passwordPrompt": "Этот файл защищен паролем. ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, ввеГите ŠæŠ°Ń€Š¾Š»ŃŒ:", + "cancelled": "ŠžŠæŠµŃ€Š°Ń†ŠøŃ отменена Š“Š»Ń PDF: {0}", + "noPassword": "ŠŠµ преГоставлен ŠæŠ°Ń€Š¾Š»ŃŒ Š“Š»Ń Š·Š°ŃˆŠøŃ„Ń€Š¾Š²Š°Š½Š½Š¾Š³Š¾ PDF: {0}", + "invalidPassword": "ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, ŠæŠ¾ŠæŃ€Š¾Š±ŃƒŠ¹Ń‚Šµ снова с ŠæŃ€Š°Š²ŠøŠ»ŃŒŠ½Ń‹Š¼ паролем.", + "invalidPasswordHeader": "ŠŠµŠ²ŠµŃ€Š½Ń‹Š¹ ŠæŠ°Ń€Š¾Š»ŃŒ или непоГГерживаемое ŃˆŠøŃ„Ń€Š¾Š²Š°Š½ŠøŠµ Š“Š»Ń PDF: {0}", + "unexpectedError": "ŠŸŃ€Š¾ŠøŠ·Š¾ŃˆŠ»Š° ошибка при обработке файла. ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, ŠæŠ¾ŠæŃ€Š¾Š±ŃƒŠ¹Ń‚Šµ снова.", + "serverError": "ŠžŃˆŠøŠ±ŠŗŠ° сервера при Ń€Š°ŃŃˆŠøŃ„Ń€Š¾Š²ŠŗŠµ: {0}", + "success": "Файл успешно Ń€Š°ŃŃˆŠøŃ„Ń€Š¾Š²Š°Š½." + }, + "multiTool-advert": { + "message": "Эта Ń„ŃƒŠ½ŠŗŃ†ŠøŃ также Š“Š¾ŃŃ‚ŃƒŠæŠ½Š° на нашей странице Š¼ŃƒŠ»ŃŒŃ‚ŠøŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚Š°. ŠŸŠ¾ŠæŃ€Š¾Š±ŃƒŠ¹Ń‚Šµ её Š“Š»Ń ŃƒŠ»ŃƒŃ‡ŃˆŠµŠ½Š½Š¾Š³Š¾ постраничного интерфейса Šø Š“Š¾ŠæŠ¾Š»Š½ŠøŃ‚ŠµŠ»ŃŒŠ½Ń‹Ń… возможностей!" + }, + "pageRemover": { + "title": "УГаление страниц", + "header": "УГаление страниц PDF", + "pagesToDelete": "Дтраницы Š“Š»Ń ŃƒŠ“Š°Š»ŠµŠ½ŠøŃ (ввеГите список номеров страниц через Š·Š°ŠæŃŃ‚ŃƒŃŽ):", + "submit": "Š£Š“Š°Š»ŠøŃ‚ŃŒ страницы", + "placeholder": "(например, 1,2,6 или 1-10,15-30)" + }, + "imageToPDF": { + "title": "Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ в PDF", + "header": "Š˜Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŠµ в PDF", + "submit": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ", + "selectLabel": "ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€Ń‹ Š²ŠæŠøŃŃ‹Š²Š°Š½ŠøŃ ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "fillPage": "Š—Š°ŠæŠ¾Š»Š½ŠøŃ‚ŃŒ ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ", + "fitDocumentToImage": "ŠŸŠ¾Š“Š¾Š³Š½Š°Ń‚ŃŒ ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ поГ изображение", + "maintainAspectRatio": "Š”Š¾Ń…Ń€Š°Š½ŃŃ‚ŃŒ пропорции", + "selectText": { + "2": "Автоматически ŠæŠ¾Š²Š¾Ń€Š°Ń‡ŠøŠ²Š°Ń‚ŃŒ PDF", + "3": "Логика обработки множества файлов (активна Ń‚Š¾Š»ŃŒŠŗŠ¾ при работе с несколькими ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃŠ¼Šø)", + "4": "ŠžŠ±ŃŠŠµŠ“ŠøŠ½ŠøŃ‚ŃŒ в оГин PDF", + "5": "ŠŸŃ€ŠµŠ¾Š±Ń€Š°Š·Š¾Š²Š°Ń‚ŃŒ в Š¾Ń‚Š“ŠµŠ»ŃŒŠ½Ń‹Šµ PDF" + } + }, + "PDFToCSV": { + "title": "PDF в CSV", + "header": "PDF в CSV", + "prompt": "Выберите ŃŃ‚Ń€Š°Š½ŠøŃ†Ńƒ Š“Š»Ń ŠøŠ·Š²Š»ŠµŃ‡ŠµŠ½ŠøŃ таблицы", + "submit": "Š˜Š·Š²Š»ŠµŃ‡ŃŒ" + }, + "split-by-size-or-count": { + "title": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ PDF по Ń€Š°Š·Š¼ŠµŃ€Ńƒ или ŠŗŠ¾Š»ŠøŃ‡ŠµŃŃ‚Š²Ńƒ", + "header": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ PDF по Ń€Š°Š·Š¼ŠµŃ€Ńƒ или ŠŗŠ¾Š»ŠøŃ‡ŠµŃŃ‚Š²Ńƒ", + "type": { + "label": "Выберите тип Ń€Š°Š·Š“ŠµŠ»ŠµŠ½ŠøŃ", + "size": "По Ń€Š°Š·Š¼ŠµŃ€Ńƒ", + "pageCount": "По ŠŗŠ¾Š»ŠøŃ‡ŠµŃŃ‚Š²Ńƒ страниц", + "docCount": "По ŠŗŠ¾Š»ŠøŃ‡ŠµŃŃ‚Š²Ńƒ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š¾Š²" + }, + "value": { + "label": "ВвеГите значение", + "placeholder": "ВвеГите размер (например, 2MB или 3KB) или количество (например, 5)" + }, + "submit": "ŠžŃ‚ŠæŃ€Š°Š²ŠøŃ‚ŃŒ" + }, + "printFile": { + "title": "ŠŸŠµŃ‡Š°Ń‚ŃŒ файла", + "header": "ŠŸŠµŃ‡Š°Ń‚ŃŒ файла на принтер", + "selectText": { + "1": "Выберите файл Š“Š»Ń печати", + "2": "ВвеГите ŠøŠ¼Ń принтера" + }, + "submit": "ŠŸŠµŃ‡Š°Ń‚ŃŒ" + }, + "licenses": { + "nav": "Лицензии", + "title": "Лицензии сторонних компонентов", + "header": "Лицензии сторонних компонентов", + "module": "МоГуль", + "version": "Š’ŠµŃ€ŃŠøŃ", + "license": "Š›ŠøŃ†ŠµŠ½Š·ŠøŃ" + }, + "survey": { + "nav": "ŠžŠæŃ€Š¾Ń", + "title": "ŠžŠæŃ€Š¾Ń Stirling-PDF", + "description": "Stirling-PDF не ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ отслеживание, ŠæŠ¾ŃŃ‚Š¾Š¼Ńƒ мы хотим ŃƒŃŠ»Ń‹ŃˆŠ°Ń‚ŃŒ мнение ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŠµŠ»ŠµŠ¹ Š“Š»Ń ŃƒŠ»ŃƒŃ‡ŃˆŠµŠ½ŠøŃ Stirling-PDF!", + "changes": "Stirling-PDF ŠøŠ·Š¼ŠµŠ½ŠøŠ»ŃŃ с момента послеГнего опроса! Чтобы ŃƒŠ·Š½Š°Ń‚ŃŒ больше, ŠæŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, прочитайте наш пост в блоге зГесь:", + "changes2": "Š” ŃŃ‚ŠøŠ¼Šø ŠøŠ·Š¼ŠµŠ½ŠµŠ½ŠøŃŠ¼Šø мы ŠæŠ¾Š»ŃƒŃ‡Š°ŠµŠ¼ ŠæŠ»Š°Ń‚Š½ŃƒŃŽ бизнес-ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠŗŃƒ Šø финансирование", + "please": "ŠŸŠ¾Š¶Š°Š»ŃƒŠ¹ŃŃ‚Š°, примите ŃƒŃ‡Š°ŃŃ‚ŠøŠµ в нашем опросе!", + "disabled": "(Š’ŃŠæŠ»Ń‹Š²Š°ŃŽŃ‰ŠµŠµ окно опроса Š±ŃƒŠ“ет Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾ в ŃŠ»ŠµŠ“ŃƒŃŽŃ‰ŠøŃ… Š¾Š±Š½Š¾Š²Š»ŠµŠ½ŠøŃŃ…, но Š±ŃƒŠ“ет Š“Š¾ŃŃ‚ŃƒŠæŠ½Š¾ в нижней части страницы)", + "button": "ŠŸŃ€Š¾Š¹Ń‚Šø опрос", + "dontShowAgain": "Š‘Š¾Š»ŃŒŃˆŠµ не ŠæŠ¾ŠŗŠ°Š·Ń‹Š²Š°Ń‚ŃŒ", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Š£Š“Š°Š»ŠøŃ‚ŃŒ изображение", + "header": "Š£Š“Š°Š»ŠøŃ‚ŃŒ изображение", + "removeImage": "Š£Š“Š°Š»ŠøŃ‚ŃŒ изображение", + "submit": "Š£Š“Š°Š»ŠøŃ‚ŃŒ изображение" + }, + "splitByChapters": { + "title": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ PDF по главам", + "header": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ PDF по главам", + "bookmarkLevel": "Š£Ń€Š¾Š²ŠµŠ½ŃŒ заклаГок", + "includeMetadata": "Š’ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ метаГанные", + "allowDuplicates": "Š Š°Š·Ń€ŠµŃˆŠøŃ‚ŃŒ Š“ŃƒŠ±Š»ŠøŠŗŠ°Ń‚Ń‹", + "desc": { + "1": "Этот ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚ Ń€Š°Š·Š“ŠµŠ»ŃŠµŃ‚ PDF-файл на несколько PDF на основе его ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Ń‹ глав.", + "2": "Š£Ń€Š¾Š²ŠµŠ½ŃŒ заклаГок: выберите ŃƒŃ€Š¾Š²ŠµŠ½ŃŒ заклаГок Š“Š»Ń Ń€Š°Š·Š“ŠµŠ»ŠµŠ½ŠøŃ (0 Š“Š»Ń верхнего ŃƒŃ€Š¾Š²Š½Ń, 1 Š“Š»Ń второго ŃƒŃ€Š¾Š²Š½Ń Šø т.Š“.).", + "3": "Š’ŠŗŠ»ŃŽŃ‡ŠøŃ‚ŃŒ метаГанные: если отмечено, метаГанные исхоГного PDF Š±ŃƒŠ“ŃƒŃ‚ Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Ń‹ в кажГый разГеленный PDF.", + "4": "Š Š°Š·Ń€ŠµŃˆŠøŃ‚ŃŒ Š“ŃƒŠ±Š»ŠøŠŗŠ°Ń‚Ń‹: если отмечено, ŠæŠ¾Š·Š²Š¾Š»ŃŠµŃ‚ ŃŠ¾Š·Š“Š°Š²Š°Ń‚ŃŒ Š¾Ń‚Š“ŠµŠ»ŃŒŠ½Ń‹Šµ PDF ŠøŠ· Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠøŃ… заклаГок на оГной странице." + }, + "submit": "Š Š°Š·Š“ŠµŠ»ŠøŃ‚ŃŒ PDF" + }, + "fileChooser": { + "click": "ŠŠ°Š¶Š¼ŠøŃ‚Šµ", + "or": "или", + "dragAndDrop": "ŠŸŠµŃ€ŠµŃ‚Š°Ń‰ŠøŃ‚Šµ", + "dragAndDropPDF": "ŠŸŠµŃ€ŠµŃ‚Š°Ń‰ŠøŃ‚Šµ PDF-файл", + "dragAndDropImage": "ŠŸŠµŃ€ŠµŃ‚Š°Ń‰ŠøŃ‚Šµ файл ŠøŠ·Š¾Š±Ń€Š°Š¶ŠµŠ½ŠøŃ", + "hoveredDragAndDrop": "ŠŸŠµŃ€ŠµŃ‚Š°Ń‰ŠøŃ‚Šµ файл(ы) ŃŃŽŠ“Š°", + "extractPDF": "Š˜Š·Š²Š»ŠµŃ‡ŠµŠ½ŠøŠµ..." + }, + "releases": { + "footer": "Релизы", + "title": "ŠŸŃ€ŠøŠ¼ŠµŃ‡Š°Š½ŠøŃ Šŗ Ń€ŠµŠ»ŠøŠ·Ńƒ", + "header": "ŠŸŃ€ŠøŠ¼ŠµŃ‡Š°Š½ŠøŃ Šŗ Ń€ŠµŠ»ŠøŠ·Ńƒ", + "current": { + "version": "Š¢ŠµŠŗŃƒŃ‰ŠøŠ¹ релиз" + }, + "note": "ŠŸŃ€ŠøŠ¼ŠµŃ‡Š°Š½ŠøŃ Šŗ Ń€ŠµŠ»ŠøŠ·Ńƒ Š“Š¾ŃŃ‚ŃƒŠæŠ½Ń‹ Ń‚Š¾Š»ŃŒŠŗŠ¾ на английском ŃŠ·Ń‹ŠŗŠµ" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/sk-SK/translation.json b/frontend/public/locales/sk-SK/translation.json new file mode 100644 index 000000000..bbdf5f676 --- /dev/null +++ b/frontend/public/locales/sk-SK/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Font Size", + "fontName": "Font Name", + "title": "PridaÅ„ čƭsla strĆ”nok", + "header": "PridaÅ„ čƭsla strĆ”nok", + "selectText": { + "1": "VybraÅ„ PDF sĆŗbor:", + "2": "VeľkosÅ„ okraja", + "3": "PozĆ­cia", + "4": "PočiatočnĆ© čƭslo", + "5": "StrĆ”nky na čƭslovanie", + "6": "Vlastný text" + }, + "customTextDesc": "Vlastný text", + "numberPagesDesc": "KtorĆ© strĆ”nky čƭslovaÅ„, predvolenĆ© 'vÅ”etky', tiež akceptuje 1-5 alebo 2,5,9 atď.", + "customNumberDesc": "PredvolenĆ© {n}, tiež akceptuje 'Strana {n} z {total}', 'Text-{n}', '{filename}-{n}", + "submit": "PridaÅ„ čƭsla strĆ”nok" + }, + "pdfPrompt": "Vyberte PDF sĆŗbor(y)", + "multiPdfPrompt": "Vyberte PDF sĆŗbory (2+)", + "multiPdfDropPrompt": "Vyberte (alebo pretiahnite) vÅ”etky požadovanĆ© PDF sĆŗbory", + "imgPrompt": "Vyberte obrĆ”zok(y)", + "genericSubmit": "OdoslaÅ„", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Varovanie: Tento proces mÓže trvaÅ„ až minĆŗtu v zĆ”vislosti od veľkosti sĆŗboru", + "pageOrderPrompt": "VlastnĆ© poradie strĆ”nok (Zadajte zoznam čƭsel strĆ”nok oddelených čiarkou alebo funkcie ako 2n+1):", + "pageSelectionPrompt": "Vlastný výber strĆ”nok (Zadajte zoznam čƭsel strĆ”nok oddelených čiarkou 1,5,6 alebo funkcie ako 2n+1):", + "goToPage": "Choď", + "true": "Ɓno", + "false": "Nie", + "unknown": "NeznĆ”me", + "save": "UložiÅ„", + "saveToBrowser": "UložiÅ„ do prehliadača", + "close": "ZatvoriÅ„", + "filesSelected": "vybranĆ© sĆŗbory", + "noFavourites": "Žiadne obľúbenĆ© položky", + "downloadComplete": "Stiahnutie dokončenĆ©", + "bored": "NudĆ­te sa pri čakanĆ­?", + "alphabet": "Abeceda", + "downloadPdf": "StiahnuÅ„ PDF", + "text": "Text", + "font": "Font", + "selectFillter": "-- Vyberte --", + "pageNum": "Číslo strĆ”nky", + "sizes": { + "small": "MalĆ©", + "medium": "StrednĆ©", + "large": "VeľkĆ©", + "x-large": "Veľmi veľkĆ©" + }, + "error": { + "pdfPassword": "PDF dokument je chrĆ”nený heslom a buď heslo nebolo zadanĆ©, alebo bolo nesprĆ”vne", + "_value": "Chyba", + "sorry": "Ospravedlňujeme sa za problĆ©m!", + "needHelp": "Potrebujete pomoc / NaÅ”li ste problĆ©m?", + "contactTip": "Ak mĆ”te stĆ”le problĆ©my, nevĆ”hajte nĆ”s kontaktovaÅ„ pre pomoc. MÓžete podaÅ„ tiket na naÅ”ej strĆ”nke GitHub alebo nĆ”s kontaktovaÅ„ cez Discord:", + "404": { + "head": "404 - StrĆ”nka nenĆ”jdenĆ” | Ups, narazili sme na chybu v kóde!", + "1": "NemÓžeme nĆ”jsÅ„ strĆ”nku, ktorĆŗ hľadĆ”te.", + "2": "Niečo sa pokazilo" + }, + "github": "Podajte tiket na GitHub", + "showStack": "ZobraziÅ„ sledovanie zĆ”sobnĆ­ka", + "copyStack": "KopĆ­rovaÅ„ sledovanie zĆ”sobnĆ­ka", + "githubSubmit": "GitHub - Podajte tiket", + "discordSubmit": "Discord - Podajte prĆ­spevok na podporu" + }, + "delete": "VymazaÅ„", + "username": "PoužívateľskĆ© meno", + "password": "Heslo", + "welcome": "Vitajte", + "property": "VlastnosÅ„", + "black": "Čierna", + "white": "Biela", + "red": "ČervenĆ”", + "green": "ZelenĆ”", + "blue": "ModrĆ”", + "custom": "VlastnĆ©...", + "WorkInProgess": "PrĆ”ca prebieha, nemusĆ­ fungovaÅ„ alebo mÓže byÅ„ chybovĆ”, prosĆ­m nahlĆ”ste akĆ©koľvek problĆ©my!", + "poweredBy": "PoskytovanĆ©", + "yes": "Ɓno", + "no": "Nie", + "changedCredsMessage": "Údaje zmenenĆ©!", + "notAuthenticatedMessage": "Používateľ nie je overený.", + "userNotFoundMessage": "Používateľ nebol nĆ”jdený.", + "incorrectPasswordMessage": "AktuĆ”lne heslo je nesprĆ”vne.", + "usernameExistsMessage": "NovĆ© používateľskĆ© meno už existuje.", + "invalidUsernameMessage": "NeplatnĆ© používateľskĆ© meno, používateľskĆ© meno musĆ­ obsahovaÅ„ len abecednĆ© znaky a čƭsla.", + "invalidPasswordMessage": "The password must not be empty and must not have spaces at the beginning or end.", + "confirmPasswordErrorMessage": "New Password and Confirm New Password must match.", + "deleteCurrentUserMessage": "Nie je možnĆ© zmazaÅ„ aktuĆ”lne prihlĆ”senĆ©ho používateľa.", + "deleteUsernameExistsMessage": "PoužívateľskĆ© meno neexistuje a nemÓže byÅ„ zmazanĆ©.", + "downgradeCurrentUserMessage": "Nie je možnĆ© znížiÅ„ rolu aktuĆ”lneho používateľa", + "disabledCurrentUserMessage": "The current user cannot be disabled", + "downgradeCurrentUserLongMessage": "Nie je možnĆ© znížiÅ„ rolu aktuĆ”lneho používateľa. Preto, aktuĆ”lny používateľ nebude zobrazený.", + "userAlreadyExistsOAuthMessage": "The user already exists as an OAuth2 user.", + "userAlreadyExistsWebMessage": "The user already exists as an web user.", + "oops": "Ups!", + "help": "Pomoc", + "goHomepage": "PrejsÅ„ na domovskĆŗ strĆ”nku", + "joinDiscord": "Pripojte sa na nÔŔ Discord server", + "seeDockerHub": "PozrieÅ„ Docker Hub", + "visitGithub": "NavÅ”tĆ­viÅ„ GitHub repozitĆ”r", + "donate": "DarovaÅ„", + "color": "Farba", + "sponsor": "SponzorovaÅ„", + "info": "Info", + "pro": "Pro", + "page": "Page", + "pages": "Pages", + "loading": "Loading...", + "addToDoc": "Add to Document", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Privacy Policy", + "terms": "Terms and Conditions", + "accessibility": "Accessibility", + "cookie": "Cookie Policy", + "impressum": "Impressum", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Menu pipeline (Beta)", + "uploadButton": "NahraÅ„ vlastný", + "configureButton": "KonfigurovaÅ„", + "defaultOption": "VlastnĆ©", + "submitButton": "OdoslaÅ„", + "help": "Pomoc s pipeline", + "scanHelp": "Pomoc so skenovanĆ­m priečinka", + "deletePrompt": "Are you sure you want to delete pipeline", + "tags": "automatizovaÅ„,sekvencia,skriptovanĆ©,dĆ”vkovĆ© spracovanie", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "KonfigurĆ”cia pipeline", + "pipelineNameLabel": "NĆ”zov pipeline", + "saveSettings": "UložiÅ„ nastavenia operĆ”cie", + "pipelineNamePrompt": "Zadajte nĆ”zov pipeline tu", + "selectOperation": "VybraÅ„ operĆ”ciu", + "addOperationButton": "PridaÅ„ operĆ”ciu", + "pipelineHeader": "Pipeline:", + "saveButton": "StiahnuÅ„", + "validateButton": "OveriÅ„" + }, + "enterpriseEdition": { + "button": "Upgrade to Pro", + "warning": "This feature is only available to Pro users.", + "yamlAdvert": "Stirling PDF Pro supports YAML configuration files and other SSO features.", + "ssoAdvert": "Looking for more user management features? Check out Stirling PDF Pro" + }, + "analytics": { + "title": "Do you want make Stirling PDF better?", + "paragraph1": "Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.", + "paragraph2": "Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.", + "enable": "Enable analytics", + "disable": "Disable analytics", + "settings": "You can change the settings for analytics in the config/settings.yml file" + }, + "navbar": { + "favorite": "Favorites", + "recent": "New and recently updated", + "darkmode": "Tmavý režim", + "language": "Languages", + "settings": "Nastavenia", + "allTools": "Tools", + "multiTool": "Multi Tools", + "search": "Search", + "sections": { + "organize": "Organize", + "convertTo": "Convert to PDF", + "convertFrom": "Convert from PDF", + "security": "Sign & Security", + "advance": "Advanced", + "edit": "View & Edit", + "popular": "Popular" + } + }, + "settings": { + "title": "Nastavenia", + "update": "DostupnĆ” aktualizĆ”cia", + "updateAvailable": "{0} je aktuĆ”lne nainÅ”talovanĆ” verzia. NovĆ” verzia ({1}) je dostupnĆ”.", + "appVersion": "Verzia aplikĆ”cie:", + "downloadOption": { + "title": "Vyberte možnosÅ„ sÅ„ahovania (Pre jednotlivĆ© neskomprimovanĆ© sĆŗbory):", + "1": "OtvoriÅ„ v rovnakom okne", + "2": "OtvoriÅ„ v novom okne", + "3": "StiahnuÅ„ sĆŗbor" + }, + "zipThreshold": "KomprimovaÅ„ sĆŗbory, keď počet stiahnutých sĆŗborov prekročƭ", + "signOut": "OdhlĆ”siÅ„ sa", + "accountSettings": "Nastavenia ĆŗÄtu", + "bored": { + "help": "Umožňuje veľkonočnĆŗ hru" + }, + "cacheInputs": { + "name": "UložiÅ„ vstupy formulĆ”ra", + "help": "Umožňuje uložiÅ„ predtým použitĆ© vstupy na budĆŗce použitie" + } + }, + "changeCreds": { + "title": "ZmeniÅ„ Ćŗdaje", + "header": "Aktualizujte Ćŗdaje svojho ĆŗÄtu", + "changePassword": "Používate predvolenĆ© prihlasovacie Ćŗdaje. ProsĆ­m, zadajte novĆ© heslo", + "newUsername": "NovĆ© používateľskĆ© meno", + "oldPassword": "AktuĆ”lne heslo", + "newPassword": "NovĆ© heslo", + "confirmNewPassword": "Potvrďte novĆ© heslo", + "submit": "OdoslaÅ„ zmeny" + }, + "account": { + "title": "Nastavenia ĆŗÄtu", + "accountSettings": "Nastavenia ĆŗÄtu", + "adminSettings": "Admin nastavenia - ZobraziÅ„ a pridaÅ„ používateľov", + "userControlSettings": "Nastavenia kontroly používateľov", + "changeUsername": "ZmeniÅ„ používateľskĆ© meno", + "newUsername": "NovĆ© používateľskĆ© meno", + "password": "Potvrdzovacie heslo", + "oldPassword": "StarĆ© heslo", + "newPassword": "NovĆ© heslo", + "changePassword": "ZmeniÅ„ heslo", + "confirmNewPassword": "Potvrďte novĆ© heslo", + "signOut": "OdhlĆ”siÅ„ sa", + "yourApiKey": "VÔŔ API kÄ¾ĆŗÄ", + "syncTitle": "SynchronizovaÅ„ nastavenia prehliadača s ĆŗÄtom", + "settingsCompare": "Porovnanie nastavenĆ­:", + "property": "VlastnosÅ„", + "webBrowserSettings": "Nastavenie webovĆ©ho prehliadača", + "syncToBrowser": "SynchronizovaÅ„ ĆŗÄet -> Prehliadač", + "syncToAccount": "SynchronizovaÅ„ ĆŗÄet <- Prehliadač" + }, + "adminUserSettings": { + "title": "Nastavenia kontroly používateľov", + "header": "Admin nastavenia kontroly používateľov", + "admin": "Admin", + "user": "Používateľ", + "addUser": "PridaÅ„ novĆ©ho používateľa", + "deleteUser": "Delete User", + "confirmDeleteUser": "Should the user be deleted?", + "confirmChangeUserStatus": "Should the user be disabled/enabled?", + "usernameInfo": "PoužívateľskĆ© meno musĆ­ obsahovaÅ„ iba pĆ­smenĆ” a čƭsla, žiadne medzery alebo Å”peciĆ”lne znaky.", + "roles": "Role", + "role": "Rola", + "actions": "Akcie", + "apiUser": "Obmedzený API používateľ", + "extraApiUser": "ĎalŔí obmedzený API používateľ", + "webOnlyUser": "Používateľ iba pre web", + "demoUser": "Demo používateľ (Bez vlastných nastavenĆ­)", + "internalApiUser": "Interný API používateľ", + "forceChange": "DonĆŗtiÅ„ používateľa zmeniÅ„ heslo pri prihlĆ”senĆ­", + "submit": "UložiÅ„ používateľa", + "changeUserRole": "ZmeniÅ„ rolu používateľa", + "authenticated": "Authenticated", + "editOwnProfil": "Edit own profile", + "enabledUser": "enabled user", + "disabledUser": "disabled user", + "activeUsers": "Active Users:", + "disabledUsers": "Disabled Users:", + "totalUsers": "Total Users:", + "lastRequest": "Last Request", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Database Import/Export", + "header": "Database Import/Export", + "fileName": "File Name", + "creationDate": "Creation Date", + "fileSize": "File Size", + "deleteBackupFile": "Delete Backup File", + "importBackupFile": "Import Backup File", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Download Backup File", + "info_1": "When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.", + "info_2": "The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.", + "submit": "Import Backup", + "importIntoDatabaseSuccessed": "Import into database successed", + "backupCreated": "Database backup successful", + "fileNotFound": "File not Found", + "fileNullOrEmpty": "File must not be null or empty", + "failedImportFile": "Failed Import File", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "Your session has expired. Please refresh the page and try again.", + "refreshPage": "Refresh Page" + }, + "home": { + "desc": "VaÅ”a lokĆ”lne hostovanĆ” jednorazovĆ” zĆ”stavka pre vÅ”etky potreby PDF.", + "searchBar": "VyhľadaÅ„ funkcie...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "ZobraziÅ„, anotovaÅ„, pridaÅ„ text alebo obrĆ”zky" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "PDF Multi Tool", + "desc": "ZlĆŗÄiÅ„, otočiÅ„, preusporiadaÅ„ a odstrĆ”niÅ„ strĆ”nky" + }, + "merge": { + "title": "ZlĆŗÄiÅ„", + "desc": "Jednoducho zlĆŗÄte viacero PDF sĆŗborov do jednĆ©ho." + }, + "split": { + "title": "RozdeliÅ„", + "desc": "Rozdeľte PDF sĆŗbory na viacero dokumentov" + }, + "rotate": { + "title": "OtočiÅ„", + "desc": "Jednoducho otĆ”Äajte svoje PDF sĆŗbory." + }, + "imageToPdf": { + "title": "ObrĆ”zok na PDF", + "desc": "Konvertujte obrĆ”zok (PNG, JPEG, GIF) na PDF." + }, + "pdfToImage": { + "title": "PDF na obrĆ”zok", + "desc": "Konvertujte PDF na obrĆ”zok. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "OrganizovaÅ„", + "desc": "OdstrÔňte/preusporiadajte strĆ”nky v ľubovoľnom poradĆ­" + }, + "addImage": { + "title": "PridaÅ„ obrĆ”zok", + "desc": "PridaÅ„ obrĆ”zok na zadanĆ© miesto v PDF" + }, + "watermark": { + "title": "PridaÅ„ vodotlač", + "desc": "PridaÅ„ vlastnĆŗ vodotlač do vÔŔho PDF dokumentu." + }, + "permissions": { + "title": "ZmeniÅ„ povolenia", + "desc": "Zmena povolenĆ­ vÔŔho PDF dokumentu" + }, + "removePages": { + "title": "OdstrĆ”niÅ„", + "desc": "OdstrĆ”niÅ„ nechcenĆ© strĆ”nky z vÔŔho PDF dokumentu." + }, + "addPassword": { + "title": "PridaÅ„ heslo", + "desc": "Å ifrovaÅ„ vÔŔ PDF dokument heslom." + }, + "removePassword": { + "title": "OdstrĆ”niÅ„ heslo", + "desc": "OdstrĆ”niÅ„ ochranu heslom z vÔŔho PDF dokumentu." + }, + "compressPdfs": { + "title": "KomprimovaÅ„", + "desc": "Komprimujte PDF na zmenÅ”enie jeho veľkosti." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "ZmeniÅ„ metadĆ”ta", + "desc": "Zmena/OdstrĆ”nenie/Pridanie metadĆ”t z PDF dokumentu" + }, + "fileToPDF": { + "title": "KonvertovaÅ„ sĆŗbor na PDF", + "desc": "Konvertujte takmer akýkoľvek sĆŗbor na PDF (DOCX, PNG, XLS, PPT, TXT a ďalÅ”ie)" + }, + "ocr": { + "title": "OCR / Čistenie skenov", + "desc": "Čistenie skenov a rozpoznanie textu z obrĆ”zkov v PDF a opƤtovnĆ© pridanie ako text." + }, + "extractImages": { + "title": "ExtrahovaÅ„ obrĆ”zky", + "desc": "Extrahuje vÅ”etky obrĆ”zky z PDF a uloží ich do zipu" + }, + "pdfToPDFA": { + "title": "PDF na PDF/A", + "desc": "Konvertujte PDF na PDF/A pre dlhodobĆ© uchovĆ”vanie" + }, + "PDFToWord": { + "title": "PDF na Word", + "desc": "Konvertujte PDF na formĆ”ty Word (DOC, DOCX a ODT)" + }, + "PDFToPresentation": { + "title": "PDF na PrezentĆ”ciu", + "desc": "Konvertujte PDF na formĆ”ty prezentĆ”cie (PPT, PPTX a ODP)" + }, + "PDFToText": { + "title": "PDF na RTF (Text)", + "desc": "Konvertujte PDF na RTF alebo textový formĆ”t" + }, + "PDFToHTML": { + "title": "PDF na HTML", + "desc": "Konvertujte PDF na HTML formĆ”t" + }, + "PDFToXML": { + "title": "PDF na XML", + "desc": "Konvertujte PDF na XML formĆ”t" + }, + "ScannerImageSplit": { + "title": "Detekcia/Rozdelenie skenovaných fotografiĆ­", + "desc": "RozdelĆ­ viacero fotografiĆ­ v rĆ”mci fotografie/PDF" + }, + "sign": { + "title": "PodpĆ­saÅ„", + "desc": "PridĆ”va podpis do PDF kreslenĆ­m, textom alebo obrĆ”zkom" + }, + "flatten": { + "title": "ZploÅ”tiÅ„", + "desc": "OdstrĆ”niÅ„ vÅ”etky interaktĆ­vne prvky a formulĆ”re z PDF" + }, + "repair": { + "title": "OpraviÅ„", + "desc": "SkĆŗÅ”a opraviÅ„ poÅ”kodenĆ©/rozbitĆ© PDF" + }, + "removeBlanks": { + "title": "OdstrĆ”niÅ„ prĆ”zdne strĆ”nky", + "desc": "Detekuje a odstraňuje prĆ”zdne strĆ”nky z dokumentu" + }, + "removeAnnotations": { + "title": "OdstrĆ”niÅ„ anotĆ”cie", + "desc": "Odstraňuje vÅ”etky komentĆ”re/anotĆ”cie z PDF" + }, + "compare": { + "title": "PorovnaÅ„", + "desc": "PorovnĆ”va a zobrazuje rozdiely medzi 2 PDF dokumentmi" + }, + "certSign": { + "title": "PodpĆ­saÅ„ s certifikĆ”tom", + "desc": "PodpĆ­saÅ„ PDF s certifikĆ”tom/kÄ¾ĆŗÄom (PEM/P12)" + }, + "removeCertSign": { + "title": "Remove Certificate Sign", + "desc": "Remove certificate signature from PDF" + }, + "pageLayout": { + "title": "ViacstranovĆ© usporiadanie", + "desc": "ZlĆŗÄte viacero strĆ”nok PDF dokumentu do jednej strĆ”nky" + }, + "scalePages": { + "title": "PrispĆ“sobiÅ„ veľkosÅ„/Å”kĆ”lovanie strĆ”nok", + "desc": "ZmeniÅ„ veľkosÅ„/Å”kĆ”lovanie strĆ”nky a/alebo jej obsahu." + }, + "pipeline": { + "title": "Pipeline", + "desc": "SpustiÅ„ viacero akciĆ­ na PDF definovanĆ­m pipeline skriptov" + }, + "add-page-numbers": { + "title": "PridaÅ„ čƭsla strĆ”nok", + "desc": "PridaÅ„ čƭsla strĆ”nok po celom dokumente na určenom mieste" + }, + "auto-rename": { + "title": "AutomatickĆ© premenovanie PDF sĆŗboru", + "desc": "Automaticky premenuje PDF sĆŗbor na zĆ”klade zistenĆ©ho zĆ”hlavia" + }, + "adjust-contrast": { + "title": "UpraviÅ„ farby/kontrast", + "desc": "Upravte kontrast, sýtosÅ„ a jas PDF" + }, + "crop": { + "title": "OrezaÅ„ PDF", + "desc": "OrezaÅ„ PDF na zmenÅ”enie jeho veľkosti (zachovĆ”va text!)" + }, + "autoSplitPDF": { + "title": "AutomatickĆ© rozdelenie strĆ”nok", + "desc": "AutomatickĆ© rozdelenie skenovanĆ©ho PDF pomocou fyzickĆ©ho skenovanĆ©ho rozdeľovača strĆ”nok QR kódom" + }, + "sanitizePdf": { + "title": "VyčistiÅ„", + "desc": "OdstrĆ”niÅ„ skripty a ďalÅ”ie prvky z PDF sĆŗborov" + }, + "URLToPDF": { + "title": "URL/WebstrĆ”nka do PDF", + "desc": "Konvertuje akĆŗkoľvek http(s)URL do PDF" + }, + "HTMLToPDF": { + "title": "HTML do PDF", + "desc": "Konvertuje akýkoľvek HTML sĆŗbor alebo zip do PDF" + }, + "MarkdownToPDF": { + "title": "Markdown do PDF", + "desc": "Konvertuje akýkoľvek Markdown sĆŗbor do PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "ZĆ­skaÅ„ vÅ”etky informĆ”cie o PDF", + "desc": "ZĆ­skava vÅ”etky dostupnĆ© informĆ”cie o PDF" + }, + "extractPage": { + "title": "ExtrahovaÅ„ strĆ”nku(y)", + "desc": "Extrahuje vybranĆ© strĆ”nky z PDF" + }, + "PdfToSinglePage": { + "title": "PDF na jednu veľkĆŗ strĆ”nku", + "desc": "ZlĆŗÄi vÅ”etky strĆ”nky PDF do jednej veľkej strĆ”nky" + }, + "showJS": { + "title": "ZobraziÅ„ JavaScript", + "desc": "VyhľadĆ” a zobrazuje akýkoľvek JS vložený do PDF" + }, + "autoRedact": { + "title": "AutomatickĆ© redigovanie", + "desc": "Automaticky rediguje (zatieni) text v PDF na zĆ”klade zadanĆ©ho textu" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF do CSV", + "desc": "Extrahuje tabuľky z PDF a konvertuje ich do CSV" + }, + "autoSizeSplitPDF": { + "title": "AutomatickĆ© rozdelenie podľa veľkosti/počtu", + "desc": "RozdelĆ­ jeden PDF na viacero dokumentov na zĆ”klade veľkosti, počtu strĆ”nok alebo počtu dokumentov" + }, + "overlay-pdfs": { + "title": "Prekrývanie PDF", + "desc": "Prekrýva PDF sĆŗbory na iný PDF" + }, + "split-by-sections": { + "title": "Rozdelenie PDF podľa sekciĆ­", + "desc": "RozdelĆ­ každĆŗ strĆ”nku PDF na menÅ”ie horizontĆ”lne a vertikĆ”lne sekcie" + }, + "AddStampRequest": { + "title": "PridaÅ„ pečiatku do PDF", + "desc": "PridaÅ„ text alebo obrĆ”zkovĆ© pečiatky na určenĆ© miesta" + }, + "removeImagePdf": { + "title": "Remove image", + "desc": "Remove image from PDF to reduce file size" + }, + "splitPdfByChapters": { + "title": "Split PDF by Chapters", + "desc": "Split a PDF into multiple files based on its chapter structure." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "replaceColorPdf": { + "title": "Replace and Invert Color", + "desc": "Replace color for text and background in PDF and invert full color of pdf to reduce file size" + } + }, + "viewPdf": { + "tags": "zobraziÅ„,čƭtaÅ„,anotovaÅ„,text,obrĆ”zok", + "title": "View/Edit PDF", + "header": "ZobraziÅ„ PDF" + }, + "multiTool": { + "tags": "Multi Tool,Multi operĆ”cie,UI,klik drag,front end,beží na klientovi,interaktĆ­vne,intraktĆ­vne,posunĆŗÅ„", + "title": "PDF Multi NĆ”stroj", + "header": "PDF Multi NĆ”stroj", + "uploadPrompts": "File Name", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "selectPages": "Page Select", + "selectedPages": "Selected Pages", + "page": "Page", + "deleteSelected": "Delete Selected", + "downloadAll": "Export", + "downloadSelected": "Export Selected", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "Page(s) Selected", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "zlĆŗÄenie,operĆ”cie so strĆ”nkami,back end,beží na serveri", + "title": "ZlĆŗÄiÅ„", + "header": "ZlĆŗÄiÅ„ viacero PDF (2+)", + "sortByName": "ZoradiÅ„ podľa nĆ”zvu", + "sortByDate": "ZoradiÅ„ podľa dĆ”tumu", + "removeCertSign": "Remove digital signature in the merged file?", + "submit": "ZlĆŗÄiÅ„" + }, + "split": { + "tags": "operĆ”cie so strĆ”nkami,rozdelenie,viacstranovĆ©,rozrezaÅ„,beží na serveri", + "title": "RozdeliÅ„ PDF", + "header": "RozdeliÅ„ PDF", + "desc": { + "1": "Čísla vybranĆ© sĆŗ čƭsla strĆ”nok, na ktorých chcete urobiÅ„ rozdelenie", + "2": "Takže výber 1,3,7-9 by rozdelil 10-stranový dokument na 6 samostatných PDF s:", + "3": "Dokument č. 1: Strana 1", + "4": "Dokument č. 2: Strany 2 a 3", + "5": "Dokument č. 3: Strany 4, 5, 6, 7", + "6": "Dokument č. 4: Strana 8", + "7": "Dokument č. 5: Strana 9", + "8": "Dokument č. 6: Strana 10" + }, + "splitPages": "Zadajte strĆ”nky na rozdelenie:", + "submit": "RozdeliÅ„" + }, + "rotate": { + "tags": "beží na serveri", + "title": "OtočiÅ„ PDF", + "header": "OtočiÅ„ PDF", + "selectAngle": "Vyberte uhol otočenia (v nĆ”sobkoch 90 stupňov):", + "submit": "OtočiÅ„" + }, + "imageToPdf": { + "tags": "konverzia,img,jpg,obrĆ”zok,fotografia" + }, + "pdfToImage": { + "tags": "konverzia,img,jpg,obrĆ”zok,fotografia", + "title": "PDF na obrĆ”zok", + "header": "PDF na obrĆ”zok", + "selectText": "FormĆ”t obrĆ”zka", + "singleOrMultiple": "Typ výslednĆ©ho obrĆ”zka", + "single": "Jedna veľkĆ” snĆ­mka", + "multi": "ViacerĆ© snĆ­mky", + "colorType": "Typ farby", + "color": "Farba", + "grey": "Odtiene Å”edej", + "blackwhite": "Čierno-biele (MÓže stratiÅ„ Ćŗdaje!)", + "submit": "KonvertovaÅ„", + "info": "Python is not installed. Required for WebP conversion.", + "placeholder": "(napr. 1,2,8 alebo 4,7,12-16 alebo 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,nepĆ”rne,pĆ”rne,zoradiÅ„,posunĆŗÅ„", + "title": "OrganizĆ”tor strĆ”nok", + "header": "OrganizĆ”tor strĆ”nok PDF", + "submit": "PreusporiadaÅ„ strĆ”nky", + "mode": { + "_value": "Režim", + "1": "VlastnĆ© poradie strĆ”nok", + "2": "ObrĆ”tenĆ© poradie", + "3": "DuplexnĆ© triedenie", + "4": "TriedenĆ” brožúra", + "5": "Brožúra s bočným Å”itĆ­m", + "6": "Rozdelenie na nepĆ”rne a pĆ”rne", + "7": "OdstrĆ”niÅ„ prvĆŗ", + "8": "OdstrĆ”niÅ„ poslednĆŗ", + "9": "OdstrĆ”niÅ„ prvĆŗ aj poslednĆŗ", + "10": "Odd-Even Merge", + "11": "Duplicate all pages" + }, + "placeholder": "(napr. 1,3,2 alebo 4-8,2,10-12 alebo 2n-1)" + }, + "addImage": { + "tags": "img,jpg,obrĆ”zok,fotografia", + "title": "PridaÅ„ obrĆ”zok", + "header": "PridaÅ„ obrĆ”zok do PDF", + "everyPage": "KaždĆ” strĆ”nka?", + "upload": "PridaÅ„ obrĆ”zok", + "submit": "PridaÅ„ obrĆ”zok" + }, + "watermark": { + "tags": "Text,opakujĆŗci sa,označenie,vlastnĆ©,autorskĆ© prĆ”va,ochrannĆ” znĆ”mka,img,jpg,obrĆ”zok,fotografia", + "title": "PridaÅ„ vodotlač", + "header": "PridaÅ„ vodotlač", + "customColor": "VlastnĆ” farba textu", + "selectText": { + "1": "Vyberte PDF, do ktorĆ©ho chcete pridaÅ„ vodotlač:", + "2": "Text vodotlače:", + "3": "VeľkosÅ„ pĆ­sma:", + "4": "RotĆ”cia (0-360):", + "5": "Å Ć­rka medzery (Medzera medzi jednotlivými vodotlačami horizontĆ”lne):", + "6": "VýŔka medzery (Medzera medzi jednotlivými vodotlačami vertikĆ”lne):", + "7": "PriehľadnosÅ„ (0% - 100%):", + "8": "Typ vodotlače:", + "9": "ObrĆ”zok vodotlače:", + "10": "Convert PDF to PDF-Image" + }, + "submit": "PridaÅ„ vodotlač", + "type": { + "1": "Text", + "2": "ObrĆ”zok" + } + }, + "permissions": { + "tags": "čƭtaÅ„,pĆ­saÅ„,upravovaÅ„,tlačiÅ„", + "title": "ZmeniÅ„ povolenia", + "header": "ZmeniÅ„ povolenia", + "warning": "Varovanie: Aby boli tieto povolenia nemennĆ©, odporĆŗÄa sa nastaviÅ„ ich s heslom cez strĆ”nku pridania hesla", + "selectText": { + "1": "Vyberte PDF na zmenu povolenĆ­", + "2": "Nastavenia povolenĆ­", + "3": "ZakĆ”zaÅ„ zostavovanie dokumentu", + "4": "ZakĆ”zaÅ„ extrakciu obsahu", + "5": "ZakĆ”zaÅ„ extrakciu pre prĆ­stupnosÅ„", + "6": "ZakĆ”zaÅ„ vypĺňanie formulĆ”rov", + "7": "ZakĆ”zaÅ„ Ćŗpravy", + "8": "ZakĆ”zaÅ„ Ćŗpravu anotĆ”ciĆ­", + "9": "ZakĆ”zaÅ„ tlač", + "10": "ZakĆ”zaÅ„ tlač rĆ“znych formĆ”tov" + }, + "submit": "ZmeniÅ„" + }, + "removePages": { + "tags": "OdstrĆ”niÅ„ strĆ”nky,vymazaÅ„ strĆ”nky" + }, + "addPassword": { + "tags": "zaistiÅ„,bezpečnosÅ„", + "title": "PridaÅ„ heslo", + "header": "PridaÅ„ heslo (ZaÅ”ifrovaÅ„)", + "selectText": { + "1": "Vyberte PDF na zaÅ”ifrovanie", + "2": "PoužívateľskĆ© heslo", + "3": "Dĺžka Å”ifrovacieho kÄ¾ĆŗÄa", + "4": "VyŔŔie hodnoty sĆŗ silnejÅ”ie, ale nižŔie hodnoty majĆŗ lepÅ”iu kompatibilitu.", + "5": "Nastavenia povolenĆ­ (OdporĆŗÄa sa používaÅ„ spolu s heslom vlastnĆ­ka)", + "6": "ZakĆ”zaÅ„ zostavovanie dokumentu", + "7": "ZakĆ”zaÅ„ extrakciu obsahu", + "8": "ZakĆ”zaÅ„ extrakciu pre prĆ­stupnosÅ„", + "9": "ZakĆ”zaÅ„ vypĺňanie formulĆ”rov", + "10": "ZakĆ”zaÅ„ Ćŗpravy", + "11": "ZakĆ”zaÅ„ Ćŗpravu anotĆ”ciĆ­", + "12": "ZakĆ”zaÅ„ tlač", + "13": "ZakĆ”zaÅ„ tlač rĆ“znych formĆ”tov", + "14": "Heslo vlastnĆ­ka", + "15": "Obmedzuje, čo mÓže byÅ„ vykonanĆ© s dokumentom po jeho otvorenĆ­ (NepodporovanĆ© vÅ”etkými čƭtačmi)", + "16": "Obmedzuje samotnĆ© otvorenie dokumentu" + }, + "submit": "ZaÅ”ifrovaÅ„" + }, + "removePassword": { + "tags": "zaistiÅ„,DeÅ”ifrovaÅ„,bezpečnosÅ„,odheslovaÅ„,vymazaÅ„ heslo", + "title": "OdstrĆ”niÅ„ heslo", + "header": "OdstrĆ”niÅ„ heslo (DeÅ”ifrovaÅ„)", + "selectText": { + "1": "Vyberte PDF na deÅ”ifrovanie", + "2": "Heslo" + }, + "submit": "OdstrĆ”niÅ„" + }, + "compressPdfs": { + "tags": "stlačiÅ„,malĆ©,drobnĆ©" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "NĆ”zov,autor,dĆ”tum,vytvorenie,čas,vydavateľ,producent,Å”tatistiky", + "title": "ZmeniÅ„ metadĆ”ta", + "header": "ZmeniÅ„ metadĆ”ta", + "selectText": { + "1": "ProsĆ­m, upravte premennĆ©, ktorĆ© chcete zmeniÅ„", + "2": "VymazaÅ„ vÅ”etky metadĆ”ta", + "3": "ZobraziÅ„ vlastnĆ© metadĆ”ta:", + "4": "InĆ© metadĆ”ta:", + "5": "PridaÅ„ vlastný zĆ”znam metadĆ”t" + }, + "author": "Autor:", + "creationDate": "DĆ”tum vytvorenia (yyyy/MM/dd HH:mm:ss):", + "creator": "Tvorca:", + "keywords": "KÄ¾ĆŗÄovĆ© slovĆ”:", + "modDate": "DĆ”tum Ćŗpravy (yyyy/MM/dd HH:mm:ss):", + "producer": "Producent:", + "subject": "Predmet:", + "trapped": "ZachytenĆ©:", + "submit": "ZmeniÅ„" + }, + "fileToPDF": { + "tags": "transformĆ”cia,formĆ”t,dokument,obrĆ”zok,prezentĆ”cia,text,konverzia,kancelĆ”ria,dokumenty,word,excel,powerpoint", + "title": "SĆŗbor do PDF", + "header": "KonvertovaÅ„ akýkoľvek sĆŗbor do PDF", + "credit": "TĆ”to služba používa LibreOffice a Unoconv pre konverziu sĆŗborov.", + "supportedFileTypesInfo": "Supported File types", + "supportedFileTypes": "PodporovanĆ© typy sĆŗborov by mali zahŕňaÅ„ nižŔie uvedenĆ©, avÅ”ak pre Ćŗplný aktualizovaný zoznam podporovaných formĆ”tov, prosĆ­m, odkazujte na dokumentĆ”ciu LibreOffice", + "submit": "KonvertovaÅ„ do PDF" + }, + "ocr": { + "tags": "rozpoznanie,text,obrĆ”zok,scan,čƭtaÅ„,identifikovaÅ„,detekcia,upraviteľnĆ©", + "title": "OCR / Čistenie skenov", + "header": "Čistenie skenov / OCR (OptickĆ© rozpoznĆ”vanie znakov)", + "selectText": { + "1": "Vyberte jazyky, ktorĆ© majĆŗ byÅ„ detekovanĆ© v PDF (UvedenĆ© sĆŗ tie, ktorĆ© sĆŗ aktuĆ”lne detekovanĆ©):", + "2": "VytvoriÅ„ textový sĆŗbor obsahujĆŗci OCR text spolu s OCR PDF", + "3": "OpraviÅ„ strĆ”nky, ktorĆ© boli naskenovanĆ© pod uhlom, otočenĆ­m späń na miesto", + "4": "VyčistiÅ„ strĆ”nku, aby OCR menej pravdepodobne naÅ”lo text v Å”ume pozadia. (Žiadna zmena výstupu)", + "5": "VyčistiÅ„ strĆ”nku, aby OCR menej pravdepodobne naÅ”lo text v Å”ume pozadia, zachovĆ”va čistenie vo výstupe.", + "6": "Ignoruje strĆ”nky, ktorĆ© majĆŗ interaktĆ­vny text, OCR iba strĆ”nky, ktorĆ© sĆŗ obrĆ”zky", + "7": "VynĆŗtiÅ„ OCR, OCR každĆŗ strĆ”nku odstrĆ”nenĆ­m vÅ”etkých pĆ“vodných textových prvkov", + "8": "NormĆ”lne (Chyba, ak PDF obsahuje text)", + "9": "ĎalÅ”ie nastavenia", + "10": "OCR režim", + "11": "OdstrĆ”niÅ„ obrĆ”zky po OCR (OdstrĆ”ni VÅ ETKY obrĆ”zky, užitočnĆ© iba ak je sĆŗÄasÅ„ou konverznĆ©ho kroku)", + "12": "Typ vykreslenia (PokročilĆ©)" + }, + "help": "ProsĆ­m, prečƭtajte si tĆŗto dokumentĆ”ciu o tom, ako používaÅ„ OCR pre inĆ© jazyky a/alebo použitie mimo docker", + "credit": "TĆ”to služba používa qpdf a Tesseract pre OCR.", + "submit": "SpracovaÅ„ PDF s OCR" + }, + "extractImages": { + "tags": "obrĆ”zok,fotografia,uložiÅ„,archĆ­v,zip,zachytiÅ„,chytiÅ„", + "title": "ExtrahovaÅ„ obrĆ”zky", + "header": "ExtrahovaÅ„ obrĆ”zky", + "selectText": "Vyberte formĆ”t obrĆ”zka na konverziu extrahovaných obrĆ”zkov", + "allowDuplicates": "Save duplicate images", + "submit": "ExtrahovaÅ„" + }, + "pdfToPDFA": { + "tags": "archĆ­v,dÄŗhodobĆ©,Å”tandard,konverzia,uchovanie", + "title": "PDF na PDF/A", + "header": "PDF na PDF/A", + "credit": "TĆ”to služba používa libreoffice na konverziu PDF/A", + "submit": "KonvertovaÅ„", + "tip": "MomentĆ”lne nefunguje pre viacero vstupov naraz", + "outputFormat": "Výstupný formĆ”t", + "pdfWithDigitalSignature": "The PDF contains a digital signature. This will be removed in the next step." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformĆ”cia,formĆ”t,konverzia,kancelĆ”ria,microsoft,dokument", + "title": "PDF na Word", + "header": "PDF na Word", + "selectText": { + "1": "Výstupný formĆ”t sĆŗboru" + }, + "credit": "TĆ”to služba používa LibreOffice na konverziu sĆŗborov.", + "submit": "KonvertovaÅ„" + }, + "PDFToPresentation": { + "tags": "slajdy,prezentĆ”cia,kancelĆ”ria,microsoft", + "title": "PDF na PrezentĆ”ciu", + "header": "PDF na PrezentĆ”ciu", + "selectText": { + "1": "Výstupný formĆ”t sĆŗboru" + }, + "credit": "TĆ”to služba používa LibreOffice na konverziu sĆŗborov.", + "submit": "KonvertovaÅ„" + }, + "PDFToText": { + "tags": "bohatý formĆ”t,bohatý textový formĆ”t,bohatý text", + "title": "PDF na RTF (Text)", + "header": "PDF na RTF (Text)", + "selectText": { + "1": "Výstupný formĆ”t sĆŗboru" + }, + "credit": "TĆ”to služba používa LibreOffice na konverziu sĆŗborov.", + "submit": "KonvertovaÅ„" + }, + "PDFToHTML": { + "tags": "webový obsah,prehliadač priateľský", + "title": "PDF na HTML", + "header": "PDF na HTML", + "credit": "TĆ”to služba používa pdftohtml na konverziu sĆŗborov.", + "submit": "KonvertovaÅ„" + }, + "PDFToXML": { + "tags": "extrakcia dĆ”t,Å”truktĆŗrovaný obsah,interop,transformĆ”cia,konvertovaÅ„", + "title": "PDF na XML", + "header": "PDF na XML", + "credit": "TĆ”to služba používa LibreOffice na konverziu sĆŗborov.", + "submit": "KonvertovaÅ„" + }, + "ScannerImageSplit": { + "tags": "rozdeliÅ„,auto-detekcia,skeny,viac-fotografiĆ­,organizovaÅ„", + "selectText": { + "1": "PrahovĆ” hodnota uhla:", + "2": "NastavĆ­ minimĆ”lny absolĆŗtny uhol potrebný na otočenie obrĆ”zka (predvolenĆ©: 10).", + "3": "Tolerancia:", + "4": "Určuje rozsah farebnej variĆ”cie okolo odhadovanej farby pozadia (predvolenĆ©: 30).", + "5": "MinimĆ”lna plocha:", + "6": "NastavĆ­ minimĆ”lnu prahovĆŗ hodnotu plochy pre fotografiu (predvolenĆ©: 10000).", + "7": "MinimĆ”lna plocha obrysu:", + "8": "NastavĆ­ minimĆ”lnu prahovĆŗ hodnotu plochy obrysu pre fotografiu", + "9": "VeľkosÅ„ okraja:", + "10": "NastavĆ­ veľkosÅ„ okraja pridanĆ©ho a odstrĆ”nenĆ©ho, aby sa zabrĆ”nilo bielym okrajom vo výstupe (predvolenĆ©: 1)." + }, + "info": "Python is not installed. It is required to run." + }, + "sign": { + "tags": "autorizovaÅ„,iniciĆ”ly,kreslený podpis,textový podpis,obrĆ”zkový podpis", + "title": "PodpĆ­saÅ„", + "header": "PodpĆ­saÅ„ PDF", + "upload": "NahraÅ„ obrĆ”zok", + "draw": "KresliÅ„ podpis", + "text": "Textový vstup", + "clear": "VymazaÅ„", + "add": "PridaÅ„", + "saved": "Saved Signatures", + "save": "Save Signature", + "personalSigs": "Personal Signatures", + "sharedSigs": "Shared Signatures", + "noSavedSigs": "No saved signatures found", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "statickĆ©,deaktivovaÅ„,neinteraktĆ­vne,zjednoduÅ”iÅ„", + "title": "ZploÅ”tiÅ„", + "header": "ZploÅ”tiÅ„ PDF", + "flattenOnlyForms": "ZploÅ”tiÅ„ iba formulĆ”re", + "submit": "ZploÅ”tiÅ„" + }, + "repair": { + "tags": "opraviÅ„,obnoviÅ„,oprava,obnovenie", + "title": "OpraviÅ„", + "header": "OpraviÅ„ PDF", + "submit": "OpraviÅ„" + }, + "removeBlanks": { + "tags": "čistenie,zjednoduÅ”iÅ„,neobsah,organizovaÅ„", + "title": "OdstrĆ”niÅ„ prĆ”zdne strĆ”nky", + "header": "OdstrĆ”niÅ„ prĆ”zdne strĆ”nky", + "threshold": "PrahovĆ” hodnota bielych pixelov:", + "thresholdDesc": "PrahovĆ” hodnota pre určenie, ako biely musĆ­ byÅ„ biely pixel, aby bol klasifikovaný ako 'biely'. 0 = čierny, 255 = čistĆ” biela.", + "whitePercent": "Percento bielych pixelov (%):", + "whitePercentDesc": "Percento strĆ”nky, ktorĆ© musĆ­ byÅ„ 'biele' pixely, aby bola odstrĆ”nenĆ”", + "submit": "OdstrĆ”niÅ„ prĆ”zdne strĆ”nky" + }, + "removeAnnotations": { + "tags": "komentĆ”re,zdĆ“raznenie,poznĆ”mky,označenie,odstrĆ”niÅ„", + "title": "OdstrĆ”niÅ„ anotĆ”cie", + "header": "OdstrĆ”niÅ„ anotĆ”cie", + "submit": "OdstrĆ”niÅ„" + }, + "compare": { + "tags": "odliÅ”ovaÅ„,kontrast,zmeny,analýza", + "title": "PorovnaÅ„", + "header": "PorovnaÅ„ PDF", + "highlightColor": { + "1": "Highlight Color 1:", + "2": "Highlight Color 2:" + }, + "document": { + "1": "Dokument 1", + "2": "Dokument 2" + }, + "submit": "PorovnaÅ„", + "complex": { + "message": "One or both of the provided documents are large files, accuracy of comparison may be reduced" + }, + "large": { + "file": { + "message": "One or Both of the provided documents are too large to process" + } + }, + "no": { + "text": { + "message": "One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison." + } + } + }, + "certSign": { + "tags": "autentifikovaÅ„,PEM,P12,oficiĆ”lne,Å”ifrovaÅ„", + "title": "Podpis certifikĆ”tom", + "header": "PodpĆ­saÅ„ PDF certifikĆ”tom (PrĆ”ca prebieha)", + "selectPDF": "Vyberte PDF sĆŗbor na podpis:", + "jksNote": "PoznĆ”mka: Ak vÔŔ typ certifikĆ”tu nie je uvedený nižŔie, prosĆ­m, konvertujte ho na Java Keystore (.jks) sĆŗbor pomocou nĆ”stroja keytool. Potom vyberte možnosÅ„ .jks sĆŗbor nižŔie.", + "selectKey": "Vyberte vÔŔ sĆŗkromný kÄ¾ĆŗÄový sĆŗbor (formĆ”t PKCS#8, mÓže byÅ„ .pem alebo .der):", + "selectCert": "Vyberte vÔŔ certifikĆ”tový sĆŗbor (formĆ”t X.509, mÓže byÅ„ .pem alebo .der):", + "selectP12": "Vyberte vÔŔ PKCS#12 Keystore sĆŗbor (.p12 alebo .pfx) (VoliteľnĆ©, ak je poskytnutĆ©, malo by obsahovaÅ„ vÔŔ sĆŗkromný kÄ¾ĆŗÄ a certifikĆ”t):", + "selectJKS": "Vyberte vÔŔ Java Keystore sĆŗbor (.jks alebo .keystore):", + "certType": "Typ certifikĆ”tu", + "password": "Zadajte heslo pre Keystore alebo sĆŗkromný kÄ¾ĆŗÄ (ak existuje):", + "showSig": "ZobraziÅ„ podpis", + "reason": "DĆ“vod", + "location": "Miesto", + "name": "Meno", + "showLogo": "Show Logo", + "submit": "PodpĆ­saÅ„ PDF" + }, + "removeCertSign": { + "tags": "authenticate,PEM,P12,official,decrypt", + "title": "Remove Certificate Signature", + "header": "Remove the digital certificate from the PDF", + "selectPDF": "Select a PDF file:", + "submit": "Remove Signature" + }, + "pageLayout": { + "tags": "zlĆŗÄiÅ„,zjednotiÅ„,jednostranový pohľad,organizovaÅ„", + "title": "ViacstranovĆ© usporiadanie", + "header": "ViacstranovĆ© usporiadanie", + "pagesPerSheet": "StrĆ”nky na list:", + "addBorder": "PridaÅ„ okraje", + "submit": "OdoslaÅ„" + }, + "scalePages": { + "tags": "veľkosÅ„,modifikovaÅ„,rozmery,prispĆ“sobiÅ„", + "title": "UpraviÅ„ mierku strĆ”nky", + "header": "UpraviÅ„ mierku strĆ”nky", + "pageSize": "VeľkosÅ„ strĆ”nky dokumentu.", + "keepPageSize": "Original Size", + "scaleFactor": "Úroveň priblíženia (orezania) strĆ”nky.", + "submit": "OdoslaÅ„" + }, + "add-page-numbers": { + "tags": "čƭslovaÅ„,označiÅ„,organizovaÅ„,indexovaÅ„" + }, + "auto-rename": { + "tags": "auto-detekcia, založenĆ© na zĆ”hlavĆ­, organizovaÅ„, premenovaÅ„", + "title": "AutomatickĆ© premenovanie", + "header": "AutomatickĆ© premenovanie PDF", + "submit": "Automaticky premenovaÅ„" + }, + "adjust-contrast": { + "tags": "farbovĆ” korekcia, doladenie, upraviÅ„, zlepÅ”iÅ„" + }, + "crop": { + "tags": "orezaÅ„, zmenÅ”iÅ„, upraviÅ„, tvarovaÅ„", + "title": "OrezaÅ„", + "header": "OrezaÅ„ PDF", + "submit": "OdoslaÅ„" + }, + "autoSplitPDF": { + "tags": "QR-založenĆ©, rozdeľ, skenovanie-segment, organizovaÅ„", + "title": "AutomatickĆ© rozdelenie PDF", + "header": "AutomatickĆ© rozdelenie PDF", + "description": "Vytlačte, vložte, naskenujte, nahrajte a nechajte nĆ”s automaticky oddeliÅ„ vaÅ”e dokumenty. Žiadna manuĆ”lna prĆ”ca nie je potrebnĆ”.", + "selectText": { + "1": "Vytlačte si niekoľko rozdeľovacĆ­ch listov nižŔie (Čierno-biele je v poriadku).", + "2": "Naskenujte vÅ”etky svoje dokumenty naraz vloženĆ­m rozdeľovacieho listu medzi ne.", + "3": "Nahrajte jeden veľký naskenovaný PDF sĆŗbor a nechajte Stirling PDF urobiÅ„ zvyÅ”ok.", + "4": "Rozdeľovacie strĆ”nky sĆŗ automaticky detekovanĆ© a odstrĆ”nenĆ©, čo zaručuje čistý konečný dokument." + }, + "formPrompt": "OdoslaÅ„ PDF obsahujĆŗce Stirling-PDF rozdeľovače strĆ”nok:", + "duplexMode": "Duplex režim (skanovanie prednej a zadnej strany)", + "dividerDownload2": "StiahnuÅ„ 'Auto Splitter Divider (s inÅ”trukciami).pdf'", + "submit": "OdoslaÅ„" + }, + "sanitizePdf": { + "tags": "čistiÅ„, zabezpečiÅ„, bezpečnĆ©, odstrĆ”niÅ„ hrozby" + }, + "URLToPDF": { + "tags": "webovĆ” snĆ­mka, uložiÅ„ strĆ”nku, web do dokumentu, archĆ­v", + "title": "URL do PDF", + "header": "URL do PDF", + "submit": "KonvertovaÅ„", + "credit": "Používa WeasyPrint" + }, + "HTMLToPDF": { + "tags": "markup, webový obsah, transformĆ”cia, konvertovaÅ„", + "title": "HTML do PDF", + "header": "HTML do PDF", + "help": "Akceptuje HTML sĆŗbory a ZIPy obsahujĆŗce html/css/obrĆ”zky atď. potrebnĆ©", + "submit": "KonvertovaÅ„", + "credit": "Používa WeasyPrint", + "zoom": "Úroveň priblíženia pre zobrazenie webstrĆ”nky.", + "pageWidth": "Å Ć­rka strĆ”nky v centimetroch. (PrĆ”zdne pre predvolenĆ©)", + "pageHeight": "VýŔka strĆ”nky v centimetroch. (PrĆ”zdne pre predvolenĆ©)", + "marginTop": "Horný okraj strĆ”nky v milimetroch. (PrĆ”zdne pre predvolenĆ©)", + "marginBottom": "Dolný okraj strĆ”nky v milimetroch. (PrĆ”zdne pre predvolenĆ©)", + "marginLeft": "Ľavý okraj strĆ”nky v milimetroch. (PrĆ”zdne pre predvolenĆ©)", + "marginRight": "Pravý okraj strĆ”nky v milimetroch. (PrĆ”zdne pre predvolenĆ©)", + "printBackground": "VykresliÅ„ pozadie webstrĆ”nok.", + "defaultHeader": "PovoliÅ„ predvolenĆ© zĆ”hlavie (NĆ”zov a čƭslo strĆ”nky)", + "cssMediaType": "ZmeniÅ„ typ CSS mĆ©diĆ­ strĆ”nky.", + "none": "Žiadne", + "print": "Tlač", + "screen": "Obrazovka" + }, + "MarkdownToPDF": { + "tags": "markup, webový obsah, transformĆ”cia, konvertovaÅ„", + "title": "Markdown do PDF", + "header": "Markdown do PDF", + "submit": "KonvertovaÅ„", + "help": "PrĆ”ca prebieha", + "credit": "Používa WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "informĆ”cie, Ćŗdaje, Å”tatistiky", + "title": "ZĆ­skaÅ„ informĆ”cie o PDF", + "header": "ZĆ­skaÅ„ informĆ”cie o PDF", + "submit": "ZĆ­skaÅ„ info", + "downloadJson": "StiahnuÅ„ JSON" + }, + "extractPage": { + "tags": "extrahovaÅ„" + }, + "PdfToSinglePage": { + "tags": "jedna strĆ”nka" + }, + "showJS": { + "tags": "JS", + "title": "ZobraziÅ„ JavaScript", + "header": "ZobraziÅ„ JavaScript", + "downloadJS": "StiahnuÅ„ JavaScript", + "submit": "ZobraziÅ„" + }, + "autoRedact": { + "tags": "redigovaÅ„, skryÅ„, zatieniÅ„, čierne, marker, skrytĆ©", + "title": "AutomatickĆ© redigovanie", + "header": "AutomatickĆ© redigovanie", + "colorLabel": "Farba", + "textsToRedactLabel": "Text na redigovanie (oddelený riadkami)", + "textsToRedactPlaceholder": "napr. \\nDĆ“vernĆ© \\nPrĆ­sne tajnĆ©", + "useRegexLabel": "PoužiÅ„ Regex", + "wholeWordSearchLabel": "VyhľadĆ”vanie celých slov", + "customPaddingLabel": "VlastnĆ© odsadenie", + "convertPDFToImageLabel": "KonvertovaÅ„ PDF na PDF-ObrĆ”zok (Používa sa na odstrĆ”nenie textu za boxom)", + "submitButton": "OdoslaÅ„" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV, extrakcia tabuliek, extrahovaÅ„, konvertovaÅ„" + }, + "autoSizeSplitPDF": { + "tags": "pdf, rozdelenie, dokument, organizĆ”cia" + }, + "overlay-pdfs": { + "tags": "prekrývanie", + "header": "Prekrytie PDF sĆŗborov", + "baseFile": { + "label": "Vyberte zĆ”kladný PDF sĆŗbor" + }, + "overlayFiles": { + "label": "Vyberte prekryvnĆ© PDF sĆŗbory" + }, + "mode": { + "label": "Vyberte režim prekrytia", + "sequential": "SĆ©riovĆ© prekrytie", + "interleaved": "PrepletenĆ© prekrytie", + "fixedRepeat": "PevnĆ© opakovanĆ© prekrytie" + }, + "counts": { + "label": "Počty prekrytĆ­ (pre režim pevnĆ©ho opakovania)", + "placeholder": "Zadajte počty oddelenĆ© čiarkami (napr. 2,3,1)" + }, + "position": { + "label": "Vyberte pozĆ­ciu prekrytia", + "foreground": "Popredie", + "background": "Pozadie" + }, + "submit": "OdoslaÅ„" + }, + "split-by-sections": { + "tags": "rozdelenie sekciĆ­, rozdeliÅ„, prispĆ“sobiÅ„", + "title": "RozdeliÅ„ PDF podľa sekciĆ­", + "header": "RozdeliÅ„ PDF na sekcie", + "horizontal": { + "label": "HorizontĆ”lne delenia", + "placeholder": "Zadajte počet horizontĆ”lnych delenĆ­" + }, + "vertical": { + "label": "VertikĆ”lne delenia", + "placeholder": "Zadajte počet vertikĆ”lnych delenĆ­" + }, + "submit": "RozdeliÅ„ PDF", + "merge": "ZlĆŗÄiÅ„ do jednĆ©ho PDF" + }, + "AddStampRequest": { + "tags": "pečiatka, pridaÅ„ obrĆ”zok, stred obrĆ”zka, vodotlač, PDF, vložiÅ„, prispĆ“sobiÅ„", + "header": "Pečiatka PDF", + "title": "Pečiatka PDF", + "stampType": "Typ pečiatky", + "stampText": "Text pečiatky", + "stampImage": "ObrĆ”zok pečiatky", + "alphabet": "Abeceda", + "fontSize": "VeľkosÅ„ pĆ­sma/obrĆ”zka", + "rotation": "RotĆ”cia", + "opacity": "PriehľadnosÅ„", + "position": "Poloha", + "overrideX": "NahradiÅ„ sĆŗradnicu X", + "overrideY": "NahradiÅ„ sĆŗradnicu Y", + "customMargin": "Vlastný okraj", + "customColor": "VlastnĆ” farba textu", + "submit": "OdoslaÅ„" + }, + "removeImagePdf": { + "tags": "Remove Image,Page operations,Back end,server side" + }, + "splitPdfByChapters": { + "tags": "split,chapters,bookmarks,organize" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Replace-Invert-Color", + "header": "Replace-Invert Color PDF", + "selectText": { + "1": "Replace or Invert color Options", + "2": "Default(Default high contrast colors)", + "3": "Custom(Customized colors)", + "4": "Full-Invert(Invert all colors)", + "5": "High contrast color options", + "6": "white text on black background", + "7": "Black text on white background", + "8": "Yellow text on black background", + "9": "Green text on black background", + "10": "Choose text Color", + "11": "Choose background Color" + }, + "submit": "Replace" + }, + "replaceColorPdf": { + "tags": "Replace Color,Page operations,Back end,server side" + }, + "login": { + "title": "PrihlĆ”senie", + "header": "PrihlĆ”senie", + "signin": "PrihlĆ”siÅ„ sa", + "rememberme": "ZapamƤtaÅ„ si ma", + "invalid": "NeplatnĆ© používateľskĆ© meno alebo heslo.", + "locked": "VÔŔ ĆŗÄet bol uzamknutý.", + "signinTitle": "ProsĆ­m, prihlĆ”ste sa", + "ssoSignIn": "PrihlĆ”siÅ„ sa cez Single Sign-on", + "oAuth2AutoCreateDisabled": "VytvĆ”ranie používateľa cez OAUTH2 je zakĆ”zanĆ©", + "oAuth2AdminBlockedUser": "Registration or logging in of non-registered users is currently blocked. Please contact the administrator.", + "oauth2RequestNotFound": "Authorization request not found", + "oauth2InvalidUserInfoResponse": "Invalid User Info Response", + "oauth2invalidRequest": "Invalid Request", + "oauth2AccessDenied": "Access Denied", + "oauth2InvalidTokenResponse": "Invalid Token Response", + "oauth2InvalidIdToken": "Invalid Id Token", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "User is deactivated, login is currently blocked with this username. Please contact the administrator.", + "alreadyLoggedIn": "You are already logged in to", + "alreadyLoggedIn2": "devices. Please log out of the devices and try again.", + "toManySessions": "You have too many active sessions", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF na jednu strĆ”nku", + "header": "PDF na jednu strĆ”nku", + "submit": "KonvertovaÅ„ na jednu strĆ”nku" + }, + "pageExtracter": { + "title": "ExtrahovaÅ„ strĆ”nky", + "header": "ExtrahovaÅ„ strĆ”nky", + "submit": "ExtrahovaÅ„", + "placeholder": "(napr. 1,2,8 alebo 4,7,12-16 alebo 2n-1)" + }, + "sanitizePDF": { + "title": "VyčistiÅ„ PDF", + "header": "VyčistiÅ„ PDF sĆŗbor", + "selectText": { + "1": "OdstrĆ”niÅ„ JavaScript akcie", + "2": "OdstrĆ”niÅ„ vloženĆ© sĆŗbory", + "3": "Remove XMP metadata", + "4": "OdstrĆ”niÅ„ odkazy", + "5": "OdstrĆ”niÅ„ fonty", + "6": "Remove Document Info Metadata" + }, + "submit": "VyčistiÅ„ PDF" + }, + "adjustContrast": { + "title": "UpraviÅ„ kontrast", + "header": "UpraviÅ„ kontrast", + "contrast": "Kontrast:", + "brightness": "Jas:", + "saturation": "SýtosÅ„:", + "download": "StiahnuÅ„" + }, + "compress": { + "title": "KomprimovaÅ„", + "header": "KomprimovaÅ„ PDF", + "credit": "TĆ”to služba používa qpdf pre kompresiu/optimalizĆ”ciu PDF.", + "grayscale": { + "label": "PoužiÅ„ odtiene Å”edej na kompresiu" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Úroveň optimalizĆ”cie:", + "4": "Automatický režim - Automaticky upravuje kvalitu, aby sa PDF dostalo na presnĆŗ veľkosÅ„", + "5": "OčakĆ”vanĆ” veľkosÅ„ PDF (napr. 25MB, 10.8MB, 25KB)" + }, + "submit": "KomprimovaÅ„" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "Odstraňovač strĆ”nok", + "header": "Odstraňovač strĆ”nok PDF", + "pagesToDelete": "StrĆ”nky na odstrĆ”nenie (Zadajte zoznam čƭsel strĆ”nok oddelených čiarkami):", + "submit": "OdstrĆ”niÅ„ strĆ”nky", + "placeholder": "(napr. 1,2,6 alebo 1-10,15-30)" + }, + "imageToPDF": { + "title": "ObrĆ”zok na PDF", + "header": "ObrĆ”zok na PDF", + "submit": "KonvertovaÅ„", + "selectLabel": "Možnosti prispĆ“sobenia obrĆ”zka", + "fillPage": "VyplniÅ„ strĆ”nku", + "fitDocumentToImage": "PrispĆ“sobiÅ„ strĆ”nku obrĆ”zku", + "maintainAspectRatio": "ZachovaÅ„ pomery strĆ”n", + "selectText": { + "2": "AutomatickĆ© otočenie PDF", + "3": "Logika pre viac sĆŗborov (PovolĆ­ sa len, ak pracujete s viacerými obrĆ”zkami)", + "4": "ZlĆŗÄiÅ„ do jednĆ©ho PDF", + "5": "KonvertovaÅ„ na samostatnĆ© PDF" + } + }, + "PDFToCSV": { + "title": "PDF na CSV", + "header": "PDF na CSV", + "prompt": "Vyberte strĆ”nku na extrakciu tabuľky", + "submit": "ExtrahovaÅ„" + }, + "split-by-size-or-count": { + "title": "RozdeliÅ„ PDF podľa veľkosti alebo počtu", + "header": "RozdeliÅ„ PDF podľa veľkosti alebo počtu", + "type": { + "label": "Vyberte typ rozdelenia", + "size": "Podľa veľkosti", + "pageCount": "Podľa počtu strĆ”nok", + "docCount": "Podľa počtu dokumentov" + }, + "value": { + "label": "Zadajte hodnotu", + "placeholder": "Zadajte veľkosÅ„ (napr. 2MB alebo 3KB) alebo počet (napr. 5)" + }, + "submit": "OdoslaÅ„" + }, + "printFile": { + "title": "VytlačiÅ„ sĆŗbor", + "header": "VytlačiÅ„ sĆŗbor na tlačiareň", + "selectText": { + "1": "Vyberte sĆŗbor na tlač", + "2": "Zadajte nĆ”zov tlačiarne" + }, + "submit": "VytlačiÅ„" + }, + "licenses": { + "nav": "Licencie", + "title": "Licencie tretĆ­ch strĆ”n", + "header": "Licencie tretĆ­ch strĆ”n", + "module": "Modul", + "version": "Verzia", + "license": "Licencia" + }, + "survey": { + "nav": "Survey", + "title": "Stirling-PDF Survey", + "description": "Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!", + "changes": "Stirling-PDF has changed since the last survey! To find out more please check our blog post here:", + "changes2": "With these changes we are getting paid business support and funding", + "please": "Please consider taking our survey!", + "disabled": "(Survey popup will be disabled in following updates but available at foot of page)", + "button": "Take Survey", + "dontShowAgain": "Don't show again", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Remove image", + "header": "Remove image", + "removeImage": "Remove image", + "submit": "Remove image" + }, + "splitByChapters": { + "title": "Split PDF by Chapters", + "header": "Split PDF by Chapters", + "bookmarkLevel": "Bookmark Level", + "includeMetadata": "Include Metadata", + "allowDuplicates": "Allow Duplicates", + "desc": { + "1": "This tool splits a PDF file into multiple PDFs based on its chapter structure.", + "2": "Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).", + "3": "Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.", + "4": "Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs." + }, + "submit": "Split PDF" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Releases", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Current Release" + }, + "note": "Release notes are only available in English" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/sl-SI/translation.json b/frontend/public/locales/sl-SI/translation.json new file mode 100644 index 000000000..68f9e3eb5 --- /dev/null +++ b/frontend/public/locales/sl-SI/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Velikost pisave", + "fontName": "Ime pisave", + "title": "Dodaj Å”tevilke strani", + "header": "Dodaj Å”tevilke strani", + "selectText": { + "1": "Izberite datoteko PDF:", + "2": "Velikost roba", + "3": "Položaj", + "4": "Začetna Å”tevilka", + "5": "Strani v Å”tevilko", + "6": "Besedilo po meri" + }, + "customTextDesc": "Besedilo po meri", + "numberPagesDesc": "Katere strani oÅ”tevilčiti, privzeto 'vse', sprejema tudi 1-5 ali 2,5,9 itd.", + "customNumberDesc": "Privzeto na {n}, sprejema tudi 'Stran {n} od {total}', 'Besedilo-{n}', '{filename}-{n}", + "submit": "Dodaj Å”tevilke strani" + }, + "pdfPrompt": "Izberi PDF(e)", + "multiPdfPrompt": "Izberi PDF (2+)", + "multiPdfDropPrompt": "Izberite (ali povlecite in spustite) vse datoteke PDF, ki jih potrebujete", + "imgPrompt": "Izberite sliko(e)", + "genericSubmit": "PoÅ”lji", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Opozorilo: ta postopek lahko traja do minute, odvisno od velikosti datoteke", + "pageOrderPrompt": "Vrstni red strani po meri (Vnesite z vejicami ločen seznam Å”tevilk strani ali funkcij, kot je 2n+1) :", + "pageSelectionPrompt": "Izbira strani po meri (Vnesite z vejicami ločen seznam Å”tevilk strani 1,5,6 ali funkcije, kot je 2n+1) :", + "goToPage": "Pojdi", + "true": "Res", + "false": "Napačno", + "unknown": "Neznano", + "save": "Shrani", + "saveToBrowser": "Shrani v brskalnik", + "close": "Zapri", + "filesSelected": "izbrane datoteke", + "noFavourites": "Ni dodanih priljubljenih", + "downloadComplete": "Prenos končan", + "bored": "dolgočaseno čakanje?", + "alphabet": "Abeceda", + "downloadPdf": "Prenesi PDF", + "text": "Besedilo", + "font": "Pisava", + "selectFillter": "-- Izberite --", + "pageNum": "Å tevilka strani", + "sizes": { + "small": "Majhen", + "medium": "Srednje", + "large": "Veliko", + "x-large": "X-Velik" + }, + "error": { + "pdfPassword": "Dokument PDF je zaŔčiten z geslom in geslo ni bilo vneseno ali pa je bilo napačno", + "_value": "Napaka", + "sorry": "Oprostite za težavo!", + "needHelp": "Potrebujete pomoč / Ste naÅ”li težavo?", + "contactTip": "Če imate Å”e vedno težave, ne oklevajte in se obrnite na nas za pomoč. Vstopnico lahko oddate na naÅ”i strani GitHub ali nas kontaktirate prek Discorda:", + "404": { + "head": "404 - Stran ni najdena | Ups, spotaknili smo se pri kodi!", + "1": "Zdi se, da ne moremo najti strani, ki jo iŔčete.", + "2": "Nekaj ​​je Å”lo narobe" + }, + "github": "Oddajte vstopnico na GitHub", + "showStack": "Prikaži sled sklada", + "copyStack": "Kopiraj sled sklada", + "githubSubmit": "GitHub - Predloži vstopnico", + "discordSubmit": "Discord - PoÅ”lji objavo podpori" + }, + "delete": "IzbriÅ”i", + "username": "UporabniÅ”ko ime", + "password": "Geslo", + "welcome": "DobrodoÅ”li", + "property": "Lastnost", + "black": "črna", + "white": "bela", + "red": "rdeča", + "green": "zelena", + "blue": "modra", + "custom": "Po meri...", + "WorkInProgess": "Delo je v teku, morda ne bo delovalo ali bo hroŔčalo, prosimo, prijavite morebitne težave!", + "poweredBy": "Poganja", + "yes": "Da", + "no": "Ne", + "changedCredsMessage": "Poverilnice spremenjene!", + "notAuthenticatedMessage": "Uporabnik ni preverjen.", + "userNotFoundMessage": "Uporabnika ni mogoče najti.", + "incorrectPasswordMessage": "Trenutno geslo ni pravilno.", + "usernameExistsMessage": "Novo uporabniÅ”ko ime že obstaja.", + "invalidUsernameMessage": "Neveljavno uporabniÅ”ko ime, uporabniÅ”ko ime lahko vsebuje samo črke, Å”tevilke in naslednje posebne znake @._+- ali mora biti veljaven e-poÅ”tni naslov.", + "invalidPasswordMessage": "Geslo ne sme biti prazno in ne sme imeti presledkov na začetku ali koncu.", + "confirmPasswordErrorMessage": "Novo geslo in Potrditev novega gesla se morata ujemati.", + "deleteCurrentUserMessage": "Trenutno prijavljenega uporabnika ni mogoče izbrisati.", + "deleteUsernameExistsMessage": "UporabniÅ”ko ime ne obstaja in ga ni mogoče izbrisati.", + "downgradeCurrentUserMessage": "Vloge trenutnega uporabnika ni mogoče znižati", + "disabledCurrentUserMessage": "Trenutnega uporabnika ni mogoče onemogočiti", + "downgradeCurrentUserLongMessage": "Vloge trenutnega uporabnika ni mogoče znižati. Zato trenutni uporabnik ne bo prikazan.", + "userAlreadyExistsOAuthMessage": "Uporabnik že obstaja kot uporabnik OAuth2.", + "userAlreadyExistsWebMessage": "Uporabnik že obstaja kot spletni uporabnik.", + "oops": "Ojoj!", + "help": "Pomoč", + "goHomepage": "Pojdi na domačo stran", + "joinDiscord": "Pridružite se naÅ”emu strežniku Discord", + "seeDockerHub": "Glej Docker Hub", + "visitGithub": "ObiŔčite skladiŔče Github", + "donate": "Doniraj", + "color": "Barva", + "sponsor": "Sponzor", + "info": "Podatki", + "pro": "Pro", + "page": "Stran", + "pages": "Strani", + "loading": "Nalaganje...", + "addToDoc": "Dodaj v dokument", + "reset": "Ponastavi", + "apply": "Uporabi", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Politika zasebnosti", + "terms": "Določila in pogoji", + "accessibility": "Dostopnost", + "cookie": "Pravilnik o piÅ”kotkih", + "impressum": "Impresum", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Meni cevovoda (beta)", + "uploadButton": "Naloži po meri", + "configureButton": "Konfiguriraj", + "defaultOption": "Po meri", + "submitButton": "PoÅ”lji", + "help": "Pomoč za cevovod", + "scanHelp": "Pomoč za skeniranje map", + "deletePrompt": "Ali ste prepričani, da želite izbrisati cevovod", + "tags": "avtomatiziraj,zaporedje,skriptiran,serijski proces", + "title": "Cevovod" + }, + "pipelineOptions": { + "header": "Konfiguracija cevovoda", + "pipelineNameLabel": "Ime cevovoda", + "saveSettings": "Shrani nastavitve delovanja", + "pipelineNamePrompt": "Sem vnesite ime cevovoda", + "selectOperation": "Izberi operacijo", + "addOperationButton": "Dodaj operacijo", + "pipelineHeader": "Cevovod:", + "saveButton": "Prenos", + "validateButton": "Potrdi" + }, + "enterpriseEdition": { + "button": "Nadgradi na Pro", + "warning": "Ta funkcija je na voljo samo uporabnikom Pro.", + "yamlAdvert": "Stirling PDF Pro podpira konfiguracijske datoteke YAML in druge funkcije SSO.", + "ssoAdvert": "IŔčete več funkcij za upravljanje uporabnikov? Oglejte si Stirling PDF Pro" + }, + "analytics": { + "title": "Ali želite izboljÅ”ati Stirling PDF?", + "paragraph1": "Stirling PDF se je odločil za analitiko, ki nam pomaga izboljÅ”ati izdelek. Ne sledimo nobenim osebnim podatkom ali vsebini datotek.", + "paragraph2": "Prosimo, razmislite o omogočanju analitike, ki bo pomagala rasti Stirling-PDF in nam bo omogočila boljÅ”e razumevanje naÅ”ih uporabnikov.", + "enable": "Omogoči analitiko", + "disable": "Onemogoči analitiko", + "settings": "Nastavitve za analitiko lahko spremenite v datoteki config/settings.yml" + }, + "navbar": { + "favorite": "Priljubljene", + "recent": "New and recently updated", + "darkmode": "Temni način", + "language": "Jeziki", + "settings": "Nastavitve", + "allTools": "Orodja", + "multiTool": "Več orodje", + "search": "IŔči", + "sections": { + "organize": "Organiziraj", + "convertTo": "Pretvori v PDF", + "convertFrom": "Pretvori iz PDF", + "security": "Podpis in varnost", + "advance": "Napredno", + "edit": "Ogled in urejanje", + "popular": "Priljubljeno" + } + }, + "settings": { + "title": "Nastavitve", + "update": "Na voljo je posodobitev", + "updateAvailable": "{0} je trenutno nameŔčena različica. Na voljo je nova različica ({1}).", + "appVersion": "Različica aplikacije:", + "downloadOption": { + "title": "Izberi možnost prenosa (za prenose ene datoteke brez zip):", + "1": "Odpri v istem oknu", + "2": "Odpri v novem oknu", + "3": "Prenesi datoteko" + }, + "zipThreshold": "Zip datoteke, ko preseže Å”tevilo prenesenih datotek", + "signOut": "Odjava", + "accountSettings": "Nastavitve računa", + "bored": { + "help": "Omogoči igro velikonočnih jajc" + }, + "cacheInputs": { + "name": "Shrani vnose obrazca", + "help": "Omogoči shranjevanje predhodno uporabljenih vnosov za prihodnje zagone" + } + }, + "changeCreds": { + "title": "Spremeni poverilnice", + "header": "Posodobite podrobnosti svojega računa", + "changePassword": "Uporabljate privzete poverilnice za prijavo. Prosim vnesite novo geslo", + "newUsername": "Novo uporabniÅ”ko ime", + "oldPassword": "Trenutno geslo", + "newPassword": "Novo geslo", + "confirmNewPassword": "Potrdi novo geslo", + "submit": "PoÅ”lji spremembe" + }, + "account": { + "title": "Nastavitve računa", + "accountSettings": "Nastavitve računa", + "adminSettings": "SkrbniÅ”ke nastavitve - ogled in dodajanje uporabnikov", + "userControlSettings": "Nastavitve uporabniÅ”kega nadzora", + "changeUsername": "Spremeni uporabniÅ”ko ime", + "newUsername": "Novo uporabniÅ”ko ime", + "password": "Geslo za potrditev", + "oldPassword": "Staro geslo", + "newPassword": "Novo geslo", + "changePassword": "Spremeni geslo", + "confirmNewPassword": "Potrdi novo geslo", + "signOut": "Odjava", + "yourApiKey": "VaÅ” API ključ", + "syncTitle": "Sinhroniziraj nastavitve brskalnika z računom", + "settingsCompare": "Primerjava nastavitev:", + "property": "Lastnina", + "webBrowserSettings": "Nastavitev spletnega brskalnika", + "syncToBrowser": "Sinhroniziraj račun -> Brskalnik", + "syncToAccount": "Sinhroniziraj račun <- Brskalnik" + }, + "adminUserSettings": { + "title": "Nastavitve uporabniÅ”kega nadzora", + "header": "Nastavitve skrbniÅ”kega nadzora uporabnika", + "admin": "Skrbnik", + "user": "Uporabnik", + "addUser": "Dodaj novega uporabnika", + "deleteUser": "IzbriÅ”i uporabnika", + "confirmDeleteUser": "Ali je treba uporabnika izbrisati?", + "confirmChangeUserStatus": "Ali naj bo uporabnik onemogočen/omogočen?", + "usernameInfo": "UporabniÅ”ko ime lahko vsebuje samo črke, Å”tevilke in naslednje posebne znake @._+- ali mora biti veljaven e-poÅ”tni naslov.", + "roles": "Vloge", + "role": "Vloga", + "actions": "Dejanja", + "apiUser": "Omejen uporabnik API-ja", + "extraApiUser": "Dodatni omejeni uporabnik API-ja", + "webOnlyUser": "Samo spletni uporabnik", + "demoUser": "Demo uporabnik (brez nastavitev po meri)", + "internalApiUser": "Notranji uporabnik API-ja", + "forceChange": "Prisili uporabnika, da spremeni geslo ob prijavi", + "submit": "Shrani uporabnika", + "changeUserRole": "Spremeni uporabniÅ”ko vlogo", + "authenticated": "Preverjeno", + "editOwnProfil": "Uredi svoj profil", + "enabledUser": "omogočen uporabnik", + "disabledUser": "onemogočen uporabnik", + "activeUsers": "Aktivni uporabniki:", + "disabledUsers": "Onemogočeni uporabniki:", + "totalUsers": "Skupno Å”tevilo uporabnikov:", + "lastRequest": "Zadnja zahteva", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Statistika končne točke", + "header": "Statistika končne točke", + "top10": "10 najboljÅ”ih", + "top20": "20 najboljÅ”ih", + "all": "Vse", + "refresh": "Osveži", + "includeHomepage": "Vključi domačo stran ('/')", + "includeLoginPage": "Vključi prijavno stran ('/login')", + "totalEndpoints": "Skupno končnih točk", + "totalVisits": "Skupno Å”tevilo obiskov", + "showing": "Prikaz", + "selectedVisits": "Izbrani obiski", + "endpoint": "Končna točka", + "visits": "Obiski", + "percentage": "Odstotek", + "loading": "Nalaganje...", + "failedToLoad": "Nalaganje podatkov končne točke ni uspelo. Poskusite osvežiti.", + "home": "Domača stran", + "login": "Prijava", + "top": "Na vrh", + "numberOfVisits": "Å tevilo obiskov", + "visitsTooltip": "Obiski: {0} ({1}% vseh)", + "retry": "Poskusi znova" + }, + "database": { + "title": "Uvoz/izvoz baze podatkov", + "header": "Uvoz/izvoz baze podatkov", + "fileName": "Ime datoteke", + "creationDate": "Datum ustvarjanja", + "fileSize": "Velikost datoteke", + "deleteBackupFile": "IzbriÅ”i datoteko varnostne kopije", + "importBackupFile": "Uvozi datoteko varnostne kopije", + "createBackupFile": "Ustvari datoteko varnostne kopije", + "downloadBackupFile": "Prenesi varnostno kopijo datoteke", + "info_1": "Pri uvažanju podatkov je ključnega pomena zagotoviti pravilno strukturo. Če niste prepričani, kaj počnete, poiŔčite nasvet in podporo strokovnjaka. Napaka v strukturi lahko povzroči motnje v delovanju aplikacije, vse do popolne nezmožnosti zagona aplikacije.", + "info_2": "Ime datoteke pri nalaganju ni pomembno. Pozneje se bo preimenoval tako, da bo sledil formatu backup_user_yyyyMMddHHmm.sql, kar bo zagotovilo dosledno poimenovanje.", + "submit": "Uvozi varnostno kopijo", + "importIntoDatabaseSuccessed": "Uvoz v bazo podatkov uspel", + "backupCreated": "UspeÅ”no varnostno kopiranje baze podatkov", + "fileNotFound": "Datoteke ni mogoče najti", + "fileNullOrEmpty": "Datoteka ne sme biti ničelna ali prazna", + "failedImportFile": "Uvoz datoteke ni uspel", + "notSupported": "Ta funkcija ni na voljo za vaÅ”o povezavo z bazo podatkov." + }, + "session": { + "expired": "VaÅ”a seja je potekla. Osvežite stran in poskusite znova.", + "refreshPage": "Osveži stran" + }, + "home": { + "desc": "VaÅ”a lokalna trgovina na enem mestu za vse vaÅ”e potrebe po PDF-jih.", + "searchBar": "IŔči funkcije...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Oglejte si, komentirajte, dodajte besedilo ali slike" + }, + "setFavorites": "Nastavi priljubljene", + "hideFavorites": "Skrij priljubljene", + "showFavorites": "Prikaži priljubljene", + "legacyHomepage": "Stara domača stran", + "newHomePage": "Preizkusite naÅ”o novo domačo stran!", + "alphabetical": "Abecedno", + "globalPopularity": "Globalna priljubljenost", + "sortBy": "Razvrsti po:", + "multiTool": { + "title": "PDF Multi Tool", + "desc": "Spoji, zavrti, prerazporedi, razdeli in odstrani strani" + }, + "merge": { + "title": "Združi", + "desc": "Enostavno združite več PDF-jev v enega." + }, + "split": { + "title": "Razdeli se", + "desc": "Razdeli PDF-je v več dokumentov" + }, + "rotate": { + "title": "Zavrti", + "desc": "Preprosto zavrtite svoje PDF-je." + }, + "imageToPdf": { + "title": "Slika v PDF", + "desc": "Pretvori sliko (PNG, JPEG, GIF) v PDF." + }, + "pdfToImage": { + "title": "PDF v sliko", + "desc": "Pretvori PDF v sliko. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Organiziraj", + "desc": "Odstrani/Prerazporedi strani v poljubnem vrstnem redu" + }, + "addImage": { + "title": "Dodaj sliko", + "desc": "Doda sliko na določeno mesto v PDF-ju" + }, + "watermark": { + "title": "Dodaj vodni žig", + "desc": "V dokument PDF dodajte vodni žig po meri." + }, + "permissions": { + "title": "Spremeni dovoljenja", + "desc": "Spremenite dovoljenja vaÅ”ega dokumenta PDF" + }, + "removePages": { + "title": "Odstrani", + "desc": "IzbriÅ”ite neželene strani iz dokumenta PDF." + }, + "addPassword": { + "title": "Dodaj geslo", + "desc": "Å ifrirajte svoj dokument PDF z geslom." + }, + "removePassword": { + "title": "Odstrani geslo", + "desc": "Odstranite zaŔčito z geslom iz vaÅ”ega dokumenta PDF." + }, + "compressPdfs": { + "title": "Stisni", + "desc": "Stisnite PDF-je, da zmanjÅ”ate njihovo velikost." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Spremeni metapodatke", + "desc": "Spremeni/Odstrani/Dodaj metapodatke iz dokumenta PDF" + }, + "fileToPDF": { + "title": "Pretvori datoteko v PDF", + "desc": "Pretvori skoraj vsako datoteko v PDF (DOCX, PNG, XLS, PPT, TXT in več)" + }, + "ocr": { + "title": "OCR / Čistilni pregledi", + "desc": "Cleanup skenira in zazna besedilo iz slik znotraj PDF-ja in ga ponovno doda kot besedilo." + }, + "extractImages": { + "title": "Izvleči slike", + "desc": "Izvleče vse slike iz PDF-ja in jih shrani v zip" + }, + "pdfToPDFA": { + "title": "PDF v PDF/A", + "desc": "Pretvori PDF v PDF/A za dolgoročno shranjevanje" + }, + "PDFToWord": { + "title": "PDF v Word", + "desc": "Pretvori PDF v format Word (DOC, DOCX in ODT)" + }, + "PDFToPresentation": { + "title": "PDF v predstavitev", + "desc": "Pretvori PDF v predstavitvene formate (PPT, PPTX in ODP)" + }, + "PDFToText": { + "title": "PDF v RTF (Besedilo)", + "desc": "Pretvori PDF v format besedila ali RTF" + }, + "PDFToHTML": { + "title": "PDF v HTML", + "desc": "Pretvori PDF v format HTML" + }, + "PDFToXML": { + "title": "PDF v XML", + "desc": "Pretvori PDF v format XML" + }, + "ScannerImageSplit": { + "title": "Zaznaj/razdeli skenirane fotografije", + "desc": "Razdeli več fotografij iz fotografije/PDF" + }, + "sign": { + "title": "PodpiÅ”i", + "desc": "Doda podpis v PDF z risbo, besedilom ali sliko" + }, + "flatten": { + "title": "Zravnaj", + "desc": "Odstrani vse interaktivne elemente in obrazce iz PDF-ja" + }, + "repair": { + "title": "Popravilo", + "desc": "PoskuÅ”a popraviti poÅ”kodovan/pokvarjen PDF" + }, + "removeBlanks": { + "title": "Odstrani prazne strani", + "desc": "Zazna in odstrani prazne strani iz dokumenta" + }, + "removeAnnotations": { + "title": "Odstrani opombe", + "desc": "Odstrani vse komentarje/opombe iz PDF-ja" + }, + "compare": { + "title": "Primerjaj", + "desc": "Primerja in prikazuje razlike med 2 dokumentoma PDF" + }, + "certSign": { + "title": "PodpiÅ”i s potrdilom", + "desc": "PodpiÅ”e PDF s potrdilom/ključem (PEM/P12)" + }, + "removeCertSign": { + "title": "Odstrani znak potrdila", + "desc": "Odstrani podpis potrdila iz PDF-ja" + }, + "pageLayout": { + "title": "Večstranska postavitev", + "desc": "Združi več strani dokumenta PDF v eno stran" + }, + "scalePages": { + "title": "Prilagodi velikost/merilo strani", + "desc": "Spremenite velikost/merilo strani in/ali njeno vsebino." + }, + "pipeline": { + "title": "Cevovod", + "desc": "Zaženi več dejanj na PDF-jih z definiranjem cevovodnih skriptov" + }, + "add-page-numbers": { + "title": "Dodaj Å”tevilke strani", + "desc": "Dodaj Å”tevilke strani skozi dokument na določeno mesto" + }, + "auto-rename": { + "title": "Samodejno preimenuj datoteko PDF", + "desc": "Samodejno preimenuje datoteko PDF glede na zaznano glavo" + }, + "adjust-contrast": { + "title": "Prilagodi barve/kontrast", + "desc": "Prilagodi kontrast, nasičenost in svetlost PDF-ja" + }, + "crop": { + "title": "Obreži PDF", + "desc": "Obrežite PDF, da zmanjÅ”ate njegovo velikost (ohranja besedilo!)" + }, + "autoSplitPDF": { + "title": "Samodejno razdeli strani", + "desc": "Samodejno razdeli optično prebrane PDF-je s fizično QR kodo razdelilnika optično prebranih strani" + }, + "sanitizePdf": { + "title": "Razkuži", + "desc": "Odstrani skripte in druge elemente iz datotek PDF" + }, + "URLToPDF": { + "title": "URL/spletna stran v PDF", + "desc": "Pretvori poljuben http(-e)URL v PDF" + }, + "HTMLToPDF": { + "title": "HTML v PDF", + "desc": "Pretvori katero koli datoteko HTML ali zip v PDF" + }, + "MarkdownToPDF": { + "title": "Markdown v PDF", + "desc": "Pretvori katero koli datoteko Markdown v PDF" + }, + "PDFToMarkdown": { + "title": "PDF v Markdown", + "desc": "Pretvori poljuben PDF v Markdown" + }, + "getPdfInfo": { + "title": "Pridobite VSE informacije o PDF-ju", + "desc": "Zgrabi vse možne informacije o PDF-jih" + }, + "extractPage": { + "title": "Izvleček strani(e)", + "desc": "Izvleče izbrane strani iz PDF-ja" + }, + "PdfToSinglePage": { + "title": "PDF na eno veliko stran", + "desc": "Združi vse strani PDF v eno samo veliko stran" + }, + "showJS": { + "title": "Prikaži Javascript", + "desc": "IŔče in prikaže vse JS, vstavljene v PDF" + }, + "autoRedact": { + "title": "Samodejno popravi", + "desc": "Samodejno popravi (začrni) besedilo v PDF-ju na podlagi vnesenega besedila" + }, + "redact": { + "title": "Ročna redakcija", + "desc": "Preredi PDF na podlagi izbranega besedila, narisanih oblik in/ali izbranih strani(-e)" + }, + "tableExtraxt": { + "title": "PDF v CSV", + "desc": "Izvleče tabele iz PDF in jih pretvori v CSV" + }, + "autoSizeSplitPDF": { + "title": "Samodejna razdelitev po velikosti/Å”tevilu", + "desc": "Razdeli en PDF na več dokumentov glede na velikost, Å”tevilo strani ali Å”tevilo dokumentov" + }, + "overlay-pdfs": { + "title": "Prekrivanje PDF-jev", + "desc": "Prekriva PDF-je na vrhu drugega PDF-ja" + }, + "split-by-sections": { + "title": "Razdeli PDF po razdelkih", + "desc": "Vsako stran PDF-ja razdelite na manjÅ”e vodoravne in navpične dele" + }, + "AddStampRequest": { + "title": "Dodaj žig v PDF", + "desc": "Dodaj besedilo ali slikovne žige na nastavljenih lokacijah" + }, + "removeImagePdf": { + "title": "Odstrani sliko", + "desc": "Odstranite sliko iz PDF-ja, da zmanjÅ”ate velikost datoteke" + }, + "splitPdfByChapters": { + "title": "Razdeli PDF po poglavjih", + "desc": "Razdeli PDF na več datotek glede na strukturo poglavij." + }, + "validateSignature": { + "title": "Preveri podpis PDF", + "desc": "Preveri digitalne podpise in potrdila v dokumentih PDF" + }, + "replaceColorPdf": { + "title": "Napredne barvne možnosti", + "desc": "Zamenjaj barvo besedila in ozadja v PDF-ju in obrni celotno barvo PDF-ja, da zmanjÅ”aÅ” velikost datoteke" + } + }, + "viewPdf": { + "tags": "ogled, branje, opomba, besedilo, slika", + "title": "View/Edit PDF", + "header": "Ogled PDF-ja" + }, + "multiTool": { + "tags": "Več orodij, več operacij, uporabniÅ”ki vmesnik, klik povleci, sprednji del, odjemalska stran, interaktivno, nepremagljivo, premakni, izbriÅ”i, preseli, razdeli", + "title": "PDF večnamensko orodje", + "header": "PDF Multi Tool", + "uploadPrompts": "Ime datoteke", + "selectAll": "Izberi vse", + "deselectAll": "Prekliči izbor vseh", + "selectPages": "Izberi stran", + "selectedPages": "Izbrane strani", + "page": "Stran", + "deleteSelected": "IzbriÅ”i izbrano", + "downloadAll": "Izvozi", + "downloadSelected": "Izvozi izbrano", + "insertPageBreak": "Vstavi prelom strani", + "addFile": "Dodaj datoteko", + "rotateLeft": "Zavrti v levo", + "rotateRight": "Zavrti v desno", + "split": "Razdeli", + "moveLeft": "Premakni levo", + "moveRight": "Premik desno", + "delete": "IzbriÅ”i", + "dragDropMessage": "Izbrane strani", + "undo": "Razveljavi", + "redo": "Ponovi" + }, + "merge": { + "tags": "spoj,operacije strani,zadnja stran,strežniÅ”ka stran", + "title": "Združi", + "header": "Združi več PDF-jev (2+)", + "sortByName": "Razvrsti po imenu", + "sortByDate": "Razvrsti po datumu", + "removeCertSign": "Odstraniti digitalni podpis v združeni datoteki?", + "submit": "Združi" + }, + "split": { + "tags": "Operacije strani,deli,Multi Page,cut,strežniÅ”ka stran", + "title": "Razdeli PDF", + "header": "Razdeli PDF", + "desc": { + "1": "Å tevilke, ki jih izberete, so Å”tevilke strani, na kateri želite narediti razdelitev", + "2": "Tako bi izbira 1,3,7-9 razdelila dokument z 10 stranmi v 6 ločenih PDF-jev z:", + "3": "Dokument #1: Stran 1", + "4": "Dokument #2: Stran 2 in 3", + "5": "Dokument #3: Stran 4, 5, 6 in 7", + "6": "Dokument #4: stran 8", + "7": "Dokument #5: stran 9", + "8": "Dokument #6: stran 10" + }, + "splitPages": "Vnesite strani za razdelitev:", + "submit": "Razdeli" + }, + "rotate": { + "tags": "strežniÅ”ka stran", + "title": "Zasukaj PDF", + "header": "Zasukaj PDF", + "selectAngle": "Izberite kot vrtenja (v večkratnikih 90 stopinj):", + "submit": "Zavrti" + }, + "imageToPdf": { + "tags": "pretvorba,img,jpg,slika,fotografija" + }, + "pdfToImage": { + "tags": "pretvorba,img,jpg,slika,fotografija", + "title": "PDF v sliko", + "header": "PDF v sliko", + "selectText": "Oblika slike", + "singleOrMultiple": "Vrsta rezultata od strani do slike", + "single": "Ena velika slika Prečesavanje vseh strani", + "multi": "Več slik, ena slika na stran", + "colorType": "Vrsta barve", + "color": "Barva", + "grey": "Sivine", + "blackwhite": "Črno-belo (Lahko izgubite podatke!)", + "submit": "Pretvori", + "info": "Python ni nameŔčen. Zahtevano za pretvorbo WebP.", + "placeholder": "(npr. 1,2,8 ali 4,7,12-16 ali 2n-1)" + }, + "pdfOrganiser": { + "tags": "dvostranski,sodi,lihi,razvrsti,premakni", + "title": "Organizator strani", + "header": "Organizator strani PDF", + "submit": "Prerazporedi strani", + "mode": { + "_value": "Način", + "1": "Vrst strani po meri", + "2": "Obraten vrstni red", + "3": "Obojestransko razvrŔčanje", + "4": "Razvrsti knjižice", + "5": "Razvrsti knjižico s stranskim Å”ivom", + "6": "Razdelitev liho-sodo", + "7": "Najprej odstrani", + "8": "Odstrani zadnjega", + "9": "Odstrani prvega in zadnjega", + "10": "Sodo-liho spajanje", + "11": "Duplicate all pages" + }, + "placeholder": "(npr. 1,3,2 ali 4-8,2,10-12 ali 2n-1)" + }, + "addImage": { + "tags": "img,jpg,slika,fotografija", + "title": "Dodaj sliko", + "header": "Dodaj sliko v PDF", + "everyPage": "Vsaka stran?", + "upload": "Dodaj sliko", + "submit": "Dodaj sliko" + }, + "watermark": { + "tags": "Besedilo, ponavljajoče se, oznaka, lastno, avtorske pravice, blagovna znamka, img, jpg, slika, fotografija", + "title": "Dodaj vodni žig", + "header": "Dodaj vodni žig", + "customColor": "Barva besedila po meri", + "selectText": { + "1": "Izberite PDF za dodajanje vodnega žiga v:", + "2": "Besedilo vodnega žiga:", + "3": "Velikost pisave:", + "4": "Vrtenje (0-360):", + "5": "Å irinski presledek (Presledek med vsakim vodnim žigom vodoravno):", + "6": "ViÅ”inski presledek (Presledek med vsakim vodnim žigom navpično):", + "7": "Neprosojnost (0% - 100%):", + "8": "Vrsta vodnega žiga:", + "9": "Slika vodnega žiga:", + "10": "Pretvori PDF v PDF-sliko" + }, + "submit": "Dodaj vodni žig", + "type": { + "1": "Besedilo", + "2": "Slika" + } + }, + "permissions": { + "tags": "branje, pisanje, urejanje, tiskanje", + "title": "Spremeni dovoljenja", + "header": "Spremeni dovoljenja", + "warning": "Opozorilo, da so ta dovoljenja nespremenljiva, priporočamo, da jih nastavite z geslom prek strani za dodajanje gesla", + "selectText": { + "1": "Izberite PDF za spremembo dovoljenj", + "2": "Dovoljenja za nastavitev", + "3": "Prepreči sestavljanje dokumenta", + "4": "Prepreči ekstrakcijo vsebine", + "5": "Prepreči ekstrakcijo za dostopnost", + "6": "Prepreči izpolnjevanje obrazca", + "7": "Prepreči spreminjanje", + "8": "Prepreči spreminjanje pripisov", + "9": "Prepreči tiskanje", + "10": "Prepreči tiskanje različnih formatov" + }, + "submit": "Spremeni" + }, + "removePages": { + "tags": "Odstrani strani, izbriÅ”i strani" + }, + "addPassword": { + "tags": "varno,varnost", + "title": "Dodaj geslo", + "header": "Dodaj geslo (Å ifriraj)", + "selectText": { + "1": "Izberite PDF za Å”ifriranje", + "2": "UporabniÅ”ko geslo", + "3": "Dolžina Å”ifrirnega ključa", + "4": "ViÅ”je vrednosti so močnejÅ”e, nižje vrednosti pa imajo boljÅ”o združljivost.", + "5": "Dovoljenja za nastavitev (priporočeno za uporabo skupaj z geslom lastnika)", + "6": "Prepreči sestavljanje dokumenta", + "7": "Prepreči ekstrakcijo vsebine", + "8": "Prepreči ekstrakcijo za dostopnost", + "9": "Prepreči izpolnjevanje obrazca", + "10": "Prepreči spreminjanje", + "11": "Prepreči spreminjanje pripisov", + "12": "Prepreči tiskanje", + "13": "Prepreči tiskanje različnih formatov", + "14": "LastniÅ”ko geslo", + "15": "Omejuje, kaj je mogoče storiti z dokumentom, ko je odprt (ni podprt za vse bralnike)", + "16": "Omeji odpiranje samega dokumenta" + }, + "submit": "Å ifriraj" + }, + "removePassword": { + "tags": "varno,deÅ”ifriranje,varnost,odstranitev gesla,brisanje gesla", + "title": "Odstrani geslo", + "header": "Odstrani geslo (deÅ”ifriraj)", + "selectText": { + "1": "Izberite PDF za deÅ”ifriranje", + "2": "Geslo" + }, + "submit": "Odstrani" + }, + "compressPdfs": { + "tags": "squish,small,tiny" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Naslov,avtor,datum,kreacija,čas,založnik,producent,statistika", + "title": "Spremeni metapodatke", + "header": "Spremeni metapodatke", + "selectText": { + "1": "Prosimo, uredite spremenljivke, ki jih želite spremeniti", + "2": "IzbriÅ”i vse metapodatke", + "3": "Prikaži metapodatke po meri:", + "4": "Drugi metapodatki:", + "5": "Dodaj vnos metapodatkov po meri" + }, + "author": "Avtor:", + "creationDate": "Datum ustvarjanja (llll/MM/dd HH:mm:ss):", + "creator": "Ustvarjalec:", + "keywords": "Ključne besede:", + "modDate": "Datum spremembe (llll/MM/dd HH:mm:ss):", + "producer": "Proizvajalec:", + "subject": "Zadeva:", + "trapped": "Ujet:", + "submit": "Spremeni" + }, + "fileToPDF": { + "tags": "transformacija,format,dokument,slika,diapozitiv,besedilo,konverzija,office,docs,word,excel,powerpoint", + "title": "Datoteka v PDF", + "header": "Pretvori katero koli datoteko v PDF", + "credit": "Ta storitev uporablja LibreOffice in Unoconv za pretvorbo datotek.", + "supportedFileTypesInfo": "Podprte vrste datotek", + "supportedFileTypes": "Podprte vrste datotek bi morale vsebovati spodaj, vendar za popoln posodobljen seznam podprtih formatov glejte dokumentacijo LibreOffice", + "submit": "Pretvori v PDF" + }, + "ocr": { + "tags": "prepoznavanje,besedilo,slika,skeniranje,branje,prepoznavanje,zaznavanje,urejanje", + "title": "OCR / ČiŔčenje skeniranja", + "header": "Čistilni pregledi / OCR (optično prepoznavanje znakov)", + "selectText": { + "1": "Izberite jezike, ki jih želite zaznati v PDF-ju (navedeni so tisti, ki so trenutno zaznani):", + "2": "Izdelajte besedilno datoteko, ki vsebuje OCR besedilo poleg OCR-jevega PDF-ja", + "3": "Pravilne strani so bile optično prebrane pod poÅ”evnim kotom z obračanjem nazaj na svoje mesto", + "4": "Čista stran, zato je manj verjetno, da bo OCR naÅ”el besedilo v hrupu v ozadju. (Brez spremembe izhoda)", + "5": "Čista stran, tako da je manj verjetno, da bo OCR naÅ”el besedilo v hrupu v ozadju, vzdržuje čiŔčenje v izhodu.", + "6": "Prezre strani, ki imajo interaktivno besedilo, samo OCR strani, ki so slike", + "7": "Vsili OCR, bo OCR Vsaka stran bo odstranila vse originalne besedilne elemente", + "8": "Normalno (Bo napaka, če PDF vsebuje besedilo)", + "9": "Dodatne nastavitve", + "10": "Način OCR", + "11": "Odstrani slike po OCR (Odstrani VSE slike, uporabno le, če je del koraka pretvorbe)", + "12": "Vrsta upodabljanja (napredno)" + }, + "help": "Prosimo, preberite to dokumentacijo o uporabi tega za druge jezike in/ali uporabi ne v dockerju", + "credit": "Ta storitev uporablja qpdf in Tesseract za OCR.", + "submit": "Obdelaj PDF z OCR" + }, + "extractImages": { + "tags": "slika,fotografija,shrani,arhiv,zip,zajemi,zgrabi", + "title": "Izvleci slike", + "header": "Izvleci slike", + "selectText": "Izberite format slike za pretvorbo ekstrahiranih slik", + "allowDuplicates": "Shrani podvojene slike", + "submit": "Izvleček" + }, + "pdfToPDFA": { + "tags": "archive,long-term,standard,conversion,storage,preservation", + "title": "PDF v PDF/A", + "header": "PDF v PDF/A", + "credit": "Ta storitev uporablja libreoffice za pretvorbo PDF/A", + "submit": "Pretvori", + "tip": "Trenutno ne deluje za več vnosov hkrati", + "outputFormat": "Izhodna oblika", + "pdfWithDigitalSignature": "PDF vsebuje digitalni podpis. To bo odstranjeno v naslednjem koraku." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformacija,format,pretvorba,office,microsoft,docfile", + "title": "PDF v Word", + "header": "PDF v Word", + "selectText": { + "1": "Oblika izhodne datoteke" + }, + "credit": "Ta storitev uporablja LibreOffice za pretvorbo datotek.", + "submit": "Pretvori" + }, + "PDFToPresentation": { + "tags": "slides,show,office,microsoft", + "title": "PDF v predstavitev", + "header": "PDF v predstavitev", + "selectText": { + "1": "Oblika izhodne datoteke" + }, + "credit": "Ta storitev uporablja LibreOffice za pretvorbo datotek.", + "submit": "Pretvori" + }, + "PDFToText": { + "tags": "richformat,richtextformat,obogaten tekst", + "title": "PDF v RTF (Besedilo)", + "header": "PDF v RTF (Besedilo)", + "selectText": { + "1": "Oblika izhodne datoteke" + }, + "credit": "Ta storitev uporablja LibreOffice za pretvorbo datotek.", + "submit": "Pretvori" + }, + "PDFToHTML": { + "tags": "spletna vsebina, brskalniku prijazen", + "title": "PDF v HTML", + "header": "PDF v HTML", + "credit": "Ta storitev uporablja pdftohtml za pretvorbo datotek.", + "submit": "Pretvori" + }, + "PDFToXML": { + "tags": "data-extraction,structured-content,interop,transformation,convert", + "title": "PDF v XML", + "header": "PDF v XML", + "credit": "Ta storitev uporablja LibreOffice za pretvorbo datotek.", + "submit": "Pretvori" + }, + "ScannerImageSplit": { + "tags": "separate,auto-detect,scans,multi-photo,organize", + "selectText": { + "1": "Prag kota:", + "2": "Nastavi najmanjÅ”i absolutni kot, potreben za vrtenje slike (privzeto: 10).", + "3": "Toleranca:", + "4": "Določi razpon barvne variacije okoli ocenjene barve ozadja (privzeto: 30).", + "5": "NajmanjÅ”a povrÅ”ina:", + "6": "Nastavi minimalni prag povrÅ”ine za fotografijo (privzeto: 10000).", + "7": "NajmanjÅ”a konturna povrÅ”ina:", + "8": "Nastavi najmanjÅ”i prag konturne povrÅ”ine za fotografijo", + "9": "Velikost obrobe:", + "10": "Nastavi velikost dodane in odstranjene obrobe, da prepreči bele obrobe v izpisu (privzeto: 1)." + }, + "info": "Python ni nameŔčen. Za tek je potrebno." + }, + "sign": { + "tags": "avtoriziraj,začetnice,narisan-podpis,besedilni-znak,podpis-slike", + "title": "PodpiÅ”i", + "header": "PodpiÅ”i PDF-je", + "upload": "Naloži sliko", + "draw": "NariÅ”i podpis", + "text": "Vnos besedila", + "clear": "Počisti", + "add": "Dodaj", + "saved": "Shranjeni podpisi", + "save": "Shrani podpis", + "personalSigs": "Osebni podpisi", + "sharedSigs": "Skupni podpisi", + "noSavedSigs": "Ni shranjenih podpisov", + "addToAll": "Dodaj na vse strani", + "delete": "IzbriÅ”i", + "first": "Prva stran", + "last": "Zadnja stran", + "next": "Naslednja stran", + "previous": "PrejÅ”nja stran", + "maintainRatio": "Preklopi ohranjanje razmerja stranic", + "undo": "Razveljavi", + "redo": "Ponovi" + }, + "flatten": { + "tags": "static,deactivate,non-interactive,streamline", + "title": "Zravnaj", + "header": "Zravnaj PDF", + "flattenOnlyForms": "SploŔči samo obrazce", + "submit": "Zravnaj" + }, + "repair": { + "tags": "popravi,obnovi,popravi,obnovi", + "title": "Popravilo", + "header": "Popravi datoteke PDF", + "submit": "Popravilo" + }, + "removeBlanks": { + "tags": "cleanup,streamline,non-content,organize", + "title": "Odstrani praznine", + "header": "Odstrani prazne strani", + "threshold": "Prag beline slikovnih pik:", + "thresholdDesc": "Prag za določanje, kako bel mora biti bel piksel, da je označen kot 'bel'. 0 = črna, 255 čisto bela.", + "whitePercent": "Odstotek beline (%):", + "whitePercentDesc": "Odstotek strani, ki mora imeti 'bele' slikovne pike za odstranitev", + "submit": "Odstrani praznine" + }, + "removeAnnotations": { + "tags": "comments,highlight,notes,markup,remove", + "title": "Odstrani opombe", + "header": "Odstrani opombe", + "submit": "Odstrani" + }, + "compare": { + "tags": "diferenciiraj,kontrast,spremembe,analiza", + "title": "Primerjaj", + "header": "Primerjaj PDF-je", + "highlightColor": { + "1": "Označite barvo 1:", + "2": "Barva osvetlitve 2:" + }, + "document": { + "1": "Dokument 1", + "2": "Dokument 2" + }, + "submit": "Primerjaj", + "complex": { + "message": "Eden ali oba predložena dokumenta sta veliki datoteki, točnost primerjave je lahko zmanjÅ”ana" + }, + "large": { + "file": { + "message": "Eden ali oba podana dokumenta sta prevelika za obdelavo" + } + }, + "no": { + "text": { + "message": "Eden ali oba izbrana dokumenta PDF nimata besedilne vsebine. Za primerjavo izberite PDF-je z besedilom." + } + } + }, + "certSign": { + "tags": "avtentikacija,PEM,P12,uradno,Å”ifriranje", + "title": "Podpisovanje potrdila", + "header": "PodpiÅ”ite PDF s svojim potrdilom (Delo v teku)", + "selectPDF": "Izberite datoteko PDF za podpis:", + "jksNote": "Opomba: Če vaÅ”a vrsta potrdila ni navedena spodaj, jo pretvorite v datoteko Java Keystore (.jks) z orodjem ukazne vrstice keytool. Nato spodaj izberite možnost datoteke .jks.", + "selectKey": "Izberite datoteko z zasebnim ključem (format PKCS#8, lahko je .pem ali .der):", + "selectCert": "Izberite svojo datoteko potrdila (format X.509, lahko je .pem ali .der):", + "selectP12": "Izberite datoteko shrambe ključev PKCS#12 (.p12 ali .pfx) (izbirno, če je na voljo, mora vsebovati vaÅ” zasebni ključ in potrdilo):", + "selectJKS": "Izberite datoteko shrambe ključev Java (.jks ali .keystore):", + "certType": "Vrsta potrdila", + "password": "Vnesite geslo shrambe ključev ali zasebnega ključa (če obstaja):", + "showSig": "Prikaži podpis", + "reason": "Razlog", + "location": "Lokacija", + "name": "Ime", + "showLogo": "Prikaži logotip", + "submit": "PodpiÅ”i PDF" + }, + "removeCertSign": { + "tags": "avtentikacija,PEM,P12,uradno,deÅ”ifriranje", + "title": "Odstrani podpis potrdila", + "header": "Odstranite digitalno potrdilo iz PDF-ja", + "selectPDF": "Izberite datoteko PDF:", + "submit": "Odstrani podpis" + }, + "pageLayout": { + "tags": "spoji,sestavi,enojni pogled,organiziraj", + "title": "Postavitev več strani", + "header": "Postavitev več strani", + "pagesPerSheet": "Strani na list:", + "addBorder": "Dodaj obrobe", + "submit": "PoÅ”lji" + }, + "scalePages": { + "tags": "resize,modify,dimension,adapt", + "title": "Prilagodi velikost strani", + "header": "Prilagodi velikost strani", + "pageSize": "Velikost strani dokumenta.", + "keepPageSize": "Izvirna velikost", + "scaleFactor": "Raven povečave (obrezovanje) strani.", + "submit": "PoÅ”lji" + }, + "add-page-numbers": { + "tags": "paginate,label,organize,index" + }, + "auto-rename": { + "tags": "samodejno zaznaj,na podlagi glave,organiziraj,preoznači", + "title": "Samodejno preimenuj", + "header": "Samodejno preimenuj PDF", + "submit": "Samodejno preimenuj" + }, + "adjust-contrast": { + "tags": "color-correction,tune,modify,enhance,colour-correction" + }, + "crop": { + "tags": "obreži, skrči, uredi, oblikuj", + "title": "Obrezovanje", + "header": "Obreži PDF", + "submit": "PoÅ”lji" + }, + "autoSplitPDF": { + "tags": "Na osnovi QR,ločeno,skeniranje-segment,organiziranje", + "title": "Samodejno razdeli PDF", + "header": "Samodejno razdeli PDF", + "description": "Natisnite, vstavite, skenirajte, naložite in nam dovolite, da samodejno ločimo vaÅ”e dokumente. Ročno razvrŔčanje ni potrebno.", + "selectText": { + "1": "Natisnite nekaj razdelilnih listov od spodaj (črno-belo je v redu).", + "2": "Skenirajte vse dokumente hkrati tako, da mednje vstavite razdelilni list.", + "3": "Naložite eno veliko optično prebrano datoteko PDF in pustite, da Stirling PDF uredi ostalo.", + "4": "Ločilne strani so samodejno zaznane in odstranjene, kar zagotavlja čist končni dokument." + }, + "formPrompt": "PoÅ”ljite PDF, ki vsebuje razdelilnike strani Stirling-PDF:", + "duplexMode": "Dupleksni način (skeniranje spredaj in zadaj)", + "dividerDownload2": "Prenesi 'Samodejni razdelilnik (z navodili).pdf'", + "submit": "PoÅ”lji" + }, + "sanitizePdf": { + "tags": "clean,secure,safe,remove-threats" + }, + "URLToPDF": { + "tags": "web-capture,save-page,web-to-doc,archive", + "title": "URL v PDF", + "header": "URL v PDF", + "submit": "Pretvori", + "credit": "Uporablja WeasyPrint" + }, + "HTMLToPDF": { + "tags": "markup,web-content,transformation,convert", + "title": "HTML v PDF", + "header": "HTML v PDF", + "help": "Sprejema datoteke HTML in ZIP, ki vsebujejo html/css/slike itd.", + "submit": "Pretvori", + "credit": "Uporablja WeasyPrint", + "zoom": "Raven povečave za prikaz spletne strani.", + "pageWidth": "Å irina strani v centimetrih. (Privzeto prazno)", + "pageHeight": "ViÅ”ina strani v centimetrih. (Privzeto prazno)", + "marginTop": "Zgornji rob strani v milimetrih. (Privzeto prazno)", + "marginBottom": "Spodnji rob strani v milimetrih. (Privzeto prazno)", + "marginLeft": "Levi rob strani v milimetrih. (Privzeto prazno)", + "marginRight": "Desni rob strani v milimetrih. (Privzeto prazno)", + "printBackground": "Upodobi ozadje spletnih strani.", + "defaultHeader": "Omogoči privzeto glavo (ime in Å”tevilka strani)", + "cssMediaType": "Spremenite vrsto medija CSS strani.", + "none": "Brez", + "print": "Natisni", + "screen": "Zaslon" + }, + "MarkdownToPDF": { + "tags": "markup,web-content,transformation,convert,md", + "title": "Označi v PDF", + "header": "Označi v PDF", + "submit": "Pretvori", + "help": "Delo v teku", + "credit": "Uporablja WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF v Markdown", + "header": "PDF v Markdown", + "submit": "Pretvori" + }, + "getPdfInfo": { + "tags": "informacije,podatki,statistika,statistika", + "title": "Pridobite informacije o PDF-ju", + "header": "Pridobite informacije o PDF-ju", + "submit": "Pridobi informacije", + "downloadJson": "Prenesite JSON" + }, + "extractPage": { + "tags": "izvleček" + }, + "PdfToSinglePage": { + "tags": "ena stran" + }, + "showJS": { + "tags": "JS", + "title": "Prikaži Javascript", + "header": "Prikaži Javascript", + "downloadJS": "Prenesi Javascript", + "submit": "Pokaži" + }, + "autoRedact": { + "tags": "Uredi,Skrij,zatemni,črno,marker,skrito", + "title": "Samodejno redigiraj", + "header": "Samodejno redigiraj", + "colorLabel": "Barva", + "textsToRedactLabel": "Besedilo za redigiranje (ločeno z vrsticami)", + "textsToRedactPlaceholder": "npr. \\nZaupno \\nStrogo zaupno", + "useRegexLabel": "Uporabi regularni izraz", + "wholeWordSearchLabel": "Iskanje po celi besedi", + "customPaddingLabel": "Dodatno oblazinjenje po meri", + "convertPDFToImageLabel": "Pretvori PDF v PDF-sliko (Uporablja se za odstranitev besedila za poljem)", + "submitButton": "PoÅ”lji" + }, + "redact": { + "tags": "Uredi,Skrij,zatemni,črno,marker,skrito,ročno", + "title": "Ročna redakcija", + "header": "Ročna redakcija", + "submit": "Uredi", + "textBasedRedaction": "Redakcija na podlagi besedila", + "pageBasedRedaction": "Redakcija na podlagi strani", + "convertPDFToImageLabel": "Pretvori PDF v PDF-sliko (Uporablja se za odstranjevanje besedila za poljem)", + "pageRedactionNumbers": { + "title": "Strani", + "placeholder": "(npr. 1,2,8 ali 4,7,12-16 ali 2n-1)" + }, + "redactionColor": { + "title": "Barva redakcije" + }, + "export": "Izvozi", + "upload": "Naloži", + "boxRedaction": "Redakcija narisane Å”katle", + "zoom": "Povečaj", + "zoomIn": "Povečaj", + "zoomOut": "PomanjÅ”aj", + "nextPage": "Naslednja stran", + "previousPage": "PrejÅ”nja stran", + "toggleSidebar": "Preklopi stransko vrstico", + "showThumbnails": "Prikaži sličice", + "showDocumentOutline": "Pokaži oris dokumenta (dvokliknite, da razÅ”irite/strnete vse elemente)", + "showAttatchments": "Prikaži priloge", + "showLayers": "Prikaži plasti (dvokliknite za ponastavitev vseh plasti na privzeto stanje)", + "colourPicker": "Izbirnik barv", + "findCurrentOutlineItem": "PoiŔči trenutno postavko orisa", + "applyChanges": "Uporabi spremembe" + }, + "tableExtraxt": { + "tags": "CSV, ekstrakcija tabele, ekstrah, pretvorba" + }, + "autoSizeSplitPDF": { + "tags": "pdf,razdelitev,dokument,organizacija" + }, + "overlay-pdfs": { + "tags": "Prekrivanje", + "header": "Prekrivne datoteke PDF", + "baseFile": { + "label": "Izberite osnovno datoteko PDF" + }, + "overlayFiles": { + "label": "Izberite Prekrivne datoteke PDF" + }, + "mode": { + "label": "Izberi način prekrivanja", + "sequential": "Zaporedno prekrivanje", + "interleaved": "Prepleteno prekrivanje", + "fixedRepeat": "Popravljeno prekrivanje ponavljanja" + }, + "counts": { + "label": "Å tevilo prekrivanj (za fiksni način ponavljanja)", + "placeholder": "Vnesite Å”tevilo, ločeno z vejico (npr. 2,3,1)" + }, + "position": { + "label": "Izberi položaj prekrivanja", + "foreground": "Ospredje", + "background": "Ozadje" + }, + "submit": "PoÅ”lji" + }, + "split-by-sections": { + "tags": "Oddelek Razdeli, razdeli, prilagodi, prilagodi", + "title": "Razdeli PDF po razdelkih", + "header": "Razdeli PDF na razdelke", + "horizontal": { + "label": "Vodoravna delitev", + "placeholder": "Vnesite Å”tevilo vodoravnih delitev" + }, + "vertical": { + "label": "Navpične delitve", + "placeholder": "Vnesite Å”tevilo navpičnih delitev" + }, + "submit": "Razdeli PDF", + "merge": "Združi v en PDF" + }, + "AddStampRequest": { + "tags": "Žig, Dodaj sliko, sredinska slika, Vodni žig, PDF, Vdelaj, Prilagodi, Prilagodi", + "header": "Ožigosajte PDF", + "title": "Ožigosajte PDF", + "stampType": "Vrsta žiga", + "stampText": "Označi besedilo", + "stampImage": "Označi sliko", + "alphabet": "Abeceda", + "fontSize": "Velikost pisave/slike", + "rotation": "Rotacija", + "opacity": "Neprosojnost", + "position": "Položaj", + "overrideX": "Preglasi X koordinato", + "overrideY": "Preglasi Y koordinato", + "customMargin": "Margina po meri", + "customColor": "Barva besedila po meri", + "submit": "PoÅ”lji" + }, + "removeImagePdf": { + "tags": "Odstrani sliko,operacije strani,zadnja stran,strežniÅ”ka stran" + }, + "splitPdfByChapters": { + "tags": "razdeli,poglavja,zaznamki,organiziraj" + }, + "validateSignature": { + "tags": "podpis,preveri,validiraj,pdf,certificate,digitalni podpis,Preveri podpis,Preveri certifikat", + "title": "Preveri podpise PDF", + "header": "Preveri digitalne podpise", + "selectPDF": "Izberite podpisano datoteko PDF", + "submit": "Preveri podpise", + "results": "Rezultati preverjanja", + "status": { + "_value": "Stanje", + "valid": "Veljaven", + "invalid": "Neveljavno" + }, + "signer": "Podpisnik", + "date": "Datum", + "reason": "Razlog", + "location": "Lokacija", + "noSignatures": "V tem dokumentu ni bilo najdenih digitalnih podpisov", + "chain": { + "invalid": "Preverjanje verige potrdil ni uspelo - ni mogoče preveriti identitete podpisnika" + }, + "trust": { + "invalid": "Certifikat ni v zaupanja vrednem skladiŔču - vira ni mogoče preveriti" + }, + "cert": { + "expired": "Potrdilo je poteklo", + "revoked": "Potrdilo je bilo preklicano", + "info": "Podrobnosti potrdila", + "issuer": "Izdajatelj", + "subject": "Zadeva", + "serialNumber": "Serijska Å”tevilka", + "validFrom": "Veljavno od", + "validUntil": "Velja do", + "algorithm": "Algoritem", + "keySize": "Velikost ključa", + "version": "Različica", + "keyUsage": "Uporaba ključa", + "selfSigned": "Samopodpisano", + "bits": "bits" + }, + "signature": { + "info": "Informacije o podpisu", + "_value": "Podpis", + "mathValid": "Podpis je matematično veljaven AMPAK:" + }, + "selectCustomCert": "Datoteka potrdila po meri X.509 (izbirno)" + }, + "replace-color": { + "title": "Napredne barvne možnosti", + "header": "Zamenjaj-Obrni barvni PDF", + "selectText": { + "1": "Zamenjaj ali obrni barvne možnosti", + "2": "Privzeto (privzete barve z visokim kontrastom)", + "3": "Po meri (barve po meri)", + "4": "Full-Invert(Invert vse barve)", + "5": "Možnosti barv z visokim kontrastom", + "6": "belo besedilo na črnem ozadju", + "7": "Črno besedilo na belem ozadju", + "8": "Rumeno besedilo na črnem ozadju", + "9": "Zeleno besedilo na črnem ozadju", + "10": "Izberi barvo besedila", + "11": "Izberi barvo ozadja" + }, + "submit": "Zamenjaj" + }, + "replaceColorPdf": { + "tags": "Zamenjaj barvo,operacije strani,zadnja stran,strežniÅ”ka stran" + }, + "login": { + "title": "Prijava", + "header": "Prijava", + "signin": "Prijava", + "rememberme": "Zapomni si me", + "invalid": "Neveljavno uporabniÅ”ko ime ali geslo.", + "locked": "VaÅ” račun je bil zaklenjen.", + "signinTitle": "Prosim prijavite se", + "ssoSignIn": "Prijava prek enotne prijave", + "oAuth2AutoCreateDisabled": "OAUTH2 Samodejno ustvarjanje uporabnika onemogočeno", + "oAuth2AdminBlockedUser": "Registracija ali prijava neregistriranih uporabnikov je trenutno blokirana. Prosimo kontaktirajte skrbnika.", + "oauth2RequestNotFound": "Zahteva za avtorizacijo ni bila najdena", + "oauth2InvalidUserInfoResponse": "Neveljaven odgovor z informacijami o uporabniku", + "oauth2invalidRequest": "Neveljavna zahteva", + "oauth2AccessDenied": "Dostop zavrnjen", + "oauth2InvalidTokenResponse": "Neveljaven odgovor žetona", + "oauth2InvalidIdToken": "Neveljaven žeton ID-ja", + "relyingPartyRegistrationNotFound": "Ni najdene registracije odvisne stranke", + "userIsDisabled": "Uporabnik je deaktiviran, prijava s tem uporabniÅ”kim imenom je trenutno blokirana. Prosimo kontaktirajte skrbnika.", + "alreadyLoggedIn": "Prijavljeni ste že v", + "alreadyLoggedIn2": "naprave. Odjavite se iz naprav in poskusite znova.", + "toManySessions": "Imate preveč aktivnih sej", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF na eno stran", + "header": "PDF na eno stran", + "submit": "Pretvori v eno stran" + }, + "pageExtracter": { + "title": "Izvleči strani", + "header": "Izvleči strani", + "submit": "Izvleček", + "placeholder": "(npr. 1,2,8 ali 4,7,12-16 ali 2n-1)" + }, + "sanitizePDF": { + "title": "Prečisti PDF", + "header": "Prečisti datoteko PDF", + "selectText": { + "1": "Odstrani dejanja JavaScript", + "2": "Odstrani vdelane datoteke", + "3": "Remove XMP metadata", + "4": "Odstrani povezave", + "5": "Odstrani pisave", + "6": "Remove Document Info Metadata" + }, + "submit": "Prečisti PDF" + }, + "adjustContrast": { + "title": "Prilagodi kontrast", + "header": "Prilagodi kontrast", + "contrast": "Kontrast:", + "brightness": "Svetlost:", + "saturation": "Nasičenost:", + "download": "Prenos" + }, + "compress": { + "title": "Stisnite", + "header": "Stisnite PDF", + "credit": "Ta storitev uporablja qpdf za stiskanje/optimizacijo PDF.", + "grayscale": { + "label": "Uporabi sivinsko lestvico za stiskanje" + }, + "selectText": { + "1": { + "_value": "Nastavitve stiskanja", + "1": "1-3 stiskanje PDF,
4-6 enostavno stiskanje slik,
7-9 intenzivno stiskanje slik Bo dramatično zmanjÅ”alo kakovost slike" + }, + "2": "Raven optimizacije:", + "4": "Samodejni način - Samodejno prilagodi kakovost, da dobi PDF na natančno velikost", + "5": "Pričakovana velikost PDF (npr. 25 MB, 10,8 MB, 25 KB)" + }, + "submit": "Stisnite" + }, + "decrypt": { + "passwordPrompt": "Ta datoteka je zaŔčitena z geslom. Prosim vnesite geslo:", + "cancelled": "Operacija preklicana za PDF: {0}", + "noPassword": "Geslo ni na voljo za Å”ifriran PDF: {0}", + "invalidPassword": "Prosimo poskusite znova s ​​pravilnim geslom.", + "invalidPasswordHeader": "Nepravilno geslo ali nepodprto Å”ifriranje za PDF: {0}", + "unexpectedError": "Pri obdelavi datoteke je priÅ”lo do napake. prosim poskusite ponovno", + "serverError": "Napaka strežnika med deÅ”ifriranjem: {0}", + "success": "Datoteka uspeÅ”no deÅ”ifrirana." + }, + "multiTool-advert": { + "message": "Ta funkcija je na voljo tudi na naÅ”i strani z več orodji. Oglejte si izboljÅ”an uporabniÅ”ki vmesnik od strani do strani in dodatne funkcije!" + }, + "pageRemover": { + "title": "Odstranjevalec strani", + "header": "Odstranjevalnik strani PDF", + "pagesToDelete": "Strani za brisanje (Vnesite z vejicami ločen seznam Å”tevilk strani) :", + "submit": "IzbriÅ”i strani", + "placeholder": "(npr. 1,2,6 ali 1-10,15-30)" + }, + "imageToPDF": { + "title": "Slika v PDF", + "header": "Slika v PDF", + "submit": "Pretvori", + "selectLabel": "Možnosti prilagajanja slike", + "fillPage": "Izpolni stran", + "fitDocumentToImage": "Prilagodi stran sliki", + "maintainAspectRatio": "Ohrani razmerja stranic", + "selectText": { + "2": "Samodejno zasukaj PDF", + "3": "Logika več datotek (omogočeno samo pri delu z več slikami)", + "4": "Združi v en PDF", + "5": "Pretvori v ločene datoteke PDF" + } + }, + "PDFToCSV": { + "title": "PDF v CSV", + "header": "PDF v CSV", + "prompt": "Izberite stran za ekstrahiranje tabele", + "submit": "Izvleček" + }, + "split-by-size-or-count": { + "title": "Razdeli PDF po velikosti ali Å”tevilu", + "header": "Razdeli PDF po velikosti ali Å”tevilu", + "type": { + "label": "Izberite vrsto razdelitve", + "size": "Po velikosti", + "pageCount": "Po Å”tevilu strani", + "docCount": "Po Å”tevilu dokumentov" + }, + "value": { + "label": "Vnesite vrednost", + "placeholder": "Vnesite velikost (npr. 2MB ali 3KB) ali Å”tevilo (npr. 5)" + }, + "submit": "PoÅ”lji" + }, + "printFile": { + "title": "Natisni datoteko", + "header": "Natisni datoteko na tiskalnik", + "selectText": { + "1": "Izberite datoteko za tiskanje", + "2": "Vnesite ime tiskalnika" + }, + "submit": "Natisni" + }, + "licenses": { + "nav": "Licence", + "title": "Licence tretjih oseb", + "header": "Licence tretjih oseb", + "module": "Modul", + "version": "Različica", + "license": "Licenca" + }, + "survey": { + "nav": "Anketa", + "title": "Anketa Stirling-PDF", + "description": "Stirling-PDF nima sledenja, zato želimo sliÅ”ati od naÅ”ih uporabnikov, da bi izboljÅ”ali Stirling-PDF!", + "changes": "Stirling-PDF se je spremenil od zadnje ankete! Če želite izvedeti več, si oglejte objavo v spletnem dnevniku tukaj:", + "changes2": "S temi spremembami dobimo plačano poslovno podporo in financiranje", + "please": "Prosimo, razmislite o sodelovanju v naÅ”i anketi, če želite prispevati k prihodnosti Stirling-PDF!", + "disabled": "(Pojavno okno ankete bo v naslednjih posodobitvah onemogočeno, vendar na voljo na dnu strani)", + "button": "Izpolnite anketo", + "dontShowAgain": "Ne prikaži več", + "meeting": { + "1": "Če v službi uporabljate Stirling PDF, bi radi govorili z vami. Ponujamo seje tehnične podpore v zameno za 15-minutno sejo odkrivanja uporabnikov.", + "2": "To je priložnost za:", + "3": "PoiŔčite pomoč pri uvajanju, integracijah ali odpravljanju težav", + "4": "Zagotovite neposredne povratne informacije o zmogljivosti, robnih primerih in vrzeli v funkcijah", + "5": "Pomagajte nam izboljÅ”ati Stirling PDF za uporabo v podjetju v resničnem svetu", + "6": "Če ste zainteresirani, si lahko rezervirate čas neposredno pri naÅ”i ekipi. (samo angleÅ”ko govoreči)", + "7": "Veselimo se poglobitve v vaÅ”e primere uporabe in izboljÅ”anja Stirling PDF-ja!", + "notInterested": "Niste podjetje in/ali vas zanima srečanje?", + "button": "Rezerviraj srečanje" + } + }, + "removeImage": { + "title": "Odstrani sliko", + "header": "Odstrani sliko", + "removeImage": "Odstrani sliko", + "submit": "Odstrani sliko" + }, + "splitByChapters": { + "title": "Razdeli PDF po poglavjih", + "header": "Razdeli PDF po poglavjih", + "bookmarkLevel": "Raven zaznamka", + "includeMetadata": "Vključi metapodatke", + "allowDuplicates": "Dovoli podvojitve", + "desc": { + "1": "To orodje razdeli datoteko PDF na več datotek PDF glede na strukturo poglavij.", + "2": "Raven zaznamkov: Izberite raven zaznamkov, ki jih želite uporabiti za razdelitev (0 za najviÅ”jo raven, 1 za drugo raven itd.).", + "3": "Vključi metapodatke: Če je označeno, bodo metapodatki izvirnega PDF-ja vključeni v vsak razdeljeni PDF.", + "4": "Dovoli dvojnike: Če je označeno, dovoljuje več zaznamkov na isti strani za ustvarjanje ločenih PDF-jev." + }, + "submit": "Razdeli PDF" + }, + "fileChooser": { + "click": "Klikni", + "or": "ali", + "dragAndDrop": "Povleci in spusti", + "dragAndDropPDF": "Povleci in spusti datoteko PDF", + "dragAndDropImage": "Povleci in spusti slikovno datoteko", + "hoveredDragAndDrop": "Povleci in spusti datoteko(e) sem", + "extractPDF": "Izvlečenje..." + }, + "releases": { + "footer": "Izdaje", + "title": "Opombe ob izdaji", + "header": "Opombe ob izdaji", + "current": { + "version": "Trenutna izdaja" + }, + "note": "Opombe ob izdaji so na voljo samo v angleŔčini" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/sr-LATN-RS/translation.json b/frontend/public/locales/sr-LATN-RS/translation.json new file mode 100644 index 000000000..2821b0ffd --- /dev/null +++ b/frontend/public/locales/sr-LATN-RS/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Font Size", + "fontName": "Font Name", + "title": "Dodavanje brojeva stranica", + "header": "Dodavanje brojeva stranica", + "selectText": { + "1": "Izaberi PDF fajl:", + "2": "Veličina margine", + "3": "Pozicija", + "4": "Početni broj", + "5": "Brojane stranice", + "6": "Prilagođeni tekst" + }, + "customTextDesc": "Prilagođeni tekst", + "numberPagesDesc": "Koje stranice brojati, podrazumevano 'sve', takođe prihvata 1-5 ili 2,5,9 itd.", + "customNumberDesc": "Podrazumevano je {n}, takođe prihvata 'Stranica {n} od {ukupno}', 'Tekst-{n}', '{ime_fajla}-{n}'", + "submit": "Dodaj brojeve stranica" + }, + "pdfPrompt": "Odaberi PDF(ove)", + "multiPdfPrompt": "Odaberi PDF-ove (2+)", + "multiPdfDropPrompt": "Odaberi (prevuci i pusti ) sve PDF-ove koji su vam potrebni", + "imgPrompt": "Odaberi sliku (slike)", + "genericSubmit": "Prihvatiti", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Warning:Upozorenje: Ovaj proces može trajati i do minut, u zavisnosti od veličine dokumenta", + "pageOrderPrompt": "Prilagođeni redosled stranica (unesi listu brojeva stranica ili funkcija, kao Å”to su 2n+1, razdvojene zarezima) :", + "pageSelectionPrompt": "Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :", + "goToPage": "Idi", + "true": "Tačno", + "false": "Netačno", + "unknown": "Nepoznato", + "save": "Sačuvaj", + "saveToBrowser": "Save to Browser", + "close": "Zatvori", + "filesSelected": "odabrani fajlovi", + "noFavourites": "Nema dodatih favorita", + "downloadComplete": "Download Complete", + "bored": "Da li ti je dosadno dok čekaÅ”?", + "alphabet": "Alfabet", + "downloadPdf": "Skini PDF", + "text": "Tekst", + "font": "Font", + "selectFillter": "-- Izaberi --", + "pageNum": "Broj Strane", + "sizes": { + "small": "Malo", + "medium": "Srednje", + "large": "Veliko", + "x-large": "X-Veliko" + }, + "error": { + "pdfPassword": "PDF dokument je Å”ifrovan i lozinka nije data ili je netačna", + "_value": "Error", + "sorry": "Sorry for the issue!", + "needHelp": "Need help / Found an issue?", + "contactTip": "If you're still having trouble, don't hesitate to reach out to us for help. You can submit a ticket on our GitHub page or contact us through Discord:", + "404": { + "head": "404 - Page Not Found | Oops, we tripped in the code!", + "1": "We can't seem to find the page you're looking for.", + "2": "Something went wrong" + }, + "github": "Submit a ticket on GitHub", + "showStack": "Show Stack Trace", + "copyStack": "Copy Stack Trace", + "githubSubmit": "GitHub - Submit a ticket", + "discordSubmit": "Discord - Submit Support post" + }, + "delete": "ObriÅ”i", + "username": "Korisničko ime", + "password": "Å ifra", + "welcome": "DobrodoÅ”li", + "property": "Svojstvo", + "black": "Crno", + "white": "Belo", + "red": "Crveno", + "green": "Zeleno", + "blue": "Plavo", + "custom": "Prilagođeno...", + "WorkInProgess": "Radovi u toku, možda neće raditi ili će biti greÅ”aka, molimo prijavite sve probleme !", + "poweredBy": "Powered by", + "yes": "Yes", + "no": "No", + "changedCredsMessage": "Podaci za prijavu uspeÅ”no promenjeni!", + "notAuthenticatedMessage": "Korisnik nije autentifikovan.", + "userNotFoundMessage": "Korisnik nije pronađen.", + "incorrectPasswordMessage": "Trenutna Å”ifra je netačna.", + "usernameExistsMessage": "Novi korisnik već postoji", + "invalidUsernameMessage": "Invalid username, username can only contain letters, numbers and the following special characters @._+- or must be a valid email address.", + "invalidPasswordMessage": "The password must not be empty and must not have spaces at the beginning or end.", + "confirmPasswordErrorMessage": "New Password and Confirm New Password must match.", + "deleteCurrentUserMessage": "Cannot delete currently logged in user.", + "deleteUsernameExistsMessage": "The username does not exist and cannot be deleted.", + "downgradeCurrentUserMessage": "Nije moguće degradirati ulogu trenutnog korisnika", + "disabledCurrentUserMessage": "The current user cannot be disabled", + "downgradeCurrentUserLongMessage": "Nije moguće unazaditi ulogu trenutnog korisnika. Dakle, trenutni korisnik neće biti prikazan.", + "userAlreadyExistsOAuthMessage": "The user already exists as an OAuth2 user.", + "userAlreadyExistsWebMessage": "The user already exists as an web user.", + "oops": "Oops!", + "help": "Help", + "goHomepage": "Go to Homepage", + "joinDiscord": "Join our Discord server", + "seeDockerHub": "See Docker Hub", + "visitGithub": "Visit Github Repository", + "donate": "Donate", + "color": "Color", + "sponsor": "Sponsor", + "info": "Info", + "pro": "Pro", + "page": "Page", + "pages": "Pages", + "loading": "Loading...", + "addToDoc": "Add to Document", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Privacy Policy", + "terms": "Terms and Conditions", + "accessibility": "Accessibility", + "cookie": "Cookie Policy", + "impressum": "Impressum", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Meni za Pipeline (Alfa verzija)", + "uploadButton": "Postavi prilagođeno", + "configureButton": "KonfiguriÅ”i", + "defaultOption": "Prilagođeno", + "submitButton": "PoÅ”alji", + "help": "Pipeline Help", + "scanHelp": "Folder Scanning Help", + "deletePrompt": "Are you sure you want to delete pipeline", + "tags": "automatizacija,sekvenciranje,skriptirano,batch-process", + "title": "Tok rada" + }, + "pipelineOptions": { + "header": "Konfiguracija Pipeline-a", + "pipelineNameLabel": "Ime Pipeline-a", + "saveSettings": "Sačuvaj podeÅ”avanja", + "pipelineNamePrompt": "Unesite ime pipeline-a ovde", + "selectOperation": "Select Operation", + "addOperationButton": "Dodaj operaciju", + "pipelineHeader": "Pipeline:", + "saveButton": "Preuzmi", + "validateButton": "Proveri" + }, + "enterpriseEdition": { + "button": "Upgrade to Pro", + "warning": "This feature is only available to Pro users.", + "yamlAdvert": "Stirling PDF Pro supports YAML configuration files and other SSO features.", + "ssoAdvert": "Looking for more user management features? Check out Stirling PDF Pro" + }, + "analytics": { + "title": "Do you want make Stirling PDF better?", + "paragraph1": "Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.", + "paragraph2": "Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.", + "enable": "Enable analytics", + "disable": "Disable analytics", + "settings": "You can change the settings for analytics in the config/settings.yml file" + }, + "navbar": { + "favorite": "Favorites", + "recent": "New and recently updated", + "darkmode": "Tamni režim", + "language": "Languages", + "settings": "PodeÅ”avanja", + "allTools": "Tools", + "multiTool": "Multi Tools", + "search": "Search", + "sections": { + "organize": "Organize", + "convertTo": "Convert to PDF", + "convertFrom": "Convert from PDF", + "security": "Sign & Security", + "advance": "Advanced", + "edit": "View & Edit", + "popular": "Popular" + } + }, + "settings": { + "title": "PodeÅ”avanja", + "update": "Dostupno ažuriranje", + "updateAvailable": "{0} is the current installed version. A new version ({1}) is available.", + "appVersion": "Verzija aplikacije:", + "downloadOption": { + "title": "Odaberite opciju preuzimanja (Za preuzimanje pojedinačnih fajlova bez zip formata):", + "1": "Otvori u istom prozoru", + "2": "Otvori u novom prozoru", + "3": "Preuzmi fajl" + }, + "zipThreshold": "Zipuj fajlove kada pređe broj preuzetih fajlova", + "signOut": "Odjava", + "accountSettings": "PodeÅ”avanja naloga", + "bored": { + "help": "Enables easter egg game" + }, + "cacheInputs": { + "name": "Save form inputs", + "help": "Enable to store previously used inputs for future runs" + } + }, + "changeCreds": { + "title": "Promeni pristupne podatke", + "header": "Ažurirajte detalje svog naloga", + "changePassword": "You are using default login credentials. Please enter a new password", + "newUsername": "Novo korisničko ime", + "oldPassword": "Trenutna lozinka", + "newPassword": "Nova lozinka", + "confirmNewPassword": "Potvrdite novu lozinku", + "submit": "Potvrdi promene" + }, + "account": { + "title": "PodeÅ”avanja naloga", + "accountSettings": "PodeÅ”avanja naloga", + "adminSettings": "Admin podeÅ”avanja - Pregled i dodavanje korisnika", + "userControlSettings": "PodeÅ”avanja kontrole korisnika", + "changeUsername": "Pormeni korisničko ime", + "newUsername": "Novo korisničko ime", + "password": "Potvrda lozinke", + "oldPassword": "Stara lozinka", + "newPassword": "Nova lozinka", + "changePassword": "Pormeni lozinku", + "confirmNewPassword": "Potvrdi novu lozinku", + "signOut": "Odjava", + "yourApiKey": "Tvoj API ključ", + "syncTitle": "Sinhronizacija podeÅ”avanja pregledača sa nalogom", + "settingsCompare": "Upoređivanje podeÅ”avanja:", + "property": "Svojstvo", + "webBrowserSettings": "PodeÅ”avanja veb pregledača", + "syncToBrowser": "Sinhronizacija naloga -> pregledač", + "syncToAccount": "Sinhronizacija naloga <- pregledač" + }, + "adminUserSettings": { + "title": "PodeÅ”avanja kontrole korisnika", + "header": "PodeÅ”avanja kontrole korisnika za administratora", + "admin": "Administrator", + "user": "Korisnik", + "addUser": "Dodaj novog korisnika", + "deleteUser": "Delete User", + "confirmDeleteUser": "Should the user be deleted?", + "confirmChangeUserStatus": "Should the user be disabled/enabled?", + "usernameInfo": "Username can only contain letters, numbers and the following special characters @._+- or must be a valid email address.", + "roles": "Uloge", + "role": "Uloga", + "actions": "Akcije", + "apiUser": "Korisnik s ograničenim API pristupom", + "extraApiUser": "Additional Limited API User", + "webOnlyUser": "Korisnik samo za web", + "demoUser": "Demo korisnik (Bez prilagođenih podeÅ”avanja)", + "internalApiUser": "Internal API User", + "forceChange": "Prisili korisnika da promeni korisničko ime/lozinku pri prijavi", + "submit": "Sačuvaj korisnika", + "changeUserRole": "Promenite ulogu korisnika", + "authenticated": "Authenticated", + "editOwnProfil": "Edit own profile", + "enabledUser": "enabled user", + "disabledUser": "disabled user", + "activeUsers": "Active Users:", + "disabledUsers": "Disabled Users:", + "totalUsers": "Total Users:", + "lastRequest": "Last Request", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Database Import/Export", + "header": "Database Import/Export", + "fileName": "File Name", + "creationDate": "Creation Date", + "fileSize": "File Size", + "deleteBackupFile": "Delete Backup File", + "importBackupFile": "Import Backup File", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Download Backup File", + "info_1": "When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.", + "info_2": "The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.", + "submit": "Import Backup", + "importIntoDatabaseSuccessed": "Import into database successed", + "backupCreated": "Database backup successful", + "fileNotFound": "File not Found", + "fileNullOrEmpty": "File must not be null or empty", + "failedImportFile": "Failed Import File", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "Your session has expired. Please refresh the page and try again.", + "refreshPage": "Refresh Page" + }, + "home": { + "desc": "VaÅ” lokalno hostovan jedinstveni alat za sve vaÅ”e potrebe vezane za PDF.", + "searchBar": "Pretraži funkcije...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Pregledaj, anotiraj, dodaj tekst ili slike" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "PDF Multi Alat", + "desc": "Spajanje, rotacija, premeÅ”tanje i uklanjanje stranica" + }, + "merge": { + "title": "Spajanje", + "desc": "Lako spojite viÅ”e PDF-ova u jedan." + }, + "split": { + "title": "Razdvajanje", + "desc": "Razdvojite PDF-ove u viÅ”e dokumenata" + }, + "rotate": { + "title": "Rotacija", + "desc": "Lako rotirajte vaÅ”e PDF-ove." + }, + "imageToPdf": { + "title": "Slika u PDF", + "desc": "Konvertujte sliku (PNG, JPEG, GIF) u PDF." + }, + "pdfToImage": { + "title": "PDF u Sliku", + "desc": "Konvertujte PDF u sliku. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Organizacija", + "desc": "Uklonite/PremeÅ”tajte stranice u bilo kom redosledu" + }, + "addImage": { + "title": "Dodaj sliku", + "desc": "Dodaje sliku na određeno mesto u PDF-u" + }, + "watermark": { + "title": "Dodaj vodeni žig", + "desc": "Dodajte prilagođeni vodeni žig na vaÅ” PDF dokument." + }, + "permissions": { + "title": "Promeni dozvole", + "desc": "Promenite dozvole vaÅ”eg PDF dokumenta" + }, + "removePages": { + "title": "Ukloni", + "desc": "ObriÅ”ite nepotrebne stranice iz vaÅ”eg PDF dokumenta." + }, + "addPassword": { + "title": "Dodaj lozinku", + "desc": "Enkriptujte vaÅ” PDF dokument lozinkom." + }, + "removePassword": { + "title": "Ukloni lozinku", + "desc": "Uklonite zaÅ”titu lozinkom sa vaÅ”eg PDF dokumenta." + }, + "compressPdfs": { + "title": "Kompresuj", + "desc": "Kompresujte PDF-ove kako bi smanjili veličinu fajla." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Promena metapodataka", + "desc": "Promenite/Uklonite/Dodajte metapodatke u PDF dokumentu" + }, + "fileToPDF": { + "title": "Konvertuj fajl u PDF", + "desc": "Konvertujte gotovo bilo koji fajl u PDF (DOCX, PNG, XLS, PPT, TXT i viÅ”e)" + }, + "ocr": { + "title": "OCR / ČiŔćenje skenova", + "desc": "ČiŔćenje skenova i detektovanje teksta sa slika unutar PDF-a i ponovno dodavanje kao teksta." + }, + "extractImages": { + "title": "Izvuci slike", + "desc": "Izvlači sve slike iz PDF-a i čuva ih u zip formatu" + }, + "pdfToPDFA": { + "title": "PDF u PDF/A", + "desc": "Konvertujte PDF u PDF/A za dugoročno čuvanje" + }, + "PDFToWord": { + "title": "PDF u Word", + "desc": "Konvertujte PDF u Word formate (DOC, DOCX i ODT)" + }, + "PDFToPresentation": { + "title": "PDF u Prezentaciju", + "desc": "Konvertujte PDF u formate za prezentaciju (PPT, PPTX i ODP)" + }, + "PDFToText": { + "title": "PDF u RTF (Tekst)", + "desc": "Konvertujte PDF u tekst ili RTF format" + }, + "PDFToHTML": { + "title": "PDF u HTML", + "desc": "Konvertujte PDF u HTML format" + }, + "PDFToXML": { + "title": "PDF u XML", + "desc": "Konvertujte PDF u XML format" + }, + "ScannerImageSplit": { + "title": "Detekcija/Razdvajanje skeniranih fotografija", + "desc": "Razdvaja viÅ”e fotografija unutar slike/PDF-a" + }, + "sign": { + "title": "Potpis", + "desc": "Dodaje potpis u PDF crtežom, tekstom ili slikom" + }, + "flatten": { + "title": "Ravnanje", + "desc": "Uklanja sve interaktivne elemente i forme iz PDF-a" + }, + "repair": { + "title": "Popravi", + "desc": "PokuÅ”ava popraviti oÅ”tećeni/izgubljeni PDF" + }, + "removeBlanks": { + "title": "Ukloni prazne stranice", + "desc": "Detektuje i uklanja prazne stranice iz dokumenta" + }, + "removeAnnotations": { + "title": "Ukloni Anotacije", + "desc": "Uklanja sve komentare/anotacije iz PDF-a" + }, + "compare": { + "title": "Uporedi", + "desc": "Upoređuje i prikazuje razlike između 2 PDF dokumenata" + }, + "certSign": { + "title": "Potpis sa sertifikatom", + "desc": "Potpisuje PDF sa sertifikatom/ključem (PEM/P12)" + }, + "removeCertSign": { + "title": "Remove Certificate Sign", + "desc": "Remove certificate signature from PDF" + }, + "pageLayout": { + "title": "ViÅ”estruki prikaz stranica", + "desc": "Spaja viÅ”e stranica PDF dokumenta u jednu stranicu" + }, + "scalePages": { + "title": "Podesi veličinu/skalu stranice", + "desc": "Podesi veličinu/skalu stranice i/ili njenog sadržaja." + }, + "pipeline": { + "title": "Pipeline (Napredno)", + "desc": "Pokreće viÅ”e akcija na PDF-ovima definisanjem skripti u pipelinu" + }, + "add-page-numbers": { + "title": "Dodaj brojeve stranica", + "desc": "Dodaje brojeve stranica u dokumentu na određeno mesto" + }, + "auto-rename": { + "title": "Automatsko preimenovanje PDF fajla", + "desc": "Automatski menja ime PDF fajla na osnovu detektovanog zaglavlja" + }, + "adjust-contrast": { + "title": "Podesi boje/kontrast", + "desc": "Podesi kontrast, zasićenost i osvetljenost PDF-a" + }, + "crop": { + "title": "Skraćivanje PDF-a", + "desc": "Skraćuje PDF radi smanjenja veličine (zadržava tekst!)" + }, + "autoSplitPDF": { + "title": "Automatsko razdvajanje stranica", + "desc": "Automatski deli skenirane PDF-ove pomoću fizičkog skenera QR koda" + }, + "sanitizePdf": { + "title": "Sanitizacija", + "desc": "Uklanja skripte i druge elemente iz PDF fajlova" + }, + "URLToPDF": { + "title": "URL/Website u PDF", + "desc": "Konvertuje bilo koji http(s) URL u PDF" + }, + "HTMLToPDF": { + "title": "HTML u PDF", + "desc": "Konvertuje bilo koji HTML fajl ili zip u PDF" + }, + "MarkdownToPDF": { + "title": "Markdown u PDF", + "desc": "Konvertuje bilo koji Markdown fajl u PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "Dohvati SVE informacije o PDF-u", + "desc": "Dobavlja sve moguće informacije o PDF-ovima" + }, + "extractPage": { + "title": "Izdvajanje stranica", + "desc": "Izdvaja odabrane stranice iz PDF-a" + }, + "PdfToSinglePage": { + "title": "PDF u Jednu Veliku Stranicu", + "desc": "Spaja sve stranice PDF-a u jednu veliku stranicu" + }, + "showJS": { + "title": "Prikaži JavaScript", + "desc": "Pretražuje i prikazuje bilo koji JavaScript ubačen u PDF" + }, + "autoRedact": { + "title": "Automatsko Cenzurisanje", + "desc": "Automatsko cenzurisanje teksta u PDF-u na osnovu unetog teksta" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF u CSV", + "desc": "Izdvaja tabele iz PDF-a pretvarajući ih u CSV" + }, + "autoSizeSplitPDF": { + "title": "Automatsko Deljenje po Veličini/Broju", + "desc": "Deljenje jednog PDF-a na viÅ”e dokumenata na osnovu veličine, broja stranica ili broja dokumenata" + }, + "overlay-pdfs": { + "title": "Preklapanje PDF-ova", + "desc": "Preklapa PDF-ove jedan preko drugog" + }, + "split-by-sections": { + "title": "Deljenje PDF-a po Odeljcima", + "desc": "Deljenje svake stranice PDF-a na manje horizontalne i vertikalne odeljke" + }, + "AddStampRequest": { + "title": "Add Stamp to PDF", + "desc": "Add text or add image stamps at set locations" + }, + "removeImagePdf": { + "title": "Remove image", + "desc": "Remove image from PDF to reduce file size" + }, + "splitPdfByChapters": { + "title": "Split PDF by Chapters", + "desc": "Split a PDF into multiple files based on its chapter structure." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "replaceColorPdf": { + "title": "Replace and Invert Color", + "desc": "Replace color for text and background in PDF and invert full color of pdf to reduce file size" + } + }, + "viewPdf": { + "tags": "pregled,čitanje,anotiranje,tekst,slika", + "title": "View/Edit PDF", + "header": "Prikaz PDF-a" + }, + "multiTool": { + "tags": "Multi Alat,Multi operacija,Korisnički interfejs,klik i povuci,front end,klijentska strana,interaktivno,pomera", + "title": "PDF Multi Alatka", + "header": "PDF Multi Alatka", + "uploadPrompts": "File Name", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "selectPages": "Page Select", + "selectedPages": "Selected Pages", + "page": "Page", + "deleteSelected": "Delete Selected", + "downloadAll": "Export", + "downloadSelected": "Export Selected", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "Page(s) Selected", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "spajanje,Operacije sa stranicama,Backend,server strana", + "title": "Spajanje", + "header": "Spajanje viÅ”e PDF fajlova (2+)", + "sortByName": "Sortiraj po imenu", + "sortByDate": "Sortiraj po datumu", + "removeCertSign": "Remove digital signature in the merged file?", + "submit": "Spajanje" + }, + "split": { + "tags": "Operacije sa stranicama,podela,ViÅ”estruke stranice,sečenje,server strana", + "title": "Razdvajanje PDF-a", + "header": "Razdvajanje PDF-a", + "desc": { + "1": "Brojevi koje izaberete predstavljaju brojeve stranica na kojima želite napraviti razdvajanje", + "2": "Na primer, izbor 1,3,7-9 bi razdvojio dokument od 10 stranica u 6 odvojenih PDF-a sa:", + "3": "Dokument #1: Stranica 1", + "4": "Dokument #2: Stranice 2 i 3", + "5": "Dokument #3: Stranice 4, 5, 6 i 7", + "6": "Dokument #4: Stranica 8", + "7": "Dokument #5: Stranica 9", + "8": "Dokument #6: Stranice 10" + }, + "splitPages": "Unesite stranice za razdvajanje:", + "submit": "Razdvoji" + }, + "rotate": { + "tags": "server strana", + "title": "Rotiranje PDF-a", + "header": "Rotiranje PDF-a", + "selectAngle": "Izaberite ugao rotacije (u viÅ”estrukim od 90 stepeni):", + "submit": "Rotiraj" + }, + "imageToPdf": { + "tags": "konverzija,img,jpg,slika,foto" + }, + "pdfToImage": { + "tags": "konverzija,img,jpg,slika,foto", + "title": "PDF u sliku", + "header": "PDF u sliku", + "selectText": "Format slike", + "singleOrMultiple": "Tip rezultata slike po stranici", + "single": "Jedna velika slika koja sadrži sve stranice", + "multi": "ViÅ”e slika, po jedna slika po stranici", + "colorType": "Tip boje", + "color": "Boja", + "grey": "Nijanse sive", + "blackwhite": "Crno-belo (Može izgubiti podatke!)", + "submit": "Konvertuj", + "info": "Python is not installed. Required for WebP conversion.", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,even,odd,sort,move", + "title": "Organizator stranica", + "header": "Organizator stranica u PDF-u", + "submit": "Preuredi stranice", + "mode": { + "_value": "Mode", + "1": "Custom Page Order", + "2": "Reverse Order", + "3": "Duplex Sort", + "4": "Booklet Sort", + "5": "Side Stitch Booklet Sort", + "6": "Odd-Even Split", + "7": "Remove First", + "8": "Remove Last", + "9": "Remove First and Last", + "10": "Odd-Even Merge", + "11": "Duplicate all pages" + }, + "placeholder": "(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)" + }, + "addImage": { + "tags": "img,jpg,slika,foto", + "title": "Dodaj sliku", + "header": "Dodaj sliku u PDF", + "everyPage": "Na svakoj stranici?", + "upload": "Dodaj sliku", + "submit": "Dodaj sliku" + }, + "watermark": { + "tags": "Tekst,ponavljanje,etiketa,vlastiti,autorsko pravo,zaÅ”tita, img,jpg,slika,foto", + "title": "Dodaj vodeni žig", + "header": "Dodaj vodeni žig", + "customColor": "Custom Text Color", + "selectText": { + "1": "Izaberite PDF za dodavanje vodenog žiga:", + "2": "Tekst vodenog žiga:", + "3": "Veličina fonta:", + "4": "Rotacija (0-360):", + "5": "Å irina razmaka (Razmak između svakog vodenog žiga horizontalno):", + "6": "Visina razmaka (Razmak između svakog vodenog žiga vertikalno):", + "7": "Opačitost (0% - 100%):", + "8": "Tip vodenog žiga:", + "9": "Slika vodenog žiga:", + "10": "Convert PDF to PDF-Image" + }, + "submit": "Dodaj vodeni žig", + "type": { + "1": "Text", + "2": "Image" + } + }, + "permissions": { + "tags": "čitanje,pisanje,izmena,Å”tampa", + "title": "Promeni dozvole", + "header": "Promeni dozvole", + "warning": "Upozorenje: Da biste ove dozvole učinili nepromenljivim, preporučuje se postavljanje Å”ifre putem stranice za dodavanje Å”ifre.", + "selectText": { + "1": "Izaberite PDF za promenu dozvola", + "2": "Postavke dozvola", + "3": "Onemogući sastavljanje dokumenta", + "4": "Onemogući ekstrakciju sadržaja", + "5": "Onemogući ekstrakciju za pristupačnost", + "6": "Onemogući popunjavanje formulara", + "7": "Onemogući modifikaciju", + "8": "Onemogući modifikaciju anotacija", + "9": "Onemogući Å”tampanje", + "10": "Onemogući Å”tampanje u različitim formatima" + }, + "submit": "Promeni" + }, + "removePages": { + "tags": "Ukloni stranice,obriÅ”i stranice" + }, + "addPassword": { + "tags": "bezbedno,zaÅ”tita", + "title": "Dodaj Å”ifru", + "header": "Dodaj Å”ifru (Enkripcija)", + "selectText": { + "1": "Izaberite PDF za enkripciju", + "2": "Korisnička Å”ifra", + "3": "Dužina enkripcijskog ključa", + "4": "Veće vrednosti su jače, ali manje vrednosti imaju bolju kompatibilnost.", + "5": "Postavke dozvola (Preporučuje se koriŔćenje sa Å”ifrom vlasnika)", + "6": "Onemogući sastavljanje dokumenta", + "7": "Onemogući ekstrakciju sadržaja", + "8": "Onemogući ekstrakciju za pristupačnost", + "9": "Onemogući popunjavanje formulara", + "10": "Onemogući modifikaciju", + "11": "Onemogući modifikaciju anotacija", + "12": "Onemogući Å”tampanje", + "13": "Onemogući Å”tampanje u različitim formatima", + "14": "Å ifra vlasnika", + "15": "Ograničava Å”ta se može raditi sa dokumentom nakon otvaranja (Nije podržano od svih čitača)", + "16": "Ograničava otvaranje samog dokumenta" + }, + "submit": "Enkriptuj" + }, + "removePassword": { + "tags": "bezbedno,DeÅ”ifruj,zaÅ”tita,ukloni lozinku", + "title": "Ukloni Å”ifru", + "header": "Ukloni Å”ifru (Dekripcija)", + "selectText": { + "1": "Izaberite PDF za dekripciju", + "2": "Å ifra" + }, + "submit": "Ukloni" + }, + "compressPdfs": { + "tags": "smanji,mali,minijaturni" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Naslov,autor,datum,kreacije,vreme,izdavač,proizvođač,statistike", + "title": "Naslov:", + "header": "Promeni metapodatke", + "selectText": { + "1": "Izmenite promenljive koje želite promeniti", + "2": "ObriÅ”i sve metapodatke", + "3": "Prikaži prilagođene metapodatke:", + "4": "Drugi metapodaci:", + "5": "Dodaj prilagođeni unos metapodataka" + }, + "author": "Autor:", + "creationDate": "Datum kreiranja (gggg/MM/dd HH:mm:ss):", + "creator": "Kreator:", + "keywords": "Ključne reči:", + "modDate": "Datum izmene (gggg/MM/dd HH:mm:ss):", + "producer": "Proizvođač:", + "subject": "Tema:", + "trapped": "Zaglavljeno:", + "submit": "Promeni" + }, + "fileToPDF": { + "tags": "transformacija,format,dokument,slika,slajd,tekst,konverzija,office,docs,word,excel,powerpoint", + "title": "Fajl u PDF", + "header": "Konvertuj bilo koji fajl u PDF", + "credit": "Ova usluga koristi LibreOffice i Unoconv za konverziju fajla.", + "supportedFileTypesInfo": "Supported File types", + "supportedFileTypes": "Podržani tipovi fajlova bi trebali uključivati navedeno, ali za punu ažuriranu listu podržanih formata, molimo pogledajte LibreOffice dokumentaciju", + "submit": "Konvertuj u PDF" + }, + "ocr": { + "tags": "prepoznavanje,tekst,slika,sken,čitanje,identifikacija,detekcija,uređivanje", + "title": "OCR / ČiŔćenje skeniranja", + "header": "ČiŔćenje skeniranja / OCR (Optičko prepoznavanje znakova)", + "selectText": { + "1": "Odaberite jezike koji će biti detektovani unutar PDF-a (Navedeni su trenutno detektovani):", + "2": "Proizvedi tekstualni fajl koji sadrži OCR tekst uz OCR-ovani PDF", + "3": "Ispravite stranice koje su skenirane pod uglom rotirajući ih na svoje mesto", + "4": "Očistite stranicu tako da je manje verovatno da će OCR pronaći tekst u pozadinskom Å”umu. (Bez promene izlaza)", + "5": "Očistite stranicu tako da je manje verovatno da će OCR pronaći tekst u pozadinskom Å”umu, zadržavajući čiŔćenje u izlazu.", + "6": "IgnoriÅ”e stranice koje imaju interaktivni tekst, samo OCR-uje stranice koje su slike", + "7": "Prinudni OCR, OCR-uje svaku stranicu uklanjajući sve originalne tekstualne elemente", + "8": "Normalno (Prikaže greÅ”ku ako PDF sadrži tekst)", + "9": "Dodatne postavke", + "10": "Režim OCR-a", + "11": "Ukloni slike nakon OCR-a (Uklanja SVE slike, korisno samo ako je deo koraka konverzije)", + "12": "Tip rendiranja (Napredno)" + }, + "help": "Molimo vas da pročitate ovu dokumentaciju o tome kako koristiti ovo za druge jezike i/ili koriŔćenje van docker-a", + "credit": "Ova usluga koristi qpdf i Tesseract za OCR.", + "submit": "Obradi PDF sa OCR-om" + }, + "extractImages": { + "tags": "slika,foto,sačuvaj,arhiva,zip,zahvati,uhvati", + "title": "Izdvajanje slika", + "header": "Izdvajanje slika", + "selectText": "Odaberite format slike za konvertovanje izdvojenih slika", + "allowDuplicates": "Save duplicate images", + "submit": "Izdvajanje" + }, + "pdfToPDFA": { + "tags": "arhiva,dugoročno,standard,konverzija,čuvanje,čuvanje", + "title": "PDF u PDF/A", + "header": "PDF u PDF/A", + "credit": "Ova usluga koristi libreoffice za konverziju u PDF/A format", + "submit": "Konvertuj", + "tip": "Currently does not work for multiple inputs at once", + "outputFormat": "Output format", + "pdfWithDigitalSignature": "The PDF contains a digital signature. This will be removed in the next step." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformacija,format,konverzija,office,microsoft,docfile", + "title": "PDF u Word", + "header": "PDF u Word", + "selectText": { + "1": "Format izlaznog fajla" + }, + "credit": "Ova usluga koristi LibreOffice za konverziju fajlova.", + "submit": "Konvertuj" + }, + "PDFToPresentation": { + "tags": "slajdovi,prikaz,office,microsoft", + "title": "PDF u Prezentaciju", + "header": "PDF u Prezentaciju", + "selectText": { + "1": "Format izlaznog fajla" + }, + "credit": "Ova usluga koristi LibreOffice za konverziju fajlova.", + "submit": "Konvertuj" + }, + "PDFToText": { + "tags": "richformat,richtextformat,rich text format", + "title": "PDF u RTF (Tekst)", + "header": "PDF u RTF (Tekst)", + "selectText": { + "1": "Format izlaznog fajla" + }, + "credit": "Ova usluga koristi LibreOffice za konverziju fajlova.", + "submit": "Konvertuj" + }, + "PDFToHTML": { + "tags": "web sadržaj,prijateljski za pretraživače", + "title": "PDF u HTML", + "header": "PDF u HTML", + "credit": "Ova usluga koristi pdftohtml za konverziju fajlova.", + "submit": "Konvertuj" + }, + "PDFToXML": { + "tags": "izdvajanje-podataka,strukturirani-sadržaj,interop,transformacija,konvertovanje", + "title": "PDF u XML", + "header": "PDF u XML", + "credit": "Ova usluga koristi LibreOffice za konverziju fajlova.", + "submit": "Konvertuj" + }, + "ScannerImageSplit": { + "tags": "razdvoji,auto-detekcija,skeniranja,viÅ”estruke fotografije,organizacija", + "selectText": { + "1": "Ugao praga:", + "2": "Postavlja minimalni apsolutni ugao potreban za rotiranje slike (podrazumevano: 10).", + "3": "Tolerancija:", + "4": "Određuje opseg varijacije boja oko procenjene boje pozadine (podrazumevano: 30).", + "5": "Minimalna povrÅ”ina:", + "6": "Postavlja minimalni prag povrÅ”ine za fotografiju (podrazumevano: 10000).", + "7": "Minimalna povrÅ”ina konture:", + "8": "Postavlja minimalni prag povrÅ”ine konture za fotografiju", + "9": "Veličina ivice:", + "10": "Postavlja veličinu ivice dodate i uklonjene kako bi se sprečile bele ivice u izlazu (podrazumevano: 1)." + }, + "info": "Python is not installed. It is required to run." + }, + "sign": { + "tags": "autorizacija,inicijali,crtani-potpis,tekstualni-potpis,slikovni-potpis", + "title": "PotpiÅ”i", + "header": "PotpiÅ”i PDF fajlove", + "upload": "Učitaj sliku", + "draw": "Nacrtaj potpis", + "text": "Tekstualni unos", + "clear": "ObriÅ”i", + "add": "Dodaj", + "saved": "Saved Signatures", + "save": "Save Signature", + "personalSigs": "Personal Signatures", + "sharedSigs": "Shared Signatures", + "noSavedSigs": "No saved signatures found", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "statično,deaktivirati,neinteraktivno,usmeriti", + "title": "Ravnanje", + "header": "Ravnanje PDF fajlova", + "flattenOnlyForms": "Flatten only forms", + "submit": "Ravnanje" + }, + "repair": { + "tags": "popravi,vrati,korekcija,obnovi", + "title": "Popravi", + "header": "Popravi PDF fajlove", + "submit": "Popravi" + }, + "removeBlanks": { + "tags": "čiŔćenje,usmeriti,ne-sadržaj,organizacija", + "title": "Ukloni prazne stranice", + "header": "Ukloni prazne stranice", + "threshold": "Prag beline piksela:", + "thresholdDesc": "Prag za određivanje koliko beli piksel mora biti 'beli'. 0 = Crno, 255 čisto belo.", + "whitePercent": "Procenat bele boje (%):", + "whitePercentDesc": "Procenat stranice koji mora biti 'beli' pikseli da bi se uklonili", + "submit": "Ukloni prazne" + }, + "removeAnnotations": { + "tags": "komentari,isticanje,beleÅ”ke,oznake,ukloni", + "title": "Ukloni Anotacije", + "header": "Ukloni Anotacije", + "submit": "Ukloni" + }, + "compare": { + "tags": "razlikovati,kontrast,izmene,analiza", + "title": "Uporedi", + "header": "Uporedi PDF fajlove", + "highlightColor": { + "1": "Highlight Color 1:", + "2": "Highlight Color 2:" + }, + "document": { + "1": "Dokument 1", + "2": "Dokument 2" + }, + "submit": "Uporedi", + "complex": { + "message": "One or both of the provided documents are large files, accuracy of comparison may be reduced" + }, + "large": { + "file": { + "message": "One or Both of the provided documents are too large to process" + } + }, + "no": { + "text": { + "message": "One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison." + } + } + }, + "certSign": { + "tags": "autentifikacija,PEM,P12,zvanično,Å”ifrovanje", + "title": "Potpisivanje Sertifikatom", + "header": "PotpiÅ”i PDF sa svojim sertifikatom (Rad u toku)", + "selectPDF": "Izaberite PDF fajl za potpisivanje:", + "jksNote": "Note: If your certificate type is not listed below, please convert it to a Java Keystore (.jks) file using the keytool command line tool. Then, choose the .jks file option below.", + "selectKey": "Izaberite svoj privatni ključ (PKCS#8 format, može biti .pem ili .der):", + "selectCert": "Izaberite svoj sertifikat (X.509 format, može biti .pem ili .der):", + "selectP12": "Izaberite svoj PKCS#12 keystore fajl (.p12 ili .pfx) (Opciono, ako je dostupan, trebalo bi da sadrži vaÅ” privatni ključ i sertifikat):", + "selectJKS": "Select Your Java Keystore File (.jks or .keystore):", + "certType": "Tip sertifikata", + "password": "Unesite lozinku vaÅ”eg keystore-a ili privatnog ključa (ako je ima):", + "showSig": "Prikaži potpis", + "reason": "Razlog", + "location": "Lokacija", + "name": "Ime", + "showLogo": "Show Logo", + "submit": "PotpiÅ”i PDF" + }, + "removeCertSign": { + "tags": "authenticate,PEM,P12,official,decrypt", + "title": "Remove Certificate Signature", + "header": "Remove the digital certificate from the PDF", + "selectPDF": "Select a PDF file:", + "submit": "Remove Signature" + }, + "pageLayout": { + "tags": "spajanje,kompozit,pojedinačan-prikaz,organizacija", + "title": "ViÅ”estruki Raspored Stranica", + "header": "ViÅ”estruki Raspored Stranica", + "pagesPerSheet": "Stranica po listu:", + "addBorder": "Dodaj ivice", + "submit": "Potvrdi" + }, + "scalePages": { + "tags": "izmena,modifikacija,dimenzija,adaptacija", + "title": "Podesi razmeru stranica", + "header": "Podesi razmeru stranica", + "pageSize": "Veličina stranice dokumenta.", + "keepPageSize": "Original Size", + "scaleFactor": "Nivo zumiranja (rezanje) stranice.", + "submit": "Potvrdi" + }, + "add-page-numbers": { + "tags": "paginacija,oznaka,organizacija,indeks" + }, + "auto-rename": { + "tags": "auto-detekcija,zaglavlje-bazirano,organizacija,preimenovanje", + "title": "Automatsko preimenovanje", + "header": "Automatsko preimenovanje PDF-a", + "submit": "Automatsko preimenovanje" + }, + "adjust-contrast": { + "tags": "korekcija-boja,podeÅ”avanje,modifikacija,unapredi" + }, + "crop": { + "tags": "trimovanje,skupljanje,uređivanje,oblikovanje", + "title": "Iseci", + "header": "Skraćivanje PDF-a", + "submit": "Potvrdi" + }, + "autoSplitPDF": { + "tags": "QR-bazirano,razdvoji,segment-skeniranja,organizacija", + "title": "Automatsko Deljenje PDF-a", + "header": "Automatsko Deljenje PDF-a", + "description": "Å tampajte, umetnite, skenirajte, učitajte i dozvolite nam da automatski razdvojimo vaÅ”e dokumente. Nije potrebno ručno sortiranje.", + "selectText": { + "1": "OdÅ”tampajte nekoliko listova razdeljivača ispod (Crno-belo je u redu).", + "2": "Skenirajte sve vaÅ”e dokumente odjednom, ubacivanjem lista razdeljivača između njih.", + "3": "Učitajte jedan veliki skenirani PDF fajl i dozvolite Stirling PDF-u da obavi ostalo.", + "4": "Listovi razdeljivača se automatski detektuju i uklanjaju, obezbeđujući uredan konačni dokument." + }, + "formPrompt": "Potvrdite PDF koji sadrži Stirling-PDF listove razdeljivača:", + "duplexMode": "Dupleks režim (skeniranje prednje i zadnje strane)", + "dividerDownload2": "Preuzmi 'Auto Splitter Divider (sa uputstvima).pdf'", + "submit": "Potvrdi" + }, + "sanitizePdf": { + "tags": "čiŔćenje,bezbednost,bezbedno,ukloni-pretnje" + }, + "URLToPDF": { + "tags": "uhvati-web,sačuvaj-stranicu,web-u-doc,arhiva", + "title": "URL u PDF", + "header": "URL u PDF", + "submit": "Konvertuj", + "credit": "Koristi WeasyPrint" + }, + "HTMLToPDF": { + "tags": "oznake,web-sadržaj,transformacija,konvertovanje", + "title": "HTML u PDF", + "header": "HTML u PDF", + "help": "Prihvata HTML fajlove i ZIP-ove koji sadrže html/css/slike itd. potrebno", + "submit": "Konvertuj", + "credit": "Koristi WeasyPrint", + "zoom": "Zoom level for displaying the website.", + "pageWidth": "Width of the page in centimeters. (Blank to default)", + "pageHeight": "Height of the page in centimeters. (Blank to default)", + "marginTop": "Top margin of the page in millimeters. (Blank to default)", + "marginBottom": "Bottom margin of the page in millimeters. (Blank to default)", + "marginLeft": "Left margin of the page in millimeters. (Blank to default)", + "marginRight": "Right margin of the page in millimeters. (Blank to default)", + "printBackground": "Render the background of websites.", + "defaultHeader": "Enable Default Header (Name and page number)", + "cssMediaType": "Change the CSS media type of the page.", + "none": "None", + "print": "Print", + "screen": "Screen" + }, + "MarkdownToPDF": { + "tags": "oznake,web-sadržaj,transformacija,konvertovanje", + "title": "Markdown u PDF", + "header": "Markdown u PDF", + "submit": "Konvertuj", + "help": "Rad u toku", + "credit": "Koristi WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "informacije,podaci,statistike", + "title": "Informacije o PDF-u", + "header": "Informacije o PDF-u", + "submit": "Informacije", + "downloadJson": "Preuzmi JSON" + }, + "extractPage": { + "tags": "izdvajanje" + }, + "PdfToSinglePage": { + "tags": "jedna-stranica" + }, + "showJS": { + "tags": "JS", + "title": "Prikaži Javascript", + "header": "Prikaži Javascript", + "downloadJS": "Preuzmi Javascript", + "submit": "Prikaži" + }, + "autoRedact": { + "tags": "Cenzura,Sakrij,prekrivanje,crna,marker,skriveno", + "title": "Auto Cenzura", + "header": "Auto Cenzura", + "colorLabel": "Boja", + "textsToRedactLabel": "Tekst za cenzurisanje (razdvojeni linijama)", + "textsToRedactPlaceholder": "npr. \\nPoverljivo \\nVrhunski Tajno", + "useRegexLabel": "Koristi Regex", + "wholeWordSearchLabel": "Pretraga celih reči", + "customPaddingLabel": "Dodatni prazan prostor", + "convertPDFToImageLabel": "Konvertuj PDF u PDF-Image (koristi se za uklanjanje teksta iza okvira)", + "submitButton": "Potvrdi" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,Izdvajanje tabela,izdvajanje,konvertovanje" + }, + "autoSizeSplitPDF": { + "tags": "pdf,delenje,dokumenti,organizacija" + }, + "overlay-pdfs": { + "tags": "Preklapanje", + "header": "Preklapanje PDF fajlova", + "baseFile": { + "label": "Izaberite osnovni PDF fajl" + }, + "overlayFiles": { + "label": "Izaberite PDF fajlove za preklapanje" + }, + "mode": { + "label": "Izaberite režim preklapanja", + "sequential": "Sekvencijalno preklapanje", + "interleaved": "Interleaved preklapanje", + "fixedRepeat": "Fixed Repeat preklapanje" + }, + "counts": { + "label": "Broj preklapanja (za režim Fixed Repeat)", + "placeholder": "Unesite brojeve odvojene zarezom (npr. 2,3,1)" + }, + "position": { + "label": "Izaberite poziciju preklapanja", + "foreground": "Prethodni plan", + "background": "Pozadina" + }, + "submit": "Potvrdi" + }, + "split-by-sections": { + "tags": "Deljenje odeljaka,Deljenje,PodeÅ”avanje", + "title": "Razdvoji PDF po sekcijama", + "header": "Razdvoji PDF u sekcije", + "horizontal": { + "label": "Horizontalne podele", + "placeholder": "Unesite broj horizontalnih podele" + }, + "vertical": { + "label": "Vertikalne podele", + "placeholder": "Unesite broj vertikalnih podele" + }, + "submit": "Razdvoji PDF", + "merge": "Merge Into One PDF" + }, + "AddStampRequest": { + "tags": "Stamp, Add image, center image, Watermark, PDF, Embed, Customize", + "header": "Stamp PDF", + "title": "Stamp PDF", + "stampType": "Stamp Type", + "stampText": "Stamp Text", + "stampImage": "Stamp Image", + "alphabet": "Alphabet", + "fontSize": "Font/Image Size", + "rotation": "Rotation", + "opacity": "Opacity", + "position": "Position", + "overrideX": "Override X Coordinate", + "overrideY": "Override Y Coordinate", + "customMargin": "Custom Margin", + "customColor": "Custom Text Color", + "submit": "Submit" + }, + "removeImagePdf": { + "tags": "Remove Image,Page operations,Back end,server side" + }, + "splitPdfByChapters": { + "tags": "split,chapters,bookmarks,organize" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Replace-Invert-Color", + "header": "Replace-Invert Color PDF", + "selectText": { + "1": "Replace or Invert color Options", + "2": "Default(Default high contrast colors)", + "3": "Custom(Customized colors)", + "4": "Full-Invert(Invert all colors)", + "5": "High contrast color options", + "6": "white text on black background", + "7": "Black text on white background", + "8": "Yellow text on black background", + "9": "Green text on black background", + "10": "Choose text Color", + "11": "Choose background Color" + }, + "submit": "Replace" + }, + "replaceColorPdf": { + "tags": "Replace Color,Page operations,Back end,server side" + }, + "login": { + "title": "Prijavite se", + "header": "Prijavite se", + "signin": "Prijavite se", + "rememberme": "Zapamti me", + "invalid": "Neispravno korisničko ime ili lozinka.", + "locked": "VaÅ” nalog je zaključan.", + "signinTitle": "Molimo vas da se prijavite", + "ssoSignIn": "Prijavite se putem jedinstvene prijave", + "oAuth2AutoCreateDisabled": "OAUTH2 automatsko kreiranje korisnika je onemogućeno", + "oAuth2AdminBlockedUser": "Registration or logging in of non-registered users is currently blocked. Please contact the administrator.", + "oauth2RequestNotFound": "Authorization request not found", + "oauth2InvalidUserInfoResponse": "Invalid User Info Response", + "oauth2invalidRequest": "Invalid Request", + "oauth2AccessDenied": "Access Denied", + "oauth2InvalidTokenResponse": "Invalid Token Response", + "oauth2InvalidIdToken": "Invalid Id Token", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "User is deactivated, login is currently blocked with this username. Please contact the administrator.", + "alreadyLoggedIn": "You are already logged in to", + "alreadyLoggedIn2": "devices. Please log out of the devices and try again.", + "toManySessions": "You have too many active sessions", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF u Jednu Stranicu", + "header": "PDF u Jednu Stranicu", + "submit": "Konvertuj u Jednu Stranicu" + }, + "pageExtracter": { + "title": "Izdvajanje stranica", + "header": "Izdvajanje stranica", + "submit": "Izdvoji", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "sanitizePDF": { + "title": "Sanitizacija PDF-a", + "header": "Sanitizacija PDF fajla", + "selectText": { + "1": "Ukloni JavaScript akcije", + "2": "Ukloni ugrađene fajlove", + "3": "Remove XMP metadata", + "4": "Ukloni linkove", + "5": "Ukloni fontove", + "6": "Remove Document Info Metadata" + }, + "submit": "Sanitizuj PDF" + }, + "adjustContrast": { + "title": "Podesi Kontrast", + "header": "Podesi Kontrast", + "contrast": "Kontrast:", + "brightness": "Osvetljenje:", + "saturation": "Zasićenje:", + "download": "Preuzmi" + }, + "compress": { + "title": "Kompresija", + "header": "Kompresuj PDF", + "credit": "Ova usluga koristi qpdf za kompresiju / optimizaciju PDF-a.", + "grayscale": { + "label": "Primeni sivinu za kompresiju" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Nivo optimizacije:", + "4": "Automatski režim - Automatski prilagođava kvalitet kako bi PDF bio tačne veličine", + "5": "Očekivana veličina PDF-a (npr. 25MB, 10.8MB, 25KB)" + }, + "submit": "Kompresuj" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "Uklanjanje stranica", + "header": "Uklanjanje stranica iz PDF-a", + "pagesToDelete": "Stranice za brisanje (Unesite listu brojeva stranica odvojenih zarezima) :", + "submit": "ObriÅ”i stranice", + "placeholder": "(e.g. 1,2,6 or 1-10,15-30)" + }, + "imageToPDF": { + "title": "Slika u PDF", + "header": "Slika u PDF", + "submit": "Konvertuj", + "selectLabel": "Opcije prilagođavanja slike", + "fillPage": "Popuni stranicu", + "fitDocumentToImage": "Prilagodi stranicu slici", + "maintainAspectRatio": "Očuvaj proporcije", + "selectText": { + "2": "Automatsko rotiranje PDF-a", + "3": "Logika za viÅ”e fajlova (Omogućeno samo ako radite sa viÅ”e slika)", + "4": "Spoji u jedan PDF", + "5": "Konvertuj u odvojene PDF-ove" + } + }, + "PDFToCSV": { + "title": "PDF u CSV", + "header": "PDF u CSV", + "prompt": "Izaberite stranicu za ekstrakciju tabele", + "submit": "Izvuci" + }, + "split-by-size-or-count": { + "title": "Razdvoji PDF po veličini ili broju", + "header": "Razdvoji PDF po veličini ili broju", + "type": { + "label": "Izaberite tip razdvajanja", + "size": "Po veličini", + "pageCount": "Po broju stranica", + "docCount": "Po broju dokumenata" + }, + "value": { + "label": "Unesite vrednost", + "placeholder": "Unesite veličinu (npr. 2MB ili 3KB) ili broj (npr. 5)" + }, + "submit": "Potvrdi" + }, + "printFile": { + "title": "Print File", + "header": "Print File to Printer", + "selectText": { + "1": "Select File to Print", + "2": "Enter Printer Name" + }, + "submit": "Print" + }, + "licenses": { + "nav": "Licenses", + "title": "3rd Party Licenses", + "header": "3rd Party Licenses", + "module": "Module", + "version": "Version", + "license": "License" + }, + "survey": { + "nav": "Survey", + "title": "Stirling-PDF Survey", + "description": "Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!", + "changes": "Stirling-PDF has changed since the last survey! To find out more please check our blog post here:", + "changes2": "With these changes we are getting paid business support and funding", + "please": "Please consider taking our survey!", + "disabled": "(Survey popup will be disabled in following updates but available at foot of page)", + "button": "Take Survey", + "dontShowAgain": "Don't show again", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Remove image", + "header": "Remove image", + "removeImage": "Remove image", + "submit": "Remove image" + }, + "splitByChapters": { + "title": "Split PDF by Chapters", + "header": "Split PDF by Chapters", + "bookmarkLevel": "Bookmark Level", + "includeMetadata": "Include Metadata", + "allowDuplicates": "Allow Duplicates", + "desc": { + "1": "This tool splits a PDF file into multiple PDFs based on its chapter structure.", + "2": "Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).", + "3": "Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.", + "4": "Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs." + }, + "submit": "Split PDF" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Releases", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Current Release" + }, + "note": "Release notes are only available in English" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/sv-SE/translation.json b/frontend/public/locales/sv-SE/translation.json new file mode 100644 index 000000000..158f5b762 --- /dev/null +++ b/frontend/public/locales/sv-SE/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Teckenstorlek", + "fontName": "Typsnitt", + "title": "LƤgg till sidnummer", + "header": "LƤgg till sidnummer", + "selectText": { + "1": "VƤlj PDF-fil:", + "2": "Marginalstorlek", + "3": "Position", + "4": "Startnummer", + "5": "Sidor att numrera", + "6": "Anpassad text" + }, + "customTextDesc": "Anpassad text", + "numberPagesDesc": "Vilka sidor som ska numreras, standard 'all', accepterar Ƥven 1-5 eller 2,5,9 etc", + "customNumberDesc": "Standard Ƥr {n}, accepterar Ƥven 'Sida {n} av {total}', 'Text-{n}', '{filnamn}-{n}", + "submit": "LƤgg till sidnummer" + }, + "pdfPrompt": "VƤlj PDF(er)", + "multiPdfPrompt": "VƤlj PDF-filer (2+)", + "multiPdfDropPrompt": "VƤlj (eller dra och slƤpp) alla PDF-filer du behƶver", + "imgPrompt": "VƤlj bild(er)", + "genericSubmit": "Skicka", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Varning: Denna process kan ta upp till en minut beroende pĆ„ filstorlek", + "pageOrderPrompt": "Sidordning (Ange en kommaseparerad lista med sidnummer) :", + "pageSelectionPrompt": "Anpassat sidval (Ange en kommaseparerad lista med sidnummer 1,5,6 eller funktioner som 2n+1) :", + "goToPage": "GĆ„ till", + "true": "Sant", + "false": "Falskt", + "unknown": "OkƤnt", + "save": "Spara", + "saveToBrowser": "Spara till webblƤsare", + "close": "StƤng", + "filesSelected": "filer valda", + "noFavourites": "Inga favoriter har lagts till", + "downloadComplete": "Nedladdning klar", + "bored": "Trƶtt pĆ„ att vƤnta?", + "alphabet": "Alfabet", + "downloadPdf": "Ladda ner PDF", + "text": "Text", + "font": "Teckensnitt", + "selectFillter": "-- VƤlj --", + "pageNum": "Sidnummer", + "sizes": { + "small": "Liten", + "medium": "Mellan", + "large": "Stor", + "x-large": "Extra stor" + }, + "error": { + "pdfPassword": "PDF-dokumentet Ƥr lƶsenordsskyddat och antingen har lƶsenordet inte angetts eller Ƥr felaktigt", + "_value": "Fel", + "sorry": "Vi beklagar problemet!", + "needHelp": "Behƶver du hjƤlp / Har du hittat ett problem?", + "contactTip": "Om du fortfarande har problem, tveka inte att kontakta oss fƶr hjƤlp. Du kan skicka in en frĆ„ga pĆ„ vĆ„r GitHub-sida eller kontakta oss via Discord:", + "404": { + "head": "404 - Sidan hittades inte | Hoppsan, vi snubblade i koden!", + "1": "Vi kan inte hitta sidan du letar efter.", + "2": "NĆ„got gick fel" + }, + "github": "Skicka in en frĆ„ga pĆ„ GitHub", + "showStack": "Visa stackspĆ„rning", + "copyStack": "Kopiera stackspĆ„rning", + "githubSubmit": "GitHub - Skicka in en frĆ„ga", + "discordSubmit": "Discord - Skicka in ett supportinlƤgg" + }, + "delete": "Radera", + "username": "AnvƤndarnamn", + "password": "Lƶsenord", + "welcome": "VƤlkommen", + "property": "Egenskap", + "black": "Svart", + "white": "Vit", + "red": "Rƶd", + "green": "Grƶn", + "blue": "BlĆ„", + "custom": "Anpassad...", + "WorkInProgess": "PĆ„gĆ„ende arbete, kan vara icke fungerande eller buggigt. Rapportera eventuella problem!", + "poweredBy": "Drivs av", + "yes": "Ja", + "no": "Nej", + "changedCredsMessage": "Inloggningsuppgifter Ƥndrade!", + "notAuthenticatedMessage": "AnvƤndaren Ƥr inte autentiserad.", + "userNotFoundMessage": "AnvƤndaren hittades inte.", + "incorrectPasswordMessage": "Nuvarande lƶsenord Ƥr felaktigt.", + "usernameExistsMessage": "Nytt anvƤndarnamn finns redan.", + "invalidUsernameMessage": "Ogiltigt anvƤndarnamn, anvƤndarnamn kan endast innehĆ„lla bokstƤver, siffror och fƶljande specialtecken @._+- eller mĆ„ste vara en giltig e-postadress.", + "invalidPasswordMessage": "Lƶsenordet fĆ„r inte vara tomt och fĆ„r inte ha mellanslag i bƶrjan eller slutet.", + "confirmPasswordErrorMessage": "Nytt lƶsenord och bekrƤfta nytt lƶsenord mĆ„ste matcha.", + "deleteCurrentUserMessage": "Kan inte ta bort den fƶr nƤrvarande inloggade anvƤndaren.", + "deleteUsernameExistsMessage": "AnvƤndarnamnet finns inte och kan inte raderas.", + "downgradeCurrentUserMessage": "Kan inte nedgradera nuvarande anvƤndares roll", + "disabledCurrentUserMessage": "Den nuvarande anvƤndaren kan inte inaktiveras", + "downgradeCurrentUserLongMessage": "Kan inte nedgradera nuvarande anvƤndares roll. DƤrfƶr kommer den aktuella anvƤndaren inte att visas.", + "userAlreadyExistsOAuthMessage": "AnvƤndaren finns redan som en OAuth2-anvƤndare.", + "userAlreadyExistsWebMessage": "AnvƤndaren finns redan som en webbanvƤndare.", + "oops": "Hoppsan!", + "help": "HjƤlp", + "goHomepage": "GĆ„ till startsidan", + "joinDiscord": "GĆ„ med i vĆ„r Discord-server", + "seeDockerHub": "Se Docker Hub", + "visitGithub": "Besƶk GitHub-repositoriet", + "donate": "Donera", + "color": "FƤrg", + "sponsor": "Sponsƶr", + "info": "Info", + "pro": "Pro", + "page": "Sidan", + "pages": "Sidor", + "loading": "Laddar...", + "addToDoc": "LƤgg till i dokument", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Dataprotektionspolicy", + "terms": "Villkor och betingelser", + "accessibility": "GƤngeshĆ„llbarhet", + "cookie": "Cockiropfer", + "impressum": "Riksdagens utskott fƶr teknikfrihet", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Pipeline-meny (Beta)", + "uploadButton": "Ladda upp anpassad", + "configureButton": "Konfigurera", + "defaultOption": "Anpassad", + "submitButton": "Skicka", + "help": "Pipeline-hjƤlp", + "scanHelp": "HjƤlp fƶr mappskanning", + "deletePrompt": "Ƅr du sƤker pĆ„ att du vill ta bort pipeline", + "tags": "automatisera,sekvens,skriptad,batchprocess", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Pipeline-konfiguration", + "pipelineNameLabel": "Pipeline-namn", + "saveSettings": "Spara operationsinstƤllningar", + "pipelineNamePrompt": "Ange pipeline-namn hƤr", + "selectOperation": "VƤlj operation", + "addOperationButton": "LƤgg till operation", + "pipelineHeader": "Pipeline:", + "saveButton": "Ladda ner", + "validateButton": "Validera" + }, + "enterpriseEdition": { + "button": "Uppgradera till Pro", + "warning": "Den hƤr funktionen Ƥr endast tillgƤnglig fƶr Pro-anvƤndare.", + "yamlAdvert": "Stirling PDF Pro stƶder YAML-konfigurationsfiler och andra SSO funktioner.", + "ssoAdvert": "Sƶker du fler funktioner fƶr anvƤndarhantering? Spana in Stirling PDF Pro." + }, + "analytics": { + "title": "Vill du gƶra Stirling PDF bƤttre?", + "paragraph1": "Stirling PDF har inaktiverad analys fƶr att hjƤlpa oss fƶrbƤttra produkten. Vi spĆ„rar ingen personlig information eller filinnehĆ„ll.", + "paragraph2": "Var god aktivera analyser fƶr att hjƤlpa Stirling-PDF att vƤxa och tillĆ„ta oss att fƶrstĆ„ vĆ„ra anvƤndare bƤttre.", + "enable": "Aktivera analys", + "disable": "Avaktivera analys", + "settings": "Du kan Ƥndra analysinstƤllningarna i config/settings.yml-filen" + }, + "navbar": { + "favorite": "Favoriter", + "recent": "New and recently updated", + "darkmode": "Mƶrkt lƤge", + "language": "SprĆ„k", + "settings": "InstƤllningar", + "allTools": "Verktyg", + "multiTool": "Multiverktyg", + "search": "Search", + "sections": { + "organize": "Organisera", + "convertTo": "Konvertera till PDF", + "convertFrom": "Konvertera frĆ„n PDF", + "security": "Signera & SƤkerhet", + "advance": "Avancerat", + "edit": "Visa & Redigera", + "popular": "PopulƤra" + } + }, + "settings": { + "title": "InstƤllningar", + "update": "Uppdatering tillgƤnglig", + "updateAvailable": "{0} Ƥr den aktuella installerade versionen. En ny version ({1}) finns tillgƤnglig.", + "appVersion": "Appversion:", + "downloadOption": { + "title": "VƤlj nedladdningsalternativ (fƶr nedladdning av en fil utan zip):", + "1": "Ɩppnas i samma fƶnster", + "2": "Ɩppna i nytt fƶnster", + "3": "Ladda ner fil" + }, + "zipThreshold": "Zippa filer nƤr antalet nedladdade filer ƶverskrider", + "signOut": "Logga ut", + "accountSettings": "KontoinstƤllningar", + "bored": { + "help": "Aktiverar pĆ„skƤggsspel" + }, + "cacheInputs": { + "name": "Spara formulƤrinmatningar", + "help": "Aktivera fƶr att lagra tidigare anvƤnda inmatningar fƶr framtida kƶrningar" + } + }, + "changeCreds": { + "title": "Ƅndra inloggningsuppgifter", + "header": "Uppdatera dina kontouppgifter", + "changePassword": "Du anvƤnder standardinloggningsuppgifter. VƤnligen ange ett nytt lƶsenord", + "newUsername": "Nytt anvƤndarnamn", + "oldPassword": "Nuvarande lƶsenord", + "newPassword": "Nytt lƶsenord", + "confirmNewPassword": "BekrƤfta nytt lƶsenord", + "submit": "Skicka Ƥndringar" + }, + "account": { + "title": "KontoinstƤllningar", + "accountSettings": "KontoinstƤllningar", + "adminSettings": "AdmininstƤllningar - Visa och lƤgg till anvƤndare", + "userControlSettings": "AnvƤndarhanteringsinstƤllningar", + "changeUsername": "Ƅndra anvƤndarnamn", + "newUsername": "Nytt anvƤndarnamn", + "password": "BekrƤftelselƶsenord", + "oldPassword": "Gammalt lƶsenord", + "newPassword": "Nytt lƶsenord", + "changePassword": "Ƅndra lƶsenord", + "confirmNewPassword": "BekrƤfta nytt lƶsenord", + "signOut": "Logga ut", + "yourApiKey": "Din API-nyckel", + "syncTitle": "Synkronisera webblƤsarinstƤllningar med konto", + "settingsCompare": "JƤmfƶrelse av instƤllningar:", + "property": "Egenskap", + "webBrowserSettings": "WebblƤsarinstƤllning", + "syncToBrowser": "Synkronisera konto -> webblƤsare", + "syncToAccount": "Synkronisera konto <- webblƤsare" + }, + "adminUserSettings": { + "title": "AnvƤndarhanteringsinstƤllningar", + "header": "AdmininstƤllningar fƶr anvƤndarhantering", + "admin": "Admin", + "user": "AnvƤndare", + "addUser": "LƤgg till ny anvƤndare", + "deleteUser": "Ta bort anvƤndare", + "confirmDeleteUser": "Ska anvƤndaren tas bort?", + "confirmChangeUserStatus": "Ska anvƤndaren inaktiveras/aktiveras?", + "usernameInfo": "AnvƤndarnamn kan endast innehĆ„lla bokstƤver, siffror och fƶljande specialtecken @._+- eller mĆ„ste vara en giltig e-postadress.", + "roles": "Roller", + "role": "Roll", + "actions": "ƅtgƤrder", + "apiUser": "BegrƤnsad API-anvƤndare", + "extraApiUser": "Ytterligare begrƤnsad API-anvƤndare", + "webOnlyUser": "Endast webbanvƤndare", + "demoUser": "DemoanvƤndare (Inga anpassade instƤllningar)", + "internalApiUser": "Intern API-anvƤndare", + "forceChange": "Tvinga anvƤndare att Ƥndra lƶsenord vid inloggning", + "submit": "Spara anvƤndare", + "changeUserRole": "Ƅndra anvƤndarens roll", + "authenticated": "Autentiserad", + "editOwnProfil": "Redigera egen profil", + "enabledUser": "aktiverad anvƤndare", + "disabledUser": "inaktiverad anvƤndare", + "activeUsers": "Aktiva anvƤndare:", + "disabledUsers": "Inaktiverade anvƤndare:", + "totalUsers": "Totalt antal anvƤndare:", + "lastRequest": "Senaste begƤran", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Databasimport/export", + "header": "Databasimport/export", + "fileName": "Filnamn", + "creationDate": "Skapelsedatum", + "fileSize": "Filstorlek", + "deleteBackupFile": "Ta bort sƤkerhetskopieringsfil", + "importBackupFile": "Importera sƤkerhetskopieringsfil", + "createBackupFile": "Skapa sƤkerhetskopieringsfil", + "downloadBackupFile": "Ladda ner sƤkerhetskopieringsfil", + "info_1": "Vid import av data Ƥr det avgƶrande att sƤkerstƤlla korrekt struktur. Om du Ƥr osƤker pĆ„ vad du gƶr, sƶk rĆ„d och stƶd frĆ„n en professionell. Ett fel i strukturen kan orsaka funktionsfel i applikationen, upp till och inklusive fullstƤndig ofƶrmĆ„ga att kƶra applikationen.", + "info_2": "Filnamnet spelar ingen roll vid uppladdning. Det kommer att dƶpas om efterĆ„t fƶr att fƶlja formatet backup_user_yyyyMMddHHmm.sql, vilket sƤkerstƤller en konsekvent namngivningskonvention.", + "submit": "Importera sƤkerhetskopia", + "importIntoDatabaseSuccessed": "Import till databas lyckades", + "backupCreated": "Backup av databas lyckades", + "fileNotFound": "Filen hittades inte", + "fileNullOrEmpty": "Filen fĆ„r inte vara null eller tom", + "failedImportFile": "Misslyckades med att importera fil", + "notSupported": "Denna funktion Ƥr inte tillgƤnglig fƶr din databasanslutning." + }, + "session": { + "expired": "Din session har lƶpt ut. Uppdatera sidan och fƶrsƶk igen.", + "refreshPage": "Uppdatera sida" + }, + "home": { + "desc": "Din lokala one-stop-shop fƶr alla dina PDF-behov.", + "searchBar": "Sƶk efter funktioner...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Visa, kommentera, lƤgg till text eller bilder" + }, + "setFavorites": "VƤlj Favoriter", + "hideFavorites": "Dƶlj Favoriter", + "showFavorites": "Visa Favoriter", + "legacyHomepage": "Gammal Hem-vy.", + "newHomePage": "Testa vĆ„r nya Hem-vy!", + "alphabetical": "Alfabetisk", + "globalPopularity": "Global Popularity", + "sortBy": "Sortera efter:", + "multiTool": { + "title": "PDF Multi-verktyg", + "desc": "Sammanfoga, rotera, ordna om och ta bort sidor" + }, + "merge": { + "title": "Sammanfoga", + "desc": "Sammanfoga enkelt flera PDF-filer till en." + }, + "split": { + "title": "Dela", + "desc": "Dela upp PDF-filer i flera dokument" + }, + "rotate": { + "title": "Rotera", + "desc": "Rotera enkelt dina PDF-filer." + }, + "imageToPdf": { + "title": "Bild till PDF", + "desc": "Konvertera en bild (PNG, JPEG, GIF) till PDF." + }, + "pdfToImage": { + "title": "PDF till bild", + "desc": "Konvertera en PDF till en bild. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Ordna", + "desc": "Ta bort/ordna om sidor i valfri ordning" + }, + "addImage": { + "title": "LƤgg till bild", + "desc": "LƤgger till en bild pĆ„ en angiven plats i PDF:en (pĆ„gĆ„r arbete)" + }, + "watermark": { + "title": "LƤgg till vattenstƤmpel", + "desc": "LƤgg till en anpassad vattenstƤmpel till ditt PDF-dokument." + }, + "permissions": { + "title": "Ƅndra behƶrigheter", + "desc": "Ƅndra behƶrigheterna fƶr ditt PDF-dokument" + }, + "removePages": { + "title": "Ta bort", + "desc": "Ta bort oƶnskade sidor frĆ„n ditt PDF-dokument." + }, + "addPassword": { + "title": "LƤgg till lƶsenord", + "desc": "Kryptera ditt PDF-dokument med ett lƶsenord." + }, + "removePassword": { + "title": "Ta bort lƶsenord", + "desc": "Ta bort lƶsenordsskydd frĆ„n ditt PDF-dokument." + }, + "compressPdfs": { + "title": "Komprimera", + "desc": "Komprimera PDF-filer fƶr att minska deras filstorlek." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Ƅndra metadata", + "desc": "Ƅndra/ta bort/lƤgg till metadata frĆ„n ett PDF-dokument" + }, + "fileToPDF": { + "title": "Konvertera fil till PDF", + "desc": "Konvertera nƤstan vilken fil som helst till PDF (DOCX, PNG, XLS, PPT, TXT och mer)" + }, + "ocr": { + "title": "OCR / Rensningsskanningar", + "desc": "Rengƶr skanningar och upptƤcker text frĆ„n bilder i en PDF och lƤgger till den igen som text." + }, + "extractImages": { + "title": "Extrahera bilder", + "desc": "Extraherar alla bilder frĆ„n en PDF och sparar dem till zip" + }, + "pdfToPDFA": { + "title": "PDF till PDF/A", + "desc": "Konvertera PDF till PDF/A fƶr lĆ„ngtidslagring" + }, + "PDFToWord": { + "title": "PDF till Word", + "desc": "Konvertera PDF till Word-format (DOC, DOCX och ODT)" + }, + "PDFToPresentation": { + "title": "PDF till presentation", + "desc": "Konvertera PDF till presentationsformat (PPT, PPTX och ODP)" + }, + "PDFToText": { + "title": "PDF till text/RTF", + "desc": "Konvertera PDF till text- eller RTF-format" + }, + "PDFToHTML": { + "title": "PDF till HTML", + "desc": "Konvertera PDF till HTML-format" + }, + "PDFToXML": { + "title": "PDF till XML", + "desc": "Konvertera PDF till XML-format" + }, + "ScannerImageSplit": { + "title": "Detektera/Dela skannade foton", + "desc": "Delar flera foton frĆ„n ett foto/PDF" + }, + "sign": { + "title": "Signera", + "desc": "LƤgger till signatur till PDF genom ritning, text eller bild" + }, + "flatten": { + "title": "Platta till", + "desc": "Ta bort alla interaktiva element och formulƤr frĆ„n en PDF" + }, + "repair": { + "title": "Reparera", + "desc": "Fƶrsƶker reparera en korrupt/trasig PDF" + }, + "removeBlanks": { + "title": "Ta bort tomma sidor", + "desc": "KƤnner av och tar bort tomma sidor frĆ„n ett dokument" + }, + "removeAnnotations": { + "title": "Ta bort anteckningar", + "desc": "Tar bort alla kommentarer/anteckningar frĆ„n en PDF" + }, + "compare": { + "title": "JƤmfƶr", + "desc": "JƤmfƶr och visar skillnaderna mellan 2 PDF-dokument" + }, + "certSign": { + "title": "Signera med certifikat", + "desc": "Signerar en PDF med ett certifikat/nyckel (PEM/P12)" + }, + "removeCertSign": { + "title": "Ta bort certifikatsignatur", + "desc": "Ta bort certifikatsignatur frĆ„n PDF" + }, + "pageLayout": { + "title": "Flersidigt layout", + "desc": "SlĆ„ samman flera sidor av ett PDF-dokument till en enda sida" + }, + "scalePages": { + "title": "Justera sidstorlek/skala", + "desc": "Ƅndra storleken/skalan pĆ„ sidan och/eller dess innehĆ„ll." + }, + "pipeline": { + "title": "Pipeline (Avancerat)", + "desc": "Kƶr flera Ć„tgƤrder pĆ„ PDF:er genom att definiera pipeline-skript" + }, + "add-page-numbers": { + "title": "LƤgg till sidnummer", + "desc": "LƤgg till sidnummer genom hela dokumentet pĆ„ en angiven plats" + }, + "auto-rename": { + "title": "Automatiskt byt namn pĆ„ PDF-fil", + "desc": "Byter automatiskt namn pĆ„ en PDF-fil baserat pĆ„ dess detekterade rubrik" + }, + "adjust-contrast": { + "title": "Justera fƤrger/kontrast", + "desc": "Justera kontrast, mƤttnad och ljusstyrka i en PDF" + }, + "crop": { + "title": "BeskƤr PDF", + "desc": "BeskƤr en PDF fƶr att minska dess storlek (behĆ„ller text!)" + }, + "autoSplitPDF": { + "title": "Auto-dela sidor", + "desc": "Auto-dela skannad PDF med fysisk skannad sidseparator QR-kod" + }, + "sanitizePdf": { + "title": "Sanera", + "desc": "Ta bort skript och andra element frĆ„n PDF-filer" + }, + "URLToPDF": { + "title": "URL/Webbplats till PDF", + "desc": "Konverterar valfri http(s)URL till PDF" + }, + "HTMLToPDF": { + "title": "HTML till PDF", + "desc": "Konverterar valfri HTML-fil eller zip till PDF" + }, + "MarkdownToPDF": { + "title": "Markdown till PDF", + "desc": "Konverterar valfri Markdown-fil till PDF" + }, + "PDFToMarkdown": { + "title": "PDF till Markdown", + "desc": "Konvertera PDF till Markdown" + }, + "getPdfInfo": { + "title": "HƤmta ALL information om PDF", + "desc": "HƤmtar all mƶjlig information om PDF:er" + }, + "extractPage": { + "title": "Extrahera sida(or)", + "desc": "Extraherar valda sidor frĆ„n PDF" + }, + "PdfToSinglePage": { + "title": "PDF till en enda stor sida", + "desc": "SlĆ„r samman alla PDF-sidor till en enda stor sida" + }, + "showJS": { + "title": "Visa Javascript", + "desc": "Sƶker och visar eventuell JS som injicerats i en PDF" + }, + "autoRedact": { + "title": "Auto-redigera", + "desc": "Auto-redigerar (svƤrtar) text i en PDF baserat pĆ„ inmatad text" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF till CSV", + "desc": "Extraherar tabeller frĆ„n en PDF och konverterar dem till CSV" + }, + "autoSizeSplitPDF": { + "title": "Auto-dela efter storlek/antal", + "desc": "Dela en enda PDF till flera dokument baserat pĆ„ storlek, sidantal eller dokumentantal" + }, + "overlay-pdfs": { + "title": "Ɩverlagra PDF:er", + "desc": "Ɩverlagrar PDF:er ovanpĆ„ en annan PDF" + }, + "split-by-sections": { + "title": "Dela PDF efter sektioner", + "desc": "Dela varje sida av en PDF i mindre horisontella och vertikala sektioner" + }, + "AddStampRequest": { + "title": "LƤgg till stƤmpel pĆ„ PDF", + "desc": "LƤgg till text eller bildstƤmplar pĆ„ angivna platser" + }, + "removeImagePdf": { + "title": "Ta bort bild", + "desc": "Ta bort bild frĆ„n PDF fƶr att minska filstorlek" + }, + "splitPdfByChapters": { + "title": "Dela upp PDF efter kapitel", + "desc": "Dela upp en PDF till flera filer baserat pĆ„ dess kapitelstruktur." + }, + "validateSignature": { + "title": "Validera PDF signature", + "desc": "Verifiera digitala signaturer och certifiakt i PDF dokument" + }, + "replaceColorPdf": { + "title": "ErsƤtt och Invertera fƤrg", + "desc": "ErsƤtt fƤrg fƶr text och bakgrund i PDF och invertera hela fƤrgen pĆ„ PDF fƶr att minska filstorlek" + } + }, + "viewPdf": { + "tags": "visa,lƤs,kommentera,text,bild", + "title": "View/Edit PDF", + "header": "Visa PDF" + }, + "multiTool": { + "tags": "Multiverktyg,Multioperation,UI,klicka dra,front end,klientsida", + "title": "PDF-multiverktyg", + "header": "PDF Multi-verktyg", + "uploadPrompts": "Filnamn", + "selectAll": "VƤlj allt", + "deselectAll": "Deselect All", + "selectPages": "VƤlj sidor", + "selectedPages": "Valda sidor", + "page": "Sida", + "deleteSelected": "Ta bort valda", + "downloadAll": "Exportera", + "downloadSelected": "Exportersa valda", + "insertPageBreak": "Insert Page Break", + "addFile": "LƤgg till fil", + "rotateLeft": "Rotera VƤnster", + "rotateRight": "Rotera Hƶger", + "split": "Dela upp", + "moveLeft": "Flytta VƤnster", + "moveRight": "Flytta Hƶger", + "delete": "Ta bort", + "dragDropMessage": "Valda sid(or)", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "sammanfoga,Sidoperationer,Backend,serversida", + "title": "Sammanfoga", + "header": "SlĆ„ samman flera PDF-filer (2+)", + "sortByName": "Sortera efter namn", + "sortByDate": "Sortera efter datum", + "removeCertSign": "Ta bort digital signatur i den sammanslagna filen?", + "submit": "SlĆ„ samman" + }, + "split": { + "tags": "Sidoperationer,dela,Multisida,klippa,serversida", + "title": "Dela upp PDF", + "header": "Dela upp PDF", + "desc": { + "1": "Siffrorna du vƤljer Ƥr sidnumret du vill gƶra en delning pĆ„", + "2": "Som sĆ„dan skulle ett val av 1,3,7-9 dela upp ett 10-sidigt dokument i 6 separata PDF-filer med:", + "3": "Dokument #1: Sida 1", + "4": "Dokument #2: Sida 2 och 3", + "5": "Dokument #3: Sida 4, 5, 6 och 7", + "6": "Dokument #4: Sida 8", + "7": "Dokument #5: Sida 9", + "8": "Dokument #6: Sida 10" + }, + "splitPages": "Ange sidor att dela pĆ„:", + "submit": "Dela" + }, + "rotate": { + "tags": "serversida", + "title": "Rotera PDF", + "header": "Rotera PDF", + "selectAngle": "VƤlj rotationsvinkel (i multipler av 90 grader):", + "submit": "Rotera" + }, + "imageToPdf": { + "tags": "konvertering,img,jpg,bild,foto" + }, + "pdfToImage": { + "tags": "konvertering,img,jpg,bild,foto", + "title": "PDF till bild", + "header": "PDF till bild", + "selectText": "Bildformat", + "singleOrMultiple": "Bildresultattyp", + "single": "Enstaka stor bild", + "multi": "Flera bilder", + "colorType": "FƤrgtyp", + "color": "FƤrg", + "grey": "GrĆ„skala", + "blackwhite": "Svartvitt (kan fƶrlora data!)", + "submit": "Konvertera", + "info": "Python Ƥr inte installerat. KrƤvs fƶr WebP-konvertering.", + "placeholder": "(t.ex. 1,2,8 eller 4,7,12-16 eller 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,jƤmn,udda,sortera,flytta", + "title": "Sidorganisatƶr", + "header": "PDF-sidorganisatƶr", + "submit": "Ordna om sidor", + "mode": { + "_value": "LƤge", + "1": "Anpassad sidordning", + "2": "OmvƤnd ordning", + "3": "Duplexsortering", + "4": "HƤftessortering", + "5": "SidohƤftad hƤftessortering", + "6": "Udda-jƤmn delning", + "7": "Ta bort fƶrsta", + "8": "Ta bort sista", + "9": "Ta bort fƶrsta och sista", + "10": "Udda-jƤmn sammanslagning", + "11": "Duplicate all pages" + }, + "placeholder": "(t.ex. 1,3,2 eller 4-8,2,10-12 eller 2n-1)" + }, + "addImage": { + "tags": "img,jpg,bild,foto", + "title": "LƤgg till bild", + "header": "LƤgg till bild till PDF", + "everyPage": "Varje sida?", + "upload": "LƤgg till bild", + "submit": "LƤgg till bild" + }, + "watermark": { + "tags": "Text,upprepande,etikett,egen,upphovsrƤtt,varumƤrke,img,jpg,bild,foto", + "title": "LƤgg till vattenstƤmpel", + "header": "LƤgg till vattenstƤmpel", + "customColor": "Anpassad textfƤrg", + "selectText": { + "1": "VƤlj PDF fƶr att lƤgga till vattenstƤmpel till:", + "2": "VattenmƤrkestext:", + "3": "Teckenstorlek:", + "4": "VƤndning (0-360):", + "5": "Width Spacer (mellanrum mellan varje vattenstƤmpel horisontellt):", + "6": "Height Spacer (mellanrum mellan varje vattenstƤmpel vertikalt):", + "7": "Opacitet (0% - 100%):", + "8": "VattenstƤmpeltyp:", + "9": "VattenstƤmpelbild:", + "10": "Konvertera PDF till PDF-bild" + }, + "submit": "LƤgg till vattenstƤmpel", + "type": { + "1": "Text", + "2": "Bild" + } + }, + "permissions": { + "tags": "lƤsa,skriva,redigera,skriva ut", + "title": "Ƅndra behƶrigheter", + "header": "Ƅndra behƶrigheter", + "warning": "Varning: fƶr att dessa behƶrigheter ska vara ofƶrƤnderliga rekommenderas det att stƤlla in dem med ett lƶsenord via sidan LƤgg till lƶsenord", + "selectText": { + "1": "VƤlj PDF fƶr att Ƥndra behƶrigheter", + "2": "Behƶrigheter att stƤlla in", + "3": "Fƶrhindra sammansƤttning av dokument", + "4": "Fƶrhindra innehĆ„llsextraktion", + "5": "Fƶrhindra extraktion fƶr tillgƤnglighet", + "6": "Fƶrhindra att fylla i formulƤr", + "7": "Fƶrhindra Ƥndring", + "8": "Fƶrhindra anteckningsƤndring", + "9": "Fƶrhindra utskrift", + "10": "Fƶrhindra utskrift av olika format" + }, + "submit": "Ƅndra" + }, + "removePages": { + "tags": "Ta bort sidor,radera sidor" + }, + "addPassword": { + "tags": "sƤkra,sƤkerhet", + "title": "LƤgg till lƶsenord", + "header": "LƤgg till lƶsenord (kryptera)", + "selectText": { + "1": "VƤlj PDF att kryptera", + "2": "Lƶsenord", + "3": "LƤngd pĆ„ krypteringsnyckeln", + "4": "Hƶgre vƤrden Ƥr starkare, men lƤgre vƤrden har bƤttre kompatibilitet.", + "5": "Behƶrigheter att stƤlla in", + "6": "Fƶrhindra sammansƤttning av dokument", + "7": "Fƶrhindra innehĆ„llsextraktion", + "8": "Fƶrhindra extraktion fƶr tillgƤnglighet", + "9": "Fƶrhindra att fylla i formulƤr", + "10": "Fƶrhindra modifiering", + "11": "Fƶrhindra anteckningsƤndring", + "12": "Fƶrhindra utskrift", + "13": "Fƶrhindra utskrift av olika format", + "14": "Ƅgarlƶsenord", + "15": "BegrƤnsar vad som kan gƶras med dokumentet nƤr det vƤl Ƥr ƶppnat (Stƶds inte av alla lƤsare)", + "16": "BegrƤnsar ƶppnandet av sjƤlva dokumentet" + }, + "submit": "Kryptera" + }, + "removePassword": { + "tags": "sƤkra,Dekryptera,sƤkerhet,ta bort lƶsenord,radera lƶsenord", + "title": "Ta bort lƶsenord", + "header": "Ta bort lƶsenord (Dekryptera)", + "selectText": { + "1": "VƤlj PDF att dekryptera", + "2": "Lƶsenord" + }, + "submit": "Ta bort" + }, + "compressPdfs": { + "tags": "pressa ihop,liten,minimal" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Titel,fƶrfattare,datum,skapelse,tid,utgivare,producent,statistik", + "title": "Titel:", + "header": "Ƅndra metadata", + "selectText": { + "1": "Redigera de variabler du vill Ƥndra", + "2": "Ta bort all metadata", + "3": "Visa anpassade metadata:", + "4": "Andra metadata:", + "5": "LƤgg till anpassad metadatapost" + }, + "author": "Fƶrfattare:", + "creationDate": "Skapningsdatum (ƄƄƄƄ/MM/dd HH:mm:ss):", + "creator": "Skapare:", + "keywords": "Sƶkord:", + "modDate": "Ƅndringsdatum (ƄƄƄƄ/MM/dd HH:mm:ss):", + "producer": "Producent:", + "subject": "Ƅmne:", + "trapped": "FĆ„ngad:", + "submit": "Ƅndra" + }, + "fileToPDF": { + "tags": "transformation,format,dokument,bild,presentation,text,konvertering,kontor,dokument,word,excel,powerpoint", + "title": "Fil till PDF", + "header": "Konvertera valfri fil till PDF", + "credit": "Denna tjƤnst anvƤnder LibreOffice och Unoconv fƶr filkonvertering.", + "supportedFileTypesInfo": "Filtyper som stƶds", + "supportedFileTypes": "Filtyper som stƶds bƶr inkludera nedanstĆ„ende, men fƶr en fullstƤndig uppdaterad lista ƶver format som stƶds, se LibreOffice-dokumentationen", + "submit": "Konvertera till PDF" + }, + "ocr": { + "tags": "igenkƤnning,text,bild,skanna,lƤsa,identifiera,detektering,redigerbar", + "title": "OCR / Rengƶring av skanningar", + "header": "Rengƶring av skanningar / OCR (Optisk teckenigenkƤnning)", + "selectText": { + "1": "VƤlj sprĆ„k som ska upptƤckas i PDF:en (de listade Ƥr de som fƶr nƤrvarande identifieras):", + "2": "Producera en textfil som innehĆ„ller OCR-text tillsammans med den OCR-behandlade PDF-filen", + "3": "Korrigera sidor som skannades i en sned vinkel genom att rotera dem tillbaka pĆ„ plats", + "4": "Rensa sidan sĆ„ att det Ƥr mindre troligt att OCR hittar text i bakgrundsbrus. (Ingen utgĆ„ngsƤndring)", + "5": "Rensa sidan sĆ„ att det Ƥr mindre sannolikt att OCR kommer att hitta text i bakgrundsbrus, upprƤtthĆ„ller rensning i utdata.", + "6": "Ignorerar sidor som har interaktiv text, endast OCR-sidor som Ƥr bilder", + "7": "Tvinga OCR, kommer OCR att ta bort alla ursprungliga textelement", + "8": "Normal (kommer ge fel om PDF innehĆ„ller text)", + "9": "Ytterligare instƤllningar", + "10": "OCR-lƤge", + "11": "Ta bort bilder efter OCR (tar bort ALLA bilder, endast anvƤndbart som en del av konverteringssteget)", + "12": "Renderingstyp (avancerat)" + }, + "help": "VƤnligen lƤs denna dokumentation om hur du anvƤnder detta fƶr andra sprĆ„k och/eller anvƤnder inte i docker", + "credit": "Denna tjƤnst anvƤnder qpdf och Tesseract fƶr OCR.", + "submit": "Bearbeta PDF med OCR" + }, + "extractImages": { + "tags": "bild,foto,spara,arkiv,zip,fĆ„nga,ta", + "title": "Extrahera bilder", + "header": "Extrahera bilder", + "selectText": "VƤlj bildformat att konvertera extraherade bilder till", + "allowDuplicates": "Spara dubblettbilder", + "submit": "Extrahera" + }, + "pdfToPDFA": { + "tags": "arkiv,lĆ„ngtids,standard,konvertering,lagring,bevarande", + "title": "PDF till PDF/A", + "header": "PDF till PDF/A", + "credit": "Denna tjƤnst anvƤnder libreoffice fƶr PDF/A-konvertering", + "submit": "Konvertera", + "tip": "Fungerar fƶr nƤrvarande inte fƶr flera inmatningar samtidigt", + "outputFormat": "Utdataformat", + "pdfWithDigitalSignature": "PDF:en innehĆ„ller en digital signatur. Denna kommer att tas bort i nƤsta steg." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,transformation,format,konvertering,kontor,microsoft,docfil", + "title": "PDF till Word", + "header": "PDF till Word", + "selectText": { + "1": "Utdatafilformat" + }, + "credit": "Denna tjƤnst anvƤnder LibreOffice fƶr filkonvertering.", + "submit": "Konvertera" + }, + "PDFToPresentation": { + "tags": "bildspel,visa,kontor,microsoft", + "title": "PDF till presentation", + "header": "PDF till presentation", + "selectText": { + "1": "Utdatafilformat" + }, + "credit": "Denna tjƤnst anvƤnder LibreOffice fƶr filkonvertering.", + "submit": "Konvertera" + }, + "PDFToText": { + "tags": "rikformat,riktextformat,rich text format", + "title": "PDF till text/RTF", + "header": "PDF till text/RTF", + "selectText": { + "1": "Utdatafilformat" + }, + "credit": "Denna tjƤnst anvƤnder LibreOffice fƶr filkonvertering.", + "submit": "Konvertera" + }, + "PDFToHTML": { + "tags": "webbinnehĆ„ll,webblƤsarvƤnlig", + "title": "PDF till HTML", + "header": "PDF till HTML", + "credit": "Denna tjƤnst anvƤnder pdftohtml fƶr filkonvertering.", + "submit": "Konvertera" + }, + "PDFToXML": { + "tags": "dataextraktion,strukturerat-innehĆ„ll,interop,transformation,konvertera", + "title": "PDF till XML", + "header": "PDF till XML", + "credit": "Denna tjƤnst anvƤnder LibreOffice fƶr filkonvertering.", + "submit": "Konvertera" + }, + "ScannerImageSplit": { + "tags": "separera,auto-detektera,skanningar,multi-foto,organisera", + "selectText": { + "1": "Vinkeltrƶskel:", + "2": "StƤller in den minsta absoluta vinkeln som krƤvs fƶr att bilden ska roteras (standard: 10).", + "3": "Tolerans:", + "4": "BestƤmmer intervallet fƶr fƤrgvariation runt den uppskattade bakgrundsfƤrgen (standard: 30).", + "5": "Minsta area:", + "6": "StƤller in minsta areatrƶskel fƶr ett foto (standard: 10000).", + "7": "Minsta konturarea:", + "8": "StƤller in minsta trƶskelvƤrde fƶr konturarea fƶr ett foto", + "9": "Kantstorlek:", + "10": "StƤller in storleken pĆ„ kanten som lƤggs till och tas bort fƶr att fƶrhindra vita kanter i utdata (standard: 1)." + }, + "info": "Python Ƥr inte installerat. Det krƤvs fƶr att kƶra." + }, + "sign": { + "tags": "auktorisera,initialer,ritad-signatur,text-signatur,bild-signatur", + "title": "Signera", + "header": "Signera PDF-filer", + "upload": "Ladda upp bild", + "draw": "Rita signatur", + "text": "Textinmatning", + "clear": "Rensa", + "add": "LƤgg till", + "saved": "Sparade signaturer", + "save": "Spara signatur", + "personalSigs": "Personliga signaturer", + "sharedSigs": "Delade signaturer", + "noSavedSigs": "Inga sparade signaturer hittades", + "addToAll": "LƤgg till pĆ„ alla sidor", + "delete": "Ta bort", + "first": "Fƶrsta sidan", + "last": "Sista sidan", + "next": "NƤsta sida", + "previous": "FƶregĆ„ende sida", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "statisk,avaktivera,icke-interaktiv,effektivisera", + "title": "Platta till", + "header": "Platta till PDF-filer", + "flattenOnlyForms": "Platta till endast formulƤr", + "submit": "Platta till" + }, + "repair": { + "tags": "fixa,Ć„terstƤlla,korrigering,Ć„terhƤmta", + "title": "Reparera", + "header": "Reparera PDF-filer", + "submit": "Reparera" + }, + "removeBlanks": { + "tags": "stƤda upp,effektivisera,icke-innehĆ„ll,organisera", + "title": "Ta bort tomrum", + "header": "Ta bort tomma sidor", + "threshold": "TrƶskelvƤrde:", + "thresholdDesc": "TrƶskelvƤrde fƶr att bestƤmma hur vit en vit pixel mĆ„ste vara", + "whitePercent": "Vit procent (%):", + "whitePercentDesc": "Procentandel av sidan som mĆ„ste vara vit fƶr att kunna tas bort", + "submit": "Ta bort tomrum" + }, + "removeAnnotations": { + "tags": "kommentarer,markera,anteckningar,markup,ta bort", + "title": "Ta bort anteckningar", + "header": "Ta bort anteckningar", + "submit": "Ta bort" + }, + "compare": { + "tags": "sƤrskilja,kontrastera,Ƥndringar,analys", + "title": "JƤmfƶr", + "header": "JƤmfƶr PDF-filer", + "highlightColor": { + "1": "MarkeringsfƤrg 1:", + "2": "MarkeringsfƤrg 2:" + }, + "document": { + "1": "Dokument 1", + "2": "Dokument 2" + }, + "submit": "JƤmfƶr", + "complex": { + "message": "En eller bĆ„da de angivna dokumenten Ƥr stora filer, jƤmfƶrelseprƤzissen kan minska." + }, + "large": { + "file": { + "message": "En eller bĆ„da de angivna dokumenten Ƥr fƶr stora att bearbeta" + } + }, + "no": { + "text": { + "message": "En eller bĆ„da de valda PDF:erna innehĆ„ller ingen textinnehĆ„ll. VƤlj PDF:er med text fƶr jƤmfƶrelse." + } + } + }, + "certSign": { + "tags": "autentisera,PEM,P12,officiell,kryptera", + "title": "Certifikatsignering", + "header": "Signera en PDF med ditt certifikat (PĆ„gĆ„ende arbete)", + "selectPDF": "VƤlj en PDF-fil fƶr signering:", + "jksNote": "Obs: Om din certifikattyp inte finns listad nedan, vƤnligen konvertera den till en Java Keystore (.jks) fil med hjƤlp av keytool-kommandoradsverktyget. VƤlj sedan .jks-filalternativet nedan.", + "selectKey": "VƤlj din privata nyckelfil (PKCS#8-format, kan vara .pem eller .der):", + "selectCert": "VƤlj din certifikatfil (X.509-format, kan vara .pem eller .der):", + "selectP12": "VƤlj din PKCS#12-nyckellagringsfil (.p12 eller .pfx) (Valfritt, om det tillhandahĆ„lls bƶr det innehĆ„lla din privata nyckel och certifikat):", + "selectJKS": "VƤlj din Java Keystore-fil (.jks eller .keystore):", + "certType": "Certifikattyp", + "password": "Ange ditt nyckellagerlƶsenord eller privata nyckellƶsenord (om tillƤmpligt):", + "showSig": "Visa signatur", + "reason": "Anledning", + "location": "Plats", + "name": "Namn", + "showLogo": "Visa logo", + "submit": "Signera PDF" + }, + "removeCertSign": { + "tags": "autentisera,PEM,P12,officiell,dekryptera", + "title": "Ta bort certifikatsignatur", + "header": "Ta bort den digitala certifikatsignaturen frĆ„n PDF:en", + "selectPDF": "VƤlj en PDF-fil:", + "submit": "Ta bort signatur" + }, + "pageLayout": { + "tags": "slĆ„ samman,sammansatt,enkel-vy,organisera", + "title": "Flersidigt layout", + "header": "Flersidigt layout", + "pagesPerSheet": "Sidor per ark:", + "addBorder": "LƤgg till kanter", + "submit": "Skicka" + }, + "scalePages": { + "tags": "Ƥndra storlek,modifiera,dimension,anpassa", + "title": "Justera sidskala", + "header": "Justera sidskala", + "pageSize": "Storlek pĆ„ en sida i dokumentet.", + "keepPageSize": "Originalstorlek", + "scaleFactor": "ZoomnivĆ„ (beskƤrning) fƶr en sida.", + "submit": "Skicka" + }, + "add-page-numbers": { + "tags": "paginera,etikett,organisera,indexera" + }, + "auto-rename": { + "tags": "auto-detektera,rubrikbaserad,organisera,mƤrka om", + "title": "Auto-byt namn", + "header": "Auto-byt namn pĆ„ PDF", + "submit": "Auto-byt namn" + }, + "adjust-contrast": { + "tags": "fƤrgkorrigering,finjustera,modifiera,fƶrbƤttra" + }, + "crop": { + "tags": "trimma,krympa,redigera,forma", + "title": "BeskƤr", + "header": "BeskƤr PDF", + "submit": "Skicka" + }, + "autoSplitPDF": { + "tags": "QR-baserad,separera,skanna-segment,organisera", + "title": "Auto-dela PDF", + "header": "Auto-dela PDF", + "description": "Skriv ut, infoga, skanna, ladda upp och lĆ„t oss automatiskt separera dina dokument. Inget manuellt sorteringsarbete behƶvs.", + "selectText": { + "1": "Skriv ut nĆ„gra avdelare frĆ„n nedan (Svartvitt gĆ„r bra).", + "2": "Skanna alla dina dokument pĆ„ en gĆ„ng genom att infoga avdelaren mellan dem.", + "3": "Ladda upp den enda stora skannade PDF-filen och lĆ„t Stirling PDF hantera resten.", + "4": "Avdelarsidor detekteras automatiskt och tas bort, vilket garanterar ett prydligt slutdokument." + }, + "formPrompt": "Skicka PDF som innehĆ„ller Stirling-PDF-sidavdelare:", + "duplexMode": "DuplexlƤge (Fram- och baksideskanning)", + "dividerDownload2": "Ladda ner 'Auto-delningsavdelare (med instruktioner).pdf'", + "submit": "Skicka" + }, + "sanitizePdf": { + "tags": "rengƶra,sƤkra,sƤker,ta bort hot" + }, + "URLToPDF": { + "tags": "webbfĆ„ngst,spara-sida,webb-till-dokument,arkivera", + "title": "URL till PDF", + "header": "URL till PDF", + "submit": "Konvertera", + "credit": "AnvƤnder WeasyPrint" + }, + "HTMLToPDF": { + "tags": "markup,webbinnehĆ„ll,transformation,konvertera", + "title": "HTML till PDF", + "header": "HTML till PDF", + "help": "Accepterar HTML-filer och ZIP-filer som innehĆ„ller html/css/bilder etc som krƤvs", + "submit": "Konvertera", + "credit": "AnvƤnder WeasyPrint", + "zoom": "ZoomnivĆ„ fƶr visning av webbplatsen.", + "pageWidth": "Sidans bredd i centimeter. (Tom fƶr standard)", + "pageHeight": "Sidans hƶjd i centimeter. (Tom fƶr standard)", + "marginTop": "Ɩvre marginal pĆ„ sidan i millimeter. (Tom fƶr standard)", + "marginBottom": "Nedre marginal pĆ„ sidan i millimeter. (Tom fƶr standard)", + "marginLeft": "VƤnster marginal pĆ„ sidan i millimeter. (Tom fƶr standard)", + "marginRight": "Hƶger marginal pĆ„ sidan i millimeter. (Tom fƶr standard)", + "printBackground": "Rendera bakgrunden pĆ„ webbplatser.", + "defaultHeader": "Aktivera standardhuvud (Namn och sidnummer)", + "cssMediaType": "Ƅndra CSS-mediatypen fƶr sidan.", + "none": "Ingen", + "print": "Utskrift", + "screen": "SkƤrm" + }, + "MarkdownToPDF": { + "tags": "markup,webbinnehĆ„ll,transformation,konvertera", + "title": "Markdown till PDF", + "header": "Markdown till PDF", + "submit": "Konvertera", + "help": "PĆ„gĆ„ende arbete", + "credit": "AnvƤnder WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF Till Markdown", + "header": "PDF Till Markdown", + "submit": "Konvertera" + }, + "getPdfInfo": { + "tags": "information,data,statistik,statistik", + "title": "HƤmta information om PDF", + "header": "HƤmta information om PDF", + "submit": "HƤmta information", + "downloadJson": "Ladda ner JSON" + }, + "extractPage": { + "tags": "extrahera" + }, + "PdfToSinglePage": { + "tags": "enstaka sida" + }, + "showJS": { + "tags": "JS", + "title": "Visa Javascript", + "header": "Visa Javascript", + "downloadJS": "Ladda ner Javascript", + "submit": "Visa" + }, + "autoRedact": { + "tags": "Redigera,Dƶlja,svƤrta,svart,markƶr,dold", + "title": "Auto-redigera", + "header": "Auto-redigera", + "colorLabel": "FƤrg", + "textsToRedactLabel": "Text att redigera (radavgrƤnsad)", + "textsToRedactPlaceholder": "t.ex. \\nKonfidentiellt \\nHemligt", + "useRegexLabel": "AnvƤnd Regex", + "wholeWordSearchLabel": "Hel ord-sƶkning", + "customPaddingLabel": "Anpassad extra utfyllnad", + "convertPDFToImageLabel": "Konvertera PDF till PDF-bild (AnvƤnds fƶr att ta bort text bakom rutan)", + "submitButton": "Skicka" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,Tabellextraktion,extrahera,konvertera" + }, + "autoSizeSplitPDF": { + "tags": "pdf,dela,dokument,organisation" + }, + "overlay-pdfs": { + "tags": "Ɩverlagra", + "header": "Ɩverlagra PDF-filer", + "baseFile": { + "label": "VƤlj bas-PDF-fil" + }, + "overlayFiles": { + "label": "VƤlj ƶverlagrings-PDF-filer" + }, + "mode": { + "label": "VƤlj ƶverlagringslƤge", + "sequential": "Sekventiell ƶverlagring", + "interleaved": "SammanflƤtad ƶverlagring", + "fixedRepeat": "Fast upprepningsƶverlagring" + }, + "counts": { + "label": "Ɩverlagringsantal (fƶr fast upprepningslƤge)", + "placeholder": "Ange kommaseparerade antal (t.ex. 2,3,1)" + }, + "position": { + "label": "VƤlj ƶverlagringsposition", + "foreground": "Fƶrgrund", + "background": "Bakgrund" + }, + "submit": "Skicka" + }, + "split-by-sections": { + "tags": "Sektionsdelning,Dela,Anpassa", + "title": "Dela PDF efter sektioner", + "header": "Dela PDF i sektioner", + "horizontal": { + "label": "Horisontella indelningar", + "placeholder": "Ange antal horisontella indelningar" + }, + "vertical": { + "label": "Vertikala indelningar", + "placeholder": "Ange antal vertikala indelningar" + }, + "submit": "Dela PDF", + "merge": "SlĆ„ samman till en PDF" + }, + "AddStampRequest": { + "tags": "StƤmpel,LƤgg till bild,centrera bild,VattenstƤmpel,PDF,BƤdda in,Anpassa", + "header": "StƤmpla PDF", + "title": "StƤmpla PDF", + "stampType": "StƤmpeltyp", + "stampText": "StƤmpeltext", + "stampImage": "StƤmpelbild", + "alphabet": "Alfabet", + "fontSize": "Tecken-/bildstorlek", + "rotation": "Rotation", + "opacity": "Opacitet", + "position": "Position", + "overrideX": "ƅsidosƤtt X-koordinat", + "overrideY": "ƅsidosƤtt Y-koordinat", + "customMargin": "Anpassad marginal", + "customColor": "Anpassad textfƤrg", + "submit": "Skicka" + }, + "removeImagePdf": { + "tags": "Ta bort bild,Sidoperationer,Backend,serversida" + }, + "splitPdfByChapters": { + "tags": "dela,kapitel,bokmƤrken,organisera" + }, + "validateSignature": { + "tags": "signatur,verifiera,validera,pdf,certifikat,digital signatur,Validera Signatur,Validera certifikat", + "title": "Validera PDF Signaturer", + "header": "Validera Digitala Signaturer", + "selectPDF": "VƤlj signerad PDF fil", + "submit": "Validera Signaturer", + "results": "Valideringsresultat", + "status": { + "_value": "Status", + "valid": "Giltig", + "invalid": "Ogiltig" + }, + "signer": "Signer", + "date": "Datum", + "reason": "Anledning", + "location": "Plats", + "noSignatures": "Inga digitala signaturer hittade i detta dokument", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "ErsƤtt-Invertera-FƤrg", + "header": "ErsƤtt-Invertera fƤrg pĆ„ PDF", + "selectText": { + "1": "ErsƤtt eller Invertera fƤrgalternativ", + "2": "Standard (standard hƶghastighetsfƤrg)", + "3": "Anpassad (anpassade fƤrger)", + "4": "Full-Invertera (invertera alla fƤrger)", + "5": "HƶghastighetsfƤrgalternativ", + "6": "Vit text pĆ„ svart bakgrund", + "7": "Svart text pĆ„ vit bakgrund", + "8": "Gul text pĆ„ svart bakgrund", + "9": "Grƶn text pĆ„ svart bakgrund", + "10": "VƤlj textfƤrg", + "11": "VƤlj bakgrundsfƤrg" + }, + "submit": "ErsƤtt" + }, + "replaceColorPdf": { + "tags": "ErsƤtt FƤrg, SidĆ„tgƤrder, Bakomliggande, Serversid" + }, + "login": { + "title": "Logga in", + "header": "Logga in", + "signin": "Logga in", + "rememberme": "Kom ihĆ„g mig", + "invalid": "Ogiltigt anvƤndarnamn eller lƶsenord.", + "locked": "Ditt konto har lĆ„sts.", + "signinTitle": "VƤnligen logga in", + "ssoSignIn": "Logga in via enkel inloggning", + "oAuth2AutoCreateDisabled": "OAUTH2 Auto-skapa anvƤndare inaktiverad", + "oAuth2AdminBlockedUser": "Registrering eller inloggning av icke-registrerade anvƤndare Ƥr fƶr nƤrvarande blockerad. Kontakta administratƶren.", + "oauth2RequestNotFound": "AuktoriseringsbegƤran hittades inte", + "oauth2InvalidUserInfoResponse": "Ogiltigt svar pĆ„ anvƤndarinformation", + "oauth2invalidRequest": "Ogiltig begƤran", + "oauth2AccessDenied": "ƅtkomst nekad", + "oauth2InvalidTokenResponse": "Ogiltigt token-svar", + "oauth2InvalidIdToken": "Ogiltigt Id-token", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "AnvƤndaren Ƥr inaktiverad, inloggning Ƥr fƶr nƤrvarande blockerad med detta anvƤndarnamn. Kontakta administratƶren.", + "alreadyLoggedIn": "Du Ƥr redan inloggad pĆ„", + "alreadyLoggedIn2": "enheter. Logga ut frĆ„n enheterna och fƶrsƶk igen.", + "toManySessions": "Du har fƶr mĆ„nga aktiva sessioner", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF till en sida", + "header": "PDF till en sida", + "submit": "Konvertera till en sida" + }, + "pageExtracter": { + "title": "Extrahera sidor", + "header": "Extrahera sidor", + "submit": "Extrahera", + "placeholder": "(t.ex. 1,2,8 eller 4,7,12-16 eller 2n-1)" + }, + "sanitizePDF": { + "title": "Sanera PDF", + "header": "Sanera en PDF-fil", + "selectText": { + "1": "Ta bort JavaScript-Ć„tgƤrder", + "2": "Ta bort inbƤddade filer", + "3": "Remove XMP metadata", + "4": "Ta bort lƤnkar", + "5": "Ta bort typsnitt", + "6": "Remove Document Info Metadata" + }, + "submit": "Sanera PDF" + }, + "adjustContrast": { + "title": "Justera kontrast", + "header": "Justera kontrast", + "contrast": "Kontrast:", + "brightness": "Ljusstyrka:", + "saturation": "MƤttnad:", + "download": "Ladda ner" + }, + "compress": { + "title": "Komprimera", + "header": "Komprimera PDF", + "credit": "Denna tjƤnst anvƤnder qpdf fƶr PDF-komprimering/optimering.", + "grayscale": { + "label": "TillƤmpa grĆ„skala fƶr komprimering" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "OptimeringsnivĆ„:", + "4": "AutolƤge - Autojusterar kvaliteten fƶr att fĆ„ PDF till exakt storlek", + "5": "FƶrvƤntad PDF-storlek (t.ex. 25MB, 10,8MB, 25KB)" + }, + "submit": "Komprimera" + }, + "decrypt": { + "passwordPrompt": "Denna fil Ƥr lƶsenordsskyddad. Fyll i lƶsenord:", + "cancelled": "Operation misslyckades fƶr PDF: {0}", + "noPassword": "Inget lƶsenord angivet fƶr krypterad PDF: {0}", + "invalidPassword": "Fƶrsƶk igen med korrekt lƶsenord.", + "invalidPasswordHeader": "Felaktigt lƶsenord eller osupportad kryptering fƶr PDF: {0}", + "unexpectedError": "Det uppstod ett fel vid processering av filen. VƤnligen fƶrsƶk igen.", + "serverError": "Serverfel vid avkryptering: {0}", + "success": "Fil avkrypterad." + }, + "multiTool-advert": { + "message": "Denna funktion finns ocksĆ„ tillgƤnglig i vĆ„r multi-tool page. Spana in den fƶr bƤttre sida-fƶr-sida anpassning och ytterligare funktioner!" + }, + "pageRemover": { + "title": "Sidborttagare", + "header": "PDF Sidborttagning", + "pagesToDelete": "Sidor att radera (Ange en kommaseparerad lista med sidnummer) :", + "submit": "Ta bort sidor", + "placeholder": "(t.ex. 1,2,6 eller 1-10,15-30)" + }, + "imageToPDF": { + "title": "Bild till PDF", + "header": "Bild till PDF", + "submit": "Konvertera", + "selectLabel": "Alternativ fƶr bildanpassning", + "fillPage": "Fyll sida", + "fitDocumentToImage": "Anpassa sida till bild", + "maintainAspectRatio": "BehĆ„ll bildfƶrhĆ„llande", + "selectText": { + "2": "Rotera PDF automatiskt", + "3": "Multifillogik (Endast aktiverad om man arbetar med flera bilder)", + "4": "SlĆ„ samman till en enda PDF", + "5": "Konvertera till separata PDF-filer" + } + }, + "PDFToCSV": { + "title": "PDF till CSV", + "header": "PDF till CSV", + "prompt": "VƤlj sida fƶr att extrahera tabell", + "submit": "Extrahera" + }, + "split-by-size-or-count": { + "title": "Dela PDF efter storlek eller antal", + "header": "Dela PDF efter storlek eller antal", + "type": { + "label": "VƤlj delningstyp", + "size": "Efter storlek", + "pageCount": "Efter sidantal", + "docCount": "Efter dokumentantal" + }, + "value": { + "label": "Ange vƤrde", + "placeholder": "Ange storlek (t.ex. 2MB eller 3KB) eller antal (t.ex. 5)" + }, + "submit": "Skicka" + }, + "printFile": { + "title": "Skriv ut fil", + "header": "Skriv ut fil till skrivare", + "selectText": { + "1": "VƤlj fil att skriva ut", + "2": "Ange skrivarnamn" + }, + "submit": "Skriv ut" + }, + "licenses": { + "nav": "Licenser", + "title": "Tredjepartslicenser", + "header": "Tredjepartslicenser", + "module": "Modul", + "version": "Version", + "license": "Licens" + }, + "survey": { + "nav": "Undersƶkning", + "title": "Stirling-PDF-undersƶkning", + "description": "Stirling-PDF har ingen spĆ„rning sĆ„ vi vill hƶra frĆ„n vĆ„ra anvƤndare fƶr att fƶrbƤttra Stirling-PDF!", + "changes": "Stirling-PDF har Ƥndrats sedan den senaste undersƶkningen. LƤr dig mer pĆ„ vĆ„r blogg hƤr:", + "changes2": "Med dessa Ƥndringar fĆ„s betalat fƶretagsstƶd och finansiering", + "please": "VƤnligen ƶvervƤg att delta i vĆ„r undersƶkning!", + "disabled": "(Undersƶkningspopup kommer att inaktiveras i kommande uppdateringar men finns tillgƤnglig lƤngst ner pĆ„ sidan)", + "button": "Delta i undersƶkningen", + "dontShowAgain": "Visa inte igen", + "meeting": { + "1": "Om du anvƤnder Stirling PDF pĆ„ jobbet skulle vi vilja prata med dig. Vi erbjuder teknisk support i utbyte mot ett 15 minuters samtal med dig som anvƤndare.", + "2": "Detta Ƥr en chans att:", + "3": "FĆ„ hjƤlp med utrullning, integrationer eller felsƶkning", + "4": "Ge direkt feedback pĆ„ prestanda, sƤllan uppkomna problem och verktyg som saknas.", + "5": "HjƤlp oss refinera Stirling PDF fƶr fƶretagsanvƤndning", + "6": "Om du Ƥr intresserad kan du boka en tid med vĆ„rt team omgĆ„ende. (Endast engelsktalande)", + "7": "Ser fram emot att grƤva ned oss i din anvƤndning och se till att Stirling PDF blir Ƥnnu bƤttre!", + "notInterested": "Inte ett fƶretag och/eller intresserad i ett mƶte?", + "button": "Boka mƶte" + } + }, + "removeImage": { + "title": "Ta bort bild", + "header": "Ta bort bild", + "removeImage": "Ta bort bild", + "submit": "Ta bort bild" + }, + "splitByChapters": { + "title": "Dela upp PDF efter kapitel", + "header": "Dela upp PDF efter kapitel", + "bookmarkLevel": "BokmƤrkesnivĆ„", + "includeMetadata": "Inkludera Metadata", + "allowDuplicates": "TillĆ„t Dubletter", + "desc": { + "1": "Detta verktyg delar upp en PDF till flera PDFer baserat pĆ„ dess kapitelstruktur.", + "2": "BokmƤrkesnivĆ„: VƤlj nivĆ„n av bokmƤrken att anvƤnda fƶr delning (0 fƶr toppnivĆ„, 1 fƶr andra nivĆ„, m.m.).", + "3": "Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.", + "4": "TillĆ„t duplicieringar: Om kryssrutan Ƥr markerad tillĆ„ts flera bokmƤrken pĆ„ samma sida skapa individuella PDF:er." + }, + "submit": "Dela upp PDF" + }, + "fileChooser": { + "click": "Klicka", + "or": "eller", + "dragAndDrop": "Dra & SlƤpp", + "dragAndDropPDF": "Dra & SlƤpp PDF fil", + "dragAndDropImage": "Dra & SlƤpp bildfil", + "hoveredDragAndDrop": "Dra & SlƤpp fil(er) hƤr", + "extractPDF": "Extraherar..." + }, + "releases": { + "footer": "UtgĆ„vor", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Nuvarande UtgĆ„va" + }, + "note": "Release notes are only available in English" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/th-TH/translation.json b/frontend/public/locales/th-TH/translation.json new file mode 100644 index 000000000..8dee79b00 --- /dev/null +++ b/frontend/public/locales/th-TH/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "ขนาดตัวอักษร", + "fontName": "ąøŠąø·ą¹ˆąø­ąøŸąø­ąø™ąø•ą¹Œ", + "title": "ą¹€ąøžąø“ą¹ˆąø”ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ąø«ąø™ą¹‰ąø²", + "header": "ą¹€ąøžąø“ą¹ˆąø”ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ąø«ąø™ą¹‰ąø²", + "selectText": { + "1": "ą¹€ąø„ąø·ąø­ąøą¹„ąøŸąø„ą¹Œ PDF:", + "2": "ąø‚ąø™ąø²ąø”ąø‚ąø­ąøš", + "3": "ąø•ąø³ą¹ąø«ąø™ą¹ˆąø‡", + "4": "ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™", + "5": "ąø«ąø™ą¹‰ąø²ą¹€ąøžąø·ą¹ˆąø­ąøąø³ąø«ąø™ąø”ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚", + "6": "ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø—ąøµą¹ˆąøąø³ąø«ąø™ąø”ą¹€ąø­ąø‡" + }, + "customTextDesc": "ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø—ąøµą¹ˆąøąø³ąø«ąø™ąø”ą¹€ąø­ąø‡", + "numberPagesDesc": "ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ąø«ąø™ą¹‰ąø²ąø—ąøµą¹ˆąøˆąø°ąøąø³ąø«ąø™ąø” ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™ 'ทั้งหดด', ąø¢ąø±ąø‡ąø¢ąø­ąø”ąø£ąø±ąøš 1-5 หรือ 2,5,9 เป็นต้น", + "customNumberDesc": "ąø„ą¹ˆąø²ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™ {n}, ąø¢ąø±ąø‡ąø¢ąø­ąø”ąø£ąø±ąøš 'หน้า {n} ąø‚ąø­ąø‡ {total}', 'ข้อควาด-{n}', '{filename}-{n}'", + "submit": "ą¹€ąøžąø“ą¹ˆąø”ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ąø«ąø™ą¹‰ąø²" + }, + "pdfPrompt": "เคือก PDF", + "multiPdfPrompt": "เคือก PDF ąø«ąø„ąø²ąø¢ą¹„ąøŸąø„ą¹Œ (2 ขึ้นไป)", + "multiPdfDropPrompt": "เคือก (หรือคากแคะวาง) PDF ąø—ąø±ą¹‰ąø‡ąø«ąø”ąø”ąø—ąøµą¹ˆąø„ąøøąø“ąø•ą¹‰ąø­ąø‡ąøąø²ąø£", + "imgPrompt": "ą¹€ąø„ąø·ąø­ąøąø ąø²ąøž", + "genericSubmit": "ąøŖą¹ˆąø‡", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "คำเตือน: ąøąø£ąø°ąøšąø§ąø™ąøąø²ąø£ąø™ąøµą¹‰ąø­ąø²ąøˆą¹ƒąøŠą¹‰ą¹€ąø§ąø„ąø²ąøŖąø¹ąø‡ąøŖąøøąø”ąø«ąø™ąø¶ą¹ˆąø‡ąø™ąø²ąø—ąøµąø‚ąø¶ą¹‰ąø™ąø­ąø¢ąø¹ą¹ˆąøąø±ąøšąø‚ąø™ąø²ąø”ą¹„ąøŸąø„ą¹Œ", + "pageOrderPrompt": "ą¹€ąø£ąøµąø¢ąø‡ąø„ąø³ąø”ąø±ąøšąø«ąø™ą¹‰ąø²ąø•ąø²ąø”ąø„ąø§ąø²ąø”ąø•ą¹‰ąø­ąø‡ąøąø²ąø£ (ąø›ą¹‰ąø­ąø™ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ąø«ąø™ą¹‰ąø²ą¹ąø¢ąøąø”ą¹‰ąø§ąø¢ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø«ąø”ąø²ąø¢ąøˆąøøąø„ąø ąø²ąø„ąø«ąø£ąø·ąø­ąøŸąø±ąø‡ąøą¹ŒąøŠąø±ąø™ ą¹€ąøŠą¹ˆąø™ 2n+1) :", + "pageSelectionPrompt": "เคือกหน้าตาดควาดต้องการ (ąø›ą¹‰ąø­ąø™ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ąø«ąø™ą¹‰ąø²ą¹ąø¢ąøąø”ą¹‰ąø§ąø¢ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø«ąø”ąø²ąø¢ąøˆąøøąø„ąø ąø²ąø„ ą¹€ąøŠą¹ˆąø™ 1,5,6 ąø«ąø£ąø·ąø­ąøŸąø±ąø‡ąøą¹ŒąøŠąø±ąø™ ą¹€ąøŠą¹ˆąø™ 2n+1) :", + "goToPage": "ą¹„ąø›ąø—ąøµą¹ˆąø«ąø™ą¹‰ąø²", + "true": "ąøˆąø£ąø“ąø‡", + "false": "ą¹€ąø—ą¹‡ąøˆ", + "unknown": "ą¹„ąø”ą¹ˆąø—ąø£ąø²ąøš", + "save": "ąøšąø±ąø™ąø—ąø¶ąø", + "saveToBrowser": "ąøšąø±ąø™ąø—ąø¶ąøą¹ƒąø™ą¹€ąøšąø£ąø²ąø§ą¹Œą¹€ąø‹ąø­ąø£ą¹Œ", + "close": "ปณด", + "filesSelected": "ą¹„ąøŸąø„ą¹Œąø—ąøµą¹ˆą¹€ąø„ąø·ąø­ąø", + "noFavourites": "ą¹„ąø”ą¹ˆąø”ąøµąø£ąø²ąø¢ąøąø²ąø£ą¹‚ąø›ąø£ąø”ąø—ąøµą¹ˆą¹€ąøžąø“ą¹ˆąø”", + "downloadComplete": "ąøąø²ąø£ąø”ąø²ąø§ąø™ą¹Œą¹‚ąø«ąø„ąø”ą¹€ąøŖąø£ą¹‡ąøˆąøŖąø”ąøšąø¹ąø£ąø“ą¹Œ", + "bored": "ą¹€ąøšąø·ą¹ˆąø­ąø£ąø­ąø«ąø£ąø·ąø­ąø¢ąø±ąø‡?", + "alphabet": "ตัวอักษร", + "downloadPdf": "ąø”ąø²ąø§ąø™ą¹Œą¹‚ąø«ąø„ąø” PDF", + "text": "ข้อควาด", + "font": "ąøŸąø­ąø™ąø•ą¹Œ", + "selectFillter": "-- เคือก --", + "pageNum": "หดายเคขหน้า", + "sizes": { + "small": "เค็ก", + "medium": "กคาง", + "large": "ą¹ƒąø«ąøą¹ˆ", + "x-large": "ą¹ƒąø«ąøą¹ˆąø”ąø²ąø" + }, + "error": { + "pdfPassword": "เอกสาร PDF ąø”ąøµąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ ą¹ąø„ąø°ą¹„ąø”ą¹ˆą¹„ąø”ą¹‰ąø£ąø°ąøšąøøąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ąø«ąø£ąø·ąø­ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ą¹„ąø”ą¹ˆąø–ąø¹ąøąø•ą¹‰ąø­ąø‡", + "_value": "ąø‚ą¹‰ąø­ąøœąø“ąø”ąøžąø„ąø²ąø”", + "sorry": "ąø‚ąø­ąø­ąø ąø±ąø¢ą¹ƒąø™ąø›ąø±ąøąø«ąø²!", + "needHelp": "ąø•ą¹‰ąø­ąø‡ąøąø²ąø£ąø„ąø§ąø²ąø”ąøŠą¹ˆąø§ąø¢ą¹€ąø«ąø„ąø·ąø­ / ąøžąøšąø›ąø±ąøąø«ąø²?", + "contactTip": "ąø«ąø²ąøąø„ąøøąø“ąø¢ąø±ąø‡ąø”ąøµąø›ąø±ąøąø«ąø² ąø­ąø¢ą¹ˆąø²ąø„ąø±ąø‡ą¹€ąø„ąø—ąøµą¹ˆąøˆąø°ąø•ąø“ąø”ąø•ą¹ˆąø­ą¹€ąø£ąø²ą¹€ąøžąø·ą¹ˆąø­ąø‚ąø­ąø„ąø§ąø²ąø”ąøŠą¹ˆąø§ąø¢ą¹€ąø«ąø„ąø·ąø­ ąø„ąøøąø“ąøŖąø²ąø”ąø²ąø£ąø–ąøŖą¹ˆąø‡ąø•ąø±ą¹‹ąø§ąøšąø™ąø«ąø™ą¹‰ąø²ąø‚ąø­ąø‡ą¹€ąø£ąø²ą¹ƒąø™ GitHub หรือ ąø•ąø“ąø”ąø•ą¹ˆąø­ą¹€ąø£ąø²ąøœą¹ˆąø²ąø™ Discord:", + "404": { + "head": "404 - ą¹„ąø”ą¹ˆąøžąøšąø«ąø™ą¹‰ąø² | อุ๊ย! ą¹€ąø£ąø²ąøžąø„ąø²ąø”ą¹ƒąø™ą¹‚ąø„ą¹‰ąø”!", + "1": "ą¹€ąø£ąø²ą¹„ąø”ą¹ˆąøŖąø²ąø”ąø²ąø£ąø–ąø«ąø²ąø«ąø™ą¹‰ąø²ąø—ąøµą¹ˆąø„ąøøąø“ąøąø³ąø„ąø±ąø‡ąø”ąø­ąø‡ąø«ąø²", + "2": "ąøšąø²ąø‡ąøŖąø“ą¹ˆąø‡ąøšąø²ąø‡ąø­ąø¢ą¹ˆąø²ąø‡ąøœąø“ąø”ąøžąø„ąø²ąø”" + }, + "github": "ąøŖą¹ˆąø‡ąø•ąø±ą¹‹ąø§ą¹ƒąø™ GitHub", + "showStack": "แสดง Stack Trace", + "copyStack": "คัดคอก Stack Trace", + "githubSubmit": "GitHub - ąøŖą¹ˆąø‡ąø•ąø±ą¹‹ąø§", + "discordSubmit": "Discord - ąøŖą¹ˆąø‡ą¹‚ąøžąøŖąø•ą¹Œąøąø²ąø£ąøŖąø™ąø±ąøšąøŖąø™ąøøąø™" + }, + "delete": "คบ", + "username": "ąøŠąø·ą¹ˆąø­ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰", + "password": "ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™", + "welcome": "ąø¢ąø“ąø™ąø”ąøµąø•ą¹‰ąø­ąø™ąø£ąø±ąøš", + "property": "ąø„ąøøąø“ąøŖąø”ąøšąø±ąø•ąø“", + "black": "ดำ", + "white": "ขาว", + "red": "แดง", + "green": "เขียว", + "blue": "น้ำเงณน", + "custom": "ąø›ąø£ąø±ąøšą¹ąø•ą¹ˆąø‡...", + "WorkInProgess": "กำคังดำเนณนการ ąø­ąø²ąøˆą¹„ąø”ą¹ˆąø—ąø³ąø‡ąø²ąø™ąø«ąø£ąø·ąø­ąø”ąøµąøšąø±ą¹Šąø ą¹‚ąø›ąø£ąø”ąø£ąø²ąø¢ąø‡ąø²ąø™ąø›ąø±ąøąø«ąø²ą¹ƒąø” ๆ!", + "poweredBy": "ąø‚ąø±ąøšą¹€ąø„ąø„ąø·ą¹ˆąø­ąø™ą¹‚ąø”ąø¢", + "yes": "ใช่", + "no": "ą¹„ąø”ą¹ˆ", + "changedCredsMessage": "ąø‚ą¹‰ąø­ąø”ąø¹ąø„ąø£ąø±ąøšąø£ąø­ąø‡ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ą¹ąø›ąø„ąø‡ą¹ąø„ą¹‰ąø§!", + "notAuthenticatedMessage": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ą¹„ąø”ą¹ˆą¹„ąø”ą¹‰ąø£ąø±ąøšąøąø²ąø£ąø¢ąø·ąø™ąø¢ąø±ąø™", + "userNotFoundMessage": "ą¹„ąø”ą¹ˆąøžąøšąøœąø¹ą¹‰ą¹ƒąøŠą¹‰", + "incorrectPasswordMessage": "ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ąø›ąø±ąøˆąøˆąøøąøšąø±ąø™ą¹„ąø”ą¹ˆąø–ąø¹ąøąø•ą¹‰ąø­ąø‡", + "usernameExistsMessage": "ąøŠąø·ą¹ˆąø­ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ą¹ƒąø«ąø”ą¹ˆąø”ąøµąø­ąø¢ąø¹ą¹ˆą¹ąø„ą¹‰ąø§", + "invalidUsernameMessage": "ąøŠąø·ą¹ˆąø­ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ą¹„ąø”ą¹ˆąø–ąø¹ąøąø•ą¹‰ąø­ąø‡ ąøŠąø·ą¹ˆąø­ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąøŖąø²ąø”ąø²ąø£ąø–ąø›ąø£ąø°ąøąø­ąøšąø”ą¹‰ąø§ąø¢ąø•ąø±ąø§ąø­ąø±ąøąø©ąø£ ตัวเคข ą¹ąø„ąø°ąø­ąø±ąøąø‚ąø£ąø°ąøžąø“ą¹€ąøØąø©ąø•ą¹ˆąø­ą¹„ąø›ąø™ąøµą¹‰ @._+- ąø«ąø£ąø·ąø­ąøˆąø°ąø•ą¹‰ąø­ąø‡ą¹€ąø›ą¹‡ąø™ąø—ąøµą¹ˆąø­ąø¢ąø¹ą¹ˆąø­ąøµą¹€ąø”ąø„ąø—ąøµą¹ˆąø–ąø¹ąøąø•ą¹‰ąø­ąø‡", + "invalidPasswordMessage": "ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ą¹„ąø”ą¹ˆąø„ąø§ąø£ąø§ą¹ˆąø²ąø‡ ą¹ąø„ąø°ą¹„ąø”ą¹ˆąø„ąø§ąø£ąø”ąøµąøžąø·ą¹‰ąø™ąø—ąøµą¹ˆąø§ą¹ˆąø²ąø‡ąø—ąøµą¹ˆąø‚ąø­ąøšąø‚ąø­ąø‡ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”", + "confirmPasswordErrorMessage": "ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ą¹ƒąø«ąø”ą¹ˆą¹ąø„ąø°ąø¢ąø·ąø™ąø¢ąø±ąø™ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ą¹ƒąø«ąø”ą¹ˆąø•ą¹‰ąø­ąø‡ąø•ąø£ąø‡ąøąø±ąø™", + "deleteCurrentUserMessage": "ą¹„ąø”ą¹ˆąøŖąø²ąø”ąø²ąø£ąø–ąø„ąøšąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø—ąøµą¹ˆą¹€ąø‚ą¹‰ąø²ąøŖąø¹ą¹ˆąø£ąø°ąøšąøšą¹ƒąø™ąø›ąø±ąøˆąøˆąøøąøšąø±ąø™ą¹„ąø”ą¹‰", + "deleteUsernameExistsMessage": "ąøŠąø·ą¹ˆąø­ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ą¹„ąø”ą¹ˆąø›ąø£ąø²ąøąøą¹ąø„ąø°ą¹„ąø”ą¹ˆąøŖąø²ąø”ąø²ąø£ąø–ąø„ąøšą¹„ąø”ą¹‰", + "downgradeCurrentUserMessage": "ą¹„ąø”ą¹ˆąøŖąø²ąø”ąø²ąø£ąø–ąø„ąø”ąø£ąø°ąø”ąø±ąøšąøšąø—ąøšąø²ąø—ąø‚ąø­ąø‡ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø›ąø±ąøˆąøˆąøøąøšąø±ąø™ą¹„ąø”ą¹‰", + "disabledCurrentUserMessage": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ąø›ąø±ąøˆąøˆąøøąøšąø±ąø™ą¹„ąø”ą¹ˆąøŖąø²ąø”ąø²ąø£ąø–ąø›ąø“ąø”ąøąø²ąø£ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ą¹„ąø”ą¹‰", + "downgradeCurrentUserLongMessage": "ą¹„ąø”ą¹ˆąøŖąø²ąø”ąø²ąø£ąø–ąø„ąø”ąø£ąø°ąø”ąø±ąøšąøšąø—ąøšąø²ąø—ąø‚ąø­ąø‡ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø›ąø±ąøˆąøˆąøøąøšąø±ąø™ą¹„ąø”ą¹‰ ąø”ąø±ąø‡ąø™ąø±ą¹‰ąø™ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø›ąø±ąøˆąøˆąøøąøšąø±ąø™ąøˆąø°ą¹„ąø”ą¹ˆąø›ąø£ąø²ąøąø", + "userAlreadyExistsOAuthMessage": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø”ąøµąø­ąø¢ąø¹ą¹ˆą¹ąø„ą¹‰ąø§ą¹ƒąø™ąøąø²ąø™ąø°ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ OAuth2", + "userAlreadyExistsWebMessage": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø”ąøµąø­ąø¢ąø¹ą¹ˆą¹ąø„ą¹‰ąø§ą¹ƒąø™ąøąø²ąø™ąø°ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ą¹€ąø§ą¹‡ąøš", + "oops": "อุ๊ย!", + "help": "ąøŠą¹ˆąø§ąø¢ą¹€ąø«ąø„ąø·ąø­", + "goHomepage": "ą¹„ąø›ąø—ąøµą¹ˆąø«ąø™ą¹‰ąø²ąø«ąø„ąø±ąø", + "joinDiscord": "ą¹€ąø‚ą¹‰ąø²ąø£ą¹ˆąø§ąø”ą¹€ąø‹ąø“ąø£ą¹ŒąøŸą¹€ąø§ąø­ąø£ą¹Œ Discord ของเรา", + "seeDockerHub": "ดู Docker Hub", + "visitGithub": "ą¹€ąø¢ąøµą¹ˆąø¢ąø”ąøŠąø”ąø—ąøµą¹ˆą¹€ąøą¹‡ąøš Github", + "donate": "ąøšąø£ąø“ąøˆąø²ąø„", + "color": "ąøŖąøµ", + "sponsor": "ąøœąø¹ą¹‰ąøŖąø™ąø±ąøšąøŖąø™ąøøąø™", + "info": "ข้อดูค", + "pro": "โปร", + "page": "หน้า", + "pages": "หน้า", + "loading": "กำคังโหคด...", + "addToDoc": "ą¹€ąøžąø“ą¹ˆąø”ą¹€ąø‚ą¹‰ąø²ąøŖąø¹ą¹ˆą¹€ąø­ąøąøŖąø²ąø£", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "ąø™ą¹‚ąø¢ąøšąø²ąø¢ąø„ąø§ąø²ąø”ą¹€ąø›ą¹‡ąø™ąøŖą¹ˆąø§ąø™ąø•ąø±ąø§", + "terms": "ąø‚ą¹‰ąø­ąøąø³ąø«ąø™ąø”ąøąø²ąø£ą¹ƒąøŠą¹‰ąø‡ąø²ąø™", + "accessibility": "ควาดเข้าถึง", + "cookie": "ąø™ą¹‚ąø¢ąøšąø²ąø¢ąø„ąøøąøąøąøµą¹‰", + "impressum": "ąø›ąøąø“ąøąøąø²", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "เดนู Pipeline (ą¹€ąøšąø•ą¹‰ąø²)", + "uploadButton": "ąø­ąø±ąø›ą¹‚ąø«ąø„ąø”ą¹ąøšąøšąøąø³ąø«ąø™ąø”ą¹€ąø­ąø‡", + "configureButton": "ąøąø³ąø«ąø™ąø”ąø„ą¹ˆąø²", + "defaultOption": "กำหนดเอง", + "submitButton": "ąøŖą¹ˆąø‡", + "help": "ąø„ąø§ąø²ąø”ąøŠą¹ˆąø§ąø¢ą¹€ąø«ąø„ąø·ąø­ Pipeline", + "scanHelp": "ąø„ąø§ąø²ąø”ąøŠą¹ˆąø§ąø¢ą¹€ąø«ąø„ąø·ąø­ąøąø²ąø£ąøŖą¹ąøąø™ą¹‚ąøŸąø„ą¹€ąø”ąø­ąø£ą¹Œ", + "deletePrompt": "ąø„ąøøąø“ą¹ąø™ą¹ˆą¹ƒąøˆąø§ą¹ˆąø²ąø•ą¹‰ąø­ąø‡ąøąø²ąø£ąø„ąøš pipeline ą¹ƒąøŠą¹ˆą¹„ąø«ąø”", + "tags": "อัตโนดัตณ, ąø„ąø³ąø”ąø±ąøš, ąøŖąø„ąø£ąø“ąø›ąø•ą¹Œ, ąø›ąø£ąø°ąø”ąø§ąø„ąøœąø„ą¹ąøšąø—ąøŠą¹Œ", + "title": "ąøžąø“ą¹‰ąøžąø„ne" + }, + "pipelineOptions": { + "header": "ąøąø²ąø£ąøąø³ąø«ąø™ąø”ąø„ą¹ˆąø² Pipeline", + "pipelineNameLabel": "ชื่อ Pipeline", + "saveSettings": "ąøšąø±ąø™ąø—ąø¶ąøąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ąøąø²ąø£ąø”ąø³ą¹€ąø™ąø“ąø™ąøąø²ąø£", + "pipelineNamePrompt": "ใส่ชื่อ pipeline ąø—ąøµą¹ˆąø™ąøµą¹ˆ", + "selectOperation": "เคือกการดำเนณนการ", + "addOperationButton": "ą¹€ąøžąø“ą¹ˆąø”ąøąø²ąø£ąø”ąø³ą¹€ąø™ąø“ąø™ąøąø²ąø£", + "pipelineHeader": "Pipeline:", + "saveButton": "ąø”ąø²ąø§ąø™ą¹Œą¹‚ąø«ąø„ąø”", + "validateButton": "ąø•ąø£ąø§ąøˆąøŖąø­ąøšąø„ąø§ąø²ąø”ąø–ąø¹ąøąø•ą¹‰ąø­ąø‡" + }, + "enterpriseEdition": { + "button": "อัปเกรดเป็นโปร", + "warning": "ąøŸąøµą¹€ąøˆąø­ąø£ą¹Œąø™ąøµą¹‰ąø”ąøµą¹ƒąø«ą¹‰ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ą¹€ąø‰ąøžąø²ąø°ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø—ąøµą¹ˆą¹€ąø›ą¹‡ąø™ą¹‚ąø›ąø£ą¹€ąø—ą¹ˆąø²ąø™ąø±ą¹‰ąø™", + "yamlAdvert": "Stirling PDF Pro supports YAML configuration files and other SSO features.", + "ssoAdvert": "Looking for more user management features? Check out Stirling PDF Pro" + }, + "analytics": { + "title": "ąø„ąøøąø“ąø•ą¹‰ąø­ąø‡ąøąø²ąø£ąø—ąøµą¹ˆąøˆąø°ąø—ąø³ą¹ƒąø«ą¹‰ Stirling PDF ąø”ąøµąø¢ąø“ą¹ˆąø‡ąø‚ąø¶ą¹‰ąø™ą¹„ąø«ąø”?", + "paragraph1": "Stirling PDF ąø”ąøµąøąø²ąø£ąø§ąø“ą¹€ąø„ąø£ąø²ąø°ąø«ą¹Œą¹ąøšąøšąøŖąø”ąø±ąø„ąø£ą¹ƒąøˆą¹€ąøžąø·ą¹ˆąø­ąøŠą¹ˆąø§ąø¢ą¹€ąø£ąø²ąø›ąø£ąø±ąøšąø›ąø£ąøøąø‡ąøœąø„ąø“ąø•ąø ąø±ąø“ąø‘ą¹Œ ą¹€ąø£ąø²ą¹„ąø”ą¹ˆąø™ąø³ąø—ąø²ąø‡ąø„ąø§ąø²ąø”ą¹€ąø›ą¹‡ąø™ąøŖą¹ˆąø§ąø™ąø•ąø±ąø§ąø«ąø£ąø·ąø­ą¹€ąø™ąø·ą¹‰ąø­ąø«ąø²ąø‚ąø­ąø‡ą¹„ąøŸąø„ą¹Œą¹„ąø›ą¹€ąøą¹‡ąøšąø‚ą¹‰ąø­ąø”ąø¹ąø„ą¹ƒąø” ๆ", + "paragraph2": "ą¹‚ąø›ąø£ąø”ąøžąø“ąøˆąø²ąø£ąø“ąø²ąøąø²ąø£ą¹€ąø›ąø“ąø”ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ąøąø²ąø£ąø§ąø“ą¹€ąø„ąø£ąø²ąø°ąø«ą¹Œą¹€ąøžąø·ą¹ˆąø­ąøŠą¹ˆąø§ąø¢ą¹ƒąø«ą¹‰ Stirling-PDF ą¹€ąøˆąø£ąø“ąøą¹€ąø•ąø“ąøšą¹‚ąø•ą¹ąø„ąø°ąø—ąø³ą¹ƒąø«ą¹‰ą¹€ąø£ąø²ą¹€ąø‚ą¹‰ąø²ą¹ƒąøˆąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ąø”ąø²ąøąø‚ąø¶ą¹‰ąø™", + "enable": "ą¹€ąø›ąø“ąø”ąøąø²ąø£ąø§ąø“ą¹€ąø„ąø£ąø²ąø°ąø«ą¹Œ", + "disable": "ąø›ąø“ąø”ąøąø²ąø£ąø§ąø“ą¹€ąø„ąø£ąø²ąø°ąø«ą¹Œ", + "settings": "ąø„ąøøąø“ąøŖąø²ąø”ąø²ąø£ąø–ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ą¹ąø›ąø„ąø‡ąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ąøąø²ąø£ąø§ąø“ą¹€ąø„ąø£ąø²ąø°ąø«ą¹Œą¹ƒąø™ą¹„ąøŸąø„ą¹Œ config/settings.yml" + }, + "navbar": { + "favorite": "รายการโปรด", + "recent": "New and recently updated", + "darkmode": "โหดดดืด", + "language": "ภาษา", + "settings": "ąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²", + "allTools": "ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø”ąø·ąø­ąø—ąø±ą¹‰ąø‡ąø«ąø”ąø”", + "multiTool": "ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø”ąø·ąø­ąø«ąø„ąø²ąø¢ąø•ąø±ąø§", + "search": "Search", + "sections": { + "organize": "ąøˆąø±ąø”ąø£ąø°ą¹€ąøšąøµąø¢ąøš", + "convertTo": "แปคงเป็น PDF", + "convertFrom": "ą¹ąø›ąø„ąø‡ąøˆąø²ąø PDF", + "security": "คงนาดแคะควาดปคอดภัย", + "advance": "ขั้นสูง", + "edit": "ดูแคะแก้ไข", + "popular": "ยอดนณยด" + } + }, + "settings": { + "title": "ąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²", + "update": "ดีการอัปเดต", + "updateAvailable": "{0} ąø„ąø·ąø­ą¹€ąø§ąø­ąø£ą¹ŒąøŠąø±ąø™ąø—ąøµą¹ˆąø•ąø“ąø”ąø•ąø±ą¹‰ąø‡ą¹ƒąø™ąø›ąø±ąøˆąøˆąøøąøšąø±ąø™ ąø”ąøµą¹€ąø§ąø­ąø£ą¹ŒąøŠąø±ąø™ą¹ƒąø«ąø”ą¹ˆ ({1}) ąøžąø£ą¹‰ąø­ąø”ą¹ƒąø«ą¹‰ąøšąø£ąø“ąøąø²ąø£", + "appVersion": "ą¹€ąø§ąø­ąø£ą¹ŒąøŠąø±ąø™ą¹ąø­ąø›:", + "downloadOption": { + "title": "ą¹€ąø„ąø·ąø­ąøąø•ąø±ąø§ą¹€ąø„ąø·ąø­ąøąøąø²ąø£ąø”ąø²ąø§ąø™ą¹Œą¹‚ąø«ąø„ąø” (ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ąø”ąø²ąø§ąø™ą¹Œą¹‚ąø«ąø„ąø”ą¹„ąøŸąø„ą¹Œą¹€ąø”ąøµąø¢ąø§ąø—ąøµą¹ˆą¹„ąø”ą¹ˆą¹ƒąøŠą¹ˆ zip):", + "1": "ą¹€ąø›ąø“ąø”ą¹ƒąø™ąø«ąø™ą¹‰ąø²ąø•ą¹ˆąø²ąø‡ą¹€ąø”ąøµąø¢ąø§ąøąø±ąø™", + "2": "ą¹€ąø›ąø“ąø”ą¹ƒąø™ąø«ąø™ą¹‰ąø²ąø•ą¹ˆąø²ąø‡ą¹ƒąø«ąø”ą¹ˆ", + "3": "ąø”ąø²ąø§ąø™ą¹Œą¹‚ąø«ąø„ąø”ą¹„ąøŸąø„ą¹Œ" + }, + "zipThreshold": "ąøšąøµąøšąø­ąø±ąø”ą¹„ąøŸąø„ą¹Œą¹€ąø”ąø·ą¹ˆąø­ąøˆąø³ąø™ąø§ąø™ą¹„ąøŸąø„ą¹Œąø—ąøµą¹ˆąø”ąø²ąø§ąø™ą¹Œą¹‚ąø«ąø„ąø”ą¹€ąøąø“ąø™", + "signOut": "ออกจากระบบ", + "accountSettings": "ąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ąøšąø±ąøąøŠąøµ", + "bored": { + "help": "ą¹€ąø›ąø“ąø”ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ą¹€ąøąø” easter egg" + }, + "cacheInputs": { + "name": "ąøšąø±ąø™ąø—ąø¶ąøąøąø²ąø£ąø›ą¹‰ąø­ąø™ąøŸąø­ąø£ą¹Œąø”", + "help": "ą¹€ąø›ąø“ąø”ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ą¹€ąøžąø·ą¹ˆąø­ąøšąø±ąø™ąø—ąø¶ąøąøąø²ąø£ąø›ą¹‰ąø­ąø™ąø‚ą¹‰ąø­ąø”ąø¹ąø„ąø—ąøµą¹ˆą¹ƒąøŠą¹‰ąøą¹ˆąø­ąø™ąø«ąø™ą¹‰ąø²ąø™ąøµą¹‰ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ąø£ąø±ąø™ą¹ƒąø™ąø­ąø™ąø²ąø„ąø•" + } + }, + "changeCreds": { + "title": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąø‚ą¹‰ąø­ąø”ąø¹ąø„ąø£ąø±ąøšąø£ąø­ąø‡", + "header": "ąø­ąø±ąø›ą¹€ąø”ąø•ąø£ąø²ąø¢ąø„ąø°ą¹€ąø­ąøµąø¢ąø”ąøšąø±ąøąøŠąøµąø‚ąø­ąø‡ąø„ąøøąø“", + "changePassword": "ąø„ąøøąø“ąøąø³ąø„ąø±ąø‡ą¹ƒąøŠą¹‰ąø‚ą¹‰ąø­ąø”ąø¹ąø„ąø£ąø±ąøšąø£ąø­ąø‡ąøąø²ąø£ą¹€ąø‚ą¹‰ąø²ąøŖąø¹ą¹ˆąø£ąø°ąøšąøšą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™ ąøąø£ąøøąø“ąø²ą¹ƒąøŖą¹ˆąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ą¹ƒąø«ąø”ą¹ˆ", + "newUsername": "ąøŠąø·ą¹ˆąø­ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ą¹ƒąø«ąø”ą¹ˆ", + "oldPassword": "ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ąø›ąø±ąøˆąøˆąøøąøšąø±ąø™", + "newPassword": "ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ą¹ƒąø«ąø”ą¹ˆ", + "confirmNewPassword": "ąø¢ąø·ąø™ąø¢ąø±ąø™ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ą¹ƒąø«ąø”ą¹ˆ", + "submit": "ąøŖą¹ˆąø‡ąøąø²ąø£ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ą¹ąø›ąø„ąø‡" + }, + "account": { + "title": "ąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ąøšąø±ąøąøŠąøµ", + "accountSettings": "ąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ąøšąø±ąøąøŠąøµ", + "adminSettings": "ąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ąøœąø¹ą¹‰ąø”ąø¹ą¹ąø„ąø£ąø°ąøšąøš - ąø”ąø¹ą¹ąø„ąø°ą¹€ąøžąø“ą¹ˆąø”ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰", + "userControlSettings": "ąøąø²ąø£ąø„ąø§ąøšąø„ąøøąø”ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰", + "changeUsername": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąøŠąø·ą¹ˆąø­ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰", + "newUsername": "ąøŠąø·ą¹ˆąø­ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ą¹ƒąø«ąø”ą¹ˆ", + "password": "ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ąø¢ąø·ąø™ąø¢ąø±ąø™", + "oldPassword": "ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ą¹€ąøą¹ˆąø²", + "newPassword": "ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ą¹ƒąø«ąø”ą¹ˆ", + "changePassword": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™", + "confirmNewPassword": "ąø¢ąø·ąø™ąø¢ąø±ąø™ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ą¹ƒąø«ąø”ą¹ˆ", + "signOut": "ออกจากระบบ", + "yourApiKey": "ąø„ąøµąø¢ą¹Œ API ของคุณ", + "syncTitle": "ąø‹ąø“ąø‡ąø„ą¹Œąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ą¹€ąøšąø£ąø²ąø§ą¹Œą¹€ąø‹ąø­ąø£ą¹Œąøąø±ąøšąøšąø±ąøąøŠąøµ", + "settingsCompare": "ąøąø²ąø£ą¹€ąø›ąø£ąøµąø¢ąøšą¹€ąø—ąøµąø¢ąøšąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²:", + "property": "ąø„ąøøąø“ąøŖąø”ąøšąø±ąø•ąø“", + "webBrowserSettings": "ąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ą¹€ąøšąø£ąø²ąø§ą¹Œą¹€ąø‹ąø­ąø£ą¹Œą¹€ąø§ą¹‡ąøš", + "syncToBrowser": "ąø‹ąø“ąø‡ąø„ą¹Œąøšąø±ąøąøŠąøµ -> ą¹€ąøšąø£ąø²ąø§ą¹Œą¹€ąø‹ąø­ąø£ą¹Œ", + "syncToAccount": "ąø‹ąø“ąø‡ąø„ą¹Œąøšąø±ąøąøŠąøµ <- ą¹€ąøšąø£ąø²ąø§ą¹Œą¹€ąø‹ąø­ąø£ą¹Œ" + }, + "adminUserSettings": { + "title": "ąøąø²ąø£ąø„ąø§ąøšąø„ąøøąø”ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰", + "header": "ąøąø²ąø£ąø„ąø§ąøšąø„ąøøąø”ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰", + "admin": "ąøœąø¹ą¹‰ąø”ąø¹ą¹ąø„ąø£ąø°ąøšąøš", + "user": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰", + "addUser": "ą¹€ąøžąø“ą¹ˆąø”ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ą¹ƒąø«ąø”ą¹ˆ", + "deleteUser": "ąø„ąøšąøœąø¹ą¹‰ą¹ƒąøŠą¹‰", + "confirmDeleteUser": "ąø„ąø§ąø£ąø„ąøšąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø™ąøµą¹‰ąø«ąø£ąø·ąø­ą¹„ąø”ą¹ˆ?", + "confirmChangeUserStatus": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø™ąøµą¹‰ąø„ąø§ąø£ąø–ąø¹ąøąø›ąø“ąø”/ą¹€ąø›ąø“ąø”ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ąø«ąø£ąø·ąø­ą¹„ąø”ą¹ˆ?", + "usernameInfo": "ąøŠąø·ą¹ˆąø­ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąøŖąø²ąø”ąø²ąø£ąø–ąø›ąø£ąø°ąøąø­ąøšąø”ą¹‰ąø§ąø¢ąø•ąø±ąø§ąø­ąø±ąøąø©ąø£ ตัวเคข ą¹ąø„ąø°ąø­ąø±ąøąø‚ąø£ąø°ąøžąø“ą¹€ąøØąø©ąø•ą¹ˆąø­ą¹„ąø›ąø™ąøµą¹‰ @._+- ąø«ąø£ąø·ąø­ąøˆąø°ąø•ą¹‰ąø­ąø‡ą¹€ąø›ą¹‡ąø™ąø—ąøµą¹ˆąø­ąø¢ąø¹ą¹ˆąø­ąøµą¹€ąø”ąø„ąø—ąøµą¹ˆąø–ąø¹ąøąø•ą¹‰ąø­ąø‡", + "roles": "ąøšąø—ąøšąø²ąø—", + "role": "ąøšąø—ąøšąø²ąø—", + "actions": "การดำเนณนการ", + "apiUser": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ API ąøˆąø³ąøąø±ąø”", + "extraApiUser": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ API ą¹€ąøžąø“ą¹ˆąø”ą¹€ąø•ąø“ąø”", + "webOnlyUser": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ą¹€ąø§ą¹‡ąøšą¹€ąø—ą¹ˆąø²ąø™ąø±ą¹‰ąø™", + "demoUser": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø—ąø”ąø„ąø­ąø‡ (ą¹„ąø”ą¹ˆąø”ąøµąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ąø›ąø£ąø±ąøšą¹ąø•ą¹ˆąø‡)", + "internalApiUser": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ API ąø ąø²ąø¢ą¹ƒąø™", + "forceChange": "ąøšąø±ąø‡ąø„ąø±ąøšą¹ƒąø«ą¹‰ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ą¹ƒąø™ąøąø²ąø£ą¹€ąø‚ą¹‰ąø²ąøŖąø¹ą¹ˆąø£ąø°ąøšąøš", + "submit": "ąøšąø±ąø™ąø—ąø¶ąøąøœąø¹ą¹‰ą¹ƒąøŠą¹‰", + "changeUserRole": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąøšąø—ąøšąø²ąø—ąø‚ąø­ąø‡ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰", + "authenticated": "ą¹„ąø”ą¹‰ąø£ąø±ąøšąøąø²ąø£ąø¢ąø·ąø™ąø¢ąø±ąø™ą¹ąø„ą¹‰ąø§", + "editOwnProfil": "ą¹ąøą¹‰ą¹„ąø‚ą¹‚ąø›ąø£ą¹„ąøŸąø„ą¹Œąø‚ąø­ąø‡ąø•ąø±ąø§ą¹€ąø­ąø‡", + "enabledUser": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø—ąøµą¹ˆą¹€ąø›ąø“ąø”ą¹ƒąøŠą¹‰ąø‡ąø²ąø™", + "disabledUser": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø—ąøµą¹ˆąø›ąø“ąø”ą¹ƒąøŠą¹‰ąø‡ąø²ąø™", + "activeUsers": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø—ąøµą¹ˆąø”ąøµąøąø²ąø£ą¹ƒąøŠą¹‰ąø‡ąø²ąø™:", + "disabledUsers": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø—ąøµą¹ˆąø–ąø¹ąøąø£ąø°ąø‡ąø±ąøšąøąø²ąø£ą¹ƒąøŠą¹‰ąø‡ąø²ąø™:", + "totalUsers": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø£ąø§ąø”ąø—ąø±ą¹‰ąø‡ąø«ąø”ąø”:", + "lastRequest": "ąøąø²ąø£ąø‚ąø­ąø‚ą¹‰ąø­ąø”ąø¹ąø„ąø„ą¹ˆąø²ąøŖąøøąø”", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "การนำเข้า/ąøŖą¹ˆąø‡ąø­ąø­ąøąøąø²ąø™ąø‚ą¹‰ąø­ąø”ąø¹ąø„", + "header": "การนำเข้า/ąøŖą¹ˆąø‡ąø­ąø­ąøąøąø²ąø™ąø‚ą¹‰ąø­ąø”ąø¹ąø„", + "fileName": "ąøŠąø·ą¹ˆąø­ą¹„ąøŸąø„ą¹Œ", + "creationDate": "ąø§ąø±ąø™ąø—ąøµą¹ˆąøŖąø£ą¹‰ąø²ąø‡", + "fileSize": "ąø‚ąø™ąø²ąø”ą¹„ąøŸąø„ą¹Œ", + "deleteBackupFile": "ąø„ąøšą¹„ąøŸąø„ą¹ŒąøŖąø³ąø£ąø­ąø‡", + "importBackupFile": "ąø™ąø³ą¹€ąø‚ą¹‰ąø²ą¹„ąøŸąø„ą¹ŒąøŖąø³ąø£ąø­ąø‡", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "ąø”ąø²ąø§ąø™ą¹Œą¹‚ąø«ąø„ąø”ą¹„ąøŸąø„ą¹ŒąøŖąø³ąø£ąø­ąø‡", + "info_1": "ą¹€ąø”ąø·ą¹ˆąø­ąø™ąø³ą¹€ąø‚ą¹‰ąø²ąø‚ą¹‰ąø­ąø”ąø¹ąø„ ąøˆąø³ą¹€ąø›ą¹‡ąø™ąø•ą¹‰ąø­ąø‡ą¹ąø™ą¹ˆą¹ƒąøˆąø§ą¹ˆąø²ą¹‚ąø„ąø£ąø‡ąøŖąø£ą¹‰ąø²ąø‡ąø–ąø¹ąøąø•ą¹‰ąø­ąø‡ ąø«ąø²ąøą¹„ąø”ą¹ˆą¹ąø™ą¹ˆą¹ƒąøˆąø§ą¹ˆąø²ąøąø³ąø„ąø±ąø‡ąø—ąø³ąø­ąø°ą¹„ąø£ąø­ąø¢ąø¹ą¹ˆ ąø„ąø§ąø£ąø‚ąø­ąø„ąø³ą¹ąø™ąø°ąø™ąø³ą¹ąø„ąø°ąø„ąø§ąø²ąø”ąøŠą¹ˆąø§ąø¢ą¹€ąø«ąø„ąø·ąø­ąøˆąø²ąøąø”ąø·ąø­ąø­ąø²ąøŠąøµąøž ąø„ąø§ąø²ąø”ąøœąø“ąø”ąøžąø„ąø²ąø”ą¹ƒąø™ą¹‚ąø„ąø£ąø‡ąøŖąø£ą¹‰ąø²ąø‡ąø­ąø²ąøˆąø—ąø³ą¹ƒąø«ą¹‰ą¹€ąøąø“ąø”ąø‚ą¹‰ąø­ąøšąøąøžąø£ą¹ˆąø­ąø‡ą¹ƒąø™ąøąø²ąø£ąø—ąø³ąø‡ąø²ąø™ąø‚ąø­ąø‡ą¹ąø­ąø›ąøžąø„ąø“ą¹€ąø„ąøŠąø±ąø™ąøˆąø™ąø–ąø¶ąø‡ąø‚ąø±ą¹‰ąø™ą¹„ąø”ą¹ˆąøŖąø²ąø”ąø²ąø£ąø–ąø£ąø±ąø™ą¹ąø­ąø›ąøžąø„ąø“ą¹€ąø„ąøŠąø±ąø™ą¹„ąø”ą¹‰ą¹€ąø„ąø¢", + "info_2": "ąøŠąø·ą¹ˆąø­ą¹„ąøŸąø„ą¹Œą¹„ąø”ą¹ˆąøŖąø³ąø„ąø±ąøą¹€ąø”ąø·ą¹ˆąø­ąø­ąø±ąø›ą¹‚ąø«ąø„ąø” ąøˆąø°ąø–ąø¹ąøą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąøŠąø·ą¹ˆąø­ąø ąø²ąø¢ąø«ąø„ąø±ąø‡ą¹ƒąø«ą¹‰ą¹€ąø›ą¹‡ąø™ąø£ąø¹ąø›ą¹ąøšąøš backup_user_yyyyMMddHHmm.sql ą¹€ąøžąø·ą¹ˆąø­ą¹ƒąø«ą¹‰ąø”ąøµąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąøŠąø·ą¹ˆąø­ąø—ąøµą¹ˆąøŖąø­ąø”ąø„ąø„ą¹‰ąø­ąø‡ąøąø±ąø™", + "submit": "นำเข้าสำรอง", + "importIntoDatabaseSuccessed": "ąøąø²ąø£ąø™ąø³ą¹€ąø‚ą¹‰ąø²ą¹ƒąø™ąøąø²ąø™ąø‚ą¹‰ąø­ąø”ąø¹ąø„ąøŖąø³ą¹€ąø£ą¹‡ąøˆ", + "backupCreated": "Database backup successful", + "fileNotFound": "ą¹„ąø”ą¹ˆąøžąøšą¹„ąøŸąø„ą¹Œ", + "fileNullOrEmpty": "ą¹„ąøŸąø„ą¹Œąø•ą¹‰ąø­ąø‡ą¹„ąø”ą¹ˆąø§ą¹ˆąø²ąø‡ą¹€ąø›ąø„ą¹ˆąø²ąø«ąø£ąø·ąø­ą¹„ąø”ą¹ˆąø”ąøµąø‚ą¹‰ąø­ąø”ąø¹ąø„", + "failedImportFile": "ąøąø²ąø£ąø™ąø³ą¹€ąø‚ą¹‰ąø²ą¹„ąøŸąø„ą¹Œąø„ą¹‰ąø”ą¹€ąø«ąø„ąø§", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "ąøŖąø–ąø²ąø™ąø°ąø‚ąø­ąø‡ąø„ąøøąø“ą¹ƒąø™ąø£ąø°ąøšąøšąø«ąø”ąø”ąø­ąø²ąø¢ąøø ąøąø£ąøøąø“ąø²ąø£ąøµą¹€ąøŸąø£ąøŠąø«ąø™ą¹‰ąø²ą¹ąø„ąø°ąø„ąø­ąø‡ą¹ƒąø«ąø”ą¹ˆąø­ąøµąøąø„ąø£ąø±ą¹‰ąø‡", + "refreshPage": "Refresh Page" + }, + "home": { + "desc": "ąøØąø¹ąø™ąø¢ą¹Œąø£ąø§ąø”ąø—ąøøąøąø„ąø§ąø²ąø”ąø•ą¹‰ąø­ąø‡ąøąø²ąø£ąø‚ąø­ąø‡ąø„ąøøąø“ą¹€ąøąøµą¹ˆąø¢ąø§ąøąø±ąøš PDF ąø—ąøµą¹ˆą¹‚ąø®ąøŖąø•ą¹Œą¹ƒąø™ąø—ą¹‰ąø­ąø‡ąø–ąø“ą¹ˆąø™ąø‚ąø­ąø‡ąø„ąøøąø“", + "searchBar": "ąø„ą¹‰ąø™ąø«ąø²ąø„ąøøąø“ąøŖąø”ąøšąø±ąø•ąø“...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "ดู ą¹€ąøžąø“ą¹ˆąø”ąø„ąø³ąø­ąø˜ąø“ąøšąø²ąø¢ ą¹€ąøžąø“ą¹ˆąø”ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø«ąø£ąø·ąø­ąø£ąø¹ąø›ąø ąø²ąøž" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø”ąø·ąø­ PDF หคายตัว", + "desc": "รวด หดุน ąøˆąø±ąø”ą¹€ąø£ąøµąø¢ąø‡ ą¹ąø„ąø°ąø„ąøšąø«ąø™ą¹‰ąø²ąø•ą¹ˆąø²ąø‡ą¹†" + }, + "merge": { + "title": "ąø£ąø§ąø”ą¹„ąøŸąø„ą¹Œ PDF", + "desc": "รวด PDF ąø«ąø„ąø²ąø¢ą¹„ąøŸąø„ą¹Œą¹€ąø›ą¹‡ąø™ąø«ąø™ąø¶ą¹ˆąø‡ą¹€ąø”ąøµąø¢ąø§ą¹„ąø”ą¹‰ąø­ąø¢ą¹ˆąø²ąø‡ąø‡ą¹ˆąø²ąø¢ąø”ąø²ąø¢" + }, + "split": { + "title": "ą¹ąø¢ąøą¹„ąøŸąø„ą¹Œ PDF", + "desc": "แยก PDF เป็นหคายเอกสาร" + }, + "rotate": { + "title": "หดุน", + "desc": "หดุน PDF ąø‚ąø­ąø‡ąø„ąøøąø“ą¹„ąø”ą¹‰ąø­ąø¢ą¹ˆąø²ąø‡ąø‡ą¹ˆąø²ąø¢ąø”ąø²ąø¢" + }, + "imageToPdf": { + "title": "ąø£ąø¹ąø›ąø ąø²ąøžą¹€ąø›ą¹‡ąø™ PDF", + "desc": "ą¹ąø›ąø„ąø‡ąø£ąø¹ąø›ąø ąø²ąøž (PNG, JPEG, GIF) เป็น PDF" + }, + "pdfToImage": { + "title": "PDF ą¹€ąø›ą¹‡ąø™ąø£ąø¹ąø›ąø ąø²ąøž", + "desc": "แปคง PDF ą¹€ąø›ą¹‡ąø™ąø£ąø¹ąø›ąø ąø²ąøž (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "ąøˆąø±ąø”ąø£ąø°ą¹€ąøšąøµąø¢ąøš", + "desc": "คบ/ąøˆąø±ąø”ą¹€ąø£ąøµąø¢ąø‡ąø«ąø™ą¹‰ąø²ąø•ą¹ˆąø²ąø‡ą¹† ą¹ƒąø™ąø„ąø³ąø”ąø±ąøšąø—ąøµą¹ˆąø•ą¹‰ąø­ąø‡ąøąø²ąø£" + }, + "addImage": { + "title": "ą¹€ąøžąø“ą¹ˆąø”ąø£ąø¹ąø›ąø ąø²ąøž", + "desc": "ą¹€ąøžąø“ą¹ˆąø”ąø£ąø¹ąø›ąø ąø²ąøžą¹„ąø›ąø¢ąø±ąø‡ąø•ąø³ą¹ąø«ąø™ą¹ˆąø‡ąø—ąøµą¹ˆąøąø³ąø«ąø™ąø”ą¹ƒąø™ PDF" + }, + "watermark": { + "title": "ą¹€ąøžąø“ą¹ˆąø”ąø„ąø²ąø¢ąø™ą¹‰ąø³", + "desc": "ą¹€ąøžąø“ą¹ˆąø”ąø„ąø²ąø¢ąø™ą¹‰ąø³ąø—ąøµą¹ˆąøąø³ąø«ąø™ąø”ą¹€ąø­ąø‡ąø„ąø‡ą¹ƒąø™ą¹€ąø­ąøąøŖąø²ąø£ PDF ของคุณ" + }, + "permissions": { + "title": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąøŖąø“ąø—ąø˜ąø“ą¹Œ", + "desc": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąøŖąø“ąø—ąø˜ąø“ą¹Œąø‚ąø­ąø‡ą¹€ąø­ąøąøŖąø²ąø£ PDF ของคุณ" + }, + "removePages": { + "title": "คบ", + "desc": "ąø„ąøšąø«ąø™ą¹‰ąø²ąø—ąøµą¹ˆą¹„ąø”ą¹ˆąø•ą¹‰ąø­ąø‡ąøąø²ąø£ąøˆąø²ąøą¹€ąø­ąøąøŖąø²ąø£ PDF ของคุณ" + }, + "addPassword": { + "title": "ą¹€ąøžąø“ą¹ˆąø”ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™", + "desc": "เข้ารหัสเอกสาร PDF ąø‚ąø­ąø‡ąø„ąøøąø“ąø”ą¹‰ąø§ąø¢ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™" + }, + "removePassword": { + "title": "ąø„ąøšąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™", + "desc": "ąø„ąøšąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ąøˆąø²ąøąøąø²ąø£ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ą¹€ąø­ąøąøŖąø²ąø£ PDF ของคุณ" + }, + "compressPdfs": { + "title": "ąøšąøµąøšąø­ąø±ąø”", + "desc": "ąøšąøµąøšąø­ąø±ąø” PDF ą¹€ąøžąø·ą¹ˆąø­ąø„ąø”ąø‚ąø™ąø²ąø”ą¹„ąøŸąø„ą¹Œ" + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąø‚ą¹‰ąø­ąø”ąø¹ąø„ą¹€ąø”ąø•ąø²", + "desc": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™/คบ/ą¹€ąøžąø“ą¹ˆąø”ąø‚ą¹‰ąø­ąø”ąø¹ąø„ą¹€ąø”ąø•ąø²ąøˆąø²ąøą¹€ąø­ąøąøŖąø²ąø£ PDF" + }, + "fileToPDF": { + "title": "ą¹ąø›ąø„ąø‡ą¹„ąøŸąø„ą¹Œą¹€ąø›ą¹‡ąø™ PDF", + "desc": "ą¹ąø›ąø„ąø‡ą¹„ąøŸąø„ą¹Œą¹€ąøąø·ąø­ąøšąø—ąøøąøąø›ąø£ąø°ą¹€ąø ąø—ą¹€ąø›ą¹‡ąø™ PDF (DOCX, PNG, XLS, PPT, TXT ą¹ąø„ąø°ąø­ąø·ą¹ˆąø™ ๆ)" + }, + "ocr": { + "title": "OCR / ทำควาดสะอาดการสแกน", + "desc": "ąø—ąø³ąø„ąø§ąø²ąø”ąøŖąø°ąø­ąø²ąø”ąøąø²ąø£ąøŖą¹ąøąø™ą¹ąø„ąø°ąø•ąø£ąø§ąøˆąøˆąø±ąøšąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąøˆąø²ąøąø ąø²ąøžąø ąø²ąø¢ą¹ƒąø™ PDF ą¹ąø„ąø°ą¹€ąøžąø“ą¹ˆąø”ą¹€ąø›ą¹‡ąø™ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø­ąøµąøąø„ąø£ąø±ą¹‰ąø‡" + }, + "extractImages": { + "title": "ą¹ąø¢ąøąø£ąø¹ąø›ąø ąø²ąøž", + "desc": "ą¹ąø¢ąøąø£ąø¹ąø›ąø ąø²ąøžąø—ąø±ą¹‰ąø‡ąø«ąø”ąø”ąøˆąø²ąø PDF ą¹ąø„ąø°ąøšąø±ąø™ąø—ąø¶ąøą¹ƒąø™ąø£ąø¹ąø›ą¹ąøšąøš zip" + }, + "pdfToPDFA": { + "title": "PDF เป็น PDF/A", + "desc": "แปคง PDF เป็น PDF/A ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ąøˆąø±ąø”ą¹€ąøą¹‡ąøšąø£ąø°ąø¢ąø°ąø¢ąø²ąø§" + }, + "PDFToWord": { + "title": "PDF เป็น Word", + "desc": "แปคง PDF ą¹€ąø›ą¹‡ąø™ąø£ąø¹ąø›ą¹ąøšąøš Word (DOC, DOCX แคะ ODT)" + }, + "PDFToPresentation": { + "title": "PDF เป็น Presentation", + "desc": "แปคง PDF ą¹€ąø›ą¹‡ąø™ąø£ąø¹ąø›ą¹ąøšąøš Presentation (PPT, PPTX แคะ ODP)" + }, + "PDFToText": { + "title": "PDF เป็น RTF (Text)", + "desc": "แปคง PDF ą¹€ąø›ą¹‡ąø™ąø£ąø¹ąø›ą¹ąøšąøšąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø«ąø£ąø·ąø­ RTF" + }, + "PDFToHTML": { + "title": "PDF เป็น HTML", + "desc": "แปคง PDF ą¹€ąø›ą¹‡ąø™ąø£ąø¹ąø›ą¹ąøšąøš HTML" + }, + "PDFToXML": { + "title": "PDF เป็น XML", + "desc": "แปคง PDF ą¹€ąø›ą¹‡ąø™ąø£ąø¹ąø›ą¹ąøšąøš XML" + }, + "ScannerImageSplit": { + "title": "ąø•ąø£ąø§ąøˆąøˆąø±ąøš/ą¹ąø¢ąøąø£ąø¹ąø›ąø ąø²ąøžąøŖą¹ąøąø™", + "desc": "ą¹ąø¢ąøąø£ąø¹ąø›ąø ąø²ąøžąø«ąø„ąø²ąø¢ąø£ąø¹ąø›ąøˆąø²ąøąø ąø²ąøž/ PDF" + }, + "sign": { + "title": "ą¹€ąø‹ą¹‡ąø™ąøŠąø·ą¹ˆąø­", + "desc": "ą¹€ąøžąø“ą¹ˆąø”ąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™ąø„ąø‡ą¹ƒąø™ PDF ด้วยการวาด ข้อควาด ąø«ąø£ąø·ąø­ąø£ąø¹ąø›ąø ąø²ąøž" + }, + "flatten": { + "title": "ą¹ąøšąø™", + "desc": "ąø„ąøšąø­ąø‡ąø„ą¹Œąø›ąø£ąø°ąøąø­ąøšą¹ąøšąøšąø­ąø“ąø™ą¹€ąø•ąø­ąø£ą¹Œą¹ąø­ąø„ąø—ąøµąøŸą¹ąø„ąø°ąøŸąø­ąø£ą¹Œąø”ąø—ąø±ą¹‰ąø‡ąø«ąø”ąø”ąøˆąø²ąø PDF" + }, + "repair": { + "title": "ąø‹ą¹ˆąø­ąø”ą¹ąø‹ąø”", + "desc": "ąøžąø¢ąø²ąø¢ąø²ąø”ąø‹ą¹ˆąø­ąø”ą¹ąø‹ąø” PDF ąø—ąøµą¹ˆą¹€ąøŖąøµąø¢ąø«ąø²ąø¢/แตก" + }, + "removeBlanks": { + "title": "ąø„ąøšąø«ąø™ą¹‰ąø²ąø§ą¹ˆąø²ąø‡", + "desc": "ąø•ąø£ąø§ąøˆąøˆąø±ąøšą¹ąø„ąø°ąø„ąøšąø«ąø™ą¹‰ąø²ąø§ą¹ˆąø²ąø‡ąøˆąø²ąøą¹€ąø­ąøąøŖąø²ąø£" + }, + "removeAnnotations": { + "title": "ąø„ąøšąø„ąø³ąø­ąø˜ąø“ąøšąø²ąø¢ąø›ąø£ąø°ąøąø­ąøš", + "desc": "ąø„ąøšąø„ąø§ąø²ąø”ąø„ąø“ąø”ą¹€ąø«ą¹‡ąø™/ąø„ąø³ąø­ąø˜ąø“ąøšąø²ąø¢ąø›ąø£ąø°ąøąø­ąøšąø—ąø±ą¹‰ąø‡ąø«ąø”ąø”ąøˆąø²ąø PDF" + }, + "compare": { + "title": "ą¹€ąø›ąø£ąøµąø¢ąøšą¹€ąø—ąøµąø¢ąøš", + "desc": "ą¹€ąø›ąø£ąøµąø¢ąøšą¹€ąø—ąøµąø¢ąøšą¹ąø„ąø°ą¹ąøŖąø”ąø‡ąø„ąø§ąø²ąø”ą¹ąø•ąøąø•ą¹ˆąø²ąø‡ąø£ąø°ąø«ąø§ą¹ˆąø²ąø‡ą¹€ąø­ąøąøŖąø²ąø£ PDF ąøŖąø­ąø‡ąø‰ąøšąø±ąøš" + }, + "certSign": { + "title": "ą¹€ąø‹ą¹‡ąø™ąøŠąø·ą¹ˆąø­ąø”ą¹‰ąø§ąø¢ą¹ƒąøšąø£ąø±ąøšąø£ąø­ąø‡", + "desc": "ą¹€ąø‹ą¹‡ąø™ąøŠąø·ą¹ˆąø­ PDF ąø”ą¹‰ąø§ąø¢ą¹ƒąøšąø£ąø±ąøšąø£ąø­ąø‡/ąø„ąøµąø¢ą¹Œ (PEM/P12)" + }, + "removeCertSign": { + "title": "ąø„ąøšąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™ą¹ƒąøšąø£ąø±ąøšąø£ąø­ąø‡", + "desc": "ąø„ąøšąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™ą¹ƒąøšąø£ąø±ąøšąø£ąø­ąø‡ąøˆąø²ąø PDF" + }, + "pageLayout": { + "title": "ą¹€ąø„ąø¢ą¹Œą¹€ąø­ąø²ąø•ą¹Œąø«ąø„ąø²ąø¢ąø«ąø™ą¹‰ąø²", + "desc": "รวดหน้าหคายหน้าของเอกสาร PDF ą¹€ąø‚ą¹‰ąø²ąø”ą¹‰ąø§ąø¢ąøąø±ąø™ą¹ƒąø™ąø«ąø™ą¹‰ąø²ą¹€ąø”ąøµąø¢ąø§" + }, + "scalePages": { + "title": "ąø›ąø£ąø±ąøšąø‚ąø™ąø²ąø”/สเกคหน้า", + "desc": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąø‚ąø™ąø²ąø”/สเกคของหน้าแคะ/หรือเนื้อหาของดัน" + }, + "pipeline": { + "title": "ทณศทางงาน", + "desc": "ą¹€ąø£ąøµąø¢ąøą¹ƒąøŠą¹‰ąø‡ąø²ąø™ąø«ąø„ąø²ąø¢ąøąø²ąø£ąøąø£ąø°ąø—ąø³ą¹ƒąø™ PDF ą¹‚ąø”ąø¢ąøąø³ąø«ąø™ąø”ąøŖąø„ąø£ąø“ąø›ąø•ą¹Œ pipeline" + }, + "add-page-numbers": { + "title": "ą¹€ąøžąø“ą¹ˆąø”ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ąø«ąø™ą¹‰ąø²", + "desc": "ą¹€ąøžąø“ą¹ˆąø”ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ąø«ąø™ą¹‰ąø²ąø•ąø„ąø­ąø”ąø—ąø±ą¹‰ąø‡ą¹€ąø­ąøąøŖąø²ąø£ą¹ƒąø™ąø•ąø³ą¹ąø«ąø™ą¹ˆąø‡ąø—ąøµą¹ˆąøąø³ąø«ąø™ąø”" + }, + "auto-rename": { + "title": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąøŠąø·ą¹ˆąø­ PDF อัตโนดัตณ", + "desc": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąøŠąø·ą¹ˆąø­ą¹„ąøŸąø„ą¹Œ PDF ą¹‚ąø”ąø¢ąø­ąø±ąø•ą¹‚ąø™ąø”ąø±ąø•ąø“ąø•ąø²ąø”ąø«ąø±ąø§ąø‚ą¹‰ąø­ąø—ąøµą¹ˆąø•ąø£ąø§ąøˆąøˆąø±ąøšą¹„ąø”ą¹‰" + }, + "adjust-contrast": { + "title": "ąø›ąø£ąø±ąøšąøŖąøµ/ąø„ąø­ąø™ąø—ąø£ąø²ąøŖąø•ą¹Œ", + "desc": "ąø›ąø£ąø±ąøšąø„ąø­ąø™ąø—ąø£ąø²ąøŖąø•ą¹Œ ąø„ąø§ąø²ąø”ąø­ąø“ą¹ˆąø”ąø•ąø±ąø§ ą¹ąø„ąø°ąø„ąø§ąø²ąø”ąøŖąø§ą¹ˆąø²ąø‡ąø‚ąø­ąø‡ PDF" + }, + "crop": { + "title": "ąø„ąø£ąø­ąøšąø•ąø±ąø” PDF", + "desc": "ąø„ąø£ąø­ąøšąø•ąø±ąø” PDF ą¹€ąøžąø·ą¹ˆąø­ąø„ąø”ąø‚ąø™ąø²ąø” (รักษาข้อควาด!)" + }, + "autoSplitPDF": { + "title": "แยกหน้าอัตโนดัตณ", + "desc": "แยก PDF ąø—ąøµą¹ˆąøŖą¹ąøąø™ą¹‚ąø”ąø¢ą¹ƒąøŠą¹‰ QR Code แยกหน้า" + }, + "sanitizePdf": { + "title": "ทำควาดสะอาด", + "desc": "ąø„ąøšąøŖąø„ąø£ąø“ąø›ąø•ą¹Œą¹ąø„ąø°ąø­ąø‡ąø„ą¹Œąø›ąø£ąø°ąøąø­ąøšąø­ąø·ą¹ˆąø™ą¹† ąøˆąø²ąøą¹„ąøŸąø„ą¹Œ PDF" + }, + "URLToPDF": { + "title": "URL/ą¹€ąø§ą¹‡ąøšą¹„ąø‹ąø•ą¹Œą¹€ąø›ą¹‡ąø™ PDF", + "desc": "แปคง URL http(s) เป็น PDF" + }, + "HTMLToPDF": { + "title": "HTML เป็น PDF", + "desc": "ą¹ąø›ąø„ąø‡ą¹„ąøŸąø„ą¹Œ HTML หรือ zip เป็น PDF" + }, + "MarkdownToPDF": { + "title": "Markdown เป็น PDF", + "desc": "ą¹ąø›ąø„ąø‡ą¹„ąøŸąø„ą¹Œ Markdown เป็น PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "ąø£ąø±ąøšąø‚ą¹‰ąø­ąø”ąø¹ąø„ąø—ąø±ą¹‰ąø‡ąø«ąø”ąø”ą¹€ąøąøµą¹ˆąø¢ąø§ąøąø±ąøš PDF", + "desc": "ąø£ąø±ąøšąø‚ą¹‰ąø­ąø”ąø¹ąø„ąø—ąøµą¹ˆą¹€ąø›ą¹‡ąø™ą¹„ąø›ą¹„ąø”ą¹‰ąø—ąø±ą¹‰ąø‡ąø«ąø”ąø”ą¹€ąøąøµą¹ˆąø¢ąø§ąøąø±ąøš PDF" + }, + "extractPage": { + "title": "แยกหน้า", + "desc": "ą¹ąø¢ąøąø«ąø™ą¹‰ąø²ąø—ąøµą¹ˆą¹€ąø„ąø·ąø­ąøąøˆąø²ąø PDF" + }, + "PdfToSinglePage": { + "title": "ąø«ąø™ą¹‰ąø²ąø‚ąø™ąø²ąø”ą¹ƒąø«ąøą¹ˆą¹€ąøžąøµąø¢ąø‡ąø«ąø™ą¹‰ąø²ą¹€ąø”ąøµąø¢ąø§", + "desc": "รวดหน้าทั้งหดดของ PDF ą¹€ąø›ą¹‡ąø™ąø«ąø™ą¹‰ąø²ą¹€ąø”ąøµąø¢ąø§ąø‚ąø™ąø²ąø”ą¹ƒąø«ąøą¹ˆ" + }, + "showJS": { + "title": "แสดง Javascript", + "desc": "ค้นหาแคะแสดง Javascript ąø—ąøµą¹ˆąøąø±ąø‡ą¹ƒąø™ PDF" + }, + "autoRedact": { + "title": "ąø‹ą¹ˆąø­ąø™ąø‚ą¹‰ąø­ąø”ąø¹ąø„ąø­ąø±ąø•ą¹‚ąø™ąø”ąø±ąø•ąø“", + "desc": "ąø‹ą¹ˆąø­ąø™ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ą¹ƒąø™ PDF ą¹‚ąø”ąø¢ąø­ąø±ąø•ą¹‚ąø™ąø”ąø±ąø•ąø“ąø•ąø²ąø”ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø—ąøµą¹ˆąø›ą¹‰ąø­ąø™" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF เป็น CSV", + "desc": "ą¹ąø¢ąøąø•ąø²ąø£ąø²ąø‡ąøˆąø²ąø PDF แปคงเป็น CSV" + }, + "autoSizeSplitPDF": { + "title": "แยกตาดขนาด/ąøˆąø³ąø™ąø§ąø™", + "desc": "แยก PDF ą¹€ąø›ą¹‡ąø™ą¹€ąø­ąøąøŖąø²ąø£ąø«ąø„ąø²ąø¢ąø‰ąøšąø±ąøšąø•ąø²ąø”ąø‚ąø™ąø²ąø” ąøˆąø³ąø™ąø§ąø™ąø«ąø™ą¹‰ąø² ąø«ąø£ąø·ąø­ąøˆąø³ąø™ąø§ąø™ą¹€ąø­ąøąøŖąø²ąø£" + }, + "overlay-pdfs": { + "title": "ąø‹ą¹‰ąø­ąø™ąø—ąø±ąøš PDF", + "desc": "ąø‹ą¹‰ąø­ąø™ąø—ąø±ąøš PDF ąøšąø™ PDF ąø­ąøµąøą¹„ąøŸąø„ą¹Œąø«ąø™ąø¶ą¹ˆąø‡" + }, + "split-by-sections": { + "title": "แยก PDF ą¹€ąø›ą¹‡ąø™ąøŖą¹ˆąø§ąø™", + "desc": "ą¹ąøšą¹ˆąø‡ą¹ąø•ą¹ˆąø„ąø°ąø«ąø™ą¹‰ąø²ąø‚ąø­ąø‡ PDF ą¹€ąø›ą¹‡ąø™ąøŖą¹ˆąø§ąø™ąø¢ą¹ˆąø­ąø¢ą¹ąø™ąø§ąø™ąø­ąø™ą¹ąø„ąø°ą¹ąø™ąø§ąø•ąø±ą¹‰ąø‡" + }, + "AddStampRequest": { + "title": "ą¹€ąøžąø“ą¹ˆąø”ąø•ąø£ąø²ąø›ąø£ąø°ąø—ąø±ąøšąø„ąø‡ą¹ƒąø™ PDF", + "desc": "ą¹€ąøžąø“ą¹ˆąø”ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø«ąø£ąø·ąø­ąø•ąø£ąø²ąø›ąø£ąø°ąø—ąø±ąøšąø£ąø¹ąø›ąø ąø²ąøžą¹ƒąø™ąø•ąø³ą¹ąø«ąø™ą¹ˆąø‡ąø—ąøµą¹ˆąøąø³ąø«ąø™ąø”" + }, + "removeImagePdf": { + "title": "ąø„ąøšąø ąø²ąøžąø­ąø­ąøąøˆąø²ąø PDF", + "desc": "ąø„ąøšąø ąø²ąøžąø­ąø­ąøąøˆąø²ąø PDF ą¹€ąøžąø·ą¹ˆąø­ąø„ąø”ąø‚ąø™ąø²ąø”ą¹„ąøŸąø„ą¹Œ" + }, + "splitPdfByChapters": { + "title": "Split PDF by Chapters", + "desc": "Split a PDF into multiple files based on its chapter structure." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "replaceColorPdf": { + "title": "Replace and Invert Color", + "desc": "Replace color for text and background in PDF and invert full color of pdf to reduce file size" + } + }, + "viewPdf": { + "tags": "ดู, ąø­ą¹ˆąø²ąø™, ą¹€ąøžąø“ą¹ˆąø”ąø„ąø³ąø­ąø˜ąø“ąøšąø²ąø¢, ข้อควาด, ąø£ąø¹ąø›ąø ąø²ąøž", + "title": "View/Edit PDF", + "header": "ดู PDF" + }, + "multiTool": { + "tags": "ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø”ąø·ąø­ąø«ąø„ąø²ąø¢ąø•ąø±ąø§, หคายการดำเนณนการ, UI, คคณกแคะคาก, ąøŖą¹ˆąø§ąø™ąø«ąø™ą¹‰ąø², ąøąø±ą¹ˆąø‡ą¹„ąø„ąø„ą¹€ąø­ąø™ąø•ą¹Œ, ąø­ąø“ąø™ą¹€ąø•ąø­ąø£ą¹Œą¹ąø­ąø„ąø—ąøµąøŸ, ą¹€ąø„ąø„ąø·ą¹ˆąø­ąø™ąø¢ą¹‰ąø²ąø¢", + "title": "ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø”ąø·ąø­ PDF หคายตัว", + "header": "ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø”ąø·ąø­ PDF หคายตัว", + "uploadPrompts": "ąøŠąø·ą¹ˆąø­ą¹„ąøŸąø„ą¹Œ", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "selectPages": "Page Select", + "selectedPages": "Selected Pages", + "page": "Page", + "deleteSelected": "Delete Selected", + "downloadAll": "Export", + "downloadSelected": "Export Selected", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "Page(s) Selected", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "รวด, การดำเนณนการหน้า, ąøąø±ą¹ˆąø‡ą¹€ąø‹ąø“ąø£ą¹ŒąøŸą¹€ąø§ąø­ąø£ą¹Œ", + "title": "รวด", + "header": "รวด PDF ąø«ąø„ąø²ąø¢ą¹„ąøŸąø„ą¹Œ (2 ขึ้นไป)", + "sortByName": "ąøˆąø±ąø”ą¹€ąø£ąøµąø¢ąø‡ąø•ąø²ąø”ąøŠąø·ą¹ˆąø­", + "sortByDate": "ąøˆąø±ąø”ą¹€ąø£ąøµąø¢ąø‡ąø•ąø²ąø”ąø§ąø±ąø™ąø—ąøµą¹ˆ", + "removeCertSign": "ąø„ąøšąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™ąø”ąø“ąøˆąø“ąø—ąø±ąø„ą¹ƒąø™ą¹„ąøŸąø„ą¹Œąø—ąøµą¹ˆąø£ąø§ąø”?", + "submit": "รวด" + }, + "split": { + "tags": "การดำเนณนการหน้า, ą¹ąøšą¹ˆąø‡, หคายหน้า, ตัด, ąøąø±ą¹ˆąø‡ą¹€ąø‹ąø“ąø£ą¹ŒąøŸą¹€ąø§ąø­ąø£ą¹Œ", + "title": "แยก PDF", + "header": "แยก PDF", + "desc": { + "1": "ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ąø—ąøµą¹ˆąø„ąøøąø“ą¹€ąø„ąø·ąø­ąøąø„ąø·ąø­ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ąø«ąø™ą¹‰ąø²ąø—ąøµą¹ˆąø„ąøøąø“ąø•ą¹‰ąø­ąø‡ąøąø²ąø£ą¹ąø¢ąø", + "2": "ดังนั้นการเคือก 1,3,7-9 ąøˆąø°ąø—ąø³ą¹ƒąø«ą¹‰ą¹€ąø­ąøąøŖąø²ąø£ 10 หน้าแยกออกเป็น PDF แยก 6 ąøŠąøøąø”:", + "3": "เอกสาร #1: หน้า 1", + "4": "เอกสาร #2: หน้า 2 แคะ 3", + "5": "เอกสาร #3: หน้า 4, 5, 6, 7", + "6": "เอกสาร #4: หน้า 8", + "7": "เอกสาร #5: หน้า 9", + "8": "เอกสาร #6: หน้า 10" + }, + "splitPages": "ąø›ą¹‰ąø­ąø™ąø«ąø™ą¹‰ąø²ąø—ąøµą¹ˆąø•ą¹‰ąø­ąø‡ąøąø²ąø£ą¹ąø¢ąø:", + "submit": "แยก" + }, + "rotate": { + "tags": "ąøąø±ą¹ˆąø‡ą¹€ąø‹ąø“ąø£ą¹ŒąøŸą¹€ąø§ąø­ąø£ą¹Œ", + "title": "หดุน PDF", + "header": "หดุน PDF", + "selectAngle": "เคือกดุดการหดุน (ą¹€ąø›ą¹‡ąø™ąø«ąø„ąø²ąø¢ą¹€ąø—ą¹ˆąø²ąø‚ąø­ąø‡ 90 องศา):", + "submit": "หดุน" + }, + "imageToPdf": { + "tags": "การแปคง, ąø£ąø¹ąø›ąø ąø²ąøž, JPG, ąø ąø²ąøž, ąø£ąø¹ąø›ąø–ą¹ˆąø²ąø¢" + }, + "pdfToImage": { + "tags": "การแปคง, ąø£ąø¹ąø›ąø ąø²ąøž, JPG, ąø ąø²ąøž, ąø£ąø¹ąø›ąø–ą¹ˆąø²ąø¢", + "title": "PDF ą¹€ąø›ą¹‡ąø™ąø£ąø¹ąø›ąø ąø²ąøž", + "header": "PDF ą¹€ąø›ą¹‡ąø™ąø£ąø¹ąø›ąø ąø²ąøž", + "selectText": "ąø£ąø¹ąø›ą¹ąøšąøšąø ąø²ąøž", + "singleOrMultiple": "ąø›ąø£ąø°ą¹€ąø ąø—ąøœąø„ąø„ąø±ąøžąø˜ą¹Œąø£ąø¹ąø›ąø ąø²ąøž", + "single": "ąø£ąø¹ąø›ąø ąø²ąøžą¹ƒąø«ąøą¹ˆą¹€ąøžąøµąø¢ąø‡ąø ąø²ąøžą¹€ąø”ąøµąø¢ąø§", + "multi": "ąø«ąø„ąø²ąø¢ąø ąø²ąøž", + "colorType": "ประเภทสี", + "color": "ąøŖąøµ", + "grey": "ąø£ąø°ąø”ąø±ąøšąøŖąøµą¹€ąø—ąø²", + "blackwhite": "ขาวดำ (ąø­ąø²ąøˆąøŖąø¹ąøą¹€ąøŖąøµąø¢ąø‚ą¹‰ąø­ąø”ąø¹ąø„!)", + "submit": "แปคง", + "info": "Python ą¹„ąø”ą¹ˆąø”ąøµąøąø²ąø£ąø•ąø“ąø”ąø•ąø±ą¹‰ąø‡ ąøˆąø³ą¹€ąø›ą¹‡ąø™ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ą¹ąø›ąø„ąø‡ WebP", + "placeholder": "(ą¹€ąøŠą¹ˆąø™ 1,2,8 หรือ 4,7,12-16 หรือ 2n-1)" + }, + "pdfOrganiser": { + "tags": "สองหน้า, ąø„ąø¹ą¹ˆąø‚ąø™ąø²ąø™, ą¹€ąø£ąøµąø¢ąø‡ąø„ąø³ąø”ąø±ąøš, ą¹€ąø„ąø„ąø·ą¹ˆąø­ąø™ąø¢ą¹‰ąø²ąø¢", + "title": "ąø•ąø±ąø§ąøˆąø±ąø”ąø£ąø°ą¹€ąøšąøµąø¢ąøšąø«ąø™ą¹‰ąø²", + "header": "ąø•ąø±ąø§ąøˆąø±ąø”ąø£ąø°ą¹€ąøšąøµąø¢ąøšąø«ąø™ą¹‰ąø² PDF", + "submit": "ąøˆąø±ąø”ą¹€ąø£ąøµąø¢ąø‡ąø«ąø™ą¹‰ąø²ą¹ƒąø«ąø”ą¹ˆ", + "mode": { + "_value": "โหดด", + "1": "ą¹€ąø£ąøµąø¢ąø‡ąø„ąø³ąø”ąø±ąøšąø«ąø™ą¹‰ąø²ąø•ąø²ąø”ąø„ąø§ąø²ąø”ąø•ą¹‰ąø­ąø‡ąøąø²ąø£", + "2": "ą¹€ąø£ąøµąø¢ąø‡ąø„ąø³ąø”ąø±ąøšąø¢ą¹‰ąø­ąø™ąøąø„ąø±ąøš", + "3": "ą¹€ąø£ąøµąø¢ąø‡ąø„ąø³ąø”ąø±ąøšą¹ąøšąøšąøŖąø­ąø‡ąø«ąø™ą¹‰ąø²", + "4": "ą¹€ąø£ąøµąø¢ąø‡ąø„ąø³ąø”ąø±ąøšą¹ąøšąøšąøŖąø”ąøøąø”", + "5": "ą¹€ąø£ąøµąø¢ąø‡ąø„ąø³ąø”ąø±ąøšą¹ąøšąøšą¹€ąø¢ą¹‡ąøšąø‚ą¹‰ąø²ąø‡", + "6": "ą¹ąø¢ąøąø«ąø™ą¹‰ąø²ą¹ąøšąøšąø„ąøµą¹ˆ-ąø„ąø¹ą¹ˆ", + "7": "ąø„ąøšąø«ąø™ą¹‰ąø²ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ą¹ąø£ąø", + "8": "ąø„ąøšąø«ąø™ą¹‰ąø²ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ąøŖąøøąø”ąø—ą¹‰ąø²ąø¢", + "9": "ąø„ąøšąø«ąø™ą¹‰ąø²ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ą¹ąø£ąøą¹ąø„ąø°ąøŖąøøąø”ąø—ą¹‰ąø²ąø¢", + "10": "ąø£ąø§ąø”ąø«ąø™ą¹‰ąø²ą¹ąøšąøšąø„ąøµą¹ˆ-ąø„ąø¹ą¹ˆ", + "11": "Duplicate all pages" + }, + "placeholder": "(ą¹€ąøŠą¹ˆąø™ 1,3,2 หรือ 4-8,2,10-12 หรือ 2n-1)" + }, + "addImage": { + "tags": "ąø£ąø¹ąø›ąø ąø²ąøž, JPG, ąø ąø²ąøž, ąø£ąø¹ąø›ąø–ą¹ˆąø²ąø¢", + "title": "ą¹€ąøžąø“ą¹ˆąø”ąø£ąø¹ąø›ąø ąø²ąøž", + "header": "ą¹€ąøžąø“ą¹ˆąø”ąø£ąø¹ąø›ąø ąø²ąøžą¹ƒąø™ PDF", + "everyPage": "ทุกหน้า?", + "upload": "ą¹€ąøžąø“ą¹ˆąø”ąø£ąø¹ąø›ąø ąø²ąøž", + "submit": "ą¹€ąøžąø“ą¹ˆąø”ąø£ąø¹ąø›ąø ąø²ąøž" + }, + "watermark": { + "tags": "ข้อควาด, ซ้ำ, ป้าย, ของคุณเอง, ąø„ąø“ąø‚ąøŖąø“ąø—ąø˜ąø“ą¹Œ, ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø«ąø”ąø²ąø¢ąøąø²ąø£ąø„ą¹‰ąø², ąø£ąø¹ąø›ąø ąø²ąøž, JPG, ąø ąø²ąøž, ąø£ąø¹ąø›ąø–ą¹ˆąø²ąø¢", + "title": "ą¹€ąøžąø“ą¹ˆąø”ąø„ąø²ąø¢ąø™ą¹‰ąø³", + "header": "ą¹€ąøžąø“ą¹ˆąø”ąø„ąø²ąø¢ąø™ą¹‰ąø³", + "customColor": "ąøŖąøµąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø—ąøµą¹ˆąøąø³ąø«ąø™ąø”ą¹€ąø­ąø‡", + "selectText": { + "1": "เคือก PDF ą¹€ąøžąø·ą¹ˆąø­ą¹€ąøžąø“ą¹ˆąø”ąø„ąø²ąø¢ąø™ą¹‰ąø³:", + "2": "ข้อควาดคายน้ำ:", + "3": "ąø‚ąø™ąø²ąø”ąøŸąø­ąø™ąø•ą¹Œ:", + "4": "การหดุน (0-360):", + "5": "ตัวเว้นระยะควาดกว้าง (ąøŠą¹ˆąø­ąø‡ąø§ą¹ˆąø²ąø‡ąø£ąø°ąø«ąø§ą¹ˆąø²ąø‡ąø„ąø²ąø¢ąø™ą¹‰ąø³ą¹ƒąø™ą¹ąø™ąø§ąø™ąø­ąø™):", + "6": "ตัวเว้นระยะควาดสูง (ąøŠą¹ˆąø­ąø‡ąø§ą¹ˆąø²ąø‡ąø£ąø°ąø«ąø§ą¹ˆąø²ąø‡ąø„ąø²ąø¢ąø™ą¹‰ąø³ą¹ƒąø™ą¹ąø™ąø§ąø•ąø±ą¹‰ąø‡):", + "7": "ąø„ąø§ąø²ąø”ąø—ąø¶ąøš (0% - 100%):", + "8": "ประเภทคายน้ำ:", + "9": "ąø ąø²ąøžąø„ąø²ąø¢ąø™ą¹‰ąø³:", + "10": "Convert PDF to PDF-Image" + }, + "submit": "ą¹€ąøžąø“ą¹ˆąø”ąø„ąø²ąø¢ąø™ą¹‰ąø³", + "type": { + "1": "ข้อควาด", + "2": "ąø ąø²ąøž" + } + }, + "permissions": { + "tags": "ąø­ą¹ˆąø²ąø™, เขียน, แก้ไข, ąøžąø“ąø”ąøžą¹Œ", + "title": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąøŖąø“ąø—ąø˜ąø“ą¹Œ", + "header": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąøŖąø“ąø—ąø˜ąø“ą¹Œ", + "warning": "คำเตือน: ąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ąøŖąø“ąø—ąø˜ąø“ą¹Œą¹€ąø«ąø„ą¹ˆąø²ąø™ąøµą¹‰ą¹€ąø›ą¹‡ąø™ąøąø²ąø£ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ą¹ąø›ąø„ąø‡ąø—ąøµą¹ˆą¹„ąø”ą¹ˆąøŖąø²ąø”ąø²ąø£ąø–ąø¢ą¹‰ąø­ąø™ąøąø„ąø±ąøšą¹„ąø”ą¹‰ ą¹ąø™ąø°ąø™ąø³ą¹ƒąø«ą¹‰ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ąøžąø£ą¹‰ąø­ąø”ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ąøœą¹ˆąø²ąø™ąø«ąø™ą¹‰ąø²ąøąø²ąø£ą¹€ąøžąø“ą¹ˆąø”ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™", + "selectText": { + "1": "เคือก PDF ą¹€ąøžąø·ą¹ˆąø­ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąøŖąø“ąø—ąø˜ąø“ą¹Œ", + "2": "ąøŖąø“ąø—ąø˜ąø“ą¹Œąø—ąøµą¹ˆąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²", + "3": "ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ąøąø²ąø£ąø›ąø£ąø°ąøąø­ąøšą¹€ąø­ąøąøŖąø²ąø£", + "4": "ป้องกันการสกัดเนื้อหา", + "5": "ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ąøąø²ąø£ąøŖąøąø±ąø”ą¹€ąøžąø·ą¹ˆąø­ąøąø²ąø£ą¹€ąø‚ą¹‰ąø²ąø–ąø¶ąø‡", + "6": "ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ąøąø²ąø£ąøąø£ąø­ąøą¹ąøšąøšąøŸąø­ąø£ą¹Œąø”", + "7": "ป้องกันการแก้ไข", + "8": "ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ąøąø²ąø£ą¹ąøą¹‰ą¹„ąø‚ąø„ąø³ąø­ąø˜ąø“ąøšąø²ąø¢ąø›ąø£ąø°ąøąø­ąøš", + "9": "ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ąøąø²ąø£ąøžąø“ąø”ąøžą¹Œ", + "10": "ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ąøąø²ąø£ąøžąø“ąø”ąøžą¹Œąø£ąø¹ąø›ą¹ąøšąøšąø•ą¹ˆąø²ąø‡ą¹†" + }, + "submit": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™" + }, + "removePages": { + "tags": "ąø„ąøšąø«ąø™ą¹‰ąø², ąø„ąøšąø«ąø™ą¹‰ąø²" + }, + "addPassword": { + "tags": "ปคอดภัย, ควาดปคอดภัย", + "title": "ą¹€ąøžąø“ą¹ˆąø”ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™", + "header": "ą¹€ąøžąø“ą¹ˆąø”ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ (เข้ารหัส)", + "selectText": { + "1": "เคือก PDF ą¹€ąøžąø·ą¹ˆąø­ą¹€ąø‚ą¹‰ąø²ąø£ąø«ąø±ąøŖ", + "2": "ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰", + "3": "ąø„ąø§ąø²ąø”ąø¢ąø²ąø§ąø„ąøµąø¢ą¹Œąøąø²ąø£ą¹€ąø‚ą¹‰ąø²ąø£ąø«ąø±ąøŖ", + "4": "ąø„ą¹ˆąø²ąøŖąø¹ąø‡ąøąø§ą¹ˆąø²ąø”ąøµąø„ąø§ąø²ąø”ą¹ąø‚ą¹‡ąø‡ą¹ąøąø£ą¹ˆąø‡ąøąø§ą¹ˆąø² ą¹ąø•ą¹ˆąø„ą¹ˆąø²ąø•ą¹ˆąø³ąøąø§ą¹ˆąø²ą¹€ąø‚ą¹‰ąø²ąøąø±ąø™ą¹„ąø”ą¹‰ąø”ąøµąøąø§ą¹ˆąø²", + "5": "ąøŖąø“ąø—ąø˜ąø“ą¹Œąø—ąøµą¹ˆąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø² (ą¹ąø™ąø°ąø™ąø³ą¹ƒąø«ą¹‰ą¹ƒąøŠą¹‰ąøžąø£ą¹‰ąø­ąø”ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ąøœąø¹ą¹‰ąø”ąø¹ą¹ąø„)", + "6": "ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ąøąø²ąø£ąø›ąø£ąø°ąøąø­ąøšą¹€ąø­ąøąøŖąø²ąø£", + "7": "ป้องกันการสกัดเนื้อหา", + "8": "ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ąøąø²ąø£ąøŖąøąø±ąø”ą¹€ąøžąø·ą¹ˆąø­ąøąø²ąø£ą¹€ąø‚ą¹‰ąø²ąø–ąø¶ąø‡", + "9": "ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ąøąø²ąø£ąøąø£ąø­ąøą¹ąøšąøšąøŸąø­ąø£ą¹Œąø”", + "10": "ป้องกันการแก้ไข", + "11": "ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ąøąø²ąø£ą¹ąøą¹‰ą¹„ąø‚ąø„ąø³ąø­ąø˜ąø“ąøšąø²ąø¢ąø›ąø£ąø°ąøąø­ąøš", + "12": "ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ąøąø²ąø£ąøžąø“ąø”ąøžą¹Œ", + "13": "ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ąøąø²ąø£ąøžąø“ąø”ąøžą¹Œąø£ąø¹ąø›ą¹ąøšąøšąø•ą¹ˆąø²ąø‡ą¹†", + "14": "ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ąøœąø¹ą¹‰ąø”ąø¹ą¹ąø„", + "15": "ąøˆąø³ąøąø±ąø”ąøŖąø“ą¹ˆąø‡ąø—ąøµą¹ˆąøŖąø²ąø”ąø²ąø£ąø–ąø—ąø³ą¹„ąø”ą¹‰ąøąø±ąøšą¹€ąø­ąøąøŖąø²ąø£ą¹€ąø”ąø·ą¹ˆąø­ą¹€ąø›ąø“ąø” (ą¹„ąø”ą¹ˆąø£ąø­ąø‡ąø£ąø±ąøšą¹‚ąø”ąø¢ąøœąø¹ą¹‰ąø­ą¹ˆąø²ąø™ąø—ąø±ą¹‰ąø‡ąø«ąø”ąø”)", + "16": "ąøˆąø³ąøąø±ąø”ąøąø²ąø£ą¹€ąø›ąø“ąø”ą¹€ąø­ąøąøŖąø²ąø£" + }, + "submit": "เข้ารหัส" + }, + "removePassword": { + "tags": "ปคอดภัย, ถอดรหัส, ควาดปคอดภัย, ąø„ąøšąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™", + "title": "ąø„ąøšąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™", + "header": "ąø„ąøšąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ (ถอดรหัส)", + "selectText": { + "1": "เคือก PDF ąø—ąøµą¹ˆąø•ą¹‰ąø­ąø‡ąøąø²ąø£ąø–ąø­ąø”ąø£ąø«ąø±ąøŖ", + "2": "ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™" + }, + "submit": "คบ" + }, + "compressPdfs": { + "tags": "ย่อ, เค็ก, ąøˆąø“ą¹‹ąø§" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "ชื่อ, ąøœąø¹ą¹‰ą¹ąø•ą¹ˆąø‡, ąø§ąø±ąø™ąø—ąøµą¹ˆ, สร้าง, เวคา, ąøœąø¹ą¹‰ą¹€ąøœąø¢ą¹ąøžąø£ą¹ˆ, ąøœąø¹ą¹‰ąøœąø„ąø“ąø•, ąøŖąø–ąø“ąø•ąø“", + "title": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąø‚ą¹‰ąø­ąø”ąø¹ąø„ą¹€ąø”ąø•ąø²", + "header": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąø‚ą¹‰ąø­ąø”ąø¹ąø„ą¹€ąø”ąø•ąø²", + "selectText": { + "1": "ą¹‚ąø›ąø£ąø”ą¹ąøą¹‰ą¹„ąø‚ąø•ąø±ąø§ą¹ąø›ąø£ąø—ąøµą¹ˆąø„ąøøąø“ąø•ą¹‰ąø­ąø‡ąøąø²ąø£ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™", + "2": "ąø„ąøšąø‚ą¹‰ąø­ąø”ąø¹ąø„ą¹€ąø”ąø•ąø²ąø—ąø±ą¹‰ąø‡ąø«ąø”ąø”", + "3": "ą¹ąøŖąø”ąø‡ąø‚ą¹‰ąø­ąø”ąø¹ąø„ą¹€ąø”ąø•ąø²ąø—ąøµą¹ˆąøąø³ąø«ąø™ąø”ą¹€ąø­ąø‡:", + "4": "ąø‚ą¹‰ąø­ąø”ąø¹ąø„ą¹€ąø”ąø•ąø²ąø­ąø·ą¹ˆąø™ ๆ:", + "5": "ą¹€ąøžąø“ą¹ˆąø”ąø£ąø²ąø¢ąøąø²ąø£ąø‚ą¹‰ąø­ąø”ąø¹ąø„ą¹€ąø”ąø•ąø²ąø—ąøµą¹ˆąøąø³ąø«ąø™ąø”ą¹€ąø­ąø‡" + }, + "author": "ąøœąø¹ą¹‰ą¹ąø•ą¹ˆąø‡:", + "creationDate": "ąø§ąø±ąø™ąø—ąøµą¹ˆąøŖąø£ą¹‰ąø²ąø‡ (yyyy/MM/dd HH:mm:ss):", + "creator": "ąøœąø¹ą¹‰ąøŖąø£ą¹‰ąø²ąø‡:", + "keywords": "ąø„ąø³ąøŖąø³ąø„ąø±ąø:", + "modDate": "ąø§ąø±ąø™ąø—ąøµą¹ˆą¹ąøą¹‰ą¹„ąø‚ (yyyy/MM/dd HH:mm:ss):", + "producer": "ąøœąø¹ą¹‰ąøœąø„ąø“ąø•:", + "subject": "หัวข้อ:", + "trapped": "ąø•ąø“ąø”ąøąø±ąøš:", + "submit": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™" + }, + "fileToPDF": { + "tags": "การแปคง, ąø£ąø¹ąø›ą¹ąøšąøš, เอกสาร, ąø£ąø¹ąø›ąø ąø²ąøž, ąøŖą¹„ąø„ąø”ą¹Œ, ข้อควาด, การแปคง, สำนักงาน, เอกสาร, Word, Excel, PowerPoint", + "title": "ą¹„ąøŸąø„ą¹Œą¹€ąø›ą¹‡ąø™ PDF", + "header": "ą¹ąø›ąø„ąø‡ą¹„ąøŸąø„ą¹Œą¹ƒąø”ą¹† เป็น PDF", + "credit": "ąøšąø£ąø“ąøąø²ąø£ąø™ąøµą¹‰ą¹ƒąøŠą¹‰ LibreOffice แคะ Unoconv ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ą¹ąø›ąø„ąø‡ą¹„ąøŸąø„ą¹Œ", + "supportedFileTypesInfo": "ąø›ąø£ąø°ą¹€ąø ąø—ą¹„ąøŸąø„ą¹Œąø—ąøµą¹ˆąø£ąø­ąø‡ąø£ąø±ąøš", + "supportedFileTypes": "ąø›ąø£ąø°ą¹€ąø ąø—ą¹„ąøŸąø„ą¹Œąø—ąøµą¹ˆąø£ąø­ąø‡ąø£ąø±ąøšąø„ąø§ąø£ąø”ąøµąø£ąø²ąø¢ąøąø²ąø£ąø”ą¹‰ąø²ąø™ąø„ą¹ˆąø²ąø‡ ąø­ąø¢ą¹ˆąø²ąø‡ą¹„ąø£ąøą¹‡ąø•ąø²ąø”ąøŖąø³ąø«ąø£ąø±ąøšąø£ąø²ąø¢ąøąø²ąø£ąø£ąø¹ąø›ą¹ąøšąøšąø—ąøµą¹ˆąø£ąø­ąø‡ąø£ąø±ąøšąø—ąø±ą¹‰ąø‡ąø«ąø”ąø” กรุณาดูเอกสาร LibreOffice", + "submit": "แปคงเป็น PDF" + }, + "ocr": { + "tags": "ąøąø²ąø£ąø£ąø¹ą¹‰ąøˆąø³, ข้อควาด, ąø£ąø¹ąø›ąø ąø²ąøž, การสแกน, ąø­ą¹ˆąø²ąø™, ระบุ, ąø•ąø£ąø§ąøˆąøˆąø±ąøš, แก้ไขได้", + "title": "OCR / ทำควาดสะอาดการสแกน", + "header": "ทำควาดสะอาดการสแกน / OCR (ąøąø²ąø£ąø£ąø¹ą¹‰ąøˆąø³ąø­ąø±ąøąø‚ąø£ąø°ąø”ą¹‰ąø§ąø¢ą¹ąøŖąø‡)", + "selectText": { + "1": "ą¹€ąø„ąø·ąø­ąøąø ąø²ąø©ąø²ąø—ąøµą¹ˆąøˆąø°ąø•ąø£ąø§ąøˆąøˆąø±ąøšą¹ƒąø™ PDF (ąø£ąø²ąø¢ąøąø²ąø£ąø—ąøµą¹ˆą¹ąøŖąø”ąø‡ąø„ąø·ąø­ąø ąø²ąø©ąø²ąø—ąøµą¹ˆąø•ąø£ąø§ąøˆąøˆąø±ąøšą¹„ąø”ą¹‰ą¹ƒąø™ąø‚ąø“ąø°ąø™ąøµą¹‰):", + "2": "ąøŖąø£ą¹‰ąø²ąø‡ą¹„ąøŸąø„ą¹Œąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø—ąøµą¹ˆąø”ąøµąø‚ą¹‰ąø­ąø„ąø§ąø²ąø” OCR ąø„ąø§ąøšąø„ąø¹ą¹ˆą¹„ąø›ąøąø±ąøš PDF ąø—ąøµą¹ˆ OCR แค้ว", + "3": "ą¹ąøą¹‰ą¹„ąø‚ąø«ąø™ą¹‰ąø²ąø—ąøµą¹ˆąøŖą¹ąøąø™ą¹€ąø­ąøµąø¢ąø‡ą¹‚ąø”ąø¢ąøąø²ąø£ąø«ąø”ąøøąø™ąøąø„ąø±ąøšą¹„ąø›ąø¢ąø±ąø‡ąø•ąø³ą¹ąø«ąø™ą¹ˆąø‡ąø—ąøµą¹ˆąø–ąø¹ąøąø•ą¹‰ąø­ąø‡", + "4": "ąø—ąø³ąø„ąø§ąø²ąø”ąøŖąø°ąø­ąø²ąø”ąø«ąø™ą¹‰ąø²ą¹€ąøžąø·ą¹ˆąø­ąø„ąø”ą¹‚ąø­ąøąø²ąøŖąø—ąøµą¹ˆ OCR ąøˆąø°ąøžąøšąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ą¹ƒąø™ą¹€ąøŖąøµąø¢ąø‡ąøžąø·ą¹‰ąø™ąø«ąø„ąø±ąø‡ (ą¹„ąø”ą¹ˆąø”ąøµąøąø²ąø£ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ą¹ąø›ąø„ąø‡ą¹ƒąø™ąøœąø„ąø„ąø±ąøžąø˜ą¹Œ)", + "5": "ąø—ąø³ąø„ąø§ąø²ąø”ąøŖąø°ąø­ąø²ąø”ąø«ąø™ą¹‰ąø²ą¹€ąøžąø·ą¹ˆąø­ąø„ąø”ą¹‚ąø­ąøąø²ąøŖąø—ąøµą¹ˆ OCR ąøˆąø°ąøžąøšąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ą¹ƒąø™ą¹€ąøŖąøµąø¢ąø‡ąøžąø·ą¹‰ąø™ąø«ąø„ąø±ąø‡ ąø£ąø±ąøąø©ąø²ąøąø²ąø£ąø—ąø³ąø„ąø§ąø²ąø”ąøŖąø°ąø­ąø²ąø”ą¹ƒąø™ąøœąø„ąø„ąø±ąøžąø˜ą¹Œ", + "6": "ą¹„ąø”ą¹ˆąøŖąø™ą¹ƒąøˆąø«ąø™ą¹‰ąø²ąø—ąøµą¹ˆąø”ąøµąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ą¹ąøšąøšą¹‚ąø•ą¹‰ąø•ąø­ąøš OCR ą¹€ąø‰ąøžąø²ąø°ąø«ąø™ą¹‰ąø²ąø—ąøµą¹ˆą¹€ąø›ą¹‡ąø™ąø ąø²ąøž", + "7": "ąøšąø±ąø‡ąø„ąø±ąøš OCR จะ OCR ąø—ąøøąøąø«ąø™ą¹‰ąø²ąø„ąøšąø­ąø‡ąø„ą¹Œąø›ąø£ąø°ąøąø­ąøšąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø•ą¹‰ąø™ąø‰ąøšąø±ąøšąø—ąø±ą¹‰ąø‡ąø«ąø”ąø”", + "8": "ปกตณ (ąøˆąø°ą¹ąøŖąø”ąø‡ąø‚ą¹‰ąø­ąøœąø“ąø”ąøžąø„ąø²ąø”ąø«ąø²ąø PDF ดีข้อควาด)", + "9": "ąøąø²ąø£ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ą¹€ąøžąø“ą¹ˆąø”ą¹€ąø•ąø“ąø”", + "10": "โหดด OCR", + "11": "ąø„ąøšąø ąø²ąøžąø«ąø„ąø±ąø‡ąøˆąø²ąø OCR (ąø„ąøšąø ąø²ąøžąø—ąø±ą¹‰ąø‡ąø«ąø”ąø”, ąø”ąøµąø›ąø£ąø°ą¹‚ąø¢ąøŠąø™ą¹Œą¹€ąø‰ąøžąø²ąø°ąø«ąø²ąøą¹€ąø›ą¹‡ąø™ąøŖą¹ˆąø§ąø™ąø«ąø™ąø¶ą¹ˆąø‡ąø‚ąø­ąø‡ąø‚ąø±ą¹‰ąø™ąø•ąø­ąø™ąøąø²ąø£ą¹ąø›ąø„ąø‡)", + "12": "ąø›ąø£ąø°ą¹€ąø ąø—ąøąø²ąø£ą¹€ąø£ąø™ą¹€ąø”ąø­ąø£ą¹Œ (ขั้นสูง)" + }, + "help": "ą¹‚ąø›ąø£ąø”ąø­ą¹ˆąø²ąø™ą¹€ąø­ąøąøŖąø²ąø£ąø™ąøµą¹‰ą¹€ąøžąø·ą¹ˆąø­ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ąø ąø²ąø©ąø²ąø­ąø·ą¹ˆąø™ą¹† แคะ/ąø«ąø£ąø·ąø­ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ąø™ąø­ąø docker", + "credit": "ąøšąø£ąø“ąøąø²ąø£ąø™ąøµą¹‰ą¹ƒąøŠą¹‰ qpdf แคะ Tesseract สำหรับ OCR", + "submit": "ąø›ąø£ąø°ąø”ąø§ąø„ąøœąø„ PDF ด้วย OCR" + }, + "extractImages": { + "tags": "ąø£ąø¹ąø›ąø ąø²ąøž, ąø ąø²ąøž, ąøšąø±ąø™ąø—ąø¶ąø, ą¹€ąøą¹‡ąøšąø–ąø²ąø§ąø£, zip, จับ, รับ", + "title": "ą¹ąø¢ąøąø£ąø¹ąø›ąø ąø²ąøž", + "header": "ą¹ąø¢ąøąø£ąø¹ąø›ąø ąø²ąøž", + "selectText": "ą¹€ąø„ąø·ąø­ąøąø£ąø¹ąø›ą¹ąøšąøšąø ąø²ąøžąø—ąøµą¹ˆąøˆąø°ą¹ƒąøŠą¹‰ą¹ƒąø™ąøąø²ąø£ą¹ąø›ąø„ąø‡ąø£ąø¹ąø›ąø ąø²ąøžąø—ąøµą¹ˆą¹ąø¢ąøą¹„ąø”ą¹‰", + "allowDuplicates": "ąøšąø±ąø™ąø—ąø¶ąøąø„ąø²ąø¢ąø‹ą¹‰ąø³", + "submit": "แยก" + }, + "pdfToPDFA": { + "tags": "ąøąø²ąø£ąøˆąø±ąø”ą¹€ąøą¹‡ąøš, ระยะยาว, ดาตรฐาน, การแปคง, ąøąø²ąø£ą¹€ąøą¹‡ąøšąø£ąø±ąøąø©ąø²", + "title": "PDF เป็น PDF/A", + "header": "PDF เป็น PDF/A", + "credit": "ąøšąø£ąø“ąøąø²ąø£ąø™ąøµą¹‰ą¹ƒąøŠą¹‰ libreoffice ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ą¹ąø›ąø„ąø‡ PDF/A", + "submit": "แปคง", + "tip": "ąø›ąø±ąøˆąøˆąøøąøšąø±ąø™ą¹„ąø”ą¹ˆąø—ąø³ąø‡ąø²ąø™ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ąø›ą¹‰ąø­ąø™ąø‚ą¹‰ąø­ąø”ąø¹ąø„ąø«ąø„ąø²ąø¢ąø£ąø²ąø¢ąøąø²ąø£ąøžąø£ą¹‰ąø­ąø”ąøąø±ąø™", + "outputFormat": "ąø£ąø¹ąø›ą¹ąøšąøšąøœąø„ąø„ąø±ąøžąø˜ą¹Œ", + "pdfWithDigitalSignature": "PDF ąø”ąøµąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™ąø”ąø“ąøˆąø“ąø—ąø±ąø„ ąø‹ąø¶ą¹ˆąø‡ąøˆąø°ąø–ąø¹ąøąø„ąøšą¹ƒąø™ąø‚ąø±ą¹‰ąø™ąø•ąø­ąø™ąø–ąø±ąø”ą¹„ąø›" + }, + "PDFToWord": { + "tags": "doc, docx, odt, word, การแปคง, ąø£ąø¹ąø›ą¹ąøšąøš, การแปคง, สำนักงาน, microsoft, docfile", + "title": "PDF เป็น Word", + "header": "PDF เป็น Word", + "selectText": { + "1": "ąø£ąø¹ąø›ą¹ąøšąøšą¹„ąøŸąø„ą¹Œąøœąø„ąø„ąø±ąøžąø˜ą¹Œ" + }, + "credit": "ąøšąø£ąø“ąøąø²ąø£ąø™ąøµą¹‰ą¹ƒąøŠą¹‰ LibreOffice ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ą¹ąø›ąø„ąø‡ą¹„ąøŸąø„ą¹Œ", + "submit": "แปคง" + }, + "PDFToPresentation": { + "tags": "ąøŖą¹„ąø„ąø”ą¹Œ, ą¹‚ąøŠąø§ą¹Œ, สำนักงาน, microsoft", + "title": "PDF เป็น Presentation", + "header": "PDF เป็น Presentation", + "selectText": { + "1": "ąø£ąø¹ąø›ą¹ąøšąøšą¹„ąøŸąø„ą¹Œąøœąø„ąø„ąø±ąøžąø˜ą¹Œ" + }, + "credit": "ąøšąø£ąø“ąøąø²ąø£ąø™ąøµą¹‰ą¹ƒąøŠą¹‰ LibreOffice ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ą¹ąø›ąø„ąø‡ą¹„ąøŸąø„ą¹Œ", + "submit": "แปคง" + }, + "PDFToText": { + "tags": "ąø£ąø¹ąø›ą¹ąøšąøšąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø—ąøµą¹ˆąø”ąøµąø„ąøøąø“ąø ąø²ąøž, rich text format", + "title": "PDF เป็น RTF (Text)", + "header": "PDF เป็น RTF (Text)", + "selectText": { + "1": "ąø£ąø¹ąø›ą¹ąøšąøšą¹„ąøŸąø„ą¹Œąøœąø„ąø„ąø±ąøžąø˜ą¹Œ" + }, + "credit": "ąøšąø£ąø“ąøąø²ąø£ąø™ąøµą¹‰ą¹ƒąøŠą¹‰ LibreOffice ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ą¹ąø›ąø„ąø‡ą¹„ąøŸąø„ą¹Œ", + "submit": "แปคง" + }, + "PDFToHTML": { + "tags": "ą¹€ąø™ąø·ą¹‰ąø­ąø«ąø²ą¹€ąø§ą¹‡ąøš, ą¹€ąø›ą¹‡ąø™ąø”ąø“ąø•ąø£ąøąø±ąøšą¹€ąøšąø£ąø²ąø§ą¹Œą¹€ąø‹ąø­ąø£ą¹Œ", + "title": "PDF เป็น HTML", + "header": "PDF เป็น HTML", + "credit": "ąøšąø£ąø“ąøąø²ąø£ąø™ąøµą¹‰ą¹ƒąøŠą¹‰ pdftohtml ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ą¹ąø›ąø„ąø‡ą¹„ąøŸąø„ą¹Œ", + "submit": "แปคง" + }, + "PDFToXML": { + "tags": "การแยกข้อดูค, เนื้อหาโครงสร้าง, ąøąø²ąø£ąø—ąø³ąø‡ąø²ąø™ąø£ą¹ˆąø§ąø”ąøąø±ąø™, การแปคง", + "title": "PDF เป็น XML", + "header": "PDF เป็น XML", + "credit": "ąøšąø£ąø“ąøąø²ąø£ąø™ąøµą¹‰ą¹ƒąøŠą¹‰ LibreOffice ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ą¹ąø›ąø„ąø‡ą¹„ąøŸąø„ą¹Œ", + "submit": "แปคง" + }, + "ScannerImageSplit": { + "tags": "แยก, ąø•ąø£ąø§ąøˆąøˆąø±ąøšąø­ąø±ąø•ą¹‚ąø™ąø”ąø±ąø•ąø“, การสแกน, ąø£ąø¹ąø›ąø ąø²ąøžąø«ąø„ąø²ąø¢ąø£ąø¹ąø›, ąøˆąø±ąø”ąø£ąø°ą¹€ąøšąøµąø¢ąøš", + "selectText": { + "1": "ą¹€ąøąø“ąø‘ą¹Œąø”ąøøąø”:", + "2": "ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ąø”ąøøąø”ąø‚ąø±ą¹‰ąø™ąø•ą¹ˆąø³ąø—ąøµą¹ˆąøˆąø³ą¹€ąø›ą¹‡ąø™ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ąø«ąø”ąøøąø™ąø ąø²ąøž (ąø„ą¹ˆąø²ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™: 10)", + "3": "ควาดอดทน:", + "4": "ąøąø³ąø«ąø™ąø”ąøŠą¹ˆąø§ąø‡ąø„ąø§ąø²ąø”ą¹ąø•ąøąø•ą¹ˆąø²ąø‡ąø‚ąø­ąø‡ąøŖąøµąø£ąø­ąøšąøŖąøµąøžąø·ą¹‰ąø™ąø«ąø„ąø±ąø‡ąø—ąøµą¹ˆąø„ąø²ąø”ąø„ąø°ą¹€ąø™ (ąø„ą¹ˆąø²ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™: 30)", + "5": "ąøžąø·ą¹‰ąø™ąø—ąøµą¹ˆąø‚ąø±ą¹‰ąø™ąø•ą¹ˆąø³:", + "6": "ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ą¹€ąøąø“ąø‘ą¹Œąøžąø·ą¹‰ąø™ąø—ąøµą¹ˆąø‚ąø±ą¹‰ąø™ąø•ą¹ˆąø³ąøŖąø³ąø«ąø£ąø±ąøšąø£ąø¹ąø›ąø ąø²ąøž (ąø„ą¹ˆąø²ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™: 10000)", + "7": "ąøžąø·ą¹‰ąø™ąø—ąøµą¹ˆą¹€ąø„ą¹‰ąø²ą¹‚ąø„ąø£ąø‡ąø‚ąø±ą¹‰ąø™ąø•ą¹ˆąø³:", + "8": "ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ą¹€ąøąø“ąø‘ą¹Œąøžąø·ą¹‰ąø™ąø—ąøµą¹ˆą¹€ąø„ą¹‰ąø²ą¹‚ąø„ąø£ąø‡ąø‚ąø±ą¹‰ąø™ąø•ą¹ˆąø³ąøŖąø³ąø«ąø£ąø±ąøšąø£ąø¹ąø›ąø ąø²ąøž", + "9": "ąø‚ąø™ąø²ąø”ąø‚ąø­ąøš:", + "10": "ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ąø‚ąø™ąø²ąø”ąø‚ąø­ąøšąø—ąøµą¹ˆą¹€ąøžąø“ą¹ˆąø”ą¹ąø„ąø°ąø„ąøšą¹€ąøžąø·ą¹ˆąø­ąø›ą¹‰ąø­ąø‡ąøąø±ąø™ąø‚ąø­ąøšąø‚ąø²ąø§ą¹ƒąø™ąøœąø„ąø„ąø±ąøžąø˜ą¹Œ (ąø„ą¹ˆąø²ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™: 1)" + }, + "info": "Python ą¹„ąø”ą¹ˆąø”ąøµąøąø²ąø£ąø•ąø“ąø”ąø•ąø±ą¹‰ąø‡ ąøąø£ąøøąø“ąø²ąø•ąø“ąø”ąø•ąø±ą¹‰ąø‡ą¹€ąøžąø·ą¹ˆąø­ą¹ƒąøŠą¹‰ąø‡ąø²ąø™" + }, + "sign": { + "tags": "ąø­ąø™ąøøąøąø²ąø•, อักษรย่อ, ąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™ąø—ąøµą¹ˆąø§ąø²ąø”, คายเซ็นข้อควาด, ąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™ąø£ąø¹ąø›ąø ąø²ąøž", + "title": "ą¹€ąø‹ą¹‡ąø™ąøŠąø·ą¹ˆąø­", + "header": "ą¹€ąø‹ą¹‡ąø™ąøŠąø·ą¹ˆąø­ PDF", + "upload": "ąø­ąø±ąø›ą¹‚ąø«ąø„ąø”ąø£ąø¹ąø›ąø ąø²ąøž", + "draw": "วาดคายเซ็น", + "text": "ป้อนข้อควาด", + "clear": "ค้าง", + "add": "ą¹€ąøžąø“ą¹ˆąø”", + "saved": "ąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™ąø—ąøµą¹ˆąøšąø±ąø™ąø—ąø¶ąøą¹„ąø§ą¹‰", + "save": "ąøšąø±ąø™ąø—ąø¶ąøąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™", + "personalSigs": "ąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™ąøŖą¹ˆąø§ąø™ąø•ąø±ąø§", + "sharedSigs": "ąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™ąø£ą¹ˆąø§ąø”", + "noSavedSigs": "ą¹„ąø”ą¹ˆąøžąøšąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™ąø—ąøµą¹ˆąøšąø±ąø™ąø—ąø¶ąøą¹„ąø§ą¹‰", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "ąøŖąø–ąø“ąø•, ąø›ąø“ąø”ąøąø²ąø£ą¹ƒąøŠą¹‰ąø‡ąø²ąø™, ą¹„ąø”ą¹ˆą¹‚ąø•ą¹‰ąø•ąø­ąøš, ąø„ąø”ąøˆąø³ąø™ąø§ąø™", + "title": "ą¹ąøšąø™", + "header": "ą¹ąøšąø™ PDF", + "flattenOnlyForms": "ą¹ąøšąø™ą¹€ąø‰ąøžąø²ąø°ąøŸąø­ąø£ą¹Œąø”", + "submit": "ą¹ąøšąø™" + }, + "repair": { + "tags": "ąø‹ą¹ˆąø­ąø”ą¹ąø‹ąø”, กู้คืน, กู้", + "title": "ąø‹ą¹ˆąø­ąø”ą¹ąø‹ąø”", + "header": "ąø‹ą¹ˆąø­ąø”ą¹ąø‹ąø” PDF", + "submit": "ąø‹ą¹ˆąø­ąø”ą¹ąø‹ąø”" + }, + "removeBlanks": { + "tags": "ทำควาดสะอาด, ąø„ąø”ąøˆąø³ąø™ąø§ąø™, ą¹„ąø”ą¹ˆąø”ąøµą¹€ąø™ąø·ą¹‰ąø­ąø«ąø², ąøˆąø±ąø”ąø£ąø°ą¹€ąøšąøµąø¢ąøš", + "title": "ąø„ąøšąø«ąø™ą¹‰ąø²ąø§ą¹ˆąø²ąø‡", + "header": "ąø„ąøšąø«ąø™ą¹‰ąø²ąø§ą¹ˆąø²ąø‡", + "threshold": "ą¹€ąøąø“ąø‘ą¹Œąø„ąø§ąø²ąø”ąø‚ąø²ąø§ąø‚ąø­ąø‡ąøžąø“ąøą¹€ąø‹ąø„:", + "thresholdDesc": "ą¹€ąøąø“ąø‘ą¹Œą¹ƒąø™ąøąø²ąø£ąøąø³ąø«ąø™ąø”ąø§ą¹ˆąø²ąøžąø“ąøą¹€ąø‹ąø„ąø‚ąø²ąø§ą¹€ąøžąøµąø¢ąø‡ąøžąø­ąøˆąø°ąø–ąø¹ąøąøˆąø±ąø”ą¹€ąø›ą¹‡ąø™ 'ขาว' ą¹€ąø—ą¹ˆąø²ą¹ƒąø” 0 = ดำ, 255 = ąø‚ąø²ąø§ąøšąø£ąø“ąøŖąøøąø—ąø˜ąø“ą¹Œ", + "whitePercent": "ą¹€ąø›ąø­ąø£ą¹Œą¹€ąø‹ą¹‡ąø™ąø•ą¹Œąø„ąø§ąø²ąø”ąø‚ąø²ąø§ (%):", + "whitePercentDesc": "ą¹€ąø›ąø­ąø£ą¹Œą¹€ąø‹ą¹‡ąø™ąø•ą¹Œąø‚ąø­ąø‡ąø«ąø™ą¹‰ąø²ąø—ąøµą¹ˆąø•ą¹‰ąø­ąø‡ą¹€ąø›ą¹‡ąø™ąøžąø“ąøą¹€ąø‹ąø„ 'ขาว' ą¹€ąøžąø·ą¹ˆąø­ąøˆąø°ąø–ąø¹ąøąø„ąøš", + "submit": "ąø„ąøšąø«ąø™ą¹‰ąø²ąø§ą¹ˆąø²ąø‡" + }, + "removeAnnotations": { + "tags": "ควาดคณดเห็น, เน้นข้อควาด, โน้ต, ąø”ąø²ąø£ą¹Œąø„ąø­ąø±ąøž, คบ", + "title": "ąø„ąøšąø„ąø³ąø­ąø˜ąø“ąøšąø²ąø¢ąø›ąø£ąø°ąøąø­ąøš", + "header": "ąø„ąøšąø„ąø³ąø­ąø˜ąø“ąøšąø²ąø¢ąø›ąø£ąø°ąøąø­ąøš", + "submit": "คบ" + }, + "compare": { + "tags": "แยกแยะ, ą¹€ąø›ąø£ąøµąø¢ąøšą¹€ąø—ąøµąø¢ąøš, ąøąø²ąø£ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ą¹ąø›ąø„ąø‡, ąøąø²ąø£ąø§ąø“ą¹€ąø„ąø£ąø²ąø°ąø«ą¹Œ", + "title": "ą¹€ąø›ąø£ąøµąø¢ąøšą¹€ąø—ąøµąø¢ąøš", + "header": "ą¹€ąø›ąø£ąøµąø¢ąøšą¹€ąø—ąøµąø¢ąøš PDF", + "highlightColor": { + "1": "สีเน้น 1:", + "2": "สีเน้น 2:" + }, + "document": { + "1": "เอกสาร 1", + "2": "เอกสาร 2" + }, + "submit": "ą¹€ąø›ąø£ąøµąø¢ąøšą¹€ąø—ąøµąø¢ąøš", + "complex": { + "message": "ąø«ąø™ąø¶ą¹ˆąø‡ąø«ąø£ąø·ąø­ąø—ąø±ą¹‰ąø‡ąøŖąø­ąø‡ą¹€ąø­ąøąøŖąø²ąø£ąø—ąøµą¹ˆą¹ƒąø«ą¹‰ąø”ąø²ąø¢ąø­ąø”ą¹€ąø›ą¹‡ąø™ą¹„ąøŸąø„ą¹Œą¹ƒąø«ąøą¹ˆ ąø„ąø§ąø²ąø”ąø–ąø¹ąøąø•ą¹‰ąø­ąø‡ąø‚ąø­ąø‡ąøąø²ąø£ą¹€ąø›ąø£ąøµąø¢ąøšą¹€ąø—ąøµąø¢ąøšąø­ąø²ąøˆąø„ąø”ąø„ąø‡" + }, + "large": { + "file": { + "message": "ąø«ąø™ąø¶ą¹ˆąø‡ąø«ąø£ąø·ąø­ąø—ąø±ą¹‰ąø‡ąøŖąø­ąø‡ą¹€ąø­ąøąøŖąø²ąø£ąø—ąøµą¹ˆą¹ƒąø«ą¹‰ąø”ąø²ąø”ąøµąø‚ąø™ąø²ąø”ą¹ƒąø«ąøą¹ˆąø”ąø²ąø ą¹„ąø”ą¹ˆąøŖąø²ąø”ąø²ąø£ąø–ąø›ąø£ąø°ąø”ąø§ąø„ąøœąø„ą¹„ąø”ą¹‰" + } + }, + "no": { + "text": { + "message": "ąø«ąø™ąø¶ą¹ˆąø‡ąø«ąø£ąø·ąø­ąø—ąø±ą¹‰ąø‡ąøŖąø­ąø‡ą¹€ąø­ąøąøŖąø²ąø£ PDF ąø—ąøµą¹ˆą¹€ąø„ąø·ąø­ąøą¹„ąø”ą¹ˆąø”ąøµą¹€ąø™ąø·ą¹‰ąø­ąø«ąø²ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø” กรุณาเคือกเอกสาร PDF ąø—ąøµą¹ˆąø”ąøµąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ą¹€ąø›ąø£ąøµąø¢ąøšą¹€ąø—ąøµąø¢ąøš" + } + } + }, + "certSign": { + "tags": "ยืนยัน, PEM, P12, เป็นทางการ, เข้ารหัส", + "title": "ąøąø²ąø£ą¹€ąø‹ą¹‡ąø™ąøŠąø·ą¹ˆąø­ąø”ą¹‰ąø§ąø¢ą¹ƒąøšąø£ąø±ąøšąø£ąø­ąø‡", + "header": "ą¹€ąø‹ą¹‡ąø™ąøŠąø·ą¹ˆąø­ PDF ąø”ą¹‰ąø§ąø¢ą¹ƒąøšąø£ąø±ąøšąø£ąø­ąø‡ąø‚ąø­ąø‡ąø„ąøøąø“ (กำคังดำเนณนการ)", + "selectPDF": "ą¹€ąø„ąø·ąø­ąøą¹„ąøŸąø„ą¹Œ PDF ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ą¹€ąø‹ą¹‡ąø™:", + "jksNote": "หดายเหตุ: ąø«ąø²ąøąø›ąø£ąø°ą¹€ąø ąø—ą¹ƒąøšąø£ąø±ąøšąø£ąø­ąø‡ąø‚ąø­ąø‡ąø„ąøøąø“ą¹„ąø”ą¹ˆąø­ąø¢ąø¹ą¹ˆą¹ƒąø™ąø£ąø²ąø¢ąøąø²ąø£ąø”ą¹‰ąø²ąø™ąø„ą¹ˆąø²ąø‡ ąøąø£ąøøąø“ąø²ą¹ąø›ąø„ąø‡ą¹€ąø›ą¹‡ąø™ą¹„ąøŸąø„ą¹Œ Java Keystore (.jks) ą¹‚ąø”ąø¢ą¹ƒąøŠą¹‰ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø”ąø·ąø­ keytool ąøˆąø²ąøąøšąø£ąø£ąø—ąø±ąø”ąø„ąø³ąøŖąø±ą¹ˆąø‡ ąøˆąø²ąøąø™ąø±ą¹‰ąø™ą¹€ąø„ąø·ąø­ąøąø•ąø±ąø§ą¹€ąø„ąø·ąø­ąøą¹„ąøŸąø„ą¹Œ .jks ąø”ą¹‰ąø²ąø™ąø„ą¹ˆąø²ąø‡", + "selectKey": "ą¹€ąø„ąø·ąø­ąøą¹„ąøŸąø„ą¹Œąø„ąøµąø¢ą¹ŒąøŖą¹ˆąø§ąø™ąø•ąø±ąø§ąø‚ąø­ąø‡ąø„ąøøąø“ (ąø£ąø¹ąø›ą¹ąøšąøš PKCS#8, ąø­ąø²ąøˆą¹€ąø›ą¹‡ąø™ .pem หรือ .der):", + "selectCert": "ą¹€ąø„ąø·ąø­ąøą¹„ąøŸąø„ą¹Œą¹ƒąøšąø£ąø±ąøšąø£ąø­ąø‡ąø‚ąø­ąø‡ąø„ąøøąø“ (ąø£ąø¹ąø›ą¹ąøšąøš X.509, ąø­ąø²ąøˆą¹€ąø›ą¹‡ąø™ .pem หรือ .der):", + "selectP12": "ą¹€ąø„ąø·ąø­ąøą¹„ąøŸąø„ą¹Œ PKCS#12 Keystore ของคุณ (.p12 หรือ .pfx) (ą¹„ąø”ą¹ˆąøšąø±ąø‡ąø„ąø±ąøš หากดี ąø„ąø§ąø£ąø”ąøµąø„ąøµąø¢ą¹ŒąøŖą¹ˆąø§ąø™ąø•ąø±ąø§ą¹ąø„ąø°ą¹ƒąøšąø£ąø±ąøšąø£ąø­ąø‡ąø‚ąø­ąø‡ąø„ąøøąø“):", + "selectJKS": "ą¹€ąø„ąø·ąø­ąøą¹„ąøŸąø„ą¹Œ Java Keystore ของคุณ (.jks หรือ .keystore):", + "certType": "ąø›ąø£ąø°ą¹€ąø ąø—ą¹ƒąøšąø£ąø±ąøšąø£ąø­ąø‡", + "password": "ą¹ƒąøŖą¹ˆąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ Keystore ąø«ąø£ąø·ąø­ąø„ąøµąø¢ą¹ŒąøŖą¹ˆąø§ąø™ąø•ąø±ąø§ąø‚ąø­ąø‡ąø„ąøøąø“ (ถ้าดี):", + "showSig": "แสดงคายเซ็น", + "reason": "ą¹€ąø«ąø•ąøøąøœąø„", + "location": "ąø•ąø³ą¹ąø«ąø™ą¹ˆąø‡", + "name": "ชื่อ", + "showLogo": "แสดงโคโก้", + "submit": "ą¹€ąø‹ą¹‡ąø™ąøŠąø·ą¹ˆąø­ PDF" + }, + "removeCertSign": { + "tags": "ยืนยัน, PEM, P12, เป็นทางการ, ถอดรหัส", + "title": "ąø„ąøšąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™ą¹ƒąøšąø£ąø±ąøšąø£ąø­ąø‡", + "header": "ąø„ąøšąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™ąø”ąø“ąøˆąø“ąø—ąø±ąø„ąøˆąø²ąø PDF", + "selectPDF": "ą¹€ąø„ąø·ąø­ąøą¹„ąøŸąø„ą¹Œ PDF:", + "submit": "ąø„ąøšąø„ąø²ąø¢ą¹€ąø‹ą¹‡ąø™" + }, + "pageLayout": { + "tags": "รวด, ąø›ąø£ąø°ąøąø­ąøš, ดุดดองเดียว, ąøˆąø±ąø”ąø£ąø°ą¹€ąøšąøµąø¢ąøš", + "title": "ą¹€ąø„ąø¢ą¹Œą¹€ąø­ąø²ąø•ą¹Œąø«ąø„ąø²ąø¢ąø«ąø™ą¹‰ąø²", + "header": "ą¹€ąø„ąø¢ą¹Œą¹€ąø­ąø²ąø•ą¹Œąø«ąø„ąø²ąø¢ąø«ąø™ą¹‰ąø²", + "pagesPerSheet": "ąøˆąø³ąø™ąø§ąø™ąø«ąø™ą¹‰ąø²ąø•ą¹ˆąø­ą¹ąøœą¹ˆąø™:", + "addBorder": "ą¹€ąøžąø“ą¹ˆąø”ąø‚ąø­ąøš", + "submit": "ąøŖą¹ˆąø‡" + }, + "scalePages": { + "tags": "ąø›ąø£ąø±ąøšąø‚ąø™ąø²ąø”, แก้ไข, ดณตณ, ąø›ąø£ąø±ąøš", + "title": "ąø›ąø£ąø±ąøšąøŖą¹€ąøąø„ąø«ąø™ą¹‰ąø²", + "header": "ąø›ąø£ąø±ąøšąøŖą¹€ąøąø„ąø«ąø™ą¹‰ąø²", + "pageSize": "ขนาดหน้าของเอกสาร", + "keepPageSize": "ąø‚ąø™ąø²ąø”ąø•ą¹‰ąø™ąø‰ąøšąø±ąøš", + "scaleFactor": "ąø£ąø°ąø”ąø±ąøšąøąø²ąø£ąø‹ąø¹ąø” (ąø„ąø£ąø­ąøšąø•ąø±ąø”) ของหน้า", + "submit": "ąøŖą¹ˆąø‡" + }, + "add-page-numbers": { + "tags": "หน้า, เคขหน้า, ąøˆąø±ąø”ąø£ąø°ą¹€ąøšąøµąø¢ąøš, ąø”ąø±ąøŠąø™ąøµ" + }, + "auto-rename": { + "tags": "ąø•ąø£ąø§ąøˆąøˆąø±ąøšąø­ąø±ąø•ą¹‚ąø™ąø”ąø±ąø•ąø“, ąø•ąø±ą¹‰ąø‡ąøŠąø·ą¹ˆąø­ą¹ƒąø«ąø”ą¹ˆ, ąøˆąø±ąø”ąø£ąø°ą¹€ąøšąøµąø¢ąøš, ป้าย", + "title": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąøŠąø·ą¹ˆąø­ąø­ąø±ąø•ą¹‚ąø™ąø”ąø±ąø•ąø“", + "header": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąøŠąø·ą¹ˆąø­ PDF อัตโนดัตณ", + "submit": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąøŠąø·ą¹ˆąø­ąø­ąø±ąø•ą¹‚ąø™ąø”ąø±ąø•ąø“" + }, + "adjust-contrast": { + "tags": "ąø›ąø£ąø±ąøšąøŖąøµ, ąøˆąø¹ąø™, แก้ไข, ąø›ąø£ąø±ąøšąø›ąø£ąøøąø‡" + }, + "crop": { + "tags": "ąø„ąø£ąø­ąøšąø•ąø±ąø”, คดขนาด, แก้ไข, รูปทรง", + "title": "ąø„ąø£ąø­ąøšąø•ąø±ąø”", + "header": "ąø„ąø£ąø­ąøšąø•ąø±ąø” PDF", + "submit": "ąøŖą¹ˆąø‡" + }, + "autoSplitPDF": { + "tags": "แยกโดย QR, แยก, ąøŖą¹ˆąø§ąø™ąøŖą¹ąøąø™, ąøˆąø±ąø”ąø£ąø°ą¹€ąøšąøµąø¢ąøš", + "title": "แยกหน้าอัตโนดัตณ", + "header": "แยก PDF อัตโนดัตณ", + "description": "ąøžąø“ąø”ąøžą¹Œ แทรก สแกน อัปโหคด ą¹ąø„ąø°ą¹ƒąø«ą¹‰ą¹€ąø£ąø²ąøˆąø±ąø”ąøąø²ąø£ą¹ąø¢ąøą¹€ąø­ąøąøŖąø²ąø£ąø‚ąø­ąø‡ąø„ąøøąø“ą¹‚ąø”ąø¢ąø­ąø±ąø•ą¹‚ąø™ąø”ąø±ąø•ąø“ ą¹„ąø”ą¹ˆąø•ą¹‰ąø­ąø‡ąø—ąø³ąø‡ąø²ąø™ą¹ąø¢ąøą¹ąø¢ąø°ąø”ą¹‰ąø§ąø¢ąø•ąø™ą¹€ąø­ąø‡", + "selectText": { + "1": "ąøžąø“ąø”ąøžą¹Œą¹ąøœą¹ˆąø™ą¹ąø¢ąøąø”ą¹‰ąø²ąø™ąø„ą¹ˆąø²ąø‡ (ขาวดำก็ได้)", + "2": "ąøŖą¹ąøąø™ą¹€ąø­ąøąøŖąø²ąø£ąø—ąø±ą¹‰ąø‡ąø«ąø”ąø”ąøžąø£ą¹‰ąø­ąø”ą¹ąø—ąø£ąøą¹ąøœą¹ˆąø™ą¹ąø¢ąøąø£ąø°ąø«ąø§ą¹ˆąø²ąø‡ą¹€ąø­ąøąøŖąø²ąø£", + "3": "ąø­ąø±ąø›ą¹‚ąø«ąø„ąø”ą¹„ąøŸąø„ą¹Œ PDF ąø—ąøµą¹ˆąøŖą¹ąøąø™ąø‚ąø™ąø²ąø”ą¹ƒąø«ąøą¹ˆą¹€ąø”ąøµąø¢ąø§ą¹ąø„ąø°ąø›ąø„ą¹ˆąø­ąø¢ą¹ƒąø«ą¹‰ Stirling PDF ąøˆąø±ąø”ąøąø²ąø£ąøŖą¹ˆąø§ąø™ąø—ąøµą¹ˆą¹€ąø«ąø„ąø·ąø­", + "4": "ąø«ąø™ą¹‰ąø²ąøąø±ą¹‰ąø™ąøˆąø°ąø–ąø¹ąøąø•ąø£ąø§ąøˆąøˆąø±ąøšą¹ąø„ąø°ąø„ąøšą¹‚ąø”ąø¢ąø­ąø±ąø•ą¹‚ąø™ąø”ąø±ąø•ąø“ ąø£ąø±ąøšąø›ąø£ąø°ąøąø±ąø™ą¹€ąø­ąøąøŖąø²ąø£ąøŖąøøąø”ąø—ą¹‰ąø²ąø¢ąø—ąøµą¹ˆą¹€ąø£ąøµąø¢ąøšąø£ą¹‰ąø­ąø¢" + }, + "formPrompt": "ąøŖą¹ˆąø‡ PDF ąø—ąøµą¹ˆąø”ąøµą¹ąøœą¹ˆąø™ą¹ąø¢ąø Stirling-PDF:", + "duplexMode": "โหดด Duplex (การสแกนหน้าแคะหคัง)", + "dividerDownload2": "ąø”ąø²ąø§ąø™ą¹Œą¹‚ąø«ąø„ąø” 'Auto Splitter Divider (with instructions).pdf'", + "submit": "ąøŖą¹ˆąø‡" + }, + "sanitizePdf": { + "tags": "ทำควาดสะอาด, ปคอดภัย, ปคอดภัย, ąø„ąøšąø ąø±ąø¢ąø„ąøøąøąø„ąø²ąø”" + }, + "URLToPDF": { + "tags": "ąøˆąø±ąøšą¹€ąø§ą¹‡ąøš, ąøšąø±ąø™ąø—ąø¶ąøąø«ąø™ą¹‰ąø², ą¹€ąø§ą¹‡ąøšą¹€ąø›ą¹‡ąø™ą¹€ąø­ąøąøŖąø²ąø£, ąøˆąø±ąø”ą¹€ąøą¹‡ąøš", + "title": "URL เป็น PDF", + "header": "URL เป็น PDF", + "submit": "แปคง", + "credit": "ą¹ƒąøŠą¹‰ WeasyPrint" + }, + "HTMLToPDF": { + "tags": "ąø”ąø²ąø£ą¹Œąøąø­ąø±ąø›, ą¹€ąø™ąø·ą¹‰ąø­ąø«ąø²ą¹€ąø§ą¹‡ąøš, การแปคง, การแปคง", + "title": "HTML เป็น PDF", + "header": "HTML เป็น PDF", + "help": "ąø¢ąø­ąø”ąø£ąø±ąøšą¹„ąøŸąø„ą¹Œ HTML แคะ ZIP ąø—ąøµą¹ˆąø”ąøµ html/css/ąø£ąø¹ąø›ąø ąø²ąøž ąøÆąø„ąøÆ ąø—ąøµą¹ˆąøˆąø³ą¹€ąø›ą¹‡ąø™", + "submit": "แปคง", + "credit": "ą¹ƒąøŠą¹‰ WeasyPrint", + "zoom": "ąø£ąø°ąø”ąø±ąøšąøąø²ąø£ąø‹ąø¹ąø”ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ą¹ąøŖąø”ąø‡ą¹€ąø§ą¹‡ąøšą¹„ąø‹ąø•ą¹Œ", + "pageWidth": "ควาดกว้างของหน้าเป็นเซนตณเดตร (ą¹€ąø§ą¹‰ąø™ąø§ą¹ˆąø²ąø‡ą¹€ąøžąø·ą¹ˆąø­ą¹ƒąøŠą¹‰ąø„ą¹ˆąø²ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™)", + "pageHeight": "ควาดสูงของหน้าเป็นเซนตณเดตร (ą¹€ąø§ą¹‰ąø™ąø§ą¹ˆąø²ąø‡ą¹€ąøžąø·ą¹ˆąø­ą¹ƒąøŠą¹‰ąø„ą¹ˆąø²ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™)", + "marginTop": "ąø‚ąø­ąøšąøšąø™ąø‚ąø­ąø‡ąø«ąø™ą¹‰ąø²ą¹€ąø›ą¹‡ąø™ąø”ąø“ąø„ąø„ąø“ą¹€ąø”ąø•ąø£ (ą¹€ąø§ą¹‰ąø™ąø§ą¹ˆąø²ąø‡ą¹€ąøžąø·ą¹ˆąø­ą¹ƒąøŠą¹‰ąø„ą¹ˆąø²ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™)", + "marginBottom": "ąø‚ąø­ąøšąø„ą¹ˆąø²ąø‡ąø‚ąø­ąø‡ąø«ąø™ą¹‰ąø²ą¹€ąø›ą¹‡ąø™ąø”ąø“ąø„ąø„ąø“ą¹€ąø”ąø•ąø£ (ą¹€ąø§ą¹‰ąø™ąø§ą¹ˆąø²ąø‡ą¹€ąøžąø·ą¹ˆąø­ą¹ƒąøŠą¹‰ąø„ą¹ˆąø²ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™)", + "marginLeft": "ąø‚ąø­ąøšąø‹ą¹‰ąø²ąø¢ąø‚ąø­ąø‡ąø«ąø™ą¹‰ąø²ą¹€ąø›ą¹‡ąø™ąø”ąø“ąø„ąø„ąø“ą¹€ąø”ąø•ąø£ (ą¹€ąø§ą¹‰ąø™ąø§ą¹ˆąø²ąø‡ą¹€ąøžąø·ą¹ˆąø­ą¹ƒąøŠą¹‰ąø„ą¹ˆąø²ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™)", + "marginRight": "ąø‚ąø­ąøšąø‚ąø§ąø²ąø‚ąø­ąø‡ąø«ąø™ą¹‰ąø²ą¹€ąø›ą¹‡ąø™ąø”ąø“ąø„ąø„ąø“ą¹€ąø”ąø•ąø£ (ą¹€ąø§ą¹‰ąø™ąø§ą¹ˆąø²ąø‡ą¹€ąøžąø·ą¹ˆąø­ą¹ƒąøŠą¹‰ąø„ą¹ˆąø²ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™)", + "printBackground": "ą¹ąøŖąø”ąø‡ąøžąø·ą¹‰ąø™ąø«ąø„ąø±ąø‡ąø‚ąø­ąø‡ą¹€ąø§ą¹‡ąøšą¹„ąø‹ąø•ą¹Œ", + "defaultHeader": "ą¹€ąø›ąø“ąø”ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ąø«ąø±ąø§ą¹€ąø£ąø·ą¹ˆąø­ąø‡ą¹€ąø£ąø“ą¹ˆąø”ąø•ą¹‰ąø™ (ąøŠąø·ą¹ˆąø­ą¹ąø„ąø°ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ąø«ąø™ą¹‰ąø²)", + "cssMediaType": "ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąø›ąø£ąø°ą¹€ąø ąø—ąøŖąø·ą¹ˆąø­ CSS ของหน้า", + "none": "ą¹„ąø”ą¹ˆąø”ąøµ", + "print": "ąøžąø“ąø”ąøžą¹Œ", + "screen": "ąø«ąø™ą¹‰ąø²ąøˆąø­" + }, + "MarkdownToPDF": { + "tags": "ąø”ąø²ąø£ą¹Œąøąø­ąø±ąø›, ą¹€ąø™ąø·ą¹‰ąø­ąø«ąø²ą¹€ąø§ą¹‡ąøš, การแปคง, การแปคง", + "title": "Markdown เป็น PDF", + "header": "Markdown เป็น PDF", + "submit": "แปคง", + "help": "กำคังดำเนณนการ", + "credit": "ą¹ƒąøŠą¹‰ WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "ข้อดูค, ąøŖąø–ąø“ąø•ąø“, ąøŖąø–ąø“ąø•ąø“", + "title": "ąø£ąø±ąøšąø‚ą¹‰ąø­ąø”ąø¹ąø„ą¹€ąøąøµą¹ˆąø¢ąø§ąøąø±ąøš PDF", + "header": "ąø£ąø±ąøšąø‚ą¹‰ąø­ąø”ąø¹ąø„ą¹€ąøąøµą¹ˆąø¢ąø§ąøąø±ąøš PDF", + "submit": "ąø£ąø±ąøšąø‚ą¹‰ąø­ąø”ąø¹ąø„", + "downloadJson": "ąø”ąø²ąø§ąø™ą¹Œą¹‚ąø«ąø„ąø” JSON" + }, + "extractPage": { + "tags": "แยก" + }, + "PdfToSinglePage": { + "tags": "หน้าเดียว" + }, + "showJS": { + "tags": "JS", + "title": "แสดง Javascript", + "header": "แสดง Javascript", + "downloadJS": "ąø”ąø²ąø§ąø™ą¹Œą¹‚ąø«ąø„ąø” Javascript", + "submit": "แสดง" + }, + "autoRedact": { + "tags": "ąø‹ą¹ˆąø­ąø™, ąø‹ą¹ˆąø­ąø™ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”, ąø‹ą¹ˆąø­ąø™ąø”ą¹‰ąø§ąø¢ąøŖąøµąø”ąø³", + "title": "ąø‹ą¹ˆąø­ąø™ąø‚ą¹‰ąø­ąø”ąø¹ąø„ąø­ąø±ąø•ą¹‚ąø™ąø”ąø±ąø•ąø“", + "header": "ąø‹ą¹ˆąø­ąø™ąø‚ą¹‰ąø­ąø”ąø¹ąø„ąø­ąø±ąø•ą¹‚ąø™ąø”ąø±ąø•ąø“", + "colorLabel": "ąøŖąøµ", + "textsToRedactLabel": "ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø—ąøµą¹ˆąøˆąø°ąø‹ą¹ˆąø­ąø™ (ą¹ąø¢ąøąø”ą¹‰ąø§ąø¢ąøšąø£ąø£ąø—ąø±ąø”)", + "textsToRedactPlaceholder": "ą¹€ąøŠą¹ˆąø™ \\nConfidential \\nTop-Secret", + "useRegexLabel": "ą¹ƒąøŠą¹‰ Regex", + "wholeWordSearchLabel": "ค้นหาทั้งคำ", + "customPaddingLabel": "ąøąø²ąø£ą¹€ąø•ąø“ąø”ąø—ąøµą¹ˆąøąø³ąø«ąø™ąø”ą¹€ąø­ąø‡", + "convertPDFToImageLabel": "แปคง PDF ą¹€ąø›ą¹‡ąø™ąø ąø²ąøž PDF (ą¹ƒąøŠą¹‰ą¹€ąøžąø·ą¹ˆąø­ąø„ąøšąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø—ąøµą¹ˆąø­ąø¢ąø¹ą¹ˆąø”ą¹‰ąø²ąø™ąø«ąø„ąø±ąø‡ąøąø„ą¹ˆąø­ąø‡)", + "submitButton": "ąøŖą¹ˆąø‡" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV, การแยกตาราง, แยก, การแปคง" + }, + "autoSizeSplitPDF": { + "tags": "pdf, แยก, เอกสาร, ąøąø²ąø£ąøˆąø±ąø”ąø£ąø°ą¹€ąøšąøµąø¢ąøš" + }, + "overlay-pdfs": { + "tags": "ąø‹ą¹‰ąø­ąø™ąø—ąø±ąøš", + "header": "ąø‹ą¹‰ąø­ąø™ąø—ąø±ąøšą¹„ąøŸąø„ą¹Œ PDF", + "baseFile": { + "label": "ą¹€ąø„ąø·ąø­ąøą¹„ąøŸąø„ą¹Œ PDF ąøžąø·ą¹‰ąø™ąøąø²ąø™" + }, + "overlayFiles": { + "label": "ą¹€ąø„ąø·ąø­ąøą¹„ąøŸąø„ą¹Œ PDF ąø‹ą¹‰ąø­ąø™ąø—ąø±ąøš" + }, + "mode": { + "label": "ą¹€ąø„ąø·ąø­ąøą¹‚ąø«ąø”ąø”ąø‹ą¹‰ąø­ąø™ąø—ąø±ąøš", + "sequential": "ąø‹ą¹‰ąø­ąø™ąø—ąø±ąøšąø•ąø²ąø”ąø„ąø³ąø”ąø±ąøš", + "interleaved": "ąø‹ą¹‰ąø­ąø™ąø—ąø±ąøšą¹ąøšąøšąøŖąø„ąø±ąøš", + "fixedRepeat": "ąø‹ą¹‰ąø­ąø™ąø—ąø±ąøšą¹ąøšąøšąø§ąø™ąø‹ą¹‰ąø³" + }, + "counts": { + "label": "ąøˆąø³ąø™ąø§ąø™ąøąø²ąø£ąø‹ą¹‰ąø­ąø™ąø—ąø±ąøš (ąøŖąø³ąø«ąø£ąø±ąøšą¹‚ąø«ąø”ąø”ąø§ąø™ąø‹ą¹‰ąø³)", + "placeholder": "ąø›ą¹‰ąø­ąø™ąøˆąø³ąø™ąø§ąø™ą¹ąø¢ąøąø”ą¹‰ąø§ąø¢ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø«ąø”ąø²ąø¢ąøˆąøøąø„ąø ąø²ąø„ (ą¹€ąøŠą¹ˆąø™ 2,3,1)" + }, + "position": { + "label": "ą¹€ąø„ąø·ąø­ąøąø•ąø³ą¹ąø«ąø™ą¹ˆąø‡ąø‹ą¹‰ąø­ąø™ąø—ąø±ąøš", + "foreground": "ąøžąø·ą¹‰ąø™ąø«ąø™ą¹‰ąø²", + "background": "ąøžąø·ą¹‰ąø™ąø«ąø„ąø±ąø‡" + }, + "submit": "ąøŖą¹ˆąø‡" + }, + "split-by-sections": { + "tags": "ą¹ąø¢ąøąøŖą¹ˆąø§ąø™, ą¹ąøšą¹ˆąø‡, ąø›ąø£ąø±ąøšą¹ąø•ą¹ˆąø‡", + "title": "แยก PDF ąø•ąø²ąø”ąøŖą¹ˆąø§ąø™", + "header": "แยก PDF ą¹€ąø›ą¹‡ąø™ąøŖą¹ˆąø§ąø™", + "horizontal": { + "label": "ąøąø²ąø£ą¹ąøšą¹ˆąø‡ą¹ąø™ąø§ąø™ąø­ąø™", + "placeholder": "ąø›ą¹‰ąø­ąø™ąøˆąø³ąø™ąø§ąø™ąøąø²ąø£ą¹ąøšą¹ˆąø‡ą¹ąø™ąø§ąø™ąø­ąø™" + }, + "vertical": { + "label": "ąøąø²ąø£ą¹ąøšą¹ˆąø‡ą¹ąø™ąø§ąø•ąø±ą¹‰ąø‡", + "placeholder": "ąø›ą¹‰ąø­ąø™ąøˆąø³ąø™ąø§ąø™ąøąø²ąø£ą¹ąøšą¹ˆąø‡ą¹ąø™ąø§ąø•ąø±ą¹‰ąø‡" + }, + "submit": "แยก PDF", + "merge": "รวดเป็น PDF เดียว" + }, + "AddStampRequest": { + "tags": "ąø•ąø£ąø²ąø›ąø£ąø°ąø—ąø±ąøš, ą¹€ąøžąø“ą¹ˆąø”ąø£ąø¹ąø›ąø ąø²ąøž, ąø£ąø¹ąø›ąø ąø²ąøžąøąø¶ą¹ˆąø‡ąøąø„ąø²ąø‡, คายน้ำ, PDF, ąøąø±ąø‡, ąø›ąø£ąø±ąøšą¹ąø•ą¹ˆąø‡", + "header": "ąø•ąø£ąø²ąø›ąø£ąø°ąø—ąø±ąøš PDF", + "title": "ąø•ąø£ąø²ąø›ąø£ąø°ąø—ąø±ąøš PDF", + "stampType": "ąø›ąø£ąø°ą¹€ąø ąø—ąø•ąø£ąø²ąø›ąø£ąø°ąø—ąø±ąøš", + "stampText": "ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø•ąø£ąø²ąø›ąø£ąø°ąø—ąø±ąøš", + "stampImage": "ąø£ąø¹ąø›ąø ąø²ąøžąø•ąø£ąø²ąø›ąø£ąø°ąø—ąø±ąøš", + "alphabet": "ตัวอักษร", + "fontSize": "ąø‚ąø™ąø²ąø”ąøŸąø­ąø™ąø•ą¹Œ/ąø£ąø¹ąø›ąø ąø²ąøž", + "rotation": "การหดุน", + "opacity": "ąø„ąø§ąø²ąø”ąø—ąø¶ąøš", + "position": "ąø•ąø³ą¹ąø«ąø™ą¹ˆąø‡", + "overrideX": "ą¹ąø—ąø™ąø—ąøµą¹ˆąøžąø“ąøąø±ąø” X", + "overrideY": "ą¹ąø—ąø™ąø—ąøµą¹ˆąøžąø“ąøąø±ąø” Y", + "customMargin": "ąø‚ąø­ąøšąø—ąøµą¹ˆąøąø³ąø«ąø™ąø”ą¹€ąø­ąø‡", + "customColor": "ąøŖąøµąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”ąø—ąøµą¹ˆąøąø³ąø«ąø™ąø”ą¹€ąø­ąø‡", + "submit": "ąøŖą¹ˆąø‡" + }, + "removeImagePdf": { + "tags": "Remove Image,Page operations,Back end,server side" + }, + "splitPdfByChapters": { + "tags": "split,chapters,bookmarks,organize" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Replace-Invert-Color", + "header": "Replace-Invert Color PDF", + "selectText": { + "1": "Replace or Invert color Options", + "2": "Default(Default high contrast colors)", + "3": "Custom(Customized colors)", + "4": "Full-Invert(Invert all colors)", + "5": "High contrast color options", + "6": "white text on black background", + "7": "Black text on white background", + "8": "Yellow text on black background", + "9": "Green text on black background", + "10": "Choose text Color", + "11": "Choose background Color" + }, + "submit": "Replace" + }, + "replaceColorPdf": { + "tags": "Replace Color,Page operations,Back end,server side" + }, + "login": { + "title": "ąø„ąø‡ąøŠąø·ą¹ˆąø­ą¹€ąø‚ą¹‰ąø²ą¹ƒąøŠą¹‰", + "header": "ąø„ąø‡ąøŠąø·ą¹ˆąø­ą¹€ąø‚ą¹‰ąø²ą¹ƒąøŠą¹‰", + "signin": "ąø„ąø‡ąøŠąø·ą¹ˆąø­ą¹€ąø‚ą¹‰ąø²ą¹ƒąøŠą¹‰", + "rememberme": "ąøˆąø³ąø‰ąø±ąø™ą¹„ąø§ą¹‰", + "invalid": "ąøŠąø·ą¹ˆąø­ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø«ąø£ąø·ąø­ąø£ąø«ąø±ąøŖąøœą¹ˆąø²ąø™ą¹„ąø”ą¹ˆąø–ąø¹ąøąø•ą¹‰ąø­ąø‡", + "locked": "ąøšąø±ąøąøŠąøµąø‚ąø­ąø‡ąø„ąøøąø“ąø–ąø¹ąøąø„ą¹‡ąø­ąø„", + "signinTitle": "ąøąø£ąøøąø“ąø²ąø„ąø‡ąøŠąø·ą¹ˆąø­ą¹€ąø‚ą¹‰ąø²ą¹ƒąøŠą¹‰", + "ssoSignIn": "ą¹€ąø‚ą¹‰ąø²ąøŖąø¹ą¹ˆąø£ąø°ąøšąøšąø”ą¹‰ąø§ąø¢ Single Sign-on", + "oAuth2AutoCreateDisabled": "ąøąø²ąø£ąøŖąø£ą¹‰ąø²ąø‡ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ OAuth2 ąø­ąø±ąø•ą¹‚ąø™ąø”ąø±ąø•ąø“ąø–ąø¹ąøąø›ąø“ąø”ą¹ƒąøŠą¹‰ąø‡ąø²ąø™", + "oAuth2AdminBlockedUser": "Registration or logging in of non-registered users is currently blocked. Please contact the administrator.", + "oauth2RequestNotFound": "ą¹„ąø”ą¹ˆąøžąøšąø„ąø³ąø‚ąø­ąøąø²ąø£ąø­ąø™ąøøąøąø²ąø•", + "oauth2InvalidUserInfoResponse": "ąøąø²ąø£ąø•ąø­ąøšąøąø„ąø±ąøšąø‚ą¹‰ąø­ąø”ąø¹ąø„ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ą¹„ąø”ą¹ˆąø–ąø¹ąøąø•ą¹‰ąø­ąø‡", + "oauth2invalidRequest": "ąø„ąø³ąø‚ąø­ą¹„ąø”ą¹ˆąø–ąø¹ąøąø•ą¹‰ąø­ąø‡", + "oauth2AccessDenied": "ąøąø²ąø£ą¹€ąø‚ą¹‰ąø²ąø–ąø¶ąø‡ąø–ąø¹ąøąø›ąøąø“ą¹€ąøŖąø˜", + "oauth2InvalidTokenResponse": "ąøąø²ąø£ąø•ąø­ąøšąøąø„ąø±ąøšą¹‚ąø—ą¹€ąø„ą¹‡ąø™ą¹„ąø”ą¹ˆąø–ąø¹ąøąø•ą¹‰ąø­ąø‡", + "oauth2InvalidIdToken": "โทเค็น Id ą¹„ąø”ą¹ˆąø–ąø¹ąøąø•ą¹‰ąø­ąø‡", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ąø–ąø¹ąøąø£ąø°ąø‡ąø±ąøšąøąø²ąø£ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ ą¹„ąø”ą¹ˆąøŖąø²ąø”ąø²ąø£ąø–ą¹€ąø‚ą¹‰ąø²ąøŖąø¹ą¹ˆąø£ąø°ąøšąøšąø”ą¹‰ąø§ąø¢ąøŠąø·ą¹ˆąø­ąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ąø™ąøµą¹‰ą¹„ąø”ą¹‰ ąøąø£ąøøąø“ąø²ąø•ąø“ąø”ąø•ą¹ˆąø­ąøœąø¹ą¹‰ąø”ąø¹ą¹ąø„ąø£ąø°ąøšąøš", + "alreadyLoggedIn": "ąø„ąøøąø“ą¹„ąø”ą¹‰ą¹€ąø‚ą¹‰ąø²ąøŖąø¹ą¹ˆąø£ąø°ąøšąøšą¹ƒąø™", + "alreadyLoggedIn2": "ąø­ąøøąø›ąøąø£ąø“ą¹Œą¹ąø„ą¹‰ąø§ ąøąø£ąøøąø“ąø²ąø­ąø­ąøąøˆąø²ąøąø£ąø°ąøšąøšąøˆąø²ąøąø­ąøøąø›ąøąø£ąø“ą¹Œąø—ąøµą¹ˆą¹ƒąøŠą¹‰ąø‡ąø²ąø™ąø­ąø¢ąø¹ą¹ˆą¹ąø„ą¹‰ąø§ ąøˆąø²ąøąø™ąø±ą¹‰ąø™ąø„ąø­ąø‡ą¹ƒąø«ąø”ą¹ˆąø­ąøµąøąø„ąø£ąø±ą¹‰ąø‡", + "toManySessions": "ąø„ąøøąø“ąø”ąøµąøąø²ąø£ą¹€ąø‚ą¹‰ąø²ąøŖąø¹ą¹ˆąø£ąø°ąøšąøšąøžąø£ą¹‰ąø­ąø”ąøąø±ąø™ą¹€ąøąø“ąø™ąøąø§ą¹ˆąø²ąøąø³ąø«ąø™ąø”", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF ą¹€ąø›ą¹‡ąø™ąø«ąø™ą¹‰ąø²ąø‚ąø™ąø²ąø”ą¹ƒąø«ąøą¹ˆą¹€ąøžąøµąø¢ąø‡ąø«ąø™ą¹‰ąø²ą¹€ąø”ąøµąø¢ąø§", + "header": "PDF ą¹€ąø›ą¹‡ąø™ąø«ąø™ą¹‰ąø²ąø‚ąø™ąø²ąø”ą¹ƒąø«ąøą¹ˆą¹€ąøžąøµąø¢ąø‡ąø«ąø™ą¹‰ąø²ą¹€ąø”ąøµąø¢ąø§", + "submit": "ą¹ąø›ąø„ąø‡ą¹€ąø›ą¹‡ąø™ąø«ąø™ą¹‰ąø²ąø‚ąø™ąø²ąø”ą¹ƒąø«ąøą¹ˆą¹€ąøžąøµąø¢ąø‡ąø«ąø™ą¹‰ąø²ą¹€ąø”ąøµąø¢ąø§" + }, + "pageExtracter": { + "title": "แยกหน้า", + "header": "แยกหน้า", + "submit": "แยก", + "placeholder": "(ą¹€ąøŠą¹ˆąø™ 1,2,8 หรือ 4,7,12-16 หรือ 2n-1)" + }, + "sanitizePDF": { + "title": "ทำควาดสะอาด PDF", + "header": "ąø—ąø³ąø„ąø§ąø²ąø”ąøŖąø°ąø­ąø²ąø”ą¹„ąøŸąø„ą¹Œ PDF", + "selectText": { + "1": "ąø„ąøšąøąø²ąø£ąøąø£ąø°ąø—ąø³ JavaScript", + "2": "ąø„ąøšą¹„ąøŸąø„ą¹Œąøąø±ąø‡ąø•ąø±ąø§", + "3": "Remove XMP metadata", + "4": "ąø„ąøšąø„ąø“ąø‡ąøą¹Œ", + "5": "ąø„ąøšąøŸąø­ąø™ąø•ą¹Œ", + "6": "Remove Document Info Metadata" + }, + "submit": "ทำควาดสะอาด PDF" + }, + "adjustContrast": { + "title": "ąø›ąø£ąø±ąøšąø„ąø­ąø™ąø—ąø£ąø²ąøŖąø•ą¹Œ", + "header": "ąø›ąø£ąø±ąøšąø„ąø­ąø™ąø—ąø£ąø²ąøŖąø•ą¹Œ", + "contrast": "ąø„ąø­ąø™ąø—ąø£ąø²ąøŖąø•ą¹Œ:", + "brightness": "ąø„ąø§ąø²ąø”ąøŖąø§ą¹ˆąø²ąø‡:", + "saturation": "ąø„ąø§ąø²ąø”ąø­ąø“ą¹ˆąø”ąø•ąø±ąø§:", + "download": "ąø”ąø²ąø§ąø™ą¹Œą¹‚ąø«ąø„ąø”" + }, + "compress": { + "title": "ąøšąøµąøšąø­ąø±ąø”", + "header": "ąøšąøµąøšąø­ąø±ąø” PDF", + "credit": "ąøšąø£ąø“ąøąø²ąø£ąø™ąøµą¹‰ą¹ƒąøŠą¹‰ qpdf ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ąøšąøµąøšąø­ąø±ąø”/ąøąø²ąø£ą¹€ąøžąø“ą¹ˆąø”ąø›ąø£ąø°ąøŖąø“ąø—ąø˜ąø“ąø ąø²ąøž PDF", + "grayscale": { + "label": "ą¹ƒąøŠą¹‰ąø£ąø°ąø”ąø±ąøšąøŖąøµą¹€ąø—ąø²ąøŖąø³ąø«ąø£ąø±ąøšąøąø²ąø£ąøšąøµąøšąø­ąø±ąø”" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "ąø£ąø°ąø”ąø±ąøšąøąø²ąø£ą¹€ąøžąø“ą¹ˆąø”ąø›ąø£ąø°ąøŖąø“ąø—ąø˜ąø“ąø ąø²ąøž:", + "4": "โหดดอัตโนดัตณ - ąø›ąø£ąø±ąøšąø„ąøøąø“ąø ąø²ąøžąø­ąø±ąø•ą¹‚ąø™ąø”ąø±ąø•ąø“ą¹€ąøžąø·ą¹ˆąø­ą¹ƒąø«ą¹‰ PDF ąø•ąø£ąø‡ąøąø±ąøšąø‚ąø™ąø²ąø”ąø—ąøµą¹ˆąø•ą¹‰ąø­ąø‡ąøąø²ąø£", + "5": "ขนาด PDF ąø—ąøµą¹ˆąø„ąø²ąø”ąø«ąø§ąø±ąø‡ (ą¹€ąøŠą¹ˆąø™ 25MB, 10.8MB, 25KB)" + }, + "submit": "ąøšąøµąøšąø­ąø±ąø”" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "ąø•ąø±ąø§ąø„ąøšąø«ąø™ą¹‰ąø²", + "header": "ąø•ąø±ąø§ąø„ąøšąø«ąø™ą¹‰ąø² PDF", + "pagesToDelete": "ąø«ąø™ą¹‰ąø²ąø—ąøµą¹ˆąøˆąø°ąø„ąøš (ąø›ą¹‰ąø­ąø™ąø«ąø”ąø²ąø¢ą¹€ąø„ąø‚ąø«ąø™ą¹‰ąø²ą¹ąø¢ąøąø”ą¹‰ąø§ąø¢ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø«ąø”ąø²ąø¢ąøˆąøøąø„ąø ąø²ąø„):", + "submit": "ąø„ąøšąø«ąø™ą¹‰ąø²", + "placeholder": "(ą¹€ąøŠą¹ˆąø™ 1,2,6 หรือ 1-10,15-30)" + }, + "imageToPDF": { + "title": "ąø£ąø¹ąø›ąø ąø²ąøžą¹€ąø›ą¹‡ąø™ PDF", + "header": "ąø£ąø¹ąø›ąø ąø²ąøžą¹€ąø›ą¹‡ąø™ PDF", + "submit": "แปคง", + "selectLabel": "ąø•ąø±ąø§ą¹€ąø„ąø·ąø­ąøąøąø²ąø£ą¹ƒąøŖą¹ˆąø ąø²ąøž", + "fillPage": "เตณดหน้า", + "fitDocumentToImage": "ąø›ąø£ąø±ąøšąø«ąø™ą¹‰ąø²ą¹ƒąø«ą¹‰ąøžąø­ąø”ąøµąøąø±ąøšąø ąø²ąøž", + "maintainAspectRatio": "ąø£ąø±ąøąø©ąø²ąø­ąø±ąø•ąø£ąø²ąøŖą¹ˆąø§ąø™ąøąø§ą¹‰ąø²ąø‡ąø¢ąø²ąø§", + "selectText": { + "2": "หดุน PDF อัตโนดัตณ", + "3": "ąø•ąø£ąø£ąøąø°ąø«ąø„ąø²ąø¢ą¹„ąøŸąø„ą¹Œ (ą¹€ąø›ąø“ąø”ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ą¹€ąø‰ąøžąø²ąø°ą¹€ąø”ąø·ą¹ˆąø­ąø—ąø³ąø‡ąø²ąø™ąøąø±ąøšąø«ąø„ąø²ąø¢ąø ąø²ąøž)", + "4": "รวดเป็น PDF เดียว", + "5": "แปคงเป็น PDF แยก" + } + }, + "PDFToCSV": { + "title": "PDF เป็น CSV", + "header": "PDF เป็น CSV", + "prompt": "ą¹€ąø„ąø·ąø­ąøąø«ąø™ą¹‰ąø²ąø—ąøµą¹ˆąø•ą¹‰ąø­ąø‡ąøąø²ąø£ą¹ąø¢ąøąø•ąø²ąø£ąø²ąø‡", + "submit": "แยก" + }, + "split-by-size-or-count": { + "title": "แยก PDF ąø•ąø²ąø”ąø‚ąø™ąø²ąø”ąø«ąø£ąø·ąø­ąøˆąø³ąø™ąø§ąø™", + "header": "แยก PDF ąø•ąø²ąø”ąø‚ąø™ąø²ąø”ąø«ąø£ąø·ąø­ąøˆąø³ąø™ąø§ąø™", + "type": { + "label": "เคือกประเภทการแยก", + "size": "ตาดขนาด", + "pageCount": "ąø•ąø²ąø”ąøˆąø³ąø™ąø§ąø™ąø«ąø™ą¹‰ąø²", + "docCount": "ąø•ąø²ąø”ąøˆąø³ąø™ąø§ąø™ą¹€ąø­ąøąøŖąø²ąø£" + }, + "value": { + "label": "ąø›ą¹‰ąø­ąø™ąø„ą¹ˆąø²", + "placeholder": "ป้อนขนาด (ą¹€ąøŠą¹ˆąø™ 2MB หรือ 3KB) ąø«ąø£ąø·ąø­ąøˆąø³ąø™ąø§ąø™ (ą¹€ąøŠą¹ˆąø™ 5)" + }, + "submit": "ąøŖą¹ˆąø‡" + }, + "printFile": { + "title": "ąøžąø“ąø”ąøžą¹Œą¹„ąøŸąø„ą¹Œ", + "header": "ąøžąø“ąø”ąøžą¹Œą¹„ąøŸąø„ą¹Œą¹„ąø›ąø¢ąø±ąø‡ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąøžąø“ąø”ąøžą¹Œ", + "selectText": { + "1": "ą¹€ąø„ąø·ąø­ąøą¹„ąøŸąø„ą¹Œąø—ąøµą¹ˆąøˆąø°ąøžąø“ąø”ąøžą¹Œ", + "2": "ąø›ą¹‰ąø­ąø™ąøŠąø·ą¹ˆąø­ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąøžąø“ąø”ąøžą¹Œ" + }, + "submit": "ąøžąø“ąø”ąøžą¹Œ" + }, + "licenses": { + "nav": "ą¹ƒąøšąø­ąø™ąøøąøąø²ąø•", + "title": "ą¹ƒąøšąø­ąø™ąøøąøąø²ąø•ąøšąøøąø„ąø„ąø„ąø—ąøµą¹ˆąøŖąø²ąø”", + "header": "ą¹ƒąøšąø­ąø™ąøøąøąø²ąø•ąøšąøøąø„ąø„ąø„ąø—ąøµą¹ˆąøŖąø²ąø”", + "module": "โดดูค", + "version": "ą¹€ąø§ąø­ąø£ą¹ŒąøŠąø±ąø™", + "license": "ą¹ƒąøšąø­ąø™ąøøąøąø²ąø•" + }, + "survey": { + "nav": "สำรวจ", + "title": "สำรวจ Stirling-PDF", + "description": "Stirling-PDF ą¹„ąø”ą¹ˆąø”ąøµąøąø²ąø£ąø•ąø“ąø”ąø•ąø²ąø” ąø”ąø±ąø‡ąø™ąø±ą¹‰ąø™ą¹€ąø£ąø²ąø•ą¹‰ąø­ąø‡ąøąø²ąø£ąøŸąø±ąø‡ąø„ąø§ąø²ąø”ąø„ąø“ąø”ą¹€ąø«ą¹‡ąø™ąøˆąø²ąøąøœąø¹ą¹‰ą¹ƒąøŠą¹‰ą¹€ąøžąø·ą¹ˆąø­ąø›ąø£ąø±ąøšąø›ąø£ąøøąø‡ Stirling-PDF!", + "changes": "Stirling-PDF ą¹„ąø”ą¹‰ąø”ąøµąøąø²ąø£ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ą¹ąø›ąø„ąø‡ąø•ąø±ą¹‰ąø‡ą¹ąø•ą¹ˆąøąø²ąø£ąøŖąø³ąø£ąø§ąøˆąø„ąø£ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ąøŖąøøąø”! ąøąø£ąøøąø“ąø²ąø•ąø£ąø§ąøˆąøŖąø­ąøšąøšąø„ą¹‡ąø­ąøąø‚ąø­ąø‡ą¹€ąø£ąø²ąø—ąøµą¹ˆąø™ąøµą¹‰ą¹€ąøžąø·ą¹ˆąø­ąø£ąø±ąøšąø‚ą¹‰ąø­ąø”ąø¹ąø„ą¹€ąøžąø“ą¹ˆąø”ą¹€ąø•ąø“ąø”:", + "changes2": "ąø”ą¹‰ąø§ąø¢ąøąø²ąø£ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ą¹ąø›ąø„ąø‡ą¹€ąø«ąø„ą¹ˆąø²ąø™ąøµą¹‰ą¹€ąø£ąø²ą¹„ąø”ą¹‰ąø£ąø±ąøšąøąø²ąø£ąøŖąø™ąø±ąøšąøŖąø™ąøøąø™ąø—ąø²ąø‡ąø˜ąøøąø£ąøąø“ąøˆą¹ąø„ąø°ąøąø²ąø£ą¹€ąø‡ąø“ąø™ąøˆąø²ąøąøœąø¹ą¹‰ąø›ąø£ąø°ąøąø­ąøšąøąø²ąø£", + "please": "ąøąø£ąøøąø“ąø²ąøžąø“ąøˆąø²ąø£ąø“ąø²ąøąø²ąø£ąøŖąø³ąø£ąø§ąøˆąø‚ąø­ąø‡ą¹€ąø£ąø²!", + "disabled": "(ąø›ą¹Šąø­ąø›ąø­ąø±ąø›ąøąø²ąø£ąøŖąø³ąø£ąø§ąøˆąøˆąø°ąø–ąø¹ąøąø›ąø“ąø”ą¹ƒąøŠą¹‰ąø‡ąø²ąø™ą¹ƒąø™ąøąø²ąø£ąø­ąø±ąø›ą¹€ąø”ąø•ąø•ą¹ˆąø­ą¹„ąø›ąø™ąøµą¹‰ ą¹ąø•ą¹ˆąøŖąø²ąø”ąø²ąø£ąø–ą¹ƒąøŠą¹‰ą¹„ąø”ą¹‰ąø—ąøµą¹ˆąøŖą¹ˆąø§ąø™ąø—ą¹‰ąø²ąø¢ąø‚ąø­ąø‡ąø«ąø™ą¹‰ąø²)", + "button": "ą¹€ąø£ąø“ą¹ˆąø”ąøŖąø³ąø£ąø§ąøˆ", + "dontShowAgain": "ą¹„ąø”ą¹ˆąø•ą¹‰ąø­ąø‡ą¹ąøŖąø”ąø‡ąø­ąøµąø", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "ąø„ąøšąø ąø²ąøž", + "header": "ąø„ąøšąø ąø²ąøž", + "removeImage": "ąø„ąøšąø ąø²ąøž", + "submit": "ąø¢ąø·ąø™ąø¢ąø±ąø™ąøąø²ąø£ąø„ąøšąø ąø²ąøž" + }, + "splitByChapters": { + "title": "ą¹ąøšą¹ˆąø‡ą¹„ąøŸąø„ą¹Œ PDF ąø•ąø²ąø”ąø«ąø”ąø§ąø”ąø«ąø”ąø¹ą¹ˆ", + "header": "ą¹ąøšą¹ˆąø‡ą¹„ąøŸąø„ą¹Œ PDF ąø•ąø²ąø”ąø«ąø”ąø§ąø”ąø«ąø”ąø¹ą¹ˆ", + "bookmarkLevel": "ąø£ąø°ąø”ąø±ąøšąøšąøøąø„ąø„ąø„ąø—ąøµą¹ˆą¹„ąø”ą¹‰ąø£ąø±ąøšą¹€ąø„ąø·ąø­ąø", + "includeMetadata": "รวดข้อดูคเสรณด", + "allowDuplicates": "ąø­ąø™ąøøąøąø²ąø•ą¹ƒąø«ą¹‰ąø”ąøµąøąø²ąø£ąø‹ą¹‰ąø³", + "desc": { + "1": "ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø”ąø·ąø­ąø™ąøµą¹‰ąøˆąø°ą¹ąøšą¹ˆąø‡ą¹„ąøŸąø„ą¹Œ PDF ąø­ąø­ąøą¹€ąø›ą¹‡ąø™ąø«ąø„ąø²ąø¢ą¹„ąøŸąø„ą¹Œ PDF ąø•ąø²ąø”ą¹‚ąø„ąø£ąø‡ąøŖąø£ą¹‰ąø²ąø‡ąø«ąø”ąø§ąø”ąø«ąø”ąø¹ą¹ˆąø‚ąø­ąø‡ą¹„ąøŸąø„ą¹Œąø™ąø±ą¹‰ąø™ą¹†", + "2": "ąø£ąø°ąø”ąø±ąøšąøšąøøąø„ąø„ąø„ąø—ąøµą¹ˆą¹„ąø”ą¹‰ąø£ąø±ąøšą¹€ąø„ąø·ąø­ąø: ą¹€ąø„ąø·ąø­ąøąø£ąø°ąø”ąø±ąøšąøšąøøąø„ąø„ąø„ąø—ąøµą¹ˆą¹„ąø”ą¹‰ąø£ąø±ąøšą¹€ąø„ąø·ąø­ąøąø—ąøµą¹ˆąøˆąø°ą¹ƒąøŠą¹‰ą¹ƒąø™ąøąø²ąø£ą¹ąøšą¹ˆąø‡ (0 ąøŖąø³ąø«ąø£ąø±ąøšąø£ąø°ąø”ąø±ąøšąø•ą¹‰ąø™, 1 ąøŖąø³ąø«ąø£ąø±ąøšąø£ąø°ąø”ąø±ąøšąø—ąøµą¹ˆąøŖąø­ąø‡ เป็นต้น)", + "3": "รวดข้อดูคเสรณด: หากถูกเคือก ąø‚ą¹‰ąø­ąø”ąø¹ąø„ą¹€ąøŖąø£ąø“ąø”ąø‚ąø­ąø‡ą¹„ąøŸąø„ą¹Œ PDF ąø—ąøµą¹ˆą¹€ąø”ąø“ąø”ąøˆąø°ąø–ąø¹ąøąø£ąø§ąø”ąø­ąø¢ąø¹ą¹ˆą¹ƒąø™ą¹ąø•ą¹ˆąø„ąø°ą¹„ąøŸąø„ą¹Œąø—ąøµą¹ˆą¹ąøšą¹ˆąø‡ąø­ąø­ąø", + "4": "ąø­ąø™ąøøąøąø²ąø•ą¹ƒąø«ą¹‰ąø”ąøµąøąø²ąø£ąø‹ą¹‰ąø³: หากถูกเคือก ąøˆąø°ąø—ąø³ą¹ƒąø«ą¹‰ąøŖąø²ąø”ąø²ąø£ąø–ąøŖąø£ą¹‰ąø²ąø‡ą¹„ąøŸąø„ą¹Œ PDF ą¹ąø¢ąøąø­ąø­ąøąø”ąø²ąøˆąø²ąøąø«ąø™ą¹‰ąø²ą¹€ąø”ąøµąø¢ąø§ąøąø±ąø™ą¹„ąø”ą¹‰ąø«ąø„ąø²ąø¢ąø£ąø²ąø¢ąøąø²ąø£" + }, + "submit": "ą¹ąøšą¹ˆąø‡ą¹„ąøŸąø„ą¹Œ PDF" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Releases", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Current Release" + }, + "note": "Release notes are only available in English" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/tr-TR/translation.json b/frontend/public/locales/tr-TR/translation.json new file mode 100644 index 000000000..1700a35f7 --- /dev/null +++ b/frontend/public/locales/tr-TR/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Font Büyüklüğü", + "fontName": "Font İsmi", + "title": "Sayfa Numaraları Ekle", + "header": "Sayfa Numaraları Ekle", + "selectText": { + "1": "PDF dosyasını seƧin:", + "2": "Kenar Boyutu", + "3": "Pozisyon", + "4": "BaşlangıƧ Numarası", + "5": "Numaralandırılacak Sayfalar", + "6": "Ɩzel Metin" + }, + "customTextDesc": "Ɩzel Metin", + "numberPagesDesc": "Hangi sayfaların numaralandırılacağını, varsayılan 'all', ayrıca 1-5 veya 2,5,9 vb. kabul eder", + "customNumberDesc": "Varsayılan {n}, ayrıca 'Sayfa {n} / {total}', 'Metin-{n}', '{filename}-{n} kabul eder", + "submit": "Sayfa Numaraları Ekle" + }, + "pdfPrompt": "PDF(leri) seƧin", + "multiPdfPrompt": "PDFleri seƧin (2+)", + "multiPdfDropPrompt": "Tüm gerekli PDF'leri seƧin (ya da sürükleyip bırakın)", + "imgPrompt": "Resim(leri) seƧin", + "genericSubmit": "Gƶnder", + "uploadLimit": "Maksimum dosya boyutu:", + "uploadLimitExceededSingular": "Ƨok büyük. İzin verilen maksimum boyut:", + "uploadLimitExceededPlural": "Ƨok büyük. İzin verilen maksimum boyut:", + "processTimeWarning": "Uyarı: Bu işlem, dosya boyutuna bağlı olarak bir dakikaya kadar sürebilir.", + "pageOrderPrompt": "Ɩzel Sayfa Sırası (Virgülle ayrılmış sayfa numaraları veya 2n+1 gibi bir fonksiyon girin) :", + "pageSelectionPrompt": "Ɩzel Sayfa SeƧimi (1,5,6 sayfa numaralarının virgülle ayrılmış bir listesini veya 2n+1 gibi bir fonksiyon girin) :", + "goToPage": "Sayfaya Git", + "true": "Doğru", + "false": "Yanlış", + "unknown": "Bilinmeyen", + "save": "Kaydet", + "saveToBrowser": "Tarayıcıya Kaydet", + "close": "Kapat", + "filesSelected": "dosya seƧildi", + "noFavourites": "Favori eklenmedi", + "downloadComplete": "İndirme Tamamlandı", + "bored": "Sıkıldınız mı?", + "alphabet": "Alfabe", + "downloadPdf": "PDF İndir", + "text": "Metin", + "font": "Yazı tipi", + "selectFillter": "-- SeƧiniz --", + "pageNum": "Sayfa Numarası", + "sizes": { + "small": "Küçük", + "medium": "Orta", + "large": "Büyük", + "x-large": "Ƈok Büyük" + }, + "error": { + "pdfPassword": "PDF belgesi şifreli ve şifre ya sağlanmadı ya da yanlış.", + "_value": "Hata", + "sorry": "Sorun iƧin ƶzür dileriz!", + "needHelp": "Yardıma mı ihtiyacınız var / Bir sorun mu buldunuz?", + "contactTip": "Hala sorun yaşıyorsanız, yardım iƧin bize ulaşmaktan Ƨekinmeyin. GitHub sayfamızdan bir bilet gƶnderebilir veya Discord üzerinden bizimle iletişime geƧebilirsiniz:", + "404": { + "head": "404 - Sayfa Bulunamadı | Tüh, kodda takıldık!", + "1": "Aradığınız sayfayı bulamıyoruz.", + "2": "Bir şeyler ters gitti" + }, + "github": "GitHub üzerinden bir hata bildirin", + "showStack": "Yığın İzlemesini Gƶster", + "copyStack": "Yığın İzini Kopyala", + "githubSubmit": "GitHub - Hata gƶnderin", + "discordSubmit": "Discord - Destek gƶnderisi gƶnderin" + }, + "delete": "Sil", + "username": "Kullanıcı Adı", + "password": "Parola", + "welcome": "Hoş geldiniz", + "property": "Ɩzellik", + "black": "Siyah", + "white": "Beyaz", + "red": "Kırmızı", + "green": "Yeşil", + "blue": "Mavi", + "custom": "Ɩzel", + "WorkInProgess": "Ƈalışmalar devam ediyor, Ƈalışmayabilir veya hatalı olabilir, Lütfen herhangi bir sorunu bildirin!", + "poweredBy": "Tarafından desteklenmektedir", + "yes": "Evet", + "no": "Hayır", + "changedCredsMessage": "Bilgiler değiştirildi!", + "notAuthenticatedMessage": "Kullanıcı doğrulanmadı.", + "userNotFoundMessage": "Kullanıcı bulunamadı.", + "incorrectPasswordMessage": "Mevcut şifre yanlış.", + "usernameExistsMessage": "Yeni Kullanıcı Adı zaten var.", + "invalidUsernameMessage": "GeƧersiz kullanıcı adı, kullanıcı adı yalnızca harf, rakam ve aşağıdaki ƶzel karakterleri @._+- iƧerebilir veya geƧerli bir e-posta adresi olmalıdır.", + "invalidPasswordMessage": "Şifre boş olmamalı ve başında veya sonunda boşluk bulunmamalıdır.", + "confirmPasswordErrorMessage": "Yeni Şifre ve Yeni Şifreyi Onayla eşleşmelidir.", + "deleteCurrentUserMessage": "Şu anda oturum aƧmış olan kullanıcı silinemiyor.", + "deleteUsernameExistsMessage": "Kullanıcı adı mevcut değil ve silinemez.", + "downgradeCurrentUserMessage": "Mevcut kullanıcının rolü düşürülemiyor", + "disabledCurrentUserMessage": "Mevcut kullanıcı devre dışı bırakılamaz", + "downgradeCurrentUserLongMessage": "Mevcut kullanıcının rolü düşürülemiyor. Bu nedenle, mevcut kullanıcı gƶsterilmeyecektir.", + "userAlreadyExistsOAuthMessage": "Kullanıcı zaten bir OAuth2 kullanıcısı olarak mevcut.", + "userAlreadyExistsWebMessage": "Kullanıcı zaten bir web kullanıcısı olarak mevcut.", + "oops": "Tüh!", + "help": "Yardım", + "goHomepage": "Anasayfa'ya git", + "joinDiscord": "Discord sunucumuza katılın", + "seeDockerHub": "Docker Hub'a bakın", + "visitGithub": "Github Deposunu Ziyaret Edin", + "donate": "Bağış Yapın", + "color": "Renk", + "sponsor": "Bağış", + "info": "Bilgi", + "pro": "Pro", + "page": "Sayfa", + "pages": "Sayfalar", + "loading": "Yükleniyor...", + "addToDoc": "Dƶkümana Ekle", + "reset": "Sıfırla", + "apply": "Uygula", + "noFileSelected": "HiƧbir dosya seƧilmedi. Lütfen bir dosya yükleyin.", + "legal": { + "privacy": "Gizlilik Politikası", + "terms": "Şartlar ve koşullar", + "accessibility": "Erişilebilirlik", + "cookie": "Ƈerez Politikası", + "impressum": "Hakkımızda", + "showCookieBanner": "Ƈerez Tercihleri" + }, + "pipeline": { + "header": "Ƈoklu İşlemler Menü (Beta)", + "uploadButton": "Yükle", + "configureButton": "Yapılandır", + "defaultOption": "Ɩzel", + "submitButton": "Gƶnder", + "help": "Ƈoklu İşlemler Yardım", + "scanHelp": "Klasƶr Tarama Yardımı", + "deletePrompt": "Ƈoklu işlemleri silmek istediğinizden emin misiniz", + "tags": "otomatikleştir,sıralı,betikli,toplu-işlem", + "title": "Ƈoklu İşlemler" + }, + "pipelineOptions": { + "header": "Ƈoklu İşlemler Yapılandırma", + "pipelineNameLabel": "Ƈoklu İşlemler İsim", + "saveSettings": "Ayarları Kaydet", + "pipelineNamePrompt": "Buraya isim girin", + "selectOperation": "İşlem SeƧin", + "addOperationButton": "İşlem ekle", + "pipelineHeader": "Ƈoklu İşlemler:", + "saveButton": "İndir", + "validateButton": "Doğrula" + }, + "enterpriseEdition": { + "button": "Pro Sürümüne Yükselt", + "warning": "Bu ƶzellik yalnızca Pro kullanıcılarına sunulmaktadır.", + "yamlAdvert": "Stirling PDF Pro, YAML yapılandırma dosyalarını ve diğer SSO ƶzelliklerini destekler.", + "ssoAdvert": "Daha fazla kullanıcı yƶnetimi ƶzelliği mi arıyorsunuz? Stirling PDF Pro'ya gƶz atın" + }, + "analytics": { + "title": "Stirling PDF’i daha iyi hale getirmek ister misiniz?", + "paragraph1": "Stirling PDF, ürünü geliştirmemize yardımcı olmak iƧin isteğe bağlı analizleri iƧerir. Kişisel bilgileri veya dosya iƧeriklerini asla takip etmiyoruz.", + "paragraph2": "Stirling PDF’in büyümesine destek olmak ve kullanıcılarımızı daha iyi anlayabilmemiz iƧin analizleri etkinleştirmeyi düşünebilirsiniz.", + "enable": "Analizi Etkinleştir", + "disable": "Analizi Devre Dışı Bırak", + "settings": "Analiz ayarlarını config/settings.yml dosyasından değiştirebilirsiniz" + }, + "navbar": { + "favorite": "Favoriler", + "recent": "New and recently updated", + "darkmode": "Karanlık Mod", + "language": "Diller", + "settings": "Ayarlar", + "allTools": "AraƧlar", + "multiTool": "Ƈoklu AraƧlar", + "search": "Search", + "sections": { + "organize": "Düzenle", + "convertTo": "PDF'ye dƶnüştür", + "convertFrom": "PDF'den dƶnüştür", + "security": "Oturum ve Güvenlik", + "advance": "Gelişmiş", + "edit": "Gƶrüntüle ve Düzenle", + "popular": "Popular" + } + }, + "settings": { + "title": "Ayarlar", + "update": "Güncelleme mevcut", + "updateAvailable": "{0} mevcut kurulu sürümdür. Yeni bir sürüm ({1}) mevcuttur.", + "appVersion": "Uygulama Sürümü:", + "downloadOption": { + "title": "İndirme seƧeneği seƧin (Zip olmayan tek dosya indirmeler iƧin):", + "1": "Aynı pencerede aƧ", + "2": "Yeni pencerede aƧ", + "3": "Dosyayı indir" + }, + "zipThreshold": "İndirilen dosya sayısı şu değeri aştığında zip dosyası oluştur:", + "signOut": "Ƈıkış Yap", + "accountSettings": "Hesap Ayarları", + "bored": { + "help": "Paskalya yumurtası oyunu etkinleştirir" + }, + "cacheInputs": { + "name": "Form girdilerini kaydet", + "help": "Gelecekteki Ƨalıştırmalar iƧin ƶnceden kullanılan girdileri saklamayı etkinleştirin" + } + }, + "changeCreds": { + "title": "Giriş Bilgilerini Değiştir", + "header": "Hesap Detaylarınızı Güncelleyin", + "changePassword": "Varsayılan giriş bilgilerini kullanıyorsunuz. Lütfen yeni bir şifre girin.", + "newUsername": "Yeni Kullanıcı Adı", + "oldPassword": "Mevcut Şifre", + "newPassword": "Yeni Şifre", + "confirmNewPassword": "Yeni Şifreyi Onayla", + "submit": "Değişiklikleri Gƶnder" + }, + "account": { + "title": "Hesap Ayarları", + "accountSettings": "Hesap Ayarları", + "adminSettings": "Yƶnetici Ayarları - Kullanıcıları Gƶrüntüle ve Ekle", + "userControlSettings": "Kullanıcı Kontrol Ayarları", + "changeUsername": "Kullanıcı Adını Değiştir", + "newUsername": "Yeni kullanıcı adı", + "password": "Onay Şifresi", + "oldPassword": "Eski Şifre", + "newPassword": "Yeni Şifre", + "changePassword": "Şifreyi Değiştir", + "confirmNewPassword": "Yeni Şifreyi Onayla", + "signOut": "Ƈıkış Yap", + "yourApiKey": "API Anahtarınız", + "syncTitle": "Hesap Ayarları ile Tarayıcı Ayarlarını Eşitle", + "settingsCompare": "Ayar Karşılaştırması:", + "property": "Ɩzellik", + "webBrowserSettings": "Web Tarayıcı Ayarı", + "syncToBrowser": "Hesaptan Tarayıcıya Eşitle", + "syncToAccount": "Tarayıcıdan Hesaba Eşitle" + }, + "adminUserSettings": { + "title": "Kullanıcı Kontrol Ayarları", + "header": "Yƶnetici Kullanıcı Kontrol Ayarları", + "admin": "Yƶnetici", + "user": "Kullanıcı", + "addUser": "Yeni Kullanıcı Ekle", + "deleteUser": "Kullanıcı Sil", + "confirmDeleteUser": "Kullanıcı silinsin mi?", + "confirmChangeUserStatus": "Kullanıcı devre dışı bırakılmalı/aktifleştirilmeli mi ?", + "usernameInfo": "Kullanıcı adı yalnızca harf, rakam ve aşağıdaki ƶzel karakterleri @._+- iƧerebilir veya geƧerli bir e-posta adresi olmalıdır.", + "roles": "Roller", + "role": "Rol", + "actions": "Eylemler", + "apiUser": "Sınırlı API Kullanıcısı", + "extraApiUser": "Ek Sınırlı API Kullanıcısı", + "webOnlyUser": "Sadece Web Kullanıcısı", + "demoUser": "Demo Kullanıcısı (Ɩzel ayar yok)", + "internalApiUser": "Dahili API Kullanıcısı", + "forceChange": "Kullanıcının girişte kullanıcı adı/şifre değiştirmesini zorla", + "submit": "Kullanıcıyı Kaydet", + "changeUserRole": "Kullanıcı rolünü değiştir", + "authenticated": "Onaylandı", + "editOwnProfil": "Profili düzenle", + "enabledUser": "aktif kullanıcı", + "disabledUser": "devre dışı kullanıcı", + "activeUsers": "Aktif Kullanıcılar:", + "disabledUsers": "Devre Dışı Kullanıcılar:", + "totalUsers": "Toplam Kullanıcılar:", + "lastRequest": "Son İstek", + "usage": "Kullanımı Gƶrüntüle" + }, + "endpointStatistics": { + "title": "Endpoint İstatistikleri", + "header": "Endpoint İstatistikleri", + "top10": "En Ƈok Kullanılan 10", + "top20": "En Ƈok Kullanılan 20", + "all": "Hepsi", + "refresh": "Yenile", + "includeHomepage": "Ana Sayfayı Dahil Et ('/')", + "includeLoginPage": "Giriş Sayfasını Dahil Et ('/login')", + "totalEndpoints": "Toplam UƧ Nokta", + "totalVisits": "Toplam Ziyaret", + "showing": "Gƶsteriliyor", + "selectedVisits": "SeƧilen Ziyaretler", + "endpoint": "Endpoint", + "visits": "Ziyaret", + "percentage": "Yüzde", + "loading": "Yükleniyor...", + "failedToLoad": "Endpoint verileri yüklenemedi. Lütfen sayfayı yenileyin.", + "home": "Ana Sayfa", + "login": "Giriş", + "top": "En Ƈok", + "numberOfVisits": "Ziyaret Sayısı", + "visitsTooltip": "Ziyaret: {0} (toplamın %{1}’i)", + "retry": "Yeniden Dene" + }, + "database": { + "title": "Veri Tabanını İƧe/Dışa Aktar", + "header": "Veri Tabanını İƧe/Dışa Aktar", + "fileName": "Dosya Adı", + "creationDate": "Oluşturulma Tarihi", + "fileSize": "Dosya Boyutu", + "deleteBackupFile": "Yedekleme Dosyasını Sil", + "importBackupFile": "Yedekleme Dosyasını İƧe Aktar", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Yedekleme Dosyasını İndir", + "info_1": "Verileri iƧe aktarırken, yapının doğru olduğundan emin olmak Ƨok ƶnemlidir. Ne yaptığınızdan emin değilseniz, bir uzmandan tavsiye ve destek alın. Yapıdaki bir hata, uygulamanın tamamen Ƨalıştırılamaması da dahil olmak üzere uygulama sorunlarına neden olabilir.", + "info_2": "Karşıya yüklerken dosya adı ƶnemli değildir. Daha sonra yedekleme_kullanıcısı_yyyyAAggSdd.sql biƧiminde yeniden adlandırılacak ve tutarlı bir adlandırma kuralı sağlanacaktır.", + "submit": "Yedeklemeyi İƧe Aktar", + "importIntoDatabaseSuccessed": "Veri tabanına başarıyla aktarıldı", + "backupCreated": "Veritabanı yedeklemesi başarılı", + "fileNotFound": "Dosya bulunamadı", + "fileNullOrEmpty": "Dosya yok veya boş olmamalıdır", + "failedImportFile": "Dosya İƧe Aktarılamadı", + "notSupported": "Bu işlev, mevcut veritabanı bağlantınız iƧin desteklenmiyor." + }, + "session": { + "expired": "Oturumunuzun süresi doldu. Lütfen sayfayı yenileyip tekrar deneyin.", + "refreshPage": "Sayfayı Yenile" + }, + "home": { + "desc": "Yerel olarak barındırılan tüm PDF ihtiyaƧlarınız iƧin tek durak noktanız.", + "searchBar": "Ɩzellikleri arayın...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Gƶrüntüleyin, aƧıklama ekleyin, metin veya resim ekleyin" + }, + "setFavorites": "Favorilere Ekle", + "hideFavorites": "Favorileri Gizle", + "showFavorites": "Favorileri Gƶster", + "legacyHomepage": "Eski ana sayfa", + "newHomePage": "Yeni ana sayfamızı deneyin!", + "alphabetical": "Alfabetik", + "globalPopularity": "Global Popülerlik", + "sortBy": "Sıralama ƶlçütü:", + "multiTool": { + "title": "PDF Ƈoklu AraƧ", + "desc": "Birleştir, Dƶndür, Yeniden Düzenle ve Sayfaları Kaldır" + }, + "merge": { + "title": "Birleştir", + "desc": "Ƈoklu PDF'leri tek bir dosyada kolayca birleştirin." + }, + "split": { + "title": "Ayır", + "desc": "PDF'leri birden fazla belgeye ayırın" + }, + "rotate": { + "title": "Dƶndür", + "desc": "PDF'lerinizi kolayca dƶndürün." + }, + "imageToPdf": { + "title": "Resimden PDF'e", + "desc": "Bir resmi (PNG, JPEG, GIF) PDF'e dƶnüştürün." + }, + "pdfToImage": { + "title": "PDF'den Resme", + "desc": "PDF'yi bir resme dƶnüştürün. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Düzenle", + "desc": "Sayfaları herhangi bir sırayla kaldırın/düzenleyin" + }, + "addImage": { + "title": "Resim Ekle", + "desc": "PDF'e belirli bir konuma resim ekler" + }, + "watermark": { + "title": "Filigran Ekle", + "desc": "PDF belgenize ƶzel bir filigran ekleyin." + }, + "permissions": { + "title": "İzinleri Değiştir", + "desc": "PDF belgenizin izinlerini değiştirin" + }, + "removePages": { + "title": "Kaldır", + "desc": "PDF belgenizden istenmeyen sayfaları silin." + }, + "addPassword": { + "title": "Parola Ekle", + "desc": "PDF belgenizi bir parola ile şifreleyin." + }, + "removePassword": { + "title": "Parolayı Kaldır", + "desc": "PDF belgenizden parola korumasını kaldırın." + }, + "compressPdfs": { + "title": "Sıkıştır", + "desc": "PDF'lerin dosya boyutunu azaltmak iƧin sıkıştırın." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Metaveriyi Değiştir", + "desc": "Bir PDF belgesinden metaveriyi değiştir/kaldır/ekle" + }, + "fileToPDF": { + "title": "Dosyayı PDF'e Dƶnüştür", + "desc": "Hemen hemen her dosyayı PDF'e dƶnüştürün (DOCX, PNG, XLS, PPT, TXT ve daha fazlası)" + }, + "ocr": { + "title": "OCR / Taramaları Temizle", + "desc": "Taramaları temizler ve bir PDF iƧindeki resimlerden metni algılar ve tekrar metin olarak ekler." + }, + "extractImages": { + "title": "Resimleri Ƈıkar", + "desc": "Bir PDF'ten tüm resimleri Ƨıkarır ve bunları zip olarak kaydeder." + }, + "pdfToPDFA": { + "title": "PDF'den PDF/A'ya", + "desc": "PDF'yi uzun vadeli saklama iƧin PDF/A'ya dƶnüştürün" + }, + "PDFToWord": { + "title": "PDF'den Word'e", + "desc": "PDF'yi Word formatlarına dƶnüştürün (DOC, DOCX ve ODT)" + }, + "PDFToPresentation": { + "title": "PDF'den Sunuma", + "desc": "PDF'yi Sunum formatlarına dƶnüştürün (PPT, PPTX ve ODP)" + }, + "PDFToText": { + "title": "PDF'den RTF (Metin)'e", + "desc": "PDF'i Metin veya RTF formatına dƶnüştür" + }, + "PDFToHTML": { + "title": "PDF'den HTML'e", + "desc": "PDF'i HTML formatına dƶnüştür" + }, + "PDFToXML": { + "title": "PDF'den XML'e", + "desc": "PDF'i XML formatına dƶnüştür" + }, + "ScannerImageSplit": { + "title": "Taranmış Fotoğrafları Tespit Et/Bƶl", + "desc": "Bir fotoğraf/PDF iƧerisindeki birden fazla fotoğrafı ayırır" + }, + "sign": { + "title": "İmzala", + "desc": "Ƈizim, metin veya resim ile PDF'e imza ekler" + }, + "flatten": { + "title": "Düzleştir", + "desc": "PDF'ten tüm etkileşimli öğeleri ve formları kaldırır" + }, + "repair": { + "title": "Onar", + "desc": "Bozuk/kırık bir PDF'i onarmaya Ƨalışır" + }, + "removeBlanks": { + "title": "Boş Sayfaları Kaldır", + "desc": "Bir belgeden boş sayfaları tespit eder ve kaldırır" + }, + "removeAnnotations": { + "title": "Ek AƧıklamaları Kaldır", + "desc": "PDF'deki tüm yorumları/aƧıklamaları kaldırır" + }, + "compare": { + "title": "Karşılaştır", + "desc": "2 PDF Belgesi arasındaki farkları karşılaştırır ve gƶsterir" + }, + "certSign": { + "title": "Sertifika ile İmzala", + "desc": "Bir PDF'i Sertifika/Anahtar (PEM/P12) ile imzalar" + }, + "removeCertSign": { + "title": "Sertifika İmzasını Kaldır", + "desc": "PDF'ten sertifika imzasını kaldırır" + }, + "pageLayout": { + "title": "Ƈoklu-Sayfa Düzeni", + "desc": "Bir PDF belgesinin Ƨoklu sayfalarını tek bir sayfada birleştirir" + }, + "scalePages": { + "title": "Sayfa boyutunu/ƶlƧeğini ayarla", + "desc": "Bir sayfanın ve/veya iƧeriğinin boyutunu/ƶlƧeğini değiştirir" + }, + "pipeline": { + "title": "Ƈoklu İşlemler", + "desc": "Ƈoklu İşlemler tanımlayarak PDF'lere birden fazla işlemi Ƨalıştır" + }, + "add-page-numbers": { + "title": "Sayfa Numaraları Ekle", + "desc": "Bir belgeye belirli bir konuma sayfa numaraları ekler" + }, + "auto-rename": { + "title": "PDF Dosyasını Otomatik Yeniden Adlandır", + "desc": "Tespit edilen başlığa dayanarak bir PDF dosyasını otomatik olarak yeniden adlandırır" + }, + "adjust-contrast": { + "title": "Renkleri/Kontrastı Ayarla", + "desc": "Bir PDF'in Kontrastını, Doygunluğunu ve Parlaklığını ayarlar" + }, + "crop": { + "title": "PDF'i Kırp", + "desc": "Boyutunu azaltmak iƧin bir PDF'i kırpar (metni korur!)" + }, + "autoSplitPDF": { + "title": "Sayfaları Otomatik Bƶl", + "desc": "Fiziksel taranmış sayfa bƶlücü QR Kod ile Taranmış PDF'i Otomatik Bƶl" + }, + "sanitizePdf": { + "title": "Temizle", + "desc": "PDF dosyalarından betikleri ve diğer öğeleri kaldırır" + }, + "URLToPDF": { + "title": "URL/Websitesi PDF'e", + "desc": "Herhangi bir http(s)URL'yi PDF'e dƶnüştürür" + }, + "HTMLToPDF": { + "title": "HTML'den PDF'e", + "desc": "Herhangi bir HTML dosyasını veya zip'i PDF'e dƶnüştürür" + }, + "MarkdownToPDF": { + "title": "Markdown'dan PDF'e", + "desc": "Herhangi bir Markdown dosyasını PDF'e dƶnüştürür" + }, + "PDFToMarkdown": { + "title": "PDF'den Markdown'a", + "desc": "Herhangi bir PDF'yi Markdown formatına dƶnüştürür" + }, + "getPdfInfo": { + "title": "PDF Hakkında TÜM Bilgiyi Al", + "desc": "PDF'ler hakkında mümkün olan her türlü bilgiyi toplar" + }, + "extractPage": { + "title": "Sayfa(ları) Ƈıkar", + "desc": "PDF'ten seƧili sayfaları Ƨıkarır" + }, + "PdfToSinglePage": { + "title": "PDF'i Tek Büyük Sayfaya", + "desc": "Tüm PDF sayfalarını tek büyük bir sayfada birleştirir" + }, + "showJS": { + "title": "Javascript'i Gƶster", + "desc": "Bir PDF'e enjekte edilen herhangi bir JS'i araştırır ve gƶsterir" + }, + "autoRedact": { + "title": "Otomatik Karartma", + "desc": "Giriş metnine dayanarak bir PDF'teki metni Otomatik Karartır (Redakte)" + }, + "redact": { + "title": "Manuel Sansürleme", + "desc": "SeƧilen metinler, Ƨizilen şekiller ve/veya belirli sayfalar üzerinden PDF'yi sansürler" + }, + "tableExtraxt": { + "title": "PDF'den CSV'ye", + "desc": "PDF'den Tabloları Ƨıkarır ve CSV'ye dƶnüştürür" + }, + "autoSizeSplitPDF": { + "title": "Boyut/Sayıya Gƶre Otomatik Bƶlme", + "desc": "Tek bir PDF'yi boyut, sayfa sayısı veya belge sayısına gƶre birden fazla belgeye bƶlün" + }, + "overlay-pdfs": { + "title": "PDF'leri Bindirme", + "desc": "PDF'leri başka bir PDF'nin üzerine bindirir" + }, + "split-by-sections": { + "title": "PDF'yi Bƶlümlere Ayırma", + "desc": "PDF'nin her sayfasını daha küçük yatay ve dikey bƶlümlere ayırın" + }, + "AddStampRequest": { + "title": "PDF'ye Damga Ekleme", + "desc": "Belirlenen konumlara metin veya resim damgaları ekleyin" + }, + "removeImagePdf": { + "title": "Resmi kaldır", + "desc": "Dosya boyutunu küçültmek iƧin PDF'den resmi kaldırın" + }, + "splitPdfByChapters": { + "title": "PDF'yi Bƶlümlere Gƶre Bƶl", + "desc": "PDF'yi bƶlüm yapısına gƶre birden fazla dosyaya ayırın." + }, + "validateSignature": { + "title": "PDF İmzasını Doğrula", + "desc": "PDF belgelerindeki dijital imzaları ve sertifikaları doğrulayın" + }, + "replaceColorPdf": { + "title": "Renkleri Değiştir ve Tersine Ƈevir", + "desc": "PDF'deki metin ve arka plan renklerini değiştirin ve PDF'nin tüm renklerini tersine Ƨevirerek dosya boyutunu azaltın" + } + }, + "viewPdf": { + "tags": "gƶrüntüle,oku,aƧıklama ekle,metin,gƶrüntü", + "title": "View/Edit PDF", + "header": "PDF Gƶrüntüle" + }, + "multiTool": { + "tags": "Ƈoklu AraƧ,Ƈoklu işlem,Arayüz,tıklama sürükleme,ƶn uƧ,istemci tarafı,etkileşimli,taşınabilir,taşı", + "title": "PDF Ƈoklu AraƧ", + "header": "PDF Ƈoklu AraƧ", + "uploadPrompts": "Dosya Adı", + "selectAll": "Tümünü SeƧ", + "deselectAll": "SeƧimi Kaldır", + "selectPages": "Sayfa SeƧ", + "selectedPages": "SeƧilen Sayfalar", + "page": "Sayfa", + "deleteSelected": "SeƧilenleri Sil", + "downloadAll": "Dışa Aktar", + "downloadSelected": "SeƧilenleri Dışa Aktar", + "insertPageBreak": "Sayfa Sonu Ekle", + "addFile": "Dosya Ekle", + "rotateLeft": "Sola Dƶndür", + "rotateRight": "Sağa Dƶndür", + "split": "Bƶl", + "moveLeft": "Sola Taşı", + "moveRight": "Sağa Taşı", + "delete": "Sil", + "dragDropMessage": "Sayfa(lar) SeƧildi", + "undo": "Geri Al", + "redo": "Yinele" + }, + "merge": { + "tags": "birleştir,Sayfa işlemleri,Arka uƧ,sunucu tarafı", + "title": "Birleştir", + "header": "Ƈoklu PDF'leri Birleştir (2+)", + "sortByName": "İsme gƶre sırala", + "sortByDate": "Tarihe gƶre sırala", + "removeCertSign": "Birleştirilen dosyadaki dijital imza kaldırılsın mı?", + "submit": "Birleştir" + }, + "split": { + "tags": "Sayfa işlemleri,bƶl,Ƈoklu Sayfa,kes,sunucu tarafı", + "title": "PDF Ayır", + "header": "PDF Ayır", + "desc": { + "1": "SeƧtiğiniz numaralar, bir ayrım yapmak istediğiniz sayfa numarasıdır", + "2": "Bu nedenle, 1,3,7-9 seƧmek 10 sayfalı bir belgeyi şunlarla 6 ayrı PDF'e bƶler:", + "3": "Belge #1: Sayfa 1", + "4": "Belge #2: Sayfa 2 ve 3", + "5": "Belge #3: Sayfa 4, 5, 6 ve 7", + "6": "Belge #4: Sayfa 8", + "7": "Belge #5: Sayfa 9", + "8": "Belge #6: Sayfa 10" + }, + "splitPages": "Ayrılacak sayfaları girin:", + "submit": "Ayır" + }, + "rotate": { + "tags": "sunucu tarafı", + "title": "PDF Dƶndür", + "header": "PDF Dƶndür", + "selectAngle": "Dƶndürme aƧısını seƧin (90 derecenin katları olarak):", + "submit": "Dƶndür" + }, + "imageToPdf": { + "tags": "dƶnüşüm,img,jpg,fotoğraf,resim" + }, + "pdfToImage": { + "tags": "dƶnüşüm,img,jpg,fotoğraf,resim", + "title": "PDF'den Resme", + "header": "PDF'den Resme", + "selectText": "Resim Formatı", + "singleOrMultiple": "SonuƧ resim tipi", + "single": "Tüm sayfaları birleştiren Tek Büyük Resim", + "multi": "Ƈoklu Resimler, sayfa başına bir resim", + "colorType": "Renk türü", + "color": "Renk", + "grey": "Gri tonlama", + "blackwhite": "Siyah ve Beyaz (Veri kaybolabilir!)", + "submit": "Dƶnüştür", + "info": "Python kurulu değil. WebP dƶnüşümü iƧin gereklidir.", + "placeholder": "(ƶrneğin 1,2,8 veya 4,7,12-16 ya da 2n-1)" + }, + "pdfOrganiser": { + "tags": "Ƨift,Ƨift,yan,yana,sırala,taşı", + "title": "Sayfa Organizatƶrü", + "header": "PDF Sayfa Organizatƶrü", + "submit": "Sayfaları Yeniden Düzenle", + "mode": { + "_value": "Mod", + "1": "Ɩzel Sayfa Düzeni", + "2": "Ters Sıralama", + "3": "Ƈift Taraflı Sıralama", + "4": "KitapƧık Sıralama", + "5": "Yandan Dikişli KitapƧık Sıralama", + "6": "Tek-Ƈift Ayrımı", + "7": "İlk Ɩnce Kaldır", + "8": "Sonuncuyu Kaldır", + "9": "İlk ve Sonu Kaldır", + "10": "Tek-Ƈift Birleştirme", + "11": "Tüm sayfaları Ƨoğalt" + }, + "placeholder": "(ƶrn. 1,3,2 veya 4-8,2,10-12 veya 2n-1)" + }, + "addImage": { + "tags": "img,jpg,fotoğraf,resim", + "title": "Resim Ekle", + "header": "PDF'e resim ekle", + "everyPage": "Her Sayfa mı?", + "upload": "Resim ekle", + "submit": "Resim ekle" + }, + "watermark": { + "tags": "Metin,tekrarlayan,etiket,kendi,telif hakkı,marka,img,jpg,fotoğraf,resim", + "title": "Filigran Ekle", + "header": "Filigran Ekle", + "customColor": "Ɩzel Metin Rengi", + "selectText": { + "1": "Filigran eklemek iƧin PDF seƧin:", + "2": "Filigran Metni:", + "3": "Yazı Boyutu:", + "4": "Dƶndürme (0-360):", + "5": "genişlikBoşluk (Yatayda her filigran arasında boşluk):", + "6": "yükseklikBoşluk (Dikeyde her filigran arasında boşluk):", + "7": "Opaklık (0% - 100%):", + "8": "Filigran Türü:", + "9": "Filigran Resmi:", + "10": "PDF'yi PDF-Resim'e Dƶnüştür" + }, + "submit": "Filigran Ekle", + "type": { + "1": "Metin", + "2": "Resim" + } + }, + "permissions": { + "tags": "oku,yaz,düzenle,yazdır", + "title": "İzinleri Değiştir", + "header": "İzinleri Değiştir", + "warning": "İzinlerin değiştirilemez olması iƧin bunları add-password sayfası aracılığıyla bir parola ile ayarlamaları ƶnerilir", + "selectText": { + "1": "İzinlerini değiştirmek iƧin PDF seƧin", + "2": "Ayarlanacak izinler", + "3": "Belgenin birleştirilmesini ƶnle", + "4": "İƧeriğin Ƨıkarılmasını ƶnle", + "5": "Erişilebilirlik iƧin Ƨıkarmanın ƶnlenmesi", + "6": "Formun doldurulmasını ƶnle", + "7": "Değişikliği ƶnle", + "8": "AƧıklama değişikliğini ƶnle", + "9": "Yazdırmayı ƶnle", + "10": "Farklı formatlarda yazdırmayı ƶnle" + }, + "submit": "Değiştir" + }, + "removePages": { + "tags": "Sayfaları kaldır,sayfaları sil" + }, + "addPassword": { + "tags": "güvenli, güvenlik", + "title": "Parola Ekle", + "header": "Parola Ekle (Şifrele)", + "selectText": { + "1": "Şifrelenecek PDF'i seƧin", + "2": "Kullanıcı Parolası", + "3": "Şifreleme Anahtar Uzunluğu", + "4": "Daha yüksek değerler daha güçlüdür, ancak daha düşük değerler daha iyi uyumluluğa sahiptir.", + "5": "İzinlerin ayarlanması (Sahip parolası ile birlikte kullanılması ƶnerilir)", + "6": "Belgenin birleştirilmesini ƶnle", + "7": "İƧeriğin Ƨıkarılmasını ƶnle", + "8": "Erişilebilirlik iƧin Ƨıkarmanın ƶnlenmesi", + "9": "Formun doldurulmasını ƶnle", + "10": "Değişikliği ƶnle", + "11": "AƧıklama değişikliğini ƶnle", + "12": "Yazdırmayı ƶnle", + "13": "Farklı formatlarda yazdırmayı ƶnle", + "14": "Sahip Parolası", + "15": "AƧıldığında belgeyle ne yapılacağını kısıtlar (Tüm okuyucular tarafından desteklenmez)", + "16": "Belgenin kendisinin aƧılmasını kısıtlar" + }, + "submit": "Şifrele" + }, + "removePassword": { + "tags": "güvenli,Şifreyi Ƨƶz,güvenlik,parolasız,parolayı sil", + "title": "Parola Kaldır", + "header": "Parola Kaldır (Şifre Ƈƶz)", + "selectText": { + "1": "Şifreyi Ƈƶzmek iƧin PDF SeƧin", + "2": "Parola" + }, + "submit": "Kaldır" + }, + "compressPdfs": { + "tags": "sıkıştır,küçük,minik" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "Başlık,yazar,tarih,oluşturma,zaman,yayıncı,üretici,istatistikler", + "title": "Başlık:", + "header": "Metaveriyi Değiştir", + "selectText": { + "1": "Değiştirmek istediğiniz değişkenleri düzenleyin", + "2": "Tüm metaveriyi sil", + "3": "Ɩzel Metaveriyi Gƶster:", + "4": "Diğer Metaveri:", + "5": "Ɩzel Metaveri Girişi Ekle" + }, + "author": "Yazar:", + "creationDate": "Oluşturma Tarihi (yyyy/MM/dd HH:mm:ss):", + "creator": "Oluşturan:", + "keywords": "Anahtar Kelimeler:", + "modDate": "Değişiklik Tarihi (yyyy/MM/dd HH:mm:ss):", + "producer": "Üretici:", + "subject": "Konu:", + "trapped": "Tuzak:", + "submit": "Değiştir" + }, + "fileToPDF": { + "tags": "dƶnüşüm,format,belge,fotoğraf,slayt,metin,dƶnüşüm,ofis,doküman,word,excel,powerpoint", + "title": "Dosyadan PDF'e", + "header": "Herhangi bir dosyayı PDF'e dƶnüştür", + "credit": "Bu hizmet dosya dƶnüşümü iƧin LibreOffice ve Unoconv'u kullanır.", + "supportedFileTypesInfo": "Desteklenen Dosya türleri", + "supportedFileTypes": "Desteklenen dosya türleri aşağıdakileri iƧermelidir ancak desteklenen formatların tam güncellenmiş listesi iƧin lütfen LibreOffice dokümantasyonuna başvurun", + "submit": "PDF'e Dƶnüştür" + }, + "ocr": { + "tags": "tanıma,metin,resim,tarama,okuma,tanımlama,algılama,düzenlenebilir", + "title": "OCR / Tarama Temizleme", + "header": "Taramaları Temizle / OCR (Optik Karakter Tanıma)", + "selectText": { + "1": "PDF iƧinde tespit edilecek dilleri seƧin (Listelenenler şu anda tespit edilenlerdir):", + "2": "OCR'li PDF ile birlikte OCR metnini iƧeren metin dosyası oluştur", + "3": "Skew aƧıda taranan sayfaları geri dƶndürerek düzeltin", + "4": "OCR'nin arka planda metin bulmasını azaltmak iƧin sayfayı temizle. (Ƈıktıda değişiklik yok)", + "5": "OCR'nin arka planda metin bulmasını azaltmak iƧin sayfayı temizle, temizlemeyi Ƨıktıda korur.", + "6": "İnteraktif metni olan sayfaları yoksay, sadece resim olan sayfaları OCR yapar", + "7": "Zorla OCR, tüm orijinal metin öğelerini kaldırarak Her sayfayı OCR yapar", + "8": "Normal (PDF metin iƧeriyorsa hata verir)", + "9": "Ek Ayarlar", + "10": "OCR Modu", + "11": "OCR'den sonra resimleri kaldır (TÜM resimleri kaldırır, sadece dƶnüşüm adımının bir parƧasıysa yararlıdır)", + "12": "Render Türü (İleri Seviye)" + }, + "help": "Lütfen bu belgede başka dillerde nasıl kullanılacağı ve/veya docker'da kullanılmaması hakkında bilgi edinin", + "credit": "Bu hizmet OCR iƧin qpdf ve Tesseract'ı kullanır.", + "submit": "PDF'i OCR(Metin Tanıma) ile İşle" + }, + "extractImages": { + "tags": "fotoğraf,resim,kaydet,arşiv,zip,yakala,al", + "title": "Resimleri Ƈıkar", + "header": "Resimleri Ƈıkar", + "selectText": "Ƈıkarılan resimleri dƶnüştürmek iƧin resim formatını seƧin", + "allowDuplicates": "Yinelenen gƶrselleri kaydet", + "submit": "Ƈıkar" + }, + "pdfToPDFA": { + "tags": "arşiv,uzun vadeli,standart,dƶnüşüm,saklama,koruma", + "title": "PDF'den PDF/A'ya", + "header": "PDF'den PDF/A'ya", + "credit": "Bu hizmet PDF/A dƶnüşümü iƧin libreoffice kullanır", + "submit": "Dƶnüştür", + "tip": "Şu anda aynı anda birden fazla giriş iƧin Ƨalışmıyor", + "outputFormat": "Ƈıkış formatı", + "pdfWithDigitalSignature": "PDF dijital imza iƧeriyor. Bu bir sonraki adımda kaldırılacak." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,dƶnüşüm,format,dƶnüşüm,ofis,microsoft,docfile", + "title": "PDF'den Word'e", + "header": "PDF'den Word'e", + "selectText": { + "1": "Ƈıktı dosya formatı" + }, + "credit": "Bu hizmet dosya dƶnüşümü iƧin LibreOffice kullanır.", + "submit": "Dƶnüştür" + }, + "PDFToPresentation": { + "tags": "slaytlar,show,ofis,microsoft", + "title": "PDF'den Sunuma", + "header": "PDF'den Sunuma", + "selectText": { + "1": "Ƈıktı dosya formatı" + }, + "credit": "Bu hizmet dosya dƶnüşümü iƧin LibreOffice kullanır.", + "submit": "Dƶnüştür" + }, + "PDFToText": { + "tags": "zenginformat,zenginmetinformatı,zengin metin formatı", + "title": "PDF'den RTF (Metin)'e", + "header": "PDF'den RTF (Metin)'e", + "selectText": { + "1": "Ƈıktı dosya formatı" + }, + "credit": "Bu hizmet dosya dƶnüşümü iƧin LibreOffice kullanır.", + "submit": "Dƶnüştür" + }, + "PDFToHTML": { + "tags": "web iƧeriği,tarayıcı dostu", + "title": "PDF'den HTML'e", + "header": "PDF'den HTML'e", + "credit": "Bu hizmet dosya dƶnüşümü iƧin pdftohtml kullanır.", + "submit": "Dƶnüştür" + }, + "PDFToXML": { + "tags": "veri-Ƨıkarımı,yapılandırılmış-iƧerik,entegrasyon,dƶnüşüm,dƶnüştür", + "title": "PDF'den XML'e", + "header": "PDF'den XML'e", + "credit": "Bu hizmet dosya dƶnüşümü iƧin LibreOffice kullanır.", + "submit": "Dƶnüştür" + }, + "ScannerImageSplit": { + "tags": "ayır,otomatik-tespit,taramalar,Ƨoklu-fotoğraf,düzenle", + "selectText": { + "1": "AƧı Eşiği:", + "2": "Resmin dƶndürülmesi iƧin gereken minimum mutlak aƧıyı ayarlar (varsayılan: 10).", + "3": "Tolerans:", + "4": "Tahmini arka plan rengi etrafındaki renk varyasyon aralığını belirler (varsayılan: 30).", + "5": "Minimum Alan:", + "6": "Bir fotoğraf iƧin minimum alan eşiğini ayarlar (varsayılan: 10000).", + "7": "Minimum Kontur Alanı:", + "8": "Bir fotoğraf iƧin minimum kontur alanı eşiğini ayarlar", + "9": "Kenar Boyutu:", + "10": "Ƈıktıda beyaz kenarların ƶnlenmesi iƧin eklenen ve kaldırılan kenarın boyutunu ayarlar (varsayılan: 1)." + }, + "info": "Python kurulu değil. Ƈalışması iƧin gereklidir." + }, + "sign": { + "tags": "onayla,başharfler,Ƨizili-imza,metin-imza,resim-imza", + "title": "İmzala", + "header": "PDF'lere İmza At", + "upload": "Resim Yükle", + "draw": "İmza Ƈiz", + "text": "Metin Girişi", + "clear": "Temizle", + "add": "Ekle", + "saved": "Kaydedilmiş İmzalar", + "save": "İmzayı Kaydet", + "personalSigs": "Kişisel İmzalar", + "sharedSigs": "Paylaşılan İmzalar", + "noSavedSigs": "Kayıtlı imza bulunamadı", + "addToAll": "Tüm sayfalara ekle", + "delete": "Sil", + "first": "İlk sayfa", + "last": "Son sayfa", + "next": "Sonraki sayfa", + "previous": "Ɩnceki sayfa", + "maintainRatio": "Oranı korumayı değiştir", + "undo": "Geri Al", + "redo": "Yinele" + }, + "flatten": { + "tags": "statik,devre dışı bırak,etkileşimsiz,sadeleştir", + "title": "Düzleştir", + "header": "PDF'leri Düzleştir", + "flattenOnlyForms": "Yalnızca formları düzleştir", + "submit": "Düzleştir" + }, + "repair": { + "tags": "onar,geri yükle,düzelt,geri getir", + "title": "Onar", + "header": "PDF'leri Onar", + "submit": "Onar" + }, + "removeBlanks": { + "tags": "temizle,sadeleştir,iƧeriksiz,düzenle", + "title": "Boşları Kaldır", + "header": "Boş Sayfaları Kaldır", + "threshold": "Pixel Beyazlık Eşiği:", + "thresholdDesc": "Bir beyaz pixelin 'Beyaz' olarak sınıflandırılması iƧin ne kadar beyaz olması gerektiğini belirlemek iƧin eşik. 0 = Siyah, 255 saf beyaz.", + "whitePercent": "Beyaz Yüzde (%):", + "whitePercentDesc": "Bir sayfanın 'beyaz' pixel olması gereken yüzdesi", + "submit": "Boşları Kaldır" + }, + "removeAnnotations": { + "tags": "yorumlar,vurgulama,notlar,işaretleme,kaldırma", + "title": "Ek AƧıklamaları Kaldır", + "header": "Ek AƧıklamaları Kaldır", + "submit": "Kaldır" + }, + "compare": { + "tags": "farklılaştır,karşılaştır,değişiklikler,analiz", + "title": "Karşılaştır", + "header": "PDF'leri Karşılaştır", + "highlightColor": { + "1": "Vurgu Rengi 1:", + "2": "Vurgu Rengi 2:" + }, + "document": { + "1": "Belge 1", + "2": "Belge 2" + }, + "submit": "Karşılaştır", + "complex": { + "message": "Verilen belgelerden biri veya her ikisi büyük dosyalar olduğundan karşılaştırma doğruluğu azalabilir" + }, + "large": { + "file": { + "message": "Verilen belgelerden biri veya her ikisi işlenemeyecek kadar büyük" + } + }, + "no": { + "text": { + "message": "SeƧilen PDF'lerden biri veya her ikisinde metin iƧeriği yok. Lütfen karşılaştırma iƧin metin iƧeren PDF'ler seƧin." + } + } + }, + "certSign": { + "tags": "doğrula,PEM,P12,resmi,şifrele", + "title": "Sertifika İmzalama", + "header": "Sertifikanızla bir PDF imzalayın (Devam eden iş)", + "selectPDF": "İmzalamak iƧin bir PDF Dosyası seƧin:", + "jksNote": "Not: Sertifika türünüz aşağıda listelenmemişse, lütfen keytool komut satırı aracını kullanarak sertifikanızı bir Java Keystore (.jks) dosyasına dƶnüştürün. Ardından, aşağıdaki .jks dosyası seƧeneğini seƧin.", + "selectKey": "Ɩzel Anahtar Dosyanızı SeƧin (PKCS#8 formatında, .pem veya .der olabilir):", + "selectCert": "Sertifika Dosyanızı SeƧin (X.509 formatında, .pem veya .der olabilir):", + "selectP12": "PKCS#12 Anahtar Deposu Dosyanızı SeƧin (.p12 veya .pfx) (İsteğe bağlı, sağlanırsa, ƶzel anahtarınızı ve sertifikanızı iƧermelidir):", + "selectJKS": "Java Keystore Dosyanızı (.jks veya .keystore) seƧin:", + "certType": "Sertifika Türü", + "password": "Anahtar Deposu veya Ɩzel Anahtar Şifrenizi Girin (Varsa):", + "showSig": "İmzayı Gƶster", + "reason": "Neden", + "location": "Konum", + "name": "İsim", + "showLogo": "Show Logo", + "submit": "PDF'i İmzala" + }, + "removeCertSign": { + "tags": "doğrula,PEM,P12,resmi,şifre Ƨƶz", + "title": "Sertifika İmzasını Kaldır", + "header": "PDF'ten dijital sertifikayı kaldırın", + "selectPDF": "PDF dosyası seƧin:", + "submit": "İmzayı Kaldır" + }, + "pageLayout": { + "tags": "birleştir,kompozit,tek-gƶrünüm,düzenle", + "title": "Ƈoklu Sayfa Düzeni", + "header": "Ƈoklu Sayfa Düzeni", + "pagesPerSheet": "Sayfa başına sayfalar:", + "addBorder": "Kenarlık Ekle", + "submit": "Gƶnder" + }, + "scalePages": { + "tags": "boyutlandır,değiştir,boyut,uyarla", + "title": "Sayfa ƖlƧeğini Ayarla", + "header": "Sayfa ƖlƧeğini Ayarla", + "pageSize": "Belgenin bir sayfa boyutu.", + "keepPageSize": "Original Size", + "scaleFactor": "Bir sayfanın yakınlaştırma seviyesi (kırpma).", + "submit": "Gƶnder" + }, + "add-page-numbers": { + "tags": "sayfalandır,etiket,düzenle,dizin" + }, + "auto-rename": { + "tags": "otomatik-tespit,başlık-tabanlı,düzenle,yeniden-etiketle", + "title": "Otomatik Yeniden Adlandır", + "header": "PDF'i Otomatik Yeniden Adlandır", + "submit": "Otomatik Yeniden Adlandır" + }, + "adjust-contrast": { + "tags": "renk-düzeltme,ayarla,değiştir,artır" + }, + "crop": { + "tags": "kırp,küçült,düzenle,şekillendir", + "title": "Kırp", + "header": "PDF'i Kırp", + "submit": "Gƶnder" + }, + "autoSplitPDF": { + "tags": "QR-tabanlı,ayır,tarama-segmenti,düzenle", + "title": "PDF'i Otomatik Bƶl", + "header": "PDF'i Otomatik Bƶl", + "description": "Yazdır, Ekle, Tara, yükle ve belgelerinizi otomatik olarak ayırmamıza izin ver. Elle sıralama yapmaya gerek yok.", + "selectText": { + "1": "Aşağıdan bazı ayırıcı sayfaları yazdırın (Siyah ve beyaz olabilir).", + "2": "Ayırıcı sayfayı aralarına ekleyerek tüm belgelerinizi birden tara.", + "3": "Tek büyük taranmış PDF dosyasını yükleyin ve gerisini Stirling PDF'in halletmesine izin verin.", + "4": "Ayırıcı sayfalar otomatik olarak tespit edilir ve kaldırılır, düzgün bir final belgesi garantilidir." + }, + "formPrompt": "Stirling-PDF Sayfa ayırıcıları iƧeren PDF'i gƶnderin:", + "duplexMode": "Ƈift Taraflı Mod (Ɩn ve arka tarama)", + "dividerDownload2": "'Otomatik Ayırıcı Ayırıcı (talimatlarla).pdf' indir", + "submit": "Gƶnder" + }, + "sanitizePdf": { + "tags": "temizle,güvende,korunaklı,tehditleri-kaldır" + }, + "URLToPDF": { + "tags": "web-yakala,sayfa-kaydet,webten-dƶkümana,arşivle", + "title": "URL'den PDF'e", + "header": "URL'den PDF'e", + "submit": "Dƶnüştür", + "credit": "WeasyPrint Kullanıyor" + }, + "HTMLToPDF": { + "tags": "biƧimlendirme,web-iƧeriği,dƶnüşüm,dƶnüştür", + "title": "HTML'den PDF'e", + "header": "HTML'den PDF'e", + "help": "HTML dosyalarını ve html/css/gƶrsel vb. iƧeren ZIP'leri kabul eder", + "submit": "Dƶnüştür", + "credit": "WeasyPrint Kullanıyor", + "zoom": "Web sitesini gƶrüntülemek iƧin yakınlaştırma düzeyi.", + "pageWidth": "Sayfanın santimetre cinsinden genişliği. (Varsayılan olarak boş)", + "pageHeight": "Sayfanın santimetre cinsinden yüksekliği. (Varsayılan olarak boş)", + "marginTop": "Sayfanın milimetre cinsinden üst kenar boşluğu. (Varsayılan olarak boş)", + "marginBottom": "Sayfanın milimetre cinsinden alt kenar boşluğu. (Varsayılan olarak boş)", + "marginLeft": "Sayfanın milimetre cinsinden sol kenar boşluğu. (Varsayılan olarak boş)", + "marginRight": "Sayfanın milimetre cinsinden sağ kenar boşluğu. (Varsayılan olarak boş)", + "printBackground": "Web sitelerinin arka planını oluşturun.", + "defaultHeader": "Varsayılan Üstbilgiyi Etkinleştir (Ad ve sayfa numarası)", + "cssMediaType": "Sayfanın CSS ortam türünü değiştirin.", + "none": "HiƧbiri", + "print": "Yazdır", + "screen": "Ekran" + }, + "MarkdownToPDF": { + "tags": "biƧimlendirme,web-iƧeriği,dƶnüşüm,dƶnüştür", + "title": "Markdown'dan PDF'e", + "header": "Markdown'dan PDF'e", + "submit": "Dƶnüştür", + "help": "Devam eden iş", + "credit": "WeasyPrint Kullanıyor" + }, + "PDFToMarkdown": { + "tags": "biƧimlendirme,web-iƧeriği,dƶnüşüm,dƶnüştür,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "bilgi,veri,istatistikler,istatistik", + "title": "PDF Hakkında Bilgi Al", + "header": "PDF Hakkında Bilgi Al", + "submit": "Bilgi Al", + "downloadJson": "JSON İndir" + }, + "extractPage": { + "tags": "Ƨıkar" + }, + "PdfToSinglePage": { + "tags": "tek sayfa" + }, + "showJS": { + "tags": "JS", + "title": "Javascript'i Gƶster", + "header": "Javascript'i Gƶster", + "downloadJS": "Javascript İndir", + "submit": "Gƶster" + }, + "autoRedact": { + "tags": "Karart,Gizle,karartma,siyah,markƶr,gizli", + "title": "Otomatik Karartma", + "header": "Otomatik Karartma", + "colorLabel": "Renk", + "textsToRedactLabel": "Karartılacak Metin (satır ayrılmış)", + "textsToRedactPlaceholder": "Ɩrn. \\nGizli \\nƇok Gizli", + "useRegexLabel": "Regex Kullan", + "wholeWordSearchLabel": "Tam Kelime Arama", + "customPaddingLabel": "Ɩzel Ekstra Dolgu", + "convertPDFToImageLabel": "PDF'i PDF-Gƶrüntü'ye dƶnüştür (Kutunun arkasındaki metni kaldırmak iƧin kullanılır)", + "submitButton": "Gƶnder" + }, + "redact": { + "tags": "Sansürle,Gizle,karart,karartma,işaretleyici,gizli,manuel", + "title": "Manuel Sansürleme", + "header": "Manuel Sansürleme", + "submit": "Sansürle", + "textBasedRedaction": "Metin Tabanlı Sansürleme", + "pageBasedRedaction": "Sayfa Tabanlı Sansürleme", + "convertPDFToImageLabel": "PDF'yi Gƶrsel PDF'ye Dƶnüştür (Kutunun arkasındaki metni kaldırmak iƧin kullanılır)", + "pageRedactionNumbers": { + "title": "Sayfalar", + "placeholder": "(ƶrneğin: 1,2,8 veya 4,7,12-16 ya da 2n-1)" + }, + "redactionColor": { + "title": "Sansür Rengi" + }, + "export": "Dışa Aktar", + "upload": "Yükle", + "boxRedaction": "Kutu Ƈizerek Sansürleme", + "zoom": "Yakınlaştırma", + "zoomIn": "Yakınlaştır", + "zoomOut": "Uzaklaştır", + "nextPage": "Sonraki Sayfa", + "previousPage": "Ɩnceki Sayfa", + "toggleSidebar": "Kenar Ƈubuğunu AƧ/Kapat", + "showThumbnails": "Küçük Resimleri Gƶster", + "showDocumentOutline": "Belge Anahatlarını Gƶster (tüm öğeleri genişletmek/daraltmak iƧin Ƨift tıklayın)", + "showAttatchments": "Ekleri Gƶster", + "showLayers": "Katmanları Gƶster (tüm katmanları varsayılana dƶndürmek iƧin Ƨift tıklayın)", + "colourPicker": "Renk SeƧici", + "findCurrentOutlineItem": "GeƧerli Anahat Ɩğesini Bul", + "applyChanges": "Değişiklikleri Uygula" + }, + "tableExtraxt": { + "tags": "CSV, Tablo Ƈıkarma, ayıklama, dƶnüştürme" + }, + "autoSizeSplitPDF": { + "tags": "pdf,bƶlme,belge,organizasyon" + }, + "overlay-pdfs": { + "tags": "Bindirme", + "header": "PDF Dosyalarını Bindirme", + "baseFile": { + "label": "Temel PDF Dosyasını SeƧin" + }, + "overlayFiles": { + "label": "İkinci PDF Dosyalarını SeƧin" + }, + "mode": { + "label": "Bindirme Modunu SeƧin", + "sequential": "Sıralı Bindirme", + "interleaved": "Serpiştirilmiş Bindirme", + "fixedRepeat": "Sabit Tekrar Bindirme" + }, + "counts": { + "label": "Bindirme Sayıları (Sabit Tekrar Modu iƧin)", + "placeholder": "Virgülle ayrılmış sayıları girin (ƶrn. 2,3,1)" + }, + "position": { + "label": "Bindirme Konumunu SeƧin", + "foreground": "Ɩn plan", + "background": "Arka plan" + }, + "submit": "Gƶnder" + }, + "split-by-sections": { + "tags": "Bƶlümlere Ayırma, Bƶlme, Ɩzelleştirme", + "title": "PDF'yi Bƶlümlere Ayırma", + "header": "PDF'yi Bƶlümlere Ayırma", + "horizontal": { + "label": "Yatay Bƶlümler", + "placeholder": "Yatay bƶlme sayısını girin" + }, + "vertical": { + "label": "Dikey Bƶlümler", + "placeholder": "Dikey bƶlme sayısını girin" + }, + "submit": "PDF'yi Bƶl", + "merge": "Bir PDF'de Birleştirin" + }, + "AddStampRequest": { + "tags": "Damga, Gƶrüntü ekle, Gƶrüntüyü ortala, Filigran, PDF, Gƶm, Ɩzelleştir", + "header": "Damga PDF", + "title": "Damga PDF", + "stampType": "Damga Türü", + "stampText": "Damga Metni", + "stampImage": "Damga Resmi", + "alphabet": "Alfabe", + "fontSize": "Yazı Tipi/Gƶrüntü Boyutu", + "rotation": "Dƶndürme", + "opacity": "Opaklık", + "position": "Konum", + "overrideX": "X Koordinatını geƧersiz kıl", + "overrideY": "Y Koordinatını GeƧersiz Kıl", + "customMargin": "Ɩzel Kenar Boşluğu", + "customColor": "Ɩzel Metin Rengi", + "submit": "Gƶnder" + }, + "removeImagePdf": { + "tags": "Resmi Kaldır,Sayfa İşlemleri,Arka uƧ,sunucu tarafı" + }, + "splitPdfByChapters": { + "tags": "bƶl, bƶlümler, yer imleri, düzenle" + }, + "validateSignature": { + "tags": "imza, doğrula, geƧerlilik kontrolü, pdf, sertifika, dijital imza, İmzayı Doğrula, Sertifikayı Doğrula", + "title": "PDF İmzalarını Doğrula", + "header": "Dijital İmzaları Doğrula", + "selectPDF": "İmzalanmış PDF dosyasını seƧin", + "submit": "İmzaları Doğrula", + "results": "Doğrulama SonuƧları", + "status": { + "_value": "Durum", + "valid": "GeƧerli", + "invalid": "GeƧersiz" + }, + "signer": "İmzalayan", + "date": "Tarih", + "reason": "GerekƧe", + "location": "Konum", + "noSignatures": "Bu belgede dijital imza bulunamadı", + "chain": { + "invalid": "Sertifika zinciri doğrulaması başarısız - imzalayanın kimliği doğrulanamıyor" + }, + "trust": { + "invalid": "Sertifika güvenilir mağazada değil - kaynak doğrulanamıyor" + }, + "cert": { + "expired": "Sertifika süresi dolmuş", + "revoked": "Sertifika iptal edilmiş", + "info": "Sertifika Detayları", + "issuer": "Veren", + "subject": "Konu", + "serialNumber": "Seri Numarası", + "validFrom": "GeƧerlilik Başlangıcı", + "validUntil": "GeƧerlilik Bitişi", + "algorithm": "Algoritma", + "keySize": "Anahtar Boyutu", + "version": "Sürüm", + "keyUsage": "Anahtar Kullanımı", + "selfSigned": "Kendi Kendine İmzalı", + "bits": "bits" + }, + "signature": { + "info": "İmza Bilgisi", + "_value": "İmza", + "mathValid": "İmza matematiksel olarak geƧerli, ANCAK:" + }, + "selectCustomCert": "Ɩzel Sertifika Dosyası X.509 (İsteğe Bağlı)" + }, + "replace-color": { + "title": "Renk Değiştir-Tersine Ƈevir", + "header": "PDF Renklerini Değiştir veya Tersine Ƈevir", + "selectText": { + "1": "Renk Değiştir veya Tersine Ƈevirme SeƧenekleri", + "2": "Varsayılan (Yüksek kontrastlı varsayılan renkler)", + "3": "Ɩzel (Kişiselleştirilmiş renkler)", + "4": "Tümü Tersine Ƈevir (Tüm renkleri tersine Ƨevir)", + "5": "Yüksek kontrastlı renk seƧenekleri", + "6": "Siyah arka plan üzerine beyaz metin", + "7": "Beyaz arka plan üzerine siyah metin", + "8": "Siyah arka plan üzerine sarı metin", + "9": "Siyah arka plan üzerine yeşil metin", + "10": "Metin Rengini SeƧ", + "11": "Arka Plan Rengini SeƧ" + }, + "submit": "Değiştir" + }, + "replaceColorPdf": { + "tags": "Renk Değiştir, Sayfa işlemleri, Arka yüz, Sunucu tarafı" + }, + "login": { + "title": "Giriş Yap", + "header": "Giriş Yap", + "signin": "Giriş Yap", + "rememberme": "Beni hatırla", + "invalid": "GeƧersiz kullanıcı adı veya şifre.", + "locked": "Hesabınız kilitlendi.", + "signinTitle": "Lütfen giriş yapınız.", + "ssoSignIn": "Tek Oturum AƧma ile Giriş Yap", + "oAuth2AutoCreateDisabled": "OAUTH2 Otomatik Oluşturma Kullanıcı Devre Dışı Bırakıldı", + "oAuth2AdminBlockedUser": "Kayıtlı olmayan kullanıcıların kayıt veya giriş yapması şu anda engellenmiştir. Lütfen yƶneticiyle iletişime geƧin.", + "oauth2RequestNotFound": "Yetkilendirme isteği bulunamadı", + "oauth2InvalidUserInfoResponse": "GeƧersiz Kullanıcı Bilgisi Yanıtı", + "oauth2invalidRequest": "GeƧersiz İstek", + "oauth2AccessDenied": "Erişim Reddedildi", + "oauth2InvalidTokenResponse": "GeƧersiz BelirteƧ Yanıtı", + "oauth2InvalidIdToken": "GeƧersiz Kimlik Belirteci", + "relyingPartyRegistrationNotFound": "Bağlı taraf kaydı bulunamadı", + "userIsDisabled": "Kullanıcı devre dışı bırakıldı, şu anda bu kullanıcı adıyla giriş engellendi. Lütfen yƶneticiyle iletişime geƧin.", + "alreadyLoggedIn": "Zaten şu cihazlarda oturum aƧılmış:", + "alreadyLoggedIn2": "Lütfen bu cihazlardan Ƨıkış yaparak tekrar deneyin.", + "toManySessions": "Ƈok fazla aktif oturumunuz var", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF'i Tek Sayfaya", + "header": "PDF'i Tek Sayfaya", + "submit": "Tek Sayfaya Dƶnüştür" + }, + "pageExtracter": { + "title": "Sayfaları Ƈıkar", + "header": "Sayfaları Ƈıkar", + "submit": "Ƈıkar", + "placeholder": "(ƶrneğin 1,2,8 veya 4,7,12-16 ya da 2n-1)" + }, + "sanitizePDF": { + "title": "PDF'i Temizle", + "header": "PDF dosyasını temizle", + "selectText": { + "1": "JavaScript işlemlerini kaldır", + "2": "Gƶmülü dosyaları kaldır", + "3": "XMP meta verisini kaldır", + "4": "Linkleri kaldır", + "5": "Fontları kaldır", + "6": "Belge Bilgisi Meta Verisini Kaldır" + }, + "submit": "PDF'i Temizle" + }, + "adjustContrast": { + "title": "Kontrastı Ayarla", + "header": "Kontrastı Ayarla", + "contrast": "Kontrast:", + "brightness": "Parlaklık:", + "saturation": "Doygunluk:", + "download": "İndir" + }, + "compress": { + "title": "Sıkıştır", + "header": "PDF'i Sıkıştır", + "credit": "Bu hizmet PDF Sıkıştırma/Optimizasyonu iƧin qpdf kullanır.", + "grayscale": { + "label": "Sıkıştırma iƧin Gri Ton Uygula" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Optimizasyon seviyesi:", + "4": "Otomatik mod - PDF'in tam boyutuna ulaşmak iƧin kaliteyi otomatik ayarlar", + "5": "Beklenen PDF Boyutu (ƶrn. 25MB, 10.8MB, 25KB)" + }, + "submit": "Sıkıştır" + }, + "decrypt": { + "passwordPrompt": "Bu dosya parola korumalı. Lütfen parolayı girin:", + "cancelled": "PDF iƧin işlem iptal edildi: {0}", + "noPassword": "Şifrelenmiş PDF iƧin parola girilmedi: {0}", + "invalidPassword": "Lütfen doğru parolayla tekrar deneyin.", + "invalidPasswordHeader": "PDF iƧin yanlış parola veya desteklenmeyen şifreleme: {0}", + "unexpectedError": "Dosya işlenirken bir hata oluştu. Lütfen tekrar deneyin.", + "serverError": "Şifre Ƨƶzme sırasında sunucu hatası: {0}", + "success": "Dosyanın şifresi başarıyla Ƨƶzüldü." + }, + "multiTool-advert": { + "message": "Bu ƶzellik Ƨoklu araƧlar sayfamızda da mevcuttur. Sayfa sayfa gelişmiş arayüz ve ek ƶzellikler iƧin gƶz atın!" + }, + "pageRemover": { + "title": "Sayfa Silici", + "header": "PDF Sayfa silici", + "pagesToDelete": "Silinmesi gereken sayfalar (Virgülle ayrılmış sayfa numaraları listesi girin):", + "submit": "Sayfaları Sil", + "placeholder": "(ƶrn. 1,2,6 veya 1-10,15-30)" + }, + "imageToPDF": { + "title": "Resimden PDF'e", + "header": "Resimden PDF'e", + "submit": "Dƶnüştür", + "selectLabel": "Resim Uydurma SeƧenekleri", + "fillPage": "Sayfayı Doldur", + "fitDocumentToImage": "Resme Uygun Sayfa", + "maintainAspectRatio": "En Boy Oranını Koru", + "selectText": { + "2": "PDF'yi otomatik dƶndür", + "3": "Ƈoklu dosya mantığı (Yalnızca birden fazla resimle Ƨalışırken etkinleştirilir)", + "4": "Tek bir PDF'e birleştir", + "5": "Ayrı PDF'lere dƶnüştür" + } + }, + "PDFToCSV": { + "title": "PDF'den CSV'ye", + "header": "PDF'den CSV'ye", + "prompt": "Tabloyu Ƨıkarmak iƧin sayfa seƧin", + "submit": "Ƈıkart" + }, + "split-by-size-or-count": { + "title": "PDF'yi Boyuta veya Sayıya Gƶre Bƶlme", + "header": "PDF'yi Boyuta veya Sayıya Gƶre Bƶlme", + "type": { + "label": "Bƶlme Türünü SeƧin", + "size": "Boyuta Gƶre", + "pageCount": "Sayfa Sayısına Gƶre", + "docCount": "Belge Sayısına Gƶre" + }, + "value": { + "label": "Değer Girin", + "placeholder": "Boyutu (ƶrn. 2MB veya 3KB) veya sayıyı (ƶrn. 5) girin" + }, + "submit": "Gƶnder" + }, + "printFile": { + "title": "Dosya Yazdır", + "header": "Dosyayı Yazıcıya Yazdır", + "selectText": { + "1": "Yazdırılacak Dosyayı SeƧin", + "2": "Yazıcı Adını Girin" + }, + "submit": "Yazdır" + }, + "licenses": { + "nav": "Lisanslar", + "title": "3. Taraf Lisansları", + "header": "3. Taraf Lisansları", + "module": "Modül", + "version": "Sürüm", + "license": "Lisans" + }, + "survey": { + "nav": "Anket", + "title": "Stirling-PDF Anketi", + "description": "Stirling-PDF'te izleme yok, bu yüzden Stirling-PDF'i iyileştirmek iƧin kullanıcılarımızdan geri bildirim almak istiyoruz!", + "changes": "Stirling-PDF son ankete gƶre değişti! Daha fazla bilgi iƧin blog yazımıza gƶz atın:", + "changes2": "Bu değişikliklerle birlikte ücretli kurumsal destek ve fon alıyoruz", + "please": "Lütfen anketimize katılmayı düşünün!", + "disabled": "(Anket aƧılır penceresi sonraki güncellemelerde devre dışı bırakılacak ancak sayfanın alt kısmında yer alacaktır)", + "button": "Ankete Katıl", + "dontShowAgain": "Tekrar gƶsterme", + "meeting": { + "1": "Eğer Stirling PDF'i iş yerinizde kullanıyorsanız, sizinle gƶrüşmek isteriz. 15 dakikalık bir kullanıcı keşif oturumu karşılığında teknik destek sunuyoruz.", + "2": "Bu fırsat sayesinde:", + "3": "Kurulum, entegrasyonlar veya sorun giderme konularında yardım alabilirsiniz", + "4": "Performans, uƧ durumlar ve eksik ƶzellikler hakkında doğrudan geri bildirim sağlayabilirsiniz", + "5": "Stirling PDF’i gerƧek dünya kurumsal kullanımı iƧin daha iyi hale getirmemize yardımcı olabilirsiniz", + "6": "İlgileniyorsanız, ekibimizden doğrudan zaman ayırabilirsiniz. (Yalnızca İngilizce)", + "7": "Kullanım senaryolarınızı dinlemeyi ve Stirling PDF’i daha da iyi hale getirmeyi sabırsızlıkla bekliyoruz!", + "notInterested": "Kurumsal kullanıcı değilseniz ve/veya gƶrüşmeye ilgi duymuyorsanız", + "button": "Gƶrüşme Planla" + } + }, + "removeImage": { + "title": "Resmi kaldır", + "header": "Resmi kaldır", + "removeImage": "Resmi kaldır", + "submit": "Resmi kaldır" + }, + "splitByChapters": { + "title": "PDF'yi Bƶlümlere Ayır", + "header": "PDF'yi Bƶlümlere Ayır", + "bookmarkLevel": "Yer imi Seviyesi", + "includeMetadata": "Meta Veriyi Dahil Et", + "allowDuplicates": "Yinelenen Yer İmlerine İzin Ver", + "desc": { + "1": "Bu araƧ, bir PDF dosyasını bƶlüm yapısına gƶre birden fazla PDF'ye bƶler.", + "2": "Bƶlme iƧin kullanılacak yer imi seviyesini seƧin (0 en üst seviye, 1 ikinci seviye vb.).", + "3": "Meta Veriyi Dahil Et: İşaretlenirse, orijinal PDF'nin meta verisi her bir bƶlünmüş PDF'ye dahil edilir.", + "4": "Yinelenen Yer İmlerine İzin Ver: İşaretlenirse, aynı sayfadaki birden fazla yer imi ayrı PDF'ler oluşturabilir." + }, + "submit": "PDF'yi Ayır" + }, + "fileChooser": { + "click": "SeƧ", + "or": "veya", + "dragAndDrop": "Sürükle & Bırak", + "dragAndDropPDF": "PDF dosyasını Sürükle & Bırak", + "dragAndDropImage": "Gƶrsel dosyasını Sürükle & Bırak", + "hoveredDragAndDrop": "Dosya(lar)ı buraya sürükleyip bırakın", + "extractPDF": "PDF Ƈıkarılıyor..." + }, + "releases": { + "footer": "Sürümler", + "title": "Sürüm Notları", + "header": "Sürüm Notları", + "current": { + "version": "Mevcut Sürüm" + }, + "note": "Sürüm notları yalnızca İngilizce dilinde mevcuttur" + }, + "cookieBanner": { + "popUp": { + "title": "Ƈerezleri Nasıl Kullanıyoruz", + "description": { + "1": "Stirling PDF’yi sizin iƧin daha iyi Ƨalıştırmak iƧin Ƨerezler ve diğer teknolojileri kullanıyoruz — araƧlarımızı geliştirmemize ve seveceğiniz ƶzellikler oluşturmamıza yardımcı oluyorlar.", + "2": "İstemiyorsanız, ā€˜Hayır Teşekkürler’ butonuna tıklayarak yalnızca temel, gerekli Ƨerezleri etkinleştirebilirsiniz." + }, + "acceptAllBtn": "Tamam", + "acceptNecessaryBtn": "Hayır Teşekkürler", + "showPreferencesBtn": "Tercihleri Yƶnet" + }, + "preferencesModal": { + "title": "Onay Tercih Merkezi", + "acceptAllBtn": "Tümünü Kabul Et", + "acceptNecessaryBtn": "Tümünü Reddet", + "savePreferencesBtn": "Tercihleri Kaydet", + "closeIconLabel": "Kapat", + "serviceCounterLabel": "Hizmet|Hizmetler", + "subtitle": "Ƈerez Kullanımı", + "description": { + "1": "Stirling PDF, deneyiminizi geliştirmek ve araƧlarımızın nasıl kullanıldığını anlamak iƧin Ƨerezler ve benzeri teknolojiler kullanır. Bu, performansı iyileştirmemize, ƶnemsediğiniz ƶzellikleri geliştirmemize ve kullanıcılarımıza sürekli destek sağlamamıza yardımcı olur.", + "2": "Stirling PDF, kullandığınız belgelerin iƧeriğini asla takip edemez veya erişemez.", + "3": "Gizliliğiniz ve güveniniz bizim iƧin en ƶnemli şeydir." + }, + "necessary": { + "title": { + "1": "Kesinlikle Gerekli Ƈerezler", + "2": "Her Zaman Etkin" + }, + "description": "Bu Ƨerezler, web sitesinin düzgün Ƨalışabilmesi iƧin gereklidir. Gizlilik tercihlerinizi ayarlama, giriş yapma ve form doldurma gibi temel işlevleri mümkün kılarlar — bu nedenle devre dışı bırakılamazlar." + }, + "analytics": { + "title": "Analitik", + "description": "Bu Ƨerezler, araƧlarımızın nasıl kullanıldığını anlamamıza yardımcı olur, bƶylece topluluğumuzun en Ƨok değer verdiği ƶzellikleri geliştirmeye odaklanabiliriz. İƧiniz rahat olsun — Stirling PDF, belgelerinizin iƧeriğini asla takip etmez ve etmeyecektir." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/uk-UA/translation.json b/frontend/public/locales/uk-UA/translation.json new file mode 100644 index 000000000..d87033abf --- /dev/null +++ b/frontend/public/locales/uk-UA/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Розмір ŃˆŃ€ŠøŃ„Ń‚Ńƒ", + "fontName": "ŠŠ°Š·Š²Š° ŃˆŃ€ŠøŃ„Ń‚Ńƒ", + "title": "ДоГати номери сторінок", + "header": "ДоГати номери сторінок", + "selectText": { + "1": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ PDF-файл:", + "2": "Розмір ŠæŠ¾Š»Ń", + "3": "ŠŸŠ¾Š·ŠøŃ†Ń–Ń", + "4": "Дтартовий номер", + "5": "Дторінки Š“Š»Ń Š½ŃƒŠ¼ŠµŃ€Š°Ń†Ń–Ń—", + "6": "Двій текст" + }, + "customTextDesc": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń†ŃŒŠŗŠøŠ¹ текст", + "numberPagesDesc": "ŠÆŠŗŃ– сторінки Š½ŃƒŠ¼ŠµŃ€ŃƒŠ²Š°Ń‚Šø, за Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼ 'всі', також приймає 1-5 або 2,5,9 тощо.", + "customNumberDesc": "За Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼ {n}, також можна Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚Šø 'Дторінка {n} Š· {total}', 'Текст-{n}', '{filename}-{n}'", + "submit": "ДоГати номери сторінок" + }, + "pdfPrompt": "ŠžŠ±ŠµŃ€Ń–Ń‚ŃŒ PDF(Šø)", + "multiPdfPrompt": "ŠžŠ±ŠµŃ€Ń–Ń‚ŃŒ PDFŠø (2+)", + "multiPdfDropPrompt": "ŠžŠ±ŠµŃ€Ń–Ń‚ŃŒ (або ŠæŠµŃ€ŠµŃ‚ŃŠ³Š½Ń–Ń‚ŃŒ) всі необхіГні PDFŠø", + "imgPrompt": "ŠžŠ±ŠµŃ€Ń–Ń‚ŃŒ Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń(я)", + "genericSubmit": "ŠŠ°Š“Ń–ŃŠ»Š°Ń‚Šø", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Увага: Цей процес може тривати Го хвилини в залежності віГ Ń€Š¾Š·Š¼Ń–Ń€Ńƒ Ń„Š°Š¹Š»Ńƒ.", + "pageOrderPrompt": "ŠŸŠ¾Ń€ŃŠ“Š¾Šŗ сторінок (Š²Š²ŠµŠ“Ń–Ń‚ŃŒ список номерів сторінок через кому):", + "pageSelectionPrompt": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń†ŃŒŠŗŠøŠ¹ вибір сторінки (Š²Š²ŠµŠ“Ń–Ń‚ŃŒ список номерів сторінок через кому 1,5,6 або Ń„ŃƒŠ½ŠŗŃ†Ń–Ń— Ń‚ŠøŠæŃƒ 2n+1) :", + "goToPage": "ВпереГ", + "true": "ŠŸŃ€Š°Š²Š“Š°", + "false": "Š‘Ń€ŠµŃ…Š½Ń", + "unknown": "ŠŠµŠ²Ń–Š“Š¾Š¼Š¾", + "save": "Зберегти", + "saveToBrowser": "Зберегти в Š±Ń€Š°ŃƒŠ·ŠµŃ€Ń–", + "close": "Закрити", + "filesSelected": "файлів обрано", + "noFavourites": "ŠŠµŠ¼Š°Ń” вибраного", + "downloadComplete": "Š—Š°Š²Š°Š½Ń‚Š°Š¶ŠµŠ½Š½Ń Š·Š°Š²ŠµŃ€ŃˆŠµŠ½Š¾", + "bored": "ŠŃƒŠ“Š½Š¾ чекати?", + "alphabet": "Алфавіт", + "downloadPdf": "Завантажити PDF", + "text": "Текст", + "font": "Шрифт", + "selectFillter": "-- Вибрати --", + "pageNum": "номер сторінки", + "sizes": { + "small": "Малий", + "medium": "ДереГній", + "large": "Великий", + "x-large": "Š”ŃƒŠ¶Šµ великий" + }, + "error": { + "pdfPassword": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ PDF захищено паролем, і ŠæŠ°Ń€Š¾Š»ŃŒ не був наГаний або був невірним", + "_value": "Помилка", + "sorry": "Вибачте за Š½ŠµŠ·Ń€ŃƒŃ‡Š½Š¾ŃŃ‚Ń–!", + "needHelp": "ŠŸŠ¾Ń‚Ń€Ń–Š±Š½Š° Гопомога / Š—Š½Š°Š¹ŃˆŠ»Šø ŠæŃ€Š¾Š±Š»ŠµŠ¼Ńƒ?", + "contactTip": "Якщо у вас Госі Š²ŠøŠ½ŠøŠŗŠ°ŃŽŃ‚ŃŒ проблеми, не ŃŠ¾Ń€Š¾Š¼Ń‚ŠµŃŃ Š·Š²ŠµŃ€Ń‚Š°Ń‚ŠøŃŃ Го нас за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ. Š’Šø можете наГіслати запит на Š½Š°ŃˆŃ–й сторінці GitHub або зв'ŃŠ·Š°Ń‚ŠøŃŃ Š· нами через Discord:", + "404": { + "head": "404 - Š”Ń‚Š¾Ń€Ń–Š½ŠŗŃƒ не знайГено | ŠžŠ¹, ми Š·Š°ŠæŠ»ŃƒŃ‚Š°Š»ŠøŃŃ в коГі!", + "1": "Ми не можемо знайти ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ, ŃŠŗŃƒ ви ŃˆŃƒŠŗŠ°Ń”Ń‚Šµ.", + "2": "Щось ŠæŃ–ŃˆŠ»Š¾ не так" + }, + "github": "ŠŠ°Š“Ń–ŃŠ»Š°Ń‚Šø запит на GitHub", + "showStack": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø стек викликів", + "copyStack": "Š”ŠŗŠ¾ŠæŃ–ŃŽŠ²Š°Ń‚Šø стек викликів", + "githubSubmit": "GitHub - ŠŠ°Š“Ń–ŃŠ»Š°Ń‚Šø запит", + "discordSubmit": "Discord - ŠŠ°Š“Ń–ŃŠ»Š°Ń‚Šø ŠæŠ¾Š²Ń–Š“Š¾Š¼Š»ŠµŠ½Š½Ń піГтримки" + }, + "delete": "ВиГалити", + "username": "Ім'я ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°", + "password": "ŠŸŠ°Ń€Š¾Š»ŃŒ", + "welcome": "Ласкаво просимо", + "property": "Š’Š»Š°ŃŃ‚ŠøŠ²Ń–ŃŃ‚ŃŒ", + "black": "Чорний", + "white": "Білий", + "red": "Червоний", + "green": "Зелений", + "blue": "Диній", + "custom": "Звичай...", + "WorkInProgess": "Робота триває, може не ŠæŃ€Š°Ń†ŃŽŠ²Š°Ń‚Šø або Š³Š»ŃŽŃ‡ŠøŃ‚Šø, буГь ласка, ŠæŠ¾Š²Ń–Š“Š¾Š¼Š»ŃŠ¹Ń‚Šµ про буГь-ŃŠŗŃ– проблеми!", + "poweredBy": "ŠŸŃ€Š°Ń†ŃŽŃ” на", + "yes": "Так", + "no": "ŠŃ–", + "changedCredsMessage": "ŠžŠ±Š»Ń–ŠŗŠ¾Š²Ń– Гані змінено!", + "notAuthenticatedMessage": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ не ŠæŃ€Š¾Š¹ŃˆŠ¾Š² ŠæŠµŃ€ŠµŠ²Ń–Ń€ŠŗŃƒ автентичності.", + "userNotFoundMessage": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° не знайГено.", + "incorrectPasswordMessage": "ŠŸŠ¾Ń‚Š¾Ń‡Š½ŠøŠ¹ ŠæŠ°Ń€Š¾Š»ŃŒ невірний.", + "usernameExistsMessage": "ŠŠ¾Š²Šµ ім'я ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° вже Ń–ŃŠ½ŃƒŃ”.", + "invalidUsernameMessage": "ŠŠµŠ“Ń–Š¹ŃŠ½Šµ Ń–Š¼ā€™Ń ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°, Ń–Š¼ā€™Ń ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° може містити лише літери, цифри та Š½Š°ŃŃ‚ŃƒŠæŠ½Ń– ŃŠæŠµŃ†Ń–Š°Š»ŃŒŠ½Ń– символи @._+- або має Š±ŃƒŃ‚Šø Š“Ń–Š¹ŃŠ½Š¾ŃŽ ŠµŠ»ŠµŠŗŃ‚Ń€Š¾Š½Š½Š¾ŃŽ Š°Š“Ń€ŠµŃŠ¾ŃŽ.", + "invalidPasswordMessage": "ŠŸŠ°Ń€Š¾Š»ŃŒ не повинен Š±ŃƒŃ‚Šø порожнім і не повинен мати пробілів на ŠæŠ¾Ń‡Š°Ń‚ŠŗŃƒ або в кінці.", + "confirmPasswordErrorMessage": "ŠŠ¾Š²ŠøŠ¹ ŠæŠ°Ń€Š¾Š»ŃŒ і ŠæŃ–Š“Ń‚Š²ŠµŃ€Š“Š¶ŠµŠ½Š½Ń нового ŠæŠ°Ń€Š¾Š»Ń Š¼Š°ŃŽŃ‚ŃŒ Š·Š±Ń–Š³Š°Ń‚ŠøŃŃ.", + "deleteCurrentUserMessage": "ŠŠµŠ¼Š¾Š¶Š»ŠøŠ²Š¾ виГалити ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°, ŃŠŗŠøŠ¹ ŃƒŠ²Ń–Š¹ŃˆŠ¾Š² в ŃŠøŃŃ‚ŠµŠ¼Ńƒ.", + "deleteUsernameExistsMessage": "Ім'я ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° не Ń–ŃŠ½ŃƒŃ” і не може Š±ŃƒŃ‚Šø виГалено.", + "downgradeCurrentUserMessage": "ŠŠµŠ¼Š¾Š¶Š»ŠøŠ²Š¾ понизити Ń€Š¾Š»ŃŒ поточного ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°", + "disabledCurrentUserMessage": "ŠŸŠ¾Ń‚Š¾Ń‡Š½Š¾Š³Š¾ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° неможливо Š²ŠøŠ¼ŠŗŠ½ŃƒŃ‚Šø", + "downgradeCurrentUserLongMessage": "ŠŠµŠ¼Š¾Š¶Š»ŠøŠ²Š¾ понизити Ń€Š¾Š»ŃŒ поточного ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°. ŠžŃ‚Š¶Šµ, поточний ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ не Š²Ń–Š“Š¾Š±Ń€Š°Š¶Š°Ń‚ŠøŠ¼ŠµŃ‚ŃŒŃŃ.", + "userAlreadyExistsOAuthMessage": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ уже Ń–ŃŠ½ŃƒŃ” ŃŠŗ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ OAuth2.", + "userAlreadyExistsWebMessage": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ уже Ń–ŃŠ½ŃƒŃ” ŃŠŗ веб-ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡.", + "oops": "Упс!", + "help": "Допомога", + "goHomepage": "До головної сторінки", + "joinDiscord": "ŠŸŃ€ŠøŃ”Š“Š½ŃƒŠ¹Ń‚ŠµŃŃŒ Го нашого Discord ŃŠµŃ€Š²ŠµŃ€Ńƒ", + "seeDockerHub": "ŠŸŠµŃ€ŠµŠ³Š»ŃŠ½ŃƒŃ‚Šø Docker Hub", + "visitGithub": "ŠŸŠµŃ€ŠµŠ³Š»ŃŠ½ŃƒŃ‚Šø Github репозиторій", + "donate": "ЗаГонатити", + "color": "ŠšŠ¾Š»Ń–Ń€", + "sponsor": "Дпонсор", + "info": "Š†Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–Ń", + "pro": "Pro", + "page": "Дторінка", + "pages": "Дторінки", + "loading": "Š—Š°Š²Š°Š½Ń‚Š°Š¶ŠµŠ½Š½Ń...", + "addToDoc": "ДоГати Го Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ńƒ", + "reset": "Š”ŠŗŠøŠ½ŃƒŃ‚Šø", + "apply": "Š—Š°ŃŃ‚Š¾ŃŃƒŠ²Š°Ń‚Šø", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "ŠŸŠ¾Š»Ń–Ń‚ŠøŠŗŠ° конфіГенційності", + "terms": "ŠŸŃ€Š°Š²ŠøŠ»Š° та умови", + "accessibility": "Š”Š¾ŃŃ‚ŃƒŠæŠ½Ń–ŃŃ‚ŃŒ", + "cookie": "ŠŸŠ¾Š»Ń–Ń‚ŠøŠŗŠ° Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń файлів cookie", + "impressum": "ВихіГні Гані", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "ŠœŠµŠ½ŃŽ конвеєрної обробки (Бета)", + "uploadButton": "Завантажити ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń†ŃŒŠŗŠøŠ¹", + "configureButton": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń", + "defaultOption": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń†ŃŒŠŗŠøŠ¹", + "submitButton": "ŠŠ°Š“Ń–ŃŠ»Š°Ń‚Šø", + "help": "ДовіГка Š· конвеєрної обробки", + "scanHelp": "ДовіГка Š·Ń– ŃŠŗŠ°Š½ŃƒŠ²Š°Š½Š½Ń папок", + "deletePrompt": "Š’Šø впевнені, що хочете виГалити конвеєр?", + "tags": "Š°Š²Ń‚Š¾Š¼Š°Ń‚ŠøŠ·Š°Ń†Ń–Ń,ŠæŠ¾ŃŠ»Ń–Š“Š¾Š²Š½Ń–ŃŃ‚ŃŒ,сценарій,scripted,batch-process", + "title": "Пайплайн" + }, + "pipelineOptions": { + "header": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń конвеєрної обробки", + "pipelineNameLabel": "ŠŠ°Š·Š²Š° конвеєра", + "saveSettings": "Зберегти Š½Š°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń операції", + "pipelineNamePrompt": "Š’Š²ŠµŠ“Ń–Ń‚ŃŒ назву конвеєра тут", + "selectOperation": "Вибрати Š¾ŠæŠµŃ€Š°Ń†Ń–ŃŽ", + "addOperationButton": "ДоГати Š¾ŠæŠµŃ€Š°Ń†Ń–ŃŽ", + "pipelineHeader": "ŠšŠ¾Š½Š²ŠµŃ”Ń€:", + "saveButton": "Завантажити", + "validateButton": "ŠŸŠµŃ€ŠµŠ²Ń–Ń€ŠøŃ‚Šø" + }, + "enterpriseEdition": { + "button": "ŠžŠ½Š¾Š²Š»ŠµŠ½Š½Ń Го Pro", + "warning": "Š¦Ń Ń„ŃƒŠ½ŠŗŃ†Ń–Ń Š“Š¾ŃŃ‚ŃƒŠæŠ½Š° лише Š“Š»Ń ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š² Pro.", + "yamlAdvert": "Stirling PDF Pro ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŃ” ŠŗŠ¾Š½Ń„Ń–Š³ŃƒŃ€Š°Ń†Ń–Š¹Š½Ń– файли YAML та Ń–Š½ŃˆŃ– Ń„ŃƒŠ½ŠŗŃ†Ń–Ń— SSO.", + "ssoAdvert": "ŠØŃƒŠŗŠ°Ń”Ń‚Šµ Š±Ń–Š»ŃŒŃˆŠµ Ń„ŃƒŠ½ŠŗŃ†Ń–Š¹ ŠŗŠµŃ€ŃƒŠ²Š°Š½Š½Ń ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°Š¼Šø? ŠŸŠµŃ€ŠµŠ³Š»ŃŠ½ŃŒŃ‚Šµ Stirling PDF Pro" + }, + "analytics": { + "title": "Бажаєте покращити Stirling PDF?", + "paragraph1": "Stirling PDF ŃƒŠ²Ń–Š¼ŠŗŠ½ŃƒŠ² Š°Š½Š°Š»Ń–Ń‚ŠøŠŗŃƒ, щоб Гопомогти нам покращити ŠæŃ€Š¾Š“ŃƒŠŗŃ‚. Ми не Š²Ń–Š“ŃŃ‚ŠµŠ¶ŃƒŃ”Š¼Š¾ жоГну Š¾ŃŠ¾Š±ŠøŃŃ‚Ńƒ Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–ŃŽ чи вміст файлів.", + "paragraph2": "Š£Š²Ń–Š¼ŠŗŠ½Ń–Ń‚ŃŒ Š°Š½Š°Š»Ń–Ń‚ŠøŠŗŃƒ, щоб Гопомогти Stirling-PDF Ń€Š¾Š·Š²ŠøŠ²Š°Ń‚ŠøŃŃ та Гозволити нам краще Ń€Š¾Š·ŃƒŠ¼Ń–Ń‚Šø Š½Š°ŃˆŠøŃ… ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š².", + "enable": "Š£Š²Ń–Š¼ŠŗŠ½ŃƒŃ‚Šø Š°Š½Š°Š»Ń–Ń‚ŠøŠŗŃƒ", + "disable": "Š’ŠøŠ¼ŠŗŠ½ŃƒŃ‚Šø Š°Š½Š°Š»Ń–Ń‚ŠøŠŗŃƒ", + "settings": "Š’Šø можете змінити параметри аналітики у файлі config/settings.yml" + }, + "navbar": { + "favorite": "ŠžŠ±Ń€Š°Š½Šµ", + "recent": "ŠŠ¾Š²ŠøŠ¹ і нещоГавно оновлений", + "darkmode": "Темний режим", + "language": "Мови", + "settings": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń", + "allTools": "Š†Š½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚Šø", + "multiTool": "ŠœŃƒŠ»ŃŒŃ‚Ń–Ń–Š½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚", + "search": "Пошук", + "sections": { + "organize": "ŠžŃ€Š³Š°Š½Ń–Š·ŃƒŠ²Š°Ń‚Šø", + "convertTo": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø в PDF", + "convertFrom": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø Š· PDF", + "security": "ŠŸŃ–Š“ŠæŠøŃ та Безпека", + "advance": "ДоГаткове", + "edit": "ŠŸŠµŃ€ŠµŠ³Š»ŃŠ“ та Š ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń", + "popular": "ŠŸŠ¾ŠæŃƒŠ»ŃŃ€Š½Šµ" + } + }, + "settings": { + "title": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń", + "update": "Š”Š¾ŃŃ‚ŃƒŠæŠ½Šµ Š¾Š½Š¾Š²Š»ŠµŠ½Š½Ń", + "updateAvailable": "Зараз встановлена Š²ŠµŃ€ŃŃ–я {0}. ŠŠ¾Š²Š° Š²ŠµŃ€ŃŃ–Ń ({1}) Š“Š¾ŃŃ‚ŃƒŠæŠ½Š°.", + "appVersion": "Š’ŠµŃ€ŃŃ–Ń Š“Š¾Š“Š°Ń‚ŠŗŃƒ:", + "downloadOption": { + "title": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ варіант Š·Š°Š²Š°Š½Ń‚Š°Š¶ŠµŠ½Š½Ń (Š“Š»Ń Š·Š°Š²Š°Š½Ń‚Š°Š¶ŠµŠ½Š½Ń оГного Ń„Š°Š¹Š»Ńƒ без zip):", + "1": "ВіГкрити в Ń‚Š¾Š¼Ńƒ ж вікні", + "2": "ВіГкрити в новому вікні", + "3": "Завантажити файл" + }, + "zipThreshold": "Zip-файли, коли ŠŗŃ–Š»ŃŒŠŗŃ–ŃŃ‚ŃŒ завантажених файлів ŠæŠµŃ€ŠµŠ²ŠøŃ‰ŃƒŃ”", + "signOut": "Вийти", + "accountSettings": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń Š°ŠŗŠ°ŃƒŠ½Ń‚Š°", + "bored": { + "help": "Вмикає Š³Ń€Ńƒ Ā«ŠæŠ°ŃŃ…Š°Š»ŃŒŠ½Šµ ŃŠ¹Ń†ŠµĀ»." + }, + "cacheInputs": { + "name": "Зберігати Гані форм", + "help": "Š£Š²Ń–Š¼ŠŗŠ½ŃƒŃ‚Šø Š“Š»Ń Š·Š±ŠµŃ€ŠµŠ¶ŠµŠ½Š½Ń Ń€Š°Š½Ń–ŃˆŠµ використаних вхіГних Ганих Š“Š»Ń Š¼Š°Š¹Š±ŃƒŃ‚Š½Ń–Ń… прогонів" + } + }, + "changeCreds": { + "title": "Змінити облікові Гані", + "header": "ŠžŠ½Š¾Š²Ń–Ń‚ŃŒ Гані вашого облікового запису", + "changePassword": "Š’Šø Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ”Ń‚Šµ Š·Š°Š²Š¾Š“ŃŃŒŠŗŃ– облікові Гані Š“Š»Ń Š²Ń…Š¾Š“Ńƒ. Š‘ŃƒŠ“ŃŒ ласка, Š²Š²ŠµŠ“Ń–Ń‚ŃŒ новий ŠæŠ°Ń€Š¾Š»ŃŒ", + "newUsername": "ŠŠ¾Š²Šµ ім'я ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°", + "oldPassword": "ŠŸŠ¾Ń‚Š¾Ń‡Š½ŠøŠ¹ ŠæŠ°Ń€Š¾Š»ŃŒ", + "newPassword": "ŠŠ¾Š²ŠøŠ¹ ŠæŠ°Ń€Š¾Š»ŃŒ", + "confirmNewPassword": "ŠŸŃ–Š“Ń‚Š²ŠµŃ€Š“Ń–Ń‚ŃŒ новий ŠæŠ°Ń€Š¾Š»ŃŒ", + "submit": "ŠŠ°Š“Ń–ŃŠ»Š°Ń‚Šø зміни" + }, + "account": { + "title": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń Š°ŠŗŠ°ŃƒŠ½Ń‚Š°", + "accountSettings": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń Š°ŠŗŠ°ŃƒŠ½Ń‚Š°", + "adminSettings": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń аГміністратора - ŠŸŠµŃ€ŠµŠ³Š»ŃŠ“ і Š“Š¾Š“Š°Š²Š°Š½Š½Ń ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š²", + "userControlSettings": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń ŠŗŠ¾Š½Ń‚Ń€Š¾Š»ŃŽ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°", + "changeUsername": "Змінити ім'я ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°", + "newUsername": "ŠŠ¾Š²Šµ ім'я ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°", + "password": "ŠŸŃ–Š“Ń‚Š²ŠµŃ€Š“Š¶ŠµŠ½Š½Ń ŠæŠ°Ń€Š¾Š»Ń", + "oldPassword": "Дтарий ŠæŠ°Ń€Š¾Š»ŃŒ", + "newPassword": "ŠŠ¾Š²ŠøŠ¹ ŠæŠ°Ń€Š¾Š»ŃŒ", + "changePassword": "Змінити ŠæŠ°Ń€Š¾Š»ŃŒ", + "confirmNewPassword": "ŠŸŃ–Š“Ń‚Š²ŠµŃ€Š“Ń–Ń‚ŃŒ новий ŠæŠ°Ń€Š¾Š»ŃŒ", + "signOut": "Вийти", + "yourApiKey": "Š’Š°Ńˆ API-ŠŗŠ»ŃŽŃ‡", + "syncTitle": "Š”ŠøŠ½Ń…Ń€Š¾Š½Ń–Š·ŃƒŠ²Š°Ń‚Šø Š½Š°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń Š±Ń€Š°ŃƒŠ·ŠµŃ€Š° Š· обліковим записом", + "settingsCompare": "ŠŸŠ¾Ń€Ń–Š²Š½ŃŠ½Š½Ń Š½Š°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½ŃŒ:", + "property": "Š’Š»Š°ŃŃ‚ŠøŠ²Ń–ŃŃ‚ŃŒ", + "webBrowserSettings": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń веб-Š±Ń€Š°ŃƒŠ·ŠµŃ€Š°", + "syncToBrowser": "Š”ŠøŠ½Ń…Ń€Š¾Š½Ń–Š·ŃƒŠ²Š°Ń‚Šø обліковий запис -> Š‘Ń€Š°ŃƒŠ·ŠµŃ€", + "syncToAccount": "Š”ŠøŠ½Ń…Ń€Š¾Š½Ń–Š·ŃƒŠ²Š°Ń‚Šø обліковий запис <- Š‘Ń€Š°ŃƒŠ·ŠµŃ€" + }, + "adminUserSettings": { + "title": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń ŠŗŠ¾Š½Ń‚Ń€Š¾Š»ŃŽ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°", + "header": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń ŠŗŠ¾Š½Ń‚Ń€Š¾Š»ŃŽ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° аГміністратора", + "admin": "АГміністратор", + "user": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡", + "addUser": "ДоГати нового ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°", + "deleteUser": "ВиГалити ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°", + "confirmDeleteUser": "ВиГалити Ń†ŃŒŠ¾Š³Š¾ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°?", + "confirmChangeUserStatus": "Чи потрібно Š²ŠøŠ¼ŠŗŠ½ŃƒŃ‚Šø/Š²Š²Ń–Š¼ŠŗŠ½ŃƒŃ‚Šø ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°?", + "usernameInfo": "Š†Š¼ā€™Ń ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° може містити лише літери, цифри та Š½Š°ŃŃ‚ŃƒŠæŠ½Ń– ŃŠæŠµŃ†Ń–Š°Š»ŃŒŠ½Ń– символи @._+- або має Š±ŃƒŃ‚Šø Š“Ń–Š¹ŃŠ½Š¾ŃŽ ŠµŠ»ŠµŠŗŃ‚Ń€Š¾Š½Š½Š¾ŃŽ Š°Š“Ń€ŠµŃŠ¾ŃŽ.", + "roles": "Ролі", + "role": "Роль", + "actions": "Дії", + "apiUser": "ŠžŠ±Š¼ŠµŠ¶ŠµŠ½ŠøŠ¹ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ API", + "extraApiUser": "ДоГатковий обмежений ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ API", + "webOnlyUser": "Š¢Ń–Š»ŃŒŠŗŠø веб-ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡", + "demoUser": "Демо-ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ (без Š½Š°Š»Š°ŃˆŃ‚ованих параметрів)", + "internalApiUser": "Š’Š½ŃƒŃ‚Ń€Ń–ŃˆŠ½Ń–Š¹ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ API", + "forceChange": "ŠŸŃ€ŠøŠ¼ŃƒŃŠøŃ‚Šø ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° змінити ŠæŠ°Ń€Š¾Š»ŃŒ при вхоГі в ŃŠøŃŃ‚ŠµŠ¼Ńƒ", + "submit": "Зберегти ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°", + "changeUserRole": "Змінити Ń€Š¾Š»ŃŒ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°", + "authenticated": "Автентифіковано", + "editOwnProfil": "Š ŠµŠ“Š°Š³ŃƒŠ²Š°Ń‚Šø власний ŠæŃ€Š¾Ń„Ń–Š»ŃŒ", + "enabledUser": "активний ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡", + "disabledUser": "заблокований ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡", + "activeUsers": "Активні ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–:", + "disabledUsers": "Заблоковані ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–:", + "totalUsers": "Š’ŃŃŒŠ¾Š³Š¾ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š²:", + "lastRequest": "ŠžŃŃ‚Š°Š½Š½Ń–Š¹ запит", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Дтатистика кінцевих точок", + "header": "Дтатистика кінцевих точок", + "top10": "Топ 10", + "top20": "Топ 20", + "all": "Всі", + "refresh": "ŠžŠ½Š¾Š²ŠøŃ‚Šø", + "includeHomepage": "Š’ŠŗŠ»ŃŽŃ‡ŠøŃ‚Šø головну ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ ('/')", + "includeLoginPage": "Š’ŠŗŠ»ŃŽŃ‡ŠøŃ‚Šø ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ Š²Ń…Š¾Š“Ńƒ ('/login')", + "totalEndpoints": "Š’ŃŃŒŠ¾Š³Š¾ кінцевих точок", + "totalVisits": "Š’ŃŃŒŠ¾Š³Š¾ Š²Ń–Š“Š²Ń–Š“ŃƒŠ²Š°Š½ŃŒ", + "showing": "Показано", + "selectedVisits": "Вибрані Š²Ń–Š“Š²Ń–Š“ŃƒŠ²Š°Š½Š½Ń", + "endpoint": "ŠšŃ–Š½Ń†ŠµŠ²Š° точка", + "visits": "Š’Ń–Š“Š²Ń–Š“ŃƒŠ²Š°Š½Š½Ń", + "percentage": "ВіГсоток", + "loading": "Š—Š°Š²Š°Š½Ń‚Š°Š¶ŠµŠ½Š½Ń...", + "failedToLoad": "ŠŠµ Š²Š“Š°Š»Š¾ŃŃ завантажити Гані кінцевих точок. Š”ŠæŃ€Š¾Š±ŃƒŠ¹Ń‚Šµ оновити.", + "home": "Головна", + "login": "Š’Ń…Ń–Š“", + "top": "Топ", + "numberOfVisits": "ŠšŃ–Š»ŃŒŠŗŃ–ŃŃ‚ŃŒ Š²Ń–Š“Š²Ń–Š“ŃƒŠ²Š°Š½ŃŒ", + "visitsTooltip": "Š’Ń–Š“Š²Ń–Š“ŃƒŠ²Š°Š½Š½Ń: {0} ({1}% віГ Š·Š°Š³Š°Š»ŃŒŠ½Š¾Ń— ŠŗŃ–Š»ŃŒŠŗŠ¾ŃŃ‚Ń–)", + "retry": "ŠŸŠ¾Š²Ń‚Š¾Ń€ŠøŃ‚Šø" + }, + "database": { + "title": "Імпорт/експорт бази Ганих", + "header": "Імпорт/експорт бази Ганих", + "fileName": "Ім'я Ń„Š°Š¹Š»Ńƒ", + "creationDate": "Дата ŃŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń", + "fileSize": "Розмір Ń„Š°Š¹Š»Ńƒ", + "deleteBackupFile": "ВиГалити файл резервної копії", + "importBackupFile": "Š†Š¼ŠæŠ¾Ń€Ń‚ŃƒŠ²Š°Ń‚Šø файл резервної копії", + "createBackupFile": "Дтворити файл резервної копії", + "downloadBackupFile": "Завантажте файл резервної копії", + "info_1": "ŠŸŃ€Šø імпорті Ганих важливо забезпечити ŠæŃ€Š°Š²ŠøŠ»ŃŒŠ½Ńƒ ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Ńƒ. Якщо ви не впевнені у своїх Š“Ń–ŃŃ…, Š·Š²ŠµŃ€Š½Ń–Ń‚ŃŒŃŃ за ŠæŃ€Š¾Ń„ŠµŃŃ–Š¹Š½Š¾ŃŽ Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ. Помилка в ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Ń– може призвести Го збоїв у роботі програми та призвести Го повної непрацезГатності.", + "info_2": "Ім'я Ń„Š°Š¹Š»Ńƒ піГ час Š·Š°Š²Š°Š½Ń‚Š°Š¶ŠµŠ½Š½Ń не має Š·Š½Š°Ń‡ŠµŠ½Š½Ń. Воно буГе перейменовано на формат backup_user_yyyyMMddHHmm.sql Š“Š»Ń Š·Š°Š±ŠµŠ·ŠæŠµŃ‡ŠµŠ½Š½Ń оГноманітності найменувань.", + "submit": "Імпорт резервної копії", + "importIntoDatabaseSuccessed": "Імпорт Го бази Ганих виконано вГало", + "backupCreated": "Резервне ŠŗŠ¾ŠæŃ–ŃŽŠ²Š°Š½Š½Ń бази Ганих ŃƒŃŠæŃ–ŃˆŠ½Š¾", + "fileNotFound": "Файл не знайГено", + "fileNullOrEmpty": "Файл не має Š±ŃƒŃ‚Šø ŠæŃƒŃŃ‚ŠøŠ¼", + "failedImportFile": "ŠŠµ Š²Š“Š°Š»Š¾ŃŃ Ń–Š¼ŠæŠ¾Ń€Ń‚ŃƒŠ²Š°Ń‚Šø файл", + "notSupported": "Š¦Ń Ń„ŃƒŠ½ŠŗŃ†Ń–Ń Š½ŠµŠ“Š¾ŃŃ‚ŃƒŠæŠ½Š° Š“Š»Ń вашого ŠæŃ–Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Š½Ń Го бази Ганих." + }, + "session": { + "expired": "Š’Š°Ńˆ сеанс Š·Š°ŠŗŃ–Š½Ń‡ŠøŠ²ŃŃ. Š‘ŃƒŠ“ŃŒ ласка, Š¾Š½Š¾Š²Ń–Ń‚ŃŒ ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ та ŠæŠ¾Š²Ń‚Š¾Ń€Ń–Ń‚ŃŒ ŃŠæŃ€Š¾Š±Ńƒ.", + "refreshPage": "ŠžŠ½Š¾Š²ŠøŃ‚Šø ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ" + }, + "home": { + "desc": "Š’Š°ŃˆŠµ локальне Ń€Ń–ŃˆŠµŠ½Š½Ń Š“Š»Ń всіх потреб, пов'ŃŠ·Š°Š½ŠøŃ… Ń–Š· PDF.", + "searchBar": "Пошук Ń„ŃƒŠ½ŠŗŃ†Ń–Š¹...", + "viewPdf": { + "title": "ŠŸŠµŃ€ŠµŠ³Š»ŃŠ“/Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń PDF", + "desc": "ŠŸŠµŃ€ŠµŠ³Š»ŃŠ“, Š°Š½Š¾Ń‚Š°Ń†Ń–Ń, Š“Š¾Š“Š°Š²Š°Š½Š½Ń Ń‚ŠµŠŗŃŃ‚Ńƒ або Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŃŒ" + }, + "setFavorites": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Ń‚Šø обрані", + "hideFavorites": "ŠŸŃ€ŠøŃ…Š¾Š²Š°Ń‚Šø обрані", + "showFavorites": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø обрані", + "legacyHomepage": "Дтара сторінка", + "newHomePage": "Š”ŠæŃ€Š¾Š±ŃƒŠ¹Ń‚Šµ нову ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ!", + "alphabetical": "ŠŠ±ŠµŃ‚ŠŗŠ¾ŃŽ", + "globalPopularity": "Š“Š»Š¾Š±Š°Š»ŃŒŠ½Š¾ŃŽ ŠæŠ¾ŃƒŠ»ŃŃ€Š½Ń–ŃŃ‚ŃŽ", + "sortBy": "Š”Š¾Ń€Ń‚ŃƒŠ²Š°Ń‚Šø за:", + "multiTool": { + "title": "ŠœŃƒŠ»ŃŒŃ‚Ń–Ń–Š½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚ PDF", + "desc": "ŠžŠ±'Ń”Š“Š½Š°Š½Š½Ń, поворот, зміна ŠæŠ¾Ń€ŃŠ“ŠŗŃƒ та Š²ŠøŠ“Š°Š»ŠµŠ½Š½Ń сторінок" + }, + "merge": { + "title": "ŠžŠ±'єГнати", + "desc": "Легко об'Ń”Š“Š½ŃƒŠ¹Ń‚Šµ ŠŗŃ–Š»ŃŒŠŗŠ° PDF-файлів у оГин." + }, + "split": { + "title": "РозГілити", + "desc": "Š Š¾Š·Š“Ń–Š»Ń–Ń‚ŃŒ PDF-файли на ŠŗŃ–Š»ŃŒŠŗŠ° Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ń–Š²" + }, + "rotate": { + "title": "ŠŸŠ¾Š²ŠµŃ€Š½ŃƒŃ‚Šø", + "desc": "Легко повертайте Š²Š°ŃˆŃ– PDF-файли." + }, + "imageToPdf": { + "title": "Š—Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń в PDF", + "desc": "ŠŸŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń (PNG, JPEG, GIF) в PDF." + }, + "pdfToImage": { + "title": "PDF в Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "desc": "ŠŸŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń PDF в Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "Š ŠµŠ¾Ń€Š³Š°Š½Ń–Š·Š°Ń†Ń–Ń", + "desc": "Š’ŠøŠ“Š°Š»ŠµŠ½Š½Ń/перестановка сторінок у буГь-ŃŠŗŠ¾Š¼Ńƒ ŠæŠ¾Ń€ŃŠ“ŠŗŃƒ" + }, + "addImage": { + "title": "ДоГати Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "desc": "ДоГає Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń у вказане місце в PDF (в розробці)" + }, + "watermark": { + "title": "ДоГати Š²Š¾Š“ŃŠ½ŠøŠ¹ знак", + "desc": "ДоГайте свій Š²Š¾Š“ŃŠ½ŠøŠ¹ знак Го Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° PDF." + }, + "permissions": { + "title": "Змінити Гозволи", + "desc": "Š—Š¼Ń–Š½Ń–Ń‚ŃŒ Гозволи вашого Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° PDF" + }, + "removePages": { + "title": "Š’ŠøŠ“Š°Š»ŠµŠ½Š½Ń", + "desc": "Š’ŠøŠ“Š°Š»Ń–Ń‚ŃŒ непотрібні сторінки Š· Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° PDF." + }, + "addPassword": { + "title": "ДоГати ŠæŠ°Ń€Š¾Š»ŃŒ", + "desc": "Š—Š°ŃˆŠøŃ„Ń€ŃƒŠ¹Ń‚Šµ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ PDF паролем." + }, + "removePassword": { + "title": "ВиГалити ŠæŠ°Ń€Š¾Š»ŃŒ", + "desc": "Š—Š½Ń–Š¼Ń–Ń‚ŃŒ захист паролем Š· вашого Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° PDF." + }, + "compressPdfs": { + "title": "Š”Ń‚ŠøŃŠ½ŃƒŃ‚Šø", + "desc": "Дтискайте PDF-файли, щоб Š·Š¼ŠµŠ½ŃˆŠøŃ‚Šø їх розмір." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Змінити метаГані", + "desc": "Змінити/виГалити/ГоГати метаГані Š· Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° PDF" + }, + "fileToPDF": { + "title": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø файл в PDF", + "desc": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ¹Ń‚Šµ майже буГь-ŃŠŗŠøŠ¹ файл в PDF (DOCX, PNG, XLS, PPT, TXT та Ń–Š½ŃˆŃ–)" + }, + "ocr": { + "title": "OCR/ŠžŃ‡ŠøŃ‰ŠµŠ½Š½Ń ŃŠŗŠ°Š½ŃƒŠ²Š°Š½Š½Ń", + "desc": "ŠžŃ‡ŠøŃ‰ŠµŠ½Š½Ń ŃŠŗŠ°Š½ŃƒŠ²Š°Š½Š½Ń та Š²ŠøŃŠ²Š»ŠµŠ½Š½Ń Ń‚ŠµŠŗŃŃ‚Ńƒ на Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½ŃŃ… у файлі PDF та повторне Š“Š¾Š“Š°Š²Š°Š½Š½Ń його ŃŠŗ текст." + }, + "extractImages": { + "title": "Š’ŠøŃ‚ŃŠ³Š½ŃƒŃ‚Šø Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "desc": "Š’ŠøŃ‚ŃŠ³ŃƒŃ” всі Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń Š· PDF і зберігає їх у zip" + }, + "pdfToPDFA": { + "title": "PDF в PDF/A", + "desc": "ŠŸŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń PDF в PDF/A Š“Š»Ń Говготривалого Š·Š±ŠµŃ€Ń–Š³Š°Š½Š½Ń" + }, + "PDFToWord": { + "title": "PDF в Word", + "desc": "ŠŸŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń PDF в формати Word (DOC, DOCX та ODT)" + }, + "PDFToPresentation": { + "title": "PDF в ŠæŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†Ń–ŃŽ", + "desc": "ŠŸŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń PDF в формати презентацій (PPT, PPTX та ODP)" + }, + "PDFToText": { + "title": "PDF в Text/RTF", + "desc": "ŠŸŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń PDF в текстовий або RTF формат" + }, + "PDFToHTML": { + "title": "PDF в HTML", + "desc": "ŠŸŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń PDF в формат HTML" + }, + "PDFToXML": { + "title": "PDF в XML", + "desc": "ŠŸŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń PDF в формат XML" + }, + "ScannerImageSplit": { + "title": "Š’ŠøŃŠ²Š»ŠµŠ½Š½Ń/Ń€Š¾Š·Š“Ń–Š»ŠµŠ½Š½Ń віГсканованих фотографій", + "desc": "Š Š¾Š·Š“Ń–Š»ŃŃ” ŠŗŃ–Š»ŃŒŠŗŠ° фотографій Š· фото/PDF" + }, + "sign": { + "title": "ŠŸŃ–Š“ŠæŠøŃ", + "desc": "ДоГає піГпис Го PDF за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ Š¼Š°Š»ŃŽŠ½ŠŗŠ°, Ń‚ŠµŠŗŃŃ‚Ńƒ або Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń" + }, + "flatten": { + "title": "Š—Š½ŠµŠ°ŠŗŃ‚ŠøŠ²ŃƒŠ²Š°Š½Š½Ń", + "desc": "Š’ŠøŠ“Š°Š»ŠµŠ½Š½Ń всіх інтерактивних елементів та форм Š· PDF" + }, + "repair": { + "title": "Ремонт", + "desc": "ŠŠ°Š¼Š°Š³Š°Ń”Ń‚ŃŒŃŃ віГновити пошкоГжений/зламаний PDF" + }, + "removeBlanks": { + "title": "ВиГалити порожні сторінки", + "desc": "Š’ŠøŃŠ²Š»ŃŃ” та Š²ŠøŠ“Š°Š»ŃŃ” порожні сторінки Š· Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°" + }, + "removeAnnotations": { + "title": "ВиГалити анотації", + "desc": "Š’ŠøŠ“Š°Š»ŃŃ” всі коментарі/анотації Š· PDF" + }, + "compare": { + "title": "ŠŸŠ¾Ń€Ń–Š²Š½ŃŠ½Š½Ń", + "desc": "ŠŸŠ¾Ń€Ń–Š²Š½ŃŽŃ” та ŠæŠ¾ŠŗŠ°Š·ŃƒŃ” Ń€Ń–Š·Š½ŠøŃ†ŃŽ між Гвома PDF-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Š¼Šø" + }, + "certSign": { + "title": "ŠŸŃ–Š“ŠæŠøŃŠ°Ń‚Šø сертифікатом", + "desc": "ŠŸŃ–Š“ŠæŠøŃŠ°Ń‚Šø PDF сертифікатом/ŠŗŠ»ŃŽŃ‡ŠµŠ¼ (PEM/P12)" + }, + "removeCertSign": { + "title": "ВиГалити піГпис сертифікатом", + "desc": "ВиГалити піГпис сертифікатом Š· PDF-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ńƒ" + }, + "pageLayout": { + "title": "ŠžŠ±'єГнати сторінки", + "desc": "ŠžŠ±'Ń”Š“Š½Š°Š½Š½Ń ŠŗŃ–Š»ŃŒŠŗŠ¾Ń… сторінок Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° PDF в оГну ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ" + }, + "scalePages": { + "title": "Змінити розмір/Š¼Š°ŃŃˆŃ‚Š°Š± сторінки", + "desc": "Змінити розмір/Š¼Š°ŃŃˆŃ‚Š°Š± сторінки та/або її Š²Š¼Ń–ŃŃ‚Ńƒ." + }, + "pipeline": { + "title": "ŠšŠ¾Š½Š²ŠµŃ”Ń€ (Ń€Š¾Š·ŃˆŠøŃ€ŠµŠ½ŠøŠ¹)", + "desc": "Š’ŠøŠŗŠ¾Š½ŃƒŠ¹Ń‚Šµ ŠŗŃ–Š»ŃŒŠŗŠ° Гій Š· PDF-файлами, Š²ŠøŠ·Š½Š°Ń‡Š°ŃŽŃ‡Šø сценарії конвеєрної обробки." + }, + "add-page-numbers": { + "title": "ДоГати номера сторінок", + "desc": "ДоГає номера сторінок по всьому Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ńƒ в заГаному місці" + }, + "auto-rename": { + "title": "Автоматичне ŠæŠµŃ€ŠµŠ¹Š¼ŠµŠ½ŃƒŠ²Š°Š½Š½Ń PDF-Ń„Š°Š¹Š»Ńƒ", + "desc": "Автоматичне ŠæŠµŃ€ŠµŠ¹Š¼ŠµŠ½ŃƒŠ²Š°Š½Š½Ń Ń„Š°Š¹Š»Ńƒ PDF на основі його Š²ŠøŃŠ²Š»ŠµŠ½Š¾Š³Š¾ заголовку" + }, + "adjust-contrast": { + "title": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń ŠŗŠ¾Š»ŃŒŠ¾Ń€Ń–Š²/контрастності", + "desc": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń контрастності, насиченості та ŃŃŠŗŃ€Š°Š²Š¾ŃŃ‚Ń– Ń„Š°Š¹Š»Ńƒ PDF" + }, + "crop": { + "title": "ŠžŠ±Ń€Ń–Š·Š°Ń‚Šø PDF-файл", + "desc": "ŠžŠ±Ń€Ń–Š·Š°Ń‚Šø PDF-файл, щоб Š·Š¼ŠµŠ½ŃˆŠøŃ‚Šø його розмір (текст Š·Š°Š»ŠøŃˆŠ°Ń”Ń‚ŃŒŃŃ!)" + }, + "autoSplitPDF": { + "title": "Автоматичне Ń€Š¾Š·Š“Ń–Š»ŠµŠ½Š½Ń сторінок", + "desc": "Автоматичне Ń€Š¾Š·Š“Ń–Š»ŠµŠ½Š½Ń віГсканованого PDF-Ń„Š°Š¹Š»Ńƒ за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ фізичного Ń€Š¾Š·Š“Ń–Š»ŃŒŠ½ŠøŠŗŠ° віГсканованих сторінок QR-коГу" + }, + "sanitizePdf": { + "title": "Данітарна обробка", + "desc": "Š’ŠøŠ“Š°Š»ŠµŠ½Š½Ń скриптів та Ń–Š½ŃˆŠøŃ… елементів Š· PDF-файлів" + }, + "URLToPDF": { + "title": "URL/сайт в PDF", + "desc": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŃ” буГь-ŃŠŗŠøŠ¹ http(s)URL у PDF" + }, + "HTMLToPDF": { + "title": "HTML в PDF", + "desc": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŃ” буГь-ŃŠŗŠøŠ¹ HTML-файл або zip-файл у PDF." + }, + "MarkdownToPDF": { + "title": "Markdown в PDF", + "desc": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŃ” буГь-ŃŠŗŠøŠ¹ файл Markdown у PDF" + }, + "PDFToMarkdown": { + "title": "PDF в Markdown", + "desc": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŃ” буГь-ŃŠŗŠøŠ¹ файл PDF у Markdown" + }, + "getPdfInfo": { + "title": "ŠžŃ‚Ń€ŠøŠ¼Š°Ń‚Šø ВДЮ Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–ŃŽ у форматі PDF", + "desc": "Збирає буГь-ŃŠŗŃƒ можливу Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–ŃŽ у PDF-файлах." + }, + "extractPage": { + "title": "Š’ŠøŠ“Š¾Š±ŃƒŃ‚Šø ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ(Šø)", + "desc": "Š’ŠøŠ“Š¾Š±ŃƒŠ²Š°Ń” обрані сторінки Š· PDF" + }, + "PdfToSinglePage": { + "title": "PDF на оГну велику ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ", + "desc": "ŠžŠ±'Ń”Š“Š½ŃƒŃ” всі сторінки PDF в оГну велику ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ." + }, + "showJS": { + "title": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø JavaScript", + "desc": "ŠØŃƒŠŗŠ°Ń” та віГображає буГь-ŃŠŗŠøŠ¹ JS, вбуГований у PDF-файл." + }, + "autoRedact": { + "title": "Автоматичне Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń", + "desc": "Автоматичне Š·Š°Ń‚ŠµŠ¼Š½ŠµŠ½Š½Ń (Ń‡Š¾Ń€Š½Ń–Š½Š½Ń) Ń‚ŠµŠŗŃŃ‚Ńƒ в PDF на основі вхіГного Ń‚ŠµŠŗŃŃ‚Ńƒ" + }, + "redact": { + "title": "Š ŃƒŃ‡Š½Šµ Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń", + "desc": "Š ŠµŠ“Š°Š³ŃƒŃ” PDF-файл на основі виГіленого Ń‚ŠµŠŗŃŃ‚Ńƒ, Š½Š°Š¼Š°Š»ŃŒŠ¾Š²Š°Š½ŠøŃ… форм і/або вибраних сторінок" + }, + "tableExtraxt": { + "title": "PDF в CSV", + "desc": "Š’ŠøŠ“Š¾Š±ŃƒŠ²Š°Ń” таблиці Š· PDF та ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŃŽŃ” їх у CSV" + }, + "autoSizeSplitPDF": { + "title": "Автоматичне Ń€Š¾Š·Š“Ń–Š»ŠµŠ½Š½Ń за розміром/ŠŗŃ–Š»ŃŒŠŗŃ–ŃŃ‚ŃŽ", + "desc": "Š Š¾Š·Š“Ń–Š»ŃŃ” оГин PDF на ŠŗŃ–Š»ŃŒŠŗŠ° Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ń–Š² на основі Ń€Š¾Š·Š¼Ń–Ń€Ńƒ, ŠŗŃ–Š»ŃŒŠŗŠ¾ŃŃ‚Ń– сторінок або ŠŗŃ–Š»ŃŒŠŗŠ¾ŃŃ‚Ń– Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ń–Š²" + }, + "overlay-pdfs": { + "title": "ŠŠ°ŠŗŠ»Š°Š“ŠµŠ½Š½Ń PDF", + "desc": "ŠŠ°ŠŗŠ»Š°Š“ŠµŠ½Š½Ń оГного PDF поверх Ń–Š½ŃˆŠ¾Š³Š¾ PDF" + }, + "split-by-sections": { + "title": "Š Š¾Š·Š“Ń–Š»ŠµŠ½Š½Ń PDF за ŃŠµŠŗŃ†Ń–ŃŠ¼Šø", + "desc": "Š Š¾Š·Š“Ń–Š»ŠµŠ½Š½Ń кожної сторінки PDF на Š¼ŠµŠ½ŃˆŃ– Š³Š¾Ń€ŠøŠ·Š¾Š½Ń‚Š°Š»ŃŒŠ½Ń– та Š²ŠµŃ€Ń‚ŠøŠŗŠ°Š»ŃŒŠ½Ń– секції" + }, + "AddStampRequest": { + "title": "ДоГати ŠæŠµŃ‡Š°Ń‚ŠŗŃƒ на PDF", + "desc": "Š”Š¾Š“Š°Š²Š°Š½Š½Ń текстової або Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń печатки у вказані Š¼Ń–ŃŃ†Ń" + }, + "removeImagePdf": { + "title": "ВиГалити Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "desc": "Š’ŠøŠ“Š°Š»ŃŃ” Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń Š· PDF Š“Š»Ń Š·Š¼ŠµŠ½ŃˆŠµŠ½Š½Ń Ń€Š¾Š·Š¼Ń–Ń€Ńƒ Ń„Š°Š¹Š»Ńƒ" + }, + "splitPdfByChapters": { + "title": "РозГілити PDF за розГілами", + "desc": "Š Š¾Š·Š“Ń–Š»ŃŃ” PDF на ŠŗŃ–Š»ŃŒŠŗŠ° файлів на основі ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Šø його розГілів" + }, + "validateSignature": { + "title": "ŠŸŠµŃ€ŠµŠ²Ń–Ń€ŠŗŠ° ŠæŃ–Š“ŠæŠøŃŃƒ PDF", + "desc": "ŠŸŠµŃ€ŠµŠ²Ń–Ń€ŠŗŠ° цифрових піГписів та сертифікатів у PDF-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń…" + }, + "replaceColorPdf": { + "title": "Заміна та Ń–Š½Š²ŠµŃ€ŃŃ–Ń ŠŗŠ¾Š»ŃŒŠ¾Ń€Ńƒ", + "desc": "Š—Š°Š¼Ń–Š½ŃŽŃ” колір Ń‚ŠµŠŗŃŃ‚Ńƒ та Ń„Š¾Š½Ńƒ у PDF та Ń–Š½Š²ŠµŃ€Ń‚ŃƒŃ” всі ŠŗŠ¾Š»ŃŒŠ¾Ń€Šø PDF Š“Š»Ń Š·Š¼ŠµŠ½ŃˆŠµŠ½Š½Ń Ń€Š¾Š·Š¼Ń–Ń€Ńƒ Ń„Š°Š¹Š»Ńƒ" + } + }, + "viewPdf": { + "tags": "ŠæŠµŃ€ŠµŠ³Š»ŃŠ“,Ń‡ŠøŃ‚Š°Š½Š½Ń,анотації,текст,Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "title": "ŠŸŠµŃ€ŠµŠ³Š»ŃŠ“/Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń PDF", + "header": "ŠŸŠµŃ€ŠµŠ³Š»ŃŠ½ŃƒŃ‚Šø PDF" + }, + "multiTool": { + "tags": "Š¼ŃƒŠ»ŃŒŃ‚ŠøŃ–Š½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚,багатоопераційний,інтерфейс,ŠæŠµŃ€ŠµŃ‚ŃŠ³ŃƒŠ²Š°Š½Š½Ń,ŠŗŠ»Ń–Ń”Š½Ń‚ŃŃŒŠŗŠ° частина,інтерактивний", + "title": "ŠœŃƒŠ»ŃŒŃ‚ŠøŃ–Š½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚ PDF", + "header": "ŠœŃƒŠ»ŃŒŃ‚ŠøŃ–Š½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚ PDF", + "uploadPrompts": "Ім'я Ń„Š°Š¹Š»Ńƒ", + "selectAll": "Вибрати все", + "deselectAll": "Š”ŠŗŠ°ŃŃƒŠ²Š°Ń‚Šø вибір усіх", + "selectPages": "Вибір сторінки", + "selectedPages": "Вибрані сторінки", + "page": "Дторінка", + "deleteSelected": "ВиГалити вибрані", + "downloadAll": "Експорт", + "downloadSelected": "Експорт вибраних", + "insertPageBreak": "Вставити розрив сторінки", + "addFile": "ДоГати файл", + "rotateLeft": "ŠŸŠ¾Š²ŠµŃ€Š½ŃƒŃ‚Šø вліво", + "rotateRight": "ŠŸŠ¾Š²ŠµŃ€Š½ŃƒŃ‚Šø ŠæŃ€Š°Š²Š¾Ń€ŃƒŃ‡", + "split": "РозГілити", + "moveLeft": "ŠŸŠµŃ€ŠµŠ¼Ń–ŃŃ‚ŠøŃ‚Šø вліво", + "moveRight": "ŠŸŠµŃ€ŠµŠ¼Ń–ŃŃ‚ŠøŃ‚Šø ŠæŃ€Š°Š²Š¾Ń€ŃƒŃ‡", + "delete": "ВиГалити", + "dragDropMessage": "Вибрано сторінок", + "undo": "Š”ŠŗŠ°ŃŃƒŠ²Š°Ń‚Šø", + "redo": "ŠŸŠ¾Š²Ń‚Š¾Ń€ŠøŃ‚Šø" + }, + "merge": { + "tags": "об'Ń”Š“Š½Š°Š½Š½Ń,операції Š·Ń– сторінками,серверна частина", + "title": "ŠžŠ±'єГнати", + "header": "ŠžŠ±'Ń”Š“Š½Š°Š½Š½Ń ŠŗŃ–Š»ŃŒŠŗŠ¾Ń… PDF-файлів (2+)", + "sortByName": "Š”Š¾Ń€Ń‚ŃƒŠ²Š°Š½Š½Ń за ім'ŃŠ¼", + "sortByDate": "Š”Š¾Ń€Ń‚ŃƒŠ²Š°Š½Š½Ń за Š“Š°Ń‚Š¾ŃŽ", + "removeCertSign": "ВиГалити цифровий піГпис у Š¾Š±ā€™Ń”Š“Š½Š°Š½Š¾Š¼Ńƒ файлі?", + "submit": "ŠžŠ±'єГнати" + }, + "split": { + "tags": "операції Š·Ń– сторінками,Ń€Š¾Š·Š“Ń–Š»ŠµŠ½Š½Ń,багатосторінковий,Š²ŠøŃ€Ń–Š·Š°Š½Š½Ń,серверна частина", + "title": "РозГілити PDF", + "header": "РозГілити PDF", + "desc": { + "1": "Числа, ŃŠŗŃ– ви вибрали, це номери сторінок, на ŃŠŗŠøŃ… ви хочете зробити розГіл.", + "2": "Таким чином, вибір 1,3,7-8 Ń€Š¾Š·Š“Ń–Š»ŠøŃ‚ŃŒ 10-сторінковий Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ на 6 окремих PDF-файлів Š·:", + "3": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #1: Дторінка 1", + "4": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #2: Дторінки 2 і 3", + "5": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #3: Дторінки 4, 5 і 6", + "6": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #4: Дторінка 7", + "7": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #5: Дторінка 8", + "8": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ #6: Дторінки 9 і 10" + }, + "splitPages": "Š’Š²ŠµŠ“Ń–Ń‚ŃŒ сторінки Š“Š»Ń Ń€Š¾Š·Š“Ń–Š»ŠµŠ½Š½Ń:", + "submit": "РозГілити" + }, + "rotate": { + "tags": "серверна частина", + "title": "ŠŸŠ¾Š²ŠµŃ€Š½ŃƒŃ‚Šø PDF", + "header": "ŠŸŠ¾Š²ŠµŃ€Š½ŃƒŃ‚Šø PDF", + "selectAngle": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ ŠŗŃƒŃ‚ ŠæŠ¾Š²Š¾Ń€Š¾Ń‚Ńƒ (кратний 90 Š³Ń€Š°Š“ŃƒŃŠ°Š¼):", + "submit": "ŠŸŠ¾Š²ŠµŃ€Š½ŃƒŃ‚Šø" + }, + "imageToPdf": { + "tags": "ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†Ń–Ń,Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń,jpg,картинка,фото" + }, + "pdfToImage": { + "tags": "ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†Ń–Ń,Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń,jpg,картинка,фото", + "title": "PDF в Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "header": "PDF в Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "selectText": "Формат Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "singleOrMultiple": "Тип Ń€ŠµŠ·ŃƒŠ»ŃŒŃ‚Š°Ń‚Ńƒ Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "single": "ŠžŠ“Š½Šµ велике Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "multi": "Š”ŠµŠŗŃ–Š»ŃŒŠŗŠ° Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŃŒ", + "colorType": "Тип ŠŗŠ¾Š»ŃŒŠ¾Ń€Ńƒ", + "color": "ŠšŠ¾Š»Ń–Ń€", + "grey": "ВіГтінки сірого", + "blackwhite": "Чорно-білий (може втратити Гані!)", + "submit": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø", + "info": "Python не встановлено. ŠŠµŠ¾Š±Ń…Ń–Š“Š½Š¾ Š“Š»Ń конвертації WebP.", + "placeholder": "(наприклаГ 1,2,8 або 4,7,12-16 або 2n-1)" + }, + "pdfOrganiser": { + "tags": "Гвосторонній Š“Ń€ŃƒŠŗ,парні,непарні,ŃŠ¾Ń€Ń‚ŃƒŠ²Š°Š½Š½Ń,ŠæŠµŃ€ŠµŠ¼Ń–Ń‰ŠµŠ½Š½Ń", + "title": "ŠžŃ€Š³Š°Š½Ń–Š·Š°Ń‚Š¾Ń€ сторінок", + "header": "ŠžŃ€Š³Š°Š½Ń–Š·Š°Ń‚Š¾Ń€ PDF-сторінок", + "submit": "ŠŸŠµŃ€ŠµŃƒŠæŠ¾Ń€ŃŠ“ŠŗŃƒŠ²Š°Ń‚Šø сторінки", + "mode": { + "_value": "Режим", + "1": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń†ŃŒŠŗŠøŠ¹ ŠæŠ¾Ń€ŃŠ“Š¾Šŗ сторінок", + "2": "Зворотній ŠæŠ¾Ń€ŃŠ“Š¾Šŗ", + "3": "Š”Š¾Ń€Ń‚ŃƒŠ²Š°Š½Š½Ń Гуплексом", + "4": "Š”Š¾Ń€Ń‚ŃƒŠ²Š°Š½Š½Ń Š±Ń€Š¾ŃˆŃƒŃ€Š¾ŃŽ", + "5": "Š”Š¾Ń€Ń‚ŃƒŠ²Š°Š½Š½Ń Š±Ń€Š¾ŃˆŃƒŃ€Š¾ŃŽ Š·Ń– степлером Š· боку", + "6": "Š Š¾Š·Š“Ń–Š»ŠµŠ½Š½Ń на парні та непарні сторінки", + "7": "ВиГалити ŠæŠµŃ€ŃˆŃƒ", + "8": "ВиГалити Š¾ŃŃ‚Š°Š½Š½ŃŽ", + "9": "ВиГалити ŠæŠµŃ€ŃˆŃƒ та Š¾ŃŃ‚Š°Š½Š½ŃŽ", + "10": "ŠžŠ±'Ń”Š“Š½Š°Š½Š½Ń парних-непарних", + "11": "Š”ŃƒŠ±Š»ŃŽŠ²Š°Ń‚Šø всі сторінки" + }, + "placeholder": "(наприклаГ, 1,3,2 або 4-8,2,10-12 або 2n-1)" + }, + "addImage": { + "tags": "Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń,jpg,картинка,фото", + "title": "ДоГати Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "header": "ДоГати Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń в PDF", + "everyPage": "Кожна сторінка?", + "upload": "ДоГати Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "submit": "ДоГати Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń" + }, + "watermark": { + "tags": "текст,повторний,мітка,власний,Š°Š²Ń‚Š¾Ń€ŃŃŒŠŗŠµ право,Ń‚Š¾Ń€Š³Š¾Š²ŠµŠ»ŃŒŠ½Š° марка,Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń,jpg,картинка,фото", + "title": "ДоГати Š²Š¾Š“ŃŠ½ŠøŠ¹ знак", + "header": "ДоГати Š²Š¾Š“ŃŠ½ŠøŠ¹ знак", + "customColor": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń†ŃŒŠŗŠøŠ¹ колір Ń‚ŠµŠŗŃŃ‚Ńƒ", + "selectText": { + "1": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ PDF, щоб ГоГати Š²Š¾Š“ŃŠ½ŠøŠ¹ знак:", + "2": "Текст Š²Š¾Š“ŃŠ½Š¾Š³Š¾ знаку:", + "3": "Розмір ŃˆŃ€ŠøŃ„Ń‚Ńƒ:", + "4": "ŠžŠ±ŠµŃ€Ń‚Š°Š½Š½Ń (0-360):", + "5": "Š“Š¾Ń€ŠøŠ·Š¾Š½Ń‚Š°Š»ŃŒŠ½ŠøŠ¹ інтервал (проміжок між кожним Š²Š¾Š“ŃŠ½ŠøŠ¼ знаком по горизонталі):", + "6": "Š’ŠµŃ€Ń‚ŠøŠŗŠ°Š»ŃŒŠ½ŠøŠ¹ інтервал (проміжок між кожним Š²Š¾Š“ŃŠ½ŠøŠ¼ знаком по вертикалі):", + "7": "ŠŠµŠæŃ€Š¾Š·Š¾Ń€Ń–ŃŃ‚ŃŒ (0% - 100%):", + "8": "Тип Š²Š¾Š“ŃŠ½Š¾Š³Š¾ знаку:", + "9": "Š—Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń Š²Š¾Š“ŃŠ½Š¾Š³Š¾ знаку:", + "10": "ŠšŠµŠ²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø PDF в PDF-Image" + }, + "submit": "ДоГати Š²Š¾Š“ŃŠ½ŠøŠ¹ знак", + "type": { + "1": "Текст", + "2": "Š—Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń" + } + }, + "permissions": { + "tags": "Ń‡ŠøŃ‚Š°Š½Š½Ń,запис,Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń,Š“Ń€ŃƒŠŗ", + "title": "Змінити Гозволи", + "header": "Змінити Гозволи", + "warning": "ŠŸŠ¾ŠæŠµŃ€ŠµŠ“Š¶ŠµŠ½Š½Ń про те, що ці Гозволи не можна змінити, Ń€ŠµŠŗŠ¾Š¼ŠµŠ½Š“ŃƒŃ”Ń‚ŃŒŃŃ встановити їх за Š“Š¾ŠæŠ¾Š¼Š¾Š³Š¾ŃŽ ŠæŠ°Ń€Š¾Š»Ń на сторінці Š“Š¾Š“Š°Š²Š°Š½Š½Ń ŠæŠ°Ń€Š¾Š»Ń.", + "selectText": { + "1": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ PDF, щоб змінити Гозволи", + "2": "Дозволи на Š²ŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Š½Ń", + "3": "Запобігти збірці Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°", + "4": "Запобігти Š²ŠøŠ»ŃƒŃ‡ŠµŠ½Š½ŃŽ ŠŗŠ¾Š½Ń‚ŠµŠ½Ń‚Ńƒ", + "5": "Запобігти Š²ŠøŠ»ŃƒŃ‡ŠµŠ½Š½ŃŽ Š“Š»Ń Š“Š¾ŃŃ‚ŃƒŠæŠ½Š¾ŃŃ‚Ń–", + "6": "Заборонити Š·Š°ŠæŠ¾Š²Š½ŠµŠ½Š½Ń форм", + "7": "Запобігти моГифікації", + "8": "Заборонити Š¼Š¾Š“ŠøŃ„Ń–ŠŗŠ°Ń†Ń–ŃŽ анотацій", + "9": "Заборонити Š“Ń€ŃƒŠŗ", + "10": "Заборонити Š“Ń€ŃƒŠŗ різних форматів" + }, + "submit": "Змінити" + }, + "removePages": { + "tags": "виГалити сторінки,Š²ŠøŠ“Š°Š»ŠµŠ½Š½Ń сторінок" + }, + "addPassword": { + "tags": "безпека,захист", + "title": "ДоГати ŠæŠ°Ń€Š¾Š»ŃŒ", + "header": "ДоГати ŠæŠ°Ń€Š¾Š»ŃŒ (Š·Š°ŃˆŠøŃ„Ń€ŃƒŠ²Š°Ń‚Šø)", + "selectText": { + "1": "ŠžŠ±ŠµŃ€Ń–Ń‚ŃŒ PDF Š“Š»Ń ŃˆŠøŃ„Ń€ŃƒŠ²Š°Š½Š½Ń", + "2": "ŠŸŠ°Ń€Š¾Š»ŃŒ", + "3": "Довжина ŠŗŠ»ŃŽŃ‡Š° ŃˆŠøŃ„Ń€ŃƒŠ²Š°Š½Š½Ń", + "4": "Вищі Š·Š½Š°Ń‡ŠµŠ½Š½Ń ŃŠøŠ»ŃŒŠ½Ń–ŃˆŃ–, але нижчі Š·Š½Š°Ń‡ŠµŠ½Š½Ń Š¼Š°ŃŽŃ‚ŃŒ ŠŗŃ€Š°Ń‰Ńƒ ŃŃƒŠ¼Ń–ŃŠ½Ń–ŃŃ‚ŃŒ.", + "5": "Дозволи на Š²ŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Š½Ń", + "6": "Запобігти збірці Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°", + "7": "Запобігти Š²ŠøŠ»ŃƒŃ‡ŠµŠ½Š½ŃŽ ŠŗŠ¾Š½Ń‚ŠµŠ½Ń‚Ńƒ", + "8": "Запобігти Š²ŠøŠ»ŃƒŃ‡ŠµŠ½Š½ŃŽ Š“Š»Ń Š“Š¾ŃŃ‚ŃƒŠæŠ½Š¾ŃŃ‚Ń–", + "9": "Заборонити Š·Š°ŠæŠ¾Š²Š½ŠµŠ½Š½Ń форм", + "10": "Запобігти моГифікації", + "11": "Заборонити Š¼Š¾Š“ŠøŃ„Ń–ŠŗŠ°Ń†Ń–ŃŽ анотацій", + "12": "Заборонити Š“Ń€ŃƒŠŗ", + "13": "Заборонити Š“Ń€ŃƒŠŗ різних форматів", + "14": "Š’Š»Š°ŃŠ½ŠøŃ†ŃŒŠŗŠøŠ¹ ŠæŠ°Ń€Š¾Š»ŃŒ", + "15": "ŠžŠ±Š¼ŠµŠ¶ŃƒŃ”, що можна робити Š· Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š¾Š¼ ŠæŃ–ŃŠ»Ń його Š²Ń–Š“ŠŗŃ€ŠøŃ‚Ń‚Ń (не ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŃ”Ń‚ŃŒŃŃ всіма програмами Ń‡ŠøŃ‚Š°Š½Š½Ń)", + "16": "ŠžŠ±Š¼ŠµŠ¶ŃƒŃ” Š²Ń–Š“ŠŗŃ€ŠøŃ‚Ń‚Ń самого Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°" + }, + "submit": "ŠØŠøŃ„Ń€ŃƒŠ²Š°Ń‚Šø" + }, + "removePassword": { + "tags": "безпека,Ń€Š¾Š·ŃˆŠøŃ„Ń€Š¾Š²ŠŗŠ°,захист,Š²ŠøŠ“Š°Š»ŠµŠ½Š½Ń ŠæŠ°Ń€Š¾Š»Ń", + "title": "ВиГалити ŠæŠ°Ń€Š¾Š»ŃŒ", + "header": "ВиГалити ŠæŠ°Ń€Š¾Š»ŃŒ (Š Š¾Š·ŃˆŠøŃ„Ń€ŃƒŠ²Š°Ń‚Šø)", + "selectText": { + "1": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ PDF Š“Š»Ń Ń€Š¾Š·ŃˆŠøŃ„Ń€ŃƒŠ²Š°Š½Š½Ń", + "2": "ŠŸŠ°Ń€Š¾Š»ŃŒ" + }, + "submit": "ВиГалити" + }, + "compressPdfs": { + "tags": "стиск,маленький,крихітний" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "заголовок,автор,Гата,ŃŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń,час,Š²ŠøŠ“Š°Š²ŠµŃ†ŃŒ,виробник,статистика", + "title": "Заголовок:", + "header": "Змінити метаГані", + "selectText": { + "1": "Š‘ŃƒŠ“ŃŒ ласка, Š²Ń–Š“Ń€ŠµŠ“Š°Š³ŃƒŠ¹Ń‚Šµ змінні, ŃŠŗŃ– ви хочете змінити", + "2": "ВиГалити всі метаГані", + "3": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń†ŃŒŠŗŃ– метаГані:", + "4": "Š†Š½ŃˆŃ– метаГані:", + "5": "ДоГати ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń†ŃŒŠŗŠøŠ¹ запис метаГаних" + }, + "author": "Автор:", + "creationDate": "Дата ŃŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń (yyyy/MM/dd HH:mm:ss):", + "creator": "Š”Ń‚Š²Š¾Ń€ŃŽŠ²Š°Ń‡:", + "keywords": "ŠšŠ»ŃŽŃ‡Š¾Š²Ń– слова:", + "modDate": "Дата зміни (yyyy/MM/dd HH:mm:ss):", + "producer": "Виробник:", + "subject": "Тема:", + "trapped": "ŠŸŠ°ŃŃ‚ŠŗŠ°:", + "submit": "Змінити" + }, + "fileToPDF": { + "tags": "ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń,формат,Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚,картинка,ŠæŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†Ń–Ń,текст,ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†Ń–Ń,офіс,Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šø,word,excel,powerpoint", + "title": "Файл у PDF", + "header": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø буГь-ŃŠŗŠøŠ¹ файл у PDF", + "credit": "Цей сервіс Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” LibreOffice та Unoconv Š“Š»Ń ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń файлів.", + "supportedFileTypesInfo": "ŠŸŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŠ²Š°Š½Ń– типи файлів", + "supportedFileTypes": "ŠŸŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŠ²Š°Š½Ń– типи файлів повинні Š²ŠŗŠ»ŃŽŃ‡Š°Ń‚Šø нижченавеГені, оГнак повний оновлений список ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŠ²Š°Š½ŠøŃ… форматів Š“ŠøŠ²Ń–Ń‚ŃŒŃŃ у Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–Ń— LibreOffice.", + "submit": "ŠŸŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠøŃ‚Šø у PDF" + }, + "ocr": { + "tags": "Ń€Š¾Š·ŠæŃ–Š·Š½Š°Š²Š°Š½Š½Ń,текст,Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń,ŃŠŗŠ°Š½ŃƒŠ²Š°Š½Š½Ń,Ń‡ŠøŃ‚Š°Š½Š½Ń,Ń–Š“ŠµŠ½Ń‚ŠøŃ„Ń–ŠŗŠ°Ń†Ń–Ń,Š²ŠøŃŠ²Š»ŠµŠ½Š½Ń,реГагований", + "title": "OCR/ŠžŃ‡ŠøŃ‰ŠµŠ½Š½Ń ŃŠŗŠ°Š½ŃƒŠ²Š°Š½Š½Ń", + "header": "ŠžŃ‡ŠøŃ‰ŠµŠ½Š½Ń ŃŠŗŠ°Š½ŃƒŠ²Š°Š½Š½Ń / OCR (Optical Character Recognition) Š Š¾Š·ŠæŃ–Š·Š½Š°Š²Š°Š½Š½Ń Ń‚ŠµŠŗŃŃ‚Ńƒ", + "selectText": { + "1": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ мови, ŃŠŗŃ– повинні Š±ŃƒŃ‚Šø Š²ŠøŃŠ²Š»ŠµŠ½Ń– у PDF-файлі (перелічені ті, ŃŠŗŃ– Š²ŠøŃŠ²Š»ŠµŠ½Ń– на Ганий момент):", + "2": "Š”Ń‚Š²Š¾Ń€Ń–Ń‚ŃŒ текстовий файл, що Š¼Ń–ŃŃ‚ŠøŃ‚ŃŒ текст OCR, разом Ń–Š· PDF-файлом, обробленим OCR.", + "3": "ŠŸŃ€Š°Š²ŠøŠ»ŃŒŠ½Ń– сторінки були віГскановані піГ ŠæŠµŃ€ŠµŠŗŠ¾ŃˆŠµŠ½ŠøŠ¼ ŠŗŃƒŃ‚Š¾Š¼ ŃˆŠ»ŃŃ…Š¾Š¼ ŠæŠ¾Š²Š¾Ń€Š¾Ń‚Ńƒ їх на місце", + "4": "ŠžŃ‡ŠøŃŃ‚Ń–Ń‚ŃŒ ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ, щоб Š·Š¼ŠµŠ½ŃˆŠøŃ‚Šø шанси, що OCR знайГе текст на Ń„Š¾Š½Š¾Š²Š¾Š¼Ńƒ ŃˆŃƒŠ¼Ń–. (без зміни Š²ŠøŃ…Š¾Š“Ńƒ)", + "5": "ŠžŃ‡ŠøŃŃ‚Ń–Ń‚ŃŒ ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ, щоб Š·Š¼ŠµŠ½ŃˆŠøŃ‚Šø шанси, що OCR знайГе текст на Ń„Š¾Š½Š¾Š²Š¾Š¼Ńƒ ŃˆŃƒŠ¼Ń–, ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŃ” Š¾Ń‡ŠøŃ‰ŠµŠ½Š½Ń вивоГу.", + "6": "Š†Š³Š½Š¾Ń€ŃƒŃ” сторінки Š· інтерактивним текстом, розпізнає лише сторінки Š· Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½ŃŠ¼Šø", + "7": "ŠŸŃ€ŠøŠ¼ŃƒŃŠ¾Š²Šµ Ń€Š¾Š·ŠæŃ–Š·Š½Š°Š²Š°Š½Š½Ń символів, буГе розпізнавати кожну ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ, Š²ŠøŠ“Š°Š»ŃŃŽŃ‡Šø всі елементи початкового Ń‚ŠµŠŗŃŃ‚Ńƒ", + "8": "Звичайний (буГе помилка, ŃŠŗŃ‰Š¾ PDF Š¼Ń–ŃŃ‚ŠøŃ‚ŃŒ текст)", + "9": "ДоГаткові Š½Š°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń", + "10": "Режим OCR", + "11": "ВиГалити Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń ŠæŃ–ŃŠ»Ń OCR (Š²ŠøŠ“Š°Š»ŃŃ” ВДІ Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń, корисно лише в Ń‚Š¾Š¼Ńƒ випаГку, ŃŠŗŃ‰Š¾ вони є Ń‡Š°ŃŃ‚ŠøŠ½Š¾ŃŽ ŠµŃ‚Š°ŠæŃƒ ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń)", + "12": "Тип Ń€ŠµŠ½Š“ŠµŃ€Ńƒ (Ń€Š¾Š·ŃˆŠøŃ€ŠµŠ½ŠøŠ¹)" + }, + "help": "ŠŸŃ€Š¾Ń‡ŠøŃ‚Š°Š¹Ń‚Šµ цю Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°Ń†Ń–ŃŽ про те, ŃŠŗ Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚Šø це Š“Š»Ń Ń–Š½ŃˆŠøŃ… мов і/або Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚Šø не в Гокері.", + "credit": "Цей сервіс Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” qpdf та Tesseract Š“Š»Ń OCR.", + "submit": "ŠžŠ±Ń€Š¾Š±ŠŗŠ° PDF Š· OCR" + }, + "extractImages": { + "tags": "Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń,фото,Š·Š±ŠµŃ€ŠµŠ¶ŠµŠ½Š½Ń,архів,zip,Š·Š°Ń…Š¾ŠæŠ»ŠµŠ½Š½Ń,Š·Š°Ń…Š¾ŠæŠ»ŠµŠ½Š½Ń", + "title": "Š’ŠøŃ‚ŃŠ³Š½ŃƒŃ‚Šø Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "header": "Š’ŠøŃ‚ŃŠ³Š½ŃƒŃ‚Šø Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "selectText": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ формат Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń Š“Š»Ń ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń Š²ŠøŃ‚ŃŠ³Š½ŃƒŃ‚ŠøŃ… Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŃŒ у", + "allowDuplicates": "Зберігати Š“ŃƒŠ±Š»Ń–ŠŗŠ°Ń‚Šø Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŃŒ", + "submit": "Š’ŠøŃ‚ŃŠ³Š½ŃƒŃ‚Šø" + }, + "pdfToPDFA": { + "tags": "архів,Говгостроковий,станГартний,ŠŗŠ¾Š½Š²ŠµŃ€ŃŃ–Ń,Š·Š±ŠµŃ€Ń–Š³Š°Š½Š½Ń,ŠŗŠ¾Š½ŃŠµŃ€Š²Š°Ń†Ń–Ń", + "title": "PDF в PDF/A", + "header": "PDF в PDF/A", + "credit": "Цей сервіс Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” libreoffice Š“Š»Ń ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń у формат PDF/A", + "submit": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø", + "tip": "ŠŠ°Ń€Š°Š·Ń– не ŠæŃ€Š°Ń†ŃŽŃ” Š“Š»Ń ŠŗŃ–Š»ŃŒŠŗŠ¾Ń… вхіГних файлів оГночасно", + "outputFormat": "ВихіГний формат", + "pdfWithDigitalSignature": "Цей PDF Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ має цифровий піГпис. Цей піГпис буГе виГалений у Š½Š°ŃŃ‚ŃƒŠæŠ½Š¾Š¼Ńƒ кроці." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń,формат,ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń,офіс,microsoft,docfile", + "title": "PDF в Word", + "header": "PDF в Word", + "selectText": { + "1": "Формат вихіГного Ń„Š°Š¹Š»Ńƒ" + }, + "credit": "Цей сервіс Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” LibreOffice Š“Š»Ń ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń файлів.", + "submit": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø" + }, + "PDFToPresentation": { + "tags": "слайГи,ŠæŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†Ń–Ń,офіс,майкрософт", + "title": "PDF в ŠŸŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†Ń–ŃŽ", + "header": "PDF в ŠŸŃ€ŠµŠ·ŠµŠ½Ń‚Š°Ń†Ń–ŃŽ", + "selectText": { + "1": "Формат вихіГного Ń„Š°Š¹Š»Ńƒ" + }, + "credit": "Цей сервіс Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” LibreOffice Š“Š»Ń ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń файлів.", + "submit": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø" + }, + "PDFToText": { + "tags": "richformat,richtextformat,формат rich text,rtf", + "title": "PDF в Text/RTF", + "header": "PDF в Text/RTF", + "selectText": { + "1": "Формат вихіГного Ń„Š°Š¹Š»Ńƒ" + }, + "credit": "Цей сервіс Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” LibreOffice Š“Š»Ń ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń файлів.", + "submit": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø" + }, + "PDFToHTML": { + "tags": "веб-контент,Š·Ń€ŃƒŃ‡Š½ŠøŠ¹ Š“Š»Ń ŠæŠµŃ€ŠµŠ³Š»ŃŠ“Ńƒ", + "title": "PDF в HTML", + "header": "PDF в HTML", + "credit": "Цей сервіс Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” pdftohtml Š“Š»Ń ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń файлів.", + "submit": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø" + }, + "PDFToXML": { + "tags": "Š²ŠøŠ»ŃƒŃ‡ŠµŠ½Š½Ń Ганих,ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Š¾Š²Š°Š½ŠøŠ¹ вміст,Š²Š·Š°Ń”Š¼Š¾Š“Ń–Ń,ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń,ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń", + "title": "PDF в XML", + "header": "PDF в XML", + "credit": "Цей сервіс Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” LibreOffice Š“Š»Ń ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń файлів.", + "submit": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø" + }, + "ScannerImageSplit": { + "tags": "окремий,автоматичне Š²ŠøŠ·Š½Š°Ń‡ŠµŠ½Š½Ń,ŃŠŗŠ°Š½ŃƒŠ²Š°Š½Š½Ń,ŠŗŃ–Š»ŃŒŠŗŠ° фотографій,ŃƒŠæŠ¾Ń€ŃŠ“ŠŗŃƒŠ²Š°Š½Š½Ń", + "selectText": { + "1": "ŠŸŠ¾Ń€Š¾Š³Š¾Š²ŠøŠ¹ ŠŗŃƒŃ‚:", + "2": "Š’ŃŃ‚Š°Š½Š¾Š²Š»ŃŽŃ” Š¼Ń–Š½Ń–Š¼Š°Š»ŃŒŠ½ŠøŠ¹ Š°Š±ŃŠ¾Š»ŃŽŃ‚Š½ŠøŠ¹ ŠŗŃƒŃ‚, необхіГний Š“Š»Ń ŠæŠ¾Š²Š¾Ń€Š¾Ń‚Ńƒ Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń (за Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼: 10).", + "3": "Š¢Š¾Š»ŠµŃ€Š°Š½Ń‚Š½Ń–ŃŃ‚ŃŒ:", + "4": "Визначає Гіапазон зміни ŠŗŠ¾Š»ŃŒŠ¾Ń€Ńƒ навколо ŠæŠµŃ€ŠµŠ“Š±Š°Ń‡ŃƒŠ²Š°Š½Š¾Š³Š¾ ŠŗŠ¾Š»ŃŒŠ¾Ń€Ńƒ Ń„Š¾Š½Ńƒ (за Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼: 30).", + "5": "ŠœŃ–Š½Ń–Š¼Š°Š»ŃŒŠ½Š° площа:", + "6": "Š’ŃŃ‚Š°Š½Š¾Š²Š»ŃŽŃ” Š¼Ń–Š½Ń–Š¼Š°Š»ŃŒŠ½ŠøŠ¹ поріг площі Š“Š»Ń фотографії (за Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼: 10000).", + "7": "ŠœŃ–Š½Ń–Š¼Š°Š»ŃŒŠ½Š° площа ŠŗŠ¾Š½Ń‚ŃƒŃ€Ńƒ:", + "8": "Š’ŃŃ‚Š°Š½Š¾Š²Š»ŃŽŃ” Š¼Ń–Š½Ń–Š¼Š°Š»ŃŒŠ½ŠøŠ¹ поріг площі ŠŗŠ¾Š½Ń‚ŃƒŃ€Ńƒ Š“Š»Ń фотографії", + "9": "Розмір рамки:", + "10": "Š’ŃŃ‚Š°Š½Š¾Š²Š»ŃŽŃ” розмір ГоГаваної та Š²ŠøŠ“Š°Š»ŃŠ½Š¾Ń— рамки, щоб запобігти ŠæŠ¾ŃŠ²Ń– білих рамок на вихоГі (за Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼: 1)." + }, + "info": "Python не встановлено. Він необхіГний роботи." + }, + "sign": { + "tags": "Š°Š²Ń‚Š¾Ń€ŠøŠ·ŃƒŠ²Š°Ń‚Šø,ініціали,намальований-піГпис,текстовий-піГпис,Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń-піГпис", + "title": "ŠŸŃ–Š“ŠæŠøŃ", + "header": "ŠŸŃ–Š“ŠæŠøŃŠ°Ń‚Šø PDF", + "upload": "Завантажити Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "draw": "ŠŠ°Š¼Š°Š»ŃŽŠ²Š°Ń‚Šø піГпис", + "text": "ВвіГ Ń‚ŠµŠŗŃŃ‚Ńƒ", + "clear": "ŠžŃ‡ŠøŃŃ‚ŠøŃ‚Šø", + "add": "ДоГати", + "saved": "Збережені піГписи", + "save": "Зберегти піГпис", + "personalSigs": "ŠžŃŠ¾Š±ŠøŃŃ‚Ń– піГписи", + "sharedSigs": "Š—Š°Š³Š°Š»ŃŒŠ½Ń– піГписи", + "noSavedSigs": "Збережені піГписи не знайГено", + "addToAll": "ДоГати на всі сторінки", + "delete": "ВиГалити", + "first": "ŠŸŠµŃ€ŃˆŠ° сторінка", + "last": "ŠžŃŃ‚Š°Š½Š½Ń сторінка", + "next": "ŠŠ°ŃŃ‚ŃƒŠæŠ½Š° сторінка", + "previous": "ŠŸŠ¾ŠæŠµŃ€ŠµŠ“Š½Ń сторінка", + "maintainRatio": "ŠŸŠµŃ€ŠµŠŗŠ»ŃŽŃ‡ŠøŃ‚Šø Š·Š±ŠµŃ€ŠµŠ¶ŠµŠ½Š½Ń пропорцій", + "undo": "Š”ŠŗŠ°ŃŃƒŠ²Š°Ń‚Šø", + "redo": "ŠŸŠ¾Š²Ń‚Š¾Ń€ŠøŃ‚Šø" + }, + "flatten": { + "tags": "flatten,статичний,Š“ŠµŠ·Š°ŠŗŃ‚ŠøŠ²ŃƒŠ²Š°Ń‚Šø,неінтерактивний, ŃƒŠæŠ¾Ń€ŃŠ“ŠŗŃƒŠ²Š°Ń‚Šø", + "title": "Š—Š³Š»Š°Š“Š¶ŃƒŠ²Š°Š½Š½Ń", + "header": "Š—Š³Š»Š°Š“Š¶ŃƒŠ²Š°Š½Š½Ń PDF", + "flattenOnlyForms": "ЗглаГити Ń‚Ń–Š»ŃŒŠŗŠø форми", + "submit": "ЗглаГити" + }, + "repair": { + "tags": "виправити,віГновити,виправити,віГновити", + "title": "Ремонт", + "header": "Ремонт PDF", + "submit": "Š ŠµŠ¼Š¾Š½Ń‚ŃƒŠ²Š°Ń‚Šø" + }, + "removeBlanks": { + "tags": "Š¾Ń‡ŠøŃ‰ŠµŠ½Š½Ń,ŃƒŠæŠ¾Ń€ŃŠ“ŠŗŃƒŠ²Š°Š½Š½Ń,без Š²Š¼Ń–ŃŃ‚Ńƒ,ŃƒŠæŠ¾Ń€ŃŠ“ŠŗŃƒŠ²Š°Š½Š½Ń", + "title": "ВиГалити порожні", + "header": "ВиГалити порожні сторінки", + "threshold": "ŠŸŠ¾Ń€Ń–Š³:", + "thresholdDesc": "ŠŸŠ¾Ń€Ń–Š³ Š“Š»Ń Š²ŠøŠ·Š½Š°Ń‡ŠµŠ½Š½Ń того, Š½Š°ŃŠŗŃ–Š»ŃŒŠŗŠø білим має Š±ŃƒŃ‚Šø білий ŠæŃ–ŠŗŃŠµŠ»ŃŒ", + "whitePercent": "ВіГсоток білого (%):", + "whitePercentDesc": "Š—Š°Š³Š°Š»ŃŒŠ½ŠøŠ¹ віГсоток білого на сторінці, Š“Š»Ń Š²ŠøŠ“Š°Š»ŠµŠ½Š½Ń", + "submit": "ВиГалити порожні" + }, + "removeAnnotations": { + "tags": "коментарі,Š²ŠøŠ“Ń–Š»ŠµŠ½Š½Ń,примітки,розмітка,Š²ŠøŠ“Š°Š»ŠµŠ½Š½Ń", + "title": "ВиГалити анотації", + "header": "ВиГалити анотації", + "submit": "ВиГалити" + }, + "compare": { + "tags": "Š“ŠøŃ„ŠµŃ€ŠµŠ½Ń†Ń–Š°Ń†Ń–Ń,контраст,зміни,аналіз", + "title": "ŠŸŠ¾Ń€Ń–Š²Š½ŃŠ½Š½Ń", + "header": "ŠŸŠ¾Ń€Ń–Š²Š½ŃŠ½Š½Ń PDF", + "highlightColor": { + "1": "ŠšŠ¾Š»Ń–Ń€ Š²ŠøŠ“Ń–Š»ŠµŠ½Š½Ń 1:", + "2": "ŠšŠ¾Š»Ń–Ń€ Š²ŠøŠ“Ń–Š»ŠµŠ½Š½Ń 2:" + }, + "document": { + "1": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ 1", + "2": "Š”Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ 2" + }, + "submit": "ŠŸŠ¾Ń€Ń–Š²Š½ŃŃ‚Šø", + "complex": { + "message": "ŠžŠ“ŠøŠ½ або обиГва наГані Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šø є великими файлами, Ń‚Š¾Ń‡Š½Ń–ŃŃ‚ŃŒ ŠæŠ¾Ń€Ń–Š²Š½ŃŠ½Š½Ń може Š±ŃƒŃ‚Šø знижена" + }, + "large": { + "file": { + "message": "ŠžŠ“ŠøŠ½ або обиГва наГані Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šø занаГто великі Š“Š»Ń обробки" + } + }, + "no": { + "text": { + "message": "Вибрані PDF-файли не Š¼Ń–ŃŃ‚ŃŃ‚ŃŒ текстового Š²Š¼Ń–ŃŃ‚Ńƒ. Š‘ŃƒŠ“ŃŒ ласка, Š²ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ PDF-файли Š· текстом Š“Š»Ń ŠæŠ¾Ń€Ń–Š²Š½ŃŠ½Š½Ń." + } + } + }, + "certSign": { + "tags": "Š°Š²Ń‚ŠµŠ½Ń‚ŠøŃ„Ń–ŠŗŠ°Ń†Ń–Ń,pem,p12,офіційний,ŃˆŠøŃ„Ń€ŃƒŠ²Š°Š½Š½Ń", + "title": "ŠŸŃ–Š“ŠæŠøŃ сертифікатом", + "header": "ŠŸŃ–Š“ŠæŠøŃˆŃ–Ń‚ŃŒ PDF своїм сертифікатом (робота в процесі)", + "selectPDF": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ файл PDF Š“Š»Ń ŠæŃ–Š“ŠæŠøŃŃƒ:", + "jksNote": "ŠŸŃ€ŠøŠ¼Ń–Ń‚ŠŗŠ°: Якщо ваш тип сертифіката не зазначений нижче, буГь ласка, ŠŗŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ¹Ń‚Šµ його в файл сховища Java Keystore (.jks), Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃŽŃ‡Šø ŃƒŃ‚ŠøŠ»Ń–Ń‚Ńƒ команГного Ń€ŃŠ“ŠŗŠ° keytool. ŠŸŠ¾Ń‚Ń–Š¼ Š²ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ Š¾ŠæŃ†Ń–ŃŽ Ń„Š°Š¹Š»Ńƒ .jks нижче.", + "selectKey": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ файл закритого ŠŗŠ»ŃŽŃ‡Š° (формат PKCS#8, може Š±ŃƒŃ‚Šø .pem або .der):", + "selectCert": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ файл сертифіката (формат X.509, може Š±ŃƒŃ‚Šø .pem або .der):", + "selectP12": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ файл сховища ŠŗŠ»ŃŽŃ‡Ń–в PKCS#12 (.p12 або .pfx) (необов'ŃŠ·ŠŗŠ¾Š²Š¾, ŃŠŗŃ‰Š¾ він наГаний, він повинен містити ваш закритий ŠŗŠ»ŃŽŃ‡ і сертифікат):", + "selectJKS": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ файл сховища Java Keystore (.jks або .keystore):", + "certType": "Тип сертифіката", + "password": "Š’Š²ŠµŠ“Ń–Ń‚ŃŒ ŠæŠ°Ń€Š¾Š»ŃŒ Го сховища ŠŗŠ»ŃŽŃ‡Ń–в або особистого ŠŗŠ»ŃŽŃ‡Š° (ŃŠŗŃ‰Š¾ є):", + "showSig": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø піГпис", + "reason": "ŠŸŃ€ŠøŃ‡ŠøŠ½Š°", + "location": "ŠœŃ–ŃŃ†ŠµŠ·Š½Š°Ń…Š¾Š“Š¶ŠµŠ½Š½Ń", + "name": "Ім'я", + "showLogo": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø логотип", + "submit": "ŠŸŃ–Š“ŠæŠøŃŠ°Ń‚Šø PDF" + }, + "removeCertSign": { + "tags": "Š°Š²Ń‚ŠµŠ½Ń‚ŠøŃ„Ń–ŠŗŠ°Ń†Ń–Ń,pem,p12,офіційний,Ń€Š¾Š·ŃˆŠøŃ„Ń€ŃƒŠ²Š°Ń‚Šø", + "title": "Š’ŠøŠ“Š°Š»ŠµŠ½Š½Ń ŠæŃ–Š“ŠæŠøŃŃƒ сертифікатом", + "header": "Š’ŠøŠ“Š°Š»ŠµŠ½Š½Ń ŠæŃ–Š“ŠæŠøŃŃƒ сертифікатом Š· PDF Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ńƒ", + "selectPDF": "ŠžŠ±ŠµŃ€Ń–Ń‚ŃŒ PDF-файл:", + "submit": "ВиГалити піГпис" + }, + "pageLayout": { + "tags": "об'єГнати,скласти,єГиний ŠæŠµŃ€ŠµŠ³Š»ŃŠ“,ŃƒŠæŠ¾Ń€ŃŠ“ŠŗŃƒŠ²Š°Ń‚Šø", + "title": "ŠœŠ½Š¾Š³Š¾ŃŃ‚Š¾Ń€Ń–Š½ŠŗŠ¾Š²ŠøŠ¹ макет", + "header": "ŠœŠ½Š¾Š³Š¾ŃŃ‚Š¾Ń€Ń–Š½ŠŗŠ¾Š²ŠøŠ¹ макет", + "pagesPerSheet": "Дторінок на оГному Š°Ń€ŠŗŃƒŃˆŃ–:", + "addBorder": "ДоГати рамки", + "submit": "ВіГправити" + }, + "scalePages": { + "tags": "змінити розмір,змінити,розмір,Š°Š“Š°ŠæŃ‚ŃƒŠ²Š°Ń‚Šø", + "title": "Š’Ń–Š“Ń€ŠµŠ³ŃƒŠ»ŃŽŠ²Š°Ń‚Šø Š¼Š°ŃŃˆŃ‚Š°Š± сторінки", + "header": "Š’Ń–Š“Ń€ŠµŠ³ŃƒŠ»ŃŽŠ²Š°Ń‚Šø Š¼Š°ŃŃˆŃ‚Š°Š± сторінки", + "pageSize": "Розмір сторінки Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š°.", + "keepPageSize": "ŠžŃ€ŠøŠ³Ń–Š½Š°Š»ŃŒŠ½ŠøŠ¹ розмір", + "scaleFactor": "Š Ń–Š²ŠµŠ½ŃŒ Š¼Š°ŃŃˆŃ‚Š°Š±ŃƒŠ²Š°Š½Š½Ń (обрізки) сторінки.", + "submit": "ВіГправити" + }, + "add-page-numbers": { + "tags": "розбити на сторінки,позначити,ŃƒŠæŠ¾Ń€ŃŠ“ŠŗŃƒŠ²Š°Ń‚Šø,Ń–Š½Š“ŠµŠŗŃŃƒŠ²Š°Ń‚Šø" + }, + "auto-rename": { + "tags": "автоматичне Š²ŠøŠ·Š½Š°Ń‡ŠµŠ½Š½Ń,на основі заголовка,Š¾Ń€Š³Š°Š½Ń–Š·Š°Ń†Ń–Ń,зміна міток", + "title": "Автоматичне ŠæŠµŃ€ŠµŠ¹Š¼ŠµŠ½ŃƒŠ²Š°Š½Š½Ń", + "header": "Автоматичне ŠæŠµŃ€ŠµŠ¹Š¼ŠµŠ½ŃƒŠ²Š°Š½Š½Ń PDF", + "submit": "Автоматичне ŠæŠµŃ€ŠµŠ¹Š¼ŠµŠ½ŃƒŠ²Š°Š½Š½Ń" + }, + "adjust-contrast": { + "tags": "ŠŗŠ¾Ń€ŠµŠŗŃ†Ń–Ń ŠŗŠ¾Š»ŃŒŠ¾Ń€Ńƒ,Š½Š°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń,зміна,ŠæŠ¾ŠŗŃ€Š°Ń‰ŠµŠ½Š½Ń" + }, + "crop": { + "tags": "обрізати,Š·Š¼ŠµŠ½ŃˆŃƒŠ²Š°Ń‚Šø,Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Ń‚Šø,Ń„Š¾Ń€Š¼ŃƒŠ²Š°Ń‚Šø", + "title": "ŠžŠ±Ń€Ń–Š·Š°Ń‚Šø", + "header": "ŠžŠ±Ń€Ń–Š·Š°Ń‚Šø PDF-файл", + "submit": "ŠŠ°Š“Ń–ŃŠ»Š°Ń‚Šø" + }, + "autoSplitPDF": { + "tags": "на основі qr,віГокремити,ŃŠŗŠ°Š½ŃƒŠ²Š°Ń‚Šø сегмент,ŃƒŠæŠ¾Ń€ŃŠ“ŠŗŃƒŠ²Š°Ń‚Šø", + "title": "Автоматичне Ń€Š¾Š·Š“Ń–Š»ŠµŠ½Š½Ń PDF", + "header": "Автоматичне Ń€Š¾Š·Š“Ń–Š»ŠµŠ½Š½Ń PDF", + "description": "Š”Ń€ŃƒŠŗ, вставка, ŃŠŗŠ°Š½ŃƒŠ²Š°Š½Š½Ń, Š·Š°Š²Š°Š½Ń‚Š°Š¶ŠµŠ½Š½Ń і Š“Š¾Š·Š²Š¾Š»ŃŒŃ‚Šµ нам автоматично розГілити Š²Š°ŃˆŃ– Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šø. ŠŠµ ŠæŠ¾Ń‚Ń€ŠµŠ±ŃƒŃ” Ń€ŃƒŃ‡Š½Š¾Š³Š¾ ŃŠ¾Ń€Ń‚ŃƒŠ²Š°Š½Š½Ń.", + "selectText": { + "1": "Š”Ń€ŃƒŠŗ ŠŗŃ–Š»ŃŒŠŗŠ¾Ń… окремих Š°Ń€ŠŗŃƒŃˆŃ–Š² (піГійГе чорно-білий варіант).", + "2": "Š”ŠŗŠ°Š½ŃƒŠ¹Ń‚Šµ всі Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Šø оГночасно, Š²ŃŃ‚Š°Š²Š»ŃŃŽŃ‡Šø між ними Ń€Š¾Š·Š“Ń–Š»ŃŒŠ½ŠøŠ¹ Š°Ń€ŠŗŃƒŃˆ.", + "3": "Завантажте оГин великий віГсканований PDF-файл, і нехай Stirling PDF Š·Ń€Š¾Š±ŠøŃ‚ŃŒ все Ń–Š½ŃˆŠµ.", + "4": "Š Š¾Š·Š“Ń–Š»ŃŒŠ½Ń– сторінки автоматично Š²ŠøŃŠ²Š»ŃŃŽŃ‚ŃŒŃŃ і Š²ŠøŠ“Š°Š»ŃŃŽŃ‚ŃŒŃŃ, Š·Š°Š±ŠµŠ·ŠæŠµŃ‡ŃƒŃŽŃ‡Šø Š°ŠŗŃƒŃ€Š°Ń‚Š½ŠøŠ¹ кінцевий Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚." + }, + "formPrompt": "ŠŠ°Š“Ń–ŃŠ»Š°Ń‚Šø PDF-файл, що Š¼Ń–ŃŃ‚ŠøŃ‚ŃŒ Ń€Š¾Š·Š“Ń–Š»ŃŒŠ½Ń– сторінки Stirling-PDF:", + "duplexMode": "Š”ŃƒŠæŠ»ŠµŠŗŃŠ½ŠøŠ¹ режим (ŃŠŗŠ°Š½ŃƒŠ²Š°Š½Š½Ń ŃŠæŠµŃ€ŠµŠ“Ńƒ і ззаГу)", + "dividerDownload2": "Завантажити 'Auto Splitter Divider (with instructions).pdf'", + "submit": "ŠŠ°Š“Ń–ŃŠ»Š°Ń‚Šø" + }, + "sanitizePdf": { + "tags": "чистка,безпека,безпечні,Š²Ń–Š“Š“Š°Š»ŠµŠ½Š½Ń загроз" + }, + "URLToPDF": { + "tags": "веб-Š·Š°Ń…Š¾ŠæŠ»ŠµŠ½Š½Ń,Š·Š±ŠµŃ€ŠµŠ¶ŠµŠ½Š½Ń сторінки,веб-Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚,архів", + "title": "URL у PDF", + "header": "URL у PDF", + "submit": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø", + "credit": "Š’ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” WeasyPrint" + }, + "HTMLToPDF": { + "tags": "розмітка,веб-контент,ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń,ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†Ń–Ń", + "title": "HTML у PDF", + "header": "HTML у PDF", + "help": "ŠŸŃ€ŠøŠ¹Š¼Š°Ń” файли HTML та ZIP-файли, що Š¼Ń–ŃŃ‚ŃŃ‚ŃŒ html/css/Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń тощо.", + "submit": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø", + "credit": "Š’ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” WeasyPrint", + "zoom": "Š Ń–Š²ŠµŠ½ŃŒ Š¼Š°ŃŃˆŃ‚Š°Š±ŃƒŠ²Š°Š½Š½Ń Š“Š»Ń Š²Ń–Š“Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń веб-ŃŠ°Š¹Ń‚Ńƒ.", + "pageWidth": "Ширина сторінки в сантиметрах. (ŠŸŠ¾Ń€Š¾Š¶Š½ŃŒŠ¾ - за Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼)", + "pageHeight": "Висота сторінки в сантиметрах. (ŠŸŠ¾Ń€Š¾Š¶Š½ŃŒŠ¾ - за Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼)", + "marginTop": "Верхній Š²Ń–Š“ŃŃ‚ŃƒŠæ сторінки в міліметрах. (ŠŸŠ¾Ń€Š¾Š¶Š½ŃŒŠ¾ - за Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼)", + "marginBottom": "ŠŠøŠ¶Š½Ń–Š¹ Š²Ń–Š“ŃŃ‚ŃƒŠæ сторінки в міліметрах. (ŠŸŠ¾Ń€Š¾Š¶Š½ŃŒŠ¾ - за Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼)", + "marginLeft": "Лівий Š²Ń–Š“ŃŃ‚ŃƒŠæ сторінки в міліметрах. (ŠŸŠ¾Ń€Š¾Š¶Š½ŃŒŠ¾ - за Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼)", + "marginRight": "ŠŸŃ€Š°Š²ŠøŠ¹ Š²Ń–Š“ŃŃ‚ŃƒŠæ сторінки в міліметрах. (ŠŸŠ¾Ń€Š¾Š¶Š½ŃŒŠ¾ - за Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼)", + "printBackground": "ВіГтворити фон веб-сайтів.", + "defaultHeader": "Š’ŠŗŠ»ŃŽŃ‡ŠøŃ‚Šø заголовок за Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼ (Ім'я та номер сторінки)", + "cssMediaType": "Змінити тип меГіа CSS сторінки.", + "none": "ŠŠµŠ¼Š°Ń”", + "print": "Š”Ń€ŃƒŠŗ", + "screen": "Екран" + }, + "MarkdownToPDF": { + "tags": "розмітка,веб-контент,ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń,ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†Ń–Ń", + "title": "Markdown в PDF", + "header": "Markdown в PDF", + "submit": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø", + "help": "Робота в процесі", + "credit": "Š’ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "розмітка,веб-вміст,Ń‚Ń€Š°Š½ŃŃ„Š¾Ń€Š¼Š°Ń†Ń–Ń,ŠæŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń,md", + "title": "PDF в Markdown", + "header": "PDF в Markdown", + "submit": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø" + }, + "getPdfInfo": { + "tags": "Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–Ń,Гані,статистика,статистика", + "title": "ŠžŃ‚Ń€ŠøŠ¼Š°Ń‚Šø Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–ŃŽ в PDF", + "header": "ŠžŃ‚Ń€ŠøŠ¼Š°Ń‚Šø Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–ŃŽ в PDF", + "submit": "ŠžŃ‚Ń€ŠøŠ¼Š°Ń‚Šø Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–ŃŽ", + "downloadJson": "Завантажити JSON" + }, + "extractPage": { + "tags": "екстракт" + }, + "PdfToSinglePage": { + "tags": "оГну ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ" + }, + "showJS": { + "tags": "js", + "title": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø JavaScript", + "header": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø JavaScript", + "downloadJS": "Завантажити JavaScript", + "submit": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø" + }, + "autoRedact": { + "tags": "Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Ń‚Šø,приховати,затемнити,чорний,маркер,приховано", + "title": "Автоматичне Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń", + "header": "Автоматичне Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń", + "colorLabel": "ŠšŠ¾Š»Ń–Ń€", + "textsToRedactLabel": "Текст Š“Š»Ń ŠæŃ€ŠøŃ…Š¾Š²ŃƒŠ²Š°Š½Š½Ń (кожен Ń€ŃŠ“Š¾Šŗ окремо)", + "textsToRedactPlaceholder": "наприклаГ \\nŠšŠ¾Š½Ń„Ń–Š“ŠµŠ½Ń†Ń–Š¹Š½Š¾ \\nЦілком таємно", + "useRegexLabel": "Š’ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚Šø Ń€ŠµŠ³ŃƒŠ»ŃŃ€Š½Ń– вирази", + "wholeWordSearchLabel": "Пошук цілих слів", + "customPaddingLabel": "ДоГаткове Š·Š°ŠæŠ¾Š²Š½ŠµŠ½Š½Ń за ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń†ŃŒŠŗŠøŠ¼ Š·Š½Š°Ń‡ŠµŠ½Š½ŃŠ¼", + "convertPDFToImageLabel": "ŠŸŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠøŃ‚Šø PDF в Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń PDF (Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ”Ń‚ŃŒŃŃ Š“Š»Ń Š²ŠøŠ“Š°Š»ŠµŠ½Š½Ń Ń‚ŠµŠŗŃŃ‚Ńƒ поза межами)", + "submitButton": "ŠŠ°Š“Ń–ŃŠ»Š°Ń‚Šø" + }, + "redact": { + "tags": "Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Ń‚Šø,приховати,затемнити,чорний,маркер,приховано,Š²Ń€ŃƒŃ‡Š½Ńƒ", + "title": "Š ŃƒŃ‡Š½Šµ Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń", + "header": "Š ŃƒŃ‡Š½Šµ Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń", + "submit": "Š ŠµŠ“Š°Š³ŃƒŠ²Š°Ń‚Šø", + "textBasedRedaction": "Š ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń на основі Ń‚ŠµŠŗŃŃ‚Ńƒ", + "pageBasedRedaction": "Š ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń на основі сторінок", + "convertPDFToImageLabel": "ŠŸŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠøŃ‚Šø PDF на PDF-Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń (Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ”Ń‚ŃŒŃŃ Š“Š»Ń Š²ŠøŠ“Š°Š»ŠµŠ½Š½Ń Ń‚ŠµŠŗŃŃ‚Ńƒ за Ń€Š°Š¼ŠŗŠ¾ŃŽ)", + "pageRedactionNumbers": { + "title": "Дторінки", + "placeholder": "(наприклаГ, 1,2,8 або 4,7,12-16 або 2n-1)" + }, + "redactionColor": { + "title": "ŠšŠ¾Š»Ń–Ń€ Ń€ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń" + }, + "export": "Експорт", + "upload": "Завантажити", + "boxRedaction": "Š ŠµŠ“Š°Š³ŃƒŠ²Š°Š½Š½Ń Š¼Š°Š»ŃŽŠ²Š°Š½Š½ŃŠ¼ рамки", + "zoom": "ŠœŠ°ŃŃˆŃ‚Š°Š±", + "zoomIn": "Š—Š±Ń–Š»ŃŒŃˆŠøŃ‚Šø", + "zoomOut": "Š—Š¼ŠµŠ½ŃˆŠøŃ‚Šø", + "nextPage": "ŠŠ°ŃŃ‚ŃƒŠæŠ½Š° сторінка", + "previousPage": "ŠŸŠ¾ŠæŠµŃ€ŠµŠ“Š½Ń сторінка", + "toggleSidebar": "ŠŸŠµŃ€ŠµŠ¼ŠøŠŗŠ°Ń‚Šø Š±Ń–Ń‡Š½Ńƒ панель", + "showThumbnails": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø Š¼Ń–Š½Ń–Š°Ń‚ŃŽŃ€Šø", + "showDocumentOutline": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Ńƒ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Š° (поГвійне ŠŗŠ»Š°Ń†Š°Š½Š½Ń Š“Š»Ń Ń€Š¾Š·Š³Š¾Ń€Ń‚Š°Š½Š½Ń/Š·Š³Š¾Ń€Ń‚Š°Š½Š½Ń всіх елементів)", + "showAttatchments": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø Š²ŠŗŠ»Š°Š“ŠµŠ½Š½Ń", + "showLayers": "ŠŸŠ¾ŠŗŠ°Š·Š°Ń‚Šø ŃˆŠ°Ń€Šø (поГвійне ŠŗŠ»Š°Ń†Š°Š½Š½Ń Š“Š»Ń ŃŠŗŠøŠ“Š°Š½Š½Ń всіх ŃˆŠ°Ń€Ń–Š² Го ŃŃ‚Š°Š½Ńƒ за ŃƒŠ¼Š¾Š²Ń‡Š°Š½Š½ŃŠ¼)", + "colourPicker": "Вибір ŠŗŠ¾Š»ŃŒŠ¾Ń€Ńƒ", + "findCurrentOutlineItem": "Знайти поточний елемент ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Šø", + "applyChanges": "Š—Š°ŃŃ‚Š¾ŃŃƒŠ²Š°Ń‚Šø зміни" + }, + "tableExtraxt": { + "tags": "csv,Š²ŠøŠ“Š¾Š±ŃƒŃ‚Š¾Šŗ таблиці,Š²ŠøŠ»ŃƒŃ‡ŠµŠ½Š½Ń,ŠŗŠ¾Š½Š²ŠµŃ€Ń‚Š°Ń†Ń–Ń" + }, + "autoSizeSplitPDF": { + "tags": "pdf,розГілити,Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚,Š¾Ń€Š³Š°Š½Ń–Š·Š°Ń†Ń–Ń" + }, + "overlay-pdfs": { + "tags": "Š½Š°ŠŗŠ»Š°Š“Š°Š½Š½Ń", + "header": "ŠŠ°ŠŗŠ»Š°Š“ŠµŠ½Š½Ń файлів PDF", + "baseFile": { + "label": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ основний файл PDF" + }, + "overlayFiles": { + "label": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ файл(Šø) Š“Š»Ń Š½Š°ŠŗŠ»Š°Š“ŠµŠ½Š½Ń" + }, + "mode": { + "label": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ режим Š½Š°ŠŗŠ»Š°Š“ŠµŠ½Š½Ń", + "sequential": "ŠŸŠ¾ŃŠ»Ń–Š“Š¾Š²Š½Šµ Š½Š°ŠŗŠ»Š°Š“ŠµŠ½Š½Ń", + "interleaved": "ŠŸŠµŃ€ŠµŃ…Ń€ŠµŃŠ½Šµ Š½Š°ŠŗŠ»Š°Š“ŠµŠ½Š½Ń", + "fixedRepeat": "ŠŠ°ŠŗŠ»Š°Š“ŠµŠ½Š½Ń Š· фіксованим ŠæŠ¾Š²Ń‚Š¾Ń€ŠµŠ½Š½ŃŠ¼" + }, + "counts": { + "label": "ŠšŃ–Š»ŃŒŠŗŃ–ŃŃ‚ŃŒ наклаГень (Š“Š»Ń Ń€ŠµŠ¶ŠøŠ¼Ńƒ Š· фіксованим ŠæŠ¾Š²Ń‚Š¾Ń€ŠµŠ½Š½ŃŠ¼)", + "placeholder": "Š’Š²ŠµŠ“Ń–Ń‚ŃŒ через кому ŠŗŃ–Š»ŃŒŠŗŃ–ŃŃ‚ŃŒ ŠæŠ¾Š²Ń‚Š¾Ń€ŠµŠ½ŃŒ (наприклаГ, 2,3,1)" + }, + "position": { + "label": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ ŠæŠ¾Š·ŠøŃ†Ń–ŃŽ Š½Š°ŠŗŠ»Š°Š“ŠµŠ½Š½Ń", + "foreground": "ŠŠ°Š“ основним", + "background": "За основним" + }, + "submit": "ŠŠ°Š“Ń–ŃŠ»Š°Ń‚Šø" + }, + "split-by-sections": { + "tags": "розГіл Ń€Š¾Š·Š“Ń–Š»Ńƒ,Ń€Š¾Š·Š“Ń–Š»ŠµŠ½Š½Ń,Š½Š°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń", + "title": "РозГілити PDF за розГілами", + "header": "РозГілити PDF на секції", + "horizontal": { + "label": "Š“Š¾Ń€ŠøŠ·Š¾Š½Ń‚Š°Š»ŃŒŠ½Ń– розГіли", + "placeholder": "Š’Š²ŠµŠ“Ń–Ń‚ŃŒ ŠŗŃ–Š»ŃŒŠŗŃ–ŃŃ‚ŃŒ Š³Š¾Ń€ŠøŠ·Š¾Š½Ń‚Š°Š»ŃŒŠ½ŠøŃ… розГілів" + }, + "vertical": { + "label": "Š’ŠµŃ€Ń‚ŠøŠŗŠ°Š»ŃŒŠ½Ń– розГіли", + "placeholder": "Š’Š²ŠµŠ“Ń–Ń‚ŃŒ ŠŗŃ–Š»ŃŒŠŗŃ–ŃŃ‚ŃŒ Š²ŠµŃ€Ń‚ŠøŠŗŠ°Š»ŃŒŠ½ŠøŃ… розГілів" + }, + "submit": "РозГілити PDF", + "merge": "ŠžŠ±'єГнати в оГин PDF" + }, + "AddStampRequest": { + "tags": "ŃˆŃ‚Š°Š¼Šæ,ГоГати Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń,Ń†ŠµŠ½Ń‚Ń€Š°Š»ŃŒŠ½Šµ Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń,Š²Š¾Š“ŃŠ½ŠøŠ¹ знак,pdf,вставити,Š½Š°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Ń‚Šø", + "header": "ŠŸŠ¾ŃŃ‚Š°Š²ŠøŃ‚Šø ŠæŠµŃ‡Š°Ń‚ŠŗŃƒ на PDF", + "title": "ŠŸŠ¾ŃŃ‚Š°Š²ŠøŃ‚Šø ŠæŠµŃ‡Š°Ń‚ŠŗŃƒ на PDF", + "stampType": "Тип печатки", + "stampText": "Текст печатки", + "stampImage": "Š—Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń печатки", + "alphabet": "Алфавіт", + "fontSize": "Розмір ŃˆŃ€ŠøŃ„Ń‚Ńƒ/Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "rotation": "ŠžŠ±ŠµŃ€Ń‚Š°Š½Š½Ń", + "opacity": "ŠŸŃ€Š¾Š·Š¾Ń€Ń–ŃŃ‚ŃŒ", + "position": "ŠŸŠ¾Š·ŠøŃ†Ń–Ń", + "overrideX": "ŠŸŠµŃ€ŠµŠ²ŠøŠ·Š½Š°Ń‡ŠøŃ‚Šø ŠŗŠ¾Š¾Ń€Š“ŠøŠ½Š°Ń‚Ńƒ X", + "overrideY": "ŠŸŠµŃ€ŠµŠ²ŠøŠ·Š½Š°Ń‡ŠøŃ‚Šø ŠŗŠ¾Š¾Ń€Š“ŠøŠ½Š°Ń‚Ńƒ Y", + "customMargin": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń†ŃŒŠŗŠøŠ¹ Š²Ń–Š“ŃŃ‚ŃƒŠæ", + "customColor": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń†ŃŒŠŗŠøŠ¹ колір Ń‚ŠµŠŗŃŃ‚Ńƒ", + "submit": "ŠŠ°Š“Ń–ŃŠ»Š°Ń‚Šø" + }, + "removeImagePdf": { + "tags": "Š²ŠøŠ“Š°Š»ŠµŠ½Š½Ń Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń,операції Š·Ń– сторінками,серверна частина" + }, + "splitPdfByChapters": { + "tags": "поГіл,глави,заклаГки,Š¾Ń€Š³Š°Š½Ń–Š·Š°Ń†Ń–Ń" + }, + "validateSignature": { + "tags": "піГпис,перевірка,Š²Š°Š»Ń–Š“Š°Ń†Ń–Ń,pdf,сертифікат,цифровий піГпис,перевірка ŠæŃ–Š“ŠæŠøŃŃƒ,перевірка сертифіката", + "title": "ŠŸŠµŃ€ŠµŠ²Ń–Ń€ŠŗŠ° піГписів PDF", + "header": "ŠŸŠµŃ€ŠµŠ²Ń–Ń€ŠŗŠ° цифрових піГписів", + "selectPDF": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ піГписаний PDF-файл", + "submit": "ŠŸŠµŃ€ŠµŠ²Ń–Ń€ŠøŃ‚Šø піГписи", + "results": "Š ŠµŠ·ŃƒŠ»ŃŒŃ‚Š°Ń‚Ń‹ проверки", + "status": { + "_value": "Š”Ń‚Š°Ń‚ŃƒŃ", + "valid": "Дійна", + "invalid": "ŠŠµŠ“Ń–Š¹ŃŠ½Š°" + }, + "signer": "ŠŸŃ–Š“ŠæŠøŃŠ°Š½Ń‚", + "date": "Дата", + "reason": "ŠŸŃ€ŠøŃ‡ŠøŠ½Š°", + "location": "ŠœŠµŃŃ‚Š¾ŠæŠ¾Š»Š¾Š¶ŠµŠ½ŠøŠµ", + "noSignatures": "Š’ Ń†ŃŒŠ¾Š¼Ńƒ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ń– не знайГено цифрових піГписів", + "chain": { + "invalid": "ŠŸŠµŃ€ŠµŠ²Ń–Ń€ŠŗŠ° цепочки сертифікатів не уГалась - неможливо перевірити Š¾ŃŠ¾Š±ŠøŃŃ‚Ń–ŃŃ‚ŃŒ піГписанта" + }, + "trust": { + "invalid": "Дертифікат Š²Ń–Š“ŃŃƒŃ‚Š½Ń–Š¹ у Š“Š¾Š²Ń–Ń€ŠµŠ½Š¾Š¼Ńƒ сховищі - Гжерело не може Š±ŃƒŃ‚Šø перевірено" + }, + "cert": { + "expired": "Дрок Гії сертифіката Ń–ŃŃ‚ŠµŠŗŃƒ", + "revoked": "Дертифікат був отозван", + "info": "Š”Š²ŠµŠ“ŠµŠ½ŠøŃ про сертифікати", + "issuer": "Š˜Š·Š“Š°Ń‚ŠµŠ»ŃŒ", + "subject": "суб'єкт", + "serialNumber": "Дерийний номер", + "validFrom": "Дійсний Š·", + "validUntil": "Дійсний Го", + "algorithm": "Алгоритм", + "keySize": "Розмір ŠŗŠ»ŃŽŃ‡Š°", + "version": "Š’ŠµŃ€ŃŃ–Ń", + "keyUsage": "Š’ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń ŠŗŠ»ŃŽŃ‡Š°", + "selfSigned": "ДамопоГписанный", + "bits": "біт" + }, + "signature": { + "info": "Š†Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–Ń про піГписи", + "_value": "ПоГпись", + "mathValid": "ПоГпись математически корректна, ŠŠž:" + }, + "selectCustomCert": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ŃŃŒŠŗŠøŠ¹ файл сертифіката X.509 (ŠŠµŠ¾Š±Š¾Š²'ŃŠ·ŠŗŠ¾Š²Š¾)" + }, + "replace-color": { + "title": "Заміна-Ń–Š½Š²ŠµŃ€ŃŃ–Ń ŠŗŠ¾Š»ŃŒŠ¾Ń€Ńƒ", + "header": "Заміна-Ń–Š½Š²ŠµŃ€ŃŃ–Ń ŠŗŠ¾Š»ŃŒŠ¾Ń€Ńƒ PDF", + "selectText": { + "1": "ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€Šø заміни або інверсії ŠŗŠ¾Š»ŃŒŠ¾Ń€Ńƒ", + "2": "За Š·Š°Š¼Š¾Š²Ń‡ŃƒŠ²Š°Š½Š½ŃŠ¼ (ŠŗŠ¾Š»ŃŒŠ¾Ń€Šø високого Ń€Š¾Š·Š¼Š°Ń—Ń‚Ń‚Ń)", + "3": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Š»ŃŒŠ½ŠøŃ†ŃŒŠŗŃ– (Š½Š°ŃŃ‚Ń€Š¾ŃŽŠ²Š°Š½Ń– ŠŗŠ¾Š»ŃŒŠ¾Ń€Šø)", + "4": "Повна Ń–Š½Š²ŠµŃ€ŃŃ–Ń (Ń–Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø всі ŠŗŠ¾Š»ŃŒŠ¾Ń€Šø)", + "5": "ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€Šø високого Ń€Š¾Š·Š¼Š°Ń—Ń‚Ń‚Ń", + "6": "білий текст на Ń‡Š¾Ń€Š½Š¾Š¼Ńƒ тлі", + "7": "чорний текст на Š±Ń–Š»Š¾Š¼Ńƒ тлі", + "8": "жовтий текст на Ń‡Š¾Ń€Š½Š¾Š¼Ńƒ тлі", + "9": "зелений текст на Ń‡Š¾Ń€Š½Š¾Š¼Ńƒ тлі", + "10": "Вибрати колір Ń‚ŠµŠŗŃŃ‚Ńƒ", + "11": "Вибрати колір тла" + }, + "submit": "Замінити" + }, + "replaceColorPdf": { + "tags": "Заміна ŠŗŠ¾Š»ŃŒŠ¾Ń€Ńƒ, операції Š·Ń– сторінками, Дерверна частина" + }, + "login": { + "title": "Š’Ń…Ń–Š“", + "header": "Š’Ń…Ń–Š“", + "signin": "Увійти", + "rememberme": "Запам'ŃŃ‚Š°Ń‚Šø мене", + "invalid": "ŠŠµŠ“Ń–Š¹ŃŠ½Šµ ім'я ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° або ŠæŠ°Ń€Š¾Š»ŃŒ.", + "locked": "Š’Š°Ńˆ обліковий запис заблоковано.", + "signinTitle": "Š‘ŃƒŠ“ŃŒ ласка, ŃƒŠ²Ń–Š¹Š“Ń–Ń‚ŃŒ", + "ssoSignIn": "Увійти через єГиний вхіГ", + "oAuth2AutoCreateDisabled": "Автоматичне ŃŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° OAUTH2 Š’Š˜ŠœŠšŠŠ•ŠŠž", + "oAuth2AdminBlockedUser": "Š ŠµŃ”ŃŃ‚Ń€Š°Ń†Ń–Ń або вхіГ незареєстрованих ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š² наразі заборонено. Š‘ŃƒŠ“ŃŒ ласка, зв'ŃŠ¶Ń–Ń‚ŃŒŃŃ Š· аГміністратором.", + "oauth2RequestNotFound": "Запит на Š°Š²Ń‚Š¾Ń€ŠøŠ·Š°Ń†Ń–Ń не знайГено", + "oauth2InvalidUserInfoResponse": "ŠŠµŠ“Ń–Š¹ŃŠ½Š° Š²Ń–Š“ŠæŠ¾Š²Ń–Š“ŃŒ Š· Ń–Š½Ń„Š¾Ń€Š¼Š°Ń†Ń–Ń”ŃŽ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š°", + "oauth2invalidRequest": "ŠŠµŠ“Ń–Š¹ŃŠ½ŠøŠ¹ запит", + "oauth2AccessDenied": "Š”Š¾ŃŃ‚ŃƒŠæ заблоковано", + "oauth2InvalidTokenResponse": "ŠŠµŠ“Ń–Š¹ŃŠ½Š° Š²Ń–Š“ŠæŠ¾Š²Ń–Š“ŃŒ Š· токеном", + "oauth2InvalidIdToken": "ŠŠµŠ“Ń–Š¹ŃŠ½ŠøŠ¹ іГентифікаційний токен", + "relyingPartyRegistrationNotFound": "Š ŠµŃ”ŃŃ‚Ń€Š°Ń†Ń–ŃŽ Š“Š¾Š²Ń–Ń€ŃŃŽŃ‡Š¾Ń— сторони не знайГено", + "userIsDisabled": "ŠšŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡ Геактивовано, вхіГ Š· цим ім'ŃŠ¼ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Š° заблоковано. Š—Š²ŠµŃ€Š½Ń–Ń‚ŃŒŃŃ Го аГміністратора.", + "alreadyLoggedIn": "Š’Šø вже ŃƒŠ²Ń–Š¹ŃˆŠ»Šø Го", + "alreadyLoggedIn2": "пристроїв (а). Š‘ŃƒŠ“ŃŒ ласка, Š²ŠøŠ¹Š“Ń–Ń‚ŃŒ Ń–Š· цих пристроїв і ŃŠæŃ€Š¾Š±ŃƒŠ¹Ń‚Šµ знову.", + "toManySessions": "Š£ вас Гуже багато активних сесій", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF на оГну ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ", + "header": "PDF на оГну ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ", + "submit": "ŠŸŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠøŃ‚Šø на оГну ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ" + }, + "pageExtracter": { + "title": "Š’ŠøŠ“Š¾Š±ŃƒŃ‚Šø сторінки", + "header": "Š’ŠøŠ“Š¾Š±ŃƒŃ‚Šø сторінки", + "submit": "Š’ŠøŠ“Š¾Š±ŃƒŃ‚Šø", + "placeholder": "(наприклаГ 1,2,8 або 4,7,12-16 або 2n-1)" + }, + "sanitizePDF": { + "title": "Š”ŠµŠ·Ń–Š½Ń„ŠµŠŗŃ†Ń–Ń PDF", + "header": "Š”ŠµŠ·Ń–Š½Ń„ŠµŠŗŃ†Ń–Ń PDF Ń„Š°Š¹Š»Ńƒ", + "selectText": { + "1": "ВиГалити JavaScript", + "2": "ВиГалити Š²Š±ŃƒŠ“овані файли", + "3": "Remove XMP metadata", + "4": "ВиГалити ŠæŠ¾ŃŠøŠ»Š°Š½Š½Ń", + "5": "ВиГалити ŃˆŃ€ŠøŃ„Ń‚Šø", + "6": "Remove Document Info Metadata" + }, + "submit": "Š”ŠµŠ·Ń–Š½Ń„ŠµŠŗŃ†Ń–Ń" + }, + "adjustContrast": { + "title": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń контрастності", + "header": "ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń контрастності", + "contrast": "ŠšŠ¾Š½Ń‚Ń€Š°ŃŃ‚:", + "brightness": "ŠÆŃŠŗŃ€Š°Š²Ń–ŃŃ‚ŃŒ:", + "saturation": "ŠŠ°ŃŠøŃ‡ŠµŠ½Ń–ŃŃ‚ŃŒ:", + "download": "Завантажити" + }, + "compress": { + "title": "Š”Ń‚ŠøŃŠ½ŃƒŃ‚Šø", + "header": "Š”Ń‚ŠøŃŠ½ŃƒŃ‚Šø PDF", + "credit": "Š¦Ń служба Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” qpdf Š“Š»Ń ŃŃ‚ŠøŃŠ½ŠµŠ½Š½Ń/оптимізації PDF.", + "grayscale": { + "label": "Š—Š°ŃŃ‚Š¾ŃŃƒŠ²Š°Ń‚Šø віГтінки сірого Š“Š»Ń ŃŃ‚ŠøŃŠ½ŠµŠ½Š½Ń" + }, + "selectText": { + "1": { + "_value": "ŠŸŠ°Ń€Š°Š¼ŠµŃ‚Ń€Šø ŃŃ‚ŠøŃŠ½ŠµŠ½Š½Ń", + "1": "1-3 ŃŃ‚ŠøŃŠ½ŠµŠ½Š½Ń PDF,
4-6 невелике ŃŃ‚ŠøŃŠ½ŠµŠ½Š½Ń Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŃŒ,
7-9 посилене ŃŃ‚ŠøŃŠ½ŠµŠ½Š½Ń Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŃŒ (різко Š·Š½ŠøŠ·ŠøŃ‚ŃŒ ŃŠŗŃ–ŃŃ‚ŃŒ Š·Š¾Š±Ń€Š°Š¶ŠµŠ½ŃŒ)" + }, + "2": "Š Ń–Š²ŠµŠ½ŃŒ оптимізації:", + "4": "Автоматичний режим - автоматично Š½Š°Š»Š°ŃˆŃ‚Š¾Š²ŃƒŃ” ŃŠŗŃ–ŃŃ‚ŃŒ Š“Š»Ń Š¾Ń‚Ń€ŠøŠ¼Š°Š½Š½Ń PDF точного Ń€Š¾Š·Š¼Ń–Ń€Ńƒ", + "5": "ŠžŃ‡Ń–ŠŗŃƒŠ²Š°Š½ŠøŠ¹ розмір PDF (наприклаГ, 25 ŠœŠ‘, 10,8 ŠœŠ‘, 25 ŠšŠ‘)" + }, + "submit": "Š”Ń‚ŠøŃŠ½ŃƒŃ‚Šø" + }, + "decrypt": { + "passwordPrompt": "Цей файл захищений паролем. Š‘ŃƒŠ“ŃŒ ласка, Š²Š²ŠµŠ“Ń–Ń‚ŃŒ ŠæŠ°Ń€Š¾Š»ŃŒ:", + "cancelled": "ŠžŠæŠµŃ€Š°Ń†Ń–ŃŽ скасовано Š“Š»Ń PDF: {0}", + "noPassword": "ŠŠµ наГано ŠæŠ°Ń€Š¾Š»ŃŒ Š“Š»Ń Š·Š°ŃˆŠøŃ„Ń€Š¾Š²Š°Š½Š¾Š³Š¾ PDF: {0}", + "invalidPassword": "Š‘ŃƒŠ“ŃŒ ласка, ŃŠæŃ€Š¾Š±ŃƒŠ¹Ń‚Šµ ще раз Š· ŠæŃ€Š°Š²ŠøŠ»ŃŒŠ½ŠøŠ¼ паролем.", + "invalidPasswordHeader": "ŠŠµŠæŃ€Š°Š²ŠøŠ»ŃŒŠ½ŠøŠ¹ ŠæŠ°Ń€Š¾Š»ŃŒ або Š½ŠµŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŠ²Š°Š½Šµ ŃˆŠøŃ„Ń€ŃƒŠ²Š°Š½Š½Ń Š“Š»Ń PDF: {0}", + "unexpectedError": "Виникла помилка при обробці Ń„Š°Š¹Š»Ńƒ. Š‘ŃƒŠ“ŃŒ ласка, ŃŠæŃ€Š¾Š±ŃƒŠ¹Ń‚Šµ ще раз.", + "serverError": "Помилка сервера піГ час Ń€Š¾Š·ŃˆŠøŃ„Ń€Š¾Š²ŠŗŠø: {0}", + "success": "Файл ŃƒŃŠæŃ–ŃˆŠ½Š¾ Ń€Š¾Š·ŃˆŠøŃ„Ń€Š¾Š²Š°Š½Š¾." + }, + "multiTool-advert": { + "message": "Š¦Ń Ń„ŃƒŠ½ŠŗŃ†Ń–Ń також Š“Š¾ŃŃ‚ŃƒŠæŠ½Š° на Š½Š°ŃˆŃ–й сторінці Š¼ŃƒŠ»ŃŒŃ‚ŠøŃ–Š½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚Ńƒ. Š”ŠæŃ€Š¾Š±ŃƒŠ¹Ń‚Šµ її Š“Š»Ń покращеного посторінкового Ń–Š½Ń‚ŠµŃ€Ń„ŠµŠ¹ŃŃƒ та ГоГаткових можливостей!" + }, + "pageRemover": { + "title": "Š’ŠøŠ“Š°Š»ŠµŠ½Š½Ń сторінок", + "header": "Š’ŠøŠ“Š°Š»ŠµŠ½Š½Ń сторінок PDF", + "pagesToDelete": "Дторінки Š“Š»Ń Š²ŠøŠ“Š°Š»ŠµŠ½Š½Ń (Š²Š²ŠµŠ“Ń–Ń‚ŃŒ список номерів сторінок через кому):", + "submit": "ВиГалити сторінки", + "placeholder": "(наприклаГ, 1,2,6 або 1-10,15-30)" + }, + "imageToPDF": { + "title": "Š—Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń в PDF", + "header": "Š—Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń в PDF", + "submit": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø", + "selectLabel": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ режим Š²Ń–Š“Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "fillPage": "Š—Š°ŠæŠ¾Š²Š½ŠµŠ½Š½Ń сторінки", + "fitDocumentToImage": "ŠŸŃ–Š“Ń–Š³Š½Š°Ń‚Šø Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚ піГ Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "maintainAspectRatio": "Зберегти пропорції", + "selectText": { + "2": "Автоматичний поворот PDF", + "3": "Логіка Š“Š»Ń ŠŗŃ–Š»ŃŒŠŗŠ¾Ń… файлів (Š°ŠŗŃ‚ŠøŠ²ŃƒŃ”Ń‚ŃŒŃŃ лише при роботі Š· Š“ŠµŠŗŃ–Š»ŃŒŠŗŠ¾Š¼Š° Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½ŃŠ¼Šø)", + "4": "ŠžŠ±'єГнати в оГин PDF", + "5": "ŠŸŠµŃ€ŠµŃ‚Š²Š¾Ń€ŠµŠ½Š½Ń в окремі PDF-файли" + } + }, + "PDFToCSV": { + "title": "PDF в CSV", + "header": "PDF в CSV", + "prompt": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ ŃŃ‚Š¾Ń€Ń–Š½ŠŗŃƒ Š“Š»Ń Š²ŠøŃ‚ŃŠ³Ńƒ таблиці", + "submit": "ŠšŠ¾Š½Š²ŠµŃ€Ń‚ŃƒŠ²Š°Ń‚Šø" + }, + "split-by-size-or-count": { + "title": "РозГілити PDF за розміром або ŠŗŃ–Š»ŃŒŠŗŃ–ŃŃ‚ŃŽ", + "header": "РозГілити PDF за розміром або ŠŗŃ–Š»ŃŒŠŗŃ–ŃŃ‚ŃŽ", + "type": { + "label": "Š’ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ тип Ń€Š¾Š·Š“Ń–Š»ŠµŠ½Š½Ń", + "size": "За розміром", + "pageCount": "За ŠŗŃ–Š»ŃŒŠŗŃ–ŃŃ‚ŃŽ сторінок", + "docCount": "За ŠŗŃ–Š»ŃŒŠŗŃ–ŃŃ‚ŃŽ Š“Š¾ŠŗŃƒŠ¼ŠµŠ½Ń‚Ń–Š²" + }, + "value": { + "label": "Š’Š²ŠµŠ“Ń–Ń‚ŃŒ Š·Š½Š°Ń‡ŠµŠ½Š½Ń", + "placeholder": "Š’Š²ŠµŠ“Ń–Ń‚ŃŒ розмір (наприклаГ, 2MB або 3KB) або ŠŗŃ–Š»ŃŒŠŗŃ–ŃŃ‚ŃŒ (наприклаГ, 5)" + }, + "submit": "ŠŠ°Š“Ń–ŃŠ»Š°Ń‚Šø" + }, + "printFile": { + "title": "Š Š¾Š·Š“Ń€ŃƒŠŗŃƒŠ²Š°Ń‚Šø файл", + "header": "Š Š¾Š·Š“Ń€ŃƒŠŗŃƒŠ²Š°Ń‚Šø файл прінтером", + "selectText": { + "1": "ŠžŠ±Ń€Š°Ń‚Šø файл Š“Š»Ń Ń€Š¾Š·Š“Ń€ŃƒŠŗŃƒŠ²Š°Š½Š½Ń", + "2": "ŠžŠ±Ń€Š°Ń‚Šø назву прінтера" + }, + "submit": "Š Š¾Š·Š“Ń€ŃƒŠŗŃƒŠ²Š°Ń‚Šø" + }, + "licenses": { + "nav": "Ліцензії", + "title": "Ліцензії віГ третіх сторін", + "header": "Ліцензії віГ третіх сторін", + "module": "МоГуль", + "version": "Š’ŠµŃ€ŃŃ–Ń", + "license": "Š›Ń–Ń†ŠµŠ½Š·Ń–Ń" + }, + "survey": { + "nav": "ŠžŠæŠøŃ‚ŃƒŠ²Š°Š½Š½Ń", + "title": "ŠžŠæŠøŃ‚ŃƒŠ²Š°Š½Š½Ń Stirling-PDF", + "description": "Stirling-PDF не має аналітичних засобів Š“Š»Ń Š²Ń–Š“ŃŠ»Ń–Š“ŠŗŠ¾Š²ŃƒŠ²Š°Š½Š½Ń, Ń‚Š¾Š¼Ńƒ ми хочемо ŠæŠ¾Ń‡ŃƒŃ‚Šø Гумку віГ ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š², ŃŠŗ покращити Stirling-PDF!", + "changes": "Stirling-PDF Š·Š¼Ń–Š½ŠøŠ²ŃŃ Š· Ń‡Š°ŃŃƒ Š¾ŃŃ‚Š°Š½Š½ŃŒŠ¾Š³Š¾ Š¾ŠæŠøŃ‚ŃƒŠ²Š°Š½Š½Ń! Щоб Š“Ń–Š·Š½Š°Ń‚ŠøŃŃ Š±Ń–Š»ŃŒŃˆŠµ, ŠæŠµŃ€ŠµŠ³Š»ŃŠ½ŃŒŃ‚Šµ Гопис у нашому блозі тут:", + "changes2": "Š—Š°Š²Š“ŃŠŗŠø цим змінам ми Š¾Ń‚Ń€ŠøŠ¼ŃƒŃ”Š¼Š¾ ŠæŠ»Š°Ń‚Š½Ńƒ ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŠŗŃƒ Š±Ń–Š·Š½ŠµŃŃƒ та Ń„Ń–Š½Š°Š½ŃŃƒŠ²Š°Š½Š½Ń", + "please": "Š‘ŃƒŠ“ŃŒ-ласка, ŠæŃ€Š¾Š¹Š“Ń–Ń‚ŃŒ Š¾ŠæŠøŃ‚ŃƒŠ²Š°Š½Š½Ń!", + "disabled": "(Вікно Š· Š¾ŠæŠøŃ‚ŃƒŠ²Š°Š½Š½Ń буГе Š²Ń–Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾ у Š½Š°ŃŃ‚ŃƒŠæŠ½ŠøŃ… Š¾Š½Š¾Š²Š»ŠµŠ½Š½ŃŃ…, але буГе Š“Š¾ŃŃ‚ŃƒŠæŠ½Šµ внизу сторінки)", + "button": "ŠŸŃ€Š¾Š¹Ń‚Šø Š¾ŠæŠøŃ‚ŃƒŠ²Š°Š½Š½Ń", + "dontShowAgain": "ŠŠµ ŠæŠ¾ŠŗŠ°Š·ŃƒŠ²Š°Ń‚Šø це вікно", + "meeting": { + "1": "Якщо ви Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ”Ń‚Šµ Stirling PDF на роботі, ми буГемо раГі поговорити Š· вами. Ми ŠæŃ€Š¾ŠæŠ¾Š½ŃƒŃ”мо сеанси технічної піГтримки в обмін на 15-хвилинний сеанс пошуку ŠŗŠ¾Ń€ŠøŃŃ‚ŃƒŠ²Š°Ń‡Ń–Š².", + "2": "Це Š¼Š¾Š¶Š»ŠøŠ²Ń–ŃŃ‚ŃŒ:", + "3": "ŠžŃ‚Ń€ŠøŠ¼Š°Š¹Ń‚Šµ Гопомогу щоГо Ń€Š¾Š·Š³Š¾Ń€Ń‚Š°Š½Š½Ń, інтеграції або ŃƒŃŃƒŠ½ŠµŠ½Š½Ń несправностей", + "4": "ŠŠ°Š“Š°Š¹Ń‚Šµ ŠæŃ€ŃŠ¼ŠøŠ¹ Š²Ń–Š“Š³ŃƒŠŗ про ŠæŃ€Š¾Š“ŃƒŠŗŃ‚ŠøŠ²Š½Ń–ŃŃ‚ŃŒ, крайні випаГки та неГоліки Ń„ŃƒŠ½ŠŗŃ†Ń–Š¹", + "5": "Š”Š¾ŠæŠ¾Š¼Š¾Š¶Ń–Ń‚ŃŒ нам ŃƒŠ“Š¾ŃŠŗŠ¾Š½Š°Š»ŠøŃ‚Šø Stirling PDF Š“Š»Ń Ń€ŠµŠ°Š»ŃŒŠ½Š¾Š³Š¾ корпоративного Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń", + "6": "Якщо ви зацікавлені, ви можете Š·Š°Š±Ń€Š¾Š½ŃŽŠ²Š°Ń‚Šø час Š±ŠµŠ·ŠæŠ¾ŃŠµŃ€ŠµŠ“Š½ŃŒŠ¾ Š· Š½Š°ŃˆŠ¾ŃŽ ŠŗŠ¾Š¼Š°Š½Š“Š¾ŃŽ. (Ń‚Ń–Š»ŃŒŠŗŠø англомовний)", + "7": "Š— Š½ŠµŃ‚ŠµŃ€ŠæŃ–Š½Š½ŃŠ¼ чекаємо на Š¼Š¾Š¶Š»ŠøŠ²Ń–ŃŃ‚ŃŒ Ń€Š¾Š·Ń–Š±Ń€Š°Ń‚ŠøŃŃ у Š²Š°ŃˆŠøŃ… ŃŃ†ŠµŠ½Š°Ń€Ń–ŃŃ… Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š°Š½Š½Ń та зробити Stirling PDF ще кращим!", + "notInterested": "ŠŠµ бізнес і/або зацікавлені у Š·ŃƒŃŃ‚Ń€Ń–Ń‡Ń–?", + "button": "Š—ŃƒŃŃ‚Ń€Ń–Ń‡" + } + }, + "removeImage": { + "title": "ВиГалити Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "header": "ВиГалити Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "removeImage": "ВиГалити Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "submit": "ВиГалити Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń" + }, + "splitByChapters": { + "title": "РозГілити PDF по главам", + "header": "РозГілити PDF по главам", + "bookmarkLevel": "Š£Ń€Š¾Š²ŠµŠ½ŃŒ заклаГок", + "includeMetadata": "Š’ŠŗŠ»ŃŽŃ‡ŠøŃ‚Šø метаГанні", + "allowDuplicates": "Š Š°Š·Ń€ŠµŃˆŠøŃ‚ŃŒ ŠæŃƒŠ±Š»ŠøŠŗŠ°Ń†ŠøŠø", + "desc": { + "1": "Цей Ń–Š½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚ Ń€Š¾Š·Š“Ń–Š»ŃŃ” PDF-файл на ŠŗŃ–Š»ŃŒŠŗŠ° PDF-файлів на основі своєї ŃŃ‚Ń€ŃƒŠŗŃ‚ŃƒŃ€Šø глави.", + "2": "Š£Ń€Š¾Š²ŠµŠ½ŃŒ заклаГок: Š²ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ Ń€Ń–Š²ŠµŠ½ŃŒ заклаГок Š“Š»Ń Ń€Š¾Š·ŠæŠ¾Š“Ń–Š»Ńƒ (0 Š“Š»Ń Š²ŠµŃ€Ń…Š½ŃŒŠ¾Š³Š¾ Ń€Ń–Š²Š½Ń, 1 Š“Š»Ń Š“Ń€ŃƒŠ³Š¾Š³Š¾ Ń€Ń–Š²Š½Ń і т.Š“.).", + "3": "Š’ŠŗŠ»ŃŽŃ‡ŠøŃ‚Šø метаГанні: ŃŠŗŃ‰Š¾ позначено, метаГанні вихіГного PDF Š±ŃƒŠ“ŃƒŃ‚ŃŒ Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Ń– в кожен розГілений PDF.", + "4": "Š Š¾Š·Ń€Ń–ŃˆŠøŃ‚Šø ŠæŃƒŠ±Š»Ń–ŠŗŠ°Ń†Ń–Ń—: ŃŠŗŃ‰Š¾ позначено, можна створити окремий PDF Ń–Š· ŠŗŃ–Š»ŃŒŠŗŠ¾Ń… заклаГок на оГній сторінці." + }, + "submit": "РозГілити PDF" + }, + "fileChooser": { + "click": "ŠŠ°Ń‚ŠøŃŠ½Ń–Ń‚ŃŒ", + "or": "або", + "dragAndDrop": "ŠŸŠµŃ€ŠµŃ‚Š°Ń‰ŠøŃ‚Šµ", + "dragAndDropPDF": "ŠŸŠµŃ€ŠµŃ‚Š°Ń‰ŠøŃ‚Šµ PDF-файл", + "dragAndDropImage": "ŠŸŠµŃ€ŠµŃ‚Š°Ń‰ŠøŃ‚Šµ файл Š·Š¾Š±Ń€Š°Š¶ŠµŠ½Š½Ń", + "hoveredDragAndDrop": "ŠŸŠµŃ€ŠµŃ‚Š°Ń‰ŠøŃ‚Šµ файл(Šø) ŃŃŽŠ“Š°", + "extractPDF": "Š’ŠøŠ“Š¾Š±ŃƒŠ²Š°Š½Š½Ń..." + }, + "releases": { + "footer": "Релізи", + "title": "ŠŸŃ€ŠøŠ¼ŠµŃ‡Š°Š½ŠøŃ Šŗ Ń€ŠµŠ»ŠøŠ·Ńƒ", + "header": "ŠŸŃ€ŠøŠ¼ŠµŃ‡Š°Š½ŠøŃ Šŗ Ń€ŠµŠ»ŠøŠ·Ńƒ", + "current": { + "version": "Š¢ŠµŠŗŃƒŃ‰ŠøŠ¹ релиз" + }, + "note": "ŠŸŃ€ŠøŠ¼Ń–Ń‚ŠŗŠ° Го Ń€ŠµŠ»Ń–Š·Ńƒ Š“Š¾ŃŃ‚ŃƒŠæŠ½Š° Ń‚Ń–Š»ŃŒŠŗŠø на Š°Š½Š³Š»Ń–Š¹ŃŃŒŠŗŃ–Š¹ мові" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/vi-VN/translation.json b/frontend/public/locales/vi-VN/translation.json new file mode 100644 index 000000000..900288953 --- /dev/null +++ b/frontend/public/locales/vi-VN/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "Font Size", + "fontName": "Font Name", + "title": "ThĆŖm số trang", + "header": "ThĆŖm số trang", + "selectText": { + "1": "Chį»n tệp PDF:", + "2": "KĆ­ch thước lề", + "3": "Vị trĆ­", + "4": "Số bįŗÆt đầu", + "5": "Trang cįŗ§n đƔnh số", + "6": "Văn bįŗ£n tùy chỉnh" + }, + "customTextDesc": "Văn bįŗ£n tùy chỉnh", + "numberPagesDesc": "Những trang cįŗ§n đƔnh số, mįŗ·c định lĆ  'all', cÅ©ng chįŗ„p nhįŗ­n 1-5 hoįŗ·c 2,5,9 v.v.", + "customNumberDesc": "Mįŗ·c định lĆ  {n}, cÅ©ng chįŗ„p nhįŗ­n 'Trang {n} / {total}', 'Văn bįŗ£n-{n}', '{filename}-{n}", + "submit": "ThĆŖm số trang" + }, + "pdfPrompt": "Chį»n (cĆ”c) tệp PDF", + "multiPdfPrompt": "Chį»n cĆ”c tệp PDF (2+)", + "multiPdfDropPrompt": "Chį»n (hoįŗ·c kĆ©o vĆ  thįŗ£) tįŗ„t cįŗ£ cĆ”c tệp PDF bįŗ”n cįŗ§n", + "imgPrompt": "Chį»n (cĆ”c) hƬnh įŗ£nh", + "genericSubmit": "Gį»­i", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "Cįŗ£nh bĆ”o: QuĆ” trƬnh nĆ y có thể mįŗ„t đến mį»™t phĆŗt tùy thuį»™c vĆ o kĆ­ch thước tệp", + "pageOrderPrompt": "Thứ tį»± trang tùy chỉnh (Nhįŗ­p danh sĆ”ch số trang được phĆ¢n tĆ”ch bįŗ±ng dįŗ„u phįŗ©y hoįŗ·c CĆ”c hĆ m nhʰ 2n+1) :", + "pageSelectionPrompt": "Lį»±a chį»n trang tùy chỉnh (Nhįŗ­p danh sĆ”ch số trang được phĆ¢n tĆ”ch bįŗ±ng dįŗ„u phįŗ©y 1,5,6 hoįŗ·c CĆ”c hĆ m nhʰ 2n+1) :", + "goToPage": "Đi đến", + "true": "Đúng", + "false": "Sai", + "unknown": "KhĆ“ng xĆ”c định", + "save": "Lʰu", + "saveToBrowser": "Lʰu vĆ o trƬnh duyệt", + "close": "Đóng", + "filesSelected": "tệp đã chį»n", + "noFavourites": "KhĆ“ng có mỄc yĆŖu thĆ­ch nĆ o được thĆŖm", + "downloadComplete": "Tįŗ£i xuống hoĆ n tįŗ„t", + "bored": "ChĆ”n phįŗ£i chį» đợi?", + "alphabet": "Bįŗ£ng chữ cĆ”i", + "downloadPdf": "Tįŗ£i xuống PDF", + "text": "Văn bįŗ£n", + "font": "PhĆ“ng chữ", + "selectFillter": "-- Chį»n --", + "pageNum": "Số trang", + "sizes": { + "small": "Nhį»", + "medium": "Trung bƬnh", + "large": "Lį»›n", + "x-large": "Rįŗ„t lį»›n" + }, + "error": { + "pdfPassword": "TĆ i liệu PDF được bįŗ£o vệ bįŗ±ng mįŗ­t khįŗ©u vĆ  mįŗ­t khįŗ©u khĆ“ng được cung cįŗ„p hoįŗ·c khĆ“ng chĆ­nh xĆ”c", + "_value": "Lį»—i", + "sorry": "Xin lį»—i vƬ sį»± cố!", + "needHelp": "Cįŗ§n trợ giĆŗp / PhĆ”t hiện sį»± cố?", + "contactTip": "Nįŗæu bįŗ”n vįŗ«n gįŗ·p khó khăn, đừng ngįŗ§n ngįŗ”i liĆŖn hệ vį»›i chĆŗng tĆ“i Ä‘į»ƒ được trợ giĆŗp. Bįŗ”n có thể gį»­i ticket trĆŖn trang GitHub cį»§a chĆŗng tĆ“i hoįŗ·c liĆŖn hệ qua Discord:", + "404": { + "head": "404 - KhĆ“ng tƬm thįŗ„y trang | į»’, có vįŗ» nhʰ chĆŗng tĆ“i đã vįŗ„p phįŗ£i lį»—i trong mĆ£ nguồn!", + "1": "ChĆŗng tĆ“i khĆ“ng thể tƬm thįŗ„y trang bįŗ”n đang tƬm kiįŗæm.", + "2": "Đã xįŗ£y ra lį»—i" + }, + "github": "Gį»­i ticket trĆŖn GitHub", + "showStack": "Hiển thị Stack Trace", + "copyStack": "Sao chĆ©p Stack Trace", + "githubSubmit": "GitHub - Gį»­i ticket", + "discordSubmit": "Discord - Gį»­i bĆ i đăng hį»— trợ" + }, + "delete": "Xóa", + "username": "TĆŖn ngĘ°į»i dùng", + "password": "Mįŗ­t khįŗ©u", + "welcome": "ChĆ o mừng", + "property": "Thuį»™c tĆ­nh", + "black": "Đen", + "white": "TrįŗÆng", + "red": "Äį»", + "green": "Xanh lĆ”", + "blue": "Xanh dʰʔng", + "custom": "Tùy chỉnh...", + "WorkInProgess": "Đang trong quĆ” trƬnh phĆ”t triển, Có thể khĆ“ng hoįŗ”t động hoįŗ·c có lį»—i, Vui lòng bĆ”o cĆ”o mį»i vįŗ„n đề!", + "poweredBy": "Được hį»— trợ bởi", + "yes": "Có", + "no": "KhĆ“ng", + "changedCredsMessage": "ThĆ“ng tin đăng nhįŗ­p đã thay đổi!", + "notAuthenticatedMessage": "NgĘ°į»i dùng chʰa được xĆ”c thį»±c.", + "userNotFoundMessage": "KhĆ“ng tƬm thįŗ„y ngĘ°į»i dùng.", + "incorrectPasswordMessage": "Mįŗ­t khįŗ©u hiện tįŗ”i khĆ“ng chĆ­nh xĆ”c.", + "usernameExistsMessage": "TĆŖn ngĘ°į»i dùng mį»›i đã tồn tįŗ”i.", + "invalidUsernameMessage": "TĆŖn ngĘ°į»i dùng khĆ“ng hợp lệ, tĆŖn ngĘ°į»i dùng chỉ có thể chứa chữ cĆ”i, số vĆ  cĆ”c ký tį»± đặc biệt sau @._+- hoįŗ·c phįŗ£i lĆ  mį»™t địa chỉ email hợp lệ.", + "invalidPasswordMessage": "The password must not be empty and must not have spaces at the beginning or end.", + "confirmPasswordErrorMessage": "Mįŗ­t khįŗ©u mį»›i vĆ  XĆ”c nhįŗ­n mįŗ­t khįŗ©u mį»›i phįŗ£i khį»›p nhau.", + "deleteCurrentUserMessage": "KhĆ“ng thể xóa ngĘ°į»i dùng đang đăng nhįŗ­p.", + "deleteUsernameExistsMessage": "TĆŖn ngĘ°į»i dùng khĆ“ng tồn tįŗ”i vĆ  khĆ“ng thể bị xóa.", + "downgradeCurrentUserMessage": "KhĆ“ng thể hįŗ” cįŗ„p vai trò cį»§a ngĘ°į»i dùng hiện tįŗ”i", + "disabledCurrentUserMessage": "The current user cannot be disabled", + "downgradeCurrentUserLongMessage": "KhĆ“ng thể hįŗ” cįŗ„p vai trò cį»§a ngĘ°į»i dùng hiện tįŗ”i. Do đó, ngĘ°į»i dùng hiện tįŗ”i sįŗ½ khĆ“ng được hiển thị.", + "userAlreadyExistsOAuthMessage": "NgĘ°į»i dùng đã tồn tįŗ”i dưới dįŗ”ng ngĘ°į»i dùng OAuth2.", + "userAlreadyExistsWebMessage": "NgĘ°į»i dùng đã tồn tįŗ”i dưới dįŗ”ng ngĘ°į»i dùng web.", + "oops": "Rįŗ„t tiįŗæc!", + "help": "Trợ giĆŗp", + "goHomepage": "Đi đến Trang chį»§", + "joinDiscord": "Tham gia mĆ”y chį»§ Discord cį»§a chĆŗng tĆ“i", + "seeDockerHub": "Xem Docker Hub", + "visitGithub": "Truy cįŗ­p kho lʰu trữ Github", + "donate": "Ủng hį»™", + "color": "MĆ u sįŗÆc", + "sponsor": "NhĆ  tĆ i trợ", + "info": "ThĆ“ng tin", + "pro": "Pro", + "page": "Page", + "pages": "Pages", + "loading": "Loading...", + "addToDoc": "Add to Document", + "reset": "Reset", + "apply": "Apply", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "Privacy Policy", + "terms": "Terms and Conditions", + "accessibility": "Accessibility", + "cookie": "Cookie Policy", + "impressum": "Impressum", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "Menu Pipeline (Beta)", + "uploadButton": "Tįŗ£i lĆŖn tùy chỉnh", + "configureButton": "Cįŗ„u hƬnh", + "defaultOption": "Tùy chỉnh", + "submitButton": "Gį»­i", + "help": "Trợ giĆŗp Pipeline", + "scanHelp": "Trợ giĆŗp quĆ©t thʰ mỄc", + "deletePrompt": "Bįŗ”n có chįŗÆc chįŗÆn muốn xóa pipeline", + "tags": "tį»± động hóa,chuį»—i,kịch bįŗ£n,xį»­ lý hĆ ng loįŗ”t", + "title": "Pipeline" + }, + "pipelineOptions": { + "header": "Cįŗ„u hƬnh Pipeline", + "pipelineNameLabel": "TĆŖn Pipeline", + "saveSettings": "Lʰu cĆ i đặt thao tĆ”c", + "pipelineNamePrompt": "Nhįŗ­p tĆŖn pipeline tįŗ”i đây", + "selectOperation": "Chį»n thao tĆ”c", + "addOperationButton": "ThĆŖm thao tĆ”c", + "pipelineHeader": "Pipeline:", + "saveButton": "Tįŗ£i xuống", + "validateButton": "XĆ”c thį»±c" + }, + "enterpriseEdition": { + "button": "Upgrade to Pro", + "warning": "This feature is only available to Pro users.", + "yamlAdvert": "Stirling PDF Pro supports YAML configuration files and other SSO features.", + "ssoAdvert": "Looking for more user management features? Check out Stirling PDF Pro" + }, + "analytics": { + "title": "Do you want make Stirling PDF better?", + "paragraph1": "Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.", + "paragraph2": "Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.", + "enable": "Enable analytics", + "disable": "Disable analytics", + "settings": "You can change the settings for analytics in the config/settings.yml file" + }, + "navbar": { + "favorite": "YĆŖu thĆ­ch", + "recent": "New and recently updated", + "darkmode": "Chįŗæ độ tối", + "language": "NgĆ“n ngữ", + "settings": "CĆ i đặt", + "allTools": "CĆ“ng cỄ", + "multiTool": "Đa cĆ“ng cỄ", + "search": "Search", + "sections": { + "organize": "SįŗÆp xįŗæp", + "convertTo": "Chuyển đổi sang PDF", + "convertFrom": "Chuyển đổi từ PDF", + "security": "Ký & Bįŗ£o mįŗ­t", + "advance": "NĆ¢ng cao", + "edit": "Xem & Chỉnh sį»­a", + "popular": "Popular" + } + }, + "settings": { + "title": "CĆ i đặt", + "update": "Có bįŗ£n cįŗ­p nhįŗ­t", + "updateAvailable": "{0} lĆ  phiĆŖn bįŗ£n hiện tįŗ”i đã cĆ i đặt. Mį»™t phiĆŖn bįŗ£n mį»›i ({1}) đã có sįŗµn.", + "appVersion": "PhiĆŖn bįŗ£n ứng dỄng:", + "downloadOption": { + "title": "Chį»n tùy chį»n tįŗ£i xuống (Đối vį»›i tįŗ£i xuống tệp đʔn khĆ“ng nĆ©n):", + "1": "Mở trong cùng cį»­a sổ", + "2": "Mở trong cį»­a sổ mį»›i", + "3": "Tįŗ£i xuống tệp" + }, + "zipThreshold": "NĆ©n tệp khi số lượng tệp tįŗ£i xuống vượt quĆ”", + "signOut": "Đăng xuįŗ„t", + "accountSettings": "CĆ i đặt tĆ i khoįŗ£n", + "bored": { + "help": "Bįŗ­t trò chĘ”i įŗ©n" + }, + "cacheInputs": { + "name": "Lʰu đầu vĆ o biểu mįŗ«u", + "help": "Bįŗ­t Ä‘į»ƒ lʰu trữ cĆ”c đầu vĆ o đã sį»­ dỄng trước đó cho cĆ”c lįŗ§n chįŗ”y trong tʰʔng lai" + } + }, + "changeCreds": { + "title": "Thay đổi thĆ“ng tin đăng nhįŗ­p", + "header": "Cįŗ­p nhįŗ­t thĆ“ng tin tĆ i khoįŗ£n cį»§a bįŗ”n", + "changePassword": "Bįŗ”n đang sį»­ dỄng thĆ“ng tin đăng nhįŗ­p mįŗ·c định. Vui lòng nhįŗ­p mįŗ­t khįŗ©u mį»›i", + "newUsername": "TĆŖn ngĘ°į»i dùng mį»›i", + "oldPassword": "Mįŗ­t khįŗ©u hiện tįŗ”i", + "newPassword": "Mįŗ­t khįŗ©u mį»›i", + "confirmNewPassword": "XĆ”c nhįŗ­n mįŗ­t khįŗ©u mį»›i", + "submit": "Gį»­i thay đổi" + }, + "account": { + "title": "CĆ i đặt tĆ i khoįŗ£n", + "accountSettings": "CĆ i đặt tĆ i khoįŗ£n", + "adminSettings": "CĆ i đặt quįŗ£n trị - Xem vĆ  thĆŖm ngĘ°į»i dùng", + "userControlSettings": "CĆ i đặt kiểm soĆ”t ngĘ°į»i dùng", + "changeUsername": "Thay đổi tĆŖn ngĘ°į»i dùng", + "newUsername": "TĆŖn ngĘ°į»i dùng mį»›i", + "password": "Mįŗ­t khįŗ©u xĆ”c nhįŗ­n", + "oldPassword": "Mįŗ­t khįŗ©u cÅ©", + "newPassword": "Mįŗ­t khįŗ©u mį»›i", + "changePassword": "Thay đổi mįŗ­t khįŗ©u", + "confirmNewPassword": "XĆ”c nhįŗ­n mįŗ­t khįŗ©u mį»›i", + "signOut": "Đăng xuįŗ„t", + "yourApiKey": "Khóa API cį»§a bįŗ”n", + "syncTitle": "Đồng bį»™ hóa cĆ i đặt trƬnh duyệt vį»›i tĆ i khoįŗ£n", + "settingsCompare": "So sĆ”nh cĆ i đặt:", + "property": "Thuį»™c tĆ­nh", + "webBrowserSettings": "CĆ i đặt trƬnh duyệt web", + "syncToBrowser": "Đồng bį»™ hóa TĆ i khoįŗ£n -> TrƬnh duyệt", + "syncToAccount": "Đồng bį»™ hóa TĆ i khoįŗ£n <- TrƬnh duyệt" + }, + "adminUserSettings": { + "title": "CĆ i đặt kiểm soĆ”t ngĘ°į»i dùng", + "header": "CĆ i đặt kiểm soĆ”t ngĘ°į»i dùng quįŗ£n trị", + "admin": "Quįŗ£n trị viĆŖn", + "user": "NgĘ°į»i dùng", + "addUser": "ThĆŖm ngĘ°į»i dùng mį»›i", + "deleteUser": "Xóa ngĘ°į»i dùng", + "confirmDeleteUser": "Bįŗ”n có muốn xóa ngĘ°į»i dùng khĆ“ng?", + "confirmChangeUserStatus": "Should the user be disabled/enabled?", + "usernameInfo": "TĆŖn ngĘ°į»i dùng chỉ có thể chứa chữ cĆ”i, số vĆ  cĆ”c ký tį»± đặc biệt sau @._+- hoįŗ·c phįŗ£i lĆ  mį»™t địa chỉ email hợp lệ.", + "roles": "Vai trò", + "role": "Vai trò", + "actions": "HĆ nh động", + "apiUser": "NgĘ°į»i dùng API giį»›i hįŗ”n", + "extraApiUser": "NgĘ°į»i dùng API giį»›i hįŗ”n bổ sung", + "webOnlyUser": "Chỉ ngĘ°į»i dùng web", + "demoUser": "NgĘ°į»i dùng demo (KhĆ“ng có cĆ i đặt tùy chỉnh)", + "internalApiUser": "NgĘ°į»i dùng API nį»™i bį»™", + "forceChange": "Buį»™c ngĘ°į»i dùng thay đổi mįŗ­t khįŗ©u khi đăng nhįŗ­p", + "submit": "Lʰu ngĘ°į»i dùng", + "changeUserRole": "Thay đổi vai trò cį»§a ngĘ°į»i dùng", + "authenticated": "Đã xĆ”c thį»±c", + "editOwnProfil": "Edit own profile", + "enabledUser": "enabled user", + "disabledUser": "disabled user", + "activeUsers": "Active Users:", + "disabledUsers": "Disabled Users:", + "totalUsers": "Total Users:", + "lastRequest": "Last Request", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "Nhįŗ­p/Xuįŗ„t cĘ” sở dữ liệu", + "header": "Nhįŗ­p/Xuįŗ„t cĘ” sở dữ liệu", + "fileName": "TĆŖn tệp", + "creationDate": "NgĆ y tįŗ”o", + "fileSize": "KĆ­ch thước tệp", + "deleteBackupFile": "Xóa tệp sao lʰu", + "importBackupFile": "Nhįŗ­p tệp sao lʰu", + "createBackupFile": "Create Backup File", + "downloadBackupFile": "Tįŗ£i xuống tệp sao lʰu", + "info_1": "Khi nhįŗ­p dữ liệu, điều quan trį»ng lĆ  phįŗ£i đảm bįŗ£o cįŗ„u trĆŗc chĆ­nh xĆ”c. Nįŗæu bįŗ”n khĆ“ng chįŗÆc chįŗÆn về những gƬ bįŗ”n đang lĆ m, hĆ£y tƬm kiįŗæm lį»i khuyĆŖn vĆ  hį»— trợ từ mį»™t chuyĆŖn gia. Lį»—i trong cįŗ„u trĆŗc có thể gĆ¢y ra sį»± cố ứng dỄng, thįŗ­m chĆ­ lĆ  khĆ“ng thể chįŗ”y ứng dỄng hoĆ n toĆ n.", + "info_2": "TĆŖn tệp khĆ“ng quan trį»ng khi tįŗ£i lĆŖn. Nó sįŗ½ được đổi tĆŖn sau đó Ä‘į»ƒ tuĆ¢n theo định dįŗ”ng backup_user_yyyyMMddHHmm.sql, đảm bįŗ£o quy ước đặt tĆŖn nhįŗ„t quĆ”n.", + "submit": "Nhįŗ­p bįŗ£n sao lʰu", + "importIntoDatabaseSuccessed": "Nhįŗ­p vĆ o cĘ” sở dữ liệu thĆ nh cĆ“ng", + "backupCreated": "Database backup successful", + "fileNotFound": "KhĆ“ng tƬm thįŗ„y tệp", + "fileNullOrEmpty": "Tệp khĆ“ng được Ä‘į»ƒ trống hoįŗ·c rį»—ng", + "failedImportFile": "KhĆ“ng thể nhįŗ­p tệp", + "notSupported": "This function is not available for your database connection." + }, + "session": { + "expired": "Your session has expired. Please refresh the page and try again.", + "refreshPage": "Refresh Page" + }, + "home": { + "desc": "Giįŗ£i phĆ”p toĆ n diện cho mį»i nhu cįŗ§u về PDF ngay trĆŖn mĆ”y cį»§a bįŗ”n", + "searchBar": "TƬm kiįŗæm tĆ­nh năng...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "Xem, chĆŗ thĆ­ch, thĆŖm văn bįŗ£n hoįŗ·c hƬnh įŗ£nh" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "Đa cĆ“ng cỄ PDF", + "desc": "GhĆ©p nối, Xoay, SįŗÆp xįŗæp lįŗ”i vĆ  Xóa trang" + }, + "merge": { + "title": "GhĆ©p nối", + "desc": "Dį»… dĆ ng ghĆ©p nối nhiều PDF thĆ nh mį»™t." + }, + "split": { + "title": "TĆ”ch", + "desc": "TĆ”ch PDF thĆ nh nhiều tĆ i liệu" + }, + "rotate": { + "title": "Xoay", + "desc": "Dį»… dĆ ng xoay PDF cį»§a bįŗ”n." + }, + "imageToPdf": { + "title": "HƬnh įŗ£nh sang PDF", + "desc": "Chuyển đổi hƬnh įŗ£nh (PNG, JPEG, GIF) sang PDF." + }, + "pdfToImage": { + "title": "PDF sang HƬnh įŗ£nh", + "desc": "Chuyển đổi PDF sang hƬnh įŗ£nh. (PNG, JPEG, GIF)" + }, + "pdfOrganiser": { + "title": "SįŗÆp xįŗæp", + "desc": "Xóa/SįŗÆp xįŗæp lįŗ”i trang theo bįŗ„t kỳ thứ tį»± nĆ o" + }, + "addImage": { + "title": "ThĆŖm hƬnh įŗ£nh", + "desc": "ThĆŖm hƬnh įŗ£nh vĆ o vị trĆ­ cố định trĆŖn PDF" + }, + "watermark": { + "title": "ThĆŖm hƬnh mį»", + "desc": "ThĆŖm hƬnh mį» tùy chỉnh vĆ o tĆ i liệu PDF cį»§a bįŗ”n." + }, + "permissions": { + "title": "Thay đổi quyền", + "desc": "Thay đổi quyền cį»§a tĆ i liệu PDF cį»§a bįŗ”n" + }, + "removePages": { + "title": "Xóa", + "desc": "Xóa cĆ”c trang khĆ“ng mong muốn khį»i tĆ i liệu PDF cį»§a bįŗ”n." + }, + "addPassword": { + "title": "ThĆŖm mįŗ­t khįŗ©u", + "desc": "MĆ£ hóa tĆ i liệu PDF cį»§a bįŗ”n bįŗ±ng mįŗ­t khįŗ©u." + }, + "removePassword": { + "title": "Xóa mįŗ­t khįŗ©u", + "desc": "Xóa bįŗ£o vệ mįŗ­t khįŗ©u khį»i tĆ i liệu PDF cį»§a bįŗ”n." + }, + "compressPdfs": { + "title": "NĆ©n", + "desc": "NĆ©n PDF Ä‘į»ƒ giįŗ£m kĆ­ch thước tệp." + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "Thay đổi Metadata", + "desc": "Thay đổi/Xóa/ThĆŖm metadata từ tĆ i liệu PDF" + }, + "fileToPDF": { + "title": "Chuyển đổi tệp sang PDF", + "desc": "Chuyển đổi hįŗ§u hįŗæt mį»i tệp sang PDF (DOCX, PNG, XLS, PPT, TXT vĆ  nhiều hĘ”n nữa)" + }, + "ocr": { + "title": "OCR / Dį»n dįŗ¹p bįŗ£n quĆ©t", + "desc": "Dį»n dįŗ¹p bįŗ£n quĆ©t vĆ  phĆ”t hiện văn bįŗ£n từ hƬnh įŗ£nh trong PDF vĆ  thĆŖm lįŗ”i dưới dįŗ”ng văn bįŗ£n." + }, + "extractImages": { + "title": "TrĆ­ch xuįŗ„t hƬnh įŗ£nh", + "desc": "TrĆ­ch xuįŗ„t tįŗ„t cįŗ£ hƬnh įŗ£nh từ PDF vĆ  lʰu chĆŗng vĆ o tệp zip" + }, + "pdfToPDFA": { + "title": "PDF sang PDF/A", + "desc": "Chuyển đổi PDF sang PDF/A Ä‘į»ƒ lʰu trữ lĆ¢u dĆ i" + }, + "PDFToWord": { + "title": "PDF sang Word", + "desc": "Chuyển đổi PDF sang cĆ”c định dįŗ”ng Word (DOC, DOCX vĆ  ODT)" + }, + "PDFToPresentation": { + "title": "PDF sang BĆ i thuyįŗæt trƬnh", + "desc": "Chuyển đổi PDF sang cĆ”c định dįŗ”ng BĆ i thuyįŗæt trƬnh (PPT, PPTX vĆ  ODP)" + }, + "PDFToText": { + "title": "PDF sang RTF (Văn bįŗ£n)", + "desc": "Chuyển đổi PDF sang định dįŗ”ng Văn bįŗ£n hoįŗ·c RTF" + }, + "PDFToHTML": { + "title": "PDF sang HTML", + "desc": "Chuyển đổi PDF sang định dįŗ”ng HTML" + }, + "PDFToXML": { + "title": "PDF sang XML", + "desc": "Chuyển đổi PDF sang định dįŗ”ng XML" + }, + "ScannerImageSplit": { + "title": "PhĆ”t hiện/TĆ”ch įŗ£nh quĆ©t", + "desc": "TĆ”ch nhiều įŗ£nh từ trong mį»™t įŗ£nh/PDF" + }, + "sign": { + "title": "Ký", + "desc": "ThĆŖm chữ ký vĆ o PDF bįŗ±ng cĆ”ch vįŗ½, văn bįŗ£n hoįŗ·c hƬnh įŗ£nh" + }, + "flatten": { + "title": "LĆ m phįŗ³ng", + "desc": "Xóa tįŗ„t cįŗ£ cĆ”c phįŗ§n tį»­ tʰʔng tĆ”c vĆ  biểu mįŗ«u từ PDF" + }, + "repair": { + "title": "Sį»­a chữa", + "desc": "Cố gįŗÆng sį»­a chữa PDF bị hį»ng/lį»—i" + }, + "removeBlanks": { + "title": "Xóa trang trống", + "desc": "PhĆ”t hiện vĆ  xóa cĆ”c trang trống khį»i tĆ i liệu" + }, + "removeAnnotations": { + "title": "Xóa chĆŗ thĆ­ch", + "desc": "Xóa tįŗ„t cįŗ£ cĆ”c bƬnh luįŗ­n/chĆŗ thĆ­ch khį»i PDF" + }, + "compare": { + "title": "So sĆ”nh", + "desc": "So sĆ”nh vĆ  hiển thị sį»± khĆ”c biệt giữa 2 tĆ i liệu PDF" + }, + "certSign": { + "title": "Ký bįŗ±ng chứng chỉ", + "desc": "Ký PDF bįŗ±ng Chứng chỉ/Khóa (PEM/P12)" + }, + "removeCertSign": { + "title": "Xóa chữ ký chứng chỉ", + "desc": "Xóa chữ ký chứng chỉ khį»i PDF" + }, + "pageLayout": { + "title": "Bố cỄc nhiều trang", + "desc": "GhĆ©p nhiều trang cį»§a tĆ i liệu PDF thĆ nh mį»™t trang duy nhįŗ„t" + }, + "scalePages": { + "title": "Điều chỉnh kĆ­ch thước/tį»· lệ trang", + "desc": "Thay đổi kĆ­ch thước/tį»· lệ cį»§a trang vĆ /hoįŗ·c nį»™i dung cį»§a nó." + }, + "pipeline": { + "title": "Pipeline (NĆ¢ng cao)", + "desc": "Chįŗ”y nhiều thao tĆ”c trĆŖn PDF bįŗ±ng cĆ”ch định nghÄ©a cĆ”c tįŗ­p lệnh pipeline" + }, + "add-page-numbers": { + "title": "ThĆŖm số trang", + "desc": "ThĆŖm số trang xuyĆŖn suốt tĆ i liệu ở vị trĆ­ cố định" + }, + "auto-rename": { + "title": "Tį»± động đổi tĆŖn tệp PDF", + "desc": "Tį»± động đổi tĆŖn tệp PDF dį»±a trĆŖn tiĆŖu đề được phĆ”t hiện" + }, + "adjust-contrast": { + "title": "Điều chỉnh mĆ u sįŗÆc/tʰʔng phįŗ£n", + "desc": "Điều chỉnh độ tʰʔng phįŗ£n, độ bĆ£o hòa vĆ  độ sĆ”ng cį»§a PDF" + }, + "crop": { + "title": "CįŗÆt PDF", + "desc": "CįŗÆt PDF Ä‘į»ƒ giįŗ£m kĆ­ch thước (giữ nguyĆŖn văn bįŗ£n!)" + }, + "autoSplitPDF": { + "title": "Tį»± động tĆ”ch trang", + "desc": "Tį»± động tĆ”ch PDF đã quĆ©t vį»›i mĆ£ QR tĆ”ch trang quĆ©t vįŗ­t lý" + }, + "sanitizePdf": { + "title": "LĆ m sįŗ”ch", + "desc": "Xóa cĆ”c tįŗ­p lệnh vĆ  phįŗ§n tį»­ khĆ”c khį»i cĆ”c tệp PDF" + }, + "URLToPDF": { + "title": "URL/Trang web sang PDF", + "desc": "Chuyển đổi bįŗ„t kỳ URL http(s) nĆ o thĆ nh PDF" + }, + "HTMLToPDF": { + "title": "HTML sang PDF", + "desc": "Chuyển đổi bįŗ„t kỳ tệp HTML hoįŗ·c zip nĆ o thĆ nh PDF" + }, + "MarkdownToPDF": { + "title": "Markdown sang PDF", + "desc": "Chuyển đổi bįŗ„t kỳ tệp Markdown nĆ o thĆ nh PDF" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "Lįŗ„y Tįŗ¤T Cįŗ¢ thĆ“ng tin về PDF", + "desc": "Lįŗ„y bįŗ„t kỳ vĆ  tįŗ„t cįŗ£ thĆ“ng tin có thể về PDF" + }, + "extractPage": { + "title": "TrĆ­ch xuįŗ„t (cĆ”c) trang", + "desc": "TrĆ­ch xuįŗ„t cĆ”c trang được chį»n từ PDF" + }, + "PdfToSinglePage": { + "title": "PDF sang mį»™t trang lį»›n", + "desc": "GhĆ©p tįŗ„t cįŗ£ cĆ”c trang PDF thĆ nh mį»™t trang lį»›n duy nhįŗ„t" + }, + "showJS": { + "title": "Hiển thị Javascript", + "desc": "TƬm kiįŗæm vĆ  hiển thị bįŗ„t kỳ JS nĆ o được chĆØn vĆ o PDF" + }, + "autoRedact": { + "title": "Tį»± động biĆŖn tįŗ­p", + "desc": "Tį»± động biĆŖn tįŗ­p (Che đen) văn bįŗ£n trong PDF dį»±a trĆŖn văn bįŗ£n đầu vĆ o" + }, + "redact": { + "title": "Manual Redaction", + "desc": "Redacts a PDF based on selected text, drawn shapes and/or selected page(s)" + }, + "tableExtraxt": { + "title": "PDF sang CSV", + "desc": "TrĆ­ch xuįŗ„t bįŗ£ng từ PDF chuyển đổi thĆ nh CSV" + }, + "autoSizeSplitPDF": { + "title": "Tį»± động chia theo kĆ­ch thước/số lượng", + "desc": "Chia mį»™t tệp PDF thĆ nh nhiều tĆ i liệu dį»±a trĆŖn kĆ­ch thước, số trang hoįŗ·c số lượng tĆ i liệu" + }, + "overlay-pdfs": { + "title": "Chồng lį»›p PDF", + "desc": "Chồng lį»›p PDF lĆŖn trĆŖn PDF khĆ”c" + }, + "split-by-sections": { + "title": "Chia PDF theo phįŗ§n", + "desc": "Chia mį»—i trang cį»§a PDF thĆ nh cĆ”c phįŗ§n nhį» hĘ”n theo chiều ngang vĆ  dį»c" + }, + "AddStampRequest": { + "title": "ThĆŖm dįŗ„u vĆ o PDF", + "desc": "ThĆŖm văn bįŗ£n hoįŗ·c hƬnh įŗ£nh dįŗ„u tįŗ”i vị trĆ­ cố định" + }, + "removeImagePdf": { + "title": "Remove image", + "desc": "Remove image from PDF to reduce file size" + }, + "splitPdfByChapters": { + "title": "Split PDF by Chapters", + "desc": "Split a PDF into multiple files based on its chapter structure." + }, + "validateSignature": { + "title": "Validate PDF Signature", + "desc": "Verify digital signatures and certificates in PDF documents" + }, + "replaceColorPdf": { + "title": "Replace and Invert Color", + "desc": "Replace color for text and background in PDF and invert full color of pdf to reduce file size" + } + }, + "viewPdf": { + "tags": "xem,Ä‘į»c,chĆŗ thĆ­ch,văn bįŗ£n,hƬnh įŗ£nh", + "title": "View/Edit PDF", + "header": "Xem PDF" + }, + "multiTool": { + "tags": "Đa cĆ“ng cỄ,Đa thao tĆ”c,Giao diện ngĘ°į»i dùng,nhįŗ„p kĆ©o,phĆ­a trước,phĆ­a mĆ”y khĆ”ch,tʰʔng tĆ”c,có thể tʰʔng tĆ”c,di chuyển", + "title": "CĆ“ng cỄ đa năng PDF", + "header": "CĆ“ng cỄ đa năng PDF", + "uploadPrompts": "TĆŖn tệp", + "selectAll": "Select All", + "deselectAll": "Deselect All", + "selectPages": "Page Select", + "selectedPages": "Selected Pages", + "page": "Page", + "deleteSelected": "Delete Selected", + "downloadAll": "Export", + "downloadSelected": "Export Selected", + "insertPageBreak": "Insert Page Break", + "addFile": "Add File", + "rotateLeft": "Rotate Left", + "rotateRight": "Rotate Right", + "split": "Split", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "Delete", + "dragDropMessage": "Page(s) Selected", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "ghĆ©p nối,Thao tĆ”c trang,PhĆ­a sau,phĆ­a mĆ”y chį»§", + "title": "Trį»™n", + "header": "Trį»™n nhiều PDF (2+)", + "sortByName": "SįŗÆp xįŗæp theo tĆŖn", + "sortByDate": "SįŗÆp xįŗæp theo ngĆ y", + "removeCertSign": "Xóa chữ ký số trong tệp đã trį»™n?", + "submit": "Trį»™n" + }, + "split": { + "tags": "Thao tĆ”c trang,chia,Nhiều trang,cįŗÆt,phĆ­a mĆ”y chį»§", + "title": "Chia PDF", + "header": "Chia PDF", + "desc": { + "1": "CĆ”c số bįŗ”n chį»n lĆ  số trang bįŗ”n muốn thį»±c hiện chia", + "2": "Nhʰ vįŗ­y, việc chį»n 1,3,7-9 sįŗ½ chia mį»™t tĆ i liệu 10 trang thĆ nh 6 PDF riĆŖng biệt vį»›i:", + "3": "TĆ i liệu #1: Trang 1", + "4": "TĆ i liệu #2: Trang 2 vĆ  3", + "5": "TĆ i liệu #3: Trang 4, 5, 6 vĆ  7", + "6": "TĆ i liệu #4: Trang 8", + "7": "TĆ i liệu #5: Trang 9", + "8": "TĆ i liệu #6: Trang 10" + }, + "splitPages": "Nhįŗ­p cĆ”c trang cįŗ§n chia:", + "submit": "Chia" + }, + "rotate": { + "tags": "phĆ­a mĆ”y chį»§", + "title": "Xoay PDF", + "header": "Xoay PDF", + "selectAngle": "Chį»n góc xoay (theo bį»™i số cį»§a 90 độ):", + "submit": "Xoay" + }, + "imageToPdf": { + "tags": "chuyển đổi,img,jpg,hƬnh įŗ£nh,įŗ£nh" + }, + "pdfToImage": { + "tags": "chuyển đổi,img,jpg,hƬnh įŗ£nh,įŗ£nh", + "title": "PDF sang hƬnh įŗ£nh", + "header": "PDF sang hƬnh įŗ£nh", + "selectText": "Định dįŗ”ng hƬnh įŗ£nh", + "singleOrMultiple": "Loįŗ”i kįŗæt quįŗ£ trang sang hƬnh įŗ£nh", + "single": "Mį»™t hƬnh įŗ£nh lį»›n kįŗæt hợp tįŗ„t cįŗ£ cĆ”c trang", + "multi": "Nhiều hƬnh įŗ£nh, mį»—i trang mį»™t hƬnh įŗ£nh", + "colorType": "Loįŗ”i mĆ u", + "color": "MĆ u", + "grey": "Thang độ xĆ”m", + "blackwhite": "Đen trįŗÆng (Có thể mįŗ„t dữ liệu!)", + "submit": "Chuyển đổi", + "info": "Python is not installed. Required for WebP conversion.", + "placeholder": "(vĆ­ dỄ: 1,2,8 hoįŗ·c 4,7,12-16 hoįŗ·c 2n-1)" + }, + "pdfOrganiser": { + "tags": "duplex,chįŗµn,lįŗ»,sįŗÆp xįŗæp,di chuyển", + "title": "SįŗÆp xįŗæp trang", + "header": "SįŗÆp xįŗæp trang PDF", + "submit": "SįŗÆp xįŗæp lįŗ”i trang", + "mode": { + "_value": "Chįŗæ độ", + "1": "Thứ tį»± trang tùy chỉnh", + "2": "Đảo ngược thứ tį»±", + "3": "SįŗÆp xįŗæp hai mįŗ·t", + "4": "SįŗÆp xįŗæp sĆ”ch nhį»", + "5": "SįŗÆp xįŗæp sĆ”ch nhį» đóng gĆ”y bĆŖn", + "6": "TĆ”ch lįŗ»-chįŗµn", + "7": "Xóa trang đầu", + "8": "Xóa trang cuối", + "9": "Xóa trang đầu vĆ  cuối", + "10": "Trį»™n lįŗ»-chįŗµn", + "11": "Duplicate all pages" + }, + "placeholder": "(vĆ­ dỄ: 1,3,2 hoįŗ·c 4-8,2,10-12 hoįŗ·c 2n-1)" + }, + "addImage": { + "tags": "img,jpg,hƬnh įŗ£nh,įŗ£nh", + "title": "ThĆŖm hƬnh įŗ£nh", + "header": "ThĆŖm hƬnh įŗ£nh vĆ o PDF", + "everyPage": "Mį»i trang?", + "upload": "ThĆŖm hƬnh įŗ£nh", + "submit": "ThĆŖm hƬnh įŗ£nh" + }, + "watermark": { + "tags": "Văn bįŗ£n,lįŗ·p lįŗ”i,nhĆ£n,riĆŖng,bįŗ£n quyền,thʰʔng hiệu,img,jpg,hƬnh įŗ£nh,įŗ£nh", + "title": "ThĆŖm hƬnh mį»", + "header": "ThĆŖm hƬnh mį»", + "customColor": "MĆ u văn bįŗ£n tùy chỉnh", + "selectText": { + "1": "Chį»n PDF Ä‘į»ƒ thĆŖm hƬnh mį»:", + "2": "Văn bįŗ£n hƬnh mį»:", + "3": "Cį»” chữ:", + "4": "Xoay (0-360):", + "5": "Khoįŗ£ng cĆ”ch ngang (Khoįŗ£ng cĆ”ch giữa mį»—i hƬnh mį» theo chiều ngang):", + "6": "Khoįŗ£ng cĆ”ch dį»c (Khoįŗ£ng cĆ”ch giữa mį»—i hƬnh mį» theo chiều dį»c):", + "7": "Độ mį» (0% - 100%):", + "8": "Loįŗ”i hƬnh mį»:", + "9": "HƬnh įŗ£nh hƬnh mį»:", + "10": "Convert PDF to PDF-Image" + }, + "submit": "ThĆŖm hƬnh mį»", + "type": { + "1": "Văn bįŗ£n", + "2": "HƬnh įŗ£nh" + } + }, + "permissions": { + "tags": "Ä‘į»c,viįŗæt,chỉnh sį»­a,in", + "title": "Thay đổi quyền", + "header": "Thay đổi quyền", + "warning": "Cįŗ£nh bĆ”o Ä‘į»ƒ cĆ”c quyền nĆ y khĆ“ng thể thay đổi, bįŗ”n nĆŖn đặt chĆŗng vį»›i mįŗ­t khįŗ©u thĆ“ng qua trang thĆŖm mįŗ­t khįŗ©u", + "selectText": { + "1": "Chį»n PDF Ä‘į»ƒ thay đổi quyền", + "2": "Quyền cįŗ§n đặt", + "3": "Ngăn chįŗ·n lįŗÆp rĆ”p tĆ i liệu", + "4": "Ngăn chįŗ·n trĆ­ch xuįŗ„t nį»™i dung", + "5": "Ngăn chįŗ·n trĆ­ch xuįŗ„t Ä‘į»ƒ truy cįŗ­p", + "6": "Ngăn chįŗ·n điền vĆ o biểu mįŗ«u", + "7": "Ngăn chįŗ·n sį»­a đổi", + "8": "Ngăn chįŗ·n sį»­a đổi chĆŗ thĆ­ch", + "9": "Ngăn chįŗ·n in", + "10": "Ngăn chįŗ·n in cĆ”c định dįŗ”ng khĆ”c nhau" + }, + "submit": "Thay đổi" + }, + "removePages": { + "tags": "Xóa trang,xóa trang" + }, + "addPassword": { + "tags": "bįŗ£o mįŗ­t,an toĆ n", + "title": "ThĆŖm mįŗ­t khįŗ©u", + "header": "ThĆŖm mįŗ­t khįŗ©u (MĆ£ hóa)", + "selectText": { + "1": "Chį»n PDF Ä‘į»ƒ mĆ£ hóa", + "2": "Mįŗ­t khįŗ©u ngĘ°į»i dùng", + "3": "Độ dĆ i khóa mĆ£ hóa", + "4": "GiĆ” trị cao hĘ”n thƬ mįŗ”nh hĘ”n, nhʰng giĆ” trị thįŗ„p hĘ”n có tĆ­nh tʰʔng thĆ­ch tốt hĘ”n.", + "5": "Quyền cįŗ§n đặt (Khuyįŗæn nghị sį»­ dỄng cùng vį»›i mįŗ­t khįŗ©u chį»§ sở hữu)", + "6": "Ngăn chįŗ·n lįŗÆp rĆ”p tĆ i liệu", + "7": "Ngăn chįŗ·n trĆ­ch xuįŗ„t nį»™i dung", + "8": "Ngăn chįŗ·n trĆ­ch xuįŗ„t Ä‘į»ƒ truy cįŗ­p", + "9": "Ngăn chįŗ·n điền vĆ o biểu mįŗ«u", + "10": "Ngăn chįŗ·n sį»­a đổi", + "11": "Ngăn chįŗ·n sį»­a đổi chĆŗ thĆ­ch", + "12": "Ngăn chįŗ·n in", + "13": "Ngăn chįŗ·n in cĆ”c định dįŗ”ng khĆ”c nhau", + "14": "Mįŗ­t khįŗ©u chį»§ sở hữu", + "15": "Hįŗ”n chįŗæ những gƬ có thể lĆ m vį»›i tĆ i liệu sau khi mở (KhĆ“ng được hį»— trợ bởi tįŗ„t cįŗ£ cĆ”c trƬnh Ä‘į»c)", + "16": "Hįŗ”n chįŗæ việc mở tĆ i liệu" + }, + "submit": "MĆ£ hóa" + }, + "removePassword": { + "tags": "bįŗ£o mįŗ­t,Giįŗ£i mĆ£,an toĆ n,bį» mįŗ­t khįŗ©u,xóa mįŗ­t khįŗ©u", + "title": "Xóa mįŗ­t khįŗ©u", + "header": "Xóa mįŗ­t khįŗ©u (Giįŗ£i mĆ£)", + "selectText": { + "1": "Chį»n PDF Ä‘į»ƒ giįŗ£i mĆ£", + "2": "Mįŗ­t khįŗ©u" + }, + "submit": "Xóa" + }, + "compressPdfs": { + "tags": "Ć©p,nhį»,nhį» gį»n" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "TiĆŖu đề,tĆ”c giįŗ£,ngĆ y,tįŗ”o,thį»i gian,nhĆ  xuįŗ„t bįŗ£n,nhĆ  sįŗ£n xuįŗ„t,thống kĆŖ", + "title": "Thay đổi metadata", + "header": "Thay đổi metadata", + "selectText": { + "1": "Vui lòng chỉnh sį»­a cĆ”c biįŗæn bįŗ”n muốn thay đổi", + "2": "Xóa tįŗ„t cįŗ£ metadata", + "3": "Hiển thị metadata tùy chỉnh:", + "4": "Metadata khĆ”c:", + "5": "ThĆŖm mỄc metadata tùy chỉnh" + }, + "author": "TĆ”c giįŗ£:", + "creationDate": "NgĆ y tįŗ”o (yyyy/MM/dd HH:mm:ss):", + "creator": "NgĘ°į»i tįŗ”o:", + "keywords": "Từ khóa:", + "modDate": "NgĆ y sį»­a đổi (yyyy/MM/dd HH:mm:ss):", + "producer": "NhĆ  sįŗ£n xuįŗ„t:", + "subject": "Chį»§ đề:", + "trapped": "Trapped:", + "submit": "Thay đổi" + }, + "fileToPDF": { + "tags": "chuyển đổi,định dįŗ”ng,tĆ i liệu,hƬnh įŗ£nh,slide,văn bįŗ£n,chuyển đổi,văn phòng,tĆ i liệu,word,excel,powerpoint", + "title": "Tệp sang PDF", + "header": "Chuyển đổi bįŗ„t kỳ tệp nĆ o sang PDF", + "credit": "Dịch vỄ nĆ y sį»­ dỄng LibreOffice vĆ  Unoconv Ä‘į»ƒ chuyển đổi tệp.", + "supportedFileTypesInfo": "CĆ”c loįŗ”i tệp được hį»— trợ", + "supportedFileTypes": "CĆ”c loįŗ”i tệp được hį»— trợ nĆŖn bao gồm cĆ”c loįŗ”i dưới đây, tuy nhiĆŖn Ä‘į»ƒ có danh sĆ”ch đầy đủ vĆ  cįŗ­p nhįŗ­t cĆ”c định dįŗ”ng được hį»— trợ, vui lòng tham khįŗ£o tĆ i liệu LibreOffice", + "submit": "Chuyển đổi sang PDF" + }, + "ocr": { + "tags": "nhįŗ­n dįŗ”ng,văn bįŗ£n,hƬnh įŗ£nh,quĆ©t,Ä‘į»c,nhįŗ­n dįŗ”ng,phĆ”t hiện,có thể chỉnh sį»­a", + "title": "OCR / LĆ m sįŗ”ch bįŗ£n Scan", + "header": "LĆ m sįŗ”ch cĆ”c bįŗ£n Scan / OCR (Nhįŗ­n dįŗ”ng ký tį»± quang hį»c)", + "selectText": { + "1": "Chį»n ngĆ“n ngữ cįŗ§n được phĆ”t hiện trong PDF (Những ngĆ“n ngữ được liệt kĆŖ lĆ  những ngĆ“n ngữ hiện đang được phĆ”t hiện):", + "2": "Tįŗ”o tệp văn bįŗ£n chứa văn bįŗ£n OCR cùng vį»›i PDF đã được OCR", + "3": "Sį»­a cĆ”c trang đã được scan ở góc nghiĆŖng bįŗ±ng cĆ”ch xoay chĆŗng trở lįŗ”i vị trĆ­", + "4": "LĆ m sįŗ”ch trang Ä‘į»ƒ giįŗ£m khįŗ£ năng OCR sįŗ½ tƬm thįŗ„y văn bįŗ£n trong nhiį»…u nền. (KhĆ“ng thay đổi đầu ra)", + "5": "LĆ m sįŗ”ch trang Ä‘į»ƒ giįŗ£m khįŗ£ năng OCR sįŗ½ tƬm thįŗ„y văn bįŗ£n trong nhiį»…u nền, duy trƬ lĆ m sįŗ”ch trong đầu ra.", + "6": "Bį» qua cĆ”c trang có văn bįŗ£n tʰʔng tĆ”c, chỉ OCR cĆ”c trang lĆ  hƬnh įŗ£nh", + "7": "BįŗÆt buį»™c OCR, sįŗ½ OCR mį»i trang vĆ  xóa tįŗ„t cįŗ£ cĆ”c phįŗ§n tį»­ văn bįŗ£n gốc", + "8": "BƬnh thĘ°į»ng (Sįŗ½ bĆ”o lį»—i nįŗæu PDF chứa văn bįŗ£n)", + "9": "CĆ i đặt bổ sung", + "10": "Chįŗæ độ OCR", + "11": "Xóa hƬnh įŗ£nh sau khi OCR (Xóa Tįŗ¤T Cįŗ¢ hƬnh įŗ£nh, chỉ hữu Ć­ch nįŗæu lĆ  mį»™t phįŗ§n cį»§a bước chuyển đổi)", + "12": "Loįŗ”i hiển thị (NĆ¢ng cao)" + }, + "help": "Vui lòng Ä‘į»c tĆ i liệu nĆ y về cĆ”ch sį»­ dỄng cho cĆ”c ngĆ“n ngữ khĆ”c vĆ /hoįŗ·c sį»­ dỄng khĆ“ng trong docker", + "credit": "Dịch vỄ nĆ y sį»­ dỄng qpdf vĆ  Tesseract cho OCR.", + "submit": "Xį»­ lý PDF vį»›i OCR" + }, + "extractImages": { + "tags": "hƬnh įŗ£nh,įŗ£nh,lʰu,lʰu trữ,zip,chỄp,lįŗ„y", + "title": "TrĆ­ch xuįŗ„t hƬnh įŗ£nh", + "header": "TrĆ­ch xuįŗ„t hƬnh įŗ£nh", + "selectText": "Chį»n định dįŗ”ng hƬnh įŗ£nh Ä‘į»ƒ chuyển đổi hƬnh įŗ£nh đã trĆ­ch xuįŗ„t", + "allowDuplicates": "Save duplicate images", + "submit": "TrĆ­ch xuįŗ„t" + }, + "pdfToPDFA": { + "tags": "lʰu trữ,dĆ i hįŗ”n,tiĆŖu chuįŗ©n,chuyển đổi,lʰu trữ,bįŗ£o quįŗ£n", + "title": "PDF sang PDF/A", + "header": "PDF sang PDF/A", + "credit": "Dịch vỄ nĆ y sį»­ dỄng libreoffice Ä‘į»ƒ chuyển đổi PDF/A", + "submit": "Chuyển đổi", + "tip": "Hiện tįŗ”i khĆ“ng hoįŗ”t động vį»›i nhiều đầu vĆ o cùng lĆŗc", + "outputFormat": "Định dįŗ”ng đầu ra", + "pdfWithDigitalSignature": "PDF chứa chữ ký số. Điều nĆ y sįŗ½ bị xóa trong bước tiįŗæp theo." + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,chuyển đổi,định dįŗ”ng,chuyển đổi,văn phòng,microsoft,tệp doc", + "title": "PDF sang Word", + "header": "PDF sang Word", + "selectText": { + "1": "Định dįŗ”ng tệp đầu ra" + }, + "credit": "Dịch vỄ nĆ y sį»­ dỄng LibreOffice Ä‘į»ƒ chuyển đổi tệp.", + "submit": "Chuyển đổi" + }, + "PDFToPresentation": { + "tags": "slides,trƬnh chiįŗæu,văn phòng,microsoft", + "title": "PDF sang bĆ i thuyįŗæt trƬnh", + "header": "PDF sang bĆ i thuyįŗæt trƬnh", + "selectText": { + "1": "Định dįŗ”ng tệp đầu ra" + }, + "credit": "Dịch vỄ nĆ y sį»­ dỄng LibreOffice Ä‘į»ƒ chuyển đổi tệp.", + "submit": "Chuyển đổi" + }, + "PDFToText": { + "tags": "định dįŗ”ng phong phĆŗ,định dįŗ”ng văn bįŗ£n phong phĆŗ,định dįŗ”ng văn bįŗ£n phong phĆŗ", + "title": "PDF sang RTF (Văn bįŗ£n)", + "header": "PDF sang RTF (Văn bįŗ£n)", + "selectText": { + "1": "Định dįŗ”ng tệp đầu ra" + }, + "credit": "Dịch vỄ nĆ y sį»­ dỄng LibreOffice Ä‘į»ƒ chuyển đổi tệp.", + "submit": "Chuyển đổi" + }, + "PDFToHTML": { + "tags": "nį»™i dung web,thĆ¢n thiện vį»›i trƬnh duyệt", + "title": "PDF sang HTML", + "header": "PDF sang HTML", + "credit": "Dịch vỄ nĆ y sį»­ dỄng pdftohtml Ä‘į»ƒ chuyển đổi tệp.", + "submit": "Chuyển đổi" + }, + "PDFToXML": { + "tags": "trĆ­ch xuįŗ„t dữ liệu,nį»™i dung có cįŗ„u trĆŗc,tʰʔng tĆ”c,chuyển đổi,chuyển", + "title": "PDF sang XML", + "header": "PDF sang XML", + "credit": "Dịch vỄ nĆ y sį»­ dỄng LibreOffice Ä‘į»ƒ chuyển đổi tệp.", + "submit": "Chuyển đổi" + }, + "ScannerImageSplit": { + "tags": "tĆ”ch,tį»± động phĆ”t hiện,quĆ©t,nhiều įŗ£nh,sįŗÆp xįŗæp", + "selectText": { + "1": "NgưỔng góc:", + "2": "Đặt góc tuyệt đối tối thiểu cįŗ§n thiįŗæt Ä‘į»ƒ xoay hƬnh įŗ£nh (mįŗ·c định: 10).", + "3": "Dung sai:", + "4": "XĆ”c định phįŗ”m vi biįŗæn đổi mĆ u sįŗÆc xung quanh mĆ u nền ước tĆ­nh (mįŗ·c định: 30).", + "5": "Diện tĆ­ch tối thiểu:", + "6": "Đặt ngưỔng diện tĆ­ch tối thiểu cho mį»™t įŗ£nh (mįŗ·c định: 10000).", + "7": "Diện tĆ­ch Ä‘Ę°į»ng viền tối thiểu:", + "8": "Đặt ngưỔng diện tĆ­ch Ä‘Ę°į»ng viền tối thiểu cho mį»™t įŗ£nh", + "9": "KĆ­ch thước viền:", + "10": "Đặt kĆ­ch thước cį»§a viền được thĆŖm vĆ o vĆ  loįŗ”i bį» Ä‘į»ƒ ngăn chįŗ·n viền trįŗÆng trong đầu ra (mįŗ·c định: 1)." + }, + "info": "Python is not installed. It is required to run." + }, + "sign": { + "tags": "į»§y quyền,ký tįŗÆt,chữ ký vįŗ½,ký văn bįŗ£n,chữ ký hƬnh įŗ£nh", + "title": "Ký", + "header": "Ký PDF", + "upload": "Tįŗ£i lĆŖn hƬnh įŗ£nh", + "draw": "Vįŗ½ chữ ký", + "text": "Nhįŗ­p văn bįŗ£n", + "clear": "Xóa", + "add": "ThĆŖm", + "saved": "Saved Signatures", + "save": "Save Signature", + "personalSigs": "Personal Signatures", + "sharedSigs": "Shared Signatures", + "noSavedSigs": "No saved signatures found", + "addToAll": "Add to all pages", + "delete": "Delete", + "first": "First page", + "last": "Last page", + "next": "Next page", + "previous": "Previous page", + "maintainRatio": "Toggle maintain aspect ratio", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "tÄ©nh,vĆ“ hiệu hóa,khĆ“ng tʰʔng tĆ”c,tinh giįŗ£n", + "title": "LĆ m phįŗ³ng", + "header": "LĆ m phįŗ³ng PDF", + "flattenOnlyForms": "Chỉ lĆ m phįŗ³ng biểu mįŗ«u", + "submit": "LĆ m phįŗ³ng" + }, + "repair": { + "tags": "sį»­a,khĆ“i phỄc,sį»­a chữa,phỄc hồi", + "title": "Sį»­a chữa", + "header": "Sį»­a chữa PDF", + "submit": "Sį»­a chữa" + }, + "removeBlanks": { + "tags": "dį»n dįŗ¹p,tinh giįŗ£n,khĆ“ng nį»™i dung,sįŗÆp xįŗæp", + "title": "Xóa trang trįŗÆng", + "header": "Xóa trang trįŗÆng", + "threshold": "NgưỔng độ trįŗÆng cį»§a pixel:", + "thresholdDesc": "NgưỔng Ä‘į»ƒ xĆ”c định mức độ trįŗÆng cį»§a mį»™t pixel Ä‘į»ƒ được coi lĆ  'TrįŗÆng'. 0 = Đen, 255 trįŗÆng tinh khiįŗæt.", + "whitePercent": "Phįŗ§n trăm trįŗÆng (%):", + "whitePercentDesc": "Phįŗ§n trăm cį»§a trang phįŗ£i lĆ  pixel 'trįŗÆng' Ä‘į»ƒ bị xóa", + "submit": "Xóa trang trįŗÆng" + }, + "removeAnnotations": { + "tags": "bƬnh luįŗ­n,đƔnh dįŗ„u,ghi chĆŗ,đƔnh dįŗ„u,xóa", + "title": "Xóa chĆŗ thĆ­ch", + "header": "Xóa chĆŗ thĆ­ch", + "submit": "Xóa" + }, + "compare": { + "tags": "phĆ¢n biệt,đối chiįŗæu,thay đổi,phĆ¢n tĆ­ch", + "title": "So sĆ”nh", + "header": "So sĆ”nh PDF", + "highlightColor": { + "1": "MĆ u đƔnh dįŗ„u 1:", + "2": "MĆ u đƔnh dįŗ„u 2:" + }, + "document": { + "1": "TĆ i liệu 1", + "2": "TĆ i liệu 2" + }, + "submit": "So sĆ”nh", + "complex": { + "message": "One or both of the provided documents are large files, accuracy of comparison may be reduced" + }, + "large": { + "file": { + "message": "One or Both of the provided documents are too large to process" + } + }, + "no": { + "text": { + "message": "One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison." + } + } + }, + "certSign": { + "tags": "xĆ”c thį»±c,PEM,P12,chĆ­nh thức,mĆ£ hóa", + "title": "Ký bįŗ±ng chứng chỉ", + "header": "Ký PDF bįŗ±ng chứng chỉ cį»§a bįŗ”n (Đang trong quĆ” trƬnh phĆ”t triển)", + "selectPDF": "Chį»n tệp PDF Ä‘į»ƒ ký:", + "jksNote": "Lʰu ý: Nįŗæu loįŗ”i chứng chỉ cį»§a bįŗ”n khĆ“ng được liệt kĆŖ bĆŖn dưới, vui lòng chuyển đổi nó thĆ nh tệp Java Keystore (.jks) bįŗ±ng cĆ“ng cỄ dòng lệnh keytool. Sau đó, chį»n tùy chį»n tệp .jks bĆŖn dưới.", + "selectKey": "Chį»n tệp khóa riĆŖng cį»§a bįŗ”n (định dįŗ”ng PKCS#8, có thể lĆ  .pem hoįŗ·c .der):", + "selectCert": "Chį»n tệp chứng chỉ cį»§a bįŗ”n (định dįŗ”ng X.509, có thể lĆ  .pem hoįŗ·c .der):", + "selectP12": "Chį»n tệp Keystore PKCS#12 cį»§a bįŗ”n (.p12 hoįŗ·c .pfx) (Tùy chį»n, nįŗæu cung cįŗ„p, nó phįŗ£i chứa khóa riĆŖng vĆ  chứng chỉ cį»§a bįŗ”n):", + "selectJKS": "Chį»n tệp Java Keystore cį»§a bįŗ”n (.jks hoįŗ·c .keystore):", + "certType": "Loįŗ”i chứng chỉ", + "password": "Nhįŗ­p mįŗ­t khįŗ©u Keystore hoįŗ·c Private Key cį»§a bįŗ”n (Nįŗæu có):", + "showSig": "Hiển thị chữ ký", + "reason": "Lý do", + "location": "Vị trĆ­", + "name": "TĆŖn", + "showLogo": "Show Logo", + "submit": "Ký PDF" + }, + "removeCertSign": { + "tags": "xĆ”c thį»±c,PEM,P12,chĆ­nh thức,giįŗ£i mĆ£", + "title": "Xóa chữ ký chứng chỉ", + "header": "Xóa chứng chỉ số khį»i PDF", + "selectPDF": "Chį»n mį»™t tệp PDF:", + "submit": "Xóa chữ ký" + }, + "pageLayout": { + "tags": "ghĆ©p,tổng hợp,xem đʔn,sįŗÆp xįŗæp", + "title": "Bố cỄc nhiều trang", + "header": "Bố cỄc nhiều trang", + "pagesPerSheet": "Số trang trĆŖn mį»™t tį»:", + "addBorder": "ThĆŖm viền", + "submit": "Gį»­i" + }, + "scalePages": { + "tags": "điều chỉnh kĆ­ch thước,sį»­a đổi,kĆ­ch thước,điều chỉnh", + "title": "Điều chỉnh tį»· lệ trang", + "header": "Điều chỉnh tį»· lệ trang", + "pageSize": "KĆ­ch thước cį»§a mį»™t trang trong tĆ i liệu.", + "keepPageSize": "Original Size", + "scaleFactor": "Mức độ phóng to (cįŗÆt cĆŗp) cį»§a mį»™t trang.", + "submit": "Gį»­i" + }, + "add-page-numbers": { + "tags": "đƔnh số trang,gįŗÆn nhĆ£n,sįŗÆp xįŗæp,chỉ mỄc" + }, + "auto-rename": { + "tags": "tį»± động phĆ”t hiện,dį»±a trĆŖn tiĆŖu đề,sįŗÆp xįŗæp,đổi nhĆ£n", + "title": "Tį»± động đổi tĆŖn", + "header": "Tį»± động đổi tĆŖn PDF", + "submit": "Tį»± động đổi tĆŖn" + }, + "adjust-contrast": { + "tags": "hiệu chỉnh mĆ u sįŗÆc,điều chỉnh,sį»­a đổi,nĆ¢ng cao" + }, + "crop": { + "tags": "cįŗÆt tỉa,thu nhį»,chỉnh sį»­a,định hƬnh", + "title": "CįŗÆt cĆŗp", + "header": "CįŗÆt cĆŗp PDF", + "submit": "Gį»­i" + }, + "autoSplitPDF": { + "tags": "Dį»±a trĆŖn QR,tĆ”ch,phĆ¢n đoįŗ”n quĆ©t,sįŗÆp xįŗæp", + "title": "Tį»± động chia PDF", + "header": "Tį»± động chia PDF", + "description": "In, chĆØn, quĆ©t, tįŗ£i lĆŖn vĆ  Ä‘į»ƒ chĆŗng tĆ“i tį»± động tĆ”ch tĆ i liệu cį»§a bįŗ”n. KhĆ“ng cįŗ§n sįŗÆp xįŗæp thį»§ cĆ“ng.", + "selectText": { + "1": "In mį»™t số trang phĆ¢n cĆ”ch từ bĆŖn dưới (Đen trįŗÆng lĆ  được).", + "2": "QuĆ©t tįŗ„t cįŗ£ tĆ i liệu cį»§a bįŗ”n cùng mį»™t lĆŗc bįŗ±ng cĆ”ch chĆØn trang phĆ¢n cĆ”ch giữa chĆŗng.", + "3": "Tįŗ£i lĆŖn tệp PDF quĆ©t lį»›n duy nhįŗ„t vĆ  Ä‘į»ƒ Stirling PDF xį»­ lý phįŗ§n còn lįŗ”i.", + "4": "CĆ”c trang phĆ¢n cĆ”ch được tį»± động phĆ”t hiện vĆ  xóa, đảm bįŗ£o tĆ i liệu cuối cùng gį»n gĆ ng." + }, + "formPrompt": "Gį»­i PDF chứa trang phĆ¢n cĆ”ch Stirling-PDF:", + "duplexMode": "Chįŗæ độ hai mįŗ·t (QuĆ©t mįŗ·t trước vĆ  sau)", + "dividerDownload2": "Tįŗ£i xuống 'Trang phĆ¢n cĆ”ch tį»± động (có hướng dįŗ«n).pdf'", + "submit": "Gį»­i" + }, + "sanitizePdf": { + "tags": "lĆ m sįŗ”ch,bįŗ£o mįŗ­t,an toĆ n,loįŗ”i bį» mối đe dį»a" + }, + "URLToPDF": { + "tags": "chỄp web,lʰu trang,web sang tĆ i liệu,lʰu trữ", + "title": "URL sang PDF", + "header": "URL sang PDF", + "submit": "Chuyển đổi", + "credit": "Sį»­ dỄng WeasyPrint" + }, + "HTMLToPDF": { + "tags": "đƔnh dįŗ„u,nį»™i dung web,chuyển đổi,chuyển", + "title": "HTML sang PDF", + "header": "HTML sang PDF", + "help": "Chįŗ„p nhįŗ­n tệp HTML vĆ  ZIP chứa html/css/hƬnh įŗ£nh cįŗ§n thiįŗæt", + "submit": "Chuyển đổi", + "credit": "Sį»­ dỄng WeasyPrint", + "zoom": "Mức độ phóng to Ä‘į»ƒ hiển thị trang web.", + "pageWidth": "Chiều rį»™ng trang tĆ­nh bįŗ±ng cm. (Để trống Ä‘į»ƒ mįŗ·c định)", + "pageHeight": "Chiều cao trang tĆ­nh bįŗ±ng cm. (Để trống Ä‘į»ƒ mįŗ·c định)", + "marginTop": "Lề trĆŖn cį»§a trang tĆ­nh bįŗ±ng mm. (Để trống Ä‘į»ƒ mįŗ·c định)", + "marginBottom": "Lề dưới cį»§a trang tĆ­nh bįŗ±ng mm. (Để trống Ä‘į»ƒ mįŗ·c định)", + "marginLeft": "Lề trĆ”i cį»§a trang tĆ­nh bįŗ±ng mm. (Để trống Ä‘į»ƒ mįŗ·c định)", + "marginRight": "Lề phįŗ£i cį»§a trang tĆ­nh bįŗ±ng mm. (Để trống Ä‘į»ƒ mįŗ·c định)", + "printBackground": "Hiển thị nền cį»§a trang web.", + "defaultHeader": "Bįŗ­t tiĆŖu đề mįŗ·c định (TĆŖn vĆ  số trang)", + "cssMediaType": "Thay đổi loįŗ”i phʰʔng tiện CSS cį»§a trang.", + "none": "KhĆ“ng", + "print": "In", + "screen": "MĆ n hƬnh" + }, + "MarkdownToPDF": { + "tags": "đƔnh dįŗ„u,nį»™i dung web,chuyển đổi,chuyển", + "title": "Markdown sang PDF", + "header": "Markdown sang PDF", + "submit": "Chuyển đổi", + "help": "Đang trong quĆ” trƬnh phĆ”t triển", + "credit": "Sį»­ dỄng WeasyPrint" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "thĆ“ng tin,dữ liệu,số liệu thống kĆŖ,thống kĆŖ", + "title": "Lįŗ„y thĆ“ng tin PDF", + "header": "Lįŗ„y thĆ“ng tin PDF", + "submit": "Lįŗ„y thĆ“ng tin", + "downloadJson": "Tįŗ£i xuống JSON" + }, + "extractPage": { + "tags": "trĆ­ch xuįŗ„t" + }, + "PdfToSinglePage": { + "tags": "trang đʔn" + }, + "showJS": { + "tags": "JS", + "title": "Hiển thị Javascript", + "header": "Hiển thị Javascript", + "downloadJS": "Tįŗ£i xuống Javascript", + "submit": "Hiển thị" + }, + "autoRedact": { + "tags": "BiĆŖn tįŗ­p,įŗØn,che đen,đen,bĆŗt đƔnh dįŗ„u,įŗ©n", + "title": "Tį»± động biĆŖn tįŗ­p", + "header": "Tį»± động biĆŖn tįŗ­p", + "colorLabel": "MĆ u sįŗÆc", + "textsToRedactLabel": "Văn bįŗ£n cįŗ§n biĆŖn tįŗ­p (mį»—i dòng mį»™t từ)", + "textsToRedactPlaceholder": "vĆ­ dỄ: \\nMįŗ­t \\nTối mįŗ­t", + "useRegexLabel": "Sį»­ dỄng Regex", + "wholeWordSearchLabel": "TƬm kiįŗæm toĆ n bį»™ từ", + "customPaddingLabel": "Đệm thĆŖm tùy chỉnh", + "convertPDFToImageLabel": "Chuyển đổi PDF thĆ nh PDF-HƬnh įŗ£nh (Dùng Ä‘į»ƒ xóa văn bįŗ£n phĆ­a sau Ć“)", + "submitButton": "Gį»­i" + }, + "redact": { + "tags": "Redact,Hide,black out,black,marker,hidden,manual", + "title": "Manual Redaction", + "header": "Manual Redaction", + "submit": "Redact", + "textBasedRedaction": "Text based Redaction", + "pageBasedRedaction": "Page-based Redaction", + "convertPDFToImageLabel": "Convert PDF to PDF-Image (Used to remove text behind the box)", + "pageRedactionNumbers": { + "title": "Pages", + "placeholder": "(e.g. 1,2,8 or 4,7,12-16 or 2n-1)" + }, + "redactionColor": { + "title": "Redaction Color" + }, + "export": "Export", + "upload": "Upload", + "boxRedaction": "Box draw redaction", + "zoom": "Zoom", + "zoomIn": "Zoom in", + "zoomOut": "Zoom out", + "nextPage": "Next Page", + "previousPage": "Previous Page", + "toggleSidebar": "Toggle Sidebar", + "showThumbnails": "Show Thumbnails", + "showDocumentOutline": "Show Document Outline (double-click to expand/collapse all items)", + "showAttatchments": "Show Attachments", + "showLayers": "Show Layers (double-click to reset all layers to the default state)", + "colourPicker": "Colour Picker", + "findCurrentOutlineItem": "Find current outline item", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,TrĆ­ch xuįŗ„t bįŗ£ng,trĆ­ch xuįŗ„t,chuyển đổi" + }, + "autoSizeSplitPDF": { + "tags": "pdf,chia,tĆ i liệu,tổ chức" + }, + "overlay-pdfs": { + "tags": "Chồng lį»›p", + "header": "Chồng lį»›p tệp PDF", + "baseFile": { + "label": "Chį»n tệp PDF nền" + }, + "overlayFiles": { + "label": "Chį»n cĆ”c tệp PDF chồng lį»›p" + }, + "mode": { + "label": "Chį»n chįŗæ độ chồng lį»›p", + "sequential": "Chồng lį»›p tuįŗ§n tį»±", + "interleaved": "Chồng lį»›p xen kįŗ½", + "fixedRepeat": "Chồng lį»›p lįŗ·p lįŗ”i cố định" + }, + "counts": { + "label": "Số lįŗ§n chồng lį»›p (cho chįŗæ độ lįŗ·p lįŗ”i cố định)", + "placeholder": "Nhįŗ­p số lįŗ§n chồng lį»›p, phĆ¢n cĆ”ch bįŗ±ng dįŗ„u phįŗ©y (vĆ­ dỄ: 2,3,1)" + }, + "position": { + "label": "Chį»n vị trĆ­ chồng lį»›p", + "foreground": "Nền trước", + "background": "Nền sau" + }, + "submit": "Gį»­i" + }, + "split-by-sections": { + "tags": "Chia phįŗ§n,PhĆ¢n chia,Tùy chỉnh", + "title": "Chia PDF theo phįŗ§n", + "header": "Chia PDF thĆ nh cĆ”c phįŗ§n", + "horizontal": { + "label": "PhĆ¢n chia theo chiều ngang", + "placeholder": "Nhįŗ­p số lượng phĆ¢n chia theo chiều ngang" + }, + "vertical": { + "label": "PhĆ¢n chia theo chiều dį»c", + "placeholder": "Nhįŗ­p số lượng phĆ¢n chia theo chiều dį»c" + }, + "submit": "Chia PDF", + "merge": "Trį»™n thĆ nh mį»™t PDF" + }, + "AddStampRequest": { + "tags": "Dįŗ„u,ThĆŖm hƬnh įŗ£nh,căn giữa hƬnh įŗ£nh,HƬnh mį»,PDF,NhĆŗng,Tùy chỉnh", + "header": "Đóng dįŗ„u PDF", + "title": "Đóng dįŗ„u PDF", + "stampType": "Loįŗ”i dįŗ„u", + "stampText": "Văn bįŗ£n dįŗ„u", + "stampImage": "HƬnh įŗ£nh dįŗ„u", + "alphabet": "Bįŗ£ng chữ cĆ”i", + "fontSize": "Cį»” chữ/KĆ­ch thước hƬnh įŗ£nh", + "rotation": "Xoay", + "opacity": "Độ mį»", + "position": "Vị trĆ­", + "overrideX": "Ghi đè tį»a độ X", + "overrideY": "Ghi đè tį»a độ Y", + "customMargin": "Lề tùy chỉnh", + "customColor": "MĆ u văn bįŗ£n tùy chỉnh", + "submit": "Gį»­i" + }, + "removeImagePdf": { + "tags": "Remove Image,Page operations,Back end,server side" + }, + "splitPdfByChapters": { + "tags": "split,chapters,bookmarks,organize" + }, + "validateSignature": { + "tags": "signature,verify,validate,pdf,certificate,digital signature,Validate Signature,Validate certificate", + "title": "Validate PDF Signatures", + "header": "Validate Digital Signatures", + "selectPDF": "Select signed PDF file", + "submit": "Validate Signatures", + "results": "Validation Results", + "status": { + "_value": "Status", + "valid": "Valid", + "invalid": "Invalid" + }, + "signer": "Signer", + "date": "Date", + "reason": "Reason", + "location": "Location", + "noSignatures": "No digital signatures found in this document", + "chain": { + "invalid": "Certificate chain validation failed - cannot verify signer's identity" + }, + "trust": { + "invalid": "Certificate not in trust store - source cannot be verified" + }, + "cert": { + "expired": "Certificate has expired", + "revoked": "Certificate has been revoked", + "info": "Certificate Details", + "issuer": "Issuer", + "subject": "Subject", + "serialNumber": "Serial Number", + "validFrom": "Valid From", + "validUntil": "Valid Until", + "algorithm": "Algorithm", + "keySize": "Key Size", + "version": "Version", + "keyUsage": "Key Usage", + "selfSigned": "Self-Signed", + "bits": "bits" + }, + "signature": { + "info": "Signature Information", + "_value": "Signature", + "mathValid": "Signature is mathematically valid BUT:" + }, + "selectCustomCert": "Custom Certificate File X.509 (Optional)" + }, + "replace-color": { + "title": "Replace-Invert-Color", + "header": "Replace-Invert Color PDF", + "selectText": { + "1": "Replace or Invert color Options", + "2": "Default(Default high contrast colors)", + "3": "Custom(Customized colors)", + "4": "Full-Invert(Invert all colors)", + "5": "High contrast color options", + "6": "white text on black background", + "7": "Black text on white background", + "8": "Yellow text on black background", + "9": "Green text on black background", + "10": "Choose text Color", + "11": "Choose background Color" + }, + "submit": "Replace" + }, + "replaceColorPdf": { + "tags": "Replace Color,Page operations,Back end,server side" + }, + "login": { + "title": "Đăng nhįŗ­p", + "header": "Đăng nhįŗ­p", + "signin": "Đăng nhįŗ­p", + "rememberme": "Ghi nhį»› tĆ“i", + "invalid": "TĆŖn đăng nhįŗ­p hoįŗ·c mįŗ­t khįŗ©u khĆ“ng hợp lệ.", + "locked": "TĆ i khoįŗ£n cį»§a bįŗ”n đã bị khóa.", + "signinTitle": "Vui lòng đăng nhįŗ­p", + "ssoSignIn": "Đăng nhįŗ­p qua Single Sign-on", + "oAuth2AutoCreateDisabled": "Tį»± động tįŗ”o ngĘ°į»i dùng OAUTH2 bị vĆ“ hiệu hóa", + "oAuth2AdminBlockedUser": "Registration or logging in of non-registered users is currently blocked. Please contact the administrator.", + "oauth2RequestNotFound": "KhĆ“ng tƬm thįŗ„y yĆŖu cįŗ§u į»§y quyền", + "oauth2InvalidUserInfoResponse": "Phįŗ£n hồi thĆ“ng tin ngĘ°į»i dùng khĆ“ng hợp lệ", + "oauth2invalidRequest": "YĆŖu cįŗ§u khĆ“ng hợp lệ", + "oauth2AccessDenied": "Truy cįŗ­p bị từ chối", + "oauth2InvalidTokenResponse": "Phįŗ£n hồi token khĆ“ng hợp lệ", + "oauth2InvalidIdToken": "Id Token khĆ“ng hợp lệ", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "User is deactivated, login is currently blocked with this username. Please contact the administrator.", + "alreadyLoggedIn": "You are already logged in to", + "alreadyLoggedIn2": "devices. Please log out of the devices and try again.", + "toManySessions": "You have too many active sessions", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF thĆ nh mį»™t trang", + "header": "PDF thĆ nh mį»™t trang", + "submit": "Chuyển đổi thĆ nh mį»™t trang" + }, + "pageExtracter": { + "title": "TrĆ­ch xuįŗ„t trang", + "header": "TrĆ­ch xuįŗ„t trang", + "submit": "TrĆ­ch xuįŗ„t", + "placeholder": "(vĆ­ dỄ: 1,2,8 hoįŗ·c 4,7,12-16 hoįŗ·c 2n-1)" + }, + "sanitizePDF": { + "title": "LĆ m sįŗ”ch PDF", + "header": "LĆ m sįŗ”ch tệp PDF", + "selectText": { + "1": "Xóa cĆ”c hĆ nh động JavaScript", + "2": "Xóa cĆ”c tệp nhĆŗng", + "3": "Remove XMP metadata", + "4": "Xóa liĆŖn kįŗæt", + "5": "Xóa phĆ“ng chữ", + "6": "Remove Document Info Metadata" + }, + "submit": "LĆ m sįŗ”ch PDF" + }, + "adjustContrast": { + "title": "Điều chỉnh độ tʰʔng phįŗ£n", + "header": "Điều chỉnh độ tʰʔng phįŗ£n", + "contrast": "Độ tʰʔng phįŗ£n:", + "brightness": "Độ sĆ”ng:", + "saturation": "Độ bĆ£o hòa:", + "download": "Tįŗ£i xuống" + }, + "compress": { + "title": "NĆ©n", + "header": "NĆ©n PDF", + "credit": "Dịch vỄ nĆ y sį»­ dỄng qpdf Ä‘į»ƒ NĆ©n/Tối ʰu hóa PDF.", + "grayscale": { + "label": "Ɓp dỄng thang độ xĆ”m Ä‘į»ƒ nĆ©n" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Mức độ tối ʰu hóa:", + "4": "Chįŗæ độ tį»± động - Tį»± động điều chỉnh chįŗ„t lượng Ä‘į»ƒ đẔt được kĆ­ch thước PDF chĆ­nh xĆ”c", + "5": "KĆ­ch thước PDF mong muốn (vĆ­ dỄ: 25MB, 10.8MB, 25KB)" + }, + "submit": "NĆ©n" + }, + "decrypt": { + "passwordPrompt": "This file is password-protected. Please enter the password:", + "cancelled": "Operation cancelled for PDF: {0}", + "noPassword": "No password provided for encrypted PDF: {0}", + "invalidPassword": "Please try again with the correct password.", + "invalidPasswordHeader": "Incorrect password or unsupported encryption for PDF: {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "File decrypted successfully." + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "Xóa trang", + "header": "Xóa trang PDF", + "pagesToDelete": "CĆ”c trang cįŗ§n xóa (Nhįŗ­p danh sĆ”ch số trang được phĆ¢n cĆ”ch bįŗ±ng dįŗ„u phįŗ©y) :", + "submit": "Xóa trang", + "placeholder": "(vĆ­ dỄ: 1,2,6 hoįŗ·c 1-10,15-30)" + }, + "imageToPDF": { + "title": "HƬnh įŗ£nh sang PDF", + "header": "HƬnh įŗ£nh sang PDF", + "submit": "Chuyển đổi", + "selectLabel": "Tùy chį»n điều chỉnh hƬnh įŗ£nh", + "fillPage": "Lįŗ„p đầy trang", + "fitDocumentToImage": "Điều chỉnh trang theo hƬnh įŗ£nh", + "maintainAspectRatio": "Giữ tį»· lệ khung hƬnh", + "selectText": { + "2": "Tį»± động xoay PDF", + "3": "Logic đa tệp (Chỉ được bįŗ­t khi lĆ m việc vį»›i nhiều hƬnh įŗ£nh)", + "4": "Trį»™n thĆ nh mį»™t PDF duy nhįŗ„t", + "5": "Chuyển đổi thĆ nh cĆ”c PDF riĆŖng biệt" + } + }, + "PDFToCSV": { + "title": "PDF sang CSV", + "header": "PDF sang CSV", + "prompt": "Chį»n trang Ä‘į»ƒ trĆ­ch xuįŗ„t bįŗ£ng", + "submit": "TrĆ­ch xuįŗ„t" + }, + "split-by-size-or-count": { + "title": "Chia PDF theo kĆ­ch thước hoįŗ·c số lượng", + "header": "Chia PDF theo kĆ­ch thước hoįŗ·c số lượng", + "type": { + "label": "Chį»n loįŗ”i chia", + "size": "Theo kĆ­ch thước", + "pageCount": "Theo số trang", + "docCount": "Theo số tĆ i liệu" + }, + "value": { + "label": "Nhįŗ­p giĆ” trị", + "placeholder": "Nhįŗ­p kĆ­ch thước (vĆ­ dỄ: 2MB hoįŗ·c 3KB) hoįŗ·c số lượng (vĆ­ dỄ: 5)" + }, + "submit": "Gį»­i" + }, + "printFile": { + "title": "In tệp", + "header": "In tệp vĆ o mĆ”y in", + "selectText": { + "1": "Chį»n tệp Ä‘į»ƒ in", + "2": "Nhįŗ­p tĆŖn mĆ”y in" + }, + "submit": "In" + }, + "licenses": { + "nav": "Giįŗ„y phĆ©p", + "title": "Giįŗ„y phĆ©p bĆŖn thứ 3", + "header": "Giįŗ„y phĆ©p bĆŖn thứ 3", + "module": "Module", + "version": "PhiĆŖn bįŗ£n", + "license": "Giįŗ„y phĆ©p" + }, + "survey": { + "nav": "Khįŗ£o sĆ”t", + "title": "Khįŗ£o sĆ”t Stirling-PDF", + "description": "Stirling-PDF khĆ“ng có cĆ i đặt theo dƵi nĆŖn chĆŗng tĆ“i muốn nghe từ ngĘ°į»i dùng Ä‘į»ƒ cįŗ£i thiện Stirling-PDF!", + "changes": "Stirling-PDF has changed since the last survey! To find out more please check our blog post here:", + "changes2": "With these changes we are getting paid business support and funding", + "please": "Vui lòng cĆ¢n nhįŗÆc tham gia khįŗ£o sĆ”t cį»§a chĆŗng tĆ“i!", + "disabled": "(Cį»­a sổ popup khįŗ£o sĆ”t sįŗ½ bị vĆ“ hiệu hóa trong cĆ”c bįŗ£n cįŗ­p nhįŗ­t tiįŗæp theo nhʰng vįŗ«n tƬm thįŗ„y ở cuối trang)", + "button": "Tham gia khįŗ£o sĆ”t", + "dontShowAgain": "KhĆ“ng hiển thị lįŗ”i", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "Remove image", + "header": "Remove image", + "removeImage": "Remove image", + "submit": "Remove image" + }, + "splitByChapters": { + "title": "Split PDF by Chapters", + "header": "Split PDF by Chapters", + "bookmarkLevel": "Bookmark Level", + "includeMetadata": "Include Metadata", + "allowDuplicates": "Allow Duplicates", + "desc": { + "1": "This tool splits a PDF file into multiple PDFs based on its chapter structure.", + "2": "Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).", + "3": "Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.", + "4": "Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs." + }, + "submit": "Split PDF" + }, + "fileChooser": { + "click": "Click", + "or": "or", + "dragAndDrop": "Drag & Drop", + "dragAndDropPDF": "Drag & Drop PDF file", + "dragAndDropImage": "Drag & Drop Image file", + "hoveredDragAndDrop": "Drag & Drop file(s) here", + "extractPDF": "Extracting..." + }, + "releases": { + "footer": "Releases", + "title": "Release Notes", + "header": "Release Notes", + "current": { + "version": "Current Release" + }, + "note": "Release notes are only available in English" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/zh-BO/translation.json b/frontend/public/locales/zh-BO/translation.json new file mode 100644 index 000000000..7386ee7fd --- /dev/null +++ b/frontend/public/locales/zh-BO/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "ą½”ą½²ą½‚ą¼‹ą½‚ą½Ÿą½“ą½‚ą½¦ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹", + "fontName": "ą½”ą½²ą½‚ą¼‹ą½‚ą½Ÿą½“ą½‚ą½¦ą¼‹ą½˜ą½²ą½„ą¼‹", + "title": "ą½¤ą½¼ą½‚ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "header": "ą½¤ą½¼ą½‚ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "selectText": { + "1": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "2": "ą½˜ą½ą½ ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą¼", + "3": "ą½‚ą½“ą½¦ą¼‹ą½¦ą¼", + "4": "ą½ ą½‚ą½¼ą¼‹ą½ ą½›ą½“ą½‚ą½¦ą¼‹ą½Øą½„ą¼‹ą½‚ą¾²ą½„ą½¦ą¼", + "5": "ą½Øą½„ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼", + "6": "རང་སྒྲིག་པི་གེ" + }, + "customTextDesc": "རང་སྒྲིག་པི་གེ", + "numberPagesDesc": "ą½Øą½„ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼ སྔོན་སྒྲིག་ནི་'ą½šą½„ą¼‹ą½˜ą¼‹'ą½”ą½²ą½“ą¼ 1-5 པང་ན་ 2,5,9 ą½¦ą½¼ą½‚ą½¦ą¼‹ą½€ą¾±ą½„ą¼‹ą½„ą½¼ą½¦ą¼‹ą½£ą½ŗą½“ą¼‹ą½–ą¾±ą½ŗą½‘ą¼", + "customNumberDesc": "སྔོན་སྒྲིག་ནི་ {n} ą½”ą½²ą½“ą¼ 'ཤོག་ངོས་ {n} / {total}', 'པི་གེ-{n}', '{filename}-{n}' ą½¦ą½¼ą½‚ą½¦ą¼‹ą½€ą¾±ą½„ą¼‹ą½„ą½¼ą½¦ą¼‹ą½£ą½ŗą½“ą¼‹ą½–ą¾±ą½ŗą½‘ą¼", + "submit": "ą½¤ą½¼ą½‚ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼" + }, + "pdfPrompt": "PDF ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "multiPdfPrompt": "PDF ą½‚ą½‰ą½²ą½¦ą¼‹ą½”ą½“ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "multiPdfDropPrompt": "ą½‘ą½‚ą½¼ą½¦ą¼‹ą½˜ą½ą½¼ą¼‹ą½ ą½‘ą½²ą¼‹ PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½šą½„ą¼‹ą½˜ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą½ ą½˜ą¼‹ą½ ą½ą½ŗą½“ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "imgPrompt": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "genericSubmit": "ą½•ą½“ą½£ą¼‹ą½–ą½…ą½¼ą½¦ą¼", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "ą½‰ą½ŗą½“ą¼‹ą½–ą½…ą½¼ą½¦ą¼ ą½–ą¾±ą¼‹ą½¢ą½²ą½˜ą¼‹ą½ ą½‘ą½²ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą½£ą¼‹ą½‚ą½žą½²ą½‚ą½¦ą¼‹ą½“ą½¦ą¼‹ą½¦ą¾ą½¢ą¼‹ą½˜ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½–ą½¢ą¼‹ą½ ą½‚ą½¼ą½¢ą¼‹ą½¦ą¾²ą½²ą½‘ą¼", + "pageOrderPrompt": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½¼ą¼‹ą½¢ą½²ą½˜ą¼‹ą½¢ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ļ¼ˆą½¤ą½¼ą½‚ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½ą½¼ą¼‹ą½‚ą½žą½“ą½„ą¼‹ą½„ą½˜ą¼‹ą½¢ą¾©ą½²ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½ą½–ą½¦ą¼‹ 2n+1 ą½£ą¾Ÿą¼‹ą½–ą½“ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼ļ¼‰", + "pageSelectionPrompt": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½¦ą¾’ą¾²ą½“ą½‚ļ¼ˆą½¤ą½¼ą½‚ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½ą½¼ą¼‹ą½‚ą½žą½“ą½„ą¼‹ 1,5,6 ą½ ą½˜ą¼‹ą½¢ą¾©ą½²ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½ą½–ą½¦ą¼‹ 2n+1 ą½£ą¾Ÿą¼‹ą½–ą½“ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼ļ¼‰", + "goToPage": "ą½ ą½‚ą¾²ą½¼ą¼‹ą½–ą¼", + "true": "ą½–ą½‘ą½ŗą½“ą¼‹ą½”ą¼", + "false": "ą½¢ą¾«ą½“ą½“ą¼‹ą½˜ą¼", + "unknown": "ą½˜ą½²ą¼‹ą½¤ą½ŗą½¦ą¼‹ą½”ą¼", + "save": "ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼", + "saveToBrowser": "ą½–ą½¤ą½¢ą¼‹ą½†ą½ŗą¼‹ą½“ą½„ą¼‹ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼", + "close": "ą½¦ą¾’ą½¼ą¼‹ą½¢ą½²ą½‚ą¼", + "filesSelected": "ą½”ą½²ą½‚ą¼‹ą½†ą½–ą½‘ą½˜ą½¦ą¼‹ą½Ÿą½²ą½“ą¼", + "noFavourites": "ą½‘ą½‚ą½ ą¼‹ą½˜ą½¼ą½¦ą¼‹ą½‚ą½„ą¼‹ą½”ą½„ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½˜ą½ŗą½‘ą¼", + "downloadComplete": "ą½•ą½–ą¼‹ą½£ą½ŗą½“ą¼‹ą½£ą½ŗą½‚ą½¦ą¼‹ą½‚ą¾²ą½“ą½–ą¼", + "bored": "ą½¦ą¾’ą½“ą½‚ą¼‹ą½¦ą¾”ą½¼ą½‘ą¼‹ą½¦ą¾ą¾±ą½²ą½‘ą¼‹ą½”ą½¼ą¼‹ą½˜ą½²ą¼‹ą½ ą½‘ą½“ą½‚ą¼‹ą½‚ą½˜ą¼", + "alphabet": "ą½‚ą½¦ą½£ą¼‹ą½–ą¾±ą½ŗą½‘ą¼", + "downloadPdf": "PDF ą½•ą½–ą¼‹ą½£ą½ŗą½“ą¼", + "text": "པི་གེ", + "font": "ą½”ą½²ą½‚ą¼‹ą½‚ą½Ÿą½“ą½‚ą½¦ą¼‹ą½", + "selectFillter": "-- ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼ --", + "pageNum": "ą½¤ą½¼ą½‚ą¼‹ą½‚ą½²ą½„ą½¦ą¼", + "sizes": { + "small": "ą½†ą½“ą½„ą¼‹ą½†ą½„ą¼‹ą¼", + "medium": "ą½ ą½–ą¾²ą½²ą½„ą¼‹ą½šą½‘ą¼", + "large": "ą½†ą½ŗą½“ą¼‹ą½”ą½¼ą¼", + "x-large": "ą½§ą¼‹ą½…ą½„ą¼‹ą½†ą½ŗą½“ą¼‹ą½”ą½¼ą¼" + }, + "error": { + "pdfPassword": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą½¢ą¼‹ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½–ą½€ą½¼ą½‘ą¼‹ą½”ą½¼ą½‘ą¼‹ą½”ą¼‹ą½‘ą½„ą¼‹ą¼ ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½˜ą¼‹ą½–ą½€ą½¼ą½‘ą¼‹ą½”ą½ ą½˜ą¼‹ą½“ą½¼ą½¢ą¼‹ą½ ą½‘ą½“ą½‚", + "_value": "ą½“ą½¼ą½¢ą¼‹ą½ ą½ą¾²ą½“ą½£ą¼", + "sorry": "དཀའ་ངལ་ལ་དགོངས་དག", + "needHelp": "ą½¢ą½¼ą½‚ą½¦ą¼‹ą½¢ą½˜ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼‹ą½¦ą½˜ą¼ / ą½‘ą½€ą½ ą¼‹ą½„ą½£ą¼‹ą½žą½²ą½‚ą¼‹ą½¢ą¾™ą½ŗą½‘ą¼‹ą½¦ą½¼ą½„ą¼‹ą½„ą½˜ą¼", + "contactTip": "ą½‚ą½£ą¼‹ą½¦ą¾²ą½²ą½‘ą¼‹ą½‘ą¼‹ą½‘ą½“ą½„ą¼‹ą½‘ą½€ą½ ą¼‹ą½„ą½£ą¼‹ą½ ą½•ą¾²ą½‘ą¼‹ą½–ą½žą½²ą½“ą¼‹ą½”ą½¼ą½‘ą¼‹ą½“ą¼ ą½¢ą½¼ą½‚ą½¦ą¼‹ą½¢ą½˜ą¼‹ą½žą½“ą¼‹ą½–ą½¢ą¼‹ą½„ą¼‹ą½šą½¼ą½¢ą¼‹ą½ ą½–ą¾²ą½ŗą½£ą¼‹ą½‚ą½ą½“ą½‚ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼ ą½ą¾±ą½ŗą½‘ą¼‹ą½€ą¾±ą½²ą½¦ą¼‹ą½„ą¼‹ą½šą½¼ą½ ą½²ą¼‹ GitHub ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¦ą½“ą¼‹ą½¦ą¾™ą½“ą¼‹ą½žą½“ą¼‹ą½ ą½–ą½“ą½£ą¼‹ą½–ą½ ą½˜ą¼‹ Discord བརྒྱནད་ནས་འབྲེལ་བ་གནང་ཆོག", + "404": { + "head": "404 - ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½˜ą¼‹ą½¢ą¾™ą½ŗą½‘ą¼ | ą½‘ą½‚ą½¼ą½„ą½¦ą¼‹ą½”ą¼‹ą½˜ą¼‹ą½šą½¼ą½˜ą¼ ą½„ą¼‹ą½šą½¼ą¼‹ą½šą½–ą½¦ą¼‹ą½†ą½ŗą½ ą½²ą¼‹ą½“ą½¼ą½¢ą¼‹ą½ ą½ą¾²ą½“ą½£ą¼‹ą½žą½²ą½‚ą¼‹ą½–ą¾±ą½“ą½„ą¼‹ą½¦ą½¼ą½„ą¼‹ą¼", + "1": "ą½ą¾±ą½ŗą½‘ą¼‹ą½€ą¾±ą½²ą½¦ą¼‹ą½ ą½šą½¼ą½£ą¼‹ą½–ą½žą½²ą½“ą¼‹ą½”ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‘ą½ŗą¼‹ą½¢ą¾™ą½ŗą½‘ą¼‹ą½ą½“ą½–ą¼‹ą½€ą¾±ą½²ą¼‹ą½˜ą½²ą¼‹ą½ ą½‘ą½“ą½‚", + "2": "ą½“ą½¼ą½¢ą¼‹ą½ ą½ą¾²ą½“ą½£ą¼‹ą½žą½²ą½‚ą¼‹ą½–ą¾±ą½“ą½„ą¼‹ą½¦ą½¼ą½„ą¼‹ą¼" + }, + "github": "GitHub ą½¦ą¾Ÿą½ŗą½„ą¼‹ą½‘ą½“ą¼‹ą½¦ą¾™ą½“ą¼‹ą½žą½“ą¼‹ą½ ą½–ą½“ą½£ą¼‹ą½–ą¼", + "showStack": "Stack Trace ą½¦ą¾Ÿą½¼ą½“ą¼", + "copyStack": "Stack Trace པར་སློག", + "githubSubmit": "GitHub - ą½¦ą¾™ą½“ą¼‹ą½žą½“ą¼‹ą½ ą½–ą½“ą½£ą¼‹ą½–ą¼", + "discordSubmit": "Discord - ą½¢ą¾’ą¾±ą½–ą¼‹ą½¦ą¾ą¾±ą½¼ą½¢ą¼‹ą½¦ą¾™ą½“ą¼‹ą½žą½“ą¼‹ą½ ą½–ą½“ą½£ą¼‹ą½–ą¼" + }, + "delete": "ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "username": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½˜ą½²ą½„ą¼‹ą¼", + "password": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼", + "welcome": "ą½‘ą½‚ą½ ą¼‹ą½–ą½¦ą½²ą¼‹ą½žą½“ą¼", + "property": "ą½ą¾±ą½‘ą¼‹ą½†ą½¼ą½¦ą¼", + "black": "ནག་པོ", + "white": "དཀར་པོ", + "red": "ą½‘ą½˜ą½¢ą¼‹ą½”ą½¼", + "green": "ą½£ą¾—ą½„ą¼‹ą½ą½“ą¼", + "blue": "སྔོན་པོ", + "custom": "ą½˜ą½šą½“ą¼‹ą½‰ą½²ą½‘ą¼‹ą½¢ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚...", + "WorkInProgess": "ą½£ą½¦ą¼‹ą½€ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½–ą½žą½²ą½“ą¼‹ą½”ą¼ ą½“ą½¼ą½¢ą¼‹ą½ ą½ą¾²ą½“ą½£ą¼‹ą½”ą½¼ą½„ą¼‹ą½¦ą¾²ą½²ą½‘ą¼ ą½‘ą½€ą½ ą¼‹ą½„ą½£ą¼‹ą½”ą½¼ą½‘ą¼‹ą½šą½ŗą¼‹ą½¦ą¾™ą½“ą¼‹ą½¦ą½ŗą½„ą¼‹ą½‚ą½“ą½„ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "poweredBy": "ą½˜ą½ą½¼ą¼‹ą½¦ą¾²ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½˜ą½ą½“ą¼", + "yes": "ą½”ą½²ą½“ą¼", + "no": "ą½˜ą½²ą½“ą¼", + "changedCredsMessage": "ą½„ą½¼ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½Ÿą½²ą½“ą¼", + "notAuthenticatedMessage": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½–ą¾±ą½¦ą¼‹ą½˜ą½ŗą½‘ą¼", + "userNotFoundMessage": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½¢ą¾™ą½ŗą½‘ą¼‹ą½˜ą¼‹ą½–ą¾±ą½“ą½„ą¼‹ą¼", + "incorrectPasswordMessage": "ą½‘ą¼‹ą½£ą¾Ÿą½ ą½²ą¼‹ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½“ą½¼ą½¢ą¼‹ą½ ą½‘ą½“ą½‚", + "usernameExistsMessage": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½˜ą½²ą½„ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą¼‹ą½‘ą½ŗą¼‹ą½”ą½¼ą½‘ą¼‹ą½Ÿą½²ą½“ą¼", + "invalidUsernameMessage": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½˜ą½²ą½„ą¼‹ą½“ą½“ą½¦ą¼‹ą½˜ą½ŗą½‘ą¼ ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½‘ą½„ą¼‹ą½Øą½„ą¼‹ą½€ą½²ą¼ ą½‘ą½˜ą½²ą½‚ą½¦ą¼‹ą½–ą½¦ą½£ą¼‹ą½˜ą½šą½¼ą½“ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ @._+- ą½”ą½„ą¼‹ą½“ą¼‹ą½‚ą¾³ą½¼ą½‚ą¼‹ą½ ą½•ą¾²ą½²ą½“ą¼‹ą½ą¼‹ą½–ą¾±ą½„ą¼‹ą½šą½‘ą¼‹ą½£ą¾”ą½“ą¼‹ą½žą½²ą½‚ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼", + "invalidPasswordMessage": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½”ą¼‹ą½”ą½²ą½“ą¼‹ą½˜ą½²ą¼‹ą½†ą½¼ą½‚ą¼‹ą½£ą¼ ą½˜ą½‚ą½¼ą¼‹ą½˜ą½‡ą½“ą½‚ą¼‹ą½ą½“ą¼‹ą½–ą½¢ą¼‹ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½”ą½¼ą½‘ą¼‹ą½˜ą½²ą¼‹ą½†ą½¼ą½‚", + "confirmPasswordErrorMessage": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą¼‹ą½‘ą½„ą¼‹ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼‹ą½‚ą½‰ą½²ą½¦ą¼‹ą½˜ą½ą½“ą½“ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼", + "deleteCurrentUserMessage": "ą½‘ą¼‹ą½£ą¾Ÿą¼‹ą½“ą½„ą¼‹ą½ ą½›ą½“ą½£ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½¦ą½“ą½–ą¼‹ą½˜ą½²ą¼‹ą½†ą½¼ą½‚", + "deleteUsernameExistsMessage": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½˜ą½²ą½„ą¼‹ą½˜ą½ŗą½‘ą¼‹ą½”ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½˜ą½²ą¼‹ą½ą½“ą½–ą¼", + "downgradeCurrentUserMessage": "ą½‘ą¼‹ą½£ą¾Ÿą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ą½‚ą½¼ą¼‹ą½‚ą½“ą½¦ą¼‹ą½˜ą½¢ą¼‹ą½ ą½–ą½ŗą½–ą½¦ą¼‹ą½˜ą½²ą¼‹ą½†ą½¼ą½‚", + "disabledCurrentUserMessage": "ą½‘ą¼‹ą½£ą¾Ÿą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½²ą¼‹ą½†ą½¼ą½‚ą¼‹ą½”ą¼‹ą½–ą½Ÿą½¼ą¼‹ą½˜ą½²ą¼‹ą½†ą½¼ą½‚", + "downgradeCurrentUserLongMessage": "ą½‘ą¼‹ą½£ą¾Ÿą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ą½‚ą½¼ą¼‹ą½‚ą½“ą½¦ą¼‹ą½˜ą½¢ą¼‹ą½ ą½–ą½ŗą½–ą½¦ą¼‹ą½˜ą½²ą¼‹ą½†ą½¼ą½‚ ą½‘ą½ŗą½¢ą¼‹ą½–ą½¢ą¾Ÿą½ŗą½“ą¼‹ą½‘ą¼‹ą½£ą¾Ÿą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼‹ą½˜ą½²ą¼‹ą½¦ą¾²ą½²ą½‘ą¼", + "userAlreadyExistsOAuthMessage": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½ ą½‘ą½²ą¼‹ OAuth2 ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½žą½²ą½‚ą¼‹ą½ą½“ą¼‹ą½”ą½¼ą½‘ą¼‹ą½Ÿą½²ą½“ą¼", + "userAlreadyExistsWebMessage": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½ ą½‘ą½²ą¼‹ą½‘ą¾²ą¼‹ą½šą½²ą½‚ą½¦ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½žą½²ą½‚ą¼‹ą½ą½“ą¼‹ą½”ą½¼ą½‘ą¼‹ą½Ÿą½²ą½“ą¼", + "oops": "ą½Øą¼‹ą½™ą½²ą¼", + "help": "ą½¢ą½¼ą½‚ą½¦ą¼‹ą½¢ą½˜ą¼", + "goHomepage": "ą½‚ą½™ą½¼ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¦ą½“ą¼‹ą½•ą¾±ą½²ą½“ą¼", + "joinDiscord": "ą½„ą¼‹ą½šą½¼ą½ ą½²ą¼‹ Discord ą½¦ą¾”ą½ŗą¼‹ą½šą½“ą¼‹ą½‘ą½“ą¼‹ą½ ą½›ą½“ą½£ą¼", + "seeDockerHub": "Docker Hub ą½£ą¼‹ą½£ą¾Ÿą¼‹ą½–ą¼", + "visitGithub": "Github ą½˜ą½›ą½¼ą½‘ą¼‹ą½ą½„ą¼‹ą½£ą¼‹ą½ ą½šą½˜ą½¦ą¼‹ą½ ą½‘ą¾²ą½²ą¼", + "donate": "ą½žą½£ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼", + "color": "ą½šą½¼ą½“ą¼‹ą½˜ą½‘ą½¼ą½‚", + "sponsor": "ą½˜ą½ą½“ą½“ą¼‹ą½ ą½‚ą¾±ą½“ą½¢ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼‹ą½˜ą½ą½“ą¼", + "info": "ą½†ą¼‹ą½ ą½•ą¾²ą½²ą½“ą¼", + "pro": "ą½†ą½ŗą½‘ą¼‹ą½£ą½¦ą¼", + "page": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼", + "pages": "ཤོག་ངོས་ཁག", + "loading": "ą½ ą½‡ą½“ą½‚ą¼‹ą½–ą½žą½²ą½“ą¼‹ą½”...", + "addToDoc": "ą½”ą½²ą½‚ą¼‹ą½†ą½¢ą¼‹ą½¦ą¾£ą½¼ą½“ą¼", + "reset": "བསྐྱར་སྒྲིག", + "apply": "ą½‰ą½ŗą½¢ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "ą½‚ą½¦ą½„ą¼‹ą½‘ą½¼ą½“ą¼‹ą½¦ą¾²ą½²ą½‘ą¼‹ą½–ą¾±ą½“ą½¦ą¼", + "terms": "ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½†ą¼‹ą½¢ą¾ą¾±ą½ŗą½“ą¼", + "accessibility": "ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½“ą½“ą½¦ą¼‹ą½”ą¼", + "cookie": "Cookie ą½¦ą¾²ą½²ą½‘ą¼‹ą½–ą¾±ą½“ą½¦ą¼", + "impressum": "ą½”ą½¢ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼‹ą½–ą½‘ą½‚ą¼‹ą½‘ą½–ą½„ą¼‹ą¼", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½¢ą½²ą½˜ą¼‹ą½ą½¼ą¼‹ą½”ą½²ą½‚ (Beta)", + "uploadButton": "ą½˜ą½ą½¼ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½¢ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚", + "configureButton": "ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼", + "defaultOption": "རང་སྒྲིག", + "submitButton": "ą½•ą½“ą½£ą¼‹ą½–ą¼", + "help": "ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½¢ą½²ą½˜ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼‹ą½¢ą½˜ą¼", + "scanHelp": "ą½”ą½²ą½‚ą¼‹ą½¦ą¾£ą½¼ą½‘ą¼‹ą½–ą½¤ą½ŗą½¢ą¼‹ą½ ą½šą½¼ą½£ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼‹ą½¢ą½˜ą¼", + "deletePrompt": "ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½¢ą½²ą½˜ą¼‹ą½¦ą½“ą½–ą¼‹ą½¢ą¾’ą¾±ą½“ą¼‹ą½‚ą½ą½“ą¼‹ą½ ą½ą½ŗą½£ą¼‹ą½£ą½˜ą¼", + "tags": "ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼,ą½¢ą½²ą½˜ą¼‹ą½”ą¼,ą½ ą½ą¾²ą½–ą¼‹ą½‚ą½žą½“ą½„ą¼‹ą¼,ą½†ą¼‹ą½šą½„ą¼‹ą½–ą½€ą½¼ą½£ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼", + "title": "ą½¢ą¾’ļæ½ļæ½ą½“ą¼‹ą½£ą½˜ą¼" + }, + "pipelineOptions": { + "header": "ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½¢ą½²ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼", + "pipelineNameLabel": "ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½¢ą½²ą½˜ą¼‹ą½˜ą½²ą½„ą¼‹ą¼", + "saveSettings": "ą½–ą½€ą½¼ą½£ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼", + "pipelineNamePrompt": "ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½¢ą½²ą½˜ą¼‹ą½‚ą¾±ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½ ą½‘ą½²ą½¢ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "selectOperation": "ą½–ą½€ą½¼ą½£ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "addOperationButton": "ą½–ą½€ą½¼ą½£ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½¦ą¾£ą½¼ą½“ą¼", + "pipelineHeader": "ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½¢ą½²ą½˜ą¼", + "saveButton": "ą½•ą½–ą¼‹ą½£ą½ŗą½“ą¼", + "validateButton": "ą½šą½‘ą¼‹ą½£ą¾”ą½“ą¼‹ą½”ą½²ą½“ą¼‹ą½˜ą½²ą½“ą¼‹ą½žą½²ą½–ą¼‹ą½–ą½¤ą½ŗą½¢ą¼" + }, + "enterpriseEdition": { + "button": "ą½†ą½ŗą½‘ą¼‹ą½£ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½¢ą½²ą½˜ą¼‹ą½”ą½¢ą¼‹ą½¢ą¾’ą¾±ą½‚", + "warning": "ą½“ą½“ą½¦ą¼‹ą½”ą¼‹ą½ ą½‘ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½£ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½ą½¼ą¼‹ą½“ą½¢ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½†ą½¼ą½‚", + "yamlAdvert": "Stirling PDF Pro པིས་ YAML སྒྲིག་འགོད་པིག་ཆ་དང་ SSO ą½“ą½“ą½¦ą¼‹ą½”ą¼‹ą½‚ą½žą½“ą¼‹ą½‘ą½‚ą¼‹ą½£ą¼‹ą½¢ą¾’ą¾±ą½–ą¼‹ą½¦ą¾ą¾±ą½¼ą½¢ą¼‹ą½–ą¾±ą½ŗą½‘ą¼", + "ssoAdvert": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½‘ą½¼ą¼‹ą½‘ą½˜ą¼‹ą½“ą½“ą½¦ą¼‹ą½”ą¼‹ą½˜ą½„ą¼‹ą½–ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼‹ą½¦ą½˜ą¼ Stirling PDF Pro ą½£ą¼‹ą½£ą¾Ÿą¼‹ą½¢ą½¼ą½‚ą½¦ą¼" + }, + "analytics": { + "title": "ཁྱེད་ཀྱིས་ Stirling PDF ą½£ą½ŗą½‚ą½¦ą¼‹ą½¦ą½“ą¼‹ą½‚ą½ą½¼ą½„ą¼‹ą½ ą½‘ą½¼ą½‘ą¼‹ą½‘ą½˜ą¼", + "paragraph1": "Stirling PDF ą½£ą¼‹ą½ą½¼ą½“ą¼‹ą½¢ą¾«ą½¦ą¼‹ą½£ą½ŗą½‚ą½¦ą¼‹ą½¦ą½“ą¼‹ą½‚ą½ą½¼ą½„ą¼‹ą½–ą½¢ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼‹ą½¢ą½˜ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½‚ą½‘ą½˜ą¼‹ą½‚ą¼‹ą½”ą½¼ą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½‘ą½”ą¾±ą½‘ą¼‹ą½žą½²ą½–ą¼‹ą½”ą½¼ą½‘ą¼ ą½„ą¼‹ą½šą½¼ą½¦ą¼‹ą½¦ą¾’ą½ŗą½¢ą¼‹ą½‚ą¾±ą½²ą¼‹ą½†ą¼‹ą½ ą½•ą¾²ą½²ą½“ą¼‹ą½‘ą½„ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½“ą½„ą¼‹ą½‘ą½¼ą½“ą¼‹ą½‚ą½„ą¼‹ą½”ą½„ą¼‹ą½¢ą¾—ą½ŗą½¦ą¼‹ą½ ą½‘ą½ŗą½‘ą¼‹ą½˜ą½²ą¼‹ą½–ą¾±ą½ŗą½‘ą¼", + "paragraph2": "Stirling-PDF ą½ ą½•ą½ŗą½£ą¼‹ą½¢ą¾’ą¾±ą½¦ą¼‹ą½‘ą½„ą¼‹ą½„ą¼‹ą½šą½¼ą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½£ą½ŗą½‚ą½¦ą¼‹ą½”ą½¼ą½¢ą¼‹ą½¢ą¾Ÿą½¼ą½‚ą½¦ą¼‹ą½”ą½¢ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼‹ą½¢ą½˜ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½‘ą½”ą¾±ą½‘ą¼‹ą½žą½²ą½–ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½ ą½‚ą½¼ą¼‹ą½ ą½›ą½“ą½‚ą½¦ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "enable": "ą½‘ą½”ą¾±ą½‘ą¼‹ą½žą½²ą½–ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½ ą½‚ą½¼ą¼‹ą½ ą½›ą½“ą½‚ą½¦ą¼", + "disable": "ą½‘ą½”ą¾±ą½‘ą¼‹ą½žą½²ą½–ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½ ą½‡ą½¼ą½‚", + "settings": "ą½‘ą½”ą¾±ą½‘ą¼‹ą½žą½²ą½–ą¼‹ą½€ą¾±ą½²ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ config/settings.yml པིག་ཆའི་ནང་བསྒྱནར་བཅོས་བྱེད་ཆོག" + }, + "navbar": { + "favorite": "ą½‘ą½‚ą½ ą¼‹ą½˜ą½¼ą½¦ą¼", + "recent": "New and recently updated", + "darkmode": "ą½˜ą½“ą½“ą¼‹ą½“ą½‚ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½”ą¼", + "language": "ą½¦ą¾ą½‘ą¼‹ą½¢ą½²ą½‚ą½¦ą¼", + "settings": "ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼", + "allTools": "ą½£ą½‚ą¼‹ą½†ą¼", + "multiTool": "ą½£ą½‚ą¼‹ą½†ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼", + "search": "ą½ ą½šą½¼ą½£ą¼‹ą½–ą½¤ą½ŗą½¢ą¼", + "sections": { + "organize": "གོ་སྒྲིག", + "convertTo": "PDF ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "convertFrom": "PDF ą½“ą½¦ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "security": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½‘ą½„ą¼‹ą½–ą½‘ą½ŗą¼‹ą½ ą½‡ą½‚ą½¦ą¼", + "advance": "ą½˜ą½ą½¼ą¼‹ą½¢ą½²ą½˜ą¼", + "edit": "ą½£ą¾Ÿą¼‹ą½–ą¼‹ą½‘ą½„ą¼‹ą½¢ą¾©ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚", + "popular": "ą½¦ą¾¤ą¾±ą½²ą¼‹ą½˜ą½¼ą½¦ą¼" + } + }, + "settings": { + "title": "ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼", + "update": "ą½‚ą½¦ą½¢ą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½”ą½¼ą½‘ą¼", + "updateAvailable": "{0} ą½“ą½²ą¼‹ą½‘ą¼‹ą½£ą¾Ÿą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½”ą½¢ą¼‹ą½‚ą½žą½²ą¼‹ą½”ą½²ą½“ą¼ ą½”ą½¢ą¼‹ą½‚ą½žą½²ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą¼‹ ({1}) ą½”ą½¼ą½‘ą¼", + "appVersion": "ą½˜ą½‰ą½ŗą½“ą¼‹ą½†ą½¦ą¼‹ą½”ą½¢ą¼‹ą½‚ą½žą½²ą¼", + "downloadOption": { + "title": "ą½•ą½–ą¼‹ą½£ą½ŗą½“ą¼‹ą½‚ą½‘ą½˜ą¼‹ą½‚ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼ (པིག་ཆ་རྐྱང་པ་ zip ą½˜ą½²ą½“ą¼‹ą½”ą½ ą½²ą¼‹ą½•ą½–ą¼‹ą½£ą½ŗą½“ą¼‹ą½†ą½ŗą½‘ą¼):", + "1": "ą½¦ą¾’ą½ŗą½ ą½“ą¼‹ą½ą½“ą½„ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½”ą½ ą½²ą¼‹ą½“ą½„ą¼‹ą½ą¼‹ą½•ą¾±ą½ŗą¼", + "2": "ą½¦ą¾’ą½ŗą½ ą½“ą¼‹ą½ą½“ą½„ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą½¢ą¼‹ą½ą¼‹ą½•ą¾±ą½ŗą¼", + "3": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½•ą½–ą¼‹ą½£ą½ŗą½“ą¼" + }, + "zipThreshold": "ཕབ་ལེན་བྱས་པའི་པིག་ཆའི་གྲངས་ཀ་འདི་ལས་བརྒལ་ན་ zip ą½–ą¾±ą½ŗą½‘ą¼", + "signOut": "ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½–ą½“ą½‘ą¼", + "accountSettings": "ą½ą½¼ą¼‹ą½˜ą½²ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼", + "bored": { + "help": "ą½¦ą¾’ą½¼ą¼‹ą½„ą¼‹ą½¢ą¾©ą½ŗą½‘ą¼‹ą½˜ą½¼ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½ ą½‚ą½¼ą¼‹ą½¢ą¾©ą½¼ą½˜ą¼" + }, + "cacheInputs": { + "name": "ą½“ą½„ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½‚ą½²ą¼‹ą½“ą½„ą¼‹ą½‘ą½¼ą½“ą¼‹ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼", + "help": "ą½¦ą¾”ą½¼ą½“ą¼‹ą½˜ą¼‹ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½“ą½„ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½‚ą½²ą¼‹ą½“ą½„ą¼‹ą½‘ą½¼ą½“ą¼‹ą½˜ą¼‹ą½ ą½¼ą½„ą½¦ą¼‹ą½”ą½¢ą¼‹ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼" + } + }, + "changeCreds": { + "title": "ą½„ą½¼ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "header": "ą½ą¾±ą½ŗą½‘ą¼‹ą½€ą¾±ą½²ą¼‹ą½ą½¼ą¼‹ą½˜ą½²ą½„ą¼‹ą½žą½²ą½–ą¼‹ą½•ą¾²ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼", + "changePassword": "ą½ą¾±ą½ŗą½‘ą¼‹ą½€ą¾±ą½²ą½¦ą¼‹ą½¦ą¾”ą½¼ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½“ą½„ą¼‹ą½ ą½›ą½“ą½£ą¼‹ą½„ą½¼ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½–ą½žą½²ą½“ą¼‹ą½”ą½¼ą½‘ą¼ ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "newUsername": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½˜ą½²ą½„ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą¼", + "oldPassword": "ą½‘ą¼‹ą½£ą¾Ÿą½ ą½²ą¼‹ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚", + "newPassword": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą¼", + "confirmNewPassword": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼", + "submit": "ą½ ą½‚ą¾±ą½“ą½¢ą¼‹ą½–ą¼‹ą½•ą½“ą½£ą¼‹ą½–ą¼" + }, + "account": { + "title": "ą½ą½¼ą¼‹ą½˜ą½²ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼", + "accountSettings": "ą½ą½¼ą¼‹ą½˜ą½²ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼", + "adminSettings": "ą½‘ą½¼ą¼‹ą½‘ą½˜ą¼‹ą½”ą½ ą½²ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼ - ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½£ą¾Ÿą¼‹ą½–ą¼‹ą½‘ą½„ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "userControlSettings": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½šą½¼ą½‘ą¼‹ą½ ą½›ą½²ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼", + "changeUsername": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½˜ą½²ą½„ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "newUsername": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½˜ą½²ą½„ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą¼", + "password": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼", + "oldPassword": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½¢ą¾™ą½²ą½„ą¼‹ą½”ą¼", + "newPassword": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą¼", + "changePassword": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "confirmNewPassword": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼", + "signOut": "ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½–ą½“ą½‘ą¼", + "yourApiKey": "ཁྱེད་ཀྱི་ API ą½£ą¾”ą½ŗą¼‹ą½˜ą½²ą½‚", + "syncTitle": "ą½–ą½¤ą½¢ą¼‹ą½†ą½¦ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ą½ą½¼ą¼‹ą½˜ą½²ą½„ą¼‹ą½‘ą½„ą¼‹ą½˜ą½‰ą½˜ą¼‹ą½–ą½‚ą¾²ą½¼ą½‘ą¼", + "settingsCompare": "ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ą½–ą½¦ą¾”ą½“ą½¢ą¼‹ą½–ą¼", + "property": "ą½ą¾±ą½‘ą¼‹ą½†ą½¼ą½¦ą¼", + "webBrowserSettings": "ą½–ą½¤ą½¢ą¼‹ą½†ą½¦ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼", + "syncToBrowser": "ą½˜ą½‰ą½˜ą¼‹ą½–ą½‚ą¾²ą½¼ą½‘ą¼‹ą½ą½¼ą¼‹ą½˜ą½²ą½„ą¼‹ -> ą½–ą½¤ą½¢ą¼‹ą½†ą½¦ą¼", + "syncToAccount": "ą½˜ą½‰ą½˜ą¼‹ą½–ą½‚ą¾²ą½¼ą½‘ą¼‹ą½ą½¼ą¼‹ą½˜ą½²ą½„ą¼‹ <- ą½–ą½¤ą½¢ą¼‹ą½†ą½¦ą¼" + }, + "adminUserSettings": { + "title": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½šą½¼ą½‘ą¼‹ą½ ą½›ą½²ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼", + "header": "ą½‘ą½¼ą¼‹ą½‘ą½˜ą¼‹ą½”ą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½šą½¼ą½‘ą¼‹ą½ ą½›ą½²ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼", + "admin": "ą½‘ą½¼ą¼‹ą½‘ą½˜ą¼‹ą½”ą¼", + "user": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼", + "addUser": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą¼‹ą½¦ą¾£ą½¼ą½“ą¼", + "deleteUser": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "confirmDeleteUser": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½¦ą½“ą½–ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼‹ą½¦ą½˜ą¼", + "confirmChangeUserStatus": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½²ą¼‹ą½†ą½¼ą½‚ą¼‹ą½”ą½ ą½˜ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½†ą½¼ą½‚ą¼‹ą½”ą¼‹ą½–ą½Ÿą½¼ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼‹ą½¦ą½˜ą¼", + "usernameInfo": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½˜ą½²ą½„ą¼‹ą½“ą½„ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½‘ą½„ą¼‹ą½Øą½„ą¼‹ą½€ą½²ą¼ ą½‘ą½˜ą½²ą½‚ą½¦ą¼‹ą½–ą½¦ą½£ą¼‹ą½˜ą½šą½¼ą½“ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ @._+- ą½”ą½„ą¼‹ą½“ą¼‹ą½‚ą¾³ą½¼ą½‚ą¼‹ą½ ą½•ą¾²ą½²ą½“ą¼‹ą½ą¼‹ą½–ą¾±ą½„ą¼‹ą½šą½‘ą¼‹ą½£ą¾”ą½“ą¼‹ą½žą½²ą½‚ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼", + "roles": "ą½ ą½‚ą½“ą¼‹ą½ ą½ą½“ą½¢ą¼", + "role": "ą½ ą½‚ą½“ą¼‹ą½ ą½ą½“ą½¢ą¼", + "actions": "ą½–ą¾±ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼", + "apiUser": "ą½šą½‘ą¼‹ą½–ą½€ą½‚ą¼‹ą½…ą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ API ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼", + "extraApiUser": "ą½šą½‘ą¼‹ą½–ą½€ą½‚ą¼‹ą½…ą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ API ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½ ą½•ą½¢ą¼‹ą½˜ą¼", + "webOnlyUser": "ą½‘ą¾²ą¼‹ą½šą½²ą½‚ą½¦ą¼‹ą½ą½¼ą¼‹ą½“ą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼", + "demoUser": "ą½–ą½¢ą¾Ÿą½‚ą¼‹ą½‘ą½”ą¾±ą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼ (ą½¢ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½˜ą½ŗą½‘ą¼‹ą½”ą¼)", + "internalApiUser": "ནང་ཁནལ་ API ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼", + "forceChange": "ą½“ą½„ą¼‹ą½ ą½›ą½“ą½£ą¼‹ą½¦ą¾ą½–ą½¦ą¼‹ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼‹ą½”ą¼‹ą½–ą½Ÿą½¼ą¼‹ą½–ą¼", + "submit": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼", + "changeUserRole": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ą½ ą½‚ą½“ą¼‹ą½ ą½ą½“ą½¢ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "authenticated": "ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½–ą¾±ą½¦ą¼‹ą½Ÿą½²ą½“ą¼", + "editOwnProfil": "ą½¢ą½„ą¼‹ą½‰ą½²ą½‘ą¼‹ą½€ą¾±ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½¢ą¾©ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚", + "enabledUser": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½†ą½¼ą½‚ą¼‹ą½”ą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼", + "disabledUser": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½²ą¼‹ą½†ą½¼ą½‚ą¼‹ą½”ą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼", + "activeUsers": "ą½ ą½‚ą½“ą½£ą¼‹ą½–ą½žą½²ą½“ą¼‹ą½”ą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼", + "disabledUsers": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½²ą¼‹ą½†ą½¼ą½‚ą¼‹ą½”ą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼", + "totalUsers": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½ą¾±ą½¼ą½“ą¼‹ą½–ą½¦ą¾”ą½¼ą½˜ą½¦ą¼", + "lastRequest": "ą½¢ą½ŗą¼‹ą½žą½“ą¼‹ą½˜ą½ą½ ą¼‹ą½˜ą¼", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "ą½‚ą½žą½²ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½˜ą½›ą½¼ą½‘ą¼‹ą½“ą½„ą¼‹ą½ ą½‘ą¾²ą½ŗą½“ą¼‹/ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą¾²ą½ŗą½“ą¼", + "header": "ą½‚ą½žą½²ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½˜ą½›ą½¼ą½‘ą¼‹ą½“ą½„ą¼‹ą½ ą½‘ą¾²ą½ŗą½“ą¼‹/ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą¾²ą½ŗą½“ą¼", + "fileName": "ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą¼", + "creationDate": "ą½–ą½Ÿą½¼ą¼‹ą½–ą½ ą½²ą¼‹ą½‘ą½“ą½¦ą¼‹ą½šą½¼ą½‘ą¼", + "fileSize": "ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą¼", + "deleteBackupFile": "ą½‚ą¾²ą½–ą½¦ą¼‹ą½‰ą½¢ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "importBackupFile": "ą½‚ą¾²ą½–ą½¦ą¼‹ą½‰ą½¢ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½“ą½„ą¼‹ą½ ą½‘ą¾²ą½ŗą½“ą¼", + "createBackupFile": "ą½‚ą¾²ą½–ą½¦ą¼‹ą½‰ą½¢ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½–ą½Ÿą½¼ą¼‹ą½–ą¼", + "downloadBackupFile": "ą½‚ą¾²ą½–ą½¦ą¼‹ą½‰ą½¢ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½•ą½–ą¼‹ą½£ą½ŗą½“ą¼", + "info_1": "ą½‚ą½žą½²ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½“ą½„ą¼‹ą½ ą½‘ą¾²ą½ŗą½“ą¼‹ą½¦ą¾ą½–ą½¦ą¼‹ą½–ą½€ą½¼ą½‘ą¼‹ą½”ą¼‹ą½ą½‚ą¼‹ą½ą½‚ą¼‹ą½”ą½²ą½“ą¼‹ą½”ą¼‹ą½„ą½ŗą½¦ą¼‹ą½”ą½¢ą¼‹ą½‘ą½“ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼ ą½‚ą½£ą¼‹ą½¦ą¾²ą½²ą½‘ą¼‹ą½ą¾±ą½ŗą½‘ą¼‹ą½¢ą½„ą¼‹ą½‚ą½„ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½–ą½žą½²ą½“ą¼‹ą½”ą¼‹ą½˜ą½²ą¼‹ą½¤ą½ŗą½¦ą¼‹ą½“ą¼ ą½†ą½ŗą½‘ą¼‹ą½£ą½¦ą¼‹ą½”ą¼‹ą½žą½²ą½‚ą¼‹ą½£ą½¦ą¼‹ą½£ą½˜ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼‹ą½‘ą½„ą¼‹ą½¢ą¾’ą¾±ą½–ą¼‹ą½¦ą¾ą¾±ą½¼ą½¢ą¼‹ą½žą½“ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼ ą½–ą½€ą½¼ą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½“ą½„ą¼‹ą½“ą½¼ą½¢ą¼‹ą½ ą½ą¾²ą½“ą½£ą¼‹ą½”ą½¼ą½‘ą¼‹ą½“ą¼‹ą½˜ą½‰ą½ŗą½“ą¼‹ą½†ą½¦ą¼‹ą½£ą¼‹ą½¦ą¾ą¾±ą½¼ą½“ą¼‹ą½¤ą½¼ą½¢ą¼‹ą½¦ą¾²ą½²ą½‘ą¼‹ą½”ą¼‹ą½‘ą½„ą¼‹ą¼ ą½ą¼‹ą½“ą¼‹ą½˜ą½‰ą½ŗą½“ą¼‹ą½†ą½¦ą¼‹ą½‚ą½ą½“ą¼‹ą½“ą½¦ą¼‹ą½ ą½ą½¼ą½¢ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½˜ą½²ą¼‹ą½ą½“ą½–ą¼‹ą½”ą½ ą½„ą¼‹ą½”ą½¼ą½„ą¼‹ą½¦ą¾²ą½²ą½‘ą¼", + "info_2": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½”ą½¢ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½¦ą¾ą½–ą½¦ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½£ą¼‹ą½ą¾±ą½‘ą¼‹ą½”ą½¢ą¼‹ą½˜ą½ŗą½‘ą¼ དེའི་རྗེས་སན་ backup_user_yyyyMMddHHmm.sql ą½žą½ŗą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½”ą½¢ą¼‹ą½˜ą½²ą½„ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½ ą½‘ą½¼ą½‚ą½¦ą¼‹ą½–ą¾±ą¼‹ą½¢ą¾’ą¾±ą½“ą¼‹ą½”ą½²ą½“ą¼‹ą½”ą½¦ą¼ ą½˜ą½²ą½„ą¼‹ą½ ą½‘ą½¼ą½‚ą½¦ą¼‹ą½¦ą¾Ÿą½„ą½¦ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½˜ą½šą½“ą½„ą½¦ą¼‹ą½”ą½²ą½“ą¼‹ą½”ą¼‹ą½„ą½ŗą½¦ą¼‹ą½”ą½¢ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½ą½“ą½–ą¼", + "submit": "ą½‚ą¾²ą½–ą½¦ą¼‹ą½‰ą½¢ą¼‹ą½“ą½„ą¼‹ą½ ą½‘ą¾²ą½ŗą½“ą¼", + "importIntoDatabaseSuccessed": "ą½‚ą½žą½²ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½˜ą½›ą½¼ą½‘ą¼‹ą½‘ą½“ą¼‹ą½“ą½„ą¼‹ą½ ą½‘ą¾²ą½ŗą½“ą¼‹ą½£ą½ŗą½‚ą½¦ą¼‹ą½‚ą¾²ą½“ą½–ą¼", + "backupCreated": "ą½‚ą½žą½²ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½˜ą½›ą½¼ą½‘ą¼‹ą½‚ą¾²ą½–ą½¦ą¼‹ą½‰ą½¢ą¼‹ą½£ą½ŗą½‚ą½¦ą¼‹ą½‚ą¾²ą½“ą½–ą¼", + "fileNotFound": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½¢ą¾™ą½ŗą½‘ą¼‹ą½˜ą¼‹ą½–ą¾±ą½“ą½„ą¼‹ą¼", + "fileNullOrEmpty": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½”ą½ ą½˜ą¼‹ą½˜ą½ŗą½‘ą¼‹ą½”ą¼‹ą½”ą½²ą½“ą¼‹ą½˜ą½²ą¼‹ą½†ą½¼ą½‚", + "failedImportFile": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½“ą½„ą¼‹ą½ ą½‘ą¾²ą½ŗą½“ą¼‹ą½•ą½˜ą¼‹ą½”ą¼", + "notSupported": "ą½¦ą¾”ą½“ą½‘ą¼‹ą½‚ą½žą½²ą¼‹ą½¢ą¾’ą¾±ą½–ą¼‹ą½¦ą¾ą¾±ą½¼ą½¢ą¼‹ą½˜ą½²ą¼‹ą½–ą¾±ą½ŗą½‘ą¼" + }, + "session": { + "expired": "ą½ą¾±ą½ŗą½‘ą¼‹ą½€ą¾±ą½²ą¼‹ą½‚ą¾³ą½ŗą½„ą¼‹ą½˜ą½¼ą½£ą¼‹ą½‘ą½“ą½¦ą¼‹ą½”ą½¼ą½£ą¼‹ą½Ÿą½²ą½“ą¼ ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¾±ą½¦ą¼‹ą½“ą½¦ą¼‹ą½”ą½„ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½šą½¼ą½‘ą¼‹ą½£ą¾Ÿą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "refreshPage": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼" + }, + "home": { + "desc": "ཁྱེད་ཀྱི་ PDF ą½‘ą½‚ą½¼ą½¦ą¼‹ą½˜ą½ą½¼ą¼‹ą½šą½„ą¼‹ą½˜ą½ ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½¦ą¼‹ą½‚ą½“ą½¦ą¼‹ą½¢ą½„ą¼‹ą½‘ą½“ą¼‹ą½–ą½žą½‚ą¼‹ą½”ą½ ą½²ą¼‹ą½žą½–ą½¦ą¼‹ą½žą½“ą¼‹ą½ą½„ą¼‹ą¼", + "searchBar": "ą½“ą½“ą½¦ą¼‹ą½”ą¼‹ą½ ą½šą½¼ą½£ą¼‹ą½–ą½¤ą½ŗą½¢ą¼", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "ą½£ą¾Ÿą¼‹ą½–ą¼ ą½˜ą½†ą½“ą¼‹ą½ ą½‚ą¾²ą½ŗą½£ą¼ ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½‘ą½„ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼" + }, + "setFavorites": "Set Favourites", + "hideFavorites": "Hide Favourites", + "showFavorites": "Show Favourites", + "legacyHomepage": "Old homepage", + "newHomePage": "Try our new homepage!", + "alphabetical": "Alphabetical", + "globalPopularity": "Global Popularity", + "sortBy": "Sort by:", + "multiTool": { + "title": "PDF ą½£ą½‚ą¼‹ą½†ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼", + "desc": "ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼ ą½ ą½ą½¼ą½¢ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼ བསྐྱར་སྒྲིག ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼ ą½‘ą½„ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "merge": { + "title": "ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼", + "desc": "PDF ą½˜ą½„ą¼‹ą½”ą½¼ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½ą½“ą¼‹ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "split": { + "title": "ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "desc": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą½¢ą¼‹ą½–ą½‚ą½¼ą¼‹ą½–ą¼" + }, + "rotate": { + "title": "ą½ ą½ą½¼ą½¢ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼", + "desc": "PDF ą½£ą½¦ą¼‹ą½¦ą¾³ą¼‹ą½”ą½¼ą½ ą½²ą¼‹ą½„ą½„ą¼‹ą½ ą½ą½¼ą½¢ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "imageToPdf": { + "title": "པར་རིས་ནས་ PDF ą½£ą¼", + "desc": "པར་རིས་ (PNG, JPEG, GIF) ནས་ PDF ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "pdfToImage": { + "title": "PDF ą½“ą½¦ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½£ą¼", + "desc": "PDF ནས་པར་རིས་ (PNG, JPEG, GIF) ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "pdfOrganiser": { + "title": "གོ་སྒྲིག", + "desc": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½‚ą½¼ą¼‹ą½¢ą½²ą½˜ą¼‹ą½‚ą½„ą¼‹ą½¢ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą½ ą½˜ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "addImage": { + "title": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "desc": "PDF ą½“ą½„ą¼‹ą½‚ą½“ą½¦ą¼‹ą½¦ą¼‹ą½„ą½ŗą½¦ą¼‹ą½…ą½“ą¼‹ą½žą½²ą½‚ą¼‹ą½ą½“ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼" + }, + "watermark": { + "title": "ą½†ą½“ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "desc": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą½¢ą¼‹ą½¢ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½‚ą½²ą¼‹ą½†ą½“ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼" + }, + "permissions": { + "title": "ą½†ą½¼ą½‚ą¼‹ą½˜ą½†ą½“ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "desc": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½†ą½¼ą½‚ą¼‹ą½˜ą½†ą½“ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "removePages": { + "title": "ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "desc": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½“ą½¦ą¼‹ą½˜ą½²ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "addPassword": { + "title": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "desc": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą½¢ą¼‹ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½‚ą½²ą½¦ą¼‹ą½‚ą½¦ą½„ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "removePassword": { + "title": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "desc": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½“ą½¦ą¼‹ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą½¦ą¾ą¾±ą½¼ą½–ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "compressPdfs": { + "title": "ą½¦ą¾”ą½“ą½‘ą¼‹ą½¦ą¾’ą¾²ą½²ą½£ą¼", + "desc": "ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą½†ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½‚ą½ą½¼ą½„ą¼‹ą½†ą½ŗą½‘ą¼‹ PDF ą½¦ą¾”ą½“ą½‘ą¼‹ą½¦ą¾’ą¾²ą½²ą½£ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "ą½‚ą½“ą½¦ą¼‹ą½†ą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą½…ą½¼ą½¦ą¼", + "desc": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½“ą½¦ą¼‹ą½‚ą½“ą½¦ą¼‹ą½†ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą½ ą½˜ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼" + }, + "fileToPDF": { + "title": "པིག་ཆ་ནས་ PDF ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "desc": "པིག་ཆ་ཕལ་ཆེ་བ་ PDF ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½ą½“ą½–ą¼ (DOCX, PNG, XLS, PPT, TXT ą½¦ą½¼ą½‚ą½¦ą¼)" + }, + "ocr": { + "title": "OCR / ą½–ą½¤ą½ŗą½¢ą¼‹ą½ ą½–ą½ŗą½–ą½¦ą¼‹ą½‚ą½™ą½„ą¼‹ą½¦ą½ŗą½£ą¼", + "desc": "བཤེར་འབེབས་གཙང་སེལ་དང་ PDF ą½“ą½„ą¼‹ą½‚ą½²ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½“ą½¦ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½„ą½¼ą½¦ą¼‹ą½ ą½›ą½²ą½“ą¼‹ą½–ą¾±ą½¦ą¼‹ą½ą½ŗą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą½ ą½²ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½”ą½¢ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "extractImages": { + "title": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼", + "desc": "PDF ą½“ą½¦ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½šą½„ą¼‹ą½˜ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½–ą½ą½¼ą½“ą¼‹ą½“ą½¦ą¼‹ zip ą½“ą½„ą¼‹ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "pdfToPDFA": { + "title": "PDF ནས་ PDF/A ą½£ą¼", + "desc": "PDF ą½“ą½¦ą¼‹ą½‘ą½“ą½¦ą¼‹ą½”ą½“ą½“ą¼‹ą½¢ą½²ą½„ą¼‹ą½”ą½¼ą½ ą½²ą¼‹ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼‹ą½†ą½ŗą½‘ą¼‹ PDF/A ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "PDFToWord": { + "title": "PDF ནས་ Word ą½£ą¼", + "desc": "PDF ནས་ Word ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚ą¼‹ (DOC, DOCX དང་ ODT) ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "PDFToPresentation": { + "title": "PDF ą½“ą½¦ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½£ą¼", + "desc": "PDF ą½“ą½¦ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚ą¼‹ (PPT, PPTX དང་ ODP) ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "PDFToText": { + "title": "PDF ནས་ RTF (པི་གེ) ą½£ą¼", + "desc": "PDF ą½“ą½¦ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą½ ą½˜ą¼‹ RTF ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚ą¼‹ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "PDFToHTML": { + "title": "PDF ནས་ HTML ą½£ą¼", + "desc": "PDF ནས་ HTML ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚ą¼‹ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "PDFToXML": { + "title": "PDF ནས་ XML ą½£ą¼", + "desc": "PDF ནས་ XML ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚ą¼‹ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "ScannerImageSplit": { + "title": "བཤེར་པར་ངོས་འཛིན་/ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "desc": "པར་རིས་/PDF ą½“ą½„ą¼‹ą½‚ą½²ą¼‹ą½”ą½¢ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "sign": { + "title": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼", + "desc": "ą½¢ą½²ą¼‹ą½˜ą½¼ą¼ ą½”ą½²ą¼‹ą½‚ą½ŗą¼ པར་རིས་བཅས་ཀྱི་སྒོ་ནས་ PDF ą½£ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼" + }, + "flatten": { + "title": "ą½¦ą¾™ą½¼ą½˜ą½¦ą¼‹ą½”ą¼", + "desc": "PDF ą½“ą½¦ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½¦ą¾’ą½¼ą¼‹ą½…ą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ą½†ą¼‹ą½¤ą½¦ą¼‹ą½‘ą½„ą¼‹ą½ ą½‚ą½ŗą½„ą½¦ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½šą½„ą¼‹ą½˜ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "repair": { + "title": "ą½–ą½Ÿą½¼ą¼‹ą½–ą½…ą½¼ą½¦ą¼", + "desc": "ą½¦ą¾ą¾±ą½¼ą½“ą¼‹ą½¤ą½¼ą½¢ą¼‹ą½–ą½ ą½˜ą¼‹ą½‚ą½ą½¼ą½¢ą¼‹ą½–ą½¤ą½²ą½‚ą¼‹ą½ą½ŗą½–ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ PDF ą½–ą½Ÿą½¼ą¼‹ą½–ą½…ą½¼ą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½ą½–ą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "removeBlanks": { + "title": "ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "desc": "PDF ą½“ą½„ą¼‹ą½‚ą½²ą¼‹ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½„ą½¼ą½¦ą¼‹ą½ ą½›ą½²ą½“ą¼‹ą½‘ą½„ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "removeAnnotations": { + "title": "ą½˜ą½†ą½“ą¼‹ą½ ą½‚ą¾²ą½ŗą½£ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "desc": "PDF ą½“ą½„ą¼‹ą½‚ą½²ą¼‹ą½˜ą½†ą½“ą¼‹ą½ ą½‚ą¾²ą½ŗą½£ą¼‹ą½šą½„ą¼‹ą½˜ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "compare": { + "title": "PDF ą½–ą½¦ą¾”ą½“ą½¢ą¼‹ą½–ą¼", + "desc": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½‚ą½‰ą½²ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½ą¾±ą½‘ą¼‹ą½”ą½¢ą¼‹ą½–ą½¦ą¾”ą½“ą½¢ą¼‹ą½–ą¼" + }, + "certSign": { + "title": "ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼", + "desc": "ལག་ཁྱེར་/ą½£ą¾”ą½ŗą¼‹ą½˜ą½²ą½‚ą¼‹ (PEM/P12) གྱིས་ PDF ą½£ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½”ą¼" + }, + "removeCertSign": { + "title": "ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "desc": "PDF ą½“ą½¦ą¼‹ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "pageLayout": { + "title": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą½ ą½²ą¼‹ą½–ą½€ą½¼ą½‘ą¼‹ą½”ą¼", + "desc": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½ą½“ą¼‹ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "scalePages": { + "title": "ཤོག་ངོས་ཆེ་ཆནང་/ą½šą½‘ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½”ą¼", + "desc": "ཤོག་ངོས་དང་/པང་ན་དེའི་ནང་དོན་གྱི་ཆེ་ཆནང་/ą½šą½‘ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "pipeline": { + "title": "ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½¢ą½²ą½˜ą¼", + "desc": "ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½¢ą½²ą½˜ą¼‹ą½ ą½ą¾²ą½–ą¼‹ą½‚ą½žą½“ą½„ą¼‹ą½–ą½Ÿą½¼ą½¦ą¼‹ą½“ą½¦ą¼‹ PDF ą½£ą¼‹ą½–ą¾±ą¼‹ą½–ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼‹ą½ ą½ą½¼ą½¢ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "add-page-numbers": { + "title": "ą½¤ą½¼ą½‚ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "desc": "ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½“ą½„ą¼‹ą½‚ą½“ą½¦ą¼‹ą½¦ą¼‹ą½„ą½ŗą½¦ą¼‹ą½…ą½“ą¼‹ą½‘ą½“ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼" + }, + "auto-rename": { + "title": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½ ą½‘ą½¼ą½‚ą½¦ą¼", + "desc": "ą½„ą½¼ą½¦ą¼‹ą½ ą½›ą½²ą½“ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½ ą½‚ą½¼ą¼‹ą½–ą½¢ą¾—ą½¼ą½‘ą¼‹ą½£ą¼‹ą½‚ą½žą½²ą½‚ą½¦ą¼‹ą½“ą½¦ą¼‹ PDF ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½ ą½‘ą½¼ą½‚ą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "adjust-contrast": { + "title": "ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼‹/ą½ ą½¼ą½‘ą¼‹ą½ą¾±ą½‘ą¼‹ą½¦ą¾™ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚", + "desc": "PDF ą½”ą½²ą¼‹ą½ ą½¼ą½‘ą¼‹ą½ą¾±ą½‘ą¼ ą½šą½¼ą½¦ą¼‹ą½Ÿą½²ą½£ą¼ ą½‘ą½„ą¼‹ą½‚ą½¦ą½£ą¼‹ą½šą½‘ą¼‹ą½¦ą¾™ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "crop": { + "title": "PDF ą½‚ą½ą½“ą½–ą¼‹ą½‚ą½…ą½¼ą½‘ą¼", + "desc": "ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą½†ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½‚ą½ą½¼ą½„ą¼‹ą½†ą½ŗą½‘ą¼‹ PDF ą½‚ą½ą½“ą½–ą¼‹ą½‚ą½…ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼ (ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą½¦ą¾ą¾±ą½¼ą½–ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½ą½“ą½–ą¼)" + }, + "autoSplitPDF": { + "title": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "desc": "བཤེར་འབེབས་བྱས་པའི་ PDF ནང་གི་དངོས་པོད་བཤེར་འབེབས་ཤོག་ངོས་ཁ་གྱེས་ QR Code ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½¦ą¼‹ą½“ą½¦ą¼‹ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "sanitizePdf": { + "title": "ą½‚ą½™ą½„ą¼‹ą½¦ą½ŗą½£ą¼", + "desc": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½“ą½¦ą¼‹ą½ ą½ą¾²ą½–ą¼‹ą½‚ą½žą½“ą½„ą¼‹ą½‘ą½„ą¼‹ą½†ą¼‹ą½¤ą½¦ą¼‹ą½‚ą½žą½“ą¼‹ą½‘ą½‚ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "URLToPDF": { + "title": "ą½‘ą¾²ļæ½ļæ½ą½šą½²ą½‚ą½¦ą¼‹ą½“ą½¦ą¼‹ PDF ą½£ą¼", + "desc": "http(s) ą½‘ą¾²ą¼‹ą½šą½²ą½‚ą½¦ą¼‹ą½‚ą½„ą¼‹ą½¢ą½“ą½„ą¼‹ PDF ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "HTMLToPDF": { + "title": "HTML ནས་ PDF ą½£ą¼", + "desc": "HTML ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½˜ą¼‹ zip པིག་ཆ་གང་རནང་ PDF ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "MarkdownToPDF": { + "title": "Markdown ནས་ PDF ą½£ą¼", + "desc": "Markdown པིག་ཆ་གང་རནང་ PDF ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "PDFToMarkdown": { + "title": "PDF to Markdown", + "desc": "Converts any PDF to Markdown" + }, + "getPdfInfo": { + "title": "PDF ą½”ą½²ą¼‹ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½†ą¼‹ą½šą½„ą¼‹ą½£ą½ŗą½“ą¼‹ą½”ą¼", + "desc": "PDF ą½”ą½²ą¼‹ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½”ą½¼ą½‘ą¼‹ą½šą½‘ą¼‹ą½£ą½ŗą½“ą¼‹ą½”ą¼" + }, + "extractPage": { + "title": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼", + "desc": "PDF ą½“ą½¦ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½¦ą¾’ą¾²ą½“ą½‚ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½”ą¼" + }, + "PdfToSinglePage": { + "title": "PDF ą½“ą½¦ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½†ą½ŗą½“ą¼‹ą½”ą½¼ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½£ą¼", + "desc": "PDF ą½”ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½šą½„ą¼‹ą½˜ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½†ą½ŗą½“ą¼‹ą½”ą½¼ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½ą½“ą¼‹ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "showJS": { + "title": "Javascript ą½¦ą¾Ÿą½¼ą½“ą¼‹ą½”ą¼", + "desc": "PDF ནང་དན་བཅནག་པའི་ JS ą½‚ą½„ą¼‹ą½”ą½¼ą½‘ą¼‹ą½ ą½šą½¼ą½£ą¼‹ą½žą½²ą½–ą¼‹ą½‘ą½„ą¼‹ą½˜ą½„ą½¼ą½“ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "autoRedact": { + "title": "ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼", + "desc": "ą½ ą½‡ą½“ą½‚ą¼‹ą½”ą½ ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½‚ą½žą½²ą½¢ą¼‹ą½–ą½Ÿą½“ą½„ą¼‹ą½“ą½¦ą¼‹ PDF ą½“ą½„ą¼‹ą½‚ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½‚ą¾±ą½²ą½¦ą¼‹ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½”ą¼" + }, + "redact": { + "title": "ą½£ą½‚ą¼‹ą½–ą½Ÿą½¼ą½¦ą¼‹ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼", + "desc": "ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½¦ą¾’ą¾²ą½“ą½‚ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼ ą½–ą¾²ą½²ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½‘ą½–ą¾±ą½²ą½–ą½¦ą¼ དང་/ą½”ą½„ą¼‹ą½“ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½¦ą¾’ą¾²ą½“ą½‚ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½žą½²ą½¢ą¼‹ą½–ą½Ÿą½“ą½„ą¼‹ą½“ą½¦ą¼‹ PDF ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "tableExtraxt": { + "title": "PDF ནས་ CSV ą½£ą¼", + "desc": "PDF ą½“ą½¦ą¼‹ą½¢ą½ŗą½ ą½“ą¼‹ą½˜ą½²ą½‚ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ CSV ą½£ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½”ą¼" + }, + "autoSizeSplitPDF": { + "title": "ཆེ་ཆནང་/ą½‚ą¾²ą½„ą½¦ą¼‹ą½€ą¼‹ą½£ą¾Ÿą½¢ą¼‹ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "desc": "PDF ą½‚ą½…ą½²ą½‚ą¼‹ą½“ą½¦ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą½¢ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą¼ ą½¤ą½¼ą½‚ą¼‹ą½‚ą¾²ą½„ą½¦ą¼ ą½”ą½„ą¼‹ą½“ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½€ą¼‹ą½‚ą½žą½²ą½¢ą¼‹ą½–ą½Ÿą½“ą½„ą¼‹ą½“ą½¦ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "overlay-pdfs": { + "title": "PDF ą½¦ą¾Ÿą½ŗą½„ą¼‹ą½–ą½¢ą¾©ą½ŗą½‚ą½¦ą¼", + "desc": "PDF ą½‚ą½žą½“ą¼‹ą½žą½²ą½‚ą¼‹ą½‚ą½²ą¼‹ą½¦ą¾Ÿą½ŗą½„ą¼‹ą½‘ą½“ą¼‹ PDF ą½–ą½¢ą¾©ą½ŗą½‚ą½¦ą¼‹ą½”ą¼" + }, + "split-by-sections": { + "title": "ą½‘ą½“ą½˜ą¼‹ą½–ą½“ą¼‹ą½£ą¾Ÿą½¢ą¼‹ PDF ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "desc": "PDF ą½”ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¢ą½ŗą¼‹ą½¢ą½ŗą¼‹ą½‚ą½žą½“ą½„ą¼‹ą½‘ą½„ą¼‹ą½ ą½•ą¾²ą½ŗą½‘ą¼‹ą½€ą¾±ą½²ą¼‹ą½‘ą½“ą½˜ą¼‹ą½–ą½“ą¼‹ą½†ą½“ą½„ą¼‹ą½†ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½–ą½‚ą½¼ą¼‹ą½–ą¼" + }, + "AddStampRequest": { + "title": "PDF ą½£ą¼‹ą½ą½ŗą½£ą¼‹ą½™ą½ŗą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "desc": "ą½‚ą½“ą½¦ą¼‹ą½¦ą¼‹ą½„ą½ŗą½¦ą¼‹ą½…ą½“ą¼‹ą½‘ą½“ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą½ ą½˜ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½ą½ŗą½£ą¼‹ą½™ą½ŗą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼" + }, + "removeImagePdf": { + "title": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "desc": "ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą½†ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½‚ą½ą½¼ą½„ą¼‹ą½†ą½ŗą½‘ą¼‹ PDF ą½“ą½¦ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "splitPdfByChapters": { + "title": "ą½£ą½ŗą½ ą½“ą¼‹ą½£ą¾Ÿą½¢ą¼‹ PDF ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "desc": "PDF ą½”ą½²ą¼‹ą½£ą½ŗą½ ą½“ą½ ą½²ą¼‹ą½¦ą¾’ą¾²ą½¼ą½˜ą¼‹ą½‚ą½žą½²ą¼‹ą½‚ą½žą½²ą½¢ą¼‹ą½–ą½Ÿą½“ą½„ą¼‹ą½“ą½¦ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą½¢ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "validateSignature": { + "title": "PDF ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼", + "desc": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½“ą½„ą¼‹ą½‚ą½²ą¼‹ą½Øą½„ą¼‹ą½€ą½²ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½‘ą½„ą¼‹ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "replaceColorPdf": { + "title": "ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą½ ą½²ą¼‹ą½‚ą½‘ą½˜ą¼‹ą½‚ą¼‹ą½˜ą½ą½¼ą¼‹ą½¢ą½²ą½˜ą¼", + "desc": "PDF ą½“ą½„ą¼‹ą½‚ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½‘ą½„ą¼‹ą½¢ą¾’ą¾±ą½–ą¼‹ą½£ą¾—ą½¼ą½„ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼‹ą½–ą½¢ą¾—ą½ŗą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼‹ą½‘ą½„ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą½†ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½‚ą½ą½¼ą½„ą¼‹ą½†ą½ŗą½‘ą¼‹ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼‹ą½”ą½¼ą½„ą½¦ą¼‹ą½¢ą¾«ą½¼ą½‚ą½¦ą¼‹ą½£ą¾”ą½¼ą½‚ą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + } + }, + "viewPdf": { + "tags": "ą½£ą¾Ÿą¼‹ą½–ą¼,ą½€ą¾³ą½¼ą½‚ą¼‹ą½”ą¼,ą½˜ą½†ą½“ą¼‹ą½ ą½‚ą¾²ą½ŗą½£ą¼,པི་གེ,ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼", + "title": "View/Edit PDF", + "header": "PDF ą½£ą¾Ÿą¼‹ą½–ą¼" + }, + "multiTool": { + "tags": "ą½£ą½‚ą¼‹ą½†ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼,ą½–ą½€ą½¼ą½£ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼,UI,ą½˜ą½ą½ŗą½–ą¼‹ą½‚ą½“ą½¼ą½“ą¼‹ą½ ą½ą½ŗą½“ą¼‹ą½”ą¼,ą½˜ą½‘ą½“ą½“ą¼‹ą½„ą½¼ą½¦ą¼,ą½˜ą½ą½¼ą¼‹ą½˜ą½ą½“ą¼‹ą½•ą¾±ą½¼ą½‚ą½¦ą¼,ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½¦ą¾’ą½¼ą¼,ą½ ą½‚ą½“ą½£ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼,ą½¦ą½“ą½–ą¼‹ą½”ą¼,ą½‚ą½“ą½¦ą¼‹ą½¦ą¾¤ą½¼ą¼,ą½–ą½‚ą½¼ą¼‹ą½–ą¼", + "title": "PDF ą½£ą½‚ą¼‹ą½†ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼", + "header": "PDF ą½£ą½‚ą¼‹ą½†ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼", + "uploadPrompts": "ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą¼", + "selectAll": "ą½šą½„ą¼‹ą½˜ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "deselectAll": "ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼‹ą½šą½„ą¼‹ą½˜ą¼‹ą½ ą½‘ą½¼ą½¢ą¼‹ą½–ą¼", + "selectPages": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "selectedPages": "ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼", + "page": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼", + "deleteSelected": "ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "downloadAll": "ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą¾²ą½ŗą½“ą¼", + "downloadSelected": "ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą¾²ą½ŗą½“ą¼", + "insertPageBreak": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½–ą½¢ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½”ą¼", + "addFile": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "rotateLeft": "ą½‚ą½”ą½¼ą½“ą¼‹ą½‘ą½“ą¼‹ą½ ą½ą½¼ą½¢ą¼‹ą½–ą¼", + "rotateRight": "ą½‚ą½”ą½¦ą¼‹ą½¦ą½“ą¼‹ą½ ą½ą½¼ą½¢ą¼‹ą½–ą¼", + "split": "ą½‘ą½–ą¾±ą½ŗą¼‹ą½–ą¼", + "moveLeft": "Move Left", + "moveRight": "Move Right", + "delete": "ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "dragDropMessage": "ą½¤ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą¾²ą½“ą½‘ą¼‹ą½ ą½ą½ŗą½“ą¼‹ą½–ą¾±ą½¦ą¼‹ą½“ą½¦ą¼‹ą½‚ą½¼ą¼‹ą½¢ą½²ą½˜ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą½…ą½¼ą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½†ą½¼ą½‚", + "undo": "ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½ą½ŗą½“ą¼", + "redo": "ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½–ą½Ÿą½¼ą¼" + }, + "merge": { + "tags": "ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼,ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½–ą½€ą½¼ą½£ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼,ą½¢ą¾’ą¾±ą½–ą¼‹ą½„ą½¼ą½¦ą¼,ą½žą½–ą½¦ą¼‹ą½žą½“ą¼‹ą½•ą¾±ą½¼ą½‚ą½¦ą¼", + "title": "ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼", + "header": "Merge multiple PDFs (2+)", + "sortByName": "Sort by name", + "sortByDate": "ą½‘ą½“ą½¦ą¼‹ą½šą½¼ą½‘ą¼‹ą½£ą¾Ÿą½¢ą¼‹ą½‚ą½¼ą¼‹ą½¢ą½²ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½”ą¼", + "removeCertSign": "ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½“ą½„ą¼‹ą½‚ą½²ą¼‹ą½Øą½„ą¼‹ą½€ą½²ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½–ą½˜ą¼", + "submit": "ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼" + }, + "split": { + "tags": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½–ą½€ą½¼ą½£ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼,ą½–ą½‚ą½¼ą¼‹ą½–ą¼,ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼,ą½‚ą½…ą½¼ą½‘ą¼‹ą½”ą¼,ą½žą½–ą½¦ą¼‹ą½žą½“ą¼‹ą½•ą¾±ą½¼ą½‚ą½¦ą¼", + "title": "PDF ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "header": "PDF ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "desc": { + "1": "ą½ą¾±ą½ŗą½‘ą¼‹ą½€ą¾±ą½²ą½¦ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½Øą½„ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½“ą½²ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼‹ą½–ą¾±ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½Øą½„ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½”ą½²ą½“ą¼", + "2": "ą½‘ą½ŗą¼‹ą½£ą¾Ÿą½¢ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ 10 ą½”ą½¼ą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½žą½²ą½‚ą¼‹ą½£ą¼‹ 1,3,7-9 ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½“ą¼‹ PDF པིག་ཆ་ 6 ą½£ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼‹ą½ą½ŗą¼", + "3": "པིག་ཆ་ #1: ཤོག་ངོས་ 1", + "4": "པིག་ཆ་ #2: ཤོག་ངོས་ 2 དང་ 3", + "5": "པིག་ཆ་ #3: ཤོག་ངོས་ 4, 5, 6 དང་ 7", + "6": "Document #4: Page 8", + "7": "Document #5: Page 9", + "8": "པིག་ཆ་ #6: ཤོག་ངོས་ 10" + }, + "splitPages": "ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼‹ą½–ą¾±ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½”ą¼", + "submit": "ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼" + }, + "rotate": { + "tags": "ą½žą½–ą½¦ą¼‹ą½žą½“ą¼‹ą½•ą¾±ą½¼ą½‚ą½¦ą¼", + "title": "Rotate PDF", + "header": "PDF ą½ ą½ą½¼ą½¢ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼", + "selectAngle": "ą½ ą½ą½¼ą½¢ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼‹ą½€ą¾±ą½²ą¼‹ą½Ÿą½“ą½¢ą¼‹ą½šą½‘ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼ (ą½Ÿą½“ą½¢ą¼‹ą½šą½‘ą¼‹ 90 ą½”ą½²ą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½ą½¼ą½–ą¼‹ą½“ą½„ą¼‹ą½‘ą½“ą¼)", + "submit": "ą½ ą½ą½¼ą½¢ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼" + }, + "imageToPdf": { + "tags": "ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼,ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼,jpg,ą½”ą½¢ą¼,ą½ ą½‘ą¾²ą¼‹ą½”ą½¢ą¼" + }, + "pdfToImage": { + "tags": "ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼,ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼,jpg,ą½”ą½¢ą¼,ą½ ą½‘ą¾²ą¼‹ą½”ą½¢ą¼", + "title": "PDF ą½“ą½¦ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½£ą¼", + "header": "PDF ą½“ą½¦ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½£ą¼", + "selectText": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚", + "singleOrMultiple": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½“ą½¦ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½ ą½–ą¾²ą½¦ą¼‹ą½–ą½“ą½ ą½²ą¼‹ą½¢ą½²ą½‚ą½¦ą¼", + "single": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½šą½„ą¼‹ą½˜ą¼‹ą½˜ą½‰ą½˜ą¼‹ą½‘ą½“ą¼‹ą½¦ą¾¦ą¾±ą½¢ą¼‹ą½–ą½ ą½²ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½†ą½ŗą½“ą¼‹ą½”ą½¼ą¼‹ą½‚ą½…ą½²ą½‚", + "multi": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼ ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¢ą½ŗą½¢ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¢ą½ŗą¼", + "colorType": "ą½šą½¼ą½¦ą¼‹ą½˜ą½‘ą½¼ą½‚ą¼‹ą½‚ą½²ą¼‹ą½¢ą½²ą½‚ą½¦ą¼", + "color": "ą½šą½¼ą½¦ą¼‹ą½˜ą½‘ą½¼ą½‚", + "grey": "ą½¦ą¾ą¾±ą¼‹ą½˜ą½‘ą½¼ą½‚", + "blackwhite": "དཀར་ནག (ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½–ą½¢ą¾³ą½‚ą¼‹ą½¦ą¾²ą½²ą½‘ą¼)", + "submit": "ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "info": "Python ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½–ą¾±ą½¦ą¼‹ą½˜ą½²ą¼‹ą½ ą½‘ą½“ą½‚ WebP ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą½¢ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼‹ą½˜ą½ą½¼ą¼‹ą½”ą½²ą½“ą¼", + "placeholder": "(ą½‘ą½”ą½ŗą½¢ą¼‹ą½“ą¼ 1,2,8 པང་ན་ 4,7,12-16 པང་ན་ 2n-1)" + }, + "pdfOrganiser": { + "tags": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½‰ą½²ą½¦ą¼‹ą½˜ą¼,ą½Øą½„ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½Ÿą½“ą½„ą¼‹ą½£ą¾”ą½“ą¼,ą½Øą½„ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½”ą¼‹ą½‚ą¾²ą½„ą½¦ą¼,ą½‚ą½¼ą¼‹ą½¢ą½²ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½”ą¼,ą½¦ą¾¤ą½¼ą¼‹ą½–ą¼", + "title": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½¼ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½˜ą½ą½“ą¼", + "header": "PDF ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½¼ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½˜ą½ą½“ą¼", + "submit": "ཤོག་ངོས་བསྐྱར་སྒྲིག", + "mode": { + "_value": "ą½¢ą¾£ą½˜ą¼‹ą½”ą¼", + "1": "ą½¢ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½¼ą¼‹ą½¢ą½²ą½˜ą¼", + "2": "ą½£ą¾”ą½¼ą½‚ą¼‹ą½•ą¾±ą½¼ą½‚ą½¦ą¼‹ą½‚ą½¼ą¼‹ą½¢ą½²ą½˜ą¼", + "3": "ą½•ą¾±ą½¼ą½‚ą½¦ą¼‹ą½‚ą½‰ą½²ą½¦ą¼‹ą½‚ą½¼ą¼‹ą½¢ą½²ą½˜ą¼", + "4": "ą½‘ą½ŗą½–ą¼‹ą½†ą½“ą½„ą¼‹ą½‚ą½¼ą¼‹ą½¢ą½²ą½˜ą¼", + "5": "ą½Ÿą½“ą½¢ą¼‹ą½ ą½‘ą¾²ą½“ą½‘ą¼‹ą½‘ą½ŗą½–ą¼‹ą½†ą½“ą½„ą¼‹ą½‚ą½¼ą¼‹ą½¢ą½²ą½˜ą¼", + "6": "ą½”ą¼‹ą½Ÿą½“ą½„ą¼‹ą½‘ą½–ą¾±ą½ŗą¼‹ą½–ą¼", + "7": "Remove First", + "8": "Remove Last", + "9": "ą½‘ą½„ą¼‹ą½”ą½¼ą¼‹ą½‘ą½„ą¼‹ą½˜ą½ą½ ą¼‹ą½˜ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "10": "ą½”ą¼‹ą½Ÿą½“ą½„ą¼‹ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼", + "11": "Duplicate all pages" + }, + "placeholder": "(ą½‘ą½”ą½ŗą½¢ą¼‹ą½“ą¼ 1,3,2 པང་ན་ 4-8,2,10-12 པང་ན་ 2n-1)" + }, + "addImage": { + "tags": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼,jpg,ą½”ą½¢ą¼,ą½ ą½‘ą¾²ą¼‹ą½”ą½¢ą¼", + "title": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "header": "PDF ą½£ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "everyPage": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½šą½„ą¼‹ą½˜ą½¢ą¼‹ą½”ą½²ą½“ą¼‹ą½“ą½˜ą¼", + "upload": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "submit": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼" + }, + "watermark": { + "tags": "པི་གེ,ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½Ÿą¾³ą½¼ą½¦ą¼,ཁ་པིག,ą½¢ą½„ą¼‹ą½‘ą½–ą½„ą¼‹ą¼,ą½”ą½¢ą¼‹ą½‘ą½–ą½„ą¼‹ą¼,ą½šą½¼ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼,ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼,jpg,ą½”ą½¢ą¼,ą½ ą½‘ą¾²ą¼‹ą½”ą½¢ą¼", + "title": "ą½¢ą¾Ÿļæ½ą½¦ą¼‹ą½ą½ŗą½£ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "header": "ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½ą½ŗą½£ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "customColor": "ą½”ą½²ą¼‹ą½‚ą½ŗą½ ą½²ą¼‹ą½šą½¼ą½¦ą¼‹ą½˜ą½‘ą½¼ą½‚ą¼‹ą½¢ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚", + "selectText": { + "1": "ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½ą½ŗą½£ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ PDF ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "2": "ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½ą½ŗą½£ą¼‹ą½‚ą¾±ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼", + "3": "ą½”ą½²ą½‚ą¼‹ą½‚ą½Ÿą½“ą½‚ą½¦ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą¼", + "4": "ą½ ą½ą½¼ą½¢ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼ (0-360)", + "5": "ą½žą½ŗą½„ą¼‹ą½šą½‘ą¼‹ą½–ą½¢ą¼‹ą½¦ą¾Ÿą½¼ą½„ą¼‹ą¼ (ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½ą½ŗą½£ą¼‹ą½¢ą½ŗą¼‹ą½¢ą½ŗą½ ą½²ą¼‹ą½–ą½¢ą¼‹ą½‚ą¾±ą½²ą¼‹ą½‚ą½žą½“ą½„ą¼‹ą½•ą¾±ą½¼ą½‚ą½¦ą¼‹ą½–ą½¢ą¼‹ą½ą½‚)", + "6": "ą½˜ą½ą½¼ą¼‹ą½šą½‘ą¼‹ą½–ą½¢ą¼‹ą½¦ą¾Ÿą½¼ą½„ą¼‹ą¼ (ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½ą½ŗą½£ą¼‹ą½¢ą½ŗą¼‹ą½¢ą½ŗą½ ą½²ą¼‹ą½–ą½¢ą¼‹ą½‚ą¾±ą½²ą¼‹ą½‚ą¾±ą½ŗą½“ą¼‹ą½•ą¾±ą½¼ą½‚ą½¦ą¼‹ą½–ą½¢ą¼‹ą½ą½‚)", + "7": "ą½‚ą½¦ą½£ą¼‹ą½šą½‘ą¼ (0% - 100%)", + "8": "ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½ą½ŗą½£ą¼‹ą½‚ą¾±ą½²ą¼‹ą½¢ą½²ą½‚ą½¦ą¼", + "9": "ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½ą½ŗą½£ą¼‹ą½‚ą¾±ą½²ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼", + "10": "PDF ནས་ PDF-ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "submit": "ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½ą½ŗą½£ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "type": { + "1": "པི་གེ", + "2": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼" + } + }, + "permissions": { + "tags": "ą½€ą¾³ą½¼ą½‚ą¼‹ą½”ą¼,ą½ ą½–ą¾²ą½²ą¼‹ą½–ą¼,ą½¢ą¾©ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚,ą½”ą½¢ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼", + "title": "ą½†ą½¼ą½‚ą¼‹ą½˜ą½†ą½“ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "header": "ą½†ą½¼ą½‚ą¼‹ą½˜ą½†ą½“ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "warning": "ą½‰ą½ŗą½“ą¼‹ą½–ą½¢ą¾”ą¼ ą½†ą½¼ą½‚ą¼‹ą½˜ą½†ą½“ą¼‹ą½ ą½‘ą½²ą¼‹ą½‘ą½‚ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½˜ą½²ą¼‹ą½ą½“ą½–ą¼‹ą½”ą¼‹ą½–ą½Ÿą½¼ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼‹ą½“ą¼ ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½“ą½¦ą¼‹ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½‘ą½„ą¼‹ą½˜ą½‰ą½˜ą¼‹ą½‘ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½ ą½¼ą½¦ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼‹ą½”ą½¼ą½‘ą¼", + "selectText": { + "1": "ą½†ą½¼ą½‚ą¼‹ą½˜ą½†ą½“ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ PDF ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "2": "ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ą½–ą¾±ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ą½†ą½¼ą½‚ą¼‹ą½˜ą½†ą½“ą¼", + "3": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼", + "4": "ą½“ą½„ą¼‹ą½‘ą½¼ą½“ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼", + "5": "ą½˜ą½ą½“ą½“ą¼‹ą½¢ą¾ą¾±ą½ŗą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼", + "6": "ą½ ą½‚ą½ŗą½„ą½¦ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½–ą½€ą½„ą¼‹ą½–ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼", + "7": "ą½–ą½Ÿą½¼ą¼‹ą½–ą½…ą½¼ą½¦ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼", + "8": "ą½˜ą½†ą½“ą¼‹ą½ ą½‚ą¾²ą½ŗą½£ą¼‹ą½–ą½Ÿą½¼ą¼‹ą½–ą½…ą½¼ą½¦ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼", + "9": "ą½”ą½¢ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼", + "10": "ą½”ą½¢ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½”ą¼‹ą½˜ą½²ą¼‹ą½ ą½‘ą¾²ą¼‹ą½–ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼" + }, + "submit": "ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "removePages": { + "tags": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼,ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "addPassword": { + "tags": "ą½–ą½‘ą½ŗą¼‹ą½ ą½‡ą½‚ą½¦ą¼,ą½‰ą½ŗą½“ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼", + "title": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "header": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼ (ą½‚ą½¦ą½„ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼)", + "selectText": { + "1": "ą½‚ą½¦ą½„ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½–ą¾±ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ PDF ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "2": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚", + "3": "ą½‚ą½¦ą½„ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½£ą¾”ą½ŗą¼‹ą½˜ą½²ą½‚ą¼‹ą½‚ą½²ą¼‹ą½¢ą½²ą½„ą¼‹ą½šą½‘ą¼", + "4": "ą½šą½‘ą¼‹ą½˜ą½ą½¼ą¼‹ą½–ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½¦ą¾²ą¼‹ą½–ą½¢ą¾Ÿą½“ą¼‹ą½†ą½ŗą¼‹ą½–ą¼‹ą½”ą½¼ą½‘ą¼ ą½ ą½¼ą½“ą¼‹ą½€ą¾±ą½„ą¼‹ą½šą½‘ą¼‹ą½‘ą½˜ą½ ą¼‹ą½–ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½ ą½†ą½˜ą¼‹ą½˜ą½ą½“ą½“ą¼‹ą½¢ą½„ą¼‹ą½–ą½žą½²ą½“ą¼‹ą½–ą½Ÿą½„ą¼‹ą½–ą¼‹ą½”ą½¼ą½‘ą¼", + "5": "ą½†ą½¼ą½‚ą¼‹ą½˜ą½†ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼ (ą½–ą½‘ą½‚ą¼‹ą½”ą½¼ą½ ą½²ą¼‹ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½‘ą½„ą¼‹ą½˜ą½‰ą½˜ą¼‹ą½‘ą½“ą¼‹ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą½¢ą¼‹ą½ ą½¼ą½¦ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼‹ą½–ą¾±ą½ŗą½‘ą¼)", + "6": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼", + "7": "ą½“ą½„ą¼‹ą½‘ą½¼ą½“ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼", + "8": "ą½˜ą½ą½“ą½“ą¼‹ą½¢ą¾ą¾±ą½ŗą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼", + "9": "ą½ ą½‚ą½ŗą½„ą½¦ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½–ą½€ą½„ą¼‹ą½–ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼", + "10": "ą½–ą½Ÿą½¼ą¼‹ą½–ą½…ą½¼ą½¦ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼", + "11": "ą½˜ą½†ą½“ą¼‹ą½ ą½‚ą¾²ą½ŗą½£ą¼‹ą½–ą½Ÿą½¼ą¼‹ą½–ą½…ą½¼ą½¦ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą¼", + "12": "Prevent printin", + "13": "Prevent printing different formats", + "14": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ą½‚ą½¦ą½„ą¼‹ą½‚ą¾²ą½„ą½¦ą¼", + "15": "ą½”ą½²ą½‚ą¼‹ą½šą½‚ą½¦ą¼‹ą½¢ą½„ą¼‹ą½¦ą¾Ÿą½ŗą½„ą¼‹ą½ą¼‹ą½•ą¾±ą½ŗą½¦ą¼‹ą½¢ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą½€ą½‚ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½–ą¾±ą½ŗą½‘ą¼ ą½ ą½‘ą½²ą¼‹ą½£ą¾Ÿą½¢ą¼‹ą½–ą¾±ą½¦ą¼‹ą½“ą¼‹ą½€ą¾³ą½¼ą½‚ą¼‹ą½†ą½¦ą¼‹ą½€ą¾±ą½²ą½¦ą¼‹ą½“ą½“ą½¦ą¼‹ą½”ą¼‹ą½ą½¼ą½“ą¼‹ą½”ą¼‹ą½”ą½ ą½²ą¼‹ą½„ą½ŗą½¦ą¼‹ą½”ą¼‹ą½˜ą½ŗą½‘ą¼", + "16": "ą½”ą½²ą½‚ą¼‹ą½šą½‚ą½¦ą¼‹ą½¢ą½„ą¼‹ą½¦ą¾Ÿą½ŗą½„ą¼‹ą½ą¼‹ą½•ą¾±ą½ŗą½¦ą¼‹ą½¢ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą½€ą½‚ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½–ą¾±ą½ŗą½‘ą¼" + }, + "submit": "ą½‚ą½¦ą½„ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼" + }, + "removePassword": { + "tags": "ą½–ą½‘ą½ŗą¼‹ą½ ą½‡ą½‚ą½¦ą¼,ą½‚ą½¦ą½„ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½‚ą¾²ą½¼ą½£ą¼‹ą½–ą¼,ą½‰ą½ŗą½“ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼,ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½˜ą½ŗą½‘ą¼‹ą½”ą¼,ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "title": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "header": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼ (ą½‚ą½¦ą½„ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½‚ą¾²ą½¼ą½£ą¼‹ą½–ą¼)", + "selectText": { + "1": "ą½‚ą½¦ą½„ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½‚ą¾²ą½¼ą½£ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ PDF ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "2": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚" + }, + "submit": "ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "compressPdfs": { + "tags": "ą½–ą½¦ą¾”ą½“ą½¦ą¼‹ą½”ą¼,ą½†ą½“ą½„ą¼‹ą½†ą½“ą½„ą¼‹ą¼,ą½†ą½“ą½„ą¼‹ą½†ą½“ą½„ą¼‹ą¼" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "ą½ą¼‹ą½–ą¾±ą½„ą¼‹ą¼,ą½¢ą¾©ą½¼ą½˜ą¼‹ą½”ą¼‹ą½”ą½¼ą¼,ą½šą½ŗą½¦ą¼‹ą½‚ą¾²ą½„ą½¦ą¼,ą½–ą½Ÿą½¼ą¼‹ą½–ą¼,ą½‘ą½“ą½¦ą¼‹ą½šą½¼ą½‘ą¼,ą½”ą½¢ą¼‹ą½¦ą¾ą¾²ą½“ą½“ą¼‹ą½”ą¼,ą½ą½¼ą½“ą¼‹ą½¦ą¾ą¾±ą½ŗą½‘ą¼‹ą½”ą¼,ą½¦ą¾”ą½¼ą½˜ą¼‹ą½¢ą¾©ą½²ą½¦ą¼", + "title": "ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½žą½²ą½–ą¼‹ą½•ą¾²ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "header": "ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½žą½²ą½–ą¼‹ą½•ą¾²ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "selectText": { + "1": "ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½ ą½‘ą½¼ą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½ ą½‚ą¾±ą½“ą½¢ą¼‹ą½šą½‘ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½¢ą¾©ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "2": "ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½žą½²ą½–ą¼‹ą½•ą¾²ą¼‹ą½šą½„ą¼‹ą½˜ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "3": "ą½¢ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½žą½²ą½–ą¼‹ą½•ą¾²ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼", + "4": "ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½žą½²ą½–ą¼‹ą½•ą¾²ą¼‹ą½‚ą½žą½“ą¼", + "5": "ą½¢ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½žą½²ą½–ą¼‹ą½•ą¾²ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½¦ą¾£ą½¼ą½“ą¼" + }, + "author": "ą½¢ą¾©ą½¼ą½˜ą¼‹ą½”ą¼‹ą½”ą½¼ą¼", + "creationDate": "ą½–ą½Ÿą½¼ą¼‹ą½–ą½ ą½²ą¼‹ą½‘ą½“ą½¦ą¼‹ą½šą½¼ą½‘ą¼ (yyyy/MM/dd HH:mm:ss)", + "creator": "ą½–ą½Ÿą½¼ą¼‹ą½˜ą½ą½“ą¼", + "keywords": "ą½‚ą½“ą½‘ą¼‹ą½šą½²ą½‚", + "modDate": "ą½–ą½Ÿą½¼ą¼‹ą½–ą½…ą½¼ą½¦ą¼‹ą½‘ą½“ą½¦ą¼‹ą½šą½¼ą½‘ą¼ (yyyy/MM/dd HH:mm:ss)", + "producer": "ą½¦ą¾ą¾²ą½“ą½“ą¼‹ą½˜ą½ą½“ą¼", + "subject": "ą½–ą½¢ą¾—ą½¼ą½‘ą¼‹ą½‚ą½žą½²ą¼", + "trapped": "ą½–ą½Ÿą½“ą½„ą¼‹ą½–ą¼", + "submit": "ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "fileToPDF": { + "tags": "ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą½…ą½¼ą½¦ą¼,ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚,ą½”ą½²ą½‚ą¼‹ą½†ą¼,ą½”ą½¢ą¼,ą½¦ą¾Ÿą½¼ą½“ą¼‹ą½–ą¾±ą½ŗą½‘ą¼,པི་གེ,ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼,ą½”ą½²ą½‚ą¼‹ą½šą½„ą¼‹ą¼,docs,word,excel,powerpoint", + "title": "པིག་ཆ་ནས་ PDF ą½£ą¼", + "header": "པིག་ཆ་གང་རནང་ PDF ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "credit": "ą½žą½–ą½¦ą¼‹ą½žą½“ą¼‹ą½ ą½‘ą½²ą½¦ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą½ ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ LibreOffice དང་ Unoconv ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼", + "supportedFileTypesInfo": "ą½¢ą¾’ą¾±ą½–ą¼‹ą½¦ą¾ą¾±ą½¼ą½¢ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½¢ą½²ą½‚ą½¦ą¼", + "supportedFileTypes": "ą½¢ą¾’ą¾±ą½–ą¼‹ą½¦ą¾ą¾±ą½¼ą½¢ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½¢ą½²ą½‚ą½¦ą¼‹ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½‚ą½¤ą½˜ą¼‹ą½‚ą¾±ą½²ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½ ą½‘ą½“ą½¦ą¼‹ą½”ą½¼ą½‘ą¼‹ą½€ą¾±ą½„ą¼‹ą¼ ą½¢ą¾’ą¾±ą½–ą¼‹ą½¦ą¾ą¾±ą½¼ą½¢ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚ą¼‹ą½‚ą½²ą¼‹ą½†ą¼‹ą½šą½„ą¼‹ą½–ą½ ą½²ą¼‹ą½ą½¼ą¼‹ą½‚ą½žą½“ą½„ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½¤ą½¼ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼ LibreOffice ą½”ą½²ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą½¢ą¼‹ą½‚ą½Ÿą½²ą½‚ą½¦ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "submit": "PDF ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "ocr": { + "tags": "ą½„ą½¼ą½¦ą¼‹ą½ ą½›ą½²ą½“ą¼,པི་གེ,ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼,ą½–ą½¤ą½ŗą½¢ą¼‹ą½ ą½–ą½ŗą½–ą½¦ą¼,ą½€ą¾³ą½¼ą½‚ą¼‹ą½”ą¼,ą½„ą½¼ą½¦ą¼‹ą½ ą½›ą½²ą½“ą¼,ą½ ą½šą½¼ą½£ą¼‹ą½žą½²ą½–ą¼,ą½¢ą¾©ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½¢ą½“ą½„ą¼‹ą½–ą¼", + "title": "OCR / ą½–ļæ½ą½ŗą½¢ą¼‹ą½ ą½–ą½ŗą½–ą½¦ą¼‹ą½‚ą½™ą½„ą¼‹ą½¦ą½ŗą½£ą¼", + "header": "ą½–ą½¤ą½ŗą½¢ą¼‹ą½ ą½–ą½ŗą½–ą½¦ą¼‹ą½‚ą½™ą½„ą¼‹ą½¦ą½ŗą½£ą¼ / OCR (ą½ ą½¼ą½‘ą¼‹ą½€ą¾±ą½²ą¼‹ą½”ą½²ą½‚ą¼‹ą½ ą½–ą¾²ą½“ą¼‹ą½„ą½¼ą½¦ą¼‹ą½ ą½›ą½²ą½“ą¼)", + "selectText": { + "1": "PDF ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½„ą½¼ą½¦ą¼‹ą½ ą½›ą½²ą½“ą¼‹ą½–ą¾±ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ą½¦ą¾ą½‘ą¼‹ą½”ą½²ą½‚ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼ (ą½–ą½€ą½¼ą½‘ą¼‹ą½”ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½“ą½²ą¼‹ą½‘ą¼‹ą½£ą¾Ÿą¼‹ą½„ą½¼ą½¦ą¼‹ą½ ą½›ą½²ą½“ą¼‹ą½–ą¾±ą½¦ą¼‹ą½Ÿą½²ą½“ą¼‹ą½”ą¼‹ą½”ą½²ą½“ą¼)", + "2": "OCR ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½‘ą½„ą¼‹ą½˜ą½‰ą½˜ą¼‹ą½‘ą½“ą¼‹ OCR བྱས་པའི་ PDF ą½”ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą½ ą½²ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½–ą½Ÿą½¼ą¼‹ą½–ą¼", + "3": "ą½”ą½¼ą¼‹ą½ ą½ą¾±ą½¼ą½‚ą¼‹ą½ą½“ą¼‹ą½–ą½¤ą½ŗą½¢ą¼‹ą½ ą½–ą½ŗą½–ą½¦ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½”ą½„ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½ ą½ą½¼ą½¢ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½¦ą¼‹ą½“ą½¦ą¼‹ą½‚ą½“ą½¦ą¼‹ą½¦ą½“ą¼‹ą½ ą½‡ą½¼ą½‚ą¼‹ą½”ą¼", + "4": "OCR ą½‚ą¾±ą½²ą½¦ą¼‹ą½¢ą¾’ą¾±ą½–ą¼‹ą½£ą¾—ą½¼ą½„ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½¦ą¾’ą¾²ą¼‹ą½‚ą½‘ą½„ą½¦ą¼‹ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½¢ą¾™ą½ŗą½‘ą¼‹ą½˜ą½²ą¼‹ą½¦ą¾²ą½²ą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½™ą½„ą¼‹ą½¦ą½ŗą½£ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼ (ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½£ą¼‹ą½ ą½‚ą¾±ą½“ą½¢ą¼‹ą½–ą¼‹ą½˜ą½ŗą½‘ą¼)", + "5": "OCR ą½‚ą¾±ą½²ą½¦ą¼‹ą½¢ą¾’ą¾±ą½–ą¼‹ą½£ą¾—ą½¼ą½„ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½¦ą¾’ą¾²ą¼‹ą½‚ą½‘ą½„ą½¦ą¼‹ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½¢ą¾™ą½ŗą½‘ą¼‹ą½˜ą½²ą¼‹ą½¦ą¾²ą½²ą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½™ą½„ą¼‹ą½¦ą½ŗą½£ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼ ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½‚ą½™ą½„ą¼‹ą½¦ą½ŗą½£ą¼‹ą½¢ą¾’ą¾±ą½“ą½“ą¼‹ą½ ą½ą¾±ą½¼ą½„ą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼", + "6": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½¦ą¾’ą½¼ą¼‹ą½”ą½¼ą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½”ą½¼ą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½¦ą¾£ą½„ą¼‹ą½˜ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½ ą½‡ą½¼ą½‚ą¼‹ą½”ą¼ པར་རིས་པིན་པའི་ཤོག་ངོས་ཁོ་ནར་ OCR ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼", + "7": "OCR ą½–ą½™ą½“ą¼‹ą½¦ą¾ą½“ą½£ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼ ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½šą½„ą¼‹ą½˜ą½¢ą¼‹ OCR ą½–ą¾±ą½¦ą¼‹ą½“ą½¦ą¼‹ą½ą½¼ą½‚ą¼‹ą½˜ą½ ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą½ ą½²ą¼‹ą½‚ą½žą½²ą¼‹ą½¢ą¾ą¾±ą½ŗą½“ą¼‹ą½šą½„ą¼‹ą½˜ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "8": "ą½¢ą¾’ą¾±ą½“ą½“ą¼‹ą½£ą¾”ą½“ą¼ (PDF ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½”ą½¼ą½‘ą¼‹ą½“ą¼‹ą½“ą½¼ą½¢ą¼‹ą½ ą½ą¾²ą½“ą½£ą¼‹ą½ ą½–ą¾±ą½“ą½„ą¼‹ą¼)", + "9": "ą½Ÿą½“ą½¢ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼", + "10": "OCR ą½¢ą¾£ą½˜ą¼‹ą½”ą¼", + "11": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼", + "12": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼" + }, + "help": "ą½¦ą¾ą½‘ą¼‹ą½”ą½²ą½‚ą¼‹ą½‚ą½žą½“ą¼‹ą½‘ą½‚ą¼‹ą½‚ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½¦ą¾Ÿą½„ą½¦ą¼‹ą½‘ą½„ą¼‹/པང་ན་ docker ą½˜ą½²ą½“ą¼‹ą½”ą½ ą½²ą¼‹ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½€ą¾±ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½²ą¼‹ą½€ą¾³ą½¼ą½‚ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "credit": "ą½žą½–ą½¦ą¼‹ą½žą½“ą¼‹ą½ ą½‘ą½²ą½¦ą¼‹ OCR གྱི་ཆེད་དན་ qpdf དང་ Tesseract ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼", + "submit": "OCR བརྒྱནད་ནས་ PDF ą½–ą½€ą½¼ą½£ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼" + }, + "extractImages": { + "tags": "ą½”ą½¢ą¼,ą½ ą½‘ą¾²ą¼‹ą½”ą½¢ą¼,ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼,ą½”ą½²ą½‚ą¼‹ą½˜ą½›ą½¼ą½‘ą¼,zip,ą½ ą½›ą½²ą½“ą¼‹ą½”ą¼,ą½£ą½ŗą½“ą¼‹ą½”ą¼", + "title": "Extract Images", + "header": "Extract Images", + "selectText": "ą½•ą¾±ą½²ą½¢ą¼‹ą½–ą½ą½¼ą½“ą¼‹ą½”ą½ ą½²ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "allowDuplicates": "ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½Ÿą¾³ą½¼ą½¦ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼", + "submit": "ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼" + }, + "pdfToPDFA": { + "tags": "ą½”ą½²ą½‚ą¼‹ą½˜ą½›ą½¼ą½‘ą¼,ą½‘ą½“ą½¦ą¼‹ą½”ą½“ą½“ą¼‹ą½¢ą½²ą½„ą¼‹ą½”ą½¼ą¼,ą½šą½‘ą¼‹ą½£ą¾”ą½“ą¼,ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼,ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼,ą½¦ą¾²ą½“ą½„ą¼‹ą½¦ą¾ą¾±ą½¼ą½–ą¼", + "title": "PDF ནས་ PDF/A ą½£ą¼", + "header": "PDF ནས་ PDF/A ą½£ą¼", + "credit": "ą½žą½–ą½¦ą¼‹ą½žą½“ą¼‹ą½ ą½‘ą½²ą½¦ą¼‹ PDF/A བསྒྱནར་བའི་ཆེད་དན་ libreoffice ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼", + "submit": "ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "tip": "ą½‘ą¼‹ą½£ą¾Ÿą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼‹ą½‘ą½“ą½¦ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½˜ą½²ą¼‹ą½ą½“ą½–ą¼", + "outputFormat": "ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚", + "pdfWithDigitalSignature": "PDF ą½ ą½‘ą½²ą½¢ą¼‹ą½Øą½„ą¼‹ą½€ą½²ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½”ą½¼ą½‘ą¼ ą½ ą½‘ą½²ą¼‹ą½¢ą¾—ą½ŗą½¦ą¼‹ą½˜ą½ ą½²ą¼‹ą½¢ą½²ą½˜ą¼‹ą½”ą½¢ą¼‹ą½¦ą½“ą½–ą¼‹ą½„ą½ŗą½¦ą¼‹ą½”ą½²ą½“ą¼" + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą½…ą½¼ą½¦ą¼,ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚,ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼,ą½”ą½²ą½‚ą¼‹ą½šą½„ą¼‹ą¼,microsoft,docfile", + "title": "PDF ནས་ Word ą½£ą¼", + "header": "PDF ནས་ Word ą½£ą¼", + "selectText": { + "1": "ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚" + }, + "credit": "ą½žą½–ą½¦ą¼‹ą½žą½“ą¼‹ą½ ą½‘ą½²ą½¦ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą½ ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ LibreOffice ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼", + "submit": "ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "PDFToPresentation": { + "tags": "ą½¦ą¾Ÿą½¼ą½“ą¼‹ą½–ą¾±ą½ŗą½‘ą¼,ą½ ą½ą¾²ą½–ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼,ą½”ą½²ą½‚ą¼‹ą½šą½„ą¼‹ą¼,microsoft", + "title": "PDF ą½“ą½¦ą¼‹ą½¦ą¾¤ą¾±ą½“ą¼‹ą½ ą½–ą½“ą½£ą¼‹ą½£ą¼", + "header": "PDF ą½“ą½¦ą¼‹ą½¦ą¾¤ą¾±ą½“ą¼‹ą½ ą½–ą½“ą½£ą¼‹ą½£ą¼", + "selectText": { + "1": "ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚" + }, + "credit": "This service uses LibreOffice for file conversion.", + "submit": "Convert" + }, + "PDFToText": { + "tags": "richformat,richtextformat,rich text format", + "title": "PDF ནས་ RTF ą½£ą¼ (པི་གེ)", + "header": "PDF ནས་ RTF ą½£ą¼ (པི་གེ)", + "selectText": { + "1": "ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚" + }, + "credit": "This service uses LibreOffice for file conversion.", + "submit": "Convert" + }, + "PDFToHTML": { + "tags": "ą½‘ą¾²ą¼‹ą½„ą½¼ą½¦ą¼‹ą½“ą½„ą¼‹ą½‘ą½¼ą½“ą¼,ą½–ą½¤ą½¢ą¼‹ą½†ą½¦ą¼‹ą½ ą½†ą½˜ą¼‹ą½˜ą½ą½“ą½“ą¼", + "title": "PDF ནས་ HTML ą½£ą¼", + "header": "PDF ནས་ HTML ą½£ą¼", + "credit": "This service uses pdftohtml for file conversion.", + "submit": "Convert" + }, + "PDFToXML": { + "tags": "ą½‚ą½žą½²ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼,ą½¦ą¾’ą¾²ą½¼ą½˜ą¼‹ą½‚ą½žą½²ą¼‹ą½…ą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ą½“ą½„ą¼‹ą½‘ą½¼ą½“ą¼,ą½˜ą½‰ą½˜ą¼‹ą½ ą½–ą¾²ą½ŗą½£ą¼,ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą½…ą½¼ą½¦ą¼,ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "title": "PDF ནས་ XML ą½£ą¼", + "header": "PDF ནས་ XML ą½£ą¼", + "credit": "This service uses LibreOffice for file conversion.", + "submit": "Convert" + }, + "ScannerImageSplit": { + "tags": "ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼,ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½„ą½¼ą½¦ą¼‹ą½ ą½›ą½²ą½“ą¼,ą½–ą½¤ą½ŗą½¢ą¼‹ą½ ą½–ą½ŗą½–ą½¦ą¼,ą½”ą½¢ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼,གོ་སྒྲིག", + "selectText": { + "1": "ļæ½ą½“ą½¢ą¼‹ą½šą½‘ą¼‹ą½˜ą½šą½˜ą½¦ą¼", + "2": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½ ą½ą½¼ą½¢ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½‰ą½“ą½„ą¼‹ą½˜ą½ą½ ą½²ą¼‹ą½Ÿą½“ą½¢ą¼‹ą½šą½‘ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼ (སྔོན་སྒྲིག 10)", + "3": "ą½–ą½Ÿą½¼ą½‘ą¼‹ą½¦ą¾²ą½“ą¼‹ą½šą½‘ą¼", + "4": "ą½šą½¼ą½‘ą¼‹ą½‘ą½”ą½‚ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½¢ą¾’ą¾±ą½–ą¼‹ą½£ą¾—ą½¼ą½„ą½¦ą¼‹ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą½ ą½²ą¼‹ą½˜ą½ą½ ą¼‹ą½ ą½ą½¼ą½¢ą¼‹ą½‚ą¾±ą½²ą¼‹ą½šą½¼ą½¦ą¼‹ą½˜ą½‘ą½¼ą½‚ą¼‹ą½ ą½‚ą¾±ą½“ą½¢ą¼‹ą½–ą½ ą½²ą¼‹ą½ą¾±ą½–ą¼‹ą½šą½‘ą¼‹ą½ą½‚ą¼‹ą½‚ą½…ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼ (སྔོན་སྒྲིག 30)", + "5": "ą½‰ą½“ą½„ą¼‹ą½˜ą½ą½ ą½²ą¼‹ą½¢ą¾’ą¾±ą¼‹ą½ą¾±ą½¼ą½“ą¼", + "6": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¤ą½²ą½‚ą¼‹ą½‚ą½²ą¼‹ą½‰ą½“ą½„ą¼‹ą½˜ą½ą½ ą½²ą¼‹ą½¢ą¾’ą¾±ą¼‹ą½ą¾±ą½¼ą½“ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼ (སྔོན་སྒྲིག 10000)", + "7": "ą½‰ą½“ą½„ą¼‹ą½˜ą½ą½ ą½²ą¼‹ą½˜ą½ą½ ą¼‹ą½ ą½ą½¼ą½¢ą¼‹ą½¢ą¾’ą¾±ą¼‹ą½ą¾±ą½¼ą½“ą¼", + "8": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¤ą½²ą½‚ą¼‹ą½‚ą½²ą¼‹ą½‰ą½“ą½„ą¼‹ą½˜ą½ą½ ą½²ą¼‹ą½˜ą½ą½ ą¼‹ą½ ą½ą½¼ą½¢ą¼‹ą½¢ą¾’ą¾±ą¼‹ą½ą¾±ą½¼ą½“ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼", + "9": "ą½˜ą½ą½ ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą¼", + "10": "ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½”ą½ ą½²ą¼‹ą½“ą½„ą¼‹ą½‘ą½€ą½¢ą¼‹ą½˜ą½ą½ ą¼‹ą½ ą½‚ą½¼ą½‚ą¼‹ą½”ą½ ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼‹ą½‘ą½„ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ļæ½ļæ½ (སྔོན་སྒྲིག 1)" + }, + "info": "Python ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½–ą¾±ą½¦ą¼‹ą½˜ą½²ą¼‹ą½ ą½‘ą½“ą½‚ ą½ ą½‘ą½²ą¼‹ą½–ą½€ą½¼ą½£ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą½¢ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼‹ą½˜ą½ą½¼ą¼‹ą½”ą½²ą½“ą¼" + }, + "sign": { + "tags": "ą½‘ą½–ą½„ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼,ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½ą½“ą½„ą¼‹ą½„ą½“ą¼‹ą¼,ą½–ą¾²ą½²ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼,ą½”ą½²ą¼‹ą½‚ą½ŗą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼,ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼", + "title": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼", + "header": "PDF ą½£ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½”ą¼", + "upload": "པར་རིས་པར་འཇོག", + "draw": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½ ą½–ą¾²ą½²ą¼‹ą½–ą¼", + "text": "ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½”ą¼", + "clear": "ą½‚ą½™ą½„ą¼‹ą½¦ą½ŗą½£ą¼", + "add": "ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "saved": "ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼", + "save": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼", + "personalSigs": "ą½¦ą¾’ą½ŗą½¢ą¼‹ą½‚ą¾±ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼", + "sharedSigs": "ą½˜ą½‰ą½˜ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼", + "noSavedSigs": "ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½˜ą¼‹ą½¢ą¾™ą½ŗą½‘ą¼", + "addToAll": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½šą½„ą¼‹ą½˜ą½¢ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "delete": "ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "first": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‘ą½„ą¼‹ą½”ą½¼ą¼", + "last": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½˜ą½ą½ ą¼‹ą½˜ą¼", + "next": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¢ą¾—ą½ŗą½¦ą¼‹ą½˜ą¼", + "previous": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¦ą¾”ą½¼ą½“ą¼‹ą½˜ą¼", + "maintainRatio": "ą½–ą½¦ą¾”ą½“ą½¢ą¼‹ą½šą½‘ą¼‹ą½¢ą¾’ą¾±ą½“ą½“ą¼‹ą½ ą½ą¾±ą½¼ą½„ą½¦ą¼‹ą½¦ą¾’ą½¼ą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½”ą¼", + "undo": "Undo", + "redo": "Redo" + }, + "flatten": { + "tags": "ą½¦ą¾™ą½¼ą½˜ą½¦ą¼‹ą½”ą¼,འགེངས་ཤོག,ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½¦ą¾’ą½¼ą¼,ą½†ą¼‹ą½¤ą½¦ą¼,ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "title": "ą½¦ą¾™ļæ½ą½˜ą½¦ą¼‹ą½”ą¼", + "header": "PDF ą½¦ą¾™ą½¼ą½˜ą½¦ą¼‹ą½”ą¼", + "flattenOnlyForms": "ą½ ą½‚ą½ŗą½„ą½¦ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½ą½¼ą¼‹ą½“ą¼‹ą½¦ą¾™ą½¼ą½˜ą½¦ą¼‹ą½”ą¼", + "submit": "ą½¦ą¾™ą½¼ą½˜ą½¦ą¼‹ą½”ą¼" + }, + "repair": { + "tags": "ą½¦ą¾ą¾±ą½¼ą½“ą¼‹ą½¦ą½ŗą½£ą¼,ą½–ą½Ÿą½¼ą¼‹ą½–ą½…ą½¼ą½¦ą¼,ą½‚ą½¦ą½¼ą¼‹ą½–ą¼,ą½£ą½ŗą½‚ą½¦ą¼‹ą½–ą½…ą½¼ą½¦ą¼", + "title": "ą½–ą½Ÿą½¼ą¼‹ą½–ą½…ą½¼ą½¦ą¼", + "header": "PDF ą½–ą½Ÿą½¼ą¼‹ą½–ą½…ą½¼ą½¦ą¼", + "submit": "ą½–ą½Ÿą½¼ą¼‹ą½–ą½…ą½¼ą½¦ą¼" + }, + "removeBlanks": { + "tags": "ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼ ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½”ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼ ą½‘ą½€ą½¢ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼ PDF ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "title": "ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "header": "ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½”ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "threshold": "ą½”ą½²ą½‚ą¼‹ą½Ÿą½ŗą½£ą¼‹ą½‘ą½€ą½¢ą¼‹ą½”ą½¼ą½ ą½²ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½šą½‘ą¼", + "thresholdDesc": "ą½”ą½²ą½‚ą¼‹ą½Ÿą½ŗą½£ą¼‹ą½‘ą½€ą½¢ą¼‹ą½”ą½¼ą¼‹ą½žą½²ą½‚ą¼‹'དཀར་པོ་'ą½¢ą½“ą¼‹ą½¢ą¾©ą½²ą¼‹ą½–ą½ ą½²ą¼‹ą½‘ą½€ą½¢ą¼‹ą½šą½‘ą¼‹ą½€ą¾±ą½²ą¼‹ą½˜ą½šą½˜ą½¦ą¼ 0 = ą½“ą½‚ą¼‹ą½”ą½¼ą¼ 255 ą½‘ą½€ą½¢ą¼‹ą½”ą½¼ą¼‹ą½‚ą½™ą½„ą¼‹ą½˜ą¼", + "whitePercent": "ą½‘ą½€ą½¢ą¼‹ą½”ą½¼ą½ ą½²ą¼‹ą½–ą½¢ą¾’ą¾±ą¼‹ą½†ą¼ (%)", + "whitePercentDesc": "སནབ་རྒྱནའི་ཤོག་ངོས་ཤིག་གི་'དཀར་པོའི་'ą½”ą½²ą½‚ą¼‹ą½Ÿą½ŗą½£ą¼‹ą½‚ą¾±ą½²ą¼‹ą½–ą½¢ą¾’ą¾±ą¼‹ą½†ą¼", + "submit": "ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "removeAnnotations": { + "tags": "ą½˜ą½†ą½“ą¼‹ą½ ą½‚ą¾²ą½ŗą½£ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼ ą½‘ą½”ą¾±ą½‘ą¼‹ą½–ą½¢ą¾—ą½¼ą½‘ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼ ą½˜ą½†ą½“ą¼‹ą½–ą½“ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼ PDF ą½˜ą½†ą½“ą¼‹ą½ ą½‚ą¾²ą½ŗą½£ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "title": "ą½˜ą½†ą½“ą¼‹ą½ ą½‚ą¾²ą½ŗą½£ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "header": "ą½˜ą½†ą½“ą¼‹ą½ ą½‚ą¾²ą½ŗą½£ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "submit": "ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "compare": { + "tags": "ą½–ą½¦ą¾”ą½“ą½¢ą¼‹ą½–ą¼ ą½ą¾±ą½‘ą¼‹ą½”ą½¢ą¼ ą½žą½²ą½–ą¼‹ą½–ą½¦ą¾”ą½“ą½¢ą¼ ą½‚ą½¤ą½²ą½–ą¼‹ą½–ą½¦ą¾”ą½“ą½¢ą¼ PDF ą½–ą½¦ą¾”ą½“ą½¢ą¼‹ą½–ą¼", + "title": "ą½–ą½¦ļæ½ą½“ą½¢ą¼‹ą½–ą¼", + "header": "PDF ą½–ą½¦ą¾”ą½“ą½¢ą¼‹ą½–ą¼", + "highlightColor": { + "1": "ą½˜ą½‘ą½„ą½¦ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼‹ ą¼”ą¼", + "2": "ą½˜ą½‘ą½„ą½¦ą¼‹ą½ ą½‘ą½¼ą½“ą¼‹ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼‹ ą¼¢ą¼" + }, + "document": { + "1": "པིག་ཆ་ ą¼”", + "2": "པིག་ཆ་ ą¼¢" + }, + "submit": "ą½–ą½¦ą¾”ą½“ą½¢ą¼‹ą½–ą¼", + "complex": { + "message": "ą½˜ą½ą½¼ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½‚ą½˜ą¼‹ą½‚ą½‰ą½²ą½¦ą¼‹ą½€ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½†ą½ŗą½“ą¼‹ą½”ą½¼ą¼‹ą½”ą½²ą½“ą¼‹ą½”ą½¦ą¼ ą½–ą½¦ą¾”ą½“ą½¢ą¼‹ą½–ą½ ą½²ą¼‹ą½ą½‚ą¼‹ą½ą½‚ą¼‹ą½šą½‘ą¼‹ą½‰ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½ ą½‚ą¾²ą½¼ą¼‹ą½¦ą¾²ą½²ą½‘ą¼" + }, + "large": { + "file": { + "message": "ą½˜ą½ą½¼ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½‚ą½˜ą¼‹ą½‚ą½‰ą½²ą½¦ą¼‹ą½€ą¼‹ą½–ą½€ą½¼ą½£ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½˜ą½²ą¼‹ą½ą½“ą½–ą¼‹ą½”ą½ ą½²ą¼‹ą½†ą½ŗą¼‹ą½šą½‘ą¼‹ą½”ą½²ą½“ą¼" + } + }, + "no": { + "text": { + "message": "ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ PDF ą½‚ą½…ą½²ą½‚ą¼‹ą½‚ą½˜ą¼‹ą½‚ą½‰ą½²ą½¦ą¼‹ą½€ą½¢ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą½ ą½²ą¼‹ą½“ą½„ą¼‹ą½‘ą½¼ą½“ą¼‹ą½˜ą½²ą¼‹ą½ ą½‘ą½“ą½‚ བསྔནར་བའི་ཆེད་དན་པི་གེ་པོད་པའི་ PDF ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼" + } + } + }, + "certSign": { + "tags": "ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼,PEM,P12,ą½‚ą½žą½“ą½„ą¼‹ą½ ą½–ą¾²ą½ŗą½£ą¼,ą½‚ą½¦ą½„ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼", + "title": "ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼", + "header": "ཁྱེད་ཀྱི་ལག་ཁྱེར་གྱིས་ PDF ą½£ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½”ą¼ (ą½£ą½¦ą¼‹ą½€ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½–ą½žą½²ą½“ą¼‹ą½”ą¼)", + "selectPDF": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "jksNote": "ą½‘ą¾²ą½“ą¼‹ą½‚ą½¦ą½¼ą¼ ą½‚ą½£ą¼‹ą½¦ą¾²ą½²ą½‘ą¼‹ą½ą¾±ą½ŗą½‘ą¼‹ą½€ą¾±ą½²ą¼‹ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½‚ą¾±ą½²ą¼‹ą½¢ą½²ą½‚ą½¦ą¼‹ą½‚ą½¤ą½˜ą¼‹ą½‘ą½“ą¼‹ą½˜ą½ŗą½‘ą¼‹ą½“ą¼ keytool བཀའ་བརྔ་ཐིག་བེད་སྤྱོད་བྱས་ནས་ Java Keystore (.jks) ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼ ą½‘ą½ŗą¼‹ą½“ą½¦ą¼‹ą½‚ą½¤ą½˜ą¼‹ą½‘ą½“ą¼‹ .jks ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "selectKey": "ą½¦ą¾’ą½ŗą½¢ą¼‹ą½‚ą¾±ą½²ą¼‹ą½£ą¾”ą½ŗą¼‹ą½˜ą½²ą½‚ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼ (PKCS#8 ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚ .pem པང་ན་ .der ą½”ą½²ą½“ą¼‹ą½¦ą¾²ą½²ą½‘ą¼)", + "selectCert": "ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼ (X.509 ą½¢ą¾£ą½˜ą¼‹ą½‚ą½žą½‚ .pem པང་ན་ .der ą½”ą½²ą½“ą¼‹ą½¦ą¾²ą½²ą½‘ą¼)", + "selectP12": "PKCS#12 ą½£ą¾”ą½ŗą¼‹ą½˜ą½²ą½‚ą¼‹ą½˜ą½›ą½¼ą½‘ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼ (.p12 པང་ན་ .pfx) (ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½¢ą½“ą½„ą¼‹ą¼ ą½‚ą½£ą¼‹ą½¦ą¾²ą½²ą½‘ą¼‹ą½˜ą½ą½¼ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½–ą¾±ą½¦ą¼‹ą½“ą¼ ą½‘ą½ŗą½ ą½²ą¼‹ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½ą¾±ą½ŗą½‘ą¼‹ą½€ą¾±ą½²ą¼‹ą½¦ą¾’ą½ŗą½¢ą¼‹ą½‚ą¾±ą½²ą¼‹ą½£ą¾”ą½ŗą¼‹ą½˜ą½²ą½‚ą¼‹ą½‘ą½„ą¼‹ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½ ą½‘ą½“ą½¦ą¼‹ą½”ą½¼ą½‘ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼)", + "selectJKS": "Java ą½£ą¾”ą½ŗą¼‹ą½˜ą½²ą½‚ą¼‹ą½˜ą½›ą½¼ą½‘ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼ (.jks པང་ན་ .keystore)", + "certType": "ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½‚ą¾±ą½²ą¼‹ą½¢ą½²ą½‚ą½¦ą¼", + "password": "ą½ą¾±ą½ŗą½‘ą¼‹ą½€ą¾±ą½²ą¼‹ą½£ą¾”ą½ŗą¼‹ą½˜ą½²ą½‚ą¼‹ą½˜ą½›ą½¼ą½‘ą¼‹ą½‘ą½˜ą¼‹ą½¦ą¾’ą½ŗą½¢ą¼‹ą½‚ą¾±ą½²ą¼‹ą½£ą¾”ą½ŗą¼‹ą½˜ą½²ą½‚ą¼‹ą½‚ą½²ą¼‹ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½”ą¼ (ą½‚ą½£ą¼‹ą½¦ą¾²ą½²ą½‘ą¼‹ą½”ą½¼ą½‘ą¼‹ą½“ą¼)", + "showSig": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼", + "reason": "ą½¢ą¾’ą¾±ą½“ą¼‹ą½˜ą½šą½“ą¼", + "location": "ą½¦ą¼‹ą½‚ą½“ą½¦ą¼", + "name": "ą½˜ą½²ą½„ą¼‹ą¼", + "showLogo": "ą½˜ą½šą½¼ą½“ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼", + "submit": "PDF ą½£ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½”ą¼" + }, + "removeCertSign": { + "tags": "ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼,PEM,P12,ą½‚ą½žą½“ą½„ą¼‹ą½ ą½–ą¾²ą½ŗą½£ą¼,ą½‚ą½¦ą½„ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½‚ą¾²ą½¼ą½£ą¼‹ą½–ą¼", + "title": "ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "header": "PDF ą½“ą½¦ą¼‹ą½Øą½„ą¼‹ą½€ą½²ą½ ą½²ą¼‹ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "selectPDF": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "submit": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "pageLayout": { + "tags": "ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼,ą½–ą½¦ą¾”ą½“ą½¦ą¼‹ą½”ą¼,ą½£ą¾Ÿą¼‹ą½šą½“ą½£ą¼‹ą½‚ą½…ą½²ą½‚,གོ་སྒྲིག", + "title": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą½ ą½²ą¼‹ą½–ą½€ą½¼ą½‘ą¼‹ą½”ą¼", + "header": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą½ ą½²ą¼‹ą½–ą½€ą½¼ą½‘ą¼‹ą½”ą¼", + "pagesPerSheet": "ą½¤ą½¼ą½‚ą¼‹ą½£ą¾·ą½ŗą¼‹ą½¢ą½ŗą½¢ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą¾²ą½„ą½¦ą¼", + "addBorder": "ą½˜ą½ą½ ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "submit": "ą½•ą½“ą½£ą¼‹ą½–ą¼" + }, + "scalePages": { + "tags": "ཆེ་ཆནང་བསྐྱར་སྒྲིག,ą½–ą½Ÿą½¼ą¼‹ą½–ą½…ą½¼ą½¦ą¼,ą½šą½‘ą¼‹ą½‚ą½žą½²ą¼,ą½–ą½¦ą¾Ÿą½“ą½“ą¼‹ą½ ą½‚ą¾±ą½“ą½¢ą¼", + "title": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą½¦ą¾™ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚", + "header": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą½¦ą¾™ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚", + "pageSize": "ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą¼", + "keepPageSize": "ą½ą½¼ą½‚ą¼‹ą½˜ą½ ą½²ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą¼", + "scaleFactor": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą½šą½‘ą¼ (ą½‚ą½ą½“ą½–ą¼‹ą½‚ą½…ą½¼ą½‘ą¼)", + "submit": "ą½•ą½“ą½£ą¼‹ą½–ą¼" + }, + "add-page-numbers": { + "tags": "ą½¤ą½¼ą½‚ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½”ą¼,ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼,གོ་སྒྲིག,དཀར་ཆག" + }, + "auto-rename": { + "tags": "ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½„ą½¼ą½¦ą¼‹ą½ ą½›ą½²ą½“ą¼,ą½ ą½‚ą½¼ą¼‹ą½–ą½¢ą¾—ą½¼ą½‘ą¼‹ą½‚ą½žą½²ą½¢ą¼‹ą½–ą½Ÿą½“ą½„ą¼‹ą¼,གོ་སྒྲིག,ą½˜ą½²ą½„ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½ ą½‘ą½¼ą½‚ą½¦ą¼", + "title": "ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½˜ą½²ą½„ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½ ą½‘ą½¼ą½‚ą½¦ą¼", + "header": "PDF ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½˜ą½²ą½„ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½ ą½‘ą½¼ą½‚ą½¦ą¼", + "submit": "ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½˜ą½²ą½„ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½ ą½‘ą½¼ą½‚ą½¦ą¼" + }, + "adjust-contrast": { + "tags": "ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼‹ą½£ą½ŗą½‚ą½¦ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚,ą½¦ą¾™ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚,ą½–ą½Ÿą½¼ą¼‹ą½–ą½…ą½¼ą½¦ą¼,ą½”ą½¢ą¼‹ą½¢ą¾’ą¾±ą½¦ą¼,ą½šą½¼ą½¦ą¼‹ą½˜ą½‘ą½„ą½¦ą¼‹ą½£ą½ŗą½‚ą½¦ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚" + }, + "crop": { + "tags": "ą½‚ą½ą½“ą½–ą¼‹ą½”ą¼,ą½†ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½‚ą½ą½¼ą½„ą¼‹ą½–ą¼,ą½¢ą¾©ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚,ą½‘ą½–ą¾±ą½²ą½–ą½¦ą¼", + "title": "ą½‚ą½ą½“ą½–ą¼‹ą½‚ą½…ą½¼ą½‘ą¼", + "header": "PDF ą½‚ą½ą½“ą½–ą¼‹ą½‚ą½…ą½¼ą½‘ą¼", + "submit": "ą½•ą½“ą½£ą¼‹ą½–ą¼" + }, + "autoSplitPDF": { + "tags": "QR ą½‚ą½žą½²ą½¢ą¼‹ą½–ą½Ÿą½“ą½„ą¼‹ą¼,ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼,ą½–ą½¤ą½ŗą½¢ą¼‹ą½‘ą½“ą½˜ą¼,གོ་སྒྲིག", + "title": "PDF ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "header": "PDF ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "description": "ą½”ą½¢ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼ ནང་འཇནག ą½–ą½¤ą½ŗą½¢ą¼‹ą½ ą½–ą½ŗą½–ą½¦ą¼ ą½”ą½¢ą¼‹ą½ ą½‡ą½¼ą½‚ą¼‹ą½–ą¾±ą½¦ą¼‹ą½“ą½¦ą¼‹ą½„ą¼‹ą½šą½¼ą½¦ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½‚ą¾±ą½²ą½¦ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½ ą½‡ą½“ą½‚ ą½£ą½‚ą¼‹ą½–ą½Ÿą½¼ą½¦ą¼‹ą½‚ą½¼ą¼‹ą½¢ą½²ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼‹ą½˜ą½ŗą½‘ą¼", + "selectText": { + "1": "ą½‚ą½¤ą½˜ą¼‹ą½“ą½¦ą¼‹ą½–ą½¢ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½–ą½“ą¼‹ą½ ą½‚ą½ ą¼‹ą½”ą½¢ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼ (ནག་དཀར་པིན་ནའང་འགྲིག)", + "2": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½šą½„ą¼‹ą½˜ą½ ą½²ą¼‹ą½–ą½¢ą¼‹ą½‘ą½“ą¼‹ą½–ą½¢ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½–ą½“ą¼‹ą½–ą½…ą½“ą½‚ą¼‹ą½“ą½¦ą¼‹ą½ą½ŗą½„ą½¦ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½£ą¼‹ą½–ą½¤ą½ŗą½¢ą¼‹ą½ ą½–ą½ŗą½–ą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ą¼", + "3": "བཤེར་འབེབས་བྱས་པའི་ PDF པིག་ཆ་ཆེན་པོ་གཅིག་པར་འཇོག་བྱས་ནས་ Stirling PDF ą½£ą¼‹ą½£ą¾·ą½‚ą¼‹ą½˜ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½ ą½‡ą½“ą½‚", + "4": "ą½–ą½¢ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¢ą¾£ą½˜ą½¦ą¼‹ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½‚ą¾±ą½²ą½¦ą¼‹ą½„ą½¼ą½¦ą¼‹ą½ ą½›ą½²ą½“ą¼‹ą½‘ą½„ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼‹ą½–ą¾±ą½¦ą¼‹ą½“ą½¦ą¼‹ą½˜ą½ą½ ą¼‹ą½˜ą½ ą½²ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½‚ą½™ą½„ą¼‹ą½˜ą¼‹ą½žą½²ą½‚ą¼‹ą½„ą½ŗą½¦ą¼‹ą½”ą½¢ą¼‹ą½‘ą½“ą¼‹ą½ą½¼ą½–ą¼‹ą½ą½“ą½–ą¼" + }, + "formPrompt": "Stirling-PDF ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½–ą½¢ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½”ą½¼ą½‘ą¼‹ą½”ą½ ą½²ą¼‹ PDF ą½•ą½“ą½£ą¼‹ą½–ą¼", + "duplexMode": "ą½•ą¾±ą½¼ą½‚ą½¦ą¼‹ą½‚ą½‰ą½²ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½”ą¼ (ą½˜ą½‘ą½“ą½“ą¼‹ą½¢ą¾’ą¾±ą½–ą¼‹ą½–ą½¤ą½ŗą½¢ą¼‹ą½ ą½–ą½ŗą½–ą½¦ą¼)", + "dividerDownload2": "'ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼‹ą½–ą½¢ą¼‹ą½˜ą½šą½˜ą½¦ą¼ (ą½–ą½€ą½¼ą½£ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½£ą½˜ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼‹ą½‘ą½„ą¼‹ą½–ą½…ą½¦ą¼‹ą½”ą¼).pdf' ą½•ą½–ą¼‹ą½£ą½ŗą½“ą¼", + "submit": "ą½•ą½“ą½£ą¼‹ą½–ą¼" + }, + "sanitizePdf": { + "tags": "ą½‚ą½™ą½„ą¼‹ą½¦ą½ŗą½£ą¼,ą½–ą½‘ą½ŗą¼‹ą½ ą½‡ą½‚ą½¦ą¼,ą½‰ą½ŗą½“ą¼‹ą½˜ą½ŗą½‘ą¼,ą½‰ą½ŗą½“ą¼‹ą½ą¼‹ą½¦ą½ŗą½£ą¼‹ą½–ą¼" + }, + "URLToPDF": { + "tags": "ą½‘ą¾²ą¼‹ą½„ą½¼ą½¦ą¼‹ą½£ą½ŗą½“ą¼‹ą½”ą¼,ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‰ą½¢ą¼‹ą½šą½‚ą½¦ą¼,ą½‘ą¾²ą¼‹ą½šą½²ą½‚ą½¦ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼,ą½”ą½²ą½‚ą¼‹ą½˜ą½›ą½¼ą½‘ą¼", + "title": "URL ནས་ PDF ą½£ą¼", + "header": "URL ནས་ PDF ą½£ą¼", + "submit": "ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "credit": "WeasyPrint ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "HTMLToPDF": { + "tags": "ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚,ą½‘ą¾²ą¼‹ą½„ą½¼ą½¦ą¼‹ą½“ą½„ą¼‹ą½‘ą½¼ą½“ą¼,ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą½…ą½¼ą½¦ą¼,ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "title": "HTML ནས་ PDF ą½£ą¼", + "header": "HTML ནས་ PDF ą½£ą¼", + "help": "HTML ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½‘ą½„ą¼‹ą½‘ą½‚ą½¼ą½¦ą¼‹ą½˜ą½ą½¼ą½ ą½²ą¼‹ html/css/པར་རིས་སོགས་འདནས་པའི་ ZIP ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½„ą½¼ą½¦ą¼‹ą½£ą½ŗą½“ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼", + "submit": "ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "credit": "WeasyPrint ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼", + "zoom": "ą½‘ą¾²ą¼‹ą½šą½²ą½‚ą½¦ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼‹ą½”ą½ ą½²ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą½šą½‘ą¼", + "pageWidth": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½žą½ŗą½„ą¼‹ą½šą½‘ą¼‹ą½¦ą½ŗą½“ą¼‹ą½Šą½²ą¼‹ą½˜ą½²ą¼‹ą½Šą½¢ą¼‹ą½“ą½„ą¼‹ą¼ (ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½”ą½¢ą¼‹ą½–ą½žą½‚ą¼‹ą½“ą¼‹ą½¦ą¾”ą½¼ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚)", + "pageHeight": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½‘ą½”ą½„ą½¦ą¼‹ą½šą½‘ą¼‹ą½¦ą½ŗą½“ą¼‹ą½Šą½²ą¼‹ą½˜ą½²ą¼‹ą½Šą½¢ą¼‹ą½“ą½„ą¼‹ą¼ (ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½”ą½¢ą¼‹ą½–ą½žą½‚ą¼‹ą½“ą¼‹ą½¦ą¾”ą½¼ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚)", + "marginTop": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½¦ą¾Ÿą½ŗą½„ą¼‹ą½˜ą½ą½ ą½²ą¼‹ą½–ą½¢ą¼‹ą½ą½‚ą¼‹ą½˜ą½²ą¼‹ą½£ą½²ą¼‹ą½˜ą½²ą¼‹ą½Šą½¢ą¼‹ą½“ą½„ą¼‹ą¼ (ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½”ą½¢ą¼‹ą½–ą½žą½‚ą¼‹ą½“ą¼‹ą½¦ą¾”ą½¼ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚)", + "marginBottom": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½ ą½¼ą½‚ą¼‹ą½˜ą½ą½ ą½²ą¼‹ą½–ą½¢ą¼‹ą½ą½‚ą¼‹ą½˜ą½²ą¼‹ą½£ą½²ą¼‹ą½˜ą½²ą¼‹ą½Šą½¢ą¼‹ą½“ą½„ą¼‹ą¼ (ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½”ą½¢ą¼‹ą½–ą½žą½‚ą¼‹ą½“ą¼‹ą½¦ą¾”ą½¼ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚)", + "marginLeft": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½‚ą½”ą½¼ą½“ą¼‹ą½˜ą½ą½ ą½²ą¼‹ą½–ą½¢ą¼‹ą½ą½‚ą¼‹ą½˜ą½²ą¼‹ą½£ą½²ą¼‹ą½˜ą½²ą¼‹ą½Šą½¢ą¼‹ą½“ą½„ą¼‹ą¼ (ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½”ą½¢ą¼‹ą½–ą½žą½‚ą¼‹ą½“ą¼‹ą½¦ą¾”ą½¼ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚)", + "marginRight": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½‚ą½”ą½¦ą¼‹ą½˜ą½ą½ ą½²ą¼‹ą½–ą½¢ą¼‹ą½ą½‚ą¼‹ą½˜ą½²ą¼‹ą½£ą½²ą¼‹ą½˜ą½²ą¼‹ą½Šą½¢ą¼‹ą½“ą½„ą¼‹ą¼ (ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½”ą½¢ą¼‹ą½–ą½žą½‚ą¼‹ą½“ą¼‹ą½¦ą¾”ą½¼ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚)", + "printBackground": "ą½‘ą¾²ą¼‹ą½šą½²ą½‚ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½¢ą¾’ą¾±ą½–ą¼‹ą½£ą¾—ą½¼ą½„ą½¦ą¼‹ą½˜ą½„ą½¼ą½“ą¼‹ą½”ą¼", + "defaultHeader": "ą½¦ą¾”ą½¼ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½˜ą½‚ą½¼ą¼‹ą½–ą¾±ą½„ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½”ą¼ (ą½˜ą½²ą½„ą¼‹ą½‘ą½„ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½‚ą¾²ą½„ą½¦ą¼)", + "cssMediaType": "ཤོག་ངོས་ཀྱི་ CSS ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½£ą½˜ą¼‹ą½¢ą½²ą½‚ą½¦ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "none": "ą½˜ą½ŗą½‘ą¼", + "print": "ą½”ą½¢ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼", + "screen": "ą½–ą½¢ą¾™ą½“ą¼‹ą½”ą½¼ą½£ą¼" + }, + "MarkdownToPDF": { + "tags": "ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚,ą½‘ą¾²ą¼‹ą½„ą½¼ą½¦ą¼‹ą½“ą½„ą¼‹ą½‘ą½¼ą½“ą¼,ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą½…ą½¼ą½¦ą¼,ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "title": "Markdown ནས་ PDF ą½£ą¼", + "header": "Markdown ནས་ PDF ą½£ą¼", + "submit": "ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "help": "ą½£ą½¦ą¼‹ą½€ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½–ą½žą½²ą½“ą¼‹ą½”ą¼", + "credit": "WeasyPrint ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼" + }, + "PDFToMarkdown": { + "tags": "markup,web-content,transformation,convert,md", + "title": "PDF To Markdown", + "header": "PDF To Markdown", + "submit": "Convert" + }, + "getPdfInfo": { + "tags": "ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼,ą½‚ą½žą½²ą¼‹ą½‚ą¾²ą½„ą½¦ą¼,ą½¦ą¾”ą½¼ą½˜ą¼‹ą½¢ą¾©ą½²ą½¦ą¼,ą½‚ą¾²ą½„ą½¦ą¼‹ą½ą½¼ą¼", + "title": "PDF ą½”ą½²ą¼‹ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½£ą½ŗą½“ą¼‹ą½”ą¼", + "header": "PDF ą½”ą½²ą¼‹ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½£ą½ŗą½“ą¼‹ą½”ą¼", + "submit": "ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½£ą½ŗą½“ą¼‹ą½”ą¼", + "downloadJson": "JSON ą½•ą½–ą¼‹ą½£ą½ŗą½“ą¼" + }, + "extractPage": { + "tags": "ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼" + }, + "PdfToSinglePage": { + "tags": "ཤོག་ངོས་གཅིག" + }, + "showJS": { + "tags": "JS", + "title": "Javascript ą½¦ļæ½ą½¼ą½“ą¼‹ą½”ą¼", + "header": "Javascript ą½¦ą¾Ÿą½¼ą½“ą¼‹ą½”ą¼", + "downloadJS": "Javascript ą½•ą½–ą¼‹ą½£ą½ŗą½“ą¼", + "submit": "ą½¦ą¾Ÿą½¼ą½“ą¼‹ą½”ą¼" + }, + "autoRedact": { + "tags": "ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼,ą½¦ą¾¦ą½¦ą¼‹ą½”ą¼,ą½“ą½‚ą¼‹ą½”ą½¼ą½¦ą¼‹ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½”ą¼,ą½“ą½‚ą¼‹ą½”ą½¼ą¼,ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚,ą½¦ą¾¦ą½¦ą¼‹ą½”ą¼", + "title": "ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼", + "header": "ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼", + "colorLabel": "ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼", + "textsToRedactLabel": "ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼ (ą½ą½²ą½‚ą¼‹ą½•ą¾²ą½ŗą½„ą¼‹ą½¦ą½¼ą¼‹ą½¦ą½¼ą½¢ą¼)", + "textsToRedactPlaceholder": "ą½‘ą½”ą½ŗą½¢ą¼‹ą½“ą¼ \\ną½‚ą½¦ą½„ą¼‹ą½–ą¼ \\ną½‚ą½¦ą½„ą¼‹ą½†ą½ŗą¼", + "useRegexLabel": "Regex ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼", + "wholeWordSearchLabel": "ą½šą½²ą½‚ą¼‹ą½†ą¼‹ą½šą½„ą¼‹ą½ ą½šą½¼ą½£ą¼‹ą½–ą¼", + "customPaddingLabel": "ą½˜ą½ą½ ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½¦ą¾Ÿą½¼ą½„ą¼‹ą½†ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼", + "convertPDFToImageLabel": "PDF ནས་ PDF-ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼ (ą½¦ą¾’ą¾²ą½¼ą½˜ą¼‹ą½‚ą¾±ą½²ą¼‹ą½¢ą¾’ą¾±ą½–ą¼‹ą½€ą¾±ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą½¢ą¼‹ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼)", + "submitButton": "ą½•ą½“ą½£ą¼‹ą½–ą¼" + }, + "redact": { + "tags": "ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼,ą½¦ą¾¦ą½¦ą¼‹ą½”ą¼,ą½“ą½‚ą¼‹ą½”ą½¼ą½¦ą¼‹ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½”ą¼,ą½“ą½‚ą¼‹ą½”ą½¼ą¼,ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¾’ą¾±ą½‚,ą½¦ą¾¦ą½¦ą¼‹ą½”ą¼,ą½£ą½‚ą¼‹ą½–ą½Ÿą½¼ą½¦ą¼", + "title": "ą½£ą½‚ą¼‹ą½–ą½Ÿą½¼ą½¦ą¼‹ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼", + "header": "ą½£ą½‚ą¼‹ą½–ą½Ÿą½¼ą½¦ą¼‹ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼", + "submit": "ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼", + "textBasedRedaction": "ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½‚ą½žą½²ą½¢ą¼‹ą½–ą½Ÿą½“ą½„ą¼‹ą½–ą½ ą½²ą¼‹ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼", + "pageBasedRedaction": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½žą½²ą½¢ą¼‹ą½–ą½Ÿą½“ą½„ą¼‹ą½–ą½ ą½²ą¼‹ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼", + "convertPDFToImageLabel": "PDF ནས་ PDF-ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼ (ą½¦ą¾’ą¾²ą½¼ą½˜ą¼‹ą½‚ą¾±ą½²ą¼‹ą½¢ą¾’ą¾±ą½–ą¼‹ą½€ą¾±ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą½¢ą¼‹ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼)", + "pageRedactionNumbers": { + "title": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼", + "placeholder": "(ą½‘ą½”ą½ŗą½¢ą¼‹ą½“ą¼ 1,2,8 པང་ན་ 4,7,12-16 པང་ན་ 2n-1)" + }, + "redactionColor": { + "title": "ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą½‚ą½²ą¼‹ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼" + }, + "export": "ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą¾²ą½ŗą½“ą¼", + "upload": "པར་འཇནག", + "boxRedaction": "ą½¦ą¾’ą¾²ą½¼ą½˜ą¼‹ą½–ą¾²ą½²ą½¦ą¼‹ą½¦ą¾’ą¾²ą½²ą½–ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą¼", + "zoom": "ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą¼", + "zoomIn": "ą½†ą½ŗą¼‹ą½¢ą½“ą¼‹ą½‚ą½ą½¼ą½„ą¼‹ą½–ą¼", + "zoomOut": "ą½†ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½‚ą½ą½¼ą½„ą¼‹ą½–ą¼", + "nextPage": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¢ą¾—ą½ŗą½¦ą¼‹ą½˜ą¼", + "previousPage": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¦ą¾”ą½¼ą½“ą¼‹ą½˜ą¼", + "toggleSidebar": "ą½Ÿą½“ą½¢ą¼‹ą½¦ą¾£ą½ŗą½ ą½²ą¼‹ą½¦ą¾”ą½ŗą¼‹ą½šą½“ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼‹ą½¦ą¾¦ą½¦ą¼", + "showThumbnails": "ą½–ą½¦ą¾”ą½“ą½¦ą¼‹ą½”ą½¢ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼", + "showDocumentOutline": "ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½¦ą¾’ą¾²ą½¼ą½˜ą¼‹ą½‚ą½žą½²ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼ (ą½“ą½„ą¼‹ą½‚ą½¦ą½ŗą½¦ą¼‹ą½šą½„ą¼‹ą½˜ą¼‹ą½¢ą¾’ą¾±ą¼‹ą½¦ą¾ą¾±ą½ŗą½‘ą¼‹/ą½–ą½¦ą¾”ą½“ą¼‹ą½–ą½¢ą¼‹ą½‰ą½²ą½¦ą¼‹ą½¢ą¾”ą½ŗą½–ą¼)", + "showAttatchments": "ą½Ÿą½“ą½¢ą¼‹ą½¦ą¾¦ą¾±ą½¢ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼", + "showLayers": "ą½¢ą½²ą½˜ą¼‹ą½”ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼ (ą½¢ą½²ą½˜ą¼‹ą½”ą¼‹ą½šą½„ą¼‹ą½˜ą¼‹ą½¦ą¾”ą½¼ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½‚ą½“ą½¦ą¼‹ą½–ą½–ą¼‹ą½£ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą½¢ą¼‹ą½‰ą½²ą½¦ą¼‹ą½¢ą¾”ą½ŗą½–ą¼)", + "colourPicker": "ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½–ą¾±ą½ŗą½‘ļæ½ļæ½ļæ½", + "findCurrentOutlineItem": "ą½‘ą¼‹ą½£ą¾Ÿą½ ą½²ą¼‹ą½¦ą¾’ą¾²ą½¼ą½˜ą¼‹ą½‚ą½žą½²ą½ ą½²ą¼‹ą½“ą½„ą¼‹ą½‘ą½¼ą½“ą¼‹ą½ ą½šą½¼ą½£ą¼‹ą½–ą¼", + "applyChanges": "Apply Changes" + }, + "tableExtraxt": { + "tags": "CSV,ą½¢ą½ŗą½ ą½“ą¼‹ą½˜ą½²ą½‚ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼,ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼,ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "autoSizeSplitPDF": { + "tags": "pdf,ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼,ą½”ą½²ą½‚ą¼‹ą½†ą¼,གོ་སྒྲིག" + }, + "overlay-pdfs": { + "tags": "ą½¦ą¾Ÿą½ŗą½„ą¼‹ą½–ą½¢ą¾©ą½ŗą½‚ą½¦ą¼", + "header": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½–ą½¢ą¾©ą½ŗą½‚ą½¦ą¼‹ą½”ą¼", + "baseFile": { + "label": "ą½‚ą½žą½²ą¼‹ą½¢ą¾©ą½ ą½²ą¼‹ PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼" + }, + "overlayFiles": { + "label": "བརྩེགས་རྒྱནའི་ PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼" + }, + "mode": { + "label": "ą½–ą½¢ą¾©ą½ŗą½‚ą½¦ą¼‹ą½¦ą¾Ÿą½„ą½¦ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "sequential": "ą½¢ą½²ą½˜ą¼‹ą½–ą½žą½²ą½“ą¼‹ą½–ą½¢ą¾©ą½ŗą½‚ą½¦ą¼‹ą½”ą¼", + "interleaved": "ą½¦ą¾¤ą½ŗą½£ą¼‹ą½˜ą½¢ą¼‹ą½–ą½¢ą¾©ą½ŗą½‚ą½¦ą¼‹ą½”ą¼", + "fixedRepeat": "ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½Ÿą¾³ą½¼ą½¦ą¼‹ą½‚ą½ą½“ą¼‹ą½ ą½‡ą½‚ą½¦ą¼‹ą½–ą½¢ą¾©ą½ŗą½‚ą½¦ą¼‹ą½”ą¼" + }, + "counts": { + "label": "ą½–ą½¢ą¾©ą½ŗą½‚ą½¦ą¼‹ą½‚ą¾²ą½„ą½¦ą¼ (ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½Ÿą¾³ą½¼ą½¦ą¼‹ą½‚ą½ą½“ą¼‹ą½ ą½‡ą½‚ą½¦ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½”ą½ ą½²ą¼‹ą½†ą½ŗą½‘ą¼)", + "placeholder": "ą½šą½ŗą½‚ą¼‹ą½ą¾±ą½²ą½˜ą¼‹ą½‚ą¾±ą½²ą½¦ą¼‹ą½–ą½…ą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½€ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½”ą¼ (ą½‘ą½”ą½ŗą½¢ą¼‹ą½“ą¼ 2,3,1)" + }, + "position": { + "label": "ą½–ą½¢ą¾©ą½ŗą½‚ą½¦ą¼‹ą½¦ą½ ą½²ą¼‹ą½‚ą½“ą½¦ą¼‹ą½¦ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "foreground": "ą½˜ą½‘ą½“ą½“ą¼‹ą½„ą½¼ą½¦ą¼", + "background": "ą½¢ą¾’ą¾±ą½–ą¼‹ą½£ą¾—ą½¼ą½„ą½¦ą¼" + }, + "submit": "ą½•ą½“ą½£ą¼‹ą½–ą¼" + }, + "split-by-sections": { + "tags": "ą½‘ą½“ą½˜ą¼‹ą½–ą½“ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼,ą½–ą½‚ą½¼ą¼‹ą½–ą¼,རང་སྒྲིག,ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼", + "title": "ļæ½ą¼‹ą½¤ą½¦ą¼‹ą½£ą¾Ÿą½¢ą¼‹ PDF ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "header": "PDF ą½†ą¼‹ą½¤ą½¦ą¼‹ą½¦ą½“ą¼‹ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "horizontal": { + "label": "ą½‚ą½žą½“ą½„ą¼‹ą½•ą¾±ą½¼ą½‚ą½¦ą¼‹ą½–ą½‚ą½¼ą¼‹ą½–ą½¤ą½ ą¼", + "placeholder": "ą½‚ą½žą½“ą½„ą¼‹ą½•ą¾±ą½¼ą½‚ą½¦ą¼‹ą½–ą½‚ą½¼ą¼‹ą½–ą½¤ą½ ą½²ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½€ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½”ą¼" + }, + "vertical": { + "label": "ą½‚ą¾±ą½ŗą½“ą¼‹ą½•ą¾±ą½¼ą½‚ą½¦ą¼‹ą½–ą½‚ą½¼ą¼‹ą½–ą½¤ą½ ą¼", + "placeholder": "ą½‚ą¾±ą½ŗą½“ą¼‹ą½•ą¾±ą½¼ą½‚ą½¦ą¼‹ą½–ą½‚ą½¼ą¼‹ą½–ą½¤ą½ ą½²ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½€ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½”ą¼" + }, + "submit": "PDF ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "merge": "PDF ą½‚ą½…ą½²ą½‚ą¼‹ą½ą½“ą¼‹ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼" + }, + "AddStampRequest": { + "tags": "ą½ą½ŗą½£ą¼‹ą½™ą½ŗą¼,ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą¾£ą½¼ą½“ą¼‹ą½”ą¼,ą½‘ą½€ą¾±ą½²ą½£ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼,ą½†ą½“ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼,PDF,ནང་འཇནག,རང་སྒྲིག,ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼", + "header": "PDF ą½£ą¼‹ą½ą½ŗą½£ą¼‹ą½™ą½ŗą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½”ą¼", + "title": "PDF ą½£ą¼‹ą½ą½ŗą½£ą¼‹ą½™ą½ŗą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½”ą¼", + "stampType": "ą½ą½ŗą½£ą¼‹ą½™ą½ŗą½ ą½²ą¼‹ą½¢ą½²ą½‚ą½¦ą¼", + "stampText": "ཐེལ་ཙེའི་པི་གེ", + "stampImage": "ą½ą½ŗą½£ą¼‹ą½™ą½ŗą½ ą½²ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼", + "alphabet": "ą½”ą½²ą¼‹ą½‚ą½ŗą½ ą½²ą¼‹ą½‚ą½Ÿą½“ą½‚ą½¦ą¼", + "fontSize": "པི་གེ/ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą¼", + "rotation": "ą½ ą½ą½¼ą½¢ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼", + "opacity": "ą½‚ą½¦ą½£ą¼‹ą½šą½‘ą¼", + "position": "ą½‚ą½“ą½¦ą¼‹ą½¦ą¼", + "overrideX": "X ą½‚ą½“ą½¦ą¼‹ą½šą½‘ą¼‹ą½–ą½¢ą¾—ą½ŗą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼", + "overrideY": "Y ą½‚ą½“ą½¦ą¼‹ą½šą½‘ą¼‹ą½–ą½¢ą¾—ą½ŗą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼", + "customMargin": "ą½˜ą½ą½ ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½¢ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚", + "customColor": "ą½”ą½²ą¼‹ą½‚ą½ŗą½ ą½²ą¼‹ą½šą½¼ą½¦ą¼‹ą½˜ą½‘ą½¼ą½‚ą¼‹ą½¢ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚", + "submit": "ą½•ą½“ą½£ą¼‹ą½–ą¼" + }, + "removeImagePdf": { + "tags": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼,ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½–ą½€ą½¼ą½£ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼,ą½¢ą¾’ą¾±ą½–ą¼‹ą½„ą½¼ą½¦ą¼,ą½žą½–ą½¦ą¼‹ą½žą½“ą¼‹ą½•ą¾±ą½¼ą½‚ą½¦ą¼" + }, + "splitPdfByChapters": { + "tags": "ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼,ą½£ą½ŗą½ ą½“ą¼,ą½‘ą½”ą½ŗą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼,གོ་སྒྲིག" + }, + "validateSignature": { + "tags": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼,ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼,ཆ་འཇོག,pdf,ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼,ą½Øą½„ą¼‹ą½€ą½²ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼,ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼,ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼", + "title": "PDF ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼", + "header": "ą½Øą½„ą¼‹ą½€ą½²ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼", + "selectPDF": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½–ą½€ą½¼ą½‘ą¼‹ą½”ą½ ą½²ą¼‹ PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "submit": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼", + "results": "ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½ ą½–ą¾²ą½¦ą¼‹ą½–ą½“ą¼", + "status": { + "_value": "ą½‚ą½“ą½¦ą¼‹ą½¦ą¾Ÿą½„ą½¦ą¼", + "valid": "ą½“ą½“ą½¦ą¼‹ą½£ą¾”ą½“ą¼", + "invalid": "ą½“ą½“ą½¦ą¼‹ą½˜ą½ŗą½‘ą¼" + }, + "signer": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼", + "date": "ą½‘ą½“ą½¦ą¼‹ą½šą½¼ą½‘ą¼", + "reason": "ą½¢ą¾’ą¾±ą½“ą¼‹ą½˜ą½šą½“ą¼", + "location": "ą½¦ą¼‹ą½‚ą½“ą½¦ą¼", + "noSignatures": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½²ą½ ą½²ą¼‹ą½“ą½„ą¼‹ą½‘ą½“ą¼‹ą½Øą½„ą¼‹ą½€ą½²ą½ ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½˜ą¼‹ą½¢ą¾™ą½ŗą½‘ą¼", + "chain": { + "invalid": "ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½¢ą½²ą½˜ą¼‹ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½˜ą¼‹ą½ ą½‚ą¾²ą½“ą½–ą¼‹ą½”ą¼ - ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ą½„ą½¼ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½˜ą½²ą¼‹ą½ą½“ą½–ą¼" + }, + "trust": { + "invalid": "ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½”ą½²ą½‘ą¼‹ą½†ą½ŗą½¦ą¼‹ą½˜ą½›ą½¼ą½‘ą¼‹ą½ą½„ą¼‹ą½“ą½„ą¼‹ą½˜ą½ŗą½‘ą¼‹ą½”ą¼ - ą½ ą½–ą¾±ą½“ą½„ą¼‹ą½ą½“ą½„ą½¦ą¼‹ą½¢ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½˜ą½²ą¼‹ą½ą½“ą½–ą¼" + }, + "cert": { + "expired": "ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½‘ą½“ą½¦ą¼‹ą½”ą½¼ą½£ą¼‹ą½Ÿą½²ą½“ą¼", + "revoked": "ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½ą½ŗą½“ą¼‹ą½–ą¾±ą½¦ą¼‹ą½Ÿą½²ą½“ą¼", + "info": "ą½£ą½‚ą¼‹ą½ą¾±ą½ŗą½¢ą¼‹ą½žą½²ą½–ą¼‹ą½•ą¾²ą¼", + "issuer": "ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼", + "subject": "ą½–ą½¢ą¾—ą½¼ą½‘ą¼‹ą½‚ą½žą½²ą¼", + "serialNumber": "ą½Øą½„ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½‚ą½¼ą¼‹ą½¢ą½²ą½˜ą¼", + "validFrom": "ą½“ą½“ą½¦ą¼‹ą½£ą¾”ą½“ą¼‹ą½ ą½‚ą½¼ą¼‹ą½ ą½›ą½“ą½‚ą½¦ą¼", + "validUntil": "ą½“ą½“ą½¦ą¼‹ą½£ą¾”ą½“ą¼‹ą½˜ą½‡ą½“ą½‚ą¼‹ą½¦ą¾’ą¾²ą½²ą½£ą¼", + "algorithm": "ą½–ą¾±ą½ŗą½‘ą¼‹ą½ą½–ą½¦ą¼", + "keySize": "ą½£ą¾”ą½ŗą¼‹ą½˜ą½²ą½‚ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą¼", + "version": "ą½”ą½¢ą¼‹ą½‚ą½žą½²ą¼", + "keyUsage": "ą½£ą¾”ą½ŗą¼‹ą½˜ą½²ą½‚ą¼‹ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼", + "selfSigned": "ą½¢ą½„ą¼‹ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼", + "bits": "ą½‚ą½“ą½¦ą¼" + }, + "signature": { + "info": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼", + "_value": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼", + "mathValid": "ą½˜ą½²ą½„ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½Øą½„ą¼‹ą½¢ą¾©ą½²ą½¦ą¼‹ą½ą½¼ą½‚ą¼‹ą½“ą½¦ą¼‹ą½“ą½“ą½¦ą¼‹ą½£ą¾”ą½“ą¼‹ą½”ą½²ą½“ą¼‹ą½”ą½„ą¼‹ą¼" + }, + "selectCustomCert": "རང་སྒྲིག་ལག་ཁྱེར་པིག་ཆ་ X.509 (ą½ ą½‘ą½˜ą¼‹ą½‚)" + }, + "replace-color": { + "title": "ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą½ ą½²ą¼‹ą½‚ą½‘ą½˜ą¼‹ą½‚ą¼‹ą½˜ą½ą½¼ą¼‹ą½¢ą½²ą½˜ą¼", + "header": "ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼‹ą½–ą½¢ą¾—ą½ŗą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹-ལྔོག་སྒྱནར་ PDF", + "selectText": { + "1": "ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼‹ą½–ą½¢ą¾—ą½ŗą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½¢ą½˜ą¼‹ą½£ą¾”ą½¼ą½‚ą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½‚ą¾±ą½²ą¼‹ą½‚ą½‘ą½˜ą¼‹ą½‚", + "2": "སྔོན་སྒྲིག (ą½¦ą¾”ą½¼ą½“ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½‚ą½²ą¼‹ą½ ą½¼ą½‘ą¼‹ą½ą¾±ą½‘ą¼‹ą½˜ą½ą½¼ą¼‹ą½–ą½ ą½²ą¼‹ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼)", + "3": "རང་སྒྲིག (ą½¢ą½„ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½‚ą½²ą¼‹ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼)", + "4": "ą½”ą½¼ą½„ą½¦ą¼‹ą½¢ą¾«ą½¼ą½‚ą½¦ą¼‹ą½£ą¾”ą½¼ą½‚ą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼ (ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼‹ą½šą½„ą¼‹ą½˜ą¼‹ą½£ą¾”ą½¼ą½‚ą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼)", + "5": "ą½ ą½¼ą½‘ą¼‹ą½ą¾±ą½‘ą¼‹ą½˜ą½ą½¼ą¼‹ą½–ą½ ą½²ą¼‹ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą½ ą½²ą¼‹ą½‚ą½‘ą½˜ą¼‹ą½‚", + "6": "ą½¢ą¾’ą¾±ą½–ą¼‹ą½£ą¾—ą½¼ą½„ą½¦ą¼‹ą½“ą½‚ą¼‹ą½”ą½¼ą½ ą½²ą¼‹ą½¦ą¾Ÿą½ŗą½„ą¼‹ą½‚ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½‘ą½€ą½¢ą¼‹ą½”ą½¼ą¼", + "7": "ą½¢ą¾’ą¾±ą½–ą¼‹ą½£ą¾—ą½¼ą½„ą½¦ą¼‹ą½‘ą½€ą½¢ą¼‹ą½”ą½¼ą½ ą½²ą¼‹ą½¦ą¾Ÿą½ŗą½„ą¼‹ą½‚ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½“ą½‚ą¼‹ą½”ą½¼ą¼", + "8": "ą½¢ą¾’ą¾±ą½–ą¼‹ą½£ą¾—ą½¼ą½„ą½¦ą¼‹ą½“ą½‚ą¼‹ą½”ą½¼ą½ ą½²ą¼‹ą½¦ą¾Ÿą½ŗą½„ą¼‹ą½‚ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½¦ą½ŗą½¢ą¼‹ą½”ą½¼ą¼", + "9": "ą½¢ą¾’ą¾±ą½–ą¼‹ą½£ą¾—ą½¼ą½„ą½¦ą¼‹ą½“ą½‚ą¼‹ą½”ą½¼ą½ ą½²ą¼‹ą½¦ą¾Ÿą½ŗą½„ą¼‹ą½‚ą½²ą¼‹ą½”ą½²ą¼‹ą½‚ą½ŗą¼‹ą½£ą¾—ą½„ą¼‹ą½ą½“ą¼", + "10": "ą½”ą½²ą¼‹ą½‚ą½ŗą½ ą½²ą¼‹ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "11": "ą½¢ą¾’ą¾±ą½–ą¼‹ą½£ą¾—ą½¼ą½„ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼" + }, + "submit": "ą½–ą½¢ą¾—ą½ŗą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼" + }, + "replaceColorPdf": { + "tags": "ą½šą½¼ą½¦ą¼‹ą½‚ą½žą½²ą¼‹ą½–ą½¢ą¾—ą½ŗą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼,ཤོག་ངོས་བཀོལ་སྤྱོད���,ą½¢ą¾’ą¾±ą½–ą¼‹ą½„ą½¼ą½¦ą¼,ą½žą½–ą½¦ą¼‹ą½žą½“ą¼‹ą½•ą¾±ą½¼ą½‚ą½¦ą¼" + }, + "login": { + "title": "ļæ½ą½„ą¼‹ą½ ą½›ą½“ą½£ą¼", + "header": "ą½“ą½„ą¼‹ą½ ą½›ą½“ą½£ą¼", + "signin": "ą½“ą½„ą¼‹ą½ ą½›ą½“ą½£ą¼", + "rememberme": "ą½„ą¼‹ą½‘ą¾²ą½“ą¼‹ą½”ą½¢ą¼‹ą½–ą¾±ą½ŗą½‘ą¼", + "invalid": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½²ą½„ą¼‹ą½„ą½˜ą¼‹ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½“ą½¼ą½¢ą¼‹ą½ ą½‘ą½“ą½‚", + "locked": "ą½ą¾±ą½ŗą½‘ą¼‹ą½€ą¾±ą½²ą¼‹ą½ą½¼ą¼‹ą½˜ą½›ą½¼ą½‘ą¼‹ą½Ÿą¾­ą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½–ą½¢ą¾’ą¾±ą½–ą¼‹ą½Ÿą½²ą½“ą¼", + "signinTitle": "ą½“ą½„ą¼‹ą½ ą½›ą½“ą½£ą¼‹ą½‚ą½“ą½„ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "ssoSignIn": "ą½‚ą½…ą½²ą½‚ą¼‹ą½‚ą¾±ą½“ą½¢ą¼‹ą½“ą½„ą¼‹ą½ ą½›ą½“ą½£ą¼‹ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½“ą½¦ą¼‹ą½“ą½„ą¼‹ą½ ą½›ą½“ą½£ą¼", + "oAuth2AutoCreateDisabled": "OAUTH2 ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½–ą½Ÿą½¼ą¼‹ą½–ą½€ą½‚ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½–ą¾±ą½¦ą¼‹ą½Ÿą½²ą½“ą¼", + "oAuth2AdminBlockedUser": "ą½‘ą¼‹ą½£ą¾Ÿą¼‹ą½ą½¼ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ą½˜ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ą½ą½¼ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ą½‘ą½„ą¼‹ą½“ą½„ą¼‹ą½ ą½›ą½“ą½£ą¼‹ą½–ą½€ą½‚ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½¼ą½‘ą¼ ą½‘ą½¼ą¼‹ą½‘ą½˜ą¼‹ą½”ą½¢ą¼‹ą½ ą½–ą¾²ą½ŗą½£ą¼‹ą½–ą¼‹ą½‚ą½“ą½„ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "oauth2RequestNotFound": "ą½‘ą½–ą½„ą¼‹ą½¦ą¾¤ą¾²ą½¼ą½‘ą¼‹ą½¢ą½ŗą¼‹ą½žą½“ą¼‹ą½¢ą¾™ą½ŗą½‘ą¼‹ą½˜ą¼‹ą½–ą¾±ą½“ą½„ą¼‹ą¼", + "oauth2InvalidUserInfoResponse": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½‚ą¾±ą½²ą¼‹ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½£ą½“ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼‹ą½“ą½¼ą½¢ą¼‹ą½ ą½ą¾²ą½“ą½£ą¼", + "oauth2invalidRequest": "ą½¢ą½ŗą¼‹ą½žą½“ą¼‹ą½“ą½¼ą½¢ą¼‹ą½ ą½ą¾²ą½“ą½£ą¼", + "oauth2AccessDenied": "འཛནལ་སྤྱོད་བཀག་འགོག", + "oauth2InvalidTokenResponse": "ą½–ą½¢ą¾”ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½£ą½“ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼‹ą½“ą½¼ą½¢ą¼‹ą½ ą½ą¾²ą½“ą½£ą¼", + "oauth2InvalidIdToken": "ą½„ą½¼ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½–ą½¢ą¾”ą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½“ą½¼ą½¢ą¼‹ą½ ą½ą¾²ą½“ą½£ą¼", + "relyingPartyRegistrationNotFound": "ą½–ą½¢ą¾Ÿą½ŗą½“ą¼‹ą½¦ą½ ą½²ą¼‹ą½šą½¼ą½‚ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½ą½¼ą¼‹ą½ ą½‚ą½¼ą½‘ą¼‹ą½¢ą¾™ą½ŗą½‘ą¼‹ą½˜ą¼‹ą½–ą¾±ą½“ą½„ą¼‹ą¼", + "userIsDisabled": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½–ą½€ą½‚ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½–ą¾±ą½¦ą¼‹ą½Ÿą½²ą½“ą¼ ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½²ą½„ą¼‹ą½ ą½‘ą½²ą¼‹ą½–ą½¢ą¾’ą¾±ą½“ą½‘ą¼‹ą½“ą½¦ą¼‹ą½“ą½„ą¼‹ą½ ą½›ą½“ą½£ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½˜ą½²ą¼‹ą½†ą½¼ą½‚ ą½‘ą½¼ą¼‹ą½‘ą½˜ą¼‹ą½”ą½¢ą¼‹ą½ ą½–ą¾²ą½ŗą½£ą¼‹ą½–ą¼‹ą½‚ą½“ą½„ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "alreadyLoggedIn": "ཁྱེད་རང་", + "alreadyLoggedIn2": "ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½†ą½¦ą¼‹ą½“ą½„ą¼‹ą½“ą½„ą¼‹ą½ ą½›ą½“ą½£ą¼‹ą½–ą¾±ą½¦ą¼‹ą½Ÿą½²ą½“ą¼ ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½†ą½¦ą¼‹ą½“ą½¦ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½ą½ŗą½“ą¼‹ą½–ą¾±ą½¦ą¼‹ą½“ą½¦ą¼‹ą½”ą½„ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½šą½¼ą½‘ą¼‹ą½£ą¾Ÿą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "toManySessions": "ą½ą¾±ą½ŗą½‘ą¼‹ą½£ą¼‹ą½ ą½›ą½“ą½£ą¼‹ą½žą½“ą½‚ą½¦ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½‚ą½“ą½¦ą¼‹ą½¦ą¾ą½–ą½¦ą¼‹ą½˜ą½„ą¼‹ą½‘ą¾²ą½‚ą½¦ą¼‹ą½ ą½‘ą½“ą½‚", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF ą½“ą½¦ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½£ą¼", + "header": "PDF ą½“ą½¦ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½£ą¼", + "submit": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½‚ą½…ą½²ą½‚ą¼‹ą½£ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + }, + "pageExtracter": { + "title": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼", + "header": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼", + "submit": "ą½•ą¾±ą½²ą½¢ą¼‹ą½ ą½‘ą½¼ą½“ą¼", + "placeholder": "(ą½‘ą½”ą½ŗą½¢ą¼‹ą½“ą¼ 1,2,8 པང་ན་ 4,7,12-16 པང་ན་ 2n-1)" + }, + "sanitizePDF": { + "title": "PDF ą½‚ą½™ą½„ą¼‹ą½¦ą½ŗą½£ą¼", + "header": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½‚ą½™ą½„ą¼‹ą½¦ą½ŗą½£ą¼", + "selectText": { + "1": "Javascript ą½–ą¾±ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "2": "ą½“ą½„ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "3": "Remove XMP metadata", + "4": "ą½ ą½–ą¾²ą½ŗą½£ą¼‹ą½ą½‚ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "5": "ą½”ą½²ą½‚ą¼‹ą½‚ą½Ÿą½“ą½‚ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "6": "Remove Document Info Metadata" + }, + "submit": "PDF ą½‚ą½™ą½„ą¼‹ą½¦ą½ŗą½£ą¼" + }, + "adjustContrast": { + "title": "ą½ ą½¼ą½‘ą¼‹ą½ą¾±ą½‘ą¼‹ą½¦ą¾™ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚", + "header": "ą½ ą½¼ą½‘ą¼‹ą½ą¾±ą½‘ą¼‹ą½¦ą¾™ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚", + "contrast": "ą½ ą½¼ą½‘ą¼‹ą½ą¾±ą½‘ą¼", + "brightness": "ą½‚ą½¦ą½£ą¼‹ą½šą½‘ą¼", + "saturation": "ą½˜ą½‘ą½¼ą½‚ą¼‹ą½šą½‘ą¼", + "download": "ą½•ą½–ą¼‹ą½£ą½ŗą½“ą¼" + }, + "compress": { + "title": "ą½¦ą¾”ą½“ą½‘ą¼‹ą½¦ą¾’ą¾²ą½²ą½£ą¼", + "header": "PDF ą½¦ą¾”ą½“ą½‘ą¼‹ą½¦ą¾’ą¾²ą½²ą½£ą¼", + "credit": "ą½žą½–ą½¦ą¼‹ą½žą½“ą¼‹ą½ ą½‘ą½²ą½¦ą¼‹ PDF སྔནད་སྒྲིལ་/ą½”ą½¢ą¼‹ą½¢ą¾’ą¾±ą½¦ą¼‹ą½‚ą½ą½¼ą½„ą¼‹ą½–ą½ ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ qpdf ą½–ą½ŗą½‘ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼", + "grayscale": { + "label": "åŗ”ē”Øē°åŗ¦čæ›č”ŒåŽ‹ē¼©" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "Optimisation level:", + "4": "ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½¢ą¾£ą½˜ą¼‹ą½”ą¼ - PDF ą½ą½‚ą¼‹ą½ą½‚ą¼‹ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą½šą½‘ą¼‹ą½£ą¼‹ą½ ą½ą¾²ą½²ą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½¦ą¾¤ą½“ą½¦ą¼‹ą½šą½‘ą¼‹ą½¢ą½„ą¼‹ą½ ą½‚ą½“ą½£ą¼‹ą½‚ą¾±ą½²ą½¦ą¼‹ą½¦ą¾™ą½¼ą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼", + "5": "རེ་བའི་ PDF ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą¼ (ą½‘ą½”ą½ŗą½¢ą¼‹ą½“ą¼ 25MB, 10.8MB, 25KB)" + }, + "submit": "ą½¦ą¾”ą½“ą½‘ą¼‹ą½¦ą¾’ą¾²ą½²ą½£ą¼" + }, + "decrypt": { + "passwordPrompt": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½²ą¼‹ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½‚ą½²ą½¦ą¼‹ą½¦ą¾²ą½“ą½„ą¼‹ą½¦ą¾ą¾±ą½¼ą½–ą¼‹ą½–ą¾±ą½¦ą¼‹ą½”ą½¼ą½‘ą¼ ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "cancelled": "PDF ą½”ą½²ą¼‹ą½–ą¾±ą¼‹ą½–ą¼‹ą½˜ą½šą½˜ą½¦ą¼‹ą½ ą½‡ą½¼ą½‚ą¼‹ą½–ą¾±ą½¦ą¼‹ą½Ÿą½²ą½“ą¼ {0}", + "noPassword": "ą½‚ą½¦ą½„ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½‚ą¾²ą½¼ą½£ą¼‹ą½Ÿą½²ą½“ą¼ {0}", + "invalidPassword": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½ą½‚ą¼‹ą½ą½‚ą¼‹ą½‘ą½„ą¼‹ą½˜ą½‰ą½˜ą¼‹ą½‘ą½“ą¼‹ą½”ą½„ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½šą½¼ą½‘ą¼‹ą½£ą¾Ÿą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "invalidPasswordHeader": "ą½‚ą½¦ą½„ą¼‹ą½šą½²ą½‚ą¼‹ą½“ą½¼ą½¢ą¼‹ą½–ą½ ą½˜ą¼‹ą½¢ą¾’ą¾±ą½–ą¼‹ą½¦ą¾ą¾±ą½¼ą½¢ą¼‹ą½˜ą½²ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą½ ą½²ą¼‹ą½‚ą½¦ą½„ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ PDF ą½”ą½²ą½“ą¼‹ą½”ą¼ {0}", + "unexpectedError": "There was an error processing the file. Please try again.", + "serverError": "Server error while decrypting: {0}", + "success": "ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½‚ą½¦ą½„ą¼‹ą½¦ą¾”ą½¼ą½˜ą¼‹ą½‚ą¾²ą½¼ą½£ą¼‹ą½Ÿą½²ą½“ą¼" + }, + "multiTool-advert": { + "message": "This feature is also available in our multi-tool page. Check it out for enhanced page-by-page UI and additional features!" + }, + "pageRemover": { + "title": "Page Remover", + "header": "PDF Page remover", + "pagesToDelete": "ą½¦ą½“ą½–ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼ (ą½¤ą½¼ą½‚ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½€ą¾±ą½²ą¼‹ą½ą½¼ą¼‹ą½‚ą½žą½“ą½„ą¼‹ą½šą½‚ą¼‹ą½¤ą½‘ą¼‹ą½€ą¾±ą½²ą½¦ą¼‹ą½–ą½…ą½‘ą¼‹ą½“ą½¦ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½”ą¼)", + "submit": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "placeholder": "(ą½‘ą½”ą½ŗą½¢ą¼‹ą½“ą¼ 1,2,6 པང་ན་ 1-10,15-30)" + }, + "imageToPDF": { + "title": "པར་རིས་ནས་ PDF ą½£ą¼", + "header": "པར་རིས་ནས་ PDF ą½£ą¼", + "submit": "ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼", + "selectLabel": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½ ą½šą½˜ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½‚ą½‘ą½˜ą¼‹ą½‚", + "fillPage": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½–ą½€ą½„ą¼‹ą½–ą¼", + "fitDocumentToImage": "ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½‘ą½„ą¼‹ą½ ą½šą½˜ą¼‹ą½”ą½¢ą¼‹ą½–ą½Ÿą½¼ą¼‹ą½–ą¼", + "maintainAspectRatio": "ą½–ą½¦ą¾”ą½“ą½¢ą¼‹ą½šą½‘ą¼‹ą½¢ą¾’ą¾±ą½“ą½“ą¼‹ą½ ą½ą¾±ą½¼ą½„ą½¦ą¼", + "selectText": { + "2": "PDF ą½ ą½ą½¼ą½¢ą¼‹ą½¦ą¾ą¾±ą½¼ą½‘ą¼‹ą½–ą¾±ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼", + "3": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą½ ą½²ą¼‹ą½‚ą½ą½“ą¼‹ą½šą½²ą½‚ą½¦ą¼ (ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½˜ą½„ą¼‹ą½”ą½¼ą¼‹ą½‘ą½„ą¼‹ą½˜ą½‰ą½˜ą¼‹ą½‘ą½“ą¼‹ą½£ą½¦ą¼‹ą½€ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½¦ą¾ą½–ą½¦ą¼‹ą½ą½¼ą¼‹ą½“ą½¢ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½†ą½¼ą½‚)", + "4": "PDF ą½‚ą½…ą½²ą½‚ą¼‹ą½ą½“ą¼‹ą½¦ą¾”ą½ŗą½–ą¼‹ą½¦ą¾¦ą¾±ą½¼ą½¢ą¼", + "5": "PDF ą½¦ą½¼ą¼‹ą½¦ą½¼ą½¢ą¼‹ą½–ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½–ą¼" + } + }, + "PDFToCSV": { + "title": "PDF ནས་ CSV ą½£ą¼", + "header": "PDF ནས་ CSV ą½£ą¼", + "prompt": "Choose page to extract table", + "submit": "Extract" + }, + "split-by-size-or-count": { + "title": "ļæ½ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą½„ą½˜ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½€ą¼‹ą½£ą¾Ÿą½¢ą¼‹ PDF ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "header": "ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą½„ą½˜ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½€ą¼‹ą½£ą¾Ÿą½¢ą¼‹ PDF ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "type": { + "label": "ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼‹ą½¢ą½²ą½‚ą½¦ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "size": "ą½†ą½ŗą¼‹ą½†ą½“ą½„ą¼‹ą½£ą¾Ÿą½¢ą¼", + "pageCount": "ą½¤ą½¼ą½‚ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½£ą¾Ÿą½¢ą¼", + "docCount": "ą½”ą½²ą½‚ą¼‹ą½†ą½ ą½²ą¼‹ą½‚ą¾²ą½„ą½¦ą¼‹ą½€ą¼‹ą½£ą¾Ÿą½¢ą¼" + }, + "value": { + "label": "ą½‚ą¾²ą½„ą½¦ą¼‹ą½ą½„ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½”ą¼", + "placeholder": "ཆེ་ཆནང་ (ą½‘ą½”ą½ŗą½¢ą¼‹ą½“ą¼ 2MB པང་ན་ 3KB) པང་ན་གྲངས་ཀ་ (ą½‘ą½”ą½ŗą½¢ą¼‹ą½“ą¼ 5) ą½ ą½‡ą½“ą½‚ą¼‹ą½”ą¼" + }, + "submit": "ą½•ą½“ą½£ą¼‹ą½–ą¼" + }, + "printFile": { + "title": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½”ą½¢ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼", + "header": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½”ą½¢ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼‹ą½ ą½•ą¾²ą½“ą½£ą¼‹ą½ ą½ą½¼ą½¢ą¼‹ą½£ą¼‹ą½”ą½¢ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼", + "selectText": { + "1": "ą½”ą½¢ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼‹ą½–ą¾±ą¼‹ą½¢ą¾’ą¾±ą½“ą½ ą½²ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½ŗą½˜ą½¦ą¼‹ą½”ą¼", + "2": "ą½”ą½¢ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼‹ą½ ą½•ą¾²ą½“ą½£ą¼‹ą½ ą½ą½¼ą½¢ą¼‹ą½‚ą¾±ą½²ą¼‹ą½˜ą½²ą½„ą¼‹ą½ ą½‡ą½“ą½‚ą¼‹ą½”ą¼" + }, + "submit": "ą½”ą½¢ą¼‹ą½ ą½‘ą½ŗą½–ą½¦ą¼" + }, + "licenses": { + "nav": "ą½†ą½¼ą½‚ą¼‹ą½˜ą½†ą½“ą¼", + "title": "ą½•ą¾±ą½²ą¼‹ą½”ą½²ą¼‹ą½†ą½¼ą½‚ą¼‹ą½˜ą½†ą½“ą¼", + "header": "ą½•ą¾±ą½²ą¼‹ą½”ą½²ą¼‹ą½†ą½¼ą½‚ą¼‹ą½˜ą½†ą½“ą¼", + "module": "ą½¦ą¾”ą½ŗą¼‹ą½šą½“ą¼", + "version": "ą½”ą½¢ą¼‹ą½‚ą½žą½²ą¼", + "license": "ą½†ą½¼ą½‚ą¼‹ą½˜ą½†ą½“ą¼" + }, + "survey": { + "nav": "ą½–ą½¦ą½˜ą¼‹ą½žą½²ą½–ą¼", + "title": "Stirling-PDF ą½–ą½¦ą½˜ą¼‹ą½žą½²ą½–ą¼", + "description": "Stirling-PDF ą½£ą¼‹ą½¢ą¾—ą½ŗą½¦ą¼‹ą½ ą½‘ą½ŗą½‘ą¼‹ą½˜ą½ŗą½‘ą¼‹ą½”ą½¦ą¼ ą½„ą¼‹ą½šą½¼ą½¦ą¼‹ Stirling-PDF ą½”ą½¢ą¼‹ą½¢ą¾’ą¾±ą½¦ą¼‹ą½‚ą½ą½¼ą½„ą¼‹ą½–ą½ ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼‹ą½˜ą½ą½“ą¼‹ą½šą½¼ą½ ą½²ą¼‹ą½–ą½¦ą½˜ą¼‹ą½ ą½†ą½¢ą¼‹ą½‰ą½“ą¼‹ą½ ą½‘ą½¼ą½‘ą¼‹ą½”ą½¼ą½‘ą¼", + "changes": "ą½–ą½¦ą½˜ą¼‹ą½žą½²ą½–ą¼‹ą½¦ą¾”ą¼‹ą½˜ą¼‹ą½“ą½¦ą¼‹ą½–ą½Ÿą½“ą½„ą¼‹ Stirling-PDF ą½£ą¼‹ą½ ą½‚ą¾±ą½“ą½¢ą¼‹ą½–ą¼‹ą½–ą¾±ą½“ą½„ą¼‹ą½”ą½¼ą½‘ą¼ ą½‘ą½ŗą½ ą½²ą¼‹ą½¦ą¾ą½¼ą½¢ą¼‹ą½£ą¼‹ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½˜ą½„ą¼‹ą½–ą¼‹ą½¤ą½ŗą½¦ą¼‹ą½ ą½‘ą½¼ą½‘ą¼‹ą½“ą¼‹ą½„ą¼‹ą½šą½¼ą½ ą½²ą¼‹ą½¢ą¾©ą½¼ą½˜ą¼‹ą½”ą½²ą½‚ą¼‹ą½ ą½‘ą½²ą½¢ą¼‹ą½‚ą½Ÿą½²ą½‚ą½¦ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "changes2": "ą½ ą½‚ą¾±ą½“ą½¢ą¼‹ą½–ą¼‹ą½ ą½‘ą½²ą¼‹ą½‘ą½‚ą¼‹ą½‘ą½„ą¼‹ą½˜ą½‰ą½˜ą¼‹ą½‘ą½“ą¼‹ą½„ą¼‹ą½šą½¼ą½¢ą¼‹ą½šą½¼ą½„ą¼‹ą½‘ą½¼ą½“ą¼‹ą½¢ą¾’ą¾±ą½–ą¼‹ą½¦ą¾ą¾±ą½¼ą½¢ą¼‹ą½‘ą½„ą¼‹ą½˜ą¼‹ą½‘ą½„ą½“ą½£ą¼‹ą½ą½¼ą½–ą¼‹ą½–ą½žą½²ą½“ą¼‹ą½”ą½¼ą½‘ą¼", + "please": "Stirling-PDF ą½”ą½²ą¼‹ą½˜ą¼‹ą½ ą½¼ą½„ą½¦ą¼‹ą½”ą½ ą½²ą¼‹ą½ą½‘ą¼‹ą½£ą¼‹ą½“ą½“ą½¦ą¼‹ą½”ą¼‹ą½ą½¼ą½“ą¼‹ą½”ą½ ą½²ą¼‹ą½†ą½ŗą½‘ą¼‹ą½‘ą½“ą¼‹ą½„ą¼‹ą½šą½¼ą½ ą½²ą¼‹ą½–ą½¦ą½˜ą¼‹ą½žą½²ą½–ą¼‹ą½“ą½„ą¼‹ą½˜ą½‰ą½˜ą¼‹ą½žą½“ą½‚ą½¦ą¼‹ą½‚ą½“ą½„ą¼‹ą½¢ą½¼ą½‚ą½¦ą¼", + "disabled": "(ą½–ą½¦ą½˜ą¼‹ą½žą½²ą½–ą¼‹ą½¦ą¾’ą½ŗą½ ą½“ą¼‹ą½ą½“ą½„ą¼‹ą½¢ą¾—ą½ŗą½¦ą¼‹ą½˜ą½ ą½²ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½¦ą¾’ą¾±ą½“ą½¢ą¼‹ą½“ą½„ą¼‹ą½¦ą¾’ą½¼ą¼‹ą½¢ą¾’ą¾±ą½‚ą¼‹ą½¢ą¾’ą¾±ą½“ą¼‹ą½”ą½²ą½“ą¼‹ą½”ą½„ą¼‹ą½¤ą½¼ą½‚ą¼‹ą½„ą½¼ą½¦ą¼‹ą½˜ą½‡ą½“ą½‚ą¼‹ą½ą½“ą¼‹ą½”ą½¼ą½‘ą¼‹ą½¢ą¾’ą¾±ą½“ą¼‹ą½”ą½²ą½“ą¼)", + "button": "ą½–ą½¦ą½˜ą¼‹ą½žą½²ą½–ą¼‹ą½–ą¾±ą½ŗą½‘ą¼‹ą½”ą¼", + "dontShowAgain": "ą½”ą½„ą¼‹ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½˜ą¼‹ą½¦ą¾Ÿą½¼ą½“ą¼", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "ą½”ļæ½ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "header": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "removeImage": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼", + "submit": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½¦ą½“ą½–ą¼‹ą½”ą¼" + }, + "splitByChapters": { + "title": "ą½£ą½ŗą½ ļæ½ą¼‹ą½£ą¾Ÿą½¢ą¼‹ PDF ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "header": "ą½£ą½ŗą½ ą½“ą¼‹ą½£ą¾Ÿą½¢ą¼‹ PDF ą½ą¼‹ą½‚ą¾±ą½ŗą½¦ą¼", + "bookmarkLevel": "ą½‘ą½”ą½ŗą¼‹ą½¢ą¾Ÿą½‚ą½¦ą¼‹ą½¢ą½²ą½˜ą¼‹ą½”ą¼", + "includeMetadata": "ą½‚ą½“ą½¦ą¼‹ą½šą½“ą½£ą¼‹ą½žą½²ą½–ą¼‹ą½•ą¾²ą¼‹ą½šą½“ą½‘ą¼‹ą½”ą¼", + "allowDuplicates": "ą½–ą½¦ą¾ą¾±ą½¢ą¼‹ą½Ÿą¾³ą½¼ą½¦ą¼‹ą½†ą½¼ą½‚ą¼‹ą½”ą¼", + "desc": { + "1": "This tool splits a PDF file into multiple PDFs based on its chapter structure.", + "2": "Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).", + "3": "Include Metadata: If checked, the original PDF metadata will be included in each split PDF.", + "4": "Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs." + }, + "submit": "Split PDF" + }, + "fileChooser": { + "click": "ą½¦ą¾¤ą¾±ą½¼ą½‘ą¼", + "or": "ą½”ą½„ą¼‹ą½“ą¼", + "dragAndDrop": "ą½ ą½ą½ŗą½“ą¼‹ą½“ą½¦ą¼‹ą½ ą½‡ą½¼ą½‚ą¼‹ą½”ą¼", + "dragAndDropPDF": "PDF ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½ą½ŗą½“ą¼‹ą½“ą½¦ą¼‹ą½ ą½‡ą½¼ą½‚ą¼‹ą½”ą¼", + "dragAndDropImage": "ą½”ą½¢ą¼‹ą½¢ą½²ą½¦ą¼‹ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½ą½ŗą½“ą¼‹ą½“ą½¦ą¼‹ą½ ą½‡ą½¼ą½‚ą¼‹ą½”ą¼", + "hoveredDragAndDrop": "ą½”ą½²ą½‚ą¼‹ą½†ą¼‹ą½ ą½‘ą½²ą½¢ą¼‹ą½ ą½ą½ŗą½“ą¼‹ą½“ą½¦ą¼‹ą½ ą½‡ą½¼ą½‚ą¼‹ą½”ą¼", + "extractPDF": "ą½ ą½‘ą½¼ą½“ą¼‹ą½¢ą½²ą½¦ą¼‹ą½ ą½‚ą¾±ą½“ą½¢ą¼‹ą½–ą½ ą½²ą¼‹ą½¦ą¾’ą¾²ą½²ą½‚ą¼‹ą½–ą½ą½„ą¼‹ą½–ą¼" + }, + "releases": { + "footer": "ą½”ą½¢ą¼‹ą½‚ą½žą½²ą¼", + "title": "ą½”ą½¢ą¼‹ą½‚ą½žą½²ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą½ ą½²ą¼‹ą½‚ą½¦ą½£ą¼‹ą½–ą½¦ą¾’ą¾²ą½‚ą½¦ą¼", + "header": "ą½”ą½¢ą¼‹ą½‚ą½žą½²ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą½ ą½²ą¼‹ą½‚ą½¦ą½£ą¼‹ą½–ą½¦ą¾’ą¾²ą½‚ą½¦ą¼", + "current": { + "version": "ą½˜ą½²ą½‚ą¼‹ą½¦ą¾”ą½ ą½²ą¼‹ą½”ą½¢ą¼‹ą½‚ą½žą½²ą¼" + }, + "note": "ą½”ą½¢ą¼‹ą½‚ą½žą½²ą¼‹ą½‚ą½¦ą½¢ą¼‹ą½”ą½ ą½²ą¼‹ą½‚ą½¦ą½£ą¼‹ą½–ą½¦ą¾’ą¾²ą½‚ą½¦ą¼‹ą½‘ą½–ą¾±ą½²ą½“ą¼‹ą½”ą½²ą½‚ą¼‹ą½ą½¼ą¼‹ą½“ą½¢ą¼‹ą½”ą½¼ą½‘ą¼" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/zh-CN/translation.json b/frontend/public/locales/zh-CN/translation.json new file mode 100644 index 000000000..eeecb643a --- /dev/null +++ b/frontend/public/locales/zh-CN/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "字体大小", + "fontName": "å­—ä½“åē§°", + "title": "添加锵码", + "header": "添加锵码", + "selectText": { + "1": "选ꋩPDFę–‡ä»¶ļ¼š", + "2": "č¾¹č·å¤§å°", + "3": "ä½ē½®", + "4": "起始锵码", + "5": "ę·»åŠ é”µē ēš„é”µę•°", + "6": "č‡Ŗå®šä¹‰ę–‡ęœ¬" + }, + "customTextDesc": "č‡Ŗå®šä¹‰ę–‡ęœ¬", + "numberPagesDesc": "č¦ę·»åŠ é”µē ēš„é”µę•°ļ¼Œé»˜č®¤äøŗā€œę‰€ęœ‰ā€ļ¼Œä¹ŸåÆä»„ęŽ„å—1-5ꈖ2,5,9ē­‰", + "customNumberDesc": "默认为 {n}ļ¼Œä¹ŸåÆä»„ęŽ„å—ā€œē¬¬ {n} 锵/共 {total} é”µā€ļ¼Œā€œę–‡ęœ¬-{n}ā€ļ¼Œā€œ{filename}-{n}ā€", + "submit": "添加锵码" + }, + "pdfPrompt": "选ꋩ PDF", + "multiPdfPrompt": "é€‰ę‹©å¤šäøŖ PDF(2äøŖęˆ–ę›“å¤šļ¼‰", + "multiPdfDropPrompt": "é€‰ę‹©ļ¼ˆęˆ–ę‹–ę‹½ļ¼‰ę‰€éœ€ēš„ PDF", + "imgPrompt": "é€‰ę‹©å›¾åƒ", + "genericSubmit": "ęäŗ¤", + "uploadLimit": "Maximum file size:", + "uploadLimitExceededSingular": "is too large. Maximum allowed size is", + "uploadLimitExceededPlural": "are too large. Maximum allowed size is", + "processTimeWarning": "č­¦å‘Šļ¼šę­¤čæ‡ēØ‹åÆčƒ½éœ€č¦å¤šč¾¾äø€åˆ†é’Ÿļ¼Œå…·ä½“ę—¶é—“å–å†³äŗŽę–‡ä»¶å¤§å°", + "pageOrderPrompt": "é”µé¢é”ŗåŗļ¼ˆč¾“å…„é€—å·åˆ†éš”ēš„é”µē åˆ—č”Øęˆ–å‡½ę•°ļ¼‰ļ¼š", + "pageSelectionPrompt": "č‡Ŗå®šä¹‰é”µé¢é€‰ę‹©ļ¼ˆč¾“å…„ä»„é€—å·åˆ†éš”ēš„é”µē åˆ—č”Øęˆ–å‡½ę•°ļ¼š1,5,6态2n+1ļ¼‰ļ¼š", + "goToPage": "到", + "true": "对", + "false": "错", + "unknown": "未矄", + "save": "äæå­˜", + "saveToBrowser": "äæå­˜åˆ°ęµč§ˆå™Ø", + "close": "关闭", + "filesSelected": "é€‰äø­ēš„ę–‡ä»¶", + "noFavourites": "ę²”ęœ‰ę·»åŠ ę”¶č—å¤¹", + "downloadComplete": "äø‹č½½å®Œęˆ", + "bored": "ē­‰å¾…ę—¶č§‰å¾—ę— čŠļ¼Ÿ", + "alphabet": "å­—ęÆč”Ø", + "downloadPdf": "äø‹č½½ PDF", + "text": "ę–‡ęœ¬", + "font": "字体", + "selectFillter": "-- 选ꋩ--", + "pageNum": "锵码", + "sizes": { + "small": "å°åž‹å°ŗåÆø", + "medium": "äø­åž‹å°ŗåÆø", + "large": "å¤§åž‹å°ŗåÆø", + "x-large": "č¶…å¤§åž‹å°ŗåÆø" + }, + "error": { + "pdfPassword": "PDFę–‡ę”£ęœ‰åÆ†ē ļ¼ŒęœŖęä¾›åÆ†ē ęˆ–åÆ†ē äøę­£ē”®", + "_value": "错误", + "sorry": "åÆ¹ę­¤é—®é¢˜ę„Ÿåˆ°ęŠ±ę­‰ļ¼", + "needHelp": "éœ€č¦åø®åŠ© / å‘ēŽ°é—®é¢˜ļ¼Ÿ", + "contactTip": "å¦‚ęžœä½ ä»ē„¶é‡åˆ°é—®é¢˜ļ¼Œäøč¦ēŠ¹č±«ļ¼Œå‘ęˆ‘ä»¬åÆ»ę±‚åø®åŠ©ć€‚ä½ åÆä»„åœØęˆ‘ä»¬ēš„ GitHub é”µé¢äøŠęäŗ¤å·„å•ļ¼Œęˆ–č€…é€ščæ‡ Discord äøŽęˆ‘ä»¬č”ē³»ļ¼š", + "404": { + "head": "404 - é”µé¢ęœŖę‰¾åˆ° | å“Žå‘€ļ¼Œęˆ‘ä»¬åœØä»£ē äø­č§¦å‘äŗ†é”™čÆÆļ¼", + "1": "ęˆ‘ä»¬ä¼¼ä¹Žę‰¾äøåˆ°ä½ åÆ»ę‰¾ēš„é”µé¢ć€‚", + "2": "å‡ŗäŗ†äŗ›é—®é¢˜" + }, + "github": "在 GitHub äøŠęäŗ¤å·„å•", + "showStack": "ę˜¾ē¤ŗå †ę ˆč·ŸčøŖ", + "copyStack": "å¤åˆ¶å †ę ˆč·ŸčøŖ", + "githubSubmit": "GitHub - ęäŗ¤å·„å•", + "discordSubmit": "Discord - ęäŗ¤ę”ÆęŒåø–å­" + }, + "delete": "删除", + "username": "ē”Øęˆ·å", + "password": "密码", + "welcome": "ę¬¢čæŽ", + "property": "资产", + "black": "黑色", + "white": "白色", + "red": "红色", + "green": "绿色", + "blue": "č“č‰²", + "custom": "č‡Ŗå®šä¹‰...", + "WorkInProgess": "å·„ä½œę­£åœØčæ›č”Œäø­ļ¼ŒåÆčƒ½ę— ę³•å·„ä½œęˆ–ęœ‰é”™čÆÆļ¼ŒčÆ·ęŠ„å‘Šä»»ä½•é—®é¢˜ļ¼", + "poweredBy": "ęœåŠ”ę„ęŗļ¼š", + "yes": "是", + "no": "否", + "changedCredsMessage": "凭证已曓改!", + "notAuthenticatedMessage": "ē”Øęˆ·ęœŖē»čæ‡čŗ«ä»½éŖŒčÆć€‚", + "userNotFoundMessage": "ęœŖę‰¾åˆ°ē”Øęˆ·ć€‚", + "incorrectPasswordMessage": "å½“å‰åÆ†ē äøę­£ē”®ć€‚", + "usernameExistsMessage": "ę–°ē”Øęˆ·åå·²å­˜åœØć€‚", + "invalidUsernameMessage": "ē”Øęˆ·åę— ę•ˆļ¼Œē”Øęˆ·ååŖčƒ½åŒ…å«å­—ęÆć€ę•°å­—å’Œä»„äø‹ē‰¹ę®Šå­—ē¬¦@._+- ęˆ–åæ…é”»ę˜Æęœ‰ę•ˆēš„ē”µå­é‚®ä»¶åœ°å€ć€‚", + "invalidPasswordMessage": "åÆ†ē äøčƒ½äøŗē©ŗäø”å¼€å¤“å’Œē»“å°¾äøčƒ½ęœ‰ē©ŗę ¼ć€‚", + "confirmPasswordErrorMessage": "äø¤ę¬”åÆ†ē äøäø€č‡“ć€‚", + "deleteCurrentUserMessage": "ę— ę³•åˆ é™¤å½“å‰ē™»å½•ēš„ē”Øęˆ·ć€‚", + "deleteUsernameExistsMessage": "ē”Øęˆ·åäøå­˜åœØļ¼Œę— ę³•åˆ é™¤ć€‚", + "downgradeCurrentUserMessage": "ę— ę³•é™ēŗ§å½“å‰ē”Øęˆ·ēš„č§’č‰²", + "disabledCurrentUserMessage": "ę— ę³•ē¦ē”Øå½“å‰ē”Øęˆ·ć€‚", + "downgradeCurrentUserLongMessage": "ę— ę³•é™ēŗ§å½“å‰ē”Øęˆ·ēš„č§’č‰²ć€‚å› ę­¤ļ¼Œå½“å‰ē”Øęˆ·å°†äøä¼šę˜¾ē¤ŗć€‚", + "userAlreadyExistsOAuthMessage": "čÆ„ē”Øęˆ·å·²ä½œäøŗ OAuth2 ē”Øęˆ·å­˜åœØć€‚", + "userAlreadyExistsWebMessage": "čÆ„ē”Øęˆ·å·²ä½œäøŗ Web ē”Øęˆ·å­˜åœØć€‚", + "oops": "å“Žå‘€ļ¼", + "help": "帮助", + "goHomepage": "čæ”å›žäø»é”µ", + "joinDiscord": "åŠ å…„ęˆ‘ä»¬ēš„ Discord ęœåŠ”å™Ø", + "seeDockerHub": "ęŸ„ēœ‹ Docker Hub", + "visitGithub": "访问 Github 仓库", + "donate": "ęę¬¾", + "color": "é¢œč‰²", + "sponsor": "čµžåŠ©", + "info": "俔息", + "pro": "äø“äøšē‰ˆ", + "page": "锵面", + "pages": "锵码", + "loading": "加载中...", + "addToDoc": "ę·»åŠ č‡³ę–‡ä»¶", + "reset": "é‡ē½®", + "apply": "应用", + "noFileSelected": "No file selected. Please upload one.", + "legal": { + "privacy": "éšē§ę”æē­–", + "terms": "ęœåŠ”ę”ę¬¾", + "accessibility": "ę— éšœē¢", + "cookie": "Cookie 政策", + "impressum": "Impressum", + "showCookieBanner": "Cookie Preferences" + }, + "pipeline": { + "header": "ęµę°“ēŗæčœå•ļ¼ˆBeta)", + "uploadButton": "äøŠä¼ č‡Ŗå®šä¹‰ęµę°“ēŗæ", + "configureButton": "é…ē½®", + "defaultOption": "č‡Ŗå®šä¹‰", + "submitButton": "ęäŗ¤", + "help": "巄作流帮助", + "scanHelp": "ę–‡ä»¶å¤¹ę‰«ęåø®åŠ©", + "deletePrompt": "ē”®č®¤åˆ é™¤čÆ„å·„ä½œęµļ¼Ÿ", + "tags": "č‡ŖåŠØåŒ–ć€é”ŗåŗć€č„šęœ¬åŒ–ć€ę‰¹å¤„ē†", + "title": "流氓线" + }, + "pipelineOptions": { + "header": "ęµę°“ēŗæé…ē½®", + "pipelineNameLabel": "ęµę°“ēŗæåē§°", + "saveSettings": "äæå­˜č®¾ē½®", + "pipelineNamePrompt": "čÆ·č¾“å…„ęµę°“ēŗæåē§°", + "selectOperation": "é€‰ę‹©ę“ä½œ", + "addOperationButton": "ę·»åŠ ę“ä½œ", + "pipelineHeader": "流氓线:", + "saveButton": "äø‹č½½", + "validateButton": "验证" + }, + "enterpriseEdition": { + "button": "å‡ēŗ§åˆ° Pro ē‰ˆęœ¬", + "warning": "ę­¤åŠŸčƒ½ä»…é€‚ē”ØäŗŽ Pro ē‰ˆęœ¬", + "yamlAdvert": "Stirling PDF Proę”ÆęŒYAMLé…ē½®ę–‡ä»¶å’Œå…¶ä»–SSOåŠŸčƒ½ć€‚", + "ssoAdvert": "åÆ»ę‰¾ę›“å¤šēš„ē”Øęˆ·ē®”ē†åŠŸčƒ½ļ¼ŸęŸ„ēœ‹Stirling PDF Pro" + }, + "analytics": { + "title": "ä½ ęƒ³ååŠ©ę”¹å–„Stirling PDF吗", + "paragraph1": "Stirling PDFęœ‰é€‰ę‹©ę€§åˆ†ęžåŠŸčƒ½ļ¼ŒåÆä»„åø®åŠ©ęˆ‘ä»¬ę”¹čæ›äŗ§å“ć€‚ęˆ‘ä»¬äøč·ŸčøŖä»»ä½•äøŖäŗŗäæ”ęÆęˆ–ę–‡ä»¶å†…å®¹ć€‚", + "paragraph2": "čÆ·č€ƒč™‘åÆē”Øåˆ†ęžę„åø®åŠ©Stirling-PDFēš„å‘å±•ļ¼Œå¹¶č®©ęˆ‘ä»¬ę›“å„½åœ°äŗ†č§£ęˆ‘ä»¬ēš„ē”Øęˆ·ć€‚", + "enable": "åÆē”Øåˆ†ęžåŠŸčƒ½", + "disable": "ē¦ē”Øåˆ†ęžåŠŸčƒ½", + "settings": "ę‚ØåÆä»„åœØ config/settings.yml ę–‡ä»¶äø­å˜ę›“åˆ†ęžåŠŸčƒ½ēš„č®¾å®š" + }, + "navbar": { + "favorite": "ę”¶č—", + "recent": "ę–°åŠŸčƒ½å’Œęœ€čæ‘ę›“ę–°", + "darkmode": "ęš—é»‘ęØ”å¼", + "language": "语言", + "settings": "设置", + "allTools": "å·„å…·ē®±", + "multiTool": "å¤šåŠŸčƒ½å·„å…·", + "search": "搜瓢", + "sections": { + "organize": "组织", + "convertTo": "č½¬ę¢ęˆPDF", + "convertFrom": "从PDFč½¬ę¢", + "security": "ē­¾åå’Œå®‰å…Ø", + "advance": "高级功能", + "edit": "ęŸ„ēœ‹å’Œē¼–č¾‘", + "popular": "ēƒ­é—Ø" + } + }, + "settings": { + "title": "设置", + "update": "ęœ‰åÆē”Øēš„ę›“ę–°", + "updateAvailable": "å½“å‰ē‰ˆęœ¬äøŗ {0}ļ¼Œę–°ē‰ˆęœ¬ ({1}) åÆē”Øć€‚", + "appVersion": "åŗ”ē”ØēØ‹åŗē‰ˆęœ¬ļ¼š", + "downloadOption": { + "title": "é€‰ę‹©äø‹č½½é€‰é”¹ļ¼ˆå•äøŖę–‡ä»¶éžåŽ‹ē¼©ę–‡ä»¶ļ¼‰ļ¼š", + "1": "åœØåŒäø€ēŖ—å£ę‰“å¼€", + "2": "åœØę–°ēŖ—å£äø­ę‰“å¼€", + "3": "下载文件" + }, + "zipThreshold": "å½“äø‹č½½ēš„ę–‡ä»¶ę•°é‡č¶…čæ‡é™åˆ¶ę—¶ļ¼Œå°†ę–‡ä»¶åŽ‹ē¼©ć€‚", + "signOut": "登出", + "accountSettings": "č“¦å·č®¾å®š", + "bored": { + "help": "åÆē”Øå½©č›‹ęøøęˆ" + }, + "cacheInputs": { + "name": "äæå­˜č”Øå•č¾“å…„", + "help": "äæå­˜å…ˆå‰č¾“å…„ä»„ä¾›ę—„åŽä½æē”Ø" + } + }, + "changeCreds": { + "title": "曓改凭证", + "header": "ę›“ę–°ę‚Øēš„č“¦ęˆ·čÆ¦ęƒ…", + "changePassword": "ę‚Øę­£åœØä½æē”Øé»˜č®¤ē™»å½•å‡­čÆļ¼ŒčÆ·č¾“å…„ę–°åÆ†ē ", + "newUsername": "ę–°ē”Øęˆ·å", + "oldPassword": "å½“å‰åÆ†ē ", + "newPassword": "新密码", + "confirmNewPassword": "甮认新密码", + "submit": "ęäŗ¤ę›“ę”¹" + }, + "account": { + "title": "č“¦å·č®¾å®š", + "accountSettings": "č“¦å·č®¾å®š", + "adminSettings": "ē®”ē†å‘˜č®¾ē½® - ęŸ„ēœ‹å’Œę·»åŠ ē”Øęˆ·", + "userControlSettings": "ē”Øęˆ·ęŽ§åˆ¶č®¾ē½®", + "changeUsername": "ę›“ę”¹ē”Øęˆ·å", + "newUsername": "ę–°ē”Øęˆ·å", + "password": "甮认密码", + "oldPassword": "旧密码", + "newPassword": "新密码", + "changePassword": "曓改密码", + "confirmNewPassword": "甮认新密码", + "signOut": "退出登录", + "yourApiKey": "ę‚Øēš„ API 密钄", + "syncTitle": "å°†ęµč§ˆå™Øč®¾ē½®äøŽč“¦ęˆ·åŒę­„", + "settingsCompare": "č®¾ē½®ęÆ”č¾ƒļ¼š", + "property": "å±žę€§", + "webBrowserSettings": "Web ęµč§ˆå™Øč®¾ē½®", + "syncToBrowser": "同歄蓦户 -> ęµč§ˆå™Ø", + "syncToAccount": "同歄蓦户 <- ęµč§ˆå™Ø" + }, + "adminUserSettings": { + "title": "ē”Øęˆ·ęŽ§åˆ¶č®¾ē½®", + "header": "ē®”ē†å‘˜ē”Øęˆ·ęŽ§åˆ¶č®¾ē½®", + "admin": "ē®”ē†å‘˜", + "user": "ē”Øęˆ·", + "addUser": "ę·»åŠ ę–°ē”Øęˆ·", + "deleteUser": "åˆ é™¤ē”Øęˆ·", + "confirmDeleteUser": "ē”®č®¤åˆ é™¤čÆ„ē”Øęˆ·ļ¼Ÿ", + "confirmChangeUserStatus": "ę˜Æå¦åŗ”ē¦ē”Ø/åÆē”ØčÆ„ē”Øęˆ·ļ¼Ÿ", + "usernameInfo": "ē”Øęˆ·ååŖčƒ½åŒ…å«å­—ęÆć€ę•°å­—å’Œä»„äø‹ē‰¹ę®Šå­—ē¬¦@._+-ļ¼Œęˆ–č€…åæ…é”»ę˜Æęœ‰ę•ˆēš„ē”µå­é‚®ä»¶åœ°å€ć€‚", + "roles": "角色", + "role": "角色", + "actions": "ę“ä½œ", + "apiUser": "å—é™åˆ¶ēš„ API ē”Øęˆ·", + "extraApiUser": "é¢å¤–å—é™åˆ¶ēš„ API ē”Øęˆ·", + "webOnlyUser": "仅限 Web ē”Øęˆ·", + "demoUser": "ę¼”ē¤ŗē”Øęˆ·(ę— č‡Ŗå®šä¹‰č®¾ē½®)", + "internalApiUser": "å†…éƒØ API ē”Øęˆ·", + "forceChange": "å¼ŗåˆ¶ē”Øęˆ·åœØē™»å½•ę—¶ę›“ę”¹ē”Øęˆ·å/密码", + "submit": "äæå­˜ē”Øęˆ·", + "changeUserRole": "ę›“ę”¹ē”Øęˆ·č§’č‰²", + "authenticated": "已验证", + "editOwnProfil": "编辑个人资料", + "enabledUser": "åÆē”Øē”Øęˆ·", + "disabledUser": "ē¦ē”Øē”Øęˆ·", + "activeUsers": "ęæ€ę“»ē”Øęˆ·:", + "disabledUsers": "ē¦ē”Øē”Øęˆ·:", + "totalUsers": "ę€»ē”Øęˆ·:", + "lastRequest": "ęœ€åŽē™»å½•", + "usage": "View Usage" + }, + "endpointStatistics": { + "title": "Endpoint Statistics", + "header": "Endpoint Statistics", + "top10": "Top 10", + "top20": "Top 20", + "all": "All", + "refresh": "Refresh", + "includeHomepage": "Include Homepage ('/')", + "includeLoginPage": "Include Login Page ('/login')", + "totalEndpoints": "Total Endpoints", + "totalVisits": "Total Visits", + "showing": "Showing", + "selectedVisits": "Selected Visits", + "endpoint": "Endpoint", + "visits": "Visits", + "percentage": "Percentage", + "loading": "Loading...", + "failedToLoad": "Failed to load endpoint data. Please try refreshing.", + "home": "Home", + "login": "Login", + "top": "Top", + "numberOfVisits": "Number of Visits", + "visitsTooltip": "Visits: {0} ({1}% of total)", + "retry": "Retry" + }, + "database": { + "title": "ę•°ę®åŗ“ 导兄/导出", + "header": "ę•°ę®åŗ“ 导兄/导出", + "fileName": "ę–‡ä»¶å", + "creationDate": "åˆ›å»ŗę—¶é—“", + "fileSize": "ę–‡ä»¶å¤§å°", + "deleteBackupFile": "åˆ é™¤å¤‡ä»½ę–‡ä»¶", + "importBackupFile": "导兄备份文件", + "createBackupFile": "åˆ›å»ŗå¤‡ä»½ę–‡ä»¶", + "downloadBackupFile": "下载备份文件", + "info_1": "åÆ¼å…„ę•°ę®ę—¶ļ¼Œē”®äæē»“ęž„ę­£ē”®č‡³å…³é‡č¦ć€‚å¦‚ęžœę‚Øäøē”®å®šč‡Ŗå·±åœØåšä»€ä¹ˆļ¼ŒčÆ·åÆ»ę±‚äø“äøšäŗŗå£«ēš„å»ŗč®®å’Œę”ÆęŒć€‚ē»“ęž„é”™čÆÆä¼šåÆ¼č‡“åŗ”ē”ØēØ‹åŗę•…éšœļ¼Œē”šč‡³å®Œå…Øę— ę³•čæč”Œåŗ”ē”ØēØ‹åŗć€‚", + "info_2": "äøŠä¼ ę–‡ä»¶ę—¶ļ¼Œę–‡ä»¶åå¹¶äøé‡č¦ć€‚äøŠä¼ åŽļ¼Œę–‡ä»¶åå°†é‡å‘½åäøŗ backup_user_yyyyMMddHHmm.sqlļ¼Œä»„ē”®äæå‘½åč§„čŒƒēš„äø€č‡“ę€§ć€‚", + "submit": "导兄备份", + "importIntoDatabaseSuccessed": "åÆ¼å…„ę•°ę®åŗ“ęˆåŠŸ", + "backupCreated": "ę•°ę®åŗ“å¤‡ä»½ęˆåŠŸ", + "fileNotFound": "ęœŖę‰¾åˆ°ę–‡ä»¶", + "fileNullOrEmpty": "ę–‡ä»¶äøčƒ½äøŗē©ŗ", + "failedImportFile": "导兄文件失蓄", + "notSupported": "ę­¤åŠŸčƒ½äøé€‚ē”ØäŗŽę‚Øēš„ę•°ę®åŗ“čæžęŽ„ć€‚" + }, + "session": { + "expired": "ę‚Øēš„ä¼ščÆå·²čæ‡ęœŸć€‚čÆ·åˆ·ę–°é”µé¢å¹¶é‡čÆ•ć€‚", + "refreshPage": "åˆ·ę–°é”µé¢" + }, + "home": { + "desc": "ęœ¬åœ°éƒØē½²ēš„äø€ē«™å¼ęœåŠ”ļ¼Œę»”č¶³ę‚Øēš„ę‰€ęœ‰ PDF éœ€ę±‚ć€‚", + "searchBar": "ęœē“¢ę‚Øéœ€č¦ēš„åŠŸčƒ½...", + "viewPdf": { + "title": "View/Edit PDF", + "desc": "ęµč§ˆć€ę³Øé‡Šć€ę·»åŠ ę–‡ęœ¬ęˆ–å›¾åƒ" + }, + "setFavorites": "ē¼–č¾‘ę”¶č—å¤¹", + "hideFavorites": "éšč—ę”¶č—å¤¹", + "showFavorites": "ę˜¾ē¤ŗę”¶č—å¤¹", + "legacyHomepage": "ä½æē”Øę—§ē‰ˆäø»é”µ", + "newHomePage": "čÆ•ē”Øę–°ē‰ˆäø»é”µ!", + "alphabetical": "ęŒ‰å­—ęÆé”ŗåŗ", + "globalPopularity": "ęŒ‰å…Øēƒēƒ­åŗ¦", + "sortBy": "ęŽ’åŗ:", + "multiTool": { + "title": "PDF å¤šåŠŸčƒ½å·„å…·", + "desc": "åˆå¹¶ć€ę—‹č½¬ć€é‡ę–°ęŽ’åˆ—å’Œåˆ é™¤ PDF 锵面" + }, + "merge": { + "title": "合并", + "desc": "č½»ę¾å°†å¤šäøŖ PDF åˆå¹¶ęˆäø€äøŖć€‚" + }, + "split": { + "title": "ę‹†åˆ†", + "desc": "将 PDF ę‹†åˆ†äøŗå¤šäøŖę–‡ę”£ć€‚" + }, + "rotate": { + "title": "旋转", + "desc": "旋转 PDF怂" + }, + "imageToPdf": { + "title": "č½¬ę¢å›¾åƒåˆ° PDF", + "desc": "å°†å›¾åƒļ¼ˆPNG态JPEG态GIFļ¼‰č½¬ę¢äøŗ PDF怂" + }, + "pdfToImage": { + "title": "č½¬ę¢ PDF 到图像", + "desc": "将 PDF č½¬ę¢äøŗå›¾åƒļ¼ˆPNG态JPEG态GIF)。" + }, + "pdfOrganiser": { + "title": "敓理", + "desc": "ęŒ‰ä»»ę„é”ŗåŗåˆ é™¤/é‡ę–°ęŽ’åˆ—é”µé¢ć€‚" + }, + "addImage": { + "title": "在 PDF äø­ę·»åŠ å›¾ē‰‡", + "desc": "å°†å›¾åƒę·»åŠ åˆ° PDF ēš„ęŒ‡å®šä½ē½®ć€‚" + }, + "watermark": { + "title": "ę·»åŠ ę°“å°", + "desc": "在 PDF äø­ę·»åŠ č‡Ŗå®šä¹‰ę°“å°ć€‚" + }, + "permissions": { + "title": "ę›“ę”¹ęƒé™", + "desc": "曓改 PDF ę–‡ę”£ēš„ęƒé™ć€‚" + }, + "removePages": { + "title": "删除", + "desc": "从 PDF ę–‡ę”£äø­åˆ é™¤äøéœ€č¦ēš„é”µé¢ć€‚" + }, + "addPassword": { + "title": "ę·»åŠ åÆ†ē ", + "desc": "使用密码对 PDF ę–‡ę”£čæ›č”ŒåŠ åÆ†ć€‚" + }, + "removePassword": { + "title": "åˆ é™¤åÆ†ē ", + "desc": "从 PDF ę–‡ę”£äø­ē§»é™¤åÆ†ē äæęŠ¤ć€‚" + }, + "compressPdfs": { + "title": "åŽ‹ē¼©", + "desc": "åŽ‹ē¼© PDF ę–‡ä»¶ä»„å‡å°ę–‡ä»¶å¤§å°ć€‚" + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "ę›“ę”¹å…ƒę•°ę®", + "desc": "曓改/删除/添加 PDF ę–‡ę”£ēš„å…ƒę•°ę®ć€‚" + }, + "fileToPDF": { + "title": "å°†ę–‡ä»¶č½¬ę¢äøŗ PDF ꖇ件", + "desc": "å°†å‡ ä¹Žę‰€ęœ‰ę–‡ä»¶č½¬ę¢äøŗ PDF (DOCX态PNG态XLS态PPT态TXT等)。" + }, + "ocr": { + "title": "运蔌 OCR /ęø…ē†ę‰«ę", + "desc": "ęø…ē†å’ŒčÆ†åˆ« PDF äø­ēš„å›¾åƒę–‡ęœ¬ļ¼Œå¹¶å°†å…¶č½¬ę¢äøŗåÆē¼–č¾‘ę–‡ęœ¬ć€‚" + }, + "extractImages": { + "title": "ęå–å›¾åƒ", + "desc": "从 PDF äø­ęå–ę‰€ęœ‰å›¾åƒå¹¶äæå­˜åˆ°åŽ‹ē¼©åŒ…äø­ć€‚" + }, + "pdfToPDFA": { + "title": "PDF 转 PDF/A", + "desc": "将 PDF č½¬ę¢äøŗ PDF/A ä»„čæ›č”Œé•æęœŸäæå­˜ć€‚" + }, + "PDFToWord": { + "title": "PDF 转 Word", + "desc": "将PDFč½¬ę¢äøŗWordę ¼å¼ļ¼ˆDOC态DOCX和ODT)。" + }, + "PDFToPresentation": { + "title": "PDF 转演示文稿", + "desc": "将 PDF č½¬ę¢äøŗę¼”ē¤ŗę–‡ēØæę ¼å¼ļ¼ˆPPT态PPTX 和 ODP)。" + }, + "PDFToText": { + "title": "PDF 转 RTFļ¼ˆę–‡ęœ¬ļ¼‰", + "desc": "将PDFč½¬ę¢äøŗę–‡ęœ¬ęˆ– RTF ę ¼å¼ć€‚" + }, + "PDFToHTML": { + "title": "PDF 转 HTML", + "desc": "将 PDF č½¬ę¢äøŗ HTML ę ¼å¼ć€‚" + }, + "PDFToXML": { + "title": "PDF 转 XML", + "desc": "将 PDF č½¬ę¢äøŗ XML ę ¼å¼ć€‚" + }, + "ScannerImageSplit": { + "title": "检测/åˆ†å‰²ę‰«ęå›¾åƒ", + "desc": "ä»Žäø€å¼ ē…§ē‰‡ęˆ– PDF äø­åˆ†å‰²å‡ŗå¤šå¼ ē…§ē‰‡ć€‚" + }, + "sign": { + "title": "ē­¾å", + "desc": "é€ščæ‡ē»˜å›¾ć€ę–‡å­—ęˆ–å›¾åƒå‘ PDF ę·»åŠ ē­¾å" + }, + "flatten": { + "title": "展平", + "desc": "从 PDF äø­åˆ é™¤ę‰€ęœ‰äŗ’åŠØå…ƒē“ å’Œč”Øå•" + }, + "repair": { + "title": "äæ®å¤", + "desc": "å°čÆ•äæ®å¤ęŸå/ęŸåēš„ PDF" + }, + "removeBlanks": { + "title": "åˆ é™¤ē©ŗē™½é”µ", + "desc": "ę£€ęµ‹å¹¶åˆ é™¤ę–‡ę”£äø­ēš„ē©ŗē™½é”µ" + }, + "removeAnnotations": { + "title": "åˆ é™¤ę ‡ę³Ø", + "desc": "删除 PDF äø­ēš„ę‰€ęœ‰ę ‡ę³Ø/评论" + }, + "compare": { + "title": "ęÆ”č¾ƒ", + "desc": "ęÆ”č¾ƒå¹¶ę˜¾ē¤ŗäø¤äøŖ PDF ę–‡ę”£ä¹‹é—“ēš„å·®å¼‚" + }, + "certSign": { + "title": "ä½æē”ØčÆä¹¦ē­¾å", + "desc": "使用证书/åÆ†é’„ļ¼ˆPEM/P12)对PDFčæ›č”Œē­¾å" + }, + "removeCertSign": { + "title": "ē§»é™¤čÆä¹¦ē­¾å", + "desc": "移除 PDF ēš„čÆä¹¦ē­¾å" + }, + "pageLayout": { + "title": "å¤šé”µåøƒå±€", + "desc": "将 PDF ę–‡ę”£ēš„å¤šäøŖé”µé¢åˆå¹¶ęˆäø€é”µ" + }, + "scalePages": { + "title": "č°ƒę•“é”µé¢å°ŗåÆø/缩放", + "desc": "č°ƒę•“é”µé¢åŠ/ęˆ–å…¶å†…å®¹ēš„å°ŗåÆø/缩放" + }, + "pipeline": { + "title": "ęµę°“ēŗæļ¼ˆé«˜ēŗ§ē‰ˆļ¼‰", + "desc": "é€ščæ‡å®šä¹‰ęµę°“ēŗæč„šęœ¬åœØ PDF äøŠčæč”Œå¤šäøŖę“ä½œ" + }, + "add-page-numbers": { + "title": "添加锵码", + "desc": "åœØę–‡ę”£ēš„ęŒ‡å®šä½ē½®ę·»åŠ é”µē " + }, + "auto-rename": { + "title": "č‡ŖåŠØé‡å‘½å PDF ꖇ件", + "desc": "ę ¹ę®ę£€ęµ‹åˆ°ēš„ę ‡é¢˜č‡ŖåŠØåÆ¹ PDF ę–‡ä»¶čæ›č”Œé‡å‘½å" + }, + "adjust-contrast": { + "title": "č°ƒę•“é¢œč‰²/对比度", + "desc": "č°ƒę•“ PDF ēš„åÆ¹ęÆ”åŗ¦ć€é„±å’Œåŗ¦å’Œäŗ®åŗ¦" + }, + "crop": { + "title": "裁剪 PDF", + "desc": "裁剪 PDF ä»„å‡å°å…¶ę–‡ä»¶å¤§å°ļ¼ˆäæē•™ę–‡ęœ¬ļ¼ļ¼‰" + }, + "autoSplitPDF": { + "title": "č‡ŖåŠØę‹†åˆ†é”µé¢", + "desc": "ä½æē”Øē‰©ē†ę‰«ęé”µé¢åˆ†å‰²å™Ø QR ä»£ē č‡ŖåŠØę‹†åˆ†ę‰«ęēš„ PDF" + }, + "sanitizePdf": { + "title": "清理", + "desc": "从 PDF ę–‡ä»¶äø­åˆ é™¤č„šęœ¬å’Œå…¶ä»–å…ƒē“ " + }, + "URLToPDF": { + "title": "URL/网站转 PDF", + "desc": "将任何 http(s)URL č½¬ę¢äøŗPDF" + }, + "HTMLToPDF": { + "title": "HTML 转 PDF", + "desc": "将任何 HTML ę–‡ä»¶ęˆ– zip ę–‡ä»¶č½¬ę¢äøŗ PDF" + }, + "MarkdownToPDF": { + "title": "Markdown 转 PDF", + "desc": "将任何 Markdown ę–‡ä»¶č½¬ę¢äøŗ PDF" + }, + "PDFToMarkdown": { + "title": "PDF 转 Markdown", + "desc": "将任何pdfę–‡ä»¶č½¬ę¢äøŗMarkdownꖇ件" + }, + "getPdfInfo": { + "title": "čŽ·å– PDF ēš„ę‰€ęœ‰äæ”ęÆ", + "desc": "čŽ·å– PDF ēš„ę‰€ęœ‰åÆčƒ½ēš„äæ”ęÆ" + }, + "extractPage": { + "title": "ęå–é”µé¢", + "desc": "从 PDF äø­ęå–é€‰å®šēš„é”µé¢" + }, + "PdfToSinglePage": { + "title": "PDF č½¬å•äø€å¤§é”µ", + "desc": "å°†ę‰€ęœ‰ PDF é”µé¢åˆå¹¶äøŗäø€äøŖå¤§ēš„å•é”µ" + }, + "showJS": { + "title": "显示 JavaScript", + "desc": "ęœē“¢å¹¶ę˜¾ē¤ŗåµŒå…„åˆ° PDF äø­ēš„ä»»ä½• JavaScript 代码" + }, + "autoRedact": { + "title": "č‡ŖåŠØåˆ é™¤", + "desc": "ę ¹ę®č¾“å…„ę–‡ęœ¬č‡ŖåŠØåˆ é™¤ļ¼ˆč¦†ē›–ļ¼‰PDF äø­ēš„ę–‡ęœ¬" + }, + "redact": { + "title": "ę‰‹åŠØäæ®č®¢", + "desc": "ę ¹ę®é€‰å®šēš„ę–‡ęœ¬ć€ē»˜åˆ¶ēš„å½¢ēŠ¶å’Œ/ęˆ–é€‰å®šēš„é”µé¢ē¼–č¾‘PDF" + }, + "tableExtraxt": { + "title": "PDF 转 CSV", + "desc": "从 PDF äø­ęå–č”Øę ¼å¹¶å°†å…¶č½¬ę¢äøŗ CSV" + }, + "autoSizeSplitPDF": { + "title": "č‡ŖåŠØę ¹ę®å¤§å°/ę•°ē›®ę‹†åˆ† PDF", + "desc": "å°†å•äøŖ PDF ę‹†åˆ†äøŗå¤šäøŖę–‡ę”£ļ¼ŒåŸŗäŗŽå¤§å°ć€é”µę•°ęˆ–ę–‡ę”£ę•°" + }, + "overlay-pdfs": { + "title": "叠加 PDF", + "desc": "将 PDF å åŠ åœØå¦äø€äøŖ PDF 上" + }, + "split-by-sections": { + "title": "ę‹†åˆ† PDF ęˆå°å—", + "desc": "将 PDF ēš„ęÆäø€é”µåˆ†å‰²ęˆę›“å°ēš„ę°“å¹³å’Œåž‚ē›“ēš„éƒØåˆ†" + }, + "AddStampRequest": { + "title": "ę·»åŠ å›¾ē« ", + "desc": "åœØęŒ‡å®šä½ē½®ę·»åŠ ę–‡ęœ¬ęˆ–å›¾ē‰‡å›¾ē« " + }, + "removeImagePdf": { + "title": "删除图像", + "desc": "删除图像减少 PDF 大小" + }, + "splitPdfByChapters": { + "title": "ęŒ‰ē« čŠ‚ę‹†åˆ† PDF", + "desc": "ę ¹ę®å…¶ē« čŠ‚ē»“ęž„å°† PDF ę‹†åˆ†äøŗå¤šäøŖę–‡ä»¶ć€‚" + }, + "validateSignature": { + "title": "验证 PDF ē­¾å", + "desc": "验证 PDF ę–‡ę”£äø­ēš„ę•°å­—ē­¾åå’ŒčÆä¹¦" + }, + "replaceColorPdf": { + "title": "ę›æę¢å’Œåč½¬é¢œč‰²", + "desc": "ę›æę¢ PDF äø­ę–‡ęœ¬å’ŒčƒŒę™Æēš„é¢œč‰²ļ¼Œå¹¶å°†PDFå…Øč‰²åč½¬ä»„å‡å°ę–‡ä»¶å¤§å°" + } + }, + "viewPdf": { + "tags": "ęµč§ˆć€é˜…čÆ»ć€ę³Øé‡Šć€ę–‡ęœ¬ć€å›¾åƒ", + "title": "View/Edit PDF", + "header": "ęµč§ˆ PDF" + }, + "multiTool": { + "tags": "å¤šå·„å…·ļ¼Œå¤šę“ä½œļ¼Œē”Øęˆ·ē•Œé¢ļ¼Œē‚¹å‡»ę‹–åŠØļ¼Œå‰ē«Æļ¼Œå®¢ęˆ·ē«Æ", + "title": "PDF å¤šåŠŸčƒ½å·„å…·", + "header": "PDF å¤šåŠŸčƒ½å·„å…·", + "uploadPrompts": "ę–‡ä»¶å", + "selectAll": "é€‰ę‹©ę‰€ęœ‰", + "deselectAll": "å–ę¶ˆé€‰ę‹©ę‰€ęœ‰", + "selectPages": "Page Select", + "selectedPages": "å·²é€‰ę‹©ēš„é”µé¢", + "page": "Page", + "deleteSelected": "删除已选", + "downloadAll": "åÆ¼å‡ŗå…ØéƒØ", + "downloadSelected": "导出已选", + "insertPageBreak": "ę’å…„åˆ†é”µē¬¦", + "addFile": "ę·»åŠ ę–‡ä»¶", + "rotateLeft": "向左旋转", + "rotateRight": "å‘å³ę—‹č½¬", + "split": "分割", + "moveLeft": "å‘åšē§»åŠØ", + "moveRight": "å‘å³ē§»åŠØ", + "delete": "删除", + "dragDropMessage": "é€‰ę‹©é”µé¢", + "undo": "Undo", + "redo": "Redo" + }, + "merge": { + "tags": "åˆå¹¶ļ¼Œé”µé¢ę“ä½œļ¼ŒåŽē«Æļ¼ŒęœåŠ”å™Øē«Æ", + "title": "合并", + "header": "合并多个 PDF(2äøŖä»„äøŠļ¼‰ć€‚", + "sortByName": "ęŒ‰åē§°ęŽ’åŗ", + "sortByDate": "ęŒ‰ę—„ęœŸęŽ’åŗ", + "removeCertSign": "åˆ é™¤åˆå¹¶ę–‡ä»¶ēš„ę•°å­—ē­¾åå—ļ¼Ÿ", + "submit": "合并" + }, + "split": { + "tags": "é”µé¢ę“ä½œļ¼Œåˆ’åˆ†ļ¼Œå¤šé”µé¢ļ¼Œå‰Ŗåˆ‡ļ¼ŒęœåŠ”å™Øē«Æ", + "title": "ę‹†åˆ† PDF", + "header": "ę‹†åˆ† PDF", + "desc": { + "1": "é€‰ę‹©åøŒęœ›čæ›č”Œåˆ†å‰²ēš„é”µę•°", + "2": "如选择1,3,7-9å°†ęŠŠäø€äøŖ 10 é”µēš„ę–‡ä»¶åˆ†å‰²ęˆ6äøŖē‹¬ē«‹ēš„PDF:", + "3": "文攣 #1:第 1 锵", + "4": "文攣 #2:第 2 é”µå’Œē¬¬ 3 锵", + "5": "文攣 #3:第 4 锵、第 5 锵、第 6 é”µå’Œē¬¬ 7 锵", + "6": "文攣 #4:第 7 锵", + "7": "文攣 #5:第 8 锵", + "8": "文攣 #6:第 9 é”µå’Œē¬¬ 10 锵" + }, + "splitPages": "č¾“å…„č¦åˆ†å‰²ēš„é”µé¢ļ¼š", + "submit": "ę‹†åˆ†" + }, + "rotate": { + "tags": "ęœåŠ”å™Øē«Æ", + "title": "旋转 PDF", + "header": "旋转 PDF", + "selectAngle": "é€‰ę‹©ę—‹č½¬č§’åŗ¦ļ¼ˆä»„ 90 åŗ¦ēš„å€ę•°ļ¼‰ļ¼š", + "submit": "旋转" + }, + "imageToPdf": { + "tags": "č½¬ę¢ć€å›¾åƒć€JPG、图片、照片" + }, + "pdfToImage": { + "tags": "č½¬ę¢ć€å›¾åƒć€JPG、图片、照片", + "title": "PDF 转图片", + "header": "将 PDF č½¬ę¢äøŗå›¾ē‰‡", + "selectText": "å›¾åƒę ¼å¼", + "singleOrMultiple": "å›¾åƒē»“ęžœē±»åž‹", + "single": "å•å¼ å›¾ē‰‡", + "multi": "å¤šå¼ å›¾ē‰‡", + "colorType": "é¢œč‰²ē±»åž‹", + "color": "é¢œč‰²", + "grey": "灰度", + "blackwhite": "é»‘ē™½ļ¼ˆåÆčƒ½ä¼šäø¢å¤±ę•°ę®ļ¼ļ¼‰ć€‚", + "submit": "č½¬ę¢", + "info": "WebP č½¬ę¢éœ€č¦å®‰č£… Python", + "placeholder": "ļ¼ˆä¾‹å¦‚ļ¼š1,2,8 ꈖ 4,7,12-16 ꈖ 2n-1)" + }, + "pdfOrganiser": { + "tags": "åŒé¢ć€å¶ę•°ć€å„‡ę•°ć€ęŽ’åŗć€ē§»åŠØ", + "title": "é”µé¢ęŽ’åŗ", + "header": "PDF é”µé¢ęŽ’åŗ", + "submit": "é‡ę–°ęŽ’åˆ—é”µé¢", + "mode": { + "_value": "ęØ”å¼", + "1": "č‡Ŗå®šä¹‰é”µé¢é”ŗåŗ", + "2": "åå‘é”ŗåŗ", + "3": "åŒé¢ęŽ’åŗ", + "4": "å°å†Œå­ęŽ’åŗ", + "5": "ä¾§č£…č®¢å°å†Œå­ęŽ’åŗ", + "6": "å„‡å¶ę‹†åˆ†", + "7": "åˆ é™¤ē¬¬äø€é”µ", + "8": "åˆ é™¤ęœ€åŽäø€é”µ", + "9": "åˆ é™¤ē¬¬äø€é”µå’Œęœ€åŽäø€é”µ", + "10": "儇偶合并", + "11": "Duplicate all pages" + }, + "placeholder": "ļ¼ˆä¾‹å¦‚ļ¼š1,3,2 ꈖ 4-8,2,10-12 ꈖ 2n-1)" + }, + "addImage": { + "tags": "å›¾åƒć€JPG、图片、照片", + "title": "ę·»åŠ å›¾åƒ", + "header": "ę·»åŠ å›¾ē‰‡åˆ° PDF", + "everyPage": "ęÆäø€é”µļ¼Ÿ", + "upload": "ę·»åŠ å›¾ē‰‡", + "submit": "ę·»åŠ å›¾ē‰‡" + }, + "watermark": { + "tags": "ę–‡ęœ¬ć€é‡å¤ć€ę ‡ē­¾ć€č‡Ŗå®šä¹‰ć€ē‰ˆęƒć€å•†ę ‡ć€å›¾åƒć€JPG、图片、照片", + "title": "ę·»åŠ ę°“å°", + "header": "ę·»åŠ ę°“å°", + "customColor": "č‡Ŗå®šä¹‰ę–‡ęœ¬é¢œč‰²", + "selectText": { + "1": "é€‰ę‹©č¦ę·»åŠ ę°“å°ēš„ PDF:", + "2": "ę°“å°ę–‡ęœ¬ļ¼š", + "3": "å­—ä½“å¤§å°ļ¼š", + "4": "ę—‹č½¬ļ¼ˆ0-360ļ¼‰ļ¼š", + "5": "ę°“å¹³é—“č·ļ¼ˆęÆäøŖę°“å°ä¹‹é—“ēš„ę°“å¹³č·ē¦»ļ¼‰ļ¼š", + "6": "åž‚ē›“é—“č·ļ¼ˆęÆäøŖę°“å°ä¹‹é—“ēš„åž‚ē›“č·ē¦»ļ¼‰ļ¼š", + "7": "é€ę˜Žåŗ¦ļ¼ˆ0% - 100%ļ¼‰ļ¼š", + "8": "ę°“å°ē±»åž‹ļ¼š", + "9": "ę°“å°å›¾ē‰‡ļ¼š", + "10": "将 PDF č½¬ę¢äøŗ PDF-Image" + }, + "submit": "ę·»åŠ ę°“å°", + "type": { + "1": "文字", + "2": "图片" + } + }, + "permissions": { + "tags": "é˜…čÆ»ć€å†™å…„ć€ē¼–č¾‘ć€ę‰“å°", + "title": "ę›“ę”¹ęƒé™", + "header": "ę”¹å˜ęƒé™", + "warning": "č­¦å‘Šļ¼Œäøŗäŗ†ä½æčæ™äŗ›ęƒé™äøčƒ½č¢«ę”¹å˜ļ¼Œå»ŗč®®é€ščæ‡ę·»åŠ åÆ†ē é”µé¢č®¾ē½®åÆ†ē ć€‚", + "selectText": { + "1": "选ꋩ PDF ę„ę”¹å˜ęƒé™", + "2": "č¦č®¾ē½®ēš„ęƒé™", + "3": "é˜²ę­¢ę–‡ä»¶ēš„ę‹¼ęŽ„", + "4": "é˜²ę­¢å†…å®¹ęå–", + "5": "é˜²ę­¢ęå–å†…å®¹ēš„åÆč®æé—®ę€§", + "6": "é˜²ę­¢å”«å†™č”Øę ¼", + "7": "é˜²ę­¢äæ®ę”¹", + "8": "é˜²ę­¢äæ®ę”¹ę³Øé‡Š", + "9": "é˜²ę­¢ę‰“å°", + "10": "é˜²ę­¢ę‰“å°äøåŒēš„ę ¼å¼" + }, + "submit": "ę”¹å˜" + }, + "removePages": { + "tags": "åˆ é™¤é”µé¢ć€åˆ é™¤" + }, + "addPassword": { + "tags": "å®‰å…Øć€åÆ†ē ć€åŠ åÆ†", + "title": "ę·»åŠ åÆ†ē ", + "header": "ę·»åŠ åÆ†ē ļ¼ˆåŠ åÆ†ļ¼‰ć€‚", + "selectText": { + "1": "é€‰ę‹©č¦åŠ åÆ†ēš„ PDF怂", + "2": "密码", + "3": "åŠ åÆ†åÆ†é’„é•æåŗ¦", + "4": "å€¼č¶Šé«˜č¶Šå¼ŗļ¼Œä½†å€¼č¶Šä½Žå…¼å®¹ę€§č¶Šå„½ć€‚", + "5": "č¦č®¾ē½®ēš„ęƒé™", + "6": "é˜²ę­¢ę–‡ä»¶ēš„ę‹¼ęŽ„ć€‚", + "7": "é˜²ę­¢å†…å®¹ęå–", + "8": "é˜²ę­¢äøŗåÆč®æé—®ę€§ęå–å†…å®¹", + "9": "é˜²ę­¢å”«å†™č”Øę ¼", + "10": "é˜²ę­¢äæ®ę”¹", + "11": "é˜²ę­¢äæ®ę”¹ę³Øé‡Š", + "12": "é˜²ę­¢ę‰“å°", + "13": "é˜²ę­¢ę‰“å°äøåŒēš„ę ¼å¼", + "14": "ę‰€ęœ‰č€…åÆ†ē ", + "15": "é™åˆ¶ę‰“å¼€åŽåÆ¹ę–‡ę”£ēš„ę“ä½œļ¼ˆäøč¢«ę‰€ęœ‰é˜…čÆ»å™Øę”ÆęŒļ¼‰", + "16": "é™åˆ¶ę‰“å¼€ę–‡ę”£ęœ¬čŗ«" + }, + "submit": "åŠ åÆ†" + }, + "removePassword": { + "tags": "å®‰å…Øć€č§£åÆ†ć€åÆ†ē ć€å®‰å…Øę€§ć€åˆ é™¤åÆ†ē ", + "title": "åˆ é™¤åÆ†ē ", + "header": "ē§»é™¤åÆ†ē ļ¼ˆč§£åÆ†ļ¼‰ć€‚", + "selectText": { + "1": "é€‰ę‹©č¦č§£åÆ†ēš„ PDF", + "2": "密码" + }, + "submit": "删除" + }, + "compressPdfs": { + "tags": "åŽ‹ē¼©ć€å°ć€å¾®å°" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "ę ‡é¢˜ć€ä½œč€…ć€ę—„ęœŸć€åˆ›å»ŗć€ę—¶é—“ć€å‘åøƒč€…ć€åˆ¶ä½œäŗŗć€ē»Ÿč®”ę•°ę®", + "title": "ę ‡é¢˜ļ¼š", + "header": "ę›“ę”¹å…ƒę•°ę®", + "selectText": { + "1": "čÆ·ē¼–č¾‘ä½ ęƒ³č¦ę”¹å˜ēš„å˜é‡ć€‚", + "2": "åˆ é™¤ę‰€ęœ‰å…ƒę•°ę®", + "3": "ę˜¾ē¤ŗč‡Ŗå®šä¹‰å…ƒę•°ę®ļ¼š", + "4": "å…¶ä»–å…ƒę•°ę®ļ¼š", + "5": "ę·»åŠ č‡Ŗå®šä¹‰å…ƒę•°ę®ę”ē›®" + }, + "author": "ä½œč€…ļ¼š", + "creationDate": "åˆ›å»ŗę—„ęœŸļ¼ˆyyyy/MM/dd HH:mm:ssļ¼‰ļ¼š", + "creator": "åˆ›å»ŗč€…ļ¼š", + "keywords": "å…³é”®čÆļ¼š", + "modDate": "äæ®ę”¹ę—„ęœŸļ¼ˆyyyy/MM/dd HH:mm:ssļ¼‰ļ¼š", + "producer": "ē”Ÿäŗ§č€…ļ¼š", + "subject": "主题:", + "trapped": "č¢«å›°ļ¼š", + "submit": "曓改" + }, + "fileToPDF": { + "tags": "č½¬ę¢ć€ę ¼å¼ć€ę–‡ę”£ć€å›¾ē‰‡ć€å¹»ēÆē‰‡ć€ę–‡ęœ¬ć€č½¬ę¢ć€Office态Docs态Word态Excel态PowerPoint", + "title": "ę–‡ä»¶č½¬ę¢äøŗ PDF", + "header": "å°†ä»»ä½•ę–‡ä»¶č½¬ę¢äøŗ PDF怂", + "credit": "ę­¤ęœåŠ”ä½æē”Ø LibreOffice 和 Unoconv čæ›č”Œę–‡ä»¶č½¬ę¢ć€‚", + "supportedFileTypesInfo": "ę”ÆęŒēš„ę–‡ä»¶ē±»åž‹", + "supportedFileTypes": "ę”ÆęŒēš„ę–‡ä»¶ē±»åž‹åŗ”čÆ„åŒ…ę‹¬ä»„äø‹å‡ ē§ļ¼Œä½†ę˜Æļ¼ŒåÆ¹äŗŽę”ÆęŒēš„ę ¼å¼ēš„å®Œę•“ę›“ę–°åˆ—č”Øļ¼ŒčÆ·å‚č€ƒ LibreOffice 文攣。", + "submit": "č½¬ę¢äøŗ PDF" + }, + "ocr": { + "tags": "čÆ†åˆ«ć€ę–‡ęœ¬ć€å›¾åƒć€ę‰«ęć€é˜…čÆ»ć€čÆ†åˆ«ć€ę£€ęµ‹ć€åÆē¼–č¾‘", + "title": "OCR/ę‰«ęęø…ē†", + "header": "ęø…ē†ę‰«ęä»¶/OCRļ¼ˆå…‰å­¦å­—ē¬¦čÆ†åˆ«ļ¼‰ć€‚", + "selectText": { + "1": "é€‰ę‹©č¦åœØ PDF äø­ę£€ęµ‹ēš„čÆ­čØ€ļ¼ˆåˆ—å‡ŗēš„čÆ­čØ€ę˜Æē›®å‰ę£€ęµ‹åˆ°ēš„ļ¼‰ļ¼š", + "2": "ē”ŸęˆåŒ…å« OCR ę–‡ęœ¬ēš„ę–‡ęœ¬ę–‡ä»¶ļ¼ŒäøŽ OCR ē¼–č¾‘ēš„ PDF 一起。", + "3": "é€ščæ‡å°†é”µé¢ę—‹č½¬å›žåŽŸä½ę„ēŗ ę­£åę–œēš„ę‰«ęč§’åŗ¦", + "4": "ęø…ē†é”µé¢ļ¼Œé™ä½Ž OCR åœØå™Ŗē‚¹äø­čÆ†åˆ«åˆ°ę–‡ęœ¬ēš„åÆčƒ½ć€‚(ę²”ęœ‰č¾“å‡ŗå˜åŒ–)", + "5": "ęø…ę“é”µé¢ļ¼Œé™ä½Ž OCR åœØå™Ŗē‚¹äø­čÆ†åˆ«åˆ°ę–‡ęœ¬ēš„åÆčƒ½ļ¼ŒäæęŒč¾“å‡ŗēš„ęø…ę“ć€‚", + "6": "åæ½ē•„ęœ‰äŗ¤äŗ’å¼ę–‡ęœ¬ēš„é”µé¢ļ¼ŒåŖåÆ¹ęœ‰å›¾åƒēš„é”µé¢čæ›č”Œ OCR怂", + "7": "强制 OCRļ¼Œå°† OCR ęÆäøŖé”µé¢ļ¼Œåˆ é™¤ę‰€ęœ‰ēš„åŽŸå§‹ę–‡ęœ¬å…ƒē“ ć€‚", + "8": "正常 (å¦‚ęžœ PDF åŒ…å«ę–‡ęœ¬ļ¼Œå°†å‡ŗēŽ°é”™čÆÆ)", + "9": "é¢å¤–č®¾ē½®", + "10": "OCR ęØ”å¼", + "11": "OCR åŽē§»é™¤å›¾åƒļ¼ˆē§»é™¤ę‰€ęœ‰å›¾åƒļ¼ŒåŖęœ‰åœØč½¬ę¢ę­„éŖ¤äø­ę‰ęœ‰ē”Øļ¼‰ć€‚", + "12": "ęø²ęŸ“ē±»åž‹ļ¼ˆé«˜ēŗ§ļ¼‰" + }, + "help": "čÆ·é˜…čÆ»ę­¤ę–‡ę”£ļ¼Œäŗ†č§£å¦‚ä½•å°†å…¶ē”ØäŗŽå…¶ä»–čÆ­čØ€å’Œ/ęˆ–äøåœØ docker 中使用。", + "credit": "ę­¤ęœåŠ”ä½æē”Ø qpdf 和 Tesseract čæ›č”Œ OCR怂", + "submit": "用 OCR 处理 PDF" + }, + "extractImages": { + "tags": "å›¾ē‰‡ć€ē…§ē‰‡ć€äæå­˜ć€å½’ę”£ć€åŽ‹ē¼©åŒ…ć€ęˆŖå–ć€ęŠ“å–", + "title": "ęå–å›¾åƒ", + "header": "ęå–å›¾åƒ", + "selectText": "é€‰ę‹©å›¾åƒę ¼å¼ļ¼Œå°†ęå–ēš„å›¾åƒč½¬ę¢äøŗ", + "allowDuplicates": "äæå­˜é‡å¤å›¾åƒ", + "submit": "ęå–" + }, + "pdfToPDFA": { + "tags": "å½’ę”£ć€é•æęœŸć€ę ‡å‡†ć€č½¬ę¢ć€å­˜å‚Øć€äæå­˜", + "title": "PDF 转 PDF/A", + "header": "将 PDF č½¬ę¢äøŗ PDF/A", + "credit": "ę­¤ęœåŠ”ä½æē”Ø libreoffice čæ›č”Œ PDF/A č½¬ę¢", + "submit": "č½¬ę¢", + "tip": "ē›®å‰äøę”ÆęŒäøŠä¼ å¤šäøŖ", + "outputFormat": "č¾“å‡ŗę ¼å¼", + "pdfWithDigitalSignature": "评PDFåŒ…å«ę•°å­—ē­¾åļ¼Œäø‹äø€ę­„å°†ē§»é™¤čÆ„ē­¾åć€‚" + }, + "PDFToWord": { + "tags": "doc态docx态odt态wordć€č½¬ę¢ć€ę ¼å¼ć€Office态Microsoft、文攣", + "title": "PDF 转 Word", + "header": "将 PDF č½¬ę¢äøŗ Word", + "selectText": { + "1": "č¾“å‡ŗę–‡ä»¶ę ¼å¼" + }, + "credit": "ę­¤ęœåŠ”ä½æē”Ø LibreOffice čæ›č”Œę–‡ä»¶č½¬ę¢ć€‚", + "submit": "č½¬ę¢" + }, + "PDFToPresentation": { + "tags": "幻灯片、展示、Office态Microsoft", + "title": "PDF 转演示文稿", + "header": "将 PDF č½¬ę¢äøŗę¼”ē¤ŗę–‡ēØæ", + "selectText": { + "1": "č¾“å‡ŗę–‡ä»¶ę ¼å¼" + }, + "credit": "ę­¤ęœåŠ”ä½æē”Ø LibreOffice čæ›č”Œę–‡ä»¶č½¬ę¢ć€‚", + "submit": "č½¬ę¢" + }, + "PDFToText": { + "tags": "åÆŒę–‡ęœ¬ę ¼å¼ć€RTFć€åÆŒę–‡ęœ¬ę ¼å¼", + "title": "PDF č½¬ę–‡ęœ¬/RTF", + "header": "将 PDF č½¬ę¢äøŗę–‡ęœ¬/RTF", + "selectText": { + "1": "č¾“å‡ŗę–‡ä»¶ę ¼å¼" + }, + "credit": "ę­¤ęœåŠ”ä½æē”Ø LibreOffice čæ›č”Œę–‡ä»¶č½¬ę¢ć€‚", + "submit": "č½¬ę¢" + }, + "PDFToHTML": { + "tags": "ē½‘é”µå†…å®¹ć€ęµč§ˆå™Øå‹å„½", + "title": "PDF 转 HTML", + "header": "将 PDF č½¬ę¢äøŗ HTML", + "credit": "ę­¤ęœåŠ”ä½æē”Ø pdftohtml čæ›č”Œę–‡ä»¶č½¬ę¢ć€‚", + "submit": "č½¬ę¢" + }, + "PDFToXML": { + "tags": "ę•°ę®ęå–ć€ē»“ęž„åŒ–å†…å®¹ć€äŗ’ę“ä½œć€č½¬ę¢", + "title": "PDF 转 XML", + "header": "将 PDF č½¬ę¢äøŗ XML", + "credit": "ę­¤ęœåŠ”ä½æē”Ø LibreOffice čæ›č”Œę–‡ä»¶č½¬ę¢ć€‚", + "submit": "č½¬ę¢" + }, + "ScannerImageSplit": { + "tags": "åˆ†ē¦»ć€č‡ŖåŠØę£€ęµ‹ć€ę‰«ęć€å¤šå¼ ē…§ē‰‡ć€ę•“ē†", + "selectText": { + "1": "č§’åŗ¦é˜ˆå€¼ļ¼š", + "2": "č®¾ē½®å›¾åƒč¢«ę—‹č½¬ę‰€éœ€ēš„ęœ€å°ē»åÆ¹č§’åŗ¦ļ¼ˆé»˜č®¤ļ¼š10)。", + "3": "å…¬å·®ļ¼š", + "4": "ē”®å®šä¼°č®”čƒŒę™Æé¢œč‰²å‘Øå›“ēš„é¢œč‰²å˜åŒ–čŒƒå›“ļ¼ˆé»˜č®¤å€¼ļ¼š30)。", + "5": "ęœ€å°é¢ē§Æļ¼š", + "6": "č®¾ē½®ē…§ē‰‡ēš„ęœ€å°é¢ē§Æé˜ˆå€¼ļ¼ˆé»˜č®¤ļ¼š10000)。", + "7": "ęœ€å°č½®å»“é¢ē§Æļ¼š", + "8": "č®¾ē½®ē…§ē‰‡ēš„ęœ€å°č½®å»“é¢ē§Æé˜ˆå€¼ć€‚", + "9": "č¾¹ę”†å°ŗåÆøļ¼š", + "10": "č®¾ē½®ę·»åŠ å’Œåˆ é™¤ēš„č¾¹ę”†å¤§å°ļ¼Œä»„é˜²ę­¢č¾“å‡ŗäø­å‡ŗēŽ°ē™½č¾¹ļ¼ˆé»˜č®¤å€¼ļ¼š1)。" + }, + "info": "ę­¤åŠŸčƒ½éœ€č¦å®‰č£… Python" + }, + "sign": { + "tags": "ęŽˆęƒć€ē¼©å†™ć€ę‰‹ē»˜ē­¾åć€ę–‡ęœ¬ē­¾åć€å›¾åƒē­¾å", + "title": "ē­¾å", + "header": "签署 PDF", + "upload": "äøŠä¼ å›¾ē‰‡", + "draw": "ē»˜åˆ¶ē­¾å", + "text": "ę–‡ęœ¬č¾“å…„", + "clear": "清除", + "add": "添加", + "saved": "å·²äæå­˜ē­¾å", + "save": "äæå­˜ē­¾å", + "personalSigs": "äøŖäŗŗē­¾å", + "sharedSigs": "å…±äŗ«ē­¾å", + "noSavedSigs": "ęœŖę‰¾åˆ°å·²äæå­˜ēš„ē­¾å", + "addToAll": "ę·»åŠ åˆ°ę‰€ęœ‰é”µé¢", + "delete": "删除", + "first": "首锵", + "last": "末锵", + "next": "下一锵", + "previous": "äøŠäø€é”µ", + "maintainRatio": "åˆ‡ę¢äæęŒé•æå®½ęÆ”", + "undo": "꒤销", + "redo": "重做" + }, + "flatten": { + "tags": "é™ę€ć€åœē”Øć€éžäŗ¤äŗ’ć€ē®€åŒ–", + "title": "展平", + "header": "展平 PDF", + "flattenOnlyForms": "仅展平蔨格", + "submit": "展平" + }, + "repair": { + "tags": "äæ®å¤ć€ę¢å¤ć€ēŗ ę­£ć€ę¢å¤", + "title": "äæ®å¤", + "header": "äæ®å¤ PDF", + "submit": "äæ®å¤" + }, + "removeBlanks": { + "tags": "ęø…ē†ć€ē®€åŒ–ć€éžå†…å®¹ć€ę•“ē†", + "title": "åˆ é™¤ē©ŗē™½", + "header": "åˆ é™¤ē©ŗē™½é”µ", + "threshold": "é˜ˆå€¼ļ¼š", + "thresholdDesc": "ē”®å®šē™½č‰²åƒē“ åæ…é”»ęœ‰å¤šē™½ēš„é˜ˆå€¼", + "whitePercent": "ē™½č‰²ē™¾åˆ†ęÆ”ļ¼ˆ%ļ¼‰ļ¼š", + "whitePercentDesc": "åæ…é”»äøŗē™½č‰²ę‰čƒ½åˆ é™¤ēš„é”µé¢ē™¾åˆ†ęÆ”", + "submit": "åˆ é™¤ē©ŗē™½" + }, + "removeAnnotations": { + "tags": "čÆ„č®ŗć€é«˜äŗ®ć€ē¬”č®°ć€ę ‡ę³Øć€åˆ é™¤", + "title": "åˆ é™¤ę ‡ę³Ø", + "header": "åˆ é™¤ę ‡ę³Ø", + "submit": "删除" + }, + "compare": { + "tags": "åŒŗåˆ†ć€åÆ¹ęÆ”ć€ę›“ę”¹ć€åˆ†ęž", + "title": "ęÆ”č¾ƒ", + "header": "ęÆ”č¾ƒPDF", + "highlightColor": { + "1": "é«˜äŗ®é¢œč‰² 1:", + "2": "é«˜äŗ®é¢œč‰² 2:" + }, + "document": { + "1": "文攣 1", + "2": "文攣 2" + }, + "submit": "ęÆ”č¾ƒ", + "complex": { + "message": "ęä¾›ēš„äø€ä»½ęˆ–äø¤ä»½ę–‡ä»¶ę˜Æå¤§ę–‡ä»¶ļ¼ŒęÆ”č¾ƒēš„å‡†ē”®ę€§åÆčƒ½ä¼šé™ä½Žć€‚" + }, + "large": { + "file": { + "message": "ęä¾›ēš„ę–‡ä»¶äø­ęœ‰äø€ä»½ęˆ–äø¤ä»½čæ‡å¤§ļ¼Œę— ę³•å¤„ē†ć€‚" + } + }, + "no": { + "text": { + "message": "ę‰€é€‰ēš„ PDF ę–‡ä»¶äø­ęœ‰äø€äøŖęˆ–äø¤äøŖę²”ęœ‰ę–‡ęœ¬å†…å®¹ć€‚čÆ·é€‰ę‹©åŒ…å«ę–‡ęœ¬ēš„ PDF ę–‡ä»¶čæ›č”ŒåÆ¹ęÆ”ć€‚" + } + } + }, + "certSign": { + "tags": "čŗ«ä»½éŖŒčÆć€PEM态P12ć€å®˜ę–¹ć€åŠ åÆ†", + "title": "čÆä¹¦ē­¾å", + "header": "ä½æē”Øę‚Øēš„čÆä¹¦ē­¾å PDFļ¼ˆčæ›č”Œäø­ļ¼‰", + "selectPDF": "é€‰ę‹©č¦ē­¾åēš„ PDF ę–‡ä»¶ļ¼š", + "jksNote": "ę³Øę„ļ¼šå¦‚ęžœę‚Øēš„čÆä¹¦ē±»åž‹ęœŖåœØäø‹é¢åˆ—å‡ŗļ¼ŒčÆ·ä½æē”Økeytoolå‘½ä»¤č”Œå·„å…·å°†å…¶č½¬ę¢äøŗ Java Keystore(.jks)文件。 ē„¶åŽļ¼Œé€‰ę‹©äø‹é¢ēš„.jks文件选锹。", + "selectKey": "é€‰ę‹©ę‚Øēš„ē§é’„ę–‡ä»¶ļ¼ˆPKCS#8ę ¼å¼ļ¼ŒåÆä»„ę˜Æ.pemꈖ.derļ¼‰ļ¼š", + "selectCert": "é€‰ę‹©ę‚Øēš„čÆä¹¦ę–‡ä»¶ļ¼ˆX.509ę ¼å¼ļ¼ŒåÆä»„ę˜Æ.pemꈖ.derļ¼‰ļ¼š", + "selectP12": "é€‰ę‹©ę‚Øēš„ PKCS#12 åÆ†é’„åŗ“ę–‡ä»¶ļ¼ˆ.p12ꈖ.pfxļ¼‰ļ¼ˆåÆé€‰ļ¼Œå¦‚ęžœęä¾›ļ¼Œå®ƒåŗ”čÆ„åŒ…å«ę‚Øēš„ē§é’„å’ŒčÆä¹¦ļ¼‰ļ¼š", + "selectJKS": "é€‰ę‹©ä½ ēš„ Java Keystore ꖇ件 (.jksꈖ.keystore):", + "certType": "čÆä¹¦ē±»åž‹", + "password": "č¾“å…„ę‚Øēš„åÆ†é’„åŗ“ęˆ–ē§é’„åÆ†ē ļ¼ˆå¦‚ęžœęœ‰ļ¼‰ļ¼š", + "showSig": "ę˜¾ē¤ŗē­¾å", + "reason": "原因", + "location": "ä½ē½®", + "name": "åē§°", + "showLogo": "显示 Logo", + "submit": "ē»™ PDF ē­¾å" + }, + "removeCertSign": { + "tags": "čŗ«ä»½éŖŒčÆć€PEM态P12ć€å®˜ę–¹ć€åŠ åÆ†", + "title": "ē§»é™¤čÆä¹¦ē­¾å", + "header": "移除 PDF ēš„čÆä¹¦ē­¾å", + "selectPDF": "选ꋩ PDF ę–‡ä»¶ļ¼š", + "submit": "ē§»é™¤ē­¾å" + }, + "pageLayout": { + "tags": "åˆå¹¶ć€ē»„åˆć€å•č§†å›¾ć€ę•“ē†", + "title": "å¤šé”µåøƒå±€", + "header": "å¤šé”µåøƒå±€", + "pagesPerSheet": "ęÆé”µēš„é”µé¢ę•°ļ¼š", + "addBorder": "ę·»åŠ č¾¹ę”†", + "submit": "ęäŗ¤" + }, + "scalePages": { + "tags": "č°ƒę•“å¤§å°ć€äæ®ę”¹ć€å°ŗåÆøć€é€‚åŗ”", + "title": "č°ƒę•“é”µé¢ē¼©ę”¾ęÆ”ä¾‹", + "header": "č°ƒę•“é”µé¢ē¼©ę”¾ęÆ”ä¾‹", + "pageSize": "ę–‡ę”£é”µé¢ēš„å°ŗåÆøć€‚", + "keepPageSize": "äæęŒé”µé¢åŽŸå°ŗåÆø", + "scaleFactor": "é”µé¢ēš„ē¼©ę”¾ēŗ§åˆ«ļ¼ˆč£å‰Ŗļ¼‰ć€‚", + "submit": "ęäŗ¤" + }, + "add-page-numbers": { + "tags": "åˆ†é”µć€ę ‡ē­¾ć€ę•“ē†ć€ē“¢å¼•" + }, + "auto-rename": { + "tags": "č‡ŖåŠØę£€ęµ‹ć€åŸŗäŗŽę ‡é¢˜ć€ę•“ē†ć€é‡ę–°ę ‡č®°", + "title": "č‡ŖåŠØé‡å‘½å", + "header": "č‡ŖåŠØé‡å‘½å PDF", + "submit": "č‡ŖåŠØé‡å‘½å" + }, + "adjust-contrast": { + "tags": "é¢œč‰²ę ”ę­£ć€č°ƒčŠ‚ć€äæ®ę”¹ć€å¢žå¼ŗ" + }, + "crop": { + "tags": "äæ®å‰Ŗć€ē¼©å°ć€ē¼–č¾‘ć€å½¢ēŠ¶", + "title": "裁剪", + "header": "裁剪 PDF", + "submit": "ęäŗ¤" + }, + "autoSplitPDF": { + "tags": "åŸŗäŗŽ QR ē ć€åˆ†ē¦»ć€ę‰«ęåˆ†å‰²ć€ę•“ē†", + "title": "č‡ŖåŠØę‹†åˆ† PDF", + "header": "č‡ŖåŠØę‹†åˆ† PDF", + "description": "ę‰“å°ć€ę’å…„ć€ę‰«ęć€äøŠä¼ ļ¼Œč®©ęˆ‘ä»¬č‡ŖåŠØåˆ†ē¦»ę‚Øēš„ę–‡ę”£ć€‚ę— éœ€ę‰‹åŠØęŽ’åŗć€‚", + "selectText": { + "1": "ä»Žäø‹é¢ę‰“å°äø€äŗ›åˆ†éš”é”µļ¼ˆé»‘ē™½ę‰“å°å³åÆļ¼‰ć€‚", + "2": "åœØę–‡ę”£ä¹‹é—“ę’å…„åˆ†éš”é”µļ¼Œäø€ę¬”ę€§ę‰«ęę‰€ęœ‰ę–‡ę”£ć€‚", + "3": "äøŠä¼ å•äøŖå¤§åž‹ę‰«ęēš„ PDF ę–‡ä»¶ļ¼Œč®© Stirling PDF å¤„ē†å‰©äø‹ēš„äŗ‹ęƒ…ć€‚", + "4": "åˆ†éš”é”µä¼šč‡ŖåŠØę£€ęµ‹å’Œåˆ é™¤ļ¼Œē”®äæęœ€ē»ˆę–‡ę”£ę•“ę“ć€‚" + }, + "formPrompt": "ęäŗ¤åŒ…å« Stirling-PDF åˆ†éš”é”µēš„ PDF:", + "duplexMode": "åŒé¢ęØ”å¼ļ¼ˆę­£åé¢ę‰«ęļ¼‰", + "dividerDownload2": "äø‹č½½ā€œč‡ŖåŠØę‹†åˆ†åˆ†éš”é”µļ¼ˆåø¦ęŒ‡åÆ¼čÆ“ę˜Žļ¼‰.pdfā€", + "submit": "ęäŗ¤" + }, + "sanitizePdf": { + "tags": "ęø…ē†ć€å®‰å…Øć€å®‰å…Øć€åˆ é™¤åØčƒ" + }, + "URLToPDF": { + "tags": "ē½‘é”µę•čŽ·ć€äæå­˜ē½‘é”µć€ē½‘é”µč½¬ę–‡ę”£ć€å½’ę”£", + "title": "URL 转 PDF", + "header": "将 URL č½¬ę¢äøŗ PDF", + "submit": "č½¬ę¢", + "credit": "ę­¤ęœåŠ”ä½æē”Ø WeasyPrint čæ›č”Œę–‡ä»¶č½¬ę¢ć€‚" + }, + "HTMLToPDF": { + "tags": "ę ‡č®°ć€ē½‘é”µå†…å®¹ć€č½¬ę¢ć€č½¬ę¢", + "title": "HTML 转 PDF", + "header": "将 HTML č½¬ę¢äøŗ PDF", + "help": "ęŽ„å— HTML ę–‡ä»¶å’ŒåŒ…å«ę‰€éœ€ēš„ html/css/images ē­‰ēš„ ZIP ꖇ件", + "submit": "č½¬ę¢", + "credit": "ę­¤ęœåŠ”ä½æē”Ø WeasyPrint čæ›č”Œę–‡ä»¶č½¬ę¢ć€‚", + "zoom": "ē½‘ē«™ę˜¾ē¤ŗē¼©ę”¾ēŗ§åˆ«", + "pageWidth": "é”µé¢å®½åŗ¦-ä»„åŽ˜ē±³äøŗå•ä½ļ¼ˆå”«ē©ŗåˆ™ä½æē”Øé»˜č®¤å€¼ļ¼‰", + "pageHeight": "é”µé¢é«˜åŗ¦-ä»„åŽ˜ē±³äøŗå•ä½ļ¼ˆå”«ē©ŗåˆ™ä½æē”Øé»˜č®¤å€¼ļ¼‰", + "marginTop": "é”µé¢äøŠč¾¹č·-ä»„ęÆ«ē±³äøŗå•ä½ļ¼ˆå”«ē©ŗåˆ™ä½æē”Øé»˜č®¤å€¼ļ¼‰", + "marginBottom": "é”µé¢äø‹č¾¹č·-ä»„ęÆ«ē±³äøŗå•ä½ļ¼ˆå”«ē©ŗåˆ™ä½æē”Øé»˜č®¤å€¼ļ¼‰", + "marginLeft": "é”µé¢å·¦äøŠč¾¹č·-ä»„ęÆ«ē±³äøŗå•ä½ļ¼ˆå”«ē©ŗåˆ™ä½æē”Øé»˜č®¤å€¼ļ¼‰", + "marginRight": "é”µé¢å³č¾¹č·-ä»„ęÆ«ē±³äøŗå•ä½ļ¼ˆå”«ē©ŗåˆ™ä½æē”Øé»˜č®¤å€¼ļ¼‰", + "printBackground": "é”µé¢čƒŒę™Æęø²ęŸ“", + "defaultHeader": "åÆē”Øé»˜č®¤é”µå¤“ļ¼ˆę–‡ä»¶åē§°å’Œé”µē ļ¼‰", + "cssMediaType": "ę›“ę¢é”µé¢ēš„ CSS åŖ’ä½“ē±»åž‹ć€‚", + "none": "ꗠ", + "print": "ę‰“å°", + "screen": "屏幕" + }, + "MarkdownToPDF": { + "tags": "ę ‡č®°ć€ē½‘é”µå†…å®¹ć€č½¬ę¢ć€č½¬ę¢", + "title": "Markdown 转 PDF", + "header": "将 Markdown č½¬ę¢äøŗ PDF", + "submit": "č½¬ę¢", + "help": "ę­£åœØåŠŖåŠ›äø­", + "credit": "ę­¤ęœåŠ”ä½æē”Ø WeasyPrint čæ›č”Œę–‡ä»¶č½¬ę¢ć€‚" + }, + "PDFToMarkdown": { + "tags": "ꠇ记,网锵内容,č½¬ę¢,转攣,md", + "title": "PDF转Markdown", + "header": "PDF转Markdown", + "submit": "č½¬ę¢" + }, + "getPdfInfo": { + "tags": "äæ”ęÆć€ę•°ę®ć€ē»Ÿč®”ć€ē»Ÿč®”ę•°ę®", + "title": "čŽ·å– PDF 俔息", + "header": "čŽ·å– PDF 俔息", + "submit": "čŽ·å–äæ”ęÆ", + "downloadJson": "äø‹č½½ JSON" + }, + "extractPage": { + "tags": "ęå–" + }, + "PdfToSinglePage": { + "tags": "单锵" + }, + "showJS": { + "tags": "JavaScript", + "title": "显示 JavaScript", + "header": "显示 JavaScript", + "downloadJS": "äø‹č½½ JavaScript", + "submit": "显示" + }, + "autoRedact": { + "tags": "č„±ę•ć€éšč—ć€ę¶‚é»‘ć€ę ‡č®°ć€äøåÆč§", + "title": "č‡ŖåŠØåˆ é™¤", + "header": "č‡ŖåŠØåˆ é™¤", + "colorLabel": "é¢œč‰²", + "textsToRedactLabel": "č¦åˆ é™¤ēš„ę–‡ęœ¬ļ¼ˆęÆč”Œäø€äøŖļ¼‰", + "textsToRedactPlaceholder": "ä¾‹å¦‚ļ¼š\\näæåÆ†\\nē»åÆ†", + "useRegexLabel": "ä½æē”Øę­£åˆ™č”Øč¾¾å¼", + "wholeWordSearchLabel": "å…Øå­—åŒ¹é…", + "customPaddingLabel": "č‡Ŗå®šä¹‰é¢å¤–é—“č·", + "convertPDFToImageLabel": "将PDFč½¬ę¢äøŗPDF-Imageļ¼ˆē”ØäŗŽåˆ é™¤ę–¹ę”†åŽé¢ēš„ę–‡ęœ¬ļ¼‰", + "submitButton": "ęäŗ¤" + }, + "redact": { + "tags": "涂改,隐藏,궂黑,黑色,ꠇ记,遮蔽,ę‰‹åŠØ", + "title": "ę‰‹åŠØēŗ ę­£", + "header": "ę‰‹åŠØēŗ ę­£", + "submit": "ēŗ ę­£", + "textBasedRedaction": "åŸŗäŗŽę–‡ęœ¬ēš„ēŗ ę­£", + "pageBasedRedaction": "åŸŗäŗŽé”µé¢ēš„ēŗ ę­£", + "convertPDFToImageLabel": "将PDFč½¬ę¢äøŗPDFå›¾åƒļ¼ˆē”ØäŗŽåˆ é™¤ę”†åŽēš„ę–‡ęœ¬ļ¼‰", + "pageRedactionNumbers": { + "title": "锵面", + "placeholder": "(例如 1,2,8 ꈖ 4,7,12-16 ꈖ 2n-1)" + }, + "redactionColor": { + "title": "ē¼–č¾‘é¢œč‰²" + }, + "export": "导出", + "upload": "上传", + "boxRedaction": "ę”†é€‰åŒŗåŸŸę¶‚é»‘", + "zoom": "缩放", + "zoomIn": "放大", + "zoomOut": "ē¼©å°", + "nextPage": "下一锵", + "previousPage": "äøŠäø€é”µ", + "toggleSidebar": "åˆ‡ę¢ä¾§č¾¹ę ", + "showThumbnails": "ę˜¾ē¤ŗē¼©ē•„å›¾", + "showDocumentOutline": "ę˜¾ē¤ŗę–‡ę”£å¤§ēŗ²ļ¼ˆåŒå‡»å±•å¼€/ęŠ˜å ę‰€ęœ‰é”¹ē›®ļ¼‰", + "showAttatchments": "ę˜¾ē¤ŗé™„ä»¶", + "showLayers": "ę˜¾ē¤ŗå›¾å±‚ļ¼ˆåŒå‡»å°†ę‰€ęœ‰å›¾å±‚é‡ē½®äøŗé»˜č®¤ēŠ¶ę€ļ¼‰", + "colourPicker": "é¢œč‰²é€‰ę‹©å™Ø", + "findCurrentOutlineItem": "ęŸ„ę‰¾å½“å‰å¤§ēŗ²é”¹ē›®", + "applyChanges": "应用" + }, + "tableExtraxt": { + "tags": "CSVć€č”Øę ¼ęå–ć€ęå–ć€č½¬ę¢" + }, + "autoSizeSplitPDF": { + "tags": "pdfć€ę‹†åˆ†ć€ę–‡ä»¶ć€ē»„ē»‡" + }, + "overlay-pdfs": { + "tags": "叠加", + "header": "叠加 PDF ꖇ件", + "baseFile": { + "label": "é€‰ę‹©åŸŗē”€ PDF ꖇ件" + }, + "overlayFiles": { + "label": "é€‰ę‹©éœ€č¦å åŠ åœØåŸŗē”€äøŠēš„ PDF ꖇ件" + }, + "mode": { + "label": "é€‰ę‹©å åŠ ęØ”å¼", + "sequential": "ęŒ‰é”ŗåŗå åŠ ", + "interleaved": "äŗ¤é”™å åŠ ", + "fixedRepeat": "å›ŗå®šé‡å¤å åŠ " + }, + "counts": { + "label": "å åŠ ę¬”ę•°ļ¼ˆä»…é™å›ŗå®šé‡å¤å åŠ ęØ”å¼ļ¼‰", + "placeholder": "č¾“å…„ē”Øé€—å·åˆ†éš”ēš„ę¬”ę•°ļ¼ˆä¾‹å¦‚ļ¼š2,3,1)" + }, + "position": { + "label": "é€‰ę‹©å åŠ ä½ē½®", + "foreground": "å‰é¢ļ¼ˆäøŠé¢ļ¼‰", + "background": "åŽé¢ļ¼ˆäø‹é¢ļ¼‰" + }, + "submit": "ęäŗ¤" + }, + "split-by-sections": { + "tags": "ē« čŠ‚ę‹†åˆ†ć€åˆ†å‰²ć€č‡Ŗå®šä¹‰", + "title": "ęŒ‰ē…§å—ļ¼ˆSectionļ¼‰ę‹†åˆ† PDF", + "header": "将 PDF ę‹†åˆ†ęˆå—", + "horizontal": { + "label": "ę°“å¹³åˆ†å‰²", + "placeholder": "č¾“å…„ę°“å¹³åˆ†å‰²ę•°" + }, + "vertical": { + "label": "åž‚ē›“åˆ†å‰²", + "placeholder": "č¾“å…„åž‚ē›“åˆ†å‰²ę•°" + }, + "submit": "分割 PDF", + "merge": "ę˜Æå¦åˆå¹¶äøŗäø€äøŖ pdf" + }, + "AddStampRequest": { + "tags": "å›¾ē« ć€ę·»åŠ å›¾ē‰‡ć€å›¾ē‰‡å±…äø­ć€ę°“å°ć€PDFć€åµŒå…„ć€č‡Ŗå®šä¹‰", + "header": "ę·»åŠ å›¾ē« ", + "title": "ę·»åŠ å›¾ē« ", + "stampType": "å›¾ē« ē±»åž‹", + "stampText": "图章文字", + "stampImage": "图章图片", + "alphabet": "å­—ęÆč”Ø", + "fontSize": "字体/å›¾ē‰‡å¤§å°", + "rotation": "旋转角度", + "opacity": "é€ę˜Žåŗ¦", + "position": "定位", + "overrideX": "覆盖Xåę ‡", + "overrideY": "覆盖Yåę ‡", + "customMargin": "č‡Ŗå®šä¹‰å¤–č¾¹č·", + "customColor": "č‡Ŗå®šä¹‰ę–‡ęœ¬é¢œč‰²", + "submit": "ęäŗ¤" + }, + "removeImagePdf": { + "tags": "删除图像, é”µé¢ę“ä½œ, åŽē«Æ, ęœåŠ”ē«Æ" + }, + "splitPdfByChapters": { + "tags": "分割,ē« čŠ‚,书签,组织" + }, + "validateSignature": { + "tags": "ē­¾åļ¼ŒéŖŒčÆļ¼ŒéŖŒčÆļ¼ŒPDFļ¼ŒčÆä¹¦ļ¼Œę•°å­—ē­¾åļ¼ŒéŖŒčÆē­¾åļ¼ŒéŖŒčÆčÆä¹¦", + "title": "验证pdfē­¾å", + "header": "éŖŒčÆę•°å­—ē­¾å", + "selectPDF": "é€‰ę‹©å·²ē­¾åēš„pdfꖇ件", + "submit": "éŖŒčÆē­¾å", + "results": "éŖŒčÆē»“ęžœ", + "status": { + "_value": "ēŠ¶ę€", + "valid": "꜉ꕈ", + "invalid": "ꗠꕈ" + }, + "signer": "签署者", + "date": "ę—„ęœŸ", + "reason": "原因", + "location": "ä½ē½®", + "noSignatures": "ę­¤ę–‡ä»¶äø­ęœŖę‰¾åˆ°ē”µå­ē­¾å", + "chain": { + "invalid": "čÆä¹¦é“¾éŖŒčÆå¤±č“„ - ę— ę³•éŖŒčÆē­¾åč€…ēš„čŗ«ä»½" + }, + "trust": { + "invalid": "čÆä¹¦äøåœØäæ”ä»»å­˜å‚ØåŒŗäø­ - ę— ę³•éŖŒčÆę„ęŗ" + }, + "cert": { + "expired": "å‡­čÆå·²čæ‡ęœŸ", + "revoked": "凭证已被撤销", + "info": "凭证俔息", + "issuer": "å‘č”Œč€…", + "subject": "主题", + "serialNumber": "åŗåˆ—å·", + "validFrom": "ęœ‰ę•ˆęœŸč‡Ŗ", + "validUntil": "ęœ‰ę•ˆęœŸč‡³", + "algorithm": "算法", + "keySize": "密钄长度", + "version": "ē‰ˆęœ¬", + "keyUsage": "密钄用途", + "selfSigned": "č‡Ŗē­¾å", + "bits": "比特" + }, + "signature": { + "info": "ē­¾åäæ”ęÆ", + "_value": "ē­¾å", + "mathValid": "ē­¾ååœØę•°å­¦äøŠęœ‰ę•ˆļ¼Œä½†:" + }, + "selectCustomCert": "X.509 č‡Ŗē­¾åčÆä¹¦ļ¼ˆåÆé€‰ļ¼‰" + }, + "replace-color": { + "title": "ę›æę¢-åč½¬-é¢œč‰²", + "header": "ę›æę¢-åč½¬ PDF é¢œč‰²", + "selectText": { + "1": "ę›æę¢ęˆ–åč½¬é¢œč‰²é€‰é”¹", + "2": "é»˜č®¤ļ¼ˆé»˜č®¤é«˜åÆ¹ęÆ”åŗ¦é¢œč‰²ļ¼‰", + "3": "定制(å®šåˆ¶ēš„é¢œč‰²)", + "4": "å…Øåč½¬ļ¼ˆåč½¬ę‰€ęœ‰é¢œč‰²ļ¼‰", + "5": "é«˜åÆ¹ęÆ”åŗ¦é¢œč‰²é€‰é”¹", + "6": "黑底白字", + "7": "白底黑字", + "8": "黑底黄字", + "9": "黑底绿字", + "10": "é€‰ę‹©ę–‡ęœ¬é¢œč‰²", + "11": "é€‰ę‹©čƒŒę™Æé¢œč‰²" + }, + "submit": "取代" + }, + "replaceColorPdf": { + "tags": "ę›“ę¢é¢œč‰²ļ¼Œé”µé¢ę“ä½œļ¼ŒåŽē«Æļ¼ŒęœåŠ”å™Øē«Æ" + }, + "login": { + "title": "登录", + "header": "登录", + "signin": "登录", + "rememberme": "č®°ä½ęˆ‘", + "invalid": "ē”Øęˆ·åęˆ–åÆ†ē ę— ę•ˆć€‚", + "locked": "ę‚Øēš„č“¦ęˆ·å·²č¢«é”å®šć€‚", + "signinTitle": "请登录", + "ssoSignIn": "é€ščæ‡å•ē‚¹ē™»å½•ē™»å½•", + "oAuth2AutoCreateDisabled": "OAuth2 č‡ŖåŠØåˆ›å»ŗē”Øęˆ·å·²ē¦ē”Ø", + "oAuth2AdminBlockedUser": "ē›®å‰å·²é˜»ę­¢ęœŖę³Øå†Œē”Øęˆ·ēš„ę³Øå†Œęˆ–ē™»å½•ć€‚čÆ·č”ē³»ē®”ē†å‘˜ć€‚", + "oauth2RequestNotFound": "ę‰¾äøåˆ°éŖŒčÆčÆ·ę±‚", + "oauth2InvalidUserInfoResponse": "ę— ę•ˆēš„ē”Øęˆ·äæ”ęÆå“åŗ”", + "oauth2invalidRequest": "ę— ę•ˆčÆ·ę±‚", + "oauth2AccessDenied": "ę‹’ē»č®æé—®", + "oauth2InvalidTokenResponse": "ę— ę•ˆēš„ Token å“åŗ”", + "oauth2InvalidIdToken": "ę— ę•ˆēš„ Token", + "relyingPartyRegistrationNotFound": "No relying party registration found", + "userIsDisabled": "ē”Øęˆ·č¢«ē¦ē”Øļ¼Œē™»å½•å·²č¢«é˜»ę­¢ć€‚čÆ·č”ē³»ē®”ē†å‘˜ć€‚", + "alreadyLoggedIn": "ę‚Øå·²ē»ē™»å½•åˆ°äŗ†", + "alreadyLoggedIn2": "č®¾å¤‡ļ¼ŒčÆ·ę³Øé”€č®¾å¤‡åŽé‡čÆ•ć€‚", + "toManySessions": "ä½ å·²ē»ęœ‰å¤Ŗå¤šēš„ä¼ščÆäŗ†ć€‚čÆ·ę³Øé”€äø€äŗ›č®¾å¤‡åŽé‡čÆ•ć€‚", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF č½¬å•é”µ", + "header": "将 PDF č½¬ę¢äøŗå•é”µ", + "submit": "č½¬äøŗå•é”µ" + }, + "pageExtracter": { + "title": "ęå–é”µé¢", + "header": "ęå–é”µé¢", + "submit": "ęå–", + "placeholder": "ļ¼ˆä¾‹å¦‚ļ¼š1,2,8 ꈖ 4,7,12-16 ꈖ 2n-1)" + }, + "sanitizePDF": { + "title": "清理 PDF", + "header": "清理 PDF ꖇ件", + "selectText": { + "1": "移除 JavaScript ę“ä½œ", + "2": "ē§»é™¤åµŒå…„ēš„ę–‡ä»¶", + "3": "Remove XMP metadata", + "4": "ē§»é™¤é“¾ęŽ„", + "5": "移除字体", + "6": "Remove Document Info Metadata" + }, + "submit": "清理PDF" + }, + "adjustContrast": { + "title": "č°ƒę•“åÆ¹ęÆ”åŗ¦", + "header": "č°ƒę•“åÆ¹ęÆ”åŗ¦", + "contrast": "åÆ¹ęÆ”åŗ¦ļ¼š", + "brightness": "亮度:", + "saturation": "é„±å’Œåŗ¦ļ¼š", + "download": "äø‹č½½" + }, + "compress": { + "title": "åŽ‹ē¼©", + "header": "åŽ‹ē¼© PDF", + "credit": "ę­¤ęœåŠ”ä½æē”Øqpdfčæ›č”Œ PDF åŽ‹ē¼©/ä¼˜åŒ–ć€‚", + "grayscale": { + "label": "åŗ”ē”Øē°åŗ¦čæ›č”ŒåŽ‹ē¼©" + }, + "selectText": { + "1": { + "_value": "Compression Settings", + "1": "1-3 PDF compression,
4-6 lite image compression,
7-9 intense image compression Will dramatically reduce image quality" + }, + "2": "ä¼˜åŒ–ēŗ§åˆ«ļ¼š", + "4": "č‡ŖåŠØęØ”å¼ - č‡ŖåŠØč°ƒę•“č“Øé‡ä»„čŽ·å¾—ē²¾ē”®å¤§å°ēš„PDF", + "5": "é¢„ęœŸPDFå¤§å°ļ¼ˆä¾‹å¦‚ļ¼š25MB态10.8MB态25KB)" + }, + "submit": "åŽ‹ē¼©" + }, + "decrypt": { + "passwordPrompt": "ę­¤ę–‡ä»¶å—åÆ†ē äæęŠ¤ć€‚čÆ·č¾“å…„åÆ†ē ļ¼š", + "cancelled": "PDF ę“ä½œå·²å–ę¶ˆļ¼š {0}", + "noPassword": "ęœŖęä¾›åŠ åÆ† PDF ēš„åÆ†ē ļ¼š {0}", + "invalidPassword": "čÆ·ä½æē”Øę­£ē”®ēš„åÆ†ē é‡čÆ•ć€‚", + "invalidPasswordHeader": "åÆ†ē é”™čÆÆęˆ–äøę”ÆęŒēš„ PDF åŠ åÆ†ļ¼š {0}", + "unexpectedError": "å¤„ē†ę–‡ä»¶ę—¶å‘ē”Ÿé”™čÆÆć€‚čÆ·å†čÆ•äø€ę¬”ć€‚", + "serverError": "ęœåŠ”å™Øč§£åÆ†ę—¶å‘ē”Ÿé”™čÆÆļ¼š {0}", + "success": "ę–‡ä»¶č§£åÆ†ęˆåŠŸć€‚" + }, + "multiTool-advert": { + "message": "ę­¤åŠŸčƒ½ä¹Ÿé€‚ē”ØäŗŽęˆ‘ä»¬ēš„ā€œå¤šåŠŸčƒ½å·„å…·é”µé¢ā€ć€‚ęŸ„ēœ‹å®ƒä»„čŽ·å¾—å¢žå¼ŗēš„é€é”µ UI ä»„åŠå…¶ä»–åŠŸčƒ½ļ¼" + }, + "pageRemover": { + "title": "删除锵面", + "header": "PDF é”µé¢ē§»é™¤å™Ø", + "pagesToDelete": "č¦åˆ é™¤ēš„é”µé¢ļ¼ˆč¾“å…„äø€äøŖē”Øé€—å·åˆ†éš”ēš„é”µē åˆ—č”Øļ¼‰ļ¼š", + "submit": "删除锵面", + "placeholder": "ļ¼ˆä¾‹å¦‚ļ¼š1,2,6 ꈖ 1-10,15-30)" + }, + "imageToPDF": { + "title": "图片转 PDF", + "header": "å°†å›¾ē‰‡č½¬ę¢äøŗ PDF", + "submit": "č½¬ę¢", + "selectLabel": "图片适应选锹", + "fillPage": "唫充锵面", + "fitDocumentToImage": "é€‚åŗ”å›¾ē‰‡å¤§å°", + "maintainAspectRatio": "äæęŒēŗµęØŖęÆ”ä¾‹", + "selectText": { + "2": "č‡ŖåŠØę—‹č½¬ PDF", + "3": "å¤šę–‡ä»¶é€»č¾‘ļ¼ˆä»…åœØå¤„ē†å¤šäøŖå›¾åƒę—¶åÆē”Øļ¼‰", + "4": "åˆå¹¶ęˆäø€äøŖ PDF ꖇ件", + "5": "č½¬ę¢äøŗē‹¬ē«‹ēš„ PDF ꖇ件" + } + }, + "PDFToCSV": { + "title": "PDF 转 CSV", + "header": "将 PDF č½¬ę¢äøŗ CSV", + "prompt": "é€‰ę‹©éœ€č¦ęå–č”Øę ¼ēš„é”µé¢", + "submit": "ęå–" + }, + "split-by-size-or-count": { + "title": "ęŒ‰ē…§å¤§å°ęˆ–ę•°ē›®ę‹†åˆ† PDF", + "header": "ęŒ‰ē…§å¤§å°ęˆ–ę•°ē›®ę‹†åˆ† PDF", + "type": { + "label": "é€‰ę‹©ę‹†åˆ†ē±»åž‹", + "size": "ęŒ‰ē…§å¤§å°", + "pageCount": "ęŒ‰ē…§é”µę•°", + "docCount": "ęŒ‰ē…§ę–‡ę”£ę•°" + }, + "value": { + "label": "输兄数值", + "placeholder": "č¾“å…„å¤§å°ļ¼ˆä¾‹å¦‚ļ¼š2MBꈖ3KBļ¼‰ęˆ–ę•°ē›®ļ¼ˆä¾‹å¦‚ļ¼š5)" + }, + "submit": "ęäŗ¤" + }, + "printFile": { + "title": "ę‰“å°ę–‡ä»¶", + "header": "ä½æē”Øę‰“å°ęœŗę‰“å°ę–‡ä»¶", + "selectText": { + "1": "é€‰ę‹©č¦ę‰“å°ēš„ę–‡ä»¶", + "2": "č¾“å…„ę‰“å°ęœŗåē§°" + }, + "submit": "ę‰“å°" + }, + "licenses": { + "nav": "č®øåÆčÆ", + "title": "ē¬¬äø‰ę–¹č®øåÆčÆ", + "header": "ē¬¬äø‰ę–¹č®øåÆčÆ", + "module": "ęØ”å—", + "version": "ē‰ˆęœ¬", + "license": "č®øåÆčÆ" + }, + "survey": { + "nav": "é—®å·č°ƒęŸ„", + "title": "Stirling-PDF é—®å·č°ƒęŸ„", + "description": "Stirling-PDF ę²”ęœ‰č·ŸčøŖå™Øļ¼Œę‰€ä»„ęˆ‘ä»¬åøŒęœ›å¬å–ē”Øęˆ·ēš„ę„č§ę„ę”¹čæ› Stirling-PDF!", + "changes": "č‡ŖäøŠę¬”č°ƒęŸ„ä»„ę„ļ¼ŒStirling-PDF å·²ē»å‘ē”Ÿäŗ†å˜åŒ–ļ¼č¦äŗ†č§£ę›“å¤šäæ”ęÆļ¼ŒčÆ·åœØę­¤å¤„ęŸ„ēœ‹ęˆ‘ä»¬ēš„åšå®¢ę–‡ē« ļ¼š", + "changes2": "é€ščæ‡čæ™äŗ›å˜åŒ–ļ¼Œęˆ‘ä»¬å¾—åˆ°äŗ†å•†äøšę”ÆęŒå’Œčµ„é‡‘ę“åŠ©ć€‚", + "please": "čÆ·č€ƒč™‘å‚åŠ ęˆ‘ä»¬ēš„č°ƒęŸ„ļ¼", + "disabled": "ļ¼ˆč°ƒęŸ„å¼¹å‡ŗēŖ—å£å°†åœØåŽē»­ę›“ę–°äø­č¢«ē¦ē”Øļ¼Œä½†åÆåœØé”µč„šå¤„ęŸ„ēœ‹ļ¼‰", + "button": "å‚äøŽč°ƒęŸ„", + "dontShowAgain": "äøå†ę˜¾ē¤ŗ", + "meeting": { + "1": "If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session.", + "2": "This is a chance to:", + "3": "Get help with deployment, integrations, or troubleshooting", + "4": "Provide direct feedback on performance, edge cases, and feature gaps", + "5": "Help us refine Stirling PDF for real-world enterprise use", + "6": "If you're interested, you can book time with our team directly. (English speaking only)", + "7": "Looking forward to digging into your use cases and making Stirling PDF even better!", + "notInterested": "Not a business and/or interested in a meeting?", + "button": "Book meeting" + } + }, + "removeImage": { + "title": "删除图像", + "header": "删除图像", + "removeImage": "删除图像", + "submit": "删除图像" + }, + "splitByChapters": { + "title": "ęŒ‰ē« čŠ‚ę‹†åˆ† PDF", + "header": "ęŒ‰ē« čŠ‚ę‹†åˆ† PDF", + "bookmarkLevel": "书签级别", + "includeMetadata": "åŒ…å«å…ƒę•°ę®", + "allowDuplicates": "å…č®øé‡å¤", + "desc": { + "1": "ę­¤å·„å…·ę ¹ę®ē« čŠ‚ē»“ęž„å°†PDFę–‡ä»¶ę‹†åˆ†äøŗå¤šäøŖPDF怂", + "2": "ä¹¦ē­¾ēŗ§åˆ«ļ¼šé€‰ę‹©ē”ØäŗŽę‹†åˆ†ēš„ä¹¦ē­¾ēŗ§åˆ«ļ¼ˆ0蔨示锶级,1č”Øē¤ŗäŗŒēŗ§ē­‰ļ¼‰ć€‚", + "3": "åŒ…å«å…ƒę•°ę®ļ¼šå¦‚ęžœé€‰äø­ļ¼ŒåŽŸå§‹PDFēš„å…ƒę•°ę®å°†åŒ…å«åœØęÆäøŖę‹†åˆ†ēš„PDF中。", + "4": "å…č®øé‡å¤ļ¼šå¦‚ęžœé€‰äø­ļ¼Œå…č®øåŒäø€é”µé¢äøŠēš„å¤šäøŖä¹¦ē­¾åˆ›å»ŗå•ē‹¬ēš„PDF怂" + }, + "submit": "ę‹†åˆ† PDF" + }, + "fileChooser": { + "click": "单击", + "or": "ꈖ", + "dragAndDrop": "拖放文件", + "dragAndDropPDF": "拖放PDFꖇ件", + "dragAndDropImage": "拖放图片文件", + "hoveredDragAndDrop": "ę‹–ę”¾ę–‡ä»¶åˆ°ę­¤å¤„", + "extractPDF": "处理中..." + }, + "releases": { + "footer": "ē‰ˆęœ¬", + "title": "ē‰ˆęœ¬čÆ“ę˜Ž", + "header": "ē‰ˆęœ¬čÆ“ę˜Ž", + "current": { + "version": "å½“å‰ē‰ˆęœ¬" + }, + "note": "ē‰ˆęœ¬čÆ“ę˜Žä»…ęä¾›č‹±ę–‡ē‰ˆęœ¬" + }, + "cookieBanner": { + "popUp": { + "title": "How we use Cookies", + "description": { + "1": "We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love.", + "2": "If you’d rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly." + }, + "acceptAllBtn": "Okay", + "acceptNecessaryBtn": "No Thanks", + "showPreferencesBtn": "Manage preferences" + }, + "preferencesModal": { + "title": "Consent Preferences Center", + "acceptAllBtn": "Accept all", + "acceptNecessaryBtn": "Reject all", + "savePreferencesBtn": "Save preferences", + "closeIconLabel": "Close modal", + "serviceCounterLabel": "Service|Services", + "subtitle": "Cookie Usage", + "description": { + "1": "Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users.", + "2": "Stirling PDF cannot—and will never—track or access the content of the documents you use.", + "3": "Your privacy and trust are at the core of what we do." + }, + "necessary": { + "title": { + "1": "Strictly Necessary Cookies", + "2": "Always Enabled" + }, + "description": "These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they can’t be turned off." + }, + "analytics": { + "title": "Analytics", + "description": "These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with." + } + } + } +} \ No newline at end of file diff --git a/frontend/public/locales/zh-TW/translation.json b/frontend/public/locales/zh-TW/translation.json new file mode 100644 index 000000000..43d456623 --- /dev/null +++ b/frontend/public/locales/zh-TW/translation.json @@ -0,0 +1,1561 @@ +{ + "language": { + "direction": "ltr" + }, + "addPageNumbers": { + "fontSize": "字型大小", + "fontName": "å­—åž‹åēØ±", + "title": "ę–°å¢žé ē¢¼", + "header": "ę–°å¢žé ē¢¼", + "selectText": { + "1": "選擇 PDF ęŖ”ę”ˆļ¼š", + "2": "é‚Šč·å¤§å°", + "3": "ä½ē½®", + "4": "čµ·å§‹č™Ÿē¢¼", + "5": "č¦ē·Øč™Ÿēš„é é¢", + "6": "自訂文字" + }, + "customTextDesc": "自訂文字", + "numberPagesDesc": "č¦ē·Øč™Ÿēš„é é¢ļ¼Œé čØ­ē‚ŗ 'å…ØéƒØ'ļ¼Œä¹ŸåÆä½æē”Ø 1-5 ꈖ 2,5,9 ē­‰ę ¼å¼", + "customNumberDesc": "預設為 {n}ļ¼Œä¹ŸęŽ„å— '頁面 {n} 共 {total}','文字-{n}','{filename}-{n}'", + "submit": "ę–°å¢žé ē¢¼" + }, + "pdfPrompt": "選擇 PDF ęŖ”ę”ˆ", + "multiPdfPrompt": "éøę“‡å¤šå€‹ PDF ęŖ”ę”ˆ", + "multiPdfDropPrompt": "éøę“‡ļ¼ˆęˆ–ę‹–ę”¾ļ¼‰ę‰€ęœ‰éœ€č¦ēš„ PDF ęŖ”ę”ˆ", + "imgPrompt": "éøę“‡åœ–ē‰‡", + "genericSubmit": "送出", + "uploadLimit": "ęŖ”ę”ˆå¤§å°äøŠé™ļ¼š", + "uploadLimitExceededSingular": "å¤Ŗå¤§ć€‚å…čØ±ēš„ęœ€å¤§ęŖ”ę”ˆå¤§å°ē‚ŗ", + "uploadLimitExceededPlural": "å¤Ŗå¤§ć€‚å…čØ±ēš„ęœ€å¤§ęŖ”ę”ˆå¤§å°ē‚ŗ", + "processTimeWarning": "č­¦å‘Šļ¼šę­¤éŽēØ‹åÆčƒ½é•·é”äø€åˆ†é˜ļ¼Œå…·é«”å–ę±ŗę–¼ęŖ”ę”ˆå¤§å°", + "pageOrderPrompt": "č‡ŖčØ‚é é¢é †åŗļ¼ˆč¼øå…„ä»„é€—č™Ÿåˆ†éš”ēš„é ē¢¼ęˆ–å‡½å¼ļ¼Œå¦‚ 2n+1ļ¼‰ļ¼š", + "pageSelectionPrompt": "č‡ŖčØ‚é é¢éøę“‡ļ¼ˆč¼øå…„ä»„é€—č™Ÿåˆ†éš”ēš„é ē¢¼ 1态5态6 ꈖ 2n+1 ē­‰å‡½å¼ēš„ęø…å–®ļ¼‰ļ¼š", + "goToPage": "前往", + "true": "是", + "false": "否", + "unknown": "未矄", + "save": "儲存", + "saveToBrowser": "å„²å­˜åˆ°ē€č¦½å™Ø", + "close": "關閉", + "filesSelected": "å·²éøę“‡ēš„ęŖ”ę”ˆ", + "noFavourites": "é‚„ę²’ęœ‰åŠŸčƒ½č¢«ę”¶č—", + "downloadComplete": "äø‹č¼‰å®Œęˆ", + "bored": "ē­‰å¾…ę™‚č¦ŗå¾—ē„”čŠļ¼Ÿ", + "alphabet": "å­—ęÆč”Ø", + "downloadPdf": "下載 PDF", + "text": "文字", + "font": "字型", + "selectFillter": "-- 選擇 --", + "pageNum": "頁碼", + "sizes": { + "small": "小", + "medium": "äø­", + "large": "大", + "x-large": "特大" + }, + "error": { + "pdfPassword": "PDF ęŖ”ę”ˆå·²åŠ åÆ†ļ¼Œä½†ęœŖęä¾›åÆ†ē¢¼ęˆ–åÆ†ē¢¼äøę­£ē¢ŗ", + "_value": "錯誤", + "sorry": "å¾ˆęŠ±ę­‰é€ ęˆę‚Øēš„å›°ę“¾ļ¼", + "needHelp": "éœ€č¦å”åŠ©ęˆ–ē™¼ē¾å•é”Œļ¼Ÿ", + "contactTip": "å¦‚ęžœę‚Øä»ē„¶é‡åˆ°å•é”Œļ¼Œč«‹äøč¦ēŒ¶č±«ļ¼ŒéšØę™‚å‘ęˆ‘å€‘å°‹ę±‚å”åŠ©ć€‚ę‚ØåÆä»„åœØęˆ‘å€‘ēš„ GitHub é é¢å›žå ±å•é”Œļ¼Œęˆ–é€éŽ Discord č·Ÿęˆ‘å€‘čÆēµ”ļ¼š", + "404": { + "head": "404 - ę‰¾äøåˆ°é é¢ | ē³Ÿē³•ļ¼Œęˆ‘å€‘åœØēØ‹å¼ē¢¼äø­čæ·č·Æäŗ†ļ¼", + "1": "ęˆ‘å€‘ä¼¼ä¹Žę‰¾äøåˆ°ę‚Øę­£åœØå°‹ę‰¾ēš„é é¢ć€‚", + "2": "ē™¼ē”Ÿäŗ†äø€äŗ›éŒÆčŖ¤" + }, + "github": "在 GitHub äøŠå›žå ±å•é”Œ", + "showStack": "é”Æē¤ŗå †ē–Ščæ½č¹¤", + "copyStack": "č¤‡č£½å †ē–Ščæ½č¹¤", + "githubSubmit": "GitHub - 回報問锌", + "discordSubmit": "Discord - ē™¼č”Øę”Æę“ę–‡ē« " + }, + "delete": "åˆŖé™¤", + "username": "ä½æē”Øč€…åēØ±", + "password": "密碼", + "welcome": "ę­”čæŽ", + "property": "屬性", + "black": "黑色", + "white": "白色", + "red": "瓅色", + "green": "綠色", + "blue": "č—č‰²", + "custom": "自訂...", + "WorkInProgess": "å·„ä½œę­£åœØé€²č”Œäø­ļ¼ŒåÆčƒ½ē„”ę³•å·„ä½œęˆ–ęœ‰å•é”Œļ¼Œč«‹å ±å‘Šä»»ä½•å•é”Œļ¼", + "poweredBy": "Powered by", + "yes": "是", + "no": "否", + "changedCredsMessage": "ę†‘č­‰å·²č®Šę›“ļ¼", + "notAuthenticatedMessage": "ä½æē”Øč€…ęœŖé€šéŽé©—č­‰ć€‚", + "userNotFoundMessage": "ę‰¾äøåˆ°ä½æē”Øč€…ć€‚", + "incorrectPasswordMessage": "ē›®å‰åÆ†ē¢¼äøę­£ē¢ŗć€‚", + "usernameExistsMessage": "ę–°ä½æē”Øč€…åēØ±å·²å­˜åœØć€‚", + "invalidUsernameMessage": "ē„”ę•ˆēš„ä½æē”Øč€…åēØ±ć€‚ä½æē”Øč€…åēØ±åŖčƒ½åŒ…å«å­—ęÆć€ę•øå­—å’Œä»„äø‹ē‰¹ę®Šå­—å…ƒ @._+- ęˆ–åæ…é ˆę˜Æęœ‰ę•ˆēš„é›»å­éƒµä»¶åœ°å€ć€‚", + "invalidPasswordMessage": "åÆ†ē¢¼äøčƒ½ē‚ŗē©ŗļ¼Œäø”é–‹é ­å’Œēµå°¾äøčƒ½ęœ‰ē©ŗę ¼ć€‚", + "confirmPasswordErrorMessage": "ę–°åÆ†ē¢¼čˆ‡ē¢ŗčŖę–°åÆ†ē¢¼åæ…é ˆē›øē¬¦ć€‚", + "deleteCurrentUserMessage": "ē„”ę³•åˆŖé™¤ē›®å‰ē™»å…„ēš„ä½æē”Øč€…ć€‚", + "deleteUsernameExistsMessage": "ä½æē”Øč€…åēØ±äøå­˜åœØļ¼Œē„”ę³•åˆŖé™¤ć€‚", + "downgradeCurrentUserMessage": "ē„”ę³•é™ē“šē›®å‰ä½æē”Øč€…ēš„č§’č‰²", + "disabledCurrentUserMessage": "ē„”ę³•åœē”Øē›®å‰ä½æē”Øč€…", + "downgradeCurrentUserLongMessage": "ē„”ę³•é™ē“šē›®å‰ä½æē”Øč€…ēš„č§’č‰²ć€‚å› ę­¤ļ¼Œå°‡äøęœƒé”Æē¤ŗē›®å‰ä½æē”Øč€…ć€‚", + "userAlreadyExistsOAuthMessage": "使用者已經仄 OAuth2 ä½æē”Øč€…čŗ«ä»½å­˜åœØć€‚", + "userAlreadyExistsWebMessage": "ä½æē”Øč€…å·²ē¶“ä»„ē¶²é ä½æē”Øč€…čŗ«ä»½å­˜åœØć€‚", + "oops": "å“Žå‘€ļ¼", + "help": "čŖŖę˜Ž", + "goHomepage": "前往首頁", + "joinDiscord": "åŠ å…„ęˆ‘å€‘ēš„ Discord ä¼ŗęœå™Ø", + "seeDockerHub": "造訪 Docker Hub å„²å­˜åŗ«", + "visitGithub": "造訪 GitHub 專攈", + "donate": "ęę¬¾", + "color": "é”č‰²", + "sponsor": "蓊助", + "info": "č³‡čØŠ", + "pro": "å°ˆę„­ē‰ˆ", + "page": "頁面", + "pages": "頁面", + "loading": "載兄中...", + "addToDoc": "ę–°å¢žč‡³ę–‡ä»¶", + "reset": "é‡čØ­", + "apply": "儗用", + "noFileSelected": "ęœŖéøę“‡ęŖ”ę”ˆļ¼Œč«‹äøŠå‚³äø€å€‹ć€‚", + "legal": { + "privacy": "éš±ē§ę¬Šę”æē­–", + "terms": "ä½æē”Øę¢ę¬¾", + "accessibility": "ē„”éšœē¤™ę€§č²ę˜Ž", + "cookie": "Cookie 政策", + "impressum": "ē‰ˆęœ¬čŖŖę˜Ž", + "showCookieBanner": "Cookie åå„½čØ­å®š" + }, + "pipeline": { + "header": "ē®”é“åŠŸčƒ½éøå–®ļ¼ˆęø¬č©¦ē‰ˆļ¼‰", + "uploadButton": "äøŠå‚³č‡ŖčØ‚čØ­å®š", + "configureButton": "設定", + "defaultOption": "自訂", + "submitButton": "送出", + "help": "ē®”é“åŠŸčƒ½čŖŖę˜Ž", + "scanHelp": "č³‡ę–™å¤¾ęŽƒęčŖŖę˜Ž", + "deletePrompt": "ę‚Øē¢ŗå®šč¦åˆŖé™¤ę­¤ē®”é“å—Žļ¼Ÿ", + "tags": "č‡Ŗå‹•åŒ–,åŗåˆ—,ęŒ‡ä»¤ē¢¼,批欔處理", + "title": "箔道" + }, + "pipelineOptions": { + "header": "ē®”é“čØ­å®š", + "pipelineNameLabel": "ē®”é“åēØ±", + "saveSettings": "å„²å­˜ę“ä½œčØ­å®š", + "pipelineNamePrompt": "č«‹åœØę­¤č¼øå…„ē®”é“åēØ±", + "selectOperation": "éøę“‡ę“ä½œ", + "addOperationButton": "ę–°å¢žę“ä½œ", + "pipelineHeader": "ē®”é“ļ¼š", + "saveButton": "下載", + "validateButton": "é©—č­‰" + }, + "enterpriseEdition": { + "button": "å‡ē“šč‡³å°ˆę„­ē‰ˆ", + "warning": "ę­¤åŠŸčƒ½åƒ…ęä¾›ēµ¦å°ˆę„­ē‰ˆä½æē”Øč€…ä½æē”Øć€‚", + "yamlAdvert": "Stirling PDF å°ˆę„­ē‰ˆę”Æę“ YAML čØ­å®šęŖ”å’Œå…¶ä»–å–®äø€ē™»å…„ (SSO) åŠŸčƒ½ć€‚", + "ssoAdvert": "éœ€č¦ę›“å¤šä½æē”Øč€…ē®”ē†åŠŸčƒ½å—Žļ¼Ÿč«‹åƒč€ƒ Stirling PDF å°ˆę„­ē‰ˆ" + }, + "analytics": { + "title": "ę‚Øęƒ³å”åŠ©ę”¹å–„ Stirling PDF å—Žļ¼Ÿ", + "paragraph1": "Stirling PDF ęœ‰éøę“‡ę€§ēš„åˆ†ęžåŠŸčƒ½ļ¼ŒåÆå¹«åŠ©ęˆ‘å€‘ę”¹é€²ē”¢å“ć€‚ęˆ‘å€‘äøęœƒčæ½č¹¤ä»»ä½•å€‹äŗŗč³‡čØŠęˆ–ęŖ”ę”ˆå…§å®¹ć€‚", + "paragraph2": "č«‹č€ƒę…®å•Ÿē”Øåˆ†ęžåŠŸčƒ½ļ¼Œä»„å”åŠ© Stirling-PDF ęˆé•·äø¦č®“ęˆ‘å€‘ę›“äŗ†č§£ä½æē”Øč€…éœ€ę±‚ć€‚", + "enable": "å•Ÿē”Øåˆ†ęžåŠŸčƒ½", + "disable": "åœē”Øåˆ†ęžåŠŸčƒ½", + "settings": "ę‚ØåÆä»„åœØ config/settings.yml ęŖ”ę”ˆäø­č®Šę›“åˆ†ęžåŠŸčƒ½ēš„čØ­å®š" + }, + "navbar": { + "favorite": "ęˆ‘ēš„ęœ€ę„›", + "recent": "ęœ€ę–°čˆ‡čæ‘ęœŸę›“ę–°", + "darkmode": "ę·±č‰²ęØ”å¼", + "language": "čŖžčØ€", + "settings": "設定", + "allTools": "å·„å…·", + "multiTool": "č¤‡åˆå·„å…·", + "search": "ęœå°‹", + "sections": { + "organize": "敓理", + "convertTo": "č½‰ę›ē‚ŗ PDF", + "convertFrom": "從 PDF č½‰ę›", + "security": "ē°½ē« čˆ‡å®‰å…Øę€§", + "advance": "進階", + "edit": "ęŖ¢č¦–čˆ‡ē·Øč¼Æ", + "popular": "ē†±é–€åŠŸčƒ½" + } + }, + "settings": { + "title": "設定", + "update": "ęœ‰ę›“ę–°åÆē”Ø", + "updateAvailable": "ē›®å‰å®‰č£ēš„ē‰ˆęœ¬ę˜Æ {0}ć€‚ęœ‰ę–°ē‰ˆęœ¬ļ¼ˆ{1}ļ¼‰åÆä¾›ä½æē”Øć€‚", + "appVersion": "ę‡‰ē”ØēØ‹å¼ē‰ˆęœ¬ļ¼š", + "downloadOption": { + "title": "éøę“‡äø‹č¼‰éøé …ļ¼ˆé©ē”Øę–¼å–®äø€ęŖ”ę”ˆéžå£“ēø®äø‹č¼‰ļ¼‰ļ¼š", + "1": "åœØåŒäø€č¦–ēŖ—äø­é–‹å•Ÿ", + "2": "åœØę–°č¦–ēŖ—äø­é–‹å•Ÿ", + "3": "äø‹č¼‰ęŖ”ę”ˆ" + }, + "zipThreshold": "ē•¶äø‹č¼‰ęŖ”ę”ˆę•øé‡č¶…éŽę­¤ę•øå€¼ę™‚ļ¼Œå°‡ęŖ”ę”ˆå£“ēø®", + "signOut": "登出", + "accountSettings": "åø³č™ŸčØ­å®š", + "bored": { + "help": "å•Ÿē”Øå½©č›‹éŠęˆ²" + }, + "cacheInputs": { + "name": "å„²å­˜č”Øå–®č¼øå…„", + "help": "å•Ÿē”Øę­¤åŠŸčƒ½ä»„å„²å­˜å…ˆå‰ä½æē”Øēš„č¼øå…„ļ¼Œä»„ä¾æę—„å¾Œä½æē”Ø" + } + }, + "changeCreds": { + "title": "變ꛓꆑ證", + "header": "ę›“ę–°ę‚Øēš„åø³č™Ÿč©³ē“°č³‡čØŠ", + "changePassword": "ę‚Øę­£åœØä½æē”Øé čØ­ē™»å…„ę†‘č­‰ć€‚č«‹č¼øå…„ę–°åÆ†ē¢¼", + "newUsername": "ę–°ä½æē”Øč€…åēØ±", + "oldPassword": "ē›®å‰åÆ†ē¢¼", + "newPassword": "新密碼", + "confirmNewPassword": "ē¢ŗčŖę–°åÆ†ē¢¼", + "submit": "é€å‡ŗč®Šę›“" + }, + "account": { + "title": "åø³č™ŸčØ­å®š", + "accountSettings": "åø³č™ŸčØ­å®š", + "adminSettings": "ē®”ē†å“”čØ­å®š - ęŖ¢č¦–å’Œę–°å¢žä½æē”Øč€…", + "userControlSettings": "ä½æē”Øč€…ęŽ§åˆ¶čØ­å®š", + "changeUsername": "äæ®ę”¹ä½æē”Øč€…åēØ±", + "newUsername": "ę–°ä½æē”Øč€…åēØ±", + "password": "ē¢ŗčŖåÆ†ē¢¼", + "oldPassword": "čˆŠåÆ†ē¢¼", + "newPassword": "新密碼", + "changePassword": "修改密碼", + "confirmNewPassword": "ē¢ŗčŖę–°åÆ†ē¢¼", + "signOut": "登出", + "yourApiKey": "ę‚Øēš„ API 金鑰", + "syncTitle": "å°‡ē€č¦½å™ØčØ­å®ščˆ‡åø³č™ŸåŒę­„", + "settingsCompare": "čØ­å®šęÆ”č¼ƒļ¼š", + "property": "屬性", + "webBrowserSettings": "ē¶²é ē€č¦½å™ØčØ­å®š", + "syncToBrowser": "åŒę­„åø³č™Ÿ → ē€č¦½å™Ø", + "syncToAccount": "åŒę­„åø³č™Ÿ ← ē€č¦½å™Ø" + }, + "adminUserSettings": { + "title": "ä½æē”Øč€…ęŽ§åˆ¶čØ­å®š", + "header": "ē®”ē†å“”ä½æē”Øč€…ęŽ§åˆ¶čØ­å®š", + "admin": "箔理哔", + "user": "使用者", + "addUser": "ę–°å¢žä½æē”Øč€…", + "deleteUser": "åˆŖé™¤ä½æē”Øč€…", + "confirmDeleteUser": "ē¢ŗå®šč¦åˆŖé™¤ę­¤ä½æē”Øč€…ļ¼Ÿ", + "confirmChangeUserStatus": "ę˜Æå¦č¦åœē”Ø/å•Ÿē”Øę­¤ä½æē”Øč€…ļ¼Ÿ", + "usernameInfo": "ä½æē”Øč€…åēØ±åŖčƒ½åŒ…å«å­—ęÆć€ę•øå­—å’Œä»„äø‹ē‰¹ę®Šå­—å…ƒ @._+- ęˆ–åæ…é ˆę˜Æęœ‰ę•ˆēš„é›»å­éƒµä»¶åœ°å€ć€‚", + "roles": "角色", + "role": "角色", + "actions": "ę“ä½œ", + "apiUser": "å—é™åˆ¶ēš„ API 使用者", + "extraApiUser": "é”å¤–å—é™åˆ¶ēš„ API 使用者", + "webOnlyUser": "åƒ…ē¶²é ē‰ˆä½æē”Øč€…", + "demoUser": "ē¤ŗēÆ„ä½æē”Øč€…ļ¼ˆē„”č‡ŖčØ‚čØ­å®šļ¼‰", + "internalApiUser": "å…§éƒØ API 使用者", + "forceChange": "å¼·åˆ¶ä½æē”Øč€…åœØē™»å…„ę™‚č®Šę›“åÆ†ē¢¼", + "submit": "å„²å­˜ä½æē”Øč€…", + "changeUserRole": "č®Šę›“ä½æē”Øč€…č§’č‰²", + "authenticated": "已驗證", + "editOwnProfil": "ē·Øč¼Æč‡Ŗå·±ēš„å€‹äŗŗč³‡ę–™", + "enabledUser": "å·²å•Ÿē”Øä½æē”Øč€…", + "disabledUser": "å·²åœē”Øä½æē”Øč€…", + "activeUsers": "ä½æē”Øäø­ēš„ä½æē”Øč€…ļ¼š", + "disabledUsers": "å·²åœē”Øēš„ä½æē”Øč€…ļ¼š", + "totalUsers": "ä½æē”Øč€…ēø½ę•øļ¼š", + "lastRequest": "ęœ€å¾Œč«‹ę±‚ę™‚é–“", + "usage": "ęŖ¢č¦–ä½æē”Øęƒ…ę³" + }, + "endpointStatistics": { + "title": "ē«Æé»žēµ±čØˆ", + "header": "ē«Æé»žēµ±čØˆ", + "top10": "前 10 名", + "top20": "前 20 名", + "all": "å…ØéƒØ", + "refresh": "é‡ę–°ę•“ē†", + "includeHomepage": "包含首頁 ('/')", + "includeLoginPage": "åŒ…å«ē™»å…„é é¢ ('/login')", + "totalEndpoints": "ē«Æé»žēø½ę•ø", + "totalVisits": "總造訪欔數", + "showing": "锯示中", + "selectedVisits": "éøå–ēš„é€ čØŖę¬”ę•ø", + "endpoint": "ē«Æé»ž", + "visits": "造訪欔數", + "percentage": "ē™¾åˆ†ęÆ”", + "loading": "載兄中...", + "failedToLoad": "ē„”ę³•č¼‰å…„ē«Æé»žč³‡ę–™ć€‚č«‹å˜—č©¦é‡ę–°ę•“ē†ć€‚", + "home": "首頁", + "login": "登兄", + "top": "前", + "numberOfVisits": "造訪欔數", + "visitsTooltip": "é€ čØŖę¬”ę•øļ¼š{0}ļ¼ˆēø½ę•øēš„ {1}%)", + "retry": "é‡č©¦" + }, + "database": { + "title": "č³‡ę–™åŗ«åŒÆå…„/åŒÆå‡ŗ", + "header": "č³‡ę–™åŗ«åŒÆå…„/åŒÆå‡ŗ", + "fileName": "ęŖ”ę”ˆåēØ±", + "creationDate": "å»ŗē«‹ę—„ęœŸ", + "fileSize": "ęŖ”ę”ˆå¤§å°", + "deleteBackupFile": "åˆŖé™¤å‚™ä»½ęŖ”ę”ˆ", + "importBackupFile": "åŒÆå…„å‚™ä»½ęŖ”ę”ˆ", + "createBackupFile": "å»ŗē«‹å‚™ä»½ęŖ”ę”ˆ", + "downloadBackupFile": "äø‹č¼‰å‚™ä»½ęŖ”ę”ˆ", + "info_1": "åœØåŒÆå…„č³‡ę–™ę™‚ļ¼Œē¢ŗäæę­£ē¢ŗēš„ēµę§‹č‡³é—œé‡č¦ć€‚å¦‚ęžœę‚Øäøē¢ŗå®šč‡Ŗå·±åœØåšä»€éŗ¼ļ¼Œč«‹å°‹ę±‚å°ˆę„­äŗŗå£«ēš„å»ŗč­°å’Œę”Æę“ć€‚ēµę§‹éŒÆčŖ¤åÆčƒ½ęœƒå°Žč‡“ę‡‰ē”ØēØ‹å¼ę•…éšœļ¼Œē”šč‡³å®Œå…Øē„”ę³•åŸ·č”Œę‡‰ē”ØēØ‹å¼ć€‚", + "info_2": "äøŠå‚³ę™‚ęŖ”ę”ˆåēØ±äø¦äøé‡č¦ć€‚äøŠå‚³å¾Œå°‡é‡ę–°å‘½åē‚ŗ backup_user_yyyyMMddHHmm.sql ę ¼å¼ļ¼Œä»„ē¢ŗäæå‘½åč¦ēÆ„äø€č‡“ć€‚", + "submit": "åŒÆå…„å‚™ä»½", + "importIntoDatabaseSuccessed": "ęˆåŠŸåŒÆå…„č³‡ę–™åŗ«", + "backupCreated": "č³‡ę–™åŗ«å‚™ä»½ęˆåŠŸ", + "fileNotFound": "ę‰¾äøåˆ°ęŖ”ę”ˆ", + "fileNullOrEmpty": "ęŖ”ę”ˆäøå¾—ē‚ŗē©ŗęˆ–ē©ŗē™½", + "failedImportFile": "åŒÆå…„ęŖ”ę”ˆå¤±ę•—", + "notSupported": "ę‚Øēš„č³‡ę–™åŗ«é€£ē·šäøę”Æę“ę­¤åŠŸčƒ½ć€‚" + }, + "session": { + "expired": "ę‚Øēš„å·„ä½œéšŽę®µå·²éŽęœŸć€‚č«‹é‡ę–°ę•“ē†é é¢äø¦å†č©¦äø€ę¬”ć€‚", + "refreshPage": "é‡ę–°ę•“ē†é é¢" + }, + "home": { + "desc": "ę‚Øēš„ęœ¬ę©Ÿäø€ē«™å¼ PDF č§£ę±ŗę–¹ę”ˆć€‚", + "searchBar": "ęœå°‹åŠŸčƒ½...", + "viewPdf": { + "title": "檢視/編輯 PDF", + "desc": "ęŖ¢č¦–ć€čØ»é‡‹ć€ę–°å¢žę–‡å­—ęˆ–åœ–ē‰‡" + }, + "setFavorites": "čØ­å®šęˆ‘ēš„ęœ€ę„›", + "hideFavorites": "éš±č—ęˆ‘ēš„ęœ€ę„›", + "showFavorites": "é”Æē¤ŗęˆ‘ēš„ęœ€ę„›", + "legacyHomepage": "čˆŠē‰ˆé¦–é ", + "newHomePage": "å˜—č©¦ä½æē”Øå…Øę–°é¦–é ļ¼", + "alphabetical": "ęŒ‰ē…§å­—ęÆęŽ’åŗ", + "globalPopularity": "熱門程度", + "sortBy": "ęŽ’åŗę–¹å¼ļ¼š", + "multiTool": { + "title": "PDF č¤‡åˆå·„å…·", + "desc": "åˆä½µć€ę—‹č½‰ć€é‡ę–°ęŽ’åˆ—å’Œē§»é™¤é é¢" + }, + "merge": { + "title": "合併", + "desc": "č¼•é¬†å°‡å¤šå€‹ PDF åˆä½µē‚ŗäø€å€‹ć€‚" + }, + "split": { + "title": "分割", + "desc": "將 PDF åˆ†å‰²ē‚ŗå¤šå€‹ę–‡ä»¶" + }, + "rotate": { + "title": "旋轉", + "desc": "č¼•é¬†ę—‹č½‰ę‚Øēš„ PDF怂" + }, + "imageToPdf": { + "title": "åœ–ē‰‡č½‰ PDF", + "desc": "å°‡åœ–ē‰‡ļ¼ˆPNG态JPEG态GIFļ¼‰č½‰ę›ē‚ŗ PDF怂" + }, + "pdfToImage": { + "title": "PDF č½‰åœ–ē‰‡", + "desc": "將 PDF č½‰ę›ē‚ŗåœ–ē‰‡ć€‚ļ¼ˆPNG态JPEG态GIF)" + }, + "pdfOrganiser": { + "title": "敓理", + "desc": "ä»„ä»»ä½•é †åŗē§»é™¤/é‡ę–°ęŽ’åˆ—é é¢" + }, + "addImage": { + "title": "ę–°å¢žåœ–ē‰‡", + "desc": "在 PDF ēš„ęŒ‡å®šä½ē½®ę–°å¢žåœ–ē‰‡" + }, + "watermark": { + "title": "ę–°å¢žęµ®ę°“å°", + "desc": "åœØę‚Øēš„ PDF ęŖ”ę”ˆäø­ę–°å¢žč‡ŖčØ‚ęµ®ę°“å°ć€‚" + }, + "permissions": { + "title": "äæ®ę”¹ę¬Šé™", + "desc": "äæ®ę”¹ę‚Øēš„ PDF ęŖ”ę”ˆę¬Šé™" + }, + "removePages": { + "title": "移除", + "desc": "å¾žę‚Øēš„ PDF ęŖ”ę”ˆäø­åˆŖé™¤äøéœ€č¦ēš„é é¢ć€‚" + }, + "addPassword": { + "title": "ę–°å¢žåÆ†ē¢¼", + "desc": "ē”ØåÆ†ē¢¼åŠ åÆ†ę‚Øēš„ PDF ęŖ”ę”ˆć€‚" + }, + "removePassword": { + "title": "移除密碼", + "desc": "å¾žę‚Øēš„ PDF ęŖ”ę”ˆäø­ē§»é™¤åÆ†ē¢¼äæč­·ć€‚" + }, + "compressPdfs": { + "title": "壓縮", + "desc": "壓縮 PDF ä»„ęø›å°‘å…¶ęŖ”ę”ˆå¤§å°ć€‚" + }, + "unlockPDFForms": { + "title": "Unlock PDF Forms", + "desc": "Remove read-only property of form fields in a PDF document." + }, + "changeMetadata": { + "title": "č®Šę›“äø­ē¹¼č³‡ę–™", + "desc": "從 PDF ęŖ”ę”ˆäø­č®Šę›“/移除/ę–°å¢žäø­ē¹¼č³‡ę–™" + }, + "fileToPDF": { + "title": "ęŖ”ę”ˆč½‰ PDF", + "desc": "å°‡å¹¾ä¹Žę‰€ęœ‰ę ¼å¼č½‰ę›ē‚ŗ PDF(DOCX态PNG态XLS态PPT态TXT 等等)" + }, + "ocr": { + "title": "OCR / ęø…ē†ęŽƒę", + "desc": "ęø…ē†ęŽƒęäø¦å¾ž PDF äø­ēš„å½±åƒäø­åµęø¬ę–‡å­—äø¦é‡ę–°ę–°å¢žē‚ŗę–‡å­—ć€‚" + }, + "extractImages": { + "title": "ęå–åœ–ē‰‡", + "desc": "從 PDF äø­ęå–ę‰€ęœ‰åœ–ē‰‡äø¦å°‡å®ƒå€‘å„²å­˜åˆ°å£“ēø®ęŖ”äø­" + }, + "pdfToPDFA": { + "title": "PDF 轉 PDF/A", + "desc": "將 PDF č½‰ę›ē‚ŗé•·ęœŸå„²å­˜ēš„ PDF/A" + }, + "PDFToWord": { + "title": "PDF 轉 Word", + "desc": "將 PDF č½‰ę›ē‚ŗ Word ę ¼å¼ļ¼ˆDOC态DOCX 和 ODT)" + }, + "PDFToPresentation": { + "title": "PDF 轉簔報", + "desc": "將 PDF č½‰ę›ē‚ŗē°”å ±ę ¼å¼ļ¼ˆPPT态PPTX 和 ODP)" + }, + "PDFToText": { + "title": "PDF 轉 RTFļ¼ˆę–‡å­—ļ¼‰", + "desc": "將 PDF č½‰ę›ē‚ŗę–‡å­—ęˆ– RTF ę ¼å¼" + }, + "PDFToHTML": { + "title": "PDF 轉 HTML", + "desc": "將 PDF č½‰ę›ē‚ŗ HTML ę ¼å¼" + }, + "PDFToXML": { + "title": "PDF 轉 XML", + "desc": "將 PDF č½‰ę›ē‚ŗ XML ę ¼å¼" + }, + "ScannerImageSplit": { + "title": "偵測/åˆ†å‰²ęŽƒęē…§ē‰‡", + "desc": "å¾žē…§ē‰‡/PDF äø­åˆ†å‰²å¤šå¼µē…§ē‰‡" + }, + "sign": { + "title": "簽章", + "desc": "é€éŽē¹Ŗåœ–ć€ę–‡å­—ęˆ–å½±åƒę–°å¢žē°½ē« åˆ° PDF" + }, + "flatten": { + "title": "平坦化", + "desc": "從 PDF äø­ē§»é™¤ę‰€ęœ‰äŗ’å‹•å…ƒē“ å’Œč”Øå–®" + }, + "repair": { + "title": "修復", + "desc": "å˜—č©¦äæ®å¾©ęå£ž/ē “ęēš„ PDF" + }, + "removeBlanks": { + "title": "ē§»é™¤ē©ŗē™½é é¢", + "desc": "åµęø¬äø¦å¾žę–‡ä»¶äø­ē§»é™¤ē©ŗē™½é é¢" + }, + "removeAnnotations": { + "title": "移除註釋", + "desc": "從 PDF äø­ē§»é™¤ę‰€ęœ‰čØ»é‡‹/註解" + }, + "compare": { + "title": "ęÆ”č¼ƒ", + "desc": "ęÆ”č¼ƒäø¦é”Æē¤ŗ 2 個 PDF ęŖ”ę”ˆēš„å·®ē•°" + }, + "certSign": { + "title": "使用憑證簽章", + "desc": "使用憑證/é‡‘é‘°ļ¼ˆPEM/P12)簽章 PDF" + }, + "removeCertSign": { + "title": "移除簽章", + "desc": "從 PDF 移除簽章" + }, + "pageLayout": { + "title": "å¤šé é¢ē‰ˆé¢é…ē½®", + "desc": "將 PDF ęŖ”ę”ˆēš„å¤šå€‹é é¢åˆä½µåˆ°å–®äø€é é¢" + }, + "scalePages": { + "title": "čŖæę•“é é¢å¤§å°/比例", + "desc": "äæ®ę”¹é é¢åŠå…¶å…§å®¹ēš„å¤§å°/比例。" + }, + "pipeline": { + "title": "ē®”é“ļ¼ˆé€²éšŽļ¼‰", + "desc": "é€éŽå®šē¾©ē®”é“ęŒ‡ä»¤ē¢¼åœØ PDF äøŠåŸ·č”Œå¤šå€‹ę“ä½œ" + }, + "add-page-numbers": { + "title": "ę–°å¢žé ē¢¼", + "desc": "åœØę–‡ä»¶ēš„čØ­å®šä½ē½®ę–°å¢žé ē¢¼" + }, + "auto-rename": { + "title": "č‡Ŗå‹•é‡ę–°å‘½å PDF ęŖ”ę”ˆ", + "desc": "ę ¹ę“šå…¶åµęø¬åˆ°ēš„ęØ™é ­č‡Ŗå‹•é‡ę–°å‘½å PDF ęŖ”ę”ˆ" + }, + "adjust-contrast": { + "title": "čŖæę•“é”č‰²/å°ęÆ”åŗ¦", + "desc": "čŖæę•“ PDF ēš„å°ęÆ”åŗ¦ć€é£½å’Œåŗ¦å’Œäŗ®åŗ¦" + }, + "crop": { + "title": "裁剪 PDF", + "desc": "裁剪 PDF ä»„ęø›å°‘å…¶å¤§å°ļ¼ˆäæęŒę–‡å­—ļ¼ļ¼‰" + }, + "autoSplitPDF": { + "title": "č‡Ŗå‹•åˆ†å‰²é é¢", + "desc": "č‡Ŗå‹•åˆ†å‰²ęŽƒęēš„ PDFļ¼Œä½æē”ØåÆ¦é«”ęŽƒęé é¢åˆ†å‰²å™Ø QR Code" + }, + "sanitizePdf": { + "title": "清理", + "desc": "從 PDF ęŖ”ę”ˆäø­ē§»é™¤ęŒ‡ä»¤ē¢¼å’Œå…¶ä»–å…ƒē“ " + }, + "URLToPDF": { + "title": "ē¶²å€/網站轉 PDF", + "desc": "將任何 http(s) ē¶²å€č½‰ę›ē‚ŗ PDF" + }, + "HTMLToPDF": { + "title": "HTML 轉 PDF", + "desc": "將任何 HTML ęŖ”ę”ˆęˆ–å£“ēø®ęŖ”č½‰ę›ē‚ŗ PDF" + }, + "MarkdownToPDF": { + "title": "Markdown 轉 PDF", + "desc": "將任何 Markdown ęŖ”ę”ˆč½‰ę›ē‚ŗ PDF" + }, + "PDFToMarkdown": { + "title": "PDF 轉 Markdown", + "desc": "將任何 PDF č½‰ę›ē‚ŗ Markdown ęŖ”ę”ˆ" + }, + "getPdfInfo": { + "title": "取得 PDF ēš„ę‰€ęœ‰č³‡čØŠ", + "desc": "取得 PDF ēš„ę‰€ęœ‰åÆčƒ½č³‡čØŠ" + }, + "extractPage": { + "title": "ęå–å¤šå€‹é é¢", + "desc": "從 PDF äø­ęå–éøå®šēš„é é¢" + }, + "PdfToSinglePage": { + "title": "PDF č½‰å–®äø€å¤§é é¢", + "desc": "å°‡ę‰€ęœ‰ PDF é é¢åˆä½µē‚ŗäø€å€‹å¤§ēš„å–®äø€é é¢" + }, + "showJS": { + "title": "锯示 JavaScript", + "desc": "ęœå°‹äø¦é”Æē¤ŗåµŒå…„ PDF äø­ēš„ä»»ä½• JS(JavaScript)" + }, + "autoRedact": { + "title": "自動唗黑", + "desc": "ę ¹ę“šč¼øå…„ēš„ę–‡å­—č‡Ŗå‹•å”—é»‘ PDF äø­ēš„ę–‡å­—" + }, + "redact": { + "title": "手動唗黑", + "desc": "ä¾ę“šéøå–ēš„ę–‡å­—ć€ē¹Ŗč£½ēš„å½¢ē‹€å’Œéøå–ēš„é é¢å”—é»‘ PDF" + }, + "tableExtraxt": { + "title": "PDF 轉 CSV", + "desc": "從 PDF äø­ęå–č”Øę ¼äø¦å°‡å…¶č½‰ę›ē‚ŗ CSV" + }, + "autoSizeSplitPDF": { + "title": "ę ¹ę“šå¤§å°/ę•øé‡č‡Ŗå‹•åˆ†å‰²", + "desc": "ę ¹ę“šå¤§å°ć€é ę•øęˆ–ę–‡ä»¶ę•øå°‡å–®äø€ PDF åˆ†å‰²ē‚ŗå¤šå€‹ę–‡ä»¶" + }, + "overlay-pdfs": { + "title": "覆蓋 PDF", + "desc": "將 PDF č¦†č“‹åœØå¦äø€å€‹ PDF 上" + }, + "split-by-sections": { + "title": "ä¾å€ę®µåˆ†å‰² PDF", + "desc": "將 PDF ēš„ęÆäø€é åˆ†å‰²ē‚ŗč¼ƒå°ēš„ę°“å¹³å’Œåž‚ē›“å€ę®µ" + }, + "AddStampRequest": { + "title": "å°‡åœ–ē« ę–°å¢žåˆ° PDF", + "desc": "åœØčØ­å®šä½ē½®ę–°å¢žę–‡å­—ęˆ–ę–°å¢žå½±åƒåœ–ē« " + }, + "removeImagePdf": { + "title": "ē§»é™¤åœ–ē‰‡", + "desc": "從 PDF äø­ē§»é™¤åœ–ē‰‡ä»„ęø›å°‘ęŖ”ę”ˆå¤§å°" + }, + "splitPdfByChapters": { + "title": "ä¾ē« ēÆ€åˆ†å‰² PDF", + "desc": "ę ¹ę“š PDF ēš„ē« ēÆ€ēµę§‹å°‡å…¶åˆ†å‰²ęˆå¤šå€‹ęŖ”ę”ˆć€‚" + }, + "validateSignature": { + "title": "é©—č­‰ PDF 簽章", + "desc": "é©—č­‰ PDF ę–‡ä»¶äø­ēš„ę•øä½ē°½ē« čˆ‡ę†‘č­‰" + }, + "replaceColorPdf": { + "title": "å–ä»£čˆ‡åč½‰é”č‰²", + "desc": "取代 PDF äø­ę–‡å­—å’ŒčƒŒę™Æēš„é”č‰²ļ¼Œäø¦åč½‰ę•“å€‹ PDF ēš„é”č‰²ä»„ęø›å°‘ęŖ”ę”ˆå¤§å°" + } + }, + "viewPdf": { + "tags": "檢視,閱讀,註釋,文字,åœ–ē‰‡", + "title": "檢視/編輯 PDF", + "header": "檢視 PDF" + }, + "multiTool": { + "tags": "č¤‡åˆå·„å…·,多功能,UI,é»žéøę‹–ę›³,å‰ē«Æ,客戶端,äŗ’å‹•,äŗ’å‹•å¼,移動", + "title": "PDF č¤‡åˆå·„å…·", + "header": "PDF č¤‡åˆå·„å…·", + "uploadPrompts": "ęŖ”å", + "selectAll": "全選", + "deselectAll": "å–ę¶ˆå…Øéø", + "selectPages": "éøå–é é¢", + "selectedPages": "å·²éøå–ēš„é é¢", + "page": "頁面", + "deleteSelected": "åˆŖé™¤å·²éøå–ēš„é …ē›®", + "downloadAll": "åŒÆå‡ŗ", + "downloadSelected": "åŒÆå‡ŗå·²éøå–ēš„é …ē›®", + "insertPageBreak": "ę’å…„åˆ†é ē¬¦č™Ÿ", + "addFile": "ę–°å¢žęŖ”ę”ˆ", + "rotateLeft": "向左旋轉", + "rotateRight": "å‘å³ę—‹č½‰", + "split": "分割", + "moveLeft": "向左移動", + "moveRight": "å‘å³ē§»å‹•", + "delete": "åˆŖé™¤", + "dragDropMessage": "å·²éøå–ēš„é é¢", + "undo": "復原", + "redo": "重做" + }, + "merge": { + "tags": "合併,é é¢ę“ä½œ,後端,ä¼ŗęœå™Øē«Æ", + "title": "合併", + "header": "合併多個 PDF", + "sortByName": "ä¾åēØ±ęŽ’åŗ", + "sortByDate": "ä¾ę—„ęœŸęŽ’åŗ", + "removeCertSign": "ę˜Æå¦ē§»é™¤åˆä½µå¾ŒęŖ”ę”ˆēš„ę†‘č­‰ē°½ē« ļ¼Ÿ", + "submit": "合併" + }, + "split": { + "tags": "é é¢ę“ä½œ,劃分,多頁,剪下,ä¼ŗęœå™Øē«Æ", + "title": "分割 PDF", + "header": "分割 PDF", + "desc": { + "1": "ä½ éøę“‡ēš„ę•øå­—ę˜Æä½ åøŒęœ›é€²č”Œåˆ†å‰²ēš„é ē¢¼", + "2": "å› ę­¤ļ¼Œéøę“‡ 1,3,7-9 å°‡ęœƒå°‡äø€å€‹ 10 é ēš„ę–‡ä»¶åˆ†å‰²ē‚ŗ 6 å€‹å–®ēØēš„ PDFļ¼ŒåŒ…ę‹¬ļ¼š", + "3": "ꖇ件 #1ļ¼šé é¢ 1", + "4": "ꖇ件 #2ļ¼šé é¢ 2 和 3", + "5": "ꖇ件 #3ļ¼šé é¢ 4态5态6 和 7", + "6": "ꖇ件 #4ļ¼šé é¢ 8", + "7": "ꖇ件 #5ļ¼šé é¢ 9", + "8": "ꖇ件 #6ļ¼šé é¢ 10" + }, + "splitPages": "č¼øå…„č¦åˆ†å‰²ēš„é é¢ļ¼š", + "submit": "分割" + }, + "rotate": { + "tags": "ä¼ŗęœå™Øē«Æ", + "title": "旋轉 PDF", + "header": "旋轉 PDF", + "selectAngle": "éøę“‡ę—‹č½‰č§’åŗ¦ļ¼ˆä»„ 90 åŗ¦ēš„å€ę•øļ¼‰ļ¼š", + "submit": "旋轉" + }, + "imageToPdf": { + "tags": "č½‰ę›,img,jpg,åœ–ē‰‡,照片" + }, + "pdfToImage": { + "tags": "č½‰ę›,img,jpg,åœ–ē‰‡,照片", + "title": "PDF č½‰åœ–ē‰‡", + "header": "PDF č½‰åœ–ē‰‡", + "selectText": "å½±åƒę ¼å¼", + "singleOrMultiple": "é é¢åˆ°å½±åƒēš„ēµęžœé”žåž‹", + "single": "å–®äø€å¤§å½±åƒēµåˆę‰€ęœ‰é é¢", + "multi": "å¤šå€‹å½±åƒļ¼ŒęÆé äø€å€‹å½±åƒ", + "colorType": "é”č‰²é”žåž‹", + "color": "é”č‰²", + "grey": "灰度", + "blackwhite": "é»‘ē™½ļ¼ˆåÆčƒ½ęœƒéŗå¤±č³‡ę–™ļ¼ļ¼‰", + "submit": "č½‰ę›", + "info": "å°šęœŖå®‰č£ Pythonć€‚éœ€č¦å®‰č£ Python ę‰čƒ½é€²č”Œ WebP č½‰ę›ć€‚", + "placeholder": "ļ¼ˆä¾‹å¦‚ 1,2,8 ꈖ 4,7,12-16 ꈖ 2n-1)" + }, + "pdfOrganiser": { + "tags": "雙面,偶數,儇數,ęŽ’åŗ,移動", + "title": "é é¢ę•“ē†", + "header": "PDF é é¢ę•“ē†", + "submit": "é‡ę–°ęŽ’åˆ—é é¢", + "mode": { + "_value": "ęØ”å¼", + "1": "č‡Ŗå®šē¾©é é¢é †åŗ", + "2": "åå‘é †åŗ", + "3": "é›™å·„ęŽ’åŗ", + "4": "ę‘ŗé å†ŠęŽ’åŗ", + "5": "å“č£čØ‚ę‘ŗé å†ŠęŽ’åŗ", + "6": "å„‡å¶ę‹†åˆ†", + "7": "åˆŖé™¤ē¬¬äø€é ", + "8": "åˆŖé™¤ęœ€å¾Œäø€é ", + "9": "åˆŖé™¤ē¬¬äø€é å’Œęœ€å¾Œäø€é ", + "10": "儇偶合併", + "11": "č¤‡č£½ę‰€ęœ‰é é¢" + }, + "placeholder": "ļ¼ˆä¾‹å¦‚ 1,3,2 ꈖ 4-8,2,10-12 ꈖ 2n-1)" + }, + "addImage": { + "tags": "img,jpg,åœ–ē‰‡,照片", + "title": "ę–°å¢žåœ–ē‰‡", + "header": "ę–°å¢žåœ–ē‰‡åˆ° PDF", + "everyPage": "ęÆäø€é ļ¼Ÿ", + "upload": "ę–°å¢žåœ–ē‰‡", + "submit": "ę–°å¢žåœ–ē‰‡" + }, + "watermark": { + "tags": "文字,重複,標籤,č‡Ŗęœ‰,ē‰ˆę¬Š,商標,img,jpg,åœ–ē‰‡,照片", + "title": "ę–°å¢žęµ®ę°“å°", + "header": "ę–°å¢žęµ®ę°“å°", + "customColor": "č‡ŖčØ‚ę–‡å­—é”č‰²", + "selectText": { + "1": "éøę“‡č¦ę–°å¢žęµ®ę°“å°ēš„ PDF:", + "2": "ęµ®ę°“å°ę–‡å­—ļ¼š", + "3": "å­—åž‹å¤§å°ļ¼š", + "4": "ę—‹č½‰ļ¼ˆ0-360ļ¼‰ļ¼š", + "5": "Width Spacerļ¼ˆęÆå€‹ęµ®ę°“å°ä¹‹é–“ēš„ę°“å¹³é–“č·ļ¼‰ļ¼š", + "6": "Height Spacerļ¼ˆęÆå€‹ęµ®ę°“å°ä¹‹é–“ēš„åž‚ē›“é–“č·ļ¼‰ļ¼š", + "7": "äøé€ę˜Žåŗ¦ļ¼ˆ0% - 100%ļ¼‰ļ¼š", + "8": "ęµ®ę°“å°é”žåž‹ļ¼š", + "9": "ęµ®ę°“å°å½±åƒļ¼š", + "10": "將 PDF č½‰ę›ē‚ŗ PDF 影像" + }, + "submit": "ę–°å¢žęµ®ę°“å°", + "type": { + "1": "文字", + "2": "åœ–ē‰‡" + } + }, + "permissions": { + "tags": "č®€å–,寫兄,編輯,列印", + "title": "變ꛓꬊ限", + "header": "變ꛓꬊ限", + "warning": "č­¦å‘Šļ¼Œč¦ä½æé€™äŗ›ę¬Šé™äøåÆč®Šę›“ļ¼Œå»ŗč­°é€éŽę–°å¢žåÆ†ē¢¼é é¢ä½æē”ØåÆ†ē¢¼čØ­å®šé€™äŗ›ę¬Šé™", + "selectText": { + "1": "éøę“‡č¦č®Šę›“ę¬Šé™ēš„ PDF", + "2": "č¦čØ­å®šēš„ę¬Šé™", + "3": "é˜²ę­¢ę–‡ä»¶ēµ„č£", + "4": "é˜²ę­¢å…§å®¹ęå–", + "5": "é˜²ę­¢ē‚ŗäŗ†ē„”éšœē¤™ä½æē”Øč€Œęå–č³‡ę–™", + "6": "é˜²ę­¢å”«åÆ«č”Øå–®", + "7": "é˜²ę­¢äæ®ę”¹", + "8": "é˜²ę­¢čØ»é‡‹äæ®ę”¹", + "9": "é˜²ę­¢åˆ—å°", + "10": "é˜²ę­¢åˆ—å°äøåŒę ¼å¼" + }, + "submit": "變ꛓ" + }, + "removePages": { + "tags": "ē§»é™¤é é¢,åˆŖé™¤é é¢" + }, + "addPassword": { + "tags": "安全,安全性", + "title": "ę–°å¢žåÆ†ē¢¼", + "header": "ę–°å¢žåÆ†ē¢¼ļ¼ˆåŠ åÆ†ļ¼‰", + "selectText": { + "1": "éøę“‡č¦åŠ åÆ†ēš„ PDF", + "2": "使用者密碼", + "3": "åŠ åÆ†é‡‘é‘°é•·åŗ¦", + "4": "č¼ƒé«˜ēš„å€¼ę›“å¼·ļ¼Œä½†č¼ƒä½Žēš„å€¼å…·ęœ‰ę›“å„½ēš„ē›øå®¹ę€§ć€‚", + "5": "č¦čØ­å®šēš„ę¬Šé™ļ¼ˆå»ŗč­°čˆ‡ę“ęœ‰č€…åÆ†ē¢¼äø€čµ·ä½æē”Øļ¼‰", + "6": "é˜²ę­¢ę–‡ä»¶ēµ„č£", + "7": "é˜²ę­¢å…§å®¹ęå–", + "8": "é˜²ę­¢ē‚ŗäŗ†ē„”éšœē¤™ä½æē”Øč€Œęå–č³‡ę–™", + "9": "é˜²ę­¢å”«åÆ«č”Øå–®", + "10": "é˜²ę­¢äæ®ę”¹", + "11": "é˜²ę­¢čØ»é‡‹äæ®ę”¹", + "12": "é˜²ę­¢åˆ—å°", + "13": "é˜²ę­¢åˆ—å°äøåŒę ¼å¼", + "14": "ę“ęœ‰č€…åÆ†ē¢¼", + "15": "é™åˆ¶äø€ę—¦é–‹å•Ÿę–‡ä»¶åÆä»„åšä»€éŗ¼ļ¼ˆäø¦éžę‰€ęœ‰č»Ÿé«”éƒ½ę”Æę“ļ¼‰", + "16": "é™åˆ¶é–‹å•Ÿę–‡ä»¶ęœ¬čŗ«" + }, + "submit": "åŠ åÆ†" + }, + "removePassword": { + "tags": "安全,解密,安全性,å–ę¶ˆåÆ†ē¢¼,åˆŖé™¤åÆ†ē¢¼", + "title": "移除密碼", + "header": "ē§»é™¤åÆ†ē¢¼ļ¼ˆč§£åÆ†ļ¼‰", + "selectText": { + "1": "éøę“‡č¦č§£åÆ†ēš„ PDF", + "2": "密碼" + }, + "submit": "移除" + }, + "compressPdfs": { + "tags": "壓縮,小,微小" + }, + "unlockPDFForms": { + "tags": "remove,delete,form,field,readonly", + "title": "Remove Read-Only from Form Fields", + "header": "Unlock PDF Forms", + "submit": "Remove" + }, + "changeMetadata": { + "tags": "ęØ™é”Œ,ä½œč€…,ę—„ęœŸ,建立,Ꙃ間,å‡ŗē‰ˆå•†,製作人,統計", + "title": "ęØ™é”Œļ¼š", + "header": "č®Šę›“äø­ē¹¼č³‡ę–™", + "selectText": { + "1": "č«‹ē·Øč¼Æä½ åøŒęœ›č®Šę›“ēš„č®Šę•ø", + "2": "åˆŖé™¤ę‰€ęœ‰äø­ē¹¼č³‡ę–™", + "3": "é”Æē¤ŗč‡ŖčØ‚äø­ē¹¼č³‡ę–™ļ¼š", + "4": "å…¶ä»–äø­ē¹¼č³‡ę–™ļ¼š", + "5": "ę–°å¢žč‡ŖčØ‚äø­ē¹¼č³‡ę–™é …ē›®" + }, + "author": "ä½œč€…ļ¼š", + "creationDate": "å»ŗē«‹ę—„ęœŸļ¼ˆyyyy/MM/dd HH:mm:ssļ¼‰ļ¼š", + "creator": "å»ŗē«‹č€…ļ¼š", + "keywords": "é—œéµå­—ļ¼š", + "modDate": "äæ®ę”¹ę—„ęœŸļ¼ˆyyyy/MM/dd HH:mm:ssļ¼‰ļ¼š", + "producer": "製作人:", + "subject": "主锌:", + "trapped": "é™·é˜±ļ¼š", + "submit": "變ꛓ" + }, + "fileToPDF": { + "tags": "č½‰ę›,ę ¼å¼,ꖇ件,åœ–ē‰‡,ęŠ•å½±ē‰‡,文字,č½‰ę›,office,docs,Word,Excel,PowerPoint", + "title": "ęŖ”ę”ˆč½‰ PDF", + "header": "å°‡ä»»ä½•ęŖ”ę”ˆč½‰ę›ē‚ŗ PDF", + "credit": "ę­¤ęœå‹™ä½æē”Ø LibreOffice 和 Unoconv é€²č”ŒęŖ”ę”ˆč½‰ę›ć€‚", + "supportedFileTypesInfo": "ę”Æę“ēš„ęŖ”ę”ˆé”žåž‹", + "supportedFileTypes": "ę”Æę“ēš„ęŖ”ę”ˆé”žåž‹ę‡‰åŒ…ę‹¬ä»„äø‹å…§å®¹ļ¼Œä½†č¦ē²å¾—å®Œę•“ēš„ę›“ę–°ę”Æę“ę ¼å¼åˆ—č”Øļ¼Œč«‹åƒé–± LibreOffice ēš„ę–‡ä»¶", + "submit": "č½‰ę›ē‚ŗ PDF" + }, + "ocr": { + "tags": "識刄,文字,影像,ꎃꏏ,č®€å–,識刄,偵測,åÆē·Øč¼Æ", + "title": "OCR / ęŽƒęęø…ē†", + "header": "ęø…ē†ęŽƒę / OCRļ¼ˆå…‰å­øå­—å…ƒč­˜åˆ„ļ¼‰", + "selectText": { + "1": "éøę“‡č¦åœØ PDF äø­åµęø¬ēš„čŖžčØ€ļ¼ˆåˆ—å‡ŗēš„ę˜Æē›®å‰åÆä»„åµęø¬ēš„čŖžčØ€ļ¼‰ļ¼š", + "2": "ē”¢ē”ŸåŒ…å« OCR ę–‡å­—ēš„ę–‡å­—ę–‡ä»¶ļ¼Œäø¦čˆ‡ OCR ēš„ PDF 一起", + "3": "äæ®ę­£ęŽƒęēš„é é¢å‚¾ę–œč§’åŗ¦ļ¼Œå°‡å®ƒå€‘ę—‹č½‰å›žåŽŸä½", + "4": "ęø…ē†é é¢ä»„é™ä½Ž OCR åœØčƒŒę™Æé›œčØŠäø­č­˜åˆ„ę–‡å­—ēš„ę©ŸēŽ‡ć€‚ļ¼ˆē„”č¼øå‡ŗč®ŠåŒ–ļ¼‰", + "5": "ęø…ē†é é¢ä»„é™ä½Ž OCR åœØčƒŒę™Æé›œčØŠäø­č­˜åˆ„ę–‡å­—ēš„ę©ŸēŽ‡ļ¼ŒäæęŒä¹¾ę·Øēš„č¼øå‡ŗć€‚", + "6": "åæ½ē•„å…·ęœ‰äŗ’å‹•ę–‡å­—ēš„é é¢ļ¼ŒåŖå°å½±åƒé é¢é€²č”Œ OCR", + "7": "強制 OCRļ¼Œå°‡å°ęÆäø€é é€²č”Œ OCRļ¼Œē§»é™¤ę‰€ęœ‰åŽŸå§‹ę–‡å­—å…ƒē“ ", + "8": "ę­£åøøļ¼ˆå¦‚ęžœ PDF åŒ…å«ę–‡å­—å°‡å‡ŗéŒÆļ¼‰", + "9": "é”å¤–čØ­å®š", + "10": "OCR ęØ”å¼", + "11": "移除 OCR å¾Œēš„å½±åƒļ¼ˆē§»é™¤ę‰€ęœ‰å½±åƒļ¼ŒåŖęœ‰åœØč½‰ę›ę­„é©Ÿäø­ę‰ęœ‰ē”Øļ¼‰", + "12": "ęø²ęŸ“é”žåž‹ļ¼ˆé€²éšŽļ¼‰" + }, + "help": "č«‹é–±č®€ę­¤ę–‡ä»¶ļ¼Œäŗ†č§£å¦‚ä½•ä½æē”Øå…¶ä»–čŖžčØ€å’Œ/ęˆ–åœØ Docker 中使用", + "credit": "ę­¤ęœå‹™ä½æē”Ø qpdf 和 Tesseract é€²č”Œ OCR怂", + "submit": "使用 OCR 處理 PDF" + }, + "extractImages": { + "tags": "åœ–ē‰‡,照片,儲存,å­˜ęŖ”,壓縮檔,ę•ē²,ęŠ“å–", + "title": "ęå–åœ–ē‰‡", + "header": "ęå–åœ–ē‰‡", + "selectText": "éøę“‡č¦č½‰ę›ęå–å½±åƒēš„å½±åƒę ¼å¼", + "allowDuplicates": "å„²å­˜é‡č¤‡ēš„åœ–ē‰‡", + "submit": "ęå–" + }, + "pdfToPDFA": { + "tags": "å­˜ęŖ”,é•·ęœŸ,標準,č½‰ę›,儲存,äæå­˜", + "title": "PDF 轉 PDF/A", + "header": "PDF 轉 PDF/A", + "credit": "ę­¤ęœå‹™ä½æē”Ø libreoffice é€²č”Œ PDF/A č½‰ę›", + "submit": "č½‰ę›", + "tip": "ē›®å‰äøę”Æę“äøŠå‚³å¤šå€‹", + "outputFormat": "č¼øå‡ŗę ¼å¼", + "pdfWithDigitalSignature": "該 PDF ēš„ę†‘č­‰ē°½ē« å°‡ęœƒåœØäø‹äø€ę­„č¢«ē§»é™¤" + }, + "PDFToWord": { + "tags": "doc,docx,odt,word,č½‰ę›,ę ¼å¼,轉檔,office,微軟,docfile", + "title": "PDF 轉 Word", + "header": "PDF 轉 Word", + "selectText": { + "1": "č¼øå‡ŗę–‡ä»¶ę ¼å¼" + }, + "credit": "ę­¤ęœå‹™ä½æē”Ø LibreOffice é€²č”ŒęŖ”ę”ˆč½‰ę›ć€‚", + "submit": "č½‰ę›" + }, + "PDFToPresentation": { + "tags": "ęŠ•å½±ē‰‡,展示,office,微軟", + "title": "PDF 轉簔報", + "header": "PDF 轉簔報", + "selectText": { + "1": "č¼øå‡ŗę–‡ä»¶ę ¼å¼" + }, + "credit": "ę­¤ęœå‹™ä½æē”Ø LibreOffice é€²č”ŒęŖ”ę”ˆč½‰ę›ć€‚", + "submit": "č½‰ę›" + }, + "PDFToText": { + "tags": "č±åÆŒę ¼å¼,č±åÆŒę–‡å­—ę ¼å¼,č±åÆŒę–‡å­—ę ¼å¼", + "title": "PDF 轉 RTFļ¼ˆę–‡å­—ļ¼‰", + "header": "PDF 轉 RTFļ¼ˆę–‡å­—ļ¼‰", + "selectText": { + "1": "č¼øå‡ŗę–‡ä»¶ę ¼å¼" + }, + "credit": "ę­¤ęœå‹™ä½æē”Ø LibreOffice é€²č”ŒęŖ”ę”ˆč½‰ę›ć€‚", + "submit": "č½‰ę›" + }, + "PDFToHTML": { + "tags": "網頁內容,ē€č¦½å™Øå‹å–„", + "title": "PDF 轉 HTML", + "header": "PDF 轉 HTML", + "credit": "ę­¤ęœå‹™ä½æē”Ø pdftohtml é€²č”ŒęŖ”ę”ˆč½‰ę›ć€‚", + "submit": "č½‰ę›" + }, + "PDFToXML": { + "tags": "č³‡ę–™ęå–,ēµę§‹åŒ–å…§å®¹,äŗ’ę“ä½œ,č½‰ę›,轉檔", + "title": "PDF č½‰ę›ē‚ŗ XML", + "header": "PDF č½‰ę›ē‚ŗ XML", + "credit": "ę­¤ęœå‹™ä½æē”Ø LibreOffice é€²č”ŒęŖ”ę”ˆč½‰ę›ć€‚", + "submit": "č½‰ę›" + }, + "ScannerImageSplit": { + "tags": "分離,自動偵測,ꎃꏏ,å¤šē…§ē‰‡,組織", + "selectText": { + "1": "č§’åŗ¦é–¾å€¼ļ¼š", + "2": "čØ­å®šå½±åƒę—‹č½‰ę‰€éœ€ēš„ęœ€å°ēµ•å°č§’åŗ¦ļ¼ˆé čØ­ļ¼š10)。", + "3": "å®¹åæåŗ¦ļ¼š", + "4": "ē¢ŗå®šåœē¹žä¼°čØˆēš„čƒŒę™Æé”č‰²ēš„é”č‰²č®ŠåŒ–ēÆ„åœļ¼ˆé čØ­ļ¼š30)。", + "5": "ęœ€å°å€åŸŸļ¼š", + "6": "čØ­å®šē…§ē‰‡ēš„ęœ€å°å€åŸŸé–¾å€¼ļ¼ˆé čØ­ļ¼š10000)。", + "7": "ęœ€å°č¼Ŗå»“å€åŸŸļ¼š", + "8": "čØ­å®šē…§ē‰‡ēš„ęœ€å°č¼Ŗå»“å€åŸŸé–¾å€¼", + "9": "é‚Šę”†å¤§å°ļ¼š", + "10": "čØ­å®šę–°å¢žå’Œē§»é™¤ēš„é‚Šę”†å¤§å°ļ¼Œä»„é˜²ę­¢č¼øå‡ŗäø­ēš„ē™½č‰²é‚Šę”†ļ¼ˆé čØ­ļ¼š1)。" + }, + "info": "å°šęœŖå®‰č£ Pythonć€‚éœ€č¦å®‰č£ Python ę‰čƒ½åŸ·č”Œć€‚" + }, + "sign": { + "tags": "ęŽˆę¬Š,縮寫,繪製簽章,文字,å½±åƒē°½ē« ", + "title": "簽章", + "header": "簽署 PDF", + "upload": "äøŠå‚³å½±åƒ", + "draw": "繪製簽章", + "text": "文字輸兄", + "clear": "清除", + "add": "ę–°å¢ž", + "saved": "å·²å„²å­˜ēš„ē°½ē« ", + "save": "å„²å­˜ē°½ē« ", + "personalSigs": "個人簽章", + "sharedSigs": "共用簽章", + "noSavedSigs": "å°šęœŖå„²å­˜ä»»ä½•ē°½ē« ", + "addToAll": "ę–°å¢žč‡³ę‰€ęœ‰é é¢", + "delete": "åˆŖé™¤", + "first": "第一頁", + "last": "ęœ€å¾Œäø€é ", + "next": "下一頁", + "previous": "äøŠäø€é ", + "maintainRatio": "åˆ‡ę›ē¶­ęŒé•·åÆ¬ęÆ”", + "undo": "꒤銷", + "redo": "重做" + }, + "flatten": { + "tags": "靜ꅋ,åœē”Ø,éžäŗ’å‹•,ē°”åŒ–", + "title": "平坦化", + "header": "PDF 平坦化", + "flattenOnlyForms": "åƒ…å°‡č”Øå–®å¹³å¦åŒ–", + "submit": "平坦化" + }, + "repair": { + "tags": "修復,恢復,修正,復原", + "title": "修復", + "header": "修復 PDF", + "submit": "修復" + }, + "removeBlanks": { + "tags": "清理,ē°”åŒ–,非內容,組織", + "title": "ē§»é™¤ē©ŗē™½é é¢", + "header": "ē§»é™¤ē©ŗē™½é é¢", + "threshold": "ē•«ē“ ē™½åŗ¦é–¾å€¼ļ¼š", + "thresholdDesc": "ē¢ŗå®šäø€å€‹ē™½č‰²ē•«ē“ åæ…é ˆå¤šéŗ¼ē™½ę‰čƒ½č¢«åˆ†é”žē‚ŗ '白色'怂0 = é»‘č‰²ļ¼Œ255 瓔白。", + "whitePercent": "ē™½č‰²ē™¾åˆ†ęÆ”ļ¼ˆ%ļ¼‰ļ¼š", + "whitePercentDesc": "é é¢åæ…é ˆę˜Æ '白色' ē•«ē“ ēš„ē™¾åˆ†ęÆ”ę‰čƒ½č¢«ē§»é™¤", + "submit": "移除空白" + }, + "removeAnnotations": { + "tags": "註釋,突出,註解,ęØ™čØ˜,移除", + "title": "移除註釋", + "header": "移除註釋", + "submit": "移除" + }, + "compare": { + "tags": "區分,å°ęÆ”,č®ŠåŒ–,åˆ†ęž", + "title": "ęÆ”č¼ƒ", + "header": "ęÆ”č¼ƒ PDF", + "highlightColor": { + "1": "ęØ™ē¤ŗé”č‰² 1:", + "2": "ęØ™ē¤ŗé”č‰² 2:" + }, + "document": { + "1": "ꖇ件 1", + "2": "ꖇ件 2" + }, + "submit": "ęÆ”č¼ƒ", + "complex": { + "message": "éøę“‡ēš„ęŖ”ę”ˆå¤§å°å¤Ŗå¤§ļ¼ˆå…¶äø­äø€å€‹ęˆ–å…©č€…ēš†ę˜Æļ¼‰ļ¼ŒåÆčƒ½ęœƒå½±éŸæęÆ”č¼ƒēš„ē²¾ē¢ŗåŗ¦" + }, + "large": { + "file": { + "message": "éøę“‡ēš„ęŖ”ę”ˆå¤§å°č¶…å‡ŗē³»ēµ±é™åˆ¶ļ¼ˆå…¶äø­äø€å€‹ęˆ–å…©č€…ēš†ę˜Æļ¼‰ļ¼Œē„”ę³•č™•ē†" + } + }, + "no": { + "text": { + "message": "éøę“‡ēš„ PDF ęŖ”ę”ˆęœŖåŒ…å«ę–‡å­—ļ¼ˆå…¶äø­äø€å€‹ęˆ–å…©č€…ēš†ę˜Æļ¼‰ć€‚č«‹éøę“‡å«ęœ‰ę–‡å­—ēš„ PDF é€²č”ŒęÆ”č¼ƒ" + } + } + }, + "certSign": { + "tags": "é©—č­‰,PEM,P12,å®˜ę–¹,åŠ åÆ†", + "title": "憑證簽章", + "header": "ä½æē”Øę‚Øēš„ę†‘č­‰ē°½ē« ļ¼ˆé€²č”Œäø­ļ¼‰", + "selectPDF": "éøę“‡č¦ē°½ē« ēš„ PDF ęŖ”ę”ˆļ¼š", + "jksNote": "ę³Øę„ļ¼šå¦‚ęžœę‚Øēš„č­‰ę›øé”žåž‹ęœŖč¢«åˆ—åœØäø‹ę–¹ļ¼Œč«‹ä½æē”Ø keytool å‘½ä»¤åˆ—å·„å…·å°‡å…¶č½‰ę›ē‚ŗ Java Keystore (.jks) ęŖ”ę”ˆę ¼å¼ļ¼Œē„¶å¾Œéøę“‡äø‹é¢ēš„ .jks ęŖ”ę”ˆéøé …ć€‚", + "selectKey": "éøę“‡ę‚Øēš„ē§é‘°ęŖ”ę”ˆļ¼ˆPKCS#8 ę ¼å¼ļ¼Œå‰ÆęŖ”ååÆčƒ½ę˜Æ .pem ꈖ .derļ¼‰ļ¼š", + "selectCert": "éøę“‡ę‚Øēš„ę†‘č­‰ęŖ”ę”ˆļ¼ˆX.509 ę ¼å¼ļ¼Œå‰ÆęŖ”ååÆčƒ½ę˜Æ .pem ꈖ .derļ¼‰ļ¼š", + "selectP12": "éøę“‡ę‚Øēš„ PKCS#12 é‡‘é‘°åŗ«ęŖ”ę”ˆļ¼ˆå‰ÆęŖ”ååÆčƒ½ę˜Æ .p12 ꈖ .pfxļ¼‰ļ¼ˆéøå”«ļ¼Œå¦‚ęžœęœ‰ęä¾›ļ¼Œå‰‡å®ƒę‡‰č©²åŒ…å«ę‚Øēš„ē§é‘°å’Œę†‘č­‰ļ¼‰ļ¼š", + "selectJKS": "éøę“‡ę‚Øēš„ Java Keystore ęŖ”ę”ˆ ļ¼ˆå‰ÆęŖ”ååÆčƒ½ę˜Æ .jks ꈖ .keystoreļ¼‰ļ¼š", + "certType": "ę†‘č­‰é”žåž‹", + "password": "č¼øå…„ę‚Øēš„é‡‘é‘°åŗ«ęˆ–ē§é‘°åÆ†ē¢¼ļ¼ˆå¦‚ęžœęœ‰ēš„č©±ļ¼‰ļ¼š", + "showSig": "锯示簽章", + "reason": "原因", + "location": "ä½ē½®", + "name": "åēØ±", + "showLogo": "锯示 Logo", + "submit": "簽章 PDF" + }, + "removeCertSign": { + "tags": "é©—č­‰,PEM,P12,å®˜ę–¹,解密", + "title": "移除憑證簽章", + "header": "從 PDF ęŖ”ę”ˆäø­ē§»é™¤ę†‘č­‰ē°½ē« ", + "selectPDF": "選擇 PDF ęŖ”ę”ˆ", + "submit": "移除" + }, + "pageLayout": { + "tags": "合併,č¤‡åˆ,單一檢視,組織", + "title": "å¤šé é¢ē‰ˆé¢é…ē½®", + "header": "å¤šé é¢ē‰ˆé¢é…ē½®", + "pagesPerSheet": "ęÆå¼µē“™ēš„é é¢ę•øļ¼š", + "addBorder": "ę–°å¢žé‚Šę”†", + "submit": "送出" + }, + "scalePages": { + "tags": "čŖæę•“å¤§å°,修改,尺寸,適ꇉ", + "title": "čŖæę•“é é¢å¤§å°/比例", + "header": "čŖæę•“é é¢å¤§å°/比例", + "pageSize": "ę–‡ä»¶ēš„é é¢å¤§å°ć€‚", + "keepPageSize": "原始大小", + "scaleFactor": "é é¢ēš„ēø®ę”¾ē“šåˆ„ļ¼ˆč£å‰Ŗļ¼‰ć€‚", + "submit": "送出" + }, + "add-page-numbers": { + "tags": "分頁,標籤,組織,瓢引" + }, + "auto-rename": { + "tags": "自動偵測,åŸŗę–¼ęØ™é ­,組織,é‡ę–°ęØ™ē±¤", + "title": "č‡Ŗå‹•é‡ę–°å‘½å", + "header": "č‡Ŗå‹•é‡ę–°å‘½å PDF", + "submit": "č‡Ŗå‹•é‡ę–°å‘½å" + }, + "adjust-contrast": { + "tags": "色彩栔正,čŖæę•“,修改,增強" + }, + "crop": { + "tags": "修剪,ēø®å°,編輯,形狀", + "title": "裁剪", + "header": "裁剪 PDF", + "submit": "送出" + }, + "autoSplitPDF": { + "tags": "åŸŗę–¼ QR Code,分離,ęŽƒęå€ę®µ,組織", + "title": "č‡Ŗå‹•åˆ†å‰² PDF", + "header": "č‡Ŗå‹•åˆ†å‰² PDF", + "description": "åˆ—å°ļ¼Œę’å…„ļ¼ŒęŽƒęļ¼ŒäøŠå‚³ļ¼Œč®“ Stirling PDF č™•ē†å…¶é¤˜ēš„å·„ä½œć€‚äøéœ€č¦ę‰‹å‹•å·„ä½œęŽ’åŗć€‚", + "selectText": { + "1": "å¾žäø‹é¢åˆ—å°äø€äŗ›åˆ†éš”ē“™å¼µļ¼ˆé»‘ē™½å³åÆļ¼‰ć€‚", + "2": "é€éŽåœØå®ƒå€‘ä¹‹é–“ę’å…„åˆ†éš”ē“™å¼µäø€ę¬”ęŽƒęę‰€ęœ‰ę–‡ä»¶ć€‚", + "3": "äøŠå‚³å–®äø€å¤§ēš„ęŽƒę PDF ęŖ”ę”ˆļ¼Œč®“ Stirling PDF č™•ē†å…¶é¤˜ēš„å·„ä½œć€‚", + "4": "č‡Ŗå‹•åµęø¬äø¦ē§»é™¤åˆ†éš”é é¢ļ¼Œē¢ŗäæęœ€ēµ‚ę–‡ä»¶ę•“ę½”ć€‚" + }, + "formPrompt": "é€å‡ŗåŒ…å« Stirling-PDF é é¢åˆ†éš”å™Øēš„ PDF:", + "duplexMode": "é›™é¢ęØ”å¼ļ¼ˆę­£åé¢ęŽƒęļ¼‰", + "dividerDownload2": "下載 'č‡Ŗå‹•åˆ†å‰²å™Øåˆ†éš”å™Øļ¼ˆåø¶čŖŖę˜Žļ¼‰.pdf'", + "submit": "送出" + }, + "sanitizePdf": { + "tags": "清理,安全,焔害,移除威脅" + }, + "URLToPDF": { + "tags": "ē¶²é ę•ē²,儲存頁面,網頁轉文件,å­˜ęŖ”", + "title": "URL 轉 PDF", + "header": "URL 轉 PDF", + "submit": "č½‰ę›", + "credit": "ę­¤ęœå‹™ä½æē”Ø WeasyPrint é€²č”Œč½‰ę›" + }, + "HTMLToPDF": { + "tags": "ęØ™čØ˜,網頁內容,č½‰ę›,轉檔", + "title": "HTML 轉 PDF", + "header": "HTML 轉 PDF", + "help": "ęŽ„å— HTML ę–‡ä»¶å’ŒåŒ…å«ę‰€éœ€ html/css/images ē­‰ēš„ ZIP", + "submit": "č½‰ę›", + "credit": "ę­¤ęœå‹™ä½æē”Ø WeasyPrint é€²č”Œč½‰ę›", + "zoom": "ē”Øę–¼é”Æē¤ŗē¶²ē«™ēš„ēø®ę”¾ē“šåˆ„ć€‚", + "pageWidth": "é é¢åÆ¬åŗ¦-ä»„å…¬åˆ†ē‚ŗå–®ä½ļ¼ˆē•™ē©ŗå‰‡ä½æē”Øé čØ­å€¼ļ¼‰", + "pageHeight": "é é¢é«˜åŗ¦-ä»„å…¬åˆ†ē‚ŗå–®ä½ļ¼ˆē•™ē©ŗå‰‡ä½æē”Øé čØ­å€¼ļ¼‰", + "marginTop": "é é¢ēš„äøŠé‚Šč·-ä»„ęÆ«ē±³ē‚ŗå–®ä½ļ¼ˆē•™ē©ŗå‰‡ä½æē”Øé čØ­å€¼ļ¼‰", + "marginBottom": "é é¢ēš„äø‹é‚Šč·-ä»„ęÆ«ē±³ē‚ŗå–®ä½ļ¼ˆē•™ē©ŗå‰‡ä½æē”Øé čØ­å€¼ļ¼‰", + "marginLeft": "é é¢ēš„å·¦é‚Šč·-ä»„ęÆ«ē±³ē‚ŗå–®ä½ļ¼ˆē•™ē©ŗå‰‡ä½æē”Øé čØ­å€¼ļ¼‰", + "marginRight": "é é¢ēš„å³é‚Šč·-ä»„ęÆ«ē±³ē‚ŗå–®ä½ļ¼ˆē•™ē©ŗå‰‡ä½æē”Øé čØ­å€¼ļ¼‰", + "printBackground": "ęø²ęŸ“ē¶²ē«™ēš„čƒŒę™Æć€‚", + "defaultHeader": "å•Ÿē”Øé čØ­ęØ™é ­ļ¼ˆåēØ±å’Œé ē¢¼ļ¼‰", + "cssMediaType": "ę›“ę”¹é é¢ēš„ CSS åŖ’é«”é”žåž‹ć€‚", + "none": "ē„”", + "print": "列印", + "screen": "čž¢å¹•" + }, + "MarkdownToPDF": { + "tags": "ęØ™čØ˜,網頁內容,č½‰ę›,轉檔,md", + "title": "Markdown 轉 PDF", + "header": "Markdown 轉 PDF", + "submit": "č½‰ę›", + "help": "ę­£åœØé€²č”Œäø­", + "credit": "ę­¤ęœå‹™ä½æē”Ø WeasyPrint é€²č”Œč½‰ę›" + }, + "PDFToMarkdown": { + "tags": "ęØ™čØ˜čŖžčØ€,網頁內容,č½‰ę›,轉檔,md", + "title": "PDF 轉 Markdown", + "header": "PDF 轉 Markdown", + "submit": "č½‰ę›" + }, + "getPdfInfo": { + "tags": "č³‡čØŠ,資料,統計,ēµ±čØˆč³‡ę–™", + "title": "取得 PDF č³‡čØŠ", + "header": "取得 PDF č³‡čØŠ", + "submit": "å–å¾—č³‡čØŠ", + "downloadJson": "下載 JSON" + }, + "extractPage": { + "tags": "ęå–" + }, + "PdfToSinglePage": { + "tags": "å–®äø€é é¢" + }, + "showJS": { + "tags": "JS", + "title": "锯示 JavaScript", + "header": "锯示 JavaScript", + "downloadJS": "下載 JavaScript", + "submit": "锯示" + }, + "autoRedact": { + "tags": "唗改,éš±č—,唗黑,黑色,ęØ™čØ˜,遮蔽", + "title": "自動唗黑", + "header": "自動唗黑", + "colorLabel": "é”č‰²", + "textsToRedactLabel": "č¦å”—é»‘ēš„ę–‡å­—ļ¼ˆä»„č”Œåˆ†éš”ļ¼‰", + "textsToRedactPlaceholder": "例如 \\nę©ŸåÆ† \\nęœ€é«˜ę©ŸåÆ†", + "useRegexLabel": "ä½æē”Øę­£å‰‡č”Øé”å¼", + "wholeWordSearchLabel": "ę•“å€‹å–®č©žęœå°‹", + "customPaddingLabel": "č‡ŖčØ‚é”å¤–å”«å……", + "convertPDFToImageLabel": "將 PDF č½‰ę›ē‚ŗ PDF-å½±åƒļ¼ˆē”Øę–¼ē§»é™¤ę–¹ę”†å¾Œé¢ēš„ę–‡å­—ļ¼‰", + "submitButton": "送出" + }, + "redact": { + "tags": "唗改,éš±č—,唗黑,黑色,ęØ™čØ˜,遮蔽,手動", + "title": "手動唗黑", + "header": "手動唗黑", + "submit": "唗黑", + "textBasedRedaction": "ä»„ę–‡å­—ē‚ŗåŸŗē¤Žēš„å”—é»‘", + "pageBasedRedaction": "ä»„é é¢ē‚ŗåŸŗē¤Žēš„å”—é»‘", + "convertPDFToImageLabel": "將 PDF č½‰ę›ē‚ŗ PDF å½±åƒļ¼ˆē”Øę–¼ē§»é™¤é»‘ę”†å¾Œēš„ę–‡å­—ļ¼‰", + "pageRedactionNumbers": { + "title": "頁面", + "placeholder": "ļ¼ˆä¾‹å¦‚ 1,2,8 ꈖ 4,7,12-16 ꈖ 2n-1)" + }, + "redactionColor": { + "title": "å”—é»‘é”č‰²" + }, + "export": "åŒÆå‡ŗ", + "upload": "äøŠå‚³", + "boxRedaction": "ę”†éøå€åŸŸå”—é»‘", + "zoom": "縮放", + "zoomIn": "放大", + "zoomOut": "ēø®å°", + "nextPage": "下一頁", + "previousPage": "äøŠäø€é ", + "toggleSidebar": "åˆ‡ę›å“é‚Šę¬„", + "showThumbnails": "é”Æē¤ŗēø®åœ–", + "showDocumentOutline": "é”Æē¤ŗę–‡ä»¶å¤§ē¶±ļ¼ˆęŒ‰å…©äø‹åÆå±•é–‹/ę‘ŗē–Šę‰€ęœ‰é …ē›®ļ¼‰", + "showAttatchments": "锯示附件", + "showLayers": "é”Æē¤ŗåœ–å±¤ļ¼ˆęŒ‰å…©äø‹åÆå°‡ę‰€ęœ‰åœ–å±¤é‡čØ­ē‚ŗé čØ­ē‹€ę…‹ļ¼‰", + "colourPicker": "é”č‰²éøę“‡å™Ø", + "findCurrentOutlineItem": "å°‹ę‰¾ē›®å‰ēš„å¤§ē¶±é …ē›®", + "applyChanges": "å„—ē”Øč®Šę›“" + }, + "tableExtraxt": { + "tags": "CSV,č”Øę ¼ęå–,ęå–,č½‰ę›" + }, + "autoSizeSplitPDF": { + "tags": "pdf,分割,ꖇ件,組織" + }, + "overlay-pdfs": { + "tags": "覆蓋", + "header": "覆蓋 PDF ęŖ”ę”ˆ", + "baseFile": { + "label": "éøę“‡åŸŗåŗ• PDF ęŖ”ę”ˆ" + }, + "overlayFiles": { + "label": "選擇覆蓋 PDF ęŖ”ę”ˆ" + }, + "mode": { + "label": "éøę“‡č¦†č“‹ęØ”å¼", + "sequential": "åŗåˆ—č¦†č“‹", + "interleaved": "äŗ¤éŒÆč¦†č“‹", + "fixedRepeat": "å›ŗå®šé‡č¤‡č¦†č“‹" + }, + "counts": { + "label": "č¦†č“‹ę¬”ę•øļ¼ˆé©ē”Øę–¼å›ŗå®šé‡č¤‡ęØ”å¼ļ¼‰", + "placeholder": "č¼øå…„é€—č™Ÿåˆ†éš”ēš„ę¬”ę•øļ¼ˆä¾‹å¦‚ļ¼š2,3,1)" + }, + "position": { + "label": "éøę“‡č¦†č“‹ä½ē½®", + "foreground": "å‰ę™Æ", + "background": "čƒŒę™Æ" + }, + "submit": "送出" + }, + "split-by-sections": { + "tags": "å€ę®µåˆ†å‰², 劃分, 自訂", + "title": "ä¾å€ę®µåˆ†å‰² PDF", + "header": "將 PDF åˆ†å‰²ęˆå€ę®µ", + "horizontal": { + "label": "ę°“å¹³åŠƒåˆ†", + "placeholder": "č¼øå…„ę°“å¹³åŠƒåˆ†ēš„ę•øé‡" + }, + "vertical": { + "label": "åž‚ē›“åŠƒåˆ†", + "placeholder": "č¼øå…„åž‚ē›“åŠƒåˆ†ēš„ę•øé‡" + }, + "submit": "分割 PDF", + "merge": "ę˜Æå¦åˆä½µē‚ŗäø€å€‹ PDF" + }, + "AddStampRequest": { + "tags": "åœ–ē« ,ę–°å¢žåœ–ē‰‡,äø­åæƒå½±åƒ,ęµ®ę°“å°,PDF,嵌兄,自訂", + "header": "åœ–ē«  PDF", + "title": "åœ–ē«  PDF", + "stampType": "åœ–ē« é”žåž‹", + "stampText": "åœ–ē« ę–‡å­—", + "stampImage": "åœ–ē« åœ–ē‰‡", + "alphabet": "å­—ęÆč”Ø", + "fontSize": "字型/影像大小", + "rotation": "旋轉", + "opacity": "é€ę˜Žåŗ¦", + "position": "ä½ē½®", + "overrideX": "覆蓋 X 座標", + "overrideY": "覆蓋 Y 座標", + "customMargin": "č‡ŖčØ‚é‚Šē·£", + "customColor": "č‡ŖčØ‚ę–‡å­—é”č‰²", + "submit": "送出" + }, + "removeImagePdf": { + "tags": "ē§»é™¤åœ–ē‰‡,é é¢ę“ä½œ,後端,ä¼ŗęœå™Øē«Æ" + }, + "splitPdfByChapters": { + "tags": "分割,章節,書籤,敓理" + }, + "validateSignature": { + "tags": "簽章,é©—č­‰,ē¢ŗčŖ,pdf,ꆑ證,ę•øä½ē°½ē« ,驗證簽章,驗證ꆑ證", + "title": "é©—č­‰ PDF 簽章", + "header": "é©—č­‰ę•øä½ē°½ē« ", + "selectPDF": "éøę“‡å·²ē°½ē« ēš„ PDF ęŖ”ę”ˆ", + "submit": "驗證簽章", + "results": "é©—č­‰ēµęžœ", + "status": { + "_value": "狀態", + "valid": "꜉ꕈ", + "invalid": "ē„”ę•ˆ" + }, + "signer": "簽署者", + "date": "ę—„ęœŸ", + "reason": "原因", + "location": "ä½ē½®", + "noSignatures": "ę­¤ę–‡ä»¶äø­ęœŖę‰¾åˆ°ę•øä½ē°½ē« ", + "chain": { + "invalid": "ę†‘č­‰éˆé©—č­‰å¤±ę•— - 焔法驗證簽署者身份" + }, + "trust": { + "invalid": "ę†‘č­‰äøåœØäæ”ä»»å„²å­˜å€äø­ - 焔法驗證來源" + }, + "cert": { + "expired": "ę†‘č­‰å·²éŽęœŸ", + "revoked": "ę†‘č­‰å·²č¢«ę’¤éŠ·", + "info": "ę†‘č­‰č©³ē“°č³‡čØŠ", + "issuer": "ē™¼č”Œč€…", + "subject": "主旨", + "serialNumber": "åŗč™Ÿ", + "validFrom": "ęœ‰ę•ˆęœŸč‡Ŗ", + "validUntil": "ęœ‰ę•ˆęœŸč‡³", + "algorithm": "演算法", + "keySize": "金鑰長度", + "version": "ē‰ˆęœ¬", + "keyUsage": "金鑰用途", + "selfSigned": "č‡Ŗęˆ‘ē°½ē½²", + "bits": "位元" + }, + "signature": { + "info": "ē°½ē« č³‡čØŠ", + "_value": "簽章", + "mathValid": "ē°½ē« åœØę•øå­øäøŠęœ‰ę•ˆļ¼Œä½†ļ¼š" + }, + "selectCustomCert": "自訂 X.509 ę†‘č­‰ęŖ”ę”ˆļ¼ˆéøå”«ļ¼‰" + }, + "replace-color": { + "title": "取代-åč½‰é”č‰²", + "header": "取代-åč½‰ PDF é”č‰²", + "selectText": { + "1": "å–ä»£ęˆ–åč½‰é”č‰²éøé …", + "2": "é čØ­ļ¼ˆé čØ­é«˜å°ęÆ”åŗ¦é”č‰²ļ¼‰", + "3": "č‡ŖčØ‚ļ¼ˆč‡ŖčØ‚é”č‰²ļ¼‰", + "4": "å…ØéƒØåč½‰ļ¼ˆåč½‰ę‰€ęœ‰é”č‰²ļ¼‰", + "5": "é«˜å°ęÆ”åŗ¦é”č‰²éøé …", + "6": "黑底白字", + "7": "白底黑字", + "8": "é»‘åŗ•é»ƒå­—", + "9": "黑底綠字", + "10": "éøę“‡ę–‡å­—é”č‰²", + "11": "éøę“‡čƒŒę™Æé”č‰²" + }, + "submit": "取代" + }, + "replaceColorPdf": { + "tags": "å–ä»£é”č‰²,é é¢ę“ä½œ,後端,ä¼ŗęœå™Øē«Æ" + }, + "login": { + "title": "登兄", + "header": "登兄", + "signin": "登兄", + "rememberme": "čØ˜ä½ęˆ‘", + "invalid": "ä½æē”Øč€…åēØ±ęˆ–åÆ†ē¢¼ē„”ę•ˆć€‚", + "locked": "ę‚Øēš„åø³č™Ÿå·²č¢«éŽ–å®šć€‚", + "signinTitle": "請登兄", + "ssoSignIn": "透過 SSO 單一登兄", + "oAuth2AutoCreateDisabled": "OAuth 2.0 č‡Ŗå‹•å»ŗē«‹ä½æē”Øč€…åŠŸčƒ½å·²åœē”Ø", + "oAuth2AdminBlockedUser": "ē›®å‰äøå…čØ±ęœŖčØ»å†Šēš„ä½æē”Øč€…čØ»å†Šęˆ–ē™»å…„ć€‚č«‹čÆēµ”ē³»ēµ±ē®”ē†å“”ć€‚", + "oauth2RequestNotFound": "ę‰¾äøåˆ°é©—č­‰č«‹ę±‚", + "oauth2InvalidUserInfoResponse": "ä½æē”Øč€…č³‡čØŠå›žę‡‰ē„”ę•ˆ", + "oauth2invalidRequest": "č«‹ę±‚ē„”ę•ˆ", + "oauth2AccessDenied": "å­˜å–č¢«ę‹’", + "oauth2InvalidTokenResponse": "ē„”ę•ˆēš„ę¬Šę–å›žę‡‰", + "oauth2InvalidIdToken": "ē„”ę•ˆēš„čŗ«åˆ†ę¬Šę–", + "relyingPartyRegistrationNotFound": "ę‰¾äøåˆ°ä»»ä½•äæ”č³“ę–¹čØ»å†Šē“€éŒ„", + "userIsDisabled": "ä½æē”Øč€…å·²åœē”Øļ¼Œē›®å‰ę­¤ä½æē”Øč€…ē„”ę³•ē™»å…„ć€‚č«‹čÆēµ”ē³»ēµ±ē®”ē†å“”ć€‚", + "alreadyLoggedIn": "您已經登兄了", + "alreadyLoggedIn2": "éƒØč£ē½®ć€‚č«‹å…ˆå¾žé€™äŗ›č£ē½®ē™»å‡ŗå¾Œå†č©¦äø€ę¬”ć€‚", + "toManySessions": "ę‚Øęœ‰å¤Ŗå¤šä½æē”Øäø­ēš„å·„ä½œéšŽę®µ", + "logoutMessage": "You have been logged out." + }, + "pdfToSinglePage": { + "title": "PDF č½‰ē‚ŗå–®äø€é é¢", + "header": "PDF č½‰ē‚ŗå–®äø€é é¢", + "submit": "č½‰ę›ē‚ŗå–®äø€é é¢" + }, + "pageExtracter": { + "title": "ęå–é é¢", + "header": "ęå–é é¢", + "submit": "ęå–", + "placeholder": "ļ¼ˆä¾‹å¦‚ 1,2,8 ꈖ 4,7,12-16 ꈖ 2n-1)" + }, + "sanitizePDF": { + "title": "清理 PDF", + "header": "清理 PDF ęŖ”ę”ˆ", + "selectText": { + "1": "移除 JavaScript ę“ä½œ", + "2": "ē§»é™¤å…§åµŒę–‡ä»¶", + "3": "ē§»é™¤å…§åµŒ XMP č³‡čØŠ", + "4": "移除連結", + "5": "ē§»é™¤å­—åž‹", + "6": "移除文件中繼資料" + }, + "submit": "清理 PDF" + }, + "adjustContrast": { + "title": "čŖæę•“å°ęÆ”åŗ¦", + "header": "čŖæę•“å°ęÆ”åŗ¦", + "contrast": "å°ęÆ”åŗ¦ļ¼š", + "brightness": "亮度:", + "saturation": "é£½å’Œåŗ¦ļ¼š", + "download": "下載" + }, + "compress": { + "title": "壓縮", + "header": "壓縮 PDF", + "credit": "ę­¤ęœå‹™ä½æē”Ø qpdf é€²č”Œ PDF 壓縮/ęœ€ä½³åŒ–ć€‚", + "grayscale": { + "label": "å„—ē”Øē°éšŽé€²č”Œå£“ēø®" + }, + "selectText": { + "1": { + "_value": "å£“ēø®čØ­å®š", + "1": "1-3 ē‚ŗäø€čˆ¬ PDF å£“ēø®ļ¼Œ
4-6 ē‚ŗč¼•åŗ¦åœ–ē‰‡å£“ēø®ļ¼Œ
7-9 ē‚ŗé«˜å¼·åŗ¦åœ–ē‰‡å£“ēø®ļ¼Œå°‡å¤§å¹…é™ä½Žåœ–ē‰‡å“č³Ŗ" + }, + "2": "ęœ€ä½³åŒ–ē­‰ē“šļ¼š", + "4": "č‡Ŗå‹•ęØ”å¼ - 自動調敓品質使 PDF é”åˆ°ęŒ‡å®šēš„ęŖ”ę”ˆå¤§å°", + "5": "ęŒ‡å®šēš„ PDF ęŖ”ę”ˆå¤§å°ļ¼ˆä¾‹å¦‚ 25MB, 10.8MB, 25KB)" + }, + "submit": "壓縮" + }, + "decrypt": { + "passwordPrompt": "ę­¤ęŖ”ę”ˆå·²å—åÆ†ē¢¼äæč­·ć€‚č«‹č¼øå…„åÆ†ē¢¼ļ¼š", + "cancelled": "å·²å–ę¶ˆč™•ē† PDF:{0}", + "noPassword": "ęœŖęä¾›åŠ åÆ† PDF ēš„åÆ†ē¢¼ļ¼š{0}", + "invalidPassword": "č«‹é‡ę–°č¼øå…„ę­£ē¢ŗēš„åÆ†ē¢¼ć€‚", + "invalidPasswordHeader": "åÆ†ē¢¼éŒÆčŖ¤ęˆ–äøę”Æę“ēš„åŠ åÆ†ę–¹å¼ļ¼ŒPDF:{0}", + "unexpectedError": "č™•ē†ęŖ”ę”ˆę™‚ē™¼ē”ŸéŒÆčŖ¤ć€‚č«‹å†č©¦äø€ę¬”ć€‚", + "serverError": "č§£åÆ†ę™‚ē™¼ē”Ÿä¼ŗęœå™ØéŒÆčŖ¤ļ¼š{0}", + "success": "ęŖ”ę”ˆå·²ęˆåŠŸč§£åÆ†ć€‚" + }, + "multiTool-advert": { + "message": "ę­¤åŠŸčƒ½ä¹ŸåÆä»„åœØęˆ‘å€‘ēš„č¤‡åˆå·„å…·é é¢äø­ä½æē”Øć€‚å‰å¾€ęŸ„ēœ‹äø¦é«”é©—ę›“å¼·å¤§ēš„é€é ę“ä½œä»‹é¢åŠå…¶ä»–é€²éšŽåŠŸčƒ½ļ¼" + }, + "pageRemover": { + "title": "é é¢ē§»é™¤", + "header": "PDF é é¢ē§»é™¤", + "pagesToDelete": "č¦åˆŖé™¤ēš„é é¢ļ¼ˆč¼øå…„ä»„é€—č™Ÿåˆ†éš”ēš„é ē¢¼ļ¼‰ļ¼š", + "submit": "åˆŖé™¤é é¢", + "placeholder": "ļ¼ˆä¾‹å¦‚ 1,2,6 ꈖ 1-10,15-30)" + }, + "imageToPDF": { + "title": "åœ–ē‰‡č½‰ PDF", + "header": "åœ–ē‰‡č½‰ PDF", + "submit": "č½‰ę›", + "selectLabel": "å½±åƒé©ę‡‰éøé …", + "fillPage": "唫充頁面", + "fitDocumentToImage": "é©ę‡‰å½±åƒåˆ°é é¢", + "maintainAspectRatio": "äæęŒé•·åÆ¬ęÆ”", + "selectText": { + "2": "自動旋轉 PDF", + "3": "å¤šę–‡ä»¶é‚č¼Æļ¼ˆåƒ…åœØč™•ē†å¤šå€‹å½±åƒę™‚å•Ÿē”Øļ¼‰", + "4": "åˆä½µē‚ŗå–®äø€ PDF", + "5": "č½‰ę›ē‚ŗå–®ēØēš„ PDF" + } + }, + "PDFToCSV": { + "title": "PDF č½‰ę›ē‚ŗ CSV", + "header": "PDF č½‰ę›ē‚ŗ CSV", + "prompt": "éøę“‡č¦ęå–č”Øę ¼ēš„é é¢", + "submit": "ęå–" + }, + "split-by-size-or-count": { + "title": "ä¾å¤§å°ęˆ–ę•øé‡åˆ†å‰² PDF", + "header": "ä¾å¤§å°ęˆ–ę•øé‡åˆ†å‰² PDF", + "type": { + "label": "éøę“‡åˆ†å‰²é”žåž‹", + "size": "依大小", + "pageCount": "ä¾é ę•ø", + "docCount": "ä¾ę–‡ä»¶ę•øé‡" + }, + "value": { + "label": "輸兄值", + "placeholder": "č¼øå…„å¤§å°ļ¼ˆä¾‹å¦‚ļ¼š2MB ꈖ 3KBļ¼‰ęˆ–ę•øé‡ļ¼ˆä¾‹å¦‚ļ¼š5)" + }, + "submit": "送出" + }, + "printFile": { + "title": "åˆ—å°ęŖ”ę”ˆ", + "header": "ä½æē”Øå°č”Øę©Ÿå°å‡ŗęŖ”ę”ˆ", + "selectText": { + "1": "éøę“‡č¦å°ēš„ęŖ”ę”ˆ", + "2": "č¼øå…„å°č”Øę©ŸåēØ±" + }, + "submit": "列印" + }, + "licenses": { + "nav": "ęŽˆę¬Šę¢ę¬¾", + "title": "ē¬¬äø‰ę–¹ęŽˆę¬Šę¢ę¬¾", + "header": "ē¬¬äø‰ę–¹ęŽˆę¬Šę¢ę¬¾", + "module": "樔組", + "version": "ē‰ˆęœ¬", + "license": "ęŽˆę¬Šę¢ę¬¾" + }, + "survey": { + "nav": "å•å·čŖæęŸ„", + "title": "Stirling-PDF å•å·čŖæęŸ„", + "description": "Stirling-PDF ę²’ęœ‰čæ½č¹¤åŠŸčƒ½ļ¼Œå› ę­¤ęˆ‘å€‘åøŒęœ›č½å–ä½æē”Øč€…ēš„ę„č¦‹ä¾†ę”¹é€² Stirling-PDF!", + "changes": "Stirling-PDF č‡ŖäøŠę¬”čŖæęŸ„ä»„ä¾†å·²ęœ‰ę‰€ę”¹č®Šļ¼ę¬²äŗ†č§£ę›“å¤šč³‡čØŠļ¼Œč«‹ęŸ„ēœ‹ęˆ‘å€‘ēš„éƒØč½ę ¼ę–‡ē« ļ¼š", + "changes2": "éšØč‘—é€™äŗ›č®Šę›“ļ¼Œęˆ‘å€‘ę­£åœØē²å¾—ä»˜č²»ēš„å•†ę„­ę”Æę“å’Œč³‡é‡‘", + "please": "č«‹č€ƒę…®åƒčˆ‡ęˆ‘å€‘ēš„å•å·čŖæęŸ„ļ¼", + "disabled": "ļ¼ˆå•å·čŖæęŸ„å½ˆå‡ŗč¦–ēŖ—å°‡åœØå¾ŒēŗŒę›“ę–°äø­åœē”Øļ¼Œä½†ä»åÆåœØé å°¾ä½æē”Øļ¼‰", + "button": "åƒčˆ‡å•å·čŖæęŸ„", + "dontShowAgain": "äøč¦å†ę¬”é”Æē¤ŗ", + "meeting": { + "1": "å¦‚ęžœę‚ØåœØå·„ä½œäø­ä½æē”Ø Stirling PDFļ¼Œęˆ‘å€‘å¾ˆåøŒęœ›čƒ½čˆ‡ę‚Øäŗ¤ęµć€‚ęˆ‘å€‘å°‡ęä¾›ęŠ€č”“ę”Æę“č«®č©¢ļ¼Œä»„ę›å– 15 åˆ†é˜ēš„ä½æē”Øč€…é«”é©—å›žé„‹äŗ¤ęµć€‚", + "2": "é€™ę˜Æäø€å€‹ę©Ÿęœƒč®“ę‚Øļ¼š", + "3": "ē²å¾—é—œę–¼éƒØē½²ć€ę•“åˆęˆ–ē–‘é›£ęŽ’č§£ę–¹é¢ēš„å”åŠ©", + "4": "é‡å°ę•ˆčƒ½ć€ē‰¹ę®Šę”ˆä¾‹å’Œē¼ŗå°‘ēš„åŠŸčƒ½ęä¾›ē›“ęŽ„ę„č¦‹å›žé„‹", + "5": "å”åŠ©ęˆ‘å€‘ę”¹č‰Æ Stirling PDF ä»„ē¬¦åˆåÆ¦éš›ä¼ę„­ä½æē”Øéœ€ę±‚", + "6": "å¦‚ęžœę‚Øęœ‰čˆˆč¶£ļ¼ŒåÆä»„ē›“ęŽ„é ē“„ę™‚é–“čˆ‡ęˆ‘å€‘ēš„åœ˜éšŠäŗ¤ęµć€‚ļ¼ˆåƒ…ęä¾›č‹±čŖžęœå‹™ļ¼‰", + "7": "ęœŸå¾…ę·±å…„äŗ†č§£ę‚Øēš„ä½æē”Øęƒ…å¢ƒļ¼Œč®“ Stirling PDF č®Šå¾—ę›“å„½ļ¼", + "notInterested": "äøę˜Æä¼ę„­ä½æē”Øč€…ęˆ–å°ęœƒč­°äøę„Ÿčˆˆč¶£ļ¼Ÿ", + "button": "é ē“„ęœƒč­°" + } + }, + "removeImage": { + "title": "ē§»é™¤åœ–ē‰‡", + "header": "ē§»é™¤åœ–ē‰‡", + "removeImage": "ē§»é™¤åœ–ē‰‡", + "submit": "ē§»é™¤åœ–ē‰‡" + }, + "splitByChapters": { + "title": "ä¾ē« ēÆ€åˆ†å‰² PDF", + "header": "ä¾ē« ēÆ€åˆ†å‰² PDF", + "bookmarkLevel": "ę›øē±¤å±¤ē“š", + "includeMetadata": "åŒ…å«äø­ē¹¼č³‡ę–™", + "allowDuplicates": "å…čØ±é‡č¤‡", + "desc": { + "1": "ę­¤å·„å…·ęœƒę ¹ę“š PDF ęŖ”ę”ˆēš„ē« ēÆ€ēµę§‹å°‡å…¶åˆ†å‰²ęˆå¤šå€‹ PDF怂", + "2": "ę›øē±¤å±¤ē“šļ¼šéøę“‡ē”Øę–¼åˆ†å‰²ēš„ę›øē±¤å±¤ē“šļ¼ˆ0 č”Øē¤ŗęœ€äøŠå±¤ļ¼Œ1 č”Øē¤ŗē¬¬äŗŒå±¤ļ¼Œä¾ę­¤é”žęŽØļ¼‰ć€‚", + "3": "åŒ…å«äø­ē¹¼č³‡ę–™ļ¼šå¦‚ęžœå‹¾éøļ¼ŒåŽŸå§‹ PDF ēš„äø­ē¹¼č³‡ę–™å°‡åŒ…å«åœØęÆå€‹åˆ†å‰²å¾Œēš„ PDF 中。", + "4": "å…čØ±é‡č¤‡ļ¼šå¦‚ęžœå‹¾éøļ¼Œå…čØ±åŒäø€é é¢äøŠēš„å¤šå€‹ę›øē±¤å»ŗē«‹ēØē«‹ēš„ PDF怂" + }, + "submit": "分割 PDF" + }, + "fileChooser": { + "click": "é»žéø", + "or": "ꈖ", + "dragAndDrop": "ę‹–ę”¾ęŖ”ę”ˆ", + "dragAndDropPDF": "拖放 PDF ęŖ”ę”ˆ", + "dragAndDropImage": "ę‹–ę”¾åœ–ē‰‡ęŖ”ę”ˆ", + "hoveredDragAndDrop": "å°‡ęŖ”ę”ˆę‹–ę”¾č‡³ę­¤", + "extractPDF": "處理中..." + }, + "releases": { + "footer": "ē‰ˆęœ¬č³‡čØŠ", + "title": "ē‰ˆęœ¬č³‡čØŠ", + "header": "ē‰ˆęœ¬č³‡čØŠ", + "current": { + "version": "ē›®å‰ē‰ˆęœ¬" + }, + "note": "ē‰ˆęœ¬č³‡čØŠåƒ…ęä¾›č‹±ę–‡ē‰ˆęœ¬" + }, + "cookieBanner": { + "popUp": { + "title": "ęˆ‘å€‘å¦‚ä½•ä½æē”Ø Cookies", + "description": { + "1": "ęˆ‘å€‘ä½æē”Ø Cookies å’Œå…¶ä»–ęŠ€č”“ä¾†č®“ Stirling PDF č®Šå¾—ę›“å„½ā€”ā€”å¹«åŠ©ęˆ‘å€‘ę”¹å–„å·„å…·äø¦ē¹¼ēŗŒå‰µé€ ę‚Øęœƒå–œę„›ēš„ę–°åŠŸčƒ½", + "2": "å¦‚ęžœę‚Øä»äøęƒ³ļ¼Œé»žę“Šć€Œäøļ¼Œč¬č¬ć€åŖęœƒé–‹å•Ÿåæ…č¦ēš„ Cookies å„½č®“ē¶²ē«™åŠŸčƒ½äæęŒé‹ä½œ" + }, + "acceptAllBtn": "ęŽ„å—", + "acceptNecessaryBtn": "äøļ¼Œč¬č¬", + "showPreferencesBtn": "ē®”ē†åå„½čØ­å®š" + }, + "preferencesModal": { + "title": "å–œå„½čØ­å®šäø­åæƒ", + "acceptAllBtn": "å…ØéƒØęŽ„å—", + "acceptNecessaryBtn": "å…ØéƒØę‹’ēµ•", + "savePreferencesBtn": "å„²å­˜čØ­å®š", + "closeIconLabel": "é—œé–‰č¦–ēŖ—", + "serviceCounterLabel": "ęœå‹™|ęœå‹™", + "subtitle": "Cookies ēš„ē”Øé€”", + "description": { + "1": "Stirling PDF 使用 Cookies čˆ‡å…¶ä»–ē›øä¼¼ęŠ€č”“åŽ»ę”¹å–„ę‚Øēš„é«”é©—å’Œåˆ†ęžę‚Øå¦‚ä½•ä½æē”Øęˆ‘å€‘ēš„å·„å…·ć€‚é€™ęœ‰åŠ©ę–¼ęˆ‘å€‘ę”¹å–„ę•ˆčƒ½ć€é–‹ē™¼ę‚Øę³Øē›®ēš„åŠŸčƒ½ļ¼Œå’Œęä¾›ä½æē”Øč€…å”åŠ©ć€‚", + "2": "Stirling PDF äøčƒ½ā€”ā€”äø”ę°øé äøęœƒā€”ā€”čæ½č¹¤ęˆ–å­˜å–ę‚Øēš„ę–‡ä»¶ć€‚", + "3": "ę‚Øēš„éš±ē§å’Œäæ”ä»»ę˜Æęˆ‘å€‘ēš„ę øåæƒē†åæµć€‚" + }, + "necessary": { + "title": { + "1": "åæ…č¦ēš„ Cookies", + "2": "ę°øé é–‹å•Ÿ" + }, + "description": "這些 Cookies å°ē¶²ē«™ę­£åøøé‹ä½œč‡³é—œé‡č¦ć€‚å®ƒå€‘č®“ę øåæƒåŠŸčƒ½ļ¼Œåƒę˜Æéš±ē§čØ­å®šć€ē™»å…„ć€å”«å…„č”Øę ¼čƒ½å¤ é‹ä½œā€”ā€”é€™ä¹Ÿę˜Æē‚ŗä»€éŗ¼å®ƒå€‘äøčƒ½č¢«é—œęŽ‰ć€‚" + }, + "analytics": { + "title": "åˆ†ęž Cookies", + "description": "這些 Cookies å¹«åŠ©ęˆ‘å€‘åˆ†ęžę‚Øå¦‚ä½•ä½æē”Øęˆ‘å€‘ēš„å·„å…·ļ¼Œå„½č®“ęˆ‘å€‘čƒ½å°ˆę³ØåœØę§‹å»ŗē¤¾ē¾¤ęœ€é‡č¦–ēš„åŠŸčƒ½ć€‚å„˜ē®”ę”¾åæƒā€”ā€” Stirling PDF äøęœƒäø”ę°øäøčæ½č¹¤ę‚Øēš„ę–‡ä»¶" + } + } + } +} \ No newline at end of file diff --git a/frontend/public/logo-tooltip.svg b/frontend/public/logo-tooltip.svg new file mode 100644 index 000000000..2d53f287c --- /dev/null +++ b/frontend/public/logo-tooltip.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/frontend/public/logo192.png b/frontend/public/logo192.png new file mode 100644 index 000000000..2994ca293 Binary files /dev/null and b/frontend/public/logo192.png differ diff --git a/frontend/public/logo512.png b/frontend/public/logo512.png new file mode 100644 index 000000000..b48155073 Binary files /dev/null and b/frontend/public/logo512.png differ diff --git a/frontend/public/manifest.json b/frontend/public/manifest.json new file mode 100644 index 000000000..080d6c77a --- /dev/null +++ b/frontend/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/frontend/public/pdf.js b/frontend/public/pdf.js new file mode 100644 index 000000000..c31b6ab62 --- /dev/null +++ b/frontend/public/pdf.js @@ -0,0 +1,22 @@ +/** + * @licstart The following is the entire license notice for the + * JavaScript code in this page + * + * Copyright 2023 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @licend The above is the entire license notice for the + * JavaScript code in this page + */ +!function webpackUniversalModuleDefinition(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=t.pdfjsLib=e():"function"==typeof define&&define.amd?define("pdfjs-dist/build/pdf",[],(()=>t.pdfjsLib=e())):"object"==typeof exports?exports["pdfjs-dist/build/pdf"]=t.pdfjsLib=e():t["pdfjs-dist/build/pdf"]=t.pdfjsLib=e()}(globalThis,(()=>(()=>{"use strict";var __webpack_modules__=[,(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0});e.VerbosityLevel=e.Util=e.UnknownErrorException=e.UnexpectedResponseException=e.TextRenderingMode=e.RenderingIntentFlag=e.PromiseCapability=e.PermissionFlag=e.PasswordResponses=e.PasswordException=e.PageActionEventType=e.OPS=e.MissingPDFException=e.MAX_IMAGE_SIZE_TO_CACHE=e.LINE_FACTOR=e.LINE_DESCENT_FACTOR=e.InvalidPDFException=e.ImageKind=e.IDENTITY_MATRIX=e.FormatError=e.FeatureTest=e.FONT_IDENTITY_MATRIX=e.DocumentActionEventType=e.CMapCompressionType=e.BaseException=e.BASELINE_FACTOR=e.AnnotationType=e.AnnotationReplyType=e.AnnotationPrefix=e.AnnotationMode=e.AnnotationFlag=e.AnnotationFieldFlag=e.AnnotationEditorType=e.AnnotationEditorPrefix=e.AnnotationEditorParamsType=e.AnnotationBorderStyleType=e.AnnotationActionEventType=e.AbortException=void 0;e.assert=function assert(t,e){t||unreachable(e)};e.bytesToString=bytesToString;e.createValidAbsoluteUrl=function createValidAbsoluteUrl(t,e=null,i=null){if(!t)return null;try{if(i&&"string"==typeof t){if(i.addDefaultProtocol&&t.startsWith("www.")){const e=t.match(/\./g);e?.length>=2&&(t=`http://${t}`)}if(i.tryConvertEncoding)try{t=stringToUTF8String(t)}catch{}}const s=e?new URL(t,e):new URL(t);if(function _isValidProtocol(t){switch(t?.protocol){case"http:":case"https:":case"ftp:":case"mailto:":case"tel:":return!0;default:return!1}}(s))return s}catch{}return null};e.getModificationDate=function getModificationDate(t=new Date){return[t.getUTCFullYear().toString(),(t.getUTCMonth()+1).toString().padStart(2,"0"),t.getUTCDate().toString().padStart(2,"0"),t.getUTCHours().toString().padStart(2,"0"),t.getUTCMinutes().toString().padStart(2,"0"),t.getUTCSeconds().toString().padStart(2,"0")].join("")};e.getUuid=function getUuid(){if("undefined"!=typeof crypto&&"function"==typeof crypto?.randomUUID)return crypto.randomUUID();const t=new Uint8Array(32);if("undefined"!=typeof crypto&&"function"==typeof crypto?.getRandomValues)crypto.getRandomValues(t);else for(let e=0;e<32;e++)t[e]=Math.floor(255*Math.random());return bytesToString(t)};e.getVerbosityLevel=function getVerbosityLevel(){return n};e.info=function info(t){n>=s.INFOS&&console.log(`Info: ${t}`)};e.isArrayBuffer=function isArrayBuffer(t){return"object"==typeof t&&void 0!==t?.byteLength};e.isArrayEqual=function isArrayEqual(t,e){if(t.length!==e.length)return!1;for(let i=0,s=t.length;ie?e.normalize("NFKC"):h.get(i)))};e.objectFromMap=function objectFromMap(t){const e=Object.create(null);for(const[i,s]of t)e[i]=s;return e};e.objectSize=function objectSize(t){return Object.keys(t).length};e.setVerbosityLevel=function setVerbosityLevel(t){Number.isInteger(t)&&(n=t)};e.shadow=shadow;e.string32=function string32(t){return String.fromCharCode(t>>24&255,t>>16&255,t>>8&255,255&t)};e.stringToBytes=stringToBytes;e.stringToPDFString=function stringToPDFString(t){if(t[0]>="ĆÆ"){let e;"þ"===t[0]&&"Ćæ"===t[1]?e="utf-16be":"Ćæ"===t[0]&&"þ"===t[1]?e="utf-16le":"ĆÆ"===t[0]&&"Ā»"===t[1]&&"Āæ"===t[2]&&(e="utf-8");if(e)try{const i=new TextDecoder(e,{fatal:!0}),s=stringToBytes(t);return i.decode(s)}catch(t){warn(`stringToPDFString: "${t}".`)}}const e=[];for(let i=0,s=t.length;i=s.WARNINGS&&console.log(`Warning: ${t}`)}function unreachable(t){throw new Error(t)}function shadow(t,e,i,s=!1){Object.defineProperty(t,e,{value:i,enumerable:!s,configurable:!0,writable:!1});return i}const a=function BaseExceptionClosure(){function BaseException(t,e){this.constructor===BaseException&&unreachable("Cannot initialize BaseException.");this.message=t;this.name=e}BaseException.prototype=new Error;BaseException.constructor=BaseException;return BaseException}();e.BaseException=a;e.PasswordException=class PasswordException extends a{constructor(t,e){super(t,"PasswordException");this.code=e}};e.UnknownErrorException=class UnknownErrorException extends a{constructor(t,e){super(t,"UnknownErrorException");this.details=e}};e.InvalidPDFException=class InvalidPDFException extends a{constructor(t){super(t,"InvalidPDFException")}};e.MissingPDFException=class MissingPDFException extends a{constructor(t){super(t,"MissingPDFException")}};e.UnexpectedResponseException=class UnexpectedResponseException extends a{constructor(t,e){super(t,"UnexpectedResponseException");this.status=e}};e.FormatError=class FormatError extends a{constructor(t){super(t,"FormatError")}};e.AbortException=class AbortException extends a{constructor(t){super(t,"AbortException")}};function bytesToString(t){"object"==typeof t&&void 0!==t?.length||unreachable("Invalid argument for bytesToString");const e=t.length,i=8192;if(et.toString(16).padStart(2,"0")));e.Util=class Util{static makeHexColor(t,e,i){return`#${r[t]}${r[e]}${r[i]}`}static scaleMinMax(t,e){let i;if(t[0]){if(t[0]<0){i=e[0];e[0]=e[1];e[1]=i}e[0]*=t[0];e[1]*=t[0];if(t[3]<0){i=e[2];e[2]=e[3];e[3]=i}e[2]*=t[3];e[3]*=t[3]}else{i=e[0];e[0]=e[2];e[2]=i;i=e[1];e[1]=e[3];e[3]=i;if(t[1]<0){i=e[2];e[2]=e[3];e[3]=i}e[2]*=t[1];e[3]*=t[1];if(t[2]<0){i=e[0];e[0]=e[1];e[1]=i}e[0]*=t[2];e[1]*=t[2]}e[0]+=t[4];e[1]+=t[4];e[2]+=t[5];e[3]+=t[5]}static transform(t,e){return[t[0]*e[0]+t[2]*e[1],t[1]*e[0]+t[3]*e[1],t[0]*e[2]+t[2]*e[3],t[1]*e[2]+t[3]*e[3],t[0]*e[4]+t[2]*e[5]+t[4],t[1]*e[4]+t[3]*e[5]+t[5]]}static applyTransform(t,e){return[t[0]*e[0]+t[1]*e[2]+e[4],t[0]*e[1]+t[1]*e[3]+e[5]]}static applyInverseTransform(t,e){const i=e[0]*e[3]-e[1]*e[2];return[(t[0]*e[3]-t[1]*e[2]+e[2]*e[5]-e[4]*e[3])/i,(-t[0]*e[1]+t[1]*e[0]+e[4]*e[1]-e[5]*e[0])/i]}static getAxialAlignedBoundingBox(t,e){const i=this.applyTransform(t,e),s=this.applyTransform(t.slice(2,4),e),n=this.applyTransform([t[0],t[3]],e),a=this.applyTransform([t[2],t[1]],e);return[Math.min(i[0],s[0],n[0],a[0]),Math.min(i[1],s[1],n[1],a[1]),Math.max(i[0],s[0],n[0],a[0]),Math.max(i[1],s[1],n[1],a[1])]}static inverseTransform(t){const e=t[0]*t[3]-t[1]*t[2];return[t[3]/e,-t[1]/e,-t[2]/e,t[0]/e,(t[2]*t[5]-t[4]*t[3])/e,(t[4]*t[1]-t[5]*t[0])/e]}static singularValueDecompose2dScale(t){const e=[t[0],t[2],t[1],t[3]],i=t[0]*e[0]+t[1]*e[2],s=t[0]*e[1]+t[1]*e[3],n=t[2]*e[0]+t[3]*e[2],a=t[2]*e[1]+t[3]*e[3],r=(i+a)/2,o=Math.sqrt((i+a)**2-4*(i*a-n*s))/2,l=r+o||1,h=r-o||1;return[Math.sqrt(l),Math.sqrt(h)]}static normalizeRect(t){const e=t.slice(0);if(t[0]>t[2]){e[0]=t[2];e[2]=t[0]}if(t[1]>t[3]){e[1]=t[3];e[3]=t[1]}return e}static intersect(t,e){const i=Math.max(Math.min(t[0],t[2]),Math.min(e[0],e[2])),s=Math.min(Math.max(t[0],t[2]),Math.max(e[0],e[2]));if(i>s)return null;const n=Math.max(Math.min(t[1],t[3]),Math.min(e[1],e[3])),a=Math.min(Math.max(t[1],t[3]),Math.max(e[1],e[3]));return n>a?null:[i,n,s,a]}static bezierBoundingBox(t,e,i,s,n,a,r,o){const l=[],h=[[],[]];let c,d,u,p,g,m,f,b;for(let h=0;h<2;++h){if(0===h){d=6*t-12*i+6*n;c=-3*t+9*i-9*n+3*r;u=3*i-3*t}else{d=6*e-12*s+6*a;c=-3*e+9*s-9*a+3*o;u=3*s-3*e}if(Math.abs(c)<1e-12){if(Math.abs(d)<1e-12)continue;p=-u/d;0{this.resolve=e=>{this.#t=!0;t(e)};this.reject=t=>{this.#t=!0;e(t)}}))}get settled(){return this.#t}};let l=null,h=null;e.AnnotationPrefix="pdfjs_internal_id_"},(__unused_webpack_module,exports,__w_pdfjs_require__)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.RenderTask=exports.PDFWorkerUtil=exports.PDFWorker=exports.PDFPageProxy=exports.PDFDocumentProxy=exports.PDFDocumentLoadingTask=exports.PDFDataRangeTransport=exports.LoopbackPort=exports.DefaultStandardFontDataFactory=exports.DefaultFilterFactory=exports.DefaultCanvasFactory=exports.DefaultCMapReaderFactory=void 0;Object.defineProperty(exports,"SVGGraphics",{enumerable:!0,get:function(){return _displaySvg.SVGGraphics}});exports.build=void 0;exports.getDocument=getDocument;exports.version=void 0;var _util=__w_pdfjs_require__(1),_annotation_storage=__w_pdfjs_require__(3),_display_utils=__w_pdfjs_require__(6),_font_loader=__w_pdfjs_require__(9),_displayNode_utils=__w_pdfjs_require__(10),_canvas=__w_pdfjs_require__(11),_worker_options=__w_pdfjs_require__(14),_message_handler=__w_pdfjs_require__(15),_metadata=__w_pdfjs_require__(16),_optional_content_config=__w_pdfjs_require__(17),_transport_stream=__w_pdfjs_require__(18),_displayFetch_stream=__w_pdfjs_require__(19),_displayNetwork=__w_pdfjs_require__(22),_displayNode_stream=__w_pdfjs_require__(23),_displaySvg=__w_pdfjs_require__(24),_xfa_text=__w_pdfjs_require__(25);const DEFAULT_RANGE_CHUNK_SIZE=65536,RENDERING_CANCELLED_TIMEOUT=100,DELAYED_CLEANUP_TIMEOUT=5e3,DefaultCanvasFactory=_util.isNodeJS?_displayNode_utils.NodeCanvasFactory:_display_utils.DOMCanvasFactory;exports.DefaultCanvasFactory=DefaultCanvasFactory;const DefaultCMapReaderFactory=_util.isNodeJS?_displayNode_utils.NodeCMapReaderFactory:_display_utils.DOMCMapReaderFactory;exports.DefaultCMapReaderFactory=DefaultCMapReaderFactory;const DefaultFilterFactory=_util.isNodeJS?_displayNode_utils.NodeFilterFactory:_display_utils.DOMFilterFactory;exports.DefaultFilterFactory=DefaultFilterFactory;const DefaultStandardFontDataFactory=_util.isNodeJS?_displayNode_utils.NodeStandardFontDataFactory:_display_utils.DOMStandardFontDataFactory;exports.DefaultStandardFontDataFactory=DefaultStandardFontDataFactory;function getDocument(t){"string"==typeof t||t instanceof URL?t={url:t}:(0,_util.isArrayBuffer)(t)&&(t={data:t});if("object"!=typeof t)throw new Error("Invalid parameter in getDocument, need parameter object.");if(!t.url&&!t.data&&!t.range)throw new Error("Invalid parameter object: need either .data, .range or .url");const e=new PDFDocumentLoadingTask,{docId:i}=e,s=t.url?getUrlProp(t.url):null,n=t.data?getDataProp(t.data):null,a=t.httpHeaders||null,r=!0===t.withCredentials,o=t.password??null,l=t.range instanceof PDFDataRangeTransport?t.range:null,h=Number.isInteger(t.rangeChunkSize)&&t.rangeChunkSize>0?t.rangeChunkSize:DEFAULT_RANGE_CHUNK_SIZE;let c=t.worker instanceof PDFWorker?t.worker:null;const d=t.verbosity,u="string"!=typeof t.docBaseUrl||(0,_display_utils.isDataScheme)(t.docBaseUrl)?null:t.docBaseUrl,p="string"==typeof t.cMapUrl?t.cMapUrl:null,g=!1!==t.cMapPacked,m=t.CMapReaderFactory||DefaultCMapReaderFactory,f="string"==typeof t.standardFontDataUrl?t.standardFontDataUrl:null,b=t.StandardFontDataFactory||DefaultStandardFontDataFactory,A=!0!==t.stopAtErrors,_=Number.isInteger(t.maxImageSize)&&t.maxImageSize>-1?t.maxImageSize:-1,v=!1!==t.isEvalSupported,y="boolean"==typeof t.isOffscreenCanvasSupported?t.isOffscreenCanvasSupported:!_util.isNodeJS,S=Number.isInteger(t.canvasMaxAreaInBytes)?t.canvasMaxAreaInBytes:-1,E="boolean"==typeof t.disableFontFace?t.disableFontFace:_util.isNodeJS,x=!0===t.fontExtraProperties,w=!0===t.enableXfa,C=t.ownerDocument||globalThis.document,T=!0===t.disableRange,P=!0===t.disableStream,M=!0===t.disableAutoFetch,k=!0===t.pdfBug,F=l?l.length:t.length??NaN,R="boolean"==typeof t.useSystemFonts?t.useSystemFonts:!_util.isNodeJS&&!E,D="boolean"==typeof t.useWorkerFetch?t.useWorkerFetch:m===_display_utils.DOMCMapReaderFactory&&b===_display_utils.DOMStandardFontDataFactory&&p&&f&&(0,_display_utils.isValidFetchUrl)(p,document.baseURI)&&(0,_display_utils.isValidFetchUrl)(f,document.baseURI),I=t.canvasFactory||new DefaultCanvasFactory({ownerDocument:C}),L=t.filterFactory||new DefaultFilterFactory({docId:i,ownerDocument:C});(0,_util.setVerbosityLevel)(d);const O={canvasFactory:I,filterFactory:L};if(!D){O.cMapReaderFactory=new m({baseUrl:p,isCompressed:g});O.standardFontDataFactory=new b({baseUrl:f})}if(!c){const t={verbosity:d,port:_worker_options.GlobalWorkerOptions.workerPort};c=t.port?PDFWorker.fromPort(t):new PDFWorker(t);e._worker=c}const N={docId:i,apiVersion:"3.11.174",data:n,password:o,disableAutoFetch:M,rangeChunkSize:h,length:F,docBaseUrl:u,enableXfa:w,evaluatorOptions:{maxImageSize:_,disableFontFace:E,ignoreErrors:A,isEvalSupported:v,isOffscreenCanvasSupported:y,canvasMaxAreaInBytes:S,fontExtraProperties:x,useSystemFonts:R,cMapUrl:D?p:null,standardFontDataUrl:D?f:null}},B={ignoreErrors:A,isEvalSupported:v,disableFontFace:E,fontExtraProperties:x,enableXfa:w,ownerDocument:C,disableAutoFetch:M,pdfBug:k,styleElement:null};c.promise.then((function(){if(e.destroyed)throw new Error("Loading aborted");const t=_fetchDocument(c,N),o=new Promise((function(t){let e;if(l)e=new _transport_stream.PDFDataTransportStream({length:F,initialData:l.initialData,progressiveDone:l.progressiveDone,contentDispositionFilename:l.contentDispositionFilename,disableRange:T,disableStream:P},l);else if(!n){e=(t=>_util.isNodeJS?new _displayNode_stream.PDFNodeStream(t):(0,_display_utils.isValidFetchUrl)(t.url)?new _displayFetch_stream.PDFFetchStream(t):new _displayNetwork.PDFNetworkStream(t))({url:s,length:F,httpHeaders:a,withCredentials:r,rangeChunkSize:h,disableRange:T,disableStream:P})}t(e)}));return Promise.all([t,o]).then((function([t,s]){if(e.destroyed)throw new Error("Loading aborted");const n=new _message_handler.MessageHandler(i,t,c.port),a=new WorkerTransport(n,e,s,B,O);e._transport=a;n.send("Ready",null)}))})).catch(e._capability.reject);return e}async function _fetchDocument(t,e){if(t.destroyed)throw new Error("Worker was destroyed");const i=await t.messageHandler.sendWithPromise("GetDocRequest",e,e.data?[e.data.buffer]:null);if(t.destroyed)throw new Error("Worker was destroyed");return i}function getUrlProp(t){if(t instanceof URL)return t.href;try{return new URL(t,window.location).href}catch{if(_util.isNodeJS&&"string"==typeof t)return t}throw new Error("Invalid PDF url data: either string or URL-object is expected in the url property.")}function getDataProp(t){if(_util.isNodeJS&&"undefined"!=typeof Buffer&&t instanceof Buffer)throw new Error("Please provide binary data as `Uint8Array`, rather than `Buffer`.");if(t instanceof Uint8Array&&t.byteLength===t.buffer.byteLength)return t;if("string"==typeof t)return(0,_util.stringToBytes)(t);if("object"==typeof t&&!isNaN(t?.length)||(0,_util.isArrayBuffer)(t))return new Uint8Array(t);throw new Error("Invalid PDF binary data: either TypedArray, string, or array-like object is expected in the data property.")}class PDFDocumentLoadingTask{static#e=0;constructor(){this._capability=new _util.PromiseCapability;this._transport=null;this._worker=null;this.docId="d"+PDFDocumentLoadingTask.#e++;this.destroyed=!1;this.onPassword=null;this.onProgress=null}get promise(){return this._capability.promise}async destroy(){this.destroyed=!0;try{this._worker?.port&&(this._worker._pendingDestroy=!0);await(this._transport?.destroy())}catch(t){this._worker?.port&&delete this._worker._pendingDestroy;throw t}this._transport=null;if(this._worker){this._worker.destroy();this._worker=null}}}exports.PDFDocumentLoadingTask=PDFDocumentLoadingTask;class PDFDataRangeTransport{constructor(t,e,i=!1,s=null){this.length=t;this.initialData=e;this.progressiveDone=i;this.contentDispositionFilename=s;this._rangeListeners=[];this._progressListeners=[];this._progressiveReadListeners=[];this._progressiveDoneListeners=[];this._readyCapability=new _util.PromiseCapability}addRangeListener(t){this._rangeListeners.push(t)}addProgressListener(t){this._progressListeners.push(t)}addProgressiveReadListener(t){this._progressiveReadListeners.push(t)}addProgressiveDoneListener(t){this._progressiveDoneListeners.push(t)}onDataRange(t,e){for(const i of this._rangeListeners)i(t,e)}onDataProgress(t,e){this._readyCapability.promise.then((()=>{for(const i of this._progressListeners)i(t,e)}))}onDataProgressiveRead(t){this._readyCapability.promise.then((()=>{for(const e of this._progressiveReadListeners)e(t)}))}onDataProgressiveDone(){this._readyCapability.promise.then((()=>{for(const t of this._progressiveDoneListeners)t()}))}transportReady(){this._readyCapability.resolve()}requestDataRange(t,e){(0,_util.unreachable)("Abstract method PDFDataRangeTransport.requestDataRange")}abort(){}}exports.PDFDataRangeTransport=PDFDataRangeTransport;class PDFDocumentProxy{constructor(t,e){this._pdfInfo=t;this._transport=e;Object.defineProperty(this,"getJavaScript",{value:()=>{(0,_display_utils.deprecated)("`PDFDocumentProxy.getJavaScript`, please use `PDFDocumentProxy.getJSActions` instead.");return this.getJSActions().then((t=>{if(!t)return t;const e=[];for(const i in t)e.push(...t[i]);return e}))}})}get annotationStorage(){return this._transport.annotationStorage}get filterFactory(){return this._transport.filterFactory}get numPages(){return this._pdfInfo.numPages}get fingerprints(){return this._pdfInfo.fingerprints}get isPureXfa(){return(0,_util.shadow)(this,"isPureXfa",!!this._transport._htmlForXfa)}get allXfaHtml(){return this._transport._htmlForXfa}getPage(t){return this._transport.getPage(t)}getPageIndex(t){return this._transport.getPageIndex(t)}getDestinations(){return this._transport.getDestinations()}getDestination(t){return this._transport.getDestination(t)}getPageLabels(){return this._transport.getPageLabels()}getPageLayout(){return this._transport.getPageLayout()}getPageMode(){return this._transport.getPageMode()}getViewerPreferences(){return this._transport.getViewerPreferences()}getOpenAction(){return this._transport.getOpenAction()}getAttachments(){return this._transport.getAttachments()}getJSActions(){return this._transport.getDocJSActions()}getOutline(){return this._transport.getOutline()}getOptionalContentConfig(){return this._transport.getOptionalContentConfig()}getPermissions(){return this._transport.getPermissions()}getMetadata(){return this._transport.getMetadata()}getMarkInfo(){return this._transport.getMarkInfo()}getData(){return this._transport.getData()}saveDocument(){return this._transport.saveDocument()}getDownloadInfo(){return this._transport.downloadInfoCapability.promise}cleanup(t=!1){return this._transport.startCleanup(t||this.isPureXfa)}destroy(){return this.loadingTask.destroy()}get loadingParams(){return this._transport.loadingParams}get loadingTask(){return this._transport.loadingTask}getFieldObjects(){return this._transport.getFieldObjects()}hasJSActions(){return this._transport.hasJSActions()}getCalculationOrderIds(){return this._transport.getCalculationOrderIds()}}exports.PDFDocumentProxy=PDFDocumentProxy;class PDFPageProxy{#i=null;#s=!1;constructor(t,e,i,s=!1){this._pageIndex=t;this._pageInfo=e;this._transport=i;this._stats=s?new _display_utils.StatTimer:null;this._pdfBug=s;this.commonObjs=i.commonObjs;this.objs=new PDFObjects;this._maybeCleanupAfterRender=!1;this._intentStates=new Map;this.destroyed=!1}get pageNumber(){return this._pageIndex+1}get rotate(){return this._pageInfo.rotate}get ref(){return this._pageInfo.ref}get userUnit(){return this._pageInfo.userUnit}get view(){return this._pageInfo.view}getViewport({scale:t,rotation:e=this.rotate,offsetX:i=0,offsetY:s=0,dontFlip:n=!1}={}){return new _display_utils.PageViewport({viewBox:this.view,scale:t,rotation:e,offsetX:i,offsetY:s,dontFlip:n})}getAnnotations({intent:t="display"}={}){const e=this._transport.getRenderingIntent(t);return this._transport.getAnnotations(this._pageIndex,e.renderingIntent)}getJSActions(){return this._transport.getPageJSActions(this._pageIndex)}get filterFactory(){return this._transport.filterFactory}get isPureXfa(){return(0,_util.shadow)(this,"isPureXfa",!!this._transport._htmlForXfa)}async getXfa(){return this._transport._htmlForXfa?.children[this._pageIndex]||null}render({canvasContext:t,viewport:e,intent:i="display",annotationMode:s=_util.AnnotationMode.ENABLE,transform:n=null,background:a=null,optionalContentConfigPromise:r=null,annotationCanvasMap:o=null,pageColors:l=null,printAnnotationStorage:h=null}){this._stats?.time("Overall");const c=this._transport.getRenderingIntent(i,s,h);this.#s=!1;this.#n();r||(r=this._transport.getOptionalContentConfig());let d=this._intentStates.get(c.cacheKey);if(!d){d=Object.create(null);this._intentStates.set(c.cacheKey,d)}if(d.streamReaderCancelTimeout){clearTimeout(d.streamReaderCancelTimeout);d.streamReaderCancelTimeout=null}const u=!!(c.renderingIntent&_util.RenderingIntentFlag.PRINT);if(!d.displayReadyCapability){d.displayReadyCapability=new _util.PromiseCapability;d.operatorList={fnArray:[],argsArray:[],lastChunk:!1,separateAnnots:null};this._stats?.time("Page Request");this._pumpOperatorList(c)}const complete=t=>{d.renderTasks.delete(p);(this._maybeCleanupAfterRender||u)&&(this.#s=!0);this.#a(!u);if(t){p.capability.reject(t);this._abortOperatorList({intentState:d,reason:t instanceof Error?t:new Error(t)})}else p.capability.resolve();this._stats?.timeEnd("Rendering");this._stats?.timeEnd("Overall")},p=new InternalRenderTask({callback:complete,params:{canvasContext:t,viewport:e,transform:n,background:a},objs:this.objs,commonObjs:this.commonObjs,annotationCanvasMap:o,operatorList:d.operatorList,pageIndex:this._pageIndex,canvasFactory:this._transport.canvasFactory,filterFactory:this._transport.filterFactory,useRequestAnimationFrame:!u,pdfBug:this._pdfBug,pageColors:l});(d.renderTasks||=new Set).add(p);const g=p.task;Promise.all([d.displayReadyCapability.promise,r]).then((([t,e])=>{if(this.destroyed)complete();else{this._stats?.time("Rendering");p.initializeGraphics({transparency:t,optionalContentConfig:e});p.operatorListChanged()}})).catch(complete);return g}getOperatorList({intent:t="display",annotationMode:e=_util.AnnotationMode.ENABLE,printAnnotationStorage:i=null}={}){const s=this._transport.getRenderingIntent(t,e,i,!0);let n,a=this._intentStates.get(s.cacheKey);if(!a){a=Object.create(null);this._intentStates.set(s.cacheKey,a)}if(!a.opListReadCapability){n=Object.create(null);n.operatorListChanged=function operatorListChanged(){if(a.operatorList.lastChunk){a.opListReadCapability.resolve(a.operatorList);a.renderTasks.delete(n)}};a.opListReadCapability=new _util.PromiseCapability;(a.renderTasks||=new Set).add(n);a.operatorList={fnArray:[],argsArray:[],lastChunk:!1,separateAnnots:null};this._stats?.time("Page Request");this._pumpOperatorList(s)}return a.opListReadCapability.promise}streamTextContent({includeMarkedContent:t=!1,disableNormalization:e=!1}={}){return this._transport.messageHandler.sendWithStream("GetTextContent",{pageIndex:this._pageIndex,includeMarkedContent:!0===t,disableNormalization:!0===e},{highWaterMark:100,size:t=>t.items.length})}getTextContent(t={}){if(this._transport._htmlForXfa)return this.getXfa().then((t=>_xfa_text.XfaText.textContent(t)));const e=this.streamTextContent(t);return new Promise((function(t,i){const s=e.getReader(),n={items:[],styles:Object.create(null)};!function pump(){s.read().then((function({value:e,done:i}){if(i)t(n);else{Object.assign(n.styles,e.styles);n.items.push(...e.items);pump()}}),i)}()}))}getStructTree(){return this._transport.getStructTree(this._pageIndex)}_destroy(){this.destroyed=!0;const t=[];for(const e of this._intentStates.values()){this._abortOperatorList({intentState:e,reason:new Error("Page was destroyed."),force:!0});if(!e.opListReadCapability)for(const i of e.renderTasks){t.push(i.completed);i.cancel()}}this.objs.clear();this.#s=!1;this.#n();return Promise.all(t)}cleanup(t=!1){this.#s=!0;const e=this.#a(!1);t&&e&&(this._stats&&=new _display_utils.StatTimer);return e}#a(t=!1){this.#n();if(!this.#s||this.destroyed)return!1;if(t){this.#i=setTimeout((()=>{this.#i=null;this.#a(!1)}),DELAYED_CLEANUP_TIMEOUT);return!1}for(const{renderTasks:t,operatorList:e}of this._intentStates.values())if(t.size>0||!e.lastChunk)return!1;this._intentStates.clear();this.objs.clear();this.#s=!1;return!0}#n(){if(this.#i){clearTimeout(this.#i);this.#i=null}}_startRenderPage(t,e){const i=this._intentStates.get(e);if(i){this._stats?.timeEnd("Page Request");i.displayReadyCapability?.resolve(t)}}_renderPageChunk(t,e){for(let i=0,s=t.length;i{a.read().then((({value:t,done:e})=>{if(e)r.streamReader=null;else if(!this._transport.destroyed){this._renderPageChunk(t,r);pump()}}),(t=>{r.streamReader=null;if(!this._transport.destroyed){if(r.operatorList){r.operatorList.lastChunk=!0;for(const t of r.renderTasks)t.operatorListChanged();this.#a(!0)}if(r.displayReadyCapability)r.displayReadyCapability.reject(t);else{if(!r.opListReadCapability)throw t;r.opListReadCapability.reject(t)}}}))};pump()}_abortOperatorList({intentState:t,reason:e,force:i=!1}){if(t.streamReader){if(t.streamReaderCancelTimeout){clearTimeout(t.streamReaderCancelTimeout);t.streamReaderCancelTimeout=null}if(!i){if(t.renderTasks.size>0)return;if(e instanceof _display_utils.RenderingCancelledException){let i=RENDERING_CANCELLED_TIMEOUT;e.extraDelay>0&&e.extraDelay<1e3&&(i+=e.extraDelay);t.streamReaderCancelTimeout=setTimeout((()=>{t.streamReaderCancelTimeout=null;this._abortOperatorList({intentState:t,reason:e,force:!0})}),i);return}}t.streamReader.cancel(new _util.AbortException(e.message)).catch((()=>{}));t.streamReader=null;if(!this._transport.destroyed){for(const[e,i]of this._intentStates)if(i===t){this._intentStates.delete(e);break}this.cleanup()}}}get stats(){return this._stats}}exports.PDFPageProxy=PDFPageProxy;class LoopbackPort{#r=new Set;#o=Promise.resolve();postMessage(t,e){const i={data:structuredClone(t,e?{transfer:e}:null)};this.#o.then((()=>{for(const t of this.#r)t.call(this,i)}))}addEventListener(t,e){this.#r.add(e)}removeEventListener(t,e){this.#r.delete(e)}terminate(){this.#r.clear()}}exports.LoopbackPort=LoopbackPort;const PDFWorkerUtil={isWorkerDisabled:!1,fallbackWorkerSrc:null,fakeWorkerId:0};exports.PDFWorkerUtil=PDFWorkerUtil;if(_util.isNodeJS&&"function"==typeof require){PDFWorkerUtil.isWorkerDisabled=!0;PDFWorkerUtil.fallbackWorkerSrc="./pdf.worker.js"}else if("object"==typeof document){const t=document?.currentScript?.src;t&&(PDFWorkerUtil.fallbackWorkerSrc=t.replace(/(\.(?:min\.)?js)(\?.*)?$/i,".worker$1$2"))}PDFWorkerUtil.isSameOrigin=function(t,e){let i;try{i=new URL(t);if(!i.origin||"null"===i.origin)return!1}catch{return!1}const s=new URL(e,i);return i.origin===s.origin};PDFWorkerUtil.createCDNWrapper=function(t){const e=`importScripts("${t}");`;return URL.createObjectURL(new Blob([e]))};class PDFWorker{static#l;constructor({name:t=null,port:e=null,verbosity:i=(0,_util.getVerbosityLevel)()}={}){this.name=t;this.destroyed=!1;this.verbosity=i;this._readyCapability=new _util.PromiseCapability;this._port=null;this._webWorker=null;this._messageHandler=null;if(e){if(PDFWorker.#l?.has(e))throw new Error("Cannot use more than one PDFWorker per port.");(PDFWorker.#l||=new WeakMap).set(e,this);this._initializeFromPort(e)}else this._initialize()}get promise(){return this._readyCapability.promise}get port(){return this._port}get messageHandler(){return this._messageHandler}_initializeFromPort(t){this._port=t;this._messageHandler=new _message_handler.MessageHandler("main","worker",t);this._messageHandler.on("ready",(function(){}));this._readyCapability.resolve();this._messageHandler.send("configure",{verbosity:this.verbosity})}_initialize(){if(!PDFWorkerUtil.isWorkerDisabled&&!PDFWorker._mainThreadWorkerMessageHandler){let{workerSrc:t}=PDFWorker;try{PDFWorkerUtil.isSameOrigin(window.location.href,t)||(t=PDFWorkerUtil.createCDNWrapper(new URL(t,window.location).href));const e=new Worker(t),i=new _message_handler.MessageHandler("main","worker",e),terminateEarly=()=>{e.removeEventListener("error",onWorkerError);i.destroy();e.terminate();this.destroyed?this._readyCapability.reject(new Error("Worker was destroyed")):this._setupFakeWorker()},onWorkerError=()=>{this._webWorker||terminateEarly()};e.addEventListener("error",onWorkerError);i.on("test",(t=>{e.removeEventListener("error",onWorkerError);if(this.destroyed)terminateEarly();else if(t){this._messageHandler=i;this._port=e;this._webWorker=e;this._readyCapability.resolve();i.send("configure",{verbosity:this.verbosity})}else{this._setupFakeWorker();i.destroy();e.terminate()}}));i.on("ready",(t=>{e.removeEventListener("error",onWorkerError);if(this.destroyed)terminateEarly();else try{sendTest()}catch{this._setupFakeWorker()}}));const sendTest=()=>{const t=new Uint8Array;i.send("test",t,[t.buffer])};sendTest();return}catch{(0,_util.info)("The worker has been disabled.")}}this._setupFakeWorker()}_setupFakeWorker(){if(!PDFWorkerUtil.isWorkerDisabled){(0,_util.warn)("Setting up fake worker.");PDFWorkerUtil.isWorkerDisabled=!0}PDFWorker._setupFakeWorkerGlobal.then((t=>{if(this.destroyed){this._readyCapability.reject(new Error("Worker was destroyed"));return}const e=new LoopbackPort;this._port=e;const i="fake"+PDFWorkerUtil.fakeWorkerId++,s=new _message_handler.MessageHandler(i+"_worker",i,e);t.setup(s,e);const n=new _message_handler.MessageHandler(i,i+"_worker",e);this._messageHandler=n;this._readyCapability.resolve();n.send("configure",{verbosity:this.verbosity})})).catch((t=>{this._readyCapability.reject(new Error(`Setting up fake worker failed: "${t.message}".`))}))}destroy(){this.destroyed=!0;if(this._webWorker){this._webWorker.terminate();this._webWorker=null}PDFWorker.#l?.delete(this._port);this._port=null;if(this._messageHandler){this._messageHandler.destroy();this._messageHandler=null}}static fromPort(t){if(!t?.port)throw new Error("PDFWorker.fromPort - invalid method signature.");const e=this.#l?.get(t.port);if(e){if(e._pendingDestroy)throw new Error("PDFWorker.fromPort - the worker is being destroyed.\nPlease remember to await `PDFDocumentLoadingTask.destroy()`-calls.");return e}return new PDFWorker(t)}static get workerSrc(){if(_worker_options.GlobalWorkerOptions.workerSrc)return _worker_options.GlobalWorkerOptions.workerSrc;if(null!==PDFWorkerUtil.fallbackWorkerSrc){_util.isNodeJS||(0,_display_utils.deprecated)('No "GlobalWorkerOptions.workerSrc" specified.');return PDFWorkerUtil.fallbackWorkerSrc}throw new Error('No "GlobalWorkerOptions.workerSrc" specified.')}static get _mainThreadWorkerMessageHandler(){try{return globalThis.pdfjsWorker?.WorkerMessageHandler||null}catch{return null}}static get _setupFakeWorkerGlobal(){const loader=async()=>{const mainWorkerMessageHandler=this._mainThreadWorkerMessageHandler;if(mainWorkerMessageHandler)return mainWorkerMessageHandler;if(_util.isNodeJS&&"function"==typeof require){const worker=eval("require")(this.workerSrc);return worker.WorkerMessageHandler}await(0,_display_utils.loadScript)(this.workerSrc);return window.pdfjsWorker.WorkerMessageHandler};return(0,_util.shadow)(this,"_setupFakeWorkerGlobal",loader())}}exports.PDFWorker=PDFWorker;class WorkerTransport{#h=new Map;#c=new Map;#d=new Map;#u=null;constructor(t,e,i,s,n){this.messageHandler=t;this.loadingTask=e;this.commonObjs=new PDFObjects;this.fontLoader=new _font_loader.FontLoader({ownerDocument:s.ownerDocument,styleElement:s.styleElement});this._params=s;this.canvasFactory=n.canvasFactory;this.filterFactory=n.filterFactory;this.cMapReaderFactory=n.cMapReaderFactory;this.standardFontDataFactory=n.standardFontDataFactory;this.destroyed=!1;this.destroyCapability=null;this._networkStream=i;this._fullReader=null;this._lastProgress=null;this.downloadInfoCapability=new _util.PromiseCapability;this.setupMessageHandler()}#p(t,e=null){const i=this.#h.get(t);if(i)return i;const s=this.messageHandler.sendWithPromise(t,e);this.#h.set(t,s);return s}get annotationStorage(){return(0,_util.shadow)(this,"annotationStorage",new _annotation_storage.AnnotationStorage)}getRenderingIntent(t,e=_util.AnnotationMode.ENABLE,i=null,s=!1){let n=_util.RenderingIntentFlag.DISPLAY,a=_annotation_storage.SerializableEmpty;switch(t){case"any":n=_util.RenderingIntentFlag.ANY;break;case"display":break;case"print":n=_util.RenderingIntentFlag.PRINT;break;default:(0,_util.warn)(`getRenderingIntent - invalid intent: ${t}`)}switch(e){case _util.AnnotationMode.DISABLE:n+=_util.RenderingIntentFlag.ANNOTATIONS_DISABLE;break;case _util.AnnotationMode.ENABLE:break;case _util.AnnotationMode.ENABLE_FORMS:n+=_util.RenderingIntentFlag.ANNOTATIONS_FORMS;break;case _util.AnnotationMode.ENABLE_STORAGE:n+=_util.RenderingIntentFlag.ANNOTATIONS_STORAGE;a=(n&_util.RenderingIntentFlag.PRINT&&i instanceof _annotation_storage.PrintAnnotationStorage?i:this.annotationStorage).serializable;break;default:(0,_util.warn)(`getRenderingIntent - invalid annotationMode: ${e}`)}s&&(n+=_util.RenderingIntentFlag.OPLIST);return{renderingIntent:n,cacheKey:`${n}_${a.hash}`,annotationStorageSerializable:a}}destroy(){if(this.destroyCapability)return this.destroyCapability.promise;this.destroyed=!0;this.destroyCapability=new _util.PromiseCapability;this.#u?.reject(new Error("Worker was destroyed during onPassword callback"));const t=[];for(const e of this.#c.values())t.push(e._destroy());this.#c.clear();this.#d.clear();this.hasOwnProperty("annotationStorage")&&this.annotationStorage.resetModified();const e=this.messageHandler.sendWithPromise("Terminate",null);t.push(e);Promise.all(t).then((()=>{this.commonObjs.clear();this.fontLoader.clear();this.#h.clear();this.filterFactory.destroy();this._networkStream?.cancelAllRequests(new _util.AbortException("Worker was terminated."));if(this.messageHandler){this.messageHandler.destroy();this.messageHandler=null}this.destroyCapability.resolve()}),this.destroyCapability.reject);return this.destroyCapability.promise}setupMessageHandler(){const{messageHandler:t,loadingTask:e}=this;t.on("GetReader",((t,e)=>{(0,_util.assert)(this._networkStream,"GetReader - no `IPDFStream` instance available.");this._fullReader=this._networkStream.getFullReader();this._fullReader.onProgress=t=>{this._lastProgress={loaded:t.loaded,total:t.total}};e.onPull=()=>{this._fullReader.read().then((function({value:t,done:i}){if(i)e.close();else{(0,_util.assert)(t instanceof ArrayBuffer,"GetReader - expected an ArrayBuffer.");e.enqueue(new Uint8Array(t),1,[t])}})).catch((t=>{e.error(t)}))};e.onCancel=t=>{this._fullReader.cancel(t);e.ready.catch((t=>{if(!this.destroyed)throw t}))}}));t.on("ReaderHeadersReady",(t=>{const i=new _util.PromiseCapability,s=this._fullReader;s.headersReady.then((()=>{if(!s.isStreamingSupported||!s.isRangeSupported){this._lastProgress&&e.onProgress?.(this._lastProgress);s.onProgress=t=>{e.onProgress?.({loaded:t.loaded,total:t.total})}}i.resolve({isStreamingSupported:s.isStreamingSupported,isRangeSupported:s.isRangeSupported,contentLength:s.contentLength})}),i.reject);return i.promise}));t.on("GetRangeReader",((t,e)=>{(0,_util.assert)(this._networkStream,"GetRangeReader - no `IPDFStream` instance available.");const i=this._networkStream.getRangeReader(t.begin,t.end);if(i){e.onPull=()=>{i.read().then((function({value:t,done:i}){if(i)e.close();else{(0,_util.assert)(t instanceof ArrayBuffer,"GetRangeReader - expected an ArrayBuffer.");e.enqueue(new Uint8Array(t),1,[t])}})).catch((t=>{e.error(t)}))};e.onCancel=t=>{i.cancel(t);e.ready.catch((t=>{if(!this.destroyed)throw t}))}}else e.close()}));t.on("GetDoc",(({pdfInfo:t})=>{this._numPages=t.numPages;this._htmlForXfa=t.htmlForXfa;delete t.htmlForXfa;e._capability.resolve(new PDFDocumentProxy(t,this))}));t.on("DocException",(function(t){let i;switch(t.name){case"PasswordException":i=new _util.PasswordException(t.message,t.code);break;case"InvalidPDFException":i=new _util.InvalidPDFException(t.message);break;case"MissingPDFException":i=new _util.MissingPDFException(t.message);break;case"UnexpectedResponseException":i=new _util.UnexpectedResponseException(t.message,t.status);break;case"UnknownErrorException":i=new _util.UnknownErrorException(t.message,t.details);break;default:(0,_util.unreachable)("DocException - expected a valid Error.")}e._capability.reject(i)}));t.on("PasswordRequest",(t=>{this.#u=new _util.PromiseCapability;if(e.onPassword){const updatePassword=t=>{t instanceof Error?this.#u.reject(t):this.#u.resolve({password:t})};try{e.onPassword(updatePassword,t.code)}catch(t){this.#u.reject(t)}}else this.#u.reject(new _util.PasswordException(t.message,t.code));return this.#u.promise}));t.on("DataLoaded",(t=>{e.onProgress?.({loaded:t.length,total:t.length});this.downloadInfoCapability.resolve(t)}));t.on("StartRenderPage",(t=>{if(this.destroyed)return;this.#c.get(t.pageIndex)._startRenderPage(t.transparency,t.cacheKey)}));t.on("commonobj",(([e,i,s])=>{if(!this.destroyed&&!this.commonObjs.has(e))switch(i){case"Font":const n=this._params;if("error"in s){const t=s.error;(0,_util.warn)(`Error during font loading: ${t}`);this.commonObjs.resolve(e,t);break}const a=n.pdfBug&&globalThis.FontInspector?.enabled?(t,e)=>globalThis.FontInspector.fontAdded(t,e):null,r=new _font_loader.FontFaceObject(s,{isEvalSupported:n.isEvalSupported,disableFontFace:n.disableFontFace,ignoreErrors:n.ignoreErrors,inspectFont:a});this.fontLoader.bind(r).catch((i=>t.sendWithPromise("FontFallback",{id:e}))).finally((()=>{!n.fontExtraProperties&&r.data&&(r.data=null);this.commonObjs.resolve(e,r)}));break;case"FontPath":case"Image":case"Pattern":this.commonObjs.resolve(e,s);break;default:throw new Error(`Got unknown common object type ${i}`)}}));t.on("obj",(([t,e,i,s])=>{if(this.destroyed)return;const n=this.#c.get(e);if(!n.objs.has(t))switch(i){case"Image":n.objs.resolve(t,s);if(s){let t;if(s.bitmap){const{width:e,height:i}=s;t=e*i*4}else t=s.data?.length||0;t>_util.MAX_IMAGE_SIZE_TO_CACHE&&(n._maybeCleanupAfterRender=!0)}break;case"Pattern":n.objs.resolve(t,s);break;default:throw new Error(`Got unknown object type ${i}`)}}));t.on("DocProgress",(t=>{this.destroyed||e.onProgress?.({loaded:t.loaded,total:t.total})}));t.on("FetchBuiltInCMap",(t=>this.destroyed?Promise.reject(new Error("Worker was destroyed.")):this.cMapReaderFactory?this.cMapReaderFactory.fetch(t):Promise.reject(new Error("CMapReaderFactory not initialized, see the `useWorkerFetch` parameter."))));t.on("FetchStandardFontData",(t=>this.destroyed?Promise.reject(new Error("Worker was destroyed.")):this.standardFontDataFactory?this.standardFontDataFactory.fetch(t):Promise.reject(new Error("StandardFontDataFactory not initialized, see the `useWorkerFetch` parameter."))))}getData(){return this.messageHandler.sendWithPromise("GetData",null)}saveDocument(){this.annotationStorage.size<=0&&(0,_util.warn)("saveDocument called while `annotationStorage` is empty, please use the getData-method instead.");const{map:t,transfers:e}=this.annotationStorage.serializable;return this.messageHandler.sendWithPromise("SaveDocument",{isPureXfa:!!this._htmlForXfa,numPages:this._numPages,annotationStorage:t,filename:this._fullReader?.filename??null},e).finally((()=>{this.annotationStorage.resetModified()}))}getPage(t){if(!Number.isInteger(t)||t<=0||t>this._numPages)return Promise.reject(new Error("Invalid page request."));const e=t-1,i=this.#d.get(e);if(i)return i;const s=this.messageHandler.sendWithPromise("GetPage",{pageIndex:e}).then((t=>{if(this.destroyed)throw new Error("Transport destroyed");const i=new PDFPageProxy(e,t,this,this._params.pdfBug);this.#c.set(e,i);return i}));this.#d.set(e,s);return s}getPageIndex(t){return"object"!=typeof t||null===t||!Number.isInteger(t.num)||t.num<0||!Number.isInteger(t.gen)||t.gen<0?Promise.reject(new Error("Invalid pageIndex request.")):this.messageHandler.sendWithPromise("GetPageIndex",{num:t.num,gen:t.gen})}getAnnotations(t,e){return this.messageHandler.sendWithPromise("GetAnnotations",{pageIndex:t,intent:e})}getFieldObjects(){return this.#p("GetFieldObjects")}hasJSActions(){return this.#p("HasJSActions")}getCalculationOrderIds(){return this.messageHandler.sendWithPromise("GetCalculationOrderIds",null)}getDestinations(){return this.messageHandler.sendWithPromise("GetDestinations",null)}getDestination(t){return"string"!=typeof t?Promise.reject(new Error("Invalid destination request.")):this.messageHandler.sendWithPromise("GetDestination",{id:t})}getPageLabels(){return this.messageHandler.sendWithPromise("GetPageLabels",null)}getPageLayout(){return this.messageHandler.sendWithPromise("GetPageLayout",null)}getPageMode(){return this.messageHandler.sendWithPromise("GetPageMode",null)}getViewerPreferences(){return this.messageHandler.sendWithPromise("GetViewerPreferences",null)}getOpenAction(){return this.messageHandler.sendWithPromise("GetOpenAction",null)}getAttachments(){return this.messageHandler.sendWithPromise("GetAttachments",null)}getDocJSActions(){return this.#p("GetDocJSActions")}getPageJSActions(t){return this.messageHandler.sendWithPromise("GetPageJSActions",{pageIndex:t})}getStructTree(t){return this.messageHandler.sendWithPromise("GetStructTree",{pageIndex:t})}getOutline(){return this.messageHandler.sendWithPromise("GetOutline",null)}getOptionalContentConfig(){return this.messageHandler.sendWithPromise("GetOptionalContentConfig",null).then((t=>new _optional_content_config.OptionalContentConfig(t)))}getPermissions(){return this.messageHandler.sendWithPromise("GetPermissions",null)}getMetadata(){const t="GetMetadata",e=this.#h.get(t);if(e)return e;const i=this.messageHandler.sendWithPromise(t,null).then((t=>({info:t[0],metadata:t[1]?new _metadata.Metadata(t[1]):null,contentDispositionFilename:this._fullReader?.filename??null,contentLength:this._fullReader?.contentLength??null})));this.#h.set(t,i);return i}getMarkInfo(){return this.messageHandler.sendWithPromise("GetMarkInfo",null)}async startCleanup(t=!1){if(!this.destroyed){await this.messageHandler.sendWithPromise("Cleanup",null);for(const t of this.#c.values()){if(!t.cleanup())throw new Error(`startCleanup: Page ${t.pageNumber} is currently rendering.`)}this.commonObjs.clear();t||this.fontLoader.clear();this.#h.clear();this.filterFactory.destroy(!0)}}get loadingParams(){const{disableAutoFetch:t,enableXfa:e}=this._params;return(0,_util.shadow)(this,"loadingParams",{disableAutoFetch:t,enableXfa:e})}}class PDFObjects{#g=Object.create(null);#m(t){return this.#g[t]||={capability:new _util.PromiseCapability,data:null}}get(t,e=null){if(e){const i=this.#m(t);i.capability.promise.then((()=>e(i.data)));return null}const i=this.#g[t];if(!i?.capability.settled)throw new Error(`Requesting object that isn't resolved yet ${t}.`);return i.data}has(t){const e=this.#g[t];return e?.capability.settled||!1}resolve(t,e=null){const i=this.#m(t);i.data=e;i.capability.resolve()}clear(){for(const t in this.#g){const{data:e}=this.#g[t];e?.bitmap?.close()}this.#g=Object.create(null)}}class RenderTask{#f=null;constructor(t){this.#f=t;this.onContinue=null}get promise(){return this.#f.capability.promise}cancel(t=0){this.#f.cancel(null,t)}get separateAnnots(){const{separateAnnots:t}=this.#f.operatorList;if(!t)return!1;const{annotationCanvasMap:e}=this.#f;return t.form||t.canvas&&e?.size>0}}exports.RenderTask=RenderTask;class InternalRenderTask{static#b=new WeakSet;constructor({callback:t,params:e,objs:i,commonObjs:s,annotationCanvasMap:n,operatorList:a,pageIndex:r,canvasFactory:o,filterFactory:l,useRequestAnimationFrame:h=!1,pdfBug:c=!1,pageColors:d=null}){this.callback=t;this.params=e;this.objs=i;this.commonObjs=s;this.annotationCanvasMap=n;this.operatorListIdx=null;this.operatorList=a;this._pageIndex=r;this.canvasFactory=o;this.filterFactory=l;this._pdfBug=c;this.pageColors=d;this.running=!1;this.graphicsReadyCallback=null;this.graphicsReady=!1;this._useRequestAnimationFrame=!0===h&&"undefined"!=typeof window;this.cancelled=!1;this.capability=new _util.PromiseCapability;this.task=new RenderTask(this);this._cancelBound=this.cancel.bind(this);this._continueBound=this._continue.bind(this);this._scheduleNextBound=this._scheduleNext.bind(this);this._nextBound=this._next.bind(this);this._canvas=e.canvasContext.canvas}get completed(){return this.capability.promise.catch((function(){}))}initializeGraphics({transparency:t=!1,optionalContentConfig:e}){if(this.cancelled)return;if(this._canvas){if(InternalRenderTask.#b.has(this._canvas))throw new Error("Cannot use the same canvas during multiple render() operations. Use different canvas or ensure previous operations were cancelled or completed.");InternalRenderTask.#b.add(this._canvas)}if(this._pdfBug&&globalThis.StepperManager?.enabled){this.stepper=globalThis.StepperManager.create(this._pageIndex);this.stepper.init(this.operatorList);this.stepper.nextBreakPoint=this.stepper.getNextBreakPoint()}const{canvasContext:i,viewport:s,transform:n,background:a}=this.params;this.gfx=new _canvas.CanvasGraphics(i,this.commonObjs,this.objs,this.canvasFactory,this.filterFactory,{optionalContentConfig:e},this.annotationCanvasMap,this.pageColors);this.gfx.beginDrawing({transform:n,viewport:s,transparency:t,background:a});this.operatorListIdx=0;this.graphicsReady=!0;this.graphicsReadyCallback?.()}cancel(t=null,e=0){this.running=!1;this.cancelled=!0;this.gfx?.endDrawing();InternalRenderTask.#b.delete(this._canvas);this.callback(t||new _display_utils.RenderingCancelledException(`Rendering cancelled, page ${this._pageIndex+1}`,e))}operatorListChanged(){if(this.graphicsReady){this.stepper?.updateOperatorList(this.operatorList);this.running||this._continue()}else this.graphicsReadyCallback||=this._continueBound}_continue(){this.running=!0;this.cancelled||(this.task.onContinue?this.task.onContinue(this._scheduleNextBound):this._scheduleNext())}_scheduleNext(){this._useRequestAnimationFrame?window.requestAnimationFrame((()=>{this._nextBound().catch(this._cancelBound)})):Promise.resolve().then(this._nextBound).catch(this._cancelBound)}async _next(){if(!this.cancelled){this.operatorListIdx=this.gfx.executeOperatorList(this.operatorList,this.operatorListIdx,this._continueBound,this.stepper);if(this.operatorListIdx===this.operatorList.argsArray.length){this.running=!1;if(this.operatorList.lastChunk){this.gfx.endDrawing();InternalRenderTask.#b.delete(this._canvas);this.callback()}}}}}const version="3.11.174";exports.version=version;const build="ce8716743";exports.build=build},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.SerializableEmpty=e.PrintAnnotationStorage=e.AnnotationStorage=void 0;var s=i(1),n=i(4),a=i(8);const r=Object.freeze({map:null,hash:"",transfers:void 0});e.SerializableEmpty=r;class AnnotationStorage{#A=!1;#_=new Map;constructor(){this.onSetModified=null;this.onResetModified=null;this.onAnnotationEditor=null}getValue(t,e){const i=this.#_.get(t);return void 0===i?e:Object.assign(e,i)}getRawValue(t){return this.#_.get(t)}remove(t){this.#_.delete(t);0===this.#_.size&&this.resetModified();if("function"==typeof this.onAnnotationEditor){for(const t of this.#_.values())if(t instanceof n.AnnotationEditor)return;this.onAnnotationEditor(null)}}setValue(t,e){const i=this.#_.get(t);let s=!1;if(void 0!==i){for(const[t,n]of Object.entries(e))if(i[t]!==n){s=!0;i[t]=n}}else{s=!0;this.#_.set(t,e)}s&&this.#v();e instanceof n.AnnotationEditor&&"function"==typeof this.onAnnotationEditor&&this.onAnnotationEditor(e.constructor._type)}has(t){return this.#_.has(t)}getAll(){return this.#_.size>0?(0,s.objectFromMap)(this.#_):null}setAll(t){for(const[e,i]of Object.entries(t))this.setValue(e,i)}get size(){return this.#_.size}#v(){if(!this.#A){this.#A=!0;"function"==typeof this.onSetModified&&this.onSetModified()}}resetModified(){if(this.#A){this.#A=!1;"function"==typeof this.onResetModified&&this.onResetModified()}}get print(){return new PrintAnnotationStorage(this)}get serializable(){if(0===this.#_.size)return r;const t=new Map,e=new a.MurmurHash3_64,i=[],s=Object.create(null);let o=!1;for(const[i,a]of this.#_){const r=a instanceof n.AnnotationEditor?a.serialize(!1,s):a;if(r){t.set(i,r);e.update(`${i}:${JSON.stringify(r)}`);o||=!!r.bitmap}}if(o)for(const e of t.values())e.bitmap&&i.push(e.bitmap);return t.size>0?{map:t,hash:e.hexdigest(),transfers:i}:r}}e.AnnotationStorage=AnnotationStorage;class PrintAnnotationStorage extends AnnotationStorage{#y;constructor(t){super();const{map:e,hash:i,transfers:s}=t.serializable,n=structuredClone(e,s?{transfer:s}:null);this.#y={map:n,hash:i,transfers:s}}get print(){(0,s.unreachable)("Should not call PrintAnnotationStorage.print")}get serializable(){return this.#y}}e.PrintAnnotationStorage=PrintAnnotationStorage},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.AnnotationEditor=void 0;var s=i(5),n=i(1),a=i(6);class AnnotationEditor{#S="";#E=!1;#x=null;#w=null;#C=null;#T=!1;#P=null;#M=this.focusin.bind(this);#k=this.focusout.bind(this);#F=!1;#R=!1;#D=!1;_initialOptions=Object.create(null);_uiManager=null;_focusEventsAllowed=!0;_l10nPromise=null;#I=!1;#L=AnnotationEditor._zIndex++;static _borderLineWidth=-1;static _colorManager=new s.ColorManager;static _zIndex=1;static SMALL_EDITOR_SIZE=0;constructor(t){this.constructor===AnnotationEditor&&(0,n.unreachable)("Cannot initialize AnnotationEditor.");this.parent=t.parent;this.id=t.id;this.width=this.height=null;this.pageIndex=t.parent.pageIndex;this.name=t.name;this.div=null;this._uiManager=t.uiManager;this.annotationElementId=null;this._willKeepAspectRatio=!1;this._initialOptions.isCentered=t.isCentered;this._structTreeParentId=null;const{rotation:e,rawDims:{pageWidth:i,pageHeight:s,pageX:a,pageY:r}}=this.parent.viewport;this.rotation=e;this.pageRotation=(360+e-this._uiManager.viewParameters.rotation)%360;this.pageDimensions=[i,s];this.pageTranslation=[a,r];const[o,l]=this.parentDimensions;this.x=t.x/o;this.y=t.y/l;this.isAttachedToDOM=!1;this.deleted=!1}get editorType(){return Object.getPrototypeOf(this).constructor._type}static get _defaultLineColor(){return(0,n.shadow)(this,"_defaultLineColor",this._colorManager.getHexCode("CanvasText"))}static deleteAnnotationElement(t){const e=new FakeEditor({id:t.parent.getNextId(),parent:t.parent,uiManager:t._uiManager});e.annotationElementId=t.annotationElementId;e.deleted=!0;e._uiManager.addToAnnotationStorage(e)}static initialize(t,e=null){AnnotationEditor._l10nPromise||=new Map(["editor_alt_text_button_label","editor_alt_text_edit_button_label","editor_alt_text_decorative_tooltip"].map((e=>[e,t.get(e)])));if(e?.strings)for(const i of e.strings)AnnotationEditor._l10nPromise.set(i,t.get(i));if(-1!==AnnotationEditor._borderLineWidth)return;const i=getComputedStyle(document.documentElement);AnnotationEditor._borderLineWidth=parseFloat(i.getPropertyValue("--outline-width"))||0}static updateDefaultParams(t,e){}static get defaultPropertiesToUpdate(){return[]}static isHandlingMimeForPasting(t){return!1}static paste(t,e){(0,n.unreachable)("Not implemented")}get propertiesToUpdate(){return[]}get _isDraggable(){return this.#I}set _isDraggable(t){this.#I=t;this.div?.classList.toggle("draggable",t)}center(){const[t,e]=this.pageDimensions;switch(this.parentRotation){case 90:this.x-=this.height*e/(2*t);this.y+=this.width*t/(2*e);break;case 180:this.x+=this.width/2;this.y+=this.height/2;break;case 270:this.x+=this.height*e/(2*t);this.y-=this.width*t/(2*e);break;default:this.x-=this.width/2;this.y-=this.height/2}this.fixAndSetPosition()}addCommands(t){this._uiManager.addCommands(t)}get currentLayer(){return this._uiManager.currentLayer}setInBackground(){this.div.style.zIndex=0}setInForeground(){this.div.style.zIndex=this.#L}setParent(t){if(null!==t){this.pageIndex=t.pageIndex;this.pageDimensions=t.pageDimensions}this.parent=t}focusin(t){this._focusEventsAllowed&&(this.#F?this.#F=!1:this.parent.setSelected(this))}focusout(t){if(!this._focusEventsAllowed)return;if(!this.isAttachedToDOM)return;const e=t.relatedTarget;if(!e?.closest(`#${this.id}`)){t.preventDefault();this.parent?.isMultipleSelection||this.commitOrRemove()}}commitOrRemove(){this.isEmpty()?this.remove():this.commit()}commit(){this.addToAnnotationStorage()}addToAnnotationStorage(){this._uiManager.addToAnnotationStorage(this)}setAt(t,e,i,s){const[n,a]=this.parentDimensions;[i,s]=this.screenToPageTranslation(i,s);this.x=(t+i)/n;this.y=(e+s)/a;this.fixAndSetPosition()}#O([t,e],i,s){[i,s]=this.screenToPageTranslation(i,s);this.x+=i/t;this.y+=s/e;this.fixAndSetPosition()}translate(t,e){this.#O(this.parentDimensions,t,e)}translateInPage(t,e){this.#O(this.pageDimensions,t,e);this.div.scrollIntoView({block:"nearest"})}drag(t,e){const[i,s]=this.parentDimensions;this.x+=t/i;this.y+=e/s;if(this.parent&&(this.x<0||this.x>1||this.y<0||this.y>1)){const{x:t,y:e}=this.div.getBoundingClientRect();if(this.parent.findNewParent(this,t,e)){this.x-=Math.floor(this.x);this.y-=Math.floor(this.y)}}let{x:n,y:a}=this;const[r,o]=this.#N();n+=r;a+=o;this.div.style.left=`${(100*n).toFixed(2)}%`;this.div.style.top=`${(100*a).toFixed(2)}%`;this.div.scrollIntoView({block:"nearest"})}#N(){const[t,e]=this.parentDimensions,{_borderLineWidth:i}=AnnotationEditor,s=i/t,n=i/e;switch(this.rotation){case 90:return[-s,n];case 180:return[s,n];case 270:return[s,-n];default:return[-s,-n]}}fixAndSetPosition(){const[t,e]=this.pageDimensions;let{x:i,y:s,width:n,height:a}=this;n*=t;a*=e;i*=t;s*=e;switch(this.rotation){case 0:i=Math.max(0,Math.min(t-n,i));s=Math.max(0,Math.min(e-a,s));break;case 90:i=Math.max(0,Math.min(t-a,i));s=Math.min(e,Math.max(n,s));break;case 180:i=Math.min(t,Math.max(n,i));s=Math.min(e,Math.max(a,s));break;case 270:i=Math.min(t,Math.max(a,i));s=Math.max(0,Math.min(e-n,s))}this.x=i/=t;this.y=s/=e;const[r,o]=this.#N();i+=r;s+=o;const{style:l}=this.div;l.left=`${(100*i).toFixed(2)}%`;l.top=`${(100*s).toFixed(2)}%`;this.moveInDOM()}static#B(t,e,i){switch(i){case 90:return[e,-t];case 180:return[-t,-e];case 270:return[-e,t];default:return[t,e]}}screenToPageTranslation(t,e){return AnnotationEditor.#B(t,e,this.parentRotation)}pageTranslationToScreen(t,e){return AnnotationEditor.#B(t,e,360-this.parentRotation)}#U(t){switch(t){case 90:{const[t,e]=this.pageDimensions;return[0,-t/e,e/t,0]}case 180:return[-1,0,0,-1];case 270:{const[t,e]=this.pageDimensions;return[0,t/e,-e/t,0]}default:return[1,0,0,1]}}get parentScale(){return this._uiManager.viewParameters.realScale}get parentRotation(){return(this._uiManager.viewParameters.rotation+this.pageRotation)%360}get parentDimensions(){const{parentScale:t,pageDimensions:[e,i]}=this,s=e*t,a=i*t;return n.FeatureTest.isCSSRoundSupported?[Math.round(s),Math.round(a)]:[s,a]}setDims(t,e){const[i,s]=this.parentDimensions;this.div.style.width=`${(100*t/i).toFixed(2)}%`;this.#T||(this.div.style.height=`${(100*e/s).toFixed(2)}%`);this.#x?.classList.toggle("small",t{this._isDraggable=a;window.removeEventListener("pointerup",pointerUpCallback);window.removeEventListener("blur",pointerUpCallback);window.removeEventListener("pointermove",s,r);this.parent.div.style.cursor=d;this.div.style.cursor=u;const t=this.x,e=this.y,i=this.width,n=this.height;t===o&&e===l&&i===h&&n===c||this.addCommands({cmd:()=>{this.width=i;this.height=n;this.x=t;this.y=e;const[s,a]=this.parentDimensions;this.setDims(s*i,a*n);this.fixAndSetPosition()},undo:()=>{this.width=h;this.height=c;this.x=o;this.y=l;const[t,e]=this.parentDimensions;this.setDims(t*h,e*c);this.fixAndSetPosition()},mustExec:!0})};window.addEventListener("pointerup",pointerUpCallback);window.addEventListener("blur",pointerUpCallback)}#H(t,e){const[i,s]=this.parentDimensions,n=this.x,a=this.y,r=this.width,o=this.height,l=AnnotationEditor.MIN_SIZE/i,h=AnnotationEditor.MIN_SIZE/s,round=t=>Math.round(1e4*t)/1e4,c=this.#U(this.rotation),transf=(t,e)=>[c[0]*t+c[2]*e,c[1]*t+c[3]*e],d=this.#U(360-this.rotation);let u,p,g=!1,m=!1;switch(t){case"topLeft":g=!0;u=(t,e)=>[0,0];p=(t,e)=>[t,e];break;case"topMiddle":u=(t,e)=>[t/2,0];p=(t,e)=>[t/2,e];break;case"topRight":g=!0;u=(t,e)=>[t,0];p=(t,e)=>[0,e];break;case"middleRight":m=!0;u=(t,e)=>[t,e/2];p=(t,e)=>[0,e/2];break;case"bottomRight":g=!0;u=(t,e)=>[t,e];p=(t,e)=>[0,0];break;case"bottomMiddle":u=(t,e)=>[t/2,e];p=(t,e)=>[t/2,0];break;case"bottomLeft":g=!0;u=(t,e)=>[0,e];p=(t,e)=>[t,0];break;case"middleLeft":m=!0;u=(t,e)=>[0,e/2];p=(t,e)=>[t,e/2]}const f=u(r,o),b=p(r,o);let A=transf(...b);const _=round(n+A[0]),v=round(a+A[1]);let y=1,S=1,[E,x]=this.screenToPageTranslation(e.movementX,e.movementY);[E,x]=(w=E/i,C=x/s,[d[0]*w+d[2]*C,d[1]*w+d[3]*C]);var w,C;if(g){const t=Math.hypot(r,o);y=S=Math.max(Math.min(Math.hypot(b[0]-f[0]-E,b[1]-f[1]-x)/t,1/r,1/o),l/r,h/o)}else m?y=Math.max(l,Math.min(1,Math.abs(b[0]-f[0]-E)))/r:S=Math.max(h,Math.min(1,Math.abs(b[1]-f[1]-x)))/o;const T=round(r*y),P=round(o*S);A=transf(...p(T,P));const M=_-A[0],k=v-A[1];this.width=T;this.height=P;this.x=M;this.y=k;this.setDims(i*T,s*P);this.fixAndSetPosition()}async addAltTextButton(){if(this.#x)return;const t=this.#x=document.createElement("button");t.className="altText";const e=await AnnotationEditor._l10nPromise.get("editor_alt_text_button_label");t.textContent=e;t.setAttribute("aria-label",e);t.tabIndex="0";t.addEventListener("contextmenu",a.noContextMenu);t.addEventListener("pointerdown",(t=>t.stopPropagation()));t.addEventListener("click",(t=>{t.preventDefault();this._uiManager.editAltText(this)}),{capture:!0});t.addEventListener("keydown",(e=>{if(e.target===t&&"Enter"===e.key){e.preventDefault();this._uiManager.editAltText(this)}}));this.#W();this.div.append(t);if(!AnnotationEditor.SMALL_EDITOR_SIZE){const e=40;AnnotationEditor.SMALL_EDITOR_SIZE=Math.min(128,Math.round(t.getBoundingClientRect().width*(1+e/100)))}}async#W(){const t=this.#x;if(!t)return;if(!this.#S&&!this.#E){t.classList.remove("done");this.#w?.remove();return}AnnotationEditor._l10nPromise.get("editor_alt_text_edit_button_label").then((e=>{t.setAttribute("aria-label",e)}));let e=this.#w;if(!e){this.#w=e=document.createElement("span");e.className="tooltip";e.setAttribute("role","tooltip");const i=e.id=`alt-text-tooltip-${this.id}`;t.setAttribute("aria-describedby",i);const s=100;t.addEventListener("mouseenter",(()=>{this.#C=setTimeout((()=>{this.#C=null;this.#w.classList.add("show");this._uiManager._eventBus.dispatch("reporttelemetry",{source:this,details:{type:"editing",subtype:this.editorType,data:{action:"alt_text_tooltip"}}})}),s)}));t.addEventListener("mouseleave",(()=>{clearTimeout(this.#C);this.#C=null;this.#w?.classList.remove("show")}))}t.classList.add("done");e.innerText=this.#E?await AnnotationEditor._l10nPromise.get("editor_alt_text_decorative_tooltip"):this.#S;e.parentNode||t.append(e)}getClientDimensions(){return this.div.getBoundingClientRect()}get altTextData(){return{altText:this.#S,decorative:this.#E}}set altTextData({altText:t,decorative:e}){if(this.#S!==t||this.#E!==e){this.#S=t;this.#E=e;this.#W()}}render(){this.div=document.createElement("div");this.div.setAttribute("data-editor-rotation",(360-this.rotation)%360);this.div.className=this.name;this.div.setAttribute("id",this.id);this.div.setAttribute("tabIndex",0);this.setInForeground();this.div.addEventListener("focusin",this.#M);this.div.addEventListener("focusout",this.#k);const[t,e]=this.parentDimensions;if(this.parentRotation%180!=0){this.div.style.maxWidth=`${(100*e/t).toFixed(2)}%`;this.div.style.maxHeight=`${(100*t/e).toFixed(2)}%`}const[i,n]=this.getInitialTranslation();this.translate(i,n);(0,s.bindEvents)(this,this.div,["pointerdown"]);return this.div}pointerdown(t){const{isMac:e}=n.FeatureTest.platform;if(0!==t.button||t.ctrlKey&&e)t.preventDefault();else{this.#F=!0;this.#G(t)}}#G(t){if(!this._isDraggable)return;const e=this._uiManager.isSelected(this);this._uiManager.setUpDragSession();let i,s;if(e){i={passive:!0,capture:!0};s=t=>{const[e,i]=this.screenToPageTranslation(t.movementX,t.movementY);this._uiManager.dragSelectedEditors(e,i)};window.addEventListener("pointermove",s,i)}const pointerUpCallback=()=>{window.removeEventListener("pointerup",pointerUpCallback);window.removeEventListener("blur",pointerUpCallback);e&&window.removeEventListener("pointermove",s,i);this.#F=!1;if(!this._uiManager.endDragSession()){const{isMac:e}=n.FeatureTest.platform;t.ctrlKey&&!e||t.shiftKey||t.metaKey&&e?this.parent.toggleSelected(this):this.parent.setSelected(this)}};window.addEventListener("pointerup",pointerUpCallback);window.addEventListener("blur",pointerUpCallback)}moveInDOM(){this.parent?.moveEditorInDOM(this)}_setParentAndPosition(t,e,i){t.changeParent(this);this.x=e;this.y=i;this.fixAndSetPosition()}getRect(t,e){const i=this.parentScale,[s,n]=this.pageDimensions,[a,r]=this.pageTranslation,o=t/i,l=e/i,h=this.x*s,c=this.y*n,d=this.width*s,u=this.height*n;switch(this.rotation){case 0:return[h+o+a,n-c-l-u+r,h+o+d+a,n-c-l+r];case 90:return[h+l+a,n-c+o+r,h+l+u+a,n-c+o+d+r];case 180:return[h-o-d+a,n-c+l+r,h-o+a,n-c+l+u+r];case 270:return[h-l-u+a,n-c-o-d+r,h-l+a,n-c-o+r];default:throw new Error("Invalid rotation")}}getRectInCurrentCoords(t,e){const[i,s,n,a]=t,r=n-i,o=a-s;switch(this.rotation){case 0:return[i,e-a,r,o];case 90:return[i,e-s,o,r];case 180:return[n,e-s,r,o];case 270:return[n,e-a,o,r];default:throw new Error("Invalid rotation")}}onceAdded(){}isEmpty(){return!1}enableEditMode(){this.#D=!0}disableEditMode(){this.#D=!1}isInEditMode(){return this.#D}shouldGetKeyboardEvents(){return!1}needsToBeRebuilt(){return this.div&&!this.isAttachedToDOM}rebuild(){this.div?.addEventListener("focusin",this.#M);this.div?.addEventListener("focusout",this.#k)}serialize(t=!1,e=null){(0,n.unreachable)("An editor must be serializable")}static deserialize(t,e,i){const s=new this.prototype.constructor({parent:e,id:e.getNextId(),uiManager:i});s.rotation=t.rotation;const[n,a]=s.pageDimensions,[r,o,l,h]=s.getRectInCurrentCoords(t.rect,a);s.x=r/n;s.y=o/a;s.width=l/n;s.height=h/a;return s}remove(){this.div.removeEventListener("focusin",this.#M);this.div.removeEventListener("focusout",this.#k);this.isEmpty()||this.commit();this.parent?this.parent.remove(this):this._uiManager.removeEditor(this);this.#x?.remove();this.#x=null;this.#w=null}get isResizable(){return!1}makeResizable(){if(this.isResizable){this.#j();this.#P.classList.remove("hidden")}}select(){this.makeResizable();this.div?.classList.add("selectedEditor")}unselect(){this.#P?.classList.add("hidden");this.div?.classList.remove("selectedEditor");this.div?.contains(document.activeElement)&&this._uiManager.currentLayer.div.focus()}updateParams(t,e){}disableEditing(){this.#x&&(this.#x.hidden=!0)}enableEditing(){this.#x&&(this.#x.hidden=!1)}enterInEditMode(){}get contentDiv(){return this.div}get isEditing(){return this.#R}set isEditing(t){this.#R=t;if(this.parent)if(t){this.parent.setSelected(this);this.parent.setActiveEditor(this)}else this.parent.setActiveEditor(null)}setAspectRatio(t,e){this.#T=!0;const i=t/e,{style:s}=this.div;s.aspectRatio=i;s.height="auto"}static get MIN_SIZE(){return 16}}e.AnnotationEditor=AnnotationEditor;class FakeEditor extends AnnotationEditor{constructor(t){super(t);this.annotationElementId=t.annotationElementId;this.deleted=!0}serialize(){return{id:this.annotationElementId,deleted:!0,pageIndex:this.pageIndex}}}},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.KeyboardManager=e.CommandManager=e.ColorManager=e.AnnotationEditorUIManager=void 0;e.bindEvents=function bindEvents(t,e,i){for(const s of i)e.addEventListener(s,t[s].bind(t))};e.opacityToHex=function opacityToHex(t){return Math.round(Math.min(255,Math.max(1,255*t))).toString(16).padStart(2,"0")};var s=i(1),n=i(6);class IdManager{#q=0;getId(){return`${s.AnnotationEditorPrefix}${this.#q++}`}}class ImageManager{#V=(0,s.getUuid)();#q=0;#$=null;static get _isSVGFittingCanvas(){const t=new OffscreenCanvas(1,3).getContext("2d"),e=new Image;e.src='data:image/svg+xml;charset=UTF-8,';const i=e.decode().then((()=>{t.drawImage(e,0,0,1,1,0,0,1,3);return 0===new Uint32Array(t.getImageData(0,0,1,1).data.buffer)[0]}));return(0,s.shadow)(this,"_isSVGFittingCanvas",i)}async#X(t,e){this.#$||=new Map;let i=this.#$.get(t);if(null===i)return null;if(i?.bitmap){i.refCounter+=1;return i}try{i||={bitmap:null,id:`image_${this.#V}_${this.#q++}`,refCounter:0,isSvg:!1};let t;if("string"==typeof e){i.url=e;const s=await fetch(e);if(!s.ok)throw new Error(s.statusText);t=await s.blob()}else t=i.file=e;if("image/svg+xml"===t.type){const e=ImageManager._isSVGFittingCanvas,s=new FileReader,n=new Image,a=new Promise(((t,a)=>{n.onload=()=>{i.bitmap=n;i.isSvg=!0;t()};s.onload=async()=>{const t=i.svgUrl=s.result;n.src=await e?`${t}#svgView(preserveAspectRatio(none))`:t};n.onerror=s.onerror=a}));s.readAsDataURL(t);await a}else i.bitmap=await createImageBitmap(t);i.refCounter=1}catch(t){console.error(t);i=null}this.#$.set(t,i);i&&this.#$.set(i.id,i);return i}async getFromFile(t){const{lastModified:e,name:i,size:s,type:n}=t;return this.#X(`${e}_${i}_${s}_${n}`,t)}async getFromUrl(t){return this.#X(t,t)}async getFromId(t){this.#$||=new Map;const e=this.#$.get(t);if(!e)return null;if(e.bitmap){e.refCounter+=1;return e}return e.file?this.getFromFile(e.file):this.getFromUrl(e.url)}getSvgUrl(t){const e=this.#$.get(t);return e?.isSvg?e.svgUrl:null}deleteId(t){this.#$||=new Map;const e=this.#$.get(t);if(e){e.refCounter-=1;0===e.refCounter&&(e.bitmap=null)}}isValidId(t){return t.startsWith(`image_${this.#V}_`)}}class CommandManager{#K=[];#Y=!1;#J;#Q=-1;constructor(t=128){this.#J=t}add({cmd:t,undo:e,mustExec:i,type:s=NaN,overwriteIfSameType:n=!1,keepUndo:a=!1}){i&&t();if(this.#Y)return;const r={cmd:t,undo:e,type:s};if(-1===this.#Q){this.#K.length>0&&(this.#K.length=0);this.#Q=0;this.#K.push(r);return}if(n&&this.#K[this.#Q].type===s){a&&(r.undo=this.#K[this.#Q].undo);this.#K[this.#Q]=r;return}const o=this.#Q+1;if(o===this.#J)this.#K.splice(0,1);else{this.#Q=o;ot===e[i])))return ColorManager._colorsMapping.get(t);return e}getHexCode(t){const e=this._colors.get(t);return e?s.Util.makeHexColor(...e):t}}e.ColorManager=ColorManager;class AnnotationEditorUIManager{#tt=null;#et=new Map;#it=new Map;#st=null;#nt=null;#at=new CommandManager;#rt=0;#ot=new Set;#lt=null;#ht=null;#ct=new Set;#dt=null;#ut=new IdManager;#pt=!1;#gt=!1;#mt=null;#ft=s.AnnotationEditorType.NONE;#bt=new Set;#At=null;#_t=this.blur.bind(this);#vt=this.focus.bind(this);#yt=this.copy.bind(this);#St=this.cut.bind(this);#Et=this.paste.bind(this);#xt=this.keydown.bind(this);#wt=this.onEditingAction.bind(this);#Ct=this.onPageChanging.bind(this);#Tt=this.onScaleChanging.bind(this);#Pt=this.onRotationChanging.bind(this);#Mt={isEditing:!1,isEmpty:!0,hasSomethingToUndo:!1,hasSomethingToRedo:!1,hasSelectedEditor:!1};#kt=[0,0];#Ft=null;#Rt=null;#Dt=null;static TRANSLATE_SMALL=1;static TRANSLATE_BIG=10;static get _keyboardManager(){const t=AnnotationEditorUIManager.prototype,arrowChecker=t=>{const{activeElement:e}=document;return e&&t.#Rt.contains(e)&&t.hasSomethingToControl()},e=this.TRANSLATE_SMALL,i=this.TRANSLATE_BIG;return(0,s.shadow)(this,"_keyboardManager",new KeyboardManager([[["ctrl+a","mac+meta+a"],t.selectAll],[["ctrl+z","mac+meta+z"],t.undo],[["ctrl+y","ctrl+shift+z","mac+meta+shift+z","ctrl+shift+Z","mac+meta+shift+Z"],t.redo],[["Backspace","alt+Backspace","ctrl+Backspace","shift+Backspace","mac+Backspace","mac+alt+Backspace","mac+ctrl+Backspace","Delete","ctrl+Delete","shift+Delete","mac+Delete"],t.delete],[["Escape","mac+Escape"],t.unselectAll],[["ArrowLeft","mac+ArrowLeft"],t.translateSelectedEditors,{args:[-e,0],checker:arrowChecker}],[["ctrl+ArrowLeft","mac+shift+ArrowLeft"],t.translateSelectedEditors,{args:[-i,0],checker:arrowChecker}],[["ArrowRight","mac+ArrowRight"],t.translateSelectedEditors,{args:[e,0],checker:arrowChecker}],[["ctrl+ArrowRight","mac+shift+ArrowRight"],t.translateSelectedEditors,{args:[i,0],checker:arrowChecker}],[["ArrowUp","mac+ArrowUp"],t.translateSelectedEditors,{args:[0,-e],checker:arrowChecker}],[["ctrl+ArrowUp","mac+shift+ArrowUp"],t.translateSelectedEditors,{args:[0,-i],checker:arrowChecker}],[["ArrowDown","mac+ArrowDown"],t.translateSelectedEditors,{args:[0,e],checker:arrowChecker}],[["ctrl+ArrowDown","mac+shift+ArrowDown"],t.translateSelectedEditors,{args:[0,i],checker:arrowChecker}]]))}constructor(t,e,i,s,a,r){this.#Rt=t;this.#Dt=e;this.#st=i;this._eventBus=s;this._eventBus._on("editingaction",this.#wt);this._eventBus._on("pagechanging",this.#Ct);this._eventBus._on("scalechanging",this.#Tt);this._eventBus._on("rotationchanging",this.#Pt);this.#nt=a.annotationStorage;this.#dt=a.filterFactory;this.#At=r;this.viewParameters={realScale:n.PixelsPerInch.PDF_TO_CSS_UNITS,rotation:0}}destroy(){this.#It();this.#Lt();this._eventBus._off("editingaction",this.#wt);this._eventBus._off("pagechanging",this.#Ct);this._eventBus._off("scalechanging",this.#Tt);this._eventBus._off("rotationchanging",this.#Pt);for(const t of this.#it.values())t.destroy();this.#it.clear();this.#et.clear();this.#ct.clear();this.#tt=null;this.#bt.clear();this.#at.destroy();this.#st.destroy()}get hcmFilter(){return(0,s.shadow)(this,"hcmFilter",this.#At?this.#dt.addHCMFilter(this.#At.foreground,this.#At.background):"none")}get direction(){return(0,s.shadow)(this,"direction",getComputedStyle(this.#Rt).direction)}editAltText(t){this.#st?.editAltText(this,t)}onPageChanging({pageNumber:t}){this.#rt=t-1}focusMainContainer(){this.#Rt.focus()}findParent(t,e){for(const i of this.#it.values()){const{x:s,y:n,width:a,height:r}=i.div.getBoundingClientRect();if(t>=s&&t<=s+a&&e>=n&&e<=n+r)return i}return null}disableUserSelect(t=!1){this.#Dt.classList.toggle("noUserSelect",t)}addShouldRescale(t){this.#ct.add(t)}removeShouldRescale(t){this.#ct.delete(t)}onScaleChanging({scale:t}){this.commitOrRemove();this.viewParameters.realScale=t*n.PixelsPerInch.PDF_TO_CSS_UNITS;for(const t of this.#ct)t.onScaleChanging()}onRotationChanging({pagesRotation:t}){this.commitOrRemove();this.viewParameters.rotation=t}addToAnnotationStorage(t){t.isEmpty()||!this.#nt||this.#nt.has(t.id)||this.#nt.setValue(t.id,t)}#Ot(){window.addEventListener("focus",this.#vt);window.addEventListener("blur",this.#_t)}#Lt(){window.removeEventListener("focus",this.#vt);window.removeEventListener("blur",this.#_t)}blur(){if(!this.hasSelection)return;const{activeElement:t}=document;for(const e of this.#bt)if(e.div.contains(t)){this.#mt=[e,t];e._focusEventsAllowed=!1;break}}focus(){if(!this.#mt)return;const[t,e]=this.#mt;this.#mt=null;e.addEventListener("focusin",(()=>{t._focusEventsAllowed=!0}),{once:!0});e.focus()}#Nt(){window.addEventListener("keydown",this.#xt,{capture:!0})}#It(){window.removeEventListener("keydown",this.#xt,{capture:!0})}#Bt(){document.addEventListener("copy",this.#yt);document.addEventListener("cut",this.#St);document.addEventListener("paste",this.#Et)}#Ut(){document.removeEventListener("copy",this.#yt);document.removeEventListener("cut",this.#St);document.removeEventListener("paste",this.#Et)}addEditListeners(){this.#Nt();this.#Bt()}removeEditListeners(){this.#It();this.#Ut()}copy(t){t.preventDefault();this.#tt?.commitOrRemove();if(!this.hasSelection)return;const e=[];for(const t of this.#bt){const i=t.serialize(!0);i&&e.push(i)}0!==e.length&&t.clipboardData.setData("application/pdfjs",JSON.stringify(e))}cut(t){this.copy(t);this.delete()}paste(t){t.preventDefault();const{clipboardData:e}=t;for(const t of e.items)for(const e of this.#ht)if(e.isHandlingMimeForPasting(t.type)){e.paste(t,this.currentLayer);return}let i=e.getData("application/pdfjs");if(!i)return;try{i=JSON.parse(i)}catch(t){(0,s.warn)(`paste: "${t.message}".`);return}if(!Array.isArray(i))return;this.unselectAll();const n=this.currentLayer;try{const t=[];for(const e of i){const i=n.deserialize(e);if(!i)return;t.push(i)}const cmd=()=>{for(const e of t)this.#jt(e);this.#zt(t)},undo=()=>{for(const e of t)e.remove()};this.addCommands({cmd:cmd,undo:undo,mustExec:!0})}catch(t){(0,s.warn)(`paste: "${t.message}".`)}}keydown(t){this.getActive()?.shouldGetKeyboardEvents()||AnnotationEditorUIManager._keyboardManager.exec(this,t)}onEditingAction(t){["undo","redo","delete","selectAll"].includes(t.name)&&this[t.name]()}#Ht(t){Object.entries(t).some((([t,e])=>this.#Mt[t]!==e))&&this._eventBus.dispatch("annotationeditorstateschanged",{source:this,details:Object.assign(this.#Mt,t)})}#Wt(t){this._eventBus.dispatch("annotationeditorparamschanged",{source:this,details:t})}setEditingState(t){if(t){this.#Ot();this.#Nt();this.#Bt();this.#Ht({isEditing:this.#ft!==s.AnnotationEditorType.NONE,isEmpty:this.#Gt(),hasSomethingToUndo:this.#at.hasSomethingToUndo(),hasSomethingToRedo:this.#at.hasSomethingToRedo(),hasSelectedEditor:!1})}else{this.#Lt();this.#It();this.#Ut();this.#Ht({isEditing:!1});this.disableUserSelect(!1)}}registerEditorTypes(t){if(!this.#ht){this.#ht=t;for(const t of this.#ht)this.#Wt(t.defaultPropertiesToUpdate)}}getId(){return this.#ut.getId()}get currentLayer(){return this.#it.get(this.#rt)}getLayer(t){return this.#it.get(t)}get currentPageIndex(){return this.#rt}addLayer(t){this.#it.set(t.pageIndex,t);this.#pt?t.enable():t.disable()}removeLayer(t){this.#it.delete(t.pageIndex)}updateMode(t,e=null){if(this.#ft!==t){this.#ft=t;if(t!==s.AnnotationEditorType.NONE){this.setEditingState(!0);this.#qt();this.unselectAll();for(const e of this.#it.values())e.updateMode(t);if(e)for(const t of this.#et.values())if(t.annotationElementId===e){this.setSelected(t);t.enterInEditMode();break}}else{this.setEditingState(!1);this.#Vt()}}}updateToolbar(t){t!==this.#ft&&this._eventBus.dispatch("switchannotationeditormode",{source:this,mode:t})}updateParams(t,e){if(this.#ht)if(t!==s.AnnotationEditorParamsType.CREATE){for(const i of this.#bt)i.updateParams(t,e);for(const i of this.#ht)i.updateDefaultParams(t,e)}else this.currentLayer.addNewEditor(t)}enableWaiting(t=!1){if(this.#gt!==t){this.#gt=t;for(const e of this.#it.values()){t?e.disableClick():e.enableClick();e.div.classList.toggle("waiting",t)}}}#qt(){if(!this.#pt){this.#pt=!0;for(const t of this.#it.values())t.enable()}}#Vt(){this.unselectAll();if(this.#pt){this.#pt=!1;for(const t of this.#it.values())t.disable()}}getEditors(t){const e=[];for(const i of this.#et.values())i.pageIndex===t&&e.push(i);return e}getEditor(t){return this.#et.get(t)}addEditor(t){this.#et.set(t.id,t)}removeEditor(t){this.#et.delete(t.id);this.unselect(t);t.annotationElementId&&this.#ot.has(t.annotationElementId)||this.#nt?.remove(t.id)}addDeletedAnnotationElement(t){this.#ot.add(t.annotationElementId);t.deleted=!0}isDeletedAnnotationElement(t){return this.#ot.has(t)}removeDeletedAnnotationElement(t){this.#ot.delete(t.annotationElementId);t.deleted=!1}#jt(t){const e=this.#it.get(t.pageIndex);e?e.addOrRebuild(t):this.addEditor(t)}setActiveEditor(t){if(this.#tt!==t){this.#tt=t;t&&this.#Wt(t.propertiesToUpdate)}}toggleSelected(t){if(this.#bt.has(t)){this.#bt.delete(t);t.unselect();this.#Ht({hasSelectedEditor:this.hasSelection})}else{this.#bt.add(t);t.select();this.#Wt(t.propertiesToUpdate);this.#Ht({hasSelectedEditor:!0})}}setSelected(t){for(const e of this.#bt)e!==t&&e.unselect();this.#bt.clear();this.#bt.add(t);t.select();this.#Wt(t.propertiesToUpdate);this.#Ht({hasSelectedEditor:!0})}isSelected(t){return this.#bt.has(t)}unselect(t){t.unselect();this.#bt.delete(t);this.#Ht({hasSelectedEditor:this.hasSelection})}get hasSelection(){return 0!==this.#bt.size}undo(){this.#at.undo();this.#Ht({hasSomethingToUndo:this.#at.hasSomethingToUndo(),hasSomethingToRedo:!0,isEmpty:this.#Gt()})}redo(){this.#at.redo();this.#Ht({hasSomethingToUndo:!0,hasSomethingToRedo:this.#at.hasSomethingToRedo(),isEmpty:this.#Gt()})}addCommands(t){this.#at.add(t);this.#Ht({hasSomethingToUndo:!0,hasSomethingToRedo:!1,isEmpty:this.#Gt()})}#Gt(){if(0===this.#et.size)return!0;if(1===this.#et.size)for(const t of this.#et.values())return t.isEmpty();return!1}delete(){this.commitOrRemove();if(!this.hasSelection)return;const t=[...this.#bt];this.addCommands({cmd:()=>{for(const e of t)e.remove()},undo:()=>{for(const e of t)this.#jt(e)},mustExec:!0})}commitOrRemove(){this.#tt?.commitOrRemove()}hasSomethingToControl(){return this.#tt||this.hasSelection}#zt(t){this.#bt.clear();for(const e of t)if(!e.isEmpty()){this.#bt.add(e);e.select()}this.#Ht({hasSelectedEditor:!0})}selectAll(){for(const t of this.#bt)t.commit();this.#zt(this.#et.values())}unselectAll(){if(this.#tt)this.#tt.commitOrRemove();else if(this.hasSelection){for(const t of this.#bt)t.unselect();this.#bt.clear();this.#Ht({hasSelectedEditor:!1})}}translateSelectedEditors(t,e,i=!1){i||this.commitOrRemove();if(!this.hasSelection)return;this.#kt[0]+=t;this.#kt[1]+=e;const[s,n]=this.#kt,a=[...this.#bt];this.#Ft&&clearTimeout(this.#Ft);this.#Ft=setTimeout((()=>{this.#Ft=null;this.#kt[0]=this.#kt[1]=0;this.addCommands({cmd:()=>{for(const t of a)this.#et.has(t.id)&&t.translateInPage(s,n)},undo:()=>{for(const t of a)this.#et.has(t.id)&&t.translateInPage(-s,-n)},mustExec:!1})}),1e3);for(const i of a)i.translateInPage(t,e)}setUpDragSession(){if(this.hasSelection){this.disableUserSelect(!0);this.#lt=new Map;for(const t of this.#bt)this.#lt.set(t,{savedX:t.x,savedY:t.y,savedPageIndex:t.pageIndex,newX:0,newY:0,newPageIndex:-1})}}endDragSession(){if(!this.#lt)return!1;this.disableUserSelect(!1);const t=this.#lt;this.#lt=null;let e=!1;for(const[{x:i,y:s,pageIndex:n},a]of t){a.newX=i;a.newY=s;a.newPageIndex=n;e||=i!==a.savedX||s!==a.savedY||n!==a.savedPageIndex}if(!e)return!1;const move=(t,e,i,s)=>{if(this.#et.has(t.id)){const n=this.#it.get(s);if(n)t._setParentAndPosition(n,e,i);else{t.pageIndex=s;t.x=e;t.y=i}}};this.addCommands({cmd:()=>{for(const[e,{newX:i,newY:s,newPageIndex:n}]of t)move(e,i,s,n)},undo:()=>{for(const[e,{savedX:i,savedY:s,savedPageIndex:n}]of t)move(e,i,s,n)},mustExec:!0});return!0}dragSelectedEditors(t,e){if(this.#lt)for(const i of this.#lt.keys())i.drag(t,e)}rebuild(t){if(null===t.parent){const e=this.getLayer(t.pageIndex);if(e){e.changeParent(t);e.addOrRebuild(t)}else{this.addEditor(t);this.addToAnnotationStorage(t);t.rebuild()}}else t.parent.addOrRebuild(t)}isActive(t){return this.#tt===t}getActive(){return this.#tt}getMode(){return this.#ft}get imageManager(){return(0,s.shadow)(this,"imageManager",new ImageManager)}}e.AnnotationEditorUIManager=AnnotationEditorUIManager},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.StatTimer=e.RenderingCancelledException=e.PixelsPerInch=e.PageViewport=e.PDFDateString=e.DOMStandardFontDataFactory=e.DOMSVGFactory=e.DOMFilterFactory=e.DOMCanvasFactory=e.DOMCMapReaderFactory=void 0;e.deprecated=function deprecated(t){console.log("Deprecated API usage: "+t)};e.getColorValues=function getColorValues(t){const e=document.createElement("span");e.style.visibility="hidden";document.body.append(e);for(const i of t.keys()){e.style.color=i;const s=window.getComputedStyle(e).color;t.set(i,getRGB(s))}e.remove()};e.getCurrentTransform=function getCurrentTransform(t){const{a:e,b:i,c:s,d:n,e:a,f:r}=t.getTransform();return[e,i,s,n,a,r]};e.getCurrentTransformInverse=function getCurrentTransformInverse(t){const{a:e,b:i,c:s,d:n,e:a,f:r}=t.getTransform().invertSelf();return[e,i,s,n,a,r]};e.getFilenameFromUrl=function getFilenameFromUrl(t,e=!1){e||([t]=t.split(/[#?]/,1));return t.substring(t.lastIndexOf("/")+1)};e.getPdfFilenameFromUrl=function getPdfFilenameFromUrl(t,e="document.pdf"){if("string"!=typeof t)return e;if(isDataScheme(t)){(0,n.warn)('getPdfFilenameFromUrl: ignore "data:"-URL for performance reasons.');return e}const i=/[^/?#=]+\.pdf\b(?!.*\.pdf\b)/i,s=/^(?:(?:[^:]+:)?\/\/[^/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/.exec(t);let a=i.exec(s[1])||i.exec(s[2])||i.exec(s[3]);if(a){a=a[0];if(a.includes("%"))try{a=i.exec(decodeURIComponent(a))[0]}catch{}}return a||e};e.getRGB=getRGB;e.getXfaPageViewport=function getXfaPageViewport(t,{scale:e=1,rotation:i=0}){const{width:s,height:n}=t.attributes.style,a=[0,0,parseInt(s),parseInt(n)];return new PageViewport({viewBox:a,scale:e,rotation:i})};e.isDataScheme=isDataScheme;e.isPdfFile=function isPdfFile(t){return"string"==typeof t&&/\.pdf$/i.test(t)};e.isValidFetchUrl=isValidFetchUrl;e.loadScript=function loadScript(t,e=!1){return new Promise(((i,s)=>{const n=document.createElement("script");n.src=t;n.onload=function(t){e&&n.remove();i(t)};n.onerror=function(){s(new Error(`Cannot load script at: ${n.src}`))};(document.head||document.documentElement).append(n)}))};e.noContextMenu=function noContextMenu(t){t.preventDefault()};e.setLayerDimensions=function setLayerDimensions(t,e,i=!1,s=!0){if(e instanceof PageViewport){const{pageWidth:s,pageHeight:a}=e.rawDims,{style:r}=t,o=n.FeatureTest.isCSSRoundSupported,l=`var(--scale-factor) * ${s}px`,h=`var(--scale-factor) * ${a}px`,c=o?`round(${l}, 1px)`:`calc(${l})`,d=o?`round(${h}, 1px)`:`calc(${h})`;if(i&&e.rotation%180!=0){r.width=d;r.height=c}else{r.width=c;r.height=d}}s&&t.setAttribute("data-main-rotation",e.rotation)};var s=i(7),n=i(1);const a="http://www.w3.org/2000/svg";class PixelsPerInch{static CSS=96;static PDF=72;static PDF_TO_CSS_UNITS=this.CSS/this.PDF}e.PixelsPerInch=PixelsPerInch;class DOMFilterFactory extends s.BaseFilterFactory{#$t;#Xt;#e;#Kt;#Yt;#Jt;#Qt;#Zt;#te;#ee;#q=0;constructor({docId:t,ownerDocument:e=globalThis.document}={}){super();this.#e=t;this.#Kt=e}get#$(){return this.#$t||=new Map}get#ie(){if(!this.#Xt){const t=this.#Kt.createElement("div"),{style:e}=t;e.visibility="hidden";e.contain="strict";e.width=e.height=0;e.position="absolute";e.top=e.left=0;e.zIndex=-1;const i=this.#Kt.createElementNS(a,"svg");i.setAttribute("width",0);i.setAttribute("height",0);this.#Xt=this.#Kt.createElementNS(a,"defs");t.append(i);i.append(this.#Xt);this.#Kt.body.append(t)}return this.#Xt}addFilter(t){if(!t)return"none";let e,i,s,n,a=this.#$.get(t);if(a)return a;if(1===t.length){const a=t[0],r=new Array(256);for(let t=0;t<256;t++)r[t]=a[t]/255;n=e=i=s=r.join(",")}else{const[a,r,o]=t,l=new Array(256),h=new Array(256),c=new Array(256);for(let t=0;t<256;t++){l[t]=a[t]/255;h[t]=r[t]/255;c[t]=o[t]/255}e=l.join(",");i=h.join(",");s=c.join(",");n=`${e}${i}${s}`}a=this.#$.get(n);if(a){this.#$.set(t,a);return a}const r=`g_${this.#e}_transfer_map_${this.#q++}`,o=`url(#${r})`;this.#$.set(t,o);this.#$.set(n,o);const l=this.#se(r);this.#ne(e,i,s,l);return o}addHCMFilter(t,e){const i=`${t}-${e}`;if(this.#Jt===i)return this.#Qt;this.#Jt=i;this.#Qt="none";this.#Yt?.remove();if(!t||!e)return this.#Qt;const s=this.#ae(t);t=n.Util.makeHexColor(...s);const a=this.#ae(e);e=n.Util.makeHexColor(...a);this.#ie.style.color="";if("#000000"===t&&"#ffffff"===e||t===e)return this.#Qt;const r=new Array(256);for(let t=0;t<=255;t++){const e=t/255;r[t]=e<=.03928?e/12.92:((e+.055)/1.055)**2.4}const o=r.join(","),l=`g_${this.#e}_hcm_filter`,h=this.#Zt=this.#se(l);this.#ne(o,o,o,h);this.#re(h);const getSteps=(t,e)=>{const i=s[t]/255,n=a[t]/255,r=new Array(e+1);for(let t=0;t<=e;t++)r[t]=i+t/e*(n-i);return r.join(",")};this.#ne(getSteps(0,5),getSteps(1,5),getSteps(2,5),h);this.#Qt=`url(#${l})`;return this.#Qt}addHighlightHCMFilter(t,e,i,s){const n=`${t}-${e}-${i}-${s}`;if(this.#te===n)return this.#ee;this.#te=n;this.#ee="none";this.#Zt?.remove();if(!t||!e)return this.#ee;const[a,r]=[t,e].map(this.#ae.bind(this));let o=Math.round(.2126*a[0]+.7152*a[1]+.0722*a[2]),l=Math.round(.2126*r[0]+.7152*r[1]+.0722*r[2]),[h,c]=[i,s].map(this.#ae.bind(this));l{const s=new Array(256),n=(l-o)/i,a=t/255,r=(e-t)/(255*i);let h=0;for(let t=0;t<=i;t++){const e=Math.round(o+t*n),i=a+t*r;for(let t=h;t<=e;t++)s[t]=i;h=e+1}for(let t=h;t<256;t++)s[t]=s[h-1];return s.join(",")},d=`g_${this.#e}_hcm_highlight_filter`,u=this.#Zt=this.#se(d);this.#re(u);this.#ne(getSteps(h[0],c[0],5),getSteps(h[1],c[1],5),getSteps(h[2],c[2],5),u);this.#ee=`url(#${d})`;return this.#ee}destroy(t=!1){if(!t||!this.#Qt&&!this.#ee){if(this.#Xt){this.#Xt.parentNode.parentNode.remove();this.#Xt=null}if(this.#$t){this.#$t.clear();this.#$t=null}this.#q=0}}#re(t){const e=this.#Kt.createElementNS(a,"feColorMatrix");e.setAttribute("type","matrix");e.setAttribute("values","0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0");t.append(e)}#se(t){const e=this.#Kt.createElementNS(a,"filter");e.setAttribute("color-interpolation-filters","sRGB");e.setAttribute("id",t);this.#ie.append(e);return e}#oe(t,e,i){const s=this.#Kt.createElementNS(a,e);s.setAttribute("type","discrete");s.setAttribute("tableValues",i);t.append(s)}#ne(t,e,i,s){const n=this.#Kt.createElementNS(a,"feComponentTransfer");s.append(n);this.#oe(n,"feFuncR",t);this.#oe(n,"feFuncG",e);this.#oe(n,"feFuncB",i)}#ae(t){this.#ie.style.color=t;return getRGB(getComputedStyle(this.#ie).getPropertyValue("color"))}}e.DOMFilterFactory=DOMFilterFactory;class DOMCanvasFactory extends s.BaseCanvasFactory{constructor({ownerDocument:t=globalThis.document}={}){super();this._document=t}_createCanvas(t,e){const i=this._document.createElement("canvas");i.width=t;i.height=e;return i}}e.DOMCanvasFactory=DOMCanvasFactory;async function fetchData(t,e=!1){if(isValidFetchUrl(t,document.baseURI)){const i=await fetch(t);if(!i.ok)throw new Error(i.statusText);return e?new Uint8Array(await i.arrayBuffer()):(0,n.stringToBytes)(await i.text())}return new Promise(((i,s)=>{const a=new XMLHttpRequest;a.open("GET",t,!0);e&&(a.responseType="arraybuffer");a.onreadystatechange=()=>{if(a.readyState===XMLHttpRequest.DONE){if(200===a.status||0===a.status){let t;e&&a.response?t=new Uint8Array(a.response):!e&&a.responseText&&(t=(0,n.stringToBytes)(a.responseText));if(t){i(t);return}}s(new Error(a.statusText))}};a.send(null)}))}class DOMCMapReaderFactory extends s.BaseCMapReaderFactory{_fetchData(t,e){return fetchData(t,this.isCompressed).then((t=>({cMapData:t,compressionType:e})))}}e.DOMCMapReaderFactory=DOMCMapReaderFactory;class DOMStandardFontDataFactory extends s.BaseStandardFontDataFactory{_fetchData(t){return fetchData(t,!0)}}e.DOMStandardFontDataFactory=DOMStandardFontDataFactory;class DOMSVGFactory extends s.BaseSVGFactory{_createSVG(t){return document.createElementNS(a,t)}}e.DOMSVGFactory=DOMSVGFactory;class PageViewport{constructor({viewBox:t,scale:e,rotation:i,offsetX:s=0,offsetY:n=0,dontFlip:a=!1}){this.viewBox=t;this.scale=e;this.rotation=i;this.offsetX=s;this.offsetY=n;const r=(t[2]+t[0])/2,o=(t[3]+t[1])/2;let l,h,c,d,u,p,g,m;(i%=360)<0&&(i+=360);switch(i){case 180:l=-1;h=0;c=0;d=1;break;case 90:l=0;h=1;c=1;d=0;break;case 270:l=0;h=-1;c=-1;d=0;break;case 0:l=1;h=0;c=0;d=-1;break;default:throw new Error("PageViewport: Invalid rotation, must be a multiple of 90 degrees.")}if(a){c=-c;d=-d}if(0===l){u=Math.abs(o-t[1])*e+s;p=Math.abs(r-t[0])*e+n;g=(t[3]-t[1])*e;m=(t[2]-t[0])*e}else{u=Math.abs(r-t[0])*e+s;p=Math.abs(o-t[1])*e+n;g=(t[2]-t[0])*e;m=(t[3]-t[1])*e}this.transform=[l*e,h*e,c*e,d*e,u-l*e*r-c*e*o,p-h*e*r-d*e*o];this.width=g;this.height=m}get rawDims(){const{viewBox:t}=this;return(0,n.shadow)(this,"rawDims",{pageWidth:t[2]-t[0],pageHeight:t[3]-t[1],pageX:t[0],pageY:t[1]})}clone({scale:t=this.scale,rotation:e=this.rotation,offsetX:i=this.offsetX,offsetY:s=this.offsetY,dontFlip:n=!1}={}){return new PageViewport({viewBox:this.viewBox.slice(),scale:t,rotation:e,offsetX:i,offsetY:s,dontFlip:n})}convertToViewportPoint(t,e){return n.Util.applyTransform([t,e],this.transform)}convertToViewportRectangle(t){const e=n.Util.applyTransform([t[0],t[1]],this.transform),i=n.Util.applyTransform([t[2],t[3]],this.transform);return[e[0],e[1],i[0],i[1]]}convertToPdfPoint(t,e){return n.Util.applyInverseTransform([t,e],this.transform)}}e.PageViewport=PageViewport;class RenderingCancelledException extends n.BaseException{constructor(t,e=0){super(t,"RenderingCancelledException");this.extraDelay=e}}e.RenderingCancelledException=RenderingCancelledException;function isDataScheme(t){const e=t.length;let i=0;for(;i=1&&s<=12?s-1:0;let n=parseInt(e[3],10);n=n>=1&&n<=31?n:1;let a=parseInt(e[4],10);a=a>=0&&a<=23?a:0;let o=parseInt(e[5],10);o=o>=0&&o<=59?o:0;let l=parseInt(e[6],10);l=l>=0&&l<=59?l:0;const h=e[7]||"Z";let c=parseInt(e[8],10);c=c>=0&&c<=23?c:0;let d=parseInt(e[9],10)||0;d=d>=0&&d<=59?d:0;if("-"===h){a+=c;o+=d}else if("+"===h){a-=c;o-=d}return new Date(Date.UTC(i,s,n,a,o,l))}};function getRGB(t){if(t.startsWith("#")){const e=parseInt(t.slice(1),16);return[(16711680&e)>>16,(65280&e)>>8,255&e]}if(t.startsWith("rgb("))return t.slice(4,-1).split(",").map((t=>parseInt(t)));if(t.startsWith("rgba("))return t.slice(5,-1).split(",").map((t=>parseInt(t))).slice(0,3);(0,n.warn)(`Not a valid color format: "${t}"`);return[0,0,0]}},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.BaseStandardFontDataFactory=e.BaseSVGFactory=e.BaseFilterFactory=e.BaseCanvasFactory=e.BaseCMapReaderFactory=void 0;var s=i(1);class BaseFilterFactory{constructor(){this.constructor===BaseFilterFactory&&(0,s.unreachable)("Cannot initialize BaseFilterFactory.")}addFilter(t){return"none"}addHCMFilter(t,e){return"none"}addHighlightHCMFilter(t,e,i,s){return"none"}destroy(t=!1){}}e.BaseFilterFactory=BaseFilterFactory;class BaseCanvasFactory{constructor(){this.constructor===BaseCanvasFactory&&(0,s.unreachable)("Cannot initialize BaseCanvasFactory.")}create(t,e){if(t<=0||e<=0)throw new Error("Invalid canvas size");const i=this._createCanvas(t,e);return{canvas:i,context:i.getContext("2d")}}reset(t,e,i){if(!t.canvas)throw new Error("Canvas is not specified");if(e<=0||i<=0)throw new Error("Invalid canvas size");t.canvas.width=e;t.canvas.height=i}destroy(t){if(!t.canvas)throw new Error("Canvas is not specified");t.canvas.width=0;t.canvas.height=0;t.canvas=null;t.context=null}_createCanvas(t,e){(0,s.unreachable)("Abstract method `_createCanvas` called.")}}e.BaseCanvasFactory=BaseCanvasFactory;class BaseCMapReaderFactory{constructor({baseUrl:t=null,isCompressed:e=!0}){this.constructor===BaseCMapReaderFactory&&(0,s.unreachable)("Cannot initialize BaseCMapReaderFactory.");this.baseUrl=t;this.isCompressed=e}async fetch({name:t}){if(!this.baseUrl)throw new Error('The CMap "baseUrl" parameter must be specified, ensure that the "cMapUrl" and "cMapPacked" API parameters are provided.');if(!t)throw new Error("CMap name must be specified.");const e=this.baseUrl+t+(this.isCompressed?".bcmap":""),i=this.isCompressed?s.CMapCompressionType.BINARY:s.CMapCompressionType.NONE;return this._fetchData(e,i).catch((t=>{throw new Error(`Unable to load ${this.isCompressed?"binary ":""}CMap at: ${e}`)}))}_fetchData(t,e){(0,s.unreachable)("Abstract method `_fetchData` called.")}}e.BaseCMapReaderFactory=BaseCMapReaderFactory;class BaseStandardFontDataFactory{constructor({baseUrl:t=null}){this.constructor===BaseStandardFontDataFactory&&(0,s.unreachable)("Cannot initialize BaseStandardFontDataFactory.");this.baseUrl=t}async fetch({filename:t}){if(!this.baseUrl)throw new Error('The standard font "baseUrl" parameter must be specified, ensure that the "standardFontDataUrl" API parameter is provided.');if(!t)throw new Error("Font filename must be specified.");const e=`${this.baseUrl}${t}`;return this._fetchData(e).catch((t=>{throw new Error(`Unable to load font data at: ${e}`)}))}_fetchData(t){(0,s.unreachable)("Abstract method `_fetchData` called.")}}e.BaseStandardFontDataFactory=BaseStandardFontDataFactory;class BaseSVGFactory{constructor(){this.constructor===BaseSVGFactory&&(0,s.unreachable)("Cannot initialize BaseSVGFactory.")}create(t,e,i=!1){if(t<=0||e<=0)throw new Error("Invalid SVG dimensions");const s=this._createSVG("svg:svg");s.setAttribute("version","1.1");if(!i){s.setAttribute("width",`${t}px`);s.setAttribute("height",`${e}px`)}s.setAttribute("preserveAspectRatio","none");s.setAttribute("viewBox",`0 0 ${t} ${e}`);return s}createElement(t){if("string"!=typeof t)throw new Error("Invalid SVG element type");return this._createSVG(t)}_createSVG(t){(0,s.unreachable)("Abstract method `_createSVG` called.")}}e.BaseSVGFactory=BaseSVGFactory},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.MurmurHash3_64=void 0;var s=i(1);const n=3285377520,a=4294901760,r=65535;e.MurmurHash3_64=class MurmurHash3_64{constructor(t){this.h1=t?4294967295&t:n;this.h2=t?4294967295&t:n}update(t){let e,i;if("string"==typeof t){e=new Uint8Array(2*t.length);i=0;for(let s=0,n=t.length;s>>8;e[i++]=255&n}}}else{if(!(0,s.isArrayBuffer)(t))throw new Error("Wrong data format in MurmurHash3_64_update. Input must be a string or array.");e=t.slice();i=e.byteLength}const n=i>>2,o=i-4*n,l=new Uint32Array(e.buffer,0,n);let h=0,c=0,d=this.h1,u=this.h2;const p=3432918353,g=461845907,m=11601,f=13715;for(let t=0;t>>17;h=h*g&a|h*f&r;d^=h;d=d<<13|d>>>19;d=5*d+3864292196}else{c=l[t];c=c*p&a|c*m&r;c=c<<15|c>>>17;c=c*g&a|c*f&r;u^=c;u=u<<13|u>>>19;u=5*u+3864292196}h=0;switch(o){case 3:h^=e[4*n+2]<<16;case 2:h^=e[4*n+1]<<8;case 1:h^=e[4*n];h=h*p&a|h*m&r;h=h<<15|h>>>17;h=h*g&a|h*f&r;1&n?d^=h:u^=h}this.h1=d;this.h2=u}hexdigest(){let t=this.h1,e=this.h2;t^=e>>>1;t=3981806797*t&a|36045*t&r;e=4283543511*e&a|(2950163797*(e<<16|t>>>16)&a)>>>16;t^=e>>>1;t=444984403*t&a|60499*t&r;e=3301882366*e&a|(3120437893*(e<<16|t>>>16)&a)>>>16;t^=e>>>1;return(t>>>0).toString(16).padStart(8,"0")+(e>>>0).toString(16).padStart(8,"0")}}},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.FontLoader=e.FontFaceObject=void 0;var s=i(1);e.FontLoader=class FontLoader{#le=new Set;constructor({ownerDocument:t=globalThis.document,styleElement:e=null}){this._document=t;this.nativeFontFaces=new Set;this.styleElement=null;this.loadingRequests=[];this.loadTestFontId=0}addNativeFontFace(t){this.nativeFontFaces.add(t);this._document.fonts.add(t)}removeNativeFontFace(t){this.nativeFontFaces.delete(t);this._document.fonts.delete(t)}insertRule(t){if(!this.styleElement){this.styleElement=this._document.createElement("style");this._document.documentElement.getElementsByTagName("head")[0].append(this.styleElement)}const e=this.styleElement.sheet;e.insertRule(t,e.cssRules.length)}clear(){for(const t of this.nativeFontFaces)this._document.fonts.delete(t);this.nativeFontFaces.clear();this.#le.clear();if(this.styleElement){this.styleElement.remove();this.styleElement=null}}async loadSystemFont(t){if(t&&!this.#le.has(t.loadedName)){(0,s.assert)(!this.disableFontFace,"loadSystemFont shouldn't be called when `disableFontFace` is set.");if(this.isFontLoadingAPISupported){const{loadedName:e,src:i,style:n}=t,a=new FontFace(e,i,n);this.addNativeFontFace(a);try{await a.load();this.#le.add(e)}catch{(0,s.warn)(`Cannot load system font: ${t.baseFontName}, installing it could help to improve PDF rendering.`);this.removeNativeFontFace(a)}}else(0,s.unreachable)("Not implemented: loadSystemFont without the Font Loading API.")}}async bind(t){if(t.attached||t.missingFile&&!t.systemFontInfo)return;t.attached=!0;if(t.systemFontInfo){await this.loadSystemFont(t.systemFontInfo);return}if(this.isFontLoadingAPISupported){const e=t.createNativeFontFace();if(e){this.addNativeFontFace(e);try{await e.loaded}catch(i){(0,s.warn)(`Failed to load font '${e.family}': '${i}'.`);t.disableFontFace=!0;throw i}}return}const e=t.createFontFaceRule();if(e){this.insertRule(e);if(this.isSyncFontLoadingSupported)return;await new Promise((e=>{const i=this._queueLoadingCallback(e);this._prepareFontLoadEvent(t,i)}))}}get isFontLoadingAPISupported(){const t=!!this._document?.fonts;return(0,s.shadow)(this,"isFontLoadingAPISupported",t)}get isSyncFontLoadingSupported(){let t=!1;(s.isNodeJS||"undefined"!=typeof navigator&&/Mozilla\/5.0.*?rv:\d+.*? Gecko/.test(navigator.userAgent))&&(t=!0);return(0,s.shadow)(this,"isSyncFontLoadingSupported",t)}_queueLoadingCallback(t){const{loadingRequests:e}=this,i={done:!1,complete:function completeRequest(){(0,s.assert)(!i.done,"completeRequest() cannot be called twice.");i.done=!0;for(;e.length>0&&e[0].done;){const t=e.shift();setTimeout(t.callback,0)}},callback:t};e.push(i);return i}get _loadTestFont(){const t=atob("T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQAFQAABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAAALwAAAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgAAAAGbmFtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1AAsD6AAAAADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACMAooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4DIP84AFoDIQAAAAAAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAAAAEAAQAAAAEAAAAAAAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUAAQAAAAEAAAAAAAYAAQAAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgABAAMAAQQJAAMAAgABAAMAAQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABYAAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAAAC7////TAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAAAAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgcA/gXBIwMAYuL+nz5tQXkD5j3CBLnEQACAQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYAAABAQAADwACAQEEE/t3Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQAAAAAAAABAAAAAMmJbzEAAAAAzgTjFQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAgABAAAAAAAAAAAD6AAAAAAAAA==");return(0,s.shadow)(this,"_loadTestFont",t)}_prepareFontLoadEvent(t,e){function int32(t,e){return t.charCodeAt(e)<<24|t.charCodeAt(e+1)<<16|t.charCodeAt(e+2)<<8|255&t.charCodeAt(e+3)}function spliceString(t,e,i,s){return t.substring(0,e)+s+t.substring(e+i)}let i,n;const a=this._document.createElement("canvas");a.width=1;a.height=1;const r=a.getContext("2d");let o=0;const l=`lt${Date.now()}${this.loadTestFontId++}`;let h=this._loadTestFont;h=spliceString(h,976,l.length,l);const c=1482184792;let d=int32(h,16);for(i=0,n=l.length-3;i30){(0,s.warn)("Load test font never loaded.");e();return}r.font="30px "+t;r.fillText(".",0,20);r.getImageData(0,0,1,1).data[3]>0?e():setTimeout(isFontReady.bind(null,t,e))}(l,(()=>{p.remove();e.complete()}))}};e.FontFaceObject=class FontFaceObject{constructor(t,{isEvalSupported:e=!0,disableFontFace:i=!1,ignoreErrors:s=!1,inspectFont:n=null}){this.compiledGlyphs=Object.create(null);for(const e in t)this[e]=t[e];this.isEvalSupported=!1!==e;this.disableFontFace=!0===i;this.ignoreErrors=!0===s;this._inspectFont=n}createNativeFontFace(){if(!this.data||this.disableFontFace)return null;let t;if(this.cssFontInfo){const e={weight:this.cssFontInfo.fontWeight};this.cssFontInfo.italicAngle&&(e.style=`oblique ${this.cssFontInfo.italicAngle}deg`);t=new FontFace(this.cssFontInfo.fontFamily,this.data,e)}else t=new FontFace(this.loadedName,this.data,{});this._inspectFont?.(this);return t}createFontFaceRule(){if(!this.data||this.disableFontFace)return null;const t=(0,s.bytesToString)(this.data),e=`url(data:${this.mimetype};base64,${btoa(t)});`;let i;if(this.cssFontInfo){let t=`font-weight: ${this.cssFontInfo.fontWeight};`;this.cssFontInfo.italicAngle&&(t+=`font-style: oblique ${this.cssFontInfo.italicAngle}deg;`);i=`@font-face {font-family:"${this.cssFontInfo.fontFamily}";${t}src:${e}}`}else i=`@font-face {font-family:"${this.loadedName}";src:${e}}`;this._inspectFont?.(this,e);return i}getPathGenerator(t,e){if(void 0!==this.compiledGlyphs[e])return this.compiledGlyphs[e];let i;try{i=t.get(this.loadedName+"_path_"+e)}catch(t){if(!this.ignoreErrors)throw t;(0,s.warn)(`getPathGenerator - ignoring character: "${t}".`);return this.compiledGlyphs[e]=function(t,e){}}if(this.isEvalSupported&&s.FeatureTest.isEvalSupported){const t=[];for(const e of i){const i=void 0!==e.args?e.args.join(","):"";t.push("c.",e.cmd,"(",i,");\n")}return this.compiledGlyphs[e]=new Function("c","size",t.join(""))}return this.compiledGlyphs[e]=function(t,e){for(const s of i){"scale"===s.cmd&&(s.args=[e,-e]);t[s.cmd].apply(t,s.args)}}}}},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.NodeStandardFontDataFactory=e.NodeFilterFactory=e.NodeCanvasFactory=e.NodeCMapReaderFactory=void 0;var s=i(7);i(1);const fetchData=function(t){return new Promise(((e,i)=>{require("fs").readFile(t,((t,s)=>{!t&&s?e(new Uint8Array(s)):i(new Error(t))}))}))};class NodeFilterFactory extends s.BaseFilterFactory{}e.NodeFilterFactory=NodeFilterFactory;class NodeCanvasFactory extends s.BaseCanvasFactory{_createCanvas(t,e){return require("canvas").createCanvas(t,e)}}e.NodeCanvasFactory=NodeCanvasFactory;class NodeCMapReaderFactory extends s.BaseCMapReaderFactory{_fetchData(t,e){return fetchData(t).then((t=>({cMapData:t,compressionType:e})))}}e.NodeCMapReaderFactory=NodeCMapReaderFactory;class NodeStandardFontDataFactory extends s.BaseStandardFontDataFactory{_fetchData(t){return fetchData(t)}}e.NodeStandardFontDataFactory=NodeStandardFontDataFactory},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.CanvasGraphics=void 0;var s=i(1),n=i(6),a=i(12),r=i(13);const o=4096,l=16;class CachedCanvases{constructor(t){this.canvasFactory=t;this.cache=Object.create(null)}getCanvas(t,e,i){let s;if(void 0!==this.cache[t]){s=this.cache[t];this.canvasFactory.reset(s,e,i)}else{s=this.canvasFactory.create(e,i);this.cache[t]=s}return s}delete(t){delete this.cache[t]}clear(){for(const t in this.cache){const e=this.cache[t];this.canvasFactory.destroy(e);delete this.cache[t]}}}function drawImageAtIntegerCoords(t,e,i,s,a,r,o,l,h,c){const[d,u,p,g,m,f]=(0,n.getCurrentTransform)(t);if(0===u&&0===p){const n=o*d+m,b=Math.round(n),A=l*g+f,_=Math.round(A),v=(o+h)*d+m,y=Math.abs(Math.round(v)-b)||1,S=(l+c)*g+f,E=Math.abs(Math.round(S)-_)||1;t.setTransform(Math.sign(d),0,0,Math.sign(g),b,_);t.drawImage(e,i,s,a,r,0,0,y,E);t.setTransform(d,u,p,g,m,f);return[y,E]}if(0===d&&0===g){const n=l*p+m,b=Math.round(n),A=o*u+f,_=Math.round(A),v=(l+c)*p+m,y=Math.abs(Math.round(v)-b)||1,S=(o+h)*u+f,E=Math.abs(Math.round(S)-_)||1;t.setTransform(0,Math.sign(u),Math.sign(p),0,b,_);t.drawImage(e,i,s,a,r,0,0,E,y);t.setTransform(d,u,p,g,m,f);return[E,y]}t.drawImage(e,i,s,a,r,o,l,h,c);return[Math.hypot(d,u)*h,Math.hypot(p,g)*c]}class CanvasExtraState{constructor(t,e){this.alphaIsShape=!1;this.fontSize=0;this.fontSizeScale=1;this.textMatrix=s.IDENTITY_MATRIX;this.textMatrixScale=1;this.fontMatrix=s.FONT_IDENTITY_MATRIX;this.leading=0;this.x=0;this.y=0;this.lineX=0;this.lineY=0;this.charSpacing=0;this.wordSpacing=0;this.textHScale=1;this.textRenderingMode=s.TextRenderingMode.FILL;this.textRise=0;this.fillColor="#000000";this.strokeColor="#000000";this.patternFill=!1;this.fillAlpha=1;this.strokeAlpha=1;this.lineWidth=1;this.activeSMask=null;this.transferMaps="none";this.startNewPathAndClipBox([0,0,t,e])}clone(){const t=Object.create(this);t.clipBox=this.clipBox.slice();return t}setCurrentPoint(t,e){this.x=t;this.y=e}updatePathMinMax(t,e,i){[e,i]=s.Util.applyTransform([e,i],t);this.minX=Math.min(this.minX,e);this.minY=Math.min(this.minY,i);this.maxX=Math.max(this.maxX,e);this.maxY=Math.max(this.maxY,i)}updateRectMinMax(t,e){const i=s.Util.applyTransform(e,t),n=s.Util.applyTransform(e.slice(2),t);this.minX=Math.min(this.minX,i[0],n[0]);this.minY=Math.min(this.minY,i[1],n[1]);this.maxX=Math.max(this.maxX,i[0],n[0]);this.maxY=Math.max(this.maxY,i[1],n[1])}updateScalingPathMinMax(t,e){s.Util.scaleMinMax(t,e);this.minX=Math.min(this.minX,e[0]);this.maxX=Math.max(this.maxX,e[1]);this.minY=Math.min(this.minY,e[2]);this.maxY=Math.max(this.maxY,e[3])}updateCurvePathMinMax(t,e,i,n,a,r,o,l,h,c){const d=s.Util.bezierBoundingBox(e,i,n,a,r,o,l,h);if(c){c[0]=Math.min(c[0],d[0],d[2]);c[1]=Math.max(c[1],d[0],d[2]);c[2]=Math.min(c[2],d[1],d[3]);c[3]=Math.max(c[3],d[1],d[3])}else this.updateRectMinMax(t,d)}getPathBoundingBox(t=a.PathType.FILL,e=null){const i=[this.minX,this.minY,this.maxX,this.maxY];if(t===a.PathType.STROKE){e||(0,s.unreachable)("Stroke bounding box must include transform.");const t=s.Util.singularValueDecompose2dScale(e),n=t[0]*this.lineWidth/2,a=t[1]*this.lineWidth/2;i[0]-=n;i[1]-=a;i[2]+=n;i[3]+=a}return i}updateClipFromPath(){const t=s.Util.intersect(this.clipBox,this.getPathBoundingBox());this.startNewPathAndClipBox(t||[0,0,0,0])}isEmptyClip(){return this.minX===1/0}startNewPathAndClipBox(t){this.clipBox=t;this.minX=1/0;this.minY=1/0;this.maxX=0;this.maxY=0}getClippedPathBoundingBox(t=a.PathType.FILL,e=null){return s.Util.intersect(this.clipBox,this.getPathBoundingBox(t,e))}}function putBinaryImageData(t,e){if("undefined"!=typeof ImageData&&e instanceof ImageData){t.putImageData(e,0,0);return}const i=e.height,n=e.width,a=i%l,r=(i-a)/l,o=0===a?r:r+1,h=t.createImageData(n,l);let c,d=0;const u=e.data,p=h.data;let g,m,f,b;if(e.kind===s.ImageKind.GRAYSCALE_1BPP){const e=u.byteLength,i=new Uint32Array(p.buffer,0,p.byteLength>>2),b=i.length,A=n+7>>3,_=4294967295,v=s.FeatureTest.isLittleEndian?4278190080:255;for(g=0;gA?n:8*t-7,r=-8&a;let o=0,l=0;for(;s>=1}}for(;c=r){f=a;b=n*f}c=0;for(m=b;m--;){p[c++]=u[d++];p[c++]=u[d++];p[c++]=u[d++];p[c++]=255}t.putImageData(h,0,g*l)}}}function putBinaryImageMask(t,e){if(e.bitmap){t.drawImage(e.bitmap,0,0);return}const i=e.height,s=e.width,n=i%l,a=(i-n)/l,o=0===n?a:a+1,h=t.createImageData(s,l);let c=0;const d=e.data,u=h.data;for(let e=0;e>8;t[a-2]=t[a-2]*n+i*r>>8;t[a-1]=t[a-1]*n+s*r>>8}}}function composeSMaskAlpha(t,e,i){const s=t.length;for(let n=3;n>8]>>8:e[n]*s>>16}}function composeSMask(t,e,i,s){const n=s[0],a=s[1],r=s[2]-n,o=s[3]-a;if(0!==r&&0!==o){!function genericComposeSMask(t,e,i,s,n,a,r,o,l,h,c){const d=!!a,u=d?a[0]:0,p=d?a[1]:0,g=d?a[2]:0,m="Luminosity"===n?composeSMaskLuminosity:composeSMaskAlpha,f=Math.min(s,Math.ceil(1048576/i));for(let n=0;n10&&"function"==typeof i,c=h?Date.now()+15:0;let d=0;const u=this.commonObjs,p=this.objs;let g;for(;;){if(void 0!==n&&o===n.nextBreakPoint){n.breakIt(o,i);return o}g=r[o];if(g!==s.OPS.dependency)this[g].apply(this,a[o]);else for(const t of a[o]){const e=t.startsWith("g_")?u:p;if(!e.has(t)){e.get(t,i);return o}}o++;if(o===l)return o;if(h&&++d>10){if(Date.now()>c){i();return o}d=0}}}#he(){for(;this.stateStack.length||this.inSMaskMode;)this.restore();this.ctx.restore();if(this.transparentCanvas){this.ctx=this.compositeCtx;this.ctx.save();this.ctx.setTransform(1,0,0,1,0,0);this.ctx.drawImage(this.transparentCanvas,0,0);this.ctx.restore();this.transparentCanvas=null}}endDrawing(){this.#he();this.cachedCanvases.clear();this.cachedPatterns.clear();for(const t of this._cachedBitmapsMap.values()){for(const e of t.values())"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement&&(e.width=e.height=0);t.clear()}this._cachedBitmapsMap.clear();this.#ce()}#ce(){if(this.pageColors){const t=this.filterFactory.addHCMFilter(this.pageColors.foreground,this.pageColors.background);if("none"!==t){const e=this.ctx.filter;this.ctx.filter=t;this.ctx.drawImage(this.ctx.canvas,0,0);this.ctx.filter=e}}}_scaleImage(t,e){const i=t.width,s=t.height;let n,a,r=Math.max(Math.hypot(e[0],e[1]),1),o=Math.max(Math.hypot(e[2],e[3]),1),l=i,h=s,c="prescale1";for(;r>2&&l>1||o>2&&h>1;){let e=l,i=h;if(r>2&&l>1){e=l>=16384?Math.floor(l/2)-1||1:Math.ceil(l/2);r/=l/e}if(o>2&&h>1){i=h>=16384?Math.floor(h/2)-1||1:Math.ceil(h)/2;o/=h/i}n=this.cachedCanvases.getCanvas(c,e,i);a=n.context;a.clearRect(0,0,e,i);a.drawImage(t,0,0,l,h,0,0,e,i);t=n.canvas;l=e;h=i;c="prescale1"===c?"prescale2":"prescale1"}return{img:t,paintWidth:l,paintHeight:h}}_createMaskCanvas(t){const e=this.ctx,{width:i,height:r}=t,o=this.current.fillColor,l=this.current.patternFill,h=(0,n.getCurrentTransform)(e);let c,d,u,p;if((t.bitmap||t.data)&&t.count>1){const e=t.bitmap||t.data.buffer;d=JSON.stringify(l?h:[h.slice(0,4),o]);c=this._cachedBitmapsMap.get(e);if(!c){c=new Map;this._cachedBitmapsMap.set(e,c)}const i=c.get(d);if(i&&!l){return{canvas:i,offsetX:Math.round(Math.min(h[0],h[2])+h[4]),offsetY:Math.round(Math.min(h[1],h[3])+h[5])}}u=i}if(!u){p=this.cachedCanvases.getCanvas("maskCanvas",i,r);putBinaryImageMask(p.context,t)}let g=s.Util.transform(h,[1/i,0,0,-1/r,0,0]);g=s.Util.transform(g,[1,0,0,1,0,-r]);const m=s.Util.applyTransform([0,0],g),f=s.Util.applyTransform([i,r],g),b=s.Util.normalizeRect([m[0],m[1],f[0],f[1]]),A=Math.round(b[2]-b[0])||1,_=Math.round(b[3]-b[1])||1,v=this.cachedCanvases.getCanvas("fillCanvas",A,_),y=v.context,S=Math.min(m[0],f[0]),E=Math.min(m[1],f[1]);y.translate(-S,-E);y.transform(...g);if(!u){u=this._scaleImage(p.canvas,(0,n.getCurrentTransformInverse)(y));u=u.img;c&&l&&c.set(d,u)}y.imageSmoothingEnabled=getImageSmoothingEnabled((0,n.getCurrentTransform)(y),t.interpolate);drawImageAtIntegerCoords(y,u,0,0,u.width,u.height,0,0,i,r);y.globalCompositeOperation="source-in";const x=s.Util.transform((0,n.getCurrentTransformInverse)(y),[1,0,0,1,-S,-E]);y.fillStyle=l?o.getPattern(e,this,x,a.PathType.FILL):o;y.fillRect(0,0,i,r);if(c&&!l){this.cachedCanvases.delete("fillCanvas");c.set(d,v.canvas)}return{canvas:v.canvas,offsetX:Math.round(S),offsetY:Math.round(E)}}setLineWidth(t){t!==this.current.lineWidth&&(this._cachedScaleForStroking[0]=-1);this.current.lineWidth=t;this.ctx.lineWidth=t}setLineCap(t){this.ctx.lineCap=h[t]}setLineJoin(t){this.ctx.lineJoin=c[t]}setMiterLimit(t){this.ctx.miterLimit=t}setDash(t,e){const i=this.ctx;if(void 0!==i.setLineDash){i.setLineDash(t);i.lineDashOffset=e}}setRenderingIntent(t){}setFlatness(t){}setGState(t){for(const[e,i]of t)switch(e){case"LW":this.setLineWidth(i);break;case"LC":this.setLineCap(i);break;case"LJ":this.setLineJoin(i);break;case"ML":this.setMiterLimit(i);break;case"D":this.setDash(i[0],i[1]);break;case"RI":this.setRenderingIntent(i);break;case"FL":this.setFlatness(i);break;case"Font":this.setFont(i[0],i[1]);break;case"CA":this.current.strokeAlpha=i;break;case"ca":this.current.fillAlpha=i;this.ctx.globalAlpha=i;break;case"BM":this.ctx.globalCompositeOperation=i;break;case"SMask":this.current.activeSMask=i?this.tempSMask:null;this.tempSMask=null;this.checkSMaskState();break;case"TR":this.ctx.filter=this.current.transferMaps=this.filterFactory.addFilter(i)}}get inSMaskMode(){return!!this.suspendedCtx}checkSMaskState(){const t=this.inSMaskMode;this.current.activeSMask&&!t?this.beginSMaskMode():!this.current.activeSMask&&t&&this.endSMaskMode()}beginSMaskMode(){if(this.inSMaskMode)throw new Error("beginSMaskMode called while already in smask mode");const t=this.ctx.canvas.width,e=this.ctx.canvas.height,i="smaskGroupAt"+this.groupLevel,s=this.cachedCanvases.getCanvas(i,t,e);this.suspendedCtx=this.ctx;this.ctx=s.context;const a=this.ctx;a.setTransform(...(0,n.getCurrentTransform)(this.suspendedCtx));copyCtxState(this.suspendedCtx,a);!function mirrorContextOperations(t,e){if(t._removeMirroring)throw new Error("Context is already forwarding operations.");t.__originalSave=t.save;t.__originalRestore=t.restore;t.__originalRotate=t.rotate;t.__originalScale=t.scale;t.__originalTranslate=t.translate;t.__originalTransform=t.transform;t.__originalSetTransform=t.setTransform;t.__originalResetTransform=t.resetTransform;t.__originalClip=t.clip;t.__originalMoveTo=t.moveTo;t.__originalLineTo=t.lineTo;t.__originalBezierCurveTo=t.bezierCurveTo;t.__originalRect=t.rect;t.__originalClosePath=t.closePath;t.__originalBeginPath=t.beginPath;t._removeMirroring=()=>{t.save=t.__originalSave;t.restore=t.__originalRestore;t.rotate=t.__originalRotate;t.scale=t.__originalScale;t.translate=t.__originalTranslate;t.transform=t.__originalTransform;t.setTransform=t.__originalSetTransform;t.resetTransform=t.__originalResetTransform;t.clip=t.__originalClip;t.moveTo=t.__originalMoveTo;t.lineTo=t.__originalLineTo;t.bezierCurveTo=t.__originalBezierCurveTo;t.rect=t.__originalRect;t.closePath=t.__originalClosePath;t.beginPath=t.__originalBeginPath;delete t._removeMirroring};t.save=function ctxSave(){e.save();this.__originalSave()};t.restore=function ctxRestore(){e.restore();this.__originalRestore()};t.translate=function ctxTranslate(t,i){e.translate(t,i);this.__originalTranslate(t,i)};t.scale=function ctxScale(t,i){e.scale(t,i);this.__originalScale(t,i)};t.transform=function ctxTransform(t,i,s,n,a,r){e.transform(t,i,s,n,a,r);this.__originalTransform(t,i,s,n,a,r)};t.setTransform=function ctxSetTransform(t,i,s,n,a,r){e.setTransform(t,i,s,n,a,r);this.__originalSetTransform(t,i,s,n,a,r)};t.resetTransform=function ctxResetTransform(){e.resetTransform();this.__originalResetTransform()};t.rotate=function ctxRotate(t){e.rotate(t);this.__originalRotate(t)};t.clip=function ctxRotate(t){e.clip(t);this.__originalClip(t)};t.moveTo=function(t,i){e.moveTo(t,i);this.__originalMoveTo(t,i)};t.lineTo=function(t,i){e.lineTo(t,i);this.__originalLineTo(t,i)};t.bezierCurveTo=function(t,i,s,n,a,r){e.bezierCurveTo(t,i,s,n,a,r);this.__originalBezierCurveTo(t,i,s,n,a,r)};t.rect=function(t,i,s,n){e.rect(t,i,s,n);this.__originalRect(t,i,s,n)};t.closePath=function(){e.closePath();this.__originalClosePath()};t.beginPath=function(){e.beginPath();this.__originalBeginPath()}}(a,this.suspendedCtx);this.setGState([["BM","source-over"],["ca",1],["CA",1]])}endSMaskMode(){if(!this.inSMaskMode)throw new Error("endSMaskMode called while not in smask mode");this.ctx._removeMirroring();copyCtxState(this.ctx,this.suspendedCtx);this.ctx=this.suspendedCtx;this.suspendedCtx=null}compose(t){if(!this.current.activeSMask)return;if(t){t[0]=Math.floor(t[0]);t[1]=Math.floor(t[1]);t[2]=Math.ceil(t[2]);t[3]=Math.ceil(t[3])}else t=[0,0,this.ctx.canvas.width,this.ctx.canvas.height];const e=this.current.activeSMask;composeSMask(this.suspendedCtx,e,this.ctx,t);this.ctx.save();this.ctx.setTransform(1,0,0,1,0,0);this.ctx.clearRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height);this.ctx.restore()}save(){if(this.inSMaskMode){copyCtxState(this.ctx,this.suspendedCtx);this.suspendedCtx.save()}else this.ctx.save();const t=this.current;this.stateStack.push(t);this.current=t.clone()}restore(){0===this.stateStack.length&&this.inSMaskMode&&this.endSMaskMode();if(0!==this.stateStack.length){this.current=this.stateStack.pop();if(this.inSMaskMode){this.suspendedCtx.restore();copyCtxState(this.suspendedCtx,this.ctx)}else this.ctx.restore();this.checkSMaskState();this.pendingClip=null;this._cachedScaleForStroking[0]=-1;this._cachedGetSinglePixelWidth=null}}transform(t,e,i,s,n,a){this.ctx.transform(t,e,i,s,n,a);this._cachedScaleForStroking[0]=-1;this._cachedGetSinglePixelWidth=null}constructPath(t,e,i){const a=this.ctx,r=this.current;let o,l,h=r.x,c=r.y;const d=(0,n.getCurrentTransform)(a),u=0===d[0]&&0===d[3]||0===d[1]&&0===d[2],p=u?i.slice(0):null;for(let i=0,n=0,g=t.length;i100&&(h=100);this.current.fontSizeScale=e/h;this.ctx.font=`${l} ${o} ${h}px ${r}`}setTextRenderingMode(t){this.current.textRenderingMode=t}setTextRise(t){this.current.textRise=t}moveText(t,e){this.current.x=this.current.lineX+=t;this.current.y=this.current.lineY+=e}setLeadingMoveText(t,e){this.setLeading(-e);this.moveText(t,e)}setTextMatrix(t,e,i,s,n,a){this.current.textMatrix=[t,e,i,s,n,a];this.current.textMatrixScale=Math.hypot(t,e);this.current.x=this.current.lineX=0;this.current.y=this.current.lineY=0}nextLine(){this.moveText(0,this.current.leading)}paintChar(t,e,i,a){const r=this.ctx,o=this.current,l=o.font,h=o.textRenderingMode,c=o.fontSize/o.fontSizeScale,d=h&s.TextRenderingMode.FILL_STROKE_MASK,u=!!(h&s.TextRenderingMode.ADD_TO_PATH_FLAG),p=o.patternFill&&!l.missingFile;let g;(l.disableFontFace||u||p)&&(g=l.getPathGenerator(this.commonObjs,t));if(l.disableFontFace||p){r.save();r.translate(e,i);r.beginPath();g(r,c);a&&r.setTransform(...a);d!==s.TextRenderingMode.FILL&&d!==s.TextRenderingMode.FILL_STROKE||r.fill();d!==s.TextRenderingMode.STROKE&&d!==s.TextRenderingMode.FILL_STROKE||r.stroke();r.restore()}else{d!==s.TextRenderingMode.FILL&&d!==s.TextRenderingMode.FILL_STROKE||r.fillText(t,e,i);d!==s.TextRenderingMode.STROKE&&d!==s.TextRenderingMode.FILL_STROKE||r.strokeText(t,e,i)}if(u){(this.pendingTextPaths||=[]).push({transform:(0,n.getCurrentTransform)(r),x:e,y:i,fontSize:c,addToPath:g})}}get isFontSubpixelAAEnabled(){const{context:t}=this.cachedCanvases.getCanvas("isFontSubpixelAAEnabled",10,10);t.scale(1.5,1);t.fillText("I",0,10);const e=t.getImageData(0,0,10,10).data;let i=!1;for(let t=3;t0&&e[t]<255){i=!0;break}return(0,s.shadow)(this,"isFontSubpixelAAEnabled",i)}showText(t){const e=this.current,i=e.font;if(i.isType3Font)return this.showType3Text(t);const r=e.fontSize;if(0===r)return;const o=this.ctx,l=e.fontSizeScale,h=e.charSpacing,c=e.wordSpacing,d=e.fontDirection,u=e.textHScale*d,p=t.length,g=i.vertical,m=g?1:-1,f=i.defaultVMetrics,b=r*e.fontMatrix[0],A=e.textRenderingMode===s.TextRenderingMode.FILL&&!i.disableFontFace&&!e.patternFill;o.save();o.transform(...e.textMatrix);o.translate(e.x,e.y+e.textRise);d>0?o.scale(u,-1):o.scale(u,1);let _;if(e.patternFill){o.save();const t=e.fillColor.getPattern(o,this,(0,n.getCurrentTransformInverse)(o),a.PathType.FILL);_=(0,n.getCurrentTransform)(o);o.restore();o.fillStyle=t}let v=e.lineWidth;const y=e.textMatrixScale;if(0===y||0===v){const t=e.textRenderingMode&s.TextRenderingMode.FILL_STROKE_MASK;t!==s.TextRenderingMode.STROKE&&t!==s.TextRenderingMode.FILL_STROKE||(v=this.getSinglePixelWidth())}else v/=y;if(1!==l){o.scale(l,l);v/=l}o.lineWidth=v;if(i.isInvalidPDFjsFont){const i=[];let s=0;for(const e of t){i.push(e.unicode);s+=e.width}o.fillText(i.join(""),0,0);e.x+=s*b*u;o.restore();this.compose();return}let S,E=0;for(S=0;S0){const t=1e3*o.measureText(a).width/r*l;if(ynew CanvasGraphics(t,this.commonObjs,this.objs,this.canvasFactory,this.filterFactory,{optionalContentConfig:this.optionalContentConfig,markedContentStack:this.markedContentStack})};e=new a.TilingPattern(t,i,this.ctx,r,s)}else e=this._getPattern(t[1],t[2]);return e}setStrokeColorN(){this.current.strokeColor=this.getColorN_Pattern(arguments)}setFillColorN(){this.current.fillColor=this.getColorN_Pattern(arguments);this.current.patternFill=!0}setStrokeRGBColor(t,e,i){const n=s.Util.makeHexColor(t,e,i);this.ctx.strokeStyle=n;this.current.strokeColor=n}setFillRGBColor(t,e,i){const n=s.Util.makeHexColor(t,e,i);this.ctx.fillStyle=n;this.current.fillColor=n;this.current.patternFill=!1}_getPattern(t,e=null){let i;if(this.cachedPatterns.has(t))i=this.cachedPatterns.get(t);else{i=(0,a.getShadingPattern)(this.getObject(t));this.cachedPatterns.set(t,i)}e&&(i.matrix=e);return i}shadingFill(t){if(!this.contentVisible)return;const e=this.ctx;this.save();const i=this._getPattern(t);e.fillStyle=i.getPattern(e,this,(0,n.getCurrentTransformInverse)(e),a.PathType.SHADING);const r=(0,n.getCurrentTransformInverse)(e);if(r){const{width:t,height:i}=e.canvas,[n,a,o,l]=s.Util.getAxialAlignedBoundingBox([0,0,t,i],r);this.ctx.fillRect(n,a,o-n,l-a)}else this.ctx.fillRect(-1e10,-1e10,2e10,2e10);this.compose(this.current.getClippedPathBoundingBox());this.restore()}beginInlineImage(){(0,s.unreachable)("Should not call beginInlineImage")}beginImageData(){(0,s.unreachable)("Should not call beginImageData")}paintFormXObjectBegin(t,e){if(this.contentVisible){this.save();this.baseTransformStack.push(this.baseTransform);Array.isArray(t)&&6===t.length&&this.transform(...t);this.baseTransform=(0,n.getCurrentTransform)(this.ctx);if(e){const t=e[2]-e[0],i=e[3]-e[1];this.ctx.rect(e[0],e[1],t,i);this.current.updateRectMinMax((0,n.getCurrentTransform)(this.ctx),e);this.clip();this.endPath()}}}paintFormXObjectEnd(){if(this.contentVisible){this.restore();this.baseTransform=this.baseTransformStack.pop()}}beginGroup(t){if(!this.contentVisible)return;this.save();if(this.inSMaskMode){this.endSMaskMode();this.current.activeSMask=null}const e=this.ctx;t.isolated||(0,s.info)("TODO: Support non-isolated groups.");t.knockout&&(0,s.warn)("Knockout groups not supported.");const i=(0,n.getCurrentTransform)(e);t.matrix&&e.transform(...t.matrix);if(!t.bbox)throw new Error("Bounding box is required.");let a=s.Util.getAxialAlignedBoundingBox(t.bbox,(0,n.getCurrentTransform)(e));const r=[0,0,e.canvas.width,e.canvas.height];a=s.Util.intersect(a,r)||[0,0,0,0];const l=Math.floor(a[0]),h=Math.floor(a[1]);let c=Math.max(Math.ceil(a[2])-l,1),d=Math.max(Math.ceil(a[3])-h,1),u=1,p=1;if(c>o){u=c/o;c=o}if(d>o){p=d/o;d=o}this.current.startNewPathAndClipBox([0,0,c,d]);let g="groupAt"+this.groupLevel;t.smask&&(g+="_smask_"+this.smaskCounter++%2);const m=this.cachedCanvases.getCanvas(g,c,d),f=m.context;f.scale(1/u,1/p);f.translate(-l,-h);f.transform(...i);if(t.smask)this.smaskStack.push({canvas:m.canvas,context:f,offsetX:l,offsetY:h,scaleX:u,scaleY:p,subtype:t.smask.subtype,backdrop:t.smask.backdrop,transferMap:t.smask.transferMap||null,startTransformInverse:null});else{e.setTransform(1,0,0,1,0,0);e.translate(l,h);e.scale(u,p);e.save()}copyCtxState(e,f);this.ctx=f;this.setGState([["BM","source-over"],["ca",1],["CA",1]]);this.groupStack.push(e);this.groupLevel++}endGroup(t){if(!this.contentVisible)return;this.groupLevel--;const e=this.ctx,i=this.groupStack.pop();this.ctx=i;this.ctx.imageSmoothingEnabled=!1;if(t.smask){this.tempSMask=this.smaskStack.pop();this.restore()}else{this.ctx.restore();const t=(0,n.getCurrentTransform)(this.ctx);this.restore();this.ctx.save();this.ctx.setTransform(...t);const i=s.Util.getAxialAlignedBoundingBox([0,0,e.canvas.width,e.canvas.height],t);this.ctx.drawImage(e.canvas,0,0);this.ctx.restore();this.compose(i)}}beginAnnotation(t,e,i,a,r){this.#he();resetCtxToDefault(this.ctx);this.ctx.save();this.save();this.baseTransform&&this.ctx.setTransform(...this.baseTransform);if(Array.isArray(e)&&4===e.length){const a=e[2]-e[0],o=e[3]-e[1];if(r&&this.annotationCanvasMap){(i=i.slice())[4]-=e[0];i[5]-=e[1];(e=e.slice())[0]=e[1]=0;e[2]=a;e[3]=o;const[r,l]=s.Util.singularValueDecompose2dScale((0,n.getCurrentTransform)(this.ctx)),{viewportScale:h}=this,c=Math.ceil(a*this.outputScaleX*h),d=Math.ceil(o*this.outputScaleY*h);this.annotationCanvas=this.canvasFactory.create(c,d);const{canvas:u,context:p}=this.annotationCanvas;this.annotationCanvasMap.set(t,u);this.annotationCanvas.savedCtx=this.ctx;this.ctx=p;this.ctx.save();this.ctx.setTransform(r,0,0,-l,0,o*l);resetCtxToDefault(this.ctx)}else{resetCtxToDefault(this.ctx);this.ctx.rect(e[0],e[1],a,o);this.ctx.clip();this.endPath()}}this.current=new CanvasExtraState(this.ctx.canvas.width,this.ctx.canvas.height);this.transform(...i);this.transform(...a)}endAnnotation(){if(this.annotationCanvas){this.ctx.restore();this.#ce();this.ctx=this.annotationCanvas.savedCtx;delete this.annotationCanvas.savedCtx;delete this.annotationCanvas}}paintImageMaskXObject(t){if(!this.contentVisible)return;const e=t.count;(t=this.getObject(t.data,t)).count=e;const i=this.ctx,s=this.processingType3;if(s){void 0===s.compiled&&(s.compiled=function compileType3Glyph(t){const{width:e,height:i}=t;if(e>1e3||i>1e3)return null;const s=new Uint8Array([0,2,4,0,1,0,5,4,8,10,0,8,0,2,1,0]),n=e+1;let a,r,o,l=new Uint8Array(n*(i+1));const h=e+7&-8;let c=new Uint8Array(h*i),d=0;for(const e of t.data){let t=128;for(;t>0;){c[d++]=e&t?0:255;t>>=1}}let u=0;d=0;if(0!==c[d]){l[0]=1;++u}for(r=1;r>2)+(c[d+1]?4:0)+(c[d-h+1]?8:0);if(s[t]){l[o+r]=s[t];++u}d++}if(c[d-h]!==c[d]){l[o+r]=c[d]?2:4;++u}if(u>1e3)return null}d=h*(i-1);o=a*n;if(0!==c[d]){l[o]=8;++u}for(r=1;r1e3)return null;const p=new Int32Array([0,n,-1,0,-n,0,0,0,1]),g=new Path2D;for(a=0;u&&a<=i;a++){let t=a*n;const i=t+e;for(;t>4;l[t]&=r>>2|r<<2}g.lineTo(t%n,t/n|0);l[t]||--u}while(s!==t);--a}c=null;l=null;return function(t){t.save();t.scale(1/e,-1/i);t.translate(0,-i);t.fill(g);t.beginPath();t.restore()}}(t));if(s.compiled){s.compiled(i);return}}const n=this._createMaskCanvas(t),a=n.canvas;i.save();i.setTransform(1,0,0,1,0,0);i.drawImage(a,n.offsetX,n.offsetY);i.restore();this.compose()}paintImageMaskXObjectRepeat(t,e,i=0,a=0,r,o){if(!this.contentVisible)return;t=this.getObject(t.data,t);const l=this.ctx;l.save();const h=(0,n.getCurrentTransform)(l);l.transform(e,i,a,r,0,0);const c=this._createMaskCanvas(t);l.setTransform(1,0,0,1,c.offsetX-h[4],c.offsetY-h[5]);for(let t=0,n=o.length;te?h/e:1;r=l>e?l/e:1}}this._cachedScaleForStroking[0]=a;this._cachedScaleForStroking[1]=r}return this._cachedScaleForStroking}rescaleAndStroke(t){const{ctx:e}=this,{lineWidth:i}=this.current,[s,n]=this.getScaleForStroking();e.lineWidth=i||1;if(1===s&&1===n){e.stroke();return}const a=e.getLineDash();t&&e.save();e.scale(s,n);if(a.length>0){const t=Math.max(s,n);e.setLineDash(a.map((e=>e/t)));e.lineDashOffset/=t}e.stroke();t&&e.restore()}isContentVisible(){for(let t=this.markedContentStack.length-1;t>=0;t--)if(!this.markedContentStack[t].visible)return!1;return!0}}e.CanvasGraphics=CanvasGraphics;for(const t in s.OPS)void 0!==CanvasGraphics.prototype[t]&&(CanvasGraphics.prototype[s.OPS[t]]=CanvasGraphics.prototype[t])},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.TilingPattern=e.PathType=void 0;e.getShadingPattern=function getShadingPattern(t){switch(t[0]){case"RadialAxial":return new RadialAxialShadingPattern(t);case"Mesh":return new MeshShadingPattern(t);case"Dummy":return new DummyShadingPattern}throw new Error(`Unknown IR type: ${t[0]}`)};var s=i(1),n=i(6);const a={FILL:"Fill",STROKE:"Stroke",SHADING:"Shading"};e.PathType=a;function applyBoundingBox(t,e){if(!e)return;const i=e[2]-e[0],s=e[3]-e[1],n=new Path2D;n.rect(e[0],e[1],i,s);t.clip(n)}class BaseShadingPattern{constructor(){this.constructor===BaseShadingPattern&&(0,s.unreachable)("Cannot initialize BaseShadingPattern.")}getPattern(){(0,s.unreachable)("Abstract method `getPattern` called.")}}class RadialAxialShadingPattern extends BaseShadingPattern{constructor(t){super();this._type=t[1];this._bbox=t[2];this._colorStops=t[3];this._p0=t[4];this._p1=t[5];this._r0=t[6];this._r1=t[7];this.matrix=null}_createGradient(t){let e;"axial"===this._type?e=t.createLinearGradient(this._p0[0],this._p0[1],this._p1[0],this._p1[1]):"radial"===this._type&&(e=t.createRadialGradient(this._p0[0],this._p0[1],this._r0,this._p1[0],this._p1[1],this._r1));for(const t of this._colorStops)e.addColorStop(t[0],t[1]);return e}getPattern(t,e,i,r){let o;if(r===a.STROKE||r===a.FILL){const a=e.current.getClippedPathBoundingBox(r,(0,n.getCurrentTransform)(t))||[0,0,0,0],l=Math.ceil(a[2]-a[0])||1,h=Math.ceil(a[3]-a[1])||1,c=e.cachedCanvases.getCanvas("pattern",l,h,!0),d=c.context;d.clearRect(0,0,d.canvas.width,d.canvas.height);d.beginPath();d.rect(0,0,d.canvas.width,d.canvas.height);d.translate(-a[0],-a[1]);i=s.Util.transform(i,[1,0,0,1,a[0],a[1]]);d.transform(...e.baseTransform);this.matrix&&d.transform(...this.matrix);applyBoundingBox(d,this._bbox);d.fillStyle=this._createGradient(d);d.fill();o=t.createPattern(c.canvas,"no-repeat");const u=new DOMMatrix(i);o.setTransform(u)}else{applyBoundingBox(t,this._bbox);o=this._createGradient(t)}return o}}function drawTriangle(t,e,i,s,n,a,r,o){const l=e.coords,h=e.colors,c=t.data,d=4*t.width;let u;if(l[i+1]>l[s+1]){u=i;i=s;s=u;u=a;a=r;r=u}if(l[s+1]>l[n+1]){u=s;s=n;n=u;u=r;r=o;o=u}if(l[i+1]>l[s+1]){u=i;i=s;s=u;u=a;a=r;r=u}const p=(l[i]+e.offsetX)*e.scaleX,g=(l[i+1]+e.offsetY)*e.scaleY,m=(l[s]+e.offsetX)*e.scaleX,f=(l[s+1]+e.offsetY)*e.scaleY,b=(l[n]+e.offsetX)*e.scaleX,A=(l[n+1]+e.offsetY)*e.scaleY;if(g>=A)return;const _=h[a],v=h[a+1],y=h[a+2],S=h[r],E=h[r+1],x=h[r+2],w=h[o],C=h[o+1],T=h[o+2],P=Math.round(g),M=Math.round(A);let k,F,R,D,I,L,O,N;for(let t=P;t<=M;t++){if(tA?1:f===A?0:(f-t)/(f-A);k=m-(m-b)*e;F=S-(S-w)*e;R=E-(E-C)*e;D=x-(x-T)*e}let e;e=tA?1:(g-t)/(g-A);I=p-(p-b)*e;L=_-(_-w)*e;O=v-(v-C)*e;N=y-(y-T)*e;const i=Math.round(Math.min(k,I)),s=Math.round(Math.max(k,I));let n=d*t+4*i;for(let t=i;t<=s;t++){e=(k-t)/(k-I);e<0?e=0:e>1&&(e=1);c[n++]=F-(F-L)*e|0;c[n++]=R-(R-O)*e|0;c[n++]=D-(D-N)*e|0;c[n++]=255}}}function drawFigure(t,e,i){const s=e.coords,n=e.colors;let a,r;switch(e.type){case"lattice":const o=e.verticesPerRow,l=Math.floor(s.length/o)-1,h=o-1;for(a=0;a=s?n=s:i=n/t;return{scale:i,size:n}}clipBbox(t,e,i,s,a){const r=s-e,o=a-i;t.ctx.rect(e,i,r,o);t.current.updateRectMinMax((0,n.getCurrentTransform)(t.ctx),[e,i,s,a]);t.clip();t.endPath()}setFillAndStrokeStyleToContext(t,e,i){const n=t.ctx,a=t.current;switch(e){case r:const t=this.ctx;n.fillStyle=t.fillStyle;n.strokeStyle=t.strokeStyle;a.fillColor=t.fillStyle;a.strokeColor=t.strokeStyle;break;case o:const l=s.Util.makeHexColor(i[0],i[1],i[2]);n.fillStyle=l;n.strokeStyle=l;a.fillColor=l;a.strokeColor=l;break;default:throw new s.FormatError(`Unsupported paint type: ${e}`)}}getPattern(t,e,i,n){let r=i;if(n!==a.SHADING){r=s.Util.transform(r,e.baseTransform);this.matrix&&(r=s.Util.transform(r,this.matrix))}const o=this.createPatternCanvas(e);let l=new DOMMatrix(r);l=l.translate(o.offsetX,o.offsetY);l=l.scale(1/o.scaleX,1/o.scaleY);const h=t.createPattern(o.canvas,"repeat");h.setTransform(l);return h}}e.TilingPattern=TilingPattern},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.convertBlackAndWhiteToRGBA=convertBlackAndWhiteToRGBA;e.convertToRGBA=function convertToRGBA(t){switch(t.kind){case s.ImageKind.GRAYSCALE_1BPP:return convertBlackAndWhiteToRGBA(t);case s.ImageKind.RGB_24BPP:return function convertRGBToRGBA({src:t,srcPos:e=0,dest:i,destPos:n=0,width:a,height:r}){let o=0;const l=t.length>>2,h=new Uint32Array(t.buffer,e,l);if(s.FeatureTest.isLittleEndian){for(;o>>24|e<<8|4278190080;i[n+2]=e>>>16|s<<16|4278190080;i[n+3]=s>>>8|4278190080}for(let e=4*o,s=t.length;e>>8|255;i[n+2]=e<<16|s>>>16|255;i[n+3]=s<<8|255}for(let e=4*o,s=t.length;e>3,u=7&n,p=t.length;i=new Uint32Array(i.buffer);let g=0;for(let s=0;s{Object.defineProperty(e,"__esModule",{value:!0});e.GlobalWorkerOptions=void 0;const i=Object.create(null);e.GlobalWorkerOptions=i;i.workerPort=null;i.workerSrc=""},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.MessageHandler=void 0;var s=i(1);const n=1,a=2,r=1,o=2,l=3,h=4,c=5,d=6,u=7,p=8;function wrapReason(t){t instanceof Error||"object"==typeof t&&null!==t||(0,s.unreachable)('wrapReason: Expected "reason" to be a (possibly cloned) Error.');switch(t.name){case"AbortException":return new s.AbortException(t.message);case"MissingPDFException":return new s.MissingPDFException(t.message);case"PasswordException":return new s.PasswordException(t.message,t.code);case"UnexpectedResponseException":return new s.UnexpectedResponseException(t.message,t.status);case"UnknownErrorException":return new s.UnknownErrorException(t.message,t.details);default:return new s.UnknownErrorException(t.message,t.toString())}}e.MessageHandler=class MessageHandler{constructor(t,e,i){this.sourceName=t;this.targetName=e;this.comObj=i;this.callbackId=1;this.streamId=1;this.streamSinks=Object.create(null);this.streamControllers=Object.create(null);this.callbackCapabilities=Object.create(null);this.actionHandler=Object.create(null);this._onComObjOnMessage=t=>{const e=t.data;if(e.targetName!==this.sourceName)return;if(e.stream){this.#de(e);return}if(e.callback){const t=e.callbackId,i=this.callbackCapabilities[t];if(!i)throw new Error(`Cannot resolve callback ${t}`);delete this.callbackCapabilities[t];if(e.callback===n)i.resolve(e.data);else{if(e.callback!==a)throw new Error("Unexpected callback case");i.reject(wrapReason(e.reason))}return}const s=this.actionHandler[e.action];if(!s)throw new Error(`Unknown action from worker: ${e.action}`);if(e.callbackId){const t=this.sourceName,r=e.sourceName;new Promise((function(t){t(s(e.data))})).then((function(s){i.postMessage({sourceName:t,targetName:r,callback:n,callbackId:e.callbackId,data:s})}),(function(s){i.postMessage({sourceName:t,targetName:r,callback:a,callbackId:e.callbackId,reason:wrapReason(s)})}))}else e.streamId?this.#ue(e):s(e.data)};i.addEventListener("message",this._onComObjOnMessage)}on(t,e){const i=this.actionHandler;if(i[t])throw new Error(`There is already an actionName called "${t}"`);i[t]=e}send(t,e,i){this.comObj.postMessage({sourceName:this.sourceName,targetName:this.targetName,action:t,data:e},i)}sendWithPromise(t,e,i){const n=this.callbackId++,a=new s.PromiseCapability;this.callbackCapabilities[n]=a;try{this.comObj.postMessage({sourceName:this.sourceName,targetName:this.targetName,action:t,callbackId:n,data:e},i)}catch(t){a.reject(t)}return a.promise}sendWithStream(t,e,i,n){const a=this.streamId++,o=this.sourceName,l=this.targetName,h=this.comObj;return new ReadableStream({start:i=>{const r=new s.PromiseCapability;this.streamControllers[a]={controller:i,startCall:r,pullCall:null,cancelCall:null,isClosed:!1};h.postMessage({sourceName:o,targetName:l,action:t,streamId:a,data:e,desiredSize:i.desiredSize},n);return r.promise},pull:t=>{const e=new s.PromiseCapability;this.streamControllers[a].pullCall=e;h.postMessage({sourceName:o,targetName:l,stream:d,streamId:a,desiredSize:t.desiredSize});return e.promise},cancel:t=>{(0,s.assert)(t instanceof Error,"cancel must have a valid reason");const e=new s.PromiseCapability;this.streamControllers[a].cancelCall=e;this.streamControllers[a].isClosed=!0;h.postMessage({sourceName:o,targetName:l,stream:r,streamId:a,reason:wrapReason(t)});return e.promise}},i)}#ue(t){const e=t.streamId,i=this.sourceName,n=t.sourceName,a=this.comObj,r=this,o=this.actionHandler[t.action],d={enqueue(t,r=1,o){if(this.isCancelled)return;const l=this.desiredSize;this.desiredSize-=r;if(l>0&&this.desiredSize<=0){this.sinkCapability=new s.PromiseCapability;this.ready=this.sinkCapability.promise}a.postMessage({sourceName:i,targetName:n,stream:h,streamId:e,chunk:t},o)},close(){if(!this.isCancelled){this.isCancelled=!0;a.postMessage({sourceName:i,targetName:n,stream:l,streamId:e});delete r.streamSinks[e]}},error(t){(0,s.assert)(t instanceof Error,"error must have a valid reason");if(!this.isCancelled){this.isCancelled=!0;a.postMessage({sourceName:i,targetName:n,stream:c,streamId:e,reason:wrapReason(t)})}},sinkCapability:new s.PromiseCapability,onPull:null,onCancel:null,isCancelled:!1,desiredSize:t.desiredSize,ready:null};d.sinkCapability.resolve();d.ready=d.sinkCapability.promise;this.streamSinks[e]=d;new Promise((function(e){e(o(t.data,d))})).then((function(){a.postMessage({sourceName:i,targetName:n,stream:p,streamId:e,success:!0})}),(function(t){a.postMessage({sourceName:i,targetName:n,stream:p,streamId:e,reason:wrapReason(t)})}))}#de(t){const e=t.streamId,i=this.sourceName,n=t.sourceName,a=this.comObj,g=this.streamControllers[e],m=this.streamSinks[e];switch(t.stream){case p:t.success?g.startCall.resolve():g.startCall.reject(wrapReason(t.reason));break;case u:t.success?g.pullCall.resolve():g.pullCall.reject(wrapReason(t.reason));break;case d:if(!m){a.postMessage({sourceName:i,targetName:n,stream:u,streamId:e,success:!0});break}m.desiredSize<=0&&t.desiredSize>0&&m.sinkCapability.resolve();m.desiredSize=t.desiredSize;new Promise((function(t){t(m.onPull?.())})).then((function(){a.postMessage({sourceName:i,targetName:n,stream:u,streamId:e,success:!0})}),(function(t){a.postMessage({sourceName:i,targetName:n,stream:u,streamId:e,reason:wrapReason(t)})}));break;case h:(0,s.assert)(g,"enqueue should have stream controller");if(g.isClosed)break;g.controller.enqueue(t.chunk);break;case l:(0,s.assert)(g,"close should have stream controller");if(g.isClosed)break;g.isClosed=!0;g.controller.close();this.#pe(g,e);break;case c:(0,s.assert)(g,"error should have stream controller");g.controller.error(wrapReason(t.reason));this.#pe(g,e);break;case o:t.success?g.cancelCall.resolve():g.cancelCall.reject(wrapReason(t.reason));this.#pe(g,e);break;case r:if(!m)break;new Promise((function(e){e(m.onCancel?.(wrapReason(t.reason)))})).then((function(){a.postMessage({sourceName:i,targetName:n,stream:o,streamId:e,success:!0})}),(function(t){a.postMessage({sourceName:i,targetName:n,stream:o,streamId:e,reason:wrapReason(t)})}));m.sinkCapability.reject(wrapReason(t.reason));m.isCancelled=!0;delete this.streamSinks[e];break;default:throw new Error("Unexpected stream case")}}async#pe(t,e){await Promise.allSettled([t.startCall?.promise,t.pullCall?.promise,t.cancelCall?.promise]);delete this.streamControllers[e]}destroy(){this.comObj.removeEventListener("message",this._onComObjOnMessage)}}},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.Metadata=void 0;var s=i(1);e.Metadata=class Metadata{#ge;#me;constructor({parsedData:t,rawData:e}){this.#ge=t;this.#me=e}getRaw(){return this.#me}get(t){return this.#ge.get(t)??null}getAll(){return(0,s.objectFromMap)(this.#ge)}has(t){return this.#ge.has(t)}}},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.OptionalContentConfig=void 0;var s=i(1),n=i(8);const a=Symbol("INTERNAL");class OptionalContentGroup{#fe=!0;constructor(t,e){this.name=t;this.intent=e}get visible(){return this.#fe}_setVisible(t,e){t!==a&&(0,s.unreachable)("Internal method `_setVisible` called.");this.#fe=e}}e.OptionalContentConfig=class OptionalContentConfig{#be=null;#Ae=new Map;#_e=null;#ve=null;constructor(t){this.name=null;this.creator=null;if(null!==t){this.name=t.name;this.creator=t.creator;this.#ve=t.order;for(const e of t.groups)this.#Ae.set(e.id,new OptionalContentGroup(e.name,e.intent));if("OFF"===t.baseState)for(const t of this.#Ae.values())t._setVisible(a,!1);for(const e of t.on)this.#Ae.get(e)._setVisible(a,!0);for(const e of t.off)this.#Ae.get(e)._setVisible(a,!1);this.#_e=this.getHash()}}#ye(t){const e=t.length;if(e<2)return!0;const i=t[0];for(let n=1;n0?(0,s.objectFromMap)(this.#Ae):null}getGroup(t){return this.#Ae.get(t)||null}getHash(){if(null!==this.#be)return this.#be;const t=new n.MurmurHash3_64;for(const[e,i]of this.#Ae)t.update(`${e}:${i.visible}`);return this.#be=t.hexdigest()}}},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.PDFDataTransportStream=void 0;var s=i(1),n=i(6);e.PDFDataTransportStream=class PDFDataTransportStream{constructor({length:t,initialData:e,progressiveDone:i=!1,contentDispositionFilename:n=null,disableRange:a=!1,disableStream:r=!1},o){(0,s.assert)(o,'PDFDataTransportStream - missing required "pdfDataRangeTransport" argument.');this._queuedChunks=[];this._progressiveDone=i;this._contentDispositionFilename=n;if(e?.length>0){const t=e instanceof Uint8Array&&e.byteLength===e.buffer.byteLength?e.buffer:new Uint8Array(e).buffer;this._queuedChunks.push(t)}this._pdfDataRangeTransport=o;this._isStreamingSupported=!r;this._isRangeSupported=!a;this._contentLength=t;this._fullRequestReader=null;this._rangeReaders=[];this._pdfDataRangeTransport.addRangeListener(((t,e)=>{this._onReceiveData({begin:t,chunk:e})}));this._pdfDataRangeTransport.addProgressListener(((t,e)=>{this._onProgress({loaded:t,total:e})}));this._pdfDataRangeTransport.addProgressiveReadListener((t=>{this._onReceiveData({chunk:t})}));this._pdfDataRangeTransport.addProgressiveDoneListener((()=>{this._onProgressiveDone()}));this._pdfDataRangeTransport.transportReady()}_onReceiveData({begin:t,chunk:e}){const i=e instanceof Uint8Array&&e.byteLength===e.buffer.byteLength?e.buffer:new Uint8Array(e).buffer;if(void 0===t)this._fullRequestReader?this._fullRequestReader._enqueue(i):this._queuedChunks.push(i);else{const e=this._rangeReaders.some((function(e){if(e._begin!==t)return!1;e._enqueue(i);return!0}));(0,s.assert)(e,"_onReceiveData - no `PDFDataTransportStreamRangeReader` instance found.")}}get _progressiveDataLength(){return this._fullRequestReader?._loaded??0}_onProgress(t){void 0===t.total?this._rangeReaders[0]?.onProgress?.({loaded:t.loaded}):this._fullRequestReader?.onProgress?.({loaded:t.loaded,total:t.total})}_onProgressiveDone(){this._fullRequestReader?.progressiveDone();this._progressiveDone=!0}_removeRangeReader(t){const e=this._rangeReaders.indexOf(t);e>=0&&this._rangeReaders.splice(e,1)}getFullReader(){(0,s.assert)(!this._fullRequestReader,"PDFDataTransportStream.getFullReader can only be called once.");const t=this._queuedChunks;this._queuedChunks=null;return new PDFDataTransportStreamReader(this,t,this._progressiveDone,this._contentDispositionFilename)}getRangeReader(t,e){if(e<=this._progressiveDataLength)return null;const i=new PDFDataTransportStreamRangeReader(this,t,e);this._pdfDataRangeTransport.requestDataRange(t,e);this._rangeReaders.push(i);return i}cancelAllRequests(t){this._fullRequestReader?.cancel(t);for(const e of this._rangeReaders.slice(0))e.cancel(t);this._pdfDataRangeTransport.abort()}};class PDFDataTransportStreamReader{constructor(t,e,i=!1,s=null){this._stream=t;this._done=i||!1;this._filename=(0,n.isPdfFile)(s)?s:null;this._queuedChunks=e||[];this._loaded=0;for(const t of this._queuedChunks)this._loaded+=t.byteLength;this._requests=[];this._headersReady=Promise.resolve();t._fullRequestReader=this;this.onProgress=null}_enqueue(t){if(!this._done){if(this._requests.length>0){this._requests.shift().resolve({value:t,done:!1})}else this._queuedChunks.push(t);this._loaded+=t.byteLength}}get headersReady(){return this._headersReady}get filename(){return this._filename}get isRangeSupported(){return this._stream._isRangeSupported}get isStreamingSupported(){return this._stream._isStreamingSupported}get contentLength(){return this._stream._contentLength}async read(){if(this._queuedChunks.length>0){return{value:this._queuedChunks.shift(),done:!1}}if(this._done)return{value:void 0,done:!0};const t=new s.PromiseCapability;this._requests.push(t);return t.promise}cancel(t){this._done=!0;for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0}progressiveDone(){this._done||(this._done=!0)}}class PDFDataTransportStreamRangeReader{constructor(t,e,i){this._stream=t;this._begin=e;this._end=i;this._queuedChunk=null;this._requests=[];this._done=!1;this.onProgress=null}_enqueue(t){if(!this._done){if(0===this._requests.length)this._queuedChunk=t;else{this._requests.shift().resolve({value:t,done:!1});for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0}this._done=!0;this._stream._removeRangeReader(this)}}get isStreamingSupported(){return!1}async read(){if(this._queuedChunk){const t=this._queuedChunk;this._queuedChunk=null;return{value:t,done:!1}}if(this._done)return{value:void 0,done:!0};const t=new s.PromiseCapability;this._requests.push(t);return t.promise}cancel(t){this._done=!0;for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0;this._stream._removeRangeReader(this)}}},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.PDFFetchStream=void 0;var s=i(1),n=i(20);function createFetchOptions(t,e,i){return{method:"GET",headers:t,signal:i.signal,mode:"cors",credentials:e?"include":"same-origin",redirect:"follow"}}function createHeaders(t){const e=new Headers;for(const i in t){const s=t[i];void 0!==s&&e.append(i,s)}return e}function getArrayBuffer(t){if(t instanceof Uint8Array)return t.buffer;if(t instanceof ArrayBuffer)return t;(0,s.warn)(`getArrayBuffer - unexpected data format: ${t}`);return new Uint8Array(t).buffer}e.PDFFetchStream=class PDFFetchStream{constructor(t){this.source=t;this.isHttp=/^https?:/i.test(t.url);this.httpHeaders=this.isHttp&&t.httpHeaders||{};this._fullRequestReader=null;this._rangeRequestReaders=[]}get _progressiveDataLength(){return this._fullRequestReader?._loaded??0}getFullReader(){(0,s.assert)(!this._fullRequestReader,"PDFFetchStream.getFullReader can only be called once.");this._fullRequestReader=new PDFFetchStreamReader(this);return this._fullRequestReader}getRangeReader(t,e){if(e<=this._progressiveDataLength)return null;const i=new PDFFetchStreamRangeReader(this,t,e);this._rangeRequestReaders.push(i);return i}cancelAllRequests(t){this._fullRequestReader?.cancel(t);for(const e of this._rangeRequestReaders.slice(0))e.cancel(t)}};class PDFFetchStreamReader{constructor(t){this._stream=t;this._reader=null;this._loaded=0;this._filename=null;const e=t.source;this._withCredentials=e.withCredentials||!1;this._contentLength=e.length;this._headersCapability=new s.PromiseCapability;this._disableRange=e.disableRange||!1;this._rangeChunkSize=e.rangeChunkSize;this._rangeChunkSize||this._disableRange||(this._disableRange=!0);this._abortController=new AbortController;this._isStreamingSupported=!e.disableStream;this._isRangeSupported=!e.disableRange;this._headers=createHeaders(this._stream.httpHeaders);const i=e.url;fetch(i,createFetchOptions(this._headers,this._withCredentials,this._abortController)).then((t=>{if(!(0,n.validateResponseStatus)(t.status))throw(0,n.createResponseStatusError)(t.status,i);this._reader=t.body.getReader();this._headersCapability.resolve();const getResponseHeader=e=>t.headers.get(e),{allowRangeRequests:e,suggestedLength:a}=(0,n.validateRangeRequestCapabilities)({getResponseHeader:getResponseHeader,isHttp:this._stream.isHttp,rangeChunkSize:this._rangeChunkSize,disableRange:this._disableRange});this._isRangeSupported=e;this._contentLength=a||this._contentLength;this._filename=(0,n.extractFilenameFromHeader)(getResponseHeader);!this._isStreamingSupported&&this._isRangeSupported&&this.cancel(new s.AbortException("Streaming is disabled."))})).catch(this._headersCapability.reject);this.onProgress=null}get headersReady(){return this._headersCapability.promise}get filename(){return this._filename}get contentLength(){return this._contentLength}get isRangeSupported(){return this._isRangeSupported}get isStreamingSupported(){return this._isStreamingSupported}async read(){await this._headersCapability.promise;const{value:t,done:e}=await this._reader.read();if(e)return{value:t,done:e};this._loaded+=t.byteLength;this.onProgress?.({loaded:this._loaded,total:this._contentLength});return{value:getArrayBuffer(t),done:!1}}cancel(t){this._reader?.cancel(t);this._abortController.abort()}}class PDFFetchStreamRangeReader{constructor(t,e,i){this._stream=t;this._reader=null;this._loaded=0;const a=t.source;this._withCredentials=a.withCredentials||!1;this._readCapability=new s.PromiseCapability;this._isStreamingSupported=!a.disableStream;this._abortController=new AbortController;this._headers=createHeaders(this._stream.httpHeaders);this._headers.append("Range",`bytes=${e}-${i-1}`);const r=a.url;fetch(r,createFetchOptions(this._headers,this._withCredentials,this._abortController)).then((t=>{if(!(0,n.validateResponseStatus)(t.status))throw(0,n.createResponseStatusError)(t.status,r);this._readCapability.resolve();this._reader=t.body.getReader()})).catch(this._readCapability.reject);this.onProgress=null}get isStreamingSupported(){return this._isStreamingSupported}async read(){await this._readCapability.promise;const{value:t,done:e}=await this._reader.read();if(e)return{value:t,done:e};this._loaded+=t.byteLength;this.onProgress?.({loaded:this._loaded});return{value:getArrayBuffer(t),done:!1}}cancel(t){this._reader?.cancel(t);this._abortController.abort()}}},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.createResponseStatusError=function createResponseStatusError(t,e){if(404===t||0===t&&e.startsWith("file:"))return new s.MissingPDFException('Missing PDF "'+e+'".');return new s.UnexpectedResponseException(`Unexpected server response (${t}) while retrieving PDF "${e}".`,t)};e.extractFilenameFromHeader=function extractFilenameFromHeader(t){const e=t("Content-Disposition");if(e){let t=(0,n.getFilenameFromContentDispositionHeader)(e);if(t.includes("%"))try{t=decodeURIComponent(t)}catch{}if((0,a.isPdfFile)(t))return t}return null};e.validateRangeRequestCapabilities=function validateRangeRequestCapabilities({getResponseHeader:t,isHttp:e,rangeChunkSize:i,disableRange:s}){const n={allowRangeRequests:!1,suggestedLength:void 0},a=parseInt(t("Content-Length"),10);if(!Number.isInteger(a))return n;n.suggestedLength=a;if(a<=2*i)return n;if(s||!e)return n;if("bytes"!==t("Accept-Ranges"))return n;if("identity"!==(t("Content-Encoding")||"identity"))return n;n.allowRangeRequests=!0;return n};e.validateResponseStatus=function validateResponseStatus(t){return 200===t||206===t};var s=i(1),n=i(21),a=i(6)},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.getFilenameFromContentDispositionHeader=function getFilenameFromContentDispositionHeader(t){let e=!0,i=toParamRegExp("filename\\*","i").exec(t);if(i){i=i[1];let t=rfc2616unquote(i);t=unescape(t);t=rfc5987decode(t);t=rfc2047decode(t);return fixupEncoding(t)}i=function rfc2231getparam(t){const e=[];let i;const s=toParamRegExp("filename\\*((?!0\\d)\\d+)(\\*?)","ig");for(;null!==(i=s.exec(t));){let[,t,s,n]=i;t=parseInt(t,10);if(t in e){if(0===t)break}else e[t]=[s,n]}const n=[];for(let t=0;t{Object.defineProperty(e,"__esModule",{value:!0});e.PDFNetworkStream=void 0;var s=i(1),n=i(20);class NetworkManager{constructor(t,e={}){this.url=t;this.isHttp=/^https?:/i.test(t);this.httpHeaders=this.isHttp&&e.httpHeaders||Object.create(null);this.withCredentials=e.withCredentials||!1;this.currXhrId=0;this.pendingRequests=Object.create(null)}requestRange(t,e,i){const s={begin:t,end:e};for(const t in i)s[t]=i[t];return this.request(s)}requestFull(t){return this.request(t)}request(t){const e=new XMLHttpRequest,i=this.currXhrId++,s=this.pendingRequests[i]={xhr:e};e.open("GET",this.url);e.withCredentials=this.withCredentials;for(const t in this.httpHeaders){const i=this.httpHeaders[t];void 0!==i&&e.setRequestHeader(t,i)}if(this.isHttp&&"begin"in t&&"end"in t){e.setRequestHeader("Range",`bytes=${t.begin}-${t.end-1}`);s.expectedStatus=206}else s.expectedStatus=200;e.responseType="arraybuffer";t.onError&&(e.onerror=function(i){t.onError(e.status)});e.onreadystatechange=this.onStateChange.bind(this,i);e.onprogress=this.onProgress.bind(this,i);s.onHeadersReceived=t.onHeadersReceived;s.onDone=t.onDone;s.onError=t.onError;s.onProgress=t.onProgress;e.send(null);return i}onProgress(t,e){const i=this.pendingRequests[t];i&&i.onProgress?.(e)}onStateChange(t,e){const i=this.pendingRequests[t];if(!i)return;const n=i.xhr;if(n.readyState>=2&&i.onHeadersReceived){i.onHeadersReceived();delete i.onHeadersReceived}if(4!==n.readyState)return;if(!(t in this.pendingRequests))return;delete this.pendingRequests[t];if(0===n.status&&this.isHttp){i.onError?.(n.status);return}const a=n.status||200;if(!(200===a&&206===i.expectedStatus)&&a!==i.expectedStatus){i.onError?.(n.status);return}const r=function getArrayBuffer(t){const e=t.response;return"string"!=typeof e?e:(0,s.stringToBytes)(e).buffer}(n);if(206===a){const t=n.getResponseHeader("Content-Range"),e=/bytes (\d+)-(\d+)\/(\d+)/.exec(t);i.onDone({begin:parseInt(e[1],10),chunk:r})}else r?i.onDone({begin:0,chunk:r}):i.onError?.(n.status)}getRequestXhr(t){return this.pendingRequests[t].xhr}isPendingRequest(t){return t in this.pendingRequests}abortRequest(t){const e=this.pendingRequests[t].xhr;delete this.pendingRequests[t];e.abort()}}e.PDFNetworkStream=class PDFNetworkStream{constructor(t){this._source=t;this._manager=new NetworkManager(t.url,{httpHeaders:t.httpHeaders,withCredentials:t.withCredentials});this._rangeChunkSize=t.rangeChunkSize;this._fullRequestReader=null;this._rangeRequestReaders=[]}_onRangeRequestReaderClosed(t){const e=this._rangeRequestReaders.indexOf(t);e>=0&&this._rangeRequestReaders.splice(e,1)}getFullReader(){(0,s.assert)(!this._fullRequestReader,"PDFNetworkStream.getFullReader can only be called once.");this._fullRequestReader=new PDFNetworkStreamFullRequestReader(this._manager,this._source);return this._fullRequestReader}getRangeReader(t,e){const i=new PDFNetworkStreamRangeRequestReader(this._manager,t,e);i.onClosed=this._onRangeRequestReaderClosed.bind(this);this._rangeRequestReaders.push(i);return i}cancelAllRequests(t){this._fullRequestReader?.cancel(t);for(const e of this._rangeRequestReaders.slice(0))e.cancel(t)}};class PDFNetworkStreamFullRequestReader{constructor(t,e){this._manager=t;const i={onHeadersReceived:this._onHeadersReceived.bind(this),onDone:this._onDone.bind(this),onError:this._onError.bind(this),onProgress:this._onProgress.bind(this)};this._url=e.url;this._fullRequestId=t.requestFull(i);this._headersReceivedCapability=new s.PromiseCapability;this._disableRange=e.disableRange||!1;this._contentLength=e.length;this._rangeChunkSize=e.rangeChunkSize;this._rangeChunkSize||this._disableRange||(this._disableRange=!0);this._isStreamingSupported=!1;this._isRangeSupported=!1;this._cachedChunks=[];this._requests=[];this._done=!1;this._storedError=void 0;this._filename=null;this.onProgress=null}_onHeadersReceived(){const t=this._fullRequestId,e=this._manager.getRequestXhr(t),getResponseHeader=t=>e.getResponseHeader(t),{allowRangeRequests:i,suggestedLength:s}=(0,n.validateRangeRequestCapabilities)({getResponseHeader:getResponseHeader,isHttp:this._manager.isHttp,rangeChunkSize:this._rangeChunkSize,disableRange:this._disableRange});i&&(this._isRangeSupported=!0);this._contentLength=s||this._contentLength;this._filename=(0,n.extractFilenameFromHeader)(getResponseHeader);this._isRangeSupported&&this._manager.abortRequest(t);this._headersReceivedCapability.resolve()}_onDone(t){if(t)if(this._requests.length>0){this._requests.shift().resolve({value:t.chunk,done:!1})}else this._cachedChunks.push(t.chunk);this._done=!0;if(!(this._cachedChunks.length>0)){for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0}}_onError(t){this._storedError=(0,n.createResponseStatusError)(t,this._url);this._headersReceivedCapability.reject(this._storedError);for(const t of this._requests)t.reject(this._storedError);this._requests.length=0;this._cachedChunks.length=0}_onProgress(t){this.onProgress?.({loaded:t.loaded,total:t.lengthComputable?t.total:this._contentLength})}get filename(){return this._filename}get isRangeSupported(){return this._isRangeSupported}get isStreamingSupported(){return this._isStreamingSupported}get contentLength(){return this._contentLength}get headersReady(){return this._headersReceivedCapability.promise}async read(){if(this._storedError)throw this._storedError;if(this._cachedChunks.length>0){return{value:this._cachedChunks.shift(),done:!1}}if(this._done)return{value:void 0,done:!0};const t=new s.PromiseCapability;this._requests.push(t);return t.promise}cancel(t){this._done=!0;this._headersReceivedCapability.reject(t);for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0;this._manager.isPendingRequest(this._fullRequestId)&&this._manager.abortRequest(this._fullRequestId);this._fullRequestReader=null}}class PDFNetworkStreamRangeRequestReader{constructor(t,e,i){this._manager=t;const s={onDone:this._onDone.bind(this),onError:this._onError.bind(this),onProgress:this._onProgress.bind(this)};this._url=t.url;this._requestId=t.requestRange(e,i,s);this._requests=[];this._queuedChunk=null;this._done=!1;this._storedError=void 0;this.onProgress=null;this.onClosed=null}_close(){this.onClosed?.(this)}_onDone(t){const e=t.chunk;if(this._requests.length>0){this._requests.shift().resolve({value:e,done:!1})}else this._queuedChunk=e;this._done=!0;for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0;this._close()}_onError(t){this._storedError=(0,n.createResponseStatusError)(t,this._url);for(const t of this._requests)t.reject(this._storedError);this._requests.length=0;this._queuedChunk=null}_onProgress(t){this.isStreamingSupported||this.onProgress?.({loaded:t.loaded})}get isStreamingSupported(){return!1}async read(){if(this._storedError)throw this._storedError;if(null!==this._queuedChunk){const t=this._queuedChunk;this._queuedChunk=null;return{value:t,done:!1}}if(this._done)return{value:void 0,done:!0};const t=new s.PromiseCapability;this._requests.push(t);return t.promise}cancel(t){this._done=!0;for(const t of this._requests)t.resolve({value:void 0,done:!0});this._requests.length=0;this._manager.isPendingRequest(this._requestId)&&this._manager.abortRequest(this._requestId);this._close()}}},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.PDFNodeStream=void 0;var s=i(1),n=i(20);const a=/^file:\/\/\/[a-zA-Z]:\//;e.PDFNodeStream=class PDFNodeStream{constructor(t){this.source=t;this.url=function parseUrl(t){const e=require("url"),i=e.parse(t);if("file:"===i.protocol||i.host)return i;if(/^[a-z]:[/\\]/i.test(t))return e.parse(`file:///${t}`);i.host||(i.protocol="file:");return i}(t.url);this.isHttp="http:"===this.url.protocol||"https:"===this.url.protocol;this.isFsUrl="file:"===this.url.protocol;this.httpHeaders=this.isHttp&&t.httpHeaders||{};this._fullRequestReader=null;this._rangeRequestReaders=[]}get _progressiveDataLength(){return this._fullRequestReader?._loaded??0}getFullReader(){(0,s.assert)(!this._fullRequestReader,"PDFNodeStream.getFullReader can only be called once.");this._fullRequestReader=this.isFsUrl?new PDFNodeStreamFsFullReader(this):new PDFNodeStreamFullReader(this);return this._fullRequestReader}getRangeReader(t,e){if(e<=this._progressiveDataLength)return null;const i=this.isFsUrl?new PDFNodeStreamFsRangeReader(this,t,e):new PDFNodeStreamRangeReader(this,t,e);this._rangeRequestReaders.push(i);return i}cancelAllRequests(t){this._fullRequestReader?.cancel(t);for(const e of this._rangeRequestReaders.slice(0))e.cancel(t)}};class BaseFullReader{constructor(t){this._url=t.url;this._done=!1;this._storedError=null;this.onProgress=null;const e=t.source;this._contentLength=e.length;this._loaded=0;this._filename=null;this._disableRange=e.disableRange||!1;this._rangeChunkSize=e.rangeChunkSize;this._rangeChunkSize||this._disableRange||(this._disableRange=!0);this._isStreamingSupported=!e.disableStream;this._isRangeSupported=!e.disableRange;this._readableStream=null;this._readCapability=new s.PromiseCapability;this._headersCapability=new s.PromiseCapability}get headersReady(){return this._headersCapability.promise}get filename(){return this._filename}get contentLength(){return this._contentLength}get isRangeSupported(){return this._isRangeSupported}get isStreamingSupported(){return this._isStreamingSupported}async read(){await this._readCapability.promise;if(this._done)return{value:void 0,done:!0};if(this._storedError)throw this._storedError;const t=this._readableStream.read();if(null===t){this._readCapability=new s.PromiseCapability;return this.read()}this._loaded+=t.length;this.onProgress?.({loaded:this._loaded,total:this._contentLength});return{value:new Uint8Array(t).buffer,done:!1}}cancel(t){this._readableStream?this._readableStream.destroy(t):this._error(t)}_error(t){this._storedError=t;this._readCapability.resolve()}_setReadableStream(t){this._readableStream=t;t.on("readable",(()=>{this._readCapability.resolve()}));t.on("end",(()=>{t.destroy();this._done=!0;this._readCapability.resolve()}));t.on("error",(t=>{this._error(t)}));!this._isStreamingSupported&&this._isRangeSupported&&this._error(new s.AbortException("streaming is disabled"));this._storedError&&this._readableStream.destroy(this._storedError)}}class BaseRangeReader{constructor(t){this._url=t.url;this._done=!1;this._storedError=null;this.onProgress=null;this._loaded=0;this._readableStream=null;this._readCapability=new s.PromiseCapability;const e=t.source;this._isStreamingSupported=!e.disableStream}get isStreamingSupported(){return this._isStreamingSupported}async read(){await this._readCapability.promise;if(this._done)return{value:void 0,done:!0};if(this._storedError)throw this._storedError;const t=this._readableStream.read();if(null===t){this._readCapability=new s.PromiseCapability;return this.read()}this._loaded+=t.length;this.onProgress?.({loaded:this._loaded});return{value:new Uint8Array(t).buffer,done:!1}}cancel(t){this._readableStream?this._readableStream.destroy(t):this._error(t)}_error(t){this._storedError=t;this._readCapability.resolve()}_setReadableStream(t){this._readableStream=t;t.on("readable",(()=>{this._readCapability.resolve()}));t.on("end",(()=>{t.destroy();this._done=!0;this._readCapability.resolve()}));t.on("error",(t=>{this._error(t)}));this._storedError&&this._readableStream.destroy(this._storedError)}}function createRequestOptions(t,e){return{protocol:t.protocol,auth:t.auth,host:t.hostname,port:t.port,path:t.path,method:"GET",headers:e}}class PDFNodeStreamFullReader extends BaseFullReader{constructor(t){super(t);const handleResponse=e=>{if(404===e.statusCode){const t=new s.MissingPDFException(`Missing PDF "${this._url}".`);this._storedError=t;this._headersCapability.reject(t);return}this._headersCapability.resolve();this._setReadableStream(e);const getResponseHeader=t=>this._readableStream.headers[t.toLowerCase()],{allowRangeRequests:i,suggestedLength:a}=(0,n.validateRangeRequestCapabilities)({getResponseHeader:getResponseHeader,isHttp:t.isHttp,rangeChunkSize:this._rangeChunkSize,disableRange:this._disableRange});this._isRangeSupported=i;this._contentLength=a||this._contentLength;this._filename=(0,n.extractFilenameFromHeader)(getResponseHeader)};this._request=null;if("http:"===this._url.protocol){const e=require("http");this._request=e.request(createRequestOptions(this._url,t.httpHeaders),handleResponse)}else{const e=require("https");this._request=e.request(createRequestOptions(this._url,t.httpHeaders),handleResponse)}this._request.on("error",(t=>{this._storedError=t;this._headersCapability.reject(t)}));this._request.end()}}class PDFNodeStreamRangeReader extends BaseRangeReader{constructor(t,e,i){super(t);this._httpHeaders={};for(const e in t.httpHeaders){const i=t.httpHeaders[e];void 0!==i&&(this._httpHeaders[e]=i)}this._httpHeaders.Range=`bytes=${e}-${i-1}`;const handleResponse=t=>{if(404!==t.statusCode)this._setReadableStream(t);else{const t=new s.MissingPDFException(`Missing PDF "${this._url}".`);this._storedError=t}};this._request=null;if("http:"===this._url.protocol){const t=require("http");this._request=t.request(createRequestOptions(this._url,this._httpHeaders),handleResponse)}else{const t=require("https");this._request=t.request(createRequestOptions(this._url,this._httpHeaders),handleResponse)}this._request.on("error",(t=>{this._storedError=t}));this._request.end()}}class PDFNodeStreamFsFullReader extends BaseFullReader{constructor(t){super(t);let e=decodeURIComponent(this._url.path);a.test(this._url.href)&&(e=e.replace(/^\//,""));const i=require("fs");i.lstat(e,((t,n)=>{if(t){"ENOENT"===t.code&&(t=new s.MissingPDFException(`Missing PDF "${e}".`));this._storedError=t;this._headersCapability.reject(t)}else{this._contentLength=n.size;this._setReadableStream(i.createReadStream(e));this._headersCapability.resolve()}}))}}class PDFNodeStreamFsRangeReader extends BaseRangeReader{constructor(t,e,i){super(t);let s=decodeURIComponent(this._url.path);a.test(this._url.href)&&(s=s.replace(/^\//,""));const n=require("fs");this._setReadableStream(n.createReadStream(s,{start:e,end:i-1}))}}},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.SVGGraphics=void 0;var s=i(6),n=i(1);const a="normal",r="normal",o="#000000",l=["butt","round","square"],h=["miter","round","bevel"],createObjectURL=function(t,e="",i=!1){if(URL.createObjectURL&&"undefined"!=typeof Blob&&!i)return URL.createObjectURL(new Blob([t],{type:e}));const s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";let n=`data:${e};base64,`;for(let e=0,i=t.length;e>2]+s[(3&a)<<4|r>>4]+s[e+1>6:64]+s[e+2>1&2147483647:i>>1&2147483647;e[t]=i}function writePngChunk(t,i,s,n){let a=n;const r=i.length;s[a]=r>>24&255;s[a+1]=r>>16&255;s[a+2]=r>>8&255;s[a+3]=255&r;a+=4;s[a]=255&t.charCodeAt(0);s[a+1]=255&t.charCodeAt(1);s[a+2]=255&t.charCodeAt(2);s[a+3]=255&t.charCodeAt(3);a+=4;s.set(i,a);a+=i.length;const o=function crc32(t,i,s){let n=-1;for(let a=i;a>>8^e[i]}return-1^n}(s,n+4,a);s[a]=o>>24&255;s[a+1]=o>>16&255;s[a+2]=o>>8&255;s[a+3]=255&o}function deflateSyncUncompressed(t){let e=t.length;const i=65535,s=Math.ceil(e/i),n=new Uint8Array(2+e+5*s+4);let a=0;n[a++]=120;n[a++]=156;let r=0;for(;e>i;){n[a++]=0;n[a++]=255;n[a++]=255;n[a++]=0;n[a++]=0;n.set(t.subarray(r,r+i),a);a+=i;r+=i;e-=i}n[a++]=1;n[a++]=255&e;n[a++]=e>>8&255;n[a++]=255&~e;n[a++]=(65535&~e)>>8&255;n.set(t.subarray(r),a);a+=t.length-r;const o=function adler32(t,e,i){let s=1,n=0;for(let a=e;a>24&255;n[a++]=o>>16&255;n[a++]=o>>8&255;n[a++]=255&o;return n}function encode(e,i,s,a){const r=e.width,o=e.height;let l,h,c;const d=e.data;switch(i){case n.ImageKind.GRAYSCALE_1BPP:h=0;l=1;c=r+7>>3;break;case n.ImageKind.RGB_24BPP:h=2;l=8;c=3*r;break;case n.ImageKind.RGBA_32BPP:h=6;l=8;c=4*r;break;default:throw new Error("invalid format")}const u=new Uint8Array((1+c)*o);let p=0,g=0;for(let t=0;t>24&255,r>>16&255,r>>8&255,255&r,o>>24&255,o>>16&255,o>>8&255,255&o,l,h,0,0,0]),f=function deflateSync(t){if(!n.isNodeJS)return deflateSyncUncompressed(t);try{const e=parseInt(process.versions.node)>=8?t:Buffer.from(t),i=require("zlib").deflateSync(e,{level:9});return i instanceof Uint8Array?i:new Uint8Array(i)}catch(t){(0,n.warn)("Not compressing PNG because zlib.deflateSync is unavailable: "+t)}return deflateSyncUncompressed(t)}(u),b=t.length+36+m.length+f.length,A=new Uint8Array(b);let _=0;A.set(t,_);_+=t.length;writePngChunk("IHDR",m,A,_);_+=12+m.length;writePngChunk("IDATA",f,A,_);_+=12+f.length;writePngChunk("IEND",new Uint8Array(0),A,_);return createObjectURL(A,"image/png",s)}return function convertImgDataToPng(t,e,i){return encode(t,void 0===t.kind?n.ImageKind.GRAYSCALE_1BPP:t.kind,e,i)}}();class SVGExtraState{constructor(){this.fontSizeScale=1;this.fontWeight=r;this.fontSize=0;this.textMatrix=n.IDENTITY_MATRIX;this.fontMatrix=n.FONT_IDENTITY_MATRIX;this.leading=0;this.textRenderingMode=n.TextRenderingMode.FILL;this.textMatrixScale=1;this.x=0;this.y=0;this.lineX=0;this.lineY=0;this.charSpacing=0;this.wordSpacing=0;this.textHScale=1;this.textRise=0;this.fillColor=o;this.strokeColor="#000000";this.fillAlpha=1;this.strokeAlpha=1;this.lineWidth=1;this.lineJoin="";this.lineCap="";this.miterLimit=0;this.dashArray=[];this.dashPhase=0;this.dependencies=[];this.activeClipUrl=null;this.clipGroup=null;this.maskId=""}clone(){return Object.create(this)}setCurrentPoint(t,e){this.x=t;this.y=e}}function pf(t){if(Number.isInteger(t))return t.toString();const e=t.toFixed(10);let i=e.length-1;if("0"!==e[i])return e;do{i--}while("0"===e[i]);return e.substring(0,"."===e[i]?i:i+1)}function pm(t){if(0===t[4]&&0===t[5]){if(0===t[1]&&0===t[2])return 1===t[0]&&1===t[3]?"":`scale(${pf(t[0])} ${pf(t[3])})`;if(t[0]===t[3]&&t[1]===-t[2]){return`rotate(${pf(180*Math.acos(t[0])/Math.PI)})`}}else if(1===t[0]&&0===t[1]&&0===t[2]&&1===t[3])return`translate(${pf(t[4])} ${pf(t[5])})`;return`matrix(${pf(t[0])} ${pf(t[1])} ${pf(t[2])} ${pf(t[3])} ${pf(t[4])} ${pf(t[5])})`}let d=0,u=0,p=0;e.SVGGraphics=class SVGGraphics{constructor(t,e,i=!1){(0,s.deprecated)("The SVG back-end is no longer maintained and *may* be removed in the future.");this.svgFactory=new s.DOMSVGFactory;this.current=new SVGExtraState;this.transformMatrix=n.IDENTITY_MATRIX;this.transformStack=[];this.extraStack=[];this.commonObjs=t;this.objs=e;this.pendingClip=null;this.pendingEOFill=!1;this.embedFonts=!1;this.embeddedFonts=Object.create(null);this.cssStyle=null;this.forceDataSchema=!!i;this._operatorIdMapping=[];for(const t in n.OPS)this._operatorIdMapping[n.OPS[t]]=t}getObject(t,e=null){return"string"==typeof t?t.startsWith("g_")?this.commonObjs.get(t):this.objs.get(t):e}save(){this.transformStack.push(this.transformMatrix);const t=this.current;this.extraStack.push(t);this.current=t.clone()}restore(){this.transformMatrix=this.transformStack.pop();this.current=this.extraStack.pop();this.pendingClip=null;this.tgrp=null}group(t){this.save();this.executeOpTree(t);this.restore()}loadDependencies(t){const e=t.fnArray,i=t.argsArray;for(let t=0,s=e.length;t{t.get(e,i)}));this.current.dependencies.push(i)}return Promise.all(this.current.dependencies)}transform(t,e,i,s,a,r){const o=[t,e,i,s,a,r];this.transformMatrix=n.Util.transform(this.transformMatrix,o);this.tgrp=null}getSVG(t,e){this.viewport=e;const i=this._initialize(e);return this.loadDependencies(t).then((()=>{this.transformMatrix=n.IDENTITY_MATRIX;this.executeOpTree(this.convertOpList(t));return i}))}convertOpList(t){const e=this._operatorIdMapping,i=t.argsArray,s=t.fnArray,n=[];for(let t=0,a=s.length;t0&&(this.current.lineWidth=t)}setLineCap(t){this.current.lineCap=l[t]}setLineJoin(t){this.current.lineJoin=h[t]}setMiterLimit(t){this.current.miterLimit=t}setStrokeAlpha(t){this.current.strokeAlpha=t}setStrokeRGBColor(t,e,i){this.current.strokeColor=n.Util.makeHexColor(t,e,i)}setFillAlpha(t){this.current.fillAlpha=t}setFillRGBColor(t,e,i){this.current.fillColor=n.Util.makeHexColor(t,e,i);this.current.tspan=this.svgFactory.createElement("svg:tspan");this.current.xcoords=[];this.current.ycoords=[]}setStrokeColorN(t){this.current.strokeColor=this._makeColorN_Pattern(t)}setFillColorN(t){this.current.fillColor=this._makeColorN_Pattern(t)}shadingFill(t){const{width:e,height:i}=this.viewport,s=n.Util.inverseTransform(this.transformMatrix),[a,r,o,l]=n.Util.getAxialAlignedBoundingBox([0,0,e,i],s),h=this.svgFactory.createElement("svg:rect");h.setAttributeNS(null,"x",a);h.setAttributeNS(null,"y",r);h.setAttributeNS(null,"width",o-a);h.setAttributeNS(null,"height",l-r);h.setAttributeNS(null,"fill",this._makeShadingPattern(t));this.current.fillAlpha<1&&h.setAttributeNS(null,"fill-opacity",this.current.fillAlpha);this._ensureTransformGroup().append(h)}_makeColorN_Pattern(t){return"TilingPattern"===t[0]?this._makeTilingPattern(t):this._makeShadingPattern(t)}_makeTilingPattern(t){const e=t[1],i=t[2],s=t[3]||n.IDENTITY_MATRIX,[a,r,o,l]=t[4],h=t[5],c=t[6],d=t[7],u="shading"+p++,[g,m,f,b]=n.Util.normalizeRect([...n.Util.applyTransform([a,r],s),...n.Util.applyTransform([o,l],s)]),[A,_]=n.Util.singularValueDecompose2dScale(s),v=h*A,y=c*_,S=this.svgFactory.createElement("svg:pattern");S.setAttributeNS(null,"id",u);S.setAttributeNS(null,"patternUnits","userSpaceOnUse");S.setAttributeNS(null,"width",v);S.setAttributeNS(null,"height",y);S.setAttributeNS(null,"x",`${g}`);S.setAttributeNS(null,"y",`${m}`);const E=this.svg,x=this.transformMatrix,w=this.current.fillColor,C=this.current.strokeColor,T=this.svgFactory.create(f-g,b-m);this.svg=T;this.transformMatrix=s;if(2===d){const t=n.Util.makeHexColor(...e);this.current.fillColor=t;this.current.strokeColor=t}this.executeOpTree(this.convertOpList(i));this.svg=E;this.transformMatrix=x;this.current.fillColor=w;this.current.strokeColor=C;S.append(T.childNodes[0]);this.defs.append(S);return`url(#${u})`}_makeShadingPattern(t){"string"==typeof t&&(t=this.objs.get(t));switch(t[0]){case"RadialAxial":const e="shading"+p++,i=t[3];let s;switch(t[1]){case"axial":const i=t[4],n=t[5];s=this.svgFactory.createElement("svg:linearGradient");s.setAttributeNS(null,"id",e);s.setAttributeNS(null,"gradientUnits","userSpaceOnUse");s.setAttributeNS(null,"x1",i[0]);s.setAttributeNS(null,"y1",i[1]);s.setAttributeNS(null,"x2",n[0]);s.setAttributeNS(null,"y2",n[1]);break;case"radial":const a=t[4],r=t[5],o=t[6],l=t[7];s=this.svgFactory.createElement("svg:radialGradient");s.setAttributeNS(null,"id",e);s.setAttributeNS(null,"gradientUnits","userSpaceOnUse");s.setAttributeNS(null,"cx",r[0]);s.setAttributeNS(null,"cy",r[1]);s.setAttributeNS(null,"r",l);s.setAttributeNS(null,"fx",a[0]);s.setAttributeNS(null,"fy",a[1]);s.setAttributeNS(null,"fr",o);break;default:throw new Error(`Unknown RadialAxial type: ${t[1]}`)}for(const t of i){const e=this.svgFactory.createElement("svg:stop");e.setAttributeNS(null,"offset",t[0]);e.setAttributeNS(null,"stop-color",t[1]);s.append(e)}this.defs.append(s);return`url(#${e})`;case"Mesh":(0,n.warn)("Unimplemented pattern Mesh");return null;case"Dummy":return"hotpink";default:throw new Error(`Unknown IR type: ${t[0]}`)}}setDash(t,e){this.current.dashArray=t;this.current.dashPhase=e}constructPath(t,e){const i=this.current;let s=i.x,a=i.y,r=[],o=0;for(const i of t)switch(0|i){case n.OPS.rectangle:s=e[o++];a=e[o++];const t=s+e[o++],i=a+e[o++];r.push("M",pf(s),pf(a),"L",pf(t),pf(a),"L",pf(t),pf(i),"L",pf(s),pf(i),"Z");break;case n.OPS.moveTo:s=e[o++];a=e[o++];r.push("M",pf(s),pf(a));break;case n.OPS.lineTo:s=e[o++];a=e[o++];r.push("L",pf(s),pf(a));break;case n.OPS.curveTo:s=e[o+4];a=e[o+5];r.push("C",pf(e[o]),pf(e[o+1]),pf(e[o+2]),pf(e[o+3]),pf(s),pf(a));o+=6;break;case n.OPS.curveTo2:r.push("C",pf(s),pf(a),pf(e[o]),pf(e[o+1]),pf(e[o+2]),pf(e[o+3]));s=e[o+2];a=e[o+3];o+=4;break;case n.OPS.curveTo3:s=e[o+2];a=e[o+3];r.push("C",pf(e[o]),pf(e[o+1]),pf(s),pf(a),pf(s),pf(a));o+=4;break;case n.OPS.closePath:r.push("Z")}r=r.join(" ");if(i.path&&t.length>0&&t[0]!==n.OPS.rectangle&&t[0]!==n.OPS.moveTo)r=i.path.getAttributeNS(null,"d")+r;else{i.path=this.svgFactory.createElement("svg:path");this._ensureTransformGroup().append(i.path)}i.path.setAttributeNS(null,"d",r);i.path.setAttributeNS(null,"fill","none");i.element=i.path;i.setCurrentPoint(s,a)}endPath(){const t=this.current;t.path=null;if(!this.pendingClip)return;if(!t.element){this.pendingClip=null;return}const e="clippath"+d++,i=this.svgFactory.createElement("svg:clipPath");i.setAttributeNS(null,"id",e);i.setAttributeNS(null,"transform",pm(this.transformMatrix));const s=t.element.cloneNode(!0);"evenodd"===this.pendingClip?s.setAttributeNS(null,"clip-rule","evenodd"):s.setAttributeNS(null,"clip-rule","nonzero");this.pendingClip=null;i.append(s);this.defs.append(i);if(t.activeClipUrl){t.clipGroup=null;for(const t of this.extraStack)t.clipGroup=null;i.setAttributeNS(null,"clip-path",t.activeClipUrl)}t.activeClipUrl=`url(#${e})`;this.tgrp=null}clip(t){this.pendingClip=t}closePath(){const t=this.current;if(t.path){const e=`${t.path.getAttributeNS(null,"d")}Z`;t.path.setAttributeNS(null,"d",e)}}setLeading(t){this.current.leading=-t}setTextRise(t){this.current.textRise=t}setTextRenderingMode(t){this.current.textRenderingMode=t}setHScale(t){this.current.textHScale=t/100}setRenderingIntent(t){}setFlatness(t){}setGState(t){for(const[e,i]of t)switch(e){case"LW":this.setLineWidth(i);break;case"LC":this.setLineCap(i);break;case"LJ":this.setLineJoin(i);break;case"ML":this.setMiterLimit(i);break;case"D":this.setDash(i[0],i[1]);break;case"RI":this.setRenderingIntent(i);break;case"FL":this.setFlatness(i);break;case"Font":this.setFont(i);break;case"CA":this.setStrokeAlpha(i);break;case"ca":this.setFillAlpha(i);break;default:(0,n.warn)(`Unimplemented graphic state operator ${e}`)}}fill(){const t=this.current;if(t.element){t.element.setAttributeNS(null,"fill",t.fillColor);t.element.setAttributeNS(null,"fill-opacity",t.fillAlpha);this.endPath()}}stroke(){const t=this.current;if(t.element){this._setStrokeAttributes(t.element);t.element.setAttributeNS(null,"fill","none");this.endPath()}}_setStrokeAttributes(t,e=1){const i=this.current;let s=i.dashArray;1!==e&&s.length>0&&(s=s.map((function(t){return e*t})));t.setAttributeNS(null,"stroke",i.strokeColor);t.setAttributeNS(null,"stroke-opacity",i.strokeAlpha);t.setAttributeNS(null,"stroke-miterlimit",pf(i.miterLimit));t.setAttributeNS(null,"stroke-linecap",i.lineCap);t.setAttributeNS(null,"stroke-linejoin",i.lineJoin);t.setAttributeNS(null,"stroke-width",pf(e*i.lineWidth)+"px");t.setAttributeNS(null,"stroke-dasharray",s.map(pf).join(" "));t.setAttributeNS(null,"stroke-dashoffset",pf(e*i.dashPhase)+"px")}eoFill(){this.current.element?.setAttributeNS(null,"fill-rule","evenodd");this.fill()}fillStroke(){this.stroke();this.fill()}eoFillStroke(){this.current.element?.setAttributeNS(null,"fill-rule","evenodd");this.fillStroke()}closeStroke(){this.closePath();this.stroke()}closeFillStroke(){this.closePath();this.fillStroke()}closeEOFillStroke(){this.closePath();this.eoFillStroke()}paintSolidColorImageMask(){const t=this.svgFactory.createElement("svg:rect");t.setAttributeNS(null,"x","0");t.setAttributeNS(null,"y","0");t.setAttributeNS(null,"width","1px");t.setAttributeNS(null,"height","1px");t.setAttributeNS(null,"fill",this.current.fillColor);this._ensureTransformGroup().append(t)}paintImageXObject(t){const e=this.getObject(t);e?this.paintInlineImageXObject(e):(0,n.warn)(`Dependent image with object ID ${t} is not ready yet`)}paintInlineImageXObject(t,e){const i=t.width,s=t.height,n=c(t,this.forceDataSchema,!!e),a=this.svgFactory.createElement("svg:rect");a.setAttributeNS(null,"x","0");a.setAttributeNS(null,"y","0");a.setAttributeNS(null,"width",pf(i));a.setAttributeNS(null,"height",pf(s));this.current.element=a;this.clip("nonzero");const r=this.svgFactory.createElement("svg:image");r.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",n);r.setAttributeNS(null,"x","0");r.setAttributeNS(null,"y",pf(-s));r.setAttributeNS(null,"width",pf(i)+"px");r.setAttributeNS(null,"height",pf(s)+"px");r.setAttributeNS(null,"transform",`scale(${pf(1/i)} ${pf(-1/s)})`);e?e.append(r):this._ensureTransformGroup().append(r)}paintImageMaskXObject(t){const e=this.getObject(t.data,t);if(e.bitmap){(0,n.warn)("paintImageMaskXObject: ImageBitmap support is not implemented, ensure that the `isOffscreenCanvasSupported` API parameter is disabled.");return}const i=this.current,s=e.width,a=e.height,r=i.fillColor;i.maskId="mask"+u++;const o=this.svgFactory.createElement("svg:mask");o.setAttributeNS(null,"id",i.maskId);const l=this.svgFactory.createElement("svg:rect");l.setAttributeNS(null,"x","0");l.setAttributeNS(null,"y","0");l.setAttributeNS(null,"width",pf(s));l.setAttributeNS(null,"height",pf(a));l.setAttributeNS(null,"fill",r);l.setAttributeNS(null,"mask",`url(#${i.maskId})`);this.defs.append(o);this._ensureTransformGroup().append(l);this.paintInlineImageXObject(e,o)}paintFormXObjectBegin(t,e){Array.isArray(t)&&6===t.length&&this.transform(t[0],t[1],t[2],t[3],t[4],t[5]);if(e){const t=e[2]-e[0],i=e[3]-e[1],s=this.svgFactory.createElement("svg:rect");s.setAttributeNS(null,"x",e[0]);s.setAttributeNS(null,"y",e[1]);s.setAttributeNS(null,"width",pf(t));s.setAttributeNS(null,"height",pf(i));this.current.element=s;this.clip("nonzero");this.endPath()}}paintFormXObjectEnd(){}_initialize(t){const e=this.svgFactory.create(t.width,t.height),i=this.svgFactory.createElement("svg:defs");e.append(i);this.defs=i;const s=this.svgFactory.createElement("svg:g");s.setAttributeNS(null,"transform",pm(t.transform));e.append(s);this.svg=s;return e}_ensureClipGroup(){if(!this.current.clipGroup){const t=this.svgFactory.createElement("svg:g");t.setAttributeNS(null,"clip-path",this.current.activeClipUrl);this.svg.append(t);this.current.clipGroup=t}return this.current.clipGroup}_ensureTransformGroup(){if(!this.tgrp){this.tgrp=this.svgFactory.createElement("svg:g");this.tgrp.setAttributeNS(null,"transform",pm(this.transformMatrix));this.current.activeClipUrl?this._ensureClipGroup().append(this.tgrp):this.svg.append(this.tgrp)}return this.tgrp}}},(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0});e.XfaText=void 0;class XfaText{static textContent(t){const e=[],i={items:e,styles:Object.create(null)};!function walk(t){if(!t)return;let i=null;const s=t.name;if("#text"===s)i=t.value;else{if(!XfaText.shouldBuildText(s))return;t?.attributes?.textContent?i=t.attributes.textContent:t.value&&(i=t.value)}null!==i&&e.push({str:i});if(t.children)for(const e of t.children)walk(e)}(t);return i}static shouldBuildText(t){return!("textarea"===t||"input"===t||"option"===t||"select"===t)}}e.XfaText=XfaText},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.TextLayerRenderTask=void 0;e.renderTextLayer=function renderTextLayer(t){if(!t.textContentSource&&(t.textContent||t.textContentStream)){(0,n.deprecated)("The TextLayerRender `textContent`/`textContentStream` parameters will be removed in the future, please use `textContentSource` instead.");t.textContentSource=t.textContent||t.textContentStream}const{container:e,viewport:i}=t,s=getComputedStyle(e),a=s.getPropertyValue("visibility"),r=parseFloat(s.getPropertyValue("--scale-factor"));"visible"===a&&(!r||Math.abs(r-i.scale)>1e-5)&&console.error("The `--scale-factor` CSS-variable must be set, to the same value as `viewport.scale`, either on the `container`-element itself or higher up in the DOM.");const o=new TextLayerRenderTask(t);o._render();return o};e.updateTextLayer=function updateTextLayer({container:t,viewport:e,textDivs:i,textDivProperties:s,isOffscreenCanvasSupported:a,mustRotate:r=!0,mustRescale:o=!0}){r&&(0,n.setLayerDimensions)(t,{rotation:e.rotation});if(o){const t=getCtx(0,a),n={prevFontSize:null,prevFontFamily:null,div:null,scale:e.scale*(globalThis.devicePixelRatio||1),properties:null,ctx:t};for(const t of i){n.properties=s.get(t);n.div=t;layout(n)}}};var s=i(1),n=i(6);const a=30,r=.8,o=new Map;function getCtx(t,e){let i;if(e&&s.FeatureTest.isOffscreenCanvasSupported)i=new OffscreenCanvas(t,t).getContext("2d",{alpha:!1});else{const e=document.createElement("canvas");e.width=e.height=t;i=e.getContext("2d",{alpha:!1})}return i}function appendText(t,e,i){const n=document.createElement("span"),l={angle:0,canvasWidth:0,hasText:""!==e.str,hasEOL:e.hasEOL,fontSize:0};t._textDivs.push(n);const h=s.Util.transform(t._transform,e.transform);let c=Math.atan2(h[1],h[0]);const d=i[e.fontName];d.vertical&&(c+=Math.PI/2);const u=Math.hypot(h[2],h[3]),p=u*function getAscent(t,e){const i=o.get(t);if(i)return i;const s=getCtx(a,e);s.font=`${a}px ${t}`;const n=s.measureText("");let l=n.fontBoundingBoxAscent,h=Math.abs(n.fontBoundingBoxDescent);if(l){const e=l/(l+h);o.set(t,e);s.canvas.width=s.canvas.height=0;return e}s.strokeStyle="red";s.clearRect(0,0,a,a);s.strokeText("g",0,0);let c=s.getImageData(0,0,a,a).data;h=0;for(let t=c.length-1-3;t>=0;t-=4)if(c[t]>0){h=Math.ceil(t/4/a);break}s.clearRect(0,0,a,a);s.strokeText("A",0,a);c=s.getImageData(0,0,a,a).data;l=0;for(let t=0,e=c.length;t0){l=a-Math.floor(t/4/a);break}s.canvas.width=s.canvas.height=0;if(l){const e=l/(l+h);o.set(t,e);return e}o.set(t,r);return r}(d.fontFamily,t._isOffscreenCanvasSupported);let g,m;if(0===c){g=h[4];m=h[5]-p}else{g=h[4]+p*Math.sin(c);m=h[5]-p*Math.cos(c)}const f="calc(var(--scale-factor)*",b=n.style;if(t._container===t._rootContainer){b.left=`${(100*g/t._pageWidth).toFixed(2)}%`;b.top=`${(100*m/t._pageHeight).toFixed(2)}%`}else{b.left=`${f}${g.toFixed(2)}px)`;b.top=`${f}${m.toFixed(2)}px)`}b.fontSize=`${f}${u.toFixed(2)}px)`;b.fontFamily=d.fontFamily;l.fontSize=u;n.setAttribute("role","presentation");n.textContent=e.str;n.dir=e.dir;t._fontInspectorEnabled&&(n.dataset.fontName=e.fontName);0!==c&&(l.angle=c*(180/Math.PI));let A=!1;if(e.str.length>1)A=!0;else if(" "!==e.str&&e.transform[0]!==e.transform[3]){const t=Math.abs(e.transform[0]),i=Math.abs(e.transform[3]);t!==i&&Math.max(t,i)/Math.min(t,i)>1.5&&(A=!0)}A&&(l.canvasWidth=d.vertical?e.height:e.width);t._textDivProperties.set(n,l);t._isReadableStream&&t._layoutText(n)}function layout(t){const{div:e,scale:i,properties:s,ctx:n,prevFontSize:a,prevFontFamily:r}=t,{style:o}=e;let l="";if(0!==s.canvasWidth&&s.hasText){const{fontFamily:h}=o,{canvasWidth:c,fontSize:d}=s;if(a!==d||r!==h){n.font=`${d*i}px ${h}`;t.prevFontSize=d;t.prevFontFamily=h}const{width:u}=n.measureText(e.textContent);u>0&&(l=`scaleX(${c*i/u})`)}0!==s.angle&&(l=`rotate(${s.angle}deg) ${l}`);l.length>0&&(o.transform=l)}class TextLayerRenderTask{constructor({textContentSource:t,container:e,viewport:i,textDivs:a,textDivProperties:r,textContentItemsStr:o,isOffscreenCanvasSupported:l}){this._textContentSource=t;this._isReadableStream=t instanceof ReadableStream;this._container=this._rootContainer=e;this._textDivs=a||[];this._textContentItemsStr=o||[];this._isOffscreenCanvasSupported=l;this._fontInspectorEnabled=!!globalThis.FontInspector?.enabled;this._reader=null;this._textDivProperties=r||new WeakMap;this._canceled=!1;this._capability=new s.PromiseCapability;this._layoutTextParams={prevFontSize:null,prevFontFamily:null,div:null,scale:i.scale*(globalThis.devicePixelRatio||1),properties:null,ctx:getCtx(0,l)};const{pageWidth:h,pageHeight:c,pageX:d,pageY:u}=i.rawDims;this._transform=[1,0,0,-1,-d,u+c];this._pageWidth=h;this._pageHeight=c;(0,n.setLayerDimensions)(e,i);this._capability.promise.finally((()=>{this._layoutTextParams=null})).catch((()=>{}))}get promise(){return this._capability.promise}cancel(){this._canceled=!0;if(this._reader){this._reader.cancel(new s.AbortException("TextLayer task cancelled.")).catch((()=>{}));this._reader=null}this._capability.reject(new s.AbortException("TextLayer task cancelled."))}_processItems(t,e){for(const i of t)if(void 0!==i.str){this._textContentItemsStr.push(i.str);appendText(this,i,e)}else if("beginMarkedContentProps"===i.type||"beginMarkedContent"===i.type){const t=this._container;this._container=document.createElement("span");this._container.classList.add("markedContent");null!==i.id&&this._container.setAttribute("id",`${i.id}`);t.append(this._container)}else"endMarkedContent"===i.type&&(this._container=this._container.parentNode)}_layoutText(t){const e=this._layoutTextParams.properties=this._textDivProperties.get(t);this._layoutTextParams.div=t;layout(this._layoutTextParams);e.hasText&&this._container.append(t);if(e.hasEOL){const t=document.createElement("br");t.setAttribute("role","presentation");this._container.append(t)}}_render(){const t=new s.PromiseCapability;let e=Object.create(null);if(this._isReadableStream){const pump=()=>{this._reader.read().then((({value:i,done:s})=>{if(s)t.resolve();else{Object.assign(e,i.styles);this._processItems(i.items,e);pump()}}),t.reject)};this._reader=this._textContentSource.getReader();pump()}else{if(!this._textContentSource)throw new Error('No "textContentSource" parameter specified.');{const{items:e,styles:i}=this._textContentSource;this._processItems(e,i);t.resolve()}}t.promise.then((()=>{e=null;!function render(t){if(t._canceled)return;const e=t._textDivs,i=t._capability;if(e.length>1e5)i.resolve();else{if(!t._isReadableStream)for(const i of e)t._layoutText(i);i.resolve()}}(this)}),this._capability.reject)}}e.TextLayerRenderTask=TextLayerRenderTask},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.AnnotationEditorLayer=void 0;var s=i(1),n=i(4),a=i(28),r=i(33),o=i(6),l=i(34);class AnnotationEditorLayer{#Se;#Ee=!1;#xe=null;#we=this.pointerup.bind(this);#Ce=this.pointerdown.bind(this);#Te=new Map;#Pe=!1;#Me=!1;#ke=!1;#Fe;static _initialized=!1;constructor({uiManager:t,pageIndex:e,div:i,accessibilityManager:s,annotationLayer:n,viewport:o,l10n:h}){const c=[a.FreeTextEditor,r.InkEditor,l.StampEditor];if(!AnnotationEditorLayer._initialized){AnnotationEditorLayer._initialized=!0;for(const t of c)t.initialize(h)}t.registerEditorTypes(c);this.#Fe=t;this.pageIndex=e;this.div=i;this.#Se=s;this.#xe=n;this.viewport=o;this.#Fe.addLayer(this)}get isEmpty(){return 0===this.#Te.size}updateToolbar(t){this.#Fe.updateToolbar(t)}updateMode(t=this.#Fe.getMode()){this.#Re();if(t===s.AnnotationEditorType.INK){this.addInkEditorIfNeeded(!1);this.disableClick()}else this.enableClick();if(t!==s.AnnotationEditorType.NONE){this.div.classList.toggle("freeTextEditing",t===s.AnnotationEditorType.FREETEXT);this.div.classList.toggle("inkEditing",t===s.AnnotationEditorType.INK);this.div.classList.toggle("stampEditing",t===s.AnnotationEditorType.STAMP);this.div.hidden=!1}}addInkEditorIfNeeded(t){if(!t&&this.#Fe.getMode()!==s.AnnotationEditorType.INK)return;if(!t)for(const t of this.#Te.values())if(t.isEmpty()){t.setInBackground();return}this.#De({offsetX:0,offsetY:0},!1).setInBackground()}setEditingState(t){this.#Fe.setEditingState(t)}addCommands(t){this.#Fe.addCommands(t)}enable(){this.div.style.pointerEvents="auto";const t=new Set;for(const e of this.#Te.values()){e.enableEditing();e.annotationElementId&&t.add(e.annotationElementId)}if(!this.#xe)return;const e=this.#xe.getEditableAnnotations();for(const i of e){i.hide();if(this.#Fe.isDeletedAnnotationElement(i.data.id))continue;if(t.has(i.data.id))continue;const e=this.deserialize(i);if(e){this.addOrRebuild(e);e.enableEditing()}}}disable(){this.#ke=!0;this.div.style.pointerEvents="none";const t=new Set;for(const e of this.#Te.values()){e.disableEditing();if(e.annotationElementId&&null===e.serialize()){this.getEditableAnnotation(e.annotationElementId)?.show();e.remove()}else t.add(e.annotationElementId)}if(this.#xe){const e=this.#xe.getEditableAnnotations();for(const i of e){const{id:e}=i.data;t.has(e)||this.#Fe.isDeletedAnnotationElement(e)||i.show()}}this.#Re();this.isEmpty&&(this.div.hidden=!0);this.#ke=!1}getEditableAnnotation(t){return this.#xe?.getEditableAnnotation(t)||null}setActiveEditor(t){this.#Fe.getActive()!==t&&this.#Fe.setActiveEditor(t)}enableClick(){this.div.addEventListener("pointerdown",this.#Ce);this.div.addEventListener("pointerup",this.#we)}disableClick(){this.div.removeEventListener("pointerdown",this.#Ce);this.div.removeEventListener("pointerup",this.#we)}attach(t){this.#Te.set(t.id,t);const{annotationElementId:e}=t;e&&this.#Fe.isDeletedAnnotationElement(e)&&this.#Fe.removeDeletedAnnotationElement(t)}detach(t){this.#Te.delete(t.id);this.#Se?.removePointerInTextLayer(t.contentDiv);!this.#ke&&t.annotationElementId&&this.#Fe.addDeletedAnnotationElement(t)}remove(t){this.detach(t);this.#Fe.removeEditor(t);t.div.contains(document.activeElement)&&setTimeout((()=>{this.#Fe.focusMainContainer()}),0);t.div.remove();t.isAttachedToDOM=!1;this.#Me||this.addInkEditorIfNeeded(!1)}changeParent(t){if(t.parent!==this){if(t.annotationElementId){this.#Fe.addDeletedAnnotationElement(t.annotationElementId);n.AnnotationEditor.deleteAnnotationElement(t);t.annotationElementId=null}this.attach(t);t.parent?.detach(t);t.setParent(this);if(t.div&&t.isAttachedToDOM){t.div.remove();this.div.append(t.div)}}}add(t){this.changeParent(t);this.#Fe.addEditor(t);this.attach(t);if(!t.isAttachedToDOM){const e=t.render();this.div.append(e);t.isAttachedToDOM=!0}t.fixAndSetPosition();t.onceAdded();this.#Fe.addToAnnotationStorage(t)}moveEditorInDOM(t){if(!t.isAttachedToDOM)return;const{activeElement:e}=document;if(t.div.contains(e)){t._focusEventsAllowed=!1;setTimeout((()=>{if(t.div.contains(document.activeElement))t._focusEventsAllowed=!0;else{t.div.addEventListener("focusin",(()=>{t._focusEventsAllowed=!0}),{once:!0});e.focus()}}),0)}t._structTreeParentId=this.#Se?.moveElementInDOM(this.div,t.div,t.contentDiv,!0)}addOrRebuild(t){t.needsToBeRebuilt()?t.rebuild():this.add(t)}addUndoableEditor(t){this.addCommands({cmd:()=>t._uiManager.rebuild(t),undo:()=>{t.remove()},mustExec:!1})}getNextId(){return this.#Fe.getId()}#Ie(t){switch(this.#Fe.getMode()){case s.AnnotationEditorType.FREETEXT:return new a.FreeTextEditor(t);case s.AnnotationEditorType.INK:return new r.InkEditor(t);case s.AnnotationEditorType.STAMP:return new l.StampEditor(t)}return null}pasteEditor(t,e){this.#Fe.updateToolbar(t);this.#Fe.updateMode(t);const{offsetX:i,offsetY:s}=this.#Le(),n=this.getNextId(),a=this.#Ie({parent:this,id:n,x:i,y:s,uiManager:this.#Fe,isCentered:!0,...e});a&&this.add(a)}deserialize(t){switch(t.annotationType??t.annotationEditorType){case s.AnnotationEditorType.FREETEXT:return a.FreeTextEditor.deserialize(t,this,this.#Fe);case s.AnnotationEditorType.INK:return r.InkEditor.deserialize(t,this,this.#Fe);case s.AnnotationEditorType.STAMP:return l.StampEditor.deserialize(t,this,this.#Fe)}return null}#De(t,e){const i=this.getNextId(),s=this.#Ie({parent:this,id:i,x:t.offsetX,y:t.offsetY,uiManager:this.#Fe,isCentered:e});s&&this.add(s);return s}#Le(){const{x:t,y:e,width:i,height:s}=this.div.getBoundingClientRect(),n=Math.max(0,t),a=Math.max(0,e),r=(n+Math.min(window.innerWidth,t+i))/2-t,o=(a+Math.min(window.innerHeight,e+s))/2-e,[l,h]=this.viewport.rotation%180==0?[r,o]:[o,r];return{offsetX:l,offsetY:h}}addNewEditor(){this.#De(this.#Le(),!0)}setSelected(t){this.#Fe.setSelected(t)}toggleSelected(t){this.#Fe.toggleSelected(t)}isSelected(t){return this.#Fe.isSelected(t)}unselect(t){this.#Fe.unselect(t)}pointerup(t){const{isMac:e}=s.FeatureTest.platform;if(!(0!==t.button||t.ctrlKey&&e)&&t.target===this.div&&this.#Pe){this.#Pe=!1;this.#Ee?this.#Fe.getMode()!==s.AnnotationEditorType.STAMP?this.#De(t,!1):this.#Fe.unselectAll():this.#Ee=!0}}pointerdown(t){if(this.#Pe){this.#Pe=!1;return}const{isMac:e}=s.FeatureTest.platform;if(0!==t.button||t.ctrlKey&&e)return;if(t.target!==this.div)return;this.#Pe=!0;const i=this.#Fe.getActive();this.#Ee=!i||i.isEmpty()}findNewParent(t,e,i){const s=this.#Fe.findParent(e,i);if(null===s||s===this)return!1;s.changeParent(t);return!0}destroy(){if(this.#Fe.getActive()?.parent===this){this.#Fe.commitOrRemove();this.#Fe.setActiveEditor(null)}for(const t of this.#Te.values()){this.#Se?.removePointerInTextLayer(t.contentDiv);t.setParent(null);t.isAttachedToDOM=!1;t.div.remove()}this.div=null;this.#Te.clear();this.#Fe.removeLayer(this)}#Re(){this.#Me=!0;for(const t of this.#Te.values())t.isEmpty()&&t.remove();this.#Me=!1}render({viewport:t}){this.viewport=t;(0,o.setLayerDimensions)(this.div,t);for(const t of this.#Fe.getEditors(this.pageIndex))this.add(t);this.updateMode()}update({viewport:t}){this.#Fe.commitOrRemove();this.viewport=t;(0,o.setLayerDimensions)(this.div,{rotation:t.rotation});this.updateMode()}get pageDimensions(){const{pageWidth:t,pageHeight:e}=this.viewport.rawDims;return[t,e]}}e.AnnotationEditorLayer=AnnotationEditorLayer},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.FreeTextEditor=void 0;var s=i(1),n=i(5),a=i(4),r=i(29);class FreeTextEditor extends a.AnnotationEditor{#Oe=this.editorDivBlur.bind(this);#Ne=this.editorDivFocus.bind(this);#Be=this.editorDivInput.bind(this);#Ue=this.editorDivKeydown.bind(this);#je;#ze="";#He=`${this.id}-editor`;#We;#Ge=null;static _freeTextDefaultContent="";static _internalPadding=0;static _defaultColor=null;static _defaultFontSize=10;static get _keyboardManager(){const t=FreeTextEditor.prototype,arrowChecker=t=>t.isEmpty(),e=n.AnnotationEditorUIManager.TRANSLATE_SMALL,i=n.AnnotationEditorUIManager.TRANSLATE_BIG;return(0,s.shadow)(this,"_keyboardManager",new n.KeyboardManager([[["ctrl+s","mac+meta+s","ctrl+p","mac+meta+p"],t.commitOrRemove,{bubbles:!0}],[["ctrl+Enter","mac+meta+Enter","Escape","mac+Escape"],t.commitOrRemove],[["ArrowLeft","mac+ArrowLeft"],t._translateEmpty,{args:[-e,0],checker:arrowChecker}],[["ctrl+ArrowLeft","mac+shift+ArrowLeft"],t._translateEmpty,{args:[-i,0],checker:arrowChecker}],[["ArrowRight","mac+ArrowRight"],t._translateEmpty,{args:[e,0],checker:arrowChecker}],[["ctrl+ArrowRight","mac+shift+ArrowRight"],t._translateEmpty,{args:[i,0],checker:arrowChecker}],[["ArrowUp","mac+ArrowUp"],t._translateEmpty,{args:[0,-e],checker:arrowChecker}],[["ctrl+ArrowUp","mac+shift+ArrowUp"],t._translateEmpty,{args:[0,-i],checker:arrowChecker}],[["ArrowDown","mac+ArrowDown"],t._translateEmpty,{args:[0,e],checker:arrowChecker}],[["ctrl+ArrowDown","mac+shift+ArrowDown"],t._translateEmpty,{args:[0,i],checker:arrowChecker}]]))}static _type="freetext";constructor(t){super({...t,name:"freeTextEditor"});this.#je=t.color||FreeTextEditor._defaultColor||a.AnnotationEditor._defaultLineColor;this.#We=t.fontSize||FreeTextEditor._defaultFontSize}static initialize(t){a.AnnotationEditor.initialize(t,{strings:["free_text2_default_content","editor_free_text2_aria_label"]});const e=getComputedStyle(document.documentElement);this._internalPadding=parseFloat(e.getPropertyValue("--freetext-padding"))}static updateDefaultParams(t,e){switch(t){case s.AnnotationEditorParamsType.FREETEXT_SIZE:FreeTextEditor._defaultFontSize=e;break;case s.AnnotationEditorParamsType.FREETEXT_COLOR:FreeTextEditor._defaultColor=e}}updateParams(t,e){switch(t){case s.AnnotationEditorParamsType.FREETEXT_SIZE:this.#qe(e);break;case s.AnnotationEditorParamsType.FREETEXT_COLOR:this.#Ve(e)}}static get defaultPropertiesToUpdate(){return[[s.AnnotationEditorParamsType.FREETEXT_SIZE,FreeTextEditor._defaultFontSize],[s.AnnotationEditorParamsType.FREETEXT_COLOR,FreeTextEditor._defaultColor||a.AnnotationEditor._defaultLineColor]]}get propertiesToUpdate(){return[[s.AnnotationEditorParamsType.FREETEXT_SIZE,this.#We],[s.AnnotationEditorParamsType.FREETEXT_COLOR,this.#je]]}#qe(t){const setFontsize=t=>{this.editorDiv.style.fontSize=`calc(${t}px * var(--scale-factor))`;this.translate(0,-(t-this.#We)*this.parentScale);this.#We=t;this.#$e()},e=this.#We;this.addCommands({cmd:()=>{setFontsize(t)},undo:()=>{setFontsize(e)},mustExec:!0,type:s.AnnotationEditorParamsType.FREETEXT_SIZE,overwriteIfSameType:!0,keepUndo:!0})}#Ve(t){const e=this.#je;this.addCommands({cmd:()=>{this.#je=this.editorDiv.style.color=t},undo:()=>{this.#je=this.editorDiv.style.color=e},mustExec:!0,type:s.AnnotationEditorParamsType.FREETEXT_COLOR,overwriteIfSameType:!0,keepUndo:!0})}_translateEmpty(t,e){this._uiManager.translateSelectedEditors(t,e,!0)}getInitialTranslation(){const t=this.parentScale;return[-FreeTextEditor._internalPadding*t,-(FreeTextEditor._internalPadding+this.#We)*t]}rebuild(){if(this.parent){super.rebuild();null!==this.div&&(this.isAttachedToDOM||this.parent.add(this))}}enableEditMode(){if(!this.isInEditMode()){this.parent.setEditingState(!1);this.parent.updateToolbar(s.AnnotationEditorType.FREETEXT);super.enableEditMode();this.overlayDiv.classList.remove("enabled");this.editorDiv.contentEditable=!0;this._isDraggable=!1;this.div.removeAttribute("aria-activedescendant");this.editorDiv.addEventListener("keydown",this.#Ue);this.editorDiv.addEventListener("focus",this.#Ne);this.editorDiv.addEventListener("blur",this.#Oe);this.editorDiv.addEventListener("input",this.#Be)}}disableEditMode(){if(this.isInEditMode()){this.parent.setEditingState(!0);super.disableEditMode();this.overlayDiv.classList.add("enabled");this.editorDiv.contentEditable=!1;this.div.setAttribute("aria-activedescendant",this.#He);this._isDraggable=!0;this.editorDiv.removeEventListener("keydown",this.#Ue);this.editorDiv.removeEventListener("focus",this.#Ne);this.editorDiv.removeEventListener("blur",this.#Oe);this.editorDiv.removeEventListener("input",this.#Be);this.div.focus({preventScroll:!0});this.isEditing=!1;this.parent.div.classList.add("freeTextEditing")}}focusin(t){if(this._focusEventsAllowed){super.focusin(t);t.target!==this.editorDiv&&this.editorDiv.focus()}}onceAdded(){if(this.width)this.#Xe();else{this.enableEditMode();this.editorDiv.focus();this._initialOptions?.isCentered&&this.center();this._initialOptions=null}}isEmpty(){return!this.editorDiv||""===this.editorDiv.innerText.trim()}remove(){this.isEditing=!1;if(this.parent){this.parent.setEditingState(!0);this.parent.div.classList.add("freeTextEditing")}super.remove()}#Ke(){const t=this.editorDiv.getElementsByTagName("div");if(0===t.length)return this.editorDiv.innerText;const e=[];for(const i of t)e.push(i.innerText.replace(/\r\n?|\n/,""));return e.join("\n")}#$e(){const[t,e]=this.parentDimensions;let i;if(this.isAttachedToDOM)i=this.div.getBoundingClientRect();else{const{currentLayer:t,div:e}=this,s=e.style.display;e.style.display="hidden";t.div.append(this.div);i=e.getBoundingClientRect();e.remove();e.style.display=s}if(this.rotation%180==this.parentRotation%180){this.width=i.width/t;this.height=i.height/e}else{this.width=i.height/t;this.height=i.width/e}this.fixAndSetPosition()}commit(){if(!this.isInEditMode())return;super.commit();this.disableEditMode();const t=this.#ze,e=this.#ze=this.#Ke().trimEnd();if(t===e)return;const setText=t=>{this.#ze=t;if(t){this.#Ye();this._uiManager.rebuild(this);this.#$e()}else this.remove()};this.addCommands({cmd:()=>{setText(e)},undo:()=>{setText(t)},mustExec:!1});this.#$e()}shouldGetKeyboardEvents(){return this.isInEditMode()}enterInEditMode(){this.enableEditMode();this.editorDiv.focus()}dblclick(t){this.enterInEditMode()}keydown(t){if(t.target===this.div&&"Enter"===t.key){this.enterInEditMode();t.preventDefault()}}editorDivKeydown(t){FreeTextEditor._keyboardManager.exec(this,t)}editorDivFocus(t){this.isEditing=!0}editorDivBlur(t){this.isEditing=!1}editorDivInput(t){this.parent.div.classList.toggle("freeTextEditing",this.isEmpty())}disableEditing(){this.editorDiv.setAttribute("role","comment");this.editorDiv.removeAttribute("aria-multiline")}enableEditing(){this.editorDiv.setAttribute("role","textbox");this.editorDiv.setAttribute("aria-multiline",!0)}render(){if(this.div)return this.div;let t,e;if(this.width){t=this.x;e=this.y}super.render();this.editorDiv=document.createElement("div");this.editorDiv.className="internal";this.editorDiv.setAttribute("id",this.#He);this.enableEditing();a.AnnotationEditor._l10nPromise.get("editor_free_text2_aria_label").then((t=>this.editorDiv?.setAttribute("aria-label",t)));a.AnnotationEditor._l10nPromise.get("free_text2_default_content").then((t=>this.editorDiv?.setAttribute("default-content",t)));this.editorDiv.contentEditable=!0;const{style:i}=this.editorDiv;i.fontSize=`calc(${this.#We}px * var(--scale-factor))`;i.color=this.#je;this.div.append(this.editorDiv);this.overlayDiv=document.createElement("div");this.overlayDiv.classList.add("overlay","enabled");this.div.append(this.overlayDiv);(0,n.bindEvents)(this,this.div,["dblclick","keydown"]);if(this.width){const[i,s]=this.parentDimensions;if(this.annotationElementId){const{position:n}=this.#Ge;let[a,r]=this.getInitialTranslation();[a,r]=this.pageTranslationToScreen(a,r);const[o,l]=this.pageDimensions,[h,c]=this.pageTranslation;let d,u;switch(this.rotation){case 0:d=t+(n[0]-h)/o;u=e+this.height-(n[1]-c)/l;break;case 90:d=t+(n[0]-h)/o;u=e-(n[1]-c)/l;[a,r]=[r,-a];break;case 180:d=t-this.width+(n[0]-h)/o;u=e-(n[1]-c)/l;[a,r]=[-a,-r];break;case 270:d=t+(n[0]-h-this.height*l)/o;u=e+(n[1]-c-this.width*o)/l;[a,r]=[-r,a]}this.setAt(d*i,u*s,a,r)}else this.setAt(t*i,e*s,this.width*i,this.height*s);this.#Ye();this._isDraggable=!0;this.editorDiv.contentEditable=!1}else{this._isDraggable=!1;this.editorDiv.contentEditable=!0}return this.div}#Ye(){this.editorDiv.replaceChildren();if(this.#ze)for(const t of this.#ze.split("\n")){const e=document.createElement("div");e.append(t?document.createTextNode(t):document.createElement("br"));this.editorDiv.append(e)}}get contentDiv(){return this.editorDiv}static deserialize(t,e,i){let n=null;if(t instanceof r.FreeTextAnnotationElement){const{data:{defaultAppearanceData:{fontSize:e,fontColor:i},rect:a,rotation:r,id:o},textContent:l,textPosition:h,parent:{page:{pageNumber:c}}}=t;if(!l||0===l.length)return null;n=t={annotationType:s.AnnotationEditorType.FREETEXT,color:Array.from(i),fontSize:e,value:l.join("\n"),position:h,pageIndex:c-1,rect:a,rotation:r,id:o,deleted:!1}}const a=super.deserialize(t,e,i);a.#We=t.fontSize;a.#je=s.Util.makeHexColor(...t.color);a.#ze=t.value;a.annotationElementId=t.id||null;a.#Ge=n;return a}serialize(t=!1){if(this.isEmpty())return null;if(this.deleted)return{pageIndex:this.pageIndex,id:this.annotationElementId,deleted:!0};const e=FreeTextEditor._internalPadding*this.parentScale,i=this.getRect(e,e),n=a.AnnotationEditor._colorManager.convert(this.isAttachedToDOM?getComputedStyle(this.editorDiv).color:this.#je),r={annotationType:s.AnnotationEditorType.FREETEXT,color:n,fontSize:this.#We,value:this.#ze,pageIndex:this.pageIndex,rect:i,rotation:this.rotation,structTreeParentId:this._structTreeParentId};if(t)return r;if(this.annotationElementId&&!this.#Je(r))return null;r.id=this.annotationElementId;return r}#Je(t){const{value:e,fontSize:i,color:s,rect:n,pageIndex:a}=this.#Ge;return t.value!==e||t.fontSize!==i||t.rect.some(((t,e)=>Math.abs(t-n[e])>=1))||t.color.some(((t,e)=>t!==s[e]))||t.pageIndex!==a}#Xe(t=!1){if(!this.annotationElementId)return;this.#$e();if(!t&&(0===this.width||0===this.height)){setTimeout((()=>this.#Xe(!0)),0);return}const e=FreeTextEditor._internalPadding*this.parentScale;this.#Ge.rect=this.getRect(e,e)}}e.FreeTextEditor=FreeTextEditor},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.StampAnnotationElement=e.InkAnnotationElement=e.FreeTextAnnotationElement=e.AnnotationLayer=void 0;var s=i(1),n=i(6),a=i(3),r=i(30),o=i(31),l=i(32);const h=1e3,c=new WeakSet;function getRectDims(t){return{width:t[2]-t[0],height:t[3]-t[1]}}class AnnotationElementFactory{static create(t){switch(t.data.annotationType){case s.AnnotationType.LINK:return new LinkAnnotationElement(t);case s.AnnotationType.TEXT:return new TextAnnotationElement(t);case s.AnnotationType.WIDGET:switch(t.data.fieldType){case"Tx":return new TextWidgetAnnotationElement(t);case"Btn":return t.data.radioButton?new RadioButtonWidgetAnnotationElement(t):t.data.checkBox?new CheckboxWidgetAnnotationElement(t):new PushButtonWidgetAnnotationElement(t);case"Ch":return new ChoiceWidgetAnnotationElement(t);case"Sig":return new SignatureWidgetAnnotationElement(t)}return new WidgetAnnotationElement(t);case s.AnnotationType.POPUP:return new PopupAnnotationElement(t);case s.AnnotationType.FREETEXT:return new FreeTextAnnotationElement(t);case s.AnnotationType.LINE:return new LineAnnotationElement(t);case s.AnnotationType.SQUARE:return new SquareAnnotationElement(t);case s.AnnotationType.CIRCLE:return new CircleAnnotationElement(t);case s.AnnotationType.POLYLINE:return new PolylineAnnotationElement(t);case s.AnnotationType.CARET:return new CaretAnnotationElement(t);case s.AnnotationType.INK:return new InkAnnotationElement(t);case s.AnnotationType.POLYGON:return new PolygonAnnotationElement(t);case s.AnnotationType.HIGHLIGHT:return new HighlightAnnotationElement(t);case s.AnnotationType.UNDERLINE:return new UnderlineAnnotationElement(t);case s.AnnotationType.SQUIGGLY:return new SquigglyAnnotationElement(t);case s.AnnotationType.STRIKEOUT:return new StrikeOutAnnotationElement(t);case s.AnnotationType.STAMP:return new StampAnnotationElement(t);case s.AnnotationType.FILEATTACHMENT:return new FileAttachmentAnnotationElement(t);default:return new AnnotationElement(t)}}}class AnnotationElement{#Qe=!1;constructor(t,{isRenderable:e=!1,ignoreBorder:i=!1,createQuadrilaterals:s=!1}={}){this.isRenderable=e;this.data=t.data;this.layer=t.layer;this.linkService=t.linkService;this.downloadManager=t.downloadManager;this.imageResourcesPath=t.imageResourcesPath;this.renderForms=t.renderForms;this.svgFactory=t.svgFactory;this.annotationStorage=t.annotationStorage;this.enableScripting=t.enableScripting;this.hasJSActions=t.hasJSActions;this._fieldObjects=t.fieldObjects;this.parent=t.parent;e&&(this.container=this._createContainer(i));s&&this._createQuadrilaterals()}static _hasPopupData({titleObj:t,contentsObj:e,richText:i}){return!!(t?.str||e?.str||i?.str)}get hasPopupData(){return AnnotationElement._hasPopupData(this.data)}_createContainer(t){const{data:e,parent:{page:i,viewport:n}}=this,a=document.createElement("section");a.setAttribute("data-annotation-id",e.id);this instanceof WidgetAnnotationElement||(a.tabIndex=h);a.style.zIndex=this.parent.zIndex++;this.data.popupRef&&a.setAttribute("aria-haspopup","dialog");e.noRotate&&a.classList.add("norotate");const{pageWidth:r,pageHeight:o,pageX:l,pageY:c}=n.rawDims;if(!e.rect||this instanceof PopupAnnotationElement){const{rotation:t}=e;e.hasOwnCanvas||0===t||this.setRotation(t,a);return a}const{width:d,height:u}=getRectDims(e.rect),p=s.Util.normalizeRect([e.rect[0],i.view[3]-e.rect[1]+i.view[1],e.rect[2],i.view[3]-e.rect[3]+i.view[1]]);if(!t&&e.borderStyle.width>0){a.style.borderWidth=`${e.borderStyle.width}px`;const t=e.borderStyle.horizontalCornerRadius,i=e.borderStyle.verticalCornerRadius;if(t>0||i>0){const e=`calc(${t}px * var(--scale-factor)) / calc(${i}px * var(--scale-factor))`;a.style.borderRadius=e}else if(this instanceof RadioButtonWidgetAnnotationElement){const t=`calc(${d}px * var(--scale-factor)) / calc(${u}px * var(--scale-factor))`;a.style.borderRadius=t}switch(e.borderStyle.style){case s.AnnotationBorderStyleType.SOLID:a.style.borderStyle="solid";break;case s.AnnotationBorderStyleType.DASHED:a.style.borderStyle="dashed";break;case s.AnnotationBorderStyleType.BEVELED:(0,s.warn)("Unimplemented border style: beveled");break;case s.AnnotationBorderStyleType.INSET:(0,s.warn)("Unimplemented border style: inset");break;case s.AnnotationBorderStyleType.UNDERLINE:a.style.borderBottomStyle="solid"}const n=e.borderColor||null;if(n){this.#Qe=!0;a.style.borderColor=s.Util.makeHexColor(0|n[0],0|n[1],0|n[2])}else a.style.borderWidth=0}a.style.left=100*(p[0]-l)/r+"%";a.style.top=100*(p[1]-c)/o+"%";const{rotation:g}=e;if(e.hasOwnCanvas||0===g){a.style.width=100*d/r+"%";a.style.height=100*u/o+"%"}else this.setRotation(g,a);return a}setRotation(t,e=this.container){if(!this.data.rect)return;const{pageWidth:i,pageHeight:s}=this.parent.viewport.rawDims,{width:n,height:a}=getRectDims(this.data.rect);let r,o;if(t%180==0){r=100*n/i;o=100*a/s}else{r=100*a/i;o=100*n/s}e.style.width=`${r}%`;e.style.height=`${o}%`;e.setAttribute("data-main-rotation",(360-t)%360)}get _commonActions(){const setColor=(t,e,i)=>{const s=i.detail[t],n=s[0],a=s.slice(1);i.target.style[e]=r.ColorConverters[`${n}_HTML`](a);this.annotationStorage.setValue(this.data.id,{[e]:r.ColorConverters[`${n}_rgb`](a)})};return(0,s.shadow)(this,"_commonActions",{display:t=>{const{display:e}=t.detail,i=e%2==1;this.container.style.visibility=i?"hidden":"visible";this.annotationStorage.setValue(this.data.id,{noView:i,noPrint:1===e||2===e})},print:t=>{this.annotationStorage.setValue(this.data.id,{noPrint:!t.detail.print})},hidden:t=>{const{hidden:e}=t.detail;this.container.style.visibility=e?"hidden":"visible";this.annotationStorage.setValue(this.data.id,{noPrint:e,noView:e})},focus:t=>{setTimeout((()=>t.target.focus({preventScroll:!1})),0)},userName:t=>{t.target.title=t.detail.userName},readonly:t=>{t.target.disabled=t.detail.readonly},required:t=>{this._setRequired(t.target,t.detail.required)},bgColor:t=>{setColor("bgColor","backgroundColor",t)},fillColor:t=>{setColor("fillColor","backgroundColor",t)},fgColor:t=>{setColor("fgColor","color",t)},textColor:t=>{setColor("textColor","color",t)},borderColor:t=>{setColor("borderColor","borderColor",t)},strokeColor:t=>{setColor("strokeColor","borderColor",t)},rotation:t=>{const e=t.detail.rotation;this.setRotation(e);this.annotationStorage.setValue(this.data.id,{rotation:e})}})}_dispatchEventFromSandbox(t,e){const i=this._commonActions;for(const s of Object.keys(e.detail)){const n=t[s]||i[s];n?.(e)}}_setDefaultPropertiesFromJS(t){if(!this.enableScripting)return;const e=this.annotationStorage.getRawValue(this.data.id);if(!e)return;const i=this._commonActions;for(const[s,n]of Object.entries(e)){const a=i[s];if(a){a({detail:{[s]:n},target:t});delete e[s]}}}_createQuadrilaterals(){if(!this.container)return;const{quadPoints:t}=this.data;if(!t)return;const[e,i,s,n]=this.data.rect;if(1===t.length){const[,{x:a,y:r},{x:o,y:l}]=t[0];if(s===a&&n===r&&e===o&&i===l)return}const{style:a}=this.container;let r;if(this.#Qe){const{borderColor:t,borderWidth:e}=a;a.borderWidth=0;r=["url('data:image/svg+xml;utf8,",'',``];this.container.classList.add("hasBorder")}const o=s-e,l=n-i,{svgFactory:h}=this,c=h.createElement("svg");c.classList.add("quadrilateralsContainer");c.setAttribute("width",0);c.setAttribute("height",0);const d=h.createElement("defs");c.append(d);const u=h.createElement("clipPath"),p=`clippath_${this.data.id}`;u.setAttribute("id",p);u.setAttribute("clipPathUnits","objectBoundingBox");d.append(u);for(const[,{x:i,y:s},{x:a,y:c}]of t){const t=h.createElement("rect"),d=(a-e)/o,p=(n-s)/l,g=(i-a)/o,m=(s-c)/l;t.setAttribute("x",d);t.setAttribute("y",p);t.setAttribute("width",g);t.setAttribute("height",m);u.append(t);r?.push(``)}if(this.#Qe){r.push("')");a.backgroundImage=r.join("")}this.container.append(c);this.container.style.clipPath=`url(#${p})`}_createPopup(){const{container:t,data:e}=this;t.setAttribute("aria-haspopup","dialog");const i=new PopupAnnotationElement({data:{color:e.color,titleObj:e.titleObj,modificationDate:e.modificationDate,contentsObj:e.contentsObj,richText:e.richText,parentRect:e.rect,borderStyle:0,id:`popup_${e.id}`,rotation:e.rotation},parent:this.parent,elements:[this]});this.parent.div.append(i.render())}render(){(0,s.unreachable)("Abstract method `AnnotationElement.render` called")}_getElementsByName(t,e=null){const i=[];if(this._fieldObjects){const n=this._fieldObjects[t];if(n)for(const{page:t,id:a,exportValues:r}of n){if(-1===t)continue;if(a===e)continue;const n="string"==typeof r?r:null,o=document.querySelector(`[data-element-id="${a}"]`);!o||c.has(o)?i.push({id:a,exportValue:n,domElement:o}):(0,s.warn)(`_getElementsByName - element not allowed: ${a}`)}return i}for(const s of document.getElementsByName(t)){const{exportValue:t}=s,n=s.getAttribute("data-element-id");n!==e&&(c.has(s)&&i.push({id:n,exportValue:t,domElement:s}))}return i}show(){this.container&&(this.container.hidden=!1);this.popup?.maybeShow()}hide(){this.container&&(this.container.hidden=!0);this.popup?.forceHide()}getElementsToTriggerPopup(){return this.container}addHighlightArea(){const t=this.getElementsToTriggerPopup();if(Array.isArray(t))for(const e of t)e.classList.add("highlightArea");else t.classList.add("highlightArea")}_editOnDoubleClick(){const{annotationEditorType:t,data:{id:e}}=this;this.container.addEventListener("dblclick",(()=>{this.linkService.eventBus?.dispatch("switchannotationeditormode",{source:this,mode:t,editId:e})}))}}class LinkAnnotationElement extends AnnotationElement{constructor(t,e=null){super(t,{isRenderable:!0,ignoreBorder:!!e?.ignoreBorder,createQuadrilaterals:!0});this.isTooltipOnly=t.data.isTooltipOnly}render(){const{data:t,linkService:e}=this,i=document.createElement("a");i.setAttribute("data-element-id",t.id);let s=!1;if(t.url){e.addLinkAttributes(i,t.url,t.newWindow);s=!0}else if(t.action){this._bindNamedAction(i,t.action);s=!0}else if(t.attachment){this._bindAttachment(i,t.attachment);s=!0}else if(t.setOCGState){this.#Ze(i,t.setOCGState);s=!0}else if(t.dest){this._bindLink(i,t.dest);s=!0}else{if(t.actions&&(t.actions.Action||t.actions["Mouse Up"]||t.actions["Mouse Down"])&&this.enableScripting&&this.hasJSActions){this._bindJSAction(i,t);s=!0}if(t.resetForm){this._bindResetFormAction(i,t.resetForm);s=!0}else if(this.isTooltipOnly&&!s){this._bindLink(i,"");s=!0}}this.container.classList.add("linkAnnotation");s&&this.container.append(i);return this.container}#ti(){this.container.setAttribute("data-internal-link","")}_bindLink(t,e){t.href=this.linkService.getDestinationHash(e);t.onclick=()=>{e&&this.linkService.goToDestination(e);return!1};(e||""===e)&&this.#ti()}_bindNamedAction(t,e){t.href=this.linkService.getAnchorUrl("");t.onclick=()=>{this.linkService.executeNamedAction(e);return!1};this.#ti()}_bindAttachment(t,e){t.href=this.linkService.getAnchorUrl("");t.onclick=()=>{this.downloadManager?.openOrDownloadData(this.container,e.content,e.filename);return!1};this.#ti()}#Ze(t,e){t.href=this.linkService.getAnchorUrl("");t.onclick=()=>{this.linkService.executeSetOCGState(e);return!1};this.#ti()}_bindJSAction(t,e){t.href=this.linkService.getAnchorUrl("");const i=new Map([["Action","onclick"],["Mouse Up","onmouseup"],["Mouse Down","onmousedown"]]);for(const s of Object.keys(e.actions)){const n=i.get(s);n&&(t[n]=()=>{this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:e.id,name:s}});return!1})}t.onclick||(t.onclick=()=>!1);this.#ti()}_bindResetFormAction(t,e){const i=t.onclick;i||(t.href=this.linkService.getAnchorUrl(""));this.#ti();if(this._fieldObjects)t.onclick=()=>{i?.();const{fields:t,refs:n,include:a}=e,r=[];if(0!==t.length||0!==n.length){const e=new Set(n);for(const i of t){const t=this._fieldObjects[i]||[];for(const{id:i}of t)e.add(i)}for(const t of Object.values(this._fieldObjects))for(const i of t)e.has(i.id)===a&&r.push(i)}else for(const t of Object.values(this._fieldObjects))r.push(...t);const o=this.annotationStorage,l=[];for(const t of r){const{id:e}=t;l.push(e);switch(t.type){case"text":{const i=t.defaultValue||"";o.setValue(e,{value:i});break}case"checkbox":case"radiobutton":{const i=t.defaultValue===t.exportValues;o.setValue(e,{value:i});break}case"combobox":case"listbox":{const i=t.defaultValue||"";o.setValue(e,{value:i});break}default:continue}const i=document.querySelector(`[data-element-id="${e}"]`);i&&(c.has(i)?i.dispatchEvent(new Event("resetform")):(0,s.warn)(`_bindResetFormAction - element not allowed: ${e}`))}this.enableScripting&&this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:"app",ids:l,name:"ResetForm"}});return!1};else{(0,s.warn)('_bindResetFormAction - "resetForm" action not supported, ensure that the `fieldObjects` parameter is provided.');i||(t.onclick=()=>!1)}}}class TextAnnotationElement extends AnnotationElement{constructor(t){super(t,{isRenderable:!0})}render(){this.container.classList.add("textAnnotation");const t=document.createElement("img");t.src=this.imageResourcesPath+"annotation-"+this.data.name.toLowerCase()+".svg";t.alt="[{{type}} Annotation]";t.dataset.l10nId="text_annotation_type";t.dataset.l10nArgs=JSON.stringify({type:this.data.name});!this.data.popupRef&&this.hasPopupData&&this._createPopup();this.container.append(t);return this.container}}class WidgetAnnotationElement extends AnnotationElement{render(){this.data.alternativeText&&(this.container.title=this.data.alternativeText);return this.container}showElementAndHideCanvas(t){if(this.data.hasOwnCanvas){"CANVAS"===t.previousSibling?.nodeName&&(t.previousSibling.hidden=!0);t.hidden=!1}}_getKeyModifier(t){const{isWin:e,isMac:i}=s.FeatureTest.platform;return e&&t.ctrlKey||i&&t.metaKey}_setEventListener(t,e,i,s,n){i.includes("mouse")?t.addEventListener(i,(t=>{this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:this.data.id,name:s,value:n(t),shift:t.shiftKey,modifier:this._getKeyModifier(t)}})})):t.addEventListener(i,(t=>{if("blur"===i){if(!e.focused||!t.relatedTarget)return;e.focused=!1}else if("focus"===i){if(e.focused)return;e.focused=!0}n&&this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:this.data.id,name:s,value:n(t)}})}))}_setEventListeners(t,e,i,s){for(const[n,a]of i)if("Action"===a||this.data.actions?.[a]){"Focus"!==a&&"Blur"!==a||(e||={focused:!1});this._setEventListener(t,e,n,a,s);"Focus"!==a||this.data.actions?.Blur?"Blur"!==a||this.data.actions?.Focus||this._setEventListener(t,e,"focus","Focus",null):this._setEventListener(t,e,"blur","Blur",null)}}_setBackgroundColor(t){const e=this.data.backgroundColor||null;t.style.backgroundColor=null===e?"transparent":s.Util.makeHexColor(e[0],e[1],e[2])}_setTextStyle(t){const e=["left","center","right"],{fontColor:i}=this.data.defaultAppearanceData,n=this.data.defaultAppearanceData.fontSize||9,a=t.style;let r;const roundToOneDecimal=t=>Math.round(10*t)/10;if(this.data.multiLine){const t=Math.abs(this.data.rect[3]-this.data.rect[1]-2),e=t/(Math.round(t/(s.LINE_FACTOR*n))||1);r=Math.min(n,roundToOneDecimal(e/s.LINE_FACTOR))}else{const t=Math.abs(this.data.rect[3]-this.data.rect[1]-2);r=Math.min(n,roundToOneDecimal(t/s.LINE_FACTOR))}a.fontSize=`calc(${r}px * var(--scale-factor))`;a.color=s.Util.makeHexColor(i[0],i[1],i[2]);null!==this.data.textAlignment&&(a.textAlign=e[this.data.textAlignment])}_setRequired(t,e){e?t.setAttribute("required",!0):t.removeAttribute("required");t.setAttribute("aria-required",e)}}class TextWidgetAnnotationElement extends WidgetAnnotationElement{constructor(t){super(t,{isRenderable:t.renderForms||!t.data.hasAppearance&&!!t.data.fieldValue})}setPropertyOnSiblings(t,e,i,s){const n=this.annotationStorage;for(const a of this._getElementsByName(t.name,t.id)){a.domElement&&(a.domElement[e]=i);n.setValue(a.id,{[s]:i})}}render(){const t=this.annotationStorage,e=this.data.id;this.container.classList.add("textWidgetAnnotation");let i=null;if(this.renderForms){const s=t.getValue(e,{value:this.data.fieldValue});let n=s.value||"";const a=t.getValue(e,{charLimit:this.data.maxLen}).charLimit;a&&n.length>a&&(n=n.slice(0,a));let r=s.formattedValue||this.data.textContent?.join("\n")||null;r&&this.data.comb&&(r=r.replaceAll(/\s+/g,""));const o={userValue:n,formattedValue:r,lastCommittedValue:null,commitKey:1,focused:!1};if(this.data.multiLine){i=document.createElement("textarea");i.textContent=r??n;this.data.doNotScroll&&(i.style.overflowY="hidden")}else{i=document.createElement("input");i.type="text";i.setAttribute("value",r??n);this.data.doNotScroll&&(i.style.overflowX="hidden")}this.data.hasOwnCanvas&&(i.hidden=!0);c.add(i);i.setAttribute("data-element-id",e);i.disabled=this.data.readOnly;i.name=this.data.fieldName;i.tabIndex=h;this._setRequired(i,this.data.required);a&&(i.maxLength=a);i.addEventListener("input",(s=>{t.setValue(e,{value:s.target.value});this.setPropertyOnSiblings(i,"value",s.target.value,"value");o.formattedValue=null}));i.addEventListener("resetform",(t=>{const e=this.data.defaultFieldValue??"";i.value=o.userValue=e;o.formattedValue=null}));let blurListener=t=>{const{formattedValue:e}=o;null!=e&&(t.target.value=e);t.target.scrollLeft=0};if(this.enableScripting&&this.hasJSActions){i.addEventListener("focus",(t=>{if(o.focused)return;const{target:e}=t;o.userValue&&(e.value=o.userValue);o.lastCommittedValue=e.value;o.commitKey=1;o.focused=!0}));i.addEventListener("updatefromsandbox",(i=>{this.showElementAndHideCanvas(i.target);const s={value(i){o.userValue=i.detail.value??"";t.setValue(e,{value:o.userValue.toString()});i.target.value=o.userValue},formattedValue(i){const{formattedValue:s}=i.detail;o.formattedValue=s;null!=s&&i.target!==document.activeElement&&(i.target.value=s);t.setValue(e,{formattedValue:s})},selRange(t){t.target.setSelectionRange(...t.detail.selRange)},charLimit:i=>{const{charLimit:s}=i.detail,{target:n}=i;if(0===s){n.removeAttribute("maxLength");return}n.setAttribute("maxLength",s);let a=o.userValue;if(a&&!(a.length<=s)){a=a.slice(0,s);n.value=o.userValue=a;t.setValue(e,{value:a});this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:e,name:"Keystroke",value:a,willCommit:!0,commitKey:1,selStart:n.selectionStart,selEnd:n.selectionEnd}})}}};this._dispatchEventFromSandbox(s,i)}));i.addEventListener("keydown",(t=>{o.commitKey=1;let i=-1;"Escape"===t.key?i=0:"Enter"!==t.key||this.data.multiLine?"Tab"===t.key&&(o.commitKey=3):i=2;if(-1===i)return;const{value:s}=t.target;if(o.lastCommittedValue!==s){o.lastCommittedValue=s;o.userValue=s;this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:e,name:"Keystroke",value:s,willCommit:!0,commitKey:i,selStart:t.target.selectionStart,selEnd:t.target.selectionEnd}})}}));const s=blurListener;blurListener=null;i.addEventListener("blur",(t=>{if(!o.focused||!t.relatedTarget)return;o.focused=!1;const{value:i}=t.target;o.userValue=i;o.lastCommittedValue!==i&&this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:e,name:"Keystroke",value:i,willCommit:!0,commitKey:o.commitKey,selStart:t.target.selectionStart,selEnd:t.target.selectionEnd}});s(t)}));this.data.actions?.Keystroke&&i.addEventListener("beforeinput",(t=>{o.lastCommittedValue=null;const{data:i,target:s}=t,{value:n,selectionStart:a,selectionEnd:r}=s;let l=a,h=r;switch(t.inputType){case"deleteWordBackward":{const t=n.substring(0,a).match(/\w*[^\w]*$/);t&&(l-=t[0].length);break}case"deleteWordForward":{const t=n.substring(a).match(/^[^\w]*\w*/);t&&(h+=t[0].length);break}case"deleteContentBackward":a===r&&(l-=1);break;case"deleteContentForward":a===r&&(h+=1)}t.preventDefault();this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:e,name:"Keystroke",value:n,change:i||"",willCommit:!1,selStart:l,selEnd:h}})}));this._setEventListeners(i,o,[["focus","Focus"],["blur","Blur"],["mousedown","Mouse Down"],["mouseenter","Mouse Enter"],["mouseleave","Mouse Exit"],["mouseup","Mouse Up"]],(t=>t.target.value))}blurListener&&i.addEventListener("blur",blurListener);if(this.data.comb){const t=(this.data.rect[2]-this.data.rect[0])/a;i.classList.add("comb");i.style.letterSpacing=`calc(${t}px * var(--scale-factor) - 1ch)`}}else{i=document.createElement("div");i.textContent=this.data.fieldValue;i.style.verticalAlign="middle";i.style.display="table-cell"}this._setTextStyle(i);this._setBackgroundColor(i);this._setDefaultPropertiesFromJS(i);this.container.append(i);return this.container}}class SignatureWidgetAnnotationElement extends WidgetAnnotationElement{constructor(t){super(t,{isRenderable:!!t.data.hasOwnCanvas})}}class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement{constructor(t){super(t,{isRenderable:t.renderForms})}render(){const t=this.annotationStorage,e=this.data,i=e.id;let s=t.getValue(i,{value:e.exportValue===e.fieldValue}).value;if("string"==typeof s){s="Off"!==s;t.setValue(i,{value:s})}this.container.classList.add("buttonWidgetAnnotation","checkBox");const n=document.createElement("input");c.add(n);n.setAttribute("data-element-id",i);n.disabled=e.readOnly;this._setRequired(n,this.data.required);n.type="checkbox";n.name=e.fieldName;s&&n.setAttribute("checked",!0);n.setAttribute("exportValue",e.exportValue);n.tabIndex=h;n.addEventListener("change",(s=>{const{name:n,checked:a}=s.target;for(const s of this._getElementsByName(n,i)){const i=a&&s.exportValue===e.exportValue;s.domElement&&(s.domElement.checked=i);t.setValue(s.id,{value:i})}t.setValue(i,{value:a})}));n.addEventListener("resetform",(t=>{const i=e.defaultFieldValue||"Off";t.target.checked=i===e.exportValue}));if(this.enableScripting&&this.hasJSActions){n.addEventListener("updatefromsandbox",(e=>{const s={value(e){e.target.checked="Off"!==e.detail.value;t.setValue(i,{value:e.target.checked})}};this._dispatchEventFromSandbox(s,e)}));this._setEventListeners(n,null,[["change","Validate"],["change","Action"],["focus","Focus"],["blur","Blur"],["mousedown","Mouse Down"],["mouseenter","Mouse Enter"],["mouseleave","Mouse Exit"],["mouseup","Mouse Up"]],(t=>t.target.checked))}this._setBackgroundColor(n);this._setDefaultPropertiesFromJS(n);this.container.append(n);return this.container}}class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement{constructor(t){super(t,{isRenderable:t.renderForms})}render(){this.container.classList.add("buttonWidgetAnnotation","radioButton");const t=this.annotationStorage,e=this.data,i=e.id;let s=t.getValue(i,{value:e.fieldValue===e.buttonValue}).value;if("string"==typeof s){s=s!==e.buttonValue;t.setValue(i,{value:s})}const n=document.createElement("input");c.add(n);n.setAttribute("data-element-id",i);n.disabled=e.readOnly;this._setRequired(n,this.data.required);n.type="radio";n.name=e.fieldName;s&&n.setAttribute("checked",!0);n.tabIndex=h;n.addEventListener("change",(e=>{const{name:s,checked:n}=e.target;for(const e of this._getElementsByName(s,i))t.setValue(e.id,{value:!1});t.setValue(i,{value:n})}));n.addEventListener("resetform",(t=>{const i=e.defaultFieldValue;t.target.checked=null!=i&&i===e.buttonValue}));if(this.enableScripting&&this.hasJSActions){const s=e.buttonValue;n.addEventListener("updatefromsandbox",(e=>{const n={value:e=>{const n=s===e.detail.value;for(const s of this._getElementsByName(e.target.name)){const e=n&&s.id===i;s.domElement&&(s.domElement.checked=e);t.setValue(s.id,{value:e})}}};this._dispatchEventFromSandbox(n,e)}));this._setEventListeners(n,null,[["change","Validate"],["change","Action"],["focus","Focus"],["blur","Blur"],["mousedown","Mouse Down"],["mouseenter","Mouse Enter"],["mouseleave","Mouse Exit"],["mouseup","Mouse Up"]],(t=>t.target.checked))}this._setBackgroundColor(n);this._setDefaultPropertiesFromJS(n);this.container.append(n);return this.container}}class PushButtonWidgetAnnotationElement extends LinkAnnotationElement{constructor(t){super(t,{ignoreBorder:t.data.hasAppearance})}render(){const t=super.render();t.classList.add("buttonWidgetAnnotation","pushButton");this.data.alternativeText&&(t.title=this.data.alternativeText);const e=t.lastChild;if(this.enableScripting&&this.hasJSActions&&e){this._setDefaultPropertiesFromJS(e);e.addEventListener("updatefromsandbox",(t=>{this._dispatchEventFromSandbox({},t)}))}return t}}class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement{constructor(t){super(t,{isRenderable:t.renderForms})}render(){this.container.classList.add("choiceWidgetAnnotation");const t=this.annotationStorage,e=this.data.id,i=t.getValue(e,{value:this.data.fieldValue}),s=document.createElement("select");c.add(s);s.setAttribute("data-element-id",e);s.disabled=this.data.readOnly;this._setRequired(s,this.data.required);s.name=this.data.fieldName;s.tabIndex=h;let n=this.data.combo&&this.data.options.length>0;if(!this.data.combo){s.size=this.data.options.length;this.data.multiSelect&&(s.multiple=!0)}s.addEventListener("resetform",(t=>{const e=this.data.defaultFieldValue;for(const t of s.options)t.selected=t.value===e}));for(const t of this.data.options){const e=document.createElement("option");e.textContent=t.displayValue;e.value=t.exportValue;if(i.value.includes(t.exportValue)){e.setAttribute("selected",!0);n=!1}s.append(e)}let a=null;if(n){const t=document.createElement("option");t.value=" ";t.setAttribute("hidden",!0);t.setAttribute("selected",!0);s.prepend(t);a=()=>{t.remove();s.removeEventListener("input",a);a=null};s.addEventListener("input",a)}const getValue=t=>{const e=t?"value":"textContent",{options:i,multiple:n}=s;return n?Array.prototype.filter.call(i,(t=>t.selected)).map((t=>t[e])):-1===i.selectedIndex?null:i[i.selectedIndex][e]};let r=getValue(!1);const getItems=t=>{const e=t.target.options;return Array.prototype.map.call(e,(t=>({displayValue:t.textContent,exportValue:t.value})))};if(this.enableScripting&&this.hasJSActions){s.addEventListener("updatefromsandbox",(i=>{const n={value(i){a?.();const n=i.detail.value,o=new Set(Array.isArray(n)?n:[n]);for(const t of s.options)t.selected=o.has(t.value);t.setValue(e,{value:getValue(!0)});r=getValue(!1)},multipleSelection(t){s.multiple=!0},remove(i){const n=s.options,a=i.detail.remove;n[a].selected=!1;s.remove(a);if(n.length>0){-1===Array.prototype.findIndex.call(n,(t=>t.selected))&&(n[0].selected=!0)}t.setValue(e,{value:getValue(!0),items:getItems(i)});r=getValue(!1)},clear(i){for(;0!==s.length;)s.remove(0);t.setValue(e,{value:null,items:[]});r=getValue(!1)},insert(i){const{index:n,displayValue:a,exportValue:o}=i.detail.insert,l=s.children[n],h=document.createElement("option");h.textContent=a;h.value=o;l?l.before(h):s.append(h);t.setValue(e,{value:getValue(!0),items:getItems(i)});r=getValue(!1)},items(i){const{items:n}=i.detail;for(;0!==s.length;)s.remove(0);for(const t of n){const{displayValue:e,exportValue:i}=t,n=document.createElement("option");n.textContent=e;n.value=i;s.append(n)}s.options.length>0&&(s.options[0].selected=!0);t.setValue(e,{value:getValue(!0),items:getItems(i)});r=getValue(!1)},indices(i){const s=new Set(i.detail.indices);for(const t of i.target.options)t.selected=s.has(t.index);t.setValue(e,{value:getValue(!0)});r=getValue(!1)},editable(t){t.target.disabled=!t.detail.editable}};this._dispatchEventFromSandbox(n,i)}));s.addEventListener("input",(i=>{const s=getValue(!0);t.setValue(e,{value:s});i.preventDefault();this.linkService.eventBus?.dispatch("dispatcheventinsandbox",{source:this,detail:{id:e,name:"Keystroke",value:r,changeEx:s,willCommit:!1,commitKey:1,keyDown:!1}})}));this._setEventListeners(s,null,[["focus","Focus"],["blur","Blur"],["mousedown","Mouse Down"],["mouseenter","Mouse Enter"],["mouseleave","Mouse Exit"],["mouseup","Mouse Up"],["input","Action"],["input","Validate"]],(t=>t.target.value))}else s.addEventListener("input",(function(i){t.setValue(e,{value:getValue(!0)})}));this.data.combo&&this._setTextStyle(s);this._setBackgroundColor(s);this._setDefaultPropertiesFromJS(s);this.container.append(s);return this.container}}class PopupAnnotationElement extends AnnotationElement{constructor(t){const{data:e,elements:i}=t;super(t,{isRenderable:AnnotationElement._hasPopupData(e)});this.elements=i}render(){this.container.classList.add("popupAnnotation");const t=new PopupElement({container:this.container,color:this.data.color,titleObj:this.data.titleObj,modificationDate:this.data.modificationDate,contentsObj:this.data.contentsObj,richText:this.data.richText,rect:this.data.rect,parentRect:this.data.parentRect||null,parent:this.parent,elements:this.elements,open:this.data.open}),e=[];for(const i of this.elements){i.popup=t;e.push(i.data.id);i.addHighlightArea()}this.container.setAttribute("aria-controls",e.map((t=>`${s.AnnotationPrefix}${t}`)).join(","));return this.container}}class PopupElement{#ei=null;#ii=this.#si.bind(this);#ni=this.#ai.bind(this);#ri=this.#oi.bind(this);#li=this.#hi.bind(this);#je=null;#Rt=null;#ci=null;#di=null;#ui=null;#pi=null;#gi=!1;#mi=null;#fi=null;#bi=null;#Ai=null;#_i=!1;constructor({container:t,color:e,elements:i,titleObj:s,modificationDate:a,contentsObj:r,richText:o,parent:l,rect:h,parentRect:c,open:d}){this.#Rt=t;this.#Ai=s;this.#ci=r;this.#bi=o;this.#ui=l;this.#je=e;this.#fi=h;this.#pi=c;this.#di=i;const u=n.PDFDateString.toDateObject(a);u&&(this.#ei=l.l10n.get("annotation_date_string",{date:u.toLocaleDateString(),time:u.toLocaleTimeString()}));this.trigger=i.flatMap((t=>t.getElementsToTriggerPopup()));for(const t of this.trigger){t.addEventListener("click",this.#li);t.addEventListener("mouseenter",this.#ri);t.addEventListener("mouseleave",this.#ni);t.classList.add("popupTriggerArea")}for(const t of i)t.container?.addEventListener("keydown",this.#ii);this.#Rt.hidden=!0;d&&this.#hi()}render(){if(this.#mi)return;const{page:{view:t},viewport:{rawDims:{pageWidth:e,pageHeight:i,pageX:n,pageY:a}}}=this.#ui,r=this.#mi=document.createElement("div");r.className="popup";if(this.#je){const t=r.style.outlineColor=s.Util.makeHexColor(...this.#je);if(CSS.supports("background-color","color-mix(in srgb, red 30%, white)"))r.style.backgroundColor=`color-mix(in srgb, ${t} 30%, white)`;else{const t=.7;r.style.backgroundColor=s.Util.makeHexColor(...this.#je.map((e=>Math.floor(t*(255-e)+e))))}}const o=document.createElement("span");o.className="header";const h=document.createElement("h1");o.append(h);({dir:h.dir,str:h.textContent}=this.#Ai);r.append(o);if(this.#ei){const t=document.createElement("span");t.classList.add("popupDate");this.#ei.then((e=>{t.textContent=e}));o.append(t)}const c=this.#ci,d=this.#bi;if(!d?.str||c?.str&&c.str!==d.str){const t=this._formatContents(c);r.append(t)}else{l.XfaLayer.render({xfaHtml:d.html,intent:"richText",div:r});r.lastChild.classList.add("richText","popupContent")}let u=!!this.#pi,p=u?this.#pi:this.#fi;for(const t of this.#di)if(!p||null!==s.Util.intersect(t.data.rect,p)){p=t.data.rect;u=!0;break}const g=s.Util.normalizeRect([p[0],t[3]-p[1]+t[1],p[2],t[3]-p[3]+t[1]]),m=u?p[2]-p[0]+5:0,f=g[0]+m,b=g[1],{style:A}=this.#Rt;A.left=100*(f-n)/e+"%";A.top=100*(b-a)/i+"%";this.#Rt.append(r)}_formatContents({str:t,dir:e}){const i=document.createElement("p");i.classList.add("popupContent");i.dir=e;const s=t.split(/(?:\r\n?|\n)/);for(let t=0,e=s.length;t{"Enter"===t.key&&(n?t.metaKey:t.ctrlKey)&&this.#Ci()}));!e.popupRef&&this.hasPopupData?this._createPopup():i.classList.add("popupTriggerArea");t.append(i);return t}getElementsToTriggerPopup(){return this.#wi}addHighlightArea(){this.container.classList.add("highlightArea")}#Ci(){this.downloadManager?.openOrDownloadData(this.container,this.content,this.filename)}}e.AnnotationLayer=class AnnotationLayer{#Se=null;#Ti=null;#Pi=new Map;constructor({div:t,accessibilityManager:e,annotationCanvasMap:i,l10n:s,page:n,viewport:a}){this.div=t;this.#Se=e;this.#Ti=i;this.l10n=s;this.page=n;this.viewport=a;this.zIndex=0;this.l10n||=o.NullL10n}#Mi(t,e){const i=t.firstChild||t;i.id=`${s.AnnotationPrefix}${e}`;this.div.append(t);this.#Se?.moveElementInDOM(this.div,t,i,!1)}async render(t){const{annotations:e}=t,i=this.div;(0,n.setLayerDimensions)(i,this.viewport);const r=new Map,o={data:null,layer:i,linkService:t.linkService,downloadManager:t.downloadManager,imageResourcesPath:t.imageResourcesPath||"",renderForms:!1!==t.renderForms,svgFactory:new n.DOMSVGFactory,annotationStorage:t.annotationStorage||new a.AnnotationStorage,enableScripting:!0===t.enableScripting,hasJSActions:t.hasJSActions,fieldObjects:t.fieldObjects,parent:this,elements:null};for(const t of e){if(t.noHTML)continue;const e=t.annotationType===s.AnnotationType.POPUP;if(e){const e=r.get(t.id);if(!e)continue;o.elements=e}else{const{width:e,height:i}=getRectDims(t.rect);if(e<=0||i<=0)continue}o.data=t;const i=AnnotationElementFactory.create(o);if(!i.isRenderable)continue;if(!e&&t.popupRef){const e=r.get(t.popupRef);e?e.push(i):r.set(t.popupRef,[i])}i.annotationEditorType>0&&this.#Pi.set(i.data.id,i);const n=i.render();t.hidden&&(n.style.visibility="hidden");this.#Mi(n,t.id)}this.#ki();await this.l10n.translate(i)}update({viewport:t}){const e=this.div;this.viewport=t;(0,n.setLayerDimensions)(e,{rotation:t.rotation});this.#ki();e.hidden=!1}#ki(){if(!this.#Ti)return;const t=this.div;for(const[e,i]of this.#Ti){const s=t.querySelector(`[data-annotation-id="${e}"]`);if(!s)continue;const{firstChild:n}=s;n?"CANVAS"===n.nodeName?n.replaceWith(i):n.before(i):s.append(i)}this.#Ti.clear()}getEditableAnnotations(){return Array.from(this.#Pi.values())}getEditableAnnotation(t){return this.#Pi.get(t)}}},(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0});e.ColorConverters=void 0;function makeColorComp(t){return Math.floor(255*Math.max(0,Math.min(1,t))).toString(16).padStart(2,"0")}function scaleAndClamp(t){return Math.max(0,Math.min(255,255*t))}e.ColorConverters=class ColorConverters{static CMYK_G([t,e,i,s]){return["G",1-Math.min(1,.3*t+.59*i+.11*e+s)]}static G_CMYK([t]){return["CMYK",0,0,0,1-t]}static G_RGB([t]){return["RGB",t,t,t]}static G_rgb([t]){return[t=scaleAndClamp(t),t,t]}static G_HTML([t]){const e=makeColorComp(t);return`#${e}${e}${e}`}static RGB_G([t,e,i]){return["G",.3*t+.59*e+.11*i]}static RGB_rgb(t){return t.map(scaleAndClamp)}static RGB_HTML(t){return`#${t.map(makeColorComp).join("")}`}static T_HTML(){return"#00000000"}static T_rgb(){return[null]}static CMYK_RGB([t,e,i,s]){return["RGB",1-Math.min(1,t+s),1-Math.min(1,i+s),1-Math.min(1,e+s)]}static CMYK_rgb([t,e,i,s]){return[scaleAndClamp(1-Math.min(1,t+s)),scaleAndClamp(1-Math.min(1,i+s)),scaleAndClamp(1-Math.min(1,e+s))]}static CMYK_HTML(t){const e=this.CMYK_RGB(t).slice(1);return this.RGB_HTML(e)}static RGB_CMYK([t,e,i]){const s=1-t,n=1-e,a=1-i;return["CMYK",s,n,a,Math.min(s,n,a)]}}},(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0});e.NullL10n=void 0;e.getL10nFallback=getL10nFallback;const i={of_pages:"of {{pagesCount}}",page_of_pages:"({{pageNumber}} of {{pagesCount}})",document_properties_kb:"{{size_kb}} KB ({{size_b}} bytes)",document_properties_mb:"{{size_mb}} MB ({{size_b}} bytes)",document_properties_date_string:"{{date}}, {{time}}",document_properties_page_size_unit_inches:"in",document_properties_page_size_unit_millimeters:"mm",document_properties_page_size_orientation_portrait:"portrait",document_properties_page_size_orientation_landscape:"landscape",document_properties_page_size_name_a3:"A3",document_properties_page_size_name_a4:"A4",document_properties_page_size_name_letter:"Letter",document_properties_page_size_name_legal:"Legal",document_properties_page_size_dimension_string:"{{width}} Ɨ {{height}} {{unit}} ({{orientation}})",document_properties_page_size_dimension_name_string:"{{width}} Ɨ {{height}} {{unit}} ({{name}}, {{orientation}})",document_properties_linearized_yes:"Yes",document_properties_linearized_no:"No",additional_layers:"Additional Layers",page_landmark:"Page {{page}}",thumb_page_title:"Page {{page}}",thumb_page_canvas:"Thumbnail of Page {{page}}",find_reached_top:"Reached top of document, continued from bottom",find_reached_bottom:"Reached end of document, continued from top","find_match_count[one]":"{{current}} of {{total}} match","find_match_count[other]":"{{current}} of {{total}} matches","find_match_count_limit[one]":"More than {{limit}} match","find_match_count_limit[other]":"More than {{limit}} matches",find_not_found:"Phrase not found",page_scale_width:"Page Width",page_scale_fit:"Page Fit",page_scale_auto:"Automatic Zoom",page_scale_actual:"Actual Size",page_scale_percent:"{{scale}}%",loading_error:"An error occurred while loading the PDF.",invalid_file_error:"Invalid or corrupted PDF file.",missing_file_error:"Missing PDF file.",unexpected_response_error:"Unexpected server response.",rendering_error:"An error occurred while rendering the page.",annotation_date_string:"{{date}}, {{time}}",printing_not_supported:"Warning: Printing is not fully supported by this browser.",printing_not_ready:"Warning: The PDF is not fully loaded for printing.",web_fonts_disabled:"Web fonts are disabled: unable to use embedded PDF fonts.",free_text2_default_content:"Start typing…",editor_free_text2_aria_label:"Text Editor",editor_ink2_aria_label:"Draw Editor",editor_ink_canvas_aria_label:"User-created image",editor_alt_text_button_label:"Alt text",editor_alt_text_edit_button_label:"Edit alt text",editor_alt_text_decorative_tooltip:"Marked as decorative",print_progress_percent:"{{progress}}%"};function getL10nFallback(t,e){switch(t){case"find_match_count":t=`find_match_count[${1===e.total?"one":"other"}]`;break;case"find_match_count_limit":t=`find_match_count_limit[${1===e.limit?"one":"other"}]`}return i[t]||""}const s={getLanguage:async()=>"en-us",getDirection:async()=>"ltr",get:async(t,e=null,i=getL10nFallback(t,e))=>function formatL10nValue(t,e){return e?t.replaceAll(/\{\{\s*(\w+)\s*\}\}/g,((t,i)=>i in e?e[i]:"{{"+i+"}}")):t}(i,e),async translate(t){}};e.NullL10n=s},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.XfaLayer=void 0;var s=i(25);e.XfaLayer=class XfaLayer{static setupStorage(t,e,i,s,n){const a=s.getValue(e,{value:null});switch(i.name){case"textarea":null!==a.value&&(t.textContent=a.value);if("print"===n)break;t.addEventListener("input",(t=>{s.setValue(e,{value:t.target.value})}));break;case"input":if("radio"===i.attributes.type||"checkbox"===i.attributes.type){a.value===i.attributes.xfaOn?t.setAttribute("checked",!0):a.value===i.attributes.xfaOff&&t.removeAttribute("checked");if("print"===n)break;t.addEventListener("change",(t=>{s.setValue(e,{value:t.target.checked?t.target.getAttribute("xfaOn"):t.target.getAttribute("xfaOff")})}))}else{null!==a.value&&t.setAttribute("value",a.value);if("print"===n)break;t.addEventListener("input",(t=>{s.setValue(e,{value:t.target.value})}))}break;case"select":if(null!==a.value){t.setAttribute("value",a.value);for(const t of i.children)t.attributes.value===a.value?t.attributes.selected=!0:t.attributes.hasOwnProperty("selected")&&delete t.attributes.selected}t.addEventListener("input",(t=>{const i=t.target.options,n=-1===i.selectedIndex?"":i[i.selectedIndex].value;s.setValue(e,{value:n})}))}}static setAttributes({html:t,element:e,storage:i=null,intent:s,linkService:n}){const{attributes:a}=e,r=t instanceof HTMLAnchorElement;"radio"===a.type&&(a.name=`${a.name}-${s}`);for(const[e,i]of Object.entries(a))if(null!=i)switch(e){case"class":i.length&&t.setAttribute(e,i.join(" "));break;case"dataId":break;case"id":t.setAttribute("data-element-id",i);break;case"style":Object.assign(t.style,i);break;case"textContent":t.textContent=i;break;default:(!r||"href"!==e&&"newWindow"!==e)&&t.setAttribute(e,i)}r&&n.addLinkAttributes(t,a.href,a.newWindow);i&&a.dataId&&this.setupStorage(t,a.dataId,e,i)}static render(t){const e=t.annotationStorage,i=t.linkService,n=t.xfaHtml,a=t.intent||"display",r=document.createElement(n.name);n.attributes&&this.setAttributes({html:r,element:n,intent:a,linkService:i});const o=[[n,-1,r]],l=t.div;l.append(r);if(t.viewport){const e=`matrix(${t.viewport.transform.join(",")})`;l.style.transform=e}"richText"!==a&&l.setAttribute("class","xfaLayer xfaFont");const h=[];for(;o.length>0;){const[t,n,r]=o.at(-1);if(n+1===t.children.length){o.pop();continue}const l=t.children[++o.at(-1)[1]];if(null===l)continue;const{name:c}=l;if("#text"===c){const t=document.createTextNode(l.value);h.push(t);r.append(t);continue}const d=l?.attributes?.xmlns?document.createElementNS(l.attributes.xmlns,c):document.createElement(c);r.append(d);l.attributes&&this.setAttributes({html:d,element:l,storage:e,intent:a,linkService:i});if(l.children&&l.children.length>0)o.push([l,-1,d]);else if(l.value){const t=document.createTextNode(l.value);s.XfaText.shouldBuildText(c)&&h.push(t);d.append(t)}}for(const t of l.querySelectorAll(".xfaNonInteractive input, .xfaNonInteractive textarea"))t.setAttribute("readOnly",!0);return{textDivs:h}}static update(t){const e=`matrix(${t.viewport.transform.join(",")})`;t.div.style.transform=e;t.div.hidden=!1}}},(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0});e.InkEditor=void 0;var s=i(1),n=i(4),a=i(29),r=i(6),o=i(5);class InkEditor extends n.AnnotationEditor{#Fi=0;#Ri=0;#Di=this.canvasPointermove.bind(this);#Ii=this.canvasPointerleave.bind(this);#Li=this.canvasPointerup.bind(this);#Oi=this.canvasPointerdown.bind(this);#Ni=new Path2D;#Bi=!1;#Ui=!1;#ji=!1;#zi=null;#Hi=0;#Wi=0;#Gi=null;static _defaultColor=null;static _defaultOpacity=1;static _defaultThickness=1;static _type="ink";constructor(t){super({...t,name:"inkEditor"});this.color=t.color||null;this.thickness=t.thickness||null;this.opacity=t.opacity||null;this.paths=[];this.bezierPath2D=[];this.allRawPaths=[];this.currentPath=[];this.scaleFactor=1;this.translationX=this.translationY=0;this.x=0;this.y=0;this._willKeepAspectRatio=!0}static initialize(t){n.AnnotationEditor.initialize(t,{strings:["editor_ink_canvas_aria_label","editor_ink2_aria_label"]})}static updateDefaultParams(t,e){switch(t){case s.AnnotationEditorParamsType.INK_THICKNESS:InkEditor._defaultThickness=e;break;case s.AnnotationEditorParamsType.INK_COLOR:InkEditor._defaultColor=e;break;case s.AnnotationEditorParamsType.INK_OPACITY:InkEditor._defaultOpacity=e/100}}updateParams(t,e){switch(t){case s.AnnotationEditorParamsType.INK_THICKNESS:this.#qi(e);break;case s.AnnotationEditorParamsType.INK_COLOR:this.#Ve(e);break;case s.AnnotationEditorParamsType.INK_OPACITY:this.#Vi(e)}}static get defaultPropertiesToUpdate(){return[[s.AnnotationEditorParamsType.INK_THICKNESS,InkEditor._defaultThickness],[s.AnnotationEditorParamsType.INK_COLOR,InkEditor._defaultColor||n.AnnotationEditor._defaultLineColor],[s.AnnotationEditorParamsType.INK_OPACITY,Math.round(100*InkEditor._defaultOpacity)]]}get propertiesToUpdate(){return[[s.AnnotationEditorParamsType.INK_THICKNESS,this.thickness||InkEditor._defaultThickness],[s.AnnotationEditorParamsType.INK_COLOR,this.color||InkEditor._defaultColor||n.AnnotationEditor._defaultLineColor],[s.AnnotationEditorParamsType.INK_OPACITY,Math.round(100*(this.opacity??InkEditor._defaultOpacity))]]}#qi(t){const e=this.thickness;this.addCommands({cmd:()=>{this.thickness=t;this.#$i()},undo:()=>{this.thickness=e;this.#$i()},mustExec:!0,type:s.AnnotationEditorParamsType.INK_THICKNESS,overwriteIfSameType:!0,keepUndo:!0})}#Ve(t){const e=this.color;this.addCommands({cmd:()=>{this.color=t;this.#Xi()},undo:()=>{this.color=e;this.#Xi()},mustExec:!0,type:s.AnnotationEditorParamsType.INK_COLOR,overwriteIfSameType:!0,keepUndo:!0})}#Vi(t){t/=100;const e=this.opacity;this.addCommands({cmd:()=>{this.opacity=t;this.#Xi()},undo:()=>{this.opacity=e;this.#Xi()},mustExec:!0,type:s.AnnotationEditorParamsType.INK_OPACITY,overwriteIfSameType:!0,keepUndo:!0})}rebuild(){if(this.parent){super.rebuild();if(null!==this.div){if(!this.canvas){this.#Ki();this.#Yi()}if(!this.isAttachedToDOM){this.parent.add(this);this.#Ji()}this.#$i()}}}remove(){if(null!==this.canvas){this.isEmpty()||this.commit();this.canvas.width=this.canvas.height=0;this.canvas.remove();this.canvas=null;this.#zi.disconnect();this.#zi=null;super.remove()}}setParent(t){!this.parent&&t?this._uiManager.removeShouldRescale(this):this.parent&&null===t&&this._uiManager.addShouldRescale(this);super.setParent(t)}onScaleChanging(){const[t,e]=this.parentDimensions,i=this.width*t,s=this.height*e;this.setDimensions(i,s)}enableEditMode(){if(!this.#Bi&&null!==this.canvas){super.enableEditMode();this._isDraggable=!1;this.canvas.addEventListener("pointerdown",this.#Oi)}}disableEditMode(){if(this.isInEditMode()&&null!==this.canvas){super.disableEditMode();this._isDraggable=!this.isEmpty();this.div.classList.remove("editing");this.canvas.removeEventListener("pointerdown",this.#Oi)}}onceAdded(){this._isDraggable=!this.isEmpty()}isEmpty(){return 0===this.paths.length||1===this.paths.length&&0===this.paths[0].length}#Qi(){const{parentRotation:t,parentDimensions:[e,i]}=this;switch(t){case 90:return[0,i,i,e];case 180:return[e,i,e,i];case 270:return[e,0,i,e];default:return[0,0,e,i]}}#Zi(){const{ctx:t,color:e,opacity:i,thickness:s,parentScale:n,scaleFactor:a}=this;t.lineWidth=s*n/a;t.lineCap="round";t.lineJoin="round";t.miterLimit=10;t.strokeStyle=`${e}${(0,o.opacityToHex)(i)}`}#ts(t,e){this.canvas.addEventListener("contextmenu",r.noContextMenu);this.canvas.addEventListener("pointerleave",this.#Ii);this.canvas.addEventListener("pointermove",this.#Di);this.canvas.addEventListener("pointerup",this.#Li);this.canvas.removeEventListener("pointerdown",this.#Oi);this.isEditing=!0;if(!this.#ji){this.#ji=!0;this.#Ji();this.thickness||=InkEditor._defaultThickness;this.color||=InkEditor._defaultColor||n.AnnotationEditor._defaultLineColor;this.opacity??=InkEditor._defaultOpacity}this.currentPath.push([t,e]);this.#Ui=!1;this.#Zi();this.#Gi=()=>{this.#es();this.#Gi&&window.requestAnimationFrame(this.#Gi)};window.requestAnimationFrame(this.#Gi)}#is(t,e){const[i,s]=this.currentPath.at(-1);if(this.currentPath.length>1&&t===i&&e===s)return;const n=this.currentPath;let a=this.#Ni;n.push([t,e]);this.#Ui=!0;if(n.length<=2){a.moveTo(...n[0]);a.lineTo(t,e)}else{if(3===n.length){this.#Ni=a=new Path2D;a.moveTo(...n[0])}this.#ss(a,...n.at(-3),...n.at(-2),t,e)}}#ns(){if(0===this.currentPath.length)return;const t=this.currentPath.at(-1);this.#Ni.lineTo(...t)}#as(t,e){this.#Gi=null;t=Math.min(Math.max(t,0),this.canvas.width);e=Math.min(Math.max(e,0),this.canvas.height);this.#is(t,e);this.#ns();let i;if(1!==this.currentPath.length)i=this.#rs();else{const s=[t,e];i=[[s,s.slice(),s.slice(),s]]}const s=this.#Ni,n=this.currentPath;this.currentPath=[];this.#Ni=new Path2D;this.addCommands({cmd:()=>{this.allRawPaths.push(n);this.paths.push(i);this.bezierPath2D.push(s);this.rebuild()},undo:()=>{this.allRawPaths.pop();this.paths.pop();this.bezierPath2D.pop();if(0===this.paths.length)this.remove();else{if(!this.canvas){this.#Ki();this.#Yi()}this.#$i()}},mustExec:!0})}#es(){if(!this.#Ui)return;this.#Ui=!1;const t=Math.ceil(this.thickness*this.parentScale),e=this.currentPath.slice(-3),i=e.map((t=>t[0])),s=e.map((t=>t[1])),{ctx:n}=(Math.min(...i),Math.max(...i),Math.min(...s),Math.max(...s),this);n.save();n.clearRect(0,0,this.canvas.width,this.canvas.height);for(const t of this.bezierPath2D)n.stroke(t);n.stroke(this.#Ni);n.restore()}#ss(t,e,i,s,n,a,r){const o=(e+s)/2,l=(i+n)/2,h=(s+a)/2,c=(n+r)/2;t.bezierCurveTo(o+2*(s-o)/3,l+2*(n-l)/3,h+2*(s-h)/3,c+2*(n-c)/3,h,c)}#rs(){const t=this.currentPath;if(t.length<=2)return[[t[0],t[0],t.at(-1),t.at(-1)]];const e=[];let i,[s,n]=t[0];for(i=1;i{this.canvas.removeEventListener("contextmenu",r.noContextMenu)}),10);this.#as(t.offsetX,t.offsetY);this.addToAnnotationStorage();this.setInBackground()}#Ki(){this.canvas=document.createElement("canvas");this.canvas.width=this.canvas.height=0;this.canvas.className="inkEditorCanvas";n.AnnotationEditor._l10nPromise.get("editor_ink_canvas_aria_label").then((t=>this.canvas?.setAttribute("aria-label",t)));this.div.append(this.canvas);this.ctx=this.canvas.getContext("2d")}#Yi(){this.#zi=new ResizeObserver((t=>{const e=t[0].contentRect;e.width&&e.height&&this.setDimensions(e.width,e.height)}));this.#zi.observe(this.div)}get isResizable(){return!this.isEmpty()&&this.#Bi}render(){if(this.div)return this.div;let t,e;if(this.width){t=this.x;e=this.y}super.render();n.AnnotationEditor._l10nPromise.get("editor_ink2_aria_label").then((t=>this.div?.setAttribute("aria-label",t)));const[i,s,a,r]=this.#Qi();this.setAt(i,s,0,0);this.setDims(a,r);this.#Ki();if(this.width){const[i,s]=this.parentDimensions;this.setAspectRatio(this.width*i,this.height*s);this.setAt(t*i,e*s,this.width*i,this.height*s);this.#ji=!0;this.#Ji();this.setDims(this.width*i,this.height*s);this.#Xi();this.div.classList.add("disabled")}else{this.div.classList.add("editing");this.enableEditMode()}this.#Yi();return this.div}#Ji(){if(!this.#ji)return;const[t,e]=this.parentDimensions;this.canvas.width=Math.ceil(this.width*t);this.canvas.height=Math.ceil(this.height*e);this.#os()}setDimensions(t,e){const i=Math.round(t),s=Math.round(e);if(this.#Hi===i&&this.#Wi===s)return;this.#Hi=i;this.#Wi=s;this.canvas.style.visibility="hidden";const[n,a]=this.parentDimensions;this.width=t/n;this.height=e/a;this.fixAndSetPosition();this.#Bi&&this.#hs(t,e);this.#Ji();this.#Xi();this.canvas.style.visibility="visible";this.fixDims()}#hs(t,e){const i=this.#cs(),s=(t-i)/this.#Ri,n=(e-i)/this.#Fi;this.scaleFactor=Math.min(s,n)}#os(){const t=this.#cs()/2;this.ctx.setTransform(this.scaleFactor,0,0,this.scaleFactor,this.translationX*this.scaleFactor+t,this.translationY*this.scaleFactor+t)}static#ds(t){const e=new Path2D;for(let i=0,s=t.length;i{Object.defineProperty(e,"__esModule",{value:!0});e.StampEditor=void 0;var s=i(1),n=i(4),a=i(6),r=i(29);class StampEditor extends n.AnnotationEditor{#fs=null;#bs=null;#As=null;#_s=null;#vs=null;#ys=null;#zi=null;#Ss=null;#Es=!1;#xs=!1;static _type="stamp";constructor(t){super({...t,name:"stampEditor"});this.#_s=t.bitmapUrl;this.#vs=t.bitmapFile}static initialize(t){n.AnnotationEditor.initialize(t)}static get supportedTypes(){return(0,s.shadow)(this,"supportedTypes",["apng","avif","bmp","gif","jpeg","png","svg+xml","webp","x-icon"].map((t=>`image/${t}`)))}static get supportedTypesStr(){return(0,s.shadow)(this,"supportedTypesStr",this.supportedTypes.join(","))}static isHandlingMimeForPasting(t){return this.supportedTypes.includes(t)}static paste(t,e){e.pasteEditor(s.AnnotationEditorType.STAMP,{bitmapFile:t.getAsFile()})}#ws(t,e=!1){if(t){this.#fs=t.bitmap;if(!e){this.#bs=t.id;this.#Es=t.isSvg}this.#Ki()}else this.remove()}#Cs(){this.#As=null;this._uiManager.enableWaiting(!1);this.#ys&&this.div.focus()}#Ts(){if(this.#bs){this._uiManager.enableWaiting(!0);this._uiManager.imageManager.getFromId(this.#bs).then((t=>this.#ws(t,!0))).finally((()=>this.#Cs()));return}if(this.#_s){const t=this.#_s;this.#_s=null;this._uiManager.enableWaiting(!0);this.#As=this._uiManager.imageManager.getFromUrl(t).then((t=>this.#ws(t))).finally((()=>this.#Cs()));return}if(this.#vs){const t=this.#vs;this.#vs=null;this._uiManager.enableWaiting(!0);this.#As=this._uiManager.imageManager.getFromFile(t).then((t=>this.#ws(t))).finally((()=>this.#Cs()));return}const t=document.createElement("input");t.type="file";t.accept=StampEditor.supportedTypesStr;this.#As=new Promise((e=>{t.addEventListener("change",(async()=>{if(t.files&&0!==t.files.length){this._uiManager.enableWaiting(!0);const e=await this._uiManager.imageManager.getFromFile(t.files[0]);this.#ws(e)}else this.remove();e()}));t.addEventListener("cancel",(()=>{this.remove();e()}))})).finally((()=>this.#Cs()));t.click()}remove(){if(this.#bs){this.#fs=null;this._uiManager.imageManager.deleteId(this.#bs);this.#ys?.remove();this.#ys=null;this.#zi?.disconnect();this.#zi=null}super.remove()}rebuild(){if(this.parent){super.rebuild();if(null!==this.div){this.#bs&&this.#Ts();this.isAttachedToDOM||this.parent.add(this)}}else this.#bs&&this.#Ts()}onceAdded(){this._isDraggable=!0;this.div.focus()}isEmpty(){return!(this.#As||this.#fs||this.#_s||this.#vs)}get isResizable(){return!0}render(){if(this.div)return this.div;let t,e;if(this.width){t=this.x;e=this.y}super.render();this.div.hidden=!0;this.#fs?this.#Ki():this.#Ts();if(this.width){const[i,s]=this.parentDimensions;this.setAt(t*i,e*s,this.width*i,this.height*s)}return this.div}#Ki(){const{div:t}=this;let{width:e,height:i}=this.#fs;const[s,n]=this.pageDimensions,a=.75;if(this.width){e=this.width*s;i=this.height*n}else if(e>a*s||i>a*n){const t=Math.min(a*s/e,a*n/i);e*=t;i*=t}const[r,o]=this.parentDimensions;this.setDims(e*r/s,i*o/n);this._uiManager.enableWaiting(!1);const l=this.#ys=document.createElement("canvas");t.append(l);t.hidden=!1;this.#Ps(e,i);this.#Yi();if(!this.#xs){this.parent.addUndoableEditor(this);this.#xs=!0}this._uiManager._eventBus.dispatch("reporttelemetry",{source:this,details:{type:"editing",subtype:this.editorType,data:{action:"inserted_image"}}});this.addAltTextButton()}#Ms(t,e){const[i,s]=this.parentDimensions;this.width=t/i;this.height=e/s;this.setDims(t,e);this._initialOptions?.isCentered?this.center():this.fixAndSetPosition();this._initialOptions=null;null!==this.#Ss&&clearTimeout(this.#Ss);this.#Ss=setTimeout((()=>{this.#Ss=null;this.#Ps(t,e)}),200)}#ks(t,e){const{width:i,height:s}=this.#fs;let n=i,a=s,r=this.#fs;for(;n>2*t||a>2*e;){const i=n,s=a;n>2*t&&(n=n>=16384?Math.floor(n/2)-1:Math.ceil(n/2));a>2*e&&(a=a>=16384?Math.floor(a/2)-1:Math.ceil(a/2));const o=new OffscreenCanvas(n,a);o.getContext("2d").drawImage(r,0,0,i,s,0,0,n,a);r=o.transferToImageBitmap()}return r}#Ps(t,e){t=Math.ceil(t);e=Math.ceil(e);const i=this.#ys;if(!i||i.width===t&&i.height===e)return;i.width=t;i.height=e;const s=this.#Es?this.#fs:this.#ks(t,e),n=i.getContext("2d");n.filter=this._uiManager.hcmFilter;n.drawImage(s,0,0,s.width,s.height,0,0,t,e)}#Fs(t){if(t){if(this.#Es){const t=this._uiManager.imageManager.getSvgUrl(this.#bs);if(t)return t}const t=document.createElement("canvas");({width:t.width,height:t.height}=this.#fs);t.getContext("2d").drawImage(this.#fs,0,0);return t.toDataURL()}if(this.#Es){const[t,e]=this.pageDimensions,i=Math.round(this.width*t*a.PixelsPerInch.PDF_TO_CSS_UNITS),s=Math.round(this.height*e*a.PixelsPerInch.PDF_TO_CSS_UNITS),n=new OffscreenCanvas(i,s);n.getContext("2d").drawImage(this.#fs,0,0,this.#fs.width,this.#fs.height,0,0,i,s);return n.transferToImageBitmap()}return structuredClone(this.#fs)}#Yi(){this.#zi=new ResizeObserver((t=>{const e=t[0].contentRect;e.width&&e.height&&this.#Ms(e.width,e.height)}));this.#zi.observe(this.div)}static deserialize(t,e,i){if(t instanceof r.StampAnnotationElement)return null;const s=super.deserialize(t,e,i),{rect:n,bitmapUrl:a,bitmapId:o,isSvg:l,accessibilityData:h}=t;o&&i.imageManager.isValidId(o)?s.#bs=o:s.#_s=a;s.#Es=l;const[c,d]=s.pageDimensions;s.width=(n[2]-n[0])/c;s.height=(n[3]-n[1])/d;h&&(s.altTextData=h);return s}serialize(t=!1,e=null){if(this.isEmpty())return null;const i={annotationType:s.AnnotationEditorType.STAMP,bitmapId:this.#bs,pageIndex:this.pageIndex,rect:this.getRect(0,0),rotation:this.rotation,isSvg:this.#Es,structTreeParentId:this._structTreeParentId};if(t){i.bitmapUrl=this.#Fs(!0);i.accessibilityData=this.altTextData;return i}const{decorative:n,altText:a}=this.altTextData;!n&&a&&(i.accessibilityData={type:"Figure",alt:a});if(null===e)return i;e.stamps||=new Map;const r=this.#Es?(i.rect[2]-i.rect[0])*(i.rect[3]-i.rect[1]):null;if(e.stamps.has(this.#bs)){if(this.#Es){const t=e.stamps.get(this.#bs);if(r>t.area){t.area=r;t.serialized.bitmap.close();t.serialized.bitmap=this.#Fs(!1)}}}else{e.stamps.set(this.#bs,{area:r,serialized:i});i.bitmap=this.#Fs(!1)}return i}}e.StampEditor=StampEditor}],__webpack_module_cache__={};function __w_pdfjs_require__(t){var e=__webpack_module_cache__[t];if(void 0!==e)return e.exports;var i=__webpack_module_cache__[t]={exports:{}};__webpack_modules__[t](i,i.exports,__w_pdfjs_require__);return i.exports}var __webpack_exports__={};(()=>{var t=__webpack_exports__;Object.defineProperty(t,"__esModule",{value:!0});Object.defineProperty(t,"AbortException",{enumerable:!0,get:function(){return e.AbortException}});Object.defineProperty(t,"AnnotationEditorLayer",{enumerable:!0,get:function(){return a.AnnotationEditorLayer}});Object.defineProperty(t,"AnnotationEditorParamsType",{enumerable:!0,get:function(){return e.AnnotationEditorParamsType}});Object.defineProperty(t,"AnnotationEditorType",{enumerable:!0,get:function(){return e.AnnotationEditorType}});Object.defineProperty(t,"AnnotationEditorUIManager",{enumerable:!0,get:function(){return r.AnnotationEditorUIManager}});Object.defineProperty(t,"AnnotationLayer",{enumerable:!0,get:function(){return o.AnnotationLayer}});Object.defineProperty(t,"AnnotationMode",{enumerable:!0,get:function(){return e.AnnotationMode}});Object.defineProperty(t,"CMapCompressionType",{enumerable:!0,get:function(){return e.CMapCompressionType}});Object.defineProperty(t,"DOMSVGFactory",{enumerable:!0,get:function(){return s.DOMSVGFactory}});Object.defineProperty(t,"FeatureTest",{enumerable:!0,get:function(){return e.FeatureTest}});Object.defineProperty(t,"GlobalWorkerOptions",{enumerable:!0,get:function(){return l.GlobalWorkerOptions}});Object.defineProperty(t,"ImageKind",{enumerable:!0,get:function(){return e.ImageKind}});Object.defineProperty(t,"InvalidPDFException",{enumerable:!0,get:function(){return e.InvalidPDFException}});Object.defineProperty(t,"MissingPDFException",{enumerable:!0,get:function(){return e.MissingPDFException}});Object.defineProperty(t,"OPS",{enumerable:!0,get:function(){return e.OPS}});Object.defineProperty(t,"PDFDataRangeTransport",{enumerable:!0,get:function(){return i.PDFDataRangeTransport}});Object.defineProperty(t,"PDFDateString",{enumerable:!0,get:function(){return s.PDFDateString}});Object.defineProperty(t,"PDFWorker",{enumerable:!0,get:function(){return i.PDFWorker}});Object.defineProperty(t,"PasswordResponses",{enumerable:!0,get:function(){return e.PasswordResponses}});Object.defineProperty(t,"PermissionFlag",{enumerable:!0,get:function(){return e.PermissionFlag}});Object.defineProperty(t,"PixelsPerInch",{enumerable:!0,get:function(){return s.PixelsPerInch}});Object.defineProperty(t,"PromiseCapability",{enumerable:!0,get:function(){return e.PromiseCapability}});Object.defineProperty(t,"RenderingCancelledException",{enumerable:!0,get:function(){return s.RenderingCancelledException}});Object.defineProperty(t,"SVGGraphics",{enumerable:!0,get:function(){return i.SVGGraphics}});Object.defineProperty(t,"UnexpectedResponseException",{enumerable:!0,get:function(){return e.UnexpectedResponseException}});Object.defineProperty(t,"Util",{enumerable:!0,get:function(){return e.Util}});Object.defineProperty(t,"VerbosityLevel",{enumerable:!0,get:function(){return e.VerbosityLevel}});Object.defineProperty(t,"XfaLayer",{enumerable:!0,get:function(){return h.XfaLayer}});Object.defineProperty(t,"build",{enumerable:!0,get:function(){return i.build}});Object.defineProperty(t,"createValidAbsoluteUrl",{enumerable:!0,get:function(){return e.createValidAbsoluteUrl}});Object.defineProperty(t,"getDocument",{enumerable:!0,get:function(){return i.getDocument}});Object.defineProperty(t,"getFilenameFromUrl",{enumerable:!0,get:function(){return s.getFilenameFromUrl}});Object.defineProperty(t,"getPdfFilenameFromUrl",{enumerable:!0,get:function(){return s.getPdfFilenameFromUrl}});Object.defineProperty(t,"getXfaPageViewport",{enumerable:!0,get:function(){return s.getXfaPageViewport}});Object.defineProperty(t,"isDataScheme",{enumerable:!0,get:function(){return s.isDataScheme}});Object.defineProperty(t,"isPdfFile",{enumerable:!0,get:function(){return s.isPdfFile}});Object.defineProperty(t,"loadScript",{enumerable:!0,get:function(){return s.loadScript}});Object.defineProperty(t,"noContextMenu",{enumerable:!0,get:function(){return s.noContextMenu}});Object.defineProperty(t,"normalizeUnicode",{enumerable:!0,get:function(){return e.normalizeUnicode}});Object.defineProperty(t,"renderTextLayer",{enumerable:!0,get:function(){return n.renderTextLayer}});Object.defineProperty(t,"setLayerDimensions",{enumerable:!0,get:function(){return s.setLayerDimensions}});Object.defineProperty(t,"shadow",{enumerable:!0,get:function(){return e.shadow}});Object.defineProperty(t,"updateTextLayer",{enumerable:!0,get:function(){return n.updateTextLayer}});Object.defineProperty(t,"version",{enumerable:!0,get:function(){return i.version}});var e=__w_pdfjs_require__(1),i=__w_pdfjs_require__(2),s=__w_pdfjs_require__(6),n=__w_pdfjs_require__(26),a=__w_pdfjs_require__(27),r=__w_pdfjs_require__(5),o=__w_pdfjs_require__(29),l=__w_pdfjs_require__(14),h=__w_pdfjs_require__(32)})();return __webpack_exports__})())); \ No newline at end of file diff --git a/frontend/public/pdf.worker.js b/frontend/public/pdf.worker.js new file mode 100644 index 000000000..ac3d027f8 --- /dev/null +++ b/frontend/public/pdf.worker.js @@ -0,0 +1,58353 @@ +/** + * @licstart The following is the entire license notice for the + * JavaScript code in this page + * + * Copyright 2023 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @licend The above is the entire license notice for the + * JavaScript code in this page + */ + +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = root.pdfjsWorker = factory(); + else if(typeof define === 'function' && define.amd) + define("pdfjs-dist/build/pdf.worker", [], () => { return (root.pdfjsWorker = factory()); }); + else if(typeof exports === 'object') + exports["pdfjs-dist/build/pdf.worker"] = root.pdfjsWorker = factory(); + else + root["pdfjs-dist/build/pdf.worker"] = root.pdfjsWorker = factory(); +})(globalThis, () => { +return /******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ([ +/* 0 */, +/* 1 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.WorkerTask = exports.WorkerMessageHandler = void 0; +var _util = __w_pdfjs_require__(2); +var _core_utils = __w_pdfjs_require__(3); +var _primitives = __w_pdfjs_require__(4); +var _pdf_manager = __w_pdfjs_require__(6); +var _annotation = __w_pdfjs_require__(10); +var _cleanup_helper = __w_pdfjs_require__(68); +var _writer = __w_pdfjs_require__(73); +var _message_handler = __w_pdfjs_require__(104); +var _worker_stream = __w_pdfjs_require__(105); +var _struct_tree = __w_pdfjs_require__(72); +class WorkerTask { + constructor(name) { + this.name = name; + this.terminated = false; + this._capability = new _util.PromiseCapability(); + } + get finished() { + return this._capability.promise; + } + finish() { + this._capability.resolve(); + } + terminate() { + this.terminated = true; + } + ensureNotTerminated() { + if (this.terminated) { + throw new Error("Worker task was terminated"); + } + } +} +exports.WorkerTask = WorkerTask; +class WorkerMessageHandler { + static setup(handler, port) { + let testMessageProcessed = false; + handler.on("test", function (data) { + if (testMessageProcessed) { + return; + } + testMessageProcessed = true; + handler.send("test", data instanceof Uint8Array); + }); + handler.on("configure", function (data) { + (0, _util.setVerbosityLevel)(data.verbosity); + }); + handler.on("GetDocRequest", function (data) { + return WorkerMessageHandler.createDocumentHandler(data, port); + }); + } + static createDocumentHandler(docParams, port) { + let pdfManager; + let terminated = false; + let cancelXHRs = null; + const WorkerTasks = new Set(); + const verbosity = (0, _util.getVerbosityLevel)(); + const { + docId, + apiVersion + } = docParams; + const workerVersion = '3.11.174'; + if (apiVersion !== workerVersion) { + throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`); + } + const enumerableProperties = []; + for (const property in []) { + enumerableProperties.push(property); + } + if (enumerableProperties.length) { + throw new Error("The `Array.prototype` contains unexpected enumerable properties: " + enumerableProperties.join(", ") + "; thus breaking e.g. `for...in` iteration of `Array`s."); + } + const workerHandlerName = docId + "_worker"; + let handler = new _message_handler.MessageHandler(workerHandlerName, docId, port); + function ensureNotTerminated() { + if (terminated) { + throw new Error("Worker was terminated"); + } + } + function startWorkerTask(task) { + WorkerTasks.add(task); + } + function finishWorkerTask(task) { + task.finish(); + WorkerTasks.delete(task); + } + async function loadDocument(recoveryMode) { + await pdfManager.ensureDoc("checkHeader"); + await pdfManager.ensureDoc("parseStartXRef"); + await pdfManager.ensureDoc("parse", [recoveryMode]); + await pdfManager.ensureDoc("checkFirstPage", [recoveryMode]); + await pdfManager.ensureDoc("checkLastPage", [recoveryMode]); + const isPureXfa = await pdfManager.ensureDoc("isPureXfa"); + if (isPureXfa) { + const task = new WorkerTask("loadXfaFonts"); + startWorkerTask(task); + await Promise.all([pdfManager.loadXfaFonts(handler, task).catch(reason => {}).then(() => finishWorkerTask(task)), pdfManager.loadXfaImages()]); + } + const [numPages, fingerprints] = await Promise.all([pdfManager.ensureDoc("numPages"), pdfManager.ensureDoc("fingerprints")]); + const htmlForXfa = isPureXfa ? await pdfManager.ensureDoc("htmlForXfa") : null; + return { + numPages, + fingerprints, + htmlForXfa + }; + } + function getPdfManager({ + data, + password, + disableAutoFetch, + rangeChunkSize, + length, + docBaseUrl, + enableXfa, + evaluatorOptions + }) { + const pdfManagerArgs = { + source: null, + disableAutoFetch, + docBaseUrl, + docId, + enableXfa, + evaluatorOptions, + handler, + length, + password, + rangeChunkSize + }; + const pdfManagerCapability = new _util.PromiseCapability(); + let newPdfManager; + if (data) { + try { + pdfManagerArgs.source = data; + newPdfManager = new _pdf_manager.LocalPdfManager(pdfManagerArgs); + pdfManagerCapability.resolve(newPdfManager); + } catch (ex) { + pdfManagerCapability.reject(ex); + } + return pdfManagerCapability.promise; + } + let pdfStream, + cachedChunks = []; + try { + pdfStream = new _worker_stream.PDFWorkerStream(handler); + } catch (ex) { + pdfManagerCapability.reject(ex); + return pdfManagerCapability.promise; + } + const fullRequest = pdfStream.getFullReader(); + fullRequest.headersReady.then(function () { + if (!fullRequest.isRangeSupported) { + return; + } + pdfManagerArgs.source = pdfStream; + pdfManagerArgs.length = fullRequest.contentLength; + pdfManagerArgs.disableAutoFetch ||= fullRequest.isStreamingSupported; + newPdfManager = new _pdf_manager.NetworkPdfManager(pdfManagerArgs); + for (const chunk of cachedChunks) { + newPdfManager.sendProgressiveData(chunk); + } + cachedChunks = []; + pdfManagerCapability.resolve(newPdfManager); + cancelXHRs = null; + }).catch(function (reason) { + pdfManagerCapability.reject(reason); + cancelXHRs = null; + }); + let loaded = 0; + const flushChunks = function () { + const pdfFile = (0, _core_utils.arrayBuffersToBytes)(cachedChunks); + if (length && pdfFile.length !== length) { + (0, _util.warn)("reported HTTP length is different from actual"); + } + try { + pdfManagerArgs.source = pdfFile; + newPdfManager = new _pdf_manager.LocalPdfManager(pdfManagerArgs); + pdfManagerCapability.resolve(newPdfManager); + } catch (ex) { + pdfManagerCapability.reject(ex); + } + cachedChunks = []; + }; + new Promise(function (resolve, reject) { + const readChunk = function ({ + value, + done + }) { + try { + ensureNotTerminated(); + if (done) { + if (!newPdfManager) { + flushChunks(); + } + cancelXHRs = null; + return; + } + loaded += value.byteLength; + if (!fullRequest.isStreamingSupported) { + handler.send("DocProgress", { + loaded, + total: Math.max(loaded, fullRequest.contentLength || 0) + }); + } + if (newPdfManager) { + newPdfManager.sendProgressiveData(value); + } else { + cachedChunks.push(value); + } + fullRequest.read().then(readChunk, reject); + } catch (e) { + reject(e); + } + }; + fullRequest.read().then(readChunk, reject); + }).catch(function (e) { + pdfManagerCapability.reject(e); + cancelXHRs = null; + }); + cancelXHRs = function (reason) { + pdfStream.cancelAllRequests(reason); + }; + return pdfManagerCapability.promise; + } + function setupDoc(data) { + function onSuccess(doc) { + ensureNotTerminated(); + handler.send("GetDoc", { + pdfInfo: doc + }); + } + function onFailure(ex) { + ensureNotTerminated(); + if (ex instanceof _util.PasswordException) { + const task = new WorkerTask(`PasswordException: response ${ex.code}`); + startWorkerTask(task); + handler.sendWithPromise("PasswordRequest", ex).then(function ({ + password + }) { + finishWorkerTask(task); + pdfManager.updatePassword(password); + pdfManagerReady(); + }).catch(function () { + finishWorkerTask(task); + handler.send("DocException", ex); + }); + } else if (ex instanceof _util.InvalidPDFException || ex instanceof _util.MissingPDFException || ex instanceof _util.UnexpectedResponseException || ex instanceof _util.UnknownErrorException) { + handler.send("DocException", ex); + } else { + handler.send("DocException", new _util.UnknownErrorException(ex.message, ex.toString())); + } + } + function pdfManagerReady() { + ensureNotTerminated(); + loadDocument(false).then(onSuccess, function (reason) { + ensureNotTerminated(); + if (!(reason instanceof _core_utils.XRefParseException)) { + onFailure(reason); + return; + } + pdfManager.requestLoadedStream().then(function () { + ensureNotTerminated(); + loadDocument(true).then(onSuccess, onFailure); + }); + }); + } + ensureNotTerminated(); + getPdfManager(data).then(function (newPdfManager) { + if (terminated) { + newPdfManager.terminate(new _util.AbortException("Worker was terminated.")); + throw new Error("Worker was terminated"); + } + pdfManager = newPdfManager; + pdfManager.requestLoadedStream(true).then(stream => { + handler.send("DataLoaded", { + length: stream.bytes.byteLength + }); + }); + }).then(pdfManagerReady, onFailure); + } + handler.on("GetPage", function (data) { + return pdfManager.getPage(data.pageIndex).then(function (page) { + return Promise.all([pdfManager.ensure(page, "rotate"), pdfManager.ensure(page, "ref"), pdfManager.ensure(page, "userUnit"), pdfManager.ensure(page, "view")]).then(function ([rotate, ref, userUnit, view]) { + return { + rotate, + ref, + userUnit, + view + }; + }); + }); + }); + handler.on("GetPageIndex", function (data) { + const pageRef = _primitives.Ref.get(data.num, data.gen); + return pdfManager.ensureCatalog("getPageIndex", [pageRef]); + }); + handler.on("GetDestinations", function (data) { + return pdfManager.ensureCatalog("destinations"); + }); + handler.on("GetDestination", function (data) { + return pdfManager.ensureCatalog("getDestination", [data.id]); + }); + handler.on("GetPageLabels", function (data) { + return pdfManager.ensureCatalog("pageLabels"); + }); + handler.on("GetPageLayout", function (data) { + return pdfManager.ensureCatalog("pageLayout"); + }); + handler.on("GetPageMode", function (data) { + return pdfManager.ensureCatalog("pageMode"); + }); + handler.on("GetViewerPreferences", function (data) { + return pdfManager.ensureCatalog("viewerPreferences"); + }); + handler.on("GetOpenAction", function (data) { + return pdfManager.ensureCatalog("openAction"); + }); + handler.on("GetAttachments", function (data) { + return pdfManager.ensureCatalog("attachments"); + }); + handler.on("GetDocJSActions", function (data) { + return pdfManager.ensureCatalog("jsActions"); + }); + handler.on("GetPageJSActions", function ({ + pageIndex + }) { + return pdfManager.getPage(pageIndex).then(function (page) { + return pdfManager.ensure(page, "jsActions"); + }); + }); + handler.on("GetOutline", function (data) { + return pdfManager.ensureCatalog("documentOutline"); + }); + handler.on("GetOptionalContentConfig", function (data) { + return pdfManager.ensureCatalog("optionalContentConfig"); + }); + handler.on("GetPermissions", function (data) { + return pdfManager.ensureCatalog("permissions"); + }); + handler.on("GetMetadata", function (data) { + return Promise.all([pdfManager.ensureDoc("documentInfo"), pdfManager.ensureCatalog("metadata")]); + }); + handler.on("GetMarkInfo", function (data) { + return pdfManager.ensureCatalog("markInfo"); + }); + handler.on("GetData", function (data) { + return pdfManager.requestLoadedStream().then(function (stream) { + return stream.bytes; + }); + }); + handler.on("GetAnnotations", function ({ + pageIndex, + intent + }) { + return pdfManager.getPage(pageIndex).then(function (page) { + const task = new WorkerTask(`GetAnnotations: page ${pageIndex}`); + startWorkerTask(task); + return page.getAnnotationsData(handler, task, intent).then(data => { + finishWorkerTask(task); + return data; + }, reason => { + finishWorkerTask(task); + throw reason; + }); + }); + }); + handler.on("GetFieldObjects", function (data) { + return pdfManager.ensureDoc("fieldObjects"); + }); + handler.on("HasJSActions", function (data) { + return pdfManager.ensureDoc("hasJSActions"); + }); + handler.on("GetCalculationOrderIds", function (data) { + return pdfManager.ensureDoc("calculationOrderIds"); + }); + handler.on("SaveDocument", async function ({ + isPureXfa, + numPages, + annotationStorage, + filename + }) { + const globalPromises = [pdfManager.requestLoadedStream(), pdfManager.ensureCatalog("acroForm"), pdfManager.ensureCatalog("acroFormRef"), pdfManager.ensureDoc("startXRef"), pdfManager.ensureDoc("xref"), pdfManager.ensureDoc("linearization"), pdfManager.ensureCatalog("structTreeRoot")]; + const promises = []; + const newAnnotationsByPage = !isPureXfa ? (0, _core_utils.getNewAnnotationsMap)(annotationStorage) : null; + const [stream, acroForm, acroFormRef, startXRef, xref, linearization, _structTreeRoot] = await Promise.all(globalPromises); + const catalogRef = xref.trailer.getRaw("Root") || null; + let structTreeRoot; + if (newAnnotationsByPage) { + if (!_structTreeRoot) { + if (await _struct_tree.StructTreeRoot.canCreateStructureTree({ + catalogRef, + pdfManager, + newAnnotationsByPage + })) { + structTreeRoot = null; + } + } else if (await _structTreeRoot.canUpdateStructTree({ + pdfManager, + newAnnotationsByPage + })) { + structTreeRoot = _structTreeRoot; + } + const imagePromises = _annotation.AnnotationFactory.generateImages(annotationStorage.values(), xref, pdfManager.evaluatorOptions.isOffscreenCanvasSupported); + const newAnnotationPromises = structTreeRoot === undefined ? promises : []; + for (const [pageIndex, annotations] of newAnnotationsByPage) { + newAnnotationPromises.push(pdfManager.getPage(pageIndex).then(page => { + const task = new WorkerTask(`Save (editor): page ${pageIndex}`); + return page.saveNewAnnotations(handler, task, annotations, imagePromises).finally(function () { + finishWorkerTask(task); + }); + })); + } + if (structTreeRoot === null) { + promises.push(Promise.all(newAnnotationPromises).then(async newRefs => { + await _struct_tree.StructTreeRoot.createStructureTree({ + newAnnotationsByPage, + xref, + catalogRef, + pdfManager, + newRefs + }); + return newRefs; + })); + } else if (structTreeRoot) { + promises.push(Promise.all(newAnnotationPromises).then(async newRefs => { + await structTreeRoot.updateStructureTree({ + newAnnotationsByPage, + pdfManager, + newRefs + }); + return newRefs; + })); + } + } + if (isPureXfa) { + promises.push(pdfManager.serializeXfaData(annotationStorage)); + } else { + for (let pageIndex = 0; pageIndex < numPages; pageIndex++) { + promises.push(pdfManager.getPage(pageIndex).then(function (page) { + const task = new WorkerTask(`Save: page ${pageIndex}`); + return page.save(handler, task, annotationStorage).finally(function () { + finishWorkerTask(task); + }); + })); + } + } + const refs = await Promise.all(promises); + let newRefs = []; + let xfaData = null; + if (isPureXfa) { + xfaData = refs[0]; + if (!xfaData) { + return stream.bytes; + } + } else { + newRefs = refs.flat(2); + if (newRefs.length === 0) { + return stream.bytes; + } + } + const needAppearances = acroFormRef && acroForm instanceof _primitives.Dict && newRefs.some(ref => ref.needAppearances); + const xfa = acroForm instanceof _primitives.Dict && acroForm.get("XFA") || null; + let xfaDatasetsRef = null; + let hasXfaDatasetsEntry = false; + if (Array.isArray(xfa)) { + for (let i = 0, ii = xfa.length; i < ii; i += 2) { + if (xfa[i] === "datasets") { + xfaDatasetsRef = xfa[i + 1]; + hasXfaDatasetsEntry = true; + } + } + if (xfaDatasetsRef === null) { + xfaDatasetsRef = xref.getNewTemporaryRef(); + } + } else if (xfa) { + (0, _util.warn)("Unsupported XFA type."); + } + let newXrefInfo = Object.create(null); + if (xref.trailer) { + const infoObj = Object.create(null); + const xrefInfo = xref.trailer.get("Info") || null; + if (xrefInfo instanceof _primitives.Dict) { + xrefInfo.forEach((key, value) => { + if (typeof value === "string") { + infoObj[key] = (0, _util.stringToPDFString)(value); + } + }); + } + newXrefInfo = { + rootRef: catalogRef, + encryptRef: xref.trailer.getRaw("Encrypt") || null, + newRef: xref.getNewTemporaryRef(), + infoRef: xref.trailer.getRaw("Info") || null, + info: infoObj, + fileIds: xref.trailer.get("ID") || null, + startXRef: linearization ? startXRef : xref.lastXRefStreamPos ?? startXRef, + filename + }; + } + return (0, _writer.incrementalUpdate)({ + originalData: stream.bytes, + xrefInfo: newXrefInfo, + newRefs, + xref, + hasXfa: !!xfa, + xfaDatasetsRef, + hasXfaDatasetsEntry, + needAppearances, + acroFormRef, + acroForm, + xfaData + }).finally(() => { + xref.resetNewTemporaryRef(); + }); + }); + handler.on("GetOperatorList", function (data, sink) { + const pageIndex = data.pageIndex; + pdfManager.getPage(pageIndex).then(function (page) { + const task = new WorkerTask(`GetOperatorList: page ${pageIndex}`); + startWorkerTask(task); + const start = verbosity >= _util.VerbosityLevel.INFOS ? Date.now() : 0; + page.getOperatorList({ + handler, + sink, + task, + intent: data.intent, + cacheKey: data.cacheKey, + annotationStorage: data.annotationStorage + }).then(function (operatorListInfo) { + finishWorkerTask(task); + if (start) { + (0, _util.info)(`page=${pageIndex + 1} - getOperatorList: time=` + `${Date.now() - start}ms, len=${operatorListInfo.length}`); + } + sink.close(); + }, function (reason) { + finishWorkerTask(task); + if (task.terminated) { + return; + } + sink.error(reason); + }); + }); + }); + handler.on("GetTextContent", function (data, sink) { + const { + pageIndex, + includeMarkedContent, + disableNormalization + } = data; + pdfManager.getPage(pageIndex).then(function (page) { + const task = new WorkerTask("GetTextContent: page " + pageIndex); + startWorkerTask(task); + const start = verbosity >= _util.VerbosityLevel.INFOS ? Date.now() : 0; + page.extractTextContent({ + handler, + task, + sink, + includeMarkedContent, + disableNormalization + }).then(function () { + finishWorkerTask(task); + if (start) { + (0, _util.info)(`page=${pageIndex + 1} - getTextContent: time=` + `${Date.now() - start}ms`); + } + sink.close(); + }, function (reason) { + finishWorkerTask(task); + if (task.terminated) { + return; + } + sink.error(reason); + }); + }); + }); + handler.on("GetStructTree", function (data) { + return pdfManager.getPage(data.pageIndex).then(function (page) { + return pdfManager.ensure(page, "getStructTree"); + }); + }); + handler.on("FontFallback", function (data) { + return pdfManager.fontFallback(data.id, handler); + }); + handler.on("Cleanup", function (data) { + return pdfManager.cleanup(true); + }); + handler.on("Terminate", function (data) { + terminated = true; + const waitOn = []; + if (pdfManager) { + pdfManager.terminate(new _util.AbortException("Worker was terminated.")); + const cleanupPromise = pdfManager.cleanup(); + waitOn.push(cleanupPromise); + pdfManager = null; + } else { + (0, _cleanup_helper.clearGlobalCaches)(); + } + if (cancelXHRs) { + cancelXHRs(new _util.AbortException("Worker was terminated.")); + } + for (const task of WorkerTasks) { + waitOn.push(task.finished); + task.terminate(); + } + return Promise.all(waitOn).then(function () { + handler.destroy(); + handler = null; + }); + }); + handler.on("Ready", function (data) { + setupDoc(docParams); + docParams = null; + }); + return workerHandlerName; + } + static initializeFromPort(port) { + const handler = new _message_handler.MessageHandler("worker", "main", port); + WorkerMessageHandler.setup(handler, port); + handler.send("ready", null); + } +} +exports.WorkerMessageHandler = WorkerMessageHandler; +function isMessagePort(maybePort) { + return typeof maybePort.postMessage === "function" && "onmessage" in maybePort; +} +if (typeof window === "undefined" && !_util.isNodeJS && typeof self !== "undefined" && isMessagePort(self)) { + WorkerMessageHandler.initializeFromPort(self); +} + +/***/ }), +/* 2 */ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.RenderingIntentFlag = exports.PromiseCapability = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.MAX_IMAGE_SIZE_TO_CACHE = exports.LINE_FACTOR = exports.LINE_DESCENT_FACTOR = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FeatureTest = exports.FONT_IDENTITY_MATRIX = exports.DocumentActionEventType = exports.CMapCompressionType = exports.BaseException = exports.BASELINE_FACTOR = exports.AnnotationType = exports.AnnotationReplyType = exports.AnnotationPrefix = exports.AnnotationMode = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationEditorType = exports.AnnotationEditorPrefix = exports.AnnotationEditorParamsType = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0; +exports.assert = assert; +exports.bytesToString = bytesToString; +exports.createValidAbsoluteUrl = createValidAbsoluteUrl; +exports.getModificationDate = getModificationDate; +exports.getUuid = getUuid; +exports.getVerbosityLevel = getVerbosityLevel; +exports.info = info; +exports.isArrayBuffer = isArrayBuffer; +exports.isArrayEqual = isArrayEqual; +exports.isNodeJS = void 0; +exports.normalizeUnicode = normalizeUnicode; +exports.objectFromMap = objectFromMap; +exports.objectSize = objectSize; +exports.setVerbosityLevel = setVerbosityLevel; +exports.shadow = shadow; +exports.string32 = string32; +exports.stringToBytes = stringToBytes; +exports.stringToPDFString = stringToPDFString; +exports.stringToUTF8String = stringToUTF8String; +exports.unreachable = unreachable; +exports.utf8StringToString = utf8StringToString; +exports.warn = warn; +const isNodeJS = typeof process === "object" && process + "" === "[object process]" && !process.versions.nw && !(process.versions.electron && process.type && process.type !== "browser"); +exports.isNodeJS = isNodeJS; +const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; +exports.IDENTITY_MATRIX = IDENTITY_MATRIX; +const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0]; +exports.FONT_IDENTITY_MATRIX = FONT_IDENTITY_MATRIX; +const MAX_IMAGE_SIZE_TO_CACHE = 10e6; +exports.MAX_IMAGE_SIZE_TO_CACHE = MAX_IMAGE_SIZE_TO_CACHE; +const LINE_FACTOR = 1.35; +exports.LINE_FACTOR = LINE_FACTOR; +const LINE_DESCENT_FACTOR = 0.35; +exports.LINE_DESCENT_FACTOR = LINE_DESCENT_FACTOR; +const BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR; +exports.BASELINE_FACTOR = BASELINE_FACTOR; +const RenderingIntentFlag = { + ANY: 0x01, + DISPLAY: 0x02, + PRINT: 0x04, + SAVE: 0x08, + ANNOTATIONS_FORMS: 0x10, + ANNOTATIONS_STORAGE: 0x20, + ANNOTATIONS_DISABLE: 0x40, + OPLIST: 0x100 +}; +exports.RenderingIntentFlag = RenderingIntentFlag; +const AnnotationMode = { + DISABLE: 0, + ENABLE: 1, + ENABLE_FORMS: 2, + ENABLE_STORAGE: 3 +}; +exports.AnnotationMode = AnnotationMode; +const AnnotationEditorPrefix = "pdfjs_internal_editor_"; +exports.AnnotationEditorPrefix = AnnotationEditorPrefix; +const AnnotationEditorType = { + DISABLE: -1, + NONE: 0, + FREETEXT: 3, + STAMP: 13, + INK: 15 +}; +exports.AnnotationEditorType = AnnotationEditorType; +const AnnotationEditorParamsType = { + RESIZE: 1, + CREATE: 2, + FREETEXT_SIZE: 11, + FREETEXT_COLOR: 12, + FREETEXT_OPACITY: 13, + INK_COLOR: 21, + INK_THICKNESS: 22, + INK_OPACITY: 23 +}; +exports.AnnotationEditorParamsType = AnnotationEditorParamsType; +const PermissionFlag = { + PRINT: 0x04, + MODIFY_CONTENTS: 0x08, + COPY: 0x10, + MODIFY_ANNOTATIONS: 0x20, + FILL_INTERACTIVE_FORMS: 0x100, + COPY_FOR_ACCESSIBILITY: 0x200, + ASSEMBLE: 0x400, + PRINT_HIGH_QUALITY: 0x800 +}; +exports.PermissionFlag = PermissionFlag; +const TextRenderingMode = { + FILL: 0, + STROKE: 1, + FILL_STROKE: 2, + INVISIBLE: 3, + FILL_ADD_TO_PATH: 4, + STROKE_ADD_TO_PATH: 5, + FILL_STROKE_ADD_TO_PATH: 6, + ADD_TO_PATH: 7, + FILL_STROKE_MASK: 3, + ADD_TO_PATH_FLAG: 4 +}; +exports.TextRenderingMode = TextRenderingMode; +const ImageKind = { + GRAYSCALE_1BPP: 1, + RGB_24BPP: 2, + RGBA_32BPP: 3 +}; +exports.ImageKind = ImageKind; +const AnnotationType = { + TEXT: 1, + LINK: 2, + FREETEXT: 3, + LINE: 4, + SQUARE: 5, + CIRCLE: 6, + POLYGON: 7, + POLYLINE: 8, + HIGHLIGHT: 9, + UNDERLINE: 10, + SQUIGGLY: 11, + STRIKEOUT: 12, + STAMP: 13, + CARET: 14, + INK: 15, + POPUP: 16, + FILEATTACHMENT: 17, + SOUND: 18, + MOVIE: 19, + WIDGET: 20, + SCREEN: 21, + PRINTERMARK: 22, + TRAPNET: 23, + WATERMARK: 24, + THREED: 25, + REDACT: 26 +}; +exports.AnnotationType = AnnotationType; +const AnnotationReplyType = { + GROUP: "Group", + REPLY: "R" +}; +exports.AnnotationReplyType = AnnotationReplyType; +const AnnotationFlag = { + INVISIBLE: 0x01, + HIDDEN: 0x02, + PRINT: 0x04, + NOZOOM: 0x08, + NOROTATE: 0x10, + NOVIEW: 0x20, + READONLY: 0x40, + LOCKED: 0x80, + TOGGLENOVIEW: 0x100, + LOCKEDCONTENTS: 0x200 +}; +exports.AnnotationFlag = AnnotationFlag; +const AnnotationFieldFlag = { + READONLY: 0x0000001, + REQUIRED: 0x0000002, + NOEXPORT: 0x0000004, + MULTILINE: 0x0001000, + PASSWORD: 0x0002000, + NOTOGGLETOOFF: 0x0004000, + RADIO: 0x0008000, + PUSHBUTTON: 0x0010000, + COMBO: 0x0020000, + EDIT: 0x0040000, + SORT: 0x0080000, + FILESELECT: 0x0100000, + MULTISELECT: 0x0200000, + DONOTSPELLCHECK: 0x0400000, + DONOTSCROLL: 0x0800000, + COMB: 0x1000000, + RICHTEXT: 0x2000000, + RADIOSINUNISON: 0x2000000, + COMMITONSELCHANGE: 0x4000000 +}; +exports.AnnotationFieldFlag = AnnotationFieldFlag; +const AnnotationBorderStyleType = { + SOLID: 1, + DASHED: 2, + BEVELED: 3, + INSET: 4, + UNDERLINE: 5 +}; +exports.AnnotationBorderStyleType = AnnotationBorderStyleType; +const AnnotationActionEventType = { + E: "Mouse Enter", + X: "Mouse Exit", + D: "Mouse Down", + U: "Mouse Up", + Fo: "Focus", + Bl: "Blur", + PO: "PageOpen", + PC: "PageClose", + PV: "PageVisible", + PI: "PageInvisible", + K: "Keystroke", + F: "Format", + V: "Validate", + C: "Calculate" +}; +exports.AnnotationActionEventType = AnnotationActionEventType; +const DocumentActionEventType = { + WC: "WillClose", + WS: "WillSave", + DS: "DidSave", + WP: "WillPrint", + DP: "DidPrint" +}; +exports.DocumentActionEventType = DocumentActionEventType; +const PageActionEventType = { + O: "PageOpen", + C: "PageClose" +}; +exports.PageActionEventType = PageActionEventType; +const VerbosityLevel = { + ERRORS: 0, + WARNINGS: 1, + INFOS: 5 +}; +exports.VerbosityLevel = VerbosityLevel; +const CMapCompressionType = { + NONE: 0, + BINARY: 1 +}; +exports.CMapCompressionType = CMapCompressionType; +const OPS = { + dependency: 1, + setLineWidth: 2, + setLineCap: 3, + setLineJoin: 4, + setMiterLimit: 5, + setDash: 6, + setRenderingIntent: 7, + setFlatness: 8, + setGState: 9, + save: 10, + restore: 11, + transform: 12, + moveTo: 13, + lineTo: 14, + curveTo: 15, + curveTo2: 16, + curveTo3: 17, + closePath: 18, + rectangle: 19, + stroke: 20, + closeStroke: 21, + fill: 22, + eoFill: 23, + fillStroke: 24, + eoFillStroke: 25, + closeFillStroke: 26, + closeEOFillStroke: 27, + endPath: 28, + clip: 29, + eoClip: 30, + beginText: 31, + endText: 32, + setCharSpacing: 33, + setWordSpacing: 34, + setHScale: 35, + setLeading: 36, + setFont: 37, + setTextRenderingMode: 38, + setTextRise: 39, + moveText: 40, + setLeadingMoveText: 41, + setTextMatrix: 42, + nextLine: 43, + showText: 44, + showSpacedText: 45, + nextLineShowText: 46, + nextLineSetSpacingShowText: 47, + setCharWidth: 48, + setCharWidthAndBounds: 49, + setStrokeColorSpace: 50, + setFillColorSpace: 51, + setStrokeColor: 52, + setStrokeColorN: 53, + setFillColor: 54, + setFillColorN: 55, + setStrokeGray: 56, + setFillGray: 57, + setStrokeRGBColor: 58, + setFillRGBColor: 59, + setStrokeCMYKColor: 60, + setFillCMYKColor: 61, + shadingFill: 62, + beginInlineImage: 63, + beginImageData: 64, + endInlineImage: 65, + paintXObject: 66, + markPoint: 67, + markPointProps: 68, + beginMarkedContent: 69, + beginMarkedContentProps: 70, + endMarkedContent: 71, + beginCompat: 72, + endCompat: 73, + paintFormXObjectBegin: 74, + paintFormXObjectEnd: 75, + beginGroup: 76, + endGroup: 77, + beginAnnotation: 80, + endAnnotation: 81, + paintImageMaskXObject: 83, + paintImageMaskXObjectGroup: 84, + paintImageXObject: 85, + paintInlineImageXObject: 86, + paintInlineImageXObjectGroup: 87, + paintImageXObjectRepeat: 88, + paintImageMaskXObjectRepeat: 89, + paintSolidColorImageMask: 90, + constructPath: 91 +}; +exports.OPS = OPS; +const PasswordResponses = { + NEED_PASSWORD: 1, + INCORRECT_PASSWORD: 2 +}; +exports.PasswordResponses = PasswordResponses; +let verbosity = VerbosityLevel.WARNINGS; +function setVerbosityLevel(level) { + if (Number.isInteger(level)) { + verbosity = level; + } +} +function getVerbosityLevel() { + return verbosity; +} +function info(msg) { + if (verbosity >= VerbosityLevel.INFOS) { + console.log(`Info: ${msg}`); + } +} +function warn(msg) { + if (verbosity >= VerbosityLevel.WARNINGS) { + console.log(`Warning: ${msg}`); + } +} +function unreachable(msg) { + throw new Error(msg); +} +function assert(cond, msg) { + if (!cond) { + unreachable(msg); + } +} +function _isValidProtocol(url) { + switch (url?.protocol) { + case "http:": + case "https:": + case "ftp:": + case "mailto:": + case "tel:": + return true; + default: + return false; + } +} +function createValidAbsoluteUrl(url, baseUrl = null, options = null) { + if (!url) { + return null; + } + try { + if (options && typeof url === "string") { + if (options.addDefaultProtocol && url.startsWith("www.")) { + const dots = url.match(/\./g); + if (dots?.length >= 2) { + url = `http://${url}`; + } + } + if (options.tryConvertEncoding) { + try { + url = stringToUTF8String(url); + } catch {} + } + } + const absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url); + if (_isValidProtocol(absoluteUrl)) { + return absoluteUrl; + } + } catch {} + return null; +} +function shadow(obj, prop, value, nonSerializable = false) { + Object.defineProperty(obj, prop, { + value, + enumerable: !nonSerializable, + configurable: true, + writable: false + }); + return value; +} +const BaseException = function BaseExceptionClosure() { + function BaseException(message, name) { + if (this.constructor === BaseException) { + unreachable("Cannot initialize BaseException."); + } + this.message = message; + this.name = name; + } + BaseException.prototype = new Error(); + BaseException.constructor = BaseException; + return BaseException; +}(); +exports.BaseException = BaseException; +class PasswordException extends BaseException { + constructor(msg, code) { + super(msg, "PasswordException"); + this.code = code; + } +} +exports.PasswordException = PasswordException; +class UnknownErrorException extends BaseException { + constructor(msg, details) { + super(msg, "UnknownErrorException"); + this.details = details; + } +} +exports.UnknownErrorException = UnknownErrorException; +class InvalidPDFException extends BaseException { + constructor(msg) { + super(msg, "InvalidPDFException"); + } +} +exports.InvalidPDFException = InvalidPDFException; +class MissingPDFException extends BaseException { + constructor(msg) { + super(msg, "MissingPDFException"); + } +} +exports.MissingPDFException = MissingPDFException; +class UnexpectedResponseException extends BaseException { + constructor(msg, status) { + super(msg, "UnexpectedResponseException"); + this.status = status; + } +} +exports.UnexpectedResponseException = UnexpectedResponseException; +class FormatError extends BaseException { + constructor(msg) { + super(msg, "FormatError"); + } +} +exports.FormatError = FormatError; +class AbortException extends BaseException { + constructor(msg) { + super(msg, "AbortException"); + } +} +exports.AbortException = AbortException; +function bytesToString(bytes) { + if (typeof bytes !== "object" || bytes?.length === undefined) { + unreachable("Invalid argument for bytesToString"); + } + const length = bytes.length; + const MAX_ARGUMENT_COUNT = 8192; + if (length < MAX_ARGUMENT_COUNT) { + return String.fromCharCode.apply(null, bytes); + } + const strBuf = []; + for (let i = 0; i < length; i += MAX_ARGUMENT_COUNT) { + const chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length); + const chunk = bytes.subarray(i, chunkEnd); + strBuf.push(String.fromCharCode.apply(null, chunk)); + } + return strBuf.join(""); +} +function stringToBytes(str) { + if (typeof str !== "string") { + unreachable("Invalid argument for stringToBytes"); + } + const length = str.length; + const bytes = new Uint8Array(length); + for (let i = 0; i < length; ++i) { + bytes[i] = str.charCodeAt(i) & 0xff; + } + return bytes; +} +function string32(value) { + return String.fromCharCode(value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff); +} +function objectSize(obj) { + return Object.keys(obj).length; +} +function objectFromMap(map) { + const obj = Object.create(null); + for (const [key, value] of map) { + obj[key] = value; + } + return obj; +} +function isLittleEndian() { + const buffer8 = new Uint8Array(4); + buffer8[0] = 1; + const view32 = new Uint32Array(buffer8.buffer, 0, 1); + return view32[0] === 1; +} +function isEvalSupported() { + try { + new Function(""); + return true; + } catch { + return false; + } +} +class FeatureTest { + static get isLittleEndian() { + return shadow(this, "isLittleEndian", isLittleEndian()); + } + static get isEvalSupported() { + return shadow(this, "isEvalSupported", isEvalSupported()); + } + static get isOffscreenCanvasSupported() { + return shadow(this, "isOffscreenCanvasSupported", typeof OffscreenCanvas !== "undefined"); + } + static get platform() { + if (typeof navigator === "undefined") { + return shadow(this, "platform", { + isWin: false, + isMac: false + }); + } + return shadow(this, "platform", { + isWin: navigator.platform.includes("Win"), + isMac: navigator.platform.includes("Mac") + }); + } + static get isCSSRoundSupported() { + return shadow(this, "isCSSRoundSupported", globalThis.CSS?.supports?.("width: round(1.5px, 1px)")); + } +} +exports.FeatureTest = FeatureTest; +const hexNumbers = [...Array(256).keys()].map(n => n.toString(16).padStart(2, "0")); +class Util { + static makeHexColor(r, g, b) { + return `#${hexNumbers[r]}${hexNumbers[g]}${hexNumbers[b]}`; + } + static scaleMinMax(transform, minMax) { + let temp; + if (transform[0]) { + if (transform[0] < 0) { + temp = minMax[0]; + minMax[0] = minMax[1]; + minMax[1] = temp; + } + minMax[0] *= transform[0]; + minMax[1] *= transform[0]; + if (transform[3] < 0) { + temp = minMax[2]; + minMax[2] = minMax[3]; + minMax[3] = temp; + } + minMax[2] *= transform[3]; + minMax[3] *= transform[3]; + } else { + temp = minMax[0]; + minMax[0] = minMax[2]; + minMax[2] = temp; + temp = minMax[1]; + minMax[1] = minMax[3]; + minMax[3] = temp; + if (transform[1] < 0) { + temp = minMax[2]; + minMax[2] = minMax[3]; + minMax[3] = temp; + } + minMax[2] *= transform[1]; + minMax[3] *= transform[1]; + if (transform[2] < 0) { + temp = minMax[0]; + minMax[0] = minMax[1]; + minMax[1] = temp; + } + minMax[0] *= transform[2]; + minMax[1] *= transform[2]; + } + minMax[0] += transform[4]; + minMax[1] += transform[4]; + minMax[2] += transform[5]; + minMax[3] += transform[5]; + } + static transform(m1, m2) { + return [m1[0] * m2[0] + m1[2] * m2[1], m1[1] * m2[0] + m1[3] * m2[1], m1[0] * m2[2] + m1[2] * m2[3], m1[1] * m2[2] + m1[3] * m2[3], m1[0] * m2[4] + m1[2] * m2[5] + m1[4], m1[1] * m2[4] + m1[3] * m2[5] + m1[5]]; + } + static applyTransform(p, m) { + const xt = p[0] * m[0] + p[1] * m[2] + m[4]; + const yt = p[0] * m[1] + p[1] * m[3] + m[5]; + return [xt, yt]; + } + static applyInverseTransform(p, m) { + const d = m[0] * m[3] - m[1] * m[2]; + const xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d; + const yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d; + return [xt, yt]; + } + static getAxialAlignedBoundingBox(r, m) { + const p1 = this.applyTransform(r, m); + const p2 = this.applyTransform(r.slice(2, 4), m); + const p3 = this.applyTransform([r[0], r[3]], m); + const p4 = this.applyTransform([r[2], r[1]], m); + return [Math.min(p1[0], p2[0], p3[0], p4[0]), Math.min(p1[1], p2[1], p3[1], p4[1]), Math.max(p1[0], p2[0], p3[0], p4[0]), Math.max(p1[1], p2[1], p3[1], p4[1])]; + } + static inverseTransform(m) { + const d = m[0] * m[3] - m[1] * m[2]; + return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d, (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d]; + } + static singularValueDecompose2dScale(m) { + const transpose = [m[0], m[2], m[1], m[3]]; + const a = m[0] * transpose[0] + m[1] * transpose[2]; + const b = m[0] * transpose[1] + m[1] * transpose[3]; + const c = m[2] * transpose[0] + m[3] * transpose[2]; + const d = m[2] * transpose[1] + m[3] * transpose[3]; + const first = (a + d) / 2; + const second = Math.sqrt((a + d) ** 2 - 4 * (a * d - c * b)) / 2; + const sx = first + second || 1; + const sy = first - second || 1; + return [Math.sqrt(sx), Math.sqrt(sy)]; + } + static normalizeRect(rect) { + const r = rect.slice(0); + if (rect[0] > rect[2]) { + r[0] = rect[2]; + r[2] = rect[0]; + } + if (rect[1] > rect[3]) { + r[1] = rect[3]; + r[3] = rect[1]; + } + return r; + } + static intersect(rect1, rect2) { + const xLow = Math.max(Math.min(rect1[0], rect1[2]), Math.min(rect2[0], rect2[2])); + const xHigh = Math.min(Math.max(rect1[0], rect1[2]), Math.max(rect2[0], rect2[2])); + if (xLow > xHigh) { + return null; + } + const yLow = Math.max(Math.min(rect1[1], rect1[3]), Math.min(rect2[1], rect2[3])); + const yHigh = Math.min(Math.max(rect1[1], rect1[3]), Math.max(rect2[1], rect2[3])); + if (yLow > yHigh) { + return null; + } + return [xLow, yLow, xHigh, yHigh]; + } + static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3) { + const tvalues = [], + bounds = [[], []]; + let a, b, c, t, t1, t2, b2ac, sqrtb2ac; + for (let i = 0; i < 2; ++i) { + if (i === 0) { + b = 6 * x0 - 12 * x1 + 6 * x2; + a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3; + c = 3 * x1 - 3 * x0; + } else { + b = 6 * y0 - 12 * y1 + 6 * y2; + a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3; + c = 3 * y1 - 3 * y0; + } + if (Math.abs(a) < 1e-12) { + if (Math.abs(b) < 1e-12) { + continue; + } + t = -c / b; + if (0 < t && t < 1) { + tvalues.push(t); + } + continue; + } + b2ac = b * b - 4 * c * a; + sqrtb2ac = Math.sqrt(b2ac); + if (b2ac < 0) { + continue; + } + t1 = (-b + sqrtb2ac) / (2 * a); + if (0 < t1 && t1 < 1) { + tvalues.push(t1); + } + t2 = (-b - sqrtb2ac) / (2 * a); + if (0 < t2 && t2 < 1) { + tvalues.push(t2); + } + } + let j = tvalues.length, + mt; + const jlen = j; + while (j--) { + t = tvalues[j]; + mt = 1 - t; + bounds[0][j] = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3; + bounds[1][j] = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3; + } + bounds[0][jlen] = x0; + bounds[1][jlen] = y0; + bounds[0][jlen + 1] = x3; + bounds[1][jlen + 1] = y3; + bounds[0].length = bounds[1].length = jlen + 2; + return [Math.min(...bounds[0]), Math.min(...bounds[1]), Math.max(...bounds[0]), Math.max(...bounds[1])]; + } +} +exports.Util = Util; +const PDFStringTranslateTable = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2d8, 0x2c7, 0x2c6, 0x2d9, 0x2dd, 0x2db, 0x2da, 0x2dc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x141, 0x152, 0x160, 0x178, 0x17d, 0x131, 0x142, 0x153, 0x161, 0x17e, 0, 0x20ac]; +function stringToPDFString(str) { + if (str[0] >= "\xEF") { + let encoding; + if (str[0] === "\xFE" && str[1] === "\xFF") { + encoding = "utf-16be"; + } else if (str[0] === "\xFF" && str[1] === "\xFE") { + encoding = "utf-16le"; + } else if (str[0] === "\xEF" && str[1] === "\xBB" && str[2] === "\xBF") { + encoding = "utf-8"; + } + if (encoding) { + try { + const decoder = new TextDecoder(encoding, { + fatal: true + }); + const buffer = stringToBytes(str); + return decoder.decode(buffer); + } catch (ex) { + warn(`stringToPDFString: "${ex}".`); + } + } + } + const strBuf = []; + for (let i = 0, ii = str.length; i < ii; i++) { + const code = PDFStringTranslateTable[str.charCodeAt(i)]; + strBuf.push(code ? String.fromCharCode(code) : str.charAt(i)); + } + return strBuf.join(""); +} +function stringToUTF8String(str) { + return decodeURIComponent(escape(str)); +} +function utf8StringToString(str) { + return unescape(encodeURIComponent(str)); +} +function isArrayBuffer(v) { + return typeof v === "object" && v?.byteLength !== undefined; +} +function isArrayEqual(arr1, arr2) { + if (arr1.length !== arr2.length) { + return false; + } + for (let i = 0, ii = arr1.length; i < ii; i++) { + if (arr1[i] !== arr2[i]) { + return false; + } + } + return true; +} +function getModificationDate(date = new Date()) { + const buffer = [date.getUTCFullYear().toString(), (date.getUTCMonth() + 1).toString().padStart(2, "0"), date.getUTCDate().toString().padStart(2, "0"), date.getUTCHours().toString().padStart(2, "0"), date.getUTCMinutes().toString().padStart(2, "0"), date.getUTCSeconds().toString().padStart(2, "0")]; + return buffer.join(""); +} +class PromiseCapability { + #settled = false; + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = data => { + this.#settled = true; + resolve(data); + }; + this.reject = reason => { + this.#settled = true; + reject(reason); + }; + }); + } + get settled() { + return this.#settled; + } +} +exports.PromiseCapability = PromiseCapability; +let NormalizeRegex = null; +let NormalizationMap = null; +function normalizeUnicode(str) { + if (!NormalizeRegex) { + NormalizeRegex = /([\u00a0\u00b5\u037e\u0eb3\u2000-\u200a\u202f\u2126\ufb00-\ufb04\ufb06\ufb20-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufba1\ufba4-\ufba9\ufbae-\ufbb1\ufbd3-\ufbdc\ufbde-\ufbe7\ufbea-\ufbf8\ufbfc-\ufbfd\ufc00-\ufc5d\ufc64-\ufcf1\ufcf5-\ufd3d\ufd88\ufdf4\ufdfa-\ufdfb\ufe71\ufe77\ufe79\ufe7b\ufe7d]+)|(\ufb05+)/gu; + NormalizationMap = new Map([["ſt", "Åæt"]]); + } + return str.replaceAll(NormalizeRegex, (_, p1, p2) => { + return p1 ? p1.normalize("NFKC") : NormalizationMap.get(p2); + }); +} +function getUuid() { + if (typeof crypto !== "undefined" && typeof crypto?.randomUUID === "function") { + return crypto.randomUUID(); + } + const buf = new Uint8Array(32); + if (typeof crypto !== "undefined" && typeof crypto?.getRandomValues === "function") { + crypto.getRandomValues(buf); + } else { + for (let i = 0; i < 32; i++) { + buf[i] = Math.floor(Math.random() * 255); + } + } + return bytesToString(buf); +} +const AnnotationPrefix = "pdfjs_internal_id_"; +exports.AnnotationPrefix = AnnotationPrefix; + +/***/ }), +/* 3 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.XRefParseException = exports.XRefEntryException = exports.ParserEOFException = exports.PDF_VERSION_REGEXP = exports.MissingDataException = void 0; +exports.arrayBuffersToBytes = arrayBuffersToBytes; +exports.collectActions = collectActions; +exports.encodeToXmlString = encodeToXmlString; +exports.escapePDFName = escapePDFName; +exports.escapeString = escapeString; +exports.getInheritableProperty = getInheritableProperty; +exports.getLookupTableFactory = getLookupTableFactory; +exports.getNewAnnotationsMap = getNewAnnotationsMap; +exports.getRotationMatrix = getRotationMatrix; +exports.isAscii = isAscii; +exports.isWhiteSpace = isWhiteSpace; +exports.log2 = log2; +exports.numberToString = numberToString; +exports.parseXFAPath = parseXFAPath; +exports.readInt8 = readInt8; +exports.readUint16 = readUint16; +exports.readUint32 = readUint32; +exports.recoverJsURL = recoverJsURL; +exports.stringToUTF16HexString = stringToUTF16HexString; +exports.stringToUTF16String = stringToUTF16String; +exports.toRomanNumerals = toRomanNumerals; +exports.validateCSSFont = validateCSSFont; +exports.validateFontName = validateFontName; +var _util = __w_pdfjs_require__(2); +var _primitives = __w_pdfjs_require__(4); +var _base_stream = __w_pdfjs_require__(5); +const PDF_VERSION_REGEXP = /^[1-9]\.\d$/; +exports.PDF_VERSION_REGEXP = PDF_VERSION_REGEXP; +function getLookupTableFactory(initializer) { + let lookup; + return function () { + if (initializer) { + lookup = Object.create(null); + initializer(lookup); + initializer = null; + } + return lookup; + }; +} +class MissingDataException extends _util.BaseException { + constructor(begin, end) { + super(`Missing data [${begin}, ${end})`, "MissingDataException"); + this.begin = begin; + this.end = end; + } +} +exports.MissingDataException = MissingDataException; +class ParserEOFException extends _util.BaseException { + constructor(msg) { + super(msg, "ParserEOFException"); + } +} +exports.ParserEOFException = ParserEOFException; +class XRefEntryException extends _util.BaseException { + constructor(msg) { + super(msg, "XRefEntryException"); + } +} +exports.XRefEntryException = XRefEntryException; +class XRefParseException extends _util.BaseException { + constructor(msg) { + super(msg, "XRefParseException"); + } +} +exports.XRefParseException = XRefParseException; +function arrayBuffersToBytes(arr) { + const length = arr.length; + if (length === 0) { + return new Uint8Array(0); + } + if (length === 1) { + return new Uint8Array(arr[0]); + } + let dataLength = 0; + for (let i = 0; i < length; i++) { + dataLength += arr[i].byteLength; + } + const data = new Uint8Array(dataLength); + let pos = 0; + for (let i = 0; i < length; i++) { + const item = new Uint8Array(arr[i]); + data.set(item, pos); + pos += item.byteLength; + } + return data; +} +function getInheritableProperty({ + dict, + key, + getArray = false, + stopWhenFound = true +}) { + let values; + const visited = new _primitives.RefSet(); + while (dict instanceof _primitives.Dict && !(dict.objId && visited.has(dict.objId))) { + if (dict.objId) { + visited.put(dict.objId); + } + const value = getArray ? dict.getArray(key) : dict.get(key); + if (value !== undefined) { + if (stopWhenFound) { + return value; + } + (values ||= []).push(value); + } + dict = dict.get("Parent"); + } + return values; +} +const ROMAN_NUMBER_MAP = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]; +function toRomanNumerals(number, lowerCase = false) { + (0, _util.assert)(Number.isInteger(number) && number > 0, "The number should be a positive integer."); + const romanBuf = []; + let pos; + while (number >= 1000) { + number -= 1000; + romanBuf.push("M"); + } + pos = number / 100 | 0; + number %= 100; + romanBuf.push(ROMAN_NUMBER_MAP[pos]); + pos = number / 10 | 0; + number %= 10; + romanBuf.push(ROMAN_NUMBER_MAP[10 + pos]); + romanBuf.push(ROMAN_NUMBER_MAP[20 + number]); + const romanStr = romanBuf.join(""); + return lowerCase ? romanStr.toLowerCase() : romanStr; +} +function log2(x) { + if (x <= 0) { + return 0; + } + return Math.ceil(Math.log2(x)); +} +function readInt8(data, offset) { + return data[offset] << 24 >> 24; +} +function readUint16(data, offset) { + return data[offset] << 8 | data[offset + 1]; +} +function readUint32(data, offset) { + return (data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]) >>> 0; +} +function isWhiteSpace(ch) { + return ch === 0x20 || ch === 0x09 || ch === 0x0d || ch === 0x0a; +} +function parseXFAPath(path) { + const positionPattern = /(.+)\[(\d+)\]$/; + return path.split(".").map(component => { + const m = component.match(positionPattern); + if (m) { + return { + name: m[1], + pos: parseInt(m[2], 10) + }; + } + return { + name: component, + pos: 0 + }; + }); +} +function escapePDFName(str) { + const buffer = []; + let start = 0; + for (let i = 0, ii = str.length; i < ii; i++) { + const char = str.charCodeAt(i); + if (char < 0x21 || char > 0x7e || char === 0x23 || char === 0x28 || char === 0x29 || char === 0x3c || char === 0x3e || char === 0x5b || char === 0x5d || char === 0x7b || char === 0x7d || char === 0x2f || char === 0x25) { + if (start < i) { + buffer.push(str.substring(start, i)); + } + buffer.push(`#${char.toString(16)}`); + start = i + 1; + } + } + if (buffer.length === 0) { + return str; + } + if (start < str.length) { + buffer.push(str.substring(start, str.length)); + } + return buffer.join(""); +} +function escapeString(str) { + return str.replaceAll(/([()\\\n\r])/g, match => { + if (match === "\n") { + return "\\n"; + } else if (match === "\r") { + return "\\r"; + } + return `\\${match}`; + }); +} +function _collectJS(entry, xref, list, parents) { + if (!entry) { + return; + } + let parent = null; + if (entry instanceof _primitives.Ref) { + if (parents.has(entry)) { + return; + } + parent = entry; + parents.put(parent); + entry = xref.fetch(entry); + } + if (Array.isArray(entry)) { + for (const element of entry) { + _collectJS(element, xref, list, parents); + } + } else if (entry instanceof _primitives.Dict) { + if ((0, _primitives.isName)(entry.get("S"), "JavaScript")) { + const js = entry.get("JS"); + let code; + if (js instanceof _base_stream.BaseStream) { + code = js.getString(); + } else if (typeof js === "string") { + code = js; + } + code &&= (0, _util.stringToPDFString)(code).replaceAll("\x00", ""); + if (code) { + list.push(code); + } + } + _collectJS(entry.getRaw("Next"), xref, list, parents); + } + if (parent) { + parents.remove(parent); + } +} +function collectActions(xref, dict, eventType) { + const actions = Object.create(null); + const additionalActionsDicts = getInheritableProperty({ + dict, + key: "AA", + stopWhenFound: false + }); + if (additionalActionsDicts) { + for (let i = additionalActionsDicts.length - 1; i >= 0; i--) { + const additionalActions = additionalActionsDicts[i]; + if (!(additionalActions instanceof _primitives.Dict)) { + continue; + } + for (const key of additionalActions.getKeys()) { + const action = eventType[key]; + if (!action) { + continue; + } + const actionDict = additionalActions.getRaw(key); + const parents = new _primitives.RefSet(); + const list = []; + _collectJS(actionDict, xref, list, parents); + if (list.length > 0) { + actions[action] = list; + } + } + } + } + if (dict.has("A")) { + const actionDict = dict.get("A"); + const parents = new _primitives.RefSet(); + const list = []; + _collectJS(actionDict, xref, list, parents); + if (list.length > 0) { + actions.Action = list; + } + } + return (0, _util.objectSize)(actions) > 0 ? actions : null; +} +const XMLEntities = { + 0x3c: "<", + 0x3e: ">", + 0x26: "&", + 0x22: """, + 0x27: "'" +}; +function encodeToXmlString(str) { + const buffer = []; + let start = 0; + for (let i = 0, ii = str.length; i < ii; i++) { + const char = str.codePointAt(i); + if (0x20 <= char && char <= 0x7e) { + const entity = XMLEntities[char]; + if (entity) { + if (start < i) { + buffer.push(str.substring(start, i)); + } + buffer.push(entity); + start = i + 1; + } + } else { + if (start < i) { + buffer.push(str.substring(start, i)); + } + buffer.push(`&#x${char.toString(16).toUpperCase()};`); + if (char > 0xd7ff && (char < 0xe000 || char > 0xfffd)) { + i++; + } + start = i + 1; + } + } + if (buffer.length === 0) { + return str; + } + if (start < str.length) { + buffer.push(str.substring(start, str.length)); + } + return buffer.join(""); +} +function validateFontName(fontFamily, mustWarn = false) { + const m = /^("|').*("|')$/.exec(fontFamily); + if (m && m[1] === m[2]) { + const re = new RegExp(`[^\\\\]${m[1]}`); + if (re.test(fontFamily.slice(1, -1))) { + if (mustWarn) { + (0, _util.warn)(`FontFamily contains unescaped ${m[1]}: ${fontFamily}.`); + } + return false; + } + } else { + for (const ident of fontFamily.split(/[ \t]+/)) { + if (/^(\d|(-(\d|-)))/.test(ident) || !/^[\w-\\]+$/.test(ident)) { + if (mustWarn) { + (0, _util.warn)(`FontFamily contains invalid : ${fontFamily}.`); + } + return false; + } + } + } + return true; +} +function validateCSSFont(cssFontInfo) { + const DEFAULT_CSS_FONT_OBLIQUE = "14"; + const DEFAULT_CSS_FONT_WEIGHT = "400"; + const CSS_FONT_WEIGHT_VALUES = new Set(["100", "200", "300", "400", "500", "600", "700", "800", "900", "1000", "normal", "bold", "bolder", "lighter"]); + const { + fontFamily, + fontWeight, + italicAngle + } = cssFontInfo; + if (!validateFontName(fontFamily, true)) { + return false; + } + const weight = fontWeight ? fontWeight.toString() : ""; + cssFontInfo.fontWeight = CSS_FONT_WEIGHT_VALUES.has(weight) ? weight : DEFAULT_CSS_FONT_WEIGHT; + const angle = parseFloat(italicAngle); + cssFontInfo.italicAngle = isNaN(angle) || angle < -90 || angle > 90 ? DEFAULT_CSS_FONT_OBLIQUE : italicAngle.toString(); + return true; +} +function recoverJsURL(str) { + const URL_OPEN_METHODS = ["app.launchURL", "window.open", "xfa.host.gotoURL"]; + const regex = new RegExp("^\\s*(" + URL_OPEN_METHODS.join("|").replaceAll(".", "\\.") + ")\\((?:'|\")([^'\"]*)(?:'|\")(?:,\\s*(\\w+)\\)|\\))", "i"); + const jsUrl = regex.exec(str); + if (jsUrl?.[2]) { + const url = jsUrl[2]; + let newWindow = false; + if (jsUrl[3] === "true" && jsUrl[1] === "app.launchURL") { + newWindow = true; + } + return { + url, + newWindow + }; + } + return null; +} +function numberToString(value) { + if (Number.isInteger(value)) { + return value.toString(); + } + const roundedValue = Math.round(value * 100); + if (roundedValue % 100 === 0) { + return (roundedValue / 100).toString(); + } + if (roundedValue % 10 === 0) { + return value.toFixed(1); + } + return value.toFixed(2); +} +function getNewAnnotationsMap(annotationStorage) { + if (!annotationStorage) { + return null; + } + const newAnnotationsByPage = new Map(); + for (const [key, value] of annotationStorage) { + if (!key.startsWith(_util.AnnotationEditorPrefix)) { + continue; + } + let annotations = newAnnotationsByPage.get(value.pageIndex); + if (!annotations) { + annotations = []; + newAnnotationsByPage.set(value.pageIndex, annotations); + } + annotations.push(value); + } + return newAnnotationsByPage.size > 0 ? newAnnotationsByPage : null; +} +function isAscii(str) { + return /^[\x00-\x7F]*$/.test(str); +} +function stringToUTF16HexString(str) { + const buf = []; + for (let i = 0, ii = str.length; i < ii; i++) { + const char = str.charCodeAt(i); + buf.push((char >> 8 & 0xff).toString(16).padStart(2, "0"), (char & 0xff).toString(16).padStart(2, "0")); + } + return buf.join(""); +} +function stringToUTF16String(str, bigEndian = false) { + const buf = []; + if (bigEndian) { + buf.push("\xFE\xFF"); + } + for (let i = 0, ii = str.length; i < ii; i++) { + const char = str.charCodeAt(i); + buf.push(String.fromCharCode(char >> 8 & 0xff), String.fromCharCode(char & 0xff)); + } + return buf.join(""); +} +function getRotationMatrix(rotation, width, height) { + switch (rotation) { + case 90: + return [0, 1, -1, 0, width, 0]; + case 180: + return [-1, 0, 0, -1, width, height]; + case 270: + return [0, -1, 1, 0, 0, height]; + default: + throw new Error("Invalid rotation"); + } +} + +/***/ }), +/* 4 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.RefSetCache = exports.RefSet = exports.Ref = exports.Name = exports.EOF = exports.Dict = exports.Cmd = exports.CIRCULAR_REF = void 0; +exports.clearPrimitiveCaches = clearPrimitiveCaches; +exports.isCmd = isCmd; +exports.isDict = isDict; +exports.isName = isName; +exports.isRefsEqual = isRefsEqual; +var _util = __w_pdfjs_require__(2); +const CIRCULAR_REF = Symbol("CIRCULAR_REF"); +exports.CIRCULAR_REF = CIRCULAR_REF; +const EOF = Symbol("EOF"); +exports.EOF = EOF; +let CmdCache = Object.create(null); +let NameCache = Object.create(null); +let RefCache = Object.create(null); +function clearPrimitiveCaches() { + CmdCache = Object.create(null); + NameCache = Object.create(null); + RefCache = Object.create(null); +} +class Name { + constructor(name) { + this.name = name; + } + static get(name) { + return NameCache[name] ||= new Name(name); + } +} +exports.Name = Name; +class Cmd { + constructor(cmd) { + this.cmd = cmd; + } + static get(cmd) { + return CmdCache[cmd] ||= new Cmd(cmd); + } +} +exports.Cmd = Cmd; +const nonSerializable = function nonSerializableClosure() { + return nonSerializable; +}; +class Dict { + constructor(xref = null) { + this._map = Object.create(null); + this.xref = xref; + this.objId = null; + this.suppressEncryption = false; + this.__nonSerializable__ = nonSerializable; + } + assignXref(newXref) { + this.xref = newXref; + } + get size() { + return Object.keys(this._map).length; + } + get(key1, key2, key3) { + let value = this._map[key1]; + if (value === undefined && key2 !== undefined) { + value = this._map[key2]; + if (value === undefined && key3 !== undefined) { + value = this._map[key3]; + } + } + if (value instanceof Ref && this.xref) { + return this.xref.fetch(value, this.suppressEncryption); + } + return value; + } + async getAsync(key1, key2, key3) { + let value = this._map[key1]; + if (value === undefined && key2 !== undefined) { + value = this._map[key2]; + if (value === undefined && key3 !== undefined) { + value = this._map[key3]; + } + } + if (value instanceof Ref && this.xref) { + return this.xref.fetchAsync(value, this.suppressEncryption); + } + return value; + } + getArray(key1, key2, key3) { + let value = this._map[key1]; + if (value === undefined && key2 !== undefined) { + value = this._map[key2]; + if (value === undefined && key3 !== undefined) { + value = this._map[key3]; + } + } + if (value instanceof Ref && this.xref) { + value = this.xref.fetch(value, this.suppressEncryption); + } + if (Array.isArray(value)) { + value = value.slice(); + for (let i = 0, ii = value.length; i < ii; i++) { + if (value[i] instanceof Ref && this.xref) { + value[i] = this.xref.fetch(value[i], this.suppressEncryption); + } + } + } + return value; + } + getRaw(key) { + return this._map[key]; + } + getKeys() { + return Object.keys(this._map); + } + getRawValues() { + return Object.values(this._map); + } + set(key, value) { + this._map[key] = value; + } + has(key) { + return this._map[key] !== undefined; + } + forEach(callback) { + for (const key in this._map) { + callback(key, this.get(key)); + } + } + static get empty() { + const emptyDict = new Dict(null); + emptyDict.set = (key, value) => { + (0, _util.unreachable)("Should not call `set` on the empty dictionary."); + }; + return (0, _util.shadow)(this, "empty", emptyDict); + } + static merge({ + xref, + dictArray, + mergeSubDicts = false + }) { + const mergedDict = new Dict(xref), + properties = new Map(); + for (const dict of dictArray) { + if (!(dict instanceof Dict)) { + continue; + } + for (const [key, value] of Object.entries(dict._map)) { + let property = properties.get(key); + if (property === undefined) { + property = []; + properties.set(key, property); + } else if (!mergeSubDicts || !(value instanceof Dict)) { + continue; + } + property.push(value); + } + } + for (const [name, values] of properties) { + if (values.length === 1 || !(values[0] instanceof Dict)) { + mergedDict._map[name] = values[0]; + continue; + } + const subDict = new Dict(xref); + for (const dict of values) { + for (const [key, value] of Object.entries(dict._map)) { + if (subDict._map[key] === undefined) { + subDict._map[key] = value; + } + } + } + if (subDict.size > 0) { + mergedDict._map[name] = subDict; + } + } + properties.clear(); + return mergedDict.size > 0 ? mergedDict : Dict.empty; + } + clone() { + const dict = new Dict(this.xref); + for (const key of this.getKeys()) { + dict.set(key, this.getRaw(key)); + } + return dict; + } +} +exports.Dict = Dict; +class Ref { + constructor(num, gen) { + this.num = num; + this.gen = gen; + } + toString() { + if (this.gen === 0) { + return `${this.num}R`; + } + return `${this.num}R${this.gen}`; + } + static fromString(str) { + const ref = RefCache[str]; + if (ref) { + return ref; + } + const m = /^(\d+)R(\d*)$/.exec(str); + if (!m || m[1] === "0") { + return null; + } + return RefCache[str] = new Ref(parseInt(m[1]), !m[2] ? 0 : parseInt(m[2])); + } + static get(num, gen) { + const key = gen === 0 ? `${num}R` : `${num}R${gen}`; + return RefCache[key] ||= new Ref(num, gen); + } +} +exports.Ref = Ref; +class RefSet { + constructor(parent = null) { + this._set = new Set(parent?._set); + } + has(ref) { + return this._set.has(ref.toString()); + } + put(ref) { + this._set.add(ref.toString()); + } + remove(ref) { + this._set.delete(ref.toString()); + } + [Symbol.iterator]() { + return this._set.values(); + } + clear() { + this._set.clear(); + } +} +exports.RefSet = RefSet; +class RefSetCache { + constructor() { + this._map = new Map(); + } + get size() { + return this._map.size; + } + get(ref) { + return this._map.get(ref.toString()); + } + has(ref) { + return this._map.has(ref.toString()); + } + put(ref, obj) { + this._map.set(ref.toString(), obj); + } + putAlias(ref, aliasRef) { + this._map.set(ref.toString(), this.get(aliasRef)); + } + [Symbol.iterator]() { + return this._map.values(); + } + clear() { + this._map.clear(); + } +} +exports.RefSetCache = RefSetCache; +function isName(v, name) { + return v instanceof Name && (name === undefined || v.name === name); +} +function isCmd(v, cmd) { + return v instanceof Cmd && (cmd === undefined || v.cmd === cmd); +} +function isDict(v, type) { + return v instanceof Dict && (type === undefined || isName(v.get("Type"), type)); +} +function isRefsEqual(v1, v2) { + return v1.num === v2.num && v1.gen === v2.gen; +} + +/***/ }), +/* 5 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.BaseStream = void 0; +var _util = __w_pdfjs_require__(2); +class BaseStream { + constructor() { + if (this.constructor === BaseStream) { + (0, _util.unreachable)("Cannot initialize BaseStream."); + } + } + get length() { + (0, _util.unreachable)("Abstract getter `length` accessed"); + } + get isEmpty() { + (0, _util.unreachable)("Abstract getter `isEmpty` accessed"); + } + get isDataLoaded() { + return (0, _util.shadow)(this, "isDataLoaded", true); + } + getByte() { + (0, _util.unreachable)("Abstract method `getByte` called"); + } + getBytes(length) { + (0, _util.unreachable)("Abstract method `getBytes` called"); + } + peekByte() { + const peekedByte = this.getByte(); + if (peekedByte !== -1) { + this.pos--; + } + return peekedByte; + } + peekBytes(length) { + const bytes = this.getBytes(length); + this.pos -= bytes.length; + return bytes; + } + getUint16() { + const b0 = this.getByte(); + const b1 = this.getByte(); + if (b0 === -1 || b1 === -1) { + return -1; + } + return (b0 << 8) + b1; + } + getInt32() { + const b0 = this.getByte(); + const b1 = this.getByte(); + const b2 = this.getByte(); + const b3 = this.getByte(); + return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3; + } + getByteRange(begin, end) { + (0, _util.unreachable)("Abstract method `getByteRange` called"); + } + getString(length) { + return (0, _util.bytesToString)(this.getBytes(length)); + } + skip(n) { + this.pos += n || 1; + } + reset() { + (0, _util.unreachable)("Abstract method `reset` called"); + } + moveStart() { + (0, _util.unreachable)("Abstract method `moveStart` called"); + } + makeSubStream(start, length, dict = null) { + (0, _util.unreachable)("Abstract method `makeSubStream` called"); + } + getBaseStreams() { + return null; + } +} +exports.BaseStream = BaseStream; + +/***/ }), +/* 6 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.NetworkPdfManager = exports.LocalPdfManager = void 0; +var _util = __w_pdfjs_require__(2); +var _chunked_stream = __w_pdfjs_require__(7); +var _core_utils = __w_pdfjs_require__(3); +var _document = __w_pdfjs_require__(9); +var _stream = __w_pdfjs_require__(8); +function parseDocBaseUrl(url) { + if (url) { + const absoluteUrl = (0, _util.createValidAbsoluteUrl)(url); + if (absoluteUrl) { + return absoluteUrl.href; + } + (0, _util.warn)(`Invalid absolute docBaseUrl: "${url}".`); + } + return null; +} +class BasePdfManager { + constructor(args) { + if (this.constructor === BasePdfManager) { + (0, _util.unreachable)("Cannot initialize BasePdfManager."); + } + this._docBaseUrl = parseDocBaseUrl(args.docBaseUrl); + this._docId = args.docId; + this._password = args.password; + this.enableXfa = args.enableXfa; + args.evaluatorOptions.isOffscreenCanvasSupported &&= _util.FeatureTest.isOffscreenCanvasSupported; + this.evaluatorOptions = args.evaluatorOptions; + } + get docId() { + return this._docId; + } + get password() { + return this._password; + } + get docBaseUrl() { + return this._docBaseUrl; + } + get catalog() { + return this.pdfDocument.catalog; + } + ensureDoc(prop, args) { + return this.ensure(this.pdfDocument, prop, args); + } + ensureXRef(prop, args) { + return this.ensure(this.pdfDocument.xref, prop, args); + } + ensureCatalog(prop, args) { + return this.ensure(this.pdfDocument.catalog, prop, args); + } + getPage(pageIndex) { + return this.pdfDocument.getPage(pageIndex); + } + fontFallback(id, handler) { + return this.pdfDocument.fontFallback(id, handler); + } + loadXfaFonts(handler, task) { + return this.pdfDocument.loadXfaFonts(handler, task); + } + loadXfaImages() { + return this.pdfDocument.loadXfaImages(); + } + serializeXfaData(annotationStorage) { + return this.pdfDocument.serializeXfaData(annotationStorage); + } + cleanup(manuallyTriggered = false) { + return this.pdfDocument.cleanup(manuallyTriggered); + } + async ensure(obj, prop, args) { + (0, _util.unreachable)("Abstract method `ensure` called"); + } + requestRange(begin, end) { + (0, _util.unreachable)("Abstract method `requestRange` called"); + } + requestLoadedStream(noFetch = false) { + (0, _util.unreachable)("Abstract method `requestLoadedStream` called"); + } + sendProgressiveData(chunk) { + (0, _util.unreachable)("Abstract method `sendProgressiveData` called"); + } + updatePassword(password) { + this._password = password; + } + terminate(reason) { + (0, _util.unreachable)("Abstract method `terminate` called"); + } +} +class LocalPdfManager extends BasePdfManager { + constructor(args) { + super(args); + const stream = new _stream.Stream(args.source); + this.pdfDocument = new _document.PDFDocument(this, stream); + this._loadedStreamPromise = Promise.resolve(stream); + } + async ensure(obj, prop, args) { + const value = obj[prop]; + if (typeof value === "function") { + return value.apply(obj, args); + } + return value; + } + requestRange(begin, end) { + return Promise.resolve(); + } + requestLoadedStream(noFetch = false) { + return this._loadedStreamPromise; + } + terminate(reason) {} +} +exports.LocalPdfManager = LocalPdfManager; +class NetworkPdfManager extends BasePdfManager { + constructor(args) { + super(args); + this.streamManager = new _chunked_stream.ChunkedStreamManager(args.source, { + msgHandler: args.handler, + length: args.length, + disableAutoFetch: args.disableAutoFetch, + rangeChunkSize: args.rangeChunkSize + }); + this.pdfDocument = new _document.PDFDocument(this, this.streamManager.getStream()); + } + async ensure(obj, prop, args) { + try { + const value = obj[prop]; + if (typeof value === "function") { + return value.apply(obj, args); + } + return value; + } catch (ex) { + if (!(ex instanceof _core_utils.MissingDataException)) { + throw ex; + } + await this.requestRange(ex.begin, ex.end); + return this.ensure(obj, prop, args); + } + } + requestRange(begin, end) { + return this.streamManager.requestRange(begin, end); + } + requestLoadedStream(noFetch = false) { + return this.streamManager.requestAllChunks(noFetch); + } + sendProgressiveData(chunk) { + this.streamManager.onReceiveData({ + chunk + }); + } + terminate(reason) { + this.streamManager.abort(reason); + } +} +exports.NetworkPdfManager = NetworkPdfManager; + +/***/ }), +/* 7 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ChunkedStreamManager = exports.ChunkedStream = void 0; +var _core_utils = __w_pdfjs_require__(3); +var _util = __w_pdfjs_require__(2); +var _stream = __w_pdfjs_require__(8); +class ChunkedStream extends _stream.Stream { + constructor(length, chunkSize, manager) { + super(new Uint8Array(length), 0, length, null); + this.chunkSize = chunkSize; + this._loadedChunks = new Set(); + this.numChunks = Math.ceil(length / chunkSize); + this.manager = manager; + this.progressiveDataLength = 0; + this.lastSuccessfulEnsureByteChunk = -1; + } + getMissingChunks() { + const chunks = []; + for (let chunk = 0, n = this.numChunks; chunk < n; ++chunk) { + if (!this._loadedChunks.has(chunk)) { + chunks.push(chunk); + } + } + return chunks; + } + get numChunksLoaded() { + return this._loadedChunks.size; + } + get isDataLoaded() { + return this.numChunksLoaded === this.numChunks; + } + onReceiveData(begin, chunk) { + const chunkSize = this.chunkSize; + if (begin % chunkSize !== 0) { + throw new Error(`Bad begin offset: ${begin}`); + } + const end = begin + chunk.byteLength; + if (end % chunkSize !== 0 && end !== this.bytes.length) { + throw new Error(`Bad end offset: ${end}`); + } + this.bytes.set(new Uint8Array(chunk), begin); + const beginChunk = Math.floor(begin / chunkSize); + const endChunk = Math.floor((end - 1) / chunkSize) + 1; + for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) { + this._loadedChunks.add(curChunk); + } + } + onReceiveProgressiveData(data) { + let position = this.progressiveDataLength; + const beginChunk = Math.floor(position / this.chunkSize); + this.bytes.set(new Uint8Array(data), position); + position += data.byteLength; + this.progressiveDataLength = position; + const endChunk = position >= this.end ? this.numChunks : Math.floor(position / this.chunkSize); + for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) { + this._loadedChunks.add(curChunk); + } + } + ensureByte(pos) { + if (pos < this.progressiveDataLength) { + return; + } + const chunk = Math.floor(pos / this.chunkSize); + if (chunk > this.numChunks) { + return; + } + if (chunk === this.lastSuccessfulEnsureByteChunk) { + return; + } + if (!this._loadedChunks.has(chunk)) { + throw new _core_utils.MissingDataException(pos, pos + 1); + } + this.lastSuccessfulEnsureByteChunk = chunk; + } + ensureRange(begin, end) { + if (begin >= end) { + return; + } + if (end <= this.progressiveDataLength) { + return; + } + const beginChunk = Math.floor(begin / this.chunkSize); + if (beginChunk > this.numChunks) { + return; + } + const endChunk = Math.min(Math.floor((end - 1) / this.chunkSize) + 1, this.numChunks); + for (let chunk = beginChunk; chunk < endChunk; ++chunk) { + if (!this._loadedChunks.has(chunk)) { + throw new _core_utils.MissingDataException(begin, end); + } + } + } + nextEmptyChunk(beginChunk) { + const numChunks = this.numChunks; + for (let i = 0; i < numChunks; ++i) { + const chunk = (beginChunk + i) % numChunks; + if (!this._loadedChunks.has(chunk)) { + return chunk; + } + } + return null; + } + hasChunk(chunk) { + return this._loadedChunks.has(chunk); + } + getByte() { + const pos = this.pos; + if (pos >= this.end) { + return -1; + } + if (pos >= this.progressiveDataLength) { + this.ensureByte(pos); + } + return this.bytes[this.pos++]; + } + getBytes(length) { + const bytes = this.bytes; + const pos = this.pos; + const strEnd = this.end; + if (!length) { + if (strEnd > this.progressiveDataLength) { + this.ensureRange(pos, strEnd); + } + return bytes.subarray(pos, strEnd); + } + let end = pos + length; + if (end > strEnd) { + end = strEnd; + } + if (end > this.progressiveDataLength) { + this.ensureRange(pos, end); + } + this.pos = end; + return bytes.subarray(pos, end); + } + getByteRange(begin, end) { + if (begin < 0) { + begin = 0; + } + if (end > this.end) { + end = this.end; + } + if (end > this.progressiveDataLength) { + this.ensureRange(begin, end); + } + return this.bytes.subarray(begin, end); + } + makeSubStream(start, length, dict = null) { + if (length) { + if (start + length > this.progressiveDataLength) { + this.ensureRange(start, start + length); + } + } else if (start >= this.progressiveDataLength) { + this.ensureByte(start); + } + function ChunkedStreamSubstream() {} + ChunkedStreamSubstream.prototype = Object.create(this); + ChunkedStreamSubstream.prototype.getMissingChunks = function () { + const chunkSize = this.chunkSize; + const beginChunk = Math.floor(this.start / chunkSize); + const endChunk = Math.floor((this.end - 1) / chunkSize) + 1; + const missingChunks = []; + for (let chunk = beginChunk; chunk < endChunk; ++chunk) { + if (!this._loadedChunks.has(chunk)) { + missingChunks.push(chunk); + } + } + return missingChunks; + }; + Object.defineProperty(ChunkedStreamSubstream.prototype, "isDataLoaded", { + get() { + if (this.numChunksLoaded === this.numChunks) { + return true; + } + return this.getMissingChunks().length === 0; + }, + configurable: true + }); + const subStream = new ChunkedStreamSubstream(); + subStream.pos = subStream.start = start; + subStream.end = start + length || this.end; + subStream.dict = dict; + return subStream; + } + getBaseStreams() { + return [this]; + } +} +exports.ChunkedStream = ChunkedStream; +class ChunkedStreamManager { + constructor(pdfNetworkStream, args) { + this.length = args.length; + this.chunkSize = args.rangeChunkSize; + this.stream = new ChunkedStream(this.length, this.chunkSize, this); + this.pdfNetworkStream = pdfNetworkStream; + this.disableAutoFetch = args.disableAutoFetch; + this.msgHandler = args.msgHandler; + this.currRequestId = 0; + this._chunksNeededByRequest = new Map(); + this._requestsByChunk = new Map(); + this._promisesByRequest = new Map(); + this.progressiveDataLength = 0; + this.aborted = false; + this._loadedStreamCapability = new _util.PromiseCapability(); + } + sendRequest(begin, end) { + const rangeReader = this.pdfNetworkStream.getRangeReader(begin, end); + if (!rangeReader.isStreamingSupported) { + rangeReader.onProgress = this.onProgress.bind(this); + } + let chunks = [], + loaded = 0; + return new Promise((resolve, reject) => { + const readChunk = ({ + value, + done + }) => { + try { + if (done) { + const chunkData = (0, _core_utils.arrayBuffersToBytes)(chunks); + chunks = null; + resolve(chunkData); + return; + } + loaded += value.byteLength; + if (rangeReader.isStreamingSupported) { + this.onProgress({ + loaded + }); + } + chunks.push(value); + rangeReader.read().then(readChunk, reject); + } catch (e) { + reject(e); + } + }; + rangeReader.read().then(readChunk, reject); + }).then(data => { + if (this.aborted) { + return; + } + this.onReceiveData({ + chunk: data, + begin + }); + }); + } + requestAllChunks(noFetch = false) { + if (!noFetch) { + const missingChunks = this.stream.getMissingChunks(); + this._requestChunks(missingChunks); + } + return this._loadedStreamCapability.promise; + } + _requestChunks(chunks) { + const requestId = this.currRequestId++; + const chunksNeeded = new Set(); + this._chunksNeededByRequest.set(requestId, chunksNeeded); + for (const chunk of chunks) { + if (!this.stream.hasChunk(chunk)) { + chunksNeeded.add(chunk); + } + } + if (chunksNeeded.size === 0) { + return Promise.resolve(); + } + const capability = new _util.PromiseCapability(); + this._promisesByRequest.set(requestId, capability); + const chunksToRequest = []; + for (const chunk of chunksNeeded) { + let requestIds = this._requestsByChunk.get(chunk); + if (!requestIds) { + requestIds = []; + this._requestsByChunk.set(chunk, requestIds); + chunksToRequest.push(chunk); + } + requestIds.push(requestId); + } + if (chunksToRequest.length > 0) { + const groupedChunksToRequest = this.groupChunks(chunksToRequest); + for (const groupedChunk of groupedChunksToRequest) { + const begin = groupedChunk.beginChunk * this.chunkSize; + const end = Math.min(groupedChunk.endChunk * this.chunkSize, this.length); + this.sendRequest(begin, end).catch(capability.reject); + } + } + return capability.promise.catch(reason => { + if (this.aborted) { + return; + } + throw reason; + }); + } + getStream() { + return this.stream; + } + requestRange(begin, end) { + end = Math.min(end, this.length); + const beginChunk = this.getBeginChunk(begin); + const endChunk = this.getEndChunk(end); + const chunks = []; + for (let chunk = beginChunk; chunk < endChunk; ++chunk) { + chunks.push(chunk); + } + return this._requestChunks(chunks); + } + requestRanges(ranges = []) { + const chunksToRequest = []; + for (const range of ranges) { + const beginChunk = this.getBeginChunk(range.begin); + const endChunk = this.getEndChunk(range.end); + for (let chunk = beginChunk; chunk < endChunk; ++chunk) { + if (!chunksToRequest.includes(chunk)) { + chunksToRequest.push(chunk); + } + } + } + chunksToRequest.sort(function (a, b) { + return a - b; + }); + return this._requestChunks(chunksToRequest); + } + groupChunks(chunks) { + const groupedChunks = []; + let beginChunk = -1; + let prevChunk = -1; + for (let i = 0, ii = chunks.length; i < ii; ++i) { + const chunk = chunks[i]; + if (beginChunk < 0) { + beginChunk = chunk; + } + if (prevChunk >= 0 && prevChunk + 1 !== chunk) { + groupedChunks.push({ + beginChunk, + endChunk: prevChunk + 1 + }); + beginChunk = chunk; + } + if (i + 1 === chunks.length) { + groupedChunks.push({ + beginChunk, + endChunk: chunk + 1 + }); + } + prevChunk = chunk; + } + return groupedChunks; + } + onProgress(args) { + this.msgHandler.send("DocProgress", { + loaded: this.stream.numChunksLoaded * this.chunkSize + args.loaded, + total: this.length + }); + } + onReceiveData(args) { + const chunk = args.chunk; + const isProgressive = args.begin === undefined; + const begin = isProgressive ? this.progressiveDataLength : args.begin; + const end = begin + chunk.byteLength; + const beginChunk = Math.floor(begin / this.chunkSize); + const endChunk = end < this.length ? Math.floor(end / this.chunkSize) : Math.ceil(end / this.chunkSize); + if (isProgressive) { + this.stream.onReceiveProgressiveData(chunk); + this.progressiveDataLength = end; + } else { + this.stream.onReceiveData(begin, chunk); + } + if (this.stream.isDataLoaded) { + this._loadedStreamCapability.resolve(this.stream); + } + const loadedRequests = []; + for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) { + const requestIds = this._requestsByChunk.get(curChunk); + if (!requestIds) { + continue; + } + this._requestsByChunk.delete(curChunk); + for (const requestId of requestIds) { + const chunksNeeded = this._chunksNeededByRequest.get(requestId); + if (chunksNeeded.has(curChunk)) { + chunksNeeded.delete(curChunk); + } + if (chunksNeeded.size > 0) { + continue; + } + loadedRequests.push(requestId); + } + } + if (!this.disableAutoFetch && this._requestsByChunk.size === 0) { + let nextEmptyChunk; + if (this.stream.numChunksLoaded === 1) { + const lastChunk = this.stream.numChunks - 1; + if (!this.stream.hasChunk(lastChunk)) { + nextEmptyChunk = lastChunk; + } + } else { + nextEmptyChunk = this.stream.nextEmptyChunk(endChunk); + } + if (Number.isInteger(nextEmptyChunk)) { + this._requestChunks([nextEmptyChunk]); + } + } + for (const requestId of loadedRequests) { + const capability = this._promisesByRequest.get(requestId); + this._promisesByRequest.delete(requestId); + capability.resolve(); + } + this.msgHandler.send("DocProgress", { + loaded: this.stream.numChunksLoaded * this.chunkSize, + total: this.length + }); + } + onError(err) { + this._loadedStreamCapability.reject(err); + } + getBeginChunk(begin) { + return Math.floor(begin / this.chunkSize); + } + getEndChunk(end) { + return Math.floor((end - 1) / this.chunkSize) + 1; + } + abort(reason) { + this.aborted = true; + this.pdfNetworkStream?.cancelAllRequests(reason); + for (const capability of this._promisesByRequest.values()) { + capability.reject(reason); + } + } +} +exports.ChunkedStreamManager = ChunkedStreamManager; + +/***/ }), +/* 8 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.StringStream = exports.Stream = exports.NullStream = void 0; +var _base_stream = __w_pdfjs_require__(5); +var _util = __w_pdfjs_require__(2); +class Stream extends _base_stream.BaseStream { + constructor(arrayBuffer, start, length, dict) { + super(); + this.bytes = arrayBuffer instanceof Uint8Array ? arrayBuffer : new Uint8Array(arrayBuffer); + this.start = start || 0; + this.pos = this.start; + this.end = start + length || this.bytes.length; + this.dict = dict; + } + get length() { + return this.end - this.start; + } + get isEmpty() { + return this.length === 0; + } + getByte() { + if (this.pos >= this.end) { + return -1; + } + return this.bytes[this.pos++]; + } + getBytes(length) { + const bytes = this.bytes; + const pos = this.pos; + const strEnd = this.end; + if (!length) { + return bytes.subarray(pos, strEnd); + } + let end = pos + length; + if (end > strEnd) { + end = strEnd; + } + this.pos = end; + return bytes.subarray(pos, end); + } + getByteRange(begin, end) { + if (begin < 0) { + begin = 0; + } + if (end > this.end) { + end = this.end; + } + return this.bytes.subarray(begin, end); + } + reset() { + this.pos = this.start; + } + moveStart() { + this.start = this.pos; + } + makeSubStream(start, length, dict = null) { + return new Stream(this.bytes.buffer, start, length, dict); + } +} +exports.Stream = Stream; +class StringStream extends Stream { + constructor(str) { + super((0, _util.stringToBytes)(str)); + } +} +exports.StringStream = StringStream; +class NullStream extends Stream { + constructor() { + super(new Uint8Array(0)); + } +} +exports.NullStream = NullStream; + +/***/ }), +/* 9 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Page = exports.PDFDocument = void 0; +var _util = __w_pdfjs_require__(2); +var _annotation = __w_pdfjs_require__(10); +var _core_utils = __w_pdfjs_require__(3); +var _primitives = __w_pdfjs_require__(4); +var _xfa_fonts = __w_pdfjs_require__(51); +var _base_stream = __w_pdfjs_require__(5); +var _crypto = __w_pdfjs_require__(74); +var _catalog = __w_pdfjs_require__(66); +var _cleanup_helper = __w_pdfjs_require__(68); +var _dataset_reader = __w_pdfjs_require__(102); +var _parser = __w_pdfjs_require__(16); +var _stream = __w_pdfjs_require__(8); +var _object_loader = __w_pdfjs_require__(76); +var _operator_list = __w_pdfjs_require__(64); +var _evaluator = __w_pdfjs_require__(13); +var _decode_stream = __w_pdfjs_require__(18); +var _struct_tree = __w_pdfjs_require__(72); +var _writer = __w_pdfjs_require__(73); +var _factory = __w_pdfjs_require__(77); +var _xref = __w_pdfjs_require__(103); +const DEFAULT_USER_UNIT = 1.0; +const LETTER_SIZE_MEDIABOX = [0, 0, 612, 792]; +class Page { + constructor({ + pdfManager, + xref, + pageIndex, + pageDict, + ref, + globalIdFactory, + fontCache, + builtInCMapCache, + standardFontDataCache, + globalImageCache, + systemFontCache, + nonBlendModesSet, + xfaFactory + }) { + this.pdfManager = pdfManager; + this.pageIndex = pageIndex; + this.pageDict = pageDict; + this.xref = xref; + this.ref = ref; + this.fontCache = fontCache; + this.builtInCMapCache = builtInCMapCache; + this.standardFontDataCache = standardFontDataCache; + this.globalImageCache = globalImageCache; + this.systemFontCache = systemFontCache; + this.nonBlendModesSet = nonBlendModesSet; + this.evaluatorOptions = pdfManager.evaluatorOptions; + this.resourcesPromise = null; + this.xfaFactory = xfaFactory; + const idCounters = { + obj: 0 + }; + this._localIdFactory = class extends globalIdFactory { + static createObjId() { + return `p${pageIndex}_${++idCounters.obj}`; + } + static getPageObjId() { + return `p${ref.toString()}`; + } + }; + } + _getInheritableProperty(key, getArray = false) { + const value = (0, _core_utils.getInheritableProperty)({ + dict: this.pageDict, + key, + getArray, + stopWhenFound: false + }); + if (!Array.isArray(value)) { + return value; + } + if (value.length === 1 || !(value[0] instanceof _primitives.Dict)) { + return value[0]; + } + return _primitives.Dict.merge({ + xref: this.xref, + dictArray: value + }); + } + get content() { + return this.pageDict.getArray("Contents"); + } + get resources() { + const resources = this._getInheritableProperty("Resources"); + return (0, _util.shadow)(this, "resources", resources instanceof _primitives.Dict ? resources : _primitives.Dict.empty); + } + _getBoundingBox(name) { + if (this.xfaData) { + return this.xfaData.bbox; + } + let box = this._getInheritableProperty(name, true); + if (Array.isArray(box) && box.length === 4) { + box = _util.Util.normalizeRect(box); + if (box[2] - box[0] > 0 && box[3] - box[1] > 0) { + return box; + } + (0, _util.warn)(`Empty, or invalid, /${name} entry.`); + } + return null; + } + get mediaBox() { + return (0, _util.shadow)(this, "mediaBox", this._getBoundingBox("MediaBox") || LETTER_SIZE_MEDIABOX); + } + get cropBox() { + return (0, _util.shadow)(this, "cropBox", this._getBoundingBox("CropBox") || this.mediaBox); + } + get userUnit() { + let obj = this.pageDict.get("UserUnit"); + if (typeof obj !== "number" || obj <= 0) { + obj = DEFAULT_USER_UNIT; + } + return (0, _util.shadow)(this, "userUnit", obj); + } + get view() { + const { + cropBox, + mediaBox + } = this; + if (cropBox !== mediaBox && !(0, _util.isArrayEqual)(cropBox, mediaBox)) { + const box = _util.Util.intersect(cropBox, mediaBox); + if (box && box[2] - box[0] > 0 && box[3] - box[1] > 0) { + return (0, _util.shadow)(this, "view", box); + } + (0, _util.warn)("Empty /CropBox and /MediaBox intersection."); + } + return (0, _util.shadow)(this, "view", mediaBox); + } + get rotate() { + let rotate = this._getInheritableProperty("Rotate") || 0; + if (rotate % 90 !== 0) { + rotate = 0; + } else if (rotate >= 360) { + rotate %= 360; + } else if (rotate < 0) { + rotate = (rotate % 360 + 360) % 360; + } + return (0, _util.shadow)(this, "rotate", rotate); + } + _onSubStreamError(reason, objId) { + if (this.evaluatorOptions.ignoreErrors) { + (0, _util.warn)(`getContentStream - ignoring sub-stream (${objId}): "${reason}".`); + return; + } + throw reason; + } + getContentStream() { + return this.pdfManager.ensure(this, "content").then(content => { + if (content instanceof _base_stream.BaseStream) { + return content; + } + if (Array.isArray(content)) { + return new _decode_stream.StreamsSequenceStream(content, this._onSubStreamError.bind(this)); + } + return new _stream.NullStream(); + }); + } + get xfaData() { + return (0, _util.shadow)(this, "xfaData", this.xfaFactory ? { + bbox: this.xfaFactory.getBoundingBox(this.pageIndex) + } : null); + } + #replaceIdByRef(annotations, deletedAnnotations, existingAnnotations) { + for (const annotation of annotations) { + if (annotation.id) { + const ref = _primitives.Ref.fromString(annotation.id); + if (!ref) { + (0, _util.warn)(`A non-linked annotation cannot be modified: ${annotation.id}`); + continue; + } + if (annotation.deleted) { + deletedAnnotations.put(ref); + continue; + } + existingAnnotations?.put(ref); + annotation.ref = ref; + delete annotation.id; + } + } + } + async saveNewAnnotations(handler, task, annotations, imagePromises) { + if (this.xfaFactory) { + throw new Error("XFA: Cannot save new annotations."); + } + const partialEvaluator = new _evaluator.PartialEvaluator({ + xref: this.xref, + handler, + pageIndex: this.pageIndex, + idFactory: this._localIdFactory, + fontCache: this.fontCache, + builtInCMapCache: this.builtInCMapCache, + standardFontDataCache: this.standardFontDataCache, + globalImageCache: this.globalImageCache, + systemFontCache: this.systemFontCache, + options: this.evaluatorOptions + }); + const deletedAnnotations = new _primitives.RefSet(); + const existingAnnotations = new _primitives.RefSet(); + this.#replaceIdByRef(annotations, deletedAnnotations, existingAnnotations); + const pageDict = this.pageDict; + const annotationsArray = this.annotations.filter(a => !(a instanceof _primitives.Ref && deletedAnnotations.has(a))); + const newData = await _annotation.AnnotationFactory.saveNewAnnotations(partialEvaluator, task, annotations, imagePromises); + for (const { + ref + } of newData.annotations) { + if (ref instanceof _primitives.Ref && !existingAnnotations.has(ref)) { + annotationsArray.push(ref); + } + } + const savedDict = pageDict.get("Annots"); + pageDict.set("Annots", annotationsArray); + const buffer = []; + await (0, _writer.writeObject)(this.ref, pageDict, buffer, this.xref); + if (savedDict) { + pageDict.set("Annots", savedDict); + } + const objects = newData.dependencies; + objects.push({ + ref: this.ref, + data: buffer.join("") + }, ...newData.annotations); + return objects; + } + save(handler, task, annotationStorage) { + const partialEvaluator = new _evaluator.PartialEvaluator({ + xref: this.xref, + handler, + pageIndex: this.pageIndex, + idFactory: this._localIdFactory, + fontCache: this.fontCache, + builtInCMapCache: this.builtInCMapCache, + standardFontDataCache: this.standardFontDataCache, + globalImageCache: this.globalImageCache, + systemFontCache: this.systemFontCache, + options: this.evaluatorOptions + }); + return this._parsedAnnotations.then(function (annotations) { + const newRefsPromises = []; + for (const annotation of annotations) { + if (!annotation.mustBePrinted(annotationStorage)) { + continue; + } + newRefsPromises.push(annotation.save(partialEvaluator, task, annotationStorage).catch(function (reason) { + (0, _util.warn)("save - ignoring annotation data during " + `"${task.name}" task: "${reason}".`); + return null; + })); + } + return Promise.all(newRefsPromises).then(function (newRefs) { + return newRefs.filter(newRef => !!newRef); + }); + }); + } + loadResources(keys) { + if (!this.resourcesPromise) { + this.resourcesPromise = this.pdfManager.ensure(this, "resources"); + } + return this.resourcesPromise.then(() => { + const objectLoader = new _object_loader.ObjectLoader(this.resources, keys, this.xref); + return objectLoader.load(); + }); + } + getOperatorList({ + handler, + sink, + task, + intent, + cacheKey, + annotationStorage = null + }) { + const contentStreamPromise = this.getContentStream(); + const resourcesPromise = this.loadResources(["ColorSpace", "ExtGState", "Font", "Pattern", "Properties", "Shading", "XObject"]); + const partialEvaluator = new _evaluator.PartialEvaluator({ + xref: this.xref, + handler, + pageIndex: this.pageIndex, + idFactory: this._localIdFactory, + fontCache: this.fontCache, + builtInCMapCache: this.builtInCMapCache, + standardFontDataCache: this.standardFontDataCache, + globalImageCache: this.globalImageCache, + systemFontCache: this.systemFontCache, + options: this.evaluatorOptions + }); + const newAnnotationsByPage = !this.xfaFactory ? (0, _core_utils.getNewAnnotationsMap)(annotationStorage) : null; + let deletedAnnotations = null; + let newAnnotationsPromise = Promise.resolve(null); + if (newAnnotationsByPage) { + const newAnnotations = newAnnotationsByPage.get(this.pageIndex); + if (newAnnotations) { + const annotationGlobalsPromise = this.pdfManager.ensureDoc("annotationGlobals"); + let imagePromises; + const missingBitmaps = new Set(); + for (const { + bitmapId, + bitmap + } of newAnnotations) { + if (bitmapId && !bitmap && !missingBitmaps.has(bitmapId)) { + missingBitmaps.add(bitmapId); + } + } + const { + isOffscreenCanvasSupported + } = this.evaluatorOptions; + if (missingBitmaps.size > 0) { + const annotationWithBitmaps = newAnnotations.slice(); + for (const [key, annotation] of annotationStorage) { + if (!key.startsWith(_util.AnnotationEditorPrefix)) { + continue; + } + if (annotation.bitmap && missingBitmaps.has(annotation.bitmapId)) { + annotationWithBitmaps.push(annotation); + } + } + imagePromises = _annotation.AnnotationFactory.generateImages(annotationWithBitmaps, this.xref, isOffscreenCanvasSupported); + } else { + imagePromises = _annotation.AnnotationFactory.generateImages(newAnnotations, this.xref, isOffscreenCanvasSupported); + } + deletedAnnotations = new _primitives.RefSet(); + this.#replaceIdByRef(newAnnotations, deletedAnnotations, null); + newAnnotationsPromise = annotationGlobalsPromise.then(annotationGlobals => { + if (!annotationGlobals) { + return null; + } + return _annotation.AnnotationFactory.printNewAnnotations(annotationGlobals, partialEvaluator, task, newAnnotations, imagePromises); + }); + } + } + const dataPromises = Promise.all([contentStreamPromise, resourcesPromise]); + const pageListPromise = dataPromises.then(([contentStream]) => { + const opList = new _operator_list.OperatorList(intent, sink); + handler.send("StartRenderPage", { + transparency: partialEvaluator.hasBlendModes(this.resources, this.nonBlendModesSet), + pageIndex: this.pageIndex, + cacheKey + }); + return partialEvaluator.getOperatorList({ + stream: contentStream, + task, + resources: this.resources, + operatorList: opList + }).then(function () { + return opList; + }); + }); + return Promise.all([pageListPromise, this._parsedAnnotations, newAnnotationsPromise]).then(function ([pageOpList, annotations, newAnnotations]) { + if (newAnnotations) { + annotations = annotations.filter(a => !(a.ref && deletedAnnotations.has(a.ref))); + for (let i = 0, ii = newAnnotations.length; i < ii; i++) { + const newAnnotation = newAnnotations[i]; + if (newAnnotation.refToReplace) { + const j = annotations.findIndex(a => a.ref && (0, _primitives.isRefsEqual)(a.ref, newAnnotation.refToReplace)); + if (j >= 0) { + annotations.splice(j, 1, newAnnotation); + newAnnotations.splice(i--, 1); + ii--; + } + } + } + annotations = annotations.concat(newAnnotations); + } + if (annotations.length === 0 || intent & _util.RenderingIntentFlag.ANNOTATIONS_DISABLE) { + pageOpList.flush(true); + return { + length: pageOpList.totalLength + }; + } + const renderForms = !!(intent & _util.RenderingIntentFlag.ANNOTATIONS_FORMS), + intentAny = !!(intent & _util.RenderingIntentFlag.ANY), + intentDisplay = !!(intent & _util.RenderingIntentFlag.DISPLAY), + intentPrint = !!(intent & _util.RenderingIntentFlag.PRINT); + const opListPromises = []; + for (const annotation of annotations) { + if (intentAny || intentDisplay && annotation.mustBeViewed(annotationStorage, renderForms) || intentPrint && annotation.mustBePrinted(annotationStorage)) { + opListPromises.push(annotation.getOperatorList(partialEvaluator, task, intent, renderForms, annotationStorage).catch(function (reason) { + (0, _util.warn)("getOperatorList - ignoring annotation data during " + `"${task.name}" task: "${reason}".`); + return { + opList: null, + separateForm: false, + separateCanvas: false + }; + })); + } + } + return Promise.all(opListPromises).then(function (opLists) { + let form = false, + canvas = false; + for (const { + opList, + separateForm, + separateCanvas + } of opLists) { + pageOpList.addOpList(opList); + form ||= separateForm; + canvas ||= separateCanvas; + } + pageOpList.flush(true, { + form, + canvas + }); + return { + length: pageOpList.totalLength + }; + }); + }); + } + extractTextContent({ + handler, + task, + includeMarkedContent, + disableNormalization, + sink + }) { + const contentStreamPromise = this.getContentStream(); + const resourcesPromise = this.loadResources(["ExtGState", "Font", "Properties", "XObject"]); + const dataPromises = Promise.all([contentStreamPromise, resourcesPromise]); + return dataPromises.then(([contentStream]) => { + const partialEvaluator = new _evaluator.PartialEvaluator({ + xref: this.xref, + handler, + pageIndex: this.pageIndex, + idFactory: this._localIdFactory, + fontCache: this.fontCache, + builtInCMapCache: this.builtInCMapCache, + standardFontDataCache: this.standardFontDataCache, + globalImageCache: this.globalImageCache, + systemFontCache: this.systemFontCache, + options: this.evaluatorOptions + }); + return partialEvaluator.getTextContent({ + stream: contentStream, + task, + resources: this.resources, + includeMarkedContent, + disableNormalization, + sink, + viewBox: this.view + }); + }); + } + async getStructTree() { + const structTreeRoot = await this.pdfManager.ensureCatalog("structTreeRoot"); + if (!structTreeRoot) { + return null; + } + await this._parsedAnnotations; + const structTree = await this.pdfManager.ensure(this, "_parseStructTree", [structTreeRoot]); + return structTree.serializable; + } + _parseStructTree(structTreeRoot) { + const tree = new _struct_tree.StructTreePage(structTreeRoot, this.pageDict); + tree.parse(this.ref); + return tree; + } + async getAnnotationsData(handler, task, intent) { + const annotations = await this._parsedAnnotations; + if (annotations.length === 0) { + return annotations; + } + const annotationsData = [], + textContentPromises = []; + let partialEvaluator; + const intentAny = !!(intent & _util.RenderingIntentFlag.ANY), + intentDisplay = !!(intent & _util.RenderingIntentFlag.DISPLAY), + intentPrint = !!(intent & _util.RenderingIntentFlag.PRINT); + for (const annotation of annotations) { + const isVisible = intentAny || intentDisplay && annotation.viewable; + if (isVisible || intentPrint && annotation.printable) { + annotationsData.push(annotation.data); + } + if (annotation.hasTextContent && isVisible) { + partialEvaluator ||= new _evaluator.PartialEvaluator({ + xref: this.xref, + handler, + pageIndex: this.pageIndex, + idFactory: this._localIdFactory, + fontCache: this.fontCache, + builtInCMapCache: this.builtInCMapCache, + standardFontDataCache: this.standardFontDataCache, + globalImageCache: this.globalImageCache, + systemFontCache: this.systemFontCache, + options: this.evaluatorOptions + }); + textContentPromises.push(annotation.extractTextContent(partialEvaluator, task, [-Infinity, -Infinity, Infinity, Infinity]).catch(function (reason) { + (0, _util.warn)(`getAnnotationsData - ignoring textContent during "${task.name}" task: "${reason}".`); + })); + } + } + await Promise.all(textContentPromises); + return annotationsData; + } + get annotations() { + const annots = this._getInheritableProperty("Annots"); + return (0, _util.shadow)(this, "annotations", Array.isArray(annots) ? annots : []); + } + get _parsedAnnotations() { + const promise = this.pdfManager.ensure(this, "annotations").then(async annots => { + if (annots.length === 0) { + return annots; + } + const annotationGlobals = await this.pdfManager.ensureDoc("annotationGlobals"); + if (!annotationGlobals) { + return []; + } + const annotationPromises = []; + for (const annotationRef of annots) { + annotationPromises.push(_annotation.AnnotationFactory.create(this.xref, annotationRef, annotationGlobals, this._localIdFactory, false, this.ref).catch(function (reason) { + (0, _util.warn)(`_parsedAnnotations: "${reason}".`); + return null; + })); + } + const sortedAnnotations = []; + let popupAnnotations; + for (const annotation of await Promise.all(annotationPromises)) { + if (!annotation) { + continue; + } + if (annotation instanceof _annotation.PopupAnnotation) { + (popupAnnotations ||= []).push(annotation); + continue; + } + sortedAnnotations.push(annotation); + } + if (popupAnnotations) { + sortedAnnotations.push(...popupAnnotations); + } + return sortedAnnotations; + }); + return (0, _util.shadow)(this, "_parsedAnnotations", promise); + } + get jsActions() { + const actions = (0, _core_utils.collectActions)(this.xref, this.pageDict, _util.PageActionEventType); + return (0, _util.shadow)(this, "jsActions", actions); + } +} +exports.Page = Page; +const PDF_HEADER_SIGNATURE = new Uint8Array([0x25, 0x50, 0x44, 0x46, 0x2d]); +const STARTXREF_SIGNATURE = new Uint8Array([0x73, 0x74, 0x61, 0x72, 0x74, 0x78, 0x72, 0x65, 0x66]); +const ENDOBJ_SIGNATURE = new Uint8Array([0x65, 0x6e, 0x64, 0x6f, 0x62, 0x6a]); +const FINGERPRINT_FIRST_BYTES = 1024; +const EMPTY_FINGERPRINT = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; +function find(stream, signature, limit = 1024, backwards = false) { + const signatureLength = signature.length; + const scanBytes = stream.peekBytes(limit); + const scanLength = scanBytes.length - signatureLength; + if (scanLength <= 0) { + return false; + } + if (backwards) { + const signatureEnd = signatureLength - 1; + let pos = scanBytes.length - 1; + while (pos >= signatureEnd) { + let j = 0; + while (j < signatureLength && scanBytes[pos - j] === signature[signatureEnd - j]) { + j++; + } + if (j >= signatureLength) { + stream.pos += pos - signatureEnd; + return true; + } + pos--; + } + } else { + let pos = 0; + while (pos <= scanLength) { + let j = 0; + while (j < signatureLength && scanBytes[pos + j] === signature[j]) { + j++; + } + if (j >= signatureLength) { + stream.pos += pos; + return true; + } + pos++; + } + } + return false; +} +class PDFDocument { + constructor(pdfManager, stream) { + if (stream.length <= 0) { + throw new _util.InvalidPDFException("The PDF file is empty, i.e. its size is zero bytes."); + } + this.pdfManager = pdfManager; + this.stream = stream; + this.xref = new _xref.XRef(stream, pdfManager); + this._pagePromises = new Map(); + this._version = null; + const idCounters = { + font: 0 + }; + this._globalIdFactory = class { + static getDocId() { + return `g_${pdfManager.docId}`; + } + static createFontId() { + return `f${++idCounters.font}`; + } + static createObjId() { + (0, _util.unreachable)("Abstract method `createObjId` called."); + } + static getPageObjId() { + (0, _util.unreachable)("Abstract method `getPageObjId` called."); + } + }; + } + parse(recoveryMode) { + this.xref.parse(recoveryMode); + this.catalog = new _catalog.Catalog(this.pdfManager, this.xref); + } + get linearization() { + let linearization = null; + try { + linearization = _parser.Linearization.create(this.stream); + } catch (err) { + if (err instanceof _core_utils.MissingDataException) { + throw err; + } + (0, _util.info)(err); + } + return (0, _util.shadow)(this, "linearization", linearization); + } + get startXRef() { + const stream = this.stream; + let startXRef = 0; + if (this.linearization) { + stream.reset(); + if (find(stream, ENDOBJ_SIGNATURE)) { + startXRef = stream.pos + 6 - stream.start; + } + } else { + const step = 1024; + const startXRefLength = STARTXREF_SIGNATURE.length; + let found = false, + pos = stream.end; + while (!found && pos > 0) { + pos -= step - startXRefLength; + if (pos < 0) { + pos = 0; + } + stream.pos = pos; + found = find(stream, STARTXREF_SIGNATURE, step, true); + } + if (found) { + stream.skip(9); + let ch; + do { + ch = stream.getByte(); + } while ((0, _core_utils.isWhiteSpace)(ch)); + let str = ""; + while (ch >= 0x20 && ch <= 0x39) { + str += String.fromCharCode(ch); + ch = stream.getByte(); + } + startXRef = parseInt(str, 10); + if (isNaN(startXRef)) { + startXRef = 0; + } + } + } + return (0, _util.shadow)(this, "startXRef", startXRef); + } + checkHeader() { + const stream = this.stream; + stream.reset(); + if (!find(stream, PDF_HEADER_SIGNATURE)) { + return; + } + stream.moveStart(); + stream.skip(PDF_HEADER_SIGNATURE.length); + let version = "", + ch; + while ((ch = stream.getByte()) > 0x20 && version.length < 7) { + version += String.fromCharCode(ch); + } + if (_core_utils.PDF_VERSION_REGEXP.test(version)) { + this._version = version; + } else { + (0, _util.warn)(`Invalid PDF header version: ${version}`); + } + } + parseStartXRef() { + this.xref.setStartXRef(this.startXRef); + } + get numPages() { + let num = 0; + if (this.catalog.hasActualNumPages) { + num = this.catalog.numPages; + } else if (this.xfaFactory) { + num = this.xfaFactory.getNumPages(); + } else if (this.linearization) { + num = this.linearization.numPages; + } else { + num = this.catalog.numPages; + } + return (0, _util.shadow)(this, "numPages", num); + } + _hasOnlyDocumentSignatures(fields, recursionDepth = 0) { + const RECURSION_LIMIT = 10; + if (!Array.isArray(fields)) { + return false; + } + return fields.every(field => { + field = this.xref.fetchIfRef(field); + if (!(field instanceof _primitives.Dict)) { + return false; + } + if (field.has("Kids")) { + if (++recursionDepth > RECURSION_LIMIT) { + (0, _util.warn)("_hasOnlyDocumentSignatures: maximum recursion depth reached"); + return false; + } + return this._hasOnlyDocumentSignatures(field.get("Kids"), recursionDepth); + } + const isSignature = (0, _primitives.isName)(field.get("FT"), "Sig"); + const rectangle = field.get("Rect"); + const isInvisible = Array.isArray(rectangle) && rectangle.every(value => value === 0); + return isSignature && isInvisible; + }); + } + get _xfaStreams() { + const acroForm = this.catalog.acroForm; + if (!acroForm) { + return null; + } + const xfa = acroForm.get("XFA"); + const entries = { + "xdp:xdp": "", + template: "", + datasets: "", + config: "", + connectionSet: "", + localeSet: "", + stylesheet: "", + "/xdp:xdp": "" + }; + if (xfa instanceof _base_stream.BaseStream && !xfa.isEmpty) { + entries["xdp:xdp"] = xfa; + return entries; + } + if (!Array.isArray(xfa) || xfa.length === 0) { + return null; + } + for (let i = 0, ii = xfa.length; i < ii; i += 2) { + let name; + if (i === 0) { + name = "xdp:xdp"; + } else if (i === ii - 2) { + name = "/xdp:xdp"; + } else { + name = xfa[i]; + } + if (!entries.hasOwnProperty(name)) { + continue; + } + const data = this.xref.fetchIfRef(xfa[i + 1]); + if (!(data instanceof _base_stream.BaseStream) || data.isEmpty) { + continue; + } + entries[name] = data; + } + return entries; + } + get xfaDatasets() { + const streams = this._xfaStreams; + if (!streams) { + return (0, _util.shadow)(this, "xfaDatasets", null); + } + for (const key of ["datasets", "xdp:xdp"]) { + const stream = streams[key]; + if (!stream) { + continue; + } + try { + const str = (0, _util.stringToUTF8String)(stream.getString()); + const data = { + [key]: str + }; + return (0, _util.shadow)(this, "xfaDatasets", new _dataset_reader.DatasetReader(data)); + } catch { + (0, _util.warn)("XFA - Invalid utf-8 string."); + break; + } + } + return (0, _util.shadow)(this, "xfaDatasets", null); + } + get xfaData() { + const streams = this._xfaStreams; + if (!streams) { + return null; + } + const data = Object.create(null); + for (const [key, stream] of Object.entries(streams)) { + if (!stream) { + continue; + } + try { + data[key] = (0, _util.stringToUTF8String)(stream.getString()); + } catch { + (0, _util.warn)("XFA - Invalid utf-8 string."); + return null; + } + } + return data; + } + get xfaFactory() { + let data; + if (this.pdfManager.enableXfa && this.catalog.needsRendering && this.formInfo.hasXfa && !this.formInfo.hasAcroForm) { + data = this.xfaData; + } + return (0, _util.shadow)(this, "xfaFactory", data ? new _factory.XFAFactory(data) : null); + } + get isPureXfa() { + return this.xfaFactory ? this.xfaFactory.isValid() : false; + } + get htmlForXfa() { + return this.xfaFactory ? this.xfaFactory.getPages() : null; + } + async loadXfaImages() { + const xfaImagesDict = await this.pdfManager.ensureCatalog("xfaImages"); + if (!xfaImagesDict) { + return; + } + const keys = xfaImagesDict.getKeys(); + const objectLoader = new _object_loader.ObjectLoader(xfaImagesDict, keys, this.xref); + await objectLoader.load(); + const xfaImages = new Map(); + for (const key of keys) { + const stream = xfaImagesDict.get(key); + if (stream instanceof _base_stream.BaseStream) { + xfaImages.set(key, stream.getBytes()); + } + } + this.xfaFactory.setImages(xfaImages); + } + async loadXfaFonts(handler, task) { + const acroForm = await this.pdfManager.ensureCatalog("acroForm"); + if (!acroForm) { + return; + } + const resources = await acroForm.getAsync("DR"); + if (!(resources instanceof _primitives.Dict)) { + return; + } + const objectLoader = new _object_loader.ObjectLoader(resources, ["Font"], this.xref); + await objectLoader.load(); + const fontRes = resources.get("Font"); + if (!(fontRes instanceof _primitives.Dict)) { + return; + } + const options = Object.assign(Object.create(null), this.pdfManager.evaluatorOptions); + options.useSystemFonts = false; + const partialEvaluator = new _evaluator.PartialEvaluator({ + xref: this.xref, + handler, + pageIndex: -1, + idFactory: this._globalIdFactory, + fontCache: this.catalog.fontCache, + builtInCMapCache: this.catalog.builtInCMapCache, + standardFontDataCache: this.catalog.standardFontDataCache, + options + }); + const operatorList = new _operator_list.OperatorList(); + const pdfFonts = []; + const initialState = { + get font() { + return pdfFonts.at(-1); + }, + set font(font) { + pdfFonts.push(font); + }, + clone() { + return this; + } + }; + const fonts = new Map(); + fontRes.forEach((fontName, font) => { + fonts.set(fontName, font); + }); + const promises = []; + for (const [fontName, font] of fonts) { + const descriptor = font.get("FontDescriptor"); + if (!(descriptor instanceof _primitives.Dict)) { + continue; + } + let fontFamily = descriptor.get("FontFamily"); + fontFamily = fontFamily.replaceAll(/[ ]+(\d)/g, "$1"); + const fontWeight = descriptor.get("FontWeight"); + const italicAngle = -descriptor.get("ItalicAngle"); + const cssFontInfo = { + fontFamily, + fontWeight, + italicAngle + }; + if (!(0, _core_utils.validateCSSFont)(cssFontInfo)) { + continue; + } + promises.push(partialEvaluator.handleSetFont(resources, [_primitives.Name.get(fontName), 1], null, operatorList, task, initialState, null, cssFontInfo).catch(function (reason) { + (0, _util.warn)(`loadXfaFonts: "${reason}".`); + return null; + })); + } + await Promise.all(promises); + const missingFonts = this.xfaFactory.setFonts(pdfFonts); + if (!missingFonts) { + return; + } + options.ignoreErrors = true; + promises.length = 0; + pdfFonts.length = 0; + const reallyMissingFonts = new Set(); + for (const missing of missingFonts) { + if (!(0, _xfa_fonts.getXfaFontName)(`${missing}-Regular`)) { + reallyMissingFonts.add(missing); + } + } + if (reallyMissingFonts.size) { + missingFonts.push("PdfJS-Fallback"); + } + for (const missing of missingFonts) { + if (reallyMissingFonts.has(missing)) { + continue; + } + for (const fontInfo of [{ + name: "Regular", + fontWeight: 400, + italicAngle: 0 + }, { + name: "Bold", + fontWeight: 700, + italicAngle: 0 + }, { + name: "Italic", + fontWeight: 400, + italicAngle: 12 + }, { + name: "BoldItalic", + fontWeight: 700, + italicAngle: 12 + }]) { + const name = `${missing}-${fontInfo.name}`; + const dict = (0, _xfa_fonts.getXfaFontDict)(name); + promises.push(partialEvaluator.handleSetFont(resources, [_primitives.Name.get(name), 1], null, operatorList, task, initialState, dict, { + fontFamily: missing, + fontWeight: fontInfo.fontWeight, + italicAngle: fontInfo.italicAngle + }).catch(function (reason) { + (0, _util.warn)(`loadXfaFonts: "${reason}".`); + return null; + })); + } + } + await Promise.all(promises); + this.xfaFactory.appendFonts(pdfFonts, reallyMissingFonts); + } + async serializeXfaData(annotationStorage) { + return this.xfaFactory ? this.xfaFactory.serializeData(annotationStorage) : null; + } + get version() { + return this.catalog.version || this._version; + } + get formInfo() { + const formInfo = { + hasFields: false, + hasAcroForm: false, + hasXfa: false, + hasSignatures: false + }; + const acroForm = this.catalog.acroForm; + if (!acroForm) { + return (0, _util.shadow)(this, "formInfo", formInfo); + } + try { + const fields = acroForm.get("Fields"); + const hasFields = Array.isArray(fields) && fields.length > 0; + formInfo.hasFields = hasFields; + const xfa = acroForm.get("XFA"); + formInfo.hasXfa = Array.isArray(xfa) && xfa.length > 0 || xfa instanceof _base_stream.BaseStream && !xfa.isEmpty; + const sigFlags = acroForm.get("SigFlags"); + const hasSignatures = !!(sigFlags & 0x1); + const hasOnlyDocumentSignatures = hasSignatures && this._hasOnlyDocumentSignatures(fields); + formInfo.hasAcroForm = hasFields && !hasOnlyDocumentSignatures; + formInfo.hasSignatures = hasSignatures; + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.warn)(`Cannot fetch form information: "${ex}".`); + } + return (0, _util.shadow)(this, "formInfo", formInfo); + } + get documentInfo() { + const docInfo = { + PDFFormatVersion: this.version, + Language: this.catalog.lang, + EncryptFilterName: this.xref.encrypt ? this.xref.encrypt.filterName : null, + IsLinearized: !!this.linearization, + IsAcroFormPresent: this.formInfo.hasAcroForm, + IsXFAPresent: this.formInfo.hasXfa, + IsCollectionPresent: !!this.catalog.collection, + IsSignaturesPresent: this.formInfo.hasSignatures + }; + let infoDict; + try { + infoDict = this.xref.trailer.get("Info"); + } catch (err) { + if (err instanceof _core_utils.MissingDataException) { + throw err; + } + (0, _util.info)("The document information dictionary is invalid."); + } + if (!(infoDict instanceof _primitives.Dict)) { + return (0, _util.shadow)(this, "documentInfo", docInfo); + } + for (const key of infoDict.getKeys()) { + const value = infoDict.get(key); + switch (key) { + case "Title": + case "Author": + case "Subject": + case "Keywords": + case "Creator": + case "Producer": + case "CreationDate": + case "ModDate": + if (typeof value === "string") { + docInfo[key] = (0, _util.stringToPDFString)(value); + continue; + } + break; + case "Trapped": + if (value instanceof _primitives.Name) { + docInfo[key] = value; + continue; + } + break; + default: + let customValue; + switch (typeof value) { + case "string": + customValue = (0, _util.stringToPDFString)(value); + break; + case "number": + case "boolean": + customValue = value; + break; + default: + if (value instanceof _primitives.Name) { + customValue = value; + } + break; + } + if (customValue === undefined) { + (0, _util.warn)(`Bad value, for custom key "${key}", in Info: ${value}.`); + continue; + } + if (!docInfo.Custom) { + docInfo.Custom = Object.create(null); + } + docInfo.Custom[key] = customValue; + continue; + } + (0, _util.warn)(`Bad value, for key "${key}", in Info: ${value}.`); + } + return (0, _util.shadow)(this, "documentInfo", docInfo); + } + get fingerprints() { + function validate(data) { + return typeof data === "string" && data.length > 0 && data !== EMPTY_FINGERPRINT; + } + function hexString(hash) { + const buf = []; + for (const num of hash) { + const hex = num.toString(16); + buf.push(hex.padStart(2, "0")); + } + return buf.join(""); + } + const idArray = this.xref.trailer.get("ID"); + let hashOriginal, hashModified; + if (Array.isArray(idArray) && validate(idArray[0])) { + hashOriginal = (0, _util.stringToBytes)(idArray[0]); + if (idArray[1] !== idArray[0] && validate(idArray[1])) { + hashModified = (0, _util.stringToBytes)(idArray[1]); + } + } else { + hashOriginal = (0, _crypto.calculateMD5)(this.stream.getByteRange(0, FINGERPRINT_FIRST_BYTES), 0, FINGERPRINT_FIRST_BYTES); + } + return (0, _util.shadow)(this, "fingerprints", [hexString(hashOriginal), hashModified ? hexString(hashModified) : null]); + } + async _getLinearizationPage(pageIndex) { + const { + catalog, + linearization, + xref + } = this; + const ref = _primitives.Ref.get(linearization.objectNumberFirst, 0); + try { + const obj = await xref.fetchAsync(ref); + if (obj instanceof _primitives.Dict) { + let type = obj.getRaw("Type"); + if (type instanceof _primitives.Ref) { + type = await xref.fetchAsync(type); + } + if ((0, _primitives.isName)(type, "Page") || !obj.has("Type") && !obj.has("Kids")) { + if (!catalog.pageKidsCountCache.has(ref)) { + catalog.pageKidsCountCache.put(ref, 1); + } + if (!catalog.pageIndexCache.has(ref)) { + catalog.pageIndexCache.put(ref, 0); + } + return [obj, ref]; + } + } + throw new _util.FormatError("The Linearization dictionary doesn't point to a valid Page dictionary."); + } catch (reason) { + (0, _util.warn)(`_getLinearizationPage: "${reason.message}".`); + return catalog.getPageDict(pageIndex); + } + } + getPage(pageIndex) { + const cachedPromise = this._pagePromises.get(pageIndex); + if (cachedPromise) { + return cachedPromise; + } + const { + catalog, + linearization, + xfaFactory + } = this; + let promise; + if (xfaFactory) { + promise = Promise.resolve([_primitives.Dict.empty, null]); + } else if (linearization?.pageFirst === pageIndex) { + promise = this._getLinearizationPage(pageIndex); + } else { + promise = catalog.getPageDict(pageIndex); + } + promise = promise.then(([pageDict, ref]) => { + return new Page({ + pdfManager: this.pdfManager, + xref: this.xref, + pageIndex, + pageDict, + ref, + globalIdFactory: this._globalIdFactory, + fontCache: catalog.fontCache, + builtInCMapCache: catalog.builtInCMapCache, + standardFontDataCache: catalog.standardFontDataCache, + globalImageCache: catalog.globalImageCache, + systemFontCache: catalog.systemFontCache, + nonBlendModesSet: catalog.nonBlendModesSet, + xfaFactory + }); + }); + this._pagePromises.set(pageIndex, promise); + return promise; + } + async checkFirstPage(recoveryMode = false) { + if (recoveryMode) { + return; + } + try { + await this.getPage(0); + } catch (reason) { + if (reason instanceof _core_utils.XRefEntryException) { + this._pagePromises.delete(0); + await this.cleanup(); + throw new _core_utils.XRefParseException(); + } + } + } + async checkLastPage(recoveryMode = false) { + const { + catalog, + pdfManager + } = this; + catalog.setActualNumPages(); + let numPages; + try { + await Promise.all([pdfManager.ensureDoc("xfaFactory"), pdfManager.ensureDoc("linearization"), pdfManager.ensureCatalog("numPages")]); + if (this.xfaFactory) { + return; + } else if (this.linearization) { + numPages = this.linearization.numPages; + } else { + numPages = catalog.numPages; + } + if (!Number.isInteger(numPages)) { + throw new _util.FormatError("Page count is not an integer."); + } else if (numPages <= 1) { + return; + } + await this.getPage(numPages - 1); + } catch (reason) { + this._pagePromises.delete(numPages - 1); + await this.cleanup(); + if (reason instanceof _core_utils.XRefEntryException && !recoveryMode) { + throw new _core_utils.XRefParseException(); + } + (0, _util.warn)(`checkLastPage - invalid /Pages tree /Count: ${numPages}.`); + let pagesTree; + try { + pagesTree = await catalog.getAllPageDicts(recoveryMode); + } catch (reasonAll) { + if (reasonAll instanceof _core_utils.XRefEntryException && !recoveryMode) { + throw new _core_utils.XRefParseException(); + } + catalog.setActualNumPages(1); + return; + } + for (const [pageIndex, [pageDict, ref]] of pagesTree) { + let promise; + if (pageDict instanceof Error) { + promise = Promise.reject(pageDict); + promise.catch(() => {}); + } else { + promise = Promise.resolve(new Page({ + pdfManager, + xref: this.xref, + pageIndex, + pageDict, + ref, + globalIdFactory: this._globalIdFactory, + fontCache: catalog.fontCache, + builtInCMapCache: catalog.builtInCMapCache, + standardFontDataCache: catalog.standardFontDataCache, + globalImageCache: catalog.globalImageCache, + systemFontCache: catalog.systemFontCache, + nonBlendModesSet: catalog.nonBlendModesSet, + xfaFactory: null + })); + } + this._pagePromises.set(pageIndex, promise); + } + catalog.setActualNumPages(pagesTree.size); + } + } + fontFallback(id, handler) { + return this.catalog.fontFallback(id, handler); + } + async cleanup(manuallyTriggered = false) { + return this.catalog ? this.catalog.cleanup(manuallyTriggered) : (0, _cleanup_helper.clearGlobalCaches)(); + } + #collectFieldObjects(name, fieldRef, promises, annotationGlobals) { + const field = this.xref.fetchIfRef(fieldRef); + if (field.has("T")) { + const partName = (0, _util.stringToPDFString)(field.get("T")); + name = name === "" ? partName : `${name}.${partName}`; + } + if (!promises.has(name)) { + promises.set(name, []); + } + promises.get(name).push(_annotation.AnnotationFactory.create(this.xref, fieldRef, annotationGlobals, this._localIdFactory, true, null).then(annotation => annotation?.getFieldObject()).catch(function (reason) { + (0, _util.warn)(`#collectFieldObjects: "${reason}".`); + return null; + })); + if (field.has("Kids")) { + for (const kid of field.get("Kids")) { + this.#collectFieldObjects(name, kid, promises, annotationGlobals); + } + } + } + get fieldObjects() { + if (!this.formInfo.hasFields) { + return (0, _util.shadow)(this, "fieldObjects", Promise.resolve(null)); + } + const promise = this.pdfManager.ensureDoc("annotationGlobals").then(async annotationGlobals => { + if (!annotationGlobals) { + return null; + } + const allFields = Object.create(null); + const fieldPromises = new Map(); + for (const fieldRef of this.catalog.acroForm.get("Fields")) { + this.#collectFieldObjects("", fieldRef, fieldPromises, annotationGlobals); + } + const allPromises = []; + for (const [name, promises] of fieldPromises) { + allPromises.push(Promise.all(promises).then(fields => { + fields = fields.filter(field => !!field); + if (fields.length > 0) { + allFields[name] = fields; + } + })); + } + await Promise.all(allPromises); + return allFields; + }); + return (0, _util.shadow)(this, "fieldObjects", promise); + } + get hasJSActions() { + const promise = this.pdfManager.ensureDoc("_parseHasJSActions"); + return (0, _util.shadow)(this, "hasJSActions", promise); + } + async _parseHasJSActions() { + const [catalogJsActions, fieldObjects] = await Promise.all([this.pdfManager.ensureCatalog("jsActions"), this.pdfManager.ensureDoc("fieldObjects")]); + if (catalogJsActions) { + return true; + } + if (fieldObjects) { + return Object.values(fieldObjects).some(fieldObject => fieldObject.some(object => object.actions !== null)); + } + return false; + } + get calculationOrderIds() { + const acroForm = this.catalog.acroForm; + if (!acroForm?.has("CO")) { + return (0, _util.shadow)(this, "calculationOrderIds", null); + } + const calculationOrder = acroForm.get("CO"); + if (!Array.isArray(calculationOrder) || calculationOrder.length === 0) { + return (0, _util.shadow)(this, "calculationOrderIds", null); + } + const ids = []; + for (const id of calculationOrder) { + if (id instanceof _primitives.Ref) { + ids.push(id.toString()); + } + } + if (ids.length === 0) { + return (0, _util.shadow)(this, "calculationOrderIds", null); + } + return (0, _util.shadow)(this, "calculationOrderIds", ids); + } + get annotationGlobals() { + return (0, _util.shadow)(this, "annotationGlobals", _annotation.AnnotationFactory.createGlobals(this.pdfManager)); + } +} +exports.PDFDocument = PDFDocument; + +/***/ }), +/* 10 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.PopupAnnotation = exports.MarkupAnnotation = exports.AnnotationFactory = exports.AnnotationBorderStyle = exports.Annotation = void 0; +exports.getQuadPoints = getQuadPoints; +var _util = __w_pdfjs_require__(2); +var _core_utils = __w_pdfjs_require__(3); +var _default_appearance = __w_pdfjs_require__(11); +var _primitives = __w_pdfjs_require__(4); +var _stream = __w_pdfjs_require__(8); +var _base_stream = __w_pdfjs_require__(5); +var _bidi = __w_pdfjs_require__(60); +var _catalog = __w_pdfjs_require__(66); +var _colorspace = __w_pdfjs_require__(12); +var _file_spec = __w_pdfjs_require__(69); +var _jpeg_stream = __w_pdfjs_require__(26); +var _object_loader = __w_pdfjs_require__(76); +var _operator_list = __w_pdfjs_require__(64); +var _writer = __w_pdfjs_require__(73); +var _factory = __w_pdfjs_require__(77); +class AnnotationFactory { + static createGlobals(pdfManager) { + return Promise.all([pdfManager.ensureCatalog("acroForm"), pdfManager.ensureDoc("xfaDatasets"), pdfManager.ensureCatalog("structTreeRoot"), pdfManager.ensureCatalog("baseUrl"), pdfManager.ensureCatalog("attachments")]).then(([acroForm, xfaDatasets, structTreeRoot, baseUrl, attachments]) => { + return { + pdfManager, + acroForm: acroForm instanceof _primitives.Dict ? acroForm : _primitives.Dict.empty, + xfaDatasets, + structTreeRoot, + baseUrl, + attachments + }; + }, reason => { + (0, _util.warn)(`createGlobals: "${reason}".`); + return null; + }); + } + static async create(xref, ref, annotationGlobals, idFactory, collectFields, pageRef) { + const pageIndex = collectFields ? await this._getPageIndex(xref, ref, annotationGlobals.pdfManager) : null; + return annotationGlobals.pdfManager.ensure(this, "_create", [xref, ref, annotationGlobals, idFactory, collectFields, pageIndex, pageRef]); + } + static _create(xref, ref, annotationGlobals, idFactory, collectFields = false, pageIndex = null, pageRef = null) { + const dict = xref.fetchIfRef(ref); + if (!(dict instanceof _primitives.Dict)) { + return undefined; + } + const { + acroForm, + pdfManager + } = annotationGlobals; + const id = ref instanceof _primitives.Ref ? ref.toString() : `annot_${idFactory.createObjId()}`; + let subtype = dict.get("Subtype"); + subtype = subtype instanceof _primitives.Name ? subtype.name : null; + const parameters = { + xref, + ref, + dict, + subtype, + id, + annotationGlobals, + collectFields, + needAppearances: !collectFields && acroForm.get("NeedAppearances") === true, + pageIndex, + evaluatorOptions: pdfManager.evaluatorOptions, + pageRef + }; + switch (subtype) { + case "Link": + return new LinkAnnotation(parameters); + case "Text": + return new TextAnnotation(parameters); + case "Widget": + let fieldType = (0, _core_utils.getInheritableProperty)({ + dict, + key: "FT" + }); + fieldType = fieldType instanceof _primitives.Name ? fieldType.name : null; + switch (fieldType) { + case "Tx": + return new TextWidgetAnnotation(parameters); + case "Btn": + return new ButtonWidgetAnnotation(parameters); + case "Ch": + return new ChoiceWidgetAnnotation(parameters); + case "Sig": + return new SignatureWidgetAnnotation(parameters); + } + (0, _util.warn)(`Unimplemented widget field type "${fieldType}", ` + "falling back to base field type."); + return new WidgetAnnotation(parameters); + case "Popup": + return new PopupAnnotation(parameters); + case "FreeText": + return new FreeTextAnnotation(parameters); + case "Line": + return new LineAnnotation(parameters); + case "Square": + return new SquareAnnotation(parameters); + case "Circle": + return new CircleAnnotation(parameters); + case "PolyLine": + return new PolylineAnnotation(parameters); + case "Polygon": + return new PolygonAnnotation(parameters); + case "Caret": + return new CaretAnnotation(parameters); + case "Ink": + return new InkAnnotation(parameters); + case "Highlight": + return new HighlightAnnotation(parameters); + case "Underline": + return new UnderlineAnnotation(parameters); + case "Squiggly": + return new SquigglyAnnotation(parameters); + case "StrikeOut": + return new StrikeOutAnnotation(parameters); + case "Stamp": + return new StampAnnotation(parameters); + case "FileAttachment": + return new FileAttachmentAnnotation(parameters); + default: + if (!collectFields) { + if (!subtype) { + (0, _util.warn)("Annotation is missing the required /Subtype."); + } else { + (0, _util.warn)(`Unimplemented annotation type "${subtype}", ` + "falling back to base annotation."); + } + } + return new Annotation(parameters); + } + } + static async _getPageIndex(xref, ref, pdfManager) { + try { + const annotDict = await xref.fetchIfRefAsync(ref); + if (!(annotDict instanceof _primitives.Dict)) { + return -1; + } + const pageRef = annotDict.getRaw("P"); + if (pageRef instanceof _primitives.Ref) { + try { + const pageIndex = await pdfManager.ensureCatalog("getPageIndex", [pageRef]); + return pageIndex; + } catch (ex) { + (0, _util.info)(`_getPageIndex -- not a valid page reference: "${ex}".`); + } + } + if (annotDict.has("Kids")) { + return -1; + } + const numPages = await pdfManager.ensureDoc("numPages"); + for (let pageIndex = 0; pageIndex < numPages; pageIndex++) { + const page = await pdfManager.getPage(pageIndex); + const annotations = await pdfManager.ensure(page, "annotations"); + for (const annotRef of annotations) { + if (annotRef instanceof _primitives.Ref && (0, _primitives.isRefsEqual)(annotRef, ref)) { + return pageIndex; + } + } + } + } catch (ex) { + (0, _util.warn)(`_getPageIndex: "${ex}".`); + } + return -1; + } + static generateImages(annotations, xref, isOffscreenCanvasSupported) { + if (!isOffscreenCanvasSupported) { + (0, _util.warn)("generateImages: OffscreenCanvas is not supported, cannot save or print some annotations with images."); + return null; + } + let imagePromises; + for (const { + bitmapId, + bitmap + } of annotations) { + if (!bitmap) { + continue; + } + imagePromises ||= new Map(); + imagePromises.set(bitmapId, StampAnnotation.createImage(bitmap, xref)); + } + return imagePromises; + } + static async saveNewAnnotations(evaluator, task, annotations, imagePromises) { + const xref = evaluator.xref; + let baseFontRef; + const dependencies = []; + const promises = []; + const { + isOffscreenCanvasSupported + } = evaluator.options; + for (const annotation of annotations) { + if (annotation.deleted) { + continue; + } + switch (annotation.annotationType) { + case _util.AnnotationEditorType.FREETEXT: + if (!baseFontRef) { + const baseFont = new _primitives.Dict(xref); + baseFont.set("BaseFont", _primitives.Name.get("Helvetica")); + baseFont.set("Type", _primitives.Name.get("Font")); + baseFont.set("Subtype", _primitives.Name.get("Type1")); + baseFont.set("Encoding", _primitives.Name.get("WinAnsiEncoding")); + const buffer = []; + baseFontRef = xref.getNewTemporaryRef(); + await (0, _writer.writeObject)(baseFontRef, baseFont, buffer, xref); + dependencies.push({ + ref: baseFontRef, + data: buffer.join("") + }); + } + promises.push(FreeTextAnnotation.createNewAnnotation(xref, annotation, dependencies, { + evaluator, + task, + baseFontRef + })); + break; + case _util.AnnotationEditorType.INK: + promises.push(InkAnnotation.createNewAnnotation(xref, annotation, dependencies)); + break; + case _util.AnnotationEditorType.STAMP: + if (!isOffscreenCanvasSupported) { + break; + } + const image = await imagePromises.get(annotation.bitmapId); + if (image.imageStream) { + const { + imageStream, + smaskStream + } = image; + const buffer = []; + if (smaskStream) { + const smaskRef = xref.getNewTemporaryRef(); + await (0, _writer.writeObject)(smaskRef, smaskStream, buffer, xref); + dependencies.push({ + ref: smaskRef, + data: buffer.join("") + }); + imageStream.dict.set("SMask", smaskRef); + buffer.length = 0; + } + const imageRef = image.imageRef = xref.getNewTemporaryRef(); + await (0, _writer.writeObject)(imageRef, imageStream, buffer, xref); + dependencies.push({ + ref: imageRef, + data: buffer.join("") + }); + image.imageStream = image.smaskStream = null; + } + promises.push(StampAnnotation.createNewAnnotation(xref, annotation, dependencies, { + image + })); + break; + } + } + return { + annotations: await Promise.all(promises), + dependencies + }; + } + static async printNewAnnotations(annotationGlobals, evaluator, task, annotations, imagePromises) { + if (!annotations) { + return null; + } + const { + options, + xref + } = evaluator; + const promises = []; + for (const annotation of annotations) { + if (annotation.deleted) { + continue; + } + switch (annotation.annotationType) { + case _util.AnnotationEditorType.FREETEXT: + promises.push(FreeTextAnnotation.createNewPrintAnnotation(annotationGlobals, xref, annotation, { + evaluator, + task, + evaluatorOptions: options + })); + break; + case _util.AnnotationEditorType.INK: + promises.push(InkAnnotation.createNewPrintAnnotation(annotationGlobals, xref, annotation, { + evaluatorOptions: options + })); + break; + case _util.AnnotationEditorType.STAMP: + if (!options.isOffscreenCanvasSupported) { + break; + } + const image = await imagePromises.get(annotation.bitmapId); + if (image.imageStream) { + const { + imageStream, + smaskStream + } = image; + if (smaskStream) { + imageStream.dict.set("SMask", smaskStream); + } + image.imageRef = new _jpeg_stream.JpegStream(imageStream, imageStream.length); + image.imageStream = image.smaskStream = null; + } + promises.push(StampAnnotation.createNewPrintAnnotation(annotationGlobals, xref, annotation, { + image, + evaluatorOptions: options + })); + break; + } + } + return Promise.all(promises); + } +} +exports.AnnotationFactory = AnnotationFactory; +function getRgbColor(color, defaultColor = new Uint8ClampedArray(3)) { + if (!Array.isArray(color)) { + return defaultColor; + } + const rgbColor = defaultColor || new Uint8ClampedArray(3); + switch (color.length) { + case 0: + return null; + case 1: + _colorspace.ColorSpace.singletons.gray.getRgbItem(color, 0, rgbColor, 0); + return rgbColor; + case 3: + _colorspace.ColorSpace.singletons.rgb.getRgbItem(color, 0, rgbColor, 0); + return rgbColor; + case 4: + _colorspace.ColorSpace.singletons.cmyk.getRgbItem(color, 0, rgbColor, 0); + return rgbColor; + default: + return defaultColor; + } +} +function getPdfColorArray(color) { + return Array.from(color, c => c / 255); +} +function getQuadPoints(dict, rect) { + const quadPoints = dict.getArray("QuadPoints"); + if (!Array.isArray(quadPoints) || quadPoints.length === 0 || quadPoints.length % 8 > 0) { + return null; + } + const quadPointsLists = []; + for (let i = 0, ii = quadPoints.length / 8; i < ii; i++) { + let minX = Infinity, + maxX = -Infinity, + minY = Infinity, + maxY = -Infinity; + for (let j = i * 8, jj = i * 8 + 8; j < jj; j += 2) { + const x = quadPoints[j]; + const y = quadPoints[j + 1]; + minX = Math.min(x, minX); + maxX = Math.max(x, maxX); + minY = Math.min(y, minY); + maxY = Math.max(y, maxY); + } + if (rect !== null && (minX < rect[0] || maxX > rect[2] || minY < rect[1] || maxY > rect[3])) { + return null; + } + quadPointsLists.push([{ + x: minX, + y: maxY + }, { + x: maxX, + y: maxY + }, { + x: minX, + y: minY + }, { + x: maxX, + y: minY + }]); + } + return quadPointsLists; +} +function getTransformMatrix(rect, bbox, matrix) { + const [minX, minY, maxX, maxY] = _util.Util.getAxialAlignedBoundingBox(bbox, matrix); + if (minX === maxX || minY === maxY) { + return [1, 0, 0, 1, rect[0], rect[1]]; + } + const xRatio = (rect[2] - rect[0]) / (maxX - minX); + const yRatio = (rect[3] - rect[1]) / (maxY - minY); + return [xRatio, 0, 0, yRatio, rect[0] - minX * xRatio, rect[1] - minY * yRatio]; +} +class Annotation { + constructor(params) { + const { + dict, + xref, + annotationGlobals + } = params; + this.setTitle(dict.get("T")); + this.setContents(dict.get("Contents")); + this.setModificationDate(dict.get("M")); + this.setFlags(dict.get("F")); + this.setRectangle(dict.getArray("Rect")); + this.setColor(dict.getArray("C")); + this.setBorderStyle(dict); + this.setAppearance(dict); + this.setOptionalContent(dict); + const MK = dict.get("MK"); + this.setBorderAndBackgroundColors(MK); + this.setRotation(MK, dict); + this.ref = params.ref instanceof _primitives.Ref ? params.ref : null; + this._streams = []; + if (this.appearance) { + this._streams.push(this.appearance); + } + const isLocked = !!(this.flags & _util.AnnotationFlag.LOCKED); + const isContentLocked = !!(this.flags & _util.AnnotationFlag.LOCKEDCONTENTS); + if (annotationGlobals.structTreeRoot) { + let structParent = dict.get("StructParent"); + structParent = Number.isInteger(structParent) && structParent >= 0 ? structParent : -1; + annotationGlobals.structTreeRoot.addAnnotationIdToPage(params.pageRef, structParent); + } + this.data = { + annotationFlags: this.flags, + borderStyle: this.borderStyle, + color: this.color, + backgroundColor: this.backgroundColor, + borderColor: this.borderColor, + rotation: this.rotation, + contentsObj: this._contents, + hasAppearance: !!this.appearance, + id: params.id, + modificationDate: this.modificationDate, + rect: this.rectangle, + subtype: params.subtype, + hasOwnCanvas: false, + noRotate: !!(this.flags & _util.AnnotationFlag.NOROTATE), + noHTML: isLocked && isContentLocked + }; + if (params.collectFields) { + const kids = dict.get("Kids"); + if (Array.isArray(kids)) { + const kidIds = []; + for (const kid of kids) { + if (kid instanceof _primitives.Ref) { + kidIds.push(kid.toString()); + } + } + if (kidIds.length !== 0) { + this.data.kidIds = kidIds; + } + } + this.data.actions = (0, _core_utils.collectActions)(xref, dict, _util.AnnotationActionEventType); + this.data.fieldName = this._constructFieldName(dict); + this.data.pageIndex = params.pageIndex; + } + this._isOffscreenCanvasSupported = params.evaluatorOptions.isOffscreenCanvasSupported; + this._fallbackFontDict = null; + this._needAppearances = false; + } + _hasFlag(flags, flag) { + return !!(flags & flag); + } + _isViewable(flags) { + return !this._hasFlag(flags, _util.AnnotationFlag.INVISIBLE) && !this._hasFlag(flags, _util.AnnotationFlag.NOVIEW); + } + _isPrintable(flags) { + return this._hasFlag(flags, _util.AnnotationFlag.PRINT) && !this._hasFlag(flags, _util.AnnotationFlag.HIDDEN) && !this._hasFlag(flags, _util.AnnotationFlag.INVISIBLE); + } + mustBeViewed(annotationStorage, _renderForms) { + const noView = annotationStorage?.get(this.data.id)?.noView; + if (noView !== undefined) { + return !noView; + } + return this.viewable && !this._hasFlag(this.flags, _util.AnnotationFlag.HIDDEN); + } + mustBePrinted(annotationStorage) { + const noPrint = annotationStorage?.get(this.data.id)?.noPrint; + if (noPrint !== undefined) { + return !noPrint; + } + return this.printable; + } + get viewable() { + if (this.data.quadPoints === null) { + return false; + } + if (this.flags === 0) { + return true; + } + return this._isViewable(this.flags); + } + get printable() { + if (this.data.quadPoints === null) { + return false; + } + if (this.flags === 0) { + return false; + } + return this._isPrintable(this.flags); + } + _parseStringHelper(data) { + const str = typeof data === "string" ? (0, _util.stringToPDFString)(data) : ""; + const dir = str && (0, _bidi.bidi)(str).dir === "rtl" ? "rtl" : "ltr"; + return { + str, + dir + }; + } + setDefaultAppearance(params) { + const { + dict, + annotationGlobals + } = params; + const defaultAppearance = (0, _core_utils.getInheritableProperty)({ + dict, + key: "DA" + }) || annotationGlobals.acroForm.get("DA"); + this._defaultAppearance = typeof defaultAppearance === "string" ? defaultAppearance : ""; + this.data.defaultAppearanceData = (0, _default_appearance.parseDefaultAppearance)(this._defaultAppearance); + } + setTitle(title) { + this._title = this._parseStringHelper(title); + } + setContents(contents) { + this._contents = this._parseStringHelper(contents); + } + setModificationDate(modificationDate) { + this.modificationDate = typeof modificationDate === "string" ? modificationDate : null; + } + setFlags(flags) { + this.flags = Number.isInteger(flags) && flags > 0 ? flags : 0; + } + hasFlag(flag) { + return this._hasFlag(this.flags, flag); + } + setRectangle(rectangle) { + this.rectangle = Array.isArray(rectangle) && rectangle.length === 4 ? _util.Util.normalizeRect(rectangle) : [0, 0, 0, 0]; + } + setColor(color) { + this.color = getRgbColor(color); + } + setLineEndings(lineEndings) { + this.lineEndings = ["None", "None"]; + if (Array.isArray(lineEndings) && lineEndings.length === 2) { + for (let i = 0; i < 2; i++) { + const obj = lineEndings[i]; + if (obj instanceof _primitives.Name) { + switch (obj.name) { + case "None": + continue; + case "Square": + case "Circle": + case "Diamond": + case "OpenArrow": + case "ClosedArrow": + case "Butt": + case "ROpenArrow": + case "RClosedArrow": + case "Slash": + this.lineEndings[i] = obj.name; + continue; + } + } + (0, _util.warn)(`Ignoring invalid lineEnding: ${obj}`); + } + } + } + setRotation(mk, dict) { + this.rotation = 0; + let angle = mk instanceof _primitives.Dict ? mk.get("R") || 0 : dict.get("Rotate") || 0; + if (Number.isInteger(angle) && angle !== 0) { + angle %= 360; + if (angle < 0) { + angle += 360; + } + if (angle % 90 === 0) { + this.rotation = angle; + } + } + } + setBorderAndBackgroundColors(mk) { + if (mk instanceof _primitives.Dict) { + this.borderColor = getRgbColor(mk.getArray("BC"), null); + this.backgroundColor = getRgbColor(mk.getArray("BG"), null); + } else { + this.borderColor = this.backgroundColor = null; + } + } + setBorderStyle(borderStyle) { + this.borderStyle = new AnnotationBorderStyle(); + if (!(borderStyle instanceof _primitives.Dict)) { + return; + } + if (borderStyle.has("BS")) { + const dict = borderStyle.get("BS"); + const dictType = dict.get("Type"); + if (!dictType || (0, _primitives.isName)(dictType, "Border")) { + this.borderStyle.setWidth(dict.get("W"), this.rectangle); + this.borderStyle.setStyle(dict.get("S")); + this.borderStyle.setDashArray(dict.getArray("D")); + } + } else if (borderStyle.has("Border")) { + const array = borderStyle.getArray("Border"); + if (Array.isArray(array) && array.length >= 3) { + this.borderStyle.setHorizontalCornerRadius(array[0]); + this.borderStyle.setVerticalCornerRadius(array[1]); + this.borderStyle.setWidth(array[2], this.rectangle); + if (array.length === 4) { + this.borderStyle.setDashArray(array[3], true); + } + } + } else { + this.borderStyle.setWidth(0); + } + } + setAppearance(dict) { + this.appearance = null; + const appearanceStates = dict.get("AP"); + if (!(appearanceStates instanceof _primitives.Dict)) { + return; + } + const normalAppearanceState = appearanceStates.get("N"); + if (normalAppearanceState instanceof _base_stream.BaseStream) { + this.appearance = normalAppearanceState; + return; + } + if (!(normalAppearanceState instanceof _primitives.Dict)) { + return; + } + const as = dict.get("AS"); + if (!(as instanceof _primitives.Name) || !normalAppearanceState.has(as.name)) { + return; + } + const appearance = normalAppearanceState.get(as.name); + if (appearance instanceof _base_stream.BaseStream) { + this.appearance = appearance; + } + } + setOptionalContent(dict) { + this.oc = null; + const oc = dict.get("OC"); + if (oc instanceof _primitives.Name) { + (0, _util.warn)("setOptionalContent: Support for /Name-entry is not implemented."); + } else if (oc instanceof _primitives.Dict) { + this.oc = oc; + } + } + loadResources(keys, appearance) { + return appearance.dict.getAsync("Resources").then(resources => { + if (!resources) { + return undefined; + } + const objectLoader = new _object_loader.ObjectLoader(resources, keys, resources.xref); + return objectLoader.load().then(function () { + return resources; + }); + }); + } + async getOperatorList(evaluator, task, intent, renderForms, annotationStorage) { + const data = this.data; + let appearance = this.appearance; + const isUsingOwnCanvas = !!(this.data.hasOwnCanvas && intent & _util.RenderingIntentFlag.DISPLAY); + if (!appearance) { + if (!isUsingOwnCanvas) { + return { + opList: new _operator_list.OperatorList(), + separateForm: false, + separateCanvas: false + }; + } + appearance = new _stream.StringStream(""); + appearance.dict = new _primitives.Dict(); + } + const appearanceDict = appearance.dict; + const resources = await this.loadResources(["ExtGState", "ColorSpace", "Pattern", "Shading", "XObject", "Font"], appearance); + const bbox = appearanceDict.getArray("BBox") || [0, 0, 1, 1]; + const matrix = appearanceDict.getArray("Matrix") || [1, 0, 0, 1, 0, 0]; + const transform = getTransformMatrix(data.rect, bbox, matrix); + const opList = new _operator_list.OperatorList(); + let optionalContent; + if (this.oc) { + optionalContent = await evaluator.parseMarkedContentProps(this.oc, null); + } + if (optionalContent !== undefined) { + opList.addOp(_util.OPS.beginMarkedContentProps, ["OC", optionalContent]); + } + opList.addOp(_util.OPS.beginAnnotation, [data.id, data.rect, transform, matrix, isUsingOwnCanvas]); + await evaluator.getOperatorList({ + stream: appearance, + task, + resources, + operatorList: opList, + fallbackFontDict: this._fallbackFontDict + }); + opList.addOp(_util.OPS.endAnnotation, []); + if (optionalContent !== undefined) { + opList.addOp(_util.OPS.endMarkedContent, []); + } + this.reset(); + return { + opList, + separateForm: false, + separateCanvas: isUsingOwnCanvas + }; + } + async save(evaluator, task, annotationStorage) { + return null; + } + get hasTextContent() { + return false; + } + async extractTextContent(evaluator, task, viewBox) { + if (!this.appearance) { + return; + } + const resources = await this.loadResources(["ExtGState", "Font", "Properties", "XObject"], this.appearance); + const text = []; + const buffer = []; + let firstPosition = null; + const sink = { + desiredSize: Math.Infinity, + ready: true, + enqueue(chunk, size) { + for (const item of chunk.items) { + if (item.str === undefined) { + continue; + } + firstPosition ||= item.transform.slice(-2); + buffer.push(item.str); + if (item.hasEOL) { + text.push(buffer.join("")); + buffer.length = 0; + } + } + } + }; + await evaluator.getTextContent({ + stream: this.appearance, + task, + resources, + includeMarkedContent: true, + sink, + viewBox + }); + this.reset(); + if (buffer.length) { + text.push(buffer.join("")); + } + if (text.length > 1 || text[0]) { + const appearanceDict = this.appearance.dict; + const bbox = appearanceDict.getArray("BBox") || [0, 0, 1, 1]; + const matrix = appearanceDict.getArray("Matrix") || [1, 0, 0, 1, 0, 0]; + const rect = this.data.rect; + const transform = getTransformMatrix(rect, bbox, matrix); + transform[4] -= rect[0]; + transform[5] -= rect[1]; + firstPosition = _util.Util.applyTransform(firstPosition, transform); + firstPosition = _util.Util.applyTransform(firstPosition, matrix); + this.data.textPosition = firstPosition; + this.data.textContent = text; + } + } + getFieldObject() { + if (this.data.kidIds) { + return { + id: this.data.id, + actions: this.data.actions, + name: this.data.fieldName, + strokeColor: this.data.borderColor, + fillColor: this.data.backgroundColor, + type: "", + kidIds: this.data.kidIds, + page: this.data.pageIndex, + rotation: this.rotation + }; + } + return null; + } + reset() { + for (const stream of this._streams) { + stream.reset(); + } + } + _constructFieldName(dict) { + if (!dict.has("T") && !dict.has("Parent")) { + (0, _util.warn)("Unknown field name, falling back to empty field name."); + return ""; + } + if (!dict.has("Parent")) { + return (0, _util.stringToPDFString)(dict.get("T")); + } + const fieldName = []; + if (dict.has("T")) { + fieldName.unshift((0, _util.stringToPDFString)(dict.get("T"))); + } + let loopDict = dict; + const visited = new _primitives.RefSet(); + if (dict.objId) { + visited.put(dict.objId); + } + while (loopDict.has("Parent")) { + loopDict = loopDict.get("Parent"); + if (!(loopDict instanceof _primitives.Dict) || loopDict.objId && visited.has(loopDict.objId)) { + break; + } + if (loopDict.objId) { + visited.put(loopDict.objId); + } + if (loopDict.has("T")) { + fieldName.unshift((0, _util.stringToPDFString)(loopDict.get("T"))); + } + } + return fieldName.join("."); + } +} +exports.Annotation = Annotation; +class AnnotationBorderStyle { + constructor() { + this.width = 1; + this.style = _util.AnnotationBorderStyleType.SOLID; + this.dashArray = [3]; + this.horizontalCornerRadius = 0; + this.verticalCornerRadius = 0; + } + setWidth(width, rect = [0, 0, 0, 0]) { + if (width instanceof _primitives.Name) { + this.width = 0; + return; + } + if (typeof width === "number") { + if (width > 0) { + const maxWidth = (rect[2] - rect[0]) / 2; + const maxHeight = (rect[3] - rect[1]) / 2; + if (maxWidth > 0 && maxHeight > 0 && (width > maxWidth || width > maxHeight)) { + (0, _util.warn)(`AnnotationBorderStyle.setWidth - ignoring width: ${width}`); + width = 1; + } + } + this.width = width; + } + } + setStyle(style) { + if (!(style instanceof _primitives.Name)) { + return; + } + switch (style.name) { + case "S": + this.style = _util.AnnotationBorderStyleType.SOLID; + break; + case "D": + this.style = _util.AnnotationBorderStyleType.DASHED; + break; + case "B": + this.style = _util.AnnotationBorderStyleType.BEVELED; + break; + case "I": + this.style = _util.AnnotationBorderStyleType.INSET; + break; + case "U": + this.style = _util.AnnotationBorderStyleType.UNDERLINE; + break; + default: + break; + } + } + setDashArray(dashArray, forceStyle = false) { + if (Array.isArray(dashArray) && dashArray.length > 0) { + let isValid = true; + let allZeros = true; + for (const element of dashArray) { + const validNumber = +element >= 0; + if (!validNumber) { + isValid = false; + break; + } else if (element > 0) { + allZeros = false; + } + } + if (isValid && !allZeros) { + this.dashArray = dashArray; + if (forceStyle) { + this.setStyle(_primitives.Name.get("D")); + } + } else { + this.width = 0; + } + } else if (dashArray) { + this.width = 0; + } + } + setHorizontalCornerRadius(radius) { + if (Number.isInteger(radius)) { + this.horizontalCornerRadius = radius; + } + } + setVerticalCornerRadius(radius) { + if (Number.isInteger(radius)) { + this.verticalCornerRadius = radius; + } + } +} +exports.AnnotationBorderStyle = AnnotationBorderStyle; +class MarkupAnnotation extends Annotation { + constructor(params) { + super(params); + const { + dict + } = params; + if (dict.has("IRT")) { + const rawIRT = dict.getRaw("IRT"); + this.data.inReplyTo = rawIRT instanceof _primitives.Ref ? rawIRT.toString() : null; + const rt = dict.get("RT"); + this.data.replyType = rt instanceof _primitives.Name ? rt.name : _util.AnnotationReplyType.REPLY; + } + let popupRef = null; + if (this.data.replyType === _util.AnnotationReplyType.GROUP) { + const parent = dict.get("IRT"); + this.setTitle(parent.get("T")); + this.data.titleObj = this._title; + this.setContents(parent.get("Contents")); + this.data.contentsObj = this._contents; + if (!parent.has("CreationDate")) { + this.data.creationDate = null; + } else { + this.setCreationDate(parent.get("CreationDate")); + this.data.creationDate = this.creationDate; + } + if (!parent.has("M")) { + this.data.modificationDate = null; + } else { + this.setModificationDate(parent.get("M")); + this.data.modificationDate = this.modificationDate; + } + popupRef = parent.getRaw("Popup"); + if (!parent.has("C")) { + this.data.color = null; + } else { + this.setColor(parent.getArray("C")); + this.data.color = this.color; + } + } else { + this.data.titleObj = this._title; + this.setCreationDate(dict.get("CreationDate")); + this.data.creationDate = this.creationDate; + popupRef = dict.getRaw("Popup"); + if (!dict.has("C")) { + this.data.color = null; + } + } + this.data.popupRef = popupRef instanceof _primitives.Ref ? popupRef.toString() : null; + if (dict.has("RC")) { + this.data.richText = _factory.XFAFactory.getRichTextAsHtml(dict.get("RC")); + } + } + setCreationDate(creationDate) { + this.creationDate = typeof creationDate === "string" ? creationDate : null; + } + _setDefaultAppearance({ + xref, + extra, + strokeColor, + fillColor, + blendMode, + strokeAlpha, + fillAlpha, + pointsCallback + }) { + let minX = Number.MAX_VALUE; + let minY = Number.MAX_VALUE; + let maxX = Number.MIN_VALUE; + let maxY = Number.MIN_VALUE; + const buffer = ["q"]; + if (extra) { + buffer.push(extra); + } + if (strokeColor) { + buffer.push(`${strokeColor[0]} ${strokeColor[1]} ${strokeColor[2]} RG`); + } + if (fillColor) { + buffer.push(`${fillColor[0]} ${fillColor[1]} ${fillColor[2]} rg`); + } + let pointsArray = this.data.quadPoints; + if (!pointsArray) { + pointsArray = [[{ + x: this.rectangle[0], + y: this.rectangle[3] + }, { + x: this.rectangle[2], + y: this.rectangle[3] + }, { + x: this.rectangle[0], + y: this.rectangle[1] + }, { + x: this.rectangle[2], + y: this.rectangle[1] + }]]; + } + for (const points of pointsArray) { + const [mX, MX, mY, MY] = pointsCallback(buffer, points); + minX = Math.min(minX, mX); + maxX = Math.max(maxX, MX); + minY = Math.min(minY, mY); + maxY = Math.max(maxY, MY); + } + buffer.push("Q"); + const formDict = new _primitives.Dict(xref); + const appearanceStreamDict = new _primitives.Dict(xref); + appearanceStreamDict.set("Subtype", _primitives.Name.get("Form")); + const appearanceStream = new _stream.StringStream(buffer.join(" ")); + appearanceStream.dict = appearanceStreamDict; + formDict.set("Fm0", appearanceStream); + const gsDict = new _primitives.Dict(xref); + if (blendMode) { + gsDict.set("BM", _primitives.Name.get(blendMode)); + } + if (typeof strokeAlpha === "number") { + gsDict.set("CA", strokeAlpha); + } + if (typeof fillAlpha === "number") { + gsDict.set("ca", fillAlpha); + } + const stateDict = new _primitives.Dict(xref); + stateDict.set("GS0", gsDict); + const resources = new _primitives.Dict(xref); + resources.set("ExtGState", stateDict); + resources.set("XObject", formDict); + const appearanceDict = new _primitives.Dict(xref); + appearanceDict.set("Resources", resources); + const bbox = this.data.rect = [minX, minY, maxX, maxY]; + appearanceDict.set("BBox", bbox); + this.appearance = new _stream.StringStream("/GS0 gs /Fm0 Do"); + this.appearance.dict = appearanceDict; + this._streams.push(this.appearance, appearanceStream); + } + static async createNewAnnotation(xref, annotation, dependencies, params) { + const annotationRef = annotation.ref ||= xref.getNewTemporaryRef(); + const ap = await this.createNewAppearanceStream(annotation, xref, params); + const buffer = []; + let annotationDict; + if (ap) { + const apRef = xref.getNewTemporaryRef(); + annotationDict = this.createNewDict(annotation, xref, { + apRef + }); + await (0, _writer.writeObject)(apRef, ap, buffer, xref); + dependencies.push({ + ref: apRef, + data: buffer.join("") + }); + } else { + annotationDict = this.createNewDict(annotation, xref, {}); + } + if (Number.isInteger(annotation.parentTreeId)) { + annotationDict.set("StructParent", annotation.parentTreeId); + } + buffer.length = 0; + await (0, _writer.writeObject)(annotationRef, annotationDict, buffer, xref); + return { + ref: annotationRef, + data: buffer.join("") + }; + } + static async createNewPrintAnnotation(annotationGlobals, xref, annotation, params) { + const ap = await this.createNewAppearanceStream(annotation, xref, params); + const annotationDict = this.createNewDict(annotation, xref, { + ap + }); + const newAnnotation = new this.prototype.constructor({ + dict: annotationDict, + xref, + annotationGlobals, + evaluatorOptions: params.evaluatorOptions + }); + if (annotation.ref) { + newAnnotation.ref = newAnnotation.refToReplace = annotation.ref; + } + return newAnnotation; + } +} +exports.MarkupAnnotation = MarkupAnnotation; +class WidgetAnnotation extends Annotation { + constructor(params) { + super(params); + const { + dict, + xref, + annotationGlobals + } = params; + const data = this.data; + this._needAppearances = params.needAppearances; + data.annotationType = _util.AnnotationType.WIDGET; + if (data.fieldName === undefined) { + data.fieldName = this._constructFieldName(dict); + } + if (data.actions === undefined) { + data.actions = (0, _core_utils.collectActions)(xref, dict, _util.AnnotationActionEventType); + } + let fieldValue = (0, _core_utils.getInheritableProperty)({ + dict, + key: "V", + getArray: true + }); + data.fieldValue = this._decodeFormValue(fieldValue); + const defaultFieldValue = (0, _core_utils.getInheritableProperty)({ + dict, + key: "DV", + getArray: true + }); + data.defaultFieldValue = this._decodeFormValue(defaultFieldValue); + if (fieldValue === undefined && annotationGlobals.xfaDatasets) { + const path = this._title.str; + if (path) { + this._hasValueFromXFA = true; + data.fieldValue = fieldValue = annotationGlobals.xfaDatasets.getValue(path); + } + } + if (fieldValue === undefined && data.defaultFieldValue !== null) { + data.fieldValue = data.defaultFieldValue; + } + data.alternativeText = (0, _util.stringToPDFString)(dict.get("TU") || ""); + this.setDefaultAppearance(params); + data.hasAppearance ||= this._needAppearances && data.fieldValue !== undefined && data.fieldValue !== null; + const fieldType = (0, _core_utils.getInheritableProperty)({ + dict, + key: "FT" + }); + data.fieldType = fieldType instanceof _primitives.Name ? fieldType.name : null; + const localResources = (0, _core_utils.getInheritableProperty)({ + dict, + key: "DR" + }); + const acroFormResources = annotationGlobals.acroForm.get("DR"); + const appearanceResources = this.appearance?.dict.get("Resources"); + this._fieldResources = { + localResources, + acroFormResources, + appearanceResources, + mergedResources: _primitives.Dict.merge({ + xref, + dictArray: [localResources, appearanceResources, acroFormResources], + mergeSubDicts: true + }) + }; + data.fieldFlags = (0, _core_utils.getInheritableProperty)({ + dict, + key: "Ff" + }); + if (!Number.isInteger(data.fieldFlags) || data.fieldFlags < 0) { + data.fieldFlags = 0; + } + data.readOnly = this.hasFieldFlag(_util.AnnotationFieldFlag.READONLY); + data.required = this.hasFieldFlag(_util.AnnotationFieldFlag.REQUIRED); + data.hidden = this._hasFlag(data.annotationFlags, _util.AnnotationFlag.HIDDEN) || this._hasFlag(data.annotationFlags, _util.AnnotationFlag.NOVIEW); + } + _decodeFormValue(formValue) { + if (Array.isArray(formValue)) { + return formValue.filter(item => typeof item === "string").map(item => (0, _util.stringToPDFString)(item)); + } else if (formValue instanceof _primitives.Name) { + return (0, _util.stringToPDFString)(formValue.name); + } else if (typeof formValue === "string") { + return (0, _util.stringToPDFString)(formValue); + } + return null; + } + hasFieldFlag(flag) { + return !!(this.data.fieldFlags & flag); + } + _isViewable(flags) { + return !this._hasFlag(flags, _util.AnnotationFlag.INVISIBLE); + } + mustBeViewed(annotationStorage, renderForms) { + if (renderForms) { + return this.viewable; + } + return super.mustBeViewed(annotationStorage, renderForms) && !this._hasFlag(this.flags, _util.AnnotationFlag.NOVIEW); + } + getRotationMatrix(annotationStorage) { + let rotation = annotationStorage?.get(this.data.id)?.rotation; + if (rotation === undefined) { + rotation = this.rotation; + } + if (rotation === 0) { + return _util.IDENTITY_MATRIX; + } + const width = this.data.rect[2] - this.data.rect[0]; + const height = this.data.rect[3] - this.data.rect[1]; + return (0, _core_utils.getRotationMatrix)(rotation, width, height); + } + getBorderAndBackgroundAppearances(annotationStorage) { + let rotation = annotationStorage?.get(this.data.id)?.rotation; + if (rotation === undefined) { + rotation = this.rotation; + } + if (!this.backgroundColor && !this.borderColor) { + return ""; + } + const width = this.data.rect[2] - this.data.rect[0]; + const height = this.data.rect[3] - this.data.rect[1]; + const rect = rotation === 0 || rotation === 180 ? `0 0 ${width} ${height} re` : `0 0 ${height} ${width} re`; + let str = ""; + if (this.backgroundColor) { + str = `${(0, _default_appearance.getPdfColor)(this.backgroundColor, true)} ${rect} f `; + } + if (this.borderColor) { + const borderWidth = this.borderStyle.width || 1; + str += `${borderWidth} w ${(0, _default_appearance.getPdfColor)(this.borderColor, false)} ${rect} S `; + } + return str; + } + async getOperatorList(evaluator, task, intent, renderForms, annotationStorage) { + if (renderForms && !(this instanceof SignatureWidgetAnnotation) && !this.data.noHTML && !this.data.hasOwnCanvas) { + return { + opList: new _operator_list.OperatorList(), + separateForm: true, + separateCanvas: false + }; + } + if (!this._hasText) { + return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage); + } + const content = await this._getAppearance(evaluator, task, intent, annotationStorage); + if (this.appearance && content === null) { + return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage); + } + const opList = new _operator_list.OperatorList(); + if (!this._defaultAppearance || content === null) { + return { + opList, + separateForm: false, + separateCanvas: false + }; + } + const isUsingOwnCanvas = !!(this.data.hasOwnCanvas && intent & _util.RenderingIntentFlag.DISPLAY); + const matrix = [1, 0, 0, 1, 0, 0]; + const bbox = [0, 0, this.data.rect[2] - this.data.rect[0], this.data.rect[3] - this.data.rect[1]]; + const transform = getTransformMatrix(this.data.rect, bbox, matrix); + let optionalContent; + if (this.oc) { + optionalContent = await evaluator.parseMarkedContentProps(this.oc, null); + } + if (optionalContent !== undefined) { + opList.addOp(_util.OPS.beginMarkedContentProps, ["OC", optionalContent]); + } + opList.addOp(_util.OPS.beginAnnotation, [this.data.id, this.data.rect, transform, this.getRotationMatrix(annotationStorage), isUsingOwnCanvas]); + const stream = new _stream.StringStream(content); + await evaluator.getOperatorList({ + stream, + task, + resources: this._fieldResources.mergedResources, + operatorList: opList + }); + opList.addOp(_util.OPS.endAnnotation, []); + if (optionalContent !== undefined) { + opList.addOp(_util.OPS.endMarkedContent, []); + } + return { + opList, + separateForm: false, + separateCanvas: isUsingOwnCanvas + }; + } + _getMKDict(rotation) { + const mk = new _primitives.Dict(null); + if (rotation) { + mk.set("R", rotation); + } + if (this.borderColor) { + mk.set("BC", getPdfColorArray(this.borderColor)); + } + if (this.backgroundColor) { + mk.set("BG", getPdfColorArray(this.backgroundColor)); + } + return mk.size > 0 ? mk : null; + } + amendSavedDict(annotationStorage, dict) {} + async save(evaluator, task, annotationStorage) { + const storageEntry = annotationStorage?.get(this.data.id); + let value = storageEntry?.value, + rotation = storageEntry?.rotation; + if (value === this.data.fieldValue || value === undefined) { + if (!this._hasValueFromXFA && rotation === undefined) { + return null; + } + value ||= this.data.fieldValue; + } + if (rotation === undefined && !this._hasValueFromXFA && Array.isArray(value) && Array.isArray(this.data.fieldValue) && value.length === this.data.fieldValue.length && value.every((x, i) => x === this.data.fieldValue[i])) { + return null; + } + if (rotation === undefined) { + rotation = this.rotation; + } + let appearance = null; + if (!this._needAppearances) { + appearance = await this._getAppearance(evaluator, task, _util.RenderingIntentFlag.SAVE, annotationStorage); + if (appearance === null) { + return null; + } + } else {} + let needAppearances = false; + if (appearance?.needAppearances) { + needAppearances = true; + appearance = null; + } + const { + xref + } = evaluator; + const originalDict = xref.fetchIfRef(this.ref); + if (!(originalDict instanceof _primitives.Dict)) { + return null; + } + const dict = new _primitives.Dict(xref); + for (const key of originalDict.getKeys()) { + if (key !== "AP") { + dict.set(key, originalDict.getRaw(key)); + } + } + const xfa = { + path: this.data.fieldName, + value + }; + const encoder = val => { + return (0, _core_utils.isAscii)(val) ? val : (0, _core_utils.stringToUTF16String)(val, true); + }; + dict.set("V", Array.isArray(value) ? value.map(encoder) : encoder(value)); + this.amendSavedDict(annotationStorage, dict); + const maybeMK = this._getMKDict(rotation); + if (maybeMK) { + dict.set("MK", maybeMK); + } + const buffer = []; + const changes = [{ + ref: this.ref, + data: "", + xfa, + needAppearances + }]; + if (appearance !== null) { + const newRef = xref.getNewTemporaryRef(); + const AP = new _primitives.Dict(xref); + dict.set("AP", AP); + AP.set("N", newRef); + const resources = this._getSaveFieldResources(xref); + const appearanceStream = new _stream.StringStream(appearance); + const appearanceDict = appearanceStream.dict = new _primitives.Dict(xref); + appearanceDict.set("Subtype", _primitives.Name.get("Form")); + appearanceDict.set("Resources", resources); + appearanceDict.set("BBox", [0, 0, this.data.rect[2] - this.data.rect[0], this.data.rect[3] - this.data.rect[1]]); + const rotationMatrix = this.getRotationMatrix(annotationStorage); + if (rotationMatrix !== _util.IDENTITY_MATRIX) { + appearanceDict.set("Matrix", rotationMatrix); + } + await (0, _writer.writeObject)(newRef, appearanceStream, buffer, xref); + changes.push({ + ref: newRef, + data: buffer.join(""), + xfa: null, + needAppearances: false + }); + buffer.length = 0; + } + dict.set("M", `D:${(0, _util.getModificationDate)()}`); + await (0, _writer.writeObject)(this.ref, dict, buffer, xref); + changes[0].data = buffer.join(""); + return changes; + } + async _getAppearance(evaluator, task, intent, annotationStorage) { + const isPassword = this.hasFieldFlag(_util.AnnotationFieldFlag.PASSWORD); + if (isPassword) { + return null; + } + const storageEntry = annotationStorage?.get(this.data.id); + let value, rotation; + if (storageEntry) { + value = storageEntry.formattedValue || storageEntry.value; + rotation = storageEntry.rotation; + } + if (rotation === undefined && value === undefined && !this._needAppearances) { + if (!this._hasValueFromXFA || this.appearance) { + return null; + } + } + const colors = this.getBorderAndBackgroundAppearances(annotationStorage); + if (value === undefined) { + value = this.data.fieldValue; + if (!value) { + return `/Tx BMC q ${colors}Q EMC`; + } + } + if (Array.isArray(value) && value.length === 1) { + value = value[0]; + } + (0, _util.assert)(typeof value === "string", "Expected `value` to be a string."); + value = value.trim(); + if (this.data.combo) { + const option = this.data.options.find(({ + exportValue + }) => value === exportValue); + value = option?.displayValue || value; + } + if (value === "") { + return `/Tx BMC q ${colors}Q EMC`; + } + if (rotation === undefined) { + rotation = this.rotation; + } + let lineCount = -1; + let lines; + if (this.data.multiLine) { + lines = value.split(/\r\n?|\n/).map(line => line.normalize("NFC")); + lineCount = lines.length; + } else { + lines = [value.replace(/\r\n?|\n/, "").normalize("NFC")]; + } + const defaultPadding = 1; + const defaultHPadding = 2; + let totalHeight = this.data.rect[3] - this.data.rect[1]; + let totalWidth = this.data.rect[2] - this.data.rect[0]; + if (rotation === 90 || rotation === 270) { + [totalWidth, totalHeight] = [totalHeight, totalWidth]; + } + if (!this._defaultAppearance) { + this.data.defaultAppearanceData = (0, _default_appearance.parseDefaultAppearance)(this._defaultAppearance = "/Helvetica 0 Tf 0 g"); + } + let font = await WidgetAnnotation._getFontData(evaluator, task, this.data.defaultAppearanceData, this._fieldResources.mergedResources); + let defaultAppearance, fontSize, lineHeight; + const encodedLines = []; + let encodingError = false; + for (const line of lines) { + const encodedString = font.encodeString(line); + if (encodedString.length > 1) { + encodingError = true; + } + encodedLines.push(encodedString.join("")); + } + if (encodingError && intent & _util.RenderingIntentFlag.SAVE) { + return { + needAppearances: true + }; + } + if (encodingError && this._isOffscreenCanvasSupported) { + const fontFamily = this.data.comb ? "monospace" : "sans-serif"; + const fakeUnicodeFont = new _default_appearance.FakeUnicodeFont(evaluator.xref, fontFamily); + const resources = fakeUnicodeFont.createFontResources(lines.join("")); + const newFont = resources.getRaw("Font"); + if (this._fieldResources.mergedResources.has("Font")) { + const oldFont = this._fieldResources.mergedResources.get("Font"); + for (const key of newFont.getKeys()) { + oldFont.set(key, newFont.getRaw(key)); + } + } else { + this._fieldResources.mergedResources.set("Font", newFont); + } + const fontName = fakeUnicodeFont.fontName.name; + font = await WidgetAnnotation._getFontData(evaluator, task, { + fontName, + fontSize: 0 + }, resources); + for (let i = 0, ii = encodedLines.length; i < ii; i++) { + encodedLines[i] = (0, _core_utils.stringToUTF16String)(lines[i]); + } + const savedDefaultAppearance = Object.assign(Object.create(null), this.data.defaultAppearanceData); + this.data.defaultAppearanceData.fontSize = 0; + this.data.defaultAppearanceData.fontName = fontName; + [defaultAppearance, fontSize, lineHeight] = this._computeFontSize(totalHeight - 2 * defaultPadding, totalWidth - 2 * defaultHPadding, value, font, lineCount); + this.data.defaultAppearanceData = savedDefaultAppearance; + } else { + if (!this._isOffscreenCanvasSupported) { + (0, _util.warn)("_getAppearance: OffscreenCanvas is not supported, annotation may not render correctly."); + } + [defaultAppearance, fontSize, lineHeight] = this._computeFontSize(totalHeight - 2 * defaultPadding, totalWidth - 2 * defaultHPadding, value, font, lineCount); + } + let descent = font.descent; + if (isNaN(descent)) { + descent = _util.BASELINE_FACTOR * lineHeight; + } else { + descent = Math.max(_util.BASELINE_FACTOR * lineHeight, Math.abs(descent) * fontSize); + } + const defaultVPadding = Math.min(Math.floor((totalHeight - fontSize) / 2), defaultPadding); + const alignment = this.data.textAlignment; + if (this.data.multiLine) { + return this._getMultilineAppearance(defaultAppearance, encodedLines, font, fontSize, totalWidth, totalHeight, alignment, defaultHPadding, defaultVPadding, descent, lineHeight, annotationStorage); + } + if (this.data.comb) { + return this._getCombAppearance(defaultAppearance, font, encodedLines[0], fontSize, totalWidth, totalHeight, defaultHPadding, defaultVPadding, descent, lineHeight, annotationStorage); + } + const bottomPadding = defaultVPadding + descent; + if (alignment === 0 || alignment > 2) { + return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 ${(0, _core_utils.numberToString)(defaultHPadding)} ${(0, _core_utils.numberToString)(bottomPadding)} Tm (${(0, _core_utils.escapeString)(encodedLines[0])}) Tj` + " ET Q EMC"; + } + const prevInfo = { + shift: 0 + }; + const renderedText = this._renderText(encodedLines[0], font, fontSize, totalWidth, alignment, prevInfo, defaultHPadding, bottomPadding); + return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 0 0 Tm ${renderedText}` + " ET Q EMC"; + } + static async _getFontData(evaluator, task, appearanceData, resources) { + const operatorList = new _operator_list.OperatorList(); + const initialState = { + font: null, + clone() { + return this; + } + }; + const { + fontName, + fontSize + } = appearanceData; + await evaluator.handleSetFont(resources, [fontName && _primitives.Name.get(fontName), fontSize], null, operatorList, task, initialState, null); + return initialState.font; + } + _getTextWidth(text, font) { + return font.charsToGlyphs(text).reduce((width, glyph) => width + glyph.width, 0) / 1000; + } + _computeFontSize(height, width, text, font, lineCount) { + let { + fontSize + } = this.data.defaultAppearanceData; + let lineHeight = (fontSize || 12) * _util.LINE_FACTOR, + numberOfLines = Math.round(height / lineHeight); + if (!fontSize) { + const roundWithTwoDigits = x => Math.floor(x * 100) / 100; + if (lineCount === -1) { + const textWidth = this._getTextWidth(text, font); + fontSize = roundWithTwoDigits(Math.min(height / _util.LINE_FACTOR, textWidth > width ? width / textWidth : Infinity)); + numberOfLines = 1; + } else { + const lines = text.split(/\r\n?|\n/); + const cachedLines = []; + for (const line of lines) { + const encoded = font.encodeString(line).join(""); + const glyphs = font.charsToGlyphs(encoded); + const positions = font.getCharPositions(encoded); + cachedLines.push({ + line: encoded, + glyphs, + positions + }); + } + const isTooBig = fsize => { + let totalHeight = 0; + for (const cache of cachedLines) { + const chunks = this._splitLine(null, font, fsize, width, cache); + totalHeight += chunks.length * fsize; + if (totalHeight > height) { + return true; + } + } + return false; + }; + numberOfLines = Math.max(numberOfLines, lineCount); + while (true) { + lineHeight = height / numberOfLines; + fontSize = roundWithTwoDigits(lineHeight / _util.LINE_FACTOR); + if (isTooBig(fontSize)) { + numberOfLines++; + continue; + } + break; + } + } + const { + fontName, + fontColor + } = this.data.defaultAppearanceData; + this._defaultAppearance = (0, _default_appearance.createDefaultAppearance)({ + fontSize, + fontName, + fontColor + }); + } + return [this._defaultAppearance, fontSize, height / numberOfLines]; + } + _renderText(text, font, fontSize, totalWidth, alignment, prevInfo, hPadding, vPadding) { + let shift; + if (alignment === 1) { + const width = this._getTextWidth(text, font) * fontSize; + shift = (totalWidth - width) / 2; + } else if (alignment === 2) { + const width = this._getTextWidth(text, font) * fontSize; + shift = totalWidth - width - hPadding; + } else { + shift = hPadding; + } + const shiftStr = (0, _core_utils.numberToString)(shift - prevInfo.shift); + prevInfo.shift = shift; + vPadding = (0, _core_utils.numberToString)(vPadding); + return `${shiftStr} ${vPadding} Td (${(0, _core_utils.escapeString)(text)}) Tj`; + } + _getSaveFieldResources(xref) { + const { + localResources, + appearanceResources, + acroFormResources + } = this._fieldResources; + const fontName = this.data.defaultAppearanceData?.fontName; + if (!fontName) { + return localResources || _primitives.Dict.empty; + } + for (const resources of [localResources, appearanceResources]) { + if (resources instanceof _primitives.Dict) { + const localFont = resources.get("Font"); + if (localFont instanceof _primitives.Dict && localFont.has(fontName)) { + return resources; + } + } + } + if (acroFormResources instanceof _primitives.Dict) { + const acroFormFont = acroFormResources.get("Font"); + if (acroFormFont instanceof _primitives.Dict && acroFormFont.has(fontName)) { + const subFontDict = new _primitives.Dict(xref); + subFontDict.set(fontName, acroFormFont.getRaw(fontName)); + const subResourcesDict = new _primitives.Dict(xref); + subResourcesDict.set("Font", subFontDict); + return _primitives.Dict.merge({ + xref, + dictArray: [subResourcesDict, localResources], + mergeSubDicts: true + }); + } + } + return localResources || _primitives.Dict.empty; + } + getFieldObject() { + return null; + } +} +class TextWidgetAnnotation extends WidgetAnnotation { + constructor(params) { + super(params); + this.data.hasOwnCanvas = this.data.readOnly && !this.data.noHTML; + this._hasText = true; + const dict = params.dict; + if (typeof this.data.fieldValue !== "string") { + this.data.fieldValue = ""; + } + let alignment = (0, _core_utils.getInheritableProperty)({ + dict, + key: "Q" + }); + if (!Number.isInteger(alignment) || alignment < 0 || alignment > 2) { + alignment = null; + } + this.data.textAlignment = alignment; + let maximumLength = (0, _core_utils.getInheritableProperty)({ + dict, + key: "MaxLen" + }); + if (!Number.isInteger(maximumLength) || maximumLength < 0) { + maximumLength = 0; + } + this.data.maxLen = maximumLength; + this.data.multiLine = this.hasFieldFlag(_util.AnnotationFieldFlag.MULTILINE); + this.data.comb = this.hasFieldFlag(_util.AnnotationFieldFlag.COMB) && !this.hasFieldFlag(_util.AnnotationFieldFlag.MULTILINE) && !this.hasFieldFlag(_util.AnnotationFieldFlag.PASSWORD) && !this.hasFieldFlag(_util.AnnotationFieldFlag.FILESELECT) && this.data.maxLen !== 0; + this.data.doNotScroll = this.hasFieldFlag(_util.AnnotationFieldFlag.DONOTSCROLL); + } + get hasTextContent() { + return !!this.appearance && !this._needAppearances; + } + _getCombAppearance(defaultAppearance, font, text, fontSize, width, height, hPadding, vPadding, descent, lineHeight, annotationStorage) { + const combWidth = width / this.data.maxLen; + const colors = this.getBorderAndBackgroundAppearances(annotationStorage); + const buf = []; + const positions = font.getCharPositions(text); + for (const [start, end] of positions) { + buf.push(`(${(0, _core_utils.escapeString)(text.substring(start, end))}) Tj`); + } + const renderedComb = buf.join(` ${(0, _core_utils.numberToString)(combWidth)} 0 Td `); + return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 ${(0, _core_utils.numberToString)(hPadding)} ${(0, _core_utils.numberToString)(vPadding + descent)} Tm ${renderedComb}` + " ET Q EMC"; + } + _getMultilineAppearance(defaultAppearance, lines, font, fontSize, width, height, alignment, hPadding, vPadding, descent, lineHeight, annotationStorage) { + const buf = []; + const totalWidth = width - 2 * hPadding; + const prevInfo = { + shift: 0 + }; + for (let i = 0, ii = lines.length; i < ii; i++) { + const line = lines[i]; + const chunks = this._splitLine(line, font, fontSize, totalWidth); + for (let j = 0, jj = chunks.length; j < jj; j++) { + const chunk = chunks[j]; + const vShift = i === 0 && j === 0 ? -vPadding - (lineHeight - descent) : -lineHeight; + buf.push(this._renderText(chunk, font, fontSize, width, alignment, prevInfo, hPadding, vShift)); + } + } + const colors = this.getBorderAndBackgroundAppearances(annotationStorage); + const renderedText = buf.join("\n"); + return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 0 ${(0, _core_utils.numberToString)(height)} Tm ${renderedText}` + " ET Q EMC"; + } + _splitLine(line, font, fontSize, width, cache = {}) { + line = cache.line || line; + const glyphs = cache.glyphs || font.charsToGlyphs(line); + if (glyphs.length <= 1) { + return [line]; + } + const positions = cache.positions || font.getCharPositions(line); + const scale = fontSize / 1000; + const chunks = []; + let lastSpacePosInStringStart = -1, + lastSpacePosInStringEnd = -1, + lastSpacePos = -1, + startChunk = 0, + currentWidth = 0; + for (let i = 0, ii = glyphs.length; i < ii; i++) { + const [start, end] = positions[i]; + const glyph = glyphs[i]; + const glyphWidth = glyph.width * scale; + if (glyph.unicode === " ") { + if (currentWidth + glyphWidth > width) { + chunks.push(line.substring(startChunk, start)); + startChunk = start; + currentWidth = glyphWidth; + lastSpacePosInStringStart = -1; + lastSpacePos = -1; + } else { + currentWidth += glyphWidth; + lastSpacePosInStringStart = start; + lastSpacePosInStringEnd = end; + lastSpacePos = i; + } + } else if (currentWidth + glyphWidth > width) { + if (lastSpacePosInStringStart !== -1) { + chunks.push(line.substring(startChunk, lastSpacePosInStringEnd)); + startChunk = lastSpacePosInStringEnd; + i = lastSpacePos + 1; + lastSpacePosInStringStart = -1; + currentWidth = 0; + } else { + chunks.push(line.substring(startChunk, start)); + startChunk = start; + currentWidth = glyphWidth; + } + } else { + currentWidth += glyphWidth; + } + } + if (startChunk < line.length) { + chunks.push(line.substring(startChunk, line.length)); + } + return chunks; + } + getFieldObject() { + return { + id: this.data.id, + value: this.data.fieldValue, + defaultValue: this.data.defaultFieldValue || "", + multiline: this.data.multiLine, + password: this.hasFieldFlag(_util.AnnotationFieldFlag.PASSWORD), + charLimit: this.data.maxLen, + comb: this.data.comb, + editable: !this.data.readOnly, + hidden: this.data.hidden, + name: this.data.fieldName, + rect: this.data.rect, + actions: this.data.actions, + page: this.data.pageIndex, + strokeColor: this.data.borderColor, + fillColor: this.data.backgroundColor, + rotation: this.rotation, + type: "text" + }; + } +} +class ButtonWidgetAnnotation extends WidgetAnnotation { + constructor(params) { + super(params); + this.checkedAppearance = null; + this.uncheckedAppearance = null; + this.data.checkBox = !this.hasFieldFlag(_util.AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(_util.AnnotationFieldFlag.PUSHBUTTON); + this.data.radioButton = this.hasFieldFlag(_util.AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(_util.AnnotationFieldFlag.PUSHBUTTON); + this.data.pushButton = this.hasFieldFlag(_util.AnnotationFieldFlag.PUSHBUTTON); + this.data.isTooltipOnly = false; + if (this.data.checkBox) { + this._processCheckBox(params); + } else if (this.data.radioButton) { + this._processRadioButton(params); + } else if (this.data.pushButton) { + this.data.hasOwnCanvas = true; + this._processPushButton(params); + } else { + (0, _util.warn)("Invalid field flags for button widget annotation"); + } + } + async getOperatorList(evaluator, task, intent, renderForms, annotationStorage) { + if (this.data.pushButton) { + return super.getOperatorList(evaluator, task, intent, false, annotationStorage); + } + let value = null; + let rotation = null; + if (annotationStorage) { + const storageEntry = annotationStorage.get(this.data.id); + value = storageEntry ? storageEntry.value : null; + rotation = storageEntry ? storageEntry.rotation : null; + } + if (value === null && this.appearance) { + return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage); + } + if (value === null || value === undefined) { + value = this.data.checkBox ? this.data.fieldValue === this.data.exportValue : this.data.fieldValue === this.data.buttonValue; + } + const appearance = value ? this.checkedAppearance : this.uncheckedAppearance; + if (appearance) { + const savedAppearance = this.appearance; + const savedMatrix = appearance.dict.getArray("Matrix") || _util.IDENTITY_MATRIX; + if (rotation) { + appearance.dict.set("Matrix", this.getRotationMatrix(annotationStorage)); + } + this.appearance = appearance; + const operatorList = super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage); + this.appearance = savedAppearance; + appearance.dict.set("Matrix", savedMatrix); + return operatorList; + } + return { + opList: new _operator_list.OperatorList(), + separateForm: false, + separateCanvas: false + }; + } + async save(evaluator, task, annotationStorage) { + if (this.data.checkBox) { + return this._saveCheckbox(evaluator, task, annotationStorage); + } + if (this.data.radioButton) { + return this._saveRadioButton(evaluator, task, annotationStorage); + } + return null; + } + async _saveCheckbox(evaluator, task, annotationStorage) { + if (!annotationStorage) { + return null; + } + const storageEntry = annotationStorage.get(this.data.id); + let rotation = storageEntry?.rotation, + value = storageEntry?.value; + if (rotation === undefined) { + if (value === undefined) { + return null; + } + const defaultValue = this.data.fieldValue === this.data.exportValue; + if (defaultValue === value) { + return null; + } + } + const dict = evaluator.xref.fetchIfRef(this.ref); + if (!(dict instanceof _primitives.Dict)) { + return null; + } + if (rotation === undefined) { + rotation = this.rotation; + } + if (value === undefined) { + value = this.data.fieldValue === this.data.exportValue; + } + const xfa = { + path: this.data.fieldName, + value: value ? this.data.exportValue : "" + }; + const name = _primitives.Name.get(value ? this.data.exportValue : "Off"); + dict.set("V", name); + dict.set("AS", name); + dict.set("M", `D:${(0, _util.getModificationDate)()}`); + const maybeMK = this._getMKDict(rotation); + if (maybeMK) { + dict.set("MK", maybeMK); + } + const buffer = []; + await (0, _writer.writeObject)(this.ref, dict, buffer, evaluator.xref); + return [{ + ref: this.ref, + data: buffer.join(""), + xfa + }]; + } + async _saveRadioButton(evaluator, task, annotationStorage) { + if (!annotationStorage) { + return null; + } + const storageEntry = annotationStorage.get(this.data.id); + let rotation = storageEntry?.rotation, + value = storageEntry?.value; + if (rotation === undefined) { + if (value === undefined) { + return null; + } + const defaultValue = this.data.fieldValue === this.data.buttonValue; + if (defaultValue === value) { + return null; + } + } + const dict = evaluator.xref.fetchIfRef(this.ref); + if (!(dict instanceof _primitives.Dict)) { + return null; + } + if (value === undefined) { + value = this.data.fieldValue === this.data.buttonValue; + } + if (rotation === undefined) { + rotation = this.rotation; + } + const xfa = { + path: this.data.fieldName, + value: value ? this.data.buttonValue : "" + }; + const name = _primitives.Name.get(value ? this.data.buttonValue : "Off"); + const buffer = []; + let parentData = null; + if (value) { + if (this.parent instanceof _primitives.Ref) { + const parent = evaluator.xref.fetch(this.parent); + parent.set("V", name); + await (0, _writer.writeObject)(this.parent, parent, buffer, evaluator.xref); + parentData = buffer.join(""); + buffer.length = 0; + } else if (this.parent instanceof _primitives.Dict) { + this.parent.set("V", name); + } + } + dict.set("AS", name); + dict.set("M", `D:${(0, _util.getModificationDate)()}`); + const maybeMK = this._getMKDict(rotation); + if (maybeMK) { + dict.set("MK", maybeMK); + } + await (0, _writer.writeObject)(this.ref, dict, buffer, evaluator.xref); + const newRefs = [{ + ref: this.ref, + data: buffer.join(""), + xfa + }]; + if (parentData) { + newRefs.push({ + ref: this.parent, + data: parentData, + xfa: null + }); + } + return newRefs; + } + _getDefaultCheckedAppearance(params, type) { + const width = this.data.rect[2] - this.data.rect[0]; + const height = this.data.rect[3] - this.data.rect[1]; + const bbox = [0, 0, width, height]; + const FONT_RATIO = 0.8; + const fontSize = Math.min(width, height) * FONT_RATIO; + let metrics, char; + if (type === "check") { + metrics = { + width: 0.755 * fontSize, + height: 0.705 * fontSize + }; + char = "\x33"; + } else if (type === "disc") { + metrics = { + width: 0.791 * fontSize, + height: 0.705 * fontSize + }; + char = "\x6C"; + } else { + (0, _util.unreachable)(`_getDefaultCheckedAppearance - unsupported type: ${type}`); + } + const xShift = (0, _core_utils.numberToString)((width - metrics.width) / 2); + const yShift = (0, _core_utils.numberToString)((height - metrics.height) / 2); + const appearance = `q BT /PdfJsZaDb ${fontSize} Tf 0 g ${xShift} ${yShift} Td (${char}) Tj ET Q`; + const appearanceStreamDict = new _primitives.Dict(params.xref); + appearanceStreamDict.set("FormType", 1); + appearanceStreamDict.set("Subtype", _primitives.Name.get("Form")); + appearanceStreamDict.set("Type", _primitives.Name.get("XObject")); + appearanceStreamDict.set("BBox", bbox); + appearanceStreamDict.set("Matrix", [1, 0, 0, 1, 0, 0]); + appearanceStreamDict.set("Length", appearance.length); + const resources = new _primitives.Dict(params.xref); + const font = new _primitives.Dict(params.xref); + font.set("PdfJsZaDb", this.fallbackFontDict); + resources.set("Font", font); + appearanceStreamDict.set("Resources", resources); + this.checkedAppearance = new _stream.StringStream(appearance); + this.checkedAppearance.dict = appearanceStreamDict; + this._streams.push(this.checkedAppearance); + } + _processCheckBox(params) { + const customAppearance = params.dict.get("AP"); + if (!(customAppearance instanceof _primitives.Dict)) { + return; + } + const normalAppearance = customAppearance.get("N"); + if (!(normalAppearance instanceof _primitives.Dict)) { + return; + } + const asValue = this._decodeFormValue(params.dict.get("AS")); + if (typeof asValue === "string") { + this.data.fieldValue = asValue; + } + const yes = this.data.fieldValue !== null && this.data.fieldValue !== "Off" ? this.data.fieldValue : "Yes"; + const exportValues = normalAppearance.getKeys(); + if (exportValues.length === 0) { + exportValues.push("Off", yes); + } else if (exportValues.length === 1) { + if (exportValues[0] === "Off") { + exportValues.push(yes); + } else { + exportValues.unshift("Off"); + } + } else if (exportValues.includes(yes)) { + exportValues.length = 0; + exportValues.push("Off", yes); + } else { + const otherYes = exportValues.find(v => v !== "Off"); + exportValues.length = 0; + exportValues.push("Off", otherYes); + } + if (!exportValues.includes(this.data.fieldValue)) { + this.data.fieldValue = "Off"; + } + this.data.exportValue = exportValues[1]; + const checkedAppearance = normalAppearance.get(this.data.exportValue); + this.checkedAppearance = checkedAppearance instanceof _base_stream.BaseStream ? checkedAppearance : null; + const uncheckedAppearance = normalAppearance.get("Off"); + this.uncheckedAppearance = uncheckedAppearance instanceof _base_stream.BaseStream ? uncheckedAppearance : null; + if (this.checkedAppearance) { + this._streams.push(this.checkedAppearance); + } else { + this._getDefaultCheckedAppearance(params, "check"); + } + if (this.uncheckedAppearance) { + this._streams.push(this.uncheckedAppearance); + } + this._fallbackFontDict = this.fallbackFontDict; + if (this.data.defaultFieldValue === null) { + this.data.defaultFieldValue = "Off"; + } + } + _processRadioButton(params) { + this.data.fieldValue = this.data.buttonValue = null; + const fieldParent = params.dict.get("Parent"); + if (fieldParent instanceof _primitives.Dict) { + this.parent = params.dict.getRaw("Parent"); + const fieldParentValue = fieldParent.get("V"); + if (fieldParentValue instanceof _primitives.Name) { + this.data.fieldValue = this._decodeFormValue(fieldParentValue); + } + } + const appearanceStates = params.dict.get("AP"); + if (!(appearanceStates instanceof _primitives.Dict)) { + return; + } + const normalAppearance = appearanceStates.get("N"); + if (!(normalAppearance instanceof _primitives.Dict)) { + return; + } + for (const key of normalAppearance.getKeys()) { + if (key !== "Off") { + this.data.buttonValue = this._decodeFormValue(key); + break; + } + } + const checkedAppearance = normalAppearance.get(this.data.buttonValue); + this.checkedAppearance = checkedAppearance instanceof _base_stream.BaseStream ? checkedAppearance : null; + const uncheckedAppearance = normalAppearance.get("Off"); + this.uncheckedAppearance = uncheckedAppearance instanceof _base_stream.BaseStream ? uncheckedAppearance : null; + if (this.checkedAppearance) { + this._streams.push(this.checkedAppearance); + } else { + this._getDefaultCheckedAppearance(params, "disc"); + } + if (this.uncheckedAppearance) { + this._streams.push(this.uncheckedAppearance); + } + this._fallbackFontDict = this.fallbackFontDict; + if (this.data.defaultFieldValue === null) { + this.data.defaultFieldValue = "Off"; + } + } + _processPushButton(params) { + const { + dict, + annotationGlobals + } = params; + if (!dict.has("A") && !dict.has("AA") && !this.data.alternativeText) { + (0, _util.warn)("Push buttons without action dictionaries are not supported"); + return; + } + this.data.isTooltipOnly = !dict.has("A") && !dict.has("AA"); + _catalog.Catalog.parseDestDictionary({ + destDict: dict, + resultObj: this.data, + docBaseUrl: annotationGlobals.baseUrl, + docAttachments: annotationGlobals.attachments + }); + } + getFieldObject() { + let type = "button"; + let exportValues; + if (this.data.checkBox) { + type = "checkbox"; + exportValues = this.data.exportValue; + } else if (this.data.radioButton) { + type = "radiobutton"; + exportValues = this.data.buttonValue; + } + return { + id: this.data.id, + value: this.data.fieldValue || "Off", + defaultValue: this.data.defaultFieldValue, + exportValues, + editable: !this.data.readOnly, + name: this.data.fieldName, + rect: this.data.rect, + hidden: this.data.hidden, + actions: this.data.actions, + page: this.data.pageIndex, + strokeColor: this.data.borderColor, + fillColor: this.data.backgroundColor, + rotation: this.rotation, + type + }; + } + get fallbackFontDict() { + const dict = new _primitives.Dict(); + dict.set("BaseFont", _primitives.Name.get("ZapfDingbats")); + dict.set("Type", _primitives.Name.get("FallbackType")); + dict.set("Subtype", _primitives.Name.get("FallbackType")); + dict.set("Encoding", _primitives.Name.get("ZapfDingbatsEncoding")); + return (0, _util.shadow)(this, "fallbackFontDict", dict); + } +} +class ChoiceWidgetAnnotation extends WidgetAnnotation { + constructor(params) { + super(params); + const { + dict, + xref + } = params; + this.indices = dict.getArray("I"); + this.hasIndices = Array.isArray(this.indices) && this.indices.length > 0; + this.data.options = []; + const options = (0, _core_utils.getInheritableProperty)({ + dict, + key: "Opt" + }); + if (Array.isArray(options)) { + for (let i = 0, ii = options.length; i < ii; i++) { + const option = xref.fetchIfRef(options[i]); + const isOptionArray = Array.isArray(option); + this.data.options[i] = { + exportValue: this._decodeFormValue(isOptionArray ? xref.fetchIfRef(option[0]) : option), + displayValue: this._decodeFormValue(isOptionArray ? xref.fetchIfRef(option[1]) : option) + }; + } + } + if (!this.hasIndices) { + if (typeof this.data.fieldValue === "string") { + this.data.fieldValue = [this.data.fieldValue]; + } else if (!this.data.fieldValue) { + this.data.fieldValue = []; + } + } else { + this.data.fieldValue = []; + const ii = this.data.options.length; + for (const i of this.indices) { + if (Number.isInteger(i) && i >= 0 && i < ii) { + this.data.fieldValue.push(this.data.options[i].exportValue); + } + } + } + this.data.combo = this.hasFieldFlag(_util.AnnotationFieldFlag.COMBO); + this.data.multiSelect = this.hasFieldFlag(_util.AnnotationFieldFlag.MULTISELECT); + this._hasText = true; + } + getFieldObject() { + const type = this.data.combo ? "combobox" : "listbox"; + const value = this.data.fieldValue.length > 0 ? this.data.fieldValue[0] : null; + return { + id: this.data.id, + value, + defaultValue: this.data.defaultFieldValue, + editable: !this.data.readOnly, + name: this.data.fieldName, + rect: this.data.rect, + numItems: this.data.fieldValue.length, + multipleSelection: this.data.multiSelect, + hidden: this.data.hidden, + actions: this.data.actions, + items: this.data.options, + page: this.data.pageIndex, + strokeColor: this.data.borderColor, + fillColor: this.data.backgroundColor, + rotation: this.rotation, + type + }; + } + amendSavedDict(annotationStorage, dict) { + if (!this.hasIndices) { + return; + } + let values = annotationStorage?.get(this.data.id)?.value; + if (!Array.isArray(values)) { + values = [values]; + } + const indices = []; + const { + options + } = this.data; + for (let i = 0, j = 0, ii = options.length; i < ii; i++) { + if (options[i].exportValue === values[j]) { + indices.push(i); + j += 1; + } + } + dict.set("I", indices); + } + async _getAppearance(evaluator, task, intent, annotationStorage) { + if (this.data.combo) { + return super._getAppearance(evaluator, task, intent, annotationStorage); + } + let exportedValue, rotation; + const storageEntry = annotationStorage?.get(this.data.id); + if (storageEntry) { + rotation = storageEntry.rotation; + exportedValue = storageEntry.value; + } + if (rotation === undefined && exportedValue === undefined && !this._needAppearances) { + return null; + } + if (exportedValue === undefined) { + exportedValue = this.data.fieldValue; + } else if (!Array.isArray(exportedValue)) { + exportedValue = [exportedValue]; + } + const defaultPadding = 1; + const defaultHPadding = 2; + let totalHeight = this.data.rect[3] - this.data.rect[1]; + let totalWidth = this.data.rect[2] - this.data.rect[0]; + if (rotation === 90 || rotation === 270) { + [totalWidth, totalHeight] = [totalHeight, totalWidth]; + } + const lineCount = this.data.options.length; + const valueIndices = []; + for (let i = 0; i < lineCount; i++) { + const { + exportValue + } = this.data.options[i]; + if (exportedValue.includes(exportValue)) { + valueIndices.push(i); + } + } + if (!this._defaultAppearance) { + this.data.defaultAppearanceData = (0, _default_appearance.parseDefaultAppearance)(this._defaultAppearance = "/Helvetica 0 Tf 0 g"); + } + const font = await WidgetAnnotation._getFontData(evaluator, task, this.data.defaultAppearanceData, this._fieldResources.mergedResources); + let defaultAppearance; + let { + fontSize + } = this.data.defaultAppearanceData; + if (!fontSize) { + const lineHeight = (totalHeight - defaultPadding) / lineCount; + let lineWidth = -1; + let value; + for (const { + displayValue + } of this.data.options) { + const width = this._getTextWidth(displayValue, font); + if (width > lineWidth) { + lineWidth = width; + value = displayValue; + } + } + [defaultAppearance, fontSize] = this._computeFontSize(lineHeight, totalWidth - 2 * defaultHPadding, value, font, -1); + } else { + defaultAppearance = this._defaultAppearance; + } + const lineHeight = fontSize * _util.LINE_FACTOR; + const vPadding = (lineHeight - fontSize) / 2; + const numberOfVisibleLines = Math.floor(totalHeight / lineHeight); + let firstIndex = 0; + if (valueIndices.length > 0) { + const minIndex = Math.min(...valueIndices); + const maxIndex = Math.max(...valueIndices); + firstIndex = Math.max(0, maxIndex - numberOfVisibleLines + 1); + if (firstIndex > minIndex) { + firstIndex = minIndex; + } + } + const end = Math.min(firstIndex + numberOfVisibleLines + 1, lineCount); + const buf = ["/Tx BMC q", `1 1 ${totalWidth} ${totalHeight} re W n`]; + if (valueIndices.length) { + buf.push("0.600006 0.756866 0.854904 rg"); + for (const index of valueIndices) { + if (firstIndex <= index && index < end) { + buf.push(`1 ${totalHeight - (index - firstIndex + 1) * lineHeight} ${totalWidth} ${lineHeight} re f`); + } + } + } + buf.push("BT", defaultAppearance, `1 0 0 1 0 ${totalHeight} Tm`); + const prevInfo = { + shift: 0 + }; + for (let i = firstIndex; i < end; i++) { + const { + displayValue + } = this.data.options[i]; + const vpadding = i === firstIndex ? vPadding : 0; + buf.push(this._renderText(displayValue, font, fontSize, totalWidth, 0, prevInfo, defaultHPadding, -lineHeight + vpadding)); + } + buf.push("ET Q EMC"); + return buf.join("\n"); + } +} +class SignatureWidgetAnnotation extends WidgetAnnotation { + constructor(params) { + super(params); + this.data.fieldValue = null; + this.data.hasOwnCanvas = this.data.noRotate; + } + getFieldObject() { + return { + id: this.data.id, + value: null, + page: this.data.pageIndex, + type: "signature" + }; + } +} +class TextAnnotation extends MarkupAnnotation { + constructor(params) { + const DEFAULT_ICON_SIZE = 22; + super(params); + this.data.noRotate = true; + this.data.hasOwnCanvas = this.data.noRotate; + const { + dict + } = params; + this.data.annotationType = _util.AnnotationType.TEXT; + if (this.data.hasAppearance) { + this.data.name = "NoIcon"; + } else { + this.data.rect[1] = this.data.rect[3] - DEFAULT_ICON_SIZE; + this.data.rect[2] = this.data.rect[0] + DEFAULT_ICON_SIZE; + this.data.name = dict.has("Name") ? dict.get("Name").name : "Note"; + } + if (dict.has("State")) { + this.data.state = dict.get("State") || null; + this.data.stateModel = dict.get("StateModel") || null; + } else { + this.data.state = null; + this.data.stateModel = null; + } + } +} +class LinkAnnotation extends Annotation { + constructor(params) { + super(params); + const { + dict, + annotationGlobals + } = params; + this.data.annotationType = _util.AnnotationType.LINK; + const quadPoints = getQuadPoints(dict, this.rectangle); + if (quadPoints) { + this.data.quadPoints = quadPoints; + } + this.data.borderColor ||= this.data.color; + _catalog.Catalog.parseDestDictionary({ + destDict: dict, + resultObj: this.data, + docBaseUrl: annotationGlobals.baseUrl, + docAttachments: annotationGlobals.attachments + }); + } +} +class PopupAnnotation extends Annotation { + constructor(params) { + super(params); + const { + dict + } = params; + this.data.annotationType = _util.AnnotationType.POPUP; + if (this.data.rect[0] === this.data.rect[2] || this.data.rect[1] === this.data.rect[3]) { + this.data.rect = null; + } + let parentItem = dict.get("Parent"); + if (!parentItem) { + (0, _util.warn)("Popup annotation has a missing or invalid parent annotation."); + return; + } + const parentRect = parentItem.getArray("Rect"); + this.data.parentRect = Array.isArray(parentRect) && parentRect.length === 4 ? _util.Util.normalizeRect(parentRect) : null; + const rt = parentItem.get("RT"); + if ((0, _primitives.isName)(rt, _util.AnnotationReplyType.GROUP)) { + parentItem = parentItem.get("IRT"); + } + if (!parentItem.has("M")) { + this.data.modificationDate = null; + } else { + this.setModificationDate(parentItem.get("M")); + this.data.modificationDate = this.modificationDate; + } + if (!parentItem.has("C")) { + this.data.color = null; + } else { + this.setColor(parentItem.getArray("C")); + this.data.color = this.color; + } + if (!this.viewable) { + const parentFlags = parentItem.get("F"); + if (this._isViewable(parentFlags)) { + this.setFlags(parentFlags); + } + } + this.setTitle(parentItem.get("T")); + this.data.titleObj = this._title; + this.setContents(parentItem.get("Contents")); + this.data.contentsObj = this._contents; + if (parentItem.has("RC")) { + this.data.richText = _factory.XFAFactory.getRichTextAsHtml(parentItem.get("RC")); + } + this.data.open = !!dict.get("Open"); + } +} +exports.PopupAnnotation = PopupAnnotation; +class FreeTextAnnotation extends MarkupAnnotation { + constructor(params) { + super(params); + this.data.hasOwnCanvas = true; + const { + evaluatorOptions, + xref + } = params; + this.data.annotationType = _util.AnnotationType.FREETEXT; + this.setDefaultAppearance(params); + if (this.appearance) { + const { + fontColor, + fontSize + } = (0, _default_appearance.parseAppearanceStream)(this.appearance, evaluatorOptions, xref); + this.data.defaultAppearanceData.fontColor = fontColor; + this.data.defaultAppearanceData.fontSize = fontSize || 10; + } else if (this._isOffscreenCanvasSupported) { + const strokeAlpha = params.dict.get("CA"); + const fakeUnicodeFont = new _default_appearance.FakeUnicodeFont(xref, "sans-serif"); + this.data.defaultAppearanceData.fontSize ||= 10; + const { + fontColor, + fontSize + } = this.data.defaultAppearanceData; + this.appearance = fakeUnicodeFont.createAppearance(this._contents.str, this.rectangle, this.rotation, fontSize, fontColor, strokeAlpha); + this._streams.push(this.appearance, _default_appearance.FakeUnicodeFont.toUnicodeStream); + } else { + (0, _util.warn)("FreeTextAnnotation: OffscreenCanvas is not supported, annotation may not render correctly."); + } + } + get hasTextContent() { + return !!this.appearance; + } + static createNewDict(annotation, xref, { + apRef, + ap + }) { + const { + color, + fontSize, + rect, + rotation, + user, + value + } = annotation; + const freetext = new _primitives.Dict(xref); + freetext.set("Type", _primitives.Name.get("Annot")); + freetext.set("Subtype", _primitives.Name.get("FreeText")); + freetext.set("CreationDate", `D:${(0, _util.getModificationDate)()}`); + freetext.set("Rect", rect); + const da = `/Helv ${fontSize} Tf ${(0, _default_appearance.getPdfColor)(color, true)}`; + freetext.set("DA", da); + freetext.set("Contents", (0, _core_utils.isAscii)(value) ? value : (0, _core_utils.stringToUTF16String)(value, true)); + freetext.set("F", 4); + freetext.set("Border", [0, 0, 0]); + freetext.set("Rotate", rotation); + if (user) { + freetext.set("T", (0, _core_utils.isAscii)(user) ? user : (0, _core_utils.stringToUTF16String)(user, true)); + } + if (apRef || ap) { + const n = new _primitives.Dict(xref); + freetext.set("AP", n); + if (apRef) { + n.set("N", apRef); + } else { + n.set("N", ap); + } + } + return freetext; + } + static async createNewAppearanceStream(annotation, xref, params) { + const { + baseFontRef, + evaluator, + task + } = params; + const { + color, + fontSize, + rect, + rotation, + value + } = annotation; + const resources = new _primitives.Dict(xref); + const font = new _primitives.Dict(xref); + if (baseFontRef) { + font.set("Helv", baseFontRef); + } else { + const baseFont = new _primitives.Dict(xref); + baseFont.set("BaseFont", _primitives.Name.get("Helvetica")); + baseFont.set("Type", _primitives.Name.get("Font")); + baseFont.set("Subtype", _primitives.Name.get("Type1")); + baseFont.set("Encoding", _primitives.Name.get("WinAnsiEncoding")); + font.set("Helv", baseFont); + } + resources.set("Font", font); + const helv = await WidgetAnnotation._getFontData(evaluator, task, { + fontName: "Helv", + fontSize + }, resources); + const [x1, y1, x2, y2] = rect; + let w = x2 - x1; + let h = y2 - y1; + if (rotation % 180 !== 0) { + [w, h] = [h, w]; + } + const lines = value.split("\n"); + const scale = fontSize / 1000; + let totalWidth = -Infinity; + const encodedLines = []; + for (let line of lines) { + const encoded = helv.encodeString(line); + if (encoded.length > 1) { + return null; + } + line = encoded.join(""); + encodedLines.push(line); + let lineWidth = 0; + const glyphs = helv.charsToGlyphs(line); + for (const glyph of glyphs) { + lineWidth += glyph.width * scale; + } + totalWidth = Math.max(totalWidth, lineWidth); + } + let hscale = 1; + if (totalWidth > w) { + hscale = w / totalWidth; + } + let vscale = 1; + const lineHeight = _util.LINE_FACTOR * fontSize; + const lineAscent = (_util.LINE_FACTOR - _util.LINE_DESCENT_FACTOR) * fontSize; + const totalHeight = lineHeight * lines.length; + if (totalHeight > h) { + vscale = h / totalHeight; + } + const fscale = Math.min(hscale, vscale); + const newFontSize = fontSize * fscale; + let firstPoint, clipBox, matrix; + switch (rotation) { + case 0: + matrix = [1, 0, 0, 1]; + clipBox = [rect[0], rect[1], w, h]; + firstPoint = [rect[0], rect[3] - lineAscent]; + break; + case 90: + matrix = [0, 1, -1, 0]; + clipBox = [rect[1], -rect[2], w, h]; + firstPoint = [rect[1], -rect[0] - lineAscent]; + break; + case 180: + matrix = [-1, 0, 0, -1]; + clipBox = [-rect[2], -rect[3], w, h]; + firstPoint = [-rect[2], -rect[1] - lineAscent]; + break; + case 270: + matrix = [0, -1, 1, 0]; + clipBox = [-rect[3], rect[0], w, h]; + firstPoint = [-rect[3], rect[2] - lineAscent]; + break; + } + const buffer = ["q", `${matrix.join(" ")} 0 0 cm`, `${clipBox.join(" ")} re W n`, `BT`, `${(0, _default_appearance.getPdfColor)(color, true)}`, `0 Tc /Helv ${(0, _core_utils.numberToString)(newFontSize)} Tf`]; + buffer.push(`${firstPoint.join(" ")} Td (${(0, _core_utils.escapeString)(encodedLines[0])}) Tj`); + const vShift = (0, _core_utils.numberToString)(lineHeight); + for (let i = 1, ii = encodedLines.length; i < ii; i++) { + const line = encodedLines[i]; + buffer.push(`0 -${vShift} Td (${(0, _core_utils.escapeString)(line)}) Tj`); + } + buffer.push("ET", "Q"); + const appearance = buffer.join("\n"); + const appearanceStreamDict = new _primitives.Dict(xref); + appearanceStreamDict.set("FormType", 1); + appearanceStreamDict.set("Subtype", _primitives.Name.get("Form")); + appearanceStreamDict.set("Type", _primitives.Name.get("XObject")); + appearanceStreamDict.set("BBox", rect); + appearanceStreamDict.set("Resources", resources); + appearanceStreamDict.set("Matrix", [1, 0, 0, 1, -rect[0], -rect[1]]); + const ap = new _stream.StringStream(appearance); + ap.dict = appearanceStreamDict; + return ap; + } +} +class LineAnnotation extends MarkupAnnotation { + constructor(params) { + super(params); + const { + dict, + xref + } = params; + this.data.annotationType = _util.AnnotationType.LINE; + this.data.hasOwnCanvas = this.data.noRotate; + const lineCoordinates = dict.getArray("L"); + this.data.lineCoordinates = _util.Util.normalizeRect(lineCoordinates); + this.setLineEndings(dict.getArray("LE")); + this.data.lineEndings = this.lineEndings; + if (!this.appearance) { + const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0]; + const strokeAlpha = dict.get("CA"); + const interiorColor = getRgbColor(dict.getArray("IC"), null); + const fillColor = interiorColor ? getPdfColorArray(interiorColor) : null; + const fillAlpha = fillColor ? strokeAlpha : null; + const borderWidth = this.borderStyle.width || 1, + borderAdjust = 2 * borderWidth; + const bbox = [this.data.lineCoordinates[0] - borderAdjust, this.data.lineCoordinates[1] - borderAdjust, this.data.lineCoordinates[2] + borderAdjust, this.data.lineCoordinates[3] + borderAdjust]; + if (!_util.Util.intersect(this.rectangle, bbox)) { + this.rectangle = bbox; + } + this._setDefaultAppearance({ + xref, + extra: `${borderWidth} w`, + strokeColor, + fillColor, + strokeAlpha, + fillAlpha, + pointsCallback: (buffer, points) => { + buffer.push(`${lineCoordinates[0]} ${lineCoordinates[1]} m`, `${lineCoordinates[2]} ${lineCoordinates[3]} l`, "S"); + return [points[0].x - borderWidth, points[1].x + borderWidth, points[3].y - borderWidth, points[1].y + borderWidth]; + } + }); + } + } +} +class SquareAnnotation extends MarkupAnnotation { + constructor(params) { + super(params); + const { + dict, + xref + } = params; + this.data.annotationType = _util.AnnotationType.SQUARE; + this.data.hasOwnCanvas = this.data.noRotate; + if (!this.appearance) { + const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0]; + const strokeAlpha = dict.get("CA"); + const interiorColor = getRgbColor(dict.getArray("IC"), null); + const fillColor = interiorColor ? getPdfColorArray(interiorColor) : null; + const fillAlpha = fillColor ? strokeAlpha : null; + if (this.borderStyle.width === 0 && !fillColor) { + return; + } + this._setDefaultAppearance({ + xref, + extra: `${this.borderStyle.width} w`, + strokeColor, + fillColor, + strokeAlpha, + fillAlpha, + pointsCallback: (buffer, points) => { + const x = points[2].x + this.borderStyle.width / 2; + const y = points[2].y + this.borderStyle.width / 2; + const width = points[3].x - points[2].x - this.borderStyle.width; + const height = points[1].y - points[3].y - this.borderStyle.width; + buffer.push(`${x} ${y} ${width} ${height} re`); + if (fillColor) { + buffer.push("B"); + } else { + buffer.push("S"); + } + return [points[0].x, points[1].x, points[3].y, points[1].y]; + } + }); + } + } +} +class CircleAnnotation extends MarkupAnnotation { + constructor(params) { + super(params); + const { + dict, + xref + } = params; + this.data.annotationType = _util.AnnotationType.CIRCLE; + if (!this.appearance) { + const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0]; + const strokeAlpha = dict.get("CA"); + const interiorColor = getRgbColor(dict.getArray("IC"), null); + const fillColor = interiorColor ? getPdfColorArray(interiorColor) : null; + const fillAlpha = fillColor ? strokeAlpha : null; + if (this.borderStyle.width === 0 && !fillColor) { + return; + } + const controlPointsDistance = 4 / 3 * Math.tan(Math.PI / (2 * 4)); + this._setDefaultAppearance({ + xref, + extra: `${this.borderStyle.width} w`, + strokeColor, + fillColor, + strokeAlpha, + fillAlpha, + pointsCallback: (buffer, points) => { + const x0 = points[0].x + this.borderStyle.width / 2; + const y0 = points[0].y - this.borderStyle.width / 2; + const x1 = points[3].x - this.borderStyle.width / 2; + const y1 = points[3].y + this.borderStyle.width / 2; + const xMid = x0 + (x1 - x0) / 2; + const yMid = y0 + (y1 - y0) / 2; + const xOffset = (x1 - x0) / 2 * controlPointsDistance; + const yOffset = (y1 - y0) / 2 * controlPointsDistance; + buffer.push(`${xMid} ${y1} m`, `${xMid + xOffset} ${y1} ${x1} ${yMid + yOffset} ${x1} ${yMid} c`, `${x1} ${yMid - yOffset} ${xMid + xOffset} ${y0} ${xMid} ${y0} c`, `${xMid - xOffset} ${y0} ${x0} ${yMid - yOffset} ${x0} ${yMid} c`, `${x0} ${yMid + yOffset} ${xMid - xOffset} ${y1} ${xMid} ${y1} c`, "h"); + if (fillColor) { + buffer.push("B"); + } else { + buffer.push("S"); + } + return [points[0].x, points[1].x, points[3].y, points[1].y]; + } + }); + } + } +} +class PolylineAnnotation extends MarkupAnnotation { + constructor(params) { + super(params); + const { + dict, + xref + } = params; + this.data.annotationType = _util.AnnotationType.POLYLINE; + this.data.hasOwnCanvas = this.data.noRotate; + this.data.vertices = []; + if (!(this instanceof PolygonAnnotation)) { + this.setLineEndings(dict.getArray("LE")); + this.data.lineEndings = this.lineEndings; + } + const rawVertices = dict.getArray("Vertices"); + if (!Array.isArray(rawVertices)) { + return; + } + for (let i = 0, ii = rawVertices.length; i < ii; i += 2) { + this.data.vertices.push({ + x: rawVertices[i], + y: rawVertices[i + 1] + }); + } + if (!this.appearance) { + const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0]; + const strokeAlpha = dict.get("CA"); + const borderWidth = this.borderStyle.width || 1, + borderAdjust = 2 * borderWidth; + const bbox = [Infinity, Infinity, -Infinity, -Infinity]; + for (const vertex of this.data.vertices) { + bbox[0] = Math.min(bbox[0], vertex.x - borderAdjust); + bbox[1] = Math.min(bbox[1], vertex.y - borderAdjust); + bbox[2] = Math.max(bbox[2], vertex.x + borderAdjust); + bbox[3] = Math.max(bbox[3], vertex.y + borderAdjust); + } + if (!_util.Util.intersect(this.rectangle, bbox)) { + this.rectangle = bbox; + } + this._setDefaultAppearance({ + xref, + extra: `${borderWidth} w`, + strokeColor, + strokeAlpha, + pointsCallback: (buffer, points) => { + const vertices = this.data.vertices; + for (let i = 0, ii = vertices.length; i < ii; i++) { + buffer.push(`${vertices[i].x} ${vertices[i].y} ${i === 0 ? "m" : "l"}`); + } + buffer.push("S"); + return [points[0].x, points[1].x, points[3].y, points[1].y]; + } + }); + } + } +} +class PolygonAnnotation extends PolylineAnnotation { + constructor(params) { + super(params); + this.data.annotationType = _util.AnnotationType.POLYGON; + } +} +class CaretAnnotation extends MarkupAnnotation { + constructor(params) { + super(params); + this.data.annotationType = _util.AnnotationType.CARET; + } +} +class InkAnnotation extends MarkupAnnotation { + constructor(params) { + super(params); + this.data.hasOwnCanvas = this.data.noRotate; + const { + dict, + xref + } = params; + this.data.annotationType = _util.AnnotationType.INK; + this.data.inkLists = []; + const rawInkLists = dict.getArray("InkList"); + if (!Array.isArray(rawInkLists)) { + return; + } + for (let i = 0, ii = rawInkLists.length; i < ii; ++i) { + this.data.inkLists.push([]); + for (let j = 0, jj = rawInkLists[i].length; j < jj; j += 2) { + this.data.inkLists[i].push({ + x: xref.fetchIfRef(rawInkLists[i][j]), + y: xref.fetchIfRef(rawInkLists[i][j + 1]) + }); + } + } + if (!this.appearance) { + const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0]; + const strokeAlpha = dict.get("CA"); + const borderWidth = this.borderStyle.width || 1, + borderAdjust = 2 * borderWidth; + const bbox = [Infinity, Infinity, -Infinity, -Infinity]; + for (const inkLists of this.data.inkLists) { + for (const vertex of inkLists) { + bbox[0] = Math.min(bbox[0], vertex.x - borderAdjust); + bbox[1] = Math.min(bbox[1], vertex.y - borderAdjust); + bbox[2] = Math.max(bbox[2], vertex.x + borderAdjust); + bbox[3] = Math.max(bbox[3], vertex.y + borderAdjust); + } + } + if (!_util.Util.intersect(this.rectangle, bbox)) { + this.rectangle = bbox; + } + this._setDefaultAppearance({ + xref, + extra: `${borderWidth} w`, + strokeColor, + strokeAlpha, + pointsCallback: (buffer, points) => { + for (const inkList of this.data.inkLists) { + for (let i = 0, ii = inkList.length; i < ii; i++) { + buffer.push(`${inkList[i].x} ${inkList[i].y} ${i === 0 ? "m" : "l"}`); + } + buffer.push("S"); + } + return [points[0].x, points[1].x, points[3].y, points[1].y]; + } + }); + } + } + static createNewDict(annotation, xref, { + apRef, + ap + }) { + const { + color, + opacity, + paths, + rect, + rotation, + thickness + } = annotation; + const ink = new _primitives.Dict(xref); + ink.set("Type", _primitives.Name.get("Annot")); + ink.set("Subtype", _primitives.Name.get("Ink")); + ink.set("CreationDate", `D:${(0, _util.getModificationDate)()}`); + ink.set("Rect", rect); + ink.set("InkList", paths.map(p => p.points)); + ink.set("F", 4); + ink.set("Rotate", rotation); + const bs = new _primitives.Dict(xref); + ink.set("BS", bs); + bs.set("W", thickness); + ink.set("C", Array.from(color, c => c / 255)); + ink.set("CA", opacity); + const n = new _primitives.Dict(xref); + ink.set("AP", n); + if (apRef) { + n.set("N", apRef); + } else { + n.set("N", ap); + } + return ink; + } + static async createNewAppearanceStream(annotation, xref, params) { + const { + color, + rect, + paths, + thickness, + opacity + } = annotation; + const appearanceBuffer = [`${thickness} w 1 J 1 j`, `${(0, _default_appearance.getPdfColor)(color, false)}`]; + if (opacity !== 1) { + appearanceBuffer.push("/R0 gs"); + } + const buffer = []; + for (const { + bezier + } of paths) { + buffer.length = 0; + buffer.push(`${(0, _core_utils.numberToString)(bezier[0])} ${(0, _core_utils.numberToString)(bezier[1])} m`); + for (let i = 2, ii = bezier.length; i < ii; i += 6) { + const curve = bezier.slice(i, i + 6).map(_core_utils.numberToString).join(" "); + buffer.push(`${curve} c`); + } + buffer.push("S"); + appearanceBuffer.push(buffer.join("\n")); + } + const appearance = appearanceBuffer.join("\n"); + const appearanceStreamDict = new _primitives.Dict(xref); + appearanceStreamDict.set("FormType", 1); + appearanceStreamDict.set("Subtype", _primitives.Name.get("Form")); + appearanceStreamDict.set("Type", _primitives.Name.get("XObject")); + appearanceStreamDict.set("BBox", rect); + appearanceStreamDict.set("Length", appearance.length); + if (opacity !== 1) { + const resources = new _primitives.Dict(xref); + const extGState = new _primitives.Dict(xref); + const r0 = new _primitives.Dict(xref); + r0.set("CA", opacity); + r0.set("Type", _primitives.Name.get("ExtGState")); + extGState.set("R0", r0); + resources.set("ExtGState", extGState); + appearanceStreamDict.set("Resources", resources); + } + const ap = new _stream.StringStream(appearance); + ap.dict = appearanceStreamDict; + return ap; + } +} +class HighlightAnnotation extends MarkupAnnotation { + constructor(params) { + super(params); + const { + dict, + xref + } = params; + this.data.annotationType = _util.AnnotationType.HIGHLIGHT; + const quadPoints = this.data.quadPoints = getQuadPoints(dict, null); + if (quadPoints) { + const resources = this.appearance?.dict.get("Resources"); + if (!this.appearance || !resources?.has("ExtGState")) { + if (this.appearance) { + (0, _util.warn)("HighlightAnnotation - ignoring built-in appearance stream."); + } + const fillColor = this.color ? getPdfColorArray(this.color) : [1, 1, 0]; + const fillAlpha = dict.get("CA"); + this._setDefaultAppearance({ + xref, + fillColor, + blendMode: "Multiply", + fillAlpha, + pointsCallback: (buffer, points) => { + buffer.push(`${points[0].x} ${points[0].y} m`, `${points[1].x} ${points[1].y} l`, `${points[3].x} ${points[3].y} l`, `${points[2].x} ${points[2].y} l`, "f"); + return [points[0].x, points[1].x, points[3].y, points[1].y]; + } + }); + } + } else { + this.data.popupRef = null; + } + } +} +class UnderlineAnnotation extends MarkupAnnotation { + constructor(params) { + super(params); + const { + dict, + xref + } = params; + this.data.annotationType = _util.AnnotationType.UNDERLINE; + const quadPoints = this.data.quadPoints = getQuadPoints(dict, null); + if (quadPoints) { + if (!this.appearance) { + const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0]; + const strokeAlpha = dict.get("CA"); + this._setDefaultAppearance({ + xref, + extra: "[] 0 d 0.571 w", + strokeColor, + strokeAlpha, + pointsCallback: (buffer, points) => { + buffer.push(`${points[2].x} ${points[2].y + 1.3} m`, `${points[3].x} ${points[3].y + 1.3} l`, "S"); + return [points[0].x, points[1].x, points[3].y, points[1].y]; + } + }); + } + } else { + this.data.popupRef = null; + } + } +} +class SquigglyAnnotation extends MarkupAnnotation { + constructor(params) { + super(params); + const { + dict, + xref + } = params; + this.data.annotationType = _util.AnnotationType.SQUIGGLY; + const quadPoints = this.data.quadPoints = getQuadPoints(dict, null); + if (quadPoints) { + if (!this.appearance) { + const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0]; + const strokeAlpha = dict.get("CA"); + this._setDefaultAppearance({ + xref, + extra: "[] 0 d 1 w", + strokeColor, + strokeAlpha, + pointsCallback: (buffer, points) => { + const dy = (points[0].y - points[2].y) / 6; + let shift = dy; + let x = points[2].x; + const y = points[2].y; + const xEnd = points[3].x; + buffer.push(`${x} ${y + shift} m`); + do { + x += 2; + shift = shift === 0 ? dy : 0; + buffer.push(`${x} ${y + shift} l`); + } while (x < xEnd); + buffer.push("S"); + return [points[2].x, xEnd, y - 2 * dy, y + 2 * dy]; + } + }); + } + } else { + this.data.popupRef = null; + } + } +} +class StrikeOutAnnotation extends MarkupAnnotation { + constructor(params) { + super(params); + const { + dict, + xref + } = params; + this.data.annotationType = _util.AnnotationType.STRIKEOUT; + const quadPoints = this.data.quadPoints = getQuadPoints(dict, null); + if (quadPoints) { + if (!this.appearance) { + const strokeColor = this.color ? getPdfColorArray(this.color) : [0, 0, 0]; + const strokeAlpha = dict.get("CA"); + this._setDefaultAppearance({ + xref, + extra: "[] 0 d 1 w", + strokeColor, + strokeAlpha, + pointsCallback: (buffer, points) => { + buffer.push(`${(points[0].x + points[2].x) / 2} ` + `${(points[0].y + points[2].y) / 2} m`, `${(points[1].x + points[3].x) / 2} ` + `${(points[1].y + points[3].y) / 2} l`, "S"); + return [points[0].x, points[1].x, points[3].y, points[1].y]; + } + }); + } + } else { + this.data.popupRef = null; + } + } +} +class StampAnnotation extends MarkupAnnotation { + constructor(params) { + super(params); + this.data.annotationType = _util.AnnotationType.STAMP; + this.data.hasOwnCanvas = this.data.noRotate; + } + static async createImage(bitmap, xref) { + const { + width, + height + } = bitmap; + const canvas = new OffscreenCanvas(width, height); + const ctx = canvas.getContext("2d", { + alpha: true + }); + ctx.drawImage(bitmap, 0, 0); + const data = ctx.getImageData(0, 0, width, height).data; + const buf32 = new Uint32Array(data.buffer); + const hasAlpha = buf32.some(_util.FeatureTest.isLittleEndian ? x => x >>> 24 !== 0xff : x => (x & 0xff) !== 0xff); + if (hasAlpha) { + ctx.fillStyle = "white"; + ctx.fillRect(0, 0, width, height); + ctx.drawImage(bitmap, 0, 0); + } + const jpegBufferPromise = canvas.convertToBlob({ + type: "image/jpeg", + quality: 1 + }).then(blob => { + return blob.arrayBuffer(); + }); + const xobjectName = _primitives.Name.get("XObject"); + const imageName = _primitives.Name.get("Image"); + const image = new _primitives.Dict(xref); + image.set("Type", xobjectName); + image.set("Subtype", imageName); + image.set("BitsPerComponent", 8); + image.set("ColorSpace", _primitives.Name.get("DeviceRGB")); + image.set("Filter", _primitives.Name.get("DCTDecode")); + image.set("BBox", [0, 0, width, height]); + image.set("Width", width); + image.set("Height", height); + let smaskStream = null; + if (hasAlpha) { + const alphaBuffer = new Uint8Array(buf32.length); + if (_util.FeatureTest.isLittleEndian) { + for (let i = 0, ii = buf32.length; i < ii; i++) { + alphaBuffer[i] = buf32[i] >>> 24; + } + } else { + for (let i = 0, ii = buf32.length; i < ii; i++) { + alphaBuffer[i] = buf32[i] & 0xff; + } + } + const smask = new _primitives.Dict(xref); + smask.set("Type", xobjectName); + smask.set("Subtype", imageName); + smask.set("BitsPerComponent", 8); + smask.set("ColorSpace", _primitives.Name.get("DeviceGray")); + smask.set("Width", width); + smask.set("Height", height); + smaskStream = new _stream.Stream(alphaBuffer, 0, 0, smask); + } + const imageStream = new _stream.Stream(await jpegBufferPromise, 0, 0, image); + return { + imageStream, + smaskStream, + width, + height + }; + } + static createNewDict(annotation, xref, { + apRef, + ap + }) { + const { + rect, + rotation, + user + } = annotation; + const stamp = new _primitives.Dict(xref); + stamp.set("Type", _primitives.Name.get("Annot")); + stamp.set("Subtype", _primitives.Name.get("Stamp")); + stamp.set("CreationDate", `D:${(0, _util.getModificationDate)()}`); + stamp.set("Rect", rect); + stamp.set("F", 4); + stamp.set("Border", [0, 0, 0]); + stamp.set("Rotate", rotation); + if (user) { + stamp.set("T", (0, _core_utils.isAscii)(user) ? user : (0, _core_utils.stringToUTF16String)(user, true)); + } + if (apRef || ap) { + const n = new _primitives.Dict(xref); + stamp.set("AP", n); + if (apRef) { + n.set("N", apRef); + } else { + n.set("N", ap); + } + } + return stamp; + } + static async createNewAppearanceStream(annotation, xref, params) { + const { + rotation + } = annotation; + const { + imageRef, + width, + height + } = params.image; + const resources = new _primitives.Dict(xref); + const xobject = new _primitives.Dict(xref); + resources.set("XObject", xobject); + xobject.set("Im0", imageRef); + const appearance = `q ${width} 0 0 ${height} 0 0 cm /Im0 Do Q`; + const appearanceStreamDict = new _primitives.Dict(xref); + appearanceStreamDict.set("FormType", 1); + appearanceStreamDict.set("Subtype", _primitives.Name.get("Form")); + appearanceStreamDict.set("Type", _primitives.Name.get("XObject")); + appearanceStreamDict.set("BBox", [0, 0, width, height]); + appearanceStreamDict.set("Resources", resources); + if (rotation) { + const matrix = (0, _core_utils.getRotationMatrix)(rotation, width, height); + appearanceStreamDict.set("Matrix", matrix); + } + const ap = new _stream.StringStream(appearance); + ap.dict = appearanceStreamDict; + return ap; + } +} +class FileAttachmentAnnotation extends MarkupAnnotation { + constructor(params) { + super(params); + const { + dict, + xref + } = params; + const file = new _file_spec.FileSpec(dict.get("FS"), xref); + this.data.annotationType = _util.AnnotationType.FILEATTACHMENT; + this.data.hasOwnCanvas = this.data.noRotate; + this.data.file = file.serializable; + const name = dict.get("Name"); + this.data.name = name instanceof _primitives.Name ? (0, _util.stringToPDFString)(name.name) : "PushPin"; + const fillAlpha = dict.get("ca"); + this.data.fillAlpha = typeof fillAlpha === "number" && fillAlpha >= 0 && fillAlpha <= 1 ? fillAlpha : null; + } +} + +/***/ }), +/* 11 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.FakeUnicodeFont = void 0; +exports.createDefaultAppearance = createDefaultAppearance; +exports.getPdfColor = getPdfColor; +exports.parseAppearanceStream = parseAppearanceStream; +exports.parseDefaultAppearance = parseDefaultAppearance; +var _primitives = __w_pdfjs_require__(4); +var _core_utils = __w_pdfjs_require__(3); +var _util = __w_pdfjs_require__(2); +var _colorspace = __w_pdfjs_require__(12); +var _evaluator = __w_pdfjs_require__(13); +var _image_utils = __w_pdfjs_require__(59); +var _function = __w_pdfjs_require__(57); +var _stream = __w_pdfjs_require__(8); +class DefaultAppearanceEvaluator extends _evaluator.EvaluatorPreprocessor { + constructor(str) { + super(new _stream.StringStream(str)); + } + parse() { + const operation = { + fn: 0, + args: [] + }; + const result = { + fontSize: 0, + fontName: "", + fontColor: new Uint8ClampedArray(3) + }; + try { + while (true) { + operation.args.length = 0; + if (!this.read(operation)) { + break; + } + if (this.savedStatesDepth !== 0) { + continue; + } + const { + fn, + args + } = operation; + switch (fn | 0) { + case _util.OPS.setFont: + const [fontName, fontSize] = args; + if (fontName instanceof _primitives.Name) { + result.fontName = fontName.name; + } + if (typeof fontSize === "number" && fontSize > 0) { + result.fontSize = fontSize; + } + break; + case _util.OPS.setFillRGBColor: + _colorspace.ColorSpace.singletons.rgb.getRgbItem(args, 0, result.fontColor, 0); + break; + case _util.OPS.setFillGray: + _colorspace.ColorSpace.singletons.gray.getRgbItem(args, 0, result.fontColor, 0); + break; + case _util.OPS.setFillCMYKColor: + _colorspace.ColorSpace.singletons.cmyk.getRgbItem(args, 0, result.fontColor, 0); + break; + } + } + } catch (reason) { + (0, _util.warn)(`parseDefaultAppearance - ignoring errors: "${reason}".`); + } + return result; + } +} +function parseDefaultAppearance(str) { + return new DefaultAppearanceEvaluator(str).parse(); +} +class AppearanceStreamEvaluator extends _evaluator.EvaluatorPreprocessor { + constructor(stream, evaluatorOptions, xref) { + super(stream); + this.stream = stream; + this.evaluatorOptions = evaluatorOptions; + this.xref = xref; + this.resources = stream.dict?.get("Resources"); + } + parse() { + const operation = { + fn: 0, + args: [] + }; + let result = { + scaleFactor: 1, + fontSize: 0, + fontName: "", + fontColor: new Uint8ClampedArray(3), + fillColorSpace: _colorspace.ColorSpace.singletons.gray + }; + let breakLoop = false; + const stack = []; + try { + while (true) { + operation.args.length = 0; + if (breakLoop || !this.read(operation)) { + break; + } + const { + fn, + args + } = operation; + switch (fn | 0) { + case _util.OPS.save: + stack.push({ + scaleFactor: result.scaleFactor, + fontSize: result.fontSize, + fontName: result.fontName, + fontColor: result.fontColor.slice(), + fillColorSpace: result.fillColorSpace + }); + break; + case _util.OPS.restore: + result = stack.pop() || result; + break; + case _util.OPS.setTextMatrix: + result.scaleFactor *= Math.hypot(args[0], args[1]); + break; + case _util.OPS.setFont: + const [fontName, fontSize] = args; + if (fontName instanceof _primitives.Name) { + result.fontName = fontName.name; + } + if (typeof fontSize === "number" && fontSize > 0) { + result.fontSize = fontSize * result.scaleFactor; + } + break; + case _util.OPS.setFillColorSpace: + result.fillColorSpace = _colorspace.ColorSpace.parse({ + cs: args[0], + xref: this.xref, + resources: this.resources, + pdfFunctionFactory: this._pdfFunctionFactory, + localColorSpaceCache: this._localColorSpaceCache + }); + break; + case _util.OPS.setFillColor: + const cs = result.fillColorSpace; + cs.getRgbItem(args, 0, result.fontColor, 0); + break; + case _util.OPS.setFillRGBColor: + _colorspace.ColorSpace.singletons.rgb.getRgbItem(args, 0, result.fontColor, 0); + break; + case _util.OPS.setFillGray: + _colorspace.ColorSpace.singletons.gray.getRgbItem(args, 0, result.fontColor, 0); + break; + case _util.OPS.setFillCMYKColor: + _colorspace.ColorSpace.singletons.cmyk.getRgbItem(args, 0, result.fontColor, 0); + break; + case _util.OPS.showText: + case _util.OPS.showSpacedText: + case _util.OPS.nextLineShowText: + case _util.OPS.nextLineSetSpacingShowText: + breakLoop = true; + break; + } + } + } catch (reason) { + (0, _util.warn)(`parseAppearanceStream - ignoring errors: "${reason}".`); + } + this.stream.reset(); + delete result.scaleFactor; + delete result.fillColorSpace; + return result; + } + get _localColorSpaceCache() { + return (0, _util.shadow)(this, "_localColorSpaceCache", new _image_utils.LocalColorSpaceCache()); + } + get _pdfFunctionFactory() { + const pdfFunctionFactory = new _function.PDFFunctionFactory({ + xref: this.xref, + isEvalSupported: this.evaluatorOptions.isEvalSupported + }); + return (0, _util.shadow)(this, "_pdfFunctionFactory", pdfFunctionFactory); + } +} +function parseAppearanceStream(stream, evaluatorOptions, xref) { + return new AppearanceStreamEvaluator(stream, evaluatorOptions, xref).parse(); +} +function getPdfColor(color, isFill) { + if (color[0] === color[1] && color[1] === color[2]) { + const gray = color[0] / 255; + return `${(0, _core_utils.numberToString)(gray)} ${isFill ? "g" : "G"}`; + } + return Array.from(color, c => (0, _core_utils.numberToString)(c / 255)).join(" ") + ` ${isFill ? "rg" : "RG"}`; +} +function createDefaultAppearance({ + fontSize, + fontName, + fontColor +}) { + return `/${(0, _core_utils.escapePDFName)(fontName)} ${fontSize} Tf ${getPdfColor(fontColor, true)}`; +} +class FakeUnicodeFont { + constructor(xref, fontFamily) { + this.xref = xref; + this.widths = null; + this.firstChar = Infinity; + this.lastChar = -Infinity; + this.fontFamily = fontFamily; + const canvas = new OffscreenCanvas(1, 1); + this.ctxMeasure = canvas.getContext("2d"); + if (!FakeUnicodeFont._fontNameId) { + FakeUnicodeFont._fontNameId = 1; + } + this.fontName = _primitives.Name.get(`InvalidPDFjsFont_${fontFamily}_${FakeUnicodeFont._fontNameId++}`); + } + get toUnicodeRef() { + if (!FakeUnicodeFont._toUnicodeRef) { + const toUnicode = `/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (Adobe) +/Ordering (UCS) /Supplement 0 >> def +/CMapName /Adobe-Identity-UCS def +/CMapType 2 def +1 begincodespacerange +<0000> +endcodespacerange +1 beginbfrange +<0000> <0000> +endbfrange +endcmap CMapName currentdict /CMap defineresource pop end end`; + const toUnicodeStream = FakeUnicodeFont.toUnicodeStream = new _stream.StringStream(toUnicode); + const toUnicodeDict = new _primitives.Dict(this.xref); + toUnicodeStream.dict = toUnicodeDict; + toUnicodeDict.set("Length", toUnicode.length); + FakeUnicodeFont._toUnicodeRef = this.xref.getNewPersistentRef(toUnicodeStream); + } + return FakeUnicodeFont._toUnicodeRef; + } + get fontDescriptorRef() { + if (!FakeUnicodeFont._fontDescriptorRef) { + const fontDescriptor = new _primitives.Dict(this.xref); + fontDescriptor.set("Type", _primitives.Name.get("FontDescriptor")); + fontDescriptor.set("FontName", this.fontName); + fontDescriptor.set("FontFamily", "MyriadPro Regular"); + fontDescriptor.set("FontBBox", [0, 0, 0, 0]); + fontDescriptor.set("FontStretch", _primitives.Name.get("Normal")); + fontDescriptor.set("FontWeight", 400); + fontDescriptor.set("ItalicAngle", 0); + FakeUnicodeFont._fontDescriptorRef = this.xref.getNewPersistentRef(fontDescriptor); + } + return FakeUnicodeFont._fontDescriptorRef; + } + get descendantFontRef() { + const descendantFont = new _primitives.Dict(this.xref); + descendantFont.set("BaseFont", this.fontName); + descendantFont.set("Type", _primitives.Name.get("Font")); + descendantFont.set("Subtype", _primitives.Name.get("CIDFontType0")); + descendantFont.set("CIDToGIDMap", _primitives.Name.get("Identity")); + descendantFont.set("FirstChar", this.firstChar); + descendantFont.set("LastChar", this.lastChar); + descendantFont.set("FontDescriptor", this.fontDescriptorRef); + descendantFont.set("DW", 1000); + const widths = []; + const chars = [...this.widths.entries()].sort(); + let currentChar = null; + let currentWidths = null; + for (const [char, width] of chars) { + if (!currentChar) { + currentChar = char; + currentWidths = [width]; + continue; + } + if (char === currentChar + currentWidths.length) { + currentWidths.push(width); + } else { + widths.push(currentChar, currentWidths); + currentChar = char; + currentWidths = [width]; + } + } + if (currentChar) { + widths.push(currentChar, currentWidths); + } + descendantFont.set("W", widths); + const cidSystemInfo = new _primitives.Dict(this.xref); + cidSystemInfo.set("Ordering", "Identity"); + cidSystemInfo.set("Registry", "Adobe"); + cidSystemInfo.set("Supplement", 0); + descendantFont.set("CIDSystemInfo", cidSystemInfo); + return this.xref.getNewPersistentRef(descendantFont); + } + get baseFontRef() { + const baseFont = new _primitives.Dict(this.xref); + baseFont.set("BaseFont", this.fontName); + baseFont.set("Type", _primitives.Name.get("Font")); + baseFont.set("Subtype", _primitives.Name.get("Type0")); + baseFont.set("Encoding", _primitives.Name.get("Identity-H")); + baseFont.set("DescendantFonts", [this.descendantFontRef]); + baseFont.set("ToUnicode", this.toUnicodeRef); + return this.xref.getNewPersistentRef(baseFont); + } + get resources() { + const resources = new _primitives.Dict(this.xref); + const font = new _primitives.Dict(this.xref); + font.set(this.fontName.name, this.baseFontRef); + resources.set("Font", font); + return resources; + } + _createContext() { + this.widths = new Map(); + this.ctxMeasure.font = `1000px ${this.fontFamily}`; + return this.ctxMeasure; + } + createFontResources(text) { + const ctx = this._createContext(); + for (const line of text.split(/\r\n?|\n/)) { + for (const char of line.split("")) { + const code = char.charCodeAt(0); + if (this.widths.has(code)) { + continue; + } + const metrics = ctx.measureText(char); + const width = Math.ceil(metrics.width); + this.widths.set(code, width); + this.firstChar = Math.min(code, this.firstChar); + this.lastChar = Math.max(code, this.lastChar); + } + } + return this.resources; + } + createAppearance(text, rect, rotation, fontSize, bgColor, strokeAlpha) { + const ctx = this._createContext(); + const lines = []; + let maxWidth = -Infinity; + for (const line of text.split(/\r\n?|\n/)) { + lines.push(line); + const lineWidth = ctx.measureText(line).width; + maxWidth = Math.max(maxWidth, lineWidth); + for (const char of line.split("")) { + const code = char.charCodeAt(0); + let width = this.widths.get(code); + if (width === undefined) { + const metrics = ctx.measureText(char); + width = Math.ceil(metrics.width); + this.widths.set(code, width); + this.firstChar = Math.min(code, this.firstChar); + this.lastChar = Math.max(code, this.lastChar); + } + } + } + maxWidth *= fontSize / 1000; + const [x1, y1, x2, y2] = rect; + let w = x2 - x1; + let h = y2 - y1; + if (rotation % 180 !== 0) { + [w, h] = [h, w]; + } + let hscale = 1; + if (maxWidth > w) { + hscale = w / maxWidth; + } + let vscale = 1; + const lineHeight = _util.LINE_FACTOR * fontSize; + const lineDescent = _util.LINE_DESCENT_FACTOR * fontSize; + const maxHeight = lineHeight * lines.length; + if (maxHeight > h) { + vscale = h / maxHeight; + } + const fscale = Math.min(hscale, vscale); + const newFontSize = fontSize * fscale; + const buffer = ["q", `0 0 ${(0, _core_utils.numberToString)(w)} ${(0, _core_utils.numberToString)(h)} re W n`, `BT`, `1 0 0 1 0 ${(0, _core_utils.numberToString)(h + lineDescent)} Tm 0 Tc ${getPdfColor(bgColor, true)}`, `/${this.fontName.name} ${(0, _core_utils.numberToString)(newFontSize)} Tf`]; + const { + resources + } = this; + strokeAlpha = typeof strokeAlpha === "number" && strokeAlpha >= 0 && strokeAlpha <= 1 ? strokeAlpha : 1; + if (strokeAlpha !== 1) { + buffer.push("/R0 gs"); + const extGState = new _primitives.Dict(this.xref); + const r0 = new _primitives.Dict(this.xref); + r0.set("ca", strokeAlpha); + r0.set("CA", strokeAlpha); + r0.set("Type", _primitives.Name.get("ExtGState")); + extGState.set("R0", r0); + resources.set("ExtGState", extGState); + } + const vShift = (0, _core_utils.numberToString)(lineHeight); + for (const line of lines) { + buffer.push(`0 -${vShift} Td <${(0, _core_utils.stringToUTF16HexString)(line)}> Tj`); + } + buffer.push("ET", "Q"); + const appearance = buffer.join("\n"); + const appearanceStreamDict = new _primitives.Dict(this.xref); + appearanceStreamDict.set("Subtype", _primitives.Name.get("Form")); + appearanceStreamDict.set("Type", _primitives.Name.get("XObject")); + appearanceStreamDict.set("BBox", [0, 0, w, h]); + appearanceStreamDict.set("Length", appearance.length); + appearanceStreamDict.set("Resources", resources); + if (rotation) { + const matrix = (0, _core_utils.getRotationMatrix)(rotation, w, h); + appearanceStreamDict.set("Matrix", matrix); + } + const ap = new _stream.StringStream(appearance); + ap.dict = appearanceStreamDict; + return ap; + } +} +exports.FakeUnicodeFont = FakeUnicodeFont; + +/***/ }), +/* 12 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ColorSpace = void 0; +var _util = __w_pdfjs_require__(2); +var _primitives = __w_pdfjs_require__(4); +var _base_stream = __w_pdfjs_require__(5); +var _core_utils = __w_pdfjs_require__(3); +function resizeRgbImage(src, dest, w1, h1, w2, h2, alpha01) { + const COMPONENTS = 3; + alpha01 = alpha01 !== 1 ? 0 : alpha01; + const xRatio = w1 / w2; + const yRatio = h1 / h2; + let newIndex = 0, + oldIndex; + const xScaled = new Uint16Array(w2); + const w1Scanline = w1 * COMPONENTS; + for (let i = 0; i < w2; i++) { + xScaled[i] = Math.floor(i * xRatio) * COMPONENTS; + } + for (let i = 0; i < h2; i++) { + const py = Math.floor(i * yRatio) * w1Scanline; + for (let j = 0; j < w2; j++) { + oldIndex = py + xScaled[j]; + dest[newIndex++] = src[oldIndex++]; + dest[newIndex++] = src[oldIndex++]; + dest[newIndex++] = src[oldIndex++]; + newIndex += alpha01; + } + } +} +class ColorSpace { + constructor(name, numComps) { + if (this.constructor === ColorSpace) { + (0, _util.unreachable)("Cannot initialize ColorSpace."); + } + this.name = name; + this.numComps = numComps; + } + getRgb(src, srcOffset) { + const rgb = new Uint8ClampedArray(3); + this.getRgbItem(src, srcOffset, rgb, 0); + return rgb; + } + getRgbItem(src, srcOffset, dest, destOffset) { + (0, _util.unreachable)("Should not call ColorSpace.getRgbItem"); + } + getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) { + (0, _util.unreachable)("Should not call ColorSpace.getRgbBuffer"); + } + getOutputLength(inputLength, alpha01) { + (0, _util.unreachable)("Should not call ColorSpace.getOutputLength"); + } + isPassthrough(bits) { + return false; + } + isDefaultDecode(decodeMap, bpc) { + return ColorSpace.isDefaultDecode(decodeMap, this.numComps); + } + fillRgb(dest, originalWidth, originalHeight, width, height, actualHeight, bpc, comps, alpha01) { + const count = originalWidth * originalHeight; + let rgbBuf = null; + const numComponentColors = 1 << bpc; + const needsResizing = originalHeight !== height || originalWidth !== width; + if (this.isPassthrough(bpc)) { + rgbBuf = comps; + } else if (this.numComps === 1 && count > numComponentColors && this.name !== "DeviceGray" && this.name !== "DeviceRGB") { + const allColors = bpc <= 8 ? new Uint8Array(numComponentColors) : new Uint16Array(numComponentColors); + for (let i = 0; i < numComponentColors; i++) { + allColors[i] = i; + } + const colorMap = new Uint8ClampedArray(numComponentColors * 3); + this.getRgbBuffer(allColors, 0, numComponentColors, colorMap, 0, bpc, 0); + if (!needsResizing) { + let destPos = 0; + for (let i = 0; i < count; ++i) { + const key = comps[i] * 3; + dest[destPos++] = colorMap[key]; + dest[destPos++] = colorMap[key + 1]; + dest[destPos++] = colorMap[key + 2]; + destPos += alpha01; + } + } else { + rgbBuf = new Uint8Array(count * 3); + let rgbPos = 0; + for (let i = 0; i < count; ++i) { + const key = comps[i] * 3; + rgbBuf[rgbPos++] = colorMap[key]; + rgbBuf[rgbPos++] = colorMap[key + 1]; + rgbBuf[rgbPos++] = colorMap[key + 2]; + } + } + } else if (!needsResizing) { + this.getRgbBuffer(comps, 0, width * actualHeight, dest, 0, bpc, alpha01); + } else { + rgbBuf = new Uint8ClampedArray(count * 3); + this.getRgbBuffer(comps, 0, count, rgbBuf, 0, bpc, 0); + } + if (rgbBuf) { + if (needsResizing) { + resizeRgbImage(rgbBuf, dest, originalWidth, originalHeight, width, height, alpha01); + } else { + let destPos = 0, + rgbPos = 0; + for (let i = 0, ii = width * actualHeight; i < ii; i++) { + dest[destPos++] = rgbBuf[rgbPos++]; + dest[destPos++] = rgbBuf[rgbPos++]; + dest[destPos++] = rgbBuf[rgbPos++]; + destPos += alpha01; + } + } + } + } + get usesZeroToOneRange() { + return (0, _util.shadow)(this, "usesZeroToOneRange", true); + } + static _cache(cacheKey, xref, localColorSpaceCache, parsedColorSpace) { + if (!localColorSpaceCache) { + throw new Error('ColorSpace._cache - expected "localColorSpaceCache" argument.'); + } + if (!parsedColorSpace) { + throw new Error('ColorSpace._cache - expected "parsedColorSpace" argument.'); + } + let csName, csRef; + if (cacheKey instanceof _primitives.Ref) { + csRef = cacheKey; + cacheKey = xref.fetch(cacheKey); + } + if (cacheKey instanceof _primitives.Name) { + csName = cacheKey.name; + } + if (csName || csRef) { + localColorSpaceCache.set(csName, csRef, parsedColorSpace); + } + } + static getCached(cacheKey, xref, localColorSpaceCache) { + if (!localColorSpaceCache) { + throw new Error('ColorSpace.getCached - expected "localColorSpaceCache" argument.'); + } + if (cacheKey instanceof _primitives.Ref) { + const localColorSpace = localColorSpaceCache.getByRef(cacheKey); + if (localColorSpace) { + return localColorSpace; + } + try { + cacheKey = xref.fetch(cacheKey); + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + } + } + if (cacheKey instanceof _primitives.Name) { + const localColorSpace = localColorSpaceCache.getByName(cacheKey.name); + if (localColorSpace) { + return localColorSpace; + } + } + return null; + } + static async parseAsync({ + cs, + xref, + resources = null, + pdfFunctionFactory, + localColorSpaceCache + }) { + const parsedColorSpace = this._parse(cs, xref, resources, pdfFunctionFactory); + this._cache(cs, xref, localColorSpaceCache, parsedColorSpace); + return parsedColorSpace; + } + static parse({ + cs, + xref, + resources = null, + pdfFunctionFactory, + localColorSpaceCache + }) { + const cachedColorSpace = this.getCached(cs, xref, localColorSpaceCache); + if (cachedColorSpace) { + return cachedColorSpace; + } + const parsedColorSpace = this._parse(cs, xref, resources, pdfFunctionFactory); + this._cache(cs, xref, localColorSpaceCache, parsedColorSpace); + return parsedColorSpace; + } + static _parse(cs, xref, resources = null, pdfFunctionFactory) { + cs = xref.fetchIfRef(cs); + if (cs instanceof _primitives.Name) { + switch (cs.name) { + case "G": + case "DeviceGray": + return this.singletons.gray; + case "RGB": + case "DeviceRGB": + return this.singletons.rgb; + case "CMYK": + case "DeviceCMYK": + return this.singletons.cmyk; + case "Pattern": + return new PatternCS(null); + default: + if (resources instanceof _primitives.Dict) { + const colorSpaces = resources.get("ColorSpace"); + if (colorSpaces instanceof _primitives.Dict) { + const resourcesCS = colorSpaces.get(cs.name); + if (resourcesCS) { + if (resourcesCS instanceof _primitives.Name) { + return this._parse(resourcesCS, xref, resources, pdfFunctionFactory); + } + cs = resourcesCS; + break; + } + } + } + throw new _util.FormatError(`Unrecognized ColorSpace: ${cs.name}`); + } + } + if (Array.isArray(cs)) { + const mode = xref.fetchIfRef(cs[0]).name; + let params, numComps, baseCS, whitePoint, blackPoint, gamma; + switch (mode) { + case "G": + case "DeviceGray": + return this.singletons.gray; + case "RGB": + case "DeviceRGB": + return this.singletons.rgb; + case "CMYK": + case "DeviceCMYK": + return this.singletons.cmyk; + case "CalGray": + params = xref.fetchIfRef(cs[1]); + whitePoint = params.getArray("WhitePoint"); + blackPoint = params.getArray("BlackPoint"); + gamma = params.get("Gamma"); + return new CalGrayCS(whitePoint, blackPoint, gamma); + case "CalRGB": + params = xref.fetchIfRef(cs[1]); + whitePoint = params.getArray("WhitePoint"); + blackPoint = params.getArray("BlackPoint"); + gamma = params.getArray("Gamma"); + const matrix = params.getArray("Matrix"); + return new CalRGBCS(whitePoint, blackPoint, gamma, matrix); + case "ICCBased": + const stream = xref.fetchIfRef(cs[1]); + const dict = stream.dict; + numComps = dict.get("N"); + const alt = dict.get("Alternate"); + if (alt) { + const altCS = this._parse(alt, xref, resources, pdfFunctionFactory); + if (altCS.numComps === numComps) { + return altCS; + } + (0, _util.warn)("ICCBased color space: Ignoring incorrect /Alternate entry."); + } + if (numComps === 1) { + return this.singletons.gray; + } else if (numComps === 3) { + return this.singletons.rgb; + } else if (numComps === 4) { + return this.singletons.cmyk; + } + break; + case "Pattern": + baseCS = cs[1] || null; + if (baseCS) { + baseCS = this._parse(baseCS, xref, resources, pdfFunctionFactory); + } + return new PatternCS(baseCS); + case "I": + case "Indexed": + baseCS = this._parse(cs[1], xref, resources, pdfFunctionFactory); + const hiVal = xref.fetchIfRef(cs[2]) + 1; + const lookup = xref.fetchIfRef(cs[3]); + return new IndexedCS(baseCS, hiVal, lookup); + case "Separation": + case "DeviceN": + const name = xref.fetchIfRef(cs[1]); + numComps = Array.isArray(name) ? name.length : 1; + baseCS = this._parse(cs[2], xref, resources, pdfFunctionFactory); + const tintFn = pdfFunctionFactory.create(cs[3]); + return new AlternateCS(numComps, baseCS, tintFn); + case "Lab": + params = xref.fetchIfRef(cs[1]); + whitePoint = params.getArray("WhitePoint"); + blackPoint = params.getArray("BlackPoint"); + const range = params.getArray("Range"); + return new LabCS(whitePoint, blackPoint, range); + default: + throw new _util.FormatError(`Unimplemented ColorSpace object: ${mode}`); + } + } + throw new _util.FormatError(`Unrecognized ColorSpace object: ${cs}`); + } + static isDefaultDecode(decode, numComps) { + if (!Array.isArray(decode)) { + return true; + } + if (numComps * 2 !== decode.length) { + (0, _util.warn)("The decode map is not the correct length"); + return true; + } + for (let i = 0, ii = decode.length; i < ii; i += 2) { + if (decode[i] !== 0 || decode[i + 1] !== 1) { + return false; + } + } + return true; + } + static get singletons() { + return (0, _util.shadow)(this, "singletons", { + get gray() { + return (0, _util.shadow)(this, "gray", new DeviceGrayCS()); + }, + get rgb() { + return (0, _util.shadow)(this, "rgb", new DeviceRgbCS()); + }, + get cmyk() { + return (0, _util.shadow)(this, "cmyk", new DeviceCmykCS()); + } + }); + } +} +exports.ColorSpace = ColorSpace; +class AlternateCS extends ColorSpace { + constructor(numComps, base, tintFn) { + super("Alternate", numComps); + this.base = base; + this.tintFn = tintFn; + this.tmpBuf = new Float32Array(base.numComps); + } + getRgbItem(src, srcOffset, dest, destOffset) { + const tmpBuf = this.tmpBuf; + this.tintFn(src, srcOffset, tmpBuf, 0); + this.base.getRgbItem(tmpBuf, 0, dest, destOffset); + } + getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) { + const tintFn = this.tintFn; + const base = this.base; + const scale = 1 / ((1 << bits) - 1); + const baseNumComps = base.numComps; + const usesZeroToOneRange = base.usesZeroToOneRange; + const isPassthrough = (base.isPassthrough(8) || !usesZeroToOneRange) && alpha01 === 0; + let pos = isPassthrough ? destOffset : 0; + const baseBuf = isPassthrough ? dest : new Uint8ClampedArray(baseNumComps * count); + const numComps = this.numComps; + const scaled = new Float32Array(numComps); + const tinted = new Float32Array(baseNumComps); + let i, j; + for (i = 0; i < count; i++) { + for (j = 0; j < numComps; j++) { + scaled[j] = src[srcOffset++] * scale; + } + tintFn(scaled, 0, tinted, 0); + if (usesZeroToOneRange) { + for (j = 0; j < baseNumComps; j++) { + baseBuf[pos++] = tinted[j] * 255; + } + } else { + base.getRgbItem(tinted, 0, baseBuf, pos); + pos += baseNumComps; + } + } + if (!isPassthrough) { + base.getRgbBuffer(baseBuf, 0, count, dest, destOffset, 8, alpha01); + } + } + getOutputLength(inputLength, alpha01) { + return this.base.getOutputLength(inputLength * this.base.numComps / this.numComps, alpha01); + } +} +class PatternCS extends ColorSpace { + constructor(baseCS) { + super("Pattern", null); + this.base = baseCS; + } + isDefaultDecode(decodeMap, bpc) { + (0, _util.unreachable)("Should not call PatternCS.isDefaultDecode"); + } +} +class IndexedCS extends ColorSpace { + constructor(base, highVal, lookup) { + super("Indexed", 1); + this.base = base; + this.highVal = highVal; + const length = base.numComps * highVal; + this.lookup = new Uint8Array(length); + if (lookup instanceof _base_stream.BaseStream) { + const bytes = lookup.getBytes(length); + this.lookup.set(bytes); + } else if (typeof lookup === "string") { + for (let i = 0; i < length; ++i) { + this.lookup[i] = lookup.charCodeAt(i) & 0xff; + } + } else { + throw new _util.FormatError(`IndexedCS - unrecognized lookup table: ${lookup}`); + } + } + getRgbItem(src, srcOffset, dest, destOffset) { + const numComps = this.base.numComps; + const start = src[srcOffset] * numComps; + this.base.getRgbBuffer(this.lookup, start, 1, dest, destOffset, 8, 0); + } + getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) { + const base = this.base; + const numComps = base.numComps; + const outputDelta = base.getOutputLength(numComps, alpha01); + const lookup = this.lookup; + for (let i = 0; i < count; ++i) { + const lookupPos = src[srcOffset++] * numComps; + base.getRgbBuffer(lookup, lookupPos, 1, dest, destOffset, 8, alpha01); + destOffset += outputDelta; + } + } + getOutputLength(inputLength, alpha01) { + return this.base.getOutputLength(inputLength * this.base.numComps, alpha01); + } + isDefaultDecode(decodeMap, bpc) { + if (!Array.isArray(decodeMap)) { + return true; + } + if (decodeMap.length !== 2) { + (0, _util.warn)("Decode map length is not correct"); + return true; + } + if (!Number.isInteger(bpc) || bpc < 1) { + (0, _util.warn)("Bits per component is not correct"); + return true; + } + return decodeMap[0] === 0 && decodeMap[1] === (1 << bpc) - 1; + } +} +class DeviceGrayCS extends ColorSpace { + constructor() { + super("DeviceGray", 1); + } + getRgbItem(src, srcOffset, dest, destOffset) { + const c = src[srcOffset] * 255; + dest[destOffset] = dest[destOffset + 1] = dest[destOffset + 2] = c; + } + getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) { + const scale = 255 / ((1 << bits) - 1); + let j = srcOffset, + q = destOffset; + for (let i = 0; i < count; ++i) { + const c = scale * src[j++]; + dest[q++] = c; + dest[q++] = c; + dest[q++] = c; + q += alpha01; + } + } + getOutputLength(inputLength, alpha01) { + return inputLength * (3 + alpha01); + } +} +class DeviceRgbCS extends ColorSpace { + constructor() { + super("DeviceRGB", 3); + } + getRgbItem(src, srcOffset, dest, destOffset) { + dest[destOffset] = src[srcOffset] * 255; + dest[destOffset + 1] = src[srcOffset + 1] * 255; + dest[destOffset + 2] = src[srcOffset + 2] * 255; + } + getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) { + if (bits === 8 && alpha01 === 0) { + dest.set(src.subarray(srcOffset, srcOffset + count * 3), destOffset); + return; + } + const scale = 255 / ((1 << bits) - 1); + let j = srcOffset, + q = destOffset; + for (let i = 0; i < count; ++i) { + dest[q++] = scale * src[j++]; + dest[q++] = scale * src[j++]; + dest[q++] = scale * src[j++]; + q += alpha01; + } + } + getOutputLength(inputLength, alpha01) { + return inputLength * (3 + alpha01) / 3 | 0; + } + isPassthrough(bits) { + return bits === 8; + } +} +class DeviceCmykCS extends ColorSpace { + constructor() { + super("DeviceCMYK", 4); + } + #toRgb(src, srcOffset, srcScale, dest, destOffset) { + const c = src[srcOffset] * srcScale; + const m = src[srcOffset + 1] * srcScale; + const y = src[srcOffset + 2] * srcScale; + const k = src[srcOffset + 3] * srcScale; + dest[destOffset] = 255 + c * (-4.387332384609988 * c + 54.48615194189176 * m + 18.82290502165302 * y + 212.25662451639585 * k + -285.2331026137004) + m * (1.7149763477362134 * m - 5.6096736904047315 * y + -17.873870861415444 * k - 5.497006427196366) + y * (-2.5217340131683033 * y - 21.248923337353073 * k + 17.5119270841813) + k * (-21.86122147463605 * k - 189.48180835922747); + dest[destOffset + 1] = 255 + c * (8.841041422036149 * c + 60.118027045597366 * m + 6.871425592049007 * y + 31.159100130055922 * k + -79.2970844816548) + m * (-15.310361306967817 * m + 17.575251261109482 * y + 131.35250912493976 * k - 190.9453302588951) + y * (4.444339102852739 * y + 9.8632861493405 * k - 24.86741582555878) + k * (-20.737325471181034 * k - 187.80453709719578); + dest[destOffset + 2] = 255 + c * (0.8842522430003296 * c + 8.078677503112928 * m + 30.89978309703729 * y - 0.23883238689178934 * k + -14.183576799673286) + m * (10.49593273432072 * m + 63.02378494754052 * y + 50.606957656360734 * k - 112.23884253719248) + y * (0.03296041114873217 * y + 115.60384449646641 * k + -193.58209356861505) + k * (-22.33816807309886 * k - 180.12613974708367); + } + getRgbItem(src, srcOffset, dest, destOffset) { + this.#toRgb(src, srcOffset, 1, dest, destOffset); + } + getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) { + const scale = 1 / ((1 << bits) - 1); + for (let i = 0; i < count; i++) { + this.#toRgb(src, srcOffset, scale, dest, destOffset); + srcOffset += 4; + destOffset += 3 + alpha01; + } + } + getOutputLength(inputLength, alpha01) { + return inputLength / 4 * (3 + alpha01) | 0; + } +} +class CalGrayCS extends ColorSpace { + constructor(whitePoint, blackPoint, gamma) { + super("CalGray", 1); + if (!whitePoint) { + throw new _util.FormatError("WhitePoint missing - required for color space CalGray"); + } + [this.XW, this.YW, this.ZW] = whitePoint; + [this.XB, this.YB, this.ZB] = blackPoint || [0, 0, 0]; + this.G = gamma || 1; + if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) { + throw new _util.FormatError(`Invalid WhitePoint components for ${this.name}, no fallback available`); + } + if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { + (0, _util.info)(`Invalid BlackPoint for ${this.name}, falling back to default.`); + this.XB = this.YB = this.ZB = 0; + } + if (this.XB !== 0 || this.YB !== 0 || this.ZB !== 0) { + (0, _util.warn)(`${this.name}, BlackPoint: XB: ${this.XB}, YB: ${this.YB}, ` + `ZB: ${this.ZB}, only default values are supported.`); + } + if (this.G < 1) { + (0, _util.info)(`Invalid Gamma: ${this.G} for ${this.name}, falling back to default.`); + this.G = 1; + } + } + #toRgb(src, srcOffset, dest, destOffset, scale) { + const A = src[srcOffset] * scale; + const AG = A ** this.G; + const L = this.YW * AG; + const val = Math.max(295.8 * L ** 0.3333333333333333 - 40.8, 0); + dest[destOffset] = val; + dest[destOffset + 1] = val; + dest[destOffset + 2] = val; + } + getRgbItem(src, srcOffset, dest, destOffset) { + this.#toRgb(src, srcOffset, dest, destOffset, 1); + } + getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) { + const scale = 1 / ((1 << bits) - 1); + for (let i = 0; i < count; ++i) { + this.#toRgb(src, srcOffset, dest, destOffset, scale); + srcOffset += 1; + destOffset += 3 + alpha01; + } + } + getOutputLength(inputLength, alpha01) { + return inputLength * (3 + alpha01); + } +} +class CalRGBCS extends ColorSpace { + static #BRADFORD_SCALE_MATRIX = new Float32Array([0.8951, 0.2664, -0.1614, -0.7502, 1.7135, 0.0367, 0.0389, -0.0685, 1.0296]); + static #BRADFORD_SCALE_INVERSE_MATRIX = new Float32Array([0.9869929, -0.1470543, 0.1599627, 0.4323053, 0.5183603, 0.0492912, -0.0085287, 0.0400428, 0.9684867]); + static #SRGB_D65_XYZ_TO_RGB_MATRIX = new Float32Array([3.2404542, -1.5371385, -0.4985314, -0.9692660, 1.8760108, 0.0415560, 0.0556434, -0.2040259, 1.0572252]); + static #FLAT_WHITEPOINT_MATRIX = new Float32Array([1, 1, 1]); + static #tempNormalizeMatrix = new Float32Array(3); + static #tempConvertMatrix1 = new Float32Array(3); + static #tempConvertMatrix2 = new Float32Array(3); + static #DECODE_L_CONSTANT = ((8 + 16) / 116) ** 3 / 8.0; + constructor(whitePoint, blackPoint, gamma, matrix) { + super("CalRGB", 3); + if (!whitePoint) { + throw new _util.FormatError("WhitePoint missing - required for color space CalRGB"); + } + const [XW, YW, ZW] = this.whitePoint = whitePoint; + const [XB, YB, ZB] = this.blackPoint = blackPoint || new Float32Array(3); + [this.GR, this.GG, this.GB] = gamma || new Float32Array([1, 1, 1]); + [this.MXA, this.MYA, this.MZA, this.MXB, this.MYB, this.MZB, this.MXC, this.MYC, this.MZC] = matrix || new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]); + if (XW < 0 || ZW < 0 || YW !== 1) { + throw new _util.FormatError(`Invalid WhitePoint components for ${this.name}, no fallback available`); + } + if (XB < 0 || YB < 0 || ZB < 0) { + (0, _util.info)(`Invalid BlackPoint for ${this.name} [${XB}, ${YB}, ${ZB}], ` + "falling back to default."); + this.blackPoint = new Float32Array(3); + } + if (this.GR < 0 || this.GG < 0 || this.GB < 0) { + (0, _util.info)(`Invalid Gamma [${this.GR}, ${this.GG}, ${this.GB}] for ` + `${this.name}, falling back to default.`); + this.GR = this.GG = this.GB = 1; + } + } + #matrixProduct(a, b, result) { + result[0] = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + result[1] = a[3] * b[0] + a[4] * b[1] + a[5] * b[2]; + result[2] = a[6] * b[0] + a[7] * b[1] + a[8] * b[2]; + } + #toFlat(sourceWhitePoint, LMS, result) { + result[0] = LMS[0] * 1 / sourceWhitePoint[0]; + result[1] = LMS[1] * 1 / sourceWhitePoint[1]; + result[2] = LMS[2] * 1 / sourceWhitePoint[2]; + } + #toD65(sourceWhitePoint, LMS, result) { + const D65X = 0.95047; + const D65Y = 1; + const D65Z = 1.08883; + result[0] = LMS[0] * D65X / sourceWhitePoint[0]; + result[1] = LMS[1] * D65Y / sourceWhitePoint[1]; + result[2] = LMS[2] * D65Z / sourceWhitePoint[2]; + } + #sRGBTransferFunction(color) { + if (color <= 0.0031308) { + return this.#adjustToRange(0, 1, 12.92 * color); + } + if (color >= 0.99554525) { + return 1; + } + return this.#adjustToRange(0, 1, (1 + 0.055) * color ** (1 / 2.4) - 0.055); + } + #adjustToRange(min, max, value) { + return Math.max(min, Math.min(max, value)); + } + #decodeL(L) { + if (L < 0) { + return -this.#decodeL(-L); + } + if (L > 8.0) { + return ((L + 16) / 116) ** 3; + } + return L * CalRGBCS.#DECODE_L_CONSTANT; + } + #compensateBlackPoint(sourceBlackPoint, XYZ_Flat, result) { + if (sourceBlackPoint[0] === 0 && sourceBlackPoint[1] === 0 && sourceBlackPoint[2] === 0) { + result[0] = XYZ_Flat[0]; + result[1] = XYZ_Flat[1]; + result[2] = XYZ_Flat[2]; + return; + } + const zeroDecodeL = this.#decodeL(0); + const X_DST = zeroDecodeL; + const X_SRC = this.#decodeL(sourceBlackPoint[0]); + const Y_DST = zeroDecodeL; + const Y_SRC = this.#decodeL(sourceBlackPoint[1]); + const Z_DST = zeroDecodeL; + const Z_SRC = this.#decodeL(sourceBlackPoint[2]); + const X_Scale = (1 - X_DST) / (1 - X_SRC); + const X_Offset = 1 - X_Scale; + const Y_Scale = (1 - Y_DST) / (1 - Y_SRC); + const Y_Offset = 1 - Y_Scale; + const Z_Scale = (1 - Z_DST) / (1 - Z_SRC); + const Z_Offset = 1 - Z_Scale; + result[0] = XYZ_Flat[0] * X_Scale + X_Offset; + result[1] = XYZ_Flat[1] * Y_Scale + Y_Offset; + result[2] = XYZ_Flat[2] * Z_Scale + Z_Offset; + } + #normalizeWhitePointToFlat(sourceWhitePoint, XYZ_In, result) { + if (sourceWhitePoint[0] === 1 && sourceWhitePoint[2] === 1) { + result[0] = XYZ_In[0]; + result[1] = XYZ_In[1]; + result[2] = XYZ_In[2]; + return; + } + const LMS = result; + this.#matrixProduct(CalRGBCS.#BRADFORD_SCALE_MATRIX, XYZ_In, LMS); + const LMS_Flat = CalRGBCS.#tempNormalizeMatrix; + this.#toFlat(sourceWhitePoint, LMS, LMS_Flat); + this.#matrixProduct(CalRGBCS.#BRADFORD_SCALE_INVERSE_MATRIX, LMS_Flat, result); + } + #normalizeWhitePointToD65(sourceWhitePoint, XYZ_In, result) { + const LMS = result; + this.#matrixProduct(CalRGBCS.#BRADFORD_SCALE_MATRIX, XYZ_In, LMS); + const LMS_D65 = CalRGBCS.#tempNormalizeMatrix; + this.#toD65(sourceWhitePoint, LMS, LMS_D65); + this.#matrixProduct(CalRGBCS.#BRADFORD_SCALE_INVERSE_MATRIX, LMS_D65, result); + } + #toRgb(src, srcOffset, dest, destOffset, scale) { + const A = this.#adjustToRange(0, 1, src[srcOffset] * scale); + const B = this.#adjustToRange(0, 1, src[srcOffset + 1] * scale); + const C = this.#adjustToRange(0, 1, src[srcOffset + 2] * scale); + const AGR = A === 1 ? 1 : A ** this.GR; + const BGG = B === 1 ? 1 : B ** this.GG; + const CGB = C === 1 ? 1 : C ** this.GB; + const X = this.MXA * AGR + this.MXB * BGG + this.MXC * CGB; + const Y = this.MYA * AGR + this.MYB * BGG + this.MYC * CGB; + const Z = this.MZA * AGR + this.MZB * BGG + this.MZC * CGB; + const XYZ = CalRGBCS.#tempConvertMatrix1; + XYZ[0] = X; + XYZ[1] = Y; + XYZ[2] = Z; + const XYZ_Flat = CalRGBCS.#tempConvertMatrix2; + this.#normalizeWhitePointToFlat(this.whitePoint, XYZ, XYZ_Flat); + const XYZ_Black = CalRGBCS.#tempConvertMatrix1; + this.#compensateBlackPoint(this.blackPoint, XYZ_Flat, XYZ_Black); + const XYZ_D65 = CalRGBCS.#tempConvertMatrix2; + this.#normalizeWhitePointToD65(CalRGBCS.#FLAT_WHITEPOINT_MATRIX, XYZ_Black, XYZ_D65); + const SRGB = CalRGBCS.#tempConvertMatrix1; + this.#matrixProduct(CalRGBCS.#SRGB_D65_XYZ_TO_RGB_MATRIX, XYZ_D65, SRGB); + dest[destOffset] = this.#sRGBTransferFunction(SRGB[0]) * 255; + dest[destOffset + 1] = this.#sRGBTransferFunction(SRGB[1]) * 255; + dest[destOffset + 2] = this.#sRGBTransferFunction(SRGB[2]) * 255; + } + getRgbItem(src, srcOffset, dest, destOffset) { + this.#toRgb(src, srcOffset, dest, destOffset, 1); + } + getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) { + const scale = 1 / ((1 << bits) - 1); + for (let i = 0; i < count; ++i) { + this.#toRgb(src, srcOffset, dest, destOffset, scale); + srcOffset += 3; + destOffset += 3 + alpha01; + } + } + getOutputLength(inputLength, alpha01) { + return inputLength * (3 + alpha01) / 3 | 0; + } +} +class LabCS extends ColorSpace { + constructor(whitePoint, blackPoint, range) { + super("Lab", 3); + if (!whitePoint) { + throw new _util.FormatError("WhitePoint missing - required for color space Lab"); + } + [this.XW, this.YW, this.ZW] = whitePoint; + [this.amin, this.amax, this.bmin, this.bmax] = range || [-100, 100, -100, 100]; + [this.XB, this.YB, this.ZB] = blackPoint || [0, 0, 0]; + if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) { + throw new _util.FormatError("Invalid WhitePoint components, no fallback available"); + } + if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { + (0, _util.info)("Invalid BlackPoint, falling back to default"); + this.XB = this.YB = this.ZB = 0; + } + if (this.amin > this.amax || this.bmin > this.bmax) { + (0, _util.info)("Invalid Range, falling back to defaults"); + this.amin = -100; + this.amax = 100; + this.bmin = -100; + this.bmax = 100; + } + } + #fn_g(x) { + return x >= 6 / 29 ? x ** 3 : 108 / 841 * (x - 4 / 29); + } + #decode(value, high1, low2, high2) { + return low2 + value * (high2 - low2) / high1; + } + #toRgb(src, srcOffset, maxVal, dest, destOffset) { + let Ls = src[srcOffset]; + let as = src[srcOffset + 1]; + let bs = src[srcOffset + 2]; + if (maxVal !== false) { + Ls = this.#decode(Ls, maxVal, 0, 100); + as = this.#decode(as, maxVal, this.amin, this.amax); + bs = this.#decode(bs, maxVal, this.bmin, this.bmax); + } + if (as > this.amax) { + as = this.amax; + } else if (as < this.amin) { + as = this.amin; + } + if (bs > this.bmax) { + bs = this.bmax; + } else if (bs < this.bmin) { + bs = this.bmin; + } + const M = (Ls + 16) / 116; + const L = M + as / 500; + const N = M - bs / 200; + const X = this.XW * this.#fn_g(L); + const Y = this.YW * this.#fn_g(M); + const Z = this.ZW * this.#fn_g(N); + let r, g, b; + if (this.ZW < 1) { + r = X * 3.1339 + Y * -1.617 + Z * -0.4906; + g = X * -0.9785 + Y * 1.916 + Z * 0.0333; + b = X * 0.072 + Y * -0.229 + Z * 1.4057; + } else { + r = X * 3.2406 + Y * -1.5372 + Z * -0.4986; + g = X * -0.9689 + Y * 1.8758 + Z * 0.0415; + b = X * 0.0557 + Y * -0.204 + Z * 1.057; + } + dest[destOffset] = Math.sqrt(r) * 255; + dest[destOffset + 1] = Math.sqrt(g) * 255; + dest[destOffset + 2] = Math.sqrt(b) * 255; + } + getRgbItem(src, srcOffset, dest, destOffset) { + this.#toRgb(src, srcOffset, false, dest, destOffset); + } + getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) { + const maxVal = (1 << bits) - 1; + for (let i = 0; i < count; i++) { + this.#toRgb(src, srcOffset, maxVal, dest, destOffset); + srcOffset += 3; + destOffset += 3 + alpha01; + } + } + getOutputLength(inputLength, alpha01) { + return inputLength * (3 + alpha01) / 3 | 0; + } + isDefaultDecode(decodeMap, bpc) { + return true; + } + get usesZeroToOneRange() { + return (0, _util.shadow)(this, "usesZeroToOneRange", false); + } +} + +/***/ }), +/* 13 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.PartialEvaluator = exports.EvaluatorPreprocessor = void 0; +var _util = __w_pdfjs_require__(2); +var _cmap = __w_pdfjs_require__(14); +var _primitives = __w_pdfjs_require__(4); +var _fonts = __w_pdfjs_require__(34); +var _encodings = __w_pdfjs_require__(37); +var _standard_fonts = __w_pdfjs_require__(41); +var _pattern = __w_pdfjs_require__(50); +var _xfa_fonts = __w_pdfjs_require__(51); +var _to_unicode_map = __w_pdfjs_require__(42); +var _function = __w_pdfjs_require__(57); +var _parser = __w_pdfjs_require__(16); +var _image_utils = __w_pdfjs_require__(59); +var _stream = __w_pdfjs_require__(8); +var _base_stream = __w_pdfjs_require__(5); +var _bidi = __w_pdfjs_require__(60); +var _colorspace = __w_pdfjs_require__(12); +var _decode_stream = __w_pdfjs_require__(18); +var _fonts_utils = __w_pdfjs_require__(38); +var _font_substitutions = __w_pdfjs_require__(61); +var _glyphlist = __w_pdfjs_require__(39); +var _metrics = __w_pdfjs_require__(45); +var _unicode = __w_pdfjs_require__(40); +var _image_resizer = __w_pdfjs_require__(62); +var _murmurhash = __w_pdfjs_require__(63); +var _operator_list = __w_pdfjs_require__(64); +var _image = __w_pdfjs_require__(65); +const DefaultPartialEvaluatorOptions = Object.freeze({ + maxImageSize: -1, + disableFontFace: false, + ignoreErrors: false, + isEvalSupported: true, + isOffscreenCanvasSupported: false, + canvasMaxAreaInBytes: -1, + fontExtraProperties: false, + useSystemFonts: true, + cMapUrl: null, + standardFontDataUrl: null +}); +const PatternType = { + TILING: 1, + SHADING: 2 +}; +const TEXT_CHUNK_BATCH_SIZE = 10; +const deferred = Promise.resolve(); +function normalizeBlendMode(value, parsingArray = false) { + if (Array.isArray(value)) { + for (const val of value) { + const maybeBM = normalizeBlendMode(val, true); + if (maybeBM) { + return maybeBM; + } + } + (0, _util.warn)(`Unsupported blend mode Array: ${value}`); + return "source-over"; + } + if (!(value instanceof _primitives.Name)) { + if (parsingArray) { + return null; + } + return "source-over"; + } + switch (value.name) { + case "Normal": + case "Compatible": + return "source-over"; + case "Multiply": + return "multiply"; + case "Screen": + return "screen"; + case "Overlay": + return "overlay"; + case "Darken": + return "darken"; + case "Lighten": + return "lighten"; + case "ColorDodge": + return "color-dodge"; + case "ColorBurn": + return "color-burn"; + case "HardLight": + return "hard-light"; + case "SoftLight": + return "soft-light"; + case "Difference": + return "difference"; + case "Exclusion": + return "exclusion"; + case "Hue": + return "hue"; + case "Saturation": + return "saturation"; + case "Color": + return "color"; + case "Luminosity": + return "luminosity"; + } + if (parsingArray) { + return null; + } + (0, _util.warn)(`Unsupported blend mode: ${value.name}`); + return "source-over"; +} +function incrementCachedImageMaskCount(data) { + if (data.fn === _util.OPS.paintImageMaskXObject && data.args[0]?.count > 0) { + data.args[0].count++; + } +} +class TimeSlotManager { + static TIME_SLOT_DURATION_MS = 20; + static CHECK_TIME_EVERY = 100; + constructor() { + this.reset(); + } + check() { + if (++this.checked < TimeSlotManager.CHECK_TIME_EVERY) { + return false; + } + this.checked = 0; + return this.endTime <= Date.now(); + } + reset() { + this.endTime = Date.now() + TimeSlotManager.TIME_SLOT_DURATION_MS; + this.checked = 0; + } +} +class PartialEvaluator { + constructor({ + xref, + handler, + pageIndex, + idFactory, + fontCache, + builtInCMapCache, + standardFontDataCache, + globalImageCache, + systemFontCache, + options = null + }) { + this.xref = xref; + this.handler = handler; + this.pageIndex = pageIndex; + this.idFactory = idFactory; + this.fontCache = fontCache; + this.builtInCMapCache = builtInCMapCache; + this.standardFontDataCache = standardFontDataCache; + this.globalImageCache = globalImageCache; + this.systemFontCache = systemFontCache; + this.options = options || DefaultPartialEvaluatorOptions; + this.parsingType3Font = false; + this._regionalImageCache = new _image_utils.RegionalImageCache(); + this._fetchBuiltInCMapBound = this.fetchBuiltInCMap.bind(this); + _image_resizer.ImageResizer.setMaxArea(this.options.canvasMaxAreaInBytes); + } + get _pdfFunctionFactory() { + const pdfFunctionFactory = new _function.PDFFunctionFactory({ + xref: this.xref, + isEvalSupported: this.options.isEvalSupported + }); + return (0, _util.shadow)(this, "_pdfFunctionFactory", pdfFunctionFactory); + } + clone(newOptions = null) { + const newEvaluator = Object.create(this); + newEvaluator.options = Object.assign(Object.create(null), this.options, newOptions); + return newEvaluator; + } + hasBlendModes(resources, nonBlendModesSet) { + if (!(resources instanceof _primitives.Dict)) { + return false; + } + if (resources.objId && nonBlendModesSet.has(resources.objId)) { + return false; + } + const processed = new _primitives.RefSet(nonBlendModesSet); + if (resources.objId) { + processed.put(resources.objId); + } + const nodes = [resources], + xref = this.xref; + while (nodes.length) { + const node = nodes.shift(); + const graphicStates = node.get("ExtGState"); + if (graphicStates instanceof _primitives.Dict) { + for (let graphicState of graphicStates.getRawValues()) { + if (graphicState instanceof _primitives.Ref) { + if (processed.has(graphicState)) { + continue; + } + try { + graphicState = xref.fetch(graphicState); + } catch (ex) { + processed.put(graphicState); + (0, _util.info)(`hasBlendModes - ignoring ExtGState: "${ex}".`); + continue; + } + } + if (!(graphicState instanceof _primitives.Dict)) { + continue; + } + if (graphicState.objId) { + processed.put(graphicState.objId); + } + const bm = graphicState.get("BM"); + if (bm instanceof _primitives.Name) { + if (bm.name !== "Normal") { + return true; + } + continue; + } + if (bm !== undefined && Array.isArray(bm)) { + for (const element of bm) { + if (element instanceof _primitives.Name && element.name !== "Normal") { + return true; + } + } + } + } + } + const xObjects = node.get("XObject"); + if (!(xObjects instanceof _primitives.Dict)) { + continue; + } + for (let xObject of xObjects.getRawValues()) { + if (xObject instanceof _primitives.Ref) { + if (processed.has(xObject)) { + continue; + } + try { + xObject = xref.fetch(xObject); + } catch (ex) { + processed.put(xObject); + (0, _util.info)(`hasBlendModes - ignoring XObject: "${ex}".`); + continue; + } + } + if (!(xObject instanceof _base_stream.BaseStream)) { + continue; + } + if (xObject.dict.objId) { + processed.put(xObject.dict.objId); + } + const xResources = xObject.dict.get("Resources"); + if (!(xResources instanceof _primitives.Dict)) { + continue; + } + if (xResources.objId && processed.has(xResources.objId)) { + continue; + } + nodes.push(xResources); + if (xResources.objId) { + processed.put(xResources.objId); + } + } + } + for (const ref of processed) { + nonBlendModesSet.put(ref); + } + return false; + } + async fetchBuiltInCMap(name) { + const cachedData = this.builtInCMapCache.get(name); + if (cachedData) { + return cachedData; + } + let data; + if (this.options.cMapUrl !== null) { + const url = `${this.options.cMapUrl}${name}.bcmap`; + const response = await fetch(url); + if (!response.ok) { + throw new Error(`fetchBuiltInCMap: failed to fetch file "${url}" with "${response.statusText}".`); + } + data = { + cMapData: new Uint8Array(await response.arrayBuffer()), + compressionType: _util.CMapCompressionType.BINARY + }; + } else { + data = await this.handler.sendWithPromise("FetchBuiltInCMap", { + name + }); + } + if (data.compressionType !== _util.CMapCompressionType.NONE) { + this.builtInCMapCache.set(name, data); + } + return data; + } + async fetchStandardFontData(name) { + const cachedData = this.standardFontDataCache.get(name); + if (cachedData) { + return new _stream.Stream(cachedData); + } + if (this.options.useSystemFonts && name !== "Symbol" && name !== "ZapfDingbats") { + return null; + } + const standardFontNameToFileName = (0, _standard_fonts.getFontNameToFileMap)(), + filename = standardFontNameToFileName[name]; + let data; + if (this.options.standardFontDataUrl !== null) { + const url = `${this.options.standardFontDataUrl}${filename}`; + const response = await fetch(url); + if (!response.ok) { + (0, _util.warn)(`fetchStandardFontData: failed to fetch file "${url}" with "${response.statusText}".`); + } else { + data = await response.arrayBuffer(); + } + } else { + try { + data = await this.handler.sendWithPromise("FetchStandardFontData", { + filename + }); + } catch (e) { + (0, _util.warn)(`fetchStandardFontData: failed to fetch file "${filename}" with "${e}".`); + } + } + if (!data) { + return null; + } + this.standardFontDataCache.set(name, data); + return new _stream.Stream(data); + } + async buildFormXObject(resources, xobj, smask, operatorList, task, initialState, localColorSpaceCache) { + const dict = xobj.dict; + const matrix = dict.getArray("Matrix"); + let bbox = dict.getArray("BBox"); + bbox = Array.isArray(bbox) && bbox.length === 4 ? _util.Util.normalizeRect(bbox) : null; + let optionalContent, groupOptions; + if (dict.has("OC")) { + optionalContent = await this.parseMarkedContentProps(dict.get("OC"), resources); + } + if (optionalContent !== undefined) { + operatorList.addOp(_util.OPS.beginMarkedContentProps, ["OC", optionalContent]); + } + const group = dict.get("Group"); + if (group) { + groupOptions = { + matrix, + bbox, + smask, + isolated: false, + knockout: false + }; + const groupSubtype = group.get("S"); + let colorSpace = null; + if ((0, _primitives.isName)(groupSubtype, "Transparency")) { + groupOptions.isolated = group.get("I") || false; + groupOptions.knockout = group.get("K") || false; + if (group.has("CS")) { + const cs = group.getRaw("CS"); + const cachedColorSpace = _colorspace.ColorSpace.getCached(cs, this.xref, localColorSpaceCache); + if (cachedColorSpace) { + colorSpace = cachedColorSpace; + } else { + colorSpace = await this.parseColorSpace({ + cs, + resources, + localColorSpaceCache + }); + } + } + } + if (smask?.backdrop) { + colorSpace ||= _colorspace.ColorSpace.singletons.rgb; + smask.backdrop = colorSpace.getRgb(smask.backdrop, 0); + } + operatorList.addOp(_util.OPS.beginGroup, [groupOptions]); + } + const args = group ? [matrix, null] : [matrix, bbox]; + operatorList.addOp(_util.OPS.paintFormXObjectBegin, args); + return this.getOperatorList({ + stream: xobj, + task, + resources: dict.get("Resources") || resources, + operatorList, + initialState + }).then(function () { + operatorList.addOp(_util.OPS.paintFormXObjectEnd, []); + if (group) { + operatorList.addOp(_util.OPS.endGroup, [groupOptions]); + } + if (optionalContent !== undefined) { + operatorList.addOp(_util.OPS.endMarkedContent, []); + } + }); + } + _sendImgData(objId, imgData, cacheGlobally = false) { + const transfers = imgData ? [imgData.bitmap || imgData.data.buffer] : null; + if (this.parsingType3Font || cacheGlobally) { + return this.handler.send("commonobj", [objId, "Image", imgData], transfers); + } + return this.handler.send("obj", [objId, this.pageIndex, "Image", imgData], transfers); + } + async buildPaintImageXObject({ + resources, + image, + isInline = false, + operatorList, + cacheKey, + localImageCache, + localColorSpaceCache + }) { + const dict = image.dict; + const imageRef = dict.objId; + const w = dict.get("W", "Width"); + const h = dict.get("H", "Height"); + if (!(w && typeof w === "number") || !(h && typeof h === "number")) { + (0, _util.warn)("Image dimensions are missing, or not numbers."); + return; + } + const maxImageSize = this.options.maxImageSize; + if (maxImageSize !== -1 && w * h > maxImageSize) { + const msg = "Image exceeded maximum allowed size and was removed."; + if (this.options.ignoreErrors) { + (0, _util.warn)(msg); + return; + } + throw new Error(msg); + } + let optionalContent; + if (dict.has("OC")) { + optionalContent = await this.parseMarkedContentProps(dict.get("OC"), resources); + } + const imageMask = dict.get("IM", "ImageMask") || false; + let imgData, args; + if (imageMask) { + const interpolate = dict.get("I", "Interpolate"); + const bitStrideLength = w + 7 >> 3; + const imgArray = image.getBytes(bitStrideLength * h); + const decode = dict.getArray("D", "Decode"); + if (this.parsingType3Font) { + imgData = _image.PDFImage.createRawMask({ + imgArray, + width: w, + height: h, + imageIsFromDecodeStream: image instanceof _decode_stream.DecodeStream, + inverseDecode: decode?.[0] > 0, + interpolate + }); + imgData.cached = !!cacheKey; + args = [imgData]; + operatorList.addImageOps(_util.OPS.paintImageMaskXObject, args, optionalContent); + if (cacheKey) { + const cacheData = { + fn: _util.OPS.paintImageMaskXObject, + args, + optionalContent + }; + localImageCache.set(cacheKey, imageRef, cacheData); + if (imageRef) { + this._regionalImageCache.set(null, imageRef, cacheData); + } + } + return; + } + imgData = await _image.PDFImage.createMask({ + imgArray, + width: w, + height: h, + imageIsFromDecodeStream: image instanceof _decode_stream.DecodeStream, + inverseDecode: decode?.[0] > 0, + interpolate, + isOffscreenCanvasSupported: this.options.isOffscreenCanvasSupported + }); + if (imgData.isSingleOpaquePixel) { + operatorList.addImageOps(_util.OPS.paintSolidColorImageMask, [], optionalContent); + if (cacheKey) { + const cacheData = { + fn: _util.OPS.paintSolidColorImageMask, + args: [], + optionalContent + }; + localImageCache.set(cacheKey, imageRef, cacheData); + if (imageRef) { + this._regionalImageCache.set(null, imageRef, cacheData); + } + } + return; + } + const objId = `mask_${this.idFactory.createObjId()}`; + operatorList.addDependency(objId); + this._sendImgData(objId, imgData); + args = [{ + data: objId, + width: imgData.width, + height: imgData.height, + interpolate: imgData.interpolate, + count: 1 + }]; + operatorList.addImageOps(_util.OPS.paintImageMaskXObject, args, optionalContent); + if (cacheKey) { + const cacheData = { + fn: _util.OPS.paintImageMaskXObject, + args, + optionalContent + }; + localImageCache.set(cacheKey, imageRef, cacheData); + if (imageRef) { + this._regionalImageCache.set(null, imageRef, cacheData); + } + } + return; + } + const SMALL_IMAGE_DIMENSIONS = 200; + if (isInline && !dict.has("SMask") && !dict.has("Mask") && w + h < SMALL_IMAGE_DIMENSIONS) { + const imageObj = new _image.PDFImage({ + xref: this.xref, + res: resources, + image, + isInline, + pdfFunctionFactory: this._pdfFunctionFactory, + localColorSpaceCache + }); + imgData = await imageObj.createImageData(true, false); + operatorList.isOffscreenCanvasSupported = this.options.isOffscreenCanvasSupported; + operatorList.addImageOps(_util.OPS.paintInlineImageXObject, [imgData], optionalContent); + return; + } + let objId = `img_${this.idFactory.createObjId()}`, + cacheGlobally = false; + if (this.parsingType3Font) { + objId = `${this.idFactory.getDocId()}_type3_${objId}`; + } else if (imageRef) { + cacheGlobally = this.globalImageCache.shouldCache(imageRef, this.pageIndex); + if (cacheGlobally) { + objId = `${this.idFactory.getDocId()}_${objId}`; + } + } + operatorList.addDependency(objId); + args = [objId, w, h]; + _image.PDFImage.buildImage({ + xref: this.xref, + res: resources, + image, + isInline, + pdfFunctionFactory: this._pdfFunctionFactory, + localColorSpaceCache + }).then(async imageObj => { + imgData = await imageObj.createImageData(false, this.options.isOffscreenCanvasSupported); + if (cacheKey && imageRef && cacheGlobally) { + const length = imgData.bitmap ? imgData.width * imgData.height * 4 : imgData.data.length; + this.globalImageCache.addByteSize(imageRef, length); + } + return this._sendImgData(objId, imgData, cacheGlobally); + }).catch(reason => { + (0, _util.warn)(`Unable to decode image "${objId}": "${reason}".`); + return this._sendImgData(objId, null, cacheGlobally); + }); + operatorList.addImageOps(_util.OPS.paintImageXObject, args, optionalContent); + if (cacheKey) { + const cacheData = { + fn: _util.OPS.paintImageXObject, + args, + optionalContent + }; + localImageCache.set(cacheKey, imageRef, cacheData); + if (imageRef) { + this._regionalImageCache.set(null, imageRef, cacheData); + if (cacheGlobally) { + (0, _util.assert)(!isInline, "Cannot cache an inline image globally."); + this.globalImageCache.setData(imageRef, { + objId, + fn: _util.OPS.paintImageXObject, + args, + optionalContent, + byteSize: 0 + }); + } + } + } + } + handleSMask(smask, resources, operatorList, task, stateManager, localColorSpaceCache) { + const smaskContent = smask.get("G"); + const smaskOptions = { + subtype: smask.get("S").name, + backdrop: smask.get("BC") + }; + const transferObj = smask.get("TR"); + if ((0, _function.isPDFFunction)(transferObj)) { + const transferFn = this._pdfFunctionFactory.create(transferObj); + const transferMap = new Uint8Array(256); + const tmp = new Float32Array(1); + for (let i = 0; i < 256; i++) { + tmp[0] = i / 255; + transferFn(tmp, 0, tmp, 0); + transferMap[i] = tmp[0] * 255 | 0; + } + smaskOptions.transferMap = transferMap; + } + return this.buildFormXObject(resources, smaskContent, smaskOptions, operatorList, task, stateManager.state.clone(), localColorSpaceCache); + } + handleTransferFunction(tr) { + let transferArray; + if (Array.isArray(tr)) { + transferArray = tr; + } else if ((0, _function.isPDFFunction)(tr)) { + transferArray = [tr]; + } else { + return null; + } + const transferMaps = []; + let numFns = 0, + numEffectfulFns = 0; + for (const entry of transferArray) { + const transferObj = this.xref.fetchIfRef(entry); + numFns++; + if ((0, _primitives.isName)(transferObj, "Identity")) { + transferMaps.push(null); + continue; + } else if (!(0, _function.isPDFFunction)(transferObj)) { + return null; + } + const transferFn = this._pdfFunctionFactory.create(transferObj); + const transferMap = new Uint8Array(256), + tmp = new Float32Array(1); + for (let j = 0; j < 256; j++) { + tmp[0] = j / 255; + transferFn(tmp, 0, tmp, 0); + transferMap[j] = tmp[0] * 255 | 0; + } + transferMaps.push(transferMap); + numEffectfulFns++; + } + if (!(numFns === 1 || numFns === 4)) { + return null; + } + if (numEffectfulFns === 0) { + return null; + } + return transferMaps; + } + handleTilingType(fn, color, resources, pattern, patternDict, operatorList, task, localTilingPatternCache) { + const tilingOpList = new _operator_list.OperatorList(); + const patternResources = _primitives.Dict.merge({ + xref: this.xref, + dictArray: [patternDict.get("Resources"), resources] + }); + return this.getOperatorList({ + stream: pattern, + task, + resources: patternResources, + operatorList: tilingOpList + }).then(function () { + const operatorListIR = tilingOpList.getIR(); + const tilingPatternIR = (0, _pattern.getTilingPatternIR)(operatorListIR, patternDict, color); + operatorList.addDependencies(tilingOpList.dependencies); + operatorList.addOp(fn, tilingPatternIR); + if (patternDict.objId) { + localTilingPatternCache.set(null, patternDict.objId, { + operatorListIR, + dict: patternDict + }); + } + }).catch(reason => { + if (reason instanceof _util.AbortException) { + return; + } + if (this.options.ignoreErrors) { + (0, _util.warn)(`handleTilingType - ignoring pattern: "${reason}".`); + return; + } + throw reason; + }); + } + handleSetFont(resources, fontArgs, fontRef, operatorList, task, state, fallbackFontDict = null, cssFontInfo = null) { + const fontName = fontArgs?.[0] instanceof _primitives.Name ? fontArgs[0].name : null; + return this.loadFont(fontName, fontRef, resources, fallbackFontDict, cssFontInfo).then(translated => { + if (!translated.font.isType3Font) { + return translated; + } + return translated.loadType3Data(this, resources, task).then(function () { + operatorList.addDependencies(translated.type3Dependencies); + return translated; + }).catch(reason => { + return new TranslatedFont({ + loadedName: "g_font_error", + font: new _fonts.ErrorFont(`Type3 font load error: ${reason}`), + dict: translated.font, + evaluatorOptions: this.options + }); + }); + }).then(translated => { + state.font = translated.font; + translated.send(this.handler); + return translated.loadedName; + }); + } + handleText(chars, state) { + const font = state.font; + const glyphs = font.charsToGlyphs(chars); + if (font.data) { + const isAddToPathSet = !!(state.textRenderingMode & _util.TextRenderingMode.ADD_TO_PATH_FLAG); + if (isAddToPathSet || state.fillColorSpace.name === "Pattern" || font.disableFontFace || this.options.disableFontFace) { + PartialEvaluator.buildFontPaths(font, glyphs, this.handler, this.options); + } + } + return glyphs; + } + ensureStateFont(state) { + if (state.font) { + return; + } + const reason = new _util.FormatError("Missing setFont (Tf) operator before text rendering operator."); + if (this.options.ignoreErrors) { + (0, _util.warn)(`ensureStateFont: "${reason}".`); + return; + } + throw reason; + } + async setGState({ + resources, + gState, + operatorList, + cacheKey, + task, + stateManager, + localGStateCache, + localColorSpaceCache + }) { + const gStateRef = gState.objId; + let isSimpleGState = true; + const gStateObj = []; + let promise = Promise.resolve(); + for (const key of gState.getKeys()) { + const value = gState.get(key); + switch (key) { + case "Type": + break; + case "LW": + case "LC": + case "LJ": + case "ML": + case "D": + case "RI": + case "FL": + case "CA": + case "ca": + gStateObj.push([key, value]); + break; + case "Font": + isSimpleGState = false; + promise = promise.then(() => { + return this.handleSetFont(resources, null, value[0], operatorList, task, stateManager.state).then(function (loadedName) { + operatorList.addDependency(loadedName); + gStateObj.push([key, [loadedName, value[1]]]); + }); + }); + break; + case "BM": + gStateObj.push([key, normalizeBlendMode(value)]); + break; + case "SMask": + if ((0, _primitives.isName)(value, "None")) { + gStateObj.push([key, false]); + break; + } + if (value instanceof _primitives.Dict) { + isSimpleGState = false; + promise = promise.then(() => { + return this.handleSMask(value, resources, operatorList, task, stateManager, localColorSpaceCache); + }); + gStateObj.push([key, true]); + } else { + (0, _util.warn)("Unsupported SMask type"); + } + break; + case "TR": + const transferMaps = this.handleTransferFunction(value); + gStateObj.push([key, transferMaps]); + break; + case "OP": + case "op": + case "OPM": + case "BG": + case "BG2": + case "UCR": + case "UCR2": + case "TR2": + case "HT": + case "SM": + case "SA": + case "AIS": + case "TK": + (0, _util.info)("graphic state operator " + key); + break; + default: + (0, _util.info)("Unknown graphic state operator " + key); + break; + } + } + return promise.then(function () { + if (gStateObj.length > 0) { + operatorList.addOp(_util.OPS.setGState, [gStateObj]); + } + if (isSimpleGState) { + localGStateCache.set(cacheKey, gStateRef, gStateObj); + } + }); + } + loadFont(fontName, font, resources, fallbackFontDict = null, cssFontInfo = null) { + const errorFont = async () => { + return new TranslatedFont({ + loadedName: "g_font_error", + font: new _fonts.ErrorFont(`Font "${fontName}" is not available.`), + dict: font, + evaluatorOptions: this.options + }); + }; + let fontRef; + if (font) { + if (font instanceof _primitives.Ref) { + fontRef = font; + } + } else { + const fontRes = resources.get("Font"); + if (fontRes) { + fontRef = fontRes.getRaw(fontName); + } + } + if (fontRef) { + if (this.parsingType3Font && this.type3FontRefs.has(fontRef)) { + return errorFont(); + } + if (this.fontCache.has(fontRef)) { + return this.fontCache.get(fontRef); + } + font = this.xref.fetchIfRef(fontRef); + } + if (!(font instanceof _primitives.Dict)) { + if (!this.options.ignoreErrors && !this.parsingType3Font) { + (0, _util.warn)(`Font "${fontName}" is not available.`); + return errorFont(); + } + (0, _util.warn)(`Font "${fontName}" is not available -- attempting to fallback to a default font.`); + font = fallbackFontDict || PartialEvaluator.fallbackFontDict; + } + if (font.cacheKey && this.fontCache.has(font.cacheKey)) { + return this.fontCache.get(font.cacheKey); + } + const fontCapability = new _util.PromiseCapability(); + let preEvaluatedFont; + try { + preEvaluatedFont = this.preEvaluateFont(font); + preEvaluatedFont.cssFontInfo = cssFontInfo; + } catch (reason) { + (0, _util.warn)(`loadFont - preEvaluateFont failed: "${reason}".`); + return errorFont(); + } + const { + descriptor, + hash + } = preEvaluatedFont; + const fontRefIsRef = fontRef instanceof _primitives.Ref; + let fontID; + if (hash && descriptor instanceof _primitives.Dict) { + const fontAliases = descriptor.fontAliases ||= Object.create(null); + if (fontAliases[hash]) { + const aliasFontRef = fontAliases[hash].aliasRef; + if (fontRefIsRef && aliasFontRef && this.fontCache.has(aliasFontRef)) { + this.fontCache.putAlias(fontRef, aliasFontRef); + return this.fontCache.get(fontRef); + } + } else { + fontAliases[hash] = { + fontID: this.idFactory.createFontId() + }; + } + if (fontRefIsRef) { + fontAliases[hash].aliasRef = fontRef; + } + fontID = fontAliases[hash].fontID; + } else { + fontID = this.idFactory.createFontId(); + } + (0, _util.assert)(fontID?.startsWith("f"), 'The "fontID" must be (correctly) defined.'); + if (fontRefIsRef) { + this.fontCache.put(fontRef, fontCapability.promise); + } else { + font.cacheKey = `cacheKey_${fontID}`; + this.fontCache.put(font.cacheKey, fontCapability.promise); + } + font.loadedName = `${this.idFactory.getDocId()}_${fontID}`; + this.translateFont(preEvaluatedFont).then(translatedFont => { + fontCapability.resolve(new TranslatedFont({ + loadedName: font.loadedName, + font: translatedFont, + dict: font, + evaluatorOptions: this.options + })); + }).catch(reason => { + (0, _util.warn)(`loadFont - translateFont failed: "${reason}".`); + fontCapability.resolve(new TranslatedFont({ + loadedName: font.loadedName, + font: new _fonts.ErrorFont(reason instanceof Error ? reason.message : reason), + dict: font, + evaluatorOptions: this.options + })); + }); + return fontCapability.promise; + } + buildPath(operatorList, fn, args, parsingText = false) { + const lastIndex = operatorList.length - 1; + if (!args) { + args = []; + } + if (lastIndex < 0 || operatorList.fnArray[lastIndex] !== _util.OPS.constructPath) { + if (parsingText) { + (0, _util.warn)(`Encountered path operator "${fn}" inside of a text object.`); + operatorList.addOp(_util.OPS.save, null); + } + let minMax; + switch (fn) { + case _util.OPS.rectangle: + const x = args[0] + args[2]; + const y = args[1] + args[3]; + minMax = [Math.min(args[0], x), Math.max(args[0], x), Math.min(args[1], y), Math.max(args[1], y)]; + break; + case _util.OPS.moveTo: + case _util.OPS.lineTo: + minMax = [args[0], args[0], args[1], args[1]]; + break; + default: + minMax = [Infinity, -Infinity, Infinity, -Infinity]; + break; + } + operatorList.addOp(_util.OPS.constructPath, [[fn], args, minMax]); + if (parsingText) { + operatorList.addOp(_util.OPS.restore, null); + } + } else { + const opArgs = operatorList.argsArray[lastIndex]; + opArgs[0].push(fn); + opArgs[1].push(...args); + const minMax = opArgs[2]; + switch (fn) { + case _util.OPS.rectangle: + const x = args[0] + args[2]; + const y = args[1] + args[3]; + minMax[0] = Math.min(minMax[0], args[0], x); + minMax[1] = Math.max(minMax[1], args[0], x); + minMax[2] = Math.min(minMax[2], args[1], y); + minMax[3] = Math.max(minMax[3], args[1], y); + break; + case _util.OPS.moveTo: + case _util.OPS.lineTo: + minMax[0] = Math.min(minMax[0], args[0]); + minMax[1] = Math.max(minMax[1], args[0]); + minMax[2] = Math.min(minMax[2], args[1]); + minMax[3] = Math.max(minMax[3], args[1]); + break; + } + } + } + parseColorSpace({ + cs, + resources, + localColorSpaceCache + }) { + return _colorspace.ColorSpace.parseAsync({ + cs, + xref: this.xref, + resources, + pdfFunctionFactory: this._pdfFunctionFactory, + localColorSpaceCache + }).catch(reason => { + if (reason instanceof _util.AbortException) { + return null; + } + if (this.options.ignoreErrors) { + (0, _util.warn)(`parseColorSpace - ignoring ColorSpace: "${reason}".`); + return null; + } + throw reason; + }); + } + parseShading({ + shading, + resources, + localColorSpaceCache, + localShadingPatternCache + }) { + let id = localShadingPatternCache.get(shading); + if (!id) { + var shadingFill = _pattern.Pattern.parseShading(shading, this.xref, resources, this._pdfFunctionFactory, localColorSpaceCache); + const patternIR = shadingFill.getIR(); + id = `pattern_${this.idFactory.createObjId()}`; + if (this.parsingType3Font) { + id = `${this.idFactory.getDocId()}_type3_${id}`; + } + localShadingPatternCache.set(shading, id); + if (this.parsingType3Font) { + this.handler.send("commonobj", [id, "Pattern", patternIR]); + } else { + this.handler.send("obj", [id, this.pageIndex, "Pattern", patternIR]); + } + } + return id; + } + handleColorN(operatorList, fn, args, cs, patterns, resources, task, localColorSpaceCache, localTilingPatternCache, localShadingPatternCache) { + const patternName = args.pop(); + if (patternName instanceof _primitives.Name) { + const rawPattern = patterns.getRaw(patternName.name); + const localTilingPattern = rawPattern instanceof _primitives.Ref && localTilingPatternCache.getByRef(rawPattern); + if (localTilingPattern) { + try { + const color = cs.base ? cs.base.getRgb(args, 0) : null; + const tilingPatternIR = (0, _pattern.getTilingPatternIR)(localTilingPattern.operatorListIR, localTilingPattern.dict, color); + operatorList.addOp(fn, tilingPatternIR); + return undefined; + } catch {} + } + const pattern = this.xref.fetchIfRef(rawPattern); + if (pattern) { + const dict = pattern instanceof _base_stream.BaseStream ? pattern.dict : pattern; + const typeNum = dict.get("PatternType"); + if (typeNum === PatternType.TILING) { + const color = cs.base ? cs.base.getRgb(args, 0) : null; + return this.handleTilingType(fn, color, resources, pattern, dict, operatorList, task, localTilingPatternCache); + } else if (typeNum === PatternType.SHADING) { + const shading = dict.get("Shading"); + const matrix = dict.getArray("Matrix"); + const objId = this.parseShading({ + shading, + resources, + localColorSpaceCache, + localShadingPatternCache + }); + operatorList.addOp(fn, ["Shading", objId, matrix]); + return undefined; + } + throw new _util.FormatError(`Unknown PatternType: ${typeNum}`); + } + } + throw new _util.FormatError(`Unknown PatternName: ${patternName}`); + } + _parseVisibilityExpression(array, nestingCounter, currentResult) { + const MAX_NESTING = 10; + if (++nestingCounter > MAX_NESTING) { + (0, _util.warn)("Visibility expression is too deeply nested"); + return; + } + const length = array.length; + const operator = this.xref.fetchIfRef(array[0]); + if (length < 2 || !(operator instanceof _primitives.Name)) { + (0, _util.warn)("Invalid visibility expression"); + return; + } + switch (operator.name) { + case "And": + case "Or": + case "Not": + currentResult.push(operator.name); + break; + default: + (0, _util.warn)(`Invalid operator ${operator.name} in visibility expression`); + return; + } + for (let i = 1; i < length; i++) { + const raw = array[i]; + const object = this.xref.fetchIfRef(raw); + if (Array.isArray(object)) { + const nestedResult = []; + currentResult.push(nestedResult); + this._parseVisibilityExpression(object, nestingCounter, nestedResult); + } else if (raw instanceof _primitives.Ref) { + currentResult.push(raw.toString()); + } + } + } + async parseMarkedContentProps(contentProperties, resources) { + let optionalContent; + if (contentProperties instanceof _primitives.Name) { + const properties = resources.get("Properties"); + optionalContent = properties.get(contentProperties.name); + } else if (contentProperties instanceof _primitives.Dict) { + optionalContent = contentProperties; + } else { + throw new _util.FormatError("Optional content properties malformed."); + } + const optionalContentType = optionalContent.get("Type")?.name; + if (optionalContentType === "OCG") { + return { + type: optionalContentType, + id: optionalContent.objId + }; + } else if (optionalContentType === "OCMD") { + const expression = optionalContent.get("VE"); + if (Array.isArray(expression)) { + const result = []; + this._parseVisibilityExpression(expression, 0, result); + if (result.length > 0) { + return { + type: "OCMD", + expression: result + }; + } + } + const optionalContentGroups = optionalContent.get("OCGs"); + if (Array.isArray(optionalContentGroups) || optionalContentGroups instanceof _primitives.Dict) { + const groupIds = []; + if (Array.isArray(optionalContentGroups)) { + for (const ocg of optionalContentGroups) { + groupIds.push(ocg.toString()); + } + } else { + groupIds.push(optionalContentGroups.objId); + } + return { + type: optionalContentType, + ids: groupIds, + policy: optionalContent.get("P") instanceof _primitives.Name ? optionalContent.get("P").name : null, + expression: null + }; + } else if (optionalContentGroups instanceof _primitives.Ref) { + return { + type: optionalContentType, + id: optionalContentGroups.toString() + }; + } + } + return null; + } + getOperatorList({ + stream, + task, + resources, + operatorList, + initialState = null, + fallbackFontDict = null + }) { + resources ||= _primitives.Dict.empty; + initialState ||= new EvalState(); + if (!operatorList) { + throw new Error('getOperatorList: missing "operatorList" parameter'); + } + const self = this; + const xref = this.xref; + let parsingText = false; + const localImageCache = new _image_utils.LocalImageCache(); + const localColorSpaceCache = new _image_utils.LocalColorSpaceCache(); + const localGStateCache = new _image_utils.LocalGStateCache(); + const localTilingPatternCache = new _image_utils.LocalTilingPatternCache(); + const localShadingPatternCache = new Map(); + const xobjs = resources.get("XObject") || _primitives.Dict.empty; + const patterns = resources.get("Pattern") || _primitives.Dict.empty; + const stateManager = new StateManager(initialState); + const preprocessor = new EvaluatorPreprocessor(stream, xref, stateManager); + const timeSlotManager = new TimeSlotManager(); + function closePendingRestoreOPS(argument) { + for (let i = 0, ii = preprocessor.savedStatesDepth; i < ii; i++) { + operatorList.addOp(_util.OPS.restore, []); + } + } + return new Promise(function promiseBody(resolve, reject) { + const next = function (promise) { + Promise.all([promise, operatorList.ready]).then(function () { + try { + promiseBody(resolve, reject); + } catch (ex) { + reject(ex); + } + }, reject); + }; + task.ensureNotTerminated(); + timeSlotManager.reset(); + const operation = {}; + let stop, i, ii, cs, name, isValidName; + while (!(stop = timeSlotManager.check())) { + operation.args = null; + if (!preprocessor.read(operation)) { + break; + } + let args = operation.args; + let fn = operation.fn; + switch (fn | 0) { + case _util.OPS.paintXObject: + isValidName = args[0] instanceof _primitives.Name; + name = args[0].name; + if (isValidName) { + const localImage = localImageCache.getByName(name); + if (localImage) { + operatorList.addImageOps(localImage.fn, localImage.args, localImage.optionalContent); + incrementCachedImageMaskCount(localImage); + args = null; + continue; + } + } + next(new Promise(function (resolveXObject, rejectXObject) { + if (!isValidName) { + throw new _util.FormatError("XObject must be referred to by name."); + } + let xobj = xobjs.getRaw(name); + if (xobj instanceof _primitives.Ref) { + const localImage = localImageCache.getByRef(xobj) || self._regionalImageCache.getByRef(xobj); + if (localImage) { + operatorList.addImageOps(localImage.fn, localImage.args, localImage.optionalContent); + incrementCachedImageMaskCount(localImage); + resolveXObject(); + return; + } + const globalImage = self.globalImageCache.getData(xobj, self.pageIndex); + if (globalImage) { + operatorList.addDependency(globalImage.objId); + operatorList.addImageOps(globalImage.fn, globalImage.args, globalImage.optionalContent); + resolveXObject(); + return; + } + xobj = xref.fetch(xobj); + } + if (!(xobj instanceof _base_stream.BaseStream)) { + throw new _util.FormatError("XObject should be a stream"); + } + const type = xobj.dict.get("Subtype"); + if (!(type instanceof _primitives.Name)) { + throw new _util.FormatError("XObject should have a Name subtype"); + } + if (type.name === "Form") { + stateManager.save(); + self.buildFormXObject(resources, xobj, null, operatorList, task, stateManager.state.clone(), localColorSpaceCache).then(function () { + stateManager.restore(); + resolveXObject(); + }, rejectXObject); + return; + } else if (type.name === "Image") { + self.buildPaintImageXObject({ + resources, + image: xobj, + operatorList, + cacheKey: name, + localImageCache, + localColorSpaceCache + }).then(resolveXObject, rejectXObject); + return; + } else if (type.name === "PS") { + (0, _util.info)("Ignored XObject subtype PS"); + } else { + throw new _util.FormatError(`Unhandled XObject subtype ${type.name}`); + } + resolveXObject(); + }).catch(function (reason) { + if (reason instanceof _util.AbortException) { + return; + } + if (self.options.ignoreErrors) { + (0, _util.warn)(`getOperatorList - ignoring XObject: "${reason}".`); + return; + } + throw reason; + })); + return; + case _util.OPS.setFont: + var fontSize = args[1]; + next(self.handleSetFont(resources, args, null, operatorList, task, stateManager.state, fallbackFontDict).then(function (loadedName) { + operatorList.addDependency(loadedName); + operatorList.addOp(_util.OPS.setFont, [loadedName, fontSize]); + })); + return; + case _util.OPS.beginText: + parsingText = true; + break; + case _util.OPS.endText: + parsingText = false; + break; + case _util.OPS.endInlineImage: + var cacheKey = args[0].cacheKey; + if (cacheKey) { + const localImage = localImageCache.getByName(cacheKey); + if (localImage) { + operatorList.addImageOps(localImage.fn, localImage.args, localImage.optionalContent); + incrementCachedImageMaskCount(localImage); + args = null; + continue; + } + } + next(self.buildPaintImageXObject({ + resources, + image: args[0], + isInline: true, + operatorList, + cacheKey, + localImageCache, + localColorSpaceCache + })); + return; + case _util.OPS.showText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } + args[0] = self.handleText(args[0], stateManager.state); + break; + case _util.OPS.showSpacedText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } + var combinedGlyphs = []; + var state = stateManager.state; + for (const arrItem of args[0]) { + if (typeof arrItem === "string") { + combinedGlyphs.push(...self.handleText(arrItem, state)); + } else if (typeof arrItem === "number") { + combinedGlyphs.push(arrItem); + } + } + args[0] = combinedGlyphs; + fn = _util.OPS.showText; + break; + case _util.OPS.nextLineShowText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } + operatorList.addOp(_util.OPS.nextLine); + args[0] = self.handleText(args[0], stateManager.state); + fn = _util.OPS.showText; + break; + case _util.OPS.nextLineSetSpacingShowText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } + operatorList.addOp(_util.OPS.nextLine); + operatorList.addOp(_util.OPS.setWordSpacing, [args.shift()]); + operatorList.addOp(_util.OPS.setCharSpacing, [args.shift()]); + args[0] = self.handleText(args[0], stateManager.state); + fn = _util.OPS.showText; + break; + case _util.OPS.setTextRenderingMode: + stateManager.state.textRenderingMode = args[0]; + break; + case _util.OPS.setFillColorSpace: + { + const cachedColorSpace = _colorspace.ColorSpace.getCached(args[0], xref, localColorSpaceCache); + if (cachedColorSpace) { + stateManager.state.fillColorSpace = cachedColorSpace; + continue; + } + next(self.parseColorSpace({ + cs: args[0], + resources, + localColorSpaceCache + }).then(function (colorSpace) { + if (colorSpace) { + stateManager.state.fillColorSpace = colorSpace; + } + })); + return; + } + case _util.OPS.setStrokeColorSpace: + { + const cachedColorSpace = _colorspace.ColorSpace.getCached(args[0], xref, localColorSpaceCache); + if (cachedColorSpace) { + stateManager.state.strokeColorSpace = cachedColorSpace; + continue; + } + next(self.parseColorSpace({ + cs: args[0], + resources, + localColorSpaceCache + }).then(function (colorSpace) { + if (colorSpace) { + stateManager.state.strokeColorSpace = colorSpace; + } + })); + return; + } + case _util.OPS.setFillColor: + cs = stateManager.state.fillColorSpace; + args = cs.getRgb(args, 0); + fn = _util.OPS.setFillRGBColor; + break; + case _util.OPS.setStrokeColor: + cs = stateManager.state.strokeColorSpace; + args = cs.getRgb(args, 0); + fn = _util.OPS.setStrokeRGBColor; + break; + case _util.OPS.setFillGray: + stateManager.state.fillColorSpace = _colorspace.ColorSpace.singletons.gray; + args = _colorspace.ColorSpace.singletons.gray.getRgb(args, 0); + fn = _util.OPS.setFillRGBColor; + break; + case _util.OPS.setStrokeGray: + stateManager.state.strokeColorSpace = _colorspace.ColorSpace.singletons.gray; + args = _colorspace.ColorSpace.singletons.gray.getRgb(args, 0); + fn = _util.OPS.setStrokeRGBColor; + break; + case _util.OPS.setFillCMYKColor: + stateManager.state.fillColorSpace = _colorspace.ColorSpace.singletons.cmyk; + args = _colorspace.ColorSpace.singletons.cmyk.getRgb(args, 0); + fn = _util.OPS.setFillRGBColor; + break; + case _util.OPS.setStrokeCMYKColor: + stateManager.state.strokeColorSpace = _colorspace.ColorSpace.singletons.cmyk; + args = _colorspace.ColorSpace.singletons.cmyk.getRgb(args, 0); + fn = _util.OPS.setStrokeRGBColor; + break; + case _util.OPS.setFillRGBColor: + stateManager.state.fillColorSpace = _colorspace.ColorSpace.singletons.rgb; + args = _colorspace.ColorSpace.singletons.rgb.getRgb(args, 0); + break; + case _util.OPS.setStrokeRGBColor: + stateManager.state.strokeColorSpace = _colorspace.ColorSpace.singletons.rgb; + args = _colorspace.ColorSpace.singletons.rgb.getRgb(args, 0); + break; + case _util.OPS.setFillColorN: + cs = stateManager.state.fillColorSpace; + if (cs.name === "Pattern") { + next(self.handleColorN(operatorList, _util.OPS.setFillColorN, args, cs, patterns, resources, task, localColorSpaceCache, localTilingPatternCache, localShadingPatternCache)); + return; + } + args = cs.getRgb(args, 0); + fn = _util.OPS.setFillRGBColor; + break; + case _util.OPS.setStrokeColorN: + cs = stateManager.state.strokeColorSpace; + if (cs.name === "Pattern") { + next(self.handleColorN(operatorList, _util.OPS.setStrokeColorN, args, cs, patterns, resources, task, localColorSpaceCache, localTilingPatternCache, localShadingPatternCache)); + return; + } + args = cs.getRgb(args, 0); + fn = _util.OPS.setStrokeRGBColor; + break; + case _util.OPS.shadingFill: + var shadingRes = resources.get("Shading"); + if (!shadingRes) { + throw new _util.FormatError("No shading resource found"); + } + var shading = shadingRes.get(args[0].name); + if (!shading) { + throw new _util.FormatError("No shading object found"); + } + const patternId = self.parseShading({ + shading, + resources, + localColorSpaceCache, + localShadingPatternCache + }); + args = [patternId]; + fn = _util.OPS.shadingFill; + break; + case _util.OPS.setGState: + isValidName = args[0] instanceof _primitives.Name; + name = args[0].name; + if (isValidName) { + const localGStateObj = localGStateCache.getByName(name); + if (localGStateObj) { + if (localGStateObj.length > 0) { + operatorList.addOp(_util.OPS.setGState, [localGStateObj]); + } + args = null; + continue; + } + } + next(new Promise(function (resolveGState, rejectGState) { + if (!isValidName) { + throw new _util.FormatError("GState must be referred to by name."); + } + const extGState = resources.get("ExtGState"); + if (!(extGState instanceof _primitives.Dict)) { + throw new _util.FormatError("ExtGState should be a dictionary."); + } + const gState = extGState.get(name); + if (!(gState instanceof _primitives.Dict)) { + throw new _util.FormatError("GState should be a dictionary."); + } + self.setGState({ + resources, + gState, + operatorList, + cacheKey: name, + task, + stateManager, + localGStateCache, + localColorSpaceCache + }).then(resolveGState, rejectGState); + }).catch(function (reason) { + if (reason instanceof _util.AbortException) { + return; + } + if (self.options.ignoreErrors) { + (0, _util.warn)(`getOperatorList - ignoring ExtGState: "${reason}".`); + return; + } + throw reason; + })); + return; + case _util.OPS.moveTo: + case _util.OPS.lineTo: + case _util.OPS.curveTo: + case _util.OPS.curveTo2: + case _util.OPS.curveTo3: + case _util.OPS.closePath: + case _util.OPS.rectangle: + self.buildPath(operatorList, fn, args, parsingText); + continue; + case _util.OPS.markPoint: + case _util.OPS.markPointProps: + case _util.OPS.beginCompat: + case _util.OPS.endCompat: + continue; + case _util.OPS.beginMarkedContentProps: + if (!(args[0] instanceof _primitives.Name)) { + (0, _util.warn)(`Expected name for beginMarkedContentProps arg0=${args[0]}`); + continue; + } + if (args[0].name === "OC") { + next(self.parseMarkedContentProps(args[1], resources).then(data => { + operatorList.addOp(_util.OPS.beginMarkedContentProps, ["OC", data]); + }).catch(reason => { + if (reason instanceof _util.AbortException) { + return; + } + if (self.options.ignoreErrors) { + (0, _util.warn)(`getOperatorList - ignoring beginMarkedContentProps: "${reason}".`); + return; + } + throw reason; + })); + return; + } + args = [args[0].name, args[1] instanceof _primitives.Dict ? args[1].get("MCID") : null]; + break; + case _util.OPS.beginMarkedContent: + case _util.OPS.endMarkedContent: + default: + if (args !== null) { + for (i = 0, ii = args.length; i < ii; i++) { + if (args[i] instanceof _primitives.Dict) { + break; + } + } + if (i < ii) { + (0, _util.warn)("getOperatorList - ignoring operator: " + fn); + continue; + } + } + } + operatorList.addOp(fn, args); + } + if (stop) { + next(deferred); + return; + } + closePendingRestoreOPS(); + resolve(); + }).catch(reason => { + if (reason instanceof _util.AbortException) { + return; + } + if (this.options.ignoreErrors) { + (0, _util.warn)(`getOperatorList - ignoring errors during "${task.name}" ` + `task: "${reason}".`); + closePendingRestoreOPS(); + return; + } + throw reason; + }); + } + getTextContent({ + stream, + task, + resources, + stateManager = null, + includeMarkedContent = false, + sink, + seenStyles = new Set(), + viewBox, + markedContentData = null, + disableNormalization = false + }) { + resources ||= _primitives.Dict.empty; + stateManager ||= new StateManager(new TextState()); + if (includeMarkedContent) { + markedContentData ||= { + level: 0 + }; + } + const textContent = { + items: [], + styles: Object.create(null) + }; + const textContentItem = { + initialized: false, + str: [], + totalWidth: 0, + totalHeight: 0, + width: 0, + height: 0, + vertical: false, + prevTransform: null, + textAdvanceScale: 0, + spaceInFlowMin: 0, + spaceInFlowMax: 0, + trackingSpaceMin: Infinity, + negativeSpaceMax: -Infinity, + notASpace: -Infinity, + transform: null, + fontName: null, + hasEOL: false + }; + const twoLastChars = [" ", " "]; + let twoLastCharsPos = 0; + function saveLastChar(char) { + const nextPos = (twoLastCharsPos + 1) % 2; + const ret = twoLastChars[twoLastCharsPos] !== " " && twoLastChars[nextPos] === " "; + twoLastChars[twoLastCharsPos] = char; + twoLastCharsPos = nextPos; + return ret; + } + function shouldAddWhitepsace() { + return twoLastChars[twoLastCharsPos] !== " " && twoLastChars[(twoLastCharsPos + 1) % 2] === " "; + } + function resetLastChars() { + twoLastChars[0] = twoLastChars[1] = " "; + twoLastCharsPos = 0; + } + const TRACKING_SPACE_FACTOR = 0.102; + const NOT_A_SPACE_FACTOR = 0.03; + const NEGATIVE_SPACE_FACTOR = -0.2; + const SPACE_IN_FLOW_MIN_FACTOR = 0.102; + const SPACE_IN_FLOW_MAX_FACTOR = 0.6; + const VERTICAL_SHIFT_RATIO = 0.25; + const self = this; + const xref = this.xref; + const showSpacedTextBuffer = []; + let xobjs = null; + const emptyXObjectCache = new _image_utils.LocalImageCache(); + const emptyGStateCache = new _image_utils.LocalGStateCache(); + const preprocessor = new EvaluatorPreprocessor(stream, xref, stateManager); + let textState; + function pushWhitespace({ + width = 0, + height = 0, + transform = textContentItem.prevTransform, + fontName = textContentItem.fontName + }) { + textContent.items.push({ + str: " ", + dir: "ltr", + width, + height, + transform, + fontName, + hasEOL: false + }); + } + function getCurrentTextTransform() { + const font = textState.font; + const tsm = [textState.fontSize * textState.textHScale, 0, 0, textState.fontSize, 0, textState.textRise]; + if (font.isType3Font && (textState.fontSize <= 1 || font.isCharBBox) && !(0, _util.isArrayEqual)(textState.fontMatrix, _util.FONT_IDENTITY_MATRIX)) { + const glyphHeight = font.bbox[3] - font.bbox[1]; + if (glyphHeight > 0) { + tsm[3] *= glyphHeight * textState.fontMatrix[3]; + } + } + return _util.Util.transform(textState.ctm, _util.Util.transform(textState.textMatrix, tsm)); + } + function ensureTextContentItem() { + if (textContentItem.initialized) { + return textContentItem; + } + const { + font, + loadedName + } = textState; + if (!seenStyles.has(loadedName)) { + seenStyles.add(loadedName); + textContent.styles[loadedName] = { + fontFamily: font.fallbackName, + ascent: font.ascent, + descent: font.descent, + vertical: font.vertical + }; + } + textContentItem.fontName = loadedName; + const trm = textContentItem.transform = getCurrentTextTransform(); + if (!font.vertical) { + textContentItem.width = textContentItem.totalWidth = 0; + textContentItem.height = textContentItem.totalHeight = Math.hypot(trm[2], trm[3]); + textContentItem.vertical = false; + } else { + textContentItem.width = textContentItem.totalWidth = Math.hypot(trm[0], trm[1]); + textContentItem.height = textContentItem.totalHeight = 0; + textContentItem.vertical = true; + } + const scaleLineX = Math.hypot(textState.textLineMatrix[0], textState.textLineMatrix[1]); + const scaleCtmX = Math.hypot(textState.ctm[0], textState.ctm[1]); + textContentItem.textAdvanceScale = scaleCtmX * scaleLineX; + const { + fontSize + } = textState; + textContentItem.trackingSpaceMin = fontSize * TRACKING_SPACE_FACTOR; + textContentItem.notASpace = fontSize * NOT_A_SPACE_FACTOR; + textContentItem.negativeSpaceMax = fontSize * NEGATIVE_SPACE_FACTOR; + textContentItem.spaceInFlowMin = fontSize * SPACE_IN_FLOW_MIN_FACTOR; + textContentItem.spaceInFlowMax = fontSize * SPACE_IN_FLOW_MAX_FACTOR; + textContentItem.hasEOL = false; + textContentItem.initialized = true; + return textContentItem; + } + function updateAdvanceScale() { + if (!textContentItem.initialized) { + return; + } + const scaleLineX = Math.hypot(textState.textLineMatrix[0], textState.textLineMatrix[1]); + const scaleCtmX = Math.hypot(textState.ctm[0], textState.ctm[1]); + const scaleFactor = scaleCtmX * scaleLineX; + if (scaleFactor === textContentItem.textAdvanceScale) { + return; + } + if (!textContentItem.vertical) { + textContentItem.totalWidth += textContentItem.width * textContentItem.textAdvanceScale; + textContentItem.width = 0; + } else { + textContentItem.totalHeight += textContentItem.height * textContentItem.textAdvanceScale; + textContentItem.height = 0; + } + textContentItem.textAdvanceScale = scaleFactor; + } + function runBidiTransform(textChunk) { + let text = textChunk.str.join(""); + if (!disableNormalization) { + text = (0, _util.normalizeUnicode)(text); + } + const bidiResult = (0, _bidi.bidi)(text, -1, textChunk.vertical); + return { + str: bidiResult.str, + dir: bidiResult.dir, + width: Math.abs(textChunk.totalWidth), + height: Math.abs(textChunk.totalHeight), + transform: textChunk.transform, + fontName: textChunk.fontName, + hasEOL: textChunk.hasEOL + }; + } + function handleSetFont(fontName, fontRef) { + return self.loadFont(fontName, fontRef, resources).then(function (translated) { + if (!translated.font.isType3Font) { + return translated; + } + return translated.loadType3Data(self, resources, task).catch(function () {}).then(function () { + return translated; + }); + }).then(function (translated) { + textState.loadedName = translated.loadedName; + textState.font = translated.font; + textState.fontMatrix = translated.font.fontMatrix || _util.FONT_IDENTITY_MATRIX; + }); + } + function applyInverseRotation(x, y, matrix) { + const scale = Math.hypot(matrix[0], matrix[1]); + return [(matrix[0] * x + matrix[1] * y) / scale, (matrix[2] * x + matrix[3] * y) / scale]; + } + function compareWithLastPosition(glyphWidth) { + const currentTransform = getCurrentTextTransform(); + let posX = currentTransform[4]; + let posY = currentTransform[5]; + if (textState.font?.vertical) { + if (posX < viewBox[0] || posX > viewBox[2] || posY + glyphWidth < viewBox[1] || posY > viewBox[3]) { + return false; + } + } else if (posX + glyphWidth < viewBox[0] || posX > viewBox[2] || posY < viewBox[1] || posY > viewBox[3]) { + return false; + } + if (!textState.font || !textContentItem.prevTransform) { + return true; + } + let lastPosX = textContentItem.prevTransform[4]; + let lastPosY = textContentItem.prevTransform[5]; + if (lastPosX === posX && lastPosY === posY) { + return true; + } + let rotate = -1; + if (currentTransform[0] && currentTransform[1] === 0 && currentTransform[2] === 0) { + rotate = currentTransform[0] > 0 ? 0 : 180; + } else if (currentTransform[1] && currentTransform[0] === 0 && currentTransform[3] === 0) { + rotate = currentTransform[1] > 0 ? 90 : 270; + } + switch (rotate) { + case 0: + break; + case 90: + [posX, posY] = [posY, posX]; + [lastPosX, lastPosY] = [lastPosY, lastPosX]; + break; + case 180: + [posX, posY, lastPosX, lastPosY] = [-posX, -posY, -lastPosX, -lastPosY]; + break; + case 270: + [posX, posY] = [-posY, -posX]; + [lastPosX, lastPosY] = [-lastPosY, -lastPosX]; + break; + default: + [posX, posY] = applyInverseRotation(posX, posY, currentTransform); + [lastPosX, lastPosY] = applyInverseRotation(lastPosX, lastPosY, textContentItem.prevTransform); + } + if (textState.font.vertical) { + const advanceY = (lastPosY - posY) / textContentItem.textAdvanceScale; + const advanceX = posX - lastPosX; + const textOrientation = Math.sign(textContentItem.height); + if (advanceY < textOrientation * textContentItem.negativeSpaceMax) { + if (Math.abs(advanceX) > 0.5 * textContentItem.width) { + appendEOL(); + return true; + } + resetLastChars(); + flushTextContentItem(); + return true; + } + if (Math.abs(advanceX) > textContentItem.width) { + appendEOL(); + return true; + } + if (advanceY <= textOrientation * textContentItem.notASpace) { + resetLastChars(); + } + if (advanceY <= textOrientation * textContentItem.trackingSpaceMin) { + if (shouldAddWhitepsace()) { + resetLastChars(); + flushTextContentItem(); + pushWhitespace({ + height: Math.abs(advanceY) + }); + } else { + textContentItem.height += advanceY; + } + } else if (!addFakeSpaces(advanceY, textContentItem.prevTransform, textOrientation)) { + if (textContentItem.str.length === 0) { + resetLastChars(); + pushWhitespace({ + height: Math.abs(advanceY) + }); + } else { + textContentItem.height += advanceY; + } + } + if (Math.abs(advanceX) > textContentItem.width * VERTICAL_SHIFT_RATIO) { + flushTextContentItem(); + } + return true; + } + const advanceX = (posX - lastPosX) / textContentItem.textAdvanceScale; + const advanceY = posY - lastPosY; + const textOrientation = Math.sign(textContentItem.width); + if (advanceX < textOrientation * textContentItem.negativeSpaceMax) { + if (Math.abs(advanceY) > 0.5 * textContentItem.height) { + appendEOL(); + return true; + } + resetLastChars(); + flushTextContentItem(); + return true; + } + if (Math.abs(advanceY) > textContentItem.height) { + appendEOL(); + return true; + } + if (advanceX <= textOrientation * textContentItem.notASpace) { + resetLastChars(); + } + if (advanceX <= textOrientation * textContentItem.trackingSpaceMin) { + if (shouldAddWhitepsace()) { + resetLastChars(); + flushTextContentItem(); + pushWhitespace({ + width: Math.abs(advanceX) + }); + } else { + textContentItem.width += advanceX; + } + } else if (!addFakeSpaces(advanceX, textContentItem.prevTransform, textOrientation)) { + if (textContentItem.str.length === 0) { + resetLastChars(); + pushWhitespace({ + width: Math.abs(advanceX) + }); + } else { + textContentItem.width += advanceX; + } + } + if (Math.abs(advanceY) > textContentItem.height * VERTICAL_SHIFT_RATIO) { + flushTextContentItem(); + } + return true; + } + function buildTextContentItem({ + chars, + extraSpacing + }) { + const font = textState.font; + if (!chars) { + const charSpacing = textState.charSpacing + extraSpacing; + if (charSpacing) { + if (!font.vertical) { + textState.translateTextMatrix(charSpacing * textState.textHScale, 0); + } else { + textState.translateTextMatrix(0, -charSpacing); + } + } + return; + } + const glyphs = font.charsToGlyphs(chars); + const scale = textState.fontMatrix[0] * textState.fontSize; + for (let i = 0, ii = glyphs.length; i < ii; i++) { + const glyph = glyphs[i]; + const { + category + } = glyph; + if (category.isInvisibleFormatMark) { + continue; + } + let charSpacing = textState.charSpacing + (i + 1 === ii ? extraSpacing : 0); + let glyphWidth = glyph.width; + if (font.vertical) { + glyphWidth = glyph.vmetric ? glyph.vmetric[0] : -glyphWidth; + } + let scaledDim = glyphWidth * scale; + if (category.isWhitespace) { + if (!font.vertical) { + charSpacing += scaledDim + textState.wordSpacing; + textState.translateTextMatrix(charSpacing * textState.textHScale, 0); + } else { + charSpacing += -scaledDim + textState.wordSpacing; + textState.translateTextMatrix(0, -charSpacing); + } + saveLastChar(" "); + continue; + } + if (!category.isZeroWidthDiacritic && !compareWithLastPosition(scaledDim)) { + if (!font.vertical) { + textState.translateTextMatrix(scaledDim * textState.textHScale, 0); + } else { + textState.translateTextMatrix(0, scaledDim); + } + continue; + } + const textChunk = ensureTextContentItem(); + if (category.isZeroWidthDiacritic) { + scaledDim = 0; + } + if (!font.vertical) { + scaledDim *= textState.textHScale; + textState.translateTextMatrix(scaledDim, 0); + textChunk.width += scaledDim; + } else { + textState.translateTextMatrix(0, scaledDim); + scaledDim = Math.abs(scaledDim); + textChunk.height += scaledDim; + } + if (scaledDim) { + textChunk.prevTransform = getCurrentTextTransform(); + } + const glyphUnicode = glyph.unicode; + if (saveLastChar(glyphUnicode)) { + textChunk.str.push(" "); + } + textChunk.str.push(glyphUnicode); + if (charSpacing) { + if (!font.vertical) { + textState.translateTextMatrix(charSpacing * textState.textHScale, 0); + } else { + textState.translateTextMatrix(0, -charSpacing); + } + } + } + } + function appendEOL() { + resetLastChars(); + if (textContentItem.initialized) { + textContentItem.hasEOL = true; + flushTextContentItem(); + } else { + textContent.items.push({ + str: "", + dir: "ltr", + width: 0, + height: 0, + transform: getCurrentTextTransform(), + fontName: textState.loadedName, + hasEOL: true + }); + } + } + function addFakeSpaces(width, transf, textOrientation) { + if (textOrientation * textContentItem.spaceInFlowMin <= width && width <= textOrientation * textContentItem.spaceInFlowMax) { + if (textContentItem.initialized) { + resetLastChars(); + textContentItem.str.push(" "); + } + return false; + } + const fontName = textContentItem.fontName; + let height = 0; + if (textContentItem.vertical) { + height = width; + width = 0; + } + flushTextContentItem(); + resetLastChars(); + pushWhitespace({ + width: Math.abs(width), + height: Math.abs(height), + transform: transf || getCurrentTextTransform(), + fontName + }); + return true; + } + function flushTextContentItem() { + if (!textContentItem.initialized || !textContentItem.str) { + return; + } + if (!textContentItem.vertical) { + textContentItem.totalWidth += textContentItem.width * textContentItem.textAdvanceScale; + } else { + textContentItem.totalHeight += textContentItem.height * textContentItem.textAdvanceScale; + } + textContent.items.push(runBidiTransform(textContentItem)); + textContentItem.initialized = false; + textContentItem.str.length = 0; + } + function enqueueChunk(batch = false) { + const length = textContent.items.length; + if (length === 0) { + return; + } + if (batch && length < TEXT_CHUNK_BATCH_SIZE) { + return; + } + sink.enqueue(textContent, length); + textContent.items = []; + textContent.styles = Object.create(null); + } + const timeSlotManager = new TimeSlotManager(); + return new Promise(function promiseBody(resolve, reject) { + const next = function (promise) { + enqueueChunk(true); + Promise.all([promise, sink.ready]).then(function () { + try { + promiseBody(resolve, reject); + } catch (ex) { + reject(ex); + } + }, reject); + }; + task.ensureNotTerminated(); + timeSlotManager.reset(); + const operation = {}; + let stop, + args = []; + while (!(stop = timeSlotManager.check())) { + args.length = 0; + operation.args = args; + if (!preprocessor.read(operation)) { + break; + } + const previousState = textState; + textState = stateManager.state; + const fn = operation.fn; + args = operation.args; + switch (fn | 0) { + case _util.OPS.setFont: + var fontNameArg = args[0].name, + fontSizeArg = args[1]; + if (textState.font && fontNameArg === textState.fontName && fontSizeArg === textState.fontSize) { + break; + } + flushTextContentItem(); + textState.fontName = fontNameArg; + textState.fontSize = fontSizeArg; + next(handleSetFont(fontNameArg, null)); + return; + case _util.OPS.setTextRise: + textState.textRise = args[0]; + break; + case _util.OPS.setHScale: + textState.textHScale = args[0] / 100; + break; + case _util.OPS.setLeading: + textState.leading = args[0]; + break; + case _util.OPS.moveText: + textState.translateTextLineMatrix(args[0], args[1]); + textState.textMatrix = textState.textLineMatrix.slice(); + break; + case _util.OPS.setLeadingMoveText: + textState.leading = -args[1]; + textState.translateTextLineMatrix(args[0], args[1]); + textState.textMatrix = textState.textLineMatrix.slice(); + break; + case _util.OPS.nextLine: + textState.carriageReturn(); + break; + case _util.OPS.setTextMatrix: + textState.setTextMatrix(args[0], args[1], args[2], args[3], args[4], args[5]); + textState.setTextLineMatrix(args[0], args[1], args[2], args[3], args[4], args[5]); + updateAdvanceScale(); + break; + case _util.OPS.setCharSpacing: + textState.charSpacing = args[0]; + break; + case _util.OPS.setWordSpacing: + textState.wordSpacing = args[0]; + break; + case _util.OPS.beginText: + textState.textMatrix = _util.IDENTITY_MATRIX.slice(); + textState.textLineMatrix = _util.IDENTITY_MATRIX.slice(); + break; + case _util.OPS.showSpacedText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } + const spaceFactor = (textState.font.vertical ? 1 : -1) * textState.fontSize / 1000; + const elements = args[0]; + for (let i = 0, ii = elements.length; i < ii; i++) { + const item = elements[i]; + if (typeof item === "string") { + showSpacedTextBuffer.push(item); + } else if (typeof item === "number" && item !== 0) { + const str = showSpacedTextBuffer.join(""); + showSpacedTextBuffer.length = 0; + buildTextContentItem({ + chars: str, + extraSpacing: item * spaceFactor + }); + } + } + if (showSpacedTextBuffer.length > 0) { + const str = showSpacedTextBuffer.join(""); + showSpacedTextBuffer.length = 0; + buildTextContentItem({ + chars: str, + extraSpacing: 0 + }); + } + break; + case _util.OPS.showText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } + buildTextContentItem({ + chars: args[0], + extraSpacing: 0 + }); + break; + case _util.OPS.nextLineShowText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } + textState.carriageReturn(); + buildTextContentItem({ + chars: args[0], + extraSpacing: 0 + }); + break; + case _util.OPS.nextLineSetSpacingShowText: + if (!stateManager.state.font) { + self.ensureStateFont(stateManager.state); + continue; + } + textState.wordSpacing = args[0]; + textState.charSpacing = args[1]; + textState.carriageReturn(); + buildTextContentItem({ + chars: args[2], + extraSpacing: 0 + }); + break; + case _util.OPS.paintXObject: + flushTextContentItem(); + if (!xobjs) { + xobjs = resources.get("XObject") || _primitives.Dict.empty; + } + var isValidName = args[0] instanceof _primitives.Name; + var name = args[0].name; + if (isValidName && emptyXObjectCache.getByName(name)) { + break; + } + next(new Promise(function (resolveXObject, rejectXObject) { + if (!isValidName) { + throw new _util.FormatError("XObject must be referred to by name."); + } + let xobj = xobjs.getRaw(name); + if (xobj instanceof _primitives.Ref) { + if (emptyXObjectCache.getByRef(xobj)) { + resolveXObject(); + return; + } + const globalImage = self.globalImageCache.getData(xobj, self.pageIndex); + if (globalImage) { + resolveXObject(); + return; + } + xobj = xref.fetch(xobj); + } + if (!(xobj instanceof _base_stream.BaseStream)) { + throw new _util.FormatError("XObject should be a stream"); + } + const type = xobj.dict.get("Subtype"); + if (!(type instanceof _primitives.Name)) { + throw new _util.FormatError("XObject should have a Name subtype"); + } + if (type.name !== "Form") { + emptyXObjectCache.set(name, xobj.dict.objId, true); + resolveXObject(); + return; + } + const currentState = stateManager.state.clone(); + const xObjStateManager = new StateManager(currentState); + const matrix = xobj.dict.getArray("Matrix"); + if (Array.isArray(matrix) && matrix.length === 6) { + xObjStateManager.transform(matrix); + } + enqueueChunk(); + const sinkWrapper = { + enqueueInvoked: false, + enqueue(chunk, size) { + this.enqueueInvoked = true; + sink.enqueue(chunk, size); + }, + get desiredSize() { + return sink.desiredSize; + }, + get ready() { + return sink.ready; + } + }; + self.getTextContent({ + stream: xobj, + task, + resources: xobj.dict.get("Resources") || resources, + stateManager: xObjStateManager, + includeMarkedContent, + sink: sinkWrapper, + seenStyles, + viewBox, + markedContentData, + disableNormalization + }).then(function () { + if (!sinkWrapper.enqueueInvoked) { + emptyXObjectCache.set(name, xobj.dict.objId, true); + } + resolveXObject(); + }, rejectXObject); + }).catch(function (reason) { + if (reason instanceof _util.AbortException) { + return; + } + if (self.options.ignoreErrors) { + (0, _util.warn)(`getTextContent - ignoring XObject: "${reason}".`); + return; + } + throw reason; + })); + return; + case _util.OPS.setGState: + isValidName = args[0] instanceof _primitives.Name; + name = args[0].name; + if (isValidName && emptyGStateCache.getByName(name)) { + break; + } + next(new Promise(function (resolveGState, rejectGState) { + if (!isValidName) { + throw new _util.FormatError("GState must be referred to by name."); + } + const extGState = resources.get("ExtGState"); + if (!(extGState instanceof _primitives.Dict)) { + throw new _util.FormatError("ExtGState should be a dictionary."); + } + const gState = extGState.get(name); + if (!(gState instanceof _primitives.Dict)) { + throw new _util.FormatError("GState should be a dictionary."); + } + const gStateFont = gState.get("Font"); + if (!gStateFont) { + emptyGStateCache.set(name, gState.objId, true); + resolveGState(); + return; + } + flushTextContentItem(); + textState.fontName = null; + textState.fontSize = gStateFont[1]; + handleSetFont(null, gStateFont[0]).then(resolveGState, rejectGState); + }).catch(function (reason) { + if (reason instanceof _util.AbortException) { + return; + } + if (self.options.ignoreErrors) { + (0, _util.warn)(`getTextContent - ignoring ExtGState: "${reason}".`); + return; + } + throw reason; + })); + return; + case _util.OPS.beginMarkedContent: + flushTextContentItem(); + if (includeMarkedContent) { + markedContentData.level++; + textContent.items.push({ + type: "beginMarkedContent", + tag: args[0] instanceof _primitives.Name ? args[0].name : null + }); + } + break; + case _util.OPS.beginMarkedContentProps: + flushTextContentItem(); + if (includeMarkedContent) { + markedContentData.level++; + let mcid = null; + if (args[1] instanceof _primitives.Dict) { + mcid = args[1].get("MCID"); + } + textContent.items.push({ + type: "beginMarkedContentProps", + id: Number.isInteger(mcid) ? `${self.idFactory.getPageObjId()}_mc${mcid}` : null, + tag: args[0] instanceof _primitives.Name ? args[0].name : null + }); + } + break; + case _util.OPS.endMarkedContent: + flushTextContentItem(); + if (includeMarkedContent) { + if (markedContentData.level === 0) { + break; + } + markedContentData.level--; + textContent.items.push({ + type: "endMarkedContent" + }); + } + break; + case _util.OPS.restore: + if (previousState && (previousState.font !== textState.font || previousState.fontSize !== textState.fontSize || previousState.fontName !== textState.fontName)) { + flushTextContentItem(); + } + break; + } + if (textContent.items.length >= sink.desiredSize) { + stop = true; + break; + } + } + if (stop) { + next(deferred); + return; + } + flushTextContentItem(); + enqueueChunk(); + resolve(); + }).catch(reason => { + if (reason instanceof _util.AbortException) { + return; + } + if (this.options.ignoreErrors) { + (0, _util.warn)(`getTextContent - ignoring errors during "${task.name}" ` + `task: "${reason}".`); + flushTextContentItem(); + enqueueChunk(); + return; + } + throw reason; + }); + } + extractDataStructures(dict, baseDict, properties) { + const xref = this.xref; + let cidToGidBytes; + const toUnicodePromise = this.readToUnicode(properties.toUnicode || dict.get("ToUnicode") || baseDict.get("ToUnicode")); + if (properties.composite) { + const cidSystemInfo = dict.get("CIDSystemInfo"); + if (cidSystemInfo instanceof _primitives.Dict) { + properties.cidSystemInfo = { + registry: (0, _util.stringToPDFString)(cidSystemInfo.get("Registry")), + ordering: (0, _util.stringToPDFString)(cidSystemInfo.get("Ordering")), + supplement: cidSystemInfo.get("Supplement") + }; + } + try { + const cidToGidMap = dict.get("CIDToGIDMap"); + if (cidToGidMap instanceof _base_stream.BaseStream) { + cidToGidBytes = cidToGidMap.getBytes(); + } + } catch (ex) { + if (!this.options.ignoreErrors) { + throw ex; + } + (0, _util.warn)(`extractDataStructures - ignoring CIDToGIDMap data: "${ex}".`); + } + } + const differences = []; + let baseEncodingName = null; + let encoding; + if (dict.has("Encoding")) { + encoding = dict.get("Encoding"); + if (encoding instanceof _primitives.Dict) { + baseEncodingName = encoding.get("BaseEncoding"); + baseEncodingName = baseEncodingName instanceof _primitives.Name ? baseEncodingName.name : null; + if (encoding.has("Differences")) { + const diffEncoding = encoding.get("Differences"); + let index = 0; + for (const entry of diffEncoding) { + const data = xref.fetchIfRef(entry); + if (typeof data === "number") { + index = data; + } else if (data instanceof _primitives.Name) { + differences[index++] = data.name; + } else { + throw new _util.FormatError(`Invalid entry in 'Differences' array: ${data}`); + } + } + } + } else if (encoding instanceof _primitives.Name) { + baseEncodingName = encoding.name; + } else { + const msg = "Encoding is not a Name nor a Dict"; + if (!this.options.ignoreErrors) { + throw new _util.FormatError(msg); + } + (0, _util.warn)(msg); + } + if (baseEncodingName !== "MacRomanEncoding" && baseEncodingName !== "MacExpertEncoding" && baseEncodingName !== "WinAnsiEncoding") { + baseEncodingName = null; + } + } + const nonEmbeddedFont = !properties.file || properties.isInternalFont, + isSymbolsFontName = (0, _standard_fonts.getSymbolsFonts)()[properties.name]; + if (baseEncodingName && nonEmbeddedFont && isSymbolsFontName) { + baseEncodingName = null; + } + if (baseEncodingName) { + properties.defaultEncoding = (0, _encodings.getEncoding)(baseEncodingName); + } else { + const isSymbolicFont = !!(properties.flags & _fonts_utils.FontFlags.Symbolic); + const isNonsymbolicFont = !!(properties.flags & _fonts_utils.FontFlags.Nonsymbolic); + encoding = _encodings.StandardEncoding; + if (properties.type === "TrueType" && !isNonsymbolicFont) { + encoding = _encodings.WinAnsiEncoding; + } + if (isSymbolicFont || isSymbolsFontName) { + encoding = _encodings.MacRomanEncoding; + if (nonEmbeddedFont) { + if (/Symbol/i.test(properties.name)) { + encoding = _encodings.SymbolSetEncoding; + } else if (/Dingbats/i.test(properties.name)) { + encoding = _encodings.ZapfDingbatsEncoding; + } else if (/Wingdings/i.test(properties.name)) { + encoding = _encodings.WinAnsiEncoding; + } + } + } + properties.defaultEncoding = encoding; + } + properties.differences = differences; + properties.baseEncodingName = baseEncodingName; + properties.hasEncoding = !!baseEncodingName || differences.length > 0; + properties.dict = dict; + return toUnicodePromise.then(readToUnicode => { + properties.toUnicode = readToUnicode; + return this.buildToUnicode(properties); + }).then(builtToUnicode => { + properties.toUnicode = builtToUnicode; + if (cidToGidBytes) { + properties.cidToGidMap = this.readCidToGidMap(cidToGidBytes, builtToUnicode); + } + return properties; + }); + } + _simpleFontToUnicode(properties, forceGlyphs = false) { + (0, _util.assert)(!properties.composite, "Must be a simple font."); + const toUnicode = []; + const encoding = properties.defaultEncoding.slice(); + const baseEncodingName = properties.baseEncodingName; + const differences = properties.differences; + for (const charcode in differences) { + const glyphName = differences[charcode]; + if (glyphName === ".notdef") { + continue; + } + encoding[charcode] = glyphName; + } + const glyphsUnicodeMap = (0, _glyphlist.getGlyphsUnicode)(); + for (const charcode in encoding) { + let glyphName = encoding[charcode]; + if (glyphName === "") { + continue; + } + let unicode = glyphsUnicodeMap[glyphName]; + if (unicode !== undefined) { + toUnicode[charcode] = String.fromCharCode(unicode); + continue; + } + let code = 0; + switch (glyphName[0]) { + case "G": + if (glyphName.length === 3) { + code = parseInt(glyphName.substring(1), 16); + } + break; + case "g": + if (glyphName.length === 5) { + code = parseInt(glyphName.substring(1), 16); + } + break; + case "C": + case "c": + if (glyphName.length >= 3 && glyphName.length <= 4) { + const codeStr = glyphName.substring(1); + if (forceGlyphs) { + code = parseInt(codeStr, 16); + break; + } + code = +codeStr; + if (Number.isNaN(code) && Number.isInteger(parseInt(codeStr, 16))) { + return this._simpleFontToUnicode(properties, true); + } + } + break; + case "u": + unicode = (0, _unicode.getUnicodeForGlyph)(glyphName, glyphsUnicodeMap); + if (unicode !== -1) { + code = unicode; + } + break; + default: + switch (glyphName) { + case "f_h": + case "f_t": + case "T_h": + toUnicode[charcode] = glyphName.replaceAll("_", ""); + continue; + } + break; + } + if (code > 0 && code <= 0x10ffff && Number.isInteger(code)) { + if (baseEncodingName && code === +charcode) { + const baseEncoding = (0, _encodings.getEncoding)(baseEncodingName); + if (baseEncoding && (glyphName = baseEncoding[charcode])) { + toUnicode[charcode] = String.fromCharCode(glyphsUnicodeMap[glyphName]); + continue; + } + } + toUnicode[charcode] = String.fromCodePoint(code); + } + } + return toUnicode; + } + async buildToUnicode(properties) { + properties.hasIncludedToUnicodeMap = properties.toUnicode?.length > 0; + if (properties.hasIncludedToUnicodeMap) { + if (!properties.composite && properties.hasEncoding) { + properties.fallbackToUnicode = this._simpleFontToUnicode(properties); + } + return properties.toUnicode; + } + if (!properties.composite) { + return new _to_unicode_map.ToUnicodeMap(this._simpleFontToUnicode(properties)); + } + if (properties.composite && (properties.cMap.builtInCMap && !(properties.cMap instanceof _cmap.IdentityCMap) || properties.cidSystemInfo.registry === "Adobe" && (properties.cidSystemInfo.ordering === "GB1" || properties.cidSystemInfo.ordering === "CNS1" || properties.cidSystemInfo.ordering === "Japan1" || properties.cidSystemInfo.ordering === "Korea1"))) { + const { + registry, + ordering + } = properties.cidSystemInfo; + const ucs2CMapName = _primitives.Name.get(`${registry}-${ordering}-UCS2`); + const ucs2CMap = await _cmap.CMapFactory.create({ + encoding: ucs2CMapName, + fetchBuiltInCMap: this._fetchBuiltInCMapBound, + useCMap: null + }); + const toUnicode = [], + buf = []; + properties.cMap.forEach(function (charcode, cid) { + if (cid > 0xffff) { + throw new _util.FormatError("Max size of CID is 65,535"); + } + const ucs2 = ucs2CMap.lookup(cid); + if (ucs2) { + buf.length = 0; + for (let i = 0, ii = ucs2.length; i < ii; i += 2) { + buf.push((ucs2.charCodeAt(i) << 8) + ucs2.charCodeAt(i + 1)); + } + toUnicode[charcode] = String.fromCharCode(...buf); + } + }); + return new _to_unicode_map.ToUnicodeMap(toUnicode); + } + return new _to_unicode_map.IdentityToUnicodeMap(properties.firstChar, properties.lastChar); + } + readToUnicode(cmapObj) { + if (!cmapObj) { + return Promise.resolve(null); + } + if (cmapObj instanceof _primitives.Name) { + return _cmap.CMapFactory.create({ + encoding: cmapObj, + fetchBuiltInCMap: this._fetchBuiltInCMapBound, + useCMap: null + }).then(function (cmap) { + if (cmap instanceof _cmap.IdentityCMap) { + return new _to_unicode_map.IdentityToUnicodeMap(0, 0xffff); + } + return new _to_unicode_map.ToUnicodeMap(cmap.getMap()); + }); + } else if (cmapObj instanceof _base_stream.BaseStream) { + return _cmap.CMapFactory.create({ + encoding: cmapObj, + fetchBuiltInCMap: this._fetchBuiltInCMapBound, + useCMap: null + }).then(function (cmap) { + if (cmap instanceof _cmap.IdentityCMap) { + return new _to_unicode_map.IdentityToUnicodeMap(0, 0xffff); + } + const map = new Array(cmap.length); + cmap.forEach(function (charCode, token) { + if (typeof token === "number") { + map[charCode] = String.fromCodePoint(token); + return; + } + const str = []; + for (let k = 0; k < token.length; k += 2) { + const w1 = token.charCodeAt(k) << 8 | token.charCodeAt(k + 1); + if ((w1 & 0xf800) !== 0xd800) { + str.push(w1); + continue; + } + k += 2; + const w2 = token.charCodeAt(k) << 8 | token.charCodeAt(k + 1); + str.push(((w1 & 0x3ff) << 10) + (w2 & 0x3ff) + 0x10000); + } + map[charCode] = String.fromCodePoint(...str); + }); + return new _to_unicode_map.ToUnicodeMap(map); + }, reason => { + if (reason instanceof _util.AbortException) { + return null; + } + if (this.options.ignoreErrors) { + (0, _util.warn)(`readToUnicode - ignoring ToUnicode data: "${reason}".`); + return null; + } + throw reason; + }); + } + return Promise.resolve(null); + } + readCidToGidMap(glyphsData, toUnicode) { + const result = []; + for (let j = 0, jj = glyphsData.length; j < jj; j++) { + const glyphID = glyphsData[j++] << 8 | glyphsData[j]; + const code = j >> 1; + if (glyphID === 0 && !toUnicode.has(code)) { + continue; + } + result[code] = glyphID; + } + return result; + } + extractWidths(dict, descriptor, properties) { + const xref = this.xref; + let glyphsWidths = []; + let defaultWidth = 0; + const glyphsVMetrics = []; + let defaultVMetrics; + let i, ii, j, jj, start, code, widths; + if (properties.composite) { + defaultWidth = dict.has("DW") ? dict.get("DW") : 1000; + widths = dict.get("W"); + if (widths) { + for (i = 0, ii = widths.length; i < ii; i++) { + start = xref.fetchIfRef(widths[i++]); + code = xref.fetchIfRef(widths[i]); + if (Array.isArray(code)) { + for (j = 0, jj = code.length; j < jj; j++) { + glyphsWidths[start++] = xref.fetchIfRef(code[j]); + } + } else { + const width = xref.fetchIfRef(widths[++i]); + for (j = start; j <= code; j++) { + glyphsWidths[j] = width; + } + } + } + } + if (properties.vertical) { + let vmetrics = dict.getArray("DW2") || [880, -1000]; + defaultVMetrics = [vmetrics[1], defaultWidth * 0.5, vmetrics[0]]; + vmetrics = dict.get("W2"); + if (vmetrics) { + for (i = 0, ii = vmetrics.length; i < ii; i++) { + start = xref.fetchIfRef(vmetrics[i++]); + code = xref.fetchIfRef(vmetrics[i]); + if (Array.isArray(code)) { + for (j = 0, jj = code.length; j < jj; j++) { + glyphsVMetrics[start++] = [xref.fetchIfRef(code[j++]), xref.fetchIfRef(code[j++]), xref.fetchIfRef(code[j])]; + } + } else { + const vmetric = [xref.fetchIfRef(vmetrics[++i]), xref.fetchIfRef(vmetrics[++i]), xref.fetchIfRef(vmetrics[++i])]; + for (j = start; j <= code; j++) { + glyphsVMetrics[j] = vmetric; + } + } + } + } + } + } else { + const firstChar = properties.firstChar; + widths = dict.get("Widths"); + if (widths) { + j = firstChar; + for (i = 0, ii = widths.length; i < ii; i++) { + glyphsWidths[j++] = xref.fetchIfRef(widths[i]); + } + defaultWidth = parseFloat(descriptor.get("MissingWidth")) || 0; + } else { + const baseFontName = dict.get("BaseFont"); + if (baseFontName instanceof _primitives.Name) { + const metrics = this.getBaseFontMetrics(baseFontName.name); + glyphsWidths = this.buildCharCodeToWidth(metrics.widths, properties); + defaultWidth = metrics.defaultWidth; + } + } + } + let isMonospace = true; + let firstWidth = defaultWidth; + for (const glyph in glyphsWidths) { + const glyphWidth = glyphsWidths[glyph]; + if (!glyphWidth) { + continue; + } + if (!firstWidth) { + firstWidth = glyphWidth; + continue; + } + if (firstWidth !== glyphWidth) { + isMonospace = false; + break; + } + } + if (isMonospace) { + properties.flags |= _fonts_utils.FontFlags.FixedPitch; + } else { + properties.flags &= ~_fonts_utils.FontFlags.FixedPitch; + } + properties.defaultWidth = defaultWidth; + properties.widths = glyphsWidths; + properties.defaultVMetrics = defaultVMetrics; + properties.vmetrics = glyphsVMetrics; + } + isSerifFont(baseFontName) { + const fontNameWoStyle = baseFontName.split("-")[0]; + return fontNameWoStyle in (0, _standard_fonts.getSerifFonts)() || /serif/gi.test(fontNameWoStyle); + } + getBaseFontMetrics(name) { + let defaultWidth = 0; + let widths = Object.create(null); + let monospace = false; + const stdFontMap = (0, _standard_fonts.getStdFontMap)(); + let lookupName = stdFontMap[name] || name; + const Metrics = (0, _metrics.getMetrics)(); + if (!(lookupName in Metrics)) { + lookupName = this.isSerifFont(name) ? "Times-Roman" : "Helvetica"; + } + const glyphWidths = Metrics[lookupName]; + if (typeof glyphWidths === "number") { + defaultWidth = glyphWidths; + monospace = true; + } else { + widths = glyphWidths(); + } + return { + defaultWidth, + monospace, + widths + }; + } + buildCharCodeToWidth(widthsByGlyphName, properties) { + const widths = Object.create(null); + const differences = properties.differences; + const encoding = properties.defaultEncoding; + for (let charCode = 0; charCode < 256; charCode++) { + if (charCode in differences && widthsByGlyphName[differences[charCode]]) { + widths[charCode] = widthsByGlyphName[differences[charCode]]; + continue; + } + if (charCode in encoding && widthsByGlyphName[encoding[charCode]]) { + widths[charCode] = widthsByGlyphName[encoding[charCode]]; + continue; + } + } + return widths; + } + preEvaluateFont(dict) { + const baseDict = dict; + let type = dict.get("Subtype"); + if (!(type instanceof _primitives.Name)) { + throw new _util.FormatError("invalid font Subtype"); + } + let composite = false; + let hash, toUnicode; + if (type.name === "Type0") { + const df = dict.get("DescendantFonts"); + if (!df) { + throw new _util.FormatError("Descendant fonts are not specified"); + } + dict = Array.isArray(df) ? this.xref.fetchIfRef(df[0]) : df; + if (!(dict instanceof _primitives.Dict)) { + throw new _util.FormatError("Descendant font is not a dictionary."); + } + type = dict.get("Subtype"); + if (!(type instanceof _primitives.Name)) { + throw new _util.FormatError("invalid font Subtype"); + } + composite = true; + } + const firstChar = dict.get("FirstChar") || 0, + lastChar = dict.get("LastChar") || (composite ? 0xffff : 0xff); + const descriptor = dict.get("FontDescriptor"); + if (descriptor) { + hash = new _murmurhash.MurmurHash3_64(); + const encoding = baseDict.getRaw("Encoding"); + if (encoding instanceof _primitives.Name) { + hash.update(encoding.name); + } else if (encoding instanceof _primitives.Ref) { + hash.update(encoding.toString()); + } else if (encoding instanceof _primitives.Dict) { + for (const entry of encoding.getRawValues()) { + if (entry instanceof _primitives.Name) { + hash.update(entry.name); + } else if (entry instanceof _primitives.Ref) { + hash.update(entry.toString()); + } else if (Array.isArray(entry)) { + const diffLength = entry.length, + diffBuf = new Array(diffLength); + for (let j = 0; j < diffLength; j++) { + const diffEntry = entry[j]; + if (diffEntry instanceof _primitives.Name) { + diffBuf[j] = diffEntry.name; + } else if (typeof diffEntry === "number" || diffEntry instanceof _primitives.Ref) { + diffBuf[j] = diffEntry.toString(); + } + } + hash.update(diffBuf.join()); + } + } + } + hash.update(`${firstChar}-${lastChar}`); + toUnicode = dict.get("ToUnicode") || baseDict.get("ToUnicode"); + if (toUnicode instanceof _base_stream.BaseStream) { + const stream = toUnicode.str || toUnicode; + const uint8array = stream.buffer ? new Uint8Array(stream.buffer.buffer, 0, stream.bufferLength) : new Uint8Array(stream.bytes.buffer, stream.start, stream.end - stream.start); + hash.update(uint8array); + } else if (toUnicode instanceof _primitives.Name) { + hash.update(toUnicode.name); + } + const widths = dict.get("Widths") || baseDict.get("Widths"); + if (Array.isArray(widths)) { + const widthsBuf = []; + for (const entry of widths) { + if (typeof entry === "number" || entry instanceof _primitives.Ref) { + widthsBuf.push(entry.toString()); + } + } + hash.update(widthsBuf.join()); + } + if (composite) { + hash.update("compositeFont"); + const compositeWidths = dict.get("W") || baseDict.get("W"); + if (Array.isArray(compositeWidths)) { + const widthsBuf = []; + for (const entry of compositeWidths) { + if (typeof entry === "number" || entry instanceof _primitives.Ref) { + widthsBuf.push(entry.toString()); + } else if (Array.isArray(entry)) { + const subWidthsBuf = []; + for (const element of entry) { + if (typeof element === "number" || element instanceof _primitives.Ref) { + subWidthsBuf.push(element.toString()); + } + } + widthsBuf.push(`[${subWidthsBuf.join()}]`); + } + } + hash.update(widthsBuf.join()); + } + const cidToGidMap = dict.getRaw("CIDToGIDMap") || baseDict.getRaw("CIDToGIDMap"); + if (cidToGidMap instanceof _primitives.Name) { + hash.update(cidToGidMap.name); + } else if (cidToGidMap instanceof _primitives.Ref) { + hash.update(cidToGidMap.toString()); + } else if (cidToGidMap instanceof _base_stream.BaseStream) { + hash.update(cidToGidMap.peekBytes()); + } + } + } + return { + descriptor, + dict, + baseDict, + composite, + type: type.name, + firstChar, + lastChar, + toUnicode, + hash: hash ? hash.hexdigest() : "" + }; + } + async translateFont({ + descriptor, + dict, + baseDict, + composite, + type, + firstChar, + lastChar, + toUnicode, + cssFontInfo + }) { + const isType3Font = type === "Type3"; + let properties; + if (!descriptor) { + if (isType3Font) { + descriptor = new _primitives.Dict(null); + descriptor.set("FontName", _primitives.Name.get(type)); + descriptor.set("FontBBox", dict.getArray("FontBBox") || [0, 0, 0, 0]); + } else { + let baseFontName = dict.get("BaseFont"); + if (!(baseFontName instanceof _primitives.Name)) { + throw new _util.FormatError("Base font is not specified"); + } + baseFontName = baseFontName.name.replaceAll(/[,_]/g, "-"); + const metrics = this.getBaseFontMetrics(baseFontName); + const fontNameWoStyle = baseFontName.split("-")[0]; + const flags = (this.isSerifFont(fontNameWoStyle) ? _fonts_utils.FontFlags.Serif : 0) | (metrics.monospace ? _fonts_utils.FontFlags.FixedPitch : 0) | ((0, _standard_fonts.getSymbolsFonts)()[fontNameWoStyle] ? _fonts_utils.FontFlags.Symbolic : _fonts_utils.FontFlags.Nonsymbolic); + properties = { + type, + name: baseFontName, + loadedName: baseDict.loadedName, + systemFontInfo: null, + widths: metrics.widths, + defaultWidth: metrics.defaultWidth, + isSimulatedFlags: true, + flags, + firstChar, + lastChar, + toUnicode, + xHeight: 0, + capHeight: 0, + italicAngle: 0, + isType3Font + }; + const widths = dict.get("Widths"); + const standardFontName = (0, _standard_fonts.getStandardFontName)(baseFontName); + let file = null; + if (standardFontName) { + file = await this.fetchStandardFontData(standardFontName); + properties.isInternalFont = !!file; + } + if (!properties.isInternalFont && this.options.useSystemFonts) { + properties.systemFontInfo = (0, _font_substitutions.getFontSubstitution)(this.systemFontCache, this.idFactory, this.options.standardFontDataUrl, baseFontName, standardFontName); + } + return this.extractDataStructures(dict, dict, properties).then(newProperties => { + if (widths) { + const glyphWidths = []; + let j = firstChar; + for (const width of widths) { + glyphWidths[j++] = this.xref.fetchIfRef(width); + } + newProperties.widths = glyphWidths; + } else { + newProperties.widths = this.buildCharCodeToWidth(metrics.widths, newProperties); + } + return new _fonts.Font(baseFontName, file, newProperties); + }); + } + } + let fontName = descriptor.get("FontName"); + let baseFont = dict.get("BaseFont"); + if (typeof fontName === "string") { + fontName = _primitives.Name.get(fontName); + } + if (typeof baseFont === "string") { + baseFont = _primitives.Name.get(baseFont); + } + const fontNameStr = fontName?.name; + const baseFontStr = baseFont?.name; + if (!isType3Font && fontNameStr !== baseFontStr) { + (0, _util.info)(`The FontDescriptor's FontName is "${fontNameStr}" but ` + `should be the same as the Font's BaseFont "${baseFontStr}".`); + if (fontNameStr && baseFontStr && (baseFontStr.startsWith(fontNameStr) || !(0, _standard_fonts.isKnownFontName)(fontNameStr) && (0, _standard_fonts.isKnownFontName)(baseFontStr))) { + fontName = null; + } + } + fontName ||= baseFont; + if (!(fontName instanceof _primitives.Name)) { + throw new _util.FormatError("invalid font name"); + } + let fontFile, subtype, length1, length2, length3; + try { + fontFile = descriptor.get("FontFile", "FontFile2", "FontFile3"); + } catch (ex) { + if (!this.options.ignoreErrors) { + throw ex; + } + (0, _util.warn)(`translateFont - fetching "${fontName.name}" font file: "${ex}".`); + fontFile = new _stream.NullStream(); + } + let isInternalFont = false; + let glyphScaleFactors = null; + let systemFontInfo = null; + if (fontFile) { + if (fontFile.dict) { + const subtypeEntry = fontFile.dict.get("Subtype"); + if (subtypeEntry instanceof _primitives.Name) { + subtype = subtypeEntry.name; + } + length1 = fontFile.dict.get("Length1"); + length2 = fontFile.dict.get("Length2"); + length3 = fontFile.dict.get("Length3"); + } + } else if (cssFontInfo) { + const standardFontName = (0, _xfa_fonts.getXfaFontName)(fontName.name); + if (standardFontName) { + cssFontInfo.fontFamily = `${cssFontInfo.fontFamily}-PdfJS-XFA`; + cssFontInfo.metrics = standardFontName.metrics || null; + glyphScaleFactors = standardFontName.factors || null; + fontFile = await this.fetchStandardFontData(standardFontName.name); + isInternalFont = !!fontFile; + baseDict = dict = (0, _xfa_fonts.getXfaFontDict)(fontName.name); + composite = true; + } + } else if (!isType3Font) { + const standardFontName = (0, _standard_fonts.getStandardFontName)(fontName.name); + if (standardFontName) { + fontFile = await this.fetchStandardFontData(standardFontName); + isInternalFont = !!fontFile; + } + if (!isInternalFont && this.options.useSystemFonts) { + systemFontInfo = (0, _font_substitutions.getFontSubstitution)(this.systemFontCache, this.idFactory, this.options.standardFontDataUrl, fontName.name, standardFontName); + } + } + properties = { + type, + name: fontName.name, + subtype, + file: fontFile, + length1, + length2, + length3, + isInternalFont, + loadedName: baseDict.loadedName, + composite, + fixedPitch: false, + fontMatrix: dict.getArray("FontMatrix") || _util.FONT_IDENTITY_MATRIX, + firstChar, + lastChar, + toUnicode, + bbox: descriptor.getArray("FontBBox") || dict.getArray("FontBBox"), + ascent: descriptor.get("Ascent"), + descent: descriptor.get("Descent"), + xHeight: descriptor.get("XHeight") || 0, + capHeight: descriptor.get("CapHeight") || 0, + flags: descriptor.get("Flags"), + italicAngle: descriptor.get("ItalicAngle") || 0, + isType3Font, + cssFontInfo, + scaleFactors: glyphScaleFactors, + systemFontInfo + }; + if (composite) { + const cidEncoding = baseDict.get("Encoding"); + if (cidEncoding instanceof _primitives.Name) { + properties.cidEncoding = cidEncoding.name; + } + const cMap = await _cmap.CMapFactory.create({ + encoding: cidEncoding, + fetchBuiltInCMap: this._fetchBuiltInCMapBound, + useCMap: null + }); + properties.cMap = cMap; + properties.vertical = properties.cMap.vertical; + } + return this.extractDataStructures(dict, baseDict, properties).then(newProperties => { + this.extractWidths(dict, descriptor, newProperties); + return new _fonts.Font(fontName.name, fontFile, newProperties); + }); + } + static buildFontPaths(font, glyphs, handler, evaluatorOptions) { + function buildPath(fontChar) { + const glyphName = `${font.loadedName}_path_${fontChar}`; + try { + if (font.renderer.hasBuiltPath(fontChar)) { + return; + } + handler.send("commonobj", [glyphName, "FontPath", font.renderer.getPathJs(fontChar)]); + } catch (reason) { + if (evaluatorOptions.ignoreErrors) { + (0, _util.warn)(`buildFontPaths - ignoring ${glyphName} glyph: "${reason}".`); + return; + } + throw reason; + } + } + for (const glyph of glyphs) { + buildPath(glyph.fontChar); + const accent = glyph.accent; + if (accent?.fontChar) { + buildPath(accent.fontChar); + } + } + } + static get fallbackFontDict() { + const dict = new _primitives.Dict(); + dict.set("BaseFont", _primitives.Name.get("Helvetica")); + dict.set("Type", _primitives.Name.get("FallbackType")); + dict.set("Subtype", _primitives.Name.get("FallbackType")); + dict.set("Encoding", _primitives.Name.get("WinAnsiEncoding")); + return (0, _util.shadow)(this, "fallbackFontDict", dict); + } +} +exports.PartialEvaluator = PartialEvaluator; +class TranslatedFont { + constructor({ + loadedName, + font, + dict, + evaluatorOptions + }) { + this.loadedName = loadedName; + this.font = font; + this.dict = dict; + this._evaluatorOptions = evaluatorOptions || DefaultPartialEvaluatorOptions; + this.type3Loaded = null; + this.type3Dependencies = font.isType3Font ? new Set() : null; + this.sent = false; + } + send(handler) { + if (this.sent) { + return; + } + this.sent = true; + handler.send("commonobj", [this.loadedName, "Font", this.font.exportData(this._evaluatorOptions.fontExtraProperties)]); + } + fallback(handler) { + if (!this.font.data) { + return; + } + this.font.disableFontFace = true; + PartialEvaluator.buildFontPaths(this.font, this.font.glyphCacheValues, handler, this._evaluatorOptions); + } + loadType3Data(evaluator, resources, task) { + if (this.type3Loaded) { + return this.type3Loaded; + } + if (!this.font.isType3Font) { + throw new Error("Must be a Type3 font."); + } + const type3Evaluator = evaluator.clone({ + ignoreErrors: false + }); + type3Evaluator.parsingType3Font = true; + const type3FontRefs = new _primitives.RefSet(evaluator.type3FontRefs); + if (this.dict.objId && !type3FontRefs.has(this.dict.objId)) { + type3FontRefs.put(this.dict.objId); + } + type3Evaluator.type3FontRefs = type3FontRefs; + const translatedFont = this.font, + type3Dependencies = this.type3Dependencies; + let loadCharProcsPromise = Promise.resolve(); + const charProcs = this.dict.get("CharProcs"); + const fontResources = this.dict.get("Resources") || resources; + const charProcOperatorList = Object.create(null); + const fontBBox = _util.Util.normalizeRect(translatedFont.bbox || [0, 0, 0, 0]), + width = fontBBox[2] - fontBBox[0], + height = fontBBox[3] - fontBBox[1]; + const fontBBoxSize = Math.hypot(width, height); + for (const key of charProcs.getKeys()) { + loadCharProcsPromise = loadCharProcsPromise.then(() => { + const glyphStream = charProcs.get(key); + const operatorList = new _operator_list.OperatorList(); + return type3Evaluator.getOperatorList({ + stream: glyphStream, + task, + resources: fontResources, + operatorList + }).then(() => { + if (operatorList.fnArray[0] === _util.OPS.setCharWidthAndBounds) { + this._removeType3ColorOperators(operatorList, fontBBoxSize); + } + charProcOperatorList[key] = operatorList.getIR(); + for (const dependency of operatorList.dependencies) { + type3Dependencies.add(dependency); + } + }).catch(function (reason) { + (0, _util.warn)(`Type3 font resource "${key}" is not available.`); + const dummyOperatorList = new _operator_list.OperatorList(); + charProcOperatorList[key] = dummyOperatorList.getIR(); + }); + }); + } + this.type3Loaded = loadCharProcsPromise.then(() => { + translatedFont.charProcOperatorList = charProcOperatorList; + if (this._bbox) { + translatedFont.isCharBBox = true; + translatedFont.bbox = this._bbox; + } + }); + return this.type3Loaded; + } + _removeType3ColorOperators(operatorList, fontBBoxSize = NaN) { + const charBBox = _util.Util.normalizeRect(operatorList.argsArray[0].slice(2)), + width = charBBox[2] - charBBox[0], + height = charBBox[3] - charBBox[1]; + const charBBoxSize = Math.hypot(width, height); + if (width === 0 || height === 0) { + operatorList.fnArray.splice(0, 1); + operatorList.argsArray.splice(0, 1); + } else if (fontBBoxSize === 0 || Math.round(charBBoxSize / fontBBoxSize) >= 10) { + if (!this._bbox) { + this._bbox = [Infinity, Infinity, -Infinity, -Infinity]; + } + this._bbox[0] = Math.min(this._bbox[0], charBBox[0]); + this._bbox[1] = Math.min(this._bbox[1], charBBox[1]); + this._bbox[2] = Math.max(this._bbox[2], charBBox[2]); + this._bbox[3] = Math.max(this._bbox[3], charBBox[3]); + } + let i = 0, + ii = operatorList.length; + while (i < ii) { + switch (operatorList.fnArray[i]) { + case _util.OPS.setCharWidthAndBounds: + break; + case _util.OPS.setStrokeColorSpace: + case _util.OPS.setFillColorSpace: + case _util.OPS.setStrokeColor: + case _util.OPS.setStrokeColorN: + case _util.OPS.setFillColor: + case _util.OPS.setFillColorN: + case _util.OPS.setStrokeGray: + case _util.OPS.setFillGray: + case _util.OPS.setStrokeRGBColor: + case _util.OPS.setFillRGBColor: + case _util.OPS.setStrokeCMYKColor: + case _util.OPS.setFillCMYKColor: + case _util.OPS.shadingFill: + case _util.OPS.setRenderingIntent: + operatorList.fnArray.splice(i, 1); + operatorList.argsArray.splice(i, 1); + ii--; + continue; + case _util.OPS.setGState: + const [gStateObj] = operatorList.argsArray[i]; + let j = 0, + jj = gStateObj.length; + while (j < jj) { + const [gStateKey] = gStateObj[j]; + switch (gStateKey) { + case "TR": + case "TR2": + case "HT": + case "BG": + case "BG2": + case "UCR": + case "UCR2": + gStateObj.splice(j, 1); + jj--; + continue; + } + j++; + } + break; + } + i++; + } + } +} +class StateManager { + constructor(initialState = new EvalState()) { + this.state = initialState; + this.stateStack = []; + } + save() { + const old = this.state; + this.stateStack.push(this.state); + this.state = old.clone(); + } + restore() { + const prev = this.stateStack.pop(); + if (prev) { + this.state = prev; + } + } + transform(args) { + this.state.ctm = _util.Util.transform(this.state.ctm, args); + } +} +class TextState { + constructor() { + this.ctm = new Float32Array(_util.IDENTITY_MATRIX); + this.fontName = null; + this.fontSize = 0; + this.loadedName = null; + this.font = null; + this.fontMatrix = _util.FONT_IDENTITY_MATRIX; + this.textMatrix = _util.IDENTITY_MATRIX.slice(); + this.textLineMatrix = _util.IDENTITY_MATRIX.slice(); + this.charSpacing = 0; + this.wordSpacing = 0; + this.leading = 0; + this.textHScale = 1; + this.textRise = 0; + } + setTextMatrix(a, b, c, d, e, f) { + const m = this.textMatrix; + m[0] = a; + m[1] = b; + m[2] = c; + m[3] = d; + m[4] = e; + m[5] = f; + } + setTextLineMatrix(a, b, c, d, e, f) { + const m = this.textLineMatrix; + m[0] = a; + m[1] = b; + m[2] = c; + m[3] = d; + m[4] = e; + m[5] = f; + } + translateTextMatrix(x, y) { + const m = this.textMatrix; + m[4] = m[0] * x + m[2] * y + m[4]; + m[5] = m[1] * x + m[3] * y + m[5]; + } + translateTextLineMatrix(x, y) { + const m = this.textLineMatrix; + m[4] = m[0] * x + m[2] * y + m[4]; + m[5] = m[1] * x + m[3] * y + m[5]; + } + carriageReturn() { + this.translateTextLineMatrix(0, -this.leading); + this.textMatrix = this.textLineMatrix.slice(); + } + clone() { + const clone = Object.create(this); + clone.textMatrix = this.textMatrix.slice(); + clone.textLineMatrix = this.textLineMatrix.slice(); + clone.fontMatrix = this.fontMatrix.slice(); + return clone; + } +} +class EvalState { + constructor() { + this.ctm = new Float32Array(_util.IDENTITY_MATRIX); + this.font = null; + this.textRenderingMode = _util.TextRenderingMode.FILL; + this.fillColorSpace = _colorspace.ColorSpace.singletons.gray; + this.strokeColorSpace = _colorspace.ColorSpace.singletons.gray; + } + clone() { + return Object.create(this); + } +} +class EvaluatorPreprocessor { + static get opMap() { + return (0, _util.shadow)(this, "opMap", { + w: { + id: _util.OPS.setLineWidth, + numArgs: 1, + variableArgs: false + }, + J: { + id: _util.OPS.setLineCap, + numArgs: 1, + variableArgs: false + }, + j: { + id: _util.OPS.setLineJoin, + numArgs: 1, + variableArgs: false + }, + M: { + id: _util.OPS.setMiterLimit, + numArgs: 1, + variableArgs: false + }, + d: { + id: _util.OPS.setDash, + numArgs: 2, + variableArgs: false + }, + ri: { + id: _util.OPS.setRenderingIntent, + numArgs: 1, + variableArgs: false + }, + i: { + id: _util.OPS.setFlatness, + numArgs: 1, + variableArgs: false + }, + gs: { + id: _util.OPS.setGState, + numArgs: 1, + variableArgs: false + }, + q: { + id: _util.OPS.save, + numArgs: 0, + variableArgs: false + }, + Q: { + id: _util.OPS.restore, + numArgs: 0, + variableArgs: false + }, + cm: { + id: _util.OPS.transform, + numArgs: 6, + variableArgs: false + }, + m: { + id: _util.OPS.moveTo, + numArgs: 2, + variableArgs: false + }, + l: { + id: _util.OPS.lineTo, + numArgs: 2, + variableArgs: false + }, + c: { + id: _util.OPS.curveTo, + numArgs: 6, + variableArgs: false + }, + v: { + id: _util.OPS.curveTo2, + numArgs: 4, + variableArgs: false + }, + y: { + id: _util.OPS.curveTo3, + numArgs: 4, + variableArgs: false + }, + h: { + id: _util.OPS.closePath, + numArgs: 0, + variableArgs: false + }, + re: { + id: _util.OPS.rectangle, + numArgs: 4, + variableArgs: false + }, + S: { + id: _util.OPS.stroke, + numArgs: 0, + variableArgs: false + }, + s: { + id: _util.OPS.closeStroke, + numArgs: 0, + variableArgs: false + }, + f: { + id: _util.OPS.fill, + numArgs: 0, + variableArgs: false + }, + F: { + id: _util.OPS.fill, + numArgs: 0, + variableArgs: false + }, + "f*": { + id: _util.OPS.eoFill, + numArgs: 0, + variableArgs: false + }, + B: { + id: _util.OPS.fillStroke, + numArgs: 0, + variableArgs: false + }, + "B*": { + id: _util.OPS.eoFillStroke, + numArgs: 0, + variableArgs: false + }, + b: { + id: _util.OPS.closeFillStroke, + numArgs: 0, + variableArgs: false + }, + "b*": { + id: _util.OPS.closeEOFillStroke, + numArgs: 0, + variableArgs: false + }, + n: { + id: _util.OPS.endPath, + numArgs: 0, + variableArgs: false + }, + W: { + id: _util.OPS.clip, + numArgs: 0, + variableArgs: false + }, + "W*": { + id: _util.OPS.eoClip, + numArgs: 0, + variableArgs: false + }, + BT: { + id: _util.OPS.beginText, + numArgs: 0, + variableArgs: false + }, + ET: { + id: _util.OPS.endText, + numArgs: 0, + variableArgs: false + }, + Tc: { + id: _util.OPS.setCharSpacing, + numArgs: 1, + variableArgs: false + }, + Tw: { + id: _util.OPS.setWordSpacing, + numArgs: 1, + variableArgs: false + }, + Tz: { + id: _util.OPS.setHScale, + numArgs: 1, + variableArgs: false + }, + TL: { + id: _util.OPS.setLeading, + numArgs: 1, + variableArgs: false + }, + Tf: { + id: _util.OPS.setFont, + numArgs: 2, + variableArgs: false + }, + Tr: { + id: _util.OPS.setTextRenderingMode, + numArgs: 1, + variableArgs: false + }, + Ts: { + id: _util.OPS.setTextRise, + numArgs: 1, + variableArgs: false + }, + Td: { + id: _util.OPS.moveText, + numArgs: 2, + variableArgs: false + }, + TD: { + id: _util.OPS.setLeadingMoveText, + numArgs: 2, + variableArgs: false + }, + Tm: { + id: _util.OPS.setTextMatrix, + numArgs: 6, + variableArgs: false + }, + "T*": { + id: _util.OPS.nextLine, + numArgs: 0, + variableArgs: false + }, + Tj: { + id: _util.OPS.showText, + numArgs: 1, + variableArgs: false + }, + TJ: { + id: _util.OPS.showSpacedText, + numArgs: 1, + variableArgs: false + }, + "'": { + id: _util.OPS.nextLineShowText, + numArgs: 1, + variableArgs: false + }, + '"': { + id: _util.OPS.nextLineSetSpacingShowText, + numArgs: 3, + variableArgs: false + }, + d0: { + id: _util.OPS.setCharWidth, + numArgs: 2, + variableArgs: false + }, + d1: { + id: _util.OPS.setCharWidthAndBounds, + numArgs: 6, + variableArgs: false + }, + CS: { + id: _util.OPS.setStrokeColorSpace, + numArgs: 1, + variableArgs: false + }, + cs: { + id: _util.OPS.setFillColorSpace, + numArgs: 1, + variableArgs: false + }, + SC: { + id: _util.OPS.setStrokeColor, + numArgs: 4, + variableArgs: true + }, + SCN: { + id: _util.OPS.setStrokeColorN, + numArgs: 33, + variableArgs: true + }, + sc: { + id: _util.OPS.setFillColor, + numArgs: 4, + variableArgs: true + }, + scn: { + id: _util.OPS.setFillColorN, + numArgs: 33, + variableArgs: true + }, + G: { + id: _util.OPS.setStrokeGray, + numArgs: 1, + variableArgs: false + }, + g: { + id: _util.OPS.setFillGray, + numArgs: 1, + variableArgs: false + }, + RG: { + id: _util.OPS.setStrokeRGBColor, + numArgs: 3, + variableArgs: false + }, + rg: { + id: _util.OPS.setFillRGBColor, + numArgs: 3, + variableArgs: false + }, + K: { + id: _util.OPS.setStrokeCMYKColor, + numArgs: 4, + variableArgs: false + }, + k: { + id: _util.OPS.setFillCMYKColor, + numArgs: 4, + variableArgs: false + }, + sh: { + id: _util.OPS.shadingFill, + numArgs: 1, + variableArgs: false + }, + BI: { + id: _util.OPS.beginInlineImage, + numArgs: 0, + variableArgs: false + }, + ID: { + id: _util.OPS.beginImageData, + numArgs: 0, + variableArgs: false + }, + EI: { + id: _util.OPS.endInlineImage, + numArgs: 1, + variableArgs: false + }, + Do: { + id: _util.OPS.paintXObject, + numArgs: 1, + variableArgs: false + }, + MP: { + id: _util.OPS.markPoint, + numArgs: 1, + variableArgs: false + }, + DP: { + id: _util.OPS.markPointProps, + numArgs: 2, + variableArgs: false + }, + BMC: { + id: _util.OPS.beginMarkedContent, + numArgs: 1, + variableArgs: false + }, + BDC: { + id: _util.OPS.beginMarkedContentProps, + numArgs: 2, + variableArgs: false + }, + EMC: { + id: _util.OPS.endMarkedContent, + numArgs: 0, + variableArgs: false + }, + BX: { + id: _util.OPS.beginCompat, + numArgs: 0, + variableArgs: false + }, + EX: { + id: _util.OPS.endCompat, + numArgs: 0, + variableArgs: false + }, + BM: null, + BD: null, + true: null, + fa: null, + fal: null, + fals: null, + false: null, + nu: null, + nul: null, + null: null + }); + } + static MAX_INVALID_PATH_OPS = 10; + constructor(stream, xref, stateManager = new StateManager()) { + this.parser = new _parser.Parser({ + lexer: new _parser.Lexer(stream, EvaluatorPreprocessor.opMap), + xref + }); + this.stateManager = stateManager; + this.nonProcessedArgs = []; + this._isPathOp = false; + this._numInvalidPathOPS = 0; + } + get savedStatesDepth() { + return this.stateManager.stateStack.length; + } + read(operation) { + let args = operation.args; + while (true) { + const obj = this.parser.getObj(); + if (obj instanceof _primitives.Cmd) { + const cmd = obj.cmd; + const opSpec = EvaluatorPreprocessor.opMap[cmd]; + if (!opSpec) { + (0, _util.warn)(`Unknown command "${cmd}".`); + continue; + } + const fn = opSpec.id; + const numArgs = opSpec.numArgs; + let argsLength = args !== null ? args.length : 0; + if (!this._isPathOp) { + this._numInvalidPathOPS = 0; + } + this._isPathOp = fn >= _util.OPS.moveTo && fn <= _util.OPS.endPath; + if (!opSpec.variableArgs) { + if (argsLength !== numArgs) { + const nonProcessedArgs = this.nonProcessedArgs; + while (argsLength > numArgs) { + nonProcessedArgs.push(args.shift()); + argsLength--; + } + while (argsLength < numArgs && nonProcessedArgs.length !== 0) { + if (args === null) { + args = []; + } + args.unshift(nonProcessedArgs.pop()); + argsLength++; + } + } + if (argsLength < numArgs) { + const partialMsg = `command ${cmd}: expected ${numArgs} args, ` + `but received ${argsLength} args.`; + if (this._isPathOp && ++this._numInvalidPathOPS > EvaluatorPreprocessor.MAX_INVALID_PATH_OPS) { + throw new _util.FormatError(`Invalid ${partialMsg}`); + } + (0, _util.warn)(`Skipping ${partialMsg}`); + if (args !== null) { + args.length = 0; + } + continue; + } + } else if (argsLength > numArgs) { + (0, _util.info)(`Command ${cmd}: expected [0, ${numArgs}] args, ` + `but received ${argsLength} args.`); + } + this.preprocessCommand(fn, args); + operation.fn = fn; + operation.args = args; + return true; + } + if (obj === _primitives.EOF) { + return false; + } + if (obj !== null) { + if (args === null) { + args = []; + } + args.push(obj); + if (args.length > 33) { + throw new _util.FormatError("Too many arguments"); + } + } + } + } + preprocessCommand(fn, args) { + switch (fn | 0) { + case _util.OPS.save: + this.stateManager.save(); + break; + case _util.OPS.restore: + this.stateManager.restore(); + break; + case _util.OPS.transform: + this.stateManager.transform(args); + break; + } + } +} +exports.EvaluatorPreprocessor = EvaluatorPreprocessor; + +/***/ }), +/* 14 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.IdentityCMap = exports.CMapFactory = exports.CMap = void 0; +var _util = __w_pdfjs_require__(2); +var _primitives = __w_pdfjs_require__(4); +var _base_stream = __w_pdfjs_require__(5); +var _binary_cmap = __w_pdfjs_require__(15); +var _parser = __w_pdfjs_require__(16); +var _core_utils = __w_pdfjs_require__(3); +var _stream = __w_pdfjs_require__(8); +const BUILT_IN_CMAPS = ["Adobe-GB1-UCS2", "Adobe-CNS1-UCS2", "Adobe-Japan1-UCS2", "Adobe-Korea1-UCS2", "78-EUC-H", "78-EUC-V", "78-H", "78-RKSJ-H", "78-RKSJ-V", "78-V", "78ms-RKSJ-H", "78ms-RKSJ-V", "83pv-RKSJ-H", "90ms-RKSJ-H", "90ms-RKSJ-V", "90msp-RKSJ-H", "90msp-RKSJ-V", "90pv-RKSJ-H", "90pv-RKSJ-V", "Add-H", "Add-RKSJ-H", "Add-RKSJ-V", "Add-V", "Adobe-CNS1-0", "Adobe-CNS1-1", "Adobe-CNS1-2", "Adobe-CNS1-3", "Adobe-CNS1-4", "Adobe-CNS1-5", "Adobe-CNS1-6", "Adobe-GB1-0", "Adobe-GB1-1", "Adobe-GB1-2", "Adobe-GB1-3", "Adobe-GB1-4", "Adobe-GB1-5", "Adobe-Japan1-0", "Adobe-Japan1-1", "Adobe-Japan1-2", "Adobe-Japan1-3", "Adobe-Japan1-4", "Adobe-Japan1-5", "Adobe-Japan1-6", "Adobe-Korea1-0", "Adobe-Korea1-1", "Adobe-Korea1-2", "B5-H", "B5-V", "B5pc-H", "B5pc-V", "CNS-EUC-H", "CNS-EUC-V", "CNS1-H", "CNS1-V", "CNS2-H", "CNS2-V", "ETHK-B5-H", "ETHK-B5-V", "ETen-B5-H", "ETen-B5-V", "ETenms-B5-H", "ETenms-B5-V", "EUC-H", "EUC-V", "Ext-H", "Ext-RKSJ-H", "Ext-RKSJ-V", "Ext-V", "GB-EUC-H", "GB-EUC-V", "GB-H", "GB-V", "GBK-EUC-H", "GBK-EUC-V", "GBK2K-H", "GBK2K-V", "GBKp-EUC-H", "GBKp-EUC-V", "GBT-EUC-H", "GBT-EUC-V", "GBT-H", "GBT-V", "GBTpc-EUC-H", "GBTpc-EUC-V", "GBpc-EUC-H", "GBpc-EUC-V", "H", "HKdla-B5-H", "HKdla-B5-V", "HKdlb-B5-H", "HKdlb-B5-V", "HKgccs-B5-H", "HKgccs-B5-V", "HKm314-B5-H", "HKm314-B5-V", "HKm471-B5-H", "HKm471-B5-V", "HKscs-B5-H", "HKscs-B5-V", "Hankaku", "Hiragana", "KSC-EUC-H", "KSC-EUC-V", "KSC-H", "KSC-Johab-H", "KSC-Johab-V", "KSC-V", "KSCms-UHC-H", "KSCms-UHC-HW-H", "KSCms-UHC-HW-V", "KSCms-UHC-V", "KSCpc-EUC-H", "KSCpc-EUC-V", "Katakana", "NWP-H", "NWP-V", "RKSJ-H", "RKSJ-V", "Roman", "UniCNS-UCS2-H", "UniCNS-UCS2-V", "UniCNS-UTF16-H", "UniCNS-UTF16-V", "UniCNS-UTF32-H", "UniCNS-UTF32-V", "UniCNS-UTF8-H", "UniCNS-UTF8-V", "UniGB-UCS2-H", "UniGB-UCS2-V", "UniGB-UTF16-H", "UniGB-UTF16-V", "UniGB-UTF32-H", "UniGB-UTF32-V", "UniGB-UTF8-H", "UniGB-UTF8-V", "UniJIS-UCS2-H", "UniJIS-UCS2-HW-H", "UniJIS-UCS2-HW-V", "UniJIS-UCS2-V", "UniJIS-UTF16-H", "UniJIS-UTF16-V", "UniJIS-UTF32-H", "UniJIS-UTF32-V", "UniJIS-UTF8-H", "UniJIS-UTF8-V", "UniJIS2004-UTF16-H", "UniJIS2004-UTF16-V", "UniJIS2004-UTF32-H", "UniJIS2004-UTF32-V", "UniJIS2004-UTF8-H", "UniJIS2004-UTF8-V", "UniJISPro-UCS2-HW-V", "UniJISPro-UCS2-V", "UniJISPro-UTF8-V", "UniJISX0213-UTF32-H", "UniJISX0213-UTF32-V", "UniJISX02132004-UTF32-H", "UniJISX02132004-UTF32-V", "UniKS-UCS2-H", "UniKS-UCS2-V", "UniKS-UTF16-H", "UniKS-UTF16-V", "UniKS-UTF32-H", "UniKS-UTF32-V", "UniKS-UTF8-H", "UniKS-UTF8-V", "V", "WP-Symbol"]; +const MAX_MAP_RANGE = 2 ** 24 - 1; +class CMap { + constructor(builtInCMap = false) { + this.codespaceRanges = [[], [], [], []]; + this.numCodespaceRanges = 0; + this._map = []; + this.name = ""; + this.vertical = false; + this.useCMap = null; + this.builtInCMap = builtInCMap; + } + addCodespaceRange(n, low, high) { + this.codespaceRanges[n - 1].push(low, high); + this.numCodespaceRanges++; + } + mapCidRange(low, high, dstLow) { + if (high - low > MAX_MAP_RANGE) { + throw new Error("mapCidRange - ignoring data above MAX_MAP_RANGE."); + } + while (low <= high) { + this._map[low++] = dstLow++; + } + } + mapBfRange(low, high, dstLow) { + if (high - low > MAX_MAP_RANGE) { + throw new Error("mapBfRange - ignoring data above MAX_MAP_RANGE."); + } + const lastByte = dstLow.length - 1; + while (low <= high) { + this._map[low++] = dstLow; + const nextCharCode = dstLow.charCodeAt(lastByte) + 1; + if (nextCharCode > 0xff) { + dstLow = dstLow.substring(0, lastByte - 1) + String.fromCharCode(dstLow.charCodeAt(lastByte - 1) + 1) + "\x00"; + continue; + } + dstLow = dstLow.substring(0, lastByte) + String.fromCharCode(nextCharCode); + } + } + mapBfRangeToArray(low, high, array) { + if (high - low > MAX_MAP_RANGE) { + throw new Error("mapBfRangeToArray - ignoring data above MAX_MAP_RANGE."); + } + const ii = array.length; + let i = 0; + while (low <= high && i < ii) { + this._map[low] = array[i++]; + ++low; + } + } + mapOne(src, dst) { + this._map[src] = dst; + } + lookup(code) { + return this._map[code]; + } + contains(code) { + return this._map[code] !== undefined; + } + forEach(callback) { + const map = this._map; + const length = map.length; + if (length <= 0x10000) { + for (let i = 0; i < length; i++) { + if (map[i] !== undefined) { + callback(i, map[i]); + } + } + } else { + for (const i in map) { + callback(i, map[i]); + } + } + } + charCodeOf(value) { + const map = this._map; + if (map.length <= 0x10000) { + return map.indexOf(value); + } + for (const charCode in map) { + if (map[charCode] === value) { + return charCode | 0; + } + } + return -1; + } + getMap() { + return this._map; + } + readCharCode(str, offset, out) { + let c = 0; + const codespaceRanges = this.codespaceRanges; + for (let n = 0, nn = codespaceRanges.length; n < nn; n++) { + c = (c << 8 | str.charCodeAt(offset + n)) >>> 0; + const codespaceRange = codespaceRanges[n]; + for (let k = 0, kk = codespaceRange.length; k < kk;) { + const low = codespaceRange[k++]; + const high = codespaceRange[k++]; + if (c >= low && c <= high) { + out.charcode = c; + out.length = n + 1; + return; + } + } + } + out.charcode = 0; + out.length = 1; + } + getCharCodeLength(charCode) { + const codespaceRanges = this.codespaceRanges; + for (let n = 0, nn = codespaceRanges.length; n < nn; n++) { + const codespaceRange = codespaceRanges[n]; + for (let k = 0, kk = codespaceRange.length; k < kk;) { + const low = codespaceRange[k++]; + const high = codespaceRange[k++]; + if (charCode >= low && charCode <= high) { + return n + 1; + } + } + } + return 1; + } + get length() { + return this._map.length; + } + get isIdentityCMap() { + if (!(this.name === "Identity-H" || this.name === "Identity-V")) { + return false; + } + if (this._map.length !== 0x10000) { + return false; + } + for (let i = 0; i < 0x10000; i++) { + if (this._map[i] !== i) { + return false; + } + } + return true; + } +} +exports.CMap = CMap; +class IdentityCMap extends CMap { + constructor(vertical, n) { + super(); + this.vertical = vertical; + this.addCodespaceRange(n, 0, 0xffff); + } + mapCidRange(low, high, dstLow) { + (0, _util.unreachable)("should not call mapCidRange"); + } + mapBfRange(low, high, dstLow) { + (0, _util.unreachable)("should not call mapBfRange"); + } + mapBfRangeToArray(low, high, array) { + (0, _util.unreachable)("should not call mapBfRangeToArray"); + } + mapOne(src, dst) { + (0, _util.unreachable)("should not call mapCidOne"); + } + lookup(code) { + return Number.isInteger(code) && code <= 0xffff ? code : undefined; + } + contains(code) { + return Number.isInteger(code) && code <= 0xffff; + } + forEach(callback) { + for (let i = 0; i <= 0xffff; i++) { + callback(i, i); + } + } + charCodeOf(value) { + return Number.isInteger(value) && value <= 0xffff ? value : -1; + } + getMap() { + const map = new Array(0x10000); + for (let i = 0; i <= 0xffff; i++) { + map[i] = i; + } + return map; + } + get length() { + return 0x10000; + } + get isIdentityCMap() { + (0, _util.unreachable)("should not access .isIdentityCMap"); + } +} +exports.IdentityCMap = IdentityCMap; +function strToInt(str) { + let a = 0; + for (let i = 0; i < str.length; i++) { + a = a << 8 | str.charCodeAt(i); + } + return a >>> 0; +} +function expectString(obj) { + if (typeof obj !== "string") { + throw new _util.FormatError("Malformed CMap: expected string."); + } +} +function expectInt(obj) { + if (!Number.isInteger(obj)) { + throw new _util.FormatError("Malformed CMap: expected int."); + } +} +function parseBfChar(cMap, lexer) { + while (true) { + let obj = lexer.getObj(); + if (obj === _primitives.EOF) { + break; + } + if ((0, _primitives.isCmd)(obj, "endbfchar")) { + return; + } + expectString(obj); + const src = strToInt(obj); + obj = lexer.getObj(); + expectString(obj); + const dst = obj; + cMap.mapOne(src, dst); + } +} +function parseBfRange(cMap, lexer) { + while (true) { + let obj = lexer.getObj(); + if (obj === _primitives.EOF) { + break; + } + if ((0, _primitives.isCmd)(obj, "endbfrange")) { + return; + } + expectString(obj); + const low = strToInt(obj); + obj = lexer.getObj(); + expectString(obj); + const high = strToInt(obj); + obj = lexer.getObj(); + if (Number.isInteger(obj) || typeof obj === "string") { + const dstLow = Number.isInteger(obj) ? String.fromCharCode(obj) : obj; + cMap.mapBfRange(low, high, dstLow); + } else if ((0, _primitives.isCmd)(obj, "[")) { + obj = lexer.getObj(); + const array = []; + while (!(0, _primitives.isCmd)(obj, "]") && obj !== _primitives.EOF) { + array.push(obj); + obj = lexer.getObj(); + } + cMap.mapBfRangeToArray(low, high, array); + } else { + break; + } + } + throw new _util.FormatError("Invalid bf range."); +} +function parseCidChar(cMap, lexer) { + while (true) { + let obj = lexer.getObj(); + if (obj === _primitives.EOF) { + break; + } + if ((0, _primitives.isCmd)(obj, "endcidchar")) { + return; + } + expectString(obj); + const src = strToInt(obj); + obj = lexer.getObj(); + expectInt(obj); + const dst = obj; + cMap.mapOne(src, dst); + } +} +function parseCidRange(cMap, lexer) { + while (true) { + let obj = lexer.getObj(); + if (obj === _primitives.EOF) { + break; + } + if ((0, _primitives.isCmd)(obj, "endcidrange")) { + return; + } + expectString(obj); + const low = strToInt(obj); + obj = lexer.getObj(); + expectString(obj); + const high = strToInt(obj); + obj = lexer.getObj(); + expectInt(obj); + const dstLow = obj; + cMap.mapCidRange(low, high, dstLow); + } +} +function parseCodespaceRange(cMap, lexer) { + while (true) { + let obj = lexer.getObj(); + if (obj === _primitives.EOF) { + break; + } + if ((0, _primitives.isCmd)(obj, "endcodespacerange")) { + return; + } + if (typeof obj !== "string") { + break; + } + const low = strToInt(obj); + obj = lexer.getObj(); + if (typeof obj !== "string") { + break; + } + const high = strToInt(obj); + cMap.addCodespaceRange(obj.length, low, high); + } + throw new _util.FormatError("Invalid codespace range."); +} +function parseWMode(cMap, lexer) { + const obj = lexer.getObj(); + if (Number.isInteger(obj)) { + cMap.vertical = !!obj; + } +} +function parseCMapName(cMap, lexer) { + const obj = lexer.getObj(); + if (obj instanceof _primitives.Name) { + cMap.name = obj.name; + } +} +async function parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap) { + let previous, embeddedUseCMap; + objLoop: while (true) { + try { + const obj = lexer.getObj(); + if (obj === _primitives.EOF) { + break; + } else if (obj instanceof _primitives.Name) { + if (obj.name === "WMode") { + parseWMode(cMap, lexer); + } else if (obj.name === "CMapName") { + parseCMapName(cMap, lexer); + } + previous = obj; + } else if (obj instanceof _primitives.Cmd) { + switch (obj.cmd) { + case "endcmap": + break objLoop; + case "usecmap": + if (previous instanceof _primitives.Name) { + embeddedUseCMap = previous.name; + } + break; + case "begincodespacerange": + parseCodespaceRange(cMap, lexer); + break; + case "beginbfchar": + parseBfChar(cMap, lexer); + break; + case "begincidchar": + parseCidChar(cMap, lexer); + break; + case "beginbfrange": + parseBfRange(cMap, lexer); + break; + case "begincidrange": + parseCidRange(cMap, lexer); + break; + } + } + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.warn)("Invalid cMap data: " + ex); + continue; + } + } + if (!useCMap && embeddedUseCMap) { + useCMap = embeddedUseCMap; + } + if (useCMap) { + return extendCMap(cMap, fetchBuiltInCMap, useCMap); + } + return cMap; +} +async function extendCMap(cMap, fetchBuiltInCMap, useCMap) { + cMap.useCMap = await createBuiltInCMap(useCMap, fetchBuiltInCMap); + if (cMap.numCodespaceRanges === 0) { + const useCodespaceRanges = cMap.useCMap.codespaceRanges; + for (let i = 0; i < useCodespaceRanges.length; i++) { + cMap.codespaceRanges[i] = useCodespaceRanges[i].slice(); + } + cMap.numCodespaceRanges = cMap.useCMap.numCodespaceRanges; + } + cMap.useCMap.forEach(function (key, value) { + if (!cMap.contains(key)) { + cMap.mapOne(key, cMap.useCMap.lookup(key)); + } + }); + return cMap; +} +async function createBuiltInCMap(name, fetchBuiltInCMap) { + if (name === "Identity-H") { + return new IdentityCMap(false, 2); + } else if (name === "Identity-V") { + return new IdentityCMap(true, 2); + } + if (!BUILT_IN_CMAPS.includes(name)) { + throw new Error("Unknown CMap name: " + name); + } + if (!fetchBuiltInCMap) { + throw new Error("Built-in CMap parameters are not provided."); + } + const { + cMapData, + compressionType + } = await fetchBuiltInCMap(name); + const cMap = new CMap(true); + if (compressionType === _util.CMapCompressionType.BINARY) { + return new _binary_cmap.BinaryCMapReader().process(cMapData, cMap, useCMap => { + return extendCMap(cMap, fetchBuiltInCMap, useCMap); + }); + } + if (compressionType === _util.CMapCompressionType.NONE) { + const lexer = new _parser.Lexer(new _stream.Stream(cMapData)); + return parseCMap(cMap, lexer, fetchBuiltInCMap, null); + } + throw new Error(`Invalid CMap "compressionType" value: ${compressionType}`); +} +class CMapFactory { + static async create({ + encoding, + fetchBuiltInCMap, + useCMap + }) { + if (encoding instanceof _primitives.Name) { + return createBuiltInCMap(encoding.name, fetchBuiltInCMap); + } else if (encoding instanceof _base_stream.BaseStream) { + const parsedCMap = await parseCMap(new CMap(), new _parser.Lexer(encoding), fetchBuiltInCMap, useCMap); + if (parsedCMap.isIdentityCMap) { + return createBuiltInCMap(parsedCMap.name, fetchBuiltInCMap); + } + return parsedCMap; + } + throw new Error("Encoding required."); + } +} +exports.CMapFactory = CMapFactory; + +/***/ }), +/* 15 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.BinaryCMapReader = void 0; +var _util = __w_pdfjs_require__(2); +function hexToInt(a, size) { + let n = 0; + for (let i = 0; i <= size; i++) { + n = n << 8 | a[i]; + } + return n >>> 0; +} +function hexToStr(a, size) { + if (size === 1) { + return String.fromCharCode(a[0], a[1]); + } + if (size === 3) { + return String.fromCharCode(a[0], a[1], a[2], a[3]); + } + return String.fromCharCode(...a.subarray(0, size + 1)); +} +function addHex(a, b, size) { + let c = 0; + for (let i = size; i >= 0; i--) { + c += a[i] + b[i]; + a[i] = c & 255; + c >>= 8; + } +} +function incHex(a, size) { + let c = 1; + for (let i = size; i >= 0 && c > 0; i--) { + c += a[i]; + a[i] = c & 255; + c >>= 8; + } +} +const MAX_NUM_SIZE = 16; +const MAX_ENCODED_NUM_SIZE = 19; +class BinaryCMapStream { + constructor(data) { + this.buffer = data; + this.pos = 0; + this.end = data.length; + this.tmpBuf = new Uint8Array(MAX_ENCODED_NUM_SIZE); + } + readByte() { + if (this.pos >= this.end) { + return -1; + } + return this.buffer[this.pos++]; + } + readNumber() { + let n = 0; + let last; + do { + const b = this.readByte(); + if (b < 0) { + throw new _util.FormatError("unexpected EOF in bcmap"); + } + last = !(b & 0x80); + n = n << 7 | b & 0x7f; + } while (!last); + return n; + } + readSigned() { + const n = this.readNumber(); + return n & 1 ? ~(n >>> 1) : n >>> 1; + } + readHex(num, size) { + num.set(this.buffer.subarray(this.pos, this.pos + size + 1)); + this.pos += size + 1; + } + readHexNumber(num, size) { + let last; + const stack = this.tmpBuf; + let sp = 0; + do { + const b = this.readByte(); + if (b < 0) { + throw new _util.FormatError("unexpected EOF in bcmap"); + } + last = !(b & 0x80); + stack[sp++] = b & 0x7f; + } while (!last); + let i = size, + buffer = 0, + bufferSize = 0; + while (i >= 0) { + while (bufferSize < 8 && stack.length > 0) { + buffer |= stack[--sp] << bufferSize; + bufferSize += 7; + } + num[i] = buffer & 255; + i--; + buffer >>= 8; + bufferSize -= 8; + } + } + readHexSigned(num, size) { + this.readHexNumber(num, size); + const sign = num[size] & 1 ? 255 : 0; + let c = 0; + for (let i = 0; i <= size; i++) { + c = (c & 1) << 8 | num[i]; + num[i] = c >> 1 ^ sign; + } + } + readString() { + const len = this.readNumber(), + buf = new Array(len); + for (let i = 0; i < len; i++) { + buf[i] = this.readNumber(); + } + return String.fromCharCode(...buf); + } +} +class BinaryCMapReader { + async process(data, cMap, extend) { + const stream = new BinaryCMapStream(data); + const header = stream.readByte(); + cMap.vertical = !!(header & 1); + let useCMap = null; + const start = new Uint8Array(MAX_NUM_SIZE); + const end = new Uint8Array(MAX_NUM_SIZE); + const char = new Uint8Array(MAX_NUM_SIZE); + const charCode = new Uint8Array(MAX_NUM_SIZE); + const tmp = new Uint8Array(MAX_NUM_SIZE); + let code; + let b; + while ((b = stream.readByte()) >= 0) { + const type = b >> 5; + if (type === 7) { + switch (b & 0x1f) { + case 0: + stream.readString(); + break; + case 1: + useCMap = stream.readString(); + break; + } + continue; + } + const sequence = !!(b & 0x10); + const dataSize = b & 15; + if (dataSize + 1 > MAX_NUM_SIZE) { + throw new Error("BinaryCMapReader.process: Invalid dataSize."); + } + const ucs2DataSize = 1; + const subitemsCount = stream.readNumber(); + switch (type) { + case 0: + stream.readHex(start, dataSize); + stream.readHexNumber(end, dataSize); + addHex(end, start, dataSize); + cMap.addCodespaceRange(dataSize + 1, hexToInt(start, dataSize), hexToInt(end, dataSize)); + for (let i = 1; i < subitemsCount; i++) { + incHex(end, dataSize); + stream.readHexNumber(start, dataSize); + addHex(start, end, dataSize); + stream.readHexNumber(end, dataSize); + addHex(end, start, dataSize); + cMap.addCodespaceRange(dataSize + 1, hexToInt(start, dataSize), hexToInt(end, dataSize)); + } + break; + case 1: + stream.readHex(start, dataSize); + stream.readHexNumber(end, dataSize); + addHex(end, start, dataSize); + stream.readNumber(); + for (let i = 1; i < subitemsCount; i++) { + incHex(end, dataSize); + stream.readHexNumber(start, dataSize); + addHex(start, end, dataSize); + stream.readHexNumber(end, dataSize); + addHex(end, start, dataSize); + stream.readNumber(); + } + break; + case 2: + stream.readHex(char, dataSize); + code = stream.readNumber(); + cMap.mapOne(hexToInt(char, dataSize), code); + for (let i = 1; i < subitemsCount; i++) { + incHex(char, dataSize); + if (!sequence) { + stream.readHexNumber(tmp, dataSize); + addHex(char, tmp, dataSize); + } + code = stream.readSigned() + (code + 1); + cMap.mapOne(hexToInt(char, dataSize), code); + } + break; + case 3: + stream.readHex(start, dataSize); + stream.readHexNumber(end, dataSize); + addHex(end, start, dataSize); + code = stream.readNumber(); + cMap.mapCidRange(hexToInt(start, dataSize), hexToInt(end, dataSize), code); + for (let i = 1; i < subitemsCount; i++) { + incHex(end, dataSize); + if (!sequence) { + stream.readHexNumber(start, dataSize); + addHex(start, end, dataSize); + } else { + start.set(end); + } + stream.readHexNumber(end, dataSize); + addHex(end, start, dataSize); + code = stream.readNumber(); + cMap.mapCidRange(hexToInt(start, dataSize), hexToInt(end, dataSize), code); + } + break; + case 4: + stream.readHex(char, ucs2DataSize); + stream.readHex(charCode, dataSize); + cMap.mapOne(hexToInt(char, ucs2DataSize), hexToStr(charCode, dataSize)); + for (let i = 1; i < subitemsCount; i++) { + incHex(char, ucs2DataSize); + if (!sequence) { + stream.readHexNumber(tmp, ucs2DataSize); + addHex(char, tmp, ucs2DataSize); + } + incHex(charCode, dataSize); + stream.readHexSigned(tmp, dataSize); + addHex(charCode, tmp, dataSize); + cMap.mapOne(hexToInt(char, ucs2DataSize), hexToStr(charCode, dataSize)); + } + break; + case 5: + stream.readHex(start, ucs2DataSize); + stream.readHexNumber(end, ucs2DataSize); + addHex(end, start, ucs2DataSize); + stream.readHex(charCode, dataSize); + cMap.mapBfRange(hexToInt(start, ucs2DataSize), hexToInt(end, ucs2DataSize), hexToStr(charCode, dataSize)); + for (let i = 1; i < subitemsCount; i++) { + incHex(end, ucs2DataSize); + if (!sequence) { + stream.readHexNumber(start, ucs2DataSize); + addHex(start, end, ucs2DataSize); + } else { + start.set(end); + } + stream.readHexNumber(end, ucs2DataSize); + addHex(end, start, ucs2DataSize); + stream.readHex(charCode, dataSize); + cMap.mapBfRange(hexToInt(start, ucs2DataSize), hexToInt(end, ucs2DataSize), hexToStr(charCode, dataSize)); + } + break; + default: + throw new Error(`BinaryCMapReader.process - unknown type: ${type}`); + } + } + if (useCMap) { + return extend(useCMap); + } + return cMap; + } +} +exports.BinaryCMapReader = BinaryCMapReader; + +/***/ }), +/* 16 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Parser = exports.Linearization = exports.Lexer = void 0; +var _util = __w_pdfjs_require__(2); +var _primitives = __w_pdfjs_require__(4); +var _core_utils = __w_pdfjs_require__(3); +var _stream = __w_pdfjs_require__(8); +var _ascii_85_stream = __w_pdfjs_require__(17); +var _ascii_hex_stream = __w_pdfjs_require__(19); +var _ccitt_stream = __w_pdfjs_require__(20); +var _flate_stream = __w_pdfjs_require__(22); +var _jbig2_stream = __w_pdfjs_require__(23); +var _jpeg_stream = __w_pdfjs_require__(26); +var _jpx_stream = __w_pdfjs_require__(29); +var _lzw_stream = __w_pdfjs_require__(31); +var _predictor_stream = __w_pdfjs_require__(32); +var _run_length_stream = __w_pdfjs_require__(33); +const MAX_LENGTH_TO_CACHE = 1000; +function getInlineImageCacheKey(bytes) { + const strBuf = [], + ii = bytes.length; + let i = 0; + while (i < ii - 1) { + strBuf.push(bytes[i++] << 8 | bytes[i++]); + } + if (i < ii) { + strBuf.push(bytes[i]); + } + return ii + "_" + String.fromCharCode.apply(null, strBuf); +} +class Parser { + constructor({ + lexer, + xref, + allowStreams = false, + recoveryMode = false + }) { + this.lexer = lexer; + this.xref = xref; + this.allowStreams = allowStreams; + this.recoveryMode = recoveryMode; + this.imageCache = Object.create(null); + this._imageId = 0; + this.refill(); + } + refill() { + this.buf1 = this.lexer.getObj(); + this.buf2 = this.lexer.getObj(); + } + shift() { + if (this.buf2 instanceof _primitives.Cmd && this.buf2.cmd === "ID") { + this.buf1 = this.buf2; + this.buf2 = null; + } else { + this.buf1 = this.buf2; + this.buf2 = this.lexer.getObj(); + } + } + tryShift() { + try { + this.shift(); + return true; + } catch (e) { + if (e instanceof _core_utils.MissingDataException) { + throw e; + } + return false; + } + } + getObj(cipherTransform = null) { + const buf1 = this.buf1; + this.shift(); + if (buf1 instanceof _primitives.Cmd) { + switch (buf1.cmd) { + case "BI": + return this.makeInlineImage(cipherTransform); + case "[": + const array = []; + while (!(0, _primitives.isCmd)(this.buf1, "]") && this.buf1 !== _primitives.EOF) { + array.push(this.getObj(cipherTransform)); + } + if (this.buf1 === _primitives.EOF) { + if (this.recoveryMode) { + return array; + } + throw new _core_utils.ParserEOFException("End of file inside array."); + } + this.shift(); + return array; + case "<<": + const dict = new _primitives.Dict(this.xref); + while (!(0, _primitives.isCmd)(this.buf1, ">>") && this.buf1 !== _primitives.EOF) { + if (!(this.buf1 instanceof _primitives.Name)) { + (0, _util.info)("Malformed dictionary: key must be a name object"); + this.shift(); + continue; + } + const key = this.buf1.name; + this.shift(); + if (this.buf1 === _primitives.EOF) { + break; + } + dict.set(key, this.getObj(cipherTransform)); + } + if (this.buf1 === _primitives.EOF) { + if (this.recoveryMode) { + return dict; + } + throw new _core_utils.ParserEOFException("End of file inside dictionary."); + } + if ((0, _primitives.isCmd)(this.buf2, "stream")) { + return this.allowStreams ? this.makeStream(dict, cipherTransform) : dict; + } + this.shift(); + return dict; + default: + return buf1; + } + } + if (Number.isInteger(buf1)) { + if (Number.isInteger(this.buf1) && (0, _primitives.isCmd)(this.buf2, "R")) { + const ref = _primitives.Ref.get(buf1, this.buf1); + this.shift(); + this.shift(); + return ref; + } + return buf1; + } + if (typeof buf1 === "string") { + if (cipherTransform) { + return cipherTransform.decryptString(buf1); + } + return buf1; + } + return buf1; + } + findDefaultInlineStreamEnd(stream) { + const E = 0x45, + I = 0x49, + SPACE = 0x20, + LF = 0xa, + CR = 0xd, + NUL = 0x0; + const { + knownCommands + } = this.lexer, + startPos = stream.pos, + n = 15; + let state = 0, + ch, + maybeEIPos; + while ((ch = stream.getByte()) !== -1) { + if (state === 0) { + state = ch === E ? 1 : 0; + } else if (state === 1) { + state = ch === I ? 2 : 0; + } else { + if (ch === SPACE || ch === LF || ch === CR) { + maybeEIPos = stream.pos; + const followingBytes = stream.peekBytes(n); + const ii = followingBytes.length; + if (ii === 0) { + break; + } + for (let i = 0; i < ii; i++) { + ch = followingBytes[i]; + if (ch === NUL && followingBytes[i + 1] !== NUL) { + continue; + } + if (ch !== LF && ch !== CR && (ch < SPACE || ch > 0x7f)) { + state = 0; + break; + } + } + if (state !== 2) { + continue; + } + if (!knownCommands) { + (0, _util.warn)("findDefaultInlineStreamEnd - `lexer.knownCommands` is undefined."); + continue; + } + const tmpLexer = new Lexer(new _stream.Stream(followingBytes.slice()), knownCommands); + tmpLexer._hexStringWarn = () => {}; + let numArgs = 0; + while (true) { + const nextObj = tmpLexer.getObj(); + if (nextObj === _primitives.EOF) { + state = 0; + break; + } + if (nextObj instanceof _primitives.Cmd) { + const knownCommand = knownCommands[nextObj.cmd]; + if (!knownCommand) { + state = 0; + break; + } else if (knownCommand.variableArgs ? numArgs <= knownCommand.numArgs : numArgs === knownCommand.numArgs) { + break; + } + numArgs = 0; + continue; + } + numArgs++; + } + if (state === 2) { + break; + } + } else { + state = 0; + } + } + } + if (ch === -1) { + (0, _util.warn)("findDefaultInlineStreamEnd: " + "Reached the end of the stream without finding a valid EI marker"); + if (maybeEIPos) { + (0, _util.warn)('... trying to recover by using the last "EI" occurrence.'); + stream.skip(-(stream.pos - maybeEIPos)); + } + } + let endOffset = 4; + stream.skip(-endOffset); + ch = stream.peekByte(); + stream.skip(endOffset); + if (!(0, _core_utils.isWhiteSpace)(ch)) { + endOffset--; + } + return stream.pos - endOffset - startPos; + } + findDCTDecodeInlineStreamEnd(stream) { + const startPos = stream.pos; + let foundEOI = false, + b, + markerLength; + while ((b = stream.getByte()) !== -1) { + if (b !== 0xff) { + continue; + } + switch (stream.getByte()) { + case 0x00: + break; + case 0xff: + stream.skip(-1); + break; + case 0xd9: + foundEOI = true; + break; + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcd: + case 0xce: + case 0xcf: + case 0xc4: + case 0xcc: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + case 0xe0: + case 0xe1: + case 0xe2: + case 0xe3: + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: + case 0xe8: + case 0xe9: + case 0xea: + case 0xeb: + case 0xec: + case 0xed: + case 0xee: + case 0xef: + case 0xfe: + markerLength = stream.getUint16(); + if (markerLength > 2) { + stream.skip(markerLength - 2); + } else { + stream.skip(-2); + } + break; + } + if (foundEOI) { + break; + } + } + const length = stream.pos - startPos; + if (b === -1) { + (0, _util.warn)("Inline DCTDecode image stream: " + "EOI marker not found, searching for /EI/ instead."); + stream.skip(-length); + return this.findDefaultInlineStreamEnd(stream); + } + this.inlineStreamSkipEI(stream); + return length; + } + findASCII85DecodeInlineStreamEnd(stream) { + const TILDE = 0x7e, + GT = 0x3e; + const startPos = stream.pos; + let ch; + while ((ch = stream.getByte()) !== -1) { + if (ch === TILDE) { + const tildePos = stream.pos; + ch = stream.peekByte(); + while ((0, _core_utils.isWhiteSpace)(ch)) { + stream.skip(); + ch = stream.peekByte(); + } + if (ch === GT) { + stream.skip(); + break; + } + if (stream.pos > tildePos) { + const maybeEI = stream.peekBytes(2); + if (maybeEI[0] === 0x45 && maybeEI[1] === 0x49) { + break; + } + } + } + } + const length = stream.pos - startPos; + if (ch === -1) { + (0, _util.warn)("Inline ASCII85Decode image stream: " + "EOD marker not found, searching for /EI/ instead."); + stream.skip(-length); + return this.findDefaultInlineStreamEnd(stream); + } + this.inlineStreamSkipEI(stream); + return length; + } + findASCIIHexDecodeInlineStreamEnd(stream) { + const GT = 0x3e; + const startPos = stream.pos; + let ch; + while ((ch = stream.getByte()) !== -1) { + if (ch === GT) { + break; + } + } + const length = stream.pos - startPos; + if (ch === -1) { + (0, _util.warn)("Inline ASCIIHexDecode image stream: " + "EOD marker not found, searching for /EI/ instead."); + stream.skip(-length); + return this.findDefaultInlineStreamEnd(stream); + } + this.inlineStreamSkipEI(stream); + return length; + } + inlineStreamSkipEI(stream) { + const E = 0x45, + I = 0x49; + let state = 0, + ch; + while ((ch = stream.getByte()) !== -1) { + if (state === 0) { + state = ch === E ? 1 : 0; + } else if (state === 1) { + state = ch === I ? 2 : 0; + } else if (state === 2) { + break; + } + } + } + makeInlineImage(cipherTransform) { + const lexer = this.lexer; + const stream = lexer.stream; + const dictMap = Object.create(null); + let dictLength; + while (!(0, _primitives.isCmd)(this.buf1, "ID") && this.buf1 !== _primitives.EOF) { + if (!(this.buf1 instanceof _primitives.Name)) { + throw new _util.FormatError("Dictionary key must be a name object"); + } + const key = this.buf1.name; + this.shift(); + if (this.buf1 === _primitives.EOF) { + break; + } + dictMap[key] = this.getObj(cipherTransform); + } + if (lexer.beginInlineImagePos !== -1) { + dictLength = stream.pos - lexer.beginInlineImagePos; + } + const filter = this.xref.fetchIfRef(dictMap.F || dictMap.Filter); + let filterName; + if (filter instanceof _primitives.Name) { + filterName = filter.name; + } else if (Array.isArray(filter)) { + const filterZero = this.xref.fetchIfRef(filter[0]); + if (filterZero instanceof _primitives.Name) { + filterName = filterZero.name; + } + } + const startPos = stream.pos; + let length; + switch (filterName) { + case "DCT": + case "DCTDecode": + length = this.findDCTDecodeInlineStreamEnd(stream); + break; + case "A85": + case "ASCII85Decode": + length = this.findASCII85DecodeInlineStreamEnd(stream); + break; + case "AHx": + case "ASCIIHexDecode": + length = this.findASCIIHexDecodeInlineStreamEnd(stream); + break; + default: + length = this.findDefaultInlineStreamEnd(stream); + } + let cacheKey; + if (length < MAX_LENGTH_TO_CACHE && dictLength > 0) { + const initialStreamPos = stream.pos; + stream.pos = lexer.beginInlineImagePos; + cacheKey = getInlineImageCacheKey(stream.getBytes(dictLength + length)); + stream.pos = initialStreamPos; + const cacheEntry = this.imageCache[cacheKey]; + if (cacheEntry !== undefined) { + this.buf2 = _primitives.Cmd.get("EI"); + this.shift(); + cacheEntry.reset(); + return cacheEntry; + } + } + const dict = new _primitives.Dict(this.xref); + for (const key in dictMap) { + dict.set(key, dictMap[key]); + } + let imageStream = stream.makeSubStream(startPos, length, dict); + if (cipherTransform) { + imageStream = cipherTransform.createStream(imageStream, length); + } + imageStream = this.filter(imageStream, dict, length); + imageStream.dict = dict; + if (cacheKey !== undefined) { + imageStream.cacheKey = `inline_img_${++this._imageId}`; + this.imageCache[cacheKey] = imageStream; + } + this.buf2 = _primitives.Cmd.get("EI"); + this.shift(); + return imageStream; + } + _findStreamLength(startPos, signature) { + const { + stream + } = this.lexer; + stream.pos = startPos; + const SCAN_BLOCK_LENGTH = 2048; + const signatureLength = signature.length; + while (stream.pos < stream.end) { + const scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH); + const scanLength = scanBytes.length - signatureLength; + if (scanLength <= 0) { + break; + } + let pos = 0; + while (pos < scanLength) { + let j = 0; + while (j < signatureLength && scanBytes[pos + j] === signature[j]) { + j++; + } + if (j >= signatureLength) { + stream.pos += pos; + return stream.pos - startPos; + } + pos++; + } + stream.pos += scanLength; + } + return -1; + } + makeStream(dict, cipherTransform) { + const lexer = this.lexer; + let stream = lexer.stream; + lexer.skipToNextLine(); + const startPos = stream.pos - 1; + let length = dict.get("Length"); + if (!Number.isInteger(length)) { + (0, _util.info)(`Bad length "${length && length.toString()}" in stream.`); + length = 0; + } + stream.pos = startPos + length; + lexer.nextChar(); + if (this.tryShift() && (0, _primitives.isCmd)(this.buf2, "endstream")) { + this.shift(); + } else { + const ENDSTREAM_SIGNATURE = new Uint8Array([0x65, 0x6e, 0x64, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d]); + let actualLength = this._findStreamLength(startPos, ENDSTREAM_SIGNATURE); + if (actualLength < 0) { + const MAX_TRUNCATION = 1; + for (let i = 1; i <= MAX_TRUNCATION; i++) { + const end = ENDSTREAM_SIGNATURE.length - i; + const TRUNCATED_SIGNATURE = ENDSTREAM_SIGNATURE.slice(0, end); + const maybeLength = this._findStreamLength(startPos, TRUNCATED_SIGNATURE); + if (maybeLength >= 0) { + const lastByte = stream.peekBytes(end + 1)[end]; + if (!(0, _core_utils.isWhiteSpace)(lastByte)) { + break; + } + (0, _util.info)(`Found "${(0, _util.bytesToString)(TRUNCATED_SIGNATURE)}" when ` + "searching for endstream command."); + actualLength = maybeLength; + break; + } + } + if (actualLength < 0) { + throw new _util.FormatError("Missing endstream command."); + } + } + length = actualLength; + lexer.nextChar(); + this.shift(); + this.shift(); + } + this.shift(); + stream = stream.makeSubStream(startPos, length, dict); + if (cipherTransform) { + stream = cipherTransform.createStream(stream, length); + } + stream = this.filter(stream, dict, length); + stream.dict = dict; + return stream; + } + filter(stream, dict, length) { + let filter = dict.get("F", "Filter"); + let params = dict.get("DP", "DecodeParms"); + if (filter instanceof _primitives.Name) { + if (Array.isArray(params)) { + (0, _util.warn)("/DecodeParms should not be an Array, when /Filter is a Name."); + } + return this.makeFilter(stream, filter.name, length, params); + } + let maybeLength = length; + if (Array.isArray(filter)) { + const filterArray = filter; + const paramsArray = params; + for (let i = 0, ii = filterArray.length; i < ii; ++i) { + filter = this.xref.fetchIfRef(filterArray[i]); + if (!(filter instanceof _primitives.Name)) { + throw new _util.FormatError(`Bad filter name "${filter}"`); + } + params = null; + if (Array.isArray(paramsArray) && i in paramsArray) { + params = this.xref.fetchIfRef(paramsArray[i]); + } + stream = this.makeFilter(stream, filter.name, maybeLength, params); + maybeLength = null; + } + } + return stream; + } + makeFilter(stream, name, maybeLength, params) { + if (maybeLength === 0) { + (0, _util.warn)(`Empty "${name}" stream.`); + return new _stream.NullStream(); + } + try { + switch (name) { + case "Fl": + case "FlateDecode": + if (params) { + return new _predictor_stream.PredictorStream(new _flate_stream.FlateStream(stream, maybeLength), maybeLength, params); + } + return new _flate_stream.FlateStream(stream, maybeLength); + case "LZW": + case "LZWDecode": + let earlyChange = 1; + if (params) { + if (params.has("EarlyChange")) { + earlyChange = params.get("EarlyChange"); + } + return new _predictor_stream.PredictorStream(new _lzw_stream.LZWStream(stream, maybeLength, earlyChange), maybeLength, params); + } + return new _lzw_stream.LZWStream(stream, maybeLength, earlyChange); + case "DCT": + case "DCTDecode": + return new _jpeg_stream.JpegStream(stream, maybeLength, params); + case "JPX": + case "JPXDecode": + return new _jpx_stream.JpxStream(stream, maybeLength, params); + case "A85": + case "ASCII85Decode": + return new _ascii_85_stream.Ascii85Stream(stream, maybeLength); + case "AHx": + case "ASCIIHexDecode": + return new _ascii_hex_stream.AsciiHexStream(stream, maybeLength); + case "CCF": + case "CCITTFaxDecode": + return new _ccitt_stream.CCITTFaxStream(stream, maybeLength, params); + case "RL": + case "RunLengthDecode": + return new _run_length_stream.RunLengthStream(stream, maybeLength); + case "JBIG2Decode": + return new _jbig2_stream.Jbig2Stream(stream, maybeLength, params); + } + (0, _util.warn)(`Filter "${name}" is not supported.`); + return stream; + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.warn)(`Invalid stream: "${ex}"`); + return new _stream.NullStream(); + } + } +} +exports.Parser = Parser; +const specialChars = [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; +function toHexDigit(ch) { + if (ch >= 0x30 && ch <= 0x39) { + return ch & 0x0f; + } + if (ch >= 0x41 && ch <= 0x46 || ch >= 0x61 && ch <= 0x66) { + return (ch & 0x0f) + 9; + } + return -1; +} +class Lexer { + constructor(stream, knownCommands = null) { + this.stream = stream; + this.nextChar(); + this.strBuf = []; + this.knownCommands = knownCommands; + this._hexStringNumWarn = 0; + this.beginInlineImagePos = -1; + } + nextChar() { + return this.currentChar = this.stream.getByte(); + } + peekChar() { + return this.stream.peekByte(); + } + getNumber() { + let ch = this.currentChar; + let eNotation = false; + let divideBy = 0; + let sign = 1; + if (ch === 0x2d) { + sign = -1; + ch = this.nextChar(); + if (ch === 0x2d) { + ch = this.nextChar(); + } + } else if (ch === 0x2b) { + ch = this.nextChar(); + } + if (ch === 0x0a || ch === 0x0d) { + do { + ch = this.nextChar(); + } while (ch === 0x0a || ch === 0x0d); + } + if (ch === 0x2e) { + divideBy = 10; + ch = this.nextChar(); + } + if (ch < 0x30 || ch > 0x39) { + const msg = `Invalid number: ${String.fromCharCode(ch)} (charCode ${ch})`; + if ((0, _core_utils.isWhiteSpace)(ch) || ch === -1) { + (0, _util.info)(`Lexer.getNumber - "${msg}".`); + return 0; + } + throw new _util.FormatError(msg); + } + let baseValue = ch - 0x30; + let powerValue = 0; + let powerValueSign = 1; + while ((ch = this.nextChar()) >= 0) { + if (ch >= 0x30 && ch <= 0x39) { + const currentDigit = ch - 0x30; + if (eNotation) { + powerValue = powerValue * 10 + currentDigit; + } else { + if (divideBy !== 0) { + divideBy *= 10; + } + baseValue = baseValue * 10 + currentDigit; + } + } else if (ch === 0x2e) { + if (divideBy === 0) { + divideBy = 1; + } else { + break; + } + } else if (ch === 0x2d) { + (0, _util.warn)("Badly formatted number: minus sign in the middle"); + } else if (ch === 0x45 || ch === 0x65) { + ch = this.peekChar(); + if (ch === 0x2b || ch === 0x2d) { + powerValueSign = ch === 0x2d ? -1 : 1; + this.nextChar(); + } else if (ch < 0x30 || ch > 0x39) { + break; + } + eNotation = true; + } else { + break; + } + } + if (divideBy !== 0) { + baseValue /= divideBy; + } + if (eNotation) { + baseValue *= 10 ** (powerValueSign * powerValue); + } + return sign * baseValue; + } + getString() { + let numParen = 1; + let done = false; + const strBuf = this.strBuf; + strBuf.length = 0; + let ch = this.nextChar(); + while (true) { + let charBuffered = false; + switch (ch | 0) { + case -1: + (0, _util.warn)("Unterminated string"); + done = true; + break; + case 0x28: + ++numParen; + strBuf.push("("); + break; + case 0x29: + if (--numParen === 0) { + this.nextChar(); + done = true; + } else { + strBuf.push(")"); + } + break; + case 0x5c: + ch = this.nextChar(); + switch (ch) { + case -1: + (0, _util.warn)("Unterminated string"); + done = true; + break; + case 0x6e: + strBuf.push("\n"); + break; + case 0x72: + strBuf.push("\r"); + break; + case 0x74: + strBuf.push("\t"); + break; + case 0x62: + strBuf.push("\b"); + break; + case 0x66: + strBuf.push("\f"); + break; + case 0x5c: + case 0x28: + case 0x29: + strBuf.push(String.fromCharCode(ch)); + break; + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + let x = ch & 0x0f; + ch = this.nextChar(); + charBuffered = true; + if (ch >= 0x30 && ch <= 0x37) { + x = (x << 3) + (ch & 0x0f); + ch = this.nextChar(); + if (ch >= 0x30 && ch <= 0x37) { + charBuffered = false; + x = (x << 3) + (ch & 0x0f); + } + } + strBuf.push(String.fromCharCode(x)); + break; + case 0x0d: + if (this.peekChar() === 0x0a) { + this.nextChar(); + } + break; + case 0x0a: + break; + default: + strBuf.push(String.fromCharCode(ch)); + break; + } + break; + default: + strBuf.push(String.fromCharCode(ch)); + break; + } + if (done) { + break; + } + if (!charBuffered) { + ch = this.nextChar(); + } + } + return strBuf.join(""); + } + getName() { + let ch, previousCh; + const strBuf = this.strBuf; + strBuf.length = 0; + while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) { + if (ch === 0x23) { + ch = this.nextChar(); + if (specialChars[ch]) { + (0, _util.warn)("Lexer_getName: " + "NUMBER SIGN (#) should be followed by a hexadecimal number."); + strBuf.push("#"); + break; + } + const x = toHexDigit(ch); + if (x !== -1) { + previousCh = ch; + ch = this.nextChar(); + const x2 = toHexDigit(ch); + if (x2 === -1) { + (0, _util.warn)(`Lexer_getName: Illegal digit (${String.fromCharCode(ch)}) ` + "in hexadecimal number."); + strBuf.push("#", String.fromCharCode(previousCh)); + if (specialChars[ch]) { + break; + } + strBuf.push(String.fromCharCode(ch)); + continue; + } + strBuf.push(String.fromCharCode(x << 4 | x2)); + } else { + strBuf.push("#", String.fromCharCode(ch)); + } + } else { + strBuf.push(String.fromCharCode(ch)); + } + } + if (strBuf.length > 127) { + (0, _util.warn)(`Name token is longer than allowed by the spec: ${strBuf.length}`); + } + return _primitives.Name.get(strBuf.join("")); + } + _hexStringWarn(ch) { + const MAX_HEX_STRING_NUM_WARN = 5; + if (this._hexStringNumWarn++ === MAX_HEX_STRING_NUM_WARN) { + (0, _util.warn)("getHexString - ignoring additional invalid characters."); + return; + } + if (this._hexStringNumWarn > MAX_HEX_STRING_NUM_WARN) { + return; + } + (0, _util.warn)(`getHexString - ignoring invalid character: ${ch}`); + } + getHexString() { + const strBuf = this.strBuf; + strBuf.length = 0; + let ch = this.currentChar; + let isFirstHex = true; + let firstDigit, secondDigit; + this._hexStringNumWarn = 0; + while (true) { + if (ch < 0) { + (0, _util.warn)("Unterminated hex string"); + break; + } else if (ch === 0x3e) { + this.nextChar(); + break; + } else if (specialChars[ch] === 1) { + ch = this.nextChar(); + continue; + } else { + if (isFirstHex) { + firstDigit = toHexDigit(ch); + if (firstDigit === -1) { + this._hexStringWarn(ch); + ch = this.nextChar(); + continue; + } + } else { + secondDigit = toHexDigit(ch); + if (secondDigit === -1) { + this._hexStringWarn(ch); + ch = this.nextChar(); + continue; + } + strBuf.push(String.fromCharCode(firstDigit << 4 | secondDigit)); + } + isFirstHex = !isFirstHex; + ch = this.nextChar(); + } + } + return strBuf.join(""); + } + getObj() { + let comment = false; + let ch = this.currentChar; + while (true) { + if (ch < 0) { + return _primitives.EOF; + } + if (comment) { + if (ch === 0x0a || ch === 0x0d) { + comment = false; + } + } else if (ch === 0x25) { + comment = true; + } else if (specialChars[ch] !== 1) { + break; + } + ch = this.nextChar(); + } + switch (ch | 0) { + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x2b: + case 0x2d: + case 0x2e: + return this.getNumber(); + case 0x28: + return this.getString(); + case 0x2f: + return this.getName(); + case 0x5b: + this.nextChar(); + return _primitives.Cmd.get("["); + case 0x5d: + this.nextChar(); + return _primitives.Cmd.get("]"); + case 0x3c: + ch = this.nextChar(); + if (ch === 0x3c) { + this.nextChar(); + return _primitives.Cmd.get("<<"); + } + return this.getHexString(); + case 0x3e: + ch = this.nextChar(); + if (ch === 0x3e) { + this.nextChar(); + return _primitives.Cmd.get(">>"); + } + return _primitives.Cmd.get(">"); + case 0x7b: + this.nextChar(); + return _primitives.Cmd.get("{"); + case 0x7d: + this.nextChar(); + return _primitives.Cmd.get("}"); + case 0x29: + this.nextChar(); + throw new _util.FormatError(`Illegal character: ${ch}`); + } + let str = String.fromCharCode(ch); + if (ch < 0x20 || ch > 0x7f) { + const nextCh = this.peekChar(); + if (nextCh >= 0x20 && nextCh <= 0x7f) { + this.nextChar(); + return _primitives.Cmd.get(str); + } + } + const knownCommands = this.knownCommands; + let knownCommandFound = knownCommands?.[str] !== undefined; + while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) { + const possibleCommand = str + String.fromCharCode(ch); + if (knownCommandFound && knownCommands[possibleCommand] === undefined) { + break; + } + if (str.length === 128) { + throw new _util.FormatError(`Command token too long: ${str.length}`); + } + str = possibleCommand; + knownCommandFound = knownCommands?.[str] !== undefined; + } + if (str === "true") { + return true; + } + if (str === "false") { + return false; + } + if (str === "null") { + return null; + } + if (str === "BI") { + this.beginInlineImagePos = this.stream.pos; + } + return _primitives.Cmd.get(str); + } + skipToNextLine() { + let ch = this.currentChar; + while (ch >= 0) { + if (ch === 0x0d) { + ch = this.nextChar(); + if (ch === 0x0a) { + this.nextChar(); + } + break; + } else if (ch === 0x0a) { + this.nextChar(); + break; + } + ch = this.nextChar(); + } + } +} +exports.Lexer = Lexer; +class Linearization { + static create(stream) { + function getInt(linDict, name, allowZeroValue = false) { + const obj = linDict.get(name); + if (Number.isInteger(obj) && (allowZeroValue ? obj >= 0 : obj > 0)) { + return obj; + } + throw new Error(`The "${name}" parameter in the linearization ` + "dictionary is invalid."); + } + function getHints(linDict) { + const hints = linDict.get("H"); + let hintsLength; + if (Array.isArray(hints) && ((hintsLength = hints.length) === 2 || hintsLength === 4)) { + for (let index = 0; index < hintsLength; index++) { + const hint = hints[index]; + if (!(Number.isInteger(hint) && hint > 0)) { + throw new Error(`Hint (${index}) in the linearization dictionary is invalid.`); + } + } + return hints; + } + throw new Error("Hint array in the linearization dictionary is invalid."); + } + const parser = new Parser({ + lexer: new Lexer(stream), + xref: null + }); + const obj1 = parser.getObj(); + const obj2 = parser.getObj(); + const obj3 = parser.getObj(); + const linDict = parser.getObj(); + let obj, length; + if (!(Number.isInteger(obj1) && Number.isInteger(obj2) && (0, _primitives.isCmd)(obj3, "obj") && linDict instanceof _primitives.Dict && typeof (obj = linDict.get("Linearized")) === "number" && obj > 0)) { + return null; + } else if ((length = getInt(linDict, "L")) !== stream.length) { + throw new Error('The "L" parameter in the linearization dictionary ' + "does not equal the stream length."); + } + return { + length, + hints: getHints(linDict), + objectNumberFirst: getInt(linDict, "O"), + endFirst: getInt(linDict, "E"), + numPages: getInt(linDict, "N"), + mainXRefEntriesOffset: getInt(linDict, "T"), + pageFirst: linDict.has("P") ? getInt(linDict, "P", true) : 0 + }; + } +} +exports.Linearization = Linearization; + +/***/ }), +/* 17 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Ascii85Stream = void 0; +var _decode_stream = __w_pdfjs_require__(18); +var _core_utils = __w_pdfjs_require__(3); +class Ascii85Stream extends _decode_stream.DecodeStream { + constructor(str, maybeLength) { + if (maybeLength) { + maybeLength *= 0.8; + } + super(maybeLength); + this.str = str; + this.dict = str.dict; + this.input = new Uint8Array(5); + } + readBlock() { + const TILDA_CHAR = 0x7e; + const Z_LOWER_CHAR = 0x7a; + const EOF = -1; + const str = this.str; + let c = str.getByte(); + while ((0, _core_utils.isWhiteSpace)(c)) { + c = str.getByte(); + } + if (c === EOF || c === TILDA_CHAR) { + this.eof = true; + return; + } + const bufferLength = this.bufferLength; + let buffer, i; + if (c === Z_LOWER_CHAR) { + buffer = this.ensureBuffer(bufferLength + 4); + for (i = 0; i < 4; ++i) { + buffer[bufferLength + i] = 0; + } + this.bufferLength += 4; + } else { + const input = this.input; + input[0] = c; + for (i = 1; i < 5; ++i) { + c = str.getByte(); + while ((0, _core_utils.isWhiteSpace)(c)) { + c = str.getByte(); + } + input[i] = c; + if (c === EOF || c === TILDA_CHAR) { + break; + } + } + buffer = this.ensureBuffer(bufferLength + i - 1); + this.bufferLength += i - 1; + if (i < 5) { + for (; i < 5; ++i) { + input[i] = 0x21 + 84; + } + this.eof = true; + } + let t = 0; + for (i = 0; i < 5; ++i) { + t = t * 85 + (input[i] - 0x21); + } + for (i = 3; i >= 0; --i) { + buffer[bufferLength + i] = t & 0xff; + t >>= 8; + } + } + } +} +exports.Ascii85Stream = Ascii85Stream; + +/***/ }), +/* 18 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.StreamsSequenceStream = exports.DecodeStream = void 0; +var _base_stream = __w_pdfjs_require__(5); +var _stream = __w_pdfjs_require__(8); +const emptyBuffer = new Uint8Array(0); +class DecodeStream extends _base_stream.BaseStream { + constructor(maybeMinBufferLength) { + super(); + this._rawMinBufferLength = maybeMinBufferLength || 0; + this.pos = 0; + this.bufferLength = 0; + this.eof = false; + this.buffer = emptyBuffer; + this.minBufferLength = 512; + if (maybeMinBufferLength) { + while (this.minBufferLength < maybeMinBufferLength) { + this.minBufferLength *= 2; + } + } + } + get isEmpty() { + while (!this.eof && this.bufferLength === 0) { + this.readBlock(); + } + return this.bufferLength === 0; + } + ensureBuffer(requested) { + const buffer = this.buffer; + if (requested <= buffer.byteLength) { + return buffer; + } + let size = this.minBufferLength; + while (size < requested) { + size *= 2; + } + const buffer2 = new Uint8Array(size); + buffer2.set(buffer); + return this.buffer = buffer2; + } + getByte() { + const pos = this.pos; + while (this.bufferLength <= pos) { + if (this.eof) { + return -1; + } + this.readBlock(); + } + return this.buffer[this.pos++]; + } + getBytes(length) { + const pos = this.pos; + let end; + if (length) { + this.ensureBuffer(pos + length); + end = pos + length; + while (!this.eof && this.bufferLength < end) { + this.readBlock(); + } + const bufEnd = this.bufferLength; + if (end > bufEnd) { + end = bufEnd; + } + } else { + while (!this.eof) { + this.readBlock(); + } + end = this.bufferLength; + } + this.pos = end; + return this.buffer.subarray(pos, end); + } + reset() { + this.pos = 0; + } + makeSubStream(start, length, dict = null) { + if (length === undefined) { + while (!this.eof) { + this.readBlock(); + } + } else { + const end = start + length; + while (this.bufferLength <= end && !this.eof) { + this.readBlock(); + } + } + return new _stream.Stream(this.buffer, start, length, dict); + } + getBaseStreams() { + return this.str ? this.str.getBaseStreams() : null; + } +} +exports.DecodeStream = DecodeStream; +class StreamsSequenceStream extends DecodeStream { + constructor(streams, onError = null) { + let maybeLength = 0; + for (const stream of streams) { + maybeLength += stream instanceof DecodeStream ? stream._rawMinBufferLength : stream.length; + } + super(maybeLength); + this.streams = streams; + this._onError = onError; + } + readBlock() { + const streams = this.streams; + if (streams.length === 0) { + this.eof = true; + return; + } + const stream = streams.shift(); + let chunk; + try { + chunk = stream.getBytes(); + } catch (reason) { + if (this._onError) { + this._onError(reason, stream.dict?.objId); + return; + } + throw reason; + } + const bufferLength = this.bufferLength; + const newLength = bufferLength + chunk.length; + const buffer = this.ensureBuffer(newLength); + buffer.set(chunk, bufferLength); + this.bufferLength = newLength; + } + getBaseStreams() { + const baseStreamsBuf = []; + for (const stream of this.streams) { + const baseStreams = stream.getBaseStreams(); + if (baseStreams) { + baseStreamsBuf.push(...baseStreams); + } + } + return baseStreamsBuf.length > 0 ? baseStreamsBuf : null; + } +} +exports.StreamsSequenceStream = StreamsSequenceStream; + +/***/ }), +/* 19 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.AsciiHexStream = void 0; +var _decode_stream = __w_pdfjs_require__(18); +class AsciiHexStream extends _decode_stream.DecodeStream { + constructor(str, maybeLength) { + if (maybeLength) { + maybeLength *= 0.5; + } + super(maybeLength); + this.str = str; + this.dict = str.dict; + this.firstDigit = -1; + } + readBlock() { + const UPSTREAM_BLOCK_SIZE = 8000; + const bytes = this.str.getBytes(UPSTREAM_BLOCK_SIZE); + if (!bytes.length) { + this.eof = true; + return; + } + const maxDecodeLength = bytes.length + 1 >> 1; + const buffer = this.ensureBuffer(this.bufferLength + maxDecodeLength); + let bufferLength = this.bufferLength; + let firstDigit = this.firstDigit; + for (const ch of bytes) { + let digit; + if (ch >= 0x30 && ch <= 0x39) { + digit = ch & 0x0f; + } else if (ch >= 0x41 && ch <= 0x46 || ch >= 0x61 && ch <= 0x66) { + digit = (ch & 0x0f) + 9; + } else if (ch === 0x3e) { + this.eof = true; + break; + } else { + continue; + } + if (firstDigit < 0) { + firstDigit = digit; + } else { + buffer[bufferLength++] = firstDigit << 4 | digit; + firstDigit = -1; + } + } + if (firstDigit >= 0 && this.eof) { + buffer[bufferLength++] = firstDigit << 4; + firstDigit = -1; + } + this.firstDigit = firstDigit; + this.bufferLength = bufferLength; + } +} +exports.AsciiHexStream = AsciiHexStream; + +/***/ }), +/* 20 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.CCITTFaxStream = void 0; +var _ccitt = __w_pdfjs_require__(21); +var _decode_stream = __w_pdfjs_require__(18); +var _primitives = __w_pdfjs_require__(4); +class CCITTFaxStream extends _decode_stream.DecodeStream { + constructor(str, maybeLength, params) { + super(maybeLength); + this.str = str; + this.dict = str.dict; + if (!(params instanceof _primitives.Dict)) { + params = _primitives.Dict.empty; + } + const source = { + next() { + return str.getByte(); + } + }; + this.ccittFaxDecoder = new _ccitt.CCITTFaxDecoder(source, { + K: params.get("K"), + EndOfLine: params.get("EndOfLine"), + EncodedByteAlign: params.get("EncodedByteAlign"), + Columns: params.get("Columns"), + Rows: params.get("Rows"), + EndOfBlock: params.get("EndOfBlock"), + BlackIs1: params.get("BlackIs1") + }); + } + readBlock() { + while (!this.eof) { + const c = this.ccittFaxDecoder.readNextChar(); + if (c === -1) { + this.eof = true; + return; + } + this.ensureBuffer(this.bufferLength + 1); + this.buffer[this.bufferLength++] = c; + } + } +} +exports.CCITTFaxStream = CCITTFaxStream; + +/***/ }), +/* 21 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.CCITTFaxDecoder = void 0; +var _util = __w_pdfjs_require__(2); +const ccittEOL = -2; +const ccittEOF = -1; +const twoDimPass = 0; +const twoDimHoriz = 1; +const twoDimVert0 = 2; +const twoDimVertR1 = 3; +const twoDimVertL1 = 4; +const twoDimVertR2 = 5; +const twoDimVertL2 = 6; +const twoDimVertR3 = 7; +const twoDimVertL3 = 8; +const twoDimTable = [[-1, -1], [-1, -1], [7, twoDimVertL3], [7, twoDimVertR3], [6, twoDimVertL2], [6, twoDimVertL2], [6, twoDimVertR2], [6, twoDimVertR2], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [4, twoDimPass], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimHoriz], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertL1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [3, twoDimVertR1], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0], [1, twoDimVert0]]; +const whiteTable1 = [[-1, -1], [12, ccittEOL], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [11, 1792], [11, 1792], [12, 1984], [12, 2048], [12, 2112], [12, 2176], [12, 2240], [12, 2304], [11, 1856], [11, 1856], [11, 1920], [11, 1920], [12, 2368], [12, 2432], [12, 2496], [12, 2560]]; +const whiteTable2 = [[-1, -1], [-1, -1], [-1, -1], [-1, -1], [8, 29], [8, 29], [8, 30], [8, 30], [8, 45], [8, 45], [8, 46], [8, 46], [7, 22], [7, 22], [7, 22], [7, 22], [7, 23], [7, 23], [7, 23], [7, 23], [8, 47], [8, 47], [8, 48], [8, 48], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [6, 13], [7, 20], [7, 20], [7, 20], [7, 20], [8, 33], [8, 33], [8, 34], [8, 34], [8, 35], [8, 35], [8, 36], [8, 36], [8, 37], [8, 37], [8, 38], [8, 38], [7, 19], [7, 19], [7, 19], [7, 19], [8, 31], [8, 31], [8, 32], [8, 32], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [6, 12], [8, 53], [8, 53], [8, 54], [8, 54], [7, 26], [7, 26], [7, 26], [7, 26], [8, 39], [8, 39], [8, 40], [8, 40], [8, 41], [8, 41], [8, 42], [8, 42], [8, 43], [8, 43], [8, 44], [8, 44], [7, 21], [7, 21], [7, 21], [7, 21], [7, 28], [7, 28], [7, 28], [7, 28], [8, 61], [8, 61], [8, 62], [8, 62], [8, 63], [8, 63], [8, 0], [8, 0], [8, 320], [8, 320], [8, 384], [8, 384], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 10], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [5, 11], [7, 27], [7, 27], [7, 27], [7, 27], [8, 59], [8, 59], [8, 60], [8, 60], [9, 1472], [9, 1536], [9, 1600], [9, 1728], [7, 18], [7, 18], [7, 18], [7, 18], [7, 24], [7, 24], [7, 24], [7, 24], [8, 49], [8, 49], [8, 50], [8, 50], [8, 51], [8, 51], [8, 52], [8, 52], [7, 25], [7, 25], [7, 25], [7, 25], [8, 55], [8, 55], [8, 56], [8, 56], [8, 57], [8, 57], [8, 58], [8, 58], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 192], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [6, 1664], [8, 448], [8, 448], [8, 512], [8, 512], [9, 704], [9, 768], [8, 640], [8, 640], [8, 576], [8, 576], [9, 832], [9, 896], [9, 960], [9, 1024], [9, 1088], [9, 1152], [9, 1216], [9, 1280], [9, 1344], [9, 1408], [7, 256], [7, 256], [7, 256], [7, 256], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 2], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 128], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 8], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [5, 9], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 16], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [6, 17], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 4], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 14], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [6, 15], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [5, 64], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 6], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7], [4, 7]]; +const blackTable1 = [[-1, -1], [-1, -1], [12, ccittEOL], [12, ccittEOL], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [11, 1792], [11, 1792], [11, 1792], [11, 1792], [12, 1984], [12, 1984], [12, 2048], [12, 2048], [12, 2112], [12, 2112], [12, 2176], [12, 2176], [12, 2240], [12, 2240], [12, 2304], [12, 2304], [11, 1856], [11, 1856], [11, 1856], [11, 1856], [11, 1920], [11, 1920], [11, 1920], [11, 1920], [12, 2368], [12, 2368], [12, 2432], [12, 2432], [12, 2496], [12, 2496], [12, 2560], [12, 2560], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [12, 52], [12, 52], [13, 640], [13, 704], [13, 768], [13, 832], [12, 55], [12, 55], [12, 56], [12, 56], [13, 1280], [13, 1344], [13, 1408], [13, 1472], [12, 59], [12, 59], [12, 60], [12, 60], [13, 1536], [13, 1600], [11, 24], [11, 24], [11, 24], [11, 24], [11, 25], [11, 25], [11, 25], [11, 25], [13, 1664], [13, 1728], [12, 320], [12, 320], [12, 384], [12, 384], [12, 448], [12, 448], [13, 512], [13, 576], [12, 53], [12, 53], [12, 54], [12, 54], [13, 896], [13, 960], [13, 1024], [13, 1088], [13, 1152], [13, 1216], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64]]; +const blackTable2 = [[8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [11, 23], [11, 23], [12, 50], [12, 51], [12, 44], [12, 45], [12, 46], [12, 47], [12, 57], [12, 58], [12, 61], [12, 256], [10, 16], [10, 16], [10, 16], [10, 16], [10, 17], [10, 17], [10, 17], [10, 17], [12, 48], [12, 49], [12, 62], [12, 63], [12, 30], [12, 31], [12, 32], [12, 33], [12, 40], [12, 41], [11, 22], [11, 22], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [12, 128], [12, 192], [12, 26], [12, 27], [12, 28], [12, 29], [11, 19], [11, 19], [11, 20], [11, 20], [12, 34], [12, 35], [12, 36], [12, 37], [12, 38], [12, 39], [11, 21], [11, 21], [12, 42], [12, 43], [10, 0], [10, 0], [10, 0], [10, 0], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12]]; +const blackTable3 = [[-1, -1], [-1, -1], [-1, -1], [-1, -1], [6, 9], [6, 8], [5, 7], [5, 7], [4, 6], [4, 6], [4, 6], [4, 6], [4, 5], [4, 5], [4, 5], [4, 5], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2]]; +class CCITTFaxDecoder { + constructor(source, options = {}) { + if (!source || typeof source.next !== "function") { + throw new Error('CCITTFaxDecoder - invalid "source" parameter.'); + } + this.source = source; + this.eof = false; + this.encoding = options.K || 0; + this.eoline = options.EndOfLine || false; + this.byteAlign = options.EncodedByteAlign || false; + this.columns = options.Columns || 1728; + this.rows = options.Rows || 0; + this.eoblock = options.EndOfBlock ?? true; + this.black = options.BlackIs1 || false; + this.codingLine = new Uint32Array(this.columns + 1); + this.refLine = new Uint32Array(this.columns + 2); + this.codingLine[0] = this.columns; + this.codingPos = 0; + this.row = 0; + this.nextLine2D = this.encoding < 0; + this.inputBits = 0; + this.inputBuf = 0; + this.outputBits = 0; + this.rowsDone = false; + let code1; + while ((code1 = this._lookBits(12)) === 0) { + this._eatBits(1); + } + if (code1 === 1) { + this._eatBits(12); + } + if (this.encoding > 0) { + this.nextLine2D = !this._lookBits(1); + this._eatBits(1); + } + } + readNextChar() { + if (this.eof) { + return -1; + } + const refLine = this.refLine; + const codingLine = this.codingLine; + const columns = this.columns; + let refPos, blackPixels, bits, i; + if (this.outputBits === 0) { + if (this.rowsDone) { + this.eof = true; + } + if (this.eof) { + return -1; + } + this.err = false; + let code1, code2, code3; + if (this.nextLine2D) { + for (i = 0; codingLine[i] < columns; ++i) { + refLine[i] = codingLine[i]; + } + refLine[i++] = columns; + refLine[i] = columns; + codingLine[0] = 0; + this.codingPos = 0; + refPos = 0; + blackPixels = 0; + while (codingLine[this.codingPos] < columns) { + code1 = this._getTwoDimCode(); + switch (code1) { + case twoDimPass: + this._addPixels(refLine[refPos + 1], blackPixels); + if (refLine[refPos + 1] < columns) { + refPos += 2; + } + break; + case twoDimHoriz: + code1 = code2 = 0; + if (blackPixels) { + do { + code1 += code3 = this._getBlackCode(); + } while (code3 >= 64); + do { + code2 += code3 = this._getWhiteCode(); + } while (code3 >= 64); + } else { + do { + code1 += code3 = this._getWhiteCode(); + } while (code3 >= 64); + do { + code2 += code3 = this._getBlackCode(); + } while (code3 >= 64); + } + this._addPixels(codingLine[this.codingPos] + code1, blackPixels); + if (codingLine[this.codingPos] < columns) { + this._addPixels(codingLine[this.codingPos] + code2, blackPixels ^ 1); + } + while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) { + refPos += 2; + } + break; + case twoDimVertR3: + this._addPixels(refLine[refPos] + 3, blackPixels); + blackPixels ^= 1; + if (codingLine[this.codingPos] < columns) { + ++refPos; + while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) { + refPos += 2; + } + } + break; + case twoDimVertR2: + this._addPixels(refLine[refPos] + 2, blackPixels); + blackPixels ^= 1; + if (codingLine[this.codingPos] < columns) { + ++refPos; + while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) { + refPos += 2; + } + } + break; + case twoDimVertR1: + this._addPixels(refLine[refPos] + 1, blackPixels); + blackPixels ^= 1; + if (codingLine[this.codingPos] < columns) { + ++refPos; + while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) { + refPos += 2; + } + } + break; + case twoDimVert0: + this._addPixels(refLine[refPos], blackPixels); + blackPixels ^= 1; + if (codingLine[this.codingPos] < columns) { + ++refPos; + while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) { + refPos += 2; + } + } + break; + case twoDimVertL3: + this._addPixelsNeg(refLine[refPos] - 3, blackPixels); + blackPixels ^= 1; + if (codingLine[this.codingPos] < columns) { + if (refPos > 0) { + --refPos; + } else { + ++refPos; + } + while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) { + refPos += 2; + } + } + break; + case twoDimVertL2: + this._addPixelsNeg(refLine[refPos] - 2, blackPixels); + blackPixels ^= 1; + if (codingLine[this.codingPos] < columns) { + if (refPos > 0) { + --refPos; + } else { + ++refPos; + } + while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) { + refPos += 2; + } + } + break; + case twoDimVertL1: + this._addPixelsNeg(refLine[refPos] - 1, blackPixels); + blackPixels ^= 1; + if (codingLine[this.codingPos] < columns) { + if (refPos > 0) { + --refPos; + } else { + ++refPos; + } + while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) { + refPos += 2; + } + } + break; + case ccittEOF: + this._addPixels(columns, 0); + this.eof = true; + break; + default: + (0, _util.info)("bad 2d code"); + this._addPixels(columns, 0); + this.err = true; + } + } + } else { + codingLine[0] = 0; + this.codingPos = 0; + blackPixels = 0; + while (codingLine[this.codingPos] < columns) { + code1 = 0; + if (blackPixels) { + do { + code1 += code3 = this._getBlackCode(); + } while (code3 >= 64); + } else { + do { + code1 += code3 = this._getWhiteCode(); + } while (code3 >= 64); + } + this._addPixels(codingLine[this.codingPos] + code1, blackPixels); + blackPixels ^= 1; + } + } + let gotEOL = false; + if (this.byteAlign) { + this.inputBits &= ~7; + } + if (!this.eoblock && this.row === this.rows - 1) { + this.rowsDone = true; + } else { + code1 = this._lookBits(12); + if (this.eoline) { + while (code1 !== ccittEOF && code1 !== 1) { + this._eatBits(1); + code1 = this._lookBits(12); + } + } else { + while (code1 === 0) { + this._eatBits(1); + code1 = this._lookBits(12); + } + } + if (code1 === 1) { + this._eatBits(12); + gotEOL = true; + } else if (code1 === ccittEOF) { + this.eof = true; + } + } + if (!this.eof && this.encoding > 0 && !this.rowsDone) { + this.nextLine2D = !this._lookBits(1); + this._eatBits(1); + } + if (this.eoblock && gotEOL && this.byteAlign) { + code1 = this._lookBits(12); + if (code1 === 1) { + this._eatBits(12); + if (this.encoding > 0) { + this._lookBits(1); + this._eatBits(1); + } + if (this.encoding >= 0) { + for (i = 0; i < 4; ++i) { + code1 = this._lookBits(12); + if (code1 !== 1) { + (0, _util.info)("bad rtc code: " + code1); + } + this._eatBits(12); + if (this.encoding > 0) { + this._lookBits(1); + this._eatBits(1); + } + } + } + this.eof = true; + } + } else if (this.err && this.eoline) { + while (true) { + code1 = this._lookBits(13); + if (code1 === ccittEOF) { + this.eof = true; + return -1; + } + if (code1 >> 1 === 1) { + break; + } + this._eatBits(1); + } + this._eatBits(12); + if (this.encoding > 0) { + this._eatBits(1); + this.nextLine2D = !(code1 & 1); + } + } + this.outputBits = codingLine[0] > 0 ? codingLine[this.codingPos = 0] : codingLine[this.codingPos = 1]; + this.row++; + } + let c; + if (this.outputBits >= 8) { + c = this.codingPos & 1 ? 0 : 0xff; + this.outputBits -= 8; + if (this.outputBits === 0 && codingLine[this.codingPos] < columns) { + this.codingPos++; + this.outputBits = codingLine[this.codingPos] - codingLine[this.codingPos - 1]; + } + } else { + bits = 8; + c = 0; + do { + if (typeof this.outputBits !== "number") { + throw new _util.FormatError('Invalid /CCITTFaxDecode data, "outputBits" must be a number.'); + } + if (this.outputBits > bits) { + c <<= bits; + if (!(this.codingPos & 1)) { + c |= 0xff >> 8 - bits; + } + this.outputBits -= bits; + bits = 0; + } else { + c <<= this.outputBits; + if (!(this.codingPos & 1)) { + c |= 0xff >> 8 - this.outputBits; + } + bits -= this.outputBits; + this.outputBits = 0; + if (codingLine[this.codingPos] < columns) { + this.codingPos++; + this.outputBits = codingLine[this.codingPos] - codingLine[this.codingPos - 1]; + } else if (bits > 0) { + c <<= bits; + bits = 0; + } + } + } while (bits); + } + if (this.black) { + c ^= 0xff; + } + return c; + } + _addPixels(a1, blackPixels) { + const codingLine = this.codingLine; + let codingPos = this.codingPos; + if (a1 > codingLine[codingPos]) { + if (a1 > this.columns) { + (0, _util.info)("row is wrong length"); + this.err = true; + a1 = this.columns; + } + if (codingPos & 1 ^ blackPixels) { + ++codingPos; + } + codingLine[codingPos] = a1; + } + this.codingPos = codingPos; + } + _addPixelsNeg(a1, blackPixels) { + const codingLine = this.codingLine; + let codingPos = this.codingPos; + if (a1 > codingLine[codingPos]) { + if (a1 > this.columns) { + (0, _util.info)("row is wrong length"); + this.err = true; + a1 = this.columns; + } + if (codingPos & 1 ^ blackPixels) { + ++codingPos; + } + codingLine[codingPos] = a1; + } else if (a1 < codingLine[codingPos]) { + if (a1 < 0) { + (0, _util.info)("invalid code"); + this.err = true; + a1 = 0; + } + while (codingPos > 0 && a1 < codingLine[codingPos - 1]) { + --codingPos; + } + codingLine[codingPos] = a1; + } + this.codingPos = codingPos; + } + _findTableCode(start, end, table, limit) { + const limitValue = limit || 0; + for (let i = start; i <= end; ++i) { + let code = this._lookBits(i); + if (code === ccittEOF) { + return [true, 1, false]; + } + if (i < end) { + code <<= end - i; + } + if (!limitValue || code >= limitValue) { + const p = table[code - limitValue]; + if (p[0] === i) { + this._eatBits(i); + return [true, p[1], true]; + } + } + } + return [false, 0, false]; + } + _getTwoDimCode() { + let code = 0; + let p; + if (this.eoblock) { + code = this._lookBits(7); + p = twoDimTable[code]; + if (p?.[0] > 0) { + this._eatBits(p[0]); + return p[1]; + } + } else { + const result = this._findTableCode(1, 7, twoDimTable); + if (result[0] && result[2]) { + return result[1]; + } + } + (0, _util.info)("Bad two dim code"); + return ccittEOF; + } + _getWhiteCode() { + let code = 0; + let p; + if (this.eoblock) { + code = this._lookBits(12); + if (code === ccittEOF) { + return 1; + } + p = code >> 5 === 0 ? whiteTable1[code] : whiteTable2[code >> 3]; + if (p[0] > 0) { + this._eatBits(p[0]); + return p[1]; + } + } else { + let result = this._findTableCode(1, 9, whiteTable2); + if (result[0]) { + return result[1]; + } + result = this._findTableCode(11, 12, whiteTable1); + if (result[0]) { + return result[1]; + } + } + (0, _util.info)("bad white code"); + this._eatBits(1); + return 1; + } + _getBlackCode() { + let code, p; + if (this.eoblock) { + code = this._lookBits(13); + if (code === ccittEOF) { + return 1; + } + if (code >> 7 === 0) { + p = blackTable1[code]; + } else if (code >> 9 === 0 && code >> 7 !== 0) { + p = blackTable2[(code >> 1) - 64]; + } else { + p = blackTable3[code >> 7]; + } + if (p[0] > 0) { + this._eatBits(p[0]); + return p[1]; + } + } else { + let result = this._findTableCode(2, 6, blackTable3); + if (result[0]) { + return result[1]; + } + result = this._findTableCode(7, 12, blackTable2, 64); + if (result[0]) { + return result[1]; + } + result = this._findTableCode(10, 13, blackTable1); + if (result[0]) { + return result[1]; + } + } + (0, _util.info)("bad black code"); + this._eatBits(1); + return 1; + } + _lookBits(n) { + let c; + while (this.inputBits < n) { + if ((c = this.source.next()) === -1) { + if (this.inputBits === 0) { + return ccittEOF; + } + return this.inputBuf << n - this.inputBits & 0xffff >> 16 - n; + } + this.inputBuf = this.inputBuf << 8 | c; + this.inputBits += 8; + } + return this.inputBuf >> this.inputBits - n & 0xffff >> 16 - n; + } + _eatBits(n) { + if ((this.inputBits -= n) < 0) { + this.inputBits = 0; + } + } +} +exports.CCITTFaxDecoder = CCITTFaxDecoder; + +/***/ }), +/* 22 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.FlateStream = void 0; +var _decode_stream = __w_pdfjs_require__(18); +var _util = __w_pdfjs_require__(2); +const codeLenCodeMap = new Int32Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); +const lengthDecode = new Int32Array([0x00003, 0x00004, 0x00005, 0x00006, 0x00007, 0x00008, 0x00009, 0x0000a, 0x1000b, 0x1000d, 0x1000f, 0x10011, 0x20013, 0x20017, 0x2001b, 0x2001f, 0x30023, 0x3002b, 0x30033, 0x3003b, 0x40043, 0x40053, 0x40063, 0x40073, 0x50083, 0x500a3, 0x500c3, 0x500e3, 0x00102, 0x00102, 0x00102]); +const distDecode = new Int32Array([0x00001, 0x00002, 0x00003, 0x00004, 0x10005, 0x10007, 0x20009, 0x2000d, 0x30011, 0x30019, 0x40021, 0x40031, 0x50041, 0x50061, 0x60081, 0x600c1, 0x70101, 0x70181, 0x80201, 0x80301, 0x90401, 0x90601, 0xa0801, 0xa0c01, 0xb1001, 0xb1801, 0xc2001, 0xc3001, 0xd4001, 0xd6001]); +const fixedLitCodeTab = [new Int32Array([0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c0, 0x70108, 0x80060, 0x80020, 0x900a0, 0x80000, 0x80080, 0x80040, 0x900e0, 0x70104, 0x80058, 0x80018, 0x90090, 0x70114, 0x80078, 0x80038, 0x900d0, 0x7010c, 0x80068, 0x80028, 0x900b0, 0x80008, 0x80088, 0x80048, 0x900f0, 0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c8, 0x7010a, 0x80064, 0x80024, 0x900a8, 0x80004, 0x80084, 0x80044, 0x900e8, 0x70106, 0x8005c, 0x8001c, 0x90098, 0x70116, 0x8007c, 0x8003c, 0x900d8, 0x7010e, 0x8006c, 0x8002c, 0x900b8, 0x8000c, 0x8008c, 0x8004c, 0x900f8, 0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c4, 0x70109, 0x80062, 0x80022, 0x900a4, 0x80002, 0x80082, 0x80042, 0x900e4, 0x70105, 0x8005a, 0x8001a, 0x90094, 0x70115, 0x8007a, 0x8003a, 0x900d4, 0x7010d, 0x8006a, 0x8002a, 0x900b4, 0x8000a, 0x8008a, 0x8004a, 0x900f4, 0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cc, 0x7010b, 0x80066, 0x80026, 0x900ac, 0x80006, 0x80086, 0x80046, 0x900ec, 0x70107, 0x8005e, 0x8001e, 0x9009c, 0x70117, 0x8007e, 0x8003e, 0x900dc, 0x7010f, 0x8006e, 0x8002e, 0x900bc, 0x8000e, 0x8008e, 0x8004e, 0x900fc, 0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c2, 0x70108, 0x80061, 0x80021, 0x900a2, 0x80001, 0x80081, 0x80041, 0x900e2, 0x70104, 0x80059, 0x80019, 0x90092, 0x70114, 0x80079, 0x80039, 0x900d2, 0x7010c, 0x80069, 0x80029, 0x900b2, 0x80009, 0x80089, 0x80049, 0x900f2, 0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900ca, 0x7010a, 0x80065, 0x80025, 0x900aa, 0x80005, 0x80085, 0x80045, 0x900ea, 0x70106, 0x8005d, 0x8001d, 0x9009a, 0x70116, 0x8007d, 0x8003d, 0x900da, 0x7010e, 0x8006d, 0x8002d, 0x900ba, 0x8000d, 0x8008d, 0x8004d, 0x900fa, 0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c6, 0x70109, 0x80063, 0x80023, 0x900a6, 0x80003, 0x80083, 0x80043, 0x900e6, 0x70105, 0x8005b, 0x8001b, 0x90096, 0x70115, 0x8007b, 0x8003b, 0x900d6, 0x7010d, 0x8006b, 0x8002b, 0x900b6, 0x8000b, 0x8008b, 0x8004b, 0x900f6, 0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900ce, 0x7010b, 0x80067, 0x80027, 0x900ae, 0x80007, 0x80087, 0x80047, 0x900ee, 0x70107, 0x8005f, 0x8001f, 0x9009e, 0x70117, 0x8007f, 0x8003f, 0x900de, 0x7010f, 0x8006f, 0x8002f, 0x900be, 0x8000f, 0x8008f, 0x8004f, 0x900fe, 0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c1, 0x70108, 0x80060, 0x80020, 0x900a1, 0x80000, 0x80080, 0x80040, 0x900e1, 0x70104, 0x80058, 0x80018, 0x90091, 0x70114, 0x80078, 0x80038, 0x900d1, 0x7010c, 0x80068, 0x80028, 0x900b1, 0x80008, 0x80088, 0x80048, 0x900f1, 0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c9, 0x7010a, 0x80064, 0x80024, 0x900a9, 0x80004, 0x80084, 0x80044, 0x900e9, 0x70106, 0x8005c, 0x8001c, 0x90099, 0x70116, 0x8007c, 0x8003c, 0x900d9, 0x7010e, 0x8006c, 0x8002c, 0x900b9, 0x8000c, 0x8008c, 0x8004c, 0x900f9, 0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c5, 0x70109, 0x80062, 0x80022, 0x900a5, 0x80002, 0x80082, 0x80042, 0x900e5, 0x70105, 0x8005a, 0x8001a, 0x90095, 0x70115, 0x8007a, 0x8003a, 0x900d5, 0x7010d, 0x8006a, 0x8002a, 0x900b5, 0x8000a, 0x8008a, 0x8004a, 0x900f5, 0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cd, 0x7010b, 0x80066, 0x80026, 0x900ad, 0x80006, 0x80086, 0x80046, 0x900ed, 0x70107, 0x8005e, 0x8001e, 0x9009d, 0x70117, 0x8007e, 0x8003e, 0x900dd, 0x7010f, 0x8006e, 0x8002e, 0x900bd, 0x8000e, 0x8008e, 0x8004e, 0x900fd, 0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c3, 0x70108, 0x80061, 0x80021, 0x900a3, 0x80001, 0x80081, 0x80041, 0x900e3, 0x70104, 0x80059, 0x80019, 0x90093, 0x70114, 0x80079, 0x80039, 0x900d3, 0x7010c, 0x80069, 0x80029, 0x900b3, 0x80009, 0x80089, 0x80049, 0x900f3, 0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900cb, 0x7010a, 0x80065, 0x80025, 0x900ab, 0x80005, 0x80085, 0x80045, 0x900eb, 0x70106, 0x8005d, 0x8001d, 0x9009b, 0x70116, 0x8007d, 0x8003d, 0x900db, 0x7010e, 0x8006d, 0x8002d, 0x900bb, 0x8000d, 0x8008d, 0x8004d, 0x900fb, 0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c7, 0x70109, 0x80063, 0x80023, 0x900a7, 0x80003, 0x80083, 0x80043, 0x900e7, 0x70105, 0x8005b, 0x8001b, 0x90097, 0x70115, 0x8007b, 0x8003b, 0x900d7, 0x7010d, 0x8006b, 0x8002b, 0x900b7, 0x8000b, 0x8008b, 0x8004b, 0x900f7, 0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900cf, 0x7010b, 0x80067, 0x80027, 0x900af, 0x80007, 0x80087, 0x80047, 0x900ef, 0x70107, 0x8005f, 0x8001f, 0x9009f, 0x70117, 0x8007f, 0x8003f, 0x900df, 0x7010f, 0x8006f, 0x8002f, 0x900bf, 0x8000f, 0x8008f, 0x8004f, 0x900ff]), 9]; +const fixedDistCodeTab = [new Int32Array([0x50000, 0x50010, 0x50008, 0x50018, 0x50004, 0x50014, 0x5000c, 0x5001c, 0x50002, 0x50012, 0x5000a, 0x5001a, 0x50006, 0x50016, 0x5000e, 0x00000, 0x50001, 0x50011, 0x50009, 0x50019, 0x50005, 0x50015, 0x5000d, 0x5001d, 0x50003, 0x50013, 0x5000b, 0x5001b, 0x50007, 0x50017, 0x5000f, 0x00000]), 5]; +class FlateStream extends _decode_stream.DecodeStream { + constructor(str, maybeLength) { + super(maybeLength); + this.str = str; + this.dict = str.dict; + const cmf = str.getByte(); + const flg = str.getByte(); + if (cmf === -1 || flg === -1) { + throw new _util.FormatError(`Invalid header in flate stream: ${cmf}, ${flg}`); + } + if ((cmf & 0x0f) !== 0x08) { + throw new _util.FormatError(`Unknown compression method in flate stream: ${cmf}, ${flg}`); + } + if (((cmf << 8) + flg) % 31 !== 0) { + throw new _util.FormatError(`Bad FCHECK in flate stream: ${cmf}, ${flg}`); + } + if (flg & 0x20) { + throw new _util.FormatError(`FDICT bit set in flate stream: ${cmf}, ${flg}`); + } + this.codeSize = 0; + this.codeBuf = 0; + } + getBits(bits) { + const str = this.str; + let codeSize = this.codeSize; + let codeBuf = this.codeBuf; + let b; + while (codeSize < bits) { + if ((b = str.getByte()) === -1) { + throw new _util.FormatError("Bad encoding in flate stream"); + } + codeBuf |= b << codeSize; + codeSize += 8; + } + b = codeBuf & (1 << bits) - 1; + this.codeBuf = codeBuf >> bits; + this.codeSize = codeSize -= bits; + return b; + } + getCode(table) { + const str = this.str; + const codes = table[0]; + const maxLen = table[1]; + let codeSize = this.codeSize; + let codeBuf = this.codeBuf; + let b; + while (codeSize < maxLen) { + if ((b = str.getByte()) === -1) { + break; + } + codeBuf |= b << codeSize; + codeSize += 8; + } + const code = codes[codeBuf & (1 << maxLen) - 1]; + const codeLen = code >> 16; + const codeVal = code & 0xffff; + if (codeLen < 1 || codeSize < codeLen) { + throw new _util.FormatError("Bad encoding in flate stream"); + } + this.codeBuf = codeBuf >> codeLen; + this.codeSize = codeSize - codeLen; + return codeVal; + } + generateHuffmanTable(lengths) { + const n = lengths.length; + let maxLen = 0; + let i; + for (i = 0; i < n; ++i) { + if (lengths[i] > maxLen) { + maxLen = lengths[i]; + } + } + const size = 1 << maxLen; + const codes = new Int32Array(size); + for (let len = 1, code = 0, skip = 2; len <= maxLen; ++len, code <<= 1, skip <<= 1) { + for (let val = 0; val < n; ++val) { + if (lengths[val] === len) { + let code2 = 0; + let t = code; + for (i = 0; i < len; ++i) { + code2 = code2 << 1 | t & 1; + t >>= 1; + } + for (i = code2; i < size; i += skip) { + codes[i] = len << 16 | val; + } + ++code; + } + } + } + return [codes, maxLen]; + } + readBlock() { + let buffer, len; + const str = this.str; + let hdr = this.getBits(3); + if (hdr & 1) { + this.eof = true; + } + hdr >>= 1; + if (hdr === 0) { + let b; + if ((b = str.getByte()) === -1) { + throw new _util.FormatError("Bad block header in flate stream"); + } + let blockLen = b; + if ((b = str.getByte()) === -1) { + throw new _util.FormatError("Bad block header in flate stream"); + } + blockLen |= b << 8; + if ((b = str.getByte()) === -1) { + throw new _util.FormatError("Bad block header in flate stream"); + } + let check = b; + if ((b = str.getByte()) === -1) { + throw new _util.FormatError("Bad block header in flate stream"); + } + check |= b << 8; + if (check !== (~blockLen & 0xffff) && (blockLen !== 0 || check !== 0)) { + throw new _util.FormatError("Bad uncompressed block length in flate stream"); + } + this.codeBuf = 0; + this.codeSize = 0; + const bufferLength = this.bufferLength, + end = bufferLength + blockLen; + buffer = this.ensureBuffer(end); + this.bufferLength = end; + if (blockLen === 0) { + if (str.peekByte() === -1) { + this.eof = true; + } + } else { + const block = str.getBytes(blockLen); + buffer.set(block, bufferLength); + if (block.length < blockLen) { + this.eof = true; + } + } + return; + } + let litCodeTable; + let distCodeTable; + if (hdr === 1) { + litCodeTable = fixedLitCodeTab; + distCodeTable = fixedDistCodeTab; + } else if (hdr === 2) { + const numLitCodes = this.getBits(5) + 257; + const numDistCodes = this.getBits(5) + 1; + const numCodeLenCodes = this.getBits(4) + 4; + const codeLenCodeLengths = new Uint8Array(codeLenCodeMap.length); + let i; + for (i = 0; i < numCodeLenCodes; ++i) { + codeLenCodeLengths[codeLenCodeMap[i]] = this.getBits(3); + } + const codeLenCodeTab = this.generateHuffmanTable(codeLenCodeLengths); + len = 0; + i = 0; + const codes = numLitCodes + numDistCodes; + const codeLengths = new Uint8Array(codes); + let bitsLength, bitsOffset, what; + while (i < codes) { + const code = this.getCode(codeLenCodeTab); + if (code === 16) { + bitsLength = 2; + bitsOffset = 3; + what = len; + } else if (code === 17) { + bitsLength = 3; + bitsOffset = 3; + what = len = 0; + } else if (code === 18) { + bitsLength = 7; + bitsOffset = 11; + what = len = 0; + } else { + codeLengths[i++] = len = code; + continue; + } + let repeatLength = this.getBits(bitsLength) + bitsOffset; + while (repeatLength-- > 0) { + codeLengths[i++] = what; + } + } + litCodeTable = this.generateHuffmanTable(codeLengths.subarray(0, numLitCodes)); + distCodeTable = this.generateHuffmanTable(codeLengths.subarray(numLitCodes, codes)); + } else { + throw new _util.FormatError("Unknown block type in flate stream"); + } + buffer = this.buffer; + let limit = buffer ? buffer.length : 0; + let pos = this.bufferLength; + while (true) { + let code1 = this.getCode(litCodeTable); + if (code1 < 256) { + if (pos + 1 >= limit) { + buffer = this.ensureBuffer(pos + 1); + limit = buffer.length; + } + buffer[pos++] = code1; + continue; + } + if (code1 === 256) { + this.bufferLength = pos; + return; + } + code1 -= 257; + code1 = lengthDecode[code1]; + let code2 = code1 >> 16; + if (code2 > 0) { + code2 = this.getBits(code2); + } + len = (code1 & 0xffff) + code2; + code1 = this.getCode(distCodeTable); + code1 = distDecode[code1]; + code2 = code1 >> 16; + if (code2 > 0) { + code2 = this.getBits(code2); + } + const dist = (code1 & 0xffff) + code2; + if (pos + len >= limit) { + buffer = this.ensureBuffer(pos + len); + limit = buffer.length; + } + for (let k = 0; k < len; ++k, ++pos) { + buffer[pos] = buffer[pos - dist]; + } + } + } +} +exports.FlateStream = FlateStream; + +/***/ }), +/* 23 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Jbig2Stream = void 0; +var _base_stream = __w_pdfjs_require__(5); +var _decode_stream = __w_pdfjs_require__(18); +var _primitives = __w_pdfjs_require__(4); +var _jbig = __w_pdfjs_require__(24); +var _util = __w_pdfjs_require__(2); +class Jbig2Stream extends _decode_stream.DecodeStream { + constructor(stream, maybeLength, params) { + super(maybeLength); + this.stream = stream; + this.dict = stream.dict; + this.maybeLength = maybeLength; + this.params = params; + } + get bytes() { + return (0, _util.shadow)(this, "bytes", this.stream.getBytes(this.maybeLength)); + } + ensureBuffer(requested) {} + readBlock() { + if (this.eof) { + return; + } + const jbig2Image = new _jbig.Jbig2Image(); + const chunks = []; + if (this.params instanceof _primitives.Dict) { + const globalsStream = this.params.get("JBIG2Globals"); + if (globalsStream instanceof _base_stream.BaseStream) { + const globals = globalsStream.getBytes(); + chunks.push({ + data: globals, + start: 0, + end: globals.length + }); + } + } + chunks.push({ + data: this.bytes, + start: 0, + end: this.bytes.length + }); + const data = jbig2Image.parseChunks(chunks); + const dataLength = data.length; + for (let i = 0; i < dataLength; i++) { + data[i] ^= 0xff; + } + this.buffer = data; + this.bufferLength = dataLength; + this.eof = true; + } +} +exports.Jbig2Stream = Jbig2Stream; + +/***/ }), +/* 24 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Jbig2Image = void 0; +var _util = __w_pdfjs_require__(2); +var _core_utils = __w_pdfjs_require__(3); +var _arithmetic_decoder = __w_pdfjs_require__(25); +var _ccitt = __w_pdfjs_require__(21); +class Jbig2Error extends _util.BaseException { + constructor(msg) { + super(`JBIG2 error: ${msg}`, "Jbig2Error"); + } +} +class ContextCache { + getContexts(id) { + if (id in this) { + return this[id]; + } + return this[id] = new Int8Array(1 << 16); + } +} +class DecodingContext { + constructor(data, start, end) { + this.data = data; + this.start = start; + this.end = end; + } + get decoder() { + const decoder = new _arithmetic_decoder.ArithmeticDecoder(this.data, this.start, this.end); + return (0, _util.shadow)(this, "decoder", decoder); + } + get contextCache() { + const cache = new ContextCache(); + return (0, _util.shadow)(this, "contextCache", cache); + } +} +const MAX_INT_32 = 2 ** 31 - 1; +const MIN_INT_32 = -(2 ** 31); +function decodeInteger(contextCache, procedure, decoder) { + const contexts = contextCache.getContexts(procedure); + let prev = 1; + function readBits(length) { + let v = 0; + for (let i = 0; i < length; i++) { + const bit = decoder.readBit(contexts, prev); + prev = prev < 256 ? prev << 1 | bit : (prev << 1 | bit) & 511 | 256; + v = v << 1 | bit; + } + return v >>> 0; + } + const sign = readBits(1); + const value = readBits(1) ? readBits(1) ? readBits(1) ? readBits(1) ? readBits(1) ? readBits(32) + 4436 : readBits(12) + 340 : readBits(8) + 84 : readBits(6) + 20 : readBits(4) + 4 : readBits(2); + let signedValue; + if (sign === 0) { + signedValue = value; + } else if (value > 0) { + signedValue = -value; + } + if (signedValue >= MIN_INT_32 && signedValue <= MAX_INT_32) { + return signedValue; + } + return null; +} +function decodeIAID(contextCache, decoder, codeLength) { + const contexts = contextCache.getContexts("IAID"); + let prev = 1; + for (let i = 0; i < codeLength; i++) { + const bit = decoder.readBit(contexts, prev); + prev = prev << 1 | bit; + } + if (codeLength < 31) { + return prev & (1 << codeLength) - 1; + } + return prev & 0x7fffffff; +} +const SegmentTypes = ["SymbolDictionary", null, null, null, "IntermediateTextRegion", null, "ImmediateTextRegion", "ImmediateLosslessTextRegion", null, null, null, null, null, null, null, null, "PatternDictionary", null, null, null, "IntermediateHalftoneRegion", null, "ImmediateHalftoneRegion", "ImmediateLosslessHalftoneRegion", null, null, null, null, null, null, null, null, null, null, null, null, "IntermediateGenericRegion", null, "ImmediateGenericRegion", "ImmediateLosslessGenericRegion", "IntermediateGenericRefinementRegion", null, "ImmediateGenericRefinementRegion", "ImmediateLosslessGenericRefinementRegion", null, null, null, null, "PageInformation", "EndOfPage", "EndOfStripe", "EndOfFile", "Profiles", "Tables", null, null, null, null, null, null, null, null, "Extension"]; +const CodingTemplates = [[{ + x: -1, + y: -2 +}, { + x: 0, + y: -2 +}, { + x: 1, + y: -2 +}, { + x: -2, + y: -1 +}, { + x: -1, + y: -1 +}, { + x: 0, + y: -1 +}, { + x: 1, + y: -1 +}, { + x: 2, + y: -1 +}, { + x: -4, + y: 0 +}, { + x: -3, + y: 0 +}, { + x: -2, + y: 0 +}, { + x: -1, + y: 0 +}], [{ + x: -1, + y: -2 +}, { + x: 0, + y: -2 +}, { + x: 1, + y: -2 +}, { + x: 2, + y: -2 +}, { + x: -2, + y: -1 +}, { + x: -1, + y: -1 +}, { + x: 0, + y: -1 +}, { + x: 1, + y: -1 +}, { + x: 2, + y: -1 +}, { + x: -3, + y: 0 +}, { + x: -2, + y: 0 +}, { + x: -1, + y: 0 +}], [{ + x: -1, + y: -2 +}, { + x: 0, + y: -2 +}, { + x: 1, + y: -2 +}, { + x: -2, + y: -1 +}, { + x: -1, + y: -1 +}, { + x: 0, + y: -1 +}, { + x: 1, + y: -1 +}, { + x: -2, + y: 0 +}, { + x: -1, + y: 0 +}], [{ + x: -3, + y: -1 +}, { + x: -2, + y: -1 +}, { + x: -1, + y: -1 +}, { + x: 0, + y: -1 +}, { + x: 1, + y: -1 +}, { + x: -4, + y: 0 +}, { + x: -3, + y: 0 +}, { + x: -2, + y: 0 +}, { + x: -1, + y: 0 +}]]; +const RefinementTemplates = [{ + coding: [{ + x: 0, + y: -1 + }, { + x: 1, + y: -1 + }, { + x: -1, + y: 0 + }], + reference: [{ + x: 0, + y: -1 + }, { + x: 1, + y: -1 + }, { + x: -1, + y: 0 + }, { + x: 0, + y: 0 + }, { + x: 1, + y: 0 + }, { + x: -1, + y: 1 + }, { + x: 0, + y: 1 + }, { + x: 1, + y: 1 + }] +}, { + coding: [{ + x: -1, + y: -1 + }, { + x: 0, + y: -1 + }, { + x: 1, + y: -1 + }, { + x: -1, + y: 0 + }], + reference: [{ + x: 0, + y: -1 + }, { + x: -1, + y: 0 + }, { + x: 0, + y: 0 + }, { + x: 1, + y: 0 + }, { + x: 0, + y: 1 + }, { + x: 1, + y: 1 + }] +}]; +const ReusedContexts = [0x9b25, 0x0795, 0x00e5, 0x0195]; +const RefinementReusedContexts = [0x0020, 0x0008]; +function decodeBitmapTemplate0(width, height, decodingContext) { + const decoder = decodingContext.decoder; + const contexts = decodingContext.contextCache.getContexts("GB"); + const bitmap = []; + let contextLabel, i, j, pixel, row, row1, row2; + const OLD_PIXEL_MASK = 0x7bf7; + for (i = 0; i < height; i++) { + row = bitmap[i] = new Uint8Array(width); + row1 = i < 1 ? row : bitmap[i - 1]; + row2 = i < 2 ? row : bitmap[i - 2]; + contextLabel = row2[0] << 13 | row2[1] << 12 | row2[2] << 11 | row1[0] << 7 | row1[1] << 6 | row1[2] << 5 | row1[3] << 4; + for (j = 0; j < width; j++) { + row[j] = pixel = decoder.readBit(contexts, contextLabel); + contextLabel = (contextLabel & OLD_PIXEL_MASK) << 1 | (j + 3 < width ? row2[j + 3] << 11 : 0) | (j + 4 < width ? row1[j + 4] << 4 : 0) | pixel; + } + } + return bitmap; +} +function decodeBitmap(mmr, width, height, templateIndex, prediction, skip, at, decodingContext) { + if (mmr) { + const input = new Reader(decodingContext.data, decodingContext.start, decodingContext.end); + return decodeMMRBitmap(input, width, height, false); + } + if (templateIndex === 0 && !skip && !prediction && at.length === 4 && at[0].x === 3 && at[0].y === -1 && at[1].x === -3 && at[1].y === -1 && at[2].x === 2 && at[2].y === -2 && at[3].x === -2 && at[3].y === -2) { + return decodeBitmapTemplate0(width, height, decodingContext); + } + const useskip = !!skip; + const template = CodingTemplates[templateIndex].concat(at); + template.sort(function (a, b) { + return a.y - b.y || a.x - b.x; + }); + const templateLength = template.length; + const templateX = new Int8Array(templateLength); + const templateY = new Int8Array(templateLength); + const changingTemplateEntries = []; + let reuseMask = 0, + minX = 0, + maxX = 0, + minY = 0; + let c, k; + for (k = 0; k < templateLength; k++) { + templateX[k] = template[k].x; + templateY[k] = template[k].y; + minX = Math.min(minX, template[k].x); + maxX = Math.max(maxX, template[k].x); + minY = Math.min(minY, template[k].y); + if (k < templateLength - 1 && template[k].y === template[k + 1].y && template[k].x === template[k + 1].x - 1) { + reuseMask |= 1 << templateLength - 1 - k; + } else { + changingTemplateEntries.push(k); + } + } + const changingEntriesLength = changingTemplateEntries.length; + const changingTemplateX = new Int8Array(changingEntriesLength); + const changingTemplateY = new Int8Array(changingEntriesLength); + const changingTemplateBit = new Uint16Array(changingEntriesLength); + for (c = 0; c < changingEntriesLength; c++) { + k = changingTemplateEntries[c]; + changingTemplateX[c] = template[k].x; + changingTemplateY[c] = template[k].y; + changingTemplateBit[c] = 1 << templateLength - 1 - k; + } + const sbb_left = -minX; + const sbb_top = -minY; + const sbb_right = width - maxX; + const pseudoPixelContext = ReusedContexts[templateIndex]; + let row = new Uint8Array(width); + const bitmap = []; + const decoder = decodingContext.decoder; + const contexts = decodingContext.contextCache.getContexts("GB"); + let ltp = 0, + j, + i0, + j0, + contextLabel = 0, + bit, + shift; + for (let i = 0; i < height; i++) { + if (prediction) { + const sltp = decoder.readBit(contexts, pseudoPixelContext); + ltp ^= sltp; + if (ltp) { + bitmap.push(row); + continue; + } + } + row = new Uint8Array(row); + bitmap.push(row); + for (j = 0; j < width; j++) { + if (useskip && skip[i][j]) { + row[j] = 0; + continue; + } + if (j >= sbb_left && j < sbb_right && i >= sbb_top) { + contextLabel = contextLabel << 1 & reuseMask; + for (k = 0; k < changingEntriesLength; k++) { + i0 = i + changingTemplateY[k]; + j0 = j + changingTemplateX[k]; + bit = bitmap[i0][j0]; + if (bit) { + bit = changingTemplateBit[k]; + contextLabel |= bit; + } + } + } else { + contextLabel = 0; + shift = templateLength - 1; + for (k = 0; k < templateLength; k++, shift--) { + j0 = j + templateX[k]; + if (j0 >= 0 && j0 < width) { + i0 = i + templateY[k]; + if (i0 >= 0) { + bit = bitmap[i0][j0]; + if (bit) { + contextLabel |= bit << shift; + } + } + } + } + } + const pixel = decoder.readBit(contexts, contextLabel); + row[j] = pixel; + } + } + return bitmap; +} +function decodeRefinement(width, height, templateIndex, referenceBitmap, offsetX, offsetY, prediction, at, decodingContext) { + let codingTemplate = RefinementTemplates[templateIndex].coding; + if (templateIndex === 0) { + codingTemplate = codingTemplate.concat([at[0]]); + } + const codingTemplateLength = codingTemplate.length; + const codingTemplateX = new Int32Array(codingTemplateLength); + const codingTemplateY = new Int32Array(codingTemplateLength); + let k; + for (k = 0; k < codingTemplateLength; k++) { + codingTemplateX[k] = codingTemplate[k].x; + codingTemplateY[k] = codingTemplate[k].y; + } + let referenceTemplate = RefinementTemplates[templateIndex].reference; + if (templateIndex === 0) { + referenceTemplate = referenceTemplate.concat([at[1]]); + } + const referenceTemplateLength = referenceTemplate.length; + const referenceTemplateX = new Int32Array(referenceTemplateLength); + const referenceTemplateY = new Int32Array(referenceTemplateLength); + for (k = 0; k < referenceTemplateLength; k++) { + referenceTemplateX[k] = referenceTemplate[k].x; + referenceTemplateY[k] = referenceTemplate[k].y; + } + const referenceWidth = referenceBitmap[0].length; + const referenceHeight = referenceBitmap.length; + const pseudoPixelContext = RefinementReusedContexts[templateIndex]; + const bitmap = []; + const decoder = decodingContext.decoder; + const contexts = decodingContext.contextCache.getContexts("GR"); + let ltp = 0; + for (let i = 0; i < height; i++) { + if (prediction) { + const sltp = decoder.readBit(contexts, pseudoPixelContext); + ltp ^= sltp; + if (ltp) { + throw new Jbig2Error("prediction is not supported"); + } + } + const row = new Uint8Array(width); + bitmap.push(row); + for (let j = 0; j < width; j++) { + let i0, j0; + let contextLabel = 0; + for (k = 0; k < codingTemplateLength; k++) { + i0 = i + codingTemplateY[k]; + j0 = j + codingTemplateX[k]; + if (i0 < 0 || j0 < 0 || j0 >= width) { + contextLabel <<= 1; + } else { + contextLabel = contextLabel << 1 | bitmap[i0][j0]; + } + } + for (k = 0; k < referenceTemplateLength; k++) { + i0 = i + referenceTemplateY[k] - offsetY; + j0 = j + referenceTemplateX[k] - offsetX; + if (i0 < 0 || i0 >= referenceHeight || j0 < 0 || j0 >= referenceWidth) { + contextLabel <<= 1; + } else { + contextLabel = contextLabel << 1 | referenceBitmap[i0][j0]; + } + } + const pixel = decoder.readBit(contexts, contextLabel); + row[j] = pixel; + } + } + return bitmap; +} +function decodeSymbolDictionary(huffman, refinement, symbols, numberOfNewSymbols, numberOfExportedSymbols, huffmanTables, templateIndex, at, refinementTemplateIndex, refinementAt, decodingContext, huffmanInput) { + if (huffman && refinement) { + throw new Jbig2Error("symbol refinement with Huffman is not supported"); + } + const newSymbols = []; + let currentHeight = 0; + let symbolCodeLength = (0, _core_utils.log2)(symbols.length + numberOfNewSymbols); + const decoder = decodingContext.decoder; + const contextCache = decodingContext.contextCache; + let tableB1, symbolWidths; + if (huffman) { + tableB1 = getStandardTable(1); + symbolWidths = []; + symbolCodeLength = Math.max(symbolCodeLength, 1); + } + while (newSymbols.length < numberOfNewSymbols) { + const deltaHeight = huffman ? huffmanTables.tableDeltaHeight.decode(huffmanInput) : decodeInteger(contextCache, "IADH", decoder); + currentHeight += deltaHeight; + let currentWidth = 0, + totalWidth = 0; + const firstSymbol = huffman ? symbolWidths.length : 0; + while (true) { + const deltaWidth = huffman ? huffmanTables.tableDeltaWidth.decode(huffmanInput) : decodeInteger(contextCache, "IADW", decoder); + if (deltaWidth === null) { + break; + } + currentWidth += deltaWidth; + totalWidth += currentWidth; + let bitmap; + if (refinement) { + const numberOfInstances = decodeInteger(contextCache, "IAAI", decoder); + if (numberOfInstances > 1) { + bitmap = decodeTextRegion(huffman, refinement, currentWidth, currentHeight, 0, numberOfInstances, 1, symbols.concat(newSymbols), symbolCodeLength, 0, 0, 1, 0, huffmanTables, refinementTemplateIndex, refinementAt, decodingContext, 0, huffmanInput); + } else { + const symbolId = decodeIAID(contextCache, decoder, symbolCodeLength); + const rdx = decodeInteger(contextCache, "IARDX", decoder); + const rdy = decodeInteger(contextCache, "IARDY", decoder); + const symbol = symbolId < symbols.length ? symbols[symbolId] : newSymbols[symbolId - symbols.length]; + bitmap = decodeRefinement(currentWidth, currentHeight, refinementTemplateIndex, symbol, rdx, rdy, false, refinementAt, decodingContext); + } + newSymbols.push(bitmap); + } else if (huffman) { + symbolWidths.push(currentWidth); + } else { + bitmap = decodeBitmap(false, currentWidth, currentHeight, templateIndex, false, null, at, decodingContext); + newSymbols.push(bitmap); + } + } + if (huffman && !refinement) { + const bitmapSize = huffmanTables.tableBitmapSize.decode(huffmanInput); + huffmanInput.byteAlign(); + let collectiveBitmap; + if (bitmapSize === 0) { + collectiveBitmap = readUncompressedBitmap(huffmanInput, totalWidth, currentHeight); + } else { + const originalEnd = huffmanInput.end; + const bitmapEnd = huffmanInput.position + bitmapSize; + huffmanInput.end = bitmapEnd; + collectiveBitmap = decodeMMRBitmap(huffmanInput, totalWidth, currentHeight, false); + huffmanInput.end = originalEnd; + huffmanInput.position = bitmapEnd; + } + const numberOfSymbolsDecoded = symbolWidths.length; + if (firstSymbol === numberOfSymbolsDecoded - 1) { + newSymbols.push(collectiveBitmap); + } else { + let i, + y, + xMin = 0, + xMax, + bitmapWidth, + symbolBitmap; + for (i = firstSymbol; i < numberOfSymbolsDecoded; i++) { + bitmapWidth = symbolWidths[i]; + xMax = xMin + bitmapWidth; + symbolBitmap = []; + for (y = 0; y < currentHeight; y++) { + symbolBitmap.push(collectiveBitmap[y].subarray(xMin, xMax)); + } + newSymbols.push(symbolBitmap); + xMin = xMax; + } + } + } + } + const exportedSymbols = [], + flags = []; + let currentFlag = false, + i, + ii; + const totalSymbolsLength = symbols.length + numberOfNewSymbols; + while (flags.length < totalSymbolsLength) { + let runLength = huffman ? tableB1.decode(huffmanInput) : decodeInteger(contextCache, "IAEX", decoder); + while (runLength--) { + flags.push(currentFlag); + } + currentFlag = !currentFlag; + } + for (i = 0, ii = symbols.length; i < ii; i++) { + if (flags[i]) { + exportedSymbols.push(symbols[i]); + } + } + for (let j = 0; j < numberOfNewSymbols; i++, j++) { + if (flags[i]) { + exportedSymbols.push(newSymbols[j]); + } + } + return exportedSymbols; +} +function decodeTextRegion(huffman, refinement, width, height, defaultPixelValue, numberOfSymbolInstances, stripSize, inputSymbols, symbolCodeLength, transposed, dsOffset, referenceCorner, combinationOperator, huffmanTables, refinementTemplateIndex, refinementAt, decodingContext, logStripSize, huffmanInput) { + if (huffman && refinement) { + throw new Jbig2Error("refinement with Huffman is not supported"); + } + const bitmap = []; + let i, row; + for (i = 0; i < height; i++) { + row = new Uint8Array(width); + if (defaultPixelValue) { + for (let j = 0; j < width; j++) { + row[j] = defaultPixelValue; + } + } + bitmap.push(row); + } + const decoder = decodingContext.decoder; + const contextCache = decodingContext.contextCache; + let stripT = huffman ? -huffmanTables.tableDeltaT.decode(huffmanInput) : -decodeInteger(contextCache, "IADT", decoder); + let firstS = 0; + i = 0; + while (i < numberOfSymbolInstances) { + const deltaT = huffman ? huffmanTables.tableDeltaT.decode(huffmanInput) : decodeInteger(contextCache, "IADT", decoder); + stripT += deltaT; + const deltaFirstS = huffman ? huffmanTables.tableFirstS.decode(huffmanInput) : decodeInteger(contextCache, "IAFS", decoder); + firstS += deltaFirstS; + let currentS = firstS; + do { + let currentT = 0; + if (stripSize > 1) { + currentT = huffman ? huffmanInput.readBits(logStripSize) : decodeInteger(contextCache, "IAIT", decoder); + } + const t = stripSize * stripT + currentT; + const symbolId = huffman ? huffmanTables.symbolIDTable.decode(huffmanInput) : decodeIAID(contextCache, decoder, symbolCodeLength); + const applyRefinement = refinement && (huffman ? huffmanInput.readBit() : decodeInteger(contextCache, "IARI", decoder)); + let symbolBitmap = inputSymbols[symbolId]; + let symbolWidth = symbolBitmap[0].length; + let symbolHeight = symbolBitmap.length; + if (applyRefinement) { + const rdw = decodeInteger(contextCache, "IARDW", decoder); + const rdh = decodeInteger(contextCache, "IARDH", decoder); + const rdx = decodeInteger(contextCache, "IARDX", decoder); + const rdy = decodeInteger(contextCache, "IARDY", decoder); + symbolWidth += rdw; + symbolHeight += rdh; + symbolBitmap = decodeRefinement(symbolWidth, symbolHeight, refinementTemplateIndex, symbolBitmap, (rdw >> 1) + rdx, (rdh >> 1) + rdy, false, refinementAt, decodingContext); + } + const offsetT = t - (referenceCorner & 1 ? 0 : symbolHeight - 1); + const offsetS = currentS - (referenceCorner & 2 ? symbolWidth - 1 : 0); + let s2, t2, symbolRow; + if (transposed) { + for (s2 = 0; s2 < symbolHeight; s2++) { + row = bitmap[offsetS + s2]; + if (!row) { + continue; + } + symbolRow = symbolBitmap[s2]; + const maxWidth = Math.min(width - offsetT, symbolWidth); + switch (combinationOperator) { + case 0: + for (t2 = 0; t2 < maxWidth; t2++) { + row[offsetT + t2] |= symbolRow[t2]; + } + break; + case 2: + for (t2 = 0; t2 < maxWidth; t2++) { + row[offsetT + t2] ^= symbolRow[t2]; + } + break; + default: + throw new Jbig2Error(`operator ${combinationOperator} is not supported`); + } + } + currentS += symbolHeight - 1; + } else { + for (t2 = 0; t2 < symbolHeight; t2++) { + row = bitmap[offsetT + t2]; + if (!row) { + continue; + } + symbolRow = symbolBitmap[t2]; + switch (combinationOperator) { + case 0: + for (s2 = 0; s2 < symbolWidth; s2++) { + row[offsetS + s2] |= symbolRow[s2]; + } + break; + case 2: + for (s2 = 0; s2 < symbolWidth; s2++) { + row[offsetS + s2] ^= symbolRow[s2]; + } + break; + default: + throw new Jbig2Error(`operator ${combinationOperator} is not supported`); + } + } + currentS += symbolWidth - 1; + } + i++; + const deltaS = huffman ? huffmanTables.tableDeltaS.decode(huffmanInput) : decodeInteger(contextCache, "IADS", decoder); + if (deltaS === null) { + break; + } + currentS += deltaS + dsOffset; + } while (true); + } + return bitmap; +} +function decodePatternDictionary(mmr, patternWidth, patternHeight, maxPatternIndex, template, decodingContext) { + const at = []; + if (!mmr) { + at.push({ + x: -patternWidth, + y: 0 + }); + if (template === 0) { + at.push({ + x: -3, + y: -1 + }, { + x: 2, + y: -2 + }, { + x: -2, + y: -2 + }); + } + } + const collectiveWidth = (maxPatternIndex + 1) * patternWidth; + const collectiveBitmap = decodeBitmap(mmr, collectiveWidth, patternHeight, template, false, null, at, decodingContext); + const patterns = []; + for (let i = 0; i <= maxPatternIndex; i++) { + const patternBitmap = []; + const xMin = patternWidth * i; + const xMax = xMin + patternWidth; + for (let y = 0; y < patternHeight; y++) { + patternBitmap.push(collectiveBitmap[y].subarray(xMin, xMax)); + } + patterns.push(patternBitmap); + } + return patterns; +} +function decodeHalftoneRegion(mmr, patterns, template, regionWidth, regionHeight, defaultPixelValue, enableSkip, combinationOperator, gridWidth, gridHeight, gridOffsetX, gridOffsetY, gridVectorX, gridVectorY, decodingContext) { + const skip = null; + if (enableSkip) { + throw new Jbig2Error("skip is not supported"); + } + if (combinationOperator !== 0) { + throw new Jbig2Error(`operator "${combinationOperator}" is not supported in halftone region`); + } + const regionBitmap = []; + let i, j, row; + for (i = 0; i < regionHeight; i++) { + row = new Uint8Array(regionWidth); + if (defaultPixelValue) { + for (j = 0; j < regionWidth; j++) { + row[j] = defaultPixelValue; + } + } + regionBitmap.push(row); + } + const numberOfPatterns = patterns.length; + const pattern0 = patterns[0]; + const patternWidth = pattern0[0].length, + patternHeight = pattern0.length; + const bitsPerValue = (0, _core_utils.log2)(numberOfPatterns); + const at = []; + if (!mmr) { + at.push({ + x: template <= 1 ? 3 : 2, + y: -1 + }); + if (template === 0) { + at.push({ + x: -3, + y: -1 + }, { + x: 2, + y: -2 + }, { + x: -2, + y: -2 + }); + } + } + const grayScaleBitPlanes = []; + let mmrInput, bitmap; + if (mmr) { + mmrInput = new Reader(decodingContext.data, decodingContext.start, decodingContext.end); + } + for (i = bitsPerValue - 1; i >= 0; i--) { + if (mmr) { + bitmap = decodeMMRBitmap(mmrInput, gridWidth, gridHeight, true); + } else { + bitmap = decodeBitmap(false, gridWidth, gridHeight, template, false, skip, at, decodingContext); + } + grayScaleBitPlanes[i] = bitmap; + } + let mg, ng, bit, patternIndex, patternBitmap, x, y, patternRow, regionRow; + for (mg = 0; mg < gridHeight; mg++) { + for (ng = 0; ng < gridWidth; ng++) { + bit = 0; + patternIndex = 0; + for (j = bitsPerValue - 1; j >= 0; j--) { + bit ^= grayScaleBitPlanes[j][mg][ng]; + patternIndex |= bit << j; + } + patternBitmap = patterns[patternIndex]; + x = gridOffsetX + mg * gridVectorY + ng * gridVectorX >> 8; + y = gridOffsetY + mg * gridVectorX - ng * gridVectorY >> 8; + if (x >= 0 && x + patternWidth <= regionWidth && y >= 0 && y + patternHeight <= regionHeight) { + for (i = 0; i < patternHeight; i++) { + regionRow = regionBitmap[y + i]; + patternRow = patternBitmap[i]; + for (j = 0; j < patternWidth; j++) { + regionRow[x + j] |= patternRow[j]; + } + } + } else { + let regionX, regionY; + for (i = 0; i < patternHeight; i++) { + regionY = y + i; + if (regionY < 0 || regionY >= regionHeight) { + continue; + } + regionRow = regionBitmap[regionY]; + patternRow = patternBitmap[i]; + for (j = 0; j < patternWidth; j++) { + regionX = x + j; + if (regionX >= 0 && regionX < regionWidth) { + regionRow[regionX] |= patternRow[j]; + } + } + } + } + } + } + return regionBitmap; +} +function readSegmentHeader(data, start) { + const segmentHeader = {}; + segmentHeader.number = (0, _core_utils.readUint32)(data, start); + const flags = data[start + 4]; + const segmentType = flags & 0x3f; + if (!SegmentTypes[segmentType]) { + throw new Jbig2Error("invalid segment type: " + segmentType); + } + segmentHeader.type = segmentType; + segmentHeader.typeName = SegmentTypes[segmentType]; + segmentHeader.deferredNonRetain = !!(flags & 0x80); + const pageAssociationFieldSize = !!(flags & 0x40); + const referredFlags = data[start + 5]; + let referredToCount = referredFlags >> 5 & 7; + const retainBits = [referredFlags & 31]; + let position = start + 6; + if (referredFlags === 7) { + referredToCount = (0, _core_utils.readUint32)(data, position - 1) & 0x1fffffff; + position += 3; + let bytes = referredToCount + 7 >> 3; + retainBits[0] = data[position++]; + while (--bytes > 0) { + retainBits.push(data[position++]); + } + } else if (referredFlags === 5 || referredFlags === 6) { + throw new Jbig2Error("invalid referred-to flags"); + } + segmentHeader.retainBits = retainBits; + let referredToSegmentNumberSize = 4; + if (segmentHeader.number <= 256) { + referredToSegmentNumberSize = 1; + } else if (segmentHeader.number <= 65536) { + referredToSegmentNumberSize = 2; + } + const referredTo = []; + let i, ii; + for (i = 0; i < referredToCount; i++) { + let number; + if (referredToSegmentNumberSize === 1) { + number = data[position]; + } else if (referredToSegmentNumberSize === 2) { + number = (0, _core_utils.readUint16)(data, position); + } else { + number = (0, _core_utils.readUint32)(data, position); + } + referredTo.push(number); + position += referredToSegmentNumberSize; + } + segmentHeader.referredTo = referredTo; + if (!pageAssociationFieldSize) { + segmentHeader.pageAssociation = data[position++]; + } else { + segmentHeader.pageAssociation = (0, _core_utils.readUint32)(data, position); + position += 4; + } + segmentHeader.length = (0, _core_utils.readUint32)(data, position); + position += 4; + if (segmentHeader.length === 0xffffffff) { + if (segmentType === 38) { + const genericRegionInfo = readRegionSegmentInformation(data, position); + const genericRegionSegmentFlags = data[position + RegionSegmentInformationFieldLength]; + const genericRegionMmr = !!(genericRegionSegmentFlags & 1); + const searchPatternLength = 6; + const searchPattern = new Uint8Array(searchPatternLength); + if (!genericRegionMmr) { + searchPattern[0] = 0xff; + searchPattern[1] = 0xac; + } + searchPattern[2] = genericRegionInfo.height >>> 24 & 0xff; + searchPattern[3] = genericRegionInfo.height >> 16 & 0xff; + searchPattern[4] = genericRegionInfo.height >> 8 & 0xff; + searchPattern[5] = genericRegionInfo.height & 0xff; + for (i = position, ii = data.length; i < ii; i++) { + let j = 0; + while (j < searchPatternLength && searchPattern[j] === data[i + j]) { + j++; + } + if (j === searchPatternLength) { + segmentHeader.length = i + searchPatternLength; + break; + } + } + if (segmentHeader.length === 0xffffffff) { + throw new Jbig2Error("segment end was not found"); + } + } else { + throw new Jbig2Error("invalid unknown segment length"); + } + } + segmentHeader.headerEnd = position; + return segmentHeader; +} +function readSegments(header, data, start, end) { + const segments = []; + let position = start; + while (position < end) { + const segmentHeader = readSegmentHeader(data, position); + position = segmentHeader.headerEnd; + const segment = { + header: segmentHeader, + data + }; + if (!header.randomAccess) { + segment.start = position; + position += segmentHeader.length; + segment.end = position; + } + segments.push(segment); + if (segmentHeader.type === 51) { + break; + } + } + if (header.randomAccess) { + for (let i = 0, ii = segments.length; i < ii; i++) { + segments[i].start = position; + position += segments[i].header.length; + segments[i].end = position; + } + } + return segments; +} +function readRegionSegmentInformation(data, start) { + return { + width: (0, _core_utils.readUint32)(data, start), + height: (0, _core_utils.readUint32)(data, start + 4), + x: (0, _core_utils.readUint32)(data, start + 8), + y: (0, _core_utils.readUint32)(data, start + 12), + combinationOperator: data[start + 16] & 7 + }; +} +const RegionSegmentInformationFieldLength = 17; +function processSegment(segment, visitor) { + const header = segment.header; + const data = segment.data, + end = segment.end; + let position = segment.start; + let args, at, i, atLength; + switch (header.type) { + case 0: + const dictionary = {}; + const dictionaryFlags = (0, _core_utils.readUint16)(data, position); + dictionary.huffman = !!(dictionaryFlags & 1); + dictionary.refinement = !!(dictionaryFlags & 2); + dictionary.huffmanDHSelector = dictionaryFlags >> 2 & 3; + dictionary.huffmanDWSelector = dictionaryFlags >> 4 & 3; + dictionary.bitmapSizeSelector = dictionaryFlags >> 6 & 1; + dictionary.aggregationInstancesSelector = dictionaryFlags >> 7 & 1; + dictionary.bitmapCodingContextUsed = !!(dictionaryFlags & 256); + dictionary.bitmapCodingContextRetained = !!(dictionaryFlags & 512); + dictionary.template = dictionaryFlags >> 10 & 3; + dictionary.refinementTemplate = dictionaryFlags >> 12 & 1; + position += 2; + if (!dictionary.huffman) { + atLength = dictionary.template === 0 ? 4 : 1; + at = []; + for (i = 0; i < atLength; i++) { + at.push({ + x: (0, _core_utils.readInt8)(data, position), + y: (0, _core_utils.readInt8)(data, position + 1) + }); + position += 2; + } + dictionary.at = at; + } + if (dictionary.refinement && !dictionary.refinementTemplate) { + at = []; + for (i = 0; i < 2; i++) { + at.push({ + x: (0, _core_utils.readInt8)(data, position), + y: (0, _core_utils.readInt8)(data, position + 1) + }); + position += 2; + } + dictionary.refinementAt = at; + } + dictionary.numberOfExportedSymbols = (0, _core_utils.readUint32)(data, position); + position += 4; + dictionary.numberOfNewSymbols = (0, _core_utils.readUint32)(data, position); + position += 4; + args = [dictionary, header.number, header.referredTo, data, position, end]; + break; + case 6: + case 7: + const textRegion = {}; + textRegion.info = readRegionSegmentInformation(data, position); + position += RegionSegmentInformationFieldLength; + const textRegionSegmentFlags = (0, _core_utils.readUint16)(data, position); + position += 2; + textRegion.huffman = !!(textRegionSegmentFlags & 1); + textRegion.refinement = !!(textRegionSegmentFlags & 2); + textRegion.logStripSize = textRegionSegmentFlags >> 2 & 3; + textRegion.stripSize = 1 << textRegion.logStripSize; + textRegion.referenceCorner = textRegionSegmentFlags >> 4 & 3; + textRegion.transposed = !!(textRegionSegmentFlags & 64); + textRegion.combinationOperator = textRegionSegmentFlags >> 7 & 3; + textRegion.defaultPixelValue = textRegionSegmentFlags >> 9 & 1; + textRegion.dsOffset = textRegionSegmentFlags << 17 >> 27; + textRegion.refinementTemplate = textRegionSegmentFlags >> 15 & 1; + if (textRegion.huffman) { + const textRegionHuffmanFlags = (0, _core_utils.readUint16)(data, position); + position += 2; + textRegion.huffmanFS = textRegionHuffmanFlags & 3; + textRegion.huffmanDS = textRegionHuffmanFlags >> 2 & 3; + textRegion.huffmanDT = textRegionHuffmanFlags >> 4 & 3; + textRegion.huffmanRefinementDW = textRegionHuffmanFlags >> 6 & 3; + textRegion.huffmanRefinementDH = textRegionHuffmanFlags >> 8 & 3; + textRegion.huffmanRefinementDX = textRegionHuffmanFlags >> 10 & 3; + textRegion.huffmanRefinementDY = textRegionHuffmanFlags >> 12 & 3; + textRegion.huffmanRefinementSizeSelector = !!(textRegionHuffmanFlags & 0x4000); + } + if (textRegion.refinement && !textRegion.refinementTemplate) { + at = []; + for (i = 0; i < 2; i++) { + at.push({ + x: (0, _core_utils.readInt8)(data, position), + y: (0, _core_utils.readInt8)(data, position + 1) + }); + position += 2; + } + textRegion.refinementAt = at; + } + textRegion.numberOfSymbolInstances = (0, _core_utils.readUint32)(data, position); + position += 4; + args = [textRegion, header.referredTo, data, position, end]; + break; + case 16: + const patternDictionary = {}; + const patternDictionaryFlags = data[position++]; + patternDictionary.mmr = !!(patternDictionaryFlags & 1); + patternDictionary.template = patternDictionaryFlags >> 1 & 3; + patternDictionary.patternWidth = data[position++]; + patternDictionary.patternHeight = data[position++]; + patternDictionary.maxPatternIndex = (0, _core_utils.readUint32)(data, position); + position += 4; + args = [patternDictionary, header.number, data, position, end]; + break; + case 22: + case 23: + const halftoneRegion = {}; + halftoneRegion.info = readRegionSegmentInformation(data, position); + position += RegionSegmentInformationFieldLength; + const halftoneRegionFlags = data[position++]; + halftoneRegion.mmr = !!(halftoneRegionFlags & 1); + halftoneRegion.template = halftoneRegionFlags >> 1 & 3; + halftoneRegion.enableSkip = !!(halftoneRegionFlags & 8); + halftoneRegion.combinationOperator = halftoneRegionFlags >> 4 & 7; + halftoneRegion.defaultPixelValue = halftoneRegionFlags >> 7 & 1; + halftoneRegion.gridWidth = (0, _core_utils.readUint32)(data, position); + position += 4; + halftoneRegion.gridHeight = (0, _core_utils.readUint32)(data, position); + position += 4; + halftoneRegion.gridOffsetX = (0, _core_utils.readUint32)(data, position) & 0xffffffff; + position += 4; + halftoneRegion.gridOffsetY = (0, _core_utils.readUint32)(data, position) & 0xffffffff; + position += 4; + halftoneRegion.gridVectorX = (0, _core_utils.readUint16)(data, position); + position += 2; + halftoneRegion.gridVectorY = (0, _core_utils.readUint16)(data, position); + position += 2; + args = [halftoneRegion, header.referredTo, data, position, end]; + break; + case 38: + case 39: + const genericRegion = {}; + genericRegion.info = readRegionSegmentInformation(data, position); + position += RegionSegmentInformationFieldLength; + const genericRegionSegmentFlags = data[position++]; + genericRegion.mmr = !!(genericRegionSegmentFlags & 1); + genericRegion.template = genericRegionSegmentFlags >> 1 & 3; + genericRegion.prediction = !!(genericRegionSegmentFlags & 8); + if (!genericRegion.mmr) { + atLength = genericRegion.template === 0 ? 4 : 1; + at = []; + for (i = 0; i < atLength; i++) { + at.push({ + x: (0, _core_utils.readInt8)(data, position), + y: (0, _core_utils.readInt8)(data, position + 1) + }); + position += 2; + } + genericRegion.at = at; + } + args = [genericRegion, data, position, end]; + break; + case 48: + const pageInfo = { + width: (0, _core_utils.readUint32)(data, position), + height: (0, _core_utils.readUint32)(data, position + 4), + resolutionX: (0, _core_utils.readUint32)(data, position + 8), + resolutionY: (0, _core_utils.readUint32)(data, position + 12) + }; + if (pageInfo.height === 0xffffffff) { + delete pageInfo.height; + } + const pageSegmentFlags = data[position + 16]; + (0, _core_utils.readUint16)(data, position + 17); + pageInfo.lossless = !!(pageSegmentFlags & 1); + pageInfo.refinement = !!(pageSegmentFlags & 2); + pageInfo.defaultPixelValue = pageSegmentFlags >> 2 & 1; + pageInfo.combinationOperator = pageSegmentFlags >> 3 & 3; + pageInfo.requiresBuffer = !!(pageSegmentFlags & 32); + pageInfo.combinationOperatorOverride = !!(pageSegmentFlags & 64); + args = [pageInfo]; + break; + case 49: + break; + case 50: + break; + case 51: + break; + case 53: + args = [header.number, data, position, end]; + break; + case 62: + break; + default: + throw new Jbig2Error(`segment type ${header.typeName}(${header.type}) is not implemented`); + } + const callbackName = "on" + header.typeName; + if (callbackName in visitor) { + visitor[callbackName].apply(visitor, args); + } +} +function processSegments(segments, visitor) { + for (let i = 0, ii = segments.length; i < ii; i++) { + processSegment(segments[i], visitor); + } +} +function parseJbig2Chunks(chunks) { + const visitor = new SimpleSegmentVisitor(); + for (let i = 0, ii = chunks.length; i < ii; i++) { + const chunk = chunks[i]; + const segments = readSegments({}, chunk.data, chunk.start, chunk.end); + processSegments(segments, visitor); + } + return visitor.buffer; +} +function parseJbig2(data) { + throw new Error("Not implemented: parseJbig2"); +} +class SimpleSegmentVisitor { + onPageInformation(info) { + this.currentPageInfo = info; + const rowSize = info.width + 7 >> 3; + const buffer = new Uint8ClampedArray(rowSize * info.height); + if (info.defaultPixelValue) { + buffer.fill(0xff); + } + this.buffer = buffer; + } + drawBitmap(regionInfo, bitmap) { + const pageInfo = this.currentPageInfo; + const width = regionInfo.width, + height = regionInfo.height; + const rowSize = pageInfo.width + 7 >> 3; + const combinationOperator = pageInfo.combinationOperatorOverride ? regionInfo.combinationOperator : pageInfo.combinationOperator; + const buffer = this.buffer; + const mask0 = 128 >> (regionInfo.x & 7); + let offset0 = regionInfo.y * rowSize + (regionInfo.x >> 3); + let i, j, mask, offset; + switch (combinationOperator) { + case 0: + for (i = 0; i < height; i++) { + mask = mask0; + offset = offset0; + for (j = 0; j < width; j++) { + if (bitmap[i][j]) { + buffer[offset] |= mask; + } + mask >>= 1; + if (!mask) { + mask = 128; + offset++; + } + } + offset0 += rowSize; + } + break; + case 2: + for (i = 0; i < height; i++) { + mask = mask0; + offset = offset0; + for (j = 0; j < width; j++) { + if (bitmap[i][j]) { + buffer[offset] ^= mask; + } + mask >>= 1; + if (!mask) { + mask = 128; + offset++; + } + } + offset0 += rowSize; + } + break; + default: + throw new Jbig2Error(`operator ${combinationOperator} is not supported`); + } + } + onImmediateGenericRegion(region, data, start, end) { + const regionInfo = region.info; + const decodingContext = new DecodingContext(data, start, end); + const bitmap = decodeBitmap(region.mmr, regionInfo.width, regionInfo.height, region.template, region.prediction, null, region.at, decodingContext); + this.drawBitmap(regionInfo, bitmap); + } + onImmediateLosslessGenericRegion() { + this.onImmediateGenericRegion(...arguments); + } + onSymbolDictionary(dictionary, currentSegment, referredSegments, data, start, end) { + let huffmanTables, huffmanInput; + if (dictionary.huffman) { + huffmanTables = getSymbolDictionaryHuffmanTables(dictionary, referredSegments, this.customTables); + huffmanInput = new Reader(data, start, end); + } + let symbols = this.symbols; + if (!symbols) { + this.symbols = symbols = {}; + } + const inputSymbols = []; + for (const referredSegment of referredSegments) { + const referredSymbols = symbols[referredSegment]; + if (referredSymbols) { + inputSymbols.push(...referredSymbols); + } + } + const decodingContext = new DecodingContext(data, start, end); + symbols[currentSegment] = decodeSymbolDictionary(dictionary.huffman, dictionary.refinement, inputSymbols, dictionary.numberOfNewSymbols, dictionary.numberOfExportedSymbols, huffmanTables, dictionary.template, dictionary.at, dictionary.refinementTemplate, dictionary.refinementAt, decodingContext, huffmanInput); + } + onImmediateTextRegion(region, referredSegments, data, start, end) { + const regionInfo = region.info; + let huffmanTables, huffmanInput; + const symbols = this.symbols; + const inputSymbols = []; + for (const referredSegment of referredSegments) { + const referredSymbols = symbols[referredSegment]; + if (referredSymbols) { + inputSymbols.push(...referredSymbols); + } + } + const symbolCodeLength = (0, _core_utils.log2)(inputSymbols.length); + if (region.huffman) { + huffmanInput = new Reader(data, start, end); + huffmanTables = getTextRegionHuffmanTables(region, referredSegments, this.customTables, inputSymbols.length, huffmanInput); + } + const decodingContext = new DecodingContext(data, start, end); + const bitmap = decodeTextRegion(region.huffman, region.refinement, regionInfo.width, regionInfo.height, region.defaultPixelValue, region.numberOfSymbolInstances, region.stripSize, inputSymbols, symbolCodeLength, region.transposed, region.dsOffset, region.referenceCorner, region.combinationOperator, huffmanTables, region.refinementTemplate, region.refinementAt, decodingContext, region.logStripSize, huffmanInput); + this.drawBitmap(regionInfo, bitmap); + } + onImmediateLosslessTextRegion() { + this.onImmediateTextRegion(...arguments); + } + onPatternDictionary(dictionary, currentSegment, data, start, end) { + let patterns = this.patterns; + if (!patterns) { + this.patterns = patterns = {}; + } + const decodingContext = new DecodingContext(data, start, end); + patterns[currentSegment] = decodePatternDictionary(dictionary.mmr, dictionary.patternWidth, dictionary.patternHeight, dictionary.maxPatternIndex, dictionary.template, decodingContext); + } + onImmediateHalftoneRegion(region, referredSegments, data, start, end) { + const patterns = this.patterns[referredSegments[0]]; + const regionInfo = region.info; + const decodingContext = new DecodingContext(data, start, end); + const bitmap = decodeHalftoneRegion(region.mmr, patterns, region.template, regionInfo.width, regionInfo.height, region.defaultPixelValue, region.enableSkip, region.combinationOperator, region.gridWidth, region.gridHeight, region.gridOffsetX, region.gridOffsetY, region.gridVectorX, region.gridVectorY, decodingContext); + this.drawBitmap(regionInfo, bitmap); + } + onImmediateLosslessHalftoneRegion() { + this.onImmediateHalftoneRegion(...arguments); + } + onTables(currentSegment, data, start, end) { + let customTables = this.customTables; + if (!customTables) { + this.customTables = customTables = {}; + } + customTables[currentSegment] = decodeTablesSegment(data, start, end); + } +} +class HuffmanLine { + constructor(lineData) { + if (lineData.length === 2) { + this.isOOB = true; + this.rangeLow = 0; + this.prefixLength = lineData[0]; + this.rangeLength = 0; + this.prefixCode = lineData[1]; + this.isLowerRange = false; + } else { + this.isOOB = false; + this.rangeLow = lineData[0]; + this.prefixLength = lineData[1]; + this.rangeLength = lineData[2]; + this.prefixCode = lineData[3]; + this.isLowerRange = lineData[4] === "lower"; + } + } +} +class HuffmanTreeNode { + constructor(line) { + this.children = []; + if (line) { + this.isLeaf = true; + this.rangeLength = line.rangeLength; + this.rangeLow = line.rangeLow; + this.isLowerRange = line.isLowerRange; + this.isOOB = line.isOOB; + } else { + this.isLeaf = false; + } + } + buildTree(line, shift) { + const bit = line.prefixCode >> shift & 1; + if (shift <= 0) { + this.children[bit] = new HuffmanTreeNode(line); + } else { + let node = this.children[bit]; + if (!node) { + this.children[bit] = node = new HuffmanTreeNode(null); + } + node.buildTree(line, shift - 1); + } + } + decodeNode(reader) { + if (this.isLeaf) { + if (this.isOOB) { + return null; + } + const htOffset = reader.readBits(this.rangeLength); + return this.rangeLow + (this.isLowerRange ? -htOffset : htOffset); + } + const node = this.children[reader.readBit()]; + if (!node) { + throw new Jbig2Error("invalid Huffman data"); + } + return node.decodeNode(reader); + } +} +class HuffmanTable { + constructor(lines, prefixCodesDone) { + if (!prefixCodesDone) { + this.assignPrefixCodes(lines); + } + this.rootNode = new HuffmanTreeNode(null); + for (let i = 0, ii = lines.length; i < ii; i++) { + const line = lines[i]; + if (line.prefixLength > 0) { + this.rootNode.buildTree(line, line.prefixLength - 1); + } + } + } + decode(reader) { + return this.rootNode.decodeNode(reader); + } + assignPrefixCodes(lines) { + const linesLength = lines.length; + let prefixLengthMax = 0; + for (let i = 0; i < linesLength; i++) { + prefixLengthMax = Math.max(prefixLengthMax, lines[i].prefixLength); + } + const histogram = new Uint32Array(prefixLengthMax + 1); + for (let i = 0; i < linesLength; i++) { + histogram[lines[i].prefixLength]++; + } + let currentLength = 1, + firstCode = 0, + currentCode, + currentTemp, + line; + histogram[0] = 0; + while (currentLength <= prefixLengthMax) { + firstCode = firstCode + histogram[currentLength - 1] << 1; + currentCode = firstCode; + currentTemp = 0; + while (currentTemp < linesLength) { + line = lines[currentTemp]; + if (line.prefixLength === currentLength) { + line.prefixCode = currentCode; + currentCode++; + } + currentTemp++; + } + currentLength++; + } + } +} +function decodeTablesSegment(data, start, end) { + const flags = data[start]; + const lowestValue = (0, _core_utils.readUint32)(data, start + 1) & 0xffffffff; + const highestValue = (0, _core_utils.readUint32)(data, start + 5) & 0xffffffff; + const reader = new Reader(data, start + 9, end); + const prefixSizeBits = (flags >> 1 & 7) + 1; + const rangeSizeBits = (flags >> 4 & 7) + 1; + const lines = []; + let prefixLength, + rangeLength, + currentRangeLow = lowestValue; + do { + prefixLength = reader.readBits(prefixSizeBits); + rangeLength = reader.readBits(rangeSizeBits); + lines.push(new HuffmanLine([currentRangeLow, prefixLength, rangeLength, 0])); + currentRangeLow += 1 << rangeLength; + } while (currentRangeLow < highestValue); + prefixLength = reader.readBits(prefixSizeBits); + lines.push(new HuffmanLine([lowestValue - 1, prefixLength, 32, 0, "lower"])); + prefixLength = reader.readBits(prefixSizeBits); + lines.push(new HuffmanLine([highestValue, prefixLength, 32, 0])); + if (flags & 1) { + prefixLength = reader.readBits(prefixSizeBits); + lines.push(new HuffmanLine([prefixLength, 0])); + } + return new HuffmanTable(lines, false); +} +const standardTablesCache = {}; +function getStandardTable(number) { + let table = standardTablesCache[number]; + if (table) { + return table; + } + let lines; + switch (number) { + case 1: + lines = [[0, 1, 4, 0x0], [16, 2, 8, 0x2], [272, 3, 16, 0x6], [65808, 3, 32, 0x7]]; + break; + case 2: + lines = [[0, 1, 0, 0x0], [1, 2, 0, 0x2], [2, 3, 0, 0x6], [3, 4, 3, 0xe], [11, 5, 6, 0x1e], [75, 6, 32, 0x3e], [6, 0x3f]]; + break; + case 3: + lines = [[-256, 8, 8, 0xfe], [0, 1, 0, 0x0], [1, 2, 0, 0x2], [2, 3, 0, 0x6], [3, 4, 3, 0xe], [11, 5, 6, 0x1e], [-257, 8, 32, 0xff, "lower"], [75, 7, 32, 0x7e], [6, 0x3e]]; + break; + case 4: + lines = [[1, 1, 0, 0x0], [2, 2, 0, 0x2], [3, 3, 0, 0x6], [4, 4, 3, 0xe], [12, 5, 6, 0x1e], [76, 5, 32, 0x1f]]; + break; + case 5: + lines = [[-255, 7, 8, 0x7e], [1, 1, 0, 0x0], [2, 2, 0, 0x2], [3, 3, 0, 0x6], [4, 4, 3, 0xe], [12, 5, 6, 0x1e], [-256, 7, 32, 0x7f, "lower"], [76, 6, 32, 0x3e]]; + break; + case 6: + lines = [[-2048, 5, 10, 0x1c], [-1024, 4, 9, 0x8], [-512, 4, 8, 0x9], [-256, 4, 7, 0xa], [-128, 5, 6, 0x1d], [-64, 5, 5, 0x1e], [-32, 4, 5, 0xb], [0, 2, 7, 0x0], [128, 3, 7, 0x2], [256, 3, 8, 0x3], [512, 4, 9, 0xc], [1024, 4, 10, 0xd], [-2049, 6, 32, 0x3e, "lower"], [2048, 6, 32, 0x3f]]; + break; + case 7: + lines = [[-1024, 4, 9, 0x8], [-512, 3, 8, 0x0], [-256, 4, 7, 0x9], [-128, 5, 6, 0x1a], [-64, 5, 5, 0x1b], [-32, 4, 5, 0xa], [0, 4, 5, 0xb], [32, 5, 5, 0x1c], [64, 5, 6, 0x1d], [128, 4, 7, 0xc], [256, 3, 8, 0x1], [512, 3, 9, 0x2], [1024, 3, 10, 0x3], [-1025, 5, 32, 0x1e, "lower"], [2048, 5, 32, 0x1f]]; + break; + case 8: + lines = [[-15, 8, 3, 0xfc], [-7, 9, 1, 0x1fc], [-5, 8, 1, 0xfd], [-3, 9, 0, 0x1fd], [-2, 7, 0, 0x7c], [-1, 4, 0, 0xa], [0, 2, 1, 0x0], [2, 5, 0, 0x1a], [3, 6, 0, 0x3a], [4, 3, 4, 0x4], [20, 6, 1, 0x3b], [22, 4, 4, 0xb], [38, 4, 5, 0xc], [70, 5, 6, 0x1b], [134, 5, 7, 0x1c], [262, 6, 7, 0x3c], [390, 7, 8, 0x7d], [646, 6, 10, 0x3d], [-16, 9, 32, 0x1fe, "lower"], [1670, 9, 32, 0x1ff], [2, 0x1]]; + break; + case 9: + lines = [[-31, 8, 4, 0xfc], [-15, 9, 2, 0x1fc], [-11, 8, 2, 0xfd], [-7, 9, 1, 0x1fd], [-5, 7, 1, 0x7c], [-3, 4, 1, 0xa], [-1, 3, 1, 0x2], [1, 3, 1, 0x3], [3, 5, 1, 0x1a], [5, 6, 1, 0x3a], [7, 3, 5, 0x4], [39, 6, 2, 0x3b], [43, 4, 5, 0xb], [75, 4, 6, 0xc], [139, 5, 7, 0x1b], [267, 5, 8, 0x1c], [523, 6, 8, 0x3c], [779, 7, 9, 0x7d], [1291, 6, 11, 0x3d], [-32, 9, 32, 0x1fe, "lower"], [3339, 9, 32, 0x1ff], [2, 0x0]]; + break; + case 10: + lines = [[-21, 7, 4, 0x7a], [-5, 8, 0, 0xfc], [-4, 7, 0, 0x7b], [-3, 5, 0, 0x18], [-2, 2, 2, 0x0], [2, 5, 0, 0x19], [3, 6, 0, 0x36], [4, 7, 0, 0x7c], [5, 8, 0, 0xfd], [6, 2, 6, 0x1], [70, 5, 5, 0x1a], [102, 6, 5, 0x37], [134, 6, 6, 0x38], [198, 6, 7, 0x39], [326, 6, 8, 0x3a], [582, 6, 9, 0x3b], [1094, 6, 10, 0x3c], [2118, 7, 11, 0x7d], [-22, 8, 32, 0xfe, "lower"], [4166, 8, 32, 0xff], [2, 0x2]]; + break; + case 11: + lines = [[1, 1, 0, 0x0], [2, 2, 1, 0x2], [4, 4, 0, 0xc], [5, 4, 1, 0xd], [7, 5, 1, 0x1c], [9, 5, 2, 0x1d], [13, 6, 2, 0x3c], [17, 7, 2, 0x7a], [21, 7, 3, 0x7b], [29, 7, 4, 0x7c], [45, 7, 5, 0x7d], [77, 7, 6, 0x7e], [141, 7, 32, 0x7f]]; + break; + case 12: + lines = [[1, 1, 0, 0x0], [2, 2, 0, 0x2], [3, 3, 1, 0x6], [5, 5, 0, 0x1c], [6, 5, 1, 0x1d], [8, 6, 1, 0x3c], [10, 7, 0, 0x7a], [11, 7, 1, 0x7b], [13, 7, 2, 0x7c], [17, 7, 3, 0x7d], [25, 7, 4, 0x7e], [41, 8, 5, 0xfe], [73, 8, 32, 0xff]]; + break; + case 13: + lines = [[1, 1, 0, 0x0], [2, 3, 0, 0x4], [3, 4, 0, 0xc], [4, 5, 0, 0x1c], [5, 4, 1, 0xd], [7, 3, 3, 0x5], [15, 6, 1, 0x3a], [17, 6, 2, 0x3b], [21, 6, 3, 0x3c], [29, 6, 4, 0x3d], [45, 6, 5, 0x3e], [77, 7, 6, 0x7e], [141, 7, 32, 0x7f]]; + break; + case 14: + lines = [[-2, 3, 0, 0x4], [-1, 3, 0, 0x5], [0, 1, 0, 0x0], [1, 3, 0, 0x6], [2, 3, 0, 0x7]]; + break; + case 15: + lines = [[-24, 7, 4, 0x7c], [-8, 6, 2, 0x3c], [-4, 5, 1, 0x1c], [-2, 4, 0, 0xc], [-1, 3, 0, 0x4], [0, 1, 0, 0x0], [1, 3, 0, 0x5], [2, 4, 0, 0xd], [3, 5, 1, 0x1d], [5, 6, 2, 0x3d], [9, 7, 4, 0x7d], [-25, 7, 32, 0x7e, "lower"], [25, 7, 32, 0x7f]]; + break; + default: + throw new Jbig2Error(`standard table B.${number} does not exist`); + } + for (let i = 0, ii = lines.length; i < ii; i++) { + lines[i] = new HuffmanLine(lines[i]); + } + table = new HuffmanTable(lines, true); + standardTablesCache[number] = table; + return table; +} +class Reader { + constructor(data, start, end) { + this.data = data; + this.start = start; + this.end = end; + this.position = start; + this.shift = -1; + this.currentByte = 0; + } + readBit() { + if (this.shift < 0) { + if (this.position >= this.end) { + throw new Jbig2Error("end of data while reading bit"); + } + this.currentByte = this.data[this.position++]; + this.shift = 7; + } + const bit = this.currentByte >> this.shift & 1; + this.shift--; + return bit; + } + readBits(numBits) { + let result = 0, + i; + for (i = numBits - 1; i >= 0; i--) { + result |= this.readBit() << i; + } + return result; + } + byteAlign() { + this.shift = -1; + } + next() { + if (this.position >= this.end) { + return -1; + } + return this.data[this.position++]; + } +} +function getCustomHuffmanTable(index, referredTo, customTables) { + let currentIndex = 0; + for (let i = 0, ii = referredTo.length; i < ii; i++) { + const table = customTables[referredTo[i]]; + if (table) { + if (index === currentIndex) { + return table; + } + currentIndex++; + } + } + throw new Jbig2Error("can't find custom Huffman table"); +} +function getTextRegionHuffmanTables(textRegion, referredTo, customTables, numberOfSymbols, reader) { + const codes = []; + for (let i = 0; i <= 34; i++) { + const codeLength = reader.readBits(4); + codes.push(new HuffmanLine([i, codeLength, 0, 0])); + } + const runCodesTable = new HuffmanTable(codes, false); + codes.length = 0; + for (let i = 0; i < numberOfSymbols;) { + const codeLength = runCodesTable.decode(reader); + if (codeLength >= 32) { + let repeatedLength, numberOfRepeats, j; + switch (codeLength) { + case 32: + if (i === 0) { + throw new Jbig2Error("no previous value in symbol ID table"); + } + numberOfRepeats = reader.readBits(2) + 3; + repeatedLength = codes[i - 1].prefixLength; + break; + case 33: + numberOfRepeats = reader.readBits(3) + 3; + repeatedLength = 0; + break; + case 34: + numberOfRepeats = reader.readBits(7) + 11; + repeatedLength = 0; + break; + default: + throw new Jbig2Error("invalid code length in symbol ID table"); + } + for (j = 0; j < numberOfRepeats; j++) { + codes.push(new HuffmanLine([i, repeatedLength, 0, 0])); + i++; + } + } else { + codes.push(new HuffmanLine([i, codeLength, 0, 0])); + i++; + } + } + reader.byteAlign(); + const symbolIDTable = new HuffmanTable(codes, false); + let customIndex = 0, + tableFirstS, + tableDeltaS, + tableDeltaT; + switch (textRegion.huffmanFS) { + case 0: + case 1: + tableFirstS = getStandardTable(textRegion.huffmanFS + 6); + break; + case 3: + tableFirstS = getCustomHuffmanTable(customIndex, referredTo, customTables); + customIndex++; + break; + default: + throw new Jbig2Error("invalid Huffman FS selector"); + } + switch (textRegion.huffmanDS) { + case 0: + case 1: + case 2: + tableDeltaS = getStandardTable(textRegion.huffmanDS + 8); + break; + case 3: + tableDeltaS = getCustomHuffmanTable(customIndex, referredTo, customTables); + customIndex++; + break; + default: + throw new Jbig2Error("invalid Huffman DS selector"); + } + switch (textRegion.huffmanDT) { + case 0: + case 1: + case 2: + tableDeltaT = getStandardTable(textRegion.huffmanDT + 11); + break; + case 3: + tableDeltaT = getCustomHuffmanTable(customIndex, referredTo, customTables); + customIndex++; + break; + default: + throw new Jbig2Error("invalid Huffman DT selector"); + } + if (textRegion.refinement) { + throw new Jbig2Error("refinement with Huffman is not supported"); + } + return { + symbolIDTable, + tableFirstS, + tableDeltaS, + tableDeltaT + }; +} +function getSymbolDictionaryHuffmanTables(dictionary, referredTo, customTables) { + let customIndex = 0, + tableDeltaHeight, + tableDeltaWidth; + switch (dictionary.huffmanDHSelector) { + case 0: + case 1: + tableDeltaHeight = getStandardTable(dictionary.huffmanDHSelector + 4); + break; + case 3: + tableDeltaHeight = getCustomHuffmanTable(customIndex, referredTo, customTables); + customIndex++; + break; + default: + throw new Jbig2Error("invalid Huffman DH selector"); + } + switch (dictionary.huffmanDWSelector) { + case 0: + case 1: + tableDeltaWidth = getStandardTable(dictionary.huffmanDWSelector + 2); + break; + case 3: + tableDeltaWidth = getCustomHuffmanTable(customIndex, referredTo, customTables); + customIndex++; + break; + default: + throw new Jbig2Error("invalid Huffman DW selector"); + } + let tableBitmapSize, tableAggregateInstances; + if (dictionary.bitmapSizeSelector) { + tableBitmapSize = getCustomHuffmanTable(customIndex, referredTo, customTables); + customIndex++; + } else { + tableBitmapSize = getStandardTable(1); + } + if (dictionary.aggregationInstancesSelector) { + tableAggregateInstances = getCustomHuffmanTable(customIndex, referredTo, customTables); + } else { + tableAggregateInstances = getStandardTable(1); + } + return { + tableDeltaHeight, + tableDeltaWidth, + tableBitmapSize, + tableAggregateInstances + }; +} +function readUncompressedBitmap(reader, width, height) { + const bitmap = []; + for (let y = 0; y < height; y++) { + const row = new Uint8Array(width); + bitmap.push(row); + for (let x = 0; x < width; x++) { + row[x] = reader.readBit(); + } + reader.byteAlign(); + } + return bitmap; +} +function decodeMMRBitmap(input, width, height, endOfBlock) { + const params = { + K: -1, + Columns: width, + Rows: height, + BlackIs1: true, + EndOfBlock: endOfBlock + }; + const decoder = new _ccitt.CCITTFaxDecoder(input, params); + const bitmap = []; + let currentByte, + eof = false; + for (let y = 0; y < height; y++) { + const row = new Uint8Array(width); + bitmap.push(row); + let shift = -1; + for (let x = 0; x < width; x++) { + if (shift < 0) { + currentByte = decoder.readNextChar(); + if (currentByte === -1) { + currentByte = 0; + eof = true; + } + shift = 7; + } + row[x] = currentByte >> shift & 1; + shift--; + } + } + if (endOfBlock && !eof) { + const lookForEOFLimit = 5; + for (let i = 0; i < lookForEOFLimit; i++) { + if (decoder.readNextChar() === -1) { + break; + } + } + } + return bitmap; +} +class Jbig2Image { + parseChunks(chunks) { + return parseJbig2Chunks(chunks); + } + parse(data) { + throw new Error("Not implemented: Jbig2Image.parse"); + } +} +exports.Jbig2Image = Jbig2Image; + +/***/ }), +/* 25 */ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ArithmeticDecoder = void 0; +const QeTable = [{ + qe: 0x5601, + nmps: 1, + nlps: 1, + switchFlag: 1 +}, { + qe: 0x3401, + nmps: 2, + nlps: 6, + switchFlag: 0 +}, { + qe: 0x1801, + nmps: 3, + nlps: 9, + switchFlag: 0 +}, { + qe: 0x0ac1, + nmps: 4, + nlps: 12, + switchFlag: 0 +}, { + qe: 0x0521, + nmps: 5, + nlps: 29, + switchFlag: 0 +}, { + qe: 0x0221, + nmps: 38, + nlps: 33, + switchFlag: 0 +}, { + qe: 0x5601, + nmps: 7, + nlps: 6, + switchFlag: 1 +}, { + qe: 0x5401, + nmps: 8, + nlps: 14, + switchFlag: 0 +}, { + qe: 0x4801, + nmps: 9, + nlps: 14, + switchFlag: 0 +}, { + qe: 0x3801, + nmps: 10, + nlps: 14, + switchFlag: 0 +}, { + qe: 0x3001, + nmps: 11, + nlps: 17, + switchFlag: 0 +}, { + qe: 0x2401, + nmps: 12, + nlps: 18, + switchFlag: 0 +}, { + qe: 0x1c01, + nmps: 13, + nlps: 20, + switchFlag: 0 +}, { + qe: 0x1601, + nmps: 29, + nlps: 21, + switchFlag: 0 +}, { + qe: 0x5601, + nmps: 15, + nlps: 14, + switchFlag: 1 +}, { + qe: 0x5401, + nmps: 16, + nlps: 14, + switchFlag: 0 +}, { + qe: 0x5101, + nmps: 17, + nlps: 15, + switchFlag: 0 +}, { + qe: 0x4801, + nmps: 18, + nlps: 16, + switchFlag: 0 +}, { + qe: 0x3801, + nmps: 19, + nlps: 17, + switchFlag: 0 +}, { + qe: 0x3401, + nmps: 20, + nlps: 18, + switchFlag: 0 +}, { + qe: 0x3001, + nmps: 21, + nlps: 19, + switchFlag: 0 +}, { + qe: 0x2801, + nmps: 22, + nlps: 19, + switchFlag: 0 +}, { + qe: 0x2401, + nmps: 23, + nlps: 20, + switchFlag: 0 +}, { + qe: 0x2201, + nmps: 24, + nlps: 21, + switchFlag: 0 +}, { + qe: 0x1c01, + nmps: 25, + nlps: 22, + switchFlag: 0 +}, { + qe: 0x1801, + nmps: 26, + nlps: 23, + switchFlag: 0 +}, { + qe: 0x1601, + nmps: 27, + nlps: 24, + switchFlag: 0 +}, { + qe: 0x1401, + nmps: 28, + nlps: 25, + switchFlag: 0 +}, { + qe: 0x1201, + nmps: 29, + nlps: 26, + switchFlag: 0 +}, { + qe: 0x1101, + nmps: 30, + nlps: 27, + switchFlag: 0 +}, { + qe: 0x0ac1, + nmps: 31, + nlps: 28, + switchFlag: 0 +}, { + qe: 0x09c1, + nmps: 32, + nlps: 29, + switchFlag: 0 +}, { + qe: 0x08a1, + nmps: 33, + nlps: 30, + switchFlag: 0 +}, { + qe: 0x0521, + nmps: 34, + nlps: 31, + switchFlag: 0 +}, { + qe: 0x0441, + nmps: 35, + nlps: 32, + switchFlag: 0 +}, { + qe: 0x02a1, + nmps: 36, + nlps: 33, + switchFlag: 0 +}, { + qe: 0x0221, + nmps: 37, + nlps: 34, + switchFlag: 0 +}, { + qe: 0x0141, + nmps: 38, + nlps: 35, + switchFlag: 0 +}, { + qe: 0x0111, + nmps: 39, + nlps: 36, + switchFlag: 0 +}, { + qe: 0x0085, + nmps: 40, + nlps: 37, + switchFlag: 0 +}, { + qe: 0x0049, + nmps: 41, + nlps: 38, + switchFlag: 0 +}, { + qe: 0x0025, + nmps: 42, + nlps: 39, + switchFlag: 0 +}, { + qe: 0x0015, + nmps: 43, + nlps: 40, + switchFlag: 0 +}, { + qe: 0x0009, + nmps: 44, + nlps: 41, + switchFlag: 0 +}, { + qe: 0x0005, + nmps: 45, + nlps: 42, + switchFlag: 0 +}, { + qe: 0x0001, + nmps: 45, + nlps: 43, + switchFlag: 0 +}, { + qe: 0x5601, + nmps: 46, + nlps: 46, + switchFlag: 0 +}]; +class ArithmeticDecoder { + constructor(data, start, end) { + this.data = data; + this.bp = start; + this.dataEnd = end; + this.chigh = data[start]; + this.clow = 0; + this.byteIn(); + this.chigh = this.chigh << 7 & 0xffff | this.clow >> 9 & 0x7f; + this.clow = this.clow << 7 & 0xffff; + this.ct -= 7; + this.a = 0x8000; + } + byteIn() { + const data = this.data; + let bp = this.bp; + if (data[bp] === 0xff) { + if (data[bp + 1] > 0x8f) { + this.clow += 0xff00; + this.ct = 8; + } else { + bp++; + this.clow += data[bp] << 9; + this.ct = 7; + this.bp = bp; + } + } else { + bp++; + this.clow += bp < this.dataEnd ? data[bp] << 8 : 0xff00; + this.ct = 8; + this.bp = bp; + } + if (this.clow > 0xffff) { + this.chigh += this.clow >> 16; + this.clow &= 0xffff; + } + } + readBit(contexts, pos) { + let cx_index = contexts[pos] >> 1, + cx_mps = contexts[pos] & 1; + const qeTableIcx = QeTable[cx_index]; + const qeIcx = qeTableIcx.qe; + let d; + let a = this.a - qeIcx; + if (this.chigh < qeIcx) { + if (a < qeIcx) { + a = qeIcx; + d = cx_mps; + cx_index = qeTableIcx.nmps; + } else { + a = qeIcx; + d = 1 ^ cx_mps; + if (qeTableIcx.switchFlag === 1) { + cx_mps = d; + } + cx_index = qeTableIcx.nlps; + } + } else { + this.chigh -= qeIcx; + if ((a & 0x8000) !== 0) { + this.a = a; + return cx_mps; + } + if (a < qeIcx) { + d = 1 ^ cx_mps; + if (qeTableIcx.switchFlag === 1) { + cx_mps = d; + } + cx_index = qeTableIcx.nlps; + } else { + d = cx_mps; + cx_index = qeTableIcx.nmps; + } + } + do { + if (this.ct === 0) { + this.byteIn(); + } + a <<= 1; + this.chigh = this.chigh << 1 & 0xffff | this.clow >> 15 & 1; + this.clow = this.clow << 1 & 0xffff; + this.ct--; + } while ((a & 0x8000) === 0); + this.a = a; + contexts[pos] = cx_index << 1 | cx_mps; + return d; + } +} +exports.ArithmeticDecoder = ArithmeticDecoder; + +/***/ }), +/* 26 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.JpegStream = void 0; +var _decode_stream = __w_pdfjs_require__(18); +var _primitives = __w_pdfjs_require__(4); +var _jpg = __w_pdfjs_require__(27); +var _util = __w_pdfjs_require__(2); +class JpegStream extends _decode_stream.DecodeStream { + constructor(stream, maybeLength, params) { + let ch; + while ((ch = stream.getByte()) !== -1) { + if (ch === 0xff) { + stream.skip(-1); + break; + } + } + super(maybeLength); + this.stream = stream; + this.dict = stream.dict; + this.maybeLength = maybeLength; + this.params = params; + } + get bytes() { + return (0, _util.shadow)(this, "bytes", this.stream.getBytes(this.maybeLength)); + } + ensureBuffer(requested) {} + readBlock() { + if (this.eof) { + return; + } + const jpegOptions = { + decodeTransform: undefined, + colorTransform: undefined + }; + const decodeArr = this.dict.getArray("D", "Decode"); + if ((this.forceRGBA || this.forceRGB) && Array.isArray(decodeArr)) { + const bitsPerComponent = this.dict.get("BPC", "BitsPerComponent") || 8; + const decodeArrLength = decodeArr.length; + const transform = new Int32Array(decodeArrLength); + let transformNeeded = false; + const maxValue = (1 << bitsPerComponent) - 1; + for (let i = 0; i < decodeArrLength; i += 2) { + transform[i] = (decodeArr[i + 1] - decodeArr[i]) * 256 | 0; + transform[i + 1] = decodeArr[i] * maxValue | 0; + if (transform[i] !== 256 || transform[i + 1] !== 0) { + transformNeeded = true; + } + } + if (transformNeeded) { + jpegOptions.decodeTransform = transform; + } + } + if (this.params instanceof _primitives.Dict) { + const colorTransform = this.params.get("ColorTransform"); + if (Number.isInteger(colorTransform)) { + jpegOptions.colorTransform = colorTransform; + } + } + const jpegImage = new _jpg.JpegImage(jpegOptions); + jpegImage.parse(this.bytes); + const data = jpegImage.getData({ + width: this.drawWidth, + height: this.drawHeight, + forceRGBA: this.forceRGBA, + forceRGB: this.forceRGB, + isSourcePDF: true + }); + this.buffer = data; + this.bufferLength = data.length; + this.eof = true; + } +} +exports.JpegStream = JpegStream; + +/***/ }), +/* 27 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.JpegImage = void 0; +var _util = __w_pdfjs_require__(2); +var _image_utils = __w_pdfjs_require__(28); +var _core_utils = __w_pdfjs_require__(3); +class JpegError extends _util.BaseException { + constructor(msg) { + super(`JPEG error: ${msg}`, "JpegError"); + } +} +class DNLMarkerError extends _util.BaseException { + constructor(message, scanLines) { + super(message, "DNLMarkerError"); + this.scanLines = scanLines; + } +} +class EOIMarkerError extends _util.BaseException { + constructor(msg) { + super(msg, "EOIMarkerError"); + } +} +const dctZigZag = new Uint8Array([0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63]); +const dctCos1 = 4017; +const dctSin1 = 799; +const dctCos3 = 3406; +const dctSin3 = 2276; +const dctCos6 = 1567; +const dctSin6 = 3784; +const dctSqrt2 = 5793; +const dctSqrt1d2 = 2896; +function buildHuffmanTable(codeLengths, values) { + let k = 0, + i, + j, + length = 16; + while (length > 0 && !codeLengths[length - 1]) { + length--; + } + const code = [{ + children: [], + index: 0 + }]; + let p = code[0], + q; + for (i = 0; i < length; i++) { + for (j = 0; j < codeLengths[i]; j++) { + p = code.pop(); + p.children[p.index] = values[k]; + while (p.index > 0) { + p = code.pop(); + } + p.index++; + code.push(p); + while (code.length <= i) { + code.push(q = { + children: [], + index: 0 + }); + p.children[p.index] = q.children; + p = q; + } + k++; + } + if (i + 1 < length) { + code.push(q = { + children: [], + index: 0 + }); + p.children[p.index] = q.children; + p = q; + } + } + return code[0].children; +} +function getBlockBufferOffset(component, row, col) { + return 64 * ((component.blocksPerLine + 1) * row + col); +} +function decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successivePrev, successive, parseDNLMarker = false) { + const mcusPerLine = frame.mcusPerLine; + const progressive = frame.progressive; + const startOffset = offset; + let bitsData = 0, + bitsCount = 0; + function readBit() { + if (bitsCount > 0) { + bitsCount--; + return bitsData >> bitsCount & 1; + } + bitsData = data[offset++]; + if (bitsData === 0xff) { + const nextByte = data[offset++]; + if (nextByte) { + if (nextByte === 0xdc && parseDNLMarker) { + offset += 2; + const scanLines = (0, _core_utils.readUint16)(data, offset); + offset += 2; + if (scanLines > 0 && scanLines !== frame.scanLines) { + throw new DNLMarkerError("Found DNL marker (0xFFDC) while parsing scan data", scanLines); + } + } else if (nextByte === 0xd9) { + if (parseDNLMarker) { + const maybeScanLines = blockRow * (frame.precision === 8 ? 8 : 0); + if (maybeScanLines > 0 && Math.round(frame.scanLines / maybeScanLines) >= 5) { + throw new DNLMarkerError("Found EOI marker (0xFFD9) while parsing scan data, " + "possibly caused by incorrect `scanLines` parameter", maybeScanLines); + } + } + throw new EOIMarkerError("Found EOI marker (0xFFD9) while parsing scan data"); + } + throw new JpegError(`unexpected marker ${(bitsData << 8 | nextByte).toString(16)}`); + } + } + bitsCount = 7; + return bitsData >>> 7; + } + function decodeHuffman(tree) { + let node = tree; + while (true) { + node = node[readBit()]; + switch (typeof node) { + case "number": + return node; + case "object": + continue; + } + throw new JpegError("invalid huffman sequence"); + } + } + function receive(length) { + let n = 0; + while (length > 0) { + n = n << 1 | readBit(); + length--; + } + return n; + } + function receiveAndExtend(length) { + if (length === 1) { + return readBit() === 1 ? 1 : -1; + } + const n = receive(length); + if (n >= 1 << length - 1) { + return n; + } + return n + (-1 << length) + 1; + } + function decodeBaseline(component, blockOffset) { + const t = decodeHuffman(component.huffmanTableDC); + const diff = t === 0 ? 0 : receiveAndExtend(t); + component.blockData[blockOffset] = component.pred += diff; + let k = 1; + while (k < 64) { + const rs = decodeHuffman(component.huffmanTableAC); + const s = rs & 15, + r = rs >> 4; + if (s === 0) { + if (r < 15) { + break; + } + k += 16; + continue; + } + k += r; + const z = dctZigZag[k]; + component.blockData[blockOffset + z] = receiveAndExtend(s); + k++; + } + } + function decodeDCFirst(component, blockOffset) { + const t = decodeHuffman(component.huffmanTableDC); + const diff = t === 0 ? 0 : receiveAndExtend(t) << successive; + component.blockData[blockOffset] = component.pred += diff; + } + function decodeDCSuccessive(component, blockOffset) { + component.blockData[blockOffset] |= readBit() << successive; + } + let eobrun = 0; + function decodeACFirst(component, blockOffset) { + if (eobrun > 0) { + eobrun--; + return; + } + let k = spectralStart; + const e = spectralEnd; + while (k <= e) { + const rs = decodeHuffman(component.huffmanTableAC); + const s = rs & 15, + r = rs >> 4; + if (s === 0) { + if (r < 15) { + eobrun = receive(r) + (1 << r) - 1; + break; + } + k += 16; + continue; + } + k += r; + const z = dctZigZag[k]; + component.blockData[blockOffset + z] = receiveAndExtend(s) * (1 << successive); + k++; + } + } + let successiveACState = 0, + successiveACNextValue; + function decodeACSuccessive(component, blockOffset) { + let k = spectralStart; + const e = spectralEnd; + let r = 0; + let s; + let rs; + while (k <= e) { + const offsetZ = blockOffset + dctZigZag[k]; + const sign = component.blockData[offsetZ] < 0 ? -1 : 1; + switch (successiveACState) { + case 0: + rs = decodeHuffman(component.huffmanTableAC); + s = rs & 15; + r = rs >> 4; + if (s === 0) { + if (r < 15) { + eobrun = receive(r) + (1 << r); + successiveACState = 4; + } else { + r = 16; + successiveACState = 1; + } + } else { + if (s !== 1) { + throw new JpegError("invalid ACn encoding"); + } + successiveACNextValue = receiveAndExtend(s); + successiveACState = r ? 2 : 3; + } + continue; + case 1: + case 2: + if (component.blockData[offsetZ]) { + component.blockData[offsetZ] += sign * (readBit() << successive); + } else { + r--; + if (r === 0) { + successiveACState = successiveACState === 2 ? 3 : 0; + } + } + break; + case 3: + if (component.blockData[offsetZ]) { + component.blockData[offsetZ] += sign * (readBit() << successive); + } else { + component.blockData[offsetZ] = successiveACNextValue << successive; + successiveACState = 0; + } + break; + case 4: + if (component.blockData[offsetZ]) { + component.blockData[offsetZ] += sign * (readBit() << successive); + } + break; + } + k++; + } + if (successiveACState === 4) { + eobrun--; + if (eobrun === 0) { + successiveACState = 0; + } + } + } + let blockRow = 0; + function decodeMcu(component, decode, mcu, row, col) { + const mcuRow = mcu / mcusPerLine | 0; + const mcuCol = mcu % mcusPerLine; + blockRow = mcuRow * component.v + row; + const blockCol = mcuCol * component.h + col; + const blockOffset = getBlockBufferOffset(component, blockRow, blockCol); + decode(component, blockOffset); + } + function decodeBlock(component, decode, mcu) { + blockRow = mcu / component.blocksPerLine | 0; + const blockCol = mcu % component.blocksPerLine; + const blockOffset = getBlockBufferOffset(component, blockRow, blockCol); + decode(component, blockOffset); + } + const componentsLength = components.length; + let component, i, j, k, n; + let decodeFn; + if (progressive) { + if (spectralStart === 0) { + decodeFn = successivePrev === 0 ? decodeDCFirst : decodeDCSuccessive; + } else { + decodeFn = successivePrev === 0 ? decodeACFirst : decodeACSuccessive; + } + } else { + decodeFn = decodeBaseline; + } + let mcu = 0, + fileMarker; + const mcuExpected = componentsLength === 1 ? components[0].blocksPerLine * components[0].blocksPerColumn : mcusPerLine * frame.mcusPerColumn; + let h, v; + while (mcu <= mcuExpected) { + const mcuToRead = resetInterval ? Math.min(mcuExpected - mcu, resetInterval) : mcuExpected; + if (mcuToRead > 0) { + for (i = 0; i < componentsLength; i++) { + components[i].pred = 0; + } + eobrun = 0; + if (componentsLength === 1) { + component = components[0]; + for (n = 0; n < mcuToRead; n++) { + decodeBlock(component, decodeFn, mcu); + mcu++; + } + } else { + for (n = 0; n < mcuToRead; n++) { + for (i = 0; i < componentsLength; i++) { + component = components[i]; + h = component.h; + v = component.v; + for (j = 0; j < v; j++) { + for (k = 0; k < h; k++) { + decodeMcu(component, decodeFn, mcu, j, k); + } + } + } + mcu++; + } + } + } + bitsCount = 0; + fileMarker = findNextFileMarker(data, offset); + if (!fileMarker) { + break; + } + if (fileMarker.invalid) { + const partialMsg = mcuToRead > 0 ? "unexpected" : "excessive"; + (0, _util.warn)(`decodeScan - ${partialMsg} MCU data, current marker is: ${fileMarker.invalid}`); + offset = fileMarker.offset; + } + if (fileMarker.marker >= 0xffd0 && fileMarker.marker <= 0xffd7) { + offset += 2; + } else { + break; + } + } + return offset - startOffset; +} +function quantizeAndInverse(component, blockBufferOffset, p) { + const qt = component.quantizationTable, + blockData = component.blockData; + let v0, v1, v2, v3, v4, v5, v6, v7; + let p0, p1, p2, p3, p4, p5, p6, p7; + let t; + if (!qt) { + throw new JpegError("missing required Quantization Table."); + } + for (let row = 0; row < 64; row += 8) { + p0 = blockData[blockBufferOffset + row]; + p1 = blockData[blockBufferOffset + row + 1]; + p2 = blockData[blockBufferOffset + row + 2]; + p3 = blockData[blockBufferOffset + row + 3]; + p4 = blockData[blockBufferOffset + row + 4]; + p5 = blockData[blockBufferOffset + row + 5]; + p6 = blockData[blockBufferOffset + row + 6]; + p7 = blockData[blockBufferOffset + row + 7]; + p0 *= qt[row]; + if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) { + t = dctSqrt2 * p0 + 512 >> 10; + p[row] = t; + p[row + 1] = t; + p[row + 2] = t; + p[row + 3] = t; + p[row + 4] = t; + p[row + 5] = t; + p[row + 6] = t; + p[row + 7] = t; + continue; + } + p1 *= qt[row + 1]; + p2 *= qt[row + 2]; + p3 *= qt[row + 3]; + p4 *= qt[row + 4]; + p5 *= qt[row + 5]; + p6 *= qt[row + 6]; + p7 *= qt[row + 7]; + v0 = dctSqrt2 * p0 + 128 >> 8; + v1 = dctSqrt2 * p4 + 128 >> 8; + v2 = p2; + v3 = p6; + v4 = dctSqrt1d2 * (p1 - p7) + 128 >> 8; + v7 = dctSqrt1d2 * (p1 + p7) + 128 >> 8; + v5 = p3 << 4; + v6 = p5 << 4; + v0 = v0 + v1 + 1 >> 1; + v1 = v0 - v1; + t = v2 * dctSin6 + v3 * dctCos6 + 128 >> 8; + v2 = v2 * dctCos6 - v3 * dctSin6 + 128 >> 8; + v3 = t; + v4 = v4 + v6 + 1 >> 1; + v6 = v4 - v6; + v7 = v7 + v5 + 1 >> 1; + v5 = v7 - v5; + v0 = v0 + v3 + 1 >> 1; + v3 = v0 - v3; + v1 = v1 + v2 + 1 >> 1; + v2 = v1 - v2; + t = v4 * dctSin3 + v7 * dctCos3 + 2048 >> 12; + v4 = v4 * dctCos3 - v7 * dctSin3 + 2048 >> 12; + v7 = t; + t = v5 * dctSin1 + v6 * dctCos1 + 2048 >> 12; + v5 = v5 * dctCos1 - v6 * dctSin1 + 2048 >> 12; + v6 = t; + p[row] = v0 + v7; + p[row + 7] = v0 - v7; + p[row + 1] = v1 + v6; + p[row + 6] = v1 - v6; + p[row + 2] = v2 + v5; + p[row + 5] = v2 - v5; + p[row + 3] = v3 + v4; + p[row + 4] = v3 - v4; + } + for (let col = 0; col < 8; ++col) { + p0 = p[col]; + p1 = p[col + 8]; + p2 = p[col + 16]; + p3 = p[col + 24]; + p4 = p[col + 32]; + p5 = p[col + 40]; + p6 = p[col + 48]; + p7 = p[col + 56]; + if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) { + t = dctSqrt2 * p0 + 8192 >> 14; + if (t < -2040) { + t = 0; + } else if (t >= 2024) { + t = 255; + } else { + t = t + 2056 >> 4; + } + blockData[blockBufferOffset + col] = t; + blockData[blockBufferOffset + col + 8] = t; + blockData[blockBufferOffset + col + 16] = t; + blockData[blockBufferOffset + col + 24] = t; + blockData[blockBufferOffset + col + 32] = t; + blockData[blockBufferOffset + col + 40] = t; + blockData[blockBufferOffset + col + 48] = t; + blockData[blockBufferOffset + col + 56] = t; + continue; + } + v0 = dctSqrt2 * p0 + 2048 >> 12; + v1 = dctSqrt2 * p4 + 2048 >> 12; + v2 = p2; + v3 = p6; + v4 = dctSqrt1d2 * (p1 - p7) + 2048 >> 12; + v7 = dctSqrt1d2 * (p1 + p7) + 2048 >> 12; + v5 = p3; + v6 = p5; + v0 = (v0 + v1 + 1 >> 1) + 4112; + v1 = v0 - v1; + t = v2 * dctSin6 + v3 * dctCos6 + 2048 >> 12; + v2 = v2 * dctCos6 - v3 * dctSin6 + 2048 >> 12; + v3 = t; + v4 = v4 + v6 + 1 >> 1; + v6 = v4 - v6; + v7 = v7 + v5 + 1 >> 1; + v5 = v7 - v5; + v0 = v0 + v3 + 1 >> 1; + v3 = v0 - v3; + v1 = v1 + v2 + 1 >> 1; + v2 = v1 - v2; + t = v4 * dctSin3 + v7 * dctCos3 + 2048 >> 12; + v4 = v4 * dctCos3 - v7 * dctSin3 + 2048 >> 12; + v7 = t; + t = v5 * dctSin1 + v6 * dctCos1 + 2048 >> 12; + v5 = v5 * dctCos1 - v6 * dctSin1 + 2048 >> 12; + v6 = t; + p0 = v0 + v7; + p7 = v0 - v7; + p1 = v1 + v6; + p6 = v1 - v6; + p2 = v2 + v5; + p5 = v2 - v5; + p3 = v3 + v4; + p4 = v3 - v4; + if (p0 < 16) { + p0 = 0; + } else if (p0 >= 4080) { + p0 = 255; + } else { + p0 >>= 4; + } + if (p1 < 16) { + p1 = 0; + } else if (p1 >= 4080) { + p1 = 255; + } else { + p1 >>= 4; + } + if (p2 < 16) { + p2 = 0; + } else if (p2 >= 4080) { + p2 = 255; + } else { + p2 >>= 4; + } + if (p3 < 16) { + p3 = 0; + } else if (p3 >= 4080) { + p3 = 255; + } else { + p3 >>= 4; + } + if (p4 < 16) { + p4 = 0; + } else if (p4 >= 4080) { + p4 = 255; + } else { + p4 >>= 4; + } + if (p5 < 16) { + p5 = 0; + } else if (p5 >= 4080) { + p5 = 255; + } else { + p5 >>= 4; + } + if (p6 < 16) { + p6 = 0; + } else if (p6 >= 4080) { + p6 = 255; + } else { + p6 >>= 4; + } + if (p7 < 16) { + p7 = 0; + } else if (p7 >= 4080) { + p7 = 255; + } else { + p7 >>= 4; + } + blockData[blockBufferOffset + col] = p0; + blockData[blockBufferOffset + col + 8] = p1; + blockData[blockBufferOffset + col + 16] = p2; + blockData[blockBufferOffset + col + 24] = p3; + blockData[blockBufferOffset + col + 32] = p4; + blockData[blockBufferOffset + col + 40] = p5; + blockData[blockBufferOffset + col + 48] = p6; + blockData[blockBufferOffset + col + 56] = p7; + } +} +function buildComponentData(frame, component) { + const blocksPerLine = component.blocksPerLine; + const blocksPerColumn = component.blocksPerColumn; + const computationBuffer = new Int16Array(64); + for (let blockRow = 0; blockRow < blocksPerColumn; blockRow++) { + for (let blockCol = 0; blockCol < blocksPerLine; blockCol++) { + const offset = getBlockBufferOffset(component, blockRow, blockCol); + quantizeAndInverse(component, offset, computationBuffer); + } + } + return component.blockData; +} +function findNextFileMarker(data, currentPos, startPos = currentPos) { + const maxPos = data.length - 1; + let newPos = startPos < currentPos ? startPos : currentPos; + if (currentPos >= maxPos) { + return null; + } + const currentMarker = (0, _core_utils.readUint16)(data, currentPos); + if (currentMarker >= 0xffc0 && currentMarker <= 0xfffe) { + return { + invalid: null, + marker: currentMarker, + offset: currentPos + }; + } + let newMarker = (0, _core_utils.readUint16)(data, newPos); + while (!(newMarker >= 0xffc0 && newMarker <= 0xfffe)) { + if (++newPos >= maxPos) { + return null; + } + newMarker = (0, _core_utils.readUint16)(data, newPos); + } + return { + invalid: currentMarker.toString(16), + marker: newMarker, + offset: newPos + }; +} +class JpegImage { + constructor({ + decodeTransform = null, + colorTransform = -1 + } = {}) { + this._decodeTransform = decodeTransform; + this._colorTransform = colorTransform; + } + parse(data, { + dnlScanLines = null + } = {}) { + function readDataBlock() { + const length = (0, _core_utils.readUint16)(data, offset); + offset += 2; + let endOffset = offset + length - 2; + const fileMarker = findNextFileMarker(data, endOffset, offset); + if (fileMarker?.invalid) { + (0, _util.warn)("readDataBlock - incorrect length, current marker is: " + fileMarker.invalid); + endOffset = fileMarker.offset; + } + const array = data.subarray(offset, endOffset); + offset += array.length; + return array; + } + function prepareComponents(frame) { + const mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / frame.maxH); + const mcusPerColumn = Math.ceil(frame.scanLines / 8 / frame.maxV); + for (const component of frame.components) { + const blocksPerLine = Math.ceil(Math.ceil(frame.samplesPerLine / 8) * component.h / frame.maxH); + const blocksPerColumn = Math.ceil(Math.ceil(frame.scanLines / 8) * component.v / frame.maxV); + const blocksPerLineForMcu = mcusPerLine * component.h; + const blocksPerColumnForMcu = mcusPerColumn * component.v; + const blocksBufferSize = 64 * blocksPerColumnForMcu * (blocksPerLineForMcu + 1); + component.blockData = new Int16Array(blocksBufferSize); + component.blocksPerLine = blocksPerLine; + component.blocksPerColumn = blocksPerColumn; + } + frame.mcusPerLine = mcusPerLine; + frame.mcusPerColumn = mcusPerColumn; + } + let offset = 0; + let jfif = null; + let adobe = null; + let frame, resetInterval; + let numSOSMarkers = 0; + const quantizationTables = []; + const huffmanTablesAC = [], + huffmanTablesDC = []; + let fileMarker = (0, _core_utils.readUint16)(data, offset); + offset += 2; + if (fileMarker !== 0xffd8) { + throw new JpegError("SOI not found"); + } + fileMarker = (0, _core_utils.readUint16)(data, offset); + offset += 2; + markerLoop: while (fileMarker !== 0xffd9) { + let i, j, l; + switch (fileMarker) { + case 0xffe0: + case 0xffe1: + case 0xffe2: + case 0xffe3: + case 0xffe4: + case 0xffe5: + case 0xffe6: + case 0xffe7: + case 0xffe8: + case 0xffe9: + case 0xffea: + case 0xffeb: + case 0xffec: + case 0xffed: + case 0xffee: + case 0xffef: + case 0xfffe: + const appData = readDataBlock(); + if (fileMarker === 0xffe0) { + if (appData[0] === 0x4a && appData[1] === 0x46 && appData[2] === 0x49 && appData[3] === 0x46 && appData[4] === 0) { + jfif = { + version: { + major: appData[5], + minor: appData[6] + }, + densityUnits: appData[7], + xDensity: appData[8] << 8 | appData[9], + yDensity: appData[10] << 8 | appData[11], + thumbWidth: appData[12], + thumbHeight: appData[13], + thumbData: appData.subarray(14, 14 + 3 * appData[12] * appData[13]) + }; + } + } + if (fileMarker === 0xffee) { + if (appData[0] === 0x41 && appData[1] === 0x64 && appData[2] === 0x6f && appData[3] === 0x62 && appData[4] === 0x65) { + adobe = { + version: appData[5] << 8 | appData[6], + flags0: appData[7] << 8 | appData[8], + flags1: appData[9] << 8 | appData[10], + transformCode: appData[11] + }; + } + } + break; + case 0xffdb: + const quantizationTablesLength = (0, _core_utils.readUint16)(data, offset); + offset += 2; + const quantizationTablesEnd = quantizationTablesLength + offset - 2; + let z; + while (offset < quantizationTablesEnd) { + const quantizationTableSpec = data[offset++]; + const tableData = new Uint16Array(64); + if (quantizationTableSpec >> 4 === 0) { + for (j = 0; j < 64; j++) { + z = dctZigZag[j]; + tableData[z] = data[offset++]; + } + } else if (quantizationTableSpec >> 4 === 1) { + for (j = 0; j < 64; j++) { + z = dctZigZag[j]; + tableData[z] = (0, _core_utils.readUint16)(data, offset); + offset += 2; + } + } else { + throw new JpegError("DQT - invalid table spec"); + } + quantizationTables[quantizationTableSpec & 15] = tableData; + } + break; + case 0xffc0: + case 0xffc1: + case 0xffc2: + if (frame) { + throw new JpegError("Only single frame JPEGs supported"); + } + offset += 2; + frame = {}; + frame.extended = fileMarker === 0xffc1; + frame.progressive = fileMarker === 0xffc2; + frame.precision = data[offset++]; + const sofScanLines = (0, _core_utils.readUint16)(data, offset); + offset += 2; + frame.scanLines = dnlScanLines || sofScanLines; + frame.samplesPerLine = (0, _core_utils.readUint16)(data, offset); + offset += 2; + frame.components = []; + frame.componentIds = {}; + const componentsCount = data[offset++]; + let maxH = 0, + maxV = 0; + for (i = 0; i < componentsCount; i++) { + const componentId = data[offset]; + const h = data[offset + 1] >> 4; + const v = data[offset + 1] & 15; + if (maxH < h) { + maxH = h; + } + if (maxV < v) { + maxV = v; + } + const qId = data[offset + 2]; + l = frame.components.push({ + h, + v, + quantizationId: qId, + quantizationTable: null + }); + frame.componentIds[componentId] = l - 1; + offset += 3; + } + frame.maxH = maxH; + frame.maxV = maxV; + prepareComponents(frame); + break; + case 0xffc4: + const huffmanLength = (0, _core_utils.readUint16)(data, offset); + offset += 2; + for (i = 2; i < huffmanLength;) { + const huffmanTableSpec = data[offset++]; + const codeLengths = new Uint8Array(16); + let codeLengthSum = 0; + for (j = 0; j < 16; j++, offset++) { + codeLengthSum += codeLengths[j] = data[offset]; + } + const huffmanValues = new Uint8Array(codeLengthSum); + for (j = 0; j < codeLengthSum; j++, offset++) { + huffmanValues[j] = data[offset]; + } + i += 17 + codeLengthSum; + (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable(codeLengths, huffmanValues); + } + break; + case 0xffdd: + offset += 2; + resetInterval = (0, _core_utils.readUint16)(data, offset); + offset += 2; + break; + case 0xffda: + const parseDNLMarker = ++numSOSMarkers === 1 && !dnlScanLines; + offset += 2; + const selectorsCount = data[offset++], + components = []; + for (i = 0; i < selectorsCount; i++) { + const index = data[offset++]; + const componentIndex = frame.componentIds[index]; + const component = frame.components[componentIndex]; + component.index = index; + const tableSpec = data[offset++]; + component.huffmanTableDC = huffmanTablesDC[tableSpec >> 4]; + component.huffmanTableAC = huffmanTablesAC[tableSpec & 15]; + components.push(component); + } + const spectralStart = data[offset++], + spectralEnd = data[offset++], + successiveApproximation = data[offset++]; + try { + const processed = decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successiveApproximation >> 4, successiveApproximation & 15, parseDNLMarker); + offset += processed; + } catch (ex) { + if (ex instanceof DNLMarkerError) { + (0, _util.warn)(`${ex.message} -- attempting to re-parse the JPEG image.`); + return this.parse(data, { + dnlScanLines: ex.scanLines + }); + } else if (ex instanceof EOIMarkerError) { + (0, _util.warn)(`${ex.message} -- ignoring the rest of the image data.`); + break markerLoop; + } + throw ex; + } + break; + case 0xffdc: + offset += 4; + break; + case 0xffff: + if (data[offset] !== 0xff) { + offset--; + } + break; + default: + const nextFileMarker = findNextFileMarker(data, offset - 2, offset - 3); + if (nextFileMarker?.invalid) { + (0, _util.warn)("JpegImage.parse - unexpected data, current marker is: " + nextFileMarker.invalid); + offset = nextFileMarker.offset; + break; + } + if (!nextFileMarker || offset >= data.length - 1) { + (0, _util.warn)("JpegImage.parse - reached the end of the image data " + "without finding an EOI marker (0xFFD9)."); + break markerLoop; + } + throw new JpegError("JpegImage.parse - unknown marker: " + fileMarker.toString(16)); + } + fileMarker = (0, _core_utils.readUint16)(data, offset); + offset += 2; + } + this.width = frame.samplesPerLine; + this.height = frame.scanLines; + this.jfif = jfif; + this.adobe = adobe; + this.components = []; + for (const component of frame.components) { + const quantizationTable = quantizationTables[component.quantizationId]; + if (quantizationTable) { + component.quantizationTable = quantizationTable; + } + this.components.push({ + index: component.index, + output: buildComponentData(frame, component), + scaleX: component.h / frame.maxH, + scaleY: component.v / frame.maxV, + blocksPerLine: component.blocksPerLine, + blocksPerColumn: component.blocksPerColumn + }); + } + this.numComponents = this.components.length; + return undefined; + } + _getLinearizedBlockData(width, height, isSourcePDF = false) { + const scaleX = this.width / width, + scaleY = this.height / height; + let component, componentScaleX, componentScaleY, blocksPerScanline; + let x, y, i, j, k; + let index; + let offset = 0; + let output; + const numComponents = this.components.length; + const dataLength = width * height * numComponents; + const data = new Uint8ClampedArray(dataLength); + const xScaleBlockOffset = new Uint32Array(width); + const mask3LSB = 0xfffffff8; + let lastComponentScaleX; + for (i = 0; i < numComponents; i++) { + component = this.components[i]; + componentScaleX = component.scaleX * scaleX; + componentScaleY = component.scaleY * scaleY; + offset = i; + output = component.output; + blocksPerScanline = component.blocksPerLine + 1 << 3; + if (componentScaleX !== lastComponentScaleX) { + for (x = 0; x < width; x++) { + j = 0 | x * componentScaleX; + xScaleBlockOffset[x] = (j & mask3LSB) << 3 | j & 7; + } + lastComponentScaleX = componentScaleX; + } + for (y = 0; y < height; y++) { + j = 0 | y * componentScaleY; + index = blocksPerScanline * (j & mask3LSB) | (j & 7) << 3; + for (x = 0; x < width; x++) { + data[offset] = output[index + xScaleBlockOffset[x]]; + offset += numComponents; + } + } + } + let transform = this._decodeTransform; + if (!isSourcePDF && numComponents === 4 && !transform) { + transform = new Int32Array([-256, 255, -256, 255, -256, 255, -256, 255]); + } + if (transform) { + for (i = 0; i < dataLength;) { + for (j = 0, k = 0; j < numComponents; j++, i++, k += 2) { + data[i] = (data[i] * transform[k] >> 8) + transform[k + 1]; + } + } + } + return data; + } + get _isColorConversionNeeded() { + if (this.adobe) { + return !!this.adobe.transformCode; + } + if (this.numComponents === 3) { + if (this._colorTransform === 0) { + return false; + } else if (this.components[0].index === 0x52 && this.components[1].index === 0x47 && this.components[2].index === 0x42) { + return false; + } + return true; + } + if (this._colorTransform === 1) { + return true; + } + return false; + } + _convertYccToRgb(data) { + let Y, Cb, Cr; + for (let i = 0, length = data.length; i < length; i += 3) { + Y = data[i]; + Cb = data[i + 1]; + Cr = data[i + 2]; + data[i] = Y - 179.456 + 1.402 * Cr; + data[i + 1] = Y + 135.459 - 0.344 * Cb - 0.714 * Cr; + data[i + 2] = Y - 226.816 + 1.772 * Cb; + } + return data; + } + _convertYccToRgba(data, out) { + for (let i = 0, j = 0, length = data.length; i < length; i += 3, j += 4) { + const Y = data[i]; + const Cb = data[i + 1]; + const Cr = data[i + 2]; + out[j] = Y - 179.456 + 1.402 * Cr; + out[j + 1] = Y + 135.459 - 0.344 * Cb - 0.714 * Cr; + out[j + 2] = Y - 226.816 + 1.772 * Cb; + out[j + 3] = 255; + } + return out; + } + _convertYcckToRgb(data) { + let Y, Cb, Cr, k; + let offset = 0; + for (let i = 0, length = data.length; i < length; i += 4) { + Y = data[i]; + Cb = data[i + 1]; + Cr = data[i + 2]; + k = data[i + 3]; + data[offset++] = -122.67195406894 + Cb * (-6.60635669420364e-5 * Cb + 0.000437130475926232 * Cr - 5.4080610064599e-5 * Y + 0.00048449797120281 * k - 0.154362151871126) + Cr * (-0.000957964378445773 * Cr + 0.000817076911346625 * Y - 0.00477271405408747 * k + 1.53380253221734) + Y * (0.000961250184130688 * Y - 0.00266257332283933 * k + 0.48357088451265) + k * (-0.000336197177618394 * k + 0.484791561490776); + data[offset++] = 107.268039397724 + Cb * (2.19927104525741e-5 * Cb - 0.000640992018297945 * Cr + 0.000659397001245577 * Y + 0.000426105652938837 * k - 0.176491792462875) + Cr * (-0.000778269941513683 * Cr + 0.00130872261408275 * Y + 0.000770482631801132 * k - 0.151051492775562) + Y * (0.00126935368114843 * Y - 0.00265090189010898 * k + 0.25802910206845) + k * (-0.000318913117588328 * k - 0.213742400323665); + data[offset++] = -20.810012546947 + Cb * (-0.000570115196973677 * Cb - 2.63409051004589e-5 * Cr + 0.0020741088115012 * Y - 0.00288260236853442 * k + 0.814272968359295) + Cr * (-1.53496057440975e-5 * Cr - 0.000132689043961446 * Y + 0.000560833691242812 * k - 0.195152027534049) + Y * (0.00174418132927582 * Y - 0.00255243321439347 * k + 0.116935020465145) + k * (-0.000343531996510555 * k + 0.24165260232407); + } + return data.subarray(0, offset); + } + _convertYcckToRgba(data) { + for (let i = 0, length = data.length; i < length; i += 4) { + const Y = data[i]; + const Cb = data[i + 1]; + const Cr = data[i + 2]; + const k = data[i + 3]; + data[i] = -122.67195406894 + Cb * (-6.60635669420364e-5 * Cb + 0.000437130475926232 * Cr - 5.4080610064599e-5 * Y + 0.00048449797120281 * k - 0.154362151871126) + Cr * (-0.000957964378445773 * Cr + 0.000817076911346625 * Y - 0.00477271405408747 * k + 1.53380253221734) + Y * (0.000961250184130688 * Y - 0.00266257332283933 * k + 0.48357088451265) + k * (-0.000336197177618394 * k + 0.484791561490776); + data[i + 1] = 107.268039397724 + Cb * (2.19927104525741e-5 * Cb - 0.000640992018297945 * Cr + 0.000659397001245577 * Y + 0.000426105652938837 * k - 0.176491792462875) + Cr * (-0.000778269941513683 * Cr + 0.00130872261408275 * Y + 0.000770482631801132 * k - 0.151051492775562) + Y * (0.00126935368114843 * Y - 0.00265090189010898 * k + 0.25802910206845) + k * (-0.000318913117588328 * k - 0.213742400323665); + data[i + 2] = -20.810012546947 + Cb * (-0.000570115196973677 * Cb - 2.63409051004589e-5 * Cr + 0.0020741088115012 * Y - 0.00288260236853442 * k + 0.814272968359295) + Cr * (-1.53496057440975e-5 * Cr - 0.000132689043961446 * Y + 0.000560833691242812 * k - 0.195152027534049) + Y * (0.00174418132927582 * Y - 0.00255243321439347 * k + 0.116935020465145) + k * (-0.000343531996510555 * k + 0.24165260232407); + data[i + 3] = 255; + } + return data; + } + _convertYcckToCmyk(data) { + let Y, Cb, Cr; + for (let i = 0, length = data.length; i < length; i += 4) { + Y = data[i]; + Cb = data[i + 1]; + Cr = data[i + 2]; + data[i] = 434.456 - Y - 1.402 * Cr; + data[i + 1] = 119.541 - Y + 0.344 * Cb + 0.714 * Cr; + data[i + 2] = 481.816 - Y - 1.772 * Cb; + } + return data; + } + _convertCmykToRgb(data) { + let c, m, y, k; + let offset = 0; + for (let i = 0, length = data.length; i < length; i += 4) { + c = data[i]; + m = data[i + 1]; + y = data[i + 2]; + k = data[i + 3]; + data[offset++] = 255 + c * (-0.00006747147073602441 * c + 0.0008379262121013727 * m + 0.0002894718188643294 * y + 0.003264231057537806 * k - 1.1185611867203937) + m * (0.000026374107616089405 * m - 0.00008626949158638572 * y - 0.0002748769067499491 * k - 0.02155688794978967) + y * (-0.00003878099212869363 * y - 0.0003267808279485286 * k + 0.0686742238595345) - k * (0.0003361971776183937 * k + 0.7430659151342254); + data[offset++] = 255 + c * (0.00013596372813588848 * c + 0.000924537132573585 * m + 0.00010567359618683593 * y + 0.0004791864687436512 * k - 0.3109689587515875) + m * (-0.00023545346108370344 * m + 0.0002702845253534714 * y + 0.0020200308977307156 * k - 0.7488052167015494) + y * (0.00006834815998235662 * y + 0.00015168452363460973 * k - 0.09751927774728933) - k * (0.0003189131175883281 * k + 0.7364883807733168); + data[offset++] = 255 + c * (0.000013598650411385307 * c + 0.00012423956175490851 * m + 0.0004751985097583589 * y - 0.0000036729317476630422 * k - 0.05562186980264034) + m * (0.00016141380598724676 * m + 0.0009692239130725186 * y + 0.0007782692450036253 * k - 0.44015232367526463) + y * (5.068882914068769e-7 * y + 0.0017778369011375071 * k - 0.7591454649749609) - k * (0.0003435319965105553 * k + 0.7063770186160144); + } + return data.subarray(0, offset); + } + _convertCmykToRgba(data) { + for (let i = 0, length = data.length; i < length; i += 4) { + const c = data[i]; + const m = data[i + 1]; + const y = data[i + 2]; + const k = data[i + 3]; + data[i] = 255 + c * (-0.00006747147073602441 * c + 0.0008379262121013727 * m + 0.0002894718188643294 * y + 0.003264231057537806 * k - 1.1185611867203937) + m * (0.000026374107616089405 * m - 0.00008626949158638572 * y - 0.0002748769067499491 * k - 0.02155688794978967) + y * (-0.00003878099212869363 * y - 0.0003267808279485286 * k + 0.0686742238595345) - k * (0.0003361971776183937 * k + 0.7430659151342254); + data[i + 1] = 255 + c * (0.00013596372813588848 * c + 0.000924537132573585 * m + 0.00010567359618683593 * y + 0.0004791864687436512 * k - 0.3109689587515875) + m * (-0.00023545346108370344 * m + 0.0002702845253534714 * y + 0.0020200308977307156 * k - 0.7488052167015494) + y * (0.00006834815998235662 * y + 0.00015168452363460973 * k - 0.09751927774728933) - k * (0.0003189131175883281 * k + 0.7364883807733168); + data[i + 2] = 255 + c * (0.000013598650411385307 * c + 0.00012423956175490851 * m + 0.0004751985097583589 * y - 0.0000036729317476630422 * k - 0.05562186980264034) + m * (0.00016141380598724676 * m + 0.0009692239130725186 * y + 0.0007782692450036253 * k - 0.44015232367526463) + y * (5.068882914068769e-7 * y + 0.0017778369011375071 * k - 0.7591454649749609) - k * (0.0003435319965105553 * k + 0.7063770186160144); + data[i + 3] = 255; + } + return data; + } + getData({ + width, + height, + forceRGBA = false, + forceRGB = false, + isSourcePDF = false + }) { + if (this.numComponents > 4) { + throw new JpegError("Unsupported color mode"); + } + const data = this._getLinearizedBlockData(width, height, isSourcePDF); + if (this.numComponents === 1 && (forceRGBA || forceRGB)) { + const len = data.length * (forceRGBA ? 4 : 3); + const rgbaData = new Uint8ClampedArray(len); + let offset = 0; + if (forceRGBA) { + (0, _image_utils.grayToRGBA)(data, new Uint32Array(rgbaData.buffer)); + } else { + for (const grayColor of data) { + rgbaData[offset++] = grayColor; + rgbaData[offset++] = grayColor; + rgbaData[offset++] = grayColor; + } + } + return rgbaData; + } else if (this.numComponents === 3 && this._isColorConversionNeeded) { + if (forceRGBA) { + const rgbaData = new Uint8ClampedArray(data.length / 3 * 4); + return this._convertYccToRgba(data, rgbaData); + } + return this._convertYccToRgb(data); + } else if (this.numComponents === 4) { + if (this._isColorConversionNeeded) { + if (forceRGBA) { + return this._convertYcckToRgba(data); + } + if (forceRGB) { + return this._convertYcckToRgb(data); + } + return this._convertYcckToCmyk(data); + } else if (forceRGBA) { + return this._convertCmykToRgba(data); + } else if (forceRGB) { + return this._convertCmykToRgb(data); + } + } + return data; + } +} +exports.JpegImage = JpegImage; + +/***/ }), +/* 28 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.convertBlackAndWhiteToRGBA = convertBlackAndWhiteToRGBA; +exports.convertToRGBA = convertToRGBA; +exports.grayToRGBA = grayToRGBA; +var _util = __w_pdfjs_require__(2); +function convertToRGBA(params) { + switch (params.kind) { + case _util.ImageKind.GRAYSCALE_1BPP: + return convertBlackAndWhiteToRGBA(params); + case _util.ImageKind.RGB_24BPP: + return convertRGBToRGBA(params); + } + return null; +} +function convertBlackAndWhiteToRGBA({ + src, + srcPos = 0, + dest, + width, + height, + nonBlackColor = 0xffffffff, + inverseDecode = false +}) { + const black = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff; + const [zeroMapping, oneMapping] = inverseDecode ? [nonBlackColor, black] : [black, nonBlackColor]; + const widthInSource = width >> 3; + const widthRemainder = width & 7; + const srcLength = src.length; + dest = new Uint32Array(dest.buffer); + let destPos = 0; + for (let i = 0; i < height; i++) { + for (const max = srcPos + widthInSource; srcPos < max; srcPos++) { + const elem = srcPos < srcLength ? src[srcPos] : 255; + dest[destPos++] = elem & 0b10000000 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b1000000 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b100000 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b10000 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b1000 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b100 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b10 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b1 ? oneMapping : zeroMapping; + } + if (widthRemainder === 0) { + continue; + } + const elem = srcPos < srcLength ? src[srcPos++] : 255; + for (let j = 0; j < widthRemainder; j++) { + dest[destPos++] = elem & 1 << 7 - j ? oneMapping : zeroMapping; + } + } + return { + srcPos, + destPos + }; +} +function convertRGBToRGBA({ + src, + srcPos = 0, + dest, + destPos = 0, + width, + height +}) { + let i = 0; + const len32 = src.length >> 2; + const src32 = new Uint32Array(src.buffer, srcPos, len32); + if (_util.FeatureTest.isLittleEndian) { + for (; i < len32 - 2; i += 3, destPos += 4) { + const s1 = src32[i]; + const s2 = src32[i + 1]; + const s3 = src32[i + 2]; + dest[destPos] = s1 | 0xff000000; + dest[destPos + 1] = s1 >>> 24 | s2 << 8 | 0xff000000; + dest[destPos + 2] = s2 >>> 16 | s3 << 16 | 0xff000000; + dest[destPos + 3] = s3 >>> 8 | 0xff000000; + } + for (let j = i * 4, jj = src.length; j < jj; j += 3) { + dest[destPos++] = src[j] | src[j + 1] << 8 | src[j + 2] << 16 | 0xff000000; + } + } else { + for (; i < len32 - 2; i += 3, destPos += 4) { + const s1 = src32[i]; + const s2 = src32[i + 1]; + const s3 = src32[i + 2]; + dest[destPos] = s1 | 0xff; + dest[destPos + 1] = s1 << 24 | s2 >>> 8 | 0xff; + dest[destPos + 2] = s2 << 16 | s3 >>> 16 | 0xff; + dest[destPos + 3] = s3 << 8 | 0xff; + } + for (let j = i * 4, jj = src.length; j < jj; j += 3) { + dest[destPos++] = src[j] << 24 | src[j + 1] << 16 | src[j + 2] << 8 | 0xff; + } + } + return { + srcPos, + destPos + }; +} +function grayToRGBA(src, dest) { + if (_util.FeatureTest.isLittleEndian) { + for (let i = 0, ii = src.length; i < ii; i++) { + dest[i] = src[i] * 0x10101 | 0xff000000; + } + } else { + for (let i = 0, ii = src.length; i < ii; i++) { + dest[i] = src[i] * 0x1010100 | 0x000000ff; + } + } +} + +/***/ }), +/* 29 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.JpxStream = void 0; +var _decode_stream = __w_pdfjs_require__(18); +var _jpx = __w_pdfjs_require__(30); +var _util = __w_pdfjs_require__(2); +class JpxStream extends _decode_stream.DecodeStream { + constructor(stream, maybeLength, params) { + super(maybeLength); + this.stream = stream; + this.dict = stream.dict; + this.maybeLength = maybeLength; + this.params = params; + } + get bytes() { + return (0, _util.shadow)(this, "bytes", this.stream.getBytes(this.maybeLength)); + } + ensureBuffer(requested) {} + readBlock() { + if (this.eof) { + return; + } + const jpxImage = new _jpx.JpxImage(); + jpxImage.parse(this.bytes); + const width = jpxImage.width; + const height = jpxImage.height; + const componentsCount = jpxImage.componentsCount; + const tileCount = jpxImage.tiles.length; + if (tileCount === 1) { + this.buffer = jpxImage.tiles[0].items; + } else { + const data = new Uint8ClampedArray(width * height * componentsCount); + for (let k = 0; k < tileCount; k++) { + const tileComponents = jpxImage.tiles[k]; + const tileWidth = tileComponents.width; + const tileHeight = tileComponents.height; + const tileLeft = tileComponents.left; + const tileTop = tileComponents.top; + const src = tileComponents.items; + let srcPosition = 0; + let dataPosition = (width * tileTop + tileLeft) * componentsCount; + const imgRowSize = width * componentsCount; + const tileRowSize = tileWidth * componentsCount; + for (let j = 0; j < tileHeight; j++) { + const rowBytes = src.subarray(srcPosition, srcPosition + tileRowSize); + data.set(rowBytes, dataPosition); + srcPosition += tileRowSize; + dataPosition += imgRowSize; + } + } + this.buffer = data; + } + this.bufferLength = this.buffer.length; + this.eof = true; + } +} +exports.JpxStream = JpxStream; + +/***/ }), +/* 30 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.JpxImage = void 0; +var _util = __w_pdfjs_require__(2); +var _core_utils = __w_pdfjs_require__(3); +var _arithmetic_decoder = __w_pdfjs_require__(25); +class JpxError extends _util.BaseException { + constructor(msg) { + super(`JPX error: ${msg}`, "JpxError"); + } +} +const SubbandsGainLog2 = { + LL: 0, + LH: 1, + HL: 1, + HH: 2 +}; +class JpxImage { + constructor() { + this.failOnCorruptedImage = false; + } + parse(data) { + const head = (0, _core_utils.readUint16)(data, 0); + if (head === 0xff4f) { + this.parseCodestream(data, 0, data.length); + return; + } + const length = data.length; + let position = 0; + while (position < length) { + let headerSize = 8; + let lbox = (0, _core_utils.readUint32)(data, position); + const tbox = (0, _core_utils.readUint32)(data, position + 4); + position += headerSize; + if (lbox === 1) { + lbox = (0, _core_utils.readUint32)(data, position) * 4294967296 + (0, _core_utils.readUint32)(data, position + 4); + position += 8; + headerSize += 8; + } + if (lbox === 0) { + lbox = length - position + headerSize; + } + if (lbox < headerSize) { + throw new JpxError("Invalid box field size"); + } + const dataLength = lbox - headerSize; + let jumpDataLength = true; + switch (tbox) { + case 0x6a703268: + jumpDataLength = false; + break; + case 0x636f6c72: + const method = data[position]; + if (method === 1) { + const colorspace = (0, _core_utils.readUint32)(data, position + 3); + switch (colorspace) { + case 16: + case 17: + case 18: + break; + default: + (0, _util.warn)("Unknown colorspace " + colorspace); + break; + } + } else if (method === 2) { + (0, _util.info)("ICC profile not supported"); + } + break; + case 0x6a703263: + this.parseCodestream(data, position, position + dataLength); + break; + case 0x6a502020: + if ((0, _core_utils.readUint32)(data, position) !== 0x0d0a870a) { + (0, _util.warn)("Invalid JP2 signature"); + } + break; + case 0x6a501a1a: + case 0x66747970: + case 0x72726571: + case 0x72657320: + case 0x69686472: + break; + default: + const headerType = String.fromCharCode(tbox >> 24 & 0xff, tbox >> 16 & 0xff, tbox >> 8 & 0xff, tbox & 0xff); + (0, _util.warn)(`Unsupported header type ${tbox} (${headerType}).`); + break; + } + if (jumpDataLength) { + position += dataLength; + } + } + } + parseImageProperties(stream) { + let newByte = stream.getByte(); + while (newByte >= 0) { + const oldByte = newByte; + newByte = stream.getByte(); + const code = oldByte << 8 | newByte; + if (code === 0xff51) { + stream.skip(4); + const Xsiz = stream.getInt32() >>> 0; + const Ysiz = stream.getInt32() >>> 0; + const XOsiz = stream.getInt32() >>> 0; + const YOsiz = stream.getInt32() >>> 0; + stream.skip(16); + const Csiz = stream.getUint16(); + this.width = Xsiz - XOsiz; + this.height = Ysiz - YOsiz; + this.componentsCount = Csiz; + this.bitsPerComponent = 8; + return; + } + } + throw new JpxError("No size marker found in JPX stream"); + } + parseCodestream(data, start, end) { + const context = {}; + let doNotRecover = false; + try { + let position = start; + while (position + 1 < end) { + const code = (0, _core_utils.readUint16)(data, position); + position += 2; + let length = 0, + j, + sqcd, + spqcds, + spqcdSize, + scalarExpounded, + tile; + switch (code) { + case 0xff4f: + context.mainHeader = true; + break; + case 0xffd9: + break; + case 0xff51: + length = (0, _core_utils.readUint16)(data, position); + const siz = {}; + siz.Xsiz = (0, _core_utils.readUint32)(data, position + 4); + siz.Ysiz = (0, _core_utils.readUint32)(data, position + 8); + siz.XOsiz = (0, _core_utils.readUint32)(data, position + 12); + siz.YOsiz = (0, _core_utils.readUint32)(data, position + 16); + siz.XTsiz = (0, _core_utils.readUint32)(data, position + 20); + siz.YTsiz = (0, _core_utils.readUint32)(data, position + 24); + siz.XTOsiz = (0, _core_utils.readUint32)(data, position + 28); + siz.YTOsiz = (0, _core_utils.readUint32)(data, position + 32); + const componentsCount = (0, _core_utils.readUint16)(data, position + 36); + siz.Csiz = componentsCount; + const components = []; + j = position + 38; + for (let i = 0; i < componentsCount; i++) { + const component = { + precision: (data[j] & 0x7f) + 1, + isSigned: !!(data[j] & 0x80), + XRsiz: data[j + 1], + YRsiz: data[j + 2] + }; + j += 3; + calculateComponentDimensions(component, siz); + components.push(component); + } + context.SIZ = siz; + context.components = components; + calculateTileGrids(context, components); + context.QCC = []; + context.COC = []; + break; + case 0xff5c: + length = (0, _core_utils.readUint16)(data, position); + const qcd = {}; + j = position + 2; + sqcd = data[j++]; + switch (sqcd & 0x1f) { + case 0: + spqcdSize = 8; + scalarExpounded = true; + break; + case 1: + spqcdSize = 16; + scalarExpounded = false; + break; + case 2: + spqcdSize = 16; + scalarExpounded = true; + break; + default: + throw new Error("Invalid SQcd value " + sqcd); + } + qcd.noQuantization = spqcdSize === 8; + qcd.scalarExpounded = scalarExpounded; + qcd.guardBits = sqcd >> 5; + spqcds = []; + while (j < length + position) { + const spqcd = {}; + if (spqcdSize === 8) { + spqcd.epsilon = data[j++] >> 3; + spqcd.mu = 0; + } else { + spqcd.epsilon = data[j] >> 3; + spqcd.mu = (data[j] & 0x7) << 8 | data[j + 1]; + j += 2; + } + spqcds.push(spqcd); + } + qcd.SPqcds = spqcds; + if (context.mainHeader) { + context.QCD = qcd; + } else { + context.currentTile.QCD = qcd; + context.currentTile.QCC = []; + } + break; + case 0xff5d: + length = (0, _core_utils.readUint16)(data, position); + const qcc = {}; + j = position + 2; + let cqcc; + if (context.SIZ.Csiz < 257) { + cqcc = data[j++]; + } else { + cqcc = (0, _core_utils.readUint16)(data, j); + j += 2; + } + sqcd = data[j++]; + switch (sqcd & 0x1f) { + case 0: + spqcdSize = 8; + scalarExpounded = true; + break; + case 1: + spqcdSize = 16; + scalarExpounded = false; + break; + case 2: + spqcdSize = 16; + scalarExpounded = true; + break; + default: + throw new Error("Invalid SQcd value " + sqcd); + } + qcc.noQuantization = spqcdSize === 8; + qcc.scalarExpounded = scalarExpounded; + qcc.guardBits = sqcd >> 5; + spqcds = []; + while (j < length + position) { + const spqcd = {}; + if (spqcdSize === 8) { + spqcd.epsilon = data[j++] >> 3; + spqcd.mu = 0; + } else { + spqcd.epsilon = data[j] >> 3; + spqcd.mu = (data[j] & 0x7) << 8 | data[j + 1]; + j += 2; + } + spqcds.push(spqcd); + } + qcc.SPqcds = spqcds; + if (context.mainHeader) { + context.QCC[cqcc] = qcc; + } else { + context.currentTile.QCC[cqcc] = qcc; + } + break; + case 0xff52: + length = (0, _core_utils.readUint16)(data, position); + const cod = {}; + j = position + 2; + const scod = data[j++]; + cod.entropyCoderWithCustomPrecincts = !!(scod & 1); + cod.sopMarkerUsed = !!(scod & 2); + cod.ephMarkerUsed = !!(scod & 4); + cod.progressionOrder = data[j++]; + cod.layersCount = (0, _core_utils.readUint16)(data, j); + j += 2; + cod.multipleComponentTransform = data[j++]; + cod.decompositionLevelsCount = data[j++]; + cod.xcb = (data[j++] & 0xf) + 2; + cod.ycb = (data[j++] & 0xf) + 2; + const blockStyle = data[j++]; + cod.selectiveArithmeticCodingBypass = !!(blockStyle & 1); + cod.resetContextProbabilities = !!(blockStyle & 2); + cod.terminationOnEachCodingPass = !!(blockStyle & 4); + cod.verticallyStripe = !!(blockStyle & 8); + cod.predictableTermination = !!(blockStyle & 16); + cod.segmentationSymbolUsed = !!(blockStyle & 32); + cod.reversibleTransformation = data[j++]; + if (cod.entropyCoderWithCustomPrecincts) { + const precinctsSizes = []; + while (j < length + position) { + const precinctsSize = data[j++]; + precinctsSizes.push({ + PPx: precinctsSize & 0xf, + PPy: precinctsSize >> 4 + }); + } + cod.precinctsSizes = precinctsSizes; + } + const unsupported = []; + if (cod.selectiveArithmeticCodingBypass) { + unsupported.push("selectiveArithmeticCodingBypass"); + } + if (cod.terminationOnEachCodingPass) { + unsupported.push("terminationOnEachCodingPass"); + } + if (cod.verticallyStripe) { + unsupported.push("verticallyStripe"); + } + if (cod.predictableTermination) { + unsupported.push("predictableTermination"); + } + if (unsupported.length > 0) { + doNotRecover = true; + (0, _util.warn)(`JPX: Unsupported COD options (${unsupported.join(", ")}).`); + } + if (context.mainHeader) { + context.COD = cod; + } else { + context.currentTile.COD = cod; + context.currentTile.COC = []; + } + break; + case 0xff90: + length = (0, _core_utils.readUint16)(data, position); + tile = {}; + tile.index = (0, _core_utils.readUint16)(data, position + 2); + tile.length = (0, _core_utils.readUint32)(data, position + 4); + tile.dataEnd = tile.length + position - 2; + tile.partIndex = data[position + 8]; + tile.partsCount = data[position + 9]; + context.mainHeader = false; + if (tile.partIndex === 0) { + tile.COD = context.COD; + tile.COC = context.COC.slice(0); + tile.QCD = context.QCD; + tile.QCC = context.QCC.slice(0); + } + context.currentTile = tile; + break; + case 0xff93: + tile = context.currentTile; + if (tile.partIndex === 0) { + initializeTile(context, tile.index); + buildPackets(context); + } + length = tile.dataEnd - position; + parseTilePackets(context, data, position, length); + break; + case 0xff53: + (0, _util.warn)("JPX: Codestream code 0xFF53 (COC) is not implemented."); + case 0xff55: + case 0xff57: + case 0xff58: + case 0xff64: + length = (0, _core_utils.readUint16)(data, position); + break; + default: + throw new Error("Unknown codestream code: " + code.toString(16)); + } + position += length; + } + } catch (e) { + if (doNotRecover || this.failOnCorruptedImage) { + throw new JpxError(e.message); + } else { + (0, _util.warn)(`JPX: Trying to recover from: "${e.message}".`); + } + } + this.tiles = transformComponents(context); + this.width = context.SIZ.Xsiz - context.SIZ.XOsiz; + this.height = context.SIZ.Ysiz - context.SIZ.YOsiz; + this.componentsCount = context.SIZ.Csiz; + } +} +exports.JpxImage = JpxImage; +function calculateComponentDimensions(component, siz) { + component.x0 = Math.ceil(siz.XOsiz / component.XRsiz); + component.x1 = Math.ceil(siz.Xsiz / component.XRsiz); + component.y0 = Math.ceil(siz.YOsiz / component.YRsiz); + component.y1 = Math.ceil(siz.Ysiz / component.YRsiz); + component.width = component.x1 - component.x0; + component.height = component.y1 - component.y0; +} +function calculateTileGrids(context, components) { + const siz = context.SIZ; + const tiles = []; + let tile; + const numXtiles = Math.ceil((siz.Xsiz - siz.XTOsiz) / siz.XTsiz); + const numYtiles = Math.ceil((siz.Ysiz - siz.YTOsiz) / siz.YTsiz); + for (let q = 0; q < numYtiles; q++) { + for (let p = 0; p < numXtiles; p++) { + tile = {}; + tile.tx0 = Math.max(siz.XTOsiz + p * siz.XTsiz, siz.XOsiz); + tile.ty0 = Math.max(siz.YTOsiz + q * siz.YTsiz, siz.YOsiz); + tile.tx1 = Math.min(siz.XTOsiz + (p + 1) * siz.XTsiz, siz.Xsiz); + tile.ty1 = Math.min(siz.YTOsiz + (q + 1) * siz.YTsiz, siz.Ysiz); + tile.width = tile.tx1 - tile.tx0; + tile.height = tile.ty1 - tile.ty0; + tile.components = []; + tiles.push(tile); + } + } + context.tiles = tiles; + const componentsCount = siz.Csiz; + for (let i = 0, ii = componentsCount; i < ii; i++) { + const component = components[i]; + for (let j = 0, jj = tiles.length; j < jj; j++) { + const tileComponent = {}; + tile = tiles[j]; + tileComponent.tcx0 = Math.ceil(tile.tx0 / component.XRsiz); + tileComponent.tcy0 = Math.ceil(tile.ty0 / component.YRsiz); + tileComponent.tcx1 = Math.ceil(tile.tx1 / component.XRsiz); + tileComponent.tcy1 = Math.ceil(tile.ty1 / component.YRsiz); + tileComponent.width = tileComponent.tcx1 - tileComponent.tcx0; + tileComponent.height = tileComponent.tcy1 - tileComponent.tcy0; + tile.components[i] = tileComponent; + } + } +} +function getBlocksDimensions(context, component, r) { + const codOrCoc = component.codingStyleParameters; + const result = {}; + if (!codOrCoc.entropyCoderWithCustomPrecincts) { + result.PPx = 15; + result.PPy = 15; + } else { + result.PPx = codOrCoc.precinctsSizes[r].PPx; + result.PPy = codOrCoc.precinctsSizes[r].PPy; + } + result.xcb_ = r > 0 ? Math.min(codOrCoc.xcb, result.PPx - 1) : Math.min(codOrCoc.xcb, result.PPx); + result.ycb_ = r > 0 ? Math.min(codOrCoc.ycb, result.PPy - 1) : Math.min(codOrCoc.ycb, result.PPy); + return result; +} +function buildPrecincts(context, resolution, dimensions) { + const precinctWidth = 1 << dimensions.PPx; + const precinctHeight = 1 << dimensions.PPy; + const isZeroRes = resolution.resLevel === 0; + const precinctWidthInSubband = 1 << dimensions.PPx + (isZeroRes ? 0 : -1); + const precinctHeightInSubband = 1 << dimensions.PPy + (isZeroRes ? 0 : -1); + const numprecinctswide = resolution.trx1 > resolution.trx0 ? Math.ceil(resolution.trx1 / precinctWidth) - Math.floor(resolution.trx0 / precinctWidth) : 0; + const numprecinctshigh = resolution.try1 > resolution.try0 ? Math.ceil(resolution.try1 / precinctHeight) - Math.floor(resolution.try0 / precinctHeight) : 0; + const numprecincts = numprecinctswide * numprecinctshigh; + resolution.precinctParameters = { + precinctWidth, + precinctHeight, + numprecinctswide, + numprecinctshigh, + numprecincts, + precinctWidthInSubband, + precinctHeightInSubband + }; +} +function buildCodeblocks(context, subband, dimensions) { + const xcb_ = dimensions.xcb_; + const ycb_ = dimensions.ycb_; + const codeblockWidth = 1 << xcb_; + const codeblockHeight = 1 << ycb_; + const cbx0 = subband.tbx0 >> xcb_; + const cby0 = subband.tby0 >> ycb_; + const cbx1 = subband.tbx1 + codeblockWidth - 1 >> xcb_; + const cby1 = subband.tby1 + codeblockHeight - 1 >> ycb_; + const precinctParameters = subband.resolution.precinctParameters; + const codeblocks = []; + const precincts = []; + let i, j, codeblock, precinctNumber; + for (j = cby0; j < cby1; j++) { + for (i = cbx0; i < cbx1; i++) { + codeblock = { + cbx: i, + cby: j, + tbx0: codeblockWidth * i, + tby0: codeblockHeight * j, + tbx1: codeblockWidth * (i + 1), + tby1: codeblockHeight * (j + 1) + }; + codeblock.tbx0_ = Math.max(subband.tbx0, codeblock.tbx0); + codeblock.tby0_ = Math.max(subband.tby0, codeblock.tby0); + codeblock.tbx1_ = Math.min(subband.tbx1, codeblock.tbx1); + codeblock.tby1_ = Math.min(subband.tby1, codeblock.tby1); + const pi = Math.floor((codeblock.tbx0_ - subband.tbx0) / precinctParameters.precinctWidthInSubband); + const pj = Math.floor((codeblock.tby0_ - subband.tby0) / precinctParameters.precinctHeightInSubband); + precinctNumber = pi + pj * precinctParameters.numprecinctswide; + codeblock.precinctNumber = precinctNumber; + codeblock.subbandType = subband.type; + codeblock.Lblock = 3; + if (codeblock.tbx1_ <= codeblock.tbx0_ || codeblock.tby1_ <= codeblock.tby0_) { + continue; + } + codeblocks.push(codeblock); + let precinct = precincts[precinctNumber]; + if (precinct !== undefined) { + if (i < precinct.cbxMin) { + precinct.cbxMin = i; + } else if (i > precinct.cbxMax) { + precinct.cbxMax = i; + } + if (j < precinct.cbyMin) { + precinct.cbxMin = j; + } else if (j > precinct.cbyMax) { + precinct.cbyMax = j; + } + } else { + precincts[precinctNumber] = precinct = { + cbxMin: i, + cbyMin: j, + cbxMax: i, + cbyMax: j + }; + } + codeblock.precinct = precinct; + } + } + subband.codeblockParameters = { + codeblockWidth: xcb_, + codeblockHeight: ycb_, + numcodeblockwide: cbx1 - cbx0 + 1, + numcodeblockhigh: cby1 - cby0 + 1 + }; + subband.codeblocks = codeblocks; + subband.precincts = precincts; +} +function createPacket(resolution, precinctNumber, layerNumber) { + const precinctCodeblocks = []; + const subbands = resolution.subbands; + for (let i = 0, ii = subbands.length; i < ii; i++) { + const subband = subbands[i]; + const codeblocks = subband.codeblocks; + for (let j = 0, jj = codeblocks.length; j < jj; j++) { + const codeblock = codeblocks[j]; + if (codeblock.precinctNumber !== precinctNumber) { + continue; + } + precinctCodeblocks.push(codeblock); + } + } + return { + layerNumber, + codeblocks: precinctCodeblocks + }; +} +function LayerResolutionComponentPositionIterator(context) { + const siz = context.SIZ; + const tileIndex = context.currentTile.index; + const tile = context.tiles[tileIndex]; + const layersCount = tile.codingStyleDefaultParameters.layersCount; + const componentsCount = siz.Csiz; + let maxDecompositionLevelsCount = 0; + for (let q = 0; q < componentsCount; q++) { + maxDecompositionLevelsCount = Math.max(maxDecompositionLevelsCount, tile.components[q].codingStyleParameters.decompositionLevelsCount); + } + let l = 0, + r = 0, + i = 0, + k = 0; + this.nextPacket = function JpxImage_nextPacket() { + for (; l < layersCount; l++) { + for (; r <= maxDecompositionLevelsCount; r++) { + for (; i < componentsCount; i++) { + const component = tile.components[i]; + if (r > component.codingStyleParameters.decompositionLevelsCount) { + continue; + } + const resolution = component.resolutions[r]; + const numprecincts = resolution.precinctParameters.numprecincts; + for (; k < numprecincts;) { + const packet = createPacket(resolution, k, l); + k++; + return packet; + } + k = 0; + } + i = 0; + } + r = 0; + } + throw new JpxError("Out of packets"); + }; +} +function ResolutionLayerComponentPositionIterator(context) { + const siz = context.SIZ; + const tileIndex = context.currentTile.index; + const tile = context.tiles[tileIndex]; + const layersCount = tile.codingStyleDefaultParameters.layersCount; + const componentsCount = siz.Csiz; + let maxDecompositionLevelsCount = 0; + for (let q = 0; q < componentsCount; q++) { + maxDecompositionLevelsCount = Math.max(maxDecompositionLevelsCount, tile.components[q].codingStyleParameters.decompositionLevelsCount); + } + let r = 0, + l = 0, + i = 0, + k = 0; + this.nextPacket = function JpxImage_nextPacket() { + for (; r <= maxDecompositionLevelsCount; r++) { + for (; l < layersCount; l++) { + for (; i < componentsCount; i++) { + const component = tile.components[i]; + if (r > component.codingStyleParameters.decompositionLevelsCount) { + continue; + } + const resolution = component.resolutions[r]; + const numprecincts = resolution.precinctParameters.numprecincts; + for (; k < numprecincts;) { + const packet = createPacket(resolution, k, l); + k++; + return packet; + } + k = 0; + } + i = 0; + } + l = 0; + } + throw new JpxError("Out of packets"); + }; +} +function ResolutionPositionComponentLayerIterator(context) { + const siz = context.SIZ; + const tileIndex = context.currentTile.index; + const tile = context.tiles[tileIndex]; + const layersCount = tile.codingStyleDefaultParameters.layersCount; + const componentsCount = siz.Csiz; + let l, r, c, p; + let maxDecompositionLevelsCount = 0; + for (c = 0; c < componentsCount; c++) { + const component = tile.components[c]; + maxDecompositionLevelsCount = Math.max(maxDecompositionLevelsCount, component.codingStyleParameters.decompositionLevelsCount); + } + const maxNumPrecinctsInLevel = new Int32Array(maxDecompositionLevelsCount + 1); + for (r = 0; r <= maxDecompositionLevelsCount; ++r) { + let maxNumPrecincts = 0; + for (c = 0; c < componentsCount; ++c) { + const resolutions = tile.components[c].resolutions; + if (r < resolutions.length) { + maxNumPrecincts = Math.max(maxNumPrecincts, resolutions[r].precinctParameters.numprecincts); + } + } + maxNumPrecinctsInLevel[r] = maxNumPrecincts; + } + l = 0; + r = 0; + c = 0; + p = 0; + this.nextPacket = function JpxImage_nextPacket() { + for (; r <= maxDecompositionLevelsCount; r++) { + for (; p < maxNumPrecinctsInLevel[r]; p++) { + for (; c < componentsCount; c++) { + const component = tile.components[c]; + if (r > component.codingStyleParameters.decompositionLevelsCount) { + continue; + } + const resolution = component.resolutions[r]; + const numprecincts = resolution.precinctParameters.numprecincts; + if (p >= numprecincts) { + continue; + } + for (; l < layersCount;) { + const packet = createPacket(resolution, p, l); + l++; + return packet; + } + l = 0; + } + c = 0; + } + p = 0; + } + throw new JpxError("Out of packets"); + }; +} +function PositionComponentResolutionLayerIterator(context) { + const siz = context.SIZ; + const tileIndex = context.currentTile.index; + const tile = context.tiles[tileIndex]; + const layersCount = tile.codingStyleDefaultParameters.layersCount; + const componentsCount = siz.Csiz; + const precinctsSizes = getPrecinctSizesInImageScale(tile); + const precinctsIterationSizes = precinctsSizes; + let l = 0, + r = 0, + c = 0, + px = 0, + py = 0; + this.nextPacket = function JpxImage_nextPacket() { + for (; py < precinctsIterationSizes.maxNumHigh; py++) { + for (; px < precinctsIterationSizes.maxNumWide; px++) { + for (; c < componentsCount; c++) { + const component = tile.components[c]; + const decompositionLevelsCount = component.codingStyleParameters.decompositionLevelsCount; + for (; r <= decompositionLevelsCount; r++) { + const resolution = component.resolutions[r]; + const sizeInImageScale = precinctsSizes.components[c].resolutions[r]; + const k = getPrecinctIndexIfExist(px, py, sizeInImageScale, precinctsIterationSizes, resolution); + if (k === null) { + continue; + } + for (; l < layersCount;) { + const packet = createPacket(resolution, k, l); + l++; + return packet; + } + l = 0; + } + r = 0; + } + c = 0; + } + px = 0; + } + throw new JpxError("Out of packets"); + }; +} +function ComponentPositionResolutionLayerIterator(context) { + const siz = context.SIZ; + const tileIndex = context.currentTile.index; + const tile = context.tiles[tileIndex]; + const layersCount = tile.codingStyleDefaultParameters.layersCount; + const componentsCount = siz.Csiz; + const precinctsSizes = getPrecinctSizesInImageScale(tile); + let l = 0, + r = 0, + c = 0, + px = 0, + py = 0; + this.nextPacket = function JpxImage_nextPacket() { + for (; c < componentsCount; ++c) { + const component = tile.components[c]; + const precinctsIterationSizes = precinctsSizes.components[c]; + const decompositionLevelsCount = component.codingStyleParameters.decompositionLevelsCount; + for (; py < precinctsIterationSizes.maxNumHigh; py++) { + for (; px < precinctsIterationSizes.maxNumWide; px++) { + for (; r <= decompositionLevelsCount; r++) { + const resolution = component.resolutions[r]; + const sizeInImageScale = precinctsIterationSizes.resolutions[r]; + const k = getPrecinctIndexIfExist(px, py, sizeInImageScale, precinctsIterationSizes, resolution); + if (k === null) { + continue; + } + for (; l < layersCount;) { + const packet = createPacket(resolution, k, l); + l++; + return packet; + } + l = 0; + } + r = 0; + } + px = 0; + } + py = 0; + } + throw new JpxError("Out of packets"); + }; +} +function getPrecinctIndexIfExist(pxIndex, pyIndex, sizeInImageScale, precinctIterationSizes, resolution) { + const posX = pxIndex * precinctIterationSizes.minWidth; + const posY = pyIndex * precinctIterationSizes.minHeight; + if (posX % sizeInImageScale.width !== 0 || posY % sizeInImageScale.height !== 0) { + return null; + } + const startPrecinctRowIndex = posY / sizeInImageScale.width * resolution.precinctParameters.numprecinctswide; + return posX / sizeInImageScale.height + startPrecinctRowIndex; +} +function getPrecinctSizesInImageScale(tile) { + const componentsCount = tile.components.length; + let minWidth = Number.MAX_VALUE; + let minHeight = Number.MAX_VALUE; + let maxNumWide = 0; + let maxNumHigh = 0; + const sizePerComponent = new Array(componentsCount); + for (let c = 0; c < componentsCount; c++) { + const component = tile.components[c]; + const decompositionLevelsCount = component.codingStyleParameters.decompositionLevelsCount; + const sizePerResolution = new Array(decompositionLevelsCount + 1); + let minWidthCurrentComponent = Number.MAX_VALUE; + let minHeightCurrentComponent = Number.MAX_VALUE; + let maxNumWideCurrentComponent = 0; + let maxNumHighCurrentComponent = 0; + let scale = 1; + for (let r = decompositionLevelsCount; r >= 0; --r) { + const resolution = component.resolutions[r]; + const widthCurrentResolution = scale * resolution.precinctParameters.precinctWidth; + const heightCurrentResolution = scale * resolution.precinctParameters.precinctHeight; + minWidthCurrentComponent = Math.min(minWidthCurrentComponent, widthCurrentResolution); + minHeightCurrentComponent = Math.min(minHeightCurrentComponent, heightCurrentResolution); + maxNumWideCurrentComponent = Math.max(maxNumWideCurrentComponent, resolution.precinctParameters.numprecinctswide); + maxNumHighCurrentComponent = Math.max(maxNumHighCurrentComponent, resolution.precinctParameters.numprecinctshigh); + sizePerResolution[r] = { + width: widthCurrentResolution, + height: heightCurrentResolution + }; + scale <<= 1; + } + minWidth = Math.min(minWidth, minWidthCurrentComponent); + minHeight = Math.min(minHeight, minHeightCurrentComponent); + maxNumWide = Math.max(maxNumWide, maxNumWideCurrentComponent); + maxNumHigh = Math.max(maxNumHigh, maxNumHighCurrentComponent); + sizePerComponent[c] = { + resolutions: sizePerResolution, + minWidth: minWidthCurrentComponent, + minHeight: minHeightCurrentComponent, + maxNumWide: maxNumWideCurrentComponent, + maxNumHigh: maxNumHighCurrentComponent + }; + } + return { + components: sizePerComponent, + minWidth, + minHeight, + maxNumWide, + maxNumHigh + }; +} +function buildPackets(context) { + const siz = context.SIZ; + const tileIndex = context.currentTile.index; + const tile = context.tiles[tileIndex]; + const componentsCount = siz.Csiz; + for (let c = 0; c < componentsCount; c++) { + const component = tile.components[c]; + const decompositionLevelsCount = component.codingStyleParameters.decompositionLevelsCount; + const resolutions = []; + const subbands = []; + for (let r = 0; r <= decompositionLevelsCount; r++) { + const blocksDimensions = getBlocksDimensions(context, component, r); + const resolution = {}; + const scale = 1 << decompositionLevelsCount - r; + resolution.trx0 = Math.ceil(component.tcx0 / scale); + resolution.try0 = Math.ceil(component.tcy0 / scale); + resolution.trx1 = Math.ceil(component.tcx1 / scale); + resolution.try1 = Math.ceil(component.tcy1 / scale); + resolution.resLevel = r; + buildPrecincts(context, resolution, blocksDimensions); + resolutions.push(resolution); + let subband; + if (r === 0) { + subband = {}; + subband.type = "LL"; + subband.tbx0 = Math.ceil(component.tcx0 / scale); + subband.tby0 = Math.ceil(component.tcy0 / scale); + subband.tbx1 = Math.ceil(component.tcx1 / scale); + subband.tby1 = Math.ceil(component.tcy1 / scale); + subband.resolution = resolution; + buildCodeblocks(context, subband, blocksDimensions); + subbands.push(subband); + resolution.subbands = [subband]; + } else { + const bscale = 1 << decompositionLevelsCount - r + 1; + const resolutionSubbands = []; + subband = {}; + subband.type = "HL"; + subband.tbx0 = Math.ceil(component.tcx0 / bscale - 0.5); + subband.tby0 = Math.ceil(component.tcy0 / bscale); + subband.tbx1 = Math.ceil(component.tcx1 / bscale - 0.5); + subband.tby1 = Math.ceil(component.tcy1 / bscale); + subband.resolution = resolution; + buildCodeblocks(context, subband, blocksDimensions); + subbands.push(subband); + resolutionSubbands.push(subband); + subband = {}; + subband.type = "LH"; + subband.tbx0 = Math.ceil(component.tcx0 / bscale); + subband.tby0 = Math.ceil(component.tcy0 / bscale - 0.5); + subband.tbx1 = Math.ceil(component.tcx1 / bscale); + subband.tby1 = Math.ceil(component.tcy1 / bscale - 0.5); + subband.resolution = resolution; + buildCodeblocks(context, subband, blocksDimensions); + subbands.push(subband); + resolutionSubbands.push(subband); + subband = {}; + subband.type = "HH"; + subband.tbx0 = Math.ceil(component.tcx0 / bscale - 0.5); + subband.tby0 = Math.ceil(component.tcy0 / bscale - 0.5); + subband.tbx1 = Math.ceil(component.tcx1 / bscale - 0.5); + subband.tby1 = Math.ceil(component.tcy1 / bscale - 0.5); + subband.resolution = resolution; + buildCodeblocks(context, subband, blocksDimensions); + subbands.push(subband); + resolutionSubbands.push(subband); + resolution.subbands = resolutionSubbands; + } + } + component.resolutions = resolutions; + component.subbands = subbands; + } + const progressionOrder = tile.codingStyleDefaultParameters.progressionOrder; + switch (progressionOrder) { + case 0: + tile.packetsIterator = new LayerResolutionComponentPositionIterator(context); + break; + case 1: + tile.packetsIterator = new ResolutionLayerComponentPositionIterator(context); + break; + case 2: + tile.packetsIterator = new ResolutionPositionComponentLayerIterator(context); + break; + case 3: + tile.packetsIterator = new PositionComponentResolutionLayerIterator(context); + break; + case 4: + tile.packetsIterator = new ComponentPositionResolutionLayerIterator(context); + break; + default: + throw new JpxError(`Unsupported progression order ${progressionOrder}`); + } +} +function parseTilePackets(context, data, offset, dataLength) { + let position = 0; + let buffer, + bufferSize = 0, + skipNextBit = false; + function readBits(count) { + while (bufferSize < count) { + const b = data[offset + position]; + position++; + if (skipNextBit) { + buffer = buffer << 7 | b; + bufferSize += 7; + skipNextBit = false; + } else { + buffer = buffer << 8 | b; + bufferSize += 8; + } + if (b === 0xff) { + skipNextBit = true; + } + } + bufferSize -= count; + return buffer >>> bufferSize & (1 << count) - 1; + } + function skipMarkerIfEqual(value) { + if (data[offset + position - 1] === 0xff && data[offset + position] === value) { + skipBytes(1); + return true; + } else if (data[offset + position] === 0xff && data[offset + position + 1] === value) { + skipBytes(2); + return true; + } + return false; + } + function skipBytes(count) { + position += count; + } + function alignToByte() { + bufferSize = 0; + if (skipNextBit) { + position++; + skipNextBit = false; + } + } + function readCodingpasses() { + if (readBits(1) === 0) { + return 1; + } + if (readBits(1) === 0) { + return 2; + } + let value = readBits(2); + if (value < 3) { + return value + 3; + } + value = readBits(5); + if (value < 31) { + return value + 6; + } + value = readBits(7); + return value + 37; + } + const tileIndex = context.currentTile.index; + const tile = context.tiles[tileIndex]; + const sopMarkerUsed = context.COD.sopMarkerUsed; + const ephMarkerUsed = context.COD.ephMarkerUsed; + const packetsIterator = tile.packetsIterator; + while (position < dataLength) { + alignToByte(); + if (sopMarkerUsed && skipMarkerIfEqual(0x91)) { + skipBytes(4); + } + const packet = packetsIterator.nextPacket(); + if (!readBits(1)) { + continue; + } + const layerNumber = packet.layerNumber, + queue = []; + let codeblock; + for (let i = 0, ii = packet.codeblocks.length; i < ii; i++) { + codeblock = packet.codeblocks[i]; + let precinct = codeblock.precinct; + const codeblockColumn = codeblock.cbx - precinct.cbxMin; + const codeblockRow = codeblock.cby - precinct.cbyMin; + let codeblockIncluded = false; + let firstTimeInclusion = false; + let valueReady, zeroBitPlanesTree; + if (codeblock.included !== undefined) { + codeblockIncluded = !!readBits(1); + } else { + precinct = codeblock.precinct; + let inclusionTree; + if (precinct.inclusionTree !== undefined) { + inclusionTree = precinct.inclusionTree; + } else { + const width = precinct.cbxMax - precinct.cbxMin + 1; + const height = precinct.cbyMax - precinct.cbyMin + 1; + inclusionTree = new InclusionTree(width, height, layerNumber); + zeroBitPlanesTree = new TagTree(width, height); + precinct.inclusionTree = inclusionTree; + precinct.zeroBitPlanesTree = zeroBitPlanesTree; + for (let l = 0; l < layerNumber; l++) { + if (readBits(1) !== 0) { + throw new JpxError("Invalid tag tree"); + } + } + } + if (inclusionTree.reset(codeblockColumn, codeblockRow, layerNumber)) { + while (true) { + if (readBits(1)) { + valueReady = !inclusionTree.nextLevel(); + if (valueReady) { + codeblock.included = true; + codeblockIncluded = firstTimeInclusion = true; + break; + } + } else { + inclusionTree.incrementValue(layerNumber); + break; + } + } + } + } + if (!codeblockIncluded) { + continue; + } + if (firstTimeInclusion) { + zeroBitPlanesTree = precinct.zeroBitPlanesTree; + zeroBitPlanesTree.reset(codeblockColumn, codeblockRow); + while (true) { + if (readBits(1)) { + valueReady = !zeroBitPlanesTree.nextLevel(); + if (valueReady) { + break; + } + } else { + zeroBitPlanesTree.incrementValue(); + } + } + codeblock.zeroBitPlanes = zeroBitPlanesTree.value; + } + const codingpasses = readCodingpasses(); + while (readBits(1)) { + codeblock.Lblock++; + } + const codingpassesLog2 = (0, _core_utils.log2)(codingpasses); + const bits = (codingpasses < 1 << codingpassesLog2 ? codingpassesLog2 - 1 : codingpassesLog2) + codeblock.Lblock; + const codedDataLength = readBits(bits); + queue.push({ + codeblock, + codingpasses, + dataLength: codedDataLength + }); + } + alignToByte(); + if (ephMarkerUsed) { + skipMarkerIfEqual(0x92); + } + while (queue.length > 0) { + const packetItem = queue.shift(); + codeblock = packetItem.codeblock; + if (codeblock.data === undefined) { + codeblock.data = []; + } + codeblock.data.push({ + data, + start: offset + position, + end: offset + position + packetItem.dataLength, + codingpasses: packetItem.codingpasses + }); + position += packetItem.dataLength; + } + } + return position; +} +function copyCoefficients(coefficients, levelWidth, levelHeight, subband, delta, mb, reversible, segmentationSymbolUsed, resetContextProbabilities) { + const x0 = subband.tbx0; + const y0 = subband.tby0; + const width = subband.tbx1 - subband.tbx0; + const codeblocks = subband.codeblocks; + const right = subband.type.charAt(0) === "H" ? 1 : 0; + const bottom = subband.type.charAt(1) === "H" ? levelWidth : 0; + for (let i = 0, ii = codeblocks.length; i < ii; ++i) { + const codeblock = codeblocks[i]; + const blockWidth = codeblock.tbx1_ - codeblock.tbx0_; + const blockHeight = codeblock.tby1_ - codeblock.tby0_; + if (blockWidth === 0 || blockHeight === 0) { + continue; + } + if (codeblock.data === undefined) { + continue; + } + const bitModel = new BitModel(blockWidth, blockHeight, codeblock.subbandType, codeblock.zeroBitPlanes, mb); + let currentCodingpassType = 2; + const data = codeblock.data; + let totalLength = 0, + codingpasses = 0; + let j, jj, dataItem; + for (j = 0, jj = data.length; j < jj; j++) { + dataItem = data[j]; + totalLength += dataItem.end - dataItem.start; + codingpasses += dataItem.codingpasses; + } + const encodedData = new Uint8Array(totalLength); + let position = 0; + for (j = 0, jj = data.length; j < jj; j++) { + dataItem = data[j]; + const chunk = dataItem.data.subarray(dataItem.start, dataItem.end); + encodedData.set(chunk, position); + position += chunk.length; + } + const decoder = new _arithmetic_decoder.ArithmeticDecoder(encodedData, 0, totalLength); + bitModel.setDecoder(decoder); + for (j = 0; j < codingpasses; j++) { + switch (currentCodingpassType) { + case 0: + bitModel.runSignificancePropagationPass(); + break; + case 1: + bitModel.runMagnitudeRefinementPass(); + break; + case 2: + bitModel.runCleanupPass(); + if (segmentationSymbolUsed) { + bitModel.checkSegmentationSymbol(); + } + break; + } + if (resetContextProbabilities) { + bitModel.reset(); + } + currentCodingpassType = (currentCodingpassType + 1) % 3; + } + let offset = codeblock.tbx0_ - x0 + (codeblock.tby0_ - y0) * width; + const sign = bitModel.coefficentsSign; + const magnitude = bitModel.coefficentsMagnitude; + const bitsDecoded = bitModel.bitsDecoded; + const magnitudeCorrection = reversible ? 0 : 0.5; + let k, n, nb; + position = 0; + const interleave = subband.type !== "LL"; + for (j = 0; j < blockHeight; j++) { + const row = offset / width | 0; + const levelOffset = 2 * row * (levelWidth - width) + right + bottom; + for (k = 0; k < blockWidth; k++) { + n = magnitude[position]; + if (n !== 0) { + n = (n + magnitudeCorrection) * delta; + if (sign[position] !== 0) { + n = -n; + } + nb = bitsDecoded[position]; + const pos = interleave ? levelOffset + (offset << 1) : offset; + coefficients[pos] = reversible && nb >= mb ? n : n * (1 << mb - nb); + } + offset++; + position++; + } + offset += width - blockWidth; + } + } +} +function transformTile(context, tile, c) { + const component = tile.components[c]; + const codingStyleParameters = component.codingStyleParameters; + const quantizationParameters = component.quantizationParameters; + const decompositionLevelsCount = codingStyleParameters.decompositionLevelsCount; + const spqcds = quantizationParameters.SPqcds; + const scalarExpounded = quantizationParameters.scalarExpounded; + const guardBits = quantizationParameters.guardBits; + const segmentationSymbolUsed = codingStyleParameters.segmentationSymbolUsed; + const resetContextProbabilities = codingStyleParameters.resetContextProbabilities; + const precision = context.components[c].precision; + const reversible = codingStyleParameters.reversibleTransformation; + const transform = reversible ? new ReversibleTransform() : new IrreversibleTransform(); + const subbandCoefficients = []; + let b = 0; + for (let i = 0; i <= decompositionLevelsCount; i++) { + const resolution = component.resolutions[i]; + const width = resolution.trx1 - resolution.trx0; + const height = resolution.try1 - resolution.try0; + const coefficients = new Float32Array(width * height); + for (let j = 0, jj = resolution.subbands.length; j < jj; j++) { + let mu, epsilon; + if (!scalarExpounded) { + mu = spqcds[0].mu; + epsilon = spqcds[0].epsilon + (i > 0 ? 1 - i : 0); + } else { + mu = spqcds[b].mu; + epsilon = spqcds[b].epsilon; + b++; + } + const subband = resolution.subbands[j]; + const gainLog2 = SubbandsGainLog2[subband.type]; + const delta = reversible ? 1 : 2 ** (precision + gainLog2 - epsilon) * (1 + mu / 2048); + const mb = guardBits + epsilon - 1; + copyCoefficients(coefficients, width, height, subband, delta, mb, reversible, segmentationSymbolUsed, resetContextProbabilities); + } + subbandCoefficients.push({ + width, + height, + items: coefficients + }); + } + const result = transform.calculate(subbandCoefficients, component.tcx0, component.tcy0); + return { + left: component.tcx0, + top: component.tcy0, + width: result.width, + height: result.height, + items: result.items + }; +} +function transformComponents(context) { + const siz = context.SIZ; + const components = context.components; + const componentsCount = siz.Csiz; + const resultImages = []; + for (let i = 0, ii = context.tiles.length; i < ii; i++) { + const tile = context.tiles[i]; + const transformedTiles = []; + for (let c = 0; c < componentsCount; c++) { + transformedTiles[c] = transformTile(context, tile, c); + } + const tile0 = transformedTiles[0]; + const out = new Uint8ClampedArray(tile0.items.length * componentsCount); + const result = { + left: tile0.left, + top: tile0.top, + width: tile0.width, + height: tile0.height, + items: out + }; + let shift, offset; + let pos = 0, + j, + jj, + y0, + y1, + y2; + if (tile.codingStyleDefaultParameters.multipleComponentTransform) { + const fourComponents = componentsCount === 4; + const y0items = transformedTiles[0].items; + const y1items = transformedTiles[1].items; + const y2items = transformedTiles[2].items; + const y3items = fourComponents ? transformedTiles[3].items : null; + shift = components[0].precision - 8; + offset = (128 << shift) + 0.5; + const component0 = tile.components[0]; + const alpha01 = componentsCount - 3; + jj = y0items.length; + if (!component0.codingStyleParameters.reversibleTransformation) { + for (j = 0; j < jj; j++, pos += alpha01) { + y0 = y0items[j] + offset; + y1 = y1items[j]; + y2 = y2items[j]; + out[pos++] = y0 + 1.402 * y2 >> shift; + out[pos++] = y0 - 0.34413 * y1 - 0.71414 * y2 >> shift; + out[pos++] = y0 + 1.772 * y1 >> shift; + } + } else { + for (j = 0; j < jj; j++, pos += alpha01) { + y0 = y0items[j] + offset; + y1 = y1items[j]; + y2 = y2items[j]; + const g = y0 - (y2 + y1 >> 2); + out[pos++] = g + y2 >> shift; + out[pos++] = g >> shift; + out[pos++] = g + y1 >> shift; + } + } + if (fourComponents) { + for (j = 0, pos = 3; j < jj; j++, pos += 4) { + out[pos] = y3items[j] + offset >> shift; + } + } + } else { + for (let c = 0; c < componentsCount; c++) { + const items = transformedTiles[c].items; + shift = components[c].precision - 8; + offset = (128 << shift) + 0.5; + for (pos = c, j = 0, jj = items.length; j < jj; j++) { + out[pos] = items[j] + offset >> shift; + pos += componentsCount; + } + } + } + resultImages.push(result); + } + return resultImages; +} +function initializeTile(context, tileIndex) { + const siz = context.SIZ; + const componentsCount = siz.Csiz; + const tile = context.tiles[tileIndex]; + for (let c = 0; c < componentsCount; c++) { + const component = tile.components[c]; + const qcdOrQcc = context.currentTile.QCC[c] !== undefined ? context.currentTile.QCC[c] : context.currentTile.QCD; + component.quantizationParameters = qcdOrQcc; + const codOrCoc = context.currentTile.COC[c] !== undefined ? context.currentTile.COC[c] : context.currentTile.COD; + component.codingStyleParameters = codOrCoc; + } + tile.codingStyleDefaultParameters = context.currentTile.COD; +} +class TagTree { + constructor(width, height) { + const levelsLength = (0, _core_utils.log2)(Math.max(width, height)) + 1; + this.levels = []; + for (let i = 0; i < levelsLength; i++) { + const level = { + width, + height, + items: [] + }; + this.levels.push(level); + width = Math.ceil(width / 2); + height = Math.ceil(height / 2); + } + } + reset(i, j) { + let currentLevel = 0, + value = 0, + level; + while (currentLevel < this.levels.length) { + level = this.levels[currentLevel]; + const index = i + j * level.width; + if (level.items[index] !== undefined) { + value = level.items[index]; + break; + } + level.index = index; + i >>= 1; + j >>= 1; + currentLevel++; + } + currentLevel--; + level = this.levels[currentLevel]; + level.items[level.index] = value; + this.currentLevel = currentLevel; + delete this.value; + } + incrementValue() { + const level = this.levels[this.currentLevel]; + level.items[level.index]++; + } + nextLevel() { + let currentLevel = this.currentLevel; + let level = this.levels[currentLevel]; + const value = level.items[level.index]; + currentLevel--; + if (currentLevel < 0) { + this.value = value; + return false; + } + this.currentLevel = currentLevel; + level = this.levels[currentLevel]; + level.items[level.index] = value; + return true; + } +} +class InclusionTree { + constructor(width, height, defaultValue) { + const levelsLength = (0, _core_utils.log2)(Math.max(width, height)) + 1; + this.levels = []; + for (let i = 0; i < levelsLength; i++) { + const items = new Uint8Array(width * height); + for (let j = 0, jj = items.length; j < jj; j++) { + items[j] = defaultValue; + } + const level = { + width, + height, + items + }; + this.levels.push(level); + width = Math.ceil(width / 2); + height = Math.ceil(height / 2); + } + } + reset(i, j, stopValue) { + let currentLevel = 0; + while (currentLevel < this.levels.length) { + const level = this.levels[currentLevel]; + const index = i + j * level.width; + level.index = index; + const value = level.items[index]; + if (value === 0xff) { + break; + } + if (value > stopValue) { + this.currentLevel = currentLevel; + this.propagateValues(); + return false; + } + i >>= 1; + j >>= 1; + currentLevel++; + } + this.currentLevel = currentLevel - 1; + return true; + } + incrementValue(stopValue) { + const level = this.levels[this.currentLevel]; + level.items[level.index] = stopValue + 1; + this.propagateValues(); + } + propagateValues() { + let levelIndex = this.currentLevel; + let level = this.levels[levelIndex]; + const currentValue = level.items[level.index]; + while (--levelIndex >= 0) { + level = this.levels[levelIndex]; + level.items[level.index] = currentValue; + } + } + nextLevel() { + let currentLevel = this.currentLevel; + let level = this.levels[currentLevel]; + const value = level.items[level.index]; + level.items[level.index] = 0xff; + currentLevel--; + if (currentLevel < 0) { + return false; + } + this.currentLevel = currentLevel; + level = this.levels[currentLevel]; + level.items[level.index] = value; + return true; + } +} +class BitModel { + static UNIFORM_CONTEXT = 17; + static RUNLENGTH_CONTEXT = 18; + static LLAndLHContextsLabel = new Uint8Array([0, 5, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 1, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8]); + static HLContextLabel = new Uint8Array([0, 3, 4, 0, 5, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 1, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8]); + static HHContextLabel = new Uint8Array([0, 1, 2, 0, 1, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 3, 4, 5, 0, 4, 5, 5, 0, 5, 5, 5, 0, 0, 0, 0, 0, 6, 7, 7, 0, 7, 7, 7, 0, 7, 7, 7, 0, 0, 0, 0, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 0, 0, 0, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8]); + constructor(width, height, subband, zeroBitPlanes, mb) { + this.width = width; + this.height = height; + let contextLabelTable; + if (subband === "HH") { + contextLabelTable = BitModel.HHContextLabel; + } else if (subband === "HL") { + contextLabelTable = BitModel.HLContextLabel; + } else { + contextLabelTable = BitModel.LLAndLHContextsLabel; + } + this.contextLabelTable = contextLabelTable; + const coefficientCount = width * height; + this.neighborsSignificance = new Uint8Array(coefficientCount); + this.coefficentsSign = new Uint8Array(coefficientCount); + let coefficentsMagnitude; + if (mb > 14) { + coefficentsMagnitude = new Uint32Array(coefficientCount); + } else if (mb > 6) { + coefficentsMagnitude = new Uint16Array(coefficientCount); + } else { + coefficentsMagnitude = new Uint8Array(coefficientCount); + } + this.coefficentsMagnitude = coefficentsMagnitude; + this.processingFlags = new Uint8Array(coefficientCount); + const bitsDecoded = new Uint8Array(coefficientCount); + if (zeroBitPlanes !== 0) { + for (let i = 0; i < coefficientCount; i++) { + bitsDecoded[i] = zeroBitPlanes; + } + } + this.bitsDecoded = bitsDecoded; + this.reset(); + } + setDecoder(decoder) { + this.decoder = decoder; + } + reset() { + this.contexts = new Int8Array(19); + this.contexts[0] = 4 << 1 | 0; + this.contexts[BitModel.UNIFORM_CONTEXT] = 46 << 1 | 0; + this.contexts[BitModel.RUNLENGTH_CONTEXT] = 3 << 1 | 0; + } + setNeighborsSignificance(row, column, index) { + const neighborsSignificance = this.neighborsSignificance; + const width = this.width, + height = this.height; + const left = column > 0; + const right = column + 1 < width; + let i; + if (row > 0) { + i = index - width; + if (left) { + neighborsSignificance[i - 1] += 0x10; + } + if (right) { + neighborsSignificance[i + 1] += 0x10; + } + neighborsSignificance[i] += 0x04; + } + if (row + 1 < height) { + i = index + width; + if (left) { + neighborsSignificance[i - 1] += 0x10; + } + if (right) { + neighborsSignificance[i + 1] += 0x10; + } + neighborsSignificance[i] += 0x04; + } + if (left) { + neighborsSignificance[index - 1] += 0x01; + } + if (right) { + neighborsSignificance[index + 1] += 0x01; + } + neighborsSignificance[index] |= 0x80; + } + runSignificancePropagationPass() { + const decoder = this.decoder; + const width = this.width, + height = this.height; + const coefficentsMagnitude = this.coefficentsMagnitude; + const coefficentsSign = this.coefficentsSign; + const neighborsSignificance = this.neighborsSignificance; + const processingFlags = this.processingFlags; + const contexts = this.contexts; + const labels = this.contextLabelTable; + const bitsDecoded = this.bitsDecoded; + const processedInverseMask = ~1; + const processedMask = 1; + const firstMagnitudeBitMask = 2; + for (let i0 = 0; i0 < height; i0 += 4) { + for (let j = 0; j < width; j++) { + let index = i0 * width + j; + for (let i1 = 0; i1 < 4; i1++, index += width) { + const i = i0 + i1; + if (i >= height) { + break; + } + processingFlags[index] &= processedInverseMask; + if (coefficentsMagnitude[index] || !neighborsSignificance[index]) { + continue; + } + const contextLabel = labels[neighborsSignificance[index]]; + const decision = decoder.readBit(contexts, contextLabel); + if (decision) { + const sign = this.decodeSignBit(i, j, index); + coefficentsSign[index] = sign; + coefficentsMagnitude[index] = 1; + this.setNeighborsSignificance(i, j, index); + processingFlags[index] |= firstMagnitudeBitMask; + } + bitsDecoded[index]++; + processingFlags[index] |= processedMask; + } + } + } + } + decodeSignBit(row, column, index) { + const width = this.width, + height = this.height; + const coefficentsMagnitude = this.coefficentsMagnitude; + const coefficentsSign = this.coefficentsSign; + let contribution, sign0, sign1, significance1; + let contextLabel, decoded; + significance1 = column > 0 && coefficentsMagnitude[index - 1] !== 0; + if (column + 1 < width && coefficentsMagnitude[index + 1] !== 0) { + sign1 = coefficentsSign[index + 1]; + if (significance1) { + sign0 = coefficentsSign[index - 1]; + contribution = 1 - sign1 - sign0; + } else { + contribution = 1 - sign1 - sign1; + } + } else if (significance1) { + sign0 = coefficentsSign[index - 1]; + contribution = 1 - sign0 - sign0; + } else { + contribution = 0; + } + const horizontalContribution = 3 * contribution; + significance1 = row > 0 && coefficentsMagnitude[index - width] !== 0; + if (row + 1 < height && coefficentsMagnitude[index + width] !== 0) { + sign1 = coefficentsSign[index + width]; + if (significance1) { + sign0 = coefficentsSign[index - width]; + contribution = 1 - sign1 - sign0 + horizontalContribution; + } else { + contribution = 1 - sign1 - sign1 + horizontalContribution; + } + } else if (significance1) { + sign0 = coefficentsSign[index - width]; + contribution = 1 - sign0 - sign0 + horizontalContribution; + } else { + contribution = horizontalContribution; + } + if (contribution >= 0) { + contextLabel = 9 + contribution; + decoded = this.decoder.readBit(this.contexts, contextLabel); + } else { + contextLabel = 9 - contribution; + decoded = this.decoder.readBit(this.contexts, contextLabel) ^ 1; + } + return decoded; + } + runMagnitudeRefinementPass() { + const decoder = this.decoder; + const width = this.width, + height = this.height; + const coefficentsMagnitude = this.coefficentsMagnitude; + const neighborsSignificance = this.neighborsSignificance; + const contexts = this.contexts; + const bitsDecoded = this.bitsDecoded; + const processingFlags = this.processingFlags; + const processedMask = 1; + const firstMagnitudeBitMask = 2; + const length = width * height; + const width4 = width * 4; + for (let index0 = 0, indexNext; index0 < length; index0 = indexNext) { + indexNext = Math.min(length, index0 + width4); + for (let j = 0; j < width; j++) { + for (let index = index0 + j; index < indexNext; index += width) { + if (!coefficentsMagnitude[index] || (processingFlags[index] & processedMask) !== 0) { + continue; + } + let contextLabel = 16; + if ((processingFlags[index] & firstMagnitudeBitMask) !== 0) { + processingFlags[index] ^= firstMagnitudeBitMask; + const significance = neighborsSignificance[index] & 127; + contextLabel = significance === 0 ? 15 : 14; + } + const bit = decoder.readBit(contexts, contextLabel); + coefficentsMagnitude[index] = coefficentsMagnitude[index] << 1 | bit; + bitsDecoded[index]++; + processingFlags[index] |= processedMask; + } + } + } + } + runCleanupPass() { + const decoder = this.decoder; + const width = this.width, + height = this.height; + const neighborsSignificance = this.neighborsSignificance; + const coefficentsMagnitude = this.coefficentsMagnitude; + const coefficentsSign = this.coefficentsSign; + const contexts = this.contexts; + const labels = this.contextLabelTable; + const bitsDecoded = this.bitsDecoded; + const processingFlags = this.processingFlags; + const processedMask = 1; + const firstMagnitudeBitMask = 2; + const oneRowDown = width; + const twoRowsDown = width * 2; + const threeRowsDown = width * 3; + let iNext; + for (let i0 = 0; i0 < height; i0 = iNext) { + iNext = Math.min(i0 + 4, height); + const indexBase = i0 * width; + const checkAllEmpty = i0 + 3 < height; + for (let j = 0; j < width; j++) { + const index0 = indexBase + j; + const allEmpty = checkAllEmpty && processingFlags[index0] === 0 && processingFlags[index0 + oneRowDown] === 0 && processingFlags[index0 + twoRowsDown] === 0 && processingFlags[index0 + threeRowsDown] === 0 && neighborsSignificance[index0] === 0 && neighborsSignificance[index0 + oneRowDown] === 0 && neighborsSignificance[index0 + twoRowsDown] === 0 && neighborsSignificance[index0 + threeRowsDown] === 0; + let i1 = 0, + index = index0; + let i = i0, + sign; + if (allEmpty) { + const hasSignificantCoefficent = decoder.readBit(contexts, BitModel.RUNLENGTH_CONTEXT); + if (!hasSignificantCoefficent) { + bitsDecoded[index0]++; + bitsDecoded[index0 + oneRowDown]++; + bitsDecoded[index0 + twoRowsDown]++; + bitsDecoded[index0 + threeRowsDown]++; + continue; + } + i1 = decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT) << 1 | decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT); + if (i1 !== 0) { + i = i0 + i1; + index += i1 * width; + } + sign = this.decodeSignBit(i, j, index); + coefficentsSign[index] = sign; + coefficentsMagnitude[index] = 1; + this.setNeighborsSignificance(i, j, index); + processingFlags[index] |= firstMagnitudeBitMask; + index = index0; + for (let i2 = i0; i2 <= i; i2++, index += width) { + bitsDecoded[index]++; + } + i1++; + } + for (i = i0 + i1; i < iNext; i++, index += width) { + if (coefficentsMagnitude[index] || (processingFlags[index] & processedMask) !== 0) { + continue; + } + const contextLabel = labels[neighborsSignificance[index]]; + const decision = decoder.readBit(contexts, contextLabel); + if (decision === 1) { + sign = this.decodeSignBit(i, j, index); + coefficentsSign[index] = sign; + coefficentsMagnitude[index] = 1; + this.setNeighborsSignificance(i, j, index); + processingFlags[index] |= firstMagnitudeBitMask; + } + bitsDecoded[index]++; + } + } + } + } + checkSegmentationSymbol() { + const decoder = this.decoder; + const contexts = this.contexts; + const symbol = decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT) << 3 | decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT) << 2 | decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT) << 1 | decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT); + if (symbol !== 0xa) { + throw new JpxError("Invalid segmentation symbol"); + } + } +} +class Transform { + constructor() { + if (this.constructor === Transform) { + (0, _util.unreachable)("Cannot initialize Transform."); + } + } + calculate(subbands, u0, v0) { + let ll = subbands[0]; + for (let i = 1, ii = subbands.length; i < ii; i++) { + ll = this.iterate(ll, subbands[i], u0, v0); + } + return ll; + } + extend(buffer, offset, size) { + let i1 = offset - 1, + j1 = offset + 1; + let i2 = offset + size - 2, + j2 = offset + size; + buffer[i1--] = buffer[j1++]; + buffer[j2++] = buffer[i2--]; + buffer[i1--] = buffer[j1++]; + buffer[j2++] = buffer[i2--]; + buffer[i1--] = buffer[j1++]; + buffer[j2++] = buffer[i2--]; + buffer[i1] = buffer[j1]; + buffer[j2] = buffer[i2]; + } + filter(x, offset, length) { + (0, _util.unreachable)("Abstract method `filter` called"); + } + iterate(ll, hl_lh_hh, u0, v0) { + const llWidth = ll.width, + llHeight = ll.height; + let llItems = ll.items; + const width = hl_lh_hh.width; + const height = hl_lh_hh.height; + const items = hl_lh_hh.items; + let i, j, k, l, u, v; + for (k = 0, i = 0; i < llHeight; i++) { + l = i * 2 * width; + for (j = 0; j < llWidth; j++, k++, l += 2) { + items[l] = llItems[k]; + } + } + llItems = ll.items = null; + const bufferPadding = 4; + const rowBuffer = new Float32Array(width + 2 * bufferPadding); + if (width === 1) { + if ((u0 & 1) !== 0) { + for (v = 0, k = 0; v < height; v++, k += width) { + items[k] *= 0.5; + } + } + } else { + for (v = 0, k = 0; v < height; v++, k += width) { + rowBuffer.set(items.subarray(k, k + width), bufferPadding); + this.extend(rowBuffer, bufferPadding, width); + this.filter(rowBuffer, bufferPadding, width); + items.set(rowBuffer.subarray(bufferPadding, bufferPadding + width), k); + } + } + let numBuffers = 16; + const colBuffers = []; + for (i = 0; i < numBuffers; i++) { + colBuffers.push(new Float32Array(height + 2 * bufferPadding)); + } + let b, + currentBuffer = 0; + ll = bufferPadding + height; + if (height === 1) { + if ((v0 & 1) !== 0) { + for (u = 0; u < width; u++) { + items[u] *= 0.5; + } + } + } else { + for (u = 0; u < width; u++) { + if (currentBuffer === 0) { + numBuffers = Math.min(width - u, numBuffers); + for (k = u, l = bufferPadding; l < ll; k += width, l++) { + for (b = 0; b < numBuffers; b++) { + colBuffers[b][l] = items[k + b]; + } + } + currentBuffer = numBuffers; + } + currentBuffer--; + const buffer = colBuffers[currentBuffer]; + this.extend(buffer, bufferPadding, height); + this.filter(buffer, bufferPadding, height); + if (currentBuffer === 0) { + k = u - numBuffers + 1; + for (l = bufferPadding; l < ll; k += width, l++) { + for (b = 0; b < numBuffers; b++) { + items[k + b] = colBuffers[b][l]; + } + } + } + } + } + return { + width, + height, + items + }; + } +} +class IrreversibleTransform extends Transform { + filter(x, offset, length) { + const len = length >> 1; + offset |= 0; + let j, n, current, next; + const alpha = -1.586134342059924; + const beta = -0.052980118572961; + const gamma = 0.882911075530934; + const delta = 0.443506852043971; + const K = 1.230174104914001; + const K_ = 1 / K; + j = offset - 3; + for (n = len + 4; n--; j += 2) { + x[j] *= K_; + } + j = offset - 2; + current = delta * x[j - 1]; + for (n = len + 3; n--; j += 2) { + next = delta * x[j + 1]; + x[j] = K * x[j] - current - next; + if (n--) { + j += 2; + current = delta * x[j + 1]; + x[j] = K * x[j] - current - next; + } else { + break; + } + } + j = offset - 1; + current = gamma * x[j - 1]; + for (n = len + 2; n--; j += 2) { + next = gamma * x[j + 1]; + x[j] -= current + next; + if (n--) { + j += 2; + current = gamma * x[j + 1]; + x[j] -= current + next; + } else { + break; + } + } + j = offset; + current = beta * x[j - 1]; + for (n = len + 1; n--; j += 2) { + next = beta * x[j + 1]; + x[j] -= current + next; + if (n--) { + j += 2; + current = beta * x[j + 1]; + x[j] -= current + next; + } else { + break; + } + } + if (len !== 0) { + j = offset + 1; + current = alpha * x[j - 1]; + for (n = len; n--; j += 2) { + next = alpha * x[j + 1]; + x[j] -= current + next; + if (n--) { + j += 2; + current = alpha * x[j + 1]; + x[j] -= current + next; + } else { + break; + } + } + } + } +} +class ReversibleTransform extends Transform { + filter(x, offset, length) { + const len = length >> 1; + offset |= 0; + let j, n; + for (j = offset, n = len + 1; n--; j += 2) { + x[j] -= x[j - 1] + x[j + 1] + 2 >> 2; + } + for (j = offset + 1, n = len; n--; j += 2) { + x[j] += x[j - 1] + x[j + 1] >> 1; + } + } +} + +/***/ }), +/* 31 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.LZWStream = void 0; +var _decode_stream = __w_pdfjs_require__(18); +class LZWStream extends _decode_stream.DecodeStream { + constructor(str, maybeLength, earlyChange) { + super(maybeLength); + this.str = str; + this.dict = str.dict; + this.cachedData = 0; + this.bitsCached = 0; + const maxLzwDictionarySize = 4096; + const lzwState = { + earlyChange, + codeLength: 9, + nextCode: 258, + dictionaryValues: new Uint8Array(maxLzwDictionarySize), + dictionaryLengths: new Uint16Array(maxLzwDictionarySize), + dictionaryPrevCodes: new Uint16Array(maxLzwDictionarySize), + currentSequence: new Uint8Array(maxLzwDictionarySize), + currentSequenceLength: 0 + }; + for (let i = 0; i < 256; ++i) { + lzwState.dictionaryValues[i] = i; + lzwState.dictionaryLengths[i] = 1; + } + this.lzwState = lzwState; + } + readBits(n) { + let bitsCached = this.bitsCached; + let cachedData = this.cachedData; + while (bitsCached < n) { + const c = this.str.getByte(); + if (c === -1) { + this.eof = true; + return null; + } + cachedData = cachedData << 8 | c; + bitsCached += 8; + } + this.bitsCached = bitsCached -= n; + this.cachedData = cachedData; + this.lastCode = null; + return cachedData >>> bitsCached & (1 << n) - 1; + } + readBlock() { + const blockSize = 512, + decodedSizeDelta = blockSize; + let estimatedDecodedSize = blockSize * 2; + let i, j, q; + const lzwState = this.lzwState; + if (!lzwState) { + return; + } + const earlyChange = lzwState.earlyChange; + let nextCode = lzwState.nextCode; + const dictionaryValues = lzwState.dictionaryValues; + const dictionaryLengths = lzwState.dictionaryLengths; + const dictionaryPrevCodes = lzwState.dictionaryPrevCodes; + let codeLength = lzwState.codeLength; + let prevCode = lzwState.prevCode; + const currentSequence = lzwState.currentSequence; + let currentSequenceLength = lzwState.currentSequenceLength; + let decodedLength = 0; + let currentBufferLength = this.bufferLength; + let buffer = this.ensureBuffer(this.bufferLength + estimatedDecodedSize); + for (i = 0; i < blockSize; i++) { + const code = this.readBits(codeLength); + const hasPrev = currentSequenceLength > 0; + if (code < 256) { + currentSequence[0] = code; + currentSequenceLength = 1; + } else if (code >= 258) { + if (code < nextCode) { + currentSequenceLength = dictionaryLengths[code]; + for (j = currentSequenceLength - 1, q = code; j >= 0; j--) { + currentSequence[j] = dictionaryValues[q]; + q = dictionaryPrevCodes[q]; + } + } else { + currentSequence[currentSequenceLength++] = currentSequence[0]; + } + } else if (code === 256) { + codeLength = 9; + nextCode = 258; + currentSequenceLength = 0; + continue; + } else { + this.eof = true; + delete this.lzwState; + break; + } + if (hasPrev) { + dictionaryPrevCodes[nextCode] = prevCode; + dictionaryLengths[nextCode] = dictionaryLengths[prevCode] + 1; + dictionaryValues[nextCode] = currentSequence[0]; + nextCode++; + codeLength = nextCode + earlyChange & nextCode + earlyChange - 1 ? codeLength : Math.min(Math.log(nextCode + earlyChange) / 0.6931471805599453 + 1, 12) | 0; + } + prevCode = code; + decodedLength += currentSequenceLength; + if (estimatedDecodedSize < decodedLength) { + do { + estimatedDecodedSize += decodedSizeDelta; + } while (estimatedDecodedSize < decodedLength); + buffer = this.ensureBuffer(this.bufferLength + estimatedDecodedSize); + } + for (j = 0; j < currentSequenceLength; j++) { + buffer[currentBufferLength++] = currentSequence[j]; + } + } + lzwState.nextCode = nextCode; + lzwState.codeLength = codeLength; + lzwState.prevCode = prevCode; + lzwState.currentSequenceLength = currentSequenceLength; + this.bufferLength = currentBufferLength; + } +} +exports.LZWStream = LZWStream; + +/***/ }), +/* 32 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.PredictorStream = void 0; +var _decode_stream = __w_pdfjs_require__(18); +var _primitives = __w_pdfjs_require__(4); +var _util = __w_pdfjs_require__(2); +class PredictorStream extends _decode_stream.DecodeStream { + constructor(str, maybeLength, params) { + super(maybeLength); + if (!(params instanceof _primitives.Dict)) { + return str; + } + const predictor = this.predictor = params.get("Predictor") || 1; + if (predictor <= 1) { + return str; + } + if (predictor !== 2 && (predictor < 10 || predictor > 15)) { + throw new _util.FormatError(`Unsupported predictor: ${predictor}`); + } + this.readBlock = predictor === 2 ? this.readBlockTiff : this.readBlockPng; + this.str = str; + this.dict = str.dict; + const colors = this.colors = params.get("Colors") || 1; + const bits = this.bits = params.get("BPC", "BitsPerComponent") || 8; + const columns = this.columns = params.get("Columns") || 1; + this.pixBytes = colors * bits + 7 >> 3; + this.rowBytes = columns * colors * bits + 7 >> 3; + return this; + } + readBlockTiff() { + const rowBytes = this.rowBytes; + const bufferLength = this.bufferLength; + const buffer = this.ensureBuffer(bufferLength + rowBytes); + const bits = this.bits; + const colors = this.colors; + const rawBytes = this.str.getBytes(rowBytes); + this.eof = !rawBytes.length; + if (this.eof) { + return; + } + let inbuf = 0, + outbuf = 0; + let inbits = 0, + outbits = 0; + let pos = bufferLength; + let i; + if (bits === 1 && colors === 1) { + for (i = 0; i < rowBytes; ++i) { + let c = rawBytes[i] ^ inbuf; + c ^= c >> 1; + c ^= c >> 2; + c ^= c >> 4; + inbuf = (c & 1) << 7; + buffer[pos++] = c; + } + } else if (bits === 8) { + for (i = 0; i < colors; ++i) { + buffer[pos++] = rawBytes[i]; + } + for (; i < rowBytes; ++i) { + buffer[pos] = buffer[pos - colors] + rawBytes[i]; + pos++; + } + } else if (bits === 16) { + const bytesPerPixel = colors * 2; + for (i = 0; i < bytesPerPixel; ++i) { + buffer[pos++] = rawBytes[i]; + } + for (; i < rowBytes; i += 2) { + const sum = ((rawBytes[i] & 0xff) << 8) + (rawBytes[i + 1] & 0xff) + ((buffer[pos - bytesPerPixel] & 0xff) << 8) + (buffer[pos - bytesPerPixel + 1] & 0xff); + buffer[pos++] = sum >> 8 & 0xff; + buffer[pos++] = sum & 0xff; + } + } else { + const compArray = new Uint8Array(colors + 1); + const bitMask = (1 << bits) - 1; + let j = 0, + k = bufferLength; + const columns = this.columns; + for (i = 0; i < columns; ++i) { + for (let kk = 0; kk < colors; ++kk) { + if (inbits < bits) { + inbuf = inbuf << 8 | rawBytes[j++] & 0xff; + inbits += 8; + } + compArray[kk] = compArray[kk] + (inbuf >> inbits - bits) & bitMask; + inbits -= bits; + outbuf = outbuf << bits | compArray[kk]; + outbits += bits; + if (outbits >= 8) { + buffer[k++] = outbuf >> outbits - 8 & 0xff; + outbits -= 8; + } + } + } + if (outbits > 0) { + buffer[k++] = (outbuf << 8 - outbits) + (inbuf & (1 << 8 - outbits) - 1); + } + } + this.bufferLength += rowBytes; + } + readBlockPng() { + const rowBytes = this.rowBytes; + const pixBytes = this.pixBytes; + const predictor = this.str.getByte(); + const rawBytes = this.str.getBytes(rowBytes); + this.eof = !rawBytes.length; + if (this.eof) { + return; + } + const bufferLength = this.bufferLength; + const buffer = this.ensureBuffer(bufferLength + rowBytes); + let prevRow = buffer.subarray(bufferLength - rowBytes, bufferLength); + if (prevRow.length === 0) { + prevRow = new Uint8Array(rowBytes); + } + let i, + j = bufferLength, + up, + c; + switch (predictor) { + case 0: + for (i = 0; i < rowBytes; ++i) { + buffer[j++] = rawBytes[i]; + } + break; + case 1: + for (i = 0; i < pixBytes; ++i) { + buffer[j++] = rawBytes[i]; + } + for (; i < rowBytes; ++i) { + buffer[j] = buffer[j - pixBytes] + rawBytes[i] & 0xff; + j++; + } + break; + case 2: + for (i = 0; i < rowBytes; ++i) { + buffer[j++] = prevRow[i] + rawBytes[i] & 0xff; + } + break; + case 3: + for (i = 0; i < pixBytes; ++i) { + buffer[j++] = (prevRow[i] >> 1) + rawBytes[i]; + } + for (; i < rowBytes; ++i) { + buffer[j] = (prevRow[i] + buffer[j - pixBytes] >> 1) + rawBytes[i] & 0xff; + j++; + } + break; + case 4: + for (i = 0; i < pixBytes; ++i) { + up = prevRow[i]; + c = rawBytes[i]; + buffer[j++] = up + c; + } + for (; i < rowBytes; ++i) { + up = prevRow[i]; + const upLeft = prevRow[i - pixBytes]; + const left = buffer[j - pixBytes]; + const p = left + up - upLeft; + let pa = p - left; + if (pa < 0) { + pa = -pa; + } + let pb = p - up; + if (pb < 0) { + pb = -pb; + } + let pc = p - upLeft; + if (pc < 0) { + pc = -pc; + } + c = rawBytes[i]; + if (pa <= pb && pa <= pc) { + buffer[j++] = left + c; + } else if (pb <= pc) { + buffer[j++] = up + c; + } else { + buffer[j++] = upLeft + c; + } + } + break; + default: + throw new _util.FormatError(`Unsupported predictor: ${predictor}`); + } + this.bufferLength += rowBytes; + } +} +exports.PredictorStream = PredictorStream; + +/***/ }), +/* 33 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.RunLengthStream = void 0; +var _decode_stream = __w_pdfjs_require__(18); +class RunLengthStream extends _decode_stream.DecodeStream { + constructor(str, maybeLength) { + super(maybeLength); + this.str = str; + this.dict = str.dict; + } + readBlock() { + const repeatHeader = this.str.getBytes(2); + if (!repeatHeader || repeatHeader.length < 2 || repeatHeader[0] === 128) { + this.eof = true; + return; + } + let buffer; + let bufferLength = this.bufferLength; + let n = repeatHeader[0]; + if (n < 128) { + buffer = this.ensureBuffer(bufferLength + n + 1); + buffer[bufferLength++] = repeatHeader[1]; + if (n > 0) { + const source = this.str.getBytes(n); + buffer.set(source, bufferLength); + bufferLength += n; + } + } else { + n = 257 - n; + const b = repeatHeader[1]; + buffer = this.ensureBuffer(bufferLength + n + 1); + for (let i = 0; i < n; i++) { + buffer[bufferLength++] = b; + } + } + this.bufferLength = bufferLength; + } +} +exports.RunLengthStream = RunLengthStream; + +/***/ }), +/* 34 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Font = exports.ErrorFont = void 0; +var _util = __w_pdfjs_require__(2); +var _cff_parser = __w_pdfjs_require__(35); +var _fonts_utils = __w_pdfjs_require__(38); +var _unicode = __w_pdfjs_require__(40); +var _glyphlist = __w_pdfjs_require__(39); +var _encodings = __w_pdfjs_require__(37); +var _standard_fonts = __w_pdfjs_require__(41); +var _to_unicode_map = __w_pdfjs_require__(42); +var _cff_font = __w_pdfjs_require__(43); +var _font_renderer = __w_pdfjs_require__(44); +var _metrics = __w_pdfjs_require__(45); +var _glyf = __w_pdfjs_require__(46); +var _cmap = __w_pdfjs_require__(14); +var _opentype_file_builder = __w_pdfjs_require__(47); +var _core_utils = __w_pdfjs_require__(3); +var _stream = __w_pdfjs_require__(8); +var _type1_font = __w_pdfjs_require__(48); +const PRIVATE_USE_AREAS = [[0xe000, 0xf8ff], [0x100000, 0x10fffd]]; +const PDF_GLYPH_SPACE_UNITS = 1000; +const EXPORT_DATA_PROPERTIES = ["ascent", "bbox", "black", "bold", "charProcOperatorList", "composite", "cssFontInfo", "data", "defaultVMetrics", "defaultWidth", "descent", "fallbackName", "fontMatrix", "isInvalidPDFjsFont", "isType3Font", "italic", "loadedName", "mimetype", "missingFile", "name", "remeasure", "subtype", "systemFontInfo", "type", "vertical"]; +const EXPORT_DATA_EXTRA_PROPERTIES = ["cMap", "defaultEncoding", "differences", "isMonospace", "isSerifFont", "isSymbolicFont", "seacMap", "toFontChar", "toUnicode", "vmetrics", "widths"]; +function adjustWidths(properties) { + if (!properties.fontMatrix) { + return; + } + if (properties.fontMatrix[0] === _util.FONT_IDENTITY_MATRIX[0]) { + return; + } + const scale = 0.001 / properties.fontMatrix[0]; + const glyphsWidths = properties.widths; + for (const glyph in glyphsWidths) { + glyphsWidths[glyph] *= scale; + } + properties.defaultWidth *= scale; +} +function adjustTrueTypeToUnicode(properties, isSymbolicFont, nameRecords) { + if (properties.isInternalFont) { + return; + } + if (properties.hasIncludedToUnicodeMap) { + return; + } + if (properties.hasEncoding) { + return; + } + if (properties.toUnicode instanceof _to_unicode_map.IdentityToUnicodeMap) { + return; + } + if (!isSymbolicFont) { + return; + } + if (nameRecords.length === 0) { + return; + } + if (properties.defaultEncoding === _encodings.WinAnsiEncoding) { + return; + } + for (const r of nameRecords) { + if (!isWinNameRecord(r)) { + return; + } + } + const encoding = _encodings.WinAnsiEncoding; + const toUnicode = [], + glyphsUnicodeMap = (0, _glyphlist.getGlyphsUnicode)(); + for (const charCode in encoding) { + const glyphName = encoding[charCode]; + if (glyphName === "") { + continue; + } + const unicode = glyphsUnicodeMap[glyphName]; + if (unicode === undefined) { + continue; + } + toUnicode[charCode] = String.fromCharCode(unicode); + } + if (toUnicode.length > 0) { + properties.toUnicode.amend(toUnicode); + } +} +function adjustType1ToUnicode(properties, builtInEncoding) { + if (properties.isInternalFont) { + return; + } + if (properties.hasIncludedToUnicodeMap) { + return; + } + if (builtInEncoding === properties.defaultEncoding) { + return; + } + if (properties.toUnicode instanceof _to_unicode_map.IdentityToUnicodeMap) { + return; + } + const toUnicode = [], + glyphsUnicodeMap = (0, _glyphlist.getGlyphsUnicode)(); + for (const charCode in builtInEncoding) { + if (properties.hasEncoding) { + if (properties.baseEncodingName || properties.differences[charCode] !== undefined) { + continue; + } + } + const glyphName = builtInEncoding[charCode]; + const unicode = (0, _unicode.getUnicodeForGlyph)(glyphName, glyphsUnicodeMap); + if (unicode !== -1) { + toUnicode[charCode] = String.fromCharCode(unicode); + } + } + if (toUnicode.length > 0) { + properties.toUnicode.amend(toUnicode); + } +} +function amendFallbackToUnicode(properties) { + if (!properties.fallbackToUnicode) { + return; + } + if (properties.toUnicode instanceof _to_unicode_map.IdentityToUnicodeMap) { + return; + } + const toUnicode = []; + for (const charCode in properties.fallbackToUnicode) { + if (properties.toUnicode.has(charCode)) { + continue; + } + toUnicode[charCode] = properties.fallbackToUnicode[charCode]; + } + if (toUnicode.length > 0) { + properties.toUnicode.amend(toUnicode); + } +} +class Glyph { + constructor(originalCharCode, fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont) { + this.originalCharCode = originalCharCode; + this.fontChar = fontChar; + this.unicode = unicode; + this.accent = accent; + this.width = width; + this.vmetric = vmetric; + this.operatorListId = operatorListId; + this.isSpace = isSpace; + this.isInFont = isInFont; + } + get category() { + return (0, _util.shadow)(this, "category", (0, _unicode.getCharUnicodeCategory)(this.unicode), true); + } +} +function int16(b0, b1) { + return (b0 << 8) + b1; +} +function writeSignedInt16(bytes, index, value) { + bytes[index + 1] = value; + bytes[index] = value >>> 8; +} +function signedInt16(b0, b1) { + const value = (b0 << 8) + b1; + return value & 1 << 15 ? value - 0x10000 : value; +} +function int32(b0, b1, b2, b3) { + return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3; +} +function string16(value) { + return String.fromCharCode(value >> 8 & 0xff, value & 0xff); +} +function safeString16(value) { + if (value > 0x7fff) { + value = 0x7fff; + } else if (value < -0x8000) { + value = -0x8000; + } + return String.fromCharCode(value >> 8 & 0xff, value & 0xff); +} +function isTrueTypeFile(file) { + const header = file.peekBytes(4); + return (0, _core_utils.readUint32)(header, 0) === 0x00010000 || (0, _util.bytesToString)(header) === "true"; +} +function isTrueTypeCollectionFile(file) { + const header = file.peekBytes(4); + return (0, _util.bytesToString)(header) === "ttcf"; +} +function isOpenTypeFile(file) { + const header = file.peekBytes(4); + return (0, _util.bytesToString)(header) === "OTTO"; +} +function isType1File(file) { + const header = file.peekBytes(2); + if (header[0] === 0x25 && header[1] === 0x21) { + return true; + } + if (header[0] === 0x80 && header[1] === 0x01) { + return true; + } + return false; +} +function isCFFFile(file) { + const header = file.peekBytes(4); + if (header[0] >= 1 && header[3] >= 1 && header[3] <= 4) { + return true; + } + return false; +} +function getFontFileType(file, { + type, + subtype, + composite +}) { + let fileType, fileSubtype; + if (isTrueTypeFile(file) || isTrueTypeCollectionFile(file)) { + fileType = composite ? "CIDFontType2" : "TrueType"; + } else if (isOpenTypeFile(file)) { + fileType = composite ? "CIDFontType2" : "OpenType"; + } else if (isType1File(file)) { + if (composite) { + fileType = "CIDFontType0"; + } else { + fileType = type === "MMType1" ? "MMType1" : "Type1"; + } + } else if (isCFFFile(file)) { + if (composite) { + fileType = "CIDFontType0"; + fileSubtype = "CIDFontType0C"; + } else { + fileType = type === "MMType1" ? "MMType1" : "Type1"; + fileSubtype = "Type1C"; + } + } else { + (0, _util.warn)("getFontFileType: Unable to detect correct font file Type/Subtype."); + fileType = type; + fileSubtype = subtype; + } + return [fileType, fileSubtype]; +} +function applyStandardFontGlyphMap(map, glyphMap) { + for (const charCode in glyphMap) { + map[+charCode] = glyphMap[charCode]; + } +} +function buildToFontChar(encoding, glyphsUnicodeMap, differences) { + const toFontChar = []; + let unicode; + for (let i = 0, ii = encoding.length; i < ii; i++) { + unicode = (0, _unicode.getUnicodeForGlyph)(encoding[i], glyphsUnicodeMap); + if (unicode !== -1) { + toFontChar[i] = unicode; + } + } + for (const charCode in differences) { + unicode = (0, _unicode.getUnicodeForGlyph)(differences[charCode], glyphsUnicodeMap); + if (unicode !== -1) { + toFontChar[+charCode] = unicode; + } + } + return toFontChar; +} +function isMacNameRecord(r) { + return r.platform === 1 && r.encoding === 0 && r.language === 0; +} +function isWinNameRecord(r) { + return r.platform === 3 && r.encoding === 1 && r.language === 0x409; +} +function convertCidString(charCode, cid, shouldThrow = false) { + switch (cid.length) { + case 1: + return cid.charCodeAt(0); + case 2: + return cid.charCodeAt(0) << 8 | cid.charCodeAt(1); + } + const msg = `Unsupported CID string (charCode ${charCode}): "${cid}".`; + if (shouldThrow) { + throw new _util.FormatError(msg); + } + (0, _util.warn)(msg); + return cid; +} +function adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId, toUnicode) { + const newMap = Object.create(null); + const toUnicodeExtraMap = new Map(); + const toFontChar = []; + const usedGlyphIds = new Set(); + let privateUseAreaIndex = 0; + const privateUseOffetStart = PRIVATE_USE_AREAS[privateUseAreaIndex][0]; + let nextAvailableFontCharCode = privateUseOffetStart; + let privateUseOffetEnd = PRIVATE_USE_AREAS[privateUseAreaIndex][1]; + const isInPrivateArea = code => PRIVATE_USE_AREAS[0][0] <= code && code <= PRIVATE_USE_AREAS[0][1] || PRIVATE_USE_AREAS[1][0] <= code && code <= PRIVATE_USE_AREAS[1][1]; + for (let originalCharCode in charCodeToGlyphId) { + originalCharCode |= 0; + let glyphId = charCodeToGlyphId[originalCharCode]; + if (!hasGlyph(glyphId)) { + continue; + } + if (nextAvailableFontCharCode > privateUseOffetEnd) { + privateUseAreaIndex++; + if (privateUseAreaIndex >= PRIVATE_USE_AREAS.length) { + (0, _util.warn)("Ran out of space in font private use area."); + break; + } + nextAvailableFontCharCode = PRIVATE_USE_AREAS[privateUseAreaIndex][0]; + privateUseOffetEnd = PRIVATE_USE_AREAS[privateUseAreaIndex][1]; + } + const fontCharCode = nextAvailableFontCharCode++; + if (glyphId === 0) { + glyphId = newGlyphZeroId; + } + let unicode = toUnicode.get(originalCharCode); + if (typeof unicode === "string") { + unicode = unicode.codePointAt(0); + } + if (unicode && !isInPrivateArea(unicode) && !usedGlyphIds.has(glyphId)) { + toUnicodeExtraMap.set(unicode, glyphId); + usedGlyphIds.add(glyphId); + } + newMap[fontCharCode] = glyphId; + toFontChar[originalCharCode] = fontCharCode; + } + return { + toFontChar, + charCodeToGlyphId: newMap, + toUnicodeExtraMap, + nextAvailableFontCharCode + }; +} +function getRanges(glyphs, toUnicodeExtraMap, numGlyphs) { + const codes = []; + for (const charCode in glyphs) { + if (glyphs[charCode] >= numGlyphs) { + continue; + } + codes.push({ + fontCharCode: charCode | 0, + glyphId: glyphs[charCode] + }); + } + if (toUnicodeExtraMap) { + for (const [unicode, glyphId] of toUnicodeExtraMap) { + if (glyphId >= numGlyphs) { + continue; + } + codes.push({ + fontCharCode: unicode, + glyphId + }); + } + } + if (codes.length === 0) { + codes.push({ + fontCharCode: 0, + glyphId: 0 + }); + } + codes.sort(function fontGetRangesSort(a, b) { + return a.fontCharCode - b.fontCharCode; + }); + const ranges = []; + const length = codes.length; + for (let n = 0; n < length;) { + const start = codes[n].fontCharCode; + const codeIndices = [codes[n].glyphId]; + ++n; + let end = start; + while (n < length && end + 1 === codes[n].fontCharCode) { + codeIndices.push(codes[n].glyphId); + ++end; + ++n; + if (end === 0xffff) { + break; + } + } + ranges.push([start, end, codeIndices]); + } + return ranges; +} +function createCmapTable(glyphs, toUnicodeExtraMap, numGlyphs) { + const ranges = getRanges(glyphs, toUnicodeExtraMap, numGlyphs); + const numTables = ranges.at(-1)[1] > 0xffff ? 2 : 1; + let cmap = "\x00\x00" + string16(numTables) + "\x00\x03" + "\x00\x01" + (0, _util.string32)(4 + numTables * 8); + let i, ii, j, jj; + for (i = ranges.length - 1; i >= 0; --i) { + if (ranges[i][0] <= 0xffff) { + break; + } + } + const bmpLength = i + 1; + if (ranges[i][0] < 0xffff && ranges[i][1] === 0xffff) { + ranges[i][1] = 0xfffe; + } + const trailingRangesCount = ranges[i][1] < 0xffff ? 1 : 0; + const segCount = bmpLength + trailingRangesCount; + const searchParams = _opentype_file_builder.OpenTypeFileBuilder.getSearchParams(segCount, 2); + let startCount = ""; + let endCount = ""; + let idDeltas = ""; + let idRangeOffsets = ""; + let glyphsIds = ""; + let bias = 0; + let range, start, end, codes; + for (i = 0, ii = bmpLength; i < ii; i++) { + range = ranges[i]; + start = range[0]; + end = range[1]; + startCount += string16(start); + endCount += string16(end); + codes = range[2]; + let contiguous = true; + for (j = 1, jj = codes.length; j < jj; ++j) { + if (codes[j] !== codes[j - 1] + 1) { + contiguous = false; + break; + } + } + if (!contiguous) { + const offset = (segCount - i) * 2 + bias * 2; + bias += end - start + 1; + idDeltas += string16(0); + idRangeOffsets += string16(offset); + for (j = 0, jj = codes.length; j < jj; ++j) { + glyphsIds += string16(codes[j]); + } + } else { + const startCode = codes[0]; + idDeltas += string16(startCode - start & 0xffff); + idRangeOffsets += string16(0); + } + } + if (trailingRangesCount > 0) { + endCount += "\xFF\xFF"; + startCount += "\xFF\xFF"; + idDeltas += "\x00\x01"; + idRangeOffsets += "\x00\x00"; + } + const format314 = "\x00\x00" + string16(2 * segCount) + string16(searchParams.range) + string16(searchParams.entry) + string16(searchParams.rangeShift) + endCount + "\x00\x00" + startCount + idDeltas + idRangeOffsets + glyphsIds; + let format31012 = ""; + let header31012 = ""; + if (numTables > 1) { + cmap += "\x00\x03" + "\x00\x0A" + (0, _util.string32)(4 + numTables * 8 + 4 + format314.length); + format31012 = ""; + for (i = 0, ii = ranges.length; i < ii; i++) { + range = ranges[i]; + start = range[0]; + codes = range[2]; + let code = codes[0]; + for (j = 1, jj = codes.length; j < jj; ++j) { + if (codes[j] !== codes[j - 1] + 1) { + end = range[0] + j - 1; + format31012 += (0, _util.string32)(start) + (0, _util.string32)(end) + (0, _util.string32)(code); + start = end + 1; + code = codes[j]; + } + } + format31012 += (0, _util.string32)(start) + (0, _util.string32)(range[1]) + (0, _util.string32)(code); + } + header31012 = "\x00\x0C" + "\x00\x00" + (0, _util.string32)(format31012.length + 16) + "\x00\x00\x00\x00" + (0, _util.string32)(format31012.length / 12); + } + return cmap + "\x00\x04" + string16(format314.length + 4) + format314 + header31012 + format31012; +} +function validateOS2Table(os2, file) { + file.pos = (file.start || 0) + os2.offset; + const version = file.getUint16(); + file.skip(60); + const selection = file.getUint16(); + if (version < 4 && selection & 0x0300) { + return false; + } + const firstChar = file.getUint16(); + const lastChar = file.getUint16(); + if (firstChar > lastChar) { + return false; + } + file.skip(6); + const usWinAscent = file.getUint16(); + if (usWinAscent === 0) { + return false; + } + os2.data[8] = os2.data[9] = 0; + return true; +} +function createOS2Table(properties, charstrings, override) { + override ||= { + unitsPerEm: 0, + yMax: 0, + yMin: 0, + ascent: 0, + descent: 0 + }; + let ulUnicodeRange1 = 0; + let ulUnicodeRange2 = 0; + let ulUnicodeRange3 = 0; + let ulUnicodeRange4 = 0; + let firstCharIndex = null; + let lastCharIndex = 0; + let position = -1; + if (charstrings) { + for (let code in charstrings) { + code |= 0; + if (firstCharIndex > code || !firstCharIndex) { + firstCharIndex = code; + } + if (lastCharIndex < code) { + lastCharIndex = code; + } + position = (0, _unicode.getUnicodeRangeFor)(code, position); + if (position < 32) { + ulUnicodeRange1 |= 1 << position; + } else if (position < 64) { + ulUnicodeRange2 |= 1 << position - 32; + } else if (position < 96) { + ulUnicodeRange3 |= 1 << position - 64; + } else if (position < 123) { + ulUnicodeRange4 |= 1 << position - 96; + } else { + throw new _util.FormatError("Unicode ranges Bits > 123 are reserved for internal usage"); + } + } + if (lastCharIndex > 0xffff) { + lastCharIndex = 0xffff; + } + } else { + firstCharIndex = 0; + lastCharIndex = 255; + } + const bbox = properties.bbox || [0, 0, 0, 0]; + const unitsPerEm = override.unitsPerEm || 1 / (properties.fontMatrix || _util.FONT_IDENTITY_MATRIX)[0]; + const scale = properties.ascentScaled ? 1.0 : unitsPerEm / PDF_GLYPH_SPACE_UNITS; + const typoAscent = override.ascent || Math.round(scale * (properties.ascent || bbox[3])); + let typoDescent = override.descent || Math.round(scale * (properties.descent || bbox[1])); + if (typoDescent > 0 && properties.descent > 0 && bbox[1] < 0) { + typoDescent = -typoDescent; + } + const winAscent = override.yMax || typoAscent; + const winDescent = -override.yMin || -typoDescent; + return "\x00\x03" + "\x02\x24" + "\x01\xF4" + "\x00\x05" + "\x00\x00" + "\x02\x8A" + "\x02\xBB" + "\x00\x00" + "\x00\x8C" + "\x02\x8A" + "\x02\xBB" + "\x00\x00" + "\x01\xDF" + "\x00\x31" + "\x01\x02" + "\x00\x00" + "\x00\x00\x06" + String.fromCharCode(properties.fixedPitch ? 0x09 : 0x00) + "\x00\x00\x00\x00\x00\x00" + (0, _util.string32)(ulUnicodeRange1) + (0, _util.string32)(ulUnicodeRange2) + (0, _util.string32)(ulUnicodeRange3) + (0, _util.string32)(ulUnicodeRange4) + "\x2A\x32\x31\x2A" + string16(properties.italicAngle ? 1 : 0) + string16(firstCharIndex || properties.firstChar) + string16(lastCharIndex || properties.lastChar) + string16(typoAscent) + string16(typoDescent) + "\x00\x64" + string16(winAscent) + string16(winDescent) + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + string16(properties.xHeight) + string16(properties.capHeight) + string16(0) + string16(firstCharIndex || properties.firstChar) + "\x00\x03"; +} +function createPostTable(properties) { + const angle = Math.floor(properties.italicAngle * 2 ** 16); + return "\x00\x03\x00\x00" + (0, _util.string32)(angle) + "\x00\x00" + "\x00\x00" + (0, _util.string32)(properties.fixedPitch ? 1 : 0) + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00"; +} +function createPostscriptName(name) { + return name.replaceAll(/[^\x21-\x7E]|[[\](){}<>/%]/g, "").slice(0, 63); +} +function createNameTable(name, proto) { + if (!proto) { + proto = [[], []]; + } + const strings = [proto[0][0] || "Original licence", proto[0][1] || name, proto[0][2] || "Unknown", proto[0][3] || "uniqueID", proto[0][4] || name, proto[0][5] || "Version 0.11", proto[0][6] || createPostscriptName(name), proto[0][7] || "Unknown", proto[0][8] || "Unknown", proto[0][9] || "Unknown"]; + const stringsUnicode = []; + let i, ii, j, jj, str; + for (i = 0, ii = strings.length; i < ii; i++) { + str = proto[1][i] || strings[i]; + const strBufUnicode = []; + for (j = 0, jj = str.length; j < jj; j++) { + strBufUnicode.push(string16(str.charCodeAt(j))); + } + stringsUnicode.push(strBufUnicode.join("")); + } + const names = [strings, stringsUnicode]; + const platforms = ["\x00\x01", "\x00\x03"]; + const encodings = ["\x00\x00", "\x00\x01"]; + const languages = ["\x00\x00", "\x04\x09"]; + const namesRecordCount = strings.length * platforms.length; + let nameTable = "\x00\x00" + string16(namesRecordCount) + string16(namesRecordCount * 12 + 6); + let strOffset = 0; + for (i = 0, ii = platforms.length; i < ii; i++) { + const strs = names[i]; + for (j = 0, jj = strs.length; j < jj; j++) { + str = strs[j]; + const nameRecord = platforms[i] + encodings[i] + languages[i] + string16(j) + string16(str.length) + string16(strOffset); + nameTable += nameRecord; + strOffset += str.length; + } + } + nameTable += strings.join("") + stringsUnicode.join(""); + return nameTable; +} +class Font { + constructor(name, file, properties) { + this.name = name; + this.psName = null; + this.mimetype = null; + this.disableFontFace = false; + this.loadedName = properties.loadedName; + this.isType3Font = properties.isType3Font; + this.missingFile = false; + this.cssFontInfo = properties.cssFontInfo; + this._charsCache = Object.create(null); + this._glyphCache = Object.create(null); + let isSerifFont = !!(properties.flags & _fonts_utils.FontFlags.Serif); + if (!isSerifFont && !properties.isSimulatedFlags) { + const baseName = name.replaceAll(/[,_]/g, "-").split("-")[0], + serifFonts = (0, _standard_fonts.getSerifFonts)(); + for (const namePart of baseName.split("+")) { + if (serifFonts[namePart]) { + isSerifFont = true; + break; + } + } + } + this.isSerifFont = isSerifFont; + this.isSymbolicFont = !!(properties.flags & _fonts_utils.FontFlags.Symbolic); + this.isMonospace = !!(properties.flags & _fonts_utils.FontFlags.FixedPitch); + let { + type, + subtype + } = properties; + this.type = type; + this.subtype = subtype; + this.systemFontInfo = properties.systemFontInfo; + const matches = name.match(/^InvalidPDFjsFont_(.*)_\d+$/); + this.isInvalidPDFjsFont = !!matches; + if (this.isInvalidPDFjsFont) { + this.fallbackName = matches[1]; + } else if (this.isMonospace) { + this.fallbackName = "monospace"; + } else if (this.isSerifFont) { + this.fallbackName = "serif"; + } else { + this.fallbackName = "sans-serif"; + } + if (this.systemFontInfo?.guessFallback) { + this.systemFontInfo.guessFallback = false; + this.systemFontInfo.css += `,${this.fallbackName}`; + } + this.differences = properties.differences; + this.widths = properties.widths; + this.defaultWidth = properties.defaultWidth; + this.composite = properties.composite; + this.cMap = properties.cMap; + this.capHeight = properties.capHeight / PDF_GLYPH_SPACE_UNITS; + this.ascent = properties.ascent / PDF_GLYPH_SPACE_UNITS; + this.descent = properties.descent / PDF_GLYPH_SPACE_UNITS; + this.lineHeight = this.ascent - this.descent; + this.fontMatrix = properties.fontMatrix; + this.bbox = properties.bbox; + this.defaultEncoding = properties.defaultEncoding; + this.toUnicode = properties.toUnicode; + this.toFontChar = []; + if (properties.type === "Type3") { + for (let charCode = 0; charCode < 256; charCode++) { + this.toFontChar[charCode] = this.differences[charCode] || properties.defaultEncoding[charCode]; + } + return; + } + this.cidEncoding = properties.cidEncoding || ""; + this.vertical = !!properties.vertical; + if (this.vertical) { + this.vmetrics = properties.vmetrics; + this.defaultVMetrics = properties.defaultVMetrics; + } + if (!file || file.isEmpty) { + if (file) { + (0, _util.warn)('Font file is empty in "' + name + '" (' + this.loadedName + ")"); + } + this.fallbackToSystemFont(properties); + return; + } + [type, subtype] = getFontFileType(file, properties); + if (type !== this.type || subtype !== this.subtype) { + (0, _util.info)("Inconsistent font file Type/SubType, expected: " + `${this.type}/${this.subtype} but found: ${type}/${subtype}.`); + } + let data; + try { + switch (type) { + case "MMType1": + (0, _util.info)("MMType1 font (" + name + "), falling back to Type1."); + case "Type1": + case "CIDFontType0": + this.mimetype = "font/opentype"; + const cff = subtype === "Type1C" || subtype === "CIDFontType0C" ? new _cff_font.CFFFont(file, properties) : new _type1_font.Type1Font(name, file, properties); + adjustWidths(properties); + data = this.convert(name, cff, properties); + break; + case "OpenType": + case "TrueType": + case "CIDFontType2": + this.mimetype = "font/opentype"; + data = this.checkAndRepair(name, file, properties); + if (this.isOpenType) { + adjustWidths(properties); + type = "OpenType"; + } + break; + default: + throw new _util.FormatError(`Font ${type} is not supported`); + } + } catch (e) { + (0, _util.warn)(e); + this.fallbackToSystemFont(properties); + return; + } + amendFallbackToUnicode(properties); + this.data = data; + this.type = type; + this.subtype = subtype; + this.fontMatrix = properties.fontMatrix; + this.widths = properties.widths; + this.defaultWidth = properties.defaultWidth; + this.toUnicode = properties.toUnicode; + this.seacMap = properties.seacMap; + } + get renderer() { + const renderer = _font_renderer.FontRendererFactory.create(this, _fonts_utils.SEAC_ANALYSIS_ENABLED); + return (0, _util.shadow)(this, "renderer", renderer); + } + exportData(extraProperties = false) { + const exportDataProperties = extraProperties ? [...EXPORT_DATA_PROPERTIES, ...EXPORT_DATA_EXTRA_PROPERTIES] : EXPORT_DATA_PROPERTIES; + const data = Object.create(null); + let property, value; + for (property of exportDataProperties) { + value = this[property]; + if (value !== undefined) { + data[property] = value; + } + } + return data; + } + fallbackToSystemFont(properties) { + this.missingFile = true; + const { + name, + type + } = this; + let fontName = (0, _fonts_utils.normalizeFontName)(name); + const stdFontMap = (0, _standard_fonts.getStdFontMap)(), + nonStdFontMap = (0, _standard_fonts.getNonStdFontMap)(); + const isStandardFont = !!stdFontMap[fontName]; + const isMappedToStandardFont = !!(nonStdFontMap[fontName] && stdFontMap[nonStdFontMap[fontName]]); + fontName = stdFontMap[fontName] || nonStdFontMap[fontName] || fontName; + const fontBasicMetricsMap = (0, _metrics.getFontBasicMetrics)(); + const metrics = fontBasicMetricsMap[fontName]; + if (metrics) { + if (isNaN(this.ascent)) { + this.ascent = metrics.ascent / PDF_GLYPH_SPACE_UNITS; + } + if (isNaN(this.descent)) { + this.descent = metrics.descent / PDF_GLYPH_SPACE_UNITS; + } + if (isNaN(this.capHeight)) { + this.capHeight = metrics.capHeight / PDF_GLYPH_SPACE_UNITS; + } + } + this.bold = /bold/gi.test(fontName); + this.italic = /oblique|italic/gi.test(fontName); + this.black = /Black/g.test(name); + const isNarrow = /Narrow/g.test(name); + this.remeasure = (!isStandardFont || isNarrow) && Object.keys(this.widths).length > 0; + if ((isStandardFont || isMappedToStandardFont) && type === "CIDFontType2" && this.cidEncoding.startsWith("Identity-")) { + const cidToGidMap = properties.cidToGidMap; + const map = []; + applyStandardFontGlyphMap(map, (0, _standard_fonts.getGlyphMapForStandardFonts)()); + if (/Arial-?Black/i.test(name)) { + applyStandardFontGlyphMap(map, (0, _standard_fonts.getSupplementalGlyphMapForArialBlack)()); + } else if (/Calibri/i.test(name)) { + applyStandardFontGlyphMap(map, (0, _standard_fonts.getSupplementalGlyphMapForCalibri)()); + } + if (cidToGidMap) { + for (const charCode in map) { + const cid = map[charCode]; + if (cidToGidMap[cid] !== undefined) { + map[+charCode] = cidToGidMap[cid]; + } + } + if (cidToGidMap.length !== this.toUnicode.length && properties.hasIncludedToUnicodeMap && this.toUnicode instanceof _to_unicode_map.IdentityToUnicodeMap) { + this.toUnicode.forEach(function (charCode, unicodeCharCode) { + const cid = map[charCode]; + if (cidToGidMap[cid] === undefined) { + map[+charCode] = unicodeCharCode; + } + }); + } + } + if (!(this.toUnicode instanceof _to_unicode_map.IdentityToUnicodeMap)) { + this.toUnicode.forEach(function (charCode, unicodeCharCode) { + map[+charCode] = unicodeCharCode; + }); + } + this.toFontChar = map; + this.toUnicode = new _to_unicode_map.ToUnicodeMap(map); + } else if (/Symbol/i.test(fontName)) { + this.toFontChar = buildToFontChar(_encodings.SymbolSetEncoding, (0, _glyphlist.getGlyphsUnicode)(), this.differences); + } else if (/Dingbats/i.test(fontName)) { + this.toFontChar = buildToFontChar(_encodings.ZapfDingbatsEncoding, (0, _glyphlist.getDingbatsGlyphsUnicode)(), this.differences); + } else if (isStandardFont) { + const map = buildToFontChar(this.defaultEncoding, (0, _glyphlist.getGlyphsUnicode)(), this.differences); + if (type === "CIDFontType2" && !this.cidEncoding.startsWith("Identity-") && !(this.toUnicode instanceof _to_unicode_map.IdentityToUnicodeMap)) { + this.toUnicode.forEach(function (charCode, unicodeCharCode) { + map[+charCode] = unicodeCharCode; + }); + } + this.toFontChar = map; + } else { + const glyphsUnicodeMap = (0, _glyphlist.getGlyphsUnicode)(); + const map = []; + this.toUnicode.forEach((charCode, unicodeCharCode) => { + if (!this.composite) { + const glyphName = this.differences[charCode] || this.defaultEncoding[charCode]; + const unicode = (0, _unicode.getUnicodeForGlyph)(glyphName, glyphsUnicodeMap); + if (unicode !== -1) { + unicodeCharCode = unicode; + } + } + map[+charCode] = unicodeCharCode; + }); + if (this.composite && this.toUnicode instanceof _to_unicode_map.IdentityToUnicodeMap) { + if (/Tahoma|Verdana/i.test(name)) { + applyStandardFontGlyphMap(map, (0, _standard_fonts.getGlyphMapForStandardFonts)()); + } + } + this.toFontChar = map; + } + amendFallbackToUnicode(properties); + this.loadedName = fontName.split("-")[0]; + } + checkAndRepair(name, font, properties) { + const VALID_TABLES = ["OS/2", "cmap", "head", "hhea", "hmtx", "maxp", "name", "post", "loca", "glyf", "fpgm", "prep", "cvt ", "CFF "]; + function readTables(file, numTables) { + const tables = Object.create(null); + tables["OS/2"] = null; + tables.cmap = null; + tables.head = null; + tables.hhea = null; + tables.hmtx = null; + tables.maxp = null; + tables.name = null; + tables.post = null; + for (let i = 0; i < numTables; i++) { + const table = readTableEntry(file); + if (!VALID_TABLES.includes(table.tag)) { + continue; + } + if (table.length === 0) { + continue; + } + tables[table.tag] = table; + } + return tables; + } + function readTableEntry(file) { + const tag = file.getString(4); + const checksum = file.getInt32() >>> 0; + const offset = file.getInt32() >>> 0; + const length = file.getInt32() >>> 0; + const previousPosition = file.pos; + file.pos = file.start || 0; + file.skip(offset); + const data = file.getBytes(length); + file.pos = previousPosition; + if (tag === "head") { + data[8] = data[9] = data[10] = data[11] = 0; + data[17] |= 0x20; + } + return { + tag, + checksum, + length, + offset, + data + }; + } + function readOpenTypeHeader(ttf) { + return { + version: ttf.getString(4), + numTables: ttf.getUint16(), + searchRange: ttf.getUint16(), + entrySelector: ttf.getUint16(), + rangeShift: ttf.getUint16() + }; + } + function readTrueTypeCollectionHeader(ttc) { + const ttcTag = ttc.getString(4); + (0, _util.assert)(ttcTag === "ttcf", "Must be a TrueType Collection font."); + const majorVersion = ttc.getUint16(); + const minorVersion = ttc.getUint16(); + const numFonts = ttc.getInt32() >>> 0; + const offsetTable = []; + for (let i = 0; i < numFonts; i++) { + offsetTable.push(ttc.getInt32() >>> 0); + } + const header = { + ttcTag, + majorVersion, + minorVersion, + numFonts, + offsetTable + }; + switch (majorVersion) { + case 1: + return header; + case 2: + header.dsigTag = ttc.getInt32() >>> 0; + header.dsigLength = ttc.getInt32() >>> 0; + header.dsigOffset = ttc.getInt32() >>> 0; + return header; + } + throw new _util.FormatError(`Invalid TrueType Collection majorVersion: ${majorVersion}.`); + } + function readTrueTypeCollectionData(ttc, fontName) { + const { + numFonts, + offsetTable + } = readTrueTypeCollectionHeader(ttc); + const fontNameParts = fontName.split("+"); + let fallbackData; + for (let i = 0; i < numFonts; i++) { + ttc.pos = (ttc.start || 0) + offsetTable[i]; + const potentialHeader = readOpenTypeHeader(ttc); + const potentialTables = readTables(ttc, potentialHeader.numTables); + if (!potentialTables.name) { + throw new _util.FormatError('TrueType Collection font must contain a "name" table.'); + } + const [nameTable] = readNameTable(potentialTables.name); + for (let j = 0, jj = nameTable.length; j < jj; j++) { + for (let k = 0, kk = nameTable[j].length; k < kk; k++) { + const nameEntry = nameTable[j][k]?.replaceAll(/\s/g, ""); + if (!nameEntry) { + continue; + } + if (nameEntry === fontName) { + return { + header: potentialHeader, + tables: potentialTables + }; + } + if (fontNameParts.length < 2) { + continue; + } + for (const part of fontNameParts) { + if (nameEntry === part) { + fallbackData = { + name: part, + header: potentialHeader, + tables: potentialTables + }; + } + } + } + } + } + if (fallbackData) { + (0, _util.warn)(`TrueType Collection does not contain "${fontName}" font, ` + `falling back to "${fallbackData.name}" font instead.`); + return { + header: fallbackData.header, + tables: fallbackData.tables + }; + } + throw new _util.FormatError(`TrueType Collection does not contain "${fontName}" font.`); + } + function readCmapTable(cmap, file, isSymbolicFont, hasEncoding) { + if (!cmap) { + (0, _util.warn)("No cmap table available."); + return { + platformId: -1, + encodingId: -1, + mappings: [], + hasShortCmap: false + }; + } + let segment; + let start = (file.start || 0) + cmap.offset; + file.pos = start; + file.skip(2); + const numTables = file.getUint16(); + let potentialTable; + let canBreak = false; + for (let i = 0; i < numTables; i++) { + const platformId = file.getUint16(); + const encodingId = file.getUint16(); + const offset = file.getInt32() >>> 0; + let useTable = false; + if (potentialTable?.platformId === platformId && potentialTable?.encodingId === encodingId) { + continue; + } + if (platformId === 0 && (encodingId === 0 || encodingId === 1 || encodingId === 3)) { + useTable = true; + } else if (platformId === 1 && encodingId === 0) { + useTable = true; + } else if (platformId === 3 && encodingId === 1 && (hasEncoding || !potentialTable)) { + useTable = true; + if (!isSymbolicFont) { + canBreak = true; + } + } else if (isSymbolicFont && platformId === 3 && encodingId === 0) { + useTable = true; + let correctlySorted = true; + if (i < numTables - 1) { + const nextBytes = file.peekBytes(2), + nextPlatformId = int16(nextBytes[0], nextBytes[1]); + if (nextPlatformId < platformId) { + correctlySorted = false; + } + } + if (correctlySorted) { + canBreak = true; + } + } + if (useTable) { + potentialTable = { + platformId, + encodingId, + offset + }; + } + if (canBreak) { + break; + } + } + if (potentialTable) { + file.pos = start + potentialTable.offset; + } + if (!potentialTable || file.peekByte() === -1) { + (0, _util.warn)("Could not find a preferred cmap table."); + return { + platformId: -1, + encodingId: -1, + mappings: [], + hasShortCmap: false + }; + } + const format = file.getUint16(); + let hasShortCmap = false; + const mappings = []; + let j, glyphId; + if (format === 0) { + file.skip(2 + 2); + for (j = 0; j < 256; j++) { + const index = file.getByte(); + if (!index) { + continue; + } + mappings.push({ + charCode: j, + glyphId: index + }); + } + hasShortCmap = true; + } else if (format === 2) { + file.skip(2 + 2); + const subHeaderKeys = []; + let maxSubHeaderKey = 0; + for (let i = 0; i < 256; i++) { + const subHeaderKey = file.getUint16() >> 3; + subHeaderKeys.push(subHeaderKey); + maxSubHeaderKey = Math.max(subHeaderKey, maxSubHeaderKey); + } + const subHeaders = []; + for (let i = 0; i <= maxSubHeaderKey; i++) { + subHeaders.push({ + firstCode: file.getUint16(), + entryCount: file.getUint16(), + idDelta: signedInt16(file.getByte(), file.getByte()), + idRangePos: file.pos + file.getUint16() + }); + } + for (let i = 0; i < 256; i++) { + if (subHeaderKeys[i] === 0) { + file.pos = subHeaders[0].idRangePos + 2 * i; + glyphId = file.getUint16(); + mappings.push({ + charCode: i, + glyphId + }); + } else { + const s = subHeaders[subHeaderKeys[i]]; + for (j = 0; j < s.entryCount; j++) { + const charCode = (i << 8) + j + s.firstCode; + file.pos = s.idRangePos + 2 * j; + glyphId = file.getUint16(); + if (glyphId !== 0) { + glyphId = (glyphId + s.idDelta) % 65536; + } + mappings.push({ + charCode, + glyphId + }); + } + } + } + } else if (format === 4) { + file.skip(2 + 2); + const segCount = file.getUint16() >> 1; + file.skip(6); + const segments = []; + let segIndex; + for (segIndex = 0; segIndex < segCount; segIndex++) { + segments.push({ + end: file.getUint16() + }); + } + file.skip(2); + for (segIndex = 0; segIndex < segCount; segIndex++) { + segments[segIndex].start = file.getUint16(); + } + for (segIndex = 0; segIndex < segCount; segIndex++) { + segments[segIndex].delta = file.getUint16(); + } + let offsetsCount = 0, + offsetIndex; + for (segIndex = 0; segIndex < segCount; segIndex++) { + segment = segments[segIndex]; + const rangeOffset = file.getUint16(); + if (!rangeOffset) { + segment.offsetIndex = -1; + continue; + } + offsetIndex = (rangeOffset >> 1) - (segCount - segIndex); + segment.offsetIndex = offsetIndex; + offsetsCount = Math.max(offsetsCount, offsetIndex + segment.end - segment.start + 1); + } + const offsets = []; + for (j = 0; j < offsetsCount; j++) { + offsets.push(file.getUint16()); + } + for (segIndex = 0; segIndex < segCount; segIndex++) { + segment = segments[segIndex]; + start = segment.start; + const end = segment.end; + const delta = segment.delta; + offsetIndex = segment.offsetIndex; + for (j = start; j <= end; j++) { + if (j === 0xffff) { + continue; + } + glyphId = offsetIndex < 0 ? j : offsets[offsetIndex + j - start]; + glyphId = glyphId + delta & 0xffff; + mappings.push({ + charCode: j, + glyphId + }); + } + } + } else if (format === 6) { + file.skip(2 + 2); + const firstCode = file.getUint16(); + const entryCount = file.getUint16(); + for (j = 0; j < entryCount; j++) { + glyphId = file.getUint16(); + const charCode = firstCode + j; + mappings.push({ + charCode, + glyphId + }); + } + } else if (format === 12) { + file.skip(2 + 4 + 4); + const nGroups = file.getInt32() >>> 0; + for (j = 0; j < nGroups; j++) { + const startCharCode = file.getInt32() >>> 0; + const endCharCode = file.getInt32() >>> 0; + let glyphCode = file.getInt32() >>> 0; + for (let charCode = startCharCode; charCode <= endCharCode; charCode++) { + mappings.push({ + charCode, + glyphId: glyphCode++ + }); + } + } + } else { + (0, _util.warn)("cmap table has unsupported format: " + format); + return { + platformId: -1, + encodingId: -1, + mappings: [], + hasShortCmap: false + }; + } + mappings.sort(function (a, b) { + return a.charCode - b.charCode; + }); + for (let i = 1; i < mappings.length; i++) { + if (mappings[i - 1].charCode === mappings[i].charCode) { + mappings.splice(i, 1); + i--; + } + } + return { + platformId: potentialTable.platformId, + encodingId: potentialTable.encodingId, + mappings, + hasShortCmap + }; + } + function sanitizeMetrics(file, header, metrics, headTable, numGlyphs, dupFirstEntry) { + if (!header) { + if (metrics) { + metrics.data = null; + } + return; + } + file.pos = (file.start || 0) + header.offset; + file.pos += 4; + file.pos += 2; + file.pos += 2; + file.pos += 2; + file.pos += 2; + file.pos += 2; + file.pos += 2; + file.pos += 2; + file.pos += 2; + file.pos += 2; + const caretOffset = file.getUint16(); + file.pos += 8; + file.pos += 2; + let numOfMetrics = file.getUint16(); + if (caretOffset !== 0) { + const macStyle = int16(headTable.data[44], headTable.data[45]); + if (!(macStyle & 2)) { + header.data[22] = 0; + header.data[23] = 0; + } + } + if (numOfMetrics > numGlyphs) { + (0, _util.info)(`The numOfMetrics (${numOfMetrics}) should not be ` + `greater than the numGlyphs (${numGlyphs}).`); + numOfMetrics = numGlyphs; + header.data[34] = (numOfMetrics & 0xff00) >> 8; + header.data[35] = numOfMetrics & 0x00ff; + } + const numOfSidebearings = numGlyphs - numOfMetrics; + const numMissing = numOfSidebearings - (metrics.length - numOfMetrics * 4 >> 1); + if (numMissing > 0) { + const entries = new Uint8Array(metrics.length + numMissing * 2); + entries.set(metrics.data); + if (dupFirstEntry) { + entries[metrics.length] = metrics.data[2]; + entries[metrics.length + 1] = metrics.data[3]; + } + metrics.data = entries; + } + } + function sanitizeGlyph(source, sourceStart, sourceEnd, dest, destStart, hintsValid) { + const glyphProfile = { + length: 0, + sizeOfInstructions: 0 + }; + if (sourceStart < 0 || sourceStart >= source.length || sourceEnd > source.length || sourceEnd - sourceStart <= 12) { + return glyphProfile; + } + const glyf = source.subarray(sourceStart, sourceEnd); + const xMin = signedInt16(glyf[2], glyf[3]); + const yMin = signedInt16(glyf[4], glyf[5]); + const xMax = signedInt16(glyf[6], glyf[7]); + const yMax = signedInt16(glyf[8], glyf[9]); + if (xMin > xMax) { + writeSignedInt16(glyf, 2, xMax); + writeSignedInt16(glyf, 6, xMin); + } + if (yMin > yMax) { + writeSignedInt16(glyf, 4, yMax); + writeSignedInt16(glyf, 8, yMin); + } + const contoursCount = signedInt16(glyf[0], glyf[1]); + if (contoursCount < 0) { + if (contoursCount < -1) { + return glyphProfile; + } + dest.set(glyf, destStart); + glyphProfile.length = glyf.length; + return glyphProfile; + } + let i, + j = 10, + flagsCount = 0; + for (i = 0; i < contoursCount; i++) { + const endPoint = glyf[j] << 8 | glyf[j + 1]; + flagsCount = endPoint + 1; + j += 2; + } + const instructionsStart = j; + const instructionsLength = glyf[j] << 8 | glyf[j + 1]; + glyphProfile.sizeOfInstructions = instructionsLength; + j += 2 + instructionsLength; + const instructionsEnd = j; + let coordinatesLength = 0; + for (i = 0; i < flagsCount; i++) { + const flag = glyf[j++]; + if (flag & 0xc0) { + glyf[j - 1] = flag & 0x3f; + } + let xLength = 2; + if (flag & 2) { + xLength = 1; + } else if (flag & 16) { + xLength = 0; + } + let yLength = 2; + if (flag & 4) { + yLength = 1; + } else if (flag & 32) { + yLength = 0; + } + const xyLength = xLength + yLength; + coordinatesLength += xyLength; + if (flag & 8) { + const repeat = glyf[j++]; + if (repeat === 0) { + glyf[j - 1] ^= 8; + } + i += repeat; + coordinatesLength += repeat * xyLength; + } + } + if (coordinatesLength === 0) { + return glyphProfile; + } + let glyphDataLength = j + coordinatesLength; + if (glyphDataLength > glyf.length) { + return glyphProfile; + } + if (!hintsValid && instructionsLength > 0) { + dest.set(glyf.subarray(0, instructionsStart), destStart); + dest.set([0, 0], destStart + instructionsStart); + dest.set(glyf.subarray(instructionsEnd, glyphDataLength), destStart + instructionsStart + 2); + glyphDataLength -= instructionsLength; + if (glyf.length - glyphDataLength > 3) { + glyphDataLength = glyphDataLength + 3 & ~3; + } + glyphProfile.length = glyphDataLength; + return glyphProfile; + } + if (glyf.length - glyphDataLength > 3) { + glyphDataLength = glyphDataLength + 3 & ~3; + dest.set(glyf.subarray(0, glyphDataLength), destStart); + glyphProfile.length = glyphDataLength; + return glyphProfile; + } + dest.set(glyf, destStart); + glyphProfile.length = glyf.length; + return glyphProfile; + } + function sanitizeHead(head, numGlyphs, locaLength) { + const data = head.data; + const version = int32(data[0], data[1], data[2], data[3]); + if (version >> 16 !== 1) { + (0, _util.info)("Attempting to fix invalid version in head table: " + version); + data[0] = 0; + data[1] = 1; + data[2] = 0; + data[3] = 0; + } + const indexToLocFormat = int16(data[50], data[51]); + if (indexToLocFormat < 0 || indexToLocFormat > 1) { + (0, _util.info)("Attempting to fix invalid indexToLocFormat in head table: " + indexToLocFormat); + const numGlyphsPlusOne = numGlyphs + 1; + if (locaLength === numGlyphsPlusOne << 1) { + data[50] = 0; + data[51] = 0; + } else if (locaLength === numGlyphsPlusOne << 2) { + data[50] = 0; + data[51] = 1; + } else { + throw new _util.FormatError("Could not fix indexToLocFormat: " + indexToLocFormat); + } + } + } + function sanitizeGlyphLocations(loca, glyf, numGlyphs, isGlyphLocationsLong, hintsValid, dupFirstEntry, maxSizeOfInstructions) { + let itemSize, itemDecode, itemEncode; + if (isGlyphLocationsLong) { + itemSize = 4; + itemDecode = function fontItemDecodeLong(data, offset) { + return data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]; + }; + itemEncode = function fontItemEncodeLong(data, offset, value) { + data[offset] = value >>> 24 & 0xff; + data[offset + 1] = value >> 16 & 0xff; + data[offset + 2] = value >> 8 & 0xff; + data[offset + 3] = value & 0xff; + }; + } else { + itemSize = 2; + itemDecode = function fontItemDecode(data, offset) { + return data[offset] << 9 | data[offset + 1] << 1; + }; + itemEncode = function fontItemEncode(data, offset, value) { + data[offset] = value >> 9 & 0xff; + data[offset + 1] = value >> 1 & 0xff; + }; + } + const numGlyphsOut = dupFirstEntry ? numGlyphs + 1 : numGlyphs; + const locaDataSize = itemSize * (1 + numGlyphsOut); + const locaData = new Uint8Array(locaDataSize); + locaData.set(loca.data.subarray(0, locaDataSize)); + loca.data = locaData; + const oldGlyfData = glyf.data; + const oldGlyfDataLength = oldGlyfData.length; + const newGlyfData = new Uint8Array(oldGlyfDataLength); + let i, j; + const locaEntries = []; + for (i = 0, j = 0; i < numGlyphs + 1; i++, j += itemSize) { + let offset = itemDecode(locaData, j); + if (offset > oldGlyfDataLength) { + offset = oldGlyfDataLength; + } + locaEntries.push({ + index: i, + offset, + endOffset: 0 + }); + } + locaEntries.sort((a, b) => { + return a.offset - b.offset; + }); + for (i = 0; i < numGlyphs; i++) { + locaEntries[i].endOffset = locaEntries[i + 1].offset; + } + locaEntries.sort((a, b) => { + return a.index - b.index; + }); + for (i = 0; i < numGlyphs; i++) { + const { + offset, + endOffset + } = locaEntries[i]; + if (offset !== 0 || endOffset !== 0) { + break; + } + const nextOffset = locaEntries[i + 1].offset; + if (nextOffset === 0) { + continue; + } + locaEntries[i].endOffset = nextOffset; + break; + } + const missingGlyphs = Object.create(null); + let writeOffset = 0; + itemEncode(locaData, 0, writeOffset); + for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) { + const glyphProfile = sanitizeGlyph(oldGlyfData, locaEntries[i].offset, locaEntries[i].endOffset, newGlyfData, writeOffset, hintsValid); + const newLength = glyphProfile.length; + if (newLength === 0) { + missingGlyphs[i] = true; + } + if (glyphProfile.sizeOfInstructions > maxSizeOfInstructions) { + maxSizeOfInstructions = glyphProfile.sizeOfInstructions; + } + writeOffset += newLength; + itemEncode(locaData, j, writeOffset); + } + if (writeOffset === 0) { + const simpleGlyph = new Uint8Array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]); + for (i = 0, j = itemSize; i < numGlyphsOut; i++, j += itemSize) { + itemEncode(locaData, j, simpleGlyph.length); + } + glyf.data = simpleGlyph; + } else if (dupFirstEntry) { + const firstEntryLength = itemDecode(locaData, itemSize); + if (newGlyfData.length > firstEntryLength + writeOffset) { + glyf.data = newGlyfData.subarray(0, firstEntryLength + writeOffset); + } else { + glyf.data = new Uint8Array(firstEntryLength + writeOffset); + glyf.data.set(newGlyfData.subarray(0, writeOffset)); + } + glyf.data.set(newGlyfData.subarray(0, firstEntryLength), writeOffset); + itemEncode(loca.data, locaData.length - itemSize, writeOffset + firstEntryLength); + } else { + glyf.data = newGlyfData.subarray(0, writeOffset); + } + return { + missingGlyphs, + maxSizeOfInstructions + }; + } + function readPostScriptTable(post, propertiesObj, maxpNumGlyphs) { + const start = (font.start || 0) + post.offset; + font.pos = start; + const length = post.length, + end = start + length; + const version = font.getInt32(); + font.skip(28); + let glyphNames; + let valid = true; + let i; + switch (version) { + case 0x00010000: + glyphNames = _fonts_utils.MacStandardGlyphOrdering; + break; + case 0x00020000: + const numGlyphs = font.getUint16(); + if (numGlyphs !== maxpNumGlyphs) { + valid = false; + break; + } + const glyphNameIndexes = []; + for (i = 0; i < numGlyphs; ++i) { + const index = font.getUint16(); + if (index >= 32768) { + valid = false; + break; + } + glyphNameIndexes.push(index); + } + if (!valid) { + break; + } + const customNames = [], + strBuf = []; + while (font.pos < end) { + const stringLength = font.getByte(); + strBuf.length = stringLength; + for (i = 0; i < stringLength; ++i) { + strBuf[i] = String.fromCharCode(font.getByte()); + } + customNames.push(strBuf.join("")); + } + glyphNames = []; + for (i = 0; i < numGlyphs; ++i) { + const j = glyphNameIndexes[i]; + if (j < 258) { + glyphNames.push(_fonts_utils.MacStandardGlyphOrdering[j]); + continue; + } + glyphNames.push(customNames[j - 258]); + } + break; + case 0x00030000: + break; + default: + (0, _util.warn)("Unknown/unsupported post table version " + version); + valid = false; + if (propertiesObj.defaultEncoding) { + glyphNames = propertiesObj.defaultEncoding; + } + break; + } + propertiesObj.glyphNames = glyphNames; + return valid; + } + function readNameTable(nameTable) { + const start = (font.start || 0) + nameTable.offset; + font.pos = start; + const names = [[], []], + records = []; + const length = nameTable.length, + end = start + length; + const format = font.getUint16(); + const FORMAT_0_HEADER_LENGTH = 6; + if (format !== 0 || length < FORMAT_0_HEADER_LENGTH) { + return [names, records]; + } + const numRecords = font.getUint16(); + const stringsStart = font.getUint16(); + const NAME_RECORD_LENGTH = 12; + let i, ii; + for (i = 0; i < numRecords && font.pos + NAME_RECORD_LENGTH <= end; i++) { + const r = { + platform: font.getUint16(), + encoding: font.getUint16(), + language: font.getUint16(), + name: font.getUint16(), + length: font.getUint16(), + offset: font.getUint16() + }; + if (isMacNameRecord(r) || isWinNameRecord(r)) { + records.push(r); + } + } + for (i = 0, ii = records.length; i < ii; i++) { + const record = records[i]; + if (record.length <= 0) { + continue; + } + const pos = start + stringsStart + record.offset; + if (pos + record.length > end) { + continue; + } + font.pos = pos; + const nameIndex = record.name; + if (record.encoding) { + let str = ""; + for (let j = 0, jj = record.length; j < jj; j += 2) { + str += String.fromCharCode(font.getUint16()); + } + names[1][nameIndex] = str; + } else { + names[0][nameIndex] = font.getString(record.length); + } + } + return [names, records]; + } + const TTOpsStackDeltas = [0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, -2, -5, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, 1, -1, -999, 0, 1, 0, -1, -2, 0, -1, -2, -1, -1, 0, -1, -1, 0, 0, -999, -999, -1, -1, -1, -1, -2, -999, -2, -2, -999, 0, -2, -2, 0, 0, -2, 0, -2, 0, 0, 0, -2, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, -999, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -999, -999, -999, -999, -999, -1, -1, -2, -2, 0, 0, 0, 0, -1, -1, -999, -2, -2, 0, 0, -1, -2, -2, 0, 0, 0, -1, -1, -1, -2]; + function sanitizeTTProgram(table, ttContext) { + let data = table.data; + let i = 0, + j, + n, + b, + funcId, + pc, + lastEndf = 0, + lastDeff = 0; + const stack = []; + const callstack = []; + const functionsCalled = []; + let tooComplexToFollowFunctions = ttContext.tooComplexToFollowFunctions; + let inFDEF = false, + ifLevel = 0, + inELSE = 0; + for (let ii = data.length; i < ii;) { + const op = data[i++]; + if (op === 0x40) { + n = data[i++]; + if (inFDEF || inELSE) { + i += n; + } else { + for (j = 0; j < n; j++) { + stack.push(data[i++]); + } + } + } else if (op === 0x41) { + n = data[i++]; + if (inFDEF || inELSE) { + i += n * 2; + } else { + for (j = 0; j < n; j++) { + b = data[i++]; + stack.push(b << 8 | data[i++]); + } + } + } else if ((op & 0xf8) === 0xb0) { + n = op - 0xb0 + 1; + if (inFDEF || inELSE) { + i += n; + } else { + for (j = 0; j < n; j++) { + stack.push(data[i++]); + } + } + } else if ((op & 0xf8) === 0xb8) { + n = op - 0xb8 + 1; + if (inFDEF || inELSE) { + i += n * 2; + } else { + for (j = 0; j < n; j++) { + b = data[i++]; + stack.push(b << 8 | data[i++]); + } + } + } else if (op === 0x2b && !tooComplexToFollowFunctions) { + if (!inFDEF && !inELSE) { + funcId = stack.at(-1); + if (isNaN(funcId)) { + (0, _util.info)("TT: CALL empty stack (or invalid entry)."); + } else { + ttContext.functionsUsed[funcId] = true; + if (funcId in ttContext.functionsStackDeltas) { + const newStackLength = stack.length + ttContext.functionsStackDeltas[funcId]; + if (newStackLength < 0) { + (0, _util.warn)("TT: CALL invalid functions stack delta."); + ttContext.hintsValid = false; + return; + } + stack.length = newStackLength; + } else if (funcId in ttContext.functionsDefined && !functionsCalled.includes(funcId)) { + callstack.push({ + data, + i, + stackTop: stack.length - 1 + }); + functionsCalled.push(funcId); + pc = ttContext.functionsDefined[funcId]; + if (!pc) { + (0, _util.warn)("TT: CALL non-existent function"); + ttContext.hintsValid = false; + return; + } + data = pc.data; + i = pc.i; + } + } + } + } else if (op === 0x2c && !tooComplexToFollowFunctions) { + if (inFDEF || inELSE) { + (0, _util.warn)("TT: nested FDEFs not allowed"); + tooComplexToFollowFunctions = true; + } + inFDEF = true; + lastDeff = i; + funcId = stack.pop(); + ttContext.functionsDefined[funcId] = { + data, + i + }; + } else if (op === 0x2d) { + if (inFDEF) { + inFDEF = false; + lastEndf = i; + } else { + pc = callstack.pop(); + if (!pc) { + (0, _util.warn)("TT: ENDF bad stack"); + ttContext.hintsValid = false; + return; + } + funcId = functionsCalled.pop(); + data = pc.data; + i = pc.i; + ttContext.functionsStackDeltas[funcId] = stack.length - pc.stackTop; + } + } else if (op === 0x89) { + if (inFDEF || inELSE) { + (0, _util.warn)("TT: nested IDEFs not allowed"); + tooComplexToFollowFunctions = true; + } + inFDEF = true; + lastDeff = i; + } else if (op === 0x58) { + ++ifLevel; + } else if (op === 0x1b) { + inELSE = ifLevel; + } else if (op === 0x59) { + if (inELSE === ifLevel) { + inELSE = 0; + } + --ifLevel; + } else if (op === 0x1c) { + if (!inFDEF && !inELSE) { + const offset = stack.at(-1); + if (offset > 0) { + i += offset - 1; + } + } + } + if (!inFDEF && !inELSE) { + let stackDelta = 0; + if (op <= 0x8e) { + stackDelta = TTOpsStackDeltas[op]; + } else if (op >= 0xc0 && op <= 0xdf) { + stackDelta = -1; + } else if (op >= 0xe0) { + stackDelta = -2; + } + if (op >= 0x71 && op <= 0x75) { + n = stack.pop(); + if (!isNaN(n)) { + stackDelta = -n * 2; + } + } + while (stackDelta < 0 && stack.length > 0) { + stack.pop(); + stackDelta++; + } + while (stackDelta > 0) { + stack.push(NaN); + stackDelta--; + } + } + } + ttContext.tooComplexToFollowFunctions = tooComplexToFollowFunctions; + const content = [data]; + if (i > data.length) { + content.push(new Uint8Array(i - data.length)); + } + if (lastDeff > lastEndf) { + (0, _util.warn)("TT: complementing a missing function tail"); + content.push(new Uint8Array([0x22, 0x2d])); + } + foldTTTable(table, content); + } + function checkInvalidFunctions(ttContext, maxFunctionDefs) { + if (ttContext.tooComplexToFollowFunctions) { + return; + } + if (ttContext.functionsDefined.length > maxFunctionDefs) { + (0, _util.warn)("TT: more functions defined than expected"); + ttContext.hintsValid = false; + return; + } + for (let j = 0, jj = ttContext.functionsUsed.length; j < jj; j++) { + if (j > maxFunctionDefs) { + (0, _util.warn)("TT: invalid function id: " + j); + ttContext.hintsValid = false; + return; + } + if (ttContext.functionsUsed[j] && !ttContext.functionsDefined[j]) { + (0, _util.warn)("TT: undefined function: " + j); + ttContext.hintsValid = false; + return; + } + } + } + function foldTTTable(table, content) { + if (content.length > 1) { + let newLength = 0; + let j, jj; + for (j = 0, jj = content.length; j < jj; j++) { + newLength += content[j].length; + } + newLength = newLength + 3 & ~3; + const result = new Uint8Array(newLength); + let pos = 0; + for (j = 0, jj = content.length; j < jj; j++) { + result.set(content[j], pos); + pos += content[j].length; + } + table.data = result; + table.length = newLength; + } + } + function sanitizeTTPrograms(fpgm, prep, cvt, maxFunctionDefs) { + const ttContext = { + functionsDefined: [], + functionsUsed: [], + functionsStackDeltas: [], + tooComplexToFollowFunctions: false, + hintsValid: true + }; + if (fpgm) { + sanitizeTTProgram(fpgm, ttContext); + } + if (prep) { + sanitizeTTProgram(prep, ttContext); + } + if (fpgm) { + checkInvalidFunctions(ttContext, maxFunctionDefs); + } + if (cvt && cvt.length & 1) { + const cvtData = new Uint8Array(cvt.length + 1); + cvtData.set(cvt.data); + cvt.data = cvtData; + } + return ttContext.hintsValid; + } + font = new _stream.Stream(new Uint8Array(font.getBytes())); + let header, tables; + if (isTrueTypeCollectionFile(font)) { + const ttcData = readTrueTypeCollectionData(font, this.name); + header = ttcData.header; + tables = ttcData.tables; + } else { + header = readOpenTypeHeader(font); + tables = readTables(font, header.numTables); + } + let cff, cffFile; + const isTrueType = !tables["CFF "]; + if (!isTrueType) { + const isComposite = properties.composite && (properties.cidToGidMap?.length > 0 || !(properties.cMap instanceof _cmap.IdentityCMap)); + if (header.version === "OTTO" && !isComposite || !tables.head || !tables.hhea || !tables.maxp || !tables.post) { + cffFile = new _stream.Stream(tables["CFF "].data); + cff = new _cff_font.CFFFont(cffFile, properties); + adjustWidths(properties); + return this.convert(name, cff, properties); + } + delete tables.glyf; + delete tables.loca; + delete tables.fpgm; + delete tables.prep; + delete tables["cvt "]; + this.isOpenType = true; + } else { + if (!tables.loca) { + throw new _util.FormatError('Required "loca" table is not found'); + } + if (!tables.glyf) { + (0, _util.warn)('Required "glyf" table is not found -- trying to recover.'); + tables.glyf = { + tag: "glyf", + data: new Uint8Array(0) + }; + } + this.isOpenType = false; + } + if (!tables.maxp) { + throw new _util.FormatError('Required "maxp" table is not found'); + } + font.pos = (font.start || 0) + tables.maxp.offset; + const version = font.getInt32(); + const numGlyphs = font.getUint16(); + if (properties.scaleFactors?.length === numGlyphs && isTrueType) { + const { + scaleFactors + } = properties; + const isGlyphLocationsLong = int16(tables.head.data[50], tables.head.data[51]); + const glyphs = new _glyf.GlyfTable({ + glyfTable: tables.glyf.data, + isGlyphLocationsLong, + locaTable: tables.loca.data, + numGlyphs + }); + glyphs.scale(scaleFactors); + const { + glyf, + loca, + isLocationLong + } = glyphs.write(); + tables.glyf.data = glyf; + tables.loca.data = loca; + if (isLocationLong !== !!isGlyphLocationsLong) { + tables.head.data[50] = 0; + tables.head.data[51] = isLocationLong ? 1 : 0; + } + const metrics = tables.hmtx.data; + for (let i = 0; i < numGlyphs; i++) { + const j = 4 * i; + const advanceWidth = Math.round(scaleFactors[i] * int16(metrics[j], metrics[j + 1])); + metrics[j] = advanceWidth >> 8 & 0xff; + metrics[j + 1] = advanceWidth & 0xff; + const lsb = Math.round(scaleFactors[i] * signedInt16(metrics[j + 2], metrics[j + 3])); + writeSignedInt16(metrics, j + 2, lsb); + } + } + let numGlyphsOut = numGlyphs + 1; + let dupFirstEntry = true; + if (numGlyphsOut > 0xffff) { + dupFirstEntry = false; + numGlyphsOut = numGlyphs; + (0, _util.warn)("Not enough space in glyfs to duplicate first glyph."); + } + let maxFunctionDefs = 0; + let maxSizeOfInstructions = 0; + if (version >= 0x00010000 && tables.maxp.length >= 22) { + font.pos += 8; + const maxZones = font.getUint16(); + if (maxZones > 2) { + tables.maxp.data[14] = 0; + tables.maxp.data[15] = 2; + } + font.pos += 4; + maxFunctionDefs = font.getUint16(); + font.pos += 4; + maxSizeOfInstructions = font.getUint16(); + } + tables.maxp.data[4] = numGlyphsOut >> 8; + tables.maxp.data[5] = numGlyphsOut & 255; + const hintsValid = sanitizeTTPrograms(tables.fpgm, tables.prep, tables["cvt "], maxFunctionDefs); + if (!hintsValid) { + delete tables.fpgm; + delete tables.prep; + delete tables["cvt "]; + } + sanitizeMetrics(font, tables.hhea, tables.hmtx, tables.head, numGlyphsOut, dupFirstEntry); + if (!tables.head) { + throw new _util.FormatError('Required "head" table is not found'); + } + sanitizeHead(tables.head, numGlyphs, isTrueType ? tables.loca.length : 0); + let missingGlyphs = Object.create(null); + if (isTrueType) { + const isGlyphLocationsLong = int16(tables.head.data[50], tables.head.data[51]); + const glyphsInfo = sanitizeGlyphLocations(tables.loca, tables.glyf, numGlyphs, isGlyphLocationsLong, hintsValid, dupFirstEntry, maxSizeOfInstructions); + missingGlyphs = glyphsInfo.missingGlyphs; + if (version >= 0x00010000 && tables.maxp.length >= 22) { + tables.maxp.data[26] = glyphsInfo.maxSizeOfInstructions >> 8; + tables.maxp.data[27] = glyphsInfo.maxSizeOfInstructions & 255; + } + } + if (!tables.hhea) { + throw new _util.FormatError('Required "hhea" table is not found'); + } + if (tables.hhea.data[10] === 0 && tables.hhea.data[11] === 0) { + tables.hhea.data[10] = 0xff; + tables.hhea.data[11] = 0xff; + } + const metricsOverride = { + unitsPerEm: int16(tables.head.data[18], tables.head.data[19]), + yMax: signedInt16(tables.head.data[42], tables.head.data[43]), + yMin: signedInt16(tables.head.data[38], tables.head.data[39]), + ascent: signedInt16(tables.hhea.data[4], tables.hhea.data[5]), + descent: signedInt16(tables.hhea.data[6], tables.hhea.data[7]), + lineGap: signedInt16(tables.hhea.data[8], tables.hhea.data[9]) + }; + this.ascent = metricsOverride.ascent / metricsOverride.unitsPerEm; + this.descent = metricsOverride.descent / metricsOverride.unitsPerEm; + this.lineGap = metricsOverride.lineGap / metricsOverride.unitsPerEm; + if (this.cssFontInfo?.lineHeight) { + this.lineHeight = this.cssFontInfo.metrics.lineHeight; + this.lineGap = this.cssFontInfo.metrics.lineGap; + } else { + this.lineHeight = this.ascent - this.descent + this.lineGap; + } + if (tables.post) { + readPostScriptTable(tables.post, properties, numGlyphs); + } + tables.post = { + tag: "post", + data: createPostTable(properties) + }; + const charCodeToGlyphId = []; + function hasGlyph(glyphId) { + return !missingGlyphs[glyphId]; + } + if (properties.composite) { + const cidToGidMap = properties.cidToGidMap || []; + const isCidToGidMapEmpty = cidToGidMap.length === 0; + properties.cMap.forEach(function (charCode, cid) { + if (typeof cid === "string") { + cid = convertCidString(charCode, cid, true); + } + if (cid > 0xffff) { + throw new _util.FormatError("Max size of CID is 65,535"); + } + let glyphId = -1; + if (isCidToGidMapEmpty) { + glyphId = cid; + } else if (cidToGidMap[cid] !== undefined) { + glyphId = cidToGidMap[cid]; + } + if (glyphId >= 0 && glyphId < numGlyphs && hasGlyph(glyphId)) { + charCodeToGlyphId[charCode] = glyphId; + } + }); + } else { + const cmapTable = readCmapTable(tables.cmap, font, this.isSymbolicFont, properties.hasEncoding); + const cmapPlatformId = cmapTable.platformId; + const cmapEncodingId = cmapTable.encodingId; + const cmapMappings = cmapTable.mappings; + let baseEncoding = [], + forcePostTable = false; + if (properties.hasEncoding && (properties.baseEncodingName === "MacRomanEncoding" || properties.baseEncodingName === "WinAnsiEncoding")) { + baseEncoding = (0, _encodings.getEncoding)(properties.baseEncodingName); + } + if (properties.hasEncoding && !this.isSymbolicFont && (cmapPlatformId === 3 && cmapEncodingId === 1 || cmapPlatformId === 1 && cmapEncodingId === 0)) { + const glyphsUnicodeMap = (0, _glyphlist.getGlyphsUnicode)(); + for (let charCode = 0; charCode < 256; charCode++) { + let glyphName; + if (this.differences[charCode] !== undefined) { + glyphName = this.differences[charCode]; + } else if (baseEncoding.length && baseEncoding[charCode] !== "") { + glyphName = baseEncoding[charCode]; + } else { + glyphName = _encodings.StandardEncoding[charCode]; + } + if (!glyphName) { + continue; + } + const standardGlyphName = (0, _fonts_utils.recoverGlyphName)(glyphName, glyphsUnicodeMap); + let unicodeOrCharCode; + if (cmapPlatformId === 3 && cmapEncodingId === 1) { + unicodeOrCharCode = glyphsUnicodeMap[standardGlyphName]; + } else if (cmapPlatformId === 1 && cmapEncodingId === 0) { + unicodeOrCharCode = _encodings.MacRomanEncoding.indexOf(standardGlyphName); + } + if (unicodeOrCharCode === undefined) { + if (!properties.glyphNames && properties.hasIncludedToUnicodeMap && !(this.toUnicode instanceof _to_unicode_map.IdentityToUnicodeMap)) { + const unicode = this.toUnicode.get(charCode); + if (unicode) { + unicodeOrCharCode = unicode.codePointAt(0); + } + } + if (unicodeOrCharCode === undefined) { + continue; + } + } + for (const mapping of cmapMappings) { + if (mapping.charCode !== unicodeOrCharCode) { + continue; + } + charCodeToGlyphId[charCode] = mapping.glyphId; + break; + } + } + } else if (cmapPlatformId === 0) { + for (const mapping of cmapMappings) { + charCodeToGlyphId[mapping.charCode] = mapping.glyphId; + } + forcePostTable = true; + } else { + for (const mapping of cmapMappings) { + let charCode = mapping.charCode; + if (cmapPlatformId === 3 && charCode >= 0xf000 && charCode <= 0xf0ff) { + charCode &= 0xff; + } + charCodeToGlyphId[charCode] = mapping.glyphId; + } + } + if (properties.glyphNames && (baseEncoding.length || this.differences.length)) { + for (let i = 0; i < 256; ++i) { + if (!forcePostTable && charCodeToGlyphId[i] !== undefined) { + continue; + } + const glyphName = this.differences[i] || baseEncoding[i]; + if (!glyphName) { + continue; + } + const glyphId = properties.glyphNames.indexOf(glyphName); + if (glyphId > 0 && hasGlyph(glyphId)) { + charCodeToGlyphId[i] = glyphId; + } + } + } + } + if (charCodeToGlyphId.length === 0) { + charCodeToGlyphId[0] = 0; + } + let glyphZeroId = numGlyphsOut - 1; + if (!dupFirstEntry) { + glyphZeroId = 0; + } + if (!properties.cssFontInfo) { + const newMapping = adjustMapping(charCodeToGlyphId, hasGlyph, glyphZeroId, this.toUnicode); + this.toFontChar = newMapping.toFontChar; + tables.cmap = { + tag: "cmap", + data: createCmapTable(newMapping.charCodeToGlyphId, newMapping.toUnicodeExtraMap, numGlyphsOut) + }; + if (!tables["OS/2"] || !validateOS2Table(tables["OS/2"], font)) { + tables["OS/2"] = { + tag: "OS/2", + data: createOS2Table(properties, newMapping.charCodeToGlyphId, metricsOverride) + }; + } + } + if (!isTrueType) { + try { + cffFile = new _stream.Stream(tables["CFF "].data); + const parser = new _cff_parser.CFFParser(cffFile, properties, _fonts_utils.SEAC_ANALYSIS_ENABLED); + cff = parser.parse(); + cff.duplicateFirstGlyph(); + const compiler = new _cff_parser.CFFCompiler(cff); + tables["CFF "].data = compiler.compile(); + } catch { + (0, _util.warn)("Failed to compile font " + properties.loadedName); + } + } + if (!tables.name) { + tables.name = { + tag: "name", + data: createNameTable(this.name) + }; + } else { + const [namePrototype, nameRecords] = readNameTable(tables.name); + tables.name.data = createNameTable(name, namePrototype); + this.psName = namePrototype[0][6] || null; + if (!properties.composite) { + adjustTrueTypeToUnicode(properties, this.isSymbolicFont, nameRecords); + } + } + const builder = new _opentype_file_builder.OpenTypeFileBuilder(header.version); + for (const tableTag in tables) { + builder.addTable(tableTag, tables[tableTag].data); + } + return builder.toArray(); + } + convert(fontName, font, properties) { + properties.fixedPitch = false; + if (properties.builtInEncoding) { + adjustType1ToUnicode(properties, properties.builtInEncoding); + } + let glyphZeroId = 1; + if (font instanceof _cff_font.CFFFont) { + glyphZeroId = font.numGlyphs - 1; + } + const mapping = font.getGlyphMapping(properties); + let newMapping = null; + let newCharCodeToGlyphId = mapping; + let toUnicodeExtraMap = null; + if (!properties.cssFontInfo) { + newMapping = adjustMapping(mapping, font.hasGlyphId.bind(font), glyphZeroId, this.toUnicode); + this.toFontChar = newMapping.toFontChar; + newCharCodeToGlyphId = newMapping.charCodeToGlyphId; + toUnicodeExtraMap = newMapping.toUnicodeExtraMap; + } + const numGlyphs = font.numGlyphs; + function getCharCodes(charCodeToGlyphId, glyphId) { + let charCodes = null; + for (const charCode in charCodeToGlyphId) { + if (glyphId === charCodeToGlyphId[charCode]) { + (charCodes ||= []).push(charCode | 0); + } + } + return charCodes; + } + function createCharCode(charCodeToGlyphId, glyphId) { + for (const charCode in charCodeToGlyphId) { + if (glyphId === charCodeToGlyphId[charCode]) { + return charCode | 0; + } + } + newMapping.charCodeToGlyphId[newMapping.nextAvailableFontCharCode] = glyphId; + return newMapping.nextAvailableFontCharCode++; + } + const seacs = font.seacs; + if (newMapping && _fonts_utils.SEAC_ANALYSIS_ENABLED && seacs?.length) { + const matrix = properties.fontMatrix || _util.FONT_IDENTITY_MATRIX; + const charset = font.getCharset(); + const seacMap = Object.create(null); + for (let glyphId in seacs) { + glyphId |= 0; + const seac = seacs[glyphId]; + const baseGlyphName = _encodings.StandardEncoding[seac[2]]; + const accentGlyphName = _encodings.StandardEncoding[seac[3]]; + const baseGlyphId = charset.indexOf(baseGlyphName); + const accentGlyphId = charset.indexOf(accentGlyphName); + if (baseGlyphId < 0 || accentGlyphId < 0) { + continue; + } + const accentOffset = { + x: seac[0] * matrix[0] + seac[1] * matrix[2] + matrix[4], + y: seac[0] * matrix[1] + seac[1] * matrix[3] + matrix[5] + }; + const charCodes = getCharCodes(mapping, glyphId); + if (!charCodes) { + continue; + } + for (const charCode of charCodes) { + const charCodeToGlyphId = newMapping.charCodeToGlyphId; + const baseFontCharCode = createCharCode(charCodeToGlyphId, baseGlyphId); + const accentFontCharCode = createCharCode(charCodeToGlyphId, accentGlyphId); + seacMap[charCode] = { + baseFontCharCode, + accentFontCharCode, + accentOffset + }; + } + } + properties.seacMap = seacMap; + } + const unitsPerEm = 1 / (properties.fontMatrix || _util.FONT_IDENTITY_MATRIX)[0]; + const builder = new _opentype_file_builder.OpenTypeFileBuilder("\x4F\x54\x54\x4F"); + builder.addTable("CFF ", font.data); + builder.addTable("OS/2", createOS2Table(properties, newCharCodeToGlyphId)); + builder.addTable("cmap", createCmapTable(newCharCodeToGlyphId, toUnicodeExtraMap, numGlyphs)); + builder.addTable("head", "\x00\x01\x00\x00" + "\x00\x00\x10\x00" + "\x00\x00\x00\x00" + "\x5F\x0F\x3C\xF5" + "\x00\x00" + safeString16(unitsPerEm) + "\x00\x00\x00\x00\x9e\x0b\x7e\x27" + "\x00\x00\x00\x00\x9e\x0b\x7e\x27" + "\x00\x00" + safeString16(properties.descent) + "\x0F\xFF" + safeString16(properties.ascent) + string16(properties.italicAngle ? 2 : 0) + "\x00\x11" + "\x00\x00" + "\x00\x00" + "\x00\x00"); + builder.addTable("hhea", "\x00\x01\x00\x00" + safeString16(properties.ascent) + safeString16(properties.descent) + "\x00\x00" + "\xFF\xFF" + "\x00\x00" + "\x00\x00" + "\x00\x00" + safeString16(properties.capHeight) + safeString16(Math.tan(properties.italicAngle) * properties.xHeight) + "\x00\x00" + "\x00\x00" + "\x00\x00" + "\x00\x00" + "\x00\x00" + "\x00\x00" + string16(numGlyphs)); + builder.addTable("hmtx", function fontFieldsHmtx() { + const charstrings = font.charstrings; + const cffWidths = font.cff ? font.cff.widths : null; + let hmtx = "\x00\x00\x00\x00"; + for (let i = 1, ii = numGlyphs; i < ii; i++) { + let width = 0; + if (charstrings) { + const charstring = charstrings[i - 1]; + width = "width" in charstring ? charstring.width : 0; + } else if (cffWidths) { + width = Math.ceil(cffWidths[i] || 0); + } + hmtx += string16(width) + string16(0); + } + return hmtx; + }()); + builder.addTable("maxp", "\x00\x00\x50\x00" + string16(numGlyphs)); + builder.addTable("name", createNameTable(fontName)); + builder.addTable("post", createPostTable(properties)); + return builder.toArray(); + } + get spaceWidth() { + const possibleSpaceReplacements = ["space", "minus", "one", "i", "I"]; + let width; + for (const glyphName of possibleSpaceReplacements) { + if (glyphName in this.widths) { + width = this.widths[glyphName]; + break; + } + const glyphsUnicodeMap = (0, _glyphlist.getGlyphsUnicode)(); + const glyphUnicode = glyphsUnicodeMap[glyphName]; + let charcode = 0; + if (this.composite && this.cMap.contains(glyphUnicode)) { + charcode = this.cMap.lookup(glyphUnicode); + if (typeof charcode === "string") { + charcode = convertCidString(glyphUnicode, charcode); + } + } + if (!charcode && this.toUnicode) { + charcode = this.toUnicode.charCodeOf(glyphUnicode); + } + if (charcode <= 0) { + charcode = glyphUnicode; + } + width = this.widths[charcode]; + if (width) { + break; + } + } + return (0, _util.shadow)(this, "spaceWidth", width || this.defaultWidth); + } + _charToGlyph(charcode, isSpace = false) { + let glyph = this._glyphCache[charcode]; + if (glyph?.isSpace === isSpace) { + return glyph; + } + let fontCharCode, width, operatorListId; + let widthCode = charcode; + if (this.cMap?.contains(charcode)) { + widthCode = this.cMap.lookup(charcode); + if (typeof widthCode === "string") { + widthCode = convertCidString(charcode, widthCode); + } + } + width = this.widths[widthCode]; + if (typeof width !== "number") { + width = this.defaultWidth; + } + const vmetric = this.vmetrics?.[widthCode]; + let unicode = this.toUnicode.get(charcode) || charcode; + if (typeof unicode === "number") { + unicode = String.fromCharCode(unicode); + } + let isInFont = this.toFontChar[charcode] !== undefined; + fontCharCode = this.toFontChar[charcode] || charcode; + if (this.missingFile) { + const glyphName = this.differences[charcode] || this.defaultEncoding[charcode]; + if ((glyphName === ".notdef" || glyphName === "") && this.type === "Type1") { + fontCharCode = 0x20; + } + fontCharCode = (0, _unicode.mapSpecialUnicodeValues)(fontCharCode); + } + if (this.isType3Font) { + operatorListId = fontCharCode; + } + let accent = null; + if (this.seacMap?.[charcode]) { + isInFont = true; + const seac = this.seacMap[charcode]; + fontCharCode = seac.baseFontCharCode; + accent = { + fontChar: String.fromCodePoint(seac.accentFontCharCode), + offset: seac.accentOffset + }; + } + let fontChar = ""; + if (typeof fontCharCode === "number") { + if (fontCharCode <= 0x10ffff) { + fontChar = String.fromCodePoint(fontCharCode); + } else { + (0, _util.warn)(`charToGlyph - invalid fontCharCode: ${fontCharCode}`); + } + } + glyph = new Glyph(charcode, fontChar, unicode, accent, width, vmetric, operatorListId, isSpace, isInFont); + return this._glyphCache[charcode] = glyph; + } + charsToGlyphs(chars) { + let glyphs = this._charsCache[chars]; + if (glyphs) { + return glyphs; + } + glyphs = []; + if (this.cMap) { + const c = Object.create(null), + ii = chars.length; + let i = 0; + while (i < ii) { + this.cMap.readCharCode(chars, i, c); + const { + charcode, + length + } = c; + i += length; + const glyph = this._charToGlyph(charcode, length === 1 && chars.charCodeAt(i - 1) === 0x20); + glyphs.push(glyph); + } + } else { + for (let i = 0, ii = chars.length; i < ii; ++i) { + const charcode = chars.charCodeAt(i); + const glyph = this._charToGlyph(charcode, charcode === 0x20); + glyphs.push(glyph); + } + } + return this._charsCache[chars] = glyphs; + } + getCharPositions(chars) { + const positions = []; + if (this.cMap) { + const c = Object.create(null); + let i = 0; + while (i < chars.length) { + this.cMap.readCharCode(chars, i, c); + const length = c.length; + positions.push([i, i + length]); + i += length; + } + } else { + for (let i = 0, ii = chars.length; i < ii; ++i) { + positions.push([i, i + 1]); + } + } + return positions; + } + get glyphCacheValues() { + return Object.values(this._glyphCache); + } + encodeString(str) { + const buffers = []; + const currentBuf = []; + const hasCurrentBufErrors = () => buffers.length % 2 === 1; + const getCharCode = this.toUnicode instanceof _to_unicode_map.IdentityToUnicodeMap ? unicode => this.toUnicode.charCodeOf(unicode) : unicode => this.toUnicode.charCodeOf(String.fromCodePoint(unicode)); + for (let i = 0, ii = str.length; i < ii; i++) { + const unicode = str.codePointAt(i); + if (unicode > 0xd7ff && (unicode < 0xe000 || unicode > 0xfffd)) { + i++; + } + if (this.toUnicode) { + const charCode = getCharCode(unicode); + if (charCode !== -1) { + if (hasCurrentBufErrors()) { + buffers.push(currentBuf.join("")); + currentBuf.length = 0; + } + const charCodeLength = this.cMap ? this.cMap.getCharCodeLength(charCode) : 1; + for (let j = charCodeLength - 1; j >= 0; j--) { + currentBuf.push(String.fromCharCode(charCode >> 8 * j & 0xff)); + } + continue; + } + } + if (!hasCurrentBufErrors()) { + buffers.push(currentBuf.join("")); + currentBuf.length = 0; + } + currentBuf.push(String.fromCodePoint(unicode)); + } + buffers.push(currentBuf.join("")); + return buffers; + } +} +exports.Font = Font; +class ErrorFont { + constructor(error) { + this.error = error; + this.loadedName = "g_font_error"; + this.missingFile = true; + } + charsToGlyphs() { + return []; + } + encodeString(chars) { + return [chars]; + } + exportData(extraProperties = false) { + return { + error: this.error + }; + } +} +exports.ErrorFont = ErrorFont; + +/***/ }), +/* 35 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.CFFTopDict = exports.CFFStrings = exports.CFFStandardStrings = exports.CFFPrivateDict = exports.CFFParser = exports.CFFIndex = exports.CFFHeader = exports.CFFFDSelect = exports.CFFCompiler = exports.CFFCharset = exports.CFF = void 0; +var _util = __w_pdfjs_require__(2); +var _charsets = __w_pdfjs_require__(36); +var _encodings = __w_pdfjs_require__(37); +const MAX_SUBR_NESTING = 10; +const CFFStandardStrings = [".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar", "degree", "thorn", "threequarters", "twosuperior", "registered", "minus", "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall", "001.000", "001.001", "001.002", "001.003", "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold"]; +exports.CFFStandardStrings = CFFStandardStrings; +const NUM_STANDARD_CFF_STRINGS = 391; +const CharstringValidationData = [null, { + id: "hstem", + min: 2, + stackClearing: true, + stem: true +}, null, { + id: "vstem", + min: 2, + stackClearing: true, + stem: true +}, { + id: "vmoveto", + min: 1, + stackClearing: true +}, { + id: "rlineto", + min: 2, + resetStack: true +}, { + id: "hlineto", + min: 1, + resetStack: true +}, { + id: "vlineto", + min: 1, + resetStack: true +}, { + id: "rrcurveto", + min: 6, + resetStack: true +}, null, { + id: "callsubr", + min: 1, + undefStack: true +}, { + id: "return", + min: 0, + undefStack: true +}, null, null, { + id: "endchar", + min: 0, + stackClearing: true +}, null, null, null, { + id: "hstemhm", + min: 2, + stackClearing: true, + stem: true +}, { + id: "hintmask", + min: 0, + stackClearing: true +}, { + id: "cntrmask", + min: 0, + stackClearing: true +}, { + id: "rmoveto", + min: 2, + stackClearing: true +}, { + id: "hmoveto", + min: 1, + stackClearing: true +}, { + id: "vstemhm", + min: 2, + stackClearing: true, + stem: true +}, { + id: "rcurveline", + min: 8, + resetStack: true +}, { + id: "rlinecurve", + min: 8, + resetStack: true +}, { + id: "vvcurveto", + min: 4, + resetStack: true +}, { + id: "hhcurveto", + min: 4, + resetStack: true +}, null, { + id: "callgsubr", + min: 1, + undefStack: true +}, { + id: "vhcurveto", + min: 4, + resetStack: true +}, { + id: "hvcurveto", + min: 4, + resetStack: true +}]; +const CharstringValidationData12 = [null, null, null, { + id: "and", + min: 2, + stackDelta: -1 +}, { + id: "or", + min: 2, + stackDelta: -1 +}, { + id: "not", + min: 1, + stackDelta: 0 +}, null, null, null, { + id: "abs", + min: 1, + stackDelta: 0 +}, { + id: "add", + min: 2, + stackDelta: -1, + stackFn(stack, index) { + stack[index - 2] = stack[index - 2] + stack[index - 1]; + } +}, { + id: "sub", + min: 2, + stackDelta: -1, + stackFn(stack, index) { + stack[index - 2] = stack[index - 2] - stack[index - 1]; + } +}, { + id: "div", + min: 2, + stackDelta: -1, + stackFn(stack, index) { + stack[index - 2] = stack[index - 2] / stack[index - 1]; + } +}, null, { + id: "neg", + min: 1, + stackDelta: 0, + stackFn(stack, index) { + stack[index - 1] = -stack[index - 1]; + } +}, { + id: "eq", + min: 2, + stackDelta: -1 +}, null, null, { + id: "drop", + min: 1, + stackDelta: -1 +}, null, { + id: "put", + min: 2, + stackDelta: -2 +}, { + id: "get", + min: 1, + stackDelta: 0 +}, { + id: "ifelse", + min: 4, + stackDelta: -3 +}, { + id: "random", + min: 0, + stackDelta: 1 +}, { + id: "mul", + min: 2, + stackDelta: -1, + stackFn(stack, index) { + stack[index - 2] = stack[index - 2] * stack[index - 1]; + } +}, null, { + id: "sqrt", + min: 1, + stackDelta: 0 +}, { + id: "dup", + min: 1, + stackDelta: 1 +}, { + id: "exch", + min: 2, + stackDelta: 0 +}, { + id: "index", + min: 2, + stackDelta: 0 +}, { + id: "roll", + min: 3, + stackDelta: -2 +}, null, null, null, { + id: "hflex", + min: 7, + resetStack: true +}, { + id: "flex", + min: 13, + resetStack: true +}, { + id: "hflex1", + min: 9, + resetStack: true +}, { + id: "flex1", + min: 11, + resetStack: true +}]; +class CFFParser { + constructor(file, properties, seacAnalysisEnabled) { + this.bytes = file.getBytes(); + this.properties = properties; + this.seacAnalysisEnabled = !!seacAnalysisEnabled; + } + parse() { + const properties = this.properties; + const cff = new CFF(); + this.cff = cff; + const header = this.parseHeader(); + const nameIndex = this.parseIndex(header.endPos); + const topDictIndex = this.parseIndex(nameIndex.endPos); + const stringIndex = this.parseIndex(topDictIndex.endPos); + const globalSubrIndex = this.parseIndex(stringIndex.endPos); + const topDictParsed = this.parseDict(topDictIndex.obj.get(0)); + const topDict = this.createDict(CFFTopDict, topDictParsed, cff.strings); + cff.header = header.obj; + cff.names = this.parseNameIndex(nameIndex.obj); + cff.strings = this.parseStringIndex(stringIndex.obj); + cff.topDict = topDict; + cff.globalSubrIndex = globalSubrIndex.obj; + this.parsePrivateDict(cff.topDict); + cff.isCIDFont = topDict.hasName("ROS"); + const charStringOffset = topDict.getByName("CharStrings"); + const charStringIndex = this.parseIndex(charStringOffset).obj; + const fontMatrix = topDict.getByName("FontMatrix"); + if (fontMatrix) { + properties.fontMatrix = fontMatrix; + } + const fontBBox = topDict.getByName("FontBBox"); + if (fontBBox) { + properties.ascent = Math.max(fontBBox[3], fontBBox[1]); + properties.descent = Math.min(fontBBox[1], fontBBox[3]); + properties.ascentScaled = true; + } + let charset, encoding; + if (cff.isCIDFont) { + const fdArrayIndex = this.parseIndex(topDict.getByName("FDArray")).obj; + for (let i = 0, ii = fdArrayIndex.count; i < ii; ++i) { + const dictRaw = fdArrayIndex.get(i); + const fontDict = this.createDict(CFFTopDict, this.parseDict(dictRaw), cff.strings); + this.parsePrivateDict(fontDict); + cff.fdArray.push(fontDict); + } + encoding = null; + charset = this.parseCharsets(topDict.getByName("charset"), charStringIndex.count, cff.strings, true); + cff.fdSelect = this.parseFDSelect(topDict.getByName("FDSelect"), charStringIndex.count); + } else { + charset = this.parseCharsets(topDict.getByName("charset"), charStringIndex.count, cff.strings, false); + encoding = this.parseEncoding(topDict.getByName("Encoding"), properties, cff.strings, charset.charset); + } + cff.charset = charset; + cff.encoding = encoding; + const charStringsAndSeacs = this.parseCharStrings({ + charStrings: charStringIndex, + localSubrIndex: topDict.privateDict.subrsIndex, + globalSubrIndex: globalSubrIndex.obj, + fdSelect: cff.fdSelect, + fdArray: cff.fdArray, + privateDict: topDict.privateDict + }); + cff.charStrings = charStringsAndSeacs.charStrings; + cff.seacs = charStringsAndSeacs.seacs; + cff.widths = charStringsAndSeacs.widths; + return cff; + } + parseHeader() { + let bytes = this.bytes; + const bytesLength = bytes.length; + let offset = 0; + while (offset < bytesLength && bytes[offset] !== 1) { + ++offset; + } + if (offset >= bytesLength) { + throw new _util.FormatError("Invalid CFF header"); + } + if (offset !== 0) { + (0, _util.info)("cff data is shifted"); + bytes = bytes.subarray(offset); + this.bytes = bytes; + } + const major = bytes[0]; + const minor = bytes[1]; + const hdrSize = bytes[2]; + const offSize = bytes[3]; + const header = new CFFHeader(major, minor, hdrSize, offSize); + return { + obj: header, + endPos: hdrSize + }; + } + parseDict(dict) { + let pos = 0; + function parseOperand() { + let value = dict[pos++]; + if (value === 30) { + return parseFloatOperand(); + } else if (value === 28) { + value = dict[pos++]; + value = (value << 24 | dict[pos++] << 16) >> 16; + return value; + } else if (value === 29) { + value = dict[pos++]; + value = value << 8 | dict[pos++]; + value = value << 8 | dict[pos++]; + value = value << 8 | dict[pos++]; + return value; + } else if (value >= 32 && value <= 246) { + return value - 139; + } else if (value >= 247 && value <= 250) { + return (value - 247) * 256 + dict[pos++] + 108; + } else if (value >= 251 && value <= 254) { + return -((value - 251) * 256) - dict[pos++] - 108; + } + (0, _util.warn)('CFFParser_parseDict: "' + value + '" is a reserved command.'); + return NaN; + } + function parseFloatOperand() { + let str = ""; + const eof = 15; + const lookup = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "E", "E-", null, "-"]; + const length = dict.length; + while (pos < length) { + const b = dict[pos++]; + const b1 = b >> 4; + const b2 = b & 15; + if (b1 === eof) { + break; + } + str += lookup[b1]; + if (b2 === eof) { + break; + } + str += lookup[b2]; + } + return parseFloat(str); + } + let operands = []; + const entries = []; + pos = 0; + const end = dict.length; + while (pos < end) { + let b = dict[pos]; + if (b <= 21) { + if (b === 12) { + b = b << 8 | dict[++pos]; + } + entries.push([b, operands]); + operands = []; + ++pos; + } else { + operands.push(parseOperand()); + } + } + return entries; + } + parseIndex(pos) { + const cffIndex = new CFFIndex(); + const bytes = this.bytes; + const count = bytes[pos++] << 8 | bytes[pos++]; + const offsets = []; + let end = pos; + let i, ii; + if (count !== 0) { + const offsetSize = bytes[pos++]; + const startPos = pos + (count + 1) * offsetSize - 1; + for (i = 0, ii = count + 1; i < ii; ++i) { + let offset = 0; + for (let j = 0; j < offsetSize; ++j) { + offset <<= 8; + offset += bytes[pos++]; + } + offsets.push(startPos + offset); + } + end = offsets[count]; + } + for (i = 0, ii = offsets.length - 1; i < ii; ++i) { + const offsetStart = offsets[i]; + const offsetEnd = offsets[i + 1]; + cffIndex.add(bytes.subarray(offsetStart, offsetEnd)); + } + return { + obj: cffIndex, + endPos: end + }; + } + parseNameIndex(index) { + const names = []; + for (let i = 0, ii = index.count; i < ii; ++i) { + const name = index.get(i); + names.push((0, _util.bytesToString)(name)); + } + return names; + } + parseStringIndex(index) { + const strings = new CFFStrings(); + for (let i = 0, ii = index.count; i < ii; ++i) { + const data = index.get(i); + strings.add((0, _util.bytesToString)(data)); + } + return strings; + } + createDict(Type, dict, strings) { + const cffDict = new Type(strings); + for (const [key, value] of dict) { + cffDict.setByKey(key, value); + } + return cffDict; + } + parseCharString(state, data, localSubrIndex, globalSubrIndex) { + if (!data || state.callDepth > MAX_SUBR_NESTING) { + return false; + } + let stackSize = state.stackSize; + const stack = state.stack; + let length = data.length; + for (let j = 0; j < length;) { + const value = data[j++]; + let validationCommand = null; + if (value === 12) { + const q = data[j++]; + if (q === 0) { + data[j - 2] = 139; + data[j - 1] = 22; + stackSize = 0; + } else { + validationCommand = CharstringValidationData12[q]; + } + } else if (value === 28) { + stack[stackSize] = (data[j] << 24 | data[j + 1] << 16) >> 16; + j += 2; + stackSize++; + } else if (value === 14) { + if (stackSize >= 4) { + stackSize -= 4; + if (this.seacAnalysisEnabled) { + state.seac = stack.slice(stackSize, stackSize + 4); + return false; + } + } + validationCommand = CharstringValidationData[value]; + } else if (value >= 32 && value <= 246) { + stack[stackSize] = value - 139; + stackSize++; + } else if (value >= 247 && value <= 254) { + stack[stackSize] = value < 251 ? (value - 247 << 8) + data[j] + 108 : -(value - 251 << 8) - data[j] - 108; + j++; + stackSize++; + } else if (value === 255) { + stack[stackSize] = (data[j] << 24 | data[j + 1] << 16 | data[j + 2] << 8 | data[j + 3]) / 65536; + j += 4; + stackSize++; + } else if (value === 19 || value === 20) { + state.hints += stackSize >> 1; + if (state.hints === 0) { + data.copyWithin(j - 1, j, -1); + j -= 1; + length -= 1; + continue; + } + j += state.hints + 7 >> 3; + stackSize %= 2; + validationCommand = CharstringValidationData[value]; + } else if (value === 10 || value === 29) { + const subrsIndex = value === 10 ? localSubrIndex : globalSubrIndex; + if (!subrsIndex) { + validationCommand = CharstringValidationData[value]; + (0, _util.warn)("Missing subrsIndex for " + validationCommand.id); + return false; + } + let bias = 32768; + if (subrsIndex.count < 1240) { + bias = 107; + } else if (subrsIndex.count < 33900) { + bias = 1131; + } + const subrNumber = stack[--stackSize] + bias; + if (subrNumber < 0 || subrNumber >= subrsIndex.count || isNaN(subrNumber)) { + validationCommand = CharstringValidationData[value]; + (0, _util.warn)("Out of bounds subrIndex for " + validationCommand.id); + return false; + } + state.stackSize = stackSize; + state.callDepth++; + const valid = this.parseCharString(state, subrsIndex.get(subrNumber), localSubrIndex, globalSubrIndex); + if (!valid) { + return false; + } + state.callDepth--; + stackSize = state.stackSize; + continue; + } else if (value === 11) { + state.stackSize = stackSize; + return true; + } else if (value === 0 && j === data.length) { + data[j - 1] = 14; + validationCommand = CharstringValidationData[14]; + } else if (value === 9) { + data.copyWithin(j - 1, j, -1); + j -= 1; + length -= 1; + continue; + } else { + validationCommand = CharstringValidationData[value]; + } + if (validationCommand) { + if (validationCommand.stem) { + state.hints += stackSize >> 1; + if (value === 3 || value === 23) { + state.hasVStems = true; + } else if (state.hasVStems && (value === 1 || value === 18)) { + (0, _util.warn)("CFF stem hints are in wrong order"); + data[j - 1] = value === 1 ? 3 : 23; + } + } + if ("min" in validationCommand) { + if (!state.undefStack && stackSize < validationCommand.min) { + (0, _util.warn)("Not enough parameters for " + validationCommand.id + "; actual: " + stackSize + ", expected: " + validationCommand.min); + if (stackSize === 0) { + data[j - 1] = 14; + return true; + } + return false; + } + } + if (state.firstStackClearing && validationCommand.stackClearing) { + state.firstStackClearing = false; + stackSize -= validationCommand.min; + if (stackSize >= 2 && validationCommand.stem) { + stackSize %= 2; + } else if (stackSize > 1) { + (0, _util.warn)("Found too many parameters for stack-clearing command"); + } + if (stackSize > 0) { + state.width = stack[stackSize - 1]; + } + } + if ("stackDelta" in validationCommand) { + if ("stackFn" in validationCommand) { + validationCommand.stackFn(stack, stackSize); + } + stackSize += validationCommand.stackDelta; + } else if (validationCommand.stackClearing) { + stackSize = 0; + } else if (validationCommand.resetStack) { + stackSize = 0; + state.undefStack = false; + } else if (validationCommand.undefStack) { + stackSize = 0; + state.undefStack = true; + state.firstStackClearing = false; + } + } + } + if (length < data.length) { + data.fill(14, length); + } + state.stackSize = stackSize; + return true; + } + parseCharStrings({ + charStrings, + localSubrIndex, + globalSubrIndex, + fdSelect, + fdArray, + privateDict + }) { + const seacs = []; + const widths = []; + const count = charStrings.count; + for (let i = 0; i < count; i++) { + const charstring = charStrings.get(i); + const state = { + callDepth: 0, + stackSize: 0, + stack: [], + undefStack: true, + hints: 0, + firstStackClearing: true, + seac: null, + width: null, + hasVStems: false + }; + let valid = true; + let localSubrToUse = null; + let privateDictToUse = privateDict; + if (fdSelect && fdArray.length) { + const fdIndex = fdSelect.getFDIndex(i); + if (fdIndex === -1) { + (0, _util.warn)("Glyph index is not in fd select."); + valid = false; + } + if (fdIndex >= fdArray.length) { + (0, _util.warn)("Invalid fd index for glyph index."); + valid = false; + } + if (valid) { + privateDictToUse = fdArray[fdIndex].privateDict; + localSubrToUse = privateDictToUse.subrsIndex; + } + } else if (localSubrIndex) { + localSubrToUse = localSubrIndex; + } + if (valid) { + valid = this.parseCharString(state, charstring, localSubrToUse, globalSubrIndex); + } + if (state.width !== null) { + const nominalWidth = privateDictToUse.getByName("nominalWidthX"); + widths[i] = nominalWidth + state.width; + } else { + const defaultWidth = privateDictToUse.getByName("defaultWidthX"); + widths[i] = defaultWidth; + } + if (state.seac !== null) { + seacs[i] = state.seac; + } + if (!valid) { + charStrings.set(i, new Uint8Array([14])); + } + } + return { + charStrings, + seacs, + widths + }; + } + emptyPrivateDictionary(parentDict) { + const privateDict = this.createDict(CFFPrivateDict, [], parentDict.strings); + parentDict.setByKey(18, [0, 0]); + parentDict.privateDict = privateDict; + } + parsePrivateDict(parentDict) { + if (!parentDict.hasName("Private")) { + this.emptyPrivateDictionary(parentDict); + return; + } + const privateOffset = parentDict.getByName("Private"); + if (!Array.isArray(privateOffset) || privateOffset.length !== 2) { + parentDict.removeByName("Private"); + return; + } + const size = privateOffset[0]; + const offset = privateOffset[1]; + if (size === 0 || offset >= this.bytes.length) { + this.emptyPrivateDictionary(parentDict); + return; + } + const privateDictEnd = offset + size; + const dictData = this.bytes.subarray(offset, privateDictEnd); + const dict = this.parseDict(dictData); + const privateDict = this.createDict(CFFPrivateDict, dict, parentDict.strings); + parentDict.privateDict = privateDict; + if (privateDict.getByName("ExpansionFactor") === 0) { + privateDict.setByName("ExpansionFactor", 0.06); + } + if (!privateDict.getByName("Subrs")) { + return; + } + const subrsOffset = privateDict.getByName("Subrs"); + const relativeOffset = offset + subrsOffset; + if (subrsOffset === 0 || relativeOffset >= this.bytes.length) { + this.emptyPrivateDictionary(parentDict); + return; + } + const subrsIndex = this.parseIndex(relativeOffset); + privateDict.subrsIndex = subrsIndex.obj; + } + parseCharsets(pos, length, strings, cid) { + if (pos === 0) { + return new CFFCharset(true, CFFCharsetPredefinedTypes.ISO_ADOBE, _charsets.ISOAdobeCharset); + } else if (pos === 1) { + return new CFFCharset(true, CFFCharsetPredefinedTypes.EXPERT, _charsets.ExpertCharset); + } else if (pos === 2) { + return new CFFCharset(true, CFFCharsetPredefinedTypes.EXPERT_SUBSET, _charsets.ExpertSubsetCharset); + } + const bytes = this.bytes; + const start = pos; + const format = bytes[pos++]; + const charset = [cid ? 0 : ".notdef"]; + let id, count, i; + length -= 1; + switch (format) { + case 0: + for (i = 0; i < length; i++) { + id = bytes[pos++] << 8 | bytes[pos++]; + charset.push(cid ? id : strings.get(id)); + } + break; + case 1: + while (charset.length <= length) { + id = bytes[pos++] << 8 | bytes[pos++]; + count = bytes[pos++]; + for (i = 0; i <= count; i++) { + charset.push(cid ? id++ : strings.get(id++)); + } + } + break; + case 2: + while (charset.length <= length) { + id = bytes[pos++] << 8 | bytes[pos++]; + count = bytes[pos++] << 8 | bytes[pos++]; + for (i = 0; i <= count; i++) { + charset.push(cid ? id++ : strings.get(id++)); + } + } + break; + default: + throw new _util.FormatError("Unknown charset format"); + } + const end = pos; + const raw = bytes.subarray(start, end); + return new CFFCharset(false, format, charset, raw); + } + parseEncoding(pos, properties, strings, charset) { + const encoding = Object.create(null); + const bytes = this.bytes; + let predefined = false; + let format, i, ii; + let raw = null; + function readSupplement() { + const supplementsCount = bytes[pos++]; + for (i = 0; i < supplementsCount; i++) { + const code = bytes[pos++]; + const sid = (bytes[pos++] << 8) + (bytes[pos++] & 0xff); + encoding[code] = charset.indexOf(strings.get(sid)); + } + } + if (pos === 0 || pos === 1) { + predefined = true; + format = pos; + const baseEncoding = pos ? _encodings.ExpertEncoding : _encodings.StandardEncoding; + for (i = 0, ii = charset.length; i < ii; i++) { + const index = baseEncoding.indexOf(charset[i]); + if (index !== -1) { + encoding[index] = i; + } + } + } else { + const dataStart = pos; + format = bytes[pos++]; + switch (format & 0x7f) { + case 0: + const glyphsCount = bytes[pos++]; + for (i = 1; i <= glyphsCount; i++) { + encoding[bytes[pos++]] = i; + } + break; + case 1: + const rangesCount = bytes[pos++]; + let gid = 1; + for (i = 0; i < rangesCount; i++) { + const start = bytes[pos++]; + const left = bytes[pos++]; + for (let j = start; j <= start + left; j++) { + encoding[j] = gid++; + } + } + break; + default: + throw new _util.FormatError(`Unknown encoding format: ${format} in CFF`); + } + const dataEnd = pos; + if (format & 0x80) { + bytes[dataStart] &= 0x7f; + readSupplement(); + } + raw = bytes.subarray(dataStart, dataEnd); + } + format &= 0x7f; + return new CFFEncoding(predefined, format, encoding, raw); + } + parseFDSelect(pos, length) { + const bytes = this.bytes; + const format = bytes[pos++]; + const fdSelect = []; + let i; + switch (format) { + case 0: + for (i = 0; i < length; ++i) { + const id = bytes[pos++]; + fdSelect.push(id); + } + break; + case 3: + const rangesCount = bytes[pos++] << 8 | bytes[pos++]; + for (i = 0; i < rangesCount; ++i) { + let first = bytes[pos++] << 8 | bytes[pos++]; + if (i === 0 && first !== 0) { + (0, _util.warn)("parseFDSelect: The first range must have a first GID of 0" + " -- trying to recover."); + first = 0; + } + const fdIndex = bytes[pos++]; + const next = bytes[pos] << 8 | bytes[pos + 1]; + for (let j = first; j < next; ++j) { + fdSelect.push(fdIndex); + } + } + pos += 2; + break; + default: + throw new _util.FormatError(`parseFDSelect: Unknown format "${format}".`); + } + if (fdSelect.length !== length) { + throw new _util.FormatError("parseFDSelect: Invalid font data."); + } + return new CFFFDSelect(format, fdSelect); + } +} +exports.CFFParser = CFFParser; +class CFF { + constructor() { + this.header = null; + this.names = []; + this.topDict = null; + this.strings = new CFFStrings(); + this.globalSubrIndex = null; + this.encoding = null; + this.charset = null; + this.charStrings = null; + this.fdArray = []; + this.fdSelect = null; + this.isCIDFont = false; + } + duplicateFirstGlyph() { + if (this.charStrings.count >= 65535) { + (0, _util.warn)("Not enough space in charstrings to duplicate first glyph."); + return; + } + const glyphZero = this.charStrings.get(0); + this.charStrings.add(glyphZero); + if (this.isCIDFont) { + this.fdSelect.fdSelect.push(this.fdSelect.fdSelect[0]); + } + } + hasGlyphId(id) { + if (id < 0 || id >= this.charStrings.count) { + return false; + } + const glyph = this.charStrings.get(id); + return glyph.length > 0; + } +} +exports.CFF = CFF; +class CFFHeader { + constructor(major, minor, hdrSize, offSize) { + this.major = major; + this.minor = minor; + this.hdrSize = hdrSize; + this.offSize = offSize; + } +} +exports.CFFHeader = CFFHeader; +class CFFStrings { + constructor() { + this.strings = []; + } + get(index) { + if (index >= 0 && index <= NUM_STANDARD_CFF_STRINGS - 1) { + return CFFStandardStrings[index]; + } + if (index - NUM_STANDARD_CFF_STRINGS <= this.strings.length) { + return this.strings[index - NUM_STANDARD_CFF_STRINGS]; + } + return CFFStandardStrings[0]; + } + getSID(str) { + let index = CFFStandardStrings.indexOf(str); + if (index !== -1) { + return index; + } + index = this.strings.indexOf(str); + if (index !== -1) { + return index + NUM_STANDARD_CFF_STRINGS; + } + return -1; + } + add(value) { + this.strings.push(value); + } + get count() { + return this.strings.length; + } +} +exports.CFFStrings = CFFStrings; +class CFFIndex { + constructor() { + this.objects = []; + this.length = 0; + } + add(data) { + this.length += data.length; + this.objects.push(data); + } + set(index, data) { + this.length += data.length - this.objects[index].length; + this.objects[index] = data; + } + get(index) { + return this.objects[index]; + } + get count() { + return this.objects.length; + } +} +exports.CFFIndex = CFFIndex; +class CFFDict { + constructor(tables, strings) { + this.keyToNameMap = tables.keyToNameMap; + this.nameToKeyMap = tables.nameToKeyMap; + this.defaults = tables.defaults; + this.types = tables.types; + this.opcodes = tables.opcodes; + this.order = tables.order; + this.strings = strings; + this.values = Object.create(null); + } + setByKey(key, value) { + if (!(key in this.keyToNameMap)) { + return false; + } + if (value.length === 0) { + return true; + } + for (const val of value) { + if (isNaN(val)) { + (0, _util.warn)(`Invalid CFFDict value: "${value}" for key "${key}".`); + return true; + } + } + const type = this.types[key]; + if (type === "num" || type === "sid" || type === "offset") { + value = value[0]; + } + this.values[key] = value; + return true; + } + setByName(name, value) { + if (!(name in this.nameToKeyMap)) { + throw new _util.FormatError(`Invalid dictionary name "${name}"`); + } + this.values[this.nameToKeyMap[name]] = value; + } + hasName(name) { + return this.nameToKeyMap[name] in this.values; + } + getByName(name) { + if (!(name in this.nameToKeyMap)) { + throw new _util.FormatError(`Invalid dictionary name ${name}"`); + } + const key = this.nameToKeyMap[name]; + if (!(key in this.values)) { + return this.defaults[key]; + } + return this.values[key]; + } + removeByName(name) { + delete this.values[this.nameToKeyMap[name]]; + } + static createTables(layout) { + const tables = { + keyToNameMap: {}, + nameToKeyMap: {}, + defaults: {}, + types: {}, + opcodes: {}, + order: [] + }; + for (const entry of layout) { + const key = Array.isArray(entry[0]) ? (entry[0][0] << 8) + entry[0][1] : entry[0]; + tables.keyToNameMap[key] = entry[1]; + tables.nameToKeyMap[entry[1]] = key; + tables.types[key] = entry[2]; + tables.defaults[key] = entry[3]; + tables.opcodes[key] = Array.isArray(entry[0]) ? entry[0] : [entry[0]]; + tables.order.push(key); + } + return tables; + } +} +const CFFTopDictLayout = [[[12, 30], "ROS", ["sid", "sid", "num"], null], [[12, 20], "SyntheticBase", "num", null], [0, "version", "sid", null], [1, "Notice", "sid", null], [[12, 0], "Copyright", "sid", null], [2, "FullName", "sid", null], [3, "FamilyName", "sid", null], [4, "Weight", "sid", null], [[12, 1], "isFixedPitch", "num", 0], [[12, 2], "ItalicAngle", "num", 0], [[12, 3], "UnderlinePosition", "num", -100], [[12, 4], "UnderlineThickness", "num", 50], [[12, 5], "PaintType", "num", 0], [[12, 6], "CharstringType", "num", 2], [[12, 7], "FontMatrix", ["num", "num", "num", "num", "num", "num"], [0.001, 0, 0, 0.001, 0, 0]], [13, "UniqueID", "num", null], [5, "FontBBox", ["num", "num", "num", "num"], [0, 0, 0, 0]], [[12, 8], "StrokeWidth", "num", 0], [14, "XUID", "array", null], [15, "charset", "offset", 0], [16, "Encoding", "offset", 0], [17, "CharStrings", "offset", 0], [18, "Private", ["offset", "offset"], null], [[12, 21], "PostScript", "sid", null], [[12, 22], "BaseFontName", "sid", null], [[12, 23], "BaseFontBlend", "delta", null], [[12, 31], "CIDFontVersion", "num", 0], [[12, 32], "CIDFontRevision", "num", 0], [[12, 33], "CIDFontType", "num", 0], [[12, 34], "CIDCount", "num", 8720], [[12, 35], "UIDBase", "num", null], [[12, 37], "FDSelect", "offset", null], [[12, 36], "FDArray", "offset", null], [[12, 38], "FontName", "sid", null]]; +class CFFTopDict extends CFFDict { + static get tables() { + return (0, _util.shadow)(this, "tables", this.createTables(CFFTopDictLayout)); + } + constructor(strings) { + super(CFFTopDict.tables, strings); + this.privateDict = null; + } +} +exports.CFFTopDict = CFFTopDict; +const CFFPrivateDictLayout = [[6, "BlueValues", "delta", null], [7, "OtherBlues", "delta", null], [8, "FamilyBlues", "delta", null], [9, "FamilyOtherBlues", "delta", null], [[12, 9], "BlueScale", "num", 0.039625], [[12, 10], "BlueShift", "num", 7], [[12, 11], "BlueFuzz", "num", 1], [10, "StdHW", "num", null], [11, "StdVW", "num", null], [[12, 12], "StemSnapH", "delta", null], [[12, 13], "StemSnapV", "delta", null], [[12, 14], "ForceBold", "num", 0], [[12, 17], "LanguageGroup", "num", 0], [[12, 18], "ExpansionFactor", "num", 0.06], [[12, 19], "initialRandomSeed", "num", 0], [20, "defaultWidthX", "num", 0], [21, "nominalWidthX", "num", 0], [19, "Subrs", "offset", null]]; +class CFFPrivateDict extends CFFDict { + static get tables() { + return (0, _util.shadow)(this, "tables", this.createTables(CFFPrivateDictLayout)); + } + constructor(strings) { + super(CFFPrivateDict.tables, strings); + this.subrsIndex = null; + } +} +exports.CFFPrivateDict = CFFPrivateDict; +const CFFCharsetPredefinedTypes = { + ISO_ADOBE: 0, + EXPERT: 1, + EXPERT_SUBSET: 2 +}; +class CFFCharset { + constructor(predefined, format, charset, raw) { + this.predefined = predefined; + this.format = format; + this.charset = charset; + this.raw = raw; + } +} +exports.CFFCharset = CFFCharset; +class CFFEncoding { + constructor(predefined, format, encoding, raw) { + this.predefined = predefined; + this.format = format; + this.encoding = encoding; + this.raw = raw; + } +} +class CFFFDSelect { + constructor(format, fdSelect) { + this.format = format; + this.fdSelect = fdSelect; + } + getFDIndex(glyphIndex) { + if (glyphIndex < 0 || glyphIndex >= this.fdSelect.length) { + return -1; + } + return this.fdSelect[glyphIndex]; + } +} +exports.CFFFDSelect = CFFFDSelect; +class CFFOffsetTracker { + constructor() { + this.offsets = Object.create(null); + } + isTracking(key) { + return key in this.offsets; + } + track(key, location) { + if (key in this.offsets) { + throw new _util.FormatError(`Already tracking location of ${key}`); + } + this.offsets[key] = location; + } + offset(value) { + for (const key in this.offsets) { + this.offsets[key] += value; + } + } + setEntryLocation(key, values, output) { + if (!(key in this.offsets)) { + throw new _util.FormatError(`Not tracking location of ${key}`); + } + const data = output.data; + const dataOffset = this.offsets[key]; + const size = 5; + for (let i = 0, ii = values.length; i < ii; ++i) { + const offset0 = i * size + dataOffset; + const offset1 = offset0 + 1; + const offset2 = offset0 + 2; + const offset3 = offset0 + 3; + const offset4 = offset0 + 4; + if (data[offset0] !== 0x1d || data[offset1] !== 0 || data[offset2] !== 0 || data[offset3] !== 0 || data[offset4] !== 0) { + throw new _util.FormatError("writing to an offset that is not empty"); + } + const value = values[i]; + data[offset0] = 0x1d; + data[offset1] = value >> 24 & 0xff; + data[offset2] = value >> 16 & 0xff; + data[offset3] = value >> 8 & 0xff; + data[offset4] = value & 0xff; + } + } +} +class CFFCompiler { + constructor(cff) { + this.cff = cff; + } + compile() { + const cff = this.cff; + const output = { + data: [], + length: 0, + add(data) { + try { + this.data.push(...data); + } catch { + this.data = this.data.concat(data); + } + this.length = this.data.length; + } + }; + const header = this.compileHeader(cff.header); + output.add(header); + const nameIndex = this.compileNameIndex(cff.names); + output.add(nameIndex); + if (cff.isCIDFont) { + if (cff.topDict.hasName("FontMatrix")) { + const base = cff.topDict.getByName("FontMatrix"); + cff.topDict.removeByName("FontMatrix"); + for (const subDict of cff.fdArray) { + let matrix = base.slice(0); + if (subDict.hasName("FontMatrix")) { + matrix = _util.Util.transform(matrix, subDict.getByName("FontMatrix")); + } + subDict.setByName("FontMatrix", matrix); + } + } + } + const xuid = cff.topDict.getByName("XUID"); + if (xuid?.length > 16) { + cff.topDict.removeByName("XUID"); + } + cff.topDict.setByName("charset", 0); + let compiled = this.compileTopDicts([cff.topDict], output.length, cff.isCIDFont); + output.add(compiled.output); + const topDictTracker = compiled.trackers[0]; + const stringIndex = this.compileStringIndex(cff.strings.strings); + output.add(stringIndex); + const globalSubrIndex = this.compileIndex(cff.globalSubrIndex); + output.add(globalSubrIndex); + if (cff.encoding && cff.topDict.hasName("Encoding")) { + if (cff.encoding.predefined) { + topDictTracker.setEntryLocation("Encoding", [cff.encoding.format], output); + } else { + const encoding = this.compileEncoding(cff.encoding); + topDictTracker.setEntryLocation("Encoding", [output.length], output); + output.add(encoding); + } + } + const charset = this.compileCharset(cff.charset, cff.charStrings.count, cff.strings, cff.isCIDFont); + topDictTracker.setEntryLocation("charset", [output.length], output); + output.add(charset); + const charStrings = this.compileCharStrings(cff.charStrings); + topDictTracker.setEntryLocation("CharStrings", [output.length], output); + output.add(charStrings); + if (cff.isCIDFont) { + topDictTracker.setEntryLocation("FDSelect", [output.length], output); + const fdSelect = this.compileFDSelect(cff.fdSelect); + output.add(fdSelect); + compiled = this.compileTopDicts(cff.fdArray, output.length, true); + topDictTracker.setEntryLocation("FDArray", [output.length], output); + output.add(compiled.output); + const fontDictTrackers = compiled.trackers; + this.compilePrivateDicts(cff.fdArray, fontDictTrackers, output); + } + this.compilePrivateDicts([cff.topDict], [topDictTracker], output); + output.add([0]); + return output.data; + } + encodeNumber(value) { + if (Number.isInteger(value)) { + return this.encodeInteger(value); + } + return this.encodeFloat(value); + } + static get EncodeFloatRegExp() { + return (0, _util.shadow)(this, "EncodeFloatRegExp", /\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/); + } + encodeFloat(num) { + let value = num.toString(); + const m = CFFCompiler.EncodeFloatRegExp.exec(value); + if (m) { + const epsilon = parseFloat("1e" + ((m[2] ? +m[2] : 0) + m[1].length)); + value = (Math.round(num * epsilon) / epsilon).toString(); + } + let nibbles = ""; + let i, ii; + for (i = 0, ii = value.length; i < ii; ++i) { + const a = value[i]; + if (a === "e") { + nibbles += value[++i] === "-" ? "c" : "b"; + } else if (a === ".") { + nibbles += "a"; + } else if (a === "-") { + nibbles += "e"; + } else { + nibbles += a; + } + } + nibbles += nibbles.length & 1 ? "f" : "ff"; + const out = [30]; + for (i = 0, ii = nibbles.length; i < ii; i += 2) { + out.push(parseInt(nibbles.substring(i, i + 2), 16)); + } + return out; + } + encodeInteger(value) { + let code; + if (value >= -107 && value <= 107) { + code = [value + 139]; + } else if (value >= 108 && value <= 1131) { + value -= 108; + code = [(value >> 8) + 247, value & 0xff]; + } else if (value >= -1131 && value <= -108) { + value = -value - 108; + code = [(value >> 8) + 251, value & 0xff]; + } else if (value >= -32768 && value <= 32767) { + code = [0x1c, value >> 8 & 0xff, value & 0xff]; + } else { + code = [0x1d, value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff]; + } + return code; + } + compileHeader(header) { + return [header.major, header.minor, 4, header.offSize]; + } + compileNameIndex(names) { + const nameIndex = new CFFIndex(); + for (const name of names) { + const length = Math.min(name.length, 127); + let sanitizedName = new Array(length); + for (let j = 0; j < length; j++) { + let char = name[j]; + if (char < "!" || char > "~" || char === "[" || char === "]" || char === "(" || char === ")" || char === "{" || char === "}" || char === "<" || char === ">" || char === "/" || char === "%") { + char = "_"; + } + sanitizedName[j] = char; + } + sanitizedName = sanitizedName.join(""); + if (sanitizedName === "") { + sanitizedName = "Bad_Font_Name"; + } + nameIndex.add((0, _util.stringToBytes)(sanitizedName)); + } + return this.compileIndex(nameIndex); + } + compileTopDicts(dicts, length, removeCidKeys) { + const fontDictTrackers = []; + let fdArrayIndex = new CFFIndex(); + for (const fontDict of dicts) { + if (removeCidKeys) { + fontDict.removeByName("CIDFontVersion"); + fontDict.removeByName("CIDFontRevision"); + fontDict.removeByName("CIDFontType"); + fontDict.removeByName("CIDCount"); + fontDict.removeByName("UIDBase"); + } + const fontDictTracker = new CFFOffsetTracker(); + const fontDictData = this.compileDict(fontDict, fontDictTracker); + fontDictTrackers.push(fontDictTracker); + fdArrayIndex.add(fontDictData); + fontDictTracker.offset(length); + } + fdArrayIndex = this.compileIndex(fdArrayIndex, fontDictTrackers); + return { + trackers: fontDictTrackers, + output: fdArrayIndex + }; + } + compilePrivateDicts(dicts, trackers, output) { + for (let i = 0, ii = dicts.length; i < ii; ++i) { + const fontDict = dicts[i]; + const privateDict = fontDict.privateDict; + if (!privateDict || !fontDict.hasName("Private")) { + throw new _util.FormatError("There must be a private dictionary."); + } + const privateDictTracker = new CFFOffsetTracker(); + const privateDictData = this.compileDict(privateDict, privateDictTracker); + let outputLength = output.length; + privateDictTracker.offset(outputLength); + if (!privateDictData.length) { + outputLength = 0; + } + trackers[i].setEntryLocation("Private", [privateDictData.length, outputLength], output); + output.add(privateDictData); + if (privateDict.subrsIndex && privateDict.hasName("Subrs")) { + const subrs = this.compileIndex(privateDict.subrsIndex); + privateDictTracker.setEntryLocation("Subrs", [privateDictData.length], output); + output.add(subrs); + } + } + } + compileDict(dict, offsetTracker) { + const out = []; + for (const key of dict.order) { + if (!(key in dict.values)) { + continue; + } + let values = dict.values[key]; + let types = dict.types[key]; + if (!Array.isArray(types)) { + types = [types]; + } + if (!Array.isArray(values)) { + values = [values]; + } + if (values.length === 0) { + continue; + } + for (let j = 0, jj = types.length; j < jj; ++j) { + const type = types[j]; + const value = values[j]; + switch (type) { + case "num": + case "sid": + out.push(...this.encodeNumber(value)); + break; + case "offset": + const name = dict.keyToNameMap[key]; + if (!offsetTracker.isTracking(name)) { + offsetTracker.track(name, out.length); + } + out.push(0x1d, 0, 0, 0, 0); + break; + case "array": + case "delta": + out.push(...this.encodeNumber(value)); + for (let k = 1, kk = values.length; k < kk; ++k) { + out.push(...this.encodeNumber(values[k])); + } + break; + default: + throw new _util.FormatError(`Unknown data type of ${type}`); + } + } + out.push(...dict.opcodes[key]); + } + return out; + } + compileStringIndex(strings) { + const stringIndex = new CFFIndex(); + for (const string of strings) { + stringIndex.add((0, _util.stringToBytes)(string)); + } + return this.compileIndex(stringIndex); + } + compileCharStrings(charStrings) { + const charStringsIndex = new CFFIndex(); + for (let i = 0; i < charStrings.count; i++) { + const glyph = charStrings.get(i); + if (glyph.length === 0) { + charStringsIndex.add(new Uint8Array([0x8b, 0x0e])); + continue; + } + charStringsIndex.add(glyph); + } + return this.compileIndex(charStringsIndex); + } + compileCharset(charset, numGlyphs, strings, isCIDFont) { + let out; + const numGlyphsLessNotDef = numGlyphs - 1; + if (isCIDFont) { + out = new Uint8Array([2, 0, 0, numGlyphsLessNotDef >> 8 & 0xff, numGlyphsLessNotDef & 0xff]); + } else { + const length = 1 + numGlyphsLessNotDef * 2; + out = new Uint8Array(length); + out[0] = 0; + let charsetIndex = 0; + const numCharsets = charset.charset.length; + let warned = false; + for (let i = 1; i < out.length; i += 2) { + let sid = 0; + if (charsetIndex < numCharsets) { + const name = charset.charset[charsetIndex++]; + sid = strings.getSID(name); + if (sid === -1) { + sid = 0; + if (!warned) { + warned = true; + (0, _util.warn)(`Couldn't find ${name} in CFF strings`); + } + } + } + out[i] = sid >> 8 & 0xff; + out[i + 1] = sid & 0xff; + } + } + return this.compileTypedArray(out); + } + compileEncoding(encoding) { + return this.compileTypedArray(encoding.raw); + } + compileFDSelect(fdSelect) { + const format = fdSelect.format; + let out, i; + switch (format) { + case 0: + out = new Uint8Array(1 + fdSelect.fdSelect.length); + out[0] = format; + for (i = 0; i < fdSelect.fdSelect.length; i++) { + out[i + 1] = fdSelect.fdSelect[i]; + } + break; + case 3: + const start = 0; + let lastFD = fdSelect.fdSelect[0]; + const ranges = [format, 0, 0, start >> 8 & 0xff, start & 0xff, lastFD]; + for (i = 1; i < fdSelect.fdSelect.length; i++) { + const currentFD = fdSelect.fdSelect[i]; + if (currentFD !== lastFD) { + ranges.push(i >> 8 & 0xff, i & 0xff, currentFD); + lastFD = currentFD; + } + } + const numRanges = (ranges.length - 3) / 3; + ranges[1] = numRanges >> 8 & 0xff; + ranges[2] = numRanges & 0xff; + ranges.push(i >> 8 & 0xff, i & 0xff); + out = new Uint8Array(ranges); + break; + } + return this.compileTypedArray(out); + } + compileTypedArray(data) { + return Array.from(data); + } + compileIndex(index, trackers = []) { + const objects = index.objects; + const count = objects.length; + if (count === 0) { + return [0, 0]; + } + const data = [count >> 8 & 0xff, count & 0xff]; + let lastOffset = 1, + i; + for (i = 0; i < count; ++i) { + lastOffset += objects[i].length; + } + let offsetSize; + if (lastOffset < 0x100) { + offsetSize = 1; + } else if (lastOffset < 0x10000) { + offsetSize = 2; + } else if (lastOffset < 0x1000000) { + offsetSize = 3; + } else { + offsetSize = 4; + } + data.push(offsetSize); + let relativeOffset = 1; + for (i = 0; i < count + 1; i++) { + if (offsetSize === 1) { + data.push(relativeOffset & 0xff); + } else if (offsetSize === 2) { + data.push(relativeOffset >> 8 & 0xff, relativeOffset & 0xff); + } else if (offsetSize === 3) { + data.push(relativeOffset >> 16 & 0xff, relativeOffset >> 8 & 0xff, relativeOffset & 0xff); + } else { + data.push(relativeOffset >>> 24 & 0xff, relativeOffset >> 16 & 0xff, relativeOffset >> 8 & 0xff, relativeOffset & 0xff); + } + if (objects[i]) { + relativeOffset += objects[i].length; + } + } + for (i = 0; i < count; i++) { + if (trackers[i]) { + trackers[i].offset(data.length); + } + data.push(...objects[i]); + } + return data; + } +} +exports.CFFCompiler = CFFCompiler; + +/***/ }), +/* 36 */ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ISOAdobeCharset = exports.ExpertSubsetCharset = exports.ExpertCharset = void 0; +const ISOAdobeCharset = [".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar", "degree", "thorn", "threequarters", "twosuperior", "registered", "minus", "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", "ydieresis", "zcaron"]; +exports.ISOAdobeCharset = ISOAdobeCharset; +const ExpertCharset = [".notdef", "space", "exclamsmall", "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", "onequarter", "onehalf", "threequarters", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall"]; +exports.ExpertCharset = ExpertCharset; +const ExpertSubsetCharset = [".notdef", "space", "dollaroldstyle", "dollarsuperior", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", "threequartersemdash", "periodsuperior", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "hyphensuperior", "colonmonetary", "onefitted", "rupiah", "centoldstyle", "figuredash", "hypheninferior", "onequarter", "onehalf", "threequarters", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior"]; +exports.ExpertSubsetCharset = ExpertSubsetCharset; + +/***/ }), +/* 37 */ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ZapfDingbatsEncoding = exports.WinAnsiEncoding = exports.SymbolSetEncoding = exports.StandardEncoding = exports.MacRomanEncoding = exports.ExpertEncoding = void 0; +exports.getEncoding = getEncoding; +const ExpertEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclamsmall", "Hungarumlautsmall", "", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "", "", "", "isuperior", "", "", "lsuperior", "msuperior", "nsuperior", "osuperior", "", "", "rsuperior", "ssuperior", "tsuperior", "", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "exclamdownsmall", "centoldstyle", "Lslashsmall", "", "", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "", "Dotaccentsmall", "", "", "Macronsmall", "", "", "figuredash", "hypheninferior", "", "", "Ogoneksmall", "Ringsmall", "Cedillasmall", "", "", "", "onequarter", "onehalf", "threequarters", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "", "", "zerosuperior", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall"]; +exports.ExpertEncoding = ExpertEncoding; +const MacExpertEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclamsmall", "Hungarumlautsmall", "centoldstyle", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon", "", "threequartersemdash", "", "questionsmall", "", "", "", "", "Ethsmall", "", "", "onequarter", "onehalf", "threequarters", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "", "", "", "", "", "", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "", "parenrightinferior", "Circumflexsmall", "hypheninferior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "", "", "asuperior", "centsuperior", "", "", "", "", "Aacutesmall", "Agravesmall", "Acircumflexsmall", "Adieresissmall", "Atildesmall", "Aringsmall", "Ccedillasmall", "Eacutesmall", "Egravesmall", "Ecircumflexsmall", "Edieresissmall", "Iacutesmall", "Igravesmall", "Icircumflexsmall", "Idieresissmall", "Ntildesmall", "Oacutesmall", "Ogravesmall", "Ocircumflexsmall", "Odieresissmall", "Otildesmall", "Uacutesmall", "Ugravesmall", "Ucircumflexsmall", "Udieresissmall", "", "eightsuperior", "fourinferior", "threeinferior", "sixinferior", "eightinferior", "seveninferior", "Scaronsmall", "", "centinferior", "twoinferior", "", "Dieresissmall", "", "Caronsmall", "osuperior", "fiveinferior", "", "commainferior", "periodinferior", "Yacutesmall", "", "dollarinferior", "", "", "Thornsmall", "", "nineinferior", "zeroinferior", "Zcaronsmall", "AEsmall", "Oslashsmall", "questiondownsmall", "oneinferior", "Lslashsmall", "", "", "", "", "", "", "Cedillasmall", "", "", "", "", "", "OEsmall", "figuredash", "hyphensuperior", "", "", "", "", "exclamdownsmall", "", "Ydieresissmall", "", "onesuperior", "twosuperior", "threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "ninesuperior", "zerosuperior", "", "esuperior", "rsuperior", "tsuperior", "", "", "isuperior", "ssuperior", "dsuperior", "", "", "", "", "", "lsuperior", "Ogoneksmall", "Brevesmall", "Macronsmall", "bsuperior", "nsuperior", "msuperior", "commasuperior", "periodsuperior", "Dotaccentsmall", "Ringsmall", "", "", "", ""]; +const MacRomanEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "", "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section", "bullet", "paragraph", "germandbls", "registered", "copyright", "trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", "mu", "partialdiff", "summation", "product", "pi", "integral", "ordfeminine", "ordmasculine", "Omega", "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "Delta", "guillemotleft", "guillemotright", "ellipsis", "space", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", "caron"]; +exports.MacRomanEncoding = MacRomanEncoding; +const StandardEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "", "endash", "dagger", "daggerdbl", "periodcentered", "", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "", "questiondown", "", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "", "ring", "cedilla", "", "hungarumlaut", "ogonek", "caron", "emdash", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AE", "", "ordfeminine", "", "", "", "", "Lslash", "Oslash", "OE", "ordmasculine", "", "", "", "", "", "ae", "", "", "", "dotlessi", "", "", "lslash", "oslash", "oe", "germandbls", "", "", "", ""]; +exports.StandardEncoding = StandardEncoding; +const WinAnsiEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "bullet", "Euro", "bullet", "quotesinglbase", "florin", "quotedblbase", "ellipsis", "dagger", "daggerdbl", "circumflex", "perthousand", "Scaron", "guilsinglleft", "OE", "bullet", "Zcaron", "bullet", "bullet", "quoteleft", "quoteright", "quotedblleft", "quotedblright", "bullet", "endash", "emdash", "tilde", "trademark", "scaron", "guilsinglright", "oe", "bullet", "zcaron", "Ydieresis", "space", "exclamdown", "cent", "sterling", "currency", "yen", "brokenbar", "section", "dieresis", "copyright", "ordfeminine", "guillemotleft", "logicalnot", "hyphen", "registered", "macron", "degree", "plusminus", "twosuperior", "threesuperior", "acute", "mu", "paragraph", "periodcentered", "cedilla", "onesuperior", "ordmasculine", "guillemotright", "onequarter", "onehalf", "threequarters", "questiondown", "Agrave", "Aacute", "Acircumflex", "Atilde", "Adieresis", "Aring", "AE", "Ccedilla", "Egrave", "Eacute", "Ecircumflex", "Edieresis", "Igrave", "Iacute", "Icircumflex", "Idieresis", "Eth", "Ntilde", "Ograve", "Oacute", "Ocircumflex", "Otilde", "Odieresis", "multiply", "Oslash", "Ugrave", "Uacute", "Ucircumflex", "Udieresis", "Yacute", "Thorn", "germandbls", "agrave", "aacute", "acircumflex", "atilde", "adieresis", "aring", "ae", "ccedilla", "egrave", "eacute", "ecircumflex", "edieresis", "igrave", "iacute", "icircumflex", "idieresis", "eth", "ntilde", "ograve", "oacute", "ocircumflex", "otilde", "odieresis", "divide", "oslash", "ugrave", "uacute", "ucircumflex", "udieresis", "yacute", "thorn", "ydieresis"]; +exports.WinAnsiEncoding = WinAnsiEncoding; +const SymbolSetEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "universal", "numbersign", "existential", "percent", "ampersand", "suchthat", "parenleft", "parenright", "asteriskmath", "plus", "comma", "minus", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "congruent", "Alpha", "Beta", "Chi", "Delta", "Epsilon", "Phi", "Gamma", "Eta", "Iota", "theta1", "Kappa", "Lambda", "Mu", "Nu", "Omicron", "Pi", "Theta", "Rho", "Sigma", "Tau", "Upsilon", "sigma1", "Omega", "Xi", "Psi", "Zeta", "bracketleft", "therefore", "bracketright", "perpendicular", "underscore", "radicalex", "alpha", "beta", "chi", "delta", "epsilon", "phi", "gamma", "eta", "iota", "phi1", "kappa", "lambda", "mu", "nu", "omicron", "pi", "theta", "rho", "sigma", "tau", "upsilon", "omega1", "omega", "xi", "psi", "zeta", "braceleft", "bar", "braceright", "similar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Euro", "Upsilon1", "minute", "lessequal", "fraction", "infinity", "florin", "club", "diamond", "heart", "spade", "arrowboth", "arrowleft", "arrowup", "arrowright", "arrowdown", "degree", "plusminus", "second", "greaterequal", "multiply", "proportional", "partialdiff", "bullet", "divide", "notequal", "equivalence", "approxequal", "ellipsis", "arrowvertex", "arrowhorizex", "carriagereturn", "aleph", "Ifraktur", "Rfraktur", "weierstrass", "circlemultiply", "circleplus", "emptyset", "intersection", "union", "propersuperset", "reflexsuperset", "notsubset", "propersubset", "reflexsubset", "element", "notelement", "angle", "gradient", "registerserif", "copyrightserif", "trademarkserif", "product", "radical", "dotmath", "logicalnot", "logicaland", "logicalor", "arrowdblboth", "arrowdblleft", "arrowdblup", "arrowdblright", "arrowdbldown", "lozenge", "angleleft", "registersans", "copyrightsans", "trademarksans", "summation", "parenlefttp", "parenleftex", "parenleftbt", "bracketlefttp", "bracketleftex", "bracketleftbt", "bracelefttp", "braceleftmid", "braceleftbt", "braceex", "", "angleright", "integral", "integraltp", "integralex", "integralbt", "parenrighttp", "parenrightex", "parenrightbt", "bracketrighttp", "bracketrightex", "bracketrightbt", "bracerighttp", "bracerightmid", "bracerightbt", ""]; +exports.SymbolSetEncoding = SymbolSetEncoding; +const ZapfDingbatsEncoding = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "a1", "a2", "a202", "a3", "a4", "a5", "a119", "a118", "a117", "a11", "a12", "a13", "a14", "a15", "a16", "a105", "a17", "a18", "a19", "a20", "a21", "a22", "a23", "a24", "a25", "a26", "a27", "a28", "a6", "a7", "a8", "a9", "a10", "a29", "a30", "a31", "a32", "a33", "a34", "a35", "a36", "a37", "a38", "a39", "a40", "a41", "a42", "a43", "a44", "a45", "a46", "a47", "a48", "a49", "a50", "a51", "a52", "a53", "a54", "a55", "a56", "a57", "a58", "a59", "a60", "a61", "a62", "a63", "a64", "a65", "a66", "a67", "a68", "a69", "a70", "a71", "a72", "a73", "a74", "a203", "a75", "a204", "a76", "a77", "a78", "a79", "a81", "a82", "a83", "a84", "a97", "a98", "a99", "a100", "", "a89", "a90", "a93", "a94", "a91", "a92", "a205", "a85", "a206", "a86", "a87", "a88", "a95", "a96", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "a101", "a102", "a103", "a104", "a106", "a107", "a108", "a112", "a111", "a110", "a109", "a120", "a121", "a122", "a123", "a124", "a125", "a126", "a127", "a128", "a129", "a130", "a131", "a132", "a133", "a134", "a135", "a136", "a137", "a138", "a139", "a140", "a141", "a142", "a143", "a144", "a145", "a146", "a147", "a148", "a149", "a150", "a151", "a152", "a153", "a154", "a155", "a156", "a157", "a158", "a159", "a160", "a161", "a163", "a164", "a196", "a165", "a192", "a166", "a167", "a168", "a169", "a170", "a171", "a172", "a173", "a162", "a174", "a175", "a176", "a177", "a178", "a179", "a193", "a180", "a199", "a181", "a200", "a182", "", "a201", "a183", "a184", "a197", "a185", "a194", "a198", "a186", "a195", "a187", "a188", "a189", "a190", "a191", ""]; +exports.ZapfDingbatsEncoding = ZapfDingbatsEncoding; +function getEncoding(encodingName) { + switch (encodingName) { + case "WinAnsiEncoding": + return WinAnsiEncoding; + case "StandardEncoding": + return StandardEncoding; + case "MacRomanEncoding": + return MacRomanEncoding; + case "SymbolSetEncoding": + return SymbolSetEncoding; + case "ZapfDingbatsEncoding": + return ZapfDingbatsEncoding; + case "ExpertEncoding": + return ExpertEncoding; + case "MacExpertEncoding": + return MacExpertEncoding; + default: + return null; + } +} + +/***/ }), +/* 38 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.SEAC_ANALYSIS_ENABLED = exports.MacStandardGlyphOrdering = exports.FontFlags = void 0; +exports.normalizeFontName = normalizeFontName; +exports.recoverGlyphName = recoverGlyphName; +exports.type1FontGlyphMapping = type1FontGlyphMapping; +var _encodings = __w_pdfjs_require__(37); +var _glyphlist = __w_pdfjs_require__(39); +var _unicode = __w_pdfjs_require__(40); +var _util = __w_pdfjs_require__(2); +const SEAC_ANALYSIS_ENABLED = true; +exports.SEAC_ANALYSIS_ENABLED = SEAC_ANALYSIS_ENABLED; +const FontFlags = { + FixedPitch: 1, + Serif: 2, + Symbolic: 4, + Script: 8, + Nonsymbolic: 32, + Italic: 64, + AllCap: 65536, + SmallCap: 131072, + ForceBold: 262144 +}; +exports.FontFlags = FontFlags; +const MacStandardGlyphOrdering = [".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section", "bullet", "paragraph", "germandbls", "registered", "copyright", "trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", "mu", "partialdiff", "summation", "product", "pi", "integral", "ordfeminine", "ordmasculine", "Omega", "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "Delta", "guillemotleft", "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron", "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn", "thorn", "minus", "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter", "threequarters", "franc", "Gbreve", "gbreve", "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron", "ccaron", "dcroat"]; +exports.MacStandardGlyphOrdering = MacStandardGlyphOrdering; +function recoverGlyphName(name, glyphsUnicodeMap) { + if (glyphsUnicodeMap[name] !== undefined) { + return name; + } + const unicode = (0, _unicode.getUnicodeForGlyph)(name, glyphsUnicodeMap); + if (unicode !== -1) { + for (const key in glyphsUnicodeMap) { + if (glyphsUnicodeMap[key] === unicode) { + return key; + } + } + } + (0, _util.info)("Unable to recover a standard glyph name for: " + name); + return name; +} +function type1FontGlyphMapping(properties, builtInEncoding, glyphNames) { + const charCodeToGlyphId = Object.create(null); + let glyphId, charCode, baseEncoding; + const isSymbolicFont = !!(properties.flags & FontFlags.Symbolic); + if (properties.isInternalFont) { + baseEncoding = builtInEncoding; + for (charCode = 0; charCode < baseEncoding.length; charCode++) { + glyphId = glyphNames.indexOf(baseEncoding[charCode]); + charCodeToGlyphId[charCode] = glyphId >= 0 ? glyphId : 0; + } + } else if (properties.baseEncodingName) { + baseEncoding = (0, _encodings.getEncoding)(properties.baseEncodingName); + for (charCode = 0; charCode < baseEncoding.length; charCode++) { + glyphId = glyphNames.indexOf(baseEncoding[charCode]); + charCodeToGlyphId[charCode] = glyphId >= 0 ? glyphId : 0; + } + } else if (isSymbolicFont) { + for (charCode in builtInEncoding) { + charCodeToGlyphId[charCode] = builtInEncoding[charCode]; + } + } else { + baseEncoding = _encodings.StandardEncoding; + for (charCode = 0; charCode < baseEncoding.length; charCode++) { + glyphId = glyphNames.indexOf(baseEncoding[charCode]); + charCodeToGlyphId[charCode] = glyphId >= 0 ? glyphId : 0; + } + } + const differences = properties.differences; + let glyphsUnicodeMap; + if (differences) { + for (charCode in differences) { + const glyphName = differences[charCode]; + glyphId = glyphNames.indexOf(glyphName); + if (glyphId === -1) { + if (!glyphsUnicodeMap) { + glyphsUnicodeMap = (0, _glyphlist.getGlyphsUnicode)(); + } + const standardGlyphName = recoverGlyphName(glyphName, glyphsUnicodeMap); + if (standardGlyphName !== glyphName) { + glyphId = glyphNames.indexOf(standardGlyphName); + } + } + charCodeToGlyphId[charCode] = glyphId >= 0 ? glyphId : 0; + } + } + return charCodeToGlyphId; +} +function normalizeFontName(name) { + return name.replaceAll(/[,_]/g, "-").replaceAll(/\s/g, ""); +} + +/***/ }), +/* 39 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getGlyphsUnicode = exports.getDingbatsGlyphsUnicode = void 0; +var _core_utils = __w_pdfjs_require__(3); +const getGlyphsUnicode = (0, _core_utils.getLookupTableFactory)(function (t) { + t.A = 0x0041; + t.AE = 0x00c6; + t.AEacute = 0x01fc; + t.AEmacron = 0x01e2; + t.AEsmall = 0xf7e6; + t.Aacute = 0x00c1; + t.Aacutesmall = 0xf7e1; + t.Abreve = 0x0102; + t.Abreveacute = 0x1eae; + t.Abrevecyrillic = 0x04d0; + t.Abrevedotbelow = 0x1eb6; + t.Abrevegrave = 0x1eb0; + t.Abrevehookabove = 0x1eb2; + t.Abrevetilde = 0x1eb4; + t.Acaron = 0x01cd; + t.Acircle = 0x24b6; + t.Acircumflex = 0x00c2; + t.Acircumflexacute = 0x1ea4; + t.Acircumflexdotbelow = 0x1eac; + t.Acircumflexgrave = 0x1ea6; + t.Acircumflexhookabove = 0x1ea8; + t.Acircumflexsmall = 0xf7e2; + t.Acircumflextilde = 0x1eaa; + t.Acute = 0xf6c9; + t.Acutesmall = 0xf7b4; + t.Acyrillic = 0x0410; + t.Adblgrave = 0x0200; + t.Adieresis = 0x00c4; + t.Adieresiscyrillic = 0x04d2; + t.Adieresismacron = 0x01de; + t.Adieresissmall = 0xf7e4; + t.Adotbelow = 0x1ea0; + t.Adotmacron = 0x01e0; + t.Agrave = 0x00c0; + t.Agravesmall = 0xf7e0; + t.Ahookabove = 0x1ea2; + t.Aiecyrillic = 0x04d4; + t.Ainvertedbreve = 0x0202; + t.Alpha = 0x0391; + t.Alphatonos = 0x0386; + t.Amacron = 0x0100; + t.Amonospace = 0xff21; + t.Aogonek = 0x0104; + t.Aring = 0x00c5; + t.Aringacute = 0x01fa; + t.Aringbelow = 0x1e00; + t.Aringsmall = 0xf7e5; + t.Asmall = 0xf761; + t.Atilde = 0x00c3; + t.Atildesmall = 0xf7e3; + t.Aybarmenian = 0x0531; + t.B = 0x0042; + t.Bcircle = 0x24b7; + t.Bdotaccent = 0x1e02; + t.Bdotbelow = 0x1e04; + t.Becyrillic = 0x0411; + t.Benarmenian = 0x0532; + t.Beta = 0x0392; + t.Bhook = 0x0181; + t.Blinebelow = 0x1e06; + t.Bmonospace = 0xff22; + t.Brevesmall = 0xf6f4; + t.Bsmall = 0xf762; + t.Btopbar = 0x0182; + t.C = 0x0043; + t.Caarmenian = 0x053e; + t.Cacute = 0x0106; + t.Caron = 0xf6ca; + t.Caronsmall = 0xf6f5; + t.Ccaron = 0x010c; + t.Ccedilla = 0x00c7; + t.Ccedillaacute = 0x1e08; + t.Ccedillasmall = 0xf7e7; + t.Ccircle = 0x24b8; + t.Ccircumflex = 0x0108; + t.Cdot = 0x010a; + t.Cdotaccent = 0x010a; + t.Cedillasmall = 0xf7b8; + t.Chaarmenian = 0x0549; + t.Cheabkhasiancyrillic = 0x04bc; + t.Checyrillic = 0x0427; + t.Chedescenderabkhasiancyrillic = 0x04be; + t.Chedescendercyrillic = 0x04b6; + t.Chedieresiscyrillic = 0x04f4; + t.Cheharmenian = 0x0543; + t.Chekhakassiancyrillic = 0x04cb; + t.Cheverticalstrokecyrillic = 0x04b8; + t.Chi = 0x03a7; + t.Chook = 0x0187; + t.Circumflexsmall = 0xf6f6; + t.Cmonospace = 0xff23; + t.Coarmenian = 0x0551; + t.Csmall = 0xf763; + t.D = 0x0044; + t.DZ = 0x01f1; + t.DZcaron = 0x01c4; + t.Daarmenian = 0x0534; + t.Dafrican = 0x0189; + t.Dcaron = 0x010e; + t.Dcedilla = 0x1e10; + t.Dcircle = 0x24b9; + t.Dcircumflexbelow = 0x1e12; + t.Dcroat = 0x0110; + t.Ddotaccent = 0x1e0a; + t.Ddotbelow = 0x1e0c; + t.Decyrillic = 0x0414; + t.Deicoptic = 0x03ee; + t.Delta = 0x2206; + t.Deltagreek = 0x0394; + t.Dhook = 0x018a; + t.Dieresis = 0xf6cb; + t.DieresisAcute = 0xf6cc; + t.DieresisGrave = 0xf6cd; + t.Dieresissmall = 0xf7a8; + t.Digammagreek = 0x03dc; + t.Djecyrillic = 0x0402; + t.Dlinebelow = 0x1e0e; + t.Dmonospace = 0xff24; + t.Dotaccentsmall = 0xf6f7; + t.Dslash = 0x0110; + t.Dsmall = 0xf764; + t.Dtopbar = 0x018b; + t.Dz = 0x01f2; + t.Dzcaron = 0x01c5; + t.Dzeabkhasiancyrillic = 0x04e0; + t.Dzecyrillic = 0x0405; + t.Dzhecyrillic = 0x040f; + t.E = 0x0045; + t.Eacute = 0x00c9; + t.Eacutesmall = 0xf7e9; + t.Ebreve = 0x0114; + t.Ecaron = 0x011a; + t.Ecedillabreve = 0x1e1c; + t.Echarmenian = 0x0535; + t.Ecircle = 0x24ba; + t.Ecircumflex = 0x00ca; + t.Ecircumflexacute = 0x1ebe; + t.Ecircumflexbelow = 0x1e18; + t.Ecircumflexdotbelow = 0x1ec6; + t.Ecircumflexgrave = 0x1ec0; + t.Ecircumflexhookabove = 0x1ec2; + t.Ecircumflexsmall = 0xf7ea; + t.Ecircumflextilde = 0x1ec4; + t.Ecyrillic = 0x0404; + t.Edblgrave = 0x0204; + t.Edieresis = 0x00cb; + t.Edieresissmall = 0xf7eb; + t.Edot = 0x0116; + t.Edotaccent = 0x0116; + t.Edotbelow = 0x1eb8; + t.Efcyrillic = 0x0424; + t.Egrave = 0x00c8; + t.Egravesmall = 0xf7e8; + t.Eharmenian = 0x0537; + t.Ehookabove = 0x1eba; + t.Eightroman = 0x2167; + t.Einvertedbreve = 0x0206; + t.Eiotifiedcyrillic = 0x0464; + t.Elcyrillic = 0x041b; + t.Elevenroman = 0x216a; + t.Emacron = 0x0112; + t.Emacronacute = 0x1e16; + t.Emacrongrave = 0x1e14; + t.Emcyrillic = 0x041c; + t.Emonospace = 0xff25; + t.Encyrillic = 0x041d; + t.Endescendercyrillic = 0x04a2; + t.Eng = 0x014a; + t.Enghecyrillic = 0x04a4; + t.Enhookcyrillic = 0x04c7; + t.Eogonek = 0x0118; + t.Eopen = 0x0190; + t.Epsilon = 0x0395; + t.Epsilontonos = 0x0388; + t.Ercyrillic = 0x0420; + t.Ereversed = 0x018e; + t.Ereversedcyrillic = 0x042d; + t.Escyrillic = 0x0421; + t.Esdescendercyrillic = 0x04aa; + t.Esh = 0x01a9; + t.Esmall = 0xf765; + t.Eta = 0x0397; + t.Etarmenian = 0x0538; + t.Etatonos = 0x0389; + t.Eth = 0x00d0; + t.Ethsmall = 0xf7f0; + t.Etilde = 0x1ebc; + t.Etildebelow = 0x1e1a; + t.Euro = 0x20ac; + t.Ezh = 0x01b7; + t.Ezhcaron = 0x01ee; + t.Ezhreversed = 0x01b8; + t.F = 0x0046; + t.Fcircle = 0x24bb; + t.Fdotaccent = 0x1e1e; + t.Feharmenian = 0x0556; + t.Feicoptic = 0x03e4; + t.Fhook = 0x0191; + t.Fitacyrillic = 0x0472; + t.Fiveroman = 0x2164; + t.Fmonospace = 0xff26; + t.Fourroman = 0x2163; + t.Fsmall = 0xf766; + t.G = 0x0047; + t.GBsquare = 0x3387; + t.Gacute = 0x01f4; + t.Gamma = 0x0393; + t.Gammaafrican = 0x0194; + t.Gangiacoptic = 0x03ea; + t.Gbreve = 0x011e; + t.Gcaron = 0x01e6; + t.Gcedilla = 0x0122; + t.Gcircle = 0x24bc; + t.Gcircumflex = 0x011c; + t.Gcommaaccent = 0x0122; + t.Gdot = 0x0120; + t.Gdotaccent = 0x0120; + t.Gecyrillic = 0x0413; + t.Ghadarmenian = 0x0542; + t.Ghemiddlehookcyrillic = 0x0494; + t.Ghestrokecyrillic = 0x0492; + t.Gheupturncyrillic = 0x0490; + t.Ghook = 0x0193; + t.Gimarmenian = 0x0533; + t.Gjecyrillic = 0x0403; + t.Gmacron = 0x1e20; + t.Gmonospace = 0xff27; + t.Grave = 0xf6ce; + t.Gravesmall = 0xf760; + t.Gsmall = 0xf767; + t.Gsmallhook = 0x029b; + t.Gstroke = 0x01e4; + t.H = 0x0048; + t.H18533 = 0x25cf; + t.H18543 = 0x25aa; + t.H18551 = 0x25ab; + t.H22073 = 0x25a1; + t.HPsquare = 0x33cb; + t.Haabkhasiancyrillic = 0x04a8; + t.Hadescendercyrillic = 0x04b2; + t.Hardsigncyrillic = 0x042a; + t.Hbar = 0x0126; + t.Hbrevebelow = 0x1e2a; + t.Hcedilla = 0x1e28; + t.Hcircle = 0x24bd; + t.Hcircumflex = 0x0124; + t.Hdieresis = 0x1e26; + t.Hdotaccent = 0x1e22; + t.Hdotbelow = 0x1e24; + t.Hmonospace = 0xff28; + t.Hoarmenian = 0x0540; + t.Horicoptic = 0x03e8; + t.Hsmall = 0xf768; + t.Hungarumlaut = 0xf6cf; + t.Hungarumlautsmall = 0xf6f8; + t.Hzsquare = 0x3390; + t.I = 0x0049; + t.IAcyrillic = 0x042f; + t.IJ = 0x0132; + t.IUcyrillic = 0x042e; + t.Iacute = 0x00cd; + t.Iacutesmall = 0xf7ed; + t.Ibreve = 0x012c; + t.Icaron = 0x01cf; + t.Icircle = 0x24be; + t.Icircumflex = 0x00ce; + t.Icircumflexsmall = 0xf7ee; + t.Icyrillic = 0x0406; + t.Idblgrave = 0x0208; + t.Idieresis = 0x00cf; + t.Idieresisacute = 0x1e2e; + t.Idieresiscyrillic = 0x04e4; + t.Idieresissmall = 0xf7ef; + t.Idot = 0x0130; + t.Idotaccent = 0x0130; + t.Idotbelow = 0x1eca; + t.Iebrevecyrillic = 0x04d6; + t.Iecyrillic = 0x0415; + t.Ifraktur = 0x2111; + t.Igrave = 0x00cc; + t.Igravesmall = 0xf7ec; + t.Ihookabove = 0x1ec8; + t.Iicyrillic = 0x0418; + t.Iinvertedbreve = 0x020a; + t.Iishortcyrillic = 0x0419; + t.Imacron = 0x012a; + t.Imacroncyrillic = 0x04e2; + t.Imonospace = 0xff29; + t.Iniarmenian = 0x053b; + t.Iocyrillic = 0x0401; + t.Iogonek = 0x012e; + t.Iota = 0x0399; + t.Iotaafrican = 0x0196; + t.Iotadieresis = 0x03aa; + t.Iotatonos = 0x038a; + t.Ismall = 0xf769; + t.Istroke = 0x0197; + t.Itilde = 0x0128; + t.Itildebelow = 0x1e2c; + t.Izhitsacyrillic = 0x0474; + t.Izhitsadblgravecyrillic = 0x0476; + t.J = 0x004a; + t.Jaarmenian = 0x0541; + t.Jcircle = 0x24bf; + t.Jcircumflex = 0x0134; + t.Jecyrillic = 0x0408; + t.Jheharmenian = 0x054b; + t.Jmonospace = 0xff2a; + t.Jsmall = 0xf76a; + t.K = 0x004b; + t.KBsquare = 0x3385; + t.KKsquare = 0x33cd; + t.Kabashkircyrillic = 0x04a0; + t.Kacute = 0x1e30; + t.Kacyrillic = 0x041a; + t.Kadescendercyrillic = 0x049a; + t.Kahookcyrillic = 0x04c3; + t.Kappa = 0x039a; + t.Kastrokecyrillic = 0x049e; + t.Kaverticalstrokecyrillic = 0x049c; + t.Kcaron = 0x01e8; + t.Kcedilla = 0x0136; + t.Kcircle = 0x24c0; + t.Kcommaaccent = 0x0136; + t.Kdotbelow = 0x1e32; + t.Keharmenian = 0x0554; + t.Kenarmenian = 0x053f; + t.Khacyrillic = 0x0425; + t.Kheicoptic = 0x03e6; + t.Khook = 0x0198; + t.Kjecyrillic = 0x040c; + t.Klinebelow = 0x1e34; + t.Kmonospace = 0xff2b; + t.Koppacyrillic = 0x0480; + t.Koppagreek = 0x03de; + t.Ksicyrillic = 0x046e; + t.Ksmall = 0xf76b; + t.L = 0x004c; + t.LJ = 0x01c7; + t.LL = 0xf6bf; + t.Lacute = 0x0139; + t.Lambda = 0x039b; + t.Lcaron = 0x013d; + t.Lcedilla = 0x013b; + t.Lcircle = 0x24c1; + t.Lcircumflexbelow = 0x1e3c; + t.Lcommaaccent = 0x013b; + t.Ldot = 0x013f; + t.Ldotaccent = 0x013f; + t.Ldotbelow = 0x1e36; + t.Ldotbelowmacron = 0x1e38; + t.Liwnarmenian = 0x053c; + t.Lj = 0x01c8; + t.Ljecyrillic = 0x0409; + t.Llinebelow = 0x1e3a; + t.Lmonospace = 0xff2c; + t.Lslash = 0x0141; + t.Lslashsmall = 0xf6f9; + t.Lsmall = 0xf76c; + t.M = 0x004d; + t.MBsquare = 0x3386; + t.Macron = 0xf6d0; + t.Macronsmall = 0xf7af; + t.Macute = 0x1e3e; + t.Mcircle = 0x24c2; + t.Mdotaccent = 0x1e40; + t.Mdotbelow = 0x1e42; + t.Menarmenian = 0x0544; + t.Mmonospace = 0xff2d; + t.Msmall = 0xf76d; + t.Mturned = 0x019c; + t.Mu = 0x039c; + t.N = 0x004e; + t.NJ = 0x01ca; + t.Nacute = 0x0143; + t.Ncaron = 0x0147; + t.Ncedilla = 0x0145; + t.Ncircle = 0x24c3; + t.Ncircumflexbelow = 0x1e4a; + t.Ncommaaccent = 0x0145; + t.Ndotaccent = 0x1e44; + t.Ndotbelow = 0x1e46; + t.Nhookleft = 0x019d; + t.Nineroman = 0x2168; + t.Nj = 0x01cb; + t.Njecyrillic = 0x040a; + t.Nlinebelow = 0x1e48; + t.Nmonospace = 0xff2e; + t.Nowarmenian = 0x0546; + t.Nsmall = 0xf76e; + t.Ntilde = 0x00d1; + t.Ntildesmall = 0xf7f1; + t.Nu = 0x039d; + t.O = 0x004f; + t.OE = 0x0152; + t.OEsmall = 0xf6fa; + t.Oacute = 0x00d3; + t.Oacutesmall = 0xf7f3; + t.Obarredcyrillic = 0x04e8; + t.Obarreddieresiscyrillic = 0x04ea; + t.Obreve = 0x014e; + t.Ocaron = 0x01d1; + t.Ocenteredtilde = 0x019f; + t.Ocircle = 0x24c4; + t.Ocircumflex = 0x00d4; + t.Ocircumflexacute = 0x1ed0; + t.Ocircumflexdotbelow = 0x1ed8; + t.Ocircumflexgrave = 0x1ed2; + t.Ocircumflexhookabove = 0x1ed4; + t.Ocircumflexsmall = 0xf7f4; + t.Ocircumflextilde = 0x1ed6; + t.Ocyrillic = 0x041e; + t.Odblacute = 0x0150; + t.Odblgrave = 0x020c; + t.Odieresis = 0x00d6; + t.Odieresiscyrillic = 0x04e6; + t.Odieresissmall = 0xf7f6; + t.Odotbelow = 0x1ecc; + t.Ogoneksmall = 0xf6fb; + t.Ograve = 0x00d2; + t.Ogravesmall = 0xf7f2; + t.Oharmenian = 0x0555; + t.Ohm = 0x2126; + t.Ohookabove = 0x1ece; + t.Ohorn = 0x01a0; + t.Ohornacute = 0x1eda; + t.Ohorndotbelow = 0x1ee2; + t.Ohorngrave = 0x1edc; + t.Ohornhookabove = 0x1ede; + t.Ohorntilde = 0x1ee0; + t.Ohungarumlaut = 0x0150; + t.Oi = 0x01a2; + t.Oinvertedbreve = 0x020e; + t.Omacron = 0x014c; + t.Omacronacute = 0x1e52; + t.Omacrongrave = 0x1e50; + t.Omega = 0x2126; + t.Omegacyrillic = 0x0460; + t.Omegagreek = 0x03a9; + t.Omegaroundcyrillic = 0x047a; + t.Omegatitlocyrillic = 0x047c; + t.Omegatonos = 0x038f; + t.Omicron = 0x039f; + t.Omicrontonos = 0x038c; + t.Omonospace = 0xff2f; + t.Oneroman = 0x2160; + t.Oogonek = 0x01ea; + t.Oogonekmacron = 0x01ec; + t.Oopen = 0x0186; + t.Oslash = 0x00d8; + t.Oslashacute = 0x01fe; + t.Oslashsmall = 0xf7f8; + t.Osmall = 0xf76f; + t.Ostrokeacute = 0x01fe; + t.Otcyrillic = 0x047e; + t.Otilde = 0x00d5; + t.Otildeacute = 0x1e4c; + t.Otildedieresis = 0x1e4e; + t.Otildesmall = 0xf7f5; + t.P = 0x0050; + t.Pacute = 0x1e54; + t.Pcircle = 0x24c5; + t.Pdotaccent = 0x1e56; + t.Pecyrillic = 0x041f; + t.Peharmenian = 0x054a; + t.Pemiddlehookcyrillic = 0x04a6; + t.Phi = 0x03a6; + t.Phook = 0x01a4; + t.Pi = 0x03a0; + t.Piwrarmenian = 0x0553; + t.Pmonospace = 0xff30; + t.Psi = 0x03a8; + t.Psicyrillic = 0x0470; + t.Psmall = 0xf770; + t.Q = 0x0051; + t.Qcircle = 0x24c6; + t.Qmonospace = 0xff31; + t.Qsmall = 0xf771; + t.R = 0x0052; + t.Raarmenian = 0x054c; + t.Racute = 0x0154; + t.Rcaron = 0x0158; + t.Rcedilla = 0x0156; + t.Rcircle = 0x24c7; + t.Rcommaaccent = 0x0156; + t.Rdblgrave = 0x0210; + t.Rdotaccent = 0x1e58; + t.Rdotbelow = 0x1e5a; + t.Rdotbelowmacron = 0x1e5c; + t.Reharmenian = 0x0550; + t.Rfraktur = 0x211c; + t.Rho = 0x03a1; + t.Ringsmall = 0xf6fc; + t.Rinvertedbreve = 0x0212; + t.Rlinebelow = 0x1e5e; + t.Rmonospace = 0xff32; + t.Rsmall = 0xf772; + t.Rsmallinverted = 0x0281; + t.Rsmallinvertedsuperior = 0x02b6; + t.S = 0x0053; + t.SF010000 = 0x250c; + t.SF020000 = 0x2514; + t.SF030000 = 0x2510; + t.SF040000 = 0x2518; + t.SF050000 = 0x253c; + t.SF060000 = 0x252c; + t.SF070000 = 0x2534; + t.SF080000 = 0x251c; + t.SF090000 = 0x2524; + t.SF100000 = 0x2500; + t.SF110000 = 0x2502; + t.SF190000 = 0x2561; + t.SF200000 = 0x2562; + t.SF210000 = 0x2556; + t.SF220000 = 0x2555; + t.SF230000 = 0x2563; + t.SF240000 = 0x2551; + t.SF250000 = 0x2557; + t.SF260000 = 0x255d; + t.SF270000 = 0x255c; + t.SF280000 = 0x255b; + t.SF360000 = 0x255e; + t.SF370000 = 0x255f; + t.SF380000 = 0x255a; + t.SF390000 = 0x2554; + t.SF400000 = 0x2569; + t.SF410000 = 0x2566; + t.SF420000 = 0x2560; + t.SF430000 = 0x2550; + t.SF440000 = 0x256c; + t.SF450000 = 0x2567; + t.SF460000 = 0x2568; + t.SF470000 = 0x2564; + t.SF480000 = 0x2565; + t.SF490000 = 0x2559; + t.SF500000 = 0x2558; + t.SF510000 = 0x2552; + t.SF520000 = 0x2553; + t.SF530000 = 0x256b; + t.SF540000 = 0x256a; + t.Sacute = 0x015a; + t.Sacutedotaccent = 0x1e64; + t.Sampigreek = 0x03e0; + t.Scaron = 0x0160; + t.Scarondotaccent = 0x1e66; + t.Scaronsmall = 0xf6fd; + t.Scedilla = 0x015e; + t.Schwa = 0x018f; + t.Schwacyrillic = 0x04d8; + t.Schwadieresiscyrillic = 0x04da; + t.Scircle = 0x24c8; + t.Scircumflex = 0x015c; + t.Scommaaccent = 0x0218; + t.Sdotaccent = 0x1e60; + t.Sdotbelow = 0x1e62; + t.Sdotbelowdotaccent = 0x1e68; + t.Seharmenian = 0x054d; + t.Sevenroman = 0x2166; + t.Shaarmenian = 0x0547; + t.Shacyrillic = 0x0428; + t.Shchacyrillic = 0x0429; + t.Sheicoptic = 0x03e2; + t.Shhacyrillic = 0x04ba; + t.Shimacoptic = 0x03ec; + t.Sigma = 0x03a3; + t.Sixroman = 0x2165; + t.Smonospace = 0xff33; + t.Softsigncyrillic = 0x042c; + t.Ssmall = 0xf773; + t.Stigmagreek = 0x03da; + t.T = 0x0054; + t.Tau = 0x03a4; + t.Tbar = 0x0166; + t.Tcaron = 0x0164; + t.Tcedilla = 0x0162; + t.Tcircle = 0x24c9; + t.Tcircumflexbelow = 0x1e70; + t.Tcommaaccent = 0x0162; + t.Tdotaccent = 0x1e6a; + t.Tdotbelow = 0x1e6c; + t.Tecyrillic = 0x0422; + t.Tedescendercyrillic = 0x04ac; + t.Tenroman = 0x2169; + t.Tetsecyrillic = 0x04b4; + t.Theta = 0x0398; + t.Thook = 0x01ac; + t.Thorn = 0x00de; + t.Thornsmall = 0xf7fe; + t.Threeroman = 0x2162; + t.Tildesmall = 0xf6fe; + t.Tiwnarmenian = 0x054f; + t.Tlinebelow = 0x1e6e; + t.Tmonospace = 0xff34; + t.Toarmenian = 0x0539; + t.Tonefive = 0x01bc; + t.Tonesix = 0x0184; + t.Tonetwo = 0x01a7; + t.Tretroflexhook = 0x01ae; + t.Tsecyrillic = 0x0426; + t.Tshecyrillic = 0x040b; + t.Tsmall = 0xf774; + t.Twelveroman = 0x216b; + t.Tworoman = 0x2161; + t.U = 0x0055; + t.Uacute = 0x00da; + t.Uacutesmall = 0xf7fa; + t.Ubreve = 0x016c; + t.Ucaron = 0x01d3; + t.Ucircle = 0x24ca; + t.Ucircumflex = 0x00db; + t.Ucircumflexbelow = 0x1e76; + t.Ucircumflexsmall = 0xf7fb; + t.Ucyrillic = 0x0423; + t.Udblacute = 0x0170; + t.Udblgrave = 0x0214; + t.Udieresis = 0x00dc; + t.Udieresisacute = 0x01d7; + t.Udieresisbelow = 0x1e72; + t.Udieresiscaron = 0x01d9; + t.Udieresiscyrillic = 0x04f0; + t.Udieresisgrave = 0x01db; + t.Udieresismacron = 0x01d5; + t.Udieresissmall = 0xf7fc; + t.Udotbelow = 0x1ee4; + t.Ugrave = 0x00d9; + t.Ugravesmall = 0xf7f9; + t.Uhookabove = 0x1ee6; + t.Uhorn = 0x01af; + t.Uhornacute = 0x1ee8; + t.Uhorndotbelow = 0x1ef0; + t.Uhorngrave = 0x1eea; + t.Uhornhookabove = 0x1eec; + t.Uhorntilde = 0x1eee; + t.Uhungarumlaut = 0x0170; + t.Uhungarumlautcyrillic = 0x04f2; + t.Uinvertedbreve = 0x0216; + t.Ukcyrillic = 0x0478; + t.Umacron = 0x016a; + t.Umacroncyrillic = 0x04ee; + t.Umacrondieresis = 0x1e7a; + t.Umonospace = 0xff35; + t.Uogonek = 0x0172; + t.Upsilon = 0x03a5; + t.Upsilon1 = 0x03d2; + t.Upsilonacutehooksymbolgreek = 0x03d3; + t.Upsilonafrican = 0x01b1; + t.Upsilondieresis = 0x03ab; + t.Upsilondieresishooksymbolgreek = 0x03d4; + t.Upsilonhooksymbol = 0x03d2; + t.Upsilontonos = 0x038e; + t.Uring = 0x016e; + t.Ushortcyrillic = 0x040e; + t.Usmall = 0xf775; + t.Ustraightcyrillic = 0x04ae; + t.Ustraightstrokecyrillic = 0x04b0; + t.Utilde = 0x0168; + t.Utildeacute = 0x1e78; + t.Utildebelow = 0x1e74; + t.V = 0x0056; + t.Vcircle = 0x24cb; + t.Vdotbelow = 0x1e7e; + t.Vecyrillic = 0x0412; + t.Vewarmenian = 0x054e; + t.Vhook = 0x01b2; + t.Vmonospace = 0xff36; + t.Voarmenian = 0x0548; + t.Vsmall = 0xf776; + t.Vtilde = 0x1e7c; + t.W = 0x0057; + t.Wacute = 0x1e82; + t.Wcircle = 0x24cc; + t.Wcircumflex = 0x0174; + t.Wdieresis = 0x1e84; + t.Wdotaccent = 0x1e86; + t.Wdotbelow = 0x1e88; + t.Wgrave = 0x1e80; + t.Wmonospace = 0xff37; + t.Wsmall = 0xf777; + t.X = 0x0058; + t.Xcircle = 0x24cd; + t.Xdieresis = 0x1e8c; + t.Xdotaccent = 0x1e8a; + t.Xeharmenian = 0x053d; + t.Xi = 0x039e; + t.Xmonospace = 0xff38; + t.Xsmall = 0xf778; + t.Y = 0x0059; + t.Yacute = 0x00dd; + t.Yacutesmall = 0xf7fd; + t.Yatcyrillic = 0x0462; + t.Ycircle = 0x24ce; + t.Ycircumflex = 0x0176; + t.Ydieresis = 0x0178; + t.Ydieresissmall = 0xf7ff; + t.Ydotaccent = 0x1e8e; + t.Ydotbelow = 0x1ef4; + t.Yericyrillic = 0x042b; + t.Yerudieresiscyrillic = 0x04f8; + t.Ygrave = 0x1ef2; + t.Yhook = 0x01b3; + t.Yhookabove = 0x1ef6; + t.Yiarmenian = 0x0545; + t.Yicyrillic = 0x0407; + t.Yiwnarmenian = 0x0552; + t.Ymonospace = 0xff39; + t.Ysmall = 0xf779; + t.Ytilde = 0x1ef8; + t.Yusbigcyrillic = 0x046a; + t.Yusbigiotifiedcyrillic = 0x046c; + t.Yuslittlecyrillic = 0x0466; + t.Yuslittleiotifiedcyrillic = 0x0468; + t.Z = 0x005a; + t.Zaarmenian = 0x0536; + t.Zacute = 0x0179; + t.Zcaron = 0x017d; + t.Zcaronsmall = 0xf6ff; + t.Zcircle = 0x24cf; + t.Zcircumflex = 0x1e90; + t.Zdot = 0x017b; + t.Zdotaccent = 0x017b; + t.Zdotbelow = 0x1e92; + t.Zecyrillic = 0x0417; + t.Zedescendercyrillic = 0x0498; + t.Zedieresiscyrillic = 0x04de; + t.Zeta = 0x0396; + t.Zhearmenian = 0x053a; + t.Zhebrevecyrillic = 0x04c1; + t.Zhecyrillic = 0x0416; + t.Zhedescendercyrillic = 0x0496; + t.Zhedieresiscyrillic = 0x04dc; + t.Zlinebelow = 0x1e94; + t.Zmonospace = 0xff3a; + t.Zsmall = 0xf77a; + t.Zstroke = 0x01b5; + t.a = 0x0061; + t.aabengali = 0x0986; + t.aacute = 0x00e1; + t.aadeva = 0x0906; + t.aagujarati = 0x0a86; + t.aagurmukhi = 0x0a06; + t.aamatragurmukhi = 0x0a3e; + t.aarusquare = 0x3303; + t.aavowelsignbengali = 0x09be; + t.aavowelsigndeva = 0x093e; + t.aavowelsigngujarati = 0x0abe; + t.abbreviationmarkarmenian = 0x055f; + t.abbreviationsigndeva = 0x0970; + t.abengali = 0x0985; + t.abopomofo = 0x311a; + t.abreve = 0x0103; + t.abreveacute = 0x1eaf; + t.abrevecyrillic = 0x04d1; + t.abrevedotbelow = 0x1eb7; + t.abrevegrave = 0x1eb1; + t.abrevehookabove = 0x1eb3; + t.abrevetilde = 0x1eb5; + t.acaron = 0x01ce; + t.acircle = 0x24d0; + t.acircumflex = 0x00e2; + t.acircumflexacute = 0x1ea5; + t.acircumflexdotbelow = 0x1ead; + t.acircumflexgrave = 0x1ea7; + t.acircumflexhookabove = 0x1ea9; + t.acircumflextilde = 0x1eab; + t.acute = 0x00b4; + t.acutebelowcmb = 0x0317; + t.acutecmb = 0x0301; + t.acutecomb = 0x0301; + t.acutedeva = 0x0954; + t.acutelowmod = 0x02cf; + t.acutetonecmb = 0x0341; + t.acyrillic = 0x0430; + t.adblgrave = 0x0201; + t.addakgurmukhi = 0x0a71; + t.adeva = 0x0905; + t.adieresis = 0x00e4; + t.adieresiscyrillic = 0x04d3; + t.adieresismacron = 0x01df; + t.adotbelow = 0x1ea1; + t.adotmacron = 0x01e1; + t.ae = 0x00e6; + t.aeacute = 0x01fd; + t.aekorean = 0x3150; + t.aemacron = 0x01e3; + t.afii00208 = 0x2015; + t.afii08941 = 0x20a4; + t.afii10017 = 0x0410; + t.afii10018 = 0x0411; + t.afii10019 = 0x0412; + t.afii10020 = 0x0413; + t.afii10021 = 0x0414; + t.afii10022 = 0x0415; + t.afii10023 = 0x0401; + t.afii10024 = 0x0416; + t.afii10025 = 0x0417; + t.afii10026 = 0x0418; + t.afii10027 = 0x0419; + t.afii10028 = 0x041a; + t.afii10029 = 0x041b; + t.afii10030 = 0x041c; + t.afii10031 = 0x041d; + t.afii10032 = 0x041e; + t.afii10033 = 0x041f; + t.afii10034 = 0x0420; + t.afii10035 = 0x0421; + t.afii10036 = 0x0422; + t.afii10037 = 0x0423; + t.afii10038 = 0x0424; + t.afii10039 = 0x0425; + t.afii10040 = 0x0426; + t.afii10041 = 0x0427; + t.afii10042 = 0x0428; + t.afii10043 = 0x0429; + t.afii10044 = 0x042a; + t.afii10045 = 0x042b; + t.afii10046 = 0x042c; + t.afii10047 = 0x042d; + t.afii10048 = 0x042e; + t.afii10049 = 0x042f; + t.afii10050 = 0x0490; + t.afii10051 = 0x0402; + t.afii10052 = 0x0403; + t.afii10053 = 0x0404; + t.afii10054 = 0x0405; + t.afii10055 = 0x0406; + t.afii10056 = 0x0407; + t.afii10057 = 0x0408; + t.afii10058 = 0x0409; + t.afii10059 = 0x040a; + t.afii10060 = 0x040b; + t.afii10061 = 0x040c; + t.afii10062 = 0x040e; + t.afii10063 = 0xf6c4; + t.afii10064 = 0xf6c5; + t.afii10065 = 0x0430; + t.afii10066 = 0x0431; + t.afii10067 = 0x0432; + t.afii10068 = 0x0433; + t.afii10069 = 0x0434; + t.afii10070 = 0x0435; + t.afii10071 = 0x0451; + t.afii10072 = 0x0436; + t.afii10073 = 0x0437; + t.afii10074 = 0x0438; + t.afii10075 = 0x0439; + t.afii10076 = 0x043a; + t.afii10077 = 0x043b; + t.afii10078 = 0x043c; + t.afii10079 = 0x043d; + t.afii10080 = 0x043e; + t.afii10081 = 0x043f; + t.afii10082 = 0x0440; + t.afii10083 = 0x0441; + t.afii10084 = 0x0442; + t.afii10085 = 0x0443; + t.afii10086 = 0x0444; + t.afii10087 = 0x0445; + t.afii10088 = 0x0446; + t.afii10089 = 0x0447; + t.afii10090 = 0x0448; + t.afii10091 = 0x0449; + t.afii10092 = 0x044a; + t.afii10093 = 0x044b; + t.afii10094 = 0x044c; + t.afii10095 = 0x044d; + t.afii10096 = 0x044e; + t.afii10097 = 0x044f; + t.afii10098 = 0x0491; + t.afii10099 = 0x0452; + t.afii10100 = 0x0453; + t.afii10101 = 0x0454; + t.afii10102 = 0x0455; + t.afii10103 = 0x0456; + t.afii10104 = 0x0457; + t.afii10105 = 0x0458; + t.afii10106 = 0x0459; + t.afii10107 = 0x045a; + t.afii10108 = 0x045b; + t.afii10109 = 0x045c; + t.afii10110 = 0x045e; + t.afii10145 = 0x040f; + t.afii10146 = 0x0462; + t.afii10147 = 0x0472; + t.afii10148 = 0x0474; + t.afii10192 = 0xf6c6; + t.afii10193 = 0x045f; + t.afii10194 = 0x0463; + t.afii10195 = 0x0473; + t.afii10196 = 0x0475; + t.afii10831 = 0xf6c7; + t.afii10832 = 0xf6c8; + t.afii10846 = 0x04d9; + t.afii299 = 0x200e; + t.afii300 = 0x200f; + t.afii301 = 0x200d; + t.afii57381 = 0x066a; + t.afii57388 = 0x060c; + t.afii57392 = 0x0660; + t.afii57393 = 0x0661; + t.afii57394 = 0x0662; + t.afii57395 = 0x0663; + t.afii57396 = 0x0664; + t.afii57397 = 0x0665; + t.afii57398 = 0x0666; + t.afii57399 = 0x0667; + t.afii57400 = 0x0668; + t.afii57401 = 0x0669; + t.afii57403 = 0x061b; + t.afii57407 = 0x061f; + t.afii57409 = 0x0621; + t.afii57410 = 0x0622; + t.afii57411 = 0x0623; + t.afii57412 = 0x0624; + t.afii57413 = 0x0625; + t.afii57414 = 0x0626; + t.afii57415 = 0x0627; + t.afii57416 = 0x0628; + t.afii57417 = 0x0629; + t.afii57418 = 0x062a; + t.afii57419 = 0x062b; + t.afii57420 = 0x062c; + t.afii57421 = 0x062d; + t.afii57422 = 0x062e; + t.afii57423 = 0x062f; + t.afii57424 = 0x0630; + t.afii57425 = 0x0631; + t.afii57426 = 0x0632; + t.afii57427 = 0x0633; + t.afii57428 = 0x0634; + t.afii57429 = 0x0635; + t.afii57430 = 0x0636; + t.afii57431 = 0x0637; + t.afii57432 = 0x0638; + t.afii57433 = 0x0639; + t.afii57434 = 0x063a; + t.afii57440 = 0x0640; + t.afii57441 = 0x0641; + t.afii57442 = 0x0642; + t.afii57443 = 0x0643; + t.afii57444 = 0x0644; + t.afii57445 = 0x0645; + t.afii57446 = 0x0646; + t.afii57448 = 0x0648; + t.afii57449 = 0x0649; + t.afii57450 = 0x064a; + t.afii57451 = 0x064b; + t.afii57452 = 0x064c; + t.afii57453 = 0x064d; + t.afii57454 = 0x064e; + t.afii57455 = 0x064f; + t.afii57456 = 0x0650; + t.afii57457 = 0x0651; + t.afii57458 = 0x0652; + t.afii57470 = 0x0647; + t.afii57505 = 0x06a4; + t.afii57506 = 0x067e; + t.afii57507 = 0x0686; + t.afii57508 = 0x0698; + t.afii57509 = 0x06af; + t.afii57511 = 0x0679; + t.afii57512 = 0x0688; + t.afii57513 = 0x0691; + t.afii57514 = 0x06ba; + t.afii57519 = 0x06d2; + t.afii57534 = 0x06d5; + t.afii57636 = 0x20aa; + t.afii57645 = 0x05be; + t.afii57658 = 0x05c3; + t.afii57664 = 0x05d0; + t.afii57665 = 0x05d1; + t.afii57666 = 0x05d2; + t.afii57667 = 0x05d3; + t.afii57668 = 0x05d4; + t.afii57669 = 0x05d5; + t.afii57670 = 0x05d6; + t.afii57671 = 0x05d7; + t.afii57672 = 0x05d8; + t.afii57673 = 0x05d9; + t.afii57674 = 0x05da; + t.afii57675 = 0x05db; + t.afii57676 = 0x05dc; + t.afii57677 = 0x05dd; + t.afii57678 = 0x05de; + t.afii57679 = 0x05df; + t.afii57680 = 0x05e0; + t.afii57681 = 0x05e1; + t.afii57682 = 0x05e2; + t.afii57683 = 0x05e3; + t.afii57684 = 0x05e4; + t.afii57685 = 0x05e5; + t.afii57686 = 0x05e6; + t.afii57687 = 0x05e7; + t.afii57688 = 0x05e8; + t.afii57689 = 0x05e9; + t.afii57690 = 0x05ea; + t.afii57694 = 0xfb2a; + t.afii57695 = 0xfb2b; + t.afii57700 = 0xfb4b; + t.afii57705 = 0xfb1f; + t.afii57716 = 0x05f0; + t.afii57717 = 0x05f1; + t.afii57718 = 0x05f2; + t.afii57723 = 0xfb35; + t.afii57793 = 0x05b4; + t.afii57794 = 0x05b5; + t.afii57795 = 0x05b6; + t.afii57796 = 0x05bb; + t.afii57797 = 0x05b8; + t.afii57798 = 0x05b7; + t.afii57799 = 0x05b0; + t.afii57800 = 0x05b2; + t.afii57801 = 0x05b1; + t.afii57802 = 0x05b3; + t.afii57803 = 0x05c2; + t.afii57804 = 0x05c1; + t.afii57806 = 0x05b9; + t.afii57807 = 0x05bc; + t.afii57839 = 0x05bd; + t.afii57841 = 0x05bf; + t.afii57842 = 0x05c0; + t.afii57929 = 0x02bc; + t.afii61248 = 0x2105; + t.afii61289 = 0x2113; + t.afii61352 = 0x2116; + t.afii61573 = 0x202c; + t.afii61574 = 0x202d; + t.afii61575 = 0x202e; + t.afii61664 = 0x200c; + t.afii63167 = 0x066d; + t.afii64937 = 0x02bd; + t.agrave = 0x00e0; + t.agujarati = 0x0a85; + t.agurmukhi = 0x0a05; + t.ahiragana = 0x3042; + t.ahookabove = 0x1ea3; + t.aibengali = 0x0990; + t.aibopomofo = 0x311e; + t.aideva = 0x0910; + t.aiecyrillic = 0x04d5; + t.aigujarati = 0x0a90; + t.aigurmukhi = 0x0a10; + t.aimatragurmukhi = 0x0a48; + t.ainarabic = 0x0639; + t.ainfinalarabic = 0xfeca; + t.aininitialarabic = 0xfecb; + t.ainmedialarabic = 0xfecc; + t.ainvertedbreve = 0x0203; + t.aivowelsignbengali = 0x09c8; + t.aivowelsigndeva = 0x0948; + t.aivowelsigngujarati = 0x0ac8; + t.akatakana = 0x30a2; + t.akatakanahalfwidth = 0xff71; + t.akorean = 0x314f; + t.alef = 0x05d0; + t.alefarabic = 0x0627; + t.alefdageshhebrew = 0xfb30; + t.aleffinalarabic = 0xfe8e; + t.alefhamzaabovearabic = 0x0623; + t.alefhamzaabovefinalarabic = 0xfe84; + t.alefhamzabelowarabic = 0x0625; + t.alefhamzabelowfinalarabic = 0xfe88; + t.alefhebrew = 0x05d0; + t.aleflamedhebrew = 0xfb4f; + t.alefmaddaabovearabic = 0x0622; + t.alefmaddaabovefinalarabic = 0xfe82; + t.alefmaksuraarabic = 0x0649; + t.alefmaksurafinalarabic = 0xfef0; + t.alefmaksurainitialarabic = 0xfef3; + t.alefmaksuramedialarabic = 0xfef4; + t.alefpatahhebrew = 0xfb2e; + t.alefqamatshebrew = 0xfb2f; + t.aleph = 0x2135; + t.allequal = 0x224c; + t.alpha = 0x03b1; + t.alphatonos = 0x03ac; + t.amacron = 0x0101; + t.amonospace = 0xff41; + t.ampersand = 0x0026; + t.ampersandmonospace = 0xff06; + t.ampersandsmall = 0xf726; + t.amsquare = 0x33c2; + t.anbopomofo = 0x3122; + t.angbopomofo = 0x3124; + t.angbracketleft = 0x3008; + t.angbracketright = 0x3009; + t.angkhankhuthai = 0x0e5a; + t.angle = 0x2220; + t.anglebracketleft = 0x3008; + t.anglebracketleftvertical = 0xfe3f; + t.anglebracketright = 0x3009; + t.anglebracketrightvertical = 0xfe40; + t.angleleft = 0x2329; + t.angleright = 0x232a; + t.angstrom = 0x212b; + t.anoteleia = 0x0387; + t.anudattadeva = 0x0952; + t.anusvarabengali = 0x0982; + t.anusvaradeva = 0x0902; + t.anusvaragujarati = 0x0a82; + t.aogonek = 0x0105; + t.apaatosquare = 0x3300; + t.aparen = 0x249c; + t.apostrophearmenian = 0x055a; + t.apostrophemod = 0x02bc; + t.apple = 0xf8ff; + t.approaches = 0x2250; + t.approxequal = 0x2248; + t.approxequalorimage = 0x2252; + t.approximatelyequal = 0x2245; + t.araeaekorean = 0x318e; + t.araeakorean = 0x318d; + t.arc = 0x2312; + t.arighthalfring = 0x1e9a; + t.aring = 0x00e5; + t.aringacute = 0x01fb; + t.aringbelow = 0x1e01; + t.arrowboth = 0x2194; + t.arrowdashdown = 0x21e3; + t.arrowdashleft = 0x21e0; + t.arrowdashright = 0x21e2; + t.arrowdashup = 0x21e1; + t.arrowdblboth = 0x21d4; + t.arrowdbldown = 0x21d3; + t.arrowdblleft = 0x21d0; + t.arrowdblright = 0x21d2; + t.arrowdblup = 0x21d1; + t.arrowdown = 0x2193; + t.arrowdownleft = 0x2199; + t.arrowdownright = 0x2198; + t.arrowdownwhite = 0x21e9; + t.arrowheaddownmod = 0x02c5; + t.arrowheadleftmod = 0x02c2; + t.arrowheadrightmod = 0x02c3; + t.arrowheadupmod = 0x02c4; + t.arrowhorizex = 0xf8e7; + t.arrowleft = 0x2190; + t.arrowleftdbl = 0x21d0; + t.arrowleftdblstroke = 0x21cd; + t.arrowleftoverright = 0x21c6; + t.arrowleftwhite = 0x21e6; + t.arrowright = 0x2192; + t.arrowrightdblstroke = 0x21cf; + t.arrowrightheavy = 0x279e; + t.arrowrightoverleft = 0x21c4; + t.arrowrightwhite = 0x21e8; + t.arrowtableft = 0x21e4; + t.arrowtabright = 0x21e5; + t.arrowup = 0x2191; + t.arrowupdn = 0x2195; + t.arrowupdnbse = 0x21a8; + t.arrowupdownbase = 0x21a8; + t.arrowupleft = 0x2196; + t.arrowupleftofdown = 0x21c5; + t.arrowupright = 0x2197; + t.arrowupwhite = 0x21e7; + t.arrowvertex = 0xf8e6; + t.asciicircum = 0x005e; + t.asciicircummonospace = 0xff3e; + t.asciitilde = 0x007e; + t.asciitildemonospace = 0xff5e; + t.ascript = 0x0251; + t.ascriptturned = 0x0252; + t.asmallhiragana = 0x3041; + t.asmallkatakana = 0x30a1; + t.asmallkatakanahalfwidth = 0xff67; + t.asterisk = 0x002a; + t.asteriskaltonearabic = 0x066d; + t.asteriskarabic = 0x066d; + t.asteriskmath = 0x2217; + t.asteriskmonospace = 0xff0a; + t.asterisksmall = 0xfe61; + t.asterism = 0x2042; + t.asuperior = 0xf6e9; + t.asymptoticallyequal = 0x2243; + t.at = 0x0040; + t.atilde = 0x00e3; + t.atmonospace = 0xff20; + t.atsmall = 0xfe6b; + t.aturned = 0x0250; + t.aubengali = 0x0994; + t.aubopomofo = 0x3120; + t.audeva = 0x0914; + t.augujarati = 0x0a94; + t.augurmukhi = 0x0a14; + t.aulengthmarkbengali = 0x09d7; + t.aumatragurmukhi = 0x0a4c; + t.auvowelsignbengali = 0x09cc; + t.auvowelsigndeva = 0x094c; + t.auvowelsigngujarati = 0x0acc; + t.avagrahadeva = 0x093d; + t.aybarmenian = 0x0561; + t.ayin = 0x05e2; + t.ayinaltonehebrew = 0xfb20; + t.ayinhebrew = 0x05e2; + t.b = 0x0062; + t.babengali = 0x09ac; + t.backslash = 0x005c; + t.backslashmonospace = 0xff3c; + t.badeva = 0x092c; + t.bagujarati = 0x0aac; + t.bagurmukhi = 0x0a2c; + t.bahiragana = 0x3070; + t.bahtthai = 0x0e3f; + t.bakatakana = 0x30d0; + t.bar = 0x007c; + t.barmonospace = 0xff5c; + t.bbopomofo = 0x3105; + t.bcircle = 0x24d1; + t.bdotaccent = 0x1e03; + t.bdotbelow = 0x1e05; + t.beamedsixteenthnotes = 0x266c; + t.because = 0x2235; + t.becyrillic = 0x0431; + t.beharabic = 0x0628; + t.behfinalarabic = 0xfe90; + t.behinitialarabic = 0xfe91; + t.behiragana = 0x3079; + t.behmedialarabic = 0xfe92; + t.behmeeminitialarabic = 0xfc9f; + t.behmeemisolatedarabic = 0xfc08; + t.behnoonfinalarabic = 0xfc6d; + t.bekatakana = 0x30d9; + t.benarmenian = 0x0562; + t.bet = 0x05d1; + t.beta = 0x03b2; + t.betasymbolgreek = 0x03d0; + t.betdagesh = 0xfb31; + t.betdageshhebrew = 0xfb31; + t.bethebrew = 0x05d1; + t.betrafehebrew = 0xfb4c; + t.bhabengali = 0x09ad; + t.bhadeva = 0x092d; + t.bhagujarati = 0x0aad; + t.bhagurmukhi = 0x0a2d; + t.bhook = 0x0253; + t.bihiragana = 0x3073; + t.bikatakana = 0x30d3; + t.bilabialclick = 0x0298; + t.bindigurmukhi = 0x0a02; + t.birusquare = 0x3331; + t.blackcircle = 0x25cf; + t.blackdiamond = 0x25c6; + t.blackdownpointingtriangle = 0x25bc; + t.blackleftpointingpointer = 0x25c4; + t.blackleftpointingtriangle = 0x25c0; + t.blacklenticularbracketleft = 0x3010; + t.blacklenticularbracketleftvertical = 0xfe3b; + t.blacklenticularbracketright = 0x3011; + t.blacklenticularbracketrightvertical = 0xfe3c; + t.blacklowerlefttriangle = 0x25e3; + t.blacklowerrighttriangle = 0x25e2; + t.blackrectangle = 0x25ac; + t.blackrightpointingpointer = 0x25ba; + t.blackrightpointingtriangle = 0x25b6; + t.blacksmallsquare = 0x25aa; + t.blacksmilingface = 0x263b; + t.blacksquare = 0x25a0; + t.blackstar = 0x2605; + t.blackupperlefttriangle = 0x25e4; + t.blackupperrighttriangle = 0x25e5; + t.blackuppointingsmalltriangle = 0x25b4; + t.blackuppointingtriangle = 0x25b2; + t.blank = 0x2423; + t.blinebelow = 0x1e07; + t.block = 0x2588; + t.bmonospace = 0xff42; + t.bobaimaithai = 0x0e1a; + t.bohiragana = 0x307c; + t.bokatakana = 0x30dc; + t.bparen = 0x249d; + t.bqsquare = 0x33c3; + t.braceex = 0xf8f4; + t.braceleft = 0x007b; + t.braceleftbt = 0xf8f3; + t.braceleftmid = 0xf8f2; + t.braceleftmonospace = 0xff5b; + t.braceleftsmall = 0xfe5b; + t.bracelefttp = 0xf8f1; + t.braceleftvertical = 0xfe37; + t.braceright = 0x007d; + t.bracerightbt = 0xf8fe; + t.bracerightmid = 0xf8fd; + t.bracerightmonospace = 0xff5d; + t.bracerightsmall = 0xfe5c; + t.bracerighttp = 0xf8fc; + t.bracerightvertical = 0xfe38; + t.bracketleft = 0x005b; + t.bracketleftbt = 0xf8f0; + t.bracketleftex = 0xf8ef; + t.bracketleftmonospace = 0xff3b; + t.bracketlefttp = 0xf8ee; + t.bracketright = 0x005d; + t.bracketrightbt = 0xf8fb; + t.bracketrightex = 0xf8fa; + t.bracketrightmonospace = 0xff3d; + t.bracketrighttp = 0xf8f9; + t.breve = 0x02d8; + t.brevebelowcmb = 0x032e; + t.brevecmb = 0x0306; + t.breveinvertedbelowcmb = 0x032f; + t.breveinvertedcmb = 0x0311; + t.breveinverteddoublecmb = 0x0361; + t.bridgebelowcmb = 0x032a; + t.bridgeinvertedbelowcmb = 0x033a; + t.brokenbar = 0x00a6; + t.bstroke = 0x0180; + t.bsuperior = 0xf6ea; + t.btopbar = 0x0183; + t.buhiragana = 0x3076; + t.bukatakana = 0x30d6; + t.bullet = 0x2022; + t.bulletinverse = 0x25d8; + t.bulletoperator = 0x2219; + t.bullseye = 0x25ce; + t.c = 0x0063; + t.caarmenian = 0x056e; + t.cabengali = 0x099a; + t.cacute = 0x0107; + t.cadeva = 0x091a; + t.cagujarati = 0x0a9a; + t.cagurmukhi = 0x0a1a; + t.calsquare = 0x3388; + t.candrabindubengali = 0x0981; + t.candrabinducmb = 0x0310; + t.candrabindudeva = 0x0901; + t.candrabindugujarati = 0x0a81; + t.capslock = 0x21ea; + t.careof = 0x2105; + t.caron = 0x02c7; + t.caronbelowcmb = 0x032c; + t.caroncmb = 0x030c; + t.carriagereturn = 0x21b5; + t.cbopomofo = 0x3118; + t.ccaron = 0x010d; + t.ccedilla = 0x00e7; + t.ccedillaacute = 0x1e09; + t.ccircle = 0x24d2; + t.ccircumflex = 0x0109; + t.ccurl = 0x0255; + t.cdot = 0x010b; + t.cdotaccent = 0x010b; + t.cdsquare = 0x33c5; + t.cedilla = 0x00b8; + t.cedillacmb = 0x0327; + t.cent = 0x00a2; + t.centigrade = 0x2103; + t.centinferior = 0xf6df; + t.centmonospace = 0xffe0; + t.centoldstyle = 0xf7a2; + t.centsuperior = 0xf6e0; + t.chaarmenian = 0x0579; + t.chabengali = 0x099b; + t.chadeva = 0x091b; + t.chagujarati = 0x0a9b; + t.chagurmukhi = 0x0a1b; + t.chbopomofo = 0x3114; + t.cheabkhasiancyrillic = 0x04bd; + t.checkmark = 0x2713; + t.checyrillic = 0x0447; + t.chedescenderabkhasiancyrillic = 0x04bf; + t.chedescendercyrillic = 0x04b7; + t.chedieresiscyrillic = 0x04f5; + t.cheharmenian = 0x0573; + t.chekhakassiancyrillic = 0x04cc; + t.cheverticalstrokecyrillic = 0x04b9; + t.chi = 0x03c7; + t.chieuchacirclekorean = 0x3277; + t.chieuchaparenkorean = 0x3217; + t.chieuchcirclekorean = 0x3269; + t.chieuchkorean = 0x314a; + t.chieuchparenkorean = 0x3209; + t.chochangthai = 0x0e0a; + t.chochanthai = 0x0e08; + t.chochingthai = 0x0e09; + t.chochoethai = 0x0e0c; + t.chook = 0x0188; + t.cieucacirclekorean = 0x3276; + t.cieucaparenkorean = 0x3216; + t.cieuccirclekorean = 0x3268; + t.cieuckorean = 0x3148; + t.cieucparenkorean = 0x3208; + t.cieucuparenkorean = 0x321c; + t.circle = 0x25cb; + t.circlecopyrt = 0x00a9; + t.circlemultiply = 0x2297; + t.circleot = 0x2299; + t.circleplus = 0x2295; + t.circlepostalmark = 0x3036; + t.circlewithlefthalfblack = 0x25d0; + t.circlewithrighthalfblack = 0x25d1; + t.circumflex = 0x02c6; + t.circumflexbelowcmb = 0x032d; + t.circumflexcmb = 0x0302; + t.clear = 0x2327; + t.clickalveolar = 0x01c2; + t.clickdental = 0x01c0; + t.clicklateral = 0x01c1; + t.clickretroflex = 0x01c3; + t.club = 0x2663; + t.clubsuitblack = 0x2663; + t.clubsuitwhite = 0x2667; + t.cmcubedsquare = 0x33a4; + t.cmonospace = 0xff43; + t.cmsquaredsquare = 0x33a0; + t.coarmenian = 0x0581; + t.colon = 0x003a; + t.colonmonetary = 0x20a1; + t.colonmonospace = 0xff1a; + t.colonsign = 0x20a1; + t.colonsmall = 0xfe55; + t.colontriangularhalfmod = 0x02d1; + t.colontriangularmod = 0x02d0; + t.comma = 0x002c; + t.commaabovecmb = 0x0313; + t.commaaboverightcmb = 0x0315; + t.commaaccent = 0xf6c3; + t.commaarabic = 0x060c; + t.commaarmenian = 0x055d; + t.commainferior = 0xf6e1; + t.commamonospace = 0xff0c; + t.commareversedabovecmb = 0x0314; + t.commareversedmod = 0x02bd; + t.commasmall = 0xfe50; + t.commasuperior = 0xf6e2; + t.commaturnedabovecmb = 0x0312; + t.commaturnedmod = 0x02bb; + t.compass = 0x263c; + t.congruent = 0x2245; + t.contourintegral = 0x222e; + t.control = 0x2303; + t.controlACK = 0x0006; + t.controlBEL = 0x0007; + t.controlBS = 0x0008; + t.controlCAN = 0x0018; + t.controlCR = 0x000d; + t.controlDC1 = 0x0011; + t.controlDC2 = 0x0012; + t.controlDC3 = 0x0013; + t.controlDC4 = 0x0014; + t.controlDEL = 0x007f; + t.controlDLE = 0x0010; + t.controlEM = 0x0019; + t.controlENQ = 0x0005; + t.controlEOT = 0x0004; + t.controlESC = 0x001b; + t.controlETB = 0x0017; + t.controlETX = 0x0003; + t.controlFF = 0x000c; + t.controlFS = 0x001c; + t.controlGS = 0x001d; + t.controlHT = 0x0009; + t.controlLF = 0x000a; + t.controlNAK = 0x0015; + t.controlNULL = 0x0000; + t.controlRS = 0x001e; + t.controlSI = 0x000f; + t.controlSO = 0x000e; + t.controlSOT = 0x0002; + t.controlSTX = 0x0001; + t.controlSUB = 0x001a; + t.controlSYN = 0x0016; + t.controlUS = 0x001f; + t.controlVT = 0x000b; + t.copyright = 0x00a9; + t.copyrightsans = 0xf8e9; + t.copyrightserif = 0xf6d9; + t.cornerbracketleft = 0x300c; + t.cornerbracketlefthalfwidth = 0xff62; + t.cornerbracketleftvertical = 0xfe41; + t.cornerbracketright = 0x300d; + t.cornerbracketrighthalfwidth = 0xff63; + t.cornerbracketrightvertical = 0xfe42; + t.corporationsquare = 0x337f; + t.cosquare = 0x33c7; + t.coverkgsquare = 0x33c6; + t.cparen = 0x249e; + t.cruzeiro = 0x20a2; + t.cstretched = 0x0297; + t.curlyand = 0x22cf; + t.curlyor = 0x22ce; + t.currency = 0x00a4; + t.cyrBreve = 0xf6d1; + t.cyrFlex = 0xf6d2; + t.cyrbreve = 0xf6d4; + t.cyrflex = 0xf6d5; + t.d = 0x0064; + t.daarmenian = 0x0564; + t.dabengali = 0x09a6; + t.dadarabic = 0x0636; + t.dadeva = 0x0926; + t.dadfinalarabic = 0xfebe; + t.dadinitialarabic = 0xfebf; + t.dadmedialarabic = 0xfec0; + t.dagesh = 0x05bc; + t.dageshhebrew = 0x05bc; + t.dagger = 0x2020; + t.daggerdbl = 0x2021; + t.dagujarati = 0x0aa6; + t.dagurmukhi = 0x0a26; + t.dahiragana = 0x3060; + t.dakatakana = 0x30c0; + t.dalarabic = 0x062f; + t.dalet = 0x05d3; + t.daletdagesh = 0xfb33; + t.daletdageshhebrew = 0xfb33; + t.dalethebrew = 0x05d3; + t.dalfinalarabic = 0xfeaa; + t.dammaarabic = 0x064f; + t.dammalowarabic = 0x064f; + t.dammatanaltonearabic = 0x064c; + t.dammatanarabic = 0x064c; + t.danda = 0x0964; + t.dargahebrew = 0x05a7; + t.dargalefthebrew = 0x05a7; + t.dasiapneumatacyrilliccmb = 0x0485; + t.dblGrave = 0xf6d3; + t.dblanglebracketleft = 0x300a; + t.dblanglebracketleftvertical = 0xfe3d; + t.dblanglebracketright = 0x300b; + t.dblanglebracketrightvertical = 0xfe3e; + t.dblarchinvertedbelowcmb = 0x032b; + t.dblarrowleft = 0x21d4; + t.dblarrowright = 0x21d2; + t.dbldanda = 0x0965; + t.dblgrave = 0xf6d6; + t.dblgravecmb = 0x030f; + t.dblintegral = 0x222c; + t.dbllowline = 0x2017; + t.dbllowlinecmb = 0x0333; + t.dbloverlinecmb = 0x033f; + t.dblprimemod = 0x02ba; + t.dblverticalbar = 0x2016; + t.dblverticallineabovecmb = 0x030e; + t.dbopomofo = 0x3109; + t.dbsquare = 0x33c8; + t.dcaron = 0x010f; + t.dcedilla = 0x1e11; + t.dcircle = 0x24d3; + t.dcircumflexbelow = 0x1e13; + t.dcroat = 0x0111; + t.ddabengali = 0x09a1; + t.ddadeva = 0x0921; + t.ddagujarati = 0x0aa1; + t.ddagurmukhi = 0x0a21; + t.ddalarabic = 0x0688; + t.ddalfinalarabic = 0xfb89; + t.dddhadeva = 0x095c; + t.ddhabengali = 0x09a2; + t.ddhadeva = 0x0922; + t.ddhagujarati = 0x0aa2; + t.ddhagurmukhi = 0x0a22; + t.ddotaccent = 0x1e0b; + t.ddotbelow = 0x1e0d; + t.decimalseparatorarabic = 0x066b; + t.decimalseparatorpersian = 0x066b; + t.decyrillic = 0x0434; + t.degree = 0x00b0; + t.dehihebrew = 0x05ad; + t.dehiragana = 0x3067; + t.deicoptic = 0x03ef; + t.dekatakana = 0x30c7; + t.deleteleft = 0x232b; + t.deleteright = 0x2326; + t.delta = 0x03b4; + t.deltaturned = 0x018d; + t.denominatorminusonenumeratorbengali = 0x09f8; + t.dezh = 0x02a4; + t.dhabengali = 0x09a7; + t.dhadeva = 0x0927; + t.dhagujarati = 0x0aa7; + t.dhagurmukhi = 0x0a27; + t.dhook = 0x0257; + t.dialytikatonos = 0x0385; + t.dialytikatonoscmb = 0x0344; + t.diamond = 0x2666; + t.diamondsuitwhite = 0x2662; + t.dieresis = 0x00a8; + t.dieresisacute = 0xf6d7; + t.dieresisbelowcmb = 0x0324; + t.dieresiscmb = 0x0308; + t.dieresisgrave = 0xf6d8; + t.dieresistonos = 0x0385; + t.dihiragana = 0x3062; + t.dikatakana = 0x30c2; + t.dittomark = 0x3003; + t.divide = 0x00f7; + t.divides = 0x2223; + t.divisionslash = 0x2215; + t.djecyrillic = 0x0452; + t.dkshade = 0x2593; + t.dlinebelow = 0x1e0f; + t.dlsquare = 0x3397; + t.dmacron = 0x0111; + t.dmonospace = 0xff44; + t.dnblock = 0x2584; + t.dochadathai = 0x0e0e; + t.dodekthai = 0x0e14; + t.dohiragana = 0x3069; + t.dokatakana = 0x30c9; + t.dollar = 0x0024; + t.dollarinferior = 0xf6e3; + t.dollarmonospace = 0xff04; + t.dollaroldstyle = 0xf724; + t.dollarsmall = 0xfe69; + t.dollarsuperior = 0xf6e4; + t.dong = 0x20ab; + t.dorusquare = 0x3326; + t.dotaccent = 0x02d9; + t.dotaccentcmb = 0x0307; + t.dotbelowcmb = 0x0323; + t.dotbelowcomb = 0x0323; + t.dotkatakana = 0x30fb; + t.dotlessi = 0x0131; + t.dotlessj = 0xf6be; + t.dotlessjstrokehook = 0x0284; + t.dotmath = 0x22c5; + t.dottedcircle = 0x25cc; + t.doubleyodpatah = 0xfb1f; + t.doubleyodpatahhebrew = 0xfb1f; + t.downtackbelowcmb = 0x031e; + t.downtackmod = 0x02d5; + t.dparen = 0x249f; + t.dsuperior = 0xf6eb; + t.dtail = 0x0256; + t.dtopbar = 0x018c; + t.duhiragana = 0x3065; + t.dukatakana = 0x30c5; + t.dz = 0x01f3; + t.dzaltone = 0x02a3; + t.dzcaron = 0x01c6; + t.dzcurl = 0x02a5; + t.dzeabkhasiancyrillic = 0x04e1; + t.dzecyrillic = 0x0455; + t.dzhecyrillic = 0x045f; + t.e = 0x0065; + t.eacute = 0x00e9; + t.earth = 0x2641; + t.ebengali = 0x098f; + t.ebopomofo = 0x311c; + t.ebreve = 0x0115; + t.ecandradeva = 0x090d; + t.ecandragujarati = 0x0a8d; + t.ecandravowelsigndeva = 0x0945; + t.ecandravowelsigngujarati = 0x0ac5; + t.ecaron = 0x011b; + t.ecedillabreve = 0x1e1d; + t.echarmenian = 0x0565; + t.echyiwnarmenian = 0x0587; + t.ecircle = 0x24d4; + t.ecircumflex = 0x00ea; + t.ecircumflexacute = 0x1ebf; + t.ecircumflexbelow = 0x1e19; + t.ecircumflexdotbelow = 0x1ec7; + t.ecircumflexgrave = 0x1ec1; + t.ecircumflexhookabove = 0x1ec3; + t.ecircumflextilde = 0x1ec5; + t.ecyrillic = 0x0454; + t.edblgrave = 0x0205; + t.edeva = 0x090f; + t.edieresis = 0x00eb; + t.edot = 0x0117; + t.edotaccent = 0x0117; + t.edotbelow = 0x1eb9; + t.eegurmukhi = 0x0a0f; + t.eematragurmukhi = 0x0a47; + t.efcyrillic = 0x0444; + t.egrave = 0x00e8; + t.egujarati = 0x0a8f; + t.eharmenian = 0x0567; + t.ehbopomofo = 0x311d; + t.ehiragana = 0x3048; + t.ehookabove = 0x1ebb; + t.eibopomofo = 0x311f; + t.eight = 0x0038; + t.eightarabic = 0x0668; + t.eightbengali = 0x09ee; + t.eightcircle = 0x2467; + t.eightcircleinversesansserif = 0x2791; + t.eightdeva = 0x096e; + t.eighteencircle = 0x2471; + t.eighteenparen = 0x2485; + t.eighteenperiod = 0x2499; + t.eightgujarati = 0x0aee; + t.eightgurmukhi = 0x0a6e; + t.eighthackarabic = 0x0668; + t.eighthangzhou = 0x3028; + t.eighthnotebeamed = 0x266b; + t.eightideographicparen = 0x3227; + t.eightinferior = 0x2088; + t.eightmonospace = 0xff18; + t.eightoldstyle = 0xf738; + t.eightparen = 0x247b; + t.eightperiod = 0x248f; + t.eightpersian = 0x06f8; + t.eightroman = 0x2177; + t.eightsuperior = 0x2078; + t.eightthai = 0x0e58; + t.einvertedbreve = 0x0207; + t.eiotifiedcyrillic = 0x0465; + t.ekatakana = 0x30a8; + t.ekatakanahalfwidth = 0xff74; + t.ekonkargurmukhi = 0x0a74; + t.ekorean = 0x3154; + t.elcyrillic = 0x043b; + t.element = 0x2208; + t.elevencircle = 0x246a; + t.elevenparen = 0x247e; + t.elevenperiod = 0x2492; + t.elevenroman = 0x217a; + t.ellipsis = 0x2026; + t.ellipsisvertical = 0x22ee; + t.emacron = 0x0113; + t.emacronacute = 0x1e17; + t.emacrongrave = 0x1e15; + t.emcyrillic = 0x043c; + t.emdash = 0x2014; + t.emdashvertical = 0xfe31; + t.emonospace = 0xff45; + t.emphasismarkarmenian = 0x055b; + t.emptyset = 0x2205; + t.enbopomofo = 0x3123; + t.encyrillic = 0x043d; + t.endash = 0x2013; + t.endashvertical = 0xfe32; + t.endescendercyrillic = 0x04a3; + t.eng = 0x014b; + t.engbopomofo = 0x3125; + t.enghecyrillic = 0x04a5; + t.enhookcyrillic = 0x04c8; + t.enspace = 0x2002; + t.eogonek = 0x0119; + t.eokorean = 0x3153; + t.eopen = 0x025b; + t.eopenclosed = 0x029a; + t.eopenreversed = 0x025c; + t.eopenreversedclosed = 0x025e; + t.eopenreversedhook = 0x025d; + t.eparen = 0x24a0; + t.epsilon = 0x03b5; + t.epsilontonos = 0x03ad; + t.equal = 0x003d; + t.equalmonospace = 0xff1d; + t.equalsmall = 0xfe66; + t.equalsuperior = 0x207c; + t.equivalence = 0x2261; + t.erbopomofo = 0x3126; + t.ercyrillic = 0x0440; + t.ereversed = 0x0258; + t.ereversedcyrillic = 0x044d; + t.escyrillic = 0x0441; + t.esdescendercyrillic = 0x04ab; + t.esh = 0x0283; + t.eshcurl = 0x0286; + t.eshortdeva = 0x090e; + t.eshortvowelsigndeva = 0x0946; + t.eshreversedloop = 0x01aa; + t.eshsquatreversed = 0x0285; + t.esmallhiragana = 0x3047; + t.esmallkatakana = 0x30a7; + t.esmallkatakanahalfwidth = 0xff6a; + t.estimated = 0x212e; + t.esuperior = 0xf6ec; + t.eta = 0x03b7; + t.etarmenian = 0x0568; + t.etatonos = 0x03ae; + t.eth = 0x00f0; + t.etilde = 0x1ebd; + t.etildebelow = 0x1e1b; + t.etnahtafoukhhebrew = 0x0591; + t.etnahtafoukhlefthebrew = 0x0591; + t.etnahtahebrew = 0x0591; + t.etnahtalefthebrew = 0x0591; + t.eturned = 0x01dd; + t.eukorean = 0x3161; + t.euro = 0x20ac; + t.evowelsignbengali = 0x09c7; + t.evowelsigndeva = 0x0947; + t.evowelsigngujarati = 0x0ac7; + t.exclam = 0x0021; + t.exclamarmenian = 0x055c; + t.exclamdbl = 0x203c; + t.exclamdown = 0x00a1; + t.exclamdownsmall = 0xf7a1; + t.exclammonospace = 0xff01; + t.exclamsmall = 0xf721; + t.existential = 0x2203; + t.ezh = 0x0292; + t.ezhcaron = 0x01ef; + t.ezhcurl = 0x0293; + t.ezhreversed = 0x01b9; + t.ezhtail = 0x01ba; + t.f = 0x0066; + t.fadeva = 0x095e; + t.fagurmukhi = 0x0a5e; + t.fahrenheit = 0x2109; + t.fathaarabic = 0x064e; + t.fathalowarabic = 0x064e; + t.fathatanarabic = 0x064b; + t.fbopomofo = 0x3108; + t.fcircle = 0x24d5; + t.fdotaccent = 0x1e1f; + t.feharabic = 0x0641; + t.feharmenian = 0x0586; + t.fehfinalarabic = 0xfed2; + t.fehinitialarabic = 0xfed3; + t.fehmedialarabic = 0xfed4; + t.feicoptic = 0x03e5; + t.female = 0x2640; + t.ff = 0xfb00; + t.f_f = 0xfb00; + t.ffi = 0xfb03; + t.f_f_i = 0xfb03; + t.ffl = 0xfb04; + t.f_f_l = 0xfb04; + t.fi = 0xfb01; + t.f_i = 0xfb01; + t.fifteencircle = 0x246e; + t.fifteenparen = 0x2482; + t.fifteenperiod = 0x2496; + t.figuredash = 0x2012; + t.filledbox = 0x25a0; + t.filledrect = 0x25ac; + t.finalkaf = 0x05da; + t.finalkafdagesh = 0xfb3a; + t.finalkafdageshhebrew = 0xfb3a; + t.finalkafhebrew = 0x05da; + t.finalmem = 0x05dd; + t.finalmemhebrew = 0x05dd; + t.finalnun = 0x05df; + t.finalnunhebrew = 0x05df; + t.finalpe = 0x05e3; + t.finalpehebrew = 0x05e3; + t.finaltsadi = 0x05e5; + t.finaltsadihebrew = 0x05e5; + t.firsttonechinese = 0x02c9; + t.fisheye = 0x25c9; + t.fitacyrillic = 0x0473; + t.five = 0x0035; + t.fivearabic = 0x0665; + t.fivebengali = 0x09eb; + t.fivecircle = 0x2464; + t.fivecircleinversesansserif = 0x278e; + t.fivedeva = 0x096b; + t.fiveeighths = 0x215d; + t.fivegujarati = 0x0aeb; + t.fivegurmukhi = 0x0a6b; + t.fivehackarabic = 0x0665; + t.fivehangzhou = 0x3025; + t.fiveideographicparen = 0x3224; + t.fiveinferior = 0x2085; + t.fivemonospace = 0xff15; + t.fiveoldstyle = 0xf735; + t.fiveparen = 0x2478; + t.fiveperiod = 0x248c; + t.fivepersian = 0x06f5; + t.fiveroman = 0x2174; + t.fivesuperior = 0x2075; + t.fivethai = 0x0e55; + t.fl = 0xfb02; + t.f_l = 0xfb02; + t.florin = 0x0192; + t.fmonospace = 0xff46; + t.fmsquare = 0x3399; + t.fofanthai = 0x0e1f; + t.fofathai = 0x0e1d; + t.fongmanthai = 0x0e4f; + t.forall = 0x2200; + t.four = 0x0034; + t.fourarabic = 0x0664; + t.fourbengali = 0x09ea; + t.fourcircle = 0x2463; + t.fourcircleinversesansserif = 0x278d; + t.fourdeva = 0x096a; + t.fourgujarati = 0x0aea; + t.fourgurmukhi = 0x0a6a; + t.fourhackarabic = 0x0664; + t.fourhangzhou = 0x3024; + t.fourideographicparen = 0x3223; + t.fourinferior = 0x2084; + t.fourmonospace = 0xff14; + t.fournumeratorbengali = 0x09f7; + t.fouroldstyle = 0xf734; + t.fourparen = 0x2477; + t.fourperiod = 0x248b; + t.fourpersian = 0x06f4; + t.fourroman = 0x2173; + t.foursuperior = 0x2074; + t.fourteencircle = 0x246d; + t.fourteenparen = 0x2481; + t.fourteenperiod = 0x2495; + t.fourthai = 0x0e54; + t.fourthtonechinese = 0x02cb; + t.fparen = 0x24a1; + t.fraction = 0x2044; + t.franc = 0x20a3; + t.g = 0x0067; + t.gabengali = 0x0997; + t.gacute = 0x01f5; + t.gadeva = 0x0917; + t.gafarabic = 0x06af; + t.gaffinalarabic = 0xfb93; + t.gafinitialarabic = 0xfb94; + t.gafmedialarabic = 0xfb95; + t.gagujarati = 0x0a97; + t.gagurmukhi = 0x0a17; + t.gahiragana = 0x304c; + t.gakatakana = 0x30ac; + t.gamma = 0x03b3; + t.gammalatinsmall = 0x0263; + t.gammasuperior = 0x02e0; + t.gangiacoptic = 0x03eb; + t.gbopomofo = 0x310d; + t.gbreve = 0x011f; + t.gcaron = 0x01e7; + t.gcedilla = 0x0123; + t.gcircle = 0x24d6; + t.gcircumflex = 0x011d; + t.gcommaaccent = 0x0123; + t.gdot = 0x0121; + t.gdotaccent = 0x0121; + t.gecyrillic = 0x0433; + t.gehiragana = 0x3052; + t.gekatakana = 0x30b2; + t.geometricallyequal = 0x2251; + t.gereshaccenthebrew = 0x059c; + t.gereshhebrew = 0x05f3; + t.gereshmuqdamhebrew = 0x059d; + t.germandbls = 0x00df; + t.gershayimaccenthebrew = 0x059e; + t.gershayimhebrew = 0x05f4; + t.getamark = 0x3013; + t.ghabengali = 0x0998; + t.ghadarmenian = 0x0572; + t.ghadeva = 0x0918; + t.ghagujarati = 0x0a98; + t.ghagurmukhi = 0x0a18; + t.ghainarabic = 0x063a; + t.ghainfinalarabic = 0xfece; + t.ghaininitialarabic = 0xfecf; + t.ghainmedialarabic = 0xfed0; + t.ghemiddlehookcyrillic = 0x0495; + t.ghestrokecyrillic = 0x0493; + t.gheupturncyrillic = 0x0491; + t.ghhadeva = 0x095a; + t.ghhagurmukhi = 0x0a5a; + t.ghook = 0x0260; + t.ghzsquare = 0x3393; + t.gihiragana = 0x304e; + t.gikatakana = 0x30ae; + t.gimarmenian = 0x0563; + t.gimel = 0x05d2; + t.gimeldagesh = 0xfb32; + t.gimeldageshhebrew = 0xfb32; + t.gimelhebrew = 0x05d2; + t.gjecyrillic = 0x0453; + t.glottalinvertedstroke = 0x01be; + t.glottalstop = 0x0294; + t.glottalstopinverted = 0x0296; + t.glottalstopmod = 0x02c0; + t.glottalstopreversed = 0x0295; + t.glottalstopreversedmod = 0x02c1; + t.glottalstopreversedsuperior = 0x02e4; + t.glottalstopstroke = 0x02a1; + t.glottalstopstrokereversed = 0x02a2; + t.gmacron = 0x1e21; + t.gmonospace = 0xff47; + t.gohiragana = 0x3054; + t.gokatakana = 0x30b4; + t.gparen = 0x24a2; + t.gpasquare = 0x33ac; + t.gradient = 0x2207; + t.grave = 0x0060; + t.gravebelowcmb = 0x0316; + t.gravecmb = 0x0300; + t.gravecomb = 0x0300; + t.gravedeva = 0x0953; + t.gravelowmod = 0x02ce; + t.gravemonospace = 0xff40; + t.gravetonecmb = 0x0340; + t.greater = 0x003e; + t.greaterequal = 0x2265; + t.greaterequalorless = 0x22db; + t.greatermonospace = 0xff1e; + t.greaterorequivalent = 0x2273; + t.greaterorless = 0x2277; + t.greateroverequal = 0x2267; + t.greatersmall = 0xfe65; + t.gscript = 0x0261; + t.gstroke = 0x01e5; + t.guhiragana = 0x3050; + t.guillemotleft = 0x00ab; + t.guillemotright = 0x00bb; + t.guilsinglleft = 0x2039; + t.guilsinglright = 0x203a; + t.gukatakana = 0x30b0; + t.guramusquare = 0x3318; + t.gysquare = 0x33c9; + t.h = 0x0068; + t.haabkhasiancyrillic = 0x04a9; + t.haaltonearabic = 0x06c1; + t.habengali = 0x09b9; + t.hadescendercyrillic = 0x04b3; + t.hadeva = 0x0939; + t.hagujarati = 0x0ab9; + t.hagurmukhi = 0x0a39; + t.haharabic = 0x062d; + t.hahfinalarabic = 0xfea2; + t.hahinitialarabic = 0xfea3; + t.hahiragana = 0x306f; + t.hahmedialarabic = 0xfea4; + t.haitusquare = 0x332a; + t.hakatakana = 0x30cf; + t.hakatakanahalfwidth = 0xff8a; + t.halantgurmukhi = 0x0a4d; + t.hamzaarabic = 0x0621; + t.hamzalowarabic = 0x0621; + t.hangulfiller = 0x3164; + t.hardsigncyrillic = 0x044a; + t.harpoonleftbarbup = 0x21bc; + t.harpoonrightbarbup = 0x21c0; + t.hasquare = 0x33ca; + t.hatafpatah = 0x05b2; + t.hatafpatah16 = 0x05b2; + t.hatafpatah23 = 0x05b2; + t.hatafpatah2f = 0x05b2; + t.hatafpatahhebrew = 0x05b2; + t.hatafpatahnarrowhebrew = 0x05b2; + t.hatafpatahquarterhebrew = 0x05b2; + t.hatafpatahwidehebrew = 0x05b2; + t.hatafqamats = 0x05b3; + t.hatafqamats1b = 0x05b3; + t.hatafqamats28 = 0x05b3; + t.hatafqamats34 = 0x05b3; + t.hatafqamatshebrew = 0x05b3; + t.hatafqamatsnarrowhebrew = 0x05b3; + t.hatafqamatsquarterhebrew = 0x05b3; + t.hatafqamatswidehebrew = 0x05b3; + t.hatafsegol = 0x05b1; + t.hatafsegol17 = 0x05b1; + t.hatafsegol24 = 0x05b1; + t.hatafsegol30 = 0x05b1; + t.hatafsegolhebrew = 0x05b1; + t.hatafsegolnarrowhebrew = 0x05b1; + t.hatafsegolquarterhebrew = 0x05b1; + t.hatafsegolwidehebrew = 0x05b1; + t.hbar = 0x0127; + t.hbopomofo = 0x310f; + t.hbrevebelow = 0x1e2b; + t.hcedilla = 0x1e29; + t.hcircle = 0x24d7; + t.hcircumflex = 0x0125; + t.hdieresis = 0x1e27; + t.hdotaccent = 0x1e23; + t.hdotbelow = 0x1e25; + t.he = 0x05d4; + t.heart = 0x2665; + t.heartsuitblack = 0x2665; + t.heartsuitwhite = 0x2661; + t.hedagesh = 0xfb34; + t.hedageshhebrew = 0xfb34; + t.hehaltonearabic = 0x06c1; + t.heharabic = 0x0647; + t.hehebrew = 0x05d4; + t.hehfinalaltonearabic = 0xfba7; + t.hehfinalalttwoarabic = 0xfeea; + t.hehfinalarabic = 0xfeea; + t.hehhamzaabovefinalarabic = 0xfba5; + t.hehhamzaaboveisolatedarabic = 0xfba4; + t.hehinitialaltonearabic = 0xfba8; + t.hehinitialarabic = 0xfeeb; + t.hehiragana = 0x3078; + t.hehmedialaltonearabic = 0xfba9; + t.hehmedialarabic = 0xfeec; + t.heiseierasquare = 0x337b; + t.hekatakana = 0x30d8; + t.hekatakanahalfwidth = 0xff8d; + t.hekutaarusquare = 0x3336; + t.henghook = 0x0267; + t.herutusquare = 0x3339; + t.het = 0x05d7; + t.hethebrew = 0x05d7; + t.hhook = 0x0266; + t.hhooksuperior = 0x02b1; + t.hieuhacirclekorean = 0x327b; + t.hieuhaparenkorean = 0x321b; + t.hieuhcirclekorean = 0x326d; + t.hieuhkorean = 0x314e; + t.hieuhparenkorean = 0x320d; + t.hihiragana = 0x3072; + t.hikatakana = 0x30d2; + t.hikatakanahalfwidth = 0xff8b; + t.hiriq = 0x05b4; + t.hiriq14 = 0x05b4; + t.hiriq21 = 0x05b4; + t.hiriq2d = 0x05b4; + t.hiriqhebrew = 0x05b4; + t.hiriqnarrowhebrew = 0x05b4; + t.hiriqquarterhebrew = 0x05b4; + t.hiriqwidehebrew = 0x05b4; + t.hlinebelow = 0x1e96; + t.hmonospace = 0xff48; + t.hoarmenian = 0x0570; + t.hohipthai = 0x0e2b; + t.hohiragana = 0x307b; + t.hokatakana = 0x30db; + t.hokatakanahalfwidth = 0xff8e; + t.holam = 0x05b9; + t.holam19 = 0x05b9; + t.holam26 = 0x05b9; + t.holam32 = 0x05b9; + t.holamhebrew = 0x05b9; + t.holamnarrowhebrew = 0x05b9; + t.holamquarterhebrew = 0x05b9; + t.holamwidehebrew = 0x05b9; + t.honokhukthai = 0x0e2e; + t.hookabovecomb = 0x0309; + t.hookcmb = 0x0309; + t.hookpalatalizedbelowcmb = 0x0321; + t.hookretroflexbelowcmb = 0x0322; + t.hoonsquare = 0x3342; + t.horicoptic = 0x03e9; + t.horizontalbar = 0x2015; + t.horncmb = 0x031b; + t.hotsprings = 0x2668; + t.house = 0x2302; + t.hparen = 0x24a3; + t.hsuperior = 0x02b0; + t.hturned = 0x0265; + t.huhiragana = 0x3075; + t.huiitosquare = 0x3333; + t.hukatakana = 0x30d5; + t.hukatakanahalfwidth = 0xff8c; + t.hungarumlaut = 0x02dd; + t.hungarumlautcmb = 0x030b; + t.hv = 0x0195; + t.hyphen = 0x002d; + t.hypheninferior = 0xf6e5; + t.hyphenmonospace = 0xff0d; + t.hyphensmall = 0xfe63; + t.hyphensuperior = 0xf6e6; + t.hyphentwo = 0x2010; + t.i = 0x0069; + t.iacute = 0x00ed; + t.iacyrillic = 0x044f; + t.ibengali = 0x0987; + t.ibopomofo = 0x3127; + t.ibreve = 0x012d; + t.icaron = 0x01d0; + t.icircle = 0x24d8; + t.icircumflex = 0x00ee; + t.icyrillic = 0x0456; + t.idblgrave = 0x0209; + t.ideographearthcircle = 0x328f; + t.ideographfirecircle = 0x328b; + t.ideographicallianceparen = 0x323f; + t.ideographiccallparen = 0x323a; + t.ideographiccentrecircle = 0x32a5; + t.ideographicclose = 0x3006; + t.ideographiccomma = 0x3001; + t.ideographiccommaleft = 0xff64; + t.ideographiccongratulationparen = 0x3237; + t.ideographiccorrectcircle = 0x32a3; + t.ideographicearthparen = 0x322f; + t.ideographicenterpriseparen = 0x323d; + t.ideographicexcellentcircle = 0x329d; + t.ideographicfestivalparen = 0x3240; + t.ideographicfinancialcircle = 0x3296; + t.ideographicfinancialparen = 0x3236; + t.ideographicfireparen = 0x322b; + t.ideographichaveparen = 0x3232; + t.ideographichighcircle = 0x32a4; + t.ideographiciterationmark = 0x3005; + t.ideographiclaborcircle = 0x3298; + t.ideographiclaborparen = 0x3238; + t.ideographicleftcircle = 0x32a7; + t.ideographiclowcircle = 0x32a6; + t.ideographicmedicinecircle = 0x32a9; + t.ideographicmetalparen = 0x322e; + t.ideographicmoonparen = 0x322a; + t.ideographicnameparen = 0x3234; + t.ideographicperiod = 0x3002; + t.ideographicprintcircle = 0x329e; + t.ideographicreachparen = 0x3243; + t.ideographicrepresentparen = 0x3239; + t.ideographicresourceparen = 0x323e; + t.ideographicrightcircle = 0x32a8; + t.ideographicsecretcircle = 0x3299; + t.ideographicselfparen = 0x3242; + t.ideographicsocietyparen = 0x3233; + t.ideographicspace = 0x3000; + t.ideographicspecialparen = 0x3235; + t.ideographicstockparen = 0x3231; + t.ideographicstudyparen = 0x323b; + t.ideographicsunparen = 0x3230; + t.ideographicsuperviseparen = 0x323c; + t.ideographicwaterparen = 0x322c; + t.ideographicwoodparen = 0x322d; + t.ideographiczero = 0x3007; + t.ideographmetalcircle = 0x328e; + t.ideographmooncircle = 0x328a; + t.ideographnamecircle = 0x3294; + t.ideographsuncircle = 0x3290; + t.ideographwatercircle = 0x328c; + t.ideographwoodcircle = 0x328d; + t.ideva = 0x0907; + t.idieresis = 0x00ef; + t.idieresisacute = 0x1e2f; + t.idieresiscyrillic = 0x04e5; + t.idotbelow = 0x1ecb; + t.iebrevecyrillic = 0x04d7; + t.iecyrillic = 0x0435; + t.ieungacirclekorean = 0x3275; + t.ieungaparenkorean = 0x3215; + t.ieungcirclekorean = 0x3267; + t.ieungkorean = 0x3147; + t.ieungparenkorean = 0x3207; + t.igrave = 0x00ec; + t.igujarati = 0x0a87; + t.igurmukhi = 0x0a07; + t.ihiragana = 0x3044; + t.ihookabove = 0x1ec9; + t.iibengali = 0x0988; + t.iicyrillic = 0x0438; + t.iideva = 0x0908; + t.iigujarati = 0x0a88; + t.iigurmukhi = 0x0a08; + t.iimatragurmukhi = 0x0a40; + t.iinvertedbreve = 0x020b; + t.iishortcyrillic = 0x0439; + t.iivowelsignbengali = 0x09c0; + t.iivowelsigndeva = 0x0940; + t.iivowelsigngujarati = 0x0ac0; + t.ij = 0x0133; + t.ikatakana = 0x30a4; + t.ikatakanahalfwidth = 0xff72; + t.ikorean = 0x3163; + t.ilde = 0x02dc; + t.iluyhebrew = 0x05ac; + t.imacron = 0x012b; + t.imacroncyrillic = 0x04e3; + t.imageorapproximatelyequal = 0x2253; + t.imatragurmukhi = 0x0a3f; + t.imonospace = 0xff49; + t.increment = 0x2206; + t.infinity = 0x221e; + t.iniarmenian = 0x056b; + t.integral = 0x222b; + t.integralbottom = 0x2321; + t.integralbt = 0x2321; + t.integralex = 0xf8f5; + t.integraltop = 0x2320; + t.integraltp = 0x2320; + t.intersection = 0x2229; + t.intisquare = 0x3305; + t.invbullet = 0x25d8; + t.invcircle = 0x25d9; + t.invsmileface = 0x263b; + t.iocyrillic = 0x0451; + t.iogonek = 0x012f; + t.iota = 0x03b9; + t.iotadieresis = 0x03ca; + t.iotadieresistonos = 0x0390; + t.iotalatin = 0x0269; + t.iotatonos = 0x03af; + t.iparen = 0x24a4; + t.irigurmukhi = 0x0a72; + t.ismallhiragana = 0x3043; + t.ismallkatakana = 0x30a3; + t.ismallkatakanahalfwidth = 0xff68; + t.issharbengali = 0x09fa; + t.istroke = 0x0268; + t.isuperior = 0xf6ed; + t.iterationhiragana = 0x309d; + t.iterationkatakana = 0x30fd; + t.itilde = 0x0129; + t.itildebelow = 0x1e2d; + t.iubopomofo = 0x3129; + t.iucyrillic = 0x044e; + t.ivowelsignbengali = 0x09bf; + t.ivowelsigndeva = 0x093f; + t.ivowelsigngujarati = 0x0abf; + t.izhitsacyrillic = 0x0475; + t.izhitsadblgravecyrillic = 0x0477; + t.j = 0x006a; + t.jaarmenian = 0x0571; + t.jabengali = 0x099c; + t.jadeva = 0x091c; + t.jagujarati = 0x0a9c; + t.jagurmukhi = 0x0a1c; + t.jbopomofo = 0x3110; + t.jcaron = 0x01f0; + t.jcircle = 0x24d9; + t.jcircumflex = 0x0135; + t.jcrossedtail = 0x029d; + t.jdotlessstroke = 0x025f; + t.jecyrillic = 0x0458; + t.jeemarabic = 0x062c; + t.jeemfinalarabic = 0xfe9e; + t.jeeminitialarabic = 0xfe9f; + t.jeemmedialarabic = 0xfea0; + t.jeharabic = 0x0698; + t.jehfinalarabic = 0xfb8b; + t.jhabengali = 0x099d; + t.jhadeva = 0x091d; + t.jhagujarati = 0x0a9d; + t.jhagurmukhi = 0x0a1d; + t.jheharmenian = 0x057b; + t.jis = 0x3004; + t.jmonospace = 0xff4a; + t.jparen = 0x24a5; + t.jsuperior = 0x02b2; + t.k = 0x006b; + t.kabashkircyrillic = 0x04a1; + t.kabengali = 0x0995; + t.kacute = 0x1e31; + t.kacyrillic = 0x043a; + t.kadescendercyrillic = 0x049b; + t.kadeva = 0x0915; + t.kaf = 0x05db; + t.kafarabic = 0x0643; + t.kafdagesh = 0xfb3b; + t.kafdageshhebrew = 0xfb3b; + t.kaffinalarabic = 0xfeda; + t.kafhebrew = 0x05db; + t.kafinitialarabic = 0xfedb; + t.kafmedialarabic = 0xfedc; + t.kafrafehebrew = 0xfb4d; + t.kagujarati = 0x0a95; + t.kagurmukhi = 0x0a15; + t.kahiragana = 0x304b; + t.kahookcyrillic = 0x04c4; + t.kakatakana = 0x30ab; + t.kakatakanahalfwidth = 0xff76; + t.kappa = 0x03ba; + t.kappasymbolgreek = 0x03f0; + t.kapyeounmieumkorean = 0x3171; + t.kapyeounphieuphkorean = 0x3184; + t.kapyeounpieupkorean = 0x3178; + t.kapyeounssangpieupkorean = 0x3179; + t.karoriisquare = 0x330d; + t.kashidaautoarabic = 0x0640; + t.kashidaautonosidebearingarabic = 0x0640; + t.kasmallkatakana = 0x30f5; + t.kasquare = 0x3384; + t.kasraarabic = 0x0650; + t.kasratanarabic = 0x064d; + t.kastrokecyrillic = 0x049f; + t.katahiraprolongmarkhalfwidth = 0xff70; + t.kaverticalstrokecyrillic = 0x049d; + t.kbopomofo = 0x310e; + t.kcalsquare = 0x3389; + t.kcaron = 0x01e9; + t.kcedilla = 0x0137; + t.kcircle = 0x24da; + t.kcommaaccent = 0x0137; + t.kdotbelow = 0x1e33; + t.keharmenian = 0x0584; + t.kehiragana = 0x3051; + t.kekatakana = 0x30b1; + t.kekatakanahalfwidth = 0xff79; + t.kenarmenian = 0x056f; + t.kesmallkatakana = 0x30f6; + t.kgreenlandic = 0x0138; + t.khabengali = 0x0996; + t.khacyrillic = 0x0445; + t.khadeva = 0x0916; + t.khagujarati = 0x0a96; + t.khagurmukhi = 0x0a16; + t.khaharabic = 0x062e; + t.khahfinalarabic = 0xfea6; + t.khahinitialarabic = 0xfea7; + t.khahmedialarabic = 0xfea8; + t.kheicoptic = 0x03e7; + t.khhadeva = 0x0959; + t.khhagurmukhi = 0x0a59; + t.khieukhacirclekorean = 0x3278; + t.khieukhaparenkorean = 0x3218; + t.khieukhcirclekorean = 0x326a; + t.khieukhkorean = 0x314b; + t.khieukhparenkorean = 0x320a; + t.khokhaithai = 0x0e02; + t.khokhonthai = 0x0e05; + t.khokhuatthai = 0x0e03; + t.khokhwaithai = 0x0e04; + t.khomutthai = 0x0e5b; + t.khook = 0x0199; + t.khorakhangthai = 0x0e06; + t.khzsquare = 0x3391; + t.kihiragana = 0x304d; + t.kikatakana = 0x30ad; + t.kikatakanahalfwidth = 0xff77; + t.kiroguramusquare = 0x3315; + t.kiromeetorusquare = 0x3316; + t.kirosquare = 0x3314; + t.kiyeokacirclekorean = 0x326e; + t.kiyeokaparenkorean = 0x320e; + t.kiyeokcirclekorean = 0x3260; + t.kiyeokkorean = 0x3131; + t.kiyeokparenkorean = 0x3200; + t.kiyeoksioskorean = 0x3133; + t.kjecyrillic = 0x045c; + t.klinebelow = 0x1e35; + t.klsquare = 0x3398; + t.kmcubedsquare = 0x33a6; + t.kmonospace = 0xff4b; + t.kmsquaredsquare = 0x33a2; + t.kohiragana = 0x3053; + t.kohmsquare = 0x33c0; + t.kokaithai = 0x0e01; + t.kokatakana = 0x30b3; + t.kokatakanahalfwidth = 0xff7a; + t.kooposquare = 0x331e; + t.koppacyrillic = 0x0481; + t.koreanstandardsymbol = 0x327f; + t.koroniscmb = 0x0343; + t.kparen = 0x24a6; + t.kpasquare = 0x33aa; + t.ksicyrillic = 0x046f; + t.ktsquare = 0x33cf; + t.kturned = 0x029e; + t.kuhiragana = 0x304f; + t.kukatakana = 0x30af; + t.kukatakanahalfwidth = 0xff78; + t.kvsquare = 0x33b8; + t.kwsquare = 0x33be; + t.l = 0x006c; + t.labengali = 0x09b2; + t.lacute = 0x013a; + t.ladeva = 0x0932; + t.lagujarati = 0x0ab2; + t.lagurmukhi = 0x0a32; + t.lakkhangyaothai = 0x0e45; + t.lamaleffinalarabic = 0xfefc; + t.lamalefhamzaabovefinalarabic = 0xfef8; + t.lamalefhamzaaboveisolatedarabic = 0xfef7; + t.lamalefhamzabelowfinalarabic = 0xfefa; + t.lamalefhamzabelowisolatedarabic = 0xfef9; + t.lamalefisolatedarabic = 0xfefb; + t.lamalefmaddaabovefinalarabic = 0xfef6; + t.lamalefmaddaaboveisolatedarabic = 0xfef5; + t.lamarabic = 0x0644; + t.lambda = 0x03bb; + t.lambdastroke = 0x019b; + t.lamed = 0x05dc; + t.lameddagesh = 0xfb3c; + t.lameddageshhebrew = 0xfb3c; + t.lamedhebrew = 0x05dc; + t.lamfinalarabic = 0xfede; + t.lamhahinitialarabic = 0xfcca; + t.laminitialarabic = 0xfedf; + t.lamjeeminitialarabic = 0xfcc9; + t.lamkhahinitialarabic = 0xfccb; + t.lamlamhehisolatedarabic = 0xfdf2; + t.lammedialarabic = 0xfee0; + t.lammeemhahinitialarabic = 0xfd88; + t.lammeeminitialarabic = 0xfccc; + t.largecircle = 0x25ef; + t.lbar = 0x019a; + t.lbelt = 0x026c; + t.lbopomofo = 0x310c; + t.lcaron = 0x013e; + t.lcedilla = 0x013c; + t.lcircle = 0x24db; + t.lcircumflexbelow = 0x1e3d; + t.lcommaaccent = 0x013c; + t.ldot = 0x0140; + t.ldotaccent = 0x0140; + t.ldotbelow = 0x1e37; + t.ldotbelowmacron = 0x1e39; + t.leftangleabovecmb = 0x031a; + t.lefttackbelowcmb = 0x0318; + t.less = 0x003c; + t.lessequal = 0x2264; + t.lessequalorgreater = 0x22da; + t.lessmonospace = 0xff1c; + t.lessorequivalent = 0x2272; + t.lessorgreater = 0x2276; + t.lessoverequal = 0x2266; + t.lesssmall = 0xfe64; + t.lezh = 0x026e; + t.lfblock = 0x258c; + t.lhookretroflex = 0x026d; + t.lira = 0x20a4; + t.liwnarmenian = 0x056c; + t.lj = 0x01c9; + t.ljecyrillic = 0x0459; + t.ll = 0xf6c0; + t.lladeva = 0x0933; + t.llagujarati = 0x0ab3; + t.llinebelow = 0x1e3b; + t.llladeva = 0x0934; + t.llvocalicbengali = 0x09e1; + t.llvocalicdeva = 0x0961; + t.llvocalicvowelsignbengali = 0x09e3; + t.llvocalicvowelsigndeva = 0x0963; + t.lmiddletilde = 0x026b; + t.lmonospace = 0xff4c; + t.lmsquare = 0x33d0; + t.lochulathai = 0x0e2c; + t.logicaland = 0x2227; + t.logicalnot = 0x00ac; + t.logicalnotreversed = 0x2310; + t.logicalor = 0x2228; + t.lolingthai = 0x0e25; + t.longs = 0x017f; + t.lowlinecenterline = 0xfe4e; + t.lowlinecmb = 0x0332; + t.lowlinedashed = 0xfe4d; + t.lozenge = 0x25ca; + t.lparen = 0x24a7; + t.lslash = 0x0142; + t.lsquare = 0x2113; + t.lsuperior = 0xf6ee; + t.ltshade = 0x2591; + t.luthai = 0x0e26; + t.lvocalicbengali = 0x098c; + t.lvocalicdeva = 0x090c; + t.lvocalicvowelsignbengali = 0x09e2; + t.lvocalicvowelsigndeva = 0x0962; + t.lxsquare = 0x33d3; + t.m = 0x006d; + t.mabengali = 0x09ae; + t.macron = 0x00af; + t.macronbelowcmb = 0x0331; + t.macroncmb = 0x0304; + t.macronlowmod = 0x02cd; + t.macronmonospace = 0xffe3; + t.macute = 0x1e3f; + t.madeva = 0x092e; + t.magujarati = 0x0aae; + t.magurmukhi = 0x0a2e; + t.mahapakhhebrew = 0x05a4; + t.mahapakhlefthebrew = 0x05a4; + t.mahiragana = 0x307e; + t.maichattawalowleftthai = 0xf895; + t.maichattawalowrightthai = 0xf894; + t.maichattawathai = 0x0e4b; + t.maichattawaupperleftthai = 0xf893; + t.maieklowleftthai = 0xf88c; + t.maieklowrightthai = 0xf88b; + t.maiekthai = 0x0e48; + t.maiekupperleftthai = 0xf88a; + t.maihanakatleftthai = 0xf884; + t.maihanakatthai = 0x0e31; + t.maitaikhuleftthai = 0xf889; + t.maitaikhuthai = 0x0e47; + t.maitholowleftthai = 0xf88f; + t.maitholowrightthai = 0xf88e; + t.maithothai = 0x0e49; + t.maithoupperleftthai = 0xf88d; + t.maitrilowleftthai = 0xf892; + t.maitrilowrightthai = 0xf891; + t.maitrithai = 0x0e4a; + t.maitriupperleftthai = 0xf890; + t.maiyamokthai = 0x0e46; + t.makatakana = 0x30de; + t.makatakanahalfwidth = 0xff8f; + t.male = 0x2642; + t.mansyonsquare = 0x3347; + t.maqafhebrew = 0x05be; + t.mars = 0x2642; + t.masoracirclehebrew = 0x05af; + t.masquare = 0x3383; + t.mbopomofo = 0x3107; + t.mbsquare = 0x33d4; + t.mcircle = 0x24dc; + t.mcubedsquare = 0x33a5; + t.mdotaccent = 0x1e41; + t.mdotbelow = 0x1e43; + t.meemarabic = 0x0645; + t.meemfinalarabic = 0xfee2; + t.meeminitialarabic = 0xfee3; + t.meemmedialarabic = 0xfee4; + t.meemmeeminitialarabic = 0xfcd1; + t.meemmeemisolatedarabic = 0xfc48; + t.meetorusquare = 0x334d; + t.mehiragana = 0x3081; + t.meizierasquare = 0x337e; + t.mekatakana = 0x30e1; + t.mekatakanahalfwidth = 0xff92; + t.mem = 0x05de; + t.memdagesh = 0xfb3e; + t.memdageshhebrew = 0xfb3e; + t.memhebrew = 0x05de; + t.menarmenian = 0x0574; + t.merkhahebrew = 0x05a5; + t.merkhakefulahebrew = 0x05a6; + t.merkhakefulalefthebrew = 0x05a6; + t.merkhalefthebrew = 0x05a5; + t.mhook = 0x0271; + t.mhzsquare = 0x3392; + t.middledotkatakanahalfwidth = 0xff65; + t.middot = 0x00b7; + t.mieumacirclekorean = 0x3272; + t.mieumaparenkorean = 0x3212; + t.mieumcirclekorean = 0x3264; + t.mieumkorean = 0x3141; + t.mieumpansioskorean = 0x3170; + t.mieumparenkorean = 0x3204; + t.mieumpieupkorean = 0x316e; + t.mieumsioskorean = 0x316f; + t.mihiragana = 0x307f; + t.mikatakana = 0x30df; + t.mikatakanahalfwidth = 0xff90; + t.minus = 0x2212; + t.minusbelowcmb = 0x0320; + t.minuscircle = 0x2296; + t.minusmod = 0x02d7; + t.minusplus = 0x2213; + t.minute = 0x2032; + t.miribaarusquare = 0x334a; + t.mirisquare = 0x3349; + t.mlonglegturned = 0x0270; + t.mlsquare = 0x3396; + t.mmcubedsquare = 0x33a3; + t.mmonospace = 0xff4d; + t.mmsquaredsquare = 0x339f; + t.mohiragana = 0x3082; + t.mohmsquare = 0x33c1; + t.mokatakana = 0x30e2; + t.mokatakanahalfwidth = 0xff93; + t.molsquare = 0x33d6; + t.momathai = 0x0e21; + t.moverssquare = 0x33a7; + t.moverssquaredsquare = 0x33a8; + t.mparen = 0x24a8; + t.mpasquare = 0x33ab; + t.mssquare = 0x33b3; + t.msuperior = 0xf6ef; + t.mturned = 0x026f; + t.mu = 0x00b5; + t.mu1 = 0x00b5; + t.muasquare = 0x3382; + t.muchgreater = 0x226b; + t.muchless = 0x226a; + t.mufsquare = 0x338c; + t.mugreek = 0x03bc; + t.mugsquare = 0x338d; + t.muhiragana = 0x3080; + t.mukatakana = 0x30e0; + t.mukatakanahalfwidth = 0xff91; + t.mulsquare = 0x3395; + t.multiply = 0x00d7; + t.mumsquare = 0x339b; + t.munahhebrew = 0x05a3; + t.munahlefthebrew = 0x05a3; + t.musicalnote = 0x266a; + t.musicalnotedbl = 0x266b; + t.musicflatsign = 0x266d; + t.musicsharpsign = 0x266f; + t.mussquare = 0x33b2; + t.muvsquare = 0x33b6; + t.muwsquare = 0x33bc; + t.mvmegasquare = 0x33b9; + t.mvsquare = 0x33b7; + t.mwmegasquare = 0x33bf; + t.mwsquare = 0x33bd; + t.n = 0x006e; + t.nabengali = 0x09a8; + t.nabla = 0x2207; + t.nacute = 0x0144; + t.nadeva = 0x0928; + t.nagujarati = 0x0aa8; + t.nagurmukhi = 0x0a28; + t.nahiragana = 0x306a; + t.nakatakana = 0x30ca; + t.nakatakanahalfwidth = 0xff85; + t.napostrophe = 0x0149; + t.nasquare = 0x3381; + t.nbopomofo = 0x310b; + t.nbspace = 0x00a0; + t.ncaron = 0x0148; + t.ncedilla = 0x0146; + t.ncircle = 0x24dd; + t.ncircumflexbelow = 0x1e4b; + t.ncommaaccent = 0x0146; + t.ndotaccent = 0x1e45; + t.ndotbelow = 0x1e47; + t.nehiragana = 0x306d; + t.nekatakana = 0x30cd; + t.nekatakanahalfwidth = 0xff88; + t.newsheqelsign = 0x20aa; + t.nfsquare = 0x338b; + t.ngabengali = 0x0999; + t.ngadeva = 0x0919; + t.ngagujarati = 0x0a99; + t.ngagurmukhi = 0x0a19; + t.ngonguthai = 0x0e07; + t.nhiragana = 0x3093; + t.nhookleft = 0x0272; + t.nhookretroflex = 0x0273; + t.nieunacirclekorean = 0x326f; + t.nieunaparenkorean = 0x320f; + t.nieuncieuckorean = 0x3135; + t.nieuncirclekorean = 0x3261; + t.nieunhieuhkorean = 0x3136; + t.nieunkorean = 0x3134; + t.nieunpansioskorean = 0x3168; + t.nieunparenkorean = 0x3201; + t.nieunsioskorean = 0x3167; + t.nieuntikeutkorean = 0x3166; + t.nihiragana = 0x306b; + t.nikatakana = 0x30cb; + t.nikatakanahalfwidth = 0xff86; + t.nikhahitleftthai = 0xf899; + t.nikhahitthai = 0x0e4d; + t.nine = 0x0039; + t.ninearabic = 0x0669; + t.ninebengali = 0x09ef; + t.ninecircle = 0x2468; + t.ninecircleinversesansserif = 0x2792; + t.ninedeva = 0x096f; + t.ninegujarati = 0x0aef; + t.ninegurmukhi = 0x0a6f; + t.ninehackarabic = 0x0669; + t.ninehangzhou = 0x3029; + t.nineideographicparen = 0x3228; + t.nineinferior = 0x2089; + t.ninemonospace = 0xff19; + t.nineoldstyle = 0xf739; + t.nineparen = 0x247c; + t.nineperiod = 0x2490; + t.ninepersian = 0x06f9; + t.nineroman = 0x2178; + t.ninesuperior = 0x2079; + t.nineteencircle = 0x2472; + t.nineteenparen = 0x2486; + t.nineteenperiod = 0x249a; + t.ninethai = 0x0e59; + t.nj = 0x01cc; + t.njecyrillic = 0x045a; + t.nkatakana = 0x30f3; + t.nkatakanahalfwidth = 0xff9d; + t.nlegrightlong = 0x019e; + t.nlinebelow = 0x1e49; + t.nmonospace = 0xff4e; + t.nmsquare = 0x339a; + t.nnabengali = 0x09a3; + t.nnadeva = 0x0923; + t.nnagujarati = 0x0aa3; + t.nnagurmukhi = 0x0a23; + t.nnnadeva = 0x0929; + t.nohiragana = 0x306e; + t.nokatakana = 0x30ce; + t.nokatakanahalfwidth = 0xff89; + t.nonbreakingspace = 0x00a0; + t.nonenthai = 0x0e13; + t.nonuthai = 0x0e19; + t.noonarabic = 0x0646; + t.noonfinalarabic = 0xfee6; + t.noonghunnaarabic = 0x06ba; + t.noonghunnafinalarabic = 0xfb9f; + t.nooninitialarabic = 0xfee7; + t.noonjeeminitialarabic = 0xfcd2; + t.noonjeemisolatedarabic = 0xfc4b; + t.noonmedialarabic = 0xfee8; + t.noonmeeminitialarabic = 0xfcd5; + t.noonmeemisolatedarabic = 0xfc4e; + t.noonnoonfinalarabic = 0xfc8d; + t.notcontains = 0x220c; + t.notelement = 0x2209; + t.notelementof = 0x2209; + t.notequal = 0x2260; + t.notgreater = 0x226f; + t.notgreaternorequal = 0x2271; + t.notgreaternorless = 0x2279; + t.notidentical = 0x2262; + t.notless = 0x226e; + t.notlessnorequal = 0x2270; + t.notparallel = 0x2226; + t.notprecedes = 0x2280; + t.notsubset = 0x2284; + t.notsucceeds = 0x2281; + t.notsuperset = 0x2285; + t.nowarmenian = 0x0576; + t.nparen = 0x24a9; + t.nssquare = 0x33b1; + t.nsuperior = 0x207f; + t.ntilde = 0x00f1; + t.nu = 0x03bd; + t.nuhiragana = 0x306c; + t.nukatakana = 0x30cc; + t.nukatakanahalfwidth = 0xff87; + t.nuktabengali = 0x09bc; + t.nuktadeva = 0x093c; + t.nuktagujarati = 0x0abc; + t.nuktagurmukhi = 0x0a3c; + t.numbersign = 0x0023; + t.numbersignmonospace = 0xff03; + t.numbersignsmall = 0xfe5f; + t.numeralsigngreek = 0x0374; + t.numeralsignlowergreek = 0x0375; + t.numero = 0x2116; + t.nun = 0x05e0; + t.nundagesh = 0xfb40; + t.nundageshhebrew = 0xfb40; + t.nunhebrew = 0x05e0; + t.nvsquare = 0x33b5; + t.nwsquare = 0x33bb; + t.nyabengali = 0x099e; + t.nyadeva = 0x091e; + t.nyagujarati = 0x0a9e; + t.nyagurmukhi = 0x0a1e; + t.o = 0x006f; + t.oacute = 0x00f3; + t.oangthai = 0x0e2d; + t.obarred = 0x0275; + t.obarredcyrillic = 0x04e9; + t.obarreddieresiscyrillic = 0x04eb; + t.obengali = 0x0993; + t.obopomofo = 0x311b; + t.obreve = 0x014f; + t.ocandradeva = 0x0911; + t.ocandragujarati = 0x0a91; + t.ocandravowelsigndeva = 0x0949; + t.ocandravowelsigngujarati = 0x0ac9; + t.ocaron = 0x01d2; + t.ocircle = 0x24de; + t.ocircumflex = 0x00f4; + t.ocircumflexacute = 0x1ed1; + t.ocircumflexdotbelow = 0x1ed9; + t.ocircumflexgrave = 0x1ed3; + t.ocircumflexhookabove = 0x1ed5; + t.ocircumflextilde = 0x1ed7; + t.ocyrillic = 0x043e; + t.odblacute = 0x0151; + t.odblgrave = 0x020d; + t.odeva = 0x0913; + t.odieresis = 0x00f6; + t.odieresiscyrillic = 0x04e7; + t.odotbelow = 0x1ecd; + t.oe = 0x0153; + t.oekorean = 0x315a; + t.ogonek = 0x02db; + t.ogonekcmb = 0x0328; + t.ograve = 0x00f2; + t.ogujarati = 0x0a93; + t.oharmenian = 0x0585; + t.ohiragana = 0x304a; + t.ohookabove = 0x1ecf; + t.ohorn = 0x01a1; + t.ohornacute = 0x1edb; + t.ohorndotbelow = 0x1ee3; + t.ohorngrave = 0x1edd; + t.ohornhookabove = 0x1edf; + t.ohorntilde = 0x1ee1; + t.ohungarumlaut = 0x0151; + t.oi = 0x01a3; + t.oinvertedbreve = 0x020f; + t.okatakana = 0x30aa; + t.okatakanahalfwidth = 0xff75; + t.okorean = 0x3157; + t.olehebrew = 0x05ab; + t.omacron = 0x014d; + t.omacronacute = 0x1e53; + t.omacrongrave = 0x1e51; + t.omdeva = 0x0950; + t.omega = 0x03c9; + t.omega1 = 0x03d6; + t.omegacyrillic = 0x0461; + t.omegalatinclosed = 0x0277; + t.omegaroundcyrillic = 0x047b; + t.omegatitlocyrillic = 0x047d; + t.omegatonos = 0x03ce; + t.omgujarati = 0x0ad0; + t.omicron = 0x03bf; + t.omicrontonos = 0x03cc; + t.omonospace = 0xff4f; + t.one = 0x0031; + t.onearabic = 0x0661; + t.onebengali = 0x09e7; + t.onecircle = 0x2460; + t.onecircleinversesansserif = 0x278a; + t.onedeva = 0x0967; + t.onedotenleader = 0x2024; + t.oneeighth = 0x215b; + t.onefitted = 0xf6dc; + t.onegujarati = 0x0ae7; + t.onegurmukhi = 0x0a67; + t.onehackarabic = 0x0661; + t.onehalf = 0x00bd; + t.onehangzhou = 0x3021; + t.oneideographicparen = 0x3220; + t.oneinferior = 0x2081; + t.onemonospace = 0xff11; + t.onenumeratorbengali = 0x09f4; + t.oneoldstyle = 0xf731; + t.oneparen = 0x2474; + t.oneperiod = 0x2488; + t.onepersian = 0x06f1; + t.onequarter = 0x00bc; + t.oneroman = 0x2170; + t.onesuperior = 0x00b9; + t.onethai = 0x0e51; + t.onethird = 0x2153; + t.oogonek = 0x01eb; + t.oogonekmacron = 0x01ed; + t.oogurmukhi = 0x0a13; + t.oomatragurmukhi = 0x0a4b; + t.oopen = 0x0254; + t.oparen = 0x24aa; + t.openbullet = 0x25e6; + t.option = 0x2325; + t.ordfeminine = 0x00aa; + t.ordmasculine = 0x00ba; + t.orthogonal = 0x221f; + t.oshortdeva = 0x0912; + t.oshortvowelsigndeva = 0x094a; + t.oslash = 0x00f8; + t.oslashacute = 0x01ff; + t.osmallhiragana = 0x3049; + t.osmallkatakana = 0x30a9; + t.osmallkatakanahalfwidth = 0xff6b; + t.ostrokeacute = 0x01ff; + t.osuperior = 0xf6f0; + t.otcyrillic = 0x047f; + t.otilde = 0x00f5; + t.otildeacute = 0x1e4d; + t.otildedieresis = 0x1e4f; + t.oubopomofo = 0x3121; + t.overline = 0x203e; + t.overlinecenterline = 0xfe4a; + t.overlinecmb = 0x0305; + t.overlinedashed = 0xfe49; + t.overlinedblwavy = 0xfe4c; + t.overlinewavy = 0xfe4b; + t.overscore = 0x00af; + t.ovowelsignbengali = 0x09cb; + t.ovowelsigndeva = 0x094b; + t.ovowelsigngujarati = 0x0acb; + t.p = 0x0070; + t.paampssquare = 0x3380; + t.paasentosquare = 0x332b; + t.pabengali = 0x09aa; + t.pacute = 0x1e55; + t.padeva = 0x092a; + t.pagedown = 0x21df; + t.pageup = 0x21de; + t.pagujarati = 0x0aaa; + t.pagurmukhi = 0x0a2a; + t.pahiragana = 0x3071; + t.paiyannoithai = 0x0e2f; + t.pakatakana = 0x30d1; + t.palatalizationcyrilliccmb = 0x0484; + t.palochkacyrillic = 0x04c0; + t.pansioskorean = 0x317f; + t.paragraph = 0x00b6; + t.parallel = 0x2225; + t.parenleft = 0x0028; + t.parenleftaltonearabic = 0xfd3e; + t.parenleftbt = 0xf8ed; + t.parenleftex = 0xf8ec; + t.parenleftinferior = 0x208d; + t.parenleftmonospace = 0xff08; + t.parenleftsmall = 0xfe59; + t.parenleftsuperior = 0x207d; + t.parenlefttp = 0xf8eb; + t.parenleftvertical = 0xfe35; + t.parenright = 0x0029; + t.parenrightaltonearabic = 0xfd3f; + t.parenrightbt = 0xf8f8; + t.parenrightex = 0xf8f7; + t.parenrightinferior = 0x208e; + t.parenrightmonospace = 0xff09; + t.parenrightsmall = 0xfe5a; + t.parenrightsuperior = 0x207e; + t.parenrighttp = 0xf8f6; + t.parenrightvertical = 0xfe36; + t.partialdiff = 0x2202; + t.paseqhebrew = 0x05c0; + t.pashtahebrew = 0x0599; + t.pasquare = 0x33a9; + t.patah = 0x05b7; + t.patah11 = 0x05b7; + t.patah1d = 0x05b7; + t.patah2a = 0x05b7; + t.patahhebrew = 0x05b7; + t.patahnarrowhebrew = 0x05b7; + t.patahquarterhebrew = 0x05b7; + t.patahwidehebrew = 0x05b7; + t.pazerhebrew = 0x05a1; + t.pbopomofo = 0x3106; + t.pcircle = 0x24df; + t.pdotaccent = 0x1e57; + t.pe = 0x05e4; + t.pecyrillic = 0x043f; + t.pedagesh = 0xfb44; + t.pedageshhebrew = 0xfb44; + t.peezisquare = 0x333b; + t.pefinaldageshhebrew = 0xfb43; + t.peharabic = 0x067e; + t.peharmenian = 0x057a; + t.pehebrew = 0x05e4; + t.pehfinalarabic = 0xfb57; + t.pehinitialarabic = 0xfb58; + t.pehiragana = 0x307a; + t.pehmedialarabic = 0xfb59; + t.pekatakana = 0x30da; + t.pemiddlehookcyrillic = 0x04a7; + t.perafehebrew = 0xfb4e; + t.percent = 0x0025; + t.percentarabic = 0x066a; + t.percentmonospace = 0xff05; + t.percentsmall = 0xfe6a; + t.period = 0x002e; + t.periodarmenian = 0x0589; + t.periodcentered = 0x00b7; + t.periodhalfwidth = 0xff61; + t.periodinferior = 0xf6e7; + t.periodmonospace = 0xff0e; + t.periodsmall = 0xfe52; + t.periodsuperior = 0xf6e8; + t.perispomenigreekcmb = 0x0342; + t.perpendicular = 0x22a5; + t.perthousand = 0x2030; + t.peseta = 0x20a7; + t.pfsquare = 0x338a; + t.phabengali = 0x09ab; + t.phadeva = 0x092b; + t.phagujarati = 0x0aab; + t.phagurmukhi = 0x0a2b; + t.phi = 0x03c6; + t.phi1 = 0x03d5; + t.phieuphacirclekorean = 0x327a; + t.phieuphaparenkorean = 0x321a; + t.phieuphcirclekorean = 0x326c; + t.phieuphkorean = 0x314d; + t.phieuphparenkorean = 0x320c; + t.philatin = 0x0278; + t.phinthuthai = 0x0e3a; + t.phisymbolgreek = 0x03d5; + t.phook = 0x01a5; + t.phophanthai = 0x0e1e; + t.phophungthai = 0x0e1c; + t.phosamphaothai = 0x0e20; + t.pi = 0x03c0; + t.pieupacirclekorean = 0x3273; + t.pieupaparenkorean = 0x3213; + t.pieupcieuckorean = 0x3176; + t.pieupcirclekorean = 0x3265; + t.pieupkiyeokkorean = 0x3172; + t.pieupkorean = 0x3142; + t.pieupparenkorean = 0x3205; + t.pieupsioskiyeokkorean = 0x3174; + t.pieupsioskorean = 0x3144; + t.pieupsiostikeutkorean = 0x3175; + t.pieupthieuthkorean = 0x3177; + t.pieuptikeutkorean = 0x3173; + t.pihiragana = 0x3074; + t.pikatakana = 0x30d4; + t.pisymbolgreek = 0x03d6; + t.piwrarmenian = 0x0583; + t.planckover2pi = 0x210f; + t.planckover2pi1 = 0x210f; + t.plus = 0x002b; + t.plusbelowcmb = 0x031f; + t.pluscircle = 0x2295; + t.plusminus = 0x00b1; + t.plusmod = 0x02d6; + t.plusmonospace = 0xff0b; + t.plussmall = 0xfe62; + t.plussuperior = 0x207a; + t.pmonospace = 0xff50; + t.pmsquare = 0x33d8; + t.pohiragana = 0x307d; + t.pointingindexdownwhite = 0x261f; + t.pointingindexleftwhite = 0x261c; + t.pointingindexrightwhite = 0x261e; + t.pointingindexupwhite = 0x261d; + t.pokatakana = 0x30dd; + t.poplathai = 0x0e1b; + t.postalmark = 0x3012; + t.postalmarkface = 0x3020; + t.pparen = 0x24ab; + t.precedes = 0x227a; + t.prescription = 0x211e; + t.primemod = 0x02b9; + t.primereversed = 0x2035; + t.product = 0x220f; + t.projective = 0x2305; + t.prolongedkana = 0x30fc; + t.propellor = 0x2318; + t.propersubset = 0x2282; + t.propersuperset = 0x2283; + t.proportion = 0x2237; + t.proportional = 0x221d; + t.psi = 0x03c8; + t.psicyrillic = 0x0471; + t.psilipneumatacyrilliccmb = 0x0486; + t.pssquare = 0x33b0; + t.puhiragana = 0x3077; + t.pukatakana = 0x30d7; + t.pvsquare = 0x33b4; + t.pwsquare = 0x33ba; + t.q = 0x0071; + t.qadeva = 0x0958; + t.qadmahebrew = 0x05a8; + t.qafarabic = 0x0642; + t.qaffinalarabic = 0xfed6; + t.qafinitialarabic = 0xfed7; + t.qafmedialarabic = 0xfed8; + t.qamats = 0x05b8; + t.qamats10 = 0x05b8; + t.qamats1a = 0x05b8; + t.qamats1c = 0x05b8; + t.qamats27 = 0x05b8; + t.qamats29 = 0x05b8; + t.qamats33 = 0x05b8; + t.qamatsde = 0x05b8; + t.qamatshebrew = 0x05b8; + t.qamatsnarrowhebrew = 0x05b8; + t.qamatsqatanhebrew = 0x05b8; + t.qamatsqatannarrowhebrew = 0x05b8; + t.qamatsqatanquarterhebrew = 0x05b8; + t.qamatsqatanwidehebrew = 0x05b8; + t.qamatsquarterhebrew = 0x05b8; + t.qamatswidehebrew = 0x05b8; + t.qarneyparahebrew = 0x059f; + t.qbopomofo = 0x3111; + t.qcircle = 0x24e0; + t.qhook = 0x02a0; + t.qmonospace = 0xff51; + t.qof = 0x05e7; + t.qofdagesh = 0xfb47; + t.qofdageshhebrew = 0xfb47; + t.qofhebrew = 0x05e7; + t.qparen = 0x24ac; + t.quarternote = 0x2669; + t.qubuts = 0x05bb; + t.qubuts18 = 0x05bb; + t.qubuts25 = 0x05bb; + t.qubuts31 = 0x05bb; + t.qubutshebrew = 0x05bb; + t.qubutsnarrowhebrew = 0x05bb; + t.qubutsquarterhebrew = 0x05bb; + t.qubutswidehebrew = 0x05bb; + t.question = 0x003f; + t.questionarabic = 0x061f; + t.questionarmenian = 0x055e; + t.questiondown = 0x00bf; + t.questiondownsmall = 0xf7bf; + t.questiongreek = 0x037e; + t.questionmonospace = 0xff1f; + t.questionsmall = 0xf73f; + t.quotedbl = 0x0022; + t.quotedblbase = 0x201e; + t.quotedblleft = 0x201c; + t.quotedblmonospace = 0xff02; + t.quotedblprime = 0x301e; + t.quotedblprimereversed = 0x301d; + t.quotedblright = 0x201d; + t.quoteleft = 0x2018; + t.quoteleftreversed = 0x201b; + t.quotereversed = 0x201b; + t.quoteright = 0x2019; + t.quoterightn = 0x0149; + t.quotesinglbase = 0x201a; + t.quotesingle = 0x0027; + t.quotesinglemonospace = 0xff07; + t.r = 0x0072; + t.raarmenian = 0x057c; + t.rabengali = 0x09b0; + t.racute = 0x0155; + t.radeva = 0x0930; + t.radical = 0x221a; + t.radicalex = 0xf8e5; + t.radoverssquare = 0x33ae; + t.radoverssquaredsquare = 0x33af; + t.radsquare = 0x33ad; + t.rafe = 0x05bf; + t.rafehebrew = 0x05bf; + t.ragujarati = 0x0ab0; + t.ragurmukhi = 0x0a30; + t.rahiragana = 0x3089; + t.rakatakana = 0x30e9; + t.rakatakanahalfwidth = 0xff97; + t.ralowerdiagonalbengali = 0x09f1; + t.ramiddlediagonalbengali = 0x09f0; + t.ramshorn = 0x0264; + t.ratio = 0x2236; + t.rbopomofo = 0x3116; + t.rcaron = 0x0159; + t.rcedilla = 0x0157; + t.rcircle = 0x24e1; + t.rcommaaccent = 0x0157; + t.rdblgrave = 0x0211; + t.rdotaccent = 0x1e59; + t.rdotbelow = 0x1e5b; + t.rdotbelowmacron = 0x1e5d; + t.referencemark = 0x203b; + t.reflexsubset = 0x2286; + t.reflexsuperset = 0x2287; + t.registered = 0x00ae; + t.registersans = 0xf8e8; + t.registerserif = 0xf6da; + t.reharabic = 0x0631; + t.reharmenian = 0x0580; + t.rehfinalarabic = 0xfeae; + t.rehiragana = 0x308c; + t.rekatakana = 0x30ec; + t.rekatakanahalfwidth = 0xff9a; + t.resh = 0x05e8; + t.reshdageshhebrew = 0xfb48; + t.reshhebrew = 0x05e8; + t.reversedtilde = 0x223d; + t.reviahebrew = 0x0597; + t.reviamugrashhebrew = 0x0597; + t.revlogicalnot = 0x2310; + t.rfishhook = 0x027e; + t.rfishhookreversed = 0x027f; + t.rhabengali = 0x09dd; + t.rhadeva = 0x095d; + t.rho = 0x03c1; + t.rhook = 0x027d; + t.rhookturned = 0x027b; + t.rhookturnedsuperior = 0x02b5; + t.rhosymbolgreek = 0x03f1; + t.rhotichookmod = 0x02de; + t.rieulacirclekorean = 0x3271; + t.rieulaparenkorean = 0x3211; + t.rieulcirclekorean = 0x3263; + t.rieulhieuhkorean = 0x3140; + t.rieulkiyeokkorean = 0x313a; + t.rieulkiyeoksioskorean = 0x3169; + t.rieulkorean = 0x3139; + t.rieulmieumkorean = 0x313b; + t.rieulpansioskorean = 0x316c; + t.rieulparenkorean = 0x3203; + t.rieulphieuphkorean = 0x313f; + t.rieulpieupkorean = 0x313c; + t.rieulpieupsioskorean = 0x316b; + t.rieulsioskorean = 0x313d; + t.rieulthieuthkorean = 0x313e; + t.rieultikeutkorean = 0x316a; + t.rieulyeorinhieuhkorean = 0x316d; + t.rightangle = 0x221f; + t.righttackbelowcmb = 0x0319; + t.righttriangle = 0x22bf; + t.rihiragana = 0x308a; + t.rikatakana = 0x30ea; + t.rikatakanahalfwidth = 0xff98; + t.ring = 0x02da; + t.ringbelowcmb = 0x0325; + t.ringcmb = 0x030a; + t.ringhalfleft = 0x02bf; + t.ringhalfleftarmenian = 0x0559; + t.ringhalfleftbelowcmb = 0x031c; + t.ringhalfleftcentered = 0x02d3; + t.ringhalfright = 0x02be; + t.ringhalfrightbelowcmb = 0x0339; + t.ringhalfrightcentered = 0x02d2; + t.rinvertedbreve = 0x0213; + t.rittorusquare = 0x3351; + t.rlinebelow = 0x1e5f; + t.rlongleg = 0x027c; + t.rlonglegturned = 0x027a; + t.rmonospace = 0xff52; + t.rohiragana = 0x308d; + t.rokatakana = 0x30ed; + t.rokatakanahalfwidth = 0xff9b; + t.roruathai = 0x0e23; + t.rparen = 0x24ad; + t.rrabengali = 0x09dc; + t.rradeva = 0x0931; + t.rragurmukhi = 0x0a5c; + t.rreharabic = 0x0691; + t.rrehfinalarabic = 0xfb8d; + t.rrvocalicbengali = 0x09e0; + t.rrvocalicdeva = 0x0960; + t.rrvocalicgujarati = 0x0ae0; + t.rrvocalicvowelsignbengali = 0x09c4; + t.rrvocalicvowelsigndeva = 0x0944; + t.rrvocalicvowelsigngujarati = 0x0ac4; + t.rsuperior = 0xf6f1; + t.rtblock = 0x2590; + t.rturned = 0x0279; + t.rturnedsuperior = 0x02b4; + t.ruhiragana = 0x308b; + t.rukatakana = 0x30eb; + t.rukatakanahalfwidth = 0xff99; + t.rupeemarkbengali = 0x09f2; + t.rupeesignbengali = 0x09f3; + t.rupiah = 0xf6dd; + t.ruthai = 0x0e24; + t.rvocalicbengali = 0x098b; + t.rvocalicdeva = 0x090b; + t.rvocalicgujarati = 0x0a8b; + t.rvocalicvowelsignbengali = 0x09c3; + t.rvocalicvowelsigndeva = 0x0943; + t.rvocalicvowelsigngujarati = 0x0ac3; + t.s = 0x0073; + t.sabengali = 0x09b8; + t.sacute = 0x015b; + t.sacutedotaccent = 0x1e65; + t.sadarabic = 0x0635; + t.sadeva = 0x0938; + t.sadfinalarabic = 0xfeba; + t.sadinitialarabic = 0xfebb; + t.sadmedialarabic = 0xfebc; + t.sagujarati = 0x0ab8; + t.sagurmukhi = 0x0a38; + t.sahiragana = 0x3055; + t.sakatakana = 0x30b5; + t.sakatakanahalfwidth = 0xff7b; + t.sallallahoualayhewasallamarabic = 0xfdfa; + t.samekh = 0x05e1; + t.samekhdagesh = 0xfb41; + t.samekhdageshhebrew = 0xfb41; + t.samekhhebrew = 0x05e1; + t.saraaathai = 0x0e32; + t.saraaethai = 0x0e41; + t.saraaimaimalaithai = 0x0e44; + t.saraaimaimuanthai = 0x0e43; + t.saraamthai = 0x0e33; + t.saraathai = 0x0e30; + t.saraethai = 0x0e40; + t.saraiileftthai = 0xf886; + t.saraiithai = 0x0e35; + t.saraileftthai = 0xf885; + t.saraithai = 0x0e34; + t.saraothai = 0x0e42; + t.saraueeleftthai = 0xf888; + t.saraueethai = 0x0e37; + t.saraueleftthai = 0xf887; + t.sarauethai = 0x0e36; + t.sarauthai = 0x0e38; + t.sarauuthai = 0x0e39; + t.sbopomofo = 0x3119; + t.scaron = 0x0161; + t.scarondotaccent = 0x1e67; + t.scedilla = 0x015f; + t.schwa = 0x0259; + t.schwacyrillic = 0x04d9; + t.schwadieresiscyrillic = 0x04db; + t.schwahook = 0x025a; + t.scircle = 0x24e2; + t.scircumflex = 0x015d; + t.scommaaccent = 0x0219; + t.sdotaccent = 0x1e61; + t.sdotbelow = 0x1e63; + t.sdotbelowdotaccent = 0x1e69; + t.seagullbelowcmb = 0x033c; + t.second = 0x2033; + t.secondtonechinese = 0x02ca; + t.section = 0x00a7; + t.seenarabic = 0x0633; + t.seenfinalarabic = 0xfeb2; + t.seeninitialarabic = 0xfeb3; + t.seenmedialarabic = 0xfeb4; + t.segol = 0x05b6; + t.segol13 = 0x05b6; + t.segol1f = 0x05b6; + t.segol2c = 0x05b6; + t.segolhebrew = 0x05b6; + t.segolnarrowhebrew = 0x05b6; + t.segolquarterhebrew = 0x05b6; + t.segoltahebrew = 0x0592; + t.segolwidehebrew = 0x05b6; + t.seharmenian = 0x057d; + t.sehiragana = 0x305b; + t.sekatakana = 0x30bb; + t.sekatakanahalfwidth = 0xff7e; + t.semicolon = 0x003b; + t.semicolonarabic = 0x061b; + t.semicolonmonospace = 0xff1b; + t.semicolonsmall = 0xfe54; + t.semivoicedmarkkana = 0x309c; + t.semivoicedmarkkanahalfwidth = 0xff9f; + t.sentisquare = 0x3322; + t.sentosquare = 0x3323; + t.seven = 0x0037; + t.sevenarabic = 0x0667; + t.sevenbengali = 0x09ed; + t.sevencircle = 0x2466; + t.sevencircleinversesansserif = 0x2790; + t.sevendeva = 0x096d; + t.seveneighths = 0x215e; + t.sevengujarati = 0x0aed; + t.sevengurmukhi = 0x0a6d; + t.sevenhackarabic = 0x0667; + t.sevenhangzhou = 0x3027; + t.sevenideographicparen = 0x3226; + t.seveninferior = 0x2087; + t.sevenmonospace = 0xff17; + t.sevenoldstyle = 0xf737; + t.sevenparen = 0x247a; + t.sevenperiod = 0x248e; + t.sevenpersian = 0x06f7; + t.sevenroman = 0x2176; + t.sevensuperior = 0x2077; + t.seventeencircle = 0x2470; + t.seventeenparen = 0x2484; + t.seventeenperiod = 0x2498; + t.seventhai = 0x0e57; + t.sfthyphen = 0x00ad; + t.shaarmenian = 0x0577; + t.shabengali = 0x09b6; + t.shacyrillic = 0x0448; + t.shaddaarabic = 0x0651; + t.shaddadammaarabic = 0xfc61; + t.shaddadammatanarabic = 0xfc5e; + t.shaddafathaarabic = 0xfc60; + t.shaddakasraarabic = 0xfc62; + t.shaddakasratanarabic = 0xfc5f; + t.shade = 0x2592; + t.shadedark = 0x2593; + t.shadelight = 0x2591; + t.shademedium = 0x2592; + t.shadeva = 0x0936; + t.shagujarati = 0x0ab6; + t.shagurmukhi = 0x0a36; + t.shalshelethebrew = 0x0593; + t.shbopomofo = 0x3115; + t.shchacyrillic = 0x0449; + t.sheenarabic = 0x0634; + t.sheenfinalarabic = 0xfeb6; + t.sheeninitialarabic = 0xfeb7; + t.sheenmedialarabic = 0xfeb8; + t.sheicoptic = 0x03e3; + t.sheqel = 0x20aa; + t.sheqelhebrew = 0x20aa; + t.sheva = 0x05b0; + t.sheva115 = 0x05b0; + t.sheva15 = 0x05b0; + t.sheva22 = 0x05b0; + t.sheva2e = 0x05b0; + t.shevahebrew = 0x05b0; + t.shevanarrowhebrew = 0x05b0; + t.shevaquarterhebrew = 0x05b0; + t.shevawidehebrew = 0x05b0; + t.shhacyrillic = 0x04bb; + t.shimacoptic = 0x03ed; + t.shin = 0x05e9; + t.shindagesh = 0xfb49; + t.shindageshhebrew = 0xfb49; + t.shindageshshindot = 0xfb2c; + t.shindageshshindothebrew = 0xfb2c; + t.shindageshsindot = 0xfb2d; + t.shindageshsindothebrew = 0xfb2d; + t.shindothebrew = 0x05c1; + t.shinhebrew = 0x05e9; + t.shinshindot = 0xfb2a; + t.shinshindothebrew = 0xfb2a; + t.shinsindot = 0xfb2b; + t.shinsindothebrew = 0xfb2b; + t.shook = 0x0282; + t.sigma = 0x03c3; + t.sigma1 = 0x03c2; + t.sigmafinal = 0x03c2; + t.sigmalunatesymbolgreek = 0x03f2; + t.sihiragana = 0x3057; + t.sikatakana = 0x30b7; + t.sikatakanahalfwidth = 0xff7c; + t.siluqhebrew = 0x05bd; + t.siluqlefthebrew = 0x05bd; + t.similar = 0x223c; + t.sindothebrew = 0x05c2; + t.siosacirclekorean = 0x3274; + t.siosaparenkorean = 0x3214; + t.sioscieuckorean = 0x317e; + t.sioscirclekorean = 0x3266; + t.sioskiyeokkorean = 0x317a; + t.sioskorean = 0x3145; + t.siosnieunkorean = 0x317b; + t.siosparenkorean = 0x3206; + t.siospieupkorean = 0x317d; + t.siostikeutkorean = 0x317c; + t.six = 0x0036; + t.sixarabic = 0x0666; + t.sixbengali = 0x09ec; + t.sixcircle = 0x2465; + t.sixcircleinversesansserif = 0x278f; + t.sixdeva = 0x096c; + t.sixgujarati = 0x0aec; + t.sixgurmukhi = 0x0a6c; + t.sixhackarabic = 0x0666; + t.sixhangzhou = 0x3026; + t.sixideographicparen = 0x3225; + t.sixinferior = 0x2086; + t.sixmonospace = 0xff16; + t.sixoldstyle = 0xf736; + t.sixparen = 0x2479; + t.sixperiod = 0x248d; + t.sixpersian = 0x06f6; + t.sixroman = 0x2175; + t.sixsuperior = 0x2076; + t.sixteencircle = 0x246f; + t.sixteencurrencydenominatorbengali = 0x09f9; + t.sixteenparen = 0x2483; + t.sixteenperiod = 0x2497; + t.sixthai = 0x0e56; + t.slash = 0x002f; + t.slashmonospace = 0xff0f; + t.slong = 0x017f; + t.slongdotaccent = 0x1e9b; + t.smileface = 0x263a; + t.smonospace = 0xff53; + t.sofpasuqhebrew = 0x05c3; + t.softhyphen = 0x00ad; + t.softsigncyrillic = 0x044c; + t.sohiragana = 0x305d; + t.sokatakana = 0x30bd; + t.sokatakanahalfwidth = 0xff7f; + t.soliduslongoverlaycmb = 0x0338; + t.solidusshortoverlaycmb = 0x0337; + t.sorusithai = 0x0e29; + t.sosalathai = 0x0e28; + t.sosothai = 0x0e0b; + t.sosuathai = 0x0e2a; + t.space = 0x0020; + t.spacehackarabic = 0x0020; + t.spade = 0x2660; + t.spadesuitblack = 0x2660; + t.spadesuitwhite = 0x2664; + t.sparen = 0x24ae; + t.squarebelowcmb = 0x033b; + t.squarecc = 0x33c4; + t.squarecm = 0x339d; + t.squarediagonalcrosshatchfill = 0x25a9; + t.squarehorizontalfill = 0x25a4; + t.squarekg = 0x338f; + t.squarekm = 0x339e; + t.squarekmcapital = 0x33ce; + t.squareln = 0x33d1; + t.squarelog = 0x33d2; + t.squaremg = 0x338e; + t.squaremil = 0x33d5; + t.squaremm = 0x339c; + t.squaremsquared = 0x33a1; + t.squareorthogonalcrosshatchfill = 0x25a6; + t.squareupperlefttolowerrightfill = 0x25a7; + t.squareupperrighttolowerleftfill = 0x25a8; + t.squareverticalfill = 0x25a5; + t.squarewhitewithsmallblack = 0x25a3; + t.srsquare = 0x33db; + t.ssabengali = 0x09b7; + t.ssadeva = 0x0937; + t.ssagujarati = 0x0ab7; + t.ssangcieuckorean = 0x3149; + t.ssanghieuhkorean = 0x3185; + t.ssangieungkorean = 0x3180; + t.ssangkiyeokkorean = 0x3132; + t.ssangnieunkorean = 0x3165; + t.ssangpieupkorean = 0x3143; + t.ssangsioskorean = 0x3146; + t.ssangtikeutkorean = 0x3138; + t.ssuperior = 0xf6f2; + t.sterling = 0x00a3; + t.sterlingmonospace = 0xffe1; + t.strokelongoverlaycmb = 0x0336; + t.strokeshortoverlaycmb = 0x0335; + t.subset = 0x2282; + t.subsetnotequal = 0x228a; + t.subsetorequal = 0x2286; + t.succeeds = 0x227b; + t.suchthat = 0x220b; + t.suhiragana = 0x3059; + t.sukatakana = 0x30b9; + t.sukatakanahalfwidth = 0xff7d; + t.sukunarabic = 0x0652; + t.summation = 0x2211; + t.sun = 0x263c; + t.superset = 0x2283; + t.supersetnotequal = 0x228b; + t.supersetorequal = 0x2287; + t.svsquare = 0x33dc; + t.syouwaerasquare = 0x337c; + t.t = 0x0074; + t.tabengali = 0x09a4; + t.tackdown = 0x22a4; + t.tackleft = 0x22a3; + t.tadeva = 0x0924; + t.tagujarati = 0x0aa4; + t.tagurmukhi = 0x0a24; + t.taharabic = 0x0637; + t.tahfinalarabic = 0xfec2; + t.tahinitialarabic = 0xfec3; + t.tahiragana = 0x305f; + t.tahmedialarabic = 0xfec4; + t.taisyouerasquare = 0x337d; + t.takatakana = 0x30bf; + t.takatakanahalfwidth = 0xff80; + t.tatweelarabic = 0x0640; + t.tau = 0x03c4; + t.tav = 0x05ea; + t.tavdages = 0xfb4a; + t.tavdagesh = 0xfb4a; + t.tavdageshhebrew = 0xfb4a; + t.tavhebrew = 0x05ea; + t.tbar = 0x0167; + t.tbopomofo = 0x310a; + t.tcaron = 0x0165; + t.tccurl = 0x02a8; + t.tcedilla = 0x0163; + t.tcheharabic = 0x0686; + t.tchehfinalarabic = 0xfb7b; + t.tchehinitialarabic = 0xfb7c; + t.tchehmedialarabic = 0xfb7d; + t.tcircle = 0x24e3; + t.tcircumflexbelow = 0x1e71; + t.tcommaaccent = 0x0163; + t.tdieresis = 0x1e97; + t.tdotaccent = 0x1e6b; + t.tdotbelow = 0x1e6d; + t.tecyrillic = 0x0442; + t.tedescendercyrillic = 0x04ad; + t.teharabic = 0x062a; + t.tehfinalarabic = 0xfe96; + t.tehhahinitialarabic = 0xfca2; + t.tehhahisolatedarabic = 0xfc0c; + t.tehinitialarabic = 0xfe97; + t.tehiragana = 0x3066; + t.tehjeeminitialarabic = 0xfca1; + t.tehjeemisolatedarabic = 0xfc0b; + t.tehmarbutaarabic = 0x0629; + t.tehmarbutafinalarabic = 0xfe94; + t.tehmedialarabic = 0xfe98; + t.tehmeeminitialarabic = 0xfca4; + t.tehmeemisolatedarabic = 0xfc0e; + t.tehnoonfinalarabic = 0xfc73; + t.tekatakana = 0x30c6; + t.tekatakanahalfwidth = 0xff83; + t.telephone = 0x2121; + t.telephoneblack = 0x260e; + t.telishagedolahebrew = 0x05a0; + t.telishaqetanahebrew = 0x05a9; + t.tencircle = 0x2469; + t.tenideographicparen = 0x3229; + t.tenparen = 0x247d; + t.tenperiod = 0x2491; + t.tenroman = 0x2179; + t.tesh = 0x02a7; + t.tet = 0x05d8; + t.tetdagesh = 0xfb38; + t.tetdageshhebrew = 0xfb38; + t.tethebrew = 0x05d8; + t.tetsecyrillic = 0x04b5; + t.tevirhebrew = 0x059b; + t.tevirlefthebrew = 0x059b; + t.thabengali = 0x09a5; + t.thadeva = 0x0925; + t.thagujarati = 0x0aa5; + t.thagurmukhi = 0x0a25; + t.thalarabic = 0x0630; + t.thalfinalarabic = 0xfeac; + t.thanthakhatlowleftthai = 0xf898; + t.thanthakhatlowrightthai = 0xf897; + t.thanthakhatthai = 0x0e4c; + t.thanthakhatupperleftthai = 0xf896; + t.theharabic = 0x062b; + t.thehfinalarabic = 0xfe9a; + t.thehinitialarabic = 0xfe9b; + t.thehmedialarabic = 0xfe9c; + t.thereexists = 0x2203; + t.therefore = 0x2234; + t.theta = 0x03b8; + t.theta1 = 0x03d1; + t.thetasymbolgreek = 0x03d1; + t.thieuthacirclekorean = 0x3279; + t.thieuthaparenkorean = 0x3219; + t.thieuthcirclekorean = 0x326b; + t.thieuthkorean = 0x314c; + t.thieuthparenkorean = 0x320b; + t.thirteencircle = 0x246c; + t.thirteenparen = 0x2480; + t.thirteenperiod = 0x2494; + t.thonangmonthothai = 0x0e11; + t.thook = 0x01ad; + t.thophuthaothai = 0x0e12; + t.thorn = 0x00fe; + t.thothahanthai = 0x0e17; + t.thothanthai = 0x0e10; + t.thothongthai = 0x0e18; + t.thothungthai = 0x0e16; + t.thousandcyrillic = 0x0482; + t.thousandsseparatorarabic = 0x066c; + t.thousandsseparatorpersian = 0x066c; + t.three = 0x0033; + t.threearabic = 0x0663; + t.threebengali = 0x09e9; + t.threecircle = 0x2462; + t.threecircleinversesansserif = 0x278c; + t.threedeva = 0x0969; + t.threeeighths = 0x215c; + t.threegujarati = 0x0ae9; + t.threegurmukhi = 0x0a69; + t.threehackarabic = 0x0663; + t.threehangzhou = 0x3023; + t.threeideographicparen = 0x3222; + t.threeinferior = 0x2083; + t.threemonospace = 0xff13; + t.threenumeratorbengali = 0x09f6; + t.threeoldstyle = 0xf733; + t.threeparen = 0x2476; + t.threeperiod = 0x248a; + t.threepersian = 0x06f3; + t.threequarters = 0x00be; + t.threequartersemdash = 0xf6de; + t.threeroman = 0x2172; + t.threesuperior = 0x00b3; + t.threethai = 0x0e53; + t.thzsquare = 0x3394; + t.tihiragana = 0x3061; + t.tikatakana = 0x30c1; + t.tikatakanahalfwidth = 0xff81; + t.tikeutacirclekorean = 0x3270; + t.tikeutaparenkorean = 0x3210; + t.tikeutcirclekorean = 0x3262; + t.tikeutkorean = 0x3137; + t.tikeutparenkorean = 0x3202; + t.tilde = 0x02dc; + t.tildebelowcmb = 0x0330; + t.tildecmb = 0x0303; + t.tildecomb = 0x0303; + t.tildedoublecmb = 0x0360; + t.tildeoperator = 0x223c; + t.tildeoverlaycmb = 0x0334; + t.tildeverticalcmb = 0x033e; + t.timescircle = 0x2297; + t.tipehahebrew = 0x0596; + t.tipehalefthebrew = 0x0596; + t.tippigurmukhi = 0x0a70; + t.titlocyrilliccmb = 0x0483; + t.tiwnarmenian = 0x057f; + t.tlinebelow = 0x1e6f; + t.tmonospace = 0xff54; + t.toarmenian = 0x0569; + t.tohiragana = 0x3068; + t.tokatakana = 0x30c8; + t.tokatakanahalfwidth = 0xff84; + t.tonebarextrahighmod = 0x02e5; + t.tonebarextralowmod = 0x02e9; + t.tonebarhighmod = 0x02e6; + t.tonebarlowmod = 0x02e8; + t.tonebarmidmod = 0x02e7; + t.tonefive = 0x01bd; + t.tonesix = 0x0185; + t.tonetwo = 0x01a8; + t.tonos = 0x0384; + t.tonsquare = 0x3327; + t.topatakthai = 0x0e0f; + t.tortoiseshellbracketleft = 0x3014; + t.tortoiseshellbracketleftsmall = 0xfe5d; + t.tortoiseshellbracketleftvertical = 0xfe39; + t.tortoiseshellbracketright = 0x3015; + t.tortoiseshellbracketrightsmall = 0xfe5e; + t.tortoiseshellbracketrightvertical = 0xfe3a; + t.totaothai = 0x0e15; + t.tpalatalhook = 0x01ab; + t.tparen = 0x24af; + t.trademark = 0x2122; + t.trademarksans = 0xf8ea; + t.trademarkserif = 0xf6db; + t.tretroflexhook = 0x0288; + t.triagdn = 0x25bc; + t.triaglf = 0x25c4; + t.triagrt = 0x25ba; + t.triagup = 0x25b2; + t.ts = 0x02a6; + t.tsadi = 0x05e6; + t.tsadidagesh = 0xfb46; + t.tsadidageshhebrew = 0xfb46; + t.tsadihebrew = 0x05e6; + t.tsecyrillic = 0x0446; + t.tsere = 0x05b5; + t.tsere12 = 0x05b5; + t.tsere1e = 0x05b5; + t.tsere2b = 0x05b5; + t.tserehebrew = 0x05b5; + t.tserenarrowhebrew = 0x05b5; + t.tserequarterhebrew = 0x05b5; + t.tserewidehebrew = 0x05b5; + t.tshecyrillic = 0x045b; + t.tsuperior = 0xf6f3; + t.ttabengali = 0x099f; + t.ttadeva = 0x091f; + t.ttagujarati = 0x0a9f; + t.ttagurmukhi = 0x0a1f; + t.tteharabic = 0x0679; + t.ttehfinalarabic = 0xfb67; + t.ttehinitialarabic = 0xfb68; + t.ttehmedialarabic = 0xfb69; + t.tthabengali = 0x09a0; + t.tthadeva = 0x0920; + t.tthagujarati = 0x0aa0; + t.tthagurmukhi = 0x0a20; + t.tturned = 0x0287; + t.tuhiragana = 0x3064; + t.tukatakana = 0x30c4; + t.tukatakanahalfwidth = 0xff82; + t.tusmallhiragana = 0x3063; + t.tusmallkatakana = 0x30c3; + t.tusmallkatakanahalfwidth = 0xff6f; + t.twelvecircle = 0x246b; + t.twelveparen = 0x247f; + t.twelveperiod = 0x2493; + t.twelveroman = 0x217b; + t.twentycircle = 0x2473; + t.twentyhangzhou = 0x5344; + t.twentyparen = 0x2487; + t.twentyperiod = 0x249b; + t.two = 0x0032; + t.twoarabic = 0x0662; + t.twobengali = 0x09e8; + t.twocircle = 0x2461; + t.twocircleinversesansserif = 0x278b; + t.twodeva = 0x0968; + t.twodotenleader = 0x2025; + t.twodotleader = 0x2025; + t.twodotleadervertical = 0xfe30; + t.twogujarati = 0x0ae8; + t.twogurmukhi = 0x0a68; + t.twohackarabic = 0x0662; + t.twohangzhou = 0x3022; + t.twoideographicparen = 0x3221; + t.twoinferior = 0x2082; + t.twomonospace = 0xff12; + t.twonumeratorbengali = 0x09f5; + t.twooldstyle = 0xf732; + t.twoparen = 0x2475; + t.twoperiod = 0x2489; + t.twopersian = 0x06f2; + t.tworoman = 0x2171; + t.twostroke = 0x01bb; + t.twosuperior = 0x00b2; + t.twothai = 0x0e52; + t.twothirds = 0x2154; + t.u = 0x0075; + t.uacute = 0x00fa; + t.ubar = 0x0289; + t.ubengali = 0x0989; + t.ubopomofo = 0x3128; + t.ubreve = 0x016d; + t.ucaron = 0x01d4; + t.ucircle = 0x24e4; + t.ucircumflex = 0x00fb; + t.ucircumflexbelow = 0x1e77; + t.ucyrillic = 0x0443; + t.udattadeva = 0x0951; + t.udblacute = 0x0171; + t.udblgrave = 0x0215; + t.udeva = 0x0909; + t.udieresis = 0x00fc; + t.udieresisacute = 0x01d8; + t.udieresisbelow = 0x1e73; + t.udieresiscaron = 0x01da; + t.udieresiscyrillic = 0x04f1; + t.udieresisgrave = 0x01dc; + t.udieresismacron = 0x01d6; + t.udotbelow = 0x1ee5; + t.ugrave = 0x00f9; + t.ugujarati = 0x0a89; + t.ugurmukhi = 0x0a09; + t.uhiragana = 0x3046; + t.uhookabove = 0x1ee7; + t.uhorn = 0x01b0; + t.uhornacute = 0x1ee9; + t.uhorndotbelow = 0x1ef1; + t.uhorngrave = 0x1eeb; + t.uhornhookabove = 0x1eed; + t.uhorntilde = 0x1eef; + t.uhungarumlaut = 0x0171; + t.uhungarumlautcyrillic = 0x04f3; + t.uinvertedbreve = 0x0217; + t.ukatakana = 0x30a6; + t.ukatakanahalfwidth = 0xff73; + t.ukcyrillic = 0x0479; + t.ukorean = 0x315c; + t.umacron = 0x016b; + t.umacroncyrillic = 0x04ef; + t.umacrondieresis = 0x1e7b; + t.umatragurmukhi = 0x0a41; + t.umonospace = 0xff55; + t.underscore = 0x005f; + t.underscoredbl = 0x2017; + t.underscoremonospace = 0xff3f; + t.underscorevertical = 0xfe33; + t.underscorewavy = 0xfe4f; + t.union = 0x222a; + t.universal = 0x2200; + t.uogonek = 0x0173; + t.uparen = 0x24b0; + t.upblock = 0x2580; + t.upperdothebrew = 0x05c4; + t.upsilon = 0x03c5; + t.upsilondieresis = 0x03cb; + t.upsilondieresistonos = 0x03b0; + t.upsilonlatin = 0x028a; + t.upsilontonos = 0x03cd; + t.uptackbelowcmb = 0x031d; + t.uptackmod = 0x02d4; + t.uragurmukhi = 0x0a73; + t.uring = 0x016f; + t.ushortcyrillic = 0x045e; + t.usmallhiragana = 0x3045; + t.usmallkatakana = 0x30a5; + t.usmallkatakanahalfwidth = 0xff69; + t.ustraightcyrillic = 0x04af; + t.ustraightstrokecyrillic = 0x04b1; + t.utilde = 0x0169; + t.utildeacute = 0x1e79; + t.utildebelow = 0x1e75; + t.uubengali = 0x098a; + t.uudeva = 0x090a; + t.uugujarati = 0x0a8a; + t.uugurmukhi = 0x0a0a; + t.uumatragurmukhi = 0x0a42; + t.uuvowelsignbengali = 0x09c2; + t.uuvowelsigndeva = 0x0942; + t.uuvowelsigngujarati = 0x0ac2; + t.uvowelsignbengali = 0x09c1; + t.uvowelsigndeva = 0x0941; + t.uvowelsigngujarati = 0x0ac1; + t.v = 0x0076; + t.vadeva = 0x0935; + t.vagujarati = 0x0ab5; + t.vagurmukhi = 0x0a35; + t.vakatakana = 0x30f7; + t.vav = 0x05d5; + t.vavdagesh = 0xfb35; + t.vavdagesh65 = 0xfb35; + t.vavdageshhebrew = 0xfb35; + t.vavhebrew = 0x05d5; + t.vavholam = 0xfb4b; + t.vavholamhebrew = 0xfb4b; + t.vavvavhebrew = 0x05f0; + t.vavyodhebrew = 0x05f1; + t.vcircle = 0x24e5; + t.vdotbelow = 0x1e7f; + t.vecyrillic = 0x0432; + t.veharabic = 0x06a4; + t.vehfinalarabic = 0xfb6b; + t.vehinitialarabic = 0xfb6c; + t.vehmedialarabic = 0xfb6d; + t.vekatakana = 0x30f9; + t.venus = 0x2640; + t.verticalbar = 0x007c; + t.verticallineabovecmb = 0x030d; + t.verticallinebelowcmb = 0x0329; + t.verticallinelowmod = 0x02cc; + t.verticallinemod = 0x02c8; + t.vewarmenian = 0x057e; + t.vhook = 0x028b; + t.vikatakana = 0x30f8; + t.viramabengali = 0x09cd; + t.viramadeva = 0x094d; + t.viramagujarati = 0x0acd; + t.visargabengali = 0x0983; + t.visargadeva = 0x0903; + t.visargagujarati = 0x0a83; + t.vmonospace = 0xff56; + t.voarmenian = 0x0578; + t.voicediterationhiragana = 0x309e; + t.voicediterationkatakana = 0x30fe; + t.voicedmarkkana = 0x309b; + t.voicedmarkkanahalfwidth = 0xff9e; + t.vokatakana = 0x30fa; + t.vparen = 0x24b1; + t.vtilde = 0x1e7d; + t.vturned = 0x028c; + t.vuhiragana = 0x3094; + t.vukatakana = 0x30f4; + t.w = 0x0077; + t.wacute = 0x1e83; + t.waekorean = 0x3159; + t.wahiragana = 0x308f; + t.wakatakana = 0x30ef; + t.wakatakanahalfwidth = 0xff9c; + t.wakorean = 0x3158; + t.wasmallhiragana = 0x308e; + t.wasmallkatakana = 0x30ee; + t.wattosquare = 0x3357; + t.wavedash = 0x301c; + t.wavyunderscorevertical = 0xfe34; + t.wawarabic = 0x0648; + t.wawfinalarabic = 0xfeee; + t.wawhamzaabovearabic = 0x0624; + t.wawhamzaabovefinalarabic = 0xfe86; + t.wbsquare = 0x33dd; + t.wcircle = 0x24e6; + t.wcircumflex = 0x0175; + t.wdieresis = 0x1e85; + t.wdotaccent = 0x1e87; + t.wdotbelow = 0x1e89; + t.wehiragana = 0x3091; + t.weierstrass = 0x2118; + t.wekatakana = 0x30f1; + t.wekorean = 0x315e; + t.weokorean = 0x315d; + t.wgrave = 0x1e81; + t.whitebullet = 0x25e6; + t.whitecircle = 0x25cb; + t.whitecircleinverse = 0x25d9; + t.whitecornerbracketleft = 0x300e; + t.whitecornerbracketleftvertical = 0xfe43; + t.whitecornerbracketright = 0x300f; + t.whitecornerbracketrightvertical = 0xfe44; + t.whitediamond = 0x25c7; + t.whitediamondcontainingblacksmalldiamond = 0x25c8; + t.whitedownpointingsmalltriangle = 0x25bf; + t.whitedownpointingtriangle = 0x25bd; + t.whiteleftpointingsmalltriangle = 0x25c3; + t.whiteleftpointingtriangle = 0x25c1; + t.whitelenticularbracketleft = 0x3016; + t.whitelenticularbracketright = 0x3017; + t.whiterightpointingsmalltriangle = 0x25b9; + t.whiterightpointingtriangle = 0x25b7; + t.whitesmallsquare = 0x25ab; + t.whitesmilingface = 0x263a; + t.whitesquare = 0x25a1; + t.whitestar = 0x2606; + t.whitetelephone = 0x260f; + t.whitetortoiseshellbracketleft = 0x3018; + t.whitetortoiseshellbracketright = 0x3019; + t.whiteuppointingsmalltriangle = 0x25b5; + t.whiteuppointingtriangle = 0x25b3; + t.wihiragana = 0x3090; + t.wikatakana = 0x30f0; + t.wikorean = 0x315f; + t.wmonospace = 0xff57; + t.wohiragana = 0x3092; + t.wokatakana = 0x30f2; + t.wokatakanahalfwidth = 0xff66; + t.won = 0x20a9; + t.wonmonospace = 0xffe6; + t.wowaenthai = 0x0e27; + t.wparen = 0x24b2; + t.wring = 0x1e98; + t.wsuperior = 0x02b7; + t.wturned = 0x028d; + t.wynn = 0x01bf; + t.x = 0x0078; + t.xabovecmb = 0x033d; + t.xbopomofo = 0x3112; + t.xcircle = 0x24e7; + t.xdieresis = 0x1e8d; + t.xdotaccent = 0x1e8b; + t.xeharmenian = 0x056d; + t.xi = 0x03be; + t.xmonospace = 0xff58; + t.xparen = 0x24b3; + t.xsuperior = 0x02e3; + t.y = 0x0079; + t.yaadosquare = 0x334e; + t.yabengali = 0x09af; + t.yacute = 0x00fd; + t.yadeva = 0x092f; + t.yaekorean = 0x3152; + t.yagujarati = 0x0aaf; + t.yagurmukhi = 0x0a2f; + t.yahiragana = 0x3084; + t.yakatakana = 0x30e4; + t.yakatakanahalfwidth = 0xff94; + t.yakorean = 0x3151; + t.yamakkanthai = 0x0e4e; + t.yasmallhiragana = 0x3083; + t.yasmallkatakana = 0x30e3; + t.yasmallkatakanahalfwidth = 0xff6c; + t.yatcyrillic = 0x0463; + t.ycircle = 0x24e8; + t.ycircumflex = 0x0177; + t.ydieresis = 0x00ff; + t.ydotaccent = 0x1e8f; + t.ydotbelow = 0x1ef5; + t.yeharabic = 0x064a; + t.yehbarreearabic = 0x06d2; + t.yehbarreefinalarabic = 0xfbaf; + t.yehfinalarabic = 0xfef2; + t.yehhamzaabovearabic = 0x0626; + t.yehhamzaabovefinalarabic = 0xfe8a; + t.yehhamzaaboveinitialarabic = 0xfe8b; + t.yehhamzaabovemedialarabic = 0xfe8c; + t.yehinitialarabic = 0xfef3; + t.yehmedialarabic = 0xfef4; + t.yehmeeminitialarabic = 0xfcdd; + t.yehmeemisolatedarabic = 0xfc58; + t.yehnoonfinalarabic = 0xfc94; + t.yehthreedotsbelowarabic = 0x06d1; + t.yekorean = 0x3156; + t.yen = 0x00a5; + t.yenmonospace = 0xffe5; + t.yeokorean = 0x3155; + t.yeorinhieuhkorean = 0x3186; + t.yerahbenyomohebrew = 0x05aa; + t.yerahbenyomolefthebrew = 0x05aa; + t.yericyrillic = 0x044b; + t.yerudieresiscyrillic = 0x04f9; + t.yesieungkorean = 0x3181; + t.yesieungpansioskorean = 0x3183; + t.yesieungsioskorean = 0x3182; + t.yetivhebrew = 0x059a; + t.ygrave = 0x1ef3; + t.yhook = 0x01b4; + t.yhookabove = 0x1ef7; + t.yiarmenian = 0x0575; + t.yicyrillic = 0x0457; + t.yikorean = 0x3162; + t.yinyang = 0x262f; + t.yiwnarmenian = 0x0582; + t.ymonospace = 0xff59; + t.yod = 0x05d9; + t.yoddagesh = 0xfb39; + t.yoddageshhebrew = 0xfb39; + t.yodhebrew = 0x05d9; + t.yodyodhebrew = 0x05f2; + t.yodyodpatahhebrew = 0xfb1f; + t.yohiragana = 0x3088; + t.yoikorean = 0x3189; + t.yokatakana = 0x30e8; + t.yokatakanahalfwidth = 0xff96; + t.yokorean = 0x315b; + t.yosmallhiragana = 0x3087; + t.yosmallkatakana = 0x30e7; + t.yosmallkatakanahalfwidth = 0xff6e; + t.yotgreek = 0x03f3; + t.yoyaekorean = 0x3188; + t.yoyakorean = 0x3187; + t.yoyakthai = 0x0e22; + t.yoyingthai = 0x0e0d; + t.yparen = 0x24b4; + t.ypogegrammeni = 0x037a; + t.ypogegrammenigreekcmb = 0x0345; + t.yr = 0x01a6; + t.yring = 0x1e99; + t.ysuperior = 0x02b8; + t.ytilde = 0x1ef9; + t.yturned = 0x028e; + t.yuhiragana = 0x3086; + t.yuikorean = 0x318c; + t.yukatakana = 0x30e6; + t.yukatakanahalfwidth = 0xff95; + t.yukorean = 0x3160; + t.yusbigcyrillic = 0x046b; + t.yusbigiotifiedcyrillic = 0x046d; + t.yuslittlecyrillic = 0x0467; + t.yuslittleiotifiedcyrillic = 0x0469; + t.yusmallhiragana = 0x3085; + t.yusmallkatakana = 0x30e5; + t.yusmallkatakanahalfwidth = 0xff6d; + t.yuyekorean = 0x318b; + t.yuyeokorean = 0x318a; + t.yyabengali = 0x09df; + t.yyadeva = 0x095f; + t.z = 0x007a; + t.zaarmenian = 0x0566; + t.zacute = 0x017a; + t.zadeva = 0x095b; + t.zagurmukhi = 0x0a5b; + t.zaharabic = 0x0638; + t.zahfinalarabic = 0xfec6; + t.zahinitialarabic = 0xfec7; + t.zahiragana = 0x3056; + t.zahmedialarabic = 0xfec8; + t.zainarabic = 0x0632; + t.zainfinalarabic = 0xfeb0; + t.zakatakana = 0x30b6; + t.zaqefgadolhebrew = 0x0595; + t.zaqefqatanhebrew = 0x0594; + t.zarqahebrew = 0x0598; + t.zayin = 0x05d6; + t.zayindagesh = 0xfb36; + t.zayindageshhebrew = 0xfb36; + t.zayinhebrew = 0x05d6; + t.zbopomofo = 0x3117; + t.zcaron = 0x017e; + t.zcircle = 0x24e9; + t.zcircumflex = 0x1e91; + t.zcurl = 0x0291; + t.zdot = 0x017c; + t.zdotaccent = 0x017c; + t.zdotbelow = 0x1e93; + t.zecyrillic = 0x0437; + t.zedescendercyrillic = 0x0499; + t.zedieresiscyrillic = 0x04df; + t.zehiragana = 0x305c; + t.zekatakana = 0x30bc; + t.zero = 0x0030; + t.zeroarabic = 0x0660; + t.zerobengali = 0x09e6; + t.zerodeva = 0x0966; + t.zerogujarati = 0x0ae6; + t.zerogurmukhi = 0x0a66; + t.zerohackarabic = 0x0660; + t.zeroinferior = 0x2080; + t.zeromonospace = 0xff10; + t.zerooldstyle = 0xf730; + t.zeropersian = 0x06f0; + t.zerosuperior = 0x2070; + t.zerothai = 0x0e50; + t.zerowidthjoiner = 0xfeff; + t.zerowidthnonjoiner = 0x200c; + t.zerowidthspace = 0x200b; + t.zeta = 0x03b6; + t.zhbopomofo = 0x3113; + t.zhearmenian = 0x056a; + t.zhebrevecyrillic = 0x04c2; + t.zhecyrillic = 0x0436; + t.zhedescendercyrillic = 0x0497; + t.zhedieresiscyrillic = 0x04dd; + t.zihiragana = 0x3058; + t.zikatakana = 0x30b8; + t.zinorhebrew = 0x05ae; + t.zlinebelow = 0x1e95; + t.zmonospace = 0xff5a; + t.zohiragana = 0x305e; + t.zokatakana = 0x30be; + t.zparen = 0x24b5; + t.zretroflexhook = 0x0290; + t.zstroke = 0x01b6; + t.zuhiragana = 0x305a; + t.zukatakana = 0x30ba; + t[".notdef"] = 0x0000; + t.angbracketleftbig = 0x2329; + t.angbracketleftBig = 0x2329; + t.angbracketleftbigg = 0x2329; + t.angbracketleftBigg = 0x2329; + t.angbracketrightBig = 0x232a; + t.angbracketrightbig = 0x232a; + t.angbracketrightBigg = 0x232a; + t.angbracketrightbigg = 0x232a; + t.arrowhookleft = 0x21aa; + t.arrowhookright = 0x21a9; + t.arrowlefttophalf = 0x21bc; + t.arrowleftbothalf = 0x21bd; + t.arrownortheast = 0x2197; + t.arrownorthwest = 0x2196; + t.arrowrighttophalf = 0x21c0; + t.arrowrightbothalf = 0x21c1; + t.arrowsoutheast = 0x2198; + t.arrowsouthwest = 0x2199; + t.backslashbig = 0x2216; + t.backslashBig = 0x2216; + t.backslashBigg = 0x2216; + t.backslashbigg = 0x2216; + t.bardbl = 0x2016; + t.bracehtipdownleft = 0xfe37; + t.bracehtipdownright = 0xfe37; + t.bracehtipupleft = 0xfe38; + t.bracehtipupright = 0xfe38; + t.braceleftBig = 0x007b; + t.braceleftbig = 0x007b; + t.braceleftbigg = 0x007b; + t.braceleftBigg = 0x007b; + t.bracerightBig = 0x007d; + t.bracerightbig = 0x007d; + t.bracerightbigg = 0x007d; + t.bracerightBigg = 0x007d; + t.bracketleftbig = 0x005b; + t.bracketleftBig = 0x005b; + t.bracketleftbigg = 0x005b; + t.bracketleftBigg = 0x005b; + t.bracketrightBig = 0x005d; + t.bracketrightbig = 0x005d; + t.bracketrightbigg = 0x005d; + t.bracketrightBigg = 0x005d; + t.ceilingleftbig = 0x2308; + t.ceilingleftBig = 0x2308; + t.ceilingleftBigg = 0x2308; + t.ceilingleftbigg = 0x2308; + t.ceilingrightbig = 0x2309; + t.ceilingrightBig = 0x2309; + t.ceilingrightbigg = 0x2309; + t.ceilingrightBigg = 0x2309; + t.circledotdisplay = 0x2299; + t.circledottext = 0x2299; + t.circlemultiplydisplay = 0x2297; + t.circlemultiplytext = 0x2297; + t.circleplusdisplay = 0x2295; + t.circleplustext = 0x2295; + t.contintegraldisplay = 0x222e; + t.contintegraltext = 0x222e; + t.coproductdisplay = 0x2210; + t.coproducttext = 0x2210; + t.floorleftBig = 0x230a; + t.floorleftbig = 0x230a; + t.floorleftbigg = 0x230a; + t.floorleftBigg = 0x230a; + t.floorrightbig = 0x230b; + t.floorrightBig = 0x230b; + t.floorrightBigg = 0x230b; + t.floorrightbigg = 0x230b; + t.hatwide = 0x0302; + t.hatwider = 0x0302; + t.hatwidest = 0x0302; + t.intercal = 0x1d40; + t.integraldisplay = 0x222b; + t.integraltext = 0x222b; + t.intersectiondisplay = 0x22c2; + t.intersectiontext = 0x22c2; + t.logicalanddisplay = 0x2227; + t.logicalandtext = 0x2227; + t.logicalordisplay = 0x2228; + t.logicalortext = 0x2228; + t.parenleftBig = 0x0028; + t.parenleftbig = 0x0028; + t.parenleftBigg = 0x0028; + t.parenleftbigg = 0x0028; + t.parenrightBig = 0x0029; + t.parenrightbig = 0x0029; + t.parenrightBigg = 0x0029; + t.parenrightbigg = 0x0029; + t.prime = 0x2032; + t.productdisplay = 0x220f; + t.producttext = 0x220f; + t.radicalbig = 0x221a; + t.radicalBig = 0x221a; + t.radicalBigg = 0x221a; + t.radicalbigg = 0x221a; + t.radicalbt = 0x221a; + t.radicaltp = 0x221a; + t.radicalvertex = 0x221a; + t.slashbig = 0x002f; + t.slashBig = 0x002f; + t.slashBigg = 0x002f; + t.slashbigg = 0x002f; + t.summationdisplay = 0x2211; + t.summationtext = 0x2211; + t.tildewide = 0x02dc; + t.tildewider = 0x02dc; + t.tildewidest = 0x02dc; + t.uniondisplay = 0x22c3; + t.unionmultidisplay = 0x228e; + t.unionmultitext = 0x228e; + t.unionsqdisplay = 0x2294; + t.unionsqtext = 0x2294; + t.uniontext = 0x22c3; + t.vextenddouble = 0x2225; + t.vextendsingle = 0x2223; +}); +exports.getGlyphsUnicode = getGlyphsUnicode; +const getDingbatsGlyphsUnicode = (0, _core_utils.getLookupTableFactory)(function (t) { + t.space = 0x0020; + t.a1 = 0x2701; + t.a2 = 0x2702; + t.a202 = 0x2703; + t.a3 = 0x2704; + t.a4 = 0x260e; + t.a5 = 0x2706; + t.a119 = 0x2707; + t.a118 = 0x2708; + t.a117 = 0x2709; + t.a11 = 0x261b; + t.a12 = 0x261e; + t.a13 = 0x270c; + t.a14 = 0x270d; + t.a15 = 0x270e; + t.a16 = 0x270f; + t.a105 = 0x2710; + t.a17 = 0x2711; + t.a18 = 0x2712; + t.a19 = 0x2713; + t.a20 = 0x2714; + t.a21 = 0x2715; + t.a22 = 0x2716; + t.a23 = 0x2717; + t.a24 = 0x2718; + t.a25 = 0x2719; + t.a26 = 0x271a; + t.a27 = 0x271b; + t.a28 = 0x271c; + t.a6 = 0x271d; + t.a7 = 0x271e; + t.a8 = 0x271f; + t.a9 = 0x2720; + t.a10 = 0x2721; + t.a29 = 0x2722; + t.a30 = 0x2723; + t.a31 = 0x2724; + t.a32 = 0x2725; + t.a33 = 0x2726; + t.a34 = 0x2727; + t.a35 = 0x2605; + t.a36 = 0x2729; + t.a37 = 0x272a; + t.a38 = 0x272b; + t.a39 = 0x272c; + t.a40 = 0x272d; + t.a41 = 0x272e; + t.a42 = 0x272f; + t.a43 = 0x2730; + t.a44 = 0x2731; + t.a45 = 0x2732; + t.a46 = 0x2733; + t.a47 = 0x2734; + t.a48 = 0x2735; + t.a49 = 0x2736; + t.a50 = 0x2737; + t.a51 = 0x2738; + t.a52 = 0x2739; + t.a53 = 0x273a; + t.a54 = 0x273b; + t.a55 = 0x273c; + t.a56 = 0x273d; + t.a57 = 0x273e; + t.a58 = 0x273f; + t.a59 = 0x2740; + t.a60 = 0x2741; + t.a61 = 0x2742; + t.a62 = 0x2743; + t.a63 = 0x2744; + t.a64 = 0x2745; + t.a65 = 0x2746; + t.a66 = 0x2747; + t.a67 = 0x2748; + t.a68 = 0x2749; + t.a69 = 0x274a; + t.a70 = 0x274b; + t.a71 = 0x25cf; + t.a72 = 0x274d; + t.a73 = 0x25a0; + t.a74 = 0x274f; + t.a203 = 0x2750; + t.a75 = 0x2751; + t.a204 = 0x2752; + t.a76 = 0x25b2; + t.a77 = 0x25bc; + t.a78 = 0x25c6; + t.a79 = 0x2756; + t.a81 = 0x25d7; + t.a82 = 0x2758; + t.a83 = 0x2759; + t.a84 = 0x275a; + t.a97 = 0x275b; + t.a98 = 0x275c; + t.a99 = 0x275d; + t.a100 = 0x275e; + t.a101 = 0x2761; + t.a102 = 0x2762; + t.a103 = 0x2763; + t.a104 = 0x2764; + t.a106 = 0x2765; + t.a107 = 0x2766; + t.a108 = 0x2767; + t.a112 = 0x2663; + t.a111 = 0x2666; + t.a110 = 0x2665; + t.a109 = 0x2660; + t.a120 = 0x2460; + t.a121 = 0x2461; + t.a122 = 0x2462; + t.a123 = 0x2463; + t.a124 = 0x2464; + t.a125 = 0x2465; + t.a126 = 0x2466; + t.a127 = 0x2467; + t.a128 = 0x2468; + t.a129 = 0x2469; + t.a130 = 0x2776; + t.a131 = 0x2777; + t.a132 = 0x2778; + t.a133 = 0x2779; + t.a134 = 0x277a; + t.a135 = 0x277b; + t.a136 = 0x277c; + t.a137 = 0x277d; + t.a138 = 0x277e; + t.a139 = 0x277f; + t.a140 = 0x2780; + t.a141 = 0x2781; + t.a142 = 0x2782; + t.a143 = 0x2783; + t.a144 = 0x2784; + t.a145 = 0x2785; + t.a146 = 0x2786; + t.a147 = 0x2787; + t.a148 = 0x2788; + t.a149 = 0x2789; + t.a150 = 0x278a; + t.a151 = 0x278b; + t.a152 = 0x278c; + t.a153 = 0x278d; + t.a154 = 0x278e; + t.a155 = 0x278f; + t.a156 = 0x2790; + t.a157 = 0x2791; + t.a158 = 0x2792; + t.a159 = 0x2793; + t.a160 = 0x2794; + t.a161 = 0x2192; + t.a163 = 0x2194; + t.a164 = 0x2195; + t.a196 = 0x2798; + t.a165 = 0x2799; + t.a192 = 0x279a; + t.a166 = 0x279b; + t.a167 = 0x279c; + t.a168 = 0x279d; + t.a169 = 0x279e; + t.a170 = 0x279f; + t.a171 = 0x27a0; + t.a172 = 0x27a1; + t.a173 = 0x27a2; + t.a162 = 0x27a3; + t.a174 = 0x27a4; + t.a175 = 0x27a5; + t.a176 = 0x27a6; + t.a177 = 0x27a7; + t.a178 = 0x27a8; + t.a179 = 0x27a9; + t.a193 = 0x27aa; + t.a180 = 0x27ab; + t.a199 = 0x27ac; + t.a181 = 0x27ad; + t.a200 = 0x27ae; + t.a182 = 0x27af; + t.a201 = 0x27b1; + t.a183 = 0x27b2; + t.a184 = 0x27b3; + t.a197 = 0x27b4; + t.a185 = 0x27b5; + t.a194 = 0x27b6; + t.a198 = 0x27b7; + t.a186 = 0x27b8; + t.a195 = 0x27b9; + t.a187 = 0x27ba; + t.a188 = 0x27bb; + t.a189 = 0x27bc; + t.a190 = 0x27bd; + t.a191 = 0x27be; + t.a89 = 0x2768; + t.a90 = 0x2769; + t.a93 = 0x276a; + t.a94 = 0x276b; + t.a91 = 0x276c; + t.a92 = 0x276d; + t.a205 = 0x276e; + t.a85 = 0x276f; + t.a206 = 0x2770; + t.a86 = 0x2771; + t.a87 = 0x2772; + t.a88 = 0x2773; + t.a95 = 0x2774; + t.a96 = 0x2775; + t[".notdef"] = 0x0000; +}); +exports.getDingbatsGlyphsUnicode = getDingbatsGlyphsUnicode; + +/***/ }), +/* 40 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.clearUnicodeCaches = clearUnicodeCaches; +exports.getCharUnicodeCategory = getCharUnicodeCategory; +exports.getUnicodeForGlyph = getUnicodeForGlyph; +exports.getUnicodeRangeFor = getUnicodeRangeFor; +exports.mapSpecialUnicodeValues = mapSpecialUnicodeValues; +var _core_utils = __w_pdfjs_require__(3); +const getSpecialPUASymbols = (0, _core_utils.getLookupTableFactory)(function (t) { + t[63721] = 0x00a9; + t[63193] = 0x00a9; + t[63720] = 0x00ae; + t[63194] = 0x00ae; + t[63722] = 0x2122; + t[63195] = 0x2122; + t[63729] = 0x23a7; + t[63730] = 0x23a8; + t[63731] = 0x23a9; + t[63740] = 0x23ab; + t[63741] = 0x23ac; + t[63742] = 0x23ad; + t[63726] = 0x23a1; + t[63727] = 0x23a2; + t[63728] = 0x23a3; + t[63737] = 0x23a4; + t[63738] = 0x23a5; + t[63739] = 0x23a6; + t[63723] = 0x239b; + t[63724] = 0x239c; + t[63725] = 0x239d; + t[63734] = 0x239e; + t[63735] = 0x239f; + t[63736] = 0x23a0; +}); +function mapSpecialUnicodeValues(code) { + if (code >= 0xfff0 && code <= 0xffff) { + return 0; + } else if (code >= 0xf600 && code <= 0xf8ff) { + return getSpecialPUASymbols()[code] || code; + } else if (code === 0x00ad) { + return 0x002d; + } + return code; +} +function getUnicodeForGlyph(name, glyphsUnicodeMap) { + let unicode = glyphsUnicodeMap[name]; + if (unicode !== undefined) { + return unicode; + } + if (!name) { + return -1; + } + if (name[0] === "u") { + const nameLen = name.length; + let hexStr; + if (nameLen === 7 && name[1] === "n" && name[2] === "i") { + hexStr = name.substring(3); + } else if (nameLen >= 5 && nameLen <= 7) { + hexStr = name.substring(1); + } else { + return -1; + } + if (hexStr === hexStr.toUpperCase()) { + unicode = parseInt(hexStr, 16); + if (unicode >= 0) { + return unicode; + } + } + } + return -1; +} +const UnicodeRanges = [[0x0000, 0x007f], [0x0080, 0x00ff], [0x0100, 0x017f], [0x0180, 0x024f], [0x0250, 0x02af, 0x1d00, 0x1d7f, 0x1d80, 0x1dbf], [0x02b0, 0x02ff, 0xa700, 0xa71f], [0x0300, 0x036f, 0x1dc0, 0x1dff], [0x0370, 0x03ff], [0x2c80, 0x2cff], [0x0400, 0x04ff, 0x0500, 0x052f, 0x2de0, 0x2dff, 0xa640, 0xa69f], [0x0530, 0x058f], [0x0590, 0x05ff], [0xa500, 0xa63f], [0x0600, 0x06ff, 0x0750, 0x077f], [0x07c0, 0x07ff], [0x0900, 0x097f], [0x0980, 0x09ff], [0x0a00, 0x0a7f], [0x0a80, 0x0aff], [0x0b00, 0x0b7f], [0x0b80, 0x0bff], [0x0c00, 0x0c7f], [0x0c80, 0x0cff], [0x0d00, 0x0d7f], [0x0e00, 0x0e7f], [0x0e80, 0x0eff], [0x10a0, 0x10ff, 0x2d00, 0x2d2f], [0x1b00, 0x1b7f], [0x1100, 0x11ff], [0x1e00, 0x1eff, 0x2c60, 0x2c7f, 0xa720, 0xa7ff], [0x1f00, 0x1fff], [0x2000, 0x206f, 0x2e00, 0x2e7f], [0x2070, 0x209f], [0x20a0, 0x20cf], [0x20d0, 0x20ff], [0x2100, 0x214f], [0x2150, 0x218f], [0x2190, 0x21ff, 0x27f0, 0x27ff, 0x2900, 0x297f, 0x2b00, 0x2bff], [0x2200, 0x22ff, 0x2a00, 0x2aff, 0x27c0, 0x27ef, 0x2980, 0x29ff], [0x2300, 0x23ff], [0x2400, 0x243f], [0x2440, 0x245f], [0x2460, 0x24ff], [0x2500, 0x257f], [0x2580, 0x259f], [0x25a0, 0x25ff], [0x2600, 0x26ff], [0x2700, 0x27bf], [0x3000, 0x303f], [0x3040, 0x309f], [0x30a0, 0x30ff, 0x31f0, 0x31ff], [0x3100, 0x312f, 0x31a0, 0x31bf], [0x3130, 0x318f], [0xa840, 0xa87f], [0x3200, 0x32ff], [0x3300, 0x33ff], [0xac00, 0xd7af], [0xd800, 0xdfff], [0x10900, 0x1091f], [0x4e00, 0x9fff, 0x2e80, 0x2eff, 0x2f00, 0x2fdf, 0x2ff0, 0x2fff, 0x3400, 0x4dbf, 0x20000, 0x2a6df, 0x3190, 0x319f], [0xe000, 0xf8ff], [0x31c0, 0x31ef, 0xf900, 0xfaff, 0x2f800, 0x2fa1f], [0xfb00, 0xfb4f], [0xfb50, 0xfdff], [0xfe20, 0xfe2f], [0xfe10, 0xfe1f], [0xfe50, 0xfe6f], [0xfe70, 0xfeff], [0xff00, 0xffef], [0xfff0, 0xffff], [0x0f00, 0x0fff], [0x0700, 0x074f], [0x0780, 0x07bf], [0x0d80, 0x0dff], [0x1000, 0x109f], [0x1200, 0x137f, 0x1380, 0x139f, 0x2d80, 0x2ddf], [0x13a0, 0x13ff], [0x1400, 0x167f], [0x1680, 0x169f], [0x16a0, 0x16ff], [0x1780, 0x17ff], [0x1800, 0x18af], [0x2800, 0x28ff], [0xa000, 0xa48f], [0x1700, 0x171f, 0x1720, 0x173f, 0x1740, 0x175f, 0x1760, 0x177f], [0x10300, 0x1032f], [0x10330, 0x1034f], [0x10400, 0x1044f], [0x1d000, 0x1d0ff, 0x1d100, 0x1d1ff, 0x1d200, 0x1d24f], [0x1d400, 0x1d7ff], [0xff000, 0xffffd], [0xfe00, 0xfe0f, 0xe0100, 0xe01ef], [0xe0000, 0xe007f], [0x1900, 0x194f], [0x1950, 0x197f], [0x1980, 0x19df], [0x1a00, 0x1a1f], [0x2c00, 0x2c5f], [0x2d30, 0x2d7f], [0x4dc0, 0x4dff], [0xa800, 0xa82f], [0x10000, 0x1007f, 0x10080, 0x100ff, 0x10100, 0x1013f], [0x10140, 0x1018f], [0x10380, 0x1039f], [0x103a0, 0x103df], [0x10450, 0x1047f], [0x10480, 0x104af], [0x10800, 0x1083f], [0x10a00, 0x10a5f], [0x1d300, 0x1d35f], [0x12000, 0x123ff, 0x12400, 0x1247f], [0x1d360, 0x1d37f], [0x1b80, 0x1bbf], [0x1c00, 0x1c4f], [0x1c50, 0x1c7f], [0xa880, 0xa8df], [0xa900, 0xa92f], [0xa930, 0xa95f], [0xaa00, 0xaa5f], [0x10190, 0x101cf], [0x101d0, 0x101ff], [0x102a0, 0x102df, 0x10280, 0x1029f, 0x10920, 0x1093f], [0x1f030, 0x1f09f, 0x1f000, 0x1f02f]]; +function getUnicodeRangeFor(value, lastPosition = -1) { + if (lastPosition !== -1) { + const range = UnicodeRanges[lastPosition]; + for (let i = 0, ii = range.length; i < ii; i += 2) { + if (value >= range[i] && value <= range[i + 1]) { + return lastPosition; + } + } + } + for (let i = 0, ii = UnicodeRanges.length; i < ii; i++) { + const range = UnicodeRanges[i]; + for (let j = 0, jj = range.length; j < jj; j += 2) { + if (value >= range[j] && value <= range[j + 1]) { + return i; + } + } + } + return -1; +} +const SpecialCharRegExp = new RegExp("^(\\s)|(\\p{Mn})|(\\p{Cf})$", "u"); +const CategoryCache = new Map(); +function getCharUnicodeCategory(char) { + const cachedCategory = CategoryCache.get(char); + if (cachedCategory) { + return cachedCategory; + } + const groups = char.match(SpecialCharRegExp); + const category = { + isWhitespace: !!groups?.[1], + isZeroWidthDiacritic: !!groups?.[2], + isInvisibleFormatMark: !!groups?.[3] + }; + CategoryCache.set(char, category); + return category; +} +function clearUnicodeCaches() { + CategoryCache.clear(); +} + +/***/ }), +/* 41 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getSerifFonts = exports.getNonStdFontMap = exports.getGlyphMapForStandardFonts = exports.getFontNameToFileMap = void 0; +exports.getStandardFontName = getStandardFontName; +exports.getSymbolsFonts = exports.getSupplementalGlyphMapForCalibri = exports.getSupplementalGlyphMapForArialBlack = exports.getStdFontMap = void 0; +exports.isKnownFontName = isKnownFontName; +var _core_utils = __w_pdfjs_require__(3); +var _fonts_utils = __w_pdfjs_require__(38); +const getStdFontMap = (0, _core_utils.getLookupTableFactory)(function (t) { + t["Times-Roman"] = "Times-Roman"; + t.Helvetica = "Helvetica"; + t.Courier = "Courier"; + t.Symbol = "Symbol"; + t["Times-Bold"] = "Times-Bold"; + t["Helvetica-Bold"] = "Helvetica-Bold"; + t["Courier-Bold"] = "Courier-Bold"; + t.ZapfDingbats = "ZapfDingbats"; + t["Times-Italic"] = "Times-Italic"; + t["Helvetica-Oblique"] = "Helvetica-Oblique"; + t["Courier-Oblique"] = "Courier-Oblique"; + t["Times-BoldItalic"] = "Times-BoldItalic"; + t["Helvetica-BoldOblique"] = "Helvetica-BoldOblique"; + t["Courier-BoldOblique"] = "Courier-BoldOblique"; + t.ArialNarrow = "Helvetica"; + t["ArialNarrow-Bold"] = "Helvetica-Bold"; + t["ArialNarrow-BoldItalic"] = "Helvetica-BoldOblique"; + t["ArialNarrow-Italic"] = "Helvetica-Oblique"; + t.ArialBlack = "Helvetica"; + t["ArialBlack-Bold"] = "Helvetica-Bold"; + t["ArialBlack-BoldItalic"] = "Helvetica-BoldOblique"; + t["ArialBlack-Italic"] = "Helvetica-Oblique"; + t["Arial-Black"] = "Helvetica"; + t["Arial-Black-Bold"] = "Helvetica-Bold"; + t["Arial-Black-BoldItalic"] = "Helvetica-BoldOblique"; + t["Arial-Black-Italic"] = "Helvetica-Oblique"; + t.Arial = "Helvetica"; + t["Arial-Bold"] = "Helvetica-Bold"; + t["Arial-BoldItalic"] = "Helvetica-BoldOblique"; + t["Arial-Italic"] = "Helvetica-Oblique"; + t.ArialMT = "Helvetica"; + t["Arial-BoldItalicMT"] = "Helvetica-BoldOblique"; + t["Arial-BoldMT"] = "Helvetica-Bold"; + t["Arial-ItalicMT"] = "Helvetica-Oblique"; + t["Arial-BoldItalicMT-BoldItalic"] = "Helvetica-BoldOblique"; + t["Arial-BoldMT-Bold"] = "Helvetica-Bold"; + t["Arial-ItalicMT-Italic"] = "Helvetica-Oblique"; + t.ArialUnicodeMS = "Helvetica"; + t["ArialUnicodeMS-Bold"] = "Helvetica-Bold"; + t["ArialUnicodeMS-BoldItalic"] = "Helvetica-BoldOblique"; + t["ArialUnicodeMS-Italic"] = "Helvetica-Oblique"; + t["Courier-BoldItalic"] = "Courier-BoldOblique"; + t["Courier-Italic"] = "Courier-Oblique"; + t.CourierNew = "Courier"; + t["CourierNew-Bold"] = "Courier-Bold"; + t["CourierNew-BoldItalic"] = "Courier-BoldOblique"; + t["CourierNew-Italic"] = "Courier-Oblique"; + t["CourierNewPS-BoldItalicMT"] = "Courier-BoldOblique"; + t["CourierNewPS-BoldMT"] = "Courier-Bold"; + t["CourierNewPS-ItalicMT"] = "Courier-Oblique"; + t.CourierNewPSMT = "Courier"; + t["Helvetica-BoldItalic"] = "Helvetica-BoldOblique"; + t["Helvetica-Italic"] = "Helvetica-Oblique"; + t["Symbol-Bold"] = "Symbol"; + t["Symbol-BoldItalic"] = "Symbol"; + t["Symbol-Italic"] = "Symbol"; + t.TimesNewRoman = "Times-Roman"; + t["TimesNewRoman-Bold"] = "Times-Bold"; + t["TimesNewRoman-BoldItalic"] = "Times-BoldItalic"; + t["TimesNewRoman-Italic"] = "Times-Italic"; + t.TimesNewRomanPS = "Times-Roman"; + t["TimesNewRomanPS-Bold"] = "Times-Bold"; + t["TimesNewRomanPS-BoldItalic"] = "Times-BoldItalic"; + t["TimesNewRomanPS-BoldItalicMT"] = "Times-BoldItalic"; + t["TimesNewRomanPS-BoldMT"] = "Times-Bold"; + t["TimesNewRomanPS-Italic"] = "Times-Italic"; + t["TimesNewRomanPS-ItalicMT"] = "Times-Italic"; + t.TimesNewRomanPSMT = "Times-Roman"; + t["TimesNewRomanPSMT-Bold"] = "Times-Bold"; + t["TimesNewRomanPSMT-BoldItalic"] = "Times-BoldItalic"; + t["TimesNewRomanPSMT-Italic"] = "Times-Italic"; +}); +exports.getStdFontMap = getStdFontMap; +const getFontNameToFileMap = (0, _core_utils.getLookupTableFactory)(function (t) { + t.Courier = "FoxitFixed.pfb"; + t["Courier-Bold"] = "FoxitFixedBold.pfb"; + t["Courier-BoldOblique"] = "FoxitFixedBoldItalic.pfb"; + t["Courier-Oblique"] = "FoxitFixedItalic.pfb"; + t.Helvetica = "LiberationSans-Regular.ttf"; + t["Helvetica-Bold"] = "LiberationSans-Bold.ttf"; + t["Helvetica-BoldOblique"] = "LiberationSans-BoldItalic.ttf"; + t["Helvetica-Oblique"] = "LiberationSans-Italic.ttf"; + t["Times-Roman"] = "FoxitSerif.pfb"; + t["Times-Bold"] = "FoxitSerifBold.pfb"; + t["Times-BoldItalic"] = "FoxitSerifBoldItalic.pfb"; + t["Times-Italic"] = "FoxitSerifItalic.pfb"; + t.Symbol = "FoxitSymbol.pfb"; + t.ZapfDingbats = "FoxitDingbats.pfb"; + t["LiberationSans-Regular"] = "LiberationSans-Regular.ttf"; + t["LiberationSans-Bold"] = "LiberationSans-Bold.ttf"; + t["LiberationSans-Italic"] = "LiberationSans-Italic.ttf"; + t["LiberationSans-BoldItalic"] = "LiberationSans-BoldItalic.ttf"; +}); +exports.getFontNameToFileMap = getFontNameToFileMap; +const getNonStdFontMap = (0, _core_utils.getLookupTableFactory)(function (t) { + t.Calibri = "Helvetica"; + t["Calibri-Bold"] = "Helvetica-Bold"; + t["Calibri-BoldItalic"] = "Helvetica-BoldOblique"; + t["Calibri-Italic"] = "Helvetica-Oblique"; + t.CenturyGothic = "Helvetica"; + t["CenturyGothic-Bold"] = "Helvetica-Bold"; + t["CenturyGothic-BoldItalic"] = "Helvetica-BoldOblique"; + t["CenturyGothic-Italic"] = "Helvetica-Oblique"; + t.ComicSansMS = "Comic Sans MS"; + t["ComicSansMS-Bold"] = "Comic Sans MS-Bold"; + t["ComicSansMS-BoldItalic"] = "Comic Sans MS-BoldItalic"; + t["ComicSansMS-Italic"] = "Comic Sans MS-Italic"; + t.Impact = "Helvetica"; + t["ItcSymbol-Bold"] = "Helvetica-Bold"; + t["ItcSymbol-BoldItalic"] = "Helvetica-BoldOblique"; + t["ItcSymbol-Book"] = "Helvetica"; + t["ItcSymbol-BookItalic"] = "Helvetica-Oblique"; + t["ItcSymbol-Medium"] = "Helvetica"; + t["ItcSymbol-MediumItalic"] = "Helvetica-Oblique"; + t.LucidaConsole = "Courier"; + t["LucidaConsole-Bold"] = "Courier-Bold"; + t["LucidaConsole-BoldItalic"] = "Courier-BoldOblique"; + t["LucidaConsole-Italic"] = "Courier-Oblique"; + t["LucidaSans-Demi"] = "Helvetica-Bold"; + t["MS-Gothic"] = "MS Gothic"; + t["MS-Gothic-Bold"] = "MS Gothic-Bold"; + t["MS-Gothic-BoldItalic"] = "MS Gothic-BoldItalic"; + t["MS-Gothic-Italic"] = "MS Gothic-Italic"; + t["MS-Mincho"] = "MS Mincho"; + t["MS-Mincho-Bold"] = "MS Mincho-Bold"; + t["MS-Mincho-BoldItalic"] = "MS Mincho-BoldItalic"; + t["MS-Mincho-Italic"] = "MS Mincho-Italic"; + t["MS-PGothic"] = "MS PGothic"; + t["MS-PGothic-Bold"] = "MS PGothic-Bold"; + t["MS-PGothic-BoldItalic"] = "MS PGothic-BoldItalic"; + t["MS-PGothic-Italic"] = "MS PGothic-Italic"; + t["MS-PMincho"] = "MS PMincho"; + t["MS-PMincho-Bold"] = "MS PMincho-Bold"; + t["MS-PMincho-BoldItalic"] = "MS PMincho-BoldItalic"; + t["MS-PMincho-Italic"] = "MS PMincho-Italic"; + t.NuptialScript = "Times-Italic"; + t.SegoeUISymbol = "Helvetica"; +}); +exports.getNonStdFontMap = getNonStdFontMap; +const getSerifFonts = (0, _core_utils.getLookupTableFactory)(function (t) { + t["Adobe Jenson"] = true; + t["Adobe Text"] = true; + t.Albertus = true; + t.Aldus = true; + t.Alexandria = true; + t.Algerian = true; + t["American Typewriter"] = true; + t.Antiqua = true; + t.Apex = true; + t.Arno = true; + t.Aster = true; + t.Aurora = true; + t.Baskerville = true; + t.Bell = true; + t.Bembo = true; + t["Bembo Schoolbook"] = true; + t.Benguiat = true; + t["Berkeley Old Style"] = true; + t["Bernhard Modern"] = true; + t["Berthold City"] = true; + t.Bodoni = true; + t["Bauer Bodoni"] = true; + t["Book Antiqua"] = true; + t.Bookman = true; + t["Bordeaux Roman"] = true; + t["Californian FB"] = true; + t.Calisto = true; + t.Calvert = true; + t.Capitals = true; + t.Cambria = true; + t.Cartier = true; + t.Caslon = true; + t.Catull = true; + t.Centaur = true; + t["Century Old Style"] = true; + t["Century Schoolbook"] = true; + t.Chaparral = true; + t["Charis SIL"] = true; + t.Cheltenham = true; + t["Cholla Slab"] = true; + t.Clarendon = true; + t.Clearface = true; + t.Cochin = true; + t.Colonna = true; + t["Computer Modern"] = true; + t["Concrete Roman"] = true; + t.Constantia = true; + t["Cooper Black"] = true; + t.Corona = true; + t.Ecotype = true; + t.Egyptienne = true; + t.Elephant = true; + t.Excelsior = true; + t.Fairfield = true; + t["FF Scala"] = true; + t.Folkard = true; + t.Footlight = true; + t.FreeSerif = true; + t["Friz Quadrata"] = true; + t.Garamond = true; + t.Gentium = true; + t.Georgia = true; + t.Gloucester = true; + t["Goudy Old Style"] = true; + t["Goudy Schoolbook"] = true; + t["Goudy Pro Font"] = true; + t.Granjon = true; + t["Guardian Egyptian"] = true; + t.Heather = true; + t.Hercules = true; + t["High Tower Text"] = true; + t.Hiroshige = true; + t["Hoefler Text"] = true; + t["Humana Serif"] = true; + t.Imprint = true; + t["Ionic No. 5"] = true; + t.Janson = true; + t.Joanna = true; + t.Korinna = true; + t.Lexicon = true; + t.LiberationSerif = true; + t["Liberation Serif"] = true; + t["Linux Libertine"] = true; + t.Literaturnaya = true; + t.Lucida = true; + t["Lucida Bright"] = true; + t.Melior = true; + t.Memphis = true; + t.Miller = true; + t.Minion = true; + t.Modern = true; + t["Mona Lisa"] = true; + t["Mrs Eaves"] = true; + t["MS Serif"] = true; + t["Museo Slab"] = true; + t["New York"] = true; + t["Nimbus Roman"] = true; + t["NPS Rawlinson Roadway"] = true; + t.NuptialScript = true; + t.Palatino = true; + t.Perpetua = true; + t.Plantin = true; + t["Plantin Schoolbook"] = true; + t.Playbill = true; + t["Poor Richard"] = true; + t["Rawlinson Roadway"] = true; + t.Renault = true; + t.Requiem = true; + t.Rockwell = true; + t.Roman = true; + t["Rotis Serif"] = true; + t.Sabon = true; + t.Scala = true; + t.Seagull = true; + t.Sistina = true; + t.Souvenir = true; + t.STIX = true; + t["Stone Informal"] = true; + t["Stone Serif"] = true; + t.Sylfaen = true; + t.Times = true; + t.Trajan = true; + t["TrinitƩ"] = true; + t["Trump Mediaeval"] = true; + t.Utopia = true; + t["Vale Type"] = true; + t["Bitstream Vera"] = true; + t["Vera Serif"] = true; + t.Versailles = true; + t.Wanted = true; + t.Weiss = true; + t["Wide Latin"] = true; + t.Windsor = true; + t.XITS = true; +}); +exports.getSerifFonts = getSerifFonts; +const getSymbolsFonts = (0, _core_utils.getLookupTableFactory)(function (t) { + t.Dingbats = true; + t.Symbol = true; + t.ZapfDingbats = true; + t.Wingdings = true; + t["Wingdings-Bold"] = true; + t["Wingdings-Regular"] = true; +}); +exports.getSymbolsFonts = getSymbolsFonts; +const getGlyphMapForStandardFonts = (0, _core_utils.getLookupTableFactory)(function (t) { + t[2] = 10; + t[3] = 32; + t[4] = 33; + t[5] = 34; + t[6] = 35; + t[7] = 36; + t[8] = 37; + t[9] = 38; + t[10] = 39; + t[11] = 40; + t[12] = 41; + t[13] = 42; + t[14] = 43; + t[15] = 44; + t[16] = 45; + t[17] = 46; + t[18] = 47; + t[19] = 48; + t[20] = 49; + t[21] = 50; + t[22] = 51; + t[23] = 52; + t[24] = 53; + t[25] = 54; + t[26] = 55; + t[27] = 56; + t[28] = 57; + t[29] = 58; + t[30] = 894; + t[31] = 60; + t[32] = 61; + t[33] = 62; + t[34] = 63; + t[35] = 64; + t[36] = 65; + t[37] = 66; + t[38] = 67; + t[39] = 68; + t[40] = 69; + t[41] = 70; + t[42] = 71; + t[43] = 72; + t[44] = 73; + t[45] = 74; + t[46] = 75; + t[47] = 76; + t[48] = 77; + t[49] = 78; + t[50] = 79; + t[51] = 80; + t[52] = 81; + t[53] = 82; + t[54] = 83; + t[55] = 84; + t[56] = 85; + t[57] = 86; + t[58] = 87; + t[59] = 88; + t[60] = 89; + t[61] = 90; + t[62] = 91; + t[63] = 92; + t[64] = 93; + t[65] = 94; + t[66] = 95; + t[67] = 96; + t[68] = 97; + t[69] = 98; + t[70] = 99; + t[71] = 100; + t[72] = 101; + t[73] = 102; + t[74] = 103; + t[75] = 104; + t[76] = 105; + t[77] = 106; + t[78] = 107; + t[79] = 108; + t[80] = 109; + t[81] = 110; + t[82] = 111; + t[83] = 112; + t[84] = 113; + t[85] = 114; + t[86] = 115; + t[87] = 116; + t[88] = 117; + t[89] = 118; + t[90] = 119; + t[91] = 120; + t[92] = 121; + t[93] = 122; + t[94] = 123; + t[95] = 124; + t[96] = 125; + t[97] = 126; + t[98] = 196; + t[99] = 197; + t[100] = 199; + t[101] = 201; + t[102] = 209; + t[103] = 214; + t[104] = 220; + t[105] = 225; + t[106] = 224; + t[107] = 226; + t[108] = 228; + t[109] = 227; + t[110] = 229; + t[111] = 231; + t[112] = 233; + t[113] = 232; + t[114] = 234; + t[115] = 235; + t[116] = 237; + t[117] = 236; + t[118] = 238; + t[119] = 239; + t[120] = 241; + t[121] = 243; + t[122] = 242; + t[123] = 244; + t[124] = 246; + t[125] = 245; + t[126] = 250; + t[127] = 249; + t[128] = 251; + t[129] = 252; + t[130] = 8224; + t[131] = 176; + t[132] = 162; + t[133] = 163; + t[134] = 167; + t[135] = 8226; + t[136] = 182; + t[137] = 223; + t[138] = 174; + t[139] = 169; + t[140] = 8482; + t[141] = 180; + t[142] = 168; + t[143] = 8800; + t[144] = 198; + t[145] = 216; + t[146] = 8734; + t[147] = 177; + t[148] = 8804; + t[149] = 8805; + t[150] = 165; + t[151] = 181; + t[152] = 8706; + t[153] = 8721; + t[154] = 8719; + t[156] = 8747; + t[157] = 170; + t[158] = 186; + t[159] = 8486; + t[160] = 230; + t[161] = 248; + t[162] = 191; + t[163] = 161; + t[164] = 172; + t[165] = 8730; + t[166] = 402; + t[167] = 8776; + t[168] = 8710; + t[169] = 171; + t[170] = 187; + t[171] = 8230; + t[179] = 8220; + t[180] = 8221; + t[181] = 8216; + t[182] = 8217; + t[200] = 193; + t[203] = 205; + t[207] = 211; + t[210] = 218; + t[223] = 711; + t[224] = 321; + t[225] = 322; + t[226] = 352; + t[227] = 353; + t[228] = 381; + t[229] = 382; + t[233] = 221; + t[234] = 253; + t[252] = 263; + t[253] = 268; + t[254] = 269; + t[258] = 258; + t[260] = 260; + t[261] = 261; + t[265] = 280; + t[266] = 281; + t[267] = 282; + t[268] = 283; + t[269] = 313; + t[275] = 323; + t[276] = 324; + t[278] = 328; + t[283] = 344; + t[284] = 345; + t[285] = 346; + t[286] = 347; + t[292] = 367; + t[295] = 377; + t[296] = 378; + t[298] = 380; + t[305] = 963; + t[306] = 964; + t[307] = 966; + t[308] = 8215; + t[309] = 8252; + t[310] = 8319; + t[311] = 8359; + t[312] = 8592; + t[313] = 8593; + t[337] = 9552; + t[493] = 1039; + t[494] = 1040; + t[672] = 1488; + t[673] = 1489; + t[674] = 1490; + t[675] = 1491; + t[676] = 1492; + t[677] = 1493; + t[678] = 1494; + t[679] = 1495; + t[680] = 1496; + t[681] = 1497; + t[682] = 1498; + t[683] = 1499; + t[684] = 1500; + t[685] = 1501; + t[686] = 1502; + t[687] = 1503; + t[688] = 1504; + t[689] = 1505; + t[690] = 1506; + t[691] = 1507; + t[692] = 1508; + t[693] = 1509; + t[694] = 1510; + t[695] = 1511; + t[696] = 1512; + t[697] = 1513; + t[698] = 1514; + t[705] = 1524; + t[706] = 8362; + t[710] = 64288; + t[711] = 64298; + t[759] = 1617; + t[761] = 1776; + t[763] = 1778; + t[775] = 1652; + t[777] = 1764; + t[778] = 1780; + t[779] = 1781; + t[780] = 1782; + t[782] = 771; + t[783] = 64726; + t[786] = 8363; + t[788] = 8532; + t[790] = 768; + t[791] = 769; + t[792] = 768; + t[795] = 803; + t[797] = 64336; + t[798] = 64337; + t[799] = 64342; + t[800] = 64343; + t[801] = 64344; + t[802] = 64345; + t[803] = 64362; + t[804] = 64363; + t[805] = 64364; + t[2424] = 7821; + t[2425] = 7822; + t[2426] = 7823; + t[2427] = 7824; + t[2428] = 7825; + t[2429] = 7826; + t[2430] = 7827; + t[2433] = 7682; + t[2678] = 8045; + t[2679] = 8046; + t[2830] = 1552; + t[2838] = 686; + t[2840] = 751; + t[2842] = 753; + t[2843] = 754; + t[2844] = 755; + t[2846] = 757; + t[2856] = 767; + t[2857] = 848; + t[2858] = 849; + t[2862] = 853; + t[2863] = 854; + t[2864] = 855; + t[2865] = 861; + t[2866] = 862; + t[2906] = 7460; + t[2908] = 7462; + t[2909] = 7463; + t[2910] = 7464; + t[2912] = 7466; + t[2913] = 7467; + t[2914] = 7468; + t[2916] = 7470; + t[2917] = 7471; + t[2918] = 7472; + t[2920] = 7474; + t[2921] = 7475; + t[2922] = 7476; + t[2924] = 7478; + t[2925] = 7479; + t[2926] = 7480; + t[2928] = 7482; + t[2929] = 7483; + t[2930] = 7484; + t[2932] = 7486; + t[2933] = 7487; + t[2934] = 7488; + t[2936] = 7490; + t[2937] = 7491; + t[2938] = 7492; + t[2940] = 7494; + t[2941] = 7495; + t[2942] = 7496; + t[2944] = 7498; + t[2946] = 7500; + t[2948] = 7502; + t[2950] = 7504; + t[2951] = 7505; + t[2952] = 7506; + t[2954] = 7508; + t[2955] = 7509; + t[2956] = 7510; + t[2958] = 7512; + t[2959] = 7513; + t[2960] = 7514; + t[2962] = 7516; + t[2963] = 7517; + t[2964] = 7518; + t[2966] = 7520; + t[2967] = 7521; + t[2968] = 7522; + t[2970] = 7524; + t[2971] = 7525; + t[2972] = 7526; + t[2974] = 7528; + t[2975] = 7529; + t[2976] = 7530; + t[2978] = 1537; + t[2979] = 1538; + t[2980] = 1539; + t[2982] = 1549; + t[2983] = 1551; + t[2984] = 1552; + t[2986] = 1554; + t[2987] = 1555; + t[2988] = 1556; + t[2990] = 1623; + t[2991] = 1624; + t[2995] = 1775; + t[2999] = 1791; + t[3002] = 64290; + t[3003] = 64291; + t[3004] = 64292; + t[3006] = 64294; + t[3007] = 64295; + t[3008] = 64296; + t[3011] = 1900; + t[3014] = 8223; + t[3015] = 8244; + t[3017] = 7532; + t[3018] = 7533; + t[3019] = 7534; + t[3075] = 7590; + t[3076] = 7591; + t[3079] = 7594; + t[3080] = 7595; + t[3083] = 7598; + t[3084] = 7599; + t[3087] = 7602; + t[3088] = 7603; + t[3091] = 7606; + t[3092] = 7607; + t[3095] = 7610; + t[3096] = 7611; + t[3099] = 7614; + t[3100] = 7615; + t[3103] = 7618; + t[3104] = 7619; + t[3107] = 8337; + t[3108] = 8338; + t[3116] = 1884; + t[3119] = 1885; + t[3120] = 1885; + t[3123] = 1886; + t[3124] = 1886; + t[3127] = 1887; + t[3128] = 1887; + t[3131] = 1888; + t[3132] = 1888; + t[3135] = 1889; + t[3136] = 1889; + t[3139] = 1890; + t[3140] = 1890; + t[3143] = 1891; + t[3144] = 1891; + t[3147] = 1892; + t[3148] = 1892; + t[3153] = 580; + t[3154] = 581; + t[3157] = 584; + t[3158] = 585; + t[3161] = 588; + t[3162] = 589; + t[3165] = 891; + t[3166] = 892; + t[3169] = 1274; + t[3170] = 1275; + t[3173] = 1278; + t[3174] = 1279; + t[3181] = 7622; + t[3182] = 7623; + t[3282] = 11799; + t[3316] = 578; + t[3379] = 42785; + t[3393] = 1159; + t[3416] = 8377; +}); +exports.getGlyphMapForStandardFonts = getGlyphMapForStandardFonts; +const getSupplementalGlyphMapForArialBlack = (0, _core_utils.getLookupTableFactory)(function (t) { + t[227] = 322; + t[264] = 261; + t[291] = 346; +}); +exports.getSupplementalGlyphMapForArialBlack = getSupplementalGlyphMapForArialBlack; +const getSupplementalGlyphMapForCalibri = (0, _core_utils.getLookupTableFactory)(function (t) { + t[1] = 32; + t[4] = 65; + t[5] = 192; + t[6] = 193; + t[9] = 196; + t[17] = 66; + t[18] = 67; + t[21] = 268; + t[24] = 68; + t[28] = 69; + t[29] = 200; + t[30] = 201; + t[32] = 282; + t[38] = 70; + t[39] = 71; + t[44] = 72; + t[47] = 73; + t[48] = 204; + t[49] = 205; + t[58] = 74; + t[60] = 75; + t[62] = 76; + t[68] = 77; + t[69] = 78; + t[75] = 79; + t[76] = 210; + t[80] = 214; + t[87] = 80; + t[89] = 81; + t[90] = 82; + t[92] = 344; + t[94] = 83; + t[97] = 352; + t[100] = 84; + t[104] = 85; + t[109] = 220; + t[115] = 86; + t[116] = 87; + t[121] = 88; + t[122] = 89; + t[124] = 221; + t[127] = 90; + t[129] = 381; + t[258] = 97; + t[259] = 224; + t[260] = 225; + t[263] = 228; + t[268] = 261; + t[271] = 98; + t[272] = 99; + t[273] = 263; + t[275] = 269; + t[282] = 100; + t[286] = 101; + t[287] = 232; + t[288] = 233; + t[290] = 283; + t[295] = 281; + t[296] = 102; + t[336] = 103; + t[346] = 104; + t[349] = 105; + t[350] = 236; + t[351] = 237; + t[361] = 106; + t[364] = 107; + t[367] = 108; + t[371] = 322; + t[373] = 109; + t[374] = 110; + t[381] = 111; + t[382] = 242; + t[383] = 243; + t[386] = 246; + t[393] = 112; + t[395] = 113; + t[396] = 114; + t[398] = 345; + t[400] = 115; + t[401] = 347; + t[403] = 353; + t[410] = 116; + t[437] = 117; + t[442] = 252; + t[448] = 118; + t[449] = 119; + t[454] = 120; + t[455] = 121; + t[457] = 253; + t[460] = 122; + t[462] = 382; + t[463] = 380; + t[853] = 44; + t[855] = 58; + t[856] = 46; + t[876] = 47; + t[878] = 45; + t[882] = 45; + t[894] = 40; + t[895] = 41; + t[896] = 91; + t[897] = 93; + t[923] = 64; + t[1004] = 48; + t[1005] = 49; + t[1006] = 50; + t[1007] = 51; + t[1008] = 52; + t[1009] = 53; + t[1010] = 54; + t[1011] = 55; + t[1012] = 56; + t[1013] = 57; + t[1081] = 37; + t[1085] = 43; + t[1086] = 45; +}); +exports.getSupplementalGlyphMapForCalibri = getSupplementalGlyphMapForCalibri; +function getStandardFontName(name) { + const fontName = (0, _fonts_utils.normalizeFontName)(name); + const stdFontMap = getStdFontMap(); + return stdFontMap[fontName]; +} +function isKnownFontName(name) { + const fontName = (0, _fonts_utils.normalizeFontName)(name); + return !!(getStdFontMap()[fontName] || getNonStdFontMap()[fontName] || getSerifFonts()[fontName] || getSymbolsFonts()[fontName]); +} + +/***/ }), +/* 42 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ToUnicodeMap = exports.IdentityToUnicodeMap = void 0; +var _util = __w_pdfjs_require__(2); +class ToUnicodeMap { + constructor(cmap = []) { + this._map = cmap; + } + get length() { + return this._map.length; + } + forEach(callback) { + for (const charCode in this._map) { + callback(charCode, this._map[charCode].charCodeAt(0)); + } + } + has(i) { + return this._map[i] !== undefined; + } + get(i) { + return this._map[i]; + } + charCodeOf(value) { + const map = this._map; + if (map.length <= 0x10000) { + return map.indexOf(value); + } + for (const charCode in map) { + if (map[charCode] === value) { + return charCode | 0; + } + } + return -1; + } + amend(map) { + for (const charCode in map) { + this._map[charCode] = map[charCode]; + } + } +} +exports.ToUnicodeMap = ToUnicodeMap; +class IdentityToUnicodeMap { + constructor(firstChar, lastChar) { + this.firstChar = firstChar; + this.lastChar = lastChar; + } + get length() { + return this.lastChar + 1 - this.firstChar; + } + forEach(callback) { + for (let i = this.firstChar, ii = this.lastChar; i <= ii; i++) { + callback(i, i); + } + } + has(i) { + return this.firstChar <= i && i <= this.lastChar; + } + get(i) { + if (this.firstChar <= i && i <= this.lastChar) { + return String.fromCharCode(i); + } + return undefined; + } + charCodeOf(v) { + return Number.isInteger(v) && v >= this.firstChar && v <= this.lastChar ? v : -1; + } + amend(map) { + (0, _util.unreachable)("Should not call amend()"); + } +} +exports.IdentityToUnicodeMap = IdentityToUnicodeMap; + +/***/ }), +/* 43 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.CFFFont = void 0; +var _cff_parser = __w_pdfjs_require__(35); +var _fonts_utils = __w_pdfjs_require__(38); +var _util = __w_pdfjs_require__(2); +class CFFFont { + constructor(file, properties) { + this.properties = properties; + const parser = new _cff_parser.CFFParser(file, properties, _fonts_utils.SEAC_ANALYSIS_ENABLED); + this.cff = parser.parse(); + this.cff.duplicateFirstGlyph(); + const compiler = new _cff_parser.CFFCompiler(this.cff); + this.seacs = this.cff.seacs; + try { + this.data = compiler.compile(); + } catch { + (0, _util.warn)("Failed to compile font " + properties.loadedName); + this.data = file; + } + this._createBuiltInEncoding(); + } + get numGlyphs() { + return this.cff.charStrings.count; + } + getCharset() { + return this.cff.charset.charset; + } + getGlyphMapping() { + const cff = this.cff; + const properties = this.properties; + const { + cidToGidMap, + cMap + } = properties; + const charsets = cff.charset.charset; + let charCodeToGlyphId; + let glyphId; + if (properties.composite) { + let invCidToGidMap; + if (cidToGidMap?.length > 0) { + invCidToGidMap = Object.create(null); + for (let i = 0, ii = cidToGidMap.length; i < ii; i++) { + const gid = cidToGidMap[i]; + if (gid !== undefined) { + invCidToGidMap[gid] = i; + } + } + } + charCodeToGlyphId = Object.create(null); + let charCode; + if (cff.isCIDFont) { + for (glyphId = 0; glyphId < charsets.length; glyphId++) { + const cid = charsets[glyphId]; + charCode = cMap.charCodeOf(cid); + if (invCidToGidMap?.[charCode] !== undefined) { + charCode = invCidToGidMap[charCode]; + } + charCodeToGlyphId[charCode] = glyphId; + } + } else { + for (glyphId = 0; glyphId < cff.charStrings.count; glyphId++) { + charCode = cMap.charCodeOf(glyphId); + charCodeToGlyphId[charCode] = glyphId; + } + } + return charCodeToGlyphId; + } + let encoding = cff.encoding ? cff.encoding.encoding : null; + if (properties.isInternalFont) { + encoding = properties.defaultEncoding; + } + charCodeToGlyphId = (0, _fonts_utils.type1FontGlyphMapping)(properties, encoding, charsets); + return charCodeToGlyphId; + } + hasGlyphId(id) { + return this.cff.hasGlyphId(id); + } + _createBuiltInEncoding() { + const { + charset, + encoding + } = this.cff; + if (!charset || !encoding) { + return; + } + const charsets = charset.charset, + encodings = encoding.encoding; + const map = []; + for (const charCode in encodings) { + const glyphId = encodings[charCode]; + if (glyphId >= 0) { + const glyphName = charsets[glyphId]; + if (glyphName) { + map[charCode] = glyphName; + } + } + } + if (map.length > 0) { + this.properties.builtInEncoding = map; + } + } +} +exports.CFFFont = CFFFont; + +/***/ }), +/* 44 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.FontRendererFactory = void 0; +var _util = __w_pdfjs_require__(2); +var _cff_parser = __w_pdfjs_require__(35); +var _glyphlist = __w_pdfjs_require__(39); +var _encodings = __w_pdfjs_require__(37); +var _stream = __w_pdfjs_require__(8); +function getUint32(data, offset) { + return (data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]) >>> 0; +} +function getUint16(data, offset) { + return data[offset] << 8 | data[offset + 1]; +} +function getInt16(data, offset) { + return (data[offset] << 24 | data[offset + 1] << 16) >> 16; +} +function getInt8(data, offset) { + return data[offset] << 24 >> 24; +} +function getFloat214(data, offset) { + return getInt16(data, offset) / 16384; +} +function getSubroutineBias(subrs) { + const numSubrs = subrs.length; + let bias = 32768; + if (numSubrs < 1240) { + bias = 107; + } else if (numSubrs < 33900) { + bias = 1131; + } + return bias; +} +function parseCmap(data, start, end) { + const offset = getUint16(data, start + 2) === 1 ? getUint32(data, start + 8) : getUint32(data, start + 16); + const format = getUint16(data, start + offset); + let ranges, p, i; + if (format === 4) { + getUint16(data, start + offset + 2); + const segCount = getUint16(data, start + offset + 6) >> 1; + p = start + offset + 14; + ranges = []; + for (i = 0; i < segCount; i++, p += 2) { + ranges[i] = { + end: getUint16(data, p) + }; + } + p += 2; + for (i = 0; i < segCount; i++, p += 2) { + ranges[i].start = getUint16(data, p); + } + for (i = 0; i < segCount; i++, p += 2) { + ranges[i].idDelta = getUint16(data, p); + } + for (i = 0; i < segCount; i++, p += 2) { + let idOffset = getUint16(data, p); + if (idOffset === 0) { + continue; + } + ranges[i].ids = []; + for (let j = 0, jj = ranges[i].end - ranges[i].start + 1; j < jj; j++) { + ranges[i].ids[j] = getUint16(data, p + idOffset); + idOffset += 2; + } + } + return ranges; + } else if (format === 12) { + const groups = getUint32(data, start + offset + 12); + p = start + offset + 16; + ranges = []; + for (i = 0; i < groups; i++) { + start = getUint32(data, p); + ranges.push({ + start, + end: getUint32(data, p + 4), + idDelta: getUint32(data, p + 8) - start + }); + p += 12; + } + return ranges; + } + throw new _util.FormatError(`unsupported cmap: ${format}`); +} +function parseCff(data, start, end, seacAnalysisEnabled) { + const properties = {}; + const parser = new _cff_parser.CFFParser(new _stream.Stream(data, start, end - start), properties, seacAnalysisEnabled); + const cff = parser.parse(); + return { + glyphs: cff.charStrings.objects, + subrs: cff.topDict.privateDict?.subrsIndex?.objects, + gsubrs: cff.globalSubrIndex?.objects, + isCFFCIDFont: cff.isCIDFont, + fdSelect: cff.fdSelect, + fdArray: cff.fdArray + }; +} +function parseGlyfTable(glyf, loca, isGlyphLocationsLong) { + let itemSize, itemDecode; + if (isGlyphLocationsLong) { + itemSize = 4; + itemDecode = getUint32; + } else { + itemSize = 2; + itemDecode = (data, offset) => 2 * getUint16(data, offset); + } + const glyphs = []; + let startOffset = itemDecode(loca, 0); + for (let j = itemSize; j < loca.length; j += itemSize) { + const endOffset = itemDecode(loca, j); + glyphs.push(glyf.subarray(startOffset, endOffset)); + startOffset = endOffset; + } + return glyphs; +} +function lookupCmap(ranges, unicode) { + const code = unicode.codePointAt(0); + let gid = 0, + l = 0, + r = ranges.length - 1; + while (l < r) { + const c = l + r + 1 >> 1; + if (code < ranges[c].start) { + r = c - 1; + } else { + l = c; + } + } + if (ranges[l].start <= code && code <= ranges[l].end) { + gid = ranges[l].idDelta + (ranges[l].ids ? ranges[l].ids[code - ranges[l].start] : code) & 0xffff; + } + return { + charCode: code, + glyphId: gid + }; +} +function compileGlyf(code, cmds, font) { + function moveTo(x, y) { + cmds.push({ + cmd: "moveTo", + args: [x, y] + }); + } + function lineTo(x, y) { + cmds.push({ + cmd: "lineTo", + args: [x, y] + }); + } + function quadraticCurveTo(xa, ya, x, y) { + cmds.push({ + cmd: "quadraticCurveTo", + args: [xa, ya, x, y] + }); + } + let i = 0; + const numberOfContours = getInt16(code, i); + let flags; + let x = 0, + y = 0; + i += 10; + if (numberOfContours < 0) { + do { + flags = getUint16(code, i); + const glyphIndex = getUint16(code, i + 2); + i += 4; + let arg1, arg2; + if (flags & 0x01) { + if (flags & 0x02) { + arg1 = getInt16(code, i); + arg2 = getInt16(code, i + 2); + } else { + arg1 = getUint16(code, i); + arg2 = getUint16(code, i + 2); + } + i += 4; + } else if (flags & 0x02) { + arg1 = getInt8(code, i++); + arg2 = getInt8(code, i++); + } else { + arg1 = code[i++]; + arg2 = code[i++]; + } + if (flags & 0x02) { + x = arg1; + y = arg2; + } else { + x = 0; + y = 0; + } + let scaleX = 1, + scaleY = 1, + scale01 = 0, + scale10 = 0; + if (flags & 0x08) { + scaleX = scaleY = getFloat214(code, i); + i += 2; + } else if (flags & 0x40) { + scaleX = getFloat214(code, i); + scaleY = getFloat214(code, i + 2); + i += 4; + } else if (flags & 0x80) { + scaleX = getFloat214(code, i); + scale01 = getFloat214(code, i + 2); + scale10 = getFloat214(code, i + 4); + scaleY = getFloat214(code, i + 6); + i += 8; + } + const subglyph = font.glyphs[glyphIndex]; + if (subglyph) { + cmds.push({ + cmd: "save" + }, { + cmd: "transform", + args: [scaleX, scale01, scale10, scaleY, x, y] + }); + if (!(flags & 0x02)) {} + compileGlyf(subglyph, cmds, font); + cmds.push({ + cmd: "restore" + }); + } + } while (flags & 0x20); + } else { + const endPtsOfContours = []; + let j, jj; + for (j = 0; j < numberOfContours; j++) { + endPtsOfContours.push(getUint16(code, i)); + i += 2; + } + const instructionLength = getUint16(code, i); + i += 2 + instructionLength; + const numberOfPoints = endPtsOfContours.at(-1) + 1; + const points = []; + while (points.length < numberOfPoints) { + flags = code[i++]; + let repeat = 1; + if (flags & 0x08) { + repeat += code[i++]; + } + while (repeat-- > 0) { + points.push({ + flags + }); + } + } + for (j = 0; j < numberOfPoints; j++) { + switch (points[j].flags & 0x12) { + case 0x00: + x += getInt16(code, i); + i += 2; + break; + case 0x02: + x -= code[i++]; + break; + case 0x12: + x += code[i++]; + break; + } + points[j].x = x; + } + for (j = 0; j < numberOfPoints; j++) { + switch (points[j].flags & 0x24) { + case 0x00: + y += getInt16(code, i); + i += 2; + break; + case 0x04: + y -= code[i++]; + break; + case 0x24: + y += code[i++]; + break; + } + points[j].y = y; + } + let startPoint = 0; + for (i = 0; i < numberOfContours; i++) { + const endPoint = endPtsOfContours[i]; + const contour = points.slice(startPoint, endPoint + 1); + if (contour[0].flags & 1) { + contour.push(contour[0]); + } else if (contour.at(-1).flags & 1) { + contour.unshift(contour.at(-1)); + } else { + const p = { + flags: 1, + x: (contour[0].x + contour.at(-1).x) / 2, + y: (contour[0].y + contour.at(-1).y) / 2 + }; + contour.unshift(p); + contour.push(p); + } + moveTo(contour[0].x, contour[0].y); + for (j = 1, jj = contour.length; j < jj; j++) { + if (contour[j].flags & 1) { + lineTo(contour[j].x, contour[j].y); + } else if (contour[j + 1].flags & 1) { + quadraticCurveTo(contour[j].x, contour[j].y, contour[j + 1].x, contour[j + 1].y); + j++; + } else { + quadraticCurveTo(contour[j].x, contour[j].y, (contour[j].x + contour[j + 1].x) / 2, (contour[j].y + contour[j + 1].y) / 2); + } + } + startPoint = endPoint + 1; + } + } +} +function compileCharString(charStringCode, cmds, font, glyphId) { + function moveTo(x, y) { + cmds.push({ + cmd: "moveTo", + args: [x, y] + }); + } + function lineTo(x, y) { + cmds.push({ + cmd: "lineTo", + args: [x, y] + }); + } + function bezierCurveTo(x1, y1, x2, y2, x, y) { + cmds.push({ + cmd: "bezierCurveTo", + args: [x1, y1, x2, y2, x, y] + }); + } + const stack = []; + let x = 0, + y = 0; + let stems = 0; + function parse(code) { + let i = 0; + while (i < code.length) { + let stackClean = false; + let v = code[i++]; + let xa, xb, ya, yb, y1, y2, y3, n, subrCode; + switch (v) { + case 1: + stems += stack.length >> 1; + stackClean = true; + break; + case 3: + stems += stack.length >> 1; + stackClean = true; + break; + case 4: + y += stack.pop(); + moveTo(x, y); + stackClean = true; + break; + case 5: + while (stack.length > 0) { + x += stack.shift(); + y += stack.shift(); + lineTo(x, y); + } + break; + case 6: + while (stack.length > 0) { + x += stack.shift(); + lineTo(x, y); + if (stack.length === 0) { + break; + } + y += stack.shift(); + lineTo(x, y); + } + break; + case 7: + while (stack.length > 0) { + y += stack.shift(); + lineTo(x, y); + if (stack.length === 0) { + break; + } + x += stack.shift(); + lineTo(x, y); + } + break; + case 8: + while (stack.length > 0) { + xa = x + stack.shift(); + ya = y + stack.shift(); + xb = xa + stack.shift(); + yb = ya + stack.shift(); + x = xb + stack.shift(); + y = yb + stack.shift(); + bezierCurveTo(xa, ya, xb, yb, x, y); + } + break; + case 10: + n = stack.pop(); + subrCode = null; + if (font.isCFFCIDFont) { + const fdIndex = font.fdSelect.getFDIndex(glyphId); + if (fdIndex >= 0 && fdIndex < font.fdArray.length) { + const fontDict = font.fdArray[fdIndex]; + let subrs; + if (fontDict.privateDict?.subrsIndex) { + subrs = fontDict.privateDict.subrsIndex.objects; + } + if (subrs) { + n += getSubroutineBias(subrs); + subrCode = subrs[n]; + } + } else { + (0, _util.warn)("Invalid fd index for glyph index."); + } + } else { + subrCode = font.subrs[n + font.subrsBias]; + } + if (subrCode) { + parse(subrCode); + } + break; + case 11: + return; + case 12: + v = code[i++]; + switch (v) { + case 34: + xa = x + stack.shift(); + xb = xa + stack.shift(); + y1 = y + stack.shift(); + x = xb + stack.shift(); + bezierCurveTo(xa, y, xb, y1, x, y1); + xa = x + stack.shift(); + xb = xa + stack.shift(); + x = xb + stack.shift(); + bezierCurveTo(xa, y1, xb, y, x, y); + break; + case 35: + xa = x + stack.shift(); + ya = y + stack.shift(); + xb = xa + stack.shift(); + yb = ya + stack.shift(); + x = xb + stack.shift(); + y = yb + stack.shift(); + bezierCurveTo(xa, ya, xb, yb, x, y); + xa = x + stack.shift(); + ya = y + stack.shift(); + xb = xa + stack.shift(); + yb = ya + stack.shift(); + x = xb + stack.shift(); + y = yb + stack.shift(); + bezierCurveTo(xa, ya, xb, yb, x, y); + stack.pop(); + break; + case 36: + xa = x + stack.shift(); + y1 = y + stack.shift(); + xb = xa + stack.shift(); + y2 = y1 + stack.shift(); + x = xb + stack.shift(); + bezierCurveTo(xa, y1, xb, y2, x, y2); + xa = x + stack.shift(); + xb = xa + stack.shift(); + y3 = y2 + stack.shift(); + x = xb + stack.shift(); + bezierCurveTo(xa, y2, xb, y3, x, y); + break; + case 37: + const x0 = x, + y0 = y; + xa = x + stack.shift(); + ya = y + stack.shift(); + xb = xa + stack.shift(); + yb = ya + stack.shift(); + x = xb + stack.shift(); + y = yb + stack.shift(); + bezierCurveTo(xa, ya, xb, yb, x, y); + xa = x + stack.shift(); + ya = y + stack.shift(); + xb = xa + stack.shift(); + yb = ya + stack.shift(); + x = xb; + y = yb; + if (Math.abs(x - x0) > Math.abs(y - y0)) { + x += stack.shift(); + } else { + y += stack.shift(); + } + bezierCurveTo(xa, ya, xb, yb, x, y); + break; + default: + throw new _util.FormatError(`unknown operator: 12 ${v}`); + } + break; + case 14: + if (stack.length >= 4) { + const achar = stack.pop(); + const bchar = stack.pop(); + y = stack.pop(); + x = stack.pop(); + cmds.push({ + cmd: "save" + }, { + cmd: "translate", + args: [x, y] + }); + let cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[_encodings.StandardEncoding[achar]])); + compileCharString(font.glyphs[cmap.glyphId], cmds, font, cmap.glyphId); + cmds.push({ + cmd: "restore" + }); + cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[_encodings.StandardEncoding[bchar]])); + compileCharString(font.glyphs[cmap.glyphId], cmds, font, cmap.glyphId); + } + return; + case 18: + stems += stack.length >> 1; + stackClean = true; + break; + case 19: + stems += stack.length >> 1; + i += stems + 7 >> 3; + stackClean = true; + break; + case 20: + stems += stack.length >> 1; + i += stems + 7 >> 3; + stackClean = true; + break; + case 21: + y += stack.pop(); + x += stack.pop(); + moveTo(x, y); + stackClean = true; + break; + case 22: + x += stack.pop(); + moveTo(x, y); + stackClean = true; + break; + case 23: + stems += stack.length >> 1; + stackClean = true; + break; + case 24: + while (stack.length > 2) { + xa = x + stack.shift(); + ya = y + stack.shift(); + xb = xa + stack.shift(); + yb = ya + stack.shift(); + x = xb + stack.shift(); + y = yb + stack.shift(); + bezierCurveTo(xa, ya, xb, yb, x, y); + } + x += stack.shift(); + y += stack.shift(); + lineTo(x, y); + break; + case 25: + while (stack.length > 6) { + x += stack.shift(); + y += stack.shift(); + lineTo(x, y); + } + xa = x + stack.shift(); + ya = y + stack.shift(); + xb = xa + stack.shift(); + yb = ya + stack.shift(); + x = xb + stack.shift(); + y = yb + stack.shift(); + bezierCurveTo(xa, ya, xb, yb, x, y); + break; + case 26: + if (stack.length % 2) { + x += stack.shift(); + } + while (stack.length > 0) { + xa = x; + ya = y + stack.shift(); + xb = xa + stack.shift(); + yb = ya + stack.shift(); + x = xb; + y = yb + stack.shift(); + bezierCurveTo(xa, ya, xb, yb, x, y); + } + break; + case 27: + if (stack.length % 2) { + y += stack.shift(); + } + while (stack.length > 0) { + xa = x + stack.shift(); + ya = y; + xb = xa + stack.shift(); + yb = ya + stack.shift(); + x = xb + stack.shift(); + y = yb; + bezierCurveTo(xa, ya, xb, yb, x, y); + } + break; + case 28: + stack.push((code[i] << 24 | code[i + 1] << 16) >> 16); + i += 2; + break; + case 29: + n = stack.pop() + font.gsubrsBias; + subrCode = font.gsubrs[n]; + if (subrCode) { + parse(subrCode); + } + break; + case 30: + while (stack.length > 0) { + xa = x; + ya = y + stack.shift(); + xb = xa + stack.shift(); + yb = ya + stack.shift(); + x = xb + stack.shift(); + y = yb + (stack.length === 1 ? stack.shift() : 0); + bezierCurveTo(xa, ya, xb, yb, x, y); + if (stack.length === 0) { + break; + } + xa = x + stack.shift(); + ya = y; + xb = xa + stack.shift(); + yb = ya + stack.shift(); + y = yb + stack.shift(); + x = xb + (stack.length === 1 ? stack.shift() : 0); + bezierCurveTo(xa, ya, xb, yb, x, y); + } + break; + case 31: + while (stack.length > 0) { + xa = x + stack.shift(); + ya = y; + xb = xa + stack.shift(); + yb = ya + stack.shift(); + y = yb + stack.shift(); + x = xb + (stack.length === 1 ? stack.shift() : 0); + bezierCurveTo(xa, ya, xb, yb, x, y); + if (stack.length === 0) { + break; + } + xa = x; + ya = y + stack.shift(); + xb = xa + stack.shift(); + yb = ya + stack.shift(); + x = xb + stack.shift(); + y = yb + (stack.length === 1 ? stack.shift() : 0); + bezierCurveTo(xa, ya, xb, yb, x, y); + } + break; + default: + if (v < 32) { + throw new _util.FormatError(`unknown operator: ${v}`); + } + if (v < 247) { + stack.push(v - 139); + } else if (v < 251) { + stack.push((v - 247) * 256 + code[i++] + 108); + } else if (v < 255) { + stack.push(-(v - 251) * 256 - code[i++] - 108); + } else { + stack.push((code[i] << 24 | code[i + 1] << 16 | code[i + 2] << 8 | code[i + 3]) / 65536); + i += 4; + } + break; + } + if (stackClean) { + stack.length = 0; + } + } + } + parse(charStringCode); +} +const NOOP = []; +class CompiledFont { + constructor(fontMatrix) { + if (this.constructor === CompiledFont) { + (0, _util.unreachable)("Cannot initialize CompiledFont."); + } + this.fontMatrix = fontMatrix; + this.compiledGlyphs = Object.create(null); + this.compiledCharCodeToGlyphId = Object.create(null); + } + getPathJs(unicode) { + const { + charCode, + glyphId + } = lookupCmap(this.cmap, unicode); + let fn = this.compiledGlyphs[glyphId]; + if (!fn) { + try { + fn = this.compileGlyph(this.glyphs[glyphId], glyphId); + this.compiledGlyphs[glyphId] = fn; + } catch (ex) { + this.compiledGlyphs[glyphId] = NOOP; + if (this.compiledCharCodeToGlyphId[charCode] === undefined) { + this.compiledCharCodeToGlyphId[charCode] = glyphId; + } + throw ex; + } + } + if (this.compiledCharCodeToGlyphId[charCode] === undefined) { + this.compiledCharCodeToGlyphId[charCode] = glyphId; + } + return fn; + } + compileGlyph(code, glyphId) { + if (!code || code.length === 0 || code[0] === 14) { + return NOOP; + } + let fontMatrix = this.fontMatrix; + if (this.isCFFCIDFont) { + const fdIndex = this.fdSelect.getFDIndex(glyphId); + if (fdIndex >= 0 && fdIndex < this.fdArray.length) { + const fontDict = this.fdArray[fdIndex]; + fontMatrix = fontDict.getByName("FontMatrix") || _util.FONT_IDENTITY_MATRIX; + } else { + (0, _util.warn)("Invalid fd index for glyph index."); + } + } + const cmds = [{ + cmd: "save" + }, { + cmd: "transform", + args: fontMatrix.slice() + }, { + cmd: "scale", + args: ["size", "-size"] + }]; + this.compileGlyphImpl(code, cmds, glyphId); + cmds.push({ + cmd: "restore" + }); + return cmds; + } + compileGlyphImpl() { + (0, _util.unreachable)("Children classes should implement this."); + } + hasBuiltPath(unicode) { + const { + charCode, + glyphId + } = lookupCmap(this.cmap, unicode); + return this.compiledGlyphs[glyphId] !== undefined && this.compiledCharCodeToGlyphId[charCode] !== undefined; + } +} +class TrueTypeCompiled extends CompiledFont { + constructor(glyphs, cmap, fontMatrix) { + super(fontMatrix || [0.000488, 0, 0, 0.000488, 0, 0]); + this.glyphs = glyphs; + this.cmap = cmap; + } + compileGlyphImpl(code, cmds) { + compileGlyf(code, cmds, this); + } +} +class Type2Compiled extends CompiledFont { + constructor(cffInfo, cmap, fontMatrix, glyphNameMap) { + super(fontMatrix || [0.001, 0, 0, 0.001, 0, 0]); + this.glyphs = cffInfo.glyphs; + this.gsubrs = cffInfo.gsubrs || []; + this.subrs = cffInfo.subrs || []; + this.cmap = cmap; + this.glyphNameMap = glyphNameMap || (0, _glyphlist.getGlyphsUnicode)(); + this.gsubrsBias = getSubroutineBias(this.gsubrs); + this.subrsBias = getSubroutineBias(this.subrs); + this.isCFFCIDFont = cffInfo.isCFFCIDFont; + this.fdSelect = cffInfo.fdSelect; + this.fdArray = cffInfo.fdArray; + } + compileGlyphImpl(code, cmds, glyphId) { + compileCharString(code, cmds, this, glyphId); + } +} +class FontRendererFactory { + static create(font, seacAnalysisEnabled) { + const data = new Uint8Array(font.data); + let cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm; + const numTables = getUint16(data, 4); + for (let i = 0, p = 12; i < numTables; i++, p += 16) { + const tag = (0, _util.bytesToString)(data.subarray(p, p + 4)); + const offset = getUint32(data, p + 8); + const length = getUint32(data, p + 12); + switch (tag) { + case "cmap": + cmap = parseCmap(data, offset, offset + length); + break; + case "glyf": + glyf = data.subarray(offset, offset + length); + break; + case "loca": + loca = data.subarray(offset, offset + length); + break; + case "head": + unitsPerEm = getUint16(data, offset + 18); + indexToLocFormat = getUint16(data, offset + 50); + break; + case "CFF ": + cff = parseCff(data, offset, offset + length, seacAnalysisEnabled); + break; + } + } + if (glyf) { + const fontMatrix = !unitsPerEm ? font.fontMatrix : [1 / unitsPerEm, 0, 0, 1 / unitsPerEm, 0, 0]; + return new TrueTypeCompiled(parseGlyfTable(glyf, loca, indexToLocFormat), cmap, fontMatrix); + } + return new Type2Compiled(cff, cmap, font.fontMatrix, font.glyphNameMap); + } +} +exports.FontRendererFactory = FontRendererFactory; + +/***/ }), +/* 45 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getMetrics = exports.getFontBasicMetrics = void 0; +var _core_utils = __w_pdfjs_require__(3); +const getMetrics = (0, _core_utils.getLookupTableFactory)(function (t) { + t.Courier = 600; + t["Courier-Bold"] = 600; + t["Courier-BoldOblique"] = 600; + t["Courier-Oblique"] = 600; + t.Helvetica = (0, _core_utils.getLookupTableFactory)(function (t) { + t.space = 278; + t.exclam = 278; + t.quotedbl = 355; + t.numbersign = 556; + t.dollar = 556; + t.percent = 889; + t.ampersand = 667; + t.quoteright = 222; + t.parenleft = 333; + t.parenright = 333; + t.asterisk = 389; + t.plus = 584; + t.comma = 278; + t.hyphen = 333; + t.period = 278; + t.slash = 278; + t.zero = 556; + t.one = 556; + t.two = 556; + t.three = 556; + t.four = 556; + t.five = 556; + t.six = 556; + t.seven = 556; + t.eight = 556; + t.nine = 556; + t.colon = 278; + t.semicolon = 278; + t.less = 584; + t.equal = 584; + t.greater = 584; + t.question = 556; + t.at = 1015; + t.A = 667; + t.B = 667; + t.C = 722; + t.D = 722; + t.E = 667; + t.F = 611; + t.G = 778; + t.H = 722; + t.I = 278; + t.J = 500; + t.K = 667; + t.L = 556; + t.M = 833; + t.N = 722; + t.O = 778; + t.P = 667; + t.Q = 778; + t.R = 722; + t.S = 667; + t.T = 611; + t.U = 722; + t.V = 667; + t.W = 944; + t.X = 667; + t.Y = 667; + t.Z = 611; + t.bracketleft = 278; + t.backslash = 278; + t.bracketright = 278; + t.asciicircum = 469; + t.underscore = 556; + t.quoteleft = 222; + t.a = 556; + t.b = 556; + t.c = 500; + t.d = 556; + t.e = 556; + t.f = 278; + t.g = 556; + t.h = 556; + t.i = 222; + t.j = 222; + t.k = 500; + t.l = 222; + t.m = 833; + t.n = 556; + t.o = 556; + t.p = 556; + t.q = 556; + t.r = 333; + t.s = 500; + t.t = 278; + t.u = 556; + t.v = 500; + t.w = 722; + t.x = 500; + t.y = 500; + t.z = 500; + t.braceleft = 334; + t.bar = 260; + t.braceright = 334; + t.asciitilde = 584; + t.exclamdown = 333; + t.cent = 556; + t.sterling = 556; + t.fraction = 167; + t.yen = 556; + t.florin = 556; + t.section = 556; + t.currency = 556; + t.quotesingle = 191; + t.quotedblleft = 333; + t.guillemotleft = 556; + t.guilsinglleft = 333; + t.guilsinglright = 333; + t.fi = 500; + t.fl = 500; + t.endash = 556; + t.dagger = 556; + t.daggerdbl = 556; + t.periodcentered = 278; + t.paragraph = 537; + t.bullet = 350; + t.quotesinglbase = 222; + t.quotedblbase = 333; + t.quotedblright = 333; + t.guillemotright = 556; + t.ellipsis = 1000; + t.perthousand = 1000; + t.questiondown = 611; + t.grave = 333; + t.acute = 333; + t.circumflex = 333; + t.tilde = 333; + t.macron = 333; + t.breve = 333; + t.dotaccent = 333; + t.dieresis = 333; + t.ring = 333; + t.cedilla = 333; + t.hungarumlaut = 333; + t.ogonek = 333; + t.caron = 333; + t.emdash = 1000; + t.AE = 1000; + t.ordfeminine = 370; + t.Lslash = 556; + t.Oslash = 778; + t.OE = 1000; + t.ordmasculine = 365; + t.ae = 889; + t.dotlessi = 278; + t.lslash = 222; + t.oslash = 611; + t.oe = 944; + t.germandbls = 611; + t.Idieresis = 278; + t.eacute = 556; + t.abreve = 556; + t.uhungarumlaut = 556; + t.ecaron = 556; + t.Ydieresis = 667; + t.divide = 584; + t.Yacute = 667; + t.Acircumflex = 667; + t.aacute = 556; + t.Ucircumflex = 722; + t.yacute = 500; + t.scommaaccent = 500; + t.ecircumflex = 556; + t.Uring = 722; + t.Udieresis = 722; + t.aogonek = 556; + t.Uacute = 722; + t.uogonek = 556; + t.Edieresis = 667; + t.Dcroat = 722; + t.commaaccent = 250; + t.copyright = 737; + t.Emacron = 667; + t.ccaron = 500; + t.aring = 556; + t.Ncommaaccent = 722; + t.lacute = 222; + t.agrave = 556; + t.Tcommaaccent = 611; + t.Cacute = 722; + t.atilde = 556; + t.Edotaccent = 667; + t.scaron = 500; + t.scedilla = 500; + t.iacute = 278; + t.lozenge = 471; + t.Rcaron = 722; + t.Gcommaaccent = 778; + t.ucircumflex = 556; + t.acircumflex = 556; + t.Amacron = 667; + t.rcaron = 333; + t.ccedilla = 500; + t.Zdotaccent = 611; + t.Thorn = 667; + t.Omacron = 778; + t.Racute = 722; + t.Sacute = 667; + t.dcaron = 643; + t.Umacron = 722; + t.uring = 556; + t.threesuperior = 333; + t.Ograve = 778; + t.Agrave = 667; + t.Abreve = 667; + t.multiply = 584; + t.uacute = 556; + t.Tcaron = 611; + t.partialdiff = 476; + t.ydieresis = 500; + t.Nacute = 722; + t.icircumflex = 278; + t.Ecircumflex = 667; + t.adieresis = 556; + t.edieresis = 556; + t.cacute = 500; + t.nacute = 556; + t.umacron = 556; + t.Ncaron = 722; + t.Iacute = 278; + t.plusminus = 584; + t.brokenbar = 260; + t.registered = 737; + t.Gbreve = 778; + t.Idotaccent = 278; + t.summation = 600; + t.Egrave = 667; + t.racute = 333; + t.omacron = 556; + t.Zacute = 611; + t.Zcaron = 611; + t.greaterequal = 549; + t.Eth = 722; + t.Ccedilla = 722; + t.lcommaaccent = 222; + t.tcaron = 317; + t.eogonek = 556; + t.Uogonek = 722; + t.Aacute = 667; + t.Adieresis = 667; + t.egrave = 556; + t.zacute = 500; + t.iogonek = 222; + t.Oacute = 778; + t.oacute = 556; + t.amacron = 556; + t.sacute = 500; + t.idieresis = 278; + t.Ocircumflex = 778; + t.Ugrave = 722; + t.Delta = 612; + t.thorn = 556; + t.twosuperior = 333; + t.Odieresis = 778; + t.mu = 556; + t.igrave = 278; + t.ohungarumlaut = 556; + t.Eogonek = 667; + t.dcroat = 556; + t.threequarters = 834; + t.Scedilla = 667; + t.lcaron = 299; + t.Kcommaaccent = 667; + t.Lacute = 556; + t.trademark = 1000; + t.edotaccent = 556; + t.Igrave = 278; + t.Imacron = 278; + t.Lcaron = 556; + t.onehalf = 834; + t.lessequal = 549; + t.ocircumflex = 556; + t.ntilde = 556; + t.Uhungarumlaut = 722; + t.Eacute = 667; + t.emacron = 556; + t.gbreve = 556; + t.onequarter = 834; + t.Scaron = 667; + t.Scommaaccent = 667; + t.Ohungarumlaut = 778; + t.degree = 400; + t.ograve = 556; + t.Ccaron = 722; + t.ugrave = 556; + t.radical = 453; + t.Dcaron = 722; + t.rcommaaccent = 333; + t.Ntilde = 722; + t.otilde = 556; + t.Rcommaaccent = 722; + t.Lcommaaccent = 556; + t.Atilde = 667; + t.Aogonek = 667; + t.Aring = 667; + t.Otilde = 778; + t.zdotaccent = 500; + t.Ecaron = 667; + t.Iogonek = 278; + t.kcommaaccent = 500; + t.minus = 584; + t.Icircumflex = 278; + t.ncaron = 556; + t.tcommaaccent = 278; + t.logicalnot = 584; + t.odieresis = 556; + t.udieresis = 556; + t.notequal = 549; + t.gcommaaccent = 556; + t.eth = 556; + t.zcaron = 500; + t.ncommaaccent = 556; + t.onesuperior = 333; + t.imacron = 278; + t.Euro = 556; + }); + t["Helvetica-Bold"] = (0, _core_utils.getLookupTableFactory)(function (t) { + t.space = 278; + t.exclam = 333; + t.quotedbl = 474; + t.numbersign = 556; + t.dollar = 556; + t.percent = 889; + t.ampersand = 722; + t.quoteright = 278; + t.parenleft = 333; + t.parenright = 333; + t.asterisk = 389; + t.plus = 584; + t.comma = 278; + t.hyphen = 333; + t.period = 278; + t.slash = 278; + t.zero = 556; + t.one = 556; + t.two = 556; + t.three = 556; + t.four = 556; + t.five = 556; + t.six = 556; + t.seven = 556; + t.eight = 556; + t.nine = 556; + t.colon = 333; + t.semicolon = 333; + t.less = 584; + t.equal = 584; + t.greater = 584; + t.question = 611; + t.at = 975; + t.A = 722; + t.B = 722; + t.C = 722; + t.D = 722; + t.E = 667; + t.F = 611; + t.G = 778; + t.H = 722; + t.I = 278; + t.J = 556; + t.K = 722; + t.L = 611; + t.M = 833; + t.N = 722; + t.O = 778; + t.P = 667; + t.Q = 778; + t.R = 722; + t.S = 667; + t.T = 611; + t.U = 722; + t.V = 667; + t.W = 944; + t.X = 667; + t.Y = 667; + t.Z = 611; + t.bracketleft = 333; + t.backslash = 278; + t.bracketright = 333; + t.asciicircum = 584; + t.underscore = 556; + t.quoteleft = 278; + t.a = 556; + t.b = 611; + t.c = 556; + t.d = 611; + t.e = 556; + t.f = 333; + t.g = 611; + t.h = 611; + t.i = 278; + t.j = 278; + t.k = 556; + t.l = 278; + t.m = 889; + t.n = 611; + t.o = 611; + t.p = 611; + t.q = 611; + t.r = 389; + t.s = 556; + t.t = 333; + t.u = 611; + t.v = 556; + t.w = 778; + t.x = 556; + t.y = 556; + t.z = 500; + t.braceleft = 389; + t.bar = 280; + t.braceright = 389; + t.asciitilde = 584; + t.exclamdown = 333; + t.cent = 556; + t.sterling = 556; + t.fraction = 167; + t.yen = 556; + t.florin = 556; + t.section = 556; + t.currency = 556; + t.quotesingle = 238; + t.quotedblleft = 500; + t.guillemotleft = 556; + t.guilsinglleft = 333; + t.guilsinglright = 333; + t.fi = 611; + t.fl = 611; + t.endash = 556; + t.dagger = 556; + t.daggerdbl = 556; + t.periodcentered = 278; + t.paragraph = 556; + t.bullet = 350; + t.quotesinglbase = 278; + t.quotedblbase = 500; + t.quotedblright = 500; + t.guillemotright = 556; + t.ellipsis = 1000; + t.perthousand = 1000; + t.questiondown = 611; + t.grave = 333; + t.acute = 333; + t.circumflex = 333; + t.tilde = 333; + t.macron = 333; + t.breve = 333; + t.dotaccent = 333; + t.dieresis = 333; + t.ring = 333; + t.cedilla = 333; + t.hungarumlaut = 333; + t.ogonek = 333; + t.caron = 333; + t.emdash = 1000; + t.AE = 1000; + t.ordfeminine = 370; + t.Lslash = 611; + t.Oslash = 778; + t.OE = 1000; + t.ordmasculine = 365; + t.ae = 889; + t.dotlessi = 278; + t.lslash = 278; + t.oslash = 611; + t.oe = 944; + t.germandbls = 611; + t.Idieresis = 278; + t.eacute = 556; + t.abreve = 556; + t.uhungarumlaut = 611; + t.ecaron = 556; + t.Ydieresis = 667; + t.divide = 584; + t.Yacute = 667; + t.Acircumflex = 722; + t.aacute = 556; + t.Ucircumflex = 722; + t.yacute = 556; + t.scommaaccent = 556; + t.ecircumflex = 556; + t.Uring = 722; + t.Udieresis = 722; + t.aogonek = 556; + t.Uacute = 722; + t.uogonek = 611; + t.Edieresis = 667; + t.Dcroat = 722; + t.commaaccent = 250; + t.copyright = 737; + t.Emacron = 667; + t.ccaron = 556; + t.aring = 556; + t.Ncommaaccent = 722; + t.lacute = 278; + t.agrave = 556; + t.Tcommaaccent = 611; + t.Cacute = 722; + t.atilde = 556; + t.Edotaccent = 667; + t.scaron = 556; + t.scedilla = 556; + t.iacute = 278; + t.lozenge = 494; + t.Rcaron = 722; + t.Gcommaaccent = 778; + t.ucircumflex = 611; + t.acircumflex = 556; + t.Amacron = 722; + t.rcaron = 389; + t.ccedilla = 556; + t.Zdotaccent = 611; + t.Thorn = 667; + t.Omacron = 778; + t.Racute = 722; + t.Sacute = 667; + t.dcaron = 743; + t.Umacron = 722; + t.uring = 611; + t.threesuperior = 333; + t.Ograve = 778; + t.Agrave = 722; + t.Abreve = 722; + t.multiply = 584; + t.uacute = 611; + t.Tcaron = 611; + t.partialdiff = 494; + t.ydieresis = 556; + t.Nacute = 722; + t.icircumflex = 278; + t.Ecircumflex = 667; + t.adieresis = 556; + t.edieresis = 556; + t.cacute = 556; + t.nacute = 611; + t.umacron = 611; + t.Ncaron = 722; + t.Iacute = 278; + t.plusminus = 584; + t.brokenbar = 280; + t.registered = 737; + t.Gbreve = 778; + t.Idotaccent = 278; + t.summation = 600; + t.Egrave = 667; + t.racute = 389; + t.omacron = 611; + t.Zacute = 611; + t.Zcaron = 611; + t.greaterequal = 549; + t.Eth = 722; + t.Ccedilla = 722; + t.lcommaaccent = 278; + t.tcaron = 389; + t.eogonek = 556; + t.Uogonek = 722; + t.Aacute = 722; + t.Adieresis = 722; + t.egrave = 556; + t.zacute = 500; + t.iogonek = 278; + t.Oacute = 778; + t.oacute = 611; + t.amacron = 556; + t.sacute = 556; + t.idieresis = 278; + t.Ocircumflex = 778; + t.Ugrave = 722; + t.Delta = 612; + t.thorn = 611; + t.twosuperior = 333; + t.Odieresis = 778; + t.mu = 611; + t.igrave = 278; + t.ohungarumlaut = 611; + t.Eogonek = 667; + t.dcroat = 611; + t.threequarters = 834; + t.Scedilla = 667; + t.lcaron = 400; + t.Kcommaaccent = 722; + t.Lacute = 611; + t.trademark = 1000; + t.edotaccent = 556; + t.Igrave = 278; + t.Imacron = 278; + t.Lcaron = 611; + t.onehalf = 834; + t.lessequal = 549; + t.ocircumflex = 611; + t.ntilde = 611; + t.Uhungarumlaut = 722; + t.Eacute = 667; + t.emacron = 556; + t.gbreve = 611; + t.onequarter = 834; + t.Scaron = 667; + t.Scommaaccent = 667; + t.Ohungarumlaut = 778; + t.degree = 400; + t.ograve = 611; + t.Ccaron = 722; + t.ugrave = 611; + t.radical = 549; + t.Dcaron = 722; + t.rcommaaccent = 389; + t.Ntilde = 722; + t.otilde = 611; + t.Rcommaaccent = 722; + t.Lcommaaccent = 611; + t.Atilde = 722; + t.Aogonek = 722; + t.Aring = 722; + t.Otilde = 778; + t.zdotaccent = 500; + t.Ecaron = 667; + t.Iogonek = 278; + t.kcommaaccent = 556; + t.minus = 584; + t.Icircumflex = 278; + t.ncaron = 611; + t.tcommaaccent = 333; + t.logicalnot = 584; + t.odieresis = 611; + t.udieresis = 611; + t.notequal = 549; + t.gcommaaccent = 611; + t.eth = 611; + t.zcaron = 500; + t.ncommaaccent = 611; + t.onesuperior = 333; + t.imacron = 278; + t.Euro = 556; + }); + t["Helvetica-BoldOblique"] = (0, _core_utils.getLookupTableFactory)(function (t) { + t.space = 278; + t.exclam = 333; + t.quotedbl = 474; + t.numbersign = 556; + t.dollar = 556; + t.percent = 889; + t.ampersand = 722; + t.quoteright = 278; + t.parenleft = 333; + t.parenright = 333; + t.asterisk = 389; + t.plus = 584; + t.comma = 278; + t.hyphen = 333; + t.period = 278; + t.slash = 278; + t.zero = 556; + t.one = 556; + t.two = 556; + t.three = 556; + t.four = 556; + t.five = 556; + t.six = 556; + t.seven = 556; + t.eight = 556; + t.nine = 556; + t.colon = 333; + t.semicolon = 333; + t.less = 584; + t.equal = 584; + t.greater = 584; + t.question = 611; + t.at = 975; + t.A = 722; + t.B = 722; + t.C = 722; + t.D = 722; + t.E = 667; + t.F = 611; + t.G = 778; + t.H = 722; + t.I = 278; + t.J = 556; + t.K = 722; + t.L = 611; + t.M = 833; + t.N = 722; + t.O = 778; + t.P = 667; + t.Q = 778; + t.R = 722; + t.S = 667; + t.T = 611; + t.U = 722; + t.V = 667; + t.W = 944; + t.X = 667; + t.Y = 667; + t.Z = 611; + t.bracketleft = 333; + t.backslash = 278; + t.bracketright = 333; + t.asciicircum = 584; + t.underscore = 556; + t.quoteleft = 278; + t.a = 556; + t.b = 611; + t.c = 556; + t.d = 611; + t.e = 556; + t.f = 333; + t.g = 611; + t.h = 611; + t.i = 278; + t.j = 278; + t.k = 556; + t.l = 278; + t.m = 889; + t.n = 611; + t.o = 611; + t.p = 611; + t.q = 611; + t.r = 389; + t.s = 556; + t.t = 333; + t.u = 611; + t.v = 556; + t.w = 778; + t.x = 556; + t.y = 556; + t.z = 500; + t.braceleft = 389; + t.bar = 280; + t.braceright = 389; + t.asciitilde = 584; + t.exclamdown = 333; + t.cent = 556; + t.sterling = 556; + t.fraction = 167; + t.yen = 556; + t.florin = 556; + t.section = 556; + t.currency = 556; + t.quotesingle = 238; + t.quotedblleft = 500; + t.guillemotleft = 556; + t.guilsinglleft = 333; + t.guilsinglright = 333; + t.fi = 611; + t.fl = 611; + t.endash = 556; + t.dagger = 556; + t.daggerdbl = 556; + t.periodcentered = 278; + t.paragraph = 556; + t.bullet = 350; + t.quotesinglbase = 278; + t.quotedblbase = 500; + t.quotedblright = 500; + t.guillemotright = 556; + t.ellipsis = 1000; + t.perthousand = 1000; + t.questiondown = 611; + t.grave = 333; + t.acute = 333; + t.circumflex = 333; + t.tilde = 333; + t.macron = 333; + t.breve = 333; + t.dotaccent = 333; + t.dieresis = 333; + t.ring = 333; + t.cedilla = 333; + t.hungarumlaut = 333; + t.ogonek = 333; + t.caron = 333; + t.emdash = 1000; + t.AE = 1000; + t.ordfeminine = 370; + t.Lslash = 611; + t.Oslash = 778; + t.OE = 1000; + t.ordmasculine = 365; + t.ae = 889; + t.dotlessi = 278; + t.lslash = 278; + t.oslash = 611; + t.oe = 944; + t.germandbls = 611; + t.Idieresis = 278; + t.eacute = 556; + t.abreve = 556; + t.uhungarumlaut = 611; + t.ecaron = 556; + t.Ydieresis = 667; + t.divide = 584; + t.Yacute = 667; + t.Acircumflex = 722; + t.aacute = 556; + t.Ucircumflex = 722; + t.yacute = 556; + t.scommaaccent = 556; + t.ecircumflex = 556; + t.Uring = 722; + t.Udieresis = 722; + t.aogonek = 556; + t.Uacute = 722; + t.uogonek = 611; + t.Edieresis = 667; + t.Dcroat = 722; + t.commaaccent = 250; + t.copyright = 737; + t.Emacron = 667; + t.ccaron = 556; + t.aring = 556; + t.Ncommaaccent = 722; + t.lacute = 278; + t.agrave = 556; + t.Tcommaaccent = 611; + t.Cacute = 722; + t.atilde = 556; + t.Edotaccent = 667; + t.scaron = 556; + t.scedilla = 556; + t.iacute = 278; + t.lozenge = 494; + t.Rcaron = 722; + t.Gcommaaccent = 778; + t.ucircumflex = 611; + t.acircumflex = 556; + t.Amacron = 722; + t.rcaron = 389; + t.ccedilla = 556; + t.Zdotaccent = 611; + t.Thorn = 667; + t.Omacron = 778; + t.Racute = 722; + t.Sacute = 667; + t.dcaron = 743; + t.Umacron = 722; + t.uring = 611; + t.threesuperior = 333; + t.Ograve = 778; + t.Agrave = 722; + t.Abreve = 722; + t.multiply = 584; + t.uacute = 611; + t.Tcaron = 611; + t.partialdiff = 494; + t.ydieresis = 556; + t.Nacute = 722; + t.icircumflex = 278; + t.Ecircumflex = 667; + t.adieresis = 556; + t.edieresis = 556; + t.cacute = 556; + t.nacute = 611; + t.umacron = 611; + t.Ncaron = 722; + t.Iacute = 278; + t.plusminus = 584; + t.brokenbar = 280; + t.registered = 737; + t.Gbreve = 778; + t.Idotaccent = 278; + t.summation = 600; + t.Egrave = 667; + t.racute = 389; + t.omacron = 611; + t.Zacute = 611; + t.Zcaron = 611; + t.greaterequal = 549; + t.Eth = 722; + t.Ccedilla = 722; + t.lcommaaccent = 278; + t.tcaron = 389; + t.eogonek = 556; + t.Uogonek = 722; + t.Aacute = 722; + t.Adieresis = 722; + t.egrave = 556; + t.zacute = 500; + t.iogonek = 278; + t.Oacute = 778; + t.oacute = 611; + t.amacron = 556; + t.sacute = 556; + t.idieresis = 278; + t.Ocircumflex = 778; + t.Ugrave = 722; + t.Delta = 612; + t.thorn = 611; + t.twosuperior = 333; + t.Odieresis = 778; + t.mu = 611; + t.igrave = 278; + t.ohungarumlaut = 611; + t.Eogonek = 667; + t.dcroat = 611; + t.threequarters = 834; + t.Scedilla = 667; + t.lcaron = 400; + t.Kcommaaccent = 722; + t.Lacute = 611; + t.trademark = 1000; + t.edotaccent = 556; + t.Igrave = 278; + t.Imacron = 278; + t.Lcaron = 611; + t.onehalf = 834; + t.lessequal = 549; + t.ocircumflex = 611; + t.ntilde = 611; + t.Uhungarumlaut = 722; + t.Eacute = 667; + t.emacron = 556; + t.gbreve = 611; + t.onequarter = 834; + t.Scaron = 667; + t.Scommaaccent = 667; + t.Ohungarumlaut = 778; + t.degree = 400; + t.ograve = 611; + t.Ccaron = 722; + t.ugrave = 611; + t.radical = 549; + t.Dcaron = 722; + t.rcommaaccent = 389; + t.Ntilde = 722; + t.otilde = 611; + t.Rcommaaccent = 722; + t.Lcommaaccent = 611; + t.Atilde = 722; + t.Aogonek = 722; + t.Aring = 722; + t.Otilde = 778; + t.zdotaccent = 500; + t.Ecaron = 667; + t.Iogonek = 278; + t.kcommaaccent = 556; + t.minus = 584; + t.Icircumflex = 278; + t.ncaron = 611; + t.tcommaaccent = 333; + t.logicalnot = 584; + t.odieresis = 611; + t.udieresis = 611; + t.notequal = 549; + t.gcommaaccent = 611; + t.eth = 611; + t.zcaron = 500; + t.ncommaaccent = 611; + t.onesuperior = 333; + t.imacron = 278; + t.Euro = 556; + }); + t["Helvetica-Oblique"] = (0, _core_utils.getLookupTableFactory)(function (t) { + t.space = 278; + t.exclam = 278; + t.quotedbl = 355; + t.numbersign = 556; + t.dollar = 556; + t.percent = 889; + t.ampersand = 667; + t.quoteright = 222; + t.parenleft = 333; + t.parenright = 333; + t.asterisk = 389; + t.plus = 584; + t.comma = 278; + t.hyphen = 333; + t.period = 278; + t.slash = 278; + t.zero = 556; + t.one = 556; + t.two = 556; + t.three = 556; + t.four = 556; + t.five = 556; + t.six = 556; + t.seven = 556; + t.eight = 556; + t.nine = 556; + t.colon = 278; + t.semicolon = 278; + t.less = 584; + t.equal = 584; + t.greater = 584; + t.question = 556; + t.at = 1015; + t.A = 667; + t.B = 667; + t.C = 722; + t.D = 722; + t.E = 667; + t.F = 611; + t.G = 778; + t.H = 722; + t.I = 278; + t.J = 500; + t.K = 667; + t.L = 556; + t.M = 833; + t.N = 722; + t.O = 778; + t.P = 667; + t.Q = 778; + t.R = 722; + t.S = 667; + t.T = 611; + t.U = 722; + t.V = 667; + t.W = 944; + t.X = 667; + t.Y = 667; + t.Z = 611; + t.bracketleft = 278; + t.backslash = 278; + t.bracketright = 278; + t.asciicircum = 469; + t.underscore = 556; + t.quoteleft = 222; + t.a = 556; + t.b = 556; + t.c = 500; + t.d = 556; + t.e = 556; + t.f = 278; + t.g = 556; + t.h = 556; + t.i = 222; + t.j = 222; + t.k = 500; + t.l = 222; + t.m = 833; + t.n = 556; + t.o = 556; + t.p = 556; + t.q = 556; + t.r = 333; + t.s = 500; + t.t = 278; + t.u = 556; + t.v = 500; + t.w = 722; + t.x = 500; + t.y = 500; + t.z = 500; + t.braceleft = 334; + t.bar = 260; + t.braceright = 334; + t.asciitilde = 584; + t.exclamdown = 333; + t.cent = 556; + t.sterling = 556; + t.fraction = 167; + t.yen = 556; + t.florin = 556; + t.section = 556; + t.currency = 556; + t.quotesingle = 191; + t.quotedblleft = 333; + t.guillemotleft = 556; + t.guilsinglleft = 333; + t.guilsinglright = 333; + t.fi = 500; + t.fl = 500; + t.endash = 556; + t.dagger = 556; + t.daggerdbl = 556; + t.periodcentered = 278; + t.paragraph = 537; + t.bullet = 350; + t.quotesinglbase = 222; + t.quotedblbase = 333; + t.quotedblright = 333; + t.guillemotright = 556; + t.ellipsis = 1000; + t.perthousand = 1000; + t.questiondown = 611; + t.grave = 333; + t.acute = 333; + t.circumflex = 333; + t.tilde = 333; + t.macron = 333; + t.breve = 333; + t.dotaccent = 333; + t.dieresis = 333; + t.ring = 333; + t.cedilla = 333; + t.hungarumlaut = 333; + t.ogonek = 333; + t.caron = 333; + t.emdash = 1000; + t.AE = 1000; + t.ordfeminine = 370; + t.Lslash = 556; + t.Oslash = 778; + t.OE = 1000; + t.ordmasculine = 365; + t.ae = 889; + t.dotlessi = 278; + t.lslash = 222; + t.oslash = 611; + t.oe = 944; + t.germandbls = 611; + t.Idieresis = 278; + t.eacute = 556; + t.abreve = 556; + t.uhungarumlaut = 556; + t.ecaron = 556; + t.Ydieresis = 667; + t.divide = 584; + t.Yacute = 667; + t.Acircumflex = 667; + t.aacute = 556; + t.Ucircumflex = 722; + t.yacute = 500; + t.scommaaccent = 500; + t.ecircumflex = 556; + t.Uring = 722; + t.Udieresis = 722; + t.aogonek = 556; + t.Uacute = 722; + t.uogonek = 556; + t.Edieresis = 667; + t.Dcroat = 722; + t.commaaccent = 250; + t.copyright = 737; + t.Emacron = 667; + t.ccaron = 500; + t.aring = 556; + t.Ncommaaccent = 722; + t.lacute = 222; + t.agrave = 556; + t.Tcommaaccent = 611; + t.Cacute = 722; + t.atilde = 556; + t.Edotaccent = 667; + t.scaron = 500; + t.scedilla = 500; + t.iacute = 278; + t.lozenge = 471; + t.Rcaron = 722; + t.Gcommaaccent = 778; + t.ucircumflex = 556; + t.acircumflex = 556; + t.Amacron = 667; + t.rcaron = 333; + t.ccedilla = 500; + t.Zdotaccent = 611; + t.Thorn = 667; + t.Omacron = 778; + t.Racute = 722; + t.Sacute = 667; + t.dcaron = 643; + t.Umacron = 722; + t.uring = 556; + t.threesuperior = 333; + t.Ograve = 778; + t.Agrave = 667; + t.Abreve = 667; + t.multiply = 584; + t.uacute = 556; + t.Tcaron = 611; + t.partialdiff = 476; + t.ydieresis = 500; + t.Nacute = 722; + t.icircumflex = 278; + t.Ecircumflex = 667; + t.adieresis = 556; + t.edieresis = 556; + t.cacute = 500; + t.nacute = 556; + t.umacron = 556; + t.Ncaron = 722; + t.Iacute = 278; + t.plusminus = 584; + t.brokenbar = 260; + t.registered = 737; + t.Gbreve = 778; + t.Idotaccent = 278; + t.summation = 600; + t.Egrave = 667; + t.racute = 333; + t.omacron = 556; + t.Zacute = 611; + t.Zcaron = 611; + t.greaterequal = 549; + t.Eth = 722; + t.Ccedilla = 722; + t.lcommaaccent = 222; + t.tcaron = 317; + t.eogonek = 556; + t.Uogonek = 722; + t.Aacute = 667; + t.Adieresis = 667; + t.egrave = 556; + t.zacute = 500; + t.iogonek = 222; + t.Oacute = 778; + t.oacute = 556; + t.amacron = 556; + t.sacute = 500; + t.idieresis = 278; + t.Ocircumflex = 778; + t.Ugrave = 722; + t.Delta = 612; + t.thorn = 556; + t.twosuperior = 333; + t.Odieresis = 778; + t.mu = 556; + t.igrave = 278; + t.ohungarumlaut = 556; + t.Eogonek = 667; + t.dcroat = 556; + t.threequarters = 834; + t.Scedilla = 667; + t.lcaron = 299; + t.Kcommaaccent = 667; + t.Lacute = 556; + t.trademark = 1000; + t.edotaccent = 556; + t.Igrave = 278; + t.Imacron = 278; + t.Lcaron = 556; + t.onehalf = 834; + t.lessequal = 549; + t.ocircumflex = 556; + t.ntilde = 556; + t.Uhungarumlaut = 722; + t.Eacute = 667; + t.emacron = 556; + t.gbreve = 556; + t.onequarter = 834; + t.Scaron = 667; + t.Scommaaccent = 667; + t.Ohungarumlaut = 778; + t.degree = 400; + t.ograve = 556; + t.Ccaron = 722; + t.ugrave = 556; + t.radical = 453; + t.Dcaron = 722; + t.rcommaaccent = 333; + t.Ntilde = 722; + t.otilde = 556; + t.Rcommaaccent = 722; + t.Lcommaaccent = 556; + t.Atilde = 667; + t.Aogonek = 667; + t.Aring = 667; + t.Otilde = 778; + t.zdotaccent = 500; + t.Ecaron = 667; + t.Iogonek = 278; + t.kcommaaccent = 500; + t.minus = 584; + t.Icircumflex = 278; + t.ncaron = 556; + t.tcommaaccent = 278; + t.logicalnot = 584; + t.odieresis = 556; + t.udieresis = 556; + t.notequal = 549; + t.gcommaaccent = 556; + t.eth = 556; + t.zcaron = 500; + t.ncommaaccent = 556; + t.onesuperior = 333; + t.imacron = 278; + t.Euro = 556; + }); + t.Symbol = (0, _core_utils.getLookupTableFactory)(function (t) { + t.space = 250; + t.exclam = 333; + t.universal = 713; + t.numbersign = 500; + t.existential = 549; + t.percent = 833; + t.ampersand = 778; + t.suchthat = 439; + t.parenleft = 333; + t.parenright = 333; + t.asteriskmath = 500; + t.plus = 549; + t.comma = 250; + t.minus = 549; + t.period = 250; + t.slash = 278; + t.zero = 500; + t.one = 500; + t.two = 500; + t.three = 500; + t.four = 500; + t.five = 500; + t.six = 500; + t.seven = 500; + t.eight = 500; + t.nine = 500; + t.colon = 278; + t.semicolon = 278; + t.less = 549; + t.equal = 549; + t.greater = 549; + t.question = 444; + t.congruent = 549; + t.Alpha = 722; + t.Beta = 667; + t.Chi = 722; + t.Delta = 612; + t.Epsilon = 611; + t.Phi = 763; + t.Gamma = 603; + t.Eta = 722; + t.Iota = 333; + t.theta1 = 631; + t.Kappa = 722; + t.Lambda = 686; + t.Mu = 889; + t.Nu = 722; + t.Omicron = 722; + t.Pi = 768; + t.Theta = 741; + t.Rho = 556; + t.Sigma = 592; + t.Tau = 611; + t.Upsilon = 690; + t.sigma1 = 439; + t.Omega = 768; + t.Xi = 645; + t.Psi = 795; + t.Zeta = 611; + t.bracketleft = 333; + t.therefore = 863; + t.bracketright = 333; + t.perpendicular = 658; + t.underscore = 500; + t.radicalex = 500; + t.alpha = 631; + t.beta = 549; + t.chi = 549; + t.delta = 494; + t.epsilon = 439; + t.phi = 521; + t.gamma = 411; + t.eta = 603; + t.iota = 329; + t.phi1 = 603; + t.kappa = 549; + t.lambda = 549; + t.mu = 576; + t.nu = 521; + t.omicron = 549; + t.pi = 549; + t.theta = 521; + t.rho = 549; + t.sigma = 603; + t.tau = 439; + t.upsilon = 576; + t.omega1 = 713; + t.omega = 686; + t.xi = 493; + t.psi = 686; + t.zeta = 494; + t.braceleft = 480; + t.bar = 200; + t.braceright = 480; + t.similar = 549; + t.Euro = 750; + t.Upsilon1 = 620; + t.minute = 247; + t.lessequal = 549; + t.fraction = 167; + t.infinity = 713; + t.florin = 500; + t.club = 753; + t.diamond = 753; + t.heart = 753; + t.spade = 753; + t.arrowboth = 1042; + t.arrowleft = 987; + t.arrowup = 603; + t.arrowright = 987; + t.arrowdown = 603; + t.degree = 400; + t.plusminus = 549; + t.second = 411; + t.greaterequal = 549; + t.multiply = 549; + t.proportional = 713; + t.partialdiff = 494; + t.bullet = 460; + t.divide = 549; + t.notequal = 549; + t.equivalence = 549; + t.approxequal = 549; + t.ellipsis = 1000; + t.arrowvertex = 603; + t.arrowhorizex = 1000; + t.carriagereturn = 658; + t.aleph = 823; + t.Ifraktur = 686; + t.Rfraktur = 795; + t.weierstrass = 987; + t.circlemultiply = 768; + t.circleplus = 768; + t.emptyset = 823; + t.intersection = 768; + t.union = 768; + t.propersuperset = 713; + t.reflexsuperset = 713; + t.notsubset = 713; + t.propersubset = 713; + t.reflexsubset = 713; + t.element = 713; + t.notelement = 713; + t.angle = 768; + t.gradient = 713; + t.registerserif = 790; + t.copyrightserif = 790; + t.trademarkserif = 890; + t.product = 823; + t.radical = 549; + t.dotmath = 250; + t.logicalnot = 713; + t.logicaland = 603; + t.logicalor = 603; + t.arrowdblboth = 1042; + t.arrowdblleft = 987; + t.arrowdblup = 603; + t.arrowdblright = 987; + t.arrowdbldown = 603; + t.lozenge = 494; + t.angleleft = 329; + t.registersans = 790; + t.copyrightsans = 790; + t.trademarksans = 786; + t.summation = 713; + t.parenlefttp = 384; + t.parenleftex = 384; + t.parenleftbt = 384; + t.bracketlefttp = 384; + t.bracketleftex = 384; + t.bracketleftbt = 384; + t.bracelefttp = 494; + t.braceleftmid = 494; + t.braceleftbt = 494; + t.braceex = 494; + t.angleright = 329; + t.integral = 274; + t.integraltp = 686; + t.integralex = 686; + t.integralbt = 686; + t.parenrighttp = 384; + t.parenrightex = 384; + t.parenrightbt = 384; + t.bracketrighttp = 384; + t.bracketrightex = 384; + t.bracketrightbt = 384; + t.bracerighttp = 494; + t.bracerightmid = 494; + t.bracerightbt = 494; + t.apple = 790; + }); + t["Times-Roman"] = (0, _core_utils.getLookupTableFactory)(function (t) { + t.space = 250; + t.exclam = 333; + t.quotedbl = 408; + t.numbersign = 500; + t.dollar = 500; + t.percent = 833; + t.ampersand = 778; + t.quoteright = 333; + t.parenleft = 333; + t.parenright = 333; + t.asterisk = 500; + t.plus = 564; + t.comma = 250; + t.hyphen = 333; + t.period = 250; + t.slash = 278; + t.zero = 500; + t.one = 500; + t.two = 500; + t.three = 500; + t.four = 500; + t.five = 500; + t.six = 500; + t.seven = 500; + t.eight = 500; + t.nine = 500; + t.colon = 278; + t.semicolon = 278; + t.less = 564; + t.equal = 564; + t.greater = 564; + t.question = 444; + t.at = 921; + t.A = 722; + t.B = 667; + t.C = 667; + t.D = 722; + t.E = 611; + t.F = 556; + t.G = 722; + t.H = 722; + t.I = 333; + t.J = 389; + t.K = 722; + t.L = 611; + t.M = 889; + t.N = 722; + t.O = 722; + t.P = 556; + t.Q = 722; + t.R = 667; + t.S = 556; + t.T = 611; + t.U = 722; + t.V = 722; + t.W = 944; + t.X = 722; + t.Y = 722; + t.Z = 611; + t.bracketleft = 333; + t.backslash = 278; + t.bracketright = 333; + t.asciicircum = 469; + t.underscore = 500; + t.quoteleft = 333; + t.a = 444; + t.b = 500; + t.c = 444; + t.d = 500; + t.e = 444; + t.f = 333; + t.g = 500; + t.h = 500; + t.i = 278; + t.j = 278; + t.k = 500; + t.l = 278; + t.m = 778; + t.n = 500; + t.o = 500; + t.p = 500; + t.q = 500; + t.r = 333; + t.s = 389; + t.t = 278; + t.u = 500; + t.v = 500; + t.w = 722; + t.x = 500; + t.y = 500; + t.z = 444; + t.braceleft = 480; + t.bar = 200; + t.braceright = 480; + t.asciitilde = 541; + t.exclamdown = 333; + t.cent = 500; + t.sterling = 500; + t.fraction = 167; + t.yen = 500; + t.florin = 500; + t.section = 500; + t.currency = 500; + t.quotesingle = 180; + t.quotedblleft = 444; + t.guillemotleft = 500; + t.guilsinglleft = 333; + t.guilsinglright = 333; + t.fi = 556; + t.fl = 556; + t.endash = 500; + t.dagger = 500; + t.daggerdbl = 500; + t.periodcentered = 250; + t.paragraph = 453; + t.bullet = 350; + t.quotesinglbase = 333; + t.quotedblbase = 444; + t.quotedblright = 444; + t.guillemotright = 500; + t.ellipsis = 1000; + t.perthousand = 1000; + t.questiondown = 444; + t.grave = 333; + t.acute = 333; + t.circumflex = 333; + t.tilde = 333; + t.macron = 333; + t.breve = 333; + t.dotaccent = 333; + t.dieresis = 333; + t.ring = 333; + t.cedilla = 333; + t.hungarumlaut = 333; + t.ogonek = 333; + t.caron = 333; + t.emdash = 1000; + t.AE = 889; + t.ordfeminine = 276; + t.Lslash = 611; + t.Oslash = 722; + t.OE = 889; + t.ordmasculine = 310; + t.ae = 667; + t.dotlessi = 278; + t.lslash = 278; + t.oslash = 500; + t.oe = 722; + t.germandbls = 500; + t.Idieresis = 333; + t.eacute = 444; + t.abreve = 444; + t.uhungarumlaut = 500; + t.ecaron = 444; + t.Ydieresis = 722; + t.divide = 564; + t.Yacute = 722; + t.Acircumflex = 722; + t.aacute = 444; + t.Ucircumflex = 722; + t.yacute = 500; + t.scommaaccent = 389; + t.ecircumflex = 444; + t.Uring = 722; + t.Udieresis = 722; + t.aogonek = 444; + t.Uacute = 722; + t.uogonek = 500; + t.Edieresis = 611; + t.Dcroat = 722; + t.commaaccent = 250; + t.copyright = 760; + t.Emacron = 611; + t.ccaron = 444; + t.aring = 444; + t.Ncommaaccent = 722; + t.lacute = 278; + t.agrave = 444; + t.Tcommaaccent = 611; + t.Cacute = 667; + t.atilde = 444; + t.Edotaccent = 611; + t.scaron = 389; + t.scedilla = 389; + t.iacute = 278; + t.lozenge = 471; + t.Rcaron = 667; + t.Gcommaaccent = 722; + t.ucircumflex = 500; + t.acircumflex = 444; + t.Amacron = 722; + t.rcaron = 333; + t.ccedilla = 444; + t.Zdotaccent = 611; + t.Thorn = 556; + t.Omacron = 722; + t.Racute = 667; + t.Sacute = 556; + t.dcaron = 588; + t.Umacron = 722; + t.uring = 500; + t.threesuperior = 300; + t.Ograve = 722; + t.Agrave = 722; + t.Abreve = 722; + t.multiply = 564; + t.uacute = 500; + t.Tcaron = 611; + t.partialdiff = 476; + t.ydieresis = 500; + t.Nacute = 722; + t.icircumflex = 278; + t.Ecircumflex = 611; + t.adieresis = 444; + t.edieresis = 444; + t.cacute = 444; + t.nacute = 500; + t.umacron = 500; + t.Ncaron = 722; + t.Iacute = 333; + t.plusminus = 564; + t.brokenbar = 200; + t.registered = 760; + t.Gbreve = 722; + t.Idotaccent = 333; + t.summation = 600; + t.Egrave = 611; + t.racute = 333; + t.omacron = 500; + t.Zacute = 611; + t.Zcaron = 611; + t.greaterequal = 549; + t.Eth = 722; + t.Ccedilla = 667; + t.lcommaaccent = 278; + t.tcaron = 326; + t.eogonek = 444; + t.Uogonek = 722; + t.Aacute = 722; + t.Adieresis = 722; + t.egrave = 444; + t.zacute = 444; + t.iogonek = 278; + t.Oacute = 722; + t.oacute = 500; + t.amacron = 444; + t.sacute = 389; + t.idieresis = 278; + t.Ocircumflex = 722; + t.Ugrave = 722; + t.Delta = 612; + t.thorn = 500; + t.twosuperior = 300; + t.Odieresis = 722; + t.mu = 500; + t.igrave = 278; + t.ohungarumlaut = 500; + t.Eogonek = 611; + t.dcroat = 500; + t.threequarters = 750; + t.Scedilla = 556; + t.lcaron = 344; + t.Kcommaaccent = 722; + t.Lacute = 611; + t.trademark = 980; + t.edotaccent = 444; + t.Igrave = 333; + t.Imacron = 333; + t.Lcaron = 611; + t.onehalf = 750; + t.lessequal = 549; + t.ocircumflex = 500; + t.ntilde = 500; + t.Uhungarumlaut = 722; + t.Eacute = 611; + t.emacron = 444; + t.gbreve = 500; + t.onequarter = 750; + t.Scaron = 556; + t.Scommaaccent = 556; + t.Ohungarumlaut = 722; + t.degree = 400; + t.ograve = 500; + t.Ccaron = 667; + t.ugrave = 500; + t.radical = 453; + t.Dcaron = 722; + t.rcommaaccent = 333; + t.Ntilde = 722; + t.otilde = 500; + t.Rcommaaccent = 667; + t.Lcommaaccent = 611; + t.Atilde = 722; + t.Aogonek = 722; + t.Aring = 722; + t.Otilde = 722; + t.zdotaccent = 444; + t.Ecaron = 611; + t.Iogonek = 333; + t.kcommaaccent = 500; + t.minus = 564; + t.Icircumflex = 333; + t.ncaron = 500; + t.tcommaaccent = 278; + t.logicalnot = 564; + t.odieresis = 500; + t.udieresis = 500; + t.notequal = 549; + t.gcommaaccent = 500; + t.eth = 500; + t.zcaron = 444; + t.ncommaaccent = 500; + t.onesuperior = 300; + t.imacron = 278; + t.Euro = 500; + }); + t["Times-Bold"] = (0, _core_utils.getLookupTableFactory)(function (t) { + t.space = 250; + t.exclam = 333; + t.quotedbl = 555; + t.numbersign = 500; + t.dollar = 500; + t.percent = 1000; + t.ampersand = 833; + t.quoteright = 333; + t.parenleft = 333; + t.parenright = 333; + t.asterisk = 500; + t.plus = 570; + t.comma = 250; + t.hyphen = 333; + t.period = 250; + t.slash = 278; + t.zero = 500; + t.one = 500; + t.two = 500; + t.three = 500; + t.four = 500; + t.five = 500; + t.six = 500; + t.seven = 500; + t.eight = 500; + t.nine = 500; + t.colon = 333; + t.semicolon = 333; + t.less = 570; + t.equal = 570; + t.greater = 570; + t.question = 500; + t.at = 930; + t.A = 722; + t.B = 667; + t.C = 722; + t.D = 722; + t.E = 667; + t.F = 611; + t.G = 778; + t.H = 778; + t.I = 389; + t.J = 500; + t.K = 778; + t.L = 667; + t.M = 944; + t.N = 722; + t.O = 778; + t.P = 611; + t.Q = 778; + t.R = 722; + t.S = 556; + t.T = 667; + t.U = 722; + t.V = 722; + t.W = 1000; + t.X = 722; + t.Y = 722; + t.Z = 667; + t.bracketleft = 333; + t.backslash = 278; + t.bracketright = 333; + t.asciicircum = 581; + t.underscore = 500; + t.quoteleft = 333; + t.a = 500; + t.b = 556; + t.c = 444; + t.d = 556; + t.e = 444; + t.f = 333; + t.g = 500; + t.h = 556; + t.i = 278; + t.j = 333; + t.k = 556; + t.l = 278; + t.m = 833; + t.n = 556; + t.o = 500; + t.p = 556; + t.q = 556; + t.r = 444; + t.s = 389; + t.t = 333; + t.u = 556; + t.v = 500; + t.w = 722; + t.x = 500; + t.y = 500; + t.z = 444; + t.braceleft = 394; + t.bar = 220; + t.braceright = 394; + t.asciitilde = 520; + t.exclamdown = 333; + t.cent = 500; + t.sterling = 500; + t.fraction = 167; + t.yen = 500; + t.florin = 500; + t.section = 500; + t.currency = 500; + t.quotesingle = 278; + t.quotedblleft = 500; + t.guillemotleft = 500; + t.guilsinglleft = 333; + t.guilsinglright = 333; + t.fi = 556; + t.fl = 556; + t.endash = 500; + t.dagger = 500; + t.daggerdbl = 500; + t.periodcentered = 250; + t.paragraph = 540; + t.bullet = 350; + t.quotesinglbase = 333; + t.quotedblbase = 500; + t.quotedblright = 500; + t.guillemotright = 500; + t.ellipsis = 1000; + t.perthousand = 1000; + t.questiondown = 500; + t.grave = 333; + t.acute = 333; + t.circumflex = 333; + t.tilde = 333; + t.macron = 333; + t.breve = 333; + t.dotaccent = 333; + t.dieresis = 333; + t.ring = 333; + t.cedilla = 333; + t.hungarumlaut = 333; + t.ogonek = 333; + t.caron = 333; + t.emdash = 1000; + t.AE = 1000; + t.ordfeminine = 300; + t.Lslash = 667; + t.Oslash = 778; + t.OE = 1000; + t.ordmasculine = 330; + t.ae = 722; + t.dotlessi = 278; + t.lslash = 278; + t.oslash = 500; + t.oe = 722; + t.germandbls = 556; + t.Idieresis = 389; + t.eacute = 444; + t.abreve = 500; + t.uhungarumlaut = 556; + t.ecaron = 444; + t.Ydieresis = 722; + t.divide = 570; + t.Yacute = 722; + t.Acircumflex = 722; + t.aacute = 500; + t.Ucircumflex = 722; + t.yacute = 500; + t.scommaaccent = 389; + t.ecircumflex = 444; + t.Uring = 722; + t.Udieresis = 722; + t.aogonek = 500; + t.Uacute = 722; + t.uogonek = 556; + t.Edieresis = 667; + t.Dcroat = 722; + t.commaaccent = 250; + t.copyright = 747; + t.Emacron = 667; + t.ccaron = 444; + t.aring = 500; + t.Ncommaaccent = 722; + t.lacute = 278; + t.agrave = 500; + t.Tcommaaccent = 667; + t.Cacute = 722; + t.atilde = 500; + t.Edotaccent = 667; + t.scaron = 389; + t.scedilla = 389; + t.iacute = 278; + t.lozenge = 494; + t.Rcaron = 722; + t.Gcommaaccent = 778; + t.ucircumflex = 556; + t.acircumflex = 500; + t.Amacron = 722; + t.rcaron = 444; + t.ccedilla = 444; + t.Zdotaccent = 667; + t.Thorn = 611; + t.Omacron = 778; + t.Racute = 722; + t.Sacute = 556; + t.dcaron = 672; + t.Umacron = 722; + t.uring = 556; + t.threesuperior = 300; + t.Ograve = 778; + t.Agrave = 722; + t.Abreve = 722; + t.multiply = 570; + t.uacute = 556; + t.Tcaron = 667; + t.partialdiff = 494; + t.ydieresis = 500; + t.Nacute = 722; + t.icircumflex = 278; + t.Ecircumflex = 667; + t.adieresis = 500; + t.edieresis = 444; + t.cacute = 444; + t.nacute = 556; + t.umacron = 556; + t.Ncaron = 722; + t.Iacute = 389; + t.plusminus = 570; + t.brokenbar = 220; + t.registered = 747; + t.Gbreve = 778; + t.Idotaccent = 389; + t.summation = 600; + t.Egrave = 667; + t.racute = 444; + t.omacron = 500; + t.Zacute = 667; + t.Zcaron = 667; + t.greaterequal = 549; + t.Eth = 722; + t.Ccedilla = 722; + t.lcommaaccent = 278; + t.tcaron = 416; + t.eogonek = 444; + t.Uogonek = 722; + t.Aacute = 722; + t.Adieresis = 722; + t.egrave = 444; + t.zacute = 444; + t.iogonek = 278; + t.Oacute = 778; + t.oacute = 500; + t.amacron = 500; + t.sacute = 389; + t.idieresis = 278; + t.Ocircumflex = 778; + t.Ugrave = 722; + t.Delta = 612; + t.thorn = 556; + t.twosuperior = 300; + t.Odieresis = 778; + t.mu = 556; + t.igrave = 278; + t.ohungarumlaut = 500; + t.Eogonek = 667; + t.dcroat = 556; + t.threequarters = 750; + t.Scedilla = 556; + t.lcaron = 394; + t.Kcommaaccent = 778; + t.Lacute = 667; + t.trademark = 1000; + t.edotaccent = 444; + t.Igrave = 389; + t.Imacron = 389; + t.Lcaron = 667; + t.onehalf = 750; + t.lessequal = 549; + t.ocircumflex = 500; + t.ntilde = 556; + t.Uhungarumlaut = 722; + t.Eacute = 667; + t.emacron = 444; + t.gbreve = 500; + t.onequarter = 750; + t.Scaron = 556; + t.Scommaaccent = 556; + t.Ohungarumlaut = 778; + t.degree = 400; + t.ograve = 500; + t.Ccaron = 722; + t.ugrave = 556; + t.radical = 549; + t.Dcaron = 722; + t.rcommaaccent = 444; + t.Ntilde = 722; + t.otilde = 500; + t.Rcommaaccent = 722; + t.Lcommaaccent = 667; + t.Atilde = 722; + t.Aogonek = 722; + t.Aring = 722; + t.Otilde = 778; + t.zdotaccent = 444; + t.Ecaron = 667; + t.Iogonek = 389; + t.kcommaaccent = 556; + t.minus = 570; + t.Icircumflex = 389; + t.ncaron = 556; + t.tcommaaccent = 333; + t.logicalnot = 570; + t.odieresis = 500; + t.udieresis = 556; + t.notequal = 549; + t.gcommaaccent = 500; + t.eth = 500; + t.zcaron = 444; + t.ncommaaccent = 556; + t.onesuperior = 300; + t.imacron = 278; + t.Euro = 500; + }); + t["Times-BoldItalic"] = (0, _core_utils.getLookupTableFactory)(function (t) { + t.space = 250; + t.exclam = 389; + t.quotedbl = 555; + t.numbersign = 500; + t.dollar = 500; + t.percent = 833; + t.ampersand = 778; + t.quoteright = 333; + t.parenleft = 333; + t.parenright = 333; + t.asterisk = 500; + t.plus = 570; + t.comma = 250; + t.hyphen = 333; + t.period = 250; + t.slash = 278; + t.zero = 500; + t.one = 500; + t.two = 500; + t.three = 500; + t.four = 500; + t.five = 500; + t.six = 500; + t.seven = 500; + t.eight = 500; + t.nine = 500; + t.colon = 333; + t.semicolon = 333; + t.less = 570; + t.equal = 570; + t.greater = 570; + t.question = 500; + t.at = 832; + t.A = 667; + t.B = 667; + t.C = 667; + t.D = 722; + t.E = 667; + t.F = 667; + t.G = 722; + t.H = 778; + t.I = 389; + t.J = 500; + t.K = 667; + t.L = 611; + t.M = 889; + t.N = 722; + t.O = 722; + t.P = 611; + t.Q = 722; + t.R = 667; + t.S = 556; + t.T = 611; + t.U = 722; + t.V = 667; + t.W = 889; + t.X = 667; + t.Y = 611; + t.Z = 611; + t.bracketleft = 333; + t.backslash = 278; + t.bracketright = 333; + t.asciicircum = 570; + t.underscore = 500; + t.quoteleft = 333; + t.a = 500; + t.b = 500; + t.c = 444; + t.d = 500; + t.e = 444; + t.f = 333; + t.g = 500; + t.h = 556; + t.i = 278; + t.j = 278; + t.k = 500; + t.l = 278; + t.m = 778; + t.n = 556; + t.o = 500; + t.p = 500; + t.q = 500; + t.r = 389; + t.s = 389; + t.t = 278; + t.u = 556; + t.v = 444; + t.w = 667; + t.x = 500; + t.y = 444; + t.z = 389; + t.braceleft = 348; + t.bar = 220; + t.braceright = 348; + t.asciitilde = 570; + t.exclamdown = 389; + t.cent = 500; + t.sterling = 500; + t.fraction = 167; + t.yen = 500; + t.florin = 500; + t.section = 500; + t.currency = 500; + t.quotesingle = 278; + t.quotedblleft = 500; + t.guillemotleft = 500; + t.guilsinglleft = 333; + t.guilsinglright = 333; + t.fi = 556; + t.fl = 556; + t.endash = 500; + t.dagger = 500; + t.daggerdbl = 500; + t.periodcentered = 250; + t.paragraph = 500; + t.bullet = 350; + t.quotesinglbase = 333; + t.quotedblbase = 500; + t.quotedblright = 500; + t.guillemotright = 500; + t.ellipsis = 1000; + t.perthousand = 1000; + t.questiondown = 500; + t.grave = 333; + t.acute = 333; + t.circumflex = 333; + t.tilde = 333; + t.macron = 333; + t.breve = 333; + t.dotaccent = 333; + t.dieresis = 333; + t.ring = 333; + t.cedilla = 333; + t.hungarumlaut = 333; + t.ogonek = 333; + t.caron = 333; + t.emdash = 1000; + t.AE = 944; + t.ordfeminine = 266; + t.Lslash = 611; + t.Oslash = 722; + t.OE = 944; + t.ordmasculine = 300; + t.ae = 722; + t.dotlessi = 278; + t.lslash = 278; + t.oslash = 500; + t.oe = 722; + t.germandbls = 500; + t.Idieresis = 389; + t.eacute = 444; + t.abreve = 500; + t.uhungarumlaut = 556; + t.ecaron = 444; + t.Ydieresis = 611; + t.divide = 570; + t.Yacute = 611; + t.Acircumflex = 667; + t.aacute = 500; + t.Ucircumflex = 722; + t.yacute = 444; + t.scommaaccent = 389; + t.ecircumflex = 444; + t.Uring = 722; + t.Udieresis = 722; + t.aogonek = 500; + t.Uacute = 722; + t.uogonek = 556; + t.Edieresis = 667; + t.Dcroat = 722; + t.commaaccent = 250; + t.copyright = 747; + t.Emacron = 667; + t.ccaron = 444; + t.aring = 500; + t.Ncommaaccent = 722; + t.lacute = 278; + t.agrave = 500; + t.Tcommaaccent = 611; + t.Cacute = 667; + t.atilde = 500; + t.Edotaccent = 667; + t.scaron = 389; + t.scedilla = 389; + t.iacute = 278; + t.lozenge = 494; + t.Rcaron = 667; + t.Gcommaaccent = 722; + t.ucircumflex = 556; + t.acircumflex = 500; + t.Amacron = 667; + t.rcaron = 389; + t.ccedilla = 444; + t.Zdotaccent = 611; + t.Thorn = 611; + t.Omacron = 722; + t.Racute = 667; + t.Sacute = 556; + t.dcaron = 608; + t.Umacron = 722; + t.uring = 556; + t.threesuperior = 300; + t.Ograve = 722; + t.Agrave = 667; + t.Abreve = 667; + t.multiply = 570; + t.uacute = 556; + t.Tcaron = 611; + t.partialdiff = 494; + t.ydieresis = 444; + t.Nacute = 722; + t.icircumflex = 278; + t.Ecircumflex = 667; + t.adieresis = 500; + t.edieresis = 444; + t.cacute = 444; + t.nacute = 556; + t.umacron = 556; + t.Ncaron = 722; + t.Iacute = 389; + t.plusminus = 570; + t.brokenbar = 220; + t.registered = 747; + t.Gbreve = 722; + t.Idotaccent = 389; + t.summation = 600; + t.Egrave = 667; + t.racute = 389; + t.omacron = 500; + t.Zacute = 611; + t.Zcaron = 611; + t.greaterequal = 549; + t.Eth = 722; + t.Ccedilla = 667; + t.lcommaaccent = 278; + t.tcaron = 366; + t.eogonek = 444; + t.Uogonek = 722; + t.Aacute = 667; + t.Adieresis = 667; + t.egrave = 444; + t.zacute = 389; + t.iogonek = 278; + t.Oacute = 722; + t.oacute = 500; + t.amacron = 500; + t.sacute = 389; + t.idieresis = 278; + t.Ocircumflex = 722; + t.Ugrave = 722; + t.Delta = 612; + t.thorn = 500; + t.twosuperior = 300; + t.Odieresis = 722; + t.mu = 576; + t.igrave = 278; + t.ohungarumlaut = 500; + t.Eogonek = 667; + t.dcroat = 500; + t.threequarters = 750; + t.Scedilla = 556; + t.lcaron = 382; + t.Kcommaaccent = 667; + t.Lacute = 611; + t.trademark = 1000; + t.edotaccent = 444; + t.Igrave = 389; + t.Imacron = 389; + t.Lcaron = 611; + t.onehalf = 750; + t.lessequal = 549; + t.ocircumflex = 500; + t.ntilde = 556; + t.Uhungarumlaut = 722; + t.Eacute = 667; + t.emacron = 444; + t.gbreve = 500; + t.onequarter = 750; + t.Scaron = 556; + t.Scommaaccent = 556; + t.Ohungarumlaut = 722; + t.degree = 400; + t.ograve = 500; + t.Ccaron = 667; + t.ugrave = 556; + t.radical = 549; + t.Dcaron = 722; + t.rcommaaccent = 389; + t.Ntilde = 722; + t.otilde = 500; + t.Rcommaaccent = 667; + t.Lcommaaccent = 611; + t.Atilde = 667; + t.Aogonek = 667; + t.Aring = 667; + t.Otilde = 722; + t.zdotaccent = 389; + t.Ecaron = 667; + t.Iogonek = 389; + t.kcommaaccent = 500; + t.minus = 606; + t.Icircumflex = 389; + t.ncaron = 556; + t.tcommaaccent = 278; + t.logicalnot = 606; + t.odieresis = 500; + t.udieresis = 556; + t.notequal = 549; + t.gcommaaccent = 500; + t.eth = 500; + t.zcaron = 389; + t.ncommaaccent = 556; + t.onesuperior = 300; + t.imacron = 278; + t.Euro = 500; + }); + t["Times-Italic"] = (0, _core_utils.getLookupTableFactory)(function (t) { + t.space = 250; + t.exclam = 333; + t.quotedbl = 420; + t.numbersign = 500; + t.dollar = 500; + t.percent = 833; + t.ampersand = 778; + t.quoteright = 333; + t.parenleft = 333; + t.parenright = 333; + t.asterisk = 500; + t.plus = 675; + t.comma = 250; + t.hyphen = 333; + t.period = 250; + t.slash = 278; + t.zero = 500; + t.one = 500; + t.two = 500; + t.three = 500; + t.four = 500; + t.five = 500; + t.six = 500; + t.seven = 500; + t.eight = 500; + t.nine = 500; + t.colon = 333; + t.semicolon = 333; + t.less = 675; + t.equal = 675; + t.greater = 675; + t.question = 500; + t.at = 920; + t.A = 611; + t.B = 611; + t.C = 667; + t.D = 722; + t.E = 611; + t.F = 611; + t.G = 722; + t.H = 722; + t.I = 333; + t.J = 444; + t.K = 667; + t.L = 556; + t.M = 833; + t.N = 667; + t.O = 722; + t.P = 611; + t.Q = 722; + t.R = 611; + t.S = 500; + t.T = 556; + t.U = 722; + t.V = 611; + t.W = 833; + t.X = 611; + t.Y = 556; + t.Z = 556; + t.bracketleft = 389; + t.backslash = 278; + t.bracketright = 389; + t.asciicircum = 422; + t.underscore = 500; + t.quoteleft = 333; + t.a = 500; + t.b = 500; + t.c = 444; + t.d = 500; + t.e = 444; + t.f = 278; + t.g = 500; + t.h = 500; + t.i = 278; + t.j = 278; + t.k = 444; + t.l = 278; + t.m = 722; + t.n = 500; + t.o = 500; + t.p = 500; + t.q = 500; + t.r = 389; + t.s = 389; + t.t = 278; + t.u = 500; + t.v = 444; + t.w = 667; + t.x = 444; + t.y = 444; + t.z = 389; + t.braceleft = 400; + t.bar = 275; + t.braceright = 400; + t.asciitilde = 541; + t.exclamdown = 389; + t.cent = 500; + t.sterling = 500; + t.fraction = 167; + t.yen = 500; + t.florin = 500; + t.section = 500; + t.currency = 500; + t.quotesingle = 214; + t.quotedblleft = 556; + t.guillemotleft = 500; + t.guilsinglleft = 333; + t.guilsinglright = 333; + t.fi = 500; + t.fl = 500; + t.endash = 500; + t.dagger = 500; + t.daggerdbl = 500; + t.periodcentered = 250; + t.paragraph = 523; + t.bullet = 350; + t.quotesinglbase = 333; + t.quotedblbase = 556; + t.quotedblright = 556; + t.guillemotright = 500; + t.ellipsis = 889; + t.perthousand = 1000; + t.questiondown = 500; + t.grave = 333; + t.acute = 333; + t.circumflex = 333; + t.tilde = 333; + t.macron = 333; + t.breve = 333; + t.dotaccent = 333; + t.dieresis = 333; + t.ring = 333; + t.cedilla = 333; + t.hungarumlaut = 333; + t.ogonek = 333; + t.caron = 333; + t.emdash = 889; + t.AE = 889; + t.ordfeminine = 276; + t.Lslash = 556; + t.Oslash = 722; + t.OE = 944; + t.ordmasculine = 310; + t.ae = 667; + t.dotlessi = 278; + t.lslash = 278; + t.oslash = 500; + t.oe = 667; + t.germandbls = 500; + t.Idieresis = 333; + t.eacute = 444; + t.abreve = 500; + t.uhungarumlaut = 500; + t.ecaron = 444; + t.Ydieresis = 556; + t.divide = 675; + t.Yacute = 556; + t.Acircumflex = 611; + t.aacute = 500; + t.Ucircumflex = 722; + t.yacute = 444; + t.scommaaccent = 389; + t.ecircumflex = 444; + t.Uring = 722; + t.Udieresis = 722; + t.aogonek = 500; + t.Uacute = 722; + t.uogonek = 500; + t.Edieresis = 611; + t.Dcroat = 722; + t.commaaccent = 250; + t.copyright = 760; + t.Emacron = 611; + t.ccaron = 444; + t.aring = 500; + t.Ncommaaccent = 667; + t.lacute = 278; + t.agrave = 500; + t.Tcommaaccent = 556; + t.Cacute = 667; + t.atilde = 500; + t.Edotaccent = 611; + t.scaron = 389; + t.scedilla = 389; + t.iacute = 278; + t.lozenge = 471; + t.Rcaron = 611; + t.Gcommaaccent = 722; + t.ucircumflex = 500; + t.acircumflex = 500; + t.Amacron = 611; + t.rcaron = 389; + t.ccedilla = 444; + t.Zdotaccent = 556; + t.Thorn = 611; + t.Omacron = 722; + t.Racute = 611; + t.Sacute = 500; + t.dcaron = 544; + t.Umacron = 722; + t.uring = 500; + t.threesuperior = 300; + t.Ograve = 722; + t.Agrave = 611; + t.Abreve = 611; + t.multiply = 675; + t.uacute = 500; + t.Tcaron = 556; + t.partialdiff = 476; + t.ydieresis = 444; + t.Nacute = 667; + t.icircumflex = 278; + t.Ecircumflex = 611; + t.adieresis = 500; + t.edieresis = 444; + t.cacute = 444; + t.nacute = 500; + t.umacron = 500; + t.Ncaron = 667; + t.Iacute = 333; + t.plusminus = 675; + t.brokenbar = 275; + t.registered = 760; + t.Gbreve = 722; + t.Idotaccent = 333; + t.summation = 600; + t.Egrave = 611; + t.racute = 389; + t.omacron = 500; + t.Zacute = 556; + t.Zcaron = 556; + t.greaterequal = 549; + t.Eth = 722; + t.Ccedilla = 667; + t.lcommaaccent = 278; + t.tcaron = 300; + t.eogonek = 444; + t.Uogonek = 722; + t.Aacute = 611; + t.Adieresis = 611; + t.egrave = 444; + t.zacute = 389; + t.iogonek = 278; + t.Oacute = 722; + t.oacute = 500; + t.amacron = 500; + t.sacute = 389; + t.idieresis = 278; + t.Ocircumflex = 722; + t.Ugrave = 722; + t.Delta = 612; + t.thorn = 500; + t.twosuperior = 300; + t.Odieresis = 722; + t.mu = 500; + t.igrave = 278; + t.ohungarumlaut = 500; + t.Eogonek = 611; + t.dcroat = 500; + t.threequarters = 750; + t.Scedilla = 500; + t.lcaron = 300; + t.Kcommaaccent = 667; + t.Lacute = 556; + t.trademark = 980; + t.edotaccent = 444; + t.Igrave = 333; + t.Imacron = 333; + t.Lcaron = 611; + t.onehalf = 750; + t.lessequal = 549; + t.ocircumflex = 500; + t.ntilde = 500; + t.Uhungarumlaut = 722; + t.Eacute = 611; + t.emacron = 444; + t.gbreve = 500; + t.onequarter = 750; + t.Scaron = 500; + t.Scommaaccent = 500; + t.Ohungarumlaut = 722; + t.degree = 400; + t.ograve = 500; + t.Ccaron = 667; + t.ugrave = 500; + t.radical = 453; + t.Dcaron = 722; + t.rcommaaccent = 389; + t.Ntilde = 667; + t.otilde = 500; + t.Rcommaaccent = 611; + t.Lcommaaccent = 556; + t.Atilde = 611; + t.Aogonek = 611; + t.Aring = 611; + t.Otilde = 722; + t.zdotaccent = 389; + t.Ecaron = 611; + t.Iogonek = 333; + t.kcommaaccent = 444; + t.minus = 675; + t.Icircumflex = 333; + t.ncaron = 500; + t.tcommaaccent = 278; + t.logicalnot = 675; + t.odieresis = 500; + t.udieresis = 500; + t.notequal = 549; + t.gcommaaccent = 500; + t.eth = 500; + t.zcaron = 389; + t.ncommaaccent = 500; + t.onesuperior = 300; + t.imacron = 278; + t.Euro = 500; + }); + t.ZapfDingbats = (0, _core_utils.getLookupTableFactory)(function (t) { + t.space = 278; + t.a1 = 974; + t.a2 = 961; + t.a202 = 974; + t.a3 = 980; + t.a4 = 719; + t.a5 = 789; + t.a119 = 790; + t.a118 = 791; + t.a117 = 690; + t.a11 = 960; + t.a12 = 939; + t.a13 = 549; + t.a14 = 855; + t.a15 = 911; + t.a16 = 933; + t.a105 = 911; + t.a17 = 945; + t.a18 = 974; + t.a19 = 755; + t.a20 = 846; + t.a21 = 762; + t.a22 = 761; + t.a23 = 571; + t.a24 = 677; + t.a25 = 763; + t.a26 = 760; + t.a27 = 759; + t.a28 = 754; + t.a6 = 494; + t.a7 = 552; + t.a8 = 537; + t.a9 = 577; + t.a10 = 692; + t.a29 = 786; + t.a30 = 788; + t.a31 = 788; + t.a32 = 790; + t.a33 = 793; + t.a34 = 794; + t.a35 = 816; + t.a36 = 823; + t.a37 = 789; + t.a38 = 841; + t.a39 = 823; + t.a40 = 833; + t.a41 = 816; + t.a42 = 831; + t.a43 = 923; + t.a44 = 744; + t.a45 = 723; + t.a46 = 749; + t.a47 = 790; + t.a48 = 792; + t.a49 = 695; + t.a50 = 776; + t.a51 = 768; + t.a52 = 792; + t.a53 = 759; + t.a54 = 707; + t.a55 = 708; + t.a56 = 682; + t.a57 = 701; + t.a58 = 826; + t.a59 = 815; + t.a60 = 789; + t.a61 = 789; + t.a62 = 707; + t.a63 = 687; + t.a64 = 696; + t.a65 = 689; + t.a66 = 786; + t.a67 = 787; + t.a68 = 713; + t.a69 = 791; + t.a70 = 785; + t.a71 = 791; + t.a72 = 873; + t.a73 = 761; + t.a74 = 762; + t.a203 = 762; + t.a75 = 759; + t.a204 = 759; + t.a76 = 892; + t.a77 = 892; + t.a78 = 788; + t.a79 = 784; + t.a81 = 438; + t.a82 = 138; + t.a83 = 277; + t.a84 = 415; + t.a97 = 392; + t.a98 = 392; + t.a99 = 668; + t.a100 = 668; + t.a89 = 390; + t.a90 = 390; + t.a93 = 317; + t.a94 = 317; + t.a91 = 276; + t.a92 = 276; + t.a205 = 509; + t.a85 = 509; + t.a206 = 410; + t.a86 = 410; + t.a87 = 234; + t.a88 = 234; + t.a95 = 334; + t.a96 = 334; + t.a101 = 732; + t.a102 = 544; + t.a103 = 544; + t.a104 = 910; + t.a106 = 667; + t.a107 = 760; + t.a108 = 760; + t.a112 = 776; + t.a111 = 595; + t.a110 = 694; + t.a109 = 626; + t.a120 = 788; + t.a121 = 788; + t.a122 = 788; + t.a123 = 788; + t.a124 = 788; + t.a125 = 788; + t.a126 = 788; + t.a127 = 788; + t.a128 = 788; + t.a129 = 788; + t.a130 = 788; + t.a131 = 788; + t.a132 = 788; + t.a133 = 788; + t.a134 = 788; + t.a135 = 788; + t.a136 = 788; + t.a137 = 788; + t.a138 = 788; + t.a139 = 788; + t.a140 = 788; + t.a141 = 788; + t.a142 = 788; + t.a143 = 788; + t.a144 = 788; + t.a145 = 788; + t.a146 = 788; + t.a147 = 788; + t.a148 = 788; + t.a149 = 788; + t.a150 = 788; + t.a151 = 788; + t.a152 = 788; + t.a153 = 788; + t.a154 = 788; + t.a155 = 788; + t.a156 = 788; + t.a157 = 788; + t.a158 = 788; + t.a159 = 788; + t.a160 = 894; + t.a161 = 838; + t.a163 = 1016; + t.a164 = 458; + t.a196 = 748; + t.a165 = 924; + t.a192 = 748; + t.a166 = 918; + t.a167 = 927; + t.a168 = 928; + t.a169 = 928; + t.a170 = 834; + t.a171 = 873; + t.a172 = 828; + t.a173 = 924; + t.a162 = 924; + t.a174 = 917; + t.a175 = 930; + t.a176 = 931; + t.a177 = 463; + t.a178 = 883; + t.a179 = 836; + t.a193 = 836; + t.a180 = 867; + t.a199 = 867; + t.a181 = 696; + t.a200 = 696; + t.a182 = 874; + t.a201 = 874; + t.a183 = 760; + t.a184 = 946; + t.a197 = 771; + t.a185 = 865; + t.a194 = 771; + t.a198 = 888; + t.a186 = 967; + t.a195 = 888; + t.a187 = 831; + t.a188 = 873; + t.a189 = 927; + t.a190 = 970; + t.a191 = 918; + }); +}); +exports.getMetrics = getMetrics; +const getFontBasicMetrics = (0, _core_utils.getLookupTableFactory)(function (t) { + t.Courier = { + ascent: 629, + descent: -157, + capHeight: 562, + xHeight: -426 + }; + t["Courier-Bold"] = { + ascent: 629, + descent: -157, + capHeight: 562, + xHeight: 439 + }; + t["Courier-Oblique"] = { + ascent: 629, + descent: -157, + capHeight: 562, + xHeight: 426 + }; + t["Courier-BoldOblique"] = { + ascent: 629, + descent: -157, + capHeight: 562, + xHeight: 426 + }; + t.Helvetica = { + ascent: 718, + descent: -207, + capHeight: 718, + xHeight: 523 + }; + t["Helvetica-Bold"] = { + ascent: 718, + descent: -207, + capHeight: 718, + xHeight: 532 + }; + t["Helvetica-Oblique"] = { + ascent: 718, + descent: -207, + capHeight: 718, + xHeight: 523 + }; + t["Helvetica-BoldOblique"] = { + ascent: 718, + descent: -207, + capHeight: 718, + xHeight: 532 + }; + t["Times-Roman"] = { + ascent: 683, + descent: -217, + capHeight: 662, + xHeight: 450 + }; + t["Times-Bold"] = { + ascent: 683, + descent: -217, + capHeight: 676, + xHeight: 461 + }; + t["Times-Italic"] = { + ascent: 683, + descent: -217, + capHeight: 653, + xHeight: 441 + }; + t["Times-BoldItalic"] = { + ascent: 683, + descent: -217, + capHeight: 669, + xHeight: 462 + }; + t.Symbol = { + ascent: Math.NaN, + descent: Math.NaN, + capHeight: Math.NaN, + xHeight: Math.NaN + }; + t.ZapfDingbats = { + ascent: Math.NaN, + descent: Math.NaN, + capHeight: Math.NaN, + xHeight: Math.NaN + }; +}); +exports.getFontBasicMetrics = getFontBasicMetrics; + +/***/ }), +/* 46 */ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.GlyfTable = void 0; +const ON_CURVE_POINT = 1 << 0; +const X_SHORT_VECTOR = 1 << 1; +const Y_SHORT_VECTOR = 1 << 2; +const REPEAT_FLAG = 1 << 3; +const X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR = 1 << 4; +const Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR = 1 << 5; +const OVERLAP_SIMPLE = 1 << 6; +const ARG_1_AND_2_ARE_WORDS = 1 << 0; +const ARGS_ARE_XY_VALUES = 1 << 1; +const WE_HAVE_A_SCALE = 1 << 3; +const MORE_COMPONENTS = 1 << 5; +const WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6; +const WE_HAVE_A_TWO_BY_TWO = 1 << 7; +const WE_HAVE_INSTRUCTIONS = 1 << 8; +class GlyfTable { + constructor({ + glyfTable, + isGlyphLocationsLong, + locaTable, + numGlyphs + }) { + this.glyphs = []; + const loca = new DataView(locaTable.buffer, locaTable.byteOffset, locaTable.byteLength); + const glyf = new DataView(glyfTable.buffer, glyfTable.byteOffset, glyfTable.byteLength); + const offsetSize = isGlyphLocationsLong ? 4 : 2; + let prev = isGlyphLocationsLong ? loca.getUint32(0) : 2 * loca.getUint16(0); + let pos = 0; + for (let i = 0; i < numGlyphs; i++) { + pos += offsetSize; + const next = isGlyphLocationsLong ? loca.getUint32(pos) : 2 * loca.getUint16(pos); + if (next === prev) { + this.glyphs.push(new Glyph({})); + continue; + } + const glyph = Glyph.parse(prev, glyf); + this.glyphs.push(glyph); + prev = next; + } + } + getSize() { + return this.glyphs.reduce((a, g) => { + const size = g.getSize(); + return a + (size + 3 & ~3); + }, 0); + } + write() { + const totalSize = this.getSize(); + const glyfTable = new DataView(new ArrayBuffer(totalSize)); + const isLocationLong = totalSize > 0x1fffe; + const offsetSize = isLocationLong ? 4 : 2; + const locaTable = new DataView(new ArrayBuffer((this.glyphs.length + 1) * offsetSize)); + if (isLocationLong) { + locaTable.setUint32(0, 0); + } else { + locaTable.setUint16(0, 0); + } + let pos = 0; + let locaIndex = 0; + for (const glyph of this.glyphs) { + pos += glyph.write(pos, glyfTable); + pos = pos + 3 & ~3; + locaIndex += offsetSize; + if (isLocationLong) { + locaTable.setUint32(locaIndex, pos); + } else { + locaTable.setUint16(locaIndex, pos >> 1); + } + } + return { + isLocationLong, + loca: new Uint8Array(locaTable.buffer), + glyf: new Uint8Array(glyfTable.buffer) + }; + } + scale(factors) { + for (let i = 0, ii = this.glyphs.length; i < ii; i++) { + this.glyphs[i].scale(factors[i]); + } + } +} +exports.GlyfTable = GlyfTable; +class Glyph { + constructor({ + header = null, + simple = null, + composites = null + }) { + this.header = header; + this.simple = simple; + this.composites = composites; + } + static parse(pos, glyf) { + const [read, header] = GlyphHeader.parse(pos, glyf); + pos += read; + if (header.numberOfContours < 0) { + const composites = []; + while (true) { + const [n, composite] = CompositeGlyph.parse(pos, glyf); + pos += n; + composites.push(composite); + if (!(composite.flags & MORE_COMPONENTS)) { + break; + } + } + return new Glyph({ + header, + composites + }); + } + const simple = SimpleGlyph.parse(pos, glyf, header.numberOfContours); + return new Glyph({ + header, + simple + }); + } + getSize() { + if (!this.header) { + return 0; + } + const size = this.simple ? this.simple.getSize() : this.composites.reduce((a, c) => a + c.getSize(), 0); + return this.header.getSize() + size; + } + write(pos, buf) { + if (!this.header) { + return 0; + } + const spos = pos; + pos += this.header.write(pos, buf); + if (this.simple) { + pos += this.simple.write(pos, buf); + } else { + for (const composite of this.composites) { + pos += composite.write(pos, buf); + } + } + return pos - spos; + } + scale(factor) { + if (!this.header) { + return; + } + const xMiddle = (this.header.xMin + this.header.xMax) / 2; + this.header.scale(xMiddle, factor); + if (this.simple) { + this.simple.scale(xMiddle, factor); + } else { + for (const composite of this.composites) { + composite.scale(xMiddle, factor); + } + } + } +} +class GlyphHeader { + constructor({ + numberOfContours, + xMin, + yMin, + xMax, + yMax + }) { + this.numberOfContours = numberOfContours; + this.xMin = xMin; + this.yMin = yMin; + this.xMax = xMax; + this.yMax = yMax; + } + static parse(pos, glyf) { + return [10, new GlyphHeader({ + numberOfContours: glyf.getInt16(pos), + xMin: glyf.getInt16(pos + 2), + yMin: glyf.getInt16(pos + 4), + xMax: glyf.getInt16(pos + 6), + yMax: glyf.getInt16(pos + 8) + })]; + } + getSize() { + return 10; + } + write(pos, buf) { + buf.setInt16(pos, this.numberOfContours); + buf.setInt16(pos + 2, this.xMin); + buf.setInt16(pos + 4, this.yMin); + buf.setInt16(pos + 6, this.xMax); + buf.setInt16(pos + 8, this.yMax); + return 10; + } + scale(x, factor) { + this.xMin = Math.round(x + (this.xMin - x) * factor); + this.xMax = Math.round(x + (this.xMax - x) * factor); + } +} +class Contour { + constructor({ + flags, + xCoordinates, + yCoordinates + }) { + this.xCoordinates = xCoordinates; + this.yCoordinates = yCoordinates; + this.flags = flags; + } +} +class SimpleGlyph { + constructor({ + contours, + instructions + }) { + this.contours = contours; + this.instructions = instructions; + } + static parse(pos, glyf, numberOfContours) { + const endPtsOfContours = []; + for (let i = 0; i < numberOfContours; i++) { + const endPt = glyf.getUint16(pos); + pos += 2; + endPtsOfContours.push(endPt); + } + const numberOfPt = endPtsOfContours[numberOfContours - 1] + 1; + const instructionLength = glyf.getUint16(pos); + pos += 2; + const instructions = new Uint8Array(glyf).slice(pos, pos + instructionLength); + pos += instructionLength; + const flags = []; + for (let i = 0; i < numberOfPt; pos++, i++) { + let flag = glyf.getUint8(pos); + flags.push(flag); + if (flag & REPEAT_FLAG) { + const count = glyf.getUint8(++pos); + flag ^= REPEAT_FLAG; + for (let m = 0; m < count; m++) { + flags.push(flag); + } + i += count; + } + } + const allXCoordinates = []; + let xCoordinates = []; + let yCoordinates = []; + let pointFlags = []; + const contours = []; + let endPtsOfContoursIndex = 0; + let lastCoordinate = 0; + for (let i = 0; i < numberOfPt; i++) { + const flag = flags[i]; + if (flag & X_SHORT_VECTOR) { + const x = glyf.getUint8(pos++); + lastCoordinate += flag & X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR ? x : -x; + xCoordinates.push(lastCoordinate); + } else if (flag & X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR) { + xCoordinates.push(lastCoordinate); + } else { + lastCoordinate += glyf.getInt16(pos); + pos += 2; + xCoordinates.push(lastCoordinate); + } + if (endPtsOfContours[endPtsOfContoursIndex] === i) { + endPtsOfContoursIndex++; + allXCoordinates.push(xCoordinates); + xCoordinates = []; + } + } + lastCoordinate = 0; + endPtsOfContoursIndex = 0; + for (let i = 0; i < numberOfPt; i++) { + const flag = flags[i]; + if (flag & Y_SHORT_VECTOR) { + const y = glyf.getUint8(pos++); + lastCoordinate += flag & Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR ? y : -y; + yCoordinates.push(lastCoordinate); + } else if (flag & Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR) { + yCoordinates.push(lastCoordinate); + } else { + lastCoordinate += glyf.getInt16(pos); + pos += 2; + yCoordinates.push(lastCoordinate); + } + pointFlags.push(flag & ON_CURVE_POINT | flag & OVERLAP_SIMPLE); + if (endPtsOfContours[endPtsOfContoursIndex] === i) { + xCoordinates = allXCoordinates[endPtsOfContoursIndex]; + endPtsOfContoursIndex++; + contours.push(new Contour({ + flags: pointFlags, + xCoordinates, + yCoordinates + })); + yCoordinates = []; + pointFlags = []; + } + } + return new SimpleGlyph({ + contours, + instructions + }); + } + getSize() { + let size = this.contours.length * 2 + 2 + this.instructions.length; + let lastX = 0; + let lastY = 0; + for (const contour of this.contours) { + size += contour.flags.length; + for (let i = 0, ii = contour.xCoordinates.length; i < ii; i++) { + const x = contour.xCoordinates[i]; + const y = contour.yCoordinates[i]; + let abs = Math.abs(x - lastX); + if (abs > 255) { + size += 2; + } else if (abs > 0) { + size += 1; + } + lastX = x; + abs = Math.abs(y - lastY); + if (abs > 255) { + size += 2; + } else if (abs > 0) { + size += 1; + } + lastY = y; + } + } + return size; + } + write(pos, buf) { + const spos = pos; + const xCoordinates = []; + const yCoordinates = []; + const flags = []; + let lastX = 0; + let lastY = 0; + for (const contour of this.contours) { + for (let i = 0, ii = contour.xCoordinates.length; i < ii; i++) { + let flag = contour.flags[i]; + const x = contour.xCoordinates[i]; + let delta = x - lastX; + if (delta === 0) { + flag |= X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR; + xCoordinates.push(0); + } else { + const abs = Math.abs(delta); + if (abs <= 255) { + flag |= delta >= 0 ? X_SHORT_VECTOR | X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR : X_SHORT_VECTOR; + xCoordinates.push(abs); + } else { + xCoordinates.push(delta); + } + } + lastX = x; + const y = contour.yCoordinates[i]; + delta = y - lastY; + if (delta === 0) { + flag |= Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR; + yCoordinates.push(0); + } else { + const abs = Math.abs(delta); + if (abs <= 255) { + flag |= delta >= 0 ? Y_SHORT_VECTOR | Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR : Y_SHORT_VECTOR; + yCoordinates.push(abs); + } else { + yCoordinates.push(delta); + } + } + lastY = y; + flags.push(flag); + } + buf.setUint16(pos, xCoordinates.length - 1); + pos += 2; + } + buf.setUint16(pos, this.instructions.length); + pos += 2; + if (this.instructions.length) { + new Uint8Array(buf.buffer, 0, buf.buffer.byteLength).set(this.instructions, pos); + pos += this.instructions.length; + } + for (const flag of flags) { + buf.setUint8(pos++, flag); + } + for (let i = 0, ii = xCoordinates.length; i < ii; i++) { + const x = xCoordinates[i]; + const flag = flags[i]; + if (flag & X_SHORT_VECTOR) { + buf.setUint8(pos++, x); + } else if (!(flag & X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR)) { + buf.setInt16(pos, x); + pos += 2; + } + } + for (let i = 0, ii = yCoordinates.length; i < ii; i++) { + const y = yCoordinates[i]; + const flag = flags[i]; + if (flag & Y_SHORT_VECTOR) { + buf.setUint8(pos++, y); + } else if (!(flag & Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR)) { + buf.setInt16(pos, y); + pos += 2; + } + } + return pos - spos; + } + scale(x, factor) { + for (const contour of this.contours) { + if (contour.xCoordinates.length === 0) { + continue; + } + for (let i = 0, ii = contour.xCoordinates.length; i < ii; i++) { + contour.xCoordinates[i] = Math.round(x + (contour.xCoordinates[i] - x) * factor); + } + } + } +} +class CompositeGlyph { + constructor({ + flags, + glyphIndex, + argument1, + argument2, + transf, + instructions + }) { + this.flags = flags; + this.glyphIndex = glyphIndex; + this.argument1 = argument1; + this.argument2 = argument2; + this.transf = transf; + this.instructions = instructions; + } + static parse(pos, glyf) { + const spos = pos; + const transf = []; + let flags = glyf.getUint16(pos); + const glyphIndex = glyf.getUint16(pos + 2); + pos += 4; + let argument1, argument2; + if (flags & ARG_1_AND_2_ARE_WORDS) { + if (flags & ARGS_ARE_XY_VALUES) { + argument1 = glyf.getInt16(pos); + argument2 = glyf.getInt16(pos + 2); + } else { + argument1 = glyf.getUint16(pos); + argument2 = glyf.getUint16(pos + 2); + } + pos += 4; + flags ^= ARG_1_AND_2_ARE_WORDS; + } else { + if (flags & ARGS_ARE_XY_VALUES) { + argument1 = glyf.getInt8(pos); + argument2 = glyf.getInt8(pos + 1); + } else { + argument1 = glyf.getUint8(pos); + argument2 = glyf.getUint8(pos + 1); + } + pos += 2; + } + if (flags & WE_HAVE_A_SCALE) { + transf.push(glyf.getUint16(pos)); + pos += 2; + } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { + transf.push(glyf.getUint16(pos), glyf.getUint16(pos + 2)); + pos += 4; + } else if (flags & WE_HAVE_A_TWO_BY_TWO) { + transf.push(glyf.getUint16(pos), glyf.getUint16(pos + 2), glyf.getUint16(pos + 4), glyf.getUint16(pos + 6)); + pos += 8; + } + let instructions = null; + if (flags & WE_HAVE_INSTRUCTIONS) { + const instructionLength = glyf.getUint16(pos); + pos += 2; + instructions = new Uint8Array(glyf).slice(pos, pos + instructionLength); + pos += instructionLength; + } + return [pos - spos, new CompositeGlyph({ + flags, + glyphIndex, + argument1, + argument2, + transf, + instructions + })]; + } + getSize() { + let size = 2 + 2 + this.transf.length * 2; + if (this.flags & WE_HAVE_INSTRUCTIONS) { + size += 2 + this.instructions.length; + } + size += 2; + if (this.flags & 2) { + if (!(this.argument1 >= -128 && this.argument1 <= 127 && this.argument2 >= -128 && this.argument2 <= 127)) { + size += 2; + } + } else if (!(this.argument1 >= 0 && this.argument1 <= 255 && this.argument2 >= 0 && this.argument2 <= 255)) { + size += 2; + } + return size; + } + write(pos, buf) { + const spos = pos; + if (this.flags & ARGS_ARE_XY_VALUES) { + if (!(this.argument1 >= -128 && this.argument1 <= 127 && this.argument2 >= -128 && this.argument2 <= 127)) { + this.flags |= ARG_1_AND_2_ARE_WORDS; + } + } else if (!(this.argument1 >= 0 && this.argument1 <= 255 && this.argument2 >= 0 && this.argument2 <= 255)) { + this.flags |= ARG_1_AND_2_ARE_WORDS; + } + buf.setUint16(pos, this.flags); + buf.setUint16(pos + 2, this.glyphIndex); + pos += 4; + if (this.flags & ARG_1_AND_2_ARE_WORDS) { + if (this.flags & ARGS_ARE_XY_VALUES) { + buf.setInt16(pos, this.argument1); + buf.setInt16(pos + 2, this.argument2); + } else { + buf.setUint16(pos, this.argument1); + buf.setUint16(pos + 2, this.argument2); + } + pos += 4; + } else { + buf.setUint8(pos, this.argument1); + buf.setUint8(pos + 1, this.argument2); + pos += 2; + } + if (this.flags & WE_HAVE_INSTRUCTIONS) { + buf.setUint16(pos, this.instructions.length); + pos += 2; + if (this.instructions.length) { + new Uint8Array(buf.buffer, 0, buf.buffer.byteLength).set(this.instructions, pos); + pos += this.instructions.length; + } + } + return pos - spos; + } + scale(x, factor) {} +} + +/***/ }), +/* 47 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.OpenTypeFileBuilder = void 0; +var _core_utils = __w_pdfjs_require__(3); +var _util = __w_pdfjs_require__(2); +function writeInt16(dest, offset, num) { + dest[offset] = num >> 8 & 0xff; + dest[offset + 1] = num & 0xff; +} +function writeInt32(dest, offset, num) { + dest[offset] = num >> 24 & 0xff; + dest[offset + 1] = num >> 16 & 0xff; + dest[offset + 2] = num >> 8 & 0xff; + dest[offset + 3] = num & 0xff; +} +function writeData(dest, offset, data) { + if (data instanceof Uint8Array) { + dest.set(data, offset); + } else if (typeof data === "string") { + for (let i = 0, ii = data.length; i < ii; i++) { + dest[offset++] = data.charCodeAt(i) & 0xff; + } + } else { + for (const num of data) { + dest[offset++] = num & 0xff; + } + } +} +const OTF_HEADER_SIZE = 12; +const OTF_TABLE_ENTRY_SIZE = 16; +class OpenTypeFileBuilder { + constructor(sfnt) { + this.sfnt = sfnt; + this.tables = Object.create(null); + } + static getSearchParams(entriesCount, entrySize) { + let maxPower2 = 1, + log2 = 0; + while ((maxPower2 ^ entriesCount) > maxPower2) { + maxPower2 <<= 1; + log2++; + } + const searchRange = maxPower2 * entrySize; + return { + range: searchRange, + entry: log2, + rangeShift: entrySize * entriesCount - searchRange + }; + } + toArray() { + let sfnt = this.sfnt; + const tables = this.tables; + const tablesNames = Object.keys(tables); + tablesNames.sort(); + const numTables = tablesNames.length; + let i, j, jj, table, tableName; + let offset = OTF_HEADER_SIZE + numTables * OTF_TABLE_ENTRY_SIZE; + const tableOffsets = [offset]; + for (i = 0; i < numTables; i++) { + table = tables[tablesNames[i]]; + const paddedLength = (table.length + 3 & ~3) >>> 0; + offset += paddedLength; + tableOffsets.push(offset); + } + const file = new Uint8Array(offset); + for (i = 0; i < numTables; i++) { + table = tables[tablesNames[i]]; + writeData(file, tableOffsets[i], table); + } + if (sfnt === "true") { + sfnt = (0, _util.string32)(0x00010000); + } + file[0] = sfnt.charCodeAt(0) & 0xff; + file[1] = sfnt.charCodeAt(1) & 0xff; + file[2] = sfnt.charCodeAt(2) & 0xff; + file[3] = sfnt.charCodeAt(3) & 0xff; + writeInt16(file, 4, numTables); + const searchParams = OpenTypeFileBuilder.getSearchParams(numTables, 16); + writeInt16(file, 6, searchParams.range); + writeInt16(file, 8, searchParams.entry); + writeInt16(file, 10, searchParams.rangeShift); + offset = OTF_HEADER_SIZE; + for (i = 0; i < numTables; i++) { + tableName = tablesNames[i]; + file[offset] = tableName.charCodeAt(0) & 0xff; + file[offset + 1] = tableName.charCodeAt(1) & 0xff; + file[offset + 2] = tableName.charCodeAt(2) & 0xff; + file[offset + 3] = tableName.charCodeAt(3) & 0xff; + let checksum = 0; + for (j = tableOffsets[i], jj = tableOffsets[i + 1]; j < jj; j += 4) { + const quad = (0, _core_utils.readUint32)(file, j); + checksum = checksum + quad >>> 0; + } + writeInt32(file, offset + 4, checksum); + writeInt32(file, offset + 8, tableOffsets[i]); + writeInt32(file, offset + 12, tables[tableName].length); + offset += OTF_TABLE_ENTRY_SIZE; + } + return file; + } + addTable(tag, data) { + if (tag in this.tables) { + throw new Error("Table " + tag + " already exists"); + } + this.tables[tag] = data; + } +} +exports.OpenTypeFileBuilder = OpenTypeFileBuilder; + +/***/ }), +/* 48 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Type1Font = void 0; +var _cff_parser = __w_pdfjs_require__(35); +var _util = __w_pdfjs_require__(2); +var _fonts_utils = __w_pdfjs_require__(38); +var _core_utils = __w_pdfjs_require__(3); +var _stream = __w_pdfjs_require__(8); +var _type1_parser = __w_pdfjs_require__(49); +function findBlock(streamBytes, signature, startIndex) { + const streamBytesLength = streamBytes.length; + const signatureLength = signature.length; + const scanLength = streamBytesLength - signatureLength; + let i = startIndex, + found = false; + while (i < scanLength) { + let j = 0; + while (j < signatureLength && streamBytes[i + j] === signature[j]) { + j++; + } + if (j >= signatureLength) { + i += j; + while (i < streamBytesLength && (0, _core_utils.isWhiteSpace)(streamBytes[i])) { + i++; + } + found = true; + break; + } + i++; + } + return { + found, + length: i + }; +} +function getHeaderBlock(stream, suggestedLength) { + const EEXEC_SIGNATURE = [0x65, 0x65, 0x78, 0x65, 0x63]; + const streamStartPos = stream.pos; + let headerBytes, headerBytesLength, block; + try { + headerBytes = stream.getBytes(suggestedLength); + headerBytesLength = headerBytes.length; + } catch {} + if (headerBytesLength === suggestedLength) { + block = findBlock(headerBytes, EEXEC_SIGNATURE, suggestedLength - 2 * EEXEC_SIGNATURE.length); + if (block.found && block.length === suggestedLength) { + return { + stream: new _stream.Stream(headerBytes), + length: suggestedLength + }; + } + } + (0, _util.warn)('Invalid "Length1" property in Type1 font -- trying to recover.'); + stream.pos = streamStartPos; + const SCAN_BLOCK_LENGTH = 2048; + let actualLength; + while (true) { + const scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH); + block = findBlock(scanBytes, EEXEC_SIGNATURE, 0); + if (block.length === 0) { + break; + } + stream.pos += block.length; + if (block.found) { + actualLength = stream.pos - streamStartPos; + break; + } + } + stream.pos = streamStartPos; + if (actualLength) { + return { + stream: new _stream.Stream(stream.getBytes(actualLength)), + length: actualLength + }; + } + (0, _util.warn)('Unable to recover "Length1" property in Type1 font -- using as is.'); + return { + stream: new _stream.Stream(stream.getBytes(suggestedLength)), + length: suggestedLength + }; +} +function getEexecBlock(stream, suggestedLength) { + const eexecBytes = stream.getBytes(); + if (eexecBytes.length === 0) { + throw new _util.FormatError("getEexecBlock - no font program found."); + } + return { + stream: new _stream.Stream(eexecBytes), + length: eexecBytes.length + }; +} +class Type1Font { + constructor(name, file, properties) { + const PFB_HEADER_SIZE = 6; + let headerBlockLength = properties.length1; + let eexecBlockLength = properties.length2; + let pfbHeader = file.peekBytes(PFB_HEADER_SIZE); + const pfbHeaderPresent = pfbHeader[0] === 0x80 && pfbHeader[1] === 0x01; + if (pfbHeaderPresent) { + file.skip(PFB_HEADER_SIZE); + headerBlockLength = pfbHeader[5] << 24 | pfbHeader[4] << 16 | pfbHeader[3] << 8 | pfbHeader[2]; + } + const headerBlock = getHeaderBlock(file, headerBlockLength); + const headerBlockParser = new _type1_parser.Type1Parser(headerBlock.stream, false, _fonts_utils.SEAC_ANALYSIS_ENABLED); + headerBlockParser.extractFontHeader(properties); + if (pfbHeaderPresent) { + pfbHeader = file.getBytes(PFB_HEADER_SIZE); + eexecBlockLength = pfbHeader[5] << 24 | pfbHeader[4] << 16 | pfbHeader[3] << 8 | pfbHeader[2]; + } + const eexecBlock = getEexecBlock(file, eexecBlockLength); + const eexecBlockParser = new _type1_parser.Type1Parser(eexecBlock.stream, true, _fonts_utils.SEAC_ANALYSIS_ENABLED); + const data = eexecBlockParser.extractFontProgram(properties); + for (const key in data.properties) { + properties[key] = data.properties[key]; + } + const charstrings = data.charstrings; + const type2Charstrings = this.getType2Charstrings(charstrings); + const subrs = this.getType2Subrs(data.subrs); + this.charstrings = charstrings; + this.data = this.wrap(name, type2Charstrings, this.charstrings, subrs, properties); + this.seacs = this.getSeacs(data.charstrings); + } + get numGlyphs() { + return this.charstrings.length + 1; + } + getCharset() { + const charset = [".notdef"]; + for (const { + glyphName + } of this.charstrings) { + charset.push(glyphName); + } + return charset; + } + getGlyphMapping(properties) { + const charstrings = this.charstrings; + if (properties.composite) { + const charCodeToGlyphId = Object.create(null); + for (let glyphId = 0, charstringsLen = charstrings.length; glyphId < charstringsLen; glyphId++) { + const charCode = properties.cMap.charCodeOf(glyphId); + charCodeToGlyphId[charCode] = glyphId + 1; + } + return charCodeToGlyphId; + } + const glyphNames = [".notdef"]; + let builtInEncoding, glyphId; + for (glyphId = 0; glyphId < charstrings.length; glyphId++) { + glyphNames.push(charstrings[glyphId].glyphName); + } + const encoding = properties.builtInEncoding; + if (encoding) { + builtInEncoding = Object.create(null); + for (const charCode in encoding) { + glyphId = glyphNames.indexOf(encoding[charCode]); + if (glyphId >= 0) { + builtInEncoding[charCode] = glyphId; + } + } + } + return (0, _fonts_utils.type1FontGlyphMapping)(properties, builtInEncoding, glyphNames); + } + hasGlyphId(id) { + if (id < 0 || id >= this.numGlyphs) { + return false; + } + if (id === 0) { + return true; + } + const glyph = this.charstrings[id - 1]; + return glyph.charstring.length > 0; + } + getSeacs(charstrings) { + const seacMap = []; + for (let i = 0, ii = charstrings.length; i < ii; i++) { + const charstring = charstrings[i]; + if (charstring.seac) { + seacMap[i + 1] = charstring.seac; + } + } + return seacMap; + } + getType2Charstrings(type1Charstrings) { + const type2Charstrings = []; + for (const type1Charstring of type1Charstrings) { + type2Charstrings.push(type1Charstring.charstring); + } + return type2Charstrings; + } + getType2Subrs(type1Subrs) { + let bias = 0; + const count = type1Subrs.length; + if (count < 1133) { + bias = 107; + } else if (count < 33769) { + bias = 1131; + } else { + bias = 32768; + } + const type2Subrs = []; + let i; + for (i = 0; i < bias; i++) { + type2Subrs.push([0x0b]); + } + for (i = 0; i < count; i++) { + type2Subrs.push(type1Subrs[i]); + } + return type2Subrs; + } + wrap(name, glyphs, charstrings, subrs, properties) { + const cff = new _cff_parser.CFF(); + cff.header = new _cff_parser.CFFHeader(1, 0, 4, 4); + cff.names = [name]; + const topDict = new _cff_parser.CFFTopDict(); + topDict.setByName("version", 391); + topDict.setByName("Notice", 392); + topDict.setByName("FullName", 393); + topDict.setByName("FamilyName", 394); + topDict.setByName("Weight", 395); + topDict.setByName("Encoding", null); + topDict.setByName("FontMatrix", properties.fontMatrix); + topDict.setByName("FontBBox", properties.bbox); + topDict.setByName("charset", null); + topDict.setByName("CharStrings", null); + topDict.setByName("Private", null); + cff.topDict = topDict; + const strings = new _cff_parser.CFFStrings(); + strings.add("Version 0.11"); + strings.add("See original notice"); + strings.add(name); + strings.add(name); + strings.add("Medium"); + cff.strings = strings; + cff.globalSubrIndex = new _cff_parser.CFFIndex(); + const count = glyphs.length; + const charsetArray = [".notdef"]; + let i, ii; + for (i = 0; i < count; i++) { + const glyphName = charstrings[i].glyphName; + const index = _cff_parser.CFFStandardStrings.indexOf(glyphName); + if (index === -1) { + strings.add(glyphName); + } + charsetArray.push(glyphName); + } + cff.charset = new _cff_parser.CFFCharset(false, 0, charsetArray); + const charStringsIndex = new _cff_parser.CFFIndex(); + charStringsIndex.add([0x8b, 0x0e]); + for (i = 0; i < count; i++) { + charStringsIndex.add(glyphs[i]); + } + cff.charStrings = charStringsIndex; + const privateDict = new _cff_parser.CFFPrivateDict(); + privateDict.setByName("Subrs", null); + const fields = ["BlueValues", "OtherBlues", "FamilyBlues", "FamilyOtherBlues", "StemSnapH", "StemSnapV", "BlueShift", "BlueFuzz", "BlueScale", "LanguageGroup", "ExpansionFactor", "ForceBold", "StdHW", "StdVW"]; + for (i = 0, ii = fields.length; i < ii; i++) { + const field = fields[i]; + if (!(field in properties.privateData)) { + continue; + } + const value = properties.privateData[field]; + if (Array.isArray(value)) { + for (let j = value.length - 1; j > 0; j--) { + value[j] -= value[j - 1]; + } + } + privateDict.setByName(field, value); + } + cff.topDict.privateDict = privateDict; + const subrIndex = new _cff_parser.CFFIndex(); + for (i = 0, ii = subrs.length; i < ii; i++) { + subrIndex.add(subrs[i]); + } + privateDict.subrsIndex = subrIndex; + const compiler = new _cff_parser.CFFCompiler(cff); + return compiler.compile(); + } +} +exports.Type1Font = Type1Font; + +/***/ }), +/* 49 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Type1Parser = void 0; +var _encodings = __w_pdfjs_require__(37); +var _core_utils = __w_pdfjs_require__(3); +var _stream = __w_pdfjs_require__(8); +var _util = __w_pdfjs_require__(2); +const HINTING_ENABLED = false; +const COMMAND_MAP = { + hstem: [1], + vstem: [3], + vmoveto: [4], + rlineto: [5], + hlineto: [6], + vlineto: [7], + rrcurveto: [8], + callsubr: [10], + flex: [12, 35], + drop: [12, 18], + endchar: [14], + rmoveto: [21], + hmoveto: [22], + vhcurveto: [30], + hvcurveto: [31] +}; +class Type1CharString { + constructor() { + this.width = 0; + this.lsb = 0; + this.flexing = false; + this.output = []; + this.stack = []; + } + convert(encoded, subrs, seacAnalysisEnabled) { + const count = encoded.length; + let error = false; + let wx, sbx, subrNumber; + for (let i = 0; i < count; i++) { + let value = encoded[i]; + if (value < 32) { + if (value === 12) { + value = (value << 8) + encoded[++i]; + } + switch (value) { + case 1: + if (!HINTING_ENABLED) { + this.stack = []; + break; + } + error = this.executeCommand(2, COMMAND_MAP.hstem); + break; + case 3: + if (!HINTING_ENABLED) { + this.stack = []; + break; + } + error = this.executeCommand(2, COMMAND_MAP.vstem); + break; + case 4: + if (this.flexing) { + if (this.stack.length < 1) { + error = true; + break; + } + const dy = this.stack.pop(); + this.stack.push(0, dy); + break; + } + error = this.executeCommand(1, COMMAND_MAP.vmoveto); + break; + case 5: + error = this.executeCommand(2, COMMAND_MAP.rlineto); + break; + case 6: + error = this.executeCommand(1, COMMAND_MAP.hlineto); + break; + case 7: + error = this.executeCommand(1, COMMAND_MAP.vlineto); + break; + case 8: + error = this.executeCommand(6, COMMAND_MAP.rrcurveto); + break; + case 9: + this.stack = []; + break; + case 10: + if (this.stack.length < 1) { + error = true; + break; + } + subrNumber = this.stack.pop(); + if (!subrs[subrNumber]) { + error = true; + break; + } + error = this.convert(subrs[subrNumber], subrs, seacAnalysisEnabled); + break; + case 11: + return error; + case 13: + if (this.stack.length < 2) { + error = true; + break; + } + wx = this.stack.pop(); + sbx = this.stack.pop(); + this.lsb = sbx; + this.width = wx; + this.stack.push(wx, sbx); + error = this.executeCommand(2, COMMAND_MAP.hmoveto); + break; + case 14: + this.output.push(COMMAND_MAP.endchar[0]); + break; + case 21: + if (this.flexing) { + break; + } + error = this.executeCommand(2, COMMAND_MAP.rmoveto); + break; + case 22: + if (this.flexing) { + this.stack.push(0); + break; + } + error = this.executeCommand(1, COMMAND_MAP.hmoveto); + break; + case 30: + error = this.executeCommand(4, COMMAND_MAP.vhcurveto); + break; + case 31: + error = this.executeCommand(4, COMMAND_MAP.hvcurveto); + break; + case (12 << 8) + 0: + this.stack = []; + break; + case (12 << 8) + 1: + if (!HINTING_ENABLED) { + this.stack = []; + break; + } + error = this.executeCommand(2, COMMAND_MAP.vstem); + break; + case (12 << 8) + 2: + if (!HINTING_ENABLED) { + this.stack = []; + break; + } + error = this.executeCommand(2, COMMAND_MAP.hstem); + break; + case (12 << 8) + 6: + if (seacAnalysisEnabled) { + const asb = this.stack.at(-5); + this.seac = this.stack.splice(-4, 4); + this.seac[0] += this.lsb - asb; + error = this.executeCommand(0, COMMAND_MAP.endchar); + } else { + error = this.executeCommand(4, COMMAND_MAP.endchar); + } + break; + case (12 << 8) + 7: + if (this.stack.length < 4) { + error = true; + break; + } + this.stack.pop(); + wx = this.stack.pop(); + const sby = this.stack.pop(); + sbx = this.stack.pop(); + this.lsb = sbx; + this.width = wx; + this.stack.push(wx, sbx, sby); + error = this.executeCommand(3, COMMAND_MAP.rmoveto); + break; + case (12 << 8) + 12: + if (this.stack.length < 2) { + error = true; + break; + } + const num2 = this.stack.pop(); + const num1 = this.stack.pop(); + this.stack.push(num1 / num2); + break; + case (12 << 8) + 16: + if (this.stack.length < 2) { + error = true; + break; + } + subrNumber = this.stack.pop(); + const numArgs = this.stack.pop(); + if (subrNumber === 0 && numArgs === 3) { + const flexArgs = this.stack.splice(-17, 17); + this.stack.push(flexArgs[2] + flexArgs[0], flexArgs[3] + flexArgs[1], flexArgs[4], flexArgs[5], flexArgs[6], flexArgs[7], flexArgs[8], flexArgs[9], flexArgs[10], flexArgs[11], flexArgs[12], flexArgs[13], flexArgs[14]); + error = this.executeCommand(13, COMMAND_MAP.flex, true); + this.flexing = false; + this.stack.push(flexArgs[15], flexArgs[16]); + } else if (subrNumber === 1 && numArgs === 0) { + this.flexing = true; + } + break; + case (12 << 8) + 17: + break; + case (12 << 8) + 33: + this.stack = []; + break; + default: + (0, _util.warn)('Unknown type 1 charstring command of "' + value + '"'); + break; + } + if (error) { + break; + } + continue; + } else if (value <= 246) { + value -= 139; + } else if (value <= 250) { + value = (value - 247) * 256 + encoded[++i] + 108; + } else if (value <= 254) { + value = -((value - 251) * 256) - encoded[++i] - 108; + } else { + value = (encoded[++i] & 0xff) << 24 | (encoded[++i] & 0xff) << 16 | (encoded[++i] & 0xff) << 8 | (encoded[++i] & 0xff) << 0; + } + this.stack.push(value); + } + return error; + } + executeCommand(howManyArgs, command, keepStack) { + const stackLength = this.stack.length; + if (howManyArgs > stackLength) { + return true; + } + const start = stackLength - howManyArgs; + for (let i = start; i < stackLength; i++) { + let value = this.stack[i]; + if (Number.isInteger(value)) { + this.output.push(28, value >> 8 & 0xff, value & 0xff); + } else { + value = 65536 * value | 0; + this.output.push(255, value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff); + } + } + this.output.push(...command); + if (keepStack) { + this.stack.splice(start, howManyArgs); + } else { + this.stack.length = 0; + } + return false; + } +} +const EEXEC_ENCRYPT_KEY = 55665; +const CHAR_STRS_ENCRYPT_KEY = 4330; +function isHexDigit(code) { + return code >= 48 && code <= 57 || code >= 65 && code <= 70 || code >= 97 && code <= 102; +} +function decrypt(data, key, discardNumber) { + if (discardNumber >= data.length) { + return new Uint8Array(0); + } + const c1 = 52845, + c2 = 22719; + let r = key | 0, + i, + j; + for (i = 0; i < discardNumber; i++) { + r = (data[i] + r) * c1 + c2 & (1 << 16) - 1; + } + const count = data.length - discardNumber; + const decrypted = new Uint8Array(count); + for (i = discardNumber, j = 0; j < count; i++, j++) { + const value = data[i]; + decrypted[j] = value ^ r >> 8; + r = (value + r) * c1 + c2 & (1 << 16) - 1; + } + return decrypted; +} +function decryptAscii(data, key, discardNumber) { + const c1 = 52845, + c2 = 22719; + let r = key | 0; + const count = data.length, + maybeLength = count >>> 1; + const decrypted = new Uint8Array(maybeLength); + let i, j; + for (i = 0, j = 0; i < count; i++) { + const digit1 = data[i]; + if (!isHexDigit(digit1)) { + continue; + } + i++; + let digit2; + while (i < count && !isHexDigit(digit2 = data[i])) { + i++; + } + if (i < count) { + const value = parseInt(String.fromCharCode(digit1, digit2), 16); + decrypted[j++] = value ^ r >> 8; + r = (value + r) * c1 + c2 & (1 << 16) - 1; + } + } + return decrypted.slice(discardNumber, j); +} +function isSpecial(c) { + return c === 0x2f || c === 0x5b || c === 0x5d || c === 0x7b || c === 0x7d || c === 0x28 || c === 0x29; +} +class Type1Parser { + constructor(stream, encrypted, seacAnalysisEnabled) { + if (encrypted) { + const data = stream.getBytes(); + const isBinary = !((isHexDigit(data[0]) || (0, _core_utils.isWhiteSpace)(data[0])) && isHexDigit(data[1]) && isHexDigit(data[2]) && isHexDigit(data[3]) && isHexDigit(data[4]) && isHexDigit(data[5]) && isHexDigit(data[6]) && isHexDigit(data[7])); + stream = new _stream.Stream(isBinary ? decrypt(data, EEXEC_ENCRYPT_KEY, 4) : decryptAscii(data, EEXEC_ENCRYPT_KEY, 4)); + } + this.seacAnalysisEnabled = !!seacAnalysisEnabled; + this.stream = stream; + this.nextChar(); + } + readNumberArray() { + this.getToken(); + const array = []; + while (true) { + const token = this.getToken(); + if (token === null || token === "]" || token === "}") { + break; + } + array.push(parseFloat(token || 0)); + } + return array; + } + readNumber() { + const token = this.getToken(); + return parseFloat(token || 0); + } + readInt() { + const token = this.getToken(); + return parseInt(token || 0, 10) | 0; + } + readBoolean() { + const token = this.getToken(); + return token === "true" ? 1 : 0; + } + nextChar() { + return this.currentChar = this.stream.getByte(); + } + prevChar() { + this.stream.skip(-2); + return this.currentChar = this.stream.getByte(); + } + getToken() { + let comment = false; + let ch = this.currentChar; + while (true) { + if (ch === -1) { + return null; + } + if (comment) { + if (ch === 0x0a || ch === 0x0d) { + comment = false; + } + } else if (ch === 0x25) { + comment = true; + } else if (!(0, _core_utils.isWhiteSpace)(ch)) { + break; + } + ch = this.nextChar(); + } + if (isSpecial(ch)) { + this.nextChar(); + return String.fromCharCode(ch); + } + let token = ""; + do { + token += String.fromCharCode(ch); + ch = this.nextChar(); + } while (ch >= 0 && !(0, _core_utils.isWhiteSpace)(ch) && !isSpecial(ch)); + return token; + } + readCharStrings(bytes, lenIV) { + if (lenIV === -1) { + return bytes; + } + return decrypt(bytes, CHAR_STRS_ENCRYPT_KEY, lenIV); + } + extractFontProgram(properties) { + const stream = this.stream; + const subrs = [], + charstrings = []; + const privateData = Object.create(null); + privateData.lenIV = 4; + const program = { + subrs: [], + charstrings: [], + properties: { + privateData + } + }; + let token, length, data, lenIV; + while ((token = this.getToken()) !== null) { + if (token !== "/") { + continue; + } + token = this.getToken(); + switch (token) { + case "CharStrings": + this.getToken(); + this.getToken(); + this.getToken(); + this.getToken(); + while (true) { + token = this.getToken(); + if (token === null || token === "end") { + break; + } + if (token !== "/") { + continue; + } + const glyph = this.getToken(); + length = this.readInt(); + this.getToken(); + data = length > 0 ? stream.getBytes(length) : new Uint8Array(0); + lenIV = program.properties.privateData.lenIV; + const encoded = this.readCharStrings(data, lenIV); + this.nextChar(); + token = this.getToken(); + if (token === "noaccess") { + this.getToken(); + } else if (token === "/") { + this.prevChar(); + } + charstrings.push({ + glyph, + encoded + }); + } + break; + case "Subrs": + this.readInt(); + this.getToken(); + while (this.getToken() === "dup") { + const index = this.readInt(); + length = this.readInt(); + this.getToken(); + data = length > 0 ? stream.getBytes(length) : new Uint8Array(0); + lenIV = program.properties.privateData.lenIV; + const encoded = this.readCharStrings(data, lenIV); + this.nextChar(); + token = this.getToken(); + if (token === "noaccess") { + this.getToken(); + } + subrs[index] = encoded; + } + break; + case "BlueValues": + case "OtherBlues": + case "FamilyBlues": + case "FamilyOtherBlues": + const blueArray = this.readNumberArray(); + if (blueArray.length > 0 && blueArray.length % 2 === 0 && HINTING_ENABLED) { + program.properties.privateData[token] = blueArray; + } + break; + case "StemSnapH": + case "StemSnapV": + program.properties.privateData[token] = this.readNumberArray(); + break; + case "StdHW": + case "StdVW": + program.properties.privateData[token] = this.readNumberArray()[0]; + break; + case "BlueShift": + case "lenIV": + case "BlueFuzz": + case "BlueScale": + case "LanguageGroup": + program.properties.privateData[token] = this.readNumber(); + break; + case "ExpansionFactor": + program.properties.privateData[token] = this.readNumber() || 0.06; + break; + case "ForceBold": + program.properties.privateData[token] = this.readBoolean(); + break; + } + } + for (const { + encoded, + glyph + } of charstrings) { + const charString = new Type1CharString(); + const error = charString.convert(encoded, subrs, this.seacAnalysisEnabled); + let output = charString.output; + if (error) { + output = [14]; + } + const charStringObject = { + glyphName: glyph, + charstring: output, + width: charString.width, + lsb: charString.lsb, + seac: charString.seac + }; + if (glyph === ".notdef") { + program.charstrings.unshift(charStringObject); + } else { + program.charstrings.push(charStringObject); + } + if (properties.builtInEncoding) { + const index = properties.builtInEncoding.indexOf(glyph); + if (index > -1 && properties.widths[index] === undefined && index >= properties.firstChar && index <= properties.lastChar) { + properties.widths[index] = charString.width; + } + } + } + return program; + } + extractFontHeader(properties) { + let token; + while ((token = this.getToken()) !== null) { + if (token !== "/") { + continue; + } + token = this.getToken(); + switch (token) { + case "FontMatrix": + const matrix = this.readNumberArray(); + properties.fontMatrix = matrix; + break; + case "Encoding": + const encodingArg = this.getToken(); + let encoding; + if (!/^\d+$/.test(encodingArg)) { + encoding = (0, _encodings.getEncoding)(encodingArg); + } else { + encoding = []; + const size = parseInt(encodingArg, 10) | 0; + this.getToken(); + for (let j = 0; j < size; j++) { + token = this.getToken(); + while (token !== "dup" && token !== "def") { + token = this.getToken(); + if (token === null) { + return; + } + } + if (token === "def") { + break; + } + const index = this.readInt(); + this.getToken(); + const glyph = this.getToken(); + encoding[index] = glyph; + this.getToken(); + } + } + properties.builtInEncoding = encoding; + break; + case "FontBBox": + const fontBBox = this.readNumberArray(); + properties.ascent = Math.max(fontBBox[3], fontBBox[1]); + properties.descent = Math.min(fontBBox[1], fontBBox[3]); + properties.ascentScaled = true; + break; + } + } + } +} +exports.Type1Parser = Type1Parser; + +/***/ }), +/* 50 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Pattern = void 0; +exports.clearPatternCaches = clearPatternCaches; +exports.getTilingPatternIR = getTilingPatternIR; +var _util = __w_pdfjs_require__(2); +var _base_stream = __w_pdfjs_require__(5); +var _colorspace = __w_pdfjs_require__(12); +var _core_utils = __w_pdfjs_require__(3); +const ShadingType = { + FUNCTION_BASED: 1, + AXIAL: 2, + RADIAL: 3, + FREE_FORM_MESH: 4, + LATTICE_FORM_MESH: 5, + COONS_PATCH_MESH: 6, + TENSOR_PATCH_MESH: 7 +}; +class Pattern { + constructor() { + (0, _util.unreachable)("Cannot initialize Pattern."); + } + static parseShading(shading, xref, res, pdfFunctionFactory, localColorSpaceCache) { + const dict = shading instanceof _base_stream.BaseStream ? shading.dict : shading; + const type = dict.get("ShadingType"); + try { + switch (type) { + case ShadingType.AXIAL: + case ShadingType.RADIAL: + return new RadialAxialShading(dict, xref, res, pdfFunctionFactory, localColorSpaceCache); + case ShadingType.FREE_FORM_MESH: + case ShadingType.LATTICE_FORM_MESH: + case ShadingType.COONS_PATCH_MESH: + case ShadingType.TENSOR_PATCH_MESH: + return new MeshShading(shading, xref, res, pdfFunctionFactory, localColorSpaceCache); + default: + throw new _util.FormatError("Unsupported ShadingType: " + type); + } + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.warn)(ex); + return new DummyShading(); + } + } +} +exports.Pattern = Pattern; +class BaseShading { + static SMALL_NUMBER = 1e-6; + constructor() { + if (this.constructor === BaseShading) { + (0, _util.unreachable)("Cannot initialize BaseShading."); + } + } + getIR() { + (0, _util.unreachable)("Abstract method `getIR` called."); + } +} +class RadialAxialShading extends BaseShading { + constructor(dict, xref, resources, pdfFunctionFactory, localColorSpaceCache) { + super(); + this.coordsArr = dict.getArray("Coords"); + this.shadingType = dict.get("ShadingType"); + const cs = _colorspace.ColorSpace.parse({ + cs: dict.getRaw("CS") || dict.getRaw("ColorSpace"), + xref, + resources, + pdfFunctionFactory, + localColorSpaceCache + }); + const bbox = dict.getArray("BBox"); + this.bbox = Array.isArray(bbox) && bbox.length === 4 ? _util.Util.normalizeRect(bbox) : null; + let t0 = 0.0, + t1 = 1.0; + if (dict.has("Domain")) { + const domainArr = dict.getArray("Domain"); + t0 = domainArr[0]; + t1 = domainArr[1]; + } + let extendStart = false, + extendEnd = false; + if (dict.has("Extend")) { + const extendArr = dict.getArray("Extend"); + extendStart = extendArr[0]; + extendEnd = extendArr[1]; + } + if (this.shadingType === ShadingType.RADIAL && (!extendStart || !extendEnd)) { + const [x1, y1, r1, x2, y2, r2] = this.coordsArr; + const distance = Math.hypot(x1 - x2, y1 - y2); + if (r1 <= r2 + distance && r2 <= r1 + distance) { + (0, _util.warn)("Unsupported radial gradient."); + } + } + this.extendStart = extendStart; + this.extendEnd = extendEnd; + const fnObj = dict.getRaw("Function"); + const fn = pdfFunctionFactory.createFromArray(fnObj); + const NUMBER_OF_SAMPLES = 840; + const step = (t1 - t0) / NUMBER_OF_SAMPLES; + const colorStops = this.colorStops = []; + if (t0 >= t1 || step <= 0) { + (0, _util.info)("Bad shading domain."); + return; + } + const color = new Float32Array(cs.numComps), + ratio = new Float32Array(1); + let rgbColor; + let iBase = 0; + ratio[0] = t0; + fn(ratio, 0, color, 0); + let rgbBase = cs.getRgb(color, 0); + const cssColorBase = _util.Util.makeHexColor(rgbBase[0], rgbBase[1], rgbBase[2]); + colorStops.push([0, cssColorBase]); + let iPrev = 1; + ratio[0] = t0 + step; + fn(ratio, 0, color, 0); + let rgbPrev = cs.getRgb(color, 0); + let maxSlopeR = rgbPrev[0] - rgbBase[0] + 1; + let maxSlopeG = rgbPrev[1] - rgbBase[1] + 1; + let maxSlopeB = rgbPrev[2] - rgbBase[2] + 1; + let minSlopeR = rgbPrev[0] - rgbBase[0] - 1; + let minSlopeG = rgbPrev[1] - rgbBase[1] - 1; + let minSlopeB = rgbPrev[2] - rgbBase[2] - 1; + for (let i = 2; i < NUMBER_OF_SAMPLES; i++) { + ratio[0] = t0 + i * step; + fn(ratio, 0, color, 0); + rgbColor = cs.getRgb(color, 0); + const run = i - iBase; + maxSlopeR = Math.min(maxSlopeR, (rgbColor[0] - rgbBase[0] + 1) / run); + maxSlopeG = Math.min(maxSlopeG, (rgbColor[1] - rgbBase[1] + 1) / run); + maxSlopeB = Math.min(maxSlopeB, (rgbColor[2] - rgbBase[2] + 1) / run); + minSlopeR = Math.max(minSlopeR, (rgbColor[0] - rgbBase[0] - 1) / run); + minSlopeG = Math.max(minSlopeG, (rgbColor[1] - rgbBase[1] - 1) / run); + minSlopeB = Math.max(minSlopeB, (rgbColor[2] - rgbBase[2] - 1) / run); + const slopesExist = minSlopeR <= maxSlopeR && minSlopeG <= maxSlopeG && minSlopeB <= maxSlopeB; + if (!slopesExist) { + const cssColor = _util.Util.makeHexColor(rgbPrev[0], rgbPrev[1], rgbPrev[2]); + colorStops.push([iPrev / NUMBER_OF_SAMPLES, cssColor]); + maxSlopeR = rgbColor[0] - rgbPrev[0] + 1; + maxSlopeG = rgbColor[1] - rgbPrev[1] + 1; + maxSlopeB = rgbColor[2] - rgbPrev[2] + 1; + minSlopeR = rgbColor[0] - rgbPrev[0] - 1; + minSlopeG = rgbColor[1] - rgbPrev[1] - 1; + minSlopeB = rgbColor[2] - rgbPrev[2] - 1; + iBase = iPrev; + rgbBase = rgbPrev; + } + iPrev = i; + rgbPrev = rgbColor; + } + const cssColor = _util.Util.makeHexColor(rgbPrev[0], rgbPrev[1], rgbPrev[2]); + colorStops.push([1, cssColor]); + let background = "transparent"; + if (dict.has("Background")) { + rgbColor = cs.getRgb(dict.get("Background"), 0); + background = _util.Util.makeHexColor(rgbColor[0], rgbColor[1], rgbColor[2]); + } + if (!extendStart) { + colorStops.unshift([0, background]); + colorStops[1][0] += BaseShading.SMALL_NUMBER; + } + if (!extendEnd) { + colorStops.at(-1)[0] -= BaseShading.SMALL_NUMBER; + colorStops.push([1, background]); + } + this.colorStops = colorStops; + } + getIR() { + const coordsArr = this.coordsArr; + const shadingType = this.shadingType; + let type, p0, p1, r0, r1; + if (shadingType === ShadingType.AXIAL) { + p0 = [coordsArr[0], coordsArr[1]]; + p1 = [coordsArr[2], coordsArr[3]]; + r0 = null; + r1 = null; + type = "axial"; + } else if (shadingType === ShadingType.RADIAL) { + p0 = [coordsArr[0], coordsArr[1]]; + p1 = [coordsArr[3], coordsArr[4]]; + r0 = coordsArr[2]; + r1 = coordsArr[5]; + type = "radial"; + } else { + (0, _util.unreachable)(`getPattern type unknown: ${shadingType}`); + } + return ["RadialAxial", type, this.bbox, this.colorStops, p0, p1, r0, r1]; + } +} +class MeshStreamReader { + constructor(stream, context) { + this.stream = stream; + this.context = context; + this.buffer = 0; + this.bufferLength = 0; + const numComps = context.numComps; + this.tmpCompsBuf = new Float32Array(numComps); + const csNumComps = context.colorSpace.numComps; + this.tmpCsCompsBuf = context.colorFn ? new Float32Array(csNumComps) : this.tmpCompsBuf; + } + get hasData() { + if (this.stream.end) { + return this.stream.pos < this.stream.end; + } + if (this.bufferLength > 0) { + return true; + } + const nextByte = this.stream.getByte(); + if (nextByte < 0) { + return false; + } + this.buffer = nextByte; + this.bufferLength = 8; + return true; + } + readBits(n) { + let buffer = this.buffer; + let bufferLength = this.bufferLength; + if (n === 32) { + if (bufferLength === 0) { + return (this.stream.getByte() << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte()) >>> 0; + } + buffer = buffer << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte(); + const nextByte = this.stream.getByte(); + this.buffer = nextByte & (1 << bufferLength) - 1; + return (buffer << 8 - bufferLength | (nextByte & 0xff) >> bufferLength) >>> 0; + } + if (n === 8 && bufferLength === 0) { + return this.stream.getByte(); + } + while (bufferLength < n) { + buffer = buffer << 8 | this.stream.getByte(); + bufferLength += 8; + } + bufferLength -= n; + this.bufferLength = bufferLength; + this.buffer = buffer & (1 << bufferLength) - 1; + return buffer >> bufferLength; + } + align() { + this.buffer = 0; + this.bufferLength = 0; + } + readFlag() { + return this.readBits(this.context.bitsPerFlag); + } + readCoordinate() { + const bitsPerCoordinate = this.context.bitsPerCoordinate; + const xi = this.readBits(bitsPerCoordinate); + const yi = this.readBits(bitsPerCoordinate); + const decode = this.context.decode; + const scale = bitsPerCoordinate < 32 ? 1 / ((1 << bitsPerCoordinate) - 1) : 2.3283064365386963e-10; + return [xi * scale * (decode[1] - decode[0]) + decode[0], yi * scale * (decode[3] - decode[2]) + decode[2]]; + } + readComponents() { + const numComps = this.context.numComps; + const bitsPerComponent = this.context.bitsPerComponent; + const scale = bitsPerComponent < 32 ? 1 / ((1 << bitsPerComponent) - 1) : 2.3283064365386963e-10; + const decode = this.context.decode; + const components = this.tmpCompsBuf; + for (let i = 0, j = 4; i < numComps; i++, j += 2) { + const ci = this.readBits(bitsPerComponent); + components[i] = ci * scale * (decode[j + 1] - decode[j]) + decode[j]; + } + const color = this.tmpCsCompsBuf; + if (this.context.colorFn) { + this.context.colorFn(components, 0, color, 0); + } + return this.context.colorSpace.getRgb(color, 0); + } +} +let bCache = Object.create(null); +function buildB(count) { + const lut = []; + for (let i = 0; i <= count; i++) { + const t = i / count, + t_ = 1 - t; + lut.push(new Float32Array([t_ ** 3, 3 * t * t_ ** 2, 3 * t ** 2 * t_, t ** 3])); + } + return lut; +} +function getB(count) { + return bCache[count] ||= buildB(count); +} +function clearPatternCaches() { + bCache = Object.create(null); +} +class MeshShading extends BaseShading { + static MIN_SPLIT_PATCH_CHUNKS_AMOUNT = 3; + static MAX_SPLIT_PATCH_CHUNKS_AMOUNT = 20; + static TRIANGLE_DENSITY = 20; + constructor(stream, xref, resources, pdfFunctionFactory, localColorSpaceCache) { + super(); + if (!(stream instanceof _base_stream.BaseStream)) { + throw new _util.FormatError("Mesh data is not a stream"); + } + const dict = stream.dict; + this.shadingType = dict.get("ShadingType"); + const bbox = dict.getArray("BBox"); + this.bbox = Array.isArray(bbox) && bbox.length === 4 ? _util.Util.normalizeRect(bbox) : null; + const cs = _colorspace.ColorSpace.parse({ + cs: dict.getRaw("CS") || dict.getRaw("ColorSpace"), + xref, + resources, + pdfFunctionFactory, + localColorSpaceCache + }); + this.background = dict.has("Background") ? cs.getRgb(dict.get("Background"), 0) : null; + const fnObj = dict.getRaw("Function"); + const fn = fnObj ? pdfFunctionFactory.createFromArray(fnObj) : null; + this.coords = []; + this.colors = []; + this.figures = []; + const decodeContext = { + bitsPerCoordinate: dict.get("BitsPerCoordinate"), + bitsPerComponent: dict.get("BitsPerComponent"), + bitsPerFlag: dict.get("BitsPerFlag"), + decode: dict.getArray("Decode"), + colorFn: fn, + colorSpace: cs, + numComps: fn ? 1 : cs.numComps + }; + const reader = new MeshStreamReader(stream, decodeContext); + let patchMesh = false; + switch (this.shadingType) { + case ShadingType.FREE_FORM_MESH: + this._decodeType4Shading(reader); + break; + case ShadingType.LATTICE_FORM_MESH: + const verticesPerRow = dict.get("VerticesPerRow") | 0; + if (verticesPerRow < 2) { + throw new _util.FormatError("Invalid VerticesPerRow"); + } + this._decodeType5Shading(reader, verticesPerRow); + break; + case ShadingType.COONS_PATCH_MESH: + this._decodeType6Shading(reader); + patchMesh = true; + break; + case ShadingType.TENSOR_PATCH_MESH: + this._decodeType7Shading(reader); + patchMesh = true; + break; + default: + (0, _util.unreachable)("Unsupported mesh type."); + break; + } + if (patchMesh) { + this._updateBounds(); + for (let i = 0, ii = this.figures.length; i < ii; i++) { + this._buildFigureFromPatch(i); + } + } + this._updateBounds(); + this._packData(); + } + _decodeType4Shading(reader) { + const coords = this.coords; + const colors = this.colors; + const operators = []; + const ps = []; + let verticesLeft = 0; + while (reader.hasData) { + const f = reader.readFlag(); + const coord = reader.readCoordinate(); + const color = reader.readComponents(); + if (verticesLeft === 0) { + if (!(0 <= f && f <= 2)) { + throw new _util.FormatError("Unknown type4 flag"); + } + switch (f) { + case 0: + verticesLeft = 3; + break; + case 1: + ps.push(ps.at(-2), ps.at(-1)); + verticesLeft = 1; + break; + case 2: + ps.push(ps.at(-3), ps.at(-1)); + verticesLeft = 1; + break; + } + operators.push(f); + } + ps.push(coords.length); + coords.push(coord); + colors.push(color); + verticesLeft--; + reader.align(); + } + this.figures.push({ + type: "triangles", + coords: new Int32Array(ps), + colors: new Int32Array(ps) + }); + } + _decodeType5Shading(reader, verticesPerRow) { + const coords = this.coords; + const colors = this.colors; + const ps = []; + while (reader.hasData) { + const coord = reader.readCoordinate(); + const color = reader.readComponents(); + ps.push(coords.length); + coords.push(coord); + colors.push(color); + } + this.figures.push({ + type: "lattice", + coords: new Int32Array(ps), + colors: new Int32Array(ps), + verticesPerRow + }); + } + _decodeType6Shading(reader) { + const coords = this.coords; + const colors = this.colors; + const ps = new Int32Array(16); + const cs = new Int32Array(4); + while (reader.hasData) { + const f = reader.readFlag(); + if (!(0 <= f && f <= 3)) { + throw new _util.FormatError("Unknown type6 flag"); + } + const pi = coords.length; + for (let i = 0, ii = f !== 0 ? 8 : 12; i < ii; i++) { + coords.push(reader.readCoordinate()); + } + const ci = colors.length; + for (let i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) { + colors.push(reader.readComponents()); + } + let tmp1, tmp2, tmp3, tmp4; + switch (f) { + case 0: + ps[12] = pi + 3; + ps[13] = pi + 4; + ps[14] = pi + 5; + ps[15] = pi + 6; + ps[8] = pi + 2; + ps[11] = pi + 7; + ps[4] = pi + 1; + ps[7] = pi + 8; + ps[0] = pi; + ps[1] = pi + 11; + ps[2] = pi + 10; + ps[3] = pi + 9; + cs[2] = ci + 1; + cs[3] = ci + 2; + cs[0] = ci; + cs[1] = ci + 3; + break; + case 1: + tmp1 = ps[12]; + tmp2 = ps[13]; + tmp3 = ps[14]; + tmp4 = ps[15]; + ps[12] = tmp4; + ps[13] = pi + 0; + ps[14] = pi + 1; + ps[15] = pi + 2; + ps[8] = tmp3; + ps[11] = pi + 3; + ps[4] = tmp2; + ps[7] = pi + 4; + ps[0] = tmp1; + ps[1] = pi + 7; + ps[2] = pi + 6; + ps[3] = pi + 5; + tmp1 = cs[2]; + tmp2 = cs[3]; + cs[2] = tmp2; + cs[3] = ci; + cs[0] = tmp1; + cs[1] = ci + 1; + break; + case 2: + tmp1 = ps[15]; + tmp2 = ps[11]; + ps[12] = ps[3]; + ps[13] = pi + 0; + ps[14] = pi + 1; + ps[15] = pi + 2; + ps[8] = ps[7]; + ps[11] = pi + 3; + ps[4] = tmp2; + ps[7] = pi + 4; + ps[0] = tmp1; + ps[1] = pi + 7; + ps[2] = pi + 6; + ps[3] = pi + 5; + tmp1 = cs[3]; + cs[2] = cs[1]; + cs[3] = ci; + cs[0] = tmp1; + cs[1] = ci + 1; + break; + case 3: + ps[12] = ps[0]; + ps[13] = pi + 0; + ps[14] = pi + 1; + ps[15] = pi + 2; + ps[8] = ps[1]; + ps[11] = pi + 3; + ps[4] = ps[2]; + ps[7] = pi + 4; + ps[0] = ps[3]; + ps[1] = pi + 7; + ps[2] = pi + 6; + ps[3] = pi + 5; + cs[2] = cs[0]; + cs[3] = ci; + cs[0] = cs[1]; + cs[1] = ci + 1; + break; + } + ps[5] = coords.length; + coords.push([(-4 * coords[ps[0]][0] - coords[ps[15]][0] + 6 * (coords[ps[4]][0] + coords[ps[1]][0]) - 2 * (coords[ps[12]][0] + coords[ps[3]][0]) + 3 * (coords[ps[13]][0] + coords[ps[7]][0])) / 9, (-4 * coords[ps[0]][1] - coords[ps[15]][1] + 6 * (coords[ps[4]][1] + coords[ps[1]][1]) - 2 * (coords[ps[12]][1] + coords[ps[3]][1]) + 3 * (coords[ps[13]][1] + coords[ps[7]][1])) / 9]); + ps[6] = coords.length; + coords.push([(-4 * coords[ps[3]][0] - coords[ps[12]][0] + 6 * (coords[ps[2]][0] + coords[ps[7]][0]) - 2 * (coords[ps[0]][0] + coords[ps[15]][0]) + 3 * (coords[ps[4]][0] + coords[ps[14]][0])) / 9, (-4 * coords[ps[3]][1] - coords[ps[12]][1] + 6 * (coords[ps[2]][1] + coords[ps[7]][1]) - 2 * (coords[ps[0]][1] + coords[ps[15]][1]) + 3 * (coords[ps[4]][1] + coords[ps[14]][1])) / 9]); + ps[9] = coords.length; + coords.push([(-4 * coords[ps[12]][0] - coords[ps[3]][0] + 6 * (coords[ps[8]][0] + coords[ps[13]][0]) - 2 * (coords[ps[0]][0] + coords[ps[15]][0]) + 3 * (coords[ps[11]][0] + coords[ps[1]][0])) / 9, (-4 * coords[ps[12]][1] - coords[ps[3]][1] + 6 * (coords[ps[8]][1] + coords[ps[13]][1]) - 2 * (coords[ps[0]][1] + coords[ps[15]][1]) + 3 * (coords[ps[11]][1] + coords[ps[1]][1])) / 9]); + ps[10] = coords.length; + coords.push([(-4 * coords[ps[15]][0] - coords[ps[0]][0] + 6 * (coords[ps[11]][0] + coords[ps[14]][0]) - 2 * (coords[ps[12]][0] + coords[ps[3]][0]) + 3 * (coords[ps[2]][0] + coords[ps[8]][0])) / 9, (-4 * coords[ps[15]][1] - coords[ps[0]][1] + 6 * (coords[ps[11]][1] + coords[ps[14]][1]) - 2 * (coords[ps[12]][1] + coords[ps[3]][1]) + 3 * (coords[ps[2]][1] + coords[ps[8]][1])) / 9]); + this.figures.push({ + type: "patch", + coords: new Int32Array(ps), + colors: new Int32Array(cs) + }); + } + } + _decodeType7Shading(reader) { + const coords = this.coords; + const colors = this.colors; + const ps = new Int32Array(16); + const cs = new Int32Array(4); + while (reader.hasData) { + const f = reader.readFlag(); + if (!(0 <= f && f <= 3)) { + throw new _util.FormatError("Unknown type7 flag"); + } + const pi = coords.length; + for (let i = 0, ii = f !== 0 ? 12 : 16; i < ii; i++) { + coords.push(reader.readCoordinate()); + } + const ci = colors.length; + for (let i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) { + colors.push(reader.readComponents()); + } + let tmp1, tmp2, tmp3, tmp4; + switch (f) { + case 0: + ps[12] = pi + 3; + ps[13] = pi + 4; + ps[14] = pi + 5; + ps[15] = pi + 6; + ps[8] = pi + 2; + ps[9] = pi + 13; + ps[10] = pi + 14; + ps[11] = pi + 7; + ps[4] = pi + 1; + ps[5] = pi + 12; + ps[6] = pi + 15; + ps[7] = pi + 8; + ps[0] = pi; + ps[1] = pi + 11; + ps[2] = pi + 10; + ps[3] = pi + 9; + cs[2] = ci + 1; + cs[3] = ci + 2; + cs[0] = ci; + cs[1] = ci + 3; + break; + case 1: + tmp1 = ps[12]; + tmp2 = ps[13]; + tmp3 = ps[14]; + tmp4 = ps[15]; + ps[12] = tmp4; + ps[13] = pi + 0; + ps[14] = pi + 1; + ps[15] = pi + 2; + ps[8] = tmp3; + ps[9] = pi + 9; + ps[10] = pi + 10; + ps[11] = pi + 3; + ps[4] = tmp2; + ps[5] = pi + 8; + ps[6] = pi + 11; + ps[7] = pi + 4; + ps[0] = tmp1; + ps[1] = pi + 7; + ps[2] = pi + 6; + ps[3] = pi + 5; + tmp1 = cs[2]; + tmp2 = cs[3]; + cs[2] = tmp2; + cs[3] = ci; + cs[0] = tmp1; + cs[1] = ci + 1; + break; + case 2: + tmp1 = ps[15]; + tmp2 = ps[11]; + ps[12] = ps[3]; + ps[13] = pi + 0; + ps[14] = pi + 1; + ps[15] = pi + 2; + ps[8] = ps[7]; + ps[9] = pi + 9; + ps[10] = pi + 10; + ps[11] = pi + 3; + ps[4] = tmp2; + ps[5] = pi + 8; + ps[6] = pi + 11; + ps[7] = pi + 4; + ps[0] = tmp1; + ps[1] = pi + 7; + ps[2] = pi + 6; + ps[3] = pi + 5; + tmp1 = cs[3]; + cs[2] = cs[1]; + cs[3] = ci; + cs[0] = tmp1; + cs[1] = ci + 1; + break; + case 3: + ps[12] = ps[0]; + ps[13] = pi + 0; + ps[14] = pi + 1; + ps[15] = pi + 2; + ps[8] = ps[1]; + ps[9] = pi + 9; + ps[10] = pi + 10; + ps[11] = pi + 3; + ps[4] = ps[2]; + ps[5] = pi + 8; + ps[6] = pi + 11; + ps[7] = pi + 4; + ps[0] = ps[3]; + ps[1] = pi + 7; + ps[2] = pi + 6; + ps[3] = pi + 5; + cs[2] = cs[0]; + cs[3] = ci; + cs[0] = cs[1]; + cs[1] = ci + 1; + break; + } + this.figures.push({ + type: "patch", + coords: new Int32Array(ps), + colors: new Int32Array(cs) + }); + } + } + _buildFigureFromPatch(index) { + const figure = this.figures[index]; + (0, _util.assert)(figure.type === "patch", "Unexpected patch mesh figure"); + const coords = this.coords, + colors = this.colors; + const pi = figure.coords; + const ci = figure.colors; + const figureMinX = Math.min(coords[pi[0]][0], coords[pi[3]][0], coords[pi[12]][0], coords[pi[15]][0]); + const figureMinY = Math.min(coords[pi[0]][1], coords[pi[3]][1], coords[pi[12]][1], coords[pi[15]][1]); + const figureMaxX = Math.max(coords[pi[0]][0], coords[pi[3]][0], coords[pi[12]][0], coords[pi[15]][0]); + const figureMaxY = Math.max(coords[pi[0]][1], coords[pi[3]][1], coords[pi[12]][1], coords[pi[15]][1]); + let splitXBy = Math.ceil((figureMaxX - figureMinX) * MeshShading.TRIANGLE_DENSITY / (this.bounds[2] - this.bounds[0])); + splitXBy = Math.max(MeshShading.MIN_SPLIT_PATCH_CHUNKS_AMOUNT, Math.min(MeshShading.MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitXBy)); + let splitYBy = Math.ceil((figureMaxY - figureMinY) * MeshShading.TRIANGLE_DENSITY / (this.bounds[3] - this.bounds[1])); + splitYBy = Math.max(MeshShading.MIN_SPLIT_PATCH_CHUNKS_AMOUNT, Math.min(MeshShading.MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitYBy)); + const verticesPerRow = splitXBy + 1; + const figureCoords = new Int32Array((splitYBy + 1) * verticesPerRow); + const figureColors = new Int32Array((splitYBy + 1) * verticesPerRow); + let k = 0; + const cl = new Uint8Array(3), + cr = new Uint8Array(3); + const c0 = colors[ci[0]], + c1 = colors[ci[1]], + c2 = colors[ci[2]], + c3 = colors[ci[3]]; + const bRow = getB(splitYBy), + bCol = getB(splitXBy); + for (let row = 0; row <= splitYBy; row++) { + cl[0] = (c0[0] * (splitYBy - row) + c2[0] * row) / splitYBy | 0; + cl[1] = (c0[1] * (splitYBy - row) + c2[1] * row) / splitYBy | 0; + cl[2] = (c0[2] * (splitYBy - row) + c2[2] * row) / splitYBy | 0; + cr[0] = (c1[0] * (splitYBy - row) + c3[0] * row) / splitYBy | 0; + cr[1] = (c1[1] * (splitYBy - row) + c3[1] * row) / splitYBy | 0; + cr[2] = (c1[2] * (splitYBy - row) + c3[2] * row) / splitYBy | 0; + for (let col = 0; col <= splitXBy; col++, k++) { + if ((row === 0 || row === splitYBy) && (col === 0 || col === splitXBy)) { + continue; + } + let x = 0, + y = 0; + let q = 0; + for (let i = 0; i <= 3; i++) { + for (let j = 0; j <= 3; j++, q++) { + const m = bRow[row][i] * bCol[col][j]; + x += coords[pi[q]][0] * m; + y += coords[pi[q]][1] * m; + } + } + figureCoords[k] = coords.length; + coords.push([x, y]); + figureColors[k] = colors.length; + const newColor = new Uint8Array(3); + newColor[0] = (cl[0] * (splitXBy - col) + cr[0] * col) / splitXBy | 0; + newColor[1] = (cl[1] * (splitXBy - col) + cr[1] * col) / splitXBy | 0; + newColor[2] = (cl[2] * (splitXBy - col) + cr[2] * col) / splitXBy | 0; + colors.push(newColor); + } + } + figureCoords[0] = pi[0]; + figureColors[0] = ci[0]; + figureCoords[splitXBy] = pi[3]; + figureColors[splitXBy] = ci[1]; + figureCoords[verticesPerRow * splitYBy] = pi[12]; + figureColors[verticesPerRow * splitYBy] = ci[2]; + figureCoords[verticesPerRow * splitYBy + splitXBy] = pi[15]; + figureColors[verticesPerRow * splitYBy + splitXBy] = ci[3]; + this.figures[index] = { + type: "lattice", + coords: figureCoords, + colors: figureColors, + verticesPerRow + }; + } + _updateBounds() { + let minX = this.coords[0][0], + minY = this.coords[0][1], + maxX = minX, + maxY = minY; + for (let i = 1, ii = this.coords.length; i < ii; i++) { + const x = this.coords[i][0], + y = this.coords[i][1]; + minX = minX > x ? x : minX; + minY = minY > y ? y : minY; + maxX = maxX < x ? x : maxX; + maxY = maxY < y ? y : maxY; + } + this.bounds = [minX, minY, maxX, maxY]; + } + _packData() { + let i, ii, j, jj; + const coords = this.coords; + const coordsPacked = new Float32Array(coords.length * 2); + for (i = 0, j = 0, ii = coords.length; i < ii; i++) { + const xy = coords[i]; + coordsPacked[j++] = xy[0]; + coordsPacked[j++] = xy[1]; + } + this.coords = coordsPacked; + const colors = this.colors; + const colorsPacked = new Uint8Array(colors.length * 3); + for (i = 0, j = 0, ii = colors.length; i < ii; i++) { + const c = colors[i]; + colorsPacked[j++] = c[0]; + colorsPacked[j++] = c[1]; + colorsPacked[j++] = c[2]; + } + this.colors = colorsPacked; + const figures = this.figures; + for (i = 0, ii = figures.length; i < ii; i++) { + const figure = figures[i], + ps = figure.coords, + cs = figure.colors; + for (j = 0, jj = ps.length; j < jj; j++) { + ps[j] *= 2; + cs[j] *= 3; + } + } + } + getIR() { + return ["Mesh", this.shadingType, this.coords, this.colors, this.figures, this.bounds, this.bbox, this.background]; + } +} +class DummyShading extends BaseShading { + getIR() { + return ["Dummy"]; + } +} +function getTilingPatternIR(operatorList, dict, color) { + const matrix = dict.getArray("Matrix"); + const bbox = _util.Util.normalizeRect(dict.getArray("BBox")); + const xstep = dict.get("XStep"); + const ystep = dict.get("YStep"); + const paintType = dict.get("PaintType"); + const tilingType = dict.get("TilingType"); + if (bbox[2] - bbox[0] === 0 || bbox[3] - bbox[1] === 0) { + throw new _util.FormatError(`Invalid getTilingPatternIR /BBox array: [${bbox}].`); + } + return ["TilingPattern", color, operatorList, matrix, bbox, xstep, ystep, paintType, tilingType]; +} + +/***/ }), +/* 51 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getXfaFontDict = getXfaFontDict; +exports.getXfaFontName = getXfaFontName; +var _calibri_factors = __w_pdfjs_require__(52); +var _primitives = __w_pdfjs_require__(4); +var _helvetica_factors = __w_pdfjs_require__(53); +var _liberationsans_widths = __w_pdfjs_require__(54); +var _myriadpro_factors = __w_pdfjs_require__(55); +var _segoeui_factors = __w_pdfjs_require__(56); +var _core_utils = __w_pdfjs_require__(3); +var _fonts_utils = __w_pdfjs_require__(38); +const getXFAFontMap = (0, _core_utils.getLookupTableFactory)(function (t) { + t["MyriadPro-Regular"] = t["PdfJS-Fallback-Regular"] = { + name: "LiberationSans-Regular", + factors: _myriadpro_factors.MyriadProRegularFactors, + baseWidths: _liberationsans_widths.LiberationSansRegularWidths, + baseMapping: _liberationsans_widths.LiberationSansRegularMapping, + metrics: _myriadpro_factors.MyriadProRegularMetrics + }; + t["MyriadPro-Bold"] = t["PdfJS-Fallback-Bold"] = { + name: "LiberationSans-Bold", + factors: _myriadpro_factors.MyriadProBoldFactors, + baseWidths: _liberationsans_widths.LiberationSansBoldWidths, + baseMapping: _liberationsans_widths.LiberationSansBoldMapping, + metrics: _myriadpro_factors.MyriadProBoldMetrics + }; + t["MyriadPro-It"] = t["MyriadPro-Italic"] = t["PdfJS-Fallback-Italic"] = { + name: "LiberationSans-Italic", + factors: _myriadpro_factors.MyriadProItalicFactors, + baseWidths: _liberationsans_widths.LiberationSansItalicWidths, + baseMapping: _liberationsans_widths.LiberationSansItalicMapping, + metrics: _myriadpro_factors.MyriadProItalicMetrics + }; + t["MyriadPro-BoldIt"] = t["MyriadPro-BoldItalic"] = t["PdfJS-Fallback-BoldItalic"] = { + name: "LiberationSans-BoldItalic", + factors: _myriadpro_factors.MyriadProBoldItalicFactors, + baseWidths: _liberationsans_widths.LiberationSansBoldItalicWidths, + baseMapping: _liberationsans_widths.LiberationSansBoldItalicMapping, + metrics: _myriadpro_factors.MyriadProBoldItalicMetrics + }; + t.ArialMT = t.Arial = t["Arial-Regular"] = { + name: "LiberationSans-Regular", + baseWidths: _liberationsans_widths.LiberationSansRegularWidths, + baseMapping: _liberationsans_widths.LiberationSansRegularMapping + }; + t["Arial-BoldMT"] = t["Arial-Bold"] = { + name: "LiberationSans-Bold", + baseWidths: _liberationsans_widths.LiberationSansBoldWidths, + baseMapping: _liberationsans_widths.LiberationSansBoldMapping + }; + t["Arial-ItalicMT"] = t["Arial-Italic"] = { + name: "LiberationSans-Italic", + baseWidths: _liberationsans_widths.LiberationSansItalicWidths, + baseMapping: _liberationsans_widths.LiberationSansItalicMapping + }; + t["Arial-BoldItalicMT"] = t["Arial-BoldItalic"] = { + name: "LiberationSans-BoldItalic", + baseWidths: _liberationsans_widths.LiberationSansBoldItalicWidths, + baseMapping: _liberationsans_widths.LiberationSansBoldItalicMapping + }; + t["Calibri-Regular"] = { + name: "LiberationSans-Regular", + factors: _calibri_factors.CalibriRegularFactors, + baseWidths: _liberationsans_widths.LiberationSansRegularWidths, + baseMapping: _liberationsans_widths.LiberationSansRegularMapping, + metrics: _calibri_factors.CalibriRegularMetrics + }; + t["Calibri-Bold"] = { + name: "LiberationSans-Bold", + factors: _calibri_factors.CalibriBoldFactors, + baseWidths: _liberationsans_widths.LiberationSansBoldWidths, + baseMapping: _liberationsans_widths.LiberationSansBoldMapping, + metrics: _calibri_factors.CalibriBoldMetrics + }; + t["Calibri-Italic"] = { + name: "LiberationSans-Italic", + factors: _calibri_factors.CalibriItalicFactors, + baseWidths: _liberationsans_widths.LiberationSansItalicWidths, + baseMapping: _liberationsans_widths.LiberationSansItalicMapping, + metrics: _calibri_factors.CalibriItalicMetrics + }; + t["Calibri-BoldItalic"] = { + name: "LiberationSans-BoldItalic", + factors: _calibri_factors.CalibriBoldItalicFactors, + baseWidths: _liberationsans_widths.LiberationSansBoldItalicWidths, + baseMapping: _liberationsans_widths.LiberationSansBoldItalicMapping, + metrics: _calibri_factors.CalibriBoldItalicMetrics + }; + t["Segoeui-Regular"] = { + name: "LiberationSans-Regular", + factors: _segoeui_factors.SegoeuiRegularFactors, + baseWidths: _liberationsans_widths.LiberationSansRegularWidths, + baseMapping: _liberationsans_widths.LiberationSansRegularMapping, + metrics: _segoeui_factors.SegoeuiRegularMetrics + }; + t["Segoeui-Bold"] = { + name: "LiberationSans-Bold", + factors: _segoeui_factors.SegoeuiBoldFactors, + baseWidths: _liberationsans_widths.LiberationSansBoldWidths, + baseMapping: _liberationsans_widths.LiberationSansBoldMapping, + metrics: _segoeui_factors.SegoeuiBoldMetrics + }; + t["Segoeui-Italic"] = { + name: "LiberationSans-Italic", + factors: _segoeui_factors.SegoeuiItalicFactors, + baseWidths: _liberationsans_widths.LiberationSansItalicWidths, + baseMapping: _liberationsans_widths.LiberationSansItalicMapping, + metrics: _segoeui_factors.SegoeuiItalicMetrics + }; + t["Segoeui-BoldItalic"] = { + name: "LiberationSans-BoldItalic", + factors: _segoeui_factors.SegoeuiBoldItalicFactors, + baseWidths: _liberationsans_widths.LiberationSansBoldItalicWidths, + baseMapping: _liberationsans_widths.LiberationSansBoldItalicMapping, + metrics: _segoeui_factors.SegoeuiBoldItalicMetrics + }; + t["Helvetica-Regular"] = t.Helvetica = { + name: "LiberationSans-Regular", + factors: _helvetica_factors.HelveticaRegularFactors, + baseWidths: _liberationsans_widths.LiberationSansRegularWidths, + baseMapping: _liberationsans_widths.LiberationSansRegularMapping, + metrics: _helvetica_factors.HelveticaRegularMetrics + }; + t["Helvetica-Bold"] = { + name: "LiberationSans-Bold", + factors: _helvetica_factors.HelveticaBoldFactors, + baseWidths: _liberationsans_widths.LiberationSansBoldWidths, + baseMapping: _liberationsans_widths.LiberationSansBoldMapping, + metrics: _helvetica_factors.HelveticaBoldMetrics + }; + t["Helvetica-Italic"] = { + name: "LiberationSans-Italic", + factors: _helvetica_factors.HelveticaItalicFactors, + baseWidths: _liberationsans_widths.LiberationSansItalicWidths, + baseMapping: _liberationsans_widths.LiberationSansItalicMapping, + metrics: _helvetica_factors.HelveticaItalicMetrics + }; + t["Helvetica-BoldItalic"] = { + name: "LiberationSans-BoldItalic", + factors: _helvetica_factors.HelveticaBoldItalicFactors, + baseWidths: _liberationsans_widths.LiberationSansBoldItalicWidths, + baseMapping: _liberationsans_widths.LiberationSansBoldItalicMapping, + metrics: _helvetica_factors.HelveticaBoldItalicMetrics + }; +}); +function getXfaFontName(name) { + const fontName = (0, _fonts_utils.normalizeFontName)(name); + const fontMap = getXFAFontMap(); + return fontMap[fontName]; +} +function getXfaFontWidths(name) { + const info = getXfaFontName(name); + if (!info) { + return null; + } + const { + baseWidths, + baseMapping, + factors + } = info; + const rescaledBaseWidths = !factors ? baseWidths : baseWidths.map((w, i) => w * factors[i]); + let currentCode = -2; + let currentArray; + const newWidths = []; + for (const [unicode, glyphIndex] of baseMapping.map((charUnicode, index) => [charUnicode, index]).sort(([unicode1], [unicode2]) => unicode1 - unicode2)) { + if (unicode === -1) { + continue; + } + if (unicode === currentCode + 1) { + currentArray.push(rescaledBaseWidths[glyphIndex]); + currentCode += 1; + } else { + currentCode = unicode; + currentArray = [rescaledBaseWidths[glyphIndex]]; + newWidths.push(unicode, currentArray); + } + } + return newWidths; +} +function getXfaFontDict(name) { + const widths = getXfaFontWidths(name); + const dict = new _primitives.Dict(null); + dict.set("BaseFont", _primitives.Name.get(name)); + dict.set("Type", _primitives.Name.get("Font")); + dict.set("Subtype", _primitives.Name.get("CIDFontType2")); + dict.set("Encoding", _primitives.Name.get("Identity-H")); + dict.set("CIDToGIDMap", _primitives.Name.get("Identity")); + dict.set("W", widths); + dict.set("FirstChar", widths[0]); + dict.set("LastChar", widths.at(-2) + widths.at(-1).length - 1); + const descriptor = new _primitives.Dict(null); + dict.set("FontDescriptor", descriptor); + const systemInfo = new _primitives.Dict(null); + systemInfo.set("Ordering", "Identity"); + systemInfo.set("Registry", "Adobe"); + systemInfo.set("Supplement", 0); + dict.set("CIDSystemInfo", systemInfo); + return dict; +} + +/***/ }), +/* 52 */ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.CalibriRegularMetrics = exports.CalibriRegularFactors = exports.CalibriItalicMetrics = exports.CalibriItalicFactors = exports.CalibriBoldMetrics = exports.CalibriBoldItalicMetrics = exports.CalibriBoldItalicFactors = exports.CalibriBoldFactors = void 0; +const CalibriBoldFactors = [1.3877, 1, 1, 1, 0.97801, 0.92482, 0.89552, 0.91133, 0.81988, 0.97566, 0.98152, 0.93548, 0.93548, 1.2798, 0.85284, 0.92794, 1, 0.96134, 1.54657, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.82845, 0.82845, 0.85284, 0.85284, 0.85284, 0.75859, 0.92138, 0.83908, 0.7762, 0.73293, 0.87289, 0.73133, 0.7514, 0.81921, 0.87356, 0.95958, 0.59526, 0.75727, 0.69225, 1.04924, 0.9121, 0.86943, 0.79795, 0.88198, 0.77958, 0.70864, 0.81055, 0.90399, 0.88653, 0.96017, 0.82577, 0.77892, 0.78257, 0.97507, 1.54657, 0.97507, 0.85284, 0.89552, 0.90176, 0.88762, 0.8785, 0.75241, 0.8785, 0.90518, 0.95015, 0.77618, 0.8785, 0.88401, 0.91916, 0.86304, 0.88401, 0.91488, 0.8785, 0.8801, 0.8785, 0.8785, 0.91343, 0.7173, 1.04106, 0.8785, 0.85075, 0.95794, 0.82616, 0.85162, 0.79492, 0.88331, 1.69808, 0.88331, 0.85284, 0.97801, 0.89552, 0.91133, 0.89552, 0.91133, 1.7801, 0.89552, 1.24487, 1.13254, 1.12401, 0.96839, 0.85284, 0.68787, 0.70645, 0.85592, 0.90747, 1.01466, 1.0088, 0.90323, 1, 1.07463, 1, 0.91056, 0.75806, 1.19118, 0.96839, 0.78864, 0.82845, 0.84133, 0.75859, 0.83908, 0.83908, 0.83908, 0.83908, 0.83908, 0.83908, 0.77539, 0.73293, 0.73133, 0.73133, 0.73133, 0.73133, 0.95958, 0.95958, 0.95958, 0.95958, 0.88506, 0.9121, 0.86943, 0.86943, 0.86943, 0.86943, 0.86943, 0.85284, 0.87508, 0.90399, 0.90399, 0.90399, 0.90399, 0.77892, 0.79795, 0.90807, 0.88762, 0.88762, 0.88762, 0.88762, 0.88762, 0.88762, 0.8715, 0.75241, 0.90518, 0.90518, 0.90518, 0.90518, 0.88401, 0.88401, 0.88401, 0.88401, 0.8785, 0.8785, 0.8801, 0.8801, 0.8801, 0.8801, 0.8801, 0.90747, 0.89049, 0.8785, 0.8785, 0.8785, 0.8785, 0.85162, 0.8785, 0.85162, 0.83908, 0.88762, 0.83908, 0.88762, 0.83908, 0.88762, 0.73293, 0.75241, 0.73293, 0.75241, 0.73293, 0.75241, 0.73293, 0.75241, 0.87289, 0.83016, 0.88506, 0.93125, 0.73133, 0.90518, 0.73133, 0.90518, 0.73133, 0.90518, 0.73133, 0.90518, 0.73133, 0.90518, 0.81921, 0.77618, 0.81921, 0.77618, 0.81921, 0.77618, 1, 1, 0.87356, 0.8785, 0.91075, 0.89608, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.76229, 0.90167, 0.59526, 0.91916, 1, 1, 0.86304, 0.69225, 0.88401, 1, 1, 0.70424, 0.79468, 0.91926, 0.88175, 0.70823, 0.94903, 0.9121, 0.8785, 1, 1, 0.9121, 0.8785, 0.87802, 0.88656, 0.8785, 0.86943, 0.8801, 0.86943, 0.8801, 0.86943, 0.8801, 0.87402, 0.89291, 0.77958, 0.91343, 1, 1, 0.77958, 0.91343, 0.70864, 0.7173, 0.70864, 0.7173, 0.70864, 0.7173, 0.70864, 0.7173, 1, 1, 0.81055, 0.75841, 0.81055, 1.06452, 0.90399, 0.8785, 0.90399, 0.8785, 0.90399, 0.8785, 0.90399, 0.8785, 0.90399, 0.8785, 0.90399, 0.8785, 0.96017, 0.95794, 0.77892, 0.85162, 0.77892, 0.78257, 0.79492, 0.78257, 0.79492, 0.78257, 0.79492, 0.9297, 0.56892, 0.83908, 0.88762, 0.77539, 0.8715, 0.87508, 0.89049, 1, 1, 0.81055, 1.04106, 1.20528, 1.20528, 1, 1.15543, 0.70674, 0.98387, 0.94721, 1.33431, 1.45894, 0.95161, 1.06303, 0.83908, 0.80352, 0.57184, 0.6965, 0.56289, 0.82001, 0.56029, 0.81235, 1.02988, 0.83908, 0.7762, 0.68156, 0.80367, 0.73133, 0.78257, 0.87356, 0.86943, 0.95958, 0.75727, 0.89019, 1.04924, 0.9121, 0.7648, 0.86943, 0.87356, 0.79795, 0.78275, 0.81055, 0.77892, 0.9762, 0.82577, 0.99819, 0.84896, 0.95958, 0.77892, 0.96108, 1.01407, 0.89049, 1.02988, 0.94211, 0.96108, 0.8936, 0.84021, 0.87842, 0.96399, 0.79109, 0.89049, 1.00813, 1.02988, 0.86077, 0.87445, 0.92099, 0.84723, 0.86513, 0.8801, 0.75638, 0.85714, 0.78216, 0.79586, 0.87965, 0.94211, 0.97747, 0.78287, 0.97926, 0.84971, 1.02988, 0.94211, 0.8801, 0.94211, 0.84971, 0.73133, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90264, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90518, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90548, 1, 1, 1, 1, 1, 1, 0.96017, 0.95794, 0.96017, 0.95794, 0.96017, 0.95794, 0.77892, 0.85162, 1, 1, 0.89552, 0.90527, 1, 0.90363, 0.92794, 0.92794, 0.92794, 0.92794, 0.87012, 0.87012, 0.87012, 0.89552, 0.89552, 1.42259, 0.71143, 1.06152, 1, 1, 1.03372, 1.03372, 0.97171, 1.4956, 2.2807, 0.93835, 0.83406, 0.91133, 0.84107, 0.91133, 1, 1, 1, 0.72021, 1, 1.23108, 0.83489, 0.88525, 0.88525, 0.81499, 0.90527, 1.81055, 0.90527, 1.81055, 1.31006, 1.53711, 0.94434, 1.08696, 1, 0.95018, 0.77192, 0.85284, 0.90747, 1.17534, 0.69825, 0.9716, 1.37077, 0.90747, 0.90747, 0.85356, 0.90747, 0.90747, 1.44947, 0.85284, 0.8941, 0.8941, 0.70572, 0.8, 0.70572, 0.70572, 0.70572, 0.70572, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.99862, 0.99862, 1, 1, 1, 1, 1, 1.08004, 0.91027, 1, 1, 1, 0.99862, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90727, 0.90727, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.CalibriBoldFactors = CalibriBoldFactors; +const CalibriBoldMetrics = { + lineHeight: 1.2207, + lineGap: 0.2207 +}; +exports.CalibriBoldMetrics = CalibriBoldMetrics; +const CalibriBoldItalicFactors = [1.3877, 1, 1, 1, 0.97801, 0.92482, 0.89552, 0.91133, 0.81988, 0.97566, 0.98152, 0.93548, 0.93548, 1.2798, 0.85284, 0.92794, 1, 0.96134, 1.56239, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.82845, 0.82845, 0.85284, 0.85284, 0.85284, 0.75859, 0.92138, 0.83908, 0.7762, 0.71805, 0.87289, 0.73133, 0.7514, 0.81921, 0.87356, 0.95958, 0.59526, 0.75727, 0.69225, 1.04924, 0.90872, 0.85938, 0.79795, 0.87068, 0.77958, 0.69766, 0.81055, 0.90399, 0.88653, 0.96068, 0.82577, 0.77892, 0.78257, 0.97507, 1.529, 0.97507, 0.85284, 0.89552, 0.90176, 0.94908, 0.86411, 0.74012, 0.86411, 0.88323, 0.95015, 0.86411, 0.86331, 0.88401, 0.91916, 0.86304, 0.88401, 0.9039, 0.86331, 0.86331, 0.86411, 0.86411, 0.90464, 0.70852, 1.04106, 0.86331, 0.84372, 0.95794, 0.82616, 0.84548, 0.79492, 0.88331, 1.69808, 0.88331, 0.85284, 0.97801, 0.89552, 0.91133, 0.89552, 0.91133, 1.7801, 0.89552, 1.24487, 1.13254, 1.19129, 0.96839, 0.85284, 0.68787, 0.70645, 0.85592, 0.90747, 1.01466, 1.0088, 0.90323, 1, 1.07463, 1, 0.91056, 0.75806, 1.19118, 0.96839, 0.78864, 0.82845, 0.84133, 0.75859, 0.83908, 0.83908, 0.83908, 0.83908, 0.83908, 0.83908, 0.77539, 0.71805, 0.73133, 0.73133, 0.73133, 0.73133, 0.95958, 0.95958, 0.95958, 0.95958, 0.88506, 0.90872, 0.85938, 0.85938, 0.85938, 0.85938, 0.85938, 0.85284, 0.87068, 0.90399, 0.90399, 0.90399, 0.90399, 0.77892, 0.79795, 0.90807, 0.94908, 0.94908, 0.94908, 0.94908, 0.94908, 0.94908, 0.85887, 0.74012, 0.88323, 0.88323, 0.88323, 0.88323, 0.88401, 0.88401, 0.88401, 0.88401, 0.8785, 0.86331, 0.86331, 0.86331, 0.86331, 0.86331, 0.86331, 0.90747, 0.89049, 0.86331, 0.86331, 0.86331, 0.86331, 0.84548, 0.86411, 0.84548, 0.83908, 0.94908, 0.83908, 0.94908, 0.83908, 0.94908, 0.71805, 0.74012, 0.71805, 0.74012, 0.71805, 0.74012, 0.71805, 0.74012, 0.87289, 0.79538, 0.88506, 0.92726, 0.73133, 0.88323, 0.73133, 0.88323, 0.73133, 0.88323, 0.73133, 0.88323, 0.73133, 0.88323, 0.81921, 0.86411, 0.81921, 0.86411, 0.81921, 0.86411, 1, 1, 0.87356, 0.86331, 0.91075, 0.8777, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.95958, 0.88401, 0.76467, 0.90167, 0.59526, 0.91916, 1, 1, 0.86304, 0.69225, 0.88401, 1, 1, 0.70424, 0.77312, 0.91926, 0.88175, 0.70823, 0.94903, 0.90872, 0.86331, 1, 1, 0.90872, 0.86331, 0.86906, 0.88116, 0.86331, 0.85938, 0.86331, 0.85938, 0.86331, 0.85938, 0.86331, 0.87402, 0.86549, 0.77958, 0.90464, 1, 1, 0.77958, 0.90464, 0.69766, 0.70852, 0.69766, 0.70852, 0.69766, 0.70852, 0.69766, 0.70852, 1, 1, 0.81055, 0.75841, 0.81055, 1.06452, 0.90399, 0.86331, 0.90399, 0.86331, 0.90399, 0.86331, 0.90399, 0.86331, 0.90399, 0.86331, 0.90399, 0.86331, 0.96068, 0.95794, 0.77892, 0.84548, 0.77892, 0.78257, 0.79492, 0.78257, 0.79492, 0.78257, 0.79492, 0.9297, 0.56892, 0.83908, 0.94908, 0.77539, 0.85887, 0.87068, 0.89049, 1, 1, 0.81055, 1.04106, 1.20528, 1.20528, 1, 1.15543, 0.70088, 0.98387, 0.94721, 1.33431, 1.45894, 0.95161, 1.48387, 0.83908, 0.80352, 0.57118, 0.6965, 0.56347, 0.79179, 0.55853, 0.80346, 1.02988, 0.83908, 0.7762, 0.67174, 0.86036, 0.73133, 0.78257, 0.87356, 0.86441, 0.95958, 0.75727, 0.89019, 1.04924, 0.90872, 0.74889, 0.85938, 0.87891, 0.79795, 0.7957, 0.81055, 0.77892, 0.97447, 0.82577, 0.97466, 0.87179, 0.95958, 0.77892, 0.94252, 0.95612, 0.8753, 1.02988, 0.92733, 0.94252, 0.87411, 0.84021, 0.8728, 0.95612, 0.74081, 0.8753, 1.02189, 1.02988, 0.84814, 0.87445, 0.91822, 0.84723, 0.85668, 0.86331, 0.81344, 0.87581, 0.76422, 0.82046, 0.96057, 0.92733, 0.99375, 0.78022, 0.95452, 0.86015, 1.02988, 0.92733, 0.86331, 0.92733, 0.86015, 0.73133, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90631, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.88323, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.85174, 1, 1, 1, 1, 1, 1, 0.96068, 0.95794, 0.96068, 0.95794, 0.96068, 0.95794, 0.77892, 0.84548, 1, 1, 0.89552, 0.90527, 1, 0.90363, 0.92794, 0.92794, 0.92794, 0.89807, 0.87012, 0.87012, 0.87012, 0.89552, 0.89552, 1.42259, 0.71094, 1.06152, 1, 1, 1.03372, 1.03372, 0.97171, 1.4956, 2.2807, 0.92972, 0.83406, 0.91133, 0.83326, 0.91133, 1, 1, 1, 0.72021, 1, 1.23108, 0.83489, 0.88525, 0.88525, 0.81499, 0.90616, 1.81055, 0.90527, 1.81055, 1.3107, 1.53711, 0.94434, 1.08696, 1, 0.95018, 0.77192, 0.85284, 0.90747, 1.17534, 0.69825, 0.9716, 1.37077, 0.90747, 0.90747, 0.85356, 0.90747, 0.90747, 1.44947, 0.85284, 0.8941, 0.8941, 0.70572, 0.8, 0.70572, 0.70572, 0.70572, 0.70572, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.99862, 0.99862, 1, 1, 1, 1, 1, 1.08004, 0.91027, 1, 1, 1, 0.99862, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90727, 0.90727, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.CalibriBoldItalicFactors = CalibriBoldItalicFactors; +const CalibriBoldItalicMetrics = { + lineHeight: 1.2207, + lineGap: 0.2207 +}; +exports.CalibriBoldItalicMetrics = CalibriBoldItalicMetrics; +const CalibriItalicFactors = [1.3877, 1, 1, 1, 1.17223, 1.1293, 0.89552, 0.91133, 0.80395, 1.02269, 1.15601, 0.91056, 0.91056, 1.2798, 0.85284, 0.89807, 1, 0.90861, 1.39543, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.96309, 0.96309, 0.85284, 0.85284, 0.85284, 0.83319, 0.88071, 0.8675, 0.81552, 0.72346, 0.85193, 0.73206, 0.7522, 0.81105, 0.86275, 0.90685, 0.6377, 0.77892, 0.75593, 1.02638, 0.89249, 0.84118, 0.77452, 0.85374, 0.75186, 0.67789, 0.79776, 0.88844, 0.85066, 0.94309, 0.77818, 0.7306, 0.76659, 1.10369, 1.38313, 1.10369, 1.06139, 0.89552, 0.8739, 0.9245, 0.9245, 0.83203, 0.9245, 0.85865, 1.09842, 0.9245, 0.9245, 1.03297, 1.07692, 0.90918, 1.03297, 0.94959, 0.9245, 0.92274, 0.9245, 0.9245, 1.02933, 0.77832, 1.20562, 0.9245, 0.8916, 0.98986, 0.86621, 0.89453, 0.79004, 0.94152, 1.77256, 0.94152, 0.85284, 0.97801, 0.89552, 0.91133, 0.89552, 0.91133, 1.91729, 0.89552, 1.17889, 1.13254, 1.16359, 0.92098, 0.85284, 0.68787, 0.71353, 0.84737, 0.90747, 1.0088, 1.0044, 0.87683, 1, 1.09091, 1, 0.92229, 0.739, 1.15642, 0.92098, 0.76288, 0.80504, 0.80972, 0.75859, 0.8675, 0.8675, 0.8675, 0.8675, 0.8675, 0.8675, 0.76318, 0.72346, 0.73206, 0.73206, 0.73206, 0.73206, 0.90685, 0.90685, 0.90685, 0.90685, 0.86477, 0.89249, 0.84118, 0.84118, 0.84118, 0.84118, 0.84118, 0.85284, 0.84557, 0.88844, 0.88844, 0.88844, 0.88844, 0.7306, 0.77452, 0.86331, 0.9245, 0.9245, 0.9245, 0.9245, 0.9245, 0.9245, 0.84843, 0.83203, 0.85865, 0.85865, 0.85865, 0.85865, 0.82601, 0.82601, 0.82601, 0.82601, 0.94469, 0.9245, 0.92274, 0.92274, 0.92274, 0.92274, 0.92274, 0.90747, 0.86651, 0.9245, 0.9245, 0.9245, 0.9245, 0.89453, 0.9245, 0.89453, 0.8675, 0.9245, 0.8675, 0.9245, 0.8675, 0.9245, 0.72346, 0.83203, 0.72346, 0.83203, 0.72346, 0.83203, 0.72346, 0.83203, 0.85193, 0.8875, 0.86477, 0.99034, 0.73206, 0.85865, 0.73206, 0.85865, 0.73206, 0.85865, 0.73206, 0.85865, 0.73206, 0.85865, 0.81105, 0.9245, 0.81105, 0.9245, 0.81105, 0.9245, 1, 1, 0.86275, 0.9245, 0.90872, 0.93591, 0.90685, 0.82601, 0.90685, 0.82601, 0.90685, 0.82601, 0.90685, 1.03297, 0.90685, 0.82601, 0.77896, 1.05611, 0.6377, 1.07692, 1, 1, 0.90918, 0.75593, 1.03297, 1, 1, 0.76032, 0.9375, 0.98156, 0.93407, 0.77261, 1.11429, 0.89249, 0.9245, 1, 1, 0.89249, 0.9245, 0.92534, 0.86698, 0.9245, 0.84118, 0.92274, 0.84118, 0.92274, 0.84118, 0.92274, 0.8667, 0.86291, 0.75186, 1.02933, 1, 1, 0.75186, 1.02933, 0.67789, 0.77832, 0.67789, 0.77832, 0.67789, 0.77832, 0.67789, 0.77832, 1, 1, 0.79776, 0.97655, 0.79776, 1.23023, 0.88844, 0.9245, 0.88844, 0.9245, 0.88844, 0.9245, 0.88844, 0.9245, 0.88844, 0.9245, 0.88844, 0.9245, 0.94309, 0.98986, 0.7306, 0.89453, 0.7306, 0.76659, 0.79004, 0.76659, 0.79004, 0.76659, 0.79004, 1.09231, 0.54873, 0.8675, 0.9245, 0.76318, 0.84843, 0.84557, 0.86651, 1, 1, 0.79776, 1.20562, 1.18622, 1.18622, 1, 1.1437, 0.67009, 0.96334, 0.93695, 1.35191, 1.40909, 0.95161, 1.48387, 0.8675, 0.90861, 0.6192, 0.7363, 0.64824, 0.82411, 0.56321, 0.85696, 1.23516, 0.8675, 0.81552, 0.7286, 0.84134, 0.73206, 0.76659, 0.86275, 0.84369, 0.90685, 0.77892, 0.85871, 1.02638, 0.89249, 0.75828, 0.84118, 0.85984, 0.77452, 0.76466, 0.79776, 0.7306, 0.90782, 0.77818, 0.903, 0.87291, 0.90685, 0.7306, 0.99058, 1.03667, 0.94635, 1.23516, 0.9849, 0.99058, 0.92393, 0.8916, 0.942, 1.03667, 0.75026, 0.94635, 1.0297, 1.23516, 0.90918, 0.94048, 0.98217, 0.89746, 0.84153, 0.92274, 0.82507, 0.88832, 0.84438, 0.88178, 1.03525, 0.9849, 1.00225, 0.78086, 0.97248, 0.89404, 1.23516, 0.9849, 0.92274, 0.9849, 0.89404, 0.73206, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.89693, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.85865, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.90933, 1, 1, 1, 1, 1, 1, 0.94309, 0.98986, 0.94309, 0.98986, 0.94309, 0.98986, 0.7306, 0.89453, 1, 1, 0.89552, 0.90527, 1, 0.90186, 1.12308, 1.12308, 1.12308, 1.12308, 1.2566, 1.2566, 1.2566, 0.89552, 0.89552, 1.42259, 0.68994, 1.03809, 1, 1, 1.0176, 1.0176, 1.11523, 1.4956, 2.01462, 0.97858, 0.82616, 0.91133, 0.83437, 0.91133, 1, 1, 1, 0.70508, 1, 1.23108, 0.79801, 0.84426, 0.84426, 0.774, 0.90572, 1.81055, 0.90749, 1.81055, 1.28809, 1.55469, 0.94434, 1.07806, 1, 0.97094, 0.7589, 0.85284, 0.90747, 1.19658, 0.69825, 0.97622, 1.33512, 0.90747, 0.90747, 0.85284, 0.90747, 0.90747, 1.44947, 0.85284, 0.8941, 0.8941, 0.70572, 0.8, 0.70572, 0.70572, 0.70572, 0.70572, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.99862, 0.99862, 1, 1, 1, 1, 1, 1.0336, 0.91027, 1, 1, 1, 0.99862, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.05859, 1.05859, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.CalibriItalicFactors = CalibriItalicFactors; +const CalibriItalicMetrics = { + lineHeight: 1.2207, + lineGap: 0.2207 +}; +exports.CalibriItalicMetrics = CalibriItalicMetrics; +const CalibriRegularFactors = [1.3877, 1, 1, 1, 1.17223, 1.1293, 0.89552, 0.91133, 0.80395, 1.02269, 1.15601, 0.91056, 0.91056, 1.2798, 0.85284, 0.89807, 1, 0.90861, 1.39016, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.91133, 0.96309, 0.96309, 0.85284, 0.85284, 0.85284, 0.83319, 0.88071, 0.8675, 0.81552, 0.73834, 0.85193, 0.73206, 0.7522, 0.81105, 0.86275, 0.90685, 0.6377, 0.77892, 0.75593, 1.02638, 0.89385, 0.85122, 0.77452, 0.86503, 0.75186, 0.68887, 0.79776, 0.88844, 0.85066, 0.94258, 0.77818, 0.7306, 0.76659, 1.10369, 1.39016, 1.10369, 1.06139, 0.89552, 0.8739, 0.86128, 0.94469, 0.8457, 0.94469, 0.89464, 1.09842, 0.84636, 0.94469, 1.03297, 1.07692, 0.90918, 1.03297, 0.95897, 0.94469, 0.9482, 0.94469, 0.94469, 1.04692, 0.78223, 1.20562, 0.94469, 0.90332, 0.98986, 0.86621, 0.90527, 0.79004, 0.94152, 1.77256, 0.94152, 0.85284, 0.97801, 0.89552, 0.91133, 0.89552, 0.91133, 1.91729, 0.89552, 1.17889, 1.13254, 1.08707, 0.92098, 0.85284, 0.68787, 0.71353, 0.84737, 0.90747, 1.0088, 1.0044, 0.87683, 1, 1.09091, 1, 0.92229, 0.739, 1.15642, 0.92098, 0.76288, 0.80504, 0.80972, 0.75859, 0.8675, 0.8675, 0.8675, 0.8675, 0.8675, 0.8675, 0.76318, 0.73834, 0.73206, 0.73206, 0.73206, 0.73206, 0.90685, 0.90685, 0.90685, 0.90685, 0.86477, 0.89385, 0.85122, 0.85122, 0.85122, 0.85122, 0.85122, 0.85284, 0.85311, 0.88844, 0.88844, 0.88844, 0.88844, 0.7306, 0.77452, 0.86331, 0.86128, 0.86128, 0.86128, 0.86128, 0.86128, 0.86128, 0.8693, 0.8457, 0.89464, 0.89464, 0.89464, 0.89464, 0.82601, 0.82601, 0.82601, 0.82601, 0.94469, 0.94469, 0.9482, 0.9482, 0.9482, 0.9482, 0.9482, 0.90747, 0.86651, 0.94469, 0.94469, 0.94469, 0.94469, 0.90527, 0.94469, 0.90527, 0.8675, 0.86128, 0.8675, 0.86128, 0.8675, 0.86128, 0.73834, 0.8457, 0.73834, 0.8457, 0.73834, 0.8457, 0.73834, 0.8457, 0.85193, 0.92454, 0.86477, 0.9921, 0.73206, 0.89464, 0.73206, 0.89464, 0.73206, 0.89464, 0.73206, 0.89464, 0.73206, 0.89464, 0.81105, 0.84636, 0.81105, 0.84636, 0.81105, 0.84636, 1, 1, 0.86275, 0.94469, 0.90872, 0.95786, 0.90685, 0.82601, 0.90685, 0.82601, 0.90685, 0.82601, 0.90685, 1.03297, 0.90685, 0.82601, 0.77741, 1.05611, 0.6377, 1.07692, 1, 1, 0.90918, 0.75593, 1.03297, 1, 1, 0.76032, 0.90452, 0.98156, 1.11842, 0.77261, 1.11429, 0.89385, 0.94469, 1, 1, 0.89385, 0.94469, 0.95877, 0.86901, 0.94469, 0.85122, 0.9482, 0.85122, 0.9482, 0.85122, 0.9482, 0.8667, 0.90016, 0.75186, 1.04692, 1, 1, 0.75186, 1.04692, 0.68887, 0.78223, 0.68887, 0.78223, 0.68887, 0.78223, 0.68887, 0.78223, 1, 1, 0.79776, 0.92188, 0.79776, 1.23023, 0.88844, 0.94469, 0.88844, 0.94469, 0.88844, 0.94469, 0.88844, 0.94469, 0.88844, 0.94469, 0.88844, 0.94469, 0.94258, 0.98986, 0.7306, 0.90527, 0.7306, 0.76659, 0.79004, 0.76659, 0.79004, 0.76659, 0.79004, 1.09231, 0.54873, 0.8675, 0.86128, 0.76318, 0.8693, 0.85311, 0.86651, 1, 1, 0.79776, 1.20562, 1.18622, 1.18622, 1, 1.1437, 0.67742, 0.96334, 0.93695, 1.35191, 1.40909, 0.95161, 1.48387, 0.86686, 0.90861, 0.62267, 0.74359, 0.65649, 0.85498, 0.56963, 0.88254, 1.23516, 0.8675, 0.81552, 0.75443, 0.84503, 0.73206, 0.76659, 0.86275, 0.85122, 0.90685, 0.77892, 0.85746, 1.02638, 0.89385, 0.75657, 0.85122, 0.86275, 0.77452, 0.74171, 0.79776, 0.7306, 0.95165, 0.77818, 0.89772, 0.88831, 0.90685, 0.7306, 0.98142, 1.02191, 0.96576, 1.23516, 0.99018, 0.98142, 0.9236, 0.89258, 0.94035, 1.02191, 0.78848, 0.96576, 0.9561, 1.23516, 0.90918, 0.92578, 0.95424, 0.89746, 0.83969, 0.9482, 0.80113, 0.89442, 0.85208, 0.86155, 0.98022, 0.99018, 1.00452, 0.81209, 0.99247, 0.89181, 1.23516, 0.99018, 0.9482, 0.99018, 0.89181, 0.73206, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.88844, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.89464, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.96766, 1, 1, 1, 1, 1, 1, 0.94258, 0.98986, 0.94258, 0.98986, 0.94258, 0.98986, 0.7306, 0.90527, 1, 1, 0.89552, 0.90527, 1, 0.90186, 1.12308, 1.12308, 1.12308, 1.12308, 1.2566, 1.2566, 1.2566, 0.89552, 0.89552, 1.42259, 0.69043, 1.03809, 1, 1, 1.0176, 1.0176, 1.11523, 1.4956, 2.01462, 0.99331, 0.82616, 0.91133, 0.84286, 0.91133, 1, 1, 1, 0.70508, 1, 1.23108, 0.79801, 0.84426, 0.84426, 0.774, 0.90527, 1.81055, 0.90527, 1.81055, 1.28809, 1.55469, 0.94434, 1.07806, 1, 0.97094, 0.7589, 0.85284, 0.90747, 1.19658, 0.69825, 0.97622, 1.33512, 0.90747, 0.90747, 0.85356, 0.90747, 0.90747, 1.44947, 0.85284, 0.8941, 0.8941, 0.70572, 0.8, 0.70572, 0.70572, 0.70572, 0.70572, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.99862, 0.99862, 1, 1, 1, 1, 1, 1.0336, 0.91027, 1, 1, 1, 0.99862, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.05859, 1.05859, 1, 1, 1, 1.07185, 0.99413, 0.96334, 1.08065, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.CalibriRegularFactors = CalibriRegularFactors; +const CalibriRegularMetrics = { + lineHeight: 1.2207, + lineGap: 0.2207 +}; +exports.CalibriRegularMetrics = CalibriRegularMetrics; + +/***/ }), +/* 53 */ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.HelveticaRegularMetrics = exports.HelveticaRegularFactors = exports.HelveticaItalicMetrics = exports.HelveticaItalicFactors = exports.HelveticaBoldMetrics = exports.HelveticaBoldItalicMetrics = exports.HelveticaBoldItalicFactors = exports.HelveticaBoldFactors = void 0; +const HelveticaBoldFactors = [0.76116, 1, 1, 1.0006, 0.99998, 0.99974, 0.99973, 0.99973, 0.99982, 0.99977, 1.00087, 0.99998, 0.99998, 0.99959, 1.00003, 1.0006, 0.99998, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99998, 1, 1.00003, 1.00003, 1.00003, 1.00026, 0.9999, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00026, 1.00022, 0.99977, 1.0006, 0.99973, 0.99977, 1.00026, 0.99999, 0.99977, 1.00022, 1.00001, 1.00022, 0.99977, 1.00001, 1.00026, 0.99977, 1.00001, 1.00016, 1.00001, 1.00001, 1.00026, 0.99998, 1.0006, 0.99998, 1.00003, 0.99973, 0.99998, 0.99973, 1.00026, 0.99973, 1.00026, 0.99973, 0.99998, 1.00026, 1.00026, 1.0006, 1.0006, 0.99973, 1.0006, 0.99982, 1.00026, 1.00026, 1.00026, 1.00026, 0.99959, 0.99973, 0.99998, 1.00026, 0.99973, 1.00022, 0.99973, 0.99973, 1, 0.99959, 1.00077, 0.99959, 1.00003, 0.99998, 0.99973, 0.99973, 0.99973, 0.99973, 1.00077, 0.99973, 0.99998, 1.00025, 0.99968, 0.99973, 1.00003, 1.00025, 0.60299, 1.00024, 1.06409, 1, 1, 0.99998, 1, 0.99973, 1.0006, 0.99998, 1, 0.99936, 0.99973, 1.00002, 1.00002, 1.00002, 1.00026, 0.99977, 0.99977, 0.99977, 0.99977, 0.99977, 0.99977, 1, 0.99977, 1.00001, 1.00001, 1.00001, 1.00001, 1.0006, 1.0006, 1.0006, 1.0006, 0.99977, 0.99977, 1.00022, 1.00022, 1.00022, 1.00022, 1.00022, 1.00003, 1.00022, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00001, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99982, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.06409, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 0.99973, 1.00026, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 1.03374, 0.99977, 1.00026, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.00042, 0.99973, 0.99973, 1.0006, 0.99977, 0.99973, 0.99973, 1.00026, 1.0006, 1.00026, 1.0006, 1.00026, 1.03828, 1.00026, 0.99999, 1.00026, 1.0006, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.9993, 0.9998, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1, 1.00016, 0.99977, 0.99959, 0.99977, 0.99959, 0.99977, 0.99959, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00026, 0.99998, 1.00026, 0.8121, 1.00026, 0.99998, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 1.00016, 1.00022, 1.00001, 0.99973, 1.00001, 1.00026, 1, 1.00026, 1, 1.00026, 1, 1.0006, 0.99973, 0.99977, 0.99973, 1, 0.99982, 1.00022, 1.00026, 1.00001, 0.99973, 1.00026, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 1.00034, 0.99977, 1, 0.99997, 1.00026, 1.00078, 1.00036, 0.99973, 1.00013, 1.0006, 0.99977, 0.99977, 0.99988, 0.85148, 1.00001, 1.00026, 0.99977, 1.00022, 1.0006, 0.99977, 1.00001, 0.99999, 0.99977, 1.00069, 1.00022, 0.99977, 1.00001, 0.99984, 1.00026, 1.00001, 1.00024, 1.00001, 0.9999, 1, 1.0006, 1.00001, 1.00041, 0.99962, 1.00026, 1.0006, 0.99995, 1.00041, 0.99942, 0.99973, 0.99927, 1.00082, 0.99902, 1.00026, 1.00087, 1.0006, 1.00069, 0.99973, 0.99867, 0.99973, 0.9993, 1.00026, 1.00049, 1.00056, 1, 0.99988, 0.99935, 0.99995, 0.99954, 1.00055, 0.99945, 1.00032, 1.0006, 0.99995, 1.00026, 0.99995, 1.00032, 1.00001, 1.00008, 0.99971, 1.00019, 0.9994, 1.00001, 1.0006, 1.00044, 0.99973, 1.00023, 1.00047, 1, 0.99942, 0.99561, 0.99989, 1.00035, 0.99977, 1.00035, 0.99977, 1.00019, 0.99944, 1.00001, 1.00021, 0.99926, 1.00035, 1.00035, 0.99942, 1.00048, 0.99999, 0.99977, 1.00022, 1.00035, 1.00001, 0.99977, 1.00026, 0.99989, 1.00057, 1.00001, 0.99936, 1.00052, 1.00012, 0.99996, 1.00043, 1, 1.00035, 0.9994, 0.99976, 1.00035, 0.99973, 1.00052, 1.00041, 1.00119, 1.00037, 0.99973, 1.00002, 0.99986, 1.00041, 1.00041, 0.99902, 0.9996, 1.00034, 0.99999, 1.00026, 0.99999, 1.00026, 0.99973, 1.00052, 0.99973, 1, 0.99973, 1.00041, 1.00075, 0.9994, 1.0003, 0.99999, 1, 1.00041, 0.99955, 1, 0.99915, 0.99973, 0.99973, 1.00026, 1.00119, 0.99955, 0.99973, 1.0006, 0.99911, 1.0006, 1.00026, 0.99972, 1.00026, 0.99902, 1.00041, 0.99973, 0.99999, 1, 1, 1.00038, 1.0005, 1.00016, 1.00022, 1.00016, 1.00022, 1.00016, 1.00022, 1.00001, 0.99973, 1, 1, 0.99973, 1, 1, 0.99955, 1.0006, 1.0006, 1.0006, 1.0006, 1, 1, 1, 0.99973, 0.99973, 0.99972, 1, 1, 1.00106, 0.99999, 0.99998, 0.99998, 0.99999, 0.99998, 1.66475, 1, 0.99973, 0.99973, 1.00023, 0.99973, 0.99971, 1.00047, 1.00023, 1, 0.99991, 0.99984, 1.00002, 1.00002, 1.00002, 1.00002, 1, 1, 1, 1, 1, 1, 1, 0.99972, 1, 1.20985, 1.39713, 1.00003, 1.00031, 1.00015, 1, 0.99561, 1.00027, 1.00031, 1.00031, 0.99915, 1.00031, 1.00031, 0.99999, 1.00003, 0.99999, 0.99999, 1.41144, 1.6, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.40579, 1.40579, 1.36625, 0.99999, 1, 0.99861, 0.99861, 1, 1.00026, 1.00026, 1.00026, 1.00026, 0.99972, 0.99999, 0.99999, 0.99999, 0.99999, 1.40483, 1, 0.99977, 1.00054, 1, 1, 0.99953, 0.99962, 1.00042, 0.9995, 1, 1, 1, 1, 1, 1, 1, 1, 0.99998, 0.99998, 0.99998, 0.99998, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.HelveticaBoldFactors = HelveticaBoldFactors; +const HelveticaBoldMetrics = { + lineHeight: 1.2, + lineGap: 0.2 +}; +exports.HelveticaBoldMetrics = HelveticaBoldMetrics; +const HelveticaBoldItalicFactors = [0.76116, 1, 1, 1.0006, 0.99998, 0.99974, 0.99973, 0.99973, 0.99982, 0.99977, 1.00087, 0.99998, 0.99998, 0.99959, 1.00003, 1.0006, 0.99998, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99998, 1, 1.00003, 1.00003, 1.00003, 1.00026, 0.9999, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00026, 1.00022, 0.99977, 1.0006, 0.99973, 0.99977, 1.00026, 0.99999, 0.99977, 1.00022, 1.00001, 1.00022, 0.99977, 1.00001, 1.00026, 0.99977, 1.00001, 1.00016, 1.00001, 1.00001, 1.00026, 0.99998, 1.0006, 0.99998, 1.00003, 0.99973, 0.99998, 0.99973, 1.00026, 0.99973, 1.00026, 0.99973, 0.99998, 1.00026, 1.00026, 1.0006, 1.0006, 0.99973, 1.0006, 0.99982, 1.00026, 1.00026, 1.00026, 1.00026, 0.99959, 0.99973, 0.99998, 1.00026, 0.99973, 1.00022, 0.99973, 0.99973, 1, 0.99959, 1.00077, 0.99959, 1.00003, 0.99998, 0.99973, 0.99973, 0.99973, 0.99973, 1.00077, 0.99973, 0.99998, 1.00025, 0.99968, 0.99973, 1.00003, 1.00025, 0.60299, 1.00024, 1.06409, 1, 1, 0.99998, 1, 0.99973, 1.0006, 0.99998, 1, 0.99936, 0.99973, 1.00002, 1.00002, 1.00002, 1.00026, 0.99977, 0.99977, 0.99977, 0.99977, 0.99977, 0.99977, 1, 0.99977, 1.00001, 1.00001, 1.00001, 1.00001, 1.0006, 1.0006, 1.0006, 1.0006, 0.99977, 0.99977, 1.00022, 1.00022, 1.00022, 1.00022, 1.00022, 1.00003, 1.00022, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00001, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99982, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 1.06409, 1.00026, 1.00026, 1.00026, 1.00026, 1.00026, 0.99973, 1.00026, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 1.0044, 0.99977, 1.00026, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 0.99971, 0.99973, 0.99973, 1.0006, 0.99977, 0.99973, 0.99973, 1.00026, 1.0006, 1.00026, 1.0006, 1.00026, 1.01011, 1.00026, 0.99999, 1.00026, 1.0006, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.9993, 0.9998, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1.00022, 1.00026, 1, 1.00016, 0.99977, 0.99959, 0.99977, 0.99959, 0.99977, 0.99959, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00026, 0.99998, 1.00026, 0.8121, 1.00026, 0.99998, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 0.99977, 1.00026, 1.00016, 1.00022, 1.00001, 0.99973, 1.00001, 1.00026, 1, 1.00026, 1, 1.00026, 1, 1.0006, 0.99973, 0.99977, 0.99973, 1, 0.99982, 1.00022, 1.00026, 1.00001, 0.99973, 1.00026, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99977, 1, 1, 1.00026, 0.99969, 0.99972, 0.99981, 0.9998, 1.0006, 0.99977, 0.99977, 1.00022, 0.91155, 1.00001, 1.00026, 0.99977, 1.00022, 1.0006, 0.99977, 1.00001, 0.99999, 0.99977, 0.99966, 1.00022, 1.00032, 1.00001, 0.99944, 1.00026, 1.00001, 0.99968, 1.00001, 1.00047, 1, 1.0006, 1.00001, 0.99981, 1.00101, 1.00026, 1.0006, 0.99948, 0.99981, 1.00064, 0.99973, 0.99942, 1.00101, 1.00061, 1.00026, 1.00069, 1.0006, 1.00014, 0.99973, 1.01322, 0.99973, 1.00065, 1.00026, 1.00012, 0.99923, 1, 1.00064, 1.00076, 0.99948, 1.00055, 1.00063, 1.00007, 0.99943, 1.0006, 0.99948, 1.00026, 0.99948, 0.99943, 1.00001, 1.00001, 1.00029, 1.00038, 1.00035, 1.00001, 1.0006, 1.0006, 0.99973, 0.99978, 1.00001, 1.00057, 0.99989, 0.99967, 0.99964, 0.99967, 0.99977, 0.99999, 0.99977, 1.00038, 0.99977, 1.00001, 0.99973, 1.00066, 0.99967, 0.99967, 1.00041, 0.99998, 0.99999, 0.99977, 1.00022, 0.99967, 1.00001, 0.99977, 1.00026, 0.99964, 1.00031, 1.00001, 0.99999, 0.99999, 1, 1.00023, 1, 1, 0.99999, 1.00035, 1.00001, 0.99999, 0.99973, 0.99977, 0.99999, 1.00058, 0.99973, 0.99973, 0.99955, 0.9995, 1.00026, 1.00026, 1.00032, 0.99989, 1.00034, 0.99999, 1.00026, 1.00026, 1.00026, 0.99973, 0.45998, 0.99973, 1.00026, 0.99973, 1.00001, 0.99999, 0.99982, 0.99994, 0.99996, 1, 1.00042, 1.00044, 1.00029, 1.00023, 0.99973, 0.99973, 1.00026, 0.99949, 1.00002, 0.99973, 1.0006, 1.0006, 1.0006, 0.99975, 1.00026, 1.00026, 1.00032, 0.98685, 0.99973, 1.00026, 1, 1, 0.99966, 1.00044, 1.00016, 1.00022, 1.00016, 1.00022, 1.00016, 1.00022, 1.00001, 0.99973, 1, 1, 0.99973, 1, 1, 0.99955, 1.0006, 1.0006, 1.0006, 1.0006, 1, 1, 1, 0.99973, 0.99973, 0.99972, 1, 1, 1.00106, 0.99999, 0.99998, 0.99998, 0.99999, 0.99998, 1.66475, 1, 0.99973, 0.99973, 1, 0.99973, 0.99971, 0.99978, 1, 1, 0.99991, 0.99984, 1.00002, 1.00002, 1.00002, 1.00002, 1.00098, 1, 1, 1, 1.00049, 1, 1, 0.99972, 1, 1.20985, 1.39713, 1.00003, 1.00031, 1.00015, 1, 0.99561, 1.00027, 1.00031, 1.00031, 0.99915, 1.00031, 1.00031, 0.99999, 1.00003, 0.99999, 0.99999, 1.41144, 1.6, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.40579, 1.40579, 1.36625, 0.99999, 1, 0.99861, 0.99861, 1, 1.00026, 1.00026, 1.00026, 1.00026, 0.99972, 0.99999, 0.99999, 0.99999, 0.99999, 1.40483, 1, 0.99977, 1.00054, 1, 1, 0.99953, 0.99962, 1.00042, 0.9995, 1, 1, 1, 1, 1, 1, 1, 1, 0.99998, 0.99998, 0.99998, 0.99998, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.HelveticaBoldItalicFactors = HelveticaBoldItalicFactors; +const HelveticaBoldItalicMetrics = { + lineHeight: 1.35, + lineGap: 0.2 +}; +exports.HelveticaBoldItalicMetrics = HelveticaBoldItalicMetrics; +const HelveticaItalicFactors = [0.76116, 1, 1, 1.0006, 1.0006, 1.00006, 0.99973, 0.99973, 0.99982, 1.00001, 1.00043, 0.99998, 0.99998, 0.99959, 1.00003, 1.0006, 0.99998, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1, 1.00003, 1.00003, 1.00003, 0.99973, 0.99987, 1.00001, 1.00001, 0.99977, 0.99977, 1.00001, 1.00026, 1.00022, 0.99977, 1.0006, 1, 1.00001, 0.99973, 0.99999, 0.99977, 1.00022, 1.00001, 1.00022, 0.99977, 1.00001, 1.00026, 0.99977, 1.00001, 1.00016, 1.00001, 1.00001, 1.00026, 1.0006, 1.0006, 1.0006, 0.99949, 0.99973, 0.99998, 0.99973, 0.99973, 1, 0.99973, 0.99973, 1.0006, 0.99973, 0.99973, 0.99924, 0.99924, 1, 0.99924, 0.99999, 0.99973, 0.99973, 0.99973, 0.99973, 0.99998, 1, 1.0006, 0.99973, 1, 0.99977, 1, 1, 1, 1.00005, 1.0009, 1.00005, 1.00003, 0.99998, 0.99973, 0.99973, 0.99973, 0.99973, 1.0009, 0.99973, 0.99998, 1.00025, 0.99968, 0.99973, 1.00003, 1.00025, 0.60299, 1.00024, 1.06409, 1, 1, 0.99998, 1, 0.9998, 1.0006, 0.99998, 1, 0.99936, 0.99973, 1.00002, 1.00002, 1.00002, 1.00026, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1, 0.99977, 1.00001, 1.00001, 1.00001, 1.00001, 1.0006, 1.0006, 1.0006, 1.0006, 0.99977, 0.99977, 1.00022, 1.00022, 1.00022, 1.00022, 1.00022, 1.00003, 1.00022, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00001, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99982, 1, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.06409, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 1, 0.99973, 1, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 0.99977, 1, 0.99977, 1, 0.99977, 1, 0.99977, 1, 0.99977, 1.0288, 0.99977, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 0.99924, 1.0006, 1.0006, 0.99946, 1.00034, 1, 0.99924, 1.00001, 1, 1, 0.99973, 0.99924, 0.99973, 0.99924, 0.99973, 1.06311, 0.99973, 1.00024, 0.99973, 0.99924, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.00041, 0.9998, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1, 1.00016, 0.99977, 0.99998, 0.99977, 0.99998, 0.99977, 0.99998, 1.00001, 1, 1.00001, 1, 1.00001, 1, 1.00001, 1, 1.00026, 1.0006, 1.00026, 0.89547, 1.00026, 1.0006, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.00016, 0.99977, 1.00001, 1, 1.00001, 1.00026, 1, 1.00026, 1, 1.00026, 1, 0.99924, 0.99973, 1.00001, 0.99973, 1, 0.99982, 1.00022, 1.00026, 1.00001, 1, 1.00026, 1.0006, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 1.00001, 1, 1.00054, 0.99977, 1.00084, 1.00007, 0.99973, 1.00013, 0.99924, 1.00001, 1.00001, 0.99945, 0.91221, 1.00001, 1.00026, 0.99977, 1.00022, 1.0006, 1.00001, 1.00001, 0.99999, 0.99977, 0.99933, 1.00022, 1.00054, 1.00001, 1.00065, 1.00026, 1.00001, 1.0001, 1.00001, 1.00052, 1, 1.0006, 1.00001, 0.99945, 0.99897, 0.99968, 0.99924, 1.00036, 0.99945, 0.99949, 1, 1.0006, 0.99897, 0.99918, 0.99968, 0.99911, 0.99924, 1, 0.99962, 1.01487, 1, 1.0005, 0.99973, 1.00012, 1.00043, 1, 0.99995, 0.99994, 1.00036, 0.99947, 1.00019, 1.00063, 1.00025, 0.99924, 1.00036, 0.99973, 1.00036, 1.00025, 1.00001, 1.00001, 1.00027, 1.0001, 1.00068, 1.00001, 1.0006, 1.0006, 1, 1.00008, 0.99957, 0.99972, 0.9994, 0.99954, 0.99975, 1.00051, 1.00001, 1.00019, 1.00001, 1.0001, 0.99986, 1.00001, 1.00001, 1.00038, 0.99954, 0.99954, 0.9994, 1.00066, 0.99999, 0.99977, 1.00022, 1.00054, 1.00001, 0.99977, 1.00026, 0.99975, 1.0001, 1.00001, 0.99993, 0.9995, 0.99955, 1.00016, 0.99978, 0.99974, 1.00019, 1.00022, 0.99955, 1.00053, 0.99973, 1.00089, 1.00005, 0.99967, 1.00048, 0.99973, 1.00002, 1.00034, 0.99973, 0.99973, 0.99964, 1.00006, 1.00066, 0.99947, 0.99973, 0.98894, 0.99973, 1, 0.44898, 1, 0.99946, 1, 1.00039, 1.00082, 0.99991, 0.99991, 0.99985, 1.00022, 1.00023, 1.00061, 1.00006, 0.99966, 0.99973, 0.99973, 0.99973, 1.00019, 1.0008, 1, 0.99924, 0.99924, 0.99924, 0.99983, 1.00044, 0.99973, 0.99964, 0.98332, 1, 0.99973, 1, 1, 0.99962, 0.99895, 1.00016, 0.99977, 1.00016, 0.99977, 1.00016, 0.99977, 1.00001, 1, 1, 1, 0.99973, 1, 1, 0.99955, 0.99924, 0.99924, 0.99924, 0.99924, 0.99998, 0.99998, 0.99998, 0.99973, 0.99973, 0.99972, 1, 1, 1.00267, 0.99999, 0.99998, 0.99998, 1, 0.99998, 1.66475, 1, 0.99973, 0.99973, 1.00023, 0.99973, 1.00423, 0.99925, 0.99999, 1, 0.99991, 0.99984, 1.00002, 1.00002, 1.00002, 1.00002, 1.00049, 1, 1.00245, 1, 1, 1, 1, 0.96329, 1, 1.20985, 1.39713, 1.00003, 0.8254, 1.00015, 1, 1.00035, 1.00027, 1.00031, 1.00031, 1.00003, 1.00031, 1.00031, 0.99999, 1.00003, 0.99999, 0.99999, 1.41144, 1.6, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.40579, 1.40579, 1.36625, 0.99999, 1, 0.99861, 0.99861, 1, 1.00026, 1.00026, 1.00026, 1.00026, 0.95317, 0.99999, 0.99999, 0.99999, 0.99999, 1.40483, 1, 0.99977, 1.00054, 1, 1, 0.99953, 0.99962, 1.00042, 0.9995, 1, 1, 1, 1, 1, 1, 1, 1, 0.99998, 0.99998, 0.99998, 0.99998, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.HelveticaItalicFactors = HelveticaItalicFactors; +const HelveticaItalicMetrics = { + lineHeight: 1.35, + lineGap: 0.2 +}; +exports.HelveticaItalicMetrics = HelveticaItalicMetrics; +const HelveticaRegularFactors = [0.76116, 1, 1, 1.0006, 1.0006, 1.00006, 0.99973, 0.99973, 0.99982, 1.00001, 1.00043, 0.99998, 0.99998, 0.99959, 1.00003, 1.0006, 0.99998, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1, 1.00003, 1.00003, 1.00003, 0.99973, 0.99987, 1.00001, 1.00001, 0.99977, 0.99977, 1.00001, 1.00026, 1.00022, 0.99977, 1.0006, 1, 1.00001, 0.99973, 0.99999, 0.99977, 1.00022, 1.00001, 1.00022, 0.99977, 1.00001, 1.00026, 0.99977, 1.00001, 1.00016, 1.00001, 1.00001, 1.00026, 1.0006, 1.0006, 1.0006, 0.99949, 0.99973, 0.99998, 0.99973, 0.99973, 1, 0.99973, 0.99973, 1.0006, 0.99973, 0.99973, 0.99924, 0.99924, 1, 0.99924, 0.99999, 0.99973, 0.99973, 0.99973, 0.99973, 0.99998, 1, 1.0006, 0.99973, 1, 0.99977, 1, 1, 1, 1.00005, 1.0009, 1.00005, 1.00003, 0.99998, 0.99973, 0.99973, 0.99973, 0.99973, 1.0009, 0.99973, 0.99998, 1.00025, 0.99968, 0.99973, 1.00003, 1.00025, 0.60299, 1.00024, 1.06409, 1, 1, 0.99998, 1, 0.9998, 1.0006, 0.99998, 1, 0.99936, 0.99973, 1.00002, 1.00002, 1.00002, 1.00026, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1, 0.99977, 1.00001, 1.00001, 1.00001, 1.00001, 1.0006, 1.0006, 1.0006, 1.0006, 0.99977, 0.99977, 1.00022, 1.00022, 1.00022, 1.00022, 1.00022, 1.00003, 1.00022, 0.99977, 0.99977, 0.99977, 0.99977, 1.00001, 1.00001, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99982, 1, 0.99973, 0.99973, 0.99973, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1.06409, 1.00026, 0.99973, 0.99973, 0.99973, 0.99973, 1, 0.99973, 1, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 0.99977, 1, 0.99977, 1, 0.99977, 1, 0.99977, 1, 0.99977, 1.04596, 0.99977, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00001, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 1.0006, 0.99924, 1.0006, 1.0006, 1.00019, 1.00034, 1, 0.99924, 1.00001, 1, 1, 0.99973, 0.99924, 0.99973, 0.99924, 0.99973, 1.02572, 0.99973, 1.00005, 0.99973, 0.99924, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99999, 0.9998, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1.00022, 0.99973, 1, 1.00016, 0.99977, 0.99998, 0.99977, 0.99998, 0.99977, 0.99998, 1.00001, 1, 1.00001, 1, 1.00001, 1, 1.00001, 1, 1.00026, 1.0006, 1.00026, 0.84533, 1.00026, 1.0006, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 0.99977, 0.99973, 1.00016, 0.99977, 1.00001, 1, 1.00001, 1.00026, 1, 1.00026, 1, 1.00026, 1, 0.99924, 0.99973, 1.00001, 0.99973, 1, 0.99982, 1.00022, 1.00026, 1.00001, 1, 1.00026, 1.0006, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99998, 0.99928, 1, 0.99977, 1.00013, 1.00055, 0.99947, 0.99945, 0.99941, 0.99924, 1.00001, 1.00001, 1.0004, 0.91621, 1.00001, 1.00026, 0.99977, 1.00022, 1.0006, 1.00001, 1.00005, 0.99999, 0.99977, 1.00015, 1.00022, 0.99977, 1.00001, 0.99973, 1.00026, 1.00001, 1.00019, 1.00001, 0.99946, 1, 1.0006, 1.00001, 0.99978, 1.00045, 0.99973, 0.99924, 1.00023, 0.99978, 0.99966, 1, 1.00065, 1.00045, 1.00019, 0.99973, 0.99973, 0.99924, 1, 1, 0.96499, 1, 1.00055, 0.99973, 1.00008, 1.00027, 1, 0.9997, 0.99995, 1.00023, 0.99933, 1.00019, 1.00015, 1.00031, 0.99924, 1.00023, 0.99973, 1.00023, 1.00031, 1.00001, 0.99928, 1.00029, 1.00092, 1.00035, 1.00001, 1.0006, 1.0006, 1, 0.99988, 0.99975, 1, 1.00082, 0.99561, 0.9996, 1.00035, 1.00001, 0.99962, 1.00001, 1.00092, 0.99964, 1.00001, 0.99963, 0.99999, 1.00035, 1.00035, 1.00082, 0.99962, 0.99999, 0.99977, 1.00022, 1.00035, 1.00001, 0.99977, 1.00026, 0.9996, 0.99967, 1.00001, 1.00034, 1.00074, 1.00054, 1.00053, 1.00063, 0.99971, 0.99962, 1.00035, 0.99975, 0.99977, 0.99973, 1.00043, 0.99953, 1.0007, 0.99915, 0.99973, 1.00008, 0.99892, 1.00073, 1.00073, 1.00114, 0.99915, 1.00073, 0.99955, 0.99973, 1.00092, 0.99973, 1, 0.99998, 1, 1.0003, 1, 1.00043, 1.00001, 0.99969, 1.0003, 1, 1.00035, 1.00001, 0.9995, 1, 1.00092, 0.99973, 0.99973, 0.99973, 1.0007, 0.9995, 1, 0.99924, 1.0006, 0.99924, 0.99972, 1.00062, 0.99973, 1.00114, 1.00073, 1, 0.99955, 1, 1, 1.00047, 0.99968, 1.00016, 0.99977, 1.00016, 0.99977, 1.00016, 0.99977, 1.00001, 1, 1, 1, 0.99973, 1, 1, 0.99955, 0.99924, 0.99924, 0.99924, 0.99924, 0.99998, 0.99998, 0.99998, 0.99973, 0.99973, 0.99972, 1, 1, 1.00267, 0.99999, 0.99998, 0.99998, 1, 0.99998, 1.66475, 1, 0.99973, 0.99973, 1.00023, 0.99973, 0.99971, 0.99925, 1.00023, 1, 0.99991, 0.99984, 1.00002, 1.00002, 1.00002, 1.00002, 1, 1, 1, 1, 1, 1, 1, 0.96329, 1, 1.20985, 1.39713, 1.00003, 0.8254, 1.00015, 1, 1.00035, 1.00027, 1.00031, 1.00031, 0.99915, 1.00031, 1.00031, 0.99999, 1.00003, 0.99999, 0.99999, 1.41144, 1.6, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.41144, 1.40579, 1.40579, 1.36625, 0.99999, 1, 0.99861, 0.99861, 1, 1.00026, 1.00026, 1.00026, 1.00026, 0.95317, 0.99999, 0.99999, 0.99999, 0.99999, 1.40483, 1, 0.99977, 1.00054, 1, 1, 0.99953, 0.99962, 1.00042, 0.9995, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.HelveticaRegularFactors = HelveticaRegularFactors; +const HelveticaRegularMetrics = { + lineHeight: 1.2, + lineGap: 0.2 +}; +exports.HelveticaRegularMetrics = HelveticaRegularMetrics; + +/***/ }), +/* 54 */ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.LiberationSansRegularWidths = exports.LiberationSansRegularMapping = exports.LiberationSansItalicWidths = exports.LiberationSansItalicMapping = exports.LiberationSansBoldWidths = exports.LiberationSansBoldMapping = exports.LiberationSansBoldItalicWidths = exports.LiberationSansBoldItalicMapping = void 0; +const LiberationSansBoldWidths = [365, 0, 333, 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 737, 552, 400, 549, 333, 333, 333, 576, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278, 611, 611, 611, 611, 611, 611, 611, 549, 611, 611, 611, 611, 611, 556, 611, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 719, 722, 611, 667, 556, 667, 556, 667, 556, 667, 556, 667, 556, 778, 611, 778, 611, 778, 611, 778, 611, 722, 611, 722, 611, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 785, 556, 556, 278, 722, 556, 556, 611, 278, 611, 278, 611, 385, 611, 479, 611, 278, 722, 611, 722, 611, 722, 611, 708, 723, 611, 778, 611, 778, 611, 778, 611, 1000, 944, 722, 389, 722, 389, 722, 389, 667, 556, 667, 556, 667, 556, 667, 556, 611, 333, 611, 479, 611, 333, 722, 611, 722, 611, 722, 611, 722, 611, 722, 611, 722, 611, 944, 778, 667, 556, 667, 611, 500, 611, 500, 611, 500, 278, 556, 722, 556, 1000, 889, 778, 611, 667, 556, 611, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 465, 722, 333, 853, 906, 474, 825, 927, 838, 278, 722, 722, 601, 719, 667, 611, 722, 778, 278, 722, 667, 833, 722, 644, 778, 722, 667, 600, 611, 667, 821, 667, 809, 802, 278, 667, 615, 451, 611, 278, 582, 615, 610, 556, 606, 475, 460, 611, 541, 278, 558, 556, 612, 556, 445, 611, 766, 619, 520, 684, 446, 582, 715, 576, 753, 845, 278, 582, 611, 582, 845, 667, 669, 885, 567, 711, 667, 278, 276, 556, 1094, 1062, 875, 610, 722, 622, 719, 722, 719, 722, 567, 712, 667, 904, 626, 719, 719, 610, 702, 833, 722, 778, 719, 667, 722, 611, 622, 854, 667, 730, 703, 1005, 1019, 870, 979, 719, 711, 1031, 719, 556, 618, 615, 417, 635, 556, 709, 497, 615, 615, 500, 635, 740, 604, 611, 604, 611, 556, 490, 556, 875, 556, 615, 581, 833, 844, 729, 854, 615, 552, 854, 583, 556, 556, 611, 417, 552, 556, 278, 281, 278, 969, 906, 611, 500, 615, 556, 604, 778, 611, 487, 447, 944, 778, 944, 778, 944, 778, 667, 556, 333, 333, 556, 1000, 1000, 552, 278, 278, 278, 278, 500, 500, 500, 556, 556, 350, 1000, 1000, 240, 479, 333, 333, 604, 333, 167, 396, 556, 556, 1094, 556, 885, 489, 1115, 1000, 768, 600, 834, 834, 834, 834, 1000, 500, 1000, 500, 1000, 500, 500, 494, 612, 823, 713, 584, 549, 713, 979, 722, 274, 549, 549, 583, 549, 549, 604, 584, 604, 604, 708, 625, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 729, 604, 604, 354, 354, 1000, 990, 990, 990, 990, 494, 604, 604, 604, 604, 354, 1021, 1052, 917, 750, 750, 531, 656, 594, 510, 500, 750, 750, 611, 611, 333, 333, 333, 333, 333, 333, 333, 333, 222, 222, 333, 333, 333, 333, 333, 333, 333, 333]; +exports.LiberationSansBoldWidths = LiberationSansBoldWidths; +const LiberationSansBoldMapping = [-1, -1, -1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 402, 506, 507, 508, 509, 510, 511, 536, 537, 538, 539, 710, 711, 713, 728, 729, 730, 731, 732, 733, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1138, 1139, 1168, 1169, 7808, 7809, 7810, 7811, 7812, 7813, 7922, 7923, 8208, 8209, 8211, 8212, 8213, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8224, 8225, 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8252, 8254, 8260, 8319, 8355, 8356, 8359, 8364, 8453, 8467, 8470, 8482, 8486, 8494, 8539, 8540, 8541, 8542, 8592, 8593, 8594, 8595, 8596, 8597, 8616, 8706, 8710, 8719, 8721, 8722, 8730, 8734, 8735, 8745, 8747, 8776, 8800, 8801, 8804, 8805, 8962, 8976, 8992, 8993, 9472, 9474, 9484, 9488, 9492, 9496, 9500, 9508, 9516, 9524, 9532, 9552, 9553, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9561, 9562, 9563, 9564, 9565, 9566, 9567, 9568, 9569, 9570, 9571, 9572, 9573, 9574, 9575, 9576, 9577, 9578, 9579, 9580, 9600, 9604, 9608, 9612, 9616, 9617, 9618, 9619, 9632, 9633, 9642, 9643, 9644, 9650, 9658, 9660, 9668, 9674, 9675, 9679, 9688, 9689, 9702, 9786, 9787, 9788, 9792, 9794, 9824, 9827, 9829, 9830, 9834, 9835, 9836, 61441, 61442, 61445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]; +exports.LiberationSansBoldMapping = LiberationSansBoldMapping; +const LiberationSansBoldItalicWidths = [365, 0, 333, 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 737, 552, 400, 549, 333, 333, 333, 576, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611, 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278, 611, 611, 611, 611, 611, 611, 611, 549, 611, 611, 611, 611, 611, 556, 611, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 740, 722, 611, 667, 556, 667, 556, 667, 556, 667, 556, 667, 556, 778, 611, 778, 611, 778, 611, 778, 611, 722, 611, 722, 611, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 782, 556, 556, 278, 722, 556, 556, 611, 278, 611, 278, 611, 396, 611, 479, 611, 278, 722, 611, 722, 611, 722, 611, 708, 723, 611, 778, 611, 778, 611, 778, 611, 1000, 944, 722, 389, 722, 389, 722, 389, 667, 556, 667, 556, 667, 556, 667, 556, 611, 333, 611, 479, 611, 333, 722, 611, 722, 611, 722, 611, 722, 611, 722, 611, 722, 611, 944, 778, 667, 556, 667, 611, 500, 611, 500, 611, 500, 278, 556, 722, 556, 1000, 889, 778, 611, 667, 556, 611, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 722, 333, 854, 906, 473, 844, 930, 847, 278, 722, 722, 610, 671, 667, 611, 722, 778, 278, 722, 667, 833, 722, 657, 778, 718, 667, 590, 611, 667, 822, 667, 829, 781, 278, 667, 620, 479, 611, 278, 591, 620, 621, 556, 610, 479, 492, 611, 558, 278, 566, 556, 603, 556, 450, 611, 712, 605, 532, 664, 409, 591, 704, 578, 773, 834, 278, 591, 611, 591, 834, 667, 667, 886, 614, 719, 667, 278, 278, 556, 1094, 1042, 854, 622, 719, 677, 719, 722, 708, 722, 614, 722, 667, 927, 643, 719, 719, 615, 687, 833, 722, 778, 719, 667, 722, 611, 677, 781, 667, 729, 708, 979, 989, 854, 1000, 708, 719, 1042, 729, 556, 619, 604, 534, 618, 556, 736, 510, 611, 611, 507, 622, 740, 604, 611, 611, 611, 556, 889, 556, 885, 556, 646, 583, 889, 935, 707, 854, 594, 552, 865, 589, 556, 556, 611, 469, 563, 556, 278, 278, 278, 969, 906, 611, 507, 619, 556, 611, 778, 611, 575, 467, 944, 778, 944, 778, 944, 778, 667, 556, 333, 333, 556, 1000, 1000, 552, 278, 278, 278, 278, 500, 500, 500, 556, 556, 350, 1000, 1000, 240, 479, 333, 333, 604, 333, 167, 396, 556, 556, 1104, 556, 885, 516, 1146, 1000, 768, 600, 834, 834, 834, 834, 999, 500, 1000, 500, 1000, 500, 500, 494, 612, 823, 713, 584, 549, 713, 979, 722, 274, 549, 549, 583, 549, 549, 604, 584, 604, 604, 708, 625, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 729, 604, 604, 354, 354, 1000, 990, 990, 990, 990, 494, 604, 604, 604, 604, 354, 1021, 1052, 917, 750, 750, 531, 656, 594, 510, 500, 750, 750, 611, 611, 333, 333, 333, 333, 333, 333, 333, 333, 222, 222, 333, 333, 333, 333, 333, 333, 333, 333]; +exports.LiberationSansBoldItalicWidths = LiberationSansBoldItalicWidths; +const LiberationSansBoldItalicMapping = [-1, -1, -1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 402, 506, 507, 508, 509, 510, 511, 536, 537, 538, 539, 710, 711, 713, 728, 729, 730, 731, 732, 733, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1138, 1139, 1168, 1169, 7808, 7809, 7810, 7811, 7812, 7813, 7922, 7923, 8208, 8209, 8211, 8212, 8213, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8224, 8225, 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8252, 8254, 8260, 8319, 8355, 8356, 8359, 8364, 8453, 8467, 8470, 8482, 8486, 8494, 8539, 8540, 8541, 8542, 8592, 8593, 8594, 8595, 8596, 8597, 8616, 8706, 8710, 8719, 8721, 8722, 8730, 8734, 8735, 8745, 8747, 8776, 8800, 8801, 8804, 8805, 8962, 8976, 8992, 8993, 9472, 9474, 9484, 9488, 9492, 9496, 9500, 9508, 9516, 9524, 9532, 9552, 9553, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9561, 9562, 9563, 9564, 9565, 9566, 9567, 9568, 9569, 9570, 9571, 9572, 9573, 9574, 9575, 9576, 9577, 9578, 9579, 9580, 9600, 9604, 9608, 9612, 9616, 9617, 9618, 9619, 9632, 9633, 9642, 9643, 9644, 9650, 9658, 9660, 9668, 9674, 9675, 9679, 9688, 9689, 9702, 9786, 9787, 9788, 9792, 9794, 9824, 9827, 9829, 9830, 9834, 9835, 9836, 61441, 61442, 61445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]; +exports.LiberationSansBoldItalicMapping = LiberationSansBoldItalicMapping; +const LiberationSansItalicWidths = [365, 0, 333, 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 737, 552, 400, 549, 333, 333, 333, 576, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, 556, 556, 556, 556, 556, 556, 556, 549, 611, 556, 556, 556, 556, 500, 556, 500, 667, 556, 667, 556, 667, 556, 722, 500, 722, 500, 722, 500, 722, 500, 722, 625, 722, 556, 667, 556, 667, 556, 667, 556, 667, 556, 667, 556, 778, 556, 778, 556, 778, 556, 778, 556, 722, 556, 722, 556, 278, 278, 278, 278, 278, 278, 278, 222, 278, 278, 733, 444, 500, 222, 667, 500, 500, 556, 222, 556, 222, 556, 281, 556, 400, 556, 222, 722, 556, 722, 556, 722, 556, 615, 723, 556, 778, 556, 778, 556, 778, 556, 1000, 944, 722, 333, 722, 333, 722, 333, 667, 500, 667, 500, 667, 500, 667, 500, 611, 278, 611, 354, 611, 278, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 944, 722, 667, 500, 667, 611, 500, 611, 500, 611, 500, 222, 556, 667, 556, 1000, 889, 778, 611, 667, 500, 611, 278, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 667, 278, 789, 846, 389, 794, 865, 775, 222, 667, 667, 570, 671, 667, 611, 722, 778, 278, 667, 667, 833, 722, 648, 778, 725, 667, 600, 611, 667, 837, 667, 831, 761, 278, 667, 570, 439, 555, 222, 550, 570, 571, 500, 556, 439, 463, 555, 542, 222, 500, 492, 548, 500, 447, 556, 670, 573, 486, 603, 374, 550, 652, 546, 728, 779, 222, 550, 556, 550, 779, 667, 667, 843, 544, 708, 667, 278, 278, 500, 1066, 982, 844, 589, 715, 639, 724, 667, 651, 667, 544, 704, 667, 917, 614, 715, 715, 589, 686, 833, 722, 778, 725, 667, 722, 611, 639, 795, 667, 727, 673, 920, 923, 805, 886, 651, 694, 1022, 682, 556, 562, 522, 493, 553, 556, 688, 465, 556, 556, 472, 564, 686, 550, 556, 556, 556, 500, 833, 500, 835, 500, 572, 518, 830, 851, 621, 736, 526, 492, 752, 534, 556, 556, 556, 378, 496, 500, 222, 222, 222, 910, 828, 556, 472, 565, 500, 556, 778, 556, 492, 339, 944, 722, 944, 722, 944, 722, 667, 500, 333, 333, 556, 1000, 1000, 552, 222, 222, 222, 222, 333, 333, 333, 556, 556, 350, 1000, 1000, 188, 354, 333, 333, 500, 333, 167, 365, 556, 556, 1094, 556, 885, 323, 1083, 1000, 768, 600, 834, 834, 834, 834, 1000, 500, 998, 500, 1000, 500, 500, 494, 612, 823, 713, 584, 549, 713, 979, 719, 274, 549, 549, 584, 549, 549, 604, 584, 604, 604, 708, 625, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 729, 604, 604, 354, 354, 1000, 990, 990, 990, 990, 494, 604, 604, 604, 604, 354, 1021, 1052, 917, 750, 750, 531, 656, 594, 510, 500, 750, 750, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 222, 222, 294, 294, 324, 324, 316, 328, 398, 285]; +exports.LiberationSansItalicWidths = LiberationSansItalicWidths; +const LiberationSansItalicMapping = [-1, -1, -1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 402, 506, 507, 508, 509, 510, 511, 536, 537, 538, 539, 710, 711, 713, 728, 729, 730, 731, 732, 733, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1138, 1139, 1168, 1169, 7808, 7809, 7810, 7811, 7812, 7813, 7922, 7923, 8208, 8209, 8211, 8212, 8213, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8224, 8225, 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8252, 8254, 8260, 8319, 8355, 8356, 8359, 8364, 8453, 8467, 8470, 8482, 8486, 8494, 8539, 8540, 8541, 8542, 8592, 8593, 8594, 8595, 8596, 8597, 8616, 8706, 8710, 8719, 8721, 8722, 8730, 8734, 8735, 8745, 8747, 8776, 8800, 8801, 8804, 8805, 8962, 8976, 8992, 8993, 9472, 9474, 9484, 9488, 9492, 9496, 9500, 9508, 9516, 9524, 9532, 9552, 9553, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9561, 9562, 9563, 9564, 9565, 9566, 9567, 9568, 9569, 9570, 9571, 9572, 9573, 9574, 9575, 9576, 9577, 9578, 9579, 9580, 9600, 9604, 9608, 9612, 9616, 9617, 9618, 9619, 9632, 9633, 9642, 9643, 9644, 9650, 9658, 9660, 9668, 9674, 9675, 9679, 9688, 9689, 9702, 9786, 9787, 9788, 9792, 9794, 9824, 9827, 9829, 9830, 9834, 9835, 9836, 61441, 61442, 61445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]; +exports.LiberationSansItalicMapping = LiberationSansItalicMapping; +const LiberationSansRegularWidths = [365, 0, 333, 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 737, 552, 400, 549, 333, 333, 333, 576, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, 556, 556, 556, 556, 556, 556, 556, 549, 611, 556, 556, 556, 556, 500, 556, 500, 667, 556, 667, 556, 667, 556, 722, 500, 722, 500, 722, 500, 722, 500, 722, 615, 722, 556, 667, 556, 667, 556, 667, 556, 667, 556, 667, 556, 778, 556, 778, 556, 778, 556, 778, 556, 722, 556, 722, 556, 278, 278, 278, 278, 278, 278, 278, 222, 278, 278, 735, 444, 500, 222, 667, 500, 500, 556, 222, 556, 222, 556, 292, 556, 334, 556, 222, 722, 556, 722, 556, 722, 556, 604, 723, 556, 778, 556, 778, 556, 778, 556, 1000, 944, 722, 333, 722, 333, 722, 333, 667, 500, 667, 500, 667, 500, 667, 500, 611, 278, 611, 375, 611, 278, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 722, 556, 944, 722, 667, 500, 667, 611, 500, 611, 500, 611, 500, 222, 556, 667, 556, 1000, 889, 778, 611, 667, 500, 611, 278, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 667, 278, 784, 838, 384, 774, 855, 752, 222, 667, 667, 551, 668, 667, 611, 722, 778, 278, 667, 668, 833, 722, 650, 778, 722, 667, 618, 611, 667, 798, 667, 835, 748, 278, 667, 578, 446, 556, 222, 547, 578, 575, 500, 557, 446, 441, 556, 556, 222, 500, 500, 576, 500, 448, 556, 690, 569, 482, 617, 395, 547, 648, 525, 713, 781, 222, 547, 556, 547, 781, 667, 667, 865, 542, 719, 667, 278, 278, 500, 1057, 1010, 854, 583, 722, 635, 719, 667, 656, 667, 542, 677, 667, 923, 604, 719, 719, 583, 656, 833, 722, 778, 719, 667, 722, 611, 635, 760, 667, 740, 667, 917, 938, 792, 885, 656, 719, 1010, 722, 556, 573, 531, 365, 583, 556, 669, 458, 559, 559, 438, 583, 688, 552, 556, 542, 556, 500, 458, 500, 823, 500, 573, 521, 802, 823, 625, 719, 521, 510, 750, 542, 556, 556, 556, 365, 510, 500, 222, 278, 222, 906, 812, 556, 438, 559, 500, 552, 778, 556, 489, 411, 944, 722, 944, 722, 944, 722, 667, 500, 333, 333, 556, 1000, 1000, 552, 222, 222, 222, 222, 333, 333, 333, 556, 556, 350, 1000, 1000, 188, 354, 333, 333, 500, 333, 167, 365, 556, 556, 1094, 556, 885, 323, 1073, 1000, 768, 600, 834, 834, 834, 834, 1000, 500, 1000, 500, 1000, 500, 500, 494, 612, 823, 713, 584, 549, 713, 979, 719, 274, 549, 549, 583, 549, 549, 604, 584, 604, 604, 708, 625, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 729, 604, 604, 354, 354, 1000, 990, 990, 990, 990, 494, 604, 604, 604, 604, 354, 1021, 1052, 917, 750, 750, 531, 656, 594, 510, 500, 750, 750, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 222, 222, 294, 294, 324, 324, 316, 328, 398, 285]; +exports.LiberationSansRegularWidths = LiberationSansRegularWidths; +const LiberationSansRegularMapping = [-1, -1, -1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 402, 506, 507, 508, 509, 510, 511, 536, 537, 538, 539, 710, 711, 713, 728, 729, 730, 731, 732, 733, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1138, 1139, 1168, 1169, 7808, 7809, 7810, 7811, 7812, 7813, 7922, 7923, 8208, 8209, 8211, 8212, 8213, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8224, 8225, 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8252, 8254, 8260, 8319, 8355, 8356, 8359, 8364, 8453, 8467, 8470, 8482, 8486, 8494, 8539, 8540, 8541, 8542, 8592, 8593, 8594, 8595, 8596, 8597, 8616, 8706, 8710, 8719, 8721, 8722, 8730, 8734, 8735, 8745, 8747, 8776, 8800, 8801, 8804, 8805, 8962, 8976, 8992, 8993, 9472, 9474, 9484, 9488, 9492, 9496, 9500, 9508, 9516, 9524, 9532, 9552, 9553, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9561, 9562, 9563, 9564, 9565, 9566, 9567, 9568, 9569, 9570, 9571, 9572, 9573, 9574, 9575, 9576, 9577, 9578, 9579, 9580, 9600, 9604, 9608, 9612, 9616, 9617, 9618, 9619, 9632, 9633, 9642, 9643, 9644, 9650, 9658, 9660, 9668, 9674, 9675, 9679, 9688, 9689, 9702, 9786, 9787, 9788, 9792, 9794, 9824, 9827, 9829, 9830, 9834, 9835, 9836, 61441, 61442, 61445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]; +exports.LiberationSansRegularMapping = LiberationSansRegularMapping; + +/***/ }), +/* 55 */ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.MyriadProRegularMetrics = exports.MyriadProRegularFactors = exports.MyriadProItalicMetrics = exports.MyriadProItalicFactors = exports.MyriadProBoldMetrics = exports.MyriadProBoldItalicMetrics = exports.MyriadProBoldItalicFactors = exports.MyriadProBoldFactors = void 0; +const MyriadProBoldFactors = [1.36898, 1, 1, 0.72706, 0.80479, 0.83734, 0.98894, 0.99793, 0.9897, 0.93884, 0.86209, 0.94292, 0.94292, 1.16661, 1.02058, 0.93582, 0.96694, 0.93582, 1.19137, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.99793, 0.78076, 0.78076, 1.02058, 1.02058, 1.02058, 0.72851, 0.78966, 0.90838, 0.83637, 0.82391, 0.96376, 0.80061, 0.86275, 0.8768, 0.95407, 1.0258, 0.73901, 0.85022, 0.83655, 1.0156, 0.95546, 0.92179, 0.87107, 0.92179, 0.82114, 0.8096, 0.89713, 0.94438, 0.95353, 0.94083, 0.91905, 0.90406, 0.9446, 0.94292, 1.18777, 0.94292, 1.02058, 0.89903, 0.90088, 0.94938, 0.97898, 0.81093, 0.97571, 0.94938, 1.024, 0.9577, 0.95933, 0.98621, 1.0474, 0.97455, 0.98981, 0.9672, 0.95933, 0.9446, 0.97898, 0.97407, 0.97646, 0.78036, 1.10208, 0.95442, 0.95298, 0.97579, 0.9332, 0.94039, 0.938, 0.80687, 1.01149, 0.80687, 1.02058, 0.80479, 0.99793, 0.99793, 0.99793, 0.99793, 1.01149, 1.00872, 0.90088, 0.91882, 1.0213, 0.8361, 1.02058, 0.62295, 0.54324, 0.89022, 1.08595, 1, 1, 0.90088, 1, 0.97455, 0.93582, 0.90088, 1, 1.05686, 0.8361, 0.99642, 0.99642, 0.99642, 0.72851, 0.90838, 0.90838, 0.90838, 0.90838, 0.90838, 0.90838, 0.868, 0.82391, 0.80061, 0.80061, 0.80061, 0.80061, 1.0258, 1.0258, 1.0258, 1.0258, 0.97484, 0.95546, 0.92179, 0.92179, 0.92179, 0.92179, 0.92179, 1.02058, 0.92179, 0.94438, 0.94438, 0.94438, 0.94438, 0.90406, 0.86958, 0.98225, 0.94938, 0.94938, 0.94938, 0.94938, 0.94938, 0.94938, 0.9031, 0.81093, 0.94938, 0.94938, 0.94938, 0.94938, 0.98621, 0.98621, 0.98621, 0.98621, 0.93969, 0.95933, 0.9446, 0.9446, 0.9446, 0.9446, 0.9446, 1.08595, 0.9446, 0.95442, 0.95442, 0.95442, 0.95442, 0.94039, 0.97898, 0.94039, 0.90838, 0.94938, 0.90838, 0.94938, 0.90838, 0.94938, 0.82391, 0.81093, 0.82391, 0.81093, 0.82391, 0.81093, 0.82391, 0.81093, 0.96376, 0.84313, 0.97484, 0.97571, 0.80061, 0.94938, 0.80061, 0.94938, 0.80061, 0.94938, 0.80061, 0.94938, 0.80061, 0.94938, 0.8768, 0.9577, 0.8768, 0.9577, 0.8768, 0.9577, 1, 1, 0.95407, 0.95933, 0.97069, 0.95933, 1.0258, 0.98621, 1.0258, 0.98621, 1.0258, 0.98621, 1.0258, 0.98621, 1.0258, 0.98621, 0.887, 1.01591, 0.73901, 1.0474, 1, 1, 0.97455, 0.83655, 0.98981, 1, 1, 0.83655, 0.73977, 0.83655, 0.73903, 0.84638, 1.033, 0.95546, 0.95933, 1, 1, 0.95546, 0.95933, 0.8271, 0.95417, 0.95933, 0.92179, 0.9446, 0.92179, 0.9446, 0.92179, 0.9446, 0.936, 0.91964, 0.82114, 0.97646, 1, 1, 0.82114, 0.97646, 0.8096, 0.78036, 0.8096, 0.78036, 1, 1, 0.8096, 0.78036, 1, 1, 0.89713, 0.77452, 0.89713, 1.10208, 0.94438, 0.95442, 0.94438, 0.95442, 0.94438, 0.95442, 0.94438, 0.95442, 0.94438, 0.95442, 0.94438, 0.95442, 0.94083, 0.97579, 0.90406, 0.94039, 0.90406, 0.9446, 0.938, 0.9446, 0.938, 0.9446, 0.938, 1, 0.99793, 0.90838, 0.94938, 0.868, 0.9031, 0.92179, 0.9446, 1, 1, 0.89713, 1.10208, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90989, 0.9358, 0.91945, 0.83181, 0.75261, 0.87992, 0.82976, 0.96034, 0.83689, 0.97268, 1.0078, 0.90838, 0.83637, 0.8019, 0.90157, 0.80061, 0.9446, 0.95407, 0.92436, 1.0258, 0.85022, 0.97153, 1.0156, 0.95546, 0.89192, 0.92179, 0.92361, 0.87107, 0.96318, 0.89713, 0.93704, 0.95638, 0.91905, 0.91709, 0.92796, 1.0258, 0.93704, 0.94836, 1.0373, 0.95933, 1.0078, 0.95871, 0.94836, 0.96174, 0.92601, 0.9498, 0.98607, 0.95776, 0.95933, 1.05453, 1.0078, 0.98275, 0.9314, 0.95617, 0.91701, 1.05993, 0.9446, 0.78367, 0.9553, 1, 0.86832, 1.0128, 0.95871, 0.99394, 0.87548, 0.96361, 0.86774, 1.0078, 0.95871, 0.9446, 0.95871, 0.86774, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.94083, 0.97579, 0.94083, 0.97579, 0.94083, 0.97579, 0.90406, 0.94039, 0.96694, 1, 0.89903, 1, 1, 1, 0.93582, 0.93582, 0.93582, 1, 0.908, 0.908, 0.918, 0.94219, 0.94219, 0.96544, 1, 1.285, 1, 1, 0.81079, 0.81079, 1, 1, 0.74854, 1, 1, 1, 1, 0.99793, 1, 1, 1, 0.65, 1, 1.36145, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.17173, 1, 0.80535, 0.76169, 1.02058, 1.0732, 1.05486, 1, 1, 1.30692, 1.08595, 1.08595, 1, 1.08595, 1.08595, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.16161, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.MyriadProBoldFactors = MyriadProBoldFactors; +const MyriadProBoldMetrics = { + lineHeight: 1.2, + lineGap: 0.2 +}; +exports.MyriadProBoldMetrics = MyriadProBoldMetrics; +const MyriadProBoldItalicFactors = [1.36898, 1, 1, 0.66227, 0.80779, 0.81625, 0.97276, 0.97276, 0.97733, 0.92222, 0.83266, 0.94292, 0.94292, 1.16148, 1.02058, 0.93582, 0.96694, 0.93582, 1.17337, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.97276, 0.78076, 0.78076, 1.02058, 1.02058, 1.02058, 0.71541, 0.76813, 0.85576, 0.80591, 0.80729, 0.94299, 0.77512, 0.83655, 0.86523, 0.92222, 0.98621, 0.71743, 0.81698, 0.79726, 0.98558, 0.92222, 0.90637, 0.83809, 0.90637, 0.80729, 0.76463, 0.86275, 0.90699, 0.91605, 0.9154, 0.85308, 0.85458, 0.90531, 0.94292, 1.21296, 0.94292, 1.02058, 0.89903, 1.18616, 0.99613, 0.91677, 0.78216, 0.91677, 0.90083, 0.98796, 0.9135, 0.92168, 0.95381, 0.98981, 0.95298, 0.95381, 0.93459, 0.92168, 0.91513, 0.92004, 0.91677, 0.95077, 0.748, 1.04502, 0.91677, 0.92061, 0.94236, 0.89544, 0.89364, 0.9, 0.80687, 0.8578, 0.80687, 1.02058, 0.80779, 0.97276, 0.97276, 0.97276, 0.97276, 0.8578, 0.99973, 1.18616, 0.91339, 1.08074, 0.82891, 1.02058, 0.55509, 0.71526, 0.89022, 1.08595, 1, 1, 1.18616, 1, 0.96736, 0.93582, 1.18616, 1, 1.04864, 0.82711, 0.99043, 0.99043, 0.99043, 0.71541, 0.85576, 0.85576, 0.85576, 0.85576, 0.85576, 0.85576, 0.845, 0.80729, 0.77512, 0.77512, 0.77512, 0.77512, 0.98621, 0.98621, 0.98621, 0.98621, 0.95961, 0.92222, 0.90637, 0.90637, 0.90637, 0.90637, 0.90637, 1.02058, 0.90251, 0.90699, 0.90699, 0.90699, 0.90699, 0.85458, 0.83659, 0.94951, 0.99613, 0.99613, 0.99613, 0.99613, 0.99613, 0.99613, 0.85811, 0.78216, 0.90083, 0.90083, 0.90083, 0.90083, 0.95381, 0.95381, 0.95381, 0.95381, 0.9135, 0.92168, 0.91513, 0.91513, 0.91513, 0.91513, 0.91513, 1.08595, 0.91677, 0.91677, 0.91677, 0.91677, 0.91677, 0.89364, 0.92332, 0.89364, 0.85576, 0.99613, 0.85576, 0.99613, 0.85576, 0.99613, 0.80729, 0.78216, 0.80729, 0.78216, 0.80729, 0.78216, 0.80729, 0.78216, 0.94299, 0.76783, 0.95961, 0.91677, 0.77512, 0.90083, 0.77512, 0.90083, 0.77512, 0.90083, 0.77512, 0.90083, 0.77512, 0.90083, 0.86523, 0.9135, 0.86523, 0.9135, 0.86523, 0.9135, 1, 1, 0.92222, 0.92168, 0.92222, 0.92168, 0.98621, 0.95381, 0.98621, 0.95381, 0.98621, 0.95381, 0.98621, 0.95381, 0.98621, 0.95381, 0.86036, 0.97096, 0.71743, 0.98981, 1, 1, 0.95298, 0.79726, 0.95381, 1, 1, 0.79726, 0.6894, 0.79726, 0.74321, 0.81691, 1.0006, 0.92222, 0.92168, 1, 1, 0.92222, 0.92168, 0.79464, 0.92098, 0.92168, 0.90637, 0.91513, 0.90637, 0.91513, 0.90637, 0.91513, 0.909, 0.87514, 0.80729, 0.95077, 1, 1, 0.80729, 0.95077, 0.76463, 0.748, 0.76463, 0.748, 1, 1, 0.76463, 0.748, 1, 1, 0.86275, 0.72651, 0.86275, 1.04502, 0.90699, 0.91677, 0.90699, 0.91677, 0.90699, 0.91677, 0.90699, 0.91677, 0.90699, 0.91677, 0.90699, 0.91677, 0.9154, 0.94236, 0.85458, 0.89364, 0.85458, 0.90531, 0.9, 0.90531, 0.9, 0.90531, 0.9, 1, 0.97276, 0.85576, 0.99613, 0.845, 0.85811, 0.90251, 0.91677, 1, 1, 0.86275, 1.04502, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.18616, 1.00899, 1.30628, 0.85576, 0.80178, 0.66862, 0.7927, 0.69323, 0.88127, 0.72459, 0.89711, 0.95381, 0.85576, 0.80591, 0.7805, 0.94729, 0.77512, 0.90531, 0.92222, 0.90637, 0.98621, 0.81698, 0.92655, 0.98558, 0.92222, 0.85359, 0.90637, 0.90976, 0.83809, 0.94523, 0.86275, 0.83509, 0.93157, 0.85308, 0.83392, 0.92346, 0.98621, 0.83509, 0.92886, 0.91324, 0.92168, 0.95381, 0.90646, 0.92886, 0.90557, 0.86847, 0.90276, 0.91324, 0.86842, 0.92168, 0.99531, 0.95381, 0.9224, 0.85408, 0.92699, 0.86847, 1.0051, 0.91513, 0.80487, 0.93481, 1, 0.88159, 1.05214, 0.90646, 0.97355, 0.81539, 0.89398, 0.85923, 0.95381, 0.90646, 0.91513, 0.90646, 0.85923, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9154, 0.94236, 0.9154, 0.94236, 0.9154, 0.94236, 0.85458, 0.89364, 0.96694, 1, 0.89903, 1, 1, 1, 0.91782, 0.91782, 0.91782, 1, 0.896, 0.896, 0.896, 0.9332, 0.9332, 0.95973, 1, 1.26, 1, 1, 0.80479, 0.80178, 1, 1, 0.85633, 1, 1, 1, 1, 0.97276, 1, 1, 1, 0.698, 1, 1.36145, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.14542, 1, 0.79199, 0.78694, 1.02058, 1.03493, 1.05486, 1, 1, 1.23026, 1.08595, 1.08595, 1, 1.08595, 1.08595, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.20006, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.MyriadProBoldItalicFactors = MyriadProBoldItalicFactors; +const MyriadProBoldItalicMetrics = { + lineHeight: 1.2, + lineGap: 0.2 +}; +exports.MyriadProBoldItalicMetrics = MyriadProBoldItalicMetrics; +const MyriadProItalicFactors = [1.36898, 1, 1, 0.65507, 0.84943, 0.85639, 0.88465, 0.88465, 0.86936, 0.88307, 0.86948, 0.85283, 0.85283, 1.06383, 1.02058, 0.75945, 0.9219, 0.75945, 1.17337, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.88465, 0.75945, 0.75945, 1.02058, 1.02058, 1.02058, 0.69046, 0.70926, 0.85158, 0.77812, 0.76852, 0.89591, 0.70466, 0.76125, 0.80094, 0.86822, 0.83864, 0.728, 0.77212, 0.79475, 0.93637, 0.87514, 0.8588, 0.76013, 0.8588, 0.72421, 0.69866, 0.77598, 0.85991, 0.80811, 0.87832, 0.78112, 0.77512, 0.8562, 1.0222, 1.18417, 1.0222, 1.27014, 0.89903, 1.15012, 0.93859, 0.94399, 0.846, 0.94399, 0.81453, 1.0186, 0.94219, 0.96017, 1.03075, 1.02175, 0.912, 1.03075, 0.96998, 0.96017, 0.93859, 0.94399, 0.94399, 0.95493, 0.746, 1.12658, 0.94578, 0.91, 0.979, 0.882, 0.882, 0.83, 0.85034, 0.83537, 0.85034, 1.02058, 0.70869, 0.88465, 0.88465, 0.88465, 0.88465, 0.83537, 0.90083, 1.15012, 0.9161, 0.94565, 0.73541, 1.02058, 0.53609, 0.69353, 0.79519, 1.08595, 1, 1, 1.15012, 1, 0.91974, 0.75945, 1.15012, 1, 0.9446, 0.73361, 0.9005, 0.9005, 0.9005, 0.62864, 0.85158, 0.85158, 0.85158, 0.85158, 0.85158, 0.85158, 0.773, 0.76852, 0.70466, 0.70466, 0.70466, 0.70466, 0.83864, 0.83864, 0.83864, 0.83864, 0.90561, 0.87514, 0.8588, 0.8588, 0.8588, 0.8588, 0.8588, 1.02058, 0.85751, 0.85991, 0.85991, 0.85991, 0.85991, 0.77512, 0.76013, 0.88075, 0.93859, 0.93859, 0.93859, 0.93859, 0.93859, 0.93859, 0.8075, 0.846, 0.81453, 0.81453, 0.81453, 0.81453, 0.82424, 0.82424, 0.82424, 0.82424, 0.9278, 0.96017, 0.93859, 0.93859, 0.93859, 0.93859, 0.93859, 1.08595, 0.8562, 0.94578, 0.94578, 0.94578, 0.94578, 0.882, 0.94578, 0.882, 0.85158, 0.93859, 0.85158, 0.93859, 0.85158, 0.93859, 0.76852, 0.846, 0.76852, 0.846, 0.76852, 0.846, 0.76852, 0.846, 0.89591, 0.8544, 0.90561, 0.94399, 0.70466, 0.81453, 0.70466, 0.81453, 0.70466, 0.81453, 0.70466, 0.81453, 0.70466, 0.81453, 0.80094, 0.94219, 0.80094, 0.94219, 0.80094, 0.94219, 1, 1, 0.86822, 0.96017, 0.86822, 0.96017, 0.83864, 0.82424, 0.83864, 0.82424, 0.83864, 0.82424, 0.83864, 1.03075, 0.83864, 0.82424, 0.81402, 1.02738, 0.728, 1.02175, 1, 1, 0.912, 0.79475, 1.03075, 1, 1, 0.79475, 0.83911, 0.79475, 0.66266, 0.80553, 1.06676, 0.87514, 0.96017, 1, 1, 0.87514, 0.96017, 0.86865, 0.87396, 0.96017, 0.8588, 0.93859, 0.8588, 0.93859, 0.8588, 0.93859, 0.867, 0.84759, 0.72421, 0.95493, 1, 1, 0.72421, 0.95493, 0.69866, 0.746, 0.69866, 0.746, 1, 1, 0.69866, 0.746, 1, 1, 0.77598, 0.88417, 0.77598, 1.12658, 0.85991, 0.94578, 0.85991, 0.94578, 0.85991, 0.94578, 0.85991, 0.94578, 0.85991, 0.94578, 0.85991, 0.94578, 0.87832, 0.979, 0.77512, 0.882, 0.77512, 0.8562, 0.83, 0.8562, 0.83, 0.8562, 0.83, 1, 0.88465, 0.85158, 0.93859, 0.773, 0.8075, 0.85751, 0.8562, 1, 1, 0.77598, 1.12658, 1.15012, 1.15012, 1.15012, 1.15012, 1.15012, 1.15313, 1.15012, 1.15012, 1.15012, 1.08106, 1.03901, 0.85158, 0.77025, 0.62264, 0.7646, 0.65351, 0.86026, 0.69461, 0.89947, 1.03075, 0.85158, 0.77812, 0.76449, 0.88836, 0.70466, 0.8562, 0.86822, 0.8588, 0.83864, 0.77212, 0.85308, 0.93637, 0.87514, 0.82352, 0.8588, 0.85701, 0.76013, 0.89058, 0.77598, 0.8156, 0.82565, 0.78112, 0.77899, 0.89386, 0.83864, 0.8156, 0.9486, 0.92388, 0.96186, 1.03075, 0.91123, 0.9486, 0.93298, 0.878, 0.93942, 0.92388, 0.84596, 0.96186, 0.95119, 1.03075, 0.922, 0.88787, 0.95829, 0.88, 0.93559, 0.93859, 0.78815, 0.93758, 1, 0.89217, 1.03737, 0.91123, 0.93969, 0.77487, 0.85769, 0.86799, 1.03075, 0.91123, 0.93859, 0.91123, 0.86799, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.87832, 0.979, 0.87832, 0.979, 0.87832, 0.979, 0.77512, 0.882, 0.9219, 1, 0.89903, 1, 1, 1, 0.87321, 0.87321, 0.87321, 1, 1.027, 1.027, 1.027, 0.86847, 0.86847, 0.79121, 1, 1.124, 1, 1, 0.73572, 0.73572, 1, 1, 0.85034, 1, 1, 1, 1, 0.88465, 1, 1, 1, 0.669, 1, 1.36145, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.04828, 1, 0.74948, 0.75187, 1.02058, 0.98391, 1.02119, 1, 1, 1.06233, 1.08595, 1.08595, 1, 1.08595, 1.08595, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.05233, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.MyriadProItalicFactors = MyriadProItalicFactors; +const MyriadProItalicMetrics = { + lineHeight: 1.2, + lineGap: 0.2 +}; +exports.MyriadProItalicMetrics = MyriadProItalicMetrics; +const MyriadProRegularFactors = [1.36898, 1, 1, 0.76305, 0.82784, 0.94935, 0.89364, 0.92241, 0.89073, 0.90706, 0.98472, 0.85283, 0.85283, 1.0664, 1.02058, 0.74505, 0.9219, 0.74505, 1.23456, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.92241, 0.74505, 0.74505, 1.02058, 1.02058, 1.02058, 0.73002, 0.72601, 0.91755, 0.8126, 0.80314, 0.92222, 0.73764, 0.79726, 0.83051, 0.90284, 0.86023, 0.74, 0.8126, 0.84869, 0.96518, 0.91115, 0.8858, 0.79761, 0.8858, 0.74498, 0.73914, 0.81363, 0.89591, 0.83659, 0.89633, 0.85608, 0.8111, 0.90531, 1.0222, 1.22736, 1.0222, 1.27014, 0.89903, 0.90088, 0.86667, 1.0231, 0.896, 1.01411, 0.90083, 1.05099, 1.00512, 0.99793, 1.05326, 1.09377, 0.938, 1.06226, 1.00119, 0.99793, 0.98714, 1.0231, 1.01231, 0.98196, 0.792, 1.19137, 0.99074, 0.962, 1.01915, 0.926, 0.942, 0.856, 0.85034, 0.92006, 0.85034, 1.02058, 0.69067, 0.92241, 0.92241, 0.92241, 0.92241, 0.92006, 0.9332, 0.90088, 0.91882, 0.93484, 0.75339, 1.02058, 0.56866, 0.54324, 0.79519, 1.08595, 1, 1, 0.90088, 1, 0.95325, 0.74505, 0.90088, 1, 0.97198, 0.75339, 0.91009, 0.91009, 0.91009, 0.66466, 0.91755, 0.91755, 0.91755, 0.91755, 0.91755, 0.91755, 0.788, 0.80314, 0.73764, 0.73764, 0.73764, 0.73764, 0.86023, 0.86023, 0.86023, 0.86023, 0.92915, 0.91115, 0.8858, 0.8858, 0.8858, 0.8858, 0.8858, 1.02058, 0.8858, 0.89591, 0.89591, 0.89591, 0.89591, 0.8111, 0.79611, 0.89713, 0.86667, 0.86667, 0.86667, 0.86667, 0.86667, 0.86667, 0.86936, 0.896, 0.90083, 0.90083, 0.90083, 0.90083, 0.84224, 0.84224, 0.84224, 0.84224, 0.97276, 0.99793, 0.98714, 0.98714, 0.98714, 0.98714, 0.98714, 1.08595, 0.89876, 0.99074, 0.99074, 0.99074, 0.99074, 0.942, 1.0231, 0.942, 0.91755, 0.86667, 0.91755, 0.86667, 0.91755, 0.86667, 0.80314, 0.896, 0.80314, 0.896, 0.80314, 0.896, 0.80314, 0.896, 0.92222, 0.93372, 0.92915, 1.01411, 0.73764, 0.90083, 0.73764, 0.90083, 0.73764, 0.90083, 0.73764, 0.90083, 0.73764, 0.90083, 0.83051, 1.00512, 0.83051, 1.00512, 0.83051, 1.00512, 1, 1, 0.90284, 0.99793, 0.90976, 0.99793, 0.86023, 0.84224, 0.86023, 0.84224, 0.86023, 0.84224, 0.86023, 1.05326, 0.86023, 0.84224, 0.82873, 1.07469, 0.74, 1.09377, 1, 1, 0.938, 0.84869, 1.06226, 1, 1, 0.84869, 0.83704, 0.84869, 0.81441, 0.85588, 1.08927, 0.91115, 0.99793, 1, 1, 0.91115, 0.99793, 0.91887, 0.90991, 0.99793, 0.8858, 0.98714, 0.8858, 0.98714, 0.8858, 0.98714, 0.894, 0.91434, 0.74498, 0.98196, 1, 1, 0.74498, 0.98196, 0.73914, 0.792, 0.73914, 0.792, 1, 1, 0.73914, 0.792, 1, 1, 0.81363, 0.904, 0.81363, 1.19137, 0.89591, 0.99074, 0.89591, 0.99074, 0.89591, 0.99074, 0.89591, 0.99074, 0.89591, 0.99074, 0.89591, 0.99074, 0.89633, 1.01915, 0.8111, 0.942, 0.8111, 0.90531, 0.856, 0.90531, 0.856, 0.90531, 0.856, 1, 0.92241, 0.91755, 0.86667, 0.788, 0.86936, 0.8858, 0.89876, 1, 1, 0.81363, 1.19137, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90088, 0.90388, 1.03901, 0.92138, 0.78105, 0.7154, 0.86169, 0.80513, 0.94007, 0.82528, 0.98612, 1.06226, 0.91755, 0.8126, 0.81884, 0.92819, 0.73764, 0.90531, 0.90284, 0.8858, 0.86023, 0.8126, 0.91172, 0.96518, 0.91115, 0.83089, 0.8858, 0.87791, 0.79761, 0.89297, 0.81363, 0.88157, 0.89992, 0.85608, 0.81992, 0.94307, 0.86023, 0.88157, 0.95308, 0.98699, 0.99793, 1.06226, 0.95817, 0.95308, 0.97358, 0.928, 0.98088, 0.98699, 0.92761, 0.99793, 0.96017, 1.06226, 0.986, 0.944, 0.95978, 0.938, 0.96705, 0.98714, 0.80442, 0.98972, 1, 0.89762, 1.04552, 0.95817, 0.99007, 0.87064, 0.91879, 0.88888, 1.06226, 0.95817, 0.98714, 0.95817, 0.88888, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.89633, 1.01915, 0.89633, 1.01915, 0.89633, 1.01915, 0.8111, 0.942, 0.9219, 1, 0.89903, 1, 1, 1, 0.93173, 0.93173, 0.93173, 1, 1.06304, 1.06304, 1.06904, 0.89903, 0.89903, 0.80549, 1, 1.156, 1, 1, 0.76575, 0.76575, 1, 1, 0.72458, 1, 1, 1, 1, 0.92241, 1, 1, 1, 0.619, 1, 1.36145, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.07257, 1, 0.74705, 0.71119, 1.02058, 1.024, 1.02119, 1, 1, 1.1536, 1.08595, 1.08595, 1, 1.08595, 1.08595, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.05638, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.MyriadProRegularFactors = MyriadProRegularFactors; +const MyriadProRegularMetrics = { + lineHeight: 1.2, + lineGap: 0.2 +}; +exports.MyriadProRegularMetrics = MyriadProRegularMetrics; + +/***/ }), +/* 56 */ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.SegoeuiRegularMetrics = exports.SegoeuiRegularFactors = exports.SegoeuiItalicMetrics = exports.SegoeuiItalicFactors = exports.SegoeuiBoldMetrics = exports.SegoeuiBoldItalicMetrics = exports.SegoeuiBoldItalicFactors = exports.SegoeuiBoldFactors = void 0; +const SegoeuiBoldFactors = [1.76738, 1, 1, 0.99297, 0.9824, 1.04016, 1.06497, 1.03424, 0.97529, 1.17647, 1.23203, 1.1085, 1.1085, 1.16939, 1.2107, 0.9754, 1.21408, 0.9754, 1.59578, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 1.03424, 0.81378, 0.81378, 1.2107, 1.2107, 1.2107, 0.71703, 0.97847, 0.97363, 0.88776, 0.8641, 1.02096, 0.79795, 0.85132, 0.914, 1.06085, 1.1406, 0.8007, 0.89858, 0.83693, 1.14889, 1.09398, 0.97489, 0.92094, 0.97489, 0.90399, 0.84041, 0.95923, 1.00135, 1, 1.06467, 0.98243, 0.90996, 0.99361, 1.1085, 1.56942, 1.1085, 1.2107, 0.74627, 0.94282, 0.96752, 1.01519, 0.86304, 1.01359, 0.97278, 1.15103, 1.01359, 0.98561, 1.02285, 1.02285, 1.00527, 1.02285, 1.0302, 0.99041, 1.0008, 1.01519, 1.01359, 1.02258, 0.79104, 1.16862, 0.99041, 0.97454, 1.02511, 0.99298, 0.96752, 0.95801, 0.94856, 1.16579, 0.94856, 1.2107, 0.9824, 1.03424, 1.03424, 1, 1.03424, 1.16579, 0.8727, 1.3871, 1.18622, 1.10818, 1.04478, 1.2107, 1.18622, 0.75155, 0.94994, 1.28826, 1.21408, 1.21408, 0.91056, 1, 0.91572, 0.9754, 0.64663, 1.18328, 1.24866, 1.04478, 1.14169, 1.15749, 1.17389, 0.71703, 0.97363, 0.97363, 0.97363, 0.97363, 0.97363, 0.97363, 0.93506, 0.8641, 0.79795, 0.79795, 0.79795, 0.79795, 1.1406, 1.1406, 1.1406, 1.1406, 1.02096, 1.09398, 0.97426, 0.97426, 0.97426, 0.97426, 0.97426, 1.2107, 0.97489, 1.00135, 1.00135, 1.00135, 1.00135, 0.90996, 0.92094, 1.02798, 0.96752, 0.96752, 0.96752, 0.96752, 0.96752, 0.96752, 0.93136, 0.86304, 0.97278, 0.97278, 0.97278, 0.97278, 1.02285, 1.02285, 1.02285, 1.02285, 0.97122, 0.99041, 1, 1, 1, 1, 1, 1.28826, 1.0008, 0.99041, 0.99041, 0.99041, 0.99041, 0.96752, 1.01519, 0.96752, 0.97363, 0.96752, 0.97363, 0.96752, 0.97363, 0.96752, 0.8641, 0.86304, 0.8641, 0.86304, 0.8641, 0.86304, 0.8641, 0.86304, 1.02096, 1.03057, 1.02096, 1.03517, 0.79795, 0.97278, 0.79795, 0.97278, 0.79795, 0.97278, 0.79795, 0.97278, 0.79795, 0.97278, 0.914, 1.01359, 0.914, 1.01359, 0.914, 1.01359, 1, 1, 1.06085, 0.98561, 1.06085, 1.00879, 1.1406, 1.02285, 1.1406, 1.02285, 1.1406, 1.02285, 1.1406, 1.02285, 1.1406, 1.02285, 0.97138, 1.08692, 0.8007, 1.02285, 1, 1, 1.00527, 0.83693, 1.02285, 1, 1, 0.83693, 0.9455, 0.83693, 0.90418, 0.83693, 1.13005, 1.09398, 0.99041, 1, 1, 1.09398, 0.99041, 0.96692, 1.09251, 0.99041, 0.97489, 1.0008, 0.97489, 1.0008, 0.97489, 1.0008, 0.93994, 0.97931, 0.90399, 1.02258, 1, 1, 0.90399, 1.02258, 0.84041, 0.79104, 0.84041, 0.79104, 0.84041, 0.79104, 0.84041, 0.79104, 1, 1, 0.95923, 1.07034, 0.95923, 1.16862, 1.00135, 0.99041, 1.00135, 0.99041, 1.00135, 0.99041, 1.00135, 0.99041, 1.00135, 0.99041, 1.00135, 0.99041, 1.06467, 1.02511, 0.90996, 0.96752, 0.90996, 0.99361, 0.95801, 0.99361, 0.95801, 0.99361, 0.95801, 1.07733, 1.03424, 0.97363, 0.96752, 0.93506, 0.93136, 0.97489, 1.0008, 1, 1, 0.95923, 1.16862, 1.15103, 1.15103, 1.01173, 1.03959, 0.75953, 0.81378, 0.79912, 1.15103, 1.21994, 0.95161, 0.87815, 1.01149, 0.81525, 0.7676, 0.98167, 1.01134, 1.02546, 0.84097, 1.03089, 1.18102, 0.97363, 0.88776, 0.85134, 0.97826, 0.79795, 0.99361, 1.06085, 0.97489, 1.1406, 0.89858, 1.0388, 1.14889, 1.09398, 0.86039, 0.97489, 1.0595, 0.92094, 0.94793, 0.95923, 0.90996, 0.99346, 0.98243, 1.02112, 0.95493, 1.1406, 0.90996, 1.03574, 1.02597, 1.0008, 1.18102, 1.06628, 1.03574, 1.0192, 1.01932, 1.00886, 0.97531, 1.0106, 1.0008, 1.13189, 1.18102, 1.02277, 0.98683, 1.0016, 0.99561, 1.07237, 1.0008, 0.90434, 0.99921, 0.93803, 0.8965, 1.23085, 1.06628, 1.04983, 0.96268, 1.0499, 0.98439, 1.18102, 1.06628, 1.0008, 1.06628, 0.98439, 0.79795, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.09466, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.97278, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.02065, 1, 1, 1, 1, 1, 1, 1.06467, 1.02511, 1.06467, 1.02511, 1.06467, 1.02511, 0.90996, 0.96752, 1, 1.21408, 0.89903, 1, 1, 0.75155, 1.04394, 1.04394, 1.04394, 1.04394, 0.98633, 0.98633, 0.98633, 0.73047, 0.73047, 1.20642, 0.91211, 1.25635, 1.222, 1.02956, 1.03372, 1.03372, 0.96039, 1.24633, 1, 1.12454, 0.93503, 1.03424, 1.19687, 1.03424, 1, 1, 1, 0.771, 1, 1, 1.15749, 1.15749, 1.15749, 1.10948, 0.86279, 0.94434, 0.86279, 0.94434, 0.86182, 1, 1, 1.16897, 1, 0.96085, 0.90137, 1.2107, 1.18416, 1.13973, 0.69825, 0.9716, 2.10339, 1.29004, 1.29004, 1.21172, 1.29004, 1.29004, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.42603, 1, 0.99862, 0.99862, 1, 0.87025, 0.87025, 0.87025, 0.87025, 1.18874, 1.42603, 1, 1.42603, 1.42603, 0.99862, 1, 1, 1, 1, 1, 1.2886, 1.04315, 1.15296, 1.34163, 1, 1, 1, 1.09193, 1.09193, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.SegoeuiBoldFactors = SegoeuiBoldFactors; +const SegoeuiBoldMetrics = { + lineHeight: 1.33008, + lineGap: 0 +}; +exports.SegoeuiBoldMetrics = SegoeuiBoldMetrics; +const SegoeuiBoldItalicFactors = [1.76738, 1, 1, 0.98946, 1.03959, 1.04016, 1.02809, 1.036, 0.97639, 1.10953, 1.23203, 1.11144, 1.11144, 1.16939, 1.21237, 0.9754, 1.21261, 0.9754, 1.59754, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 1.036, 0.81378, 0.81378, 1.21237, 1.21237, 1.21237, 0.73541, 0.97847, 0.97363, 0.89723, 0.87897, 1.0426, 0.79429, 0.85292, 0.91149, 1.05815, 1.1406, 0.79631, 0.90128, 0.83853, 1.04396, 1.10615, 0.97552, 0.94436, 0.97552, 0.88641, 0.80527, 0.96083, 1.00135, 1, 1.06777, 0.9817, 0.91142, 0.99361, 1.11144, 1.57293, 1.11144, 1.21237, 0.74627, 1.31818, 1.06585, 0.97042, 0.83055, 0.97042, 0.93503, 1.1261, 0.97042, 0.97922, 1.14236, 0.94552, 1.01054, 1.14236, 1.02471, 0.97922, 0.94165, 0.97042, 0.97042, 1.0276, 0.78929, 1.1261, 0.97922, 0.95874, 1.02197, 0.98507, 0.96752, 0.97168, 0.95107, 1.16579, 0.95107, 1.21237, 1.03959, 1.036, 1.036, 1, 1.036, 1.16579, 0.87357, 1.31818, 1.18754, 1.26781, 1.05356, 1.21237, 1.18622, 0.79487, 0.94994, 1.29004, 1.24047, 1.24047, 1.31818, 1, 0.91484, 0.9754, 1.31818, 1.1349, 1.24866, 1.05356, 1.13934, 1.15574, 1.17389, 0.73541, 0.97363, 0.97363, 0.97363, 0.97363, 0.97363, 0.97363, 0.94385, 0.87897, 0.79429, 0.79429, 0.79429, 0.79429, 1.1406, 1.1406, 1.1406, 1.1406, 1.0426, 1.10615, 0.97552, 0.97552, 0.97552, 0.97552, 0.97552, 1.21237, 0.97552, 1.00135, 1.00135, 1.00135, 1.00135, 0.91142, 0.94436, 0.98721, 1.06585, 1.06585, 1.06585, 1.06585, 1.06585, 1.06585, 0.96705, 0.83055, 0.93503, 0.93503, 0.93503, 0.93503, 1.14236, 1.14236, 1.14236, 1.14236, 0.93125, 0.97922, 0.94165, 0.94165, 0.94165, 0.94165, 0.94165, 1.29004, 0.94165, 0.97922, 0.97922, 0.97922, 0.97922, 0.96752, 0.97042, 0.96752, 0.97363, 1.06585, 0.97363, 1.06585, 0.97363, 1.06585, 0.87897, 0.83055, 0.87897, 0.83055, 0.87897, 0.83055, 0.87897, 0.83055, 1.0426, 1.0033, 1.0426, 0.97042, 0.79429, 0.93503, 0.79429, 0.93503, 0.79429, 0.93503, 0.79429, 0.93503, 0.79429, 0.93503, 0.91149, 0.97042, 0.91149, 0.97042, 0.91149, 0.97042, 1, 1, 1.05815, 0.97922, 1.05815, 0.97922, 1.1406, 1.14236, 1.1406, 1.14236, 1.1406, 1.14236, 1.1406, 1.14236, 1.1406, 1.14236, 0.97441, 1.04302, 0.79631, 1.01582, 1, 1, 1.01054, 0.83853, 1.14236, 1, 1, 0.83853, 1.09125, 0.83853, 0.90418, 0.83853, 1.19508, 1.10615, 0.97922, 1, 1, 1.10615, 0.97922, 1.01034, 1.10466, 0.97922, 0.97552, 0.94165, 0.97552, 0.94165, 0.97552, 0.94165, 0.91602, 0.91981, 0.88641, 1.0276, 1, 1, 0.88641, 1.0276, 0.80527, 0.78929, 0.80527, 0.78929, 0.80527, 0.78929, 0.80527, 0.78929, 1, 1, 0.96083, 1.05403, 0.95923, 1.16862, 1.00135, 0.97922, 1.00135, 0.97922, 1.00135, 0.97922, 1.00135, 0.97922, 1.00135, 0.97922, 1.00135, 0.97922, 1.06777, 1.02197, 0.91142, 0.96752, 0.91142, 0.99361, 0.97168, 0.99361, 0.97168, 0.99361, 0.97168, 1.23199, 1.036, 0.97363, 1.06585, 0.94385, 0.96705, 0.97552, 0.94165, 1, 1, 0.96083, 1.1261, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 1.31818, 0.95161, 1.27126, 1.00811, 0.83284, 0.77702, 0.99137, 0.95253, 1.0347, 0.86142, 1.07205, 1.14236, 0.97363, 0.89723, 0.86869, 1.09818, 0.79429, 0.99361, 1.05815, 0.97552, 1.1406, 0.90128, 1.06662, 1.04396, 1.10615, 0.84918, 0.97552, 1.04694, 0.94436, 0.98015, 0.96083, 0.91142, 1.00356, 0.9817, 1.01945, 0.98999, 1.1406, 0.91142, 1.04961, 0.9898, 1.00639, 1.14236, 1.07514, 1.04961, 0.99607, 1.02897, 1.008, 0.9898, 0.95134, 1.00639, 1.11121, 1.14236, 1.00518, 0.97981, 1.02186, 1, 1.08578, 0.94165, 0.99314, 0.98387, 0.93028, 0.93377, 1.35125, 1.07514, 1.10687, 0.93491, 1.04232, 1.00351, 1.14236, 1.07514, 0.94165, 1.07514, 1.00351, 0.79429, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.09097, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.93503, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.96609, 1, 1, 1, 1, 1, 1, 1.06777, 1.02197, 1.06777, 1.02197, 1.06777, 1.02197, 0.91142, 0.96752, 1, 1.21261, 0.89903, 1, 1, 0.75155, 1.04745, 1.04745, 1.04745, 1.04394, 0.98633, 0.98633, 0.98633, 0.72959, 0.72959, 1.20502, 0.91406, 1.26514, 1.222, 1.02956, 1.03372, 1.03372, 0.96039, 1.24633, 1, 1.09125, 0.93327, 1.03336, 1.16541, 1.036, 1, 1, 1, 0.771, 1, 1, 1.15574, 1.15574, 1.15574, 1.15574, 0.86364, 0.94434, 0.86279, 0.94434, 0.86224, 1, 1, 1.16798, 1, 0.96085, 0.90068, 1.21237, 1.18416, 1.13904, 0.69825, 0.9716, 2.10339, 1.29004, 1.29004, 1.21339, 1.29004, 1.29004, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.42603, 1, 0.99862, 0.99862, 1, 0.87025, 0.87025, 0.87025, 0.87025, 1.18775, 1.42603, 1, 1.42603, 1.42603, 0.99862, 1, 1, 1, 1, 1, 1.2886, 1.04315, 1.15296, 1.34163, 1, 1, 1, 1.13269, 1.13269, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.SegoeuiBoldItalicFactors = SegoeuiBoldItalicFactors; +const SegoeuiBoldItalicMetrics = { + lineHeight: 1.33008, + lineGap: 0 +}; +exports.SegoeuiBoldItalicMetrics = SegoeuiBoldItalicMetrics; +const SegoeuiItalicFactors = [1.76738, 1, 1, 0.98946, 1.14763, 1.05365, 1.06234, 0.96927, 0.92586, 1.15373, 1.18414, 0.91349, 0.91349, 1.07403, 1.17308, 0.78383, 1.20088, 0.78383, 1.42531, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.78383, 0.78383, 1.17308, 1.17308, 1.17308, 0.77349, 0.94565, 0.94729, 0.85944, 0.88506, 0.9858, 0.74817, 0.80016, 0.88449, 0.98039, 0.95782, 0.69238, 0.89898, 0.83231, 0.98183, 1.03989, 0.96924, 0.86237, 0.96924, 0.80595, 0.74524, 0.86091, 0.95402, 0.94143, 0.98448, 0.8858, 0.83089, 0.93285, 1.0949, 1.39016, 1.0949, 1.45994, 0.74627, 1.04839, 0.97454, 0.97454, 0.87207, 0.97454, 0.87533, 1.06151, 0.97454, 1.00176, 1.16484, 1.08132, 0.98047, 1.16484, 1.02989, 1.01054, 0.96225, 0.97454, 0.97454, 1.06598, 0.79004, 1.16344, 1.00351, 0.94629, 0.9973, 0.91016, 0.96777, 0.9043, 0.91082, 0.92481, 0.91082, 1.17308, 0.95748, 0.96927, 0.96927, 1, 0.96927, 0.92481, 0.80597, 1.04839, 1.23393, 1.1781, 0.9245, 1.17308, 1.20808, 0.63218, 0.94261, 1.24822, 1.09971, 1.09971, 1.04839, 1, 0.85273, 0.78032, 1.04839, 1.09971, 1.22326, 0.9245, 1.09836, 1.13525, 1.15222, 0.70424, 0.94729, 0.94729, 0.94729, 0.94729, 0.94729, 0.94729, 0.85498, 0.88506, 0.74817, 0.74817, 0.74817, 0.74817, 0.95782, 0.95782, 0.95782, 0.95782, 0.9858, 1.03989, 0.96924, 0.96924, 0.96924, 0.96924, 0.96924, 1.17308, 0.96924, 0.95402, 0.95402, 0.95402, 0.95402, 0.83089, 0.86237, 0.88409, 0.97454, 0.97454, 0.97454, 0.97454, 0.97454, 0.97454, 0.92916, 0.87207, 0.87533, 0.87533, 0.87533, 0.87533, 0.93146, 0.93146, 0.93146, 0.93146, 0.93854, 1.01054, 0.96225, 0.96225, 0.96225, 0.96225, 0.96225, 1.24822, 0.8761, 1.00351, 1.00351, 1.00351, 1.00351, 0.96777, 0.97454, 0.96777, 0.94729, 0.97454, 0.94729, 0.97454, 0.94729, 0.97454, 0.88506, 0.87207, 0.88506, 0.87207, 0.88506, 0.87207, 0.88506, 0.87207, 0.9858, 0.95391, 0.9858, 0.97454, 0.74817, 0.87533, 0.74817, 0.87533, 0.74817, 0.87533, 0.74817, 0.87533, 0.74817, 0.87533, 0.88449, 0.97454, 0.88449, 0.97454, 0.88449, 0.97454, 1, 1, 0.98039, 1.00176, 0.98039, 1.00176, 0.95782, 0.93146, 0.95782, 0.93146, 0.95782, 0.93146, 0.95782, 1.16484, 0.95782, 0.93146, 0.84421, 1.12761, 0.69238, 1.08132, 1, 1, 0.98047, 0.83231, 1.16484, 1, 1, 0.84723, 1.04861, 0.84723, 0.78755, 0.83231, 1.23736, 1.03989, 1.01054, 1, 1, 1.03989, 1.01054, 0.9857, 1.03849, 1.01054, 0.96924, 0.96225, 0.96924, 0.96225, 0.96924, 0.96225, 0.92383, 0.90171, 0.80595, 1.06598, 1, 1, 0.80595, 1.06598, 0.74524, 0.79004, 0.74524, 0.79004, 0.74524, 0.79004, 0.74524, 0.79004, 1, 1, 0.86091, 1.02759, 0.85771, 1.16344, 0.95402, 1.00351, 0.95402, 1.00351, 0.95402, 1.00351, 0.95402, 1.00351, 0.95402, 1.00351, 0.95402, 1.00351, 0.98448, 0.9973, 0.83089, 0.96777, 0.83089, 0.93285, 0.9043, 0.93285, 0.9043, 0.93285, 0.9043, 1.31868, 0.96927, 0.94729, 0.97454, 0.85498, 0.92916, 0.96924, 0.8761, 1, 1, 0.86091, 1.16344, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 1.04839, 0.81965, 0.81965, 0.94729, 0.78032, 0.71022, 0.90883, 0.84171, 0.99877, 0.77596, 1.05734, 1.2, 0.94729, 0.85944, 0.82791, 0.9607, 0.74817, 0.93285, 0.98039, 0.96924, 0.95782, 0.89898, 0.98316, 0.98183, 1.03989, 0.78614, 0.96924, 0.97642, 0.86237, 0.86075, 0.86091, 0.83089, 0.90082, 0.8858, 0.97296, 1.01284, 0.95782, 0.83089, 1.0976, 1.04, 1.03342, 1.2, 1.0675, 1.0976, 0.98205, 1.03809, 1.05097, 1.04, 0.95364, 1.03342, 1.05401, 1.2, 1.02148, 1.0119, 1.04724, 1.0127, 1.02732, 0.96225, 0.8965, 0.97783, 0.93574, 0.94818, 1.30679, 1.0675, 1.11826, 0.99821, 1.0557, 1.0326, 1.2, 1.0675, 0.96225, 1.0675, 1.0326, 0.74817, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.03754, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.87533, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.98705, 1, 1, 1, 1, 1, 1, 0.98448, 0.9973, 0.98448, 0.9973, 0.98448, 0.9973, 0.83089, 0.96777, 1, 1.20088, 0.89903, 1, 1, 0.75155, 0.94945, 0.94945, 0.94945, 0.94945, 1.12317, 1.12317, 1.12317, 0.67603, 0.67603, 1.15621, 0.73584, 1.21191, 1.22135, 1.06483, 0.94868, 0.94868, 0.95996, 1.24633, 1, 1.07497, 0.87709, 0.96927, 1.01473, 0.96927, 1, 1, 1, 0.77295, 1, 1, 1.09836, 1.09836, 1.09836, 1.01522, 0.86321, 0.94434, 0.8649, 0.94434, 0.86182, 1, 1, 1.083, 1, 0.91578, 0.86438, 1.17308, 1.18416, 1.14589, 0.69825, 0.97622, 1.96791, 1.24822, 1.24822, 1.17308, 1.24822, 1.24822, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.42603, 1, 0.99862, 0.99862, 1, 0.87025, 0.87025, 0.87025, 0.87025, 1.17984, 1.42603, 1, 1.42603, 1.42603, 0.99862, 1, 1, 1, 1, 1, 1.2886, 1.04315, 1.15296, 1.34163, 1, 1, 1, 1.10742, 1.10742, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.SegoeuiItalicFactors = SegoeuiItalicFactors; +const SegoeuiItalicMetrics = { + lineHeight: 1.33008, + lineGap: 0 +}; +exports.SegoeuiItalicMetrics = SegoeuiItalicMetrics; +const SegoeuiRegularFactors = [1.76738, 1, 1, 0.98594, 1.02285, 1.10454, 1.06234, 0.96927, 0.92037, 1.19985, 1.2046, 0.90616, 0.90616, 1.07152, 1.1714, 0.78032, 1.20088, 0.78032, 1.40246, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.96927, 0.78032, 0.78032, 1.1714, 1.1714, 1.1714, 0.80597, 0.94084, 0.96706, 0.85944, 0.85734, 0.97093, 0.75842, 0.79936, 0.88198, 0.9831, 0.95782, 0.71387, 0.86969, 0.84636, 1.07796, 1.03584, 0.96924, 0.83968, 0.96924, 0.82826, 0.79649, 0.85771, 0.95132, 0.93119, 0.98965, 0.88433, 0.8287, 0.93365, 1.08612, 1.3638, 1.08612, 1.45786, 0.74627, 0.80499, 0.91484, 1.05707, 0.92383, 1.05882, 0.9403, 1.12654, 1.05882, 1.01756, 1.09011, 1.09011, 0.99414, 1.09011, 1.034, 1.01756, 1.05356, 1.05707, 1.05882, 1.04399, 0.84863, 1.21968, 1.01756, 0.95801, 1.00068, 0.91797, 0.96777, 0.9043, 0.90351, 0.92105, 0.90351, 1.1714, 0.85337, 0.96927, 0.96927, 0.99912, 0.96927, 0.92105, 0.80597, 1.2434, 1.20808, 1.05937, 0.90957, 1.1714, 1.20808, 0.75155, 0.94261, 1.24644, 1.09971, 1.09971, 0.84751, 1, 0.85273, 0.78032, 0.61584, 1.05425, 1.17914, 0.90957, 1.08665, 1.11593, 1.14169, 0.73381, 0.96706, 0.96706, 0.96706, 0.96706, 0.96706, 0.96706, 0.86035, 0.85734, 0.75842, 0.75842, 0.75842, 0.75842, 0.95782, 0.95782, 0.95782, 0.95782, 0.97093, 1.03584, 0.96924, 0.96924, 0.96924, 0.96924, 0.96924, 1.1714, 0.96924, 0.95132, 0.95132, 0.95132, 0.95132, 0.8287, 0.83968, 0.89049, 0.91484, 0.91484, 0.91484, 0.91484, 0.91484, 0.91484, 0.93575, 0.92383, 0.9403, 0.9403, 0.9403, 0.9403, 0.8717, 0.8717, 0.8717, 0.8717, 1.00527, 1.01756, 1.05356, 1.05356, 1.05356, 1.05356, 1.05356, 1.24644, 0.95923, 1.01756, 1.01756, 1.01756, 1.01756, 0.96777, 1.05707, 0.96777, 0.96706, 0.91484, 0.96706, 0.91484, 0.96706, 0.91484, 0.85734, 0.92383, 0.85734, 0.92383, 0.85734, 0.92383, 0.85734, 0.92383, 0.97093, 1.0969, 0.97093, 1.05882, 0.75842, 0.9403, 0.75842, 0.9403, 0.75842, 0.9403, 0.75842, 0.9403, 0.75842, 0.9403, 0.88198, 1.05882, 0.88198, 1.05882, 0.88198, 1.05882, 1, 1, 0.9831, 1.01756, 0.9831, 1.01756, 0.95782, 0.8717, 0.95782, 0.8717, 0.95782, 0.8717, 0.95782, 1.09011, 0.95782, 0.8717, 0.84784, 1.11551, 0.71387, 1.09011, 1, 1, 0.99414, 0.84636, 1.09011, 1, 1, 0.84636, 1.0536, 0.84636, 0.94298, 0.84636, 1.23297, 1.03584, 1.01756, 1, 1, 1.03584, 1.01756, 1.00323, 1.03444, 1.01756, 0.96924, 1.05356, 0.96924, 1.05356, 0.96924, 1.05356, 0.93066, 0.98293, 0.82826, 1.04399, 1, 1, 0.82826, 1.04399, 0.79649, 0.84863, 0.79649, 0.84863, 0.79649, 0.84863, 0.79649, 0.84863, 1, 1, 0.85771, 1.17318, 0.85771, 1.21968, 0.95132, 1.01756, 0.95132, 1.01756, 0.95132, 1.01756, 0.95132, 1.01756, 0.95132, 1.01756, 0.95132, 1.01756, 0.98965, 1.00068, 0.8287, 0.96777, 0.8287, 0.93365, 0.9043, 0.93365, 0.9043, 0.93365, 0.9043, 1.08571, 0.96927, 0.96706, 0.91484, 0.86035, 0.93575, 0.96924, 0.95923, 1, 1, 0.85771, 1.21968, 1.11437, 1.11437, 0.93109, 0.91202, 0.60411, 0.84164, 0.55572, 1.01173, 0.97361, 0.81818, 0.81818, 0.96635, 0.78032, 0.72727, 0.92366, 0.98601, 1.03405, 0.77968, 1.09799, 1.2, 0.96706, 0.85944, 0.85638, 0.96491, 0.75842, 0.93365, 0.9831, 0.96924, 0.95782, 0.86969, 0.94152, 1.07796, 1.03584, 0.78437, 0.96924, 0.98715, 0.83968, 0.83491, 0.85771, 0.8287, 0.94492, 0.88433, 0.9287, 1.0098, 0.95782, 0.8287, 1.0625, 0.98248, 1.03424, 1.2, 1.01071, 1.0625, 0.95246, 1.03809, 1.04912, 0.98248, 1.00221, 1.03424, 1.05443, 1.2, 1.04785, 0.99609, 1.00169, 1.05176, 0.99346, 1.05356, 0.9087, 1.03004, 0.95542, 0.93117, 1.23362, 1.01071, 1.07831, 1.02512, 1.05205, 1.03502, 1.2, 1.01071, 1.05356, 1.01071, 1.03502, 0.75842, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.03719, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9403, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.04021, 1, 1, 1, 1, 1, 1, 0.98965, 1.00068, 0.98965, 1.00068, 0.98965, 1.00068, 0.8287, 0.96777, 1, 1.20088, 0.89903, 1, 1, 0.75155, 1.03077, 1.03077, 1.03077, 1.03077, 1.13196, 1.13196, 1.13196, 0.67428, 0.67428, 1.16039, 0.73291, 1.20996, 1.22135, 1.06483, 0.94868, 0.94868, 0.95996, 1.24633, 1, 1.07497, 0.87796, 0.96927, 1.01518, 0.96927, 1, 1, 1, 0.77295, 1, 1, 1.10539, 1.10539, 1.11358, 1.06967, 0.86279, 0.94434, 0.86279, 0.94434, 0.86182, 1, 1, 1.083, 1, 0.91578, 0.86507, 1.1714, 1.18416, 1.14589, 0.69825, 0.97622, 1.9697, 1.24822, 1.24822, 1.17238, 1.24822, 1.24822, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.42603, 1, 0.99862, 0.99862, 1, 0.87025, 0.87025, 0.87025, 0.87025, 1.18083, 1.42603, 1, 1.42603, 1.42603, 0.99862, 1, 1, 1, 1, 1, 1.2886, 1.04315, 1.15296, 1.34163, 1, 1, 1, 1.10938, 1.10938, 1, 1, 1, 1.05425, 1.09971, 1.09971, 1.09971, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +exports.SegoeuiRegularFactors = SegoeuiRegularFactors; +const SegoeuiRegularMetrics = { + lineHeight: 1.33008, + lineGap: 0 +}; +exports.SegoeuiRegularMetrics = SegoeuiRegularMetrics; + +/***/ }), +/* 57 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.PostScriptEvaluator = exports.PostScriptCompiler = exports.PDFFunctionFactory = void 0; +exports.isPDFFunction = isPDFFunction; +var _primitives = __w_pdfjs_require__(4); +var _util = __w_pdfjs_require__(2); +var _ps_parser = __w_pdfjs_require__(58); +var _base_stream = __w_pdfjs_require__(5); +var _image_utils = __w_pdfjs_require__(59); +class PDFFunctionFactory { + constructor({ + xref, + isEvalSupported = true + }) { + this.xref = xref; + this.isEvalSupported = isEvalSupported !== false; + } + create(fn) { + const cachedFunction = this.getCached(fn); + if (cachedFunction) { + return cachedFunction; + } + const parsedFunction = PDFFunction.parse({ + xref: this.xref, + isEvalSupported: this.isEvalSupported, + fn: fn instanceof _primitives.Ref ? this.xref.fetch(fn) : fn + }); + this._cache(fn, parsedFunction); + return parsedFunction; + } + createFromArray(fnObj) { + const cachedFunction = this.getCached(fnObj); + if (cachedFunction) { + return cachedFunction; + } + const parsedFunction = PDFFunction.parseArray({ + xref: this.xref, + isEvalSupported: this.isEvalSupported, + fnObj: fnObj instanceof _primitives.Ref ? this.xref.fetch(fnObj) : fnObj + }); + this._cache(fnObj, parsedFunction); + return parsedFunction; + } + getCached(cacheKey) { + let fnRef; + if (cacheKey instanceof _primitives.Ref) { + fnRef = cacheKey; + } else if (cacheKey instanceof _primitives.Dict) { + fnRef = cacheKey.objId; + } else if (cacheKey instanceof _base_stream.BaseStream) { + fnRef = cacheKey.dict?.objId; + } + if (fnRef) { + const localFunction = this._localFunctionCache.getByRef(fnRef); + if (localFunction) { + return localFunction; + } + } + return null; + } + _cache(cacheKey, parsedFunction) { + if (!parsedFunction) { + throw new Error('PDFFunctionFactory._cache - expected "parsedFunction" argument.'); + } + let fnRef; + if (cacheKey instanceof _primitives.Ref) { + fnRef = cacheKey; + } else if (cacheKey instanceof _primitives.Dict) { + fnRef = cacheKey.objId; + } else if (cacheKey instanceof _base_stream.BaseStream) { + fnRef = cacheKey.dict?.objId; + } + if (fnRef) { + this._localFunctionCache.set(null, fnRef, parsedFunction); + } + } + get _localFunctionCache() { + return (0, _util.shadow)(this, "_localFunctionCache", new _image_utils.LocalFunctionCache()); + } +} +exports.PDFFunctionFactory = PDFFunctionFactory; +function toNumberArray(arr) { + if (!Array.isArray(arr)) { + return null; + } + const length = arr.length; + for (let i = 0; i < length; i++) { + if (typeof arr[i] !== "number") { + const result = new Array(length); + for (let j = 0; j < length; j++) { + result[j] = +arr[j]; + } + return result; + } + } + return arr; +} +class PDFFunction { + static getSampleArray(size, outputSize, bps, stream) { + let i, ii; + let length = 1; + for (i = 0, ii = size.length; i < ii; i++) { + length *= size[i]; + } + length *= outputSize; + const array = new Array(length); + let codeSize = 0; + let codeBuf = 0; + const sampleMul = 1.0 / (2.0 ** bps - 1); + const strBytes = stream.getBytes((length * bps + 7) / 8); + let strIdx = 0; + for (i = 0; i < length; i++) { + while (codeSize < bps) { + codeBuf <<= 8; + codeBuf |= strBytes[strIdx++]; + codeSize += 8; + } + codeSize -= bps; + array[i] = (codeBuf >> codeSize) * sampleMul; + codeBuf &= (1 << codeSize) - 1; + } + return array; + } + static parse({ + xref, + isEvalSupported, + fn + }) { + const dict = fn.dict || fn; + const typeNum = dict.get("FunctionType"); + switch (typeNum) { + case 0: + return this.constructSampled({ + xref, + isEvalSupported, + fn, + dict + }); + case 1: + break; + case 2: + return this.constructInterpolated({ + xref, + isEvalSupported, + dict + }); + case 3: + return this.constructStiched({ + xref, + isEvalSupported, + dict + }); + case 4: + return this.constructPostScript({ + xref, + isEvalSupported, + fn, + dict + }); + } + throw new _util.FormatError("Unknown type of function"); + } + static parseArray({ + xref, + isEvalSupported, + fnObj + }) { + if (!Array.isArray(fnObj)) { + return this.parse({ + xref, + isEvalSupported, + fn: fnObj + }); + } + const fnArray = []; + for (const fn of fnObj) { + fnArray.push(this.parse({ + xref, + isEvalSupported, + fn: xref.fetchIfRef(fn) + })); + } + return function (src, srcOffset, dest, destOffset) { + for (let i = 0, ii = fnArray.length; i < ii; i++) { + fnArray[i](src, srcOffset, dest, destOffset + i); + } + }; + } + static constructSampled({ + xref, + isEvalSupported, + fn, + dict + }) { + function toMultiArray(arr) { + const inputLength = arr.length; + const out = []; + let index = 0; + for (let i = 0; i < inputLength; i += 2) { + out[index++] = [arr[i], arr[i + 1]]; + } + return out; + } + function interpolate(x, xmin, xmax, ymin, ymax) { + return ymin + (x - xmin) * ((ymax - ymin) / (xmax - xmin)); + } + let domain = toNumberArray(dict.getArray("Domain")); + let range = toNumberArray(dict.getArray("Range")); + if (!domain || !range) { + throw new _util.FormatError("No domain or range"); + } + const inputSize = domain.length / 2; + const outputSize = range.length / 2; + domain = toMultiArray(domain); + range = toMultiArray(range); + const size = toNumberArray(dict.getArray("Size")); + const bps = dict.get("BitsPerSample"); + const order = dict.get("Order") || 1; + if (order !== 1) { + (0, _util.info)("No support for cubic spline interpolation: " + order); + } + let encode = toNumberArray(dict.getArray("Encode")); + if (!encode) { + encode = []; + for (let i = 0; i < inputSize; ++i) { + encode.push([0, size[i] - 1]); + } + } else { + encode = toMultiArray(encode); + } + let decode = toNumberArray(dict.getArray("Decode")); + decode = !decode ? range : toMultiArray(decode); + const samples = this.getSampleArray(size, outputSize, bps, fn); + return function constructSampledFn(src, srcOffset, dest, destOffset) { + const cubeVertices = 1 << inputSize; + const cubeN = new Float64Array(cubeVertices); + const cubeVertex = new Uint32Array(cubeVertices); + let i, j; + for (j = 0; j < cubeVertices; j++) { + cubeN[j] = 1; + } + let k = outputSize, + pos = 1; + for (i = 0; i < inputSize; ++i) { + const domain_2i = domain[i][0]; + const domain_2i_1 = domain[i][1]; + const xi = Math.min(Math.max(src[srcOffset + i], domain_2i), domain_2i_1); + let e = interpolate(xi, domain_2i, domain_2i_1, encode[i][0], encode[i][1]); + const size_i = size[i]; + e = Math.min(Math.max(e, 0), size_i - 1); + const e0 = e < size_i - 1 ? Math.floor(e) : e - 1; + const n0 = e0 + 1 - e; + const n1 = e - e0; + const offset0 = e0 * k; + const offset1 = offset0 + k; + for (j = 0; j < cubeVertices; j++) { + if (j & pos) { + cubeN[j] *= n1; + cubeVertex[j] += offset1; + } else { + cubeN[j] *= n0; + cubeVertex[j] += offset0; + } + } + k *= size_i; + pos <<= 1; + } + for (j = 0; j < outputSize; ++j) { + let rj = 0; + for (i = 0; i < cubeVertices; i++) { + rj += samples[cubeVertex[i] + j] * cubeN[i]; + } + rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]); + dest[destOffset + j] = Math.min(Math.max(rj, range[j][0]), range[j][1]); + } + }; + } + static constructInterpolated({ + xref, + isEvalSupported, + dict + }) { + const c0 = toNumberArray(dict.getArray("C0")) || [0]; + const c1 = toNumberArray(dict.getArray("C1")) || [1]; + const n = dict.get("N"); + const diff = []; + for (let i = 0, ii = c0.length; i < ii; ++i) { + diff.push(c1[i] - c0[i]); + } + const length = diff.length; + return function constructInterpolatedFn(src, srcOffset, dest, destOffset) { + const x = n === 1 ? src[srcOffset] : src[srcOffset] ** n; + for (let j = 0; j < length; ++j) { + dest[destOffset + j] = c0[j] + x * diff[j]; + } + }; + } + static constructStiched({ + xref, + isEvalSupported, + dict + }) { + const domain = toNumberArray(dict.getArray("Domain")); + if (!domain) { + throw new _util.FormatError("No domain"); + } + const inputSize = domain.length / 2; + if (inputSize !== 1) { + throw new _util.FormatError("Bad domain for stiched function"); + } + const fns = []; + for (const fn of dict.get("Functions")) { + fns.push(this.parse({ + xref, + isEvalSupported, + fn: xref.fetchIfRef(fn) + })); + } + const bounds = toNumberArray(dict.getArray("Bounds")); + const encode = toNumberArray(dict.getArray("Encode")); + const tmpBuf = new Float32Array(1); + return function constructStichedFn(src, srcOffset, dest, destOffset) { + const clip = function constructStichedFromIRClip(v, min, max) { + if (v > max) { + v = max; + } else if (v < min) { + v = min; + } + return v; + }; + const v = clip(src[srcOffset], domain[0], domain[1]); + const length = bounds.length; + let i; + for (i = 0; i < length; ++i) { + if (v < bounds[i]) { + break; + } + } + let dmin = domain[0]; + if (i > 0) { + dmin = bounds[i - 1]; + } + let dmax = domain[1]; + if (i < bounds.length) { + dmax = bounds[i]; + } + const rmin = encode[2 * i]; + const rmax = encode[2 * i + 1]; + tmpBuf[0] = dmin === dmax ? rmin : rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin); + fns[i](tmpBuf, 0, dest, destOffset); + }; + } + static constructPostScript({ + xref, + isEvalSupported, + fn, + dict + }) { + const domain = toNumberArray(dict.getArray("Domain")); + const range = toNumberArray(dict.getArray("Range")); + if (!domain) { + throw new _util.FormatError("No domain."); + } + if (!range) { + throw new _util.FormatError("No range."); + } + const lexer = new _ps_parser.PostScriptLexer(fn); + const parser = new _ps_parser.PostScriptParser(lexer); + const code = parser.parse(); + if (isEvalSupported && _util.FeatureTest.isEvalSupported) { + const compiled = new PostScriptCompiler().compile(code, domain, range); + if (compiled) { + return new Function("src", "srcOffset", "dest", "destOffset", compiled); + } + } + (0, _util.info)("Unable to compile PS function"); + const numOutputs = range.length >> 1; + const numInputs = domain.length >> 1; + const evaluator = new PostScriptEvaluator(code); + const cache = Object.create(null); + const MAX_CACHE_SIZE = 2048 * 4; + let cache_available = MAX_CACHE_SIZE; + const tmpBuf = new Float32Array(numInputs); + return function constructPostScriptFn(src, srcOffset, dest, destOffset) { + let i, value; + let key = ""; + const input = tmpBuf; + for (i = 0; i < numInputs; i++) { + value = src[srcOffset + i]; + input[i] = value; + key += value + "_"; + } + const cachedValue = cache[key]; + if (cachedValue !== undefined) { + dest.set(cachedValue, destOffset); + return; + } + const output = new Float32Array(numOutputs); + const stack = evaluator.execute(input); + const stackIndex = stack.length - numOutputs; + for (i = 0; i < numOutputs; i++) { + value = stack[stackIndex + i]; + let bound = range[i * 2]; + if (value < bound) { + value = bound; + } else { + bound = range[i * 2 + 1]; + if (value > bound) { + value = bound; + } + } + output[i] = value; + } + if (cache_available > 0) { + cache_available--; + cache[key] = output; + } + dest.set(output, destOffset); + }; + } +} +function isPDFFunction(v) { + let fnDict; + if (v instanceof _primitives.Dict) { + fnDict = v; + } else if (v instanceof _base_stream.BaseStream) { + fnDict = v.dict; + } else { + return false; + } + return fnDict.has("FunctionType"); +} +class PostScriptStack { + static MAX_STACK_SIZE = 100; + constructor(initialStack) { + this.stack = initialStack ? Array.from(initialStack) : []; + } + push(value) { + if (this.stack.length >= PostScriptStack.MAX_STACK_SIZE) { + throw new Error("PostScript function stack overflow."); + } + this.stack.push(value); + } + pop() { + if (this.stack.length <= 0) { + throw new Error("PostScript function stack underflow."); + } + return this.stack.pop(); + } + copy(n) { + if (this.stack.length + n >= PostScriptStack.MAX_STACK_SIZE) { + throw new Error("PostScript function stack overflow."); + } + const stack = this.stack; + for (let i = stack.length - n, j = n - 1; j >= 0; j--, i++) { + stack.push(stack[i]); + } + } + index(n) { + this.push(this.stack[this.stack.length - n - 1]); + } + roll(n, p) { + const stack = this.stack; + const l = stack.length - n; + const r = stack.length - 1; + const c = l + (p - Math.floor(p / n) * n); + for (let i = l, j = r; i < j; i++, j--) { + const t = stack[i]; + stack[i] = stack[j]; + stack[j] = t; + } + for (let i = l, j = c - 1; i < j; i++, j--) { + const t = stack[i]; + stack[i] = stack[j]; + stack[j] = t; + } + for (let i = c, j = r; i < j; i++, j--) { + const t = stack[i]; + stack[i] = stack[j]; + stack[j] = t; + } + } +} +class PostScriptEvaluator { + constructor(operators) { + this.operators = operators; + } + execute(initialStack) { + const stack = new PostScriptStack(initialStack); + let counter = 0; + const operators = this.operators; + const length = operators.length; + let operator, a, b; + while (counter < length) { + operator = operators[counter++]; + if (typeof operator === "number") { + stack.push(operator); + continue; + } + switch (operator) { + case "jz": + b = stack.pop(); + a = stack.pop(); + if (!a) { + counter = b; + } + break; + case "j": + a = stack.pop(); + counter = a; + break; + case "abs": + a = stack.pop(); + stack.push(Math.abs(a)); + break; + case "add": + b = stack.pop(); + a = stack.pop(); + stack.push(a + b); + break; + case "and": + b = stack.pop(); + a = stack.pop(); + if (typeof a === "boolean" && typeof b === "boolean") { + stack.push(a && b); + } else { + stack.push(a & b); + } + break; + case "atan": + b = stack.pop(); + a = stack.pop(); + a = Math.atan2(a, b) / Math.PI * 180; + if (a < 0) { + a += 360; + } + stack.push(a); + break; + case "bitshift": + b = stack.pop(); + a = stack.pop(); + if (a > 0) { + stack.push(a << b); + } else { + stack.push(a >> b); + } + break; + case "ceiling": + a = stack.pop(); + stack.push(Math.ceil(a)); + break; + case "copy": + a = stack.pop(); + stack.copy(a); + break; + case "cos": + a = stack.pop(); + stack.push(Math.cos(a % 360 / 180 * Math.PI)); + break; + case "cvi": + a = stack.pop() | 0; + stack.push(a); + break; + case "cvr": + break; + case "div": + b = stack.pop(); + a = stack.pop(); + stack.push(a / b); + break; + case "dup": + stack.copy(1); + break; + case "eq": + b = stack.pop(); + a = stack.pop(); + stack.push(a === b); + break; + case "exch": + stack.roll(2, 1); + break; + case "exp": + b = stack.pop(); + a = stack.pop(); + stack.push(a ** b); + break; + case "false": + stack.push(false); + break; + case "floor": + a = stack.pop(); + stack.push(Math.floor(a)); + break; + case "ge": + b = stack.pop(); + a = stack.pop(); + stack.push(a >= b); + break; + case "gt": + b = stack.pop(); + a = stack.pop(); + stack.push(a > b); + break; + case "idiv": + b = stack.pop(); + a = stack.pop(); + stack.push(a / b | 0); + break; + case "index": + a = stack.pop(); + stack.index(a); + break; + case "le": + b = stack.pop(); + a = stack.pop(); + stack.push(a <= b); + break; + case "ln": + a = stack.pop(); + stack.push(Math.log(a)); + break; + case "log": + a = stack.pop(); + stack.push(Math.log10(a)); + break; + case "lt": + b = stack.pop(); + a = stack.pop(); + stack.push(a < b); + break; + case "mod": + b = stack.pop(); + a = stack.pop(); + stack.push(a % b); + break; + case "mul": + b = stack.pop(); + a = stack.pop(); + stack.push(a * b); + break; + case "ne": + b = stack.pop(); + a = stack.pop(); + stack.push(a !== b); + break; + case "neg": + a = stack.pop(); + stack.push(-a); + break; + case "not": + a = stack.pop(); + if (typeof a === "boolean") { + stack.push(!a); + } else { + stack.push(~a); + } + break; + case "or": + b = stack.pop(); + a = stack.pop(); + if (typeof a === "boolean" && typeof b === "boolean") { + stack.push(a || b); + } else { + stack.push(a | b); + } + break; + case "pop": + stack.pop(); + break; + case "roll": + b = stack.pop(); + a = stack.pop(); + stack.roll(a, b); + break; + case "round": + a = stack.pop(); + stack.push(Math.round(a)); + break; + case "sin": + a = stack.pop(); + stack.push(Math.sin(a % 360 / 180 * Math.PI)); + break; + case "sqrt": + a = stack.pop(); + stack.push(Math.sqrt(a)); + break; + case "sub": + b = stack.pop(); + a = stack.pop(); + stack.push(a - b); + break; + case "true": + stack.push(true); + break; + case "truncate": + a = stack.pop(); + a = a < 0 ? Math.ceil(a) : Math.floor(a); + stack.push(a); + break; + case "xor": + b = stack.pop(); + a = stack.pop(); + if (typeof a === "boolean" && typeof b === "boolean") { + stack.push(a !== b); + } else { + stack.push(a ^ b); + } + break; + default: + throw new _util.FormatError(`Unknown operator ${operator}`); + } + } + return stack.stack; + } +} +exports.PostScriptEvaluator = PostScriptEvaluator; +class AstNode { + constructor(type) { + this.type = type; + } + visit(visitor) { + (0, _util.unreachable)("abstract method"); + } +} +class AstArgument extends AstNode { + constructor(index, min, max) { + super("args"); + this.index = index; + this.min = min; + this.max = max; + } + visit(visitor) { + visitor.visitArgument(this); + } +} +class AstLiteral extends AstNode { + constructor(number) { + super("literal"); + this.number = number; + this.min = number; + this.max = number; + } + visit(visitor) { + visitor.visitLiteral(this); + } +} +class AstBinaryOperation extends AstNode { + constructor(op, arg1, arg2, min, max) { + super("binary"); + this.op = op; + this.arg1 = arg1; + this.arg2 = arg2; + this.min = min; + this.max = max; + } + visit(visitor) { + visitor.visitBinaryOperation(this); + } +} +class AstMin extends AstNode { + constructor(arg, max) { + super("max"); + this.arg = arg; + this.min = arg.min; + this.max = max; + } + visit(visitor) { + visitor.visitMin(this); + } +} +class AstVariable extends AstNode { + constructor(index, min, max) { + super("var"); + this.index = index; + this.min = min; + this.max = max; + } + visit(visitor) { + visitor.visitVariable(this); + } +} +class AstVariableDefinition extends AstNode { + constructor(variable, arg) { + super("definition"); + this.variable = variable; + this.arg = arg; + } + visit(visitor) { + visitor.visitVariableDefinition(this); + } +} +class ExpressionBuilderVisitor { + constructor() { + this.parts = []; + } + visitArgument(arg) { + this.parts.push("Math.max(", arg.min, ", Math.min(", arg.max, ", src[srcOffset + ", arg.index, "]))"); + } + visitVariable(variable) { + this.parts.push("v", variable.index); + } + visitLiteral(literal) { + this.parts.push(literal.number); + } + visitBinaryOperation(operation) { + this.parts.push("("); + operation.arg1.visit(this); + this.parts.push(" ", operation.op, " "); + operation.arg2.visit(this); + this.parts.push(")"); + } + visitVariableDefinition(definition) { + this.parts.push("var "); + definition.variable.visit(this); + this.parts.push(" = "); + definition.arg.visit(this); + this.parts.push(";"); + } + visitMin(max) { + this.parts.push("Math.min("); + max.arg.visit(this); + this.parts.push(", ", max.max, ")"); + } + toString() { + return this.parts.join(""); + } +} +function buildAddOperation(num1, num2) { + if (num2.type === "literal" && num2.number === 0) { + return num1; + } + if (num1.type === "literal" && num1.number === 0) { + return num2; + } + if (num2.type === "literal" && num1.type === "literal") { + return new AstLiteral(num1.number + num2.number); + } + return new AstBinaryOperation("+", num1, num2, num1.min + num2.min, num1.max + num2.max); +} +function buildMulOperation(num1, num2) { + if (num2.type === "literal") { + if (num2.number === 0) { + return new AstLiteral(0); + } else if (num2.number === 1) { + return num1; + } else if (num1.type === "literal") { + return new AstLiteral(num1.number * num2.number); + } + } + if (num1.type === "literal") { + if (num1.number === 0) { + return new AstLiteral(0); + } else if (num1.number === 1) { + return num2; + } + } + const min = Math.min(num1.min * num2.min, num1.min * num2.max, num1.max * num2.min, num1.max * num2.max); + const max = Math.max(num1.min * num2.min, num1.min * num2.max, num1.max * num2.min, num1.max * num2.max); + return new AstBinaryOperation("*", num1, num2, min, max); +} +function buildSubOperation(num1, num2) { + if (num2.type === "literal") { + if (num2.number === 0) { + return num1; + } else if (num1.type === "literal") { + return new AstLiteral(num1.number - num2.number); + } + } + if (num2.type === "binary" && num2.op === "-" && num1.type === "literal" && num1.number === 1 && num2.arg1.type === "literal" && num2.arg1.number === 1) { + return num2.arg2; + } + return new AstBinaryOperation("-", num1, num2, num1.min - num2.max, num1.max - num2.min); +} +function buildMinOperation(num1, max) { + if (num1.min >= max) { + return new AstLiteral(max); + } else if (num1.max <= max) { + return num1; + } + return new AstMin(num1, max); +} +class PostScriptCompiler { + compile(code, domain, range) { + const stack = []; + const instructions = []; + const inputSize = domain.length >> 1, + outputSize = range.length >> 1; + let lastRegister = 0; + let n, j; + let num1, num2, ast1, ast2, tmpVar, item; + for (let i = 0; i < inputSize; i++) { + stack.push(new AstArgument(i, domain[i * 2], domain[i * 2 + 1])); + } + for (let i = 0, ii = code.length; i < ii; i++) { + item = code[i]; + if (typeof item === "number") { + stack.push(new AstLiteral(item)); + continue; + } + switch (item) { + case "add": + if (stack.length < 2) { + return null; + } + num2 = stack.pop(); + num1 = stack.pop(); + stack.push(buildAddOperation(num1, num2)); + break; + case "cvr": + if (stack.length < 1) { + return null; + } + break; + case "mul": + if (stack.length < 2) { + return null; + } + num2 = stack.pop(); + num1 = stack.pop(); + stack.push(buildMulOperation(num1, num2)); + break; + case "sub": + if (stack.length < 2) { + return null; + } + num2 = stack.pop(); + num1 = stack.pop(); + stack.push(buildSubOperation(num1, num2)); + break; + case "exch": + if (stack.length < 2) { + return null; + } + ast1 = stack.pop(); + ast2 = stack.pop(); + stack.push(ast1, ast2); + break; + case "pop": + if (stack.length < 1) { + return null; + } + stack.pop(); + break; + case "index": + if (stack.length < 1) { + return null; + } + num1 = stack.pop(); + if (num1.type !== "literal") { + return null; + } + n = num1.number; + if (n < 0 || !Number.isInteger(n) || stack.length < n) { + return null; + } + ast1 = stack[stack.length - n - 1]; + if (ast1.type === "literal" || ast1.type === "var") { + stack.push(ast1); + break; + } + tmpVar = new AstVariable(lastRegister++, ast1.min, ast1.max); + stack[stack.length - n - 1] = tmpVar; + stack.push(tmpVar); + instructions.push(new AstVariableDefinition(tmpVar, ast1)); + break; + case "dup": + if (stack.length < 1) { + return null; + } + if (typeof code[i + 1] === "number" && code[i + 2] === "gt" && code[i + 3] === i + 7 && code[i + 4] === "jz" && code[i + 5] === "pop" && code[i + 6] === code[i + 1]) { + num1 = stack.pop(); + stack.push(buildMinOperation(num1, code[i + 1])); + i += 6; + break; + } + ast1 = stack.at(-1); + if (ast1.type === "literal" || ast1.type === "var") { + stack.push(ast1); + break; + } + tmpVar = new AstVariable(lastRegister++, ast1.min, ast1.max); + stack[stack.length - 1] = tmpVar; + stack.push(tmpVar); + instructions.push(new AstVariableDefinition(tmpVar, ast1)); + break; + case "roll": + if (stack.length < 2) { + return null; + } + num2 = stack.pop(); + num1 = stack.pop(); + if (num2.type !== "literal" || num1.type !== "literal") { + return null; + } + j = num2.number; + n = num1.number; + if (n <= 0 || !Number.isInteger(n) || !Number.isInteger(j) || stack.length < n) { + return null; + } + j = (j % n + n) % n; + if (j === 0) { + break; + } + stack.push(...stack.splice(stack.length - n, n - j)); + break; + default: + return null; + } + } + if (stack.length !== outputSize) { + return null; + } + const result = []; + for (const instruction of instructions) { + const statementBuilder = new ExpressionBuilderVisitor(); + instruction.visit(statementBuilder); + result.push(statementBuilder.toString()); + } + for (let i = 0, ii = stack.length; i < ii; i++) { + const expr = stack[i], + statementBuilder = new ExpressionBuilderVisitor(); + expr.visit(statementBuilder); + const min = range[i * 2], + max = range[i * 2 + 1]; + const out = [statementBuilder.toString()]; + if (min > expr.min) { + out.unshift("Math.max(", min, ", "); + out.push(")"); + } + if (max < expr.max) { + out.unshift("Math.min(", max, ", "); + out.push(")"); + } + out.unshift("dest[destOffset + ", i, "] = "); + out.push(";"); + result.push(out.join("")); + } + return result.join("\n"); + } +} +exports.PostScriptCompiler = PostScriptCompiler; + +/***/ }), +/* 58 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.PostScriptParser = exports.PostScriptLexer = void 0; +var _util = __w_pdfjs_require__(2); +var _primitives = __w_pdfjs_require__(4); +var _core_utils = __w_pdfjs_require__(3); +class PostScriptParser { + constructor(lexer) { + this.lexer = lexer; + this.operators = []; + this.token = null; + this.prev = null; + } + nextToken() { + this.prev = this.token; + this.token = this.lexer.getToken(); + } + accept(type) { + if (this.token.type === type) { + this.nextToken(); + return true; + } + return false; + } + expect(type) { + if (this.accept(type)) { + return true; + } + throw new _util.FormatError(`Unexpected symbol: found ${this.token.type} expected ${type}.`); + } + parse() { + this.nextToken(); + this.expect(PostScriptTokenTypes.LBRACE); + this.parseBlock(); + this.expect(PostScriptTokenTypes.RBRACE); + return this.operators; + } + parseBlock() { + while (true) { + if (this.accept(PostScriptTokenTypes.NUMBER)) { + this.operators.push(this.prev.value); + } else if (this.accept(PostScriptTokenTypes.OPERATOR)) { + this.operators.push(this.prev.value); + } else if (this.accept(PostScriptTokenTypes.LBRACE)) { + this.parseCondition(); + } else { + return; + } + } + } + parseCondition() { + const conditionLocation = this.operators.length; + this.operators.push(null, null); + this.parseBlock(); + this.expect(PostScriptTokenTypes.RBRACE); + if (this.accept(PostScriptTokenTypes.IF)) { + this.operators[conditionLocation] = this.operators.length; + this.operators[conditionLocation + 1] = "jz"; + } else if (this.accept(PostScriptTokenTypes.LBRACE)) { + const jumpLocation = this.operators.length; + this.operators.push(null, null); + const endOfTrue = this.operators.length; + this.parseBlock(); + this.expect(PostScriptTokenTypes.RBRACE); + this.expect(PostScriptTokenTypes.IFELSE); + this.operators[jumpLocation] = this.operators.length; + this.operators[jumpLocation + 1] = "j"; + this.operators[conditionLocation] = endOfTrue; + this.operators[conditionLocation + 1] = "jz"; + } else { + throw new _util.FormatError("PS Function: error parsing conditional."); + } + } +} +exports.PostScriptParser = PostScriptParser; +const PostScriptTokenTypes = { + LBRACE: 0, + RBRACE: 1, + NUMBER: 2, + OPERATOR: 3, + IF: 4, + IFELSE: 5 +}; +class PostScriptToken { + static get opCache() { + return (0, _util.shadow)(this, "opCache", Object.create(null)); + } + constructor(type, value) { + this.type = type; + this.value = value; + } + static getOperator(op) { + return PostScriptToken.opCache[op] ||= new PostScriptToken(PostScriptTokenTypes.OPERATOR, op); + } + static get LBRACE() { + return (0, _util.shadow)(this, "LBRACE", new PostScriptToken(PostScriptTokenTypes.LBRACE, "{")); + } + static get RBRACE() { + return (0, _util.shadow)(this, "RBRACE", new PostScriptToken(PostScriptTokenTypes.RBRACE, "}")); + } + static get IF() { + return (0, _util.shadow)(this, "IF", new PostScriptToken(PostScriptTokenTypes.IF, "IF")); + } + static get IFELSE() { + return (0, _util.shadow)(this, "IFELSE", new PostScriptToken(PostScriptTokenTypes.IFELSE, "IFELSE")); + } +} +class PostScriptLexer { + constructor(stream) { + this.stream = stream; + this.nextChar(); + this.strBuf = []; + } + nextChar() { + return this.currentChar = this.stream.getByte(); + } + getToken() { + let comment = false; + let ch = this.currentChar; + while (true) { + if (ch < 0) { + return _primitives.EOF; + } + if (comment) { + if (ch === 0x0a || ch === 0x0d) { + comment = false; + } + } else if (ch === 0x25) { + comment = true; + } else if (!(0, _core_utils.isWhiteSpace)(ch)) { + break; + } + ch = this.nextChar(); + } + switch (ch | 0) { + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x2b: + case 0x2d: + case 0x2e: + return new PostScriptToken(PostScriptTokenTypes.NUMBER, this.getNumber()); + case 0x7b: + this.nextChar(); + return PostScriptToken.LBRACE; + case 0x7d: + this.nextChar(); + return PostScriptToken.RBRACE; + } + const strBuf = this.strBuf; + strBuf.length = 0; + strBuf[0] = String.fromCharCode(ch); + while ((ch = this.nextChar()) >= 0 && (ch >= 0x41 && ch <= 0x5a || ch >= 0x61 && ch <= 0x7a)) { + strBuf.push(String.fromCharCode(ch)); + } + const str = strBuf.join(""); + switch (str.toLowerCase()) { + case "if": + return PostScriptToken.IF; + case "ifelse": + return PostScriptToken.IFELSE; + default: + return PostScriptToken.getOperator(str); + } + } + getNumber() { + let ch = this.currentChar; + const strBuf = this.strBuf; + strBuf.length = 0; + strBuf[0] = String.fromCharCode(ch); + while ((ch = this.nextChar()) >= 0) { + if (ch >= 0x30 && ch <= 0x39 || ch === 0x2d || ch === 0x2e) { + strBuf.push(String.fromCharCode(ch)); + } else { + break; + } + } + const value = parseFloat(strBuf.join("")); + if (isNaN(value)) { + throw new _util.FormatError(`Invalid floating point number: ${value}`); + } + return value; + } +} +exports.PostScriptLexer = PostScriptLexer; + +/***/ }), +/* 59 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.RegionalImageCache = exports.LocalTilingPatternCache = exports.LocalImageCache = exports.LocalGStateCache = exports.LocalFunctionCache = exports.LocalColorSpaceCache = exports.GlobalImageCache = void 0; +var _util = __w_pdfjs_require__(2); +var _primitives = __w_pdfjs_require__(4); +class BaseLocalCache { + constructor(options) { + if (this.constructor === BaseLocalCache) { + (0, _util.unreachable)("Cannot initialize BaseLocalCache."); + } + this._onlyRefs = options?.onlyRefs === true; + if (!this._onlyRefs) { + this._nameRefMap = new Map(); + this._imageMap = new Map(); + } + this._imageCache = new _primitives.RefSetCache(); + } + getByName(name) { + if (this._onlyRefs) { + (0, _util.unreachable)("Should not call `getByName` method."); + } + const ref = this._nameRefMap.get(name); + if (ref) { + return this.getByRef(ref); + } + return this._imageMap.get(name) || null; + } + getByRef(ref) { + return this._imageCache.get(ref) || null; + } + set(name, ref, data) { + (0, _util.unreachable)("Abstract method `set` called."); + } +} +class LocalImageCache extends BaseLocalCache { + set(name, ref = null, data) { + if (typeof name !== "string") { + throw new Error('LocalImageCache.set - expected "name" argument.'); + } + if (ref) { + if (this._imageCache.has(ref)) { + return; + } + this._nameRefMap.set(name, ref); + this._imageCache.put(ref, data); + return; + } + if (this._imageMap.has(name)) { + return; + } + this._imageMap.set(name, data); + } +} +exports.LocalImageCache = LocalImageCache; +class LocalColorSpaceCache extends BaseLocalCache { + set(name = null, ref = null, data) { + if (typeof name !== "string" && !ref) { + throw new Error('LocalColorSpaceCache.set - expected "name" and/or "ref" argument.'); + } + if (ref) { + if (this._imageCache.has(ref)) { + return; + } + if (name !== null) { + this._nameRefMap.set(name, ref); + } + this._imageCache.put(ref, data); + return; + } + if (this._imageMap.has(name)) { + return; + } + this._imageMap.set(name, data); + } +} +exports.LocalColorSpaceCache = LocalColorSpaceCache; +class LocalFunctionCache extends BaseLocalCache { + constructor(options) { + super({ + onlyRefs: true + }); + } + set(name = null, ref, data) { + if (!ref) { + throw new Error('LocalFunctionCache.set - expected "ref" argument.'); + } + if (this._imageCache.has(ref)) { + return; + } + this._imageCache.put(ref, data); + } +} +exports.LocalFunctionCache = LocalFunctionCache; +class LocalGStateCache extends BaseLocalCache { + set(name, ref = null, data) { + if (typeof name !== "string") { + throw new Error('LocalGStateCache.set - expected "name" argument.'); + } + if (ref) { + if (this._imageCache.has(ref)) { + return; + } + this._nameRefMap.set(name, ref); + this._imageCache.put(ref, data); + return; + } + if (this._imageMap.has(name)) { + return; + } + this._imageMap.set(name, data); + } +} +exports.LocalGStateCache = LocalGStateCache; +class LocalTilingPatternCache extends BaseLocalCache { + constructor(options) { + super({ + onlyRefs: true + }); + } + set(name = null, ref, data) { + if (!ref) { + throw new Error('LocalTilingPatternCache.set - expected "ref" argument.'); + } + if (this._imageCache.has(ref)) { + return; + } + this._imageCache.put(ref, data); + } +} +exports.LocalTilingPatternCache = LocalTilingPatternCache; +class RegionalImageCache extends BaseLocalCache { + constructor(options) { + super({ + onlyRefs: true + }); + } + set(name = null, ref, data) { + if (!ref) { + throw new Error('RegionalImageCache.set - expected "ref" argument.'); + } + if (this._imageCache.has(ref)) { + return; + } + this._imageCache.put(ref, data); + } +} +exports.RegionalImageCache = RegionalImageCache; +class GlobalImageCache { + static NUM_PAGES_THRESHOLD = 2; + static MIN_IMAGES_TO_CACHE = 10; + static MAX_BYTE_SIZE = 5 * _util.MAX_IMAGE_SIZE_TO_CACHE; + constructor() { + this._refCache = new _primitives.RefSetCache(); + this._imageCache = new _primitives.RefSetCache(); + } + get _byteSize() { + let byteSize = 0; + for (const imageData of this._imageCache) { + byteSize += imageData.byteSize; + } + return byteSize; + } + get _cacheLimitReached() { + if (this._imageCache.size < GlobalImageCache.MIN_IMAGES_TO_CACHE) { + return false; + } + if (this._byteSize < GlobalImageCache.MAX_BYTE_SIZE) { + return false; + } + return true; + } + shouldCache(ref, pageIndex) { + let pageIndexSet = this._refCache.get(ref); + if (!pageIndexSet) { + pageIndexSet = new Set(); + this._refCache.put(ref, pageIndexSet); + } + pageIndexSet.add(pageIndex); + if (pageIndexSet.size < GlobalImageCache.NUM_PAGES_THRESHOLD) { + return false; + } + if (!this._imageCache.has(ref) && this._cacheLimitReached) { + return false; + } + return true; + } + addByteSize(ref, byteSize) { + const imageData = this._imageCache.get(ref); + if (!imageData) { + return; + } + if (imageData.byteSize) { + return; + } + imageData.byteSize = byteSize; + } + getData(ref, pageIndex) { + const pageIndexSet = this._refCache.get(ref); + if (!pageIndexSet) { + return null; + } + if (pageIndexSet.size < GlobalImageCache.NUM_PAGES_THRESHOLD) { + return null; + } + const imageData = this._imageCache.get(ref); + if (!imageData) { + return null; + } + pageIndexSet.add(pageIndex); + return imageData; + } + setData(ref, data) { + if (!this._refCache.has(ref)) { + throw new Error('GlobalImageCache.setData - expected "shouldCache" to have been called.'); + } + if (this._imageCache.has(ref)) { + return; + } + if (this._cacheLimitReached) { + (0, _util.warn)("GlobalImageCache.setData - cache limit reached."); + return; + } + this._imageCache.put(ref, data); + } + clear(onlyData = false) { + if (!onlyData) { + this._refCache.clear(); + } + this._imageCache.clear(); + } +} +exports.GlobalImageCache = GlobalImageCache; + +/***/ }), +/* 60 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.bidi = bidi; +var _util = __w_pdfjs_require__(2); +const baseTypes = ["BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "S", "B", "S", "WS", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "B", "B", "B", "S", "WS", "ON", "ON", "ET", "ET", "ET", "ON", "ON", "ON", "ON", "ON", "ES", "CS", "ES", "CS", "CS", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "CS", "ON", "ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "ON", "ON", "ON", "BN", "BN", "BN", "BN", "BN", "BN", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "CS", "ON", "ET", "ET", "ET", "ET", "ON", "ON", "ON", "ON", "L", "ON", "ON", "BN", "ON", "ON", "ET", "ET", "EN", "EN", "ON", "L", "ON", "ON", "ON", "EN", "L", "ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "L", "L", "L", "L", "L", "L", "L", "L"]; +const arabicTypes = ["AN", "AN", "AN", "AN", "AN", "AN", "ON", "ON", "AL", "ET", "ET", "AL", "CS", "AL", "ON", "ON", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "ET", "AN", "AN", "AL", "AL", "AL", "NSM", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "ON", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "NSM", "NSM", "ON", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "AL", "AL", "AL", "AL", "AL", "AL"]; +function isOdd(i) { + return (i & 1) !== 0; +} +function isEven(i) { + return (i & 1) === 0; +} +function findUnequal(arr, start, value) { + let j, jj; + for (j = start, jj = arr.length; j < jj; ++j) { + if (arr[j] !== value) { + return j; + } + } + return j; +} +function setValues(arr, start, end, value) { + for (let j = start; j < end; ++j) { + arr[j] = value; + } +} +function reverseValues(arr, start, end) { + for (let i = start, j = end - 1; i < j; ++i, --j) { + const temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } +} +function createBidiText(str, isLTR, vertical = false) { + let dir = "ltr"; + if (vertical) { + dir = "ttb"; + } else if (!isLTR) { + dir = "rtl"; + } + return { + str, + dir + }; +} +const chars = []; +const types = []; +function bidi(str, startLevel = -1, vertical = false) { + let isLTR = true; + const strLength = str.length; + if (strLength === 0 || vertical) { + return createBidiText(str, isLTR, vertical); + } + chars.length = strLength; + types.length = strLength; + let numBidi = 0; + let i, ii; + for (i = 0; i < strLength; ++i) { + chars[i] = str.charAt(i); + const charCode = str.charCodeAt(i); + let charType = "L"; + if (charCode <= 0x00ff) { + charType = baseTypes[charCode]; + } else if (0x0590 <= charCode && charCode <= 0x05f4) { + charType = "R"; + } else if (0x0600 <= charCode && charCode <= 0x06ff) { + charType = arabicTypes[charCode & 0xff]; + if (!charType) { + (0, _util.warn)("Bidi: invalid Unicode character " + charCode.toString(16)); + } + } else if (0x0700 <= charCode && charCode <= 0x08ac || 0xfb50 <= charCode && charCode <= 0xfdff || 0xfe70 <= charCode && charCode <= 0xfeff) { + charType = "AL"; + } + if (charType === "R" || charType === "AL" || charType === "AN") { + numBidi++; + } + types[i] = charType; + } + if (numBidi === 0) { + isLTR = true; + return createBidiText(str, isLTR); + } + if (startLevel === -1) { + if (numBidi / strLength < 0.3 && strLength > 4) { + isLTR = true; + startLevel = 0; + } else { + isLTR = false; + startLevel = 1; + } + } + const levels = []; + for (i = 0; i < strLength; ++i) { + levels[i] = startLevel; + } + const e = isOdd(startLevel) ? "R" : "L"; + const sor = e; + const eor = sor; + let lastType = sor; + for (i = 0; i < strLength; ++i) { + if (types[i] === "NSM") { + types[i] = lastType; + } else { + lastType = types[i]; + } + } + lastType = sor; + let t; + for (i = 0; i < strLength; ++i) { + t = types[i]; + if (t === "EN") { + types[i] = lastType === "AL" ? "AN" : "EN"; + } else if (t === "R" || t === "L" || t === "AL") { + lastType = t; + } + } + for (i = 0; i < strLength; ++i) { + t = types[i]; + if (t === "AL") { + types[i] = "R"; + } + } + for (i = 1; i < strLength - 1; ++i) { + if (types[i] === "ES" && types[i - 1] === "EN" && types[i + 1] === "EN") { + types[i] = "EN"; + } + if (types[i] === "CS" && (types[i - 1] === "EN" || types[i - 1] === "AN") && types[i + 1] === types[i - 1]) { + types[i] = types[i - 1]; + } + } + for (i = 0; i < strLength; ++i) { + if (types[i] === "EN") { + for (let j = i - 1; j >= 0; --j) { + if (types[j] !== "ET") { + break; + } + types[j] = "EN"; + } + for (let j = i + 1; j < strLength; ++j) { + if (types[j] !== "ET") { + break; + } + types[j] = "EN"; + } + } + } + for (i = 0; i < strLength; ++i) { + t = types[i]; + if (t === "WS" || t === "ES" || t === "ET" || t === "CS") { + types[i] = "ON"; + } + } + lastType = sor; + for (i = 0; i < strLength; ++i) { + t = types[i]; + if (t === "EN") { + types[i] = lastType === "L" ? "L" : "EN"; + } else if (t === "R" || t === "L") { + lastType = t; + } + } + for (i = 0; i < strLength; ++i) { + if (types[i] === "ON") { + const end = findUnequal(types, i + 1, "ON"); + let before = sor; + if (i > 0) { + before = types[i - 1]; + } + let after = eor; + if (end + 1 < strLength) { + after = types[end + 1]; + } + if (before !== "L") { + before = "R"; + } + if (after !== "L") { + after = "R"; + } + if (before === after) { + setValues(types, i, end, before); + } + i = end - 1; + } + } + for (i = 0; i < strLength; ++i) { + if (types[i] === "ON") { + types[i] = e; + } + } + for (i = 0; i < strLength; ++i) { + t = types[i]; + if (isEven(levels[i])) { + if (t === "R") { + levels[i] += 1; + } else if (t === "AN" || t === "EN") { + levels[i] += 2; + } + } else if (t === "L" || t === "AN" || t === "EN") { + levels[i] += 1; + } + } + let highestLevel = -1; + let lowestOddLevel = 99; + let level; + for (i = 0, ii = levels.length; i < ii; ++i) { + level = levels[i]; + if (highestLevel < level) { + highestLevel = level; + } + if (lowestOddLevel > level && isOdd(level)) { + lowestOddLevel = level; + } + } + for (level = highestLevel; level >= lowestOddLevel; --level) { + let start = -1; + for (i = 0, ii = levels.length; i < ii; ++i) { + if (levels[i] < level) { + if (start >= 0) { + reverseValues(chars, start, i); + start = -1; + } + } else if (start < 0) { + start = i; + } + } + if (start >= 0) { + reverseValues(chars, start, levels.length); + } + } + for (i = 0, ii = chars.length; i < ii; ++i) { + const ch = chars[i]; + if (ch === "<" || ch === ">") { + chars[i] = ""; + } + } + return createBidiText(chars.join(""), isLTR); +} + +/***/ }), +/* 61 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getFontSubstitution = getFontSubstitution; +var _fonts_utils = __w_pdfjs_require__(38); +var _core_utils = __w_pdfjs_require__(3); +const NORMAL = { + style: "normal", + weight: "normal" +}; +const BOLD = { + style: "normal", + weight: "bold" +}; +const ITALIC = { + style: "italic", + weight: "normal" +}; +const BOLDITALIC = { + style: "italic", + weight: "bold" +}; +const substitutionMap = new Map([["Times-Roman", { + local: ["Times New Roman", "Times-Roman", "Times", "Liberation Serif", "Nimbus Roman", "Nimbus Roman L", "Tinos", "Thorndale", "TeX Gyre Termes", "FreeSerif", "DejaVu Serif", "Bitstream Vera Serif", "Ubuntu"], + style: NORMAL, + ultimate: "serif" +}], ["Times-Bold", { + alias: "Times-Roman", + style: BOLD, + ultimate: "serif" +}], ["Times-Italic", { + alias: "Times-Roman", + style: ITALIC, + ultimate: "serif" +}], ["Times-BoldItalic", { + alias: "Times-Roman", + style: BOLDITALIC, + ultimate: "serif" +}], ["Helvetica", { + local: ["Helvetica", "Helvetica Neue", "Arial", "Arial Nova", "Liberation Sans", "Arimo", "Nimbus Sans", "Nimbus Sans L", "A030", "TeX Gyre Heros", "FreeSans", "DejaVu Sans", "Albany", "Bitstream Vera Sans", "Arial Unicode MS", "Microsoft Sans Serif", "Apple Symbols", "Cantarell"], + path: "LiberationSans-Regular.ttf", + style: NORMAL, + ultimate: "sans-serif" +}], ["Helvetica-Bold", { + alias: "Helvetica", + path: "LiberationSans-Bold.ttf", + style: BOLD, + ultimate: "sans-serif" +}], ["Helvetica-Oblique", { + alias: "Helvetica", + path: "LiberationSans-Italic.ttf", + style: ITALIC, + ultimate: "sans-serif" +}], ["Helvetica-BoldOblique", { + alias: "Helvetica", + path: "LiberationSans-BoldItalic.ttf", + style: BOLDITALIC, + ultimate: "sans-serif" +}], ["Courier", { + local: ["Courier", "Courier New", "Liberation Mono", "Nimbus Mono", "Nimbus Mono L", "Cousine", "Cumberland", "TeX Gyre Cursor", "FreeMono"], + style: NORMAL, + ultimate: "monospace" +}], ["Courier-Bold", { + alias: "Courier", + style: BOLD, + ultimate: "monospace" +}], ["Courier-Oblique", { + alias: "Courier", + style: ITALIC, + ultimate: "monospace" +}], ["Courier-BoldOblique", { + alias: "Courier", + style: BOLDITALIC, + ultimate: "monospace" +}], ["ArialBlack", { + local: ["Arial Black"], + style: { + style: "normal", + weight: "900" + }, + fallback: "Helvetica-Bold" +}], ["ArialBlack-Bold", { + alias: "ArialBlack" +}], ["ArialBlack-Italic", { + alias: "ArialBlack", + style: { + style: "italic", + weight: "900" + }, + fallback: "Helvetica-BoldOblique" +}], ["ArialBlack-BoldItalic", { + alias: "ArialBlack-Italic" +}], ["ArialNarrow", { + local: ["Arial Narrow", "Liberation Sans Narrow", "Helvetica Condensed", "Nimbus Sans Narrow", "TeX Gyre Heros Cn"], + style: NORMAL, + fallback: "Helvetica" +}], ["ArialNarrow-Bold", { + alias: "ArialNarrow", + style: BOLD, + fallback: "Helvetica-Bold" +}], ["ArialNarrow-Italic", { + alias: "ArialNarrow", + style: ITALIC, + fallback: "Helvetica-Oblique" +}], ["ArialNarrow-BoldItalic", { + alias: "ArialNarrow", + style: BOLDITALIC, + fallback: "Helvetica-BoldOblique" +}], ["Calibri", { + local: ["Calibri", "Carlito"], + style: NORMAL, + fallback: "Helvetica" +}], ["Calibri-Bold", { + alias: "Calibri", + style: BOLD, + fallback: "Helvetica-Bold" +}], ["Calibri-Italic", { + alias: "Calibri", + style: ITALIC, + fallback: "Helvetica-Oblique" +}], ["Calibri-BoldItalic", { + alias: "Calibri", + style: BOLDITALIC, + fallback: "Helvetica-BoldOblique" +}], ["Wingdings", { + local: ["Wingdings", "URW Dingbats"], + style: NORMAL +}], ["Wingdings-Regular", { + alias: "Wingdings" +}], ["Wingdings-Bold", { + alias: "Wingdings" +}]]); +const fontAliases = new Map([["Arial-Black", "ArialBlack"]]); +function getStyleToAppend(style) { + switch (style) { + case BOLD: + return "Bold"; + case ITALIC: + return "Italic"; + case BOLDITALIC: + return "Bold Italic"; + default: + if (style?.weight === "bold") { + return "Bold"; + } + if (style?.style === "italic") { + return "Italic"; + } + } + return ""; +} +function generateFont({ + alias, + local, + path, + fallback, + style, + ultimate +}, src, localFontPath, useFallback = true, usePath = true, append = "") { + const result = { + style: null, + ultimate: null + }; + if (local) { + const extra = append ? ` ${append}` : ""; + for (const name of local) { + src.push(`local(${name}${extra})`); + } + } + if (alias) { + const substitution = substitutionMap.get(alias); + const aliasAppend = append || getStyleToAppend(style); + Object.assign(result, generateFont(substitution, src, localFontPath, useFallback && !fallback, usePath && !path, aliasAppend)); + } + if (style) { + result.style = style; + } + if (ultimate) { + result.ultimate = ultimate; + } + if (useFallback && fallback) { + const fallbackInfo = substitutionMap.get(fallback); + const { + ultimate: fallbackUltimate + } = generateFont(fallbackInfo, src, localFontPath, useFallback, usePath && !path, append); + result.ultimate ||= fallbackUltimate; + } + if (usePath && path && localFontPath) { + src.push(`url(${localFontPath}${path})`); + } + return result; +} +function getFontSubstitution(systemFontCache, idFactory, localFontPath, baseFontName, standardFontName) { + baseFontName = (0, _fonts_utils.normalizeFontName)(baseFontName); + const key = baseFontName; + let substitutionInfo = systemFontCache.get(key); + if (substitutionInfo) { + return substitutionInfo; + } + let substitution = substitutionMap.get(baseFontName); + if (!substitution) { + for (const [alias, subst] of fontAliases) { + if (baseFontName.startsWith(alias)) { + baseFontName = `${subst}${baseFontName.substring(alias.length)}`; + substitution = substitutionMap.get(baseFontName); + break; + } + } + } + let mustAddBaseFont = false; + if (!substitution) { + substitution = substitutionMap.get(standardFontName); + mustAddBaseFont = true; + } + const loadedName = `${idFactory.getDocId()}_s${idFactory.createFontId()}`; + if (!substitution) { + if (!(0, _core_utils.validateFontName)(baseFontName)) { + systemFontCache.set(key, null); + return null; + } + const bold = /bold/gi.test(baseFontName); + const italic = /oblique|italic/gi.test(baseFontName); + const style = bold && italic && BOLDITALIC || bold && BOLD || italic && ITALIC || NORMAL; + substitutionInfo = { + css: loadedName, + guessFallback: true, + loadedName, + baseFontName, + src: `local(${baseFontName})`, + style + }; + systemFontCache.set(key, substitutionInfo); + return substitutionInfo; + } + const src = []; + if (mustAddBaseFont && (0, _core_utils.validateFontName)(baseFontName)) { + src.push(`local(${baseFontName})`); + } + const { + style, + ultimate + } = generateFont(substitution, src, localFontPath); + const guessFallback = ultimate === null; + const fallback = guessFallback ? "" : `,${ultimate}`; + substitutionInfo = { + css: `${loadedName}${fallback}`, + guessFallback, + loadedName, + baseFontName, + src: src.join(","), + style + }; + systemFontCache.set(key, substitutionInfo); + return substitutionInfo; +} + +/***/ }), +/* 62 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ImageResizer = void 0; +var _util = __w_pdfjs_require__(2); +const MIN_IMAGE_DIM = 2048; +const MAX_IMAGE_DIM = 65537; +const MAX_ERROR = 128; +class ImageResizer { + constructor(imgData, isMask) { + this._imgData = imgData; + this._isMask = isMask; + } + static needsToBeResized(width, height) { + if (width <= this._goodSquareLength && height <= this._goodSquareLength) { + return false; + } + const { + MAX_DIM + } = this; + if (width > MAX_DIM || height > MAX_DIM) { + return true; + } + const area = width * height; + if (this._hasMaxArea) { + return area > this.MAX_AREA; + } + if (area < this._goodSquareLength ** 2) { + return false; + } + if (this._areGoodDims(width, height)) { + this._goodSquareLength = Math.max(this._goodSquareLength, Math.floor(Math.sqrt(width * height))); + return false; + } + this._goodSquareLength = this._guessMax(this._goodSquareLength, MAX_DIM, MAX_ERROR, 0); + const maxArea = this.MAX_AREA = this._goodSquareLength ** 2; + return area > maxArea; + } + static get MAX_DIM() { + return (0, _util.shadow)(this, "MAX_DIM", this._guessMax(MIN_IMAGE_DIM, MAX_IMAGE_DIM, 0, 1)); + } + static get MAX_AREA() { + this._hasMaxArea = true; + return (0, _util.shadow)(this, "MAX_AREA", this._guessMax(ImageResizer._goodSquareLength, this.MAX_DIM, MAX_ERROR, 0) ** 2); + } + static set MAX_AREA(area) { + if (area >= 0) { + this._hasMaxArea = true; + (0, _util.shadow)(this, "MAX_AREA", area); + } + } + static setMaxArea(area) { + if (!this._hasMaxArea) { + this.MAX_AREA = area >> 2; + } + } + static _areGoodDims(width, height) { + try { + const canvas = new OffscreenCanvas(width, height); + const ctx = canvas.getContext("2d"); + ctx.fillRect(0, 0, 1, 1); + const opacity = ctx.getImageData(0, 0, 1, 1).data[3]; + canvas.width = canvas.height = 1; + return opacity !== 0; + } catch { + return false; + } + } + static _guessMax(start, end, tolerance, defaultHeight) { + while (start + tolerance + 1 < end) { + const middle = Math.floor((start + end) / 2); + const height = defaultHeight || middle; + if (this._areGoodDims(middle, height)) { + start = middle; + } else { + end = middle; + } + } + return start; + } + static async createImage(imgData, isMask = false) { + return new ImageResizer(imgData, isMask)._createImage(); + } + async _createImage() { + const data = this._encodeBMP(); + const blob = new Blob([data.buffer], { + type: "image/bmp" + }); + const bitmapPromise = createImageBitmap(blob); + const { + MAX_AREA, + MAX_DIM + } = ImageResizer; + const { + _imgData: imgData + } = this; + const { + width, + height + } = imgData; + const minFactor = Math.max(width / MAX_DIM, height / MAX_DIM, Math.sqrt(width * height / MAX_AREA)); + const firstFactor = Math.max(minFactor, 2); + const factor = Math.round(10 * (minFactor + 1.25)) / 10 / firstFactor; + const N = Math.floor(Math.log2(factor)); + const steps = new Array(N + 2).fill(2); + steps[0] = firstFactor; + steps.splice(-1, 1, factor / (1 << N)); + let newWidth = width; + let newHeight = height; + let bitmap = await bitmapPromise; + for (const step of steps) { + const prevWidth = newWidth; + const prevHeight = newHeight; + newWidth = Math.floor(newWidth / step) - 1; + newHeight = Math.floor(newHeight / step) - 1; + const canvas = new OffscreenCanvas(newWidth, newHeight); + const ctx = canvas.getContext("2d"); + ctx.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight); + bitmap = canvas.transferToImageBitmap(); + } + imgData.data = null; + imgData.bitmap = bitmap; + imgData.width = newWidth; + imgData.height = newHeight; + return imgData; + } + _encodeBMP() { + const { + width, + height, + kind + } = this._imgData; + let data = this._imgData.data; + let bitPerPixel; + let colorTable = new Uint8Array(0); + let maskTable = colorTable; + let compression = 0; + switch (kind) { + case _util.ImageKind.GRAYSCALE_1BPP: + { + bitPerPixel = 1; + colorTable = new Uint8Array(this._isMask ? [255, 255, 255, 255, 0, 0, 0, 0] : [0, 0, 0, 0, 255, 255, 255, 255]); + const rowLen = width + 7 >> 3; + const rowSize = rowLen + 3 & -4; + if (rowLen !== rowSize) { + const newData = new Uint8Array(rowSize * height); + let k = 0; + for (let i = 0, ii = height * rowLen; i < ii; i += rowLen, k += rowSize) { + newData.set(data.subarray(i, i + rowLen), k); + } + data = newData; + } + break; + } + case _util.ImageKind.RGB_24BPP: + { + bitPerPixel = 24; + if (width & 3) { + const rowLen = 3 * width; + const rowSize = rowLen + 3 & -4; + const extraLen = rowSize - rowLen; + const newData = new Uint8Array(rowSize * height); + let k = 0; + for (let i = 0, ii = height * rowLen; i < ii; i += rowLen) { + const row = data.subarray(i, i + rowLen); + for (let j = 0; j < rowLen; j += 3) { + newData[k++] = row[j + 2]; + newData[k++] = row[j + 1]; + newData[k++] = row[j]; + } + k += extraLen; + } + data = newData; + } else { + for (let i = 0, ii = data.length; i < ii; i += 3) { + const tmp = data[i]; + data[i] = data[i + 2]; + data[i + 2] = tmp; + } + } + break; + } + case _util.ImageKind.RGBA_32BPP: + bitPerPixel = 32; + compression = 3; + maskTable = new Uint8Array(4 + 4 + 4 + 4 + 52); + const view = new DataView(maskTable.buffer); + if (_util.FeatureTest.isLittleEndian) { + view.setUint32(0, 0x000000ff, true); + view.setUint32(4, 0x0000ff00, true); + view.setUint32(8, 0x00ff0000, true); + view.setUint32(12, 0xff000000, true); + } else { + view.setUint32(0, 0xff000000, true); + view.setUint32(4, 0x00ff0000, true); + view.setUint32(8, 0x0000ff00, true); + view.setUint32(12, 0x000000ff, true); + } + break; + default: + throw new Error("invalid format"); + } + let i = 0; + const headerLength = 40 + maskTable.length; + const fileLength = 14 + headerLength + colorTable.length + data.length; + const bmpData = new Uint8Array(fileLength); + const view = new DataView(bmpData.buffer); + view.setUint16(i, 0x4d42, true); + i += 2; + view.setUint32(i, fileLength, true); + i += 4; + view.setUint32(i, 0, true); + i += 4; + view.setUint32(i, 14 + headerLength + colorTable.length, true); + i += 4; + view.setUint32(i, headerLength, true); + i += 4; + view.setInt32(i, width, true); + i += 4; + view.setInt32(i, -height, true); + i += 4; + view.setUint16(i, 1, true); + i += 2; + view.setUint16(i, bitPerPixel, true); + i += 2; + view.setUint32(i, compression, true); + i += 4; + view.setUint32(i, 0, true); + i += 4; + view.setInt32(i, 0, true); + i += 4; + view.setInt32(i, 0, true); + i += 4; + view.setUint32(i, colorTable.length / 4, true); + i += 4; + view.setUint32(i, 0, true); + i += 4; + bmpData.set(maskTable, i); + i += maskTable.length; + bmpData.set(colorTable, i); + i += colorTable.length; + bmpData.set(data, i); + return bmpData; + } +} +exports.ImageResizer = ImageResizer; +ImageResizer._goodSquareLength = MIN_IMAGE_DIM; + +/***/ }), +/* 63 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.MurmurHash3_64 = void 0; +var _util = __w_pdfjs_require__(2); +const SEED = 0xc3d2e1f0; +const MASK_HIGH = 0xffff0000; +const MASK_LOW = 0xffff; +class MurmurHash3_64 { + constructor(seed) { + this.h1 = seed ? seed & 0xffffffff : SEED; + this.h2 = seed ? seed & 0xffffffff : SEED; + } + update(input) { + let data, length; + if (typeof input === "string") { + data = new Uint8Array(input.length * 2); + length = 0; + for (let i = 0, ii = input.length; i < ii; i++) { + const code = input.charCodeAt(i); + if (code <= 0xff) { + data[length++] = code; + } else { + data[length++] = code >>> 8; + data[length++] = code & 0xff; + } + } + } else if ((0, _util.isArrayBuffer)(input)) { + data = input.slice(); + length = data.byteLength; + } else { + throw new Error("Wrong data format in MurmurHash3_64_update. " + "Input must be a string or array."); + } + const blockCounts = length >> 2; + const tailLength = length - blockCounts * 4; + const dataUint32 = new Uint32Array(data.buffer, 0, blockCounts); + let k1 = 0, + k2 = 0; + let h1 = this.h1, + h2 = this.h2; + const C1 = 0xcc9e2d51, + C2 = 0x1b873593; + const C1_LOW = C1 & MASK_LOW, + C2_LOW = C2 & MASK_LOW; + for (let i = 0; i < blockCounts; i++) { + if (i & 1) { + k1 = dataUint32[i]; + k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; + k1 = k1 << 15 | k1 >>> 17; + k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW; + h1 ^= k1; + h1 = h1 << 13 | h1 >>> 19; + h1 = h1 * 5 + 0xe6546b64; + } else { + k2 = dataUint32[i]; + k2 = k2 * C1 & MASK_HIGH | k2 * C1_LOW & MASK_LOW; + k2 = k2 << 15 | k2 >>> 17; + k2 = k2 * C2 & MASK_HIGH | k2 * C2_LOW & MASK_LOW; + h2 ^= k2; + h2 = h2 << 13 | h2 >>> 19; + h2 = h2 * 5 + 0xe6546b64; + } + } + k1 = 0; + switch (tailLength) { + case 3: + k1 ^= data[blockCounts * 4 + 2] << 16; + case 2: + k1 ^= data[blockCounts * 4 + 1] << 8; + case 1: + k1 ^= data[blockCounts * 4]; + k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; + k1 = k1 << 15 | k1 >>> 17; + k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW; + if (blockCounts & 1) { + h1 ^= k1; + } else { + h2 ^= k1; + } + } + this.h1 = h1; + this.h2 = h2; + } + hexdigest() { + let h1 = this.h1, + h2 = this.h2; + h1 ^= h2 >>> 1; + h1 = h1 * 0xed558ccd & MASK_HIGH | h1 * 0x8ccd & MASK_LOW; + h2 = h2 * 0xff51afd7 & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16; + h1 ^= h2 >>> 1; + h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW; + h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16; + h1 ^= h2 >>> 1; + return (h1 >>> 0).toString(16).padStart(8, "0") + (h2 >>> 0).toString(16).padStart(8, "0"); + } +} +exports.MurmurHash3_64 = MurmurHash3_64; + +/***/ }), +/* 64 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.OperatorList = void 0; +var _util = __w_pdfjs_require__(2); +function addState(parentState, pattern, checkFn, iterateFn, processFn) { + let state = parentState; + for (let i = 0, ii = pattern.length - 1; i < ii; i++) { + const item = pattern[i]; + state = state[item] ||= []; + } + state[pattern.at(-1)] = { + checkFn, + iterateFn, + processFn + }; +} +const InitialState = []; +addState(InitialState, [_util.OPS.save, _util.OPS.transform, _util.OPS.paintInlineImageXObject, _util.OPS.restore], null, function iterateInlineImageGroup(context, i) { + const fnArray = context.fnArray; + const iFirstSave = context.iCurr - 3; + const pos = (i - iFirstSave) % 4; + switch (pos) { + case 0: + return fnArray[i] === _util.OPS.save; + case 1: + return fnArray[i] === _util.OPS.transform; + case 2: + return fnArray[i] === _util.OPS.paintInlineImageXObject; + case 3: + return fnArray[i] === _util.OPS.restore; + } + throw new Error(`iterateInlineImageGroup - invalid pos: ${pos}`); +}, function foundInlineImageGroup(context, i) { + const MIN_IMAGES_IN_INLINE_IMAGES_BLOCK = 10; + const MAX_IMAGES_IN_INLINE_IMAGES_BLOCK = 200; + const MAX_WIDTH = 1000; + const IMAGE_PADDING = 1; + const fnArray = context.fnArray, + argsArray = context.argsArray; + const curr = context.iCurr; + const iFirstSave = curr - 3; + const iFirstTransform = curr - 2; + const iFirstPIIXO = curr - 1; + const count = Math.min(Math.floor((i - iFirstSave) / 4), MAX_IMAGES_IN_INLINE_IMAGES_BLOCK); + if (count < MIN_IMAGES_IN_INLINE_IMAGES_BLOCK) { + return i - (i - iFirstSave) % 4; + } + let maxX = 0; + const map = []; + let maxLineHeight = 0; + let currentX = IMAGE_PADDING, + currentY = IMAGE_PADDING; + for (let q = 0; q < count; q++) { + const transform = argsArray[iFirstTransform + (q << 2)]; + const img = argsArray[iFirstPIIXO + (q << 2)][0]; + if (currentX + img.width > MAX_WIDTH) { + maxX = Math.max(maxX, currentX); + currentY += maxLineHeight + 2 * IMAGE_PADDING; + currentX = 0; + maxLineHeight = 0; + } + map.push({ + transform, + x: currentX, + y: currentY, + w: img.width, + h: img.height + }); + currentX += img.width + 2 * IMAGE_PADDING; + maxLineHeight = Math.max(maxLineHeight, img.height); + } + const imgWidth = Math.max(maxX, currentX) + IMAGE_PADDING; + const imgHeight = currentY + maxLineHeight + IMAGE_PADDING; + const imgData = new Uint8Array(imgWidth * imgHeight * 4); + const imgRowSize = imgWidth << 2; + for (let q = 0; q < count; q++) { + const data = argsArray[iFirstPIIXO + (q << 2)][0].data; + const rowSize = map[q].w << 2; + let dataOffset = 0; + let offset = map[q].x + map[q].y * imgWidth << 2; + imgData.set(data.subarray(0, rowSize), offset - imgRowSize); + for (let k = 0, kk = map[q].h; k < kk; k++) { + imgData.set(data.subarray(dataOffset, dataOffset + rowSize), offset); + dataOffset += rowSize; + offset += imgRowSize; + } + imgData.set(data.subarray(dataOffset - rowSize, dataOffset), offset); + while (offset >= 0) { + data[offset - 4] = data[offset]; + data[offset - 3] = data[offset + 1]; + data[offset - 2] = data[offset + 2]; + data[offset - 1] = data[offset + 3]; + data[offset + rowSize] = data[offset + rowSize - 4]; + data[offset + rowSize + 1] = data[offset + rowSize - 3]; + data[offset + rowSize + 2] = data[offset + rowSize - 2]; + data[offset + rowSize + 3] = data[offset + rowSize - 1]; + offset -= imgRowSize; + } + } + const img = { + width: imgWidth, + height: imgHeight + }; + if (context.isOffscreenCanvasSupported) { + const canvas = new OffscreenCanvas(imgWidth, imgHeight); + const ctx = canvas.getContext("2d"); + ctx.putImageData(new ImageData(new Uint8ClampedArray(imgData.buffer), imgWidth, imgHeight), 0, 0); + img.bitmap = canvas.transferToImageBitmap(); + img.data = null; + } else { + img.kind = _util.ImageKind.RGBA_32BPP; + img.data = imgData; + } + fnArray.splice(iFirstSave, count * 4, _util.OPS.paintInlineImageXObjectGroup); + argsArray.splice(iFirstSave, count * 4, [img, map]); + return iFirstSave + 1; +}); +addState(InitialState, [_util.OPS.save, _util.OPS.transform, _util.OPS.paintImageMaskXObject, _util.OPS.restore], null, function iterateImageMaskGroup(context, i) { + const fnArray = context.fnArray; + const iFirstSave = context.iCurr - 3; + const pos = (i - iFirstSave) % 4; + switch (pos) { + case 0: + return fnArray[i] === _util.OPS.save; + case 1: + return fnArray[i] === _util.OPS.transform; + case 2: + return fnArray[i] === _util.OPS.paintImageMaskXObject; + case 3: + return fnArray[i] === _util.OPS.restore; + } + throw new Error(`iterateImageMaskGroup - invalid pos: ${pos}`); +}, function foundImageMaskGroup(context, i) { + const MIN_IMAGES_IN_MASKS_BLOCK = 10; + const MAX_IMAGES_IN_MASKS_BLOCK = 100; + const MAX_SAME_IMAGES_IN_MASKS_BLOCK = 1000; + const fnArray = context.fnArray, + argsArray = context.argsArray; + const curr = context.iCurr; + const iFirstSave = curr - 3; + const iFirstTransform = curr - 2; + const iFirstPIMXO = curr - 1; + let count = Math.floor((i - iFirstSave) / 4); + if (count < MIN_IMAGES_IN_MASKS_BLOCK) { + return i - (i - iFirstSave) % 4; + } + let isSameImage = false; + let iTransform, transformArgs; + const firstPIMXOArg0 = argsArray[iFirstPIMXO][0]; + const firstTransformArg0 = argsArray[iFirstTransform][0], + firstTransformArg1 = argsArray[iFirstTransform][1], + firstTransformArg2 = argsArray[iFirstTransform][2], + firstTransformArg3 = argsArray[iFirstTransform][3]; + if (firstTransformArg1 === firstTransformArg2) { + isSameImage = true; + iTransform = iFirstTransform + 4; + let iPIMXO = iFirstPIMXO + 4; + for (let q = 1; q < count; q++, iTransform += 4, iPIMXO += 4) { + transformArgs = argsArray[iTransform]; + if (argsArray[iPIMXO][0] !== firstPIMXOArg0 || transformArgs[0] !== firstTransformArg0 || transformArgs[1] !== firstTransformArg1 || transformArgs[2] !== firstTransformArg2 || transformArgs[3] !== firstTransformArg3) { + if (q < MIN_IMAGES_IN_MASKS_BLOCK) { + isSameImage = false; + } else { + count = q; + } + break; + } + } + } + if (isSameImage) { + count = Math.min(count, MAX_SAME_IMAGES_IN_MASKS_BLOCK); + const positions = new Float32Array(count * 2); + iTransform = iFirstTransform; + for (let q = 0; q < count; q++, iTransform += 4) { + transformArgs = argsArray[iTransform]; + positions[q << 1] = transformArgs[4]; + positions[(q << 1) + 1] = transformArgs[5]; + } + fnArray.splice(iFirstSave, count * 4, _util.OPS.paintImageMaskXObjectRepeat); + argsArray.splice(iFirstSave, count * 4, [firstPIMXOArg0, firstTransformArg0, firstTransformArg1, firstTransformArg2, firstTransformArg3, positions]); + } else { + count = Math.min(count, MAX_IMAGES_IN_MASKS_BLOCK); + const images = []; + for (let q = 0; q < count; q++) { + transformArgs = argsArray[iFirstTransform + (q << 2)]; + const maskParams = argsArray[iFirstPIMXO + (q << 2)][0]; + images.push({ + data: maskParams.data, + width: maskParams.width, + height: maskParams.height, + interpolate: maskParams.interpolate, + count: maskParams.count, + transform: transformArgs + }); + } + fnArray.splice(iFirstSave, count * 4, _util.OPS.paintImageMaskXObjectGroup); + argsArray.splice(iFirstSave, count * 4, [images]); + } + return iFirstSave + 1; +}); +addState(InitialState, [_util.OPS.save, _util.OPS.transform, _util.OPS.paintImageXObject, _util.OPS.restore], function (context) { + const argsArray = context.argsArray; + const iFirstTransform = context.iCurr - 2; + return argsArray[iFirstTransform][1] === 0 && argsArray[iFirstTransform][2] === 0; +}, function iterateImageGroup(context, i) { + const fnArray = context.fnArray, + argsArray = context.argsArray; + const iFirstSave = context.iCurr - 3; + const pos = (i - iFirstSave) % 4; + switch (pos) { + case 0: + return fnArray[i] === _util.OPS.save; + case 1: + if (fnArray[i] !== _util.OPS.transform) { + return false; + } + const iFirstTransform = context.iCurr - 2; + const firstTransformArg0 = argsArray[iFirstTransform][0]; + const firstTransformArg3 = argsArray[iFirstTransform][3]; + if (argsArray[i][0] !== firstTransformArg0 || argsArray[i][1] !== 0 || argsArray[i][2] !== 0 || argsArray[i][3] !== firstTransformArg3) { + return false; + } + return true; + case 2: + if (fnArray[i] !== _util.OPS.paintImageXObject) { + return false; + } + const iFirstPIXO = context.iCurr - 1; + const firstPIXOArg0 = argsArray[iFirstPIXO][0]; + if (argsArray[i][0] !== firstPIXOArg0) { + return false; + } + return true; + case 3: + return fnArray[i] === _util.OPS.restore; + } + throw new Error(`iterateImageGroup - invalid pos: ${pos}`); +}, function (context, i) { + const MIN_IMAGES_IN_BLOCK = 3; + const MAX_IMAGES_IN_BLOCK = 1000; + const fnArray = context.fnArray, + argsArray = context.argsArray; + const curr = context.iCurr; + const iFirstSave = curr - 3; + const iFirstTransform = curr - 2; + const iFirstPIXO = curr - 1; + const firstPIXOArg0 = argsArray[iFirstPIXO][0]; + const firstTransformArg0 = argsArray[iFirstTransform][0]; + const firstTransformArg3 = argsArray[iFirstTransform][3]; + const count = Math.min(Math.floor((i - iFirstSave) / 4), MAX_IMAGES_IN_BLOCK); + if (count < MIN_IMAGES_IN_BLOCK) { + return i - (i - iFirstSave) % 4; + } + const positions = new Float32Array(count * 2); + let iTransform = iFirstTransform; + for (let q = 0; q < count; q++, iTransform += 4) { + const transformArgs = argsArray[iTransform]; + positions[q << 1] = transformArgs[4]; + positions[(q << 1) + 1] = transformArgs[5]; + } + const args = [firstPIXOArg0, firstTransformArg0, firstTransformArg3, positions]; + fnArray.splice(iFirstSave, count * 4, _util.OPS.paintImageXObjectRepeat); + argsArray.splice(iFirstSave, count * 4, args); + return iFirstSave + 1; +}); +addState(InitialState, [_util.OPS.beginText, _util.OPS.setFont, _util.OPS.setTextMatrix, _util.OPS.showText, _util.OPS.endText], null, function iterateShowTextGroup(context, i) { + const fnArray = context.fnArray, + argsArray = context.argsArray; + const iFirstSave = context.iCurr - 4; + const pos = (i - iFirstSave) % 5; + switch (pos) { + case 0: + return fnArray[i] === _util.OPS.beginText; + case 1: + return fnArray[i] === _util.OPS.setFont; + case 2: + return fnArray[i] === _util.OPS.setTextMatrix; + case 3: + if (fnArray[i] !== _util.OPS.showText) { + return false; + } + const iFirstSetFont = context.iCurr - 3; + const firstSetFontArg0 = argsArray[iFirstSetFont][0]; + const firstSetFontArg1 = argsArray[iFirstSetFont][1]; + if (argsArray[i][0] !== firstSetFontArg0 || argsArray[i][1] !== firstSetFontArg1) { + return false; + } + return true; + case 4: + return fnArray[i] === _util.OPS.endText; + } + throw new Error(`iterateShowTextGroup - invalid pos: ${pos}`); +}, function (context, i) { + const MIN_CHARS_IN_BLOCK = 3; + const MAX_CHARS_IN_BLOCK = 1000; + const fnArray = context.fnArray, + argsArray = context.argsArray; + const curr = context.iCurr; + const iFirstBeginText = curr - 4; + const iFirstSetFont = curr - 3; + const iFirstSetTextMatrix = curr - 2; + const iFirstShowText = curr - 1; + const iFirstEndText = curr; + const firstSetFontArg0 = argsArray[iFirstSetFont][0]; + const firstSetFontArg1 = argsArray[iFirstSetFont][1]; + let count = Math.min(Math.floor((i - iFirstBeginText) / 5), MAX_CHARS_IN_BLOCK); + if (count < MIN_CHARS_IN_BLOCK) { + return i - (i - iFirstBeginText) % 5; + } + let iFirst = iFirstBeginText; + if (iFirstBeginText >= 4 && fnArray[iFirstBeginText - 4] === fnArray[iFirstSetFont] && fnArray[iFirstBeginText - 3] === fnArray[iFirstSetTextMatrix] && fnArray[iFirstBeginText - 2] === fnArray[iFirstShowText] && fnArray[iFirstBeginText - 1] === fnArray[iFirstEndText] && argsArray[iFirstBeginText - 4][0] === firstSetFontArg0 && argsArray[iFirstBeginText - 4][1] === firstSetFontArg1) { + count++; + iFirst -= 5; + } + let iEndText = iFirst + 4; + for (let q = 1; q < count; q++) { + fnArray.splice(iEndText, 3); + argsArray.splice(iEndText, 3); + iEndText += 2; + } + return iEndText + 1; +}); +class NullOptimizer { + constructor(queue) { + this.queue = queue; + } + _optimize() {} + push(fn, args) { + this.queue.fnArray.push(fn); + this.queue.argsArray.push(args); + this._optimize(); + } + flush() {} + reset() {} +} +class QueueOptimizer extends NullOptimizer { + constructor(queue) { + super(queue); + this.state = null; + this.context = { + iCurr: 0, + fnArray: queue.fnArray, + argsArray: queue.argsArray, + isOffscreenCanvasSupported: false + }; + this.match = null; + this.lastProcessed = 0; + } + set isOffscreenCanvasSupported(value) { + this.context.isOffscreenCanvasSupported = value; + } + _optimize() { + const fnArray = this.queue.fnArray; + let i = this.lastProcessed, + ii = fnArray.length; + let state = this.state; + let match = this.match; + if (!state && !match && i + 1 === ii && !InitialState[fnArray[i]]) { + this.lastProcessed = ii; + return; + } + const context = this.context; + while (i < ii) { + if (match) { + const iterate = (0, match.iterateFn)(context, i); + if (iterate) { + i++; + continue; + } + i = (0, match.processFn)(context, i + 1); + ii = fnArray.length; + match = null; + state = null; + if (i >= ii) { + break; + } + } + state = (state || InitialState)[fnArray[i]]; + if (!state || Array.isArray(state)) { + i++; + continue; + } + context.iCurr = i; + i++; + if (state.checkFn && !(0, state.checkFn)(context)) { + state = null; + continue; + } + match = state; + state = null; + } + this.state = state; + this.match = match; + this.lastProcessed = i; + } + flush() { + while (this.match) { + const length = this.queue.fnArray.length; + this.lastProcessed = (0, this.match.processFn)(this.context, length); + this.match = null; + this.state = null; + this._optimize(); + } + } + reset() { + this.state = null; + this.match = null; + this.lastProcessed = 0; + } +} +class OperatorList { + static CHUNK_SIZE = 1000; + static CHUNK_SIZE_ABOUT = this.CHUNK_SIZE - 5; + constructor(intent = 0, streamSink) { + this._streamSink = streamSink; + this.fnArray = []; + this.argsArray = []; + this.optimizer = streamSink && !(intent & _util.RenderingIntentFlag.OPLIST) ? new QueueOptimizer(this) : new NullOptimizer(this); + this.dependencies = new Set(); + this._totalLength = 0; + this.weight = 0; + this._resolved = streamSink ? null : Promise.resolve(); + } + set isOffscreenCanvasSupported(value) { + this.optimizer.isOffscreenCanvasSupported = value; + } + get length() { + return this.argsArray.length; + } + get ready() { + return this._resolved || this._streamSink.ready; + } + get totalLength() { + return this._totalLength + this.length; + } + addOp(fn, args) { + this.optimizer.push(fn, args); + this.weight++; + if (this._streamSink) { + if (this.weight >= OperatorList.CHUNK_SIZE) { + this.flush(); + } else if (this.weight >= OperatorList.CHUNK_SIZE_ABOUT && (fn === _util.OPS.restore || fn === _util.OPS.endText)) { + this.flush(); + } + } + } + addImageOps(fn, args, optionalContent) { + if (optionalContent !== undefined) { + this.addOp(_util.OPS.beginMarkedContentProps, ["OC", optionalContent]); + } + this.addOp(fn, args); + if (optionalContent !== undefined) { + this.addOp(_util.OPS.endMarkedContent, []); + } + } + addDependency(dependency) { + if (this.dependencies.has(dependency)) { + return; + } + this.dependencies.add(dependency); + this.addOp(_util.OPS.dependency, [dependency]); + } + addDependencies(dependencies) { + for (const dependency of dependencies) { + this.addDependency(dependency); + } + } + addOpList(opList) { + if (!(opList instanceof OperatorList)) { + (0, _util.warn)('addOpList - ignoring invalid "opList" parameter.'); + return; + } + for (const dependency of opList.dependencies) { + this.dependencies.add(dependency); + } + for (let i = 0, ii = opList.length; i < ii; i++) { + this.addOp(opList.fnArray[i], opList.argsArray[i]); + } + } + getIR() { + return { + fnArray: this.fnArray, + argsArray: this.argsArray, + length: this.length + }; + } + get _transfers() { + const transfers = []; + const { + fnArray, + argsArray, + length + } = this; + for (let i = 0; i < length; i++) { + switch (fnArray[i]) { + case _util.OPS.paintInlineImageXObject: + case _util.OPS.paintInlineImageXObjectGroup: + case _util.OPS.paintImageMaskXObject: + const arg = argsArray[i][0]; + if (!arg.cached && arg.data?.buffer instanceof ArrayBuffer) { + transfers.push(arg.data.buffer); + } + break; + } + } + return transfers; + } + flush(lastChunk = false, separateAnnots = null) { + this.optimizer.flush(); + const length = this.length; + this._totalLength += length; + this._streamSink.enqueue({ + fnArray: this.fnArray, + argsArray: this.argsArray, + lastChunk, + separateAnnots, + length + }, 1, this._transfers); + this.dependencies.clear(); + this.fnArray.length = 0; + this.argsArray.length = 0; + this.weight = 0; + this.optimizer.reset(); + } +} +exports.OperatorList = OperatorList; + +/***/ }), +/* 65 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.PDFImage = void 0; +var _util = __w_pdfjs_require__(2); +var _image_utils = __w_pdfjs_require__(28); +var _base_stream = __w_pdfjs_require__(5); +var _colorspace = __w_pdfjs_require__(12); +var _decode_stream = __w_pdfjs_require__(18); +var _image_resizer = __w_pdfjs_require__(62); +var _jpeg_stream = __w_pdfjs_require__(26); +var _jpx = __w_pdfjs_require__(30); +var _primitives = __w_pdfjs_require__(4); +function decodeAndClamp(value, addend, coefficient, max) { + value = addend + value * coefficient; + if (value < 0) { + value = 0; + } else if (value > max) { + value = max; + } + return value; +} +function resizeImageMask(src, bpc, w1, h1, w2, h2) { + const length = w2 * h2; + let dest; + if (bpc <= 8) { + dest = new Uint8Array(length); + } else if (bpc <= 16) { + dest = new Uint16Array(length); + } else { + dest = new Uint32Array(length); + } + const xRatio = w1 / w2; + const yRatio = h1 / h2; + let i, + j, + py, + newIndex = 0, + oldIndex; + const xScaled = new Uint16Array(w2); + const w1Scanline = w1; + for (i = 0; i < w2; i++) { + xScaled[i] = Math.floor(i * xRatio); + } + for (i = 0; i < h2; i++) { + py = Math.floor(i * yRatio) * w1Scanline; + for (j = 0; j < w2; j++) { + oldIndex = py + xScaled[j]; + dest[newIndex++] = src[oldIndex]; + } + } + return dest; +} +class PDFImage { + constructor({ + xref, + res, + image, + isInline = false, + smask = null, + mask = null, + isMask = false, + pdfFunctionFactory, + localColorSpaceCache + }) { + this.image = image; + const dict = image.dict; + const filter = dict.get("F", "Filter"); + let filterName; + if (filter instanceof _primitives.Name) { + filterName = filter.name; + } else if (Array.isArray(filter)) { + const filterZero = xref.fetchIfRef(filter[0]); + if (filterZero instanceof _primitives.Name) { + filterName = filterZero.name; + } + } + switch (filterName) { + case "JPXDecode": + const jpxImage = new _jpx.JpxImage(); + jpxImage.parseImageProperties(image.stream); + image.stream.reset(); + image.width = jpxImage.width; + image.height = jpxImage.height; + image.bitsPerComponent = jpxImage.bitsPerComponent; + image.numComps = jpxImage.componentsCount; + break; + case "JBIG2Decode": + image.bitsPerComponent = 1; + image.numComps = 1; + break; + } + let width = dict.get("W", "Width"); + let height = dict.get("H", "Height"); + if (Number.isInteger(image.width) && image.width > 0 && Number.isInteger(image.height) && image.height > 0 && (image.width !== width || image.height !== height)) { + (0, _util.warn)("PDFImage - using the Width/Height of the image data, " + "rather than the image dictionary."); + width = image.width; + height = image.height; + } + if (width < 1 || height < 1) { + throw new _util.FormatError(`Invalid image width: ${width} or height: ${height}`); + } + this.width = width; + this.height = height; + this.interpolate = dict.get("I", "Interpolate"); + this.imageMask = dict.get("IM", "ImageMask") || false; + this.matte = dict.get("Matte") || false; + let bitsPerComponent = image.bitsPerComponent; + if (!bitsPerComponent) { + bitsPerComponent = dict.get("BPC", "BitsPerComponent"); + if (!bitsPerComponent) { + if (this.imageMask) { + bitsPerComponent = 1; + } else { + throw new _util.FormatError(`Bits per component missing in image: ${this.imageMask}`); + } + } + } + this.bpc = bitsPerComponent; + if (!this.imageMask) { + let colorSpace = dict.getRaw("CS") || dict.getRaw("ColorSpace"); + if (!colorSpace) { + (0, _util.info)("JPX images (which do not require color spaces)"); + switch (image.numComps) { + case 1: + colorSpace = _primitives.Name.get("DeviceGray"); + break; + case 3: + colorSpace = _primitives.Name.get("DeviceRGB"); + break; + case 4: + colorSpace = _primitives.Name.get("DeviceCMYK"); + break; + default: + throw new Error(`JPX images with ${image.numComps} color components not supported.`); + } + } + this.colorSpace = _colorspace.ColorSpace.parse({ + cs: colorSpace, + xref, + resources: isInline ? res : null, + pdfFunctionFactory, + localColorSpaceCache + }); + this.numComps = this.colorSpace.numComps; + } + this.decode = dict.getArray("D", "Decode"); + this.needsDecode = false; + if (this.decode && (this.colorSpace && !this.colorSpace.isDefaultDecode(this.decode, bitsPerComponent) || isMask && !_colorspace.ColorSpace.isDefaultDecode(this.decode, 1))) { + this.needsDecode = true; + const max = (1 << bitsPerComponent) - 1; + this.decodeCoefficients = []; + this.decodeAddends = []; + const isIndexed = this.colorSpace?.name === "Indexed"; + for (let i = 0, j = 0; i < this.decode.length; i += 2, ++j) { + const dmin = this.decode[i]; + const dmax = this.decode[i + 1]; + this.decodeCoefficients[j] = isIndexed ? (dmax - dmin) / max : dmax - dmin; + this.decodeAddends[j] = isIndexed ? dmin : max * dmin; + } + } + if (smask) { + this.smask = new PDFImage({ + xref, + res, + image: smask, + isInline, + pdfFunctionFactory, + localColorSpaceCache + }); + } else if (mask) { + if (mask instanceof _base_stream.BaseStream) { + const maskDict = mask.dict, + imageMask = maskDict.get("IM", "ImageMask"); + if (!imageMask) { + (0, _util.warn)("Ignoring /Mask in image without /ImageMask."); + } else { + this.mask = new PDFImage({ + xref, + res, + image: mask, + isInline, + isMask: true, + pdfFunctionFactory, + localColorSpaceCache + }); + } + } else { + this.mask = mask; + } + } + } + static async buildImage({ + xref, + res, + image, + isInline = false, + pdfFunctionFactory, + localColorSpaceCache + }) { + const imageData = image; + let smaskData = null; + let maskData = null; + const smask = image.dict.get("SMask"); + const mask = image.dict.get("Mask"); + if (smask) { + if (smask instanceof _base_stream.BaseStream) { + smaskData = smask; + } else { + (0, _util.warn)("Unsupported /SMask format."); + } + } else if (mask) { + if (mask instanceof _base_stream.BaseStream || Array.isArray(mask)) { + maskData = mask; + } else { + (0, _util.warn)("Unsupported /Mask format."); + } + } + return new PDFImage({ + xref, + res, + image: imageData, + isInline, + smask: smaskData, + mask: maskData, + pdfFunctionFactory, + localColorSpaceCache + }); + } + static createRawMask({ + imgArray, + width, + height, + imageIsFromDecodeStream, + inverseDecode, + interpolate + }) { + const computedLength = (width + 7 >> 3) * height; + const actualLength = imgArray.byteLength; + const haveFullData = computedLength === actualLength; + let data, i; + if (imageIsFromDecodeStream && (!inverseDecode || haveFullData)) { + data = imgArray; + } else if (!inverseDecode) { + data = new Uint8Array(imgArray); + } else { + data = new Uint8Array(computedLength); + data.set(imgArray); + data.fill(0xff, actualLength); + } + if (inverseDecode) { + for (i = 0; i < actualLength; i++) { + data[i] ^= 0xff; + } + } + return { + data, + width, + height, + interpolate + }; + } + static async createMask({ + imgArray, + width, + height, + imageIsFromDecodeStream, + inverseDecode, + interpolate, + isOffscreenCanvasSupported = false + }) { + const isSingleOpaquePixel = width === 1 && height === 1 && inverseDecode === (imgArray.length === 0 || !!(imgArray[0] & 128)); + if (isSingleOpaquePixel) { + return { + isSingleOpaquePixel + }; + } + if (isOffscreenCanvasSupported) { + if (_image_resizer.ImageResizer.needsToBeResized(width, height)) { + const data = new Uint8ClampedArray(width * height * 4); + (0, _image_utils.convertBlackAndWhiteToRGBA)({ + src: imgArray, + dest: data, + width, + height, + nonBlackColor: 0, + inverseDecode + }); + return _image_resizer.ImageResizer.createImage({ + kind: _util.ImageKind.RGBA_32BPP, + data, + width, + height, + interpolate + }); + } + const canvas = new OffscreenCanvas(width, height); + const ctx = canvas.getContext("2d"); + const imgData = ctx.createImageData(width, height); + (0, _image_utils.convertBlackAndWhiteToRGBA)({ + src: imgArray, + dest: imgData.data, + width, + height, + nonBlackColor: 0, + inverseDecode + }); + ctx.putImageData(imgData, 0, 0); + const bitmap = canvas.transferToImageBitmap(); + return { + data: null, + width, + height, + interpolate, + bitmap + }; + } + return this.createRawMask({ + imgArray, + width, + height, + inverseDecode, + imageIsFromDecodeStream, + interpolate + }); + } + get drawWidth() { + return Math.max(this.width, this.smask?.width || 0, this.mask?.width || 0); + } + get drawHeight() { + return Math.max(this.height, this.smask?.height || 0, this.mask?.height || 0); + } + decodeBuffer(buffer) { + const bpc = this.bpc; + const numComps = this.numComps; + const decodeAddends = this.decodeAddends; + const decodeCoefficients = this.decodeCoefficients; + const max = (1 << bpc) - 1; + let i, ii; + if (bpc === 1) { + for (i = 0, ii = buffer.length; i < ii; i++) { + buffer[i] = +!buffer[i]; + } + return; + } + let index = 0; + for (i = 0, ii = this.width * this.height; i < ii; i++) { + for (let j = 0; j < numComps; j++) { + buffer[index] = decodeAndClamp(buffer[index], decodeAddends[j], decodeCoefficients[j], max); + index++; + } + } + } + getComponents(buffer) { + const bpc = this.bpc; + if (bpc === 8) { + return buffer; + } + const width = this.width; + const height = this.height; + const numComps = this.numComps; + const length = width * height * numComps; + let bufferPos = 0; + let output; + if (bpc <= 8) { + output = new Uint8Array(length); + } else if (bpc <= 16) { + output = new Uint16Array(length); + } else { + output = new Uint32Array(length); + } + const rowComps = width * numComps; + const max = (1 << bpc) - 1; + let i = 0, + ii, + buf; + if (bpc === 1) { + let mask, loop1End, loop2End; + for (let j = 0; j < height; j++) { + loop1End = i + (rowComps & ~7); + loop2End = i + rowComps; + while (i < loop1End) { + buf = buffer[bufferPos++]; + output[i] = buf >> 7 & 1; + output[i + 1] = buf >> 6 & 1; + output[i + 2] = buf >> 5 & 1; + output[i + 3] = buf >> 4 & 1; + output[i + 4] = buf >> 3 & 1; + output[i + 5] = buf >> 2 & 1; + output[i + 6] = buf >> 1 & 1; + output[i + 7] = buf & 1; + i += 8; + } + if (i < loop2End) { + buf = buffer[bufferPos++]; + mask = 128; + while (i < loop2End) { + output[i++] = +!!(buf & mask); + mask >>= 1; + } + } + } + } else { + let bits = 0; + buf = 0; + for (i = 0, ii = length; i < ii; ++i) { + if (i % rowComps === 0) { + buf = 0; + bits = 0; + } + while (bits < bpc) { + buf = buf << 8 | buffer[bufferPos++]; + bits += 8; + } + const remainingBits = bits - bpc; + let value = buf >> remainingBits; + if (value < 0) { + value = 0; + } else if (value > max) { + value = max; + } + output[i] = value; + buf &= (1 << remainingBits) - 1; + bits = remainingBits; + } + } + return output; + } + fillOpacity(rgbaBuf, width, height, actualHeight, image) { + const smask = this.smask; + const mask = this.mask; + let alphaBuf, sw, sh, i, ii, j; + if (smask) { + sw = smask.width; + sh = smask.height; + alphaBuf = new Uint8ClampedArray(sw * sh); + smask.fillGrayBuffer(alphaBuf); + if (sw !== width || sh !== height) { + alphaBuf = resizeImageMask(alphaBuf, smask.bpc, sw, sh, width, height); + } + } else if (mask) { + if (mask instanceof PDFImage) { + sw = mask.width; + sh = mask.height; + alphaBuf = new Uint8ClampedArray(sw * sh); + mask.numComps = 1; + mask.fillGrayBuffer(alphaBuf); + for (i = 0, ii = sw * sh; i < ii; ++i) { + alphaBuf[i] = 255 - alphaBuf[i]; + } + if (sw !== width || sh !== height) { + alphaBuf = resizeImageMask(alphaBuf, mask.bpc, sw, sh, width, height); + } + } else if (Array.isArray(mask)) { + alphaBuf = new Uint8ClampedArray(width * height); + const numComps = this.numComps; + for (i = 0, ii = width * height; i < ii; ++i) { + let opacity = 0; + const imageOffset = i * numComps; + for (j = 0; j < numComps; ++j) { + const color = image[imageOffset + j]; + const maskOffset = j * 2; + if (color < mask[maskOffset] || color > mask[maskOffset + 1]) { + opacity = 255; + break; + } + } + alphaBuf[i] = opacity; + } + } else { + throw new _util.FormatError("Unknown mask format."); + } + } + if (alphaBuf) { + for (i = 0, j = 3, ii = width * actualHeight; i < ii; ++i, j += 4) { + rgbaBuf[j] = alphaBuf[i]; + } + } else { + for (i = 0, j = 3, ii = width * actualHeight; i < ii; ++i, j += 4) { + rgbaBuf[j] = 255; + } + } + } + undoPreblend(buffer, width, height) { + const matte = this.smask?.matte; + if (!matte) { + return; + } + const matteRgb = this.colorSpace.getRgb(matte, 0); + const matteR = matteRgb[0]; + const matteG = matteRgb[1]; + const matteB = matteRgb[2]; + const length = width * height * 4; + for (let i = 0; i < length; i += 4) { + const alpha = buffer[i + 3]; + if (alpha === 0) { + buffer[i] = 255; + buffer[i + 1] = 255; + buffer[i + 2] = 255; + continue; + } + const k = 255 / alpha; + buffer[i] = (buffer[i] - matteR) * k + matteR; + buffer[i + 1] = (buffer[i + 1] - matteG) * k + matteG; + buffer[i + 2] = (buffer[i + 2] - matteB) * k + matteB; + } + } + async createImageData(forceRGBA = false, isOffscreenCanvasSupported = false) { + const drawWidth = this.drawWidth; + const drawHeight = this.drawHeight; + const imgData = { + width: drawWidth, + height: drawHeight, + interpolate: this.interpolate, + kind: 0, + data: null + }; + const numComps = this.numComps; + const originalWidth = this.width; + const originalHeight = this.height; + const bpc = this.bpc; + const rowBytes = originalWidth * numComps * bpc + 7 >> 3; + const mustBeResized = isOffscreenCanvasSupported && _image_resizer.ImageResizer.needsToBeResized(drawWidth, drawHeight); + if (!forceRGBA) { + let kind; + if (this.colorSpace.name === "DeviceGray" && bpc === 1) { + kind = _util.ImageKind.GRAYSCALE_1BPP; + } else if (this.colorSpace.name === "DeviceRGB" && bpc === 8 && !this.needsDecode) { + kind = _util.ImageKind.RGB_24BPP; + } + if (kind && !this.smask && !this.mask && drawWidth === originalWidth && drawHeight === originalHeight) { + const data = this.getImageBytes(originalHeight * rowBytes, {}); + if (isOffscreenCanvasSupported) { + if (mustBeResized) { + return _image_resizer.ImageResizer.createImage({ + data, + kind, + width: drawWidth, + height: drawHeight, + interpolate: this.interpolate + }, this.needsDecode); + } + return this.createBitmap(kind, originalWidth, originalHeight, data); + } + imgData.kind = kind; + imgData.data = data; + if (this.needsDecode) { + (0, _util.assert)(kind === _util.ImageKind.GRAYSCALE_1BPP, "PDFImage.createImageData: The image must be grayscale."); + const buffer = imgData.data; + for (let i = 0, ii = buffer.length; i < ii; i++) { + buffer[i] ^= 0xff; + } + } + return imgData; + } + if (this.image instanceof _jpeg_stream.JpegStream && !this.smask && !this.mask && !this.needsDecode) { + let imageLength = originalHeight * rowBytes; + if (isOffscreenCanvasSupported && !mustBeResized) { + let isHandled = false; + switch (this.colorSpace.name) { + case "DeviceGray": + imageLength *= 4; + isHandled = true; + break; + case "DeviceRGB": + imageLength = imageLength / 3 * 4; + isHandled = true; + break; + case "DeviceCMYK": + isHandled = true; + break; + } + if (isHandled) { + const rgba = this.getImageBytes(imageLength, { + drawWidth, + drawHeight, + forceRGBA: true + }); + return this.createBitmap(_util.ImageKind.RGBA_32BPP, drawWidth, drawHeight, rgba); + } + } else { + switch (this.colorSpace.name) { + case "DeviceGray": + imageLength *= 3; + case "DeviceRGB": + case "DeviceCMYK": + imgData.kind = _util.ImageKind.RGB_24BPP; + imgData.data = this.getImageBytes(imageLength, { + drawWidth, + drawHeight, + forceRGB: true + }); + if (mustBeResized) { + return _image_resizer.ImageResizer.createImage(imgData); + } + return imgData; + } + } + } + } + const imgArray = this.getImageBytes(originalHeight * rowBytes, { + internal: true + }); + const actualHeight = 0 | imgArray.length / rowBytes * drawHeight / originalHeight; + const comps = this.getComponents(imgArray); + let alpha01, maybeUndoPreblend; + let canvas, ctx, canvasImgData, data; + if (isOffscreenCanvasSupported && !mustBeResized) { + canvas = new OffscreenCanvas(drawWidth, drawHeight); + ctx = canvas.getContext("2d"); + canvasImgData = ctx.createImageData(drawWidth, drawHeight); + data = canvasImgData.data; + } + imgData.kind = _util.ImageKind.RGBA_32BPP; + if (!forceRGBA && !this.smask && !this.mask) { + if (!isOffscreenCanvasSupported || mustBeResized) { + imgData.kind = _util.ImageKind.RGB_24BPP; + data = new Uint8ClampedArray(drawWidth * drawHeight * 3); + alpha01 = 0; + } else { + const arr = new Uint32Array(data.buffer); + arr.fill(_util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff); + alpha01 = 1; + } + maybeUndoPreblend = false; + } else { + if (!isOffscreenCanvasSupported || mustBeResized) { + data = new Uint8ClampedArray(drawWidth * drawHeight * 4); + } + alpha01 = 1; + maybeUndoPreblend = true; + this.fillOpacity(data, drawWidth, drawHeight, actualHeight, comps); + } + if (this.needsDecode) { + this.decodeBuffer(comps); + } + this.colorSpace.fillRgb(data, originalWidth, originalHeight, drawWidth, drawHeight, actualHeight, bpc, comps, alpha01); + if (maybeUndoPreblend) { + this.undoPreblend(data, drawWidth, actualHeight); + } + if (isOffscreenCanvasSupported && !mustBeResized) { + ctx.putImageData(canvasImgData, 0, 0); + const bitmap = canvas.transferToImageBitmap(); + return { + data: null, + width: drawWidth, + height: drawHeight, + bitmap, + interpolate: this.interpolate + }; + } + imgData.data = data; + if (mustBeResized) { + return _image_resizer.ImageResizer.createImage(imgData); + } + return imgData; + } + fillGrayBuffer(buffer) { + const numComps = this.numComps; + if (numComps !== 1) { + throw new _util.FormatError(`Reading gray scale from a color image: ${numComps}`); + } + const width = this.width; + const height = this.height; + const bpc = this.bpc; + const rowBytes = width * numComps * bpc + 7 >> 3; + const imgArray = this.getImageBytes(height * rowBytes, { + internal: true + }); + const comps = this.getComponents(imgArray); + let i, length; + if (bpc === 1) { + length = width * height; + if (this.needsDecode) { + for (i = 0; i < length; ++i) { + buffer[i] = comps[i] - 1 & 255; + } + } else { + for (i = 0; i < length; ++i) { + buffer[i] = -comps[i] & 255; + } + } + return; + } + if (this.needsDecode) { + this.decodeBuffer(comps); + } + length = width * height; + const scale = 255 / ((1 << bpc) - 1); + for (i = 0; i < length; ++i) { + buffer[i] = scale * comps[i]; + } + } + createBitmap(kind, width, height, src) { + const canvas = new OffscreenCanvas(width, height); + const ctx = canvas.getContext("2d"); + let imgData; + if (kind === _util.ImageKind.RGBA_32BPP) { + imgData = new ImageData(src, width, height); + } else { + imgData = ctx.createImageData(width, height); + (0, _image_utils.convertToRGBA)({ + kind, + src, + dest: new Uint32Array(imgData.data.buffer), + width, + height, + inverseDecode: this.needsDecode + }); + } + ctx.putImageData(imgData, 0, 0); + const bitmap = canvas.transferToImageBitmap(); + return { + data: null, + width, + height, + bitmap, + interpolate: this.interpolate + }; + } + getImageBytes(length, { + drawWidth, + drawHeight, + forceRGBA = false, + forceRGB = false, + internal = false + }) { + this.image.reset(); + this.image.drawWidth = drawWidth || this.width; + this.image.drawHeight = drawHeight || this.height; + this.image.forceRGBA = !!forceRGBA; + this.image.forceRGB = !!forceRGB; + const imageBytes = this.image.getBytes(length); + if (internal || this.image instanceof _decode_stream.DecodeStream) { + return imageBytes; + } + (0, _util.assert)(imageBytes instanceof Uint8Array, 'PDFImage.getImageBytes: Unsupported "imageBytes" type.'); + return new Uint8Array(imageBytes); + } +} +exports.PDFImage = PDFImage; + +/***/ }), +/* 66 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Catalog = void 0; +var _core_utils = __w_pdfjs_require__(3); +var _util = __w_pdfjs_require__(2); +var _primitives = __w_pdfjs_require__(4); +var _name_number_tree = __w_pdfjs_require__(67); +var _base_stream = __w_pdfjs_require__(5); +var _cleanup_helper = __w_pdfjs_require__(68); +var _colorspace = __w_pdfjs_require__(12); +var _file_spec = __w_pdfjs_require__(69); +var _image_utils = __w_pdfjs_require__(59); +var _metadata_parser = __w_pdfjs_require__(70); +var _struct_tree = __w_pdfjs_require__(72); +function fetchDestination(dest) { + if (dest instanceof _primitives.Dict) { + dest = dest.get("D"); + } + return Array.isArray(dest) ? dest : null; +} +class Catalog { + constructor(pdfManager, xref) { + this.pdfManager = pdfManager; + this.xref = xref; + this._catDict = xref.getCatalogObj(); + if (!(this._catDict instanceof _primitives.Dict)) { + throw new _util.FormatError("Catalog object is not a dictionary."); + } + this.toplevelPagesDict; + this._actualNumPages = null; + this.fontCache = new _primitives.RefSetCache(); + this.builtInCMapCache = new Map(); + this.standardFontDataCache = new Map(); + this.globalImageCache = new _image_utils.GlobalImageCache(); + this.pageKidsCountCache = new _primitives.RefSetCache(); + this.pageIndexCache = new _primitives.RefSetCache(); + this.nonBlendModesSet = new _primitives.RefSet(); + this.systemFontCache = new Map(); + } + cloneDict() { + return this._catDict.clone(); + } + get version() { + const version = this._catDict.get("Version"); + if (version instanceof _primitives.Name) { + if (_core_utils.PDF_VERSION_REGEXP.test(version.name)) { + return (0, _util.shadow)(this, "version", version.name); + } + (0, _util.warn)(`Invalid PDF catalog version: ${version.name}`); + } + return (0, _util.shadow)(this, "version", null); + } + get lang() { + const lang = this._catDict.get("Lang"); + return (0, _util.shadow)(this, "lang", typeof lang === "string" ? (0, _util.stringToPDFString)(lang) : null); + } + get needsRendering() { + const needsRendering = this._catDict.get("NeedsRendering"); + return (0, _util.shadow)(this, "needsRendering", typeof needsRendering === "boolean" ? needsRendering : false); + } + get collection() { + let collection = null; + try { + const obj = this._catDict.get("Collection"); + if (obj instanceof _primitives.Dict && obj.size > 0) { + collection = obj; + } + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.info)("Cannot fetch Collection entry; assuming no collection is present."); + } + return (0, _util.shadow)(this, "collection", collection); + } + get acroForm() { + let acroForm = null; + try { + const obj = this._catDict.get("AcroForm"); + if (obj instanceof _primitives.Dict && obj.size > 0) { + acroForm = obj; + } + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.info)("Cannot fetch AcroForm entry; assuming no forms are present."); + } + return (0, _util.shadow)(this, "acroForm", acroForm); + } + get acroFormRef() { + const value = this._catDict.getRaw("AcroForm"); + return (0, _util.shadow)(this, "acroFormRef", value instanceof _primitives.Ref ? value : null); + } + get metadata() { + const streamRef = this._catDict.getRaw("Metadata"); + if (!(streamRef instanceof _primitives.Ref)) { + return (0, _util.shadow)(this, "metadata", null); + } + let metadata = null; + try { + const stream = this.xref.fetch(streamRef, !this.xref.encrypt?.encryptMetadata); + if (stream instanceof _base_stream.BaseStream && stream.dict instanceof _primitives.Dict) { + const type = stream.dict.get("Type"); + const subtype = stream.dict.get("Subtype"); + if ((0, _primitives.isName)(type, "Metadata") && (0, _primitives.isName)(subtype, "XML")) { + const data = (0, _util.stringToUTF8String)(stream.getString()); + if (data) { + metadata = new _metadata_parser.MetadataParser(data).serializable; + } + } + } + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.info)(`Skipping invalid Metadata: "${ex}".`); + } + return (0, _util.shadow)(this, "metadata", metadata); + } + get markInfo() { + let markInfo = null; + try { + markInfo = this._readMarkInfo(); + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.warn)("Unable to read mark info."); + } + return (0, _util.shadow)(this, "markInfo", markInfo); + } + _readMarkInfo() { + const obj = this._catDict.get("MarkInfo"); + if (!(obj instanceof _primitives.Dict)) { + return null; + } + const markInfo = { + Marked: false, + UserProperties: false, + Suspects: false + }; + for (const key in markInfo) { + const value = obj.get(key); + if (typeof value === "boolean") { + markInfo[key] = value; + } + } + return markInfo; + } + get structTreeRoot() { + let structTree = null; + try { + structTree = this._readStructTreeRoot(); + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.warn)("Unable read to structTreeRoot info."); + } + return (0, _util.shadow)(this, "structTreeRoot", structTree); + } + _readStructTreeRoot() { + const rawObj = this._catDict.getRaw("StructTreeRoot"); + const obj = this.xref.fetchIfRef(rawObj); + if (!(obj instanceof _primitives.Dict)) { + return null; + } + const root = new _struct_tree.StructTreeRoot(obj, rawObj); + root.init(); + return root; + } + get toplevelPagesDict() { + const pagesObj = this._catDict.get("Pages"); + if (!(pagesObj instanceof _primitives.Dict)) { + throw new _util.FormatError("Invalid top-level pages dictionary."); + } + return (0, _util.shadow)(this, "toplevelPagesDict", pagesObj); + } + get documentOutline() { + let obj = null; + try { + obj = this._readDocumentOutline(); + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.warn)("Unable to read document outline."); + } + return (0, _util.shadow)(this, "documentOutline", obj); + } + _readDocumentOutline() { + let obj = this._catDict.get("Outlines"); + if (!(obj instanceof _primitives.Dict)) { + return null; + } + obj = obj.getRaw("First"); + if (!(obj instanceof _primitives.Ref)) { + return null; + } + const root = { + items: [] + }; + const queue = [{ + obj, + parent: root + }]; + const processed = new _primitives.RefSet(); + processed.put(obj); + const xref = this.xref, + blackColor = new Uint8ClampedArray(3); + while (queue.length > 0) { + const i = queue.shift(); + const outlineDict = xref.fetchIfRef(i.obj); + if (outlineDict === null) { + continue; + } + if (!outlineDict.has("Title")) { + throw new _util.FormatError("Invalid outline item encountered."); + } + const data = { + url: null, + dest: null, + action: null + }; + Catalog.parseDestDictionary({ + destDict: outlineDict, + resultObj: data, + docBaseUrl: this.baseUrl, + docAttachments: this.attachments + }); + const title = outlineDict.get("Title"); + const flags = outlineDict.get("F") || 0; + const color = outlineDict.getArray("C"); + const count = outlineDict.get("Count"); + let rgbColor = blackColor; + if (Array.isArray(color) && color.length === 3 && (color[0] !== 0 || color[1] !== 0 || color[2] !== 0)) { + rgbColor = _colorspace.ColorSpace.singletons.rgb.getRgb(color, 0); + } + const outlineItem = { + action: data.action, + attachment: data.attachment, + dest: data.dest, + url: data.url, + unsafeUrl: data.unsafeUrl, + newWindow: data.newWindow, + setOCGState: data.setOCGState, + title: (0, _util.stringToPDFString)(title), + color: rgbColor, + count: Number.isInteger(count) ? count : undefined, + bold: !!(flags & 2), + italic: !!(flags & 1), + items: [] + }; + i.parent.items.push(outlineItem); + obj = outlineDict.getRaw("First"); + if (obj instanceof _primitives.Ref && !processed.has(obj)) { + queue.push({ + obj, + parent: outlineItem + }); + processed.put(obj); + } + obj = outlineDict.getRaw("Next"); + if (obj instanceof _primitives.Ref && !processed.has(obj)) { + queue.push({ + obj, + parent: i.parent + }); + processed.put(obj); + } + } + return root.items.length > 0 ? root.items : null; + } + get permissions() { + let permissions = null; + try { + permissions = this._readPermissions(); + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.warn)("Unable to read permissions."); + } + return (0, _util.shadow)(this, "permissions", permissions); + } + _readPermissions() { + const encrypt = this.xref.trailer.get("Encrypt"); + if (!(encrypt instanceof _primitives.Dict)) { + return null; + } + let flags = encrypt.get("P"); + if (typeof flags !== "number") { + return null; + } + flags += 2 ** 32; + const permissions = []; + for (const key in _util.PermissionFlag) { + const value = _util.PermissionFlag[key]; + if (flags & value) { + permissions.push(value); + } + } + return permissions; + } + get optionalContentConfig() { + let config = null; + try { + const properties = this._catDict.get("OCProperties"); + if (!properties) { + return (0, _util.shadow)(this, "optionalContentConfig", null); + } + const defaultConfig = properties.get("D"); + if (!defaultConfig) { + return (0, _util.shadow)(this, "optionalContentConfig", null); + } + const groupsData = properties.get("OCGs"); + if (!Array.isArray(groupsData)) { + return (0, _util.shadow)(this, "optionalContentConfig", null); + } + const groups = []; + const groupRefs = []; + for (const groupRef of groupsData) { + if (!(groupRef instanceof _primitives.Ref)) { + continue; + } + groupRefs.push(groupRef); + const group = this.xref.fetchIfRef(groupRef); + groups.push({ + id: groupRef.toString(), + name: typeof group.get("Name") === "string" ? (0, _util.stringToPDFString)(group.get("Name")) : null, + intent: typeof group.get("Intent") === "string" ? (0, _util.stringToPDFString)(group.get("Intent")) : null + }); + } + config = this._readOptionalContentConfig(defaultConfig, groupRefs); + config.groups = groups; + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.warn)(`Unable to read optional content config: ${ex}`); + } + return (0, _util.shadow)(this, "optionalContentConfig", config); + } + _readOptionalContentConfig(config, contentGroupRefs) { + function parseOnOff(refs) { + const onParsed = []; + if (Array.isArray(refs)) { + for (const value of refs) { + if (!(value instanceof _primitives.Ref)) { + continue; + } + if (contentGroupRefs.includes(value)) { + onParsed.push(value.toString()); + } + } + } + return onParsed; + } + function parseOrder(refs, nestedLevels = 0) { + if (!Array.isArray(refs)) { + return null; + } + const order = []; + for (const value of refs) { + if (value instanceof _primitives.Ref && contentGroupRefs.includes(value)) { + parsedOrderRefs.put(value); + order.push(value.toString()); + continue; + } + const nestedOrder = parseNestedOrder(value, nestedLevels); + if (nestedOrder) { + order.push(nestedOrder); + } + } + if (nestedLevels > 0) { + return order; + } + const hiddenGroups = []; + for (const groupRef of contentGroupRefs) { + if (parsedOrderRefs.has(groupRef)) { + continue; + } + hiddenGroups.push(groupRef.toString()); + } + if (hiddenGroups.length) { + order.push({ + name: null, + order: hiddenGroups + }); + } + return order; + } + function parseNestedOrder(ref, nestedLevels) { + if (++nestedLevels > MAX_NESTED_LEVELS) { + (0, _util.warn)("parseNestedOrder - reached MAX_NESTED_LEVELS."); + return null; + } + const value = xref.fetchIfRef(ref); + if (!Array.isArray(value)) { + return null; + } + const nestedName = xref.fetchIfRef(value[0]); + if (typeof nestedName !== "string") { + return null; + } + const nestedOrder = parseOrder(value.slice(1), nestedLevels); + if (!nestedOrder || !nestedOrder.length) { + return null; + } + return { + name: (0, _util.stringToPDFString)(nestedName), + order: nestedOrder + }; + } + const xref = this.xref, + parsedOrderRefs = new _primitives.RefSet(), + MAX_NESTED_LEVELS = 10; + return { + name: typeof config.get("Name") === "string" ? (0, _util.stringToPDFString)(config.get("Name")) : null, + creator: typeof config.get("Creator") === "string" ? (0, _util.stringToPDFString)(config.get("Creator")) : null, + baseState: config.get("BaseState") instanceof _primitives.Name ? config.get("BaseState").name : null, + on: parseOnOff(config.get("ON")), + off: parseOnOff(config.get("OFF")), + order: parseOrder(config.get("Order")), + groups: null + }; + } + setActualNumPages(num = null) { + this._actualNumPages = num; + } + get hasActualNumPages() { + return this._actualNumPages !== null; + } + get _pagesCount() { + const obj = this.toplevelPagesDict.get("Count"); + if (!Number.isInteger(obj)) { + throw new _util.FormatError("Page count in top-level pages dictionary is not an integer."); + } + return (0, _util.shadow)(this, "_pagesCount", obj); + } + get numPages() { + return this.hasActualNumPages ? this._actualNumPages : this._pagesCount; + } + get destinations() { + const obj = this._readDests(), + dests = Object.create(null); + if (obj instanceof _name_number_tree.NameTree) { + for (const [key, value] of obj.getAll()) { + const dest = fetchDestination(value); + if (dest) { + dests[(0, _util.stringToPDFString)(key)] = dest; + } + } + } else if (obj instanceof _primitives.Dict) { + obj.forEach(function (key, value) { + const dest = fetchDestination(value); + if (dest) { + dests[key] = dest; + } + }); + } + return (0, _util.shadow)(this, "destinations", dests); + } + getDestination(id) { + const obj = this._readDests(); + if (obj instanceof _name_number_tree.NameTree) { + const dest = fetchDestination(obj.get(id)); + if (dest) { + return dest; + } + const allDest = this.destinations[id]; + if (allDest) { + (0, _util.warn)(`Found "${id}" at an incorrect position in the NameTree.`); + return allDest; + } + } else if (obj instanceof _primitives.Dict) { + const dest = fetchDestination(obj.get(id)); + if (dest) { + return dest; + } + } + return null; + } + _readDests() { + const obj = this._catDict.get("Names"); + if (obj?.has("Dests")) { + return new _name_number_tree.NameTree(obj.getRaw("Dests"), this.xref); + } else if (this._catDict.has("Dests")) { + return this._catDict.get("Dests"); + } + return undefined; + } + get pageLabels() { + let obj = null; + try { + obj = this._readPageLabels(); + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.warn)("Unable to read page labels."); + } + return (0, _util.shadow)(this, "pageLabels", obj); + } + _readPageLabels() { + const obj = this._catDict.getRaw("PageLabels"); + if (!obj) { + return null; + } + const pageLabels = new Array(this.numPages); + let style = null, + prefix = ""; + const numberTree = new _name_number_tree.NumberTree(obj, this.xref); + const nums = numberTree.getAll(); + let currentLabel = "", + currentIndex = 1; + for (let i = 0, ii = this.numPages; i < ii; i++) { + const labelDict = nums.get(i); + if (labelDict !== undefined) { + if (!(labelDict instanceof _primitives.Dict)) { + throw new _util.FormatError("PageLabel is not a dictionary."); + } + if (labelDict.has("Type") && !(0, _primitives.isName)(labelDict.get("Type"), "PageLabel")) { + throw new _util.FormatError("Invalid type in PageLabel dictionary."); + } + if (labelDict.has("S")) { + const s = labelDict.get("S"); + if (!(s instanceof _primitives.Name)) { + throw new _util.FormatError("Invalid style in PageLabel dictionary."); + } + style = s.name; + } else { + style = null; + } + if (labelDict.has("P")) { + const p = labelDict.get("P"); + if (typeof p !== "string") { + throw new _util.FormatError("Invalid prefix in PageLabel dictionary."); + } + prefix = (0, _util.stringToPDFString)(p); + } else { + prefix = ""; + } + if (labelDict.has("St")) { + const st = labelDict.get("St"); + if (!(Number.isInteger(st) && st >= 1)) { + throw new _util.FormatError("Invalid start in PageLabel dictionary."); + } + currentIndex = st; + } else { + currentIndex = 1; + } + } + switch (style) { + case "D": + currentLabel = currentIndex; + break; + case "R": + case "r": + currentLabel = (0, _core_utils.toRomanNumerals)(currentIndex, style === "r"); + break; + case "A": + case "a": + const LIMIT = 26; + const A_UPPER_CASE = 0x41, + A_LOWER_CASE = 0x61; + const baseCharCode = style === "a" ? A_LOWER_CASE : A_UPPER_CASE; + const letterIndex = currentIndex - 1; + const character = String.fromCharCode(baseCharCode + letterIndex % LIMIT); + currentLabel = character.repeat(Math.floor(letterIndex / LIMIT) + 1); + break; + default: + if (style) { + throw new _util.FormatError(`Invalid style "${style}" in PageLabel dictionary.`); + } + currentLabel = ""; + } + pageLabels[i] = prefix + currentLabel; + currentIndex++; + } + return pageLabels; + } + get pageLayout() { + const obj = this._catDict.get("PageLayout"); + let pageLayout = ""; + if (obj instanceof _primitives.Name) { + switch (obj.name) { + case "SinglePage": + case "OneColumn": + case "TwoColumnLeft": + case "TwoColumnRight": + case "TwoPageLeft": + case "TwoPageRight": + pageLayout = obj.name; + } + } + return (0, _util.shadow)(this, "pageLayout", pageLayout); + } + get pageMode() { + const obj = this._catDict.get("PageMode"); + let pageMode = "UseNone"; + if (obj instanceof _primitives.Name) { + switch (obj.name) { + case "UseNone": + case "UseOutlines": + case "UseThumbs": + case "FullScreen": + case "UseOC": + case "UseAttachments": + pageMode = obj.name; + } + } + return (0, _util.shadow)(this, "pageMode", pageMode); + } + get viewerPreferences() { + const obj = this._catDict.get("ViewerPreferences"); + if (!(obj instanceof _primitives.Dict)) { + return (0, _util.shadow)(this, "viewerPreferences", null); + } + let prefs = null; + for (const key of obj.getKeys()) { + const value = obj.get(key); + let prefValue; + switch (key) { + case "HideToolbar": + case "HideMenubar": + case "HideWindowUI": + case "FitWindow": + case "CenterWindow": + case "DisplayDocTitle": + case "PickTrayByPDFSize": + if (typeof value === "boolean") { + prefValue = value; + } + break; + case "NonFullScreenPageMode": + if (value instanceof _primitives.Name) { + switch (value.name) { + case "UseNone": + case "UseOutlines": + case "UseThumbs": + case "UseOC": + prefValue = value.name; + break; + default: + prefValue = "UseNone"; + } + } + break; + case "Direction": + if (value instanceof _primitives.Name) { + switch (value.name) { + case "L2R": + case "R2L": + prefValue = value.name; + break; + default: + prefValue = "L2R"; + } + } + break; + case "ViewArea": + case "ViewClip": + case "PrintArea": + case "PrintClip": + if (value instanceof _primitives.Name) { + switch (value.name) { + case "MediaBox": + case "CropBox": + case "BleedBox": + case "TrimBox": + case "ArtBox": + prefValue = value.name; + break; + default: + prefValue = "CropBox"; + } + } + break; + case "PrintScaling": + if (value instanceof _primitives.Name) { + switch (value.name) { + case "None": + case "AppDefault": + prefValue = value.name; + break; + default: + prefValue = "AppDefault"; + } + } + break; + case "Duplex": + if (value instanceof _primitives.Name) { + switch (value.name) { + case "Simplex": + case "DuplexFlipShortEdge": + case "DuplexFlipLongEdge": + prefValue = value.name; + break; + default: + prefValue = "None"; + } + } + break; + case "PrintPageRange": + if (Array.isArray(value) && value.length % 2 === 0) { + const isValid = value.every((page, i, arr) => { + return Number.isInteger(page) && page > 0 && (i === 0 || page >= arr[i - 1]) && page <= this.numPages; + }); + if (isValid) { + prefValue = value; + } + } + break; + case "NumCopies": + if (Number.isInteger(value) && value > 0) { + prefValue = value; + } + break; + default: + (0, _util.warn)(`Ignoring non-standard key in ViewerPreferences: ${key}.`); + continue; + } + if (prefValue === undefined) { + (0, _util.warn)(`Bad value, for key "${key}", in ViewerPreferences: ${value}.`); + continue; + } + if (!prefs) { + prefs = Object.create(null); + } + prefs[key] = prefValue; + } + return (0, _util.shadow)(this, "viewerPreferences", prefs); + } + get openAction() { + const obj = this._catDict.get("OpenAction"); + const openAction = Object.create(null); + if (obj instanceof _primitives.Dict) { + const destDict = new _primitives.Dict(this.xref); + destDict.set("A", obj); + const resultObj = { + url: null, + dest: null, + action: null + }; + Catalog.parseDestDictionary({ + destDict, + resultObj + }); + if (Array.isArray(resultObj.dest)) { + openAction.dest = resultObj.dest; + } else if (resultObj.action) { + openAction.action = resultObj.action; + } + } else if (Array.isArray(obj)) { + openAction.dest = obj; + } + return (0, _util.shadow)(this, "openAction", (0, _util.objectSize)(openAction) > 0 ? openAction : null); + } + get attachments() { + const obj = this._catDict.get("Names"); + let attachments = null; + if (obj instanceof _primitives.Dict && obj.has("EmbeddedFiles")) { + const nameTree = new _name_number_tree.NameTree(obj.getRaw("EmbeddedFiles"), this.xref); + for (const [key, value] of nameTree.getAll()) { + const fs = new _file_spec.FileSpec(value, this.xref); + if (!attachments) { + attachments = Object.create(null); + } + attachments[(0, _util.stringToPDFString)(key)] = fs.serializable; + } + } + return (0, _util.shadow)(this, "attachments", attachments); + } + get xfaImages() { + const obj = this._catDict.get("Names"); + let xfaImages = null; + if (obj instanceof _primitives.Dict && obj.has("XFAImages")) { + const nameTree = new _name_number_tree.NameTree(obj.getRaw("XFAImages"), this.xref); + for (const [key, value] of nameTree.getAll()) { + if (!xfaImages) { + xfaImages = new _primitives.Dict(this.xref); + } + xfaImages.set((0, _util.stringToPDFString)(key), value); + } + } + return (0, _util.shadow)(this, "xfaImages", xfaImages); + } + _collectJavaScript() { + const obj = this._catDict.get("Names"); + let javaScript = null; + function appendIfJavaScriptDict(name, jsDict) { + if (!(jsDict instanceof _primitives.Dict)) { + return; + } + if (!(0, _primitives.isName)(jsDict.get("S"), "JavaScript")) { + return; + } + let js = jsDict.get("JS"); + if (js instanceof _base_stream.BaseStream) { + js = js.getString(); + } else if (typeof js !== "string") { + return; + } + js = (0, _util.stringToPDFString)(js).replaceAll("\x00", ""); + if (js) { + (javaScript ||= new Map()).set(name, js); + } + } + if (obj instanceof _primitives.Dict && obj.has("JavaScript")) { + const nameTree = new _name_number_tree.NameTree(obj.getRaw("JavaScript"), this.xref); + for (const [key, value] of nameTree.getAll()) { + appendIfJavaScriptDict((0, _util.stringToPDFString)(key), value); + } + } + const openAction = this._catDict.get("OpenAction"); + if (openAction) { + appendIfJavaScriptDict("OpenAction", openAction); + } + return javaScript; + } + get jsActions() { + const javaScript = this._collectJavaScript(); + let actions = (0, _core_utils.collectActions)(this.xref, this._catDict, _util.DocumentActionEventType); + if (javaScript) { + actions ||= Object.create(null); + for (const [key, val] of javaScript) { + if (key in actions) { + actions[key].push(val); + } else { + actions[key] = [val]; + } + } + } + return (0, _util.shadow)(this, "jsActions", actions); + } + async fontFallback(id, handler) { + const translatedFonts = await Promise.all(this.fontCache); + for (const translatedFont of translatedFonts) { + if (translatedFont.loadedName === id) { + translatedFont.fallback(handler); + return; + } + } + } + async cleanup(manuallyTriggered = false) { + (0, _cleanup_helper.clearGlobalCaches)(); + this.globalImageCache.clear(manuallyTriggered); + this.pageKidsCountCache.clear(); + this.pageIndexCache.clear(); + this.nonBlendModesSet.clear(); + const translatedFonts = await Promise.all(this.fontCache); + for (const { + dict + } of translatedFonts) { + delete dict.cacheKey; + } + this.fontCache.clear(); + this.builtInCMapCache.clear(); + this.standardFontDataCache.clear(); + this.systemFontCache.clear(); + } + async getPageDict(pageIndex) { + const nodesToVisit = [this.toplevelPagesDict]; + const visitedNodes = new _primitives.RefSet(); + const pagesRef = this._catDict.getRaw("Pages"); + if (pagesRef instanceof _primitives.Ref) { + visitedNodes.put(pagesRef); + } + const xref = this.xref, + pageKidsCountCache = this.pageKidsCountCache, + pageIndexCache = this.pageIndexCache; + let currentPageIndex = 0; + while (nodesToVisit.length) { + const currentNode = nodesToVisit.pop(); + if (currentNode instanceof _primitives.Ref) { + const count = pageKidsCountCache.get(currentNode); + if (count >= 0 && currentPageIndex + count <= pageIndex) { + currentPageIndex += count; + continue; + } + if (visitedNodes.has(currentNode)) { + throw new _util.FormatError("Pages tree contains circular reference."); + } + visitedNodes.put(currentNode); + const obj = await xref.fetchAsync(currentNode); + if (obj instanceof _primitives.Dict) { + let type = obj.getRaw("Type"); + if (type instanceof _primitives.Ref) { + type = await xref.fetchAsync(type); + } + if ((0, _primitives.isName)(type, "Page") || !obj.has("Kids")) { + if (!pageKidsCountCache.has(currentNode)) { + pageKidsCountCache.put(currentNode, 1); + } + if (!pageIndexCache.has(currentNode)) { + pageIndexCache.put(currentNode, currentPageIndex); + } + if (currentPageIndex === pageIndex) { + return [obj, currentNode]; + } + currentPageIndex++; + continue; + } + } + nodesToVisit.push(obj); + continue; + } + if (!(currentNode instanceof _primitives.Dict)) { + throw new _util.FormatError("Page dictionary kid reference points to wrong type of object."); + } + const { + objId + } = currentNode; + let count = currentNode.getRaw("Count"); + if (count instanceof _primitives.Ref) { + count = await xref.fetchAsync(count); + } + if (Number.isInteger(count) && count >= 0) { + if (objId && !pageKidsCountCache.has(objId)) { + pageKidsCountCache.put(objId, count); + } + if (currentPageIndex + count <= pageIndex) { + currentPageIndex += count; + continue; + } + } + let kids = currentNode.getRaw("Kids"); + if (kids instanceof _primitives.Ref) { + kids = await xref.fetchAsync(kids); + } + if (!Array.isArray(kids)) { + let type = currentNode.getRaw("Type"); + if (type instanceof _primitives.Ref) { + type = await xref.fetchAsync(type); + } + if ((0, _primitives.isName)(type, "Page") || !currentNode.has("Kids")) { + if (currentPageIndex === pageIndex) { + return [currentNode, null]; + } + currentPageIndex++; + continue; + } + throw new _util.FormatError("Page dictionary kids object is not an array."); + } + for (let last = kids.length - 1; last >= 0; last--) { + nodesToVisit.push(kids[last]); + } + } + throw new Error(`Page index ${pageIndex} not found.`); + } + async getAllPageDicts(recoveryMode = false) { + const { + ignoreErrors + } = this.pdfManager.evaluatorOptions; + const queue = [{ + currentNode: this.toplevelPagesDict, + posInKids: 0 + }]; + const visitedNodes = new _primitives.RefSet(); + const pagesRef = this._catDict.getRaw("Pages"); + if (pagesRef instanceof _primitives.Ref) { + visitedNodes.put(pagesRef); + } + const map = new Map(), + xref = this.xref, + pageIndexCache = this.pageIndexCache; + let pageIndex = 0; + function addPageDict(pageDict, pageRef) { + if (pageRef && !pageIndexCache.has(pageRef)) { + pageIndexCache.put(pageRef, pageIndex); + } + map.set(pageIndex++, [pageDict, pageRef]); + } + function addPageError(error) { + if (error instanceof _core_utils.XRefEntryException && !recoveryMode) { + throw error; + } + if (recoveryMode && ignoreErrors && pageIndex === 0) { + (0, _util.warn)(`getAllPageDicts - Skipping invalid first page: "${error}".`); + error = _primitives.Dict.empty; + } + map.set(pageIndex++, [error, null]); + } + while (queue.length > 0) { + const queueItem = queue.at(-1); + const { + currentNode, + posInKids + } = queueItem; + let kids = currentNode.getRaw("Kids"); + if (kids instanceof _primitives.Ref) { + try { + kids = await xref.fetchAsync(kids); + } catch (ex) { + addPageError(ex); + break; + } + } + if (!Array.isArray(kids)) { + addPageError(new _util.FormatError("Page dictionary kids object is not an array.")); + break; + } + if (posInKids >= kids.length) { + queue.pop(); + continue; + } + const kidObj = kids[posInKids]; + let obj; + if (kidObj instanceof _primitives.Ref) { + if (visitedNodes.has(kidObj)) { + addPageError(new _util.FormatError("Pages tree contains circular reference.")); + break; + } + visitedNodes.put(kidObj); + try { + obj = await xref.fetchAsync(kidObj); + } catch (ex) { + addPageError(ex); + break; + } + } else { + obj = kidObj; + } + if (!(obj instanceof _primitives.Dict)) { + addPageError(new _util.FormatError("Page dictionary kid reference points to wrong type of object.")); + break; + } + let type = obj.getRaw("Type"); + if (type instanceof _primitives.Ref) { + try { + type = await xref.fetchAsync(type); + } catch (ex) { + addPageError(ex); + break; + } + } + if ((0, _primitives.isName)(type, "Page") || !obj.has("Kids")) { + addPageDict(obj, kidObj instanceof _primitives.Ref ? kidObj : null); + } else { + queue.push({ + currentNode: obj, + posInKids: 0 + }); + } + queueItem.posInKids++; + } + return map; + } + getPageIndex(pageRef) { + const cachedPageIndex = this.pageIndexCache.get(pageRef); + if (cachedPageIndex !== undefined) { + return Promise.resolve(cachedPageIndex); + } + const xref = this.xref; + function pagesBeforeRef(kidRef) { + let total = 0, + parentRef; + return xref.fetchAsync(kidRef).then(function (node) { + if ((0, _primitives.isRefsEqual)(kidRef, pageRef) && !(0, _primitives.isDict)(node, "Page") && !(node instanceof _primitives.Dict && !node.has("Type") && node.has("Contents"))) { + throw new _util.FormatError("The reference does not point to a /Page dictionary."); + } + if (!node) { + return null; + } + if (!(node instanceof _primitives.Dict)) { + throw new _util.FormatError("Node must be a dictionary."); + } + parentRef = node.getRaw("Parent"); + return node.getAsync("Parent"); + }).then(function (parent) { + if (!parent) { + return null; + } + if (!(parent instanceof _primitives.Dict)) { + throw new _util.FormatError("Parent must be a dictionary."); + } + return parent.getAsync("Kids"); + }).then(function (kids) { + if (!kids) { + return null; + } + const kidPromises = []; + let found = false; + for (const kid of kids) { + if (!(kid instanceof _primitives.Ref)) { + throw new _util.FormatError("Kid must be a reference."); + } + if ((0, _primitives.isRefsEqual)(kid, kidRef)) { + found = true; + break; + } + kidPromises.push(xref.fetchAsync(kid).then(function (obj) { + if (!(obj instanceof _primitives.Dict)) { + throw new _util.FormatError("Kid node must be a dictionary."); + } + if (obj.has("Count")) { + total += obj.get("Count"); + } else { + total++; + } + })); + } + if (!found) { + throw new _util.FormatError("Kid reference not found in parent's kids."); + } + return Promise.all(kidPromises).then(function () { + return [total, parentRef]; + }); + }); + } + let total = 0; + const next = ref => pagesBeforeRef(ref).then(args => { + if (!args) { + this.pageIndexCache.put(pageRef, total); + return total; + } + const [count, parentRef] = args; + total += count; + return next(parentRef); + }); + return next(pageRef); + } + get baseUrl() { + const uri = this._catDict.get("URI"); + if (uri instanceof _primitives.Dict) { + const base = uri.get("Base"); + if (typeof base === "string") { + const absoluteUrl = (0, _util.createValidAbsoluteUrl)(base, null, { + tryConvertEncoding: true + }); + if (absoluteUrl) { + return (0, _util.shadow)(this, "baseUrl", absoluteUrl.href); + } + } + } + return (0, _util.shadow)(this, "baseUrl", this.pdfManager.docBaseUrl); + } + static parseDestDictionary({ + destDict, + resultObj, + docBaseUrl = null, + docAttachments = null + }) { + if (!(destDict instanceof _primitives.Dict)) { + (0, _util.warn)("parseDestDictionary: `destDict` must be a dictionary."); + return; + } + let action = destDict.get("A"), + url, + dest; + if (!(action instanceof _primitives.Dict)) { + if (destDict.has("Dest")) { + action = destDict.get("Dest"); + } else { + action = destDict.get("AA"); + if (action instanceof _primitives.Dict) { + if (action.has("D")) { + action = action.get("D"); + } else if (action.has("U")) { + action = action.get("U"); + } + } + } + } + if (action instanceof _primitives.Dict) { + const actionType = action.get("S"); + if (!(actionType instanceof _primitives.Name)) { + (0, _util.warn)("parseDestDictionary: Invalid type in Action dictionary."); + return; + } + const actionName = actionType.name; + switch (actionName) { + case "ResetForm": + const flags = action.get("Flags"); + const include = ((typeof flags === "number" ? flags : 0) & 1) === 0; + const fields = []; + const refs = []; + for (const obj of action.get("Fields") || []) { + if (obj instanceof _primitives.Ref) { + refs.push(obj.toString()); + } else if (typeof obj === "string") { + fields.push((0, _util.stringToPDFString)(obj)); + } + } + resultObj.resetForm = { + fields, + refs, + include + }; + break; + case "URI": + url = action.get("URI"); + if (url instanceof _primitives.Name) { + url = "/" + url.name; + } + break; + case "GoTo": + dest = action.get("D"); + break; + case "Launch": + case "GoToR": + const urlDict = action.get("F"); + if (urlDict instanceof _primitives.Dict) { + url = urlDict.get("F") || null; + } else if (typeof urlDict === "string") { + url = urlDict; + } + let remoteDest = action.get("D"); + if (remoteDest) { + if (remoteDest instanceof _primitives.Name) { + remoteDest = remoteDest.name; + } + if (typeof url === "string") { + const baseUrl = url.split("#")[0]; + if (typeof remoteDest === "string") { + url = baseUrl + "#" + remoteDest; + } else if (Array.isArray(remoteDest)) { + url = baseUrl + "#" + JSON.stringify(remoteDest); + } + } + } + const newWindow = action.get("NewWindow"); + if (typeof newWindow === "boolean") { + resultObj.newWindow = newWindow; + } + break; + case "GoToE": + const target = action.get("T"); + let attachment; + if (docAttachments && target instanceof _primitives.Dict) { + const relationship = target.get("R"); + const name = target.get("N"); + if ((0, _primitives.isName)(relationship, "C") && typeof name === "string") { + attachment = docAttachments[(0, _util.stringToPDFString)(name)]; + } + } + if (attachment) { + resultObj.attachment = attachment; + } else { + (0, _util.warn)(`parseDestDictionary - unimplemented "GoToE" action.`); + } + break; + case "Named": + const namedAction = action.get("N"); + if (namedAction instanceof _primitives.Name) { + resultObj.action = namedAction.name; + } + break; + case "SetOCGState": + const state = action.get("State"); + const preserveRB = action.get("PreserveRB"); + if (!Array.isArray(state) || state.length === 0) { + break; + } + const stateArr = []; + for (const elem of state) { + if (elem instanceof _primitives.Name) { + switch (elem.name) { + case "ON": + case "OFF": + case "Toggle": + stateArr.push(elem.name); + break; + } + } else if (elem instanceof _primitives.Ref) { + stateArr.push(elem.toString()); + } + } + if (stateArr.length !== state.length) { + break; + } + resultObj.setOCGState = { + state: stateArr, + preserveRB: typeof preserveRB === "boolean" ? preserveRB : true + }; + break; + case "JavaScript": + const jsAction = action.get("JS"); + let js; + if (jsAction instanceof _base_stream.BaseStream) { + js = jsAction.getString(); + } else if (typeof jsAction === "string") { + js = jsAction; + } + const jsURL = js && (0, _core_utils.recoverJsURL)((0, _util.stringToPDFString)(js)); + if (jsURL) { + url = jsURL.url; + resultObj.newWindow = jsURL.newWindow; + break; + } + default: + if (actionName === "JavaScript" || actionName === "SubmitForm") { + break; + } + (0, _util.warn)(`parseDestDictionary - unsupported action: "${actionName}".`); + break; + } + } else if (destDict.has("Dest")) { + dest = destDict.get("Dest"); + } + if (typeof url === "string") { + const absoluteUrl = (0, _util.createValidAbsoluteUrl)(url, docBaseUrl, { + addDefaultProtocol: true, + tryConvertEncoding: true + }); + if (absoluteUrl) { + resultObj.url = absoluteUrl.href; + } + resultObj.unsafeUrl = url; + } + if (dest) { + if (dest instanceof _primitives.Name) { + dest = dest.name; + } + if (typeof dest === "string") { + resultObj.dest = (0, _util.stringToPDFString)(dest); + } else if (Array.isArray(dest)) { + resultObj.dest = dest; + } + } + } +} +exports.Catalog = Catalog; + +/***/ }), +/* 67 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.NumberTree = exports.NameTree = void 0; +var _primitives = __w_pdfjs_require__(4); +var _util = __w_pdfjs_require__(2); +class NameOrNumberTree { + constructor(root, xref, type) { + if (this.constructor === NameOrNumberTree) { + (0, _util.unreachable)("Cannot initialize NameOrNumberTree."); + } + this.root = root; + this.xref = xref; + this._type = type; + } + getAll() { + const map = new Map(); + if (!this.root) { + return map; + } + const xref = this.xref; + const processed = new _primitives.RefSet(); + processed.put(this.root); + const queue = [this.root]; + while (queue.length > 0) { + const obj = xref.fetchIfRef(queue.shift()); + if (!(obj instanceof _primitives.Dict)) { + continue; + } + if (obj.has("Kids")) { + const kids = obj.get("Kids"); + if (!Array.isArray(kids)) { + continue; + } + for (const kid of kids) { + if (processed.has(kid)) { + throw new _util.FormatError(`Duplicate entry in "${this._type}" tree.`); + } + queue.push(kid); + processed.put(kid); + } + continue; + } + const entries = obj.get(this._type); + if (!Array.isArray(entries)) { + continue; + } + for (let i = 0, ii = entries.length; i < ii; i += 2) { + map.set(xref.fetchIfRef(entries[i]), xref.fetchIfRef(entries[i + 1])); + } + } + return map; + } + get(key) { + if (!this.root) { + return null; + } + const xref = this.xref; + let kidsOrEntries = xref.fetchIfRef(this.root); + let loopCount = 0; + const MAX_LEVELS = 10; + while (kidsOrEntries.has("Kids")) { + if (++loopCount > MAX_LEVELS) { + (0, _util.warn)(`Search depth limit reached for "${this._type}" tree.`); + return null; + } + const kids = kidsOrEntries.get("Kids"); + if (!Array.isArray(kids)) { + return null; + } + let l = 0, + r = kids.length - 1; + while (l <= r) { + const m = l + r >> 1; + const kid = xref.fetchIfRef(kids[m]); + const limits = kid.get("Limits"); + if (key < xref.fetchIfRef(limits[0])) { + r = m - 1; + } else if (key > xref.fetchIfRef(limits[1])) { + l = m + 1; + } else { + kidsOrEntries = kid; + break; + } + } + if (l > r) { + return null; + } + } + const entries = kidsOrEntries.get(this._type); + if (Array.isArray(entries)) { + let l = 0, + r = entries.length - 2; + while (l <= r) { + const tmp = l + r >> 1, + m = tmp + (tmp & 1); + const currentKey = xref.fetchIfRef(entries[m]); + if (key < currentKey) { + r = m - 2; + } else if (key > currentKey) { + l = m + 2; + } else { + return xref.fetchIfRef(entries[m + 1]); + } + } + } + return null; + } +} +class NameTree extends NameOrNumberTree { + constructor(root, xref) { + super(root, xref, "Names"); + } +} +exports.NameTree = NameTree; +class NumberTree extends NameOrNumberTree { + constructor(root, xref) { + super(root, xref, "Nums"); + } +} +exports.NumberTree = NumberTree; + +/***/ }), +/* 68 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.clearGlobalCaches = clearGlobalCaches; +var _pattern = __w_pdfjs_require__(50); +var _primitives = __w_pdfjs_require__(4); +var _unicode = __w_pdfjs_require__(40); +function clearGlobalCaches() { + (0, _pattern.clearPatternCaches)(); + (0, _primitives.clearPrimitiveCaches)(); + (0, _unicode.clearUnicodeCaches)(); +} + +/***/ }), +/* 69 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.FileSpec = void 0; +var _util = __w_pdfjs_require__(2); +var _base_stream = __w_pdfjs_require__(5); +var _primitives = __w_pdfjs_require__(4); +function pickPlatformItem(dict) { + if (dict.has("UF")) { + return dict.get("UF"); + } else if (dict.has("F")) { + return dict.get("F"); + } else if (dict.has("Unix")) { + return dict.get("Unix"); + } else if (dict.has("Mac")) { + return dict.get("Mac"); + } else if (dict.has("DOS")) { + return dict.get("DOS"); + } + return null; +} +class FileSpec { + constructor(root, xref) { + if (!(root instanceof _primitives.Dict)) { + return; + } + this.xref = xref; + this.root = root; + if (root.has("FS")) { + this.fs = root.get("FS"); + } + this.description = root.has("Desc") ? (0, _util.stringToPDFString)(root.get("Desc")) : ""; + if (root.has("RF")) { + (0, _util.warn)("Related file specifications are not supported"); + } + this.contentAvailable = true; + if (!root.has("EF")) { + this.contentAvailable = false; + (0, _util.warn)("Non-embedded file specifications are not supported"); + } + } + get filename() { + if (!this._filename && this.root) { + const filename = pickPlatformItem(this.root) || "unnamed"; + this._filename = (0, _util.stringToPDFString)(filename).replaceAll("\\\\", "\\").replaceAll("\\/", "/").replaceAll("\\", "/"); + } + return this._filename; + } + get content() { + if (!this.contentAvailable) { + return null; + } + if (!this.contentRef && this.root) { + this.contentRef = pickPlatformItem(this.root.get("EF")); + } + let content = null; + if (this.contentRef) { + const fileObj = this.xref.fetchIfRef(this.contentRef); + if (fileObj instanceof _base_stream.BaseStream) { + content = fileObj.getBytes(); + } else { + (0, _util.warn)("Embedded file specification points to non-existing/invalid content"); + } + } else { + (0, _util.warn)("Embedded file specification does not have a content"); + } + return content; + } + get serializable() { + return { + filename: this.filename, + content: this.content + }; + } +} +exports.FileSpec = FileSpec; + +/***/ }), +/* 70 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.MetadataParser = void 0; +var _xml_parser = __w_pdfjs_require__(71); +class MetadataParser { + constructor(data) { + data = this._repair(data); + const parser = new _xml_parser.SimpleXMLParser({ + lowerCaseName: true + }); + const xmlDocument = parser.parseFromString(data); + this._metadataMap = new Map(); + this._data = data; + if (xmlDocument) { + this._parse(xmlDocument); + } + } + _repair(data) { + return data.replace(/^[^<]+/, "").replaceAll(/>\\376\\377([^<]+)/g, function (all, codes) { + const bytes = codes.replaceAll(/\\([0-3])([0-7])([0-7])/g, function (code, d1, d2, d3) { + return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1); + }).replaceAll(/&(amp|apos|gt|lt|quot);/g, function (str, name) { + switch (name) { + case "amp": + return "&"; + case "apos": + return "'"; + case "gt": + return ">"; + case "lt": + return "<"; + case "quot": + return '"'; + } + throw new Error(`_repair: ${name} isn't defined.`); + }); + const charBuf = [">"]; + for (let i = 0, ii = bytes.length; i < ii; i += 2) { + const code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1); + if (code >= 32 && code < 127 && code !== 60 && code !== 62 && code !== 38) { + charBuf.push(String.fromCharCode(code)); + } else { + charBuf.push("&#x" + (0x10000 + code).toString(16).substring(1) + ";"); + } + } + return charBuf.join(""); + }); + } + _getSequence(entry) { + const name = entry.nodeName; + if (name !== "rdf:bag" && name !== "rdf:seq" && name !== "rdf:alt") { + return null; + } + return entry.childNodes.filter(node => node.nodeName === "rdf:li"); + } + _parseArray(entry) { + if (!entry.hasChildNodes()) { + return; + } + const [seqNode] = entry.childNodes; + const sequence = this._getSequence(seqNode) || []; + this._metadataMap.set(entry.nodeName, sequence.map(node => node.textContent.trim())); + } + _parse(xmlDocument) { + let rdf = xmlDocument.documentElement; + if (rdf.nodeName !== "rdf:rdf") { + rdf = rdf.firstChild; + while (rdf && rdf.nodeName !== "rdf:rdf") { + rdf = rdf.nextSibling; + } + } + if (!rdf || rdf.nodeName !== "rdf:rdf" || !rdf.hasChildNodes()) { + return; + } + for (const desc of rdf.childNodes) { + if (desc.nodeName !== "rdf:description") { + continue; + } + for (const entry of desc.childNodes) { + const name = entry.nodeName; + switch (name) { + case "#text": + continue; + case "dc:creator": + case "dc:subject": + this._parseArray(entry); + continue; + } + this._metadataMap.set(name, entry.textContent.trim()); + } + } + } + get serializable() { + return { + parsedData: this._metadataMap, + rawData: this._data + }; + } +} +exports.MetadataParser = MetadataParser; + +/***/ }), +/* 71 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.XMLParserErrorCode = exports.XMLParserBase = exports.SimpleXMLParser = exports.SimpleDOMNode = void 0; +var _core_utils = __w_pdfjs_require__(3); +const XMLParserErrorCode = { + NoError: 0, + EndOfDocument: -1, + UnterminatedCdat: -2, + UnterminatedXmlDeclaration: -3, + UnterminatedDoctypeDeclaration: -4, + UnterminatedComment: -5, + MalformedElement: -6, + OutOfMemory: -7, + UnterminatedAttributeValue: -8, + UnterminatedElement: -9, + ElementNeverBegun: -10 +}; +exports.XMLParserErrorCode = XMLParserErrorCode; +function isWhitespace(s, index) { + const ch = s[index]; + return ch === " " || ch === "\n" || ch === "\r" || ch === "\t"; +} +function isWhitespaceString(s) { + for (let i = 0, ii = s.length; i < ii; i++) { + if (!isWhitespace(s, i)) { + return false; + } + } + return true; +} +class XMLParserBase { + _resolveEntities(s) { + return s.replaceAll(/&([^;]+);/g, (all, entity) => { + if (entity.substring(0, 2) === "#x") { + return String.fromCodePoint(parseInt(entity.substring(2), 16)); + } else if (entity.substring(0, 1) === "#") { + return String.fromCodePoint(parseInt(entity.substring(1), 10)); + } + switch (entity) { + case "lt": + return "<"; + case "gt": + return ">"; + case "amp": + return "&"; + case "quot": + return '"'; + case "apos": + return "'"; + } + return this.onResolveEntity(entity); + }); + } + _parseContent(s, start) { + const attributes = []; + let pos = start; + function skipWs() { + while (pos < s.length && isWhitespace(s, pos)) { + ++pos; + } + } + while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== ">" && s[pos] !== "/") { + ++pos; + } + const name = s.substring(start, pos); + skipWs(); + while (pos < s.length && s[pos] !== ">" && s[pos] !== "/" && s[pos] !== "?") { + skipWs(); + let attrName = "", + attrValue = ""; + while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== "=") { + attrName += s[pos]; + ++pos; + } + skipWs(); + if (s[pos] !== "=") { + return null; + } + ++pos; + skipWs(); + const attrEndChar = s[pos]; + if (attrEndChar !== '"' && attrEndChar !== "'") { + return null; + } + const attrEndIndex = s.indexOf(attrEndChar, ++pos); + if (attrEndIndex < 0) { + return null; + } + attrValue = s.substring(pos, attrEndIndex); + attributes.push({ + name: attrName, + value: this._resolveEntities(attrValue) + }); + pos = attrEndIndex + 1; + skipWs(); + } + return { + name, + attributes, + parsed: pos - start + }; + } + _parseProcessingInstruction(s, start) { + let pos = start; + function skipWs() { + while (pos < s.length && isWhitespace(s, pos)) { + ++pos; + } + } + while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== ">" && s[pos] !== "?" && s[pos] !== "/") { + ++pos; + } + const name = s.substring(start, pos); + skipWs(); + const attrStart = pos; + while (pos < s.length && (s[pos] !== "?" || s[pos + 1] !== ">")) { + ++pos; + } + const value = s.substring(attrStart, pos); + return { + name, + value, + parsed: pos - start + }; + } + parseXml(s) { + let i = 0; + while (i < s.length) { + const ch = s[i]; + let j = i; + if (ch === "<") { + ++j; + const ch2 = s[j]; + let q; + switch (ch2) { + case "/": + ++j; + q = s.indexOf(">", j); + if (q < 0) { + this.onError(XMLParserErrorCode.UnterminatedElement); + return; + } + this.onEndElement(s.substring(j, q)); + j = q + 1; + break; + case "?": + ++j; + const pi = this._parseProcessingInstruction(s, j); + if (s.substring(j + pi.parsed, j + pi.parsed + 2) !== "?>") { + this.onError(XMLParserErrorCode.UnterminatedXmlDeclaration); + return; + } + this.onPi(pi.name, pi.value); + j += pi.parsed + 2; + break; + case "!": + if (s.substring(j + 1, j + 3) === "--") { + q = s.indexOf("-->", j + 3); + if (q < 0) { + this.onError(XMLParserErrorCode.UnterminatedComment); + return; + } + this.onComment(s.substring(j + 3, q)); + j = q + 3; + } else if (s.substring(j + 1, j + 8) === "[CDATA[") { + q = s.indexOf("]]>", j + 8); + if (q < 0) { + this.onError(XMLParserErrorCode.UnterminatedCdat); + return; + } + this.onCdata(s.substring(j + 8, q)); + j = q + 3; + } else if (s.substring(j + 1, j + 8) === "DOCTYPE") { + const q2 = s.indexOf("[", j + 8); + let complexDoctype = false; + q = s.indexOf(">", j + 8); + if (q < 0) { + this.onError(XMLParserErrorCode.UnterminatedDoctypeDeclaration); + return; + } + if (q2 > 0 && q > q2) { + q = s.indexOf("]>", j + 8); + if (q < 0) { + this.onError(XMLParserErrorCode.UnterminatedDoctypeDeclaration); + return; + } + complexDoctype = true; + } + const doctypeContent = s.substring(j + 8, q + (complexDoctype ? 1 : 0)); + this.onDoctype(doctypeContent); + j = q + (complexDoctype ? 2 : 1); + } else { + this.onError(XMLParserErrorCode.MalformedElement); + return; + } + break; + default: + const content = this._parseContent(s, j); + if (content === null) { + this.onError(XMLParserErrorCode.MalformedElement); + return; + } + let isClosed = false; + if (s.substring(j + content.parsed, j + content.parsed + 2) === "/>") { + isClosed = true; + } else if (s.substring(j + content.parsed, j + content.parsed + 1) !== ">") { + this.onError(XMLParserErrorCode.UnterminatedElement); + return; + } + this.onBeginElement(content.name, content.attributes, isClosed); + j += content.parsed + (isClosed ? 2 : 1); + break; + } + } else { + while (j < s.length && s[j] !== "<") { + j++; + } + const text = s.substring(i, j); + this.onText(this._resolveEntities(text)); + } + i = j; + } + } + onResolveEntity(name) { + return `&${name};`; + } + onPi(name, value) {} + onComment(text) {} + onCdata(text) {} + onDoctype(doctypeContent) {} + onText(text) {} + onBeginElement(name, attributes, isEmpty) {} + onEndElement(name) {} + onError(code) {} +} +exports.XMLParserBase = XMLParserBase; +class SimpleDOMNode { + constructor(nodeName, nodeValue) { + this.nodeName = nodeName; + this.nodeValue = nodeValue; + Object.defineProperty(this, "parentNode", { + value: null, + writable: true + }); + } + get firstChild() { + return this.childNodes?.[0]; + } + get nextSibling() { + const childNodes = this.parentNode.childNodes; + if (!childNodes) { + return undefined; + } + const index = childNodes.indexOf(this); + if (index === -1) { + return undefined; + } + return childNodes[index + 1]; + } + get textContent() { + if (!this.childNodes) { + return this.nodeValue || ""; + } + return this.childNodes.map(function (child) { + return child.textContent; + }).join(""); + } + get children() { + return this.childNodes || []; + } + hasChildNodes() { + return this.childNodes?.length > 0; + } + searchNode(paths, pos) { + if (pos >= paths.length) { + return this; + } + const component = paths[pos]; + if (component.name.startsWith("#") && pos < paths.length - 1) { + return this.searchNode(paths, pos + 1); + } + const stack = []; + let node = this; + while (true) { + if (component.name === node.nodeName) { + if (component.pos === 0) { + const res = node.searchNode(paths, pos + 1); + if (res !== null) { + return res; + } + } else if (stack.length === 0) { + return null; + } else { + const [parent] = stack.pop(); + let siblingPos = 0; + for (const child of parent.childNodes) { + if (component.name === child.nodeName) { + if (siblingPos === component.pos) { + return child.searchNode(paths, pos + 1); + } + siblingPos++; + } + } + return node.searchNode(paths, pos + 1); + } + } + if (node.childNodes?.length > 0) { + stack.push([node, 0]); + node = node.childNodes[0]; + } else if (stack.length === 0) { + return null; + } else { + while (stack.length !== 0) { + const [parent, currentPos] = stack.pop(); + const newPos = currentPos + 1; + if (newPos < parent.childNodes.length) { + stack.push([parent, newPos]); + node = parent.childNodes[newPos]; + break; + } + } + if (stack.length === 0) { + return null; + } + } + } + } + dump(buffer) { + if (this.nodeName === "#text") { + buffer.push((0, _core_utils.encodeToXmlString)(this.nodeValue)); + return; + } + buffer.push(`<${this.nodeName}`); + if (this.attributes) { + for (const attribute of this.attributes) { + buffer.push(` ${attribute.name}="${(0, _core_utils.encodeToXmlString)(attribute.value)}"`); + } + } + if (this.hasChildNodes()) { + buffer.push(">"); + for (const child of this.childNodes) { + child.dump(buffer); + } + buffer.push(``); + } else if (this.nodeValue) { + buffer.push(`>${(0, _core_utils.encodeToXmlString)(this.nodeValue)}`); + } else { + buffer.push("/>"); + } + } +} +exports.SimpleDOMNode = SimpleDOMNode; +class SimpleXMLParser extends XMLParserBase { + constructor({ + hasAttributes = false, + lowerCaseName = false + }) { + super(); + this._currentFragment = null; + this._stack = null; + this._errorCode = XMLParserErrorCode.NoError; + this._hasAttributes = hasAttributes; + this._lowerCaseName = lowerCaseName; + } + parseFromString(data) { + this._currentFragment = []; + this._stack = []; + this._errorCode = XMLParserErrorCode.NoError; + this.parseXml(data); + if (this._errorCode !== XMLParserErrorCode.NoError) { + return undefined; + } + const [documentElement] = this._currentFragment; + if (!documentElement) { + return undefined; + } + return { + documentElement + }; + } + onText(text) { + if (isWhitespaceString(text)) { + return; + } + const node = new SimpleDOMNode("#text", text); + this._currentFragment.push(node); + } + onCdata(text) { + const node = new SimpleDOMNode("#text", text); + this._currentFragment.push(node); + } + onBeginElement(name, attributes, isEmpty) { + if (this._lowerCaseName) { + name = name.toLowerCase(); + } + const node = new SimpleDOMNode(name); + node.childNodes = []; + if (this._hasAttributes) { + node.attributes = attributes; + } + this._currentFragment.push(node); + if (isEmpty) { + return; + } + this._stack.push(this._currentFragment); + this._currentFragment = node.childNodes; + } + onEndElement(name) { + this._currentFragment = this._stack.pop() || []; + const lastElement = this._currentFragment.at(-1); + if (!lastElement) { + return null; + } + for (const childNode of lastElement.childNodes) { + childNode.parentNode = lastElement; + } + return lastElement; + } + onError(code) { + this._errorCode = code; + } +} +exports.SimpleXMLParser = SimpleXMLParser; + +/***/ }), +/* 72 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.StructTreeRoot = exports.StructTreePage = void 0; +var _util = __w_pdfjs_require__(2); +var _primitives = __w_pdfjs_require__(4); +var _name_number_tree = __w_pdfjs_require__(67); +var _writer = __w_pdfjs_require__(73); +const MAX_DEPTH = 40; +const StructElementType = { + PAGE_CONTENT: 1, + STREAM_CONTENT: 2, + OBJECT: 3, + ANNOTATION: 4, + ELEMENT: 5 +}; +class StructTreeRoot { + constructor(rootDict, rootRef) { + this.dict = rootDict; + this.ref = rootRef instanceof _primitives.Ref ? rootRef : null; + this.roleMap = new Map(); + this.structParentIds = null; + } + init() { + this.readRoleMap(); + } + #addIdToPage(pageRef, id, type) { + if (!(pageRef instanceof _primitives.Ref) || id < 0) { + return; + } + this.structParentIds ||= new _primitives.RefSetCache(); + let ids = this.structParentIds.get(pageRef); + if (!ids) { + ids = []; + this.structParentIds.put(pageRef, ids); + } + ids.push([id, type]); + } + addAnnotationIdToPage(pageRef, id) { + this.#addIdToPage(pageRef, id, StructElementType.ANNOTATION); + } + readRoleMap() { + const roleMapDict = this.dict.get("RoleMap"); + if (!(roleMapDict instanceof _primitives.Dict)) { + return; + } + roleMapDict.forEach((key, value) => { + if (!(value instanceof _primitives.Name)) { + return; + } + this.roleMap.set(key, value.name); + }); + } + static async canCreateStructureTree({ + catalogRef, + pdfManager, + newAnnotationsByPage + }) { + if (!(catalogRef instanceof _primitives.Ref)) { + (0, _util.warn)("Cannot save the struct tree: no catalog reference."); + return false; + } + let nextKey = 0; + let hasNothingToUpdate = true; + for (const [pageIndex, elements] of newAnnotationsByPage) { + const { + ref: pageRef + } = await pdfManager.getPage(pageIndex); + if (!(pageRef instanceof _primitives.Ref)) { + (0, _util.warn)(`Cannot save the struct tree: page ${pageIndex} has no ref.`); + hasNothingToUpdate = true; + break; + } + for (const element of elements) { + if (element.accessibilityData?.type) { + element.parentTreeId = nextKey++; + hasNothingToUpdate = false; + } + } + } + if (hasNothingToUpdate) { + for (const elements of newAnnotationsByPage.values()) { + for (const element of elements) { + delete element.parentTreeId; + } + } + return false; + } + return true; + } + static async createStructureTree({ + newAnnotationsByPage, + xref, + catalogRef, + pdfManager, + newRefs + }) { + const root = pdfManager.catalog.cloneDict(); + const structTreeRootRef = xref.getNewTemporaryRef(); + root.set("StructTreeRoot", structTreeRootRef); + const buffer = []; + await (0, _writer.writeObject)(catalogRef, root, buffer, xref); + newRefs.push({ + ref: catalogRef, + data: buffer.join("") + }); + const structTreeRoot = new _primitives.Dict(xref); + structTreeRoot.set("Type", _primitives.Name.get("StructTreeRoot")); + const parentTreeRef = xref.getNewTemporaryRef(); + structTreeRoot.set("ParentTree", parentTreeRef); + const kids = []; + structTreeRoot.set("K", kids); + const parentTree = new _primitives.Dict(xref); + const nums = []; + parentTree.set("Nums", nums); + const nextKey = await this.#writeKids({ + newAnnotationsByPage, + structTreeRootRef, + kids, + nums, + xref, + pdfManager, + newRefs, + buffer + }); + structTreeRoot.set("ParentTreeNextKey", nextKey); + buffer.length = 0; + await (0, _writer.writeObject)(parentTreeRef, parentTree, buffer, xref); + newRefs.push({ + ref: parentTreeRef, + data: buffer.join("") + }); + buffer.length = 0; + await (0, _writer.writeObject)(structTreeRootRef, structTreeRoot, buffer, xref); + newRefs.push({ + ref: structTreeRootRef, + data: buffer.join("") + }); + } + async canUpdateStructTree({ + pdfManager, + newAnnotationsByPage + }) { + if (!this.ref) { + (0, _util.warn)("Cannot update the struct tree: no root reference."); + return false; + } + let nextKey = this.dict.get("ParentTreeNextKey"); + if (!Number.isInteger(nextKey) || nextKey < 0) { + (0, _util.warn)("Cannot update the struct tree: invalid next key."); + return false; + } + const parentTree = this.dict.get("ParentTree"); + if (!(parentTree instanceof _primitives.Dict)) { + (0, _util.warn)("Cannot update the struct tree: ParentTree isn't a dict."); + return false; + } + const nums = parentTree.get("Nums"); + if (!Array.isArray(nums)) { + (0, _util.warn)("Cannot update the struct tree: nums isn't an array."); + return false; + } + const { + numPages + } = pdfManager.catalog; + for (const pageIndex of newAnnotationsByPage.keys()) { + const { + pageDict, + ref: pageRef + } = await pdfManager.getPage(pageIndex); + if (!(pageRef instanceof _primitives.Ref)) { + (0, _util.warn)(`Cannot save the struct tree: page ${pageIndex} has no ref.`); + return false; + } + const id = pageDict.get("StructParents"); + if (!Number.isInteger(id) || id < 0 || id >= numPages) { + (0, _util.warn)(`Cannot save the struct tree: page ${pageIndex} has no id.`); + return false; + } + } + let hasNothingToUpdate = true; + for (const [pageIndex, elements] of newAnnotationsByPage) { + const { + pageDict + } = await pdfManager.getPage(pageIndex); + StructTreeRoot.#collectParents({ + elements, + xref: this.dict.xref, + pageDict, + parentTree + }); + for (const element of elements) { + if (element.accessibilityData?.type) { + element.parentTreeId = nextKey++; + hasNothingToUpdate = false; + } + } + } + if (hasNothingToUpdate) { + for (const elements of newAnnotationsByPage.values()) { + for (const element of elements) { + delete element.parentTreeId; + delete element.structTreeParent; + } + } + return false; + } + return true; + } + async updateStructureTree({ + newAnnotationsByPage, + pdfManager, + newRefs + }) { + const xref = this.dict.xref; + const structTreeRoot = this.dict.clone(); + const structTreeRootRef = this.ref; + let parentTreeRef = structTreeRoot.getRaw("ParentTree"); + let parentTree; + if (parentTreeRef instanceof _primitives.Ref) { + parentTree = xref.fetch(parentTreeRef); + } else { + parentTree = parentTreeRef; + parentTreeRef = xref.getNewTemporaryRef(); + structTreeRoot.set("ParentTree", parentTreeRef); + } + parentTree = parentTree.clone(); + let nums = parentTree.getRaw("Nums"); + let numsRef = null; + if (nums instanceof _primitives.Ref) { + numsRef = nums; + nums = xref.fetch(numsRef); + } + nums = nums.slice(); + if (!numsRef) { + parentTree.set("Nums", nums); + } + let kids = structTreeRoot.getRaw("K"); + let kidsRef = null; + if (kids instanceof _primitives.Ref) { + kidsRef = kids; + kids = xref.fetch(kidsRef); + } else { + kidsRef = xref.getNewTemporaryRef(); + structTreeRoot.set("K", kidsRef); + } + kids = Array.isArray(kids) ? kids.slice() : [kids]; + const buffer = []; + const newNextkey = await StructTreeRoot.#writeKids({ + newAnnotationsByPage, + structTreeRootRef, + kids, + nums, + xref, + pdfManager, + newRefs, + buffer + }); + structTreeRoot.set("ParentTreeNextKey", newNextkey); + buffer.length = 0; + await (0, _writer.writeObject)(kidsRef, kids, buffer, xref); + newRefs.push({ + ref: kidsRef, + data: buffer.join("") + }); + if (numsRef) { + buffer.length = 0; + await (0, _writer.writeObject)(numsRef, nums, buffer, xref); + newRefs.push({ + ref: numsRef, + data: buffer.join("") + }); + } + buffer.length = 0; + await (0, _writer.writeObject)(parentTreeRef, parentTree, buffer, xref); + newRefs.push({ + ref: parentTreeRef, + data: buffer.join("") + }); + buffer.length = 0; + await (0, _writer.writeObject)(structTreeRootRef, structTreeRoot, buffer, xref); + newRefs.push({ + ref: structTreeRootRef, + data: buffer.join("") + }); + } + static async #writeKids({ + newAnnotationsByPage, + structTreeRootRef, + kids, + nums, + xref, + pdfManager, + newRefs, + buffer + }) { + const objr = _primitives.Name.get("OBJR"); + let nextKey = -Infinity; + for (const [pageIndex, elements] of newAnnotationsByPage) { + const { + ref: pageRef + } = await pdfManager.getPage(pageIndex); + for (const { + accessibilityData: { + type, + title, + lang, + alt, + expanded, + actualText + }, + ref, + parentTreeId, + structTreeParent + } of elements) { + nextKey = Math.max(nextKey, parentTreeId); + const tagRef = xref.getNewTemporaryRef(); + const tagDict = new _primitives.Dict(xref); + tagDict.set("S", _primitives.Name.get(type)); + if (title) { + tagDict.set("T", title); + } + if (lang) { + tagDict.set("Lang", lang); + } + if (alt) { + tagDict.set("Alt", alt); + } + if (expanded) { + tagDict.set("E", expanded); + } + if (actualText) { + tagDict.set("ActualText", actualText); + } + if (structTreeParent) { + await this.#updateParentTag({ + structTreeParent, + tagDict, + newTagRef: tagRef, + fallbackRef: structTreeRootRef, + xref, + newRefs, + buffer + }); + } else { + tagDict.set("P", structTreeRootRef); + } + const objDict = new _primitives.Dict(xref); + tagDict.set("K", objDict); + objDict.set("Type", objr); + objDict.set("Pg", pageRef); + objDict.set("Obj", ref); + buffer.length = 0; + await (0, _writer.writeObject)(tagRef, tagDict, buffer, xref); + newRefs.push({ + ref: tagRef, + data: buffer.join("") + }); + nums.push(parentTreeId, tagRef); + kids.push(tagRef); + } + } + return nextKey + 1; + } + static #collectParents({ + elements, + xref, + pageDict, + parentTree + }) { + const idToElement = new Map(); + for (const element of elements) { + if (element.structTreeParentId) { + const id = parseInt(element.structTreeParentId.split("_mc")[1], 10); + idToElement.set(id, element); + } + } + const id = pageDict.get("StructParents"); + const numberTree = new _name_number_tree.NumberTree(parentTree, xref); + const parentArray = numberTree.get(id); + if (!Array.isArray(parentArray)) { + return; + } + const updateElement = (kid, pageKid, kidRef) => { + const element = idToElement.get(kid); + if (element) { + const parentRef = pageKid.getRaw("P"); + const parentDict = xref.fetchIfRef(parentRef); + if (parentRef instanceof _primitives.Ref && parentDict instanceof _primitives.Dict) { + element.structTreeParent = { + ref: kidRef, + dict: pageKid + }; + } + return true; + } + return false; + }; + for (const kidRef of parentArray) { + if (!(kidRef instanceof _primitives.Ref)) { + continue; + } + const pageKid = xref.fetch(kidRef); + const k = pageKid.get("K"); + if (Number.isInteger(k)) { + updateElement(k, pageKid, kidRef); + continue; + } + if (!Array.isArray(k)) { + continue; + } + for (let kid of k) { + kid = xref.fetchIfRef(kid); + if (Number.isInteger(kid) && updateElement(kid, pageKid, kidRef)) { + break; + } + } + } + } + static async #updateParentTag({ + structTreeParent: { + ref, + dict + }, + tagDict, + newTagRef, + fallbackRef, + xref, + newRefs, + buffer + }) { + const parentRef = dict.getRaw("P"); + let parentDict = xref.fetchIfRef(parentRef); + tagDict.set("P", parentRef); + let saveParentDict = false; + let parentKids; + let parentKidsRef = parentDict.getRaw("K"); + if (!(parentKidsRef instanceof _primitives.Ref)) { + parentKids = parentKidsRef; + parentKidsRef = xref.getNewTemporaryRef(); + parentDict = parentDict.clone(); + parentDict.set("K", parentKidsRef); + saveParentDict = true; + } else { + parentKids = xref.fetch(parentKidsRef); + } + if (Array.isArray(parentKids)) { + const index = parentKids.indexOf(ref); + if (index >= 0) { + parentKids = parentKids.slice(); + parentKids.splice(index + 1, 0, newTagRef); + } else { + (0, _util.warn)("Cannot update the struct tree: parent kid not found."); + tagDict.set("P", fallbackRef); + return; + } + } else if (parentKids instanceof _primitives.Dict) { + parentKids = [parentKidsRef, newTagRef]; + parentKidsRef = xref.getNewTemporaryRef(); + parentDict.set("K", parentKidsRef); + saveParentDict = true; + } + buffer.length = 0; + await (0, _writer.writeObject)(parentKidsRef, parentKids, buffer, xref); + newRefs.push({ + ref: parentKidsRef, + data: buffer.join("") + }); + if (!saveParentDict) { + return; + } + buffer.length = 0; + await (0, _writer.writeObject)(parentRef, parentDict, buffer, xref); + newRefs.push({ + ref: parentRef, + data: buffer.join("") + }); + } +} +exports.StructTreeRoot = StructTreeRoot; +class StructElementNode { + constructor(tree, dict) { + this.tree = tree; + this.dict = dict; + this.kids = []; + this.parseKids(); + } + get role() { + const nameObj = this.dict.get("S"); + const name = nameObj instanceof _primitives.Name ? nameObj.name : ""; + const { + root + } = this.tree; + if (root.roleMap.has(name)) { + return root.roleMap.get(name); + } + return name; + } + parseKids() { + let pageObjId = null; + const objRef = this.dict.getRaw("Pg"); + if (objRef instanceof _primitives.Ref) { + pageObjId = objRef.toString(); + } + const kids = this.dict.get("K"); + if (Array.isArray(kids)) { + for (const kid of kids) { + const element = this.parseKid(pageObjId, kid); + if (element) { + this.kids.push(element); + } + } + } else { + const element = this.parseKid(pageObjId, kids); + if (element) { + this.kids.push(element); + } + } + } + parseKid(pageObjId, kid) { + if (Number.isInteger(kid)) { + if (this.tree.pageDict.objId !== pageObjId) { + return null; + } + return new StructElement({ + type: StructElementType.PAGE_CONTENT, + mcid: kid, + pageObjId + }); + } + let kidDict = null; + if (kid instanceof _primitives.Ref) { + kidDict = this.dict.xref.fetch(kid); + } else if (kid instanceof _primitives.Dict) { + kidDict = kid; + } + if (!kidDict) { + return null; + } + const pageRef = kidDict.getRaw("Pg"); + if (pageRef instanceof _primitives.Ref) { + pageObjId = pageRef.toString(); + } + const type = kidDict.get("Type") instanceof _primitives.Name ? kidDict.get("Type").name : null; + if (type === "MCR") { + if (this.tree.pageDict.objId !== pageObjId) { + return null; + } + const kidRef = kidDict.getRaw("Stm"); + return new StructElement({ + type: StructElementType.STREAM_CONTENT, + refObjId: kidRef instanceof _primitives.Ref ? kidRef.toString() : null, + pageObjId, + mcid: kidDict.get("MCID") + }); + } + if (type === "OBJR") { + if (this.tree.pageDict.objId !== pageObjId) { + return null; + } + const kidRef = kidDict.getRaw("Obj"); + return new StructElement({ + type: StructElementType.OBJECT, + refObjId: kidRef instanceof _primitives.Ref ? kidRef.toString() : null, + pageObjId + }); + } + return new StructElement({ + type: StructElementType.ELEMENT, + dict: kidDict + }); + } +} +class StructElement { + constructor({ + type, + dict = null, + mcid = null, + pageObjId = null, + refObjId = null + }) { + this.type = type; + this.dict = dict; + this.mcid = mcid; + this.pageObjId = pageObjId; + this.refObjId = refObjId; + this.parentNode = null; + } +} +class StructTreePage { + constructor(structTreeRoot, pageDict) { + this.root = structTreeRoot; + this.rootDict = structTreeRoot ? structTreeRoot.dict : null; + this.pageDict = pageDict; + this.nodes = []; + } + parse(pageRef) { + if (!this.root || !this.rootDict) { + return; + } + const parentTree = this.rootDict.get("ParentTree"); + if (!parentTree) { + return; + } + const id = this.pageDict.get("StructParents"); + const ids = pageRef instanceof _primitives.Ref && this.root.structParentIds?.get(pageRef); + if (!Number.isInteger(id) && !ids) { + return; + } + const map = new Map(); + const numberTree = new _name_number_tree.NumberTree(parentTree, this.rootDict.xref); + if (Number.isInteger(id)) { + const parentArray = numberTree.get(id); + if (Array.isArray(parentArray)) { + for (const ref of parentArray) { + if (ref instanceof _primitives.Ref) { + this.addNode(this.rootDict.xref.fetch(ref), map); + } + } + } + } + if (!ids) { + return; + } + for (const [elemId, type] of ids) { + const obj = numberTree.get(elemId); + if (obj) { + const elem = this.addNode(this.rootDict.xref.fetchIfRef(obj), map); + if (elem?.kids?.length === 1 && elem.kids[0].type === StructElementType.OBJECT) { + elem.kids[0].type = type; + } + } + } + } + addNode(dict, map, level = 0) { + if (level > MAX_DEPTH) { + (0, _util.warn)("StructTree MAX_DEPTH reached."); + return null; + } + if (map.has(dict)) { + return map.get(dict); + } + const element = new StructElementNode(this, dict); + map.set(dict, element); + const parent = dict.get("P"); + if (!parent || (0, _primitives.isName)(parent.get("Type"), "StructTreeRoot")) { + if (!this.addTopLevelNode(dict, element)) { + map.delete(dict); + } + return element; + } + const parentNode = this.addNode(parent, map, level + 1); + if (!parentNode) { + return element; + } + let save = false; + for (const kid of parentNode.kids) { + if (kid.type === StructElementType.ELEMENT && kid.dict === dict) { + kid.parentNode = element; + save = true; + } + } + if (!save) { + map.delete(dict); + } + return element; + } + addTopLevelNode(dict, element) { + const obj = this.rootDict.get("K"); + if (!obj) { + return false; + } + if (obj instanceof _primitives.Dict) { + if (obj.objId !== dict.objId) { + return false; + } + this.nodes[0] = element; + return true; + } + if (!Array.isArray(obj)) { + return true; + } + let save = false; + for (let i = 0; i < obj.length; i++) { + const kidRef = obj[i]; + if (kidRef?.toString() === dict.objId) { + this.nodes[i] = element; + save = true; + } + } + return save; + } + get serializable() { + function nodeToSerializable(node, parent, level = 0) { + if (level > MAX_DEPTH) { + (0, _util.warn)("StructTree too deep to be fully serialized."); + return; + } + const obj = Object.create(null); + obj.role = node.role; + obj.children = []; + parent.children.push(obj); + const alt = node.dict.get("Alt"); + if (typeof alt === "string") { + obj.alt = (0, _util.stringToPDFString)(alt); + } + const lang = node.dict.get("Lang"); + if (typeof lang === "string") { + obj.lang = (0, _util.stringToPDFString)(lang); + } + for (const kid of node.kids) { + const kidElement = kid.type === StructElementType.ELEMENT ? kid.parentNode : null; + if (kidElement) { + nodeToSerializable(kidElement, obj, level + 1); + continue; + } else if (kid.type === StructElementType.PAGE_CONTENT || kid.type === StructElementType.STREAM_CONTENT) { + obj.children.push({ + type: "content", + id: `p${kid.pageObjId}_mc${kid.mcid}` + }); + } else if (kid.type === StructElementType.OBJECT) { + obj.children.push({ + type: "object", + id: kid.refObjId + }); + } else if (kid.type === StructElementType.ANNOTATION) { + obj.children.push({ + type: "annotation", + id: `${_util.AnnotationPrefix}${kid.refObjId}` + }); + } + } + } + const root = Object.create(null); + root.children = []; + root.role = "Root"; + for (const child of this.nodes) { + if (!child) { + continue; + } + nodeToSerializable(child, root); + } + return root; + } +} +exports.StructTreePage = StructTreePage; + +/***/ }), +/* 73 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.incrementalUpdate = incrementalUpdate; +exports.writeDict = writeDict; +exports.writeObject = writeObject; +var _util = __w_pdfjs_require__(2); +var _primitives = __w_pdfjs_require__(4); +var _core_utils = __w_pdfjs_require__(3); +var _xml_parser = __w_pdfjs_require__(71); +var _base_stream = __w_pdfjs_require__(5); +var _crypto = __w_pdfjs_require__(74); +async function writeObject(ref, obj, buffer, { + encrypt = null +}) { + const transform = encrypt?.createCipherTransform(ref.num, ref.gen); + buffer.push(`${ref.num} ${ref.gen} obj\n`); + if (obj instanceof _primitives.Dict) { + await writeDict(obj, buffer, transform); + } else if (obj instanceof _base_stream.BaseStream) { + await writeStream(obj, buffer, transform); + } else if (Array.isArray(obj)) { + await writeArray(obj, buffer, transform); + } + buffer.push("\nendobj\n"); +} +async function writeDict(dict, buffer, transform) { + buffer.push("<<"); + for (const key of dict.getKeys()) { + buffer.push(` /${(0, _core_utils.escapePDFName)(key)} `); + await writeValue(dict.getRaw(key), buffer, transform); + } + buffer.push(">>"); +} +async function writeStream(stream, buffer, transform) { + let string = stream.getString(); + const { + dict + } = stream; + const [filter, params] = await Promise.all([dict.getAsync("Filter"), dict.getAsync("DecodeParms")]); + const filterZero = Array.isArray(filter) ? await dict.xref.fetchIfRefAsync(filter[0]) : filter; + const isFilterZeroFlateDecode = (0, _primitives.isName)(filterZero, "FlateDecode"); + const MIN_LENGTH_FOR_COMPRESSING = 256; + if (typeof CompressionStream !== "undefined" && (string.length >= MIN_LENGTH_FOR_COMPRESSING || isFilterZeroFlateDecode)) { + try { + const byteArray = (0, _util.stringToBytes)(string); + const cs = new CompressionStream("deflate"); + const writer = cs.writable.getWriter(); + writer.write(byteArray); + writer.close(); + const buf = await new Response(cs.readable).arrayBuffer(); + string = (0, _util.bytesToString)(new Uint8Array(buf)); + let newFilter, newParams; + if (!filter) { + newFilter = _primitives.Name.get("FlateDecode"); + } else if (!isFilterZeroFlateDecode) { + newFilter = Array.isArray(filter) ? [_primitives.Name.get("FlateDecode"), ...filter] : [_primitives.Name.get("FlateDecode"), filter]; + if (params) { + newParams = Array.isArray(params) ? [null, ...params] : [null, params]; + } + } + if (newFilter) { + dict.set("Filter", newFilter); + } + if (newParams) { + dict.set("DecodeParms", newParams); + } + } catch (ex) { + (0, _util.info)(`writeStream - cannot compress data: "${ex}".`); + } + } + if (transform) { + string = transform.encryptString(string); + } + dict.set("Length", string.length); + await writeDict(dict, buffer, transform); + buffer.push(" stream\n", string, "\nendstream"); +} +async function writeArray(array, buffer, transform) { + buffer.push("["); + let first = true; + for (const val of array) { + if (!first) { + buffer.push(" "); + } else { + first = false; + } + await writeValue(val, buffer, transform); + } + buffer.push("]"); +} +async function writeValue(value, buffer, transform) { + if (value instanceof _primitives.Name) { + buffer.push(`/${(0, _core_utils.escapePDFName)(value.name)}`); + } else if (value instanceof _primitives.Ref) { + buffer.push(`${value.num} ${value.gen} R`); + } else if (Array.isArray(value)) { + await writeArray(value, buffer, transform); + } else if (typeof value === "string") { + if (transform) { + value = transform.encryptString(value); + } + buffer.push(`(${(0, _core_utils.escapeString)(value)})`); + } else if (typeof value === "number") { + buffer.push((0, _core_utils.numberToString)(value)); + } else if (typeof value === "boolean") { + buffer.push(value.toString()); + } else if (value instanceof _primitives.Dict) { + await writeDict(value, buffer, transform); + } else if (value instanceof _base_stream.BaseStream) { + await writeStream(value, buffer, transform); + } else if (value === null) { + buffer.push("null"); + } else { + (0, _util.warn)(`Unhandled value in writer: ${typeof value}, please file a bug.`); + } +} +function writeInt(number, size, offset, buffer) { + for (let i = size + offset - 1; i > offset - 1; i--) { + buffer[i] = number & 0xff; + number >>= 8; + } + return offset + size; +} +function writeString(string, offset, buffer) { + for (let i = 0, len = string.length; i < len; i++) { + buffer[offset + i] = string.charCodeAt(i) & 0xff; + } +} +function computeMD5(filesize, xrefInfo) { + const time = Math.floor(Date.now() / 1000); + const filename = xrefInfo.filename || ""; + const md5Buffer = [time.toString(), filename, filesize.toString()]; + let md5BufferLen = md5Buffer.reduce((a, str) => a + str.length, 0); + for (const value of Object.values(xrefInfo.info)) { + md5Buffer.push(value); + md5BufferLen += value.length; + } + const array = new Uint8Array(md5BufferLen); + let offset = 0; + for (const str of md5Buffer) { + writeString(str, offset, array); + offset += str.length; + } + return (0, _util.bytesToString)((0, _crypto.calculateMD5)(array)); +} +function writeXFADataForAcroform(str, newRefs) { + const xml = new _xml_parser.SimpleXMLParser({ + hasAttributes: true + }).parseFromString(str); + for (const { + xfa + } of newRefs) { + if (!xfa) { + continue; + } + const { + path, + value + } = xfa; + if (!path) { + continue; + } + const nodePath = (0, _core_utils.parseXFAPath)(path); + let node = xml.documentElement.searchNode(nodePath, 0); + if (!node && nodePath.length > 1) { + node = xml.documentElement.searchNode([nodePath.at(-1)], 0); + } + if (node) { + node.childNodes = Array.isArray(value) ? value.map(val => new _xml_parser.SimpleDOMNode("value", val)) : [new _xml_parser.SimpleDOMNode("#text", value)]; + } else { + (0, _util.warn)(`Node not found for path: ${path}`); + } + } + const buffer = []; + xml.documentElement.dump(buffer); + return buffer.join(""); +} +async function updateAcroform({ + xref, + acroForm, + acroFormRef, + hasXfa, + hasXfaDatasetsEntry, + xfaDatasetsRef, + needAppearances, + newRefs +}) { + if (hasXfa && !hasXfaDatasetsEntry && !xfaDatasetsRef) { + (0, _util.warn)("XFA - Cannot save it"); + } + if (!needAppearances && (!hasXfa || !xfaDatasetsRef || hasXfaDatasetsEntry)) { + return; + } + const dict = acroForm.clone(); + if (hasXfa && !hasXfaDatasetsEntry) { + const newXfa = acroForm.get("XFA").slice(); + newXfa.splice(2, 0, "datasets"); + newXfa.splice(3, 0, xfaDatasetsRef); + dict.set("XFA", newXfa); + } + if (needAppearances) { + dict.set("NeedAppearances", true); + } + const buffer = []; + await writeObject(acroFormRef, dict, buffer, xref); + newRefs.push({ + ref: acroFormRef, + data: buffer.join("") + }); +} +function updateXFA({ + xfaData, + xfaDatasetsRef, + newRefs, + xref +}) { + if (xfaData === null) { + const datasets = xref.fetchIfRef(xfaDatasetsRef); + xfaData = writeXFADataForAcroform(datasets.getString(), newRefs); + } + const encrypt = xref.encrypt; + if (encrypt) { + const transform = encrypt.createCipherTransform(xfaDatasetsRef.num, xfaDatasetsRef.gen); + xfaData = transform.encryptString(xfaData); + } + const data = `${xfaDatasetsRef.num} ${xfaDatasetsRef.gen} obj\n` + `<< /Type /EmbeddedFile /Length ${xfaData.length}>>\nstream\n` + xfaData + "\nendstream\nendobj\n"; + newRefs.push({ + ref: xfaDatasetsRef, + data + }); +} +async function incrementalUpdate({ + originalData, + xrefInfo, + newRefs, + xref = null, + hasXfa = false, + xfaDatasetsRef = null, + hasXfaDatasetsEntry = false, + needAppearances, + acroFormRef = null, + acroForm = null, + xfaData = null +}) { + await updateAcroform({ + xref, + acroForm, + acroFormRef, + hasXfa, + hasXfaDatasetsEntry, + xfaDatasetsRef, + needAppearances, + newRefs + }); + if (hasXfa) { + updateXFA({ + xfaData, + xfaDatasetsRef, + newRefs, + xref + }); + } + const newXref = new _primitives.Dict(null); + const refForXrefTable = xrefInfo.newRef; + let buffer, baseOffset; + const lastByte = originalData.at(-1); + if (lastByte === 0x0a || lastByte === 0x0d) { + buffer = []; + baseOffset = originalData.length; + } else { + buffer = ["\n"]; + baseOffset = originalData.length + 1; + } + newXref.set("Size", refForXrefTable.num + 1); + newXref.set("Prev", xrefInfo.startXRef); + newXref.set("Type", _primitives.Name.get("XRef")); + if (xrefInfo.rootRef !== null) { + newXref.set("Root", xrefInfo.rootRef); + } + if (xrefInfo.infoRef !== null) { + newXref.set("Info", xrefInfo.infoRef); + } + if (xrefInfo.encryptRef !== null) { + newXref.set("Encrypt", xrefInfo.encryptRef); + } + newRefs.push({ + ref: refForXrefTable, + data: "" + }); + newRefs = newRefs.sort((a, b) => { + return a.ref.num - b.ref.num; + }); + const xrefTableData = [[0, 1, 0xffff]]; + const indexes = [0, 1]; + let maxOffset = 0; + for (const { + ref, + data + } of newRefs) { + maxOffset = Math.max(maxOffset, baseOffset); + xrefTableData.push([1, baseOffset, Math.min(ref.gen, 0xffff)]); + baseOffset += data.length; + indexes.push(ref.num, 1); + buffer.push(data); + } + newXref.set("Index", indexes); + if (Array.isArray(xrefInfo.fileIds) && xrefInfo.fileIds.length > 0) { + const md5 = computeMD5(baseOffset, xrefInfo); + newXref.set("ID", [xrefInfo.fileIds[0], md5]); + } + const offsetSize = Math.ceil(Math.log2(maxOffset) / 8); + const sizes = [1, offsetSize, 2]; + const structSize = sizes[0] + sizes[1] + sizes[2]; + const tableLength = structSize * xrefTableData.length; + newXref.set("W", sizes); + newXref.set("Length", tableLength); + buffer.push(`${refForXrefTable.num} ${refForXrefTable.gen} obj\n`); + await writeDict(newXref, buffer, null); + buffer.push(" stream\n"); + const bufferLen = buffer.reduce((a, str) => a + str.length, 0); + const footer = `\nendstream\nendobj\nstartxref\n${baseOffset}\n%%EOF\n`; + const array = new Uint8Array(originalData.length + bufferLen + tableLength + footer.length); + array.set(originalData); + let offset = originalData.length; + for (const str of buffer) { + writeString(str, offset, array); + offset += str.length; + } + for (const [type, objOffset, gen] of xrefTableData) { + offset = writeInt(type, sizes[0], offset, array); + offset = writeInt(objOffset, sizes[1], offset, array); + offset = writeInt(gen, sizes[2], offset, array); + } + writeString(footer, offset, array); + return array; +} + +/***/ }), +/* 74 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.calculateSHA256 = exports.calculateMD5 = exports.PDF20 = exports.PDF17 = exports.CipherTransformFactory = exports.ARCFourCipher = exports.AES256Cipher = exports.AES128Cipher = void 0; +exports.calculateSHA384 = calculateSHA384; +exports.calculateSHA512 = void 0; +var _util = __w_pdfjs_require__(2); +var _primitives = __w_pdfjs_require__(4); +var _decrypt_stream = __w_pdfjs_require__(75); +class ARCFourCipher { + constructor(key) { + this.a = 0; + this.b = 0; + const s = new Uint8Array(256); + const keyLength = key.length; + for (let i = 0; i < 256; ++i) { + s[i] = i; + } + for (let i = 0, j = 0; i < 256; ++i) { + const tmp = s[i]; + j = j + tmp + key[i % keyLength] & 0xff; + s[i] = s[j]; + s[j] = tmp; + } + this.s = s; + } + encryptBlock(data) { + let a = this.a, + b = this.b; + const s = this.s; + const n = data.length; + const output = new Uint8Array(n); + for (let i = 0; i < n; ++i) { + a = a + 1 & 0xff; + const tmp = s[a]; + b = b + tmp & 0xff; + const tmp2 = s[b]; + s[a] = tmp2; + s[b] = tmp; + output[i] = data[i] ^ s[tmp + tmp2 & 0xff]; + } + this.a = a; + this.b = b; + return output; + } + decryptBlock(data) { + return this.encryptBlock(data); + } + encrypt(data) { + return this.encryptBlock(data); + } +} +exports.ARCFourCipher = ARCFourCipher; +const calculateMD5 = function calculateMD5Closure() { + const r = new Uint8Array([7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]); + const k = new Int32Array([-680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, -1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162, 1804603682, -40341101, -1502002290, 1236535329, -165796510, -1069501632, 643717713, -373897302, -701558691, 38016083, -660478335, -405537848, 568446438, -1019803690, -187363961, 1163531501, -1444681467, -51403784, 1735328473, -1926607734, -378558, -2022574463, 1839030562, -35309556, -1530992060, 1272893353, -155497632, -1094730640, 681279174, -358537222, -722521979, 76029189, -640364487, -421815835, 530742520, -995338651, -198630844, 1126891415, -1416354905, -57434055, 1700485571, -1894986606, -1051523, -2054922799, 1873313359, -30611744, -1560198380, 1309151649, -145523070, -1120210379, 718787259, -343485551]); + function hash(data, offset, length) { + let h0 = 1732584193, + h1 = -271733879, + h2 = -1732584194, + h3 = 271733878; + const paddedLength = length + 72 & ~63; + const padded = new Uint8Array(paddedLength); + let i, j; + for (i = 0; i < length; ++i) { + padded[i] = data[offset++]; + } + padded[i++] = 0x80; + const n = paddedLength - 8; + while (i < n) { + padded[i++] = 0; + } + padded[i++] = length << 3 & 0xff; + padded[i++] = length >> 5 & 0xff; + padded[i++] = length >> 13 & 0xff; + padded[i++] = length >> 21 & 0xff; + padded[i++] = length >>> 29 & 0xff; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + const w = new Int32Array(16); + for (i = 0; i < paddedLength;) { + for (j = 0; j < 16; ++j, i += 4) { + w[j] = padded[i] | padded[i + 1] << 8 | padded[i + 2] << 16 | padded[i + 3] << 24; + } + let a = h0, + b = h1, + c = h2, + d = h3, + f, + g; + for (j = 0; j < 64; ++j) { + if (j < 16) { + f = b & c | ~b & d; + g = j; + } else if (j < 32) { + f = d & b | ~d & c; + g = 5 * j + 1 & 15; + } else if (j < 48) { + f = b ^ c ^ d; + g = 3 * j + 5 & 15; + } else { + f = c ^ (b | ~d); + g = 7 * j & 15; + } + const tmp = d, + rotateArg = a + f + k[j] + w[g] | 0, + rotate = r[j]; + d = c; + c = b; + b = b + (rotateArg << rotate | rotateArg >>> 32 - rotate) | 0; + a = tmp; + } + h0 = h0 + a | 0; + h1 = h1 + b | 0; + h2 = h2 + c | 0; + h3 = h3 + d | 0; + } + return new Uint8Array([h0 & 0xFF, h0 >> 8 & 0xFF, h0 >> 16 & 0xFF, h0 >>> 24 & 0xFF, h1 & 0xFF, h1 >> 8 & 0xFF, h1 >> 16 & 0xFF, h1 >>> 24 & 0xFF, h2 & 0xFF, h2 >> 8 & 0xFF, h2 >> 16 & 0xFF, h2 >>> 24 & 0xFF, h3 & 0xFF, h3 >> 8 & 0xFF, h3 >> 16 & 0xFF, h3 >>> 24 & 0xFF]); + } + return hash; +}(); +exports.calculateMD5 = calculateMD5; +class Word64 { + constructor(highInteger, lowInteger) { + this.high = highInteger | 0; + this.low = lowInteger | 0; + } + and(word) { + this.high &= word.high; + this.low &= word.low; + } + xor(word) { + this.high ^= word.high; + this.low ^= word.low; + } + or(word) { + this.high |= word.high; + this.low |= word.low; + } + shiftRight(places) { + if (places >= 32) { + this.low = this.high >>> places - 32 | 0; + this.high = 0; + } else { + this.low = this.low >>> places | this.high << 32 - places; + this.high = this.high >>> places | 0; + } + } + shiftLeft(places) { + if (places >= 32) { + this.high = this.low << places - 32; + this.low = 0; + } else { + this.high = this.high << places | this.low >>> 32 - places; + this.low <<= places; + } + } + rotateRight(places) { + let low, high; + if (places & 32) { + high = this.low; + low = this.high; + } else { + low = this.low; + high = this.high; + } + places &= 31; + this.low = low >>> places | high << 32 - places; + this.high = high >>> places | low << 32 - places; + } + not() { + this.high = ~this.high; + this.low = ~this.low; + } + add(word) { + const lowAdd = (this.low >>> 0) + (word.low >>> 0); + let highAdd = (this.high >>> 0) + (word.high >>> 0); + if (lowAdd > 0xffffffff) { + highAdd += 1; + } + this.low = lowAdd | 0; + this.high = highAdd | 0; + } + copyTo(bytes, offset) { + bytes[offset] = this.high >>> 24 & 0xff; + bytes[offset + 1] = this.high >> 16 & 0xff; + bytes[offset + 2] = this.high >> 8 & 0xff; + bytes[offset + 3] = this.high & 0xff; + bytes[offset + 4] = this.low >>> 24 & 0xff; + bytes[offset + 5] = this.low >> 16 & 0xff; + bytes[offset + 6] = this.low >> 8 & 0xff; + bytes[offset + 7] = this.low & 0xff; + } + assign(word) { + this.high = word.high; + this.low = word.low; + } +} +const calculateSHA256 = function calculateSHA256Closure() { + function rotr(x, n) { + return x >>> n | x << 32 - n; + } + function ch(x, y, z) { + return x & y ^ ~x & z; + } + function maj(x, y, z) { + return x & y ^ x & z ^ y & z; + } + function sigma(x) { + return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22); + } + function sigmaPrime(x) { + return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25); + } + function littleSigma(x) { + return rotr(x, 7) ^ rotr(x, 18) ^ x >>> 3; + } + function littleSigmaPrime(x) { + return rotr(x, 17) ^ rotr(x, 19) ^ x >>> 10; + } + const k = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2]; + function hash(data, offset, length) { + let h0 = 0x6a09e667, + h1 = 0xbb67ae85, + h2 = 0x3c6ef372, + h3 = 0xa54ff53a, + h4 = 0x510e527f, + h5 = 0x9b05688c, + h6 = 0x1f83d9ab, + h7 = 0x5be0cd19; + const paddedLength = Math.ceil((length + 9) / 64) * 64; + const padded = new Uint8Array(paddedLength); + let i, j; + for (i = 0; i < length; ++i) { + padded[i] = data[offset++]; + } + padded[i++] = 0x80; + const n = paddedLength - 8; + while (i < n) { + padded[i++] = 0; + } + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = length >>> 29 & 0xff; + padded[i++] = length >> 21 & 0xff; + padded[i++] = length >> 13 & 0xff; + padded[i++] = length >> 5 & 0xff; + padded[i++] = length << 3 & 0xff; + const w = new Uint32Array(64); + for (i = 0; i < paddedLength;) { + for (j = 0; j < 16; ++j) { + w[j] = padded[i] << 24 | padded[i + 1] << 16 | padded[i + 2] << 8 | padded[i + 3]; + i += 4; + } + for (j = 16; j < 64; ++j) { + w[j] = littleSigmaPrime(w[j - 2]) + w[j - 7] + littleSigma(w[j - 15]) + w[j - 16] | 0; + } + let a = h0, + b = h1, + c = h2, + d = h3, + e = h4, + f = h5, + g = h6, + h = h7, + t1, + t2; + for (j = 0; j < 64; ++j) { + t1 = h + sigmaPrime(e) + ch(e, f, g) + k[j] + w[j]; + t2 = sigma(a) + maj(a, b, c); + h = g; + g = f; + f = e; + e = d + t1 | 0; + d = c; + c = b; + b = a; + a = t1 + t2 | 0; + } + h0 = h0 + a | 0; + h1 = h1 + b | 0; + h2 = h2 + c | 0; + h3 = h3 + d | 0; + h4 = h4 + e | 0; + h5 = h5 + f | 0; + h6 = h6 + g | 0; + h7 = h7 + h | 0; + } + return new Uint8Array([h0 >> 24 & 0xFF, h0 >> 16 & 0xFF, h0 >> 8 & 0xFF, h0 & 0xFF, h1 >> 24 & 0xFF, h1 >> 16 & 0xFF, h1 >> 8 & 0xFF, h1 & 0xFF, h2 >> 24 & 0xFF, h2 >> 16 & 0xFF, h2 >> 8 & 0xFF, h2 & 0xFF, h3 >> 24 & 0xFF, h3 >> 16 & 0xFF, h3 >> 8 & 0xFF, h3 & 0xFF, h4 >> 24 & 0xFF, h4 >> 16 & 0xFF, h4 >> 8 & 0xFF, h4 & 0xFF, h5 >> 24 & 0xFF, h5 >> 16 & 0xFF, h5 >> 8 & 0xFF, h5 & 0xFF, h6 >> 24 & 0xFF, h6 >> 16 & 0xFF, h6 >> 8 & 0xFF, h6 & 0xFF, h7 >> 24 & 0xFF, h7 >> 16 & 0xFF, h7 >> 8 & 0xFF, h7 & 0xFF]); + } + return hash; +}(); +exports.calculateSHA256 = calculateSHA256; +const calculateSHA512 = function calculateSHA512Closure() { + function ch(result, x, y, z, tmp) { + result.assign(x); + result.and(y); + tmp.assign(x); + tmp.not(); + tmp.and(z); + result.xor(tmp); + } + function maj(result, x, y, z, tmp) { + result.assign(x); + result.and(y); + tmp.assign(x); + tmp.and(z); + result.xor(tmp); + tmp.assign(y); + tmp.and(z); + result.xor(tmp); + } + function sigma(result, x, tmp) { + result.assign(x); + result.rotateRight(28); + tmp.assign(x); + tmp.rotateRight(34); + result.xor(tmp); + tmp.assign(x); + tmp.rotateRight(39); + result.xor(tmp); + } + function sigmaPrime(result, x, tmp) { + result.assign(x); + result.rotateRight(14); + tmp.assign(x); + tmp.rotateRight(18); + result.xor(tmp); + tmp.assign(x); + tmp.rotateRight(41); + result.xor(tmp); + } + function littleSigma(result, x, tmp) { + result.assign(x); + result.rotateRight(1); + tmp.assign(x); + tmp.rotateRight(8); + result.xor(tmp); + tmp.assign(x); + tmp.shiftRight(7); + result.xor(tmp); + } + function littleSigmaPrime(result, x, tmp) { + result.assign(x); + result.rotateRight(19); + tmp.assign(x); + tmp.rotateRight(61); + result.xor(tmp); + tmp.assign(x); + tmp.shiftRight(6); + result.xor(tmp); + } + const k = [new Word64(0x428a2f98, 0xd728ae22), new Word64(0x71374491, 0x23ef65cd), new Word64(0xb5c0fbcf, 0xec4d3b2f), new Word64(0xe9b5dba5, 0x8189dbbc), new Word64(0x3956c25b, 0xf348b538), new Word64(0x59f111f1, 0xb605d019), new Word64(0x923f82a4, 0xaf194f9b), new Word64(0xab1c5ed5, 0xda6d8118), new Word64(0xd807aa98, 0xa3030242), new Word64(0x12835b01, 0x45706fbe), new Word64(0x243185be, 0x4ee4b28c), new Word64(0x550c7dc3, 0xd5ffb4e2), new Word64(0x72be5d74, 0xf27b896f), new Word64(0x80deb1fe, 0x3b1696b1), new Word64(0x9bdc06a7, 0x25c71235), new Word64(0xc19bf174, 0xcf692694), new Word64(0xe49b69c1, 0x9ef14ad2), new Word64(0xefbe4786, 0x384f25e3), new Word64(0x0fc19dc6, 0x8b8cd5b5), new Word64(0x240ca1cc, 0x77ac9c65), new Word64(0x2de92c6f, 0x592b0275), new Word64(0x4a7484aa, 0x6ea6e483), new Word64(0x5cb0a9dc, 0xbd41fbd4), new Word64(0x76f988da, 0x831153b5), new Word64(0x983e5152, 0xee66dfab), new Word64(0xa831c66d, 0x2db43210), new Word64(0xb00327c8, 0x98fb213f), new Word64(0xbf597fc7, 0xbeef0ee4), new Word64(0xc6e00bf3, 0x3da88fc2), new Word64(0xd5a79147, 0x930aa725), new Word64(0x06ca6351, 0xe003826f), new Word64(0x14292967, 0x0a0e6e70), new Word64(0x27b70a85, 0x46d22ffc), new Word64(0x2e1b2138, 0x5c26c926), new Word64(0x4d2c6dfc, 0x5ac42aed), new Word64(0x53380d13, 0x9d95b3df), new Word64(0x650a7354, 0x8baf63de), new Word64(0x766a0abb, 0x3c77b2a8), new Word64(0x81c2c92e, 0x47edaee6), new Word64(0x92722c85, 0x1482353b), new Word64(0xa2bfe8a1, 0x4cf10364), new Word64(0xa81a664b, 0xbc423001), new Word64(0xc24b8b70, 0xd0f89791), new Word64(0xc76c51a3, 0x0654be30), new Word64(0xd192e819, 0xd6ef5218), new Word64(0xd6990624, 0x5565a910), new Word64(0xf40e3585, 0x5771202a), new Word64(0x106aa070, 0x32bbd1b8), new Word64(0x19a4c116, 0xb8d2d0c8), new Word64(0x1e376c08, 0x5141ab53), new Word64(0x2748774c, 0xdf8eeb99), new Word64(0x34b0bcb5, 0xe19b48a8), new Word64(0x391c0cb3, 0xc5c95a63), new Word64(0x4ed8aa4a, 0xe3418acb), new Word64(0x5b9cca4f, 0x7763e373), new Word64(0x682e6ff3, 0xd6b2b8a3), new Word64(0x748f82ee, 0x5defb2fc), new Word64(0x78a5636f, 0x43172f60), new Word64(0x84c87814, 0xa1f0ab72), new Word64(0x8cc70208, 0x1a6439ec), new Word64(0x90befffa, 0x23631e28), new Word64(0xa4506ceb, 0xde82bde9), new Word64(0xbef9a3f7, 0xb2c67915), new Word64(0xc67178f2, 0xe372532b), new Word64(0xca273ece, 0xea26619c), new Word64(0xd186b8c7, 0x21c0c207), new Word64(0xeada7dd6, 0xcde0eb1e), new Word64(0xf57d4f7f, 0xee6ed178), new Word64(0x06f067aa, 0x72176fba), new Word64(0x0a637dc5, 0xa2c898a6), new Word64(0x113f9804, 0xbef90dae), new Word64(0x1b710b35, 0x131c471b), new Word64(0x28db77f5, 0x23047d84), new Word64(0x32caab7b, 0x40c72493), new Word64(0x3c9ebe0a, 0x15c9bebc), new Word64(0x431d67c4, 0x9c100d4c), new Word64(0x4cc5d4be, 0xcb3e42b6), new Word64(0x597f299c, 0xfc657e2a), new Word64(0x5fcb6fab, 0x3ad6faec), new Word64(0x6c44198c, 0x4a475817)]; + function hash(data, offset, length, mode384 = false) { + let h0, h1, h2, h3, h4, h5, h6, h7; + if (!mode384) { + h0 = new Word64(0x6a09e667, 0xf3bcc908); + h1 = new Word64(0xbb67ae85, 0x84caa73b); + h2 = new Word64(0x3c6ef372, 0xfe94f82b); + h3 = new Word64(0xa54ff53a, 0x5f1d36f1); + h4 = new Word64(0x510e527f, 0xade682d1); + h5 = new Word64(0x9b05688c, 0x2b3e6c1f); + h6 = new Word64(0x1f83d9ab, 0xfb41bd6b); + h7 = new Word64(0x5be0cd19, 0x137e2179); + } else { + h0 = new Word64(0xcbbb9d5d, 0xc1059ed8); + h1 = new Word64(0x629a292a, 0x367cd507); + h2 = new Word64(0x9159015a, 0x3070dd17); + h3 = new Word64(0x152fecd8, 0xf70e5939); + h4 = new Word64(0x67332667, 0xffc00b31); + h5 = new Word64(0x8eb44a87, 0x68581511); + h6 = new Word64(0xdb0c2e0d, 0x64f98fa7); + h7 = new Word64(0x47b5481d, 0xbefa4fa4); + } + const paddedLength = Math.ceil((length + 17) / 128) * 128; + const padded = new Uint8Array(paddedLength); + let i, j; + for (i = 0; i < length; ++i) { + padded[i] = data[offset++]; + } + padded[i++] = 0x80; + const n = paddedLength - 16; + while (i < n) { + padded[i++] = 0; + } + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = length >>> 29 & 0xff; + padded[i++] = length >> 21 & 0xff; + padded[i++] = length >> 13 & 0xff; + padded[i++] = length >> 5 & 0xff; + padded[i++] = length << 3 & 0xff; + const w = new Array(80); + for (i = 0; i < 80; i++) { + w[i] = new Word64(0, 0); + } + let a = new Word64(0, 0), + b = new Word64(0, 0), + c = new Word64(0, 0); + let d = new Word64(0, 0), + e = new Word64(0, 0), + f = new Word64(0, 0); + let g = new Word64(0, 0), + h = new Word64(0, 0); + const t1 = new Word64(0, 0), + t2 = new Word64(0, 0); + const tmp1 = new Word64(0, 0), + tmp2 = new Word64(0, 0); + let tmp3; + for (i = 0; i < paddedLength;) { + for (j = 0; j < 16; ++j) { + w[j].high = padded[i] << 24 | padded[i + 1] << 16 | padded[i + 2] << 8 | padded[i + 3]; + w[j].low = padded[i + 4] << 24 | padded[i + 5] << 16 | padded[i + 6] << 8 | padded[i + 7]; + i += 8; + } + for (j = 16; j < 80; ++j) { + tmp3 = w[j]; + littleSigmaPrime(tmp3, w[j - 2], tmp2); + tmp3.add(w[j - 7]); + littleSigma(tmp1, w[j - 15], tmp2); + tmp3.add(tmp1); + tmp3.add(w[j - 16]); + } + a.assign(h0); + b.assign(h1); + c.assign(h2); + d.assign(h3); + e.assign(h4); + f.assign(h5); + g.assign(h6); + h.assign(h7); + for (j = 0; j < 80; ++j) { + t1.assign(h); + sigmaPrime(tmp1, e, tmp2); + t1.add(tmp1); + ch(tmp1, e, f, g, tmp2); + t1.add(tmp1); + t1.add(k[j]); + t1.add(w[j]); + sigma(t2, a, tmp2); + maj(tmp1, a, b, c, tmp2); + t2.add(tmp1); + tmp3 = h; + h = g; + g = f; + f = e; + d.add(t1); + e = d; + d = c; + c = b; + b = a; + tmp3.assign(t1); + tmp3.add(t2); + a = tmp3; + } + h0.add(a); + h1.add(b); + h2.add(c); + h3.add(d); + h4.add(e); + h5.add(f); + h6.add(g); + h7.add(h); + } + let result; + if (!mode384) { + result = new Uint8Array(64); + h0.copyTo(result, 0); + h1.copyTo(result, 8); + h2.copyTo(result, 16); + h3.copyTo(result, 24); + h4.copyTo(result, 32); + h5.copyTo(result, 40); + h6.copyTo(result, 48); + h7.copyTo(result, 56); + } else { + result = new Uint8Array(48); + h0.copyTo(result, 0); + h1.copyTo(result, 8); + h2.copyTo(result, 16); + h3.copyTo(result, 24); + h4.copyTo(result, 32); + h5.copyTo(result, 40); + } + return result; + } + return hash; +}(); +exports.calculateSHA512 = calculateSHA512; +function calculateSHA384(data, offset, length) { + return calculateSHA512(data, offset, length, true); +} +class NullCipher { + decryptBlock(data) { + return data; + } + encrypt(data) { + return data; + } +} +class AESBaseCipher { + constructor() { + if (this.constructor === AESBaseCipher) { + (0, _util.unreachable)("Cannot initialize AESBaseCipher."); + } + this._s = new Uint8Array([0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]); + this._inv_s = new Uint8Array([0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d]); + this._mix = new Uint32Array([0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3]); + this._mixCol = new Uint8Array(256); + for (let i = 0; i < 256; i++) { + this._mixCol[i] = i < 128 ? i << 1 : i << 1 ^ 0x1b; + } + this.buffer = new Uint8Array(16); + this.bufferPosition = 0; + } + _expandKey(cipherKey) { + (0, _util.unreachable)("Cannot call `_expandKey` on the base class"); + } + _decrypt(input, key) { + let t, u, v; + const state = new Uint8Array(16); + state.set(input); + for (let j = 0, k = this._keySize; j < 16; ++j, ++k) { + state[j] ^= key[k]; + } + for (let i = this._cyclesOfRepetition - 1; i >= 1; --i) { + t = state[13]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = state[1]; + state[1] = t; + t = state[14]; + u = state[10]; + state[14] = state[6]; + state[10] = state[2]; + state[6] = t; + state[2] = u; + t = state[15]; + u = state[11]; + v = state[7]; + state[15] = state[3]; + state[11] = t; + state[7] = u; + state[3] = v; + for (let j = 0; j < 16; ++j) { + state[j] = this._inv_s[state[j]]; + } + for (let j = 0, k = i * 16; j < 16; ++j, ++k) { + state[j] ^= key[k]; + } + for (let j = 0; j < 16; j += 4) { + const s0 = this._mix[state[j]]; + const s1 = this._mix[state[j + 1]]; + const s2 = this._mix[state[j + 2]]; + const s3 = this._mix[state[j + 3]]; + t = s0 ^ s1 >>> 8 ^ s1 << 24 ^ s2 >>> 16 ^ s2 << 16 ^ s3 >>> 24 ^ s3 << 8; + state[j] = t >>> 24 & 0xff; + state[j + 1] = t >> 16 & 0xff; + state[j + 2] = t >> 8 & 0xff; + state[j + 3] = t & 0xff; + } + } + t = state[13]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = state[1]; + state[1] = t; + t = state[14]; + u = state[10]; + state[14] = state[6]; + state[10] = state[2]; + state[6] = t; + state[2] = u; + t = state[15]; + u = state[11]; + v = state[7]; + state[15] = state[3]; + state[11] = t; + state[7] = u; + state[3] = v; + for (let j = 0; j < 16; ++j) { + state[j] = this._inv_s[state[j]]; + state[j] ^= key[j]; + } + return state; + } + _encrypt(input, key) { + const s = this._s; + let t, u, v; + const state = new Uint8Array(16); + state.set(input); + for (let j = 0; j < 16; ++j) { + state[j] ^= key[j]; + } + for (let i = 1; i < this._cyclesOfRepetition; i++) { + for (let j = 0; j < 16; ++j) { + state[j] = s[state[j]]; + } + v = state[1]; + state[1] = state[5]; + state[5] = state[9]; + state[9] = state[13]; + state[13] = v; + v = state[2]; + u = state[6]; + state[2] = state[10]; + state[6] = state[14]; + state[10] = v; + state[14] = u; + v = state[3]; + u = state[7]; + t = state[11]; + state[3] = state[15]; + state[7] = v; + state[11] = u; + state[15] = t; + for (let j = 0; j < 16; j += 4) { + const s0 = state[j + 0]; + const s1 = state[j + 1]; + const s2 = state[j + 2]; + const s3 = state[j + 3]; + t = s0 ^ s1 ^ s2 ^ s3; + state[j + 0] ^= t ^ this._mixCol[s0 ^ s1]; + state[j + 1] ^= t ^ this._mixCol[s1 ^ s2]; + state[j + 2] ^= t ^ this._mixCol[s2 ^ s3]; + state[j + 3] ^= t ^ this._mixCol[s3 ^ s0]; + } + for (let j = 0, k = i * 16; j < 16; ++j, ++k) { + state[j] ^= key[k]; + } + } + for (let j = 0; j < 16; ++j) { + state[j] = s[state[j]]; + } + v = state[1]; + state[1] = state[5]; + state[5] = state[9]; + state[9] = state[13]; + state[13] = v; + v = state[2]; + u = state[6]; + state[2] = state[10]; + state[6] = state[14]; + state[10] = v; + state[14] = u; + v = state[3]; + u = state[7]; + t = state[11]; + state[3] = state[15]; + state[7] = v; + state[11] = u; + state[15] = t; + for (let j = 0, k = this._keySize; j < 16; ++j, ++k) { + state[j] ^= key[k]; + } + return state; + } + _decryptBlock2(data, finalize) { + const sourceLength = data.length; + let buffer = this.buffer, + bufferLength = this.bufferPosition; + const result = []; + let iv = this.iv; + for (let i = 0; i < sourceLength; ++i) { + buffer[bufferLength] = data[i]; + ++bufferLength; + if (bufferLength < 16) { + continue; + } + const plain = this._decrypt(buffer, this._key); + for (let j = 0; j < 16; ++j) { + plain[j] ^= iv[j]; + } + iv = buffer; + result.push(plain); + buffer = new Uint8Array(16); + bufferLength = 0; + } + this.buffer = buffer; + this.bufferLength = bufferLength; + this.iv = iv; + if (result.length === 0) { + return new Uint8Array(0); + } + let outputLength = 16 * result.length; + if (finalize) { + const lastBlock = result.at(-1); + let psLen = lastBlock[15]; + if (psLen <= 16) { + for (let i = 15, ii = 16 - psLen; i >= ii; --i) { + if (lastBlock[i] !== psLen) { + psLen = 0; + break; + } + } + outputLength -= psLen; + result[result.length - 1] = lastBlock.subarray(0, 16 - psLen); + } + } + const output = new Uint8Array(outputLength); + for (let i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) { + output.set(result[i], j); + } + return output; + } + decryptBlock(data, finalize, iv = null) { + const sourceLength = data.length; + const buffer = this.buffer; + let bufferLength = this.bufferPosition; + if (iv) { + this.iv = iv; + } else { + for (let i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength) { + buffer[bufferLength] = data[i]; + } + if (bufferLength < 16) { + this.bufferLength = bufferLength; + return new Uint8Array(0); + } + this.iv = buffer; + data = data.subarray(16); + } + this.buffer = new Uint8Array(16); + this.bufferLength = 0; + this.decryptBlock = this._decryptBlock2; + return this.decryptBlock(data, finalize); + } + encrypt(data, iv) { + const sourceLength = data.length; + let buffer = this.buffer, + bufferLength = this.bufferPosition; + const result = []; + if (!iv) { + iv = new Uint8Array(16); + } + for (let i = 0; i < sourceLength; ++i) { + buffer[bufferLength] = data[i]; + ++bufferLength; + if (bufferLength < 16) { + continue; + } + for (let j = 0; j < 16; ++j) { + buffer[j] ^= iv[j]; + } + const cipher = this._encrypt(buffer, this._key); + iv = cipher; + result.push(cipher); + buffer = new Uint8Array(16); + bufferLength = 0; + } + this.buffer = buffer; + this.bufferLength = bufferLength; + this.iv = iv; + if (result.length === 0) { + return new Uint8Array(0); + } + const outputLength = 16 * result.length; + const output = new Uint8Array(outputLength); + for (let i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) { + output.set(result[i], j); + } + return output; + } +} +class AES128Cipher extends AESBaseCipher { + constructor(key) { + super(); + this._cyclesOfRepetition = 10; + this._keySize = 160; + this._rcon = new Uint8Array([0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d]); + this._key = this._expandKey(key); + } + _expandKey(cipherKey) { + const b = 176; + const s = this._s; + const rcon = this._rcon; + const result = new Uint8Array(b); + result.set(cipherKey); + for (let j = 16, i = 1; j < b; ++i) { + let t1 = result[j - 3]; + let t2 = result[j - 2]; + let t3 = result[j - 1]; + let t4 = result[j - 4]; + t1 = s[t1]; + t2 = s[t2]; + t3 = s[t3]; + t4 = s[t4]; + t1 ^= rcon[i]; + for (let n = 0; n < 4; ++n) { + result[j] = t1 ^= result[j - 16]; + j++; + result[j] = t2 ^= result[j - 16]; + j++; + result[j] = t3 ^= result[j - 16]; + j++; + result[j] = t4 ^= result[j - 16]; + j++; + } + } + return result; + } +} +exports.AES128Cipher = AES128Cipher; +class AES256Cipher extends AESBaseCipher { + constructor(key) { + super(); + this._cyclesOfRepetition = 14; + this._keySize = 224; + this._key = this._expandKey(key); + } + _expandKey(cipherKey) { + const b = 240; + const s = this._s; + const result = new Uint8Array(b); + result.set(cipherKey); + let r = 1; + let t1, t2, t3, t4; + for (let j = 32, i = 1; j < b; ++i) { + if (j % 32 === 16) { + t1 = s[t1]; + t2 = s[t2]; + t3 = s[t3]; + t4 = s[t4]; + } else if (j % 32 === 0) { + t1 = result[j - 3]; + t2 = result[j - 2]; + t3 = result[j - 1]; + t4 = result[j - 4]; + t1 = s[t1]; + t2 = s[t2]; + t3 = s[t3]; + t4 = s[t4]; + t1 ^= r; + if ((r <<= 1) >= 256) { + r = (r ^ 0x1b) & 0xff; + } + } + for (let n = 0; n < 4; ++n) { + result[j] = t1 ^= result[j - 32]; + j++; + result[j] = t2 ^= result[j - 32]; + j++; + result[j] = t3 ^= result[j - 32]; + j++; + result[j] = t4 ^= result[j - 32]; + j++; + } + } + return result; + } +} +exports.AES256Cipher = AES256Cipher; +class PDF17 { + checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) { + const hashData = new Uint8Array(password.length + 56); + hashData.set(password, 0); + hashData.set(ownerValidationSalt, password.length); + hashData.set(userBytes, password.length + ownerValidationSalt.length); + const result = calculateSHA256(hashData, 0, hashData.length); + return (0, _util.isArrayEqual)(result, ownerPassword); + } + checkUserPassword(password, userValidationSalt, userPassword) { + const hashData = new Uint8Array(password.length + 8); + hashData.set(password, 0); + hashData.set(userValidationSalt, password.length); + const result = calculateSHA256(hashData, 0, hashData.length); + return (0, _util.isArrayEqual)(result, userPassword); + } + getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) { + const hashData = new Uint8Array(password.length + 56); + hashData.set(password, 0); + hashData.set(ownerKeySalt, password.length); + hashData.set(userBytes, password.length + ownerKeySalt.length); + const key = calculateSHA256(hashData, 0, hashData.length); + const cipher = new AES256Cipher(key); + return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16)); + } + getUserKey(password, userKeySalt, userEncryption) { + const hashData = new Uint8Array(password.length + 8); + hashData.set(password, 0); + hashData.set(userKeySalt, password.length); + const key = calculateSHA256(hashData, 0, hashData.length); + const cipher = new AES256Cipher(key); + return cipher.decryptBlock(userEncryption, false, new Uint8Array(16)); + } +} +exports.PDF17 = PDF17; +class PDF20 { + _hash(password, input, userBytes) { + let k = calculateSHA256(input, 0, input.length).subarray(0, 32); + let e = [0]; + let i = 0; + while (i < 64 || e.at(-1) > i - 32) { + const combinedLength = password.length + k.length + userBytes.length, + combinedArray = new Uint8Array(combinedLength); + let writeOffset = 0; + combinedArray.set(password, writeOffset); + writeOffset += password.length; + combinedArray.set(k, writeOffset); + writeOffset += k.length; + combinedArray.set(userBytes, writeOffset); + const k1 = new Uint8Array(combinedLength * 64); + for (let j = 0, pos = 0; j < 64; j++, pos += combinedLength) { + k1.set(combinedArray, pos); + } + const cipher = new AES128Cipher(k.subarray(0, 16)); + e = cipher.encrypt(k1, k.subarray(16, 32)); + const remainder = e.slice(0, 16).reduce((a, b) => a + b, 0) % 3; + if (remainder === 0) { + k = calculateSHA256(e, 0, e.length); + } else if (remainder === 1) { + k = calculateSHA384(e, 0, e.length); + } else if (remainder === 2) { + k = calculateSHA512(e, 0, e.length); + } + i++; + } + return k.subarray(0, 32); + } + checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) { + const hashData = new Uint8Array(password.length + 56); + hashData.set(password, 0); + hashData.set(ownerValidationSalt, password.length); + hashData.set(userBytes, password.length + ownerValidationSalt.length); + const result = this._hash(password, hashData, userBytes); + return (0, _util.isArrayEqual)(result, ownerPassword); + } + checkUserPassword(password, userValidationSalt, userPassword) { + const hashData = new Uint8Array(password.length + 8); + hashData.set(password, 0); + hashData.set(userValidationSalt, password.length); + const result = this._hash(password, hashData, []); + return (0, _util.isArrayEqual)(result, userPassword); + } + getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) { + const hashData = new Uint8Array(password.length + 56); + hashData.set(password, 0); + hashData.set(ownerKeySalt, password.length); + hashData.set(userBytes, password.length + ownerKeySalt.length); + const key = this._hash(password, hashData, userBytes); + const cipher = new AES256Cipher(key); + return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16)); + } + getUserKey(password, userKeySalt, userEncryption) { + const hashData = new Uint8Array(password.length + 8); + hashData.set(password, 0); + hashData.set(userKeySalt, password.length); + const key = this._hash(password, hashData, []); + const cipher = new AES256Cipher(key); + return cipher.decryptBlock(userEncryption, false, new Uint8Array(16)); + } +} +exports.PDF20 = PDF20; +class CipherTransform { + constructor(stringCipherConstructor, streamCipherConstructor) { + this.StringCipherConstructor = stringCipherConstructor; + this.StreamCipherConstructor = streamCipherConstructor; + } + createStream(stream, length) { + const cipher = new this.StreamCipherConstructor(); + return new _decrypt_stream.DecryptStream(stream, length, function cipherTransformDecryptStream(data, finalize) { + return cipher.decryptBlock(data, finalize); + }); + } + decryptString(s) { + const cipher = new this.StringCipherConstructor(); + let data = (0, _util.stringToBytes)(s); + data = cipher.decryptBlock(data, true); + return (0, _util.bytesToString)(data); + } + encryptString(s) { + const cipher = new this.StringCipherConstructor(); + if (cipher instanceof AESBaseCipher) { + const strLen = s.length; + const pad = 16 - strLen % 16; + s += String.fromCharCode(pad).repeat(pad); + const iv = new Uint8Array(16); + if (typeof crypto !== "undefined") { + crypto.getRandomValues(iv); + } else { + for (let i = 0; i < 16; i++) { + iv[i] = Math.floor(256 * Math.random()); + } + } + let data = (0, _util.stringToBytes)(s); + data = cipher.encrypt(data, iv); + const buf = new Uint8Array(16 + data.length); + buf.set(iv); + buf.set(data, 16); + return (0, _util.bytesToString)(buf); + } + let data = (0, _util.stringToBytes)(s); + data = cipher.encrypt(data); + return (0, _util.bytesToString)(data); + } +} +class CipherTransformFactory { + static #defaultPasswordBytes = new Uint8Array([0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a]); + #createEncryptionKey20(revision, password, ownerPassword, ownerValidationSalt, ownerKeySalt, uBytes, userPassword, userValidationSalt, userKeySalt, ownerEncryption, userEncryption, perms) { + if (password) { + const passwordLength = Math.min(127, password.length); + password = password.subarray(0, passwordLength); + } else { + password = []; + } + const pdfAlgorithm = revision === 6 ? new PDF20() : new PDF17(); + if (pdfAlgorithm.checkUserPassword(password, userValidationSalt, userPassword)) { + return pdfAlgorithm.getUserKey(password, userKeySalt, userEncryption); + } else if (password.length && pdfAlgorithm.checkOwnerPassword(password, ownerValidationSalt, uBytes, ownerPassword)) { + return pdfAlgorithm.getOwnerKey(password, ownerKeySalt, uBytes, ownerEncryption); + } + return null; + } + #prepareKeyData(fileId, password, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata) { + const hashDataSize = 40 + ownerPassword.length + fileId.length; + const hashData = new Uint8Array(hashDataSize); + let i = 0, + j, + n; + if (password) { + n = Math.min(32, password.length); + for (; i < n; ++i) { + hashData[i] = password[i]; + } + } + j = 0; + while (i < 32) { + hashData[i++] = CipherTransformFactory.#defaultPasswordBytes[j++]; + } + for (j = 0, n = ownerPassword.length; j < n; ++j) { + hashData[i++] = ownerPassword[j]; + } + hashData[i++] = flags & 0xff; + hashData[i++] = flags >> 8 & 0xff; + hashData[i++] = flags >> 16 & 0xff; + hashData[i++] = flags >>> 24 & 0xff; + for (j = 0, n = fileId.length; j < n; ++j) { + hashData[i++] = fileId[j]; + } + if (revision >= 4 && !encryptMetadata) { + hashData[i++] = 0xff; + hashData[i++] = 0xff; + hashData[i++] = 0xff; + hashData[i++] = 0xff; + } + let hash = calculateMD5(hashData, 0, i); + const keyLengthInBytes = keyLength >> 3; + if (revision >= 3) { + for (j = 0; j < 50; ++j) { + hash = calculateMD5(hash, 0, keyLengthInBytes); + } + } + const encryptionKey = hash.subarray(0, keyLengthInBytes); + let cipher, checkData; + if (revision >= 3) { + for (i = 0; i < 32; ++i) { + hashData[i] = CipherTransformFactory.#defaultPasswordBytes[i]; + } + for (j = 0, n = fileId.length; j < n; ++j) { + hashData[i++] = fileId[j]; + } + cipher = new ARCFourCipher(encryptionKey); + checkData = cipher.encryptBlock(calculateMD5(hashData, 0, i)); + n = encryptionKey.length; + const derivedKey = new Uint8Array(n); + for (j = 1; j <= 19; ++j) { + for (let k = 0; k < n; ++k) { + derivedKey[k] = encryptionKey[k] ^ j; + } + cipher = new ARCFourCipher(derivedKey); + checkData = cipher.encryptBlock(checkData); + } + for (j = 0, n = checkData.length; j < n; ++j) { + if (userPassword[j] !== checkData[j]) { + return null; + } + } + } else { + cipher = new ARCFourCipher(encryptionKey); + checkData = cipher.encryptBlock(CipherTransformFactory.#defaultPasswordBytes); + for (j = 0, n = checkData.length; j < n; ++j) { + if (userPassword[j] !== checkData[j]) { + return null; + } + } + } + return encryptionKey; + } + #decodeUserPassword(password, ownerPassword, revision, keyLength) { + const hashData = new Uint8Array(32); + let i = 0; + const n = Math.min(32, password.length); + for (; i < n; ++i) { + hashData[i] = password[i]; + } + let j = 0; + while (i < 32) { + hashData[i++] = CipherTransformFactory.#defaultPasswordBytes[j++]; + } + let hash = calculateMD5(hashData, 0, i); + const keyLengthInBytes = keyLength >> 3; + if (revision >= 3) { + for (j = 0; j < 50; ++j) { + hash = calculateMD5(hash, 0, hash.length); + } + } + let cipher, userPassword; + if (revision >= 3) { + userPassword = ownerPassword; + const derivedKey = new Uint8Array(keyLengthInBytes); + for (j = 19; j >= 0; j--) { + for (let k = 0; k < keyLengthInBytes; ++k) { + derivedKey[k] = hash[k] ^ j; + } + cipher = new ARCFourCipher(derivedKey); + userPassword = cipher.encryptBlock(userPassword); + } + } else { + cipher = new ARCFourCipher(hash.subarray(0, keyLengthInBytes)); + userPassword = cipher.encryptBlock(ownerPassword); + } + return userPassword; + } + #buildObjectKey(num, gen, encryptionKey, isAes = false) { + const key = new Uint8Array(encryptionKey.length + 9); + const n = encryptionKey.length; + let i; + for (i = 0; i < n; ++i) { + key[i] = encryptionKey[i]; + } + key[i++] = num & 0xff; + key[i++] = num >> 8 & 0xff; + key[i++] = num >> 16 & 0xff; + key[i++] = gen & 0xff; + key[i++] = gen >> 8 & 0xff; + if (isAes) { + key[i++] = 0x73; + key[i++] = 0x41; + key[i++] = 0x6c; + key[i++] = 0x54; + } + const hash = calculateMD5(key, 0, i); + return hash.subarray(0, Math.min(encryptionKey.length + 5, 16)); + } + #buildCipherConstructor(cf, name, num, gen, key) { + if (!(name instanceof _primitives.Name)) { + throw new _util.FormatError("Invalid crypt filter name."); + } + const self = this; + const cryptFilter = cf.get(name.name); + const cfm = cryptFilter?.get("CFM"); + if (!cfm || cfm.name === "None") { + return function () { + return new NullCipher(); + }; + } + if (cfm.name === "V2") { + return function () { + return new ARCFourCipher(self.#buildObjectKey(num, gen, key, false)); + }; + } + if (cfm.name === "AESV2") { + return function () { + return new AES128Cipher(self.#buildObjectKey(num, gen, key, true)); + }; + } + if (cfm.name === "AESV3") { + return function () { + return new AES256Cipher(key); + }; + } + throw new _util.FormatError("Unknown crypto method"); + } + constructor(dict, fileId, password) { + const filter = dict.get("Filter"); + if (!(0, _primitives.isName)(filter, "Standard")) { + throw new _util.FormatError("unknown encryption method"); + } + this.filterName = filter.name; + this.dict = dict; + const algorithm = dict.get("V"); + if (!Number.isInteger(algorithm) || algorithm !== 1 && algorithm !== 2 && algorithm !== 4 && algorithm !== 5) { + throw new _util.FormatError("unsupported encryption algorithm"); + } + this.algorithm = algorithm; + let keyLength = dict.get("Length"); + if (!keyLength) { + if (algorithm <= 3) { + keyLength = 40; + } else { + const cfDict = dict.get("CF"); + const streamCryptoName = dict.get("StmF"); + if (cfDict instanceof _primitives.Dict && streamCryptoName instanceof _primitives.Name) { + cfDict.suppressEncryption = true; + const handlerDict = cfDict.get(streamCryptoName.name); + keyLength = handlerDict?.get("Length") || 128; + if (keyLength < 40) { + keyLength <<= 3; + } + } + } + } + if (!Number.isInteger(keyLength) || keyLength < 40 || keyLength % 8 !== 0) { + throw new _util.FormatError("invalid key length"); + } + const ownerBytes = (0, _util.stringToBytes)(dict.get("O")), + userBytes = (0, _util.stringToBytes)(dict.get("U")); + const ownerPassword = ownerBytes.subarray(0, 32); + const userPassword = userBytes.subarray(0, 32); + const flags = dict.get("P"); + const revision = dict.get("R"); + const encryptMetadata = (algorithm === 4 || algorithm === 5) && dict.get("EncryptMetadata") !== false; + this.encryptMetadata = encryptMetadata; + const fileIdBytes = (0, _util.stringToBytes)(fileId); + let passwordBytes; + if (password) { + if (revision === 6) { + try { + password = (0, _util.utf8StringToString)(password); + } catch { + (0, _util.warn)("CipherTransformFactory: Unable to convert UTF8 encoded password."); + } + } + passwordBytes = (0, _util.stringToBytes)(password); + } + let encryptionKey; + if (algorithm !== 5) { + encryptionKey = this.#prepareKeyData(fileIdBytes, passwordBytes, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata); + } else { + const ownerValidationSalt = ownerBytes.subarray(32, 40); + const ownerKeySalt = ownerBytes.subarray(40, 48); + const uBytes = userBytes.subarray(0, 48); + const userValidationSalt = userBytes.subarray(32, 40); + const userKeySalt = userBytes.subarray(40, 48); + const ownerEncryption = (0, _util.stringToBytes)(dict.get("OE")); + const userEncryption = (0, _util.stringToBytes)(dict.get("UE")); + const perms = (0, _util.stringToBytes)(dict.get("Perms")); + encryptionKey = this.#createEncryptionKey20(revision, passwordBytes, ownerPassword, ownerValidationSalt, ownerKeySalt, uBytes, userPassword, userValidationSalt, userKeySalt, ownerEncryption, userEncryption, perms); + } + if (!encryptionKey && !password) { + throw new _util.PasswordException("No password given", _util.PasswordResponses.NEED_PASSWORD); + } else if (!encryptionKey && password) { + const decodedPassword = this.#decodeUserPassword(passwordBytes, ownerPassword, revision, keyLength); + encryptionKey = this.#prepareKeyData(fileIdBytes, decodedPassword, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata); + } + if (!encryptionKey) { + throw new _util.PasswordException("Incorrect Password", _util.PasswordResponses.INCORRECT_PASSWORD); + } + this.encryptionKey = encryptionKey; + if (algorithm >= 4) { + const cf = dict.get("CF"); + if (cf instanceof _primitives.Dict) { + cf.suppressEncryption = true; + } + this.cf = cf; + this.stmf = dict.get("StmF") || _primitives.Name.get("Identity"); + this.strf = dict.get("StrF") || _primitives.Name.get("Identity"); + this.eff = dict.get("EFF") || this.stmf; + } + } + createCipherTransform(num, gen) { + if (this.algorithm === 4 || this.algorithm === 5) { + return new CipherTransform(this.#buildCipherConstructor(this.cf, this.strf, num, gen, this.encryptionKey), this.#buildCipherConstructor(this.cf, this.stmf, num, gen, this.encryptionKey)); + } + const key = this.#buildObjectKey(num, gen, this.encryptionKey, false); + const cipherConstructor = function () { + return new ARCFourCipher(key); + }; + return new CipherTransform(cipherConstructor, cipherConstructor); + } +} +exports.CipherTransformFactory = CipherTransformFactory; + +/***/ }), +/* 75 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.DecryptStream = void 0; +var _decode_stream = __w_pdfjs_require__(18); +const chunkSize = 512; +class DecryptStream extends _decode_stream.DecodeStream { + constructor(str, maybeLength, decrypt) { + super(maybeLength); + this.str = str; + this.dict = str.dict; + this.decrypt = decrypt; + this.nextChunk = null; + this.initialized = false; + } + readBlock() { + let chunk; + if (this.initialized) { + chunk = this.nextChunk; + } else { + chunk = this.str.getBytes(chunkSize); + this.initialized = true; + } + if (!chunk || chunk.length === 0) { + this.eof = true; + return; + } + this.nextChunk = this.str.getBytes(chunkSize); + const hasMoreData = this.nextChunk?.length > 0; + const decrypt = this.decrypt; + chunk = decrypt(chunk, !hasMoreData); + const bufferLength = this.bufferLength, + newLength = bufferLength + chunk.length, + buffer = this.ensureBuffer(newLength); + buffer.set(chunk, bufferLength); + this.bufferLength = newLength; + } +} +exports.DecryptStream = DecryptStream; + +/***/ }), +/* 76 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ObjectLoader = void 0; +var _primitives = __w_pdfjs_require__(4); +var _base_stream = __w_pdfjs_require__(5); +var _core_utils = __w_pdfjs_require__(3); +var _util = __w_pdfjs_require__(2); +function mayHaveChildren(value) { + return value instanceof _primitives.Ref || value instanceof _primitives.Dict || value instanceof _base_stream.BaseStream || Array.isArray(value); +} +function addChildren(node, nodesToVisit) { + if (node instanceof _primitives.Dict) { + node = node.getRawValues(); + } else if (node instanceof _base_stream.BaseStream) { + node = node.dict.getRawValues(); + } else if (!Array.isArray(node)) { + return; + } + for (const rawValue of node) { + if (mayHaveChildren(rawValue)) { + nodesToVisit.push(rawValue); + } + } +} +class ObjectLoader { + constructor(dict, keys, xref) { + this.dict = dict; + this.keys = keys; + this.xref = xref; + this.refSet = null; + } + async load() { + if (this.xref.stream.isDataLoaded) { + return undefined; + } + const { + keys, + dict + } = this; + this.refSet = new _primitives.RefSet(); + const nodesToVisit = []; + for (const key of keys) { + const rawValue = dict.getRaw(key); + if (rawValue !== undefined) { + nodesToVisit.push(rawValue); + } + } + return this._walk(nodesToVisit); + } + async _walk(nodesToVisit) { + const nodesToRevisit = []; + const pendingRequests = []; + while (nodesToVisit.length) { + let currentNode = nodesToVisit.pop(); + if (currentNode instanceof _primitives.Ref) { + if (this.refSet.has(currentNode)) { + continue; + } + try { + this.refSet.put(currentNode); + currentNode = this.xref.fetch(currentNode); + } catch (ex) { + if (!(ex instanceof _core_utils.MissingDataException)) { + (0, _util.warn)(`ObjectLoader._walk - requesting all data: "${ex}".`); + this.refSet = null; + const { + manager + } = this.xref.stream; + return manager.requestAllChunks(); + } + nodesToRevisit.push(currentNode); + pendingRequests.push({ + begin: ex.begin, + end: ex.end + }); + } + } + if (currentNode instanceof _base_stream.BaseStream) { + const baseStreams = currentNode.getBaseStreams(); + if (baseStreams) { + let foundMissingData = false; + for (const stream of baseStreams) { + if (stream.isDataLoaded) { + continue; + } + foundMissingData = true; + pendingRequests.push({ + begin: stream.start, + end: stream.end + }); + } + if (foundMissingData) { + nodesToRevisit.push(currentNode); + } + } + } + addChildren(currentNode, nodesToVisit); + } + if (pendingRequests.length) { + await this.xref.stream.manager.requestRanges(pendingRequests); + for (const node of nodesToRevisit) { + if (node instanceof _primitives.Ref) { + this.refSet.remove(node); + } + } + return this._walk(nodesToRevisit); + } + this.refSet = null; + return undefined; + } +} +exports.ObjectLoader = ObjectLoader; + +/***/ }), +/* 77 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.XFAFactory = void 0; +var _symbol_utils = __w_pdfjs_require__(78); +var _bind = __w_pdfjs_require__(79); +var _data = __w_pdfjs_require__(89); +var _fonts = __w_pdfjs_require__(85); +var _utils = __w_pdfjs_require__(84); +var _util = __w_pdfjs_require__(2); +var _parser = __w_pdfjs_require__(90); +var _xhtml = __w_pdfjs_require__(100); +class XFAFactory { + constructor(data) { + try { + this.root = new _parser.XFAParser().parse(XFAFactory._createDocument(data)); + const binder = new _bind.Binder(this.root); + this.form = binder.bind(); + this.dataHandler = new _data.DataHandler(this.root, binder.getData()); + this.form[_symbol_utils.$globalData].template = this.form; + } catch (e) { + (0, _util.warn)(`XFA - an error occurred during parsing and binding: ${e}`); + } + } + isValid() { + return this.root && this.form; + } + _createPagesHelper() { + const iterator = this.form[_symbol_utils.$toPages](); + return new Promise((resolve, reject) => { + const nextIteration = () => { + try { + const value = iterator.next(); + if (value.done) { + resolve(value.value); + } else { + setTimeout(nextIteration, 0); + } + } catch (e) { + reject(e); + } + }; + setTimeout(nextIteration, 0); + }); + } + async _createPages() { + try { + this.pages = await this._createPagesHelper(); + this.dims = this.pages.children.map(c => { + const { + width, + height + } = c.attributes.style; + return [0, 0, parseInt(width), parseInt(height)]; + }); + } catch (e) { + (0, _util.warn)(`XFA - an error occurred during layout: ${e}`); + } + } + getBoundingBox(pageIndex) { + return this.dims[pageIndex]; + } + async getNumPages() { + if (!this.pages) { + await this._createPages(); + } + return this.dims.length; + } + setImages(images) { + this.form[_symbol_utils.$globalData].images = images; + } + setFonts(fonts) { + this.form[_symbol_utils.$globalData].fontFinder = new _fonts.FontFinder(fonts); + const missingFonts = []; + for (let typeface of this.form[_symbol_utils.$globalData].usedTypefaces) { + typeface = (0, _utils.stripQuotes)(typeface); + const font = this.form[_symbol_utils.$globalData].fontFinder.find(typeface); + if (!font) { + missingFonts.push(typeface); + } + } + if (missingFonts.length > 0) { + return missingFonts; + } + return null; + } + appendFonts(fonts, reallyMissingFonts) { + this.form[_symbol_utils.$globalData].fontFinder.add(fonts, reallyMissingFonts); + } + async getPages() { + if (!this.pages) { + await this._createPages(); + } + const pages = this.pages; + this.pages = null; + return pages; + } + serializeData(storage) { + return this.dataHandler.serialize(storage); + } + static _createDocument(data) { + if (!data["/xdp:xdp"]) { + return data["xdp:xdp"]; + } + return Object.values(data).join(""); + } + static getRichTextAsHtml(rc) { + if (!rc || typeof rc !== "string") { + return null; + } + try { + let root = new _parser.XFAParser(_xhtml.XhtmlNamespace, true).parse(rc); + if (!["body", "xhtml"].includes(root[_symbol_utils.$nodeName])) { + const newRoot = _xhtml.XhtmlNamespace.body({}); + newRoot[_symbol_utils.$appendChild](root); + root = newRoot; + } + const result = root[_symbol_utils.$toHTML](); + if (!result.success) { + return null; + } + const { + html + } = result; + const { + attributes + } = html; + if (attributes) { + if (attributes.class) { + attributes.class = attributes.class.filter(attr => !attr.startsWith("xfa")); + } + attributes.dir = "auto"; + } + return { + html, + str: root[_symbol_utils.$text]() + }; + } catch (e) { + (0, _util.warn)(`XFA - an error occurred during parsing of rich text: ${e}`); + } + return null; + } +} +exports.XFAFactory = XFAFactory; + +/***/ }), +/* 78 */ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.$uid = exports.$toStyle = exports.$toString = exports.$toPages = exports.$toHTML = exports.$text = exports.$tabIndex = exports.$setValue = exports.$setSetAttributes = exports.$setId = exports.$searchNode = exports.$root = exports.$resolvePrototypes = exports.$removeChild = exports.$pushPara = exports.$pushGlyphs = exports.$popPara = exports.$onText = exports.$onChildCheck = exports.$onChild = exports.$nsAttributes = exports.$nodeName = exports.$namespaceId = exports.$lastAttribute = exports.$isUsable = exports.$isTransparent = exports.$isThereMoreWidth = exports.$isSplittable = exports.$isNsAgnostic = exports.$isDescendent = exports.$isDataValue = exports.$isCDATAXml = exports.$isBindable = exports.$insertAt = exports.$indexOf = exports.$ids = exports.$hasSettableValue = exports.$globalData = exports.$getTemplateRoot = exports.$getSubformParent = exports.$getRealChildrenByNameIt = exports.$getParent = exports.$getNextPage = exports.$getExtra = exports.$getDataValue = exports.$getContainedChildren = exports.$getChildrenByNameIt = exports.$getChildrenByName = exports.$getChildrenByClass = exports.$getChildren = exports.$getAvailableSpace = exports.$getAttributes = exports.$getAttributeIt = exports.$flushHTML = exports.$finalize = exports.$extra = exports.$dump = exports.$data = exports.$content = exports.$consumed = exports.$clone = exports.$cleanup = exports.$cleanPage = exports.$clean = exports.$childrenToHTML = exports.$appendChild = exports.$addHTML = exports.$acceptWhitespace = void 0; +const $acceptWhitespace = Symbol(); +exports.$acceptWhitespace = $acceptWhitespace; +const $addHTML = Symbol(); +exports.$addHTML = $addHTML; +const $appendChild = Symbol(); +exports.$appendChild = $appendChild; +const $childrenToHTML = Symbol(); +exports.$childrenToHTML = $childrenToHTML; +const $clean = Symbol(); +exports.$clean = $clean; +const $cleanPage = Symbol(); +exports.$cleanPage = $cleanPage; +const $cleanup = Symbol(); +exports.$cleanup = $cleanup; +const $clone = Symbol(); +exports.$clone = $clone; +const $consumed = Symbol(); +exports.$consumed = $consumed; +const $content = Symbol("content"); +exports.$content = $content; +const $data = Symbol("data"); +exports.$data = $data; +const $dump = Symbol(); +exports.$dump = $dump; +const $extra = Symbol("extra"); +exports.$extra = $extra; +const $finalize = Symbol(); +exports.$finalize = $finalize; +const $flushHTML = Symbol(); +exports.$flushHTML = $flushHTML; +const $getAttributeIt = Symbol(); +exports.$getAttributeIt = $getAttributeIt; +const $getAttributes = Symbol(); +exports.$getAttributes = $getAttributes; +const $getAvailableSpace = Symbol(); +exports.$getAvailableSpace = $getAvailableSpace; +const $getChildrenByClass = Symbol(); +exports.$getChildrenByClass = $getChildrenByClass; +const $getChildrenByName = Symbol(); +exports.$getChildrenByName = $getChildrenByName; +const $getChildrenByNameIt = Symbol(); +exports.$getChildrenByNameIt = $getChildrenByNameIt; +const $getDataValue = Symbol(); +exports.$getDataValue = $getDataValue; +const $getExtra = Symbol(); +exports.$getExtra = $getExtra; +const $getRealChildrenByNameIt = Symbol(); +exports.$getRealChildrenByNameIt = $getRealChildrenByNameIt; +const $getChildren = Symbol(); +exports.$getChildren = $getChildren; +const $getContainedChildren = Symbol(); +exports.$getContainedChildren = $getContainedChildren; +const $getNextPage = Symbol(); +exports.$getNextPage = $getNextPage; +const $getSubformParent = Symbol(); +exports.$getSubformParent = $getSubformParent; +const $getParent = Symbol(); +exports.$getParent = $getParent; +const $getTemplateRoot = Symbol(); +exports.$getTemplateRoot = $getTemplateRoot; +const $globalData = Symbol(); +exports.$globalData = $globalData; +const $hasSettableValue = Symbol(); +exports.$hasSettableValue = $hasSettableValue; +const $ids = Symbol(); +exports.$ids = $ids; +const $indexOf = Symbol(); +exports.$indexOf = $indexOf; +const $insertAt = Symbol(); +exports.$insertAt = $insertAt; +const $isCDATAXml = Symbol(); +exports.$isCDATAXml = $isCDATAXml; +const $isBindable = Symbol(); +exports.$isBindable = $isBindable; +const $isDataValue = Symbol(); +exports.$isDataValue = $isDataValue; +const $isDescendent = Symbol(); +exports.$isDescendent = $isDescendent; +const $isNsAgnostic = Symbol(); +exports.$isNsAgnostic = $isNsAgnostic; +const $isSplittable = Symbol(); +exports.$isSplittable = $isSplittable; +const $isThereMoreWidth = Symbol(); +exports.$isThereMoreWidth = $isThereMoreWidth; +const $isTransparent = Symbol(); +exports.$isTransparent = $isTransparent; +const $isUsable = Symbol(); +exports.$isUsable = $isUsable; +const $lastAttribute = Symbol(); +exports.$lastAttribute = $lastAttribute; +const $namespaceId = Symbol("namespaceId"); +exports.$namespaceId = $namespaceId; +const $nodeName = Symbol("nodeName"); +exports.$nodeName = $nodeName; +const $nsAttributes = Symbol(); +exports.$nsAttributes = $nsAttributes; +const $onChild = Symbol(); +exports.$onChild = $onChild; +const $onChildCheck = Symbol(); +exports.$onChildCheck = $onChildCheck; +const $onText = Symbol(); +exports.$onText = $onText; +const $pushGlyphs = Symbol(); +exports.$pushGlyphs = $pushGlyphs; +const $popPara = Symbol(); +exports.$popPara = $popPara; +const $pushPara = Symbol(); +exports.$pushPara = $pushPara; +const $removeChild = Symbol(); +exports.$removeChild = $removeChild; +const $root = Symbol("root"); +exports.$root = $root; +const $resolvePrototypes = Symbol(); +exports.$resolvePrototypes = $resolvePrototypes; +const $searchNode = Symbol(); +exports.$searchNode = $searchNode; +const $setId = Symbol(); +exports.$setId = $setId; +const $setSetAttributes = Symbol(); +exports.$setSetAttributes = $setSetAttributes; +const $setValue = Symbol(); +exports.$setValue = $setValue; +const $tabIndex = Symbol(); +exports.$tabIndex = $tabIndex; +const $text = Symbol(); +exports.$text = $text; +const $toPages = Symbol(); +exports.$toPages = $toPages; +const $toHTML = Symbol(); +exports.$toHTML = $toHTML; +const $toString = Symbol(); +exports.$toString = $toString; +const $toStyle = Symbol(); +exports.$toStyle = $toStyle; +const $uid = Symbol("uid"); +exports.$uid = $uid; + +/***/ }), +/* 79 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Binder = void 0; +var _symbol_utils = __w_pdfjs_require__(78); +var _template = __w_pdfjs_require__(80); +var _som = __w_pdfjs_require__(88); +var _xfa_object = __w_pdfjs_require__(87); +var _namespaces = __w_pdfjs_require__(81); +var _util = __w_pdfjs_require__(2); +const NS_DATASETS = _namespaces.NamespaceIds.datasets.id; +function createText(content) { + const node = new _template.Text({}); + node[_symbol_utils.$content] = content; + return node; +} +class Binder { + constructor(root) { + this.root = root; + this.datasets = root.datasets; + this.data = root.datasets?.data || new _xfa_object.XmlObject(_namespaces.NamespaceIds.datasets.id, "data"); + this.emptyMerge = this.data[_symbol_utils.$getChildren]().length === 0; + this.root.form = this.form = root.template[_symbol_utils.$clone](); + } + _isConsumeData() { + return !this.emptyMerge && this._mergeMode; + } + _isMatchTemplate() { + return !this._isConsumeData(); + } + bind() { + this._bindElement(this.form, this.data); + return this.form; + } + getData() { + return this.data; + } + _bindValue(formNode, data, picture) { + formNode[_symbol_utils.$data] = data; + if (formNode[_symbol_utils.$hasSettableValue]()) { + if (data[_symbol_utils.$isDataValue]()) { + const value = data[_symbol_utils.$getDataValue](); + formNode[_symbol_utils.$setValue](createText(value)); + } else if (formNode instanceof _template.Field && formNode.ui?.choiceList?.open === "multiSelect") { + const value = data[_symbol_utils.$getChildren]().map(child => child[_symbol_utils.$content].trim()).join("\n"); + formNode[_symbol_utils.$setValue](createText(value)); + } else if (this._isConsumeData()) { + (0, _util.warn)(`XFA - Nodes haven't the same type.`); + } + } else if (!data[_symbol_utils.$isDataValue]() || this._isMatchTemplate()) { + this._bindElement(formNode, data); + } else { + (0, _util.warn)(`XFA - Nodes haven't the same type.`); + } + } + _findDataByNameToConsume(name, isValue, dataNode, global) { + if (!name) { + return null; + } + let generator, match; + for (let i = 0; i < 3; i++) { + generator = dataNode[_symbol_utils.$getRealChildrenByNameIt](name, false, true); + while (true) { + match = generator.next().value; + if (!match) { + break; + } + if (isValue === match[_symbol_utils.$isDataValue]()) { + return match; + } + } + if (dataNode[_symbol_utils.$namespaceId] === _namespaces.NamespaceIds.datasets.id && dataNode[_symbol_utils.$nodeName] === "data") { + break; + } + dataNode = dataNode[_symbol_utils.$getParent](); + } + if (!global) { + return null; + } + generator = this.data[_symbol_utils.$getRealChildrenByNameIt](name, true, false); + match = generator.next().value; + if (match) { + return match; + } + generator = this.data[_symbol_utils.$getAttributeIt](name, true); + match = generator.next().value; + if (match?.[_symbol_utils.$isDataValue]()) { + return match; + } + return null; + } + _setProperties(formNode, dataNode) { + if (!formNode.hasOwnProperty("setProperty")) { + return; + } + for (const { + ref, + target, + connection + } of formNode.setProperty.children) { + if (connection) { + continue; + } + if (!ref) { + continue; + } + const nodes = (0, _som.searchNode)(this.root, dataNode, ref, false, false); + if (!nodes) { + (0, _util.warn)(`XFA - Invalid reference: ${ref}.`); + continue; + } + const [node] = nodes; + if (!node[_symbol_utils.$isDescendent](this.data)) { + (0, _util.warn)(`XFA - Invalid node: must be a data node.`); + continue; + } + const targetNodes = (0, _som.searchNode)(this.root, formNode, target, false, false); + if (!targetNodes) { + (0, _util.warn)(`XFA - Invalid target: ${target}.`); + continue; + } + const [targetNode] = targetNodes; + if (!targetNode[_symbol_utils.$isDescendent](formNode)) { + (0, _util.warn)(`XFA - Invalid target: must be a property or subproperty.`); + continue; + } + const targetParent = targetNode[_symbol_utils.$getParent](); + if (targetNode instanceof _template.SetProperty || targetParent instanceof _template.SetProperty) { + (0, _util.warn)(`XFA - Invalid target: cannot be a setProperty or one of its properties.`); + continue; + } + if (targetNode instanceof _template.BindItems || targetParent instanceof _template.BindItems) { + (0, _util.warn)(`XFA - Invalid target: cannot be a bindItems or one of its properties.`); + continue; + } + const content = node[_symbol_utils.$text](); + const name = targetNode[_symbol_utils.$nodeName]; + if (targetNode instanceof _xfa_object.XFAAttribute) { + const attrs = Object.create(null); + attrs[name] = content; + const obj = Reflect.construct(Object.getPrototypeOf(targetParent).constructor, [attrs]); + targetParent[name] = obj[name]; + continue; + } + if (!targetNode.hasOwnProperty(_symbol_utils.$content)) { + (0, _util.warn)(`XFA - Invalid node to use in setProperty`); + continue; + } + targetNode[_symbol_utils.$data] = node; + targetNode[_symbol_utils.$content] = content; + targetNode[_symbol_utils.$finalize](); + } + } + _bindItems(formNode, dataNode) { + if (!formNode.hasOwnProperty("items") || !formNode.hasOwnProperty("bindItems") || formNode.bindItems.isEmpty()) { + return; + } + for (const item of formNode.items.children) { + formNode[_symbol_utils.$removeChild](item); + } + formNode.items.clear(); + const labels = new _template.Items({}); + const values = new _template.Items({}); + formNode[_symbol_utils.$appendChild](labels); + formNode.items.push(labels); + formNode[_symbol_utils.$appendChild](values); + formNode.items.push(values); + for (const { + ref, + labelRef, + valueRef, + connection + } of formNode.bindItems.children) { + if (connection) { + continue; + } + if (!ref) { + continue; + } + const nodes = (0, _som.searchNode)(this.root, dataNode, ref, false, false); + if (!nodes) { + (0, _util.warn)(`XFA - Invalid reference: ${ref}.`); + continue; + } + for (const node of nodes) { + if (!node[_symbol_utils.$isDescendent](this.datasets)) { + (0, _util.warn)(`XFA - Invalid ref (${ref}): must be a datasets child.`); + continue; + } + const labelNodes = (0, _som.searchNode)(this.root, node, labelRef, true, false); + if (!labelNodes) { + (0, _util.warn)(`XFA - Invalid label: ${labelRef}.`); + continue; + } + const [labelNode] = labelNodes; + if (!labelNode[_symbol_utils.$isDescendent](this.datasets)) { + (0, _util.warn)(`XFA - Invalid label: must be a datasets child.`); + continue; + } + const valueNodes = (0, _som.searchNode)(this.root, node, valueRef, true, false); + if (!valueNodes) { + (0, _util.warn)(`XFA - Invalid value: ${valueRef}.`); + continue; + } + const [valueNode] = valueNodes; + if (!valueNode[_symbol_utils.$isDescendent](this.datasets)) { + (0, _util.warn)(`XFA - Invalid value: must be a datasets child.`); + continue; + } + const label = createText(labelNode[_symbol_utils.$text]()); + const value = createText(valueNode[_symbol_utils.$text]()); + labels[_symbol_utils.$appendChild](label); + labels.text.push(label); + values[_symbol_utils.$appendChild](value); + values.text.push(value); + } + } + } + _bindOccurrences(formNode, matches, picture) { + let baseClone; + if (matches.length > 1) { + baseClone = formNode[_symbol_utils.$clone](); + baseClone[_symbol_utils.$removeChild](baseClone.occur); + baseClone.occur = null; + } + this._bindValue(formNode, matches[0], picture); + this._setProperties(formNode, matches[0]); + this._bindItems(formNode, matches[0]); + if (matches.length === 1) { + return; + } + const parent = formNode[_symbol_utils.$getParent](); + const name = formNode[_symbol_utils.$nodeName]; + const pos = parent[_symbol_utils.$indexOf](formNode); + for (let i = 1, ii = matches.length; i < ii; i++) { + const match = matches[i]; + const clone = baseClone[_symbol_utils.$clone](); + parent[name].push(clone); + parent[_symbol_utils.$insertAt](pos + i, clone); + this._bindValue(clone, match, picture); + this._setProperties(clone, match); + this._bindItems(clone, match); + } + } + _createOccurrences(formNode) { + if (!this.emptyMerge) { + return; + } + const { + occur + } = formNode; + if (!occur || occur.initial <= 1) { + return; + } + const parent = formNode[_symbol_utils.$getParent](); + const name = formNode[_symbol_utils.$nodeName]; + if (!(parent[name] instanceof _xfa_object.XFAObjectArray)) { + return; + } + let currentNumber; + if (formNode.name) { + currentNumber = parent[name].children.filter(e => e.name === formNode.name).length; + } else { + currentNumber = parent[name].children.length; + } + const pos = parent[_symbol_utils.$indexOf](formNode) + 1; + const ii = occur.initial - currentNumber; + if (ii) { + const nodeClone = formNode[_symbol_utils.$clone](); + nodeClone[_symbol_utils.$removeChild](nodeClone.occur); + nodeClone.occur = null; + parent[name].push(nodeClone); + parent[_symbol_utils.$insertAt](pos, nodeClone); + for (let i = 1; i < ii; i++) { + const clone = nodeClone[_symbol_utils.$clone](); + parent[name].push(clone); + parent[_symbol_utils.$insertAt](pos + i, clone); + } + } + } + _getOccurInfo(formNode) { + const { + name, + occur + } = formNode; + if (!occur || !name) { + return [1, 1]; + } + const max = occur.max === -1 ? Infinity : occur.max; + return [occur.min, max]; + } + _setAndBind(formNode, dataNode) { + this._setProperties(formNode, dataNode); + this._bindItems(formNode, dataNode); + this._bindElement(formNode, dataNode); + } + _bindElement(formNode, dataNode) { + const uselessNodes = []; + this._createOccurrences(formNode); + for (const child of formNode[_symbol_utils.$getChildren]()) { + if (child[_symbol_utils.$data]) { + continue; + } + if (this._mergeMode === undefined && child[_symbol_utils.$nodeName] === "subform") { + this._mergeMode = child.mergeMode === "consumeData"; + const dataChildren = dataNode[_symbol_utils.$getChildren](); + if (dataChildren.length > 0) { + this._bindOccurrences(child, [dataChildren[0]], null); + } else if (this.emptyMerge) { + const nsId = dataNode[_symbol_utils.$namespaceId] === NS_DATASETS ? -1 : dataNode[_symbol_utils.$namespaceId]; + const dataChild = child[_symbol_utils.$data] = new _xfa_object.XmlObject(nsId, child.name || "root"); + dataNode[_symbol_utils.$appendChild](dataChild); + this._bindElement(child, dataChild); + } + continue; + } + if (!child[_symbol_utils.$isBindable]()) { + continue; + } + let global = false; + let picture = null; + let ref = null; + let match = null; + if (child.bind) { + switch (child.bind.match) { + case "none": + this._setAndBind(child, dataNode); + continue; + case "global": + global = true; + break; + case "dataRef": + if (!child.bind.ref) { + (0, _util.warn)(`XFA - ref is empty in node ${child[_symbol_utils.$nodeName]}.`); + this._setAndBind(child, dataNode); + continue; + } + ref = child.bind.ref; + break; + default: + break; + } + if (child.bind.picture) { + picture = child.bind.picture[_symbol_utils.$content]; + } + } + const [min, max] = this._getOccurInfo(child); + if (ref) { + match = (0, _som.searchNode)(this.root, dataNode, ref, true, false); + if (match === null) { + match = (0, _som.createDataNode)(this.data, dataNode, ref); + if (!match) { + continue; + } + if (this._isConsumeData()) { + match[_symbol_utils.$consumed] = true; + } + this._setAndBind(child, match); + continue; + } else { + if (this._isConsumeData()) { + match = match.filter(node => !node[_symbol_utils.$consumed]); + } + if (match.length > max) { + match = match.slice(0, max); + } else if (match.length === 0) { + match = null; + } + if (match && this._isConsumeData()) { + match.forEach(node => { + node[_symbol_utils.$consumed] = true; + }); + } + } + } else { + if (!child.name) { + this._setAndBind(child, dataNode); + continue; + } + if (this._isConsumeData()) { + const matches = []; + while (matches.length < max) { + const found = this._findDataByNameToConsume(child.name, child[_symbol_utils.$hasSettableValue](), dataNode, global); + if (!found) { + break; + } + found[_symbol_utils.$consumed] = true; + matches.push(found); + } + match = matches.length > 0 ? matches : null; + } else { + match = dataNode[_symbol_utils.$getRealChildrenByNameIt](child.name, false, this.emptyMerge).next().value; + if (!match) { + if (min === 0) { + uselessNodes.push(child); + continue; + } + const nsId = dataNode[_symbol_utils.$namespaceId] === NS_DATASETS ? -1 : dataNode[_symbol_utils.$namespaceId]; + match = child[_symbol_utils.$data] = new _xfa_object.XmlObject(nsId, child.name); + if (this.emptyMerge) { + match[_symbol_utils.$consumed] = true; + } + dataNode[_symbol_utils.$appendChild](match); + this._setAndBind(child, match); + continue; + } + if (this.emptyMerge) { + match[_symbol_utils.$consumed] = true; + } + match = [match]; + } + } + if (match) { + this._bindOccurrences(child, match, picture); + } else if (min > 0) { + this._setAndBind(child, dataNode); + } else { + uselessNodes.push(child); + } + } + uselessNodes.forEach(node => node[_symbol_utils.$getParent]()[_symbol_utils.$removeChild](node)); + } +} +exports.Binder = Binder; + +/***/ }), +/* 80 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Value = exports.Text = exports.TemplateNamespace = exports.Template = exports.SetProperty = exports.Items = exports.Field = exports.BindItems = void 0; +var _symbol_utils = __w_pdfjs_require__(78); +var _namespaces = __w_pdfjs_require__(81); +var _layout = __w_pdfjs_require__(82); +var _html_utils = __w_pdfjs_require__(83); +var _xfa_object = __w_pdfjs_require__(87); +var _utils = __w_pdfjs_require__(84); +var _util = __w_pdfjs_require__(2); +var _fonts = __w_pdfjs_require__(85); +var _core_utils = __w_pdfjs_require__(3); +var _som = __w_pdfjs_require__(88); +const TEMPLATE_NS_ID = _namespaces.NamespaceIds.template.id; +const SVG_NS = "http://www.w3.org/2000/svg"; +const MAX_ATTEMPTS_FOR_LRTB_LAYOUT = 2; +const MAX_EMPTY_PAGES = 3; +const DEFAULT_TAB_INDEX = 5000; +const HEADING_PATTERN = /^H(\d+)$/; +const MIMES = new Set(["image/gif", "image/jpeg", "image/jpg", "image/pjpeg", "image/png", "image/apng", "image/x-png", "image/bmp", "image/x-ms-bmp", "image/tiff", "image/tif", "application/octet-stream"]); +const IMAGES_HEADERS = [[[0x42, 0x4d], "image/bmp"], [[0xff, 0xd8, 0xff], "image/jpeg"], [[0x49, 0x49, 0x2a, 0x00], "image/tiff"], [[0x4d, 0x4d, 0x00, 0x2a], "image/tiff"], [[0x47, 0x49, 0x46, 0x38, 0x39, 0x61], "image/gif"], [[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], "image/png"]]; +function getBorderDims(node) { + if (!node || !node.border) { + return { + w: 0, + h: 0 + }; + } + const borderExtra = node.border[_symbol_utils.$getExtra](); + if (!borderExtra) { + return { + w: 0, + h: 0 + }; + } + return { + w: borderExtra.widths[0] + borderExtra.widths[2] + borderExtra.insets[0] + borderExtra.insets[2], + h: borderExtra.widths[1] + borderExtra.widths[3] + borderExtra.insets[1] + borderExtra.insets[3] + }; +} +function hasMargin(node) { + return node.margin && (node.margin.topInset || node.margin.rightInset || node.margin.bottomInset || node.margin.leftInset); +} +function _setValue(templateNode, value) { + if (!templateNode.value) { + const nodeValue = new Value({}); + templateNode[_symbol_utils.$appendChild](nodeValue); + templateNode.value = nodeValue; + } + templateNode.value[_symbol_utils.$setValue](value); +} +function* getContainedChildren(node) { + for (const child of node[_symbol_utils.$getChildren]()) { + if (child instanceof SubformSet) { + yield* child[_symbol_utils.$getContainedChildren](); + continue; + } + yield child; + } +} +function isRequired(node) { + return node.validate?.nullTest === "error"; +} +function setTabIndex(node) { + while (node) { + if (!node.traversal) { + node[_symbol_utils.$tabIndex] = node[_symbol_utils.$getParent]()[_symbol_utils.$tabIndex]; + return; + } + if (node[_symbol_utils.$tabIndex]) { + return; + } + let next = null; + for (const child of node.traversal[_symbol_utils.$getChildren]()) { + if (child.operation === "next") { + next = child; + break; + } + } + if (!next || !next.ref) { + node[_symbol_utils.$tabIndex] = node[_symbol_utils.$getParent]()[_symbol_utils.$tabIndex]; + return; + } + const root = node[_symbol_utils.$getTemplateRoot](); + node[_symbol_utils.$tabIndex] = ++root[_symbol_utils.$tabIndex]; + const ref = root[_symbol_utils.$searchNode](next.ref, node); + if (!ref) { + return; + } + node = ref[0]; + } +} +function applyAssist(obj, attributes) { + const assist = obj.assist; + if (assist) { + const assistTitle = assist[_symbol_utils.$toHTML](); + if (assistTitle) { + attributes.title = assistTitle; + } + const role = assist.role; + const match = role.match(HEADING_PATTERN); + if (match) { + const ariaRole = "heading"; + const ariaLevel = match[1]; + attributes.role = ariaRole; + attributes["aria-level"] = ariaLevel; + } + } + if (obj.layout === "table") { + attributes.role = "table"; + } else if (obj.layout === "row") { + attributes.role = "row"; + } else { + const parent = obj[_symbol_utils.$getParent](); + if (parent.layout === "row") { + attributes.role = parent.assist?.role === "TH" ? "columnheader" : "cell"; + } + } +} +function ariaLabel(obj) { + if (!obj.assist) { + return null; + } + const assist = obj.assist; + if (assist.speak && assist.speak[_symbol_utils.$content] !== "") { + return assist.speak[_symbol_utils.$content]; + } + if (assist.toolTip) { + return assist.toolTip[_symbol_utils.$content]; + } + return null; +} +function valueToHtml(value) { + return _utils.HTMLResult.success({ + name: "div", + attributes: { + class: ["xfaRich"], + style: Object.create(null) + }, + children: [{ + name: "span", + attributes: { + style: Object.create(null) + }, + value + }] + }); +} +function setFirstUnsplittable(node) { + const root = node[_symbol_utils.$getTemplateRoot](); + if (root[_symbol_utils.$extra].firstUnsplittable === null) { + root[_symbol_utils.$extra].firstUnsplittable = node; + root[_symbol_utils.$extra].noLayoutFailure = true; + } +} +function unsetFirstUnsplittable(node) { + const root = node[_symbol_utils.$getTemplateRoot](); + if (root[_symbol_utils.$extra].firstUnsplittable === node) { + root[_symbol_utils.$extra].noLayoutFailure = false; + } +} +function handleBreak(node) { + if (node[_symbol_utils.$extra]) { + return false; + } + node[_symbol_utils.$extra] = Object.create(null); + if (node.targetType === "auto") { + return false; + } + const root = node[_symbol_utils.$getTemplateRoot](); + let target = null; + if (node.target) { + target = root[_symbol_utils.$searchNode](node.target, node[_symbol_utils.$getParent]()); + if (!target) { + return false; + } + target = target[0]; + } + const { + currentPageArea, + currentContentArea + } = root[_symbol_utils.$extra]; + if (node.targetType === "pageArea") { + if (!(target instanceof PageArea)) { + target = null; + } + if (node.startNew) { + node[_symbol_utils.$extra].target = target || currentPageArea; + return true; + } else if (target && target !== currentPageArea) { + node[_symbol_utils.$extra].target = target; + return true; + } + return false; + } + if (!(target instanceof ContentArea)) { + target = null; + } + const pageArea = target && target[_symbol_utils.$getParent](); + let index; + let nextPageArea = pageArea; + if (node.startNew) { + if (target) { + const contentAreas = pageArea.contentArea.children; + const indexForCurrent = contentAreas.indexOf(currentContentArea); + const indexForTarget = contentAreas.indexOf(target); + if (indexForCurrent !== -1 && indexForCurrent < indexForTarget) { + nextPageArea = null; + } + index = indexForTarget - 1; + } else { + index = currentPageArea.contentArea.children.indexOf(currentContentArea); + } + } else if (target && target !== currentContentArea) { + const contentAreas = pageArea.contentArea.children; + index = contentAreas.indexOf(target) - 1; + nextPageArea = pageArea === currentPageArea ? null : pageArea; + } else { + return false; + } + node[_symbol_utils.$extra].target = nextPageArea; + node[_symbol_utils.$extra].index = index; + return true; +} +function handleOverflow(node, extraNode, space) { + const root = node[_symbol_utils.$getTemplateRoot](); + const saved = root[_symbol_utils.$extra].noLayoutFailure; + const savedMethod = extraNode[_symbol_utils.$getSubformParent]; + extraNode[_symbol_utils.$getSubformParent] = () => node; + root[_symbol_utils.$extra].noLayoutFailure = true; + const res = extraNode[_symbol_utils.$toHTML](space); + node[_symbol_utils.$addHTML](res.html, res.bbox); + root[_symbol_utils.$extra].noLayoutFailure = saved; + extraNode[_symbol_utils.$getSubformParent] = savedMethod; +} +class AppearanceFilter extends _xfa_object.StringObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "appearanceFilter"); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Arc extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "arc", true); + this.circular = (0, _utils.getInteger)({ + data: attributes.circular, + defaultValue: 0, + validate: x => x === 1 + }); + this.hand = (0, _utils.getStringOption)(attributes.hand, ["even", "left", "right"]); + this.id = attributes.id || ""; + this.startAngle = (0, _utils.getFloat)({ + data: attributes.startAngle, + defaultValue: 0, + validate: x => true + }); + this.sweepAngle = (0, _utils.getFloat)({ + data: attributes.sweepAngle, + defaultValue: 360, + validate: x => true + }); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.edge = null; + this.fill = null; + } + [_symbol_utils.$toHTML]() { + const edge = this.edge || new Edge({}); + const edgeStyle = edge[_symbol_utils.$toStyle](); + const style = Object.create(null); + if (this.fill?.presence === "visible") { + Object.assign(style, this.fill[_symbol_utils.$toStyle]()); + } else { + style.fill = "transparent"; + } + style.strokeWidth = (0, _html_utils.measureToString)(edge.presence === "visible" ? edge.thickness : 0); + style.stroke = edgeStyle.color; + let arc; + const attributes = { + xmlns: SVG_NS, + style: { + width: "100%", + height: "100%", + overflow: "visible" + } + }; + if (this.sweepAngle === 360) { + arc = { + name: "ellipse", + attributes: { + xmlns: SVG_NS, + cx: "50%", + cy: "50%", + rx: "50%", + ry: "50%", + style + } + }; + } else { + const startAngle = this.startAngle * Math.PI / 180; + const sweepAngle = this.sweepAngle * Math.PI / 180; + const largeArc = this.sweepAngle > 180 ? 1 : 0; + const [x1, y1, x2, y2] = [50 * (1 + Math.cos(startAngle)), 50 * (1 - Math.sin(startAngle)), 50 * (1 + Math.cos(startAngle + sweepAngle)), 50 * (1 - Math.sin(startAngle + sweepAngle))]; + arc = { + name: "path", + attributes: { + xmlns: SVG_NS, + d: `M ${x1} ${y1} A 50 50 0 ${largeArc} 0 ${x2} ${y2}`, + vectorEffect: "non-scaling-stroke", + style + } + }; + Object.assign(attributes, { + viewBox: "0 0 100 100", + preserveAspectRatio: "none" + }); + } + const svg = { + name: "svg", + children: [arc], + attributes + }; + const parent = this[_symbol_utils.$getParent]()[_symbol_utils.$getParent](); + if (hasMargin(parent)) { + return _utils.HTMLResult.success({ + name: "div", + attributes: { + style: { + display: "inline", + width: "100%", + height: "100%" + } + }, + children: [svg] + }); + } + svg.attributes.style.position = "absolute"; + return _utils.HTMLResult.success(svg); + } +} +class Area extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "area", true); + this.colSpan = (0, _utils.getInteger)({ + data: attributes.colSpan, + defaultValue: 1, + validate: n => n >= 1 || n === -1 + }); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.relevant = (0, _utils.getRelevant)(attributes.relevant); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.x = (0, _utils.getMeasurement)(attributes.x, "0pt"); + this.y = (0, _utils.getMeasurement)(attributes.y, "0pt"); + this.desc = null; + this.extras = null; + this.area = new _xfa_object.XFAObjectArray(); + this.draw = new _xfa_object.XFAObjectArray(); + this.exObject = new _xfa_object.XFAObjectArray(); + this.exclGroup = new _xfa_object.XFAObjectArray(); + this.field = new _xfa_object.XFAObjectArray(); + this.subform = new _xfa_object.XFAObjectArray(); + this.subformSet = new _xfa_object.XFAObjectArray(); + } + *[_symbol_utils.$getContainedChildren]() { + yield* getContainedChildren(this); + } + [_symbol_utils.$isTransparent]() { + return true; + } + [_symbol_utils.$isBindable]() { + return true; + } + [_symbol_utils.$addHTML](html, bbox) { + const [x, y, w, h] = bbox; + this[_symbol_utils.$extra].width = Math.max(this[_symbol_utils.$extra].width, x + w); + this[_symbol_utils.$extra].height = Math.max(this[_symbol_utils.$extra].height, y + h); + this[_symbol_utils.$extra].children.push(html); + } + [_symbol_utils.$getAvailableSpace]() { + return this[_symbol_utils.$extra].availableSpace; + } + [_symbol_utils.$toHTML](availableSpace) { + const style = (0, _html_utils.toStyle)(this, "position"); + const attributes = { + style, + id: this[_symbol_utils.$uid], + class: ["xfaArea"] + }; + if ((0, _html_utils.isPrintOnly)(this)) { + attributes.class.push("xfaPrintOnly"); + } + if (this.name) { + attributes.xfaName = this.name; + } + const children = []; + this[_symbol_utils.$extra] = { + children, + width: 0, + height: 0, + availableSpace + }; + const result = this[_symbol_utils.$childrenToHTML]({ + filter: new Set(["area", "draw", "field", "exclGroup", "subform", "subformSet"]), + include: true + }); + if (!result.success) { + if (result.isBreak()) { + return result; + } + delete this[_symbol_utils.$extra]; + return _utils.HTMLResult.FAILURE; + } + style.width = (0, _html_utils.measureToString)(this[_symbol_utils.$extra].width); + style.height = (0, _html_utils.measureToString)(this[_symbol_utils.$extra].height); + const html = { + name: "div", + attributes, + children + }; + const bbox = [this.x, this.y, this[_symbol_utils.$extra].width, this[_symbol_utils.$extra].height]; + delete this[_symbol_utils.$extra]; + return _utils.HTMLResult.success(html, bbox); + } +} +class Assist extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "assist", true); + this.id = attributes.id || ""; + this.role = attributes.role || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.speak = null; + this.toolTip = null; + } + [_symbol_utils.$toHTML]() { + return this.toolTip?.[_symbol_utils.$content] || null; + } +} +class Barcode extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "barcode", true); + this.charEncoding = (0, _utils.getKeyword)({ + data: attributes.charEncoding ? attributes.charEncoding.toLowerCase() : "", + defaultValue: "", + validate: k => ["utf-8", "big-five", "fontspecific", "gbk", "gb-18030", "gb-2312", "ksc-5601", "none", "shift-jis", "ucs-2", "utf-16"].includes(k) || k.match(/iso-8859-\d{2}/) + }); + this.checksum = (0, _utils.getStringOption)(attributes.checksum, ["none", "1mod10", "1mod10_1mod11", "2mod10", "auto"]); + this.dataColumnCount = (0, _utils.getInteger)({ + data: attributes.dataColumnCount, + defaultValue: -1, + validate: x => x >= 0 + }); + this.dataLength = (0, _utils.getInteger)({ + data: attributes.dataLength, + defaultValue: -1, + validate: x => x >= 0 + }); + this.dataPrep = (0, _utils.getStringOption)(attributes.dataPrep, ["none", "flateCompress"]); + this.dataRowCount = (0, _utils.getInteger)({ + data: attributes.dataRowCount, + defaultValue: -1, + validate: x => x >= 0 + }); + this.endChar = attributes.endChar || ""; + this.errorCorrectionLevel = (0, _utils.getInteger)({ + data: attributes.errorCorrectionLevel, + defaultValue: -1, + validate: x => x >= 0 && x <= 8 + }); + this.id = attributes.id || ""; + this.moduleHeight = (0, _utils.getMeasurement)(attributes.moduleHeight, "5mm"); + this.moduleWidth = (0, _utils.getMeasurement)(attributes.moduleWidth, "0.25mm"); + this.printCheckDigit = (0, _utils.getInteger)({ + data: attributes.printCheckDigit, + defaultValue: 0, + validate: x => x === 1 + }); + this.rowColumnRatio = (0, _utils.getRatio)(attributes.rowColumnRatio); + this.startChar = attributes.startChar || ""; + this.textLocation = (0, _utils.getStringOption)(attributes.textLocation, ["below", "above", "aboveEmbedded", "belowEmbedded", "none"]); + this.truncate = (0, _utils.getInteger)({ + data: attributes.truncate, + defaultValue: 0, + validate: x => x === 1 + }); + this.type = (0, _utils.getStringOption)(attributes.type ? attributes.type.toLowerCase() : "", ["aztec", "codabar", "code2of5industrial", "code2of5interleaved", "code2of5matrix", "code2of5standard", "code3of9", "code3of9extended", "code11", "code49", "code93", "code128", "code128a", "code128b", "code128c", "code128sscc", "datamatrix", "ean8", "ean8add2", "ean8add5", "ean13", "ean13add2", "ean13add5", "ean13pwcd", "fim", "logmars", "maxicode", "msi", "pdf417", "pdf417macro", "plessey", "postauscust2", "postauscust3", "postausreplypaid", "postausstandard", "postukrm4scc", "postusdpbc", "postusimb", "postusstandard", "postus5zip", "qrcode", "rfid", "rss14", "rss14expanded", "rss14limited", "rss14stacked", "rss14stackedomni", "rss14truncated", "telepen", "ucc128", "ucc128random", "ucc128sscc", "upca", "upcaadd2", "upcaadd5", "upcapwcd", "upce", "upceadd2", "upceadd5", "upcean2", "upcean5", "upsmaxicode"]); + this.upsMode = (0, _utils.getStringOption)(attributes.upsMode, ["usCarrier", "internationalCarrier", "secureSymbol", "standardSymbol"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.wideNarrowRatio = (0, _utils.getRatio)(attributes.wideNarrowRatio); + this.encrypt = null; + this.extras = null; + } +} +class Bind extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "bind", true); + this.match = (0, _utils.getStringOption)(attributes.match, ["once", "dataRef", "global", "none"]); + this.ref = attributes.ref || ""; + this.picture = null; + } +} +class BindItems extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "bindItems"); + this.connection = attributes.connection || ""; + this.labelRef = attributes.labelRef || ""; + this.ref = attributes.ref || ""; + this.valueRef = attributes.valueRef || ""; + } +} +exports.BindItems = BindItems; +class Bookend extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "bookend"); + this.id = attributes.id || ""; + this.leader = attributes.leader || ""; + this.trailer = attributes.trailer || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class BooleanElement extends _xfa_object.Option01 { + constructor(attributes) { + super(TEMPLATE_NS_ID, "boolean"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } + [_symbol_utils.$toHTML](availableSpace) { + return valueToHtml(this[_symbol_utils.$content] === 1 ? "1" : "0"); + } +} +class Border extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "border", true); + this.break = (0, _utils.getStringOption)(attributes.break, ["close", "open"]); + this.hand = (0, _utils.getStringOption)(attributes.hand, ["even", "left", "right"]); + this.id = attributes.id || ""; + this.presence = (0, _utils.getStringOption)(attributes.presence, ["visible", "hidden", "inactive", "invisible"]); + this.relevant = (0, _utils.getRelevant)(attributes.relevant); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.corner = new _xfa_object.XFAObjectArray(4); + this.edge = new _xfa_object.XFAObjectArray(4); + this.extras = null; + this.fill = null; + this.margin = null; + } + [_symbol_utils.$getExtra]() { + if (!this[_symbol_utils.$extra]) { + const edges = this.edge.children.slice(); + if (edges.length < 4) { + const defaultEdge = edges.at(-1) || new Edge({}); + for (let i = edges.length; i < 4; i++) { + edges.push(defaultEdge); + } + } + const widths = edges.map(edge => edge.thickness); + const insets = [0, 0, 0, 0]; + if (this.margin) { + insets[0] = this.margin.topInset; + insets[1] = this.margin.rightInset; + insets[2] = this.margin.bottomInset; + insets[3] = this.margin.leftInset; + } + this[_symbol_utils.$extra] = { + widths, + insets, + edges + }; + } + return this[_symbol_utils.$extra]; + } + [_symbol_utils.$toStyle]() { + const { + edges + } = this[_symbol_utils.$getExtra](); + const edgeStyles = edges.map(node => { + const style = node[_symbol_utils.$toStyle](); + style.color ||= "#000000"; + return style; + }); + const style = Object.create(null); + if (this.margin) { + Object.assign(style, this.margin[_symbol_utils.$toStyle]()); + } + if (this.fill?.presence === "visible") { + Object.assign(style, this.fill[_symbol_utils.$toStyle]()); + } + if (this.corner.children.some(node => node.radius !== 0)) { + const cornerStyles = this.corner.children.map(node => node[_symbol_utils.$toStyle]()); + if (cornerStyles.length === 2 || cornerStyles.length === 3) { + const last = cornerStyles.at(-1); + for (let i = cornerStyles.length; i < 4; i++) { + cornerStyles.push(last); + } + } + style.borderRadius = cornerStyles.map(s => s.radius).join(" "); + } + switch (this.presence) { + case "invisible": + case "hidden": + style.borderStyle = ""; + break; + case "inactive": + style.borderStyle = "none"; + break; + default: + style.borderStyle = edgeStyles.map(s => s.style).join(" "); + break; + } + style.borderWidth = edgeStyles.map(s => s.width).join(" "); + style.borderColor = edgeStyles.map(s => s.color).join(" "); + return style; + } +} +class Break extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "break", true); + this.after = (0, _utils.getStringOption)(attributes.after, ["auto", "contentArea", "pageArea", "pageEven", "pageOdd"]); + this.afterTarget = attributes.afterTarget || ""; + this.before = (0, _utils.getStringOption)(attributes.before, ["auto", "contentArea", "pageArea", "pageEven", "pageOdd"]); + this.beforeTarget = attributes.beforeTarget || ""; + this.bookendLeader = attributes.bookendLeader || ""; + this.bookendTrailer = attributes.bookendTrailer || ""; + this.id = attributes.id || ""; + this.overflowLeader = attributes.overflowLeader || ""; + this.overflowTarget = attributes.overflowTarget || ""; + this.overflowTrailer = attributes.overflowTrailer || ""; + this.startNew = (0, _utils.getInteger)({ + data: attributes.startNew, + defaultValue: 0, + validate: x => x === 1 + }); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + } +} +class BreakAfter extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "breakAfter", true); + this.id = attributes.id || ""; + this.leader = attributes.leader || ""; + this.startNew = (0, _utils.getInteger)({ + data: attributes.startNew, + defaultValue: 0, + validate: x => x === 1 + }); + this.target = attributes.target || ""; + this.targetType = (0, _utils.getStringOption)(attributes.targetType, ["auto", "contentArea", "pageArea"]); + this.trailer = attributes.trailer || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.script = null; + } +} +class BreakBefore extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "breakBefore", true); + this.id = attributes.id || ""; + this.leader = attributes.leader || ""; + this.startNew = (0, _utils.getInteger)({ + data: attributes.startNew, + defaultValue: 0, + validate: x => x === 1 + }); + this.target = attributes.target || ""; + this.targetType = (0, _utils.getStringOption)(attributes.targetType, ["auto", "contentArea", "pageArea"]); + this.trailer = attributes.trailer || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.script = null; + } + [_symbol_utils.$toHTML](availableSpace) { + this[_symbol_utils.$extra] = {}; + return _utils.HTMLResult.FAILURE; + } +} +class Button extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "button", true); + this.highlight = (0, _utils.getStringOption)(attributes.highlight, ["inverted", "none", "outline", "push"]); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + } + [_symbol_utils.$toHTML](availableSpace) { + const parent = this[_symbol_utils.$getParent](); + const grandpa = parent[_symbol_utils.$getParent](); + const htmlButton = { + name: "button", + attributes: { + id: this[_symbol_utils.$uid], + class: ["xfaButton"], + style: {} + }, + children: [] + }; + for (const event of grandpa.event.children) { + if (event.activity !== "click" || !event.script) { + continue; + } + const jsURL = (0, _core_utils.recoverJsURL)(event.script[_symbol_utils.$content]); + if (!jsURL) { + continue; + } + const href = (0, _html_utils.fixURL)(jsURL.url); + if (!href) { + continue; + } + htmlButton.children.push({ + name: "a", + attributes: { + id: "link" + this[_symbol_utils.$uid], + href, + newWindow: jsURL.newWindow, + class: ["xfaLink"], + style: {} + }, + children: [] + }); + } + return _utils.HTMLResult.success(htmlButton); + } +} +class Calculate extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "calculate", true); + this.id = attributes.id || ""; + this.override = (0, _utils.getStringOption)(attributes.override, ["disabled", "error", "ignore", "warning"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + this.message = null; + this.script = null; + } +} +class Caption extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "caption", true); + this.id = attributes.id || ""; + this.placement = (0, _utils.getStringOption)(attributes.placement, ["left", "bottom", "inline", "right", "top"]); + this.presence = (0, _utils.getStringOption)(attributes.presence, ["visible", "hidden", "inactive", "invisible"]); + this.reserve = Math.ceil((0, _utils.getMeasurement)(attributes.reserve)); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + this.font = null; + this.margin = null; + this.para = null; + this.value = null; + } + [_symbol_utils.$setValue](value) { + _setValue(this, value); + } + [_symbol_utils.$getExtra](availableSpace) { + if (!this[_symbol_utils.$extra]) { + let { + width, + height + } = availableSpace; + switch (this.placement) { + case "left": + case "right": + case "inline": + width = this.reserve <= 0 ? width : this.reserve; + break; + case "top": + case "bottom": + height = this.reserve <= 0 ? height : this.reserve; + break; + } + this[_symbol_utils.$extra] = (0, _html_utils.layoutNode)(this, { + width, + height + }); + } + return this[_symbol_utils.$extra]; + } + [_symbol_utils.$toHTML](availableSpace) { + if (!this.value) { + return _utils.HTMLResult.EMPTY; + } + this[_symbol_utils.$pushPara](); + const value = this.value[_symbol_utils.$toHTML](availableSpace).html; + if (!value) { + this[_symbol_utils.$popPara](); + return _utils.HTMLResult.EMPTY; + } + const savedReserve = this.reserve; + if (this.reserve <= 0) { + const { + w, + h + } = this[_symbol_utils.$getExtra](availableSpace); + switch (this.placement) { + case "left": + case "right": + case "inline": + this.reserve = w; + break; + case "top": + case "bottom": + this.reserve = h; + break; + } + } + const children = []; + if (typeof value === "string") { + children.push({ + name: "#text", + value + }); + } else { + children.push(value); + } + const style = (0, _html_utils.toStyle)(this, "font", "margin", "visibility"); + switch (this.placement) { + case "left": + case "right": + if (this.reserve > 0) { + style.width = (0, _html_utils.measureToString)(this.reserve); + } + break; + case "top": + case "bottom": + if (this.reserve > 0) { + style.height = (0, _html_utils.measureToString)(this.reserve); + } + break; + } + (0, _html_utils.setPara)(this, null, value); + this[_symbol_utils.$popPara](); + this.reserve = savedReserve; + return _utils.HTMLResult.success({ + name: "div", + attributes: { + style, + class: ["xfaCaption"] + }, + children + }); + } +} +class Certificate extends _xfa_object.StringObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "certificate"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Certificates extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "certificates", true); + this.credentialServerPolicy = (0, _utils.getStringOption)(attributes.credentialServerPolicy, ["optional", "required"]); + this.id = attributes.id || ""; + this.url = attributes.url || ""; + this.urlPolicy = attributes.urlPolicy || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.encryption = null; + this.issuers = null; + this.keyUsage = null; + this.oids = null; + this.signing = null; + this.subjectDNs = null; + } +} +class CheckButton extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "checkButton", true); + this.id = attributes.id || ""; + this.mark = (0, _utils.getStringOption)(attributes.mark, ["default", "check", "circle", "cross", "diamond", "square", "star"]); + this.shape = (0, _utils.getStringOption)(attributes.shape, ["square", "round"]); + this.size = (0, _utils.getMeasurement)(attributes.size, "10pt"); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.border = null; + this.extras = null; + this.margin = null; + } + [_symbol_utils.$toHTML](availableSpace) { + const style = (0, _html_utils.toStyle)("margin"); + const size = (0, _html_utils.measureToString)(this.size); + style.width = style.height = size; + let type; + let className; + let groupId; + const field = this[_symbol_utils.$getParent]()[_symbol_utils.$getParent](); + const items = field.items.children.length && field.items.children[0][_symbol_utils.$toHTML]().html || []; + const exportedValue = { + on: (items[0] !== undefined ? items[0] : "on").toString(), + off: (items[1] !== undefined ? items[1] : "off").toString() + }; + const value = field.value?.[_symbol_utils.$text]() || "off"; + const checked = value === exportedValue.on || undefined; + const container = field[_symbol_utils.$getSubformParent](); + const fieldId = field[_symbol_utils.$uid]; + let dataId; + if (container instanceof ExclGroup) { + groupId = container[_symbol_utils.$uid]; + type = "radio"; + className = "xfaRadio"; + dataId = container[_symbol_utils.$data]?.[_symbol_utils.$uid] || container[_symbol_utils.$uid]; + } else { + type = "checkbox"; + className = "xfaCheckbox"; + dataId = field[_symbol_utils.$data]?.[_symbol_utils.$uid] || field[_symbol_utils.$uid]; + } + const input = { + name: "input", + attributes: { + class: [className], + style, + fieldId, + dataId, + type, + checked, + xfaOn: exportedValue.on, + xfaOff: exportedValue.off, + "aria-label": ariaLabel(field), + "aria-required": false + } + }; + if (groupId) { + input.attributes.name = groupId; + } + if (isRequired(field)) { + input.attributes["aria-required"] = true; + input.attributes.required = true; + } + return _utils.HTMLResult.success({ + name: "label", + attributes: { + class: ["xfaLabel"] + }, + children: [input] + }); + } +} +class ChoiceList extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "choiceList", true); + this.commitOn = (0, _utils.getStringOption)(attributes.commitOn, ["select", "exit"]); + this.id = attributes.id || ""; + this.open = (0, _utils.getStringOption)(attributes.open, ["userControl", "always", "multiSelect", "onEntry"]); + this.textEntry = (0, _utils.getInteger)({ + data: attributes.textEntry, + defaultValue: 0, + validate: x => x === 1 + }); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.border = null; + this.extras = null; + this.margin = null; + } + [_symbol_utils.$toHTML](availableSpace) { + const style = (0, _html_utils.toStyle)(this, "border", "margin"); + const ui = this[_symbol_utils.$getParent](); + const field = ui[_symbol_utils.$getParent](); + const fontSize = field.font?.size || 10; + const optionStyle = { + fontSize: `calc(${fontSize}px * var(--scale-factor))` + }; + const children = []; + if (field.items.children.length > 0) { + const items = field.items; + let displayedIndex = 0; + let saveIndex = 0; + if (items.children.length === 2) { + displayedIndex = items.children[0].save; + saveIndex = 1 - displayedIndex; + } + const displayed = items.children[displayedIndex][_symbol_utils.$toHTML]().html; + const values = items.children[saveIndex][_symbol_utils.$toHTML]().html; + let selected = false; + const value = field.value?.[_symbol_utils.$text]() || ""; + for (let i = 0, ii = displayed.length; i < ii; i++) { + const option = { + name: "option", + attributes: { + value: values[i] || displayed[i], + style: optionStyle + }, + value: displayed[i] + }; + if (values[i] === value) { + option.attributes.selected = selected = true; + } + children.push(option); + } + if (!selected) { + children.splice(0, 0, { + name: "option", + attributes: { + hidden: true, + selected: true + }, + value: " " + }); + } + } + const selectAttributes = { + class: ["xfaSelect"], + fieldId: field[_symbol_utils.$uid], + dataId: field[_symbol_utils.$data]?.[_symbol_utils.$uid] || field[_symbol_utils.$uid], + style, + "aria-label": ariaLabel(field), + "aria-required": false + }; + if (isRequired(field)) { + selectAttributes["aria-required"] = true; + selectAttributes.required = true; + } + if (this.open === "multiSelect") { + selectAttributes.multiple = true; + } + return _utils.HTMLResult.success({ + name: "label", + attributes: { + class: ["xfaLabel"] + }, + children: [{ + name: "select", + children, + attributes: selectAttributes + }] + }); + } +} +class Color extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "color", true); + this.cSpace = (0, _utils.getStringOption)(attributes.cSpace, ["SRGB"]); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.value = attributes.value ? (0, _utils.getColor)(attributes.value) : ""; + this.extras = null; + } + [_symbol_utils.$hasSettableValue]() { + return false; + } + [_symbol_utils.$toStyle]() { + return this.value ? _util.Util.makeHexColor(this.value.r, this.value.g, this.value.b) : null; + } +} +class Comb extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "comb"); + this.id = attributes.id || ""; + this.numberOfCells = (0, _utils.getInteger)({ + data: attributes.numberOfCells, + defaultValue: 0, + validate: x => x >= 0 + }); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Connect extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "connect", true); + this.connection = attributes.connection || ""; + this.id = attributes.id || ""; + this.ref = attributes.ref || ""; + this.usage = (0, _utils.getStringOption)(attributes.usage, ["exportAndImport", "exportOnly", "importOnly"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.picture = null; + } +} +class ContentArea extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "contentArea", true); + this.h = (0, _utils.getMeasurement)(attributes.h); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.relevant = (0, _utils.getRelevant)(attributes.relevant); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.w = (0, _utils.getMeasurement)(attributes.w); + this.x = (0, _utils.getMeasurement)(attributes.x, "0pt"); + this.y = (0, _utils.getMeasurement)(attributes.y, "0pt"); + this.desc = null; + this.extras = null; + } + [_symbol_utils.$toHTML](availableSpace) { + const left = (0, _html_utils.measureToString)(this.x); + const top = (0, _html_utils.measureToString)(this.y); + const style = { + left, + top, + width: (0, _html_utils.measureToString)(this.w), + height: (0, _html_utils.measureToString)(this.h) + }; + const classNames = ["xfaContentarea"]; + if ((0, _html_utils.isPrintOnly)(this)) { + classNames.push("xfaPrintOnly"); + } + return _utils.HTMLResult.success({ + name: "div", + children: [], + attributes: { + style, + class: classNames, + id: this[_symbol_utils.$uid] + } + }); + } +} +class Corner extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "corner", true); + this.id = attributes.id || ""; + this.inverted = (0, _utils.getInteger)({ + data: attributes.inverted, + defaultValue: 0, + validate: x => x === 1 + }); + this.join = (0, _utils.getStringOption)(attributes.join, ["square", "round"]); + this.presence = (0, _utils.getStringOption)(attributes.presence, ["visible", "hidden", "inactive", "invisible"]); + this.radius = (0, _utils.getMeasurement)(attributes.radius); + this.stroke = (0, _utils.getStringOption)(attributes.stroke, ["solid", "dashDot", "dashDotDot", "dashed", "dotted", "embossed", "etched", "lowered", "raised"]); + this.thickness = (0, _utils.getMeasurement)(attributes.thickness, "0.5pt"); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.color = null; + this.extras = null; + } + [_symbol_utils.$toStyle]() { + const style = (0, _html_utils.toStyle)(this, "visibility"); + style.radius = (0, _html_utils.measureToString)(this.join === "square" ? 0 : this.radius); + return style; + } +} +class DateElement extends _xfa_object.ContentObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "date"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } + [_symbol_utils.$finalize]() { + const date = this[_symbol_utils.$content].trim(); + this[_symbol_utils.$content] = date ? new Date(date) : null; + } + [_symbol_utils.$toHTML](availableSpace) { + return valueToHtml(this[_symbol_utils.$content] ? this[_symbol_utils.$content].toString() : ""); + } +} +class DateTime extends _xfa_object.ContentObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "dateTime"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } + [_symbol_utils.$finalize]() { + const date = this[_symbol_utils.$content].trim(); + this[_symbol_utils.$content] = date ? new Date(date) : null; + } + [_symbol_utils.$toHTML](availableSpace) { + return valueToHtml(this[_symbol_utils.$content] ? this[_symbol_utils.$content].toString() : ""); + } +} +class DateTimeEdit extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "dateTimeEdit", true); + this.hScrollPolicy = (0, _utils.getStringOption)(attributes.hScrollPolicy, ["auto", "off", "on"]); + this.id = attributes.id || ""; + this.picker = (0, _utils.getStringOption)(attributes.picker, ["host", "none"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.border = null; + this.comb = null; + this.extras = null; + this.margin = null; + } + [_symbol_utils.$toHTML](availableSpace) { + const style = (0, _html_utils.toStyle)(this, "border", "font", "margin"); + const field = this[_symbol_utils.$getParent]()[_symbol_utils.$getParent](); + const html = { + name: "input", + attributes: { + type: "text", + fieldId: field[_symbol_utils.$uid], + dataId: field[_symbol_utils.$data]?.[_symbol_utils.$uid] || field[_symbol_utils.$uid], + class: ["xfaTextfield"], + style, + "aria-label": ariaLabel(field), + "aria-required": false + } + }; + if (isRequired(field)) { + html.attributes["aria-required"] = true; + html.attributes.required = true; + } + return _utils.HTMLResult.success({ + name: "label", + attributes: { + class: ["xfaLabel"] + }, + children: [html] + }); + } +} +class Decimal extends _xfa_object.ContentObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "decimal"); + this.fracDigits = (0, _utils.getInteger)({ + data: attributes.fracDigits, + defaultValue: 2, + validate: x => true + }); + this.id = attributes.id || ""; + this.leadDigits = (0, _utils.getInteger)({ + data: attributes.leadDigits, + defaultValue: -1, + validate: x => true + }); + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } + [_symbol_utils.$finalize]() { + const number = parseFloat(this[_symbol_utils.$content].trim()); + this[_symbol_utils.$content] = isNaN(number) ? null : number; + } + [_symbol_utils.$toHTML](availableSpace) { + return valueToHtml(this[_symbol_utils.$content] !== null ? this[_symbol_utils.$content].toString() : ""); + } +} +class DefaultUi extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "defaultUi", true); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + } +} +class Desc extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "desc", true); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.boolean = new _xfa_object.XFAObjectArray(); + this.date = new _xfa_object.XFAObjectArray(); + this.dateTime = new _xfa_object.XFAObjectArray(); + this.decimal = new _xfa_object.XFAObjectArray(); + this.exData = new _xfa_object.XFAObjectArray(); + this.float = new _xfa_object.XFAObjectArray(); + this.image = new _xfa_object.XFAObjectArray(); + this.integer = new _xfa_object.XFAObjectArray(); + this.text = new _xfa_object.XFAObjectArray(); + this.time = new _xfa_object.XFAObjectArray(); + } +} +class DigestMethod extends _xfa_object.OptionObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "digestMethod", ["", "SHA1", "SHA256", "SHA512", "RIPEMD160"]); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class DigestMethods extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "digestMethods", true); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.digestMethod = new _xfa_object.XFAObjectArray(); + } +} +class Draw extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "draw", true); + this.anchorType = (0, _utils.getStringOption)(attributes.anchorType, ["topLeft", "bottomCenter", "bottomLeft", "bottomRight", "middleCenter", "middleLeft", "middleRight", "topCenter", "topRight"]); + this.colSpan = (0, _utils.getInteger)({ + data: attributes.colSpan, + defaultValue: 1, + validate: n => n >= 1 || n === -1 + }); + this.h = attributes.h ? (0, _utils.getMeasurement)(attributes.h) : ""; + this.hAlign = (0, _utils.getStringOption)(attributes.hAlign, ["left", "center", "justify", "justifyAll", "radix", "right"]); + this.id = attributes.id || ""; + this.locale = attributes.locale || ""; + this.maxH = (0, _utils.getMeasurement)(attributes.maxH, "0pt"); + this.maxW = (0, _utils.getMeasurement)(attributes.maxW, "0pt"); + this.minH = (0, _utils.getMeasurement)(attributes.minH, "0pt"); + this.minW = (0, _utils.getMeasurement)(attributes.minW, "0pt"); + this.name = attributes.name || ""; + this.presence = (0, _utils.getStringOption)(attributes.presence, ["visible", "hidden", "inactive", "invisible"]); + this.relevant = (0, _utils.getRelevant)(attributes.relevant); + this.rotate = (0, _utils.getInteger)({ + data: attributes.rotate, + defaultValue: 0, + validate: x => x % 90 === 0 + }); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.w = attributes.w ? (0, _utils.getMeasurement)(attributes.w) : ""; + this.x = (0, _utils.getMeasurement)(attributes.x, "0pt"); + this.y = (0, _utils.getMeasurement)(attributes.y, "0pt"); + this.assist = null; + this.border = null; + this.caption = null; + this.desc = null; + this.extras = null; + this.font = null; + this.keep = null; + this.margin = null; + this.para = null; + this.traversal = null; + this.ui = null; + this.value = null; + this.setProperty = new _xfa_object.XFAObjectArray(); + } + [_symbol_utils.$setValue](value) { + _setValue(this, value); + } + [_symbol_utils.$toHTML](availableSpace) { + setTabIndex(this); + if (this.presence === "hidden" || this.presence === "inactive") { + return _utils.HTMLResult.EMPTY; + } + (0, _html_utils.fixDimensions)(this); + this[_symbol_utils.$pushPara](); + const savedW = this.w; + const savedH = this.h; + const { + w, + h, + isBroken + } = (0, _html_utils.layoutNode)(this, availableSpace); + if (w && this.w === "") { + if (isBroken && this[_symbol_utils.$getSubformParent]()[_symbol_utils.$isThereMoreWidth]()) { + this[_symbol_utils.$popPara](); + return _utils.HTMLResult.FAILURE; + } + this.w = w; + } + if (h && this.h === "") { + this.h = h; + } + setFirstUnsplittable(this); + if (!(0, _layout.checkDimensions)(this, availableSpace)) { + this.w = savedW; + this.h = savedH; + this[_symbol_utils.$popPara](); + return _utils.HTMLResult.FAILURE; + } + unsetFirstUnsplittable(this); + const style = (0, _html_utils.toStyle)(this, "font", "hAlign", "dimensions", "position", "presence", "rotate", "anchorType", "border", "margin"); + (0, _html_utils.setMinMaxDimensions)(this, style); + if (style.margin) { + style.padding = style.margin; + delete style.margin; + } + const classNames = ["xfaDraw"]; + if (this.font) { + classNames.push("xfaFont"); + } + if ((0, _html_utils.isPrintOnly)(this)) { + classNames.push("xfaPrintOnly"); + } + const attributes = { + style, + id: this[_symbol_utils.$uid], + class: classNames + }; + if (this.name) { + attributes.xfaName = this.name; + } + const html = { + name: "div", + attributes, + children: [] + }; + applyAssist(this, attributes); + const bbox = (0, _html_utils.computeBbox)(this, html, availableSpace); + const value = this.value ? this.value[_symbol_utils.$toHTML](availableSpace).html : null; + if (value === null) { + this.w = savedW; + this.h = savedH; + this[_symbol_utils.$popPara](); + return _utils.HTMLResult.success((0, _html_utils.createWrapper)(this, html), bbox); + } + html.children.push(value); + (0, _html_utils.setPara)(this, style, value); + this.w = savedW; + this.h = savedH; + this[_symbol_utils.$popPara](); + return _utils.HTMLResult.success((0, _html_utils.createWrapper)(this, html), bbox); + } +} +class Edge extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "edge", true); + this.cap = (0, _utils.getStringOption)(attributes.cap, ["square", "butt", "round"]); + this.id = attributes.id || ""; + this.presence = (0, _utils.getStringOption)(attributes.presence, ["visible", "hidden", "inactive", "invisible"]); + this.stroke = (0, _utils.getStringOption)(attributes.stroke, ["solid", "dashDot", "dashDotDot", "dashed", "dotted", "embossed", "etched", "lowered", "raised"]); + this.thickness = (0, _utils.getMeasurement)(attributes.thickness, "0.5pt"); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.color = null; + this.extras = null; + } + [_symbol_utils.$toStyle]() { + const style = (0, _html_utils.toStyle)(this, "visibility"); + Object.assign(style, { + linecap: this.cap, + width: (0, _html_utils.measureToString)(this.thickness), + color: this.color ? this.color[_symbol_utils.$toStyle]() : "#000000", + style: "" + }); + if (this.presence !== "visible") { + style.style = "none"; + } else { + switch (this.stroke) { + case "solid": + style.style = "solid"; + break; + case "dashDot": + style.style = "dashed"; + break; + case "dashDotDot": + style.style = "dashed"; + break; + case "dashed": + style.style = "dashed"; + break; + case "dotted": + style.style = "dotted"; + break; + case "embossed": + style.style = "ridge"; + break; + case "etched": + style.style = "groove"; + break; + case "lowered": + style.style = "inset"; + break; + case "raised": + style.style = "outset"; + break; + } + } + return style; + } +} +class Encoding extends _xfa_object.OptionObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "encoding", ["adbe.x509.rsa_sha1", "adbe.pkcs7.detached", "adbe.pkcs7.sha1"]); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Encodings extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "encodings", true); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.encoding = new _xfa_object.XFAObjectArray(); + } +} +class Encrypt extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "encrypt", true); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.certificate = null; + } +} +class EncryptData extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "encryptData", true); + this.id = attributes.id || ""; + this.operation = (0, _utils.getStringOption)(attributes.operation, ["encrypt", "decrypt"]); + this.target = attributes.target || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.filter = null; + this.manifest = null; + } +} +class Encryption extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "encryption", true); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.certificate = new _xfa_object.XFAObjectArray(); + } +} +class EncryptionMethod extends _xfa_object.OptionObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "encryptionMethod", ["", "AES256-CBC", "TRIPLEDES-CBC", "AES128-CBC", "AES192-CBC"]); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class EncryptionMethods extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "encryptionMethods", true); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.encryptionMethod = new _xfa_object.XFAObjectArray(); + } +} +class Event extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "event", true); + this.activity = (0, _utils.getStringOption)(attributes.activity, ["click", "change", "docClose", "docReady", "enter", "exit", "full", "indexChange", "initialize", "mouseDown", "mouseEnter", "mouseExit", "mouseUp", "postExecute", "postOpen", "postPrint", "postSave", "postSign", "postSubmit", "preExecute", "preOpen", "prePrint", "preSave", "preSign", "preSubmit", "ready", "validationState"]); + this.id = attributes.id || ""; + this.listen = (0, _utils.getStringOption)(attributes.listen, ["refOnly", "refAndDescendents"]); + this.name = attributes.name || ""; + this.ref = attributes.ref || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + this.encryptData = null; + this.execute = null; + this.script = null; + this.signData = null; + this.submit = null; + } +} +class ExData extends _xfa_object.ContentObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "exData"); + this.contentType = attributes.contentType || ""; + this.href = attributes.href || ""; + this.id = attributes.id || ""; + this.maxLength = (0, _utils.getInteger)({ + data: attributes.maxLength, + defaultValue: -1, + validate: x => x >= -1 + }); + this.name = attributes.name || ""; + this.rid = attributes.rid || ""; + this.transferEncoding = (0, _utils.getStringOption)(attributes.transferEncoding, ["none", "base64", "package"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } + [_symbol_utils.$isCDATAXml]() { + return this.contentType === "text/html"; + } + [_symbol_utils.$onChild](child) { + if (this.contentType === "text/html" && child[_symbol_utils.$namespaceId] === _namespaces.NamespaceIds.xhtml.id) { + this[_symbol_utils.$content] = child; + return true; + } + if (this.contentType === "text/xml") { + this[_symbol_utils.$content] = child; + return true; + } + return false; + } + [_symbol_utils.$toHTML](availableSpace) { + if (this.contentType !== "text/html" || !this[_symbol_utils.$content]) { + return _utils.HTMLResult.EMPTY; + } + return this[_symbol_utils.$content][_symbol_utils.$toHTML](availableSpace); + } +} +class ExObject extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "exObject", true); + this.archive = attributes.archive || ""; + this.classId = attributes.classId || ""; + this.codeBase = attributes.codeBase || ""; + this.codeType = attributes.codeType || ""; + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + this.boolean = new _xfa_object.XFAObjectArray(); + this.date = new _xfa_object.XFAObjectArray(); + this.dateTime = new _xfa_object.XFAObjectArray(); + this.decimal = new _xfa_object.XFAObjectArray(); + this.exData = new _xfa_object.XFAObjectArray(); + this.exObject = new _xfa_object.XFAObjectArray(); + this.float = new _xfa_object.XFAObjectArray(); + this.image = new _xfa_object.XFAObjectArray(); + this.integer = new _xfa_object.XFAObjectArray(); + this.text = new _xfa_object.XFAObjectArray(); + this.time = new _xfa_object.XFAObjectArray(); + } +} +class ExclGroup extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "exclGroup", true); + this.access = (0, _utils.getStringOption)(attributes.access, ["open", "nonInteractive", "protected", "readOnly"]); + this.accessKey = attributes.accessKey || ""; + this.anchorType = (0, _utils.getStringOption)(attributes.anchorType, ["topLeft", "bottomCenter", "bottomLeft", "bottomRight", "middleCenter", "middleLeft", "middleRight", "topCenter", "topRight"]); + this.colSpan = (0, _utils.getInteger)({ + data: attributes.colSpan, + defaultValue: 1, + validate: n => n >= 1 || n === -1 + }); + this.h = attributes.h ? (0, _utils.getMeasurement)(attributes.h) : ""; + this.hAlign = (0, _utils.getStringOption)(attributes.hAlign, ["left", "center", "justify", "justifyAll", "radix", "right"]); + this.id = attributes.id || ""; + this.layout = (0, _utils.getStringOption)(attributes.layout, ["position", "lr-tb", "rl-row", "rl-tb", "row", "table", "tb"]); + this.maxH = (0, _utils.getMeasurement)(attributes.maxH, "0pt"); + this.maxW = (0, _utils.getMeasurement)(attributes.maxW, "0pt"); + this.minH = (0, _utils.getMeasurement)(attributes.minH, "0pt"); + this.minW = (0, _utils.getMeasurement)(attributes.minW, "0pt"); + this.name = attributes.name || ""; + this.presence = (0, _utils.getStringOption)(attributes.presence, ["visible", "hidden", "inactive", "invisible"]); + this.relevant = (0, _utils.getRelevant)(attributes.relevant); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.w = attributes.w ? (0, _utils.getMeasurement)(attributes.w) : ""; + this.x = (0, _utils.getMeasurement)(attributes.x, "0pt"); + this.y = (0, _utils.getMeasurement)(attributes.y, "0pt"); + this.assist = null; + this.bind = null; + this.border = null; + this.calculate = null; + this.caption = null; + this.desc = null; + this.extras = null; + this.margin = null; + this.para = null; + this.traversal = null; + this.validate = null; + this.connect = new _xfa_object.XFAObjectArray(); + this.event = new _xfa_object.XFAObjectArray(); + this.field = new _xfa_object.XFAObjectArray(); + this.setProperty = new _xfa_object.XFAObjectArray(); + } + [_symbol_utils.$isBindable]() { + return true; + } + [_symbol_utils.$hasSettableValue]() { + return true; + } + [_symbol_utils.$setValue](value) { + for (const field of this.field.children) { + if (!field.value) { + const nodeValue = new Value({}); + field[_symbol_utils.$appendChild](nodeValue); + field.value = nodeValue; + } + field.value[_symbol_utils.$setValue](value); + } + } + [_symbol_utils.$isThereMoreWidth]() { + return this.layout.endsWith("-tb") && this[_symbol_utils.$extra].attempt === 0 && this[_symbol_utils.$extra].numberInLine > 0 || this[_symbol_utils.$getParent]()[_symbol_utils.$isThereMoreWidth](); + } + [_symbol_utils.$isSplittable]() { + const parent = this[_symbol_utils.$getSubformParent](); + if (!parent[_symbol_utils.$isSplittable]()) { + return false; + } + if (this[_symbol_utils.$extra]._isSplittable !== undefined) { + return this[_symbol_utils.$extra]._isSplittable; + } + if (this.layout === "position" || this.layout.includes("row")) { + this[_symbol_utils.$extra]._isSplittable = false; + return false; + } + if (parent.layout?.endsWith("-tb") && parent[_symbol_utils.$extra].numberInLine !== 0) { + return false; + } + this[_symbol_utils.$extra]._isSplittable = true; + return true; + } + [_symbol_utils.$flushHTML]() { + return (0, _layout.flushHTML)(this); + } + [_symbol_utils.$addHTML](html, bbox) { + (0, _layout.addHTML)(this, html, bbox); + } + [_symbol_utils.$getAvailableSpace]() { + return (0, _layout.getAvailableSpace)(this); + } + [_symbol_utils.$toHTML](availableSpace) { + setTabIndex(this); + if (this.presence === "hidden" || this.presence === "inactive" || this.h === 0 || this.w === 0) { + return _utils.HTMLResult.EMPTY; + } + (0, _html_utils.fixDimensions)(this); + const children = []; + const attributes = { + id: this[_symbol_utils.$uid], + class: [] + }; + (0, _html_utils.setAccess)(this, attributes.class); + if (!this[_symbol_utils.$extra]) { + this[_symbol_utils.$extra] = Object.create(null); + } + Object.assign(this[_symbol_utils.$extra], { + children, + attributes, + attempt: 0, + line: null, + numberInLine: 0, + availableSpace: { + width: Math.min(this.w || Infinity, availableSpace.width), + height: Math.min(this.h || Infinity, availableSpace.height) + }, + width: 0, + height: 0, + prevHeight: 0, + currentWidth: 0 + }); + const isSplittable = this[_symbol_utils.$isSplittable](); + if (!isSplittable) { + setFirstUnsplittable(this); + } + if (!(0, _layout.checkDimensions)(this, availableSpace)) { + return _utils.HTMLResult.FAILURE; + } + const filter = new Set(["field"]); + if (this.layout.includes("row")) { + const columnWidths = this[_symbol_utils.$getSubformParent]().columnWidths; + if (Array.isArray(columnWidths) && columnWidths.length > 0) { + this[_symbol_utils.$extra].columnWidths = columnWidths; + this[_symbol_utils.$extra].currentColumn = 0; + } + } + const style = (0, _html_utils.toStyle)(this, "anchorType", "dimensions", "position", "presence", "border", "margin", "hAlign"); + const classNames = ["xfaExclgroup"]; + const cl = (0, _html_utils.layoutClass)(this); + if (cl) { + classNames.push(cl); + } + if ((0, _html_utils.isPrintOnly)(this)) { + classNames.push("xfaPrintOnly"); + } + attributes.style = style; + attributes.class = classNames; + if (this.name) { + attributes.xfaName = this.name; + } + this[_symbol_utils.$pushPara](); + const isLrTb = this.layout === "lr-tb" || this.layout === "rl-tb"; + const maxRun = isLrTb ? MAX_ATTEMPTS_FOR_LRTB_LAYOUT : 1; + for (; this[_symbol_utils.$extra].attempt < maxRun; this[_symbol_utils.$extra].attempt++) { + if (isLrTb && this[_symbol_utils.$extra].attempt === MAX_ATTEMPTS_FOR_LRTB_LAYOUT - 1) { + this[_symbol_utils.$extra].numberInLine = 0; + } + const result = this[_symbol_utils.$childrenToHTML]({ + filter, + include: true + }); + if (result.success) { + break; + } + if (result.isBreak()) { + this[_symbol_utils.$popPara](); + return result; + } + if (isLrTb && this[_symbol_utils.$extra].attempt === 0 && this[_symbol_utils.$extra].numberInLine === 0 && !this[_symbol_utils.$getTemplateRoot]()[_symbol_utils.$extra].noLayoutFailure) { + this[_symbol_utils.$extra].attempt = maxRun; + break; + } + } + this[_symbol_utils.$popPara](); + if (!isSplittable) { + unsetFirstUnsplittable(this); + } + if (this[_symbol_utils.$extra].attempt === maxRun) { + if (!isSplittable) { + delete this[_symbol_utils.$extra]; + } + return _utils.HTMLResult.FAILURE; + } + let marginH = 0; + let marginV = 0; + if (this.margin) { + marginH = this.margin.leftInset + this.margin.rightInset; + marginV = this.margin.topInset + this.margin.bottomInset; + } + const width = Math.max(this[_symbol_utils.$extra].width + marginH, this.w || 0); + const height = Math.max(this[_symbol_utils.$extra].height + marginV, this.h || 0); + const bbox = [this.x, this.y, width, height]; + if (this.w === "") { + style.width = (0, _html_utils.measureToString)(width); + } + if (this.h === "") { + style.height = (0, _html_utils.measureToString)(height); + } + const html = { + name: "div", + attributes, + children + }; + applyAssist(this, attributes); + delete this[_symbol_utils.$extra]; + return _utils.HTMLResult.success((0, _html_utils.createWrapper)(this, html), bbox); + } +} +class Execute extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "execute"); + this.connection = attributes.connection || ""; + this.executeType = (0, _utils.getStringOption)(attributes.executeType, ["import", "remerge"]); + this.id = attributes.id || ""; + this.runAt = (0, _utils.getStringOption)(attributes.runAt, ["client", "both", "server"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Extras extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "extras", true); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.boolean = new _xfa_object.XFAObjectArray(); + this.date = new _xfa_object.XFAObjectArray(); + this.dateTime = new _xfa_object.XFAObjectArray(); + this.decimal = new _xfa_object.XFAObjectArray(); + this.exData = new _xfa_object.XFAObjectArray(); + this.extras = new _xfa_object.XFAObjectArray(); + this.float = new _xfa_object.XFAObjectArray(); + this.image = new _xfa_object.XFAObjectArray(); + this.integer = new _xfa_object.XFAObjectArray(); + this.text = new _xfa_object.XFAObjectArray(); + this.time = new _xfa_object.XFAObjectArray(); + } +} +class Field extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "field", true); + this.access = (0, _utils.getStringOption)(attributes.access, ["open", "nonInteractive", "protected", "readOnly"]); + this.accessKey = attributes.accessKey || ""; + this.anchorType = (0, _utils.getStringOption)(attributes.anchorType, ["topLeft", "bottomCenter", "bottomLeft", "bottomRight", "middleCenter", "middleLeft", "middleRight", "topCenter", "topRight"]); + this.colSpan = (0, _utils.getInteger)({ + data: attributes.colSpan, + defaultValue: 1, + validate: n => n >= 1 || n === -1 + }); + this.h = attributes.h ? (0, _utils.getMeasurement)(attributes.h) : ""; + this.hAlign = (0, _utils.getStringOption)(attributes.hAlign, ["left", "center", "justify", "justifyAll", "radix", "right"]); + this.id = attributes.id || ""; + this.locale = attributes.locale || ""; + this.maxH = (0, _utils.getMeasurement)(attributes.maxH, "0pt"); + this.maxW = (0, _utils.getMeasurement)(attributes.maxW, "0pt"); + this.minH = (0, _utils.getMeasurement)(attributes.minH, "0pt"); + this.minW = (0, _utils.getMeasurement)(attributes.minW, "0pt"); + this.name = attributes.name || ""; + this.presence = (0, _utils.getStringOption)(attributes.presence, ["visible", "hidden", "inactive", "invisible"]); + this.relevant = (0, _utils.getRelevant)(attributes.relevant); + this.rotate = (0, _utils.getInteger)({ + data: attributes.rotate, + defaultValue: 0, + validate: x => x % 90 === 0 + }); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.w = attributes.w ? (0, _utils.getMeasurement)(attributes.w) : ""; + this.x = (0, _utils.getMeasurement)(attributes.x, "0pt"); + this.y = (0, _utils.getMeasurement)(attributes.y, "0pt"); + this.assist = null; + this.bind = null; + this.border = null; + this.calculate = null; + this.caption = null; + this.desc = null; + this.extras = null; + this.font = null; + this.format = null; + this.items = new _xfa_object.XFAObjectArray(2); + this.keep = null; + this.margin = null; + this.para = null; + this.traversal = null; + this.ui = null; + this.validate = null; + this.value = null; + this.bindItems = new _xfa_object.XFAObjectArray(); + this.connect = new _xfa_object.XFAObjectArray(); + this.event = new _xfa_object.XFAObjectArray(); + this.setProperty = new _xfa_object.XFAObjectArray(); + } + [_symbol_utils.$isBindable]() { + return true; + } + [_symbol_utils.$setValue](value) { + _setValue(this, value); + } + [_symbol_utils.$toHTML](availableSpace) { + setTabIndex(this); + if (!this.ui) { + this.ui = new Ui({}); + this.ui[_symbol_utils.$globalData] = this[_symbol_utils.$globalData]; + this[_symbol_utils.$appendChild](this.ui); + let node; + switch (this.items.children.length) { + case 0: + node = new TextEdit({}); + this.ui.textEdit = node; + break; + case 1: + node = new CheckButton({}); + this.ui.checkButton = node; + break; + case 2: + node = new ChoiceList({}); + this.ui.choiceList = node; + break; + } + this.ui[_symbol_utils.$appendChild](node); + } + if (!this.ui || this.presence === "hidden" || this.presence === "inactive" || this.h === 0 || this.w === 0) { + return _utils.HTMLResult.EMPTY; + } + if (this.caption) { + delete this.caption[_symbol_utils.$extra]; + } + this[_symbol_utils.$pushPara](); + const caption = this.caption ? this.caption[_symbol_utils.$toHTML](availableSpace).html : null; + const savedW = this.w; + const savedH = this.h; + let marginH = 0; + let marginV = 0; + if (this.margin) { + marginH = this.margin.leftInset + this.margin.rightInset; + marginV = this.margin.topInset + this.margin.bottomInset; + } + let borderDims = null; + if (this.w === "" || this.h === "") { + let width = null; + let height = null; + let uiW = 0; + let uiH = 0; + if (this.ui.checkButton) { + uiW = uiH = this.ui.checkButton.size; + } else { + const { + w, + h + } = (0, _html_utils.layoutNode)(this, availableSpace); + if (w !== null) { + uiW = w; + uiH = h; + } else { + uiH = (0, _fonts.getMetrics)(this.font, true).lineNoGap; + } + } + borderDims = getBorderDims(this.ui[_symbol_utils.$getExtra]()); + uiW += borderDims.w; + uiH += borderDims.h; + if (this.caption) { + const { + w, + h, + isBroken + } = this.caption[_symbol_utils.$getExtra](availableSpace); + if (isBroken && this[_symbol_utils.$getSubformParent]()[_symbol_utils.$isThereMoreWidth]()) { + this[_symbol_utils.$popPara](); + return _utils.HTMLResult.FAILURE; + } + width = w; + height = h; + switch (this.caption.placement) { + case "left": + case "right": + case "inline": + width += uiW; + break; + case "top": + case "bottom": + height += uiH; + break; + } + } else { + width = uiW; + height = uiH; + } + if (width && this.w === "") { + width += marginH; + this.w = Math.min(this.maxW <= 0 ? Infinity : this.maxW, this.minW + 1 < width ? width : this.minW); + } + if (height && this.h === "") { + height += marginV; + this.h = Math.min(this.maxH <= 0 ? Infinity : this.maxH, this.minH + 1 < height ? height : this.minH); + } + } + this[_symbol_utils.$popPara](); + (0, _html_utils.fixDimensions)(this); + setFirstUnsplittable(this); + if (!(0, _layout.checkDimensions)(this, availableSpace)) { + this.w = savedW; + this.h = savedH; + this[_symbol_utils.$popPara](); + return _utils.HTMLResult.FAILURE; + } + unsetFirstUnsplittable(this); + const style = (0, _html_utils.toStyle)(this, "font", "dimensions", "position", "rotate", "anchorType", "presence", "margin", "hAlign"); + (0, _html_utils.setMinMaxDimensions)(this, style); + const classNames = ["xfaField"]; + if (this.font) { + classNames.push("xfaFont"); + } + if ((0, _html_utils.isPrintOnly)(this)) { + classNames.push("xfaPrintOnly"); + } + const attributes = { + style, + id: this[_symbol_utils.$uid], + class: classNames + }; + if (style.margin) { + style.padding = style.margin; + delete style.margin; + } + (0, _html_utils.setAccess)(this, classNames); + if (this.name) { + attributes.xfaName = this.name; + } + const children = []; + const html = { + name: "div", + attributes, + children + }; + applyAssist(this, attributes); + const borderStyle = this.border ? this.border[_symbol_utils.$toStyle]() : null; + const bbox = (0, _html_utils.computeBbox)(this, html, availableSpace); + const ui = this.ui[_symbol_utils.$toHTML]().html; + if (!ui) { + Object.assign(style, borderStyle); + return _utils.HTMLResult.success((0, _html_utils.createWrapper)(this, html), bbox); + } + if (this[_symbol_utils.$tabIndex]) { + if (ui.children?.[0]) { + ui.children[0].attributes.tabindex = this[_symbol_utils.$tabIndex]; + } else { + ui.attributes.tabindex = this[_symbol_utils.$tabIndex]; + } + } + if (!ui.attributes.style) { + ui.attributes.style = Object.create(null); + } + let aElement = null; + if (this.ui.button) { + if (ui.children.length === 1) { + [aElement] = ui.children.splice(0, 1); + } + Object.assign(ui.attributes.style, borderStyle); + } else { + Object.assign(style, borderStyle); + } + children.push(ui); + if (this.value) { + if (this.ui.imageEdit) { + ui.children.push(this.value[_symbol_utils.$toHTML]().html); + } else if (!this.ui.button) { + let value = ""; + if (this.value.exData) { + value = this.value.exData[_symbol_utils.$text](); + } else if (this.value.text) { + value = this.value.text[_symbol_utils.$getExtra](); + } else { + const htmlValue = this.value[_symbol_utils.$toHTML]().html; + if (htmlValue !== null) { + value = htmlValue.children[0].value; + } + } + if (this.ui.textEdit && this.value.text?.maxChars) { + ui.children[0].attributes.maxLength = this.value.text.maxChars; + } + if (value) { + if (this.ui.numericEdit) { + value = parseFloat(value); + value = isNaN(value) ? "" : value.toString(); + } + if (ui.children[0].name === "textarea") { + ui.children[0].attributes.textContent = value; + } else { + ui.children[0].attributes.value = value; + } + } + } + } + if (!this.ui.imageEdit && ui.children?.[0] && this.h) { + borderDims = borderDims || getBorderDims(this.ui[_symbol_utils.$getExtra]()); + let captionHeight = 0; + if (this.caption && ["top", "bottom"].includes(this.caption.placement)) { + captionHeight = this.caption.reserve; + if (captionHeight <= 0) { + captionHeight = this.caption[_symbol_utils.$getExtra](availableSpace).h; + } + const inputHeight = this.h - captionHeight - marginV - borderDims.h; + ui.children[0].attributes.style.height = (0, _html_utils.measureToString)(inputHeight); + } else { + ui.children[0].attributes.style.height = "100%"; + } + } + if (aElement) { + ui.children.push(aElement); + } + if (!caption) { + if (ui.attributes.class) { + ui.attributes.class.push("xfaLeft"); + } + this.w = savedW; + this.h = savedH; + return _utils.HTMLResult.success((0, _html_utils.createWrapper)(this, html), bbox); + } + if (this.ui.button) { + if (style.padding) { + delete style.padding; + } + if (caption.name === "div") { + caption.name = "span"; + } + ui.children.push(caption); + return _utils.HTMLResult.success(html, bbox); + } else if (this.ui.checkButton) { + caption.attributes.class[0] = "xfaCaptionForCheckButton"; + } + if (!ui.attributes.class) { + ui.attributes.class = []; + } + ui.children.splice(0, 0, caption); + switch (this.caption.placement) { + case "left": + ui.attributes.class.push("xfaLeft"); + break; + case "right": + ui.attributes.class.push("xfaRight"); + break; + case "top": + ui.attributes.class.push("xfaTop"); + break; + case "bottom": + ui.attributes.class.push("xfaBottom"); + break; + case "inline": + ui.attributes.class.push("xfaLeft"); + break; + } + this.w = savedW; + this.h = savedH; + return _utils.HTMLResult.success((0, _html_utils.createWrapper)(this, html), bbox); + } +} +exports.Field = Field; +class Fill extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "fill", true); + this.id = attributes.id || ""; + this.presence = (0, _utils.getStringOption)(attributes.presence, ["visible", "hidden", "inactive", "invisible"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.color = null; + this.extras = null; + this.linear = null; + this.pattern = null; + this.radial = null; + this.solid = null; + this.stipple = null; + } + [_symbol_utils.$toStyle]() { + const parent = this[_symbol_utils.$getParent](); + const grandpa = parent[_symbol_utils.$getParent](); + const ggrandpa = grandpa[_symbol_utils.$getParent](); + const style = Object.create(null); + let propName = "color"; + let altPropName = propName; + if (parent instanceof Border) { + propName = "background-color"; + altPropName = "background"; + if (ggrandpa instanceof Ui) { + style.backgroundColor = "white"; + } + } + if (parent instanceof Rectangle || parent instanceof Arc) { + propName = altPropName = "fill"; + style.fill = "white"; + } + for (const name of Object.getOwnPropertyNames(this)) { + if (name === "extras" || name === "color") { + continue; + } + const obj = this[name]; + if (!(obj instanceof _xfa_object.XFAObject)) { + continue; + } + const color = obj[_symbol_utils.$toStyle](this.color); + if (color) { + style[color.startsWith("#") ? propName : altPropName] = color; + } + return style; + } + if (this.color?.value) { + const color = this.color[_symbol_utils.$toStyle](); + style[color.startsWith("#") ? propName : altPropName] = color; + } + return style; + } +} +class Filter extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "filter", true); + this.addRevocationInfo = (0, _utils.getStringOption)(attributes.addRevocationInfo, ["", "required", "optional", "none"]); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.version = (0, _utils.getInteger)({ + data: this.version, + defaultValue: 5, + validate: x => x >= 1 && x <= 5 + }); + this.appearanceFilter = null; + this.certificates = null; + this.digestMethods = null; + this.encodings = null; + this.encryptionMethods = null; + this.handler = null; + this.lockDocument = null; + this.mdp = null; + this.reasons = null; + this.timeStamp = null; + } +} +class Float extends _xfa_object.ContentObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "float"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } + [_symbol_utils.$finalize]() { + const number = parseFloat(this[_symbol_utils.$content].trim()); + this[_symbol_utils.$content] = isNaN(number) ? null : number; + } + [_symbol_utils.$toHTML](availableSpace) { + return valueToHtml(this[_symbol_utils.$content] !== null ? this[_symbol_utils.$content].toString() : ""); + } +} +class Font extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "font", true); + this.baselineShift = (0, _utils.getMeasurement)(attributes.baselineShift); + this.fontHorizontalScale = (0, _utils.getFloat)({ + data: attributes.fontHorizontalScale, + defaultValue: 100, + validate: x => x >= 0 + }); + this.fontVerticalScale = (0, _utils.getFloat)({ + data: attributes.fontVerticalScale, + defaultValue: 100, + validate: x => x >= 0 + }); + this.id = attributes.id || ""; + this.kerningMode = (0, _utils.getStringOption)(attributes.kerningMode, ["none", "pair"]); + this.letterSpacing = (0, _utils.getMeasurement)(attributes.letterSpacing, "0"); + this.lineThrough = (0, _utils.getInteger)({ + data: attributes.lineThrough, + defaultValue: 0, + validate: x => x === 1 || x === 2 + }); + this.lineThroughPeriod = (0, _utils.getStringOption)(attributes.lineThroughPeriod, ["all", "word"]); + this.overline = (0, _utils.getInteger)({ + data: attributes.overline, + defaultValue: 0, + validate: x => x === 1 || x === 2 + }); + this.overlinePeriod = (0, _utils.getStringOption)(attributes.overlinePeriod, ["all", "word"]); + this.posture = (0, _utils.getStringOption)(attributes.posture, ["normal", "italic"]); + this.size = (0, _utils.getMeasurement)(attributes.size, "10pt"); + this.typeface = attributes.typeface || "Courier"; + this.underline = (0, _utils.getInteger)({ + data: attributes.underline, + defaultValue: 0, + validate: x => x === 1 || x === 2 + }); + this.underlinePeriod = (0, _utils.getStringOption)(attributes.underlinePeriod, ["all", "word"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.weight = (0, _utils.getStringOption)(attributes.weight, ["normal", "bold"]); + this.extras = null; + this.fill = null; + } + [_symbol_utils.$clean](builder) { + super[_symbol_utils.$clean](builder); + this[_symbol_utils.$globalData].usedTypefaces.add(this.typeface); + } + [_symbol_utils.$toStyle]() { + const style = (0, _html_utils.toStyle)(this, "fill"); + const color = style.color; + if (color) { + if (color === "#000000") { + delete style.color; + } else if (!color.startsWith("#")) { + style.background = color; + style.backgroundClip = "text"; + style.color = "transparent"; + } + } + if (this.baselineShift) { + style.verticalAlign = (0, _html_utils.measureToString)(this.baselineShift); + } + style.fontKerning = this.kerningMode === "none" ? "none" : "normal"; + style.letterSpacing = (0, _html_utils.measureToString)(this.letterSpacing); + if (this.lineThrough !== 0) { + style.textDecoration = "line-through"; + if (this.lineThrough === 2) { + style.textDecorationStyle = "double"; + } + } + if (this.overline !== 0) { + style.textDecoration = "overline"; + if (this.overline === 2) { + style.textDecorationStyle = "double"; + } + } + style.fontStyle = this.posture; + style.fontSize = (0, _html_utils.measureToString)(0.99 * this.size); + (0, _html_utils.setFontFamily)(this, this, this[_symbol_utils.$globalData].fontFinder, style); + if (this.underline !== 0) { + style.textDecoration = "underline"; + if (this.underline === 2) { + style.textDecorationStyle = "double"; + } + } + style.fontWeight = this.weight; + return style; + } +} +class Format extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "format", true); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + this.picture = null; + } +} +class Handler extends _xfa_object.StringObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "handler"); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Hyphenation extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "hyphenation"); + this.excludeAllCaps = (0, _utils.getInteger)({ + data: attributes.excludeAllCaps, + defaultValue: 0, + validate: x => x === 1 + }); + this.excludeInitialCap = (0, _utils.getInteger)({ + data: attributes.excludeInitialCap, + defaultValue: 0, + validate: x => x === 1 + }); + this.hyphenate = (0, _utils.getInteger)({ + data: attributes.hyphenate, + defaultValue: 0, + validate: x => x === 1 + }); + this.id = attributes.id || ""; + this.pushCharacterCount = (0, _utils.getInteger)({ + data: attributes.pushCharacterCount, + defaultValue: 3, + validate: x => x >= 0 + }); + this.remainCharacterCount = (0, _utils.getInteger)({ + data: attributes.remainCharacterCount, + defaultValue: 3, + validate: x => x >= 0 + }); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.wordCharacterCount = (0, _utils.getInteger)({ + data: attributes.wordCharacterCount, + defaultValue: 7, + validate: x => x >= 0 + }); + } +} +class Image extends _xfa_object.StringObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "image"); + this.aspect = (0, _utils.getStringOption)(attributes.aspect, ["fit", "actual", "height", "none", "width"]); + this.contentType = attributes.contentType || ""; + this.href = attributes.href || ""; + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.transferEncoding = (0, _utils.getStringOption)(attributes.transferEncoding, ["base64", "none", "package"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } + [_symbol_utils.$toHTML]() { + if (this.contentType && !MIMES.has(this.contentType.toLowerCase())) { + return _utils.HTMLResult.EMPTY; + } + let buffer = this[_symbol_utils.$globalData].images && this[_symbol_utils.$globalData].images.get(this.href); + if (!buffer && (this.href || !this[_symbol_utils.$content])) { + return _utils.HTMLResult.EMPTY; + } + if (!buffer && this.transferEncoding === "base64") { + buffer = (0, _util.stringToBytes)(atob(this[_symbol_utils.$content])); + } + if (!buffer) { + return _utils.HTMLResult.EMPTY; + } + if (!this.contentType) { + for (const [header, type] of IMAGES_HEADERS) { + if (buffer.length > header.length && header.every((x, i) => x === buffer[i])) { + this.contentType = type; + break; + } + } + if (!this.contentType) { + return _utils.HTMLResult.EMPTY; + } + } + const blob = new Blob([buffer], { + type: this.contentType + }); + let style; + switch (this.aspect) { + case "fit": + case "actual": + break; + case "height": + style = { + height: "100%", + objectFit: "fill" + }; + break; + case "none": + style = { + width: "100%", + height: "100%", + objectFit: "fill" + }; + break; + case "width": + style = { + width: "100%", + objectFit: "fill" + }; + break; + } + const parent = this[_symbol_utils.$getParent](); + return _utils.HTMLResult.success({ + name: "img", + attributes: { + class: ["xfaImage"], + style, + src: URL.createObjectURL(blob), + alt: parent ? ariaLabel(parent[_symbol_utils.$getParent]()) : null + } + }); + } +} +class ImageEdit extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "imageEdit", true); + this.data = (0, _utils.getStringOption)(attributes.data, ["link", "embed"]); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.border = null; + this.extras = null; + this.margin = null; + } + [_symbol_utils.$toHTML](availableSpace) { + if (this.data === "embed") { + return _utils.HTMLResult.success({ + name: "div", + children: [], + attributes: {} + }); + } + return _utils.HTMLResult.EMPTY; + } +} +class Integer extends _xfa_object.ContentObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "integer"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } + [_symbol_utils.$finalize]() { + const number = parseInt(this[_symbol_utils.$content].trim(), 10); + this[_symbol_utils.$content] = isNaN(number) ? null : number; + } + [_symbol_utils.$toHTML](availableSpace) { + return valueToHtml(this[_symbol_utils.$content] !== null ? this[_symbol_utils.$content].toString() : ""); + } +} +class Issuers extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "issuers", true); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.certificate = new _xfa_object.XFAObjectArray(); + } +} +class Items extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "items", true); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.presence = (0, _utils.getStringOption)(attributes.presence, ["visible", "hidden", "inactive", "invisible"]); + this.ref = attributes.ref || ""; + this.save = (0, _utils.getInteger)({ + data: attributes.save, + defaultValue: 0, + validate: x => x === 1 + }); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.boolean = new _xfa_object.XFAObjectArray(); + this.date = new _xfa_object.XFAObjectArray(); + this.dateTime = new _xfa_object.XFAObjectArray(); + this.decimal = new _xfa_object.XFAObjectArray(); + this.exData = new _xfa_object.XFAObjectArray(); + this.float = new _xfa_object.XFAObjectArray(); + this.image = new _xfa_object.XFAObjectArray(); + this.integer = new _xfa_object.XFAObjectArray(); + this.text = new _xfa_object.XFAObjectArray(); + this.time = new _xfa_object.XFAObjectArray(); + } + [_symbol_utils.$toHTML]() { + const output = []; + for (const child of this[_symbol_utils.$getChildren]()) { + output.push(child[_symbol_utils.$text]()); + } + return _utils.HTMLResult.success(output); + } +} +exports.Items = Items; +class Keep extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "keep", true); + this.id = attributes.id || ""; + const options = ["none", "contentArea", "pageArea"]; + this.intact = (0, _utils.getStringOption)(attributes.intact, options); + this.next = (0, _utils.getStringOption)(attributes.next, options); + this.previous = (0, _utils.getStringOption)(attributes.previous, options); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + } +} +class KeyUsage extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "keyUsage"); + const options = ["", "yes", "no"]; + this.crlSign = (0, _utils.getStringOption)(attributes.crlSign, options); + this.dataEncipherment = (0, _utils.getStringOption)(attributes.dataEncipherment, options); + this.decipherOnly = (0, _utils.getStringOption)(attributes.decipherOnly, options); + this.digitalSignature = (0, _utils.getStringOption)(attributes.digitalSignature, options); + this.encipherOnly = (0, _utils.getStringOption)(attributes.encipherOnly, options); + this.id = attributes.id || ""; + this.keyAgreement = (0, _utils.getStringOption)(attributes.keyAgreement, options); + this.keyCertSign = (0, _utils.getStringOption)(attributes.keyCertSign, options); + this.keyEncipherment = (0, _utils.getStringOption)(attributes.keyEncipherment, options); + this.nonRepudiation = (0, _utils.getStringOption)(attributes.nonRepudiation, options); + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Line extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "line", true); + this.hand = (0, _utils.getStringOption)(attributes.hand, ["even", "left", "right"]); + this.id = attributes.id || ""; + this.slope = (0, _utils.getStringOption)(attributes.slope, ["\\", "/"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.edge = null; + } + [_symbol_utils.$toHTML]() { + const parent = this[_symbol_utils.$getParent]()[_symbol_utils.$getParent](); + const edge = this.edge || new Edge({}); + const edgeStyle = edge[_symbol_utils.$toStyle](); + const style = Object.create(null); + const thickness = edge.presence === "visible" ? edge.thickness : 0; + style.strokeWidth = (0, _html_utils.measureToString)(thickness); + style.stroke = edgeStyle.color; + let x1, y1, x2, y2; + let width = "100%"; + let height = "100%"; + if (parent.w <= thickness) { + [x1, y1, x2, y2] = ["50%", 0, "50%", "100%"]; + width = style.strokeWidth; + } else if (parent.h <= thickness) { + [x1, y1, x2, y2] = [0, "50%", "100%", "50%"]; + height = style.strokeWidth; + } else if (this.slope === "\\") { + [x1, y1, x2, y2] = [0, 0, "100%", "100%"]; + } else { + [x1, y1, x2, y2] = [0, "100%", "100%", 0]; + } + const line = { + name: "line", + attributes: { + xmlns: SVG_NS, + x1, + y1, + x2, + y2, + style + } + }; + const svg = { + name: "svg", + children: [line], + attributes: { + xmlns: SVG_NS, + width, + height, + style: { + overflow: "visible" + } + } + }; + if (hasMargin(parent)) { + return _utils.HTMLResult.success({ + name: "div", + attributes: { + style: { + display: "inline", + width: "100%", + height: "100%" + } + }, + children: [svg] + }); + } + svg.attributes.style.position = "absolute"; + return _utils.HTMLResult.success(svg); + } +} +class Linear extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "linear", true); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["toRight", "toBottom", "toLeft", "toTop"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.color = null; + this.extras = null; + } + [_symbol_utils.$toStyle](startColor) { + startColor = startColor ? startColor[_symbol_utils.$toStyle]() : "#FFFFFF"; + const transf = this.type.replace(/([RBLT])/, " $1").toLowerCase(); + const endColor = this.color ? this.color[_symbol_utils.$toStyle]() : "#000000"; + return `linear-gradient(${transf}, ${startColor}, ${endColor})`; + } +} +class LockDocument extends _xfa_object.ContentObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "lockDocument"); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } + [_symbol_utils.$finalize]() { + this[_symbol_utils.$content] = (0, _utils.getStringOption)(this[_symbol_utils.$content], ["auto", "0", "1"]); + } +} +class Manifest extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "manifest", true); + this.action = (0, _utils.getStringOption)(attributes.action, ["include", "all", "exclude"]); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + this.ref = new _xfa_object.XFAObjectArray(); + } +} +class Margin extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "margin", true); + this.bottomInset = (0, _utils.getMeasurement)(attributes.bottomInset, "0"); + this.id = attributes.id || ""; + this.leftInset = (0, _utils.getMeasurement)(attributes.leftInset, "0"); + this.rightInset = (0, _utils.getMeasurement)(attributes.rightInset, "0"); + this.topInset = (0, _utils.getMeasurement)(attributes.topInset, "0"); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + } + [_symbol_utils.$toStyle]() { + return { + margin: (0, _html_utils.measureToString)(this.topInset) + " " + (0, _html_utils.measureToString)(this.rightInset) + " " + (0, _html_utils.measureToString)(this.bottomInset) + " " + (0, _html_utils.measureToString)(this.leftInset) + }; + } +} +class Mdp extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "mdp"); + this.id = attributes.id || ""; + this.permissions = (0, _utils.getInteger)({ + data: attributes.permissions, + defaultValue: 2, + validate: x => x === 1 || x === 3 + }); + this.signatureType = (0, _utils.getStringOption)(attributes.signatureType, ["filler", "author"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Medium extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "medium"); + this.id = attributes.id || ""; + this.imagingBBox = (0, _utils.getBBox)(attributes.imagingBBox); + this.long = (0, _utils.getMeasurement)(attributes.long); + this.orientation = (0, _utils.getStringOption)(attributes.orientation, ["portrait", "landscape"]); + this.short = (0, _utils.getMeasurement)(attributes.short); + this.stock = attributes.stock || ""; + this.trayIn = (0, _utils.getStringOption)(attributes.trayIn, ["auto", "delegate", "pageFront"]); + this.trayOut = (0, _utils.getStringOption)(attributes.trayOut, ["auto", "delegate"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Message extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "message", true); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.text = new _xfa_object.XFAObjectArray(); + } +} +class NumericEdit extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "numericEdit", true); + this.hScrollPolicy = (0, _utils.getStringOption)(attributes.hScrollPolicy, ["auto", "off", "on"]); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.border = null; + this.comb = null; + this.extras = null; + this.margin = null; + } + [_symbol_utils.$toHTML](availableSpace) { + const style = (0, _html_utils.toStyle)(this, "border", "font", "margin"); + const field = this[_symbol_utils.$getParent]()[_symbol_utils.$getParent](); + const html = { + name: "input", + attributes: { + type: "text", + fieldId: field[_symbol_utils.$uid], + dataId: field[_symbol_utils.$data]?.[_symbol_utils.$uid] || field[_symbol_utils.$uid], + class: ["xfaTextfield"], + style, + "aria-label": ariaLabel(field), + "aria-required": false + } + }; + if (isRequired(field)) { + html.attributes["aria-required"] = true; + html.attributes.required = true; + } + return _utils.HTMLResult.success({ + name: "label", + attributes: { + class: ["xfaLabel"] + }, + children: [html] + }); + } +} +class Occur extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "occur", true); + this.id = attributes.id || ""; + this.initial = attributes.initial !== "" ? (0, _utils.getInteger)({ + data: attributes.initial, + defaultValue: "", + validate: x => true + }) : ""; + this.max = attributes.max !== "" ? (0, _utils.getInteger)({ + data: attributes.max, + defaultValue: 1, + validate: x => true + }) : ""; + this.min = attributes.min !== "" ? (0, _utils.getInteger)({ + data: attributes.min, + defaultValue: 1, + validate: x => true + }) : ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + } + [_symbol_utils.$clean]() { + const parent = this[_symbol_utils.$getParent](); + const originalMin = this.min; + if (this.min === "") { + this.min = parent instanceof PageArea || parent instanceof PageSet ? 0 : 1; + } + if (this.max === "") { + if (originalMin === "") { + this.max = parent instanceof PageArea || parent instanceof PageSet ? -1 : 1; + } else { + this.max = this.min; + } + } + if (this.max !== -1 && this.max < this.min) { + this.max = this.min; + } + if (this.initial === "") { + this.initial = parent instanceof Template ? 1 : this.min; + } + } +} +class Oid extends _xfa_object.StringObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "oid"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Oids extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "oids", true); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.oid = new _xfa_object.XFAObjectArray(); + } +} +class Overflow extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "overflow"); + this.id = attributes.id || ""; + this.leader = attributes.leader || ""; + this.target = attributes.target || ""; + this.trailer = attributes.trailer || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } + [_symbol_utils.$getExtra]() { + if (!this[_symbol_utils.$extra]) { + const parent = this[_symbol_utils.$getParent](); + const root = this[_symbol_utils.$getTemplateRoot](); + const target = root[_symbol_utils.$searchNode](this.target, parent); + const leader = root[_symbol_utils.$searchNode](this.leader, parent); + const trailer = root[_symbol_utils.$searchNode](this.trailer, parent); + this[_symbol_utils.$extra] = { + target: target?.[0] || null, + leader: leader?.[0] || null, + trailer: trailer?.[0] || null, + addLeader: false, + addTrailer: false + }; + } + return this[_symbol_utils.$extra]; + } +} +class PageArea extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "pageArea", true); + this.blankOrNotBlank = (0, _utils.getStringOption)(attributes.blankOrNotBlank, ["any", "blank", "notBlank"]); + this.id = attributes.id || ""; + this.initialNumber = (0, _utils.getInteger)({ + data: attributes.initialNumber, + defaultValue: 1, + validate: x => true + }); + this.name = attributes.name || ""; + this.numbered = (0, _utils.getInteger)({ + data: attributes.numbered, + defaultValue: 1, + validate: x => true + }); + this.oddOrEven = (0, _utils.getStringOption)(attributes.oddOrEven, ["any", "even", "odd"]); + this.pagePosition = (0, _utils.getStringOption)(attributes.pagePosition, ["any", "first", "last", "only", "rest"]); + this.relevant = (0, _utils.getRelevant)(attributes.relevant); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.desc = null; + this.extras = null; + this.medium = null; + this.occur = null; + this.area = new _xfa_object.XFAObjectArray(); + this.contentArea = new _xfa_object.XFAObjectArray(); + this.draw = new _xfa_object.XFAObjectArray(); + this.exclGroup = new _xfa_object.XFAObjectArray(); + this.field = new _xfa_object.XFAObjectArray(); + this.subform = new _xfa_object.XFAObjectArray(); + } + [_symbol_utils.$isUsable]() { + if (!this[_symbol_utils.$extra]) { + this[_symbol_utils.$extra] = { + numberOfUse: 0 + }; + return true; + } + return !this.occur || this.occur.max === -1 || this[_symbol_utils.$extra].numberOfUse < this.occur.max; + } + [_symbol_utils.$cleanPage]() { + delete this[_symbol_utils.$extra]; + } + [_symbol_utils.$getNextPage]() { + if (!this[_symbol_utils.$extra]) { + this[_symbol_utils.$extra] = { + numberOfUse: 0 + }; + } + const parent = this[_symbol_utils.$getParent](); + if (parent.relation === "orderedOccurrence") { + if (this[_symbol_utils.$isUsable]()) { + this[_symbol_utils.$extra].numberOfUse += 1; + return this; + } + } + return parent[_symbol_utils.$getNextPage](); + } + [_symbol_utils.$getAvailableSpace]() { + return this[_symbol_utils.$extra].space || { + width: 0, + height: 0 + }; + } + [_symbol_utils.$toHTML]() { + if (!this[_symbol_utils.$extra]) { + this[_symbol_utils.$extra] = { + numberOfUse: 1 + }; + } + const children = []; + this[_symbol_utils.$extra].children = children; + const style = Object.create(null); + if (this.medium && this.medium.short && this.medium.long) { + style.width = (0, _html_utils.measureToString)(this.medium.short); + style.height = (0, _html_utils.measureToString)(this.medium.long); + this[_symbol_utils.$extra].space = { + width: this.medium.short, + height: this.medium.long + }; + if (this.medium.orientation === "landscape") { + const x = style.width; + style.width = style.height; + style.height = x; + this[_symbol_utils.$extra].space = { + width: this.medium.long, + height: this.medium.short + }; + } + } else { + (0, _util.warn)("XFA - No medium specified in pageArea: please file a bug."); + } + this[_symbol_utils.$childrenToHTML]({ + filter: new Set(["area", "draw", "field", "subform"]), + include: true + }); + this[_symbol_utils.$childrenToHTML]({ + filter: new Set(["contentArea"]), + include: true + }); + return _utils.HTMLResult.success({ + name: "div", + children, + attributes: { + class: ["xfaPage"], + id: this[_symbol_utils.$uid], + style, + xfaName: this.name + } + }); + } +} +class PageSet extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "pageSet", true); + this.duplexImposition = (0, _utils.getStringOption)(attributes.duplexImposition, ["longEdge", "shortEdge"]); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.relation = (0, _utils.getStringOption)(attributes.relation, ["orderedOccurrence", "duplexPaginated", "simplexPaginated"]); + this.relevant = (0, _utils.getRelevant)(attributes.relevant); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + this.occur = null; + this.pageArea = new _xfa_object.XFAObjectArray(); + this.pageSet = new _xfa_object.XFAObjectArray(); + } + [_symbol_utils.$cleanPage]() { + for (const page of this.pageArea.children) { + page[_symbol_utils.$cleanPage](); + } + for (const page of this.pageSet.children) { + page[_symbol_utils.$cleanPage](); + } + } + [_symbol_utils.$isUsable]() { + return !this.occur || this.occur.max === -1 || this[_symbol_utils.$extra].numberOfUse < this.occur.max; + } + [_symbol_utils.$getNextPage]() { + if (!this[_symbol_utils.$extra]) { + this[_symbol_utils.$extra] = { + numberOfUse: 1, + pageIndex: -1, + pageSetIndex: -1 + }; + } + if (this.relation === "orderedOccurrence") { + if (this[_symbol_utils.$extra].pageIndex + 1 < this.pageArea.children.length) { + this[_symbol_utils.$extra].pageIndex += 1; + const pageArea = this.pageArea.children[this[_symbol_utils.$extra].pageIndex]; + return pageArea[_symbol_utils.$getNextPage](); + } + if (this[_symbol_utils.$extra].pageSetIndex + 1 < this.pageSet.children.length) { + this[_symbol_utils.$extra].pageSetIndex += 1; + return this.pageSet.children[this[_symbol_utils.$extra].pageSetIndex][_symbol_utils.$getNextPage](); + } + if (this[_symbol_utils.$isUsable]()) { + this[_symbol_utils.$extra].numberOfUse += 1; + this[_symbol_utils.$extra].pageIndex = -1; + this[_symbol_utils.$extra].pageSetIndex = -1; + return this[_symbol_utils.$getNextPage](); + } + const parent = this[_symbol_utils.$getParent](); + if (parent instanceof PageSet) { + return parent[_symbol_utils.$getNextPage](); + } + this[_symbol_utils.$cleanPage](); + return this[_symbol_utils.$getNextPage](); + } + const pageNumber = this[_symbol_utils.$getTemplateRoot]()[_symbol_utils.$extra].pageNumber; + const parity = pageNumber % 2 === 0 ? "even" : "odd"; + const position = pageNumber === 0 ? "first" : "rest"; + let page = this.pageArea.children.find(p => p.oddOrEven === parity && p.pagePosition === position); + if (page) { + return page; + } + page = this.pageArea.children.find(p => p.oddOrEven === "any" && p.pagePosition === position); + if (page) { + return page; + } + page = this.pageArea.children.find(p => p.oddOrEven === "any" && p.pagePosition === "any"); + if (page) { + return page; + } + return this.pageArea.children[0]; + } +} +class Para extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "para", true); + this.hAlign = (0, _utils.getStringOption)(attributes.hAlign, ["left", "center", "justify", "justifyAll", "radix", "right"]); + this.id = attributes.id || ""; + this.lineHeight = attributes.lineHeight ? (0, _utils.getMeasurement)(attributes.lineHeight, "0pt") : ""; + this.marginLeft = attributes.marginLeft ? (0, _utils.getMeasurement)(attributes.marginLeft, "0pt") : ""; + this.marginRight = attributes.marginRight ? (0, _utils.getMeasurement)(attributes.marginRight, "0pt") : ""; + this.orphans = (0, _utils.getInteger)({ + data: attributes.orphans, + defaultValue: 0, + validate: x => x >= 0 + }); + this.preserve = attributes.preserve || ""; + this.radixOffset = attributes.radixOffset ? (0, _utils.getMeasurement)(attributes.radixOffset, "0pt") : ""; + this.spaceAbove = attributes.spaceAbove ? (0, _utils.getMeasurement)(attributes.spaceAbove, "0pt") : ""; + this.spaceBelow = attributes.spaceBelow ? (0, _utils.getMeasurement)(attributes.spaceBelow, "0pt") : ""; + this.tabDefault = attributes.tabDefault ? (0, _utils.getMeasurement)(this.tabDefault) : ""; + this.tabStops = (attributes.tabStops || "").trim().split(/\s+/).map((x, i) => i % 2 === 1 ? (0, _utils.getMeasurement)(x) : x); + this.textIndent = attributes.textIndent ? (0, _utils.getMeasurement)(attributes.textIndent, "0pt") : ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.vAlign = (0, _utils.getStringOption)(attributes.vAlign, ["top", "bottom", "middle"]); + this.widows = (0, _utils.getInteger)({ + data: attributes.widows, + defaultValue: 0, + validate: x => x >= 0 + }); + this.hyphenation = null; + } + [_symbol_utils.$toStyle]() { + const style = (0, _html_utils.toStyle)(this, "hAlign"); + if (this.marginLeft !== "") { + style.paddingLeft = (0, _html_utils.measureToString)(this.marginLeft); + } + if (this.marginRight !== "") { + style.paddingight = (0, _html_utils.measureToString)(this.marginRight); + } + if (this.spaceAbove !== "") { + style.paddingTop = (0, _html_utils.measureToString)(this.spaceAbove); + } + if (this.spaceBelow !== "") { + style.paddingBottom = (0, _html_utils.measureToString)(this.spaceBelow); + } + if (this.textIndent !== "") { + style.textIndent = (0, _html_utils.measureToString)(this.textIndent); + (0, _html_utils.fixTextIndent)(style); + } + if (this.lineHeight > 0) { + style.lineHeight = (0, _html_utils.measureToString)(this.lineHeight); + } + if (this.tabDefault !== "") { + style.tabSize = (0, _html_utils.measureToString)(this.tabDefault); + } + if (this.tabStops.length > 0) {} + if (this.hyphenatation) { + Object.assign(style, this.hyphenatation[_symbol_utils.$toStyle]()); + } + return style; + } +} +class PasswordEdit extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "passwordEdit", true); + this.hScrollPolicy = (0, _utils.getStringOption)(attributes.hScrollPolicy, ["auto", "off", "on"]); + this.id = attributes.id || ""; + this.passwordChar = attributes.passwordChar || "*"; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.border = null; + this.extras = null; + this.margin = null; + } +} +class Pattern extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "pattern", true); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["crossHatch", "crossDiagonal", "diagonalLeft", "diagonalRight", "horizontal", "vertical"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.color = null; + this.extras = null; + } + [_symbol_utils.$toStyle](startColor) { + startColor = startColor ? startColor[_symbol_utils.$toStyle]() : "#FFFFFF"; + const endColor = this.color ? this.color[_symbol_utils.$toStyle]() : "#000000"; + const width = 5; + const cmd = "repeating-linear-gradient"; + const colors = `${startColor},${startColor} ${width}px,${endColor} ${width}px,${endColor} ${2 * width}px`; + switch (this.type) { + case "crossHatch": + return `${cmd}(to top,${colors}) ${cmd}(to right,${colors})`; + case "crossDiagonal": + return `${cmd}(45deg,${colors}) ${cmd}(-45deg,${colors})`; + case "diagonalLeft": + return `${cmd}(45deg,${colors})`; + case "diagonalRight": + return `${cmd}(-45deg,${colors})`; + case "horizontal": + return `${cmd}(to top,${colors})`; + case "vertical": + return `${cmd}(to right,${colors})`; + } + return ""; + } +} +class Picture extends _xfa_object.StringObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "picture"); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Proto extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "proto", true); + this.appearanceFilter = new _xfa_object.XFAObjectArray(); + this.arc = new _xfa_object.XFAObjectArray(); + this.area = new _xfa_object.XFAObjectArray(); + this.assist = new _xfa_object.XFAObjectArray(); + this.barcode = new _xfa_object.XFAObjectArray(); + this.bindItems = new _xfa_object.XFAObjectArray(); + this.bookend = new _xfa_object.XFAObjectArray(); + this.boolean = new _xfa_object.XFAObjectArray(); + this.border = new _xfa_object.XFAObjectArray(); + this.break = new _xfa_object.XFAObjectArray(); + this.breakAfter = new _xfa_object.XFAObjectArray(); + this.breakBefore = new _xfa_object.XFAObjectArray(); + this.button = new _xfa_object.XFAObjectArray(); + this.calculate = new _xfa_object.XFAObjectArray(); + this.caption = new _xfa_object.XFAObjectArray(); + this.certificate = new _xfa_object.XFAObjectArray(); + this.certificates = new _xfa_object.XFAObjectArray(); + this.checkButton = new _xfa_object.XFAObjectArray(); + this.choiceList = new _xfa_object.XFAObjectArray(); + this.color = new _xfa_object.XFAObjectArray(); + this.comb = new _xfa_object.XFAObjectArray(); + this.connect = new _xfa_object.XFAObjectArray(); + this.contentArea = new _xfa_object.XFAObjectArray(); + this.corner = new _xfa_object.XFAObjectArray(); + this.date = new _xfa_object.XFAObjectArray(); + this.dateTime = new _xfa_object.XFAObjectArray(); + this.dateTimeEdit = new _xfa_object.XFAObjectArray(); + this.decimal = new _xfa_object.XFAObjectArray(); + this.defaultUi = new _xfa_object.XFAObjectArray(); + this.desc = new _xfa_object.XFAObjectArray(); + this.digestMethod = new _xfa_object.XFAObjectArray(); + this.digestMethods = new _xfa_object.XFAObjectArray(); + this.draw = new _xfa_object.XFAObjectArray(); + this.edge = new _xfa_object.XFAObjectArray(); + this.encoding = new _xfa_object.XFAObjectArray(); + this.encodings = new _xfa_object.XFAObjectArray(); + this.encrypt = new _xfa_object.XFAObjectArray(); + this.encryptData = new _xfa_object.XFAObjectArray(); + this.encryption = new _xfa_object.XFAObjectArray(); + this.encryptionMethod = new _xfa_object.XFAObjectArray(); + this.encryptionMethods = new _xfa_object.XFAObjectArray(); + this.event = new _xfa_object.XFAObjectArray(); + this.exData = new _xfa_object.XFAObjectArray(); + this.exObject = new _xfa_object.XFAObjectArray(); + this.exclGroup = new _xfa_object.XFAObjectArray(); + this.execute = new _xfa_object.XFAObjectArray(); + this.extras = new _xfa_object.XFAObjectArray(); + this.field = new _xfa_object.XFAObjectArray(); + this.fill = new _xfa_object.XFAObjectArray(); + this.filter = new _xfa_object.XFAObjectArray(); + this.float = new _xfa_object.XFAObjectArray(); + this.font = new _xfa_object.XFAObjectArray(); + this.format = new _xfa_object.XFAObjectArray(); + this.handler = new _xfa_object.XFAObjectArray(); + this.hyphenation = new _xfa_object.XFAObjectArray(); + this.image = new _xfa_object.XFAObjectArray(); + this.imageEdit = new _xfa_object.XFAObjectArray(); + this.integer = new _xfa_object.XFAObjectArray(); + this.issuers = new _xfa_object.XFAObjectArray(); + this.items = new _xfa_object.XFAObjectArray(); + this.keep = new _xfa_object.XFAObjectArray(); + this.keyUsage = new _xfa_object.XFAObjectArray(); + this.line = new _xfa_object.XFAObjectArray(); + this.linear = new _xfa_object.XFAObjectArray(); + this.lockDocument = new _xfa_object.XFAObjectArray(); + this.manifest = new _xfa_object.XFAObjectArray(); + this.margin = new _xfa_object.XFAObjectArray(); + this.mdp = new _xfa_object.XFAObjectArray(); + this.medium = new _xfa_object.XFAObjectArray(); + this.message = new _xfa_object.XFAObjectArray(); + this.numericEdit = new _xfa_object.XFAObjectArray(); + this.occur = new _xfa_object.XFAObjectArray(); + this.oid = new _xfa_object.XFAObjectArray(); + this.oids = new _xfa_object.XFAObjectArray(); + this.overflow = new _xfa_object.XFAObjectArray(); + this.pageArea = new _xfa_object.XFAObjectArray(); + this.pageSet = new _xfa_object.XFAObjectArray(); + this.para = new _xfa_object.XFAObjectArray(); + this.passwordEdit = new _xfa_object.XFAObjectArray(); + this.pattern = new _xfa_object.XFAObjectArray(); + this.picture = new _xfa_object.XFAObjectArray(); + this.radial = new _xfa_object.XFAObjectArray(); + this.reason = new _xfa_object.XFAObjectArray(); + this.reasons = new _xfa_object.XFAObjectArray(); + this.rectangle = new _xfa_object.XFAObjectArray(); + this.ref = new _xfa_object.XFAObjectArray(); + this.script = new _xfa_object.XFAObjectArray(); + this.setProperty = new _xfa_object.XFAObjectArray(); + this.signData = new _xfa_object.XFAObjectArray(); + this.signature = new _xfa_object.XFAObjectArray(); + this.signing = new _xfa_object.XFAObjectArray(); + this.solid = new _xfa_object.XFAObjectArray(); + this.speak = new _xfa_object.XFAObjectArray(); + this.stipple = new _xfa_object.XFAObjectArray(); + this.subform = new _xfa_object.XFAObjectArray(); + this.subformSet = new _xfa_object.XFAObjectArray(); + this.subjectDN = new _xfa_object.XFAObjectArray(); + this.subjectDNs = new _xfa_object.XFAObjectArray(); + this.submit = new _xfa_object.XFAObjectArray(); + this.text = new _xfa_object.XFAObjectArray(); + this.textEdit = new _xfa_object.XFAObjectArray(); + this.time = new _xfa_object.XFAObjectArray(); + this.timeStamp = new _xfa_object.XFAObjectArray(); + this.toolTip = new _xfa_object.XFAObjectArray(); + this.traversal = new _xfa_object.XFAObjectArray(); + this.traverse = new _xfa_object.XFAObjectArray(); + this.ui = new _xfa_object.XFAObjectArray(); + this.validate = new _xfa_object.XFAObjectArray(); + this.value = new _xfa_object.XFAObjectArray(); + this.variables = new _xfa_object.XFAObjectArray(); + } +} +class Radial extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "radial", true); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["toEdge", "toCenter"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.color = null; + this.extras = null; + } + [_symbol_utils.$toStyle](startColor) { + startColor = startColor ? startColor[_symbol_utils.$toStyle]() : "#FFFFFF"; + const endColor = this.color ? this.color[_symbol_utils.$toStyle]() : "#000000"; + const colors = this.type === "toEdge" ? `${startColor},${endColor}` : `${endColor},${startColor}`; + return `radial-gradient(circle at center, ${colors})`; + } +} +class Reason extends _xfa_object.StringObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "reason"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Reasons extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "reasons", true); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.reason = new _xfa_object.XFAObjectArray(); + } +} +class Rectangle extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "rectangle", true); + this.hand = (0, _utils.getStringOption)(attributes.hand, ["even", "left", "right"]); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.corner = new _xfa_object.XFAObjectArray(4); + this.edge = new _xfa_object.XFAObjectArray(4); + this.fill = null; + } + [_symbol_utils.$toHTML]() { + const edge = this.edge.children.length ? this.edge.children[0] : new Edge({}); + const edgeStyle = edge[_symbol_utils.$toStyle](); + const style = Object.create(null); + if (this.fill?.presence === "visible") { + Object.assign(style, this.fill[_symbol_utils.$toStyle]()); + } else { + style.fill = "transparent"; + } + style.strokeWidth = (0, _html_utils.measureToString)(edge.presence === "visible" ? edge.thickness : 0); + style.stroke = edgeStyle.color; + const corner = this.corner.children.length ? this.corner.children[0] : new Corner({}); + const cornerStyle = corner[_symbol_utils.$toStyle](); + const rect = { + name: "rect", + attributes: { + xmlns: SVG_NS, + width: "100%", + height: "100%", + x: 0, + y: 0, + rx: cornerStyle.radius, + ry: cornerStyle.radius, + style + } + }; + const svg = { + name: "svg", + children: [rect], + attributes: { + xmlns: SVG_NS, + style: { + overflow: "visible" + }, + width: "100%", + height: "100%" + } + }; + const parent = this[_symbol_utils.$getParent]()[_symbol_utils.$getParent](); + if (hasMargin(parent)) { + return _utils.HTMLResult.success({ + name: "div", + attributes: { + style: { + display: "inline", + width: "100%", + height: "100%" + } + }, + children: [svg] + }); + } + svg.attributes.style.position = "absolute"; + return _utils.HTMLResult.success(svg); + } +} +class RefElement extends _xfa_object.StringObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "ref"); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Script extends _xfa_object.StringObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "script"); + this.binding = attributes.binding || ""; + this.contentType = attributes.contentType || ""; + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.runAt = (0, _utils.getStringOption)(attributes.runAt, ["client", "both", "server"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class SetProperty extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "setProperty"); + this.connection = attributes.connection || ""; + this.ref = attributes.ref || ""; + this.target = attributes.target || ""; + } +} +exports.SetProperty = SetProperty; +class SignData extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "signData", true); + this.id = attributes.id || ""; + this.operation = (0, _utils.getStringOption)(attributes.operation, ["sign", "clear", "verify"]); + this.ref = attributes.ref || ""; + this.target = attributes.target || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.filter = null; + this.manifest = null; + } +} +class Signature extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "signature", true); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["PDF1.3", "PDF1.6"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.border = null; + this.extras = null; + this.filter = null; + this.manifest = null; + this.margin = null; + } +} +class Signing extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "signing", true); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.certificate = new _xfa_object.XFAObjectArray(); + } +} +class Solid extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "solid", true); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + } + [_symbol_utils.$toStyle](startColor) { + return startColor ? startColor[_symbol_utils.$toStyle]() : "#FFFFFF"; + } +} +class Speak extends _xfa_object.StringObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "speak"); + this.disable = (0, _utils.getInteger)({ + data: attributes.disable, + defaultValue: 0, + validate: x => x === 1 + }); + this.id = attributes.id || ""; + this.priority = (0, _utils.getStringOption)(attributes.priority, ["custom", "caption", "name", "toolTip"]); + this.rid = attributes.rid || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Stipple extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "stipple", true); + this.id = attributes.id || ""; + this.rate = (0, _utils.getInteger)({ + data: attributes.rate, + defaultValue: 50, + validate: x => x >= 0 && x <= 100 + }); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.color = null; + this.extras = null; + } + [_symbol_utils.$toStyle](bgColor) { + const alpha = this.rate / 100; + return _util.Util.makeHexColor(Math.round(bgColor.value.r * (1 - alpha) + this.value.r * alpha), Math.round(bgColor.value.g * (1 - alpha) + this.value.g * alpha), Math.round(bgColor.value.b * (1 - alpha) + this.value.b * alpha)); + } +} +class Subform extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "subform", true); + this.access = (0, _utils.getStringOption)(attributes.access, ["open", "nonInteractive", "protected", "readOnly"]); + this.allowMacro = (0, _utils.getInteger)({ + data: attributes.allowMacro, + defaultValue: 0, + validate: x => x === 1 + }); + this.anchorType = (0, _utils.getStringOption)(attributes.anchorType, ["topLeft", "bottomCenter", "bottomLeft", "bottomRight", "middleCenter", "middleLeft", "middleRight", "topCenter", "topRight"]); + this.colSpan = (0, _utils.getInteger)({ + data: attributes.colSpan, + defaultValue: 1, + validate: n => n >= 1 || n === -1 + }); + this.columnWidths = (attributes.columnWidths || "").trim().split(/\s+/).map(x => x === "-1" ? -1 : (0, _utils.getMeasurement)(x)); + this.h = attributes.h ? (0, _utils.getMeasurement)(attributes.h) : ""; + this.hAlign = (0, _utils.getStringOption)(attributes.hAlign, ["left", "center", "justify", "justifyAll", "radix", "right"]); + this.id = attributes.id || ""; + this.layout = (0, _utils.getStringOption)(attributes.layout, ["position", "lr-tb", "rl-row", "rl-tb", "row", "table", "tb"]); + this.locale = attributes.locale || ""; + this.maxH = (0, _utils.getMeasurement)(attributes.maxH, "0pt"); + this.maxW = (0, _utils.getMeasurement)(attributes.maxW, "0pt"); + this.mergeMode = (0, _utils.getStringOption)(attributes.mergeMode, ["consumeData", "matchTemplate"]); + this.minH = (0, _utils.getMeasurement)(attributes.minH, "0pt"); + this.minW = (0, _utils.getMeasurement)(attributes.minW, "0pt"); + this.name = attributes.name || ""; + this.presence = (0, _utils.getStringOption)(attributes.presence, ["visible", "hidden", "inactive", "invisible"]); + this.relevant = (0, _utils.getRelevant)(attributes.relevant); + this.restoreState = (0, _utils.getStringOption)(attributes.restoreState, ["manual", "auto"]); + this.scope = (0, _utils.getStringOption)(attributes.scope, ["name", "none"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.w = attributes.w ? (0, _utils.getMeasurement)(attributes.w) : ""; + this.x = (0, _utils.getMeasurement)(attributes.x, "0pt"); + this.y = (0, _utils.getMeasurement)(attributes.y, "0pt"); + this.assist = null; + this.bind = null; + this.bookend = null; + this.border = null; + this.break = null; + this.calculate = null; + this.desc = null; + this.extras = null; + this.keep = null; + this.margin = null; + this.occur = null; + this.overflow = null; + this.pageSet = null; + this.para = null; + this.traversal = null; + this.validate = null; + this.variables = null; + this.area = new _xfa_object.XFAObjectArray(); + this.breakAfter = new _xfa_object.XFAObjectArray(); + this.breakBefore = new _xfa_object.XFAObjectArray(); + this.connect = new _xfa_object.XFAObjectArray(); + this.draw = new _xfa_object.XFAObjectArray(); + this.event = new _xfa_object.XFAObjectArray(); + this.exObject = new _xfa_object.XFAObjectArray(); + this.exclGroup = new _xfa_object.XFAObjectArray(); + this.field = new _xfa_object.XFAObjectArray(); + this.proto = new _xfa_object.XFAObjectArray(); + this.setProperty = new _xfa_object.XFAObjectArray(); + this.subform = new _xfa_object.XFAObjectArray(); + this.subformSet = new _xfa_object.XFAObjectArray(); + } + [_symbol_utils.$getSubformParent]() { + const parent = this[_symbol_utils.$getParent](); + if (parent instanceof SubformSet) { + return parent[_symbol_utils.$getSubformParent](); + } + return parent; + } + [_symbol_utils.$isBindable]() { + return true; + } + [_symbol_utils.$isThereMoreWidth]() { + return this.layout.endsWith("-tb") && this[_symbol_utils.$extra].attempt === 0 && this[_symbol_utils.$extra].numberInLine > 0 || this[_symbol_utils.$getParent]()[_symbol_utils.$isThereMoreWidth](); + } + *[_symbol_utils.$getContainedChildren]() { + yield* getContainedChildren(this); + } + [_symbol_utils.$flushHTML]() { + return (0, _layout.flushHTML)(this); + } + [_symbol_utils.$addHTML](html, bbox) { + (0, _layout.addHTML)(this, html, bbox); + } + [_symbol_utils.$getAvailableSpace]() { + return (0, _layout.getAvailableSpace)(this); + } + [_symbol_utils.$isSplittable]() { + const parent = this[_symbol_utils.$getSubformParent](); + if (!parent[_symbol_utils.$isSplittable]()) { + return false; + } + if (this[_symbol_utils.$extra]._isSplittable !== undefined) { + return this[_symbol_utils.$extra]._isSplittable; + } + if (this.layout === "position" || this.layout.includes("row")) { + this[_symbol_utils.$extra]._isSplittable = false; + return false; + } + if (this.keep && this.keep.intact !== "none") { + this[_symbol_utils.$extra]._isSplittable = false; + return false; + } + if (parent.layout?.endsWith("-tb") && parent[_symbol_utils.$extra].numberInLine !== 0) { + return false; + } + this[_symbol_utils.$extra]._isSplittable = true; + return true; + } + [_symbol_utils.$toHTML](availableSpace) { + setTabIndex(this); + if (this.break) { + if (this.break.after !== "auto" || this.break.afterTarget !== "") { + const node = new BreakAfter({ + targetType: this.break.after, + target: this.break.afterTarget, + startNew: this.break.startNew.toString() + }); + node[_symbol_utils.$globalData] = this[_symbol_utils.$globalData]; + this[_symbol_utils.$appendChild](node); + this.breakAfter.push(node); + } + if (this.break.before !== "auto" || this.break.beforeTarget !== "") { + const node = new BreakBefore({ + targetType: this.break.before, + target: this.break.beforeTarget, + startNew: this.break.startNew.toString() + }); + node[_symbol_utils.$globalData] = this[_symbol_utils.$globalData]; + this[_symbol_utils.$appendChild](node); + this.breakBefore.push(node); + } + if (this.break.overflowTarget !== "") { + const node = new Overflow({ + target: this.break.overflowTarget, + leader: this.break.overflowLeader, + trailer: this.break.overflowTrailer + }); + node[_symbol_utils.$globalData] = this[_symbol_utils.$globalData]; + this[_symbol_utils.$appendChild](node); + this.overflow.push(node); + } + this[_symbol_utils.$removeChild](this.break); + this.break = null; + } + if (this.presence === "hidden" || this.presence === "inactive") { + return _utils.HTMLResult.EMPTY; + } + if (this.breakBefore.children.length > 1 || this.breakAfter.children.length > 1) { + (0, _util.warn)("XFA - Several breakBefore or breakAfter in subforms: please file a bug."); + } + if (this.breakBefore.children.length >= 1) { + const breakBefore = this.breakBefore.children[0]; + if (handleBreak(breakBefore)) { + return _utils.HTMLResult.breakNode(breakBefore); + } + } + if (this[_symbol_utils.$extra]?.afterBreakAfter) { + return _utils.HTMLResult.EMPTY; + } + (0, _html_utils.fixDimensions)(this); + const children = []; + const attributes = { + id: this[_symbol_utils.$uid], + class: [] + }; + (0, _html_utils.setAccess)(this, attributes.class); + if (!this[_symbol_utils.$extra]) { + this[_symbol_utils.$extra] = Object.create(null); + } + Object.assign(this[_symbol_utils.$extra], { + children, + line: null, + attributes, + attempt: 0, + numberInLine: 0, + availableSpace: { + width: Math.min(this.w || Infinity, availableSpace.width), + height: Math.min(this.h || Infinity, availableSpace.height) + }, + width: 0, + height: 0, + prevHeight: 0, + currentWidth: 0 + }); + const root = this[_symbol_utils.$getTemplateRoot](); + const savedNoLayoutFailure = root[_symbol_utils.$extra].noLayoutFailure; + const isSplittable = this[_symbol_utils.$isSplittable](); + if (!isSplittable) { + setFirstUnsplittable(this); + } + if (!(0, _layout.checkDimensions)(this, availableSpace)) { + return _utils.HTMLResult.FAILURE; + } + const filter = new Set(["area", "draw", "exclGroup", "field", "subform", "subformSet"]); + if (this.layout.includes("row")) { + const columnWidths = this[_symbol_utils.$getSubformParent]().columnWidths; + if (Array.isArray(columnWidths) && columnWidths.length > 0) { + this[_symbol_utils.$extra].columnWidths = columnWidths; + this[_symbol_utils.$extra].currentColumn = 0; + } + } + const style = (0, _html_utils.toStyle)(this, "anchorType", "dimensions", "position", "presence", "border", "margin", "hAlign"); + const classNames = ["xfaSubform"]; + const cl = (0, _html_utils.layoutClass)(this); + if (cl) { + classNames.push(cl); + } + attributes.style = style; + attributes.class = classNames; + if (this.name) { + attributes.xfaName = this.name; + } + if (this.overflow) { + const overflowExtra = this.overflow[_symbol_utils.$getExtra](); + if (overflowExtra.addLeader) { + overflowExtra.addLeader = false; + handleOverflow(this, overflowExtra.leader, availableSpace); + } + } + this[_symbol_utils.$pushPara](); + const isLrTb = this.layout === "lr-tb" || this.layout === "rl-tb"; + const maxRun = isLrTb ? MAX_ATTEMPTS_FOR_LRTB_LAYOUT : 1; + for (; this[_symbol_utils.$extra].attempt < maxRun; this[_symbol_utils.$extra].attempt++) { + if (isLrTb && this[_symbol_utils.$extra].attempt === MAX_ATTEMPTS_FOR_LRTB_LAYOUT - 1) { + this[_symbol_utils.$extra].numberInLine = 0; + } + const result = this[_symbol_utils.$childrenToHTML]({ + filter, + include: true + }); + if (result.success) { + break; + } + if (result.isBreak()) { + this[_symbol_utils.$popPara](); + return result; + } + if (isLrTb && this[_symbol_utils.$extra].attempt === 0 && this[_symbol_utils.$extra].numberInLine === 0 && !root[_symbol_utils.$extra].noLayoutFailure) { + this[_symbol_utils.$extra].attempt = maxRun; + break; + } + } + this[_symbol_utils.$popPara](); + if (!isSplittable) { + unsetFirstUnsplittable(this); + } + root[_symbol_utils.$extra].noLayoutFailure = savedNoLayoutFailure; + if (this[_symbol_utils.$extra].attempt === maxRun) { + if (this.overflow) { + this[_symbol_utils.$getTemplateRoot]()[_symbol_utils.$extra].overflowNode = this.overflow; + } + if (!isSplittable) { + delete this[_symbol_utils.$extra]; + } + return _utils.HTMLResult.FAILURE; + } + if (this.overflow) { + const overflowExtra = this.overflow[_symbol_utils.$getExtra](); + if (overflowExtra.addTrailer) { + overflowExtra.addTrailer = false; + handleOverflow(this, overflowExtra.trailer, availableSpace); + } + } + let marginH = 0; + let marginV = 0; + if (this.margin) { + marginH = this.margin.leftInset + this.margin.rightInset; + marginV = this.margin.topInset + this.margin.bottomInset; + } + const width = Math.max(this[_symbol_utils.$extra].width + marginH, this.w || 0); + const height = Math.max(this[_symbol_utils.$extra].height + marginV, this.h || 0); + const bbox = [this.x, this.y, width, height]; + if (this.w === "") { + style.width = (0, _html_utils.measureToString)(width); + } + if (this.h === "") { + style.height = (0, _html_utils.measureToString)(height); + } + if ((style.width === "0px" || style.height === "0px") && children.length === 0) { + return _utils.HTMLResult.EMPTY; + } + const html = { + name: "div", + attributes, + children + }; + applyAssist(this, attributes); + const result = _utils.HTMLResult.success((0, _html_utils.createWrapper)(this, html), bbox); + if (this.breakAfter.children.length >= 1) { + const breakAfter = this.breakAfter.children[0]; + if (handleBreak(breakAfter)) { + this[_symbol_utils.$extra].afterBreakAfter = result; + return _utils.HTMLResult.breakNode(breakAfter); + } + } + delete this[_symbol_utils.$extra]; + return result; + } +} +class SubformSet extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "subformSet", true); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.relation = (0, _utils.getStringOption)(attributes.relation, ["ordered", "choice", "unordered"]); + this.relevant = (0, _utils.getRelevant)(attributes.relevant); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.bookend = null; + this.break = null; + this.desc = null; + this.extras = null; + this.occur = null; + this.overflow = null; + this.breakAfter = new _xfa_object.XFAObjectArray(); + this.breakBefore = new _xfa_object.XFAObjectArray(); + this.subform = new _xfa_object.XFAObjectArray(); + this.subformSet = new _xfa_object.XFAObjectArray(); + } + *[_symbol_utils.$getContainedChildren]() { + yield* getContainedChildren(this); + } + [_symbol_utils.$getSubformParent]() { + let parent = this[_symbol_utils.$getParent](); + while (!(parent instanceof Subform)) { + parent = parent[_symbol_utils.$getParent](); + } + return parent; + } + [_symbol_utils.$isBindable]() { + return true; + } +} +class SubjectDN extends _xfa_object.ContentObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "subjectDN"); + this.delimiter = attributes.delimiter || ","; + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } + [_symbol_utils.$finalize]() { + this[_symbol_utils.$content] = new Map(this[_symbol_utils.$content].split(this.delimiter).map(kv => { + kv = kv.split("=", 2); + kv[0] = kv[0].trim(); + return kv; + })); + } +} +class SubjectDNs extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "subjectDNs", true); + this.id = attributes.id || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.subjectDN = new _xfa_object.XFAObjectArray(); + } +} +class Submit extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "submit", true); + this.embedPDF = (0, _utils.getInteger)({ + data: attributes.embedPDF, + defaultValue: 0, + validate: x => x === 1 + }); + this.format = (0, _utils.getStringOption)(attributes.format, ["xdp", "formdata", "pdf", "urlencoded", "xfd", "xml"]); + this.id = attributes.id || ""; + this.target = attributes.target || ""; + this.textEncoding = (0, _utils.getKeyword)({ + data: attributes.textEncoding ? attributes.textEncoding.toLowerCase() : "", + defaultValue: "", + validate: k => ["utf-8", "big-five", "fontspecific", "gbk", "gb-18030", "gb-2312", "ksc-5601", "none", "shift-jis", "ucs-2", "utf-16"].includes(k) || k.match(/iso-8859-\d{2}/) + }); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.xdpContent = attributes.xdpContent || ""; + this.encrypt = null; + this.encryptData = new _xfa_object.XFAObjectArray(); + this.signData = new _xfa_object.XFAObjectArray(); + } +} +class Template extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "template", true); + this.baseProfile = (0, _utils.getStringOption)(attributes.baseProfile, ["full", "interactiveForms"]); + this.extras = null; + this.subform = new _xfa_object.XFAObjectArray(); + } + [_symbol_utils.$finalize]() { + if (this.subform.children.length === 0) { + (0, _util.warn)("XFA - No subforms in template node."); + } + if (this.subform.children.length >= 2) { + (0, _util.warn)("XFA - Several subforms in template node: please file a bug."); + } + this[_symbol_utils.$tabIndex] = DEFAULT_TAB_INDEX; + } + [_symbol_utils.$isSplittable]() { + return true; + } + [_symbol_utils.$searchNode](expr, container) { + if (expr.startsWith("#")) { + return [this[_symbol_utils.$ids].get(expr.slice(1))]; + } + return (0, _som.searchNode)(this, container, expr, true, true); + } + *[_symbol_utils.$toPages]() { + if (!this.subform.children.length) { + return _utils.HTMLResult.success({ + name: "div", + children: [] + }); + } + this[_symbol_utils.$extra] = { + overflowNode: null, + firstUnsplittable: null, + currentContentArea: null, + currentPageArea: null, + noLayoutFailure: false, + pageNumber: 1, + pagePosition: "first", + oddOrEven: "odd", + blankOrNotBlank: "nonBlank", + paraStack: [] + }; + const root = this.subform.children[0]; + root.pageSet[_symbol_utils.$cleanPage](); + const pageAreas = root.pageSet.pageArea.children; + const mainHtml = { + name: "div", + children: [] + }; + let pageArea = null; + let breakBefore = null; + let breakBeforeTarget = null; + if (root.breakBefore.children.length >= 1) { + breakBefore = root.breakBefore.children[0]; + breakBeforeTarget = breakBefore.target; + } else if (root.subform.children.length >= 1 && root.subform.children[0].breakBefore.children.length >= 1) { + breakBefore = root.subform.children[0].breakBefore.children[0]; + breakBeforeTarget = breakBefore.target; + } else if (root.break?.beforeTarget) { + breakBefore = root.break; + breakBeforeTarget = breakBefore.beforeTarget; + } else if (root.subform.children.length >= 1 && root.subform.children[0].break?.beforeTarget) { + breakBefore = root.subform.children[0].break; + breakBeforeTarget = breakBefore.beforeTarget; + } + if (breakBefore) { + const target = this[_symbol_utils.$searchNode](breakBeforeTarget, breakBefore[_symbol_utils.$getParent]()); + if (target instanceof PageArea) { + pageArea = target; + breakBefore[_symbol_utils.$extra] = {}; + } + } + if (!pageArea) { + pageArea = pageAreas[0]; + } + pageArea[_symbol_utils.$extra] = { + numberOfUse: 1 + }; + const pageAreaParent = pageArea[_symbol_utils.$getParent](); + pageAreaParent[_symbol_utils.$extra] = { + numberOfUse: 1, + pageIndex: pageAreaParent.pageArea.children.indexOf(pageArea), + pageSetIndex: 0 + }; + let targetPageArea; + let leader = null; + let trailer = null; + let hasSomething = true; + let hasSomethingCounter = 0; + let startIndex = 0; + while (true) { + if (!hasSomething) { + mainHtml.children.pop(); + if (++hasSomethingCounter === MAX_EMPTY_PAGES) { + (0, _util.warn)("XFA - Something goes wrong: please file a bug."); + return mainHtml; + } + } else { + hasSomethingCounter = 0; + } + targetPageArea = null; + this[_symbol_utils.$extra].currentPageArea = pageArea; + const page = pageArea[_symbol_utils.$toHTML]().html; + mainHtml.children.push(page); + if (leader) { + this[_symbol_utils.$extra].noLayoutFailure = true; + page.children.push(leader[_symbol_utils.$toHTML](pageArea[_symbol_utils.$extra].space).html); + leader = null; + } + if (trailer) { + this[_symbol_utils.$extra].noLayoutFailure = true; + page.children.push(trailer[_symbol_utils.$toHTML](pageArea[_symbol_utils.$extra].space).html); + trailer = null; + } + const contentAreas = pageArea.contentArea.children; + const htmlContentAreas = page.children.filter(node => node.attributes.class.includes("xfaContentarea")); + hasSomething = false; + this[_symbol_utils.$extra].firstUnsplittable = null; + this[_symbol_utils.$extra].noLayoutFailure = false; + const flush = index => { + const html = root[_symbol_utils.$flushHTML](); + if (html) { + hasSomething ||= html.children?.length > 0; + htmlContentAreas[index].children.push(html); + } + }; + for (let i = startIndex, ii = contentAreas.length; i < ii; i++) { + const contentArea = this[_symbol_utils.$extra].currentContentArea = contentAreas[i]; + const space = { + width: contentArea.w, + height: contentArea.h + }; + startIndex = 0; + if (leader) { + htmlContentAreas[i].children.push(leader[_symbol_utils.$toHTML](space).html); + leader = null; + } + if (trailer) { + htmlContentAreas[i].children.push(trailer[_symbol_utils.$toHTML](space).html); + trailer = null; + } + const html = root[_symbol_utils.$toHTML](space); + if (html.success) { + if (html.html) { + hasSomething ||= html.html.children?.length > 0; + htmlContentAreas[i].children.push(html.html); + } else if (!hasSomething && mainHtml.children.length > 1) { + mainHtml.children.pop(); + } + return mainHtml; + } + if (html.isBreak()) { + const node = html.breakNode; + flush(i); + if (node.targetType === "auto") { + continue; + } + if (node.leader) { + leader = this[_symbol_utils.$searchNode](node.leader, node[_symbol_utils.$getParent]()); + leader = leader ? leader[0] : null; + } + if (node.trailer) { + trailer = this[_symbol_utils.$searchNode](node.trailer, node[_symbol_utils.$getParent]()); + trailer = trailer ? trailer[0] : null; + } + if (node.targetType === "pageArea") { + targetPageArea = node[_symbol_utils.$extra].target; + i = Infinity; + } else if (!node[_symbol_utils.$extra].target) { + i = node[_symbol_utils.$extra].index; + } else { + targetPageArea = node[_symbol_utils.$extra].target; + startIndex = node[_symbol_utils.$extra].index + 1; + i = Infinity; + } + continue; + } + if (this[_symbol_utils.$extra].overflowNode) { + const node = this[_symbol_utils.$extra].overflowNode; + this[_symbol_utils.$extra].overflowNode = null; + const overflowExtra = node[_symbol_utils.$getExtra](); + const target = overflowExtra.target; + overflowExtra.addLeader = overflowExtra.leader !== null; + overflowExtra.addTrailer = overflowExtra.trailer !== null; + flush(i); + const currentIndex = i; + i = Infinity; + if (target instanceof PageArea) { + targetPageArea = target; + } else if (target instanceof ContentArea) { + const index = contentAreas.indexOf(target); + if (index !== -1) { + if (index > currentIndex) { + i = index - 1; + } else { + startIndex = index; + } + } else { + targetPageArea = target[_symbol_utils.$getParent](); + startIndex = targetPageArea.contentArea.children.indexOf(target); + } + } + continue; + } + flush(i); + } + this[_symbol_utils.$extra].pageNumber += 1; + if (targetPageArea) { + if (targetPageArea[_symbol_utils.$isUsable]()) { + targetPageArea[_symbol_utils.$extra].numberOfUse += 1; + } else { + targetPageArea = null; + } + } + pageArea = targetPageArea || pageArea[_symbol_utils.$getNextPage](); + yield null; + } + } +} +exports.Template = Template; +class Text extends _xfa_object.ContentObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "text"); + this.id = attributes.id || ""; + this.maxChars = (0, _utils.getInteger)({ + data: attributes.maxChars, + defaultValue: 0, + validate: x => x >= 0 + }); + this.name = attributes.name || ""; + this.rid = attributes.rid || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } + [_symbol_utils.$acceptWhitespace]() { + return true; + } + [_symbol_utils.$onChild](child) { + if (child[_symbol_utils.$namespaceId] === _namespaces.NamespaceIds.xhtml.id) { + this[_symbol_utils.$content] = child; + return true; + } + (0, _util.warn)(`XFA - Invalid content in Text: ${child[_symbol_utils.$nodeName]}.`); + return false; + } + [_symbol_utils.$onText](str) { + if (this[_symbol_utils.$content] instanceof _xfa_object.XFAObject) { + return; + } + super[_symbol_utils.$onText](str); + } + [_symbol_utils.$finalize]() { + if (typeof this[_symbol_utils.$content] === "string") { + this[_symbol_utils.$content] = this[_symbol_utils.$content].replaceAll("\r\n", "\n"); + } + } + [_symbol_utils.$getExtra]() { + if (typeof this[_symbol_utils.$content] === "string") { + return this[_symbol_utils.$content].split(/[\u2029\u2028\n]/).reduce((acc, line) => { + if (line) { + acc.push(line); + } + return acc; + }, []).join("\n"); + } + return this[_symbol_utils.$content][_symbol_utils.$text](); + } + [_symbol_utils.$toHTML](availableSpace) { + if (typeof this[_symbol_utils.$content] === "string") { + const html = valueToHtml(this[_symbol_utils.$content]).html; + if (this[_symbol_utils.$content].includes("\u2029")) { + html.name = "div"; + html.children = []; + this[_symbol_utils.$content].split("\u2029").map(para => para.split(/[\u2028\n]/).reduce((acc, line) => { + acc.push({ + name: "span", + value: line + }, { + name: "br" + }); + return acc; + }, [])).forEach(lines => { + html.children.push({ + name: "p", + children: lines + }); + }); + } else if (/[\u2028\n]/.test(this[_symbol_utils.$content])) { + html.name = "div"; + html.children = []; + this[_symbol_utils.$content].split(/[\u2028\n]/).forEach(line => { + html.children.push({ + name: "span", + value: line + }, { + name: "br" + }); + }); + } + return _utils.HTMLResult.success(html); + } + return this[_symbol_utils.$content][_symbol_utils.$toHTML](availableSpace); + } +} +exports.Text = Text; +class TextEdit extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "textEdit", true); + this.allowRichText = (0, _utils.getInteger)({ + data: attributes.allowRichText, + defaultValue: 0, + validate: x => x === 1 + }); + this.hScrollPolicy = (0, _utils.getStringOption)(attributes.hScrollPolicy, ["auto", "off", "on"]); + this.id = attributes.id || ""; + this.multiLine = (0, _utils.getInteger)({ + data: attributes.multiLine, + defaultValue: "", + validate: x => x === 0 || x === 1 + }); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.vScrollPolicy = (0, _utils.getStringOption)(attributes.vScrollPolicy, ["auto", "off", "on"]); + this.border = null; + this.comb = null; + this.extras = null; + this.margin = null; + } + [_symbol_utils.$toHTML](availableSpace) { + const style = (0, _html_utils.toStyle)(this, "border", "font", "margin"); + let html; + const field = this[_symbol_utils.$getParent]()[_symbol_utils.$getParent](); + if (this.multiLine === "") { + this.multiLine = field instanceof Draw ? 1 : 0; + } + if (this.multiLine === 1) { + html = { + name: "textarea", + attributes: { + dataId: field[_symbol_utils.$data]?.[_symbol_utils.$uid] || field[_symbol_utils.$uid], + fieldId: field[_symbol_utils.$uid], + class: ["xfaTextfield"], + style, + "aria-label": ariaLabel(field), + "aria-required": false + } + }; + } else { + html = { + name: "input", + attributes: { + type: "text", + dataId: field[_symbol_utils.$data]?.[_symbol_utils.$uid] || field[_symbol_utils.$uid], + fieldId: field[_symbol_utils.$uid], + class: ["xfaTextfield"], + style, + "aria-label": ariaLabel(field), + "aria-required": false + } + }; + } + if (isRequired(field)) { + html.attributes["aria-required"] = true; + html.attributes.required = true; + } + return _utils.HTMLResult.success({ + name: "label", + attributes: { + class: ["xfaLabel"] + }, + children: [html] + }); + } +} +class Time extends _xfa_object.StringObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "time"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } + [_symbol_utils.$finalize]() { + const date = this[_symbol_utils.$content].trim(); + this[_symbol_utils.$content] = date ? new Date(date) : null; + } + [_symbol_utils.$toHTML](availableSpace) { + return valueToHtml(this[_symbol_utils.$content] ? this[_symbol_utils.$content].toString() : ""); + } +} +class TimeStamp extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "timeStamp"); + this.id = attributes.id || ""; + this.server = attributes.server || ""; + this.type = (0, _utils.getStringOption)(attributes.type, ["optional", "required"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class ToolTip extends _xfa_object.StringObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "toolTip"); + this.id = attributes.id || ""; + this.rid = attributes.rid || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Traversal extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "traversal", true); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + this.traverse = new _xfa_object.XFAObjectArray(); + } +} +class Traverse extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "traverse", true); + this.id = attributes.id || ""; + this.operation = (0, _utils.getStringOption)(attributes.operation, ["next", "back", "down", "first", "left", "right", "up"]); + this.ref = attributes.ref || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + this.script = null; + } + get name() { + return this.operation; + } + [_symbol_utils.$isTransparent]() { + return false; + } +} +class Ui extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "ui", true); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + this.picture = null; + this.barcode = null; + this.button = null; + this.checkButton = null; + this.choiceList = null; + this.dateTimeEdit = null; + this.defaultUi = null; + this.imageEdit = null; + this.numericEdit = null; + this.passwordEdit = null; + this.signature = null; + this.textEdit = null; + } + [_symbol_utils.$getExtra]() { + if (this[_symbol_utils.$extra] === undefined) { + for (const name of Object.getOwnPropertyNames(this)) { + if (name === "extras" || name === "picture") { + continue; + } + const obj = this[name]; + if (!(obj instanceof _xfa_object.XFAObject)) { + continue; + } + this[_symbol_utils.$extra] = obj; + return obj; + } + this[_symbol_utils.$extra] = null; + } + return this[_symbol_utils.$extra]; + } + [_symbol_utils.$toHTML](availableSpace) { + const obj = this[_symbol_utils.$getExtra](); + if (obj) { + return obj[_symbol_utils.$toHTML](availableSpace); + } + return _utils.HTMLResult.EMPTY; + } +} +class Validate extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "validate", true); + this.formatTest = (0, _utils.getStringOption)(attributes.formatTest, ["warning", "disabled", "error"]); + this.id = attributes.id || ""; + this.nullTest = (0, _utils.getStringOption)(attributes.nullTest, ["disabled", "error", "warning"]); + this.scriptTest = (0, _utils.getStringOption)(attributes.scriptTest, ["error", "disabled", "warning"]); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.extras = null; + this.message = null; + this.picture = null; + this.script = null; + } +} +class Value extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "value", true); + this.id = attributes.id || ""; + this.override = (0, _utils.getInteger)({ + data: attributes.override, + defaultValue: 0, + validate: x => x === 1 + }); + this.relevant = (0, _utils.getRelevant)(attributes.relevant); + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.arc = null; + this.boolean = null; + this.date = null; + this.dateTime = null; + this.decimal = null; + this.exData = null; + this.float = null; + this.image = null; + this.integer = null; + this.line = null; + this.rectangle = null; + this.text = null; + this.time = null; + } + [_symbol_utils.$setValue](value) { + const parent = this[_symbol_utils.$getParent](); + if (parent instanceof Field) { + if (parent.ui?.imageEdit) { + if (!this.image) { + this.image = new Image({}); + this[_symbol_utils.$appendChild](this.image); + } + this.image[_symbol_utils.$content] = value[_symbol_utils.$content]; + return; + } + } + const valueName = value[_symbol_utils.$nodeName]; + if (this[valueName] !== null) { + this[valueName][_symbol_utils.$content] = value[_symbol_utils.$content]; + return; + } + for (const name of Object.getOwnPropertyNames(this)) { + const obj = this[name]; + if (obj instanceof _xfa_object.XFAObject) { + this[name] = null; + this[_symbol_utils.$removeChild](obj); + } + } + this[value[_symbol_utils.$nodeName]] = value; + this[_symbol_utils.$appendChild](value); + } + [_symbol_utils.$text]() { + if (this.exData) { + if (typeof this.exData[_symbol_utils.$content] === "string") { + return this.exData[_symbol_utils.$content].trim(); + } + return this.exData[_symbol_utils.$content][_symbol_utils.$text]().trim(); + } + for (const name of Object.getOwnPropertyNames(this)) { + if (name === "image") { + continue; + } + const obj = this[name]; + if (obj instanceof _xfa_object.XFAObject) { + return (obj[_symbol_utils.$content] || "").toString().trim(); + } + } + return null; + } + [_symbol_utils.$toHTML](availableSpace) { + for (const name of Object.getOwnPropertyNames(this)) { + const obj = this[name]; + if (!(obj instanceof _xfa_object.XFAObject)) { + continue; + } + return obj[_symbol_utils.$toHTML](availableSpace); + } + return _utils.HTMLResult.EMPTY; + } +} +exports.Value = Value; +class Variables extends _xfa_object.XFAObject { + constructor(attributes) { + super(TEMPLATE_NS_ID, "variables", true); + this.id = attributes.id || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + this.boolean = new _xfa_object.XFAObjectArray(); + this.date = new _xfa_object.XFAObjectArray(); + this.dateTime = new _xfa_object.XFAObjectArray(); + this.decimal = new _xfa_object.XFAObjectArray(); + this.exData = new _xfa_object.XFAObjectArray(); + this.float = new _xfa_object.XFAObjectArray(); + this.image = new _xfa_object.XFAObjectArray(); + this.integer = new _xfa_object.XFAObjectArray(); + this.manifest = new _xfa_object.XFAObjectArray(); + this.script = new _xfa_object.XFAObjectArray(); + this.text = new _xfa_object.XFAObjectArray(); + this.time = new _xfa_object.XFAObjectArray(); + } + [_symbol_utils.$isTransparent]() { + return true; + } +} +class TemplateNamespace { + static [_namespaces.$buildXFAObject](name, attributes) { + if (TemplateNamespace.hasOwnProperty(name)) { + const node = TemplateNamespace[name](attributes); + node[_symbol_utils.$setSetAttributes](attributes); + return node; + } + return undefined; + } + static appearanceFilter(attrs) { + return new AppearanceFilter(attrs); + } + static arc(attrs) { + return new Arc(attrs); + } + static area(attrs) { + return new Area(attrs); + } + static assist(attrs) { + return new Assist(attrs); + } + static barcode(attrs) { + return new Barcode(attrs); + } + static bind(attrs) { + return new Bind(attrs); + } + static bindItems(attrs) { + return new BindItems(attrs); + } + static bookend(attrs) { + return new Bookend(attrs); + } + static boolean(attrs) { + return new BooleanElement(attrs); + } + static border(attrs) { + return new Border(attrs); + } + static break(attrs) { + return new Break(attrs); + } + static breakAfter(attrs) { + return new BreakAfter(attrs); + } + static breakBefore(attrs) { + return new BreakBefore(attrs); + } + static button(attrs) { + return new Button(attrs); + } + static calculate(attrs) { + return new Calculate(attrs); + } + static caption(attrs) { + return new Caption(attrs); + } + static certificate(attrs) { + return new Certificate(attrs); + } + static certificates(attrs) { + return new Certificates(attrs); + } + static checkButton(attrs) { + return new CheckButton(attrs); + } + static choiceList(attrs) { + return new ChoiceList(attrs); + } + static color(attrs) { + return new Color(attrs); + } + static comb(attrs) { + return new Comb(attrs); + } + static connect(attrs) { + return new Connect(attrs); + } + static contentArea(attrs) { + return new ContentArea(attrs); + } + static corner(attrs) { + return new Corner(attrs); + } + static date(attrs) { + return new DateElement(attrs); + } + static dateTime(attrs) { + return new DateTime(attrs); + } + static dateTimeEdit(attrs) { + return new DateTimeEdit(attrs); + } + static decimal(attrs) { + return new Decimal(attrs); + } + static defaultUi(attrs) { + return new DefaultUi(attrs); + } + static desc(attrs) { + return new Desc(attrs); + } + static digestMethod(attrs) { + return new DigestMethod(attrs); + } + static digestMethods(attrs) { + return new DigestMethods(attrs); + } + static draw(attrs) { + return new Draw(attrs); + } + static edge(attrs) { + return new Edge(attrs); + } + static encoding(attrs) { + return new Encoding(attrs); + } + static encodings(attrs) { + return new Encodings(attrs); + } + static encrypt(attrs) { + return new Encrypt(attrs); + } + static encryptData(attrs) { + return new EncryptData(attrs); + } + static encryption(attrs) { + return new Encryption(attrs); + } + static encryptionMethod(attrs) { + return new EncryptionMethod(attrs); + } + static encryptionMethods(attrs) { + return new EncryptionMethods(attrs); + } + static event(attrs) { + return new Event(attrs); + } + static exData(attrs) { + return new ExData(attrs); + } + static exObject(attrs) { + return new ExObject(attrs); + } + static exclGroup(attrs) { + return new ExclGroup(attrs); + } + static execute(attrs) { + return new Execute(attrs); + } + static extras(attrs) { + return new Extras(attrs); + } + static field(attrs) { + return new Field(attrs); + } + static fill(attrs) { + return new Fill(attrs); + } + static filter(attrs) { + return new Filter(attrs); + } + static float(attrs) { + return new Float(attrs); + } + static font(attrs) { + return new Font(attrs); + } + static format(attrs) { + return new Format(attrs); + } + static handler(attrs) { + return new Handler(attrs); + } + static hyphenation(attrs) { + return new Hyphenation(attrs); + } + static image(attrs) { + return new Image(attrs); + } + static imageEdit(attrs) { + return new ImageEdit(attrs); + } + static integer(attrs) { + return new Integer(attrs); + } + static issuers(attrs) { + return new Issuers(attrs); + } + static items(attrs) { + return new Items(attrs); + } + static keep(attrs) { + return new Keep(attrs); + } + static keyUsage(attrs) { + return new KeyUsage(attrs); + } + static line(attrs) { + return new Line(attrs); + } + static linear(attrs) { + return new Linear(attrs); + } + static lockDocument(attrs) { + return new LockDocument(attrs); + } + static manifest(attrs) { + return new Manifest(attrs); + } + static margin(attrs) { + return new Margin(attrs); + } + static mdp(attrs) { + return new Mdp(attrs); + } + static medium(attrs) { + return new Medium(attrs); + } + static message(attrs) { + return new Message(attrs); + } + static numericEdit(attrs) { + return new NumericEdit(attrs); + } + static occur(attrs) { + return new Occur(attrs); + } + static oid(attrs) { + return new Oid(attrs); + } + static oids(attrs) { + return new Oids(attrs); + } + static overflow(attrs) { + return new Overflow(attrs); + } + static pageArea(attrs) { + return new PageArea(attrs); + } + static pageSet(attrs) { + return new PageSet(attrs); + } + static para(attrs) { + return new Para(attrs); + } + static passwordEdit(attrs) { + return new PasswordEdit(attrs); + } + static pattern(attrs) { + return new Pattern(attrs); + } + static picture(attrs) { + return new Picture(attrs); + } + static proto(attrs) { + return new Proto(attrs); + } + static radial(attrs) { + return new Radial(attrs); + } + static reason(attrs) { + return new Reason(attrs); + } + static reasons(attrs) { + return new Reasons(attrs); + } + static rectangle(attrs) { + return new Rectangle(attrs); + } + static ref(attrs) { + return new RefElement(attrs); + } + static script(attrs) { + return new Script(attrs); + } + static setProperty(attrs) { + return new SetProperty(attrs); + } + static signData(attrs) { + return new SignData(attrs); + } + static signature(attrs) { + return new Signature(attrs); + } + static signing(attrs) { + return new Signing(attrs); + } + static solid(attrs) { + return new Solid(attrs); + } + static speak(attrs) { + return new Speak(attrs); + } + static stipple(attrs) { + return new Stipple(attrs); + } + static subform(attrs) { + return new Subform(attrs); + } + static subformSet(attrs) { + return new SubformSet(attrs); + } + static subjectDN(attrs) { + return new SubjectDN(attrs); + } + static subjectDNs(attrs) { + return new SubjectDNs(attrs); + } + static submit(attrs) { + return new Submit(attrs); + } + static template(attrs) { + return new Template(attrs); + } + static text(attrs) { + return new Text(attrs); + } + static textEdit(attrs) { + return new TextEdit(attrs); + } + static time(attrs) { + return new Time(attrs); + } + static timeStamp(attrs) { + return new TimeStamp(attrs); + } + static toolTip(attrs) { + return new ToolTip(attrs); + } + static traversal(attrs) { + return new Traversal(attrs); + } + static traverse(attrs) { + return new Traverse(attrs); + } + static ui(attrs) { + return new Ui(attrs); + } + static validate(attrs) { + return new Validate(attrs); + } + static value(attrs) { + return new Value(attrs); + } + static variables(attrs) { + return new Variables(attrs); + } +} +exports.TemplateNamespace = TemplateNamespace; + +/***/ }), +/* 81 */ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.NamespaceIds = exports.$buildXFAObject = void 0; +const $buildXFAObject = Symbol(); +exports.$buildXFAObject = $buildXFAObject; +const NamespaceIds = { + config: { + id: 0, + check: ns => ns.startsWith("http://www.xfa.org/schema/xci/") + }, + connectionSet: { + id: 1, + check: ns => ns.startsWith("http://www.xfa.org/schema/xfa-connection-set/") + }, + datasets: { + id: 2, + check: ns => ns.startsWith("http://www.xfa.org/schema/xfa-data/") + }, + form: { + id: 3, + check: ns => ns.startsWith("http://www.xfa.org/schema/xfa-form/") + }, + localeSet: { + id: 4, + check: ns => ns.startsWith("http://www.xfa.org/schema/xfa-locale-set/") + }, + pdf: { + id: 5, + check: ns => ns === "http://ns.adobe.com/xdp/pdf/" + }, + signature: { + id: 6, + check: ns => ns === "http://www.w3.org/2000/09/xmldsig#" + }, + sourceSet: { + id: 7, + check: ns => ns.startsWith("http://www.xfa.org/schema/xfa-source-set/") + }, + stylesheet: { + id: 8, + check: ns => ns === "http://www.w3.org/1999/XSL/Transform" + }, + template: { + id: 9, + check: ns => ns.startsWith("http://www.xfa.org/schema/xfa-template/") + }, + xdc: { + id: 10, + check: ns => ns.startsWith("http://www.xfa.org/schema/xdc/") + }, + xdp: { + id: 11, + check: ns => ns === "http://ns.adobe.com/xdp/" + }, + xfdf: { + id: 12, + check: ns => ns === "http://ns.adobe.com/xfdf/" + }, + xhtml: { + id: 13, + check: ns => ns === "http://www.w3.org/1999/xhtml" + }, + xmpmeta: { + id: 14, + check: ns => ns === "http://ns.adobe.com/xmpmeta/" + } +}; +exports.NamespaceIds = NamespaceIds; + +/***/ }), +/* 82 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.addHTML = addHTML; +exports.checkDimensions = checkDimensions; +exports.flushHTML = flushHTML; +exports.getAvailableSpace = getAvailableSpace; +var _symbol_utils = __w_pdfjs_require__(78); +var _html_utils = __w_pdfjs_require__(83); +function createLine(node, children) { + return { + name: "div", + attributes: { + class: [node.layout === "lr-tb" ? "xfaLr" : "xfaRl"] + }, + children + }; +} +function flushHTML(node) { + if (!node[_symbol_utils.$extra]) { + return null; + } + const attributes = node[_symbol_utils.$extra].attributes; + const html = { + name: "div", + attributes, + children: node[_symbol_utils.$extra].children + }; + if (node[_symbol_utils.$extra].failingNode) { + const htmlFromFailing = node[_symbol_utils.$extra].failingNode[_symbol_utils.$flushHTML](); + if (htmlFromFailing) { + if (node.layout.endsWith("-tb")) { + html.children.push(createLine(node, [htmlFromFailing])); + } else { + html.children.push(htmlFromFailing); + } + } + } + if (html.children.length === 0) { + return null; + } + return html; +} +function addHTML(node, html, bbox) { + const extra = node[_symbol_utils.$extra]; + const availableSpace = extra.availableSpace; + const [x, y, w, h] = bbox; + switch (node.layout) { + case "position": + { + extra.width = Math.max(extra.width, x + w); + extra.height = Math.max(extra.height, y + h); + extra.children.push(html); + break; + } + case "lr-tb": + case "rl-tb": + if (!extra.line || extra.attempt === 1) { + extra.line = createLine(node, []); + extra.children.push(extra.line); + extra.numberInLine = 0; + } + extra.numberInLine += 1; + extra.line.children.push(html); + if (extra.attempt === 0) { + extra.currentWidth += w; + extra.height = Math.max(extra.height, extra.prevHeight + h); + } else { + extra.currentWidth = w; + extra.prevHeight = extra.height; + extra.height += h; + extra.attempt = 0; + } + extra.width = Math.max(extra.width, extra.currentWidth); + break; + case "rl-row": + case "row": + { + extra.children.push(html); + extra.width += w; + extra.height = Math.max(extra.height, h); + const height = (0, _html_utils.measureToString)(extra.height); + for (const child of extra.children) { + child.attributes.style.height = height; + } + break; + } + case "table": + { + extra.width = Math.min(availableSpace.width, Math.max(extra.width, w)); + extra.height += h; + extra.children.push(html); + break; + } + case "tb": + { + extra.width = Math.min(availableSpace.width, Math.max(extra.width, w)); + extra.height += h; + extra.children.push(html); + break; + } + } +} +function getAvailableSpace(node) { + const availableSpace = node[_symbol_utils.$extra].availableSpace; + const marginV = node.margin ? node.margin.topInset + node.margin.bottomInset : 0; + const marginH = node.margin ? node.margin.leftInset + node.margin.rightInset : 0; + switch (node.layout) { + case "lr-tb": + case "rl-tb": + if (node[_symbol_utils.$extra].attempt === 0) { + return { + width: availableSpace.width - marginH - node[_symbol_utils.$extra].currentWidth, + height: availableSpace.height - marginV - node[_symbol_utils.$extra].prevHeight + }; + } + return { + width: availableSpace.width - marginH, + height: availableSpace.height - marginV - node[_symbol_utils.$extra].height + }; + case "rl-row": + case "row": + const width = node[_symbol_utils.$extra].columnWidths.slice(node[_symbol_utils.$extra].currentColumn).reduce((a, x) => a + x); + return { + width, + height: availableSpace.height - marginH + }; + case "table": + case "tb": + return { + width: availableSpace.width - marginH, + height: availableSpace.height - marginV - node[_symbol_utils.$extra].height + }; + case "position": + default: + return availableSpace; + } +} +function getTransformedBBox(node) { + let w = node.w === "" ? NaN : node.w; + let h = node.h === "" ? NaN : node.h; + let [centerX, centerY] = [0, 0]; + switch (node.anchorType || "") { + case "bottomCenter": + [centerX, centerY] = [w / 2, h]; + break; + case "bottomLeft": + [centerX, centerY] = [0, h]; + break; + case "bottomRight": + [centerX, centerY] = [w, h]; + break; + case "middleCenter": + [centerX, centerY] = [w / 2, h / 2]; + break; + case "middleLeft": + [centerX, centerY] = [0, h / 2]; + break; + case "middleRight": + [centerX, centerY] = [w, h / 2]; + break; + case "topCenter": + [centerX, centerY] = [w / 2, 0]; + break; + case "topRight": + [centerX, centerY] = [w, 0]; + break; + } + let x, y; + switch (node.rotate || 0) { + case 0: + [x, y] = [-centerX, -centerY]; + break; + case 90: + [x, y] = [-centerY, centerX]; + [w, h] = [h, -w]; + break; + case 180: + [x, y] = [centerX, centerY]; + [w, h] = [-w, -h]; + break; + case 270: + [x, y] = [centerY, -centerX]; + [w, h] = [-h, w]; + break; + } + return [node.x + x + Math.min(0, w), node.y + y + Math.min(0, h), Math.abs(w), Math.abs(h)]; +} +function checkDimensions(node, space) { + if (node[_symbol_utils.$getTemplateRoot]()[_symbol_utils.$extra].firstUnsplittable === null) { + return true; + } + if (node.w === 0 || node.h === 0) { + return true; + } + const ERROR = 2; + const parent = node[_symbol_utils.$getSubformParent](); + const attempt = parent[_symbol_utils.$extra]?.attempt || 0; + const [, y, w, h] = getTransformedBBox(node); + switch (parent.layout) { + case "lr-tb": + case "rl-tb": + if (attempt === 0) { + if (!node[_symbol_utils.$getTemplateRoot]()[_symbol_utils.$extra].noLayoutFailure) { + if (node.h !== "" && Math.round(h - space.height) > ERROR) { + return false; + } + if (node.w !== "") { + if (Math.round(w - space.width) <= ERROR) { + return true; + } + if (parent[_symbol_utils.$extra].numberInLine === 0) { + return space.height > ERROR; + } + return false; + } + return space.width > ERROR; + } + if (node.w !== "") { + return Math.round(w - space.width) <= ERROR; + } + return space.width > ERROR; + } + if (node[_symbol_utils.$getTemplateRoot]()[_symbol_utils.$extra].noLayoutFailure) { + return true; + } + if (node.h !== "" && Math.round(h - space.height) > ERROR) { + return false; + } + if (node.w === "" || Math.round(w - space.width) <= ERROR) { + return space.height > ERROR; + } + if (parent[_symbol_utils.$isThereMoreWidth]()) { + return false; + } + return space.height > ERROR; + case "table": + case "tb": + if (node[_symbol_utils.$getTemplateRoot]()[_symbol_utils.$extra].noLayoutFailure) { + return true; + } + if (node.h !== "" && !node[_symbol_utils.$isSplittable]()) { + return Math.round(h - space.height) <= ERROR; + } + if (node.w === "" || Math.round(w - space.width) <= ERROR) { + return space.height > ERROR; + } + if (parent[_symbol_utils.$isThereMoreWidth]()) { + return false; + } + return space.height > ERROR; + case "position": + if (node[_symbol_utils.$getTemplateRoot]()[_symbol_utils.$extra].noLayoutFailure) { + return true; + } + if (node.h === "" || Math.round(h + y - space.height) <= ERROR) { + return true; + } + const area = node[_symbol_utils.$getTemplateRoot]()[_symbol_utils.$extra].currentContentArea; + return h + y > area.h; + case "rl-row": + case "row": + if (node[_symbol_utils.$getTemplateRoot]()[_symbol_utils.$extra].noLayoutFailure) { + return true; + } + if (node.h !== "") { + return Math.round(h - space.height) <= ERROR; + } + return true; + default: + return true; + } +} + +/***/ }), +/* 83 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.computeBbox = computeBbox; +exports.createWrapper = createWrapper; +exports.fixDimensions = fixDimensions; +exports.fixTextIndent = fixTextIndent; +exports.fixURL = fixURL; +exports.isPrintOnly = isPrintOnly; +exports.layoutClass = layoutClass; +exports.layoutNode = layoutNode; +exports.measureToString = measureToString; +exports.setAccess = setAccess; +exports.setFontFamily = setFontFamily; +exports.setMinMaxDimensions = setMinMaxDimensions; +exports.setPara = setPara; +exports.toStyle = toStyle; +var _symbol_utils = __w_pdfjs_require__(78); +var _util = __w_pdfjs_require__(2); +var _utils = __w_pdfjs_require__(84); +var _fonts = __w_pdfjs_require__(85); +var _text = __w_pdfjs_require__(86); +var _xfa_object = __w_pdfjs_require__(87); +function measureToString(m) { + if (typeof m === "string") { + return "0px"; + } + return Number.isInteger(m) ? `${m}px` : `${m.toFixed(2)}px`; +} +const converters = { + anchorType(node, style) { + const parent = node[_symbol_utils.$getSubformParent](); + if (!parent || parent.layout && parent.layout !== "position") { + return; + } + if (!("transform" in style)) { + style.transform = ""; + } + switch (node.anchorType) { + case "bottomCenter": + style.transform += "translate(-50%, -100%)"; + break; + case "bottomLeft": + style.transform += "translate(0,-100%)"; + break; + case "bottomRight": + style.transform += "translate(-100%,-100%)"; + break; + case "middleCenter": + style.transform += "translate(-50%,-50%)"; + break; + case "middleLeft": + style.transform += "translate(0,-50%)"; + break; + case "middleRight": + style.transform += "translate(-100%,-50%)"; + break; + case "topCenter": + style.transform += "translate(-50%,0)"; + break; + case "topRight": + style.transform += "translate(-100%,0)"; + break; + } + }, + dimensions(node, style) { + const parent = node[_symbol_utils.$getSubformParent](); + let width = node.w; + const height = node.h; + if (parent.layout?.includes("row")) { + const extra = parent[_symbol_utils.$extra]; + const colSpan = node.colSpan; + let w; + if (colSpan === -1) { + w = extra.columnWidths.slice(extra.currentColumn).reduce((a, x) => a + x, 0); + extra.currentColumn = 0; + } else { + w = extra.columnWidths.slice(extra.currentColumn, extra.currentColumn + colSpan).reduce((a, x) => a + x, 0); + extra.currentColumn = (extra.currentColumn + node.colSpan) % extra.columnWidths.length; + } + if (!isNaN(w)) { + width = node.w = w; + } + } + style.width = width !== "" ? measureToString(width) : "auto"; + style.height = height !== "" ? measureToString(height) : "auto"; + }, + position(node, style) { + const parent = node[_symbol_utils.$getSubformParent](); + if (parent?.layout && parent.layout !== "position") { + return; + } + style.position = "absolute"; + style.left = measureToString(node.x); + style.top = measureToString(node.y); + }, + rotate(node, style) { + if (node.rotate) { + if (!("transform" in style)) { + style.transform = ""; + } + style.transform += `rotate(-${node.rotate}deg)`; + style.transformOrigin = "top left"; + } + }, + presence(node, style) { + switch (node.presence) { + case "invisible": + style.visibility = "hidden"; + break; + case "hidden": + case "inactive": + style.display = "none"; + break; + } + }, + hAlign(node, style) { + if (node[_symbol_utils.$nodeName] === "para") { + switch (node.hAlign) { + case "justifyAll": + style.textAlign = "justify-all"; + break; + case "radix": + style.textAlign = "left"; + break; + default: + style.textAlign = node.hAlign; + } + } else { + switch (node.hAlign) { + case "left": + style.alignSelf = "start"; + break; + case "center": + style.alignSelf = "center"; + break; + case "right": + style.alignSelf = "end"; + break; + } + } + }, + margin(node, style) { + if (node.margin) { + style.margin = node.margin[_symbol_utils.$toStyle]().margin; + } + } +}; +function setMinMaxDimensions(node, style) { + const parent = node[_symbol_utils.$getSubformParent](); + if (parent.layout === "position") { + if (node.minW > 0) { + style.minWidth = measureToString(node.minW); + } + if (node.maxW > 0) { + style.maxWidth = measureToString(node.maxW); + } + if (node.minH > 0) { + style.minHeight = measureToString(node.minH); + } + if (node.maxH > 0) { + style.maxHeight = measureToString(node.maxH); + } + } +} +function layoutText(text, xfaFont, margin, lineHeight, fontFinder, width) { + const measure = new _text.TextMeasure(xfaFont, margin, lineHeight, fontFinder); + if (typeof text === "string") { + measure.addString(text); + } else { + text[_symbol_utils.$pushGlyphs](measure); + } + return measure.compute(width); +} +function layoutNode(node, availableSpace) { + let height = null; + let width = null; + let isBroken = false; + if ((!node.w || !node.h) && node.value) { + let marginH = 0; + let marginV = 0; + if (node.margin) { + marginH = node.margin.leftInset + node.margin.rightInset; + marginV = node.margin.topInset + node.margin.bottomInset; + } + let lineHeight = null; + let margin = null; + if (node.para) { + margin = Object.create(null); + lineHeight = node.para.lineHeight === "" ? null : node.para.lineHeight; + margin.top = node.para.spaceAbove === "" ? 0 : node.para.spaceAbove; + margin.bottom = node.para.spaceBelow === "" ? 0 : node.para.spaceBelow; + margin.left = node.para.marginLeft === "" ? 0 : node.para.marginLeft; + margin.right = node.para.marginRight === "" ? 0 : node.para.marginRight; + } + let font = node.font; + if (!font) { + const root = node[_symbol_utils.$getTemplateRoot](); + let parent = node[_symbol_utils.$getParent](); + while (parent && parent !== root) { + if (parent.font) { + font = parent.font; + break; + } + parent = parent[_symbol_utils.$getParent](); + } + } + const maxWidth = (node.w || availableSpace.width) - marginH; + const fontFinder = node[_symbol_utils.$globalData].fontFinder; + if (node.value.exData && node.value.exData[_symbol_utils.$content] && node.value.exData.contentType === "text/html") { + const res = layoutText(node.value.exData[_symbol_utils.$content], font, margin, lineHeight, fontFinder, maxWidth); + width = res.width; + height = res.height; + isBroken = res.isBroken; + } else { + const text = node.value[_symbol_utils.$text](); + if (text) { + const res = layoutText(text, font, margin, lineHeight, fontFinder, maxWidth); + width = res.width; + height = res.height; + isBroken = res.isBroken; + } + } + if (width !== null && !node.w) { + width += marginH; + } + if (height !== null && !node.h) { + height += marginV; + } + } + return { + w: width, + h: height, + isBroken + }; +} +function computeBbox(node, html, availableSpace) { + let bbox; + if (node.w !== "" && node.h !== "") { + bbox = [node.x, node.y, node.w, node.h]; + } else { + if (!availableSpace) { + return null; + } + let width = node.w; + if (width === "") { + if (node.maxW === 0) { + const parent = node[_symbol_utils.$getSubformParent](); + width = parent.layout === "position" && parent.w !== "" ? 0 : node.minW; + } else { + width = Math.min(node.maxW, availableSpace.width); + } + html.attributes.style.width = measureToString(width); + } + let height = node.h; + if (height === "") { + if (node.maxH === 0) { + const parent = node[_symbol_utils.$getSubformParent](); + height = parent.layout === "position" && parent.h !== "" ? 0 : node.minH; + } else { + height = Math.min(node.maxH, availableSpace.height); + } + html.attributes.style.height = measureToString(height); + } + bbox = [node.x, node.y, width, height]; + } + return bbox; +} +function fixDimensions(node) { + const parent = node[_symbol_utils.$getSubformParent](); + if (parent.layout?.includes("row")) { + const extra = parent[_symbol_utils.$extra]; + const colSpan = node.colSpan; + let width; + if (colSpan === -1) { + width = extra.columnWidths.slice(extra.currentColumn).reduce((a, w) => a + w, 0); + } else { + width = extra.columnWidths.slice(extra.currentColumn, extra.currentColumn + colSpan).reduce((a, w) => a + w, 0); + } + if (!isNaN(width)) { + node.w = width; + } + } + if (parent.layout && parent.layout !== "position") { + node.x = node.y = 0; + } + if (node.layout === "table") { + if (node.w === "" && Array.isArray(node.columnWidths)) { + node.w = node.columnWidths.reduce((a, x) => a + x, 0); + } + } +} +function layoutClass(node) { + switch (node.layout) { + case "position": + return "xfaPosition"; + case "lr-tb": + return "xfaLrTb"; + case "rl-row": + return "xfaRlRow"; + case "rl-tb": + return "xfaRlTb"; + case "row": + return "xfaRow"; + case "table": + return "xfaTable"; + case "tb": + return "xfaTb"; + default: + return "xfaPosition"; + } +} +function toStyle(node, ...names) { + const style = Object.create(null); + for (const name of names) { + const value = node[name]; + if (value === null) { + continue; + } + if (converters.hasOwnProperty(name)) { + converters[name](node, style); + continue; + } + if (value instanceof _xfa_object.XFAObject) { + const newStyle = value[_symbol_utils.$toStyle](); + if (newStyle) { + Object.assign(style, newStyle); + } else { + (0, _util.warn)(`(DEBUG) - XFA - style for ${name} not implemented yet`); + } + } + } + return style; +} +function createWrapper(node, html) { + const { + attributes + } = html; + const { + style + } = attributes; + const wrapper = { + name: "div", + attributes: { + class: ["xfaWrapper"], + style: Object.create(null) + }, + children: [] + }; + attributes.class.push("xfaWrapped"); + if (node.border) { + const { + widths, + insets + } = node.border[_symbol_utils.$extra]; + let width, height; + let top = insets[0]; + let left = insets[3]; + const insetsH = insets[0] + insets[2]; + const insetsW = insets[1] + insets[3]; + switch (node.border.hand) { + case "even": + top -= widths[0] / 2; + left -= widths[3] / 2; + width = `calc(100% + ${(widths[1] + widths[3]) / 2 - insetsW}px)`; + height = `calc(100% + ${(widths[0] + widths[2]) / 2 - insetsH}px)`; + break; + case "left": + top -= widths[0]; + left -= widths[3]; + width = `calc(100% + ${widths[1] + widths[3] - insetsW}px)`; + height = `calc(100% + ${widths[0] + widths[2] - insetsH}px)`; + break; + case "right": + width = insetsW ? `calc(100% - ${insetsW}px)` : "100%"; + height = insetsH ? `calc(100% - ${insetsH}px)` : "100%"; + break; + } + const classNames = ["xfaBorder"]; + if (isPrintOnly(node.border)) { + classNames.push("xfaPrintOnly"); + } + const border = { + name: "div", + attributes: { + class: classNames, + style: { + top: `${top}px`, + left: `${left}px`, + width, + height + } + }, + children: [] + }; + for (const key of ["border", "borderWidth", "borderColor", "borderRadius", "borderStyle"]) { + if (style[key] !== undefined) { + border.attributes.style[key] = style[key]; + delete style[key]; + } + } + wrapper.children.push(border, html); + } else { + wrapper.children.push(html); + } + for (const key of ["background", "backgroundClip", "top", "left", "width", "height", "minWidth", "minHeight", "maxWidth", "maxHeight", "transform", "transformOrigin", "visibility"]) { + if (style[key] !== undefined) { + wrapper.attributes.style[key] = style[key]; + delete style[key]; + } + } + wrapper.attributes.style.position = style.position === "absolute" ? "absolute" : "relative"; + delete style.position; + if (style.alignSelf) { + wrapper.attributes.style.alignSelf = style.alignSelf; + delete style.alignSelf; + } + return wrapper; +} +function fixTextIndent(styles) { + const indent = (0, _utils.getMeasurement)(styles.textIndent, "0px"); + if (indent >= 0) { + return; + } + const align = styles.textAlign === "right" ? "right" : "left"; + const name = "padding" + (align === "left" ? "Left" : "Right"); + const padding = (0, _utils.getMeasurement)(styles[name], "0px"); + styles[name] = `${padding - indent}px`; +} +function setAccess(node, classNames) { + switch (node.access) { + case "nonInteractive": + classNames.push("xfaNonInteractive"); + break; + case "readOnly": + classNames.push("xfaReadOnly"); + break; + case "protected": + classNames.push("xfaDisabled"); + break; + } +} +function isPrintOnly(node) { + return node.relevant.length > 0 && !node.relevant[0].excluded && node.relevant[0].viewname === "print"; +} +function getCurrentPara(node) { + const stack = node[_symbol_utils.$getTemplateRoot]()[_symbol_utils.$extra].paraStack; + return stack.length ? stack.at(-1) : null; +} +function setPara(node, nodeStyle, value) { + if (value.attributes.class?.includes("xfaRich")) { + if (nodeStyle) { + if (node.h === "") { + nodeStyle.height = "auto"; + } + if (node.w === "") { + nodeStyle.width = "auto"; + } + } + const para = getCurrentPara(node); + if (para) { + const valueStyle = value.attributes.style; + valueStyle.display = "flex"; + valueStyle.flexDirection = "column"; + switch (para.vAlign) { + case "top": + valueStyle.justifyContent = "start"; + break; + case "bottom": + valueStyle.justifyContent = "end"; + break; + case "middle": + valueStyle.justifyContent = "center"; + break; + } + const paraStyle = para[_symbol_utils.$toStyle](); + for (const [key, val] of Object.entries(paraStyle)) { + if (!(key in valueStyle)) { + valueStyle[key] = val; + } + } + } + } +} +function setFontFamily(xfaFont, node, fontFinder, style) { + if (!fontFinder) { + delete style.fontFamily; + return; + } + const name = (0, _utils.stripQuotes)(xfaFont.typeface); + style.fontFamily = `"${name}"`; + const typeface = fontFinder.find(name); + if (typeface) { + const { + fontFamily + } = typeface.regular.cssFontInfo; + if (fontFamily !== name) { + style.fontFamily = `"${fontFamily}"`; + } + const para = getCurrentPara(node); + if (para && para.lineHeight !== "") { + return; + } + if (style.lineHeight) { + return; + } + const pdfFont = (0, _fonts.selectFont)(xfaFont, typeface); + if (pdfFont) { + style.lineHeight = Math.max(1.2, pdfFont.lineHeight); + } + } +} +function fixURL(str) { + const absoluteUrl = (0, _util.createValidAbsoluteUrl)(str, null, { + addDefaultProtocol: true, + tryConvertEncoding: true + }); + return absoluteUrl ? absoluteUrl.href : null; +} + +/***/ }), +/* 84 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.HTMLResult = void 0; +exports.getBBox = getBBox; +exports.getColor = getColor; +exports.getFloat = getFloat; +exports.getInteger = getInteger; +exports.getKeyword = getKeyword; +exports.getMeasurement = getMeasurement; +exports.getRatio = getRatio; +exports.getRelevant = getRelevant; +exports.getStringOption = getStringOption; +exports.stripQuotes = stripQuotes; +var _util = __w_pdfjs_require__(2); +const dimConverters = { + pt: x => x, + cm: x => x / 2.54 * 72, + mm: x => x / (10 * 2.54) * 72, + in: x => x * 72, + px: x => x +}; +const measurementPattern = /([+-]?\d+\.?\d*)(.*)/; +function stripQuotes(str) { + if (str.startsWith("'") || str.startsWith('"')) { + return str.slice(1, -1); + } + return str; +} +function getInteger({ + data, + defaultValue, + validate +}) { + if (!data) { + return defaultValue; + } + data = data.trim(); + const n = parseInt(data, 10); + if (!isNaN(n) && validate(n)) { + return n; + } + return defaultValue; +} +function getFloat({ + data, + defaultValue, + validate +}) { + if (!data) { + return defaultValue; + } + data = data.trim(); + const n = parseFloat(data); + if (!isNaN(n) && validate(n)) { + return n; + } + return defaultValue; +} +function getKeyword({ + data, + defaultValue, + validate +}) { + if (!data) { + return defaultValue; + } + data = data.trim(); + if (validate(data)) { + return data; + } + return defaultValue; +} +function getStringOption(data, options) { + return getKeyword({ + data, + defaultValue: options[0], + validate: k => options.includes(k) + }); +} +function getMeasurement(str, def = "0") { + def ||= "0"; + if (!str) { + return getMeasurement(def); + } + const match = str.trim().match(measurementPattern); + if (!match) { + return getMeasurement(def); + } + const [, valueStr, unit] = match; + const value = parseFloat(valueStr); + if (isNaN(value)) { + return getMeasurement(def); + } + if (value === 0) { + return 0; + } + const conv = dimConverters[unit]; + if (conv) { + return conv(value); + } + return value; +} +function getRatio(data) { + if (!data) { + return { + num: 1, + den: 1 + }; + } + const ratio = data.trim().split(/\s*:\s*/).map(x => parseFloat(x)).filter(x => !isNaN(x)); + if (ratio.length === 1) { + ratio.push(1); + } + if (ratio.length === 0) { + return { + num: 1, + den: 1 + }; + } + const [num, den] = ratio; + return { + num, + den + }; +} +function getRelevant(data) { + if (!data) { + return []; + } + return data.trim().split(/\s+/).map(e => { + return { + excluded: e[0] === "-", + viewname: e.substring(1) + }; + }); +} +function getColor(data, def = [0, 0, 0]) { + let [r, g, b] = def; + if (!data) { + return { + r, + g, + b + }; + } + const color = data.trim().split(/\s*,\s*/).map(c => Math.min(Math.max(0, parseInt(c.trim(), 10)), 255)).map(c => isNaN(c) ? 0 : c); + if (color.length < 3) { + return { + r, + g, + b + }; + } + [r, g, b] = color; + return { + r, + g, + b + }; +} +function getBBox(data) { + const def = -1; + if (!data) { + return { + x: def, + y: def, + width: def, + height: def + }; + } + const bbox = data.trim().split(/\s*,\s*/).map(m => getMeasurement(m, "-1")); + if (bbox.length < 4 || bbox[2] < 0 || bbox[3] < 0) { + return { + x: def, + y: def, + width: def, + height: def + }; + } + const [x, y, width, height] = bbox; + return { + x, + y, + width, + height + }; +} +class HTMLResult { + static get FAILURE() { + return (0, _util.shadow)(this, "FAILURE", new HTMLResult(false, null, null, null)); + } + static get EMPTY() { + return (0, _util.shadow)(this, "EMPTY", new HTMLResult(true, null, null, null)); + } + constructor(success, html, bbox, breakNode) { + this.success = success; + this.html = html; + this.bbox = bbox; + this.breakNode = breakNode; + } + isBreak() { + return !!this.breakNode; + } + static breakNode(node) { + return new HTMLResult(false, null, null, node); + } + static success(html, bbox = null) { + return new HTMLResult(true, html, bbox, null); + } +} +exports.HTMLResult = HTMLResult; + +/***/ }), +/* 85 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.FontFinder = void 0; +exports.getMetrics = getMetrics; +exports.selectFont = selectFont; +var _symbol_utils = __w_pdfjs_require__(78); +var _utils = __w_pdfjs_require__(84); +var _util = __w_pdfjs_require__(2); +class FontFinder { + constructor(pdfFonts) { + this.fonts = new Map(); + this.cache = new Map(); + this.warned = new Set(); + this.defaultFont = null; + this.add(pdfFonts); + } + add(pdfFonts, reallyMissingFonts = null) { + for (const pdfFont of pdfFonts) { + this.addPdfFont(pdfFont); + } + for (const pdfFont of this.fonts.values()) { + if (!pdfFont.regular) { + pdfFont.regular = pdfFont.italic || pdfFont.bold || pdfFont.bolditalic; + } + } + if (!reallyMissingFonts || reallyMissingFonts.size === 0) { + return; + } + const myriad = this.fonts.get("PdfJS-Fallback-PdfJS-XFA"); + for (const missing of reallyMissingFonts) { + this.fonts.set(missing, myriad); + } + } + addPdfFont(pdfFont) { + const cssFontInfo = pdfFont.cssFontInfo; + const name = cssFontInfo.fontFamily; + let font = this.fonts.get(name); + if (!font) { + font = Object.create(null); + this.fonts.set(name, font); + if (!this.defaultFont) { + this.defaultFont = font; + } + } + let property = ""; + const fontWeight = parseFloat(cssFontInfo.fontWeight); + if (parseFloat(cssFontInfo.italicAngle) !== 0) { + property = fontWeight >= 700 ? "bolditalic" : "italic"; + } else if (fontWeight >= 700) { + property = "bold"; + } + if (!property) { + if (pdfFont.name.includes("Bold") || pdfFont.psName?.includes("Bold")) { + property = "bold"; + } + if (pdfFont.name.includes("Italic") || pdfFont.name.endsWith("It") || pdfFont.psName?.includes("Italic") || pdfFont.psName?.endsWith("It")) { + property += "italic"; + } + } + if (!property) { + property = "regular"; + } + font[property] = pdfFont; + } + getDefault() { + return this.defaultFont; + } + find(fontName, mustWarn = true) { + let font = this.fonts.get(fontName) || this.cache.get(fontName); + if (font) { + return font; + } + const pattern = /,|-|_| |bolditalic|bold|italic|regular|it/gi; + let name = fontName.replaceAll(pattern, ""); + font = this.fonts.get(name); + if (font) { + this.cache.set(fontName, font); + return font; + } + name = name.toLowerCase(); + const maybe = []; + for (const [family, pdfFont] of this.fonts.entries()) { + if (family.replaceAll(pattern, "").toLowerCase().startsWith(name)) { + maybe.push(pdfFont); + } + } + if (maybe.length === 0) { + for (const [, pdfFont] of this.fonts.entries()) { + if (pdfFont.regular.name?.replaceAll(pattern, "").toLowerCase().startsWith(name)) { + maybe.push(pdfFont); + } + } + } + if (maybe.length === 0) { + name = name.replaceAll(/psmt|mt/gi, ""); + for (const [family, pdfFont] of this.fonts.entries()) { + if (family.replaceAll(pattern, "").toLowerCase().startsWith(name)) { + maybe.push(pdfFont); + } + } + } + if (maybe.length === 0) { + for (const pdfFont of this.fonts.values()) { + if (pdfFont.regular.name?.replaceAll(pattern, "").toLowerCase().startsWith(name)) { + maybe.push(pdfFont); + } + } + } + if (maybe.length >= 1) { + if (maybe.length !== 1 && mustWarn) { + (0, _util.warn)(`XFA - Too many choices to guess the correct font: ${fontName}`); + } + this.cache.set(fontName, maybe[0]); + return maybe[0]; + } + if (mustWarn && !this.warned.has(fontName)) { + this.warned.add(fontName); + (0, _util.warn)(`XFA - Cannot find the font: ${fontName}`); + } + return null; + } +} +exports.FontFinder = FontFinder; +function selectFont(xfaFont, typeface) { + if (xfaFont.posture === "italic") { + if (xfaFont.weight === "bold") { + return typeface.bolditalic; + } + return typeface.italic; + } else if (xfaFont.weight === "bold") { + return typeface.bold; + } + return typeface.regular; +} +function getMetrics(xfaFont, real = false) { + let pdfFont = null; + if (xfaFont) { + const name = (0, _utils.stripQuotes)(xfaFont.typeface); + const typeface = xfaFont[_symbol_utils.$globalData].fontFinder.find(name); + pdfFont = selectFont(xfaFont, typeface); + } + if (!pdfFont) { + return { + lineHeight: 12, + lineGap: 2, + lineNoGap: 10 + }; + } + const size = xfaFont.size || 10; + const lineHeight = pdfFont.lineHeight ? Math.max(real ? 0 : 1.2, pdfFont.lineHeight) : 1.2; + const lineGap = pdfFont.lineGap === undefined ? 0.2 : pdfFont.lineGap; + return { + lineHeight: lineHeight * size, + lineGap: lineGap * size, + lineNoGap: Math.max(1, lineHeight - lineGap) * size + }; +} + +/***/ }), +/* 86 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.TextMeasure = void 0; +var _fonts = __w_pdfjs_require__(85); +const WIDTH_FACTOR = 1.02; +class FontInfo { + constructor(xfaFont, margin, lineHeight, fontFinder) { + this.lineHeight = lineHeight; + this.paraMargin = margin || { + top: 0, + bottom: 0, + left: 0, + right: 0 + }; + if (!xfaFont) { + [this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder); + return; + } + this.xfaFont = { + typeface: xfaFont.typeface, + posture: xfaFont.posture, + weight: xfaFont.weight, + size: xfaFont.size, + letterSpacing: xfaFont.letterSpacing + }; + const typeface = fontFinder.find(xfaFont.typeface); + if (!typeface) { + [this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder); + return; + } + this.pdfFont = (0, _fonts.selectFont)(xfaFont, typeface); + if (!this.pdfFont) { + [this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder); + } + } + defaultFont(fontFinder) { + const font = fontFinder.find("Helvetica", false) || fontFinder.find("Myriad Pro", false) || fontFinder.find("Arial", false) || fontFinder.getDefault(); + if (font?.regular) { + const pdfFont = font.regular; + const info = pdfFont.cssFontInfo; + const xfaFont = { + typeface: info.fontFamily, + posture: "normal", + weight: "normal", + size: 10, + letterSpacing: 0 + }; + return [pdfFont, xfaFont]; + } + const xfaFont = { + typeface: "Courier", + posture: "normal", + weight: "normal", + size: 10, + letterSpacing: 0 + }; + return [null, xfaFont]; + } +} +class FontSelector { + constructor(defaultXfaFont, defaultParaMargin, defaultLineHeight, fontFinder) { + this.fontFinder = fontFinder; + this.stack = [new FontInfo(defaultXfaFont, defaultParaMargin, defaultLineHeight, fontFinder)]; + } + pushData(xfaFont, margin, lineHeight) { + const lastFont = this.stack.at(-1); + for (const name of ["typeface", "posture", "weight", "size", "letterSpacing"]) { + if (!xfaFont[name]) { + xfaFont[name] = lastFont.xfaFont[name]; + } + } + for (const name of ["top", "bottom", "left", "right"]) { + if (isNaN(margin[name])) { + margin[name] = lastFont.paraMargin[name]; + } + } + const fontInfo = new FontInfo(xfaFont, margin, lineHeight || lastFont.lineHeight, this.fontFinder); + if (!fontInfo.pdfFont) { + fontInfo.pdfFont = lastFont.pdfFont; + } + this.stack.push(fontInfo); + } + popFont() { + this.stack.pop(); + } + topFont() { + return this.stack.at(-1); + } +} +class TextMeasure { + constructor(defaultXfaFont, defaultParaMargin, defaultLineHeight, fonts) { + this.glyphs = []; + this.fontSelector = new FontSelector(defaultXfaFont, defaultParaMargin, defaultLineHeight, fonts); + this.extraHeight = 0; + } + pushData(xfaFont, margin, lineHeight) { + this.fontSelector.pushData(xfaFont, margin, lineHeight); + } + popFont(xfaFont) { + return this.fontSelector.popFont(); + } + addPara() { + const lastFont = this.fontSelector.topFont(); + this.extraHeight += lastFont.paraMargin.top + lastFont.paraMargin.bottom; + } + addString(str) { + if (!str) { + return; + } + const lastFont = this.fontSelector.topFont(); + const fontSize = lastFont.xfaFont.size; + if (lastFont.pdfFont) { + const letterSpacing = lastFont.xfaFont.letterSpacing; + const pdfFont = lastFont.pdfFont; + const fontLineHeight = pdfFont.lineHeight || 1.2; + const lineHeight = lastFont.lineHeight || Math.max(1.2, fontLineHeight) * fontSize; + const lineGap = pdfFont.lineGap === undefined ? 0.2 : pdfFont.lineGap; + const noGap = fontLineHeight - lineGap; + const firstLineHeight = Math.max(1, noGap) * fontSize; + const scale = fontSize / 1000; + const fallbackWidth = pdfFont.defaultWidth || pdfFont.charsToGlyphs(" ")[0].width; + for (const line of str.split(/[\u2029\n]/)) { + const encodedLine = pdfFont.encodeString(line).join(""); + const glyphs = pdfFont.charsToGlyphs(encodedLine); + for (const glyph of glyphs) { + const width = glyph.width || fallbackWidth; + this.glyphs.push([width * scale + letterSpacing, lineHeight, firstLineHeight, glyph.unicode, false]); + } + this.glyphs.push([0, 0, 0, "\n", true]); + } + this.glyphs.pop(); + return; + } + for (const line of str.split(/[\u2029\n]/)) { + for (const char of line.split("")) { + this.glyphs.push([fontSize, 1.2 * fontSize, fontSize, char, false]); + } + this.glyphs.push([0, 0, 0, "\n", true]); + } + this.glyphs.pop(); + } + compute(maxWidth) { + let lastSpacePos = -1, + lastSpaceWidth = 0, + width = 0, + height = 0, + currentLineWidth = 0, + currentLineHeight = 0; + let isBroken = false; + let isFirstLine = true; + for (let i = 0, ii = this.glyphs.length; i < ii; i++) { + const [glyphWidth, lineHeight, firstLineHeight, char, isEOL] = this.glyphs[i]; + const isSpace = char === " "; + const glyphHeight = isFirstLine ? firstLineHeight : lineHeight; + if (isEOL) { + width = Math.max(width, currentLineWidth); + currentLineWidth = 0; + height += currentLineHeight; + currentLineHeight = glyphHeight; + lastSpacePos = -1; + lastSpaceWidth = 0; + isFirstLine = false; + continue; + } + if (isSpace) { + if (currentLineWidth + glyphWidth > maxWidth) { + width = Math.max(width, currentLineWidth); + currentLineWidth = 0; + height += currentLineHeight; + currentLineHeight = glyphHeight; + lastSpacePos = -1; + lastSpaceWidth = 0; + isBroken = true; + isFirstLine = false; + } else { + currentLineHeight = Math.max(glyphHeight, currentLineHeight); + lastSpaceWidth = currentLineWidth; + currentLineWidth += glyphWidth; + lastSpacePos = i; + } + continue; + } + if (currentLineWidth + glyphWidth > maxWidth) { + height += currentLineHeight; + currentLineHeight = glyphHeight; + if (lastSpacePos !== -1) { + i = lastSpacePos; + width = Math.max(width, lastSpaceWidth); + currentLineWidth = 0; + lastSpacePos = -1; + lastSpaceWidth = 0; + } else { + width = Math.max(width, currentLineWidth); + currentLineWidth = glyphWidth; + } + isBroken = true; + isFirstLine = false; + continue; + } + currentLineWidth += glyphWidth; + currentLineHeight = Math.max(glyphHeight, currentLineHeight); + } + width = Math.max(width, currentLineWidth); + height += currentLineHeight + this.extraHeight; + return { + width: WIDTH_FACTOR * width, + height, + isBroken + }; + } +} +exports.TextMeasure = TextMeasure; + +/***/ }), +/* 87 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.XmlObject = exports.XFAObjectArray = exports.XFAObject = exports.XFAAttribute = exports.StringObject = exports.OptionObject = exports.Option10 = exports.Option01 = exports.IntegerObject = exports.ContentObject = void 0; +var _symbol_utils = __w_pdfjs_require__(78); +var _utils = __w_pdfjs_require__(84); +var _util = __w_pdfjs_require__(2); +var _core_utils = __w_pdfjs_require__(3); +var _namespaces = __w_pdfjs_require__(81); +var _som = __w_pdfjs_require__(88); +const _applyPrototype = Symbol(); +const _attributes = Symbol(); +const _attributeNames = Symbol(); +const _children = Symbol("_children"); +const _cloneAttribute = Symbol(); +const _dataValue = Symbol(); +const _defaultValue = Symbol(); +const _filteredChildrenGenerator = Symbol(); +const _getPrototype = Symbol(); +const _getUnsetAttributes = Symbol(); +const _hasChildren = Symbol(); +const _max = Symbol(); +const _options = Symbol(); +const _parent = Symbol("parent"); +const _resolvePrototypesHelper = Symbol(); +const _setAttributes = Symbol(); +const _validator = Symbol(); +let uid = 0; +const NS_DATASETS = _namespaces.NamespaceIds.datasets.id; +class XFAObject { + constructor(nsId, name, hasChildren = false) { + this[_symbol_utils.$namespaceId] = nsId; + this[_symbol_utils.$nodeName] = name; + this[_hasChildren] = hasChildren; + this[_parent] = null; + this[_children] = []; + this[_symbol_utils.$uid] = `${name}${uid++}`; + this[_symbol_utils.$globalData] = null; + } + get isXFAObject() { + return true; + } + get isXFAObjectArray() { + return false; + } + createNodes(path) { + let root = this, + node = null; + for (const { + name, + index + } of path) { + for (let i = 0, ii = isFinite(index) ? index : 0; i <= ii; i++) { + const nsId = root[_symbol_utils.$namespaceId] === NS_DATASETS ? -1 : root[_symbol_utils.$namespaceId]; + node = new XmlObject(nsId, name); + root[_symbol_utils.$appendChild](node); + } + root = node; + } + return node; + } + [_symbol_utils.$onChild](child) { + if (!this[_hasChildren] || !this[_symbol_utils.$onChildCheck](child)) { + return false; + } + const name = child[_symbol_utils.$nodeName]; + const node = this[name]; + if (node instanceof XFAObjectArray) { + if (node.push(child)) { + this[_symbol_utils.$appendChild](child); + return true; + } + } else { + if (node !== null) { + this[_symbol_utils.$removeChild](node); + } + this[name] = child; + this[_symbol_utils.$appendChild](child); + return true; + } + let id = ""; + if (this.id) { + id = ` (id: ${this.id})`; + } else if (this.name) { + id = ` (name: ${this.name} ${this.h.value})`; + } + (0, _util.warn)(`XFA - node "${this[_symbol_utils.$nodeName]}"${id} has already enough "${name}"!`); + return false; + } + [_symbol_utils.$onChildCheck](child) { + return this.hasOwnProperty(child[_symbol_utils.$nodeName]) && child[_symbol_utils.$namespaceId] === this[_symbol_utils.$namespaceId]; + } + [_symbol_utils.$isNsAgnostic]() { + return false; + } + [_symbol_utils.$acceptWhitespace]() { + return false; + } + [_symbol_utils.$isCDATAXml]() { + return false; + } + [_symbol_utils.$isBindable]() { + return false; + } + [_symbol_utils.$popPara]() { + if (this.para) { + this[_symbol_utils.$getTemplateRoot]()[_symbol_utils.$extra].paraStack.pop(); + } + } + [_symbol_utils.$pushPara]() { + this[_symbol_utils.$getTemplateRoot]()[_symbol_utils.$extra].paraStack.push(this.para); + } + [_symbol_utils.$setId](ids) { + if (this.id && this[_symbol_utils.$namespaceId] === _namespaces.NamespaceIds.template.id) { + ids.set(this.id, this); + } + } + [_symbol_utils.$getTemplateRoot]() { + return this[_symbol_utils.$globalData].template; + } + [_symbol_utils.$isSplittable]() { + return false; + } + [_symbol_utils.$isThereMoreWidth]() { + return false; + } + [_symbol_utils.$appendChild](child) { + child[_parent] = this; + this[_children].push(child); + if (!child[_symbol_utils.$globalData] && this[_symbol_utils.$globalData]) { + child[_symbol_utils.$globalData] = this[_symbol_utils.$globalData]; + } + } + [_symbol_utils.$removeChild](child) { + const i = this[_children].indexOf(child); + this[_children].splice(i, 1); + } + [_symbol_utils.$hasSettableValue]() { + return this.hasOwnProperty("value"); + } + [_symbol_utils.$setValue](_) {} + [_symbol_utils.$onText](_) {} + [_symbol_utils.$finalize]() {} + [_symbol_utils.$clean](builder) { + delete this[_hasChildren]; + if (this[_symbol_utils.$cleanup]) { + builder.clean(this[_symbol_utils.$cleanup]); + delete this[_symbol_utils.$cleanup]; + } + } + [_symbol_utils.$indexOf](child) { + return this[_children].indexOf(child); + } + [_symbol_utils.$insertAt](i, child) { + child[_parent] = this; + this[_children].splice(i, 0, child); + if (!child[_symbol_utils.$globalData] && this[_symbol_utils.$globalData]) { + child[_symbol_utils.$globalData] = this[_symbol_utils.$globalData]; + } + } + [_symbol_utils.$isTransparent]() { + return !this.name; + } + [_symbol_utils.$lastAttribute]() { + return ""; + } + [_symbol_utils.$text]() { + if (this[_children].length === 0) { + return this[_symbol_utils.$content]; + } + return this[_children].map(c => c[_symbol_utils.$text]()).join(""); + } + get [_attributeNames]() { + const proto = Object.getPrototypeOf(this); + if (!proto._attributes) { + const attributes = proto._attributes = new Set(); + for (const name of Object.getOwnPropertyNames(this)) { + if (this[name] === null || this[name] instanceof XFAObject || this[name] instanceof XFAObjectArray) { + break; + } + attributes.add(name); + } + } + return (0, _util.shadow)(this, _attributeNames, proto._attributes); + } + [_symbol_utils.$isDescendent](parent) { + let node = this; + while (node) { + if (node === parent) { + return true; + } + node = node[_symbol_utils.$getParent](); + } + return false; + } + [_symbol_utils.$getParent]() { + return this[_parent]; + } + [_symbol_utils.$getSubformParent]() { + return this[_symbol_utils.$getParent](); + } + [_symbol_utils.$getChildren](name = null) { + if (!name) { + return this[_children]; + } + return this[name]; + } + [_symbol_utils.$dump]() { + const dumped = Object.create(null); + if (this[_symbol_utils.$content]) { + dumped.$content = this[_symbol_utils.$content]; + } + for (const name of Object.getOwnPropertyNames(this)) { + const value = this[name]; + if (value === null) { + continue; + } + if (value instanceof XFAObject) { + dumped[name] = value[_symbol_utils.$dump](); + } else if (value instanceof XFAObjectArray) { + if (!value.isEmpty()) { + dumped[name] = value.dump(); + } + } else { + dumped[name] = value; + } + } + return dumped; + } + [_symbol_utils.$toStyle]() { + return null; + } + [_symbol_utils.$toHTML]() { + return _utils.HTMLResult.EMPTY; + } + *[_symbol_utils.$getContainedChildren]() { + for (const node of this[_symbol_utils.$getChildren]()) { + yield node; + } + } + *[_filteredChildrenGenerator](filter, include) { + for (const node of this[_symbol_utils.$getContainedChildren]()) { + if (!filter || include === filter.has(node[_symbol_utils.$nodeName])) { + const availableSpace = this[_symbol_utils.$getAvailableSpace](); + const res = node[_symbol_utils.$toHTML](availableSpace); + if (!res.success) { + this[_symbol_utils.$extra].failingNode = node; + } + yield res; + } + } + } + [_symbol_utils.$flushHTML]() { + return null; + } + [_symbol_utils.$addHTML](html, bbox) { + this[_symbol_utils.$extra].children.push(html); + } + [_symbol_utils.$getAvailableSpace]() {} + [_symbol_utils.$childrenToHTML]({ + filter = null, + include = true + }) { + if (!this[_symbol_utils.$extra].generator) { + this[_symbol_utils.$extra].generator = this[_filteredChildrenGenerator](filter, include); + } else { + const availableSpace = this[_symbol_utils.$getAvailableSpace](); + const res = this[_symbol_utils.$extra].failingNode[_symbol_utils.$toHTML](availableSpace); + if (!res.success) { + return res; + } + if (res.html) { + this[_symbol_utils.$addHTML](res.html, res.bbox); + } + delete this[_symbol_utils.$extra].failingNode; + } + while (true) { + const gen = this[_symbol_utils.$extra].generator.next(); + if (gen.done) { + break; + } + const res = gen.value; + if (!res.success) { + return res; + } + if (res.html) { + this[_symbol_utils.$addHTML](res.html, res.bbox); + } + } + this[_symbol_utils.$extra].generator = null; + return _utils.HTMLResult.EMPTY; + } + [_symbol_utils.$setSetAttributes](attributes) { + this[_setAttributes] = new Set(Object.keys(attributes)); + } + [_getUnsetAttributes](protoAttributes) { + const allAttr = this[_attributeNames]; + const setAttr = this[_setAttributes]; + return [...protoAttributes].filter(x => allAttr.has(x) && !setAttr.has(x)); + } + [_symbol_utils.$resolvePrototypes](ids, ancestors = new Set()) { + for (const child of this[_children]) { + child[_resolvePrototypesHelper](ids, ancestors); + } + } + [_resolvePrototypesHelper](ids, ancestors) { + const proto = this[_getPrototype](ids, ancestors); + if (proto) { + this[_applyPrototype](proto, ids, ancestors); + } else { + this[_symbol_utils.$resolvePrototypes](ids, ancestors); + } + } + [_getPrototype](ids, ancestors) { + const { + use, + usehref + } = this; + if (!use && !usehref) { + return null; + } + let proto = null; + let somExpression = null; + let id = null; + let ref = use; + if (usehref) { + ref = usehref; + if (usehref.startsWith("#som(") && usehref.endsWith(")")) { + somExpression = usehref.slice("#som(".length, -1); + } else if (usehref.startsWith(".#som(") && usehref.endsWith(")")) { + somExpression = usehref.slice(".#som(".length, -1); + } else if (usehref.startsWith("#")) { + id = usehref.slice(1); + } else if (usehref.startsWith(".#")) { + id = usehref.slice(2); + } + } else if (use.startsWith("#")) { + id = use.slice(1); + } else { + somExpression = use; + } + this.use = this.usehref = ""; + if (id) { + proto = ids.get(id); + } else { + proto = (0, _som.searchNode)(ids.get(_symbol_utils.$root), this, somExpression, true, false); + if (proto) { + proto = proto[0]; + } + } + if (!proto) { + (0, _util.warn)(`XFA - Invalid prototype reference: ${ref}.`); + return null; + } + if (proto[_symbol_utils.$nodeName] !== this[_symbol_utils.$nodeName]) { + (0, _util.warn)(`XFA - Incompatible prototype: ${proto[_symbol_utils.$nodeName]} !== ${this[_symbol_utils.$nodeName]}.`); + return null; + } + if (ancestors.has(proto)) { + (0, _util.warn)(`XFA - Cycle detected in prototypes use.`); + return null; + } + ancestors.add(proto); + const protoProto = proto[_getPrototype](ids, ancestors); + if (protoProto) { + proto[_applyPrototype](protoProto, ids, ancestors); + } + proto[_symbol_utils.$resolvePrototypes](ids, ancestors); + ancestors.delete(proto); + return proto; + } + [_applyPrototype](proto, ids, ancestors) { + if (ancestors.has(proto)) { + (0, _util.warn)(`XFA - Cycle detected in prototypes use.`); + return; + } + if (!this[_symbol_utils.$content] && proto[_symbol_utils.$content]) { + this[_symbol_utils.$content] = proto[_symbol_utils.$content]; + } + const newAncestors = new Set(ancestors); + newAncestors.add(proto); + for (const unsetAttrName of this[_getUnsetAttributes](proto[_setAttributes])) { + this[unsetAttrName] = proto[unsetAttrName]; + if (this[_setAttributes]) { + this[_setAttributes].add(unsetAttrName); + } + } + for (const name of Object.getOwnPropertyNames(this)) { + if (this[_attributeNames].has(name)) { + continue; + } + const value = this[name]; + const protoValue = proto[name]; + if (value instanceof XFAObjectArray) { + for (const child of value[_children]) { + child[_resolvePrototypesHelper](ids, ancestors); + } + for (let i = value[_children].length, ii = protoValue[_children].length; i < ii; i++) { + const child = proto[_children][i][_symbol_utils.$clone](); + if (value.push(child)) { + child[_parent] = this; + this[_children].push(child); + child[_resolvePrototypesHelper](ids, ancestors); + } else { + break; + } + } + continue; + } + if (value !== null) { + value[_symbol_utils.$resolvePrototypes](ids, ancestors); + if (protoValue) { + value[_applyPrototype](protoValue, ids, ancestors); + } + continue; + } + if (protoValue !== null) { + const child = protoValue[_symbol_utils.$clone](); + child[_parent] = this; + this[name] = child; + this[_children].push(child); + child[_resolvePrototypesHelper](ids, ancestors); + } + } + } + static [_cloneAttribute](obj) { + if (Array.isArray(obj)) { + return obj.map(x => XFAObject[_cloneAttribute](x)); + } + if (typeof obj === "object" && obj !== null) { + return Object.assign({}, obj); + } + return obj; + } + [_symbol_utils.$clone]() { + const clone = Object.create(Object.getPrototypeOf(this)); + for (const $symbol of Object.getOwnPropertySymbols(this)) { + try { + clone[$symbol] = this[$symbol]; + } catch { + (0, _util.shadow)(clone, $symbol, this[$symbol]); + } + } + clone[_symbol_utils.$uid] = `${clone[_symbol_utils.$nodeName]}${uid++}`; + clone[_children] = []; + for (const name of Object.getOwnPropertyNames(this)) { + if (this[_attributeNames].has(name)) { + clone[name] = XFAObject[_cloneAttribute](this[name]); + continue; + } + const value = this[name]; + clone[name] = value instanceof XFAObjectArray ? new XFAObjectArray(value[_max]) : null; + } + for (const child of this[_children]) { + const name = child[_symbol_utils.$nodeName]; + const clonedChild = child[_symbol_utils.$clone](); + clone[_children].push(clonedChild); + clonedChild[_parent] = clone; + if (clone[name] === null) { + clone[name] = clonedChild; + } else { + clone[name][_children].push(clonedChild); + } + } + return clone; + } + [_symbol_utils.$getChildren](name = null) { + if (!name) { + return this[_children]; + } + return this[_children].filter(c => c[_symbol_utils.$nodeName] === name); + } + [_symbol_utils.$getChildrenByClass](name) { + return this[name]; + } + [_symbol_utils.$getChildrenByName](name, allTransparent, first = true) { + return Array.from(this[_symbol_utils.$getChildrenByNameIt](name, allTransparent, first)); + } + *[_symbol_utils.$getChildrenByNameIt](name, allTransparent, first = true) { + if (name === "parent") { + yield this[_parent]; + return; + } + for (const child of this[_children]) { + if (child[_symbol_utils.$nodeName] === name) { + yield child; + } + if (child.name === name) { + yield child; + } + if (allTransparent || child[_symbol_utils.$isTransparent]()) { + yield* child[_symbol_utils.$getChildrenByNameIt](name, allTransparent, false); + } + } + if (first && this[_attributeNames].has(name)) { + yield new XFAAttribute(this, name, this[name]); + } + } +} +exports.XFAObject = XFAObject; +class XFAObjectArray { + constructor(max = Infinity) { + this[_max] = max; + this[_children] = []; + } + get isXFAObject() { + return false; + } + get isXFAObjectArray() { + return true; + } + push(child) { + const len = this[_children].length; + if (len <= this[_max]) { + this[_children].push(child); + return true; + } + (0, _util.warn)(`XFA - node "${child[_symbol_utils.$nodeName]}" accepts no more than ${this[_max]} children`); + return false; + } + isEmpty() { + return this[_children].length === 0; + } + dump() { + return this[_children].length === 1 ? this[_children][0][_symbol_utils.$dump]() : this[_children].map(x => x[_symbol_utils.$dump]()); + } + [_symbol_utils.$clone]() { + const clone = new XFAObjectArray(this[_max]); + clone[_children] = this[_children].map(c => c[_symbol_utils.$clone]()); + return clone; + } + get children() { + return this[_children]; + } + clear() { + this[_children].length = 0; + } +} +exports.XFAObjectArray = XFAObjectArray; +class XFAAttribute { + constructor(node, name, value) { + this[_parent] = node; + this[_symbol_utils.$nodeName] = name; + this[_symbol_utils.$content] = value; + this[_symbol_utils.$consumed] = false; + this[_symbol_utils.$uid] = `attribute${uid++}`; + } + [_symbol_utils.$getParent]() { + return this[_parent]; + } + [_symbol_utils.$isDataValue]() { + return true; + } + [_symbol_utils.$getDataValue]() { + return this[_symbol_utils.$content].trim(); + } + [_symbol_utils.$setValue](value) { + value = value.value || ""; + this[_symbol_utils.$content] = value.toString(); + } + [_symbol_utils.$text]() { + return this[_symbol_utils.$content]; + } + [_symbol_utils.$isDescendent](parent) { + return this[_parent] === parent || this[_parent][_symbol_utils.$isDescendent](parent); + } +} +exports.XFAAttribute = XFAAttribute; +class XmlObject extends XFAObject { + constructor(nsId, name, attributes = {}) { + super(nsId, name); + this[_symbol_utils.$content] = ""; + this[_dataValue] = null; + if (name !== "#text") { + const map = new Map(); + this[_attributes] = map; + for (const [attrName, value] of Object.entries(attributes)) { + map.set(attrName, new XFAAttribute(this, attrName, value)); + } + if (attributes.hasOwnProperty(_symbol_utils.$nsAttributes)) { + const dataNode = attributes[_symbol_utils.$nsAttributes].xfa.dataNode; + if (dataNode !== undefined) { + if (dataNode === "dataGroup") { + this[_dataValue] = false; + } else if (dataNode === "dataValue") { + this[_dataValue] = true; + } + } + } + } + this[_symbol_utils.$consumed] = false; + } + [_symbol_utils.$toString](buf) { + const tagName = this[_symbol_utils.$nodeName]; + if (tagName === "#text") { + buf.push((0, _core_utils.encodeToXmlString)(this[_symbol_utils.$content])); + return; + } + const utf8TagName = (0, _util.utf8StringToString)(tagName); + const prefix = this[_symbol_utils.$namespaceId] === NS_DATASETS ? "xfa:" : ""; + buf.push(`<${prefix}${utf8TagName}`); + for (const [name, value] of this[_attributes].entries()) { + const utf8Name = (0, _util.utf8StringToString)(name); + buf.push(` ${utf8Name}="${(0, _core_utils.encodeToXmlString)(value[_symbol_utils.$content])}"`); + } + if (this[_dataValue] !== null) { + if (this[_dataValue]) { + buf.push(` xfa:dataNode="dataValue"`); + } else { + buf.push(` xfa:dataNode="dataGroup"`); + } + } + if (!this[_symbol_utils.$content] && this[_children].length === 0) { + buf.push("/>"); + return; + } + buf.push(">"); + if (this[_symbol_utils.$content]) { + if (typeof this[_symbol_utils.$content] === "string") { + buf.push((0, _core_utils.encodeToXmlString)(this[_symbol_utils.$content])); + } else { + this[_symbol_utils.$content][_symbol_utils.$toString](buf); + } + } else { + for (const child of this[_children]) { + child[_symbol_utils.$toString](buf); + } + } + buf.push(``); + } + [_symbol_utils.$onChild](child) { + if (this[_symbol_utils.$content]) { + const node = new XmlObject(this[_symbol_utils.$namespaceId], "#text"); + this[_symbol_utils.$appendChild](node); + node[_symbol_utils.$content] = this[_symbol_utils.$content]; + this[_symbol_utils.$content] = ""; + } + this[_symbol_utils.$appendChild](child); + return true; + } + [_symbol_utils.$onText](str) { + this[_symbol_utils.$content] += str; + } + [_symbol_utils.$finalize]() { + if (this[_symbol_utils.$content] && this[_children].length > 0) { + const node = new XmlObject(this[_symbol_utils.$namespaceId], "#text"); + this[_symbol_utils.$appendChild](node); + node[_symbol_utils.$content] = this[_symbol_utils.$content]; + delete this[_symbol_utils.$content]; + } + } + [_symbol_utils.$toHTML]() { + if (this[_symbol_utils.$nodeName] === "#text") { + return _utils.HTMLResult.success({ + name: "#text", + value: this[_symbol_utils.$content] + }); + } + return _utils.HTMLResult.EMPTY; + } + [_symbol_utils.$getChildren](name = null) { + if (!name) { + return this[_children]; + } + return this[_children].filter(c => c[_symbol_utils.$nodeName] === name); + } + [_symbol_utils.$getAttributes]() { + return this[_attributes]; + } + [_symbol_utils.$getChildrenByClass](name) { + const value = this[_attributes].get(name); + if (value !== undefined) { + return value; + } + return this[_symbol_utils.$getChildren](name); + } + *[_symbol_utils.$getChildrenByNameIt](name, allTransparent) { + const value = this[_attributes].get(name); + if (value) { + yield value; + } + for (const child of this[_children]) { + if (child[_symbol_utils.$nodeName] === name) { + yield child; + } + if (allTransparent) { + yield* child[_symbol_utils.$getChildrenByNameIt](name, allTransparent); + } + } + } + *[_symbol_utils.$getAttributeIt](name, skipConsumed) { + const value = this[_attributes].get(name); + if (value && (!skipConsumed || !value[_symbol_utils.$consumed])) { + yield value; + } + for (const child of this[_children]) { + yield* child[_symbol_utils.$getAttributeIt](name, skipConsumed); + } + } + *[_symbol_utils.$getRealChildrenByNameIt](name, allTransparent, skipConsumed) { + for (const child of this[_children]) { + if (child[_symbol_utils.$nodeName] === name && (!skipConsumed || !child[_symbol_utils.$consumed])) { + yield child; + } + if (allTransparent) { + yield* child[_symbol_utils.$getRealChildrenByNameIt](name, allTransparent, skipConsumed); + } + } + } + [_symbol_utils.$isDataValue]() { + if (this[_dataValue] === null) { + return this[_children].length === 0 || this[_children][0][_symbol_utils.$namespaceId] === _namespaces.NamespaceIds.xhtml.id; + } + return this[_dataValue]; + } + [_symbol_utils.$getDataValue]() { + if (this[_dataValue] === null) { + if (this[_children].length === 0) { + return this[_symbol_utils.$content].trim(); + } + if (this[_children][0][_symbol_utils.$namespaceId] === _namespaces.NamespaceIds.xhtml.id) { + return this[_children][0][_symbol_utils.$text]().trim(); + } + return null; + } + return this[_symbol_utils.$content].trim(); + } + [_symbol_utils.$setValue](value) { + value = value.value || ""; + this[_symbol_utils.$content] = value.toString(); + } + [_symbol_utils.$dump](hasNS = false) { + const dumped = Object.create(null); + if (hasNS) { + dumped.$ns = this[_symbol_utils.$namespaceId]; + } + if (this[_symbol_utils.$content]) { + dumped.$content = this[_symbol_utils.$content]; + } + dumped.$name = this[_symbol_utils.$nodeName]; + dumped.children = []; + for (const child of this[_children]) { + dumped.children.push(child[_symbol_utils.$dump](hasNS)); + } + dumped.attributes = Object.create(null); + for (const [name, value] of this[_attributes]) { + dumped.attributes[name] = value[_symbol_utils.$content]; + } + return dumped; + } +} +exports.XmlObject = XmlObject; +class ContentObject extends XFAObject { + constructor(nsId, name) { + super(nsId, name); + this[_symbol_utils.$content] = ""; + } + [_symbol_utils.$onText](text) { + this[_symbol_utils.$content] += text; + } + [_symbol_utils.$finalize]() {} +} +exports.ContentObject = ContentObject; +class OptionObject extends ContentObject { + constructor(nsId, name, options) { + super(nsId, name); + this[_options] = options; + } + [_symbol_utils.$finalize]() { + this[_symbol_utils.$content] = (0, _utils.getKeyword)({ + data: this[_symbol_utils.$content], + defaultValue: this[_options][0], + validate: k => this[_options].includes(k) + }); + } + [_symbol_utils.$clean](builder) { + super[_symbol_utils.$clean](builder); + delete this[_options]; + } +} +exports.OptionObject = OptionObject; +class StringObject extends ContentObject { + [_symbol_utils.$finalize]() { + this[_symbol_utils.$content] = this[_symbol_utils.$content].trim(); + } +} +exports.StringObject = StringObject; +class IntegerObject extends ContentObject { + constructor(nsId, name, defaultValue, validator) { + super(nsId, name); + this[_defaultValue] = defaultValue; + this[_validator] = validator; + } + [_symbol_utils.$finalize]() { + this[_symbol_utils.$content] = (0, _utils.getInteger)({ + data: this[_symbol_utils.$content], + defaultValue: this[_defaultValue], + validate: this[_validator] + }); + } + [_symbol_utils.$clean](builder) { + super[_symbol_utils.$clean](builder); + delete this[_defaultValue]; + delete this[_validator]; + } +} +exports.IntegerObject = IntegerObject; +class Option01 extends IntegerObject { + constructor(nsId, name) { + super(nsId, name, 0, n => n === 1); + } +} +exports.Option01 = Option01; +class Option10 extends IntegerObject { + constructor(nsId, name) { + super(nsId, name, 1, n => n === 0); + } +} +exports.Option10 = Option10; + +/***/ }), +/* 88 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.createDataNode = createDataNode; +exports.searchNode = searchNode; +var _symbol_utils = __w_pdfjs_require__(78); +var _util = __w_pdfjs_require__(2); +const namePattern = /^[^.[]+/; +const indexPattern = /^[^\]]+/; +const operators = { + dot: 0, + dotDot: 1, + dotHash: 2, + dotBracket: 3, + dotParen: 4 +}; +const shortcuts = new Map([["$data", (root, current) => root.datasets ? root.datasets.data : root], ["$record", (root, current) => (root.datasets ? root.datasets.data : root)[_symbol_utils.$getChildren]()[0]], ["$template", (root, current) => root.template], ["$connectionSet", (root, current) => root.connectionSet], ["$form", (root, current) => root.form], ["$layout", (root, current) => root.layout], ["$host", (root, current) => root.host], ["$dataWindow", (root, current) => root.dataWindow], ["$event", (root, current) => root.event], ["!", (root, current) => root.datasets], ["$xfa", (root, current) => root], ["xfa", (root, current) => root], ["$", (root, current) => current]]); +const somCache = new WeakMap(); +function parseIndex(index) { + index = index.trim(); + if (index === "*") { + return Infinity; + } + return parseInt(index, 10) || 0; +} +function parseExpression(expr, dotDotAllowed, noExpr = true) { + let match = expr.match(namePattern); + if (!match) { + return null; + } + let [name] = match; + const parsed = [{ + name, + cacheName: "." + name, + index: 0, + js: null, + formCalc: null, + operator: operators.dot + }]; + let pos = name.length; + while (pos < expr.length) { + const spos = pos; + const char = expr.charAt(pos++); + if (char === "[") { + match = expr.slice(pos).match(indexPattern); + if (!match) { + (0, _util.warn)("XFA - Invalid index in SOM expression"); + return null; + } + parsed.at(-1).index = parseIndex(match[0]); + pos += match[0].length + 1; + continue; + } + let operator; + switch (expr.charAt(pos)) { + case ".": + if (!dotDotAllowed) { + return null; + } + pos++; + operator = operators.dotDot; + break; + case "#": + pos++; + operator = operators.dotHash; + break; + case "[": + if (noExpr) { + (0, _util.warn)("XFA - SOM expression contains a FormCalc subexpression which is not supported for now."); + return null; + } + operator = operators.dotBracket; + break; + case "(": + if (noExpr) { + (0, _util.warn)("XFA - SOM expression contains a JavaScript subexpression which is not supported for now."); + return null; + } + operator = operators.dotParen; + break; + default: + operator = operators.dot; + break; + } + match = expr.slice(pos).match(namePattern); + if (!match) { + break; + } + [name] = match; + pos += name.length; + parsed.push({ + name, + cacheName: expr.slice(spos, pos), + operator, + index: 0, + js: null, + formCalc: null + }); + } + return parsed; +} +function searchNode(root, container, expr, dotDotAllowed = true, useCache = true) { + const parsed = parseExpression(expr, dotDotAllowed); + if (!parsed) { + return null; + } + const fn = shortcuts.get(parsed[0].name); + let i = 0; + let isQualified; + if (fn) { + isQualified = true; + root = [fn(root, container)]; + i = 1; + } else { + isQualified = container === null; + root = [container || root]; + } + for (let ii = parsed.length; i < ii; i++) { + const { + name, + cacheName, + operator, + index + } = parsed[i]; + const nodes = []; + for (const node of root) { + if (!node.isXFAObject) { + continue; + } + let children, cached; + if (useCache) { + cached = somCache.get(node); + if (!cached) { + cached = new Map(); + somCache.set(node, cached); + } + children = cached.get(cacheName); + } + if (!children) { + switch (operator) { + case operators.dot: + children = node[_symbol_utils.$getChildrenByName](name, false); + break; + case operators.dotDot: + children = node[_symbol_utils.$getChildrenByName](name, true); + break; + case operators.dotHash: + children = node[_symbol_utils.$getChildrenByClass](name); + children = children.isXFAObjectArray ? children.children : [children]; + break; + default: + break; + } + if (useCache) { + cached.set(cacheName, children); + } + } + if (children.length > 0) { + nodes.push(children); + } + } + if (nodes.length === 0 && !isQualified && i === 0) { + const parent = container[_symbol_utils.$getParent](); + container = parent; + if (!container) { + return null; + } + i = -1; + root = [container]; + continue; + } + root = isFinite(index) ? nodes.filter(node => index < node.length).map(node => node[index]) : nodes.flat(); + } + if (root.length === 0) { + return null; + } + return root; +} +function createDataNode(root, container, expr) { + const parsed = parseExpression(expr); + if (!parsed) { + return null; + } + if (parsed.some(x => x.operator === operators.dotDot)) { + return null; + } + const fn = shortcuts.get(parsed[0].name); + let i = 0; + if (fn) { + root = fn(root, container); + i = 1; + } else { + root = container || root; + } + for (let ii = parsed.length; i < ii; i++) { + const { + name, + operator, + index + } = parsed[i]; + if (!isFinite(index)) { + parsed[i].index = 0; + return root.createNodes(parsed.slice(i)); + } + let children; + switch (operator) { + case operators.dot: + children = root[_symbol_utils.$getChildrenByName](name, false); + break; + case operators.dotDot: + children = root[_symbol_utils.$getChildrenByName](name, true); + break; + case operators.dotHash: + children = root[_symbol_utils.$getChildrenByClass](name); + children = children.isXFAObjectArray ? children.children : [children]; + break; + default: + break; + } + if (children.length === 0) { + return root.createNodes(parsed.slice(i)); + } + if (index < children.length) { + const child = children[index]; + if (!child.isXFAObject) { + (0, _util.warn)(`XFA - Cannot create a node.`); + return null; + } + root = child; + } else { + parsed[i].index = index - children.length; + return root.createNodes(parsed.slice(i)); + } + } + return null; +} + +/***/ }), +/* 89 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.DataHandler = void 0; +var _symbol_utils = __w_pdfjs_require__(78); +class DataHandler { + constructor(root, data) { + this.data = data; + this.dataset = root.datasets || null; + } + serialize(storage) { + const stack = [[-1, this.data[_symbol_utils.$getChildren]()]]; + while (stack.length > 0) { + const last = stack.at(-1); + const [i, children] = last; + if (i + 1 === children.length) { + stack.pop(); + continue; + } + const child = children[++last[0]]; + const storageEntry = storage.get(child[_symbol_utils.$uid]); + if (storageEntry) { + child[_symbol_utils.$setValue](storageEntry); + } else { + const attributes = child[_symbol_utils.$getAttributes](); + for (const value of attributes.values()) { + const entry = storage.get(value[_symbol_utils.$uid]); + if (entry) { + value[_symbol_utils.$setValue](entry); + break; + } + } + } + const nodes = child[_symbol_utils.$getChildren](); + if (nodes.length > 0) { + stack.push([-1, nodes]); + } + } + const buf = [``]; + if (this.dataset) { + for (const child of this.dataset[_symbol_utils.$getChildren]()) { + if (child[_symbol_utils.$nodeName] !== "data") { + child[_symbol_utils.$toString](buf); + } + } + } + this.data[_symbol_utils.$toString](buf); + buf.push(""); + return buf.join(""); + } +} +exports.DataHandler = DataHandler; + +/***/ }), +/* 90 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.XFAParser = void 0; +var _symbol_utils = __w_pdfjs_require__(78); +var _xml_parser = __w_pdfjs_require__(71); +var _builder = __w_pdfjs_require__(91); +var _util = __w_pdfjs_require__(2); +class XFAParser extends _xml_parser.XMLParserBase { + constructor(rootNameSpace = null, richText = false) { + super(); + this._builder = new _builder.Builder(rootNameSpace); + this._stack = []; + this._globalData = { + usedTypefaces: new Set() + }; + this._ids = new Map(); + this._current = this._builder.buildRoot(this._ids); + this._errorCode = _xml_parser.XMLParserErrorCode.NoError; + this._whiteRegex = /^\s+$/; + this._nbsps = /\xa0+/g; + this._richText = richText; + } + parse(data) { + this.parseXml(data); + if (this._errorCode !== _xml_parser.XMLParserErrorCode.NoError) { + return undefined; + } + this._current[_symbol_utils.$finalize](); + return this._current.element; + } + onText(text) { + text = text.replace(this._nbsps, match => match.slice(1) + " "); + if (this._richText || this._current[_symbol_utils.$acceptWhitespace]()) { + this._current[_symbol_utils.$onText](text, this._richText); + return; + } + if (this._whiteRegex.test(text)) { + return; + } + this._current[_symbol_utils.$onText](text.trim()); + } + onCdata(text) { + this._current[_symbol_utils.$onText](text); + } + _mkAttributes(attributes, tagName) { + let namespace = null; + let prefixes = null; + const attributeObj = Object.create({}); + for (const { + name, + value + } of attributes) { + if (name === "xmlns") { + if (!namespace) { + namespace = value; + } else { + (0, _util.warn)(`XFA - multiple namespace definition in <${tagName}>`); + } + } else if (name.startsWith("xmlns:")) { + const prefix = name.substring("xmlns:".length); + if (!prefixes) { + prefixes = []; + } + prefixes.push({ + prefix, + value + }); + } else { + const i = name.indexOf(":"); + if (i === -1) { + attributeObj[name] = value; + } else { + let nsAttrs = attributeObj[_symbol_utils.$nsAttributes]; + if (!nsAttrs) { + nsAttrs = attributeObj[_symbol_utils.$nsAttributes] = Object.create(null); + } + const [ns, attrName] = [name.slice(0, i), name.slice(i + 1)]; + const attrs = nsAttrs[ns] ||= Object.create(null); + attrs[attrName] = value; + } + } + } + return [namespace, prefixes, attributeObj]; + } + _getNameAndPrefix(name, nsAgnostic) { + const i = name.indexOf(":"); + if (i === -1) { + return [name, null]; + } + return [name.substring(i + 1), nsAgnostic ? "" : name.substring(0, i)]; + } + onBeginElement(tagName, attributes, isEmpty) { + const [namespace, prefixes, attributesObj] = this._mkAttributes(attributes, tagName); + const [name, nsPrefix] = this._getNameAndPrefix(tagName, this._builder.isNsAgnostic()); + const node = this._builder.build({ + nsPrefix, + name, + attributes: attributesObj, + namespace, + prefixes + }); + node[_symbol_utils.$globalData] = this._globalData; + if (isEmpty) { + node[_symbol_utils.$finalize](); + if (this._current[_symbol_utils.$onChild](node)) { + node[_symbol_utils.$setId](this._ids); + } + node[_symbol_utils.$clean](this._builder); + return; + } + this._stack.push(this._current); + this._current = node; + } + onEndElement(name) { + const node = this._current; + if (node[_symbol_utils.$isCDATAXml]() && typeof node[_symbol_utils.$content] === "string") { + const parser = new XFAParser(); + parser._globalData = this._globalData; + const root = parser.parse(node[_symbol_utils.$content]); + node[_symbol_utils.$content] = null; + node[_symbol_utils.$onChild](root); + } + node[_symbol_utils.$finalize](); + this._current = this._stack.pop(); + if (this._current[_symbol_utils.$onChild](node)) { + node[_symbol_utils.$setId](this._ids); + } + node[_symbol_utils.$clean](this._builder); + } + onError(code) { + this._errorCode = code; + } +} +exports.XFAParser = XFAParser; + +/***/ }), +/* 91 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Builder = void 0; +var _namespaces = __w_pdfjs_require__(81); +var _symbol_utils = __w_pdfjs_require__(78); +var _setup = __w_pdfjs_require__(92); +var _template = __w_pdfjs_require__(80); +var _unknown = __w_pdfjs_require__(101); +var _util = __w_pdfjs_require__(2); +var _xfa_object = __w_pdfjs_require__(87); +class Root extends _xfa_object.XFAObject { + constructor(ids) { + super(-1, "root", Object.create(null)); + this.element = null; + this[_symbol_utils.$ids] = ids; + } + [_symbol_utils.$onChild](child) { + this.element = child; + return true; + } + [_symbol_utils.$finalize]() { + super[_symbol_utils.$finalize](); + if (this.element.template instanceof _template.Template) { + this[_symbol_utils.$ids].set(_symbol_utils.$root, this.element); + this.element.template[_symbol_utils.$resolvePrototypes](this[_symbol_utils.$ids]); + this.element.template[_symbol_utils.$ids] = this[_symbol_utils.$ids]; + } + } +} +class Empty extends _xfa_object.XFAObject { + constructor() { + super(-1, "", Object.create(null)); + } + [_symbol_utils.$onChild](_) { + return false; + } +} +class Builder { + constructor(rootNameSpace = null) { + this._namespaceStack = []; + this._nsAgnosticLevel = 0; + this._namespacePrefixes = new Map(); + this._namespaces = new Map(); + this._nextNsId = Math.max(...Object.values(_namespaces.NamespaceIds).map(({ + id + }) => id)); + this._currentNamespace = rootNameSpace || new _unknown.UnknownNamespace(++this._nextNsId); + } + buildRoot(ids) { + return new Root(ids); + } + build({ + nsPrefix, + name, + attributes, + namespace, + prefixes + }) { + const hasNamespaceDef = namespace !== null; + if (hasNamespaceDef) { + this._namespaceStack.push(this._currentNamespace); + this._currentNamespace = this._searchNamespace(namespace); + } + if (prefixes) { + this._addNamespacePrefix(prefixes); + } + if (attributes.hasOwnProperty(_symbol_utils.$nsAttributes)) { + const dataTemplate = _setup.NamespaceSetUp.datasets; + const nsAttrs = attributes[_symbol_utils.$nsAttributes]; + let xfaAttrs = null; + for (const [ns, attrs] of Object.entries(nsAttrs)) { + const nsToUse = this._getNamespaceToUse(ns); + if (nsToUse === dataTemplate) { + xfaAttrs = { + xfa: attrs + }; + break; + } + } + if (xfaAttrs) { + attributes[_symbol_utils.$nsAttributes] = xfaAttrs; + } else { + delete attributes[_symbol_utils.$nsAttributes]; + } + } + const namespaceToUse = this._getNamespaceToUse(nsPrefix); + const node = namespaceToUse?.[_namespaces.$buildXFAObject](name, attributes) || new Empty(); + if (node[_symbol_utils.$isNsAgnostic]()) { + this._nsAgnosticLevel++; + } + if (hasNamespaceDef || prefixes || node[_symbol_utils.$isNsAgnostic]()) { + node[_symbol_utils.$cleanup] = { + hasNamespace: hasNamespaceDef, + prefixes, + nsAgnostic: node[_symbol_utils.$isNsAgnostic]() + }; + } + return node; + } + isNsAgnostic() { + return this._nsAgnosticLevel > 0; + } + _searchNamespace(nsName) { + let ns = this._namespaces.get(nsName); + if (ns) { + return ns; + } + for (const [name, { + check + }] of Object.entries(_namespaces.NamespaceIds)) { + if (check(nsName)) { + ns = _setup.NamespaceSetUp[name]; + if (ns) { + this._namespaces.set(nsName, ns); + return ns; + } + break; + } + } + ns = new _unknown.UnknownNamespace(++this._nextNsId); + this._namespaces.set(nsName, ns); + return ns; + } + _addNamespacePrefix(prefixes) { + for (const { + prefix, + value + } of prefixes) { + const namespace = this._searchNamespace(value); + let prefixStack = this._namespacePrefixes.get(prefix); + if (!prefixStack) { + prefixStack = []; + this._namespacePrefixes.set(prefix, prefixStack); + } + prefixStack.push(namespace); + } + } + _getNamespaceToUse(prefix) { + if (!prefix) { + return this._currentNamespace; + } + const prefixStack = this._namespacePrefixes.get(prefix); + if (prefixStack?.length > 0) { + return prefixStack.at(-1); + } + (0, _util.warn)(`Unknown namespace prefix: ${prefix}.`); + return null; + } + clean(data) { + const { + hasNamespace, + prefixes, + nsAgnostic + } = data; + if (hasNamespace) { + this._currentNamespace = this._namespaceStack.pop(); + } + if (prefixes) { + prefixes.forEach(({ + prefix + }) => { + this._namespacePrefixes.get(prefix).pop(); + }); + } + if (nsAgnostic) { + this._nsAgnosticLevel--; + } + } +} +exports.Builder = Builder; + +/***/ }), +/* 92 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.NamespaceSetUp = void 0; +var _config = __w_pdfjs_require__(93); +var _connection_set = __w_pdfjs_require__(94); +var _datasets = __w_pdfjs_require__(95); +var _locale_set = __w_pdfjs_require__(96); +var _signature = __w_pdfjs_require__(97); +var _stylesheet = __w_pdfjs_require__(98); +var _template = __w_pdfjs_require__(80); +var _xdp = __w_pdfjs_require__(99); +var _xhtml = __w_pdfjs_require__(100); +const NamespaceSetUp = { + config: _config.ConfigNamespace, + connection: _connection_set.ConnectionSetNamespace, + datasets: _datasets.DatasetsNamespace, + localeSet: _locale_set.LocaleSetNamespace, + signature: _signature.SignatureNamespace, + stylesheet: _stylesheet.StylesheetNamespace, + template: _template.TemplateNamespace, + xdp: _xdp.XdpNamespace, + xhtml: _xhtml.XhtmlNamespace +}; +exports.NamespaceSetUp = NamespaceSetUp; + +/***/ }), +/* 93 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ConfigNamespace = void 0; +var _namespaces = __w_pdfjs_require__(81); +var _symbol_utils = __w_pdfjs_require__(78); +var _xfa_object = __w_pdfjs_require__(87); +var _utils = __w_pdfjs_require__(84); +var _util = __w_pdfjs_require__(2); +const CONFIG_NS_ID = _namespaces.NamespaceIds.config.id; +class Acrobat extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "acrobat", true); + this.acrobat7 = null; + this.autoSave = null; + this.common = null; + this.validate = null; + this.validateApprovalSignatures = null; + this.submitUrl = new _xfa_object.XFAObjectArray(); + } +} +class Acrobat7 extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "acrobat7", true); + this.dynamicRender = null; + } +} +class ADBE_JSConsole extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "ADBE_JSConsole", ["delegate", "Enable", "Disable"]); + } +} +class ADBE_JSDebugger extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "ADBE_JSDebugger", ["delegate", "Enable", "Disable"]); + } +} +class AddSilentPrint extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "addSilentPrint"); + } +} +class AddViewerPreferences extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "addViewerPreferences"); + } +} +class AdjustData extends _xfa_object.Option10 { + constructor(attributes) { + super(CONFIG_NS_ID, "adjustData"); + } +} +class AdobeExtensionLevel extends _xfa_object.IntegerObject { + constructor(attributes) { + super(CONFIG_NS_ID, "adobeExtensionLevel", 0, n => n >= 1 && n <= 8); + } +} +class Agent extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "agent", true); + this.name = attributes.name ? attributes.name.trim() : ""; + this.common = new _xfa_object.XFAObjectArray(); + } +} +class AlwaysEmbed extends _xfa_object.ContentObject { + constructor(attributes) { + super(CONFIG_NS_ID, "alwaysEmbed"); + } +} +class Amd extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "amd"); + } +} +class Area extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "area"); + this.level = (0, _utils.getInteger)({ + data: attributes.level, + defaultValue: 0, + validate: n => n >= 1 && n <= 3 + }); + this.name = (0, _utils.getStringOption)(attributes.name, ["", "barcode", "coreinit", "deviceDriver", "font", "general", "layout", "merge", "script", "signature", "sourceSet", "templateCache"]); + } +} +class Attributes extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "attributes", ["preserve", "delegate", "ignore"]); + } +} +class AutoSave extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "autoSave", ["disabled", "enabled"]); + } +} +class Base extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "base"); + } +} +class BatchOutput extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "batchOutput"); + this.format = (0, _utils.getStringOption)(attributes.format, ["none", "concat", "zip", "zipCompress"]); + } +} +class BehaviorOverride extends _xfa_object.ContentObject { + constructor(attributes) { + super(CONFIG_NS_ID, "behaviorOverride"); + } + [_symbol_utils.$finalize]() { + this[_symbol_utils.$content] = new Map(this[_symbol_utils.$content].trim().split(/\s+/).filter(x => x.includes(":")).map(x => x.split(":", 2))); + } +} +class Cache extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "cache", true); + this.templateCache = null; + } +} +class Change extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "change"); + } +} +class Common extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "common", true); + this.data = null; + this.locale = null; + this.localeSet = null; + this.messaging = null; + this.suppressBanner = null; + this.template = null; + this.validationMessaging = null; + this.versionControl = null; + this.log = new _xfa_object.XFAObjectArray(); + } +} +class Compress extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "compress"); + this.scope = (0, _utils.getStringOption)(attributes.scope, ["imageOnly", "document"]); + } +} +class CompressLogicalStructure extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "compressLogicalStructure"); + } +} +class CompressObjectStream extends _xfa_object.Option10 { + constructor(attributes) { + super(CONFIG_NS_ID, "compressObjectStream"); + } +} +class Compression extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "compression", true); + this.compressLogicalStructure = null; + this.compressObjectStream = null; + this.level = null; + this.type = null; + } +} +class Config extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "config", true); + this.acrobat = null; + this.present = null; + this.trace = null; + this.agent = new _xfa_object.XFAObjectArray(); + } +} +class Conformance extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "conformance", ["A", "B"]); + } +} +class ContentCopy extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "contentCopy"); + } +} +class Copies extends _xfa_object.IntegerObject { + constructor(attributes) { + super(CONFIG_NS_ID, "copies", 1, n => n >= 1); + } +} +class Creator extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "creator"); + } +} +class CurrentPage extends _xfa_object.IntegerObject { + constructor(attributes) { + super(CONFIG_NS_ID, "currentPage", 0, n => n >= 0); + } +} +class Data extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "data", true); + this.adjustData = null; + this.attributes = null; + this.incrementalLoad = null; + this.outputXSL = null; + this.range = null; + this.record = null; + this.startNode = null; + this.uri = null; + this.window = null; + this.xsl = null; + this.excludeNS = new _xfa_object.XFAObjectArray(); + this.transform = new _xfa_object.XFAObjectArray(); + } +} +class Debug extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "debug", true); + this.uri = null; + } +} +class DefaultTypeface extends _xfa_object.ContentObject { + constructor(attributes) { + super(CONFIG_NS_ID, "defaultTypeface"); + this.writingScript = (0, _utils.getStringOption)(attributes.writingScript, ["*", "Arabic", "Cyrillic", "EastEuropeanRoman", "Greek", "Hebrew", "Japanese", "Korean", "Roman", "SimplifiedChinese", "Thai", "TraditionalChinese", "Vietnamese"]); + } +} +class Destination extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "destination", ["pdf", "pcl", "ps", "webClient", "zpl"]); + } +} +class DocumentAssembly extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "documentAssembly"); + } +} +class Driver extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "driver", true); + this.name = attributes.name ? attributes.name.trim() : ""; + this.fontInfo = null; + this.xdc = null; + } +} +class DuplexOption extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "duplexOption", ["simplex", "duplexFlipLongEdge", "duplexFlipShortEdge"]); + } +} +class DynamicRender extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "dynamicRender", ["forbidden", "required"]); + } +} +class Embed extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "embed"); + } +} +class Encrypt extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "encrypt"); + } +} +class Encryption extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "encryption", true); + this.encrypt = null; + this.encryptionLevel = null; + this.permissions = null; + } +} +class EncryptionLevel extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "encryptionLevel", ["40bit", "128bit"]); + } +} +class Enforce extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "enforce"); + } +} +class Equate extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "equate"); + this.force = (0, _utils.getInteger)({ + data: attributes.force, + defaultValue: 1, + validate: n => n === 0 + }); + this.from = attributes.from || ""; + this.to = attributes.to || ""; + } +} +class EquateRange extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "equateRange"); + this.from = attributes.from || ""; + this.to = attributes.to || ""; + this._unicodeRange = attributes.unicodeRange || ""; + } + get unicodeRange() { + const ranges = []; + const unicodeRegex = /U\+([0-9a-fA-F]+)/; + const unicodeRange = this._unicodeRange; + for (let range of unicodeRange.split(",").map(x => x.trim()).filter(x => !!x)) { + range = range.split("-", 2).map(x => { + const found = x.match(unicodeRegex); + if (!found) { + return 0; + } + return parseInt(found[1], 16); + }); + if (range.length === 1) { + range.push(range[0]); + } + ranges.push(range); + } + return (0, _util.shadow)(this, "unicodeRange", ranges); + } +} +class Exclude extends _xfa_object.ContentObject { + constructor(attributes) { + super(CONFIG_NS_ID, "exclude"); + } + [_symbol_utils.$finalize]() { + this[_symbol_utils.$content] = this[_symbol_utils.$content].trim().split(/\s+/).filter(x => x && ["calculate", "close", "enter", "exit", "initialize", "ready", "validate"].includes(x)); + } +} +class ExcludeNS extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "excludeNS"); + } +} +class FlipLabel extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "flipLabel", ["usePrinterSetting", "on", "off"]); + } +} +class FontInfo extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "fontInfo", true); + this.embed = null; + this.map = null; + this.subsetBelow = null; + this.alwaysEmbed = new _xfa_object.XFAObjectArray(); + this.defaultTypeface = new _xfa_object.XFAObjectArray(); + this.neverEmbed = new _xfa_object.XFAObjectArray(); + } +} +class FormFieldFilling extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "formFieldFilling"); + } +} +class GroupParent extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "groupParent"); + } +} +class IfEmpty extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "ifEmpty", ["dataValue", "dataGroup", "ignore", "remove"]); + } +} +class IncludeXDPContent extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "includeXDPContent"); + } +} +class IncrementalLoad extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "incrementalLoad", ["none", "forwardOnly"]); + } +} +class IncrementalMerge extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "incrementalMerge"); + } +} +class Interactive extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "interactive"); + } +} +class Jog extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "jog", ["usePrinterSetting", "none", "pageSet"]); + } +} +class LabelPrinter extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "labelPrinter", true); + this.name = (0, _utils.getStringOption)(attributes.name, ["zpl", "dpl", "ipl", "tcpl"]); + this.batchOutput = null; + this.flipLabel = null; + this.fontInfo = null; + this.xdc = null; + } +} +class Layout extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "layout", ["paginate", "panel"]); + } +} +class Level extends _xfa_object.IntegerObject { + constructor(attributes) { + super(CONFIG_NS_ID, "level", 0, n => n > 0); + } +} +class Linearized extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "linearized"); + } +} +class Locale extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "locale"); + } +} +class LocaleSet extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "localeSet"); + } +} +class Log extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "log", true); + this.mode = null; + this.threshold = null; + this.to = null; + this.uri = null; + } +} +class MapElement extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "map", true); + this.equate = new _xfa_object.XFAObjectArray(); + this.equateRange = new _xfa_object.XFAObjectArray(); + } +} +class MediumInfo extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "mediumInfo", true); + this.map = null; + } +} +class Message extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "message", true); + this.msgId = null; + this.severity = null; + } +} +class Messaging extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "messaging", true); + this.message = new _xfa_object.XFAObjectArray(); + } +} +class Mode extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "mode", ["append", "overwrite"]); + } +} +class ModifyAnnots extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "modifyAnnots"); + } +} +class MsgId extends _xfa_object.IntegerObject { + constructor(attributes) { + super(CONFIG_NS_ID, "msgId", 1, n => n >= 1); + } +} +class NameAttr extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "nameAttr"); + } +} +class NeverEmbed extends _xfa_object.ContentObject { + constructor(attributes) { + super(CONFIG_NS_ID, "neverEmbed"); + } +} +class NumberOfCopies extends _xfa_object.IntegerObject { + constructor(attributes) { + super(CONFIG_NS_ID, "numberOfCopies", null, n => n >= 2 && n <= 5); + } +} +class OpenAction extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "openAction", true); + this.destination = null; + } +} +class Output extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "output", true); + this.to = null; + this.type = null; + this.uri = null; + } +} +class OutputBin extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "outputBin"); + } +} +class OutputXSL extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "outputXSL", true); + this.uri = null; + } +} +class Overprint extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "overprint", ["none", "both", "draw", "field"]); + } +} +class Packets extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "packets"); + } + [_symbol_utils.$finalize]() { + if (this[_symbol_utils.$content] === "*") { + return; + } + this[_symbol_utils.$content] = this[_symbol_utils.$content].trim().split(/\s+/).filter(x => ["config", "datasets", "template", "xfdf", "xslt"].includes(x)); + } +} +class PageOffset extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "pageOffset"); + this.x = (0, _utils.getInteger)({ + data: attributes.x, + defaultValue: "useXDCSetting", + validate: n => true + }); + this.y = (0, _utils.getInteger)({ + data: attributes.y, + defaultValue: "useXDCSetting", + validate: n => true + }); + } +} +class PageRange extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "pageRange"); + } + [_symbol_utils.$finalize]() { + const numbers = this[_symbol_utils.$content].trim().split(/\s+/).map(x => parseInt(x, 10)); + const ranges = []; + for (let i = 0, ii = numbers.length; i < ii; i += 2) { + ranges.push(numbers.slice(i, i + 2)); + } + this[_symbol_utils.$content] = ranges; + } +} +class Pagination extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "pagination", ["simplex", "duplexShortEdge", "duplexLongEdge"]); + } +} +class PaginationOverride extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "paginationOverride", ["none", "forceDuplex", "forceDuplexLongEdge", "forceDuplexShortEdge", "forceSimplex"]); + } +} +class Part extends _xfa_object.IntegerObject { + constructor(attributes) { + super(CONFIG_NS_ID, "part", 1, n => false); + } +} +class Pcl extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "pcl", true); + this.name = attributes.name || ""; + this.batchOutput = null; + this.fontInfo = null; + this.jog = null; + this.mediumInfo = null; + this.outputBin = null; + this.pageOffset = null; + this.staple = null; + this.xdc = null; + } +} +class Pdf extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "pdf", true); + this.name = attributes.name || ""; + this.adobeExtensionLevel = null; + this.batchOutput = null; + this.compression = null; + this.creator = null; + this.encryption = null; + this.fontInfo = null; + this.interactive = null; + this.linearized = null; + this.openAction = null; + this.pdfa = null; + this.producer = null; + this.renderPolicy = null; + this.scriptModel = null; + this.silentPrint = null; + this.submitFormat = null; + this.tagged = null; + this.version = null; + this.viewerPreferences = null; + this.xdc = null; + } +} +class Pdfa extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "pdfa", true); + this.amd = null; + this.conformance = null; + this.includeXDPContent = null; + this.part = null; + } +} +class Permissions extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "permissions", true); + this.accessibleContent = null; + this.change = null; + this.contentCopy = null; + this.documentAssembly = null; + this.formFieldFilling = null; + this.modifyAnnots = null; + this.plaintextMetadata = null; + this.print = null; + this.printHighQuality = null; + } +} +class PickTrayByPDFSize extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "pickTrayByPDFSize"); + } +} +class Picture extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "picture"); + } +} +class PlaintextMetadata extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "plaintextMetadata"); + } +} +class Presence extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "presence", ["preserve", "dissolve", "dissolveStructure", "ignore", "remove"]); + } +} +class Present extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "present", true); + this.behaviorOverride = null; + this.cache = null; + this.common = null; + this.copies = null; + this.destination = null; + this.incrementalMerge = null; + this.layout = null; + this.output = null; + this.overprint = null; + this.pagination = null; + this.paginationOverride = null; + this.script = null; + this.validate = null; + this.xdp = null; + this.driver = new _xfa_object.XFAObjectArray(); + this.labelPrinter = new _xfa_object.XFAObjectArray(); + this.pcl = new _xfa_object.XFAObjectArray(); + this.pdf = new _xfa_object.XFAObjectArray(); + this.ps = new _xfa_object.XFAObjectArray(); + this.submitUrl = new _xfa_object.XFAObjectArray(); + this.webClient = new _xfa_object.XFAObjectArray(); + this.zpl = new _xfa_object.XFAObjectArray(); + } +} +class Print extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "print"); + } +} +class PrintHighQuality extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "printHighQuality"); + } +} +class PrintScaling extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "printScaling", ["appdefault", "noScaling"]); + } +} +class PrinterName extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "printerName"); + } +} +class Producer extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "producer"); + } +} +class Ps extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "ps", true); + this.name = attributes.name || ""; + this.batchOutput = null; + this.fontInfo = null; + this.jog = null; + this.mediumInfo = null; + this.outputBin = null; + this.staple = null; + this.xdc = null; + } +} +class Range extends _xfa_object.ContentObject { + constructor(attributes) { + super(CONFIG_NS_ID, "range"); + } + [_symbol_utils.$finalize]() { + this[_symbol_utils.$content] = this[_symbol_utils.$content].trim().split(/\s*,\s*/, 2).map(range => range.split("-").map(x => parseInt(x.trim(), 10))).filter(range => range.every(x => !isNaN(x))).map(range => { + if (range.length === 1) { + range.push(range[0]); + } + return range; + }); + } +} +class Record extends _xfa_object.ContentObject { + constructor(attributes) { + super(CONFIG_NS_ID, "record"); + } + [_symbol_utils.$finalize]() { + this[_symbol_utils.$content] = this[_symbol_utils.$content].trim(); + const n = parseInt(this[_symbol_utils.$content], 10); + if (!isNaN(n) && n >= 0) { + this[_symbol_utils.$content] = n; + } + } +} +class Relevant extends _xfa_object.ContentObject { + constructor(attributes) { + super(CONFIG_NS_ID, "relevant"); + } + [_symbol_utils.$finalize]() { + this[_symbol_utils.$content] = this[_symbol_utils.$content].trim().split(/\s+/); + } +} +class Rename extends _xfa_object.ContentObject { + constructor(attributes) { + super(CONFIG_NS_ID, "rename"); + } + [_symbol_utils.$finalize]() { + this[_symbol_utils.$content] = this[_symbol_utils.$content].trim(); + if (this[_symbol_utils.$content].toLowerCase().startsWith("xml") || new RegExp("[\\p{L}_][\\p{L}\\d._\\p{M}-]*", "u").test(this[_symbol_utils.$content])) { + (0, _util.warn)("XFA - Rename: invalid XFA name"); + } + } +} +class RenderPolicy extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "renderPolicy", ["server", "client"]); + } +} +class RunScripts extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "runScripts", ["both", "client", "none", "server"]); + } +} +class Script extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "script", true); + this.currentPage = null; + this.exclude = null; + this.runScripts = null; + } +} +class ScriptModel extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "scriptModel", ["XFA", "none"]); + } +} +class Severity extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "severity", ["ignore", "error", "information", "trace", "warning"]); + } +} +class SilentPrint extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "silentPrint", true); + this.addSilentPrint = null; + this.printerName = null; + } +} +class Staple extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "staple"); + this.mode = (0, _utils.getStringOption)(attributes.mode, ["usePrinterSetting", "on", "off"]); + } +} +class StartNode extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "startNode"); + } +} +class StartPage extends _xfa_object.IntegerObject { + constructor(attributes) { + super(CONFIG_NS_ID, "startPage", 0, n => true); + } +} +class SubmitFormat extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "submitFormat", ["html", "delegate", "fdf", "xml", "pdf"]); + } +} +class SubmitUrl extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "submitUrl"); + } +} +class SubsetBelow extends _xfa_object.IntegerObject { + constructor(attributes) { + super(CONFIG_NS_ID, "subsetBelow", 100, n => n >= 0 && n <= 100); + } +} +class SuppressBanner extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "suppressBanner"); + } +} +class Tagged extends _xfa_object.Option01 { + constructor(attributes) { + super(CONFIG_NS_ID, "tagged"); + } +} +class Template extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "template", true); + this.base = null; + this.relevant = null; + this.startPage = null; + this.uri = null; + this.xsl = null; + } +} +class Threshold extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "threshold", ["trace", "error", "information", "warning"]); + } +} +class To extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "to", ["null", "memory", "stderr", "stdout", "system", "uri"]); + } +} +class TemplateCache extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "templateCache"); + this.maxEntries = (0, _utils.getInteger)({ + data: attributes.maxEntries, + defaultValue: 5, + validate: n => n >= 0 + }); + } +} +class Trace extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "trace", true); + this.area = new _xfa_object.XFAObjectArray(); + } +} +class Transform extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "transform", true); + this.groupParent = null; + this.ifEmpty = null; + this.nameAttr = null; + this.picture = null; + this.presence = null; + this.rename = null; + this.whitespace = null; + } +} +class Type extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "type", ["none", "ascii85", "asciiHex", "ccittfax", "flate", "lzw", "runLength", "native", "xdp", "mergedXDP"]); + } +} +class Uri extends _xfa_object.StringObject { + constructor(attributes) { + super(CONFIG_NS_ID, "uri"); + } +} +class Validate extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "validate", ["preSubmit", "prePrint", "preExecute", "preSave"]); + } +} +class ValidateApprovalSignatures extends _xfa_object.ContentObject { + constructor(attributes) { + super(CONFIG_NS_ID, "validateApprovalSignatures"); + } + [_symbol_utils.$finalize]() { + this[_symbol_utils.$content] = this[_symbol_utils.$content].trim().split(/\s+/).filter(x => ["docReady", "postSign"].includes(x)); + } +} +class ValidationMessaging extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "validationMessaging", ["allMessagesIndividually", "allMessagesTogether", "firstMessageOnly", "noMessages"]); + } +} +class Version extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "version", ["1.7", "1.6", "1.5", "1.4", "1.3", "1.2"]); + } +} +class VersionControl extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "VersionControl"); + this.outputBelow = (0, _utils.getStringOption)(attributes.outputBelow, ["warn", "error", "update"]); + this.sourceAbove = (0, _utils.getStringOption)(attributes.sourceAbove, ["warn", "error"]); + this.sourceBelow = (0, _utils.getStringOption)(attributes.sourceBelow, ["update", "maintain"]); + } +} +class ViewerPreferences extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "viewerPreferences", true); + this.ADBE_JSConsole = null; + this.ADBE_JSDebugger = null; + this.addViewerPreferences = null; + this.duplexOption = null; + this.enforce = null; + this.numberOfCopies = null; + this.pageRange = null; + this.pickTrayByPDFSize = null; + this.printScaling = null; + } +} +class WebClient extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "webClient", true); + this.name = attributes.name ? attributes.name.trim() : ""; + this.fontInfo = null; + this.xdc = null; + } +} +class Whitespace extends _xfa_object.OptionObject { + constructor(attributes) { + super(CONFIG_NS_ID, "whitespace", ["preserve", "ltrim", "normalize", "rtrim", "trim"]); + } +} +class Window extends _xfa_object.ContentObject { + constructor(attributes) { + super(CONFIG_NS_ID, "window"); + } + [_symbol_utils.$finalize]() { + const pair = this[_symbol_utils.$content].trim().split(/\s*,\s*/, 2).map(x => parseInt(x, 10)); + if (pair.some(x => isNaN(x))) { + this[_symbol_utils.$content] = [0, 0]; + return; + } + if (pair.length === 1) { + pair.push(pair[0]); + } + this[_symbol_utils.$content] = pair; + } +} +class Xdc extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "xdc", true); + this.uri = new _xfa_object.XFAObjectArray(); + this.xsl = new _xfa_object.XFAObjectArray(); + } +} +class Xdp extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "xdp", true); + this.packets = null; + } +} +class Xsl extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "xsl", true); + this.debug = null; + this.uri = null; + } +} +class Zpl extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONFIG_NS_ID, "zpl", true); + this.name = attributes.name ? attributes.name.trim() : ""; + this.batchOutput = null; + this.flipLabel = null; + this.fontInfo = null; + this.xdc = null; + } +} +class ConfigNamespace { + static [_namespaces.$buildXFAObject](name, attributes) { + if (ConfigNamespace.hasOwnProperty(name)) { + return ConfigNamespace[name](attributes); + } + return undefined; + } + static acrobat(attrs) { + return new Acrobat(attrs); + } + static acrobat7(attrs) { + return new Acrobat7(attrs); + } + static ADBE_JSConsole(attrs) { + return new ADBE_JSConsole(attrs); + } + static ADBE_JSDebugger(attrs) { + return new ADBE_JSDebugger(attrs); + } + static addSilentPrint(attrs) { + return new AddSilentPrint(attrs); + } + static addViewerPreferences(attrs) { + return new AddViewerPreferences(attrs); + } + static adjustData(attrs) { + return new AdjustData(attrs); + } + static adobeExtensionLevel(attrs) { + return new AdobeExtensionLevel(attrs); + } + static agent(attrs) { + return new Agent(attrs); + } + static alwaysEmbed(attrs) { + return new AlwaysEmbed(attrs); + } + static amd(attrs) { + return new Amd(attrs); + } + static area(attrs) { + return new Area(attrs); + } + static attributes(attrs) { + return new Attributes(attrs); + } + static autoSave(attrs) { + return new AutoSave(attrs); + } + static base(attrs) { + return new Base(attrs); + } + static batchOutput(attrs) { + return new BatchOutput(attrs); + } + static behaviorOverride(attrs) { + return new BehaviorOverride(attrs); + } + static cache(attrs) { + return new Cache(attrs); + } + static change(attrs) { + return new Change(attrs); + } + static common(attrs) { + return new Common(attrs); + } + static compress(attrs) { + return new Compress(attrs); + } + static compressLogicalStructure(attrs) { + return new CompressLogicalStructure(attrs); + } + static compressObjectStream(attrs) { + return new CompressObjectStream(attrs); + } + static compression(attrs) { + return new Compression(attrs); + } + static config(attrs) { + return new Config(attrs); + } + static conformance(attrs) { + return new Conformance(attrs); + } + static contentCopy(attrs) { + return new ContentCopy(attrs); + } + static copies(attrs) { + return new Copies(attrs); + } + static creator(attrs) { + return new Creator(attrs); + } + static currentPage(attrs) { + return new CurrentPage(attrs); + } + static data(attrs) { + return new Data(attrs); + } + static debug(attrs) { + return new Debug(attrs); + } + static defaultTypeface(attrs) { + return new DefaultTypeface(attrs); + } + static destination(attrs) { + return new Destination(attrs); + } + static documentAssembly(attrs) { + return new DocumentAssembly(attrs); + } + static driver(attrs) { + return new Driver(attrs); + } + static duplexOption(attrs) { + return new DuplexOption(attrs); + } + static dynamicRender(attrs) { + return new DynamicRender(attrs); + } + static embed(attrs) { + return new Embed(attrs); + } + static encrypt(attrs) { + return new Encrypt(attrs); + } + static encryption(attrs) { + return new Encryption(attrs); + } + static encryptionLevel(attrs) { + return new EncryptionLevel(attrs); + } + static enforce(attrs) { + return new Enforce(attrs); + } + static equate(attrs) { + return new Equate(attrs); + } + static equateRange(attrs) { + return new EquateRange(attrs); + } + static exclude(attrs) { + return new Exclude(attrs); + } + static excludeNS(attrs) { + return new ExcludeNS(attrs); + } + static flipLabel(attrs) { + return new FlipLabel(attrs); + } + static fontInfo(attrs) { + return new FontInfo(attrs); + } + static formFieldFilling(attrs) { + return new FormFieldFilling(attrs); + } + static groupParent(attrs) { + return new GroupParent(attrs); + } + static ifEmpty(attrs) { + return new IfEmpty(attrs); + } + static includeXDPContent(attrs) { + return new IncludeXDPContent(attrs); + } + static incrementalLoad(attrs) { + return new IncrementalLoad(attrs); + } + static incrementalMerge(attrs) { + return new IncrementalMerge(attrs); + } + static interactive(attrs) { + return new Interactive(attrs); + } + static jog(attrs) { + return new Jog(attrs); + } + static labelPrinter(attrs) { + return new LabelPrinter(attrs); + } + static layout(attrs) { + return new Layout(attrs); + } + static level(attrs) { + return new Level(attrs); + } + static linearized(attrs) { + return new Linearized(attrs); + } + static locale(attrs) { + return new Locale(attrs); + } + static localeSet(attrs) { + return new LocaleSet(attrs); + } + static log(attrs) { + return new Log(attrs); + } + static map(attrs) { + return new MapElement(attrs); + } + static mediumInfo(attrs) { + return new MediumInfo(attrs); + } + static message(attrs) { + return new Message(attrs); + } + static messaging(attrs) { + return new Messaging(attrs); + } + static mode(attrs) { + return new Mode(attrs); + } + static modifyAnnots(attrs) { + return new ModifyAnnots(attrs); + } + static msgId(attrs) { + return new MsgId(attrs); + } + static nameAttr(attrs) { + return new NameAttr(attrs); + } + static neverEmbed(attrs) { + return new NeverEmbed(attrs); + } + static numberOfCopies(attrs) { + return new NumberOfCopies(attrs); + } + static openAction(attrs) { + return new OpenAction(attrs); + } + static output(attrs) { + return new Output(attrs); + } + static outputBin(attrs) { + return new OutputBin(attrs); + } + static outputXSL(attrs) { + return new OutputXSL(attrs); + } + static overprint(attrs) { + return new Overprint(attrs); + } + static packets(attrs) { + return new Packets(attrs); + } + static pageOffset(attrs) { + return new PageOffset(attrs); + } + static pageRange(attrs) { + return new PageRange(attrs); + } + static pagination(attrs) { + return new Pagination(attrs); + } + static paginationOverride(attrs) { + return new PaginationOverride(attrs); + } + static part(attrs) { + return new Part(attrs); + } + static pcl(attrs) { + return new Pcl(attrs); + } + static pdf(attrs) { + return new Pdf(attrs); + } + static pdfa(attrs) { + return new Pdfa(attrs); + } + static permissions(attrs) { + return new Permissions(attrs); + } + static pickTrayByPDFSize(attrs) { + return new PickTrayByPDFSize(attrs); + } + static picture(attrs) { + return new Picture(attrs); + } + static plaintextMetadata(attrs) { + return new PlaintextMetadata(attrs); + } + static presence(attrs) { + return new Presence(attrs); + } + static present(attrs) { + return new Present(attrs); + } + static print(attrs) { + return new Print(attrs); + } + static printHighQuality(attrs) { + return new PrintHighQuality(attrs); + } + static printScaling(attrs) { + return new PrintScaling(attrs); + } + static printerName(attrs) { + return new PrinterName(attrs); + } + static producer(attrs) { + return new Producer(attrs); + } + static ps(attrs) { + return new Ps(attrs); + } + static range(attrs) { + return new Range(attrs); + } + static record(attrs) { + return new Record(attrs); + } + static relevant(attrs) { + return new Relevant(attrs); + } + static rename(attrs) { + return new Rename(attrs); + } + static renderPolicy(attrs) { + return new RenderPolicy(attrs); + } + static runScripts(attrs) { + return new RunScripts(attrs); + } + static script(attrs) { + return new Script(attrs); + } + static scriptModel(attrs) { + return new ScriptModel(attrs); + } + static severity(attrs) { + return new Severity(attrs); + } + static silentPrint(attrs) { + return new SilentPrint(attrs); + } + static staple(attrs) { + return new Staple(attrs); + } + static startNode(attrs) { + return new StartNode(attrs); + } + static startPage(attrs) { + return new StartPage(attrs); + } + static submitFormat(attrs) { + return new SubmitFormat(attrs); + } + static submitUrl(attrs) { + return new SubmitUrl(attrs); + } + static subsetBelow(attrs) { + return new SubsetBelow(attrs); + } + static suppressBanner(attrs) { + return new SuppressBanner(attrs); + } + static tagged(attrs) { + return new Tagged(attrs); + } + static template(attrs) { + return new Template(attrs); + } + static templateCache(attrs) { + return new TemplateCache(attrs); + } + static threshold(attrs) { + return new Threshold(attrs); + } + static to(attrs) { + return new To(attrs); + } + static trace(attrs) { + return new Trace(attrs); + } + static transform(attrs) { + return new Transform(attrs); + } + static type(attrs) { + return new Type(attrs); + } + static uri(attrs) { + return new Uri(attrs); + } + static validate(attrs) { + return new Validate(attrs); + } + static validateApprovalSignatures(attrs) { + return new ValidateApprovalSignatures(attrs); + } + static validationMessaging(attrs) { + return new ValidationMessaging(attrs); + } + static version(attrs) { + return new Version(attrs); + } + static versionControl(attrs) { + return new VersionControl(attrs); + } + static viewerPreferences(attrs) { + return new ViewerPreferences(attrs); + } + static webClient(attrs) { + return new WebClient(attrs); + } + static whitespace(attrs) { + return new Whitespace(attrs); + } + static window(attrs) { + return new Window(attrs); + } + static xdc(attrs) { + return new Xdc(attrs); + } + static xdp(attrs) { + return new Xdp(attrs); + } + static xsl(attrs) { + return new Xsl(attrs); + } + static zpl(attrs) { + return new Zpl(attrs); + } +} +exports.ConfigNamespace = ConfigNamespace; + +/***/ }), +/* 94 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ConnectionSetNamespace = void 0; +var _namespaces = __w_pdfjs_require__(81); +var _xfa_object = __w_pdfjs_require__(87); +const CONNECTION_SET_NS_ID = _namespaces.NamespaceIds.connectionSet.id; +class ConnectionSet extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONNECTION_SET_NS_ID, "connectionSet", true); + this.wsdlConnection = new _xfa_object.XFAObjectArray(); + this.xmlConnection = new _xfa_object.XFAObjectArray(); + this.xsdConnection = new _xfa_object.XFAObjectArray(); + } +} +class EffectiveInputPolicy extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONNECTION_SET_NS_ID, "effectiveInputPolicy"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class EffectiveOutputPolicy extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONNECTION_SET_NS_ID, "effectiveOutputPolicy"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Operation extends _xfa_object.StringObject { + constructor(attributes) { + super(CONNECTION_SET_NS_ID, "operation"); + this.id = attributes.id || ""; + this.input = attributes.input || ""; + this.name = attributes.name || ""; + this.output = attributes.output || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class RootElement extends _xfa_object.StringObject { + constructor(attributes) { + super(CONNECTION_SET_NS_ID, "rootElement"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class SoapAction extends _xfa_object.StringObject { + constructor(attributes) { + super(CONNECTION_SET_NS_ID, "soapAction"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class SoapAddress extends _xfa_object.StringObject { + constructor(attributes) { + super(CONNECTION_SET_NS_ID, "soapAddress"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class Uri extends _xfa_object.StringObject { + constructor(attributes) { + super(CONNECTION_SET_NS_ID, "uri"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class WsdlAddress extends _xfa_object.StringObject { + constructor(attributes) { + super(CONNECTION_SET_NS_ID, "wsdlAddress"); + this.id = attributes.id || ""; + this.name = attributes.name || ""; + this.use = attributes.use || ""; + this.usehref = attributes.usehref || ""; + } +} +class WsdlConnection extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONNECTION_SET_NS_ID, "wsdlConnection", true); + this.dataDescription = attributes.dataDescription || ""; + this.name = attributes.name || ""; + this.effectiveInputPolicy = null; + this.effectiveOutputPolicy = null; + this.operation = null; + this.soapAction = null; + this.soapAddress = null; + this.wsdlAddress = null; + } +} +class XmlConnection extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONNECTION_SET_NS_ID, "xmlConnection", true); + this.dataDescription = attributes.dataDescription || ""; + this.name = attributes.name || ""; + this.uri = null; + } +} +class XsdConnection extends _xfa_object.XFAObject { + constructor(attributes) { + super(CONNECTION_SET_NS_ID, "xsdConnection", true); + this.dataDescription = attributes.dataDescription || ""; + this.name = attributes.name || ""; + this.rootElement = null; + this.uri = null; + } +} +class ConnectionSetNamespace { + static [_namespaces.$buildXFAObject](name, attributes) { + if (ConnectionSetNamespace.hasOwnProperty(name)) { + return ConnectionSetNamespace[name](attributes); + } + return undefined; + } + static connectionSet(attrs) { + return new ConnectionSet(attrs); + } + static effectiveInputPolicy(attrs) { + return new EffectiveInputPolicy(attrs); + } + static effectiveOutputPolicy(attrs) { + return new EffectiveOutputPolicy(attrs); + } + static operation(attrs) { + return new Operation(attrs); + } + static rootElement(attrs) { + return new RootElement(attrs); + } + static soapAction(attrs) { + return new SoapAction(attrs); + } + static soapAddress(attrs) { + return new SoapAddress(attrs); + } + static uri(attrs) { + return new Uri(attrs); + } + static wsdlAddress(attrs) { + return new WsdlAddress(attrs); + } + static wsdlConnection(attrs) { + return new WsdlConnection(attrs); + } + static xmlConnection(attrs) { + return new XmlConnection(attrs); + } + static xsdConnection(attrs) { + return new XsdConnection(attrs); + } +} +exports.ConnectionSetNamespace = ConnectionSetNamespace; + +/***/ }), +/* 95 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.DatasetsNamespace = void 0; +var _symbol_utils = __w_pdfjs_require__(78); +var _namespaces = __w_pdfjs_require__(81); +var _xfa_object = __w_pdfjs_require__(87); +const DATASETS_NS_ID = _namespaces.NamespaceIds.datasets.id; +class Data extends _xfa_object.XmlObject { + constructor(attributes) { + super(DATASETS_NS_ID, "data", attributes); + } + [_symbol_utils.$isNsAgnostic]() { + return true; + } +} +class Datasets extends _xfa_object.XFAObject { + constructor(attributes) { + super(DATASETS_NS_ID, "datasets", true); + this.data = null; + this.Signature = null; + } + [_symbol_utils.$onChild](child) { + const name = child[_symbol_utils.$nodeName]; + if (name === "data" && child[_symbol_utils.$namespaceId] === DATASETS_NS_ID || name === "Signature" && child[_symbol_utils.$namespaceId] === _namespaces.NamespaceIds.signature.id) { + this[name] = child; + } + this[_symbol_utils.$appendChild](child); + } +} +class DatasetsNamespace { + static [_namespaces.$buildXFAObject](name, attributes) { + if (DatasetsNamespace.hasOwnProperty(name)) { + return DatasetsNamespace[name](attributes); + } + return undefined; + } + static datasets(attributes) { + return new Datasets(attributes); + } + static data(attributes) { + return new Data(attributes); + } +} +exports.DatasetsNamespace = DatasetsNamespace; + +/***/ }), +/* 96 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.LocaleSetNamespace = void 0; +var _namespaces = __w_pdfjs_require__(81); +var _xfa_object = __w_pdfjs_require__(87); +var _utils = __w_pdfjs_require__(84); +const LOCALE_SET_NS_ID = _namespaces.NamespaceIds.localeSet.id; +class CalendarSymbols extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "calendarSymbols", true); + this.name = "gregorian"; + this.dayNames = new _xfa_object.XFAObjectArray(2); + this.eraNames = null; + this.meridiemNames = null; + this.monthNames = new _xfa_object.XFAObjectArray(2); + } +} +class CurrencySymbol extends _xfa_object.StringObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "currencySymbol"); + this.name = (0, _utils.getStringOption)(attributes.name, ["symbol", "isoname", "decimal"]); + } +} +class CurrencySymbols extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "currencySymbols", true); + this.currencySymbol = new _xfa_object.XFAObjectArray(3); + } +} +class DatePattern extends _xfa_object.StringObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "datePattern"); + this.name = (0, _utils.getStringOption)(attributes.name, ["full", "long", "med", "short"]); + } +} +class DatePatterns extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "datePatterns", true); + this.datePattern = new _xfa_object.XFAObjectArray(4); + } +} +class DateTimeSymbols extends _xfa_object.ContentObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "dateTimeSymbols"); + } +} +class Day extends _xfa_object.StringObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "day"); + } +} +class DayNames extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "dayNames", true); + this.abbr = (0, _utils.getInteger)({ + data: attributes.abbr, + defaultValue: 0, + validate: x => x === 1 + }); + this.day = new _xfa_object.XFAObjectArray(7); + } +} +class Era extends _xfa_object.StringObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "era"); + } +} +class EraNames extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "eraNames", true); + this.era = new _xfa_object.XFAObjectArray(2); + } +} +class Locale extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "locale", true); + this.desc = attributes.desc || ""; + this.name = "isoname"; + this.calendarSymbols = null; + this.currencySymbols = null; + this.datePatterns = null; + this.dateTimeSymbols = null; + this.numberPatterns = null; + this.numberSymbols = null; + this.timePatterns = null; + this.typeFaces = null; + } +} +class LocaleSet extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "localeSet", true); + this.locale = new _xfa_object.XFAObjectArray(); + } +} +class Meridiem extends _xfa_object.StringObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "meridiem"); + } +} +class MeridiemNames extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "meridiemNames", true); + this.meridiem = new _xfa_object.XFAObjectArray(2); + } +} +class Month extends _xfa_object.StringObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "month"); + } +} +class MonthNames extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "monthNames", true); + this.abbr = (0, _utils.getInteger)({ + data: attributes.abbr, + defaultValue: 0, + validate: x => x === 1 + }); + this.month = new _xfa_object.XFAObjectArray(12); + } +} +class NumberPattern extends _xfa_object.StringObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "numberPattern"); + this.name = (0, _utils.getStringOption)(attributes.name, ["full", "long", "med", "short"]); + } +} +class NumberPatterns extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "numberPatterns", true); + this.numberPattern = new _xfa_object.XFAObjectArray(4); + } +} +class NumberSymbol extends _xfa_object.StringObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "numberSymbol"); + this.name = (0, _utils.getStringOption)(attributes.name, ["decimal", "grouping", "percent", "minus", "zero"]); + } +} +class NumberSymbols extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "numberSymbols", true); + this.numberSymbol = new _xfa_object.XFAObjectArray(5); + } +} +class TimePattern extends _xfa_object.StringObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "timePattern"); + this.name = (0, _utils.getStringOption)(attributes.name, ["full", "long", "med", "short"]); + } +} +class TimePatterns extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "timePatterns", true); + this.timePattern = new _xfa_object.XFAObjectArray(4); + } +} +class TypeFace extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "typeFace", true); + this.name = attributes.name | ""; + } +} +class TypeFaces extends _xfa_object.XFAObject { + constructor(attributes) { + super(LOCALE_SET_NS_ID, "typeFaces", true); + this.typeFace = new _xfa_object.XFAObjectArray(); + } +} +class LocaleSetNamespace { + static [_namespaces.$buildXFAObject](name, attributes) { + if (LocaleSetNamespace.hasOwnProperty(name)) { + return LocaleSetNamespace[name](attributes); + } + return undefined; + } + static calendarSymbols(attrs) { + return new CalendarSymbols(attrs); + } + static currencySymbol(attrs) { + return new CurrencySymbol(attrs); + } + static currencySymbols(attrs) { + return new CurrencySymbols(attrs); + } + static datePattern(attrs) { + return new DatePattern(attrs); + } + static datePatterns(attrs) { + return new DatePatterns(attrs); + } + static dateTimeSymbols(attrs) { + return new DateTimeSymbols(attrs); + } + static day(attrs) { + return new Day(attrs); + } + static dayNames(attrs) { + return new DayNames(attrs); + } + static era(attrs) { + return new Era(attrs); + } + static eraNames(attrs) { + return new EraNames(attrs); + } + static locale(attrs) { + return new Locale(attrs); + } + static localeSet(attrs) { + return new LocaleSet(attrs); + } + static meridiem(attrs) { + return new Meridiem(attrs); + } + static meridiemNames(attrs) { + return new MeridiemNames(attrs); + } + static month(attrs) { + return new Month(attrs); + } + static monthNames(attrs) { + return new MonthNames(attrs); + } + static numberPattern(attrs) { + return new NumberPattern(attrs); + } + static numberPatterns(attrs) { + return new NumberPatterns(attrs); + } + static numberSymbol(attrs) { + return new NumberSymbol(attrs); + } + static numberSymbols(attrs) { + return new NumberSymbols(attrs); + } + static timePattern(attrs) { + return new TimePattern(attrs); + } + static timePatterns(attrs) { + return new TimePatterns(attrs); + } + static typeFace(attrs) { + return new TypeFace(attrs); + } + static typeFaces(attrs) { + return new TypeFaces(attrs); + } +} +exports.LocaleSetNamespace = LocaleSetNamespace; + +/***/ }), +/* 97 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.SignatureNamespace = void 0; +var _namespaces = __w_pdfjs_require__(81); +var _xfa_object = __w_pdfjs_require__(87); +const SIGNATURE_NS_ID = _namespaces.NamespaceIds.signature.id; +class Signature extends _xfa_object.XFAObject { + constructor(attributes) { + super(SIGNATURE_NS_ID, "signature", true); + } +} +class SignatureNamespace { + static [_namespaces.$buildXFAObject](name, attributes) { + if (SignatureNamespace.hasOwnProperty(name)) { + return SignatureNamespace[name](attributes); + } + return undefined; + } + static signature(attributes) { + return new Signature(attributes); + } +} +exports.SignatureNamespace = SignatureNamespace; + +/***/ }), +/* 98 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.StylesheetNamespace = void 0; +var _namespaces = __w_pdfjs_require__(81); +var _xfa_object = __w_pdfjs_require__(87); +const STYLESHEET_NS_ID = _namespaces.NamespaceIds.stylesheet.id; +class Stylesheet extends _xfa_object.XFAObject { + constructor(attributes) { + super(STYLESHEET_NS_ID, "stylesheet", true); + } +} +class StylesheetNamespace { + static [_namespaces.$buildXFAObject](name, attributes) { + if (StylesheetNamespace.hasOwnProperty(name)) { + return StylesheetNamespace[name](attributes); + } + return undefined; + } + static stylesheet(attributes) { + return new Stylesheet(attributes); + } +} +exports.StylesheetNamespace = StylesheetNamespace; + +/***/ }), +/* 99 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.XdpNamespace = void 0; +var _namespaces = __w_pdfjs_require__(81); +var _symbol_utils = __w_pdfjs_require__(78); +var _xfa_object = __w_pdfjs_require__(87); +const XDP_NS_ID = _namespaces.NamespaceIds.xdp.id; +class Xdp extends _xfa_object.XFAObject { + constructor(attributes) { + super(XDP_NS_ID, "xdp", true); + this.uuid = attributes.uuid || ""; + this.timeStamp = attributes.timeStamp || ""; + this.config = null; + this.connectionSet = null; + this.datasets = null; + this.localeSet = null; + this.stylesheet = new _xfa_object.XFAObjectArray(); + this.template = null; + } + [_symbol_utils.$onChildCheck](child) { + const ns = _namespaces.NamespaceIds[child[_symbol_utils.$nodeName]]; + return ns && child[_symbol_utils.$namespaceId] === ns.id; + } +} +class XdpNamespace { + static [_namespaces.$buildXFAObject](name, attributes) { + if (XdpNamespace.hasOwnProperty(name)) { + return XdpNamespace[name](attributes); + } + return undefined; + } + static xdp(attributes) { + return new Xdp(attributes); + } +} +exports.XdpNamespace = XdpNamespace; + +/***/ }), +/* 100 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.XhtmlNamespace = void 0; +var _symbol_utils = __w_pdfjs_require__(78); +var _namespaces = __w_pdfjs_require__(81); +var _html_utils = __w_pdfjs_require__(83); +var _utils = __w_pdfjs_require__(84); +var _xfa_object = __w_pdfjs_require__(87); +const XHTML_NS_ID = _namespaces.NamespaceIds.xhtml.id; +const $richText = Symbol(); +const VALID_STYLES = new Set(["color", "font", "font-family", "font-size", "font-stretch", "font-style", "font-weight", "margin", "margin-bottom", "margin-left", "margin-right", "margin-top", "letter-spacing", "line-height", "orphans", "page-break-after", "page-break-before", "page-break-inside", "tab-interval", "tab-stop", "text-align", "text-decoration", "text-indent", "vertical-align", "widows", "kerning-mode", "xfa-font-horizontal-scale", "xfa-font-vertical-scale", "xfa-spacerun", "xfa-tab-stops"]); +const StyleMapping = new Map([["page-break-after", "breakAfter"], ["page-break-before", "breakBefore"], ["page-break-inside", "breakInside"], ["kerning-mode", value => value === "none" ? "none" : "normal"], ["xfa-font-horizontal-scale", value => `scaleX(${Math.max(0, Math.min(parseInt(value) / 100)).toFixed(2)})`], ["xfa-font-vertical-scale", value => `scaleY(${Math.max(0, Math.min(parseInt(value) / 100)).toFixed(2)})`], ["xfa-spacerun", ""], ["xfa-tab-stops", ""], ["font-size", (value, original) => { + value = original.fontSize = (0, _utils.getMeasurement)(value); + return (0, _html_utils.measureToString)(0.99 * value); +}], ["letter-spacing", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["line-height", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["margin", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["margin-bottom", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["margin-left", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["margin-right", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["margin-top", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["text-indent", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))], ["font-family", value => value], ["vertical-align", value => (0, _html_utils.measureToString)((0, _utils.getMeasurement)(value))]]); +const spacesRegExp = /\s+/g; +const crlfRegExp = /[\r\n]+/g; +const crlfForRichTextRegExp = /\r\n?/g; +function mapStyle(styleStr, node, richText) { + const style = Object.create(null); + if (!styleStr) { + return style; + } + const original = Object.create(null); + for (const [key, value] of styleStr.split(";").map(s => s.split(":", 2))) { + const mapping = StyleMapping.get(key); + if (mapping === "") { + continue; + } + let newValue = value; + if (mapping) { + newValue = typeof mapping === "string" ? mapping : mapping(value, original); + } + if (key.endsWith("scale")) { + style.transform = style.transform ? `${style[key]} ${newValue}` : newValue; + } else { + style[key.replaceAll(/-([a-zA-Z])/g, (_, x) => x.toUpperCase())] = newValue; + } + } + if (style.fontFamily) { + (0, _html_utils.setFontFamily)({ + typeface: style.fontFamily, + weight: style.fontWeight || "normal", + posture: style.fontStyle || "normal", + size: original.fontSize || 0 + }, node, node[_symbol_utils.$globalData].fontFinder, style); + } + if (richText && style.verticalAlign && style.verticalAlign !== "0px" && style.fontSize) { + const SUB_SUPER_SCRIPT_FACTOR = 0.583; + const VERTICAL_FACTOR = 0.333; + const fontSize = (0, _utils.getMeasurement)(style.fontSize); + style.fontSize = (0, _html_utils.measureToString)(fontSize * SUB_SUPER_SCRIPT_FACTOR); + style.verticalAlign = (0, _html_utils.measureToString)(Math.sign((0, _utils.getMeasurement)(style.verticalAlign)) * fontSize * VERTICAL_FACTOR); + } + if (richText && style.fontSize) { + style.fontSize = `calc(${style.fontSize} * var(--scale-factor))`; + } + (0, _html_utils.fixTextIndent)(style); + return style; +} +function checkStyle(node) { + if (!node.style) { + return ""; + } + return node.style.trim().split(/\s*;\s*/).filter(s => !!s).map(s => s.split(/\s*:\s*/, 2)).filter(([key, value]) => { + if (key === "font-family") { + node[_symbol_utils.$globalData].usedTypefaces.add(value); + } + return VALID_STYLES.has(key); + }).map(kv => kv.join(":")).join(";"); +} +const NoWhites = new Set(["body", "html"]); +class XhtmlObject extends _xfa_object.XmlObject { + constructor(attributes, name) { + super(XHTML_NS_ID, name); + this[$richText] = false; + this.style = attributes.style || ""; + } + [_symbol_utils.$clean](builder) { + super[_symbol_utils.$clean](builder); + this.style = checkStyle(this); + } + [_symbol_utils.$acceptWhitespace]() { + return !NoWhites.has(this[_symbol_utils.$nodeName]); + } + [_symbol_utils.$onText](str, richText = false) { + if (!richText) { + str = str.replaceAll(crlfRegExp, ""); + if (!this.style.includes("xfa-spacerun:yes")) { + str = str.replaceAll(spacesRegExp, " "); + } + } else { + this[$richText] = true; + } + if (str) { + this[_symbol_utils.$content] += str; + } + } + [_symbol_utils.$pushGlyphs](measure, mustPop = true) { + const xfaFont = Object.create(null); + const margin = { + top: NaN, + bottom: NaN, + left: NaN, + right: NaN + }; + let lineHeight = null; + for (const [key, value] of this.style.split(";").map(s => s.split(":", 2))) { + switch (key) { + case "font-family": + xfaFont.typeface = (0, _utils.stripQuotes)(value); + break; + case "font-size": + xfaFont.size = (0, _utils.getMeasurement)(value); + break; + case "font-weight": + xfaFont.weight = value; + break; + case "font-style": + xfaFont.posture = value; + break; + case "letter-spacing": + xfaFont.letterSpacing = (0, _utils.getMeasurement)(value); + break; + case "margin": + const values = value.split(/ \t/).map(x => (0, _utils.getMeasurement)(x)); + switch (values.length) { + case 1: + margin.top = margin.bottom = margin.left = margin.right = values[0]; + break; + case 2: + margin.top = margin.bottom = values[0]; + margin.left = margin.right = values[1]; + break; + case 3: + margin.top = values[0]; + margin.bottom = values[2]; + margin.left = margin.right = values[1]; + break; + case 4: + margin.top = values[0]; + margin.left = values[1]; + margin.bottom = values[2]; + margin.right = values[3]; + break; + } + break; + case "margin-top": + margin.top = (0, _utils.getMeasurement)(value); + break; + case "margin-bottom": + margin.bottom = (0, _utils.getMeasurement)(value); + break; + case "margin-left": + margin.left = (0, _utils.getMeasurement)(value); + break; + case "margin-right": + margin.right = (0, _utils.getMeasurement)(value); + break; + case "line-height": + lineHeight = (0, _utils.getMeasurement)(value); + break; + } + } + measure.pushData(xfaFont, margin, lineHeight); + if (this[_symbol_utils.$content]) { + measure.addString(this[_symbol_utils.$content]); + } else { + for (const child of this[_symbol_utils.$getChildren]()) { + if (child[_symbol_utils.$nodeName] === "#text") { + measure.addString(child[_symbol_utils.$content]); + continue; + } + child[_symbol_utils.$pushGlyphs](measure); + } + } + if (mustPop) { + measure.popFont(); + } + } + [_symbol_utils.$toHTML](availableSpace) { + const children = []; + this[_symbol_utils.$extra] = { + children + }; + this[_symbol_utils.$childrenToHTML]({}); + if (children.length === 0 && !this[_symbol_utils.$content]) { + return _utils.HTMLResult.EMPTY; + } + let value; + if (this[$richText]) { + value = this[_symbol_utils.$content] ? this[_symbol_utils.$content].replaceAll(crlfForRichTextRegExp, "\n") : undefined; + } else { + value = this[_symbol_utils.$content] || undefined; + } + return _utils.HTMLResult.success({ + name: this[_symbol_utils.$nodeName], + attributes: { + href: this.href, + style: mapStyle(this.style, this, this[$richText]) + }, + children, + value + }); + } +} +class A extends XhtmlObject { + constructor(attributes) { + super(attributes, "a"); + this.href = (0, _html_utils.fixURL)(attributes.href) || ""; + } +} +class B extends XhtmlObject { + constructor(attributes) { + super(attributes, "b"); + } + [_symbol_utils.$pushGlyphs](measure) { + measure.pushFont({ + weight: "bold" + }); + super[_symbol_utils.$pushGlyphs](measure); + measure.popFont(); + } +} +class Body extends XhtmlObject { + constructor(attributes) { + super(attributes, "body"); + } + [_symbol_utils.$toHTML](availableSpace) { + const res = super[_symbol_utils.$toHTML](availableSpace); + const { + html + } = res; + if (!html) { + return _utils.HTMLResult.EMPTY; + } + html.name = "div"; + html.attributes.class = ["xfaRich"]; + return res; + } +} +class Br extends XhtmlObject { + constructor(attributes) { + super(attributes, "br"); + } + [_symbol_utils.$text]() { + return "\n"; + } + [_symbol_utils.$pushGlyphs](measure) { + measure.addString("\n"); + } + [_symbol_utils.$toHTML](availableSpace) { + return _utils.HTMLResult.success({ + name: "br" + }); + } +} +class Html extends XhtmlObject { + constructor(attributes) { + super(attributes, "html"); + } + [_symbol_utils.$toHTML](availableSpace) { + const children = []; + this[_symbol_utils.$extra] = { + children + }; + this[_symbol_utils.$childrenToHTML]({}); + if (children.length === 0) { + return _utils.HTMLResult.success({ + name: "div", + attributes: { + class: ["xfaRich"], + style: {} + }, + value: this[_symbol_utils.$content] || "" + }); + } + if (children.length === 1) { + const child = children[0]; + if (child.attributes?.class.includes("xfaRich")) { + return _utils.HTMLResult.success(child); + } + } + return _utils.HTMLResult.success({ + name: "div", + attributes: { + class: ["xfaRich"], + style: {} + }, + children + }); + } +} +class I extends XhtmlObject { + constructor(attributes) { + super(attributes, "i"); + } + [_symbol_utils.$pushGlyphs](measure) { + measure.pushFont({ + posture: "italic" + }); + super[_symbol_utils.$pushGlyphs](measure); + measure.popFont(); + } +} +class Li extends XhtmlObject { + constructor(attributes) { + super(attributes, "li"); + } +} +class Ol extends XhtmlObject { + constructor(attributes) { + super(attributes, "ol"); + } +} +class P extends XhtmlObject { + constructor(attributes) { + super(attributes, "p"); + } + [_symbol_utils.$pushGlyphs](measure) { + super[_symbol_utils.$pushGlyphs](measure, false); + measure.addString("\n"); + measure.addPara(); + measure.popFont(); + } + [_symbol_utils.$text]() { + const siblings = this[_symbol_utils.$getParent]()[_symbol_utils.$getChildren](); + if (siblings.at(-1) === this) { + return super[_symbol_utils.$text](); + } + return super[_symbol_utils.$text]() + "\n"; + } +} +class Span extends XhtmlObject { + constructor(attributes) { + super(attributes, "span"); + } +} +class Sub extends XhtmlObject { + constructor(attributes) { + super(attributes, "sub"); + } +} +class Sup extends XhtmlObject { + constructor(attributes) { + super(attributes, "sup"); + } +} +class Ul extends XhtmlObject { + constructor(attributes) { + super(attributes, "ul"); + } +} +class XhtmlNamespace { + static [_namespaces.$buildXFAObject](name, attributes) { + if (XhtmlNamespace.hasOwnProperty(name)) { + return XhtmlNamespace[name](attributes); + } + return undefined; + } + static a(attributes) { + return new A(attributes); + } + static b(attributes) { + return new B(attributes); + } + static body(attributes) { + return new Body(attributes); + } + static br(attributes) { + return new Br(attributes); + } + static html(attributes) { + return new Html(attributes); + } + static i(attributes) { + return new I(attributes); + } + static li(attributes) { + return new Li(attributes); + } + static ol(attributes) { + return new Ol(attributes); + } + static p(attributes) { + return new P(attributes); + } + static span(attributes) { + return new Span(attributes); + } + static sub(attributes) { + return new Sub(attributes); + } + static sup(attributes) { + return new Sup(attributes); + } + static ul(attributes) { + return new Ul(attributes); + } +} +exports.XhtmlNamespace = XhtmlNamespace; + +/***/ }), +/* 101 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.UnknownNamespace = void 0; +var _namespaces = __w_pdfjs_require__(81); +var _xfa_object = __w_pdfjs_require__(87); +class UnknownNamespace { + constructor(nsId) { + this.namespaceId = nsId; + } + [_namespaces.$buildXFAObject](name, attributes) { + return new _xfa_object.XmlObject(this.namespaceId, name, attributes); + } +} +exports.UnknownNamespace = UnknownNamespace; + +/***/ }), +/* 102 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.DatasetReader = void 0; +var _util = __w_pdfjs_require__(2); +var _core_utils = __w_pdfjs_require__(3); +var _xml_parser = __w_pdfjs_require__(71); +function decodeString(str) { + try { + return (0, _util.stringToUTF8String)(str); + } catch (ex) { + (0, _util.warn)(`UTF-8 decoding failed: "${ex}".`); + return str; + } +} +class DatasetXMLParser extends _xml_parser.SimpleXMLParser { + constructor(options) { + super(options); + this.node = null; + } + onEndElement(name) { + const node = super.onEndElement(name); + if (node && name === "xfa:datasets") { + this.node = node; + throw new Error("Aborting DatasetXMLParser."); + } + } +} +class DatasetReader { + constructor(data) { + if (data.datasets) { + this.node = new _xml_parser.SimpleXMLParser({ + hasAttributes: true + }).parseFromString(data.datasets).documentElement; + } else { + const parser = new DatasetXMLParser({ + hasAttributes: true + }); + try { + parser.parseFromString(data["xdp:xdp"]); + } catch {} + this.node = parser.node; + } + } + getValue(path) { + if (!this.node || !path) { + return ""; + } + const node = this.node.searchNode((0, _core_utils.parseXFAPath)(path), 0); + if (!node) { + return ""; + } + const first = node.firstChild; + if (first?.nodeName === "value") { + return node.children.map(child => decodeString(child.textContent)); + } + return decodeString(node.textContent); + } +} +exports.DatasetReader = DatasetReader; + +/***/ }), +/* 103 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.XRef = void 0; +var _util = __w_pdfjs_require__(2); +var _primitives = __w_pdfjs_require__(4); +var _parser = __w_pdfjs_require__(16); +var _core_utils = __w_pdfjs_require__(3); +var _base_stream = __w_pdfjs_require__(5); +var _crypto = __w_pdfjs_require__(74); +class XRef { + #firstXRefStmPos = null; + constructor(stream, pdfManager) { + this.stream = stream; + this.pdfManager = pdfManager; + this.entries = []; + this._xrefStms = new Set(); + this._cacheMap = new Map(); + this._pendingRefs = new _primitives.RefSet(); + this._newPersistentRefNum = null; + this._newTemporaryRefNum = null; + } + getNewPersistentRef(obj) { + if (this._newPersistentRefNum === null) { + this._newPersistentRefNum = this.entries.length || 1; + } + const num = this._newPersistentRefNum++; + this._cacheMap.set(num, obj); + return _primitives.Ref.get(num, 0); + } + getNewTemporaryRef() { + if (this._newTemporaryRefNum === null) { + this._newTemporaryRefNum = this.entries.length || 1; + } + return _primitives.Ref.get(this._newTemporaryRefNum++, 0); + } + resetNewTemporaryRef() { + this._newTemporaryRefNum = null; + } + setStartXRef(startXRef) { + this.startXRefQueue = [startXRef]; + } + parse(recoveryMode = false) { + let trailerDict; + if (!recoveryMode) { + trailerDict = this.readXRef(); + } else { + (0, _util.warn)("Indexing all PDF objects"); + trailerDict = this.indexObjects(); + } + trailerDict.assignXref(this); + this.trailer = trailerDict; + let encrypt; + try { + encrypt = trailerDict.get("Encrypt"); + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.warn)(`XRef.parse - Invalid "Encrypt" reference: "${ex}".`); + } + if (encrypt instanceof _primitives.Dict) { + const ids = trailerDict.get("ID"); + const fileId = ids?.length ? ids[0] : ""; + encrypt.suppressEncryption = true; + this.encrypt = new _crypto.CipherTransformFactory(encrypt, fileId, this.pdfManager.password); + } + let root; + try { + root = trailerDict.get("Root"); + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.warn)(`XRef.parse - Invalid "Root" reference: "${ex}".`); + } + if (root instanceof _primitives.Dict) { + try { + const pages = root.get("Pages"); + if (pages instanceof _primitives.Dict) { + this.root = root; + return; + } + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + } + (0, _util.warn)(`XRef.parse - Invalid "Pages" reference: "${ex}".`); + } + } + if (!recoveryMode) { + throw new _core_utils.XRefParseException(); + } + throw new _util.InvalidPDFException("Invalid Root reference."); + } + processXRefTable(parser) { + if (!("tableState" in this)) { + this.tableState = { + entryNum: 0, + streamPos: parser.lexer.stream.pos, + parserBuf1: parser.buf1, + parserBuf2: parser.buf2 + }; + } + const obj = this.readXRefTable(parser); + if (!(0, _primitives.isCmd)(obj, "trailer")) { + throw new _util.FormatError("Invalid XRef table: could not find trailer dictionary"); + } + let dict = parser.getObj(); + if (!(dict instanceof _primitives.Dict) && dict.dict) { + dict = dict.dict; + } + if (!(dict instanceof _primitives.Dict)) { + throw new _util.FormatError("Invalid XRef table: could not parse trailer dictionary"); + } + delete this.tableState; + return dict; + } + readXRefTable(parser) { + const stream = parser.lexer.stream; + const tableState = this.tableState; + stream.pos = tableState.streamPos; + parser.buf1 = tableState.parserBuf1; + parser.buf2 = tableState.parserBuf2; + let obj; + while (true) { + if (!("firstEntryNum" in tableState) || !("entryCount" in tableState)) { + if ((0, _primitives.isCmd)(obj = parser.getObj(), "trailer")) { + break; + } + tableState.firstEntryNum = obj; + tableState.entryCount = parser.getObj(); + } + let first = tableState.firstEntryNum; + const count = tableState.entryCount; + if (!Number.isInteger(first) || !Number.isInteger(count)) { + throw new _util.FormatError("Invalid XRef table: wrong types in subsection header"); + } + for (let i = tableState.entryNum; i < count; i++) { + tableState.streamPos = stream.pos; + tableState.entryNum = i; + tableState.parserBuf1 = parser.buf1; + tableState.parserBuf2 = parser.buf2; + const entry = {}; + entry.offset = parser.getObj(); + entry.gen = parser.getObj(); + const type = parser.getObj(); + if (type instanceof _primitives.Cmd) { + switch (type.cmd) { + case "f": + entry.free = true; + break; + case "n": + entry.uncompressed = true; + break; + } + } + if (!Number.isInteger(entry.offset) || !Number.isInteger(entry.gen) || !(entry.free || entry.uncompressed)) { + throw new _util.FormatError(`Invalid entry in XRef subsection: ${first}, ${count}`); + } + if (i === 0 && entry.free && first === 1) { + first = 0; + } + if (!this.entries[i + first]) { + this.entries[i + first] = entry; + } + } + tableState.entryNum = 0; + tableState.streamPos = stream.pos; + tableState.parserBuf1 = parser.buf1; + tableState.parserBuf2 = parser.buf2; + delete tableState.firstEntryNum; + delete tableState.entryCount; + } + if (this.entries[0] && !this.entries[0].free) { + throw new _util.FormatError("Invalid XRef table: unexpected first object"); + } + return obj; + } + processXRefStream(stream) { + if (!("streamState" in this)) { + const streamParameters = stream.dict; + const byteWidths = streamParameters.get("W"); + let range = streamParameters.get("Index"); + if (!range) { + range = [0, streamParameters.get("Size")]; + } + this.streamState = { + entryRanges: range, + byteWidths, + entryNum: 0, + streamPos: stream.pos + }; + } + this.readXRefStream(stream); + delete this.streamState; + return stream.dict; + } + readXRefStream(stream) { + const streamState = this.streamState; + stream.pos = streamState.streamPos; + const [typeFieldWidth, offsetFieldWidth, generationFieldWidth] = streamState.byteWidths; + const entryRanges = streamState.entryRanges; + while (entryRanges.length > 0) { + const [first, n] = entryRanges; + if (!Number.isInteger(first) || !Number.isInteger(n)) { + throw new _util.FormatError(`Invalid XRef range fields: ${first}, ${n}`); + } + if (!Number.isInteger(typeFieldWidth) || !Number.isInteger(offsetFieldWidth) || !Number.isInteger(generationFieldWidth)) { + throw new _util.FormatError(`Invalid XRef entry fields length: ${first}, ${n}`); + } + for (let i = streamState.entryNum; i < n; ++i) { + streamState.entryNum = i; + streamState.streamPos = stream.pos; + let type = 0, + offset = 0, + generation = 0; + for (let j = 0; j < typeFieldWidth; ++j) { + const typeByte = stream.getByte(); + if (typeByte === -1) { + throw new _util.FormatError("Invalid XRef byteWidths 'type'."); + } + type = type << 8 | typeByte; + } + if (typeFieldWidth === 0) { + type = 1; + } + for (let j = 0; j < offsetFieldWidth; ++j) { + const offsetByte = stream.getByte(); + if (offsetByte === -1) { + throw new _util.FormatError("Invalid XRef byteWidths 'offset'."); + } + offset = offset << 8 | offsetByte; + } + for (let j = 0; j < generationFieldWidth; ++j) { + const generationByte = stream.getByte(); + if (generationByte === -1) { + throw new _util.FormatError("Invalid XRef byteWidths 'generation'."); + } + generation = generation << 8 | generationByte; + } + const entry = {}; + entry.offset = offset; + entry.gen = generation; + switch (type) { + case 0: + entry.free = true; + break; + case 1: + entry.uncompressed = true; + break; + case 2: + break; + default: + throw new _util.FormatError(`Invalid XRef entry type: ${type}`); + } + if (!this.entries[first + i]) { + this.entries[first + i] = entry; + } + } + streamState.entryNum = 0; + streamState.streamPos = stream.pos; + entryRanges.splice(0, 2); + } + } + indexObjects() { + const TAB = 0x9, + LF = 0xa, + CR = 0xd, + SPACE = 0x20; + const PERCENT = 0x25, + LT = 0x3c; + function readToken(data, offset) { + let token = "", + ch = data[offset]; + while (ch !== LF && ch !== CR && ch !== LT) { + if (++offset >= data.length) { + break; + } + token += String.fromCharCode(ch); + ch = data[offset]; + } + return token; + } + function skipUntil(data, offset, what) { + const length = what.length, + dataLength = data.length; + let skipped = 0; + while (offset < dataLength) { + let i = 0; + while (i < length && data[offset + i] === what[i]) { + ++i; + } + if (i >= length) { + break; + } + offset++; + skipped++; + } + return skipped; + } + const gEndobjRegExp = /\b(endobj|\d+\s+\d+\s+obj|xref|trailer\s*<<)\b/g; + const gStartxrefRegExp = /\b(startxref|\d+\s+\d+\s+obj)\b/g; + const objRegExp = /^(\d+)\s+(\d+)\s+obj\b/; + const trailerBytes = new Uint8Array([116, 114, 97, 105, 108, 101, 114]); + const startxrefBytes = new Uint8Array([115, 116, 97, 114, 116, 120, 114, 101, 102]); + const xrefBytes = new Uint8Array([47, 88, 82, 101, 102]); + this.entries.length = 0; + this._cacheMap.clear(); + const stream = this.stream; + stream.pos = 0; + const buffer = stream.getBytes(), + bufferStr = (0, _util.bytesToString)(buffer), + length = buffer.length; + let position = stream.start; + const trailers = [], + xrefStms = []; + while (position < length) { + let ch = buffer[position]; + if (ch === TAB || ch === LF || ch === CR || ch === SPACE) { + ++position; + continue; + } + if (ch === PERCENT) { + do { + ++position; + if (position >= length) { + break; + } + ch = buffer[position]; + } while (ch !== LF && ch !== CR); + continue; + } + const token = readToken(buffer, position); + let m; + if (token.startsWith("xref") && (token.length === 4 || /\s/.test(token[4]))) { + position += skipUntil(buffer, position, trailerBytes); + trailers.push(position); + position += skipUntil(buffer, position, startxrefBytes); + } else if (m = objRegExp.exec(token)) { + const num = m[1] | 0, + gen = m[2] | 0; + const startPos = position + token.length; + let contentLength, + updateEntries = false; + if (!this.entries[num]) { + updateEntries = true; + } else if (this.entries[num].gen === gen) { + try { + const parser = new _parser.Parser({ + lexer: new _parser.Lexer(stream.makeSubStream(startPos)) + }); + parser.getObj(); + updateEntries = true; + } catch (ex) { + if (ex instanceof _core_utils.ParserEOFException) { + (0, _util.warn)(`indexObjects -- checking object (${token}): "${ex}".`); + } else { + updateEntries = true; + } + } + } + if (updateEntries) { + this.entries[num] = { + offset: position - stream.start, + gen, + uncompressed: true + }; + } + gEndobjRegExp.lastIndex = startPos; + const match = gEndobjRegExp.exec(bufferStr); + if (match) { + const endPos = gEndobjRegExp.lastIndex + 1; + contentLength = endPos - position; + if (match[1] !== "endobj") { + (0, _util.warn)(`indexObjects: Found "${match[1]}" inside of another "obj", ` + 'caused by missing "endobj" -- trying to recover.'); + contentLength -= match[1].length + 1; + } + } else { + contentLength = length - position; + } + const content = buffer.subarray(position, position + contentLength); + const xrefTagOffset = skipUntil(content, 0, xrefBytes); + if (xrefTagOffset < contentLength && content[xrefTagOffset + 5] < 64) { + xrefStms.push(position - stream.start); + this._xrefStms.add(position - stream.start); + } + position += contentLength; + } else if (token.startsWith("trailer") && (token.length === 7 || /\s/.test(token[7]))) { + trailers.push(position); + const startPos = position + token.length; + let contentLength; + gStartxrefRegExp.lastIndex = startPos; + const match = gStartxrefRegExp.exec(bufferStr); + if (match) { + const endPos = gStartxrefRegExp.lastIndex + 1; + contentLength = endPos - position; + if (match[1] !== "startxref") { + (0, _util.warn)(`indexObjects: Found "${match[1]}" after "trailer", ` + 'caused by missing "startxref" -- trying to recover.'); + contentLength -= match[1].length + 1; + } + } else { + contentLength = length - position; + } + position += contentLength; + } else { + position += token.length + 1; + } + } + for (const xrefStm of xrefStms) { + this.startXRefQueue.push(xrefStm); + this.readXRef(true); + } + const trailerDicts = []; + let isEncrypted = false; + for (const trailer of trailers) { + stream.pos = trailer; + const parser = new _parser.Parser({ + lexer: new _parser.Lexer(stream), + xref: this, + allowStreams: true, + recoveryMode: true + }); + const obj = parser.getObj(); + if (!(0, _primitives.isCmd)(obj, "trailer")) { + continue; + } + const dict = parser.getObj(); + if (!(dict instanceof _primitives.Dict)) { + continue; + } + trailerDicts.push(dict); + if (dict.has("Encrypt")) { + isEncrypted = true; + } + } + let trailerDict, trailerError; + for (const dict of [...trailerDicts, "genFallback", ...trailerDicts]) { + if (dict === "genFallback") { + if (!trailerError) { + break; + } + this._generationFallback = true; + continue; + } + let validPagesDict = false; + try { + const rootDict = dict.get("Root"); + if (!(rootDict instanceof _primitives.Dict)) { + continue; + } + const pagesDict = rootDict.get("Pages"); + if (!(pagesDict instanceof _primitives.Dict)) { + continue; + } + const pagesCount = pagesDict.get("Count"); + if (Number.isInteger(pagesCount)) { + validPagesDict = true; + } + } catch (ex) { + trailerError = ex; + continue; + } + if (validPagesDict && (!isEncrypted || dict.has("Encrypt")) && dict.has("ID")) { + return dict; + } + trailerDict = dict; + } + if (trailerDict) { + return trailerDict; + } + if (this.topDict) { + return this.topDict; + } + throw new _util.InvalidPDFException("Invalid PDF structure."); + } + readXRef(recoveryMode = false) { + const stream = this.stream; + const startXRefParsedCache = new Set(); + while (this.startXRefQueue.length) { + try { + const startXRef = this.startXRefQueue[0]; + if (startXRefParsedCache.has(startXRef)) { + (0, _util.warn)("readXRef - skipping XRef table since it was already parsed."); + this.startXRefQueue.shift(); + continue; + } + startXRefParsedCache.add(startXRef); + stream.pos = startXRef + stream.start; + const parser = new _parser.Parser({ + lexer: new _parser.Lexer(stream), + xref: this, + allowStreams: true + }); + let obj = parser.getObj(); + let dict; + if ((0, _primitives.isCmd)(obj, "xref")) { + dict = this.processXRefTable(parser); + if (!this.topDict) { + this.topDict = dict; + } + obj = dict.get("XRefStm"); + if (Number.isInteger(obj) && !this._xrefStms.has(obj)) { + this._xrefStms.add(obj); + this.startXRefQueue.push(obj); + this.#firstXRefStmPos ??= obj; + } + } else if (Number.isInteger(obj)) { + if (!Number.isInteger(parser.getObj()) || !(0, _primitives.isCmd)(parser.getObj(), "obj") || !((obj = parser.getObj()) instanceof _base_stream.BaseStream)) { + throw new _util.FormatError("Invalid XRef stream"); + } + dict = this.processXRefStream(obj); + if (!this.topDict) { + this.topDict = dict; + } + if (!dict) { + throw new _util.FormatError("Failed to read XRef stream"); + } + } else { + throw new _util.FormatError("Invalid XRef stream header"); + } + obj = dict.get("Prev"); + if (Number.isInteger(obj)) { + this.startXRefQueue.push(obj); + } else if (obj instanceof _primitives.Ref) { + this.startXRefQueue.push(obj.num); + } + } catch (e) { + if (e instanceof _core_utils.MissingDataException) { + throw e; + } + (0, _util.info)("(while reading XRef): " + e); + } + this.startXRefQueue.shift(); + } + if (this.topDict) { + return this.topDict; + } + if (recoveryMode) { + return undefined; + } + throw new _core_utils.XRefParseException(); + } + get lastXRefStreamPos() { + return this.#firstXRefStmPos ?? (this._xrefStms.size > 0 ? Math.max(...this._xrefStms) : null); + } + getEntry(i) { + const xrefEntry = this.entries[i]; + if (xrefEntry && !xrefEntry.free && xrefEntry.offset) { + return xrefEntry; + } + return null; + } + fetchIfRef(obj, suppressEncryption = false) { + if (obj instanceof _primitives.Ref) { + return this.fetch(obj, suppressEncryption); + } + return obj; + } + fetch(ref, suppressEncryption = false) { + if (!(ref instanceof _primitives.Ref)) { + throw new Error("ref object is not a reference"); + } + const num = ref.num; + const cacheEntry = this._cacheMap.get(num); + if (cacheEntry !== undefined) { + if (cacheEntry instanceof _primitives.Dict && !cacheEntry.objId) { + cacheEntry.objId = ref.toString(); + } + return cacheEntry; + } + let xrefEntry = this.getEntry(num); + if (xrefEntry === null) { + this._cacheMap.set(num, xrefEntry); + return xrefEntry; + } + if (this._pendingRefs.has(ref)) { + this._pendingRefs.remove(ref); + (0, _util.warn)(`Ignoring circular reference: ${ref}.`); + return _primitives.CIRCULAR_REF; + } + this._pendingRefs.put(ref); + try { + xrefEntry = xrefEntry.uncompressed ? this.fetchUncompressed(ref, xrefEntry, suppressEncryption) : this.fetchCompressed(ref, xrefEntry, suppressEncryption); + this._pendingRefs.remove(ref); + } catch (ex) { + this._pendingRefs.remove(ref); + throw ex; + } + if (xrefEntry instanceof _primitives.Dict) { + xrefEntry.objId = ref.toString(); + } else if (xrefEntry instanceof _base_stream.BaseStream) { + xrefEntry.dict.objId = ref.toString(); + } + return xrefEntry; + } + fetchUncompressed(ref, xrefEntry, suppressEncryption = false) { + const gen = ref.gen; + let num = ref.num; + if (xrefEntry.gen !== gen) { + const msg = `Inconsistent generation in XRef: ${ref}`; + if (this._generationFallback && xrefEntry.gen < gen) { + (0, _util.warn)(msg); + return this.fetchUncompressed(_primitives.Ref.get(num, xrefEntry.gen), xrefEntry, suppressEncryption); + } + throw new _core_utils.XRefEntryException(msg); + } + const stream = this.stream.makeSubStream(xrefEntry.offset + this.stream.start); + const parser = new _parser.Parser({ + lexer: new _parser.Lexer(stream), + xref: this, + allowStreams: true + }); + const obj1 = parser.getObj(); + const obj2 = parser.getObj(); + const obj3 = parser.getObj(); + if (obj1 !== num || obj2 !== gen || !(obj3 instanceof _primitives.Cmd)) { + throw new _core_utils.XRefEntryException(`Bad (uncompressed) XRef entry: ${ref}`); + } + if (obj3.cmd !== "obj") { + if (obj3.cmd.startsWith("obj")) { + num = parseInt(obj3.cmd.substring(3), 10); + if (!Number.isNaN(num)) { + return num; + } + } + throw new _core_utils.XRefEntryException(`Bad (uncompressed) XRef entry: ${ref}`); + } + xrefEntry = this.encrypt && !suppressEncryption ? parser.getObj(this.encrypt.createCipherTransform(num, gen)) : parser.getObj(); + if (!(xrefEntry instanceof _base_stream.BaseStream)) { + this._cacheMap.set(num, xrefEntry); + } + return xrefEntry; + } + fetchCompressed(ref, xrefEntry, suppressEncryption = false) { + const tableOffset = xrefEntry.offset; + const stream = this.fetch(_primitives.Ref.get(tableOffset, 0)); + if (!(stream instanceof _base_stream.BaseStream)) { + throw new _util.FormatError("bad ObjStm stream"); + } + const first = stream.dict.get("First"); + const n = stream.dict.get("N"); + if (!Number.isInteger(first) || !Number.isInteger(n)) { + throw new _util.FormatError("invalid first and n parameters for ObjStm stream"); + } + let parser = new _parser.Parser({ + lexer: new _parser.Lexer(stream), + xref: this, + allowStreams: true + }); + const nums = new Array(n); + const offsets = new Array(n); + for (let i = 0; i < n; ++i) { + const num = parser.getObj(); + if (!Number.isInteger(num)) { + throw new _util.FormatError(`invalid object number in the ObjStm stream: ${num}`); + } + const offset = parser.getObj(); + if (!Number.isInteger(offset)) { + throw new _util.FormatError(`invalid object offset in the ObjStm stream: ${offset}`); + } + nums[i] = num; + offsets[i] = offset; + } + const start = (stream.start || 0) + first; + const entries = new Array(n); + for (let i = 0; i < n; ++i) { + const length = i < n - 1 ? offsets[i + 1] - offsets[i] : undefined; + if (length < 0) { + throw new _util.FormatError("Invalid offset in the ObjStm stream."); + } + parser = new _parser.Parser({ + lexer: new _parser.Lexer(stream.makeSubStream(start + offsets[i], length, stream.dict)), + xref: this, + allowStreams: true + }); + const obj = parser.getObj(); + entries[i] = obj; + if (obj instanceof _base_stream.BaseStream) { + continue; + } + const num = nums[i], + entry = this.entries[num]; + if (entry && entry.offset === tableOffset && entry.gen === i) { + this._cacheMap.set(num, obj); + } + } + xrefEntry = entries[xrefEntry.gen]; + if (xrefEntry === undefined) { + throw new _core_utils.XRefEntryException(`Bad (compressed) XRef entry: ${ref}`); + } + return xrefEntry; + } + async fetchIfRefAsync(obj, suppressEncryption) { + if (obj instanceof _primitives.Ref) { + return this.fetchAsync(obj, suppressEncryption); + } + return obj; + } + async fetchAsync(ref, suppressEncryption) { + try { + return this.fetch(ref, suppressEncryption); + } catch (ex) { + if (!(ex instanceof _core_utils.MissingDataException)) { + throw ex; + } + await this.pdfManager.requestRange(ex.begin, ex.end); + return this.fetchAsync(ref, suppressEncryption); + } + } + getCatalogObj() { + return this.root; + } +} +exports.XRef = XRef; + +/***/ }), +/* 104 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.MessageHandler = void 0; +var _util = __w_pdfjs_require__(2); +const CallbackKind = { + UNKNOWN: 0, + DATA: 1, + ERROR: 2 +}; +const StreamKind = { + UNKNOWN: 0, + CANCEL: 1, + CANCEL_COMPLETE: 2, + CLOSE: 3, + ENQUEUE: 4, + ERROR: 5, + PULL: 6, + PULL_COMPLETE: 7, + START_COMPLETE: 8 +}; +function wrapReason(reason) { + if (!(reason instanceof Error || typeof reason === "object" && reason !== null)) { + (0, _util.unreachable)('wrapReason: Expected "reason" to be a (possibly cloned) Error.'); + } + switch (reason.name) { + case "AbortException": + return new _util.AbortException(reason.message); + case "MissingPDFException": + return new _util.MissingPDFException(reason.message); + case "PasswordException": + return new _util.PasswordException(reason.message, reason.code); + case "UnexpectedResponseException": + return new _util.UnexpectedResponseException(reason.message, reason.status); + case "UnknownErrorException": + return new _util.UnknownErrorException(reason.message, reason.details); + default: + return new _util.UnknownErrorException(reason.message, reason.toString()); + } +} +class MessageHandler { + constructor(sourceName, targetName, comObj) { + this.sourceName = sourceName; + this.targetName = targetName; + this.comObj = comObj; + this.callbackId = 1; + this.streamId = 1; + this.streamSinks = Object.create(null); + this.streamControllers = Object.create(null); + this.callbackCapabilities = Object.create(null); + this.actionHandler = Object.create(null); + this._onComObjOnMessage = event => { + const data = event.data; + if (data.targetName !== this.sourceName) { + return; + } + if (data.stream) { + this.#processStreamMessage(data); + return; + } + if (data.callback) { + const callbackId = data.callbackId; + const capability = this.callbackCapabilities[callbackId]; + if (!capability) { + throw new Error(`Cannot resolve callback ${callbackId}`); + } + delete this.callbackCapabilities[callbackId]; + if (data.callback === CallbackKind.DATA) { + capability.resolve(data.data); + } else if (data.callback === CallbackKind.ERROR) { + capability.reject(wrapReason(data.reason)); + } else { + throw new Error("Unexpected callback case"); + } + return; + } + const action = this.actionHandler[data.action]; + if (!action) { + throw new Error(`Unknown action from worker: ${data.action}`); + } + if (data.callbackId) { + const cbSourceName = this.sourceName; + const cbTargetName = data.sourceName; + new Promise(function (resolve) { + resolve(action(data.data)); + }).then(function (result) { + comObj.postMessage({ + sourceName: cbSourceName, + targetName: cbTargetName, + callback: CallbackKind.DATA, + callbackId: data.callbackId, + data: result + }); + }, function (reason) { + comObj.postMessage({ + sourceName: cbSourceName, + targetName: cbTargetName, + callback: CallbackKind.ERROR, + callbackId: data.callbackId, + reason: wrapReason(reason) + }); + }); + return; + } + if (data.streamId) { + this.#createStreamSink(data); + return; + } + action(data.data); + }; + comObj.addEventListener("message", this._onComObjOnMessage); + } + on(actionName, handler) { + const ah = this.actionHandler; + if (ah[actionName]) { + throw new Error(`There is already an actionName called "${actionName}"`); + } + ah[actionName] = handler; + } + send(actionName, data, transfers) { + this.comObj.postMessage({ + sourceName: this.sourceName, + targetName: this.targetName, + action: actionName, + data + }, transfers); + } + sendWithPromise(actionName, data, transfers) { + const callbackId = this.callbackId++; + const capability = new _util.PromiseCapability(); + this.callbackCapabilities[callbackId] = capability; + try { + this.comObj.postMessage({ + sourceName: this.sourceName, + targetName: this.targetName, + action: actionName, + callbackId, + data + }, transfers); + } catch (ex) { + capability.reject(ex); + } + return capability.promise; + } + sendWithStream(actionName, data, queueingStrategy, transfers) { + const streamId = this.streamId++, + sourceName = this.sourceName, + targetName = this.targetName, + comObj = this.comObj; + return new ReadableStream({ + start: controller => { + const startCapability = new _util.PromiseCapability(); + this.streamControllers[streamId] = { + controller, + startCall: startCapability, + pullCall: null, + cancelCall: null, + isClosed: false + }; + comObj.postMessage({ + sourceName, + targetName, + action: actionName, + streamId, + data, + desiredSize: controller.desiredSize + }, transfers); + return startCapability.promise; + }, + pull: controller => { + const pullCapability = new _util.PromiseCapability(); + this.streamControllers[streamId].pullCall = pullCapability; + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.PULL, + streamId, + desiredSize: controller.desiredSize + }); + return pullCapability.promise; + }, + cancel: reason => { + (0, _util.assert)(reason instanceof Error, "cancel must have a valid reason"); + const cancelCapability = new _util.PromiseCapability(); + this.streamControllers[streamId].cancelCall = cancelCapability; + this.streamControllers[streamId].isClosed = true; + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.CANCEL, + streamId, + reason: wrapReason(reason) + }); + return cancelCapability.promise; + } + }, queueingStrategy); + } + #createStreamSink(data) { + const streamId = data.streamId, + sourceName = this.sourceName, + targetName = data.sourceName, + comObj = this.comObj; + const self = this, + action = this.actionHandler[data.action]; + const streamSink = { + enqueue(chunk, size = 1, transfers) { + if (this.isCancelled) { + return; + } + const lastDesiredSize = this.desiredSize; + this.desiredSize -= size; + if (lastDesiredSize > 0 && this.desiredSize <= 0) { + this.sinkCapability = new _util.PromiseCapability(); + this.ready = this.sinkCapability.promise; + } + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.ENQUEUE, + streamId, + chunk + }, transfers); + }, + close() { + if (this.isCancelled) { + return; + } + this.isCancelled = true; + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.CLOSE, + streamId + }); + delete self.streamSinks[streamId]; + }, + error(reason) { + (0, _util.assert)(reason instanceof Error, "error must have a valid reason"); + if (this.isCancelled) { + return; + } + this.isCancelled = true; + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.ERROR, + streamId, + reason: wrapReason(reason) + }); + }, + sinkCapability: new _util.PromiseCapability(), + onPull: null, + onCancel: null, + isCancelled: false, + desiredSize: data.desiredSize, + ready: null + }; + streamSink.sinkCapability.resolve(); + streamSink.ready = streamSink.sinkCapability.promise; + this.streamSinks[streamId] = streamSink; + new Promise(function (resolve) { + resolve(action(data.data, streamSink)); + }).then(function () { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.START_COMPLETE, + streamId, + success: true + }); + }, function (reason) { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.START_COMPLETE, + streamId, + reason: wrapReason(reason) + }); + }); + } + #processStreamMessage(data) { + const streamId = data.streamId, + sourceName = this.sourceName, + targetName = data.sourceName, + comObj = this.comObj; + const streamController = this.streamControllers[streamId], + streamSink = this.streamSinks[streamId]; + switch (data.stream) { + case StreamKind.START_COMPLETE: + if (data.success) { + streamController.startCall.resolve(); + } else { + streamController.startCall.reject(wrapReason(data.reason)); + } + break; + case StreamKind.PULL_COMPLETE: + if (data.success) { + streamController.pullCall.resolve(); + } else { + streamController.pullCall.reject(wrapReason(data.reason)); + } + break; + case StreamKind.PULL: + if (!streamSink) { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.PULL_COMPLETE, + streamId, + success: true + }); + break; + } + if (streamSink.desiredSize <= 0 && data.desiredSize > 0) { + streamSink.sinkCapability.resolve(); + } + streamSink.desiredSize = data.desiredSize; + new Promise(function (resolve) { + resolve(streamSink.onPull?.()); + }).then(function () { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.PULL_COMPLETE, + streamId, + success: true + }); + }, function (reason) { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.PULL_COMPLETE, + streamId, + reason: wrapReason(reason) + }); + }); + break; + case StreamKind.ENQUEUE: + (0, _util.assert)(streamController, "enqueue should have stream controller"); + if (streamController.isClosed) { + break; + } + streamController.controller.enqueue(data.chunk); + break; + case StreamKind.CLOSE: + (0, _util.assert)(streamController, "close should have stream controller"); + if (streamController.isClosed) { + break; + } + streamController.isClosed = true; + streamController.controller.close(); + this.#deleteStreamController(streamController, streamId); + break; + case StreamKind.ERROR: + (0, _util.assert)(streamController, "error should have stream controller"); + streamController.controller.error(wrapReason(data.reason)); + this.#deleteStreamController(streamController, streamId); + break; + case StreamKind.CANCEL_COMPLETE: + if (data.success) { + streamController.cancelCall.resolve(); + } else { + streamController.cancelCall.reject(wrapReason(data.reason)); + } + this.#deleteStreamController(streamController, streamId); + break; + case StreamKind.CANCEL: + if (!streamSink) { + break; + } + new Promise(function (resolve) { + resolve(streamSink.onCancel?.(wrapReason(data.reason))); + }).then(function () { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.CANCEL_COMPLETE, + streamId, + success: true + }); + }, function (reason) { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.CANCEL_COMPLETE, + streamId, + reason: wrapReason(reason) + }); + }); + streamSink.sinkCapability.reject(wrapReason(data.reason)); + streamSink.isCancelled = true; + delete this.streamSinks[streamId]; + break; + default: + throw new Error("Unexpected stream case"); + } + } + async #deleteStreamController(streamController, streamId) { + await Promise.allSettled([streamController.startCall?.promise, streamController.pullCall?.promise, streamController.cancelCall?.promise]); + delete this.streamControllers[streamId]; + } + destroy() { + this.comObj.removeEventListener("message", this._onComObjOnMessage); + } +} +exports.MessageHandler = MessageHandler; + +/***/ }), +/* 105 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.PDFWorkerStream = void 0; +var _util = __w_pdfjs_require__(2); +class PDFWorkerStream { + constructor(msgHandler) { + this._msgHandler = msgHandler; + this._contentLength = null; + this._fullRequestReader = null; + this._rangeRequestReaders = []; + } + getFullReader() { + (0, _util.assert)(!this._fullRequestReader, "PDFWorkerStream.getFullReader can only be called once."); + this._fullRequestReader = new PDFWorkerStreamReader(this._msgHandler); + return this._fullRequestReader; + } + getRangeReader(begin, end) { + const reader = new PDFWorkerStreamRangeReader(begin, end, this._msgHandler); + this._rangeRequestReaders.push(reader); + return reader; + } + cancelAllRequests(reason) { + this._fullRequestReader?.cancel(reason); + for (const reader of this._rangeRequestReaders.slice(0)) { + reader.cancel(reason); + } + } +} +exports.PDFWorkerStream = PDFWorkerStream; +class PDFWorkerStreamReader { + constructor(msgHandler) { + this._msgHandler = msgHandler; + this.onProgress = null; + this._contentLength = null; + this._isRangeSupported = false; + this._isStreamingSupported = false; + const readableStream = this._msgHandler.sendWithStream("GetReader"); + this._reader = readableStream.getReader(); + this._headersReady = this._msgHandler.sendWithPromise("ReaderHeadersReady").then(data => { + this._isStreamingSupported = data.isStreamingSupported; + this._isRangeSupported = data.isRangeSupported; + this._contentLength = data.contentLength; + }); + } + get headersReady() { + return this._headersReady; + } + get contentLength() { + return this._contentLength; + } + get isStreamingSupported() { + return this._isStreamingSupported; + } + get isRangeSupported() { + return this._isRangeSupported; + } + async read() { + const { + value, + done + } = await this._reader.read(); + if (done) { + return { + value: undefined, + done: true + }; + } + return { + value: value.buffer, + done: false + }; + } + cancel(reason) { + this._reader.cancel(reason); + } +} +class PDFWorkerStreamRangeReader { + constructor(begin, end, msgHandler) { + this._msgHandler = msgHandler; + this.onProgress = null; + const readableStream = this._msgHandler.sendWithStream("GetRangeReader", { + begin, + end + }); + this._reader = readableStream.getReader(); + } + get isStreamingSupported() { + return false; + } + async read() { + const { + value, + done + } = await this._reader.read(); + if (done) { + return { + value: undefined, + done: true + }; + } + return { + value: value.buffer, + done: false + }; + } + cancel(reason) { + this._reader.cancel(reason); + } +} + +/***/ }) +/******/ ]); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __w_pdfjs_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __w_pdfjs_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +var exports = __webpack_exports__; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "WorkerMessageHandler", ({ + enumerable: true, + get: function () { + return _worker.WorkerMessageHandler; + } +})); +var _worker = __w_pdfjs_require__(1); +const pdfjsVersion = '3.11.174'; +const pdfjsBuild = 'ce8716743'; +})(); + +/******/ return __webpack_exports__; +/******/ })() +; +}); +//# sourceMappingURL=pdf.worker.js.map \ No newline at end of file diff --git a/frontend/public/robots.txt b/frontend/public/robots.txt new file mode 100644 index 000000000..e9e57dc4d --- /dev/null +++ b/frontend/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/frontend/public/thumbnailWorker.js b/frontend/public/thumbnailWorker.js new file mode 100644 index 000000000..2654ce6a4 --- /dev/null +++ b/frontend/public/thumbnailWorker.js @@ -0,0 +1,157 @@ +// Web Worker for parallel thumbnail generation +console.log('šŸ”§ Thumbnail worker starting up...'); + +let pdfJsLoaded = false; + +// Import PDF.js properly for worker context +try { + console.log('šŸ“¦ Loading PDF.js locally...'); + importScripts('/pdf.js'); + + // PDF.js exports to globalThis, check both self and globalThis + const pdfjsLib = self.pdfjsLib || globalThis.pdfjsLib; + + if (pdfjsLib) { + // Make it available on self for consistency + self.pdfjsLib = pdfjsLib; + + // Set up PDF.js worker + self.pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.js'; + pdfJsLoaded = true; + console.log('āœ“ PDF.js loaded successfully from local files'); + console.log('āœ“ PDF.js version:', self.pdfjsLib.version || 'unknown'); + } else { + throw new Error('pdfjsLib not available after import - neither self.pdfjsLib nor globalThis.pdfjsLib found'); + } +} catch (error) { + console.error('āœ— Failed to load local PDF.js:', error.message || error); + console.error('āœ— Available globals:', Object.keys(self).filter(key => key.includes('pdf'))); + pdfJsLoaded = false; +} + +// Log the final status +if (pdfJsLoaded) { + console.log('āœ… Thumbnail worker ready for PDF processing'); +} else { + console.log('āŒ Thumbnail worker failed to initialize - PDF.js not available'); +} + +self.onmessage = async function(e) { + const { type, data, jobId } = e.data; + + try { + // Handle PING for worker health check + if (type === 'PING') { + console.log('šŸ“ Worker PING received, checking PDF.js status...'); + + // Check if PDF.js is loaded before responding + if (pdfJsLoaded && self.pdfjsLib) { + console.log('āœ“ Worker PONG - PDF.js ready'); + self.postMessage({ type: 'PONG', jobId }); + } else { + console.error('āœ— PDF.js not loaded - worker not ready'); + console.error('āœ— pdfJsLoaded:', pdfJsLoaded); + console.error('āœ— self.pdfjsLib:', !!self.pdfjsLib); + self.postMessage({ + type: 'ERROR', + jobId, + data: { error: 'PDF.js not loaded in worker' } + }); + } + return; + } + + if (type === 'GENERATE_THUMBNAILS') { + console.log('šŸ–¼ļø Starting thumbnail generation for', data.pageNumbers.length, 'pages'); + + if (!pdfJsLoaded || !self.pdfjsLib) { + const error = 'PDF.js not available in worker'; + console.error('āœ—', error); + throw new Error(error); + } + const { pdfArrayBuffer, pageNumbers, scale = 0.2, quality = 0.8 } = data; + + console.log('šŸ“„ Loading PDF document, size:', pdfArrayBuffer.byteLength, 'bytes'); + // Load PDF in worker using imported PDF.js + const pdf = await self.pdfjsLib.getDocument({ data: pdfArrayBuffer }).promise; + console.log('āœ“ PDF loaded, total pages:', pdf.numPages); + + const thumbnails = []; + + // Process pages in smaller batches for smoother UI + const batchSize = 3; // Process 3 pages at once for smoother UI + for (let i = 0; i < pageNumbers.length; i += batchSize) { + const batch = pageNumbers.slice(i, i + batchSize); + + const batchPromises = batch.map(async (pageNumber) => { + try { + console.log(`šŸŽÆ Processing page ${pageNumber}...`); + const page = await pdf.getPage(pageNumber); + const viewport = page.getViewport({ scale }); + console.log(`šŸ“ Page ${pageNumber} viewport:`, viewport.width, 'x', viewport.height); + + // Create OffscreenCanvas for better performance + const canvas = new OffscreenCanvas(viewport.width, viewport.height); + const context = canvas.getContext('2d'); + + if (!context) { + throw new Error('Failed to get 2D context from OffscreenCanvas'); + } + + await page.render({ canvasContext: context, viewport }).promise; + console.log(`āœ“ Page ${pageNumber} rendered`); + + // Convert to blob then to base64 (more efficient than toDataURL) + const blob = await canvas.convertToBlob({ type: 'image/jpeg', quality }); + const arrayBuffer = await blob.arrayBuffer(); + const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer))); + const thumbnail = `data:image/jpeg;base64,${base64}`; + console.log(`āœ“ Page ${pageNumber} thumbnail generated (${base64.length} chars)`); + + return { pageNumber, thumbnail, success: true }; + } catch (error) { + console.error(`āœ— Failed to generate thumbnail for page ${pageNumber}:`, error.message || error); + return { pageNumber, error: error.message || String(error), success: false }; + } + }); + + const batchResults = await Promise.all(batchPromises); + thumbnails.push(...batchResults); + + // Send progress update + console.log(`šŸ“Š Worker: Sending progress update - ${thumbnails.length}/${pageNumbers.length} completed, ${batchResults.filter(r => r.success).length} new thumbnails`); + self.postMessage({ + type: 'PROGRESS', + jobId, + data: { + completed: thumbnails.length, + total: pageNumbers.length, + thumbnails: batchResults.filter(r => r.success) + } + }); + + // Small delay between batches to keep UI smooth + if (i + batchSize < pageNumbers.length) { + console.log(`āøļø Worker: Pausing 100ms before next batch (${i + batchSize}/${pageNumbers.length})`); + await new Promise(resolve => setTimeout(resolve, 100)); // Increased to 100ms pause between batches for smoother scrolling + } + } + + // Clean up + pdf.destroy(); + + self.postMessage({ + type: 'COMPLETE', + jobId, + data: { thumbnails: thumbnails.filter(r => r.success) } + }); + + } + } catch (error) { + self.postMessage({ + type: 'ERROR', + jobId, + data: { error: error.message } + }); + } +}; diff --git a/frontend/scripts/generate-licenses.js b/frontend/scripts/generate-licenses.js new file mode 100644 index 000000000..cfd5f675a --- /dev/null +++ b/frontend/scripts/generate-licenses.js @@ -0,0 +1,415 @@ +#!/usr/bin/env node + +const { execSync } = require('child_process'); +const fs = require('fs'); +const path = require('path'); + +/** + * Generate 3rd party licenses for frontend dependencies + * This script creates a JSON file similar to the Java backend's 3rdPartyLicenses.json + */ + +const OUTPUT_FILE = path.join(__dirname, '..', 'src', 'assets', '3rdPartyLicenses.json'); +const PACKAGE_JSON = path.join(__dirname, '..', 'package.json'); + +// Ensure the output directory exists +const outputDir = path.dirname(OUTPUT_FILE); +if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); +} + +console.log('šŸ” Generating frontend license report...'); + +try { + // Install license-checker if not present + try { + require.resolve('license-checker'); + } catch (e) { + console.log('šŸ“¦ Installing license-checker...'); + execSync('npm install --save-dev license-checker', { stdio: 'inherit' }); + } + + // Generate license report using license-checker (more reliable) + const licenseReport = execSync('npx license-checker --production --json', { + encoding: 'utf8', + cwd: path.dirname(PACKAGE_JSON) + }); + + let licenseData; + try { + licenseData = JSON.parse(licenseReport); + } catch (parseError) { + console.error('āŒ Failed to parse license data:', parseError.message); + console.error('Raw output:', licenseReport.substring(0, 500) + '...'); + process.exit(1); + } + + if (!licenseData || typeof licenseData !== 'object') { + console.error('āŒ Invalid license data structure'); + process.exit(1); + } + + // Convert license-checker format to array + const licenseArray = Object.entries(licenseData).map(([key, value]) => { + let name, version; + + // Handle scoped packages like @mantine/core@1.0.0 + if (key.startsWith('@')) { + const parts = key.split('@'); + name = `@${parts[1]}`; + version = parts[2]; + } else { + // Handle regular packages like react@18.0.0 + const lastAtIndex = key.lastIndexOf('@'); + name = key.substring(0, lastAtIndex); + version = key.substring(lastAtIndex + 1); + } + + // Normalize license types for edge cases + let licenseType = value.licenses; + + // Handle missing or null licenses + if (!licenseType || licenseType === null || licenseType === undefined) { + licenseType = 'Unknown'; + } + + // Handle empty string licenses + if (licenseType === '') { + licenseType = 'Unknown'; + } + + // Handle array licenses (rare but possible) + if (Array.isArray(licenseType)) { + licenseType = licenseType.join(' AND '); + } + + // Handle object licenses (fallback) + if (typeof licenseType === 'object' && licenseType !== null) { + licenseType = 'Unknown'; + } + + return { + name: name, + version: version || value.version || 'unknown', + licenseType: licenseType, + repository: value.repository, + url: value.url, + link: value.licenseUrl + }; + }); + + // Transform to match Java backend format + const transformedData = { + dependencies: licenseArray.map(dep => { + const licenseType = Array.isArray(dep.licenseType) ? dep.licenseType.join(', ') : (dep.licenseType || 'Unknown'); + const licenseUrl = dep.link || getLicenseUrl(licenseType); + + return { + moduleName: dep.name, + moduleUrl: dep.repository || dep.url || `https://www.npmjs.com/package/${dep.name}`, + moduleVersion: dep.version, + moduleLicense: licenseType, + moduleLicenseUrl: licenseUrl + }; + }) + }; + + // Log summary of license types found + const licenseSummary = licenseArray.reduce((acc, dep) => { + const license = Array.isArray(dep.licenseType) ? dep.licenseType.join(', ') : (dep.licenseType || 'Unknown'); + acc[license] = (acc[license] || 0) + 1; + return acc; + }, {}); + + console.log('šŸ“Š License types found:'); + Object.entries(licenseSummary).forEach(([license, count]) => { + console.log(` ${license}: ${count} packages`); + }); + + // Log any complex or unusual license formats for debugging + const complexLicenses = licenseArray.filter(dep => + dep.licenseType && ( + dep.licenseType.includes('AND') || + dep.licenseType.includes('OR') || + dep.licenseType === 'Unknown' || + dep.licenseType.includes('SEE LICENSE') + ) + ); + + if (complexLicenses.length > 0) { + console.log('\nšŸ” Complex/Edge case licenses detected:'); + complexLicenses.forEach(dep => { + console.log(` ${dep.name}@${dep.version}: "${dep.licenseType}"`); + }); + } + + // Check for potentially problematic licenses + const problematicLicenses = checkLicenseCompatibility(licenseSummary, licenseArray); + if (problematicLicenses.length > 0) { + console.log('\nāš ļø License compatibility warnings:'); + problematicLicenses.forEach(warning => { + console.log(` ${warning.message}`); + }); + + // Write license warnings to a separate file for CI/CD + const warningsFile = path.join(__dirname, '..', 'src', 'assets', 'license-warnings.json'); + fs.writeFileSync(warningsFile, JSON.stringify({ + warnings: problematicLicenses, + generated: new Date().toISOString() + }, null, 2)); + console.log(`āš ļø License warnings saved to: ${warningsFile}`); + } else { + console.log('\nāœ… All licenses appear to be corporate-friendly'); + } + + // Write to file + fs.writeFileSync(OUTPUT_FILE, JSON.stringify(transformedData, null, 4)); + + console.log(`āœ… License report generated successfully!`); + console.log(`šŸ“„ Found ${transformedData.dependencies.length} dependencies`); + console.log(`šŸ’¾ Saved to: ${OUTPUT_FILE}`); + +} catch (error) { + console.error('āŒ Error generating license report:', error.message); + process.exit(1); +} + +/** + * Get standard license URLs for common licenses + */ +function getLicenseUrl(licenseType) { + if (!licenseType || licenseType === 'Unknown') return ''; + + const licenseUrls = { + 'MIT': 'https://opensource.org/licenses/MIT', + 'Apache-2.0': 'https://www.apache.org/licenses/LICENSE-2.0', + 'Apache License 2.0': 'https://www.apache.org/licenses/LICENSE-2.0', + 'BSD-3-Clause': 'https://opensource.org/licenses/BSD-3-Clause', + 'BSD-2-Clause': 'https://opensource.org/licenses/BSD-2-Clause', + 'BSD': 'https://opensource.org/licenses/BSD-3-Clause', + 'GPL-3.0': 'https://www.gnu.org/licenses/gpl-3.0.html', + 'GPL-2.0': 'https://www.gnu.org/licenses/gpl-2.0.html', + 'LGPL-2.1': 'https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html', + 'LGPL-3.0': 'https://www.gnu.org/licenses/lgpl-3.0.html', + 'ISC': 'https://opensource.org/licenses/ISC', + 'CC0-1.0': 'https://creativecommons.org/publicdomain/zero/1.0/', + 'Unlicense': 'https://unlicense.org/', + 'MPL-2.0': 'https://www.mozilla.org/en-US/MPL/2.0/', + 'WTFPL': 'http://www.wtfpl.net/', + 'Zlib': 'https://opensource.org/licenses/Zlib', + 'Artistic-2.0': 'https://opensource.org/licenses/Artistic-2.0', + 'EPL-1.0': 'https://www.eclipse.org/legal/epl-v10.html', + 'EPL-2.0': 'https://www.eclipse.org/legal/epl-2.0/', + 'CDDL-1.0': 'https://opensource.org/licenses/CDDL-1.0', + 'Ruby': 'https://www.ruby-lang.org/en/about/license.txt', + 'Python-2.0': 'https://www.python.org/download/releases/2.0/license/', + 'Public Domain': 'https://creativecommons.org/publicdomain/zero/1.0/', + 'UNLICENSED': '' + }; + + // Try exact match first + if (licenseUrls[licenseType]) { + return licenseUrls[licenseType]; + } + + // Try case-insensitive match + const lowerType = licenseType.toLowerCase(); + for (const [key, url] of Object.entries(licenseUrls)) { + if (key.toLowerCase() === lowerType) { + return url; + } + } + + // Handle complex SPDX expressions like "(MIT AND Zlib)" or "(MIT OR CC0-1.0)" + if (licenseType.includes('AND') || licenseType.includes('OR')) { + // Extract the first license from compound expressions for URL + const match = licenseType.match(/\(?\s*([A-Za-z0-9\-\.]+)/); + if (match && licenseUrls[match[1]]) { + return licenseUrls[match[1]]; + } + } + + // For non-standard licenses, return empty string (will use package link if available) + return ''; +} + +/** + * Check for potentially problematic licenses that may not be MIT/corporate compatible + */ +function checkLicenseCompatibility(licenseSummary, licenseArray) { + const warnings = []; + + // Define problematic license patterns + const problematicLicenses = { + // Copyleft licenses + 'GPL-2.0': 'Strong copyleft license - requires derivative works to be GPL', + 'GPL-3.0': 'Strong copyleft license - requires derivative works to be GPL', + 'LGPL-2.1': 'Weak copyleft license - may require source disclosure for modifications', + 'LGPL-3.0': 'Weak copyleft license - may require source disclosure for modifications', + 'AGPL-3.0': 'Network copyleft license - requires source disclosure for network use', + 'AGPL-1.0': 'Network copyleft license - requires source disclosure for network use', + + // Other potentially problematic licenses + 'WTFPL': 'Potentially problematic license - legal uncertainty', + 'CC-BY-SA-4.0': 'ShareAlike license - requires derivative works to use same license', + 'CC-BY-SA-3.0': 'ShareAlike license - requires derivative works to use same license', + 'CC-BY-NC-4.0': 'Non-commercial license - prohibits commercial use', + 'CC-BY-NC-3.0': 'Non-commercial license - prohibits commercial use', + 'OSL-3.0': 'Copyleft license - requires derivative works to be OSL', + 'EPL-1.0': 'Weak copyleft license - may require source disclosure', + 'EPL-2.0': 'Weak copyleft license - may require source disclosure', + 'CDDL-1.0': 'Weak copyleft license - may require source disclosure', + 'CDDL-1.1': 'Weak copyleft license - may require source disclosure', + 'CPL-1.0': 'Weak copyleft license - may require source disclosure', + 'MPL-1.1': 'Weak copyleft license - may require source disclosure', + 'EUPL-1.1': 'Copyleft license - requires derivative works to be EUPL', + 'EUPL-1.2': 'Copyleft license - requires derivative works to be EUPL', + 'UNLICENSED': 'No license specified - usage rights unclear', + 'Unknown': 'License not detected - manual review required' + }; + + // Known good licenses (no warnings needed) + const goodLicenses = new Set([ + 'MIT', 'Apache-2.0', 'Apache License 2.0', 'BSD-2-Clause', 'BSD-3-Clause', 'BSD', + 'ISC', 'CC0-1.0', 'Public Domain', 'Unlicense', '0BSD', 'BlueOak-1.0.0', + 'Zlib', 'Artistic-2.0', 'Python-2.0', 'Ruby', 'MPL-2.0', 'CC-BY-4.0', + 'SEE LICENSE IN https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/proprietary/LICENSE' + ]); + + // Helper function to normalize license names for comparison + function normalizeLicense(license) { + return license + .replace(/-or-later$/, '') // Remove -or-later suffix + .replace(/\+$/, '') // Remove + suffix + .trim(); + } + + // Check each license type + Object.entries(licenseSummary).forEach(([license, count]) => { + // Skip known good licenses + if (goodLicenses.has(license)) { + return; + } + + // Check if this license only affects our own packages + const affectedPackages = licenseArray.filter(dep => { + const depLicense = Array.isArray(dep.licenseType) ? dep.licenseType.join(', ') : dep.licenseType; + return depLicense === license; + }); + + const isOnlyOurPackages = affectedPackages.every(dep => + dep.name === 'frontend' || + dep.name.toLowerCase().includes('stirling-pdf') || + dep.name.toLowerCase().includes('stirling_pdf') || + dep.name.toLowerCase().includes('stirlingpdf') + ); + + if (isOnlyOurPackages && (license === 'UNLICENSED' || license.startsWith('SEE LICENSE IN'))) { + return; // Skip warnings for our own Stirling-PDF packages + } + + // Check for compound licenses like "(MIT AND Zlib)" or "(MIT OR CC0-1.0)" + if (license.includes('AND') || license.includes('OR')) { + // For OR licenses, check if there's at least one acceptable license option + if (license.includes('OR')) { + // Extract license components from OR expression + const orComponents = license + .replace(/[()]/g, '') // Remove parentheses + .split(' OR ') + .map(component => component.trim()); + + // Check if any component is in the goodLicenses set (with normalization) + const hasGoodLicense = orComponents.some(component => { + const normalized = normalizeLicense(component); + return goodLicenses.has(component) || goodLicenses.has(normalized); + }); + + if (hasGoodLicense) { + return; // Skip warning - can use the good license option + } + } + + // For AND licenses or OR licenses with no good options, check for problematic components + const hasProblematicComponent = Object.keys(problematicLicenses).some(problematic => + license.includes(problematic) + ); + + if (hasProblematicComponent) { + const affectedPackages = licenseArray + .filter(dep => { + const depLicense = Array.isArray(dep.licenseType) ? dep.licenseType.join(', ') : dep.licenseType; + return depLicense === license; + }) + .map(dep => ({ + name: dep.name, + version: dep.version, + url: dep.repository || dep.url || `https://www.npmjs.com/package/${dep.name}` + })); + + const licenseType = license.includes('AND') ? 'AND' : 'OR'; + const reason = licenseType === 'AND' + ? 'Compound license with AND requirement - all components must be compatible' + : 'Compound license with potentially problematic components and no good fallback options'; + + warnings.push({ + message: `šŸ“‹ This PR contains ${count} package${count > 1 ? 's' : ''} with compound license "${license}" - manual review recommended`, + licenseType: license, + licenseUrl: '', + reason: reason, + packageCount: count, + affectedDependencies: affectedPackages + }); + } + return; + } + + // Check for exact matches with problematic licenses + if (problematicLicenses[license]) { + const affectedPackages = licenseArray + .filter(dep => { + const depLicense = Array.isArray(dep.licenseType) ? dep.licenseType.join(', ') : dep.licenseType; + return depLicense === license; + }) + .map(dep => ({ + name: dep.name, + version: dep.version, + url: dep.repository || dep.url || `https://www.npmjs.com/package/${dep.name}` + })); + + const packageList = affectedPackages.map(pkg => pkg.name).slice(0, 5).join(', ') + (affectedPackages.length > 5 ? `, and ${affectedPackages.length - 5} more` : ''); + const licenseUrl = getLicenseUrl(license) || 'https://opensource.org/licenses'; + + warnings.push({ + message: `āš ļø This PR contains ${count} package${count > 1 ? 's' : ''} with license type [${license}](${licenseUrl}) - ${problematicLicenses[license]}. Affected packages: ${packageList}`, + licenseType: license, + licenseUrl: licenseUrl, + reason: problematicLicenses[license], + packageCount: count, + affectedDependencies: affectedPackages + }); + } else { + // Unknown license type - flag for manual review + const affectedPackages = licenseArray + .filter(dep => { + const depLicense = Array.isArray(dep.licenseType) ? dep.licenseType.join(', ') : dep.licenseType; + return depLicense === license; + }) + .map(dep => ({ + name: dep.name, + version: dep.version, + url: dep.repository || dep.url || `https://www.npmjs.com/package/${dep.name}` + })); + + warnings.push({ + message: `ā“ This PR contains ${count} package${count > 1 ? 's' : ''} with unknown license type "${license}" - manual review required`, + licenseType: license, + licenseUrl: '', + reason: 'Unknown license type', + packageCount: count, + affectedDependencies: affectedPackages + }); + } + }); + + return warnings; +} \ No newline at end of file diff --git a/frontend/src/App.css b/frontend/src/App.css new file mode 100644 index 000000000..74b5e0534 --- /dev/null +++ b/frontend/src/App.css @@ -0,0 +1,38 @@ +.App { + text-align: center; +} + +.App-logo { + height: 40vmin; + pointer-events: none; +} + +@media (prefers-reduced-motion: no-preference) { + .App-logo { + animation: App-logo-spin infinite 20s linear; + } +} + +.App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; +} + +.App-link { + color: #61dafb; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx new file mode 100644 index 000000000..852204b25 --- /dev/null +++ b/frontend/src/App.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { RainbowThemeProvider } from './components/shared/RainbowThemeProvider'; +import { FileContextProvider } from './contexts/FileContext'; +import { FilesModalProvider } from './contexts/FilesModalContext'; +import HomePage from './pages/HomePage'; + +// Import global styles +import './styles/tailwind.css'; +import './index.css'; + +export default function App() { + return ( + + + + + + + + ); +} diff --git a/frontend/src/assets/3rdPartyLicenses.json b/frontend/src/assets/3rdPartyLicenses.json new file mode 100644 index 000000000..0235380af --- /dev/null +++ b/frontend/src/assets/3rdPartyLicenses.json @@ -0,0 +1,2006 @@ +{ + "dependencies": [ + { + "moduleName": "@adobe/css-tools", + "moduleUrl": "https://github.com/adobe/css-tools", + "moduleVersion": "4.4.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@alloc/quick-lru", + "moduleUrl": "https://github.com/sindresorhus/quick-lru", + "moduleVersion": "5.2.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@ampproject/remapping", + "moduleUrl": "https://github.com/ampproject/remapping", + "moduleVersion": "2.3.0", + "moduleLicense": "Apache-2.0", + "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" + }, + { + "moduleName": "@babel/code-frame", + "moduleUrl": "https://github.com/babel/babel", + "moduleVersion": "7.27.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@babel/generator", + "moduleUrl": "https://github.com/babel/babel", + "moduleVersion": "7.27.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@babel/helper-module-imports", + "moduleUrl": "https://github.com/babel/babel", + "moduleVersion": "7.27.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@babel/helper-string-parser", + "moduleUrl": "https://github.com/babel/babel", + "moduleVersion": "7.27.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@babel/helper-validator-identifier", + "moduleUrl": "https://github.com/babel/babel", + "moduleVersion": "7.27.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@babel/parser", + "moduleUrl": "https://github.com/babel/babel", + "moduleVersion": "7.27.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@babel/runtime", + "moduleUrl": "https://github.com/babel/babel", + "moduleVersion": "7.27.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@babel/template", + "moduleUrl": "https://github.com/babel/babel", + "moduleVersion": "7.27.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@babel/traverse", + "moduleUrl": "https://github.com/babel/babel", + "moduleVersion": "7.27.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@babel/types", + "moduleUrl": "https://github.com/babel/babel", + "moduleVersion": "7.27.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@emotion/babel-plugin", + "moduleUrl": "https://github.com/emotion-js/emotion/tree/main/packages/babel-plugin", + "moduleVersion": "11.13.5", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@emotion/cache", + "moduleUrl": "https://github.com/emotion-js/emotion/tree/main/packages/cache", + "moduleVersion": "11.14.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@emotion/hash", + "moduleUrl": "https://github.com/emotion-js/emotion/tree/main/packages/hash", + "moduleVersion": "0.9.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@emotion/is-prop-valid", + "moduleUrl": "https://github.com/emotion-js/emotion/tree/main/packages/is-prop-valid", + "moduleVersion": "1.3.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@emotion/memoize", + "moduleUrl": "https://github.com/emotion-js/emotion/tree/main/packages/memoize", + "moduleVersion": "0.9.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@emotion/react", + "moduleUrl": "https://github.com/emotion-js/emotion/tree/main/packages/react", + "moduleVersion": "11.14.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@emotion/serialize", + "moduleUrl": "https://github.com/emotion-js/emotion/tree/main/packages/serialize", + "moduleVersion": "1.3.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@emotion/sheet", + "moduleUrl": "https://github.com/emotion-js/emotion/tree/main/packages/sheet", + "moduleVersion": "1.4.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@emotion/styled", + "moduleUrl": "https://github.com/emotion-js/emotion/tree/main/packages/styled", + "moduleVersion": "11.14.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@emotion/unitless", + "moduleUrl": "https://github.com/emotion-js/emotion/tree/main/packages/unitless", + "moduleVersion": "0.10.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@emotion/use-insertion-effect-with-fallbacks", + "moduleUrl": "https://github.com/emotion-js/emotion/tree/main/packages/use-insertion-effect-with-fallbacks", + "moduleVersion": "1.2.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@emotion/utils", + "moduleUrl": "https://github.com/emotion-js/emotion/tree/main/packages/utils", + "moduleVersion": "1.4.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@emotion/weak-memoize", + "moduleUrl": "https://github.com/emotion-js/emotion/tree/main/packages/weak-memoize", + "moduleVersion": "0.4.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@floating-ui/core", + "moduleUrl": "https://github.com/floating-ui/floating-ui", + "moduleVersion": "1.7.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@floating-ui/dom", + "moduleUrl": "https://github.com/floating-ui/floating-ui", + "moduleVersion": "1.7.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@floating-ui/react-dom", + "moduleUrl": "https://github.com/floating-ui/floating-ui", + "moduleVersion": "2.1.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@floating-ui/react", + "moduleUrl": "https://github.com/floating-ui/floating-ui", + "moduleVersion": "0.26.28", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@floating-ui/utils", + "moduleUrl": "https://github.com/floating-ui/floating-ui", + "moduleVersion": "0.2.9", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@isaacs/fs-minipass", + "moduleUrl": "https://github.com/npm/fs-minipass", + "moduleVersion": "4.0.1", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "@jridgewell/gen-mapping", + "moduleUrl": "https://github.com/jridgewell/gen-mapping", + "moduleVersion": "0.3.8", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@jridgewell/resolve-uri", + "moduleUrl": "https://github.com/jridgewell/resolve-uri", + "moduleVersion": "3.1.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@jridgewell/set-array", + "moduleUrl": "https://github.com/jridgewell/set-array", + "moduleVersion": "1.2.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@jridgewell/sourcemap-codec", + "moduleUrl": "https://github.com/jridgewell/sourcemap-codec", + "moduleVersion": "1.5.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@jridgewell/trace-mapping", + "moduleUrl": "https://github.com/jridgewell/trace-mapping", + "moduleVersion": "0.3.25", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@mantine/core", + "moduleUrl": "https://github.com/mantinedev/mantine", + "moduleVersion": "8.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@mantine/dropzone", + "moduleUrl": "https://github.com/mantinedev/mantine", + "moduleVersion": "8.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@mantine/hooks", + "moduleUrl": "https://github.com/mantinedev/mantine", + "moduleVersion": "8.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@mapbox/node-pre-gyp", + "moduleUrl": "https://github.com/mapbox/node-pre-gyp", + "moduleVersion": "1.0.11", + "moduleLicense": "BSD-3-Clause", + "moduleLicenseUrl": "https://opensource.org/licenses/BSD-3-Clause" + }, + { + "moduleName": "@mui/core-downloads-tracker", + "moduleUrl": "https://github.com/mui/material-ui", + "moduleVersion": "7.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@mui/icons-material", + "moduleUrl": "https://github.com/mui/material-ui", + "moduleVersion": "7.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@mui/material", + "moduleUrl": "https://github.com/mui/material-ui", + "moduleVersion": "7.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@mui/private-theming", + "moduleUrl": "https://github.com/mui/material-ui", + "moduleVersion": "7.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@mui/styled-engine", + "moduleUrl": "https://github.com/mui/material-ui", + "moduleVersion": "7.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@mui/system", + "moduleUrl": "https://github.com/mui/material-ui", + "moduleVersion": "7.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@mui/types", + "moduleUrl": "https://github.com/mui/material-ui", + "moduleVersion": "7.4.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@mui/utils", + "moduleUrl": "https://github.com/mui/material-ui", + "moduleVersion": "7.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@pdf-lib/standard-fonts", + "moduleUrl": "https://github.com/Hopding/standard-fonts", + "moduleVersion": "1.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@pdf-lib/upng", + "moduleUrl": "https://github.com/Hopding/upng", + "moduleVersion": "1.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@popperjs/core", + "moduleUrl": "https://github.com/popperjs/popper-core", + "moduleVersion": "2.11.8", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@tailwindcss/node", + "moduleUrl": "https://github.com/tailwindlabs/tailwindcss", + "moduleVersion": "4.1.8", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@tailwindcss/oxide-linux-x64-gnu", + "moduleUrl": "https://github.com/tailwindlabs/tailwindcss", + "moduleVersion": "4.1.8", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@tailwindcss/oxide-linux-x64-musl", + "moduleUrl": "https://github.com/tailwindlabs/tailwindcss", + "moduleVersion": "4.1.8", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@tailwindcss/oxide", + "moduleUrl": "https://github.com/tailwindlabs/tailwindcss", + "moduleVersion": "4.1.8", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@tailwindcss/postcss", + "moduleUrl": "https://github.com/tailwindlabs/tailwindcss", + "moduleVersion": "4.1.8", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@testing-library/dom", + "moduleUrl": "https://github.com/testing-library/dom-testing-library", + "moduleVersion": "10.4.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@testing-library/jest-dom", + "moduleUrl": "https://github.com/testing-library/jest-dom", + "moduleVersion": "6.6.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@testing-library/react", + "moduleUrl": "https://github.com/testing-library/react-testing-library", + "moduleVersion": "16.3.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@testing-library/user-event", + "moduleUrl": "https://github.com/testing-library/user-event", + "moduleVersion": "13.5.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@types/aria-query", + "moduleUrl": "https://github.com/DefinitelyTyped/DefinitelyTyped", + "moduleVersion": "5.0.4", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@types/parse-json", + "moduleUrl": "https://github.com/DefinitelyTyped/DefinitelyTyped", + "moduleVersion": "4.0.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@types/prop-types", + "moduleUrl": "https://github.com/DefinitelyTyped/DefinitelyTyped", + "moduleVersion": "15.7.14", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@types/react-dom", + "moduleUrl": "https://github.com/DefinitelyTyped/DefinitelyTyped", + "moduleVersion": "19.1.5", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@types/react-transition-group", + "moduleUrl": "https://github.com/DefinitelyTyped/DefinitelyTyped", + "moduleVersion": "4.4.12", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "@types/react", + "moduleUrl": "https://github.com/DefinitelyTyped/DefinitelyTyped", + "moduleVersion": "19.1.4", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "abbrev", + "moduleUrl": "https://github.com/isaacs/abbrev-js", + "moduleVersion": "1.1.1", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "agent-base", + "moduleUrl": "https://github.com/TooTallNate/node-agent-base", + "moduleVersion": "6.0.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "ansi-regex", + "moduleUrl": "https://github.com/chalk/ansi-regex", + "moduleVersion": "5.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "ansi-styles", + "moduleUrl": "https://github.com/chalk/ansi-styles", + "moduleVersion": "4.3.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "ansi-styles", + "moduleUrl": "https://github.com/chalk/ansi-styles", + "moduleVersion": "5.2.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "aproba", + "moduleUrl": "https://github.com/iarna/aproba", + "moduleVersion": "2.0.0", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "are-we-there-yet", + "moduleUrl": "https://github.com/npm/are-we-there-yet", + "moduleVersion": "2.0.0", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "aria-query", + "moduleUrl": "https://github.com/A11yance/aria-query", + "moduleVersion": "5.3.0", + "moduleLicense": "Apache-2.0", + "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" + }, + { + "moduleName": "asynckit", + "moduleUrl": "https://github.com/alexindigo/asynckit", + "moduleVersion": "0.4.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "attr-accept", + "moduleUrl": "https://github.com/react-dropzone/attr-accept", + "moduleVersion": "2.2.5", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "autoprefixer", + "moduleUrl": "https://github.com/postcss/autoprefixer", + "moduleVersion": "10.4.21", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "axios", + "moduleUrl": "https://github.com/axios/axios", + "moduleVersion": "1.9.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "babel-plugin-macros", + "moduleUrl": "https://github.com/kentcdodds/babel-plugin-macros", + "moduleVersion": "3.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "balanced-match", + "moduleUrl": "https://github.com/juliangruber/balanced-match", + "moduleVersion": "1.0.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "brace-expansion", + "moduleUrl": "https://github.com/juliangruber/brace-expansion", + "moduleVersion": "1.1.11", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "browserslist", + "moduleUrl": "https://github.com/browserslist/browserslist", + "moduleVersion": "4.24.5", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "call-bind-apply-helpers", + "moduleUrl": "https://github.com/ljharb/call-bind-apply-helpers", + "moduleVersion": "1.0.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "callsites", + "moduleUrl": "https://github.com/sindresorhus/callsites", + "moduleVersion": "3.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "caniuse-lite", + "moduleUrl": "https://github.com/browserslist/caniuse-lite", + "moduleVersion": "1.0.30001718", + "moduleLicense": "CC-BY-4.0", + "moduleLicenseUrl": "" + }, + { + "moduleName": "canvas", + "moduleUrl": "https://github.com/Automattic/node-canvas", + "moduleVersion": "2.11.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "chalk", + "moduleUrl": "https://github.com/chalk/chalk", + "moduleVersion": "3.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "chalk", + "moduleUrl": "https://github.com/chalk/chalk", + "moduleVersion": "4.1.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "chownr", + "moduleUrl": "https://github.com/isaacs/chownr", + "moduleVersion": "2.0.0", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "chownr", + "moduleUrl": "https://github.com/isaacs/chownr", + "moduleVersion": "3.0.0", + "moduleLicense": "BlueOak-1.0.0", + "moduleLicenseUrl": "" + }, + { + "moduleName": "clsx", + "moduleUrl": "https://github.com/lukeed/clsx", + "moduleVersion": "2.1.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "color-convert", + "moduleUrl": "https://github.com/Qix-/color-convert", + "moduleVersion": "2.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "color-name", + "moduleUrl": "https://github.com/colorjs/color-name", + "moduleVersion": "1.1.4", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "color-support", + "moduleUrl": "https://github.com/isaacs/color-support", + "moduleVersion": "1.1.3", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "combined-stream", + "moduleUrl": "https://github.com/felixge/node-combined-stream", + "moduleVersion": "1.0.8", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "concat-map", + "moduleUrl": "https://github.com/substack/node-concat-map", + "moduleVersion": "0.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "console-control-strings", + "moduleUrl": "https://github.com/iarna/console-control-strings", + "moduleVersion": "1.1.0", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "convert-source-map", + "moduleUrl": "https://github.com/thlorenz/convert-source-map", + "moduleVersion": "1.9.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "cookie", + "moduleUrl": "https://github.com/jshttp/cookie", + "moduleVersion": "1.0.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "core-util-is", + "moduleUrl": "https://github.com/isaacs/core-util-is", + "moduleVersion": "1.0.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "cosmiconfig", + "moduleUrl": "https://github.com/davidtheclark/cosmiconfig", + "moduleVersion": "7.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "cross-fetch", + "moduleUrl": "https://github.com/lquixada/cross-fetch", + "moduleVersion": "4.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "css.escape", + "moduleUrl": "https://github.com/mathiasbynens/CSS.escape", + "moduleVersion": "1.5.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "csstype", + "moduleUrl": "https://github.com/frenic/csstype", + "moduleVersion": "3.1.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "debug", + "moduleUrl": "https://github.com/debug-js/debug", + "moduleVersion": "4.4.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "decompress-response", + "moduleUrl": "https://github.com/sindresorhus/decompress-response", + "moduleVersion": "4.2.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "delayed-stream", + "moduleUrl": "https://github.com/felixge/node-delayed-stream", + "moduleVersion": "1.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "delegates", + "moduleUrl": "https://github.com/visionmedia/node-delegates", + "moduleVersion": "1.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "dequal", + "moduleUrl": "https://github.com/lukeed/dequal", + "moduleVersion": "2.0.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "detect-libc", + "moduleUrl": "https://github.com/lovell/detect-libc", + "moduleVersion": "2.0.4", + "moduleLicense": "Apache-2.0", + "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" + }, + { + "moduleName": "detect-node-es", + "moduleUrl": "https://github.com/thekashey/detect-node", + "moduleVersion": "1.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "dom-accessibility-api", + "moduleUrl": "https://github.com/eps1lon/dom-accessibility-api", + "moduleVersion": "0.5.16", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "dom-accessibility-api", + "moduleUrl": "https://github.com/eps1lon/dom-accessibility-api", + "moduleVersion": "0.6.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "dom-helpers", + "moduleUrl": "https://github.com/react-bootstrap/dom-helpers", + "moduleVersion": "5.2.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "dunder-proto", + "moduleUrl": "https://github.com/es-shims/dunder-proto", + "moduleVersion": "1.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "electron-to-chromium", + "moduleUrl": "https://github.com/kilian/electron-to-chromium", + "moduleVersion": "1.5.159", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "emoji-regex", + "moduleUrl": "https://github.com/mathiasbynens/emoji-regex", + "moduleVersion": "8.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "enhanced-resolve", + "moduleUrl": "https://github.com/webpack/enhanced-resolve", + "moduleVersion": "5.18.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "error-ex", + "moduleUrl": "https://github.com/qix-/node-error-ex", + "moduleVersion": "1.3.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "es-define-property", + "moduleUrl": "https://github.com/ljharb/es-define-property", + "moduleVersion": "1.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "es-errors", + "moduleUrl": "https://github.com/ljharb/es-errors", + "moduleVersion": "1.3.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "es-object-atoms", + "moduleUrl": "https://github.com/ljharb/es-object-atoms", + "moduleVersion": "1.1.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "es-set-tostringtag", + "moduleUrl": "https://github.com/es-shims/es-set-tostringtag", + "moduleVersion": "2.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "escalade", + "moduleUrl": "https://github.com/lukeed/escalade", + "moduleVersion": "3.2.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "escape-string-regexp", + "moduleUrl": "https://github.com/sindresorhus/escape-string-regexp", + "moduleVersion": "4.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "file-selector", + "moduleUrl": "https://github.com/react-dropzone/file-selector", + "moduleVersion": "2.1.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "find-root", + "moduleUrl": "https://github.com/js-n/find-root", + "moduleVersion": "1.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "follow-redirects", + "moduleUrl": "https://github.com/follow-redirects/follow-redirects", + "moduleVersion": "1.15.9", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "form-data", + "moduleUrl": "https://github.com/form-data/form-data", + "moduleVersion": "4.0.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "fraction.js", + "moduleUrl": "https://github.com/rawify/Fraction.js", + "moduleVersion": "4.3.7", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "frontend", + "moduleUrl": "https://www.npmjs.com/package/frontend", + "moduleVersion": "0.1.0", + "moduleLicense": "UNLICENSED", + "moduleLicenseUrl": "" + }, + { + "moduleName": "fs-minipass", + "moduleUrl": "https://github.com/npm/fs-minipass", + "moduleVersion": "2.1.0", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "fs.realpath", + "moduleUrl": "https://github.com/isaacs/fs.realpath", + "moduleVersion": "1.0.0", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "function-bind", + "moduleUrl": "https://github.com/Raynos/function-bind", + "moduleVersion": "1.1.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "gauge", + "moduleUrl": "https://github.com/iarna/gauge", + "moduleVersion": "3.0.2", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "get-intrinsic", + "moduleUrl": "https://github.com/ljharb/get-intrinsic", + "moduleVersion": "1.3.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "get-nonce", + "moduleUrl": "https://github.com/theKashey/get-nonce", + "moduleVersion": "1.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "get-proto", + "moduleUrl": "https://github.com/ljharb/get-proto", + "moduleVersion": "1.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "glob", + "moduleUrl": "https://github.com/isaacs/node-glob", + "moduleVersion": "7.2.3", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "globals", + "moduleUrl": "https://github.com/sindresorhus/globals", + "moduleVersion": "11.12.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "gopd", + "moduleUrl": "https://github.com/ljharb/gopd", + "moduleVersion": "1.2.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "graceful-fs", + "moduleUrl": "https://github.com/isaacs/node-graceful-fs", + "moduleVersion": "4.2.11", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "has-flag", + "moduleUrl": "https://github.com/sindresorhus/has-flag", + "moduleVersion": "4.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "has-symbols", + "moduleUrl": "https://github.com/inspect-js/has-symbols", + "moduleVersion": "1.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "has-tostringtag", + "moduleUrl": "https://github.com/inspect-js/has-tostringtag", + "moduleVersion": "1.0.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "has-unicode", + "moduleUrl": "https://github.com/iarna/has-unicode", + "moduleVersion": "2.0.1", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "hasown", + "moduleUrl": "https://github.com/inspect-js/hasOwn", + "moduleVersion": "2.0.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "hoist-non-react-statics", + "moduleUrl": "https://github.com/mridgway/hoist-non-react-statics", + "moduleVersion": "3.3.2", + "moduleLicense": "BSD-3-Clause", + "moduleLicenseUrl": "https://opensource.org/licenses/BSD-3-Clause" + }, + { + "moduleName": "html-parse-stringify", + "moduleUrl": "https://github.com/henrikjoreteg/html-parse-stringify", + "moduleVersion": "3.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "https-proxy-agent", + "moduleUrl": "https://github.com/TooTallNate/node-https-proxy-agent", + "moduleVersion": "5.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "i18next-browser-languagedetector", + "moduleUrl": "https://github.com/i18next/i18next-browser-languageDetector", + "moduleVersion": "8.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "i18next-http-backend", + "moduleUrl": "https://github.com/i18next/i18next-http-backend", + "moduleVersion": "3.0.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "i18next", + "moduleUrl": "https://github.com/i18next/i18next", + "moduleVersion": "25.2.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "immediate", + "moduleUrl": "https://github.com/calvinmetcalf/immediate", + "moduleVersion": "3.0.6", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "import-fresh", + "moduleUrl": "https://github.com/sindresorhus/import-fresh", + "moduleVersion": "3.3.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "indent-string", + "moduleUrl": "https://github.com/sindresorhus/indent-string", + "moduleVersion": "4.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "inflight", + "moduleUrl": "https://github.com/npm/inflight", + "moduleVersion": "1.0.6", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "inherits", + "moduleUrl": "https://github.com/isaacs/inherits", + "moduleVersion": "2.0.4", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "is-arrayish", + "moduleUrl": "https://github.com/qix-/node-is-arrayish", + "moduleVersion": "0.2.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "is-core-module", + "moduleUrl": "https://github.com/inspect-js/is-core-module", + "moduleVersion": "2.16.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "is-fullwidth-code-point", + "moduleUrl": "https://github.com/sindresorhus/is-fullwidth-code-point", + "moduleVersion": "3.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "isarray", + "moduleUrl": "https://github.com/juliangruber/isarray", + "moduleVersion": "1.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "jiti", + "moduleUrl": "https://github.com/unjs/jiti", + "moduleVersion": "2.4.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "js-tokens", + "moduleUrl": "https://github.com/lydell/js-tokens", + "moduleVersion": "4.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "jsesc", + "moduleUrl": "https://github.com/mathiasbynens/jsesc", + "moduleVersion": "3.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "json-parse-even-better-errors", + "moduleUrl": "https://github.com/npm/json-parse-even-better-errors", + "moduleVersion": "2.3.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "jszip", + "moduleUrl": "https://github.com/Stuk/jszip", + "moduleVersion": "3.10.1", + "moduleLicense": "(MIT OR GPL-3.0-or-later)", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "lie", + "moduleUrl": "https://github.com/calvinmetcalf/lie", + "moduleVersion": "3.3.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "lightningcss-linux-x64-gnu", + "moduleUrl": "https://github.com/parcel-bundler/lightningcss", + "moduleVersion": "1.30.1", + "moduleLicense": "MPL-2.0", + "moduleLicenseUrl": "https://www.mozilla.org/en-US/MPL/2.0/" + }, + { + "moduleName": "lightningcss-linux-x64-musl", + "moduleUrl": "https://github.com/parcel-bundler/lightningcss", + "moduleVersion": "1.30.1", + "moduleLicense": "MPL-2.0", + "moduleLicenseUrl": "https://www.mozilla.org/en-US/MPL/2.0/" + }, + { + "moduleName": "lightningcss", + "moduleUrl": "https://github.com/parcel-bundler/lightningcss", + "moduleVersion": "1.30.1", + "moduleLicense": "MPL-2.0", + "moduleLicenseUrl": "https://www.mozilla.org/en-US/MPL/2.0/" + }, + { + "moduleName": "lines-and-columns", + "moduleUrl": "https://github.com/eventualbuddha/lines-and-columns", + "moduleVersion": "1.2.4", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "lodash", + "moduleUrl": "https://github.com/lodash/lodash", + "moduleVersion": "4.17.21", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "loose-envify", + "moduleUrl": "https://github.com/zertosh/loose-envify", + "moduleVersion": "1.4.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "lz-string", + "moduleUrl": "https://github.com/pieroxy/lz-string", + "moduleVersion": "1.5.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "magic-string", + "moduleUrl": "https://github.com/rich-harris/magic-string", + "moduleVersion": "0.30.17", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "make-dir", + "moduleUrl": "https://github.com/sindresorhus/make-dir", + "moduleVersion": "3.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "material-symbols", + "moduleUrl": "https://github.com/marella/material-symbols", + "moduleVersion": "0.33.0", + "moduleLicense": "Apache-2.0", + "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" + }, + { + "moduleName": "math-intrinsics", + "moduleUrl": "https://github.com/es-shims/math-intrinsics", + "moduleVersion": "1.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "mime-db", + "moduleUrl": "https://github.com/jshttp/mime-db", + "moduleVersion": "1.52.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "mime-types", + "moduleUrl": "https://github.com/jshttp/mime-types", + "moduleVersion": "2.1.35", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "mimic-response", + "moduleUrl": "https://github.com/sindresorhus/mimic-response", + "moduleVersion": "2.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "min-indent", + "moduleUrl": "https://github.com/thejameskyle/min-indent", + "moduleVersion": "1.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "minimatch", + "moduleUrl": "https://github.com/isaacs/minimatch", + "moduleVersion": "3.1.2", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "minipass", + "moduleUrl": "https://github.com/isaacs/minipass", + "moduleVersion": "3.3.6", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "minipass", + "moduleUrl": "https://github.com/isaacs/minipass", + "moduleVersion": "5.0.0", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "minipass", + "moduleUrl": "https://github.com/isaacs/minipass", + "moduleVersion": "7.1.2", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "minizlib", + "moduleUrl": "https://github.com/isaacs/minizlib", + "moduleVersion": "2.1.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "minizlib", + "moduleUrl": "https://github.com/isaacs/minizlib", + "moduleVersion": "3.0.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "mkdirp", + "moduleUrl": "https://github.com/isaacs/node-mkdirp", + "moduleVersion": "1.0.4", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "mkdirp", + "moduleUrl": "https://github.com/isaacs/node-mkdirp", + "moduleVersion": "3.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "ms", + "moduleUrl": "https://github.com/vercel/ms", + "moduleVersion": "2.1.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "nan", + "moduleUrl": "https://github.com/nodejs/nan", + "moduleVersion": "2.22.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "nanoid", + "moduleUrl": "https://github.com/ai/nanoid", + "moduleVersion": "3.3.11", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "node-fetch", + "moduleUrl": "https://github.com/bitinn/node-fetch", + "moduleVersion": "2.7.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "node-releases", + "moduleUrl": "https://github.com/chicoxyzzy/node-releases", + "moduleVersion": "2.0.19", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "nopt", + "moduleUrl": "https://github.com/npm/nopt", + "moduleVersion": "5.0.0", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "normalize-range", + "moduleUrl": "https://github.com/jamestalmage/normalize-range", + "moduleVersion": "0.1.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "npmlog", + "moduleUrl": "https://github.com/npm/npmlog", + "moduleVersion": "5.0.1", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "object-assign", + "moduleUrl": "https://github.com/sindresorhus/object-assign", + "moduleVersion": "4.1.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "once", + "moduleUrl": "https://github.com/isaacs/once", + "moduleVersion": "1.4.0", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "pako", + "moduleUrl": "https://github.com/nodeca/pako", + "moduleVersion": "1.0.11", + "moduleLicense": "(MIT AND Zlib)", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "parent-module", + "moduleUrl": "https://github.com/sindresorhus/parent-module", + "moduleVersion": "1.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "parse-json", + "moduleUrl": "https://github.com/sindresorhus/parse-json", + "moduleVersion": "5.2.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "path-is-absolute", + "moduleUrl": "https://github.com/sindresorhus/path-is-absolute", + "moduleVersion": "1.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "path-parse", + "moduleUrl": "https://github.com/jbgutierrez/path-parse", + "moduleVersion": "1.0.7", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "path-type", + "moduleUrl": "https://github.com/sindresorhus/path-type", + "moduleVersion": "4.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "path2d-polyfill", + "moduleUrl": "https://github.com/nilzona/path2d-polyfill", + "moduleVersion": "2.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "pdf-lib", + "moduleUrl": "https://github.com/Hopding/pdf-lib", + "moduleVersion": "1.17.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "pdfjs-dist", + "moduleUrl": "https://github.com/mozilla/pdfjs-dist", + "moduleVersion": "3.11.174", + "moduleLicense": "Apache-2.0", + "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" + }, + { + "moduleName": "picocolors", + "moduleUrl": "https://github.com/alexeyraspopov/picocolors", + "moduleVersion": "1.1.1", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "postcss-value-parser", + "moduleUrl": "https://github.com/TrySound/postcss-value-parser", + "moduleVersion": "4.2.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "postcss", + "moduleUrl": "https://github.com/postcss/postcss", + "moduleVersion": "8.5.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "pretty-format", + "moduleUrl": "https://github.com/facebook/jest", + "moduleVersion": "27.5.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "process-nextick-args", + "moduleUrl": "https://github.com/calvinmetcalf/process-nextick-args", + "moduleVersion": "2.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "prop-types", + "moduleUrl": "https://github.com/facebook/prop-types", + "moduleVersion": "15.8.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "proxy-from-env", + "moduleUrl": "https://github.com/Rob--W/proxy-from-env", + "moduleVersion": "1.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-dom", + "moduleUrl": "https://github.com/facebook/react", + "moduleVersion": "19.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-dropzone", + "moduleUrl": "https://github.com/react-dropzone/react-dropzone", + "moduleVersion": "14.3.8", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-i18next", + "moduleUrl": "https://github.com/i18next/react-i18next", + "moduleVersion": "15.5.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-is", + "moduleUrl": "https://github.com/facebook/react", + "moduleVersion": "16.13.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-is", + "moduleUrl": "https://github.com/facebook/react", + "moduleVersion": "17.0.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-is", + "moduleUrl": "https://github.com/facebook/react", + "moduleVersion": "19.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-number-format", + "moduleUrl": "https://github.com/s-yadav/react-number-format", + "moduleVersion": "5.4.4", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-remove-scroll-bar", + "moduleUrl": "https://github.com/theKashey/react-remove-scroll-bar", + "moduleVersion": "2.3.8", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-remove-scroll", + "moduleUrl": "https://github.com/theKashey/react-remove-scroll", + "moduleVersion": "2.6.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-router-dom", + "moduleUrl": "https://github.com/remix-run/react-router", + "moduleVersion": "7.6.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-router", + "moduleUrl": "https://github.com/remix-run/react-router", + "moduleVersion": "7.6.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-style-singleton", + "moduleUrl": "https://github.com/theKashey/react-style-singleton", + "moduleVersion": "2.2.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-textarea-autosize", + "moduleUrl": "https://github.com/Andarist/react-textarea-autosize", + "moduleVersion": "8.5.9", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "react-transition-group", + "moduleUrl": "https://github.com/reactjs/react-transition-group", + "moduleVersion": "4.4.5", + "moduleLicense": "BSD-3-Clause", + "moduleLicenseUrl": "https://opensource.org/licenses/BSD-3-Clause" + }, + { + "moduleName": "react", + "moduleUrl": "https://github.com/facebook/react", + "moduleVersion": "19.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "readable-stream", + "moduleUrl": "https://github.com/nodejs/readable-stream", + "moduleVersion": "2.3.8", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "readable-stream", + "moduleUrl": "https://github.com/nodejs/readable-stream", + "moduleVersion": "3.6.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "redent", + "moduleUrl": "https://github.com/sindresorhus/redent", + "moduleVersion": "3.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "resolve-from", + "moduleUrl": "https://github.com/sindresorhus/resolve-from", + "moduleVersion": "4.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "resolve", + "moduleUrl": "https://github.com/browserify/resolve", + "moduleVersion": "1.22.10", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "rimraf", + "moduleUrl": "https://github.com/isaacs/rimraf", + "moduleVersion": "3.0.2", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "safe-buffer", + "moduleUrl": "https://github.com/feross/safe-buffer", + "moduleVersion": "5.1.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "safe-buffer", + "moduleUrl": "https://github.com/feross/safe-buffer", + "moduleVersion": "5.2.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "scheduler", + "moduleUrl": "https://github.com/facebook/react", + "moduleVersion": "0.26.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "semver", + "moduleUrl": "https://github.com/npm/node-semver", + "moduleVersion": "6.3.1", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "semver", + "moduleUrl": "https://github.com/npm/node-semver", + "moduleVersion": "7.7.2", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "set-blocking", + "moduleUrl": "https://github.com/yargs/set-blocking", + "moduleVersion": "2.0.0", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "set-cookie-parser", + "moduleUrl": "https://github.com/nfriedly/set-cookie-parser", + "moduleVersion": "2.7.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "setimmediate", + "moduleUrl": "https://github.com/YuzuJS/setImmediate", + "moduleVersion": "1.0.5", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "signal-exit", + "moduleUrl": "https://github.com/tapjs/signal-exit", + "moduleVersion": "3.0.7", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "simple-concat", + "moduleUrl": "https://github.com/feross/simple-concat", + "moduleVersion": "1.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "simple-get", + "moduleUrl": "https://github.com/feross/simple-get", + "moduleVersion": "3.1.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "source-map-js", + "moduleUrl": "https://github.com/7rulnik/source-map-js", + "moduleVersion": "1.2.1", + "moduleLicense": "BSD-3-Clause", + "moduleLicenseUrl": "https://opensource.org/licenses/BSD-3-Clause" + }, + { + "moduleName": "source-map", + "moduleUrl": "https://github.com/mozilla/source-map", + "moduleVersion": "0.5.7", + "moduleLicense": "BSD-3-Clause", + "moduleLicenseUrl": "https://opensource.org/licenses/BSD-3-Clause" + }, + { + "moduleName": "string-width", + "moduleUrl": "https://github.com/sindresorhus/string-width", + "moduleVersion": "4.2.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "string_decoder", + "moduleUrl": "https://github.com/nodejs/string_decoder", + "moduleVersion": "1.1.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "string_decoder", + "moduleUrl": "https://github.com/nodejs/string_decoder", + "moduleVersion": "1.3.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "strip-ansi", + "moduleUrl": "https://github.com/chalk/strip-ansi", + "moduleVersion": "6.0.1", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "strip-indent", + "moduleUrl": "https://github.com/sindresorhus/strip-indent", + "moduleVersion": "3.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "stylis", + "moduleUrl": "https://github.com/thysultan/stylis.js", + "moduleVersion": "4.2.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "supports-color", + "moduleUrl": "https://github.com/chalk/supports-color", + "moduleVersion": "7.2.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "supports-preserve-symlinks-flag", + "moduleUrl": "https://github.com/inspect-js/node-supports-preserve-symlinks-flag", + "moduleVersion": "1.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "tabbable", + "moduleUrl": "https://github.com/focus-trap/tabbable", + "moduleVersion": "6.2.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "tailwindcss", + "moduleUrl": "https://github.com/tailwindlabs/tailwindcss", + "moduleVersion": "4.1.8", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "tapable", + "moduleUrl": "https://github.com/webpack/tapable", + "moduleVersion": "2.2.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "tar", + "moduleUrl": "https://github.com/isaacs/node-tar", + "moduleVersion": "6.2.1", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "tar", + "moduleUrl": "https://github.com/isaacs/node-tar", + "moduleVersion": "7.4.3", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "tr46", + "moduleUrl": "https://github.com/Sebmaster/tr46.js", + "moduleVersion": "0.0.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "tslib", + "moduleUrl": "https://github.com/Microsoft/tslib", + "moduleVersion": "1.14.1", + "moduleLicense": "0BSD", + "moduleLicenseUrl": "" + }, + { + "moduleName": "tslib", + "moduleUrl": "https://github.com/Microsoft/tslib", + "moduleVersion": "2.8.1", + "moduleLicense": "0BSD", + "moduleLicenseUrl": "" + }, + { + "moduleName": "type-fest", + "moduleUrl": "https://github.com/sindresorhus/type-fest", + "moduleVersion": "4.41.0", + "moduleLicense": "(MIT OR CC0-1.0)", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "typescript", + "moduleUrl": "https://github.com/microsoft/TypeScript", + "moduleVersion": "5.8.3", + "moduleLicense": "Apache-2.0", + "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" + }, + { + "moduleName": "update-browserslist-db", + "moduleUrl": "https://github.com/browserslist/update-db", + "moduleVersion": "1.1.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "use-callback-ref", + "moduleUrl": "https://github.com/theKashey/use-callback-ref", + "moduleVersion": "1.3.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "use-composed-ref", + "moduleUrl": "https://github.com/Andarist/use-composed-ref", + "moduleVersion": "1.4.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "use-isomorphic-layout-effect", + "moduleUrl": "https://github.com/Andarist/use-isomorphic-layout-effect", + "moduleVersion": "1.2.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "use-latest", + "moduleUrl": "https://github.com/Andarist/use-latest", + "moduleVersion": "1.3.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "use-sidecar", + "moduleUrl": "https://github.com/theKashey/use-sidecar", + "moduleVersion": "1.1.3", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "util-deprecate", + "moduleUrl": "https://github.com/TooTallNate/util-deprecate", + "moduleVersion": "1.0.2", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "void-elements", + "moduleUrl": "https://github.com/pugjs/void-elements", + "moduleVersion": "3.1.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "web-vitals", + "moduleUrl": "https://github.com/GoogleChrome/web-vitals", + "moduleVersion": "2.1.4", + "moduleLicense": "Apache-2.0", + "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" + }, + { + "moduleName": "webidl-conversions", + "moduleUrl": "https://github.com/jsdom/webidl-conversions", + "moduleVersion": "3.0.1", + "moduleLicense": "BSD-2-Clause", + "moduleLicenseUrl": "https://opensource.org/licenses/BSD-2-Clause" + }, + { + "moduleName": "whatwg-url", + "moduleUrl": "https://github.com/jsdom/whatwg-url", + "moduleVersion": "5.0.0", + "moduleLicense": "MIT", + "moduleLicenseUrl": "https://opensource.org/licenses/MIT" + }, + { + "moduleName": "wide-align", + "moduleUrl": "https://github.com/iarna/wide-align", + "moduleVersion": "1.1.5", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "wrappy", + "moduleUrl": "https://github.com/npm/wrappy", + "moduleVersion": "1.0.2", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "yallist", + "moduleUrl": "https://github.com/isaacs/yallist", + "moduleVersion": "4.0.0", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + }, + { + "moduleName": "yallist", + "moduleUrl": "https://github.com/isaacs/yallist", + "moduleVersion": "5.0.0", + "moduleLicense": "BlueOak-1.0.0", + "moduleLicenseUrl": "" + }, + { + "moduleName": "yaml", + "moduleUrl": "https://github.com/eemeli/yaml", + "moduleVersion": "1.10.2", + "moduleLicense": "ISC", + "moduleLicenseUrl": "https://opensource.org/licenses/ISC" + } + ] +} \ No newline at end of file diff --git a/frontend/src/commands/pageCommands.ts b/frontend/src/commands/pageCommands.ts new file mode 100644 index 000000000..4e5572234 --- /dev/null +++ b/frontend/src/commands/pageCommands.ts @@ -0,0 +1,315 @@ +import { Command, CommandSequence } from '../hooks/useUndoRedo'; +import { PDFDocument, PDFPage } from '../types/pageEditor'; + +// Base class for page operations +abstract class PageCommand implements Command { + protected pdfDocument: PDFDocument; + protected setPdfDocument: (doc: PDFDocument) => void; + protected previousState: PDFDocument; + + constructor( + pdfDocument: PDFDocument, + setPdfDocument: (doc: PDFDocument) => void + ) { + this.pdfDocument = pdfDocument; + this.setPdfDocument = setPdfDocument; + this.previousState = JSON.parse(JSON.stringify(pdfDocument)); // Deep clone + } + + abstract execute(): void; + abstract description: string; + + undo(): void { + this.setPdfDocument(this.previousState); + } +} + +// Rotate pages command +export class RotatePagesCommand extends PageCommand { + private pageIds: string[]; + private rotation: number; + + constructor( + pdfDocument: PDFDocument, + setPdfDocument: (doc: PDFDocument) => void, + pageIds: string[], + rotation: number + ) { + super(pdfDocument, setPdfDocument); + this.pageIds = pageIds; + this.rotation = rotation; + } + + execute(): void { + const updatedPages = this.pdfDocument.pages.map(page => { + if (this.pageIds.includes(page.id)) { + return { ...page, rotation: page.rotation + this.rotation }; + } + return page; + }); + + this.setPdfDocument({ ...this.pdfDocument, pages: updatedPages }); + } + + get description(): string { + const direction = this.rotation > 0 ? 'right' : 'left'; + return `Rotate ${this.pageIds.length} page(s) ${direction}`; + } +} + +// Delete pages command +export class DeletePagesCommand extends PageCommand { + private pageIds: string[]; + private deletedPages: PDFPage[]; + private deletedPositions: Map; + + constructor( + pdfDocument: PDFDocument, + setPdfDocument: (doc: PDFDocument) => void, + pageIds: string[] + ) { + super(pdfDocument, setPdfDocument); + this.pageIds = pageIds; + this.deletedPages = []; + this.deletedPositions = new Map(); + } + + execute(): void { + // Store deleted pages and their positions for undo + this.deletedPages = this.pdfDocument.pages.filter(page => + this.pageIds.includes(page.id) + ); + + this.deletedPages.forEach(page => { + const index = this.pdfDocument.pages.findIndex(p => p.id === page.id); + this.deletedPositions.set(page.id, index); + }); + + const updatedPages = this.pdfDocument.pages + .filter(page => !this.pageIds.includes(page.id)) + .map((page, index) => ({ ...page, pageNumber: index + 1 })); + + this.setPdfDocument({ + ...this.pdfDocument, + pages: updatedPages, + totalPages: updatedPages.length + }); + } + + undo(): void { + // Simply restore to the previous state (before deletion) + this.setPdfDocument(this.previousState); + } + + get description(): string { + return `Delete ${this.pageIds.length} page(s)`; + } +} + +// Move pages command +export class MovePagesCommand extends PageCommand { + private pageIds: string[]; + private targetIndex: number; + private originalIndices: Map; + + constructor( + pdfDocument: PDFDocument, + setPdfDocument: (doc: PDFDocument) => void, + pageIds: string[], + targetIndex: number + ) { + super(pdfDocument, setPdfDocument); + this.pageIds = pageIds; + this.targetIndex = targetIndex; + this.originalIndices = new Map(); + } + + execute(): void { + // Store original positions + this.pageIds.forEach(pageId => { + const index = this.pdfDocument.pages.findIndex(p => p.id === pageId); + this.originalIndices.set(pageId, index); + }); + + let newPages = [...this.pdfDocument.pages]; + const pagesToMove = this.pageIds + .map(id => this.pdfDocument.pages.find(p => p.id === id)) + .filter((page): page is PDFPage => page !== undefined); + + // Remove pages to move + newPages = newPages.filter(page => !this.pageIds.includes(page.id)); + + // Insert pages at target position + newPages.splice(this.targetIndex, 0, ...pagesToMove); + + // Update page numbers + newPages = newPages.map((page, index) => ({ + ...page, + pageNumber: index + 1 + })); + + this.setPdfDocument({ ...this.pdfDocument, pages: newPages }); + } + + get description(): string { + return `Move ${this.pageIds.length} page(s)`; + } +} + +// Reorder single page command (for drag-and-drop) +export class ReorderPageCommand extends PageCommand { + private pageId: string; + private targetIndex: number; + private originalIndex: number; + + constructor( + pdfDocument: PDFDocument, + setPdfDocument: (doc: PDFDocument) => void, + pageId: string, + targetIndex: number + ) { + super(pdfDocument, setPdfDocument); + this.pageId = pageId; + this.targetIndex = targetIndex; + this.originalIndex = pdfDocument.pages.findIndex(p => p.id === pageId); + } + + execute(): void { + const newPages = [...this.pdfDocument.pages]; + const [movedPage] = newPages.splice(this.originalIndex, 1); + newPages.splice(this.targetIndex, 0, movedPage); + + // Update page numbers + const updatedPages = newPages.map((page, index) => ({ + ...page, + pageNumber: index + 1 + })); + + this.setPdfDocument({ ...this.pdfDocument, pages: updatedPages }); + } + + get description(): string { + return `Reorder page ${this.originalIndex + 1} to position ${this.targetIndex + 1}`; + } +} + +// Toggle split markers command +export class ToggleSplitCommand extends PageCommand { + private pageIds: string[]; + private previousSplitStates: Map; + + constructor( + pdfDocument: PDFDocument, + setPdfDocument: (doc: PDFDocument) => void, + pageIds: string[] + ) { + super(pdfDocument, setPdfDocument); + this.pageIds = pageIds; + this.previousSplitStates = new Map(); + } + + execute(): void { + // Store previous split states + this.pageIds.forEach(pageId => { + const page = this.pdfDocument.pages.find(p => p.id === pageId); + if (page) { + this.previousSplitStates.set(pageId, !!page.splitBefore); + } + }); + + const updatedPages = this.pdfDocument.pages.map(page => { + if (this.pageIds.includes(page.id)) { + return { ...page, splitBefore: !page.splitBefore }; + } + return page; + }); + + this.setPdfDocument({ ...this.pdfDocument, pages: updatedPages }); + } + + undo(): void { + const updatedPages = this.pdfDocument.pages.map(page => { + if (this.pageIds.includes(page.id)) { + const previousState = this.previousSplitStates.get(page.id); + return { ...page, splitBefore: previousState }; + } + return page; + }); + + this.setPdfDocument({ ...this.pdfDocument, pages: updatedPages }); + } + + get description(): string { + return `Toggle split markers for ${this.pageIds.length} page(s)`; + } +} + +// Add pages command (for inserting new files) +export class AddPagesCommand extends PageCommand { + private newPages: PDFPage[]; + private insertIndex: number; + + constructor( + pdfDocument: PDFDocument, + setPdfDocument: (doc: PDFDocument) => void, + newPages: PDFPage[], + insertIndex: number = -1 // -1 means append to end + ) { + super(pdfDocument, setPdfDocument); + this.newPages = newPages; + this.insertIndex = insertIndex === -1 ? pdfDocument.pages.length : insertIndex; + } + + execute(): void { + const newPagesArray = [...this.pdfDocument.pages]; + newPagesArray.splice(this.insertIndex, 0, ...this.newPages); + + // Update page numbers for all pages + const updatedPages = newPagesArray.map((page, index) => ({ + ...page, + pageNumber: index + 1 + })); + + this.setPdfDocument({ + ...this.pdfDocument, + pages: updatedPages, + totalPages: updatedPages.length + }); + } + + undo(): void { + const updatedPages = this.pdfDocument.pages + .filter(page => !this.newPages.some(newPage => newPage.id === page.id)) + .map((page, index) => ({ ...page, pageNumber: index + 1 })); + + this.setPdfDocument({ + ...this.pdfDocument, + pages: updatedPages, + totalPages: updatedPages.length + }); + } + + get description(): string { + return `Add ${this.newPages.length} page(s)`; + } +} + +// Command sequence for bulk operations +export class PageCommandSequence implements CommandSequence { + commands: Command[]; + description: string; + + constructor(commands: Command[], description?: string) { + this.commands = commands; + this.description = description || `Execute ${commands.length} operations`; + } + + execute(): void { + this.commands.forEach(command => command.execute()); + } + + undo(): void { + // Undo in reverse order + [...this.commands].reverse().forEach(command => command.undo()); + } +} \ No newline at end of file diff --git a/frontend/src/components/FileCard.standalone.tsx b/frontend/src/components/FileCard.standalone.tsx new file mode 100644 index 000000000..4d140689b --- /dev/null +++ b/frontend/src/components/FileCard.standalone.tsx @@ -0,0 +1,136 @@ +import React from "react"; +import { Card, Stack, Text, Group, Badge, Button, Box, Image, ThemeIcon } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf"; +import StorageIcon from "@mui/icons-material/Storage"; + +import { FileWithUrl } from "../types/file"; +import { getFileSize, getFileDate } from "../utils/fileUtils"; +import { useIndexedDBThumbnail } from "../hooks/useIndexedDBThumbnail"; + +interface FileCardProps { + file: FileWithUrl; + onRemove: () => void; + onDoubleClick?: () => void; +} + +const FileCard: React.FC = ({ file, onRemove, onDoubleClick }) => { + const { t } = useTranslation(); + const { thumbnail: thumb, isGenerating } = useIndexedDBThumbnail(file); + + return ( + + + + {thumb ? ( + PDF thumbnail + ) : isGenerating ? ( +
+
+ Generating... +
+ ) : ( +
+ 100 * 1024 * 1024 ? "orange" : "red"} + size={60} + radius="sm" + style={{ display: "flex", alignItems: "center", justifyContent: "center" }} + > + + + {file.size > 100 * 1024 * 1024 && ( + Large File + )} +
+ )} + + + + {file.name} + + + + + {getFileSize(file)} + + + {getFileDate(file)} + + {file.storedInIndexedDB && ( + } + > + DB + + )} + + + + + + ); +}; + +export default FileCard; \ No newline at end of file diff --git a/frontend/src/components/FileManager.tsx b/frontend/src/components/FileManager.tsx new file mode 100644 index 000000000..02f9af5e4 --- /dev/null +++ b/frontend/src/components/FileManager.tsx @@ -0,0 +1,168 @@ +import React, { useState, useCallback, useEffect } from 'react'; +import { Modal } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { FileWithUrl } from '../types/file'; +import { useFileManager } from '../hooks/useFileManager'; +import { useFilesModalContext } from '../contexts/FilesModalContext'; +import { Tool } from '../types/tool'; +import MobileLayout from './fileManager/MobileLayout'; +import DesktopLayout from './fileManager/DesktopLayout'; +import DragOverlay from './fileManager/DragOverlay'; +import { FileManagerProvider } from '../contexts/FileManagerContext'; + +interface FileManagerProps { + selectedTool?: Tool | null; +} + +const FileManager: React.FC = ({ selectedTool }) => { + const { isFilesModalOpen, closeFilesModal, onFilesSelect } = useFilesModalContext(); + const [recentFiles, setRecentFiles] = useState([]); + const [isDragging, setIsDragging] = useState(false); + const [isMobile, setIsMobile] = useState(false); + + const { loadRecentFiles, handleRemoveFile, storeFile, convertToFile } = useFileManager(); + + // File management handlers + const isFileSupported = useCallback((fileName: string) => { + if (!selectedTool?.supportedFormats) return true; + const extension = fileName.split('.').pop()?.toLowerCase(); + return selectedTool.supportedFormats.includes(extension || ''); + }, [selectedTool?.supportedFormats]); + + const refreshRecentFiles = useCallback(async () => { + const files = await loadRecentFiles(); + setRecentFiles(files); + }, [loadRecentFiles]); + + const handleFilesSelected = useCallback(async (files: FileWithUrl[]) => { + try { + const fileObjects = await Promise.all( + files.map(async (fileWithUrl) => { + return await convertToFile(fileWithUrl); + }) + ); + onFilesSelect(fileObjects); + } catch (error) { + console.error('Failed to process selected files:', error); + } + }, [convertToFile, onFilesSelect]); + + const handleNewFileUpload = useCallback(async (files: File[]) => { + if (files.length > 0) { + try { + // Files will get IDs assigned through onFilesSelect -> FileContext addFiles + onFilesSelect(files); + await refreshRecentFiles(); + } catch (error) { + console.error('Failed to process dropped files:', error); + } + } + }, [onFilesSelect, refreshRecentFiles]); + + const handleRemoveFileByIndex = useCallback(async (index: number) => { + await handleRemoveFile(index, recentFiles, setRecentFiles); + }, [handleRemoveFile, recentFiles]); + + useEffect(() => { + const checkMobile = () => setIsMobile(window.innerWidth < 1030); + checkMobile(); + window.addEventListener('resize', checkMobile); + return () => window.removeEventListener('resize', checkMobile); + }, []); + + useEffect(() => { + if (isFilesModalOpen) { + refreshRecentFiles(); + } else { + // Reset state when modal is closed + setIsDragging(false); + } + }, [isFilesModalOpen, refreshRecentFiles]); + + // Cleanup any blob URLs when component unmounts + useEffect(() => { + return () => { + // Clean up blob URLs from recent files + recentFiles.forEach(file => { + if (file.url && file.url.startsWith('blob:')) { + URL.revokeObjectURL(file.url); + } + }); + }; + }, [recentFiles]); + + // Modal size constants for consistent scaling + const modalHeight = '80vh'; + const modalWidth = isMobile ? '100%' : '80vw'; + const modalMaxWidth = isMobile ? '100%' : '1200px'; + const modalMaxHeight = '1200px'; + const modalMinWidth = isMobile ? '320px' : '800px'; + + return ( + +
+ setIsDragging(true)} + onDragLeave={() => setIsDragging(false)} + accept={["*/*"]} + multiple={true} + activateOnClick={false} + style={{ + height: '100%', + width: '100%', + border: 'none', + borderRadius: '30px', + backgroundColor: 'var(--bg-file-manager)' + }} + styles={{ + inner: { pointerEvents: 'all' } + }} + > + + {isMobile ? : } + + + + +
+
+ ); +}; + +export default FileManager; \ No newline at end of file diff --git a/frontend/src/components/StorageStatsCard.tsx b/frontend/src/components/StorageStatsCard.tsx new file mode 100644 index 000000000..31c991208 --- /dev/null +++ b/frontend/src/components/StorageStatsCard.tsx @@ -0,0 +1,76 @@ +import React from "react"; +import { Card, Group, Text, Button, Progress } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import StorageIcon from "@mui/icons-material/Storage"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { StorageStats } from "../services/fileStorage"; +import { formatFileSize } from "../utils/fileUtils"; +import { getStorageUsagePercent } from "../utils/storageUtils"; + +interface StorageStatsCardProps { + storageStats: StorageStats | null; + filesCount: number; + onClearAll: () => void; + onReloadFiles: () => void; +} + +const StorageStatsCard: React.FC = ({ + storageStats, + filesCount, + onClearAll, + onReloadFiles, +}) => { + const { t } = useTranslation(); + + if (!storageStats) return null; + + const storageUsagePercent = getStorageUsagePercent(storageStats); + + return ( + + + +
+ + {t("fileManager.storage", "Storage")}: {formatFileSize(storageStats.used)} + {storageStats.quota && ` / ${formatFileSize(storageStats.quota)}`} + + {storageStats.quota && ( + 80 ? "red" : storageUsagePercent > 60 ? "yellow" : "blue"} + size="sm" + mt={4} + /> + )} + + {storageStats.fileCount} {t("fileManager.filesStored", "files stored")} + +
+ + {filesCount > 0 && ( + + )} + + +
+
+ ); +}; + +export default StorageStatsCard; \ No newline at end of file diff --git a/frontend/src/components/fileEditor/FileEditor.tsx b/frontend/src/components/fileEditor/FileEditor.tsx new file mode 100644 index 000000000..ca5f594b8 --- /dev/null +++ b/frontend/src/components/fileEditor/FileEditor.tsx @@ -0,0 +1,863 @@ +import React, { useState, useCallback, useRef, useEffect } from 'react'; +import { + Button, Text, Center, Box, Notification, TextInput, LoadingOverlay, Modal, Alert, Container, + Stack, Group +} from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { useTranslation } from 'react-i18next'; +import UploadFileIcon from '@mui/icons-material/UploadFile'; +import { useFileContext } from '../../contexts/FileContext'; +import { useFileSelection } from '../../contexts/FileSelectionContext'; +import { FileOperation } from '../../types/fileContext'; +import { fileStorage } from '../../services/fileStorage'; +import { generateThumbnailForFile } from '../../utils/thumbnailUtils'; +import { zipFileService } from '../../services/zipFileService'; +import { detectFileExtension } from '../../utils/fileUtils'; +import styles from '../pageEditor/PageEditor.module.css'; +import FileThumbnail from '../pageEditor/FileThumbnail'; +import DragDropGrid from '../pageEditor/DragDropGrid'; +import FilePickerModal from '../shared/FilePickerModal'; +import SkeletonLoader from '../shared/SkeletonLoader'; + +interface FileItem { + id: string; + name: string; + pageCount: number; + thumbnail: string; + size: number; + file: File; + splitBefore?: boolean; +} + +interface FileEditorProps { + onOpenPageEditor?: (file: File) => void; + onMergeFiles?: (files: File[]) => void; + toolMode?: boolean; + showUpload?: boolean; + showBulkActions?: boolean; + supportedExtensions?: string[]; +} + +const FileEditor = ({ + onOpenPageEditor, + onMergeFiles, + toolMode = false, + showUpload = true, + showBulkActions = true, + supportedExtensions = ["pdf"] +}: FileEditorProps) => { + const { t } = useTranslation(); + + // Utility function to check if a file extension is supported + const isFileSupported = useCallback((fileName: string): boolean => { + const extension = detectFileExtension(fileName); + return extension ? supportedExtensions.includes(extension) : false; + }, [supportedExtensions]); + + // Get file context + const fileContext = useFileContext(); + const { + activeFiles, + processedFiles, + selectedFileIds, + setSelectedFiles: setContextSelectedFiles, + isProcessing, + addFiles, + removeFiles, + setCurrentView, + recordOperation, + markOperationApplied + } = fileContext; + + // Get file selection context + const { + selectedFiles: toolSelectedFiles, + setSelectedFiles: setToolSelectedFiles, + maxFiles, + isToolMode + } = useFileSelection(); + + const [files, setFiles] = useState([]); + const [status, setStatus] = useState(null); + const [error, setError] = useState(null); + const [localLoading, setLocalLoading] = useState(false); + const [selectionMode, setSelectionMode] = useState(toolMode); + + // Enable selection mode automatically in tool mode + React.useEffect(() => { + if (toolMode) { + setSelectionMode(true); + } + }, [toolMode]); + const [draggedFile, setDraggedFile] = useState(null); + const [dropTarget, setDropTarget] = useState(null); + const [multiFileDrag, setMultiFileDrag] = useState<{fileIds: string[], count: number} | null>(null); + const [dragPosition, setDragPosition] = useState<{x: number, y: number} | null>(null); + const [isAnimating, setIsAnimating] = useState(false); + const [showFilePickerModal, setShowFilePickerModal] = useState(false); + const [conversionProgress, setConversionProgress] = useState(0); + const [zipExtractionProgress, setZipExtractionProgress] = useState<{ + isExtracting: boolean; + currentFile: string; + progress: number; + extractedCount: number; + totalFiles: number; + }>({ + isExtracting: false, + currentFile: '', + progress: 0, + extractedCount: 0, + totalFiles: 0 + }); + const fileRefs = useRef>(new Map()); + const lastActiveFilesRef = useRef([]); + const lastProcessedFilesRef = useRef(0); + + // Get selected file IDs from context (defensive programming) + const contextSelectedIds = Array.isArray(selectedFileIds) ? selectedFileIds : []; + + // Map context selections to local file IDs for UI display + const localSelectedIds = files + .filter(file => { + const fileId = (file.file as any).id || file.name; + return contextSelectedIds.includes(fileId); + }) + .map(file => file.id); + + // Convert shared files to FileEditor format + const convertToFileItem = useCallback(async (sharedFile: any): Promise => { + // Generate thumbnail if not already available + const thumbnail = sharedFile.thumbnail || await generateThumbnailForFile(sharedFile.file || sharedFile); + + return { + id: sharedFile.id || `file-${Date.now()}-${Math.random()}`, + name: (sharedFile.file?.name || sharedFile.name || 'unknown'), + pageCount: sharedFile.pageCount || Math.floor(Math.random() * 20) + 1, // Mock for now + thumbnail, + size: sharedFile.file?.size || sharedFile.size || 0, + file: sharedFile.file || sharedFile, + }; + }, []); + + // Convert activeFiles to FileItem format using context (async to avoid blocking) + useEffect(() => { + // Check if the actual content has changed, not just references + const currentActiveFileNames = activeFiles.map(f => f.name); + const currentProcessedFilesSize = processedFiles.size; + + const activeFilesChanged = JSON.stringify(currentActiveFileNames) !== JSON.stringify(lastActiveFilesRef.current); + const processedFilesChanged = currentProcessedFilesSize !== lastProcessedFilesRef.current; + + if (!activeFilesChanged && !processedFilesChanged) { + return; + } + + // Update refs + lastActiveFilesRef.current = currentActiveFileNames; + lastProcessedFilesRef.current = currentProcessedFilesSize; + + const convertActiveFiles = async () => { + + if (activeFiles.length > 0) { + setLocalLoading(true); + try { + // Process files in chunks to avoid blocking UI + const convertedFiles: FileItem[] = []; + + for (let i = 0; i < activeFiles.length; i++) { + const file = activeFiles[i]; + + // Try to get thumbnail from processed file first + const processedFile = processedFiles.get(file); + let thumbnail = processedFile?.pages?.[0]?.thumbnail; + + // If no thumbnail from processed file, try to generate one + if (!thumbnail) { + try { + thumbnail = await generateThumbnailForFile(file); + } catch (error) { + console.warn(`Failed to generate thumbnail for ${file.name}:`, error); + thumbnail = undefined; // Use placeholder + } + } + + const convertedFile = { + id: `file-${Date.now()}-${Math.random()}`, + name: file.name, + pageCount: processedFile?.totalPages || Math.floor(Math.random() * 20) + 1, + thumbnail, + size: file.size, + file, + }; + + convertedFiles.push(convertedFile); + + // Update progress + setConversionProgress(((i + 1) / activeFiles.length) * 100); + + // Yield to main thread between files + if (i < activeFiles.length - 1) { + await new Promise(resolve => requestAnimationFrame(resolve)); + } + } + + + setFiles(convertedFiles); + } catch (err) { + console.error('Error converting active files:', err); + } finally { + setLocalLoading(false); + setConversionProgress(0); + } + } else { + setFiles([]); + setLocalLoading(false); + setConversionProgress(0); + } + }; + + convertActiveFiles(); + }, [activeFiles, processedFiles]); + + + // Process uploaded files using context + const handleFileUpload = useCallback(async (uploadedFiles: File[]) => { + setError(null); + + try { + const allExtractedFiles: File[] = []; + const errors: string[] = []; + + for (const file of uploadedFiles) { + if (file.type === 'application/pdf') { + // Handle PDF files normally + allExtractedFiles.push(file); + } else if (file.type === 'application/zip' || file.type === 'application/x-zip-compressed' || file.name.toLowerCase().endsWith('.zip')) { + // Handle ZIP files - only expand if they contain PDFs + try { + // Validate ZIP file first + const validation = await zipFileService.validateZipFile(file); + + if (validation.isValid && validation.containsPDFs) { + // ZIP contains PDFs - extract them + setZipExtractionProgress({ + isExtracting: true, + currentFile: file.name, + progress: 0, + extractedCount: 0, + totalFiles: validation.fileCount + }); + + const extractionResult = await zipFileService.extractPdfFiles(file, (progress) => { + setZipExtractionProgress({ + isExtracting: true, + currentFile: progress.currentFile, + progress: progress.progress, + extractedCount: progress.extractedCount, + totalFiles: progress.totalFiles + }); + }); + + // Reset extraction progress + setZipExtractionProgress({ + isExtracting: false, + currentFile: '', + progress: 0, + extractedCount: 0, + totalFiles: 0 + }); + + if (extractionResult.success) { + allExtractedFiles.push(...extractionResult.extractedFiles); + + // Record ZIP extraction operation + const operationId = `zip-extract-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + const operation: FileOperation = { + id: operationId, + type: 'convert', + timestamp: Date.now(), + fileIds: extractionResult.extractedFiles.map(f => f.name), + status: 'pending', + metadata: { + originalFileName: file.name, + outputFileNames: extractionResult.extractedFiles.map(f => f.name), + fileSize: file.size, + parameters: { + extractionType: 'zip', + extractedCount: extractionResult.extractedCount, + totalFiles: extractionResult.totalFiles + } + } + }; + + recordOperation(file.name, operation); + markOperationApplied(file.name, operationId); + + if (extractionResult.errors.length > 0) { + errors.push(...extractionResult.errors); + } + } else { + errors.push(`Failed to extract ZIP file "${file.name}": ${extractionResult.errors.join(', ')}`); + } + } else { + // ZIP doesn't contain PDFs or is invalid - treat as regular file + console.log(`Adding ZIP file as regular file: ${file.name} (no PDFs found)`); + allExtractedFiles.push(file); + } + } catch (zipError) { + errors.push(`Failed to process ZIP file "${file.name}": ${zipError instanceof Error ? zipError.message : 'Unknown error'}`); + setZipExtractionProgress({ + isExtracting: false, + currentFile: '', + progress: 0, + extractedCount: 0, + totalFiles: 0 + }); + } + } else { + console.log(`Adding none PDF file: ${file.name} (${file.type})`); + allExtractedFiles.push(file); + } + } + + // Show any errors + if (errors.length > 0) { + setError(errors.join('\n')); + } + + // Process all extracted files + if (allExtractedFiles.length > 0) { + // Record upload operations for PDF files + for (const file of allExtractedFiles) { + const operationId = `upload-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + const operation: FileOperation = { + id: operationId, + type: 'upload', + timestamp: Date.now(), + fileIds: [file.name], + status: 'pending', + metadata: { + originalFileName: file.name, + fileSize: file.size, + parameters: { + uploadMethod: 'drag-drop' + } + } + }; + + recordOperation(file.name, operation); + markOperationApplied(file.name, operationId); + } + + // Add files to context (they will be processed automatically) + await addFiles(allExtractedFiles); + setStatus(`Added ${allExtractedFiles.length} files`); + } + } catch (err) { + const errorMessage = err instanceof Error ? err.message : 'Failed to process files'; + setError(errorMessage); + console.error('File processing error:', err); + + // Reset extraction progress on error + setZipExtractionProgress({ + isExtracting: false, + currentFile: '', + progress: 0, + extractedCount: 0, + totalFiles: 0 + }); + } + }, [addFiles, recordOperation, markOperationApplied]); + + const selectAll = useCallback(() => { + setContextSelectedFiles(files.map(f => (f.file as any).id || f.name)); + }, [files, setContextSelectedFiles]); + + const deselectAll = useCallback(() => setContextSelectedFiles([]), [setContextSelectedFiles]); + + const closeAllFiles = useCallback(() => { + if (activeFiles.length === 0) return; + + // Record close all operation for each file + activeFiles.forEach(file => { + const operationId = `close-all-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + const operation: FileOperation = { + id: operationId, + type: 'remove', + timestamp: Date.now(), + fileIds: [file.name], + status: 'pending', + metadata: { + originalFileName: file.name, + fileSize: file.size, + parameters: { + action: 'close_all', + reason: 'user_request' + } + } + }; + + recordOperation(file.name, operation); + markOperationApplied(file.name, operationId); + }); + + // Remove all files from context but keep in storage + removeFiles(activeFiles.map(f => (f as any).id || f.name), false); + + // Clear selections + setContextSelectedFiles([]); + }, [activeFiles, removeFiles, setContextSelectedFiles, recordOperation, markOperationApplied]); + + const toggleFile = useCallback((fileId: string) => { + const targetFile = files.find(f => f.id === fileId); + if (!targetFile) return; + + const contextFileId = (targetFile.file as any).id || targetFile.name; + const isSelected = contextSelectedIds.includes(contextFileId); + + let newSelection: string[]; + + if (isSelected) { + // Remove file from selection + newSelection = contextSelectedIds.filter(id => id !== contextFileId); + } else { + // Add file to selection + if (maxFiles === 1) { + newSelection = [contextFileId]; + } else { + // Check if we've hit the selection limit + if (maxFiles > 1 && contextSelectedIds.length >= maxFiles) { + setStatus(`Maximum ${maxFiles} files can be selected`); + return; + } + newSelection = [...contextSelectedIds, contextFileId]; + } + } + + // Update context + setContextSelectedFiles(newSelection); + + // Update tool selection context if in tool mode + if (isToolMode || toolMode) { + const selectedFiles = files + .filter(f => { + const fId = (f.file as any).id || f.name; + return newSelection.includes(fId); + }) + .map(f => f.file); + setToolSelectedFiles(selectedFiles); + } + }, [files, setContextSelectedFiles, maxFiles, contextSelectedIds, setStatus, isToolMode, toolMode, setToolSelectedFiles]); + + const toggleSelectionMode = useCallback(() => { + setSelectionMode(prev => { + const newMode = !prev; + if (!newMode) { + setContextSelectedFiles([]); + } + return newMode; + }); + }, [setContextSelectedFiles]); + + + // Drag and drop handlers + const handleDragStart = useCallback((fileId: string) => { + setDraggedFile(fileId); + + if (selectionMode && localSelectedIds.includes(fileId) && localSelectedIds.length > 1) { + setMultiFileDrag({ + fileIds: localSelectedIds, + count: localSelectedIds.length + }); + } else { + setMultiFileDrag(null); + } + }, [selectionMode, localSelectedIds]); + + const handleDragEnd = useCallback(() => { + setDraggedFile(null); + setDropTarget(null); + setMultiFileDrag(null); + setDragPosition(null); + }, []); + + const handleDragOver = useCallback((e: React.DragEvent) => { + e.preventDefault(); + + if (!draggedFile) return; + + if (multiFileDrag) { + setDragPosition({ x: e.clientX, y: e.clientY }); + } + + const elementUnderCursor = document.elementFromPoint(e.clientX, e.clientY); + if (!elementUnderCursor) return; + + const fileContainer = elementUnderCursor.closest('[data-file-id]'); + if (fileContainer) { + const fileId = fileContainer.getAttribute('data-file-id'); + if (fileId && fileId !== draggedFile) { + setDropTarget(fileId); + return; + } + } + + const endZone = elementUnderCursor.closest('[data-drop-zone="end"]'); + if (endZone) { + setDropTarget('end'); + return; + } + + setDropTarget(null); + }, [draggedFile, multiFileDrag]); + + const handleDragEnter = useCallback((fileId: string) => { + if (draggedFile && fileId !== draggedFile) { + setDropTarget(fileId); + } + }, [draggedFile]); + + const handleDragLeave = useCallback(() => { + // Let dragover handle this + }, []); + + const handleDrop = useCallback((e: React.DragEvent, targetFileId: string | 'end') => { + e.preventDefault(); + if (!draggedFile || draggedFile === targetFileId) return; + + let targetIndex: number; + if (targetFileId === 'end') { + targetIndex = files.length; + } else { + targetIndex = files.findIndex(f => f.id === targetFileId); + if (targetIndex === -1) return; + } + + const filesToMove = selectionMode && localSelectedIds.includes(draggedFile) + ? localSelectedIds + : [draggedFile]; + + // Update the local files state and sync with activeFiles + setFiles(prev => { + const newFiles = [...prev]; + const movedFiles = filesToMove.map(id => newFiles.find(f => f.id === id)!).filter(Boolean); + + // Remove moved files + filesToMove.forEach(id => { + const index = newFiles.findIndex(f => f.id === id); + if (index !== -1) newFiles.splice(index, 1); + }); + + // Insert at target position + newFiles.splice(targetIndex, 0, ...movedFiles); + + // TODO: Update context with reordered files (need to implement file reordering in context) + // For now, just return the reordered local state + return newFiles; + }); + + const moveCount = multiFileDrag ? multiFileDrag.count : 1; + setStatus(`${moveCount > 1 ? `${moveCount} files` : 'File'} reordered`); + + }, [draggedFile, files, selectionMode, localSelectedIds, multiFileDrag]); + + const handleEndZoneDragEnter = useCallback(() => { + if (draggedFile) { + setDropTarget('end'); + } + }, [draggedFile]); + + // File operations using context + const handleDeleteFile = useCallback((fileId: string) => { + console.log('handleDeleteFile called with fileId:', fileId); + const file = files.find(f => f.id === fileId); + console.log('Found file:', file); + + if (file) { + console.log('Attempting to remove file:', file.name); + console.log('Actual file object:', file.file); + console.log('Actual file.file.name:', file.file.name); + + // Record close operation + const fileName = file.file.name; + const fileId = (file.file as any).id || fileName; + const operationId = `close-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + const operation: FileOperation = { + id: operationId, + type: 'remove', + timestamp: Date.now(), + fileIds: [fileName], + status: 'pending', + metadata: { + originalFileName: fileName, + fileSize: file.size, + parameters: { + action: 'close', + reason: 'user_request' + } + } + }; + + recordOperation(fileName, operation); + + // Remove file from context but keep in storage (close, don't delete) + console.log('Calling removeFiles with:', [fileId]); + removeFiles([fileId], false); + + // Remove from context selections + setContextSelectedFiles(prev => { + const safePrev = Array.isArray(prev) ? prev : []; + return safePrev.filter(id => id !== fileId); + }); + + // Mark operation as applied + markOperationApplied(fileName, operationId); + } else { + console.log('File not found for fileId:', fileId); + } + }, [files, removeFiles, setContextSelectedFiles, recordOperation, markOperationApplied]); + + const handleViewFile = useCallback((fileId: string) => { + const file = files.find(f => f.id === fileId); + if (file) { + // Set the file as selected in context and switch to page editor view + const contextFileId = (file.file as any).id || file.name; + setContextSelectedFiles([contextFileId]); + setCurrentView('pageEditor'); + onOpenPageEditor?.(file.file); + } + }, [files, setContextSelectedFiles, setCurrentView, onOpenPageEditor]); + + const handleMergeFromHere = useCallback((fileId: string) => { + const startIndex = files.findIndex(f => f.id === fileId); + if (startIndex === -1) return; + + const filesToMerge = files.slice(startIndex).map(f => f.file); + if (onMergeFiles) { + onMergeFiles(filesToMerge); + } + }, [files, onMergeFiles]); + + const handleSplitFile = useCallback((fileId: string) => { + const file = files.find(f => f.id === fileId); + if (file && onOpenPageEditor) { + onOpenPageEditor(file.file); + } + }, [files, onOpenPageEditor]); + + const handleLoadFromStorage = useCallback(async (selectedFiles: any[]) => { + if (selectedFiles.length === 0) return; + + setLocalLoading(true); + try { + const convertedFiles = await Promise.all( + selectedFiles.map(convertToFileItem) + ); + setFiles(prev => [...prev, ...convertedFiles]); + setStatus(`Loaded ${selectedFiles.length} files from storage`); + } catch (err) { + console.error('Error loading files from storage:', err); + setError('Failed to load some files from storage'); + } finally { + setLocalLoading(false); + } + }, [convertToFileItem]); + + + return ( + + + + + + + {showBulkActions && !toolMode && ( + <> + + + + + )} + + + + {files.length === 0 && !localLoading && !zipExtractionProgress.isExtracting ? ( +
+ + šŸ“ + No files loaded + Upload PDF files, ZIP archives, or load from storage to get started + +
+ ) : files.length === 0 && (localLoading || zipExtractionProgress.isExtracting) ? ( + + + + {/* ZIP Extraction Progress */} + {zipExtractionProgress.isExtracting && ( + + + Extracting ZIP archive... + {Math.round(zipExtractionProgress.progress)}% + + + {zipExtractionProgress.currentFile || 'Processing files...'} + + + {zipExtractionProgress.extractedCount} of {zipExtractionProgress.totalFiles} files extracted + +
+
+
+ + )} + + {/* Processing indicator */} + {localLoading && ( + + + Loading files... + {Math.round(conversionProgress)}% + +
+
+
+ + )} + + + + ) : ( + ( + + )} + renderSplitMarker={(file, index) => ( +
+ )} + /> + )} + + + {/* File Picker Modal */} + setShowFilePickerModal(false)} + storedFiles={[]} // FileEditor doesn't have access to stored files, needs to be passed from parent + onSelectFiles={handleLoadFromStorage} + allowMultiple={true} + /> + + {status && ( + setStatus(null)} + style={{ position: 'fixed', bottom: 20, right: 20, zIndex: 1000 }} + > + {status} + + )} + + {error && ( + setError(null)} + style={{ position: 'fixed', bottom: 80, right: 20, zIndex: 1000 }} + > + {error} + + )} + + + ); +}; + +export default FileEditor; diff --git a/frontend/src/components/fileManager/CompactFileDetails.tsx b/frontend/src/components/fileManager/CompactFileDetails.tsx new file mode 100644 index 000000000..7f7c410b7 --- /dev/null +++ b/frontend/src/components/fileManager/CompactFileDetails.tsx @@ -0,0 +1,126 @@ +import React from 'react'; +import { Stack, Box, Text, Button, ActionIcon, Center } from '@mantine/core'; +import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf'; +import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; +import ChevronRightIcon from '@mui/icons-material/ChevronRight'; +import { useTranslation } from 'react-i18next'; +import { getFileSize } from '../../utils/fileUtils'; +import { FileWithUrl } from '../../types/file'; + +interface CompactFileDetailsProps { + currentFile: FileWithUrl | null; + thumbnail: string | null; + selectedFiles: FileWithUrl[]; + currentFileIndex: number; + numberOfFiles: number; + isAnimating: boolean; + onPrevious: () => void; + onNext: () => void; + onOpenFiles: () => void; +} + +const CompactFileDetails: React.FC = ({ + currentFile, + thumbnail, + selectedFiles, + currentFileIndex, + numberOfFiles, + isAnimating, + onPrevious, + onNext, + onOpenFiles +}) => { + const { t } = useTranslation(); + const hasSelection = selectedFiles.length > 0; + const hasMultipleFiles = numberOfFiles > 1; + + return ( + + {/* Compact mobile layout */} + + {/* Small preview */} + + {currentFile && thumbnail ? ( + {currentFile.name} + ) : currentFile ? ( +
+ +
+ ) : null} +
+ + {/* File info */} + + + {currentFile ? currentFile.name : 'No file selected'} + + + {currentFile ? getFileSize(currentFile) : ''} + {selectedFiles.length > 1 && ` • ${selectedFiles.length} files`} + + {hasMultipleFiles && ( + + {currentFileIndex + 1} of {selectedFiles.length} + + )} + + + {/* Navigation arrows for multiple files */} + {hasMultipleFiles && ( + + + + + + + + + )} +
+ + {/* Action Button */} + +
+ ); +}; + +export default CompactFileDetails; \ No newline at end of file diff --git a/frontend/src/components/fileManager/DesktopLayout.tsx b/frontend/src/components/fileManager/DesktopLayout.tsx new file mode 100644 index 000000000..be701ff20 --- /dev/null +++ b/frontend/src/components/fileManager/DesktopLayout.tsx @@ -0,0 +1,89 @@ +import React from 'react'; +import { Grid } from '@mantine/core'; +import FileSourceButtons from './FileSourceButtons'; +import FileDetails from './FileDetails'; +import SearchInput from './SearchInput'; +import FileListArea from './FileListArea'; +import HiddenFileInput from './HiddenFileInput'; +import { useFileManagerContext } from '../../contexts/FileManagerContext'; + +const DesktopLayout: React.FC = () => { + const { + activeSource, + recentFiles, + modalHeight, + } = useFileManagerContext(); + + return ( + + {/* Column 1: File Sources */} + + + + + {/* Column 2: File List */} + +
+ {activeSource === 'recent' && ( +
+ +
+ )} + +
+ 0 ? modalHeight : '100%', + backgroundColor: 'transparent', + border: 'none', + borderRadius: 0 + }} + /> +
+
+
+ + {/* Column 3: File Details */} + +
+ +
+
+ + {/* Hidden file input for local file selection */} + +
+ ); +}; + +export default DesktopLayout; \ No newline at end of file diff --git a/frontend/src/components/fileManager/DragOverlay.tsx b/frontend/src/components/fileManager/DragOverlay.tsx new file mode 100644 index 000000000..976bb940e --- /dev/null +++ b/frontend/src/components/fileManager/DragOverlay.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { Stack, Text, useMantineTheme, alpha } from '@mantine/core'; +import UploadFileIcon from '@mui/icons-material/UploadFile'; +import { useTranslation } from 'react-i18next'; + +interface DragOverlayProps { + isVisible: boolean; +} + +const DragOverlay: React.FC = ({ isVisible }) => { + const { t } = useTranslation(); + const theme = useMantineTheme(); + + if (!isVisible) return null; + + return ( +
+ + + + {t('fileManager.dropFilesHere', 'Drop files here to upload')} + + +
+ ); +}; + +export default DragOverlay; \ No newline at end of file diff --git a/frontend/src/components/fileManager/FileDetails.tsx b/frontend/src/components/fileManager/FileDetails.tsx new file mode 100644 index 000000000..9673d06ad --- /dev/null +++ b/frontend/src/components/fileManager/FileDetails.tsx @@ -0,0 +1,116 @@ +import React, { useState, useEffect } from 'react'; +import { Stack, Button } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; +import { useIndexedDBThumbnail } from '../../hooks/useIndexedDBThumbnail'; +import { useFileManagerContext } from '../../contexts/FileManagerContext'; +import FilePreview from './FilePreview'; +import FileInfoCard from './FileInfoCard'; +import CompactFileDetails from './CompactFileDetails'; + +interface FileDetailsProps { + compact?: boolean; +} + +const FileDetails: React.FC = ({ + compact = false +}) => { + const { selectedFiles, onOpenFiles, modalHeight } = useFileManagerContext(); + const { t } = useTranslation(); + const [currentFileIndex, setCurrentFileIndex] = useState(0); + const [isAnimating, setIsAnimating] = useState(false); + + // Get the currently displayed file + const currentFile = selectedFiles.length > 0 ? selectedFiles[currentFileIndex] : null; + const hasSelection = selectedFiles.length > 0; + const hasMultipleFiles = selectedFiles.length > 1; + + // Use IndexedDB hook for the current file + const { thumbnail: currentThumbnail } = useIndexedDBThumbnail(currentFile); + + // Get thumbnail for current file + const getCurrentThumbnail = () => { + return currentThumbnail; + }; + + const handlePrevious = () => { + if (isAnimating) return; + setIsAnimating(true); + setTimeout(() => { + setCurrentFileIndex(prev => prev > 0 ? prev - 1 : selectedFiles.length - 1); + setIsAnimating(false); + }, 150); + }; + + const handleNext = () => { + if (isAnimating) return; + setIsAnimating(true); + setTimeout(() => { + setCurrentFileIndex(prev => prev < selectedFiles.length - 1 ? prev + 1 : 0); + setIsAnimating(false); + }, 150); + }; + + // Reset index when selection changes + React.useEffect(() => { + if (currentFileIndex >= selectedFiles.length) { + setCurrentFileIndex(0); + } + }, [selectedFiles.length, currentFileIndex]); + + if (compact) { + return ( + + ); + } + + return ( + + {/* Section 1: Thumbnail Preview */} + + + {/* Section 2: File Details */} + + + + + ); +}; + +export default FileDetails; \ No newline at end of file diff --git a/frontend/src/components/fileManager/FileInfoCard.tsx b/frontend/src/components/fileManager/FileInfoCard.tsx new file mode 100644 index 000000000..7e69dd2ed --- /dev/null +++ b/frontend/src/components/fileManager/FileInfoCard.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import { Stack, Card, Box, Text, Badge, Group, Divider, ScrollArea } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; +import { detectFileExtension, getFileSize } from '../../utils/fileUtils'; +import { FileWithUrl } from '../../types/file'; + +interface FileInfoCardProps { + currentFile: FileWithUrl | null; + modalHeight: string; +} + +const FileInfoCard: React.FC = ({ + currentFile, + modalHeight +}) => { + const { t } = useTranslation(); + + return ( + + + + {t('fileManager.details', 'File Details')} + + + + + + {t('fileManager.fileName', 'Name')} + + {currentFile ? currentFile.name : ''} + + + + + + {t('fileManager.fileFormat', 'Format')} + {currentFile ? ( + + {detectFileExtension(currentFile.name).toUpperCase()} + + ) : ( + + )} + + + + + {t('fileManager.fileSize', 'Size')} + + {currentFile ? getFileSize(currentFile) : ''} + + + + + + {t('fileManager.fileVersion', 'Version')} + + {currentFile ? '1.0' : ''} + + + + + + ); +}; + +export default FileInfoCard; \ No newline at end of file diff --git a/frontend/src/components/fileManager/FileListArea.tsx b/frontend/src/components/fileManager/FileListArea.tsx new file mode 100644 index 000000000..8e1975137 --- /dev/null +++ b/frontend/src/components/fileManager/FileListArea.tsx @@ -0,0 +1,80 @@ +import React from 'react'; +import { Center, ScrollArea, Text, Stack } from '@mantine/core'; +import CloudIcon from '@mui/icons-material/Cloud'; +import HistoryIcon from '@mui/icons-material/History'; +import { useTranslation } from 'react-i18next'; +import FileListItem from './FileListItem'; +import { useFileManagerContext } from '../../contexts/FileManagerContext'; + +interface FileListAreaProps { + scrollAreaHeight: string; + scrollAreaStyle?: React.CSSProperties; +} + +const FileListArea: React.FC = ({ + scrollAreaHeight, + scrollAreaStyle = {}, +}) => { + const { + activeSource, + recentFiles, + filteredFiles, + selectedFileIds, + onFileSelect, + onFileRemove, + onFileDoubleClick, + isFileSupported, + } = useFileManagerContext(); + const { t } = useTranslation(); + + if (activeSource === 'recent') { + return ( + + + {recentFiles.length === 0 ? ( +
+ + + {t('fileManager.noRecentFiles', 'No recent files')} + + {t('fileManager.dropFilesHint', 'Drop files anywhere to upload')} + + +
+ ) : ( + filteredFiles.map((file, index) => ( + onFileSelect(file)} + onRemove={() => onFileRemove(index)} + onDoubleClick={() => onFileDoubleClick(file)} + /> + )) + )} +
+
+ ); + } + + // Google Drive placeholder + return ( +
+ + + {t('fileManager.googleDriveNotAvailable', 'Google Drive integration coming soon')} + +
+ ); +}; + +export default FileListArea; \ No newline at end of file diff --git a/frontend/src/components/fileManager/FileListItem.tsx b/frontend/src/components/fileManager/FileListItem.tsx new file mode 100644 index 000000000..147133009 --- /dev/null +++ b/frontend/src/components/fileManager/FileListItem.tsx @@ -0,0 +1,84 @@ +import React, { useState } from 'react'; +import { Group, Box, Text, ActionIcon, Checkbox, Divider } from '@mantine/core'; +import DeleteIcon from '@mui/icons-material/Delete'; +import { getFileSize, getFileDate } from '../../utils/fileUtils'; +import { FileWithUrl } from '../../types/file'; + +interface FileListItemProps { + file: FileWithUrl; + isSelected: boolean; + isSupported: boolean; + onSelect: () => void; + onRemove: () => void; + onDoubleClick?: () => void; + isLast?: boolean; +} + +const FileListItem: React.FC = ({ + file, + isSelected, + isSupported, + onSelect, + onRemove, + onDoubleClick +}) => { + const [isHovered, setIsHovered] = useState(false); + + return ( + <> + setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + > + + + {}} // Handled by parent onClick + size="sm" + pl="sm" + pr="xs" + styles={{ + input: { + cursor: 'pointer' + } + }} + /> + + + + {file.name} + {getFileSize(file)} • {getFileDate(file)} + + {/* Delete button - fades in/out on hover */} + { e.stopPropagation(); onRemove(); }} + style={{ + opacity: isHovered ? 1 : 0, + transform: isHovered ? 'scale(1)' : 'scale(0.8)', + transition: 'opacity 0.3s ease, transform 0.3s ease', + pointerEvents: isHovered ? 'auto' : 'none' + }} + > + + + + + { } + + ); +}; + +export default FileListItem; \ No newline at end of file diff --git a/frontend/src/components/fileManager/FilePreview.tsx b/frontend/src/components/fileManager/FilePreview.tsx new file mode 100644 index 000000000..deb4cc67b --- /dev/null +++ b/frontend/src/components/fileManager/FilePreview.tsx @@ -0,0 +1,156 @@ +import React from 'react'; +import { Box, Center, ActionIcon, Image } from '@mantine/core'; +import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf'; +import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; +import ChevronRightIcon from '@mui/icons-material/ChevronRight'; +import { FileWithUrl } from '../../types/file'; + +interface FilePreviewProps { + currentFile: FileWithUrl | null; + thumbnail: string | null; + numberOfFiles: number; + isAnimating: boolean; + modalHeight: string; + onPrevious: () => void; + onNext: () => void; +} + +const FilePreview: React.FC = ({ + currentFile, + thumbnail, + numberOfFiles, + isAnimating, + modalHeight, + onPrevious, + onNext +}) => { + const hasMultipleFiles = numberOfFiles > 1; + // Common style objects + const navigationArrowStyle = { + position: 'absolute' as const, + top: '50%', + transform: 'translateY(-50%)', + zIndex: 10 + }; + + const stackDocumentBaseStyle = { + position: 'absolute' as const, + width: '100%', + height: '100%' + }; + + const animationStyle = { + transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)', + transform: isAnimating ? 'scale(0.95) translateX(1.25rem)' : 'scale(1) translateX(0)', + opacity: isAnimating ? 0.7 : 1 + }; + + const mainDocumentShadow = '0 6px 16px rgba(0, 0, 0, 0.2)'; + const stackDocumentShadows = { + back: '0 2px 8px rgba(0, 0, 0, 0.1)', + middle: '0 3px 10px rgba(0, 0, 0, 0.12)' + }; + + return ( + + + {/* Left Navigation Arrow */} + {hasMultipleFiles && ( + + + + )} + + {/* Document Stack Container */} + + {/* Background documents (stack effect) */} + {/* Show 2 shadow pages for 3+ files */} + {numberOfFiles >= 3 && ( + + )} + + {/* Show 1 shadow page for 2+ files */} + {numberOfFiles >= 2 && ( + + )} + + {/* Main document */} + {currentFile && thumbnail ? ( + {currentFile.name} + ) : currentFile ? ( +
+ +
+ ) : null} +
+ + {/* Right Navigation Arrow */} + {hasMultipleFiles && ( + + + + )} +
+
+ ); +}; + +export default FilePreview; \ No newline at end of file diff --git a/frontend/src/components/fileManager/FileSourceButtons.tsx b/frontend/src/components/fileManager/FileSourceButtons.tsx new file mode 100644 index 000000000..a6870a661 --- /dev/null +++ b/frontend/src/components/fileManager/FileSourceButtons.tsx @@ -0,0 +1,103 @@ +import React from 'react'; +import { Stack, Text, Button, Group } from '@mantine/core'; +import HistoryIcon from '@mui/icons-material/History'; +import FolderIcon from '@mui/icons-material/Folder'; +import CloudIcon from '@mui/icons-material/Cloud'; +import { useTranslation } from 'react-i18next'; +import { useFileManagerContext } from '../../contexts/FileManagerContext'; + +interface FileSourceButtonsProps { + horizontal?: boolean; +} + +const FileSourceButtons: React.FC = ({ + horizontal = false +}) => { + const { activeSource, onSourceChange, onLocalFileClick } = useFileManagerContext(); + const { t } = useTranslation(); + + const buttonProps = { + variant: (source: string) => activeSource === source ? 'filled' : 'subtle', + getColor: (source: string) => activeSource === source ? 'var(--mantine-color-gray-2)' : undefined, + getStyles: (source: string) => ({ + root: { + backgroundColor: activeSource === source ? undefined : 'transparent', + color: activeSource === source ? 'var(--mantine-color-gray-9)' : 'var(--mantine-color-gray-6)', + border: 'none', + '&:hover': { + backgroundColor: activeSource === source ? undefined : 'var(--mantine-color-gray-0)' + } + } + }) + }; + + const buttons = ( + <> + + + + + + + ); + + if (horizontal) { + return ( + + {buttons} + + ); + } + + return ( + + + {t('fileManager.myFiles', 'My Files')} + + {buttons} + + ); +}; + +export default FileSourceButtons; \ No newline at end of file diff --git a/frontend/src/components/fileManager/HiddenFileInput.tsx b/frontend/src/components/fileManager/HiddenFileInput.tsx new file mode 100644 index 000000000..6f2834267 --- /dev/null +++ b/frontend/src/components/fileManager/HiddenFileInput.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { useFileManagerContext } from '../../contexts/FileManagerContext'; + +const HiddenFileInput: React.FC = () => { + const { fileInputRef, onFileInputChange } = useFileManagerContext(); + + return ( + + ); +}; + +export default HiddenFileInput; \ No newline at end of file diff --git a/frontend/src/components/fileManager/MobileLayout.tsx b/frontend/src/components/fileManager/MobileLayout.tsx new file mode 100644 index 000000000..30d1ad6b9 --- /dev/null +++ b/frontend/src/components/fileManager/MobileLayout.tsx @@ -0,0 +1,83 @@ +import React from 'react'; +import { Stack, Box } from '@mantine/core'; +import FileSourceButtons from './FileSourceButtons'; +import FileDetails from './FileDetails'; +import SearchInput from './SearchInput'; +import FileListArea from './FileListArea'; +import HiddenFileInput from './HiddenFileInput'; +import { useFileManagerContext } from '../../contexts/FileManagerContext'; + +const MobileLayout: React.FC = () => { + const { + activeSource, + selectedFiles, + modalHeight, + } = useFileManagerContext(); + + // Calculate the height more accurately based on actual content + const calculateFileListHeight = () => { + // Base modal height minus padding and gaps + const baseHeight = `calc(${modalHeight} - 2rem)`; // Account for Stack padding + + // Estimate heights of fixed components + const fileSourceHeight = '3rem'; // FileSourceButtons height + const fileDetailsHeight = selectedFiles.length > 0 ? '10rem' : '8rem'; // FileDetails compact height + const searchHeight = activeSource === 'recent' ? '3rem' : '0rem'; // SearchInput height + const gapHeight = activeSource === 'recent' ? '3rem' : '2rem'; // Stack gaps + + return `calc(${baseHeight} - ${fileSourceHeight} - ${fileDetailsHeight} - ${searchHeight} - ${gapHeight})`; + }; + + return ( + + {/* Section 1: File Sources - Fixed at top */} + + + + + + + + + {/* Section 3 & 4: Search Bar + File List - Unified background extending to modal edge */} + + {activeSource === 'recent' && ( + + + + )} + + + + + + + {/* Hidden file input for local file selection */} + + + ); +}; + +export default MobileLayout; \ No newline at end of file diff --git a/frontend/src/components/fileManager/SearchInput.tsx b/frontend/src/components/fileManager/SearchInput.tsx new file mode 100644 index 000000000..f47da0dca --- /dev/null +++ b/frontend/src/components/fileManager/SearchInput.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { TextInput } from '@mantine/core'; +import SearchIcon from '@mui/icons-material/Search'; +import { useTranslation } from 'react-i18next'; +import { useFileManagerContext } from '../../contexts/FileManagerContext'; + +interface SearchInputProps { + style?: React.CSSProperties; +} + +const SearchInput: React.FC = ({ style }) => { + const { t } = useTranslation(); + const { searchTerm, onSearchChange } = useFileManagerContext(); + + return ( + } + value={searchTerm} + onChange={(e) => onSearchChange(e.target.value)} + + style={{ padding: '0.5rem', ...style }} + styles={{ + input: { + border: 'none', + backgroundColor: 'transparent' + } + }} + /> + ); +}; + +export default SearchInput; \ No newline at end of file diff --git a/frontend/src/components/history/FileOperationHistory.tsx b/frontend/src/components/history/FileOperationHistory.tsx new file mode 100644 index 000000000..365b5a8f8 --- /dev/null +++ b/frontend/src/components/history/FileOperationHistory.tsx @@ -0,0 +1,177 @@ +import React from 'react'; +import { + Stack, + Paper, + Text, + Badge, + Group, + Collapse, + Box, + ScrollArea, + Code, + Divider +} from '@mantine/core'; +import { useFileContext } from '../../contexts/FileContext'; +import { FileOperation, FileOperationHistory as FileOperationHistoryType } from '../../types/fileContext'; +import { PageOperation } from '../../types/pageEditor'; + +interface FileOperationHistoryProps { + fileId: string; + showOnlyApplied?: boolean; + maxHeight?: number; +} + +const FileOperationHistory: React.FC = ({ + fileId, + showOnlyApplied = false, + maxHeight = 400 +}) => { + const { getFileHistory, getAppliedOperations } = useFileContext(); + + const history = getFileHistory(fileId); + const operations = showOnlyApplied ? getAppliedOperations(fileId) : history?.operations || []; + + const formatTimestamp = (timestamp: number) => { + return new Date(timestamp).toLocaleString(); + }; + + const getOperationIcon = (type: string) => { + switch (type) { + case 'split': return 'āœ‚ļø'; + case 'merge': return 'šŸ”—'; + case 'compress': return 'šŸ—œļø'; + case 'rotate': return 'šŸ”„'; + case 'delete': return 'šŸ—‘ļø'; + case 'move': return 'ā†•ļø'; + case 'insert': return 'šŸ“„'; + case 'upload': return 'ā¬†ļø'; + case 'add': return 'āž•'; + case 'remove': return 'āž–'; + case 'replace': return 'šŸ”„'; + case 'convert': return 'šŸ”„'; + default: return 'āš™ļø'; + } + }; + + const getStatusColor = (status: string) => { + switch (status) { + case 'applied': return 'green'; + case 'failed': return 'red'; + case 'pending': return 'yellow'; + default: return 'gray'; + } + }; + + const renderOperationDetails = (operation: FileOperation | PageOperation) => { + if ('metadata' in operation && operation.metadata) { + const { metadata } = operation; + return ( + + {metadata.parameters && ( + + Parameters: {JSON.stringify(metadata.parameters, null, 2)} + + )} + {metadata.originalFileName && ( + + Original file: {metadata.originalFileName} + + )} + {metadata.outputFileNames && ( + + Output files: {metadata.outputFileNames.join(', ')} + + )} + {metadata.fileSize && ( + + File size: {(metadata.fileSize / 1024 / 1024).toFixed(2)} MB + + )} + {metadata.pageCount && ( + + Pages: {metadata.pageCount} + + )} + {metadata.error && ( + + Error: {metadata.error} + + )} + + ); + } + return null; + }; + + if (!history || operations.length === 0) { + return ( + + + {showOnlyApplied ? 'No applied operations found' : 'No operation history available'} + + + ); + } + + return ( + + + + {showOnlyApplied ? 'Applied Operations' : 'Operation History'} + + + {operations.length} operations + + + + + + {operations.map((operation, index) => ( + + + + + {getOperationIcon(operation.type)} + + + + {operation.type.charAt(0).toUpperCase() + operation.type.slice(1)} + + + {formatTimestamp(operation.timestamp)} + + + + + + {operation.status} + + + + {renderOperationDetails(operation)} + + {index < operations.length - 1 && } + + ))} + + + + {history && ( + + + Created: {formatTimestamp(history.createdAt)} + + + Last modified: {formatTimestamp(history.lastModified)} + + + )} + + ); +}; + +export default FileOperationHistory; \ No newline at end of file diff --git a/frontend/src/components/layout/Workbench.tsx b/frontend/src/components/layout/Workbench.tsx new file mode 100644 index 000000000..b0c984ee8 --- /dev/null +++ b/frontend/src/components/layout/Workbench.tsx @@ -0,0 +1,160 @@ +import React from 'react'; +import { Box } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; +import { useRainbowThemeContext } from '../shared/RainbowThemeProvider'; +import { useWorkbenchState, useToolSelection } from '../../contexts/ToolWorkflowContext'; +import { useFileHandler } from '../../hooks/useFileHandler'; +import { useFileContext } from '../../contexts/FileContext'; + +import TopControls from '../shared/TopControls'; +import FileEditor from '../fileEditor/FileEditor'; +import PageEditor from '../pageEditor/PageEditor'; +import PageEditorControls from '../pageEditor/PageEditorControls'; +import Viewer from '../viewer/Viewer'; +import ToolRenderer from '../tools/ToolRenderer'; +import LandingPage from '../shared/LandingPage'; + +// No props needed - component uses contexts directly +export default function Workbench() { + const { t } = useTranslation(); + const { isRainbowMode } = useRainbowThemeContext(); + + // Use context-based hooks to eliminate all prop drilling + const { activeFiles, currentView, setCurrentView } = useFileContext(); + const { + previewFile, + pageEditorFunctions, + sidebarsVisible, + setPreviewFile, + setPageEditorFunctions, + setSidebarsVisible + } = useWorkbenchState(); + + const { selectedToolKey, selectedTool, handleToolSelect } = useToolSelection(); + const { addToActiveFiles } = useFileHandler(); + + const handlePreviewClose = () => { + setPreviewFile(null); + const previousMode = sessionStorage.getItem('previousMode'); + if (previousMode === 'split') { + // Use context's handleToolSelect which coordinates tool selection and view changes + handleToolSelect('split'); + sessionStorage.removeItem('previousMode'); + } else if (previousMode === 'compress') { + handleToolSelect('compress'); + sessionStorage.removeItem('previousMode'); + } else if (previousMode === 'convert') { + handleToolSelect('convert'); + sessionStorage.removeItem('previousMode'); + } else { + setCurrentView('fileEditor' as any); + } + }; + + const renderMainContent = () => { + if (!activeFiles[0]) { + return ( + + ); + } + + switch (currentView) { + case "fileEditor": + return ( + { + setCurrentView("pageEditor" as any); + }, + onMergeFiles: (filesToMerge) => { + filesToMerge.forEach(addToActiveFiles); + setCurrentView("viewer" as any); + } + })} + /> + ); + + case "viewer": + return ( + + ); + + case "pageEditor": + return ( + <> + + {pageEditorFunctions && ( + + )} + + ); + + default: + // Check if it's a tool view + if (selectedToolKey && selectedTool) { + return ( + + ); + } + return ( + + ); + } + }; + + return ( + + {/* Top Controls */} + + + {/* Main content area */} + + {renderMainContent()} + + + ); +} \ No newline at end of file diff --git a/frontend/src/components/pageEditor/BulkSelectionPanel.tsx b/frontend/src/components/pageEditor/BulkSelectionPanel.tsx new file mode 100644 index 000000000..5a6b4504f --- /dev/null +++ b/frontend/src/components/pageEditor/BulkSelectionPanel.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { Paper, Group, TextInput, Button, Text } from '@mantine/core'; + +interface BulkSelectionPanelProps { + csvInput: string; + setCsvInput: (value: string) => void; + selectedPages: number[]; + onUpdatePagesFromCSV: () => void; +} + +const BulkSelectionPanel = ({ + csvInput, + setCsvInput, + selectedPages, + onUpdatePagesFromCSV, +}: BulkSelectionPanelProps) => { + return ( + + + setCsvInput(e.target.value)} + placeholder="1,3,5-10" + label="Page Selection" + onBlur={onUpdatePagesFromCSV} + onKeyDown={(e) => e.key === 'Enter' && onUpdatePagesFromCSV()} + style={{ flex: 1 }} + /> + + + {selectedPages.length > 0 && ( + + Selected: {selectedPages.length} pages + + )} + + ); +}; + +export default BulkSelectionPanel; \ No newline at end of file diff --git a/frontend/src/components/pageEditor/DragDropGrid.tsx b/frontend/src/components/pageEditor/DragDropGrid.tsx new file mode 100644 index 000000000..39dbb396f --- /dev/null +++ b/frontend/src/components/pageEditor/DragDropGrid.tsx @@ -0,0 +1,137 @@ +import React, { useState, useCallback, useRef, useEffect } from 'react'; +import { Box } from '@mantine/core'; +import styles from './PageEditor.module.css'; + +interface DragDropItem { + id: string; + splitBefore?: boolean; +} + +interface DragDropGridProps { + items: T[]; + selectedItems: number[]; + selectionMode: boolean; + isAnimating: boolean; + onDragStart: (pageNumber: number) => void; + onDragEnd: () => void; + onDragOver: (e: React.DragEvent) => void; + onDragEnter: (pageNumber: number) => void; + onDragLeave: () => void; + onDrop: (e: React.DragEvent, targetPageNumber: number | 'end') => void; + onEndZoneDragEnter: () => void; + renderItem: (item: T, index: number, refs: React.MutableRefObject>) => React.ReactNode; + renderSplitMarker?: (item: T, index: number) => React.ReactNode; + draggedItem: number | null; + dropTarget: number | null; + multiItemDrag: {pageNumbers: number[], count: number} | null; + dragPosition: {x: number, y: number} | null; +} + +const DragDropGrid = ({ + items, + selectedItems, + selectionMode, + isAnimating, + onDragStart, + onDragEnd, + onDragOver, + onDragEnter, + onDragLeave, + onDrop, + onEndZoneDragEnter, + renderItem, + renderSplitMarker, + draggedItem, + dropTarget, + multiItemDrag, + dragPosition, +}: DragDropGridProps) => { + const itemRefs = useRef>(new Map()); + + // Global drag cleanup + useEffect(() => { + const handleGlobalDragEnd = () => { + onDragEnd(); + }; + + const handleGlobalDrop = (e: DragEvent) => { + e.preventDefault(); + }; + + if (draggedItem) { + document.addEventListener('dragend', handleGlobalDragEnd); + document.addEventListener('drop', handleGlobalDrop); + } + + return () => { + document.removeEventListener('dragend', handleGlobalDragEnd); + document.removeEventListener('drop', handleGlobalDrop); + }; + }, [draggedItem, onDragEnd]); + + return ( + +
+ {items.map((item, index) => ( + + {/* Split marker */} + {renderSplitMarker && item.splitBefore && index > 0 && renderSplitMarker(item, index)} + + {/* Item */} + {renderItem(item, index, itemRefs)} + + ))} + + {/* End drop zone */} +
+
onDrop(e, 'end')} + > +
+ Drop here to
move to end +
+
+
+
+ + {/* Multi-item drag indicator */} + {multiItemDrag && dragPosition && ( +
+ {multiItemDrag.count} items +
+ )} +
+ ); +}; + +export default DragDropGrid; diff --git a/frontend/src/components/pageEditor/FileThumbnail.tsx b/frontend/src/components/pageEditor/FileThumbnail.tsx new file mode 100644 index 000000000..b129ce6d9 --- /dev/null +++ b/frontend/src/components/pageEditor/FileThumbnail.tsx @@ -0,0 +1,360 @@ +import React, { useState } from 'react'; +import { Text, Checkbox, Tooltip, ActionIcon, Badge, Modal } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; +import CloseIcon from '@mui/icons-material/Close'; +import VisibilityIcon from '@mui/icons-material/Visibility'; +import HistoryIcon from '@mui/icons-material/History'; +import DragIndicatorIcon from '@mui/icons-material/DragIndicator'; +import styles from './PageEditor.module.css'; +import FileOperationHistory from '../history/FileOperationHistory'; + +interface FileItem { + id: string; + name: string; + pageCount: number; + thumbnail: string; + size: number; + splitBefore?: boolean; +} + +interface FileThumbnailProps { + file: FileItem; + index: number; + totalFiles: number; + selectedFiles: string[]; + selectionMode: boolean; + draggedFile: string | null; + dropTarget: string | null; + isAnimating: boolean; + fileRefs: React.MutableRefObject>; + onDragStart: (fileId: string) => void; + onDragEnd: () => void; + onDragOver: (e: React.DragEvent) => void; + onDragEnter: (fileId: string) => void; + onDragLeave: () => void; + onDrop: (e: React.DragEvent, fileId: string) => void; + onToggleFile: (fileId: string) => void; + onDeleteFile: (fileId: string) => void; + onViewFile: (fileId: string) => void; + onSetStatus: (status: string) => void; + toolMode?: boolean; + isSupported?: boolean; +} + +const FileThumbnail = ({ + file, + index, + totalFiles, + selectedFiles, + selectionMode, + draggedFile, + dropTarget, + isAnimating, + fileRefs, + onDragStart, + onDragEnd, + onDragOver, + onDragEnter, + onDragLeave, + onDrop, + onToggleFile, + onDeleteFile, + onViewFile, + onSetStatus, + toolMode = false, + isSupported = true, +}: FileThumbnailProps) => { + const { t } = useTranslation(); + const [showHistory, setShowHistory] = useState(false); + + const formatFileSize = (bytes: number) => { + if (bytes === 0) return '0 B'; + const k = 1024; + const sizes = ['B', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; + }; + + return ( +
{ + if (el) { + fileRefs.current.set(file.id, el); + } else { + fileRefs.current.delete(file.id); + } + }} + data-file-id={file.id} + data-testid="file-thumbnail" + className={` + ${styles.pageContainer} + !rounded-lg + cursor-grab + select-none + w-[20rem] + h-[24rem] + flex flex-col items-center justify-center + flex-shrink-0 + shadow-sm + hover:shadow-md + transition-all + relative + ${selectionMode + ? 'bg-white hover:bg-gray-50' + : 'bg-white hover:bg-gray-50'} + ${draggedFile === file.id ? 'opacity-50 scale-95' : ''} + `} + style={{ + transform: (() => { + if (!isAnimating && draggedFile && file.id !== draggedFile && dropTarget === file.id) { + return 'translateX(20px)'; + } + return 'translateX(0)'; + })(), + transition: isAnimating ? 'none' : 'transform 0.2s ease-in-out', + opacity: isSupported ? 1 : 0.5, + filter: isSupported ? 'none' : 'grayscale(50%)' + }} + draggable + onDragStart={() => onDragStart(file.id)} + onDragEnd={onDragEnd} + onDragOver={onDragOver} + onDragEnter={() => onDragEnter(file.id)} + onDragLeave={onDragLeave} + onDrop={(e) => onDrop(e, file.id)} + > + {selectionMode && ( +
e.stopPropagation()} + onDragStart={(e) => { + e.preventDefault(); + e.stopPropagation(); + }} + > + { + event.stopPropagation(); + if (isSupported) { + onToggleFile(file.id); + } + }} + onClick={(e) => e.stopPropagation()} + disabled={!isSupported} + size="sm" + /> +
+ )} + + {/* File content area */} +
+ {/* Stacked file effect - multiple shadows to simulate pages */} +
+ {file.name} +
+ + {/* Page count badge */} + + {file.pageCount} pages + + + {/* Unsupported badge */} + {!isSupported && ( + +{t("fileManager.unsupported", "Unsupported")} + + )} + + {/* File name overlay */} + + {file.name} + + + {/* Hover controls */} +
+ {!toolMode && isSupported && ( + <> + + { + e.stopPropagation(); + onViewFile(file.id); + onSetStatus(`Opened ${file.name}`); + }} + > + + + + + + )} + + + { + e.stopPropagation(); + setShowHistory(true); + onSetStatus(`Viewing history for ${file.name}`); + }} + > + + + + + + { + e.stopPropagation(); + onDeleteFile(file.id); + onSetStatus(`Closed ${file.name}`); + }} + > + + + +
+ + +
+ + {/* File info */} +
+ + {file.name} + + + {formatFileSize(file.size)} + +
+ + {/* History Modal */} + setShowHistory(false)} + title={`Operation History - ${file.name}`} + size="lg" + scrollAreaComponent="div" + > + + +
+ ); +}; + +export default FileThumbnail; \ No newline at end of file diff --git a/frontend/src/components/pageEditor/PageEditor.module.css b/frontend/src/components/pageEditor/PageEditor.module.css new file mode 100644 index 000000000..8b1c84638 --- /dev/null +++ b/frontend/src/components/pageEditor/PageEditor.module.css @@ -0,0 +1,67 @@ +/* Page container hover effects - optimized for smooth scrolling */ +.pageContainer { + transition: transform 0.2s ease-in-out; + /* Enable hardware acceleration for smoother scrolling */ + will-change: transform; + transform: translateZ(0); + backface-visibility: hidden; +} + +.pageContainer:hover { + transform: scale(1.02) translateZ(0); +} + +.pageContainer:hover .pageNumber { + opacity: 1 !important; +} + +.pageContainer:hover .pageHoverControls { + opacity: 1 !important; +} + +/* Checkbox container - prevent transform inheritance */ +.checkboxContainer { + transform: none !important; + transition: none !important; +} + +/* Page movement animations */ +.pageMoveAnimation { + transition: all 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +.pageMoving { + z-index: 10; + transform: scale(1.05); + box-shadow: 0 10px 30px rgba(0,0,0,0.3); +} + +/* Multi-page drag indicator */ +.multiDragIndicator { + position: fixed; + background: rgba(59, 130, 246, 0.9); + color: white; + padding: 8px 12px; + border-radius: 20px; + font-size: 12px; + font-weight: 600; + pointer-events: none; + z-index: 1000; + box-shadow: 0 4px 12px rgba(0,0,0,0.3); + transform: translate(-50%, -50%); + backdrop-filter: blur(4px); +} + +/* Animations */ +@keyframes pulse { + 0%, 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } +} + +.pulse { + animation: pulse 1s infinite; +} \ No newline at end of file diff --git a/frontend/src/components/pageEditor/PageEditor.tsx b/frontend/src/components/pageEditor/PageEditor.tsx new file mode 100644 index 000000000..4ba56a291 --- /dev/null +++ b/frontend/src/components/pageEditor/PageEditor.tsx @@ -0,0 +1,1415 @@ +import React, { useState, useCallback, useRef, useEffect, useMemo } from "react"; +import { + Button, Text, Center, Checkbox, Box, Tooltip, ActionIcon, + Notification, TextInput, LoadingOverlay, Modal, Alert, + Stack, Group +} from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import { useFileContext, useCurrentFile } from "../../contexts/FileContext"; +import { ViewType, ToolType } from "../../types/fileContext"; +import { PDFDocument, PDFPage } from "../../types/pageEditor"; +import { ProcessedFile as EnhancedProcessedFile } from "../../types/processing"; +import { useUndoRedo } from "../../hooks/useUndoRedo"; +import { + RotatePagesCommand, + DeletePagesCommand, + ReorderPageCommand, + MovePagesCommand, + ToggleSplitCommand +} from "../../commands/pageCommands"; +import { pdfExportService } from "../../services/pdfExportService"; +import { useThumbnailGeneration } from "../../hooks/useThumbnailGeneration"; +import { calculateScaleFromFileSize } from "../../utils/thumbnailUtils"; +import { fileStorage } from "../../services/fileStorage"; +import './PageEditor.module.css'; +import PageThumbnail from './PageThumbnail'; +import BulkSelectionPanel from './BulkSelectionPanel'; +import DragDropGrid from './DragDropGrid'; +import SkeletonLoader from '../shared/SkeletonLoader'; +import NavigationWarningModal from '../shared/NavigationWarningModal'; + +export interface PageEditorProps { + // Optional callbacks to expose internal functions for PageEditorControls + onFunctionsReady?: (functions: { + handleUndo: () => void; + handleRedo: () => void; + canUndo: boolean; + canRedo: boolean; + handleRotate: (direction: 'left' | 'right') => void; + handleDelete: () => void; + handleSplit: () => void; + showExportPreview: (selectedOnly: boolean) => void; + onExportSelected: () => void; + onExportAll: () => void; + exportLoading: boolean; + selectionMode: boolean; + selectedPages: string[]; + closePdf: () => void; + }) => void; +} + +const PageEditor = ({ + onFunctionsReady, +}: PageEditorProps) => { + const { t } = useTranslation(); + + // Get file context + const fileContext = useFileContext(); + const { file: currentFile, processedFile: currentProcessedFile } = useCurrentFile(); + + // Use file context state + const { + activeFiles, + processedFiles, + selectedPageNumbers, + setSelectedPages, + updateProcessedFile, + setHasUnsavedChanges, + hasUnsavedChanges, + isProcessing: globalProcessing, + processingProgress, + clearAllFiles + } = fileContext; + + // Edit state management + const [editedDocument, setEditedDocument] = useState(null); + const [hasUnsavedDraft, setHasUnsavedDraft] = useState(false); + const [showResumeModal, setShowResumeModal] = useState(false); + const [foundDraft, setFoundDraft] = useState(null); + const autoSaveTimer = useRef(null); + + // Simple computed document from processed files (no caching needed) + const mergedPdfDocument = useMemo(() => { + if (activeFiles.length === 0) return null; + + if (activeFiles.length === 1) { + // Single file + const processedFile = processedFiles.get(activeFiles[0]); + if (!processedFile) return null; + + return { + id: processedFile.id, + name: activeFiles[0].name, + file: activeFiles[0], + pages: processedFile.pages.map(page => ({ + ...page, + rotation: page.rotation || 0, + splitBefore: page.splitBefore || false + })), + totalPages: processedFile.totalPages + }; + } else { + // Multiple files - merge them + const allPages: PDFPage[] = []; + let totalPages = 0; + const filenames: string[] = []; + + activeFiles.forEach((file, i) => { + const processedFile = processedFiles.get(file); + if (processedFile) { + filenames.push(file.name.replace(/\.pdf$/i, '')); + + processedFile.pages.forEach((page, pageIndex) => { + const newPage: PDFPage = { + ...page, + id: `${i}-${page.id}`, // Unique ID across all files + pageNumber: totalPages + pageIndex + 1, + rotation: page.rotation || 0, + splitBefore: page.splitBefore || false + }; + allPages.push(newPage); + }); + + totalPages += processedFile.pages.length; + } + }); + + if (allPages.length === 0) return null; + + return { + id: `merged-${Date.now()}`, + name: filenames.join(' + '), + file: activeFiles[0], // Use first file as reference + pages: allPages, + totalPages: totalPages + }; + } + }, [activeFiles, processedFiles]); + + // Display document: Use edited version if exists, otherwise original + const displayDocument = editedDocument || mergedPdfDocument; + + const [filename, setFilename] = useState(""); + + + // Page editor state (use context for selectedPages) + const [status, setStatus] = useState(null); + const [csvInput, setCsvInput] = useState(""); + const [selectionMode, setSelectionMode] = useState(false); + + // Drag and drop state + const [draggedPage, setDraggedPage] = useState(null); + const [dropTarget, setDropTarget] = useState(null); + const [multiPageDrag, setMultiPageDrag] = useState<{pageNumbers: number[], count: number} | null>(null); + const [dragPosition, setDragPosition] = useState<{x: number, y: number} | null>(null); + + // Export state + const [exportLoading, setExportLoading] = useState(false); + const [showExportModal, setShowExportModal] = useState(false); + const [exportPreview, setExportPreview] = useState<{pageCount: number; splitCount: number; estimatedSize: string} | null>(null); + + // Animation state + const [movingPage, setMovingPage] = useState(null); + const [pagePositions, setPagePositions] = useState>(new Map()); + const [isAnimating, setIsAnimating] = useState(false); + const pageRefs = useRef>(new Map()); + const fileInputRef = useRef<() => void>(null); + + // Undo/Redo system + const { executeCommand, undo, redo, canUndo, canRedo } = useUndoRedo(); + + // Set initial filename when document changes + useEffect(() => { + if (mergedPdfDocument) { + if (activeFiles.length === 1) { + setFilename(activeFiles[0].name.replace(/\.pdf$/i, '')); + } else { + const filenames = activeFiles.map(f => f.name.replace(/\.pdf$/i, '')); + setFilename(filenames.join('_')); + } + } + }, [mergedPdfDocument, activeFiles]); + + // Handle file upload from FileUploadSelector (now using context) + const handleMultipleFileUpload = useCallback(async (uploadedFiles: File[]) => { + if (!uploadedFiles || uploadedFiles.length === 0) { + setStatus('No files provided'); + return; + } + + // Add files to context + await fileContext.addFiles(uploadedFiles); + setStatus(`Added ${uploadedFiles.length} file(s) for processing`); + }, [fileContext]); + + + // PageEditor no longer handles cleanup - it's centralized in FileContext + + // Shared PDF instance for thumbnail generation + const [sharedPdfInstance, setSharedPdfInstance] = useState(null); + const [thumbnailGenerationStarted, setThumbnailGenerationStarted] = useState(false); + + // Thumbnail generation (opt-in for visual tools) + const { + generateThumbnails, + addThumbnailToCache, + getThumbnailFromCache, + stopGeneration, + destroyThumbnails + } = useThumbnailGeneration(); + + // Start thumbnail generation process (separate from document loading) + const startThumbnailGeneration = useCallback(() => { + console.log('šŸŽ¬ PageEditor: startThumbnailGeneration called'); + console.log('šŸŽ¬ Conditions - mergedPdfDocument:', !!mergedPdfDocument, 'activeFiles:', activeFiles.length, 'started:', thumbnailGenerationStarted); + + if (!mergedPdfDocument || activeFiles.length !== 1 || thumbnailGenerationStarted) { + console.log('šŸŽ¬ PageEditor: Skipping thumbnail generation due to conditions'); + return; + } + + const file = activeFiles[0]; + const totalPages = mergedPdfDocument.totalPages; + + console.log('šŸŽ¬ PageEditor: Starting thumbnail generation for', totalPages, 'pages'); + setThumbnailGenerationStarted(true); + + // Run everything asynchronously to avoid blocking the main thread + setTimeout(async () => { + try { + // Load PDF array buffer for Web Workers + const arrayBuffer = await file.arrayBuffer(); + + // Generate page numbers for pages that don't have thumbnails yet + const pageNumbers = Array.from({ length: totalPages }, (_, i) => i + 1) + .filter(pageNum => { + const page = mergedPdfDocument.pages.find(p => p.pageNumber === pageNum); + return !page?.thumbnail; // Only generate for pages without thumbnails + }); + + console.log(`šŸŽ¬ PageEditor: Generating thumbnails for ${pageNumbers.length} pages (out of ${totalPages} total):`, pageNumbers.slice(0, 10), pageNumbers.length > 10 ? '...' : ''); + + // If no pages need thumbnails, we're done + if (pageNumbers.length === 0) { + console.log('šŸŽ¬ PageEditor: All pages already have thumbnails, no generation needed'); + return; + } + + // Calculate quality scale based on file size + const scale = activeFiles.length === 1 ? calculateScaleFromFileSize(activeFiles[0].size) : 0.2; + + // Start parallel thumbnail generation WITHOUT blocking the main thread + const generationPromise = generateThumbnails( + arrayBuffer, + pageNumbers, + { + scale, // Dynamic quality based on file size + quality: 0.8, + batchSize: 15, // Smaller batches per worker for smoother UI + parallelBatches: 3 // Use 3 Web Workers in parallel + }, + // Progress callback (throttled for better performance) + (progress) => { + console.log(`šŸŽ¬ PageEditor: Progress - ${progress.completed}/${progress.total} pages, ${progress.thumbnails.length} new thumbnails`); + // Batch process thumbnails to reduce main thread work + requestAnimationFrame(() => { + progress.thumbnails.forEach(({ pageNumber, thumbnail }) => { + // Check cache first, then send thumbnail + const pageId = `${file.name}-page-${pageNumber}`; + const cached = getThumbnailFromCache(pageId); + + if (!cached) { + // Cache and send to component + addThumbnailToCache(pageId, thumbnail); + + window.dispatchEvent(new CustomEvent('thumbnailReady', { + detail: { pageNumber, thumbnail, pageId } + })); + console.log(`āœ“ PageEditor: Dispatched thumbnail for page ${pageNumber}`); + } + }); + }); + } + ); + + // Handle completion properly + generationPromise + .then((allThumbnails) => { + console.log(`āœ… PageEditor: Thumbnail generation completed! Generated ${allThumbnails.length} thumbnails`); + // Don't reset thumbnailGenerationStarted here - let it stay true to prevent restarts + }) + .catch(error => { + console.error('āœ— PageEditor: Web Worker thumbnail generation failed:', error); + setThumbnailGenerationStarted(false); + }); + + } catch (error) { + console.error('Failed to start Web Worker thumbnail generation:', error); + setThumbnailGenerationStarted(false); + } + }, 0); // setTimeout with 0ms to defer to next tick + }, [mergedPdfDocument, activeFiles, thumbnailGenerationStarted, getThumbnailFromCache, addThumbnailToCache]); + + // Start thumbnail generation after document loads + useEffect(() => { + console.log('šŸŽ¬ PageEditor: Thumbnail generation effect triggered'); + console.log('šŸŽ¬ Conditions - mergedPdfDocument:', !!mergedPdfDocument, 'started:', thumbnailGenerationStarted); + + if (mergedPdfDocument && !thumbnailGenerationStarted) { + // Check if ALL pages already have thumbnails from processed files + const totalPages = mergedPdfDocument.pages.length; + const pagesWithThumbnails = mergedPdfDocument.pages.filter(page => page.thumbnail).length; + const hasAllThumbnails = pagesWithThumbnails === totalPages; + + console.log('šŸŽ¬ PageEditor: Thumbnail status:', { + totalPages, + pagesWithThumbnails, + hasAllThumbnails, + missingThumbnails: totalPages - pagesWithThumbnails + }); + + if (hasAllThumbnails) { + console.log('šŸŽ¬ PageEditor: Skipping generation - all thumbnails already exist'); + return; // Skip generation if ALL thumbnails already exist + } + + console.log('šŸŽ¬ PageEditor: Some thumbnails missing, proceeding with generation'); + // Small delay to let document render, then start thumbnail generation + console.log('šŸŽ¬ PageEditor: Scheduling thumbnail generation in 500ms'); + const timer = setTimeout(startThumbnailGeneration, 500); + return () => clearTimeout(timer); + } + }, [mergedPdfDocument, startThumbnailGeneration, thumbnailGenerationStarted]); + + // Cleanup shared PDF instance when component unmounts (but preserve cache) + useEffect(() => { + return () => { + if (sharedPdfInstance) { + sharedPdfInstance.destroy(); + setSharedPdfInstance(null); + } + setThumbnailGenerationStarted(false); + // DON'T stop generation on file changes - preserve cache for view switching + // stopGeneration(); + }; + }, [sharedPdfInstance]); // Only depend on PDF instance, not activeFiles + + // Clear selections when files change + useEffect(() => { + setSelectedPages([]); + setCsvInput(""); + setSelectionMode(false); + }, [activeFiles, setSelectedPages]); + + // Sync csvInput with selectedPageNumbers changes + useEffect(() => { + // Simply sort the page numbers and join them + const sortedPageNumbers = [...selectedPageNumbers].sort((a, b) => a - b); + const newCsvInput = sortedPageNumbers.join(', '); + setCsvInput(newCsvInput); + }, [selectedPageNumbers]); + + useEffect(() => { + const handleGlobalDragEnd = () => { + // Clean up drag state when drag operation ends anywhere + setDraggedPage(null); + setDropTarget(null); + setMultiPageDrag(null); + setDragPosition(null); + }; + + const handleGlobalDrop = (e: DragEvent) => { + // Prevent default to handle invalid drops + e.preventDefault(); + }; + + if (draggedPage) { + document.addEventListener('dragend', handleGlobalDragEnd); + document.addEventListener('drop', handleGlobalDrop); + } + + return () => { + document.removeEventListener('dragend', handleGlobalDragEnd); + document.removeEventListener('drop', handleGlobalDrop); + }; + }, [draggedPage]); + + const selectAll = useCallback(() => { + if (mergedPdfDocument) { + setSelectedPages(mergedPdfDocument.pages.map(p => p.pageNumber)); + } + }, [mergedPdfDocument, setSelectedPages]); + + const deselectAll = useCallback(() => setSelectedPages([]), [setSelectedPages]); + + const togglePage = useCallback((pageNumber: number) => { + console.log('šŸ”„ Toggling page', pageNumber); + + // Check if currently selected and update accordingly + const isCurrentlySelected = selectedPageNumbers.includes(pageNumber); + + if (isCurrentlySelected) { + // Remove from selection + console.log('šŸ”„ Removing page', pageNumber); + const newSelectedPageNumbers = selectedPageNumbers.filter(num => num !== pageNumber); + setSelectedPages(newSelectedPageNumbers); + } else { + // Add to selection + console.log('šŸ”„ Adding page', pageNumber); + const newSelectedPageNumbers = [...selectedPageNumbers, pageNumber]; + setSelectedPages(newSelectedPageNumbers); + } + }, [selectedPageNumbers, setSelectedPages]); + + const toggleSelectionMode = useCallback(() => { + setSelectionMode(prev => { + const newMode = !prev; + if (!newMode) { + // Clear selections when exiting selection mode + setSelectedPages([]); + setCsvInput(""); + } + return newMode; + }); + }, []); + + const parseCSVInput = useCallback((csv: string) => { + if (!mergedPdfDocument) return []; + + const pageNumbers: number[] = []; + const ranges = csv.split(',').map(s => s.trim()).filter(Boolean); + + ranges.forEach(range => { + if (range.includes('-')) { + const [start, end] = range.split('-').map(n => parseInt(n.trim())); + for (let i = start; i <= end && i <= mergedPdfDocument.totalPages; i++) { + if (i > 0) { + pageNumbers.push(i); + } + } + } else { + const pageNum = parseInt(range); + if (pageNum > 0 && pageNum <= mergedPdfDocument.totalPages) { + pageNumbers.push(pageNum); + } + } + }); + + return pageNumbers; + }, [mergedPdfDocument]); + + const updatePagesFromCSV = useCallback(() => { + const pageNumbers = parseCSVInput(csvInput); + setSelectedPages(pageNumbers); + }, [csvInput, parseCSVInput, setSelectedPages]); + + const handleDragStart = useCallback((pageNumber: number) => { + setDraggedPage(pageNumber); + + // Check if this is a multi-page drag in selection mode + if (selectionMode && selectedPageNumbers.includes(pageNumber) && selectedPageNumbers.length > 1) { + setMultiPageDrag({ + pageNumbers: selectedPageNumbers, + count: selectedPageNumbers.length + }); + } else { + setMultiPageDrag(null); + } + }, [selectionMode, selectedPageNumbers]); + + const handleDragEnd = useCallback(() => { + // Clean up drag state regardless of where the drop happened + setDraggedPage(null); + setDropTarget(null); + setMultiPageDrag(null); + setDragPosition(null); + }, []); + + const handleDragOver = useCallback((e: React.DragEvent) => { + e.preventDefault(); + + if (!draggedPage) return; + + // Update drag position for multi-page indicator + if (multiPageDrag) { + setDragPosition({ x: e.clientX, y: e.clientY }); + } + + // Get the element under the mouse cursor + const elementUnderCursor = document.elementFromPoint(e.clientX, e.clientY); + if (!elementUnderCursor) return; + + // Find the closest page container + const pageContainer = elementUnderCursor.closest('[data-page-number]'); + if (pageContainer) { + const pageNumberStr = pageContainer.getAttribute('data-page-number'); + const pageNumber = pageNumberStr ? parseInt(pageNumberStr) : null; + if (pageNumber && pageNumber !== draggedPage) { + setDropTarget(pageNumber); + return; + } + } + + // Check if over the end zone + const endZone = elementUnderCursor.closest('[data-drop-zone="end"]'); + if (endZone) { + setDropTarget('end'); + return; + } + + // If not over any valid drop target, clear it + setDropTarget(null); + }, [draggedPage, multiPageDrag]); + + const handleDragEnter = useCallback((pageNumber: number) => { + if (draggedPage && pageNumber !== draggedPage) { + setDropTarget(pageNumber); + } + }, [draggedPage]); + + const handleDragLeave = useCallback(() => { + // Don't clear drop target on drag leave - let dragover handle it + }, []); + + // Update PDF document state with edit tracking + const setPdfDocument = useCallback((updatedDoc: PDFDocument) => { + console.log('setPdfDocument called - setting edited state'); + + // Update local edit state for immediate visual feedback + setEditedDocument(updatedDoc); + setHasUnsavedChanges(true); // Use global state + setHasUnsavedDraft(true); // Mark that we have unsaved draft changes + + // Auto-save to drafts (debounced) - only if we have new changes + if (autoSaveTimer.current) { + clearTimeout(autoSaveTimer.current); + } + + autoSaveTimer.current = setTimeout(() => { + if (hasUnsavedDraft) { + saveDraftToIndexedDB(updatedDoc); + setHasUnsavedDraft(false); // Mark draft as saved + } + }, 30000); // Auto-save after 30 seconds of inactivity + + return updatedDoc; + }, [setHasUnsavedChanges, hasUnsavedDraft]); + + // Save draft to separate IndexedDB location + const saveDraftToIndexedDB = useCallback(async (doc: PDFDocument) => { + try { + const draftKey = `draft-${doc.id || 'merged'}`; + const draftData = { + document: doc, + timestamp: Date.now(), + originalFiles: activeFiles.map(f => f.name) + }; + + // Save to 'pdf-drafts' store in IndexedDB + const request = indexedDB.open('stirling-pdf-drafts', 1); + request.onupgradeneeded = () => { + const db = request.result; + if (!db.objectStoreNames.contains('drafts')) { + db.createObjectStore('drafts'); + } + }; + + request.onsuccess = () => { + const db = request.result; + const transaction = db.transaction('drafts', 'readwrite'); + const store = transaction.objectStore('drafts'); + store.put(draftData, draftKey); + console.log('Draft auto-saved to IndexedDB'); + }; + } catch (error) { + console.warn('Failed to auto-save draft:', error); + } + }, [activeFiles]); + + // Clean up draft from IndexedDB + const cleanupDraft = useCallback(async () => { + try { + const draftKey = `draft-${mergedPdfDocument?.id || 'merged'}`; + const request = indexedDB.open('stirling-pdf-drafts', 1); + + request.onsuccess = () => { + const db = request.result; + const transaction = db.transaction('drafts', 'readwrite'); + const store = transaction.objectStore('drafts'); + store.delete(draftKey); + }; + } catch (error) { + console.warn('Failed to cleanup draft:', error); + } + }, [mergedPdfDocument]); + + // Apply changes to create new processed file + const applyChanges = useCallback(async () => { + if (!editedDocument || !mergedPdfDocument) return; + + try { + if (activeFiles.length === 1) { + const file = activeFiles[0]; + const currentProcessedFile = processedFiles.get(file); + + if (currentProcessedFile) { + const updatedProcessedFile = { + ...currentProcessedFile, + id: `${currentProcessedFile.id}-edited-${Date.now()}`, + pages: editedDocument.pages.map(page => ({ + ...page, + rotation: page.rotation || 0, + splitBefore: page.splitBefore || false + })), + totalPages: editedDocument.pages.length, + lastModified: Date.now() + }; + + updateProcessedFile(file, updatedProcessedFile); + } + } else if (activeFiles.length > 1) { + setStatus('Apply changes for multiple files not yet supported'); + return; + } + + // Wait for the processed file update to complete before clearing edit state + setTimeout(() => { + setEditedDocument(null); + setHasUnsavedChanges(false); + setHasUnsavedDraft(false); + cleanupDraft(); + setStatus('Changes applied successfully'); + }, 100); + + } catch (error) { + console.error('Failed to apply changes:', error); + setStatus('Failed to apply changes'); + } + }, [editedDocument, mergedPdfDocument, processedFiles, activeFiles, updateProcessedFile, setHasUnsavedChanges, setStatus, cleanupDraft]); + + const animateReorder = useCallback((pageNumber: number, targetIndex: number) => { + if (!displayDocument || isAnimating) return; + + // In selection mode, if the dragged page is selected, move all selected pages + const pagesToMove = selectionMode && selectedPageNumbers.includes(pageNumber) + ? selectedPageNumbers.map(num => { + const page = displayDocument.pages.find(p => p.pageNumber === num); + return page?.id || ''; + }).filter(id => id) + : [displayDocument.pages.find(p => p.pageNumber === pageNumber)?.id || ''].filter(id => id); + + const originalIndex = displayDocument.pages.findIndex(p => p.pageNumber === pageNumber); + if (originalIndex === -1 || originalIndex === targetIndex) return; + + // Skip animation for large documents (500+ pages) to improve performance + const isLargeDocument = displayDocument.pages.length > 500; + + if (isLargeDocument) { + // For large documents, just execute the command without animation + if (pagesToMove.length > 1) { + const command = new MovePagesCommand(displayDocument, setPdfDocument, pagesToMove, targetIndex); + executeCommand(command); + } else { + const pageId = pagesToMove[0]; + const command = new ReorderPageCommand(displayDocument, setPdfDocument, pageId, targetIndex); + executeCommand(command); + } + return; + } + + setIsAnimating(true); + + // For smaller documents, determine which pages might be affected by the move + const startIndex = Math.min(originalIndex, targetIndex); + const endIndex = Math.max(originalIndex, targetIndex); + const affectedPageIds = displayDocument.pages + .slice(Math.max(0, startIndex - 5), Math.min(displayDocument.pages.length, endIndex + 5)) + .map(p => p.id); + + // Only capture positions for potentially affected pages + const currentPositions = new Map(); + + affectedPageIds.forEach(pageId => { + const element = document.querySelector(`[data-page-number="${pageId}"]`); + if (element) { + const rect = element.getBoundingClientRect(); + currentPositions.set(pageId, { x: rect.left, y: rect.top }); + } + }); + + // Execute the reorder command + if (pagesToMove.length > 1) { + const command = new MovePagesCommand(displayDocument, setPdfDocument, pagesToMove, targetIndex); + executeCommand(command); + } else { + const pageId = pagesToMove[0]; + const command = new ReorderPageCommand(displayDocument, setPdfDocument, pageId, targetIndex); + executeCommand(command); + } + + // Animate only the affected pages + setTimeout(() => { + requestAnimationFrame(() => { + requestAnimationFrame(() => { + const newPositions = new Map(); + + // Get new positions only for affected pages + affectedPageIds.forEach(pageId => { + const element = document.querySelector(`[data-page-number="${pageId}"]`); + if (element) { + const rect = element.getBoundingClientRect(); + newPositions.set(pageId, { x: rect.left, y: rect.top }); + } + }); + + const elementsToAnimate: HTMLElement[] = []; + + // Apply animations only to pages that actually moved + affectedPageIds.forEach(pageId => { + const element = document.querySelector(`[data-page-number="${pageId}"]`) as HTMLElement; + if (!element) return; + + const currentPos = currentPositions.get(pageId); + const newPos = newPositions.get(pageId); + + if (currentPos && newPos) { + const deltaX = currentPos.x - newPos.x; + const deltaY = currentPos.y - newPos.y; + + if (Math.abs(deltaX) > 1 || Math.abs(deltaY) > 1) { + elementsToAnimate.push(element); + + // Apply initial transform + element.style.transform = `translate(${deltaX}px, ${deltaY}px)`; + element.style.transition = 'none'; + + // Force reflow + element.offsetHeight; + + // Animate to final position + element.style.transition = 'transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94)'; + element.style.transform = 'translate(0px, 0px)'; + } + } + }); + + // Clean up after animation (only for animated elements) + setTimeout(() => { + elementsToAnimate.forEach((element) => { + element.style.transform = ''; + element.style.transition = ''; + }); + setIsAnimating(false); + }, 300); + }); + }); + }, 10); // Small delay to allow state update + }, [displayDocument, isAnimating, executeCommand, selectionMode, selectedPageNumbers, setPdfDocument]); + + const handleDrop = useCallback((e: React.DragEvent, targetPageNumber: number | 'end') => { + e.preventDefault(); + if (!draggedPage || !displayDocument || draggedPage === targetPageNumber) return; + + let targetIndex: number; + if (targetPageNumber === 'end') { + targetIndex = displayDocument.pages.length; + } else { + targetIndex = displayDocument.pages.findIndex(p => p.pageNumber === targetPageNumber); + if (targetIndex === -1) return; + } + + animateReorder(draggedPage, targetIndex); + + setDraggedPage(null); + setDropTarget(null); + setMultiPageDrag(null); + setDragPosition(null); + + const moveCount = multiPageDrag ? multiPageDrag.count : 1; + setStatus(`${moveCount > 1 ? `${moveCount} pages` : 'Page'} reordered`); + }, [draggedPage, displayDocument, animateReorder, multiPageDrag]); + + const handleEndZoneDragEnter = useCallback(() => { + if (draggedPage) { + setDropTarget('end'); + } + }, [draggedPage]); + + const handleRotate = useCallback((direction: 'left' | 'right') => { + if (!displayDocument) return; + + const rotation = direction === 'left' ? -90 : 90; + const pagesToRotate = selectionMode + ? selectedPageNumbers.map(pageNum => { + const page = displayDocument.pages.find(p => p.pageNumber === pageNum); + return page?.id || ''; + }).filter(id => id) + : displayDocument.pages.map(p => p.id); + + if (selectionMode && selectedPageNumbers.length === 0) return; + + const command = new RotatePagesCommand( + displayDocument, + setPdfDocument, + pagesToRotate, + rotation + ); + + executeCommand(command); + const pageCount = selectionMode ? selectedPageNumbers.length : displayDocument.pages.length; + setStatus(`Rotated ${pageCount} pages ${direction}`); + }, [displayDocument, selectedPageNumbers, selectionMode, executeCommand, setPdfDocument]); + + const handleDelete = useCallback(() => { + if (!displayDocument) return; + + const pagesToDelete = selectionMode + ? selectedPageNumbers.map(pageNum => { + const page = displayDocument.pages.find(p => p.pageNumber === pageNum); + return page?.id || ''; + }).filter(id => id) + : displayDocument.pages.map(p => p.id); + + if (selectionMode && selectedPageNumbers.length === 0) return; + + const command = new DeletePagesCommand( + displayDocument, + setPdfDocument, + pagesToDelete + ); + + executeCommand(command); + if (selectionMode) { + setSelectedPages([]); + } + const pageCount = selectionMode ? selectedPageNumbers.length : displayDocument.pages.length; + setStatus(`Deleted ${pageCount} pages`); + }, [displayDocument, selectedPageNumbers, selectionMode, executeCommand, setPdfDocument, setSelectedPages]); + + const handleSplit = useCallback(() => { + if (!displayDocument) return; + + const pagesToSplit = selectionMode + ? selectedPageNumbers.map(pageNum => { + const page = displayDocument.pages.find(p => p.pageNumber === pageNum); + return page?.id || ''; + }).filter(id => id) + : displayDocument.pages.map(p => p.id); + + if (selectionMode && selectedPageNumbers.length === 0) return; + + const command = new ToggleSplitCommand( + displayDocument, + setPdfDocument, + pagesToSplit + ); + + executeCommand(command); + const pageCount = selectionMode ? selectedPageNumbers.length : displayDocument.pages.length; + setStatus(`Split markers toggled for ${pageCount} pages`); + }, [displayDocument, selectedPageNumbers, selectionMode, executeCommand, setPdfDocument]); + + const showExportPreview = useCallback((selectedOnly: boolean = false) => { + if (!mergedPdfDocument) return; + + // Convert page numbers to page IDs for export service + const exportPageIds = selectedOnly + ? selectedPageNumbers.map(pageNum => { + const page = mergedPdfDocument.pages.find(p => p.pageNumber === pageNum); + return page?.id || ''; + }).filter(id => id) + : []; + + const preview = pdfExportService.getExportInfo(mergedPdfDocument, exportPageIds, selectedOnly); + setExportPreview(preview); + setShowExportModal(true); + }, [mergedPdfDocument, selectedPageNumbers]); + + const handleExport = useCallback(async (selectedOnly: boolean = false) => { + if (!mergedPdfDocument) return; + + setExportLoading(true); + try { + // Convert page numbers to page IDs for export service + const exportPageIds = selectedOnly + ? selectedPageNumbers.map(pageNum => { + const page = mergedPdfDocument.pages.find(p => p.pageNumber === pageNum); + return page?.id || ''; + }).filter(id => id) + : []; + + const errors = pdfExportService.validateExport(mergedPdfDocument, exportPageIds, selectedOnly); + if (errors.length > 0) { + setError(errors.join(', ')); + return; + } + + const hasSplitMarkers = mergedPdfDocument.pages.some(page => page.splitBefore); + + if (hasSplitMarkers) { + const result = await pdfExportService.exportPDF(mergedPdfDocument, exportPageIds, { + selectedOnly, + filename, + splitDocuments: true + }) as { blobs: Blob[]; filenames: string[] }; + + result.blobs.forEach((blob, index) => { + setTimeout(() => { + pdfExportService.downloadFile(blob, result.filenames[index]); + }, index * 500); + }); + + setStatus(`Exported ${result.blobs.length} split documents`); + } else { + const result = await pdfExportService.exportPDF(mergedPdfDocument, exportPageIds, { + selectedOnly, + filename + }) as { blob: Blob; filename: string }; + + pdfExportService.downloadFile(result.blob, result.filename); + setStatus('PDF exported successfully'); + } + } catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Export failed'; + setError(errorMessage); + } finally { + setExportLoading(false); + } + }, [mergedPdfDocument, selectedPageNumbers, filename]); + + const handleUndo = useCallback(() => { + if (undo()) { + setStatus('Operation undone'); + } + }, [undo]); + + const handleRedo = useCallback(() => { + if (redo()) { + setStatus('Operation redone'); + } + }, [redo]); + + const closePdf = useCallback(() => { + // Use global navigation guard system + fileContext.requestNavigation(() => { + clearAllFiles(); // This now handles all cleanup centrally (including merged docs) + setSelectedPages([]); + }); + }, [fileContext, clearAllFiles, setSelectedPages]); + + // PageEditorControls needs onExportSelected and onExportAll + const onExportSelected = useCallback(() => showExportPreview(true), [showExportPreview]); + const onExportAll = useCallback(() => showExportPreview(false), [showExportPreview]); + + // Expose functions to parent component for PageEditorControls + useEffect(() => { + if (onFunctionsReady) { + onFunctionsReady({ + handleUndo, + handleRedo, + canUndo, + canRedo, + handleRotate, + handleDelete, + handleSplit, + showExportPreview, + onExportSelected, + onExportAll, + exportLoading, + selectionMode, + selectedPages: selectedPageNumbers, + closePdf, + }); + } + }, [ + onFunctionsReady, + handleUndo, + handleRedo, + canUndo, + canRedo, + handleRotate, + handleDelete, + handleSplit, + showExportPreview, + onExportSelected, + onExportAll, + exportLoading, + selectionMode, + selectedPageNumbers, + closePdf + ]); + + // Show loading or empty state instead of blocking + const showLoading = !mergedPdfDocument && (globalProcessing || activeFiles.length > 0); + const showEmpty = !mergedPdfDocument && !globalProcessing && activeFiles.length === 0; + // Functions for global NavigationWarningModal + const handleApplyAndContinue = useCallback(async () => { + if (editedDocument) { + await applyChanges(); + } + }, [editedDocument, applyChanges]); + + const handleExportAndContinue = useCallback(async () => { + if (editedDocument) { + await applyChanges(); + await handleExport(false); + } + }, [editedDocument, applyChanges, handleExport]); + + // Check for existing drafts + const checkForDrafts = useCallback(async () => { + if (!mergedPdfDocument) return; + + try { + const draftKey = `draft-${mergedPdfDocument.id || 'merged'}`; + const request = indexedDB.open('stirling-pdf-drafts', 1); + + request.onsuccess = () => { + const db = request.result; + if (!db.objectStoreNames.contains('drafts')) return; + + const transaction = db.transaction('drafts', 'readonly'); + const store = transaction.objectStore('drafts'); + const getRequest = store.get(draftKey); + + getRequest.onsuccess = () => { + const draft = getRequest.result; + if (draft && draft.timestamp) { + // Check if draft is recent (within last 24 hours) + const draftAge = Date.now() - draft.timestamp; + const twentyFourHours = 24 * 60 * 60 * 1000; + + if (draftAge < twentyFourHours) { + setFoundDraft(draft); + setShowResumeModal(true); + } + } + }; + }; + } catch (error) { + console.warn('Failed to check for drafts:', error); + } + }, [mergedPdfDocument]); + + // Resume work from draft + const resumeWork = useCallback(() => { + if (foundDraft && foundDraft.document) { + setEditedDocument(foundDraft.document); + setHasUnsavedChanges(true); + setFoundDraft(null); + setShowResumeModal(false); + setStatus('Resumed previous work'); + } + }, [foundDraft]); + + // Start fresh (ignore draft) + const startFresh = useCallback(() => { + if (foundDraft) { + // Clean up the draft + cleanupDraft(); + } + setFoundDraft(null); + setShowResumeModal(false); + }, [foundDraft, cleanupDraft]); + + // Cleanup on unmount + useEffect(() => { + return () => { + console.log('PageEditor unmounting - cleaning up resources'); + + // Clear auto-save timer + if (autoSaveTimer.current) { + clearTimeout(autoSaveTimer.current); + } + + // Clean up draft if component unmounts with unsaved changes + if (hasUnsavedChanges) { + cleanupDraft(); + } + }; + }, [hasUnsavedChanges, cleanupDraft]); + + // Check for drafts when document loads + useEffect(() => { + if (mergedPdfDocument && !editedDocument && !hasUnsavedChanges) { + // Small delay to let the component settle + setTimeout(checkForDrafts, 1000); + } + }, [mergedPdfDocument, editedDocument, hasUnsavedChanges, checkForDrafts]); + + // Global navigation intercept - listen for navigation events + useEffect(() => { + if (!hasUnsavedChanges) return; + + const handleBeforeUnload = (e: BeforeUnloadEvent) => { + e.preventDefault(); + e.returnValue = 'You have unsaved changes. Are you sure you want to leave?'; + return 'You have unsaved changes. Are you sure you want to leave?'; + }; + + // Intercept browser navigation + window.addEventListener('beforeunload', handleBeforeUnload); + + return () => { + window.removeEventListener('beforeunload', handleBeforeUnload); + }; + }, [hasUnsavedChanges]); + + // Display all pages - use edited or original document + const displayedPages = displayDocument?.pages || []; + + return ( + + + + {showEmpty && ( +
+ + šŸ“„ + No PDF files loaded + Add files to start editing pages + +
+ )} + + {showLoading && ( + + + + {/* Progress indicator */} + + + + Processing PDF files... + + + {Math.round(processingProgress || 0)}% + + +
+
+
+ + + + + )} + + {displayDocument && ( + + {/* Enhanced Processing Status */} + {globalProcessing && processingProgress < 100 && ( + + + Processing thumbnails... + {Math.round(processingProgress || 0)}% + +
+
+
+ + )} + + + setFilename(e.target.value)} + placeholder="Enter filename" + style={{ minWidth: 200 }} + /> + + {selectionMode && ( + <> + + + + )} + + {/* Apply Changes Button */} + {hasUnsavedChanges && ( + + )} + + + {selectionMode && ( + + )} + + + ( + + )} + renderSplitMarker={(page, index) => ( +
+ )} + /> + + + )} + + {/* Modal should be outside the conditional but inside the main container */} + setShowExportModal(false)} + title="Export Preview" + > + {exportPreview && ( + + + Pages to export: + {exportPreview.pageCount} + + + {exportPreview.splitCount > 1 && ( + + Split into documents: + {exportPreview.splitCount} + + )} + + + Estimated size: + {exportPreview.estimatedSize} + + + {mergedPdfDocument && mergedPdfDocument.pages.some(p => p.splitBefore) && ( + + This will create multiple PDF files based on split markers. + + )} + + + + + + + )} + + + {/* Global Navigation Warning Modal */} + + + {/* Resume Work Modal */} + + + + We found unsaved changes from a previous session. Would you like to resume where you left off? + + + {foundDraft && ( + + Last saved: {new Date(foundDraft.timestamp).toLocaleString()} + + )} + + + + + + + + + + {status && ( + setStatus(null)} + style={{ position: 'fixed', bottom: 20, right: 20, zIndex: 1000 }} + > + {status} + + )} + + ); +}; + +export default PageEditor; diff --git a/frontend/src/components/pageEditor/PageEditorControls.tsx b/frontend/src/components/pageEditor/PageEditorControls.tsx new file mode 100644 index 000000000..9ab23ae2d --- /dev/null +++ b/frontend/src/components/pageEditor/PageEditorControls.tsx @@ -0,0 +1,191 @@ +import React from "react"; +import { + Tooltip, + ActionIcon, + Paper +} from "@mantine/core"; +import UndoIcon from "@mui/icons-material/Undo"; +import RedoIcon from "@mui/icons-material/Redo"; +import ContentCutIcon from "@mui/icons-material/ContentCut"; +import DownloadIcon from "@mui/icons-material/Download"; +import RotateLeftIcon from "@mui/icons-material/RotateLeft"; +import RotateRightIcon from "@mui/icons-material/RotateRight"; +import DeleteIcon from "@mui/icons-material/Delete"; +import CloseIcon from "@mui/icons-material/Close"; + +interface PageEditorControlsProps { + // Close/Reset functions + onClosePdf: () => void; + + // Undo/Redo + onUndo: () => void; + onRedo: () => void; + canUndo: boolean; + canRedo: boolean; + + // Page operations + onRotate: (direction: 'left' | 'right') => void; + onDelete: () => void; + onSplit: () => void; + + // Export functions + onExportSelected: () => void; + onExportAll: () => void; + exportLoading: boolean; + + // Selection state + selectionMode: boolean; + selectedPages: string[]; +} + +const PageEditorControls = ({ + onClosePdf, + onUndo, + onRedo, + canUndo, + canRedo, + onRotate, + onDelete, + onSplit, + onExportSelected, + onExportAll, + exportLoading, + selectionMode, + selectedPages +}: PageEditorControlsProps) => { + return ( +
+ + {/* Close PDF */} + + + + + + +
+ + {/* Undo/Redo */} + + + + + + + + + + + +
+ + {/* Page Operations */} + + onRotate('left')} + disabled={selectionMode && selectedPages.length === 0} + variant={selectionMode && selectedPages.length > 0 ? "light" : "default"} + color={selectionMode && selectedPages.length > 0 ? "blue" : undefined} + size="lg" + > + + + + + onRotate('right')} + disabled={selectionMode && selectedPages.length === 0} + variant={selectionMode && selectedPages.length > 0 ? "light" : "default"} + color={selectionMode && selectedPages.length > 0 ? "blue" : undefined} + size="lg" + > + + + + + 0 ? "light" : "default"} + size="lg" + > + + + + + 0 ? "light" : "default"} + color={selectionMode && selectedPages.length > 0 ? "blue" : undefined} + size="lg" + > + + + + +
+ + {/* Export Controls */} + {selectionMode && selectedPages.length > 0 && ( + + + + + + )} + + + + + + +
+ ); +}; + +export default PageEditorControls; diff --git a/frontend/src/components/pageEditor/PageThumbnail.tsx b/frontend/src/components/pageEditor/PageThumbnail.tsx new file mode 100644 index 000000000..3f6edc68e --- /dev/null +++ b/frontend/src/components/pageEditor/PageThumbnail.tsx @@ -0,0 +1,440 @@ +import React, { useCallback, useState, useEffect, useRef } from 'react'; +import { Text, Checkbox, Tooltip, ActionIcon, Loader } from '@mantine/core'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; +import RotateLeftIcon from '@mui/icons-material/RotateLeft'; +import RotateRightIcon from '@mui/icons-material/RotateRight'; +import DeleteIcon from '@mui/icons-material/Delete'; +import ContentCutIcon from '@mui/icons-material/ContentCut'; +import DragIndicatorIcon from '@mui/icons-material/DragIndicator'; +import { PDFPage, PDFDocument } from '../../../types/pageEditor'; +import { RotatePagesCommand, DeletePagesCommand, ToggleSplitCommand } from '../../../commands/pageCommands'; +import { Command } from '../../../hooks/useUndoRedo'; +import styles from './PageEditor.module.css'; +import { getDocument, GlobalWorkerOptions } from 'pdfjs-dist'; + +// Ensure PDF.js worker is available +if (!GlobalWorkerOptions.workerSrc) { + GlobalWorkerOptions.workerSrc = '/pdf.worker.js'; + console.log('šŸ“ø PageThumbnail: Set PDF.js worker source to /pdf.worker.js'); +} else { + console.log('šŸ“ø PageThumbnail: PDF.js worker source already set to', GlobalWorkerOptions.workerSrc); +} + +interface PageThumbnailProps { + page: PDFPage; + index: number; + totalPages: number; + originalFile?: File; // For lazy thumbnail generation + selectedPages: number[]; + selectionMode: boolean; + draggedPage: number | null; + dropTarget: number | null; + movingPage: number | null; + isAnimating: boolean; + pageRefs: React.MutableRefObject>; + onDragStart: (pageNumber: number) => void; + onDragEnd: () => void; + onDragOver: (e: React.DragEvent) => void; + onDragEnter: (pageNumber: number) => void; + onDragLeave: () => void; + onDrop: (e: React.DragEvent, pageNumber: number) => void; + onTogglePage: (pageNumber: number) => void; + onAnimateReorder: (pageNumber: number, targetIndex: number) => void; + onExecuteCommand: (command: Command) => void; + onSetStatus: (status: string) => void; + onSetMovingPage: (pageNumber: number | null) => void; + RotatePagesCommand: typeof RotatePagesCommand; + DeletePagesCommand: typeof DeletePagesCommand; + ToggleSplitCommand: typeof ToggleSplitCommand; + pdfDocument: PDFDocument; + setPdfDocument: (doc: PDFDocument) => void; +} + +const PageThumbnail = React.memo(({ + page, + index, + totalPages, + originalFile, + selectedPages, + selectionMode, + draggedPage, + dropTarget, + movingPage, + isAnimating, + pageRefs, + onDragStart, + onDragEnd, + onDragOver, + onDragEnter, + onDragLeave, + onDrop, + onTogglePage, + onAnimateReorder, + onExecuteCommand, + onSetStatus, + onSetMovingPage, + RotatePagesCommand, + DeletePagesCommand, + ToggleSplitCommand, + pdfDocument, + setPdfDocument, +}: PageThumbnailProps) => { + const [thumbnailUrl, setThumbnailUrl] = useState(page.thumbnail); + const [isLoadingThumbnail, setIsLoadingThumbnail] = useState(false); + + // Update thumbnail URL when page prop changes + useEffect(() => { + if (page.thumbnail && page.thumbnail !== thumbnailUrl) { + console.log(`šŸ“ø PageThumbnail: Updating thumbnail URL for page ${page.pageNumber}`, page.thumbnail.substring(0, 50) + '...'); + setThumbnailUrl(page.thumbnail); + } + }, [page.thumbnail, page.pageNumber, page.id, thumbnailUrl]); + + // Listen for ready thumbnails from Web Workers (only if no existing thumbnail) + useEffect(() => { + if (thumbnailUrl) { + console.log(`šŸ“ø PageThumbnail: Page ${page.pageNumber} already has thumbnail, skipping worker listener`); + return; // Skip if we already have a thumbnail + } + + console.log(`šŸ“ø PageThumbnail: Setting up worker listener for page ${page.pageNumber} (${page.id})`); + + const handleThumbnailReady = (event: CustomEvent) => { + const { pageNumber, thumbnail, pageId } = event.detail; + console.log(`šŸ“ø PageThumbnail: Received worker thumbnail for page ${pageNumber}, looking for page ${page.pageNumber} (${page.id})`); + + if (pageNumber === page.pageNumber && pageId === page.id) { + console.log(`āœ“ PageThumbnail: Thumbnail matched for page ${page.pageNumber}, setting URL`); + setThumbnailUrl(thumbnail); + } + }; + + window.addEventListener('thumbnailReady', handleThumbnailReady as EventListener); + return () => { + console.log(`šŸ“ø PageThumbnail: Cleaning up worker listener for page ${page.pageNumber}`); + window.removeEventListener('thumbnailReady', handleThumbnailReady as EventListener); + }; + }, [page.pageNumber, page.id, thumbnailUrl]); + + + // Register this component with pageRefs for animations + const pageElementRef = useCallback((element: HTMLDivElement | null) => { + if (element) { + pageRefs.current.set(page.id, element); + } else { + pageRefs.current.delete(page.id); + } + }, [page.id, pageRefs]); + + return ( +
{ + if (!isAnimating && draggedPage && page.pageNumber !== draggedPage && dropTarget === page.pageNumber) { + return 'translateX(20px)'; + } + return 'translateX(0)'; + })(), + transition: isAnimating ? 'none' : 'transform 0.2s ease-in-out' + }} + draggable + onDragStart={() => onDragStart(page.pageNumber)} + onDragEnd={onDragEnd} + onDragOver={onDragOver} + onDragEnter={() => onDragEnter(page.pageNumber)} + onDragLeave={onDragLeave} + onDrop={(e) => onDrop(e, page.pageNumber)} + > + {selectionMode && ( +
e.stopPropagation()} + onDragStart={(e) => { + e.preventDefault(); + e.stopPropagation(); + }} + onClick={(e) => { + console.log('šŸ“ø Checkbox clicked for page', page.pageNumber); + e.stopPropagation(); + onTogglePage(page.pageNumber); + }} + > + { + // onChange is handled by the parent div click + }} + size="sm" + /> +
+ )} + +
+
+ {thumbnailUrl ? ( + {`Page + ) : isLoadingThumbnail ? ( +
+ + Loading... +
+ ) : ( +
+ šŸ“„ + Page {page.pageNumber} +
+ )} +
+ + + {page.pageNumber} + + +
+ + { + e.stopPropagation(); + if (index > 0 && !movingPage && !isAnimating) { + onSetMovingPage(page.pageNumber); + onAnimateReorder(page.pageNumber, index - 1); + setTimeout(() => onSetMovingPage(null), 500); + onSetStatus(`Moved page ${page.pageNumber} left`); + } + }} + > + + + + + + { + e.stopPropagation(); + if (index < totalPages - 1 && !movingPage && !isAnimating) { + onSetMovingPage(page.pageNumber); + onAnimateReorder(page.pageNumber, index + 1); + setTimeout(() => onSetMovingPage(null), 500); + onSetStatus(`Moved page ${page.pageNumber} right`); + } + }} + > + + + + + + { + e.stopPropagation(); + const command = new RotatePagesCommand( + pdfDocument, + setPdfDocument, + [page.id], + -90 + ); + onExecuteCommand(command); + onSetStatus(`Rotated page ${page.pageNumber} left`); + }} + > + + + + + + { + e.stopPropagation(); + const command = new RotatePagesCommand( + pdfDocument, + setPdfDocument, + [page.id], + 90 + ); + onExecuteCommand(command); + onSetStatus(`Rotated page ${page.pageNumber} right`); + }} + > + + + + + + { + e.stopPropagation(); + const command = new DeletePagesCommand( + pdfDocument, + setPdfDocument, + [page.id] + ); + onExecuteCommand(command); + onSetStatus(`Deleted page ${page.pageNumber}`); + }} + > + + + + + {index > 0 && ( + + { + e.stopPropagation(); + const command = new ToggleSplitCommand( + pdfDocument, + setPdfDocument, + [page.id] + ); + onExecuteCommand(command); + onSetStatus(`Split marker toggled for page ${page.pageNumber}`); + }} + > + + + + )} +
+ + +
+
+ ); +}, (prevProps, nextProps) => { + // Only re-render if essential props change + return ( + prevProps.page.id === nextProps.page.id && + prevProps.page.pageNumber === nextProps.page.pageNumber && + prevProps.page.rotation === nextProps.page.rotation && + prevProps.page.thumbnail === nextProps.page.thumbnail && + prevProps.selectedPages === nextProps.selectedPages && // Compare array reference - will re-render when selection changes + prevProps.selectionMode === nextProps.selectionMode && + prevProps.draggedPage === nextProps.draggedPage && + prevProps.dropTarget === nextProps.dropTarget && + prevProps.movingPage === nextProps.movingPage && + prevProps.isAnimating === nextProps.isAnimating + ); +}); + +export default PageThumbnail; diff --git a/frontend/src/components/shared/AppConfigModal.tsx b/frontend/src/components/shared/AppConfigModal.tsx new file mode 100644 index 000000000..a73e3ff73 --- /dev/null +++ b/frontend/src/components/shared/AppConfigModal.tsx @@ -0,0 +1,140 @@ +import React from 'react'; +import { Modal, Button, Stack, Text, Code, ScrollArea, Group, Badge, Alert, Loader } from '@mantine/core'; +import { useAppConfig } from '../../hooks/useAppConfig'; + +interface AppConfigModalProps { + opened: boolean; + onClose: () => void; +} + +const AppConfigModal: React.FC = ({ opened, onClose }) => { + const { config, loading, error, refetch } = useAppConfig(); + + const renderConfigSection = (title: string, data: any) => { + if (!data || typeof data !== 'object') return null; + + return ( + + {title} + + {Object.entries(data).map(([key, value]) => ( + + + {key}: + + {typeof value === 'boolean' ? ( + + {value ? 'true' : 'false'} + + ) : typeof value === 'object' ? ( + {JSON.stringify(value, null, 2)} + ) : ( + String(value) || 'null' + )} + + ))} + + + ); + }; + + const basicConfig = config ? { + appName: config.appName, + appNameNavbar: config.appNameNavbar, + baseUrl: config.baseUrl, + contextPath: config.contextPath, + serverPort: config.serverPort, + } : null; + + const securityConfig = config ? { + enableLogin: config.enableLogin, + } : null; + + const systemConfig = config ? { + enableAlphaFunctionality: config.enableAlphaFunctionality, + enableAnalytics: config.enableAnalytics, + } : null; + + const premiumConfig = config ? { + premiumEnabled: config.premiumEnabled, + premiumKey: config.premiumKey ? '***hidden***' : null, + runningProOrHigher: config.runningProOrHigher, + runningEE: config.runningEE, + license: config.license, + } : null; + + const integrationConfig = config ? { + GoogleDriveEnabled: config.GoogleDriveEnabled, + SSOAutoLogin: config.SSOAutoLogin, + } : null; + + const legalConfig = config ? { + termsAndConditions: config.termsAndConditions, + privacyPolicy: config.privacyPolicy, + cookiePolicy: config.cookiePolicy, + impressum: config.impressum, + accessibilityStatement: config.accessibilityStatement, + } : null; + + return ( + + + + + This modal shows the current application configuration for testing purposes only. + + + + + {loading && ( + + + Loading configuration... + + )} + + {error && ( + + {error} + + )} + + {config && ( + + + {renderConfigSection('Basic Configuration', basicConfig)} + {renderConfigSection('Security Configuration', securityConfig)} + {renderConfigSection('System Configuration', systemConfig)} + {renderConfigSection('Premium/Enterprise Configuration', premiumConfig)} + {renderConfigSection('Integration Configuration', integrationConfig)} + {renderConfigSection('Legal Configuration', legalConfig)} + + {config.error && ( + + {config.error} + + )} + + + Raw Configuration + + {JSON.stringify(config, null, 2)} + + + + + )} + + + ); +}; + +export default AppConfigModal; \ No newline at end of file diff --git a/frontend/src/components/shared/DropdownListWithFooter.tsx b/frontend/src/components/shared/DropdownListWithFooter.tsx new file mode 100644 index 000000000..368b2255e --- /dev/null +++ b/frontend/src/components/shared/DropdownListWithFooter.tsx @@ -0,0 +1,237 @@ +import React, { ReactNode, useState, useMemo } from 'react'; +import { Stack, Text, Popover, Box, Checkbox, Group, TextInput } from '@mantine/core'; +import UnfoldMoreIcon from '@mui/icons-material/UnfoldMore'; +import SearchIcon from '@mui/icons-material/Search'; + +export interface DropdownItem { + value: string; + name: string; + leftIcon?: ReactNode; + disabled?: boolean; +} + +export interface DropdownListWithFooterProps { + // Value and onChange - support both single and multi-select + value: string | string[]; + onChange: (value: string | string[]) => void; + + // Items and display + items: DropdownItem[]; + placeholder?: string; + disabled?: boolean; + + // Labels and headers + label?: string; + header?: ReactNode; + footer?: ReactNode; + + // Behavior + multiSelect?: boolean; + searchable?: boolean; + maxHeight?: number; + + // Styling + className?: string; + dropdownClassName?: string; + + // Popover props + position?: 'top' | 'bottom' | 'left' | 'right'; + withArrow?: boolean; + width?: 'target' | number; +} + +const DropdownListWithFooter: React.FC = ({ + value, + onChange, + items, + placeholder = 'Select option', + disabled = false, + label, + header, + footer, + multiSelect = false, + searchable = false, + maxHeight = 300, + className = '', + dropdownClassName = '', + position = 'bottom', + withArrow = false, + width = 'target' +}) => { + + const [searchTerm, setSearchTerm] = useState(''); + + const isMultiValue = Array.isArray(value); + const selectedValues = isMultiValue ? value : (value ? [value] : []); + + // Filter items based on search term + const filteredItems = useMemo(() => { + if (!searchable || !searchTerm.trim()) { + return items; + } + return items.filter(item => + item.name.toLowerCase().includes(searchTerm.toLowerCase()) + ); + }, [items, searchTerm, searchable]); + + const handleItemClick = (itemValue: string) => { + if (multiSelect) { + const newSelection = selectedValues.includes(itemValue) + ? selectedValues.filter(v => v !== itemValue) + : [...selectedValues, itemValue]; + onChange(newSelection); + } else { + onChange(itemValue); + } + }; + + const getDisplayText = () => { + if (selectedValues.length === 0) { + return placeholder; + } else if (selectedValues.length === 1) { + const selectedItem = items.find(item => item.value === selectedValues[0]); + return selectedItem?.name || selectedValues[0]; + } else { + return `${selectedValues.length} selected`; + } + }; + + const handleSearchChange = (event: React.ChangeEvent) => { + setSearchTerm(event.currentTarget.value); + }; + + return ( + + {label && ( + + {label} + + )} + + searchable && setSearchTerm('')} + > + + + + {getDisplayText()} + + + + + + + + {header && ( + + {header} + + )} + + {searchable && ( + + } + size="sm" + style={{ width: '100%' }} + /> + + )} + + + {filteredItems.length === 0 ? ( + + + {searchable && searchTerm ? 'No results found' : 'No items available'} + + + ) : ( + filteredItems.map((item) => ( + !item.disabled && handleItemClick(item.value)} + style={{ + padding: '8px 12px', + cursor: item.disabled ? 'not-allowed' : 'pointer', + borderRadius: 'var(--mantine-radius-sm)', + opacity: item.disabled ? 0.5 : 1, + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between' + }} + onMouseEnter={(e) => { + if (!item.disabled) { + e.currentTarget.style.backgroundColor = 'light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-5))'; + } + }} + onMouseLeave={(e) => { + e.currentTarget.style.backgroundColor = 'transparent'; + }} + > + + {item.leftIcon && ( + + {item.leftIcon} + + )} + {item.name} + + + {multiSelect && ( + {}} // Handled by parent onClick + size="sm" + disabled={item.disabled} + /> + )} + + )) + )} + + + {footer && ( + + {footer} + + )} + + + + + ); +}; + +export default DropdownListWithFooter; \ No newline at end of file diff --git a/frontend/src/components/shared/FileCard.tsx b/frontend/src/components/shared/FileCard.tsx new file mode 100644 index 000000000..1b686ddaf --- /dev/null +++ b/frontend/src/components/shared/FileCard.tsx @@ -0,0 +1,211 @@ +import React, { useState } from "react"; +import { Card, Stack, Text, Group, Badge, Button, Box, Image, ThemeIcon, ActionIcon, Tooltip } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf"; +import StorageIcon from "@mui/icons-material/Storage"; +import VisibilityIcon from "@mui/icons-material/Visibility"; +import EditIcon from "@mui/icons-material/Edit"; + +import { FileWithUrl } from "../../types/file"; +import { getFileSize, getFileDate } from "../../utils/fileUtils"; +import { useIndexedDBThumbnail } from "../../hooks/useIndexedDBThumbnail"; +import { fileStorage } from "../../services/fileStorage"; + +interface FileCardProps { + file: FileWithUrl; + onRemove: () => void; + onDoubleClick?: () => void; + onView?: () => void; + onEdit?: () => void; + isSelected?: boolean; + onSelect?: () => void; + isSupported?: boolean; // Whether the file format is supported by the current tool +} + +const FileCard = ({ file, onRemove, onDoubleClick, onView, onEdit, isSelected, onSelect, isSupported = true }: FileCardProps) => { + const { t } = useTranslation(); + const { thumbnail: thumb, isGenerating } = useIndexedDBThumbnail(file); + const [isHovered, setIsHovered] = useState(false); + + return ( + setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + onClick={onSelect} + data-testid="file-card" + > + + + {/* Hover action buttons */} + {isHovered && (onView || onEdit) && ( +
e.stopPropagation()} + > + {onView && ( + + { + e.stopPropagation(); + onView(); + }} + > + + + + )} + {onEdit && ( + + { + e.stopPropagation(); + onEdit(); + }} + > + + + + )} +
+ )} + {thumb ? ( + PDF thumbnail + ) : isGenerating ? ( +
+
+ Generating... +
+ ) : ( +
+ 100 * 1024 * 1024 ? "orange" : "red"} + size={60} + radius="sm" + style={{ display: "flex", alignItems: "center", justifyContent: "center" }} + > + + + {file.size > 100 * 1024 * 1024 && ( + Large File + )} +
+ )} + + + + {file.name} + + + + + {getFileSize(file)} + + + {getFileDate(file)} + + {file.storedInIndexedDB && ( + } + > + DB + + )} + {!isSupported && ( + + {t("fileManager.unsupported", "Unsupported")} + + )} + + + + + + ); +}; + +export default FileCard; diff --git a/frontend/src/components/shared/FileGrid.tsx b/frontend/src/components/shared/FileGrid.tsx new file mode 100644 index 000000000..791a8a453 --- /dev/null +++ b/frontend/src/components/shared/FileGrid.tsx @@ -0,0 +1,172 @@ +import React, { useState } from "react"; +import { Box, Flex, Group, Text, Button, TextInput, Select, Badge } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import SearchIcon from "@mui/icons-material/Search"; +import SortIcon from "@mui/icons-material/Sort"; +import FileCard from "./FileCard"; +import { FileWithUrl } from "../../types/file"; + +interface FileGridProps { + files: FileWithUrl[]; + onRemove?: (index: number) => void; + onDoubleClick?: (file: FileWithUrl) => void; + onView?: (file: FileWithUrl) => void; + onEdit?: (file: FileWithUrl) => void; + onSelect?: (fileId: string) => void; + selectedFiles?: string[]; + showSearch?: boolean; + showSort?: boolean; + maxDisplay?: number; // If set, shows only this many files with "Show All" option + onShowAll?: () => void; + showingAll?: boolean; + onDeleteAll?: () => void; + isFileSupported?: (fileName: string) => boolean; // Function to check if file is supported +} + +type SortOption = 'date' | 'name' | 'size'; + +const FileGrid = ({ + files, + onRemove, + onDoubleClick, + onView, + onEdit, + onSelect, + selectedFiles = [], + showSearch = false, + showSort = false, + maxDisplay, + onShowAll, + showingAll = false, + onDeleteAll, + isFileSupported +}: FileGridProps) => { + const { t } = useTranslation(); + const [searchTerm, setSearchTerm] = useState(""); + const [sortBy, setSortBy] = useState('date'); + + // Filter files based on search term + const filteredFiles = files.filter(file => + file.name.toLowerCase().includes(searchTerm.toLowerCase()) + ); + + // Sort files + const sortedFiles = [...filteredFiles].sort((a, b) => { + switch (sortBy) { + case 'date': + return (b.lastModified || 0) - (a.lastModified || 0); + case 'name': + return a.name.localeCompare(b.name); + case 'size': + return (b.size || 0) - (a.size || 0); + default: + return 0; + } + }); + + // Apply max display limit if specified + const displayFiles = maxDisplay && !showingAll + ? sortedFiles.slice(0, maxDisplay) + : sortedFiles; + + const hasMoreFiles = maxDisplay && !showingAll && sortedFiles.length > maxDisplay; + + return ( + + {/* Search and Sort Controls */} + {(showSearch || showSort || onDeleteAll) && ( + + + {showSearch && ( + } + value={searchTerm} + onChange={(e) => setSearchTerm(e.currentTarget.value)} + style={{ flexGrow: 1, maxWidth: 300, minWidth: 200 }} + /> + )} + + {showSort && ( + + +
+ + {/* Instruction Text */} + + {t('fileUpload.dragFilesInOrClick', 'Drag files in or click "Add Files" to browse')} + +
+ + + ); +}; + +export default LandingPage; \ No newline at end of file diff --git a/frontend/src/components/shared/LanguageSelector.module.css b/frontend/src/components/shared/LanguageSelector.module.css new file mode 100644 index 000000000..431f43806 --- /dev/null +++ b/frontend/src/components/shared/LanguageSelector.module.css @@ -0,0 +1,88 @@ +/* Language selector grid responsive layout */ +.languageGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 0; +} + +.languageItem { + border-right: 2px solid var(--mantine-color-gray-3); +} + +.languageItem:nth-child(4n) { + border-right: none; +} + +/* Responsive breakpoints */ +@media (max-width: 600px) { + .languageGrid { + grid-template-columns: repeat(2, 1fr); + } + + .languageItem:nth-child(4n) { + border-right: 2px solid var(--mantine-color-gray-3); + } + + .languageItem:nth-child(2n) { + border-right: none; + } +} + +@media (min-width: 601px) and (max-width: 900px) { + .languageGrid { + grid-template-columns: repeat(3, 1fr); + } + + .languageItem:nth-child(4n) { + border-right: 2px solid var(--mantine-color-gray-3); + } + + .languageItem:nth-child(3n) { + border-right: none; + } +} + +/* Dark theme support */ +[data-mantine-color-scheme="dark"] .languageItem { + border-right-color: var(--mantine-color-dark-3); +} + +[data-mantine-color-scheme="dark"] .languageItem:nth-child(4n) { + border-right: none; +} + +[data-mantine-color-scheme="dark"] .languageItem:nth-child(2n) { + border-right-color: var(--mantine-color-dark-3); +} + +[data-mantine-color-scheme="dark"] .languageItem:nth-child(3n) { + border-right-color: var(--mantine-color-dark-3); +} + +/* Responsive text visibility */ +.languageText { + display: none; +} + +@media (min-width: 768px) { + .languageText { + display: inline; + } +} + +/* Ripple animation */ +@keyframes ripple { + 0% { + width: 0; + height: 0; + opacity: 0.6; + } + 50% { + opacity: 0.3; + } + 100% { + width: 100px; + height: 100px; + opacity: 0; + } +} \ No newline at end of file diff --git a/frontend/src/components/shared/LanguageSelector.tsx b/frontend/src/components/shared/LanguageSelector.tsx new file mode 100644 index 000000000..bd6269b8e --- /dev/null +++ b/frontend/src/components/shared/LanguageSelector.tsx @@ -0,0 +1,215 @@ +import React, { useState, useEffect } from 'react'; +import { Menu, Button, ScrollArea } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; +import { supportedLanguages } from '../../i18n'; +import LanguageIcon from '@mui/icons-material/Language'; +import styles from './LanguageSelector.module.css'; + +const LanguageSelector = () => { + const { i18n } = useTranslation(); + const [opened, setOpened] = useState(false); + const [animationTriggered, setAnimationTriggered] = useState(false); + const [isChanging, setIsChanging] = useState(false); + const [pendingLanguage, setPendingLanguage] = useState(null); + const [rippleEffect, setRippleEffect] = useState<{x: number, y: number, key: number} | null>(null); + + const languageOptions = Object.entries(supportedLanguages) + .sort(([, nameA], [, nameB]) => nameA.localeCompare(nameB)) + .map(([code, name]) => ({ + value: code, + label: name, + })); + + const handleLanguageChange = (value: string, event: React.MouseEvent) => { + // Create ripple effect at click position + const rect = event.currentTarget.getBoundingClientRect(); + const x = event.clientX - rect.left; + const y = event.clientY - rect.top; + + setRippleEffect({ x, y, key: Date.now() }); + + // Start transition animation + setIsChanging(true); + setPendingLanguage(value); + + // Simulate processing time for smooth transition + setTimeout(() => { + i18n.changeLanguage(value); + + setTimeout(() => { + setIsChanging(false); + setPendingLanguage(null); + setOpened(false); + + // Clear ripple effect + setTimeout(() => setRippleEffect(null), 100); + }, 300); + }, 200); + }; + + const currentLanguage = supportedLanguages[i18n.language as keyof typeof supportedLanguages] || + supportedLanguages['en-GB']; + + // Trigger animation when dropdown opens + useEffect(() => { + if (opened) { + setAnimationTriggered(false); + // Small delay to ensure DOM is ready + setTimeout(() => setAnimationTriggered(true), 50); + } + }, [opened]); + + return ( + <> + + + + + + + + +
+ {languageOptions.map((option, index) => ( +
+ +
+ ))} +
+
+
+
+ + ); +}; + +export default LanguageSelector; \ No newline at end of file diff --git a/frontend/src/components/shared/MultiSelectControls.tsx b/frontend/src/components/shared/MultiSelectControls.tsx new file mode 100644 index 000000000..11790abf8 --- /dev/null +++ b/frontend/src/components/shared/MultiSelectControls.tsx @@ -0,0 +1,88 @@ +import React from "react"; +import { Box, Group, Text, Button } from "@mantine/core"; +import { useTranslation } from "react-i18next"; + +interface MultiSelectControlsProps { + selectedCount: number; + onClearSelection: () => void; + onOpenInFileEditor?: () => void; + onOpenInPageEditor?: () => void; + onAddToUpload?: () => void; + onDeleteAll?: () => void; +} + +const MultiSelectControls = ({ + selectedCount, + onClearSelection, + onOpenInFileEditor, + onOpenInPageEditor, + onAddToUpload, + onDeleteAll +}: MultiSelectControlsProps) => { + const { t } = useTranslation(); + + if (selectedCount === 0) return null; + + return ( + + + + {selectedCount} {t("fileManager.filesSelected", "files selected")} + + + + + {onAddToUpload && ( + + )} + + {onOpenInFileEditor && ( + + )} + + {onOpenInPageEditor && ( + + )} + + {onDeleteAll && ( + + )} + + + + ); +}; + +export default MultiSelectControls; \ No newline at end of file diff --git a/frontend/src/components/shared/NavigationWarningModal.tsx b/frontend/src/components/shared/NavigationWarningModal.tsx new file mode 100644 index 000000000..a3d3983d2 --- /dev/null +++ b/frontend/src/components/shared/NavigationWarningModal.tsx @@ -0,0 +1,106 @@ +import React from 'react'; +import { Modal, Text, Button, Group, Stack } from '@mantine/core'; +import { useFileContext } from '../../contexts/FileContext'; + +interface NavigationWarningModalProps { + onApplyAndContinue?: () => Promise; + onExportAndContinue?: () => Promise; +} + +const NavigationWarningModal = ({ + onApplyAndContinue, + onExportAndContinue +}: NavigationWarningModalProps) => { + const { + showNavigationWarning, + hasUnsavedChanges, + confirmNavigation, + cancelNavigation, + setHasUnsavedChanges + } = useFileContext(); + + const handleKeepWorking = () => { + cancelNavigation(); + }; + + const handleDiscardChanges = () => { + setHasUnsavedChanges(false); + confirmNavigation(); + }; + + const handleApplyAndContinue = async () => { + if (onApplyAndContinue) { + await onApplyAndContinue(); + } + setHasUnsavedChanges(false); + confirmNavigation(); + }; + + const handleExportAndContinue = async () => { + if (onExportAndContinue) { + await onExportAndContinue(); + } + setHasUnsavedChanges(false); + confirmNavigation(); + }; + + if (!hasUnsavedChanges) { + return null; + } + + return ( + + + + You have unsaved changes to your PDF. What would you like to do? + + + + + + + + {onApplyAndContinue && ( + + )} + + {onExportAndContinue && ( + + )} + + + + ); +}; + +export default NavigationWarningModal; \ No newline at end of file diff --git a/frontend/src/components/shared/QuickAccessBar.css b/frontend/src/components/shared/QuickAccessBar.css new file mode 100644 index 000000000..b1d22fcc3 --- /dev/null +++ b/frontend/src/components/shared/QuickAccessBar.css @@ -0,0 +1,179 @@ +.activeIconScale { + transform: scale(1.3); + transition: transform 0.2s; + z-index: 1; +} + +.iconContainer { + display: flex; + align-items: center; + justify-content: center; + width: 2rem; + height: 2rem; +} + +/* Action icon styles */ +.action-icon-style { + background-color: var(--icon-user-bg); + color: var(--icon-user-color); + border-radius: 50%; + width: 1.5rem; + height: 1.5rem; +} + +/* Main container styles */ +.quick-access-bar-main { + background-color: var(--bg-muted); + width: 5rem; + min-width: 5rem; + max-width: 5rem; + position: relative; + z-index: 10; +} + +/* Rainbow mode container */ +.quick-access-bar-main.rainbow-mode { + background-color: var(--bg-muted); + width: 5rem; + min-width: 5rem; + max-width: 5rem; + position: relative; + z-index: 10; +} + +/* Header padding */ +.quick-access-header { + padding: 1rem 0.5rem 0.5rem 0.5rem; +} + +.nav-header { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + margin-bottom: 0; + gap: 0.5rem; +} + +/* Nav header divider */ +.nav-header-divider { + width: 3.75rem; + border-color: var(--color-gray-300); + margin-top: 0.5rem; + margin-bottom: 1rem; +} + +/* All tools text styles */ +.all-tools-text { + margin-top: 0.75rem; + font-size: 0.75rem; + text-rendering: optimizeLegibility; + font-synthesis: none; +} + +.all-tools-text.active { + color: var(--text-primary); + font-weight: bold; +} + +.all-tools-text.inactive { + color: var(--color-gray-700); + font-weight: normal; +} + +/* Overflow divider */ +.overflow-divider { + width: 3.75rem; + border-color: var(--color-gray-300); + margin: 0 0.5rem; +} + +/* Scrollable content area */ +.quick-access-bar { + overflow-x: auto; + overflow-y: auto; + scrollbar-gutter: stable both-edges; + -webkit-overflow-scrolling: touch; + padding: 0 0.5rem 1rem 0.5rem; +} + +/* Scrollable content container */ +.scrollable-content { + display: flex; + flex-direction: column; + height: 100%; + min-height: 100%; +} + +/* Button text styles */ +.button-text { + margin-top: 0.75rem; + font-size: 0.75rem; + text-rendering: optimizeLegibility; + font-synthesis: none; +} + +.button-text.active { + color: var(--text-primary); + font-weight: bold; +} + +.button-text.inactive { + color: var(--color-gray-700); + font-weight: normal; +} + +/* Content divider */ +.content-divider { + width: 3.75rem; + border-color: var(--color-gray-300); +} + +/* Spacer */ +.spacer { + flex: 1; + margin-top: 1rem; +} + +/* Config button text */ +.config-button-text { + margin-top: 0.75rem; + font-size: 0.75rem; + color: var(--color-gray-700); + font-weight: normal; + text-rendering: optimizeLegibility; + font-synthesis: none; +} + +/* Font size utility */ +.font-size-20 { + font-size: 20px; +} + +/* Hide scrollbar by default, show on scroll (Webkit browsers - Chrome, Safari, Edge) */ +.quick-access-bar::-webkit-scrollbar { + width: 0.5rem; + height: 0.5rem; + background: transparent; +} + +.quick-access-bar:hover::-webkit-scrollbar, +.quick-access-bar:active::-webkit-scrollbar, +.quick-access-bar:focus::-webkit-scrollbar { + background: rgba(0, 0, 0, 0.1); +} + +.quick-access-bar::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.2); + border-radius: 0.25rem; +} + +.quick-access-bar::-webkit-scrollbar-track { + background: transparent; +} + +/* Firefox scrollbar styling */ +.quick-access-bar { + scrollbar-width: auto; + scrollbar-color: rgba(0, 0, 0, 0.2) transparent; +} \ No newline at end of file diff --git a/frontend/src/components/shared/QuickAccessBar.tsx b/frontend/src/components/shared/QuickAccessBar.tsx new file mode 100644 index 000000000..7aed3632b --- /dev/null +++ b/frontend/src/components/shared/QuickAccessBar.tsx @@ -0,0 +1,313 @@ +import React, { useState, useRef, forwardRef } from "react"; +import { ActionIcon, Stack, Tooltip, Divider } from "@mantine/core"; +import MenuBookIcon from "@mui/icons-material/MenuBookRounded"; +import AppsIcon from "@mui/icons-material/AppsRounded"; +import SettingsIcon from "@mui/icons-material/SettingsRounded"; +import AutoAwesomeIcon from "@mui/icons-material/AutoAwesomeRounded"; +import FolderIcon from "@mui/icons-material/FolderRounded"; +import PersonIcon from "@mui/icons-material/PersonRounded"; +import NotificationsIcon from "@mui/icons-material/NotificationsRounded"; +import { useRainbowThemeContext } from "./RainbowThemeProvider"; +import AppConfigModal from './AppConfigModal'; +import { useIsOverflowing } from '../../hooks/useIsOverflowing'; +import { useFilesModalContext } from '../../contexts/FilesModalContext'; +import { useToolWorkflow } from '../../contexts/ToolWorkflowContext'; +import { ButtonConfig } from '../../types/sidebar'; +import './QuickAccessBar.css'; + +function NavHeader({ + activeButton, + setActiveButton +}: { + activeButton: string; + setActiveButton: (id: string) => void; +}) { + const { handleReaderToggle, handleBackToTools } = useToolWorkflow(); + return ( + <> +
+ + + + + + + + + + +
+ {/* Divider after top icons */} + + {/* All Tools button below divider */} + +
+ { + setActiveButton('tools'); + handleReaderToggle(); + handleBackToTools(); + }} + style={{ + backgroundColor: activeButton === 'tools' ? 'var(--icon-tools-bg)' : 'var(--icon-inactive-bg)', + color: activeButton === 'tools' ? 'var(--icon-tools-color)' : 'var(--icon-inactive-color)', + border: 'none', + borderRadius: '8px', + }} + className={activeButton === 'tools' ? 'activeIconScale' : ''} + > + + + + + + All Tools + +
+
+ + ); +} + +const QuickAccessBar = forwardRef(({ +}, ref) => { + const { isRainbowMode } = useRainbowThemeContext(); + const { openFilesModal, isFilesModalOpen } = useFilesModalContext(); + const { handleReaderToggle } = useToolWorkflow(); + const [configModalOpen, setConfigModalOpen] = useState(false); + const [activeButton, setActiveButton] = useState('tools'); + const scrollableRef = useRef(null); + const isOverflow = useIsOverflowing(scrollableRef); + + const handleFilesButtonClick = () => { + openFilesModal(); + }; + + const buttonConfigs: ButtonConfig[] = [ + { + id: 'read', + name: 'Read', + icon: , + tooltip: 'Read documents', + size: 'lg', + isRound: false, + type: 'navigation', + onClick: () => { + setActiveButton('read'); + handleReaderToggle(); + } + }, + { + id: 'sign', + name: 'Sign', + icon: + + signature + , + tooltip: 'Sign your document', + size: 'lg', + isRound: false, + type: 'navigation', + onClick: () => setActiveButton('sign') + }, + { + id: 'automate', + name: 'Automate', + icon: , + tooltip: 'Automate workflows', + size: 'lg', + isRound: false, + type: 'navigation', + onClick: () => setActiveButton('automate') + }, + { + id: 'files', + name: 'Files', + icon: , + tooltip: 'Manage files', + isRound: true, + size: 'lg', + type: 'modal', + onClick: handleFilesButtonClick + }, + { + id: 'activity', + name: 'Activity', + icon: + + vital_signs + , + tooltip: 'View activity and analytics', + isRound: true, + size: 'lg', + type: 'navigation', + onClick: () => setActiveButton('activity') + }, + { + id: 'config', + name: 'Config', + icon: , + tooltip: 'Configure settings', + size: 'lg', + type: 'modal', + onClick: () => { + setConfigModalOpen(true); + } + } + ]; + + const CIRCULAR_BORDER_RADIUS = '50%'; + const ROUND_BORDER_RADIUS = '8px'; + + const getBorderRadius = (config: ButtonConfig): string => { + return config.isRound ? CIRCULAR_BORDER_RADIUS : ROUND_BORDER_RADIUS; + }; + + const isButtonActive = (config: ButtonConfig): boolean => { + return ( + (config.type === 'navigation' && activeButton === config.id) || + (config.type === 'modal' && config.id === 'files' && isFilesModalOpen) || + (config.type === 'modal' && config.id === 'config' && configModalOpen) + ); + }; + + const getButtonStyle = (config: ButtonConfig) => { + const isActive = isButtonActive(config); + + if (isActive) { + return { + backgroundColor: `var(--icon-${config.id}-bg)`, + color: `var(--icon-${config.id}-color)`, + border: 'none', + borderRadius: getBorderRadius(config), + }; + } + + // Inactive state for all buttons + return { + backgroundColor: 'var(--icon-inactive-bg)', + color: 'var(--icon-inactive-color)', + border: 'none', + borderRadius: getBorderRadius(config), + }; + }; + + return ( +
+ {/* Fixed header outside scrollable area */} +
+ +
+ + {/* Conditional divider when overflowing */} + {isOverflow && ( + + )} + + {/* Scrollable content area */} +
{ + // Prevent the wheel event from bubbling up to parent containers + e.stopPropagation(); + }} + > +
+ {/* Top section with main buttons */} + + {buttonConfigs.slice(0, -1).map((config, index) => ( + + +
+ + + {config.icon} + + + + {config.name} + +
+
+ + {/* Add divider after Automate button (index 2) */} + {index === 2 && ( + + )} +
+ ))} +
+ + {/* Spacer to push Config button to bottom */} +
+ + {/* Config button at the bottom */} + {buttonConfigs + .filter(config => config.id === 'config') + .map(config => ( + +
+ + + {config.icon} + + + + {config.name} + +
+
+ ))} +
+
+ + setConfigModalOpen(false)} + /> +
+ ); +}); + +export default QuickAccessBar; \ No newline at end of file diff --git a/frontend/src/components/shared/RainbowThemeProvider.tsx b/frontend/src/components/shared/RainbowThemeProvider.tsx new file mode 100644 index 000000000..27cf5101f --- /dev/null +++ b/frontend/src/components/shared/RainbowThemeProvider.tsx @@ -0,0 +1,55 @@ +import React, { createContext, useContext, ReactNode } from 'react'; +import { MantineProvider, ColorSchemeScript } from '@mantine/core'; +import { useRainbowTheme } from '../../hooks/useRainbowTheme'; +import { mantineTheme } from '../../theme/mantineTheme'; +import rainbowStyles from '../../styles/rainbow.module.css'; + +interface RainbowThemeContextType { + themeMode: 'light' | 'dark' | 'rainbow'; + isRainbowMode: boolean; + isToggleDisabled: boolean; + toggleTheme: () => void; + activateRainbow: () => void; + deactivateRainbow: () => void; +} + +const RainbowThemeContext = createContext(null); + +export function useRainbowThemeContext() { + const context = useContext(RainbowThemeContext); + if (!context) { + throw new Error('useRainbowThemeContext must be used within RainbowThemeProvider'); + } + return context; +} + +interface RainbowThemeProviderProps { + children: ReactNode; +} + +export function RainbowThemeProvider({ children }: RainbowThemeProviderProps) { + const rainbowTheme = useRainbowTheme(); + + // Determine the Mantine color scheme + const mantineColorScheme = rainbowTheme.themeMode === 'rainbow' ? 'dark' : rainbowTheme.themeMode; + + return ( + <> + + + +
+ {children} +
+
+
+ + ); +} diff --git a/frontend/src/components/shared/SkeletonLoader.tsx b/frontend/src/components/shared/SkeletonLoader.tsx new file mode 100644 index 000000000..63c4bd22a --- /dev/null +++ b/frontend/src/components/shared/SkeletonLoader.tsx @@ -0,0 +1,104 @@ +import React from 'react'; +import { Box, Group, Stack } from '@mantine/core'; + +interface SkeletonLoaderProps { + type: 'pageGrid' | 'fileGrid' | 'controls' | 'viewer'; + count?: number; + animated?: boolean; +} + +const SkeletonLoader: React.FC = ({ + type, + count = 8, + animated = true +}) => { + const animationStyle = animated ? { animation: 'pulse 2s infinite' } : {}; + + const renderPageGridSkeleton = () => ( +
+ {Array.from({ length: count }).map((_, i) => ( + + ))} +
+ ); + + const renderFileGridSkeleton = () => ( +
+ {Array.from({ length: count }).map((_, i) => ( + + ))} +
+ ); + + const renderControlsSkeleton = () => ( + + + + + + ); + + const renderViewerSkeleton = () => ( + + {/* Toolbar skeleton */} + + + + + + + {/* Main content skeleton */} + + + ); + + switch (type) { + case 'pageGrid': + return renderPageGridSkeleton(); + case 'fileGrid': + return renderFileGridSkeleton(); + case 'controls': + return renderControlsSkeleton(); + case 'viewer': + return renderViewerSkeleton(); + default: + return null; + } +}; + +export default SkeletonLoader; \ No newline at end of file diff --git a/frontend/src/components/shared/Tooltip.tsx b/frontend/src/components/shared/Tooltip.tsx new file mode 100644 index 000000000..6deda77c4 --- /dev/null +++ b/frontend/src/components/shared/Tooltip.tsx @@ -0,0 +1,243 @@ +import React, { useState, useRef, useEffect } from 'react'; +import { createPortal } from 'react-dom'; +import { isClickOutside, addEventListenerWithCleanup } from '../../utils/genericUtils'; +import { useTooltipPosition } from '../../hooks/useTooltipPosition'; +import { TooltipContent, TooltipTip } from './tooltip/TooltipContent'; +import { useSidebarContext } from '../../contexts/SidebarContext'; +import styles from './tooltip/Tooltip.module.css' + +export interface TooltipProps { + sidebarTooltip?: boolean; + position?: 'right' | 'left' | 'top' | 'bottom'; + content?: React.ReactNode; + tips?: TooltipTip[]; + children: React.ReactElement; + offset?: number; + maxWidth?: number | string; + open?: boolean; + onOpenChange?: (open: boolean) => void; + arrow?: boolean; + portalTarget?: HTMLElement; + header?: { + title: string; + logo?: React.ReactNode; + }; +} + +export const Tooltip: React.FC = ({ + sidebarTooltip = false, + position = 'right', + content, + tips, + children, + offset: gap = 8, + maxWidth = 280, + open: controlledOpen, + onOpenChange, + arrow = false, + portalTarget, + header, +}) => { + const [internalOpen, setInternalOpen] = useState(false); + const [isPinned, setIsPinned] = useState(false); + const triggerRef = useRef(null); + const tooltipRef = useRef(null); + const hoverTimeoutRef = useRef | null>(null); + + // Get sidebar context for tooltip positioning + const sidebarContext = sidebarTooltip ? useSidebarContext() : null; + + // Always use controlled mode - if no controlled props provided, use internal state + const isControlled = controlledOpen !== undefined; + const open = isControlled ? controlledOpen : internalOpen; + + const handleOpenChange = (newOpen: boolean) => { + if (isControlled) { + onOpenChange?.(newOpen); + } else { + setInternalOpen(newOpen); + } + + // Reset pin state when closing + if (!newOpen) { + setIsPinned(false); + } + }; + + const handleTooltipClick = (e: React.MouseEvent) => { + e.stopPropagation(); + setIsPinned(true); + }; + + const handleDocumentClick = (e: MouseEvent) => { + // If tooltip is pinned and we click outside of it, unpin it + if (isPinned && isClickOutside(e, tooltipRef.current)) { + setIsPinned(false); + handleOpenChange(false); + } + }; + + // Use the positioning hook + const { coords, positionReady } = useTooltipPosition({ + open, + sidebarTooltip, + position, + gap, + triggerRef, + tooltipRef, + sidebarRefs: sidebarContext?.sidebarRefs, + sidebarState: sidebarContext?.sidebarState + }); + + // Add document click listener for unpinning + useEffect(() => { + if (isPinned) { + return addEventListenerWithCleanup(document, 'click', handleDocumentClick as EventListener); + } + }, [isPinned]); + + const getArrowClass = () => { + // No arrow for sidebar tooltips + if (sidebarTooltip) return null; + + switch (position) { + case 'top': return "tooltip-arrow tooltip-arrow-top"; + case 'bottom': return "tooltip-arrow tooltip-arrow-bottom"; + case 'left': return "tooltip-arrow tooltip-arrow-left"; + case 'right': return "tooltip-arrow tooltip-arrow-right"; + default: return "tooltip-arrow tooltip-arrow-right"; + } + }; + + const getArrowStyleClass = (arrowClass: string) => { + const styleKey = arrowClass.split(' ')[1]; + // Handle both kebab-case and camelCase CSS module exports + return styles[styleKey as keyof typeof styles] || + styles[styleKey.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) as keyof typeof styles] || + ''; + }; + + // Only show tooltip when position is ready and correct + const shouldShowTooltip = open && (sidebarTooltip ? positionReady : true); + + const tooltipElement = shouldShowTooltip ? ( +
+ {isPinned && ( + + )} + {arrow && getArrowClass() && ( +
+ )} + {header && ( +
+
+ {header.logo || Stirling PDF} +
+ {header.title} +
+ )} + +
+ ) : null; + + const handleMouseEnter = (e: React.MouseEvent) => { + // Clear any existing timeout + if (hoverTimeoutRef.current) { + clearTimeout(hoverTimeoutRef.current); + hoverTimeoutRef.current = null; + } + + // Only show on hover if not pinned + if (!isPinned) { + handleOpenChange(true); + } + + (children.props as any)?.onMouseEnter?.(e); + }; + + const handleMouseLeave = (e: React.MouseEvent) => { + // Only hide on mouse leave if not pinned + if (!isPinned) { + // Add a small delay to prevent flickering + hoverTimeoutRef.current = setTimeout(() => { + handleOpenChange(false); + }, 100); + } + + (children.props as any)?.onMouseLeave?.(e); + }; + + const handleClick = (e: React.MouseEvent) => { + // Toggle pin state on click + if (open) { + setIsPinned(!isPinned); + } else { + handleOpenChange(true); + setIsPinned(true); + } + + (children.props as any)?.onClick?.(e); + }; + + // Take the child element and add tooltip behavior to it + const childWithTooltipHandlers = React.cloneElement(children as any, { + // Keep track of the element for positioning + ref: (node: HTMLElement) => { + triggerRef.current = node; + // Don't break if the child already has a ref + const originalRef = (children as any).ref; + if (typeof originalRef === 'function') { + originalRef(node); + } else if (originalRef && typeof originalRef === 'object') { + originalRef.current = node; + } + }, + // Add mouse events to show/hide tooltip + onMouseEnter: handleMouseEnter, + onMouseLeave: handleMouseLeave, + onClick: handleClick, + }); + + return ( + <> + {childWithTooltipHandlers} + {portalTarget && document.body.contains(portalTarget) + ? tooltipElement && createPortal(tooltipElement, portalTarget) + : tooltipElement} + + ); +}; \ No newline at end of file diff --git a/frontend/src/components/shared/TopControls.tsx b/frontend/src/components/shared/TopControls.tsx new file mode 100644 index 000000000..5b772c90a --- /dev/null +++ b/frontend/src/components/shared/TopControls.tsx @@ -0,0 +1,139 @@ +import React, { useState, useCallback } from "react"; +import { Button, SegmentedControl, Loader } from "@mantine/core"; +import { useRainbowThemeContext } from "./RainbowThemeProvider"; +import LanguageSelector from "./LanguageSelector"; +import rainbowStyles from '../../styles/rainbow.module.css'; +import DarkModeIcon from '@mui/icons-material/DarkMode'; +import LightModeIcon from '@mui/icons-material/LightMode'; +import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome'; +import VisibilityIcon from "@mui/icons-material/Visibility"; +import EditNoteIcon from "@mui/icons-material/EditNote"; +import FolderIcon from "@mui/icons-material/Folder"; +import { Group } from "@mantine/core"; + +// This will be created inside the component to access switchingTo +const createViewOptions = (switchingTo: string | null) => [ + { + label: ( + + {switchingTo === "viewer" ? ( + + ) : ( + + )} + + ), + value: "viewer", + }, + { + label: ( + + {switchingTo === "pageEditor" ? ( + + ) : ( + + )} + + ), + value: "pageEditor", + }, + { + label: ( + + {switchingTo === "fileEditor" ? ( + + ) : ( + + )} + + ), + value: "fileEditor", + }, +]; + +interface TopControlsProps { + currentView: string; + setCurrentView: (view: string) => void; + selectedToolKey?: string | null; +} + +const TopControls = ({ + currentView, + setCurrentView, + selectedToolKey, +}: TopControlsProps) => { + const { themeMode, isRainbowMode, isToggleDisabled, toggleTheme } = useRainbowThemeContext(); + const [switchingTo, setSwitchingTo] = useState(null); + + const isToolSelected = selectedToolKey !== null; + + const handleViewChange = useCallback((view: string) => { + // Show immediate feedback + setSwitchingTo(view); + + // Defer the heavy view change to next frame so spinner can render + requestAnimationFrame(() => { + // Give the spinner one more frame to show + requestAnimationFrame(() => { + setCurrentView(view); + + // Clear the loading state after view change completes + setTimeout(() => setSwitchingTo(null), 300); + }); + }); + }, [setCurrentView]); + + const getThemeIcon = () => { + if (isRainbowMode) return ; + if (themeMode === "dark") return ; + return ; + }; + + return ( +
+
+ + +
+ {!isToolSelected && ( +
+ +
+ )} +
+ ); +}; + +export default TopControls; diff --git a/frontend/src/components/shared/tooltip/Tooltip.README.md b/frontend/src/components/shared/tooltip/Tooltip.README.md new file mode 100644 index 000000000..df1a977b0 --- /dev/null +++ b/frontend/src/components/shared/tooltip/Tooltip.README.md @@ -0,0 +1,223 @@ +# Tooltip Component + +A flexible, accessible tooltip component that supports both regular positioning and special sidebar positioning logic with click-to-pin functionality. The tooltip is controlled by default, appearing on hover and pinning on click. + +## Features + +- šŸŽÆ **Smart Positioning**: Automatically positions tooltips to stay within viewport bounds +- šŸ“± **Sidebar Support**: Special positioning logic for sidebar/navigation elements +- ♿ **Accessible**: Works with mouse interactions and click-to-pin functionality +- šŸŽØ **Customizable**: Support for arrows, structured content, and custom JSX +- šŸŒ™ **Theme Support**: Built-in dark mode and theme variable support +- ⚔ **Performance**: Memoized calculations and efficient event handling +- šŸ“œ **Scrollable**: Content area scrolls when content exceeds max height +- šŸ“Œ **Click-to-Pin**: Click to pin tooltips open, click outside or the close button to unpin +- šŸ”— **Link Support**: Full support for clickable links in descriptions, bullets, and body content +- šŸŽ® **Controlled by Default**: Always uses controlled state management for consistent behavior + +## Behavior + +### Default Behavior (Controlled) +- **Hover**: Tooltips appear on hover with a small delay when leaving to prevent flickering +- **Click**: Click the trigger to pin the tooltip open +- **Click tooltip**: Pins the tooltip to keep it open +- **Click close button**: Unpins and closes the tooltip (red X button in top-right when pinned) +- **Click outside**: Unpins and closes the tooltip +- **Visual indicator**: Pinned tooltips have a blue border and close button + +### Manual Control (Optional) +- Use `open` and `onOpenChange` props for complete external control +- Useful for complex state management or custom interaction patterns + +## Basic Usage + +```tsx +import { Tooltip } from '@/components/shared'; + +function MyComponent() { + return ( + + + + ); +} +``` + +## API Reference + +### Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `content` | `ReactNode` | - | Custom JSX content to display in the tooltip | +| `tips` | `TooltipTip[]` | - | Structured content with title, description, bullets, and optional body | +| `children` | `ReactElement` | **required** | Element that triggers the tooltip | +| `sidebarTooltip` | `boolean` | `false` | Enables special sidebar positioning logic | +| `position` | `'right' \| 'left' \| 'top' \| 'bottom'` | `'right'` | Tooltip position (ignored if `sidebarTooltip` is true) | +| `offset` | `number` | `8` | Distance in pixels between trigger and tooltip | +| `maxWidth` | `number \| string` | `280` | Maximum width constraint for the tooltip | +| `open` | `boolean` | `undefined` | External open state (makes component fully controlled) | +| `onOpenChange` | `(open: boolean) => void` | `undefined` | Callback for external control | +| `arrow` | `boolean` | `false` | Shows a small triangular arrow pointing to the trigger element | +| `portalTarget` | `HTMLElement` | `undefined` | DOM node to portal the tooltip into | +| `header` | `{ title: string; logo?: ReactNode }` | - | Optional header with title and logo | + +### TooltipTip Interface + +```typescript +interface TooltipTip { + title?: string; // Optional pill label + description?: string; // Optional description text (supports HTML including tags) + bullets?: string[]; // Optional bullet points (supports HTML including tags) + body?: React.ReactNode; // Optional custom JSX for this tip +} +``` + +## Usage Examples + +### Default Behavior (Recommended) + +```tsx +// Simple tooltip with hover and click-to-pin + + + + +// Structured content with tips +Auto skips pages that already contain text.", + "Force re-processes every page.", + "Strict stops if text is found.", + "Learn more" + ] + } + ]} + header={{ + title: "Basic Settings Overview", + logo: Logo + }} +> + + +``` + +### Custom JSX Content + +```tsx + +

Custom Content

+

Any JSX you want here

+ + External link +
+ } +> + + +``` + +### Mixed Content (Tips + Custom JSX) + +```tsx +Additional custom content below tips
} +> + + +``` + +### Sidebar Tooltips + +```tsx +// For items in a sidebar/navigation + +
+ šŸ“ File Manager +
+
+``` + +### With Arrows + +```tsx + + + +``` + +### Manual Control (Advanced) + +```tsx +function ManualControlTooltip() { + const [open, setOpen] = useState(false); + + return ( + + + + ); +} +``` + +## Click-to-Pin Interaction + +### How to Use (Default Behavior) +1. **Hover** over the trigger element to show the tooltip +2. **Click** the trigger element to pin the tooltip open +3. **Click** the red X button in the top-right corner to close +4. **Click** anywhere outside the tooltip to close +5. **Click** the trigger again to toggle pin state + +### Visual States +- **Unpinned**: Normal tooltip appearance +- **Pinned**: Blue border, subtle glow, and close button (X) in top-right corner + +## Link Support + +The tooltip fully supports clickable links in all content areas: + +- **Descriptions**: Use `` in description strings +- **Bullets**: Use `` in bullet point strings +- **Body**: Use JSX `` elements in the body ReactNode +- **Content**: Use JSX `` elements in custom content + +Links automatically get proper styling with hover states and open in new tabs when using `target="_blank"`. + +## Positioning Logic + +### Regular Tooltips +- Uses the `position` prop to determine initial placement +- Automatically clamps to viewport boundaries +- Calculates optimal position based on trigger element's `getBoundingClientRect()` +- **Dynamic arrow positioning**: Arrow stays aligned with trigger even when tooltip is clamped + +### Sidebar Tooltips +- When `sidebarTooltip={true}`, horizontal positioning is locked to the right of the sidebar +- Vertical positioning follows the trigger but clamps to viewport +- **Smart sidebar detection**: Uses `getSidebarInfo()` to determine which sidebar is active (tool panel vs quick access bar) and gets its exact position +- **Dynamic positioning**: Adapts to whether the tool panel is expanded or collapsed +- **Conditional display**: Only shows tooltips when the tool panel is active (`sidebarInfo.isToolPanelActive`) +- **No arrows** - sidebar tooltips don't show arrows diff --git a/frontend/src/components/shared/tooltip/Tooltip.module.css b/frontend/src/components/shared/tooltip/Tooltip.module.css new file mode 100644 index 000000000..209f0dcbd --- /dev/null +++ b/frontend/src/components/shared/tooltip/Tooltip.module.css @@ -0,0 +1,191 @@ +/* Tooltip Container */ +.tooltip-container { + position: fixed; + border: 0.0625rem solid var(--border-default); + border-radius: 0.75rem; + background-color: var(--bg-raised); + box-shadow: 0 0.625rem 0.9375rem -0.1875rem rgba(0, 0, 0, 0.1), 0 0.25rem 0.375rem -0.125rem rgba(0, 0, 0, 0.05); + font-size: 0.875rem; + line-height: 1.5; + pointer-events: auto; + z-index: 9999; + transition: opacity 100ms ease-out, transform 100ms ease-out; + min-width: 25rem; + max-width: 50vh; + max-height: 80vh; + color: var(--text-primary); + display: flex; + flex-direction: column; +} + +/* Pinned tooltip indicator */ +.tooltip-container.pinned { + border-color: var(--primary-color, #3b82f6); + box-shadow: 0 0.625rem 0.9375rem -0.1875rem rgba(0, 0, 0, 0.1), 0 0.25rem 0.375rem -0.125rem rgba(0, 0, 0, 0.05), 0 0 0 0.125rem rgba(59, 130, 246, 0.1); +} + +/* Pinned tooltip header */ +.tooltip-container.pinned .tooltip-header { + background-color: var(--primary-color, #3b82f6); + color: white; + border-color: var(--primary-color, #3b82f6); +} + +/* Close button */ +.tooltip-pin-button { + position: absolute; + top: -0.5rem; + right: 0.5rem; + font-size: 0.875rem; + background: var(--bg-raised); + padding: 0.25rem; + border-radius: 0.25rem; + border: 0.0625rem solid var(--primary-color, #3b82f6); + cursor: pointer; + transition: background-color 0.2s ease, border-color 0.2s ease; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + min-width: 1.5rem; + min-height: 1.5rem; +} + +.tooltip-pin-button .material-symbols-outlined { + font-size: 1rem; + line-height: 1; +} + +.tooltip-pin-button:hover { + background-color: #ef4444 !important; + border-color: #ef4444 !important; +} + +/* Tooltip Header */ +.tooltip-header { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.75rem 1rem; + background-color: var(--tooltip-header-bg); + color: var(--tooltip-header-color); + font-size: 0.875rem; + font-weight: 500; + border-top-left-radius: 0.75rem; + border-top-right-radius: 0.75rem; + margin: -0.0625rem -0.0625rem 0 -0.0625rem; + border: 0.0625rem solid var(--tooltip-border); + flex-shrink: 0; +} + +.tooltip-logo { + width: 1rem; + height: 1rem; + display: flex; + align-items: center; + justify-content: center; +} + +.tooltip-title { + flex: 1; +} + +/* Tooltip Body */ +.tooltip-body { + padding: 1rem !important; + color: var(--text-primary) !important; + font-size: 0.875rem !important; + line-height: 1.6 !important; + overflow-y: auto; + flex: 1; + min-height: 0; +} + +.tooltip-body * { + color: var(--text-primary) !important; +} + +/* Link styling within tooltips */ +.tooltip-body a { + color: var(--link-color, #3b82f6) !important; + text-decoration: underline; + text-decoration-color: var(--link-underline-color, rgba(59, 130, 246, 0.3)); + transition: color 0.2s ease, text-decoration-color 0.2s ease; +} + +.tooltip-body a:hover { + color: var(--link-hover-color, #2563eb) !important; + text-decoration-color: var(--link-hover-underline-color, rgba(37, 99, 235, 0.5)); +} + +.tooltip-container .tooltip-body { + color: var(--text-primary) !important; +} + +.tooltip-container .tooltip-body * { + color: var(--text-primary) !important; +} + +/* Ensure links maintain their styling */ +.tooltip-container .tooltip-body a { + color: var(--link-color, #3b82f6) !important; + text-decoration: underline; + text-decoration-color: var(--link-underline-color, rgba(59, 130, 246, 0.3)); +} + +.tooltip-container .tooltip-body a:hover { + color: var(--link-hover-color, #2563eb) !important; + text-decoration-color: var(--link-hover-underline-color, rgba(37, 99, 235, 0.5)); +} + + +/* Tooltip Arrows */ +.tooltip-arrow { + position: absolute; + width: 0.5rem; + height: 0.5rem; + background: var(--bg-raised); + border: 0.0625rem solid var(--border-default); + transform: rotate(45deg); +} + + +.tooltip-arrow-sidebar { + top: 50%; + left: -0.25rem; + transform: translateY(-50%) rotate(45deg); + border-left: none; + border-bottom: none; +} + +.tooltip-arrow-top { + top: -0.25rem; + left: 50%; + transform: translateX(-50%) rotate(45deg); + border-top: none; + border-left: none; +} + +.tooltip-arrow-bottom { + bottom: -0.25rem; + left: 50%; + transform: translateX(-50%) rotate(45deg); + border-bottom: none; + border-right: none; +} + +.tooltip-arrow-left { + right: -0.25rem; + top: 50%; + transform: translateY(-50%) rotate(45deg); + border-left: none; + border-bottom: none; +} + +.tooltip-arrow-right { + left: -0.25rem; + top: 50%; + transform: translateY(-50%) rotate(45deg); + border-right: none; + border-top: none; +} \ No newline at end of file diff --git a/frontend/src/components/shared/tooltip/TooltipContent.tsx b/frontend/src/components/shared/tooltip/TooltipContent.tsx new file mode 100644 index 000000000..e3515e0e6 --- /dev/null +++ b/frontend/src/components/shared/tooltip/TooltipContent.tsx @@ -0,0 +1,78 @@ +import React from 'react'; +import styles from './Tooltip.module.css'; + +export interface TooltipTip { + title?: string; + description?: string; + bullets?: string[]; + body?: React.ReactNode; +} + +interface TooltipContentProps { + content?: React.ReactNode; + tips?: TooltipTip[]; +} + +export const TooltipContent: React.FC = ({ + content, + tips, +}) => { + return ( +
+
+ {tips ? ( + <> + {tips.map((tip, index) => ( +
+ {tip.title && ( +
+ {tip.title} +
+ )} + {tip.description && ( +

+ )} + {tip.bullets && tip.bullets.length > 0 && ( +

    + {tip.bullets.map((bullet, bulletIndex) => ( +
  • + ))} +
+ )} + {tip.body && ( +
+ {tip.body} +
+ )} +
+ ))} + {content && ( +
+ {content} +
+ )} + + ) : ( + content + )} +
+
+ ); +}; \ No newline at end of file diff --git a/frontend/src/components/tools/ToolLoadingFallback.tsx b/frontend/src/components/tools/ToolLoadingFallback.tsx new file mode 100644 index 000000000..8e41db433 --- /dev/null +++ b/frontend/src/components/tools/ToolLoadingFallback.tsx @@ -0,0 +1,14 @@ +import { Center, Stack, Loader, Text } from "@mantine/core"; + +export default function ToolLoadingFallback({ toolName }: { toolName?: string }) { + return ( +
+ + + + {toolName ? `Loading ${toolName}...` : "Loading tool..."} + + +
+ ) +} diff --git a/frontend/src/components/tools/ToolPanel.tsx b/frontend/src/components/tools/ToolPanel.tsx new file mode 100644 index 000000000..1551ea6c9 --- /dev/null +++ b/frontend/src/components/tools/ToolPanel.tsx @@ -0,0 +1,89 @@ +import React from 'react'; +import { TextInput } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; +import { useRainbowThemeContext } from '../shared/RainbowThemeProvider'; +import { useToolPanelState, useToolSelection, useWorkbenchState } from '../../contexts/ToolWorkflowContext'; +import ToolPicker from './ToolPicker'; +import ToolRenderer from './ToolRenderer'; +import { useSidebarContext } from "../../contexts/SidebarContext"; +import rainbowStyles from '../../styles/rainbow.module.css'; + +// No props needed - component uses context + +export default function ToolPanel() { + const { t } = useTranslation(); + const { isRainbowMode } = useRainbowThemeContext(); + const { sidebarRefs } = useSidebarContext(); + const { toolPanelRef } = sidebarRefs; + + + // Use context-based hooks to eliminate prop drilling + const { + leftPanelView, + isPanelVisible, + searchQuery, + filteredTools, + setSearchQuery, + handleBackToTools + } = useToolPanelState(); + + const { selectedToolKey, handleToolSelect } = useToolSelection(); + const { setPreviewFile } = useWorkbenchState(); + + return ( +
+
+ {/* Search Bar - Always visible at the top */} +
+ setSearchQuery(e.currentTarget.value)} + autoComplete="off" + size="sm" + /> +
+ + {leftPanelView === 'toolPicker' ? ( + // Tool Picker View +
+ +
+ ) : ( + // Selected Tool Content View +
+ {/* Tool content */} +
+ +
+
+ )} +
+
+ ); +} \ No newline at end of file diff --git a/frontend/src/components/tools/ToolPicker.tsx b/frontend/src/components/tools/ToolPicker.tsx new file mode 100644 index 000000000..d392f21b6 --- /dev/null +++ b/frontend/src/components/tools/ToolPicker.tsx @@ -0,0 +1,45 @@ +import React from "react"; +import { Box, Text, Stack, Button } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import { ToolRegistry } from "../../types/tool"; + +interface ToolPickerProps { + selectedToolKey: string | null; + onSelect: (id: string) => void; + /** Pre-filtered tools to display */ + filteredTools: [string, ToolRegistry[string]][]; +} + +const ToolPicker = ({ selectedToolKey, onSelect, filteredTools }: ToolPickerProps) => { + const { t } = useTranslation(); + + return ( + + + {filteredTools.length === 0 ? ( + + {t("toolPicker.noToolsFound", "No tools found")} + + ) : ( + filteredTools.map(([id, { icon, name }]) => ( + + )) + )} + + + ); +}; + +export default ToolPicker; diff --git a/frontend/src/components/tools/ToolRenderer.tsx b/frontend/src/components/tools/ToolRenderer.tsx new file mode 100644 index 000000000..493470935 --- /dev/null +++ b/frontend/src/components/tools/ToolRenderer.tsx @@ -0,0 +1,39 @@ +import React, { Suspense } from "react"; +import { useToolManagement } from "../../hooks/useToolManagement"; +import { BaseToolProps } from "../../types/tool"; +import ToolLoadingFallback from "./ToolLoadingFallback"; + +interface ToolRendererProps extends BaseToolProps { + selectedToolKey: string; +} + + +const ToolRenderer = ({ + selectedToolKey, + onPreviewFile, + onComplete, + onError, +}: ToolRendererProps) => { + // Get the tool from registry + const { toolRegistry } = useToolManagement(); + const selectedTool = toolRegistry[selectedToolKey]; + + if (!selectedTool || !selectedTool.component) { + return
Tool not found: {selectedToolKey}
; + } + + const ToolComponent = selectedTool.component; + + // Wrap lazy-loaded component with Suspense + return ( + }> + + + ); +}; + +export default ToolRenderer; diff --git a/frontend/src/components/tools/compress/CompressSettings.tsx b/frontend/src/components/tools/compress/CompressSettings.tsx new file mode 100644 index 000000000..717b07566 --- /dev/null +++ b/frontend/src/components/tools/compress/CompressSettings.tsx @@ -0,0 +1,161 @@ +import React, { useState } from "react"; +import { Button, Stack, Text, NumberInput, Select } from "@mantine/core"; +import { useTranslation } from "react-i18next"; + +interface CompressParameters { + compressionMethod: 'quality' | 'filesize'; + compressionLevel: number; + fileSizeValue: string; + fileSizeUnit: 'KB' | 'MB'; + grayscale: boolean; +} + +interface CompressSettingsProps { + parameters: CompressParameters; + onParameterChange: (key: keyof CompressParameters, value: any) => void; + disabled?: boolean; +} + +const CompressSettings = ({ parameters, onParameterChange, disabled = false }: CompressSettingsProps) => { + const { t } = useTranslation(); + const [isSliding, setIsSliding] = useState(false); + + return ( + + {/* Compression Method */} + + Compression Method +
+ + +
+
+ + {/* Quality Adjustment */} + {parameters.compressionMethod === 'quality' && ( + + Compression Level +
+ onParameterChange('compressionLevel', parseInt(e.target.value))} + onMouseDown={() => setIsSliding(true)} + onMouseUp={() => setIsSliding(false)} + onTouchStart={() => setIsSliding(true)} + onTouchEnd={() => setIsSliding(false)} + disabled={disabled} + style={{ + width: '100%', + height: '6px', + borderRadius: '3px', + background: `linear-gradient(to right, #228be6 0%, #228be6 ${(parameters.compressionLevel - 1) / 8 * 100}%, #e9ecef ${(parameters.compressionLevel - 1) / 8 * 100}%, #e9ecef 100%)`, + outline: 'none', + WebkitAppearance: 'none' + }} + /> + {isSliding && ( +
+ {parameters.compressionLevel} +
+ )} +
+
+ Min 1 + Max 9 +
+ + {parameters.compressionLevel <= 3 && "1-3 PDF compression"} + {parameters.compressionLevel >= 4 && parameters.compressionLevel <= 6 && "4-6 lite image compression"} + {parameters.compressionLevel >= 7 && "7-9 intense image compression Will dramatically reduce image quality"} + +
+ )} + + {/* File Size Input */} + {parameters.compressionMethod === 'filesize' && ( + + Desired File Size +
+ onParameterChange('fileSizeValue', value?.toString() || '')} + min={0} + disabled={disabled} + style={{ flex: 1 }} + /> + onParameterChange('grayscale', e.target.checked)} + disabled={disabled} + /> + {t("compress.grayscale.label", "Apply Grayscale for compression")} + + + + ); +}; + +export default CompressSettings; \ No newline at end of file diff --git a/frontend/src/components/tools/convert/ConvertFromEmailSettings.tsx b/frontend/src/components/tools/convert/ConvertFromEmailSettings.tsx new file mode 100644 index 000000000..59fa824ee --- /dev/null +++ b/frontend/src/components/tools/convert/ConvertFromEmailSettings.tsx @@ -0,0 +1,77 @@ +import React from 'react'; +import { Stack, Text, NumberInput, Checkbox } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; +import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters'; + +interface ConvertFromEmailSettingsProps { + parameters: ConvertParameters; + onParameterChange: (key: keyof ConvertParameters, value: any) => void; + disabled?: boolean; +} + +const ConvertFromEmailSettings = ({ + parameters, + onParameterChange, + disabled = false +}: ConvertFromEmailSettingsProps) => { + const { t } = useTranslation(); + + return ( + + {t("convert.emailOptions", "Email to PDF Options")}: + + onParameterChange('emailOptions', { + ...parameters.emailOptions, + includeAttachments: event.currentTarget.checked + })} + disabled={disabled} + data-testid="include-attachments-checkbox" + /> + + {parameters.emailOptions.includeAttachments && ( + + {t("convert.maxAttachmentSize", "Maximum attachment size (MB)")}: + onParameterChange('emailOptions', { + ...parameters.emailOptions, + maxAttachmentSizeMB: Number(value) || 10 + })} + min={1} + max={100} + step={1} + disabled={disabled} + data-testid="max-attachment-size-input" + /> + + )} + + onParameterChange('emailOptions', { + ...parameters.emailOptions, + includeAllRecipients: event.currentTarget.checked + })} + disabled={disabled} + data-testid="include-all-recipients-checkbox" + /> + + onParameterChange('emailOptions', { + ...parameters.emailOptions, + downloadHtml: event.currentTarget.checked + })} + disabled={disabled} + data-testid="download-html-checkbox" + /> + + ); +}; + +export default ConvertFromEmailSettings; \ No newline at end of file diff --git a/frontend/src/components/tools/convert/ConvertFromImageSettings.tsx b/frontend/src/components/tools/convert/ConvertFromImageSettings.tsx new file mode 100644 index 000000000..78d2e75a8 --- /dev/null +++ b/frontend/src/components/tools/convert/ConvertFromImageSettings.tsx @@ -0,0 +1,82 @@ +import React from "react"; +import { Stack, Text, Select, Switch } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import { COLOR_TYPES, FIT_OPTIONS } from "../../../constants/convertConstants"; +import { ConvertParameters } from "../../../hooks/tools/convert/useConvertParameters"; + +interface ConvertFromImageSettingsProps { + parameters: ConvertParameters; + onParameterChange: (key: keyof ConvertParameters, value: any) => void; + disabled?: boolean; +} + +const ConvertFromImageSettings = ({ + parameters, + onParameterChange, + disabled = false +}: ConvertFromImageSettingsProps) => { + const { t } = useTranslation(); + + return ( + + {t("convert.pdfOptions", "PDF Options")}: + val && onParameterChange('imageOptions', { + ...parameters.imageOptions, + fitOption: val as typeof FIT_OPTIONS[keyof typeof FIT_OPTIONS] + })} + data={[ + { value: FIT_OPTIONS.MAINTAIN_ASPECT, label: t("convert.maintainAspectRatio", "Maintain Aspect Ratio") }, + { value: FIT_OPTIONS.FIT_PAGE, label: t("convert.fitDocumentToPage", "Fit Document to Page") }, + { value: FIT_OPTIONS.FILL_PAGE, label: t("convert.fillPage", "Fill Page") }, + ]} + disabled={disabled} + /> + + onParameterChange('imageOptions', { + ...parameters.imageOptions, + autoRotate: event.currentTarget.checked + })} + disabled={disabled} + /> + + onParameterChange('imageOptions', { + ...parameters.imageOptions, + combineImages: event.currentTarget.checked + })} + disabled={disabled} + /> + + ); +}; + +export default ConvertFromImageSettings; \ No newline at end of file diff --git a/frontend/src/components/tools/convert/ConvertFromWebSettings.tsx b/frontend/src/components/tools/convert/ConvertFromWebSettings.tsx new file mode 100644 index 000000000..2cb8474a5 --- /dev/null +++ b/frontend/src/components/tools/convert/ConvertFromWebSettings.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import { Stack, Text, NumberInput, Slider } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; +import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters'; + +interface ConvertFromWebSettingsProps { + parameters: ConvertParameters; + onParameterChange: (key: keyof ConvertParameters, value: any) => void; + disabled?: boolean; +} + +const ConvertFromWebSettings = ({ + parameters, + onParameterChange, + disabled = false +}: ConvertFromWebSettingsProps) => { + const { t } = useTranslation(); + + return ( + + {t("convert.webOptions", "Web to PDF Options")}: + + + {t("convert.zoomLevel", "Zoom Level")}: + onParameterChange('htmlOptions', { + ...parameters.htmlOptions, + zoomLevel: Number(value) || 1.0 + })} + min={0.1} + max={3.0} + step={0.1} + precision={1} + disabled={disabled} + data-testid="zoom-level-input" + /> + onParameterChange('htmlOptions', { + ...parameters.htmlOptions, + zoomLevel: value + })} + min={0.1} + max={3.0} + step={0.1} + disabled={disabled} + data-testid="zoom-level-slider" + /> + + + ); +}; + +export default ConvertFromWebSettings; \ No newline at end of file diff --git a/frontend/src/components/tools/convert/ConvertSettings.tsx b/frontend/src/components/tools/convert/ConvertSettings.tsx new file mode 100644 index 000000000..a3051c88f --- /dev/null +++ b/frontend/src/components/tools/convert/ConvertSettings.tsx @@ -0,0 +1,318 @@ +import React, { useMemo } from "react"; +import { Stack, Text, Group, Divider, UnstyledButton, useMantineTheme, useMantineColorScheme } from "@mantine/core"; +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; +import { useTranslation } from "react-i18next"; +import { useMultipleEndpointsEnabled } from "../../../hooks/useEndpointConfig"; +import { isImageFormat, isWebFormat } from "../../../utils/convertUtils"; +import { useFileSelectionActions } from "../../../contexts/FileSelectionContext"; +import { useFileContext } from "../../../contexts/FileContext"; +import { detectFileExtension } from "../../../utils/fileUtils"; +import GroupedFormatDropdown from "./GroupedFormatDropdown"; +import ConvertToImageSettings from "./ConvertToImageSettings"; +import ConvertFromImageSettings from "./ConvertFromImageSettings"; +import ConvertFromWebSettings from "./ConvertFromWebSettings"; +import ConvertFromEmailSettings from "./ConvertFromEmailSettings"; +import ConvertToPdfaSettings from "./ConvertToPdfaSettings"; +import { ConvertParameters } from "../../../hooks/tools/convert/useConvertParameters"; +import { + FROM_FORMAT_OPTIONS, + EXTENSION_TO_ENDPOINT, + COLOR_TYPES, + OUTPUT_OPTIONS, + FIT_OPTIONS +} from "../../../constants/convertConstants"; + +interface ConvertSettingsProps { + parameters: ConvertParameters; + onParameterChange: (key: keyof ConvertParameters, value: any) => void; + getAvailableToExtensions: (fromExtension: string) => Array<{value: string, label: string, group: string}>; + selectedFiles: File[]; + disabled?: boolean; +} + +const ConvertSettings = ({ + parameters, + onParameterChange, + getAvailableToExtensions, + selectedFiles, + disabled = false +}: ConvertSettingsProps) => { + const { t } = useTranslation(); + const theme = useMantineTheme(); + const { colorScheme } = useMantineColorScheme(); + const { setSelectedFiles } = useFileSelectionActions(); + const { activeFiles, setSelectedFiles: setContextSelectedFiles } = useFileContext(); + + const allEndpoints = useMemo(() => { + const endpoints = new Set(); + Object.values(EXTENSION_TO_ENDPOINT).forEach(toEndpoints => { + Object.values(toEndpoints).forEach(endpoint => { + endpoints.add(endpoint); + }); + }); + return Array.from(endpoints); + }, []); + + const { endpointStatus } = useMultipleEndpointsEnabled(allEndpoints); + + const isConversionAvailable = (fromExt: string, toExt: string): boolean => { + const endpointKey = EXTENSION_TO_ENDPOINT[fromExt]?.[toExt]; + if (!endpointKey) return false; + + return endpointStatus[endpointKey] === true; + }; + + // Enhanced FROM options with endpoint availability + const enhancedFromOptions = useMemo(() => { + const baseOptions = FROM_FORMAT_OPTIONS.map(option => { + // Check if this source format has any available conversions + const availableConversions = getAvailableToExtensions(option.value) || []; + const hasAvailableConversions = availableConversions.some(targetOption => + isConversionAvailable(option.value, targetOption.value) + ); + + return { + ...option, + enabled: hasAvailableConversions + }; + }); + + // Add dynamic format option if current selection is a file- format + if (parameters.fromExtension && parameters.fromExtension.startsWith('file-')) { + const extension = parameters.fromExtension.replace('file-', ''); + const dynamicOption = { + value: parameters.fromExtension, + label: extension.toUpperCase(), + group: 'File', + enabled: true + }; + + // Add the dynamic option at the beginning + return [dynamicOption, ...baseOptions]; + } + + return baseOptions; + }, [getAvailableToExtensions, endpointStatus, parameters.fromExtension]); + + // Enhanced TO options with endpoint availability + const enhancedToOptions = useMemo(() => { + if (!parameters.fromExtension) return []; + + const availableOptions = getAvailableToExtensions(parameters.fromExtension) || []; + return availableOptions.map(option => ({ + ...option, + enabled: isConversionAvailable(parameters.fromExtension, option.value) + })); + }, [parameters.fromExtension, getAvailableToExtensions, endpointStatus]); + + const resetParametersToDefaults = () => { + onParameterChange('imageOptions', { + colorType: COLOR_TYPES.COLOR, + dpi: 300, + singleOrMultiple: OUTPUT_OPTIONS.MULTIPLE, + fitOption: FIT_OPTIONS.MAINTAIN_ASPECT, + autoRotate: true, + combineImages: true, + }); + onParameterChange('emailOptions', { + includeAttachments: true, + maxAttachmentSizeMB: 10, + downloadHtml: false, + includeAllRecipients: false, + }); + onParameterChange('pdfaOptions', { + outputFormat: 'pdfa-1', + }); + onParameterChange('isSmartDetection', false); + onParameterChange('smartDetectionType', 'none'); + }; + + const setAutoTargetExtension = (fromExtension: string) => { + const availableToOptions = getAvailableToExtensions(fromExtension); + const autoTarget = availableToOptions.length === 1 ? availableToOptions[0].value : ''; + onParameterChange('toExtension', autoTarget); + }; + + const filterFilesByExtension = (extension: string) => { + return activeFiles.filter(file => { + const fileExtension = detectFileExtension(file.name); + + if (extension === 'any') { + return true; + } else if (extension === 'image') { + return isImageFormat(fileExtension); + } else { + return fileExtension === extension; + } + }); + }; + + const updateFileSelection = (files: File[]) => { + setSelectedFiles(files); + const fileIds = files.map(file => (file as any).id || file.name); + setContextSelectedFiles(fileIds); + }; + + const handleFromExtensionChange = (value: string) => { + onParameterChange('fromExtension', value); + setAutoTargetExtension(value); + resetParametersToDefaults(); + + if (activeFiles.length > 0) { + const matchingFiles = filterFilesByExtension(value); + updateFileSelection(matchingFiles); + } else { + updateFileSelection([]); + } + }; + + const handleToExtensionChange = (value: string) => { + onParameterChange('toExtension', value); + onParameterChange('imageOptions', { + colorType: COLOR_TYPES.COLOR, + dpi: 300, + singleOrMultiple: OUTPUT_OPTIONS.MULTIPLE, + fitOption: FIT_OPTIONS.MAINTAIN_ASPECT, + autoRotate: true, + combineImages: true, + }); + onParameterChange('emailOptions', { + includeAttachments: true, + maxAttachmentSizeMB: 10, + downloadHtml: false, + includeAllRecipients: false, + }); + onParameterChange('pdfaOptions', { + outputFormat: 'pdfa-1', + }); + }; + + + return ( + + + {/* Format Selection */} + + + {t("convert.convertFrom", "Convert from")}: + + + + + + + {t("convert.convertTo", "Convert to")}: + + {!parameters.fromExtension ? ( + + + {t("convert.selectSourceFormatFirst", "Select a source format first")} + + + + ) : ( + + )} + + + {/* Format-specific options */} + {isImageFormat(parameters.toExtension) && ( + <> + + + + )} + + + {/* Color options for image to PDF conversion */} + {(isImageFormat(parameters.fromExtension) && parameters.toExtension === 'pdf') || + (parameters.isSmartDetection && parameters.smartDetectionType === 'images') ? ( + <> + + + + ) : null} + + {/* Web to PDF options */} + {((isWebFormat(parameters.fromExtension) && parameters.toExtension === 'pdf') || + (parameters.isSmartDetection && parameters.smartDetectionType === 'web')) ? ( + <> + + + + ) : null} + + {/* Email to PDF options */} + {parameters.fromExtension === 'eml' && parameters.toExtension === 'pdf' && ( + <> + + + + )} + + {/* PDF to PDF/A options */} + {parameters.fromExtension === 'pdf' && parameters.toExtension === 'pdfa' && ( + <> + + + + )} + + + ); +}; + +export default ConvertSettings; \ No newline at end of file diff --git a/frontend/src/components/tools/convert/ConvertToImageSettings.tsx b/frontend/src/components/tools/convert/ConvertToImageSettings.tsx new file mode 100644 index 000000000..043541672 --- /dev/null +++ b/frontend/src/components/tools/convert/ConvertToImageSettings.tsx @@ -0,0 +1,71 @@ +import React from "react"; +import { Stack, Text, Select, NumberInput, Group } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import { COLOR_TYPES, OUTPUT_OPTIONS } from "../../../constants/convertConstants"; +import { ConvertParameters } from "../../../hooks/tools/convert/useConvertParameters"; + +interface ConvertToImageSettingsProps { + parameters: ConvertParameters; + onParameterChange: (key: keyof ConvertParameters, value: any) => void; + disabled?: boolean; +} + +const ConvertToImageSettings = ({ + parameters, + onParameterChange, + disabled = false +}: ConvertToImageSettingsProps) => { + const { t } = useTranslation(); + + return ( + + {t("convert.imageOptions", "Image Options")}: + + val && onParameterChange('imageOptions', { + ...parameters.imageOptions, + singleOrMultiple: val as typeof OUTPUT_OPTIONS[keyof typeof OUTPUT_OPTIONS] + })} + data={[ + { value: OUTPUT_OPTIONS.SINGLE, label: t("convert.single", "Single") }, + { value: OUTPUT_OPTIONS.MULTIPLE, label: t("convert.multiple", "Multiple") }, + ]} + disabled={disabled} + /> + + ); +}; + +export default ConvertToImageSettings; \ No newline at end of file diff --git a/frontend/src/components/tools/convert/ConvertToPdfaSettings.tsx b/frontend/src/components/tools/convert/ConvertToPdfaSettings.tsx new file mode 100644 index 000000000..0422ee780 --- /dev/null +++ b/frontend/src/components/tools/convert/ConvertToPdfaSettings.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import { Stack, Text, Select, Alert } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; +import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters'; +import { usePdfSignatureDetection } from '../../../hooks/usePdfSignatureDetection'; + +interface ConvertToPdfaSettingsProps { + parameters: ConvertParameters; + onParameterChange: (key: keyof ConvertParameters, value: any) => void; + selectedFiles: File[]; + disabled?: boolean; +} + +const ConvertToPdfaSettings = ({ + parameters, + onParameterChange, + selectedFiles, + disabled = false +}: ConvertToPdfaSettingsProps) => { + const { t } = useTranslation(); + const { hasDigitalSignatures, isChecking } = usePdfSignatureDetection(selectedFiles); + + const pdfaFormatOptions = [ + { value: 'pdfa-1', label: 'PDF/A-1b' }, + { value: 'pdfa', label: 'PDF/A-2b' } + ]; + + return ( + + {t("convert.pdfaOptions", "PDF/A Options")}: + + {hasDigitalSignatures && ( + + + {t("convert.pdfaDigitalSignatureWarning", "The PDF contains a digital signature. This will be removed in the next step.")} + + + )} + + + {t("convert.outputFormat", "Output Format")}: + onParameterChange('ocrType', value || 'skip-text')} + data={[ + { value: 'skip-text', label: t('ocr.settings.ocrMode.auto', 'Auto (skip text layers)') }, + { value: 'force-ocr', label: t('ocr.settings.ocrMode.force', 'Force (re-OCR all, replace text)') }, + { value: 'Normal', label: t('ocr.settings.ocrMode.strict', 'Strict (abort if text found)') }, + ]} + disabled={disabled} + /> + + + + onParameterChange('languages', value)} + placeholder={t('ocr.settings.languages.placeholder', 'Select languages')} + disabled={disabled} + label={t('ocr.settings.languages.label', 'Languages')} + /> + + ); +}; + +export default OCRSettings; \ No newline at end of file diff --git a/frontend/src/components/tools/shared/ErrorNotification.tsx b/frontend/src/components/tools/shared/ErrorNotification.tsx new file mode 100644 index 000000000..a1740a1f6 --- /dev/null +++ b/frontend/src/components/tools/shared/ErrorNotification.tsx @@ -0,0 +1,35 @@ +import { Notification } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; + +export interface ErrorNotificationProps { + error: string | null; + onClose: () => void; + title?: string; + color?: string; + mb?: string; +} + +const ErrorNotification = ({ + error, + onClose, + title, + color = 'red', + mb = 'md' +}: ErrorNotificationProps) => { + const { t } = useTranslation(); + + if (!error) return null; + + return ( + + {error} + + ); +} + +export default ErrorNotification; diff --git a/frontend/src/components/tools/shared/FileStatusIndicator.tsx b/frontend/src/components/tools/shared/FileStatusIndicator.tsx new file mode 100644 index 000000000..5ff76c13c --- /dev/null +++ b/frontend/src/components/tools/shared/FileStatusIndicator.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { Text } from '@mantine/core'; + +export interface FileStatusIndicatorProps { + selectedFiles?: File[]; + isCompleted?: boolean; + placeholder?: string; + showFileName?: boolean; +} + +const FileStatusIndicator = ({ + selectedFiles = [], + isCompleted = false, + placeholder = "Select a PDF file in the main view to get started", + showFileName = true +}: FileStatusIndicatorProps) => { + if (selectedFiles.length === 0) { + return ( + + {placeholder} + + ); + } + + if (isCompleted) { + return ( + + āœ“ Selected: {showFileName ? selectedFiles[0]?.name : `${selectedFiles.length} file${selectedFiles.length > 1 ? 's' : ''}`} + + ); + } + + return ( + + Selected: {showFileName ? selectedFiles[0]?.name : `${selectedFiles.length} file${selectedFiles.length > 1 ? 's' : ''}`} + + ); +} + +export default FileStatusIndicator; \ No newline at end of file diff --git a/frontend/src/components/tools/shared/OperationButton.tsx b/frontend/src/components/tools/shared/OperationButton.tsx new file mode 100644 index 000000000..094a5b6d3 --- /dev/null +++ b/frontend/src/components/tools/shared/OperationButton.tsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { Button } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; + +export interface OperationButtonProps { + onClick?: () => void; + isLoading?: boolean; + disabled?: boolean; + loadingText?: string; + submitText?: string; + variant?: 'filled' | 'outline' | 'subtle'; + color?: string; + fullWidth?: boolean; + mt?: string; + type?: 'button' | 'submit' | 'reset'; + 'data-testid'?: string; +} + +const OperationButton = ({ + onClick, + isLoading = false, + disabled = false, + loadingText, + submitText, + variant = 'filled', + color = 'blue', + fullWidth = true, + mt = 'md', + type = 'button', + 'data-testid': dataTestId +}: OperationButtonProps) => { + const { t } = useTranslation(); + + return ( + + ); +} + +export default OperationButton; \ No newline at end of file diff --git a/frontend/src/components/tools/shared/ResultsPreview.tsx b/frontend/src/components/tools/shared/ResultsPreview.tsx new file mode 100644 index 000000000..9bddb5dc9 --- /dev/null +++ b/frontend/src/components/tools/shared/ResultsPreview.tsx @@ -0,0 +1,113 @@ +import { Grid, Paper, Box, Image, Text, Loader, Stack, Center } from '@mantine/core'; + +export interface ResultFile { + file: File; + thumbnail?: string; +} + +export interface ResultsPreviewProps { + files: ResultFile[]; + isGeneratingThumbnails?: boolean; + onFileClick?: (file: File) => void; + title?: string; + emptyMessage?: string; + loadingMessage?: string; +} + +const ResultsPreview = ({ + files, + isGeneratingThumbnails = false, + onFileClick, + title, + emptyMessage = "No files to preview", + loadingMessage = "Generating previews..." +}: ResultsPreviewProps) => { + const formatSize = (size: number) => { + if (size > 1024 * 1024) return `${(size / (1024 * 1024)).toFixed(1)} MB`; + if (size > 1024) return `${(size / 1024).toFixed(1)} KB`; + return `${size} B`; + }; + + if (files.length === 0 && !isGeneratingThumbnails) { + return ( + + {emptyMessage} + + ); + } + + return ( + + {title && ( + + {title} ({files.length} files) + + )} + + {isGeneratingThumbnails ? ( +
+ + + {loadingMessage} + +
+ ) : ( + + {files.map((result, index) => ( + + onFileClick?.(result.file)} + data-testid={`results-preview-thumbnail-${index}`} + style={{ + textAlign: 'center', + height: '10rem', + width:'5rem', + display: 'flex', + flexDirection: 'column', + cursor: onFileClick ? 'pointer' : 'default', + transition: 'all 0.2s ease' + }} + > + + {result.thumbnail ? ( + {`Preview + ) : ( + No preview + )} + + + {result.file.name} + + + {formatSize(result.file.size)} + + + + ))} + + )} +
+ ); +} + +export default ResultsPreview; diff --git a/frontend/src/components/tools/shared/ToolStep.tsx b/frontend/src/components/tools/shared/ToolStep.tsx new file mode 100644 index 000000000..5ae6aec9b --- /dev/null +++ b/frontend/src/components/tools/shared/ToolStep.tsx @@ -0,0 +1,194 @@ +import React, { createContext, useContext, useMemo, useRef } from 'react'; +import { Paper, Text, Stack, Box, Flex } from '@mantine/core'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import ChevronRightIcon from '@mui/icons-material/ChevronRight'; +import { Tooltip } from '../../shared/Tooltip'; +import { TooltipTip } from '../../shared/tooltip/TooltipContent'; + +interface ToolStepContextType { + visibleStepCount: number; + getStepNumber: () => number; +} + +const ToolStepContext = createContext(null); + +export interface ToolStepProps { + title: string; + isVisible?: boolean; + isCollapsed?: boolean; + isCompleted?: boolean; + onCollapsedClick?: () => void; + children?: React.ReactNode; + completedMessage?: string; + helpText?: string; + showNumber?: boolean; + tooltip?: { + content?: React.ReactNode; + tips?: TooltipTip[]; + header?: { + title: string; + logo?: React.ReactNode; + }; + }; +} + +const renderTooltipTitle = ( + title: string, + tooltip: ToolStepProps['tooltip'], + isCollapsed: boolean +) => { + if (tooltip && !isCollapsed) { + return ( + + e.stopPropagation()}> + + {title} + + + gpp_maybe + + + + ); + } + + return ( + + {title} + + ); +}; + +const ToolStep = ({ + title, + isVisible = true, + isCollapsed = false, + isCompleted = false, + onCollapsedClick, + children, + completedMessage, + helpText, + showNumber, + tooltip +}: ToolStepProps) => { + if (!isVisible) return null; + + const parent = useContext(ToolStepContext); + + // Auto-detect if we should show numbers based on sibling count + const shouldShowNumber = useMemo(() => { + if (showNumber !== undefined) return showNumber; + return parent ? parent.visibleStepCount >= 3 : false; + }, [showNumber, parent]); + + const stepNumber = parent?.getStepNumber?.() || 1; + + return ( + + {/* Chevron icon to collapse/expand the step */} + + + {shouldShowNumber && ( + + {stepNumber} + + )} + {renderTooltipTitle(title, tooltip, isCollapsed)} + + + {isCollapsed ? ( + + ) : ( + + )} + + + {isCollapsed ? ( + + {isCompleted && completedMessage && ( + + āœ“ {completedMessage} + {onCollapsedClick && ( + + (click to change) + + )} + + )} + + ) : ( + + {helpText && ( + + {helpText} + + )} + {children} + + )} + + ); +} + +export interface ToolStepContainerProps { + children: React.ReactNode; +} + +export const ToolStepContainer = ({ children }: ToolStepContainerProps) => { + const stepCounterRef = useRef(0); + + // Count visible ToolStep children + const visibleStepCount = useMemo(() => { + let count = 0; + React.Children.forEach(children, (child) => { + if (React.isValidElement(child) && child.type === ToolStep) { + const isVisible = (child.props as ToolStepProps).isVisible !== false; + if (isVisible) count++; + } + }); + return count; + }, [children]); + + const contextValue = useMemo(() => ({ + visibleStepCount, + getStepNumber: () => ++stepCounterRef.current + }), [visibleStepCount]); + + stepCounterRef.current = 0; + + return ( + + {children} + + ); +} + +export default ToolStep; diff --git a/frontend/src/components/tools/split/SplitSettings.tsx b/frontend/src/components/tools/split/SplitSettings.tsx new file mode 100644 index 000000000..95e972eaf --- /dev/null +++ b/frontend/src/components/tools/split/SplitSettings.tsx @@ -0,0 +1,145 @@ +import { Stack, TextInput, Select, Checkbox } from '@mantine/core'; +import { useTranslation } from 'react-i18next'; +import { SPLIT_MODES, SPLIT_TYPES, type SplitMode, type SplitType } from '../../../constants/splitConstants'; + +export interface SplitParameters { + mode: SplitMode | ''; + pages: string; + hDiv: string; + vDiv: string; + merge: boolean; + splitType: SplitType | ''; + splitValue: string; + bookmarkLevel: string; + includeMetadata: boolean; + allowDuplicates: boolean; +} + +export interface SplitSettingsProps { + parameters: SplitParameters; + onParameterChange: (parameter: keyof SplitParameters, value: string | boolean) => void; + disabled?: boolean; +} + +const SplitSettings = ({ + parameters, + onParameterChange, + disabled = false +}: SplitSettingsProps) => { + const { t } = useTranslation(); + + const renderByPagesForm = () => ( + onParameterChange('pages', e.target.value)} + disabled={disabled} + /> + ); + + const renderBySectionsForm = () => ( + + onParameterChange('hDiv', e.target.value)} + placeholder={t("split-by-sections.horizontal.placeholder", "Enter number of horizontal divisions")} + disabled={disabled} + /> + onParameterChange('vDiv', e.target.value)} + placeholder={t("split-by-sections.vertical.placeholder", "Enter number of vertical divisions")} + disabled={disabled} + /> + onParameterChange('merge', e.currentTarget.checked)} + disabled={disabled} + /> + + ); + + const renderBySizeOrCountForm = () => ( + + v && onParameterChange('mode', v)} + disabled={disabled} + data={[ + { value: SPLIT_MODES.BY_PAGES, label: t("split.header", "Split by Pages") + " (e.g. 1,3,5-10)" }, + { value: SPLIT_MODES.BY_SECTIONS, label: t("split-by-sections.title", "Split by Grid Sections") }, + { value: SPLIT_MODES.BY_SIZE_OR_COUNT, label: t("split-by-size-or-count.title", "Split by Size or Count") }, + { value: SPLIT_MODES.BY_CHAPTERS, label: t("splitByChapters.title", "Split by Chapters") }, + ]} + /> + + {/* Parameter Form */} + {parameters.mode === SPLIT_MODES.BY_PAGES && renderByPagesForm()} + {parameters.mode === SPLIT_MODES.BY_SECTIONS && renderBySectionsForm()} + {parameters.mode === SPLIT_MODES.BY_SIZE_OR_COUNT && renderBySizeOrCountForm()} + {parameters.mode === SPLIT_MODES.BY_CHAPTERS && renderByChaptersForm()} + + ); +} + +export default SplitSettings; diff --git a/frontend/src/components/tooltips/CompressTips.ts b/frontend/src/components/tooltips/CompressTips.ts new file mode 100644 index 000000000..2fb2a0777 --- /dev/null +++ b/frontend/src/components/tooltips/CompressTips.ts @@ -0,0 +1,30 @@ +import { useTranslation } from 'react-i18next'; +import { TooltipContent } from '../../types/tips'; + +export const CompressTips = (): TooltipContent => { + const { t } = useTranslation(); + + return { + header: { + title: t("compress.tooltip.header.title", "Compress Settings Overview") + }, + tips: [ + { + title: t("compress.tooltip.description.title", "Description"), + description: t("compress.tooltip.description.text", "Compression is an easy way to reduce your file size. Pick File Size to enter a target size and have us adjust quality for you. Pick Quality to set compression strength manually.") + }, + { + title: t("compress.tooltip.qualityAdjustment.title", "Quality Adjustment"), + description: t("compress.tooltip.qualityAdjustment.text", "Drag the slider to adjust the compression strength. Lower values (1-3) preserve quality but result in larger files. Higher values (7-9) shrink the file more but reduce image clarity."), + bullets: [ + t("compress.tooltip.qualityAdjustment.bullet1", "Lower values preserve quality"), + t("compress.tooltip.qualityAdjustment.bullet2", "Higher values reduce file size") + ] + }, + { + title: t("compress.tooltip.grayscale.title", "Grayscale"), + description: t("compress.tooltip.grayscale.text", "Select this option to convert all images to black and white, which can significantly reduce file size especially for scanned PDFs or image-heavy documents.") + } + ] + }; +}; \ No newline at end of file diff --git a/frontend/src/components/tooltips/OCRTips.ts b/frontend/src/components/tooltips/OCRTips.ts new file mode 100644 index 000000000..1002182f2 --- /dev/null +++ b/frontend/src/components/tooltips/OCRTips.ts @@ -0,0 +1,36 @@ +import { useTranslation } from 'react-i18next'; +import { TooltipContent } from '../../types/tips'; + +export const OcrTips = (): TooltipContent => { + const { t } = useTranslation(); + + return { + header: { + title: t("ocr.tooltip.header.title", "OCR Settings Overview"), + }, + tips: [ + { + title: t("ocr.tooltip.mode.title", "OCR Mode"), + description: t("ocr.tooltip.mode.text", "Optical Character Recognition (OCR) helps you turn scanned or screenshotted pages into text you can search, copy, or highlight."), + bullets: [ + t("ocr.tooltip.mode.bullet1", "Auto skips pages that already contain text layers."), + t("ocr.tooltip.mode.bullet2", "Force re-OCRs every page and replaces all the text."), + t("ocr.tooltip.mode.bullet3", "Strict halts if any selectable text is found.") + ] + }, + { + title: t("ocr.tooltip.languages.title", "Languages"), + description: t("ocr.tooltip.languages.text", "Improve OCR accuracy by specifying the expected languages. Choose one or more languages to guide detection.") + }, + { + title: t("ocr.tooltip.output.title", "Output"), + description: t("ocr.tooltip.output.text", "Decide how you want the text output formatted:"), + bullets: [ + t("ocr.tooltip.output.bullet1", "Searchable PDF embeds text behind the original image."), + t("ocr.tooltip.output.bullet2", "HOCR XML returns a structured machine-readable file."), + t("ocr.tooltip.output.bullet3", "Plain-text sidecar creates a separate .txt file with raw content.") + ] + } + ] + }; +}; \ No newline at end of file diff --git a/frontend/src/components/viewer/Viewer.tsx b/frontend/src/components/viewer/Viewer.tsx new file mode 100644 index 000000000..065ce5824 --- /dev/null +++ b/frontend/src/components/viewer/Viewer.tsx @@ -0,0 +1,682 @@ +import React, { useEffect, useState, useRef, useCallback } from "react"; +import { Paper, Stack, Text, ScrollArea, Loader, Center, Button, Group, NumberInput, useMantineTheme, ActionIcon, Box, Tabs } from "@mantine/core"; +import { getDocument, GlobalWorkerOptions } from "pdfjs-dist"; +import { useTranslation } from "react-i18next"; +import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew"; +import ArrowForwardIosIcon from "@mui/icons-material/ArrowForwardIos"; +import FirstPageIcon from "@mui/icons-material/FirstPage"; +import LastPageIcon from "@mui/icons-material/LastPage"; +import ViewSidebarIcon from "@mui/icons-material/ViewSidebar"; +import ViewWeekIcon from "@mui/icons-material/ViewWeek"; // for dual page (book) +import DescriptionIcon from "@mui/icons-material/Description"; // for single page +import CloseIcon from "@mui/icons-material/Close"; +import { useLocalStorage } from "@mantine/hooks"; +import { fileStorage } from "../../services/fileStorage"; +import SkeletonLoader from '../shared/SkeletonLoader'; +import { useFileContext } from "../../contexts/FileContext"; +import { useFileWithUrl } from "../../hooks/useFileWithUrl"; + +GlobalWorkerOptions.workerSrc = "/pdf.worker.js"; + +// Lazy loading page image component +interface LazyPageImageProps { + pageIndex: number; + zoom: number; + theme: any; + isFirst: boolean; + renderPage: (pageIndex: number) => Promise; + pageImages: (string | null)[]; + setPageRef: (index: number, ref: HTMLImageElement | null) => void; +} + +const LazyPageImage = ({ + pageIndex, zoom, theme, isFirst, renderPage, pageImages, setPageRef +}: LazyPageImageProps) => { + const [isVisible, setIsVisible] = useState(false); + const [imageUrl, setImageUrl] = useState(null); + const imgRef = useRef(null); + + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting && !imageUrl) { + setIsVisible(true); + } + }); + }, + { + rootMargin: '200px', // Start loading 200px before visible + threshold: 0.1 + } + ); + + if (imgRef.current) { + observer.observe(imgRef.current); + } + + return () => observer.disconnect(); + }, [imageUrl]); + + // Update local state when pageImages changes (from preloading) + useEffect(() => { + if (pageImages[pageIndex]) { + setImageUrl(pageImages[pageIndex]); + } + }, [pageImages, pageIndex]); + + useEffect(() => { + if (isVisible && !imageUrl) { + renderPage(pageIndex).then((url) => { + if (url) setImageUrl(url); + }); + } + }, [isVisible, imageUrl, pageIndex, renderPage]); + + useEffect(() => { + if (imgRef.current) { + setPageRef(pageIndex, imgRef.current); + } + }, [pageIndex, setPageRef]); + + if (imageUrl) { + return ( + {`Page + ); + } + + // Placeholder while loading + return ( +
+ {isVisible ? ( +
+
+ Loading page {pageIndex + 1}... +
+ ) : ( + Page {pageIndex + 1} + )} +
+ ); +}; + +export interface ViewerProps { + sidebarsVisible: boolean; + setSidebarsVisible: (v: boolean) => void; + onClose?: () => void; + previewFile?: File; // For preview mode - bypasses context +} + +const Viewer = ({ + sidebarsVisible, + setSidebarsVisible, + onClose, + previewFile, +}: ViewerProps) => { + const { t } = useTranslation(); + const theme = useMantineTheme(); + + // Get current file from FileContext + const { getCurrentFile, getCurrentProcessedFile, clearAllFiles, addFiles, activeFiles } = useFileContext(); + const currentFile = getCurrentFile(); + const processedFile = getCurrentProcessedFile(); + + // Convert File to FileWithUrl format for viewer + const pdfFile = useFileWithUrl(currentFile); + + // Tab management for multiple files + const [activeTab, setActiveTab] = useState("0"); + + // Reset PDF state when switching tabs + const handleTabChange = (newTab: string) => { + setActiveTab(newTab); + setNumPages(0); + setPageImages([]); + setCurrentPage(null); + setLoading(true); + }; + const [numPages, setNumPages] = useState(0); + const [pageImages, setPageImages] = useState([]); + const [loading, setLoading] = useState(false); + const [currentPage, setCurrentPage] = useState(null); + const [dualPage, setDualPage] = useState(false); + const [zoom, setZoom] = useState(1); // 1 = 100% + const pageRefs = useRef<(HTMLImageElement | null)[]>([]); + + + // Get files with URLs for tabs - we'll need to create these individually + const file0WithUrl = useFileWithUrl(activeFiles[0]); + const file1WithUrl = useFileWithUrl(activeFiles[1]); + const file2WithUrl = useFileWithUrl(activeFiles[2]); + const file3WithUrl = useFileWithUrl(activeFiles[3]); + const file4WithUrl = useFileWithUrl(activeFiles[4]); + + const filesWithUrls = React.useMemo(() => { + return [file0WithUrl, file1WithUrl, file2WithUrl, file3WithUrl, file4WithUrl] + .slice(0, activeFiles.length) + .filter(Boolean); + }, [file0WithUrl, file1WithUrl, file2WithUrl, file3WithUrl, file4WithUrl, activeFiles.length]); + + // Use preview file if available, otherwise use active tab file + const effectiveFile = React.useMemo(() => { + if (previewFile) { + // Validate the preview file + if (!(previewFile instanceof File)) { + return null; + } + + if (previewFile.size === 0) { + return null; + } + + return { file: previewFile, url: null }; + } else { + // Use the file from the active tab + const tabIndex = parseInt(activeTab); + return filesWithUrls[tabIndex] || null; + } + }, [previewFile, filesWithUrls, activeTab]); + + const scrollAreaRef = useRef(null); + const pdfDocRef = useRef(null); + const renderingPagesRef = useRef>(new Set()); + const currentArrayBufferRef = useRef(null); + const preloadingRef = useRef(false); + + // Function to render a specific page on-demand + const renderPage = async (pageIndex: number): Promise => { + if (!pdfDocRef.current || renderingPagesRef.current.has(pageIndex)) { + return null; + } + + const pageNum = pageIndex + 1; + if (pageImages[pageIndex]) { + return pageImages[pageIndex]; // Already rendered + } + + renderingPagesRef.current.add(pageIndex); + + try { + const page = await pdfDocRef.current.getPage(pageNum); + const viewport = page.getViewport({ scale: 1.2 }); + const canvas = document.createElement("canvas"); + canvas.width = viewport.width; + canvas.height = viewport.height; + const ctx = canvas.getContext("2d"); + + if (ctx) { + await page.render({ canvasContext: ctx, viewport }).promise; + const dataUrl = canvas.toDataURL(); + + // Update the pageImages array + setPageImages(prev => { + const newImages = [...prev]; + newImages[pageIndex] = dataUrl; + return newImages; + }); + + renderingPagesRef.current.delete(pageIndex); + return dataUrl; + } + } catch (error) { + console.error(`Failed to render page ${pageNum}:`, error); + } + + renderingPagesRef.current.delete(pageIndex); + return null; + }; + + // Progressive preloading function + const startProgressivePreload = async () => { + if (!pdfDocRef.current || preloadingRef.current || numPages === 0) return; + + preloadingRef.current = true; + + // Start with first few pages for immediate viewing + const priorityPages = [0, 1, 2, 3, 4]; // First 5 pages + + // Render priority pages first + for (const pageIndex of priorityPages) { + if (pageIndex < numPages && !pageImages[pageIndex]) { + await renderPage(pageIndex); + // Small delay to allow UI to update + await new Promise(resolve => setTimeout(resolve, 50)); + } + } + + // Then render remaining pages in background + for (let pageIndex = 5; pageIndex < numPages; pageIndex++) { + if (!pageImages[pageIndex]) { + await renderPage(pageIndex); + // Longer delay for background loading to not block UI + await new Promise(resolve => setTimeout(resolve, 100)); + } + } + + preloadingRef.current = false; + }; + + // Initialize current page when PDF loads + useEffect(() => { + if (numPages > 0 && !currentPage) { + setCurrentPage(1); + } + }, [numPages, currentPage]); + + // Function to scroll to a specific page + const scrollToPage = (pageNumber: number) => { + const el = pageRefs.current[pageNumber - 1]; + const scrollArea = scrollAreaRef.current; + + if (el && scrollArea) { + const scrollAreaRect = scrollArea.getBoundingClientRect(); + const elRect = el.getBoundingClientRect(); + const currentScrollTop = scrollArea.scrollTop; + + // Position page near top of viewport with some padding + const targetScrollTop = currentScrollTop + (elRect.top - scrollAreaRect.top) - 20; + + scrollArea.scrollTo({ + top: targetScrollTop, + behavior: "smooth" + }); + } + }; + + // Throttled scroll handler to prevent jerky updates + const handleScrollThrottled = useCallback(() => { + const scrollArea = scrollAreaRef.current; + if (!scrollArea || !pageRefs.current.length) return; + + const areaRect = scrollArea.getBoundingClientRect(); + const viewportCenter = areaRect.top + areaRect.height / 2; + let closestIdx = 0; + let minDist = Infinity; + + pageRefs.current.forEach((img, idx) => { + if (img) { + const imgRect = img.getBoundingClientRect(); + const imgCenter = imgRect.top + imgRect.height / 2; + const dist = Math.abs(imgCenter - viewportCenter); + if (dist < minDist) { + minDist = dist; + closestIdx = idx; + } + } + }); + + // Update page number display only if changed + if (currentPage !== closestIdx + 1) { + setCurrentPage(closestIdx + 1); + } + }, [currentPage]); + + // Throttle scroll events to reduce jerkiness + const handleScroll = useCallback(() => { + if (window.requestAnimationFrame) { + window.requestAnimationFrame(handleScrollThrottled); + } else { + handleScrollThrottled(); + } + }, [handleScrollThrottled]); + + useEffect(() => { + let cancelled = false; + async function loadPdfInfo() { + if (!effectiveFile) { + setNumPages(0); + setPageImages([]); + return; + } + setLoading(true); + try { + let pdfData; + + // For preview files, use ArrayBuffer directly to avoid blob URL issues + if (previewFile && effectiveFile.file === previewFile) { + const arrayBuffer = await previewFile.arrayBuffer(); + pdfData = { data: arrayBuffer }; + } + // Handle special IndexedDB URLs for large files + else if (effectiveFile.url?.startsWith('indexeddb:')) { + const fileId = effectiveFile.url.replace('indexeddb:', ''); + + // Get data directly from IndexedDB + const arrayBuffer = await fileStorage.getFileData(fileId); + if (!arrayBuffer) { + throw new Error('File not found in IndexedDB - may have been purged by browser'); + } + + // Store reference for cleanup + currentArrayBufferRef.current = arrayBuffer; + pdfData = { data: arrayBuffer }; + } else if (effectiveFile.url) { + // Standard blob URL or regular URL + pdfData = effectiveFile.url; + } else { + throw new Error('No valid PDF source available'); + } + + const pdf = await getDocument(pdfData).promise; + pdfDocRef.current = pdf; + setNumPages(pdf.numPages); + if (!cancelled) { + setPageImages(new Array(pdf.numPages).fill(null)); + // Start progressive preloading after a short delay + setTimeout(() => startProgressivePreload(), 100); + } + } catch (error) { + if (!cancelled) { + setPageImages([]); + setNumPages(0); + } + } + if (!cancelled) setLoading(false); + } + loadPdfInfo(); + return () => { + cancelled = true; + // Stop any ongoing preloading + preloadingRef.current = false; + // Cleanup ArrayBuffer reference to help garbage collection + currentArrayBufferRef.current = null; + }; + }, [effectiveFile, previewFile]); + + useEffect(() => { + const viewport = scrollAreaRef.current; + if (!viewport) return; + const handler = () => { + handleScroll(); + }; + viewport.addEventListener("scroll", handler); + return () => viewport.removeEventListener("scroll", handler); + }, [pageImages]); + + return ( + + {/* Close Button - Only show in preview mode */} + {onClose && previewFile && ( + + + + )} + + {!effectiveFile ? ( +
+ Error: No file provided to viewer +
+ ) : ( + <> + {/* Tabs for multiple files */} + {activeFiles.length > 1 && !previewFile && ( + + handleTabChange(value || "0")}> + + {activeFiles.map((file, index) => ( + + {file.name.length > 20 ? `${file.name.substring(0, 20)}...` : file.name} + + ))} + + + + )} + + {loading ? ( +
+ +
+ ) : ( + + + {numPages === 0 && ( + {t("viewer.noPagesToDisplay", "No pages to display.")} + )} + {dualPage + ? Array.from({ length: Math.ceil(numPages / 2) }).map((_, i) => ( + + { pageRefs.current[index] = ref; }} + /> + {i * 2 + 1 < numPages && ( + { pageRefs.current[index] = ref; }} + /> + )} + + )) + : Array.from({ length: numPages }).map((_, idx) => ( + { pageRefs.current[index] = ref; }} + /> + ))} + + {/* Navigation bar overlays the scroll area */} +
+ + + + { + const page = Number(value); + if (!isNaN(page) && page >= 1 && page <= numPages) { + scrollToPage(page); + } + }} + min={1} + max={numPages} + hideControls + styles={{ + input: { width: 48, textAlign: "center", fontWeight: 500, fontSize: 16}, + }} + /> + + / {numPages} + + + + + + + {Math.round(zoom * 100)}% + + + +
+
+ )} + + )} + +
+ ); +}; + +export default Viewer; diff --git a/frontend/src/constants/convertConstants.ts b/frontend/src/constants/convertConstants.ts new file mode 100644 index 000000000..f371c7081 --- /dev/null +++ b/frontend/src/constants/convertConstants.ts @@ -0,0 +1,149 @@ + +export const COLOR_TYPES = { + COLOR: 'color', + GREYSCALE: 'greyscale', + BLACK_WHITE: 'blackwhite' +} as const; + +export const OUTPUT_OPTIONS = { + SINGLE: 'single', + MULTIPLE: 'multiple' +} as const; + +export const FIT_OPTIONS = { + FIT_PAGE: 'fitDocumentToPage', + MAINTAIN_ASPECT: 'maintainAspectRatio', + FILL_PAGE: 'fillPage' +} as const; + + +export const CONVERSION_ENDPOINTS = { + 'office-pdf': '/api/v1/convert/file/pdf', + 'pdf-image': '/api/v1/convert/pdf/img', + 'image-pdf': '/api/v1/convert/img/pdf', + 'pdf-office-word': '/api/v1/convert/pdf/word', + 'pdf-office-presentation': '/api/v1/convert/pdf/presentation', + 'pdf-office-text': '/api/v1/convert/pdf/text', + 'pdf-csv': '/api/v1/convert/pdf/csv', + 'pdf-markdown': '/api/v1/convert/pdf/markdown', + 'pdf-html': '/api/v1/convert/pdf/html', + 'pdf-xml': '/api/v1/convert/pdf/xml', + 'pdf-pdfa': '/api/v1/convert/pdf/pdfa', + 'html-pdf': '/api/v1/convert/html/pdf', + 'markdown-pdf': '/api/v1/convert/markdown/pdf', + 'eml-pdf': '/api/v1/convert/eml/pdf' +} as const; + +export const ENDPOINT_NAMES = { + 'office-pdf': 'file-to-pdf', + 'pdf-image': 'pdf-to-img', + 'image-pdf': 'img-to-pdf', + 'pdf-office-word': 'pdf-to-word', + 'pdf-office-presentation': 'pdf-to-presentation', + 'pdf-office-text': 'pdf-to-text', + 'pdf-csv': 'pdf-to-csv', + 'pdf-markdown': 'pdf-to-markdown', + 'pdf-html': 'pdf-to-html', + 'pdf-xml': 'pdf-to-xml', + 'pdf-pdfa': 'pdf-to-pdfa', + 'html-pdf': 'html-to-pdf', + 'markdown-pdf': 'markdown-to-pdf', + 'eml-pdf': 'eml-to-pdf' +} as const; + + +// Grouped file extensions for dropdowns +export const FROM_FORMAT_OPTIONS = [ + { value: 'any', label: 'Any', group: 'Multiple Files' }, + { value: 'image', label: 'Images', group: 'Multiple Files' }, + { value: 'pdf', label: 'PDF', group: 'Document' }, + { value: 'docx', label: 'DOCX', group: 'Document' }, + { value: 'doc', label: 'DOC', group: 'Document' }, + { value: 'odt', label: 'ODT', group: 'Document' }, + { value: 'xlsx', label: 'XLSX', group: 'Spreadsheet' }, + { value: 'xls', label: 'XLS', group: 'Spreadsheet' }, + { value: 'ods', label: 'ODS', group: 'Spreadsheet' }, + { value: 'pptx', label: 'PPTX', group: 'Presentation' }, + { value: 'ppt', label: 'PPT', group: 'Presentation' }, + { value: 'odp', label: 'ODP', group: 'Presentation' }, + { value: 'jpg', label: 'JPG', group: 'Image' }, + { value: 'jpeg', label: 'JPEG', group: 'Image' }, + { value: 'png', label: 'PNG', group: 'Image' }, + { value: 'gif', label: 'GIF', group: 'Image' }, + { value: 'bmp', label: 'BMP', group: 'Image' }, + { value: 'tiff', label: 'TIFF', group: 'Image' }, + { value: 'webp', label: 'WEBP', group: 'Image' }, + { value: 'svg', label: 'SVG', group: 'Image' }, + { value: 'html', label: 'HTML', group: 'Web' }, + { value: 'zip', label: 'ZIP', group: 'Web' }, + { value: 'md', label: 'MD', group: 'Text' }, + { value: 'txt', label: 'TXT', group: 'Text' }, + { value: 'rtf', label: 'RTF', group: 'Text' }, + { value: 'eml', label: 'EML', group: 'Email' }, +]; + +export const TO_FORMAT_OPTIONS = [ + { value: 'pdf', label: 'PDF', group: 'Document' }, + { value: 'pdfa', label: 'PDF/A', group: 'Document' }, + { value: 'docx', label: 'DOCX', group: 'Document' }, + { value: 'odt', label: 'ODT', group: 'Document' }, + { value: 'csv', label: 'CSV', group: 'Spreadsheet' }, + { value: 'pptx', label: 'PPTX', group: 'Presentation' }, + { value: 'odp', label: 'ODP', group: 'Presentation' }, + { value: 'txt', label: 'TXT', group: 'Text' }, + { value: 'rtf', label: 'RTF', group: 'Text' }, + { value: 'md', label: 'MD', group: 'Text' }, + { value: 'png', label: 'PNG', group: 'Image' }, + { value: 'jpg', label: 'JPG', group: 'Image' }, + { value: 'gif', label: 'GIF', group: 'Image' }, + { value: 'tiff', label: 'TIFF', group: 'Image' }, + { value: 'bmp', label: 'BMP', group: 'Image' }, + { value: 'webp', label: 'WEBP', group: 'Image' }, + { value: 'html', label: 'HTML', group: 'Web' }, + { value: 'xml', label: 'XML', group: 'Web' }, +]; + +// Conversion matrix - what each source format can convert to +export const CONVERSION_MATRIX: Record = { + 'any': ['pdf'], // Mixed files always convert to PDF + 'image': ['pdf'], // Multiple images always convert to PDF + 'pdf': ['png', 'jpg', 'gif', 'tiff', 'bmp', 'webp', 'docx', 'odt', 'pptx', 'odp', 'csv', 'txt', 'rtf', 'md', 'html', 'xml', 'pdfa'], + 'docx': ['pdf'], 'doc': ['pdf'], 'odt': ['pdf'], + 'xlsx': ['pdf'], 'xls': ['pdf'], 'ods': ['pdf'], + 'pptx': ['pdf'], 'ppt': ['pdf'], 'odp': ['pdf'], + 'jpg': ['pdf'], 'jpeg': ['pdf'], 'png': ['pdf'], 'gif': ['pdf'], 'bmp': ['pdf'], 'tiff': ['pdf'], 'webp': ['pdf'], 'svg': ['pdf'], + 'html': ['pdf'], + 'zip': ['pdf'], + 'md': ['pdf'], + 'txt': ['pdf'], 'rtf': ['pdf'], + 'eml': ['pdf'] +}; + +// Map extensions to endpoint keys +export const EXTENSION_TO_ENDPOINT: Record> = { + 'any': { 'pdf': 'file-to-pdf' }, // Mixed files use file-to-pdf endpoint + 'image': { 'pdf': 'img-to-pdf' }, // Multiple images use img-to-pdf endpoint + 'pdf': { + 'png': 'pdf-to-img', 'jpg': 'pdf-to-img', 'gif': 'pdf-to-img', 'tiff': 'pdf-to-img', 'bmp': 'pdf-to-img', 'webp': 'pdf-to-img', + 'docx': 'pdf-to-word', 'odt': 'pdf-to-word', + 'pptx': 'pdf-to-presentation', 'odp': 'pdf-to-presentation', + 'csv': 'pdf-to-csv', + 'txt': 'pdf-to-text', 'rtf': 'pdf-to-text', 'md': 'pdf-to-markdown', + 'html': 'pdf-to-html', 'xml': 'pdf-to-xml', + 'pdfa': 'pdf-to-pdfa' + }, + 'docx': { 'pdf': 'file-to-pdf' }, 'doc': { 'pdf': 'file-to-pdf' }, 'odt': { 'pdf': 'file-to-pdf' }, + 'xlsx': { 'pdf': 'file-to-pdf' }, 'xls': { 'pdf': 'file-to-pdf' }, 'ods': { 'pdf': 'file-to-pdf' }, + 'pptx': { 'pdf': 'file-to-pdf' }, 'ppt': { 'pdf': 'file-to-pdf' }, 'odp': { 'pdf': 'file-to-pdf' }, + 'jpg': { 'pdf': 'img-to-pdf' }, 'jpeg': { 'pdf': 'img-to-pdf' }, 'png': { 'pdf': 'img-to-pdf' }, + 'gif': { 'pdf': 'img-to-pdf' }, 'bmp': { 'pdf': 'img-to-pdf' }, 'tiff': { 'pdf': 'img-to-pdf' }, 'webp': { 'pdf': 'img-to-pdf' }, 'svg': { 'pdf': 'img-to-pdf' }, + 'html': { 'pdf': 'html-to-pdf' }, + 'zip': { 'pdf': 'html-to-pdf' }, + 'md': { 'pdf': 'markdown-to-pdf' }, + 'txt': { 'pdf': 'file-to-pdf' }, 'rtf': { 'pdf': 'file-to-pdf' }, + 'eml': { 'pdf': 'eml-to-pdf' } +}; + +export type ColorType = typeof COLOR_TYPES[keyof typeof COLOR_TYPES]; +export type OutputOption = typeof OUTPUT_OPTIONS[keyof typeof OUTPUT_OPTIONS]; +export type FitOption = typeof FIT_OPTIONS[keyof typeof FIT_OPTIONS]; \ No newline at end of file diff --git a/frontend/src/constants/splitConstants.ts b/frontend/src/constants/splitConstants.ts new file mode 100644 index 000000000..0da43ac57 --- /dev/null +++ b/frontend/src/constants/splitConstants.ts @@ -0,0 +1,22 @@ +export const SPLIT_MODES = { + BY_PAGES: 'byPages', + BY_SECTIONS: 'bySections', + BY_SIZE_OR_COUNT: 'bySizeOrCount', + BY_CHAPTERS: 'byChapters' +} as const; + +export const SPLIT_TYPES = { + SIZE: 'size', + PAGES: 'pages', + DOCS: 'docs' +} as const; + +export const ENDPOINTS = { + [SPLIT_MODES.BY_PAGES]: 'split-pages', + [SPLIT_MODES.BY_SECTIONS]: 'split-pdf-by-sections', + [SPLIT_MODES.BY_SIZE_OR_COUNT]: 'split-by-size-or-count', + [SPLIT_MODES.BY_CHAPTERS]: 'split-pdf-by-chapters' +} as const; + +export type SplitMode = typeof SPLIT_MODES[keyof typeof SPLIT_MODES]; +export type SplitType = typeof SPLIT_TYPES[keyof typeof SPLIT_TYPES]; \ No newline at end of file diff --git a/frontend/src/contexts/FileContext.tsx b/frontend/src/contexts/FileContext.tsx new file mode 100644 index 000000000..f84d2ec8b --- /dev/null +++ b/frontend/src/contexts/FileContext.tsx @@ -0,0 +1,878 @@ +/** + * Global file context for managing files, edits, and navigation across all views and tools + */ + +import React, { createContext, useContext, useReducer, useCallback, useEffect, useRef } from 'react'; +import { + FileContextValue, + FileContextState, + FileContextProviderProps, + ModeType, + ViewType, + ToolType, + FileOperation, + FileEditHistory, + FileOperationHistory, + ViewerConfig, + FileContextUrlParams +} from '../types/fileContext'; +import { ProcessedFile } from '../types/processing'; +import { PageOperation, PDFDocument } from '../types/pageEditor'; +import { useEnhancedProcessedFiles } from '../hooks/useEnhancedProcessedFiles'; +import { fileStorage } from '../services/fileStorage'; +import { enhancedPDFProcessingService } from '../services/enhancedPDFProcessingService'; +import { thumbnailGenerationService } from '../services/thumbnailGenerationService'; +import { getFileId } from '../utils/fileUtils'; + +// Initial state +const initialViewerConfig: ViewerConfig = { + zoom: 1.0, + currentPage: 1, + viewMode: 'single', + sidebarOpen: false +}; + +const initialState: FileContextState = { + activeFiles: [], + processedFiles: new Map(), + currentMode: 'pageEditor', + currentView: 'fileEditor', // Legacy field + currentTool: null, // Legacy field + fileEditHistory: new Map(), + globalFileOperations: [], + fileOperationHistory: new Map(), + selectedFileIds: [], + selectedPageNumbers: [], + viewerConfig: initialViewerConfig, + isProcessing: false, + processingProgress: 0, + lastExportConfig: undefined, + hasUnsavedChanges: false, + pendingNavigation: null, + showNavigationWarning: false +}; + +// Action types +type FileContextAction = + | { type: 'SET_ACTIVE_FILES'; payload: File[] } + | { type: 'ADD_FILES'; payload: File[] } + | { type: 'REMOVE_FILES'; payload: string[] } + | { type: 'SET_PROCESSED_FILES'; payload: Map } + | { type: 'UPDATE_PROCESSED_FILE'; payload: { file: File; processedFile: ProcessedFile } } + | { type: 'SET_CURRENT_MODE'; payload: ModeType } + | { type: 'SET_CURRENT_VIEW'; payload: ViewType } + | { type: 'SET_CURRENT_TOOL'; payload: ToolType } + | { type: 'SET_SELECTED_FILES'; payload: string[] } + | { type: 'SET_SELECTED_PAGES'; payload: number[] } + | { type: 'CLEAR_SELECTIONS' } + | { type: 'SET_PROCESSING'; payload: { isProcessing: boolean; progress: number } } + | { type: 'UPDATE_VIEWER_CONFIG'; payload: Partial } + | { type: 'ADD_PAGE_OPERATIONS'; payload: { fileId: string; operations: PageOperation[] } } + | { type: 'ADD_FILE_OPERATION'; payload: FileOperation } + | { type: 'RECORD_OPERATION'; payload: { fileId: string; operation: FileOperation | PageOperation } } + | { type: 'MARK_OPERATION_APPLIED'; payload: { fileId: string; operationId: string } } + | { type: 'MARK_OPERATION_FAILED'; payload: { fileId: string; operationId: string; error: string } } + | { type: 'CLEAR_FILE_HISTORY'; payload: string } + | { type: 'SET_EXPORT_CONFIG'; payload: FileContextState['lastExportConfig'] } + | { type: 'SET_UNSAVED_CHANGES'; payload: boolean } + | { type: 'SET_PENDING_NAVIGATION'; payload: (() => void) | null } + | { type: 'SHOW_NAVIGATION_WARNING'; payload: boolean } + | { type: 'RESET_CONTEXT' } + | { type: 'LOAD_STATE'; payload: Partial }; + +// Reducer +function fileContextReducer(state: FileContextState, action: FileContextAction): FileContextState { + switch (action.type) { + case 'SET_ACTIVE_FILES': + return { + ...state, + activeFiles: action.payload, + selectedFileIds: [], // Clear selections when files change + selectedPageNumbers: [] + }; + + case 'ADD_FILES': + return { + ...state, + activeFiles: [...state.activeFiles, ...action.payload] + }; + + case 'REMOVE_FILES': + const remainingFiles = state.activeFiles.filter(file => { + const fileId = getFileId(file); + return !fileId || !action.payload.includes(fileId); + }); + const safeSelectedFileIds = Array.isArray(state.selectedFileIds) ? state.selectedFileIds : []; + return { + ...state, + activeFiles: remainingFiles, + selectedFileIds: safeSelectedFileIds.filter(id => !action.payload.includes(id)) + }; + + case 'SET_PROCESSED_FILES': + return { + ...state, + processedFiles: action.payload + }; + + case 'UPDATE_PROCESSED_FILE': + const updatedProcessedFiles = new Map(state.processedFiles); + updatedProcessedFiles.set(action.payload.file, action.payload.processedFile); + return { + ...state, + processedFiles: updatedProcessedFiles + }; + + case 'SET_CURRENT_MODE': + const coreViews = ['viewer', 'pageEditor', 'fileEditor']; + const isToolMode = !coreViews.includes(action.payload); + + return { + ...state, + currentMode: action.payload, + // Update legacy fields for backward compatibility + currentView: isToolMode ? 'fileEditor' : action.payload as ViewType, + currentTool: isToolMode ? action.payload as ToolType : null + }; + + case 'SET_CURRENT_VIEW': + // Legacy action - just update currentMode + return { + ...state, + currentMode: action.payload as ModeType, + currentView: action.payload, + currentTool: null + }; + + case 'SET_CURRENT_TOOL': + // Legacy action - just update currentMode + return { + ...state, + currentMode: action.payload ? action.payload as ModeType : 'pageEditor', + currentView: action.payload ? 'fileEditor' : 'pageEditor', + currentTool: action.payload + }; + + case 'SET_SELECTED_FILES': + return { + ...state, + selectedFileIds: action.payload + }; + + case 'SET_SELECTED_PAGES': + return { + ...state, + selectedPageNumbers: action.payload + }; + + case 'CLEAR_SELECTIONS': + return { + ...state, + selectedFileIds: [], + selectedPageNumbers: [] + }; + + case 'SET_PROCESSING': + return { + ...state, + isProcessing: action.payload.isProcessing, + processingProgress: action.payload.progress + }; + + case 'UPDATE_VIEWER_CONFIG': + return { + ...state, + viewerConfig: { + ...state.viewerConfig, + ...action.payload + } + }; + + case 'ADD_PAGE_OPERATIONS': + const newHistory = new Map(state.fileEditHistory); + const existing = newHistory.get(action.payload.fileId); + newHistory.set(action.payload.fileId, { + fileId: action.payload.fileId, + pageOperations: existing ? + [...existing.pageOperations, ...action.payload.operations] : + action.payload.operations, + lastModified: Date.now() + }); + return { + ...state, + fileEditHistory: newHistory + }; + + case 'ADD_FILE_OPERATION': + return { + ...state, + globalFileOperations: [...state.globalFileOperations, action.payload] + }; + + case 'RECORD_OPERATION': + const { fileId, operation } = action.payload; + const newOperationHistory = new Map(state.fileOperationHistory); + const existingHistory = newOperationHistory.get(fileId); + + if (existingHistory) { + // Add operation to existing history + newOperationHistory.set(fileId, { + ...existingHistory, + operations: [...existingHistory.operations, operation], + lastModified: Date.now() + }); + } else { + // Create new history for this file + newOperationHistory.set(fileId, { + fileId, + fileName: fileId, // Will be updated with actual filename when available + operations: [operation], + createdAt: Date.now(), + lastModified: Date.now() + }); + } + + return { + ...state, + fileOperationHistory: newOperationHistory + }; + + case 'MARK_OPERATION_APPLIED': + const appliedHistory = new Map(state.fileOperationHistory); + const appliedFileHistory = appliedHistory.get(action.payload.fileId); + + if (appliedFileHistory) { + const updatedOperations = appliedFileHistory.operations.map(op => + op.id === action.payload.operationId + ? { ...op, status: 'applied' as const } + : op + ); + appliedHistory.set(action.payload.fileId, { + ...appliedFileHistory, + operations: updatedOperations, + lastModified: Date.now() + }); + } + + return { + ...state, + fileOperationHistory: appliedHistory + }; + + case 'MARK_OPERATION_FAILED': + const failedHistory = new Map(state.fileOperationHistory); + const failedFileHistory = failedHistory.get(action.payload.fileId); + + if (failedFileHistory) { + const updatedOperations = failedFileHistory.operations.map(op => + op.id === action.payload.operationId + ? { + ...op, + status: 'failed' as const, + metadata: { ...op.metadata, error: action.payload.error } + } + : op + ); + failedHistory.set(action.payload.fileId, { + ...failedFileHistory, + operations: updatedOperations, + lastModified: Date.now() + }); + } + + return { + ...state, + fileOperationHistory: failedHistory + }; + + case 'CLEAR_FILE_HISTORY': + const clearedHistory = new Map(state.fileOperationHistory); + clearedHistory.delete(action.payload); + return { + ...state, + fileOperationHistory: clearedHistory + }; + + case 'SET_EXPORT_CONFIG': + return { + ...state, + lastExportConfig: action.payload + }; + + case 'SET_UNSAVED_CHANGES': + return { + ...state, + hasUnsavedChanges: action.payload + }; + + case 'SET_PENDING_NAVIGATION': + return { + ...state, + pendingNavigation: action.payload + }; + + case 'SHOW_NAVIGATION_WARNING': + return { + ...state, + showNavigationWarning: action.payload + }; + + case 'RESET_CONTEXT': + return { + ...initialState + }; + + case 'LOAD_STATE': + return { + ...state, + ...action.payload + }; + + default: + return state; + } +} + +// Context +const FileContext = createContext(undefined); + +// Provider component +export function FileContextProvider({ + children, + enableUrlSync = true, + enablePersistence = true, + maxCacheSize = 1024 * 1024 * 1024 // 1GB +}: FileContextProviderProps) { + const [state, dispatch] = useReducer(fileContextReducer, initialState); + + // Cleanup timers and refs + const cleanupTimers = useRef>(new Map()); + const blobUrls = useRef>(new Set()); + const pdfDocuments = useRef>(new Map()); + + // Enhanced file processing hook + const { + processedFiles, + processingStates, + isProcessing: globalProcessing, + processingProgress, + actions: processingActions + } = useEnhancedProcessedFiles(state.activeFiles, { + strategy: 'progressive_chunked', + thumbnailQuality: 'medium', + chunkSize: 5, // Process 5 pages at a time for smooth progress + priorityPageCount: 0 // No special priority pages + }); + + // Update processed files when they change + useEffect(() => { + dispatch({ type: 'SET_PROCESSED_FILES', payload: processedFiles }); + dispatch({ + type: 'SET_PROCESSING', + payload: { + isProcessing: globalProcessing, + progress: processingProgress.overall + } + }); + }, [processedFiles, globalProcessing, processingProgress.overall]); + + + // Centralized memory management + const trackBlobUrl = useCallback((url: string) => { + blobUrls.current.add(url); + }, []); + + const trackPdfDocument = useCallback((fileId: string, pdfDoc: PDFDocument) => { + // Clean up existing document for this file if any + const existing = pdfDocuments.current.get(fileId); + if (existing && existing.destroy) { + try { + existing.destroy(); + } catch (error) { + console.warn('Error destroying existing PDF document:', error); + } + } + pdfDocuments.current.set(fileId, pdfDoc); + }, []); + + const cleanupFile = useCallback(async (fileId: string) => { + console.log('Cleaning up file:', fileId); + + try { + // Cancel any pending cleanup timer + const timer = cleanupTimers.current.get(fileId); + if (timer) { + clearTimeout(timer); + cleanupTimers.current.delete(fileId); + } + + // Cleanup PDF document instances (but preserve processed file cache) + const pdfDoc = pdfDocuments.current.get(fileId); + if (pdfDoc && pdfDoc.destroy) { + pdfDoc.destroy(); + pdfDocuments.current.delete(fileId); + } + + // IMPORTANT: Don't cancel processing or clear cache during normal view switches + // Only do this when file is actually being removed + // enhancedPDFProcessingService.cancelProcessing(fileId); + // thumbnailGenerationService.stopGeneration(); + + } catch (error) { + console.warn('Error during file cleanup:', error); + } + }, []); + + const cleanupAllFiles = useCallback(() => { + console.log('Cleaning up all files'); + + try { + // Clear all timers + cleanupTimers.current.forEach(timer => clearTimeout(timer)); + cleanupTimers.current.clear(); + + // Destroy all PDF documents + pdfDocuments.current.forEach((pdfDoc, fileId) => { + if (pdfDoc && pdfDoc.destroy) { + try { + pdfDoc.destroy(); + } catch (error) { + console.warn(`Error destroying PDF document for ${fileId}:`, error); + } + } + }); + pdfDocuments.current.clear(); + + // Revoke all blob URLs + blobUrls.current.forEach(url => { + try { + URL.revokeObjectURL(url); + } catch (error) { + console.warn('Error revoking blob URL:', error); + } + }); + blobUrls.current.clear(); + + // Clear all processing + enhancedPDFProcessingService.clearAllProcessing(); + + // Destroy thumbnails + thumbnailGenerationService.destroy(); + + // Force garbage collection hint + if (typeof window !== 'undefined' && window.gc) { + setTimeout(() => window.gc(), 100); + } + + } catch (error) { + console.warn('Error during cleanup all files:', error); + } + }, []); + + const scheduleCleanup = useCallback((fileId: string, delay: number = 30000) => { + // Cancel existing timer + const existingTimer = cleanupTimers.current.get(fileId); + if (existingTimer) { + clearTimeout(existingTimer); + cleanupTimers.current.delete(fileId); + } + + // If delay is negative, just cancel (don't reschedule) + if (delay < 0) { + return; + } + + // Schedule new cleanup + const timer = setTimeout(() => { + cleanupFile(fileId); + }, delay); + + cleanupTimers.current.set(fileId, timer); + }, [cleanupFile]); + + // Action implementations + const addFiles = useCallback(async (files: File[]): Promise => { + dispatch({ type: 'ADD_FILES', payload: files }); + + // Auto-save to IndexedDB if persistence enabled + if (enablePersistence) { + for (const file of files) { + try { + // Check if file already has an explicit ID property (already in IndexedDB) + const fileId = getFileId(file); + if (!fileId) { + // File doesn't have explicit ID, store it with thumbnail + try { + // Generate thumbnail for better recent files experience + const thumbnail = await thumbnailGenerationService.generateThumbnail(file); + const storedFile = await fileStorage.storeFile(file, thumbnail); + // Add the ID to the file object + Object.defineProperty(file, 'id', { value: storedFile.id, writable: false }); + } catch (thumbnailError) { + // If thumbnail generation fails, store without thumbnail + console.warn('Failed to generate thumbnail, storing without:', thumbnailError); + const storedFile = await fileStorage.storeFile(file); + Object.defineProperty(file, 'id', { value: storedFile.id, writable: false }); + } + } + } catch (error) { + console.error('Failed to store file:', error); + } + } + } + + // Return files with their IDs assigned + return files; + }, [enablePersistence]); + + const removeFiles = useCallback((fileIds: string[], deleteFromStorage: boolean = true) => { + // FULL cleanup for actually removed files (including cache) + fileIds.forEach(fileId => { + // Cancel processing and clear caches when file is actually removed + enhancedPDFProcessingService.cancelProcessing(fileId); + cleanupFile(fileId); + }); + + dispatch({ type: 'REMOVE_FILES', payload: fileIds }); + + // Remove from IndexedDB only if requested + if (enablePersistence && deleteFromStorage) { + fileIds.forEach(async (fileId) => { + try { + await fileStorage.deleteFile(fileId); + } catch (error) { + console.error('Failed to remove file from storage:', error); + } + }); + } + }, [enablePersistence, cleanupFile]); + + + const replaceFile = useCallback(async (oldFileId: string, newFile: File) => { + // Remove old file and add new one + removeFiles([oldFileId]); + await addFiles([newFile]); + }, [removeFiles, addFiles]); + + const clearAllFiles = useCallback(() => { + // Cleanup all memory before clearing files + cleanupAllFiles(); + + dispatch({ type: 'SET_ACTIVE_FILES', payload: [] }); + dispatch({ type: 'CLEAR_SELECTIONS' }); + }, [cleanupAllFiles]); + + // Navigation guard system functions + const setHasUnsavedChanges = useCallback((hasChanges: boolean) => { + dispatch({ type: 'SET_UNSAVED_CHANGES', payload: hasChanges }); + }, []); + + const requestNavigation = useCallback((navigationFn: () => void): boolean => { + if (state.hasUnsavedChanges) { + dispatch({ type: 'SET_PENDING_NAVIGATION', payload: navigationFn }); + dispatch({ type: 'SHOW_NAVIGATION_WARNING', payload: true }); + return false; + } else { + navigationFn(); + return true; + } + }, [state.hasUnsavedChanges]); + + const confirmNavigation = useCallback(() => { + if (state.pendingNavigation) { + state.pendingNavigation(); + dispatch({ type: 'SET_PENDING_NAVIGATION', payload: null }); + } + dispatch({ type: 'SHOW_NAVIGATION_WARNING', payload: false }); + }, [state.pendingNavigation]); + + const cancelNavigation = useCallback(() => { + dispatch({ type: 'SET_PENDING_NAVIGATION', payload: null }); + dispatch({ type: 'SHOW_NAVIGATION_WARNING', payload: false }); + }, []); + + const setCurrentMode = useCallback((mode: ModeType) => { + requestNavigation(() => { + dispatch({ type: 'SET_CURRENT_MODE', payload: mode }); + + if (state.currentMode !== mode && state.activeFiles.length > 0) { + if (window.requestIdleCallback && typeof window !== 'undefined' && window.gc) { + window.requestIdleCallback(() => { + window.gc(); + }, { timeout: 5000 }); + } + } + }); + }, [requestNavigation, state.currentMode, state.activeFiles]); + + const setCurrentView = useCallback((view: ViewType) => { + requestNavigation(() => { + dispatch({ type: 'SET_CURRENT_VIEW', payload: view }); + + if (state.currentView !== view && state.activeFiles.length > 0) { + if (window.requestIdleCallback && typeof window !== 'undefined' && window.gc) { + window.requestIdleCallback(() => { + window.gc(); + }, { timeout: 5000 }); + } + } + }); + }, [requestNavigation, state.currentView, state.activeFiles]); + + const setCurrentTool = useCallback((tool: ToolType) => { + requestNavigation(() => { + dispatch({ type: 'SET_CURRENT_TOOL', payload: tool }); + }); + }, [requestNavigation]); + + const setSelectedFiles = useCallback((fileIds: string[]) => { + dispatch({ type: 'SET_SELECTED_FILES', payload: fileIds }); + }, []); + + const setSelectedPages = useCallback((pageNumbers: number[]) => { + dispatch({ type: 'SET_SELECTED_PAGES', payload: pageNumbers }); + }, []); + + const updateProcessedFile = useCallback((file: File, processedFile: ProcessedFile) => { + dispatch({ type: 'UPDATE_PROCESSED_FILE', payload: { file, processedFile } }); + }, []); + + const clearSelections = useCallback(() => { + dispatch({ type: 'CLEAR_SELECTIONS' }); + }, []); + + const applyPageOperations = useCallback((fileId: string, operations: PageOperation[]) => { + dispatch({ + type: 'ADD_PAGE_OPERATIONS', + payload: { fileId, operations } + }); + }, []); + + const applyFileOperation = useCallback((operation: FileOperation) => { + dispatch({ type: 'ADD_FILE_OPERATION', payload: operation }); + }, []); + + const undoLastOperation = useCallback((fileId?: string) => { + console.warn('Undo not yet implemented'); + }, []); + + const updateViewerConfig = useCallback((config: Partial) => { + dispatch({ type: 'UPDATE_VIEWER_CONFIG', payload: config }); + }, []); + + const setExportConfig = useCallback((config: FileContextState['lastExportConfig']) => { + dispatch({ type: 'SET_EXPORT_CONFIG', payload: config }); + }, []); + + // Operation history management functions + const recordOperation = useCallback((fileId: string, operation: FileOperation | PageOperation) => { + dispatch({ type: 'RECORD_OPERATION', payload: { fileId, operation } }); + }, []); + + const markOperationApplied = useCallback((fileId: string, operationId: string) => { + dispatch({ type: 'MARK_OPERATION_APPLIED', payload: { fileId, operationId } }); + }, []); + + const markOperationFailed = useCallback((fileId: string, operationId: string, error: string) => { + dispatch({ type: 'MARK_OPERATION_FAILED', payload: { fileId, operationId, error } }); + }, []); + + const getFileHistory = useCallback((fileId: string): FileOperationHistory | undefined => { + return state.fileOperationHistory.get(fileId); + }, [state.fileOperationHistory]); + + const getAppliedOperations = useCallback((fileId: string): (FileOperation | PageOperation)[] => { + const history = state.fileOperationHistory.get(fileId); + return history ? history.operations.filter(op => op.status === 'applied') : []; + }, [state.fileOperationHistory]); + + const clearFileHistory = useCallback((fileId: string) => { + dispatch({ type: 'CLEAR_FILE_HISTORY', payload: fileId }); + }, []); + + // Utility functions + const getFileById = useCallback((fileId: string): File | undefined => { + return state.activeFiles.find(file => { + const actualFileId = getFileId(file); + return actualFileId && actualFileId === fileId; + }); + }, [state.activeFiles]); + + const getProcessedFileById = useCallback((fileId: string): ProcessedFile | undefined => { + const file = getFileById(fileId); + return file ? state.processedFiles.get(file) : undefined; + }, [getFileById, state.processedFiles]); + + const getCurrentFile = useCallback((): File | undefined => { + if (state.selectedFileIds.length > 0) { + return getFileById(state.selectedFileIds[0]); + } + return state.activeFiles[0]; // Default to first file + }, [state.selectedFileIds, state.activeFiles, getFileById]); + + const getCurrentProcessedFile = useCallback((): ProcessedFile | undefined => { + const file = getCurrentFile(); + return file ? state.processedFiles.get(file) : undefined; + }, [getCurrentFile, state.processedFiles]); + + // Context persistence + const saveContext = useCallback(async () => { + if (!enablePersistence) return; + + try { + const contextData = { + currentView: state.currentView, + currentTool: state.currentTool, + selectedFileIds: state.selectedFileIds, + selectedPageIds: state.selectedPageIds, + viewerConfig: state.viewerConfig, + lastExportConfig: state.lastExportConfig, + timestamp: Date.now() + }; + + localStorage.setItem('fileContext', JSON.stringify(contextData)); + } catch (error) { + console.error('Failed to save context:', error); + } + }, [state, enablePersistence]); + + const loadContext = useCallback(async () => { + if (!enablePersistence) return; + + try { + const saved = localStorage.getItem('fileContext'); + if (saved) { + const contextData = JSON.parse(saved); + dispatch({ type: 'LOAD_STATE', payload: contextData }); + } + } catch (error) { + console.error('Failed to load context:', error); + } + }, [enablePersistence]); + + const resetContext = useCallback(() => { + dispatch({ type: 'RESET_CONTEXT' }); + if (enablePersistence) { + localStorage.removeItem('fileContext'); + } + }, [enablePersistence]); + + + // Auto-save context when it changes + useEffect(() => { + saveContext(); + }, [saveContext]); + + // Load context on mount + useEffect(() => { + loadContext(); + }, [loadContext]); + + // Cleanup on unmount + useEffect(() => { + return () => { + console.log('FileContext unmounting - cleaning up all resources'); + cleanupAllFiles(); + }; + }, [cleanupAllFiles]); + + const contextValue: FileContextValue = { + // State + ...state, + + // Actions + addFiles, + removeFiles, + replaceFile, + clearAllFiles, + setCurrentMode, + setCurrentView, + setCurrentTool, + setSelectedFiles, + setSelectedPages, + updateProcessedFile, + clearSelections, + applyPageOperations, + applyFileOperation, + undoLastOperation, + updateViewerConfig, + setExportConfig, + getFileById, + getProcessedFileById, + getCurrentFile, + getCurrentProcessedFile, + saveContext, + loadContext, + resetContext, + + // Operation history management + recordOperation, + markOperationApplied, + markOperationFailed, + getFileHistory, + getAppliedOperations, + clearFileHistory, + + // Navigation guard system + setHasUnsavedChanges, + requestNavigation, + confirmNavigation, + cancelNavigation, + + // Memory management + trackBlobUrl, + trackPdfDocument, + cleanupFile, + scheduleCleanup + }; + + return ( + + {children} + + ); +} + +// Custom hook to use the context +export function useFileContext(): FileContextValue { + const context = useContext(FileContext); + if (!context) { + throw new Error('useFileContext must be used within a FileContextProvider'); + } + return context; +} + +// Helper hooks for specific aspects +export function useCurrentFile() { + const { getCurrentFile, getCurrentProcessedFile } = useFileContext(); + return { + file: getCurrentFile(), + processedFile: getCurrentProcessedFile() + }; +} + +export function useFileSelection() { + const { + selectedFileIds, + selectedPageIds, + setSelectedFiles, + setSelectedPages, + clearSelections + } = useFileContext(); + + return { + selectedFileIds, + selectedPageIds, + setSelectedFiles, + setSelectedPages, + clearSelections + }; +} + +export function useViewerState() { + const { viewerConfig, updateViewerConfig } = useFileContext(); + return { + config: viewerConfig, + updateConfig: updateViewerConfig + }; +} \ No newline at end of file diff --git a/frontend/src/contexts/FileManagerContext.tsx b/frontend/src/contexts/FileManagerContext.tsx new file mode 100644 index 000000000..c7f924e8e --- /dev/null +++ b/frontend/src/contexts/FileManagerContext.tsx @@ -0,0 +1,218 @@ +import React, { createContext, useContext, useState, useRef, useCallback, useEffect } from 'react'; +import { FileWithUrl } from '../types/file'; +import { StoredFile } from '../services/fileStorage'; + +// Type for the context value - now contains everything directly +interface FileManagerContextValue { + // State + activeSource: 'recent' | 'local' | 'drive'; + selectedFileIds: string[]; + searchTerm: string; + selectedFiles: FileWithUrl[]; + filteredFiles: FileWithUrl[]; + fileInputRef: React.RefObject; + + // Handlers + onSourceChange: (source: 'recent' | 'local' | 'drive') => void; + onLocalFileClick: () => void; + onFileSelect: (file: FileWithUrl) => void; + onFileRemove: (index: number) => void; + onFileDoubleClick: (file: FileWithUrl) => void; + onOpenFiles: () => void; + onSearchChange: (value: string) => void; + onFileInputChange: (event: React.ChangeEvent) => void; + + // External props + recentFiles: FileWithUrl[]; + isFileSupported: (fileName: string) => boolean; + modalHeight: string; +} + +// Create the context +const FileManagerContext = createContext(null); + +// Provider component props +interface FileManagerProviderProps { + children: React.ReactNode; + recentFiles: FileWithUrl[]; + onFilesSelected: (files: FileWithUrl[]) => void; + onClose: () => void; + isFileSupported: (fileName: string) => boolean; + isOpen: boolean; + onFileRemove: (index: number) => void; + modalHeight: string; + storeFile: (file: File) => Promise; + refreshRecentFiles: () => Promise; +} + +export const FileManagerProvider: React.FC = ({ + children, + recentFiles, + onFilesSelected, + onClose, + isFileSupported, + isOpen, + onFileRemove, + modalHeight, + storeFile, + refreshRecentFiles, +}) => { + const [activeSource, setActiveSource] = useState<'recent' | 'local' | 'drive'>('recent'); + const [selectedFileIds, setSelectedFileIds] = useState([]); + const [searchTerm, setSearchTerm] = useState(''); + const fileInputRef = useRef(null); + + // Track blob URLs for cleanup + const createdBlobUrls = useRef>(new Set()); + + // Computed values (with null safety) + const selectedFiles = (recentFiles || []).filter(file => selectedFileIds.includes(file.id || file.name)); + const filteredFiles = (recentFiles || []).filter(file => + file.name.toLowerCase().includes(searchTerm.toLowerCase()) + ); + + const handleSourceChange = useCallback((source: 'recent' | 'local' | 'drive') => { + setActiveSource(source); + if (source !== 'recent') { + setSelectedFileIds([]); + setSearchTerm(''); + } + }, []); + + const handleLocalFileClick = useCallback(() => { + fileInputRef.current?.click(); + }, []); + + const handleFileSelect = useCallback((file: FileWithUrl) => { + setSelectedFileIds(prev => { + if (prev.includes(file.id)) { + return prev.filter(id => id !== file.id); + } else { + return [...prev, file.id]; + } + }); + }, []); + + const handleFileRemove = useCallback((index: number) => { + const fileToRemove = filteredFiles[index]; + if (fileToRemove) { + setSelectedFileIds(prev => prev.filter(id => id !== fileToRemove.id)); + } + onFileRemove(index); + }, [filteredFiles, onFileRemove]); + + const handleFileDoubleClick = useCallback((file: FileWithUrl) => { + if (isFileSupported(file.name)) { + onFilesSelected([file]); + onClose(); + } + }, [isFileSupported, onFilesSelected, onClose]); + + const handleOpenFiles = useCallback(() => { + if (selectedFiles.length > 0) { + onFilesSelected(selectedFiles); + onClose(); + } + }, [selectedFiles, onFilesSelected, onClose]); + + const handleSearchChange = useCallback((value: string) => { + setSearchTerm(value); + }, []); + + const handleFileInputChange = useCallback(async (event: React.ChangeEvent) => { + const files = Array.from(event.target.files || []); + if (files.length > 0) { + try { + // Create FileWithUrl objects - FileContext will handle storage and ID assignment + const fileWithUrls = files.map(file => { + const url = URL.createObjectURL(file); + createdBlobUrls.current.add(url); + + return { + // No ID assigned here - FileContext will handle storage and ID assignment + name: file.name, + file, + url, + size: file.size, + lastModified: file.lastModified, + }; + }); + + onFilesSelected(fileWithUrls); + await refreshRecentFiles(); + onClose(); + } catch (error) { + console.error('Failed to process selected files:', error); + } + } + event.target.value = ''; + }, [storeFile, onFilesSelected, refreshRecentFiles, onClose]); + + // Cleanup blob URLs when component unmounts + useEffect(() => { + return () => { + // Clean up all created blob URLs + createdBlobUrls.current.forEach(url => { + URL.revokeObjectURL(url); + }); + createdBlobUrls.current.clear(); + }; + }, []); + + // Reset state when modal closes + useEffect(() => { + if (!isOpen) { + setActiveSource('recent'); + setSelectedFileIds([]); + setSearchTerm(''); + } + }, [isOpen]); + + const contextValue: FileManagerContextValue = { + // State + activeSource, + selectedFileIds, + searchTerm, + selectedFiles, + filteredFiles, + fileInputRef, + + // Handlers + onSourceChange: handleSourceChange, + onLocalFileClick: handleLocalFileClick, + onFileSelect: handleFileSelect, + onFileRemove: handleFileRemove, + onFileDoubleClick: handleFileDoubleClick, + onOpenFiles: handleOpenFiles, + onSearchChange: handleSearchChange, + onFileInputChange: handleFileInputChange, + + // External props + recentFiles, + isFileSupported, + modalHeight, + }; + + return ( + + {children} + + ); +}; + +// Custom hook to use the context +export const useFileManagerContext = (): FileManagerContextValue => { + const context = useContext(FileManagerContext); + + if (!context) { + throw new Error( + 'useFileManagerContext must be used within a FileManagerProvider. ' + + 'Make sure you wrap your component with .' + ); + } + + return context; +}; + +// Export the context for advanced use cases +export { FileManagerContext }; \ No newline at end of file diff --git a/frontend/src/contexts/FileSelectionContext.tsx b/frontend/src/contexts/FileSelectionContext.tsx new file mode 100644 index 000000000..2c79882b2 --- /dev/null +++ b/frontend/src/contexts/FileSelectionContext.tsx @@ -0,0 +1,86 @@ +import React, { createContext, useContext, useState, useCallback, ReactNode } from 'react'; +import { + MaxFiles, + FileSelectionContextValue +} from '../types/tool'; + +interface FileSelectionProviderProps { + children: ReactNode; +} + +const FileSelectionContext = createContext(undefined); + +export function FileSelectionProvider({ children }: FileSelectionProviderProps) { + const [selectedFiles, setSelectedFiles] = useState([]); + const [maxFiles, setMaxFiles] = useState(-1); + const [isToolMode, setIsToolMode] = useState(false); + + const clearSelection = useCallback(() => { + setSelectedFiles([]); + }, []); + + const selectionCount = selectedFiles.length; + const canSelectMore = maxFiles === -1 || selectionCount < maxFiles; + const isAtLimit = maxFiles > 0 && selectionCount >= maxFiles; + const isMultiFileMode = maxFiles !== 1; + + const contextValue: FileSelectionContextValue = { + selectedFiles, + maxFiles, + isToolMode, + setSelectedFiles, + setMaxFiles, + setIsToolMode, + clearSelection, + canSelectMore, + isAtLimit, + selectionCount, + isMultiFileMode + }; + + return ( + + {children} + + ); +} + +/** + * Access the file selection context. + * Throws if used outside a . + */ +export function useFileSelection(): FileSelectionContextValue { + const context = useContext(FileSelectionContext); + if (!context) { + throw new Error('useFileSelection must be used within a FileSelectionProvider'); + } + return context; +} + +// Returns only the file selection values relevant for tools (e.g. merge, split, etc.) +// Use this in tool panels/components that need to know which files are selected and selection limits. +export function useToolFileSelection(): Pick { + const { selectedFiles, maxFiles, canSelectMore, isAtLimit, selectionCount } = useFileSelection(); + return { selectedFiles, maxFiles, canSelectMore, isAtLimit, selectionCount }; +} + +// Returns actions for manipulating file selection state. +// Use this in components that need to update the selection, clear it, or change selection mode. +export function useFileSelectionActions(): Pick { + const { setSelectedFiles, clearSelection, setMaxFiles, setIsToolMode } = useFileSelection(); + return { setSelectedFiles, clearSelection, setMaxFiles, setIsToolMode }; +} + +// Returns the raw file selection state (selected files, max files, tool mode). +// Use this for low-level state access, e.g. in context-aware UI. +export function useFileSelectionState(): Pick { + const { selectedFiles, maxFiles, isToolMode } = useFileSelection(); + return { selectedFiles, maxFiles, isToolMode }; +} + +// Returns computed values derived from file selection state. +// Use this for file selection UI logic (e.g. disabling buttons when at limit). +export function useFileSelectionComputed(): Pick { + const { canSelectMore, isAtLimit, selectionCount, isMultiFileMode } = useFileSelection(); + return { canSelectMore, isAtLimit, selectionCount, isMultiFileMode }; +} diff --git a/frontend/src/contexts/FilesModalContext.tsx b/frontend/src/contexts/FilesModalContext.tsx new file mode 100644 index 000000000..788db77bd --- /dev/null +++ b/frontend/src/contexts/FilesModalContext.tsx @@ -0,0 +1,67 @@ +import React, { createContext, useContext, useState, useCallback } from 'react'; +import { useFileHandler } from '../hooks/useFileHandler'; + +interface FilesModalContextType { + isFilesModalOpen: boolean; + openFilesModal: () => void; + closeFilesModal: () => void; + onFileSelect: (file: File) => void; + onFilesSelect: (files: File[]) => void; + onModalClose: () => void; + setOnModalClose: (callback: () => void) => void; +} + +const FilesModalContext = createContext(null); + +export const FilesModalProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const { addToActiveFiles, addMultipleFiles } = useFileHandler(); + const [isFilesModalOpen, setIsFilesModalOpen] = useState(false); + const [onModalClose, setOnModalClose] = useState<(() => void) | undefined>(); + + const openFilesModal = useCallback(() => { + setIsFilesModalOpen(true); + }, []); + + const closeFilesModal = useCallback(() => { + setIsFilesModalOpen(false); + onModalClose?.(); + }, [onModalClose]); + + const handleFileSelect = useCallback((file: File) => { + addToActiveFiles(file); + closeFilesModal(); + }, [addToActiveFiles, closeFilesModal]); + + const handleFilesSelect = useCallback((files: File[]) => { + addMultipleFiles(files); + closeFilesModal(); + }, [addMultipleFiles, closeFilesModal]); + + const setModalCloseCallback = useCallback((callback: () => void) => { + setOnModalClose(() => callback); + }, []); + + const contextValue: FilesModalContextType = { + isFilesModalOpen, + openFilesModal, + closeFilesModal, + onFileSelect: handleFileSelect, + onFilesSelect: handleFilesSelect, + onModalClose, + setOnModalClose: setModalCloseCallback, + }; + + return ( + + {children} + + ); +}; + +export const useFilesModalContext = () => { + const context = useContext(FilesModalContext); + if (!context) { + throw new Error('useFilesModalContext must be used within FilesModalProvider'); + } + return context; +}; \ No newline at end of file diff --git a/frontend/src/contexts/SidebarContext.tsx b/frontend/src/contexts/SidebarContext.tsx new file mode 100644 index 000000000..f09815c5c --- /dev/null +++ b/frontend/src/contexts/SidebarContext.tsx @@ -0,0 +1,47 @@ +import React, { createContext, useContext, useState, useRef } from 'react'; +import { SidebarState, SidebarRefs, SidebarContextValue, SidebarProviderProps } from '../types/sidebar'; + +const SidebarContext = createContext(undefined); + +export function SidebarProvider({ children }: SidebarProviderProps) { + // All sidebar state management + const quickAccessRef = useRef(null); + const toolPanelRef = useRef(null); + + const [sidebarsVisible, setSidebarsVisible] = useState(true); + const [leftPanelView, setLeftPanelView] = useState<'toolPicker' | 'toolContent'>('toolPicker'); + const [readerMode, setReaderMode] = useState(false); + + const sidebarState: SidebarState = { + sidebarsVisible, + leftPanelView, + readerMode, + }; + + const sidebarRefs: SidebarRefs = { + quickAccessRef, + toolPanelRef, + }; + + const contextValue: SidebarContextValue = { + sidebarState, + sidebarRefs, + setSidebarsVisible, + setLeftPanelView, + setReaderMode, + }; + + return ( + + {children} + + ); +} + +export function useSidebarContext(): SidebarContextValue { + const context = useContext(SidebarContext); + if (context === undefined) { + throw new Error('useSidebarContext must be used within a SidebarProvider'); + } + return context; +} \ No newline at end of file diff --git a/frontend/src/contexts/ToolWorkflowContext.tsx b/frontend/src/contexts/ToolWorkflowContext.tsx new file mode 100644 index 000000000..47f42b011 --- /dev/null +++ b/frontend/src/contexts/ToolWorkflowContext.tsx @@ -0,0 +1,221 @@ +/** + * ToolWorkflowContext - Manages tool selection, UI state, and workflow coordination + * Eliminates prop drilling with a single, simple context + */ + +import React, { createContext, useContext, useReducer, useCallback, useMemo } from 'react'; +import { useToolManagement } from '../hooks/useToolManagement'; +import { ToolConfiguration } from '../types/tool'; +import { PageEditorFunctions } from '../types/pageEditor'; + +// State interface +interface ToolWorkflowState { + // UI State + sidebarsVisible: boolean; + leftPanelView: 'toolPicker' | 'toolContent'; + readerMode: boolean; + + // File/Preview State + previewFile: File | null; + pageEditorFunctions: PageEditorFunctions | null; + + // Search State + searchQuery: string; +} + +// Actions +type ToolWorkflowAction = + | { type: 'SET_SIDEBARS_VISIBLE'; payload: boolean } + | { type: 'SET_LEFT_PANEL_VIEW'; payload: 'toolPicker' | 'toolContent' } + | { type: 'SET_READER_MODE'; payload: boolean } + | { type: 'SET_PREVIEW_FILE'; payload: File | null } + | { type: 'SET_PAGE_EDITOR_FUNCTIONS'; payload: PageEditorFunctions | null } + | { type: 'SET_SEARCH_QUERY'; payload: string } + | { type: 'RESET_UI_STATE' }; + +// Initial state +const initialState: ToolWorkflowState = { + sidebarsVisible: true, + leftPanelView: 'toolPicker', + readerMode: false, + previewFile: null, + pageEditorFunctions: null, + searchQuery: '', +}; + +// Reducer +function toolWorkflowReducer(state: ToolWorkflowState, action: ToolWorkflowAction): ToolWorkflowState { + switch (action.type) { + case 'SET_SIDEBARS_VISIBLE': + return { ...state, sidebarsVisible: action.payload }; + case 'SET_LEFT_PANEL_VIEW': + return { ...state, leftPanelView: action.payload }; + case 'SET_READER_MODE': + return { ...state, readerMode: action.payload }; + case 'SET_PREVIEW_FILE': + return { ...state, previewFile: action.payload }; + case 'SET_PAGE_EDITOR_FUNCTIONS': + return { ...state, pageEditorFunctions: action.payload }; + case 'SET_SEARCH_QUERY': + return { ...state, searchQuery: action.payload }; + case 'RESET_UI_STATE': + return { ...initialState, searchQuery: state.searchQuery }; // Preserve search + default: + return state; + } +} + +// Context value interface +interface ToolWorkflowContextValue extends ToolWorkflowState { + // Tool management (from hook) + selectedToolKey: string | null; + selectedTool: ToolConfiguration | null; + toolRegistry: any; // From useToolManagement + + // UI Actions + setSidebarsVisible: (visible: boolean) => void; + setLeftPanelView: (view: 'toolPicker' | 'toolContent') => void; + setReaderMode: (mode: boolean) => void; + setPreviewFile: (file: File | null) => void; + setPageEditorFunctions: (functions: PageEditorFunctions | null) => void; + setSearchQuery: (query: string) => void; + + // Tool Actions + selectTool: (toolId: string) => void; + clearToolSelection: () => void; + + // Workflow Actions (compound actions) + handleToolSelect: (toolId: string) => void; + handleBackToTools: () => void; + handleReaderToggle: () => void; + + // Computed values + filteredTools: [string, any][]; // Filtered by search + isPanelVisible: boolean; +} + +const ToolWorkflowContext = createContext(undefined); + +// Provider component +interface ToolWorkflowProviderProps { + children: React.ReactNode; + /** Handler for view changes (passed from parent) */ + onViewChange?: (view: string) => void; +} + +export function ToolWorkflowProvider({ children, onViewChange }: ToolWorkflowProviderProps) { + const [state, dispatch] = useReducer(toolWorkflowReducer, initialState); + + // Tool management hook + const { + selectedToolKey, + selectedTool, + toolRegistry, + selectTool, + clearToolSelection, + } = useToolManagement(); + + // UI Action creators + const setSidebarsVisible = useCallback((visible: boolean) => { + dispatch({ type: 'SET_SIDEBARS_VISIBLE', payload: visible }); + }, []); + + const setLeftPanelView = useCallback((view: 'toolPicker' | 'toolContent') => { + dispatch({ type: 'SET_LEFT_PANEL_VIEW', payload: view }); + }, []); + + const setReaderMode = useCallback((mode: boolean) => { + dispatch({ type: 'SET_READER_MODE', payload: mode }); + }, []); + + const setPreviewFile = useCallback((file: File | null) => { + dispatch({ type: 'SET_PREVIEW_FILE', payload: file }); + }, []); + + const setPageEditorFunctions = useCallback((functions: PageEditorFunctions | null) => { + dispatch({ type: 'SET_PAGE_EDITOR_FUNCTIONS', payload: functions }); + }, []); + + const setSearchQuery = useCallback((query: string) => { + dispatch({ type: 'SET_SEARCH_QUERY', payload: query }); + }, []); + + // Workflow actions (compound actions that coordinate multiple state changes) + const handleToolSelect = useCallback((toolId: string) => { + selectTool(toolId); + onViewChange?.('fileEditor'); + setLeftPanelView('toolContent'); + setReaderMode(false); + }, [selectTool, onViewChange, setLeftPanelView, setReaderMode]); + + const handleBackToTools = useCallback(() => { + setLeftPanelView('toolPicker'); + setReaderMode(false); + clearToolSelection(); + }, [setLeftPanelView, setReaderMode, clearToolSelection]); + + const handleReaderToggle = useCallback(() => { + setReaderMode(true); + }, [setReaderMode]); + + // Filter tools based on search query + const filteredTools = useMemo(() => { + if (!toolRegistry) return []; + return Object.entries(toolRegistry).filter(([_, { name }]) => + name.toLowerCase().includes(state.searchQuery.toLowerCase()) + ); + }, [toolRegistry, state.searchQuery]); + + const isPanelVisible = useMemo(() => + state.sidebarsVisible && !state.readerMode, + [state.sidebarsVisible, state.readerMode] + ); + + // Simple context value with basic memoization + const contextValue = useMemo((): ToolWorkflowContextValue => ({ + // State + ...state, + selectedToolKey, + selectedTool, + toolRegistry, + + // Actions + setSidebarsVisible, + setLeftPanelView, + setReaderMode, + setPreviewFile, + setPageEditorFunctions, + setSearchQuery, + selectTool, + clearToolSelection, + + // Workflow Actions + handleToolSelect, + handleBackToTools, + handleReaderToggle, + + // Computed + filteredTools, + isPanelVisible, + }), [state, selectedToolKey, selectedTool, toolRegistry, filteredTools, isPanelVisible]); + + return ( + + {children} + + ); +} + +// Custom hook to use the context +export function useToolWorkflow(): ToolWorkflowContextValue { + const context = useContext(ToolWorkflowContext); + if (!context) { + throw new Error('useToolWorkflow must be used within a ToolWorkflowProvider'); + } + return context; +} + +// Convenience exports for specific use cases (optional - components can use useToolWorkflow directly) +export const useToolSelection = useToolWorkflow; +export const useToolPanelState = useToolWorkflow; +export const useWorkbenchState = useToolWorkflow; \ No newline at end of file diff --git a/frontend/src/global.d.ts b/frontend/src/global.d.ts new file mode 100644 index 000000000..efbaa35a9 --- /dev/null +++ b/frontend/src/global.d.ts @@ -0,0 +1,7 @@ +declare module "../tools/Split"; +declare module "../tools/Compress"; +declare module "../tools/Merge"; +declare module "../components/PageEditor"; +declare module "../components/Viewer"; +declare module "*.js"; +declare module '*.module.css'; \ No newline at end of file diff --git a/frontend/src/hooks/tools/compress/useCompressOperation.ts b/frontend/src/hooks/tools/compress/useCompressOperation.ts new file mode 100644 index 000000000..e254cbe1c --- /dev/null +++ b/frontend/src/hooks/tools/compress/useCompressOperation.ts @@ -0,0 +1,49 @@ +import { useTranslation } from 'react-i18next'; +import { useToolOperation, ToolOperationConfig } from '../shared/useToolOperation'; +import { createStandardErrorHandler } from '../../../utils/toolErrorHandler'; + +export interface CompressParameters { + compressionLevel: number; + grayscale: boolean; + expectedSize: string; + compressionMethod: 'quality' | 'filesize'; + fileSizeValue: string; + fileSizeUnit: 'KB' | 'MB'; +} + +const buildFormData = (parameters: CompressParameters, file: File): FormData => { + const formData = new FormData(); + formData.append("fileInput", file); + + if (parameters.compressionMethod === 'quality') { + formData.append("optimizeLevel", parameters.compressionLevel.toString()); + } else { + // File size method + const fileSize = parameters.fileSizeValue ? `${parameters.fileSizeValue}${parameters.fileSizeUnit}` : ''; + if (fileSize) { + formData.append("expectedOutputSize", fileSize); + } + } + + formData.append("grayscale", parameters.grayscale.toString()); + return formData; +}; + +export const useCompressOperation = () => { + const { t } = useTranslation(); + + return useToolOperation({ + operationType: 'compress', + endpoint: '/api/v1/misc/compress-pdf', + buildFormData, + filePrefix: 'compressed_', + multiFileEndpoint: false, // Individual API calls per file + validateParams: (params) => { + if (params.compressionMethod === 'filesize' && !params.fileSizeValue) { + return { valid: false, errors: [t('compress.validation.fileSizeRequired', 'File size value is required when using filesize method')] }; + } + return { valid: true }; + }, + getErrorMessage: createStandardErrorHandler(t('compress.error.failed', 'An error occurred while compressing the PDF.')) + }); +}; diff --git a/frontend/src/hooks/tools/compress/useCompressParameters.ts b/frontend/src/hooks/tools/compress/useCompressParameters.ts new file mode 100644 index 000000000..bbd1a0994 --- /dev/null +++ b/frontend/src/hooks/tools/compress/useCompressParameters.ts @@ -0,0 +1,49 @@ +import { useState } from 'react'; +import { CompressParameters } from './useCompressOperation'; + +export interface CompressParametersHook { + parameters: CompressParameters; + updateParameter: (parameter: keyof CompressParameters, value: string | boolean | number) => void; + resetParameters: () => void; + validateParameters: () => boolean; + getEndpointName: () => string; +} + +const initialParameters: CompressParameters = { + compressionLevel: 5, + grayscale: false, + expectedSize: '', + compressionMethod: 'quality', + fileSizeValue: '', + fileSizeUnit: 'MB', +}; + +export const useCompressParameters = (): CompressParametersHook => { + const [parameters, setParameters] = useState(initialParameters); + + const updateParameter = (parameter: keyof CompressParameters, value: string | boolean | number) => { + setParameters(prev => ({ ...prev, [parameter]: value })); + }; + + const resetParameters = () => { + setParameters(initialParameters); + }; + + const validateParameters = () => { + // For compression, we only need to validate that compression level is within range + // and that at least one file is selected (at least, I think that's all we need to do here) + return parameters.compressionLevel >= 1 && parameters.compressionLevel <= 9; + }; + + const getEndpointName = () => { + return 'compress-pdf'; + }; + + return { + parameters, + updateParameter, + resetParameters, + validateParameters, + getEndpointName, + }; +}; \ No newline at end of file diff --git a/frontend/src/hooks/tools/convert/useConvertOperation.ts b/frontend/src/hooks/tools/convert/useConvertOperation.ts new file mode 100644 index 000000000..6d8d3971f --- /dev/null +++ b/frontend/src/hooks/tools/convert/useConvertOperation.ts @@ -0,0 +1,150 @@ +import { useCallback } from 'react'; +import axios from 'axios'; +import { useTranslation } from 'react-i18next'; +import { ConvertParameters } from './useConvertParameters'; +import { detectFileExtension } from '../../../utils/fileUtils'; +import { createFileFromApiResponse } from '../../../utils/fileResponseUtils'; +import { useToolOperation, ToolOperationConfig } from '../shared/useToolOperation'; +import { getEndpointUrl, isImageFormat, isWebFormat } from '../../../utils/convertUtils'; + +const shouldProcessFilesSeparately = ( + selectedFiles: File[], + parameters: ConvertParameters +): boolean => { + return selectedFiles.length > 1 && ( + // Image to PDF with combineImages = false + ((isImageFormat(parameters.fromExtension) || parameters.fromExtension === 'image') && + parameters.toExtension === 'pdf' && !parameters.imageOptions.combineImages) || + // PDF to image conversions (each PDF should generate its own image file) + (parameters.fromExtension === 'pdf' && isImageFormat(parameters.toExtension)) || + // PDF to PDF/A conversions (each PDF should be processed separately) + (parameters.fromExtension === 'pdf' && parameters.toExtension === 'pdfa') || + // Web files to PDF conversions (each web file should generate its own PDF) + ((isWebFormat(parameters.fromExtension) || parameters.fromExtension === 'web') && + parameters.toExtension === 'pdf') || + // Web files smart detection + (parameters.isSmartDetection && parameters.smartDetectionType === 'web') || + // Mixed file types (smart detection) + (parameters.isSmartDetection && parameters.smartDetectionType === 'mixed') + ); +}; + +const buildFormData = (parameters: ConvertParameters, selectedFiles: File[]): FormData => { + const formData = new FormData(); + + selectedFiles.forEach(file => { + formData.append("fileInput", file); + }); + + const { fromExtension, toExtension, imageOptions, htmlOptions, emailOptions, pdfaOptions } = parameters; + + if (isImageFormat(toExtension)) { + formData.append("imageFormat", toExtension); + formData.append("colorType", imageOptions.colorType); + formData.append("dpi", imageOptions.dpi.toString()); + formData.append("singleOrMultiple", imageOptions.singleOrMultiple); + } else if (fromExtension === 'pdf' && ['docx', 'odt'].includes(toExtension)) { + formData.append("outputFormat", toExtension); + } else if (fromExtension === 'pdf' && ['pptx', 'odp'].includes(toExtension)) { + formData.append("outputFormat", toExtension); + } else if (fromExtension === 'pdf' && ['txt', 'rtf'].includes(toExtension)) { + formData.append("outputFormat", toExtension); + } else if ((isImageFormat(fromExtension) || fromExtension === 'image') && toExtension === 'pdf') { + formData.append("fitOption", imageOptions.fitOption); + formData.append("colorType", imageOptions.colorType); + formData.append("autoRotate", imageOptions.autoRotate.toString()); + } else if ((fromExtension === 'html' || fromExtension === 'zip') && toExtension === 'pdf') { + formData.append("zoom", htmlOptions.zoomLevel.toString()); + } else if (fromExtension === 'eml' && toExtension === 'pdf') { + formData.append("includeAttachments", emailOptions.includeAttachments.toString()); + formData.append("maxAttachmentSizeMB", emailOptions.maxAttachmentSizeMB.toString()); + formData.append("downloadHtml", emailOptions.downloadHtml.toString()); + formData.append("includeAllRecipients", emailOptions.includeAllRecipients.toString()); + } else if (fromExtension === 'pdf' && toExtension === 'pdfa') { + formData.append("outputFormat", pdfaOptions.outputFormat); + } else if (fromExtension === 'pdf' && toExtension === 'csv') { + formData.append("pageNumbers", "all"); + } + + return formData; +}; + +const createFileFromResponse = ( + responseData: any, + headers: any, + originalFileName: string, + targetExtension: string +): File => { + const originalName = originalFileName.split('.')[0]; + const fallbackFilename = `${originalName}_converted.${targetExtension}`; + + return createFileFromApiResponse(responseData, headers, fallbackFilename); +}; + +export const useConvertOperation = () => { + const { t } = useTranslation(); + + const customConvertProcessor = useCallback(async ( + parameters: ConvertParameters, + selectedFiles: File[] + ): Promise => { + + const processedFiles: File[] = []; + const endpoint = getEndpointUrl(parameters.fromExtension, parameters.toExtension); + + if (!endpoint) { + throw new Error(t('errorNotSupported', 'Unsupported conversion format')); + } + + // Convert-specific routing logic: decide batch vs individual processing + if (shouldProcessFilesSeparately(selectedFiles, parameters)) { + // Individual processing for complex cases (PDF→image, smart detection, etc.) + for (const file of selectedFiles) { + try { + const formData = buildFormData(parameters, [file]); + const response = await axios.post(endpoint, formData, { responseType: 'blob' }); + + const convertedFile = createFileFromResponse(response.data, response.headers, file.name, parameters.toExtension); + + processedFiles.push(convertedFile); + } catch (error) { + console.warn(`Failed to convert file ${file.name}:`, error); + } + } + } else { + // Batch processing for simple cases (image→PDF combine) + const formData = buildFormData(parameters, selectedFiles); + const response = await axios.post(endpoint, formData, { responseType: 'blob' }); + + const baseFilename = selectedFiles.length === 1 + ? selectedFiles[0].name + : 'converted_files'; + + const convertedFile = createFileFromResponse(response.data, response.headers, baseFilename, parameters.toExtension); + processedFiles.push(convertedFile); + + } + + return processedFiles; + }, [t]); + + return useToolOperation({ + operationType: 'convert', + endpoint: '', // Not used with customProcessor but required + buildFormData, // Not used with customProcessor but required + filePrefix: 'converted_', + customProcessor: customConvertProcessor, // Convert handles its own routing + validateParams: (params) => { + return { valid: true }; + }, + getErrorMessage: (error) => { + if (error.response?.data && typeof error.response.data === 'string') { + return error.response.data; + } + if (error.message) { + return error.message; + } + return t("convert.errorConversion", "An error occurred while converting the file."); + } + }); +}; \ No newline at end of file diff --git a/frontend/src/hooks/tools/convert/useConvertParameters.test.ts b/frontend/src/hooks/tools/convert/useConvertParameters.test.ts new file mode 100644 index 000000000..b106c18cd --- /dev/null +++ b/frontend/src/hooks/tools/convert/useConvertParameters.test.ts @@ -0,0 +1,223 @@ +/** + * Unit tests for useConvertParameters hook + */ + +import { describe, test, expect } from 'vitest'; +import { renderHook, act } from '@testing-library/react'; +import { useConvertParameters } from './useConvertParameters'; + +describe('useConvertParameters', () => { + + describe('Parameter Management', () => { + + test('should initialize with default parameters', () => { + const { result } = renderHook(() => useConvertParameters()); + + expect(result.current.parameters.fromExtension).toBe(''); + expect(result.current.parameters.toExtension).toBe(''); + expect(result.current.parameters.imageOptions.colorType).toBe('color'); + expect(result.current.parameters.imageOptions.dpi).toBe(300); + expect(result.current.parameters.imageOptions.singleOrMultiple).toBe('multiple'); + expect(result.current.parameters.htmlOptions.zoomLevel).toBe(1.0); + expect(result.current.parameters.emailOptions.includeAttachments).toBe(true); + expect(result.current.parameters.emailOptions.maxAttachmentSizeMB).toBe(10); + expect(result.current.parameters.emailOptions.downloadHtml).toBe(false); + expect(result.current.parameters.emailOptions.includeAllRecipients).toBe(false); + expect(result.current.parameters.pdfaOptions.outputFormat).toBe('pdfa-1'); + }); + + test('should update individual parameters', () => { + const { result } = renderHook(() => useConvertParameters()); + + act(() => { + result.current.updateParameter('fromExtension', 'pdf'); + }); + + expect(result.current.parameters.fromExtension).toBe('pdf'); + expect(result.current.parameters.toExtension).toBe(''); // Should not affect other params + }); + + test('should update nested image options', () => { + const { result } = renderHook(() => useConvertParameters()); + + act(() => { + result.current.updateParameter('imageOptions', { + colorType: 'grayscale', + dpi: 150, + singleOrMultiple: 'single' + }); + }); + + expect(result.current.parameters.imageOptions.colorType).toBe('grayscale'); + expect(result.current.parameters.imageOptions.dpi).toBe(150); + expect(result.current.parameters.imageOptions.singleOrMultiple).toBe('single'); + }); + + test('should update nested HTML options', () => { + const { result } = renderHook(() => useConvertParameters()); + + act(() => { + result.current.updateParameter('htmlOptions', { + zoomLevel: 1.5 + }); + }); + + expect(result.current.parameters.htmlOptions.zoomLevel).toBe(1.5); + }); + + test('should update nested email options', () => { + const { result } = renderHook(() => useConvertParameters()); + + act(() => { + result.current.updateParameter('emailOptions', { + includeAttachments: false, + maxAttachmentSizeMB: 20, + downloadHtml: true, + includeAllRecipients: true + }); + }); + + expect(result.current.parameters.emailOptions.includeAttachments).toBe(false); + expect(result.current.parameters.emailOptions.maxAttachmentSizeMB).toBe(20); + expect(result.current.parameters.emailOptions.downloadHtml).toBe(true); + expect(result.current.parameters.emailOptions.includeAllRecipients).toBe(true); + }); + + test('should update nested PDF/A options', () => { + const { result } = renderHook(() => useConvertParameters()); + + act(() => { + result.current.updateParameter('pdfaOptions', { + outputFormat: 'pdfa' + }); + }); + + expect(result.current.parameters.pdfaOptions.outputFormat).toBe('pdfa'); + }); + + test('should reset parameters to defaults', () => { + const { result } = renderHook(() => useConvertParameters()); + + act(() => { + result.current.updateParameter('fromExtension', 'pdf'); + result.current.updateParameter('toExtension', 'png'); + }); + + expect(result.current.parameters.fromExtension).toBe('pdf'); + + act(() => { + result.current.resetParameters(); + }); + + expect(result.current.parameters.fromExtension).toBe(''); + expect(result.current.parameters.toExtension).toBe(''); + }); + }); + + describe('Parameter Validation', () => { + + test('should validate parameters correctly', () => { + const { result } = renderHook(() => useConvertParameters()); + + // No parameters - should be invalid + expect(result.current.validateParameters()).toBe(false); + + // Only fromExtension - should be invalid + act(() => { + result.current.updateParameter('fromExtension', 'pdf'); + }); + expect(result.current.validateParameters()).toBe(false); + + // Both extensions with supported conversion - should be valid + act(() => { + result.current.updateParameter('toExtension', 'png'); + }); + expect(result.current.validateParameters()).toBe(true); + }); + + test('should validate unsupported conversions', () => { + const { result } = renderHook(() => useConvertParameters()); + + act(() => { + result.current.updateParameter('fromExtension', 'pdf'); + result.current.updateParameter('toExtension', 'unsupported'); + }); + + expect(result.current.validateParameters()).toBe(false); + }); + + }); + + describe('Endpoint Generation', () => { + + test('should generate correct endpoint names', () => { + const { result } = renderHook(() => useConvertParameters()); + + act(() => { + result.current.updateParameter('fromExtension', 'pdf'); + result.current.updateParameter('toExtension', 'png'); + }); + + const endpointName = result.current.getEndpointName(); + expect(endpointName).toBe('pdf-to-img'); + }); + + test('should generate correct endpoint URLs', () => { + const { result } = renderHook(() => useConvertParameters()); + + act(() => { + result.current.updateParameter('fromExtension', 'pdf'); + result.current.updateParameter('toExtension', 'png'); + }); + + const endpoint = result.current.getEndpoint(); + expect(endpoint).toBe('/api/v1/convert/pdf/img'); + }); + + test('should return empty strings for invalid conversions', () => { + const { result } = renderHook(() => useConvertParameters()); + + act(() => { + result.current.updateParameter('fromExtension', 'invalid'); + result.current.updateParameter('toExtension', 'invalid'); + }); + + expect(result.current.getEndpointName()).toBe(''); + expect(result.current.getEndpoint()).toBe(''); + }); + }); + + describe('Available Extensions', () => { + + test('should return available extensions for valid source format', () => { + const { result } = renderHook(() => useConvertParameters()); + + const availableExtensions = result.current.getAvailableToExtensions('pdf'); + + expect(availableExtensions.length).toBeGreaterThan(0); + expect(availableExtensions.some(ext => ext.value === 'png')).toBe(true); + expect(availableExtensions.some(ext => ext.value === 'jpg')).toBe(true); + }); + + test('should return empty array for invalid source format', () => { + const { result } = renderHook(() => useConvertParameters()); + + const availableExtensions = result.current.getAvailableToExtensions('invalid'); + + expect(availableExtensions).toEqual([{ + "group": "Document", + "label": "PDF", + "value": "pdf", + }]); + }); + + test('should return empty array for empty source format', () => { + const { result } = renderHook(() => useConvertParameters()); + + const availableExtensions = result.current.getAvailableToExtensions(''); + + expect(availableExtensions).toEqual([]); + }); + }); + +}); \ No newline at end of file diff --git a/frontend/src/hooks/tools/convert/useConvertParameters.ts b/frontend/src/hooks/tools/convert/useConvertParameters.ts new file mode 100644 index 000000000..9843ef44f --- /dev/null +++ b/frontend/src/hooks/tools/convert/useConvertParameters.ts @@ -0,0 +1,327 @@ +import { useState, useEffect } from 'react'; +import { + COLOR_TYPES, + OUTPUT_OPTIONS, + FIT_OPTIONS, + TO_FORMAT_OPTIONS, + CONVERSION_MATRIX, + type ColorType, + type OutputOption, + type FitOption +} from '../../../constants/convertConstants'; +import { getEndpointName as getEndpointNameUtil, getEndpointUrl, isImageFormat, isWebFormat } from '../../../utils/convertUtils'; +import { detectFileExtension as detectFileExtensionUtil } from '../../../utils/fileUtils'; + +export interface ConvertParameters { + fromExtension: string; + toExtension: string; + imageOptions: { + colorType: ColorType; + dpi: number; + singleOrMultiple: OutputOption; + fitOption: FitOption; + autoRotate: boolean; + combineImages: boolean; + }; + htmlOptions: { + zoomLevel: number; + }; + emailOptions: { + includeAttachments: boolean; + maxAttachmentSizeMB: number; + downloadHtml: boolean; + includeAllRecipients: boolean; + }; + pdfaOptions: { + outputFormat: string; + }; + isSmartDetection: boolean; + smartDetectionType: 'mixed' | 'images' | 'web' | 'none'; +} + +export interface ConvertParametersHook { + parameters: ConvertParameters; + updateParameter: (parameter: keyof ConvertParameters, value: any) => void; + resetParameters: () => void; + validateParameters: () => boolean; + getEndpointName: () => string; + getEndpoint: () => string; + getAvailableToExtensions: (fromExtension: string) => Array<{value: string, label: string, group: string}>; + analyzeFileTypes: (files: Array<{name: string}>) => void; +} + +const initialParameters: ConvertParameters = { + fromExtension: '', + toExtension: '', + imageOptions: { + colorType: COLOR_TYPES.COLOR, + dpi: 300, + singleOrMultiple: OUTPUT_OPTIONS.MULTIPLE, + fitOption: FIT_OPTIONS.MAINTAIN_ASPECT, + autoRotate: true, + combineImages: true, + }, + htmlOptions: { + zoomLevel: 1.0, + }, + emailOptions: { + includeAttachments: true, + maxAttachmentSizeMB: 10, + downloadHtml: false, + includeAllRecipients: false, + }, + pdfaOptions: { + outputFormat: 'pdfa-1', + }, + isSmartDetection: false, + smartDetectionType: 'none', +}; + +export const useConvertParameters = (): ConvertParametersHook => { + const [parameters, setParameters] = useState(initialParameters); + + const updateParameter = (parameter: keyof ConvertParameters, value: any) => { + setParameters(prev => ({ ...prev, [parameter]: value })); + }; + + const resetParameters = () => { + setParameters(initialParameters); + }; + + const validateParameters = () => { + const { fromExtension, toExtension } = parameters; + + if (!fromExtension || !toExtension) return false; + + // Handle dynamic format identifiers (file-) + let supportedToExtensions: string[] = []; + if (fromExtension.startsWith('file-')) { + // Dynamic format - use 'any' conversion options + supportedToExtensions = CONVERSION_MATRIX['any'] || []; + } else { + // Regular format - check conversion matrix + supportedToExtensions = CONVERSION_MATRIX[fromExtension] || []; + } + + if (!supportedToExtensions.includes(toExtension)) { + return false; + } + + return true; + }; + + const getEndpointName = () => { + const { fromExtension, toExtension, isSmartDetection, smartDetectionType } = parameters; + + if (isSmartDetection) { + if (smartDetectionType === 'mixed') { + // Mixed file types -> PDF using file-to-pdf endpoint + return 'file-to-pdf'; + } else if (smartDetectionType === 'images') { + // All images -> PDF using img-to-pdf endpoint + return 'img-to-pdf'; + } else if (smartDetectionType === 'web') { + // All web files -> PDF using html-to-pdf endpoint + return 'html-to-pdf'; + } + } + + // Handle dynamic format identifiers (file-) + if (fromExtension.startsWith('file-')) { + // Dynamic format - use file-to-pdf endpoint + return 'file-to-pdf'; + } + + return getEndpointNameUtil(fromExtension, toExtension); + }; + + const getEndpoint = () => { + const { fromExtension, toExtension, isSmartDetection, smartDetectionType } = parameters; + + if (isSmartDetection) { + if (smartDetectionType === 'mixed') { + // Mixed file types -> PDF using file-to-pdf endpoint + return '/api/v1/convert/file/pdf'; + } else if (smartDetectionType === 'images') { + // All images -> PDF using img-to-pdf endpoint + return '/api/v1/convert/img/pdf'; + } else if (smartDetectionType === 'web') { + // All web files -> PDF using html-to-pdf endpoint + return '/api/v1/convert/html/pdf'; + } + } + + // Handle dynamic format identifiers (file-) + if (fromExtension.startsWith('file-')) { + // Dynamic format - use file-to-pdf endpoint + return '/api/v1/convert/file/pdf'; + } + + return getEndpointUrl(fromExtension, toExtension); + }; + + const getAvailableToExtensions = (fromExtension: string) => { + if (!fromExtension) return []; + + // Handle dynamic format identifiers (file-) + if (fromExtension.startsWith('file-')) { + // Dynamic format - use 'any' conversion options (file-to-pdf) + const supportedExtensions = CONVERSION_MATRIX['any'] || []; + return TO_FORMAT_OPTIONS.filter(option => + supportedExtensions.includes(option.value) + ); + } + + let supportedExtensions = CONVERSION_MATRIX[fromExtension] || []; + + // If no explicit conversion exists, but file-to-pdf might be available, + // fall back to 'any' conversion (which converts unknown files to PDF via file-to-pdf) + if (supportedExtensions.length === 0 && fromExtension !== 'any') { + supportedExtensions = CONVERSION_MATRIX['any'] || []; + } + + return TO_FORMAT_OPTIONS.filter(option => + supportedExtensions.includes(option.value) + ); + }; + + + const analyzeFileTypes = (files: Array<{name: string}>) => { + if (files.length === 0) { + // No files - only reset smart detection, keep user's format choices + setParameters(prev => ({ + ...prev, + isSmartDetection: false, + smartDetectionType: 'none' + // Don't reset fromExtension and toExtension - let user keep their choices + })); + return; + } + + if (files.length === 1) { + // Single file - use regular detection with smart target selection + const detectedExt = detectFileExtensionUtil(files[0].name); + let fromExt = detectedExt; + let availableTargets = detectedExt ? CONVERSION_MATRIX[detectedExt] || [] : []; + + // If no explicit conversion exists for this file type, create a dynamic format entry + // and fall back to 'any' conversion logic for the actual endpoint + if (availableTargets.length === 0 && detectedExt) { + fromExt = `file-${detectedExt}`; // Create dynamic format identifier + availableTargets = CONVERSION_MATRIX['any'] || []; + } else if (availableTargets.length === 0) { + // No extension detected - fall back to 'any' + fromExt = 'any'; + availableTargets = CONVERSION_MATRIX['any'] || []; + } + + setParameters(prev => { + // Check if current toExtension is still valid for the new fromExtension + const currentToExt = prev.toExtension; + const isCurrentToExtValid = availableTargets.includes(currentToExt); + + // Auto-select target only if: + // 1. No current target is set, OR + // 2. Current target is invalid for new source type, OR + // 3. There's only one possible target (forced conversion) + let newToExtension = currentToExt; + if (!currentToExt || !isCurrentToExtValid) { + newToExtension = availableTargets.length === 1 ? availableTargets[0] : ''; + } + + return { + ...prev, + isSmartDetection: false, + smartDetectionType: 'none', + fromExtension: fromExt, + toExtension: newToExtension + }; + }); + return; + } + + // Multiple files - analyze file types + const extensions = files.map(file => detectFileExtensionUtil(file.name)); + const uniqueExtensions = [...new Set(extensions)]; + + if (uniqueExtensions.length === 1) { + // All files are the same type - use regular detection with smart target selection + const detectedExt = uniqueExtensions[0]; + let fromExt = detectedExt; + let availableTargets = CONVERSION_MATRIX[detectedExt] || []; + + // If no explicit conversion exists for this file type, fall back to 'any' + if (availableTargets.length === 0) { + fromExt = 'any'; + availableTargets = CONVERSION_MATRIX['any'] || []; + } + + setParameters(prev => { + // Check if current toExtension is still valid for the new fromExtension + const currentToExt = prev.toExtension; + const isCurrentToExtValid = availableTargets.includes(currentToExt); + + // Auto-select target only if: + // 1. No current target is set, OR + // 2. Current target is invalid for new source type, OR + // 3. There's only one possible target (forced conversion) + let newToExtension = currentToExt; + if (!currentToExt || !isCurrentToExtValid) { + newToExtension = availableTargets.length === 1 ? availableTargets[0] : ''; + } + + return { + ...prev, + isSmartDetection: false, + smartDetectionType: 'none', + fromExtension: fromExt, + toExtension: newToExtension + }; + }); + } else { + // Mixed file types + const allImages = uniqueExtensions.every(ext => isImageFormat(ext)); + const allWeb = uniqueExtensions.every(ext => isWebFormat(ext)); + + if (allImages) { + // All files are images - use image-to-pdf conversion + setParameters(prev => ({ + ...prev, + isSmartDetection: true, + smartDetectionType: 'images', + fromExtension: 'image', + toExtension: 'pdf' + })); + } else if (allWeb) { + // All files are web files - use html-to-pdf conversion + setParameters(prev => ({ + ...prev, + isSmartDetection: true, + smartDetectionType: 'web', + fromExtension: 'html', + toExtension: 'pdf' + })); + } else { + // Mixed non-image types - use file-to-pdf conversion + setParameters(prev => ({ + ...prev, + isSmartDetection: true, + smartDetectionType: 'mixed', + fromExtension: 'any', + toExtension: 'pdf' + })); + } + } + }; + + return { + parameters, + updateParameter, + resetParameters, + validateParameters, + getEndpointName, + getEndpoint, + getAvailableToExtensions, + analyzeFileTypes, + }; +}; \ No newline at end of file diff --git a/frontend/src/hooks/tools/convert/useConvertParametersAutoDetection.test.ts b/frontend/src/hooks/tools/convert/useConvertParametersAutoDetection.test.ts new file mode 100644 index 000000000..4552a4546 --- /dev/null +++ b/frontend/src/hooks/tools/convert/useConvertParametersAutoDetection.test.ts @@ -0,0 +1,365 @@ +/** + * Tests for auto-detection and smart conversion features in useConvertParameters + * This covers the analyzeFileTypes function and related smart detection logic + */ + +import { describe, test, expect } from 'vitest'; +import { renderHook, act, waitFor } from '@testing-library/react'; +import { useConvertParameters } from './useConvertParameters'; + +describe('useConvertParameters - Auto Detection & Smart Conversion', () => { + + describe('Single File Detection', () => { + + test('should detect single file extension and set auto-target', () => { + const { result } = renderHook(() => useConvertParameters()); + + const pdfFile = [{ name: 'document.pdf' }]; + + act(() => { + result.current.analyzeFileTypes(pdfFile); + }); + + expect(result.current.parameters.fromExtension).toBe('pdf'); + expect(result.current.parameters.toExtension).toBe(''); // No auto-selection for multiple targets + expect(result.current.parameters.isSmartDetection).toBe(false); + expect(result.current.parameters.smartDetectionType).toBe('none'); + }); + + test('should handle unknown file types with file-to-pdf fallback', () => { + const { result } = renderHook(() => useConvertParameters()); + + const unknownFile = [{ name: 'document.xyz' }, { name: 'image.jpggg' }]; + + act(() => { + result.current.analyzeFileTypes(unknownFile); + }); + + expect(result.current.parameters.fromExtension).toBe('any'); + expect(result.current.parameters.toExtension).toBe('pdf'); // Fallback to file-to-pdf + expect(result.current.parameters.isSmartDetection).toBe(true); + }); + + test('should handle files without extensions', () => { + const { result } = renderHook(() => useConvertParameters()); + + const noExtFile = [{ name: 'document' }]; + + act(() => { + result.current.analyzeFileTypes(noExtFile); + }); + + expect(result.current.parameters.fromExtension).toBe('any'); + expect(result.current.parameters.toExtension).toBe('pdf'); // Fallback to file-to-pdf + }); + + + }); + + describe('Multiple Identical Files', () => { + + test('should detect multiple PDF files and set auto-target', () => { + const { result } = renderHook(() => useConvertParameters()); + + const pdfFiles = [ + { name: 'doc1.pdf' }, + { name: 'doc2.pdf' }, + { name: 'doc3.pdf' } + ]; + + act(() => { + result.current.analyzeFileTypes(pdfFiles); + }); + + expect(result.current.parameters.fromExtension).toBe('pdf'); + expect(result.current.parameters.toExtension).toBe(''); // Auto-selected + expect(result.current.parameters.isSmartDetection).toBe(false); + expect(result.current.parameters.smartDetectionType).toBe('none'); + }); + + test('should handle multiple unknown file types with fallback', () => { + const { result } = renderHook(() => useConvertParameters()); + + const unknownFiles = [ + { name: 'file1.xyz' }, + { name: 'file2.xyz' } + ]; + + act(() => { + result.current.analyzeFileTypes(unknownFiles); + }); + + expect(result.current.parameters.fromExtension).toBe('any'); + expect(result.current.parameters.toExtension).toBe('pdf'); + expect(result.current.parameters.isSmartDetection).toBe(false); + }); + }); + + describe('Smart Detection - All Images', () => { + + test('should detect all image files and enable smart detection', () => { + const { result } = renderHook(() => useConvertParameters()); + + const imageFiles = [ + { name: 'photo1.jpg' }, + { name: 'photo2.png' }, + { name: 'photo3.gif' } + ]; + + act(() => { + result.current.analyzeFileTypes(imageFiles); + }); + + expect(result.current.parameters.fromExtension).toBe('image'); + expect(result.current.parameters.toExtension).toBe('pdf'); + expect(result.current.parameters.isSmartDetection).toBe(true); + expect(result.current.parameters.smartDetectionType).toBe('images'); + }); + + test('should handle mixed case image extensions', () => { + const { result } = renderHook(() => useConvertParameters()); + + const imageFiles = [ + { name: 'photo1.JPG' }, + { name: 'photo2.PNG' } + ]; + + act(() => { + result.current.analyzeFileTypes(imageFiles); + }); + + expect(result.current.parameters.isSmartDetection).toBe(true); + expect(result.current.parameters.smartDetectionType).toBe('images'); + }); + }); + + describe('Smart Detection - All Web Files', () => { + + test('should detect all web files and enable web smart detection', () => { + const { result } = renderHook(() => useConvertParameters()); + + const webFiles = [ + { name: 'page1.html' }, + { name: 'archive.zip' } + ]; + + act(() => { + result.current.analyzeFileTypes(webFiles); + }); + + expect(result.current.parameters.fromExtension).toBe('html'); + expect(result.current.parameters.toExtension).toBe('pdf'); + expect(result.current.parameters.isSmartDetection).toBe(true); + expect(result.current.parameters.smartDetectionType).toBe('web'); + }); + + test('should handle mixed case web extensions', () => { + const { result } = renderHook(() => useConvertParameters()); + + const webFiles = [ + { name: 'page1.HTML' }, + { name: 'archive.ZIP' } + ]; + + act(() => { + result.current.analyzeFileTypes(webFiles); + }); + + expect(result.current.parameters.isSmartDetection).toBe(true); + expect(result.current.parameters.smartDetectionType).toBe('web'); + }); + + test('should detect multiple web files and enable web smart detection', () => { + const { result } = renderHook(() => useConvertParameters()); + + const zipFiles = [ + { name: 'site1.zip' }, + { name: 'site2.html' } + ]; + + act(() => { + result.current.analyzeFileTypes(zipFiles); + }); + + expect(result.current.parameters.fromExtension).toBe('html'); + expect(result.current.parameters.toExtension).toBe('pdf'); + expect(result.current.parameters.isSmartDetection).toBe(true); + expect(result.current.parameters.smartDetectionType).toBe('web'); + }); + }); + + describe('Smart Detection - Mixed File Types', () => { + + test('should detect mixed file types and enable smart detection', () => { + const { result } = renderHook(() => useConvertParameters()); + + const mixedFiles = [ + { name: 'document.pdf' }, + { name: 'spreadsheet.xlsx' }, + { name: 'presentation.pptx' } + ]; + + act(() => { + result.current.analyzeFileTypes(mixedFiles); + }); + + expect(result.current.parameters.fromExtension).toBe('any'); + expect(result.current.parameters.toExtension).toBe('pdf'); + expect(result.current.parameters.isSmartDetection).toBe(true); + expect(result.current.parameters.smartDetectionType).toBe('mixed'); + }); + + test('should detect mixed images and documents as mixed type', () => { + const { result } = renderHook(() => useConvertParameters()); + + const mixedFiles = [ + { name: 'photo.jpg' }, + { name: 'document.pdf' }, + { name: 'text.txt' } + ]; + + act(() => { + result.current.analyzeFileTypes(mixedFiles); + }); + + expect(result.current.parameters.isSmartDetection).toBe(true); + expect(result.current.parameters.smartDetectionType).toBe('mixed'); + }); + + test('should handle mixed with unknown file types', () => { + const { result } = renderHook(() => useConvertParameters()); + + const mixedFiles = [ + { name: 'document.pdf' }, + { name: 'unknown.xyz' }, + { name: 'noextension' } + ]; + + act(() => { + result.current.analyzeFileTypes(mixedFiles); + }); + + expect(result.current.parameters.isSmartDetection).toBe(true); + expect(result.current.parameters.smartDetectionType).toBe('mixed'); + }); + }); + + describe('Smart Detection Endpoint Resolution', () => { + + test('should return correct endpoint for image smart detection', () => { + const { result } = renderHook(() => useConvertParameters()); + + const imageFiles = [ + { name: 'photo1.jpg' }, + { name: 'photo2.png' } + ]; + + act(() => { + result.current.analyzeFileTypes(imageFiles); + }); + + expect(result.current.getEndpointName()).toBe('img-to-pdf'); + expect(result.current.getEndpoint()).toBe('/api/v1/convert/img/pdf'); + }); + + test('should return correct endpoint for web smart detection', () => { + const { result } = renderHook(() => useConvertParameters()); + + const webFiles = [ + { name: 'page1.html' }, + { name: 'archive.zip' } + ]; + + act(() => { + result.current.analyzeFileTypes(webFiles); + }); + + expect(result.current.getEndpointName()).toBe('html-to-pdf'); + expect(result.current.getEndpoint()).toBe('/api/v1/convert/html/pdf'); + }); + + test('should return correct endpoint for mixed smart detection', () => { + const { result } = renderHook(() => useConvertParameters()); + + const mixedFiles = [ + { name: 'document.pdf' }, + { name: 'spreadsheet.xlsx' } + ]; + + act(() => { + result.current.analyzeFileTypes(mixedFiles); + }); + + expect(result.current.getEndpointName()).toBe('file-to-pdf'); + expect(result.current.getEndpoint()).toBe('/api/v1/convert/file/pdf'); + }); + }); + + describe('Auto-Target Selection Logic', () => { + + test('should select single available target automatically', () => { + const { result } = renderHook(() => useConvertParameters()); + + // Markdown has only one conversion target (PDF) + const mdFile = [{ name: 'readme.md' }]; + + act(() => { + result.current.analyzeFileTypes(mdFile); + }); + + expect(result.current.parameters.fromExtension).toBe('md'); + expect(result.current.parameters.toExtension).toBe('pdf'); // Only available target + }); + + test('should not auto-select when multiple targets available', () => { + const { result } = renderHook(() => useConvertParameters()); + + // PDF has multiple conversion targets, so no auto-selection + const pdfFile = [{ name: 'document.pdf' }]; + + act(() => { + result.current.analyzeFileTypes(pdfFile); + }); + + expect(result.current.parameters.fromExtension).toBe('pdf'); + // Should NOT auto-select when multiple targets available + expect(result.current.parameters.toExtension).toBe(''); + }); + }); + + describe('Edge Cases', () => { + + test('should handle empty file names', () => { + const { result } = renderHook(() => useConvertParameters()); + + const emptyFiles = [{ name: '' }]; + + act(() => { + result.current.analyzeFileTypes(emptyFiles); + }); + + expect(result.current.parameters.fromExtension).toBe('any'); + expect(result.current.parameters.toExtension).toBe('pdf'); + }); + + test('should handle malformed file objects', () => { + const { result } = renderHook(() => useConvertParameters()); + + const malformedFiles = [ + { name: 'valid.pdf' }, + // @ts-ignore - Testing runtime resilience + { name: null }, + // @ts-ignore + { name: undefined } + ]; + + act(() => { + result.current.analyzeFileTypes(malformedFiles); + }); + + // Should still process the valid file and handle gracefully + expect(result.current.parameters.isSmartDetection).toBe(true); + expect(result.current.parameters.smartDetectionType).toBe('mixed'); + }); + }); +}); \ No newline at end of file diff --git a/frontend/src/hooks/tools/ocr/useOCROperation.ts b/frontend/src/hooks/tools/ocr/useOCROperation.ts new file mode 100644 index 000000000..316b867d8 --- /dev/null +++ b/frontend/src/hooks/tools/ocr/useOCROperation.ts @@ -0,0 +1,117 @@ +import { useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; +import { OCRParameters } from '../../../components/tools/ocr/OCRSettings'; +import { useToolOperation, ToolOperationConfig } from '../shared/useToolOperation'; +import { createStandardErrorHandler } from '../../../utils/toolErrorHandler'; +import { useToolResources } from '../shared/useToolResources'; + +// Helper: get MIME type based on file extension +function getMimeType(filename: string): string { + const ext = filename.toLowerCase().split('.').pop(); + switch (ext) { + case 'pdf': return 'application/pdf'; + case 'txt': return 'text/plain'; + case 'zip': return 'application/zip'; + default: return 'application/octet-stream'; + } +} + +// Lightweight ZIP extractor (keep or replace with a shared util if you have one) +async function extractZipFile(zipBlob: Blob): Promise { + const JSZip = await import('jszip'); + const zip = new JSZip.default(); + const zipContent = await zip.loadAsync(await zipBlob.arrayBuffer()); + const out: File[] = []; + for (const [filename, file] of Object.entries(zipContent.files)) { + if (!file.dir) { + const content = await file.async('blob'); + out.push(new File([content], filename, { type: getMimeType(filename) })); + } + } + return out; +} + +// Helper: strip extension +function stripExt(name: string): string { + const i = name.lastIndexOf('.'); + return i > 0 ? name.slice(0, i) : name; +} + +// Signature must be (file, params) +const buildFormData = (file: File, parameters: OCRParameters): FormData => { + const formData = new FormData(); + formData.append('fileInput', file); + parameters.languages.forEach((lang) => formData.append('languages', lang)); + formData.append('ocrType', parameters.ocrType); + formData.append('ocrRenderType', parameters.ocrRenderType); + formData.append('sidecar', parameters.additionalOptions.includes('sidecar').toString()); + formData.append('deskew', parameters.additionalOptions.includes('deskew').toString()); + formData.append('clean', parameters.additionalOptions.includes('clean').toString()); + formData.append('cleanFinal', parameters.additionalOptions.includes('cleanFinal').toString()); + formData.append('removeImagesAfter', parameters.additionalOptions.includes('removeImagesAfter').toString()); + return formData; +}; + +export const useOCROperation = () => { + const { t } = useTranslation(); + const { extractZipFiles } = useToolResources(); + + // OCR-specific parsing: ZIP (sidecar) vs PDF vs HTML error + const responseHandler = useCallback(async (blob: Blob, originalFiles: File[]): Promise => { + const headBuf = await blob.slice(0, 8).arrayBuffer(); + const head = new TextDecoder().decode(new Uint8Array(headBuf)); + + // ZIP: sidecar or multi-asset output + if (head.startsWith('PK')) { + const base = stripExt(originalFiles[0].name); + try { + const extracted = await extractZipFiles(blob); + if (extracted.length > 0) return extracted; + } catch { /* ignore and try local extractor */ } + try { + const local = await extractZipFile(blob); // local fallback + if (local.length > 0) return local; + } catch { /* fall through */ } + return [new File([blob], `ocr_${base}.zip`, { type: 'application/zip' })]; + } + + // Not a PDF: surface error details if present + if (!head.startsWith('%PDF')) { + const textBuf = await blob.slice(0, 1024).arrayBuffer(); + const text = new TextDecoder().decode(new Uint8Array(textBuf)); + if (/error|exception|html/i.test(text)) { + if (text.includes('OCR tools') && text.includes('not installed')) { + throw new Error('OCR tools (OCRmyPDF or Tesseract) are not installed on the server. Use the standard or fat Docker image instead of ultra-lite, or install OCR tools manually.'); + } + const title = + text.match(/]*>([^<]+)<\/title>/i)?.[1] || + text.match(/]*>([^<]+)<\/h1>/i)?.[1] || + t('ocr.error.unknown', 'Unknown error'); + throw new Error(`OCR service error: ${title}`); + } + throw new Error(`Response is not a valid PDF. Header: "${head}"`); + } + + const base = stripExt(originalFiles[0].name); + return [new File([blob], `ocr_${base}.pdf`, { type: 'application/pdf' })]; + }, [t, extractZipFiles]); + + const ocrConfig: ToolOperationConfig = { + operationType: 'ocr', + endpoint: '/api/v1/misc/ocr-pdf', + buildFormData, + filePrefix: 'ocr_', + multiFileEndpoint: false, // Process files individually + responseHandler, // use shared flow + validateParams: (params) => + params.languages.length === 0 + ? { valid: false, errors: [t('ocr.validation.languageRequired', 'Please select at least one language for OCR processing.')] } + : { valid: true }, + getErrorMessage: (error) => + error.message?.includes('OCR tools') && error.message?.includes('not installed') + ? 'OCR tools (OCRmyPDF or Tesseract) are not installed on the server. Use the standard or fat Docker image instead of ultra-lite, or install OCR tools manually.' + : createStandardErrorHandler(t('ocr.error.failed', 'OCR operation failed'))(error), + }; + + return useToolOperation(ocrConfig); +}; diff --git a/frontend/src/hooks/tools/ocr/useOCRParameters.ts b/frontend/src/hooks/tools/ocr/useOCRParameters.ts new file mode 100644 index 000000000..23702cdce --- /dev/null +++ b/frontend/src/hooks/tools/ocr/useOCRParameters.ts @@ -0,0 +1,43 @@ +import { useState } from 'react'; +import { OCRParameters } from '../../../components/tools/ocr/OCRSettings'; + +export interface OCRParametersHook { + parameters: OCRParameters; + updateParameter: (key: keyof OCRParameters, value: any) => void; + resetParameters: () => void; + validateParameters: () => boolean; +} + +const defaultParameters: OCRParameters = { + languages: [], + ocrType: 'skip-text', + ocrRenderType: 'hocr', + additionalOptions: [], +}; + +export const useOCRParameters = (): OCRParametersHook => { + const [parameters, setParameters] = useState(defaultParameters); + + const updateParameter = (key: keyof OCRParameters, value: any) => { + setParameters(prev => ({ + ...prev, + [key]: value + })); + }; + + const resetParameters = () => { + setParameters(defaultParameters); + }; + + const validateParameters = () => { + // At minimum, we need at least one language selected + return parameters.languages.length > 0; + }; + + return { + parameters, + updateParameter, + resetParameters, + validateParameters, + }; +}; \ No newline at end of file diff --git a/frontend/src/hooks/tools/shared/useOperationResults.ts b/frontend/src/hooks/tools/shared/useOperationResults.ts new file mode 100644 index 000000000..fca4f922a --- /dev/null +++ b/frontend/src/hooks/tools/shared/useOperationResults.ts @@ -0,0 +1,67 @@ +import { useState, useCallback } from 'react'; + +export interface OperationResult { + files: File[]; + thumbnails: string[]; + isGeneratingThumbnails: boolean; +} + +export interface OperationResultsHook { + results: OperationResult; + downloadUrl: string | null; + status: string; + errorMessage: string | null; + isLoading: boolean; + + setResults: (results: OperationResult) => void; + setDownloadUrl: (url: string | null) => void; + setStatus: (status: string) => void; + setErrorMessage: (error: string | null) => void; + setIsLoading: (loading: boolean) => void; + + resetResults: () => void; + clearError: () => void; +} + +const initialResults: OperationResult = { + files: [], + thumbnails: [], + isGeneratingThumbnails: false, +}; + +export const useOperationResults = (): OperationResultsHook => { + const [results, setResults] = useState(initialResults); + const [downloadUrl, setDownloadUrl] = useState(null); + const [status, setStatus] = useState(''); + const [errorMessage, setErrorMessage] = useState(null); + const [isLoading, setIsLoading] = useState(false); + + const resetResults = useCallback(() => { + setResults(initialResults); + setDownloadUrl(null); + setStatus(''); + setErrorMessage(null); + setIsLoading(false); + }, []); + + const clearError = useCallback(() => { + setErrorMessage(null); + }, []); + + return { + results, + downloadUrl, + status, + errorMessage, + isLoading, + + setResults, + setDownloadUrl, + setStatus, + setErrorMessage, + setIsLoading, + + resetResults, + clearError, + }; +}; \ No newline at end of file diff --git a/frontend/src/hooks/tools/shared/useToolApiCalls.ts b/frontend/src/hooks/tools/shared/useToolApiCalls.ts new file mode 100644 index 000000000..88f1f4d31 --- /dev/null +++ b/frontend/src/hooks/tools/shared/useToolApiCalls.ts @@ -0,0 +1,86 @@ +import { useCallback, useRef } from 'react'; +import axios, { CancelTokenSource } from 'axios'; +import { processResponse } from '../../../utils/toolResponseProcessor'; +import type { ResponseHandler, ProcessingProgress } from './useToolState'; + +export interface ApiCallsConfig { + endpoint: string | ((params: TParams) => string); + buildFormData: (file: File, params: TParams) => FormData; + filePrefix: string; + responseHandler?: ResponseHandler; +} + +export const useToolApiCalls = () => { + const cancelTokenRef = useRef(null); + + const processFiles = useCallback(async ( + params: TParams, + validFiles: File[], + config: ApiCallsConfig, + onProgress: (progress: ProcessingProgress) => void, + onStatus: (status: string) => void + ): Promise => { + const processedFiles: File[] = []; + const failedFiles: string[] = []; + const total = validFiles.length; + + // Create cancel token for this operation + cancelTokenRef.current = axios.CancelToken.source(); + + for (let i = 0; i < validFiles.length; i++) { + const file = validFiles[i]; + + onProgress({ current: i + 1, total, currentFileName: file.name }); + onStatus(`Processing ${file.name} (${i + 1}/${total})`); + + try { + const formData = config.buildFormData(file, params); + const endpoint = typeof config.endpoint === 'function' ? config.endpoint(params) : config.endpoint; + const response = await axios.post(endpoint, formData, { + responseType: 'blob', + cancelToken: cancelTokenRef.current.token, + }); + + // Forward to shared response processor (uses tool-specific responseHandler if provided) + const responseFiles = await processResponse( + response.data, + [file], + config.filePrefix, + config.responseHandler + ); + processedFiles.push(...responseFiles); + + } catch (error) { + if (axios.isCancel(error)) { + throw new Error('Operation was cancelled'); + } + console.error(`Failed to process ${file.name}:`, error); + failedFiles.push(file.name); + } + } + + if (failedFiles.length > 0 && processedFiles.length === 0) { + throw new Error(`Failed to process all files: ${failedFiles.join(', ')}`); + } + + if (failedFiles.length > 0) { + onStatus(`Processed ${processedFiles.length}/${total} files. Failed: ${failedFiles.join(', ')}`); + } else { + onStatus(`Successfully processed ${processedFiles.length} file${processedFiles.length === 1 ? '' : 's'}`); + } + + return processedFiles; + }, []); + + const cancelOperation = useCallback(() => { + if (cancelTokenRef.current) { + cancelTokenRef.current.cancel('Operation cancelled by user'); + cancelTokenRef.current = null; + } + }, []); + + return { + processFiles, + cancelOperation, + }; +}; diff --git a/frontend/src/hooks/tools/shared/useToolOperation.ts b/frontend/src/hooks/tools/shared/useToolOperation.ts new file mode 100644 index 000000000..7251d1fd2 --- /dev/null +++ b/frontend/src/hooks/tools/shared/useToolOperation.ts @@ -0,0 +1,264 @@ +import { useCallback } from 'react'; +import axios from 'axios'; +import { useTranslation } from 'react-i18next'; +import { useFileContext } from '../../../contexts/FileContext'; +import { useToolState, type ProcessingProgress } from './useToolState'; +import { useToolApiCalls, type ApiCallsConfig } from './useToolApiCalls'; +import { useToolResources } from './useToolResources'; +import { extractErrorMessage } from '../../../utils/toolErrorHandler'; +import { createOperation } from '../../../utils/toolOperationTracker'; +import { type ResponseHandler, processResponse } from '../../../utils/toolResponseProcessor'; + +export interface ValidationResult { + valid: boolean; + errors?: string[]; +} + +// Re-export for backwards compatibility +export type { ProcessingProgress, ResponseHandler }; + +/** + * Configuration for tool operations defining processing behavior and API integration. + * + * Supports three patterns: + * 1. Single-file tools: multiFileEndpoint: false, processes files individually + * 2. Multi-file tools: multiFileEndpoint: true, single API call with all files + * 3. Complex tools: customProcessor handles all processing logic + */ +export interface ToolOperationConfig { + /** Operation identifier for tracking and logging */ + operationType: string; + + /** + * API endpoint for the operation. Can be static string or function for dynamic routing. + * Not used when customProcessor is provided. + */ + endpoint: string | ((params: TParams) => string); + + /** + * Builds FormData for API request. Signature determines processing approach: + * - (params, file: File) => FormData: Single-file processing + * - (params, files: File[]) => FormData: Multi-file processing + * Not used when customProcessor is provided. + */ + buildFormData: ((params: TParams, file: File) => FormData) | ((params: TParams, files: File[]) => FormData); + + /** Prefix added to processed filenames (e.g., 'compressed_', 'split_') */ + filePrefix: string; + + /** + * Whether this tool uses backends that accept MultipartFile[] arrays. + * - true: Single API call with all files (backend uses MultipartFile[]) + * - false/undefined: Individual API calls per file (backend uses single MultipartFile) + * Ignored when customProcessor is provided. + */ + multiFileEndpoint?: boolean; + + /** How to handle API responses (e.g., ZIP extraction, single file response) */ + responseHandler?: ResponseHandler; + + /** + * Custom processing logic that completely bypasses standard file processing. + * When provided, tool handles all API calls, response processing, and file creation. + * Use for tools with complex routing logic or non-standard processing requirements. + */ + customProcessor?: (params: TParams, files: File[]) => Promise; + + /** Validate parameters before execution. Return validation errors if invalid. */ + validateParams?: (params: TParams) => ValidationResult; + + /** Extract user-friendly error messages from API errors */ + getErrorMessage?: (error: any) => string; +} + +/** + * Complete tool operation interface with execution capability + */ +export interface ToolOperationHook { + // State + files: File[]; + thumbnails: string[]; + isGeneratingThumbnails: boolean; + downloadUrl: string | null; + downloadFilename: string; + isLoading: boolean; + status: string; + errorMessage: string | null; + progress: ProcessingProgress | null; + + // Actions + executeOperation: (params: TParams, selectedFiles: File[]) => Promise; + resetResults: () => void; + clearError: () => void; + cancelOperation: () => void; +} + +// Re-export for backwards compatibility +export { createStandardErrorHandler } from '../../../utils/toolErrorHandler'; + +/** + * Shared hook for tool operations providing consistent error handling, progress tracking, + * and FileContext integration. Eliminates boilerplate while maintaining flexibility. + * + * Supports three tool patterns: + * 1. Single-file tools: Set multiFileEndpoint: false, processes files individually + * 2. Multi-file tools: Set multiFileEndpoint: true, single API call with all files + * 3. Complex tools: Provide customProcessor for full control over processing logic + * + * @param config - Tool operation configuration + * @returns Hook interface with state and execution methods + */ +export const useToolOperation = ( + config: ToolOperationConfig +): ToolOperationHook => { + const { t } = useTranslation(); + const { recordOperation, markOperationApplied, markOperationFailed, addFiles } = useFileContext(); + + // Composed hooks + const { state, actions } = useToolState(); + const { processFiles, cancelOperation: cancelApiCalls } = useToolApiCalls(); + const { generateThumbnails, createDownloadInfo, cleanupBlobUrls, extractZipFiles, extractAllZipFiles } = useToolResources(); + + const executeOperation = useCallback(async ( + params: TParams, + selectedFiles: File[] + ): Promise => { + // Validation + if (selectedFiles.length === 0) { + actions.setError(t('noFileSelected', 'No files selected')); + return; + } + + if (config.validateParams) { + const validation = config.validateParams(params); + if (!validation.valid) { + actions.setError(validation.errors?.join(', ') || 'Invalid parameters'); + return; + } + } + + const validFiles = selectedFiles.filter(file => file.size > 0); + if (validFiles.length === 0) { + actions.setError(t('noValidFiles', 'No valid files to process')); + return; + } + + // Setup operation tracking + const { operation, operationId, fileId } = createOperation(config.operationType, params, selectedFiles); + recordOperation(fileId, operation); + + // Reset state + actions.setLoading(true); + actions.setError(null); + actions.resetResults(); + cleanupBlobUrls(); + + try { + let processedFiles: File[]; + + if (config.customProcessor) { + actions.setStatus('Processing files...'); + processedFiles = await config.customProcessor(params, validFiles); + } else { + // Use explicit multiFileEndpoint flag to determine processing approach + if (config.multiFileEndpoint) { + // Multi-file processing - single API call with all files + actions.setStatus('Processing files...'); + const formData = (config.buildFormData as (params: TParams, files: File[]) => FormData)(params, validFiles); + const endpoint = typeof config.endpoint === 'function' ? config.endpoint(params) : config.endpoint; + + const response = await axios.post(endpoint, formData, { responseType: 'blob' }); + + // Multi-file responses are typically ZIP files that need extraction + if (config.responseHandler) { + // Use custom responseHandler for multi-file (handles ZIP extraction) + processedFiles = await config.responseHandler(response.data, validFiles); + } else { + // Default: assume ZIP response for multi-file endpoints + processedFiles = await extractZipFiles(response.data); + + if (processedFiles.length === 0) { + // Try the generic extraction as fallback + processedFiles = await extractAllZipFiles(response.data); + } + } + } else { + // Individual file processing - separate API call per file + const apiCallsConfig: ApiCallsConfig = { + endpoint: config.endpoint, + buildFormData: (file: File, params: TParams) => (config.buildFormData as (file: File, params: TParams) => FormData)(file, params), + filePrefix: config.filePrefix, + responseHandler: config.responseHandler + }; + processedFiles = await processFiles( + params, + validFiles, + apiCallsConfig, + actions.setProgress, + actions.setStatus + ); + } + } + + if (processedFiles.length > 0) { + actions.setFiles(processedFiles); + + // Generate thumbnails and download URL concurrently + actions.setGeneratingThumbnails(true); + const [thumbnails, downloadInfo] = await Promise.all([ + generateThumbnails(processedFiles), + createDownloadInfo(processedFiles, config.operationType) + ]); + actions.setGeneratingThumbnails(false); + + actions.setThumbnails(thumbnails); + actions.setDownloadInfo(downloadInfo.url, downloadInfo.filename); + + // Add to file context + await addFiles(processedFiles); + + markOperationApplied(fileId, operationId); + } + + } catch (error: any) { + const errorMessage = config.getErrorMessage?.(error) || extractErrorMessage(error); + actions.setError(errorMessage); + actions.setStatus(''); + markOperationFailed(fileId, operationId, errorMessage); + } finally { + actions.setLoading(false); + actions.setProgress(null); + } + }, [t, config, actions, recordOperation, markOperationApplied, markOperationFailed, addFiles, processFiles, generateThumbnails, createDownloadInfo, cleanupBlobUrls, extractZipFiles, extractAllZipFiles]); + + const cancelOperation = useCallback(() => { + cancelApiCalls(); + actions.setLoading(false); + actions.setProgress(null); + actions.setStatus('Operation cancelled'); + }, [cancelApiCalls, actions]); + + const resetResults = useCallback(() => { + cleanupBlobUrls(); + actions.resetResults(); + }, [cleanupBlobUrls, actions]); + + return { + // State + files: state.files, + thumbnails: state.thumbnails, + isGeneratingThumbnails: state.isGeneratingThumbnails, + downloadUrl: state.downloadUrl, + downloadFilename: state.downloadFilename, + isLoading: state.isLoading, + status: state.status, + errorMessage: state.errorMessage, + progress: state.progress, + + // Actions + executeOperation, + resetResults, + clearError: actions.clearError, + cancelOperation + }; +}; diff --git a/frontend/src/hooks/tools/shared/useToolResources.ts b/frontend/src/hooks/tools/shared/useToolResources.ts new file mode 100644 index 000000000..69f48fe20 --- /dev/null +++ b/frontend/src/hooks/tools/shared/useToolResources.ts @@ -0,0 +1,114 @@ +import { useState, useCallback, useEffect } from 'react'; +import { generateThumbnailForFile } from '../../../utils/thumbnailUtils'; +import { zipFileService } from '../../../services/zipFileService'; + + +export const useToolResources = () => { + const [blobUrls, setBlobUrls] = useState([]); + + const addBlobUrl = useCallback((url: string) => { + setBlobUrls(prev => [...prev, url]); + }, []); + + const cleanupBlobUrls = useCallback(() => { + blobUrls.forEach(url => { + try { + URL.revokeObjectURL(url); + } catch (error) { + console.warn('Failed to revoke blob URL:', error); + } + }); + setBlobUrls([]); + }, [blobUrls]); + + // Cleanup on unmount + useEffect(() => { + return () => { + blobUrls.forEach(url => { + try { + URL.revokeObjectURL(url); + } catch (error) { + console.warn('Failed to revoke blob URL during cleanup:', error); + } + }); + }; + }, [blobUrls]); + + const generateThumbnails = useCallback(async (files: File[]): Promise => { + const thumbnails: string[] = []; + + for (const file of files) { + try { + const thumbnail = await generateThumbnailForFile(file); + thumbnails.push(thumbnail); + } catch (error) { + console.warn(`Failed to generate thumbnail for ${file.name}:`, error); + thumbnails.push(''); + } + } + + return thumbnails; + }, []); + + const extractZipFiles = useCallback(async (zipBlob: Blob): Promise => { + try { + const zipFile = new File([zipBlob], 'temp.zip', { type: 'application/zip' }); + const extractionResult = await zipFileService.extractPdfFiles(zipFile); + return extractionResult.success ? extractionResult.extractedFiles : []; + } catch (error) { + console.error('useToolResources.extractZipFiles - Error:', error); + return []; + } + }, []); + + const extractAllZipFiles = useCallback(async (zipBlob: Blob): Promise => { + try { + const JSZip = (await import('jszip')).default; + const zip = new JSZip(); + + const arrayBuffer = await zipBlob.arrayBuffer(); + const zipContent = await zip.loadAsync(arrayBuffer); + + const extractedFiles: File[] = []; + + for (const [filename, file] of Object.entries(zipContent.files)) { + if (!file.dir) { + const content = await file.async('blob'); + const extractedFile = new File([content], filename, { type: 'application/pdf' }); + extractedFiles.push(extractedFile); + } + } + + return extractedFiles; + } catch (error) { + console.error('Error in extractAllZipFiles:', error); + return []; + } + }, []); + + const createDownloadInfo = useCallback(async ( + files: File[], + operationType: string + ): Promise<{ url: string; filename: string }> => { + if (files.length === 1) { + const url = URL.createObjectURL(files[0]); + addBlobUrl(url); + return { url, filename: files[0].name }; + } + + // Multiple files - create zip using shared service + const { zipFile } = await zipFileService.createZipFromFiles(files, `${operationType}_results.zip`); + const url = URL.createObjectURL(zipFile); + addBlobUrl(url); + + return { url, filename: zipFile.name }; + }, [addBlobUrl]); + + return { + generateThumbnails, + createDownloadInfo, + extractZipFiles, + extractAllZipFiles, + cleanupBlobUrls, + }; +}; \ No newline at end of file diff --git a/frontend/src/hooks/tools/shared/useToolState.ts b/frontend/src/hooks/tools/shared/useToolState.ts new file mode 100644 index 000000000..196a05e72 --- /dev/null +++ b/frontend/src/hooks/tools/shared/useToolState.ts @@ -0,0 +1,137 @@ +import { useReducer, useCallback } from 'react'; + +export interface ProcessingProgress { + current: number; + total: number; + currentFileName?: string; +} + +export interface OperationState { + files: File[]; + thumbnails: string[]; + isGeneratingThumbnails: boolean; + downloadUrl: string | null; + downloadFilename: string; + isLoading: boolean; + status: string; + errorMessage: string | null; + progress: ProcessingProgress | null; +} + +type OperationAction = + | { type: 'SET_LOADING'; payload: boolean } + | { type: 'SET_FILES'; payload: File[] } + | { type: 'SET_THUMBNAILS'; payload: string[] } + | { type: 'SET_GENERATING_THUMBNAILS'; payload: boolean } + | { type: 'SET_DOWNLOAD_INFO'; payload: { url: string | null; filename: string } } + | { type: 'SET_STATUS'; payload: string } + | { type: 'SET_ERROR'; payload: string | null } + | { type: 'SET_PROGRESS'; payload: ProcessingProgress | null } + | { type: 'RESET_RESULTS' } + | { type: 'CLEAR_ERROR' }; + +const initialState: OperationState = { + files: [], + thumbnails: [], + isGeneratingThumbnails: false, + downloadUrl: null, + downloadFilename: '', + isLoading: false, + status: '', + errorMessage: null, + progress: null, +}; + +const operationReducer = (state: OperationState, action: OperationAction): OperationState => { + switch (action.type) { + case 'SET_LOADING': + return { ...state, isLoading: action.payload }; + case 'SET_FILES': + return { ...state, files: action.payload }; + case 'SET_THUMBNAILS': + return { ...state, thumbnails: action.payload }; + case 'SET_GENERATING_THUMBNAILS': + return { ...state, isGeneratingThumbnails: action.payload }; + case 'SET_DOWNLOAD_INFO': + return { + ...state, + downloadUrl: action.payload.url, + downloadFilename: action.payload.filename + }; + case 'SET_STATUS': + return { ...state, status: action.payload }; + case 'SET_ERROR': + return { ...state, errorMessage: action.payload }; + case 'SET_PROGRESS': + return { ...state, progress: action.payload }; + case 'RESET_RESULTS': + return { + ...initialState, + isLoading: state.isLoading, // Preserve loading state during reset + }; + case 'CLEAR_ERROR': + return { ...state, errorMessage: null }; + default: + return state; + } +}; + +export const useToolState = () => { + const [state, dispatch] = useReducer(operationReducer, initialState); + + const setLoading = useCallback((loading: boolean) => { + dispatch({ type: 'SET_LOADING', payload: loading }); + }, []); + + const setFiles = useCallback((files: File[]) => { + dispatch({ type: 'SET_FILES', payload: files }); + }, []); + + const setThumbnails = useCallback((thumbnails: string[]) => { + dispatch({ type: 'SET_THUMBNAILS', payload: thumbnails }); + }, []); + + const setGeneratingThumbnails = useCallback((generating: boolean) => { + dispatch({ type: 'SET_GENERATING_THUMBNAILS', payload: generating }); + }, []); + + const setDownloadInfo = useCallback((url: string | null, filename: string) => { + dispatch({ type: 'SET_DOWNLOAD_INFO', payload: { url, filename } }); + }, []); + + const setStatus = useCallback((status: string) => { + dispatch({ type: 'SET_STATUS', payload: status }); + }, []); + + const setError = useCallback((error: string | null) => { + dispatch({ type: 'SET_ERROR', payload: error }); + }, []); + + const setProgress = useCallback((progress: ProcessingProgress | null) => { + dispatch({ type: 'SET_PROGRESS', payload: progress }); + }, []); + + const resetResults = useCallback(() => { + dispatch({ type: 'RESET_RESULTS' }); + }, []); + + const clearError = useCallback(() => { + dispatch({ type: 'CLEAR_ERROR' }); + }, []); + + return { + state, + actions: { + setLoading, + setFiles, + setThumbnails, + setGeneratingThumbnails, + setDownloadInfo, + setStatus, + setError, + setProgress, + resetResults, + clearError, + }, + }; +}; \ No newline at end of file diff --git a/frontend/src/hooks/tools/split/useSplitOperation.ts b/frontend/src/hooks/tools/split/useSplitOperation.ts new file mode 100644 index 000000000..4979d0ea0 --- /dev/null +++ b/frontend/src/hooks/tools/split/useSplitOperation.ts @@ -0,0 +1,82 @@ +import { useCallback } from 'react'; +import axios from 'axios'; +import { useTranslation } from 'react-i18next'; +import { useToolOperation, ToolOperationConfig } from '../shared/useToolOperation'; +import { createStandardErrorHandler } from '../../../utils/toolErrorHandler'; +import { SplitParameters } from '../../../components/tools/split/SplitSettings'; +import { SPLIT_MODES } from '../../../constants/splitConstants'; + + +const buildFormData = (parameters: SplitParameters, selectedFiles: File[]): FormData => { + const formData = new FormData(); + + selectedFiles.forEach(file => { + formData.append("fileInput", file); + }); + + switch (parameters.mode) { + case SPLIT_MODES.BY_PAGES: + formData.append("pageNumbers", parameters.pages); + break; + case SPLIT_MODES.BY_SECTIONS: + formData.append("horizontalDivisions", parameters.hDiv); + formData.append("verticalDivisions", parameters.vDiv); + formData.append("merge", parameters.merge.toString()); + break; + case SPLIT_MODES.BY_SIZE_OR_COUNT: + formData.append( + "splitType", + parameters.splitType === "size" ? "0" : parameters.splitType === "pages" ? "1" : "2" + ); + formData.append("splitValue", parameters.splitValue); + break; + case SPLIT_MODES.BY_CHAPTERS: + formData.append("bookmarkLevel", parameters.bookmarkLevel); + formData.append("includeMetadata", parameters.includeMetadata.toString()); + formData.append("allowDuplicates", parameters.allowDuplicates.toString()); + break; + default: + throw new Error(`Unknown split mode: ${parameters.mode}`); + } + + return formData; +}; + +const getEndpoint = (parameters: SplitParameters): string => { + switch (parameters.mode) { + case SPLIT_MODES.BY_PAGES: + return "/api/v1/general/split-pages"; + case SPLIT_MODES.BY_SECTIONS: + return "/api/v1/general/split-pdf-by-sections"; + case SPLIT_MODES.BY_SIZE_OR_COUNT: + return "/api/v1/general/split-by-size-or-count"; + case SPLIT_MODES.BY_CHAPTERS: + return "/api/v1/general/split-pdf-by-chapters"; + default: + throw new Error(`Unknown split mode: ${parameters.mode}`); + } +}; + +export const useSplitOperation = () => { + const { t } = useTranslation(); + + return useToolOperation({ + operationType: 'split', + endpoint: (params) => getEndpoint(params), + buildFormData: buildFormData, // Multi-file signature: (params, selectedFiles) => FormData + filePrefix: 'split_', + multiFileEndpoint: true, // Single API call with all files + validateParams: (params) => { + if (!params.mode) { + return { valid: false, errors: [t('split.validation.modeRequired', 'Split mode is required')] }; + } + + if (params.mode === SPLIT_MODES.BY_PAGES && !params.pages) { + return { valid: false, errors: [t('split.validation.pagesRequired', 'Page numbers are required for split by pages')] }; + } + + return { valid: true }; + }, + getErrorMessage: createStandardErrorHandler(t('split.error.failed', 'An error occurred while splitting the PDF.')) + }); +}; diff --git a/frontend/src/hooks/tools/split/useSplitParameters.ts b/frontend/src/hooks/tools/split/useSplitParameters.ts new file mode 100644 index 000000000..72d479311 --- /dev/null +++ b/frontend/src/hooks/tools/split/useSplitParameters.ts @@ -0,0 +1,66 @@ +import { useState } from 'react'; +import { SPLIT_MODES, SPLIT_TYPES, ENDPOINTS, type SplitMode, type SplitType } from '../../../constants/splitConstants'; +import { SplitParameters } from '../../../components/tools/split/SplitSettings'; + +export interface SplitParametersHook { + parameters: SplitParameters; + updateParameter: (parameter: keyof SplitParameters, value: string | boolean) => void; + resetParameters: () => void; + validateParameters: () => boolean; + getEndpointName: () => string; +} + +const initialParameters: SplitParameters = { + mode: '', + pages: '', + hDiv: '2', + vDiv: '2', + merge: false, + splitType: SPLIT_TYPES.SIZE, + splitValue: '', + bookmarkLevel: '1', + includeMetadata: false, + allowDuplicates: false, +}; + +export const useSplitParameters = (): SplitParametersHook => { + const [parameters, setParameters] = useState(initialParameters); + + const updateParameter = (parameter: keyof SplitParameters, value: string | boolean) => { + setParameters(prev => ({ ...prev, [parameter]: value })); + }; + + const resetParameters = () => { + setParameters(initialParameters); + }; + + const validateParameters = () => { + if (!parameters.mode) return false; + + switch (parameters.mode) { + case SPLIT_MODES.BY_PAGES: + return parameters.pages.trim() !== ""; + case SPLIT_MODES.BY_SECTIONS: + return parameters.hDiv !== "" && parameters.vDiv !== ""; + case SPLIT_MODES.BY_SIZE_OR_COUNT: + return parameters.splitValue.trim() !== ""; + case SPLIT_MODES.BY_CHAPTERS: + return parameters.bookmarkLevel !== ""; + default: + return false; + } + }; + + const getEndpointName = () => { + if (!parameters.mode) return ENDPOINTS[SPLIT_MODES.BY_PAGES]; + return ENDPOINTS[parameters.mode as SplitMode]; + }; + + return { + parameters, + updateParameter, + resetParameters, + validateParameters, + getEndpointName, + }; +}; \ No newline at end of file diff --git a/frontend/src/hooks/useAppConfig.ts b/frontend/src/hooks/useAppConfig.ts new file mode 100644 index 000000000..899038f51 --- /dev/null +++ b/frontend/src/hooks/useAppConfig.ts @@ -0,0 +1,77 @@ +import { useState, useEffect } from 'react'; + +export interface AppConfig { + baseUrl?: string; + contextPath?: string; + serverPort?: number; + appName?: string; + appNameNavbar?: string; + homeDescription?: string; + languages?: string[]; + enableLogin?: boolean; + enableAlphaFunctionality?: boolean; + enableAnalytics?: boolean; + premiumEnabled?: boolean; + premiumKey?: string; + termsAndConditions?: string; + privacyPolicy?: string; + cookiePolicy?: string; + impressum?: string; + accessibilityStatement?: string; + runningProOrHigher?: boolean; + runningEE?: boolean; + license?: string; + GoogleDriveEnabled?: boolean; + SSOAutoLogin?: boolean; + error?: string; +} + +interface UseAppConfigReturn { + config: AppConfig | null; + loading: boolean; + error: string | null; + refetch: () => Promise; +} + +/** + * Custom hook to fetch and manage application configuration + */ +export function useAppConfig(): UseAppConfigReturn { + const [config, setConfig] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + const fetchConfig = async () => { + try { + setLoading(true); + setError(null); + + const response = await fetch('/api/v1/config/app-config'); + + if (!response.ok) { + throw new Error(`Failed to fetch config: ${response.status} ${response.statusText}`); + } + + const data: AppConfig = await response.json(); + setConfig(data); + } catch (err) { + const errorMessage = err instanceof Error ? err.message : 'Unknown error occurred'; + setError(errorMessage); + console.error('Failed to fetch app config:', err); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchConfig(); + }, []); + + return { + config, + loading, + error, + refetch: fetchConfig, + }; +} + diff --git a/frontend/src/hooks/useEndpointConfig.ts b/frontend/src/hooks/useEndpointConfig.ts new file mode 100644 index 000000000..5419f3506 --- /dev/null +++ b/frontend/src/hooks/useEndpointConfig.ts @@ -0,0 +1,118 @@ +import { useState, useEffect } from 'react'; + +/** + * Hook to check if a specific endpoint is enabled + */ +export function useEndpointEnabled(endpoint: string): { + enabled: boolean | null; + loading: boolean; + error: string | null; + refetch: () => Promise; +} { + const [enabled, setEnabled] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + const fetchEndpointStatus = async () => { + if (!endpoint) { + setEnabled(null); + setLoading(false); + return; + } + + try { + setLoading(true); + setError(null); + + const response = await fetch(`/api/v1/config/endpoint-enabled?endpoint=${encodeURIComponent(endpoint)}`); + + if (!response.ok) { + throw new Error(`Failed to check endpoint: ${response.status} ${response.statusText}`); + } + + const isEnabled: boolean = await response.json(); + setEnabled(isEnabled); + } catch (err) { + const errorMessage = err instanceof Error ? err.message : 'Unknown error occurred'; + setError(errorMessage); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchEndpointStatus(); + }, [endpoint]); + + return { + enabled, + loading, + error, + refetch: fetchEndpointStatus, + }; +} + +/** + * Hook to check multiple endpoints at once using batch API + * Returns a map of endpoint -> enabled status + */ +export function useMultipleEndpointsEnabled(endpoints: string[]): { + endpointStatus: Record; + loading: boolean; + error: string | null; + refetch: () => Promise; +} { + const [endpointStatus, setEndpointStatus] = useState>({}); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + const fetchAllEndpointStatuses = async () => { + if (!endpoints || endpoints.length === 0) { + setEndpointStatus({}); + setLoading(false); + return; + } + + try { + setLoading(true); + setError(null); + + // Use batch API for efficiency + const endpointsParam = endpoints.join(','); + + const response = await fetch(`/api/v1/config/endpoints-enabled?endpoints=${encodeURIComponent(endpointsParam)}`); + + if (!response.ok) { + throw new Error(`Failed to check endpoints: ${response.status} ${response.statusText}`); + } + + const statusMap: Record = await response.json(); + setEndpointStatus(statusMap); + } catch (err) { + const errorMessage = err instanceof Error ? err.message : 'Unknown error occurred'; + setError(errorMessage); + console.error('Failed to check multiple endpoints:', err); + + // Fallback: assume all endpoints are disabled on error + const fallbackStatus = endpoints.reduce((acc, endpoint) => { + acc[endpoint] = false; + return acc; + }, {} as Record); + setEndpointStatus(fallbackStatus); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + const endpointsKey = endpoints.join(','); + fetchAllEndpointStatuses(); + }, [endpoints.join(',')]); // Re-run when endpoints array changes + + return { + endpointStatus, + loading, + error, + refetch: fetchAllEndpointStatuses, + }; +} \ No newline at end of file diff --git a/frontend/src/hooks/useEnhancedProcessedFiles.ts b/frontend/src/hooks/useEnhancedProcessedFiles.ts new file mode 100644 index 000000000..ebdff4bf5 --- /dev/null +++ b/frontend/src/hooks/useEnhancedProcessedFiles.ts @@ -0,0 +1,312 @@ +import { useState, useEffect, useRef } from 'react'; +import { ProcessedFile, ProcessingState, ProcessingConfig } from '../types/processing'; +import { enhancedPDFProcessingService } from '../services/enhancedPDFProcessingService'; +import { FileHasher } from '../utils/fileHash'; + +interface UseEnhancedProcessedFilesResult { + processedFiles: Map; + processingStates: Map; + isProcessing: boolean; + hasProcessingErrors: boolean; + processingProgress: { + overall: number; + fileProgress: Map; + estimatedTimeRemaining: number; + }; + cacheStats: { + entries: number; + totalSizeBytes: number; + maxSizeBytes: number; + }; + metrics: { + totalFiles: number; + completedFiles: number; + failedFiles: number; + averageProcessingTime: number; + cacheHitRate: number; + }; + actions: { + cancelProcessing: (fileKey: string) => void; + retryProcessing: (file: File) => void; + clearCache: () => void; + }; +} + +export function useEnhancedProcessedFiles( + activeFiles: File[], + config?: Partial +): UseEnhancedProcessedFilesResult { + const [processedFiles, setProcessedFiles] = useState>(new Map()); + const fileHashMapRef = useRef>(new Map()); // Use ref to avoid state update loops + const [processingStates, setProcessingStates] = useState>(new Map()); + + // Subscribe to processing state changes once + useEffect(() => { + const unsubscribe = enhancedPDFProcessingService.onProcessingChange(setProcessingStates); + return unsubscribe; + }, []); + + // Process files when activeFiles changes + useEffect(() => { + console.log('useEnhancedProcessedFiles: activeFiles changed', activeFiles.length, 'files'); + + if (activeFiles.length === 0) { + console.log('useEnhancedProcessedFiles: No active files, clearing processed cache'); + setProcessedFiles(new Map()); + // Clear any ongoing processing when no files + enhancedPDFProcessingService.clearAllProcessing(); + return; + } + + const processFiles = async () => { + const newProcessedFiles = new Map(); + + for (const file of activeFiles) { + // Generate hash for this file + const fileHash = await FileHasher.generateHybridHash(file); + fileHashMapRef.current.set(file, fileHash); + + // First, check if we have this exact File object cached + let existing = processedFiles.get(file); + + // If not found by File object, try to find by hash in case File was recreated + if (!existing) { + for (const [cachedFile, processed] of processedFiles.entries()) { + const cachedHash = fileHashMapRef.current.get(cachedFile); + if (cachedHash === fileHash) { + existing = processed; + break; + } + } + } + + if (existing) { + newProcessedFiles.set(file, existing); + continue; + } + + try { + const processed = await enhancedPDFProcessingService.processFile(file, config); + if (processed) { + newProcessedFiles.set(file, processed); + } + } catch (error) { + console.error(`Failed to start processing for ${file.name}:`, error); + } + } + + // Only update if the content actually changed + const hasChanged = newProcessedFiles.size !== processedFiles.size || + Array.from(newProcessedFiles.keys()).some(file => !processedFiles.has(file)); + + if (hasChanged) { + setProcessedFiles(newProcessedFiles); + } + }; + + processFiles(); + }, [activeFiles]); // Only depend on activeFiles to avoid infinite loops + + // Listen for processing completion + useEffect(() => { + const checkForCompletedFiles = async () => { + let hasNewFiles = false; + const updatedFiles = new Map(processedFiles); + + // Generate file keys for all files first + const fileKeyPromises = activeFiles.map(async (file) => ({ + file, + key: await FileHasher.generateHybridHash(file) + })); + + const fileKeyPairs = await Promise.all(fileKeyPromises); + + for (const { file, key } of fileKeyPairs) { + // Only check files that don't have processed results yet + if (!updatedFiles.has(file)) { + const processingState = processingStates.get(key); + + // Check for both processing and recently completed files + // This ensures we catch completed files before they're cleaned up + if (processingState?.status === 'processing' || processingState?.status === 'completed') { + try { + const processed = await enhancedPDFProcessingService.processFile(file, config); + if (processed) { + updatedFiles.set(file, processed); + hasNewFiles = true; + } + } catch (error) { + // Ignore errors in completion check + } + } + } + } + + if (hasNewFiles) { + setProcessedFiles(updatedFiles); + } + }; + + // Check every 500ms for completed processing + const interval = setInterval(checkForCompletedFiles, 500); + return () => clearInterval(interval); + }, [activeFiles, processingStates]); + + + // Cleanup when activeFiles changes + useEffect(() => { + const currentFiles = new Set(activeFiles); + const previousFiles = Array.from(processedFiles.keys()); + const removedFiles = previousFiles.filter(file => !currentFiles.has(file)); + + if (removedFiles.length > 0) { + // Clean up processing service cache + enhancedPDFProcessingService.cleanup(removedFiles); + + // Update local state + setProcessedFiles(prev => { + const updated = new Map(); + for (const [file, processed] of prev) { + if (currentFiles.has(file)) { + updated.set(file, processed); + } + } + return updated; + }); + } + }, [activeFiles]); + + // Calculate derived state + const isProcessing = processingStates.size > 0; + const hasProcessingErrors = Array.from(processingStates.values()).some(state => state.status === 'error'); + + // Calculate overall progress + const processingProgress = calculateProcessingProgress(processingStates); + + // Get cache stats and metrics + const cacheStats = enhancedPDFProcessingService.getCacheStats(); + const metrics = enhancedPDFProcessingService.getMetrics(); + + // Action handlers + const actions = { + cancelProcessing: (fileKey: string) => { + enhancedPDFProcessingService.cancelProcessing(fileKey); + }, + + retryProcessing: async (file: File) => { + try { + await enhancedPDFProcessingService.processFile(file, config); + } catch (error) { + console.error(`Failed to retry processing for ${file.name}:`, error); + } + }, + + clearCache: () => { + enhancedPDFProcessingService.clearAll(); + } + }; + + // Cleanup on unmount + useEffect(() => { + return () => { + enhancedPDFProcessingService.clearAllProcessing(); + }; + }, []); + + return { + processedFiles, + processingStates, + isProcessing, + hasProcessingErrors, + processingProgress, + cacheStats, + metrics, + actions + }; +} + +/** + * Calculate overall processing progress from individual file states + */ +function calculateProcessingProgress(states: Map): { + overall: number; + fileProgress: Map; + estimatedTimeRemaining: number; +} { + if (states.size === 0) { + return { + overall: 100, + fileProgress: new Map(), + estimatedTimeRemaining: 0 + }; + } + + const fileProgress = new Map(); + let totalProgress = 0; + let totalEstimatedTime = 0; + + for (const [fileKey, state] of states) { + fileProgress.set(fileKey, state.progress); + totalProgress += state.progress; + totalEstimatedTime += state.estimatedTimeRemaining || 0; + } + + const overall = totalProgress / states.size; + const estimatedTimeRemaining = totalEstimatedTime; + + return { + overall, + fileProgress, + estimatedTimeRemaining + }; +} + +/** + * Hook for getting a single processed file with enhanced features + */ +export function useEnhancedProcessedFile( + file: File | null, + config?: Partial +): { + processedFile: ProcessedFile | null; + isProcessing: boolean; + processingState: ProcessingState | null; + error: string | null; + canRetry: boolean; + actions: { + cancel: () => void; + retry: () => void; + }; +} { + const result = useEnhancedProcessedFiles(file ? [file] : [], config); + + const processedFile = file ? result.processedFiles.get(file) || null : null; + // Note: This is async but we can't await in hook return - consider refactoring if needed + const fileKey = file ? '' : ''; + const processingState = fileKey ? result.processingStates.get(fileKey) || null : null; + const isProcessing = !!processingState; + const error = processingState?.error?.message || null; + const canRetry = processingState?.error?.recoverable || false; + + const actions = { + cancel: () => { + if (fileKey) { + result.actions.cancelProcessing(fileKey); + } + }, + retry: () => { + if (file) { + result.actions.retryProcessing(file); + } + } + }; + + return { + processedFile, + isProcessing, + processingState, + error, + canRetry, + actions + }; +} \ No newline at end of file diff --git a/frontend/src/hooks/useFileHandler.ts b/frontend/src/hooks/useFileHandler.ts new file mode 100644 index 000000000..efd988906 --- /dev/null +++ b/frontend/src/hooks/useFileHandler.ts @@ -0,0 +1,27 @@ +import { useCallback } from 'react'; +import { useFileContext } from '../contexts/FileContext'; + +export const useFileHandler = () => { + const { activeFiles, addFiles } = useFileContext(); + + const addToActiveFiles = useCallback(async (file: File) => { + const exists = activeFiles.some(f => f.name === file.name && f.size === file.size); + if (!exists) { + await addFiles([file]); + } + }, [activeFiles, addFiles]); + + const addMultipleFiles = useCallback(async (files: File[]) => { + const newFiles = files.filter(file => + !activeFiles.some(f => f.name === file.name && f.size === file.size) + ); + if (newFiles.length > 0) { + await addFiles(newFiles); + } + }, [activeFiles, addFiles]); + + return { + addToActiveFiles, + addMultipleFiles, + }; +}; \ No newline at end of file diff --git a/frontend/src/hooks/useFileManager.ts b/frontend/src/hooks/useFileManager.ts new file mode 100644 index 000000000..efb6724eb --- /dev/null +++ b/frontend/src/hooks/useFileManager.ts @@ -0,0 +1,137 @@ +import { useState, useCallback } from 'react'; +import { fileStorage } from '../services/fileStorage'; +import { FileWithUrl } from '../types/file'; +import { generateThumbnailForFile } from '../utils/thumbnailUtils'; + +export const useFileManager = () => { + const [loading, setLoading] = useState(false); + + const convertToFile = useCallback(async (fileWithUrl: FileWithUrl): Promise => { + if (fileWithUrl.url && fileWithUrl.url.startsWith('blob:')) { + const response = await fetch(fileWithUrl.url); + const data = await response.arrayBuffer(); + const file = new File([data], fileWithUrl.name, { + type: fileWithUrl.type || 'application/pdf', + lastModified: fileWithUrl.lastModified || Date.now() + }); + // Preserve the ID if it exists + if (fileWithUrl.id) { + Object.defineProperty(file, 'id', { value: fileWithUrl.id, writable: false }); + } + return file; + } + + // Always use ID first, fallback to name only if ID doesn't exist + const lookupKey = fileWithUrl.id || fileWithUrl.name; + const storedFile = await fileStorage.getFile(lookupKey); + if (storedFile) { + const file = new File([storedFile.data], storedFile.name, { + type: storedFile.type, + lastModified: storedFile.lastModified + }); + // Add the ID to the file object + Object.defineProperty(file, 'id', { value: storedFile.id, writable: false }); + return file; + } + + throw new Error('File not found in storage'); + }, []); + + const loadRecentFiles = useCallback(async (): Promise => { + setLoading(true); + try { + const files = await fileStorage.getAllFiles(); + const sortedFiles = files.sort((a, b) => (b.lastModified || 0) - (a.lastModified || 0)); + return sortedFiles; + } catch (error) { + console.error('Failed to load recent files:', error); + return []; + } finally { + setLoading(false); + } + }, []); + + const handleRemoveFile = useCallback(async (index: number, files: FileWithUrl[], setFiles: (files: FileWithUrl[]) => void) => { + const file = files[index]; + try { + await fileStorage.deleteFile(file.id || file.name); + setFiles(files.filter((_, i) => i !== index)); + } catch (error) { + console.error('Failed to remove file:', error); + throw error; + } + }, []); + + const storeFile = useCallback(async (file: File) => { + try { + // Generate thumbnail for the file + const thumbnail = await generateThumbnailForFile(file); + + // Store file with thumbnail + const storedFile = await fileStorage.storeFile(file, thumbnail); + + // Add the ID to the file object + Object.defineProperty(file, 'id', { value: storedFile.id, writable: false }); + return storedFile; + } catch (error) { + console.error('Failed to store file:', error); + throw error; + } + }, []); + + const createFileSelectionHandlers = useCallback(( + selectedFiles: string[], + setSelectedFiles: (files: string[]) => void + ) => { + const toggleSelection = (fileId: string) => { + setSelectedFiles( + selectedFiles.includes(fileId) + ? selectedFiles.filter(id => id !== fileId) + : [...selectedFiles, fileId] + ); + }; + + const clearSelection = () => { + setSelectedFiles([]); + }; + + const selectMultipleFiles = async (files: FileWithUrl[], onFilesSelect: (files: File[]) => void) => { + if (selectedFiles.length === 0) return; + + try { + const selectedFileObjects = files.filter(f => selectedFiles.includes(f.id || f.name)); + const filePromises = selectedFileObjects.map(convertToFile); + const convertedFiles = await Promise.all(filePromises); + onFilesSelect(convertedFiles); + clearSelection(); + } catch (error) { + console.error('Failed to load selected files:', error); + throw error; + } + }; + + return { + toggleSelection, + clearSelection, + selectMultipleFiles + }; + }, [convertToFile]); + + const touchFile = useCallback(async (id: string) => { + try { + await fileStorage.touchFile(id); + } catch (error) { + console.error('Failed to touch file:', error); + } + }, []); + + return { + loading, + convertToFile, + loadRecentFiles, + handleRemoveFile, + storeFile, + touchFile, + createFileSelectionHandlers + }; +}; \ No newline at end of file diff --git a/frontend/src/hooks/useFileWithUrl.ts b/frontend/src/hooks/useFileWithUrl.ts new file mode 100644 index 000000000..aeb954cd1 --- /dev/null +++ b/frontend/src/hooks/useFileWithUrl.ts @@ -0,0 +1,50 @@ +import { useMemo } from 'react'; + +/** + * Hook to convert a File object to { file: File; url: string } format + * Creates blob URL on-demand and handles cleanup + */ +export function useFileWithUrl(file: File | null): { file: File; url: string } | null { + return useMemo(() => { + if (!file) return null; + + // Validate that file is a proper File or Blob object + if (!(file instanceof File) && !(file instanceof Blob)) { + console.warn('useFileWithUrl: Expected File or Blob, got:', file); + return null; + } + + try { + const url = URL.createObjectURL(file); + + // Return object with cleanup function + const result = { file, url }; + + // Store cleanup function for later use + (result as any)._cleanup = () => URL.revokeObjectURL(url); + + return result; + } catch (error) { + console.error('useFileWithUrl: Failed to create object URL:', error, file); + return null; + } + }, [file]); +} + +/** + * Hook variant that returns cleanup function separately + */ +export function useFileWithUrlAndCleanup(file: File | null): { + fileObj: { file: File; url: string } | null; + cleanup: () => void; +} { + return useMemo(() => { + if (!file) return { fileObj: null, cleanup: () => {} }; + + const url = URL.createObjectURL(file); + const fileObj = { file, url }; + const cleanup = () => URL.revokeObjectURL(url); + + return { fileObj, cleanup }; + }, [file]); +} \ No newline at end of file diff --git a/frontend/src/hooks/useIndexedDBThumbnail.ts b/frontend/src/hooks/useIndexedDBThumbnail.ts new file mode 100644 index 000000000..b8b2c669c --- /dev/null +++ b/frontend/src/hooks/useIndexedDBThumbnail.ts @@ -0,0 +1,105 @@ +import { useState, useEffect } from "react"; +import { FileWithUrl } from "../types/file"; +import { fileStorage } from "../services/fileStorage"; +import { generateThumbnailForFile } from "../utils/thumbnailUtils"; + +/** + * Calculate optimal scale for thumbnail generation + * Ensures high quality while preventing oversized renders + */ +function calculateThumbnailScale(pageViewport: { width: number; height: number }): number { + const maxWidth = 400; // Max thumbnail width + const maxHeight = 600; // Max thumbnail height + + const scaleX = maxWidth / pageViewport.width; + const scaleY = maxHeight / pageViewport.height; + + // Don't upscale, only downscale if needed + return Math.min(scaleX, scaleY, 1.0); +} + +/** + * Hook for IndexedDB-aware thumbnail loading + * Handles thumbnail generation for files not in IndexedDB + */ +export function useIndexedDBThumbnail(file: FileWithUrl | undefined | null): { + thumbnail: string | null; + isGenerating: boolean +} { + const [thumb, setThumb] = useState(null); + const [generating, setGenerating] = useState(false); + + useEffect(() => { + let cancelled = false; + + async function loadThumbnail() { + if (!file) { + setThumb(null); + return; + } + + // First priority: use stored thumbnail + if (file.thumbnail) { + setThumb(file.thumbnail); + return; + } + + // Second priority: generate thumbnail for any file type + if (file.size < 100 * 1024 * 1024 && !generating) { + setGenerating(true); + try { + let fileObject: File; + + // Handle IndexedDB files vs regular File objects + if (file.storedInIndexedDB && file.id) { + // For IndexedDB files, recreate File object from stored data + const storedFile = await fileStorage.getFile(file.id); + if (!storedFile) { + throw new Error('File not found in IndexedDB'); + } + fileObject = new File([storedFile.data], storedFile.name, { + type: storedFile.type, + lastModified: storedFile.lastModified + }); + } else if (file.file) { + // For FileWithUrl objects that have a File object + fileObject = file.file; + } else if (file.id) { + // Fallback: try to get from IndexedDB even if storedInIndexedDB flag is missing + const storedFile = await fileStorage.getFile(file.id); + if (!storedFile) { + throw new Error('File not found in IndexedDB and no File object available'); + } + fileObject = new File([storedFile.data], storedFile.name, { + type: storedFile.type, + lastModified: storedFile.lastModified + }); + } else { + throw new Error('File object not available and no ID for IndexedDB lookup'); + } + + // Use the universal thumbnail generator + const thumbnail = await generateThumbnailForFile(fileObject); + if (!cancelled && thumbnail) { + setThumb(thumbnail); + } else if (!cancelled) { + setThumb(null); + } + } catch (error) { + console.warn('Failed to generate thumbnail for file', file.name, error); + if (!cancelled) setThumb(null); + } finally { + if (!cancelled) setGenerating(false); + } + } else { + // Large files - generate placeholder + setThumb(null); + } + } + + loadThumbnail(); + return () => { cancelled = true; }; + }, [file, file?.thumbnail, file?.id]); + + return { thumbnail: thumb, isGenerating: generating }; +} \ No newline at end of file diff --git a/frontend/src/hooks/useIsOverflowing.ts b/frontend/src/hooks/useIsOverflowing.ts new file mode 100644 index 000000000..b5e6d3962 --- /dev/null +++ b/frontend/src/hooks/useIsOverflowing.ts @@ -0,0 +1,73 @@ +import * as React from 'react'; + + +/** + Hook to detect if an element's content overflows its container + + + Parameters: + - ref: React ref to the element to monitor + - callback: Optional callback function called when overflow state changes + + Returns: boolean | undefined - true if overflowing, false if not, undefined before first check + + Usage example: + + useEffect(() => { + if (isOverflow) { + // Do something + } + }, [isOverflow]); + + const scrollableRef = useRef(null); + const isOverflow = useIsOverflowing(scrollableRef); + + Fallback example (for browsers without ResizeObserver): + + return ( +
+ {Content that might overflow} +
+ ); +*/ + + +export const useIsOverflowing = (ref: React.RefObject, callback?: (isOverflow: boolean) => void) => { + // State to track overflow status + const [isOverflow, setIsOverflow] = React.useState(undefined); + + React.useLayoutEffect(() => { + const { current } = ref; + + // Function to check if element is overflowing + const trigger = () => { + if (!current) return; + + // Compare scroll height (total content height) vs client height (visible height) + const hasOverflow = current.scrollHeight > current.clientHeight; + setIsOverflow(hasOverflow); + + // Call optional callback with overflow state + if (callback) callback(hasOverflow); + }; + + if (current) { + // Use ResizeObserver for modern browsers (real-time detection) + if ('ResizeObserver' in window) { + const resizeObserver = new ResizeObserver(trigger); + resizeObserver.observe(current); + + // Cleanup function to disconnect observer + return () => { + resizeObserver.disconnect(); + }; + } + + // Fallback for browsers without ResizeObserver support + // Add a small delay to ensure the element is fully rendered + setTimeout(trigger, 0); + } + }, [callback, ref]); + + return isOverflow; +}; \ No newline at end of file diff --git a/frontend/src/hooks/useMemoryManagement.ts b/frontend/src/hooks/useMemoryManagement.ts new file mode 100644 index 000000000..d27e5ed56 --- /dev/null +++ b/frontend/src/hooks/useMemoryManagement.ts @@ -0,0 +1,30 @@ +import { useCallback } from 'react'; +import { useFileContext } from '../contexts/FileContext'; + +/** + * Hook for components that need to register resources with centralized memory management + */ +export function useMemoryManagement() { + const { trackBlobUrl, trackPdfDocument, scheduleCleanup } = useFileContext(); + + const registerBlobUrl = useCallback((url: string) => { + trackBlobUrl(url); + return url; + }, [trackBlobUrl]); + + const registerPdfDocument = useCallback((fileId: string, pdfDoc: any) => { + trackPdfDocument(fileId, pdfDoc); + return pdfDoc; + }, [trackPdfDocument]); + + const cancelCleanup = useCallback((fileId: string) => { + // Cancel scheduled cleanup (user is actively using the file) + scheduleCleanup(fileId, -1); // -1 cancels the timer + }, [scheduleCleanup]); + + return { + registerBlobUrl, + registerPdfDocument, + cancelCleanup + }; +} \ No newline at end of file diff --git a/frontend/src/hooks/usePDFProcessor.ts b/frontend/src/hooks/usePDFProcessor.ts new file mode 100644 index 000000000..0a717a3a9 --- /dev/null +++ b/frontend/src/hooks/usePDFProcessor.ts @@ -0,0 +1,102 @@ +import { useState, useCallback } from 'react'; +import { getDocument } from 'pdfjs-dist'; +import { PDFDocument, PDFPage } from '../types/pageEditor'; + +export function usePDFProcessor() { + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + const generatePageThumbnail = useCallback(async ( + file: File, + pageNumber: number, + scale: number = 0.5 + ): Promise => { + try { + const arrayBuffer = await file.arrayBuffer(); + const pdf = await getDocument({ data: arrayBuffer }).promise; + const page = await pdf.getPage(pageNumber); + + const viewport = page.getViewport({ scale }); + const canvas = document.createElement('canvas'); + canvas.width = viewport.width; + canvas.height = viewport.height; + + const context = canvas.getContext('2d'); + if (!context) { + throw new Error('Could not get canvas context'); + } + + await page.render({ canvasContext: context, viewport }).promise; + const thumbnail = canvas.toDataURL(); + + // Clean up + pdf.destroy(); + + return thumbnail; + } catch (error) { + console.error('Failed to generate thumbnail:', error); + throw error; + } + }, []); + + const processPDFFile = useCallback(async (file: File): Promise => { + setLoading(true); + setError(null); + + try { + const arrayBuffer = await file.arrayBuffer(); + const pdf = await getDocument({ data: arrayBuffer }).promise; + const totalPages = pdf.numPages; + + const pages: PDFPage[] = []; + + // Create pages without thumbnails initially - load them lazily + for (let i = 1; i <= totalPages; i++) { + pages.push({ + id: `${file.name}-page-${i}`, + pageNumber: i, + thumbnail: null, // Will be loaded lazily + rotation: 0, + selected: false + }); + } + + // Generate thumbnails for first 10 pages immediately for better UX + const priorityPages = Math.min(10, totalPages); + for (let i = 1; i <= priorityPages; i++) { + try { + const thumbnail = await generatePageThumbnail(file, i); + pages[i - 1].thumbnail = thumbnail; + } catch (error) { + console.warn(`Failed to generate thumbnail for page ${i}:`, error); + } + } + + // Clean up + pdf.destroy(); + + const document: PDFDocument = { + id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, + name: file.name, + file, + pages, + totalPages + }; + + return document; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Failed to process PDF'; + setError(errorMessage); + throw error; + } finally { + setLoading(false); + } + }, [generatePageThumbnail]); + + return { + processPDFFile, + generatePageThumbnail, + loading, + error + }; +} \ No newline at end of file diff --git a/frontend/src/hooks/usePdfSignatureDetection.ts b/frontend/src/hooks/usePdfSignatureDetection.ts new file mode 100644 index 000000000..96d80fb9d --- /dev/null +++ b/frontend/src/hooks/usePdfSignatureDetection.ts @@ -0,0 +1,66 @@ +import { useState, useEffect } from 'react'; +import * as pdfjsLib from 'pdfjs-dist'; + +export interface PdfSignatureDetectionResult { + hasDigitalSignatures: boolean; + isChecking: boolean; +} + +export const usePdfSignatureDetection = (files: File[]): PdfSignatureDetectionResult => { + const [hasDigitalSignatures, setHasDigitalSignatures] = useState(false); + const [isChecking, setIsChecking] = useState(false); + + useEffect(() => { + const checkForDigitalSignatures = async () => { + if (files.length === 0) { + setHasDigitalSignatures(false); + return; + } + + setIsChecking(true); + let foundSignature = false; + + try { + // Set up PDF.js worker + pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdfjs-legacy/pdf.worker.mjs'; + + for (const file of files) { + const arrayBuffer = await file.arrayBuffer(); + + try { + const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise; + + for (let i = 1; i <= pdf.numPages; i++) { + const page = await pdf.getPage(i); + const annotations = await page.getAnnotations({ intent: 'display' }); + + annotations.forEach(annotation => { + if (annotation.subtype === 'Widget' && annotation.fieldType === 'Sig') { + foundSignature = true; + } + }); + + if (foundSignature) break; + } + } catch (error) { + console.warn('Error analyzing PDF for signatures:', error); + } + + if (foundSignature) break; + } + } catch (error) { + console.warn('Error checking for digital signatures:', error); + } + + setHasDigitalSignatures(foundSignature); + setIsChecking(false); + }; + + checkForDigitalSignatures(); + }, [files]); + + return { + hasDigitalSignatures, + isChecking + }; +}; \ No newline at end of file diff --git a/frontend/src/hooks/useProcessedFiles.ts b/frontend/src/hooks/useProcessedFiles.ts new file mode 100644 index 000000000..a7db9b07e --- /dev/null +++ b/frontend/src/hooks/useProcessedFiles.ts @@ -0,0 +1,125 @@ +import { useState, useEffect } from 'react'; +import { ProcessedFile, ProcessingState } from '../types/processing'; +import { pdfProcessingService } from '../services/pdfProcessingService'; + +interface UseProcessedFilesResult { + processedFiles: Map; + processingStates: Map; + isProcessing: boolean; + hasProcessingErrors: boolean; + cacheStats: { + entries: number; + totalSizeBytes: number; + maxSizeBytes: number; + }; +} + +export function useProcessedFiles(activeFiles: File[]): UseProcessedFilesResult { + const [processedFiles, setProcessedFiles] = useState>(new Map()); + const [processingStates, setProcessingStates] = useState>(new Map()); + + useEffect(() => { + // Subscribe to processing state changes + const unsubscribe = pdfProcessingService.onProcessingChange(setProcessingStates); + + // Check/start processing for each active file + const checkProcessing = async () => { + const newProcessedFiles = new Map(); + + for (const file of activeFiles) { + const processed = await pdfProcessingService.getProcessedFile(file); + if (processed) { + newProcessedFiles.set(file, processed); + } + } + + setProcessedFiles(newProcessedFiles); + }; + + checkProcessing(); + + return unsubscribe; + }, [activeFiles]); + + // Listen for processing completion and update processed files + useEffect(() => { + const updateProcessedFiles = async () => { + const updated = new Map(); + + for (const file of activeFiles) { + const existing = processedFiles.get(file); + if (existing) { + updated.set(file, existing); + } else { + // Check if processing just completed + const processed = await pdfProcessingService.getProcessedFile(file); + if (processed) { + updated.set(file, processed); + } + } + } + + setProcessedFiles(updated); + }; + + // Small delay to allow processing state to settle + const timeoutId = setTimeout(updateProcessedFiles, 100); + return () => clearTimeout(timeoutId); + }, [processingStates, activeFiles]); + + // Cleanup when activeFiles changes + useEffect(() => { + const currentFiles = new Set(activeFiles); + const previousFiles = Array.from(processedFiles.keys()); + const removedFiles = previousFiles.filter(file => !currentFiles.has(file)); + + if (removedFiles.length > 0) { + // Clean up processing service cache + pdfProcessingService.cleanup(removedFiles); + + // Update local state + setProcessedFiles(prev => { + const updated = new Map(); + for (const [file, processed] of prev) { + if (currentFiles.has(file)) { + updated.set(file, processed); + } + } + return updated; + }); + } + }, [activeFiles]); + + // Derived state + const isProcessing = processingStates.size > 0; + const hasProcessingErrors = Array.from(processingStates.values()).some(state => state.status === 'error'); + const cacheStats = pdfProcessingService.getCacheStats(); + + return { + processedFiles, + processingStates, + isProcessing, + hasProcessingErrors, + cacheStats + }; +} + +// Hook for getting a single processed file +export function useProcessedFile(file: File | null): { + processedFile: ProcessedFile | null; + isProcessing: boolean; + processingState: ProcessingState | null; +} { + const result = useProcessedFiles(file ? [file] : []); + + const processedFile = file ? result.processedFiles.get(file) || null : null; + const fileKey = file ? pdfProcessingService.generateFileKey(file) : ''; + const processingState = fileKey ? result.processingStates.get(fileKey) || null : null; + const isProcessing = !!processingState; + + return { + processedFile, + isProcessing, + processingState + }; +} \ No newline at end of file diff --git a/frontend/src/hooks/useRainbowTheme.ts b/frontend/src/hooks/useRainbowTheme.ts new file mode 100644 index 000000000..a3c8f6e67 --- /dev/null +++ b/frontend/src/hooks/useRainbowTheme.ts @@ -0,0 +1,200 @@ +import { useState, useCallback, useRef, useEffect } from 'react'; + +type ThemeMode = 'light' | 'dark' | 'rainbow'; + +interface RainbowThemeHook { + themeMode: ThemeMode; + isRainbowMode: boolean; + isToggleDisabled: boolean; + toggleTheme: () => void; + activateRainbow: () => void; + deactivateRainbow: () => void; +} + +export function useRainbowTheme(initialTheme: 'light' | 'dark' = 'light'): RainbowThemeHook { + // Get theme from localStorage or use initial + const [themeMode, setThemeMode] = useState(() => { + const stored = localStorage.getItem('stirling-theme'); + if (stored && ['light', 'dark', 'rainbow'].includes(stored)) { + return stored as ThemeMode; + } + return initialTheme; + }); + + // Track rapid toggles for easter egg + const toggleCount = useRef(0); + const lastToggleTime = useRef(Date.now()); + const [isToggleDisabled, setIsToggleDisabled] = useState(false); + + // Save theme to localStorage whenever it changes + useEffect(() => { + localStorage.setItem('stirling-theme', themeMode); + + // Apply rainbow class to body if in rainbow mode + if (themeMode === 'rainbow') { + document.body.classList.add('rainbow-mode-active'); + + // Show easter egg notification + showRainbowNotification(); + } else { + document.body.classList.remove('rainbow-mode-active'); + } + }, [themeMode]); + + const showRainbowNotification = () => { + // Remove any existing notification + const existingNotification = document.getElementById('rainbow-notification'); + if (existingNotification) { + existingNotification.remove(); + } + + // Create and show rainbow notification + const notification = document.createElement('div'); + notification.id = 'rainbow-notification'; + notification.innerHTML = '🌈 RAINBOW MODE ACTIVATED! 🌈
Button disabled for 3 seconds, then click to exit'; + notification.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + background: linear-gradient(45deg, #ff0000, #ff8800, #ffff00, #88ff00, #00ff88, #00ffff, #0088ff, #8800ff); + background-size: 300% 300%; + animation: rainbowBackground 1s ease infinite; + color: white; + padding: 15px 20px; + border-radius: 25px; + font-weight: bold; + font-size: 16px; + z-index: 1000; + border: 2px solid white; + box-shadow: 0 0 20px rgba(255, 255, 255, 0.8); + user-select: none; + pointer-events: none; + transition: opacity 0.3s ease; + `; + + document.body.appendChild(notification); + + // Auto-remove notification after 3 seconds + setTimeout(() => { + if (notification) { + notification.style.opacity = '0'; + setTimeout(() => { + if (notification.parentNode) { + notification.parentNode.removeChild(notification); + } + }, 300); + } + }, 3000); + }; + + const showExitNotification = () => { + // Remove any existing notification + const existingNotification = document.getElementById('rainbow-exit-notification'); + if (existingNotification) { + existingNotification.remove(); + } + + // Create and show exit notification + const notification = document.createElement('div'); + notification.id = 'rainbow-exit-notification'; + notification.innerHTML = 'šŸŒ™ Rainbow mode deactivated'; + notification.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + background: linear-gradient(45deg, #333, #666); + color: white; + padding: 15px 20px; + border-radius: 25px; + font-weight: bold; + font-size: 16px; + z-index: 1000; + border: 2px solid #999; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.3); + user-select: none; + pointer-events: none; + transition: opacity 0.3s ease; + `; + + document.body.appendChild(notification); + + // Auto-remove notification after 2 seconds + setTimeout(() => { + if (notification) { + notification.style.opacity = '0'; + setTimeout(() => { + if (notification.parentNode) { + notification.parentNode.removeChild(notification); + } + }, 300); + } + }, 2000); + }; + + const toggleTheme = useCallback(() => { + // Don't allow toggle if disabled + if (isToggleDisabled) { + return; + } + + const currentTime = Date.now(); + + // Simple exit from rainbow mode with single click (after cooldown period) + if (themeMode === 'rainbow') { + setThemeMode('light'); + console.log('🌈 Rainbow mode deactivated. Thanks for trying it!'); + showExitNotification(); + return; + } + + // Reset counter if too much time has passed (2.5 seconds) + if (currentTime - lastToggleTime.current > 2500) { + toggleCount.current = 1; + } else { + toggleCount.current++; + } + lastToggleTime.current = currentTime; + + // Easter egg: Activate rainbow mode after 6 rapid toggles + if (toggleCount.current >= 6) { + setThemeMode('rainbow'); + console.log('🌈 RAINBOW MODE ACTIVATED! 🌈 You found the secret easter egg!'); + console.log('🌈 Button will be disabled for 3 seconds, then click once to exit!'); + + // Disable toggle for 3 seconds + setIsToggleDisabled(true); + setTimeout(() => { + setIsToggleDisabled(false); + console.log('🌈 Theme toggle re-enabled! Click once to exit rainbow mode.'); + }, 3000); + + // Reset counter + toggleCount.current = 0; + return; + } + + // Normal theme switching + setThemeMode(prevMode => prevMode === 'light' ? 'dark' : 'light'); + }, [themeMode, isToggleDisabled]); + + const activateRainbow = useCallback(() => { + setThemeMode('rainbow'); + console.log('🌈 Rainbow mode manually activated!'); + }, []); + + const deactivateRainbow = useCallback(() => { + if (themeMode === 'rainbow') { + setThemeMode('light'); + console.log('🌈 Rainbow mode manually deactivated.'); + } + }, [themeMode]); + + return { + themeMode, + isRainbowMode: themeMode === 'rainbow', + isToggleDisabled, + toggleTheme, + activateRainbow, + deactivateRainbow, + }; +} \ No newline at end of file diff --git a/frontend/src/hooks/useThumbnailGeneration.ts b/frontend/src/hooks/useThumbnailGeneration.ts new file mode 100644 index 000000000..2d1138401 --- /dev/null +++ b/frontend/src/hooks/useThumbnailGeneration.ts @@ -0,0 +1,56 @@ +import { useCallback } from 'react'; +import { thumbnailGenerationService } from '../services/thumbnailGenerationService'; + +/** + * Hook for tools that want to use thumbnail generation + * Tools can choose whether to include visual features + */ +export function useThumbnailGeneration() { + const generateThumbnails = useCallback(async ( + pdfArrayBuffer: ArrayBuffer, + pageNumbers: number[], + options: { + scale?: number; + quality?: number; + batchSize?: number; + parallelBatches?: number; + } = {}, + onProgress?: (progress: { completed: number; total: number; thumbnails: any[] }) => void + ) => { + return thumbnailGenerationService.generateThumbnails( + pdfArrayBuffer, + pageNumbers, + options, + onProgress + ); + }, []); + + const addThumbnailToCache = useCallback((pageId: string, thumbnail: string) => { + thumbnailGenerationService.addThumbnailToCache(pageId, thumbnail); + }, []); + + const getThumbnailFromCache = useCallback((pageId: string): string | null => { + return thumbnailGenerationService.getThumbnailFromCache(pageId); + }, []); + + const getCacheStats = useCallback(() => { + return thumbnailGenerationService.getCacheStats(); + }, []); + + const stopGeneration = useCallback(() => { + thumbnailGenerationService.stopGeneration(); + }, []); + + const destroyThumbnails = useCallback(() => { + thumbnailGenerationService.destroy(); + }, []); + + return { + generateThumbnails, + addThumbnailToCache, + getThumbnailFromCache, + getCacheStats, + stopGeneration, + destroyThumbnails + }; +} \ No newline at end of file diff --git a/frontend/src/hooks/useToolManagement.tsx b/frontend/src/hooks/useToolManagement.tsx new file mode 100644 index 000000000..debd3f5b1 --- /dev/null +++ b/frontend/src/hooks/useToolManagement.tsx @@ -0,0 +1,155 @@ +import React, { useState, useCallback, useMemo, useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; +import ContentCutIcon from "@mui/icons-material/ContentCut"; +import ZoomInMapIcon from "@mui/icons-material/ZoomInMap"; +import SwapHorizIcon from "@mui/icons-material/SwapHoriz"; +import ApiIcon from "@mui/icons-material/Api"; +import { useMultipleEndpointsEnabled } from "./useEndpointConfig"; +import { Tool, ToolDefinition, BaseToolProps, ToolRegistry } from "../types/tool"; + + +// Add entry here with maxFiles, endpoints, and lazy component +const toolDefinitions: Record = { + split: { + id: "split", + icon: , + component: React.lazy(() => import("../tools/Split")), + maxFiles: 1, + category: "manipulation", + description: "Split PDF files into smaller parts", + endpoints: ["split-pages", "split-pdf-by-sections", "split-by-size-or-count", "split-pdf-by-chapters"] + }, + compress: { + id: "compress", + icon: , + component: React.lazy(() => import("../tools/Compress")), + maxFiles: -1, + category: "optimization", + description: "Reduce PDF file size", + endpoints: ["compress-pdf"] + }, + convert: { + id: "convert", + icon: , + component: React.lazy(() => import("../tools/Convert")), + maxFiles: -1, + category: "manipulation", + description: "Change to and from PDF and other formats", + endpoints: ["pdf-to-img", "img-to-pdf", "pdf-to-word", "pdf-to-presentation", "pdf-to-text", "pdf-to-html", "pdf-to-xml", "html-to-pdf", "markdown-to-pdf", "file-to-pdf"], + supportedFormats: [ + // Microsoft Office + "doc", "docx", "dot", "dotx", "csv", "xls", "xlsx", "xlt", "xltx", "slk", "dif", "ppt", "pptx", + // OpenDocument + "odt", "ott", "ods", "ots", "odp", "otp", "odg", "otg", + // Text formats + "txt", "text", "xml", "rtf", "html", "lwp", "md", + // Images + "bmp", "gif", "jpeg", "jpg", "png", "tif", "tiff", "pbm", "pgm", "ppm", "ras", "xbm", "xpm", "svg", "svm", "wmf", "webp", + // StarOffice + "sda", "sdc", "sdd", "sdw", "stc", "std", "sti", "stw", "sxd", "sxg", "sxi", "sxw", + // Email formats + "eml", + // Archive formats + "zip", + // Other + "dbf", "fods", "vsd", "vor", "vor3", "vor4", "uop", "pct", "ps", "pdf" + ] + }, + swagger: { + id: "swagger", + icon: , + component: React.lazy(() => import("../tools/SwaggerUI")), + maxFiles: 0, + category: "utility", + description: "Open API documentation", + endpoints: ["swagger-ui"] + }, + ocr: { + id: "ocr", + icon: + quick_reference_all + , + component: React.lazy(() => import("../tools/OCR")), + maxFiles: -1, + category: "utility", + description: "Extract text from images using OCR", + endpoints: ["ocr-pdf"] + }, + +}; + +interface ToolManagementResult { + selectedToolKey: string | null; + selectedTool: Tool | null; + toolSelectedFileIds: string[]; + toolRegistry: ToolRegistry; + selectTool: (toolKey: string) => void; + clearToolSelection: () => void; + setToolSelectedFileIds: (fileIds: string[]) => void; +} + +export const useToolManagement = (): ToolManagementResult => { + const { t } = useTranslation(); + + const [selectedToolKey, setSelectedToolKey] = useState(null); + const [toolSelectedFileIds, setToolSelectedFileIds] = useState([]); + + const allEndpoints = Array.from(new Set( + Object.values(toolDefinitions).flatMap(tool => tool.endpoints || []) + )); + const { endpointStatus, loading: endpointsLoading } = useMultipleEndpointsEnabled(allEndpoints); + + const isToolAvailable = useCallback((toolKey: string): boolean => { + if (endpointsLoading) return true; + const tool = toolDefinitions[toolKey]; + if (!tool?.endpoints) return true; + return tool.endpoints.some(endpoint => endpointStatus[endpoint] === true); + }, [endpointsLoading, endpointStatus]); + + const toolRegistry: ToolRegistry = useMemo(() => { + const availableTools: ToolRegistry = {}; + Object.keys(toolDefinitions).forEach(toolKey => { + if (isToolAvailable(toolKey)) { + const toolDef = toolDefinitions[toolKey]; + availableTools[toolKey] = { + ...toolDef, + name: t(`home.${toolKey}.title`, toolKey.charAt(0).toUpperCase() + toolKey.slice(1)) + }; + } + }); + return availableTools; + }, [t, isToolAvailable]); + + useEffect(() => { + if (!endpointsLoading && selectedToolKey && !toolRegistry[selectedToolKey]) { + const firstAvailableTool = Object.keys(toolRegistry)[0]; + if (firstAvailableTool) { + setSelectedToolKey(firstAvailableTool); + } else { + setSelectedToolKey(null); + } + } + }, [endpointsLoading, selectedToolKey, toolRegistry]); + + const selectTool = useCallback((toolKey: string) => { + setSelectedToolKey(toolKey); + }, []); + + const clearToolSelection = useCallback(() => { + setSelectedToolKey(null); + }, []); + + const selectedTool = selectedToolKey ? toolRegistry[selectedToolKey] : null; + + return { + selectedToolKey, + selectedTool, + toolSelectedFileIds, + toolRegistry, + + selectTool, + clearToolSelection, + setToolSelectedFileIds, + + }; +}; diff --git a/frontend/src/hooks/useToolParameters.ts b/frontend/src/hooks/useToolParameters.ts new file mode 100644 index 000000000..d6eae6d8b --- /dev/null +++ b/frontend/src/hooks/useToolParameters.ts @@ -0,0 +1,51 @@ +/** + * React hooks for tool parameter management (URL logic removed) + */ + +import { useCallback, useMemo } from 'react'; + +type ToolParameterValues = Record; + +/** + * Register tool parameters and get current values + */ +export function useToolParameters( + toolName: string, + parameters: Record +): [ToolParameterValues, (updates: Partial) => void] { + + // Return empty values and noop updater + const currentValues = useMemo(() => ({}), []); + const updateParameters = useCallback(() => {}, []); + + return [currentValues, updateParameters]; +} + +/** + * Hook for managing a single tool parameter + */ +export function useToolParameter( + toolName: string, + paramName: string, + definition: any +): [T, (value: T) => void] { + const [allParams, updateParams] = useToolParameters(toolName, { [paramName]: definition }); + + const value = allParams[paramName] as T; + + const setValue = useCallback((newValue: T) => { + updateParams({ [paramName]: newValue }); + }, [paramName, updateParams]); + + return [value, setValue]; +} + +/** + * Hook for getting/setting global parameters (zoom, page, etc.) + */ +export function useGlobalParameters() { + const currentValues = useMemo(() => ({}), []); + const updateParameters = useCallback(() => {}, []); + + return [currentValues, updateParameters]; +} \ No newline at end of file diff --git a/frontend/src/hooks/useTooltipPosition.ts b/frontend/src/hooks/useTooltipPosition.ts new file mode 100644 index 000000000..3651c1d47 --- /dev/null +++ b/frontend/src/hooks/useTooltipPosition.ts @@ -0,0 +1,177 @@ +import { useState, useEffect, useMemo } from 'react'; +import { clamp } from '../utils/genericUtils'; +import { getSidebarInfo } from '../utils/sidebarUtils'; +import { SidebarRefs, SidebarState } from '../types/sidebar'; + +type Position = 'right' | 'left' | 'top' | 'bottom'; + +interface PlacementResult { + top: number; + left: number; +} + +interface PositionState { + coords: { top: number; left: number; arrowOffset: number | null }; + positionReady: boolean; +} + +function place( + triggerRect: DOMRect, + tooltipRect: DOMRect, + position: Position, + offset: number +): PlacementResult { + let top = 0; + let left = 0; + + switch (position) { + case 'right': + top = triggerRect.top + triggerRect.height / 2 - tooltipRect.height / 2; + left = triggerRect.right + offset; + break; + case 'left': + top = triggerRect.top + triggerRect.height / 2 - tooltipRect.height / 2; + left = triggerRect.left - tooltipRect.width - offset; + break; + case 'top': + top = triggerRect.top - tooltipRect.height - offset; + left = triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2; + break; + case 'bottom': + top = triggerRect.bottom + offset; + left = triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2; + break; + } + + return { top, left }; +} + +export function useTooltipPosition({ + open, + sidebarTooltip, + position, + gap, + triggerRef, + tooltipRef, + sidebarRefs, + sidebarState +}: { + open: boolean; + sidebarTooltip: boolean; + position: Position; + gap: number; + triggerRef: React.RefObject; + tooltipRef: React.RefObject; + sidebarRefs?: SidebarRefs; + sidebarState?: SidebarState; +}): PositionState { + const [coords, setCoords] = useState<{ top: number; left: number; arrowOffset: number | null }>({ + top: 0, + left: 0, + arrowOffset: null + }); + const [positionReady, setPositionReady] = useState(false); + + // Fallback sidebar position (only used as last resort) + const sidebarLeft = 240; + + const updatePosition = () => { + if (!triggerRef.current || !open) return; + + const triggerRect = triggerRef.current.getBoundingClientRect(); + + let top: number; + let left: number; + let arrowOffset: number | null = null; + + if (sidebarTooltip) { + // Require sidebar refs and state for proper positioning + if (!sidebarRefs || !sidebarState) { + console.warn('āš ļø Sidebar tooltip requires sidebarRefs and sidebarState props'); + setPositionReady(false); + return; + } + + const sidebarInfo = getSidebarInfo(sidebarRefs, sidebarState); + const currentSidebarRight = sidebarInfo.rect ? sidebarInfo.rect.right : sidebarLeft; + + // Only show tooltip if we have the tool panel active + if (!sidebarInfo.isToolPanelActive) { + console.log('🚫 Not showing tooltip - tool panel not active'); + setPositionReady(false); + return; + } + + // Position to the right of active sidebar with 20px gap + left = currentSidebarRight + 20; + top = triggerRect.top; // Align top of tooltip with trigger element + + // Only clamp if we have tooltip dimensions + if (tooltipRef.current) { + const tooltipRect = tooltipRef.current.getBoundingClientRect(); + const maxTop = window.innerHeight - tooltipRect.height - 4; + const originalTop = top; + top = clamp(top, 4, maxTop); + + // If tooltip was clamped, adjust arrow position to stay aligned with trigger + if (originalTop !== top) { + arrowOffset = triggerRect.top + triggerRect.height / 2 - top; + } + } + + setCoords({ top, left, arrowOffset }); + setPositionReady(true); + } else { + // Regular tooltip logic + if (!tooltipRef.current) return; + + const tooltipRect = tooltipRef.current.getBoundingClientRect(); + const placement = place(triggerRect, tooltipRect, position, gap); + top = placement.top; + left = placement.left; + + // Clamp to viewport + top = clamp(top, 4, window.innerHeight - tooltipRect.height - 4); + left = clamp(left, 4, window.innerWidth - tooltipRect.width - 4); + + // Calculate arrow position to stay aligned with trigger + if (position === 'top' || position === 'bottom') { + // For top/bottom arrows, adjust horizontal position + const triggerCenter = triggerRect.left + triggerRect.width / 2; + const tooltipCenter = left + tooltipRect.width / 2; + if (Math.abs(triggerCenter - tooltipCenter) > 4) { + // Arrow needs adjustment + arrowOffset = triggerCenter - left - 4; // 4px is half arrow width + } + } else { + // For left/right arrows, adjust vertical position + const triggerCenter = triggerRect.top + triggerRect.height / 2; + const tooltipCenter = top + tooltipRect.height / 2; + if (Math.abs(triggerCenter - tooltipCenter) > 4) { + // Arrow needs adjustment + arrowOffset = triggerCenter - top - 4; // 4px is half arrow height + } + } + + setCoords({ top, left, arrowOffset }); + setPositionReady(true); + } + }; + + useEffect(() => { + if (!open) return; + + requestAnimationFrame(updatePosition); + + const handleUpdate = () => requestAnimationFrame(updatePosition); + window.addEventListener('scroll', handleUpdate, true); + window.addEventListener('resize', handleUpdate); + + return () => { + window.removeEventListener('scroll', handleUpdate, true); + window.removeEventListener('resize', handleUpdate); + }; + }, [open, sidebarLeft, position, gap, sidebarTooltip]); + + return { coords, positionReady }; +} \ No newline at end of file diff --git a/frontend/src/hooks/useTranslation.ts b/frontend/src/hooks/useTranslation.ts new file mode 100644 index 000000000..97a7aa032 --- /dev/null +++ b/frontend/src/hooks/useTranslation.ts @@ -0,0 +1,20 @@ +// Re-export react-i18next hook with our custom types +export { useTranslation } from 'react-i18next'; + +// You can add custom hooks here later if needed +// For example, a hook that returns commonly used translations +import { useTranslation as useI18nTranslation } from 'react-i18next'; + +export const useCommonTranslations = () => { + const { t } = useI18nTranslation(); + + return { + submit: t('genericSubmit'), + selectPdf: t('pdfPrompt'), + selectPdfs: t('multiPdfPrompt'), + selectImages: t('imgPrompt'), + loading: t('loading', 'Loading...'), // fallback if not found + error: t('error._value', 'Error'), + success: t('success', 'Success'), + }; +}; \ No newline at end of file diff --git a/frontend/src/hooks/useUndoRedo.ts b/frontend/src/hooks/useUndoRedo.ts new file mode 100644 index 000000000..6ce914a89 --- /dev/null +++ b/frontend/src/hooks/useUndoRedo.ts @@ -0,0 +1,68 @@ +import { useState, useCallback } from 'react'; + +export interface Command { + execute(): void; + undo(): void; + description: string; +} + +export interface CommandSequence { + commands: Command[]; + execute(): void; + undo(): void; + description: string; +} + +export function useUndoRedo() { + const [undoStack, setUndoStack] = useState<(Command | CommandSequence)[]>([]); + const [redoStack, setRedoStack] = useState<(Command | CommandSequence)[]>([]); + + const executeCommand = useCallback((command: Command | CommandSequence) => { + command.execute(); + setUndoStack(prev => [command, ...prev]); + setRedoStack([]); // Clear redo stack when new command is executed + }, []); + + const undo = useCallback(() => { + if (undoStack.length === 0) return false; + + const command = undoStack[0]; + command.undo(); + + setUndoStack(prev => prev.slice(1)); + setRedoStack(prev => [command, ...prev]); + + return true; + }, [undoStack]); + + const redo = useCallback(() => { + if (redoStack.length === 0) return false; + + const command = redoStack[0]; + command.execute(); + + setRedoStack(prev => prev.slice(1)); + setUndoStack(prev => [command, ...prev]); + + return true; + }, [redoStack]); + + const clear = useCallback(() => { + setUndoStack([]); + setRedoStack([]); + }, []); + + const canUndo = undoStack.length > 0; + const canRedo = redoStack.length > 0; + + return { + executeCommand, + undo, + redo, + clear, + canUndo, + canRedo, + undoStack, + redoStack + }; +} \ No newline at end of file diff --git a/frontend/src/i18n.ts b/frontend/src/i18n.ts new file mode 100644 index 000000000..a33a29929 --- /dev/null +++ b/frontend/src/i18n.ts @@ -0,0 +1,87 @@ +import i18n from 'i18next'; +import { initReactI18next } from 'react-i18next'; +import LanguageDetector from 'i18next-browser-languagedetector'; +import Backend from 'i18next-http-backend'; + +// Define supported languages (based on your existing translations) +export const supportedLanguages = { + 'en-GB': 'English (UK)', + 'en-US': 'English (US)', + 'ar-AR': 'Ų§Ł„Ų¹Ų±ŲØŁŠŲ©', + 'az-AZ': 'Azərbaycan Dili', + 'bg-BG': 'Š‘ŃŠŠ»Š³Š°Ń€ŃŠŗŠø', + 'ca-CA': 'CatalĆ ', + 'cs-CZ': 'Česky', + 'da-DK': 'Dansk', + 'de-DE': 'Deutsch', + 'el-GR': 'Ελληνικά', + 'es-ES': 'EspaƱol', + 'eu-ES': 'Euskara', + 'fa-IR': 'فارسی', + 'fr-FR': 'FranƧais', + 'ga-IE': 'Gaeilge', + 'hi-IN': 'ą¤¹ą¤æą¤‚ą¤¦ą„€', + 'hr-HR': 'Hrvatski', + 'hu-HU': 'Magyar', + 'id-ID': 'Bahasa Indonesia', + 'it-IT': 'Italiano', + 'ja-JP': 'ę—„ęœ¬čŖž', + 'ko-KR': 'ķ•œźµ­ģ–“', + 'ml-ML': 'ą“®ą“²ą“Æą“¾ą“³ą“‚', + 'nl-NL': 'Nederlands', + 'no-NB': 'Norsk', + 'pl-PL': 'Polski', + 'pt-BR': 'PortuguĆŖs (Brasil)', + 'pt-PT': 'PortuguĆŖs', + 'ro-RO': 'RomĆ¢nă', + 'ru-RU': 'Русский', + 'sk-SK': 'Slovensky', + 'sl-SI': 'SlovenŔčina', + 'sr-LATN-RS': 'Srpski', + 'sv-SE': 'Svenska', + 'th-TH': 'ไทย', + 'tr-TR': 'TürkƧe', + 'uk-UA': 'Š£ŠŗŃ€Š°Ń—Š½ŃŃŒŠŗŠ°', + 'vi-VN': 'Tiįŗæng Việt', + 'zh-BO': 'བོད་པིག', + 'zh-CN': '简体中文', + 'zh-TW': '繁體中文', +}; + +// RTL languages (based on your existing language.direction property) +export const rtlLanguages = ['ar-AR', 'fa-IR']; + +i18n + .use(Backend) + .use(LanguageDetector) + .use(initReactI18next) + .init({ + fallbackLng: 'en-GB', + debug: process.env.NODE_ENV === 'development', + + interpolation: { + escapeValue: false, // React already escapes values + }, + + backend: { + loadPath: '/locales/{{lng}}/{{ns}}.json', + }, + + detection: { + order: ['localStorage', 'navigator', 'htmlTag'], + caches: ['localStorage'], + }, + + react: { + useSuspense: false, // Set to false to avoid suspense issues with SSR + }, + }); + +// Set document direction based on language +i18n.on('languageChanged', (lng) => { + const isRTL = rtlLanguages.includes(lng); + document.documentElement.dir = isRTL ? 'rtl' : 'ltr'; + document.documentElement.lang = lng; +}); + +export default i18n; \ No newline at end of file diff --git a/frontend/src/i18n/config.ts b/frontend/src/i18n/config.ts new file mode 100644 index 000000000..2a7e6a431 --- /dev/null +++ b/frontend/src/i18n/config.ts @@ -0,0 +1,48 @@ +import i18n from 'i18next'; +import { initReactI18next } from 'react-i18next'; +import Backend from 'i18next-http-backend'; + +i18n + .use(Backend) + .use(initReactI18next) + .init({ + lng: 'en', + fallbackLng: 'en', + debug: false, + backend: { + loadPath: '/locales/{{lng}}/{{ns}}.json', + }, + interpolation: { + escapeValue: false, + }, + // For testing environment, provide fallback resources + resources: { + en: { + translation: { + 'convert.selectSourceFormat': 'Select source file format', + 'convert.selectTargetFormat': 'Select target file format', + 'convert.selectFirst': 'Select a source format first', + 'convert.imageOptions': 'Image Options:', + 'convert.emailOptions': 'Email Options:', + 'convert.colorType': 'Color Type', + 'convert.dpi': 'DPI', + 'convert.singleOrMultiple': 'Output', + 'convert.emailNote': 'Email attachments and embedded images will be included', + 'common.color': 'Color', + 'common.grayscale': 'Grayscale', + 'common.blackWhite': 'Black & White', + 'common.single': 'Single Image', + 'common.multiple': 'Multiple Images', + 'groups.document': 'Document', + 'groups.spreadsheet': 'Spreadsheet', + 'groups.presentation': 'Presentation', + 'groups.image': 'Image', + 'groups.web': 'Web', + 'groups.text': 'Text', + 'groups.email': 'Email' + } + } + } + }); + +export default i18n; \ No newline at end of file diff --git a/frontend/src/index.css b/frontend/src/index.css new file mode 100644 index 000000000..f7e5e0865 --- /dev/null +++ b/frontend/src/index.css @@ -0,0 +1,19 @@ +@import 'material-symbols/rounded.css'; + +.material-symbols-rounded { + font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24; +} + +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx new file mode 100644 index 000000000..e8d719e24 --- /dev/null +++ b/frontend/src/index.tsx @@ -0,0 +1,26 @@ +import '@mantine/core/styles.css'; +import './index.css'; // Import Tailwind CSS +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import { ColorSchemeScript, MantineProvider, mantineHtmlProps } from '@mantine/core'; +import { BrowserRouter } from 'react-router-dom'; +import App from './App'; +import './i18n'; // Initialize i18next + + +const container = document.getElementById('root'); +if (!container) { + throw new Error("Root container missing in index.html"); +} +const root = ReactDOM.createRoot(container); // Finds the root DOM element +root.render( + + + + + + + + +); + diff --git a/frontend/src/logo.svg b/frontend/src/logo.svg new file mode 100644 index 000000000..9dfc1c058 --- /dev/null +++ b/frontend/src/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/output.css b/frontend/src/output.css new file mode 100644 index 000000000..c77b20bc8 --- /dev/null +++ b/frontend/src/output.css @@ -0,0 +1,362 @@ +*, ::before, ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: +} +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: +} +.mb-3 { + margin-bottom: 0.75rem +} +.mb-4 { + margin-bottom: 1rem +} +.mr-2 { + margin-right: 0.5rem +} +.mt-2 { + margin-top: 0.5rem +} +.mt-4 { + margin-top: 1rem +} +.block { + display: block +} +.flex { + display: flex +} +.hidden { + display: none +} +.h-6 { + height: 1.5rem +} +.h-full { + height: 100% +} +.h-screen { + height: 100vh +} +.w-6 { + width: 1.5rem +} +.w-64 { + width: 16rem +} +.w-72 { + width: 18rem +} +.w-full { + width: 100% +} +.max-w-3xl { + max-width: 48rem +} +.flex-1 { + flex: 1 1 0% +} +.cursor-pointer { + cursor: pointer +} +.list-disc { + list-style-type: disc +} +.flex-col { + flex-direction: column +} +.items-center { + align-items: center +} +.justify-center { + justify-content: center +} +.justify-between { + justify-content: space-between +} +.space-x-2 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(0.5rem * var(--tw-space-x-reverse)); + margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))) +} +.space-x-3 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(0.75rem * var(--tw-space-x-reverse)); + margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))) +} +.space-y-2 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)) +} +.space-y-3 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)) +} +.space-y-4 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1rem * var(--tw-space-y-reverse)) +} +.overflow-hidden { + overflow: hidden +} +.overflow-y-auto { + overflow-y: auto +} +.rounded { + border-radius: 0.25rem +} +.rounded-md { + border-radius: 0.375rem +} +.border { + border-width: 1px +} +.border-b { + border-bottom-width: 1px +} +.border-l { + border-left-width: 1px +} +.border-r { + border-right-width: 1px +} +.border-none { + border-style: none +} +.bg-blue-600 { + --tw-bg-opacity: 1; + background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1)) +} +.bg-gray-100 { + --tw-bg-opacity: 1; + background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1)) +} +.bg-gray-50 { + --tw-bg-opacity: 1; + background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1)) +} +.bg-green-600 { + --tw-bg-opacity: 1; + background-color: rgb(22 163 74 / var(--tw-bg-opacity, 1)) +} +.bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)) +} +.p-2 { + padding: 0.5rem +} +.p-4 { + padding: 1rem +} +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem +} +.px-4 { + padding-left: 1rem; + padding-right: 1rem +} +.py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem +} +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem +} +.pl-5 { + padding-left: 1.25rem +} +.text-left { + text-align: left +} +.text-center { + text-align: center +} +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem +} +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem +} +.text-xl { + font-size: 1.25rem; + line-height: 1.75rem +} +.text-xs { + font-size: 0.75rem; + line-height: 1rem +} +.font-medium { + font-weight: 500 +} +.font-semibold { + font-weight: 600 +} +.leading-none { + line-height: 1 +} +.text-blue-600 { + --tw-text-opacity: 1; + color: rgb(37 99 235 / var(--tw-text-opacity, 1)) +} +.text-gray-500 { + --tw-text-opacity: 1; + color: rgb(107 114 128 / var(--tw-text-opacity, 1)) +} +.text-gray-600 { + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity, 1)) +} +.text-red-500 { + --tw-text-opacity: 1; + color: rgb(239 68 68 / var(--tw-text-opacity, 1)) +} +.text-red-600 { + --tw-text-opacity: 1; + color: rgb(220 38 38 / var(--tw-text-opacity, 1)) +} +.text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity, 1)) +} +.underline { + text-decoration-line: underline +} +.shadow { + --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) +} +.shadow-sm { + --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) +} +.grayscale { + --tw-grayscale: grayscale(100%); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) +} +.filter { + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) +} +.hover\:bg-blue-700:hover { + --tw-bg-opacity: 1; + background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1)) +} +.hover\:bg-gray-200:hover { + --tw-bg-opacity: 1; + background-color: rgb(229 231 235 / var(--tw-bg-opacity, 1)) +} +.hover\:bg-green-700:hover { + --tw-bg-opacity: 1; + background-color: rgb(21 128 61 / var(--tw-bg-opacity, 1)) +} +.hover\:underline:hover { + text-decoration-line: underline +} diff --git a/frontend/src/pages/HomePage.tsx b/frontend/src/pages/HomePage.tsx new file mode 100644 index 000000000..e9009282e --- /dev/null +++ b/frontend/src/pages/HomePage.tsx @@ -0,0 +1,63 @@ +import React, { useEffect } from "react"; +import { useFileContext } from "../contexts/FileContext"; +import { FileSelectionProvider, useFileSelection } from "../contexts/FileSelectionContext"; +import { ToolWorkflowProvider, useToolSelection } from "../contexts/ToolWorkflowContext"; +import { Group } from "@mantine/core"; +import { SidebarProvider, useSidebarContext } from "../contexts/SidebarContext"; + +import ToolPanel from "../components/tools/ToolPanel"; +import Workbench from "../components/layout/Workbench"; +import QuickAccessBar from "../components/shared/QuickAccessBar"; +import FileManager from "../components/FileManager"; + + +function HomePageContent() { + const { + sidebarRefs, + } = useSidebarContext(); + + const { quickAccessRef } = sidebarRefs; + + const { setMaxFiles, setIsToolMode, setSelectedFiles } = useFileSelection(); + + const { selectedTool } = useToolSelection(); + + // Update file selection context when tool changes + useEffect(() => { + if (selectedTool) { + setMaxFiles(selectedTool.maxFiles); + setIsToolMode(true); + } else { + setMaxFiles(-1); + setIsToolMode(false); + setSelectedFiles([]); + } + }, [selectedTool, setMaxFiles, setIsToolMode, setSelectedFiles]); + + return ( + + + + + + + ); +} + +export default function HomePage() { + const { setCurrentView } = useFileContext(); + return ( + + + + + + + + ); +} diff --git a/frontend/src/reportWebVitals.js b/frontend/src/reportWebVitals.js new file mode 100644 index 000000000..5253d3ad9 --- /dev/null +++ b/frontend/src/reportWebVitals.js @@ -0,0 +1,13 @@ +const reportWebVitals = onPerfEntry => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals; diff --git a/frontend/src/services/enhancedPDFProcessingService.ts b/frontend/src/services/enhancedPDFProcessingService.ts new file mode 100644 index 000000000..984d106e4 --- /dev/null +++ b/frontend/src/services/enhancedPDFProcessingService.ts @@ -0,0 +1,545 @@ +import { getDocument, GlobalWorkerOptions } from 'pdfjs-dist'; +import { ProcessedFile, ProcessingState, PDFPage, ProcessingStrategy, ProcessingConfig, ProcessingMetrics } from '../types/processing'; +import { ProcessingCache } from './processingCache'; +import { FileHasher } from '../utils/fileHash'; +import { FileAnalyzer } from './fileAnalyzer'; +import { ProcessingErrorHandler } from './processingErrorHandler'; + +// Set up PDF.js worker +GlobalWorkerOptions.workerSrc = '/pdf.worker.js'; + +export class EnhancedPDFProcessingService { + private static instance: EnhancedPDFProcessingService; + private cache = new ProcessingCache(); + private processing = new Map(); + private processingListeners = new Set<(states: Map) => void>(); + private metrics: ProcessingMetrics = { + totalFiles: 0, + completedFiles: 0, + failedFiles: 0, + averageProcessingTime: 0, + cacheHitRate: 0, + memoryUsage: 0 + }; + + private defaultConfig: ProcessingConfig = { + strategy: 'immediate_full', + chunkSize: 20, + thumbnailQuality: 'medium', + priorityPageCount: 10, + useWebWorker: false, + maxRetries: 3 + }; + + private constructor() {} + + static getInstance(): EnhancedPDFProcessingService { + if (!EnhancedPDFProcessingService.instance) { + EnhancedPDFProcessingService.instance = new EnhancedPDFProcessingService(); + } + return EnhancedPDFProcessingService.instance; + } + + /** + * Process a file with intelligent strategy selection + */ + async processFile(file: File, customConfig?: Partial): Promise { + const fileKey = await this.generateFileKey(file); + + // Check cache first + const cached = this.cache.get(fileKey); + if (cached) { + this.updateMetrics('cacheHit'); + return cached; + } + + // Check if already processing + if (this.processing.has(fileKey)) { + return null; + } + + // Analyze file to determine optimal strategy + const analysis = await FileAnalyzer.analyzeFile(file); + if (analysis.isCorrupted) { + throw new Error(`File ${file.name} appears to be corrupted`); + } + + // Create processing config + const config: ProcessingConfig = { + ...this.defaultConfig, + strategy: analysis.recommendedStrategy, + ...customConfig + }; + + // Start processing + this.startProcessing(file, fileKey, config, analysis.estimatedProcessingTime); + return null; + } + + /** + * Start processing a file with the specified configuration + */ + private async startProcessing( + file: File, + fileKey: string, + config: ProcessingConfig, + estimatedTime: number + ): Promise { + // Create cancellation token + const cancellationToken = new AbortController(); + + // Set initial state + const state: ProcessingState = { + fileKey, + fileName: file.name, + status: 'processing', + progress: 0, + strategy: config.strategy, + startedAt: Date.now(), + estimatedTimeRemaining: estimatedTime, + cancellationToken + }; + + this.processing.set(fileKey, state); + this.notifyListeners(); + this.updateMetrics('started'); + + try { + // Execute processing with retry logic + const processedFile = await ProcessingErrorHandler.executeWithRetry( + () => this.executeProcessingStrategy(file, config, state), + (error) => { + state.error = error; + this.notifyListeners(); + }, + config.maxRetries + ); + + // Cache the result + this.cache.set(fileKey, processedFile); + + // Update state to completed + state.status = 'completed'; + state.progress = 100; + state.completedAt = Date.now(); + this.notifyListeners(); + this.updateMetrics('completed', Date.now() - state.startedAt); + + // Remove from processing map after brief delay + setTimeout(() => { + this.processing.delete(fileKey); + this.notifyListeners(); + }, 2000); + + } catch (error) { + console.error('Processing failed for', file.name, ':', error); + + const processingError = ProcessingErrorHandler.createProcessingError(error); + state.status = 'error'; + state.error = processingError; + this.notifyListeners(); + this.updateMetrics('failed'); + + // Remove failed processing after delay + setTimeout(() => { + this.processing.delete(fileKey); + this.notifyListeners(); + }, 10000); + } + } + + /** + * Execute the actual processing based on strategy + */ + private async executeProcessingStrategy( + file: File, + config: ProcessingConfig, + state: ProcessingState + ): Promise { + switch (config.strategy) { + case 'immediate_full': + return this.processImmediateFull(file, config, state); + + case 'priority_pages': + return this.processPriorityPages(file, config, state); + + case 'progressive_chunked': + return this.processProgressiveChunked(file, config, state); + + case 'metadata_only': + return this.processMetadataOnly(file, config, state); + + default: + return this.processImmediateFull(file, config, state); + } + } + + /** + * Process all pages immediately (for small files) + */ + private async processImmediateFull( + file: File, + config: ProcessingConfig, + state: ProcessingState + ): Promise { + const arrayBuffer = await file.arrayBuffer(); + const pdf = await getDocument({ data: arrayBuffer }).promise; + const totalPages = pdf.numPages; + + state.progress = 10; + this.notifyListeners(); + + const pages: PDFPage[] = []; + + for (let i = 1; i <= totalPages; i++) { + // Check for cancellation + if (state.cancellationToken?.signal.aborted) { + pdf.destroy(); + throw new Error('Processing cancelled'); + } + + const page = await pdf.getPage(i); + const thumbnail = await this.renderPageThumbnail(page, config.thumbnailQuality); + + pages.push({ + id: `${file.name}-page-${i}`, + pageNumber: i, + thumbnail, + rotation: 0, + selected: false + }); + + // Update progress + state.progress = 10 + (i / totalPages) * 85; + state.currentPage = i; + this.notifyListeners(); + } + + pdf.destroy(); + state.progress = 100; + this.notifyListeners(); + + return this.createProcessedFile(file, pages, totalPages); + } + + /** + * Process priority pages first, then queue the rest + */ + private async processPriorityPages( + file: File, + config: ProcessingConfig, + state: ProcessingState + ): Promise { + const arrayBuffer = await file.arrayBuffer(); + const pdf = await getDocument({ data: arrayBuffer }).promise; + const totalPages = pdf.numPages; + + state.progress = 10; + this.notifyListeners(); + + const pages: PDFPage[] = []; + const priorityCount = Math.min(config.priorityPageCount, totalPages); + + // Process priority pages first + for (let i = 1; i <= priorityCount; i++) { + if (state.cancellationToken?.signal.aborted) { + pdf.destroy(); + throw new Error('Processing cancelled'); + } + + const page = await pdf.getPage(i); + const thumbnail = await this.renderPageThumbnail(page, config.thumbnailQuality); + + pages.push({ + id: `${file.name}-page-${i}`, + pageNumber: i, + thumbnail, + rotation: 0, + selected: false + }); + + state.progress = 10 + (i / priorityCount) * 60; + state.currentPage = i; + this.notifyListeners(); + } + + // Create placeholder pages for remaining pages + for (let i = priorityCount + 1; i <= totalPages; i++) { + pages.push({ + id: `${file.name}-page-${i}`, + pageNumber: i, + thumbnail: null, // Will be loaded lazily + rotation: 0, + selected: false + }); + } + + pdf.destroy(); + state.progress = 100; + this.notifyListeners(); + + return this.createProcessedFile(file, pages, totalPages); + } + + /** + * Process in chunks with breaks between chunks + */ + private async processProgressiveChunked( + file: File, + config: ProcessingConfig, + state: ProcessingState + ): Promise { + const arrayBuffer = await file.arrayBuffer(); + const pdf = await getDocument({ data: arrayBuffer }).promise; + const totalPages = pdf.numPages; + + state.progress = 10; + this.notifyListeners(); + + const pages: PDFPage[] = []; + const chunkSize = config.chunkSize; + let processedPages = 0; + + // Process first chunk immediately + const firstChunkEnd = Math.min(chunkSize, totalPages); + + for (let i = 1; i <= firstChunkEnd; i++) { + if (state.cancellationToken?.signal.aborted) { + pdf.destroy(); + throw new Error('Processing cancelled'); + } + + const page = await pdf.getPage(i); + const thumbnail = await this.renderPageThumbnail(page, config.thumbnailQuality); + + pages.push({ + id: `${file.name}-page-${i}`, + pageNumber: i, + thumbnail, + rotation: 0, + selected: false + }); + + processedPages++; + state.progress = 10 + (processedPages / totalPages) * 70; + state.currentPage = i; + this.notifyListeners(); + + // Small delay to prevent UI blocking + if (i % 5 === 0) { + await new Promise(resolve => setTimeout(resolve, 10)); + } + } + + // Create placeholders for remaining pages + for (let i = firstChunkEnd + 1; i <= totalPages; i++) { + pages.push({ + id: `${file.name}-page-${i}`, + pageNumber: i, + thumbnail: null, + rotation: 0, + selected: false + }); + } + + pdf.destroy(); + state.progress = 100; + this.notifyListeners(); + + return this.createProcessedFile(file, pages, totalPages); + } + + /** + * Process metadata only (for very large files) + */ + private async processMetadataOnly( + file: File, + config: ProcessingConfig, + state: ProcessingState + ): Promise { + const arrayBuffer = await file.arrayBuffer(); + const pdf = await getDocument({ data: arrayBuffer }).promise; + const totalPages = pdf.numPages; + + state.progress = 50; + this.notifyListeners(); + + // Create placeholder pages without thumbnails + const pages: PDFPage[] = []; + for (let i = 1; i <= totalPages; i++) { + pages.push({ + id: `${file.name}-page-${i}`, + pageNumber: i, + thumbnail: null, + rotation: 0, + selected: false + }); + } + + pdf.destroy(); + state.progress = 100; + this.notifyListeners(); + + return this.createProcessedFile(file, pages, totalPages); + } + + /** + * Render a page thumbnail with specified quality + */ + private async renderPageThumbnail(page: any, quality: 'low' | 'medium' | 'high'): Promise { + const scales = { low: 0.2, medium: 0.5, high: 0.8 }; // Reduced low quality for page editor + const scale = scales[quality]; + + const viewport = page.getViewport({ scale }); + const canvas = document.createElement('canvas'); + canvas.width = viewport.width; + canvas.height = viewport.height; + + const context = canvas.getContext('2d'); + if (!context) { + throw new Error('Could not get canvas context'); + } + + await page.render({ canvasContext: context, viewport }).promise; + return canvas.toDataURL('image/jpeg', 0.8); // Use JPEG for better compression + } + + /** + * Create a ProcessedFile object + */ + private createProcessedFile(file: File, pages: PDFPage[], totalPages: number): ProcessedFile { + return { + id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, + pages, + totalPages, + metadata: { + title: file.name, + createdAt: new Date().toISOString(), + modifiedAt: new Date().toISOString() + } + }; + } + + + /** + * Generate a unique, collision-resistant cache key + */ + private async generateFileKey(file: File): Promise { + return await FileHasher.generateHybridHash(file); + } + + /** + * Cancel processing for a specific file + */ + cancelProcessing(fileKey: string): void { + const state = this.processing.get(fileKey); + if (state && state.cancellationToken) { + state.cancellationToken.abort(); + state.status = 'cancelled'; + this.notifyListeners(); + } + } + + /** + * Update processing metrics + */ + private updateMetrics(event: 'started' | 'completed' | 'failed' | 'cacheHit', processingTime?: number): void { + switch (event) { + case 'started': + this.metrics.totalFiles++; + break; + case 'completed': + this.metrics.completedFiles++; + if (processingTime) { + // Update rolling average + const totalProcessingTime = this.metrics.averageProcessingTime * (this.metrics.completedFiles - 1) + processingTime; + this.metrics.averageProcessingTime = totalProcessingTime / this.metrics.completedFiles; + } + break; + case 'failed': + this.metrics.failedFiles++; + break; + case 'cacheHit': + // Update cache hit rate + const totalAttempts = this.metrics.totalFiles + 1; + this.metrics.cacheHitRate = (this.metrics.cacheHitRate * this.metrics.totalFiles + 1) / totalAttempts; + break; + } + } + + /** + * Get processing metrics + */ + getMetrics(): ProcessingMetrics { + return { ...this.metrics }; + } + + /** + * State subscription for components + */ + onProcessingChange(callback: (states: Map) => void): () => void { + this.processingListeners.add(callback); + return () => this.processingListeners.delete(callback); + } + + getProcessingStates(): Map { + return new Map(this.processing); + } + + private notifyListeners(): void { + this.processingListeners.forEach(callback => callback(this.processing)); + } + + /** + * Cleanup method for removed files + */ + cleanup(removedFiles: File[]): void { + removedFiles.forEach(async (file) => { + const key = await this.generateFileKey(file); + this.cache.delete(key); + this.cancelProcessing(key); + this.processing.delete(key); + }); + this.notifyListeners(); + } + + /** + * Clear all processing for view switches + */ + clearAllProcessing(): void { + // Cancel all ongoing processing + this.processing.forEach((state, key) => { + if (state.cancellationToken) { + state.cancellationToken.abort(); + } + }); + + // Clear processing states + this.processing.clear(); + this.notifyListeners(); + + // Force memory cleanup hint + if (typeof window !== 'undefined' && window.gc) { + setTimeout(() => window.gc(), 100); + } + } + + /** + * Get cache statistics + */ + getCacheStats() { + return this.cache.getStats(); + } + + /** + * Clear all cache and processing + */ + clearAll(): void { + this.cache.clear(); + this.processing.clear(); + this.notifyListeners(); + } +} + +// Export singleton instance +export const enhancedPDFProcessingService = EnhancedPDFProcessingService.getInstance(); \ No newline at end of file diff --git a/frontend/src/services/fileAnalyzer.ts b/frontend/src/services/fileAnalyzer.ts new file mode 100644 index 000000000..2a9f15cff --- /dev/null +++ b/frontend/src/services/fileAnalyzer.ts @@ -0,0 +1,240 @@ +import { getDocument } from 'pdfjs-dist'; +import { FileAnalysis, ProcessingStrategy } from '../types/processing'; + +export class FileAnalyzer { + private static readonly SIZE_THRESHOLDS = { + SMALL: 10 * 1024 * 1024, // 10MB + MEDIUM: 50 * 1024 * 1024, // 50MB + LARGE: 200 * 1024 * 1024, // 200MB + }; + + private static readonly PAGE_THRESHOLDS = { + FEW: 10, // < 10 pages - immediate full processing + MANY: 50, // < 50 pages - priority pages + MASSIVE: 100, // < 100 pages - progressive chunked + // >100 pages = metadata only + }; + + /** + * Analyze a file to determine optimal processing strategy + */ + static async analyzeFile(file: File): Promise { + const analysis: FileAnalysis = { + fileSize: file.size, + isEncrypted: false, + isCorrupted: false, + recommendedStrategy: 'metadata_only', + estimatedProcessingTime: 0, + }; + + try { + // Quick validation and page count estimation + const quickAnalysis = await this.quickPDFAnalysis(file); + analysis.estimatedPageCount = quickAnalysis.pageCount; + analysis.isEncrypted = quickAnalysis.isEncrypted; + analysis.isCorrupted = quickAnalysis.isCorrupted; + + // Determine strategy based on file characteristics + analysis.recommendedStrategy = this.determineStrategy(file.size, quickAnalysis.pageCount); + + // Estimate processing time + analysis.estimatedProcessingTime = this.estimateProcessingTime( + file.size, + quickAnalysis.pageCount, + analysis.recommendedStrategy + ); + + } catch (error) { + console.error('File analysis failed:', error); + analysis.isCorrupted = true; + analysis.recommendedStrategy = 'metadata_only'; + } + + return analysis; + } + + /** + * Quick PDF analysis without full processing + */ + private static async quickPDFAnalysis(file: File): Promise<{ + pageCount: number; + isEncrypted: boolean; + isCorrupted: boolean; + }> { + try { + // For small files, read the whole file + // For large files, try the whole file first (PDF.js needs the complete structure) + const arrayBuffer = await file.arrayBuffer(); + + const pdf = await getDocument({ + data: arrayBuffer, + stopAtErrors: false, // Don't stop at minor errors + verbosity: 0 // Suppress PDF.js warnings + }).promise; + + const pageCount = pdf.numPages; + const isEncrypted = pdf.isEncrypted; + + // Clean up + pdf.destroy(); + + return { + pageCount, + isEncrypted, + isCorrupted: false + }; + + } catch (error) { + // Try to determine if it's corruption vs encryption + const errorMessage = error instanceof Error ? error.message.toLowerCase() : ''; + const isEncrypted = errorMessage.includes('password') || errorMessage.includes('encrypted'); + + return { + pageCount: 0, + isEncrypted, + isCorrupted: !isEncrypted // If not encrypted, probably corrupted + }; + } + } + + /** + * Determine the best processing strategy based on file characteristics + */ + private static determineStrategy(fileSize: number, pageCount?: number): ProcessingStrategy { + // Handle corrupted or encrypted files + if (!pageCount || pageCount === 0) { + return 'metadata_only'; + } + + // Small files with few pages - process everything immediately + if (fileSize <= this.SIZE_THRESHOLDS.SMALL && pageCount <= this.PAGE_THRESHOLDS.FEW) { + return 'immediate_full'; + } + + // Medium files or many pages - priority pages first, then progressive + if (fileSize <= this.SIZE_THRESHOLDS.MEDIUM && pageCount <= this.PAGE_THRESHOLDS.MANY) { + return 'priority_pages'; + } + + // Large files or massive page counts - chunked processing + if (fileSize <= this.SIZE_THRESHOLDS.LARGE && pageCount <= this.PAGE_THRESHOLDS.MASSIVE) { + return 'progressive_chunked'; + } + + // Very large files - metadata only + return 'metadata_only'; + } + + /** + * Estimate processing time based on file characteristics and strategy + */ + private static estimateProcessingTime( + fileSize: number, + pageCount: number = 0, + strategy: ProcessingStrategy + ): number { + const baseTimes = { + immediate_full: 200, // 200ms per page + priority_pages: 150, // 150ms per page (optimized) + progressive_chunked: 100, // 100ms per page (chunked) + metadata_only: 50 // 50ms total + }; + + const baseTime = baseTimes[strategy]; + + switch (strategy) { + case 'metadata_only': + return baseTime; + + case 'immediate_full': + return pageCount * baseTime; + + case 'priority_pages': + // Estimate time for priority pages (first 10) + const priorityPages = Math.min(pageCount, 10); + return priorityPages * baseTime; + + case 'progressive_chunked': + // Estimate time for first chunk (20 pages) + const firstChunk = Math.min(pageCount, 20); + return firstChunk * baseTime; + + default: + return pageCount * baseTime; + } + } + + /** + * Get processing recommendations for a set of files + */ + static async analyzeMultipleFiles(files: File[]): Promise<{ + analyses: Map; + recommendations: { + totalEstimatedTime: number; + suggestedBatchSize: number; + shouldUseWebWorker: boolean; + memoryWarning: boolean; + }; + }> { + const analyses = new Map(); + let totalEstimatedTime = 0; + let totalSize = 0; + let totalPages = 0; + + // Analyze each file + for (const file of files) { + const analysis = await this.analyzeFile(file); + analyses.set(file, analysis); + totalEstimatedTime += analysis.estimatedProcessingTime; + totalSize += file.size; + totalPages += analysis.estimatedPageCount || 0; + } + + // Generate recommendations + const recommendations = { + totalEstimatedTime, + suggestedBatchSize: this.calculateBatchSize(files.length, totalSize), + shouldUseWebWorker: totalPages > 100 || totalSize > this.SIZE_THRESHOLDS.MEDIUM, + memoryWarning: totalSize > this.SIZE_THRESHOLDS.LARGE || totalPages > this.PAGE_THRESHOLDS.MASSIVE + }; + + return { analyses, recommendations }; + } + + /** + * Calculate optimal batch size for processing multiple files + */ + private static calculateBatchSize(fileCount: number, totalSize: number): number { + // Process small batches for large total sizes + if (totalSize > this.SIZE_THRESHOLDS.LARGE) { + return Math.max(1, Math.floor(fileCount / 4)); + } + + if (totalSize > this.SIZE_THRESHOLDS.MEDIUM) { + return Math.max(2, Math.floor(fileCount / 2)); + } + + // Process all at once for smaller total sizes + return fileCount; + } + + /** + * Check if a file appears to be a valid PDF + */ + static async isValidPDF(file: File): Promise { + if (file.type !== 'application/pdf' && !file.name.toLowerCase().endsWith('.pdf')) { + return false; + } + + try { + // Read first few bytes to check PDF header + const header = file.slice(0, 8); + const headerBytes = new Uint8Array(await header.arrayBuffer()); + const headerString = String.fromCharCode(...headerBytes); + + return headerString.startsWith('%PDF-'); + } catch (error) { + return false; + } + } +} \ No newline at end of file diff --git a/frontend/src/services/fileOperationsService.ts b/frontend/src/services/fileOperationsService.ts new file mode 100644 index 000000000..d13965837 --- /dev/null +++ b/frontend/src/services/fileOperationsService.ts @@ -0,0 +1,194 @@ +import { FileWithUrl } from "../types/file"; +import { fileStorage, StorageStats } from "./fileStorage"; +import { loadFilesFromIndexedDB, createEnhancedFileFromStored, cleanupFileUrls } from "../utils/fileUtils"; +import { generateThumbnailForFile } from "../utils/thumbnailUtils"; +import { updateStorageStatsIncremental } from "../utils/storageUtils"; + +/** + * Service for file storage operations + * Contains all IndexedDB operations and file management logic + */ +export const fileOperationsService = { + + /** + * Load storage statistics + */ + async loadStorageStats(): Promise { + try { + return await fileStorage.getStorageStats(); + } catch (error) { + console.error('Failed to load storage stats:', error); + return null; + } + }, + + /** + * Force reload files from IndexedDB + */ + async forceReloadFiles(): Promise { + try { + return await loadFilesFromIndexedDB(); + } catch (error) { + console.error('Failed to force reload files:', error); + return []; + } + }, + + /** + * Load existing files from IndexedDB if not already loaded + */ + async loadExistingFiles( + filesLoaded: boolean, + currentFiles: FileWithUrl[] + ): Promise { + if (filesLoaded && currentFiles.length > 0) { + return currentFiles; + } + + try { + await fileStorage.init(); + const storedFiles = await fileStorage.getAllFileMetadata(); + + // Detect if IndexedDB was purged by comparing with current UI state + if (currentFiles.length > 0 && storedFiles.length === 0) { + console.warn('IndexedDB appears to have been purged - clearing UI state'); + return []; + } + + return await loadFilesFromIndexedDB(); + } catch (error) { + console.error('Failed to load existing files:', error); + return []; + } + }, + + /** + * Upload files to IndexedDB with thumbnail generation + */ + async uploadFiles( + uploadedFiles: File[], + useIndexedDB: boolean + ): Promise { + const newFiles: FileWithUrl[] = []; + + for (const file of uploadedFiles) { + if (useIndexedDB) { + try { + console.log('Storing file in IndexedDB:', file.name); + + // Generate thumbnail only during upload + const thumbnail = await generateThumbnailForFile(file); + + const storedFile = await fileStorage.storeFile(file, thumbnail); + console.log('File stored with ID:', storedFile.id); + + const baseFile = fileStorage.createFileFromStored(storedFile); + const enhancedFile = createEnhancedFileFromStored(storedFile, thumbnail); + + // Copy File interface methods from baseFile + enhancedFile.arrayBuffer = baseFile.arrayBuffer.bind(baseFile); + enhancedFile.slice = baseFile.slice.bind(baseFile); + enhancedFile.stream = baseFile.stream.bind(baseFile); + enhancedFile.text = baseFile.text.bind(baseFile); + + newFiles.push(enhancedFile); + } catch (error) { + console.error('Failed to store file in IndexedDB:', error); + // Fallback to RAM storage + const enhancedFile: FileWithUrl = Object.assign(file, { + url: URL.createObjectURL(file), + storedInIndexedDB: false + }); + newFiles.push(enhancedFile); + } + } else { + // IndexedDB disabled - use RAM + const enhancedFile: FileWithUrl = Object.assign(file, { + url: URL.createObjectURL(file), + storedInIndexedDB: false + }); + newFiles.push(enhancedFile); + } + } + + return newFiles; + }, + + /** + * Remove a file from storage + */ + async removeFile(file: FileWithUrl): Promise { + // Clean up blob URL + if (file.url && !file.url.startsWith('indexeddb:')) { + URL.revokeObjectURL(file.url); + } + + // Remove from IndexedDB if stored there + if (file.storedInIndexedDB && file.id) { + try { + await fileStorage.deleteFile(file.id); + } catch (error) { + console.error('Failed to delete file from IndexedDB:', error); + } + } + }, + + /** + * Clear all files from storage + */ + async clearAllFiles(files: FileWithUrl[]): Promise { + // Clean up all blob URLs + cleanupFileUrls(files); + + // Clear IndexedDB + try { + await fileStorage.clearAll(); + } catch (error) { + console.error('Failed to clear IndexedDB:', error); + } + }, + + /** + * Create blob URL for file viewing + */ + async createBlobUrlForFile(file: FileWithUrl): Promise { + // For large files, use IndexedDB direct access to avoid memory issues + const FILE_SIZE_LIMIT = 100 * 1024 * 1024; // 100MB + if (file.size > FILE_SIZE_LIMIT) { + console.warn(`File ${file.name} is too large for blob URL. Use direct IndexedDB access.`); + return `indexeddb:${file.id}`; + } + + // For all files, avoid persistent blob URLs + if (file.storedInIndexedDB && file.id) { + const storedFile = await fileStorage.getFile(file.id); + if (storedFile) { + return fileStorage.createBlobUrl(storedFile); + } + } + + // Fallback for files not in IndexedDB + return URL.createObjectURL(file); + }, + + /** + * Check for IndexedDB purge + */ + async checkForPurge(currentFiles: FileWithUrl[]): Promise { + if (currentFiles.length === 0) return false; + + try { + await fileStorage.init(); + const storedFiles = await fileStorage.getAllFileMetadata(); + return storedFiles.length === 0; // Purge detected if no files in storage but UI shows files + } catch (error) { + console.error('Error checking for purge:', error); + return true; // Assume purged if can't access IndexedDB + } + }, + + /** + * Update storage stats incrementally (re-export utility for convenience) + */ + updateStorageStatsIncremental +}; \ No newline at end of file diff --git a/frontend/src/services/fileStorage.ts b/frontend/src/services/fileStorage.ts new file mode 100644 index 000000000..5fd5739e8 --- /dev/null +++ b/frontend/src/services/fileStorage.ts @@ -0,0 +1,602 @@ +/** + * IndexedDB File Storage Service + * Provides high-capacity file storage for PDF processing + */ + +export interface StoredFile { + id: string; + name: string; + type: string; + size: number; + lastModified: number; + data: ArrayBuffer; + thumbnail?: string; + url?: string; // For compatibility with existing components +} + +export interface StorageStats { + used: number; + available: number; + fileCount: number; + quota?: number; +} + +class FileStorageService { + private dbName = 'stirling-pdf-files'; + private dbVersion = 2; // Increment version to force schema update + private storeName = 'files'; + private db: IDBDatabase | null = null; + private initPromise: Promise | null = null; + + /** + * Initialize the IndexedDB database (singleton pattern) + */ + async init(): Promise { + if (this.db) { + return Promise.resolve(); + } + + if (this.initPromise) { + return this.initPromise; + } + + this.initPromise = new Promise((resolve, reject) => { + const request = indexedDB.open(this.dbName, this.dbVersion); + + request.onerror = () => { + this.initPromise = null; + reject(request.error); + }; + + request.onsuccess = () => { + this.db = request.result; + console.log('IndexedDB connection established'); + resolve(); + }; + + request.onupgradeneeded = (event) => { + const db = (event.target as IDBOpenDBRequest).result; + const oldVersion = (event as any).oldVersion; + + console.log('IndexedDB upgrade needed from version', oldVersion, 'to', this.dbVersion); + + // Only recreate object store if it doesn't exist or if upgrading from version < 2 + if (!db.objectStoreNames.contains(this.storeName)) { + const store = db.createObjectStore(this.storeName, { keyPath: 'id' }); + store.createIndex('name', 'name', { unique: false }); + store.createIndex('lastModified', 'lastModified', { unique: false }); + console.log('IndexedDB object store created with keyPath: id'); + } else if (oldVersion < 2) { + // Only delete and recreate if upgrading from version 1 to 2 + db.deleteObjectStore(this.storeName); + const store = db.createObjectStore(this.storeName, { keyPath: 'id' }); + store.createIndex('name', 'name', { unique: false }); + store.createIndex('lastModified', 'lastModified', { unique: false }); + console.log('IndexedDB object store recreated with keyPath: id (version upgrade)'); + } + }; + }); + + return this.initPromise; + } + + /** + * Store a file in IndexedDB + */ + async storeFile(file: File, thumbnail?: string): Promise { + if (!this.db) await this.init(); + + const id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + const arrayBuffer = await file.arrayBuffer(); + + const storedFile: StoredFile = { + id, + name: file.name, + type: file.type, + size: file.size, + lastModified: file.lastModified, + data: arrayBuffer, + thumbnail + }; + + return new Promise((resolve, reject) => { + try { + const transaction = this.db!.transaction([this.storeName], 'readwrite'); + const store = transaction.objectStore(this.storeName); + + // Debug logging + console.log('Object store keyPath:', store.keyPath); + console.log('Storing file:', { + id: storedFile.id, + name: storedFile.name, + hasData: !!storedFile.data, + dataSize: storedFile.data.byteLength + }); + + const request = store.add(storedFile); + + request.onerror = () => { + console.error('IndexedDB add error:', request.error); + console.error('Failed object:', storedFile); + reject(request.error); + }; + request.onsuccess = () => { + console.log('File stored successfully with ID:', storedFile.id); + resolve(storedFile); + }; + } catch (error) { + console.error('Transaction error:', error); + reject(error); + } + }); + } + + /** + * Retrieve a file from IndexedDB + */ + async getFile(id: string): Promise { + if (!this.db) await this.init(); + + return new Promise((resolve, reject) => { + const transaction = this.db!.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + const request = store.get(id); + + request.onerror = () => reject(request.error); + request.onsuccess = () => resolve(request.result || null); + }); + } + + /** + * Get all stored files (WARNING: loads all data into memory) + */ + async getAllFiles(): Promise { + if (!this.db) await this.init(); + + return new Promise((resolve, reject) => { + const transaction = this.db!.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + const request = store.getAll(); + + request.onerror = () => reject(request.error); + request.onsuccess = () => { + // Filter out null/corrupted entries + const files = request.result.filter(file => + file && + file.data && + file.name && + typeof file.size === 'number' + ); + resolve(files); + }; + }); + } + + /** + * Get metadata of all stored files (without loading data into memory) + */ + async getAllFileMetadata(): Promise[]> { + if (!this.db) await this.init(); + + return new Promise((resolve, reject) => { + const transaction = this.db!.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + const request = store.openCursor(); + const files: Omit[] = []; + + request.onerror = () => reject(request.error); + request.onsuccess = (event) => { + const cursor = (event.target as IDBRequest).result; + if (cursor) { + const storedFile = cursor.value; + // Only extract metadata, skip the data field + if (storedFile && storedFile.name && typeof storedFile.size === 'number') { + files.push({ + id: storedFile.id, + name: storedFile.name, + type: storedFile.type, + size: storedFile.size, + lastModified: storedFile.lastModified, + thumbnail: storedFile.thumbnail + }); + } + cursor.continue(); + } else { + console.log('Loaded metadata for', files.length, 'files without loading data'); + resolve(files); + } + }; + }); + } + + /** + * Delete a file from IndexedDB + */ + async deleteFile(id: string): Promise { + if (!this.db) await this.init(); + + return new Promise((resolve, reject) => { + const transaction = this.db!.transaction([this.storeName], 'readwrite'); + const store = transaction.objectStore(this.storeName); + const request = store.delete(id); + + request.onerror = () => reject(request.error); + request.onsuccess = () => resolve(); + }); + } + + /** + * Update the lastModified timestamp of a file (for most recently used sorting) + */ + async touchFile(id: string): Promise { + if (!this.db) await this.init(); + return new Promise((resolve, reject) => { + const transaction = this.db!.transaction([this.storeName], 'readwrite'); + const store = transaction.objectStore(this.storeName); + + const getRequest = store.get(id); + getRequest.onsuccess = () => { + const file = getRequest.result; + if (file) { + // Update lastModified to current timestamp + file.lastModified = Date.now(); + const updateRequest = store.put(file); + updateRequest.onsuccess = () => resolve(true); + updateRequest.onerror = () => reject(updateRequest.error); + } else { + resolve(false); // File not found + } + }; + getRequest.onerror = () => reject(getRequest.error); + }); + } + + /** + * Clear all stored files + */ + async clearAll(): Promise { + if (!this.db) await this.init(); + + return new Promise((resolve, reject) => { + const transaction = this.db!.transaction([this.storeName], 'readwrite'); + const store = transaction.objectStore(this.storeName); + const request = store.clear(); + + request.onerror = () => reject(request.error); + request.onsuccess = () => resolve(); + }); + } + + /** + * Get storage statistics (only our IndexedDB usage) + */ + async getStorageStats(): Promise { + if (!this.db) await this.init(); + + let used = 0; + let available = 0; + let quota: number | undefined; + let fileCount = 0; + + try { + // Get browser quota for context + if ('storage' in navigator && 'estimate' in navigator.storage) { + const estimate = await navigator.storage.estimate(); + quota = estimate.quota; + available = estimate.quota || 0; + } + + // Calculate our actual IndexedDB usage from file metadata + const files = await this.getAllFileMetadata(); + used = files.reduce((total, file) => total + (file?.size || 0), 0); + fileCount = files.length; + + // Adjust available space + if (quota) { + available = quota - used; + } + + } catch (error) { + console.warn('Could not get storage stats:', error); + // If we can't read metadata, database might be purged + used = 0; + fileCount = 0; + } + + return { + used, + available, + fileCount, + quota + }; + } + + /** + * Get file count quickly without loading metadata + */ + async getFileCount(): Promise { + if (!this.db) await this.init(); + + return new Promise((resolve, reject) => { + const transaction = this.db!.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + const request = store.count(); + + request.onerror = () => reject(request.error); + request.onsuccess = () => resolve(request.result); + }); + } + + /** + * Check all IndexedDB databases to see if files are in another version + */ + async debugAllDatabases(): Promise { + console.log('=== Checking All IndexedDB Databases ==='); + + if ('databases' in indexedDB) { + try { + const databases = await indexedDB.databases(); + console.log('Found databases:', databases); + + for (const dbInfo of databases) { + if (dbInfo.name?.includes('stirling') || dbInfo.name?.includes('pdf')) { + console.log(`Checking database: ${dbInfo.name} (version: ${dbInfo.version})`); + try { + const db = await new Promise((resolve, reject) => { + const request = indexedDB.open(dbInfo.name!, dbInfo.version); + request.onsuccess = () => resolve(request.result); + request.onerror = () => reject(request.error); + }); + + console.log(`Database ${dbInfo.name} object stores:`, Array.from(db.objectStoreNames)); + db.close(); + } catch (error) { + console.error(`Failed to open database ${dbInfo.name}:`, error); + } + } + } + } catch (error) { + console.error('Failed to list databases:', error); + } + } else { + console.log('indexedDB.databases() not supported'); + } + + // Also check our specific database with different versions + for (let version = 1; version <= 3; version++) { + try { + console.log(`Trying to open ${this.dbName} version ${version}...`); + const db = await new Promise((resolve, reject) => { + const request = indexedDB.open(this.dbName, version); + request.onsuccess = () => resolve(request.result); + request.onerror = () => reject(request.error); + request.onupgradeneeded = () => { + // Don't actually upgrade, just check + request.transaction?.abort(); + }; + }); + + console.log(`Version ${version} object stores:`, Array.from(db.objectStoreNames)); + + if (db.objectStoreNames.contains('files')) { + const transaction = db.transaction(['files'], 'readonly'); + const store = transaction.objectStore('files'); + const countRequest = store.count(); + countRequest.onsuccess = () => { + console.log(`Version ${version} files store has ${countRequest.result} entries`); + }; + } + + db.close(); + } catch (error) { + console.log(`Version ${version} not accessible:`, error.message); + } + } + } + + /** + * Debug method to check what's actually in the database + */ + async debugDatabaseContents(): Promise { + if (!this.db) await this.init(); + + return new Promise((resolve, reject) => { + const transaction = this.db!.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + + // First try getAll to see if there's anything + const getAllRequest = store.getAll(); + getAllRequest.onsuccess = () => { + console.log('=== Raw getAll() result ==='); + console.log('Raw entries found:', getAllRequest.result.length); + getAllRequest.result.forEach((item, index) => { + console.log(`Raw entry ${index}:`, { + keys: Object.keys(item || {}), + id: item?.id, + name: item?.name, + size: item?.size, + type: item?.type, + hasData: !!item?.data, + dataSize: item?.data?.byteLength, + fullObject: item + }); + }); + }; + + // Then try cursor + const cursorRequest = store.openCursor(); + console.log('=== IndexedDB Cursor Debug ==='); + let count = 0; + + cursorRequest.onerror = () => { + console.error('Cursor error:', cursorRequest.error); + reject(cursorRequest.error); + }; + + cursorRequest.onsuccess = (event) => { + const cursor = (event.target as IDBRequest).result; + if (cursor) { + count++; + const value = cursor.value; + console.log(`Cursor File ${count}:`, { + id: value?.id, + name: value?.name, + size: value?.size, + type: value?.type, + hasData: !!value?.data, + dataSize: value?.data?.byteLength, + hasThumbnail: !!value?.thumbnail, + allKeys: Object.keys(value || {}) + }); + cursor.continue(); + } else { + console.log(`=== End Cursor Debug - Found ${count} files ===`); + resolve(); + } + }; + }); + } + + /** + * Convert StoredFile back to File object for compatibility + */ + createFileFromStored(storedFile: StoredFile): File { + if (!storedFile || !storedFile.data) { + throw new Error('Invalid stored file: missing data'); + } + + if (!storedFile.name || typeof storedFile.size !== 'number') { + throw new Error('Invalid stored file: missing metadata'); + } + + const blob = new Blob([storedFile.data], { type: storedFile.type }); + const file = new File([blob], storedFile.name, { + type: storedFile.type, + lastModified: storedFile.lastModified + }); + + // Add custom properties for compatibility + Object.defineProperty(file, 'id', { value: storedFile.id, writable: false }); + Object.defineProperty(file, 'thumbnail', { value: storedFile.thumbnail, writable: false }); + + return file; + } + + /** + * Create blob URL for stored file + */ + createBlobUrl(storedFile: StoredFile): string { + const blob = new Blob([storedFile.data], { type: storedFile.type }); + return URL.createObjectURL(blob); + } + + /** + * Get file data as ArrayBuffer for streaming/chunked processing + */ + async getFileData(id: string): Promise { + try { + const storedFile = await this.getFile(id); + return storedFile ? storedFile.data : null; + } catch (error) { + console.warn(`Failed to get file data for ${id}:`, error); + return null; + } + } + + /** + * Create a temporary blob URL that gets revoked automatically + */ + async createTemporaryBlobUrl(id: string): Promise { + const data = await this.getFileData(id); + if (!data) return null; + + const blob = new Blob([data], { type: 'application/pdf' }); + const url = URL.createObjectURL(blob); + + // Auto-revoke after a short delay to free memory + setTimeout(() => { + URL.revokeObjectURL(url); + }, 10000); // 10 seconds + + return url; + } + + /** + * Update thumbnail for an existing file + */ + async updateThumbnail(id: string, thumbnail: string): Promise { + if (!this.db) await this.init(); + + return new Promise((resolve, reject) => { + try { + const transaction = this.db!.transaction([this.storeName], 'readwrite'); + const store = transaction.objectStore(this.storeName); + const getRequest = store.get(id); + + getRequest.onsuccess = () => { + const storedFile = getRequest.result; + if (storedFile) { + storedFile.thumbnail = thumbnail; + const updateRequest = store.put(storedFile); + + updateRequest.onsuccess = () => { + console.log('Thumbnail updated for file:', id); + resolve(true); + }; + updateRequest.onerror = () => { + console.error('Failed to update thumbnail:', updateRequest.error); + resolve(false); + }; + } else { + resolve(false); + } + }; + + getRequest.onerror = () => { + console.error('Failed to get file for thumbnail update:', getRequest.error); + resolve(false); + }; + } catch (error) { + console.error('Transaction error during thumbnail update:', error); + resolve(false); + } + }); + } + + /** + * Check if storage quota is running low + */ + async isStorageLow(): Promise { + const stats = await this.getStorageStats(); + if (!stats.quota) return false; + + const usagePercent = stats.used / stats.quota; + return usagePercent > 0.8; // Consider low if over 80% used + } + + /** + * Clean up old files if storage is low + */ + async cleanupOldFiles(maxFiles: number = 50): Promise { + const files = await this.getAllFileMetadata(); + + if (files.length <= maxFiles) return; + + // Sort by last modified (oldest first) + files.sort((a, b) => a.lastModified - b.lastModified); + + // Delete oldest files + const filesToDelete = files.slice(0, files.length - maxFiles); + for (const file of filesToDelete) { + await this.deleteFile(file.id); + } + } +} + +// Export singleton instance +export const fileStorage = new FileStorageService(); + +// Helper hook for React components +export function useFileStorage() { + return fileStorage; +} \ No newline at end of file diff --git a/frontend/src/services/pdfExportService.ts b/frontend/src/services/pdfExportService.ts new file mode 100644 index 000000000..b0662437e --- /dev/null +++ b/frontend/src/services/pdfExportService.ts @@ -0,0 +1,262 @@ +import { PDFDocument as PDFLibDocument, degrees, PageSizes } from 'pdf-lib'; +import { PDFDocument, PDFPage } from '../types/pageEditor'; + +export interface ExportOptions { + selectedOnly?: boolean; + filename?: string; + splitDocuments?: boolean; +} + +export class PDFExportService { + /** + * Export PDF document with applied operations + */ + async exportPDF( + pdfDocument: PDFDocument, + selectedPageIds: string[] = [], + options: ExportOptions = {} + ): Promise<{ blob: Blob; filename: string } | { blobs: Blob[]; filenames: string[] }> { + const { selectedOnly = false, filename, splitDocuments = false } = options; + + try { + // Determine which pages to export + const pagesToExport = selectedOnly && selectedPageIds.length > 0 + ? pdfDocument.pages.filter(page => selectedPageIds.includes(page.id)) + : pdfDocument.pages; + + if (pagesToExport.length === 0) { + throw new Error('No pages to export'); + } + + // Load original PDF once + const originalPDFBytes = await pdfDocument.file.arrayBuffer(); + const sourceDoc = await PDFLibDocument.load(originalPDFBytes); + + if (splitDocuments) { + return await this.createSplitDocuments(sourceDoc, pagesToExport, filename || pdfDocument.name); + } else { + const blob = await this.createSingleDocument(sourceDoc, pagesToExport); + const exportFilename = this.generateFilename(filename || pdfDocument.name, selectedOnly); + return { blob, filename: exportFilename }; + } + } catch (error) { + console.error('PDF export error:', error); + throw new Error(`Failed to export PDF: ${error instanceof Error ? error.message : 'Unknown error'}`); + } + } + + /** + * Create a single PDF document with all operations applied + */ + private async createSingleDocument( + sourceDoc: PDFLibDocument, + pages: PDFPage[] + ): Promise { + const newDoc = await PDFLibDocument.create(); + + for (const page of pages) { + // Get the original page from source document + const sourcePageIndex = page.pageNumber - 1; + + if (sourcePageIndex >= 0 && sourcePageIndex < sourceDoc.getPageCount()) { + // Copy the page + const [copiedPage] = await newDoc.copyPages(sourceDoc, [sourcePageIndex]); + + // Apply rotation + if (page.rotation !== 0) { + copiedPage.setRotation(degrees(page.rotation)); + } + + newDoc.addPage(copiedPage); + } + } + + // Set metadata + newDoc.setCreator('Stirling PDF'); + newDoc.setProducer('Stirling PDF'); + newDoc.setCreationDate(new Date()); + newDoc.setModificationDate(new Date()); + + const pdfBytes = await newDoc.save(); + return new Blob([pdfBytes], { type: 'application/pdf' }); + } + + /** + * Create multiple PDF documents based on split markers + */ + private async createSplitDocuments( + sourceDoc: PDFLibDocument, + pages: PDFPage[], + baseFilename: string + ): Promise<{ blobs: Blob[]; filenames: string[] }> { + const splitPoints: number[] = []; + const blobs: Blob[] = []; + const filenames: string[] = []; + + // Find split points + pages.forEach((page, index) => { + if (page.splitBefore && index > 0) { + splitPoints.push(index); + } + }); + + // Add end point + splitPoints.push(pages.length); + + let startIndex = 0; + let partNumber = 1; + + for (const endIndex of splitPoints) { + const segmentPages = pages.slice(startIndex, endIndex); + + if (segmentPages.length > 0) { + const newDoc = await PDFLibDocument.create(); + + for (const page of segmentPages) { + const sourcePageIndex = page.pageNumber - 1; + + if (sourcePageIndex >= 0 && sourcePageIndex < sourceDoc.getPageCount()) { + const [copiedPage] = await newDoc.copyPages(sourceDoc, [sourcePageIndex]); + + if (page.rotation !== 0) { + copiedPage.setRotation(degrees(page.rotation)); + } + + newDoc.addPage(copiedPage); + } + } + + // Set metadata + newDoc.setCreator('Stirling PDF'); + newDoc.setProducer('Stirling PDF'); + newDoc.setTitle(`${baseFilename} - Part ${partNumber}`); + + const pdfBytes = await newDoc.save(); + const blob = new Blob([pdfBytes], { type: 'application/pdf' }); + const filename = this.generateSplitFilename(baseFilename, partNumber); + + blobs.push(blob); + filenames.push(filename); + partNumber++; + } + + startIndex = endIndex; + } + + return { blobs, filenames }; + } + + /** + * Generate appropriate filename for export + */ + private generateFilename(originalName: string, selectedOnly: boolean): string { + const baseName = originalName.replace(/\.pdf$/i, ''); + const suffix = selectedOnly ? '_selected' : '_edited'; + return `${baseName}${suffix}.pdf`; + } + + /** + * Generate filename for split documents + */ + private generateSplitFilename(baseName: string, partNumber: number): string { + const cleanBaseName = baseName.replace(/\.pdf$/i, ''); + return `${cleanBaseName}_part_${partNumber}.pdf`; + } + + /** + * Download a single file + */ + downloadFile(blob: Blob, filename: string): void { + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = filename; + link.style.display = 'none'; + + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + // Clean up the URL after a short delay + setTimeout(() => URL.revokeObjectURL(url), 1000); + } + + /** + * Download multiple files as a ZIP + */ + async downloadAsZip(blobs: Blob[], filenames: string[], zipFilename: string): Promise { + // For now, download files wherindividually + blobs.forEach((blob, index) => { + setTimeout(() => { + this.downloadFile(blob, filenames[index]); + }, index * 500); // Stagger downloads + }); + } + + /** + * Validate PDF operations before export + */ + validateExport(pdfDocument: PDFDocument, selectedPageIds: string[], selectedOnly: boolean): string[] { + const errors: string[] = []; + + if (selectedOnly && selectedPageIds.length === 0) { + errors.push('No pages selected for export'); + } + + if (pdfDocument.pages.length === 0) { + errors.push('No pages available to export'); + } + + const pagesToExport = selectedOnly + ? pdfDocument.pages.filter(page => selectedPageIds.includes(page.id)) + : pdfDocument.pages; + + if (pagesToExport.length === 0) { + errors.push('No valid pages to export after applying filters'); + } + + return errors; + } + + /** + * Get export preview information + */ + getExportInfo(pdfDocument: PDFDocument, selectedPageIds: string[], selectedOnly: boolean): { + pageCount: number; + splitCount: number; + estimatedSize: string; + } { + const pagesToExport = selectedOnly + ? pdfDocument.pages.filter(page => selectedPageIds.includes(page.id)) + : pdfDocument.pages; + + const splitCount = pagesToExport.reduce((count, page, index) => { + return count + (page.splitBefore && index > 0 ? 1 : 0); + }, 1); // At least 1 document + + // Rough size estimation (very approximate) + const avgPageSize = pdfDocument.file.size / pdfDocument.totalPages; + const estimatedBytes = avgPageSize * pagesToExport.length; + const estimatedSize = this.formatFileSize(estimatedBytes); + + return { + pageCount: pagesToExport.length, + splitCount, + estimatedSize + }; + } + + /** + * Format file size for display + */ + private formatFileSize(bytes: number): string { + if (bytes === 0) return '0 B'; + const k = 1024; + const sizes = ['B', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; + } +} + +// Export singleton instance +export const pdfExportService = new PDFExportService(); diff --git a/frontend/src/services/pdfProcessingService.ts b/frontend/src/services/pdfProcessingService.ts new file mode 100644 index 000000000..5bb6f2ce3 --- /dev/null +++ b/frontend/src/services/pdfProcessingService.ts @@ -0,0 +1,188 @@ +import { getDocument, GlobalWorkerOptions } from 'pdfjs-dist'; +import { ProcessedFile, ProcessingState, PDFPage } from '../types/processing'; +import { ProcessingCache } from './processingCache'; + +// Set up PDF.js worker +GlobalWorkerOptions.workerSrc = '/pdf.worker.js'; + +export class PDFProcessingService { + private static instance: PDFProcessingService; + private cache = new ProcessingCache(); + private processing = new Map(); + private processingListeners = new Set<(states: Map) => void>(); + + private constructor() {} + + static getInstance(): PDFProcessingService { + if (!PDFProcessingService.instance) { + PDFProcessingService.instance = new PDFProcessingService(); + } + return PDFProcessingService.instance; + } + + async getProcessedFile(file: File): Promise { + const fileKey = this.generateFileKey(file); + + // Check cache first + const cached = this.cache.get(fileKey); + if (cached) { + console.log('Cache hit for:', file.name); + return cached; + } + + // Check if already processing + if (this.processing.has(fileKey)) { + console.log('Already processing:', file.name); + return null; // Will be available when processing completes + } + + // Start processing + this.startProcessing(file, fileKey); + return null; + } + + private async startProcessing(file: File, fileKey: string): Promise { + // Set initial state + const state: ProcessingState = { + fileKey, + fileName: file.name, + status: 'processing', + progress: 0, + startedAt: Date.now() + }; + + this.processing.set(fileKey, state); + this.notifyListeners(); + + try { + // Process the file with progress updates + const processedFile = await this.processFileWithProgress(file, (progress) => { + state.progress = progress; + this.notifyListeners(); + }); + + // Cache the result + this.cache.set(fileKey, processedFile); + + // Update state to completed + state.status = 'completed'; + state.progress = 100; + state.completedAt = Date.now(); + this.notifyListeners(); + + // Remove from processing map after brief delay + setTimeout(() => { + this.processing.delete(fileKey); + this.notifyListeners(); + }, 2000); + + } catch (error) { + console.error('Processing failed for', file.name, ':', error); + state.status = 'error'; + state.error = error instanceof Error ? error.message : 'Unknown error'; + this.notifyListeners(); + + // Remove failed processing after delay + setTimeout(() => { + this.processing.delete(fileKey); + this.notifyListeners(); + }, 5000); + } + } + + private async processFileWithProgress( + file: File, + onProgress: (progress: number) => void + ): Promise { + const arrayBuffer = await file.arrayBuffer(); + const pdf = await getDocument({ data: arrayBuffer }).promise; + const totalPages = pdf.numPages; + + onProgress(10); // PDF loaded + + const pages: PDFPage[] = []; + + for (let i = 1; i <= totalPages; i++) { + const page = await pdf.getPage(i); + const viewport = page.getViewport({ scale: 0.5 }); + const canvas = document.createElement('canvas'); + canvas.width = viewport.width; + canvas.height = viewport.height; + + const context = canvas.getContext('2d'); + if (context) { + await page.render({ canvasContext: context, viewport }).promise; + const thumbnail = canvas.toDataURL(); + + pages.push({ + id: `${file.name}-page-${i}`, + pageNumber: i, + thumbnail, + rotation: 0, + selected: false + }); + } + + // Update progress + const progress = 10 + (i / totalPages) * 85; // 10-95% + onProgress(progress); + } + + pdf.destroy(); + onProgress(100); + + return { + id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, + pages, + totalPages, + metadata: { + title: file.name, + createdAt: new Date().toISOString(), + modifiedAt: new Date().toISOString() + } + }; + } + + // State subscription for components + onProcessingChange(callback: (states: Map) => void): () => void { + this.processingListeners.add(callback); + return () => this.processingListeners.delete(callback); + } + + getProcessingStates(): Map { + return new Map(this.processing); + } + + private notifyListeners(): void { + this.processingListeners.forEach(callback => callback(this.processing)); + } + + generateFileKey(file: File): string { + return `${file.name}-${file.size}-${file.lastModified}`; + } + + // Cleanup method for activeFiles changes + cleanup(removedFiles: File[]): void { + removedFiles.forEach(file => { + const key = this.generateFileKey(file); + this.cache.delete(key); + this.processing.delete(key); + }); + this.notifyListeners(); + } + + // Get cache stats (for debugging) + getCacheStats() { + return this.cache.getStats(); + } + + // Clear all cache and processing + clearAll(): void { + this.cache.clear(); + this.processing.clear(); + this.notifyListeners(); + } +} + +// Export singleton instance +export const pdfProcessingService = PDFProcessingService.getInstance(); \ No newline at end of file diff --git a/frontend/src/services/processingCache.ts b/frontend/src/services/processingCache.ts new file mode 100644 index 000000000..820cfcbef --- /dev/null +++ b/frontend/src/services/processingCache.ts @@ -0,0 +1,138 @@ +import { ProcessedFile, CacheConfig, CacheEntry, CacheStats } from '../types/processing'; + +export class ProcessingCache { + private cache = new Map(); + private totalSize = 0; + + constructor(private config: CacheConfig = { + maxFiles: 20, + maxSizeBytes: 2 * 1024 * 1024 * 1024, // 2GB + ttlMs: 30 * 60 * 1000 // 30 minutes + }) {} + + set(key: string, data: ProcessedFile): void { + // Remove expired entries first + this.cleanup(); + + // Calculate entry size (rough estimate) + const size = this.calculateSize(data); + + // Make room if needed + this.makeRoom(size); + + this.cache.set(key, { + data, + size, + lastAccessed: Date.now(), + createdAt: Date.now() + }); + + this.totalSize += size; + } + + get(key: string): ProcessedFile | null { + const entry = this.cache.get(key); + if (!entry) return null; + + // Check TTL + if (Date.now() - entry.createdAt > this.config.ttlMs) { + this.delete(key); + return null; + } + + // Update last accessed + entry.lastAccessed = Date.now(); + return entry.data; + } + + has(key: string): boolean { + const entry = this.cache.get(key); + if (!entry) return false; + + // Check TTL + if (Date.now() - entry.createdAt > this.config.ttlMs) { + this.delete(key); + return false; + } + + return true; + } + + private makeRoom(neededSize: number): void { + // Remove oldest entries until we have space + while ( + this.cache.size >= this.config.maxFiles || + this.totalSize + neededSize > this.config.maxSizeBytes + ) { + const oldestKey = this.findOldestEntry(); + if (oldestKey) { + this.delete(oldestKey); + } else break; + } + } + + private findOldestEntry(): string | null { + let oldest: { key: string; lastAccessed: number } | null = null; + + for (const [key, entry] of this.cache) { + if (!oldest || entry.lastAccessed < oldest.lastAccessed) { + oldest = { key, lastAccessed: entry.lastAccessed }; + } + } + + return oldest?.key || null; + } + + private cleanup(): void { + const now = Date.now(); + for (const [key, entry] of this.cache) { + if (now - entry.createdAt > this.config.ttlMs) { + this.delete(key); + } + } + } + + private calculateSize(data: ProcessedFile): number { + // Rough size estimation + let size = 0; + + // Estimate size of thumbnails (main memory consumer) + data.pages.forEach(page => { + if (page.thumbnail) { + // Base64 thumbnail is roughly 50KB each + size += 50 * 1024; + } + }); + + // Add some overhead for other data + size += 10 * 1024; // 10KB overhead + + return size; + } + + delete(key: string): void { + const entry = this.cache.get(key); + if (entry) { + this.totalSize -= entry.size; + this.cache.delete(key); + } + } + + clear(): void { + this.cache.clear(); + this.totalSize = 0; + } + + getStats(): CacheStats { + return { + entries: this.cache.size, + totalSizeBytes: this.totalSize, + maxSizeBytes: this.config.maxSizeBytes + }; + } + + // Get all cached keys (for debugging and cleanup) + getKeys(): string[] { + return Array.from(this.cache.keys()); + } +} \ No newline at end of file diff --git a/frontend/src/services/processingErrorHandler.ts b/frontend/src/services/processingErrorHandler.ts new file mode 100644 index 000000000..f6871008d --- /dev/null +++ b/frontend/src/services/processingErrorHandler.ts @@ -0,0 +1,282 @@ +import { ProcessingError } from '../types/processing'; + +export class ProcessingErrorHandler { + private static readonly DEFAULT_MAX_RETRIES = 3; + private static readonly RETRY_DELAYS = [1000, 2000, 4000]; // Progressive backoff in ms + + /** + * Create a ProcessingError from an unknown error + */ + static createProcessingError( + error: unknown, + retryCount: number = 0, + maxRetries: number = this.DEFAULT_MAX_RETRIES + ): ProcessingError { + const originalError = error instanceof Error ? error : new Error(String(error)); + const message = originalError.message; + + // Determine error type based on error message and properties + const errorType = this.determineErrorType(originalError, message); + + // Determine if error is recoverable + const recoverable = this.isRecoverable(errorType, retryCount, maxRetries); + + return { + type: errorType, + message: this.formatErrorMessage(errorType, message), + recoverable, + retryCount, + maxRetries, + originalError + }; + } + + /** + * Determine the type of error based on error characteristics + */ + private static determineErrorType(error: Error, message: string): ProcessingError['type'] { + const lowerMessage = message.toLowerCase(); + + // Network-related errors + if (lowerMessage.includes('network') || + lowerMessage.includes('fetch') || + lowerMessage.includes('connection')) { + return 'network'; + } + + // Memory-related errors + if (lowerMessage.includes('memory') || + lowerMessage.includes('quota') || + lowerMessage.includes('allocation') || + error.name === 'QuotaExceededError') { + return 'memory'; + } + + // Timeout errors + if (lowerMessage.includes('timeout') || + lowerMessage.includes('aborted') || + error.name === 'AbortError') { + return 'timeout'; + } + + // Cancellation + if (lowerMessage.includes('cancel') || + lowerMessage.includes('abort') || + error.name === 'AbortError') { + return 'cancelled'; + } + + // PDF corruption/parsing errors + if (lowerMessage.includes('pdf') || + lowerMessage.includes('parse') || + lowerMessage.includes('invalid') || + lowerMessage.includes('corrupt') || + lowerMessage.includes('malformed')) { + return 'corruption'; + } + + // Default to parsing error + return 'parsing'; + } + + /** + * Determine if an error is recoverable based on type and retry count + */ + private static isRecoverable( + errorType: ProcessingError['type'], + retryCount: number, + maxRetries: number + ): boolean { + // Never recoverable + if (errorType === 'cancelled' || errorType === 'corruption') { + return false; + } + + // Recoverable if we haven't exceeded retry count + if (retryCount >= maxRetries) { + return false; + } + + // Memory errors are usually not recoverable + if (errorType === 'memory') { + return retryCount < 1; // Only one retry for memory errors + } + + // Network and timeout errors are usually recoverable + return errorType === 'network' || errorType === 'timeout' || errorType === 'parsing'; + } + + /** + * Format error message for user display + */ + private static formatErrorMessage(errorType: ProcessingError['type'], originalMessage: string): string { + switch (errorType) { + case 'network': + return 'Network connection failed. Please check your internet connection and try again.'; + + case 'memory': + return 'Insufficient memory to process this file. Try closing other applications or processing a smaller file.'; + + case 'timeout': + return 'Processing timed out. This file may be too large or complex to process.'; + + case 'cancelled': + return 'Processing was cancelled by user.'; + + case 'corruption': + return 'This PDF file appears to be corrupted or encrypted. Please try a different file.'; + + case 'parsing': + return `Failed to process PDF: ${originalMessage}`; + + default: + return `Processing failed: ${originalMessage}`; + } + } + + /** + * Execute an operation with automatic retry logic + */ + static async executeWithRetry( + operation: () => Promise, + onError?: (error: ProcessingError) => void, + maxRetries: number = this.DEFAULT_MAX_RETRIES + ): Promise { + let lastError: ProcessingError | null = null; + + for (let attempt = 0; attempt <= maxRetries; attempt++) { + try { + return await operation(); + } catch (error) { + lastError = this.createProcessingError(error, attempt, maxRetries); + + // Notify error handler + if (onError) { + onError(lastError); + } + + // Don't retry if not recoverable + if (!lastError.recoverable) { + break; + } + + // Don't retry on last attempt + if (attempt === maxRetries) { + break; + } + + // Wait before retry with progressive backoff + const delay = this.RETRY_DELAYS[Math.min(attempt, this.RETRY_DELAYS.length - 1)]; + await this.delay(delay); + + console.log(`Retrying operation (attempt ${attempt + 2}/${maxRetries + 1}) after ${delay}ms delay`); + } + } + + // All retries exhausted + throw lastError || new Error('Operation failed after all retries'); + } + + /** + * Create a timeout wrapper for operations + */ + static withTimeout( + operation: () => Promise, + timeoutMs: number, + timeoutMessage: string = 'Operation timed out' + ): Promise { + return new Promise((resolve, reject) => { + const timeoutId = setTimeout(() => { + reject(new Error(timeoutMessage)); + }, timeoutMs); + + operation() + .then(result => { + clearTimeout(timeoutId); + resolve(result); + }) + .catch(error => { + clearTimeout(timeoutId); + reject(error); + }); + }); + } + + /** + * Create an AbortController that times out after specified duration + */ + static createTimeoutController(timeoutMs: number): AbortController { + const controller = new AbortController(); + + setTimeout(() => { + controller.abort(); + }, timeoutMs); + + return controller; + } + + /** + * Check if an error indicates the operation should be retried + */ + static shouldRetry(error: ProcessingError): boolean { + return error.recoverable && error.retryCount < error.maxRetries; + } + + /** + * Get user-friendly suggestions based on error type + */ + static getErrorSuggestions(error: ProcessingError): string[] { + switch (error.type) { + case 'network': + return [ + 'Check your internet connection', + 'Try refreshing the page', + 'Try again in a few moments' + ]; + + case 'memory': + return [ + 'Close other browser tabs or applications', + 'Try processing a smaller file', + 'Restart your browser', + 'Use a device with more memory' + ]; + + case 'timeout': + return [ + 'Try processing a smaller file', + 'Break large files into smaller sections', + 'Check your internet connection speed' + ]; + + case 'corruption': + return [ + 'Verify the PDF file opens in other applications', + 'Try re-downloading the file', + 'Try a different PDF file', + 'Contact the file creator if it appears corrupted' + ]; + + case 'parsing': + return [ + 'Verify this is a valid PDF file', + 'Try a different PDF file', + 'Contact support if the problem persists' + ]; + + default: + return [ + 'Try refreshing the page', + 'Try again in a few moments', + 'Contact support if the problem persists' + ]; + } + } + + /** + * Utility function for delays + */ + private static delay(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); + } +} \ No newline at end of file diff --git a/frontend/src/services/thumbnailGenerationService.ts b/frontend/src/services/thumbnailGenerationService.ts new file mode 100644 index 000000000..3f16a23ea --- /dev/null +++ b/frontend/src/services/thumbnailGenerationService.ts @@ -0,0 +1,450 @@ +/** + * High-performance thumbnail generation service using Web Workers + */ + +interface ThumbnailResult { + pageNumber: number; + thumbnail: string; + success: boolean; + error?: string; +} + +interface ThumbnailGenerationOptions { + scale?: number; + quality?: number; + batchSize?: number; + parallelBatches?: number; +} + +interface CachedThumbnail { + thumbnail: string; + lastUsed: number; + sizeBytes: number; +} + +export class ThumbnailGenerationService { + private workers: Worker[] = []; + private activeJobs = new Map(); + private jobCounter = 0; + private isGenerating = false; + + // Session-based thumbnail cache + private thumbnailCache = new Map(); + private maxCacheSizeBytes = 1024 * 1024 * 1024; // 1GB cache limit + private currentCacheSize = 0; + + constructor(private maxWorkers: number = 3) { + this.initializeWorkers(); + } + + private initializeWorkers(): void { + const workerPromises: Promise[] = []; + + for (let i = 0; i < this.maxWorkers; i++) { + const workerPromise = new Promise((resolve) => { + try { + console.log(`Attempting to create worker ${i}...`); + const worker = new Worker('/thumbnailWorker.js'); + let workerReady = false; + let pingTimeout: NodeJS.Timeout; + + worker.onmessage = (e) => { + const { type, data, jobId } = e.data; + + // Handle PONG response to confirm worker is ready + if (type === 'PONG') { + workerReady = true; + clearTimeout(pingTimeout); + console.log(`āœ“ Worker ${i} is ready and responsive`); + resolve(worker); + return; + } + + const job = this.activeJobs.get(jobId); + if (!job) return; + + switch (type) { + case 'PROGRESS': + if (job.onProgress) { + job.onProgress(data); + } + break; + + case 'COMPLETE': + job.resolve(data.thumbnails); + this.activeJobs.delete(jobId); + break; + + case 'ERROR': + job.reject(new Error(data.error)); + this.activeJobs.delete(jobId); + break; + } + }; + + worker.onerror = (error) => { + console.error(`āœ— Worker ${i} failed with error:`, error); + clearTimeout(pingTimeout); + worker.terminate(); + resolve(null); + }; + + // Test worker with timeout + pingTimeout = setTimeout(() => { + if (!workerReady) { + console.warn(`āœ— Worker ${i} timed out (no PONG response)`); + worker.terminate(); + resolve(null); + } + }, 3000); // Reduced timeout for faster feedback + + // Send PING to test worker + try { + worker.postMessage({ type: 'PING' }); + } catch (pingError) { + console.error(`āœ— Failed to send PING to worker ${i}:`, pingError); + clearTimeout(pingTimeout); + worker.terminate(); + resolve(null); + } + + } catch (error) { + console.error(`āœ— Failed to create worker ${i}:`, error); + resolve(null); + } + }); + + workerPromises.push(workerPromise); + } + + // Wait for all workers to initialize or fail + Promise.all(workerPromises).then((workers) => { + this.workers = workers.filter((w): w is Worker => w !== null); + const successCount = this.workers.length; + const failCount = this.maxWorkers - successCount; + + console.log(`šŸ”§ Worker initialization complete: ${successCount}/${this.maxWorkers} workers ready`); + + if (failCount > 0) { + console.warn(`āš ļø ${failCount} workers failed to initialize - will use main thread fallback`); + } + + if (successCount === 0) { + console.warn('🚨 No Web Workers available - all thumbnail generation will use main thread'); + } + }); + } + + /** + * Generate thumbnails for multiple pages using Web Workers + */ + async generateThumbnails( + pdfArrayBuffer: ArrayBuffer, + pageNumbers: number[], + options: ThumbnailGenerationOptions = {}, + onProgress?: (progress: { completed: number; total: number; thumbnails: ThumbnailResult[] }) => void + ): Promise { + if (this.isGenerating) { + console.warn('🚨 ThumbnailService: Thumbnail generation already in progress, rejecting new request'); + throw new Error('Thumbnail generation already in progress'); + } + + console.log(`šŸŽ¬ ThumbnailService: Starting thumbnail generation for ${pageNumbers.length} pages`); + this.isGenerating = true; + + const { + scale = 0.2, + quality = 0.8, + batchSize = 20, // Pages per worker + parallelBatches = this.maxWorkers + } = options; + + try { + // Check if workers are available, fallback to main thread if not + if (this.workers.length === 0) { + console.warn('No Web Workers available, falling back to main thread processing'); + return await this.generateThumbnailsMainThread(pdfArrayBuffer, pageNumbers, scale, quality, onProgress); + } + + // Split pages across workers + const workerBatches = this.distributeWork(pageNumbers, this.workers.length); + console.log(`šŸ”§ ThumbnailService: Distributing ${pageNumbers.length} pages across ${this.workers.length} workers:`, workerBatches.map(batch => batch.length)); + const jobPromises: Promise[] = []; + + for (let i = 0; i < workerBatches.length; i++) { + const batch = workerBatches[i]; + if (batch.length === 0) continue; + + const worker = this.workers[i % this.workers.length]; + const jobId = `job-${++this.jobCounter}`; + console.log(`šŸ”§ ThumbnailService: Sending job ${jobId} with ${batch.length} pages to worker ${i}:`, batch); + + const promise = new Promise((resolve, reject) => { + // Add timeout for worker jobs + const timeout = setTimeout(() => { + console.error(`ā° ThumbnailService: Worker job ${jobId} timed out`); + this.activeJobs.delete(jobId); + reject(new Error(`Worker job ${jobId} timed out`)); + }, 60000); // 1 minute timeout + + // Create job with timeout handling + this.activeJobs.set(jobId, { + resolve: (result: any) => { + console.log(`āœ… ThumbnailService: Job ${jobId} completed with ${result.length} thumbnails`); + clearTimeout(timeout); + resolve(result); + }, + reject: (error: any) => { + console.error(`āŒ ThumbnailService: Job ${jobId} failed:`, error); + clearTimeout(timeout); + reject(error); + }, + onProgress: onProgress ? (progressData: any) => { + console.log(`šŸ“Š ThumbnailService: Job ${jobId} progress - ${progressData.completed}/${progressData.total} (${progressData.thumbnails.length} new)`); + onProgress(progressData); + } : undefined + }); + + worker.postMessage({ + type: 'GENERATE_THUMBNAILS', + jobId, + data: { + pdfArrayBuffer, + pageNumbers: batch, + scale, + quality + } + }); + }); + + jobPromises.push(promise); + } + + // Wait for all workers to complete + const results = await Promise.all(jobPromises); + + // Flatten and sort results by page number + const allThumbnails = results.flat().sort((a, b) => a.pageNumber - b.pageNumber); + console.log(`šŸŽÆ ThumbnailService: All workers completed, returning ${allThumbnails.length} thumbnails`); + + return allThumbnails; + + } catch (error) { + console.error('Web Worker thumbnail generation failed, falling back to main thread:', error); + return await this.generateThumbnailsMainThread(pdfArrayBuffer, pageNumbers, scale, quality, onProgress); + } finally { + console.log('šŸ”„ ThumbnailService: Resetting isGenerating flag'); + this.isGenerating = false; + } + } + + /** + * Fallback thumbnail generation on main thread + */ + private async generateThumbnailsMainThread( + pdfArrayBuffer: ArrayBuffer, + pageNumbers: number[], + scale: number, + quality: number, + onProgress?: (progress: { completed: number; total: number; thumbnails: ThumbnailResult[] }) => void + ): Promise { + console.log(`šŸ”§ ThumbnailService: Fallback to main thread for ${pageNumbers.length} pages`); + + // Import PDF.js dynamically for main thread + const { getDocument } = await import('pdfjs-dist'); + + // Load PDF once + const pdf = await getDocument({ data: pdfArrayBuffer }).promise; + console.log(`āœ“ ThumbnailService: PDF loaded on main thread`); + + + const allResults: ThumbnailResult[] = []; + let completed = 0; + const batchSize = 5; // Small batches for UI responsiveness + + // Process pages in small batches + for (let i = 0; i < pageNumbers.length; i += batchSize) { + const batch = pageNumbers.slice(i, i + batchSize); + + // Process batch sequentially (to avoid canvas conflicts) + for (const pageNumber of batch) { + try { + const page = await pdf.getPage(pageNumber); + const viewport = page.getViewport({ scale }); + + const canvas = document.createElement('canvas'); + canvas.width = viewport.width; + canvas.height = viewport.height; + + const context = canvas.getContext('2d'); + if (!context) { + throw new Error('Could not get canvas context'); + } + + await page.render({ canvasContext: context, viewport }).promise; + const thumbnail = canvas.toDataURL('image/jpeg', quality); + + allResults.push({ pageNumber, thumbnail, success: true }); + + } catch (error) { + console.error(`Failed to generate thumbnail for page ${pageNumber}:`, error); + allResults.push({ + pageNumber, + thumbnail: '', + success: false, + error: error instanceof Error ? error.message : 'Unknown error' + }); + } + } + + completed += batch.length; + + // Report progress + if (onProgress) { + onProgress({ + completed, + total: pageNumbers.length, + thumbnails: allResults.slice(-batch.length).filter(r => r.success) + }); + } + + // Small delay to keep UI responsive + if (i + batchSize < pageNumbers.length) { + await new Promise(resolve => setTimeout(resolve, 10)); + } + } + + // Clean up + pdf.destroy(); + + return allResults.filter(r => r.success); + } + + /** + * Distribute work evenly across workers + */ + private distributeWork(pageNumbers: number[], numWorkers: number): number[][] { + const batches: number[][] = Array(numWorkers).fill(null).map(() => []); + + pageNumbers.forEach((pageNum, index) => { + const workerIndex = index % numWorkers; + batches[workerIndex].push(pageNum); + }); + + return batches; + } + + /** + * Generate a single thumbnail (fallback for individual pages) + */ + async generateSingleThumbnail( + pdfArrayBuffer: ArrayBuffer, + pageNumber: number, + options: ThumbnailGenerationOptions = {} + ): Promise { + const results = await this.generateThumbnails(pdfArrayBuffer, [pageNumber], options); + + if (results.length === 0 || !results[0].success) { + throw new Error(`Failed to generate thumbnail for page ${pageNumber}`); + } + + return results[0].thumbnail; + } + + /** + * Add thumbnail to cache with size management + */ + addThumbnailToCache(pageId: string, thumbnail: string): void { + const thumbnailSizeBytes = thumbnail.length * 0.75; // Rough base64 size estimate + const now = Date.now(); + + // Add new thumbnail + this.thumbnailCache.set(pageId, { + thumbnail, + lastUsed: now, + sizeBytes: thumbnailSizeBytes + }); + + this.currentCacheSize += thumbnailSizeBytes; + + // If we exceed 1GB, trigger cleanup + if (this.currentCacheSize > this.maxCacheSizeBytes) { + this.cleanupThumbnailCache(); + } + } + + /** + * Get thumbnail from cache and update last used timestamp + */ + getThumbnailFromCache(pageId: string): string | null { + const cached = this.thumbnailCache.get(pageId); + if (!cached) return null; + + // Update last used timestamp + cached.lastUsed = Date.now(); + + return cached.thumbnail; + } + + /** + * Clean up cache using LRU eviction + */ + private cleanupThumbnailCache(): void { + const entries = Array.from(this.thumbnailCache.entries()); + + // Sort by last used (oldest first) + entries.sort(([, a], [, b]) => a.lastUsed - b.lastUsed); + + this.thumbnailCache.clear(); + this.currentCacheSize = 0; + const targetSize = this.maxCacheSizeBytes * 0.8; // Clean to 80% of limit + + // Keep most recently used entries until we hit target size + for (let i = entries.length - 1; i >= 0 && this.currentCacheSize < targetSize; i--) { + const [key, value] = entries[i]; + this.thumbnailCache.set(key, value); + this.currentCacheSize += value.sizeBytes; + } + } + + /** + * Clear all cached thumbnails + */ + clearThumbnailCache(): void { + this.thumbnailCache.clear(); + this.currentCacheSize = 0; + } + + /** + * Get cache statistics + */ + getCacheStats() { + return { + entries: this.thumbnailCache.size, + totalSizeBytes: this.currentCacheSize, + maxSizeBytes: this.maxCacheSizeBytes + }; + } + + /** + * Stop generation but keep cache and workers alive + */ + stopGeneration(): void { + this.activeJobs.clear(); + this.isGenerating = false; + } + + /** + * Terminate all workers and clear cache (only on explicit cleanup) + */ + destroy(): void { + this.workers.forEach(worker => worker.terminate()); + this.workers = []; + this.activeJobs.clear(); + this.isGenerating = false; + this.clearThumbnailCache(); + } +} + +// Export singleton instance +export const thumbnailGenerationService = new ThumbnailGenerationService(); \ No newline at end of file diff --git a/frontend/src/services/zipFileService.ts b/frontend/src/services/zipFileService.ts new file mode 100644 index 000000000..90f5b2574 --- /dev/null +++ b/frontend/src/services/zipFileService.ts @@ -0,0 +1,331 @@ +import JSZip from 'jszip'; + +export interface ZipExtractionResult { + success: boolean; + extractedFiles: File[]; + errors: string[]; + totalFiles: number; + extractedCount: number; +} + +export interface ZipValidationResult { + isValid: boolean; + fileCount: number; + totalSizeBytes: number; + containsPDFs: boolean; + errors: string[]; +} + +export interface ZipExtractionProgress { + currentFile: string; + extractedCount: number; + totalFiles: number; + progress: number; +} + +export class ZipFileService { + private readonly maxFileSize = 100 * 1024 * 1024; // 100MB per file + private readonly maxTotalSize = 500 * 1024 * 1024; // 500MB total extraction limit + private readonly supportedExtensions = ['.pdf']; + + /** + * Validate a ZIP file without extracting it + */ + async validateZipFile(file: File): Promise { + const result: ZipValidationResult = { + isValid: false, + fileCount: 0, + totalSizeBytes: 0, + containsPDFs: false, + errors: [] + }; + + try { + // Check file size + if (file.size > this.maxTotalSize) { + result.errors.push(`ZIP file too large: ${this.formatFileSize(file.size)} (max: ${this.formatFileSize(this.maxTotalSize)})`); + return result; + } + + // Check file type + if (!this.isZipFile(file)) { + result.errors.push('File is not a valid ZIP archive'); + return result; + } + + // Load and validate ZIP contents + const zip = new JSZip(); + const zipContents = await zip.loadAsync(file); + + let totalSize = 0; + let fileCount = 0; + let containsPDFs = false; + + // Analyze ZIP contents + for (const [filename, zipEntry] of Object.entries(zipContents.files)) { + if (zipEntry.dir) { + continue; // Skip directories + } + + fileCount++; + const uncompressedSize = zipEntry._data?.uncompressedSize || 0; + totalSize += uncompressedSize; + + // Check if file is a PDF + if (this.isPdfFile(filename)) { + containsPDFs = true; + } + + // Check individual file size + if (uncompressedSize > this.maxFileSize) { + result.errors.push(`File "${filename}" too large: ${this.formatFileSize(uncompressedSize)} (max: ${this.formatFileSize(this.maxFileSize)})`); + } + } + + // Check total uncompressed size + if (totalSize > this.maxTotalSize) { + result.errors.push(`Total uncompressed size too large: ${this.formatFileSize(totalSize)} (max: ${this.formatFileSize(this.maxTotalSize)})`); + } + + result.fileCount = fileCount; + result.totalSizeBytes = totalSize; + result.containsPDFs = containsPDFs; + result.isValid = result.errors.length === 0 && containsPDFs; + + if (!containsPDFs) { + result.errors.push('ZIP file does not contain any PDF files'); + } + + return result; + } catch (error) { + result.errors.push(`Failed to validate ZIP file: ${error instanceof Error ? error.message : 'Unknown error'}`); + return result; + } + } + + /** + * Create a ZIP file from an array of files + */ + async createZipFromFiles(files: File[], zipFilename: string): Promise<{ zipFile: File; size: number }> { + try { + const zip = new JSZip(); + + // Add each file to the ZIP + for (const file of files) { + const content = await file.arrayBuffer(); + zip.file(file.name, content); + } + + // Generate ZIP blob + const zipBlob = await zip.generateAsync({ + type: 'blob', + compression: 'DEFLATE', + compressionOptions: { level: 6 } + }); + + const zipFile = new File([zipBlob], zipFilename, { + type: 'application/zip', + lastModified: Date.now() + }); + + return { zipFile, size: zipFile.size }; + } catch (error) { + throw new Error(`Failed to create ZIP file: ${error instanceof Error ? error.message : 'Unknown error'}`); + } + } + + /** + * Extract PDF files from a ZIP archive + */ + async extractPdfFiles( + file: File, + onProgress?: (progress: ZipExtractionProgress) => void + ): Promise { + const result: ZipExtractionResult = { + success: false, + extractedFiles: [], + errors: [], + totalFiles: 0, + extractedCount: 0 + }; + + try { + // Validate ZIP file first + const validation = await this.validateZipFile(file); + if (!validation.isValid) { + result.errors = validation.errors; + return result; + } + + // Load ZIP contents + const zip = new JSZip(); + const zipContents = await zip.loadAsync(file); + + // Get all PDF files + const pdfFiles = Object.entries(zipContents.files).filter(([filename, zipEntry]) => + !zipEntry.dir && this.isPdfFile(filename) + ); + + result.totalFiles = pdfFiles.length; + + // Extract each PDF file + for (let i = 0; i < pdfFiles.length; i++) { + const [filename, zipEntry] = pdfFiles[i]; + + try { + // Report progress + if (onProgress) { + onProgress({ + currentFile: filename, + extractedCount: i, + totalFiles: pdfFiles.length, + progress: (i / pdfFiles.length) * 100 + }); + } + + // Extract file content + const content = await zipEntry.async('uint8array'); + + // Create File object + const extractedFile = new File([content], this.sanitizeFilename(filename), { + type: 'application/pdf', + lastModified: zipEntry.date?.getTime() || Date.now() + }); + + // Validate extracted PDF + if (await this.isValidPdfFile(extractedFile)) { + result.extractedFiles.push(extractedFile); + result.extractedCount++; + } else { + result.errors.push(`File "${filename}" is not a valid PDF`); + } + } catch (error) { + result.errors.push(`Failed to extract "${filename}": ${error instanceof Error ? error.message : 'Unknown error'}`); + } + } + + // Final progress report + if (onProgress) { + onProgress({ + currentFile: '', + extractedCount: result.extractedCount, + totalFiles: result.totalFiles, + progress: 100 + }); + } + + result.success = result.extractedCount > 0; + return result; + } catch (error) { + result.errors.push(`Failed to extract ZIP file: ${error instanceof Error ? error.message : 'Unknown error'}`); + return result; + } + } + + /** + * Check if a file is a ZIP file based on type and extension + */ + private isZipFile(file: File): boolean { + const validTypes = [ + 'application/zip', + 'application/x-zip-compressed', + 'application/x-zip', + 'application/octet-stream' // Some browsers use this for ZIP files + ]; + + const validExtensions = ['.zip']; + const hasValidType = validTypes.includes(file.type); + const hasValidExtension = validExtensions.some(ext => + file.name.toLowerCase().endsWith(ext) + ); + + return hasValidType || hasValidExtension; + } + + /** + * Check if a filename indicates a PDF file + */ + private isPdfFile(filename: string): boolean { + return filename.toLowerCase().endsWith('.pdf'); + } + + /** + * Validate that a file is actually a PDF by checking its header + */ + private async isValidPdfFile(file: File): Promise { + try { + // Read first few bytes to check PDF header + const buffer = await file.slice(0, 8).arrayBuffer(); + const bytes = new Uint8Array(buffer); + + // Check for PDF header: %PDF- + return bytes[0] === 0x25 && // % + bytes[1] === 0x50 && // P + bytes[2] === 0x44 && // D + bytes[3] === 0x46 && // F + bytes[4] === 0x2D; // - + } catch (error) { + return false; + } + } + + /** + * Sanitize filename for safe use + */ + private sanitizeFilename(filename: string): string { + // Remove directory path and get just the filename + const basename = filename.split('/').pop() || filename; + + // Remove or replace unsafe characters + return basename + .replace(/[<>:"/\\|?*]/g, '_') // Replace unsafe chars with underscore + .replace(/\s+/g, '_') // Replace spaces with underscores + .replace(/_{2,}/g, '_') // Replace multiple underscores with single + .replace(/^_|_$/g, ''); // Remove leading/trailing underscores + } + + /** + * Format file size for display + */ + private formatFileSize(bytes: number): string { + if (bytes === 0) return '0 B'; + const k = 1024; + const sizes = ['B', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; + } + + /** + * Get file extension from filename + */ + private getFileExtension(filename: string): string { + return filename.substring(filename.lastIndexOf('.')).toLowerCase(); + } + + /** + * Check if ZIP file contains password protection + */ + private async isPasswordProtected(file: File): Promise { + try { + const zip = new JSZip(); + await zip.loadAsync(file); + + // Check if any files are encrypted + for (const [filename, zipEntry] of Object.entries(zip.files)) { + if (zipEntry.options?.compression === 'STORE' && zipEntry._data?.compressedSize === 0) { + // This might indicate encryption, but JSZip doesn't provide direct encryption detection + // We'll handle this in the extraction phase + } + } + + return false; // JSZip will throw an error if password is required + } catch (error) { + // If we can't load the ZIP, it might be password protected + const errorMessage = error instanceof Error ? error.message : ''; + return errorMessage.includes('password') || errorMessage.includes('encrypted'); + } + } +} + +// Export singleton instance +export const zipFileService = new ZipFileService(); \ No newline at end of file diff --git a/frontend/src/setupTests.js b/frontend/src/setupTests.js new file mode 100644 index 000000000..8f2609b7b --- /dev/null +++ b/frontend/src/setupTests.js @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom'; diff --git a/frontend/src/setupTests.ts b/frontend/src/setupTests.ts new file mode 100644 index 000000000..0f5ca8648 --- /dev/null +++ b/frontend/src/setupTests.ts @@ -0,0 +1,123 @@ +import '@testing-library/jest-dom' +import { vi } from 'vitest' + +// Mock i18next for tests +vi.mock('react-i18next', () => ({ + useTranslation: () => ({ + t: (key: string) => key, + i18n: { + changeLanguage: vi.fn(), + }, + }), + initReactI18next: { + type: '3rdParty', + init: vi.fn(), + }, + I18nextProvider: ({ children }: { children: React.ReactNode }) => children, +})); + +// Mock i18next-http-backend +vi.mock('i18next-http-backend', () => ({ + default: { + type: 'backend', + init: vi.fn(), + read: vi.fn(), + save: vi.fn(), + }, +})); + +// Mock window.URL.createObjectURL and revokeObjectURL for tests +global.URL.createObjectURL = vi.fn(() => 'mocked-url') +global.URL.revokeObjectURL = vi.fn() + +// Mock File and Blob API methods that aren't available in jsdom +if (!globalThis.File.prototype.arrayBuffer) { + globalThis.File.prototype.arrayBuffer = function() { + // Return a simple ArrayBuffer with some mock data + const buffer = new ArrayBuffer(8); + const view = new Uint8Array(buffer); + view.set([1, 2, 3, 4, 5, 6, 7, 8]); + return Promise.resolve(buffer); + }; +} + +if (!globalThis.Blob.prototype.arrayBuffer) { + globalThis.Blob.prototype.arrayBuffer = function() { + // Return a simple ArrayBuffer with some mock data + const buffer = new ArrayBuffer(8); + const view = new Uint8Array(buffer); + view.set([1, 2, 3, 4, 5, 6, 7, 8]); + return Promise.resolve(buffer); + }; +} + +// Mock crypto.subtle for hashing in tests - force override even if exists +const mockHashBuffer = new ArrayBuffer(32); +const mockHashView = new Uint8Array(mockHashBuffer); +// Fill with predictable mock hash data +for (let i = 0; i < 32; i++) { + mockHashView[i] = i; +} + +// Force override crypto.subtle to avoid Node.js native implementation +Object.defineProperty(globalThis, 'crypto', { + value: { + subtle: { + digest: vi.fn().mockImplementation(async (algorithm: string, data: any) => { + // Always return the mock hash buffer regardless of input + return mockHashBuffer.slice(); + }), + }, + getRandomValues: vi.fn().mockImplementation((array: any) => { + // Mock getRandomValues if needed + for (let i = 0; i < array.length; i++) { + array[i] = Math.floor(Math.random() * 256); + } + return array; + }), + } as Crypto, + writable: true, + configurable: true, +}); + +// Mock Worker for tests (Web Workers not available in test environment) +global.Worker = vi.fn().mockImplementation(() => ({ + postMessage: vi.fn(), + terminate: vi.fn(), + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + onmessage: null, + onerror: null, +})) + +// Mock ResizeObserver for Mantine components +global.ResizeObserver = vi.fn().mockImplementation(() => ({ + observe: vi.fn(), + unobserve: vi.fn(), + disconnect: vi.fn(), +})) + +// Mock IntersectionObserver for components that might use it +global.IntersectionObserver = vi.fn().mockImplementation(() => ({ + observe: vi.fn(), + unobserve: vi.fn(), + disconnect: vi.fn(), +})) + +// Mock matchMedia for responsive components +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: vi.fn().mockImplementation(query => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // deprecated + removeListener: vi.fn(), // deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), +}) + +// Set global test timeout to prevent hangs +vi.setConfig({ testTimeout: 5000, hookTimeout: 5000 }) \ No newline at end of file diff --git a/frontend/src/styles/rainbow.module.css b/frontend/src/styles/rainbow.module.css new file mode 100644 index 000000000..d56578a14 --- /dev/null +++ b/frontend/src/styles/rainbow.module.css @@ -0,0 +1,202 @@ +/* Rainbow Mode Styles - Easter Egg! */ +@keyframes rainbowBackground { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} + +@keyframes rainbowBorder { + 0% { border-color: #ff0000; box-shadow: 0 0 15px #ff0000; } + 14% { border-color: #ff8800; box-shadow: 0 0 15px #ff8800; } + 28% { border-color: #ffff00; box-shadow: 0 0 15px #ffff00; } + 42% { border-color: #88ff00; box-shadow: 0 0 15px #88ff00; } + 57% { border-color: #00ff88; box-shadow: 0 0 15px #00ff88; } + 71% { border-color: #0088ff; box-shadow: 0 0 15px #0088ff; } + 85% { border-color: #8800ff; box-shadow: 0 0 15px #8800ff; } + 100% { border-color: #ff0000; box-shadow: 0 0 15px #ff0000; } +} + +@keyframes rainbowText { + 0% { color: #ff0000; text-shadow: 0 0 10px #ff0000; } + 14% { color: #ff8800; text-shadow: 0 0 10px #ff8800; } + 28% { color: #ffff00; text-shadow: 0 0 10px #ffff00; } + 42% { color: #88ff00; text-shadow: 0 0 10px #88ff00; } + 57% { color: #00ff88; text-shadow: 0 0 10px #00ff88; } + 71% { color: #0088ff; text-shadow: 0 0 10px #0088ff; } + 85% { color: #8800ff; text-shadow: 0 0 10px #8800ff; } + 100% { color: #ff0000; text-shadow: 0 0 10px #ff0000; } +} + +@keyframes rainbowPulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.05); } +} + +/* Main rainbow theme class */ +.rainbowMode { + background: linear-gradient( + -45deg, + #ff0000, #ff8800, #ffff00, #88ff00, #00ff88, #00ffff, #0088ff, #8800ff, #ff0088, #ff0000 + ) !important; + background-size: 400% 400% !important; + animation: rainbowBackground 3s ease infinite !important; + color: white !important; + overflow-x: hidden; +} + +/* Rainbow components */ +.rainbowCard { + background: linear-gradient( + 45deg, + #ff0000, #ff8800, #ffff00, #88ff00, #00ff88, #00ffff, #0088ff, #8800ff, #ff0088 + ) !important; + background-size: 400% 400% !important; + animation: rainbowBackground 4s ease infinite, rainbowBorder 2s linear infinite !important; + color: white !important; + border: 2px solid !important; + border-radius: 15px !important; + box-shadow: 0 0 20px rgba(255, 255, 255, 0.3) !important; +} + +.rainbowButton { + background: linear-gradient( + 45deg, + #ff0000, #ff8800, #ffff00, #88ff00, #00ff88, #00ffff, #0088ff, #8800ff, #ff0088 + ) !important; + background-size: 300% 300% !important; + animation: rainbowBackground 2s ease infinite, rainbowBorder 1s linear infinite !important; + border: 2px solid !important; + color: white !important; + border-radius: 8px !important; + transition: all 0.3s ease !important; + font-weight: bold !important; +} + +.rainbowButton:hover { + transform: scale(1.05) !important; + animation: rainbowBackground 1s ease infinite, rainbowBorder 0.5s linear infinite, rainbowPulse 0.5s ease infinite !important; + box-shadow: 0 0 25px rgba(255, 255, 255, 0.6) !important; +} + +.rainbowInput { + background: linear-gradient( + 90deg, + #ff0000, #ff8800, #ffff00, #88ff00, #00ff88, #00ffff, #0088ff, #8800ff, #ff0088 + ) !important; + background-size: 300% 300% !important; + animation: rainbowBackground 2.5s ease infinite, rainbowBorder 1.5s linear infinite !important; + border: 2px solid !important; + color: white !important; + border-radius: 8px !important; +} + +.rainbowInput::placeholder { + color: rgba(255, 255, 255, 0.8) !important; +} + +.rainbowText { + animation: rainbowText 3s linear infinite !important; + font-weight: bold !important; + text-shadow: 0 0 10px currentColor !important; +} + +.rainbowSegmentedControl { + background: linear-gradient( + 45deg, + #ff0000, #ff8800, #ffff00, #88ff00, #00ff88, #00ffff, #0088ff, #8800ff, #ff0088 + ) !important; + background-size: 400% 400% !important; + animation: rainbowBackground 3s ease infinite, rainbowBorder 2s linear infinite !important; + border: 2px solid !important; + border-radius: 12px !important; + padding: 4px !important; +} + +.rainbowPaper { + background: linear-gradient( + 90deg, + #00ffff, #0088ff, #8800ff, #ff0088 + ) !important; + background-size: 100% 100% !important; + animation: rainbowBackground 3.5s ease infinite, rainbowBorder 2s linear infinite !important; + border: 2px solid !important; + color: white !important; + border-radius: 12px !important; +} + +/* Easter egg notification */ +.rainbowNotification { + position: fixed !important; + top: 20px !important; + right: 20px !important; + background: linear-gradient(45deg,#ffff00, #88ff00, #00ff88, #00ffff) !important; + background-size: 300% 300% !important; + animation: rainbowBackground 1s ease infinite, rainbowBorder 0.5s linear infinite !important; + color: white !important; + padding: 15px 20px !important; + border-radius: 25px !important; + font-weight: bold !important; + font-size: 16px !important; + z-index: 10000 !important; + border: 2px solid white !important; + box-shadow: 0 0 20px rgba(255, 255, 255, 0.8) !important; + user-select: none !important; + pointer-events: none !important; +} + +/* Specific component overrides */ +.rainbowMode [data-mantine-color-scheme] { + background: linear-gradient( + -45deg, + #ff0000, #ff8800, #ffff00, #88ff00, #00ff88, #00ffff, #0088ff, #8800ff, #ff0088, #ff0000 + ) !important; + background-size: 400% 400% !important; + animation: rainbowBackground 3s ease infinite !important; +} + +/* Make all buttons rainbow in rainbow mode */ +.rainbowMode button { + background: linear-gradient( + 45deg, + #ffff00, #88ff00, #00ff88, #00ffff + ) !important; + background-size: 100% 100% !important; + animation: rainbowBackground 2s ease infinite !important; + border: 2px solid !important; + animation: rainbowBackground 2s ease infinite, rainbowBorder 1.5s linear infinite !important; + color: white !important; + font-weight: bold !important; +} + +/* Make all inputs rainbow in rainbow mode */ +.rainbowMode input, +.rainbowMode select, +.rainbowMode textarea { + background: linear-gradient( + 90deg, + #ffff00, #88ff00, #00ff88, #00ffff + ) !important; + background-size: 100% 100% !important; + animation: rainbowBackground 2.5s ease infinite !important; + border: 2px solid !important; + animation: rainbowBackground 2.5s ease infinite, rainbowBorder 1.5s linear infinite !important; + color: white !important; +} + +/* Rainbow text class */ +.rainbowText { + animation: rainbowText 3s linear infinite !important; + font-weight: bold !important; + text-shadow: 0 0 10px currentColor !important; +} + +/* Make all text rainbow */ +.rainbowMode h1, +.rainbowMode h2, +.rainbowMode h3, +.rainbowMode h4, +.rainbowMode h5, +.rainbowMode h6 { + animation: rainbowText 3s linear infinite !important; + font-weight: bold !important; +} diff --git a/frontend/src/styles/tailwind.css b/frontend/src/styles/tailwind.css new file mode 100644 index 000000000..9415e80ce --- /dev/null +++ b/frontend/src/styles/tailwind.css @@ -0,0 +1,15 @@ + +/* Import minimal theme variables */ +@import './theme.css'; + +@layer base { + @tailwind base; +} + +@layer components { + @tailwind components; +} + +@layer utilities { + @tailwind utilities; +} diff --git a/frontend/src/styles/theme.css b/frontend/src/styles/theme.css new file mode 100644 index 000000000..9ec48bca7 --- /dev/null +++ b/frontend/src/styles/theme.css @@ -0,0 +1,265 @@ +/* CSS variables for Tailwind + Mantine integration */ + +:root { + /* Standard gray scale */ + --gray-50: 249 250 251; + --gray-100: 243 244 246; + --gray-200: 229 231 235; + --gray-300: 209 213 219; + --gray-400: 156 163 175; + --gray-500: 107 114 128; + --gray-600: 75 85 99; + --gray-700: 55 65 81; + --gray-800: 31 41 55; + --gray-900: 17 24 39; + + /* Semantic colors for Tailwind */ + --surface: 255 255 255; + --background: 249 250 251; + --border: 229 231 235; + + /* Colors for Mantine integration */ + --color-primary-50: #eff6ff; + --color-primary-100: #dbeafe; + --color-primary-200: #bfdbfe; + --color-primary-300: #93c5fd; + --color-primary-400: #60a5fa; + --color-primary-500: #3b82f6; + --color-primary-600: #2563eb; + --color-primary-700: #1d4ed8; + --color-primary-800: #1e40af; + --color-primary-900: #1e3a8a; + + --color-gray-50: #f9fafb; + --color-gray-100: #f3f4f6; + --color-gray-200: #e5e7eb; + --color-gray-300: #d1d5db; + --color-gray-400: #9ca3af; + --color-gray-500: #6b7280; + --color-gray-600: #4b5563; + --color-gray-700: #374151; + --color-gray-800: #1f2937; + --color-gray-900: #111827; + + /* Spacing system */ + --space-xs: 4px; + --space-sm: 8px; + --space-md: 16px; + --space-lg: 24px; + --space-xl: 32px; + + /* Radius system */ + --radius-xs: 2px; + --radius-sm: 4px; + --radius-md: 8px; + --radius-lg: 12px; + --radius-xl: 16px; + + /* Shadow system */ + --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.05); + --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1); + --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1); + --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1); + --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.1); + + /* Font weights */ + --font-weight-normal: 400; + --font-weight-medium: 500; + --font-weight-semibold: 600; + --font-weight-bold: 700; + + /* Light theme semantic colors */ + --bg-surface: #ffffff; + --bg-raised: #f9fafb; + --bg-muted: #f3f4f6; + --bg-background: #f9fafb; + --bg-toolbar: #ffffff; + --bg-file-manager: #F5F6F8; + --bg-file-list: #ffffff; + --btn-open-file: #0A8BFF; + --text-primary: #111827; + --text-secondary: #4b5563; + --text-muted: #6b7280; + --border-subtle: #e5e7eb; + --border-default: #d1d5db; + --border-strong: #9ca3af; + --hover-bg: #f9fafb; + --active-bg: #f3f4f6; + + /* Icon colors for light mode */ + --icon-user-bg: #9CA3AF; + --icon-user-color: #FFFFFF; + --icon-notifications-bg: #9CA3AF; + --icon-notifications-color: #FFFFFF; + --icon-tools-bg: #1E88E5; + --icon-tools-color: #FFFFFF; + --icon-read-bg: #4CAF50; + --icon-read-color: #FFFFFF; + --icon-sign-bg: #3BA99C; + --icon-sign-color: #FFFFFF; + --icon-automate-bg: #A576E3; + --icon-automate-color: #FFFFFF; + --icon-files-bg: #D3E7F7; + --icon-files-color: #0A8BFF; + --icon-activity-bg: #D3E7F7; + --icon-activity-color: #0A8BFF; + --icon-config-bg: #9CA3AF; + --icon-config-color: #FFFFFF; + + /* Colors for tooltips */ + --tooltip-title-bg: #DBEFFF; + --tooltip-title-color: #31528E; + --tooltip-header-bg: #31528E; + --tooltip-header-color: white; + --tooltip-border: var(--border-default); + + /* Inactive icon colors for light mode */ + --icon-inactive-bg: #9CA3AF; + --icon-inactive-color: #FFFFFF; + + --accent-interactive: #4A90E2; + --text-instruction: #4A90E2; + --text-brand: var(--color-gray-700); + --text-brand-accent: #DC2626; + + /* container */ + --landing-paper-bg: var(--bg-surface); + --landing-inner-paper-bg: #EEF8FF; + --landing-inner-paper-border: #CDEAFF; + --landing-button-bg: var(--bg-surface); + --landing-button-color: var(--icon-tools-bg); + --landing-button-border: #E0F2F7; + --landing-button-hover-bg: rgb(251, 251, 251); + + /* drop state */ + --landing-drop-paper-bg: #E3F2FD; + --landing-drop-inner-paper-bg: #BBDEFB; + --landing-drop-inner-paper-border: #90CAF9; + + /* shadows */ + --drop-shadow-color: rgba(0, 0, 0, 0.08); + --drop-shadow-color-strong: rgba(0, 0, 0, 0.04); + --drop-shadow-filter: drop-shadow(0 0.2rem 0.4rem rgba(0, 0, 0, 0.08)) drop-shadow(0 0.6rem 0.6rem rgba(0, 0, 0, 0.06)) drop-shadow(0 1.2rem 1rem rgba(0, 0, 0, 0.04)); +} + +[data-mantine-color-scheme="dark"] { + /* Dark theme gray scale (inverted) */ + --gray-50: 17 24 39; + --gray-100: 31 35 41; + --gray-200: 42 47 54; + --gray-300: 55 65 81; + --gray-400: 75 85 99; + --gray-500: 107 114 128; + --gray-600: 156 163 175; + --gray-700: 209 213 219; + --gray-800: 229 231 235; + --gray-900: 243 244 246; + + /* Dark semantic colors for Tailwind */ + --surface: 31 35 41; + --background: 42 47 54; + --border: 55 65 81; + + /* Dark theme Mantine colors */ + --color-gray-50: #111827; + --color-gray-100: #1F2329; + --color-gray-200: #2A2F36; + --color-gray-300: #374151; + --color-gray-400: #4b5563; + --color-gray-500: #6b7280; + --color-gray-600: #9ca3af; + --color-gray-700: #d1d5db; + --color-gray-800: #e5e7eb; + --color-gray-900: #f3f4f6; + + /* Dark theme semantic colors */ + --bg-surface: #2A2F36; + --bg-raised: #1F2329; + --bg-muted: #1F2329; + --bg-background: #2A2F36; + --bg-toolbar: #272A2E; + --bg-file-manager: #1F2329; + --bg-file-list: #2A2F36; + --btn-open-file: #0A8BFF; + --text-primary: #f9fafb; + --text-secondary: #d1d5db; + --text-muted: #9ca3af; + --border-subtle: #2A2F36; + --border-default: #374151; + --border-strong: #4b5563; + --hover-bg: #374151; + --active-bg: #4b5563; + + /* Icon colors for dark mode */ + --icon-user-bg: #2A2F36; + --icon-user-color: #6E7581; + --icon-notifications-bg: #2A2F36; + --icon-notifications-color: #6E7581; + --icon-tools-bg: #4B525A; + --icon-tools-color: #EAEAEA; + --icon-read-bg: #4B525A; + --icon-read-color: #EAEAEA; + --icon-sign-bg: #4B525A; + --icon-sign-color: #EAEAEA; + --icon-automate-bg: #4B525A; + --icon-automate-color: #EAEAEA; + --icon-files-bg: #4B525A; + --icon-files-color: #EAEAEA; + --icon-activity-bg: #4B525A; + --icon-activity-color: #EAEAEA; + --icon-config-bg: #4B525A; + --icon-config-color: #EAEAEA; + + /* Inactive icon colors for dark mode */ + --icon-inactive-bg: #2A2F36; + --icon-inactive-color: #6E7581; + + /* Dark mode tooltip colors */ + --tooltip-title-bg: #4B525A; + --tooltip-title-color: #fff; + --tooltip-header-bg: var(--bg-raised); + --tooltip-header-color: var(--text-primary); + --tooltip-border: var(--border-default); + + --accent-interactive: #ffffff; + --text-instruction: #ffffff; + --text-brand: var(--color-gray-800); + --text-brand-accent: #EF4444; + + /* container */ + --landing-paper-bg: #171A1F; + --landing-inner-paper-bg: var(--bg-raised); + --landing-inner-paper-border: #2D3237; + --landing-button-bg: #2B3037; + --landing-button-color: #ffffff; + --landing-button-border: #2D3237; + --landing-button-hover-bg: #4c525b; + + /* drop state */ + --landing-drop-paper-bg: #1A2332; + --landing-drop-inner-paper-bg: #2A3441; + --landing-drop-inner-paper-border: #3A4451; + + /* shadows */ + --drop-shadow-color: rgba(255, 255, 255, 0.08); + --drop-shadow-color-strong: rgba(255, 255, 255, 0.04); + --drop-shadow-filter: drop-shadow(0 0.2rem 0.4rem rgba(200, 200, 200, 0.08)) drop-shadow(0 0.6rem 0.6rem rgba(200, 200, 200, 0.06)) drop-shadow(0 1.2rem 1rem rgba(200, 200, 200, 0.04)); + + /* Adjust shadows for dark mode */ + --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.3); + --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4); + --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4); + --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.4); + --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.4); +} + +/* Dropzone drop state styling */ +[data-accept] .dropzone-inner { + background-color: var(--landing-drop-inner-paper-bg) !important; + border-color: var(--landing-drop-inner-paper-border) !important; +} + +/* Smooth transitions for theme switching */ +* { + transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease; +} \ No newline at end of file diff --git a/frontend/src/tests/convert/ConvertE2E.spec.ts b/frontend/src/tests/convert/ConvertE2E.spec.ts new file mode 100644 index 000000000..90d203b55 --- /dev/null +++ b/frontend/src/tests/convert/ConvertE2E.spec.ts @@ -0,0 +1,440 @@ +/** + * End-to-End Tests for Convert Tool + * + * These tests dynamically discover available conversion endpoints and test them. + * Tests are automatically skipped if the backend endpoint is not available. + * + * Run with: npm run test:e2e or npx playwright test + */ + +import { test, expect, Page } from '@playwright/test'; +import { + conversionDiscovery, + type ConversionEndpoint +} from '../helpers/conversionEndpointDiscovery'; +import * as path from 'path'; +import * as fs from 'fs'; + +// Test configuration +const BASE_URL = process.env.BASE_URL || 'http://localhost:5173'; +const BACKEND_URL = process.env.BACKEND_URL || 'http://localhost:8080'; + +/** + * Resolves test fixture paths dynamically based on current working directory. + * Works from both top-level project directory and frontend subdirectory. + */ +function resolveTestFixturePath(filename: string): string { + const cwd = process.cwd(); + + // Try frontend/src/tests/test-fixtures/ first (from top-level) + const topLevelPath = path.join(cwd, 'frontend', 'src', 'tests', 'test-fixtures', filename); + if (fs.existsSync(topLevelPath)) { + return topLevelPath; + } + + // Try src/tests/test-fixtures/ (from frontend directory) + const frontendPath = path.join(cwd, 'src', 'tests', 'test-fixtures', filename); + if (fs.existsSync(frontendPath)) { + return frontendPath; + } + + // Try relative path from current test file location + const relativePath = path.join(__dirname, '..', 'test-fixtures', filename); + if (fs.existsSync(relativePath)) { + return relativePath; + } + + // Fallback to the original path format (should work from top-level) + return path.join('.', 'frontend', 'src', 'tests', 'test-fixtures', filename); +} + +// Test file paths (dynamically resolved based on current working directory) +const TEST_FILES = { + pdf: resolveTestFixturePath('sample.pdf'), + docx: resolveTestFixturePath('sample.docx'), + doc: resolveTestFixturePath('sample.doc'), + pptx: resolveTestFixturePath('sample.pptx'), + ppt: resolveTestFixturePath('sample.ppt'), + xlsx: resolveTestFixturePath('sample.xlsx'), + xls: resolveTestFixturePath('sample.xls'), + png: resolveTestFixturePath('sample.png'), + jpg: resolveTestFixturePath('sample.jpg'), + jpeg: resolveTestFixturePath('sample.jpeg'), + gif: resolveTestFixturePath('sample.gif'), + bmp: resolveTestFixturePath('sample.bmp'), + tiff: resolveTestFixturePath('sample.tiff'), + webp: resolveTestFixturePath('sample.webp'), + md: resolveTestFixturePath('sample.md'), + eml: resolveTestFixturePath('sample.eml'), + html: resolveTestFixturePath('sample.html'), + txt: resolveTestFixturePath('sample.txt'), + xml: resolveTestFixturePath('sample.xml'), + csv: resolveTestFixturePath('sample.csv') +}; + +// File format to test file mapping +const getTestFileForFormat = (format: string): string => { + const formatMap: Record = { + 'pdf': TEST_FILES.pdf, + 'docx': TEST_FILES.docx, + 'doc': TEST_FILES.doc, + 'pptx': TEST_FILES.pptx, + 'ppt': TEST_FILES.ppt, + 'xlsx': TEST_FILES.xlsx, + 'xls': TEST_FILES.xls, + 'office': TEST_FILES.docx, // Default office file + 'image': TEST_FILES.png, // Default image file + 'png': TEST_FILES.png, + 'jpg': TEST_FILES.jpg, + 'jpeg': TEST_FILES.jpeg, + 'gif': TEST_FILES.gif, + 'bmp': TEST_FILES.bmp, + 'tiff': TEST_FILES.tiff, + 'webp': TEST_FILES.webp, + 'md': TEST_FILES.md, + 'eml': TEST_FILES.eml, + 'html': TEST_FILES.html, + 'txt': TEST_FILES.txt, + 'xml': TEST_FILES.xml, + 'csv': TEST_FILES.csv + }; + + return formatMap[format] || TEST_FILES.pdf; // Fallback to PDF +}; + +// Expected file extensions for target formats +const getExpectedExtension = (toFormat: string): string => { + const extensionMap: Record = { + 'pdf': '.pdf', + 'docx': '.docx', + 'pptx': '.pptx', + 'txt': '.txt', + 'html': '.zip', // HTML is zipped + 'xml': '.xml', + 'csv': '.csv', + 'md': '.md', + 'image': '.png', // Default for image conversion + 'png': '.png', + 'jpg': '.jpg', + 'jpeg': '.jpeg', + 'gif': '.gif', + 'bmp': '.bmp', + 'tiff': '.tiff', + 'webp': '.webp', + 'pdfa': '.pdf' + }; + + return extensionMap[toFormat] || '.pdf'; +}; + +/** + * Helper function to upload files through the modal system + */ +async function uploadFileViaModal(page: Page, filePath: string) { + // Click the Files button in the QuickAccessBar to open the modal + await page.click('[data-testid="files-button"]'); + + // Wait for the modal to open + await page.waitForSelector('.mantine-Modal-overlay', { state: 'visible' }, { timeout: 5000 }); + //await page.waitForSelector('[data-testid="file-upload-modal"]', { timeout: 5000 }); + + // Upload the file through the modal's file input + await page.setInputFiles('input[type="file"]', filePath); + + // Wait for the file to be processed and the modal to close + await page.waitForSelector('[data-testid="file-upload-modal"]', { state: 'hidden' }); + + // Wait for the file thumbnail to appear in the main interface + await page.waitForSelector('[data-testid="file-thumbnail"]', { timeout: 10000 }); +} + +/** + * Generic test function for any conversion + */ +async function testConversion(page: Page, conversion: ConversionEndpoint) { + const expectedExtension = getExpectedExtension(conversion.toFormat); + + console.log(`Testing ${conversion.endpoint}: ${conversion.fromFormat} → ${conversion.toFormat}`); + + // File should already be uploaded, click the Convert tool button + await page.click('[data-testid="tool-convert"]'); + + // Wait for the FileEditor to load in convert mode with file thumbnails + await page.waitForSelector('[data-testid="file-thumbnail"]', { timeout: 5000 }); + + // Click the file thumbnail checkbox to select it in the FileEditor + await page.click('[data-testid="file-thumbnail-checkbox"]'); + + // Wait for the conversion settings to appear after file selection + await page.waitForSelector('[data-testid="convert-from-dropdown"]', { timeout: 5000 }); + + // Select FROM format + await page.click('[data-testid="convert-from-dropdown"]'); + const fromFormatOption = page.locator(`[data-testid="format-option-${conversion.fromFormat}"]`); + await fromFormatOption.scrollIntoViewIfNeeded(); + await fromFormatOption.click(); + + // Select TO format + await page.click('[data-testid="convert-to-dropdown"]'); + const toFormatOption = page.locator(`[data-testid="format-option-${conversion.toFormat}"]`); + await toFormatOption.scrollIntoViewIfNeeded(); + await toFormatOption.click(); + + // Handle format-specific options + if (conversion.toFormat === 'image' || ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'tiff', 'webp'].includes(conversion.toFormat)) { + // Set image conversion options if they appear + const imageOptionsVisible = await page.locator('[data-testid="image-options-section"]').isVisible().catch(() => false); + if (imageOptionsVisible) { + // Click the color type dropdown and select "Color" + await page.click('[data-testid="color-type-select"]'); + await page.getByRole('option', { name: 'Color' }).click(); + + // Set DPI value + await page.fill('[data-testid="dpi-input"]', '150'); + + // Click the output type dropdown and select "Multiple" + await page.click('[data-testid="output-type-select"]'); + + await page.getByRole('option', { name: 'single' }).click(); + } + } + + if (conversion.fromFormat === 'image' && conversion.toFormat === 'pdf') { + // Set PDF creation options if they appear + const pdfOptionsVisible = await page.locator('[data-testid="pdf-options-section"]').isVisible().catch(() => false); + if (pdfOptionsVisible) { + // Click the color type dropdown and select "Color" + await page.click('[data-testid="color-type-select"]'); + await page.locator('[data-value="color"]').click(); + } + } + + if (conversion.fromFormat === 'pdf' && conversion.toFormat === 'csv') { + // Set CSV extraction options if they appear + const csvOptionsVisible = await page.locator('[data-testid="csv-options-section"]').isVisible().catch(() => false); + if (csvOptionsVisible) { + // Set specific page numbers for testing (test pages 1-2) + await page.fill('[data-testid="page-numbers-input"]', '1-2'); + } + } + + // Start conversion + await page.click('[data-testid="convert-button"]'); + + // Wait for conversion to complete (with generous timeout) + await page.waitForSelector('[data-testid="download-button"]', { timeout: 60000 }); + + // Verify download is available + const downloadButton = page.locator('[data-testid="download-button"]'); + await expect(downloadButton).toBeVisible(); + + // Start download and verify file + const downloadPromise = page.waitForEvent('download'); + await downloadButton.click(); + const download = await downloadPromise; + + // Verify file extension + expect(download.suggestedFilename()).toMatch(new RegExp(`\\${expectedExtension}$`)); + + // Save and verify file is not empty + const path = await download.path(); + if (path) { + const fs = require('fs'); + const stats = fs.statSync(path); + expect(stats.size).toBeGreaterThan(0); + + // Format-specific validations + if (conversion.toFormat === 'pdf' || conversion.toFormat === 'pdfa') { + // Verify PDF header + const buffer = fs.readFileSync(path); + const header = buffer.toString('utf8', 0, 4); + expect(header).toBe('%PDF'); + } + + if (conversion.toFormat === 'txt') { + // Verify text content exists + const content = fs.readFileSync(path, 'utf8'); + expect(content.length).toBeGreaterThan(0); + } + + if (conversion.toFormat === 'csv') { + // Verify CSV content contains separators + const content = fs.readFileSync(path, 'utf8'); + expect(content).toContain(','); + } + } +} + +// Discover conversions at module level before tests are defined +let allConversions: ConversionEndpoint[] = []; +let availableConversions: ConversionEndpoint[] = []; +let unavailableConversions: ConversionEndpoint[] = []; + +// Pre-populate conversions synchronously for test generation +(async () => { + try { + availableConversions = await conversionDiscovery.getAvailableConversions(); + unavailableConversions = await conversionDiscovery.getUnavailableConversions(); + allConversions = [...availableConversions, ...unavailableConversions]; + } catch (error) { + console.error('Failed to discover conversions during module load:', error); + } +})(); + +test.describe('Convert Tool E2E Tests', () => { + + test.beforeAll(async () => { + // Re-discover to ensure fresh data at test time + console.log('Re-discovering available conversion endpoints...'); + availableConversions = await conversionDiscovery.getAvailableConversions(); + unavailableConversions = await conversionDiscovery.getUnavailableConversions(); + + console.log(`Found ${availableConversions.length} available conversions:`); + availableConversions.forEach(conv => { + console.log(` āœ“ ${conv.endpoint}: ${conv.fromFormat} → ${conv.toFormat}`); + }); + + if (unavailableConversions.length > 0) { + console.log(`Found ${unavailableConversions.length} unavailable conversions:`); + unavailableConversions.forEach(conv => { + console.log(` āœ— ${conv.endpoint}: ${conv.fromFormat} → ${conv.toFormat}`); + }); + } + }); + + test.beforeEach(async ({ page }) => { + // Navigate to the homepage + await page.goto(`${BASE_URL}`); + + // Wait for the page to load + await page.waitForLoadState('networkidle'); + + // Wait for the QuickAccessBar to appear + await page.waitForSelector('[data-testid="files-button"]', { timeout: 10000 }); + }); + + test.describe('Dynamic Conversion Tests', () => { + + // Generate a test for each potentially available conversion + // We'll discover all possible conversions and then skip unavailable ones at runtime + test('PDF to PNG conversion', async ({ page }) => { + const conversion = { endpoint: '/api/v1/convert/pdf/img', fromFormat: 'pdf', toFormat: 'png' }; + const isAvailable = availableConversions.some(c => c.apiPath === conversion.endpoint); + test.skip(!isAvailable, `Endpoint ${conversion.endpoint} is not available`); + + const testFile = getTestFileForFormat(conversion.fromFormat); + await uploadFileViaModal(page, testFile); + + await testConversion(page, conversion); + }); + + test('PDF to DOCX conversion', async ({ page }) => { + const conversion = { endpoint: '/api/v1/convert/pdf/word', fromFormat: 'pdf', toFormat: 'docx' }; + const isAvailable = availableConversions.some(c => c.apiPath === conversion.endpoint); + test.skip(!isAvailable, `Endpoint ${conversion.endpoint} is not available`); + + const testFile = getTestFileForFormat(conversion.fromFormat); + await uploadFileViaModal(page, testFile); + + await testConversion(page, conversion); + }); + + test('DOCX to PDF conversion', async ({ page }) => { + const conversion = { endpoint: '/api/v1/convert/file/pdf', fromFormat: 'docx', toFormat: 'pdf' }; + const isAvailable = availableConversions.some(c => c.apiPath === conversion.endpoint); + test.skip(!isAvailable, `Endpoint ${conversion.endpoint} is not available`); + + const testFile = getTestFileForFormat(conversion.fromFormat); + await uploadFileViaModal(page, testFile); + + await testConversion(page, conversion); + }); + + test('Image to PDF conversion', async ({ page }) => { + const conversion = { endpoint: '/api/v1/convert/img/pdf', fromFormat: 'png', toFormat: 'pdf' }; + const isAvailable = availableConversions.some(c => c.apiPath === conversion.endpoint); + test.skip(!isAvailable, `Endpoint ${conversion.endpoint} is not available`); + + const testFile = getTestFileForFormat(conversion.fromFormat); + await uploadFileViaModal(page, testFile); + + await testConversion(page, conversion); + }); + + test('PDF to TXT conversion', async ({ page }) => { + const conversion = { endpoint: '/api/v1/convert/pdf/text', fromFormat: 'pdf', toFormat: 'txt' }; + const isAvailable = availableConversions.some(c => c.apiPath === conversion.endpoint); + test.skip(!isAvailable, `Endpoint ${conversion.endpoint} is not available`); + + const testFile = getTestFileForFormat(conversion.fromFormat); + await uploadFileViaModal(page, testFile); + + await testConversion(page, conversion); + }); + + test('PDF to HTML conversion', async ({ page }) => { + const conversion = { endpoint: '/api/v1/convert/pdf/html', fromFormat: 'pdf', toFormat: 'html' }; + const isAvailable = availableConversions.some(c => c.apiPath === conversion.endpoint); + test.skip(!isAvailable, `Endpoint ${conversion.endpoint} is not available`); + + const testFile = getTestFileForFormat(conversion.fromFormat); + await uploadFileViaModal(page, testFile); + + await testConversion(page, conversion); + }); + + test('PDF to XML conversion', async ({ page }) => { + const conversion = { endpoint: '/api/v1/convert/pdf/xml', fromFormat: 'pdf', toFormat: 'xml' }; + const isAvailable = availableConversions.some(c => c.apiPath === conversion.endpoint); + test.skip(!isAvailable, `Endpoint ${conversion.endpoint} is not available`); + + const testFile = getTestFileForFormat(conversion.fromFormat); + await uploadFileViaModal(page, testFile); + + await testConversion(page, conversion); + }); + + test('PDF to CSV conversion', async ({ page }) => { + const conversion = { endpoint: '/api/v1/convert/pdf/csv', fromFormat: 'pdf', toFormat: 'csv' }; + const isAvailable = availableConversions.some(c => c.apiPath === conversion.endpoint); + test.skip(!isAvailable, `Endpoint ${conversion.endpoint} is not available`); + + const testFile = getTestFileForFormat(conversion.fromFormat); + await uploadFileViaModal(page, testFile); + + await testConversion(page, conversion); + }); + + test('PDF to PDFA conversion', async ({ page }) => { + const conversion = { endpoint: '/api/v1/convert/pdf/pdfa', fromFormat: 'pdf', toFormat: 'pdfa' }; + const isAvailable = availableConversions.some(c => c.apiPath === conversion.endpoint); + test.skip(!isAvailable, `Endpoint ${conversion.endpoint} is not available`); + + const testFile = getTestFileForFormat(conversion.fromFormat); + await uploadFileViaModal(page, testFile); + + await testConversion(page, conversion); + }); + }); + + test.describe('Static Tests', () => { + + // Test that disabled conversions don't appear in dropdowns when they shouldn't + test('should not show conversion button when no valid conversions available', async ({ page }) => { + // This test ensures the convert button is disabled when no valid conversion is possible + await uploadFileViaModal(page, TEST_FILES.pdf); + + // Click the Convert tool button + await page.click('[data-testid="tool-convert"]'); + + // Wait for convert mode and select file + await page.waitForSelector('[data-testid="file-thumbnail"]', { timeout: 5000 }); + await page.click('[data-testid="file-thumbnail-checkbox"]'); + + // Don't select any formats - convert button should not exist + const convertButton = page.locator('[data-testid="convert-button"]'); + await expect(convertButton).toHaveCount(0); + }); + }); +}); + diff --git a/frontend/src/tests/convert/ConvertIntegration.test.tsx b/frontend/src/tests/convert/ConvertIntegration.test.tsx new file mode 100644 index 000000000..4e6b7cc68 --- /dev/null +++ b/frontend/src/tests/convert/ConvertIntegration.test.tsx @@ -0,0 +1,620 @@ +/** + * Integration tests for Convert Tool - Tests actual conversion functionality + * + * These tests verify the integration between frontend components and backend: + * 1. useConvertOperation hook makes correct API calls + * 2. File upload/download flow functions properly + * 3. Error handling works for various failure scenarios + * 4. Parameter passing works between frontend and backend + * 5. FileContext integration works correctly + */ + +import React from 'react'; +import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest'; +import { renderHook, act, waitFor } from '@testing-library/react'; +import { useConvertOperation } from '../../hooks/tools/convert/useConvertOperation'; +import { ConvertParameters } from '../../hooks/tools/convert/useConvertParameters'; +import { FileContextProvider } from '../../contexts/FileContext'; +import { I18nextProvider } from 'react-i18next'; +import i18n from '../../i18n/config'; +import axios from 'axios'; + +// Mock axios +vi.mock('axios'); +const mockedAxios = vi.mocked(axios); + +// Mock only essential services that are actually called by the tests +vi.mock('../../services/fileStorage', () => ({ + fileStorage: { + init: vi.fn().mockResolvedValue(undefined), + storeFile: vi.fn().mockImplementation((file, thumbnail) => { + return Promise.resolve({ + id: `mock-id-${file.name}`, + name: file.name, + size: file.size, + type: file.type, + lastModified: file.lastModified, + thumbnail: thumbnail + }); + }), + getAllFileMetadata: vi.fn().mockResolvedValue([]), + cleanup: vi.fn().mockResolvedValue(undefined) + } +})); + +vi.mock('../../services/thumbnailGenerationService', () => ({ + thumbnailGenerationService: { + generateThumbnail: vi.fn().mockResolvedValue('data:image/png;base64,fake-thumbnail'), + cleanup: vi.fn(), + destroy: vi.fn() + } +})); + +// Create realistic test files +const createTestFile = (name: string, content: string, type: string): File => { + return new File([content], name, { type }); +}; + +const createPDFFile = (): File => { + const pdfContent = '%PDF-1.4\n1 0 obj\n<<\n/Type /Catalog\n/Pages 2 0 R\n>>\nendobj\ntrailer\n<<\n/Size 2\n/Root 1 0 R\n>>\nstartxref\n0\n%%EOF'; + return createTestFile('test.pdf', pdfContent, 'application/pdf'); +}; + +// Test wrapper component +const TestWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => ( + + + {children} + + +); + +describe('Convert Tool Integration Tests', () => { + + beforeEach(() => { + vi.clearAllMocks(); + // Setup default axios mock + mockedAxios.post = vi.fn(); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + describe('useConvertOperation Integration', () => { + + test('should make correct API call for PDF to PNG conversion', async () => { + const mockBlob = new Blob(['fake-image-data'], { type: 'image/png' }); + mockedAxios.post.mockResolvedValueOnce({ + data: mockBlob, + status: 200, + statusText: 'OK' + }); + + const { result } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const testFile = createPDFFile(); + const parameters: ConvertParameters = { + fromExtension: 'pdf', + toExtension: 'png', + imageOptions: { + colorType: 'color', + dpi: 300, + singleOrMultiple: 'multiple', + fitOption: 'maintainAspectRatio', + autoRotate: true, + combineImages: true + }, + isSmartDetection: false, + smartDetectionType: 'none' + }; + + await act(async () => { + await result.current.executeOperation(parameters, [testFile]); + }); + + // Verify axios was called with correct parameters + expect(mockedAxios.post).toHaveBeenCalledWith( + '/api/v1/convert/pdf/img', + expect.any(FormData), + { responseType: 'blob' } + ); + + // Verify FormData contains correct parameters + const formDataCall = mockedAxios.post.mock.calls[0][1] as FormData; + expect(formDataCall.get('imageFormat')).toBe('png'); + expect(formDataCall.get('colorType')).toBe('color'); + expect(formDataCall.get('dpi')).toBe('300'); + expect(formDataCall.get('singleOrMultiple')).toBe('multiple'); + + // Verify hook state updates + expect(result.current.downloadUrl).toBeTruthy(); + expect(result.current.downloadFilename).toBe('test_converted.png'); + expect(result.current.isLoading).toBe(false); + expect(result.current.errorMessage).toBe(null); + }); + + test('should handle API error responses correctly', async () => { + const errorMessage = 'Invalid file format'; + mockedAxios.post.mockRejectedValueOnce({ + response: { + status: 400, + data: errorMessage + }, + message: errorMessage + }); + + const { result } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const testFile = createTestFile('invalid.txt', 'not a pdf', 'text/plain'); + const parameters: ConvertParameters = { + fromExtension: 'pdf', + toExtension: 'png', + imageOptions: { + colorType: 'color', + dpi: 300, + singleOrMultiple: 'multiple', + fitOption: 'maintainAspectRatio', + autoRotate: true, + combineImages: true + }, + isSmartDetection: false, + smartDetectionType: 'none' + }; + + await act(async () => { + await result.current.executeOperation(parameters, [testFile]); + }); + + // Verify error handling + expect(result.current.errorMessage).toBe(errorMessage); + expect(result.current.isLoading).toBe(false); + expect(result.current.downloadUrl).toBe(null); + }); + + test('should handle network errors gracefully', async () => { + mockedAxios.post.mockRejectedValueOnce(new Error('Network error')); + + const { result } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const testFile = createPDFFile(); + const parameters: ConvertParameters = { + fromExtension: 'pdf', + toExtension: 'png', + imageOptions: { + colorType: 'color', + dpi: 300, + singleOrMultiple: 'multiple', + fitOption: 'maintainAspectRatio', + autoRotate: true, + combineImages: true + }, + isSmartDetection: false, + smartDetectionType: 'none' + }; + + await act(async () => { + await result.current.executeOperation(parameters, [testFile]); + }); + + expect(result.current.errorMessage).toBe('Network error'); + expect(result.current.isLoading).toBe(false); + }); + }); + + describe('API and Hook Integration', () => { + + test('should correctly map image conversion parameters to API call', async () => { + const mockBlob = new Blob(['fake-data'], { type: 'image/jpeg' }); + mockedAxios.post.mockResolvedValueOnce({ + data: mockBlob, + status: 200, + headers: { + 'content-type': 'image/jpeg', + 'content-disposition': 'attachment; filename="test_converted.jpg"' + } + }); + + const { result } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const testFile = createPDFFile(); + const parameters: ConvertParameters = { + fromExtension: 'pdf', + toExtension: 'jpg', + pageNumbers: 'all', + imageOptions: { + colorType: 'grayscale', + dpi: 150, + singleOrMultiple: 'single', + fitOption: 'maintainAspectRatio', + autoRotate: true, + combineImages: true + }, + isSmartDetection: false, + smartDetectionType: 'none' + }; + + await act(async () => { + await result.current.executeOperation(parameters, [testFile]); + }); + + // Verify integration: hook parameters → FormData → axios call → hook state + const formDataCall = mockedAxios.post.mock.calls[0][1] as FormData; + expect(formDataCall.get('imageFormat')).toBe('jpg'); + expect(formDataCall.get('colorType')).toBe('grayscale'); + expect(formDataCall.get('dpi')).toBe('150'); + expect(formDataCall.get('singleOrMultiple')).toBe('single'); + + // Verify complete workflow: API response → hook state → FileContext integration + expect(result.current.downloadUrl).toBeTruthy(); + expect(result.current.files).toHaveLength(1); + expect(result.current.files[0].name).toBe('test_converted.jpg'); + expect(result.current.isLoading).toBe(false); + }); + + test('should make correct API call for PDF to CSV conversion with simplified workflow', async () => { + const mockBlob = new Blob(['fake-csv-data'], { type: 'text/csv' }); + mockedAxios.post.mockResolvedValueOnce({ + data: mockBlob, + status: 200, + statusText: 'OK' + }); + + const { result } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const testFile = createPDFFile(); + const parameters: ConvertParameters = { + fromExtension: 'pdf', + toExtension: 'csv', + imageOptions: { + colorType: 'color', + dpi: 300, + singleOrMultiple: 'multiple', + fitOption: 'maintainAspectRatio', + autoRotate: true, + combineImages: true + }, + isSmartDetection: false, + smartDetectionType: 'none' + }; + + await act(async () => { + await result.current.executeOperation(parameters, [testFile]); + }); + + // Verify correct endpoint is called + expect(mockedAxios.post).toHaveBeenCalledWith( + '/api/v1/convert/pdf/csv', + expect.any(FormData), + { responseType: 'blob' } + ); + + // Verify FormData contains correct parameters for simplified CSV conversion + const formDataCall = mockedAxios.post.mock.calls[0][1] as FormData; + expect(formDataCall.get('pageNumbers')).toBe('all'); // Always "all" for simplified workflow + expect(formDataCall.get('fileInput')).toBe(testFile); + + // Verify hook state updates correctly + expect(result.current.downloadUrl).toBeTruthy(); + expect(result.current.downloadFilename).toBe('test_converted.csv'); + expect(result.current.isLoading).toBe(false); + expect(result.current.errorMessage).toBe(null); + }); + + test('should handle complete unsupported conversion workflow', async () => { + const { result } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const testFile = createPDFFile(); + const parameters: ConvertParameters = { + fromExtension: 'pdf', + toExtension: 'unsupported', + imageOptions: { + colorType: 'color', + dpi: 300, + singleOrMultiple: 'multiple', + fitOption: 'maintainAspectRatio', + autoRotate: true, + combineImages: true + }, + isSmartDetection: false, + smartDetectionType: 'none' + }; + + await act(async () => { + await result.current.executeOperation(parameters, [testFile]); + }); + + // Verify integration: utils validation prevents API call, hook shows error + expect(mockedAxios.post).not.toHaveBeenCalled(); + expect(result.current.errorMessage).toContain('errorNotSupported'); + expect(result.current.isLoading).toBe(false); + expect(result.current.downloadUrl).toBe(null); + }); + }); + + describe('File Upload Integration', () => { + + test('should handle multiple file uploads correctly', async () => { + const mockBlob = new Blob(['zip-content'], { type: 'application/zip' }); + mockedAxios.post.mockResolvedValueOnce({ data: mockBlob }); + + const { result } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + const files = [ + createPDFFile(), + createTestFile('test2.pdf', '%PDF-1.4...', 'application/pdf') + ] + const parameters: ConvertParameters = { + fromExtension: 'pdf', + toExtension: 'png', + imageOptions: { + colorType: 'color', + dpi: 300, + singleOrMultiple: 'multiple', + fitOption: 'maintainAspectRatio', + autoRotate: true, + combineImages: true + }, + isSmartDetection: false, + smartDetectionType: 'none' + }; + + await act(async () => { + await result.current.executeOperation(parameters, files); + }); + + // Verify both files were uploaded + const calls = mockedAxios.post.mock.calls; + + for (let i = 0; i < calls.length; i++) { + const formData = calls[i][1] as FormData; + const fileInputs = formData.getAll('fileInput'); + expect(fileInputs).toHaveLength(1); + expect(fileInputs[0]).toBeInstanceOf(File); + expect(fileInputs[0].name).toBe(files[i].name); + } + + }); + + test('should handle no files selected', async () => { + const { result } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const parameters: ConvertParameters = { + fromExtension: 'pdf', + toExtension: 'png', + imageOptions: { + colorType: 'color', + dpi: 300, + singleOrMultiple: 'multiple', + fitOption: 'maintainAspectRatio', + autoRotate: true, + combineImages: true + }, + isSmartDetection: false, + smartDetectionType: 'none' + }; + + await act(async () => { + await result.current.executeOperation(parameters, []); + }); + + expect(mockedAxios.post).not.toHaveBeenCalled(); + expect(result.current.errorMessage).toContain('noFileSelected'); + }); + }); + + describe('Error Boundary Integration', () => { + + test('should handle corrupted file gracefully', async () => { + mockedAxios.post.mockRejectedValueOnce({ + response: { + status: 422, + data: 'Processing failed' + } + }); + + const { result } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const corruptedFile = createTestFile('corrupted.pdf', 'not-a-pdf', 'application/pdf'); + const parameters: ConvertParameters = { + fromExtension: 'pdf', + toExtension: 'png', + imageOptions: { + colorType: 'color', + dpi: 300, + singleOrMultiple: 'multiple', + fitOption: 'maintainAspectRatio', + autoRotate: true, + combineImages: true + }, + isSmartDetection: false, + smartDetectionType: 'none' + }; + + await act(async () => { + await result.current.executeOperation(parameters, [corruptedFile]); + }); + + expect(result.current.errorMessage).toBe('Processing failed'); + expect(result.current.isLoading).toBe(false); + }); + + test('should handle backend service unavailable', async () => { + mockedAxios.post.mockRejectedValueOnce({ + response: { + status: 503, + data: 'Service unavailable' + } + }); + + const { result } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const testFile = createPDFFile(); + const parameters: ConvertParameters = { + fromExtension: 'pdf', + toExtension: 'png', + imageOptions: { + colorType: 'color', + dpi: 300, + singleOrMultiple: 'multiple', + fitOption: 'maintainAspectRatio', + autoRotate: true, + combineImages: true + }, + isSmartDetection: false, + smartDetectionType: 'none' + }; + + await act(async () => { + await result.current.executeOperation(parameters, [testFile]); + }); + + expect(result.current.errorMessage).toBe('Service unavailable'); + expect(result.current.isLoading).toBe(false); + }); + }); + + describe('FileContext Integration', () => { + + test('should record operation in FileContext', async () => { + const mockBlob = new Blob(['fake-data'], { type: 'image/png' }); + mockedAxios.post.mockResolvedValueOnce({ + data: mockBlob, + status: 200, + headers: { + 'content-type': 'image/png', + 'content-disposition': 'attachment; filename="test_converted.png"' + } + }); + + const { result } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const testFile = createPDFFile(); + const parameters: ConvertParameters = { + fromExtension: 'pdf', + toExtension: 'png', + imageOptions: { + colorType: 'color', + dpi: 300, + singleOrMultiple: 'multiple', + fitOption: 'maintainAspectRatio', + autoRotate: true, + combineImages: true + }, + isSmartDetection: false, + smartDetectionType: 'none' + }; + + await act(async () => { + await result.current.executeOperation(parameters, [testFile]); + }); + + // Verify operation was successful and files were processed + expect(result.current.files).toHaveLength(1); + expect(result.current.files[0].name).toBe('test_converted.png'); + expect(result.current.downloadUrl).toBeTruthy(); + }); + + test('should clean up blob URLs on reset', async () => { + const mockBlob = new Blob(['fake-data'], { type: 'image/png' }); + mockedAxios.post.mockResolvedValueOnce({ + data: mockBlob, + status: 200, + headers: { + 'content-type': 'image/png', + 'content-disposition': 'attachment; filename="test_converted.png"' + } + }); + + const { result } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const testFile = createPDFFile(); + const parameters: ConvertParameters = { + fromExtension: 'pdf', + toExtension: 'png', + imageOptions: { + colorType: 'color', + dpi: 300, + singleOrMultiple: 'multiple', + fitOption: 'maintainAspectRatio', + autoRotate: true, + combineImages: true + }, + isSmartDetection: false, + smartDetectionType: 'none' + }; + + await act(async () => { + await result.current.executeOperation(parameters, [testFile]); + }); + + expect(result.current.downloadUrl).toBeTruthy(); + + act(() => { + result.current.resetResults(); + }); + + expect(result.current.downloadUrl).toBe(null); + expect(result.current.files).toHaveLength(0); + expect(result.current.errorMessage).toBe(null); + }); + }); +}); + +/** + * Additional Integration Tests That Require Real Backend + * + * These tests would require a running backend server and are better suited + * for E2E testing with tools like Playwright or Cypress: + * + * 1. **Real File Conversion Tests** + * - Upload actual PDF files and verify conversion quality + * - Test image format outputs are valid and viewable + * - Test CSV/TXT outputs contain expected content + * - Test file size limits and memory constraints + * + * 2. **Performance Integration Tests** + * - Test conversion time for various file sizes + * - Test memory usage during large file conversions + * - Test concurrent conversion requests + * - Test timeout handling for long-running conversions + * + * 3. **Authentication Integration** + * - Test conversions with and without authentication + * - Test rate limiting and user quotas + * - Test permission-based endpoint access + * + * 4. **File Preview Integration** + * - Test that converted files integrate correctly with viewer + * - Test thumbnail generation for converted files + * - Test file download functionality + * - Test FileContext persistence across tool switches + * + * 5. **Endpoint Availability Tests** + * - Test real endpoint availability checking + * - Test graceful degradation when endpoints are disabled + * - Test dynamic endpoint configuration updates + */ \ No newline at end of file diff --git a/frontend/src/tests/convert/ConvertSmartDetectionIntegration.test.tsx b/frontend/src/tests/convert/ConvertSmartDetectionIntegration.test.tsx new file mode 100644 index 000000000..64aafc488 --- /dev/null +++ b/frontend/src/tests/convert/ConvertSmartDetectionIntegration.test.tsx @@ -0,0 +1,527 @@ +/** + * Integration tests for Convert Tool Smart Detection with real file scenarios + * Tests the complete flow from file upload through auto-detection to API calls + */ + +import React from 'react'; +import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest'; +import { renderHook, act, waitFor } from '@testing-library/react'; +import { useConvertOperation } from '../../hooks/tools/convert/useConvertOperation'; +import { useConvertParameters } from '../../hooks/tools/convert/useConvertParameters'; +import { FileContextProvider } from '../../contexts/FileContext'; +import { I18nextProvider } from 'react-i18next'; +import i18n from '../../i18n/config'; +import axios from 'axios'; +import { detectFileExtension } from '../../utils/fileUtils'; + +// Mock axios +vi.mock('axios'); +const mockedAxios = vi.mocked(axios); + +// Mock only essential services that are actually called by the tests +vi.mock('../../services/fileStorage', () => ({ + fileStorage: { + init: vi.fn().mockResolvedValue(undefined), + storeFile: vi.fn().mockImplementation((file, thumbnail) => { + return Promise.resolve({ + id: `mock-id-${file.name}`, + name: file.name, + size: file.size, + type: file.type, + lastModified: file.lastModified, + thumbnail: thumbnail + }); + }), + getAllFileMetadata: vi.fn().mockResolvedValue([]), + cleanup: vi.fn().mockResolvedValue(undefined) + } +})); + +vi.mock('../../services/thumbnailGenerationService', () => ({ + thumbnailGenerationService: { + generateThumbnail: vi.fn().mockResolvedValue('data:image/png;base64,fake-thumbnail'), + cleanup: vi.fn(), + destroy: vi.fn() + } +})); + +const TestWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => ( + + + {children} + + +); + +describe('Convert Tool - Smart Detection Integration Tests', () => { + + beforeEach(() => { + vi.clearAllMocks(); + + // Mock successful API response + mockedAxios.post.mockResolvedValue({ + data: new Blob(['fake converted content'], { type: 'application/pdf' }) + }); + }); + + afterEach(() => { + // Clean up any blob URLs created during tests + vi.restoreAllMocks(); + }); + + describe('Single File Auto-Detection Flow', () => { + test('should auto-detect PDF from DOCX and convert to PDF', async () => { + const { result: paramsResult } = renderHook(() => useConvertParameters(), { + wrapper: TestWrapper + }); + + const { result: operationResult } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + // Create mock DOCX file + const docxFile = new File(['docx content'], 'document.docx', { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }); + + // Test auto-detection + act(() => { + paramsResult.current.analyzeFileTypes([docxFile]); + }); + + await waitFor(() => { + expect(paramsResult.current.parameters.fromExtension).toBe('docx'); + expect(paramsResult.current.parameters.toExtension).toBe('pdf'); + expect(paramsResult.current.parameters.isSmartDetection).toBe(false); + }); + + // Test conversion operation + await act(async () => { + await operationResult.current.executeOperation( + paramsResult.current.parameters, + [docxFile] + ); + }); + + expect(mockedAxios.post).toHaveBeenCalledWith('/api/v1/convert/file/pdf', expect.any(FormData), { + responseType: 'blob' + }); + }); + + test('should handle unknown file type with file-to-pdf fallback', async () => { + const { result: paramsResult } = renderHook(() => useConvertParameters(), { + wrapper: TestWrapper + }); + + const { result: operationResult } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + // Create mock unknown file + const unknownFile = new File(['unknown content'], 'document.xyz', { type: 'application/octet-stream' }); + + // Test auto-detection + act(() => { + paramsResult.current.analyzeFileTypes([unknownFile]); + }); + + await waitFor(() => { + expect(paramsResult.current.parameters.fromExtension).toBe('file-xyz'); + expect(paramsResult.current.parameters.toExtension).toBe('pdf'); // Fallback + expect(paramsResult.current.parameters.isSmartDetection).toBe(false); + }); + + // Test conversion operation + await act(async () => { + await operationResult.current.executeOperation( + paramsResult.current.parameters, + [unknownFile] + ); + }); + + expect(mockedAxios.post).toHaveBeenCalledWith('/api/v1/convert/file/pdf', expect.any(FormData), { + responseType: 'blob' + }); + }); + }); + + describe('Multi-File Smart Detection Flow', () => { + + test('should detect all images and use img-to-pdf endpoint', async () => { + const { result: paramsResult } = renderHook(() => useConvertParameters(), { + wrapper: TestWrapper + }); + + const { result: operationResult } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + // Create mock image files + const imageFiles = [ + new File(['jpg content'], 'photo1.jpg', { type: 'image/jpeg' }), + new File(['png content'], 'photo2.png', { type: 'image/png' }), + new File(['gif content'], 'photo3.gif', { type: 'image/gif' }) + ]; + + // Test smart detection for all images + act(() => { + paramsResult.current.analyzeFileTypes(imageFiles); + }); + + await waitFor(() => { + expect(paramsResult.current.parameters.fromExtension).toBe('image'); + expect(paramsResult.current.parameters.toExtension).toBe('pdf'); + expect(paramsResult.current.parameters.isSmartDetection).toBe(true); + expect(paramsResult.current.parameters.smartDetectionType).toBe('images'); + }); + + // Test conversion operation + await act(async () => { + await operationResult.current.executeOperation( + paramsResult.current.parameters, + imageFiles + ); + }); + + expect(mockedAxios.post).toHaveBeenCalledWith('/api/v1/convert/img/pdf', expect.any(FormData), { + responseType: 'blob' + }); + + // Should send all files in single request + const formData = mockedAxios.post.mock.calls[0][1] as FormData; + const files = formData.getAll('fileInput'); + expect(files).toHaveLength(3); + }); + + test('should detect mixed file types and use file-to-pdf endpoint', async () => { + const { result: paramsResult } = renderHook(() => useConvertParameters(), { + wrapper: TestWrapper + }); + + const { result: operationResult } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + // Create mixed file types + const mixedFiles = [ + new File(['pdf content'], 'document.pdf', { type: 'application/pdf' }), + new File(['docx content'], 'spreadsheet.xlsx', { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }), + new File(['pptx content'], 'presentation.pptx', { type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' }) + ]; + + // Test smart detection for mixed types + act(() => { + paramsResult.current.analyzeFileTypes(mixedFiles); + }); + + await waitFor(() => { + expect(paramsResult.current.parameters.fromExtension).toBe('any'); + expect(paramsResult.current.parameters.toExtension).toBe('pdf'); + expect(paramsResult.current.parameters.isSmartDetection).toBe(true); + expect(paramsResult.current.parameters.smartDetectionType).toBe('mixed'); + }); + + // Test conversion operation + await act(async () => { + await operationResult.current.executeOperation( + paramsResult.current.parameters, + mixedFiles + ); + }); + + expect(mockedAxios.post).toHaveBeenCalledWith('/api/v1/convert/file/pdf', expect.any(FormData), { + responseType: 'blob' + }); + }); + + test('should detect all web files and use html-to-pdf endpoint', async () => { + const { result: paramsResult } = renderHook(() => useConvertParameters(), { + wrapper: TestWrapper + }); + + const { result: operationResult } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + // Create mock web files + const webFiles = [ + new File(['content'], 'page1.html', { type: 'text/html' }), + new File(['zip content'], 'site.zip', { type: 'application/zip' }) + ]; + + // Test smart detection for web files + act(() => { + paramsResult.current.analyzeFileTypes(webFiles); + }); + + await waitFor(() => { + expect(paramsResult.current.parameters.fromExtension).toBe('html'); + expect(paramsResult.current.parameters.toExtension).toBe('pdf'); + expect(paramsResult.current.parameters.isSmartDetection).toBe(true); + expect(paramsResult.current.parameters.smartDetectionType).toBe('web'); + }); + + // Test conversion operation + await act(async () => { + await operationResult.current.executeOperation( + paramsResult.current.parameters, + webFiles + ); + }); + + expect(mockedAxios.post).toHaveBeenCalledWith('/api/v1/convert/html/pdf', expect.any(FormData), { + responseType: 'blob' + }); + + // Should process files separately for web files + expect(mockedAxios.post).toHaveBeenCalledTimes(2); + }); + }); + + describe('Web and Email Conversion Options Integration', () => { + + test('should send correct HTML parameters for web-to-pdf conversion', async () => { + const { result: paramsResult } = renderHook(() => useConvertParameters(), { + wrapper: TestWrapper + }); + + const { result: operationResult } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const htmlFile = new File(['content'], 'page.html', { type: 'text/html' }); + + // Set up HTML conversion parameters + act(() => { + paramsResult.current.analyzeFileTypes([htmlFile]); + paramsResult.current.updateParameter('htmlOptions', { + zoomLevel: 1.5 + }); + }); + + await act(async () => { + await operationResult.current.executeOperation( + paramsResult.current.parameters, + [htmlFile] + ); + }); + + const formData = mockedAxios.post.mock.calls[0][1] as FormData; + expect(formData.get('zoom')).toBe('1.5'); + }); + + test('should send correct email parameters for eml-to-pdf conversion', async () => { + const { result: paramsResult } = renderHook(() => useConvertParameters(), { + wrapper: TestWrapper + }); + + const { result: operationResult } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const emlFile = new File(['email content'], 'email.eml', { type: 'message/rfc822' }); + + // Set up email conversion parameters + act(() => { + paramsResult.current.updateParameter('fromExtension', 'eml'); + paramsResult.current.updateParameter('toExtension', 'pdf'); + paramsResult.current.updateParameter('emailOptions', { + includeAttachments: false, + maxAttachmentSizeMB: 20, + downloadHtml: true, + includeAllRecipients: true + }); + }); + + await act(async () => { + await operationResult.current.executeOperation( + paramsResult.current.parameters, + [emlFile] + ); + }); + + const formData = mockedAxios.post.mock.calls[0][1] as FormData; + expect(formData.get('includeAttachments')).toBe('false'); + expect(formData.get('maxAttachmentSizeMB')).toBe('20'); + expect(formData.get('downloadHtml')).toBe('true'); + expect(formData.get('includeAllRecipients')).toBe('true'); + }); + + test('should send correct PDF/A parameters for pdf-to-pdfa conversion', async () => { + const { result: paramsResult } = renderHook(() => useConvertParameters(), { + wrapper: TestWrapper + }); + + const { result: operationResult } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const pdfFile = new File(['pdf content'], 'document.pdf', { type: 'application/pdf' }); + + // Set up PDF/A conversion parameters + act(() => { + paramsResult.current.updateParameter('fromExtension', 'pdf'); + paramsResult.current.updateParameter('toExtension', 'pdfa'); + paramsResult.current.updateParameter('pdfaOptions', { + outputFormat: 'pdfa' + }); + }); + + await act(async () => { + await operationResult.current.executeOperation( + paramsResult.current.parameters, + [pdfFile] + ); + }); + + const formData = mockedAxios.post.mock.calls[0][1] as FormData; + expect(formData.get('outputFormat')).toBe('pdfa'); + expect(mockedAxios.post).toHaveBeenCalledWith('/api/v1/convert/pdf/pdfa', expect.any(FormData), { + responseType: 'blob' + }); + }); + }); + + describe('Image Conversion Options Integration', () => { + + test('should send correct parameters for image-to-pdf conversion', async () => { + const { result: paramsResult } = renderHook(() => useConvertParameters(), { + wrapper: TestWrapper + }); + + const { result: operationResult } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const imageFiles = [ + new File(['jpg1'], 'photo1.jpg', { type: 'image/jpeg' }), + new File(['jpg2'], 'photo2.jpg', { type: 'image/jpeg' }) + ]; + + // Set up image conversion parameters + act(() => { + paramsResult.current.analyzeFileTypes(imageFiles); + paramsResult.current.updateParameter('imageOptions', { + colorType: 'grayscale', + dpi: 150, + singleOrMultiple: 'single', + fitOption: 'fitToPage', + autoRotate: false, + combineImages: true + }); + }); + + await act(async () => { + await operationResult.current.executeOperation( + paramsResult.current.parameters, + imageFiles + ); + }); + + const formData = mockedAxios.post.mock.calls[0][1] as FormData; + expect(formData.get('fitOption')).toBe('fitToPage'); + expect(formData.get('colorType')).toBe('grayscale'); + expect(formData.get('autoRotate')).toBe('false'); + }); + + test('should process images separately when combineImages is false', async () => { + const { result: paramsResult } = renderHook(() => useConvertParameters(), { + wrapper: TestWrapper + }); + + const { result: operationResult } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + const imageFiles = [ + new File(['jpg1'], 'photo1.jpg', { type: 'image/jpeg' }), + new File(['jpg2'], 'photo2.jpg', { type: 'image/jpeg' }) + ]; + + // Set up for separate processing + act(() => { + paramsResult.current.analyzeFileTypes(imageFiles); + paramsResult.current.updateParameter('imageOptions', { + ...paramsResult.current.parameters.imageOptions, + combineImages: false + }); + }); + + await act(async () => { + await operationResult.current.executeOperation( + paramsResult.current.parameters, + imageFiles + ); + }); + + // Should make separate API calls for each file + expect(mockedAxios.post).toHaveBeenCalledTimes(2); + }); + }); + + describe('Error Scenarios in Smart Detection', () => { + + + test('should handle partial failures in multi-file processing', async () => { + const { result: paramsResult } = renderHook(() => useConvertParameters(), { + wrapper: TestWrapper + }); + + const { result: operationResult } = renderHook(() => useConvertOperation(), { + wrapper: TestWrapper + }); + + // Mock one success, one failure + mockedAxios.post + .mockResolvedValueOnce({ + data: new Blob(['converted1'], { type: 'application/pdf' }) + }) + .mockRejectedValueOnce(new Error('File 2 failed')); + + const mixedFiles = [ + new File(['file1'], 'doc1.txt', { type: 'text/plain' }), + new File(['file2'], 'doc2.xyz', { type: 'application/octet-stream' }) + ]; + + // Set up for separate processing (mixed smart detection) + act(() => { + paramsResult.current.analyzeFileTypes(mixedFiles); + }); + + await act(async () => { + await operationResult.current.executeOperation( + paramsResult.current.parameters, + mixedFiles + ); + }); + + await waitFor(() => { + // Should have processed at least one file successfully + expect(operationResult.current.files.length).toBeGreaterThan(0); + expect(mockedAxios.post).toHaveBeenCalledTimes(2); + }); + }); + }); + + describe('Real File Extension Detection', () => { + + test('should correctly detect various file extensions', async () => { + const { result } = renderHook(() => useConvertParameters(), { + wrapper: TestWrapper + }); + + const testCases = [ + { filename: 'document.PDF', expected: 'pdf' }, + { filename: 'image.JPEG', expected: 'jpg' }, // JPEG should normalize to jpg + { filename: 'photo.jpeg', expected: 'jpg' }, // jpeg should normalize to jpg + { filename: 'archive.tar.gz', expected: 'gz' }, + { filename: 'file.', expected: '' }, + { filename: '.hidden', expected: 'hidden' }, + { filename: 'noextension', expected: '' } + ]; + + testCases.forEach(({ filename, expected }) => { + const detected = detectFileExtension(filename); + expect(detected).toBe(expected); + }); + }); + }); +}); \ No newline at end of file diff --git a/frontend/src/tests/convert/README.md b/frontend/src/tests/convert/README.md new file mode 100644 index 000000000..e008ea838 --- /dev/null +++ b/frontend/src/tests/convert/README.md @@ -0,0 +1,264 @@ +# Convert Tool Test Suite + +This directory contains comprehensive tests for the Convert Tool functionality. + +## Test Files Overview + +### 1. ConvertTool.test.tsx +**Purpose**: Unit/Component testing for the Convert Tool UI components +- Tests dropdown behavior and navigation +- Tests format availability based on endpoint status +- Tests UI state management and form validation +- Mocks backend dependencies for isolated testing + +**Key Test Areas**: +- FROM dropdown enables/disables formats based on endpoint availability +- TO dropdown shows correct conversions for selected source format +- Format-specific options appear/disappear correctly +- Parameter validation and state management + +### 2. ConvertIntegration.test.ts +**Purpose**: Integration testing for Convert Tool business logic +- Tests parameter validation and conversion matrix logic +- Tests endpoint resolution and availability checking +- Tests file extension detection +- Provides framework for testing actual conversions (requires backend) + +**Key Test Areas**: +- Endpoint availability checking matches real backend status +- Conversion parameters are correctly validated +- File extension detection works properly +- Conversion matrix returns correct available formats + +### 3. ConvertE2E.spec.ts +**Purpose**: End-to-End testing using Playwright with Dynamic Endpoint Discovery +- **Automatically discovers available conversion endpoints** from the backend +- Tests complete user workflows from file upload to download +- Tests actual file conversions with real backend +- **Skips tests for unavailable endpoints** automatically +- Tests error handling and edge cases +- Tests UI/UX flow and user interactions + +**Key Test Areas**: +- **Dynamic endpoint discovery** using `/api/v1/config/endpoints-enabled` API +- Complete conversion workflows for **all available endpoints** +- **Unavailable endpoint testing** - verifies disabled conversions are properly blocked +- File upload, conversion, and download process +- Error handling for corrupted files and network issues +- Performance testing with large files +- UI responsiveness and progress indicators + +**Supported Conversions** (tested if available): +- PDF ↔ Images (PNG, JPG, GIF, BMP, TIFF, WebP) +- PDF ↔ Office (DOCX, PPTX) +- PDF ↔ Text (TXT, HTML, XML, CSV, Markdown) +- Office → PDF (DOCX, PPTX, XLSX, etc.) +- Email (EML) → PDF +- HTML → PDF, URL → PDF +- Markdown → PDF + +## Running the Tests + +**Important**: All commands should be run from the `frontend/` directory: +```bash +cd frontend +``` + +### Setup (First Time Only) +```bash +# Install dependencies (includes test frameworks) +npm install + +# Install Playwright browsers for E2E tests +npx playwright install +``` + +### Unit Tests (ConvertTool.test.tsx) +```bash +# Run all unit tests +npm test + +# Run specific test file +npm test ConvertTool.test.tsx + +# Run with coverage +npm run test:coverage + +# Run in watch mode (re-runs on file changes) +npm run test:watch + +# Run specific test pattern +npm test -- --grep "dropdown" +``` + +### Integration Tests (ConvertIntegration.test.ts) +```bash +# Run integration tests +npm test ConvertIntegration.test.ts + +# Run with verbose output +npm test ConvertIntegration.test.ts -- --reporter=verbose +``` + +### E2E Tests (ConvertE2E.spec.ts) +```bash +# Prerequisites: Backend must be running on localhost:8080 +# Start backend first, then: + +# Run all E2E tests (automatically discovers available endpoints) +npm run test:e2e + +# Run specific E2E test file +npx playwright test ConvertE2E.spec.ts + +# Run with UI mode for debugging +npx playwright test --ui + +# Run specific test by endpoint name (dynamic) +npx playwright test -g "pdf-to-img:" + +# Run only available conversion tests +npx playwright test -g "Dynamic Conversion Tests" + +# Run only unavailable conversion tests +npx playwright test -g "Unavailable Conversions" + +# Run in headed mode (see browser) +npx playwright test --headed + +# Generate HTML report +npx playwright test ConvertE2E.spec.ts --reporter=html +``` + +**Test Discovery Process:** +1. Tests automatically query `/api/v1/config/endpoints-enabled` to discover available conversions +2. Tests are generated dynamically for each available endpoint +3. Tests for unavailable endpoints verify they're properly disabled in the UI +4. Console output shows which endpoints were discovered + +## Test Requirements + +### For Unit Tests +- No special requirements +- All dependencies are mocked +- Can run in any environment + +### For Integration Tests +- May require backend API for full functionality +- Uses mock data for endpoint availability +- Tests business logic in isolation + +### For E2E Tests +- **Requires running backend server** (localhost:8080) +- **Requires test fixture files** (see ../test-fixtures/README.md) +- Requires frontend dev server (localhost:5173) +- Tests real conversion functionality + +## Test Data + +The tests use realistic endpoint availability data based on your current server configuration: + +**Available Endpoints** (should pass): +- `file-to-pdf`: true (DOCX, XLSX, PPTX → PDF) +- `img-to-pdf`: true (PNG, JPG, etc. → PDF) +- `markdown-to-pdf`: true (MD → PDF) +- `pdf-to-csv`: true (PDF → CSV) +- `pdf-to-img`: true (PDF → PNG, JPG, etc.) +- `pdf-to-text`: true (PDF → TXT) + +**Disabled Endpoints** (should be blocked): +- `eml-to-pdf`: false +- `html-to-pdf`: false +- `pdf-to-html`: false +- `pdf-to-markdown`: false +- `pdf-to-pdfa`: false +- `pdf-to-presentation`: false +- `pdf-to-word`: false +- `pdf-to-xml`: false + +## Test Scenarios + +### Success Scenarios (Available Endpoints) +1. **PDF → Image**: PDF to PNG/JPG with various DPI and color settings +2. **PDF → Data**: PDF to CSV (table extraction), PDF to TXT (text extraction) +3. **Office → PDF**: DOCX/XLSX/PPTX to PDF conversion +4. **Image → PDF**: PNG/JPG to PDF with image options +5. **Markdown → PDF**: MD to PDF with formatting preservation + +### Blocked Scenarios (Disabled Endpoints) +1. **EML conversions**: Should be disabled in FROM dropdown +2. **PDF → Office**: PDF to Word/PowerPoint should be disabled +3. **PDF → Web**: PDF to HTML/XML should be disabled +4. **PDF → PDF/A**: Should be disabled + +### Error Scenarios +1. **Corrupted files**: Should show helpful error messages +2. **Network failures**: Should handle backend unavailability +3. **Large files**: Should handle memory constraints gracefully +4. **Invalid parameters**: Should validate before submission + +## Adding New Tests + +When adding new conversion formats: + +1. **Update ConvertTool.test.tsx**: + - Add the new format to test data + - Test dropdown behavior for the new format + - Test format-specific options if any + +2. **Update ConvertIntegration.test.ts**: + - Add endpoint availability test cases + - Add conversion matrix test cases + - Add parameter validation tests + +3. **Update ConvertE2E.spec.ts**: + - Add end-to-end workflow tests + - Add test fixture files + - Test actual conversion functionality + +4. **Update test fixtures**: + - Add sample files for the new format + - Update ../test-fixtures/README.md + +## Debugging Failed Tests + +### Unit Test Failures +- Check mock data matches real endpoint status +- Verify component props and state management +- Check for React hook dependency issues + +### Integration Test Failures +- Verify conversion matrix includes new formats +- Check endpoint name mappings +- Ensure parameter validation logic is correct + +### E2E Test Failures +- Ensure backend server is running +- Check test fixture files exist and are valid +- Verify element selectors match current UI +- Check for timing issues (increase timeouts if needed) + +## Test Maintenance + +### Regular Updates Needed +1. **Endpoint Status**: Update mock data when backend endpoints change +2. **UI Selectors**: Update test selectors when UI changes +3. **Test Fixtures**: Replace old test files with new ones periodically +4. **Performance Benchmarks**: Update expected performance metrics + +### CI/CD Integration +- Unit tests: Run on every commit +- Integration tests: Run on pull requests +- E2E tests: Run on staging deployment +- Performance tests: Run weekly or on major releases + +## Performance Expectations + +These tests focus on frontend functionality, not backend performance: + +- **File upload/UI**: < 1 second for small test files +- **Dropdown interactions**: < 200ms +- **Form validation**: < 100ms +- **Conversion UI flow**: < 5 seconds for small test files + +Tests will fail if UI interactions are slow, indicating frontend performance issues. \ No newline at end of file diff --git a/frontend/src/tests/helpers/conversionEndpointDiscovery.ts b/frontend/src/tests/helpers/conversionEndpointDiscovery.ts new file mode 100644 index 000000000..cf0474dac --- /dev/null +++ b/frontend/src/tests/helpers/conversionEndpointDiscovery.ts @@ -0,0 +1,304 @@ +/** + * Conversion Endpoint Discovery for E2E Testing + * + * Uses the backend's endpoint configuration API to discover available conversions + */ + +import { useMultipleEndpointsEnabled } from '../../hooks/useEndpointConfig'; + +export interface ConversionEndpoint { + endpoint: string; + fromFormat: string; + toFormat: string; + description: string; + apiPath: string; +} + +// Complete list of conversion endpoints based on EndpointConfiguration.java +const ALL_CONVERSION_ENDPOINTS: ConversionEndpoint[] = [ + { + endpoint: 'pdf-to-img', + fromFormat: 'pdf', + toFormat: 'image', + description: 'Convert PDF to images (PNG, JPG, GIF, etc.)', + apiPath: '/api/v1/convert/pdf/img' + }, + { + endpoint: 'img-to-pdf', + fromFormat: 'image', + toFormat: 'pdf', + description: 'Convert images to PDF', + apiPath: '/api/v1/convert/img/pdf' + }, + { + endpoint: 'pdf-to-pdfa', + fromFormat: 'pdf', + toFormat: 'pdfa', + description: 'Convert PDF to PDF/A', + apiPath: '/api/v1/convert/pdf/pdfa' + }, + { + endpoint: 'file-to-pdf', + fromFormat: 'office', + toFormat: 'pdf', + description: 'Convert office files to PDF', + apiPath: '/api/v1/convert/file/pdf' + }, + { + endpoint: 'pdf-to-word', + fromFormat: 'pdf', + toFormat: 'docx', + description: 'Convert PDF to Word document', + apiPath: '/api/v1/convert/pdf/word' + }, + { + endpoint: 'pdf-to-presentation', + fromFormat: 'pdf', + toFormat: 'pptx', + description: 'Convert PDF to PowerPoint presentation', + apiPath: '/api/v1/convert/pdf/presentation' + }, + { + endpoint: 'pdf-to-text', + fromFormat: 'pdf', + toFormat: 'txt', + description: 'Convert PDF to plain text', + apiPath: '/api/v1/convert/pdf/text' + }, + { + endpoint: 'pdf-to-html', + fromFormat: 'pdf', + toFormat: 'html', + description: 'Convert PDF to HTML', + apiPath: '/api/v1/convert/pdf/html' + }, + { + endpoint: 'pdf-to-xml', + fromFormat: 'pdf', + toFormat: 'xml', + description: 'Convert PDF to XML', + apiPath: '/api/v1/convert/pdf/xml' + }, + { + endpoint: 'html-to-pdf', + fromFormat: 'html', + toFormat: 'pdf', + description: 'Convert HTML to PDF', + apiPath: '/api/v1/convert/html/pdf' + }, + { + endpoint: 'url-to-pdf', + fromFormat: 'url', + toFormat: 'pdf', + description: 'Convert web page to PDF', + apiPath: '/api/v1/convert/url/pdf' + }, + { + endpoint: 'markdown-to-pdf', + fromFormat: 'md', + toFormat: 'pdf', + description: 'Convert Markdown to PDF', + apiPath: '/api/v1/convert/markdown/pdf' + }, + { + endpoint: 'pdf-to-csv', + fromFormat: 'pdf', + toFormat: 'csv', + description: 'Extract CSV data from PDF', + apiPath: '/api/v1/convert/pdf/csv' + }, + { + endpoint: 'pdf-to-markdown', + fromFormat: 'pdf', + toFormat: 'md', + description: 'Convert PDF to Markdown', + apiPath: '/api/v1/convert/pdf/markdown' + }, + { + endpoint: 'eml-to-pdf', + fromFormat: 'eml', + toFormat: 'pdf', + description: 'Convert email (EML) to PDF', + apiPath: '/api/v1/convert/eml/pdf' + } +]; + +export class ConversionEndpointDiscovery { + private baseUrl: string; + private cache: Map | null = null; + private cacheExpiry: number = 0; + private readonly CACHE_DURATION = 5 * 60 * 1000; // 5 minutes + + constructor(baseUrl: string = process.env.BACKEND_URL || 'http://localhost:8080') { + this.baseUrl = baseUrl; + } + + /** + * Get all available conversion endpoints by checking with backend + */ + async getAvailableConversions(): Promise { + const endpointStatuses = await this.getEndpointStatuses(); + + return ALL_CONVERSION_ENDPOINTS.filter(conversion => + endpointStatuses.get(conversion.endpoint) === true + ); + } + + /** + * Get all unavailable conversion endpoints + */ + async getUnavailableConversions(): Promise { + const endpointStatuses = await this.getEndpointStatuses(); + + return ALL_CONVERSION_ENDPOINTS.filter(conversion => + endpointStatuses.get(conversion.endpoint) === false + ); + } + + /** + * Check if a specific conversion is available + */ + async isConversionAvailable(endpoint: string): Promise { + const endpointStatuses = await this.getEndpointStatuses(); + return endpointStatuses.get(endpoint) === true; + } + + /** + * Get available conversions grouped by source format + */ + async getConversionsByFormat(): Promise> { + const availableConversions = await this.getAvailableConversions(); + + const grouped: Record = {}; + + availableConversions.forEach(conversion => { + if (!grouped[conversion.fromFormat]) { + grouped[conversion.fromFormat] = []; + } + grouped[conversion.fromFormat].push(conversion); + }); + + return grouped; + } + + /** + * Get supported target formats for a given source format + */ + async getSupportedTargetFormats(fromFormat: string): Promise { + const availableConversions = await this.getAvailableConversions(); + + return availableConversions + .filter(conversion => conversion.fromFormat === fromFormat) + .map(conversion => conversion.toFormat); + } + + /** + * Get all supported source formats + */ + async getSupportedSourceFormats(): Promise { + const availableConversions = await this.getAvailableConversions(); + + const sourceFormats = new Set( + availableConversions.map(conversion => conversion.fromFormat) + ); + + return Array.from(sourceFormats); + } + + /** + * Get endpoint statuses from backend using batch API + */ + private async getEndpointStatuses(): Promise> { + // Return cached result if still valid + if (this.cache && Date.now() < this.cacheExpiry) { + return this.cache; + } + + try { + const endpointNames = ALL_CONVERSION_ENDPOINTS.map(conv => conv.endpoint); + const endpointsParam = endpointNames.join(','); + + const response = await fetch( + `${this.baseUrl}/api/v1/config/endpoints-enabled?endpoints=${encodeURIComponent(endpointsParam)}` + ); + + if (!response.ok) { + throw new Error(`Failed to fetch endpoint statuses: ${response.status} ${response.statusText}`); + } + + const statusMap: Record = await response.json(); + + // Convert to Map and cache + this.cache = new Map(Object.entries(statusMap)); + this.cacheExpiry = Date.now() + this.CACHE_DURATION; + + console.log(`Retrieved status for ${Object.keys(statusMap).length} conversion endpoints`); + return this.cache; + + } catch (error) { + console.error('Failed to get endpoint statuses:', error); + + // Fallback: assume all endpoints are disabled + const fallbackMap = new Map(); + ALL_CONVERSION_ENDPOINTS.forEach(conv => { + fallbackMap.set(conv.endpoint, false); + }); + + return fallbackMap; + } + } + + /** + * Utility to create a skipping condition for tests + */ + static createSkipCondition(endpoint: string, discovery: ConversionEndpointDiscovery) { + return async () => { + const available = await discovery.isConversionAvailable(endpoint); + return !available; + }; + } + + /** + * Get detailed conversion info by endpoint name + */ + getConversionInfo(endpoint: string): ConversionEndpoint | undefined { + return ALL_CONVERSION_ENDPOINTS.find(conv => conv.endpoint === endpoint); + } + + /** + * Get all conversion endpoints (regardless of availability) + */ + getAllConversions(): ConversionEndpoint[] { + return [...ALL_CONVERSION_ENDPOINTS]; + } +} + +// Export singleton instance for reuse across tests +export const conversionDiscovery = new ConversionEndpointDiscovery(); + +/** + * React hook version for use in components (wraps the class) + */ +export function useConversionEndpoints() { + const endpointNames = ALL_CONVERSION_ENDPOINTS.map(conv => conv.endpoint); + const { endpointStatus, loading, error, refetch } = useMultipleEndpointsEnabled(endpointNames); + + const availableConversions = ALL_CONVERSION_ENDPOINTS.filter( + conv => endpointStatus[conv.endpoint] === true + ); + + const unavailableConversions = ALL_CONVERSION_ENDPOINTS.filter( + conv => endpointStatus[conv.endpoint] === false + ); + + return { + availableConversions, + unavailableConversions, + allConversions: ALL_CONVERSION_ENDPOINTS, + endpointStatus, + loading, + error, + refetch, + isConversionAvailable: (endpoint: string) => endpointStatus[endpoint] === true + }; +} \ No newline at end of file diff --git a/frontend/src/tests/test-fixtures/README.md b/frontend/src/tests/test-fixtures/README.md new file mode 100644 index 000000000..32e64b346 --- /dev/null +++ b/frontend/src/tests/test-fixtures/README.md @@ -0,0 +1,132 @@ +# Test Fixtures for Convert Tool Testing + +This directory contains sample files for testing the convert tool functionality. + +## Required Test Files + +To run the full test suite, please add the following test files to this directory: + +### 1. sample.pdf +- A small PDF document (1-2 pages) +- Should contain text and ideally a simple table for CSV conversion testing +- Should be under 1MB for fast testing + +### 2. sample.docx +- A Microsoft Word document with basic formatting +- Should contain headers, paragraphs, and possibly a table +- Should be under 500KB + +### 3. sample.png +- A small PNG image (e.g., 500x500 pixels) +- Should be a real image, not just a test pattern +- Should be under 100KB + +### 3b. sample.jpg +- A small JPG image (same image as PNG, different format) +- Should be under 100KB +- Can be created by converting sample.png to JPG + +### 4. sample.md +- A Markdown file with various formatting elements: + ```markdown + # Test Document + + This is a **test** markdown file. + + ## Features + + - Lists + - **Bold text** + - *Italic text* + - [Links](https://example.com) + + ### Code Block + + ```javascript + console.log('Hello, world!'); + ``` + + | Column 1 | Column 2 | + |----------|----------| + | Data 1 | Data 2 | + ``` + +### 5. sample.eml (Optional) +- An email file with headers and body +- Can be exported from any email client +- Should contain some attachments for testing + +### 6. sample.html (Optional) +- A simple HTML file with various elements +- Should include text, headings, and basic styling + + +## File Creation Tips + +### Creating a test PDF: +1. Create a document in LibreOffice Writer or Google Docs +2. Add some text, headers, and a simple table +3. Export/Save as PDF + +### Creating a test DOCX: +1. Create a document in Microsoft Word or LibreOffice Writer +2. Add formatted content (headers, bold, italic, lists) +3. Save as DOCX format + +### Creating a test PNG: +1. Use any image editor or screenshot tool +2. Create a simple image with text or shapes +3. Save as PNG format + +### Creating a test EML: +1. In your email client, save an email as .eml format +2. Or create manually with proper headers: + ``` + From: test@example.com + To: recipient@example.com + Subject: Test Email + Date: Mon, 1 Jan 2024 12:00:00 +0000 + + This is a test email for conversion testing. + ``` + +## Test File Structure + +``` +frontend/src/tests/test-fixtures/ +ā”œā”€ā”€ README.md (this file) +ā”œā”€ā”€ sample.pdf +ā”œā”€ā”€ sample.docx +ā”œā”€ā”€ sample.png +ā”œā”€ā”€ sample.jpg +ā”œā”€ā”€ sample.md +ā”œā”€ā”€ sample.eml (optional) +└── sample.html (optional) +``` + +## Usage in Tests + +These files are referenced in the test files: + +- `ConvertE2E.spec.ts` - Uses all files for E2E testing +- `ConvertIntegration.test.ts` - Uses files for integration testing +- Manual testing scenarios + +## Security Note + +These are test files only and should not contain any sensitive information. They will be committed to the repository and used in automated testing. + +## File Size Guidelines + +- Keep test files small for fast CI/CD pipelines and frontend testing +- PDF files: < 1MB (preferably 100-500KB) +- Image files: < 100KB +- Text files: < 50KB +- Focus on frontend functionality, not backend performance + +## Maintenance + +When updating the convert tool with new formats: +1. Add corresponding test files to this directory +2. Update the test files list above +3. Update the test cases to include the new formats \ No newline at end of file diff --git a/frontend/src/tests/test-fixtures/corrupted.pdf b/frontend/src/tests/test-fixtures/corrupted.pdf new file mode 100644 index 000000000..fcfa08529 --- /dev/null +++ b/frontend/src/tests/test-fixtures/corrupted.pdf @@ -0,0 +1 @@ +This is not a valid PDF file \ No newline at end of file diff --git a/frontend/src/tests/test-fixtures/sample.csv b/frontend/src/tests/test-fixtures/sample.csv new file mode 100644 index 000000000..9c139e4bc --- /dev/null +++ b/frontend/src/tests/test-fixtures/sample.csv @@ -0,0 +1,6 @@ +Name,Age,City,Country +John Doe,30,New York,USA +Jane Smith,25,London,UK +Bob Johnson,35,Toronto,Canada +Alice Brown,28,Sydney,Australia +Charlie Wilson,42,Berlin,Germany \ No newline at end of file diff --git a/frontend/src/tests/test-fixtures/sample.doc b/frontend/src/tests/test-fixtures/sample.doc new file mode 100644 index 000000000..23bec4b35 --- /dev/null +++ b/frontend/src/tests/test-fixtures/sample.doc @@ -0,0 +1,10 @@ +# Test DOC File + +This is a test DOC file for conversion testing. + +Content: +- Test bullet point 1 +- Test bullet point 2 +- Test bullet point 3 + +This file should be sufficient for testing office document conversions. \ No newline at end of file diff --git a/frontend/src/tests/test-fixtures/sample.docx b/frontend/src/tests/test-fixtures/sample.docx new file mode 100644 index 000000000..45fc50c23 Binary files /dev/null and b/frontend/src/tests/test-fixtures/sample.docx differ diff --git a/frontend/src/tests/test-fixtures/sample.eml b/frontend/src/tests/test-fixtures/sample.eml new file mode 100644 index 000000000..99023066d --- /dev/null +++ b/frontend/src/tests/test-fixtures/sample.eml @@ -0,0 +1,105 @@ +Return-Path: +Delivered-To: recipient@example.com +Received: from mail.example.com (mail.example.com [192.168.1.1]) + by mx.example.com (Postfix) with ESMTP id 1234567890 + for ; Mon, 1 Jan 2024 12:00:00 +0000 (UTC) +Message-ID: +Date: Mon, 1 Jan 2024 12:00:00 +0000 +From: Test Sender +User-Agent: Mozilla/5.0 (compatible; Test Email Client) +MIME-Version: 1.0 +To: Test Recipient +Subject: Test Email for Convert Tool +Content-Type: multipart/alternative; + boundary="------------boundary123456789" + +This is a multi-part message in MIME format. +--------------boundary123456789 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +Test Email for Convert Tool +=========================== + +This is a test email for testing the EML to PDF conversion functionality. + +Email Details: +- From: test@example.com +- To: recipient@example.com +- Subject: Test Email for Convert Tool +- Date: January 1, 2024 + +Content Features: +- Plain text content +- HTML content (in alternative part) +- Headers and metadata +- MIME structure + +This email should convert to a PDF that includes: +1. Email headers (From, To, Subject, Date) +2. Email body content +3. Proper formatting + +Important Notes: +- This is a test email only +- Generated for Stirling PDF testing +- Contains no sensitive information +- Should preserve email formatting in PDF + +Best regards, +Test Email System + +--------------boundary123456789 +Content-Type: text/html; charset=UTF-8 +Content-Transfer-Encoding: 7bit + + + + + + Test Email + + +

Test Email for Convert Tool

+ +

This is a test email for testing the EML to PDF conversion functionality.

+ +

Email Details:

+
    +
  • From: test@example.com
  • +
  • To: recipient@example.com
  • +
  • Subject: Test Email for Convert Tool
  • +
  • Date: January 1, 2024
  • +
+ +

Content Features:

+
    +
  • Plain text content
  • +
  • HTML content (this part)
  • +
  • Headers and metadata
  • +
  • MIME structure
  • +
+ +
+

This email should convert to a PDF that includes:

+
    +
  1. Email headers (From, To, Subject, Date)
  2. +
  3. Email body content
  4. +
  5. Proper formatting
  6. +
+
+ +

Important Notes:

+
    +
  • This is a test email only
  • +
  • Generated for Stirling PDF testing
  • +
  • Contains no sensitive information
  • +
  • Should preserve email formatting in PDF
  • +
+ +

Best regards,
+ Test Email System

+ + + +--------------boundary123456789-- \ No newline at end of file diff --git a/frontend/src/tests/test-fixtures/sample.htm b/frontend/src/tests/test-fixtures/sample.htm new file mode 100644 index 000000000..83a5260a7 --- /dev/null +++ b/frontend/src/tests/test-fixtures/sample.htm @@ -0,0 +1,125 @@ + + + + + + Test HTML Document + + + +

Test HTML Document for Convert Tool

+ +

This is a test HTML file for testing the HTML to PDF conversion functionality. It contains various HTML elements to ensure proper conversion.

+ +

Text Formatting

+

This paragraph contains bold text, italic text, and inline code.

+ +
+

Important: This is a highlighted section that should be preserved in the PDF output.

+
+ +

Lists

+

Unordered List

+
+ +

Ordered List

+
    +
  1. Primary point
  2. +
  3. Secondary point
  4. +
  5. Tertiary point
  6. +
+ +

Table

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Column 1Column 2Column 3
Data AData BData C
Test 1Test 2Test 3
Sample XSample YSample Z
+ +

Code Block

+
function testFunction() {
+    console.log("This is a test function");
+    return "Hello from HTML to PDF conversion";
+}
+ +

Final Notes

+

This HTML document should convert to a well-formatted PDF that preserves:

+
    +
  • Text formatting (bold, italic)
  • +
  • Headings and hierarchy
  • +
  • Tables with proper borders
  • +
  • Lists (ordered and unordered)
  • +
  • Code formatting
  • +
  • Basic CSS styling
  • +
+ +

Generated for Stirling PDF Convert Tool testing purposes.

+ + \ No newline at end of file diff --git a/frontend/src/tests/test-fixtures/sample.html b/frontend/src/tests/test-fixtures/sample.html new file mode 100644 index 000000000..83a5260a7 --- /dev/null +++ b/frontend/src/tests/test-fixtures/sample.html @@ -0,0 +1,125 @@ + + + + + + Test HTML Document + + + +

Test HTML Document for Convert Tool

+ +

This is a test HTML file for testing the HTML to PDF conversion functionality. It contains various HTML elements to ensure proper conversion.

+ +

Text Formatting

+

This paragraph contains bold text, italic text, and inline code.

+ +
+

Important: This is a highlighted section that should be preserved in the PDF output.

+
+ +

Lists

+

Unordered List

+
    +
  • First item
  • +
  • Second item with a link
  • +
  • Third item
  • +
+ +

Ordered List

+
    +
  1. Primary point
  2. +
  3. Secondary point
  4. +
  5. Tertiary point
  6. +
+ +

Table

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Column 1Column 2Column 3
Data AData BData C
Test 1Test 2Test 3
Sample XSample YSample Z
+ +

Code Block

+
function testFunction() {
+    console.log("This is a test function");
+    return "Hello from HTML to PDF conversion";
+}
+ +

Final Notes

+

This HTML document should convert to a well-formatted PDF that preserves:

+
    +
  • Text formatting (bold, italic)
  • +
  • Headings and hierarchy
  • +
  • Tables with proper borders
  • +
  • Lists (ordered and unordered)
  • +
  • Code formatting
  • +
  • Basic CSS styling
  • +
+ +

Generated for Stirling PDF Convert Tool testing purposes.

+ + \ No newline at end of file diff --git a/frontend/src/tests/test-fixtures/sample.jpg b/frontend/src/tests/test-fixtures/sample.jpg new file mode 100644 index 000000000..a2dc48c27 Binary files /dev/null and b/frontend/src/tests/test-fixtures/sample.jpg differ diff --git a/frontend/src/tests/test-fixtures/sample.md b/frontend/src/tests/test-fixtures/sample.md new file mode 100644 index 000000000..fba73ad74 --- /dev/null +++ b/frontend/src/tests/test-fixtures/sample.md @@ -0,0 +1,49 @@ +# Test Document for Convert Tool + +This is a **test** markdown file for testing the markdown to PDF conversion functionality. + +## Features Being Tested + +- **Bold text** +- *Italic text* +- [Links](https://example.com) +- Lists and formatting + +### Code Block + +```javascript +console.log('Hello, world!'); +function testFunction() { + return "This is a test"; +} +``` + +### Table + +| Column 1 | Column 2 | Column 3 | +|----------|----------|----------| +| Data 1 | Data 2 | Data 3 | +| Test A | Test B | Test C | + +## Lists + +### Unordered List +- Item 1 +- Item 2 + - Nested item + - Another nested item +- Item 3 + +### Ordered List +1. First item +2. Second item +3. Third item + +## Blockquote + +> This is a blockquote for testing purposes. +> It should be properly formatted in the PDF output. + +## Conclusion + +This markdown file contains various elements to test the conversion functionality. The PDF output should preserve formatting, tables, code blocks, and other markdown elements. \ No newline at end of file diff --git a/frontend/src/tests/test-fixtures/sample.pdf b/frontend/src/tests/test-fixtures/sample.pdf new file mode 100644 index 000000000..a7fb3ba0b Binary files /dev/null and b/frontend/src/tests/test-fixtures/sample.pdf differ diff --git a/frontend/src/tests/test-fixtures/sample.png b/frontend/src/tests/test-fixtures/sample.png new file mode 100644 index 000000000..b6993935a Binary files /dev/null and b/frontend/src/tests/test-fixtures/sample.png differ diff --git a/frontend/src/tests/test-fixtures/sample.pptx b/frontend/src/tests/test-fixtures/sample.pptx new file mode 100644 index 000000000..2067ee215 --- /dev/null +++ b/frontend/src/tests/test-fixtures/sample.pptx @@ -0,0 +1,12 @@ +# Test PPTX Presentation + +## Slide 1: Title +This is a test PowerPoint presentation for conversion testing. + +## Slide 2: Content +- Test bullet point 1 +- Test bullet point 2 +- Test bullet point 3 + +## Slide 3: Conclusion +This file should be sufficient for testing presentation conversions. \ No newline at end of file diff --git a/frontend/src/tests/test-fixtures/sample.svg b/frontend/src/tests/test-fixtures/sample.svg new file mode 100644 index 000000000..c2056280a --- /dev/null +++ b/frontend/src/tests/test-fixtures/sample.svg @@ -0,0 +1,32 @@ + + + + + + + Test Image for Convert Tool + + + + + + + + + Circle + Square + Triangle + + + + This image tests conversion functionality + + + PNG/JPG ↔ PDF conversions + + + + + Generated for Stirling PDF testing - 400x300px + + \ No newline at end of file diff --git a/frontend/src/tests/test-fixtures/sample.txt b/frontend/src/tests/test-fixtures/sample.txt new file mode 100644 index 000000000..903e18f09 --- /dev/null +++ b/frontend/src/tests/test-fixtures/sample.txt @@ -0,0 +1,8 @@ +This is a test text file for conversion testing. + +It contains multiple lines of text to test various conversion scenarios. +Special characters: àÔâãäÄæçèéêëìíîïðñòóÓõö÷øùúûüýþÿ +Numbers: 1234567890 +Symbols: !@#$%^&*()_+-=[]{}|;':\",./<>? + +This file should be sufficient for testing text-based conversions. \ No newline at end of file diff --git a/frontend/src/tests/test-fixtures/sample.xlsx b/frontend/src/tests/test-fixtures/sample.xlsx new file mode 100644 index 000000000..7eb45724b --- /dev/null +++ b/frontend/src/tests/test-fixtures/sample.xlsx @@ -0,0 +1,6 @@ +Name,Age,City,Country,Department,Salary +John Doe,30,New York,USA,Engineering,75000 +Jane Smith,25,London,UK,Marketing,65000 +Bob Johnson,35,Toronto,Canada,Sales,70000 +Alice Brown,28,Sydney,Australia,Design,68000 +Charlie Wilson,42,Berlin,Germany,Operations,72000 \ No newline at end of file diff --git a/frontend/src/tests/test-fixtures/sample.xml b/frontend/src/tests/test-fixtures/sample.xml new file mode 100644 index 000000000..f39b92f6f --- /dev/null +++ b/frontend/src/tests/test-fixtures/sample.xml @@ -0,0 +1,18 @@ + + + Test Document + +
+ Introduction + This is a test XML document for conversion testing. +
+
+ Data + + + + + +
+
+
\ No newline at end of file diff --git a/frontend/src/theme/mantineTheme.ts b/frontend/src/theme/mantineTheme.ts new file mode 100644 index 000000000..cc263f126 --- /dev/null +++ b/frontend/src/theme/mantineTheme.ts @@ -0,0 +1,314 @@ +import { createTheme, MantineColorsTuple } from '@mantine/core'; + +// Define color tuples using CSS variables +const primary: MantineColorsTuple = [ + 'var(--color-primary-50)', + 'var(--color-primary-100)', + 'var(--color-primary-200)', + 'var(--color-primary-300)', + 'var(--color-primary-400)', + 'var(--color-primary-500)', + 'var(--color-primary-600)', + 'var(--color-primary-700)', + 'var(--color-primary-800)', + 'var(--color-primary-900)', +]; + +const gray: MantineColorsTuple = [ + 'var(--color-gray-50)', + 'var(--color-gray-100)', + 'var(--color-gray-200)', + 'var(--color-gray-300)', + 'var(--color-gray-400)', + 'var(--color-gray-500)', + 'var(--color-gray-600)', + 'var(--color-gray-700)', + 'var(--color-gray-800)', + 'var(--color-gray-900)', +]; + +export const mantineTheme = createTheme({ + // Primary color + primaryColor: 'primary', + + // Color palette + colors: { + primary, + gray, + }, + + // Spacing system - uses CSS variables + spacing: { + xs: 'var(--space-xs)', + sm: 'var(--space-sm)', + md: 'var(--space-md)', + lg: 'var(--space-lg)', + xl: 'var(--space-xl)', + }, + + // Border radius system + radius: { + xs: 'var(--radius-xs)', + sm: 'var(--radius-sm)', + md: 'var(--radius-md)', + lg: 'var(--radius-lg)', + xl: 'var(--radius-xl)', + }, + + // Shadow system + shadows: { + xs: 'var(--shadow-xs)', + sm: 'var(--shadow-sm)', + md: 'var(--shadow-md)', + lg: 'var(--shadow-lg)', + xl: 'var(--shadow-xl)', + }, + + // Font weights + fontWeights: { + normal: 'var(--font-weight-normal)', + medium: 'var(--font-weight-medium)', + semibold: 'var(--font-weight-semibold)', + bold: 'var(--font-weight-bold)', + }, + + // Component customizations + components: { + Button: { + styles: { + root: { + fontWeight: 'var(--font-weight-medium)', + transition: 'all 0.2s ease', + }, + }, + variants: { + // Custom button variant for PDF tools + pdfTool: (theme) => ({ + root: { + backgroundColor: 'var(--bg-surface)', + border: '1px solid var(--border-default)', + color: 'var(--text-primary)', + '&:hover': { + backgroundColor: 'var(--hover-bg)', + borderColor: 'var(--color-primary-500)', + }, + }, + }), + }, + }, + + Paper: { + styles: { + root: { + backgroundColor: 'var(--bg-surface)', + border: '1px solid var(--border-subtle)', + }, + }, + }, + + Card: { + styles: { + root: { + backgroundColor: 'var(--bg-surface)', + border: '1px solid var(--border-subtle)', + boxShadow: 'var(--shadow-sm)', + }, + }, + }, + + TextInput: { + styles: { + input: { + backgroundColor: 'var(--bg-surface)', + borderColor: 'var(--border-default)', + color: 'var(--text-primary)', + '&:focus': { + borderColor: 'var(--color-primary-500)', + boxShadow: '0 0 0 1px var(--color-primary-500)', + }, + }, + label: { + color: 'var(--text-secondary)', + fontWeight: 'var(--font-weight-medium)', + }, + }, + }, + + Select: { + styles: { + input: { + backgroundColor: 'var(--bg-surface)', + borderColor: 'var(--border-default)', + color: 'var(--text-primary)', + '&:focus': { + borderColor: 'var(--color-primary-500)', + boxShadow: '0 0 0 1px var(--color-primary-500)', + }, + }, + label: { + color: 'var(--text-secondary)', + fontWeight: 'var(--font-weight-medium)', + }, + dropdown: { + backgroundColor: 'var(--bg-surface)', + borderColor: 'var(--border-subtle)', + boxShadow: 'var(--shadow-lg)', + }, + option: { + color: 'var(--text-primary)', + '&[data-hovered]': { + backgroundColor: 'var(--hover-bg)', + }, + '&[data-selected]': { + backgroundColor: 'var(--color-primary-100)', + color: 'var(--color-primary-900)', + }, + }, + }, + }, + + MultiSelect: { + styles: { + input: { + backgroundColor: 'var(--bg-surface)', + borderColor: 'var(--border-default)', + color: 'var(--text-primary)', + '&:focus': { + borderColor: 'var(--color-primary-500)', + boxShadow: '0 0 0 1px var(--color-primary-500)', + }, + }, + label: { + color: 'var(--text-secondary)', + fontWeight: 'var(--font-weight-medium)', + }, + dropdown: { + backgroundColor: 'var(--bg-surface)', + borderColor: 'var(--border-subtle)', + boxShadow: 'var(--shadow-lg)', + }, + option: { + color: 'var(--text-primary)', + '&[data-hovered]': { + backgroundColor: 'var(--hover-bg)', + }, + '&[data-selected]': { + backgroundColor: 'var(--color-primary-100)', + color: 'var(--color-primary-900)', + }, + }, + }, + }, + + Checkbox: { + styles: { + input: { + borderColor: 'var(--border-default)', + '&:checked': { + backgroundColor: 'var(--color-primary-500)', + borderColor: 'var(--color-primary-500)', + }, + }, + label: { + color: 'var(--text-primary)', + }, + }, + }, + + Slider: { + styles: { + track: { + backgroundColor: 'var(--bg-muted)', + }, + bar: { + backgroundColor: 'var(--color-primary-500)', + }, + thumb: { + backgroundColor: 'var(--color-primary-500)', + borderColor: 'var(--color-primary-500)', + }, + mark: { + borderColor: 'var(--border-default)', + }, + markLabel: { + color: 'var(--text-muted)', + }, + }, + }, + + Modal: { + styles: { + content: { + backgroundColor: 'var(--bg-surface)', + border: '1px solid var(--border-subtle)', + boxShadow: 'var(--shadow-xl)', + }, + header: { + backgroundColor: 'var(--bg-surface)', + borderBottom: '1px solid var(--border-subtle)', + }, + title: { + color: 'var(--text-primary)', + fontWeight: 'var(--font-weight-semibold)', + }, + }, + }, + + Notification: { + styles: { + root: { + backgroundColor: 'var(--bg-surface)', + border: '1px solid var(--border-subtle)', + boxShadow: 'var(--shadow-lg)', + }, + title: { + color: 'var(--text-primary)', + }, + description: { + color: 'var(--text-secondary)', + }, + }, + }, + + SegmentedControl: { + styles: { + root: { + backgroundColor: 'var(--bg-muted)', + border: '1px solid var(--border-subtle)', + }, + control: { + color: 'var(--text-secondary)', + '[dataActive]': { + backgroundColor: 'var(--bg-surface)', + color: 'var(--text-primary)', + boxShadow: 'var(--shadow-sm)', + }, + }, + }, + }, + }, + + // Global styles + globalStyles: () => ({ + // Ensure smooth color transitions + '*': { + transition: 'background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease', + }, + + // Custom scrollbar styling + '*::-webkit-scrollbar': { + width: '8px', + height: '8px', + }, + '*::-webkit-scrollbar-track': { + backgroundColor: 'var(--bg-muted)', + }, + '*::-webkit-scrollbar-thumb': { + backgroundColor: 'var(--border-strong)', + borderRadius: 'var(--radius-md)', + }, + '*::-webkit-scrollbar-thumb:hover': { + backgroundColor: 'var(--color-primary-500)', + }, + }), +}); diff --git a/frontend/src/tools/Compress.tsx b/frontend/src/tools/Compress.tsx new file mode 100644 index 000000000..f4b50b264 --- /dev/null +++ b/frontend/src/tools/Compress.tsx @@ -0,0 +1,171 @@ +import React, { useEffect, useMemo } from "react"; +import { Button, Stack, Text } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import DownloadIcon from "@mui/icons-material/Download"; +import { useEndpointEnabled } from "../hooks/useEndpointConfig"; +import { useFileContext } from "../contexts/FileContext"; +import { useToolFileSelection } from "../contexts/FileSelectionContext"; + +import ToolStep, { ToolStepContainer } from "../components/tools/shared/ToolStep"; +import OperationButton from "../components/tools/shared/OperationButton"; +import ErrorNotification from "../components/tools/shared/ErrorNotification"; +import FileStatusIndicator from "../components/tools/shared/FileStatusIndicator"; +import ResultsPreview from "../components/tools/shared/ResultsPreview"; + +import CompressSettings from "../components/tools/compress/CompressSettings"; + +import { useCompressParameters } from "../hooks/tools/compress/useCompressParameters"; +import { useCompressOperation } from "../hooks/tools/compress/useCompressOperation"; +import { BaseToolProps } from "../types/tool"; +import { CompressTips } from "../components/tooltips/CompressTips"; + +const Compress = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => { + const { t } = useTranslation(); + const { setCurrentMode } = useFileContext(); + const { selectedFiles } = useToolFileSelection(); + + const compressParams = useCompressParameters(); + const compressOperation = useCompressOperation(); + const compressTips = CompressTips(); + + // Endpoint validation + const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled("compress-pdf"); + + useEffect(() => { + compressOperation.resetResults(); + onPreviewFile?.(null); + }, [compressParams.parameters, selectedFiles]); + + const handleCompress = async () => { + try { + await compressOperation.executeOperation( + compressParams.parameters, + selectedFiles + ); + if (compressOperation.files && onComplete) { + onComplete(compressOperation.files); + } + } catch (error) { + if (onError) { + onError(error instanceof Error ? error.message : 'Compress operation failed'); + } + } + }; + + const handleThumbnailClick = (file: File) => { + onPreviewFile?.(file); + sessionStorage.setItem('previousMode', 'compress'); + setCurrentMode('viewer'); + }; + + const handleSettingsReset = () => { + compressOperation.resetResults(); + onPreviewFile?.(null); + setCurrentMode('compress'); + }; + + const hasFiles = selectedFiles.length > 0; + const hasResults = compressOperation.files.length > 0 || compressOperation.downloadUrl !== null; + const filesCollapsed = hasFiles; + const settingsCollapsed = hasResults; + + const previewResults = useMemo(() => + compressOperation.files?.map((file, index) => ({ + file, + thumbnail: compressOperation.thumbnails[index] + })) || [], + [compressOperation.files, compressOperation.thumbnails] + ); + + return ( + + + {/* Files Step */} + + + + + {/* Settings Step */} + + + + + + + + + {/* Results Step */} + + + {compressOperation.status && ( + {compressOperation.status} + )} + + + + {compressOperation.downloadUrl && ( + + )} + + + + + + + ); +} + + +export default Compress; diff --git a/frontend/src/tools/Convert.tsx b/frontend/src/tools/Convert.tsx new file mode 100644 index 000000000..3512ca8eb --- /dev/null +++ b/frontend/src/tools/Convert.tsx @@ -0,0 +1,207 @@ +import React, { useEffect, useMemo, useRef } from "react"; +import { Button, Stack, Text } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import DownloadIcon from "@mui/icons-material/Download"; +import { useEndpointEnabled } from "../hooks/useEndpointConfig"; +import { useFileContext } from "../contexts/FileContext"; +import { useToolFileSelection } from "../contexts/FileSelectionContext"; + +import ToolStep, { ToolStepContainer } from "../components/tools/shared/ToolStep"; +import OperationButton from "../components/tools/shared/OperationButton"; +import ErrorNotification from "../components/tools/shared/ErrorNotification"; +import FileStatusIndicator from "../components/tools/shared/FileStatusIndicator"; +import ResultsPreview from "../components/tools/shared/ResultsPreview"; + +import ConvertSettings from "../components/tools/convert/ConvertSettings"; + +import { useConvertParameters } from "../hooks/tools/convert/useConvertParameters"; +import { useConvertOperation } from "../hooks/tools/convert/useConvertOperation"; +import { BaseToolProps } from "../types/tool"; + +const Convert = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => { + const { t } = useTranslation(); + const { setCurrentMode, activeFiles } = useFileContext(); + const { selectedFiles } = useToolFileSelection(); + const scrollContainerRef = useRef(null); + + const convertParams = useConvertParameters(); + const convertOperation = useConvertOperation(); + + const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled( + convertParams.getEndpointName() + ); + + const scrollToBottom = () => { + if (scrollContainerRef.current) { + scrollContainerRef.current.scrollTo({ + top: scrollContainerRef.current.scrollHeight, + behavior: 'smooth' + }); + } + }; + + const hasFiles = selectedFiles.length > 0; + const hasResults = convertOperation.downloadUrl !== null; + const filesCollapsed = hasFiles; + const settingsCollapsed = hasResults; + + useEffect(() => { + if (selectedFiles.length > 0) { + convertParams.analyzeFileTypes(selectedFiles); + } else { + // Only reset when there are no active files at all + // If there are active files but no selected files, keep current format (user filtered by format) + if (activeFiles.length === 0) { + convertParams.resetParameters(); + } + } + }, [selectedFiles, activeFiles]); + + useEffect(() => { + // Only clear results if we're not currently processing and parameters changed + if (!convertOperation.isLoading) { + convertOperation.resetResults(); + onPreviewFile?.(null); + } + }, [convertParams.parameters.fromExtension, convertParams.parameters.toExtension]); + + useEffect(() => { + if (hasFiles) { + setTimeout(scrollToBottom, 100); + } + }, [hasFiles]); + + useEffect(() => { + if (hasResults) { + setTimeout(scrollToBottom, 100); + } + }, [hasResults]); + + const handleConvert = async () => { + try { + await convertOperation.executeOperation( + convertParams.parameters, + selectedFiles + ); + if (convertOperation.files && onComplete) { + onComplete(convertOperation.files); + } + } catch (error) { + if (onError) { + onError(error instanceof Error ? error.message : 'Convert operation failed'); + } + } + }; + + const handleThumbnailClick = (file: File) => { + onPreviewFile?.(file); + sessionStorage.setItem('previousMode', 'convert'); + setCurrentMode('viewer'); + }; + + const handleSettingsReset = () => { + convertOperation.resetResults(); + onPreviewFile?.(null); + setCurrentMode('convert'); + }; + + const previewResults = useMemo(() => + convertOperation.files?.map((file, index) => ({ + file, + thumbnail: convertOperation.thumbnails[index] + })) || [], + [convertOperation.files, convertOperation.thumbnails] + ); + + return ( +
+ + + + + + + + + + + {hasFiles && convertParams.parameters.fromExtension && convertParams.parameters.toExtension && ( + + )} + + + + + + {convertOperation.status && ( + {convertOperation.status} + )} + + + + {convertOperation.downloadUrl && ( + + )} + + + + + + +
+ ); +}; + +export default Convert; diff --git a/frontend/src/tools/Merge.tsx b/frontend/src/tools/Merge.tsx new file mode 100644 index 000000000..582a3d6ec --- /dev/null +++ b/frontend/src/tools/Merge.tsx @@ -0,0 +1,167 @@ +import React, { useState, useEffect } from "react"; +import { Paper, Button, Checkbox, Stack, Text, Group, Loader, Alert } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import { FileWithUrl } from "../types/file"; +import { fileStorage } from "../services/fileStorage"; +import { useEndpointEnabled } from "../hooks/useEndpointConfig"; + +export interface MergePdfPanelProps { + files: FileWithUrl[]; + setDownloadUrl: (url: string) => void; + params: { + order: string; + removeDuplicates: boolean; + }; + updateParams: (newParams: Partial) => void; +} + +const MergePdfPanel: React.FC = ({ + files, + setDownloadUrl, + params, + updateParams, +}) => { + const { t } = useTranslation(); + const [selectedFiles, setSelectedFiles] = useState([]); + const [downloadUrl, setLocalDownloadUrl] = useState(null); + const [isLoading, setIsLoading] = useState(false); + const [errorMessage, setErrorMessage] = useState(null); + const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled("merge-pdfs"); + + useEffect(() => { + setSelectedFiles(files.map(() => true)); + }, [files]); + + const handleMerge = async () => { + const filesToMerge = files.filter((_, index) => selectedFiles[index]); + if (filesToMerge.length < 2) { + setErrorMessage(t("multiPdfPrompt")); // "Select PDFs (2+)" + return; + } + + const formData = new FormData(); + + // Handle IndexedDB files + for (const file of filesToMerge) { + if (!file.id) { + continue; // Skip files without an id + } + const storedFile = await fileStorage.getFile(file?.id); + if (storedFile) { + const blob = new Blob([storedFile.data], { type: storedFile.type }); + const actualFile = new File([blob], storedFile.name, { + type: storedFile.type, + lastModified: storedFile.lastModified + }); + formData.append("fileInput", actualFile); + } + } + + setIsLoading(true); + setErrorMessage(null); + + try { + const response = await fetch("/api/v1/general/merge-pdfs", { + method: "POST", + body: formData, + }); + + if (!response.ok) { + const errorText = await response.text(); + throw new Error(`Failed to merge PDFs: ${errorText}`); + } + + const blob = await response.blob(); + const url = URL.createObjectURL(blob); + setDownloadUrl(url); + setLocalDownloadUrl(url); + } catch (error: any) { + setErrorMessage(error.message || "Unknown error occurred."); + } finally { + setIsLoading(false); + } + }; + + const handleCheckboxChange = (index: number) => { + setSelectedFiles((prev) => + prev.map((selected, i) => (i === index ? !selected : selected)) + ); + }; + + const selectedCount = selectedFiles.filter(Boolean).length; + + const { order, removeDuplicates } = params; + + if (endpointLoading) { + return ( + + + {t("loading", "Loading...")} + + ); + } + + if (endpointEnabled === false) { + return ( + + + {t("endpointDisabled", "This feature is currently disabled.")} + + + ); + } + + return ( + + {t("merge.header")} + + {files.map((file, index) => ( + + handleCheckboxChange(index)} + /> + {file.name} + + ))} + + {selectedCount < 2 && ( + + {t("multiPdfPrompt")} + + )} + + {errorMessage && ( + + {errorMessage} + + )} + {downloadUrl && ( + + )} + updateParams({ removeDuplicates: !removeDuplicates })} + /> + + ); +}; + +export default MergePdfPanel; diff --git a/frontend/src/tools/OCR.tsx b/frontend/src/tools/OCR.tsx new file mode 100644 index 000000000..89da5be87 --- /dev/null +++ b/frontend/src/tools/OCR.tsx @@ -0,0 +1,218 @@ +import React, { useEffect, useMemo, useState } from "react"; +import { Button, Stack, Text, Box } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import DownloadIcon from "@mui/icons-material/Download"; +import { useEndpointEnabled } from "../hooks/useEndpointConfig"; +import { useFileContext } from "../contexts/FileContext"; +import { useToolFileSelection } from "../contexts/FileSelectionContext"; + +import ToolStep, { ToolStepContainer } from "../components/tools/shared/ToolStep"; +import OperationButton from "../components/tools/shared/OperationButton"; +import ErrorNotification from "../components/tools/shared/ErrorNotification"; +import FileStatusIndicator from "../components/tools/shared/FileStatusIndicator"; +import ResultsPreview from "../components/tools/shared/ResultsPreview"; + +import OCRSettings from "../components/tools/ocr/OCRSettings"; +import AdvancedOCRSettings from "../components/tools/ocr/AdvancedOCRSettings"; + +import { useOCRParameters } from "../hooks/tools/ocr/useOCRParameters"; +import { useOCROperation } from "../hooks/tools/ocr/useOCROperation"; +import { BaseToolProps } from "../types/tool"; +import { OcrTips } from "../components/tooltips/OCRTips"; + +const OCR = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => { + const { t } = useTranslation(); + const { setCurrentMode } = useFileContext(); + const { selectedFiles } = useToolFileSelection(); + + const ocrParams = useOCRParameters(); + const ocrOperation = useOCROperation(); + const ocrTips = OcrTips(); + + // Step expansion state management + const [expandedStep, setExpandedStep] = useState<'files' | 'settings' | 'advanced' | null>('files'); + + const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled("ocr-pdf"); + + const hasFiles = selectedFiles.length > 0; + const hasResults = ocrOperation.files.length > 0 || ocrOperation.downloadUrl !== null; + const hasValidSettings = ocrParams.validateParameters(); + + useEffect(() => { + ocrOperation.resetResults(); + onPreviewFile?.(null); + }, [ocrParams.parameters, selectedFiles]); + + useEffect(() => { + if (selectedFiles.length > 0 && expandedStep === 'files') { + setExpandedStep('settings'); + } + }, [selectedFiles.length, expandedStep]); + + // Collapse all steps when results appear + useEffect(() => { + if (hasResults) { + setExpandedStep(null); + } + }, [hasResults]); + + const handleOCR = async () => { + try { + await ocrOperation.executeOperation( + ocrParams.parameters, + selectedFiles + ); + if (ocrOperation.files && onComplete) { + onComplete(ocrOperation.files); + } + } catch (error) { + if (onError) { + onError(error instanceof Error ? error.message : 'OCR operation failed'); + } + } + }; + + const handleThumbnailClick = (file: File) => { + onPreviewFile?.(file); + sessionStorage.setItem('previousMode', 'ocr'); + setCurrentMode('viewer'); + }; + + + // Step visibility and collapse logic + const filesVisible = true; + const settingsVisible = true; + const resultsVisible = hasResults; + + const filesCollapsed = expandedStep !== 'files'; + const settingsCollapsed = expandedStep !== 'settings'; + + const previewResults = useMemo(() => + ocrOperation.files?.map((file: File, index: number) => ({ + file, + thumbnail: ocrOperation.thumbnails[index] + })) || [], + [ocrOperation.files, ocrOperation.thumbnails] + ); + + return ( + + + {/* Files Step */} + + + + + {/* Settings Step */} + { + if (!hasFiles) return; // Only allow if files are selected + setExpandedStep(expandedStep === 'settings' ? null : 'settings'); + }} + completedMessage={hasFiles && hasValidSettings && settingsCollapsed ? "Basic settings configured" : undefined} + tooltip={ocrTips} + > + + + + + + + {/* Advanced Step */} + { + if (!hasFiles) return; // Only allow if files are selected + setExpandedStep(expandedStep === 'advanced' ? null : 'advanced'); + }} + completedMessage={hasFiles && hasResults && expandedStep !== 'advanced' ? "OCR processing completed" : undefined} + > + + + + {/* Process Button - Available after all configuration */} + {hasValidSettings && !hasResults && ( + + + + )} + + {/* Results Step */} + + + {ocrOperation.status && ( + {ocrOperation.status} + )} + + + + {ocrOperation.downloadUrl && ( + + )} + + + + + + + ); +} + +export default OCR; \ No newline at end of file diff --git a/frontend/src/tools/Split.tsx b/frontend/src/tools/Split.tsx new file mode 100644 index 000000000..bc516c754 --- /dev/null +++ b/frontend/src/tools/Split.tsx @@ -0,0 +1,166 @@ +import React, { useEffect, useMemo } from "react"; +import { Button, Stack, Text } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import DownloadIcon from "@mui/icons-material/Download"; +import { useEndpointEnabled } from "../hooks/useEndpointConfig"; +import { useFileContext } from "../contexts/FileContext"; +import { useToolFileSelection } from "../contexts/FileSelectionContext"; + +import ToolStep, { ToolStepContainer } from "../components/tools/shared/ToolStep"; +import OperationButton from "../components/tools/shared/OperationButton"; +import ErrorNotification from "../components/tools/shared/ErrorNotification"; +import FileStatusIndicator from "../components/tools/shared/FileStatusIndicator"; +import ResultsPreview from "../components/tools/shared/ResultsPreview"; +import SplitSettings from "../components/tools/split/SplitSettings"; + +import { useSplitParameters } from "../hooks/tools/split/useSplitParameters"; +import { useSplitOperation } from "../hooks/tools/split/useSplitOperation"; +import { BaseToolProps } from "../types/tool"; + +const Split = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => { + const { t } = useTranslation(); + const { setCurrentMode } = useFileContext(); + const { selectedFiles } = useToolFileSelection(); + + const splitParams = useSplitParameters(); + const splitOperation = useSplitOperation(); + + // Endpoint validation + const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled( + splitParams.getEndpointName() + ); + + useEffect(() => { + splitOperation.resetResults(); + onPreviewFile?.(null); + }, [splitParams.parameters, selectedFiles]); + + const handleSplit = async () => { + try { + await splitOperation.executeOperation( + splitParams.parameters, + selectedFiles + ); + if (splitOperation.files && onComplete) { + onComplete(splitOperation.files); + } + } catch (error) { + if (onError) { + onError(error instanceof Error ? error.message : 'Split operation failed'); + } + } + }; + + const handleThumbnailClick = (file: File) => { + onPreviewFile?.(file); + sessionStorage.setItem('previousMode', 'split'); + setCurrentMode('viewer'); + }; + + const handleSettingsReset = () => { + splitOperation.resetResults(); + onPreviewFile?.(null); + setCurrentMode('split'); + }; + + const hasFiles = selectedFiles.length > 0; + const hasResults = splitOperation.downloadUrl !== null; + const filesCollapsed = hasFiles; + const settingsCollapsed = hasResults; + + const previewResults = useMemo(() => + splitOperation.files?.map((file, index) => ({ + file, + thumbnail: splitOperation.thumbnails[index] + })) || [], + [splitOperation.files, splitOperation.thumbnails] + ); + + return ( + + + {/* Files Step */} + + + + + {/* Settings Step */} + + + + + {splitParams.parameters.mode && ( + + )} + + + + {/* Results Step */} + + + {splitOperation.status && ( + {splitOperation.status} + )} + + + + {splitOperation.downloadUrl && ( + + )} + + + + + + + ); +} + +export default Split; diff --git a/frontend/src/tools/SwaggerUI.tsx b/frontend/src/tools/SwaggerUI.tsx new file mode 100644 index 000000000..0712b6068 --- /dev/null +++ b/frontend/src/tools/SwaggerUI.tsx @@ -0,0 +1,18 @@ +import React, { useEffect } from 'react'; +import { BaseToolProps } from '../types/tool'; + +const SwaggerUI: React.FC = () => { + useEffect(() => { + // Redirect to Swagger UI + window.open('/swagger-ui/5.21.0/index.html', '_blank'); + }, []); + + return ( +
+

Opening Swagger UI in a new tab...

+

If it didn't open automatically, click here

+
+ ); +}; + +export default SwaggerUI; \ No newline at end of file diff --git a/frontend/src/types/file.ts b/frontend/src/types/file.ts new file mode 100644 index 000000000..c887c093b --- /dev/null +++ b/frontend/src/types/file.ts @@ -0,0 +1,50 @@ +/** + * Enhanced file types for IndexedDB storage + */ + +export interface FileWithUrl extends File { + id?: string; + url?: string; + thumbnail?: string; + storedInIndexedDB?: boolean; +} + +export interface StorageConfig { + useIndexedDB: boolean; + maxFileSize: number; // Maximum size per file in bytes + maxTotalStorage: number; // Maximum total storage in bytes + warningThreshold: number; // Warning threshold (percentage 0-1) +} + +export const defaultStorageConfig: StorageConfig = { + useIndexedDB: true, + maxFileSize: 100 * 1024 * 1024, // 100MB per file + maxTotalStorage: 1024 * 1024 * 1024, // 1GB default, will be updated dynamically + warningThreshold: 0.8, // Warn at 80% capacity +}; + +// Calculate and update storage limit: half of available storage or 10GB, whichever is smaller +export const initializeStorageConfig = async (): Promise => { + const tenGB = 10 * 1024 * 1024 * 1024; // 10GB in bytes + const oneGB = 1024 * 1024 * 1024; // 1GB fallback + + let maxTotalStorage = oneGB; // Default fallback + + // Try to estimate available storage + if ('storage' in navigator && 'estimate' in navigator.storage) { + try { + const estimate = await navigator.storage.estimate(); + if (estimate.quota) { + const halfQuota = estimate.quota / 2; + maxTotalStorage = Math.min(halfQuota, tenGB); + } + } catch (error) { + console.warn('Could not estimate storage quota, using 1GB default:', error); + } + } + + return { + ...defaultStorageConfig, + maxTotalStorage + }; +}; \ No newline at end of file diff --git a/frontend/src/types/fileContext.ts b/frontend/src/types/fileContext.ts new file mode 100644 index 000000000..d9c049ae7 --- /dev/null +++ b/frontend/src/types/fileContext.ts @@ -0,0 +1,166 @@ +/** + * Types for global file context management across views and tools + */ + +import { ProcessedFile } from './processing'; +import { PDFDocument, PDFPage, PageOperation } from './pageEditor'; + +export type ModeType = 'viewer' | 'pageEditor' | 'fileEditor' | 'merge' | 'split' | 'compress' | 'ocr'; + +export type OperationType = 'merge' | 'split' | 'compress' | 'add' | 'remove' | 'replace' | 'convert' | 'upload' | 'ocr'; + +export interface FileOperation { + id: string; + type: OperationType; + timestamp: number; + fileIds: string[]; + status: 'pending' | 'applied' | 'failed'; + data?: any; + metadata?: { + originalFileName?: string; + outputFileNames?: string[]; + parameters?: Record; + fileSize?: number; + pageCount?: number; + error?: string; + }; +} + +export interface FileOperationHistory { + fileId: string; + fileName: string; + operations: (FileOperation | PageOperation)[]; + createdAt: number; + lastModified: number; +} + +export interface ViewerConfig { + zoom: number; + currentPage: number; + viewMode: 'single' | 'continuous' | 'facing'; + sidebarOpen: boolean; +} + +export interface FileEditHistory { + fileId: string; + pageOperations: PageOperation[]; + lastModified: number; +} + +export interface FileContextState { + // Core file management + activeFiles: File[]; + processedFiles: Map; + + // Current navigation state + currentMode: ModeType; + + // Edit history and state + fileEditHistory: Map; + globalFileOperations: FileOperation[]; + // New comprehensive operation history + fileOperationHistory: Map; + + // UI state that persists across views + selectedFileIds: string[]; + selectedPageNumbers: number[]; + viewerConfig: ViewerConfig; + + // Processing state + isProcessing: boolean; + processingProgress: number; + + // Export state + lastExportConfig?: { + filename: string; + selectedOnly: boolean; + splitDocuments: boolean; + }; + + // Navigation guard system + hasUnsavedChanges: boolean; + pendingNavigation: (() => void) | null; + showNavigationWarning: boolean; +} + +export interface FileContextActions { + // File management + addFiles: (files: File[]) => Promise; + removeFiles: (fileIds: string[], deleteFromStorage?: boolean) => void; + replaceFile: (oldFileId: string, newFile: File) => Promise; + clearAllFiles: () => void; + + // Navigation + setCurrentMode: (mode: ModeType) => void; + // Selection management + setSelectedFiles: (fileIds: string[]) => void; + setSelectedPages: (pageNumbers: number[]) => void; + updateProcessedFile: (file: File, processedFile: ProcessedFile) => void; + clearSelections: () => void; + + // Edit operations + applyPageOperations: (fileId: string, operations: PageOperation[]) => void; + applyFileOperation: (operation: FileOperation) => void; + undoLastOperation: (fileId?: string) => void; + + // Operation history management + recordOperation: (fileId: string, operation: FileOperation | PageOperation) => void; + markOperationApplied: (fileId: string, operationId: string) => void; + markOperationFailed: (fileId: string, operationId: string, error: string) => void; + getFileHistory: (fileId: string) => FileOperationHistory | undefined; + getAppliedOperations: (fileId: string) => (FileOperation | PageOperation)[]; + clearFileHistory: (fileId: string) => void; + + // Viewer state + updateViewerConfig: (config: Partial) => void; + + // Export configuration + setExportConfig: (config: FileContextState['lastExportConfig']) => void; + + + // Utility + getFileById: (fileId: string) => File | undefined; + getProcessedFileById: (fileId: string) => ProcessedFile | undefined; + getCurrentFile: () => File | undefined; + getCurrentProcessedFile: () => ProcessedFile | undefined; + + // Context persistence + saveContext: () => Promise; + loadContext: () => Promise; + resetContext: () => void; + + // Navigation guard system + setHasUnsavedChanges: (hasChanges: boolean) => void; + requestNavigation: (navigationFn: () => void) => boolean; + confirmNavigation: () => void; + cancelNavigation: () => void; + + // Memory management + trackBlobUrl: (url: string) => void; + trackPdfDocument: (fileId: string, pdfDoc: any) => void; + cleanupFile: (fileId: string) => Promise; + scheduleCleanup: (fileId: string, delay?: number) => void; +} + +export interface FileContextValue extends FileContextState, FileContextActions {} + +export interface FileContextProviderProps { + children: React.ReactNode; + enableUrlSync?: boolean; + enablePersistence?: boolean; + maxCacheSize?: number; +} + +// Helper types for component props +export interface WithFileContext { + fileContext: FileContextValue; +} + +// URL parameter types for deep linking +export interface FileContextUrlParams { + mode?: ModeType; + fileIds?: string[]; + pageIds?: string[]; + zoom?: number; + page?: number; +} \ No newline at end of file diff --git a/frontend/src/types/pageEditor.ts b/frontend/src/types/pageEditor.ts new file mode 100644 index 000000000..f5529aee3 --- /dev/null +++ b/frontend/src/types/pageEditor.ts @@ -0,0 +1,54 @@ +export interface PDFPage { + id: string; + pageNumber: number; + thumbnail: string | null; + rotation: number; + selected: boolean; + splitBefore?: boolean; +} + +export interface PDFDocument { + id: string; + name: string; + file: File; + pages: PDFPage[]; + totalPages: number; +} + +export interface PageOperation { + id: string; + type: 'rotate' | 'delete' | 'move' | 'split' | 'insert' | 'reorder'; + pageIds: string[]; + timestamp: number; + status: 'pending' | 'applied' | 'failed'; + data?: any; + metadata?: { + rotation?: number; + fromPosition?: number; + toPosition?: number; + splitType?: string; + insertAfterPage?: number; + error?: string; + }; +} + +export interface UndoRedoState { + operations: PageOperation[]; + currentIndex: number; +} + +export interface PageEditorFunctions { + closePdf: () => void; + handleUndo: () => void; + handleRedo: () => void; + canUndo: boolean; + canRedo: boolean; + handleRotate: () => void; + handleDelete: () => void; + handleSplit: () => void; + onExportSelected: () => void; + onExportAll: () => void; + exportLoading: boolean; + selectionMode: boolean; + selectedPages: number[]; +} diff --git a/frontend/src/types/processing.ts b/frontend/src/types/processing.ts new file mode 100644 index 000000000..ee2f5be17 --- /dev/null +++ b/frontend/src/types/processing.ts @@ -0,0 +1,90 @@ +export interface ProcessingError { + type: 'network' | 'parsing' | 'memory' | 'corruption' | 'timeout' | 'cancelled'; + message: string; + recoverable: boolean; + retryCount: number; + maxRetries: number; + originalError?: Error; +} + +export interface ProcessingState { + fileKey: string; + fileName: string; + status: 'pending' | 'processing' | 'completed' | 'error' | 'cancelled'; + progress: number; // 0-100 + strategy: ProcessingStrategy; + error?: ProcessingError; + startedAt: number; + completedAt?: number; + estimatedTimeRemaining?: number; + currentPage?: number; + cancellationToken?: AbortController; +} + +export interface ProcessedFile { + id: string; + pages: PDFPage[]; + totalPages: number; + metadata: { + title: string; + createdAt: string; + modifiedAt: string; + }; +} + +export interface PDFPage { + id: string; + pageNumber: number; + thumbnail: string | null; + rotation: number; + selected: boolean; + splitBefore?: boolean; +} + +export interface CacheConfig { + maxFiles: number; + maxSizeBytes: number; + ttlMs: number; +} + +export interface CacheEntry { + data: ProcessedFile; + size: number; + lastAccessed: number; + createdAt: number; +} + +export interface CacheStats { + entries: number; + totalSizeBytes: number; + maxSizeBytes: number; +} + +export type ProcessingStrategy = 'immediate_full' | 'progressive_chunked' | 'metadata_only' | 'priority_pages'; + +export interface ProcessingConfig { + strategy: ProcessingStrategy; + chunkSize: number; // Pages per chunk + thumbnailQuality: 'low' | 'medium' | 'high'; + priorityPageCount: number; // Number of priority pages to process first + useWebWorker: boolean; + maxRetries: number; +} + +export interface FileAnalysis { + fileSize: number; + estimatedPageCount?: number; + isEncrypted: boolean; + isCorrupted: boolean; + recommendedStrategy: ProcessingStrategy; + estimatedProcessingTime: number; // milliseconds +} + +export interface ProcessingMetrics { + totalFiles: number; + completedFiles: number; + failedFiles: number; + averageProcessingTime: number; + cacheHitRate: number; + memoryUsage: number; +} \ No newline at end of file diff --git a/frontend/src/types/sidebar.ts b/frontend/src/types/sidebar.ts new file mode 100644 index 000000000..b286f0b82 --- /dev/null +++ b/frontend/src/types/sidebar.ts @@ -0,0 +1,40 @@ +export interface SidebarState { + sidebarsVisible: boolean; + leftPanelView: 'toolPicker' | 'toolContent'; + readerMode: boolean; +} + +export interface SidebarRefs { + quickAccessRef: React.RefObject; + toolPanelRef: React.RefObject; +} + +export interface SidebarInfo { + rect: DOMRect | null; + isToolPanelActive: boolean; + sidebarState: SidebarState; +} + +// Context-related interfaces +export interface SidebarContextValue { + sidebarState: SidebarState; + sidebarRefs: SidebarRefs; + setSidebarsVisible: React.Dispatch>; + setLeftPanelView: React.Dispatch>; + setReaderMode: React.Dispatch>; +} + +export interface SidebarProviderProps { + children: React.ReactNode; +} + +export interface ButtonConfig { + id: string; + name: string; + icon: React.ReactNode; + tooltip: string; + isRound?: boolean; + size?: 'sm' | 'md' | 'lg' | 'xl'; + onClick: () => void; + type?: 'navigation' | 'modal' | 'action'; +} diff --git a/frontend/src/types/tips.ts b/frontend/src/types/tips.ts new file mode 100644 index 000000000..58519e114 --- /dev/null +++ b/frontend/src/types/tips.ts @@ -0,0 +1,13 @@ +export interface TooltipContent { + header?: { + title: string; + logo?: string | React.ReactNode; + }; + tips?: Array<{ + title?: string; + description?: string; + bullets?: string[]; + body?: React.ReactNode; + }>; + content?: React.ReactNode; +} \ No newline at end of file diff --git a/frontend/src/types/tool.ts b/frontend/src/types/tool.ts new file mode 100644 index 000000000..731f0b90e --- /dev/null +++ b/frontend/src/types/tool.ts @@ -0,0 +1,73 @@ +import React from 'react'; + +export type MaxFiles = number; // 1=single, >1=limited, -1=unlimited +export type ToolCategory = 'manipulation' | 'conversion' | 'analysis' | 'utility' | 'optimization' | 'security'; +export type ToolDefinition = Omit; +export type ToolStepType = 'files' | 'settings' | 'results'; + +export interface BaseToolProps { + onComplete?: (results: File[]) => void; + onError?: (error: string) => void; + onPreviewFile?: (file: File | null) => void; +} + +export interface ToolStepConfig { + type: ToolStepType; + title: string; + isVisible: boolean; + isCompleted: boolean; + isCollapsed?: boolean; + completedMessage?: string; + onCollapsedClick?: () => void; +} + +export interface ToolValidationResult { + valid: boolean; + errors?: string[]; + warnings?: string[]; +} + +export interface ToolResult { + success: boolean; + files?: File[]; + error?: string; + downloadUrl?: string; + metadata?: Record; +} + +export interface Tool { + id: string; + name: string; + icon: React.ReactNode; + component: React.ComponentType; + maxFiles: MaxFiles; + category?: ToolCategory; + description?: string; + endpoints?: string[]; + supportedFormats?: string[]; + validation?: (files: File[]) => ToolValidationResult; +} + +export type ToolRegistry = Record; + +export interface FileSelectionState { + selectedFiles: File[]; + maxFiles: MaxFiles; + isToolMode: boolean; +} + +export interface FileSelectionActions { + setSelectedFiles: (files: File[]) => void; + setMaxFiles: (maxFiles: MaxFiles) => void; + setIsToolMode: (isToolMode: boolean) => void; + clearSelection: () => void; +} + +export interface FileSelectionComputed { + canSelectMore: boolean; + isAtLimit: boolean; + selectionCount: number; + isMultiFileMode: boolean; +} + +export interface FileSelectionContextValue extends FileSelectionState, FileSelectionActions, FileSelectionComputed {} \ No newline at end of file diff --git a/frontend/src/utils/convertUtils.test.ts b/frontend/src/utils/convertUtils.test.ts new file mode 100644 index 000000000..4f44f949b --- /dev/null +++ b/frontend/src/utils/convertUtils.test.ts @@ -0,0 +1,334 @@ +/** + * Unit tests for convertUtils + */ + +import { describe, test, expect } from 'vitest'; +import { + getEndpointName, + getEndpointUrl, + isConversionSupported, + isImageFormat +} from './convertUtils'; + +describe('convertUtils', () => { + + describe('getEndpointName', () => { + + test('should return correct endpoint names for all supported conversions', () => { + // PDF to Image formats + expect(getEndpointName('pdf', 'png')).toBe('pdf-to-img'); + expect(getEndpointName('pdf', 'jpg')).toBe('pdf-to-img'); + expect(getEndpointName('pdf', 'gif')).toBe('pdf-to-img'); + expect(getEndpointName('pdf', 'tiff')).toBe('pdf-to-img'); + expect(getEndpointName('pdf', 'bmp')).toBe('pdf-to-img'); + expect(getEndpointName('pdf', 'webp')).toBe('pdf-to-img'); + + // PDF to Office formats + expect(getEndpointName('pdf', 'docx')).toBe('pdf-to-word'); + expect(getEndpointName('pdf', 'odt')).toBe('pdf-to-word'); + expect(getEndpointName('pdf', 'pptx')).toBe('pdf-to-presentation'); + expect(getEndpointName('pdf', 'odp')).toBe('pdf-to-presentation'); + + // PDF to Data formats + expect(getEndpointName('pdf', 'csv')).toBe('pdf-to-csv'); + expect(getEndpointName('pdf', 'txt')).toBe('pdf-to-text'); + expect(getEndpointName('pdf', 'rtf')).toBe('pdf-to-text'); + expect(getEndpointName('pdf', 'md')).toBe('pdf-to-markdown'); + + // PDF to Web formats + expect(getEndpointName('pdf', 'html')).toBe('pdf-to-html'); + expect(getEndpointName('pdf', 'xml')).toBe('pdf-to-xml'); + + // PDF to PDF/A + expect(getEndpointName('pdf', 'pdfa')).toBe('pdf-to-pdfa'); + + // Office Documents to PDF + expect(getEndpointName('docx', 'pdf')).toBe('file-to-pdf'); + expect(getEndpointName('doc', 'pdf')).toBe('file-to-pdf'); + expect(getEndpointName('odt', 'pdf')).toBe('file-to-pdf'); + + // Spreadsheets to PDF + expect(getEndpointName('xlsx', 'pdf')).toBe('file-to-pdf'); + expect(getEndpointName('xls', 'pdf')).toBe('file-to-pdf'); + expect(getEndpointName('ods', 'pdf')).toBe('file-to-pdf'); + + // Presentations to PDF + expect(getEndpointName('pptx', 'pdf')).toBe('file-to-pdf'); + expect(getEndpointName('ppt', 'pdf')).toBe('file-to-pdf'); + expect(getEndpointName('odp', 'pdf')).toBe('file-to-pdf'); + + // Images to PDF + expect(getEndpointName('jpg', 'pdf')).toBe('img-to-pdf'); + expect(getEndpointName('jpeg', 'pdf')).toBe('img-to-pdf'); + expect(getEndpointName('png', 'pdf')).toBe('img-to-pdf'); + expect(getEndpointName('gif', 'pdf')).toBe('img-to-pdf'); + expect(getEndpointName('bmp', 'pdf')).toBe('img-to-pdf'); + expect(getEndpointName('tiff', 'pdf')).toBe('img-to-pdf'); + expect(getEndpointName('webp', 'pdf')).toBe('img-to-pdf'); + + // Web formats to PDF + expect(getEndpointName('html', 'pdf')).toBe('html-to-pdf'); + + // Markdown to PDF + expect(getEndpointName('md', 'pdf')).toBe('markdown-to-pdf'); + + // Text formats to PDF + expect(getEndpointName('txt', 'pdf')).toBe('file-to-pdf'); + expect(getEndpointName('rtf', 'pdf')).toBe('file-to-pdf'); + + // Email to PDF + expect(getEndpointName('eml', 'pdf')).toBe('eml-to-pdf'); + }); + + test('should return empty string for unsupported conversions', () => { + expect(getEndpointName('pdf', 'exe')).toBe(''); + expect(getEndpointName('wav', 'pdf')).toBe('file-to-pdf'); // Try using file to pdf as fallback + expect(getEndpointName('png', 'docx')).toBe(''); // Images can't convert to Word docs + }); + + test('should handle empty or invalid inputs', () => { + expect(getEndpointName('', '')).toBe(''); + expect(getEndpointName('pdf', '')).toBe(''); + expect(getEndpointName('', 'pdf')).toBe(''); + expect(getEndpointName('nonexistent', 'alsononexistent')).toBe(''); + }); + }); + + describe('getEndpointUrl', () => { + + test('should return correct endpoint URLs for all supported conversions', () => { + // PDF to Image formats + expect(getEndpointUrl('pdf', 'png')).toBe('/api/v1/convert/pdf/img'); + expect(getEndpointUrl('pdf', 'jpg')).toBe('/api/v1/convert/pdf/img'); + expect(getEndpointUrl('pdf', 'gif')).toBe('/api/v1/convert/pdf/img'); + expect(getEndpointUrl('pdf', 'tiff')).toBe('/api/v1/convert/pdf/img'); + expect(getEndpointUrl('pdf', 'bmp')).toBe('/api/v1/convert/pdf/img'); + expect(getEndpointUrl('pdf', 'webp')).toBe('/api/v1/convert/pdf/img'); + + // PDF to Office formats + expect(getEndpointUrl('pdf', 'docx')).toBe('/api/v1/convert/pdf/word'); + expect(getEndpointUrl('pdf', 'odt')).toBe('/api/v1/convert/pdf/word'); + expect(getEndpointUrl('pdf', 'pptx')).toBe('/api/v1/convert/pdf/presentation'); + expect(getEndpointUrl('pdf', 'odp')).toBe('/api/v1/convert/pdf/presentation'); + + // PDF to Data formats + expect(getEndpointUrl('pdf', 'csv')).toBe('/api/v1/convert/pdf/csv'); + expect(getEndpointUrl('pdf', 'txt')).toBe('/api/v1/convert/pdf/text'); + expect(getEndpointUrl('pdf', 'rtf')).toBe('/api/v1/convert/pdf/text'); + expect(getEndpointUrl('pdf', 'md')).toBe('/api/v1/convert/pdf/markdown'); + + // PDF to Web formats + expect(getEndpointUrl('pdf', 'html')).toBe('/api/v1/convert/pdf/html'); + expect(getEndpointUrl('pdf', 'xml')).toBe('/api/v1/convert/pdf/xml'); + + // PDF to PDF/A + expect(getEndpointUrl('pdf', 'pdfa')).toBe('/api/v1/convert/pdf/pdfa'); + + // Office Documents to PDF + expect(getEndpointUrl('docx', 'pdf')).toBe('/api/v1/convert/file/pdf'); + expect(getEndpointUrl('doc', 'pdf')).toBe('/api/v1/convert/file/pdf'); + expect(getEndpointUrl('odt', 'pdf')).toBe('/api/v1/convert/file/pdf'); + + // Spreadsheets to PDF + expect(getEndpointUrl('xlsx', 'pdf')).toBe('/api/v1/convert/file/pdf'); + expect(getEndpointUrl('xls', 'pdf')).toBe('/api/v1/convert/file/pdf'); + expect(getEndpointUrl('ods', 'pdf')).toBe('/api/v1/convert/file/pdf'); + + // Presentations to PDF + expect(getEndpointUrl('pptx', 'pdf')).toBe('/api/v1/convert/file/pdf'); + expect(getEndpointUrl('ppt', 'pdf')).toBe('/api/v1/convert/file/pdf'); + expect(getEndpointUrl('odp', 'pdf')).toBe('/api/v1/convert/file/pdf'); + + // Images to PDF + expect(getEndpointUrl('jpg', 'pdf')).toBe('/api/v1/convert/img/pdf'); + expect(getEndpointUrl('jpeg', 'pdf')).toBe('/api/v1/convert/img/pdf'); + expect(getEndpointUrl('png', 'pdf')).toBe('/api/v1/convert/img/pdf'); + expect(getEndpointUrl('gif', 'pdf')).toBe('/api/v1/convert/img/pdf'); + expect(getEndpointUrl('bmp', 'pdf')).toBe('/api/v1/convert/img/pdf'); + expect(getEndpointUrl('tiff', 'pdf')).toBe('/api/v1/convert/img/pdf'); + expect(getEndpointUrl('webp', 'pdf')).toBe('/api/v1/convert/img/pdf'); + + // Web formats to PDF + expect(getEndpointUrl('html', 'pdf')).toBe('/api/v1/convert/html/pdf'); + + // Markdown to PDF + expect(getEndpointUrl('md', 'pdf')).toBe('/api/v1/convert/markdown/pdf'); + + // Text formats to PDF + expect(getEndpointUrl('txt', 'pdf')).toBe('/api/v1/convert/file/pdf'); + expect(getEndpointUrl('rtf', 'pdf')).toBe('/api/v1/convert/file/pdf'); + + // Email to PDF + expect(getEndpointUrl('eml', 'pdf')).toBe('/api/v1/convert/eml/pdf'); + }); + + test('should return empty string for unsupported conversions', () => { + expect(getEndpointUrl('pdf', 'exe')).toBe(''); + expect(getEndpointUrl('wav', 'pdf')).toBe('/api/v1/convert/file/pdf'); // Try using file to pdf as fallback + expect(getEndpointUrl('invalid', 'invalid')).toBe(''); + }); + + test('should handle empty inputs', () => { + expect(getEndpointUrl('', '')).toBe(''); + expect(getEndpointUrl('pdf', '')).toBe(''); + expect(getEndpointUrl('', 'pdf')).toBe(''); + }); + }); + + describe('isConversionSupported', () => { + + test('should return true for all supported conversions', () => { + // PDF to Image formats + expect(isConversionSupported('pdf', 'png')).toBe(true); + expect(isConversionSupported('pdf', 'jpg')).toBe(true); + expect(isConversionSupported('pdf', 'gif')).toBe(true); + expect(isConversionSupported('pdf', 'tiff')).toBe(true); + expect(isConversionSupported('pdf', 'bmp')).toBe(true); + expect(isConversionSupported('pdf', 'webp')).toBe(true); + + // PDF to Office formats + expect(isConversionSupported('pdf', 'docx')).toBe(true); + expect(isConversionSupported('pdf', 'odt')).toBe(true); + expect(isConversionSupported('pdf', 'pptx')).toBe(true); + expect(isConversionSupported('pdf', 'odp')).toBe(true); + + // PDF to Data formats + expect(isConversionSupported('pdf', 'csv')).toBe(true); + expect(isConversionSupported('pdf', 'txt')).toBe(true); + expect(isConversionSupported('pdf', 'rtf')).toBe(true); + expect(isConversionSupported('pdf', 'md')).toBe(true); + + // PDF to Web formats + expect(isConversionSupported('pdf', 'html')).toBe(true); + expect(isConversionSupported('pdf', 'xml')).toBe(true); + + // PDF to PDF/A + expect(isConversionSupported('pdf', 'pdfa')).toBe(true); + + // Office Documents to PDF + expect(isConversionSupported('docx', 'pdf')).toBe(true); + expect(isConversionSupported('doc', 'pdf')).toBe(true); + expect(isConversionSupported('odt', 'pdf')).toBe(true); + + // Spreadsheets to PDF + expect(isConversionSupported('xlsx', 'pdf')).toBe(true); + expect(isConversionSupported('xls', 'pdf')).toBe(true); + expect(isConversionSupported('ods', 'pdf')).toBe(true); + + // Presentations to PDF + expect(isConversionSupported('pptx', 'pdf')).toBe(true); + expect(isConversionSupported('ppt', 'pdf')).toBe(true); + expect(isConversionSupported('odp', 'pdf')).toBe(true); + + // Images to PDF + expect(isConversionSupported('jpg', 'pdf')).toBe(true); + expect(isConversionSupported('jpeg', 'pdf')).toBe(true); + expect(isConversionSupported('png', 'pdf')).toBe(true); + expect(isConversionSupported('gif', 'pdf')).toBe(true); + expect(isConversionSupported('bmp', 'pdf')).toBe(true); + expect(isConversionSupported('tiff', 'pdf')).toBe(true); + expect(isConversionSupported('webp', 'pdf')).toBe(true); + + // Web formats to PDF + expect(isConversionSupported('html', 'pdf')).toBe(true); + expect(isConversionSupported('htm', 'pdf')).toBe(true); + + // Markdown to PDF + expect(isConversionSupported('md', 'pdf')).toBe(true); + + // Text formats to PDF + expect(isConversionSupported('txt', 'pdf')).toBe(true); + expect(isConversionSupported('rtf', 'pdf')).toBe(true); + + // Email to PDF + expect(isConversionSupported('eml', 'pdf')).toBe(true); + }); + + test('should return false for unsupported conversions', () => { + expect(isConversionSupported('pdf', 'exe')).toBe(false); + expect(isConversionSupported('wav', 'pdf')).toBe(true); // Fallback to file to pdf + expect(isConversionSupported('png', 'docx')).toBe(false); + expect(isConversionSupported('nonexistent', 'alsononexistent')).toBe(false); + }); + + test('should handle empty inputs', () => { + expect(isConversionSupported('', '')).toBe(false); + expect(isConversionSupported('pdf', '')).toBe(false); + expect(isConversionSupported('', 'pdf')).toBe(false); + }); + }); + + describe('isImageFormat', () => { + + test('should return true for image formats', () => { + expect(isImageFormat('png')).toBe(true); + expect(isImageFormat('jpg')).toBe(true); + expect(isImageFormat('jpeg')).toBe(true); + expect(isImageFormat('gif')).toBe(true); + expect(isImageFormat('tiff')).toBe(true); + expect(isImageFormat('bmp')).toBe(true); + expect(isImageFormat('webp')).toBe(true); + }); + + test('should return false for non-image formats', () => { + expect(isImageFormat('pdf')).toBe(false); + expect(isImageFormat('docx')).toBe(false); + expect(isImageFormat('txt')).toBe(false); + expect(isImageFormat('csv')).toBe(false); + expect(isImageFormat('html')).toBe(false); + expect(isImageFormat('xml')).toBe(false); + }); + + test('should handle case insensitivity', () => { + expect(isImageFormat('PNG')).toBe(true); + expect(isImageFormat('JPG')).toBe(true); + expect(isImageFormat('JPEG')).toBe(true); + expect(isImageFormat('Png')).toBe(true); + expect(isImageFormat('JpG')).toBe(true); + }); + + test('should handle empty and invalid inputs', () => { + expect(isImageFormat('')).toBe(false); + expect(isImageFormat('invalid')).toBe(false); + expect(isImageFormat('123')).toBe(false); + expect(isImageFormat('.')).toBe(false); + }); + + test('should handle mixed case and edge cases', () => { + expect(isImageFormat('webP')).toBe(true); + expect(isImageFormat('WEBP')).toBe(true); + expect(isImageFormat('tIFf')).toBe(true); + expect(isImageFormat('bMp')).toBe(true); + }); + }); + + describe('Edge Cases and Error Handling', () => { + + test('should handle null and undefined inputs gracefully', () => { + // Note: TypeScript prevents these, but test runtime behavior for robustness + // The current implementation handles these gracefully by returning falsy values + expect(getEndpointName(null as any, null as any)).toBe(''); + expect(getEndpointUrl(undefined as any, undefined as any)).toBe(''); + expect(isConversionSupported(null as any, null as any)).toBe(false); + + // isImageFormat will throw because it calls toLowerCase() on null/undefined + expect(() => isImageFormat(null as any)).toThrow(); + expect(() => isImageFormat(undefined as any)).toThrow(); + }); + + test('should handle special characters in file extensions', () => { + expect(isImageFormat('png@')).toBe(false); + expect(isImageFormat('jpg#')).toBe(false); + expect(isImageFormat('png.')).toBe(false); + expect(getEndpointName('pdf@', 'png')).toBe(''); + expect(getEndpointName('pdf', 'png#')).toBe(''); + }); + + test('should handle very long extension names', () => { + const longExtension = 'a'.repeat(100); + expect(isImageFormat(longExtension)).toBe(false); + expect(getEndpointName('pdf', longExtension)).toBe(''); + expect(getEndpointName(longExtension, 'pdf')).toBe('file-to-pdf'); // Fallback to file to pdf + }); + }); +}); \ No newline at end of file diff --git a/frontend/src/utils/convertUtils.ts b/frontend/src/utils/convertUtils.ts new file mode 100644 index 000000000..9c058c5ce --- /dev/null +++ b/frontend/src/utils/convertUtils.ts @@ -0,0 +1,59 @@ +import { + CONVERSION_ENDPOINTS, + ENDPOINT_NAMES, + EXTENSION_TO_ENDPOINT +} from '../constants/convertConstants'; + +/** + * Resolves the endpoint name for a given conversion + */ +export const getEndpointName = (fromExtension: string, toExtension: string): string => { + if (!fromExtension || !toExtension) return ''; + + let endpointKey = EXTENSION_TO_ENDPOINT[fromExtension]?.[toExtension]; + + // If no explicit mapping exists and we're converting to PDF, + // fall back to 'any' which uses file-to-pdf endpoint + if (!endpointKey && toExtension === 'pdf' && fromExtension !== 'any') { + endpointKey = EXTENSION_TO_ENDPOINT['any']?.[toExtension]; + } + + return endpointKey || ''; +}; + +/** + * Resolves the full endpoint URL for a given conversion + */ +export const getEndpointUrl = (fromExtension: string, toExtension: string): string => { + const endpointName = getEndpointName(fromExtension, toExtension); + if (!endpointName) return ''; + + // Find the endpoint URL from CONVERSION_ENDPOINTS using the endpoint name + for (const [key, endpoint] of Object.entries(CONVERSION_ENDPOINTS)) { + if (ENDPOINT_NAMES[key as keyof typeof ENDPOINT_NAMES] === endpointName) { + return endpoint; + } + } + return ''; +}; + +/** + * Checks if a conversion is supported + */ +export const isConversionSupported = (fromExtension: string, toExtension: string): boolean => { + return getEndpointName(fromExtension, toExtension) !== ''; +}; + +/** + * Checks if the given extension is an image format + */ +export const isImageFormat = (extension: string): boolean => { + return ['png', 'jpg', 'jpeg', 'gif', 'tiff', 'bmp', 'webp', 'svg'].includes(extension.toLowerCase()); +}; + +/** + * Checks if the given extension is a web format + */ +export const isWebFormat = (extension: string): boolean => { + return ['html', 'zip'].includes(extension.toLowerCase()); +}; \ No newline at end of file diff --git a/frontend/src/utils/fileHash.ts b/frontend/src/utils/fileHash.ts new file mode 100644 index 000000000..3ff911a56 --- /dev/null +++ b/frontend/src/utils/fileHash.ts @@ -0,0 +1,127 @@ +/** + * File hashing utilities for cache key generation + */ + +export class FileHasher { + private static readonly CHUNK_SIZE = 64 * 1024; // 64KB chunks for hashing + + /** + * Generate a content-based hash for a file + * Uses first + last + middle chunks to create a reasonably unique hash + * without reading the entire file (which would be expensive for large files) + */ + static async generateContentHash(file: File): Promise { + const chunks = await this.getFileChunks(file); + const combined = await this.combineChunks(chunks); + return await this.hashArrayBuffer(combined); + } + + /** + * Generate a fast hash based on file metadata + * Faster but less collision-resistant than content hash + */ + static generateMetadataHash(file: File): string { + const data = `${file.name}-${file.size}-${file.lastModified}-${file.type}`; + return this.simpleHash(data); + } + + /** + * Generate a hybrid hash that balances speed and uniqueness + * Uses metadata + small content sample + */ + static async generateHybridHash(file: File): Promise { + const metadataHash = this.generateMetadataHash(file); + + // For small files, use full content hash + if (file.size <= 1024 * 1024) { // 1MB + const contentHash = await this.generateContentHash(file); + return `${metadataHash}-${contentHash}`; + } + + // For large files, use first chunk only + const firstChunk = file.slice(0, this.CHUNK_SIZE); + const firstChunkBuffer = await firstChunk.arrayBuffer(); + const firstChunkHash = await this.hashArrayBuffer(firstChunkBuffer); + + return `${metadataHash}-${firstChunkHash}`; + } + + private static async getFileChunks(file: File): Promise { + const chunks: ArrayBuffer[] = []; + + // First chunk + if (file.size > 0) { + const firstChunk = file.slice(0, Math.min(this.CHUNK_SIZE, file.size)); + chunks.push(await firstChunk.arrayBuffer()); + } + + // Middle chunk (if file is large enough) + if (file.size > this.CHUNK_SIZE * 2) { + const middleStart = Math.floor(file.size / 2) - Math.floor(this.CHUNK_SIZE / 2); + const middleEnd = middleStart + this.CHUNK_SIZE; + const middleChunk = file.slice(middleStart, middleEnd); + chunks.push(await middleChunk.arrayBuffer()); + } + + // Last chunk (if file is large enough and different from first) + if (file.size > this.CHUNK_SIZE) { + const lastStart = Math.max(file.size - this.CHUNK_SIZE, this.CHUNK_SIZE); + const lastChunk = file.slice(lastStart); + chunks.push(await lastChunk.arrayBuffer()); + } + + return chunks; + } + + private static async combineChunks(chunks: ArrayBuffer[]): Promise { + const totalLength = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0); + const combined = new Uint8Array(totalLength); + + let offset = 0; + for (const chunk of chunks) { + combined.set(new Uint8Array(chunk), offset); + offset += chunk.byteLength; + } + + return combined.buffer; + } + + private static async hashArrayBuffer(buffer: ArrayBuffer): Promise { + // Use Web Crypto API for proper hashing + if (crypto.subtle) { + const hashBuffer = await crypto.subtle.digest('SHA-256', buffer); + const hashArray = Array.from(new Uint8Array(hashBuffer)); + return hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); + } + + // Fallback for environments without crypto.subtle + return this.simpleHash(Array.from(new Uint8Array(buffer)).join('')); + } + + private static simpleHash(str: string): string { + let hash = 0; + if (str.length === 0) return hash.toString(); + + for (let i = 0; i < str.length; i++) { + const char = str.charCodeAt(i); + hash = ((hash << 5) - hash) + char; + hash = hash & hash; // Convert to 32-bit integer + } + + return Math.abs(hash).toString(16); + } + + /** + * Validate that a file matches its expected hash + * Useful for detecting file corruption or changes + */ + static async validateFileHash(file: File, expectedHash: string): Promise { + try { + const actualHash = await this.generateHybridHash(file); + return actualHash === expectedHash; + } catch (error) { + console.error('Hash validation failed:', error); + return false; + } + } +} \ No newline at end of file diff --git a/frontend/src/utils/fileResponseUtils.test.ts b/frontend/src/utils/fileResponseUtils.test.ts new file mode 100644 index 000000000..2f16a7c61 --- /dev/null +++ b/frontend/src/utils/fileResponseUtils.test.ts @@ -0,0 +1,147 @@ +/** + * Unit tests for file response utility functions + */ + +import { describe, test, expect } from 'vitest'; +import { getFilenameFromHeaders, createFileFromApiResponse } from './fileResponseUtils'; + +describe('fileResponseUtils', () => { + + describe('getFilenameFromHeaders', () => { + + test('should extract filename from content-disposition header', () => { + const contentDisposition = 'attachment; filename="document.pdf"'; + const filename = getFilenameFromHeaders(contentDisposition); + + expect(filename).toBe('document.pdf'); + }); + + test('should extract filename without quotes', () => { + const contentDisposition = 'attachment; filename=document.pdf'; + const filename = getFilenameFromHeaders(contentDisposition); + + expect(filename).toBe('document.pdf'); + }); + + test('should handle single quotes', () => { + const contentDisposition = "attachment; filename='document.pdf'"; + const filename = getFilenameFromHeaders(contentDisposition); + + expect(filename).toBe('document.pdf'); + }); + + test('should return null for malformed header', () => { + const contentDisposition = 'attachment; invalid=format'; + const filename = getFilenameFromHeaders(contentDisposition); + + expect(filename).toBe(null); + }); + + test('should return null for empty header', () => { + const filename = getFilenameFromHeaders(''); + + expect(filename).toBe(null); + }); + + test('should return null for undefined header', () => { + const filename = getFilenameFromHeaders(); + + expect(filename).toBe(null); + }); + + test('should handle complex filenames with spaces and special chars', () => { + const contentDisposition = 'attachment; filename="My Document (1).pdf"'; + const filename = getFilenameFromHeaders(contentDisposition); + + expect(filename).toBe('My Document (1).pdf'); + }); + + test('should handle filename with extension when downloadHtml is enabled', () => { + const contentDisposition = 'attachment; filename="email_content.html"'; + const filename = getFilenameFromHeaders(contentDisposition); + + expect(filename).toBe('email_content.html'); + }); + }); + + describe('createFileFromApiResponse', () => { + + test('should create file using header filename when available', () => { + const responseData = new Uint8Array([1, 2, 3, 4]); + const headers = { + 'content-type': 'application/pdf', + 'content-disposition': 'attachment; filename="server_filename.pdf"' + }; + const fallbackFilename = 'fallback.pdf'; + + const file = createFileFromApiResponse(responseData, headers, fallbackFilename); + + expect(file.name).toBe('server_filename.pdf'); + expect(file.type).toBe('application/pdf'); + expect(file.size).toBe(4); + }); + + test('should use fallback filename when no header filename', () => { + const responseData = new Uint8Array([1, 2, 3, 4]); + const headers = { + 'content-type': 'application/pdf' + }; + const fallbackFilename = 'converted_file.pdf'; + + const file = createFileFromApiResponse(responseData, headers, fallbackFilename); + + expect(file.name).toBe('converted_file.pdf'); + expect(file.type).toBe('application/pdf'); + }); + + test('should handle HTML response when downloadHtml is enabled', () => { + const responseData = 'Test'; + const headers = { + 'content-type': 'text/html', + 'content-disposition': 'attachment; filename="email_content.html"' + }; + const fallbackFilename = 'fallback.pdf'; + + const file = createFileFromApiResponse(responseData, headers, fallbackFilename); + + expect(file.name).toBe('email_content.html'); + expect(file.type).toBe('text/html'); + }); + + test('should handle ZIP response', () => { + const responseData = new Uint8Array([80, 75, 3, 4]); // ZIP file signature + const headers = { + 'content-type': 'application/zip', + 'content-disposition': 'attachment; filename="converted_files.zip"' + }; + const fallbackFilename = 'fallback.pdf'; + + const file = createFileFromApiResponse(responseData, headers, fallbackFilename); + + expect(file.name).toBe('converted_files.zip'); + expect(file.type).toBe('application/zip'); + }); + + test('should use default content-type when none provided', () => { + const responseData = new Uint8Array([1, 2, 3, 4]); + const headers = {}; + const fallbackFilename = 'test.bin'; + + const file = createFileFromApiResponse(responseData, headers, fallbackFilename); + + expect(file.name).toBe('test.bin'); + expect(file.type).toBe('application/octet-stream'); + }); + + test('should handle null/undefined headers gracefully', () => { + const responseData = new Uint8Array([1, 2, 3, 4]); + const headers = null; + const fallbackFilename = 'test.bin'; + + const file = createFileFromApiResponse(responseData, headers, fallbackFilename); + + expect(file.name).toBe('test.bin'); + expect(file.type).toBe('application/octet-stream'); + }); + }); +}); \ No newline at end of file diff --git a/frontend/src/utils/fileResponseUtils.ts b/frontend/src/utils/fileResponseUtils.ts new file mode 100644 index 000000000..6e4422099 --- /dev/null +++ b/frontend/src/utils/fileResponseUtils.ts @@ -0,0 +1,37 @@ +/** + * Generic utility functions for handling file responses from API endpoints + */ + +/** + * Extracts filename from Content-Disposition header + * @param contentDisposition - Content-Disposition header value + * @returns Filename if found, null otherwise + */ +export const getFilenameFromHeaders = (contentDisposition: string = ''): string | null => { + const match = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); + if (match && match[1]) { + return match[1].replace(/['"]/g, ''); + } + return null; +}; + +/** + * Creates a File object from API response using the filename from headers + * @param responseData - The response data (blob/arraybuffer/string) + * @param headers - Response headers object + * @param fallbackFilename - Filename to use if none provided in headers + * @returns File object + */ +export const createFileFromApiResponse = ( + responseData: any, + headers: any, + fallbackFilename: string +): File => { + const contentType = headers?.['content-type'] || 'application/octet-stream'; + const contentDisposition = headers?.['content-disposition'] || ''; + + const filename = getFilenameFromHeaders(contentDisposition) || fallbackFilename; + const blob = new Blob([responseData], { type: contentType }); + + return new File([blob], filename, { type: contentType }); +}; \ No newline at end of file diff --git a/frontend/src/utils/fileUtils.ts b/frontend/src/utils/fileUtils.ts new file mode 100644 index 000000000..682cd9f3c --- /dev/null +++ b/frontend/src/utils/fileUtils.ts @@ -0,0 +1,175 @@ +import { FileWithUrl } from "../types/file"; +import { StoredFile, fileStorage } from "../services/fileStorage"; + +export function getFileId(file: File): string | null { + return (file as File & { id?: string }).id || null; +} + +/** + * Consolidated file size formatting utility + */ +export function formatFileSize(bytes: number): string { + if (bytes === 0) return '0 B'; + const k = 1024; + const sizes = ['B', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; +} + +/** + * Get file date as string + */ +export function getFileDate(file: File): string { + if (file.lastModified) { + return new Date(file.lastModified).toLocaleString(); + } + return "Unknown"; +} + +/** + * Get file size as string (legacy method for backward compatibility) + */ +export function getFileSize(file: File): string { + if (!file.size) return "Unknown"; + return formatFileSize(file.size); +} + +/** + * Create enhanced file object from stored file metadata + * This eliminates the repeated pattern in FileManager + */ +export function createEnhancedFileFromStored(storedFile: StoredFile, thumbnail?: string): FileWithUrl { + const enhancedFile: FileWithUrl = { + id: storedFile.id, + storedInIndexedDB: true, + url: undefined, // Don't create blob URL immediately to save memory + thumbnail: thumbnail || storedFile.thumbnail, + // File metadata + name: storedFile.name, + size: storedFile.size, + type: storedFile.type, + lastModified: storedFile.lastModified, + // Lazy-loading File interface methods + arrayBuffer: async () => { + const data = await fileStorage.getFileData(storedFile.id); + if (!data) throw new Error(`File ${storedFile.name} not found in IndexedDB - may have been purged`); + return data; + }, + slice: (start?: number, end?: number, contentType?: string) => { + // Return a promise-based slice that loads from IndexedDB + return new Blob([], { type: contentType || storedFile.type }); + }, + stream: () => { + throw new Error('Stream not implemented for IndexedDB files'); + }, + text: async () => { + const data = await fileStorage.getFileData(storedFile.id); + if (!data) throw new Error(`File ${storedFile.name} not found in IndexedDB - may have been purged`); + return new TextDecoder().decode(data); + } + } as FileWithUrl; + + return enhancedFile; +} + +/** + * Load files from IndexedDB and convert to enhanced file objects + */ +export async function loadFilesFromIndexedDB(): Promise { + try { + await fileStorage.init(); + const storedFiles = await fileStorage.getAllFileMetadata(); + + if (storedFiles.length === 0) { + return []; + } + + const restoredFiles: FileWithUrl[] = storedFiles + .filter(storedFile => { + // Filter out corrupted entries + return storedFile && + storedFile.name && + typeof storedFile.size === 'number'; + }) + .map(storedFile => { + try { + return createEnhancedFileFromStored(storedFile); + } catch (error) { + console.error('Failed to restore file:', storedFile?.name || 'unknown', error); + return null; + } + }) + .filter((file): file is FileWithUrl => file !== null); + + return restoredFiles; + } catch (error) { + console.error('Failed to load files from IndexedDB:', error); + return []; + } +} + +/** + * Clean up blob URLs from file objects + */ +export function cleanupFileUrls(files: FileWithUrl[]): void { + files.forEach(file => { + if (file.url && !file.url.startsWith('indexeddb:')) { + URL.revokeObjectURL(file.url); + } + }); +} + +/** + * Check if file should use blob URL or IndexedDB direct access + */ +export function shouldUseDirectIndexedDBAccess(file: FileWithUrl): boolean { + const FILE_SIZE_LIMIT = 100 * 1024 * 1024; // 100MB + return file.size > FILE_SIZE_LIMIT; +} + +/** + * Detects and normalizes file extension from filename + * @param filename - The filename to extract extension from + * @returns Normalized file extension in lowercase, empty string if no extension + */ +export function detectFileExtension(filename: string): string { + if (!filename || typeof filename !== 'string') return ''; + + const parts = filename.split('.'); + // If there's no extension (no dots or only one part), return empty string + if (parts.length <= 1) return ''; + + // Get the last part (extension) in lowercase + let extension = parts[parts.length - 1].toLowerCase(); + + // Normalize common extension variants + if (extension === 'jpeg') extension = 'jpg'; + + return extension; +} + +/** + * Gets the filename without extension + * @param filename - The filename to process + * @returns Filename without extension + */ +export function getFilenameWithoutExtension(filename: string): string { + if (!filename || typeof filename !== 'string') return ''; + + const parts = filename.split('.'); + if (parts.length <= 1) return filename; + + // Return all parts except the last one (extension) + return parts.slice(0, -1).join('.'); +} + +/** + * Creates a new filename with a different extension + * @param filename - Original filename + * @param newExtension - New extension (without dot) + * @returns New filename with the specified extension + */ +export function changeFileExtension(filename: string, newExtension: string): string { + const nameWithoutExt = getFilenameWithoutExtension(filename); + return `${nameWithoutExt}.${newExtension}`; +} \ No newline at end of file diff --git a/frontend/src/utils/genericUtils.ts b/frontend/src/utils/genericUtils.ts new file mode 100644 index 000000000..253346292 --- /dev/null +++ b/frontend/src/utils/genericUtils.ts @@ -0,0 +1,42 @@ +/** + * DOM utility functions for common operations + */ + +/** + * Clamps a value between a minimum and maximum + * @param value - The value to clamp + * @param min - The minimum allowed value + * @param max - The maximum allowed value + * @returns The clamped value + */ +export function clamp(value: number, min: number, max: number): number { + return Math.min(Math.max(value, min), max); +} + +/** + * Safely adds an event listener with proper cleanup + * @param target - The target element or window/document + * @param event - The event type + * @param handler - The event handler function + * @param options - Event listener options + * @returns A cleanup function to remove the listener + */ +export function addEventListenerWithCleanup( + target: EventTarget, + event: string, + handler: EventListener, + options?: boolean | AddEventListenerOptions +): () => void { + target.addEventListener(event, handler, options); + return () => target.removeEventListener(event, handler, options); +} + +/** + * Checks if a click event occurred outside of a specified element + * @param event - The click event + * @param element - The element to check against + * @returns True if the click was outside the element + */ +export function isClickOutside(event: MouseEvent, element: HTMLElement | null): boolean { + return element ? !element.contains(event.target as Node) : true; +} diff --git a/frontend/src/utils/languageMapping.ts b/frontend/src/utils/languageMapping.ts new file mode 100644 index 000000000..687c63258 --- /dev/null +++ b/frontend/src/utils/languageMapping.ts @@ -0,0 +1,1020 @@ +// Unified Language System - Tri-directional mapping between browser languages, OCR codes, and display names +// Replaces both languageMapping.ts and tempOcrLanguages.ts + +interface LanguageDefinition { + ocrCode: string; + displayName: string; + browserCodes: string[]; +} + +// Comprehensive language definitions with all mappings +const languageDefinitions: LanguageDefinition[] = [ + // English + { + ocrCode: 'eng', + displayName: 'English', + browserCodes: ['en', 'en-US', 'en-GB', 'en-AU', 'en-CA', 'en-IE', 'en-NZ', 'en-ZA'] + }, + + // Spanish + { + ocrCode: 'spa', + displayName: 'Spanish', + browserCodes: ['es', 'es-ES', 'es-MX', 'es-AR', 'es-CO', 'es-CL', 'es-PE', 'es-VE'] + }, + + // French + { + ocrCode: 'fra', + displayName: 'French', + browserCodes: ['fr', 'fr-FR', 'fr-CA', 'fr-BE', 'fr-CH'] + }, + + // German + { + ocrCode: 'deu', + displayName: 'German', + browserCodes: ['de', 'de-DE', 'de-AT', 'de-CH'] + }, + + // Portuguese + { + ocrCode: 'por', + displayName: 'Portuguese', + browserCodes: ['pt', 'pt-PT', 'pt-BR'] + }, + + // Italian + { + ocrCode: 'ita', + displayName: 'Italian', + browserCodes: ['it', 'it-IT', 'it-CH'] + }, + + // Chinese Simplified + { + ocrCode: 'chi_sim', + displayName: 'Chinese (Simplified)', + browserCodes: ['zh', 'zh-CN', 'zh-Hans'] + }, + + // Chinese Traditional + { + ocrCode: 'chi_tra', + displayName: 'Chinese (Traditional)', + browserCodes: ['zh-TW', 'zh-HK', 'zh-Hant'] + }, + + // Tibetan + { + ocrCode: 'bod', + displayName: 'Tibetan', + browserCodes: ['bo', 'zh-BO'] + }, + + // Japanese + { + ocrCode: 'jpn', + displayName: 'Japanese', + browserCodes: ['ja', 'ja-JP'] + }, + + // Korean + { + ocrCode: 'kor', + displayName: 'Korean', + browserCodes: ['ko', 'ko-KR'] + }, + + // Russian + { + ocrCode: 'rus', + displayName: 'Russian', + browserCodes: ['ru', 'ru-RU'] + }, + + // Arabic + { + ocrCode: 'ara', + displayName: 'Arabic', + browserCodes: ['ar', 'ar-SA', 'ar-EG', 'ar-AE', 'ar-MA'] + }, + + // Dutch + { + ocrCode: 'nld', + displayName: 'Dutch; Flemish', + browserCodes: ['nl', 'nl-NL', 'nl-BE'] + }, + + // Polish + { + ocrCode: 'pol', + displayName: 'Polish', + browserCodes: ['pl', 'pl-PL'] + }, + + // Czech + { + ocrCode: 'ces', + displayName: 'Czech', + browserCodes: ['cs', 'cs-CZ'] + }, + + // Slovak + { + ocrCode: 'slk', + displayName: 'Slovak', + browserCodes: ['sk', 'sk-SK'] + }, + + // Hungarian + { + ocrCode: 'hun', + displayName: 'Hungarian', + browserCodes: ['hu', 'hu-HU'] + }, + + // Romanian + { + ocrCode: 'ron', + displayName: 'Romanian, Moldavian, Moldovan', + browserCodes: ['ro', 'ro-RO'] + }, + + // Bulgarian + { + ocrCode: 'bul', + displayName: 'Bulgarian', + browserCodes: ['bg', 'bg-BG'] + }, + + // Croatian + { + ocrCode: 'hrv', + displayName: 'Croatian', + browserCodes: ['hr', 'hr-HR'] + }, + + // Serbian + { + ocrCode: 'srp', + displayName: 'Serbian', + browserCodes: ['sr', 'sr-RS'] + }, + + // Serbian Latin + { + ocrCode: 'srp_latn', + displayName: 'Serbian (Latin)', + browserCodes: ['sr-Latn'] + }, + + // Slovenian + { + ocrCode: 'slv', + displayName: 'Slovenian', + browserCodes: ['sl', 'sl-SI'] + }, + + // Estonian + { + ocrCode: 'est', + displayName: 'Estonian', + browserCodes: ['et', 'et-EE'] + }, + + // Latvian + { + ocrCode: 'lav', + displayName: 'Latvian', + browserCodes: ['lv', 'lv-LV'] + }, + + // Lithuanian + { + ocrCode: 'lit', + displayName: 'Lithuanian', + browserCodes: ['lt', 'lt-LT'] + }, + + // Finnish + { + ocrCode: 'fin', + displayName: 'Finnish', + browserCodes: ['fi', 'fi-FI'] + }, + + // Swedish + { + ocrCode: 'swe', + displayName: 'Swedish', + browserCodes: ['sv', 'sv-SE'] + }, + + // Norwegian + { + ocrCode: 'nor', + displayName: 'Norwegian', + browserCodes: ['no', 'nb', 'nn', 'no-NO', 'nb-NO', 'nn-NO'] + }, + + // Danish + { + ocrCode: 'dan', + displayName: 'Danish', + browserCodes: ['da', 'da-DK'] + }, + + // Icelandic + { + ocrCode: 'isl', + displayName: 'Icelandic', + browserCodes: ['is', 'is-IS'] + }, + + // Greek + { + ocrCode: 'ell', + displayName: 'Greek', + browserCodes: ['el', 'el-GR'] + }, + + // Turkish + { + ocrCode: 'tur', + displayName: 'Turkish', + browserCodes: ['tr', 'tr-TR'] + }, + + // Hebrew + { + ocrCode: 'heb', + displayName: 'Hebrew', + browserCodes: ['he', 'he-IL'] + }, + + // Hindi + { + ocrCode: 'hin', + displayName: 'Hindi', + browserCodes: ['hi', 'hi-IN'] + }, + + // Thai + { + ocrCode: 'tha', + displayName: 'Thai', + browserCodes: ['th', 'th-TH'] + }, + + // Vietnamese + { + ocrCode: 'vie', + displayName: 'Vietnamese', + browserCodes: ['vi', 'vi-VN'] + }, + + // Indonesian + { + ocrCode: 'ind', + displayName: 'Indonesian', + browserCodes: ['id', 'id-ID'] + }, + + // Malay + { + ocrCode: 'msa', + displayName: 'Malay', + browserCodes: ['ms', 'ms-MY'] + }, + + // Filipino + { + ocrCode: 'fil', + displayName: 'Filipino', + browserCodes: ['fil'] + }, + + // Tagalog + { + ocrCode: 'tgl', + displayName: 'Tagalog', + browserCodes: ['tl'] + }, + + // Ukrainian + { + ocrCode: 'ukr', + displayName: 'Ukrainian', + browserCodes: ['uk', 'uk-UA'] + }, + + // Belarusian + { + ocrCode: 'bel', + displayName: 'Belarusian', + browserCodes: ['be', 'be-BY'] + }, + + // Kazakh + { + ocrCode: 'kaz', + displayName: 'Kazakh', + browserCodes: ['kk', 'kk-KZ'] + }, + + // Uzbek + { + ocrCode: 'uzb', + displayName: 'Uzbek', + browserCodes: ['uz', 'uz-UZ'] + }, + + // Georgian + { + ocrCode: 'kat', + displayName: 'Georgian', + browserCodes: ['ka', 'ka-GE'] + }, + + // Armenian + { + ocrCode: 'hye', + displayName: 'Armenian', + browserCodes: ['hy', 'hy-AM'] + }, + + // Azerbaijani + { + ocrCode: 'aze', + displayName: 'Azerbaijani', + browserCodes: ['az', 'az-AZ'] + }, + + // Persian/Farsi + { + ocrCode: 'fas', + displayName: 'Persian', + browserCodes: ['fa', 'fa-IR'] + }, + + // Urdu + { + ocrCode: 'urd', + displayName: 'Urdu', + browserCodes: ['ur', 'ur-PK'] + }, + + // Bengali + { + ocrCode: 'ben', + displayName: 'Bengali', + browserCodes: ['bn', 'bn-BD', 'bn-IN'] + }, + + // Tamil + { + ocrCode: 'tam', + displayName: 'Tamil', + browserCodes: ['ta', 'ta-IN', 'ta-LK'] + }, + + // Telugu + { + ocrCode: 'tel', + displayName: 'Telugu', + browserCodes: ['te', 'te-IN'] + }, + + // Kannada + { + ocrCode: 'kan', + displayName: 'Kannada', + browserCodes: ['kn', 'kn-IN'] + }, + + // Malayalam + { + ocrCode: 'mal', + displayName: 'Malayalam', + browserCodes: ['ml', 'ml-IN'] + }, + + // Gujarati + { + ocrCode: 'guj', + displayName: 'Gujarati', + browserCodes: ['gu', 'gu-IN'] + }, + + // Marathi + { + ocrCode: 'mar', + displayName: 'Marathi', + browserCodes: ['mr', 'mr-IN'] + }, + + // Punjabi + { + ocrCode: 'pan', + displayName: 'Panjabi, Punjabi', + browserCodes: ['pa', 'pa-IN'] + }, + + // Nepali + { + ocrCode: 'nep', + displayName: 'Nepali', + browserCodes: ['ne', 'ne-NP'] + }, + + // Sinhala + { + ocrCode: 'sin', + displayName: 'Sinhala, Sinhalese', + browserCodes: ['si', 'si-LK'] + }, + + // Burmese + { + ocrCode: 'mya', + displayName: 'Burmese', + browserCodes: ['my', 'my-MM'] + }, + + // Khmer + { + ocrCode: 'khm', + displayName: 'Central Khmer', + browserCodes: ['km', 'km-KH'] + }, + + // Lao + { + ocrCode: 'lao', + displayName: 'Lao', + browserCodes: ['lo', 'lo-LA'] + }, + + // Mongolian + { + ocrCode: 'mon', + displayName: 'Mongolian', + browserCodes: ['mn', 'mn-MN'] + }, + + // Welsh + { + ocrCode: 'cym', + displayName: 'Welsh', + browserCodes: ['cy', 'cy-GB'] + }, + + // Irish + { + ocrCode: 'gle', + displayName: 'Irish', + browserCodes: ['ga', 'ga-IE'] + }, + + // Scottish Gaelic + { + ocrCode: 'gla', + displayName: 'Scottish Gaelic', + browserCodes: ['gd', 'gd-GB'] + }, + + // Basque + { + ocrCode: 'eus', + displayName: 'Basque', + browserCodes: ['eu', 'eu-ES'] + }, + + // Catalan + { + ocrCode: 'cat', + displayName: 'Catalan', + browserCodes: ['ca', 'ca-ES'] + }, + + // Galician + { + ocrCode: 'glg', + displayName: 'Galician', + browserCodes: ['gl', 'gl-ES'] + }, + + // Macedonian + { + ocrCode: 'mkd', + displayName: 'Macedonian', + browserCodes: ['mk', 'mk-MK'] + }, + + // Albanian + { + ocrCode: 'sqi', + displayName: 'Albanian', + browserCodes: ['sq', 'sq-AL'] + }, + + // Maltese + { + ocrCode: 'mlt', + displayName: 'Maltese', + browserCodes: ['mt', 'mt-MT'] + }, + + // Afrikaans + { + ocrCode: 'afr', + displayName: 'Afrikaans', + browserCodes: ['af', 'af-ZA'] + }, + + // Swahili + { + ocrCode: 'swa', + displayName: 'Swahili', + browserCodes: ['sw', 'sw-KE', 'sw-TZ'] + }, + + // Amharic + { + ocrCode: 'amh', + displayName: 'Amharic', + browserCodes: ['am'] + }, + + // Assamese + { + ocrCode: 'asm', + displayName: 'Assamese', + browserCodes: ['as'] + }, + + // Azerbaijani (Cyrillic) + { + ocrCode: 'aze_cyrl', + displayName: 'Azerbaijani (Cyrillic)', + browserCodes: [] + }, + + // Bosnian + { + ocrCode: 'bos', + displayName: 'Bosnian', + browserCodes: ['bs'] + }, + + // Breton + { + ocrCode: 'bre', + displayName: 'Breton', + browserCodes: ['br'] + }, + + // Bambara + { + ocrCode: 'bam', + displayName: 'Bambara', + browserCodes: ['bm'] + }, + + // Bashkir + { + ocrCode: 'bak', + displayName: 'Bashkir', + browserCodes: ['ba'] + }, + + // Cornish + { + ocrCode: 'cor', + displayName: 'Cornish', + browserCodes: ['kw'] + }, + + // Corsican + { + ocrCode: 'cos', + displayName: 'Corsican', + browserCodes: ['co'] + }, + + // Ewe + { + ocrCode: 'ewe', + displayName: 'Ewe', + browserCodes: ['ee'] + }, + + // Faroese + { + ocrCode: 'fao', + displayName: 'Faroese', + browserCodes: ['fo'] + }, + + // Fijian + { + ocrCode: 'fij', + displayName: 'Fijian', + browserCodes: ['fj'] + }, + + // Haitian Creole + { + ocrCode: 'hat', + displayName: 'Haitian, Haitian Creole', + browserCodes: ['ht'] + }, + + // Javanese + { + ocrCode: 'jav', + displayName: 'Javanese', + browserCodes: ['jv'] + }, + + // Kirghiz + { + ocrCode: 'kir', + displayName: 'Kirghiz, Kyrgyz', + browserCodes: ['ky'] + }, + + // Quechua + { + ocrCode: 'que', + displayName: 'Quechua', + browserCodes: ['qu'] + }, + + // Sindhi + { + ocrCode: 'snd', + displayName: 'Sindhi', + browserCodes: ['sd'] + }, + + // Yiddish + { + ocrCode: 'yid', + displayName: 'Yiddish', + browserCodes: ['yi'] + }, + + // Yoruba + { + ocrCode: 'yor', + displayName: 'Yoruba', + browserCodes: ['yo'] + }, + + // Additional OCR languages without browser mappings or with very specific/rare codes + { + ocrCode: 'ceb', + displayName: 'Cebuano', + browserCodes: [] + }, + { + ocrCode: 'chi_sim_vert', + displayName: 'Chinese (Simplified, Vertical)', + browserCodes: [] + }, + { + ocrCode: 'chi_tra_vert', + displayName: 'Chinese (Traditional, Vertical)', + browserCodes: [] + }, + { + ocrCode: 'chr', + displayName: 'Cherokee', + browserCodes: [] + }, + { + ocrCode: 'dan_frak', + displayName: 'Danish (Fraktur)', + browserCodes: [] + }, + { + ocrCode: 'deu_frak', + displayName: 'German (Fraktur)', + browserCodes: [] + }, + { + ocrCode: 'div', + displayName: 'Divehi', + browserCodes: ['dv'] + }, + { + ocrCode: 'dzo', + displayName: 'Dzongkha', + browserCodes: ['dz'] + }, + { + ocrCode: 'enm', + displayName: 'English, Middle (1100-1500)', + browserCodes: [] + }, + { + ocrCode: 'epo', + displayName: 'Esperanto', + browserCodes: ['eo'] + }, + { + ocrCode: 'equ', + displayName: 'Math / equation detection module', + browserCodes: [] + }, + { + ocrCode: 'frk', + displayName: 'Frankish', + browserCodes: [] + }, + { + ocrCode: 'frm', + displayName: 'French, Middle (ca.1400-1600)', + browserCodes: [] + }, + { + ocrCode: 'fry', + displayName: 'Western Frisian', + browserCodes: ['fy'] + }, + { + ocrCode: 'grc', + displayName: 'Ancient Greek', + browserCodes: [] + }, + { + ocrCode: 'iku', + displayName: 'Inuktitut', + browserCodes: ['iu'] + }, + { + ocrCode: 'ita_old', + displayName: 'Italian (Old)', + browserCodes: [] + }, + { + ocrCode: 'jpn_vert', + displayName: 'Japanese (Vertical)', + browserCodes: [] + }, + { + ocrCode: 'kat_old', + displayName: 'Georgian (Old)', + browserCodes: [] + }, + { + ocrCode: 'kmr', + displayName: 'Northern Kurdish', + browserCodes: ['ku'] + }, + { + ocrCode: 'kor_vert', + displayName: 'Korean (Vertical)', + browserCodes: [] + }, + { + ocrCode: 'lat', + displayName: 'Latin', + browserCodes: ['la'] + }, + { + ocrCode: 'ltz', + displayName: 'Luxembourgish', + browserCodes: ['lb'] + }, + { + ocrCode: 'mri', + displayName: 'Maori', + browserCodes: ['mi'] + }, + { + ocrCode: 'oci', + displayName: 'Occitan (post 1500)', + browserCodes: ['oc'] + }, + { + ocrCode: 'ori', + displayName: 'Oriya', + browserCodes: ['or'] + }, + { + ocrCode: 'osd', + displayName: 'Orientation and script detection module', + browserCodes: [] + }, + { + ocrCode: 'pus', + displayName: 'Pushto, Pashto', + browserCodes: ['ps'] + }, + { + ocrCode: 'san', + displayName: 'Sanskrit', + browserCodes: ['sa'] + }, + { + ocrCode: 'slk_frak', + displayName: 'Slovak (Fraktur)', + browserCodes: [] + }, + { + ocrCode: 'spa_old', + displayName: 'Spanish (Old)', + browserCodes: [] + }, + { + ocrCode: 'sun', + displayName: 'Sundanese', + browserCodes: ['su'] + }, + { + ocrCode: 'syr', + displayName: 'Syriac', + browserCodes: [] + }, + { + ocrCode: 'tat', + displayName: 'Tatar', + browserCodes: ['tt'] + }, + { + ocrCode: 'tgk', + displayName: 'Tajik', + browserCodes: ['tg'] + }, + { + ocrCode: 'tir', + displayName: 'Tigrinya', + browserCodes: ['ti'] + }, + { + ocrCode: 'ton', + displayName: 'Tonga (Tonga Islands)', + browserCodes: ['to'] + }, + { + ocrCode: 'uig', + displayName: 'Uighur, Uyghur', + browserCodes: ['ug'] + }, + { + ocrCode: 'uzb_cyrl', + displayName: 'Uzbek (Cyrillic)', + browserCodes: [] + } +]; + +// Build lookup maps for efficient access +const browserToOcrMap = new Map(); +const ocrToDisplayMap = new Map(); +const displayToOcrMap = new Map(); +const ocrToBrowserMap = new Map(); + +// Populate lookup maps +languageDefinitions.forEach(lang => { + // OCR code to display name + ocrToDisplayMap.set(lang.ocrCode, lang.displayName); + + // Display name to OCR code + displayToOcrMap.set(lang.displayName.toLowerCase(), lang.ocrCode); + + // OCR code to browser codes + ocrToBrowserMap.set(lang.ocrCode, lang.browserCodes); + + // Browser codes to OCR code + lang.browserCodes.forEach(browserCode => { + browserToOcrMap.set(browserCode.toLowerCase(), lang.ocrCode); + }); +}); + +/** + * Maps a browser language code to an OCR language code + * Handles exact matches and similar language fallbacks + * + * @param browserLanguage - The browser language code (e.g., 'en-GB', 'fr-FR') + * @returns OCR language code if found, null if no match + * + * @example + * mapBrowserLanguageToOcr('de-DE') // Returns 'deu' + * mapBrowserLanguageToOcr('en-GB') // Returns 'eng' + * mapBrowserLanguageToOcr('zh-CN') // Returns 'chi_sim' + */ +export function mapBrowserLanguageToOcr(browserLanguage: string): string | null { + if (!browserLanguage) return null; + + // Normalize the input + const normalizedInput = browserLanguage.toLowerCase().replace('_', '-'); + + // Try exact match first + const exactMatch = browserToOcrMap.get(normalizedInput); + if (exactMatch) return exactMatch; + + // Try with different casing variations + const variations = [ + browserLanguage.toLowerCase(), + browserLanguage.toUpperCase().toLowerCase(), + normalizedInput, + ]; + + for (const variant of variations) { + const match = browserToOcrMap.get(variant); + if (match) return match; + } + + // Try base language code (e.g., 'en' from 'en-GB') + const baseLanguage = normalizedInput.split('-')[0]; + const baseMatch = browserToOcrMap.get(baseLanguage); + if (baseMatch) return baseMatch; + + // No match found + return null; +} + +/** + * Gets the display name for an OCR language code + * + * @param ocrCode - The OCR language code (e.g., 'eng', 'deu') + * @returns Display name if found, the original code if not found + * + * @example + * getOcrDisplayName('deu') // Returns 'German' + * getOcrDisplayName('eng') // Returns 'English' + * getOcrDisplayName('chi_sim') // Returns 'Chinese (Simplified)' + */ +export function getOcrDisplayName(ocrCode: string): string { + return ocrToDisplayMap.get(ocrCode) || ocrCode; +} + +/** + * Gets the OCR code from a display name + * + * @param displayName - The display name (e.g., 'English', 'German') + * @returns OCR code if found, null if no match + * + * @example + * getOcrCodeFromDisplayName('German') // Returns 'deu' + * getOcrCodeFromDisplayName('English') // Returns 'eng' + * getOcrCodeFromDisplayName('chinese (simplified)') // Returns 'chi_sim' (case insensitive) + */ +export function getOcrCodeFromDisplayName(displayName: string): string | null { + return displayToOcrMap.get(displayName.toLowerCase()) || null; +} + +/** + * Gets the browser language codes for an OCR language code + * + * @param ocrCode - The OCR language code (e.g., 'eng', 'deu') + * @returns Array of browser language codes + * + * @example + * getBrowserLanguagesForOcr('deu') // Returns ['de', 'de-DE', 'de-AT', 'de-CH'] + * getBrowserLanguagesForOcr('eng') // Returns ['en', 'en-US', 'en-GB', 'en-AU', ...] + * getBrowserLanguagesForOcr('nor') // Returns ['no', 'nb', 'nn', 'no-NO', 'nb-NO', 'nn-NO'] + */ +export function getBrowserLanguagesForOcr(ocrCode: string): string[] { + return ocrToBrowserMap.get(ocrCode) || []; +} + +/** + * Gets the OCR language code for the current browser language + * + * @param currentLanguage - Current i18n language + * @returns OCR language code array (empty if no match) + * + * @example + * getAutoOcrLanguage('de-DE') // Returns ['deu'] + * getAutoOcrLanguage('en-GB') // Returns ['eng'] + * getAutoOcrLanguage('unknown') // Returns [] + */ +export function getAutoOcrLanguage(currentLanguage: string): string[] { + const ocrLanguage = mapBrowserLanguageToOcr(currentLanguage); + return ocrLanguage ? [ocrLanguage] : []; +} + +/** + * Gets all available language definitions + * + * @returns Array of all language definitions + * + * @example + * const allLanguages = getAllLanguageDefinitions(); + * // Returns: [{ ocrCode: 'eng', displayName: 'English', browserCodes: ['en', 'en-US', ...] }, ...] + */ +export function getAllLanguageDefinitions(): LanguageDefinition[] { + return [...languageDefinitions]; +} + +/** + * Legacy compatibility - provides the same interface as tempOcrLanguages.ts + */ +export const tempOcrLanguages = { + lang: Object.fromEntries(ocrToDisplayMap) +} as const; \ No newline at end of file diff --git a/frontend/src/utils/sidebarUtils.ts b/frontend/src/utils/sidebarUtils.ts new file mode 100644 index 000000000..cef144971 --- /dev/null +++ b/frontend/src/utils/sidebarUtils.ts @@ -0,0 +1,34 @@ +import { SidebarRefs, SidebarState, SidebarInfo } from '../types/sidebar'; + +/** + * Gets the All tools sidebar information using React refs and state + * @param refs - Object containing refs to sidebar elements + * @param state - Current sidebar state + * @returns Object containing the sidebar rect and whether the tool panel is active + */ +export function getSidebarInfo(refs: SidebarRefs, state: SidebarState): SidebarInfo { + const { quickAccessRef, toolPanelRef } = refs; + const { sidebarsVisible, readerMode } = state; + + // Determine if tool panel should be active based on state + const isToolPanelActive = sidebarsVisible && !readerMode; + + let rect: DOMRect | null = null; + + if (isToolPanelActive && toolPanelRef.current) { + // Tool panel is expanded: use its rect + rect = toolPanelRef.current.getBoundingClientRect(); + } else if (quickAccessRef.current) { + // Fall back to quick access bar + // This probably isn't needed but if we ever have tooltips or modals that need to be positioned relative to the quick access bar, we can use this + rect = quickAccessRef.current.getBoundingClientRect(); + } + + return { + rect, + isToolPanelActive, + sidebarState: state + }; +} + + \ No newline at end of file diff --git a/frontend/src/utils/storageUtils.ts b/frontend/src/utils/storageUtils.ts new file mode 100644 index 000000000..def05b96d --- /dev/null +++ b/frontend/src/utils/storageUtils.ts @@ -0,0 +1,71 @@ +import { StorageStats } from "../services/fileStorage"; +import { FileWithUrl } from "../types/file"; + +/** + * Storage operation types for incremental updates + */ +export type StorageOperation = 'add' | 'remove' | 'clear'; + +/** + * Update storage stats incrementally based on operation + */ +export function updateStorageStatsIncremental( + currentStats: StorageStats, + operation: StorageOperation, + files: FileWithUrl[] = [] +): StorageStats { + const filesSizeTotal = files.reduce((total, file) => total + file.size, 0); + + switch (operation) { + case 'add': + return { + ...currentStats, + used: currentStats.used + filesSizeTotal, + available: currentStats.available - filesSizeTotal, + fileCount: currentStats.fileCount + files.length + }; + + case 'remove': + return { + ...currentStats, + used: Math.max(0, currentStats.used - filesSizeTotal), + available: currentStats.available + filesSizeTotal, + fileCount: Math.max(0, currentStats.fileCount - files.length) + }; + + case 'clear': + return { + ...currentStats, + used: 0, + available: currentStats.quota || currentStats.available, + fileCount: 0 + }; + + default: + return currentStats; + } +} + +/** + * Check storage usage and return warning message if needed + */ +export function checkStorageWarnings(stats: StorageStats): string | null { + if (!stats.quota || stats.used === 0) return null; + + const usagePercent = (stats.used / stats.quota) * 100; + + if (usagePercent > 90) { + return 'Warning: Storage is nearly full (>90%). Browser may start clearing data.'; + } else if (usagePercent > 80) { + return 'Storage is getting full (>80%). Consider removing old files.'; + } + + return null; +} + +/** + * Calculate storage usage percentage + */ +export function getStorageUsagePercent(stats: StorageStats): number { + return stats.quota ? (stats.used / stats.quota) * 100 : 0; +} \ No newline at end of file diff --git a/frontend/src/utils/thumbnailUtils.ts b/frontend/src/utils/thumbnailUtils.ts new file mode 100644 index 000000000..f4f224044 --- /dev/null +++ b/frontend/src/utils/thumbnailUtils.ts @@ -0,0 +1,265 @@ +import { getDocument } from "pdfjs-dist"; + +/** + * Calculate thumbnail scale based on file size + * Smaller files get higher quality, larger files get lower quality + */ +export function calculateScaleFromFileSize(fileSize: number): number { + const MB = 1024 * 1024; + + if (fileSize < 1 * MB) return 0.6; // < 1MB: High quality + if (fileSize < 5 * MB) return 0.4; // 1-5MB: Medium-high quality + if (fileSize < 15 * MB) return 0.3; // 5-15MB: Medium quality + if (fileSize < 30 * MB) return 0.2; // 15-30MB: Low-medium quality + return 0.15; // 30MB+: Low quality +} + +/** + * Generate modern placeholder thumbnail with file extension + */ +function generatePlaceholderThumbnail(file: File): string { + const canvas = document.createElement('canvas'); + canvas.width = 120; + canvas.height = 150; + const ctx = canvas.getContext('2d')!; + + // Get file extension for color theming + const extension = file.name.split('.').pop()?.toUpperCase() || 'FILE'; + const colorScheme = getFileTypeColorScheme(extension); + + // Create gradient background + const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height); + gradient.addColorStop(0, colorScheme.bgTop); + gradient.addColorStop(1, colorScheme.bgBottom); + + // Rounded rectangle background + drawRoundedRect(ctx, 8, 8, canvas.width - 16, canvas.height - 16, 8); + ctx.fillStyle = gradient; + ctx.fill(); + + // Subtle shadow/border + ctx.strokeStyle = colorScheme.border; + ctx.lineWidth = 1.5; + ctx.stroke(); + + // Modern document icon + drawModernDocumentIcon(ctx, canvas.width / 2, 45, colorScheme.icon); + + // Extension badge + drawExtensionBadge(ctx, canvas.width / 2, canvas.height / 2 + 15, extension, colorScheme); + + // File size with subtle styling + const sizeText = formatFileSize(file.size); + ctx.font = '11px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'; + ctx.fillStyle = colorScheme.textSecondary; + ctx.textAlign = 'center'; + ctx.fillText(sizeText, canvas.width / 2, canvas.height - 15); + + return canvas.toDataURL(); +} + +/** + * Get color scheme based on file extension + */ +function getFileTypeColorScheme(extension: string) { + const schemes: Record = { + // Documents + 'PDF': { bgTop: '#FF6B6B20', bgBottom: '#FF6B6B10', border: '#FF6B6B40', icon: '#FF6B6B', badge: '#FF6B6B', textPrimary: '#FFFFFF', textSecondary: '#666666' }, + 'DOC': { bgTop: '#4ECDC420', bgBottom: '#4ECDC410', border: '#4ECDC440', icon: '#4ECDC4', badge: '#4ECDC4', textPrimary: '#FFFFFF', textSecondary: '#666666' }, + 'DOCX': { bgTop: '#4ECDC420', bgBottom: '#4ECDC410', border: '#4ECDC440', icon: '#4ECDC4', badge: '#4ECDC4', textPrimary: '#FFFFFF', textSecondary: '#666666' }, + 'TXT': { bgTop: '#95A5A620', bgBottom: '#95A5A610', border: '#95A5A640', icon: '#95A5A6', badge: '#95A5A6', textPrimary: '#FFFFFF', textSecondary: '#666666' }, + + // Spreadsheets + 'XLS': { bgTop: '#2ECC7120', bgBottom: '#2ECC7110', border: '#2ECC7140', icon: '#2ECC71', badge: '#2ECC71', textPrimary: '#FFFFFF', textSecondary: '#666666' }, + 'XLSX': { bgTop: '#2ECC7120', bgBottom: '#2ECC7110', border: '#2ECC7140', icon: '#2ECC71', badge: '#2ECC71', textPrimary: '#FFFFFF', textSecondary: '#666666' }, + 'CSV': { bgTop: '#2ECC7120', bgBottom: '#2ECC7110', border: '#2ECC7140', icon: '#2ECC71', badge: '#2ECC71', textPrimary: '#FFFFFF', textSecondary: '#666666' }, + + // Presentations + 'PPT': { bgTop: '#E67E2220', bgBottom: '#E67E2210', border: '#E67E2240', icon: '#E67E22', badge: '#E67E22', textPrimary: '#FFFFFF', textSecondary: '#666666' }, + 'PPTX': { bgTop: '#E67E2220', bgBottom: '#E67E2210', border: '#E67E2240', icon: '#E67E22', badge: '#E67E22', textPrimary: '#FFFFFF', textSecondary: '#666666' }, + + // Archives + 'ZIP': { bgTop: '#9B59B620', bgBottom: '#9B59B610', border: '#9B59B640', icon: '#9B59B6', badge: '#9B59B6', textPrimary: '#FFFFFF', textSecondary: '#666666' }, + 'RAR': { bgTop: '#9B59B620', bgBottom: '#9B59B610', border: '#9B59B640', icon: '#9B59B6', badge: '#9B59B6', textPrimary: '#FFFFFF', textSecondary: '#666666' }, + '7Z': { bgTop: '#9B59B620', bgBottom: '#9B59B610', border: '#9B59B640', icon: '#9B59B6', badge: '#9B59B6', textPrimary: '#FFFFFF', textSecondary: '#666666' }, + + // Default + 'DEFAULT': { bgTop: '#74B9FF20', bgBottom: '#74B9FF10', border: '#74B9FF40', icon: '#74B9FF', badge: '#74B9FF', textPrimary: '#FFFFFF', textSecondary: '#666666' } + }; + + return schemes[extension] || schemes['DEFAULT']; +} + +/** + * Draw rounded rectangle + */ +function drawRoundedRect(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number) { + ctx.beginPath(); + ctx.moveTo(x + radius, y); + ctx.lineTo(x + width - radius, y); + ctx.quadraticCurveTo(x + width, y, x + width, y + radius); + ctx.lineTo(x + width, y + height - radius); + ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); + ctx.lineTo(x + radius, y + height); + ctx.quadraticCurveTo(x, y + height, x, y + height - radius); + ctx.lineTo(x, y + radius); + ctx.quadraticCurveTo(x, y, x + radius, y); + ctx.closePath(); +} + +/** + * Draw modern document icon + */ +function drawModernDocumentIcon(ctx: CanvasRenderingContext2D, centerX: number, centerY: number, color: string) { + const size = 24; + ctx.fillStyle = color; + ctx.strokeStyle = color; + ctx.lineWidth = 2; + + // Document body + drawRoundedRect(ctx, centerX - size/2, centerY - size/2, size, size * 1.2, 3); + ctx.fill(); + + // Folded corner + ctx.beginPath(); + ctx.moveTo(centerX + size/2 - 6, centerY - size/2); + ctx.lineTo(centerX + size/2, centerY - size/2 + 6); + ctx.lineTo(centerX + size/2 - 6, centerY - size/2 + 6); + ctx.closePath(); + ctx.fillStyle = '#FFFFFF40'; + ctx.fill(); +} + +/** + * Draw extension badge + */ +function drawExtensionBadge(ctx: CanvasRenderingContext2D, centerX: number, centerY: number, extension: string, colorScheme: any) { + const badgeWidth = Math.max(extension.length * 8 + 16, 40); + const badgeHeight = 22; + + // Badge background + drawRoundedRect(ctx, centerX - badgeWidth/2, centerY - badgeHeight/2, badgeWidth, badgeHeight, 11); + ctx.fillStyle = colorScheme.badge; + ctx.fill(); + + // Badge text + ctx.font = 'bold 11px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'; + ctx.fillStyle = colorScheme.textPrimary; + ctx.textAlign = 'center'; + ctx.fillText(extension, centerX, centerY + 4); +} + +/** + * Format file size for display + */ +function formatFileSize(bytes: number): string { + if (bytes === 0) return '0 B'; + const k = 1024; + const sizes = ['B', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; +} + + +/** + * Generate thumbnail for any file type + * Returns base64 data URL or undefined if generation fails + */ +export async function generateThumbnailForFile(file: File): Promise { + // Skip thumbnail generation for very large files to avoid memory issues + if (file.size >= 100 * 1024 * 1024) { // 100MB limit + console.log('Skipping thumbnail generation for large file:', file.name); + return generatePlaceholderThumbnail(file); + } + + // Handle image files - use original file directly + if (file.type.startsWith('image/')) { + return URL.createObjectURL(file); + } + + // Handle PDF files + if (!file.type.startsWith('application/pdf')) { + console.log('File is not a PDF or image, generating placeholder:', file.name); + return generatePlaceholderThumbnail(file); + } + + try { + console.log('Generating thumbnail for', file.name); + + // Calculate quality scale based on file size + const scale = calculateScaleFromFileSize(file.size); + console.log(`Using scale ${scale} for ${file.name} (${(file.size / 1024 / 1024).toFixed(1)}MB)`); + + // Only read first 2MB for thumbnail generation to save memory + const chunkSize = 2 * 1024 * 1024; // 2MB + const chunk = file.slice(0, Math.min(chunkSize, file.size)); + const arrayBuffer = await chunk.arrayBuffer(); + + const pdf = await getDocument({ + data: arrayBuffer, + disableAutoFetch: true, + disableStream: true + }).promise; + + const page = await pdf.getPage(1); + const viewport = page.getViewport({ scale }); // Dynamic scale based on file size + const canvas = document.createElement("canvas"); + canvas.width = viewport.width; + canvas.height = viewport.height; + const context = canvas.getContext("2d"); + + if (!context) { + throw new Error('Could not get canvas context'); + } + + await page.render({ canvasContext: context, viewport }).promise; + const thumbnail = canvas.toDataURL(); + + // Immediately clean up memory after thumbnail generation + pdf.destroy(); + console.log('Thumbnail generated and PDF destroyed for', file.name); + + return thumbnail; + } catch (error) { + if (error instanceof Error) { + if (error.name === 'InvalidPDFException') { + console.warn(`PDF structure issue for ${file.name} - using fallback thumbnail`); + // Return a placeholder or try with full file instead of chunk + try { + const fullArrayBuffer = await file.arrayBuffer(); + const pdf = await getDocument({ + data: fullArrayBuffer, + disableAutoFetch: true, + disableStream: true, + verbosity: 0 // Reduce PDF.js warnings + }).promise; + + const page = await pdf.getPage(1); + const viewport = page.getViewport({ scale }); + const canvas = document.createElement("canvas"); + canvas.width = viewport.width; + canvas.height = viewport.height; + const context = canvas.getContext("2d"); + + if (!context) { + throw new Error('Could not get canvas context'); + } + + await page.render({ canvasContext: context, viewport }).promise; + const thumbnail = canvas.toDataURL(); + + pdf.destroy(); + return thumbnail; + } catch (fallbackError) { + console.warn('Fallback thumbnail generation also failed for', file.name, fallbackError); + return undefined; + } + } else { + console.warn('Failed to generate thumbnail for', file.name, error); + return undefined; + } + } + console.warn('Unknown error generating thumbnail for', file.name, error); + return undefined; + } +} \ No newline at end of file diff --git a/frontend/src/utils/toolErrorHandler.ts b/frontend/src/utils/toolErrorHandler.ts new file mode 100644 index 000000000..ee1efe4d9 --- /dev/null +++ b/frontend/src/utils/toolErrorHandler.ts @@ -0,0 +1,33 @@ +/** + * Standardized error handling utilities for tool operations + */ + +/** + * Default error extractor that follows the standard pattern + */ +export const extractErrorMessage = (error: any): string => { + if (error.response?.data && typeof error.response.data === 'string') { + return error.response.data; + } + if (error.message) { + return error.message; + } + return 'Operation failed'; +}; + +/** + * Creates a standardized error handler for tool operations + * @param fallbackMessage - Message to show when no specific error can be extracted + * @returns Error handler function that follows the standard pattern + */ +export const createStandardErrorHandler = (fallbackMessage: string) => { + return (error: any): string => { + if (error.response?.data && typeof error.response.data === 'string') { + return error.response.data; + } + if (error.message) { + return error.message; + } + return fallbackMessage; + }; +}; \ No newline at end of file diff --git a/frontend/src/utils/toolOperationTracker.ts b/frontend/src/utils/toolOperationTracker.ts new file mode 100644 index 000000000..091ef1872 --- /dev/null +++ b/frontend/src/utils/toolOperationTracker.ts @@ -0,0 +1,28 @@ +import { FileOperation } from '../types/fileContext'; + +/** + * Creates operation tracking data for FileContext integration + */ +export const createOperation = ( + operationType: string, + params: TParams, + selectedFiles: File[] +): { operation: FileOperation; operationId: string; fileId: string } => { + const operationId = `${operationType}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + const fileId = selectedFiles.map(f => f.name).join(','); + + const operation: FileOperation = { + id: operationId, + type: operationType, + timestamp: Date.now(), + fileIds: selectedFiles.map(f => f.name), + status: 'pending', + metadata: { + originalFileName: selectedFiles[0]?.name, + parameters: params, + fileSize: selectedFiles.reduce((sum, f) => sum + f.size, 0) + } + }; + + return { operation, operationId, fileId }; +}; \ No newline at end of file diff --git a/frontend/src/utils/toolResponseProcessor.ts b/frontend/src/utils/toolResponseProcessor.ts new file mode 100644 index 000000000..fe2f11242 --- /dev/null +++ b/frontend/src/utils/toolResponseProcessor.ts @@ -0,0 +1,25 @@ +// Note: This utility should be used with useToolResources for ZIP operations + +export type ResponseHandler = (blob: Blob, originalFiles: File[]) => Promise | File[]; + +/** + * Processes a blob response into File(s). + * - If a tool-specific responseHandler is provided, it is used. + * - Otherwise, create a single file using the filePrefix + original name. + */ +export async function processResponse( + blob: Blob, + originalFiles: File[], + filePrefix: string, + responseHandler?: ResponseHandler +): Promise { + if (responseHandler) { + const out = await responseHandler(blob, originalFiles); + return Array.isArray(out) ? out : [out as unknown as File]; + } + + const original = originalFiles[0]?.name ?? 'result.pdf'; + const name = `${filePrefix}${original}`; + const type = blob.type || 'application/octet-stream'; + return [new File([blob], name, { type })]; +} diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js new file mode 100644 index 000000000..42d04d16d --- /dev/null +++ b/frontend/tailwind.config.js @@ -0,0 +1,48 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + "./index.html", + "./src/**/*.{js,ts,jsx,tsx}", + ], + darkMode: ['class', '[data-mantine-color-scheme="dark"]'], + theme: { + extend: { + // Use standard Tailwind color system with CSS variables for theme switching + colors: { + // Override gray to work with both themes + gray: { + 50: 'rgb(var(--gray-50) / )', + 100: 'rgb(var(--gray-100) / )', + 200: 'rgb(var(--gray-200) / )', + 300: 'rgb(var(--gray-300) / )', + 400: 'rgb(var(--gray-400) / )', + 500: 'rgb(var(--gray-500) / )', + 600: 'rgb(var(--gray-600) / )', + 700: 'rgb(var(--gray-700) / )', + 800: 'rgb(var(--gray-800) / )', + 900: 'rgb(var(--gray-900) / )', + }, + // Custom semantic colors for app-specific usage + surface: 'rgb(var(--surface) / )', + background: 'rgb(var(--background) / )', + border: 'rgb(var(--border) / )', + }, + + // Z-index scale + zIndex: { + 'dropdown': '1000', + 'sticky': '1020', + 'fixed': '1030', + 'modal-backdrop': '1040', + 'modal': '1050', + 'popover': '1060', + 'tooltip': '1070', + }, + }, + }, + plugins: [], + // Enable preflight for standard Tailwind functionality + corePlugins: { + preflight: true, + }, +} \ No newline at end of file diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 000000000..215a9378b --- /dev/null +++ b/frontend/tsconfig.json @@ -0,0 +1,117 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "jsx": "react-jsx", /* Specify what JSX code is generated. */ + // "libReplacement": true, /* Enable lib replacement. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "esnext", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "noUncheckedSideEffectImports": true, /* Check side effect imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ + // "erasableSyntaxOnly": true, /* Do not allow runtime constructs that are not part of ECMAScript. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": [ + "src", + "src/global.d.ts" +, "vite.config.ts" ] +} diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts new file mode 100644 index 000000000..d957fa3f0 --- /dev/null +++ b/frontend/vite.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + server: { + proxy: { + '/api': { + target: 'http://localhost:8080', + changeOrigin: true, + secure: false, + }, + }, + }, +}); diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts new file mode 100644 index 000000000..9c913c2e1 --- /dev/null +++ b/frontend/vitest.config.ts @@ -0,0 +1,40 @@ +import { defineConfig } from 'vitest/config' +import react from '@vitejs/plugin-react' + +export default defineConfig({ + plugins: [react()], + test: { + globals: true, + environment: 'jsdom', + setupFiles: ['./src/setupTests.ts'], + css: false, // Disable CSS processing to speed up tests + include: [ + 'src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}' + ], + exclude: [ + 'node_modules/', + 'src/**/*.spec.ts', // Exclude Playwright E2E tests + 'src/tests/test-fixtures/**' + ], + testTimeout: 10000, // 10 second timeout + hookTimeout: 10000, // 10 second timeout for setup/teardown + coverage: { + reporter: ['text', 'json', 'html'], + exclude: [ + 'node_modules/', + 'src/setupTests.ts', + '**/*.d.ts', + 'src/tests/test-fixtures/**', + 'src/**/*.spec.ts' // Exclude Playwright files from coverage + ] + } + }, + esbuild: { + target: 'es2020' // Use older target to avoid warnings + }, + resolve: { + alias: { + '@': '/src' + } + } +}) \ No newline at end of file diff --git a/frontend/vitest.minimal.config.ts b/frontend/vitest.minimal.config.ts new file mode 100644 index 000000000..335af4e9c --- /dev/null +++ b/frontend/vitest.minimal.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + environment: 'node', + testTimeout: 5000, + include: ['src/utils/convertUtils.test.ts'] + }, +}) \ No newline at end of file diff --git a/scripts/convert_properties_to_json.py b/scripts/convert_properties_to_json.py new file mode 100644 index 000000000..991550fb6 --- /dev/null +++ b/scripts/convert_properties_to_json.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +""" +Convert Java .properties files to JSON for react-i18next +Preserves hierarchical structure and handles special cases +""" + +import os +import json +import re +from pathlib import Path + +def properties_to_dict(file_path): + """Convert .properties file to nested dictionary""" + result = {} + + with open(file_path, 'r', encoding='utf-8') as f: + for line_num, line in enumerate(f, 1): + line = line.strip() + + # Skip empty lines and comments + if not line or line.startswith('#'): + continue + + # Handle key=value pairs + if '=' in line: + key, value = line.split('=', 1) + key = key.strip() + value = value.strip() + + # Handle multiline values (ending with \) + while value.endswith('\\'): + next_line = next(f, '').strip() + value = value[:-1] + next_line + + # Create nested structure from dot notation + set_nested_value(result, key, value) + + return result + +def set_nested_value(dictionary, key_path, value): + """Set value in nested dictionary using dot notation""" + keys = key_path.split('.') + current = dictionary + + for key in keys[:-1]: + if key not in current: + current[key] = {} + elif not isinstance(current[key], dict): + # Convert existing string value to nested object + old_value = current[key] + current[key] = {"_value": old_value} + current = current[key] + + final_key = keys[-1] + if final_key in current and isinstance(current[final_key], dict): + # If the final key already exists as an object, store the value under "_value" + current[final_key]["_value"] = value + else: + current[final_key] = value + +def convert_all_properties(): + """Convert all messages_*.properties files to JSON""" + + # Get project root + script_dir = Path(__file__).parent + project_root = script_dir.parent + resources_dir = project_root / 'src' / 'main' / 'resources' + output_dir = project_root / 'frontend' / 'public' / 'locales' + + # Create output directory + output_dir.mkdir(parents=True, exist_ok=True) + + # Find all .properties files + properties_files = list(resources_dir.glob('messages*.properties')) + + converted_count = 0 + + for props_file in properties_files: + # Extract locale from filename + filename = props_file.name + if filename == 'messages.properties': + locale = 'en' # Default locale + else: + # Extract locale from messages_en_US.properties format + locale_match = re.match(r'messages_(.+)\.properties', filename) + if locale_match: + locale = locale_match.group(1) + # Convert Java locale format to standard (en_US -> en-US) + locale = locale.replace('_', '-') + else: + continue + + print(f"Converting {filename} -> {locale}.json") + + # Convert to dictionary + data = properties_to_dict(props_file) + + # Create locale directory + locale_dir = output_dir / locale + locale_dir.mkdir(exist_ok=True) + + # Write translation.json (react-i18next default namespace) + output_file = locale_dir / 'translation.json' + with open(output_file, 'w', encoding='utf-8') as f: + json.dump(data, f, indent=2, ensure_ascii=False) + + converted_count += 1 + + print(f"\nConverted {converted_count} language files to {output_dir}") + print("Languages available:", [d.name for d in output_dir.iterdir() if d.is_dir()]) + +if __name__ == '__main__': + convert_all_properties() \ No newline at end of file diff --git a/scripts/init-without-ocr.sh b/scripts/init-without-ocr.sh index 73d9feb4a..bbc1a32ec 100644 --- a/scripts/init-without-ocr.sh +++ b/scripts/init-without-ocr.sh @@ -19,9 +19,8 @@ if [[ "$INSTALL_BOOK_AND_ADVANCED_HTML_OPS" == "true" && "$FAT_DOCKER" != "true" #apk add --no-cache calibre@testing fi -if [[ "$FAT_DOCKER" != "true" ]]; then - /scripts/download-security-jar.sh -fi +# Security jar is now built into the application jar during Docker build +# No need to download it separately if [[ -n "$LANGS" ]]; then /scripts/installFonts.sh $LANGS diff --git a/testing/compose/docker-compose-security-with-login.yml b/testing/compose/docker-compose-security-with-login.yml new file mode 100644 index 000000000..feb91b080 --- /dev/null +++ b/testing/compose/docker-compose-security-with-login.yml @@ -0,0 +1,63 @@ +services: + backend: + build: + context: ../.. + dockerfile: docker/backend/Dockerfile + container_name: Stirling-PDF-Security-with-login + restart: on-failure:5 + deploy: + resources: + limits: + memory: 4G + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP'"] + interval: 5s + timeout: 10s + retries: 16 + ports: + - "8080:8080" + volumes: + - ../../stirling/latest/data:/usr/share/tessdata:rw + - ../../stirling/latest/config:/configs:rw + - ../../stirling/latest/logs:/logs:rw + environment: + DISABLE_ADDITIONAL_FEATURES: "false" + DOCKER_ENABLE_SECURITY: "true" + SECURITY_ENABLELOGIN: "true" + SECURITY_INITIALLOGIN_USERNAME: "admin" + SECURITY_INITIALLOGIN_PASSWORD: "stirling" + SYSTEM_DEFAULTLOCALE: en-US + UI_APPNAME: Stirling-PDF + UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest with Security and Login + UI_APPNAMENAVBAR: Stirling-PDF Latest + SYSTEM_MAXFILESIZE: "100" + METRICS_ENABLED: "true" + SYSTEM_GOOGLEVISIBILITY: "true" + SECURITY_CUSTOMGLOBALAPIKEY: "123456789" + SHOW_SURVEY: "true" + networks: + - stirling-network + + frontend: + build: + context: ../.. + dockerfile: docker/frontend/Dockerfile + container_name: stirling-pdf-frontend-security-login + restart: on-failure:5 + ports: + - "3000:80" + environment: + BACKEND_URL: http://backend:8080 + depends_on: + - backend + networks: + - stirling-network + +networks: + stirling-network: + driver: bridge + +volumes: + stirling-data: + stirling-config: + stirling-logs: \ No newline at end of file diff --git a/testing/compose/docker-compose-security.yml b/testing/compose/docker-compose-security.yml new file mode 100644 index 000000000..14aedb697 --- /dev/null +++ b/testing/compose/docker-compose-security.yml @@ -0,0 +1,59 @@ +services: + backend: + build: + context: ../.. + dockerfile: docker/backend/Dockerfile + container_name: Stirling-PDF-Security + restart: on-failure:5 + deploy: + resources: + limits: + memory: 4G + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP'"] + interval: 5s + timeout: 10s + retries: 16 + ports: + - "8080:8080" + volumes: + - ../../stirling/latest/data:/usr/share/tessdata:rw + - ../../stirling/latest/config:/configs:rw + - ../../stirling/latest/logs:/logs:rw + environment: + DISABLE_ADDITIONAL_FEATURES: "false" + SECURITY_ENABLELOGIN: "false" + SYSTEM_DEFAULTLOCALE: en-US + UI_APPNAME: Stirling-PDF + UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest with Security + UI_APPNAMENAVBAR: Stirling-PDF Latest + SYSTEM_MAXFILESIZE: "100" + METRICS_ENABLED: "true" + SYSTEM_GOOGLEVISIBILITY: "true" + SHOW_SURVEY: "true" + networks: + - stirling-network + + frontend: + build: + context: ../.. + dockerfile: docker/frontend/Dockerfile + container_name: stirling-pdf-frontend-security + restart: on-failure:5 + ports: + - "3000:80" + environment: + BACKEND_URL: http://backend:8080 + depends_on: + - backend + networks: + - stirling-network + +networks: + stirling-network: + driver: bridge + +volumes: + stirling-data: + stirling-config: + stirling-logs: \ No newline at end of file diff --git a/exampleYmlFiles/docker-compose-latest-ultra-lite.yml b/testing/compose/docker-compose-ultra-lite.yml similarity index 50% rename from exampleYmlFiles/docker-compose-latest-ultra-lite.yml rename to testing/compose/docker-compose-ultra-lite.yml index a3710ad82..2ea9464a6 100644 --- a/exampleYmlFiles/docker-compose-latest-ultra-lite.yml +++ b/testing/compose/docker-compose-ultra-lite.yml @@ -1,11 +1,14 @@ services: - stirling-pdf: + backend: + build: + context: ../.. + dockerfile: docker/backend/Dockerfile.ultra-lite container_name: Stirling-PDF-Ultra-Lite - image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest-ultra-lite + restart: on-failure:5 deploy: resources: limits: - memory: 1G + memory: 2G healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -qv 'Please sign in'"] interval: 5s @@ -14,10 +17,12 @@ services: ports: - "8080:8080" volumes: - - ./stirling/latest/config:/configs:rw - - ./stirling/latest/logs:/logs:rw + - ../../stirling/latest/config:/configs:rw + - ../../stirling/latest/logs:/logs:rw environment: + DISABLE_ADDITIONAL_FEATURES: "true" SECURITY_ENABLELOGIN: "false" + ENDPOINTS_GROUPS_TO_REMOVE: "CLI" SYSTEM_DEFAULTLOCALE: en-US UI_APPNAME: Stirling-PDF-Ultra-lite UI_HOMEDESCRIPTION: Demo site for Stirling-PDF-Ultra-lite Latest @@ -26,4 +31,29 @@ services: METRICS_ENABLED: "true" SYSTEM_GOOGLEVISIBILITY: "true" SHOW_SURVEY: "true" + networks: + - stirling-network + + frontend: + build: + context: ../.. + dockerfile: docker/frontend/Dockerfile + container_name: stirling-pdf-frontend-ultra-lite restart: on-failure:5 + ports: + - "3000:80" + environment: + BACKEND_URL: http://backend:8080 + depends_on: + - backend + networks: + - stirling-network + +networks: + stirling-network: + driver: bridge + +volumes: + stirling-data: + stirling-config: + stirling-logs: \ No newline at end of file diff --git a/testing/cucumber/features/examples.feature b/testing/cucumber/features/examples.feature index 398a80ce1..a9cf5b41a 100644 --- a/testing/cucumber/features/examples.feature +++ b/testing/cucumber/features/examples.feature @@ -25,7 +25,7 @@ Feature: API Validation | password | wrongPassword | When I send the API request to the endpoint "/api/v1/security/remove-password" Then the response status code should be 500 - And the response should contain error message "Internal Server Error" + And the response should contain error message "Job failed: org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException: Cannot decrypt PDF, the password is incorrect" @positive @info Scenario: Get info diff --git a/testing/test.sh b/testing/test.sh index d4adce375..0876893de 100644 --- a/testing/test.sh +++ b/testing/test.sh @@ -225,8 +225,8 @@ test_compose() { echo "Testing $compose_file configuration..." - # Start up the Docker Compose service - docker-compose -f "$compose_file" up -d + # Start up the Docker Compose service with forced rebuild + docker-compose -f "$compose_file" up -d --build # Wait for the service to become healthy if check_health "$service_name" "$compose_file"; then @@ -276,22 +276,27 @@ main() { EXPECTED_VERSION=$(get_expected_version) echo "Expected version: $EXPECTED_VERSION" - # Building Docker images - # docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t stirlingtools/stirling-pdf:latest -f ./Dockerfile . - docker build --build-arg VERSION_TAG=alpha -t docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest-ultra-lite -f ./Dockerfile.ultra-lite . - # Test each configuration - run_tests "Stirling-PDF-Ultra-Lite" "./exampleYmlFiles/docker-compose-latest-ultra-lite.yml" + run_tests "Stirling-PDF-Ultra-Lite" "./testing/compose/docker-compose-ultra-lite.yml" - echo "Testing webpage accessibility..." - cd "testing" - if ./test_webpages.sh -f webpage_urls.txt -b http://localhost:8080; then - passed_tests+=("Webpage-Accessibility-lite") + echo "Testing basic frontend homepage accessibility..." + if curl -f http://localhost:3000 > /dev/null 2>&1; then + passed_tests+=("Frontend-Homepage-Accessibility-lite") + echo "Frontend homepage accessibility check passed" else - failed_tests+=("Webpage-Accessibility-lite") - echo "Webpage accessibility lite tests failed" + failed_tests+=("Frontend-Homepage-Accessibility-lite") + echo "Frontend homepage accessibility check failed" fi - cd "$PROJECT_ROOT" + + # echo "Testing webpage accessibility..." + # cd "testing" + # if ./test_webpages.sh -f webpage_urls.txt -b http://localhost:8080; then + # passed_tests+=("Webpage-Accessibility-lite") + # else + # failed_tests+=("Webpage-Accessibility-lite") + # echo "Webpage accessibility lite tests failed" + # fi + # cd "$PROJECT_ROOT" echo "Testing version verification..." if verify_app_version "Stirling-PDF-Ultra-Lite" "http://localhost:8080"; then @@ -302,10 +307,11 @@ main() { echo "Version verification failed for Stirling-PDF-Ultra-Lite" fi - docker-compose -f "./exampleYmlFiles/docker-compose-latest-ultra-lite.yml" down - - # run_tests "Stirling-PDF" "./exampleYmlFiles/docker-compose-latest.yml" - # docker-compose -f "./exampleYmlFiles/docker-compose-latest.yml" down + docker-compose -f "./testing/compose/docker-compose-ultra-lite.yml" down + + # Clean up any generated config files + echo "Cleaning up generated config files..." + rm -rf "$PROJECT_ROOT/stirling/" 2>/dev/null || true export DISABLE_ADDITIONAL_FEATURES=false # Run the gradlew build command and check if it fails @@ -319,43 +325,44 @@ main() { EXPECTED_VERSION=$(get_expected_version) echo "Expected version with security enabled: $EXPECTED_VERSION" - # Building Docker images with security enabled - # docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t stirlingtools/stirling-pdf:latest -f ./Dockerfile . - # docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t stirlingtools/stirling-pdf:latest-ultra-lite -f ./Dockerfile.ultra-lite . - docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest-fat -f ./Dockerfile.fat . - - # Test each configuration with security - # run_tests "Stirling-PDF-Ultra-Lite-Security" "./exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml" - # docker-compose -f "./exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml" down - # run_tests "Stirling-PDF-Security" "./exampleYmlFiles/docker-compose-latest-security.yml" - # docker-compose -f "./exampleYmlFiles/docker-compose-latest-security.yml" down + run_tests "Stirling-PDF-Security" "./testing/compose/docker-compose-security.yml" - - run_tests "Stirling-PDF-Security-Fat" "./exampleYmlFiles/docker-compose-latest-fat-security.yml" - - echo "Testing webpage accessibility..." - cd "testing" - if ./test_webpages.sh -f webpage_urls_full.txt -b http://localhost:8080; then - passed_tests+=("Webpage-Accessibility-full") + echo "Testing basic frontend homepage accessibility..." + if curl -f http://localhost:3000 > /dev/null 2>&1; then + passed_tests+=("Frontend-Homepage-Accessibility-full") + echo "Frontend homepage accessibility check passed" else - failed_tests+=("Webpage-Accessibility-full") - echo "Webpage accessibility full tests failed" + failed_tests+=("Frontend-Homepage-Accessibility-full") + echo "Frontend homepage accessibility check failed" fi - cd "$PROJECT_ROOT" + + # echo "Testing webpage accessibility..." + # cd "testing" + # if ./test_webpages.sh -f webpage_urls_full.txt -b http://localhost:8080; then + # passed_tests+=("Webpage-Accessibility-full") + # else + # failed_tests+=("Webpage-Accessibility-full") + # echo "Webpage accessibility full tests failed" + # fi + # cd "$PROJECT_ROOT" echo "Testing version verification..." - if verify_app_version "Stirling-PDF-Security-Fat" "http://localhost:8080"; then - passed_tests+=("Stirling-PDF-Security-Fat-Version-Check") - echo "Version verification passed for Stirling-PDF-Security-Fat" + if verify_app_version "Stirling-PDF-Security" "http://localhost:8080"; then + passed_tests+=("Stirling-PDF-Security-Version-Check") + echo "Version verification passed for Stirling-PDF-Security" else - failed_tests+=("Stirling-PDF-Security-Fat-Version-Check") - echo "Version verification failed for Stirling-PDF-Security-Fat" + failed_tests+=("Stirling-PDF-Security-Version-Check") + echo "Version verification failed for Stirling-PDF-Security" fi - docker-compose -f "./exampleYmlFiles/docker-compose-latest-fat-security.yml" down + docker-compose -f "./testing/compose/docker-compose-security.yml" down + + # Clean up any generated config files + echo "Cleaning up generated config files..." + rm -rf "$PROJECT_ROOT/stirling/" 2>/dev/null || true - run_tests "Stirling-PDF-Security-Fat-with-login" "./exampleYmlFiles/test_cicd.yml" + run_tests "Stirling-PDF-Security-with-login" "./testing/compose/docker-compose-security-with-login.yml" if [ $? -eq 0 ]; then # Create directory for file snapshots if it doesn't exist @@ -368,7 +375,7 @@ main() { DIFF_FILE="$SNAPSHOT_DIR/files_diff.txt" # Define container name variable for consistency - CONTAINER_NAME="Stirling-PDF-Security-Fat-with-login" + CONTAINER_NAME="Stirling-PDF-Security-with-login" capture_file_list "$CONTAINER_NAME" "$BEFORE_FILE" @@ -409,28 +416,12 @@ main() { fi fi - docker-compose -f "./exampleYmlFiles/test_cicd.yml" down + docker-compose -f "./testing/compose/docker-compose-security-with-login.yml" down + + # Clean up any generated config files + echo "Cleaning up generated config files..." + rm -rf "$PROJECT_ROOT/stirling/" 2>/dev/null || true - run_tests "Stirling-PDF-Fat-Disable-Endpoints" "./exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml" - - echo "Testing disabled endpoints..." - if ./testing/test_disabledEndpoints.sh -f ./testing/endpoints.txt -b http://localhost:8080; then - passed_tests+=("Disabled-Endpoints") - else - failed_tests+=("Disabled-Endpoints") - echo "Disabled Endpoints tests failed" - fi - - echo "Testing version verification..." - if verify_app_version "Stirling-PDF-Fat-Disable-Endpoints" "http://localhost:8080"; then - passed_tests+=("Stirling-PDF-Fat-Disable-Endpoints-Version-Check") - echo "Version verification passed for Stirling-PDF-Fat-Disable-Endpoints" - else - failed_tests+=("Stirling-PDF-Fat-Disable-Endpoints-Version-Check") - echo "Version verification failed for Stirling-PDF-Fat-Disable-Endpoints" - fi - - docker-compose -f "./exampleYmlFiles/docker-compose-latest-fat-endpoints-disabled.yml" down # Report results echo "All tests completed in $SECONDS seconds." diff --git a/testing/test2.sh b/testing/test2.sh index b33d2df8c..c8376d288 100644 --- a/testing/test2.sh +++ b/testing/test2.sh @@ -51,29 +51,33 @@ build_and_test() { local dockerfile_name="./Dockerfile" local image_base="stirlingtools/stirling-pdf" local security_suffix="" - local docker_compose_base="./exampleYmlFiles/docker-compose-latest" + local docker_compose_base="./testing/compose/docker-compose" local compose_suffix=".yml" local service_name_base="Stirling-PDF" - if [ "$enable_security" == "true" ]; then - security_suffix="-Security" - docker_compose_base+="-security" # Append to base name for Docker Compose files with security - fi - case "$build_type" in full) - dockerfile_name="./Dockerfile" + dockerfile_name="./docker/backend/Dockerfile" + if [ "$enable_security" == "true" ]; then + compose_file="${docker_compose_base}-fat-security${compose_suffix}" + service_name="Stirling-PDF-Security-Fat" + else + compose_file="${docker_compose_base}-fat${compose_suffix}" + service_name="stirling-pdf-backend-fat" + fi ;; ultra-lite) - dockerfile_name="./Dockerfile.ultra-lite" + dockerfile_name="./docker/backend/Dockerfile.ultra-lite" + if [ "$enable_security" == "true" ]; then + compose_file="${docker_compose_base}-ultra-lite-security${compose_suffix}" + service_name="stirling-pdf-backend-ultra-lite-security" + else + compose_file="${docker_compose_base}-ultra-lite${compose_suffix}" + service_name="Stirling-PDF-Ultra-Lite" + fi ;; esac - # Dynamic image tag and service name based on build type and security - local image_tag="${image_base}:latest${build_type}${security_suffix}" - local service_name="${service_name_base}${build_type^}${security_suffix}" - local compose_file="${docker_compose_base}${build_type}${compose_suffix}" - # Gradle build with or without security echo "Running ./gradlew clean build with security=$enable_security..." ./gradlew clean build @@ -83,10 +87,6 @@ build_and_test() { exit 1 fi - # Building Docker image - echo "Building Docker image $image_tag with Dockerfile $dockerfile_name..." - docker build --build-arg VERSION_TAG=$version_tag -t $image_tag -f $dockerfile_name . - if [ "$run_compose" == "true" ]; then echo "Running Docker Compose for $build_type with security=$enable_security..." docker-compose -f "$compose_file" up -d