@trustchex/react-native-sdk 1.513.2 → 1.513.3
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.
- package/lib/module/Shared/Components/IdentityDocumentCamera.constants.js +9 -0
- package/lib/module/Shared/Components/IdentityDocumentCamera.js +32 -2
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts +1 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/Shared/Components/IdentityDocumentCamera.constants.ts +9 -0
- package/src/Shared/Components/IdentityDocumentCamera.tsx +43 -1
- package/src/version.ts +1 -1
|
@@ -15,6 +15,15 @@ export const MIN_MLI_FACE_SIZE_PERCENT = 0.01; // MLI (Multi Layer Image): min 1
|
|
|
15
15
|
export const REQUIRED_CONSISTENT_MRZ_READS = 2;
|
|
16
16
|
export const REQUIRED_CONSISTENT_DOCTYPE_DETECTIONS = 3;
|
|
17
17
|
|
|
18
|
+
// Frames a check-digit-VALID MRZ consensus must stay UNCHANGED before it is
|
|
19
|
+
// accepted regardless of the per-cell vote-margin ("confident") gate. This
|
|
20
|
+
// unblocks a dense passport MRZ where one stubborn OCR-B look-alike keeps a
|
|
21
|
+
// single cell below the margin threshold forever — the scan would otherwise
|
|
22
|
+
// wedge on "hold steady". Set well above the aggregator's stabilityTarget (3)
|
|
23
|
+
// so the normal confident+stable path handles the common case and this only
|
|
24
|
+
// rescues the persistent-look-alike tail (~1.5s at ~8fps).
|
|
25
|
+
export const MRZ_STREAK_ACCEPT_OVERRIDE = 12;
|
|
26
|
+
|
|
18
27
|
// After this long on a single scan step without completing it, surface the
|
|
19
28
|
// "Having trouble?" prompt so the user isn't stranded on a live camera with no
|
|
20
29
|
// timeout, retry, or help. Per-step (re-armed on each step transition).
|
|
@@ -24,7 +24,7 @@ import { useTheme } from "../Contexts/ThemeContext.js";
|
|
|
24
24
|
import DebugOverlay, { TestModePanel } from "./DebugOverlay.js";
|
|
25
25
|
import { getStatusMessage, getFrameToScreenTransform, transformBoundsToScreen, getScanAreaBounds, angleBetweenPoints, detectDocumentType, determineDocumentTypeToSet, areMRZFieldsEqual, hasRequiredMRZFields, validateFacePosition, isPassportDocumentCode, StableFlag } from "./IdentityDocumentCamera.utils.js";
|
|
26
26
|
import { handlePassportFlow, handleIDFrontFlow, handleIDBackFlow, getNextStepAfterHologram } from "./IdentityDocumentCamera.flows.js";
|
|
27
|
-
import { HOLOGRAM_IMAGE_COUNT, HOLOGRAM_DETECTION_THRESHOLD, HOLOGRAM_DETECTION_RETRY_COUNT, HOLOGRAM_CAPTURE_INTERVAL, HOLOGRAM_MAX_FRAMES_WITHOUT_FACE, MIN_BRIGHTNESS_THRESHOLD, FACE_EDGE_MARGIN_PERCENT, MAX_CONSECUTIVE_QUALITY_FAILURES, REQUIRED_CONSISTENT_DOCTYPE_DETECTIONS, HELP_PROMPT_DELAY_MS, SIGNATURE_TEXT_REGEX, MRZ_BLOCK_PATTERN, MIN_CARD_FACE_SIZE_PERCENT } from "./IdentityDocumentCamera.constants.js";
|
|
27
|
+
import { HOLOGRAM_IMAGE_COUNT, HOLOGRAM_DETECTION_THRESHOLD, HOLOGRAM_DETECTION_RETRY_COUNT, HOLOGRAM_CAPTURE_INTERVAL, HOLOGRAM_MAX_FRAMES_WITHOUT_FACE, MIN_BRIGHTNESS_THRESHOLD, FACE_EDGE_MARGIN_PERCENT, MAX_CONSECUTIVE_QUALITY_FAILURES, REQUIRED_CONSISTENT_DOCTYPE_DETECTIONS, MRZ_STREAK_ACCEPT_OVERRIDE, HELP_PROMPT_DELAY_MS, SIGNATURE_TEXT_REGEX, MRZ_BLOCK_PATTERN, MIN_CARD_FACE_SIZE_PERCENT } from "./IdentityDocumentCamera.constants.js";
|
|
28
28
|
|
|
29
29
|
// Re-export types for backward compatibility
|
|
30
30
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
@@ -810,7 +810,19 @@ const IdentityDocumentCamera = ({
|
|
|
810
810
|
// vote must be unchanged across `stabilityTarget` consecutive contributing
|
|
811
811
|
// frames, which is exactly the "only accept once stable" guarantee.
|
|
812
812
|
// `addFrame` runs for every frame above, so the consensus is always current.
|
|
813
|
-
|
|
813
|
+
// `consensus.stable` also requires a "confident" vote — every contested
|
|
814
|
+
// cell's winner must lead by a margin. On a dense TD3 passport MRZ (88
|
|
815
|
+
// cells) a single stubborn OCR-B look-alike (A↔4, S↔5) can keep one cell
|
|
816
|
+
// at a 1-vote margin indefinitely, so `stable` never flips and the scan
|
|
817
|
+
// wedges on "hold steady" — even though the check-digit-VALID consensus
|
|
818
|
+
// has been UNCHANGED for many frames. Check digits are the real correctness
|
|
819
|
+
// guarantee; a long unchanged, valid streak is conclusive. So also accept
|
|
820
|
+
// once a valid consensus has held unchanged for MRZ_STREAK_ACCEPT_OVERRIDE
|
|
821
|
+
// frames (well above `stabilityTarget`), independent of the margin gate.
|
|
822
|
+
// Short streaks still require the full confident+stable gate, preserving
|
|
823
|
+
// the early-misread protection.
|
|
824
|
+
const mrzValidStreakSettled = parsedMRZData?.valid === true && consensus.stableStreak >= MRZ_STREAK_ACCEPT_OVERRIDE;
|
|
825
|
+
const mrzStableAndValid = (consensus.stable || mrzValidStreakSettled) && parsedMRZData?.valid === true;
|
|
814
826
|
|
|
815
827
|
// Surface the reliable-detection signal to the render so the UI can show a
|
|
816
828
|
// green "GO" the moment (and only once) the consensus is stable + valid.
|
|
@@ -1484,6 +1496,24 @@ const IdentityDocumentCamera = ({
|
|
|
1484
1496
|
}))
|
|
1485
1497
|
};
|
|
1486
1498
|
|
|
1499
|
+
// Isolate the MRZ text (bottom-of-document blocks matching the MRZ
|
|
1500
|
+
// pattern) and feed ONLY that to the multi-frame consensus. CRITICAL:
|
|
1501
|
+
// this must run for EVERY build, not just debug — the identical logic
|
|
1502
|
+
// used to live only inside an `if (isDebugEnabled())` overlay block, so
|
|
1503
|
+
// in release `mrzOnlyText` was never set and the aggregator fell back to
|
|
1504
|
+
// the FULL OCR text (including the passport header "PASSPORT / TÜR /
|
|
1505
|
+
// REPUBLIC OF…"). That header noise kept the per-character consensus from
|
|
1506
|
+
// ever stabilizing, so a passport wedged on "hold steady" forever in
|
|
1507
|
+
// release while working in debug/example. Passport MRZ sits low on the
|
|
1508
|
+
// page; the `y > bottom-half` filter drops the header/photo-area text.
|
|
1509
|
+
if (textBlocks.length > 0) {
|
|
1510
|
+
const bottomHalf = frame.height * 0.5;
|
|
1511
|
+
const mrzBlocks = textBlocks.filter(block => block.blockFrame && block.blockFrame.y > bottomHalf && MRZ_BLOCK_PATTERN.test(block.text));
|
|
1512
|
+
if (mrzBlocks.length > 0) {
|
|
1513
|
+
scannedText.mrzOnlyText = [...mrzBlocks].sort((a, b) => (a.blockFrame?.y || 0) - (b.blockFrame?.y || 0)).map(b => b.text).join('\n');
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1487
1517
|
// Read barcodes directly from native ML Kit results
|
|
1488
1518
|
let barcodes = [];
|
|
1489
1519
|
if (frame.barcodes) {
|
package/lib/module/version.js
CHANGED
|
@@ -11,6 +11,7 @@ export declare const MIN_CARD_FACE_SIZE_PERCENT = 0.05;
|
|
|
11
11
|
export declare const MIN_MLI_FACE_SIZE_PERCENT = 0.01;
|
|
12
12
|
export declare const REQUIRED_CONSISTENT_MRZ_READS = 2;
|
|
13
13
|
export declare const REQUIRED_CONSISTENT_DOCTYPE_DETECTIONS = 3;
|
|
14
|
+
export declare const MRZ_STREAK_ACCEPT_OVERRIDE = 12;
|
|
14
15
|
export declare const HELP_PROMPT_DELAY_MS = 25000;
|
|
15
16
|
export declare const SIGNATURE_REGEX: RegExp;
|
|
16
17
|
export declare const SIGNATURE_TEXT_REGEX: RegExp;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IdentityDocumentCamera.constants.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,4BAA4B,OAAO,CAAC;AACjD,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,gCAAgC,KAAK,CAAC;AAEnD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,gCAAgC,KAAK,CAAC;AACnD,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAC/C,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAC/C,eAAO,MAAM,sCAAsC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"IdentityDocumentCamera.constants.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,4BAA4B,OAAO,CAAC;AACjD,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,gCAAgC,KAAK,CAAC;AAEnD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,gCAAgC,KAAK,CAAC;AACnD,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAC/C,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAC/C,eAAO,MAAM,sCAAsC,IAAI,CAAC;AASxD,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAK7C,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAE1C,eAAO,MAAM,eAAe,QAAkC,CAAC;AAC/D,eAAO,MAAM,oBAAoB,QAAyB,CAAC;AAC3D,eAAO,MAAM,iBAAiB,QAAsB,CAAC;AASrD,eAAO,MAAM,iBAAiB,QAA+B,CAAC;AAS9D,eAAO,MAAM,oBAAoB,QAAyC,CAAC;AAI3E,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD,eAAO,MAAM,sBAAsB;;;;;;;;;;CAUzB,CAAC;AAKX,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,eAAO,MAAM,gCAAgC,MAAM,CAAC;AACpD,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAChD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,mBAAmB,MAAM,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IdentityDocumentCamera.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"IdentityDocumentCamera.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.tsx"],"names":[],"mappings":"AA6EA,OAAO,KAAK,EACV,mBAAmB,EACnB,SAAS,EACT,2BAA2B,EAK5B,MAAM,gCAAgC,CAAC;AAGxC,YAAY,EAAE,mBAAmB,EAAE,SAAS,EAAE,2BAA2B,EAAE,CAAC;AAC5E,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAMnE,QAAA,MAAM,sBAAsB,GAAI,uDAI7B,2BAA2B,4CA2uF7B,CAAC;AAmLF,eAAe,sBAAsB,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "1.513.
|
|
1
|
+
export declare const SDK_VERSION = "1.513.3";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
@@ -14,6 +14,15 @@ export const MIN_MLI_FACE_SIZE_PERCENT = 0.01; // MLI (Multi Layer Image): min 1
|
|
|
14
14
|
export const REQUIRED_CONSISTENT_MRZ_READS = 2;
|
|
15
15
|
export const REQUIRED_CONSISTENT_DOCTYPE_DETECTIONS = 3;
|
|
16
16
|
|
|
17
|
+
// Frames a check-digit-VALID MRZ consensus must stay UNCHANGED before it is
|
|
18
|
+
// accepted regardless of the per-cell vote-margin ("confident") gate. This
|
|
19
|
+
// unblocks a dense passport MRZ where one stubborn OCR-B look-alike keeps a
|
|
20
|
+
// single cell below the margin threshold forever — the scan would otherwise
|
|
21
|
+
// wedge on "hold steady". Set well above the aggregator's stabilityTarget (3)
|
|
22
|
+
// so the normal confident+stable path handles the common case and this only
|
|
23
|
+
// rescues the persistent-look-alike tail (~1.5s at ~8fps).
|
|
24
|
+
export const MRZ_STREAK_ACCEPT_OVERRIDE = 12;
|
|
25
|
+
|
|
17
26
|
// After this long on a single scan step without completing it, surface the
|
|
18
27
|
// "Having trouble?" prompt so the user isn't stranded on a live camera with no
|
|
19
28
|
// timeout, retry, or help. Per-step (re-armed on each step transition).
|
|
@@ -69,6 +69,7 @@ import {
|
|
|
69
69
|
MAX_CONSECUTIVE_QUALITY_FAILURES,
|
|
70
70
|
REQUIRED_CONSISTENT_MRZ_READS,
|
|
71
71
|
REQUIRED_CONSISTENT_DOCTYPE_DETECTIONS,
|
|
72
|
+
MRZ_STREAK_ACCEPT_OVERRIDE,
|
|
72
73
|
HELP_PROMPT_DELAY_MS,
|
|
73
74
|
SIGNATURE_TEXT_REGEX,
|
|
74
75
|
MRZ_BLOCK_PATTERN,
|
|
@@ -1173,8 +1174,23 @@ const IdentityDocumentCamera = ({
|
|
|
1173
1174
|
// vote must be unchanged across `stabilityTarget` consecutive contributing
|
|
1174
1175
|
// frames, which is exactly the "only accept once stable" guarantee.
|
|
1175
1176
|
// `addFrame` runs for every frame above, so the consensus is always current.
|
|
1177
|
+
// `consensus.stable` also requires a "confident" vote — every contested
|
|
1178
|
+
// cell's winner must lead by a margin. On a dense TD3 passport MRZ (88
|
|
1179
|
+
// cells) a single stubborn OCR-B look-alike (A↔4, S↔5) can keep one cell
|
|
1180
|
+
// at a 1-vote margin indefinitely, so `stable` never flips and the scan
|
|
1181
|
+
// wedges on "hold steady" — even though the check-digit-VALID consensus
|
|
1182
|
+
// has been UNCHANGED for many frames. Check digits are the real correctness
|
|
1183
|
+
// guarantee; a long unchanged, valid streak is conclusive. So also accept
|
|
1184
|
+
// once a valid consensus has held unchanged for MRZ_STREAK_ACCEPT_OVERRIDE
|
|
1185
|
+
// frames (well above `stabilityTarget`), independent of the margin gate.
|
|
1186
|
+
// Short streaks still require the full confident+stable gate, preserving
|
|
1187
|
+
// the early-misread protection.
|
|
1188
|
+
const mrzValidStreakSettled =
|
|
1189
|
+
parsedMRZData?.valid === true &&
|
|
1190
|
+
consensus.stableStreak >= MRZ_STREAK_ACCEPT_OVERRIDE;
|
|
1176
1191
|
const mrzStableAndValid =
|
|
1177
|
-
consensus.stable
|
|
1192
|
+
(consensus.stable || mrzValidStreakSettled) &&
|
|
1193
|
+
parsedMRZData?.valid === true;
|
|
1178
1194
|
|
|
1179
1195
|
// Surface the reliable-detection signal to the render so the UI can show a
|
|
1180
1196
|
// green "GO" the moment (and only once) the consensus is stable + valid.
|
|
@@ -2127,6 +2143,32 @@ const IdentityDocumentCamera = ({
|
|
|
2127
2143
|
})),
|
|
2128
2144
|
};
|
|
2129
2145
|
|
|
2146
|
+
// Isolate the MRZ text (bottom-of-document blocks matching the MRZ
|
|
2147
|
+
// pattern) and feed ONLY that to the multi-frame consensus. CRITICAL:
|
|
2148
|
+
// this must run for EVERY build, not just debug — the identical logic
|
|
2149
|
+
// used to live only inside an `if (isDebugEnabled())` overlay block, so
|
|
2150
|
+
// in release `mrzOnlyText` was never set and the aggregator fell back to
|
|
2151
|
+
// the FULL OCR text (including the passport header "PASSPORT / TÜR /
|
|
2152
|
+
// REPUBLIC OF…"). That header noise kept the per-character consensus from
|
|
2153
|
+
// ever stabilizing, so a passport wedged on "hold steady" forever in
|
|
2154
|
+
// release while working in debug/example. Passport MRZ sits low on the
|
|
2155
|
+
// page; the `y > bottom-half` filter drops the header/photo-area text.
|
|
2156
|
+
if (textBlocks.length > 0) {
|
|
2157
|
+
const bottomHalf = frame.height * 0.5;
|
|
2158
|
+
const mrzBlocks = textBlocks.filter(
|
|
2159
|
+
(block) =>
|
|
2160
|
+
block.blockFrame &&
|
|
2161
|
+
block.blockFrame.y > bottomHalf &&
|
|
2162
|
+
MRZ_BLOCK_PATTERN.test(block.text)
|
|
2163
|
+
);
|
|
2164
|
+
if (mrzBlocks.length > 0) {
|
|
2165
|
+
scannedText.mrzOnlyText = [...mrzBlocks]
|
|
2166
|
+
.sort((a, b) => (a.blockFrame?.y || 0) - (b.blockFrame?.y || 0))
|
|
2167
|
+
.map((b) => b.text)
|
|
2168
|
+
.join('\n');
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2130
2172
|
// Read barcodes directly from native ML Kit results
|
|
2131
2173
|
let barcodes: Barcode[] = [];
|
|
2132
2174
|
if (frame.barcodes) {
|
package/src/version.ts
CHANGED