phucsd commited on
Commit
b650e2c
·
verified ·
1 Parent(s): 4a83fd1

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +9 -0
  2. ocr_webapp/PaddleOCR/.clang_format.hook +20 -0
  3. ocr_webapp/PaddleOCR/.github/ISSUE_TEMPLATE/bug-report.yml +62 -0
  4. ocr_webapp/PaddleOCR/.github/ISSUE_TEMPLATE/config.yml +11 -0
  5. ocr_webapp/PaddleOCR/.github/ISSUE_TEMPLATE/custom.md +17 -0
  6. ocr_webapp/PaddleOCR/.github/ISSUE_TEMPLATE/newfeature.md +17 -0
  7. ocr_webapp/PaddleOCR/.github/actions/detect-docs-only/action.yml +55 -0
  8. ocr_webapp/PaddleOCR/.github/dependabot.yml +13 -0
  9. ocr_webapp/PaddleOCR/.github/pull_request_template.md +15 -0
  10. ocr_webapp/PaddleOCR/.github/workflows/build_publish_develop_docs.yml +39 -0
  11. ocr_webapp/PaddleOCR/.github/workflows/build_publish_release_docs.yml +41 -0
  12. ocr_webapp/PaddleOCR/.github/workflows/close_inactive_issues.yml +23 -0
  13. ocr_webapp/PaddleOCR/.github/workflows/codestyle.yml +41 -0
  14. ocr_webapp/PaddleOCR/.github/workflows/docs_anchor_check.yml +39 -0
  15. ocr_webapp/PaddleOCR/.github/workflows/link_check.yml +42 -0
  16. ocr_webapp/PaddleOCR/.github/workflows/python-publish.yml +41 -0
  17. ocr_webapp/PaddleOCR/.github/workflows/python_publish.yml +39 -0
  18. ocr_webapp/PaddleOCR/.github/workflows/test_gpu.yml +117 -0
  19. ocr_webapp/PaddleOCR/.github/workflows/tests.yml +108 -0
  20. ocr_webapp/PaddleOCR/.gitignore +34 -0
  21. ocr_webapp/PaddleOCR/.lycheeignore +5 -0
  22. ocr_webapp/PaddleOCR/.pre-commit-config.yaml +42 -0
  23. ocr_webapp/PaddleOCR/.style.yapf +3 -0
  24. ocr_webapp/PaddleOCR/CNAME +1 -0
  25. ocr_webapp/PaddleOCR/__init__.py +21 -0
  26. ocr_webapp/PaddleOCR/api_sdk/README.md +50 -0
  27. ocr_webapp/PaddleOCR/api_sdk/README_cn.md +48 -0
  28. ocr_webapp/PaddleOCR/api_sdk/go/README.md +72 -0
  29. ocr_webapp/PaddleOCR/api_sdk/go/README_cn.md +70 -0
  30. ocr_webapp/PaddleOCR/api_sdk/go/client.go +66 -0
  31. ocr_webapp/PaddleOCR/api_sdk/go/client_test.go +235 -0
  32. ocr_webapp/PaddleOCR/api_sdk/go/doc.go +30 -0
  33. ocr_webapp/PaddleOCR/api_sdk/go/errors.go +103 -0
  34. ocr_webapp/PaddleOCR/api_sdk/go/examples/doc_parsing_file/main.go +61 -0
  35. ocr_webapp/PaddleOCR/api_sdk/go/examples/ocr_url/main.go +43 -0
  36. ocr_webapp/PaddleOCR/api_sdk/go/go.mod +3 -0
  37. ocr_webapp/PaddleOCR/api_sdk/go/models.go +159 -0
  38. ocr_webapp/PaddleOCR/api_sdk/go/ocr.go +317 -0
  39. ocr_webapp/PaddleOCR/api_sdk/go/operation.go +69 -0
  40. ocr_webapp/PaddleOCR/api_sdk/go/options.go +73 -0
  41. ocr_webapp/PaddleOCR/api_sdk/go/poller.go +90 -0
  42. ocr_webapp/PaddleOCR/api_sdk/go/resource.go +267 -0
  43. ocr_webapp/PaddleOCR/api_sdk/go/results.go +74 -0
  44. ocr_webapp/PaddleOCR/api_sdk/go/transport.go +329 -0
  45. ocr_webapp/PaddleOCR/api_sdk/typescript/.gitignore +9 -0
  46. ocr_webapp/PaddleOCR/api_sdk/typescript/README.md +72 -0
  47. ocr_webapp/PaddleOCR/api_sdk/typescript/README_cn.md +70 -0
  48. ocr_webapp/PaddleOCR/api_sdk/typescript/examples/doc-parsing-file.ts +47 -0
  49. ocr_webapp/PaddleOCR/api_sdk/typescript/examples/ocr-url.ts +31 -0
  50. ocr_webapp/PaddleOCR/api_sdk/typescript/package-lock.json +2640 -0
.gitattributes CHANGED
@@ -33,3 +33,12 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ ocr_webapp/data/output/rec_cham_inference/inference.pdiparams filter=lfs diff=lfs merge=lfs -text
37
+ ocr_webapp/data/output/rec_cham_inference_latest/inference.pdiparams filter=lfs diff=lfs merge=lfs -text
38
+ ocr_webapp/data/output/rec_cham_inference_v18/inference.pdiparams filter=lfs diff=lfs merge=lfs -text
39
+ ocr_webapp/data/output/rec_cham_inference_v21/inference.pdiparams filter=lfs diff=lfs merge=lfs -text
40
+ ocr_webapp/data/output/rec_cham_inference_v22/inference.pdiparams filter=lfs diff=lfs merge=lfs -text
41
+ ocr_webapp/data/output/rec_cham_inference_v23/inference.pdiparams filter=lfs diff=lfs merge=lfs -text
42
+ ocr_webapp/data/output/rec_cham_inference_v23/inference.pdiparams.info filter=lfs diff=lfs merge=lfs -text
43
+ ocr_webapp/data/output/rec_cham_inference_v23/inference.pdmodel filter=lfs diff=lfs merge=lfs -text
44
+ ocr_webapp/PaddleOCR/benchmark/PaddleOCR_DBNet/imgs/paper/db.jpg filter=lfs diff=lfs merge=lfs -text
ocr_webapp/PaddleOCR/.clang_format.hook ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ readonly VERSION="13.0.0"
5
+
6
+ version=$(clang-format -version)
7
+
8
+ if ! [[ $(python -V 2>&1 | awk '{print $2}' | awk -F '.' '{print $1$2}') -ge 36 ]]; then
9
+ echo "clang-format installation by pip need python version great equal 3.6,
10
+ please change the default python to higher version."
11
+ exit 1
12
+ fi
13
+
14
+ if ! [[ $version == *"$VERSION"* ]]; then
15
+ # low version of pip may not have the source of clang-format whl
16
+ pip install --upgrade pip
17
+ pip install clang-format==13.0.0
18
+ fi
19
+
20
+ clang-format $@
ocr_webapp/PaddleOCR/.github/ISSUE_TEMPLATE/bug-report.yml ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PaddleOCR
2
+
3
+ name: 🐛 Bug Report
4
+ description: Problems with PaddleOCR
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ Thank you for submitting a PaddleOCR 🐛 Bug Report!
10
+
11
+ - type: checkboxes
12
+ attributes:
13
+ label: 🔎 Search before asking
14
+ description: >
15
+ Please search the PaddleOCR [Docs](https://paddlepaddle.github.io/PaddleOCR/), [Issues](https://github.com/PaddlePaddle/PaddleOCR/issues) and [Discussions](https://github.com/PaddlePaddle/PaddleOCR/discussions) to see if a similar bug report already exists.
16
+ options:
17
+ - label: I have searched the PaddleOCR [Docs](https://paddlepaddle.github.io/PaddleOCR/) and found no similar bug report.
18
+ required: true
19
+ - label: I have searched the PaddleOCR [Issues](https://github.com/PaddlePaddle/PaddleOCR/issues) and found no similar bug report.
20
+ required: true
21
+ - label: I have searched the PaddleOCR [Discussions](https://github.com/PaddlePaddle/PaddleOCR/discussions) and found no similar bug report.
22
+ required: true
23
+
24
+ - type: textarea
25
+ attributes:
26
+ label: 🐛 Bug (问题描述)
27
+ description: Provide console output with error messages and/or screenshots of the bug. (请提供详细报错信息或者截图)
28
+ placeholder: |
29
+ 💡 ProTip! Include as much information as possible (screenshots, logs, tracebacks etc.) to receive the most helpful response.
30
+ validations:
31
+ required: true
32
+
33
+ - type: textarea
34
+ attributes:
35
+ label: 🏃‍♂️ Environment (运行环境)
36
+ description: Please specify the software and hardware you used to produce the bug. (请给出详细依赖包信息,便于复现问题)
37
+ placeholder: |
38
+ ```bash
39
+ OS macOS-13.5.2
40
+ Environment Jupyter
41
+ Python 3.11.2
42
+ PaddleOCR 2.8.1
43
+ Install git
44
+ RAM 16.00 GB
45
+ CPU Apple M2
46
+ CUDA None
47
+ ```
48
+ validations:
49
+ required: true
50
+
51
+ - type: textarea
52
+ attributes:
53
+ label: 🌰 Minimal Reproducible Example (最小可复现问题的Demo)
54
+ description: >
55
+ When asking a question, people will be better able to provide help if you provide code that they can easily understand and use to **reproduce** the problem.
56
+ This is referred to by community members as creating a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). (请务必提供该Demo,这样节省大家时间)
57
+ placeholder: |
58
+ ```bash
59
+ # Code to reproduce your issue here
60
+ ```
61
+ validations:
62
+ required: true
ocr_webapp/PaddleOCR/.github/ISSUE_TEMPLATE/config.yml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: 🙏 Q&A
4
+ url: https://github.com/PaddlePaddle/PaddleOCR/discussions/categories/q-a
5
+ about: Ask the community for help
6
+ - name: 💡 Feature requests and ideas
7
+ url: https://github.com/PaddlePaddle/PaddleOCR/discussions/categories/ideas
8
+ about: Share ideas for new features
9
+ - name: 🙌 Show and tell
10
+ url: https://github.com/PaddlePaddle/PaddleOCR/discussions/categories/show-and-tell
11
+ about: Show off something you've made
ocr_webapp/PaddleOCR/.github/ISSUE_TEMPLATE/custom.md ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: Issue template
3
+ about: Issue template for code error.
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ 请提供下述完整信息以便快速定位问题/Please provide the following information to quickly locate the problem
11
+
12
+ - 系统环境/System Environment:
13
+ - 版本号/Version:Paddle: PaddleOCR: 问题相关组件/Related components:
14
+ - 运行指令/Command Code:
15
+ - 完整报错/Complete Error Message:
16
+
17
+ 请尽量不要包含图片在问题中/Please try to not include the image in the issue.
ocr_webapp/PaddleOCR/.github/ISSUE_TEMPLATE/newfeature.md ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: New Feature Issue template
3
+ about: Issue template for new features.
4
+ title: ''
5
+ labels: 'Code PR is needed'
6
+ assignees: 'shiyutang'
7
+
8
+ ---
9
+
10
+ ## 背景
11
+
12
+ 经过需求征集https://github.com/PaddlePaddle/PaddleOCR/issues/10334 和每周技术研讨会 https://github.com/PaddlePaddle/PaddleOCR/issues/10223 讨论,我们确定了XXXX任务。
13
+
14
+ ## 解决步骤
15
+ 1. 根据开源代码进行网络结构、评估指标转换。代码链接:XXXX
16
+ 2. 结合[论文复现指南](https://github.com/PaddlePaddle/models/blob/release%2F2.2/tutorials/article-implementation/ArticleReproduction_CV.md),进行前反向对齐等操作,达到论文Table.1中的指标。
17
+ 3. 参考[PR提交规范](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.6/doc/doc_ch/code_and_doc.md)提交代码PR到ppocr中。
ocr_webapp/PaddleOCR/.github/actions/detect-docs-only/action.yml ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Detect Docs-Only Change
2
+ description: >
3
+ Output docs_only=true if every changed file in the current pull_request
4
+ matches docs/**, **/*.md, or .github/**. On push or workflow_dispatch,
5
+ always output docs_only=false.
6
+ outputs:
7
+ docs_only:
8
+ description: "true if change is docs-only, otherwise false"
9
+ value: ${{ steps.compute.outputs.docs_only }}
10
+ runs:
11
+ using: composite
12
+ steps:
13
+ - id: compute
14
+ shell: bash
15
+ env:
16
+ GITHUB_EVENT_NAME: ${{ github.event_name }}
17
+ GITHUB_BASE_REF: ${{ github.base_ref }}
18
+ run: |
19
+ set -euo pipefail
20
+ if [ "${GITHUB_EVENT_NAME}" != "pull_request" ]; then
21
+ echo "docs_only=false" >> "$GITHUB_OUTPUT"
22
+ exit 0
23
+ fi
24
+ git fetch origin "${GITHUB_BASE_REF}" --depth=1 >/dev/null 2>&1 || true
25
+ CHANGED_FILES="$(git diff --name-only "origin/${GITHUB_BASE_REF}...HEAD")"
26
+ # >>> matcher-begin
27
+ shopt -s globstar extglob nullglob
28
+ is_docs_only() {
29
+ local files="$1"
30
+ if [ -z "$files" ]; then
31
+ echo "false"; return 0
32
+ fi
33
+ while IFS= read -r f; do
34
+ [ -z "$f" ] && continue
35
+ case "$f" in
36
+ docs/*) ;;
37
+ .github/*) ;;
38
+ *.md) ;;
39
+ *)
40
+ # also accept nested */**/*.md via case glob
41
+ case "$f" in
42
+ */*.md) ;;
43
+ *) echo "false"; return 0 ;;
44
+ esac
45
+ ;;
46
+ esac
47
+ done <<< "$files"
48
+ echo "true"
49
+ }
50
+ result="$(is_docs_only "${CHANGED_FILES}")"
51
+ if [ -n "${GITHUB_OUTPUT:-}" ] && [ "${GITHUB_OUTPUT}" != "/dev/null" ]; then
52
+ echo "docs_only=${result}" >> "$GITHUB_OUTPUT"
53
+ fi
54
+ echo "${result}"
55
+ # <<< matcher-end
ocr_webapp/PaddleOCR/.github/dependabot.yml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Keep GitHub Actions up to date with GitHub's Dependabot...
2
+ # https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
3
+ # https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem
4
+ version: 2
5
+ updates:
6
+ - package-ecosystem: github-actions
7
+ directory: /
8
+ groups:
9
+ github-actions:
10
+ patterns:
11
+ - "*" # Group all Actions updates into a single larger pull request
12
+ schedule:
13
+ interval: weekly
ocr_webapp/PaddleOCR/.github/pull_request_template.md ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### PR 类型 PR types
2
+ <!-- One of [ New features | Bug fixes | Function optimization | Performance optimization | Breaking changes | Others ] -->
3
+
4
+ ### PR 变化内容类型 PR changes
5
+ <!-- One of [ Models | APIs | Docs | Others ] -->
6
+
7
+ ### 描述 Description
8
+ <!-- Describe what this PR does -->
9
+
10
+ ### 提PR之前的检查 Check-list
11
+
12
+ - [ ] 这个 PR 是提交到dygraph分支或者是一个cherry-pick,否则请先提交到dygarph分支。
13
+ This PR is pushed to the dygraph branch or cherry-picked from the dygraph branch. Otherwise, please push your changes to the dygraph branch.
14
+ - [ ] 这个PR清楚描述了功能,帮助评审能提升效率。This PR have fully described what it does such that reviewers can speedup.
15
+ - [ ] 这个PR已经经过本地测试。This PR can be covered by existing tests or locally verified.
ocr_webapp/PaddleOCR/.github/workflows/build_publish_develop_docs.yml ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Build/Publish Develop Docs
2
+ on:
3
+ push:
4
+ branches:
5
+ - master
6
+ - main
7
+ permissions:
8
+ contents: write
9
+ jobs:
10
+ deploy:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v6
14
+ - name: Configure Git Credentials
15
+ run: |
16
+ git config user.name github-actions[bot]
17
+ git config user.email 41898282+github-actions[bot]@users.noreply.github.com
18
+ - uses: actions/setup-python@v6
19
+ with:
20
+ python-version: 3.x
21
+ - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
22
+ - uses: actions/cache@v5
23
+ with:
24
+ key: mkdocs-material-${{ env.cache_id }}
25
+ path: .cache
26
+ restore-keys: |
27
+ mkdocs-material-
28
+ - run: pip install mike mkdocs-material jieba mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-static-i18n markdown-callouts
29
+ - name: Check docs GitHub source links
30
+ run: python tools/check_docs_github_links.py --repo-slug PaddlePaddle/PaddleOCR --forbidden-ref main --forbidden-ref master
31
+ - name: Resolve docs GitHub source refs
32
+ run: python tools/resolve_doc_github_refs.py --placeholder '{{PADDLEOCR_GITHUB_REF}}' --source-ref "${REF_NAME}"
33
+ env:
34
+ REF_NAME: ${{ github.ref_name }}
35
+ - run: |
36
+ git fetch origin gh-pages --depth=1
37
+ mike deploy --push --update-aliases main latest
38
+ env:
39
+ DOCS_EDIT_URI: edit/${{ github.ref_name }}/docs/
ocr_webapp/PaddleOCR/.github/workflows/build_publish_release_docs.yml ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Build/Publish Release Docs
2
+ on:
3
+ push:
4
+ tags:
5
+ - v*
6
+
7
+ permissions:
8
+ contents: write
9
+ jobs:
10
+ deploy:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v6
14
+ - name: Configure Git Credentials
15
+ run: |
16
+ git config user.name github-actions[bot]
17
+ git config user.email github-actions[bot]@users.noreply.github.com
18
+ - uses: actions/setup-python@v6
19
+ with:
20
+ python-version: 3.x
21
+ - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
22
+ - uses: actions/cache@v5
23
+ with:
24
+ key: mkdocs-material-${{ env.cache_id }}
25
+ path: .cache
26
+ restore-keys: |
27
+ mkdocs-material-
28
+ - run: pip install mike mkdocs-material jieba mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-static-i18n markdown-callouts
29
+ - name: Check docs GitHub source links
30
+ run: python tools/check_docs_github_links.py --repo-slug PaddlePaddle/PaddleOCR --forbidden-ref main --forbidden-ref master
31
+ - name: Resolve docs GitHub source refs
32
+ run: python tools/resolve_doc_github_refs.py --placeholder '{{PADDLEOCR_GITHUB_REF}}' --source-ref "${REF_NAME}"
33
+ env:
34
+ REF_NAME: ${{ github.ref_name }}
35
+ - run: |
36
+ git fetch origin gh-pages --depth=1
37
+ mike deploy --push "${REF_NAME}"
38
+
39
+ env:
40
+ REF_NAME: ${{ github.ref_name }}
41
+ DOCS_EDIT_URI: blob/${{ github.ref_name }}/docs/
ocr_webapp/PaddleOCR/.github/workflows/close_inactive_issues.yml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Close inactive issues
2
+ on:
3
+ schedule:
4
+ - cron: "30 1 * * *"
5
+
6
+ jobs:
7
+ close-issues:
8
+ runs-on: ubuntu-latest
9
+ permissions:
10
+ issues: write
11
+ pull-requests: write
12
+ steps:
13
+ - uses: actions/stale@v10
14
+ with:
15
+ days-before-issue-stale: 90
16
+ days-before-issue-close: 14
17
+ stale-issue-label: "stale"
18
+ stale-issue-message: "This issue is stale because it has been open for 90 days with no activity."
19
+ close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
20
+ days-before-pr-stale: -1
21
+ days-before-pr-close: -1
22
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
23
+
ocr_webapp/PaddleOCR/.github/workflows/codestyle.yml ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: PaddleOCR Code Style Check
2
+
3
+ # NOTE: Job name `check-code-style` is the required status check context
4
+ # configured in branch protection. Do not rename without updating settings.
5
+
6
+ on:
7
+ pull_request: {}
8
+ push:
9
+ branches: ['main', 'release/*']
10
+
11
+ jobs:
12
+ check-code-style:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v6
16
+ with:
17
+ ref: ${{ github.ref }}
18
+ fetch-depth: 0
19
+ - id: detect
20
+ uses: ./.github/actions/detect-docs-only
21
+ - uses: actions/setup-python@v6
22
+ if: steps.detect.outputs.docs_only != 'true'
23
+ with:
24
+ python-version: '3.10'
25
+ - name: Cache Python dependencies
26
+ if: steps.detect.outputs.docs_only != 'true'
27
+ uses: actions/cache@v5
28
+ with:
29
+ path: ~/.cache/pip
30
+ key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
31
+ restore-keys: |
32
+ ${{ runner.os }}-pip-
33
+ - name: Install Dependencies for Python
34
+ if: steps.detect.outputs.docs_only != 'true'
35
+ run: |
36
+ python -m pip install --upgrade pip
37
+ pip install "clang-format==13.0.0"
38
+ - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
39
+ if: steps.detect.outputs.docs_only != 'true'
40
+ with:
41
+ extra_args: '--all-files'
ocr_webapp/PaddleOCR/.github/workflows/docs_anchor_check.yml ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Docs Anchor Link Check
2
+
3
+ on:
4
+ pull_request:
5
+ paths:
6
+ - 'docs/**'
7
+ - 'mkdocs.yml'
8
+ - 'mkdocs-ci.yml'
9
+ - 'overrides/**'
10
+
11
+ jobs:
12
+ check-anchor-links:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v6
16
+ with:
17
+ fetch-depth: 1
18
+
19
+ - uses: actions/setup-python@v6
20
+ with:
21
+ python-version: '3.x'
22
+
23
+ - uses: actions/cache@v5
24
+ with:
25
+ path: ~/.cache/pip
26
+ key: ${{ runner.os }}-pip-mkdocs-${{ hashFiles('mkdocs.yml') }}
27
+ restore-keys: |
28
+ ${{ runner.os }}-pip-mkdocs-
29
+
30
+ - name: Install dependencies
31
+ run: pip install mike mkdocs-material jieba mkdocs-git-revision-date-localized-plugin mkdocs-git-committers-plugin-2 mkdocs-static-i18n markdown-callouts
32
+
33
+ - name: Resolve docs GitHub source refs
34
+ run: python tools/resolve_doc_github_refs.py --placeholder '{{PADDLEOCR_GITHUB_REF}}' --source-ref main
35
+
36
+ - name: Check for broken anchor links
37
+ env:
38
+ ENABLE_GIT_PLUGINS: 'false'
39
+ run: mkdocs build -f mkdocs-ci.yml
ocr_webapp/PaddleOCR/.github/workflows/link_check.yml ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Link Checker
2
+
3
+ on:
4
+ repository_dispatch:
5
+ workflow_dispatch:
6
+ # push:
7
+ # branches:
8
+ # - main
9
+ # schedule:
10
+ # - cron: "00 18 * * 6"
11
+
12
+ jobs:
13
+ linkChecker:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v6
17
+
18
+ - uses: actions/setup-python@v6
19
+ with:
20
+ python-version: '3.x'
21
+
22
+ - name: Resolve docs GitHub source refs
23
+ run: python tools/resolve_doc_github_refs.py --placeholder '{{PADDLEOCR_GITHUB_REF}}' --source-ref main
24
+
25
+ - name: Link Checker
26
+ id: lychee
27
+ uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2
28
+ env:
29
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
30
+ with:
31
+ args: --exclude 'docs/index/*.md' 'docs/update/*.md' --verbose --no-progress --max-redirects 8 'docs/**/*.md'
32
+ format: markdown
33
+ fail: false
34
+ output: lychee/results.md
35
+
36
+ - name: Create Issue From File
37
+ if: steps.lychee.outputs.exit_code != 0
38
+ uses: peter-evans/create-issue-from-file@fca9117c27cdc29c6c4db3b86c48e4115a786710 # v6
39
+ with:
40
+ title: Link Checker Report
41
+ content-filepath: ./lychee/results.md
42
+ labels: report, automated issue
ocr_webapp/PaddleOCR/.github/workflows/python-publish.yml ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This workflow will upload a Python Package using Twine when a release is created
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3
+
4
+ # This workflow uses actions that are not certified by GitHub.
5
+ # They are provided by a third-party and are governed by
6
+ # separate terms of service, privacy policy, and support
7
+ # documentation.
8
+
9
+ name: Upload Python Package
10
+
11
+ on:
12
+ release:
13
+ types: [published]
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ deploy:
20
+
21
+ runs-on: ubuntu-latest
22
+
23
+ steps:
24
+ - uses: actions/checkout@v4
25
+ - name: Set up Python
26
+ uses: actions/setup-python@v4
27
+ with:
28
+ python-version: '3.x'
29
+ - name: Install dependencies
30
+ run: |
31
+ python -m pip install --upgrade pip
32
+ pip install build
33
+ pip install setuptools
34
+ pip install wheel
35
+ - name: Build package
36
+ run: python setup.py bdist_wheel
37
+ - name: Publish package
38
+ uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
39
+ with:
40
+ user: __token__
41
+ password: ${{ secrets.PYPI_API_TOKEN }}
ocr_webapp/PaddleOCR/.github/workflows/python_publish.yml ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This workflow will upload a Python Package using Twine when a release is created
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3
+
4
+ # This workflow uses actions that are not certified by GitHub.
5
+ # They are provided by a third-party and are governed by
6
+ # separate terms of service, privacy policy, and support
7
+ # documentation.
8
+
9
+ name: Upload Python Package
10
+
11
+ on:
12
+ release:
13
+ types: [published]
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ deploy:
20
+
21
+ runs-on: ubuntu-latest
22
+
23
+ steps:
24
+ - uses: actions/checkout@v6
25
+ - name: Set up Python
26
+ uses: actions/setup-python@v6
27
+ with:
28
+ python-version: '3.x'
29
+ - name: Install dependencies
30
+ run: |
31
+ python -m pip install --upgrade pip
32
+ pip install build==1.2.2
33
+ - name: Build package
34
+ run: python -m build
35
+ - name: Publish package
36
+ uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
37
+ with:
38
+ user: __token__
39
+ password: ${{ secrets.PYPI_API_TOKEN }}
ocr_webapp/PaddleOCR/.github/workflows/test_gpu.yml ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: PaddleOCR PR Tests GPU
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ pull_request:
7
+ branches: ["main"]
8
+ workflow_dispatch:
9
+ env:
10
+ PR_ID: ${{ github.event.pull_request.number }}
11
+ COMMIT_ID: ${{ github.event.pull_request.head.sha || github.sha }}
12
+ work_dir: /workspace/PaddleOCR
13
+ PADDLENLP_ROOT: /workspace/PaddleOCR
14
+ TASK: paddleocr-CI-${{ github.event.pull_request.number }}
15
+ BRANCH: ${{ github.event.pull_request.base.ref }}
16
+ AGILE_COMPILE_BRANCH: ${{ github.event.pull_request.base.ref }}
17
+ DIR_NAME: ${{ github.repository }}
18
+ permissions:
19
+ contents: read
20
+
21
+ jobs:
22
+ detect-changes:
23
+ runs-on: ubuntu-latest
24
+ outputs:
25
+ docs_only: ${{ steps.detect.outputs.docs_only }}
26
+ steps:
27
+ - uses: actions/checkout@v6
28
+ with:
29
+ fetch-depth: 0
30
+ - id: detect
31
+ uses: ./.github/actions/detect-docs-only
32
+
33
+ test-pr-gpu-impl:
34
+ runs-on: [self-hosted, GPU-2Card-OCR]
35
+ needs: detect-changes
36
+ if: needs.detect-changes.outputs.docs_only != 'true'
37
+ steps:
38
+ - name: run test
39
+ env:
40
+ py_version: "3.10"
41
+ paddle_whl: https://paddle-qa.bj.bcebos.com/paddle-pipeline/Develop-GpuSome-LinuxCentos-Gcc82-Cuda118-Cudnn86-Trt85-Py310-CINN-Compile/latest/paddlepaddle_gpu-0.0.0-cp310-cp310-linux_x86_64.whl
42
+ docker_image: ccr-2vdh3abv-pub.cnc.bj.baidubce.com/paddlepaddle/paddle:latest-dev-cuda11.8-cudnn8.6-trt8.5-gcc82
43
+ run: |
44
+ work_dir=$RANDOM
45
+ mkdir $work_dir
46
+ cd $work_dir
47
+ git clone --depth=1 https://github.com/PaddlePaddle/PaddleOCR.git -b main
48
+ cd PaddleOCR
49
+ if [ -n "${PR_ID}" ]; then
50
+ git fetch origin pull/${PR_ID}/head:ci_build
51
+ git checkout ci_build
52
+ else
53
+ git fetch --depth=1 origin "${COMMIT_ID}"
54
+ git checkout "${COMMIT_ID}"
55
+ fi
56
+ docker run --gpus all --rm -i --name PaddleOCR_CI_$RANDOM \
57
+ --shm-size=128g --net=host \
58
+ -v $PWD:/workspace -w /workspace \
59
+ -e "py_version=${py_version}" \
60
+ -e "paddle_whl=${paddle_whl}" \
61
+ ${docker_image} /bin/bash -c '
62
+ ldconfig;
63
+ nvidia-smi
64
+ df -hl
65
+
66
+ echo ${py_version}
67
+ rm -rf run_env
68
+ mkdir run_env
69
+ ln -s $(which python${py_version}) run_env/python
70
+ ln -s $(which python${py_version}) run_env/python3
71
+ ln -s $(which pip${py_version}) run_env/pip
72
+ export PATH=$PWD/run_env:${PATH}
73
+
74
+ git config --global --add safe.directory /workspace
75
+
76
+ python -m pip install paddlepaddle-gpu==3.1.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu118/
77
+ python -c "import paddle; paddle.version.show()"
78
+ python -m pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
79
+ python -m pip install pytest
80
+ if [ -f requirements.txt ]; then python -m pip install -r requirements.txt; fi
81
+ PADDLEX_SERIES=$(grep -oE "paddlex\[[^]]+\]>=[0-9]+\.[0-9]+" pyproject.toml | head -1 | grep -oE "[0-9]+\.[0-9]+")
82
+ if [ -z "$PADDLEX_SERIES" ]; then
83
+ echo "Failed to determine PaddleX version requirement from pyproject.toml" >&2
84
+ exit 1
85
+ fi
86
+ PADDLEX_BRANCH="release/${PADDLEX_SERIES}"
87
+ echo "Installing PaddleX from branch: ${PADDLEX_BRANCH}"
88
+ python -m pip install -e ".[all]" "paddlex@git+https://github.com/PaddlePaddle/PaddleX.git@${PADDLEX_BRANCH}"
89
+ python -c "import paddlex; print(f\"Installed paddlex version: {paddlex.__version__}\")"
90
+ python -m pytest --verbose tests/
91
+ '
92
+
93
+ # Aggregator: produces a single check named `test-pr-gpu` so branch
94
+ # protection (which requires the literal context `test-pr-gpu`) is satisfied
95
+ # even when the heavy GPU job is skipped (e.g. docs-only changes). Without
96
+ # this, a SKIPPED conclusion on the GPU job leaves the required check
97
+ # unsatisfied and blocks merge.
98
+ test-pr-gpu:
99
+ runs-on: ubuntu-latest
100
+ needs: [detect-changes, test-pr-gpu-impl]
101
+ if: always()
102
+ steps:
103
+ - name: Verify required jobs
104
+ run: |
105
+ if [ "${{ needs.detect-changes.result }}" != "success" ]; then
106
+ echo "detect-changes did not succeed: ${{ needs.detect-changes.result }}"
107
+ exit 1
108
+ fi
109
+ if [ "${{ needs.detect-changes.outputs.docs_only }}" = "true" ]; then
110
+ echo "Docs-only change; treating GPU tests as not required."
111
+ exit 0
112
+ fi
113
+ if [ "${{ needs.test-pr-gpu-impl.result }}" != "success" ]; then
114
+ echo "test-pr-gpu-impl concluded with: ${{ needs.test-pr-gpu-impl.result }}"
115
+ exit 1
116
+ fi
117
+ echo "GPU tests passed."
ocr_webapp/PaddleOCR/.github/workflows/tests.yml ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: PaddleOCR PR Tests
2
+
3
+ on:
4
+ push:
5
+ branches: ["main", "release/*"]
6
+ pull_request:
7
+ branches: ["main", "release/*"]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ detect-changes:
14
+ runs-on: ubuntu-latest
15
+ outputs:
16
+ docs_only: ${{ steps.detect.outputs.docs_only }}
17
+ steps:
18
+ - uses: actions/checkout@v6
19
+ with:
20
+ fetch-depth: 0
21
+ - id: detect
22
+ uses: ./.github/actions/detect-docs-only
23
+
24
+ test-pr-python:
25
+ runs-on: ubuntu-latest
26
+ needs: detect-changes
27
+ if: needs.detect-changes.outputs.docs_only != 'true'
28
+ strategy:
29
+ matrix:
30
+ python-version: ["3.8", "3.9", "3.13"]
31
+
32
+ steps:
33
+ - uses: actions/checkout@v6
34
+ - name: Set up Python ${{ matrix.python-version }}
35
+ uses: actions/setup-python@v6
36
+ with:
37
+ python-version: ${{ matrix.python-version }}
38
+
39
+ - name: Cache dependencies
40
+ uses: actions/cache@v5
41
+ with:
42
+ path: |
43
+ ~/.cache/pip
44
+ ~/.local/lib/python${{ matrix.python-version }}/site-packages
45
+ ~/.paddleocr/
46
+ key: ${{ runner.os }}-dependencies-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt', 'pyproject.toml') }}
47
+ restore-keys: |
48
+ ${{ runner.os }}-dependencies-
49
+
50
+ - name: Install dependencies
51
+ run: |
52
+ python -m pip install --upgrade pip
53
+ pip install pytest
54
+ if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
55
+ # On py3.8 several paddlex transitive deps require py3.9+, so only
56
+ # paddleocr[doc2md] is installable. See installation.md for the
57
+ # supported extras-by-Python-version matrix.
58
+ if [[ "${{ matrix.python-version }}" == "3.8" ]]; then
59
+ python -m pip install paddlepaddle==3.0.0 -i https://www.paddlepaddle.org.cn/packages/stable/cpu/
60
+ PADDLEOCR_EXTRAS="[doc2md]"
61
+ else
62
+ python -m pip install paddlepaddle==3.1.0 -i https://www.paddlepaddle.org.cn/packages/stable/cpu/
63
+ PADDLEOCR_EXTRAS="[all]"
64
+ fi
65
+ PADDLEX_SERIES=$(grep -oE 'paddlex\[[^]]+\]>=[0-9]+\.[0-9]+' pyproject.toml | head -1 | grep -oE '[0-9]+\.[0-9]+')
66
+ if [ -z "$PADDLEX_SERIES" ]; then
67
+ echo "Failed to determine PaddleX version requirement from pyproject.toml" >&2
68
+ exit 1
69
+ fi
70
+
71
+ python -m pip install "paddlex>=3.7.0,<3.8.0"
72
+ PADDLEX_BRANCH="release/${PADDLEX_SERIES}"
73
+ echo "Installing PaddleX from branch: ${PADDLEX_BRANCH}"
74
+ python -m pip install -e ".${PADDLEOCR_EXTRAS}" "paddlex@git+https://github.com/PaddlePaddle/PaddleX.git@${PADDLEX_BRANCH}"
75
+ python -c "import paddlex; print(f'Installed paddlex version: {paddlex.__version__}')"
76
+ - name: Test with pytest
77
+ run: |
78
+ # Skip py38_incompatible tests on py3.8.
79
+ if [[ "${{ matrix.python-version }}" == "3.8" ]]; then
80
+ pytest --verbose tests/ -m "not resource_intensive and not py38_incompatible"
81
+ else
82
+ pytest --verbose tests/
83
+ fi
84
+
85
+ # Aggregator: produces a single check named `test-pr` so branch protection
86
+ # (which requires the literal context `test-pr`) is satisfied. Without this,
87
+ # the matrix above only emits `test-pr (3.x)` checks and the required
88
+ # `test-pr` context never reports.
89
+ test-pr:
90
+ runs-on: ubuntu-latest
91
+ needs: [detect-changes, test-pr-python]
92
+ if: always()
93
+ steps:
94
+ - name: Verify required jobs
95
+ run: |
96
+ if [ "${{ needs.detect-changes.result }}" != "success" ]; then
97
+ echo "detect-changes did not succeed: ${{ needs.detect-changes.result }}"
98
+ exit 1
99
+ fi
100
+ if [ "${{ needs.detect-changes.outputs.docs_only }}" = "true" ]; then
101
+ echo "Docs-only change; skipping python tests."
102
+ exit 0
103
+ fi
104
+ if [ "${{ needs.test-pr-python.result }}" != "success" ]; then
105
+ echo "test-pr-python concluded with: ${{ needs.test-pr-python.result }}"
106
+ exit 1
107
+ fi
108
+ echo "All python matrix variants passed."
ocr_webapp/PaddleOCR/.gitignore ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ .ipynb_checkpoints/
4
+ *.py[cod]
5
+ *$py.class
6
+
7
+ # C extensions
8
+ *.so
9
+
10
+ inference/
11
+ inference_results/
12
+ output/
13
+ train_data/
14
+ log/
15
+ *.DS_Store
16
+ *.vs
17
+ *.user
18
+ *~
19
+ *.vscode
20
+ *.idea
21
+
22
+ *.log
23
+ .clang-format
24
+ .clang_format.hook
25
+
26
+ build/
27
+ dist/
28
+ paddleocr.egg-info/
29
+ /deploy/android_demo/app/OpenCV/
30
+ /deploy/android_demo/app/PaddleLite/
31
+ /deploy/android_demo/app/.cxx/
32
+ /deploy/android_demo/app/cache/
33
+ test_tipc/web/models/
34
+ test_tipc/web/node_modules/
ocr_webapp/PaddleOCR/.lycheeignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ zhuanlan.zhihu.com/*
2
+ https://demo.doctrp.top/
3
+ http://127.0.0.1:8001/
4
+ http://localhost:9003
5
+ https://rrc.cvc.uab.es/
ocr_webapp/PaddleOCR/.pre-commit-config.yaml ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: a11d9314b22d8f8c7556443875b731ef05965464
4
+ hooks:
5
+ - id: check-merge-conflict
6
+ - id: check-symlinks
7
+ - id: detect-private-key
8
+ files: (?!.*paddle)^.*$
9
+ - id: end-of-file-fixer
10
+ files: \.md$
11
+ - id: trailing-whitespace
12
+ files: \.md$
13
+ - repo: https://github.com/Lucas-C/pre-commit-hooks
14
+ rev: v1.0.1
15
+ hooks:
16
+ - id: forbid-crlf
17
+ files: \.md$
18
+ - id: remove-crlf
19
+ files: \.md$
20
+ - id: forbid-tabs
21
+ files: \.md$
22
+ - id: remove-tabs
23
+ files: \.md$
24
+ - repo: local
25
+ hooks:
26
+ - id: clang-format
27
+ name: clang-format
28
+ description: Format files with ClangFormat
29
+ entry: bash .clang_format.hook -i
30
+ language: system
31
+ files: \.(c|cc|cxx|cpp|cu|h|hpp|hxx|cuh|proto)$
32
+ # For Python files
33
+ - repo: https://github.com/psf/black.git
34
+ rev: 23.3.0
35
+ hooks:
36
+ - id: black
37
+ files: (.*\.(py|pyi|bzl)|BUILD|.*\.BUILD|WORKSPACE)$
38
+ - repo: https://github.com/astral-sh/ruff-pre-commit
39
+ rev: v0.2.0
40
+ hooks:
41
+ - id: ruff
42
+ args: [--fix, --exit-non-zero-on-fix, --no-cache]
ocr_webapp/PaddleOCR/.style.yapf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ [style]
2
+ based_on_style = pep8
3
+ column_limit = 80
ocr_webapp/PaddleOCR/CNAME ADDED
@@ -0,0 +1 @@
 
 
1
+ www.paddleocr.ai
ocr_webapp/PaddleOCR/__init__.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from .paddleocr import *
15
+
16
+ __version__ = paddleocr.VERSION
17
+ __all__ = [
18
+ 'PaddleOCR', 'PPStructure', 'draw_ocr', 'draw_structure_result',
19
+ 'save_structure_res', 'download_with_progressbar', 'sorted_layout_boxes',
20
+ 'convert_info_docx', 'to_excel'
21
+ ]
ocr_webapp/PaddleOCR/api_sdk/README.md ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PaddleOCR official API SDKs
2
+
3
+ English | [简体中文](README_cn.md)
4
+
5
+ This directory contains source-adjacent maintainer files for the PaddleOCR
6
+ official API SDKs. The SDKs call hosted PaddleOCR official API services; they do
7
+ not run local PaddleOCR inference or load local models.
8
+
9
+ The official user documentation:
10
+
11
+ - [Overview](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/overview.md)
12
+ - [Python SDK](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/python.md)
13
+ - [TypeScript SDK](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/typescript.md)
14
+ - [Go SDK](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/go.md)
15
+ - [CLI](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/cli.md)
16
+
17
+ ## Maintainer Files
18
+
19
+ | File | Purpose |
20
+ | --- | --- |
21
+ | [`typescript/README.md`](typescript/README.md) | Package-level README for the TypeScript SDK. |
22
+ | [`go/README.md`](go/README.md) | Package-level README for the Go SDK. |
23
+
24
+ The Python SDK is part of the main `paddleocr` package.
25
+
26
+ ## Package Locations
27
+
28
+ | Language | Source location | User docs |
29
+ | --- | --- | --- |
30
+ | Python | [`../paddleocr`](../paddleocr) | [Python SDK](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/python.md) |
31
+ | TypeScript | [`typescript`](typescript) | [TypeScript SDK](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/typescript.md) |
32
+ | Go | [`go`](go) | [Go SDK](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/go.md) |
33
+
34
+ ## Validation
35
+
36
+ Run these from the PaddleOCR repo root directory:
37
+
38
+ ```bash
39
+ # Python
40
+ python -m pytest tests/api_client/
41
+
42
+ # TypeScript
43
+ cd api_sdk/typescript
44
+ npm run lint
45
+ npm test
46
+
47
+ # Go
48
+ cd ../go
49
+ go test ./...
50
+ ```
ocr_webapp/PaddleOCR/api_sdk/README_cn.md ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PaddleOCR 官方 API SDK
2
+
3
+ [English](README.md) | 简体中文
4
+
5
+ 本目录包含 PaddleOCR 官方 API SDK 的源码相邻维护文档。SDK 调用 PaddleOCR 官方 API 托管服务;它们不在本地执行 PaddleOCR 推理,也不加载本地模型。
6
+
7
+ 正式用户文档:
8
+
9
+ - [总览](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/overview.md)
10
+ - [Python SDK](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/python.md)
11
+ - [TypeScript SDK](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/typescript.md)
12
+ - [Go SDK](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/go.md)
13
+ - [CLI](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/cli.md)
14
+
15
+ ## 维护者文件
16
+
17
+ | 文件 | 作用 |
18
+ | --- | --- |
19
+ | [`typescript/README_cn.md`](typescript/README_cn.md) | TypeScript SDK 的包级 README。 |
20
+ | [`go/README_cn.md`](go/README_cn.md) | Go SDK 的包级 README。 |
21
+
22
+ Python SDK 是主 `paddleocr` 包的一部分。
23
+
24
+ ## 包位置
25
+
26
+ | 语言 | 源码位置 | 用户文档 |
27
+ | --- | --- | --- |
28
+ | Python | [`../paddleocr`](../paddleocr) | [Python SDK](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/python.md) |
29
+ | TypeScript | [`typescript`](typescript) | [TypeScript SDK](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/typescript.md) |
30
+ | Go | [`go`](go) | [Go SDK](../docs/version3.x/inference_deployment/serving/paddleocr_official_api/go.md) |
31
+
32
+ ## 验证
33
+
34
+ 在 PaddleOCR 仓库根目录执行:
35
+
36
+ ```bash
37
+ # Python
38
+ python -m pytest tests/api_client/
39
+
40
+ # TypeScript
41
+ cd api_sdk/typescript
42
+ npm run lint
43
+ npm test
44
+
45
+ # Go
46
+ cd ../go
47
+ go test ./...
48
+ ```
ocr_webapp/PaddleOCR/api_sdk/go/README.md ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PaddleOCR Go SDK
2
+
3
+ English | [简体中文](README_cn.md)
4
+
5
+ Go client for the PaddleOCR official API. It submits OCR and document parsing
6
+ jobs to hosted PaddleOCR services; it does not run local PaddleOCR inference or
7
+ load local models.
8
+
9
+ Official user docs:
10
+
11
+ - [Go SDK](../../docs/version3.x/inference_deployment/serving/paddleocr_official_api/go.md)
12
+ - [Go SDK (English)](../../docs/version3.x/inference_deployment/serving/paddleocr_official_api/go.en.md)
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ go get github.com/PaddlePaddle/PaddleOCR/api_sdk/go
18
+ ```
19
+
20
+ Versioned releases use submodule tags such as `api_sdk/go/v0.1.0`.
21
+
22
+ ## Minimal Usage
23
+
24
+ Set `PADDLEOCR_ACCESS_TOKEN` or pass `WithToken` when constructing the client:
25
+
26
+ ```bash
27
+ export PADDLEOCR_ACCESS_TOKEN="your-access-token"
28
+ ```
29
+
30
+ ```go
31
+ client, err := paddleocr.NewClient()
32
+ if err != nil {
33
+ return err
34
+ }
35
+
36
+ result, err := client.OCR(ctx, &paddleocr.OCRRequest{
37
+ Model: paddleocr.PPOCRv5,
38
+ FileURL: "https://example.com/invoice.pdf",
39
+ })
40
+ if err != nil {
41
+ return err
42
+ }
43
+ fmt.Println(result.JobID, len(result.Pages))
44
+ ```
45
+
46
+ Set `Model: paddleocr.PPOCRv6` (or `"PP-OCRv6"`) to use the PP-OCRv6 hosted OCR model.
47
+ Set `Model: paddleocr.PPOCRv5Latin` (or `"PP-OCRv5-latin"`) to use the PP-OCRv5 Latin-script hosted OCR model.
48
+
49
+ Document parsing defaults to PaddleOCR-VL-1.6:
50
+
51
+ ```go
52
+ doc, err := client.ParseDocument(ctx, &paddleocr.DocParsingRequest{
53
+ FilePath: "./report.pdf",
54
+ Options: &paddleocr.PaddleOCRVLOptions{
55
+ UseChartRecognition: paddleocr.Bool(true),
56
+ },
57
+ })
58
+ if err != nil {
59
+ return err
60
+ }
61
+ fmt.Println(doc.JobID, len(doc.Pages))
62
+ ```
63
+
64
+ ## Build And Test
65
+
66
+ ```bash
67
+ go test ./...
68
+ go vet ./...
69
+ go test -race ./...
70
+ ```
71
+
72
+ `go test -race ./...` is recommended before public release.
ocr_webapp/PaddleOCR/api_sdk/go/README_cn.md ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PaddleOCR Go SDK
2
+
3
+ [English](README.md) | 简体中文
4
+
5
+ 面向 PaddleOCR 官方 API 的 Go 客户端。它会把 OCR 和文档解析任务提交到 PaddleOCR 官方托管服务;不会运行本地 PaddleOCR 推理,也不会加载本地模型。
6
+
7
+ 正式用户文档:
8
+
9
+ - [Go SDK](../../docs/version3.x/inference_deployment/serving/paddleocr_official_api/go.md)
10
+ - [Go SDK(英文)](../../docs/version3.x/inference_deployment/serving/paddleocr_official_api/go.en.md)
11
+
12
+ ## 安装
13
+
14
+ ```bash
15
+ go get github.com/PaddlePaddle/PaddleOCR/api_sdk/go
16
+ ```
17
+
18
+ 版本化发布使用 `api_sdk/go/v0.1.0` 这类子目录 module tag。
19
+
20
+ ## 最小示例
21
+
22
+ 设置 `PADDLEOCR_ACCESS_TOKEN`,或在构造客户端时传入 `WithToken`:
23
+
24
+ ```bash
25
+ export PADDLEOCR_ACCESS_TOKEN="your-access-token"
26
+ ```
27
+
28
+ ```go
29
+ client, err := paddleocr.NewClient()
30
+ if err != nil {
31
+ return err
32
+ }
33
+
34
+ result, err := client.OCR(ctx, &paddleocr.OCRRequest{
35
+ Model: paddleocr.PPOCRv5,
36
+ FileURL: "https://example.com/invoice.pdf",
37
+ })
38
+ if err != nil {
39
+ return err
40
+ }
41
+ fmt.Println(result.JobID, len(result.Pages))
42
+ ```
43
+
44
+ 将 `Model` 设为 `paddleocr.PPOCRv6`(或 `"PP-OCRv6"`)可使用 PP-OCRv6 云端 OCR 模型。
45
+ 将 `Model` 设为 `paddleocr.PPOCRv5Latin`(或 `"PP-OCRv5-latin"`)可使用 PP-OCRv5 拉丁语系云端 OCR 模型。
46
+
47
+ 文档解析默认使用 PaddleOCR-VL-1.6:
48
+
49
+ ```go
50
+ doc, err := client.ParseDocument(ctx, &paddleocr.DocParsingRequest{
51
+ FilePath: "./report.pdf",
52
+ Options: &paddleocr.PaddleOCRVLOptions{
53
+ UseChartRecognition: paddleocr.Bool(true),
54
+ },
55
+ })
56
+ if err != nil {
57
+ return err
58
+ }
59
+ fmt.Println(doc.JobID, len(doc.Pages))
60
+ ```
61
+
62
+ ## 构建与测试
63
+
64
+ ```bash
65
+ go test ./...
66
+ go vet ./...
67
+ go test -race ./...
68
+ ```
69
+
70
+ 公开发布前建议运行 `go test -race ./...`。
ocr_webapp/PaddleOCR/api_sdk/go/client.go ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ package paddleocr
16
+
17
+ import (
18
+ "net/http"
19
+ "os"
20
+ "strings"
21
+ "time"
22
+ )
23
+
24
+ type Client struct {
25
+ token string
26
+ baseURL string
27
+ jobsURL string
28
+ requestTimeout time.Duration
29
+ pollTimeout time.Duration
30
+ clientPlatform string
31
+ httpClient *http.Client
32
+ }
33
+
34
+ func NewClient(opts ...ClientOption) (*Client, error) {
35
+ c := &Client{
36
+ requestTimeout: 5 * time.Minute,
37
+ pollTimeout: 10 * time.Minute,
38
+ }
39
+ for _, opt := range opts {
40
+ opt(c)
41
+ }
42
+ if c.token == "" {
43
+ c.token = os.Getenv("PADDLEOCR_ACCESS_TOKEN")
44
+ }
45
+ if c.token == "" {
46
+ return nil, &AuthError{PaddleOCRAPIError{Message: "Token is required. Set PADDLEOCR_ACCESS_TOKEN or use WithToken()."}}
47
+ }
48
+ if c.baseURL == "" {
49
+ c.baseURL = os.Getenv("PADDLEOCR_BASE_URL")
50
+ }
51
+ if c.baseURL == "" {
52
+ c.baseURL = DefaultBaseURL
53
+ }
54
+ c.baseURL = strings.TrimRight(c.baseURL, "/")
55
+ c.jobsURL = c.baseURL + apiPath
56
+ if c.httpClient == nil {
57
+ c.httpClient = &http.Client{Timeout: c.requestTimeout}
58
+ }
59
+ return c, nil
60
+ }
61
+
62
+ func (c *Client) setClientPlatformHeader(req *http.Request) {
63
+ if c.clientPlatform != "" {
64
+ req.Header.Set("Client-Platform", c.clientPlatform)
65
+ }
66
+ }
ocr_webapp/PaddleOCR/api_sdk/go/client_test.go ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package paddleocr
2
+
3
+ import (
4
+ "context"
5
+ "encoding/json"
6
+ "net/http"
7
+ "net/http/httptest"
8
+ "testing"
9
+ )
10
+
11
+ func TestClientPlatformHeader(t *testing.T) {
12
+ var got string
13
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
14
+ got = r.Header.Get("Client-Platform")
15
+ w.Header().Set("Content-Type", "application/json")
16
+ _ = json.NewEncoder(w).Encode(map[string]interface{}{
17
+ "code": 0,
18
+ "data": map[string]string{"jobId": "job-1"},
19
+ })
20
+ }))
21
+ defer server.Close()
22
+
23
+ client, err := NewClient(
24
+ WithToken("token"),
25
+ WithBaseURL(server.URL),
26
+ WithClientPlatform("my-app"),
27
+ )
28
+ if err != nil {
29
+ t.Fatalf("NewClient() error = %v", err)
30
+ }
31
+
32
+ job, err := client.SubmitOCR(context.Background(), &OCRRequest{
33
+ FileURL: "https://example.test/input.pdf",
34
+ })
35
+ if err != nil {
36
+ t.Fatalf("SubmitOCR() error = %v", err)
37
+ }
38
+ if job.JobID != "job-1" {
39
+ t.Fatalf("JobID = %q, want job-1", job.JobID)
40
+ }
41
+ if got != "my-app" {
42
+ t.Fatalf("Client-Platform = %q, want my-app", got)
43
+ }
44
+ }
45
+
46
+ func TestDocumentParsingOptionsIncludeCurrentAndFutureServiceParameters(t *testing.T) {
47
+ trueValue := true
48
+ falseValue := false
49
+ var got map[string]interface{}
50
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
51
+ var body struct {
52
+ OptionalPayload map[string]interface{} `json:"optionalPayload"`
53
+ }
54
+ if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
55
+ t.Fatalf("Decode request body error = %v", err)
56
+ }
57
+ got = body.OptionalPayload
58
+ w.Header().Set("Content-Type", "application/json")
59
+ _ = json.NewEncoder(w).Encode(map[string]interface{}{
60
+ "code": 0,
61
+ "data": map[string]string{"jobId": "job-doc"},
62
+ })
63
+ }))
64
+ defer server.Close()
65
+
66
+ client, err := NewClient(
67
+ WithToken("token"),
68
+ WithBaseURL(server.URL),
69
+ )
70
+ if err != nil {
71
+ t.Fatalf("NewClient() error = %v", err)
72
+ }
73
+
74
+ _, err = client.SubmitDocumentParsing(context.Background(), &DocParsingRequest{
75
+ Model: PaddleOCRVL16,
76
+ FileURL: "https://example.test/doc.pdf",
77
+ Options: &PaddleOCRVLOptions{
78
+ UseOcrForImageBlock: &trueValue,
79
+ FormatBlockContent: &trueValue,
80
+ MarkdownIgnoreLabels: []string{"image"},
81
+ VlmExtraArgs: map[string]interface{}{"temperature": 0.1},
82
+ ReturnMarkdownImages: &falseValue,
83
+ OutputFormats: []string{"docx"},
84
+ ExtraOptions: map[string]interface{}{"futureOption": "enabled"},
85
+ },
86
+ })
87
+ if err != nil {
88
+ t.Fatalf("SubmitDocumentParsing() error = %v", err)
89
+ }
90
+
91
+ if got["useOcrForImageBlock"] != true || got["formatBlockContent"] != true {
92
+ t.Fatalf("got boolean options %#v", got)
93
+ }
94
+ if got["returnMarkdownImages"] != false || got["futureOption"] != "enabled" {
95
+ t.Fatalf("got passthrough options %#v", got)
96
+ }
97
+ }
98
+
99
+ func TestResultParsersPreserveRawFieldsAndDataInfo(t *testing.T) {
100
+ ocrLine := map[string]interface{}{
101
+ "result": map[string]interface{}{
102
+ "dataInfo": map[string]interface{}{"numPages": float64(1)},
103
+ "ocrResults": []interface{}{
104
+ map[string]interface{}{
105
+ "prunedResult": map[string]interface{}{"text": "hello"},
106
+ "ocrImage": "ocr.png",
107
+ "docPreprocessingImage": "pre.png",
108
+ "inputImage": "input.png",
109
+ },
110
+ },
111
+ },
112
+ }
113
+ ocrResult, err := parseOCRResult("job-ocr", []map[string]interface{}{ocrLine})
114
+ if err != nil {
115
+ t.Fatalf("parseOCRResult() error = %v", err)
116
+ }
117
+ if ocrResult.DataInfo["numPages"] != float64(1) {
118
+ t.Fatalf("OCR metadata not preserved: %#v", ocrResult)
119
+ }
120
+ if ocrResult.Pages[0].DocPreprocessingImageURL != "pre.png" || ocrResult.Pages[0].InputImageURL != "input.png" {
121
+ t.Fatalf("OCR page image URLs not preserved: %#v", ocrResult.Pages[0])
122
+ }
123
+ if ocrResult.Pages[0].Raw["ocrImage"] != "ocr.png" {
124
+ t.Fatalf("OCR raw page not preserved: %#v", ocrResult.Pages[0].Raw)
125
+ }
126
+
127
+ docPage := map[string]interface{}{
128
+ "prunedResult": map[string]interface{}{"blocks": []interface{}{map[string]interface{}{"label": "text"}}},
129
+ "markdown": map[string]interface{}{"text": "hello", "images": map[string]interface{}{"figure.png": "figure-url"}, "isStart": true},
130
+ "outputImages": map[string]interface{}{"page.png": "page-url"},
131
+ "inputImage": "input.png",
132
+ "exports": map[string]interface{}{"docx": "docx-url"},
133
+ }
134
+ docLine := map[string]interface{}{
135
+ "result": map[string]interface{}{
136
+ "dataInfo": map[string]interface{}{"numPages": float64(1)},
137
+ "layoutParsingResults": []interface{}{docPage},
138
+ },
139
+ }
140
+ docResult, err := parseDocParsingResult("job-doc", []map[string]interface{}{docLine})
141
+ if err != nil {
142
+ t.Fatalf("parseDocParsingResult() error = %v", err)
143
+ }
144
+ if docResult.DataInfo["numPages"] != float64(1) {
145
+ t.Fatalf("document metadata not preserved: %#v", docResult)
146
+ }
147
+ if docResult.Pages[0].PrunedResult == nil || docResult.Pages[0].Raw["inputImage"] != "input.png" {
148
+ t.Fatalf("document page raw fields not preserved: %#v", docResult.Pages[0])
149
+ }
150
+ if docResult.Pages[0].Exports["docx"] != "docx-url" || docResult.Pages[0].Markdown["isStart"] != true {
151
+ t.Fatalf("document structured fields not preserved: %#v", docResult.Pages[0])
152
+ }
153
+ }
154
+
155
+ func TestSubmitOCRAcceptsOfficialModelNameString(t *testing.T) {
156
+ var got string
157
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
158
+ var body struct {
159
+ Model string `json:"model"`
160
+ }
161
+ if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
162
+ t.Fatalf("Decode request body error = %v", err)
163
+ }
164
+ got = body.Model
165
+ w.Header().Set("Content-Type", "application/json")
166
+ _ = json.NewEncoder(w).Encode(map[string]interface{}{
167
+ "code": 0,
168
+ "data": map[string]string{"jobId": "job-1"},
169
+ })
170
+ }))
171
+ defer server.Close()
172
+
173
+ client, err := NewClient(
174
+ WithToken("token"),
175
+ WithBaseURL(server.URL),
176
+ )
177
+ if err != nil {
178
+ t.Fatalf("NewClient() error = %v", err)
179
+ }
180
+
181
+ job, err := client.SubmitOCR(context.Background(), &OCRRequest{
182
+ Model: "PP-OCRv5",
183
+ FileURL: "https://example.test/input.pdf",
184
+ })
185
+ if err != nil {
186
+ t.Fatalf("SubmitOCR() error = %v", err)
187
+ }
188
+ if job.Model != "PP-OCRv5" {
189
+ t.Fatalf("Job model = %q, want PP-OCRv5", job.Model)
190
+ }
191
+ if got != "PP-OCRv5" {
192
+ t.Fatalf("Request model = %q, want PP-OCRv5", got)
193
+ }
194
+ }
195
+
196
+ func TestSubmitOCRAcceptsPPOCRv5LatinModelNameString(t *testing.T) {
197
+ var got string
198
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
199
+ var body struct {
200
+ Model string `json:"model"`
201
+ }
202
+ if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
203
+ t.Fatalf("Decode request body error = %v", err)
204
+ }
205
+ got = body.Model
206
+ w.Header().Set("Content-Type", "application/json")
207
+ _ = json.NewEncoder(w).Encode(map[string]interface{}{
208
+ "code": 0,
209
+ "data": map[string]string{"jobId": "job-latin"},
210
+ })
211
+ }))
212
+ defer server.Close()
213
+
214
+ client, err := NewClient(
215
+ WithToken("token"),
216
+ WithBaseURL(server.URL),
217
+ )
218
+ if err != nil {
219
+ t.Fatalf("NewClient() error = %v", err)
220
+ }
221
+
222
+ job, err := client.SubmitOCR(context.Background(), &OCRRequest{
223
+ Model: PPOCRv5Latin,
224
+ FileURL: "https://example.test/latin.pdf",
225
+ })
226
+ if err != nil {
227
+ t.Fatalf("SubmitOCR() error = %v", err)
228
+ }
229
+ if job.Model != PPOCRv5Latin {
230
+ t.Fatalf("Job model = %q, want %s", job.Model, PPOCRv5Latin)
231
+ }
232
+ if got != PPOCRv5Latin {
233
+ t.Fatalf("Request model = %q, want %s", got, PPOCRv5Latin)
234
+ }
235
+ }
ocr_webapp/PaddleOCR/api_sdk/go/doc.go ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ // Package paddleocr provides a Go client for the PaddleOCR official API.
16
+ //
17
+ // Create a client with NewClient and authenticate with WithToken or the
18
+ // PADDLEOCR_ACCESS_TOKEN environment variable. Use OCR for supported OCR models
19
+ // and ParseDocument for document parsing models.
20
+ // SubmitOCR and SubmitDocumentParsing return an Operation for non-blocking
21
+ // status checks with Poll or typed waits with WaitOCR and WaitDocumentParsing.
22
+ // SaveResource downloads one result resource URL. SaveOCRResultResources and
23
+ // SaveDocumentParsingResultResources save resources from typed result objects
24
+ // into an existing directory.
25
+ //
26
+ // Request timeout and polling timeout are configured separately with
27
+ // WithRequestTimeout and WithPollTimeout. Errors are exposed as typed values,
28
+ // such as AuthError, InvalidRequestError, APIError, ResponseFormatError, and
29
+ // ResultParseError, and are suitable for errors.As.
30
+ package paddleocr
ocr_webapp/PaddleOCR/api_sdk/go/errors.go ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ package paddleocr
16
+
17
+ import "fmt"
18
+
19
+ type PaddleOCRAPIError struct {
20
+ Message string
21
+ Cause error
22
+ }
23
+
24
+ func (e *PaddleOCRAPIError) Error() string {
25
+ if e.Message == "" && e.Cause != nil {
26
+ return e.Cause.Error()
27
+ }
28
+ return e.Message
29
+ }
30
+
31
+ func (e *PaddleOCRAPIError) Unwrap() error {
32
+ return e.Cause
33
+ }
34
+
35
+ type AuthError struct {
36
+ PaddleOCRAPIError
37
+ }
38
+
39
+ type InvalidRequestError struct {
40
+ PaddleOCRAPIError
41
+ }
42
+
43
+ type APIError struct {
44
+ StatusCode int
45
+ PaddleOCRAPIError
46
+ }
47
+
48
+ func (e *APIError) Error() string {
49
+ return fmt.Sprintf("HTTP %d: %s", e.StatusCode, e.Message)
50
+ }
51
+
52
+ type RateLimitError struct {
53
+ APIError
54
+ }
55
+
56
+ type ServiceUnavailableError struct {
57
+ APIError
58
+ }
59
+
60
+ type JobFailedError struct {
61
+ JobID string
62
+ ErrorMsg string
63
+ PaddleOCRAPIError
64
+ }
65
+
66
+ func (e *JobFailedError) Error() string {
67
+ return fmt.Sprintf("Job %s failed: %s", e.JobID, e.ErrorMsg)
68
+ }
69
+
70
+ type RequestTimeoutError struct {
71
+ PaddleOCRAPIError
72
+ }
73
+
74
+ type PollTimeoutError struct {
75
+ JobID string
76
+ Elapsed float64
77
+ PaddleOCRAPIError
78
+ }
79
+
80
+ func (e *PollTimeoutError) Error() string {
81
+ return fmt.Sprintf("Timed out after %.1fs waiting for job %s", e.Elapsed, e.JobID)
82
+ }
83
+
84
+ type NetworkError struct {
85
+ PaddleOCRAPIError
86
+ }
87
+
88
+ type FileNotFoundError struct {
89
+ Path string
90
+ PaddleOCRAPIError
91
+ }
92
+
93
+ func (e *FileNotFoundError) Error() string {
94
+ return fmt.Sprintf("File not found: %s", e.Path)
95
+ }
96
+
97
+ type ResponseFormatError struct {
98
+ PaddleOCRAPIError
99
+ }
100
+
101
+ type ResultParseError struct {
102
+ PaddleOCRAPIError
103
+ }
ocr_webapp/PaddleOCR/api_sdk/go/examples/doc_parsing_file/main.go ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ package main
16
+
17
+ import (
18
+ "context"
19
+ "fmt"
20
+ "log"
21
+
22
+ paddleocr "github.com/PaddlePaddle/PaddleOCR/api_sdk/go"
23
+ )
24
+
25
+ func main() {
26
+ client, err := paddleocr.NewClient()
27
+ if err != nil {
28
+ log.Fatal(err)
29
+ }
30
+ ctx := context.Background()
31
+
32
+ // Convenience method (blocks until done)
33
+ result, err := client.ParseDocument(ctx, &paddleocr.DocParsingRequest{
34
+ Model: paddleocr.PPStructureV3,
35
+ FilePath: "./sample.pdf",
36
+ Options: &paddleocr.PPStructureV3Options{UseChartRecognition: paddleocr.Bool(true)},
37
+ })
38
+ if err != nil {
39
+ log.Fatal(err)
40
+ }
41
+ for i, page := range result.Pages {
42
+ fmt.Printf("Page %d:\n%s\n", i+1, page.MarkdownText)
43
+ }
44
+
45
+ // Manual control with typed job metadata and typed wait methods.
46
+ ocrJob, _ := client.SubmitOCR(ctx, &paddleocr.OCRRequest{FileURL: "https://example.com/f1.pdf"})
47
+ docJob, _ := client.SubmitDocumentParsing(ctx, &paddleocr.DocParsingRequest{
48
+ Model: paddleocr.PPStructureV3, FilePath: "./sample.pdf",
49
+ })
50
+
51
+ ocrResult, err := client.WaitOCRResult(ctx, ocrJob.JobID)
52
+ if err != nil {
53
+ log.Printf("OCR job error: %v", err)
54
+ }
55
+ docResult, err := client.WaitDocumentParsingResult(ctx, docJob.JobID)
56
+ if err != nil {
57
+ log.Printf("document parsing job error: %v", err)
58
+ }
59
+ fmt.Printf("OCR done: %v\n", ocrResult)
60
+ fmt.Printf("Document parsing done: %v\n", docResult)
61
+ }
ocr_webapp/PaddleOCR/api_sdk/go/examples/ocr_url/main.go ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ package main
16
+
17
+ import (
18
+ "context"
19
+ "fmt"
20
+ "log"
21
+
22
+ paddleocr "github.com/PaddlePaddle/PaddleOCR/api_sdk/go"
23
+ )
24
+
25
+ func main() {
26
+ client, err := paddleocr.NewClient()
27
+ if err != nil {
28
+ log.Fatal(err)
29
+ }
30
+ ctx := context.Background()
31
+
32
+ result, err := client.OCR(ctx, &paddleocr.OCRRequest{
33
+ FileURL: "https://example.com/invoice.pdf",
34
+ })
35
+ if err != nil {
36
+ log.Fatal(err)
37
+ }
38
+
39
+ for i, page := range result.Pages {
40
+ fmt.Printf("Page %d: %v\n", i+1, page.PrunedResult)
41
+ fmt.Printf(" Image URL: %s\n", page.OCRImageURL)
42
+ }
43
+ }
ocr_webapp/PaddleOCR/api_sdk/go/go.mod ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ module github.com/PaddlePaddle/PaddleOCR/api_sdk/go
2
+
3
+ go 1.21
ocr_webapp/PaddleOCR/api_sdk/go/models.go ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ package paddleocr
16
+
17
+ const (
18
+ PPOCRv5 = "PP-OCRv5"
19
+ PPOCRv5Latin = "PP-OCRv5-latin"
20
+ PPOCRv6 = "PP-OCRv6"
21
+ PPStructureV3 = "PP-StructureV3"
22
+ PaddleOCRVL = "PaddleOCR-VL"
23
+ PaddleOCRVL15 = "PaddleOCR-VL-1.5"
24
+ PaddleOCRVL16 = "PaddleOCR-VL-1.6"
25
+ )
26
+
27
+ // IsOCRModel reports whether model is supported by OCR APIs.
28
+ func IsOCRModel(model string) bool {
29
+ return model == PPOCRv5 || model == PPOCRv5Latin || model == PPOCRv6
30
+ }
31
+
32
+ // IsDocumentParsingModel reports whether model is supported by document parsing APIs.
33
+ func IsDocumentParsingModel(model string) bool {
34
+ switch model {
35
+ case PPStructureV3, PaddleOCRVL, PaddleOCRVL15, PaddleOCRVL16:
36
+ return true
37
+ default:
38
+ return false
39
+ }
40
+ }
41
+
42
+ // IsVLModel reports whether model is a PaddleOCR-VL family model.
43
+ func IsVLModel(model string) bool {
44
+ switch model {
45
+ case PaddleOCRVL, PaddleOCRVL15, PaddleOCRVL16:
46
+ return true
47
+ default:
48
+ return false
49
+ }
50
+ }
51
+
52
+ type OCROptions struct {
53
+ UseDocOrientationClassify *bool `json:"useDocOrientationClassify,omitempty"`
54
+ UseDocUnwarping *bool `json:"useDocUnwarping,omitempty"`
55
+ UseTextlineOrientation *bool `json:"useTextlineOrientation,omitempty"`
56
+ TextDetLimitSideLen *int `json:"textDetLimitSideLen,omitempty"`
57
+ TextDetLimitType *string `json:"textDetLimitType,omitempty"`
58
+ TextDetThresh *float64 `json:"textDetThresh,omitempty"`
59
+ TextDetBoxThresh *float64 `json:"textDetBoxThresh,omitempty"`
60
+ TextDetUnclipRatio *float64 `json:"textDetUnclipRatio,omitempty"`
61
+ TextRecScoreThresh *float64 `json:"textRecScoreThresh,omitempty"`
62
+ Visualize *bool `json:"visualize,omitempty"`
63
+ ExtraOptions map[string]interface{} `json:"-"`
64
+ }
65
+
66
+ type PPStructureV3Options struct {
67
+ UseDocOrientationClassify *bool `json:"useDocOrientationClassify,omitempty"`
68
+ UseDocUnwarping *bool `json:"useDocUnwarping,omitempty"`
69
+ UseTextlineOrientation *bool `json:"useTextlineOrientation,omitempty"`
70
+ UseSealRecognition *bool `json:"useSealRecognition,omitempty"`
71
+ UseTableRecognition *bool `json:"useTableRecognition,omitempty"`
72
+ UseFormulaRecognition *bool `json:"useFormulaRecognition,omitempty"`
73
+ UseChartRecognition *bool `json:"useChartRecognition,omitempty"`
74
+ UseRegionDetection *bool `json:"useRegionDetection,omitempty"`
75
+ LayoutThreshold interface{} `json:"layoutThreshold,omitempty"`
76
+ LayoutNms *bool `json:"layoutNms,omitempty"`
77
+ LayoutUnclipRatio interface{} `json:"layoutUnclipRatio,omitempty"`
78
+ LayoutMergeBboxesMode interface{} `json:"layoutMergeBboxesMode,omitempty"`
79
+ FormatBlockContent *bool `json:"formatBlockContent,omitempty"`
80
+ TextDetLimitSideLen *int `json:"textDetLimitSideLen,omitempty"`
81
+ TextDetLimitType *string `json:"textDetLimitType,omitempty"`
82
+ TextDetThresh *float64 `json:"textDetThresh,omitempty"`
83
+ TextDetBoxThresh *float64 `json:"textDetBoxThresh,omitempty"`
84
+ TextDetUnclipRatio *float64 `json:"textDetUnclipRatio,omitempty"`
85
+ TextRecScoreThresh *float64 `json:"textRecScoreThresh,omitempty"`
86
+ UseWiredTableCellsTransToHtml *bool `json:"useWiredTableCellsTransToHtml,omitempty"`
87
+ UseWirelessTableCellsTransToHtml *bool `json:"useWirelessTableCellsTransToHtml,omitempty"`
88
+ UseTableOrientationClassify *bool `json:"useTableOrientationClassify,omitempty"`
89
+ UseOcrResultsWithTableCells *bool `json:"useOcrResultsWithTableCells,omitempty"`
90
+ UseE2eWiredTableRecModel *bool `json:"useE2eWiredTableRecModel,omitempty"`
91
+ UseE2eWirelessTableRecModel *bool `json:"useE2eWirelessTableRecModel,omitempty"`
92
+ MarkdownIgnoreLabels []string `json:"markdownIgnoreLabels,omitempty"`
93
+ PrettifyMarkdown *bool `json:"prettifyMarkdown,omitempty"`
94
+ ShowFormulaNumber *bool `json:"showFormulaNumber,omitempty"`
95
+ ReturnMarkdownImages *bool `json:"returnMarkdownImages,omitempty"`
96
+ OutputFormats []string `json:"outputFormats,omitempty"`
97
+ Visualize *bool `json:"visualize,omitempty"`
98
+ ExtraOptions map[string]interface{} `json:"-"`
99
+ }
100
+
101
+ type PaddleOCRVLOptions struct {
102
+ UseDocOrientationClassify *bool `json:"useDocOrientationClassify,omitempty"`
103
+ UseDocUnwarping *bool `json:"useDocUnwarping,omitempty"`
104
+ UseLayoutDetection *bool `json:"useLayoutDetection,omitempty"`
105
+ UseChartRecognition *bool `json:"useChartRecognition,omitempty"`
106
+ UseSealRecognition *bool `json:"useSealRecognition,omitempty"`
107
+ UseOcrForImageBlock *bool `json:"useOcrForImageBlock,omitempty"`
108
+ LayoutThreshold interface{} `json:"layoutThreshold,omitempty"`
109
+ LayoutNms *bool `json:"layoutNms,omitempty"`
110
+ LayoutUnclipRatio interface{} `json:"layoutUnclipRatio,omitempty"`
111
+ LayoutMergeBboxesMode interface{} `json:"layoutMergeBboxesMode,omitempty"`
112
+ LayoutShapeMode *string `json:"layoutShapeMode,omitempty"`
113
+ PromptLabel *string `json:"promptLabel,omitempty"`
114
+ FormatBlockContent *bool `json:"formatBlockContent,omitempty"`
115
+ RepetitionPenalty *float64 `json:"repetitionPenalty,omitempty"`
116
+ Temperature *float64 `json:"temperature,omitempty"`
117
+ TopP *float64 `json:"topP,omitempty"`
118
+ MinPixels *int `json:"minPixels,omitempty"`
119
+ MaxPixels *int `json:"maxPixels,omitempty"`
120
+ MaxNewTokens *int `json:"maxNewTokens,omitempty"`
121
+ VlmExtraArgs map[string]interface{} `json:"vlmExtraArgs,omitempty"`
122
+ MergeLayoutBlocks *bool `json:"mergeLayoutBlocks,omitempty"`
123
+ MarkdownIgnoreLabels []string `json:"markdownIgnoreLabels,omitempty"`
124
+ PrettifyMarkdown *bool `json:"prettifyMarkdown,omitempty"`
125
+ ShowFormulaNumber *bool `json:"showFormulaNumber,omitempty"`
126
+ RestructurePages *bool `json:"restructurePages,omitempty"`
127
+ MergeTables *bool `json:"mergeTables,omitempty"`
128
+ RelevelTitles *bool `json:"relevelTitles,omitempty"`
129
+ ReturnMarkdownImages *bool `json:"returnMarkdownImages,omitempty"`
130
+ OutputFormats []string `json:"outputFormats,omitempty"`
131
+ Visualize *bool `json:"visualize,omitempty"`
132
+ ExtraOptions map[string]interface{} `json:"-"`
133
+ }
134
+
135
+ // DocParsingOptionsProvider marks document parsing option structs.
136
+ type DocParsingOptionsProvider interface {
137
+ isDocParsingOptions()
138
+ }
139
+
140
+ func (*PPStructureV3Options) isDocParsingOptions() {}
141
+ func (*PaddleOCRVLOptions) isDocParsingOptions() {}
142
+
143
+ type OCRRequest struct {
144
+ Model string
145
+ FileURL string
146
+ FilePath string
147
+ PageRanges string
148
+ BatchID string
149
+ Options *OCROptions
150
+ }
151
+
152
+ type DocParsingRequest struct {
153
+ Model string
154
+ FileURL string
155
+ FilePath string
156
+ PageRanges string
157
+ BatchID string
158
+ Options DocParsingOptionsProvider
159
+ }
ocr_webapp/PaddleOCR/api_sdk/go/ocr.go ADDED
@@ -0,0 +1,317 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ package paddleocr
16
+
17
+ import (
18
+ "context"
19
+ "encoding/json"
20
+ )
21
+
22
+ func (c *Client) OCR(ctx context.Context, req *OCRRequest) (*OCRResult, error) {
23
+ job, err := c.SubmitOCR(ctx, req)
24
+ if err != nil {
25
+ return nil, err
26
+ }
27
+ return c.WaitOCRResult(ctx, job.JobID)
28
+ }
29
+
30
+ // ParseDocument performs document parsing. Blocks until result is ready.
31
+ func (c *Client) ParseDocument(ctx context.Context, req *DocParsingRequest) (*DocParsingResult, error) {
32
+ job, err := c.SubmitDocumentParsing(ctx, req)
33
+ if err != nil {
34
+ return nil, err
35
+ }
36
+ return c.WaitDocumentParsingResult(ctx, job.JobID)
37
+ }
38
+
39
+ // SubmitOCR submits an OCR job and returns job metadata for tracking.
40
+ func (c *Client) SubmitOCR(ctx context.Context, req *OCRRequest) (*Job, error) {
41
+ if req == nil {
42
+ return nil, &InvalidRequestError{PaddleOCRAPIError{Message: "OCR request is nil"}}
43
+ }
44
+ model := req.Model
45
+ if model == "" {
46
+ model = PPOCRv6
47
+ }
48
+ if !IsOCRModel(model) {
49
+ return nil, &InvalidRequestError{PaddleOCRAPIError{Message: "model is not an OCR model: " + model}}
50
+ }
51
+ jobID, err := c.submit(ctx, model, req.FileURL, req.FilePath, req.Options, req.PageRanges, req.BatchID)
52
+ if err != nil {
53
+ return nil, err
54
+ }
55
+ return &Job{JobID: jobID, Model: model, Task: "ocr", PageRanges: req.PageRanges, BatchID: req.BatchID}, nil
56
+ }
57
+
58
+ // SubmitDocumentParsing submits a document parsing job and returns job metadata for tracking.
59
+ func (c *Client) SubmitDocumentParsing(ctx context.Context, req *DocParsingRequest) (*Job, error) {
60
+ if req == nil {
61
+ return nil, &InvalidRequestError{PaddleOCRAPIError{Message: "document parsing request is nil"}}
62
+ }
63
+ model := req.Model
64
+ if model == "" {
65
+ model = PaddleOCRVL16
66
+ }
67
+ if !IsDocumentParsingModel(model) {
68
+ return nil, &InvalidRequestError{PaddleOCRAPIError{Message: "model is not a document parsing model: " + model}}
69
+ }
70
+ jobID, err := c.submit(ctx, model, req.FileURL, req.FilePath, req.Options, req.PageRanges, req.BatchID)
71
+ if err != nil {
72
+ return nil, err
73
+ }
74
+ return &Job{JobID: jobID, Model: model, Task: "document_parsing", PageRanges: req.PageRanges, BatchID: req.BatchID}, nil
75
+ }
76
+
77
+ func (c *Client) WaitOCRResult(ctx context.Context, jobID string) (*OCRResult, error) {
78
+ jsonlData, err := c.pollUntilDone(ctx, jobID)
79
+ if err != nil {
80
+ return nil, err
81
+ }
82
+ return parseOCRResult(jobID, jsonlData)
83
+ }
84
+
85
+ func (c *Client) WaitDocumentParsingResult(ctx context.Context, jobID string) (*DocParsingResult, error) {
86
+ jsonlData, err := c.pollUntilDone(ctx, jobID)
87
+ if err != nil {
88
+ return nil, err
89
+ }
90
+ return parseDocParsingResult(jobID, jsonlData)
91
+ }
92
+
93
+ func (c *Client) GetStatus(ctx context.Context, jobID string) (*JobStatus, error) {
94
+ status, err := c.getJobStatus(ctx, jobID)
95
+ if err != nil {
96
+ return nil, err
97
+ }
98
+ return normalizeStatus(jobID, status)
99
+ }
100
+
101
+ func (c *Client) GetBatchStatus(ctx context.Context, batchID string) (*BatchStatus, error) {
102
+ if batchID == "" {
103
+ return nil, &InvalidRequestError{PaddleOCRAPIError{Message: "batchID is required"}}
104
+ }
105
+ return c.getBatchStatus(ctx, batchID)
106
+ }
107
+
108
+ func (c *Client) submit(ctx context.Context, model, fileURL, filePath string, options interface{}, pageRanges, batchID string) (string, error) {
109
+ if fileURL == "" && filePath == "" {
110
+ return "", &InvalidRequestError{PaddleOCRAPIError{Message: "Either FileURL or FilePath is required."}}
111
+ }
112
+ if fileURL != "" && filePath != "" {
113
+ return "", &InvalidRequestError{PaddleOCRAPIError{Message: "FileURL and FilePath are mutually exclusive."}}
114
+ }
115
+
116
+ payload := defaultPayload(model, options)
117
+
118
+ if fileURL != "" {
119
+ return c.submitURL(ctx, model, fileURL, payload, pageRanges, batchID)
120
+ }
121
+ return c.submitFile(ctx, model, filePath, payload, pageRanges, batchID)
122
+ }
123
+
124
+ func defaultPayload(model string, options interface{}) interface{} {
125
+ switch typed := options.(type) {
126
+ case *OCROptions:
127
+ if typed != nil {
128
+ return payloadWithExtraOptions(typed)
129
+ }
130
+ case *PPStructureV3Options:
131
+ if typed != nil {
132
+ return payloadWithExtraOptions(typed)
133
+ }
134
+ case *PaddleOCRVLOptions:
135
+ if typed != nil {
136
+ return payloadWithExtraOptions(typed)
137
+ }
138
+ default:
139
+ if options != nil {
140
+ return payloadWithExtraOptions(options)
141
+ }
142
+ }
143
+ if IsOCRModel(model) {
144
+ return payloadWithExtraOptions(&OCROptions{})
145
+ }
146
+ if IsVLModel(model) {
147
+ return payloadWithExtraOptions(&PaddleOCRVLOptions{})
148
+ }
149
+ return payloadWithExtraOptions(&PPStructureV3Options{})
150
+ }
151
+
152
+ func payloadWithExtraOptions(options interface{}) interface{} {
153
+ payloadBytes, _ := json.Marshal(options)
154
+ payload := map[string]interface{}{}
155
+ _ = json.Unmarshal(payloadBytes, &payload)
156
+
157
+ var extraOptions map[string]interface{}
158
+ switch typed := options.(type) {
159
+ case *OCROptions:
160
+ extraOptions = typed.ExtraOptions
161
+ case *PPStructureV3Options:
162
+ extraOptions = typed.ExtraOptions
163
+ case *PaddleOCRVLOptions:
164
+ extraOptions = typed.ExtraOptions
165
+ }
166
+ for key, value := range extraOptions {
167
+ payload[key] = value
168
+ }
169
+ return payload
170
+ }
171
+
172
+ func parseOCRResult(jobID string, jsonlData []map[string]interface{}) (*OCRResult, error) {
173
+ result := &OCRResult{JobID: jobID, DataInfo: map[string]interface{}{}}
174
+ for _, lineObj := range jsonlData {
175
+ resultData, ok := lineObj["result"].(map[string]interface{})
176
+ if !ok {
177
+ return nil, &ResultParseError{PaddleOCRAPIError{Message: "OCR result item is missing result"}}
178
+ }
179
+ if dataInfo, ok := resultData["dataInfo"].(map[string]interface{}); ok {
180
+ for key, value := range dataInfo {
181
+ result.DataInfo[key] = value
182
+ }
183
+ }
184
+ ocrResults, ok := resultData["ocrResults"].([]interface{})
185
+ if !ok {
186
+ return nil, &ResultParseError{PaddleOCRAPIError{Message: "OCR result item is missing ocrResults"}}
187
+ }
188
+ for _, item := range ocrResults {
189
+ itemMap, ok := item.(map[string]interface{})
190
+ if !ok {
191
+ return nil, &ResultParseError{PaddleOCRAPIError{Message: "OCR result page is malformed"}}
192
+ }
193
+ if _, ok := itemMap["prunedResult"]; !ok {
194
+ return nil, &ResultParseError{PaddleOCRAPIError{Message: "OCR result page is missing prunedResult"}}
195
+ }
196
+ page := OCRPage{
197
+ PrunedResult: itemMap["prunedResult"],
198
+ OCRImageURL: getString(itemMap, "ocrImage"),
199
+ DocPreprocessingImageURL: getString(itemMap, "docPreprocessingImage"),
200
+ InputImageURL: getString(itemMap, "inputImage"),
201
+ Raw: itemMap,
202
+ }
203
+ result.Pages = append(result.Pages, page)
204
+ }
205
+ }
206
+ return result, nil
207
+ }
208
+
209
+ func parseDocParsingResult(jobID string, jsonlData []map[string]interface{}) (*DocParsingResult, error) {
210
+ result := &DocParsingResult{JobID: jobID, DataInfo: map[string]interface{}{}}
211
+ for _, lineObj := range jsonlData {
212
+ resultData, ok := lineObj["result"].(map[string]interface{})
213
+ if !ok {
214
+ return nil, &ResultParseError{PaddleOCRAPIError{Message: "document parsing result item is missing result"}}
215
+ }
216
+ if dataInfo, ok := resultData["dataInfo"].(map[string]interface{}); ok {
217
+ for key, value := range dataInfo {
218
+ result.DataInfo[key] = value
219
+ }
220
+ }
221
+ lpResults, ok := resultData["layoutParsingResults"].([]interface{})
222
+ if !ok {
223
+ return nil, &ResultParseError{PaddleOCRAPIError{Message: "document parsing result item is missing layoutParsingResults"}}
224
+ }
225
+ for _, item := range lpResults {
226
+ itemMap, ok := item.(map[string]interface{})
227
+ if !ok {
228
+ return nil, &ResultParseError{PaddleOCRAPIError{Message: "document parsing result page is malformed"}}
229
+ }
230
+ markdown, ok := itemMap["markdown"].(map[string]interface{})
231
+ if !ok || getString(markdown, "text") == "" {
232
+ return nil, &ResultParseError{PaddleOCRAPIError{Message: "document parsing result page is missing markdown.text"}}
233
+ }
234
+ page := DocParsingPage{
235
+ MarkdownText: getString(markdown, "text"),
236
+ MarkdownImages: getStringMap(markdown, "images"),
237
+ OutputImages: getStringMap(itemMap, "outputImages"),
238
+ PrunedResult: itemMap["prunedResult"],
239
+ InputImageURL: getString(itemMap, "inputImage"),
240
+ Exports: getMap(itemMap, "exports"),
241
+ Markdown: markdown,
242
+ Raw: itemMap,
243
+ }
244
+ result.Pages = append(result.Pages, page)
245
+ }
246
+ }
247
+ return result, nil
248
+ }
249
+
250
+ func getString(m map[string]interface{}, key string) string {
251
+ if m == nil {
252
+ return ""
253
+ }
254
+ v, _ := m[key].(string)
255
+ return v
256
+ }
257
+
258
+ func getMap(m map[string]interface{}, key string) map[string]interface{} {
259
+ value, ok := m[key].(map[string]interface{})
260
+ if !ok {
261
+ return map[string]interface{}{}
262
+ }
263
+ return value
264
+ }
265
+
266
+ func getStringMap(m map[string]interface{}, key string) map[string]string {
267
+ if m == nil {
268
+ return nil
269
+ }
270
+ raw, ok := m[key]
271
+ if !ok {
272
+ return nil
273
+ }
274
+ switch v := raw.(type) {
275
+ case map[string]interface{}:
276
+ result := make(map[string]string, len(v))
277
+ for k, val := range v {
278
+ if s, ok := val.(string); ok {
279
+ result[k] = s
280
+ }
281
+ }
282
+ return result
283
+ default:
284
+ b, _ := json.Marshal(raw)
285
+ var result map[string]string
286
+ json.Unmarshal(b, &result)
287
+ return result
288
+ }
289
+ }
290
+
291
+ func normalizeStatus(jobID string, status *jobStatusResponse) (*JobStatus, error) {
292
+ if status == nil || status.State == "" {
293
+ return nil, &ResponseFormatError{PaddleOCRAPIError{Message: "status response is missing state"}}
294
+ }
295
+ if status.State != "pending" && status.State != "running" && status.State != "done" && status.State != "failed" {
296
+ return nil, &ResponseFormatError{PaddleOCRAPIError{Message: "unknown job state: " + status.State}}
297
+ }
298
+ result := &JobStatus{
299
+ JobID: jobID,
300
+ State: status.State,
301
+ ResultURL: status.ResultURL,
302
+ ErrorMsg: status.ErrorMsg,
303
+ }
304
+ if len(status.ExtractProgress) != 0 && string(status.ExtractProgress) != "null" {
305
+ var progress extractProgress
306
+ if err := json.Unmarshal(status.ExtractProgress, &progress); err != nil {
307
+ return nil, &ResponseFormatError{PaddleOCRAPIError{Message: "status progress is malformed", Cause: err}}
308
+ }
309
+ result.Progress = &Progress{
310
+ TotalPages: progress.TotalPages,
311
+ ExtractedPages: progress.ExtractedPages,
312
+ StartTime: progress.StartTime,
313
+ EndTime: progress.EndTime,
314
+ }
315
+ }
316
+ return result, nil
317
+ }
ocr_webapp/PaddleOCR/api_sdk/go/operation.go ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ package paddleocr
16
+
17
+ import (
18
+ "context"
19
+ "encoding/json"
20
+ )
21
+
22
+ // Operation represents an in-progress job. Use Wait() to block until done,
23
+ // or Poll() to check status without blocking.
24
+ type Operation struct {
25
+ client *Client
26
+ JobID string
27
+ model string
28
+ }
29
+
30
+ // Wait blocks until the job completes and returns the parsed result.
31
+ func (op *Operation) Wait(ctx context.Context) (interface{}, error) {
32
+ jsonlData, err := op.client.pollUntilDone(ctx, op.JobID)
33
+ if err != nil {
34
+ return nil, err
35
+ }
36
+ if IsOCRModel(op.model) {
37
+ return parseOCRResult(op.JobID, jsonlData)
38
+ }
39
+ return parseDocParsingResult(op.JobID, jsonlData)
40
+ }
41
+
42
+ // Poll checks the current job status without waiting.
43
+ // Returns the status, whether the job is done, and any error.
44
+ func (op *Operation) Poll(ctx context.Context) (*JobStatus, bool, error) {
45
+ status, err := op.client.getJobStatus(ctx, op.JobID)
46
+ if err != nil {
47
+ return nil, false, err
48
+ }
49
+
50
+ js := &JobStatus{
51
+ JobID: op.JobID,
52
+ State: status.State,
53
+ ErrorMsg: status.ErrorMsg,
54
+ }
55
+
56
+ if status.ExtractProgress != nil {
57
+ var ep extractProgress
58
+ if err := json.Unmarshal(status.ExtractProgress, &ep); err == nil {
59
+ js.Progress = &Progress{
60
+ TotalPages: ep.TotalPages,
61
+ ExtractedPages: ep.ExtractedPages,
62
+ StartTime: ep.StartTime,
63
+ EndTime: ep.EndTime,
64
+ }
65
+ }
66
+ }
67
+
68
+ return js, status.State == "done", nil
69
+ }
ocr_webapp/PaddleOCR/api_sdk/go/options.go ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ package paddleocr
16
+
17
+ import (
18
+ "net/http"
19
+ "time"
20
+ )
21
+
22
+ const DefaultBaseURL = "https://paddleocr.aistudio-app.com"
23
+
24
+ const apiPath = "/api/v2/ocr/jobs"
25
+
26
+ type ClientOption func(*Client)
27
+
28
+ func WithToken(token string) ClientOption {
29
+ return func(c *Client) {
30
+ c.token = token
31
+ }
32
+ }
33
+
34
+ func WithBaseURL(url string) ClientOption {
35
+ return func(c *Client) {
36
+ c.baseURL = url
37
+ }
38
+ }
39
+
40
+ func WithTimeout(d time.Duration) ClientOption {
41
+ return func(c *Client) {
42
+ c.requestTimeout = d
43
+ c.pollTimeout = d
44
+ }
45
+ }
46
+
47
+ func WithRequestTimeout(d time.Duration) ClientOption {
48
+ return func(c *Client) {
49
+ c.requestTimeout = d
50
+ }
51
+ }
52
+
53
+ func WithPollTimeout(d time.Duration) ClientOption {
54
+ return func(c *Client) {
55
+ c.pollTimeout = d
56
+ }
57
+ }
58
+
59
+ func WithClientPlatform(clientPlatform string) ClientOption {
60
+ return func(c *Client) {
61
+ c.clientPlatform = clientPlatform
62
+ }
63
+ }
64
+
65
+ func WithHTTPClient(hc *http.Client) ClientOption {
66
+ return func(c *Client) {
67
+ c.httpClient = hc
68
+ }
69
+ }
70
+
71
+ func Bool(v bool) *bool {
72
+ return &v
73
+ }
ocr_webapp/PaddleOCR/api_sdk/go/poller.go ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ package paddleocr
16
+
17
+ import (
18
+ "context"
19
+ "fmt"
20
+ "time"
21
+ )
22
+
23
+ const (
24
+ initialInterval = 3 * time.Second
25
+ multiplier = 1.5
26
+ maxInterval = 15 * time.Second
27
+ )
28
+
29
+ func (c *Client) pollUntilDone(ctx context.Context, jobID string) ([]map[string]interface{}, error) {
30
+ interval := initialInterval
31
+ deadline := time.Now().Add(c.pollTimeout)
32
+ pollCtx, cancel := context.WithDeadline(ctx, deadline)
33
+ defer cancel()
34
+
35
+ for time.Now().Before(deadline) {
36
+ remaining := time.Until(deadline)
37
+ if remaining <= 0 {
38
+ break
39
+ }
40
+ if interval > remaining {
41
+ interval = remaining
42
+ }
43
+ timer := time.NewTimer(interval)
44
+ select {
45
+ case <-pollCtx.Done():
46
+ timer.Stop()
47
+ if ctx.Err() != nil {
48
+ return nil, ctx.Err()
49
+ }
50
+ return nil, &PollTimeoutError{
51
+ JobID: jobID,
52
+ Elapsed: c.pollTimeout.Seconds(),
53
+ PaddleOCRAPIError: PaddleOCRAPIError{Message: fmt.Sprintf("Timed out after %.1fs", c.pollTimeout.Seconds())},
54
+ }
55
+ case <-timer.C:
56
+ }
57
+
58
+ status, err := c.getJobStatus(pollCtx, jobID)
59
+ if err != nil {
60
+ return nil, err
61
+ }
62
+
63
+ switch status.State {
64
+ case "done":
65
+ jsonURL := status.ResultURL["jsonUrl"]
66
+ if jsonURL == "" {
67
+ return nil, &ResponseFormatError{PaddleOCRAPIError{Message: "done job response is missing resultUrl.jsonUrl"}}
68
+ }
69
+ return c.fetchJSONL(pollCtx, jsonURL)
70
+ case "failed":
71
+ return nil, &JobFailedError{
72
+ JobID: jobID,
73
+ ErrorMsg: status.ErrorMsg,
74
+ PaddleOCRAPIError: PaddleOCRAPIError{Message: status.ErrorMsg},
75
+ }
76
+ }
77
+
78
+ next := time.Duration(float64(interval) * multiplier)
79
+ if next > maxInterval {
80
+ next = maxInterval
81
+ }
82
+ interval = next
83
+ }
84
+
85
+ return nil, &PollTimeoutError{
86
+ JobID: jobID,
87
+ Elapsed: c.pollTimeout.Seconds(),
88
+ PaddleOCRAPIError: PaddleOCRAPIError{Message: fmt.Sprintf("Timed out after %.1fs", c.pollTimeout.Seconds())},
89
+ }
90
+ }
ocr_webapp/PaddleOCR/api_sdk/go/resource.go ADDED
@@ -0,0 +1,267 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ package paddleocr
16
+
17
+ import (
18
+ "context"
19
+ "errors"
20
+ "fmt"
21
+ "io"
22
+ "net/http"
23
+ "net/url"
24
+ "os"
25
+ "path"
26
+ "path/filepath"
27
+ "sort"
28
+ "strings"
29
+ )
30
+
31
+ type SaveResourceOption func(*saveResourceOptions)
32
+
33
+ type saveResourceOptions struct {
34
+ overwrite bool
35
+ }
36
+
37
+ func WithOverwrite(overwrite bool) SaveResourceOption {
38
+ return func(o *saveResourceOptions) {
39
+ o.overwrite = overwrite
40
+ }
41
+ }
42
+
43
+ // SaveResource downloads one result resource URL.
44
+ func (c *Client) SaveResource(ctx context.Context, resourceURL, dest string, opts ...SaveResourceOption) (string, error) {
45
+ if resourceURL == "" {
46
+ return "", &InvalidRequestError{PaddleOCRAPIError{Message: "resource URL is required"}}
47
+ }
48
+ if dest == "" {
49
+ return "", &InvalidRequestError{PaddleOCRAPIError{Message: "destination path is required"}}
50
+ }
51
+ options := saveResourceOptions{}
52
+ for _, opt := range opts {
53
+ opt(&options)
54
+ }
55
+ savedPath, err := resolveSavePath(resourceURL, dest)
56
+ if err != nil {
57
+ return "", err
58
+ }
59
+ parent := filepath.Dir(savedPath)
60
+ if st, err := os.Stat(parent); err != nil {
61
+ if errors.Is(err, os.ErrNotExist) {
62
+ return "", &FileNotFoundError{Path: parent, PaddleOCRAPIError: PaddleOCRAPIError{Message: "destination parent not found: " + parent, Cause: err}}
63
+ }
64
+ return "", err
65
+ } else if !st.IsDir() {
66
+ return "", &FileNotFoundError{Path: parent, PaddleOCRAPIError: PaddleOCRAPIError{Message: "destination parent is not a directory: " + parent}}
67
+ }
68
+ if !options.overwrite {
69
+ if _, err := os.Stat(savedPath); err == nil {
70
+ return "", &InvalidRequestError{PaddleOCRAPIError{Message: "destination already exists: " + savedPath}}
71
+ } else if err != nil && !errors.Is(err, os.ErrNotExist) {
72
+ return "", err
73
+ }
74
+ }
75
+
76
+ req, err := http.NewRequestWithContext(ctx, http.MethodGet, resourceURL, nil)
77
+ if err != nil {
78
+ return "", &NetworkError{PaddleOCRAPIError{Message: err.Error(), Cause: err}}
79
+ }
80
+ resp, err := c.httpClient.Do(req)
81
+ if err != nil {
82
+ return "", classifyHTTPError(err)
83
+ }
84
+ defer resp.Body.Close()
85
+ if err := raiseForResourceResponse(resp); err != nil {
86
+ return "", err
87
+ }
88
+
89
+ tmp, err := os.CreateTemp(parent, "."+filepath.Base(savedPath)+".tmp-*")
90
+ if err != nil {
91
+ return "", err
92
+ }
93
+ tmpPath := tmp.Name()
94
+ cleanupTemp := true
95
+ defer func() {
96
+ if cleanupTemp {
97
+ _ = os.Remove(tmpPath)
98
+ }
99
+ }()
100
+ if _, err := io.Copy(tmp, resp.Body); err != nil {
101
+ _ = tmp.Close()
102
+ return "", err
103
+ }
104
+ if err := tmp.Close(); err != nil {
105
+ return "", err
106
+ }
107
+ if options.overwrite {
108
+ if err := os.Rename(tmpPath, savedPath); err != nil {
109
+ return "", err
110
+ }
111
+ } else {
112
+ if err := os.Link(tmpPath, savedPath); err != nil {
113
+ if errors.Is(err, os.ErrExist) {
114
+ return "", &InvalidRequestError{PaddleOCRAPIError{Message: "destination already exists: " + savedPath, Cause: err}}
115
+ }
116
+ return "", err
117
+ }
118
+ if err := os.Remove(tmpPath); err != nil {
119
+ return "", err
120
+ }
121
+ }
122
+ cleanupTemp = false
123
+ return savedPath, nil
124
+ }
125
+
126
+ func (c *Client) SaveOCRResultResources(ctx context.Context, result *OCRResult, destDir string, opts ...SaveResourceOption) ([]string, error) {
127
+ if result == nil {
128
+ return nil, &InvalidRequestError{PaddleOCRAPIError{Message: "OCR result is required"}}
129
+ }
130
+ if err := requireExistingDirectory(destDir); err != nil {
131
+ return nil, err
132
+ }
133
+ saved := make([]string, 0, len(result.Pages))
134
+ for i, page := range result.Pages {
135
+ if page.OCRImageURL == "" {
136
+ continue
137
+ }
138
+ name := fmt.Sprintf("ocr-page-%d%s", i+1, safeResourceExtension(page.OCRImageURL))
139
+ if err := validateResultResourceFilename(name); err != nil {
140
+ return nil, err
141
+ }
142
+ path, err := c.SaveResource(ctx, page.OCRImageURL, filepath.Join(destDir, name), opts...)
143
+ if err != nil {
144
+ return nil, err
145
+ }
146
+ saved = append(saved, path)
147
+ }
148
+ return saved, nil
149
+ }
150
+
151
+ func (c *Client) SaveDocumentParsingResultResources(ctx context.Context, result *DocParsingResult, destDir string, opts ...SaveResourceOption) ([]string, error) {
152
+ if result == nil {
153
+ return nil, &InvalidRequestError{PaddleOCRAPIError{Message: "document parsing result is required"}}
154
+ }
155
+ if err := requireExistingDirectory(destDir); err != nil {
156
+ return nil, err
157
+ }
158
+ var saved []string
159
+ for _, page := range result.Pages {
160
+ paths, err := c.saveNamedResourceMap(ctx, page.MarkdownImages, destDir, opts...)
161
+ if err != nil {
162
+ return nil, err
163
+ }
164
+ saved = append(saved, paths...)
165
+ paths, err = c.saveNamedResourceMap(ctx, page.OutputImages, destDir, opts...)
166
+ if err != nil {
167
+ return nil, err
168
+ }
169
+ saved = append(saved, paths...)
170
+ }
171
+ return saved, nil
172
+ }
173
+
174
+ func (c *Client) saveNamedResourceMap(ctx context.Context, resources map[string]string, destDir string, opts ...SaveResourceOption) ([]string, error) {
175
+ keys := make([]string, 0, len(resources))
176
+ for key := range resources {
177
+ keys = append(keys, key)
178
+ }
179
+ sort.Strings(keys)
180
+ saved := make([]string, 0, len(keys))
181
+ for _, key := range keys {
182
+ resourceURL := resources[key]
183
+ if resourceURL == "" {
184
+ continue
185
+ }
186
+ name, err := resultResourceFilename(key)
187
+ if err != nil {
188
+ return nil, err
189
+ }
190
+ path, err := c.SaveResource(ctx, resourceURL, filepath.Join(destDir, name), opts...)
191
+ if err != nil {
192
+ return nil, err
193
+ }
194
+ saved = append(saved, path)
195
+ }
196
+ return saved, nil
197
+ }
198
+
199
+ func resolveSavePath(resourceURL, dest string) (string, error) {
200
+ if st, err := os.Stat(dest); err == nil && st.IsDir() {
201
+ name := "resource"
202
+ u, parseErr := url.Parse(resourceURL)
203
+ if parseErr == nil {
204
+ if base := path.Base(u.Path); base != "." && base != "/" && base != "" {
205
+ name = base
206
+ }
207
+ }
208
+ return filepath.Join(dest, name), nil
209
+ } else if err != nil && !errors.Is(err, os.ErrNotExist) {
210
+ return "", err
211
+ }
212
+ return dest, nil
213
+ }
214
+
215
+ func raiseForResourceResponse(resp *http.Response) error {
216
+ if resp.StatusCode >= 200 && resp.StatusCode < 300 {
217
+ return nil
218
+ }
219
+ body, _ := io.ReadAll(resp.Body)
220
+ return &APIError{StatusCode: resp.StatusCode, PaddleOCRAPIError: PaddleOCRAPIError{Message: string(body)}}
221
+ }
222
+
223
+ func requireExistingDirectory(destDir string) error {
224
+ if destDir == "" {
225
+ return &InvalidRequestError{PaddleOCRAPIError{Message: "destination directory is required"}}
226
+ }
227
+ st, err := os.Stat(destDir)
228
+ if err != nil {
229
+ if errors.Is(err, os.ErrNotExist) {
230
+ return &FileNotFoundError{Path: destDir, PaddleOCRAPIError: PaddleOCRAPIError{Message: "destination directory not found: " + destDir, Cause: err}}
231
+ }
232
+ return err
233
+ }
234
+ if !st.IsDir() {
235
+ return &FileNotFoundError{Path: destDir, PaddleOCRAPIError: PaddleOCRAPIError{Message: "destination is not a directory: " + destDir}}
236
+ }
237
+ return nil
238
+ }
239
+
240
+ func resultResourceFilename(key string) (string, error) {
241
+ if err := validateResultResourceFilename(key); err != nil {
242
+ return "", err
243
+ }
244
+ return key, nil
245
+ }
246
+
247
+ func validateResultResourceFilename(name string) error {
248
+ if name == "" || name == "." || name == ".." || filepath.IsAbs(name) || path.IsAbs(name) || strings.ContainsAny(name, `/\`) {
249
+ return &InvalidRequestError{PaddleOCRAPIError{Message: "unsafe resource filename: " + name}}
250
+ }
251
+ return nil
252
+ }
253
+
254
+ func safeResourceExtension(resourceURL string) string {
255
+ u, err := url.Parse(resourceURL)
256
+ if err != nil {
257
+ return ""
258
+ }
259
+ ext := path.Ext(path.Base(u.Path))
260
+ if len(ext) <= 1 {
261
+ return ""
262
+ }
263
+ if err := validateResultResourceFilename("resource" + ext); err != nil {
264
+ return ""
265
+ }
266
+ return ext
267
+ }
ocr_webapp/PaddleOCR/api_sdk/go/results.go ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ package paddleocr
16
+
17
+ type OCRPage struct {
18
+ PrunedResult interface{} `json:"prunedResult"`
19
+ OCRImageURL string `json:"ocrImageUrl,omitempty"`
20
+ DocPreprocessingImageURL string `json:"docPreprocessingImageUrl,omitempty"`
21
+ InputImageURL string `json:"inputImageUrl,omitempty"`
22
+ Raw map[string]interface{} `json:"raw,omitempty"`
23
+ }
24
+
25
+ type DocParsingPage struct {
26
+ MarkdownText string `json:"markdownText"`
27
+ MarkdownImages map[string]string `json:"markdownImages"`
28
+ OutputImages map[string]string `json:"outputImages"`
29
+ PrunedResult interface{} `json:"prunedResult,omitempty"`
30
+ InputImageURL string `json:"inputImageUrl,omitempty"`
31
+ Exports map[string]interface{} `json:"exports,omitempty"`
32
+ Markdown map[string]interface{} `json:"markdown,omitempty"`
33
+ Raw map[string]interface{} `json:"raw,omitempty"`
34
+ }
35
+
36
+ type OCRResult struct {
37
+ JobID string `json:"jobId"`
38
+ Pages []OCRPage `json:"pages"`
39
+ DataInfo map[string]interface{} `json:"dataInfo,omitempty"`
40
+ }
41
+
42
+ type DocParsingResult struct {
43
+ JobID string `json:"jobId"`
44
+ Pages []DocParsingPage `json:"pages"`
45
+ DataInfo map[string]interface{} `json:"dataInfo,omitempty"`
46
+ }
47
+
48
+ type Progress struct {
49
+ TotalPages int `json:"totalPages"`
50
+ ExtractedPages int `json:"extractedPages"`
51
+ StartTime string `json:"startTime,omitempty"`
52
+ EndTime string `json:"endTime,omitempty"`
53
+ }
54
+
55
+ type Job struct {
56
+ JobID string `json:"jobId"`
57
+ Model string `json:"model"`
58
+ Task string `json:"task"`
59
+ PageRanges string `json:"pageRanges,omitempty"`
60
+ BatchID string `json:"batchId,omitempty"`
61
+ }
62
+
63
+ type JobStatus struct {
64
+ JobID string `json:"jobId"`
65
+ State string `json:"state"`
66
+ Progress *Progress `json:"progress,omitempty"`
67
+ ResultURL map[string]string `json:"resultUrl,omitempty"`
68
+ ErrorMsg string `json:"errorMsg,omitempty"`
69
+ }
70
+
71
+ type BatchStatus struct {
72
+ BatchID string `json:"batchId"`
73
+ Jobs []*JobStatus `json:"jobs"`
74
+ }
ocr_webapp/PaddleOCR/api_sdk/go/transport.go ADDED
@@ -0,0 +1,329 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ package paddleocr
16
+
17
+ import (
18
+ "bytes"
19
+ "context"
20
+ "encoding/json"
21
+ "io"
22
+ "mime/multipart"
23
+ "net"
24
+ "net/http"
25
+ "os"
26
+ "path/filepath"
27
+ "strings"
28
+ )
29
+
30
+ type apiResponse struct {
31
+ Code int `json:"code"`
32
+ Msg string `json:"msg"`
33
+ Data json.RawMessage `json:"data"`
34
+ }
35
+
36
+ type submitResponse struct {
37
+ JobID string `json:"jobId"`
38
+ }
39
+
40
+ type jobStatusResponse struct {
41
+ JobID string `json:"jobId"`
42
+ State string `json:"state"`
43
+ ExtractProgress json.RawMessage `json:"extractProgress"`
44
+ ResultURL map[string]string `json:"resultUrl"`
45
+ ErrorMsg string `json:"errorMsg"`
46
+ }
47
+
48
+ type extractProgress struct {
49
+ TotalPages int `json:"totalPages"`
50
+ ExtractedPages int `json:"extractedPages"`
51
+ StartTime string `json:"startTime"`
52
+ EndTime string `json:"endTime"`
53
+ }
54
+
55
+ func (c *Client) submitURL(ctx context.Context, model, fileURL string, payload interface{}, pageRanges, batchID string) (string, error) {
56
+ body := map[string]interface{}{
57
+ "fileUrl": fileURL,
58
+ "model": model,
59
+ "optionalPayload": payload,
60
+ }
61
+ if pageRanges != "" {
62
+ body["pageRanges"] = pageRanges
63
+ }
64
+ if batchID != "" {
65
+ body["batchId"] = batchID
66
+ }
67
+ jsonBody, err := json.Marshal(body)
68
+ if err != nil {
69
+ return "", &ResponseFormatError{PaddleOCRAPIError{Message: "failed to encode submit request", Cause: err}}
70
+ }
71
+
72
+ req, err := http.NewRequestWithContext(ctx, "POST", c.jobsURL, bytes.NewReader(jsonBody))
73
+ if err != nil {
74
+ return "", &NetworkError{PaddleOCRAPIError{Message: err.Error()}}
75
+ }
76
+ req.Header.Set("Authorization", "Bearer "+c.token)
77
+ req.Header.Set("Content-Type", "application/json")
78
+ c.setClientPlatformHeader(req)
79
+
80
+ resp, err := c.httpClient.Do(req)
81
+ if err != nil {
82
+ return "", classifyHTTPError(err)
83
+ }
84
+ defer resp.Body.Close()
85
+
86
+ if err := raiseForResponse(resp); err != nil {
87
+ return "", err
88
+ }
89
+
90
+ apiResp, err := decodeAPIResponse(resp)
91
+ if err != nil {
92
+ return "", err
93
+ }
94
+ var sr submitResponse
95
+ if err := json.Unmarshal(apiResp.Data, &sr); err != nil {
96
+ return "", &ResponseFormatError{PaddleOCRAPIError{Message: "submit response is malformed", Cause: err}}
97
+ }
98
+ if sr.JobID == "" {
99
+ return "", &ResponseFormatError{PaddleOCRAPIError{Message: "submit response is missing jobId"}}
100
+ }
101
+ return sr.JobID, nil
102
+ }
103
+
104
+ func (c *Client) submitFile(ctx context.Context, model, filePath string, payload interface{}, pageRanges, batchID string) (string, error) {
105
+ if _, err := os.Stat(filePath); os.IsNotExist(err) {
106
+ return "", &FileNotFoundError{Path: filePath, PaddleOCRAPIError: PaddleOCRAPIError{Message: "File not found: " + filePath}}
107
+ }
108
+
109
+ var buf bytes.Buffer
110
+ w := multipart.NewWriter(&buf)
111
+
112
+ _ = w.WriteField("model", model)
113
+ payloadJSON, err := json.Marshal(payload)
114
+ if err != nil {
115
+ return "", &ResponseFormatError{PaddleOCRAPIError{Message: "failed to encode optionalPayload", Cause: err}}
116
+ }
117
+ if err := w.WriteField("optionalPayload", string(payloadJSON)); err != nil {
118
+ return "", &ResponseFormatError{PaddleOCRAPIError{Message: "failed to prepare multipart body", Cause: err}}
119
+ }
120
+ if pageRanges != "" {
121
+ _ = w.WriteField("pageRanges", pageRanges)
122
+ }
123
+ if batchID != "" {
124
+ _ = w.WriteField("batchId", batchID)
125
+ }
126
+
127
+ file, err := os.Open(filePath)
128
+ if err != nil {
129
+ return "", &FileNotFoundError{Path: filePath, PaddleOCRAPIError: PaddleOCRAPIError{Message: "Failed to open file: " + filePath, Cause: err}}
130
+ }
131
+ defer file.Close()
132
+
133
+ fw, err := w.CreateFormFile("file", filepath.Base(filePath))
134
+ if err != nil {
135
+ return "", &ResponseFormatError{PaddleOCRAPIError{Message: "failed to prepare multipart body", Cause: err}}
136
+ }
137
+ if _, err := io.Copy(fw, file); err != nil {
138
+ return "", &NetworkError{PaddleOCRAPIError{Message: "failed to read file content", Cause: err}}
139
+ }
140
+ if err := w.Close(); err != nil {
141
+ return "", &ResponseFormatError{PaddleOCRAPIError{Message: "failed to finalize multipart body", Cause: err}}
142
+ }
143
+
144
+ req, err := http.NewRequestWithContext(ctx, "POST", c.jobsURL, &buf)
145
+ if err != nil {
146
+ return "", &NetworkError{PaddleOCRAPIError{Message: err.Error()}}
147
+ }
148
+ req.Header.Set("Authorization", "Bearer "+c.token)
149
+ req.Header.Set("Content-Type", w.FormDataContentType())
150
+ c.setClientPlatformHeader(req)
151
+
152
+ resp, err := c.httpClient.Do(req)
153
+ if err != nil {
154
+ return "", classifyHTTPError(err)
155
+ }
156
+ defer resp.Body.Close()
157
+
158
+ if err := raiseForResponse(resp); err != nil {
159
+ return "", err
160
+ }
161
+
162
+ apiResp, err := decodeAPIResponse(resp)
163
+ if err != nil {
164
+ return "", err
165
+ }
166
+ var sr submitResponse
167
+ if err := json.Unmarshal(apiResp.Data, &sr); err != nil {
168
+ return "", &ResponseFormatError{PaddleOCRAPIError{Message: "submit response is malformed", Cause: err}}
169
+ }
170
+ if sr.JobID == "" {
171
+ return "", &ResponseFormatError{PaddleOCRAPIError{Message: "submit response is missing jobId"}}
172
+ }
173
+ return sr.JobID, nil
174
+ }
175
+
176
+ func (c *Client) getJobStatus(ctx context.Context, jobID string) (*jobStatusResponse, error) {
177
+ req, err := http.NewRequestWithContext(ctx, "GET", c.jobsURL+"/"+jobID, nil)
178
+ if err != nil {
179
+ return nil, &NetworkError{PaddleOCRAPIError{Message: err.Error()}}
180
+ }
181
+ req.Header.Set("Authorization", "Bearer "+c.token)
182
+ c.setClientPlatformHeader(req)
183
+
184
+ resp, err := c.httpClient.Do(req)
185
+ if err != nil {
186
+ return nil, classifyHTTPError(err)
187
+ }
188
+ defer resp.Body.Close()
189
+
190
+ if err := raiseForResponse(resp); err != nil {
191
+ return nil, err
192
+ }
193
+
194
+ apiResp, err := decodeAPIResponse(resp)
195
+ if err != nil {
196
+ return nil, err
197
+ }
198
+ var status jobStatusResponse
199
+ if err := json.Unmarshal(apiResp.Data, &status); err != nil {
200
+ return nil, &ResponseFormatError{PaddleOCRAPIError{Message: "status response is malformed", Cause: err}}
201
+ }
202
+ if status.State == "" {
203
+ return nil, &ResponseFormatError{PaddleOCRAPIError{Message: "status response is missing state"}}
204
+ }
205
+ return &status, nil
206
+ }
207
+
208
+ func (c *Client) getBatchStatus(ctx context.Context, batchID string) (*BatchStatus, error) {
209
+ req, err := http.NewRequestWithContext(ctx, "GET", c.jobsURL+"/batch/"+batchID, nil)
210
+ if err != nil {
211
+ return nil, &NetworkError{PaddleOCRAPIError{Message: err.Error(), Cause: err}}
212
+ }
213
+ req.Header.Set("Authorization", "Bearer "+c.token)
214
+ c.setClientPlatformHeader(req)
215
+
216
+ resp, err := c.httpClient.Do(req)
217
+ if err != nil {
218
+ return nil, classifyHTTPError(err)
219
+ }
220
+ defer resp.Body.Close()
221
+
222
+ if err := raiseForResponse(resp); err != nil {
223
+ return nil, err
224
+ }
225
+ apiResp, err := decodeAPIResponse(resp)
226
+ if err != nil {
227
+ return nil, err
228
+ }
229
+ var payload struct {
230
+ ExtractResult []jobStatusResponse `json:"extractResult"`
231
+ }
232
+ if err := json.Unmarshal(apiResp.Data, &payload); err != nil {
233
+ return nil, &ResponseFormatError{PaddleOCRAPIError{Message: "batch response is malformed", Cause: err}}
234
+ }
235
+ result := &BatchStatus{BatchID: batchID}
236
+ for _, item := range payload.ExtractResult {
237
+ jobID := item.JobID
238
+ if jobID == "" {
239
+ return nil, &ResponseFormatError{PaddleOCRAPIError{Message: "batch response item is missing jobId"}}
240
+ }
241
+ status, err := normalizeStatus(jobID, &item)
242
+ if err != nil {
243
+ return nil, err
244
+ }
245
+ result.Jobs = append(result.Jobs, status)
246
+ }
247
+ return result, nil
248
+ }
249
+
250
+ func (c *Client) fetchJSONL(ctx context.Context, url string) ([]map[string]interface{}, error) {
251
+ req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
252
+ if err != nil {
253
+ return nil, &NetworkError{PaddleOCRAPIError{Message: err.Error()}}
254
+ }
255
+ resp, err := c.httpClient.Do(req)
256
+ if err != nil {
257
+ return nil, classifyHTTPError(err)
258
+ }
259
+ defer resp.Body.Close()
260
+ if err := raiseForResponse(resp); err != nil {
261
+ return nil, err
262
+ }
263
+
264
+ body, err := io.ReadAll(resp.Body)
265
+ if err != nil {
266
+ return nil, err
267
+ }
268
+
269
+ lines := strings.Split(strings.TrimSpace(string(body)), "\n")
270
+ var results []map[string]interface{}
271
+ for _, line := range lines {
272
+ line = strings.TrimSpace(line)
273
+ if line == "" {
274
+ continue
275
+ }
276
+ var obj map[string]interface{}
277
+ if err := json.Unmarshal([]byte(line), &obj); err != nil {
278
+ return nil, &ResultParseError{PaddleOCRAPIError{Message: "failed to parse JSONL result payload", Cause: err}}
279
+ }
280
+ results = append(results, obj)
281
+ }
282
+ return results, nil
283
+ }
284
+
285
+ func raiseForResponse(resp *http.Response) error {
286
+ if resp.StatusCode >= 200 && resp.StatusCode < 300 {
287
+ return nil
288
+ }
289
+ body, _ := io.ReadAll(resp.Body)
290
+ msg := string(body)
291
+
292
+ switch {
293
+ case resp.StatusCode == 401 || resp.StatusCode == 403:
294
+ return &AuthError{PaddleOCRAPIError{Message: "Authentication failed: " + msg}}
295
+ case resp.StatusCode == 400:
296
+ return &InvalidRequestError{PaddleOCRAPIError{Message: "Bad request: " + msg}}
297
+ case resp.StatusCode == 429:
298
+ return &RateLimitError{APIError{StatusCode: 429, PaddleOCRAPIError: PaddleOCRAPIError{Message: "Rate limit exceeded: " + msg}}}
299
+ case resp.StatusCode == 503 || resp.StatusCode == 504:
300
+ return &ServiceUnavailableError{APIError{StatusCode: resp.StatusCode, PaddleOCRAPIError: PaddleOCRAPIError{Message: "Service unavailable: " + msg}}}
301
+ default:
302
+ return &APIError{StatusCode: resp.StatusCode, PaddleOCRAPIError: PaddleOCRAPIError{Message: msg}}
303
+ }
304
+ }
305
+
306
+ func decodeAPIResponse(resp *http.Response) (*apiResponse, error) {
307
+ var apiResp apiResponse
308
+ if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil {
309
+ return nil, &ResponseFormatError{PaddleOCRAPIError{Message: "expected a JSON response body", Cause: err}}
310
+ }
311
+ if apiResp.Code != 0 {
312
+ msg := apiResp.Msg
313
+ if msg == "" {
314
+ msg = "PaddleOCR official API request failed"
315
+ }
316
+ return nil, &APIError{StatusCode: resp.StatusCode, PaddleOCRAPIError: PaddleOCRAPIError{Message: msg}}
317
+ }
318
+ if len(apiResp.Data) == 0 || string(apiResp.Data) == "null" {
319
+ return nil, &ResponseFormatError{PaddleOCRAPIError{Message: "response body is missing data"}}
320
+ }
321
+ return &apiResp, nil
322
+ }
323
+
324
+ func classifyHTTPError(err error) error {
325
+ if ne, ok := err.(net.Error); ok && ne.Timeout() {
326
+ return &RequestTimeoutError{PaddleOCRAPIError: PaddleOCRAPIError{Message: err.Error(), Cause: err}}
327
+ }
328
+ return &NetworkError{PaddleOCRAPIError{Message: err.Error(), Cause: err}}
329
+ }
ocr_webapp/PaddleOCR/api_sdk/typescript/.gitignore ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ node_modules/
2
+ dist/
3
+ .vite/
4
+ coverage/
5
+ .nyc_output/
6
+ npm-debug.log*
7
+ yarn-debug.log*
8
+ yarn-error.log*
9
+ pnpm-debug.log*
ocr_webapp/PaddleOCR/api_sdk/typescript/README.md ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PaddleOCR TypeScript SDK
2
+
3
+ English | [简体中文](README_cn.md)
4
+
5
+ TypeScript client for the PaddleOCR official API. It submits OCR and document
6
+ parsing jobs to hosted PaddleOCR services; it does not perform local OCR
7
+ inference.
8
+
9
+ Official user docs:
10
+
11
+ - [TypeScript SDK](../../docs/version3.x/inference_deployment/serving/paddleocr_official_api/typescript.md)
12
+ - [TypeScript SDK (English)](../../docs/version3.x/inference_deployment/serving/paddleocr_official_api/typescript.en.md)
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install @paddleocr/api-sdk
18
+ ```
19
+
20
+ This package follows SemVer and is published as a public scoped npm package.
21
+
22
+ For local development:
23
+
24
+ ```bash
25
+ npm install
26
+ npm run build
27
+ ```
28
+
29
+ ## Minimal Usage
30
+
31
+ Set `PADDLEOCR_ACCESS_TOKEN` or pass `token` to the client:
32
+
33
+ ```bash
34
+ export PADDLEOCR_ACCESS_TOKEN="your-access-token"
35
+ ```
36
+
37
+ ```ts
38
+ import { Model, PaddleOCRClient } from "@paddleocr/api-sdk";
39
+
40
+ const client = new PaddleOCRClient();
41
+ const result = await client.ocr({
42
+ model: Model.PPOCRv5,
43
+ fileUrl: "https://example.com/invoice.pdf",
44
+ });
45
+
46
+ console.log(result.jobId, result.pages.length);
47
+ ```
48
+
49
+ Specify `model: Model.PPOCRv6` (or `"PP-OCRv6"`) to use the PP-OCRv6 hosted OCR model.
50
+ Use `Model.PPOCRv5Latin` (or `"PP-OCRv5-latin"`) for the PP-OCRv5 Latin-script hosted OCR model.
51
+
52
+ Document parsing defaults to PaddleOCR-VL-1.6:
53
+
54
+ ```ts
55
+ const doc = await client.parseDocument({
56
+ filePath: "./report.pdf",
57
+ options: {
58
+ useChartRecognition: true,
59
+ },
60
+ });
61
+
62
+ console.log(doc.jobId, doc.pages.length);
63
+ ```
64
+
65
+ ## Build And Test
66
+
67
+ ```bash
68
+ npm run lint
69
+ npm run build
70
+ npm test
71
+ npm audit --audit-level=moderate
72
+ ```
ocr_webapp/PaddleOCR/api_sdk/typescript/README_cn.md ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PaddleOCR TypeScript SDK
2
+
3
+ [English](README.md) | 简体中文
4
+
5
+ 面向 PaddleOCR 官方 API 的 TypeScript 客户端。它会把 OCR 和文档解析任务提交到 PaddleOCR 官方托管服务;不会在本地执行 OCR 推理。
6
+
7
+ 正式用户文档:
8
+
9
+ - [TypeScript SDK](../../docs/version3.x/inference_deployment/serving/paddleocr_official_api/typescript.md)
10
+ - [TypeScript SDK(英文)](../../docs/version3.x/inference_deployment/serving/paddleocr_official_api/typescript.en.md)
11
+
12
+ ## 安装
13
+
14
+ ```bash
15
+ npm install @paddleocr/api-sdk
16
+ ```
17
+
18
+ 该包遵循语义化版本,并作为公开 scoped npm 包发布。
19
+
20
+ 本地开发:
21
+
22
+ ```bash
23
+ npm install
24
+ npm run build
25
+ ```
26
+
27
+ ## 最小示例
28
+
29
+ 设置 `PADDLEOCR_ACCESS_TOKEN`,或在构造客户端时传入 `token`:
30
+
31
+ ```bash
32
+ export PADDLEOCR_ACCESS_TOKEN="your-access-token"
33
+ ```
34
+
35
+ ```ts
36
+ import { Model, PaddleOCRClient } from "@paddleocr/api-sdk";
37
+
38
+ const client = new PaddleOCRClient();
39
+ const result = await client.ocr({
40
+ model: Model.PPOCRv5,
41
+ fileUrl: "https://example.com/invoice.pdf",
42
+ });
43
+
44
+ console.log(result.jobId, result.pages.length);
45
+ ```
46
+
47
+ 通过 `model: Model.PPOCRv6`(或 `"PP-OCRv6"`)可指定 PP-OCRv6 云端 OCR 模型。
48
+ 使用 `Model.PPOCRv5Latin`(或 `"PP-OCRv5-latin"`)可指定 PP-OCRv5 拉丁语系云端 OCR 模型。
49
+
50
+ 文档解析默认使用 PaddleOCR-VL-1.6:
51
+
52
+ ```ts
53
+ const doc = await client.parseDocument({
54
+ filePath: "./report.pdf",
55
+ options: {
56
+ useChartRecognition: true,
57
+ },
58
+ });
59
+
60
+ console.log(doc.jobId, doc.pages.length);
61
+ ```
62
+
63
+ ## 构建与测试
64
+
65
+ ```bash
66
+ npm run lint
67
+ npm run build
68
+ npm test
69
+ npm audit --audit-level=moderate
70
+ ```
ocr_webapp/PaddleOCR/api_sdk/typescript/examples/doc-parsing-file.ts ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import { PaddleOCRClient, Model } from "@paddleocr/api-sdk";
16
+
17
+ async function main() {
18
+ const client = new PaddleOCRClient();
19
+
20
+ // Convenience: doc parsing with local file
21
+ const result = await client.parseDocument({
22
+ model: Model.PPStructureV3,
23
+ filePath: "./sample.pdf",
24
+ options: { useChartRecognition: true },
25
+ });
26
+
27
+ for (const page of result.pages) {
28
+ console.log(page.markdownText);
29
+ }
30
+
31
+ // Manual control: submit + concurrent wait
32
+ const job1 = await client.submitOcr({ fileUrl: "https://example.com/f1.pdf" });
33
+ const job2 = await client.submitDocumentParsing({
34
+ model: Model.PPStructureV3,
35
+ filePath: "./sample.pdf",
36
+ });
37
+
38
+ const [r1, r2] = await Promise.all([
39
+ client.waitOcrResult(job1.jobId),
40
+ client.waitDocumentParsingResult(job2.jobId),
41
+ ]);
42
+
43
+ console.log("Job1 done:", r1);
44
+ console.log("Job2 done:", r2);
45
+ }
46
+
47
+ main().catch(console.error);
ocr_webapp/PaddleOCR/api_sdk/typescript/examples/ocr-url.ts ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import { PaddleOCRClient, Model } from "@paddleocr/api-sdk";
16
+
17
+ async function main() {
18
+ const client = new PaddleOCRClient();
19
+
20
+ // Convenience: OCR with URL
21
+ const ocrResult = await client.ocr({
22
+ fileUrl: "https://example.com/invoice.pdf",
23
+ });
24
+
25
+ for (const page of ocrResult.pages) {
26
+ console.log("Result:", page.prunedResult);
27
+ console.log("Image:", page.ocrImageUrl);
28
+ }
29
+ }
30
+
31
+ main().catch(console.error);
ocr_webapp/PaddleOCR/api_sdk/typescript/package-lock.json ADDED
@@ -0,0 +1,2640 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "@paddleocr/api-sdk",
3
+ "version": "0.2.2",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "@paddleocr/api-sdk",
9
+ "version": "0.2.2",
10
+ "license": "Apache-2.0",
11
+ "devDependencies": {
12
+ "@types/node": "^25.9.1",
13
+ "tsup": "^8.0.0",
14
+ "typescript": "^5.3.0",
15
+ "vitest": "^4.1.7"
16
+ },
17
+ "engines": {
18
+ "node": ">=18"
19
+ }
20
+ },
21
+ "node_modules/@emnapi/core": {
22
+ "version": "1.10.0",
23
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
24
+ "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
25
+ "dev": true,
26
+ "license": "MIT",
27
+ "optional": true,
28
+ "dependencies": {
29
+ "@emnapi/wasi-threads": "1.2.1",
30
+ "tslib": "^2.4.0"
31
+ }
32
+ },
33
+ "node_modules/@emnapi/runtime": {
34
+ "version": "1.10.0",
35
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
36
+ "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
37
+ "dev": true,
38
+ "license": "MIT",
39
+ "optional": true,
40
+ "dependencies": {
41
+ "tslib": "^2.4.0"
42
+ }
43
+ },
44
+ "node_modules/@emnapi/wasi-threads": {
45
+ "version": "1.2.1",
46
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
47
+ "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
48
+ "dev": true,
49
+ "license": "MIT",
50
+ "optional": true,
51
+ "dependencies": {
52
+ "tslib": "^2.4.0"
53
+ }
54
+ },
55
+ "node_modules/@esbuild/aix-ppc64": {
56
+ "version": "0.27.7",
57
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz",
58
+ "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==",
59
+ "cpu": [
60
+ "ppc64"
61
+ ],
62
+ "dev": true,
63
+ "license": "MIT",
64
+ "optional": true,
65
+ "os": [
66
+ "aix"
67
+ ],
68
+ "engines": {
69
+ "node": ">=18"
70
+ }
71
+ },
72
+ "node_modules/@esbuild/android-arm": {
73
+ "version": "0.27.7",
74
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz",
75
+ "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==",
76
+ "cpu": [
77
+ "arm"
78
+ ],
79
+ "dev": true,
80
+ "license": "MIT",
81
+ "optional": true,
82
+ "os": [
83
+ "android"
84
+ ],
85
+ "engines": {
86
+ "node": ">=18"
87
+ }
88
+ },
89
+ "node_modules/@esbuild/android-arm64": {
90
+ "version": "0.27.7",
91
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz",
92
+ "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==",
93
+ "cpu": [
94
+ "arm64"
95
+ ],
96
+ "dev": true,
97
+ "license": "MIT",
98
+ "optional": true,
99
+ "os": [
100
+ "android"
101
+ ],
102
+ "engines": {
103
+ "node": ">=18"
104
+ }
105
+ },
106
+ "node_modules/@esbuild/android-x64": {
107
+ "version": "0.27.7",
108
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz",
109
+ "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==",
110
+ "cpu": [
111
+ "x64"
112
+ ],
113
+ "dev": true,
114
+ "license": "MIT",
115
+ "optional": true,
116
+ "os": [
117
+ "android"
118
+ ],
119
+ "engines": {
120
+ "node": ">=18"
121
+ }
122
+ },
123
+ "node_modules/@esbuild/darwin-arm64": {
124
+ "version": "0.27.7",
125
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz",
126
+ "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==",
127
+ "cpu": [
128
+ "arm64"
129
+ ],
130
+ "dev": true,
131
+ "license": "MIT",
132
+ "optional": true,
133
+ "os": [
134
+ "darwin"
135
+ ],
136
+ "engines": {
137
+ "node": ">=18"
138
+ }
139
+ },
140
+ "node_modules/@esbuild/darwin-x64": {
141
+ "version": "0.27.7",
142
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz",
143
+ "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==",
144
+ "cpu": [
145
+ "x64"
146
+ ],
147
+ "dev": true,
148
+ "license": "MIT",
149
+ "optional": true,
150
+ "os": [
151
+ "darwin"
152
+ ],
153
+ "engines": {
154
+ "node": ">=18"
155
+ }
156
+ },
157
+ "node_modules/@esbuild/freebsd-arm64": {
158
+ "version": "0.27.7",
159
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz",
160
+ "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==",
161
+ "cpu": [
162
+ "arm64"
163
+ ],
164
+ "dev": true,
165
+ "license": "MIT",
166
+ "optional": true,
167
+ "os": [
168
+ "freebsd"
169
+ ],
170
+ "engines": {
171
+ "node": ">=18"
172
+ }
173
+ },
174
+ "node_modules/@esbuild/freebsd-x64": {
175
+ "version": "0.27.7",
176
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz",
177
+ "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==",
178
+ "cpu": [
179
+ "x64"
180
+ ],
181
+ "dev": true,
182
+ "license": "MIT",
183
+ "optional": true,
184
+ "os": [
185
+ "freebsd"
186
+ ],
187
+ "engines": {
188
+ "node": ">=18"
189
+ }
190
+ },
191
+ "node_modules/@esbuild/linux-arm": {
192
+ "version": "0.27.7",
193
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz",
194
+ "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==",
195
+ "cpu": [
196
+ "arm"
197
+ ],
198
+ "dev": true,
199
+ "license": "MIT",
200
+ "optional": true,
201
+ "os": [
202
+ "linux"
203
+ ],
204
+ "engines": {
205
+ "node": ">=18"
206
+ }
207
+ },
208
+ "node_modules/@esbuild/linux-arm64": {
209
+ "version": "0.27.7",
210
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz",
211
+ "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==",
212
+ "cpu": [
213
+ "arm64"
214
+ ],
215
+ "dev": true,
216
+ "license": "MIT",
217
+ "optional": true,
218
+ "os": [
219
+ "linux"
220
+ ],
221
+ "engines": {
222
+ "node": ">=18"
223
+ }
224
+ },
225
+ "node_modules/@esbuild/linux-ia32": {
226
+ "version": "0.27.7",
227
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz",
228
+ "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==",
229
+ "cpu": [
230
+ "ia32"
231
+ ],
232
+ "dev": true,
233
+ "license": "MIT",
234
+ "optional": true,
235
+ "os": [
236
+ "linux"
237
+ ],
238
+ "engines": {
239
+ "node": ">=18"
240
+ }
241
+ },
242
+ "node_modules/@esbuild/linux-loong64": {
243
+ "version": "0.27.7",
244
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz",
245
+ "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==",
246
+ "cpu": [
247
+ "loong64"
248
+ ],
249
+ "dev": true,
250
+ "license": "MIT",
251
+ "optional": true,
252
+ "os": [
253
+ "linux"
254
+ ],
255
+ "engines": {
256
+ "node": ">=18"
257
+ }
258
+ },
259
+ "node_modules/@esbuild/linux-mips64el": {
260
+ "version": "0.27.7",
261
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz",
262
+ "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==",
263
+ "cpu": [
264
+ "mips64el"
265
+ ],
266
+ "dev": true,
267
+ "license": "MIT",
268
+ "optional": true,
269
+ "os": [
270
+ "linux"
271
+ ],
272
+ "engines": {
273
+ "node": ">=18"
274
+ }
275
+ },
276
+ "node_modules/@esbuild/linux-ppc64": {
277
+ "version": "0.27.7",
278
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz",
279
+ "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==",
280
+ "cpu": [
281
+ "ppc64"
282
+ ],
283
+ "dev": true,
284
+ "license": "MIT",
285
+ "optional": true,
286
+ "os": [
287
+ "linux"
288
+ ],
289
+ "engines": {
290
+ "node": ">=18"
291
+ }
292
+ },
293
+ "node_modules/@esbuild/linux-riscv64": {
294
+ "version": "0.27.7",
295
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz",
296
+ "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==",
297
+ "cpu": [
298
+ "riscv64"
299
+ ],
300
+ "dev": true,
301
+ "license": "MIT",
302
+ "optional": true,
303
+ "os": [
304
+ "linux"
305
+ ],
306
+ "engines": {
307
+ "node": ">=18"
308
+ }
309
+ },
310
+ "node_modules/@esbuild/linux-s390x": {
311
+ "version": "0.27.7",
312
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz",
313
+ "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==",
314
+ "cpu": [
315
+ "s390x"
316
+ ],
317
+ "dev": true,
318
+ "license": "MIT",
319
+ "optional": true,
320
+ "os": [
321
+ "linux"
322
+ ],
323
+ "engines": {
324
+ "node": ">=18"
325
+ }
326
+ },
327
+ "node_modules/@esbuild/linux-x64": {
328
+ "version": "0.27.7",
329
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz",
330
+ "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==",
331
+ "cpu": [
332
+ "x64"
333
+ ],
334
+ "dev": true,
335
+ "license": "MIT",
336
+ "optional": true,
337
+ "os": [
338
+ "linux"
339
+ ],
340
+ "engines": {
341
+ "node": ">=18"
342
+ }
343
+ },
344
+ "node_modules/@esbuild/netbsd-arm64": {
345
+ "version": "0.27.7",
346
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz",
347
+ "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==",
348
+ "cpu": [
349
+ "arm64"
350
+ ],
351
+ "dev": true,
352
+ "license": "MIT",
353
+ "optional": true,
354
+ "os": [
355
+ "netbsd"
356
+ ],
357
+ "engines": {
358
+ "node": ">=18"
359
+ }
360
+ },
361
+ "node_modules/@esbuild/netbsd-x64": {
362
+ "version": "0.27.7",
363
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz",
364
+ "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==",
365
+ "cpu": [
366
+ "x64"
367
+ ],
368
+ "dev": true,
369
+ "license": "MIT",
370
+ "optional": true,
371
+ "os": [
372
+ "netbsd"
373
+ ],
374
+ "engines": {
375
+ "node": ">=18"
376
+ }
377
+ },
378
+ "node_modules/@esbuild/openbsd-arm64": {
379
+ "version": "0.27.7",
380
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz",
381
+ "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==",
382
+ "cpu": [
383
+ "arm64"
384
+ ],
385
+ "dev": true,
386
+ "license": "MIT",
387
+ "optional": true,
388
+ "os": [
389
+ "openbsd"
390
+ ],
391
+ "engines": {
392
+ "node": ">=18"
393
+ }
394
+ },
395
+ "node_modules/@esbuild/openbsd-x64": {
396
+ "version": "0.27.7",
397
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz",
398
+ "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==",
399
+ "cpu": [
400
+ "x64"
401
+ ],
402
+ "dev": true,
403
+ "license": "MIT",
404
+ "optional": true,
405
+ "os": [
406
+ "openbsd"
407
+ ],
408
+ "engines": {
409
+ "node": ">=18"
410
+ }
411
+ },
412
+ "node_modules/@esbuild/openharmony-arm64": {
413
+ "version": "0.27.7",
414
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz",
415
+ "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==",
416
+ "cpu": [
417
+ "arm64"
418
+ ],
419
+ "dev": true,
420
+ "license": "MIT",
421
+ "optional": true,
422
+ "os": [
423
+ "openharmony"
424
+ ],
425
+ "engines": {
426
+ "node": ">=18"
427
+ }
428
+ },
429
+ "node_modules/@esbuild/sunos-x64": {
430
+ "version": "0.27.7",
431
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz",
432
+ "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==",
433
+ "cpu": [
434
+ "x64"
435
+ ],
436
+ "dev": true,
437
+ "license": "MIT",
438
+ "optional": true,
439
+ "os": [
440
+ "sunos"
441
+ ],
442
+ "engines": {
443
+ "node": ">=18"
444
+ }
445
+ },
446
+ "node_modules/@esbuild/win32-arm64": {
447
+ "version": "0.27.7",
448
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz",
449
+ "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==",
450
+ "cpu": [
451
+ "arm64"
452
+ ],
453
+ "dev": true,
454
+ "license": "MIT",
455
+ "optional": true,
456
+ "os": [
457
+ "win32"
458
+ ],
459
+ "engines": {
460
+ "node": ">=18"
461
+ }
462
+ },
463
+ "node_modules/@esbuild/win32-ia32": {
464
+ "version": "0.27.7",
465
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz",
466
+ "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==",
467
+ "cpu": [
468
+ "ia32"
469
+ ],
470
+ "dev": true,
471
+ "license": "MIT",
472
+ "optional": true,
473
+ "os": [
474
+ "win32"
475
+ ],
476
+ "engines": {
477
+ "node": ">=18"
478
+ }
479
+ },
480
+ "node_modules/@esbuild/win32-x64": {
481
+ "version": "0.27.7",
482
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz",
483
+ "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==",
484
+ "cpu": [
485
+ "x64"
486
+ ],
487
+ "dev": true,
488
+ "license": "MIT",
489
+ "optional": true,
490
+ "os": [
491
+ "win32"
492
+ ],
493
+ "engines": {
494
+ "node": ">=18"
495
+ }
496
+ },
497
+ "node_modules/@jridgewell/gen-mapping": {
498
+ "version": "0.3.13",
499
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
500
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
501
+ "dev": true,
502
+ "license": "MIT",
503
+ "dependencies": {
504
+ "@jridgewell/sourcemap-codec": "^1.5.0",
505
+ "@jridgewell/trace-mapping": "^0.3.24"
506
+ }
507
+ },
508
+ "node_modules/@jridgewell/resolve-uri": {
509
+ "version": "3.1.2",
510
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
511
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
512
+ "dev": true,
513
+ "license": "MIT",
514
+ "engines": {
515
+ "node": ">=6.0.0"
516
+ }
517
+ },
518
+ "node_modules/@jridgewell/sourcemap-codec": {
519
+ "version": "1.5.5",
520
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
521
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
522
+ "dev": true,
523
+ "license": "MIT"
524
+ },
525
+ "node_modules/@jridgewell/trace-mapping": {
526
+ "version": "0.3.31",
527
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
528
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
529
+ "dev": true,
530
+ "license": "MIT",
531
+ "dependencies": {
532
+ "@jridgewell/resolve-uri": "^3.1.0",
533
+ "@jridgewell/sourcemap-codec": "^1.4.14"
534
+ }
535
+ },
536
+ "node_modules/@napi-rs/wasm-runtime": {
537
+ "version": "1.1.4",
538
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz",
539
+ "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
540
+ "dev": true,
541
+ "license": "MIT",
542
+ "optional": true,
543
+ "dependencies": {
544
+ "@tybys/wasm-util": "^0.10.1"
545
+ },
546
+ "funding": {
547
+ "type": "github",
548
+ "url": "https://github.com/sponsors/Brooooooklyn"
549
+ },
550
+ "peerDependencies": {
551
+ "@emnapi/core": "^1.7.1",
552
+ "@emnapi/runtime": "^1.7.1"
553
+ }
554
+ },
555
+ "node_modules/@oxc-project/types": {
556
+ "version": "0.132.0",
557
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.132.0.tgz",
558
+ "integrity": "sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==",
559
+ "dev": true,
560
+ "license": "MIT",
561
+ "funding": {
562
+ "url": "https://github.com/sponsors/Boshen"
563
+ }
564
+ },
565
+ "node_modules/@rolldown/binding-android-arm64": {
566
+ "version": "1.0.2",
567
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.2.tgz",
568
+ "integrity": "sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==",
569
+ "cpu": [
570
+ "arm64"
571
+ ],
572
+ "dev": true,
573
+ "license": "MIT",
574
+ "optional": true,
575
+ "os": [
576
+ "android"
577
+ ],
578
+ "engines": {
579
+ "node": "^20.19.0 || >=22.12.0"
580
+ }
581
+ },
582
+ "node_modules/@rolldown/binding-darwin-arm64": {
583
+ "version": "1.0.2",
584
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.2.tgz",
585
+ "integrity": "sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==",
586
+ "cpu": [
587
+ "arm64"
588
+ ],
589
+ "dev": true,
590
+ "license": "MIT",
591
+ "optional": true,
592
+ "os": [
593
+ "darwin"
594
+ ],
595
+ "engines": {
596
+ "node": "^20.19.0 || >=22.12.0"
597
+ }
598
+ },
599
+ "node_modules/@rolldown/binding-darwin-x64": {
600
+ "version": "1.0.2",
601
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.2.tgz",
602
+ "integrity": "sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==",
603
+ "cpu": [
604
+ "x64"
605
+ ],
606
+ "dev": true,
607
+ "license": "MIT",
608
+ "optional": true,
609
+ "os": [
610
+ "darwin"
611
+ ],
612
+ "engines": {
613
+ "node": "^20.19.0 || >=22.12.0"
614
+ }
615
+ },
616
+ "node_modules/@rolldown/binding-freebsd-x64": {
617
+ "version": "1.0.2",
618
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.2.tgz",
619
+ "integrity": "sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==",
620
+ "cpu": [
621
+ "x64"
622
+ ],
623
+ "dev": true,
624
+ "license": "MIT",
625
+ "optional": true,
626
+ "os": [
627
+ "freebsd"
628
+ ],
629
+ "engines": {
630
+ "node": "^20.19.0 || >=22.12.0"
631
+ }
632
+ },
633
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
634
+ "version": "1.0.2",
635
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.2.tgz",
636
+ "integrity": "sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==",
637
+ "cpu": [
638
+ "arm"
639
+ ],
640
+ "dev": true,
641
+ "license": "MIT",
642
+ "optional": true,
643
+ "os": [
644
+ "linux"
645
+ ],
646
+ "engines": {
647
+ "node": "^20.19.0 || >=22.12.0"
648
+ }
649
+ },
650
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
651
+ "version": "1.0.2",
652
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.2.tgz",
653
+ "integrity": "sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==",
654
+ "cpu": [
655
+ "arm64"
656
+ ],
657
+ "dev": true,
658
+ "license": "MIT",
659
+ "optional": true,
660
+ "os": [
661
+ "linux"
662
+ ],
663
+ "engines": {
664
+ "node": "^20.19.0 || >=22.12.0"
665
+ }
666
+ },
667
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
668
+ "version": "1.0.2",
669
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.2.tgz",
670
+ "integrity": "sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==",
671
+ "cpu": [
672
+ "arm64"
673
+ ],
674
+ "dev": true,
675
+ "license": "MIT",
676
+ "optional": true,
677
+ "os": [
678
+ "linux"
679
+ ],
680
+ "engines": {
681
+ "node": "^20.19.0 || >=22.12.0"
682
+ }
683
+ },
684
+ "node_modules/@rolldown/binding-linux-ppc64-gnu": {
685
+ "version": "1.0.2",
686
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.2.tgz",
687
+ "integrity": "sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==",
688
+ "cpu": [
689
+ "ppc64"
690
+ ],
691
+ "dev": true,
692
+ "license": "MIT",
693
+ "optional": true,
694
+ "os": [
695
+ "linux"
696
+ ],
697
+ "engines": {
698
+ "node": "^20.19.0 || >=22.12.0"
699
+ }
700
+ },
701
+ "node_modules/@rolldown/binding-linux-s390x-gnu": {
702
+ "version": "1.0.2",
703
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.2.tgz",
704
+ "integrity": "sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==",
705
+ "cpu": [
706
+ "s390x"
707
+ ],
708
+ "dev": true,
709
+ "license": "MIT",
710
+ "optional": true,
711
+ "os": [
712
+ "linux"
713
+ ],
714
+ "engines": {
715
+ "node": "^20.19.0 || >=22.12.0"
716
+ }
717
+ },
718
+ "node_modules/@rolldown/binding-linux-x64-gnu": {
719
+ "version": "1.0.2",
720
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.2.tgz",
721
+ "integrity": "sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==",
722
+ "cpu": [
723
+ "x64"
724
+ ],
725
+ "dev": true,
726
+ "license": "MIT",
727
+ "optional": true,
728
+ "os": [
729
+ "linux"
730
+ ],
731
+ "engines": {
732
+ "node": "^20.19.0 || >=22.12.0"
733
+ }
734
+ },
735
+ "node_modules/@rolldown/binding-linux-x64-musl": {
736
+ "version": "1.0.2",
737
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.2.tgz",
738
+ "integrity": "sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==",
739
+ "cpu": [
740
+ "x64"
741
+ ],
742
+ "dev": true,
743
+ "license": "MIT",
744
+ "optional": true,
745
+ "os": [
746
+ "linux"
747
+ ],
748
+ "engines": {
749
+ "node": "^20.19.0 || >=22.12.0"
750
+ }
751
+ },
752
+ "node_modules/@rolldown/binding-openharmony-arm64": {
753
+ "version": "1.0.2",
754
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.2.tgz",
755
+ "integrity": "sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==",
756
+ "cpu": [
757
+ "arm64"
758
+ ],
759
+ "dev": true,
760
+ "license": "MIT",
761
+ "optional": true,
762
+ "os": [
763
+ "openharmony"
764
+ ],
765
+ "engines": {
766
+ "node": "^20.19.0 || >=22.12.0"
767
+ }
768
+ },
769
+ "node_modules/@rolldown/binding-wasm32-wasi": {
770
+ "version": "1.0.2",
771
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.2.tgz",
772
+ "integrity": "sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==",
773
+ "cpu": [
774
+ "wasm32"
775
+ ],
776
+ "dev": true,
777
+ "license": "MIT",
778
+ "optional": true,
779
+ "dependencies": {
780
+ "@emnapi/core": "1.10.0",
781
+ "@emnapi/runtime": "1.10.0",
782
+ "@napi-rs/wasm-runtime": "^1.1.4"
783
+ },
784
+ "engines": {
785
+ "node": "^20.19.0 || >=22.12.0"
786
+ }
787
+ },
788
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
789
+ "version": "1.0.2",
790
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.2.tgz",
791
+ "integrity": "sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==",
792
+ "cpu": [
793
+ "arm64"
794
+ ],
795
+ "dev": true,
796
+ "license": "MIT",
797
+ "optional": true,
798
+ "os": [
799
+ "win32"
800
+ ],
801
+ "engines": {
802
+ "node": "^20.19.0 || >=22.12.0"
803
+ }
804
+ },
805
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
806
+ "version": "1.0.2",
807
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.2.tgz",
808
+ "integrity": "sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==",
809
+ "cpu": [
810
+ "x64"
811
+ ],
812
+ "dev": true,
813
+ "license": "MIT",
814
+ "optional": true,
815
+ "os": [
816
+ "win32"
817
+ ],
818
+ "engines": {
819
+ "node": "^20.19.0 || >=22.12.0"
820
+ }
821
+ },
822
+ "node_modules/@rolldown/pluginutils": {
823
+ "version": "1.0.1",
824
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
825
+ "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
826
+ "dev": true,
827
+ "license": "MIT"
828
+ },
829
+ "node_modules/@rollup/rollup-android-arm-eabi": {
830
+ "version": "4.60.4",
831
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.4.tgz",
832
+ "integrity": "sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==",
833
+ "cpu": [
834
+ "arm"
835
+ ],
836
+ "dev": true,
837
+ "license": "MIT",
838
+ "optional": true,
839
+ "os": [
840
+ "android"
841
+ ]
842
+ },
843
+ "node_modules/@rollup/rollup-android-arm64": {
844
+ "version": "4.60.4",
845
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.4.tgz",
846
+ "integrity": "sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==",
847
+ "cpu": [
848
+ "arm64"
849
+ ],
850
+ "dev": true,
851
+ "license": "MIT",
852
+ "optional": true,
853
+ "os": [
854
+ "android"
855
+ ]
856
+ },
857
+ "node_modules/@rollup/rollup-darwin-arm64": {
858
+ "version": "4.60.4",
859
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.4.tgz",
860
+ "integrity": "sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==",
861
+ "cpu": [
862
+ "arm64"
863
+ ],
864
+ "dev": true,
865
+ "license": "MIT",
866
+ "optional": true,
867
+ "os": [
868
+ "darwin"
869
+ ]
870
+ },
871
+ "node_modules/@rollup/rollup-darwin-x64": {
872
+ "version": "4.60.4",
873
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.4.tgz",
874
+ "integrity": "sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==",
875
+ "cpu": [
876
+ "x64"
877
+ ],
878
+ "dev": true,
879
+ "license": "MIT",
880
+ "optional": true,
881
+ "os": [
882
+ "darwin"
883
+ ]
884
+ },
885
+ "node_modules/@rollup/rollup-freebsd-arm64": {
886
+ "version": "4.60.4",
887
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.4.tgz",
888
+ "integrity": "sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==",
889
+ "cpu": [
890
+ "arm64"
891
+ ],
892
+ "dev": true,
893
+ "license": "MIT",
894
+ "optional": true,
895
+ "os": [
896
+ "freebsd"
897
+ ]
898
+ },
899
+ "node_modules/@rollup/rollup-freebsd-x64": {
900
+ "version": "4.60.4",
901
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.4.tgz",
902
+ "integrity": "sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==",
903
+ "cpu": [
904
+ "x64"
905
+ ],
906
+ "dev": true,
907
+ "license": "MIT",
908
+ "optional": true,
909
+ "os": [
910
+ "freebsd"
911
+ ]
912
+ },
913
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
914
+ "version": "4.60.4",
915
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.4.tgz",
916
+ "integrity": "sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==",
917
+ "cpu": [
918
+ "arm"
919
+ ],
920
+ "dev": true,
921
+ "license": "MIT",
922
+ "optional": true,
923
+ "os": [
924
+ "linux"
925
+ ]
926
+ },
927
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
928
+ "version": "4.60.4",
929
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.4.tgz",
930
+ "integrity": "sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==",
931
+ "cpu": [
932
+ "arm"
933
+ ],
934
+ "dev": true,
935
+ "license": "MIT",
936
+ "optional": true,
937
+ "os": [
938
+ "linux"
939
+ ]
940
+ },
941
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
942
+ "version": "4.60.4",
943
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.4.tgz",
944
+ "integrity": "sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==",
945
+ "cpu": [
946
+ "arm64"
947
+ ],
948
+ "dev": true,
949
+ "license": "MIT",
950
+ "optional": true,
951
+ "os": [
952
+ "linux"
953
+ ]
954
+ },
955
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
956
+ "version": "4.60.4",
957
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.4.tgz",
958
+ "integrity": "sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==",
959
+ "cpu": [
960
+ "arm64"
961
+ ],
962
+ "dev": true,
963
+ "license": "MIT",
964
+ "optional": true,
965
+ "os": [
966
+ "linux"
967
+ ]
968
+ },
969
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
970
+ "version": "4.60.4",
971
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.4.tgz",
972
+ "integrity": "sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==",
973
+ "cpu": [
974
+ "loong64"
975
+ ],
976
+ "dev": true,
977
+ "license": "MIT",
978
+ "optional": true,
979
+ "os": [
980
+ "linux"
981
+ ]
982
+ },
983
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
984
+ "version": "4.60.4",
985
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.4.tgz",
986
+ "integrity": "sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==",
987
+ "cpu": [
988
+ "loong64"
989
+ ],
990
+ "dev": true,
991
+ "license": "MIT",
992
+ "optional": true,
993
+ "os": [
994
+ "linux"
995
+ ]
996
+ },
997
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
998
+ "version": "4.60.4",
999
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.4.tgz",
1000
+ "integrity": "sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==",
1001
+ "cpu": [
1002
+ "ppc64"
1003
+ ],
1004
+ "dev": true,
1005
+ "license": "MIT",
1006
+ "optional": true,
1007
+ "os": [
1008
+ "linux"
1009
+ ]
1010
+ },
1011
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
1012
+ "version": "4.60.4",
1013
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.4.tgz",
1014
+ "integrity": "sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==",
1015
+ "cpu": [
1016
+ "ppc64"
1017
+ ],
1018
+ "dev": true,
1019
+ "license": "MIT",
1020
+ "optional": true,
1021
+ "os": [
1022
+ "linux"
1023
+ ]
1024
+ },
1025
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
1026
+ "version": "4.60.4",
1027
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.4.tgz",
1028
+ "integrity": "sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==",
1029
+ "cpu": [
1030
+ "riscv64"
1031
+ ],
1032
+ "dev": true,
1033
+ "license": "MIT",
1034
+ "optional": true,
1035
+ "os": [
1036
+ "linux"
1037
+ ]
1038
+ },
1039
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
1040
+ "version": "4.60.4",
1041
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.4.tgz",
1042
+ "integrity": "sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==",
1043
+ "cpu": [
1044
+ "riscv64"
1045
+ ],
1046
+ "dev": true,
1047
+ "license": "MIT",
1048
+ "optional": true,
1049
+ "os": [
1050
+ "linux"
1051
+ ]
1052
+ },
1053
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
1054
+ "version": "4.60.4",
1055
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.4.tgz",
1056
+ "integrity": "sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==",
1057
+ "cpu": [
1058
+ "s390x"
1059
+ ],
1060
+ "dev": true,
1061
+ "license": "MIT",
1062
+ "optional": true,
1063
+ "os": [
1064
+ "linux"
1065
+ ]
1066
+ },
1067
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
1068
+ "version": "4.60.4",
1069
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.4.tgz",
1070
+ "integrity": "sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==",
1071
+ "cpu": [
1072
+ "x64"
1073
+ ],
1074
+ "dev": true,
1075
+ "license": "MIT",
1076
+ "optional": true,
1077
+ "os": [
1078
+ "linux"
1079
+ ]
1080
+ },
1081
+ "node_modules/@rollup/rollup-linux-x64-musl": {
1082
+ "version": "4.60.4",
1083
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.4.tgz",
1084
+ "integrity": "sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==",
1085
+ "cpu": [
1086
+ "x64"
1087
+ ],
1088
+ "dev": true,
1089
+ "license": "MIT",
1090
+ "optional": true,
1091
+ "os": [
1092
+ "linux"
1093
+ ]
1094
+ },
1095
+ "node_modules/@rollup/rollup-openbsd-x64": {
1096
+ "version": "4.60.4",
1097
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.4.tgz",
1098
+ "integrity": "sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==",
1099
+ "cpu": [
1100
+ "x64"
1101
+ ],
1102
+ "dev": true,
1103
+ "license": "MIT",
1104
+ "optional": true,
1105
+ "os": [
1106
+ "openbsd"
1107
+ ]
1108
+ },
1109
+ "node_modules/@rollup/rollup-openharmony-arm64": {
1110
+ "version": "4.60.4",
1111
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.4.tgz",
1112
+ "integrity": "sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==",
1113
+ "cpu": [
1114
+ "arm64"
1115
+ ],
1116
+ "dev": true,
1117
+ "license": "MIT",
1118
+ "optional": true,
1119
+ "os": [
1120
+ "openharmony"
1121
+ ]
1122
+ },
1123
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
1124
+ "version": "4.60.4",
1125
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.4.tgz",
1126
+ "integrity": "sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==",
1127
+ "cpu": [
1128
+ "arm64"
1129
+ ],
1130
+ "dev": true,
1131
+ "license": "MIT",
1132
+ "optional": true,
1133
+ "os": [
1134
+ "win32"
1135
+ ]
1136
+ },
1137
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
1138
+ "version": "4.60.4",
1139
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.4.tgz",
1140
+ "integrity": "sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==",
1141
+ "cpu": [
1142
+ "ia32"
1143
+ ],
1144
+ "dev": true,
1145
+ "license": "MIT",
1146
+ "optional": true,
1147
+ "os": [
1148
+ "win32"
1149
+ ]
1150
+ },
1151
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
1152
+ "version": "4.60.4",
1153
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.4.tgz",
1154
+ "integrity": "sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==",
1155
+ "cpu": [
1156
+ "x64"
1157
+ ],
1158
+ "dev": true,
1159
+ "license": "MIT",
1160
+ "optional": true,
1161
+ "os": [
1162
+ "win32"
1163
+ ]
1164
+ },
1165
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
1166
+ "version": "4.60.4",
1167
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.4.tgz",
1168
+ "integrity": "sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==",
1169
+ "cpu": [
1170
+ "x64"
1171
+ ],
1172
+ "dev": true,
1173
+ "license": "MIT",
1174
+ "optional": true,
1175
+ "os": [
1176
+ "win32"
1177
+ ]
1178
+ },
1179
+ "node_modules/@standard-schema/spec": {
1180
+ "version": "1.1.0",
1181
+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
1182
+ "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
1183
+ "dev": true,
1184
+ "license": "MIT"
1185
+ },
1186
+ "node_modules/@tybys/wasm-util": {
1187
+ "version": "0.10.2",
1188
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz",
1189
+ "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==",
1190
+ "dev": true,
1191
+ "license": "MIT",
1192
+ "optional": true,
1193
+ "dependencies": {
1194
+ "tslib": "^2.4.0"
1195
+ }
1196
+ },
1197
+ "node_modules/@types/chai": {
1198
+ "version": "5.2.3",
1199
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
1200
+ "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==",
1201
+ "dev": true,
1202
+ "license": "MIT",
1203
+ "dependencies": {
1204
+ "@types/deep-eql": "*",
1205
+ "assertion-error": "^2.0.1"
1206
+ }
1207
+ },
1208
+ "node_modules/@types/deep-eql": {
1209
+ "version": "4.0.2",
1210
+ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
1211
+ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
1212
+ "dev": true,
1213
+ "license": "MIT"
1214
+ },
1215
+ "node_modules/@types/estree": {
1216
+ "version": "1.0.8",
1217
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
1218
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
1219
+ "dev": true,
1220
+ "license": "MIT"
1221
+ },
1222
+ "node_modules/@types/node": {
1223
+ "version": "25.9.1",
1224
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz",
1225
+ "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==",
1226
+ "dev": true,
1227
+ "license": "MIT",
1228
+ "dependencies": {
1229
+ "undici-types": ">=7.24.0 <7.24.7"
1230
+ }
1231
+ },
1232
+ "node_modules/@vitest/expect": {
1233
+ "version": "4.1.7",
1234
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.7.tgz",
1235
+ "integrity": "sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==",
1236
+ "dev": true,
1237
+ "license": "MIT",
1238
+ "dependencies": {
1239
+ "@standard-schema/spec": "^1.1.0",
1240
+ "@types/chai": "^5.2.2",
1241
+ "@vitest/spy": "4.1.7",
1242
+ "@vitest/utils": "4.1.7",
1243
+ "chai": "^6.2.2",
1244
+ "tinyrainbow": "^3.1.0"
1245
+ },
1246
+ "funding": {
1247
+ "url": "https://opencollective.com/vitest"
1248
+ }
1249
+ },
1250
+ "node_modules/@vitest/mocker": {
1251
+ "version": "4.1.7",
1252
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.7.tgz",
1253
+ "integrity": "sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==",
1254
+ "dev": true,
1255
+ "license": "MIT",
1256
+ "dependencies": {
1257
+ "@vitest/spy": "4.1.7",
1258
+ "estree-walker": "^3.0.3",
1259
+ "magic-string": "^0.30.21"
1260
+ },
1261
+ "funding": {
1262
+ "url": "https://opencollective.com/vitest"
1263
+ },
1264
+ "peerDependencies": {
1265
+ "msw": "^2.4.9",
1266
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
1267
+ },
1268
+ "peerDependenciesMeta": {
1269
+ "msw": {
1270
+ "optional": true
1271
+ },
1272
+ "vite": {
1273
+ "optional": true
1274
+ }
1275
+ }
1276
+ },
1277
+ "node_modules/@vitest/pretty-format": {
1278
+ "version": "4.1.7",
1279
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.7.tgz",
1280
+ "integrity": "sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==",
1281
+ "dev": true,
1282
+ "license": "MIT",
1283
+ "dependencies": {
1284
+ "tinyrainbow": "^3.1.0"
1285
+ },
1286
+ "funding": {
1287
+ "url": "https://opencollective.com/vitest"
1288
+ }
1289
+ },
1290
+ "node_modules/@vitest/runner": {
1291
+ "version": "4.1.7",
1292
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.7.tgz",
1293
+ "integrity": "sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==",
1294
+ "dev": true,
1295
+ "license": "MIT",
1296
+ "dependencies": {
1297
+ "@vitest/utils": "4.1.7",
1298
+ "pathe": "^2.0.3"
1299
+ },
1300
+ "funding": {
1301
+ "url": "https://opencollective.com/vitest"
1302
+ }
1303
+ },
1304
+ "node_modules/@vitest/snapshot": {
1305
+ "version": "4.1.7",
1306
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.7.tgz",
1307
+ "integrity": "sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==",
1308
+ "dev": true,
1309
+ "license": "MIT",
1310
+ "dependencies": {
1311
+ "@vitest/pretty-format": "4.1.7",
1312
+ "@vitest/utils": "4.1.7",
1313
+ "magic-string": "^0.30.21",
1314
+ "pathe": "^2.0.3"
1315
+ },
1316
+ "funding": {
1317
+ "url": "https://opencollective.com/vitest"
1318
+ }
1319
+ },
1320
+ "node_modules/@vitest/spy": {
1321
+ "version": "4.1.7",
1322
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.7.tgz",
1323
+ "integrity": "sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==",
1324
+ "dev": true,
1325
+ "license": "MIT",
1326
+ "funding": {
1327
+ "url": "https://opencollective.com/vitest"
1328
+ }
1329
+ },
1330
+ "node_modules/@vitest/utils": {
1331
+ "version": "4.1.7",
1332
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.7.tgz",
1333
+ "integrity": "sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==",
1334
+ "dev": true,
1335
+ "license": "MIT",
1336
+ "dependencies": {
1337
+ "@vitest/pretty-format": "4.1.7",
1338
+ "convert-source-map": "^2.0.0",
1339
+ "tinyrainbow": "^3.1.0"
1340
+ },
1341
+ "funding": {
1342
+ "url": "https://opencollective.com/vitest"
1343
+ }
1344
+ },
1345
+ "node_modules/acorn": {
1346
+ "version": "8.16.0",
1347
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
1348
+ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
1349
+ "dev": true,
1350
+ "license": "MIT",
1351
+ "bin": {
1352
+ "acorn": "bin/acorn"
1353
+ },
1354
+ "engines": {
1355
+ "node": ">=0.4.0"
1356
+ }
1357
+ },
1358
+ "node_modules/any-promise": {
1359
+ "version": "1.3.0",
1360
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
1361
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
1362
+ "dev": true,
1363
+ "license": "MIT"
1364
+ },
1365
+ "node_modules/assertion-error": {
1366
+ "version": "2.0.1",
1367
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
1368
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
1369
+ "dev": true,
1370
+ "license": "MIT",
1371
+ "engines": {
1372
+ "node": ">=12"
1373
+ }
1374
+ },
1375
+ "node_modules/bundle-require": {
1376
+ "version": "5.1.0",
1377
+ "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz",
1378
+ "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==",
1379
+ "dev": true,
1380
+ "license": "MIT",
1381
+ "dependencies": {
1382
+ "load-tsconfig": "^0.2.3"
1383
+ },
1384
+ "engines": {
1385
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
1386
+ },
1387
+ "peerDependencies": {
1388
+ "esbuild": ">=0.18"
1389
+ }
1390
+ },
1391
+ "node_modules/cac": {
1392
+ "version": "6.7.14",
1393
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
1394
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
1395
+ "dev": true,
1396
+ "license": "MIT",
1397
+ "engines": {
1398
+ "node": ">=8"
1399
+ }
1400
+ },
1401
+ "node_modules/chai": {
1402
+ "version": "6.2.2",
1403
+ "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz",
1404
+ "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==",
1405
+ "dev": true,
1406
+ "license": "MIT",
1407
+ "engines": {
1408
+ "node": ">=18"
1409
+ }
1410
+ },
1411
+ "node_modules/chokidar": {
1412
+ "version": "4.0.3",
1413
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
1414
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
1415
+ "dev": true,
1416
+ "license": "MIT",
1417
+ "dependencies": {
1418
+ "readdirp": "^4.0.1"
1419
+ },
1420
+ "engines": {
1421
+ "node": ">= 14.16.0"
1422
+ },
1423
+ "funding": {
1424
+ "url": "https://paulmillr.com/funding/"
1425
+ }
1426
+ },
1427
+ "node_modules/commander": {
1428
+ "version": "4.1.1",
1429
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
1430
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
1431
+ "dev": true,
1432
+ "license": "MIT",
1433
+ "engines": {
1434
+ "node": ">= 6"
1435
+ }
1436
+ },
1437
+ "node_modules/confbox": {
1438
+ "version": "0.1.8",
1439
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
1440
+ "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
1441
+ "dev": true,
1442
+ "license": "MIT"
1443
+ },
1444
+ "node_modules/consola": {
1445
+ "version": "3.4.2",
1446
+ "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
1447
+ "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==",
1448
+ "dev": true,
1449
+ "license": "MIT",
1450
+ "engines": {
1451
+ "node": "^14.18.0 || >=16.10.0"
1452
+ }
1453
+ },
1454
+ "node_modules/convert-source-map": {
1455
+ "version": "2.0.0",
1456
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
1457
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
1458
+ "dev": true,
1459
+ "license": "MIT"
1460
+ },
1461
+ "node_modules/debug": {
1462
+ "version": "4.4.3",
1463
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
1464
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
1465
+ "dev": true,
1466
+ "license": "MIT",
1467
+ "dependencies": {
1468
+ "ms": "^2.1.3"
1469
+ },
1470
+ "engines": {
1471
+ "node": ">=6.0"
1472
+ },
1473
+ "peerDependenciesMeta": {
1474
+ "supports-color": {
1475
+ "optional": true
1476
+ }
1477
+ }
1478
+ },
1479
+ "node_modules/detect-libc": {
1480
+ "version": "2.1.2",
1481
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
1482
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
1483
+ "dev": true,
1484
+ "license": "Apache-2.0",
1485
+ "engines": {
1486
+ "node": ">=8"
1487
+ }
1488
+ },
1489
+ "node_modules/es-module-lexer": {
1490
+ "version": "2.1.0",
1491
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz",
1492
+ "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==",
1493
+ "dev": true,
1494
+ "license": "MIT"
1495
+ },
1496
+ "node_modules/esbuild": {
1497
+ "version": "0.27.7",
1498
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz",
1499
+ "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==",
1500
+ "dev": true,
1501
+ "hasInstallScript": true,
1502
+ "license": "MIT",
1503
+ "bin": {
1504
+ "esbuild": "bin/esbuild"
1505
+ },
1506
+ "engines": {
1507
+ "node": ">=18"
1508
+ },
1509
+ "optionalDependencies": {
1510
+ "@esbuild/aix-ppc64": "0.27.7",
1511
+ "@esbuild/android-arm": "0.27.7",
1512
+ "@esbuild/android-arm64": "0.27.7",
1513
+ "@esbuild/android-x64": "0.27.7",
1514
+ "@esbuild/darwin-arm64": "0.27.7",
1515
+ "@esbuild/darwin-x64": "0.27.7",
1516
+ "@esbuild/freebsd-arm64": "0.27.7",
1517
+ "@esbuild/freebsd-x64": "0.27.7",
1518
+ "@esbuild/linux-arm": "0.27.7",
1519
+ "@esbuild/linux-arm64": "0.27.7",
1520
+ "@esbuild/linux-ia32": "0.27.7",
1521
+ "@esbuild/linux-loong64": "0.27.7",
1522
+ "@esbuild/linux-mips64el": "0.27.7",
1523
+ "@esbuild/linux-ppc64": "0.27.7",
1524
+ "@esbuild/linux-riscv64": "0.27.7",
1525
+ "@esbuild/linux-s390x": "0.27.7",
1526
+ "@esbuild/linux-x64": "0.27.7",
1527
+ "@esbuild/netbsd-arm64": "0.27.7",
1528
+ "@esbuild/netbsd-x64": "0.27.7",
1529
+ "@esbuild/openbsd-arm64": "0.27.7",
1530
+ "@esbuild/openbsd-x64": "0.27.7",
1531
+ "@esbuild/openharmony-arm64": "0.27.7",
1532
+ "@esbuild/sunos-x64": "0.27.7",
1533
+ "@esbuild/win32-arm64": "0.27.7",
1534
+ "@esbuild/win32-ia32": "0.27.7",
1535
+ "@esbuild/win32-x64": "0.27.7"
1536
+ }
1537
+ },
1538
+ "node_modules/estree-walker": {
1539
+ "version": "3.0.3",
1540
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
1541
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
1542
+ "dev": true,
1543
+ "license": "MIT",
1544
+ "dependencies": {
1545
+ "@types/estree": "^1.0.0"
1546
+ }
1547
+ },
1548
+ "node_modules/expect-type": {
1549
+ "version": "1.3.0",
1550
+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz",
1551
+ "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==",
1552
+ "dev": true,
1553
+ "license": "Apache-2.0",
1554
+ "engines": {
1555
+ "node": ">=12.0.0"
1556
+ }
1557
+ },
1558
+ "node_modules/fdir": {
1559
+ "version": "6.5.0",
1560
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
1561
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
1562
+ "dev": true,
1563
+ "license": "MIT",
1564
+ "engines": {
1565
+ "node": ">=12.0.0"
1566
+ },
1567
+ "peerDependencies": {
1568
+ "picomatch": "^3 || ^4"
1569
+ },
1570
+ "peerDependenciesMeta": {
1571
+ "picomatch": {
1572
+ "optional": true
1573
+ }
1574
+ }
1575
+ },
1576
+ "node_modules/fix-dts-default-cjs-exports": {
1577
+ "version": "1.0.1",
1578
+ "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz",
1579
+ "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==",
1580
+ "dev": true,
1581
+ "license": "MIT",
1582
+ "dependencies": {
1583
+ "magic-string": "^0.30.17",
1584
+ "mlly": "^1.7.4",
1585
+ "rollup": "^4.34.8"
1586
+ }
1587
+ },
1588
+ "node_modules/fsevents": {
1589
+ "version": "2.3.3",
1590
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1591
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1592
+ "dev": true,
1593
+ "hasInstallScript": true,
1594
+ "license": "MIT",
1595
+ "optional": true,
1596
+ "os": [
1597
+ "darwin"
1598
+ ],
1599
+ "engines": {
1600
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1601
+ }
1602
+ },
1603
+ "node_modules/joycon": {
1604
+ "version": "3.1.1",
1605
+ "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
1606
+ "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
1607
+ "dev": true,
1608
+ "license": "MIT",
1609
+ "engines": {
1610
+ "node": ">=10"
1611
+ }
1612
+ },
1613
+ "node_modules/lightningcss": {
1614
+ "version": "1.32.0",
1615
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
1616
+ "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
1617
+ "dev": true,
1618
+ "license": "MPL-2.0",
1619
+ "dependencies": {
1620
+ "detect-libc": "^2.0.3"
1621
+ },
1622
+ "engines": {
1623
+ "node": ">= 12.0.0"
1624
+ },
1625
+ "funding": {
1626
+ "type": "opencollective",
1627
+ "url": "https://opencollective.com/parcel"
1628
+ },
1629
+ "optionalDependencies": {
1630
+ "lightningcss-android-arm64": "1.32.0",
1631
+ "lightningcss-darwin-arm64": "1.32.0",
1632
+ "lightningcss-darwin-x64": "1.32.0",
1633
+ "lightningcss-freebsd-x64": "1.32.0",
1634
+ "lightningcss-linux-arm-gnueabihf": "1.32.0",
1635
+ "lightningcss-linux-arm64-gnu": "1.32.0",
1636
+ "lightningcss-linux-arm64-musl": "1.32.0",
1637
+ "lightningcss-linux-x64-gnu": "1.32.0",
1638
+ "lightningcss-linux-x64-musl": "1.32.0",
1639
+ "lightningcss-win32-arm64-msvc": "1.32.0",
1640
+ "lightningcss-win32-x64-msvc": "1.32.0"
1641
+ }
1642
+ },
1643
+ "node_modules/lightningcss-android-arm64": {
1644
+ "version": "1.32.0",
1645
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
1646
+ "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
1647
+ "cpu": [
1648
+ "arm64"
1649
+ ],
1650
+ "dev": true,
1651
+ "license": "MPL-2.0",
1652
+ "optional": true,
1653
+ "os": [
1654
+ "android"
1655
+ ],
1656
+ "engines": {
1657
+ "node": ">= 12.0.0"
1658
+ },
1659
+ "funding": {
1660
+ "type": "opencollective",
1661
+ "url": "https://opencollective.com/parcel"
1662
+ }
1663
+ },
1664
+ "node_modules/lightningcss-darwin-arm64": {
1665
+ "version": "1.32.0",
1666
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
1667
+ "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
1668
+ "cpu": [
1669
+ "arm64"
1670
+ ],
1671
+ "dev": true,
1672
+ "license": "MPL-2.0",
1673
+ "optional": true,
1674
+ "os": [
1675
+ "darwin"
1676
+ ],
1677
+ "engines": {
1678
+ "node": ">= 12.0.0"
1679
+ },
1680
+ "funding": {
1681
+ "type": "opencollective",
1682
+ "url": "https://opencollective.com/parcel"
1683
+ }
1684
+ },
1685
+ "node_modules/lightningcss-darwin-x64": {
1686
+ "version": "1.32.0",
1687
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
1688
+ "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
1689
+ "cpu": [
1690
+ "x64"
1691
+ ],
1692
+ "dev": true,
1693
+ "license": "MPL-2.0",
1694
+ "optional": true,
1695
+ "os": [
1696
+ "darwin"
1697
+ ],
1698
+ "engines": {
1699
+ "node": ">= 12.0.0"
1700
+ },
1701
+ "funding": {
1702
+ "type": "opencollective",
1703
+ "url": "https://opencollective.com/parcel"
1704
+ }
1705
+ },
1706
+ "node_modules/lightningcss-freebsd-x64": {
1707
+ "version": "1.32.0",
1708
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
1709
+ "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
1710
+ "cpu": [
1711
+ "x64"
1712
+ ],
1713
+ "dev": true,
1714
+ "license": "MPL-2.0",
1715
+ "optional": true,
1716
+ "os": [
1717
+ "freebsd"
1718
+ ],
1719
+ "engines": {
1720
+ "node": ">= 12.0.0"
1721
+ },
1722
+ "funding": {
1723
+ "type": "opencollective",
1724
+ "url": "https://opencollective.com/parcel"
1725
+ }
1726
+ },
1727
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
1728
+ "version": "1.32.0",
1729
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
1730
+ "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
1731
+ "cpu": [
1732
+ "arm"
1733
+ ],
1734
+ "dev": true,
1735
+ "license": "MPL-2.0",
1736
+ "optional": true,
1737
+ "os": [
1738
+ "linux"
1739
+ ],
1740
+ "engines": {
1741
+ "node": ">= 12.0.0"
1742
+ },
1743
+ "funding": {
1744
+ "type": "opencollective",
1745
+ "url": "https://opencollective.com/parcel"
1746
+ }
1747
+ },
1748
+ "node_modules/lightningcss-linux-arm64-gnu": {
1749
+ "version": "1.32.0",
1750
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
1751
+ "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
1752
+ "cpu": [
1753
+ "arm64"
1754
+ ],
1755
+ "dev": true,
1756
+ "license": "MPL-2.0",
1757
+ "optional": true,
1758
+ "os": [
1759
+ "linux"
1760
+ ],
1761
+ "engines": {
1762
+ "node": ">= 12.0.0"
1763
+ },
1764
+ "funding": {
1765
+ "type": "opencollective",
1766
+ "url": "https://opencollective.com/parcel"
1767
+ }
1768
+ },
1769
+ "node_modules/lightningcss-linux-arm64-musl": {
1770
+ "version": "1.32.0",
1771
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
1772
+ "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
1773
+ "cpu": [
1774
+ "arm64"
1775
+ ],
1776
+ "dev": true,
1777
+ "license": "MPL-2.0",
1778
+ "optional": true,
1779
+ "os": [
1780
+ "linux"
1781
+ ],
1782
+ "engines": {
1783
+ "node": ">= 12.0.0"
1784
+ },
1785
+ "funding": {
1786
+ "type": "opencollective",
1787
+ "url": "https://opencollective.com/parcel"
1788
+ }
1789
+ },
1790
+ "node_modules/lightningcss-linux-x64-gnu": {
1791
+ "version": "1.32.0",
1792
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
1793
+ "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
1794
+ "cpu": [
1795
+ "x64"
1796
+ ],
1797
+ "dev": true,
1798
+ "license": "MPL-2.0",
1799
+ "optional": true,
1800
+ "os": [
1801
+ "linux"
1802
+ ],
1803
+ "engines": {
1804
+ "node": ">= 12.0.0"
1805
+ },
1806
+ "funding": {
1807
+ "type": "opencollective",
1808
+ "url": "https://opencollective.com/parcel"
1809
+ }
1810
+ },
1811
+ "node_modules/lightningcss-linux-x64-musl": {
1812
+ "version": "1.32.0",
1813
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
1814
+ "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
1815
+ "cpu": [
1816
+ "x64"
1817
+ ],
1818
+ "dev": true,
1819
+ "license": "MPL-2.0",
1820
+ "optional": true,
1821
+ "os": [
1822
+ "linux"
1823
+ ],
1824
+ "engines": {
1825
+ "node": ">= 12.0.0"
1826
+ },
1827
+ "funding": {
1828
+ "type": "opencollective",
1829
+ "url": "https://opencollective.com/parcel"
1830
+ }
1831
+ },
1832
+ "node_modules/lightningcss-win32-arm64-msvc": {
1833
+ "version": "1.32.0",
1834
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
1835
+ "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
1836
+ "cpu": [
1837
+ "arm64"
1838
+ ],
1839
+ "dev": true,
1840
+ "license": "MPL-2.0",
1841
+ "optional": true,
1842
+ "os": [
1843
+ "win32"
1844
+ ],
1845
+ "engines": {
1846
+ "node": ">= 12.0.0"
1847
+ },
1848
+ "funding": {
1849
+ "type": "opencollective",
1850
+ "url": "https://opencollective.com/parcel"
1851
+ }
1852
+ },
1853
+ "node_modules/lightningcss-win32-x64-msvc": {
1854
+ "version": "1.32.0",
1855
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
1856
+ "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
1857
+ "cpu": [
1858
+ "x64"
1859
+ ],
1860
+ "dev": true,
1861
+ "license": "MPL-2.0",
1862
+ "optional": true,
1863
+ "os": [
1864
+ "win32"
1865
+ ],
1866
+ "engines": {
1867
+ "node": ">= 12.0.0"
1868
+ },
1869
+ "funding": {
1870
+ "type": "opencollective",
1871
+ "url": "https://opencollective.com/parcel"
1872
+ }
1873
+ },
1874
+ "node_modules/lilconfig": {
1875
+ "version": "3.1.3",
1876
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
1877
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
1878
+ "dev": true,
1879
+ "license": "MIT",
1880
+ "engines": {
1881
+ "node": ">=14"
1882
+ },
1883
+ "funding": {
1884
+ "url": "https://github.com/sponsors/antonk52"
1885
+ }
1886
+ },
1887
+ "node_modules/lines-and-columns": {
1888
+ "version": "1.2.4",
1889
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
1890
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
1891
+ "dev": true,
1892
+ "license": "MIT"
1893
+ },
1894
+ "node_modules/load-tsconfig": {
1895
+ "version": "0.2.5",
1896
+ "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz",
1897
+ "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==",
1898
+ "dev": true,
1899
+ "license": "MIT",
1900
+ "engines": {
1901
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
1902
+ }
1903
+ },
1904
+ "node_modules/magic-string": {
1905
+ "version": "0.30.21",
1906
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
1907
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
1908
+ "dev": true,
1909
+ "license": "MIT",
1910
+ "dependencies": {
1911
+ "@jridgewell/sourcemap-codec": "^1.5.5"
1912
+ }
1913
+ },
1914
+ "node_modules/mlly": {
1915
+ "version": "1.8.2",
1916
+ "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz",
1917
+ "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==",
1918
+ "dev": true,
1919
+ "license": "MIT",
1920
+ "dependencies": {
1921
+ "acorn": "^8.16.0",
1922
+ "pathe": "^2.0.3",
1923
+ "pkg-types": "^1.3.1",
1924
+ "ufo": "^1.6.3"
1925
+ }
1926
+ },
1927
+ "node_modules/ms": {
1928
+ "version": "2.1.3",
1929
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1930
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1931
+ "dev": true,
1932
+ "license": "MIT"
1933
+ },
1934
+ "node_modules/mz": {
1935
+ "version": "2.7.0",
1936
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
1937
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
1938
+ "dev": true,
1939
+ "license": "MIT",
1940
+ "dependencies": {
1941
+ "any-promise": "^1.0.0",
1942
+ "object-assign": "^4.0.1",
1943
+ "thenify-all": "^1.0.0"
1944
+ }
1945
+ },
1946
+ "node_modules/nanoid": {
1947
+ "version": "3.3.12",
1948
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
1949
+ "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
1950
+ "dev": true,
1951
+ "funding": [
1952
+ {
1953
+ "type": "github",
1954
+ "url": "https://github.com/sponsors/ai"
1955
+ }
1956
+ ],
1957
+ "license": "MIT",
1958
+ "bin": {
1959
+ "nanoid": "bin/nanoid.cjs"
1960
+ },
1961
+ "engines": {
1962
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1963
+ }
1964
+ },
1965
+ "node_modules/object-assign": {
1966
+ "version": "4.1.1",
1967
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1968
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1969
+ "dev": true,
1970
+ "license": "MIT",
1971
+ "engines": {
1972
+ "node": ">=0.10.0"
1973
+ }
1974
+ },
1975
+ "node_modules/obug": {
1976
+ "version": "2.1.1",
1977
+ "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz",
1978
+ "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==",
1979
+ "dev": true,
1980
+ "funding": [
1981
+ "https://github.com/sponsors/sxzz",
1982
+ "https://opencollective.com/debug"
1983
+ ],
1984
+ "license": "MIT"
1985
+ },
1986
+ "node_modules/pathe": {
1987
+ "version": "2.0.3",
1988
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
1989
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
1990
+ "dev": true,
1991
+ "license": "MIT"
1992
+ },
1993
+ "node_modules/picocolors": {
1994
+ "version": "1.1.1",
1995
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1996
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1997
+ "dev": true,
1998
+ "license": "ISC"
1999
+ },
2000
+ "node_modules/picomatch": {
2001
+ "version": "4.0.4",
2002
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
2003
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
2004
+ "dev": true,
2005
+ "license": "MIT",
2006
+ "engines": {
2007
+ "node": ">=12"
2008
+ },
2009
+ "funding": {
2010
+ "url": "https://github.com/sponsors/jonschlinkert"
2011
+ }
2012
+ },
2013
+ "node_modules/pirates": {
2014
+ "version": "4.0.7",
2015
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
2016
+ "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
2017
+ "dev": true,
2018
+ "license": "MIT",
2019
+ "engines": {
2020
+ "node": ">= 6"
2021
+ }
2022
+ },
2023
+ "node_modules/pkg-types": {
2024
+ "version": "1.3.1",
2025
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
2026
+ "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
2027
+ "dev": true,
2028
+ "license": "MIT",
2029
+ "dependencies": {
2030
+ "confbox": "^0.1.8",
2031
+ "mlly": "^1.7.4",
2032
+ "pathe": "^2.0.1"
2033
+ }
2034
+ },
2035
+ "node_modules/postcss": {
2036
+ "version": "8.5.15",
2037
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
2038
+ "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
2039
+ "dev": true,
2040
+ "funding": [
2041
+ {
2042
+ "type": "opencollective",
2043
+ "url": "https://opencollective.com/postcss/"
2044
+ },
2045
+ {
2046
+ "type": "tidelift",
2047
+ "url": "https://tidelift.com/funding/github/npm/postcss"
2048
+ },
2049
+ {
2050
+ "type": "github",
2051
+ "url": "https://github.com/sponsors/ai"
2052
+ }
2053
+ ],
2054
+ "license": "MIT",
2055
+ "dependencies": {
2056
+ "nanoid": "^3.3.12",
2057
+ "picocolors": "^1.1.1",
2058
+ "source-map-js": "^1.2.1"
2059
+ },
2060
+ "engines": {
2061
+ "node": "^10 || ^12 || >=14"
2062
+ }
2063
+ },
2064
+ "node_modules/postcss-load-config": {
2065
+ "version": "6.0.1",
2066
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
2067
+ "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
2068
+ "dev": true,
2069
+ "funding": [
2070
+ {
2071
+ "type": "opencollective",
2072
+ "url": "https://opencollective.com/postcss/"
2073
+ },
2074
+ {
2075
+ "type": "github",
2076
+ "url": "https://github.com/sponsors/ai"
2077
+ }
2078
+ ],
2079
+ "license": "MIT",
2080
+ "dependencies": {
2081
+ "lilconfig": "^3.1.1"
2082
+ },
2083
+ "engines": {
2084
+ "node": ">= 18"
2085
+ },
2086
+ "peerDependencies": {
2087
+ "jiti": ">=1.21.0",
2088
+ "postcss": ">=8.0.9",
2089
+ "tsx": "^4.8.1",
2090
+ "yaml": "^2.4.2"
2091
+ },
2092
+ "peerDependenciesMeta": {
2093
+ "jiti": {
2094
+ "optional": true
2095
+ },
2096
+ "postcss": {
2097
+ "optional": true
2098
+ },
2099
+ "tsx": {
2100
+ "optional": true
2101
+ },
2102
+ "yaml": {
2103
+ "optional": true
2104
+ }
2105
+ }
2106
+ },
2107
+ "node_modules/readdirp": {
2108
+ "version": "4.1.2",
2109
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
2110
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
2111
+ "dev": true,
2112
+ "license": "MIT",
2113
+ "engines": {
2114
+ "node": ">= 14.18.0"
2115
+ },
2116
+ "funding": {
2117
+ "type": "individual",
2118
+ "url": "https://paulmillr.com/funding/"
2119
+ }
2120
+ },
2121
+ "node_modules/resolve-from": {
2122
+ "version": "5.0.0",
2123
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
2124
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
2125
+ "dev": true,
2126
+ "license": "MIT",
2127
+ "engines": {
2128
+ "node": ">=8"
2129
+ }
2130
+ },
2131
+ "node_modules/rolldown": {
2132
+ "version": "1.0.2",
2133
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.2.tgz",
2134
+ "integrity": "sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==",
2135
+ "dev": true,
2136
+ "license": "MIT",
2137
+ "dependencies": {
2138
+ "@oxc-project/types": "=0.132.0",
2139
+ "@rolldown/pluginutils": "^1.0.0"
2140
+ },
2141
+ "bin": {
2142
+ "rolldown": "bin/cli.mjs"
2143
+ },
2144
+ "engines": {
2145
+ "node": "^20.19.0 || >=22.12.0"
2146
+ },
2147
+ "optionalDependencies": {
2148
+ "@rolldown/binding-android-arm64": "1.0.2",
2149
+ "@rolldown/binding-darwin-arm64": "1.0.2",
2150
+ "@rolldown/binding-darwin-x64": "1.0.2",
2151
+ "@rolldown/binding-freebsd-x64": "1.0.2",
2152
+ "@rolldown/binding-linux-arm-gnueabihf": "1.0.2",
2153
+ "@rolldown/binding-linux-arm64-gnu": "1.0.2",
2154
+ "@rolldown/binding-linux-arm64-musl": "1.0.2",
2155
+ "@rolldown/binding-linux-ppc64-gnu": "1.0.2",
2156
+ "@rolldown/binding-linux-s390x-gnu": "1.0.2",
2157
+ "@rolldown/binding-linux-x64-gnu": "1.0.2",
2158
+ "@rolldown/binding-linux-x64-musl": "1.0.2",
2159
+ "@rolldown/binding-openharmony-arm64": "1.0.2",
2160
+ "@rolldown/binding-wasm32-wasi": "1.0.2",
2161
+ "@rolldown/binding-win32-arm64-msvc": "1.0.2",
2162
+ "@rolldown/binding-win32-x64-msvc": "1.0.2"
2163
+ }
2164
+ },
2165
+ "node_modules/rollup": {
2166
+ "version": "4.60.4",
2167
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.4.tgz",
2168
+ "integrity": "sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==",
2169
+ "dev": true,
2170
+ "license": "MIT",
2171
+ "dependencies": {
2172
+ "@types/estree": "1.0.8"
2173
+ },
2174
+ "bin": {
2175
+ "rollup": "dist/bin/rollup"
2176
+ },
2177
+ "engines": {
2178
+ "node": ">=18.0.0",
2179
+ "npm": ">=8.0.0"
2180
+ },
2181
+ "optionalDependencies": {
2182
+ "@rollup/rollup-android-arm-eabi": "4.60.4",
2183
+ "@rollup/rollup-android-arm64": "4.60.4",
2184
+ "@rollup/rollup-darwin-arm64": "4.60.4",
2185
+ "@rollup/rollup-darwin-x64": "4.60.4",
2186
+ "@rollup/rollup-freebsd-arm64": "4.60.4",
2187
+ "@rollup/rollup-freebsd-x64": "4.60.4",
2188
+ "@rollup/rollup-linux-arm-gnueabihf": "4.60.4",
2189
+ "@rollup/rollup-linux-arm-musleabihf": "4.60.4",
2190
+ "@rollup/rollup-linux-arm64-gnu": "4.60.4",
2191
+ "@rollup/rollup-linux-arm64-musl": "4.60.4",
2192
+ "@rollup/rollup-linux-loong64-gnu": "4.60.4",
2193
+ "@rollup/rollup-linux-loong64-musl": "4.60.4",
2194
+ "@rollup/rollup-linux-ppc64-gnu": "4.60.4",
2195
+ "@rollup/rollup-linux-ppc64-musl": "4.60.4",
2196
+ "@rollup/rollup-linux-riscv64-gnu": "4.60.4",
2197
+ "@rollup/rollup-linux-riscv64-musl": "4.60.4",
2198
+ "@rollup/rollup-linux-s390x-gnu": "4.60.4",
2199
+ "@rollup/rollup-linux-x64-gnu": "4.60.4",
2200
+ "@rollup/rollup-linux-x64-musl": "4.60.4",
2201
+ "@rollup/rollup-openbsd-x64": "4.60.4",
2202
+ "@rollup/rollup-openharmony-arm64": "4.60.4",
2203
+ "@rollup/rollup-win32-arm64-msvc": "4.60.4",
2204
+ "@rollup/rollup-win32-ia32-msvc": "4.60.4",
2205
+ "@rollup/rollup-win32-x64-gnu": "4.60.4",
2206
+ "@rollup/rollup-win32-x64-msvc": "4.60.4",
2207
+ "fsevents": "~2.3.2"
2208
+ }
2209
+ },
2210
+ "node_modules/siginfo": {
2211
+ "version": "2.0.0",
2212
+ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
2213
+ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
2214
+ "dev": true,
2215
+ "license": "ISC"
2216
+ },
2217
+ "node_modules/source-map": {
2218
+ "version": "0.7.6",
2219
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
2220
+ "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==",
2221
+ "dev": true,
2222
+ "license": "BSD-3-Clause",
2223
+ "engines": {
2224
+ "node": ">= 12"
2225
+ }
2226
+ },
2227
+ "node_modules/source-map-js": {
2228
+ "version": "1.2.1",
2229
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
2230
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
2231
+ "dev": true,
2232
+ "license": "BSD-3-Clause",
2233
+ "engines": {
2234
+ "node": ">=0.10.0"
2235
+ }
2236
+ },
2237
+ "node_modules/stackback": {
2238
+ "version": "0.0.2",
2239
+ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
2240
+ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
2241
+ "dev": true,
2242
+ "license": "MIT"
2243
+ },
2244
+ "node_modules/std-env": {
2245
+ "version": "4.1.0",
2246
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
2247
+ "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
2248
+ "dev": true,
2249
+ "license": "MIT"
2250
+ },
2251
+ "node_modules/sucrase": {
2252
+ "version": "3.35.1",
2253
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz",
2254
+ "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==",
2255
+ "dev": true,
2256
+ "license": "MIT",
2257
+ "dependencies": {
2258
+ "@jridgewell/gen-mapping": "^0.3.2",
2259
+ "commander": "^4.0.0",
2260
+ "lines-and-columns": "^1.1.6",
2261
+ "mz": "^2.7.0",
2262
+ "pirates": "^4.0.1",
2263
+ "tinyglobby": "^0.2.11",
2264
+ "ts-interface-checker": "^0.1.9"
2265
+ },
2266
+ "bin": {
2267
+ "sucrase": "bin/sucrase",
2268
+ "sucrase-node": "bin/sucrase-node"
2269
+ },
2270
+ "engines": {
2271
+ "node": ">=16 || 14 >=14.17"
2272
+ }
2273
+ },
2274
+ "node_modules/thenify": {
2275
+ "version": "3.3.1",
2276
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
2277
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
2278
+ "dev": true,
2279
+ "license": "MIT",
2280
+ "dependencies": {
2281
+ "any-promise": "^1.0.0"
2282
+ }
2283
+ },
2284
+ "node_modules/thenify-all": {
2285
+ "version": "1.6.0",
2286
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
2287
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
2288
+ "dev": true,
2289
+ "license": "MIT",
2290
+ "dependencies": {
2291
+ "thenify": ">= 3.1.0 < 4"
2292
+ },
2293
+ "engines": {
2294
+ "node": ">=0.8"
2295
+ }
2296
+ },
2297
+ "node_modules/tinybench": {
2298
+ "version": "2.9.0",
2299
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
2300
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
2301
+ "dev": true,
2302
+ "license": "MIT"
2303
+ },
2304
+ "node_modules/tinyexec": {
2305
+ "version": "0.3.2",
2306
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
2307
+ "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
2308
+ "dev": true,
2309
+ "license": "MIT"
2310
+ },
2311
+ "node_modules/tinyglobby": {
2312
+ "version": "0.2.16",
2313
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
2314
+ "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
2315
+ "dev": true,
2316
+ "license": "MIT",
2317
+ "dependencies": {
2318
+ "fdir": "^6.5.0",
2319
+ "picomatch": "^4.0.4"
2320
+ },
2321
+ "engines": {
2322
+ "node": ">=12.0.0"
2323
+ },
2324
+ "funding": {
2325
+ "url": "https://github.com/sponsors/SuperchupuDev"
2326
+ }
2327
+ },
2328
+ "node_modules/tinyrainbow": {
2329
+ "version": "3.1.0",
2330
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz",
2331
+ "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==",
2332
+ "dev": true,
2333
+ "license": "MIT",
2334
+ "engines": {
2335
+ "node": ">=14.0.0"
2336
+ }
2337
+ },
2338
+ "node_modules/tree-kill": {
2339
+ "version": "1.2.2",
2340
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
2341
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
2342
+ "dev": true,
2343
+ "license": "MIT",
2344
+ "bin": {
2345
+ "tree-kill": "cli.js"
2346
+ }
2347
+ },
2348
+ "node_modules/ts-interface-checker": {
2349
+ "version": "0.1.13",
2350
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
2351
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
2352
+ "dev": true,
2353
+ "license": "Apache-2.0"
2354
+ },
2355
+ "node_modules/tslib": {
2356
+ "version": "2.8.1",
2357
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
2358
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
2359
+ "dev": true,
2360
+ "license": "0BSD",
2361
+ "optional": true
2362
+ },
2363
+ "node_modules/tsup": {
2364
+ "version": "8.5.1",
2365
+ "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.1.tgz",
2366
+ "integrity": "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==",
2367
+ "dev": true,
2368
+ "license": "MIT",
2369
+ "dependencies": {
2370
+ "bundle-require": "^5.1.0",
2371
+ "cac": "^6.7.14",
2372
+ "chokidar": "^4.0.3",
2373
+ "consola": "^3.4.0",
2374
+ "debug": "^4.4.0",
2375
+ "esbuild": "^0.27.0",
2376
+ "fix-dts-default-cjs-exports": "^1.0.0",
2377
+ "joycon": "^3.1.1",
2378
+ "picocolors": "^1.1.1",
2379
+ "postcss-load-config": "^6.0.1",
2380
+ "resolve-from": "^5.0.0",
2381
+ "rollup": "^4.34.8",
2382
+ "source-map": "^0.7.6",
2383
+ "sucrase": "^3.35.0",
2384
+ "tinyexec": "^0.3.2",
2385
+ "tinyglobby": "^0.2.11",
2386
+ "tree-kill": "^1.2.2"
2387
+ },
2388
+ "bin": {
2389
+ "tsup": "dist/cli-default.js",
2390
+ "tsup-node": "dist/cli-node.js"
2391
+ },
2392
+ "engines": {
2393
+ "node": ">=18"
2394
+ },
2395
+ "peerDependencies": {
2396
+ "@microsoft/api-extractor": "^7.36.0",
2397
+ "@swc/core": "^1",
2398
+ "postcss": "^8.4.12",
2399
+ "typescript": ">=4.5.0"
2400
+ },
2401
+ "peerDependenciesMeta": {
2402
+ "@microsoft/api-extractor": {
2403
+ "optional": true
2404
+ },
2405
+ "@swc/core": {
2406
+ "optional": true
2407
+ },
2408
+ "postcss": {
2409
+ "optional": true
2410
+ },
2411
+ "typescript": {
2412
+ "optional": true
2413
+ }
2414
+ }
2415
+ },
2416
+ "node_modules/typescript": {
2417
+ "version": "5.9.3",
2418
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
2419
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
2420
+ "dev": true,
2421
+ "license": "Apache-2.0",
2422
+ "bin": {
2423
+ "tsc": "bin/tsc",
2424
+ "tsserver": "bin/tsserver"
2425
+ },
2426
+ "engines": {
2427
+ "node": ">=14.17"
2428
+ }
2429
+ },
2430
+ "node_modules/ufo": {
2431
+ "version": "1.6.4",
2432
+ "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz",
2433
+ "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==",
2434
+ "dev": true,
2435
+ "license": "MIT"
2436
+ },
2437
+ "node_modules/undici-types": {
2438
+ "version": "7.24.6",
2439
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
2440
+ "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
2441
+ "dev": true,
2442
+ "license": "MIT"
2443
+ },
2444
+ "node_modules/vite": {
2445
+ "version": "8.0.14",
2446
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.14.tgz",
2447
+ "integrity": "sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw==",
2448
+ "dev": true,
2449
+ "license": "MIT",
2450
+ "dependencies": {
2451
+ "lightningcss": "^1.32.0",
2452
+ "picomatch": "^4.0.4",
2453
+ "postcss": "^8.5.15",
2454
+ "rolldown": "1.0.2",
2455
+ "tinyglobby": "^0.2.16"
2456
+ },
2457
+ "bin": {
2458
+ "vite": "bin/vite.js"
2459
+ },
2460
+ "engines": {
2461
+ "node": "^20.19.0 || >=22.12.0"
2462
+ },
2463
+ "funding": {
2464
+ "url": "https://github.com/vitejs/vite?sponsor=1"
2465
+ },
2466
+ "optionalDependencies": {
2467
+ "fsevents": "~2.3.3"
2468
+ },
2469
+ "peerDependencies": {
2470
+ "@types/node": "^20.19.0 || >=22.12.0",
2471
+ "@vitejs/devtools": "^0.1.18",
2472
+ "esbuild": "^0.27.0 || ^0.28.0",
2473
+ "jiti": ">=1.21.0",
2474
+ "less": "^4.0.0",
2475
+ "sass": "^1.70.0",
2476
+ "sass-embedded": "^1.70.0",
2477
+ "stylus": ">=0.54.8",
2478
+ "sugarss": "^5.0.0",
2479
+ "terser": "^5.16.0",
2480
+ "tsx": "^4.8.1",
2481
+ "yaml": "^2.4.2"
2482
+ },
2483
+ "peerDependenciesMeta": {
2484
+ "@types/node": {
2485
+ "optional": true
2486
+ },
2487
+ "@vitejs/devtools": {
2488
+ "optional": true
2489
+ },
2490
+ "esbuild": {
2491
+ "optional": true
2492
+ },
2493
+ "jiti": {
2494
+ "optional": true
2495
+ },
2496
+ "less": {
2497
+ "optional": true
2498
+ },
2499
+ "sass": {
2500
+ "optional": true
2501
+ },
2502
+ "sass-embedded": {
2503
+ "optional": true
2504
+ },
2505
+ "stylus": {
2506
+ "optional": true
2507
+ },
2508
+ "sugarss": {
2509
+ "optional": true
2510
+ },
2511
+ "terser": {
2512
+ "optional": true
2513
+ },
2514
+ "tsx": {
2515
+ "optional": true
2516
+ },
2517
+ "yaml": {
2518
+ "optional": true
2519
+ }
2520
+ }
2521
+ },
2522
+ "node_modules/vitest": {
2523
+ "version": "4.1.7",
2524
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.7.tgz",
2525
+ "integrity": "sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==",
2526
+ "dev": true,
2527
+ "license": "MIT",
2528
+ "dependencies": {
2529
+ "@vitest/expect": "4.1.7",
2530
+ "@vitest/mocker": "4.1.7",
2531
+ "@vitest/pretty-format": "4.1.7",
2532
+ "@vitest/runner": "4.1.7",
2533
+ "@vitest/snapshot": "4.1.7",
2534
+ "@vitest/spy": "4.1.7",
2535
+ "@vitest/utils": "4.1.7",
2536
+ "es-module-lexer": "^2.0.0",
2537
+ "expect-type": "^1.3.0",
2538
+ "magic-string": "^0.30.21",
2539
+ "obug": "^2.1.1",
2540
+ "pathe": "^2.0.3",
2541
+ "picomatch": "^4.0.3",
2542
+ "std-env": "^4.0.0-rc.1",
2543
+ "tinybench": "^2.9.0",
2544
+ "tinyexec": "^1.0.2",
2545
+ "tinyglobby": "^0.2.15",
2546
+ "tinyrainbow": "^3.1.0",
2547
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0",
2548
+ "why-is-node-running": "^2.3.0"
2549
+ },
2550
+ "bin": {
2551
+ "vitest": "vitest.mjs"
2552
+ },
2553
+ "engines": {
2554
+ "node": "^20.0.0 || ^22.0.0 || >=24.0.0"
2555
+ },
2556
+ "funding": {
2557
+ "url": "https://opencollective.com/vitest"
2558
+ },
2559
+ "peerDependencies": {
2560
+ "@edge-runtime/vm": "*",
2561
+ "@opentelemetry/api": "^1.9.0",
2562
+ "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
2563
+ "@vitest/browser-playwright": "4.1.7",
2564
+ "@vitest/browser-preview": "4.1.7",
2565
+ "@vitest/browser-webdriverio": "4.1.7",
2566
+ "@vitest/coverage-istanbul": "4.1.7",
2567
+ "@vitest/coverage-v8": "4.1.7",
2568
+ "@vitest/ui": "4.1.7",
2569
+ "happy-dom": "*",
2570
+ "jsdom": "*",
2571
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
2572
+ },
2573
+ "peerDependenciesMeta": {
2574
+ "@edge-runtime/vm": {
2575
+ "optional": true
2576
+ },
2577
+ "@opentelemetry/api": {
2578
+ "optional": true
2579
+ },
2580
+ "@types/node": {
2581
+ "optional": true
2582
+ },
2583
+ "@vitest/browser-playwright": {
2584
+ "optional": true
2585
+ },
2586
+ "@vitest/browser-preview": {
2587
+ "optional": true
2588
+ },
2589
+ "@vitest/browser-webdriverio": {
2590
+ "optional": true
2591
+ },
2592
+ "@vitest/coverage-istanbul": {
2593
+ "optional": true
2594
+ },
2595
+ "@vitest/coverage-v8": {
2596
+ "optional": true
2597
+ },
2598
+ "@vitest/ui": {
2599
+ "optional": true
2600
+ },
2601
+ "happy-dom": {
2602
+ "optional": true
2603
+ },
2604
+ "jsdom": {
2605
+ "optional": true
2606
+ },
2607
+ "vite": {
2608
+ "optional": false
2609
+ }
2610
+ }
2611
+ },
2612
+ "node_modules/vitest/node_modules/tinyexec": {
2613
+ "version": "1.2.2",
2614
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.2.tgz",
2615
+ "integrity": "sha512-M/Q0B2cp4K7kynaT/vnED1j8TlLY+Pp7C6Wl2bl/7u/F0mUVwdyOpwomQb8JpYLitHUssAJRmLZdMCGsrx7i+g==",
2616
+ "dev": true,
2617
+ "license": "MIT",
2618
+ "engines": {
2619
+ "node": ">=18"
2620
+ }
2621
+ },
2622
+ "node_modules/why-is-node-running": {
2623
+ "version": "2.3.0",
2624
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
2625
+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
2626
+ "dev": true,
2627
+ "license": "MIT",
2628
+ "dependencies": {
2629
+ "siginfo": "^2.0.0",
2630
+ "stackback": "0.0.2"
2631
+ },
2632
+ "bin": {
2633
+ "why-is-node-running": "cli.js"
2634
+ },
2635
+ "engines": {
2636
+ "node": ">=8"
2637
+ }
2638
+ }
2639
+ }
2640
+ }