BabelDOC 0.1.23__tar.gz → 0.1.25__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. {babeldoc-0.1.23 → babeldoc-0.1.25}/.github/workflows/docs.yml +1 -1
  2. {babeldoc-0.1.23 → babeldoc-0.1.25}/.github/workflows/publish-to-pypi.yml +3 -3
  3. {babeldoc-0.1.23 → babeldoc-0.1.25}/.github/workflows/test.yml +1 -1
  4. {babeldoc-0.1.23 → babeldoc-0.1.25}/PKG-INFO +10 -3
  5. {babeldoc-0.1.23 → babeldoc-0.1.25}/README.md +8 -2
  6. babeldoc-0.1.25/babeldoc/__init__.py +1 -0
  7. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/const.py +1 -1
  8. babeldoc-0.1.25/babeldoc/document_il/babeldoc_exception/BabelDOCException.py +3 -0
  9. babeldoc-0.1.25/babeldoc/document_il/midend/detect_scanned_file.py +124 -0
  10. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/midend/layout_parser.py +1 -1
  11. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/midend/styles_and_formulas.py +3 -1
  12. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/utils/fontmap.py +11 -4
  13. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/docvision/rpc_doclayout.py +18 -15
  14. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/high_level.py +24 -11
  15. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/main.py +3 -3
  16. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/progress_monitor.py +29 -8
  17. babeldoc-0.1.25/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.png +0 -0
  18. babeldoc-0.1.25/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.svg +16 -0
  19. babeldoc-0.1.25/docs/images/babeldoc-big-logo-with-transparent-background.png +0 -0
  20. babeldoc-0.1.25/docs/images/babeldoc-big-logo-with-transparent-background.svg +16 -0
  21. babeldoc-0.1.25/docs/images/babeldoc-big-logo.png +0 -0
  22. babeldoc-0.1.25/docs/images/babeldoc-small-logo-with-transparent-background.png +0 -0
  23. babeldoc-0.1.25/docs/images/babeldoc-small-logo-with-transparent-background.svg +15 -0
  24. babeldoc-0.1.25/docs/images/babeldoc-small-logo.png +0 -0
  25. {babeldoc-0.1.23 → babeldoc-0.1.25}/mkdocs.yml +3 -3
  26. {babeldoc-0.1.23 → babeldoc-0.1.25}/pyproject.toml +3 -2
  27. {babeldoc-0.1.23 → babeldoc-0.1.25}/uv.lock +171 -4
  28. babeldoc-0.1.23/babeldoc/__init__.py +0 -1
  29. {babeldoc-0.1.23 → babeldoc-0.1.25}/.cursorignore +0 -0
  30. {babeldoc-0.1.23 → babeldoc-0.1.25}/.github/ISSUE_TEMPLATE/bug_report.yaml +0 -0
  31. {babeldoc-0.1.23 → babeldoc-0.1.25}/.github/ISSUE_TEMPLATE/feature_request.yaml +0 -0
  32. {babeldoc-0.1.23 → babeldoc-0.1.25}/.github/dependabot.yml +0 -0
  33. {babeldoc-0.1.23 → babeldoc-0.1.25}/.github/labels.yml +0 -0
  34. {babeldoc-0.1.23 → babeldoc-0.1.25}/.github/release-drafter.yml +0 -0
  35. {babeldoc-0.1.23 → babeldoc-0.1.25}/.github/workflows/codeql.yml +0 -0
  36. {babeldoc-0.1.23 → babeldoc-0.1.25}/.github/workflows/labeler.yml +0 -0
  37. {babeldoc-0.1.23 → babeldoc-0.1.25}/.gitignore +0 -0
  38. {babeldoc-0.1.23 → babeldoc-0.1.25}/.pre-commit-config.yaml +0 -0
  39. {babeldoc-0.1.23 → babeldoc-0.1.25}/LICENSE +0 -0
  40. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/assets/assets.py +0 -0
  41. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/assets/embedding_assets_metadata.py +0 -0
  42. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/asynchronize/__init__.py +0 -0
  43. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/converter.py +0 -0
  44. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/__init__.py +0 -0
  45. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/backend/__init__.py +0 -0
  46. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/backend/pdf_creater.py +0 -0
  47. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/frontend/__init__.py +0 -0
  48. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/frontend/il_creater.py +0 -0
  49. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/il_version_1.py +0 -0
  50. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/il_version_1.rnc +0 -0
  51. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/il_version_1.rng +0 -0
  52. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/il_version_1.xsd +0 -0
  53. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/midend/__init__.py +0 -0
  54. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/midend/add_debug_information.py +0 -0
  55. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/midend/il_translator.py +0 -0
  56. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/midend/paragraph_finder.py +0 -0
  57. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/midend/remove_descent.py +0 -0
  58. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/midend/typesetting.py +0 -0
  59. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/translator/__init__.py +0 -0
  60. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/translator/cache.py +0 -0
  61. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/translator/translator.py +0 -0
  62. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/utils/layout_helper.py +0 -0
  63. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/utils/style_helper.py +0 -0
  64. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/document_il/xml_converter.py +0 -0
  65. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/docvision/README.md +0 -0
  66. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/docvision/__init__.py +0 -0
  67. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/docvision/doclayout.py +0 -0
  68. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/pdfinterp.py +0 -0
  69. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/tools/generate_font_metadata.py +0 -0
  70. {babeldoc-0.1.23 → babeldoc-0.1.25}/babeldoc/translation_config.py +0 -0
  71. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/CODE_OF_CONDUCT.md +0 -0
  72. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/CONTRIBUTING.md +0 -0
  73. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/CONTRIBUTOR_REWARD.md +0 -0
  74. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/ImplementationDetails/AsyncTranslate/AsyncTranslate.md +0 -0
  75. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/ImplementationDetails/ILTranslator/ILTranslator.md +0 -0
  76. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/ImplementationDetails/PDFCreation/PDFCreation.md +0 -0
  77. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/ImplementationDetails/PDFParsing/PDFParsing.md +0 -0
  78. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/ImplementationDetails/ParagraphFinding/ParagraphFinding.md +0 -0
  79. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/ImplementationDetails/README.md +0 -0
  80. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/ImplementationDetails/StylesAndFormulas/StylesAndFormulas.md +0 -0
  81. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/ImplementationDetails/Typesetting/Typesetting.md +0 -0
  82. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/README.md +0 -0
  83. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/deploy.sh +0 -0
  84. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/images/babeldoc-banner.png +0 -0
  85. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/images/babeldoc-contributor_reward_example.png +0 -0
  86. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/images/babeldoc-preview.gif +0 -0
  87. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/index.md +0 -0
  88. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/intro-to-pdf-object.md +0 -0
  89. {babeldoc-0.1.23 → babeldoc-0.1.25}/docs/requirements.txt +0 -0
  90. {babeldoc-0.1.23 → babeldoc-0.1.25}/tests/test_translation_config.py +0 -0
@@ -17,7 +17,7 @@ jobs:
17
17
  git config user.name github-actions[bot]
18
18
  git config user.email 41898282+github-actions[bot]@users.noreply.github.com
19
19
  - name: Setup uv with Python 3.12
20
- uses: astral-sh/setup-uv@1edb52594c857e2b5b13128931090f0640537287 # v5.3.0
20
+ uses: astral-sh/setup-uv@f94ec6bedd8674c4426838e6b50417d36b6ab231 # v5.3.1
21
21
  with:
22
22
  python-version: "3.12"
23
23
  enable-cache: true
@@ -35,7 +35,7 @@ jobs:
35
35
  token: ${{ secrets.GITHUB_TOKEN }}
36
36
 
37
37
  - name: Setup uv with Python 3.12
38
- uses: astral-sh/setup-uv@1edb52594c857e2b5b13128931090f0640537287 # v5.3.0
38
+ uses: astral-sh/setup-uv@f94ec6bedd8674c4426838e6b50417d36b6ab231 # v5.3.1
39
39
  with:
40
40
  python-version: "3.12"
41
41
  enable-cache: true
@@ -89,7 +89,7 @@ jobs:
89
89
 
90
90
  steps:
91
91
  - name: Download all the dists
92
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
92
+ uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
93
93
  with:
94
94
  name: python-package-distributions
95
95
  path: dist/
@@ -113,7 +113,7 @@ jobs:
113
113
 
114
114
  steps:
115
115
  - name: Download all the dists
116
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
116
+ uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
117
117
  with:
118
118
  name: python-package-distributions
119
119
  path: dist/
@@ -28,7 +28,7 @@ jobs:
28
28
  path: ~/.cache/babeldoc
29
29
  key: babeldoc-assets-${{ hashFiles('babeldoc/assets/embedding_assets_metadata.py') }}
30
30
  - name: Setup uv with Python ${{ matrix.python-version }}
31
- uses: astral-sh/setup-uv@1edb52594c857e2b5b13128931090f0640537287 # v5.3.0
31
+ uses: astral-sh/setup-uv@f94ec6bedd8674c4426838e6b50417d36b6ab231 # v5.3.1
32
32
  with:
33
33
  python-version: ${{ matrix.python-version }}
34
34
  enable-cache: true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BabelDOC
3
- Version: 0.1.23
3
+ Version: 0.1.25
4
4
  Summary: Yet Another Document Translator
5
5
  Project-URL: Homepage, https://github.com/funstory-ai/BabelDOC
6
6
  Project-URL: Issues, https://github.com/funstory-ai/BabelDOC/issues
@@ -26,6 +26,7 @@ Requires-Dist: peewee>=3.17.8
26
26
  Requires-Dist: pydantic>=2.10.6
27
27
  Requires-Dist: pymupdf>=1.25.1
28
28
  Requires-Dist: rich>=13.9.4
29
+ Requires-Dist: scikit-image>=0.25.2
29
30
  Requires-Dist: tenacity>=9.0.0
30
31
  Requires-Dist: toml>=0.10.2
31
32
  Requires-Dist: tqdm>=4.67.1
@@ -35,10 +36,16 @@ Description-Content-Type: text/markdown
35
36
  <!-- # Yet Another Document Translator -->
36
37
 
37
38
  <div align="center">
38
- <img src="https://s.immersivetranslate.com/assets/r2-uploads/images/babeldoc-banner.png" width="320px" alt="YADT"/>
39
+ <!-- <img src="https://s.immersivetranslate.com/assets/r2-uploads/images/babeldoc-banner.png" width="320px" alt="YADT"/> -->
39
40
 
41
+ <br/>
40
42
 
41
- <h2 id="title">BabelDOC</h2>
43
+ <picture>
44
+ <source media="(prefers-color-scheme: dark)" srcset="https://s.immersivetranslate.com/assets/uploads/babeldoc-big-logo-darkmode-with-transparent-background-IKuNO1.svg" width="320px" alt="BabelDOC"/>
45
+ <img src="https://s.immersivetranslate.com/assets/uploads/babeldoc-big-logo-with-transparent-background-2xweBr.svg" width="320px" alt="BabelDOC"/>
46
+ </picture>
47
+
48
+ <!-- <h2 id="title">BabelDOC</h2> -->
42
49
 
43
50
  <p>
44
51
  <!-- PyPI -->
@@ -1,10 +1,16 @@
1
1
  <!-- # Yet Another Document Translator -->
2
2
 
3
3
  <div align="center">
4
- <img src="https://s.immersivetranslate.com/assets/r2-uploads/images/babeldoc-banner.png" width="320px" alt="YADT"/>
4
+ <!-- <img src="https://s.immersivetranslate.com/assets/r2-uploads/images/babeldoc-banner.png" width="320px" alt="YADT"/> -->
5
5
 
6
+ <br/>
6
7
 
7
- <h2 id="title">BabelDOC</h2>
8
+ <picture>
9
+ <source media="(prefers-color-scheme: dark)" srcset="https://s.immersivetranslate.com/assets/uploads/babeldoc-big-logo-darkmode-with-transparent-background-IKuNO1.svg" width="320px" alt="BabelDOC"/>
10
+ <img src="https://s.immersivetranslate.com/assets/uploads/babeldoc-big-logo-with-transparent-background-2xweBr.svg" width="320px" alt="BabelDOC"/>
11
+ </picture>
12
+
13
+ <!-- <h2 id="title">BabelDOC</h2> -->
8
14
 
9
15
  <p>
10
16
  <!-- PyPI -->
@@ -0,0 +1 @@
1
+ __version__ = "0.1.25"
@@ -2,7 +2,7 @@ import shutil
2
2
  import subprocess
3
3
  from pathlib import Path
4
4
 
5
- __version__ = "0.1.23"
5
+ __version__ = "0.1.25"
6
6
 
7
7
  CACHE_FOLDER = Path.home() / ".cache" / "babeldoc"
8
8
 
@@ -0,0 +1,3 @@
1
+ class ScannedPDFError(Exception):
2
+ def __init__(self, message):
3
+ super().__init__(message)
@@ -0,0 +1,124 @@
1
+ import logging
2
+
3
+ import cv2
4
+ import numpy as np
5
+ import pymupdf
6
+ from skimage.metrics import structural_similarity
7
+
8
+ from babeldoc.document_il import il_version_1
9
+ from babeldoc.document_il.babeldoc_exception.BabelDOCException import ScannedPDFError
10
+ from babeldoc.document_il.utils.style_helper import GREEN
11
+ from babeldoc.translation_config import TranslationConfig
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class DetectScannedFile:
17
+ stage_name = "DetectScannedFile"
18
+
19
+ def __init__(self, translation_config: TranslationConfig):
20
+ self.translation_config = translation_config
21
+
22
+ def _save_debug_box_to_page(self, page: il_version_1.Page, similarity: float):
23
+ """Save debug boxes and text labels to the PDF page."""
24
+ if not self.translation_config.debug:
25
+ return
26
+
27
+ color = GREEN
28
+
29
+ # Create text label at top-left corner
30
+ # Note: PDF coordinates are from bottom-left,
31
+ # so we use y2 for top position
32
+ style = il_version_1.PdfStyle(
33
+ font_id="china-ss",
34
+ font_size=4,
35
+ graphic_state=color,
36
+ )
37
+ page_width = page.cropbox.box.x2 - page.cropbox.box.x
38
+ page_height = page.cropbox.box.y2 - page.cropbox.box.y
39
+ unicode = f"scanned score: {similarity * 100:.2f} %"
40
+ page.pdf_paragraph.append(
41
+ il_version_1.PdfParagraph(
42
+ first_line_indent=False,
43
+ box=il_version_1.Box(
44
+ x=page.cropbox.box.x + page_width * 0.03,
45
+ y=page.cropbox.box.y,
46
+ x2=page.cropbox.box.x2,
47
+ y2=page.cropbox.box.y2 - page_height * 0.03,
48
+ ),
49
+ vertical=False,
50
+ pdf_style=style,
51
+ unicode=unicode,
52
+ pdf_paragraph_composition=[
53
+ il_version_1.PdfParagraphComposition(
54
+ pdf_same_style_unicode_characters=il_version_1.PdfSameStyleUnicodeCharacters(
55
+ unicode=unicode,
56
+ pdf_style=style,
57
+ debug_info=True,
58
+ ),
59
+ ),
60
+ ],
61
+ xobj_id=-1,
62
+ ),
63
+ )
64
+
65
+ def process(self, docs: il_version_1.Document):
66
+ """Generate layouts for all pages that need to be translated."""
67
+ # Get pages that need to be translated
68
+ pages_to_translate = [
69
+ page
70
+ for page in docs.page
71
+ if self.translation_config.should_translate_page(page.page_number + 1)
72
+ ]
73
+ mupdf = pymupdf.open(self.translation_config.get_working_file_path("input.pdf"))
74
+ total = len(pages_to_translate)
75
+ threshold = 0.8 * total
76
+ threshold = max(threshold, 1)
77
+ scanned = 0
78
+ non_scanned = 0
79
+ non_scanned_threshold = total - threshold
80
+ with self.translation_config.progress_monitor.stage_start(
81
+ self.stage_name,
82
+ total,
83
+ ) as progress:
84
+ for page in pages_to_translate:
85
+ if scanned < threshold and non_scanned < non_scanned_threshold:
86
+ # Only continue detection if both counts are below thresholds
87
+ is_scanned = self.detect_page_is_scanned(page, mupdf)
88
+ if is_scanned:
89
+ scanned += 1
90
+ else:
91
+ non_scanned += 1
92
+ else:
93
+ # We have enough information to determine document type
94
+ non_scanned += 1
95
+ progress.advance(1)
96
+
97
+ if scanned > threshold:
98
+ logger.warning(
99
+ f"Detected {scanned} scanned pages, which is more than 80% of the total pages. "
100
+ "Please check the input PDF file.",
101
+ )
102
+ raise ScannedPDFError("Scanned PDF detected.")
103
+
104
+ @staticmethod
105
+ def detect_page_is_scanned(page: il_version_1.Page, pdf: pymupdf.Document) -> bool:
106
+ before_page_image = pdf[page.page_number].get_pixmap()
107
+ before_page_image = np.frombuffer(before_page_image.samples, np.uint8).reshape(
108
+ before_page_image.height,
109
+ before_page_image.width,
110
+ 3,
111
+ )[:, :, ::-1]
112
+ new_xref = pdf.get_new_xref()
113
+ pdf.update_object(new_xref, "<<>>")
114
+ pdf.update_stream(new_xref, page.base_operations.value.encode("utf-8"))
115
+ pdf[page.page_number].set_contents(new_xref)
116
+ after_page_image = pdf[page.page_number].get_pixmap()
117
+ after_page_image = np.frombuffer(after_page_image.samples, np.uint8).reshape(
118
+ after_page_image.height,
119
+ after_page_image.width,
120
+ 3,
121
+ )[:, :, ::-1]
122
+ before_page_image = cv2.cvtColor(before_page_image, cv2.COLOR_RGB2GRAY)
123
+ after_page_image = cv2.cvtColor(after_page_image, cv2.COLOR_RGB2GRAY)
124
+ return structural_similarity(before_page_image, after_page_image) > 0.9
@@ -121,7 +121,7 @@ class LayoutParser:
121
121
  total,
122
122
  ) as progress:
123
123
  # Process pages in batches
124
- batch_size = 16
124
+ batch_size = 1
125
125
  for i in range(0, total, batch_size):
126
126
  self.translation_config.raise_if_cancelled()
127
127
  batch_pages = pages_to_translate[i : i + batch_size]
@@ -479,7 +479,9 @@ class StylesAndFormulas:
479
479
  return bool(re.match(r"^[0-9, ]+$", text))
480
480
 
481
481
  def is_formulas_font(self, font_name: str) -> bool:
482
- pattern2 = r"^(Cambria|Cambria-BoldItalic|Cambria-Bold|Cambria-Italic)$"
482
+ pattern2 = (
483
+ r"^(Cambria|Cambria-BoldItalic|Cambria-Bold|Cambria-Italic|EUAlbertina.+)$"
484
+ )
483
485
  if self.translation_config.formular_font_pattern:
484
486
  pattern = self.translation_config.formular_font_pattern
485
487
  else:
@@ -33,7 +33,14 @@ class FontMapper:
33
33
  if font_file_name in self.fontid2fontpath:
34
34
  continue
35
35
  font_path, font_metadata = assets.get_font_and_metadata(font_file_name)
36
- self.fonts[font_file_name] = pymupdf.Font(fontfile=str(font_path))
36
+ pymupdf_font = pymupdf.Font(fontfile=str(font_path))
37
+ pymupdf_font.has_glyph = functools.lru_cache(maxsize=10240, typed=True)(
38
+ pymupdf_font.has_glyph,
39
+ )
40
+ pymupdf_font.char_lengths = functools.lru_cache(maxsize=10240, typed=True)(
41
+ pymupdf_font.char_lengths,
42
+ )
43
+ self.fonts[font_file_name] = pymupdf_font
37
44
  self.fontid2fontpath[font_file_name] = font_path
38
45
  self.fonts[font_file_name].font_id = font_file_name
39
46
  self.fonts[font_file_name].font_path = font_path
@@ -106,12 +113,12 @@ class FontMapper:
106
113
  for font in self.type2font[font_type]:
107
114
  if not font.has_glyph(current_char):
108
115
  continue
109
- if bold != font.is_bold:
116
+ if bool(bold) != bool(font.is_bold):
110
117
  continue
111
118
  # 不知道什么原因,思源黑体的 serif 属性为 1,先 workaround
112
- if serif == 1 and "serif" not in font.font_id.lower():
119
+ if bool(serif) and "serif" not in font.font_id.lower():
113
120
  continue
114
- if serif == 0 and "serif" in font.font_id.lower():
121
+ if not bool(serif) and "serif" in font.font_id.lower():
115
122
  continue
116
123
  return font
117
124
 
@@ -130,21 +130,24 @@ class RpcDocLayoutModel(DocLayoutModel):
130
130
  image = [image]
131
131
 
132
132
  results = []
133
- preds = predict_layout(image, host=self.host, imgsz=imgsz)
134
- if len(preds) > 0:
135
- for pred in preds:
136
- boxes = [
137
- YoloBox(None, np.array(x["xyxy"]), np.array(x["conf"]), x["cls"])
138
- for x in pred["boxes"]
139
- ]
140
- results.append(
141
- YoloResult(
142
- boxes=boxes,
143
- names={int(k): v for k, v in pred["names"].items()},
144
- ),
145
- )
146
- else:
147
- results.append(YoloResult(boxes_data=np.array([]), names=[]))
133
+ for img in image:
134
+ preds = predict_layout([img], host=self.host, imgsz=imgsz)
135
+ if len(preds) > 0:
136
+ for pred in preds:
137
+ boxes = [
138
+ YoloBox(
139
+ None, np.array(x["xyxy"]), np.array(x["conf"]), x["cls"]
140
+ )
141
+ for x in pred["boxes"]
142
+ ]
143
+ results.append(
144
+ YoloResult(
145
+ boxes=boxes,
146
+ names={int(k): v for k, v in pred["names"].items()},
147
+ ),
148
+ )
149
+ else:
150
+ results.append(YoloResult(boxes_data=np.array([]), names=[]))
148
151
 
149
152
  return results
150
153
 
@@ -24,6 +24,7 @@ from babeldoc.document_il.backend.pdf_creater import SUBSET_FONT_STAGE_NAME
24
24
  from babeldoc.document_il.backend.pdf_creater import PDFCreater
25
25
  from babeldoc.document_il.frontend.il_creater import ILCreater
26
26
  from babeldoc.document_il.midend.add_debug_information import AddDebugInformation
27
+ from babeldoc.document_il.midend.detect_scanned_file import DetectScannedFile
27
28
  from babeldoc.document_il.midend.il_translator import ILTranslator
28
29
  from babeldoc.document_il.midend.layout_parser import LayoutParser
29
30
  from babeldoc.document_il.midend.paragraph_finder import ParagraphFinder
@@ -40,17 +41,18 @@ from babeldoc.translation_config import TranslationConfig
40
41
  logger = logging.getLogger(__name__)
41
42
 
42
43
  TRANSLATE_STAGES = [
43
- ILCreater.stage_name,
44
- LayoutParser.stage_name,
45
- ParagraphFinder.stage_name,
46
- StylesAndFormulas.stage_name,
47
- RemoveDescent.stage_name,
48
- ILTranslator.stage_name,
49
- Typesetting.stage_name,
50
- FontMapper.stage_name,
51
- PDFCreater.stage_name,
52
- SUBSET_FONT_STAGE_NAME,
53
- SAVE_PDF_STAGE_NAME,
44
+ (ILCreater.stage_name, 5.35), # Parse PDF and Create IR
45
+ (DetectScannedFile.stage_name, 0.5), # No historical data, estimated
46
+ (LayoutParser.stage_name, 6.42), # Parse Page Layout
47
+ (ParagraphFinder.stage_name, 2.14), # Parse Paragraphs
48
+ (StylesAndFormulas.stage_name, 1.12), # Parse Formulas and Styles
49
+ (RemoveDescent.stage_name, 0.15), # Remove Char Descent
50
+ (ILTranslator.stage_name, 75.16), # Translate Paragraphs
51
+ (Typesetting.stage_name, 3.84), # Typesetting
52
+ (FontMapper.stage_name, 0.65), # Add Fonts
53
+ (PDFCreater.stage_name, 1.41), # Generate drawing instructions
54
+ (SUBSET_FONT_STAGE_NAME, 1.29), # Subset font
55
+ (SAVE_PDF_STAGE_NAME, 2.45), # Save PDF
54
56
  ]
55
57
 
56
58
  resfont_map = {
@@ -307,6 +309,17 @@ def do_translate(pm, translation_config):
307
309
  docs,
308
310
  translation_config.get_working_file_path("create_il.debug.json"),
309
311
  )
312
+
313
+ # 检测是否为扫描文件
314
+ logger.debug("start detect scanned file")
315
+ DetectScannedFile(translation_config).process(docs)
316
+ logger.debug("finish detect scanned file")
317
+ if translation_config.debug:
318
+ xml_converter.write_json(
319
+ docs,
320
+ translation_config.get_working_file_path("detect_scanned_file.json"),
321
+ )
322
+
310
323
  # Generate layouts for all pages
311
324
  logger.debug("start generating layouts")
312
325
  docs = LayoutParser(translation_config).process(docs, doc_input)
@@ -23,7 +23,7 @@ from babeldoc.docvision.rpc_doclayout import RpcDocLayoutModel
23
23
  from babeldoc.translation_config import TranslationConfig
24
24
 
25
25
  logger = logging.getLogger(__name__)
26
- __version__ = "0.1.23"
26
+ __version__ = "0.1.25"
27
27
 
28
28
 
29
29
  def create_parser():
@@ -392,7 +392,7 @@ def create_progress_handler(translation_config: TranslationConfig):
392
392
  stage_tasks[stage],
393
393
  completed=event["stage_current"],
394
394
  total=event["stage_total"],
395
- description=f"{event['stage']} ({event['stage_current']}/{event['stage_total']})",
395
+ description=f"{event['stage']}",
396
396
  refresh=True,
397
397
  )
398
398
  progress.update(
@@ -407,7 +407,7 @@ def create_progress_handler(translation_config: TranslationConfig):
407
407
  stage_tasks[stage],
408
408
  completed=event["stage_total"],
409
409
  total=event["stage_total"],
410
- description=f"{event['stage']} (Complete)",
410
+ description=f"{event['stage']}",
411
411
  refresh=True,
412
412
  )
413
413
  progress.update(
@@ -11,7 +11,7 @@ logger = logging.getLogger(__name__)
11
11
  class ProgressMonitor:
12
12
  def __init__(
13
13
  self,
14
- stages: list[str],
14
+ stages: list[tuple[str, float]],
15
15
  progress_change_callback: Callable | None = None,
16
16
  finish_callback: Callable | None = None,
17
17
  report_interval: float = 0.1,
@@ -19,7 +19,13 @@ class ProgressMonitor:
19
19
  cancel_event: threading.Event | None = None,
20
20
  loop: asyncio.AbstractEventLoop | None = None,
21
21
  ):
22
- self.stage = {k: TranslationStage(k, 0, self) for k in stages}
22
+ # Convert stages list to dict with name and weight
23
+ self.stage = {}
24
+ total_weight = sum(weight for _, weight in stages)
25
+ for name, weight in stages:
26
+ normalized_weight = weight / total_weight
27
+ self.stage[name] = TranslationStage(name, 0, self, normalized_weight)
28
+
23
29
  self.progress_change_callback = progress_change_callback
24
30
  self.finish_callback = finish_callback
25
31
  self.report_interval = report_interval
@@ -37,9 +43,9 @@ class ProgressMonitor:
37
43
  stages=[
38
44
  {
39
45
  "name": name,
40
- "percent": 1.0 / len(stages),
46
+ "percent": self.stage[name].weight,
41
47
  }
42
- for name in stages
48
+ for name, _ in stages
43
49
  ],
44
50
  )
45
51
  self.lock = threading.Lock()
@@ -102,9 +108,23 @@ class ProgressMonitor:
102
108
  )
103
109
 
104
110
  def calculate_current_progress(self, stage=None):
105
- progress = self.finish_stage_count * 100 / len(self.stage)
106
- if stage is not None:
107
- progress += stage.current * 100 / stage.total / len(self.stage)
111
+ # Count completed stages
112
+ completed_stages = sum(
113
+ 1 for s in self.stage.values() if s.run_time > 0 and s.current == s.total
114
+ )
115
+
116
+ # If all stages are complete, return exactly 100
117
+ if completed_stages == len(self.stage):
118
+ return 100
119
+
120
+ # Calculate progress based on weights
121
+ progress = sum(
122
+ s.weight * 100
123
+ for s in self.stage.values()
124
+ if s.run_time > 0 and s.current == s.total
125
+ )
126
+ if stage is not None and stage.total > 0:
127
+ progress += stage.weight * stage.current * 100 / stage.total
108
128
  return progress
109
129
 
110
130
  def stage_update(self, stage, n: int):
@@ -142,13 +162,14 @@ class ProgressMonitor:
142
162
 
143
163
 
144
164
  class TranslationStage:
145
- def __init__(self, name: str, total: int, pm: ProgressMonitor):
165
+ def __init__(self, name: str, total: int, pm: ProgressMonitor, weight: float):
146
166
  self.name = name
147
167
  self.display_name = name
148
168
  self.current = 0
149
169
  self.total = total
150
170
  self.pm = pm
151
171
  self.run_time = 0
172
+ self.weight = weight
152
173
 
153
174
  def __enter__(self):
154
175
  return self
@@ -0,0 +1,16 @@
1
+ <svg width="3033" height="1024" viewBox="0 0 3033 1024" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M545.97 191.828L7.28418 333.753L176.393 975.617L715.079 833.692L545.97 191.828Z" fill="#D7DAE6"/>
3
+ <path d="M1023.27 162.578L572.766 44.2217L416.264 639.924L866.77 758.28L1023.27 162.578Z" fill="#D7DAE6"/>
4
+ <path d="M777.884 119.796H220.815V904.673H777.884V119.796Z" fill="#024AFF"/>
5
+ <path d="M571.439 253.802H99.1982V483.38H571.439V253.802Z" fill="white"/>
6
+ <path d="M279.087 328.642H152.667V353.926H279.087V328.642Z" fill="#024AFF"/>
7
+ <path d="M234.84 379.209H152.667V404.493H234.84V379.209Z" fill="#024AFF"/>
8
+ <path d="M902.217 541.153H429.976V770.732H902.217V541.153Z" fill="#FFBE19"/>
9
+ <path d="M669.862 512.262C669.862 513.463 669.799 514.664 669.799 515.865H695.083C695.083 514.664 695.146 513.463 695.146 512.262C695.146 439.697 655.45 376.298 596.729 342.48V372.379C640.912 403.225 669.862 454.425 669.862 512.262Z" fill="white"/>
10
+ <path d="M404.693 654.049C358.929 623.455 328.778 571.307 328.778 512.269C328.778 511.068 328.841 509.867 328.841 508.666H303.557C303.557 509.867 303.494 511.068 303.494 512.269C303.494 585.972 344.391 650.256 404.693 683.631V654.049Z" fill="#FFBD14"/>
11
+ <path d="M866.938 619.407H740.519V644.691H866.938V619.407Z" fill="#024AFF"/>
12
+ <path d="M866.938 669.975H784.766V695.259H866.938V669.975Z" fill="#024AFF"/>
13
+ <path d="M454.76 304.9H523.33V408.135H454.76V465.023H424.419V408.135H354.938V304.9H424.419V271.753L454.76 272.815V304.9ZM385.052 334.862V378.628H424.343V334.862H385.052ZM454.76 378.552H493.216V334.786H454.76V378.552Z" fill="#024AFF"/>
14
+ <path d="M550.839 695.334L539.385 728.861H500.321L554.935 581.48H605.452L659.61 728.861H619.712L608.486 695.334H550.914H550.839ZM598.17 664.69L581.179 613.945H578.6L561.154 664.69H598.094H598.17Z" fill="#024AFF"/>
15
+ <path d="M1189.6 740.358V305.79H1307.38C1338.99 305.79 1361.95 313.527 1376.27 329C1390.76 344.309 1398 369.659 1398 405.05V424.062C1398 444.474 1394.3 461.017 1386.89 473.692C1379.65 486.367 1368.54 494.679 1353.56 498.63C1373.14 503.568 1386.23 515.173 1392.81 533.445C1399.56 551.552 1402.94 573.692 1402.94 599.865C1402.94 628.013 1400.3 652.622 1395.04 673.692C1389.77 694.762 1380.22 711.14 1366.4 722.828C1352.57 734.515 1332.9 740.358 1307.38 740.358H1189.6ZM1274.54 469.494H1292.32C1300.39 469.494 1305.57 466.367 1307.88 460.111C1310.18 453.856 1311.33 446.367 1311.33 437.642V393.939C1311.33 379.947 1305.16 372.951 1292.81 372.951H1274.54V469.494ZM1283.19 663.815C1305.74 663.815 1317.01 653.116 1317.01 631.716V577.395C1317.01 565.05 1315.12 555.338 1311.33 548.26C1307.71 541.017 1300.8 537.395 1290.59 537.395H1274.54V663.321C1278.16 663.651 1281.05 663.815 1283.19 663.815ZM1497.51 744.309C1476.93 744.309 1461.21 739.535 1450.35 729.988C1439.65 720.441 1432.32 707.354 1428.37 690.729C1424.42 674.103 1422.44 655.256 1422.44 634.186C1422.44 611.634 1424.67 593.198 1429.11 578.877C1433.56 564.391 1441.13 552.539 1451.83 543.321C1462.69 534.103 1477.59 526.284 1496.52 519.865L1551.33 501.099V463.074C1551.33 443.157 1544.83 433.198 1531.83 433.198C1519.98 433.198 1514.05 441.264 1514.05 457.395V479.618H1428.12C1427.96 478.301 1427.88 476.655 1427.88 474.679C1427.88 472.539 1427.88 470.153 1427.88 467.519C1427.88 430.646 1436.52 404.556 1453.8 389.247C1471.25 373.774 1498.82 366.037 1536.52 366.037C1556.27 366.037 1573.97 369.577 1589.6 376.655C1605.24 383.568 1617.59 393.856 1626.64 407.519C1635.86 421.181 1640.47 438.054 1640.47 458.136V740.358H1552.57V696.408C1548.29 711.881 1541.21 723.733 1531.33 731.963C1521.46 740.194 1510.18 744.309 1497.51 744.309ZM1532.32 675.667C1539.56 675.667 1544.5 672.622 1547.14 666.531C1549.77 660.441 1551.09 653.856 1551.09 646.778V543.568C1538.91 548.507 1529.44 554.762 1522.69 562.334C1515.94 569.741 1512.57 580.688 1512.57 595.173V642.828C1512.57 664.721 1519.15 675.667 1532.32 675.667ZM1822.44 744.309C1807.96 744.309 1796.19 740.77 1787.14 733.692C1778.08 726.449 1770.84 715.502 1765.41 700.852V740.358H1675.53V305.79H1765.41V409.494C1770.84 395.832 1778.33 385.214 1787.88 377.642C1797.59 369.906 1811.42 366.037 1829.36 366.037C1853.56 366.037 1870.59 374.844 1880.47 392.457C1890.51 410.07 1895.53 433.116 1895.53 461.593V643.815C1895.53 662.745 1892.9 679.865 1887.63 695.173C1882.53 710.317 1874.54 722.334 1863.68 731.223C1852.98 739.947 1839.23 744.309 1822.44 744.309ZM1785.9 675.42C1795.28 675.42 1800.96 670.811 1802.94 661.593C1804.91 652.375 1805.9 641.017 1805.9 627.519V482.828C1805.9 469.165 1804.91 457.807 1802.94 448.753C1800.96 439.535 1795.37 434.926 1786.15 434.926C1776.6 434.926 1770.76 439.618 1768.62 449C1766.48 458.218 1765.41 469.494 1765.41 482.828V627.519C1765.41 640.852 1766.48 652.21 1768.62 661.593C1770.76 670.811 1776.52 675.42 1785.9 675.42ZM2032.07 744.309C2005.74 744.309 1984.75 739.371 1969.11 729.494C1953.47 719.618 1942.28 705.379 1935.53 686.778C1928.78 668.177 1925.41 645.79 1925.41 619.618V470.729C1925.41 436.325 1935.28 410.317 1955.04 392.704C1974.79 374.926 2001.95 366.037 2036.52 366.037C2107.63 366.037 2143.19 400.935 2143.19 470.729V497.642C2143.19 530.235 2142.86 552.128 2142.2 563.321H2013.8V634.926C2013.8 641.511 2014.21 648.013 2015.04 654.432C2015.86 660.688 2017.67 665.873 2020.47 669.988C2023.43 674.103 2028.12 676.161 2034.54 676.161C2043.76 676.161 2049.52 672.21 2051.83 664.309C2054.13 656.243 2055.28 645.79 2055.28 632.951V597.395H2143.19V618.383C2143.19 646.037 2139.73 669.247 2132.81 688.013C2126.07 706.614 2114.54 720.688 2098.25 730.235C2082.12 739.618 2060.06 744.309 2032.07 744.309ZM2013.31 519.371H2055.28V469.494C2055.28 456.161 2053.64 446.614 2050.35 440.852C2047.05 434.926 2042.12 431.963 2035.53 431.963C2028.45 431.963 2022.94 434.762 2018.99 440.358C2015.2 445.955 2013.31 455.667 2013.31 469.494V519.371ZM2175.28 740.358V305.79H2265.16V740.358H2175.28ZM2302.2 740.358V305.79H2421.7C2452.98 305.79 2476.52 314.515 2492.32 331.963C2508.12 349.247 2516.02 374.597 2516.02 408.013V611.47C2516.02 652.622 2508.78 684.391 2494.3 706.778C2479.98 729.165 2454.79 740.358 2418.74 740.358H2302.2ZM2389.61 663.568H2404.67C2420.63 663.568 2428.62 655.832 2428.62 640.358V416.161C2428.62 401.675 2426.64 392.375 2422.69 388.26C2418.91 383.98 2411.09 381.84 2399.23 381.84H2389.61V663.568ZM2657.75 744.309C2584.01 744.309 2547.14 706.037 2547.14 629.494V480.852C2547.14 445.955 2556.93 418.136 2576.52 397.395C2596.11 376.49 2623.19 366.037 2657.75 366.037C2692.49 366.037 2719.65 376.49 2739.23 397.395C2758.82 418.136 2768.62 445.955 2768.62 480.852V629.494C2768.62 706.037 2731.66 744.309 2657.75 744.309ZM2657.75 676.161C2665.16 676.161 2670.43 673.527 2673.56 668.26C2676.85 662.828 2678.49 655.996 2678.49 647.766V466.778C2678.49 445.214 2671.58 434.432 2657.75 434.432C2643.93 434.432 2637.01 445.214 2637.01 466.778V647.766C2637.01 655.996 2638.58 662.828 2641.7 668.26C2645 673.527 2650.35 676.161 2657.75 676.161ZM2912.81 744.309C2871.33 744.309 2841.87 733.692 2824.42 712.457C2807.14 691.223 2798.49 660.029 2798.49 618.877V504.803C2798.49 473.856 2801.79 448.095 2808.37 427.519C2814.95 406.943 2826.48 391.552 2842.94 381.346C2859.4 371.14 2882.28 366.037 2911.58 366.037C2931.99 366.037 2950.26 369.659 2966.4 376.902C2982.69 384.144 2995.53 394.762 3004.91 408.753C3014.3 422.745 3018.99 439.865 3018.99 460.111V516.655H2928.86V464.803C2928.86 456.243 2927.63 449.083 2925.16 443.321C2922.69 437.395 2917.34 434.432 2909.11 434.432C2894.63 434.432 2887.38 444.721 2887.38 465.297V644.803C2887.38 652.375 2889.03 659.371 2892.32 665.79C2895.61 672.046 2901.05 675.173 2908.62 675.173C2916.35 675.173 2921.7 672.128 2924.67 666.037C2927.79 659.782 2929.36 652.539 2929.36 644.309V582.087H3018.99V646.778C3018.99 667.19 3014.38 684.721 3005.16 699.371C2996.11 713.856 2983.6 724.967 2967.63 732.704C2951.66 740.441 2933.39 744.309 2912.81 744.309Z" fill="white"/>
16
+ </svg>
@@ -0,0 +1,16 @@
1
+ <svg width="3033" height="1024" viewBox="0 0 3033 1024" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M545.97 191.828L7.28418 333.753L176.393 975.617L715.079 833.692L545.97 191.828Z" fill="#D7DAE6"/>
3
+ <path d="M1023.27 162.578L572.766 44.2217L416.264 639.924L866.77 758.28L1023.27 162.578Z" fill="#D7DAE6"/>
4
+ <path d="M777.884 119.796H220.815V904.673H777.884V119.796Z" fill="#024AFF"/>
5
+ <path d="M571.439 253.802H99.1982V483.38H571.439V253.802Z" fill="white"/>
6
+ <path d="M279.087 328.642H152.667V353.926H279.087V328.642Z" fill="#024AFF"/>
7
+ <path d="M234.84 379.209H152.667V404.493H234.84V379.209Z" fill="#024AFF"/>
8
+ <path d="M902.217 541.153H429.976V770.732H902.217V541.153Z" fill="#FFBE19"/>
9
+ <path d="M669.862 512.262C669.862 513.463 669.799 514.664 669.799 515.865H695.083C695.083 514.664 695.146 513.463 695.146 512.262C695.146 439.697 655.45 376.298 596.729 342.48V372.379C640.912 403.225 669.862 454.425 669.862 512.262Z" fill="white"/>
10
+ <path d="M404.693 654.049C358.929 623.455 328.778 571.307 328.778 512.269C328.778 511.068 328.841 509.867 328.841 508.666H303.557C303.557 509.867 303.494 511.068 303.494 512.269C303.494 585.972 344.391 650.256 404.693 683.631V654.049Z" fill="#FFBD14"/>
11
+ <path d="M866.938 619.407H740.519V644.691H866.938V619.407Z" fill="#024AFF"/>
12
+ <path d="M866.938 669.975H784.766V695.259H866.938V669.975Z" fill="#024AFF"/>
13
+ <path d="M454.76 304.9H523.33V408.135H454.76V465.023H424.419V408.135H354.938V304.9H424.419V271.753L454.76 272.815V304.9ZM385.052 334.862V378.628H424.343V334.862H385.052ZM454.76 378.552H493.216V334.786H454.76V378.552Z" fill="#024AFF"/>
14
+ <path d="M550.839 695.334L539.385 728.861H500.321L554.935 581.48H605.452L659.61 728.861H619.712L608.486 695.334H550.914H550.839ZM598.17 664.69L581.179 613.945H578.6L561.154 664.69H598.094H598.17Z" fill="#024AFF"/>
15
+ <path d="M1189.6 740.358V305.79H1307.38C1338.99 305.79 1361.95 313.527 1376.27 329C1390.76 344.309 1398 369.659 1398 405.05V424.062C1398 444.474 1394.3 461.017 1386.89 473.692C1379.65 486.367 1368.54 494.679 1353.56 498.63C1373.14 503.568 1386.23 515.173 1392.81 533.445C1399.56 551.552 1402.94 573.692 1402.94 599.865C1402.94 628.013 1400.3 652.622 1395.04 673.692C1389.77 694.762 1380.22 711.14 1366.4 722.828C1352.57 734.515 1332.9 740.358 1307.38 740.358H1189.6ZM1274.54 469.494H1292.32C1300.39 469.494 1305.57 466.367 1307.88 460.111C1310.18 453.856 1311.33 446.367 1311.33 437.642V393.939C1311.33 379.947 1305.16 372.951 1292.81 372.951H1274.54V469.494ZM1283.19 663.815C1305.74 663.815 1317.01 653.116 1317.01 631.716V577.395C1317.01 565.05 1315.12 555.338 1311.33 548.26C1307.71 541.017 1300.8 537.395 1290.59 537.395H1274.54V663.321C1278.16 663.651 1281.05 663.815 1283.19 663.815ZM1497.51 744.309C1476.93 744.309 1461.21 739.535 1450.35 729.988C1439.65 720.441 1432.32 707.354 1428.37 690.729C1424.42 674.103 1422.44 655.256 1422.44 634.186C1422.44 611.634 1424.67 593.198 1429.11 578.877C1433.56 564.391 1441.13 552.539 1451.83 543.321C1462.69 534.103 1477.59 526.284 1496.52 519.865L1551.33 501.099V463.074C1551.33 443.157 1544.83 433.198 1531.83 433.198C1519.98 433.198 1514.05 441.264 1514.05 457.395V479.618H1428.12C1427.96 478.301 1427.88 476.655 1427.88 474.679C1427.88 472.539 1427.88 470.153 1427.88 467.519C1427.88 430.646 1436.52 404.556 1453.8 389.247C1471.25 373.774 1498.82 366.037 1536.52 366.037C1556.27 366.037 1573.97 369.577 1589.6 376.655C1605.24 383.568 1617.59 393.856 1626.64 407.519C1635.86 421.181 1640.47 438.054 1640.47 458.136V740.358H1552.57V696.408C1548.29 711.881 1541.21 723.733 1531.33 731.963C1521.46 740.194 1510.18 744.309 1497.51 744.309ZM1532.32 675.667C1539.56 675.667 1544.5 672.622 1547.14 666.531C1549.77 660.441 1551.09 653.856 1551.09 646.778V543.568C1538.91 548.507 1529.44 554.762 1522.69 562.334C1515.94 569.741 1512.57 580.688 1512.57 595.173V642.828C1512.57 664.721 1519.15 675.667 1532.32 675.667ZM1822.44 744.309C1807.96 744.309 1796.19 740.77 1787.14 733.692C1778.08 726.449 1770.84 715.502 1765.41 700.852V740.358H1675.53V305.79H1765.41V409.494C1770.84 395.832 1778.33 385.214 1787.88 377.642C1797.59 369.906 1811.42 366.037 1829.36 366.037C1853.56 366.037 1870.59 374.844 1880.47 392.457C1890.51 410.07 1895.53 433.116 1895.53 461.593V643.815C1895.53 662.745 1892.9 679.865 1887.63 695.173C1882.53 710.317 1874.54 722.334 1863.68 731.223C1852.98 739.947 1839.23 744.309 1822.44 744.309ZM1785.9 675.42C1795.28 675.42 1800.96 670.811 1802.94 661.593C1804.91 652.375 1805.9 641.017 1805.9 627.519V482.828C1805.9 469.165 1804.91 457.807 1802.94 448.753C1800.96 439.535 1795.37 434.926 1786.15 434.926C1776.6 434.926 1770.76 439.618 1768.62 449C1766.48 458.218 1765.41 469.494 1765.41 482.828V627.519C1765.41 640.852 1766.48 652.21 1768.62 661.593C1770.76 670.811 1776.52 675.42 1785.9 675.42ZM2032.07 744.309C2005.74 744.309 1984.75 739.371 1969.11 729.494C1953.47 719.618 1942.28 705.379 1935.53 686.778C1928.78 668.177 1925.41 645.79 1925.41 619.618V470.729C1925.41 436.325 1935.28 410.317 1955.04 392.704C1974.79 374.926 2001.95 366.037 2036.52 366.037C2107.63 366.037 2143.19 400.935 2143.19 470.729V497.642C2143.19 530.235 2142.86 552.128 2142.2 563.321H2013.8V634.926C2013.8 641.511 2014.21 648.013 2015.04 654.432C2015.86 660.688 2017.67 665.873 2020.47 669.988C2023.43 674.103 2028.12 676.161 2034.54 676.161C2043.76 676.161 2049.52 672.21 2051.83 664.309C2054.13 656.243 2055.28 645.79 2055.28 632.951V597.395H2143.19V618.383C2143.19 646.037 2139.73 669.247 2132.81 688.013C2126.07 706.614 2114.54 720.688 2098.25 730.235C2082.12 739.618 2060.06 744.309 2032.07 744.309ZM2013.31 519.371H2055.28V469.494C2055.28 456.161 2053.64 446.614 2050.35 440.852C2047.05 434.926 2042.12 431.963 2035.53 431.963C2028.45 431.963 2022.94 434.762 2018.99 440.358C2015.2 445.955 2013.31 455.667 2013.31 469.494V519.371ZM2175.28 740.358V305.79H2265.16V740.358H2175.28ZM2302.2 740.358V305.79H2421.7C2452.98 305.79 2476.52 314.515 2492.32 331.963C2508.12 349.247 2516.02 374.597 2516.02 408.013V611.47C2516.02 652.622 2508.78 684.391 2494.3 706.778C2479.98 729.165 2454.79 740.358 2418.74 740.358H2302.2ZM2389.61 663.568H2404.67C2420.63 663.568 2428.62 655.832 2428.62 640.358V416.161C2428.62 401.675 2426.64 392.375 2422.69 388.26C2418.91 383.98 2411.09 381.84 2399.23 381.84H2389.61V663.568ZM2657.75 744.309C2584.01 744.309 2547.14 706.037 2547.14 629.494V480.852C2547.14 445.955 2556.93 418.136 2576.52 397.395C2596.11 376.49 2623.19 366.037 2657.75 366.037C2692.49 366.037 2719.65 376.49 2739.23 397.395C2758.82 418.136 2768.62 445.955 2768.62 480.852V629.494C2768.62 706.037 2731.66 744.309 2657.75 744.309ZM2657.75 676.161C2665.16 676.161 2670.43 673.527 2673.56 668.26C2676.85 662.828 2678.49 655.996 2678.49 647.766V466.778C2678.49 445.214 2671.58 434.432 2657.75 434.432C2643.93 434.432 2637.01 445.214 2637.01 466.778V647.766C2637.01 655.996 2638.58 662.828 2641.7 668.26C2645 673.527 2650.35 676.161 2657.75 676.161ZM2912.81 744.309C2871.33 744.309 2841.87 733.692 2824.42 712.457C2807.14 691.223 2798.49 660.029 2798.49 618.877V504.803C2798.49 473.856 2801.79 448.095 2808.37 427.519C2814.95 406.943 2826.48 391.552 2842.94 381.346C2859.4 371.14 2882.28 366.037 2911.58 366.037C2931.99 366.037 2950.26 369.659 2966.4 376.902C2982.69 384.144 2995.53 394.762 3004.91 408.753C3014.3 422.745 3018.99 439.865 3018.99 460.111V516.655H2928.86V464.803C2928.86 456.243 2927.63 449.083 2925.16 443.321C2922.69 437.395 2917.34 434.432 2909.11 434.432C2894.63 434.432 2887.38 444.721 2887.38 465.297V644.803C2887.38 652.375 2889.03 659.371 2892.32 665.79C2895.61 672.046 2901.05 675.173 2908.62 675.173C2916.35 675.173 2921.7 672.128 2924.67 666.037C2927.79 659.782 2929.36 652.539 2929.36 644.309V582.087H3018.99V646.778C3018.99 667.19 3014.38 684.721 3005.16 699.371C2996.11 713.856 2983.6 724.967 2967.63 732.704C2951.66 740.441 2933.39 744.309 2912.81 744.309Z" fill="#333333"/>
16
+ </svg>
@@ -0,0 +1,15 @@
1
+ <svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M545.008 191.828L6.32129 333.753L175.43 975.617L714.116 833.692L545.008 191.828Z" fill="#D7DAE6"/>
3
+ <path d="M1022.31 162.578L571.803 44.2217L415.301 639.924L865.807 758.28L1022.31 162.578Z" fill="#D7DAE6"/>
4
+ <path d="M776.921 119.796H219.853V904.673H776.921V119.796Z" fill="#024AFF"/>
5
+ <path d="M570.476 253.802H98.2354V483.38H570.476V253.802Z" fill="white"/>
6
+ <path d="M278.124 328.642H151.704V353.926H278.124V328.642Z" fill="#024AFF"/>
7
+ <path d="M233.877 379.209H151.704V404.493H233.877V379.209Z" fill="#024AFF"/>
8
+ <path d="M901.254 541.153H429.013V770.732H901.254V541.153Z" fill="#FFBE19"/>
9
+ <path d="M668.899 512.262C668.899 513.463 668.836 514.664 668.836 515.865H694.12C694.12 514.664 694.183 513.463 694.183 512.262C694.183 439.697 654.488 376.298 595.766 342.48V372.379C639.949 403.225 668.899 454.425 668.899 512.262Z" fill="white"/>
10
+ <path d="M403.73 654.049C357.966 623.455 327.815 571.307 327.815 512.269C327.815 511.068 327.878 509.867 327.878 508.666H302.594C302.594 509.867 302.531 511.068 302.531 512.269C302.531 585.972 343.428 650.256 403.73 683.631V654.049Z" fill="#FFBD14"/>
11
+ <path d="M865.976 619.407H739.557V644.691H865.976V619.407Z" fill="#024AFF"/>
12
+ <path d="M865.976 669.975H783.803V695.259H865.976V669.975Z" fill="#024AFF"/>
13
+ <path d="M453.797 304.9H522.367V408.135H453.797V465.023H423.456V408.135H353.976V304.9H423.456V271.753L453.797 272.815V304.9ZM384.089 334.862V378.628H423.38V334.862H384.089ZM453.797 378.552H492.254V334.786H453.797V378.552Z" fill="#024AFF"/>
14
+ <path d="M549.876 695.334L538.422 728.861H499.358L553.972 581.48H604.489L658.647 728.861H618.749L607.523 695.334H549.952H549.876ZM597.207 664.69L580.217 613.945H577.638L560.192 664.69H597.131H597.207Z" fill="#024AFF"/>
15
+ </svg>
@@ -88,9 +88,9 @@ theme:
88
88
  font:
89
89
  text: Roboto
90
90
  code: Roboto Mono
91
- favicon: assets/favicon.png
92
- icon:
93
- logo: logo
91
+ # favicon: assets/favicon.png
92
+ favicon: images/babeldoc-small-logo-with-transparent-background.svg
93
+ logo: images/babeldoc-small-logo-with-transparent-background.svg
94
94
 
95
95
  # Plugins
96
96
  plugins:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "BabelDOC"
3
- version = "0.1.23"
3
+ version = "0.1.25"
4
4
  description = "Yet Another Document Translator"
5
5
  license = "AGPL-3.0"
6
6
  readme = "README.md"
@@ -31,6 +31,7 @@ dependencies = [
31
31
  "msgpack>=1.1.0",
32
32
  "pydantic>=2.10.6",
33
33
  "tenacity>=9.0.0",
34
+ "scikit-image>=0.25.2",
34
35
  ]
35
36
 
36
37
  [project.urls]
@@ -132,7 +133,7 @@ pythonpath = [".", "src"]
132
133
  testpaths = ["tests"]
133
134
 
134
135
  [bumpver]
135
- current_version = "0.1.23"
136
+ current_version = "0.1.25"
136
137
  version_pattern = "MAJOR.MINOR.PATCH[.PYTAGNUM]"
137
138
 
138
139
  [bumpver.file_patterns]
@@ -48,7 +48,7 @@ wheels = [
48
48
 
49
49
  [[package]]
50
50
  name = "babeldoc"
51
- version = "0.1.23"
51
+ version = "0.1.25"
52
52
  source = { editable = "." }
53
53
  dependencies = [
54
54
  { name = "bitstring" },
@@ -67,6 +67,7 @@ dependencies = [
67
67
  { name = "pydantic" },
68
68
  { name = "pymupdf" },
69
69
  { name = "rich" },
70
+ { name = "scikit-image" },
70
71
  { name = "tenacity" },
71
72
  { name = "toml" },
72
73
  { name = "tqdm" },
@@ -106,6 +107,7 @@ requires-dist = [
106
107
  { name = "pydantic", specifier = ">=2.10.6" },
107
108
  { name = "pymupdf", specifier = ">=1.25.1" },
108
109
  { name = "rich", specifier = ">=13.9.4" },
110
+ { name = "scikit-image", specifier = ">=0.25.2" },
109
111
  { name = "tenacity", specifier = ">=9.0.0" },
110
112
  { name = "toml", specifier = ">=0.10.2" },
111
113
  { name = "tqdm", specifier = ">=4.67.1" },
@@ -660,6 +662,19 @@ wheels = [
660
662
  { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
661
663
  ]
662
664
 
665
+ [[package]]
666
+ name = "imageio"
667
+ version = "2.37.0"
668
+ source = { registry = "https://pypi.org/simple" }
669
+ dependencies = [
670
+ { name = "numpy" },
671
+ { name = "pillow" },
672
+ ]
673
+ sdist = { url = "https://files.pythonhosted.org/packages/0c/47/57e897fb7094afb2d26e8b2e4af9a45c7cf1a405acdeeca001fdf2c98501/imageio-2.37.0.tar.gz", hash = "sha256:71b57b3669666272c818497aebba2b4c5f20d5b37c81720e5e1a56d59c492996", size = 389963 }
674
+ wheels = [
675
+ { url = "https://files.pythonhosted.org/packages/cb/bd/b394387b598ed84d8d0fa90611a90bee0adc2021820ad5729f7ced74a8e2/imageio-2.37.0-py3-none-any.whl", hash = "sha256:11efa15b87bc7871b61590326b2d635439acc321cf7f8ce996f812543ce10eed", size = 315796 },
676
+ ]
677
+
663
678
  [[package]]
664
679
  name = "iniconfig"
665
680
  version = "2.0.0"
@@ -731,6 +746,18 @@ version = "3.0.1"
731
746
  source = { registry = "https://pypi.org/simple" }
732
747
  sdist = { url = "https://files.pythonhosted.org/packages/5e/73/e01e4c5e11ad0494f4407a3f623ad4d87714909f50b17a06ed121034ff6e/jsmin-3.0.1.tar.gz", hash = "sha256:c0959a121ef94542e807a674142606f7e90214a2b3d1eb17300244bbb5cc2bfc", size = 13925 }
733
748
 
749
+ [[package]]
750
+ name = "lazy-loader"
751
+ version = "0.4"
752
+ source = { registry = "https://pypi.org/simple" }
753
+ dependencies = [
754
+ { name = "packaging" },
755
+ ]
756
+ sdist = { url = "https://files.pythonhosted.org/packages/6f/6b/c875b30a1ba490860c93da4cabf479e03f584eba06fe5963f6f6644653d8/lazy_loader-0.4.tar.gz", hash = "sha256:47c75182589b91a4e1a85a136c074285a5ad4d9f39c63e0d7fb76391c4574cd1", size = 15431 }
757
+ wheels = [
758
+ { url = "https://files.pythonhosted.org/packages/83/60/d497a310bde3f01cb805196ac61b7ad6dc5dcf8dce66634dc34364b20b4f/lazy_loader-0.4-py3-none-any.whl", hash = "sha256:342aa8e14d543a154047afb4ba8ef17f5563baad3fc610d7b15b213b0f119efc", size = 12097 },
759
+ ]
760
+
734
761
  [[package]]
735
762
  name = "lexid"
736
763
  version = "2021.1006"
@@ -987,7 +1014,7 @@ wheels = [
987
1014
 
988
1015
  [[package]]
989
1016
  name = "mkdocs-material"
990
- version = "9.6.6"
1017
+ version = "9.6.7"
991
1018
  source = { registry = "https://pypi.org/simple" }
992
1019
  dependencies = [
993
1020
  { name = "babel" },
@@ -1002,9 +1029,9 @@ dependencies = [
1002
1029
  { name = "pymdown-extensions" },
1003
1030
  { name = "requests" },
1004
1031
  ]
1005
- sdist = { url = "https://files.pythonhosted.org/packages/26/b2/4244c578bf00f88181c55a76e484efb429159a1a49db60eaf6b696783760/mkdocs_material-9.6.6.tar.gz", hash = "sha256:06141bd720b0b235829bd59e8afc11d5587c35ae7fc340612d2b3f554e6a69d8", size = 3947396 }
1032
+ sdist = { url = "https://files.pythonhosted.org/packages/9b/d7/93e19c9587e5f4ed25647890555d58cf484a4d412be7037dc17b9c9179d9/mkdocs_material-9.6.7.tar.gz", hash = "sha256:3e2c1fceb9410056c2d91f334a00cdea3215c28750e00c691c1e46b2a33309b4", size = 3947458 }
1006
1033
  wheels = [
1007
- { url = "https://files.pythonhosted.org/packages/a4/2d/c71b689cbccef26806cea4f3dd98f1555cb5894e374c8c5ca6d2106d7fd4/mkdocs_material-9.6.6-py3-none-any.whl", hash = "sha256:904c422ec86086144495831cee2614bb8a0092572ef579af6392b8080309d3a3", size = 8696753 },
1034
+ { url = "https://files.pythonhosted.org/packages/aa/d3/12f22de41bdd9e576ddc459b38c651d68edfb840b32acaa1f46ae36845e3/mkdocs_material-9.6.7-py3-none-any.whl", hash = "sha256:8a159e45e80fcaadd9fbeef62cbf928569b93df954d4dc5ba76d46820caf7b47", size = 8696755 },
1008
1035
  ]
1009
1036
 
1010
1037
  [package.optional-dependencies]
@@ -1116,6 +1143,15 @@ wheels = [
1116
1143
  { url = "https://files.pythonhosted.org/packages/73/80/2708a4641f7d553a63bc934a3eb7214806b5b39d200133ca7f7afb0a53e8/msgpack-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:115a7af8ee9e8cddc10f87636767857e7e3717b7a2e97379dc2054712693e90f", size = 75347 },
1117
1144
  ]
1118
1145
 
1146
+ [[package]]
1147
+ name = "networkx"
1148
+ version = "3.4.2"
1149
+ source = { registry = "https://pypi.org/simple" }
1150
+ sdist = { url = "https://files.pythonhosted.org/packages/fd/1d/06475e1cd5264c0b870ea2cc6fdb3e37177c1e565c43f56ff17a10e3937f/networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1", size = 2151368 }
1151
+ wheels = [
1152
+ { url = "https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f", size = 1723263 },
1153
+ ]
1154
+
1119
1155
  [[package]]
1120
1156
  name = "nodeenv"
1121
1157
  version = "1.9.1"
@@ -1353,6 +1389,54 @@ version = "3.17.9"
1353
1389
  source = { registry = "https://pypi.org/simple" }
1354
1390
  sdist = { url = "https://files.pythonhosted.org/packages/57/09/4393bd378e70b7fc3163ee83353cc27bb520010a5c2b3c924121e7e7e068/peewee-3.17.9.tar.gz", hash = "sha256:fe15cd001758e324c8e3ca8c8ed900e7397c2907291789e1efc383e66b9bc7a8", size = 3026085 }
1355
1391
 
1392
+ [[package]]
1393
+ name = "pillow"
1394
+ version = "11.1.0"
1395
+ source = { registry = "https://pypi.org/simple" }
1396
+ sdist = { url = "https://files.pythonhosted.org/packages/f3/af/c097e544e7bd278333db77933e535098c259609c4eb3b85381109602fb5b/pillow-11.1.0.tar.gz", hash = "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20", size = 46742715 }
1397
+ wheels = [
1398
+ { url = "https://files.pythonhosted.org/packages/50/1c/2dcea34ac3d7bc96a1fd1bd0a6e06a57c67167fec2cff8d95d88229a8817/pillow-11.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:e1abe69aca89514737465752b4bcaf8016de61b3be1397a8fc260ba33321b3a8", size = 3229983 },
1399
+ { url = "https://files.pythonhosted.org/packages/14/ca/6bec3df25e4c88432681de94a3531cc738bd85dea6c7aa6ab6f81ad8bd11/pillow-11.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c640e5a06869c75994624551f45e5506e4256562ead981cce820d5ab39ae2192", size = 3101831 },
1400
+ { url = "https://files.pythonhosted.org/packages/d4/2c/668e18e5521e46eb9667b09e501d8e07049eb5bfe39d56be0724a43117e6/pillow-11.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a07dba04c5e22824816b2615ad7a7484432d7f540e6fa86af60d2de57b0fcee2", size = 4314074 },
1401
+ { url = "https://files.pythonhosted.org/packages/02/80/79f99b714f0fc25f6a8499ecfd1f810df12aec170ea1e32a4f75746051ce/pillow-11.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e267b0ed063341f3e60acd25c05200df4193e15a4a5807075cd71225a2386e26", size = 4394933 },
1402
+ { url = "https://files.pythonhosted.org/packages/81/aa/8d4ad25dc11fd10a2001d5b8a80fdc0e564ac33b293bdfe04ed387e0fd95/pillow-11.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bd165131fd51697e22421d0e467997ad31621b74bfc0b75956608cb2906dda07", size = 4353349 },
1403
+ { url = "https://files.pythonhosted.org/packages/84/7a/cd0c3eaf4a28cb2a74bdd19129f7726277a7f30c4f8424cd27a62987d864/pillow-11.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:abc56501c3fd148d60659aae0af6ddc149660469082859fa7b066a298bde9482", size = 4476532 },
1404
+ { url = "https://files.pythonhosted.org/packages/8f/8b/a907fdd3ae8f01c7670dfb1499c53c28e217c338b47a813af8d815e7ce97/pillow-11.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:54ce1c9a16a9561b6d6d8cb30089ab1e5eb66918cb47d457bd996ef34182922e", size = 4279789 },
1405
+ { url = "https://files.pythonhosted.org/packages/6f/9a/9f139d9e8cccd661c3efbf6898967a9a337eb2e9be2b454ba0a09533100d/pillow-11.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:73ddde795ee9b06257dac5ad42fcb07f3b9b813f8c1f7f870f402f4dc54b5269", size = 4413131 },
1406
+ { url = "https://files.pythonhosted.org/packages/a8/68/0d8d461f42a3f37432203c8e6df94da10ac8081b6d35af1c203bf3111088/pillow-11.1.0-cp310-cp310-win32.whl", hash = "sha256:3a5fe20a7b66e8135d7fd617b13272626a28278d0e578c98720d9ba4b2439d49", size = 2291213 },
1407
+ { url = "https://files.pythonhosted.org/packages/14/81/d0dff759a74ba87715509af9f6cb21fa21d93b02b3316ed43bda83664db9/pillow-11.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:b6123aa4a59d75f06e9dd3dac5bf8bc9aa383121bb3dd9a7a612e05eabc9961a", size = 2625725 },
1408
+ { url = "https://files.pythonhosted.org/packages/ce/1f/8d50c096a1d58ef0584ddc37e6f602828515219e9d2428e14ce50f5ecad1/pillow-11.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:a76da0a31da6fcae4210aa94fd779c65c75786bc9af06289cd1c184451ef7a65", size = 2375213 },
1409
+ { url = "https://files.pythonhosted.org/packages/dd/d6/2000bfd8d5414fb70cbbe52c8332f2283ff30ed66a9cde42716c8ecbe22c/pillow-11.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e06695e0326d05b06833b40b7ef477e475d0b1ba3a6d27da1bb48c23209bf457", size = 3229968 },
1410
+ { url = "https://files.pythonhosted.org/packages/d9/45/3fe487010dd9ce0a06adf9b8ff4f273cc0a44536e234b0fad3532a42c15b/pillow-11.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96f82000e12f23e4f29346e42702b6ed9a2f2fea34a740dd5ffffcc8c539eb35", size = 3101806 },
1411
+ { url = "https://files.pythonhosted.org/packages/e3/72/776b3629c47d9d5f1c160113158a7a7ad177688d3a1159cd3b62ded5a33a/pillow-11.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3cd561ded2cf2bbae44d4605837221b987c216cff94f49dfeed63488bb228d2", size = 4322283 },
1412
+ { url = "https://files.pythonhosted.org/packages/e4/c2/e25199e7e4e71d64eeb869f5b72c7ddec70e0a87926398785ab944d92375/pillow-11.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f189805c8be5ca5add39e6f899e6ce2ed824e65fb45f3c28cb2841911da19070", size = 4402945 },
1413
+ { url = "https://files.pythonhosted.org/packages/c1/ed/51d6136c9d5911f78632b1b86c45241c712c5a80ed7fa7f9120a5dff1eba/pillow-11.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:dd0052e9db3474df30433f83a71b9b23bd9e4ef1de13d92df21a52c0303b8ab6", size = 4361228 },
1414
+ { url = "https://files.pythonhosted.org/packages/48/a4/fbfe9d5581d7b111b28f1d8c2762dee92e9821bb209af9fa83c940e507a0/pillow-11.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:837060a8599b8f5d402e97197d4924f05a2e0d68756998345c829c33186217b1", size = 4484021 },
1415
+ { url = "https://files.pythonhosted.org/packages/39/db/0b3c1a5018117f3c1d4df671fb8e47d08937f27519e8614bbe86153b65a5/pillow-11.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aa8dd43daa836b9a8128dbe7d923423e5ad86f50a7a14dc688194b7be5c0dea2", size = 4287449 },
1416
+ { url = "https://files.pythonhosted.org/packages/d9/58/bc128da7fea8c89fc85e09f773c4901e95b5936000e6f303222490c052f3/pillow-11.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0a2f91f8a8b367e7a57c6e91cd25af510168091fb89ec5146003e424e1558a96", size = 4419972 },
1417
+ { url = "https://files.pythonhosted.org/packages/5f/bb/58f34379bde9fe197f51841c5bbe8830c28bbb6d3801f16a83b8f2ad37df/pillow-11.1.0-cp311-cp311-win32.whl", hash = "sha256:c12fc111ef090845de2bb15009372175d76ac99969bdf31e2ce9b42e4b8cd88f", size = 2291201 },
1418
+ { url = "https://files.pythonhosted.org/packages/3a/c6/fce9255272bcf0c39e15abd2f8fd8429a954cf344469eaceb9d0d1366913/pillow-11.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbd43429d0d7ed6533b25fc993861b8fd512c42d04514a0dd6337fb3ccf22761", size = 2625686 },
1419
+ { url = "https://files.pythonhosted.org/packages/c8/52/8ba066d569d932365509054859f74f2a9abee273edcef5cd75e4bc3e831e/pillow-11.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:f7955ecf5609dee9442cbface754f2c6e541d9e6eda87fad7f7a989b0bdb9d71", size = 2375194 },
1420
+ { url = "https://files.pythonhosted.org/packages/95/20/9ce6ed62c91c073fcaa23d216e68289e19d95fb8188b9fb7a63d36771db8/pillow-11.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2062ffb1d36544d42fcaa277b069c88b01bb7298f4efa06731a7fd6cc290b81a", size = 3226818 },
1421
+ { url = "https://files.pythonhosted.org/packages/b9/d8/f6004d98579a2596c098d1e30d10b248798cceff82d2b77aa914875bfea1/pillow-11.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a85b653980faad27e88b141348707ceeef8a1186f75ecc600c395dcac19f385b", size = 3101662 },
1422
+ { url = "https://files.pythonhosted.org/packages/08/d9/892e705f90051c7a2574d9f24579c9e100c828700d78a63239676f960b74/pillow-11.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9409c080586d1f683df3f184f20e36fb647f2e0bc3988094d4fd8c9f4eb1b3b3", size = 4329317 },
1423
+ { url = "https://files.pythonhosted.org/packages/8c/aa/7f29711f26680eab0bcd3ecdd6d23ed6bce180d82e3f6380fb7ae35fcf3b/pillow-11.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fdadc077553621911f27ce206ffcbec7d3f8d7b50e0da39f10997e8e2bb7f6a", size = 4412999 },
1424
+ { url = "https://files.pythonhosted.org/packages/c8/c4/8f0fe3b9e0f7196f6d0bbb151f9fba323d72a41da068610c4c960b16632a/pillow-11.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:93a18841d09bcdd774dcdc308e4537e1f867b3dec059c131fde0327899734aa1", size = 4368819 },
1425
+ { url = "https://files.pythonhosted.org/packages/38/0d/84200ed6a871ce386ddc82904bfadc0c6b28b0c0ec78176871a4679e40b3/pillow-11.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9aa9aeddeed452b2f616ff5507459e7bab436916ccb10961c4a382cd3e03f47f", size = 4496081 },
1426
+ { url = "https://files.pythonhosted.org/packages/84/9c/9bcd66f714d7e25b64118e3952d52841a4babc6d97b6d28e2261c52045d4/pillow-11.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3cdcdb0b896e981678eee140d882b70092dac83ac1cdf6b3a60e2216a73f2b91", size = 4296513 },
1427
+ { url = "https://files.pythonhosted.org/packages/db/61/ada2a226e22da011b45f7104c95ebda1b63dcbb0c378ad0f7c2a710f8fd2/pillow-11.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:36ba10b9cb413e7c7dfa3e189aba252deee0602c86c309799da5a74009ac7a1c", size = 4431298 },
1428
+ { url = "https://files.pythonhosted.org/packages/e7/c4/fc6e86750523f367923522014b821c11ebc5ad402e659d8c9d09b3c9d70c/pillow-11.1.0-cp312-cp312-win32.whl", hash = "sha256:cfd5cd998c2e36a862d0e27b2df63237e67273f2fc78f47445b14e73a810e7e6", size = 2291630 },
1429
+ { url = "https://files.pythonhosted.org/packages/08/5c/2104299949b9d504baf3f4d35f73dbd14ef31bbd1ddc2c1b66a5b7dfda44/pillow-11.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a697cd8ba0383bba3d2d3ada02b34ed268cb548b369943cd349007730c92bddf", size = 2626369 },
1430
+ { url = "https://files.pythonhosted.org/packages/37/f3/9b18362206b244167c958984b57c7f70a0289bfb59a530dd8af5f699b910/pillow-11.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:4dd43a78897793f60766563969442020e90eb7847463eca901e41ba186a7d4a5", size = 2375240 },
1431
+ { url = "https://files.pythonhosted.org/packages/fa/c5/389961578fb677b8b3244fcd934f720ed25a148b9a5cc81c91bdf59d8588/pillow-11.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8c730dc3a83e5ac137fbc92dfcfe1511ce3b2b5d7578315b63dbbb76f7f51d90", size = 3198345 },
1432
+ { url = "https://files.pythonhosted.org/packages/c4/fa/803c0e50ffee74d4b965229e816af55276eac1d5806712de86f9371858fd/pillow-11.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7d33d2fae0e8b170b6a6c57400e077412240f6f5bb2a342cf1ee512a787942bb", size = 3072938 },
1433
+ { url = "https://files.pythonhosted.org/packages/dc/67/2a3a5f8012b5d8c63fe53958ba906c1b1d0482ebed5618057ef4d22f8076/pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8d65b38173085f24bc07f8b6c505cbb7418009fa1a1fcb111b1f4961814a442", size = 3400049 },
1434
+ { url = "https://files.pythonhosted.org/packages/e5/a0/514f0d317446c98c478d1872497eb92e7cde67003fed74f696441e647446/pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:015c6e863faa4779251436db398ae75051469f7c903b043a48f078e437656f83", size = 3422431 },
1435
+ { url = "https://files.pythonhosted.org/packages/cd/00/20f40a935514037b7d3f87adfc87d2c538430ea625b63b3af8c3f5578e72/pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d44ff19eea13ae4acdaaab0179fa68c0c6f2f45d66a4d8ec1eda7d6cecbcc15f", size = 3446208 },
1436
+ { url = "https://files.pythonhosted.org/packages/28/3c/7de681727963043e093c72e6c3348411b0185eab3263100d4490234ba2f6/pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d3d8da4a631471dfaf94c10c85f5277b1f8e42ac42bade1ac67da4b4a7359b73", size = 3509746 },
1437
+ { url = "https://files.pythonhosted.org/packages/41/67/936f9814bdd74b2dfd4822f1f7725ab5d8ff4103919a1664eb4874c58b2f/pillow-11.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4637b88343166249fe8aa94e7c4a62a180c4b3898283bb5d3d2fd5fe10d8e4e0", size = 2626353 },
1438
+ ]
1439
+
1356
1440
  [[package]]
1357
1441
  name = "platformdirs"
1358
1442
  version = "4.3.6"
@@ -1669,6 +1753,77 @@ wheels = [
1669
1753
  { url = "https://files.pythonhosted.org/packages/31/d8/de873d1c1b020d668d8ec9855d390764cb90cf8f6486c0983da52be8b7b7/ruff-0.9.9-py3-none-win_arm64.whl", hash = "sha256:3ac78f127517209fe6d96ab00f3ba97cafe38718b23b1db3e96d8b2d39e37ddf", size = 10435860 },
1670
1754
  ]
1671
1755
 
1756
+ [[package]]
1757
+ name = "scikit-image"
1758
+ version = "0.25.2"
1759
+ source = { registry = "https://pypi.org/simple" }
1760
+ dependencies = [
1761
+ { name = "imageio" },
1762
+ { name = "lazy-loader" },
1763
+ { name = "networkx" },
1764
+ { name = "numpy" },
1765
+ { name = "packaging" },
1766
+ { name = "pillow" },
1767
+ { name = "scipy" },
1768
+ { name = "tifffile" },
1769
+ ]
1770
+ sdist = { url = "https://files.pythonhosted.org/packages/c7/a8/3c0f256012b93dd2cb6fda9245e9f4bff7dc0486880b248005f15ea2255e/scikit_image-0.25.2.tar.gz", hash = "sha256:e5a37e6cd4d0c018a7a55b9d601357e3382826d3888c10d0213fc63bff977dde", size = 22693594 }
1771
+ wheels = [
1772
+ { url = "https://files.pythonhosted.org/packages/11/cb/016c63f16065c2d333c8ed0337e18a5cdf9bc32d402e4f26b0db362eb0e2/scikit_image-0.25.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d3278f586793176599df6a4cf48cb6beadae35c31e58dc01a98023af3dc31c78", size = 13988922 },
1773
+ { url = "https://files.pythonhosted.org/packages/30/ca/ff4731289cbed63c94a0c9a5b672976603118de78ed21910d9060c82e859/scikit_image-0.25.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:5c311069899ce757d7dbf1d03e32acb38bb06153236ae77fcd820fd62044c063", size = 13192698 },
1774
+ { url = "https://files.pythonhosted.org/packages/39/6d/a2aadb1be6d8e149199bb9b540ccde9e9622826e1ab42fe01de4c35ab918/scikit_image-0.25.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be455aa7039a6afa54e84f9e38293733a2622b8c2fb3362b822d459cc5605e99", size = 14153634 },
1775
+ { url = "https://files.pythonhosted.org/packages/96/08/916e7d9ee4721031b2f625db54b11d8379bd51707afaa3e5a29aecf10bc4/scikit_image-0.25.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4c464b90e978d137330be433df4e76d92ad3c5f46a22f159520ce0fdbea8a09", size = 14767545 },
1776
+ { url = "https://files.pythonhosted.org/packages/5f/ee/c53a009e3997dda9d285402f19226fbd17b5b3cb215da391c4ed084a1424/scikit_image-0.25.2-cp310-cp310-win_amd64.whl", hash = "sha256:60516257c5a2d2f74387c502aa2f15a0ef3498fbeaa749f730ab18f0a40fd054", size = 12812908 },
1777
+ { url = "https://files.pythonhosted.org/packages/c4/97/3051c68b782ee3f1fb7f8f5bb7d535cf8cb92e8aae18fa9c1cdf7e15150d/scikit_image-0.25.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f4bac9196fb80d37567316581c6060763b0f4893d3aca34a9ede3825bc035b17", size = 14003057 },
1778
+ { url = "https://files.pythonhosted.org/packages/19/23/257fc696c562639826065514d551b7b9b969520bd902c3a8e2fcff5b9e17/scikit_image-0.25.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d989d64ff92e0c6c0f2018c7495a5b20e2451839299a018e0e5108b2680f71e0", size = 13180335 },
1779
+ { url = "https://files.pythonhosted.org/packages/ef/14/0c4a02cb27ca8b1e836886b9ec7c9149de03053650e9e2ed0625f248dd92/scikit_image-0.25.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2cfc96b27afe9a05bc92f8c6235321d3a66499995675b27415e0d0c76625173", size = 14144783 },
1780
+ { url = "https://files.pythonhosted.org/packages/dd/9b/9fb556463a34d9842491d72a421942c8baff4281025859c84fcdb5e7e602/scikit_image-0.25.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24cc986e1f4187a12aa319f777b36008764e856e5013666a4a83f8df083c2641", size = 14785376 },
1781
+ { url = "https://files.pythonhosted.org/packages/de/ec/b57c500ee85885df5f2188f8bb70398481393a69de44a00d6f1d055f103c/scikit_image-0.25.2-cp311-cp311-win_amd64.whl", hash = "sha256:b4f6b61fc2db6340696afe3db6b26e0356911529f5f6aee8c322aa5157490c9b", size = 12791698 },
1782
+ { url = "https://files.pythonhosted.org/packages/35/8c/5df82881284459f6eec796a5ac2a0a304bb3384eec2e73f35cfdfcfbf20c/scikit_image-0.25.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8db8dd03663112783221bf01ccfc9512d1cc50ac9b5b0fe8f4023967564719fb", size = 13986000 },
1783
+ { url = "https://files.pythonhosted.org/packages/ce/e6/93bebe1abcdce9513ffec01d8af02528b4c41fb3c1e46336d70b9ed4ef0d/scikit_image-0.25.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:483bd8cc10c3d8a7a37fae36dfa5b21e239bd4ee121d91cad1f81bba10cfb0ed", size = 13235893 },
1784
+ { url = "https://files.pythonhosted.org/packages/53/4b/eda616e33f67129e5979a9eb33c710013caa3aa8a921991e6cc0b22cea33/scikit_image-0.25.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d1e80107bcf2bf1291acfc0bf0425dceb8890abe9f38d8e94e23497cbf7ee0d", size = 14178389 },
1785
+ { url = "https://files.pythonhosted.org/packages/6b/b5/b75527c0f9532dd8a93e8e7cd8e62e547b9f207d4c11e24f0006e8646b36/scikit_image-0.25.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a17e17eb8562660cc0d31bb55643a4da996a81944b82c54805c91b3fe66f4824", size = 15003435 },
1786
+ { url = "https://files.pythonhosted.org/packages/34/e3/49beb08ebccda3c21e871b607c1cb2f258c3fa0d2f609fed0a5ba741b92d/scikit_image-0.25.2-cp312-cp312-win_amd64.whl", hash = "sha256:bdd2b8c1de0849964dbc54037f36b4e9420157e67e45a8709a80d727f52c7da2", size = 12899474 },
1787
+ ]
1788
+
1789
+ [[package]]
1790
+ name = "scipy"
1791
+ version = "1.15.2"
1792
+ source = { registry = "https://pypi.org/simple" }
1793
+ dependencies = [
1794
+ { name = "numpy" },
1795
+ ]
1796
+ sdist = { url = "https://files.pythonhosted.org/packages/b7/b9/31ba9cd990e626574baf93fbc1ac61cf9ed54faafd04c479117517661637/scipy-1.15.2.tar.gz", hash = "sha256:cd58a314d92838f7e6f755c8a2167ead4f27e1fd5c1251fd54289569ef3495ec", size = 59417316 }
1797
+ wheels = [
1798
+ { url = "https://files.pythonhosted.org/packages/95/df/ef233fff6838fe6f7840d69b5ef9f20d2b5c912a8727b21ebf876cb15d54/scipy-1.15.2-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:a2ec871edaa863e8213ea5df811cd600734f6400b4af272e1c011e69401218e9", size = 38692502 },
1799
+ { url = "https://files.pythonhosted.org/packages/5c/20/acdd4efb8a68b842968f7bc5611b1aeb819794508771ad104de418701422/scipy-1.15.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:6f223753c6ea76983af380787611ae1291e3ceb23917393079dcc746ba60cfb5", size = 30085508 },
1800
+ { url = "https://files.pythonhosted.org/packages/42/55/39cf96ca7126f1e78ee72a6344ebdc6702fc47d037319ad93221063e6cf4/scipy-1.15.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:ecf797d2d798cf7c838c6d98321061eb3e72a74710e6c40540f0e8087e3b499e", size = 22359166 },
1801
+ { url = "https://files.pythonhosted.org/packages/51/48/708d26a4ab8a1441536bf2dfcad1df0ca14a69f010fba3ccbdfc02df7185/scipy-1.15.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:9b18aa747da280664642997e65aab1dd19d0c3d17068a04b3fe34e2559196cb9", size = 25112047 },
1802
+ { url = "https://files.pythonhosted.org/packages/dd/65/f9c5755b995ad892020381b8ae11f16d18616208e388621dfacc11df6de6/scipy-1.15.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87994da02e73549dfecaed9e09a4f9d58a045a053865679aeb8d6d43747d4df3", size = 35536214 },
1803
+ { url = "https://files.pythonhosted.org/packages/de/3c/c96d904b9892beec978562f64d8cc43f9cca0842e65bd3cd1b7f7389b0ba/scipy-1.15.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69ea6e56d00977f355c0f84eba69877b6df084516c602d93a33812aa04d90a3d", size = 37646981 },
1804
+ { url = "https://files.pythonhosted.org/packages/3d/74/c2d8a24d18acdeae69ed02e132b9bc1bb67b7bee90feee1afe05a68f9d67/scipy-1.15.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:888307125ea0c4466287191e5606a2c910963405ce9671448ff9c81c53f85f58", size = 37230048 },
1805
+ { url = "https://files.pythonhosted.org/packages/42/19/0aa4ce80eca82d487987eff0bc754f014dec10d20de2f66754fa4ea70204/scipy-1.15.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9412f5e408b397ff5641080ed1e798623dbe1ec0d78e72c9eca8992976fa65aa", size = 40010322 },
1806
+ { url = "https://files.pythonhosted.org/packages/d0/d2/f0683b7e992be44d1475cc144d1f1eeae63c73a14f862974b4db64af635e/scipy-1.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:b5e025e903b4f166ea03b109bb241355b9c42c279ea694d8864d033727205e65", size = 41233385 },
1807
+ { url = "https://files.pythonhosted.org/packages/40/1f/bf0a5f338bda7c35c08b4ed0df797e7bafe8a78a97275e9f439aceb46193/scipy-1.15.2-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:92233b2df6938147be6fa8824b8136f29a18f016ecde986666be5f4d686a91a4", size = 38703651 },
1808
+ { url = "https://files.pythonhosted.org/packages/de/54/db126aad3874601048c2c20ae3d8a433dbfd7ba8381551e6f62606d9bd8e/scipy-1.15.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:62ca1ff3eb513e09ed17a5736929429189adf16d2d740f44e53270cc800ecff1", size = 30102038 },
1809
+ { url = "https://files.pythonhosted.org/packages/61/d8/84da3fffefb6c7d5a16968fe5b9f24c98606b165bb801bb0b8bc3985200f/scipy-1.15.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:4c6676490ad76d1c2894d77f976144b41bd1a4052107902238047fb6a473e971", size = 22375518 },
1810
+ { url = "https://files.pythonhosted.org/packages/44/78/25535a6e63d3b9c4c90147371aedb5d04c72f3aee3a34451f2dc27c0c07f/scipy-1.15.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a8bf5cb4a25046ac61d38f8d3c3426ec11ebc350246a4642f2f315fe95bda655", size = 25142523 },
1811
+ { url = "https://files.pythonhosted.org/packages/e0/22/4b4a26fe1cd9ed0bc2b2cb87b17d57e32ab72c346949eaf9288001f8aa8e/scipy-1.15.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a8e34cf4c188b6dd004654f88586d78f95639e48a25dfae9c5e34a6dc34547e", size = 35491547 },
1812
+ { url = "https://files.pythonhosted.org/packages/32/ea/564bacc26b676c06a00266a3f25fdfe91a9d9a2532ccea7ce6dd394541bc/scipy-1.15.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28a0d2c2075946346e4408b211240764759e0fabaeb08d871639b5f3b1aca8a0", size = 37634077 },
1813
+ { url = "https://files.pythonhosted.org/packages/43/c2/bfd4e60668897a303b0ffb7191e965a5da4056f0d98acfb6ba529678f0fb/scipy-1.15.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:42dabaaa798e987c425ed76062794e93a243be8f0f20fff6e7a89f4d61cb3d40", size = 37231657 },
1814
+ { url = "https://files.pythonhosted.org/packages/4a/75/5f13050bf4f84c931bcab4f4e83c212a36876c3c2244475db34e4b5fe1a6/scipy-1.15.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6f5e296ec63c5da6ba6fa0343ea73fd51b8b3e1a300b0a8cae3ed4b1122c7462", size = 40035857 },
1815
+ { url = "https://files.pythonhosted.org/packages/b9/8b/7ec1832b09dbc88f3db411f8cdd47db04505c4b72c99b11c920a8f0479c3/scipy-1.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:597a0c7008b21c035831c39927406c6181bcf8f60a73f36219b69d010aa04737", size = 41217654 },
1816
+ { url = "https://files.pythonhosted.org/packages/4b/5d/3c78815cbab499610f26b5bae6aed33e227225a9fa5290008a733a64f6fc/scipy-1.15.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c4697a10da8f8765bb7c83e24a470da5797e37041edfd77fd95ba3811a47c4fd", size = 38756184 },
1817
+ { url = "https://files.pythonhosted.org/packages/37/20/3d04eb066b471b6e171827548b9ddb3c21c6bbea72a4d84fc5989933910b/scipy-1.15.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:869269b767d5ee7ea6991ed7e22b3ca1f22de73ab9a49c44bad338b725603301", size = 30163558 },
1818
+ { url = "https://files.pythonhosted.org/packages/a4/98/e5c964526c929ef1f795d4c343b2ff98634ad2051bd2bbadfef9e772e413/scipy-1.15.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:bad78d580270a4d32470563ea86c6590b465cb98f83d760ff5b0990cb5518a93", size = 22437211 },
1819
+ { url = "https://files.pythonhosted.org/packages/1d/cd/1dc7371e29195ecbf5222f9afeedb210e0a75057d8afbd942aa6cf8c8eca/scipy-1.15.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:b09ae80010f52efddb15551025f9016c910296cf70adbf03ce2a8704f3a5ad20", size = 25232260 },
1820
+ { url = "https://files.pythonhosted.org/packages/f0/24/1a181a9e5050090e0b5138c5f496fee33293c342b788d02586bc410c6477/scipy-1.15.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a6fd6eac1ce74a9f77a7fc724080d507c5812d61e72bd5e4c489b042455865e", size = 35198095 },
1821
+ { url = "https://files.pythonhosted.org/packages/c0/53/eaada1a414c026673eb983f8b4a55fe5eb172725d33d62c1b21f63ff6ca4/scipy-1.15.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b871df1fe1a3ba85d90e22742b93584f8d2b8e6124f8372ab15c71b73e428b8", size = 37297371 },
1822
+ { url = "https://files.pythonhosted.org/packages/e9/06/0449b744892ed22b7e7b9a1994a866e64895363572677a316a9042af1fe5/scipy-1.15.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:03205d57a28e18dfd39f0377d5002725bf1f19a46f444108c29bdb246b6c8a11", size = 36872390 },
1823
+ { url = "https://files.pythonhosted.org/packages/6a/6f/a8ac3cfd9505ec695c1bc35edc034d13afbd2fc1882a7c6b473e280397bb/scipy-1.15.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:601881dfb761311045b03114c5fe718a12634e5608c3b403737ae463c9885d53", size = 39700276 },
1824
+ { url = "https://files.pythonhosted.org/packages/f5/6f/e6e5aff77ea2a48dd96808bb51d7450875af154ee7cbe72188afb0b37929/scipy-1.15.2-cp312-cp312-win_amd64.whl", hash = "sha256:e7c68b6a43259ba0aab737237876e5c2c549a031ddb7abc28c7b47f22e202ded", size = 40942317 },
1825
+ ]
1826
+
1672
1827
  [[package]]
1673
1828
  name = "six"
1674
1829
  version = "1.17.0"
@@ -1726,6 +1881,18 @@ wheels = [
1726
1881
  { url = "https://files.pythonhosted.org/packages/b6/cb/b86984bed139586d01532a587464b5805f12e397594f19f931c4c2fbfa61/tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539", size = 28169 },
1727
1882
  ]
1728
1883
 
1884
+ [[package]]
1885
+ name = "tifffile"
1886
+ version = "2025.2.18"
1887
+ source = { registry = "https://pypi.org/simple" }
1888
+ dependencies = [
1889
+ { name = "numpy" },
1890
+ ]
1891
+ sdist = { url = "https://files.pythonhosted.org/packages/de/1f/96d743b3417425f958dfed2518ad271b346a072d27b6859bb158e601bc21/tifffile-2025.2.18.tar.gz", hash = "sha256:8d731789e691b468746c1615d989bc550ac93cf753e9210865222e90a5a95d11", size = 365412 }
1892
+ wheels = [
1893
+ { url = "https://files.pythonhosted.org/packages/63/70/6f363ab13f9903557a567a4471a28ee231b962e34af8e1dd8d1b0f17e64e/tifffile-2025.2.18-py3-none-any.whl", hash = "sha256:54b36c4d5e5b8d8920134413edfe5a7cfb1c7617bb50cddf7e2772edb7149043", size = 226358 },
1894
+ ]
1895
+
1729
1896
  [[package]]
1730
1897
  name = "toml"
1731
1898
  version = "0.10.2"
@@ -1 +0,0 @@
1
- __version__ = "0.1.23"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes