codarascan 0.1.2__tar.gz → 0.2.0__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.
- {codarascan-0.1.2 → codarascan-0.2.0}/CHANGELOG.md +18 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/PKG-INFO +24 -16
- {codarascan-0.1.2 → codarascan-0.2.0}/README.md +23 -15
- {codarascan-0.1.2 → codarascan-0.2.0}/THIRD_PARTY_NOTICES.md +1 -1
- {codarascan-0.1.2 → codarascan-0.2.0}/docs/API.md +7 -4
- {codarascan-0.1.2 → codarascan-0.2.0}/docs/COMPATIBILITY.md +1 -1
- {codarascan-0.1.2 → codarascan-0.2.0}/docs/KNOWN_LIMITATIONS.md +2 -2
- {codarascan-0.1.2 → codarascan-0.2.0}/docs/RELEASE.md +13 -8
- codarascan-0.2.0/docs/RELEASE_EVIDENCE_0.1.2.md +141 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/pyproject.toml +1 -1
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/__init__.py +1 -1
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/cli.py +3 -1
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/documents.py +1 -1
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/__init__.py +1 -1
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/catalog.py +7 -1
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/__init__.py +1 -1
- codarascan-0.2.0/src/codarascan/engines/panorama/__init__.py +6 -0
- codarascan-0.2.0/src/codarascan/engines/panorama/extraction.py +705 -0
- codarascan-0.2.0/src/codarascan/engines/panorama/reconciliation.py +689 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/registry.py +4 -1
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/inputs.py +5 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/models.py +38 -26
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/scanner.py +13 -7
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/schemas/result.decoded.example.json +2 -4
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/schemas/result.localized.example.json +2 -4
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/schemas/result.schema.json +3 -5
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/schemas/stream.example.json +2 -2
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/schemas/stream.schema.json +2 -2
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan.egg-info/PKG-INFO +24 -16
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan.egg-info/SOURCES.txt +4 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/CONTRIBUTING.md +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/LICENSE +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/MANIFEST.in +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/MIGRATION.md +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/NOTICE +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/SECURITY.md +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/docs/RELEASE_EVIDENCE_0.1.0.md +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/docs/WORKER_PROTOCOL.md +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/setup.cfg +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/setup.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/core/__init__.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/core/contracts.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/base.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/classical_2d.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/classical_2d_extractor.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/classical_2d_localizer.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/classical_localizer.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/detection_classical_2d.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/detection_sttg.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/extraction_classical_2d.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/extraction_vendored.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/linear_recovery.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/linear_review_gate_v2.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/linear_review_gate_v3.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/native/__init__.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/native/loader.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/native/sttg_localizer.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/native/sttg_native.cpp +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/pdfium_pages.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/__init__.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/adaptive.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/hybrid.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/locator.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/matrix.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/runtime.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/zxing.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/review_gate.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/tensor_decode.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/tensor_decoder.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/tensor_localizer.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/vendored_decoder.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/mosaic/__init__.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/mosaic/detection.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/mosaic/extraction.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/tessera/__init__.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/tessera/detection.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/tessera/extraction.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/errors.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/formats.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/py.typed +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/schemas/worker.schema.json +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/serialization.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/worker.py +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan.egg-info/dependency_links.txt +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan.egg-info/entry_points.txt +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan.egg-info/requires.txt +0 -0
- {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan.egg-info/top_level.txt +0 -0
|
@@ -3,6 +3,24 @@
|
|
|
3
3
|
All notable changes are recorded here. CodaraScan follows semantic versioning
|
|
4
4
|
after 1.0; during 0.x, breaking changes are identified explicitly.
|
|
5
5
|
|
|
6
|
+
## 0.2.0 - 2026-09-07
|
|
7
|
+
|
|
8
|
+
- Add the Panorama high-recall extraction engine and public
|
|
9
|
+
`Scanner(mode="panorama")` API. Panorama reconciles complementary Tessera,
|
|
10
|
+
whole-page ZXing, split-guard, and failure-tolerant Mosaic results.
|
|
11
|
+
- Preserve `high-recall-extractor` as an input alias for
|
|
12
|
+
`panorama-extractor` while exposing only the new canonical identity.
|
|
13
|
+
|
|
14
|
+
## 0.1.3 - 2026-08-10
|
|
15
|
+
|
|
16
|
+
- Remove Pillow's process-wide decompression-bomb pixel admission threshold
|
|
17
|
+
before normalizing image inputs, preserving CodaraScan's documented policy
|
|
18
|
+
that callers own resource quotas and admission control.
|
|
19
|
+
- Store analyzed `width` and `height` once on each image or PDF page result
|
|
20
|
+
instead of repeating `image_width` and `image_height` on every serialized
|
|
21
|
+
symbol. Constructor-only dimensions still validate geometry without being
|
|
22
|
+
stored on each `SymbolResult`.
|
|
23
|
+
|
|
6
24
|
## 0.1.2 - 2026-08-10
|
|
7
25
|
|
|
8
26
|
- Restrict explicit CLI debug-output directories to mode `0700` and their
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codarascan
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Open-source, offline barcode detection, localization, and decoding for images and PDFs
|
|
5
5
|
Author-email: Abderraouf FELLAHI <ma_fellahi@esi.dz>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -73,7 +73,7 @@ For teams looking for a universal barcode detection layer, CodaraScan provides o
|
|
|
73
73
|
[Formats](#supported-barcode-formats) · [API reference](https://github.com/flh-raouf/codarascan/blob/main/docs/API.md) ·
|
|
74
74
|
[PyPI](https://pypi.org/project/codarascan/)
|
|
75
75
|
|
|
76
|
-
> **Alpha notice — CodaraScan 0.
|
|
76
|
+
> **Alpha notice — CodaraScan 0.2.0 is alpha software.** Its APIs and schemas
|
|
77
77
|
> may change during 0.x. Pin an exact version and evaluate it against your own documents before
|
|
78
78
|
> production use. See the [known limitations](https://github.com/flh-raouf/codarascan/blob/main/docs/KNOWN_LIMITATIONS.md)
|
|
79
79
|
> and [release policy](https://github.com/flh-raouf/codarascan/blob/main/docs/RELEASE.md).
|
|
@@ -89,8 +89,8 @@ Most barcode libraries focus on decoding a clean, tightly cropped symbol. Docume
|
|
|
89
89
|
| Barcode decoding | Returns Unicode text, exact raw payload bytes, and a canonical format name |
|
|
90
90
|
| Document scanning | Reads selected PDF pages, preserves requested order, and supports bounded parallel work |
|
|
91
91
|
| Batch processing | Scans complete or selected multi-page PDFs and can stream pages without accumulating them |
|
|
92
|
-
| Format coverage | 40 selectable formats: 27 linear and 13 matrix selections in version 0.
|
|
93
|
-
| Recovery profiles | `fast` Tessera
|
|
92
|
+
| Format coverage | 40 selectable formats: 27 linear and 13 matrix selections in version 0.2.0 |
|
|
93
|
+
| Recovery profiles | `fast` Tessera for lower latency; `robust` Mosaic for stronger recovery; `panorama` for maximum recall |
|
|
94
94
|
| Local processing | No server, network request, telemetry, external executable, or runtime model download |
|
|
95
95
|
| Integration | Typed Python API, deterministic JSON, CLI, schemas, and a private persistent worker protocol |
|
|
96
96
|
| Deployment | Native wheels for supported Linux, macOS, and Windows targets; Python fallback for Tessera |
|
|
@@ -116,7 +116,7 @@ python -m pip install codarascan
|
|
|
116
116
|
For reproducible alpha deployments, pin the current release:
|
|
117
117
|
|
|
118
118
|
```bash
|
|
119
|
-
python -m pip install codarascan==0.
|
|
119
|
+
python -m pip install codarascan==0.2.0
|
|
120
120
|
```
|
|
121
121
|
|
|
122
122
|
|
|
@@ -128,7 +128,7 @@ python -m pip install codarascan==0.1.2
|
|
|
128
128
|
from codarascan import DecodedSymbolResult, Scanner
|
|
129
129
|
|
|
130
130
|
scanner = Scanner(
|
|
131
|
-
mode="fast", # "fast" (Tessera)
|
|
131
|
+
mode="fast", # "fast" (Tessera), "robust" (Mosaic), or "panorama"
|
|
132
132
|
symbols="all", # "linear", "2d", or "all"
|
|
133
133
|
decode=True,
|
|
134
134
|
)
|
|
@@ -267,22 +267,25 @@ A difficult symbol may be localized without being decoded. CodaraScan keeps that
|
|
|
267
267
|
| `localized` | Geometry-only result produced with `decode=False` |
|
|
268
268
|
| `review_candidate` | A barcode-like region was found with weaker evidence and may require human review |
|
|
269
269
|
|
|
270
|
-
Confidence is an engine-specific evidence score in `[0, 1]`, not a calibrated probability. It is not directly comparable between Tessera and
|
|
270
|
+
Confidence is an engine-specific evidence score in `[0, 1]`, not a calibrated probability. It is not directly comparable between Tessera, Mosaic, and Panorama. Treat `status` as the primary semantic signal.
|
|
271
271
|
|
|
272
|
-
##
|
|
272
|
+
## Choosing a scanning engine
|
|
273
273
|
|
|
274
|
-
CodaraScan makes the performance/recovery choice explicit.
|
|
274
|
+
CodaraScan makes the performance/recovery choice explicit.
|
|
275
275
|
|
|
276
276
|
| Mode | Engine | Best fit | Trade-off |
|
|
277
277
|
|---|---|---|---|
|
|
278
278
|
| `mode="fast"` | Tessera | Low-latency document scanning and common workflows | Less exhaustive recovery |
|
|
279
279
|
| `mode="robust"` | Mosaic | Difficult inputs where stronger recovery is worth more work | Higher CPU time and latency |
|
|
280
|
+
| `mode="panorama"` | Panorama | Maximum-recall extraction and review workflows | Highest CPU time and latency; extraction only |
|
|
280
281
|
|
|
281
|
-
Start with `fast`, measure on representative inputs, and choose `robust`
|
|
282
|
+
Start with `fast`, measure on representative inputs, and choose `robust` or
|
|
283
|
+
`panorama` where the additional recovery materially improves your corpus.
|
|
284
|
+
Avoid choosing a mode from synthetic benchmarks alone.
|
|
282
285
|
|
|
283
286
|
## Supported barcode formats
|
|
284
287
|
|
|
285
|
-
CodaraScan 0.
|
|
288
|
+
CodaraScan 0.2.0 exposes **40 selectable barcode formats** generated from the installed ZXing-C++ readable catalog: **27 linear/1D selections** and **13 matrix/2D selections**.
|
|
286
289
|
|
|
287
290
|
### 1D and linear barcodes
|
|
288
291
|
|
|
@@ -331,8 +334,11 @@ Every symbol includes:
|
|
|
331
334
|
- engine-specific `confidence` and contributing `sources`;
|
|
332
335
|
- `quad`: four pixel-space points in top-left, top-right, bottom-right,
|
|
333
336
|
bottom-left order;
|
|
334
|
-
- `normalized_quad`: the same four points normalized by image width and height
|
|
335
|
-
|
|
337
|
+
- `normalized_quad`: the same four points normalized by image width and height.
|
|
338
|
+
|
|
339
|
+
Image dimensions are recorded once as `width` and `height` on the containing
|
|
340
|
+
image result. PDF page results record `page`, `width`, and `height` together;
|
|
341
|
+
symbols do not repeat those dimensions.
|
|
336
342
|
|
|
337
343
|
A `DecodedSymbolResult` additionally includes `format`, `text`, its `value`
|
|
338
344
|
alias, and exact `raw_bytes`.
|
|
@@ -380,7 +386,7 @@ Run `codarascan image --help` or `codarascan document --help` for every option.
|
|
|
380
386
|
|
|
381
387
|
## Platform support
|
|
382
388
|
|
|
383
|
-
Official 0.
|
|
389
|
+
Official 0.2.0 wheels target:
|
|
384
390
|
|
|
385
391
|
| Operating system | Architectures | Python |
|
|
386
392
|
|---|---|---|
|
|
@@ -424,12 +430,14 @@ Yes. Barcode detection, decoding, PDF rendering, the CLI, and the worker all run
|
|
|
424
430
|
|
|
425
431
|
### Is CodaraScan a universal barcode reader?
|
|
426
432
|
|
|
427
|
-
It is a multi-format barcode detection layer with 40 selectable 1D and 2D formats in version 0.
|
|
433
|
+
It is a multi-format barcode detection layer with 40 selectable 1D and 2D formats in version 0.2.0. No honest scanner can guarantee every barcode under every capture condition, so CodaraScan publishes the exact catalog, evidence, and known limitations instead of making an unlimited compatibility claim.
|
|
428
434
|
|
|
429
435
|
|
|
430
436
|
### Which mode should I use?
|
|
431
437
|
|
|
432
|
-
Begin with `mode="fast"` for lower latency. Evaluate `mode="robust"`
|
|
438
|
+
Begin with `mode="fast"` for lower latency. Evaluate `mode="robust"` for
|
|
439
|
+
difficult inputs and `mode="panorama"` when maximum recall justifies the extra
|
|
440
|
+
work. Benchmark the relevant modes on your actual documents.
|
|
433
441
|
|
|
434
442
|
### Is CodaraScan open source and usable commercially?
|
|
435
443
|
|
|
@@ -16,7 +16,7 @@ For teams looking for a universal barcode detection layer, CodaraScan provides o
|
|
|
16
16
|
[Formats](#supported-barcode-formats) · [API reference](https://github.com/flh-raouf/codarascan/blob/main/docs/API.md) ·
|
|
17
17
|
[PyPI](https://pypi.org/project/codarascan/)
|
|
18
18
|
|
|
19
|
-
> **Alpha notice — CodaraScan 0.
|
|
19
|
+
> **Alpha notice — CodaraScan 0.2.0 is alpha software.** Its APIs and schemas
|
|
20
20
|
> may change during 0.x. Pin an exact version and evaluate it against your own documents before
|
|
21
21
|
> production use. See the [known limitations](https://github.com/flh-raouf/codarascan/blob/main/docs/KNOWN_LIMITATIONS.md)
|
|
22
22
|
> and [release policy](https://github.com/flh-raouf/codarascan/blob/main/docs/RELEASE.md).
|
|
@@ -32,8 +32,8 @@ Most barcode libraries focus on decoding a clean, tightly cropped symbol. Docume
|
|
|
32
32
|
| Barcode decoding | Returns Unicode text, exact raw payload bytes, and a canonical format name |
|
|
33
33
|
| Document scanning | Reads selected PDF pages, preserves requested order, and supports bounded parallel work |
|
|
34
34
|
| Batch processing | Scans complete or selected multi-page PDFs and can stream pages without accumulating them |
|
|
35
|
-
| Format coverage | 40 selectable formats: 27 linear and 13 matrix selections in version 0.
|
|
36
|
-
| Recovery profiles | `fast` Tessera
|
|
35
|
+
| Format coverage | 40 selectable formats: 27 linear and 13 matrix selections in version 0.2.0 |
|
|
36
|
+
| Recovery profiles | `fast` Tessera for lower latency; `robust` Mosaic for stronger recovery; `panorama` for maximum recall |
|
|
37
37
|
| Local processing | No server, network request, telemetry, external executable, or runtime model download |
|
|
38
38
|
| Integration | Typed Python API, deterministic JSON, CLI, schemas, and a private persistent worker protocol |
|
|
39
39
|
| Deployment | Native wheels for supported Linux, macOS, and Windows targets; Python fallback for Tessera |
|
|
@@ -59,7 +59,7 @@ python -m pip install codarascan
|
|
|
59
59
|
For reproducible alpha deployments, pin the current release:
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
|
-
python -m pip install codarascan==0.
|
|
62
|
+
python -m pip install codarascan==0.2.0
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
|
|
@@ -71,7 +71,7 @@ python -m pip install codarascan==0.1.2
|
|
|
71
71
|
from codarascan import DecodedSymbolResult, Scanner
|
|
72
72
|
|
|
73
73
|
scanner = Scanner(
|
|
74
|
-
mode="fast", # "fast" (Tessera)
|
|
74
|
+
mode="fast", # "fast" (Tessera), "robust" (Mosaic), or "panorama"
|
|
75
75
|
symbols="all", # "linear", "2d", or "all"
|
|
76
76
|
decode=True,
|
|
77
77
|
)
|
|
@@ -210,22 +210,25 @@ A difficult symbol may be localized without being decoded. CodaraScan keeps that
|
|
|
210
210
|
| `localized` | Geometry-only result produced with `decode=False` |
|
|
211
211
|
| `review_candidate` | A barcode-like region was found with weaker evidence and may require human review |
|
|
212
212
|
|
|
213
|
-
Confidence is an engine-specific evidence score in `[0, 1]`, not a calibrated probability. It is not directly comparable between Tessera and
|
|
213
|
+
Confidence is an engine-specific evidence score in `[0, 1]`, not a calibrated probability. It is not directly comparable between Tessera, Mosaic, and Panorama. Treat `status` as the primary semantic signal.
|
|
214
214
|
|
|
215
|
-
##
|
|
215
|
+
## Choosing a scanning engine
|
|
216
216
|
|
|
217
|
-
CodaraScan makes the performance/recovery choice explicit.
|
|
217
|
+
CodaraScan makes the performance/recovery choice explicit.
|
|
218
218
|
|
|
219
219
|
| Mode | Engine | Best fit | Trade-off |
|
|
220
220
|
|---|---|---|---|
|
|
221
221
|
| `mode="fast"` | Tessera | Low-latency document scanning and common workflows | Less exhaustive recovery |
|
|
222
222
|
| `mode="robust"` | Mosaic | Difficult inputs where stronger recovery is worth more work | Higher CPU time and latency |
|
|
223
|
+
| `mode="panorama"` | Panorama | Maximum-recall extraction and review workflows | Highest CPU time and latency; extraction only |
|
|
223
224
|
|
|
224
|
-
Start with `fast`, measure on representative inputs, and choose `robust`
|
|
225
|
+
Start with `fast`, measure on representative inputs, and choose `robust` or
|
|
226
|
+
`panorama` where the additional recovery materially improves your corpus.
|
|
227
|
+
Avoid choosing a mode from synthetic benchmarks alone.
|
|
225
228
|
|
|
226
229
|
## Supported barcode formats
|
|
227
230
|
|
|
228
|
-
CodaraScan 0.
|
|
231
|
+
CodaraScan 0.2.0 exposes **40 selectable barcode formats** generated from the installed ZXing-C++ readable catalog: **27 linear/1D selections** and **13 matrix/2D selections**.
|
|
229
232
|
|
|
230
233
|
### 1D and linear barcodes
|
|
231
234
|
|
|
@@ -274,8 +277,11 @@ Every symbol includes:
|
|
|
274
277
|
- engine-specific `confidence` and contributing `sources`;
|
|
275
278
|
- `quad`: four pixel-space points in top-left, top-right, bottom-right,
|
|
276
279
|
bottom-left order;
|
|
277
|
-
- `normalized_quad`: the same four points normalized by image width and height
|
|
278
|
-
|
|
280
|
+
- `normalized_quad`: the same four points normalized by image width and height.
|
|
281
|
+
|
|
282
|
+
Image dimensions are recorded once as `width` and `height` on the containing
|
|
283
|
+
image result. PDF page results record `page`, `width`, and `height` together;
|
|
284
|
+
symbols do not repeat those dimensions.
|
|
279
285
|
|
|
280
286
|
A `DecodedSymbolResult` additionally includes `format`, `text`, its `value`
|
|
281
287
|
alias, and exact `raw_bytes`.
|
|
@@ -323,7 +329,7 @@ Run `codarascan image --help` or `codarascan document --help` for every option.
|
|
|
323
329
|
|
|
324
330
|
## Platform support
|
|
325
331
|
|
|
326
|
-
Official 0.
|
|
332
|
+
Official 0.2.0 wheels target:
|
|
327
333
|
|
|
328
334
|
| Operating system | Architectures | Python |
|
|
329
335
|
|---|---|---|
|
|
@@ -367,12 +373,14 @@ Yes. Barcode detection, decoding, PDF rendering, the CLI, and the worker all run
|
|
|
367
373
|
|
|
368
374
|
### Is CodaraScan a universal barcode reader?
|
|
369
375
|
|
|
370
|
-
It is a multi-format barcode detection layer with 40 selectable 1D and 2D formats in version 0.
|
|
376
|
+
It is a multi-format barcode detection layer with 40 selectable 1D and 2D formats in version 0.2.0. No honest scanner can guarantee every barcode under every capture condition, so CodaraScan publishes the exact catalog, evidence, and known limitations instead of making an unlimited compatibility claim.
|
|
371
377
|
|
|
372
378
|
|
|
373
379
|
### Which mode should I use?
|
|
374
380
|
|
|
375
|
-
Begin with `mode="fast"` for lower latency. Evaluate `mode="robust"`
|
|
381
|
+
Begin with `mode="fast"` for lower latency. Evaluate `mode="robust"` for
|
|
382
|
+
difficult inputs and `mode="panorama"` when maximum recall justifies the extra
|
|
383
|
+
work. Benchmark the relevant modes on your actual documents.
|
|
376
384
|
|
|
377
385
|
### Is CodaraScan open source and usable commercially?
|
|
378
386
|
|
|
@@ -13,7 +13,7 @@ while the declared range remains authoritative for dependency resolution.
|
|
|
13
13
|
| Pillow | `>=10,<13`; 12.3.0 | Encoded-image loading and EXIF orientation; https://python-pillow.org/ | Package metadata: MIT-CMU | External dependency, unmodified. Retain its permission notice; permissive terms are compatible with Apache-2.0 distribution. |
|
|
14
14
|
| PDFium / `pypdfium2` | `>=4.30,<6`; 5.12.1 | Local PDF rendering; https://github.com/pypdfium2-team/pypdfium2 | Package metadata: BSD-3-Clause and Apache-2.0, with dependency license materials in its distribution | External dependency, unmodified. Preserve the dependency's bundled notices and licenses; the declared terms are compatible with Apache-2.0 distribution. |
|
|
15
15
|
| Tessera native extension | repository source at `src/codarascan/engines/common/native/sttg_native.cpp`; 0.1.0 | Structure-tensor acceleration maintained in this repository | Authored project source, Apache-2.0 | Modified as part of the CodaraScan package/native-loader boundary. Distributed with SPDX identification, LICENSE, and NOTICE. |
|
|
16
|
-
| Research-derived Tessera/Mosaic Python modules | repository history under `src/codarascan/engines`; 0.
|
|
16
|
+
| Research-derived Tessera/Mosaic/Panorama Python modules | repository history under `src/codarascan/engines`; 0.2.0 | Canonical engine implementation maintained in this repository | Authored project source, Apache-2.0 | Reorganized and adapted behind the public Scanner contract. No external corpus or confidential document is bundled. Distributed under the project LICENSE and NOTICE. |
|
|
17
17
|
|
|
18
18
|
The `archive/`, benchmark datasets, reports, pinned third-party checkout, and
|
|
19
19
|
ignored research material are not installed as package data. `tools/inspect_artifacts.py`
|
|
@@ -5,12 +5,13 @@
|
|
|
5
5
|
`Scanner(mode="fast", symbols="all", formats=None, decode=True)` is immutable,
|
|
6
6
|
hashable, lazily initialized, reusable, and safe to share across threads.
|
|
7
7
|
|
|
8
|
-
- `mode`: `fast` selects Tessera
|
|
9
|
-
|
|
8
|
+
- `mode`: `fast` selects Tessera, `robust` selects Mosaic, and `panorama`
|
|
9
|
+
selects the high-recall Panorama composition. There is no `auto` mode.
|
|
10
10
|
- `symbols`: `linear`, `2d`, or `all`.
|
|
11
11
|
- `formats`: optional canonical names or accepted aliases. Contradictions with
|
|
12
12
|
`symbols` and unknown names fail at construction.
|
|
13
|
-
- `decode`: a strict boolean. False produces geometry-only public results
|
|
13
|
+
- `decode`: a strict boolean. False produces geometry-only public results and
|
|
14
|
+
is supported by Tessera and Mosaic; Panorama is extraction-only.
|
|
14
15
|
|
|
15
16
|
`warm()` performs the same idempotent initialization used on first scan.
|
|
16
17
|
|
|
@@ -62,7 +63,9 @@ Pixel coordinates use an origin at the orientation-corrected image's top-left,
|
|
|
62
63
|
with x increasing right and y increasing down. Quads contain top-left,
|
|
63
64
|
top-right, bottom-right, and bottom-left corners in clockwise, non-self-
|
|
64
65
|
intersecting order. `normalized_quad` divides x by image width and y by image
|
|
65
|
-
height.
|
|
66
|
+
height. Image results carry `width` and `height` once at the result level. PDF
|
|
67
|
+
page results carry `page`, `width`, and `height` together. Symbols do not repeat
|
|
68
|
+
their containing image dimensions. There is no stable bounding-box field.
|
|
66
69
|
|
|
67
70
|
`DecodedSymbolResult` adds `text`, `value`, `raw_bytes`, and canonical `format`
|
|
68
71
|
to the base geometry/status contract. `SymbolResult` used for localization-only,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Interpreter and platform matrix
|
|
4
4
|
|
|
5
|
-
CodaraScan 0.
|
|
5
|
+
CodaraScan 0.2.0 declares CPython 3.11, 3.12, 3.13, and 3.14. The official
|
|
6
6
|
wheel target matrix is:
|
|
7
7
|
|
|
8
8
|
| Platform | Architectures | Wheel expectation |
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Known limitations in 0.
|
|
1
|
+
# Known limitations in 0.2.0 alpha
|
|
2
2
|
|
|
3
3
|
- Degraded-corpus validation is deepest for established QR Code, Data Matrix,
|
|
4
4
|
and common linear workflows. Broader catalog blur, glare, perspective,
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
structure-tensor linear localizer is tuned for document layouts and does not
|
|
10
10
|
guarantee clean-crop localization for every linear family.
|
|
11
11
|
- Confidence values are not calibrated probabilities and are not comparable
|
|
12
|
-
between Tessera and
|
|
12
|
+
between Tessera, Mosaic, and Panorama.
|
|
13
13
|
- Native and Python-reference Tessera geometry is tolerance-equivalent, not
|
|
14
14
|
pixel-identical.
|
|
15
15
|
- PDF support does not expose a password parameter in 0.1. Password-protected
|
|
@@ -7,7 +7,7 @@ Every 0.x release must:
|
|
|
7
7
|
- pass Ruff, strict public-boundary mypy, unit/integration tests, and native
|
|
8
8
|
fallback/parity checks;
|
|
9
9
|
- build wheel and sdist artifacts and install them outside the source tree;
|
|
10
|
-
- smoke
|
|
10
|
+
- smoke Tessera/Mosaic linear and matrix scans, Panorama extraction, PDFium PDF scanning, CLI JSON, and
|
|
11
11
|
framed worker output from installed artifacts;
|
|
12
12
|
- include the native extension in official wheels and verify forced fallback;
|
|
13
13
|
- include Apache-2.0 license, notice, attribution, schemas, and native source;
|
|
@@ -25,14 +25,19 @@ python -m pytest --cov=codarascan --cov-report=term-missing
|
|
|
25
25
|
python -m build
|
|
26
26
|
python tools/inspect_artifacts.py dist/*.whl dist/*.tar.gz
|
|
27
27
|
python tools/dependency_manifest.py dist/*.whl --output dist/dependency-manifest.json
|
|
28
|
-
python benchmarks
|
|
28
|
+
python -m benchmarks.format_smoke --mode robust --repeats 3
|
|
29
29
|
git diff --check
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
Release records:
|
|
33
|
+
|
|
34
|
+
- [CodaraScan 0.1.2 release evidence](RELEASE_EVIDENCE_0.1.2.md) covers the
|
|
35
|
+
current PyPI release, security hardening, provenance, and Codara verification.
|
|
36
|
+
- [CodaraScan 0.1.0 release evidence](RELEASE_EVIDENCE_0.1.0.md) preserves the
|
|
37
|
+
original alpha-publication record.
|
|
38
|
+
|
|
39
|
+
Platform-matrix and publication results are recorded only after the protected
|
|
40
|
+
release workflow is explicitly approved and run.
|
|
36
41
|
|
|
37
42
|
The release workflow builds CPython 3.11-3.14 wheels on Linux x86_64/ARM64,
|
|
38
43
|
macOS Intel/Apple Silicon, and Windows x86_64. Artifact upload and PyPI trusted
|
|
@@ -42,7 +47,7 @@ publication authority.
|
|
|
42
47
|
|
|
43
48
|
## 1.0 blocking gates
|
|
44
49
|
|
|
45
|
-
Stable 1.0 additionally requires frozen per-format Tessera/Mosaic accuracy,
|
|
50
|
+
Stable 1.0 additionally requires frozen per-format Tessera/Mosaic/Panorama accuracy,
|
|
46
51
|
false-positive, zero-wrong-decode, duplicate, geometry, degraded-case, latency,
|
|
47
52
|
throughput, and peak-memory thresholds; every input/status/error contract;
|
|
48
53
|
native/reference and prior-Poppler/PDFium parity; all official wheels; schema
|
|
@@ -50,4 +55,4 @@ parity across Python/CLI/worker/Codara and any included Node wrapper; complete
|
|
|
50
55
|
Codara package consumption without copied engines; and licensing, privacy,
|
|
51
56
|
offline, upgrade, and artifact reviews.
|
|
52
57
|
|
|
53
|
-
0.
|
|
58
|
+
No 0.x release claims these production gates.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# CodaraScan 0.1.2 release evidence
|
|
2
|
+
|
|
3
|
+
Date: 2026-08-10
|
|
4
|
+
|
|
5
|
+
Scope: documentation refresh, security hardening, public PyPI publication, and
|
|
6
|
+
Codara consumer verification for CodaraScan 0.1.2. This record distinguishes
|
|
7
|
+
completed package publication and downstream integration from the remaining
|
|
8
|
+
GitHub source-visibility gate.
|
|
9
|
+
|
|
10
|
+
## Source and quality gates
|
|
11
|
+
|
|
12
|
+
Source commit: `826998bbb21c41ed7bfe4191380de72ef80fe518`
|
|
13
|
+
|
|
14
|
+
The release source passed the following local gates:
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
Ruff: passed
|
|
18
|
+
mypy: passed
|
|
19
|
+
pytest: 187 passed
|
|
20
|
+
wheel and sdist build: passed
|
|
21
|
+
artifact inspection: passed
|
|
22
|
+
git diff --check: passed
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
GitHub CI run
|
|
26
|
+
[`31397915733`](https://github.com/flh-raouf/codarascan/actions/runs/31397915733)
|
|
27
|
+
passed the quality and distribution jobs, CPython 3.11-3.14 tests, and platform
|
|
28
|
+
smoke tests on Linux x86-64/ARM64, macOS Intel/Apple Silicon, and Windows
|
|
29
|
+
x86-64.
|
|
30
|
+
|
|
31
|
+
The 0.1.2 hardening changes make explicit CLI debug directories owner-only
|
|
32
|
+
(`0700`) and their warning/result files owner-readable and owner-writable only
|
|
33
|
+
(`0600`), including under a permissive process umask. All third-party GitHub
|
|
34
|
+
Actions in the package CI and release workflows are pinned to full commit
|
|
35
|
+
SHAs. A regression test rejects mutable action references, and repository
|
|
36
|
+
Actions policy also requires SHA-pinned actions.
|
|
37
|
+
|
|
38
|
+
## Published artifacts and provenance
|
|
39
|
+
|
|
40
|
+
Release workflow run
|
|
41
|
+
[`31398141966`](https://github.com/flh-raouf/codarascan/actions/runs/31398141966)
|
|
42
|
+
completed successfully using PyPI Trusted Publishing. It built and inspected
|
|
43
|
+
the native-required source distribution and 20 wheels, then required a complete
|
|
44
|
+
21-artifact manifest before publication.
|
|
45
|
+
|
|
46
|
+
PyPI exposes the release at
|
|
47
|
+
<https://pypi.org/project/codarascan/0.1.2/>. The published description is the
|
|
48
|
+
0.1.2 README, including the installation, API, PDF/batch, format, platform,
|
|
49
|
+
privacy, FAQ, SEO/GEO, contact, and limitation sections. PyPI displays Sigstore
|
|
50
|
+
provenance for the artifacts and binds publication to the source commit and
|
|
51
|
+
`release.yml` workflow above.
|
|
52
|
+
|
|
53
|
+
The published source distribution is:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
f58e35058f98a73a407ddf2f5b705c54f02f9d246709b4ba7962daeddb94bbc8 codarascan-0.1.2.tar.gz
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Independent registry verification
|
|
60
|
+
|
|
61
|
+
A new virtual environment outside the repository installed the exact version
|
|
62
|
+
from the public simple index with no wheel cache:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
python -m pip install --no-cache-dir --index-url https://pypi.org/simple \
|
|
66
|
+
codarascan==0.1.2
|
|
67
|
+
codarascan --version
|
|
68
|
+
# codarascan 0.1.2 (Apache-2.0)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The imported module resolved from the environment's `site-packages`, not the
|
|
72
|
+
source checkout. The installed package also reproduced the owner-only debug
|
|
73
|
+
directory and file modes.
|
|
74
|
+
|
|
75
|
+
## Codara consumer verification
|
|
76
|
+
|
|
77
|
+
Codara migration commit `031ee468f5f5addc7c549bb94413cd5b73276941`
|
|
78
|
+
pins `codarascan==0.1.2` and commits a registry-backed production lock. A clean
|
|
79
|
+
`uv --no-sources --locked` environment imported 0.1.2 from `site-packages` and
|
|
80
|
+
passed all 75 backend tests.
|
|
81
|
+
|
|
82
|
+
Codara CI run
|
|
83
|
+
[`31401474599`](https://github.com/flh-raouf/codara/actions/runs/31401474599)
|
|
84
|
+
passed backend checks, frontend typechecking/tests/build, and the production
|
|
85
|
+
container build from the neutral `codarascan-0.1.2-migration` branch. The five
|
|
86
|
+
migration commits were then merged into Codara `main` through
|
|
87
|
+
[Codara PR #3](https://github.com/flh-raouf/codara/pull/3) at merge commit
|
|
88
|
+
`cfb0aca331727b07f00f24c655526d66e5613218`.
|
|
89
|
+
|
|
90
|
+
Post-merge Codara CI/CD run
|
|
91
|
+
[`31404892126`](https://github.com/flh-raouf/codara/actions/runs/31404892126)
|
|
92
|
+
passed backend checks, frontend typechecking/tests/build, the production
|
|
93
|
+
container build, the OpenScaler deployment, and the public endpoint health
|
|
94
|
+
check.
|
|
95
|
+
|
|
96
|
+
## Public-source safety gate
|
|
97
|
+
|
|
98
|
+
The distributable package and PyPI release are public. The GitHub repository is
|
|
99
|
+
intentionally private while GitHub Support removes three immutable pull-request
|
|
100
|
+
refs that still retain objects from before the sanitized history rewrite.
|
|
101
|
+
Normal branches and tags expose only the sanitized history. The source
|
|
102
|
+
repository must not be made public until GitHub confirms the server-side purge
|
|
103
|
+
and cached-view cleanup.
|
|
104
|
+
|
|
105
|
+
The preserved research tree also passed a targeted publication-residue scan:
|
|
106
|
+
it contains no personal filesystem paths, internal document names, `VN LOT`
|
|
107
|
+
labels, or assistant-environment cache names. Research notebook cache examples
|
|
108
|
+
now use the neutral `barcode-research` label, and private benchmark groups use
|
|
109
|
+
generic corpus names. All retained synthetic benchmark PDFs have an empty
|
|
110
|
+
Author field and only anonymous or generic dataset-generator Creator metadata.
|
|
111
|
+
The maintainer name and contact email remain intentionally public in package
|
|
112
|
+
metadata, the README, and the license notices.
|
|
113
|
+
|
|
114
|
+
GitHub Actions history was audited separately because workflow logs and
|
|
115
|
+
artifacts become externally visible with a public repository. All 18 retained
|
|
116
|
+
CodaraScan workflow logs were downloaded and scanned; no personal paths,
|
|
117
|
+
internal dossier or dataset names, research notebook names, or checkpoint paths
|
|
118
|
+
were present. All 25 retained artifact bundles were downloaded, yielding 60
|
|
119
|
+
wheel and source-distribution files across versions 0.1.0-0.1.2. Every file
|
|
120
|
+
passed the matching-version artifact inspector for forbidden content, local
|
|
121
|
+
paths, credentials, unsafe archive paths, license/SPDX coverage, and packaging
|
|
122
|
+
boundaries. One duplicate CI run records the branch label used before the
|
|
123
|
+
neutral branch rename, but contains no confidential data.
|
|
124
|
+
|
|
125
|
+
The GitHub Support payload has been derived and retained privately: repository
|
|
126
|
+
identity, three affected pull requests, the first-changed-commit mapping, and
|
|
127
|
+
confirmation that the rewrite reported no filtering problems, no LFS object
|
|
128
|
+
store exists, and GitHub reports zero forks. Sensitive object identifiers are
|
|
129
|
+
intentionally not reproduced in this public evidence file.
|
|
130
|
+
|
|
131
|
+
The repository's issue #3 was deleted. Main rejects force-pushes and deletions,
|
|
132
|
+
enforces administrators, linear history, resolved conversations, pull-request
|
|
133
|
+
flow, and the complete up-to-date CI matrix. Dependabot and automated security
|
|
134
|
+
updates are enabled. Code scanning, secret scanning, and push protection remain
|
|
135
|
+
platform/plan-dependent while the repository is private and should be enabled
|
|
136
|
+
immediately after the visibility gate is cleared.
|
|
137
|
+
|
|
138
|
+
The standard security review reported two medium findings; both were fixed in
|
|
139
|
+
0.1.2 and their original reproductions no longer succeed. The environment did
|
|
140
|
+
not provide the managed read-only profile required by the deeper independent
|
|
141
|
+
scan, so this record does not claim that unavailable coverage.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "codarascan"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "Open-source, offline barcode detection, localization, and decoding for images and PDFs"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11,<3.15"
|
|
@@ -82,7 +82,9 @@ def _workers(value: str) -> int | str:
|
|
|
82
82
|
|
|
83
83
|
|
|
84
84
|
def _add_scanner_options(parser: argparse.ArgumentParser) -> None:
|
|
85
|
-
parser.add_argument(
|
|
85
|
+
parser.add_argument(
|
|
86
|
+
"--mode", choices=("fast", "robust", "panorama"), default="fast"
|
|
87
|
+
)
|
|
86
88
|
parser.add_argument("--symbols", choices=("linear", "2d", "all"), default="all")
|
|
87
89
|
parser.add_argument("--formats", type=_formats)
|
|
88
90
|
parser.add_argument("--no-decode", action="store_true")
|
|
@@ -60,7 +60,7 @@ def _document_source(value: DocumentInput) -> str | bytes:
|
|
|
60
60
|
)
|
|
61
61
|
if path.suffix.lower() != ".pdf":
|
|
62
62
|
raise DocumentError(
|
|
63
|
-
"the
|
|
63
|
+
"the document API supports PDF files only",
|
|
64
64
|
context={"path": str(path), "type": path.suffix.lower()},
|
|
65
65
|
)
|
|
66
66
|
return str(path)
|
|
@@ -48,7 +48,7 @@ def load_registry() -> Any:
|
|
|
48
48
|
missing.startswith(f"{module}.") for module in engine_modules
|
|
49
49
|
):
|
|
50
50
|
raise RuntimeError(
|
|
51
|
-
"The Tessera/Mosaic runtime is unavailable because "
|
|
51
|
+
"The Tessera/Mosaic/Panorama runtime is unavailable because "
|
|
52
52
|
f"{missing!r} is missing. Install the engine dependencies with "
|
|
53
53
|
"`pip install -e .` before loading the registry."
|
|
54
54
|
) from exc
|
|
@@ -11,7 +11,7 @@ from dataclasses import dataclass
|
|
|
11
11
|
from typing import Literal
|
|
12
12
|
|
|
13
13
|
CapabilityName = Literal["detect", "decode"]
|
|
14
|
-
Role = Literal["recommended", "base"]
|
|
14
|
+
Role = Literal["recommended", "base", "high-recall"]
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
@dataclass(frozen=True)
|
|
@@ -50,4 +50,10 @@ ENGINE_CATALOG: tuple[EngineSpec, ...] = (
|
|
|
50
50
|
role="base",
|
|
51
51
|
source="src/codarascan/engines/mosaic/extraction.py",
|
|
52
52
|
),
|
|
53
|
+
EngineSpec(
|
|
54
|
+
name="Panorama",
|
|
55
|
+
capability="decode",
|
|
56
|
+
role="high-recall",
|
|
57
|
+
source="src/codarascan/engines/panorama/extraction.py",
|
|
58
|
+
),
|
|
53
59
|
)
|