idmission-web-sdk 2.3.67 → 2.3.68

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 (45) hide show
  1. package/dist/components/common/InvisibleCanvas.d.ts +1 -0
  2. package/dist/components/common/InvisibleCanvas.d.ts.map +1 -1
  3. package/dist/components/id_capture/BarcodeReadabilityModelProvider.d.ts +29 -0
  4. package/dist/components/id_capture/BarcodeReadabilityModelProvider.d.ts.map +1 -0
  5. package/dist/components/id_capture/CapturedDocuments.d.ts +2 -1
  6. package/dist/components/id_capture/CapturedDocuments.d.ts.map +1 -1
  7. package/dist/components/id_capture/FocusModelProvider.d.ts.map +1 -1
  8. package/dist/components/id_capture/IdCapture.d.ts +1 -1
  9. package/dist/components/id_capture/IdCapture.d.ts.map +1 -1
  10. package/dist/components/id_capture/IdCaptureModelsProvider.d.ts +17 -1
  11. package/dist/components/id_capture/IdCaptureModelsProvider.d.ts.map +1 -1
  12. package/dist/components/id_capture/IdCaptureStateProvider.d.ts +7 -0
  13. package/dist/components/id_capture/IdCaptureStateProvider.d.ts.map +1 -1
  14. package/dist/components/id_capture/IdCaptureSuccess.d.ts.map +1 -1
  15. package/dist/components/id_capture/IdCaptureWizard.d.ts +1 -0
  16. package/dist/components/id_capture/IdCaptureWizard.d.ts.map +1 -1
  17. package/dist/components/submission/SubmissionProvider.d.ts +6 -0
  18. package/dist/components/submission/SubmissionProvider.d.ts.map +1 -1
  19. package/dist/components/submission/types.d.ts +2 -0
  20. package/dist/components/submission/types.d.ts.map +1 -1
  21. package/dist/lib/models/BarcodeReadability.d.ts +50 -0
  22. package/dist/lib/models/BarcodeReadability.d.ts.map +1 -0
  23. package/dist/lib/models/DocumentDetection.d.ts +1 -0
  24. package/dist/lib/models/DocumentDetection.d.ts.map +1 -1
  25. package/dist/lib/models/Focus.d.ts.map +1 -1
  26. package/dist/lib/models/defaults/BarcodeReadability.d.ts +2 -0
  27. package/dist/lib/models/defaults/BarcodeReadability.d.ts.map +1 -0
  28. package/dist/lib/models/defaults/index.d.ts +7 -0
  29. package/dist/lib/models/defaults/index.d.ts.map +1 -1
  30. package/dist/lib/models/preloadModels.d.ts +9 -5
  31. package/dist/lib/models/preloadModels.d.ts.map +1 -1
  32. package/dist/lib/utils/cropping.d.ts +3 -1
  33. package/dist/lib/utils/cropping.d.ts.map +1 -1
  34. package/dist/sdk2.cjs.development.js +1955 -1602
  35. package/dist/sdk2.cjs.development.js.map +1 -1
  36. package/dist/sdk2.cjs.production.js +1 -1
  37. package/dist/sdk2.cjs.production.js.map +1 -1
  38. package/dist/sdk2.esm.js +1956 -1603
  39. package/dist/sdk2.esm.js.map +1 -1
  40. package/dist/sdk2.umd.development.js +1608 -1255
  41. package/dist/sdk2.umd.development.js.map +1 -1
  42. package/dist/sdk2.umd.production.js +1 -1
  43. package/dist/sdk2.umd.production.js.map +1 -1
  44. package/dist/version.d.ts +1 -1
  45. package/package.json +1 -1
@@ -211,7 +211,7 @@
211
211
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
212
212
  };
213
213
 
214
- var webSdkVersion = '2.3.67';
214
+ var webSdkVersion = '2.3.68';
215
215
 
216
216
  function getPlatform() {
217
217
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -472,27 +472,27 @@
472
472
  if (!portalLocation) return element;
473
473
  return /*#__PURE__*/reactDom.createPortal(element, portalLocation);
474
474
  };
475
- var GuidanceMessage = styled.div(templateObject_2$I || (templateObject_2$I = __makeTemplateObject(["\n margin-left: auto;\n margin-right: auto;\n background: ", ";\n color: ", ";\n border-radius: 8px;\n z-index: 10001;\n padding: 16px 24px;\n font-size: 18px;\n font-weight: bold;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n"], ["\n margin-left: auto;\n margin-right: auto;\n background: ", ";\n color: ", ";\n border-radius: 8px;\n z-index: 10001;\n padding: 16px 24px;\n font-size: 18px;\n font-weight: bold;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n"])), function (props) {
475
+ var GuidanceMessage = styled.div(templateObject_2$J || (templateObject_2$J = __makeTemplateObject(["\n margin-left: auto;\n margin-right: auto;\n background: ", ";\n color: ", ";\n border-radius: 8px;\n z-index: 10001;\n padding: 16px 24px;\n font-size: 18px;\n font-weight: bold;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n"], ["\n margin-left: auto;\n margin-right: auto;\n background: ", ";\n color: ", ";\n border-radius: 8px;\n z-index: 10001;\n padding: 16px 24px;\n font-size: 18px;\n font-weight: bold;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n"])), function (props) {
476
476
  var _a, _b, _c, _d, _e, _f;
477
477
  return (_f = (_a = props.$background) !== null && _a !== void 0 ? _a : (_e = (_c = (_b = props.theme) === null || _b === void 0 ? void 0 : _b.guidanceMessages) === null || _c === void 0 ? void 0 : _c[(_d = props.$variant) !== null && _d !== void 0 ? _d : 'default']) === null || _e === void 0 ? void 0 : _e.backgroundColor) !== null && _f !== void 0 ? _f : 'white';
478
478
  }, function (props) {
479
479
  var _a, _b, _c, _d, _e, _f;
480
480
  return (_f = (_a = props.$textColor) !== null && _a !== void 0 ? _a : (_e = (_c = (_b = props.theme) === null || _b === void 0 ? void 0 : _b.guidanceMessages) === null || _c === void 0 ? void 0 : _c[(_d = props.$variant) !== null && _d !== void 0 ? _d : 'default']) === null || _e === void 0 ? void 0 : _e.textColor) !== null && _f !== void 0 ? _f : 'black';
481
481
  });
482
- var templateObject_1$Q, templateObject_2$I;
482
+ var templateObject_1$Q, templateObject_2$J;
483
483
 
484
484
  var wavesAnimation = styled.keyframes(templateObject_1$P || (templateObject_1$P = __makeTemplateObject(["\n 0% {\n opacity: 0;\n transform: scale3d(1, 1, 1);\n }\n 80% {\n opacity: 1;\n }\n 100% {\n transform: scale3d(2, 2, 1);\n opacity: 0;\n }\n"], ["\n 0% {\n opacity: 0;\n transform: scale3d(1, 1, 1);\n }\n 80% {\n opacity: 1;\n }\n 100% {\n transform: scale3d(2, 2, 1);\n opacity: 0;\n }\n"])));
485
- var progressBarAnimation = styled.keyframes(templateObject_2$H || (templateObject_2$H = __makeTemplateObject(["\n 0% {\n width: 0;\n }\n 100% {\n width: 100%;\n }\n"], ["\n 0% {\n width: 0;\n }\n 100% {\n width: 100%;\n }\n"])));
485
+ var progressBarAnimation = styled.keyframes(templateObject_2$I || (templateObject_2$I = __makeTemplateObject(["\n 0% {\n width: 0;\n }\n 100% {\n width: 100%;\n }\n"], ["\n 0% {\n width: 0;\n }\n 100% {\n width: 100%;\n }\n"])));
486
486
  var dualRingSpinnerAnimation = styled.keyframes(templateObject_3$u || (templateObject_3$u = __makeTemplateObject(["\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n"], ["\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n"])));
487
487
  var progressBorderAnimation = styled.keyframes(templateObject_4$n || (templateObject_4$n = __makeTemplateObject(["\n to {\n stroke-dashoffset: 0;\n }\n"], ["\n to {\n stroke-dashoffset: 0;\n }\n"])));
488
- var templateObject_1$P, templateObject_2$H, templateObject_3$u, templateObject_4$n;
488
+ var templateObject_1$P, templateObject_2$I, templateObject_3$u, templateObject_4$n;
489
489
 
490
490
  var OverlayContainer = styled.div(templateObject_1$O || (templateObject_1$O = __makeTemplateObject(["\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n\n display: flex;\n flex-direction: column;\n\n overflow-x: hidden;\n overflow-y: auto;\n\n background: ", ";\n ", "\n\n z-index: 10000;\n"], ["\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n\n display: flex;\n flex-direction: column;\n\n overflow-x: hidden;\n overflow-y: auto;\n\n background: ", ";\n ", "\n\n z-index: 10000;\n"])), function (props) {
491
491
  return props.theme.background ? "".concat(props.theme.background) : "white";
492
492
  }, function (props) {
493
493
  return props.theme.textColor ? "color: ".concat(props.theme.textColor, ";") : "";
494
494
  });
495
- var OverlayInner$2 = styled.div(templateObject_2$G || (templateObject_2$G = __makeTemplateObject(["\n text-align: ", ";\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n width: 100%;\n height: 100%;\n ", "\n"], ["\n text-align: ", ";\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n width: 100%;\n height: 100%;\n ", "\n"])), function (props) {
495
+ var OverlayInner$2 = styled.div(templateObject_2$H || (templateObject_2$H = __makeTemplateObject(["\n text-align: ", ";\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n width: 100%;\n height: 100%;\n ", "\n"], ["\n text-align: ", ";\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n width: 100%;\n height: 100%;\n ", "\n"])), function (props) {
496
496
  var _a;
497
497
  return (_a = props.theme.textAlign) !== null && _a !== void 0 ? _a : 'center';
498
498
  }, function (props) {
@@ -540,7 +540,7 @@
540
540
  var LoadingOverlayProgressContainer = styled.div(templateObject_20 || (templateObject_20 = __makeTemplateObject(["\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n"], ["\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n"])));
541
541
  var LoadingOverlayCustomLoadingGraphic = styled.img(templateObject_21 || (templateObject_21 = __makeTemplateObject(["\n transform-style: preserve-3d;\n"], ["\n transform-style: preserve-3d;\n"])));
542
542
  var LoadingOverlayContinueButtonContainer = styled.div(templateObject_22 || (templateObject_22 = __makeTemplateObject(["\n display: flex;\n"], ["\n display: flex;\n"])));
543
- var templateObject_1$O, templateObject_2$G, templateObject_3$t, templateObject_4$m, templateObject_5$e, templateObject_6$9, templateObject_7$5, templateObject_8$4, templateObject_9$2, templateObject_10$1, templateObject_11$1, templateObject_12$1, templateObject_13$1, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21, templateObject_22;
543
+ var templateObject_1$O, templateObject_2$H, templateObject_3$t, templateObject_4$m, templateObject_5$e, templateObject_6$9, templateObject_7$5, templateObject_8$4, templateObject_9$2, templateObject_10$1, templateObject_11$1, templateObject_12$1, templateObject_13$1, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21, templateObject_22;
544
544
 
545
545
  function _extends() {
546
546
  return _extends = Object.assign ? Object.assign.bind() : function (n) {
@@ -2083,6 +2083,11 @@
2083
2083
  idFrontImage: null,
2084
2084
  idBackImage: null,
2085
2085
  passportImage: null,
2086
+ idFrontIrImage: null,
2087
+ idBackIrImage: null,
2088
+ idFrontUvImage: null,
2089
+ idBackUvImage: null,
2090
+ idBarcodeImage: null,
2086
2091
  selfieImage: null,
2087
2092
  signatureData: null,
2088
2093
  signatureVideoUrl: null,
@@ -2113,6 +2118,9 @@
2113
2118
  setIdBackUvImage: function setIdBackUvImage() {
2114
2119
  return null;
2115
2120
  },
2121
+ setIdBarcodeImage: function setIdBarcodeImage() {
2122
+ return null;
2123
+ },
2116
2124
  setSelfieImage: function setSelfieImage() {
2117
2125
  return null;
2118
2126
  },
@@ -2280,53 +2288,56 @@
2280
2288
  passportImage = _13[0],
2281
2289
  setPassportImage = _13[1];
2282
2290
  var _14 = React.useState(null),
2283
- selfieImage = _14[0],
2284
- setSelfieImage = _14[1];
2291
+ idBarcodeImage = _14[0],
2292
+ setIdBarcodeImage = _14[1];
2285
2293
  var _15 = React.useState(null),
2286
- signatureData = _15[0],
2287
- setSignatureData = _15[1];
2294
+ selfieImage = _15[0],
2295
+ setSelfieImage = _15[1];
2288
2296
  var _16 = React.useState(null),
2289
- signatureVideoUrl = _16[0],
2290
- setSignatureVideoUrl = _16[1];
2297
+ signatureData = _16[0],
2298
+ setSignatureData = _16[1];
2291
2299
  var _17 = React.useState(null),
2292
- idCaptureVideoUrl = _17[0],
2293
- setIdCaptureVideoUrl = _17[1];
2300
+ signatureVideoUrl = _17[0],
2301
+ setSignatureVideoUrl = _17[1];
2294
2302
  var _18 = React.useState(null),
2295
- idCaptureVideoIdFrontImage = _18[0],
2296
- setIdCaptureVideoIdFrontImage = _18[1];
2303
+ idCaptureVideoUrl = _18[0],
2304
+ setIdCaptureVideoUrl = _18[1];
2297
2305
  var _19 = React.useState(null),
2298
- idCaptureVideoIdBackImage = _19[0],
2299
- setIdCaptureVideoIdBackImage = _19[1];
2306
+ idCaptureVideoIdFrontImage = _19[0],
2307
+ setIdCaptureVideoIdFrontImage = _19[1];
2300
2308
  var _20 = React.useState(null),
2301
- idCaptureVideoAudioUrl = _20[0],
2302
- setIdCaptureVideoAudioUrl = _20[1];
2309
+ idCaptureVideoIdBackImage = _20[0],
2310
+ setIdCaptureVideoIdBackImage = _20[1];
2303
2311
  var _21 = React.useState(null),
2304
- idCaptureVideoAudioStartsAt = _21[0],
2305
- setIdCaptureVideoAudioStartsAt = _21[1];
2312
+ idCaptureVideoAudioUrl = _21[0],
2313
+ setIdCaptureVideoAudioUrl = _21[1];
2306
2314
  var _22 = React.useState(null),
2307
- expectedAudioText = _22[0],
2308
- setExpectedAudioText = _22[1];
2315
+ idCaptureVideoAudioStartsAt = _22[0],
2316
+ setIdCaptureVideoAudioStartsAt = _22[1];
2309
2317
  var _23 = React.useState(null),
2310
- additionalDocuments = _23[0],
2311
- setAdditionalDocuments = _23[1];
2318
+ expectedAudioText = _23[0],
2319
+ setExpectedAudioText = _23[1];
2312
2320
  var _24 = React.useState(null),
2313
- geolocationResult = _24[0],
2314
- setGeolocationResult = _24[1];
2315
- var _25 = React.useState(0),
2316
- geolocationAttempts = _25[0],
2317
- setGeolocationAttempts = _25[1];
2318
- var _26 = React.useState(false),
2319
- geolocationBlocked = _26[0],
2320
- setGeolocationBlocked = _26[1];
2321
- var _27 = React.useState([]),
2322
- idFrontCaptureAttempts = _27[0],
2323
- setIdFrontCaptureAttempts = _27[1];
2321
+ additionalDocuments = _24[0],
2322
+ setAdditionalDocuments = _24[1];
2323
+ var _25 = React.useState(null),
2324
+ geolocationResult = _25[0],
2325
+ setGeolocationResult = _25[1];
2326
+ var _26 = React.useState(0),
2327
+ geolocationAttempts = _26[0],
2328
+ setGeolocationAttempts = _26[1];
2329
+ var _27 = React.useState(false),
2330
+ geolocationBlocked = _27[0],
2331
+ setGeolocationBlocked = _27[1];
2324
2332
  var _28 = React.useState([]),
2325
- idBackCaptureAttempts = _28[0],
2326
- setIdBackCaptureAttempts = _28[1];
2333
+ idFrontCaptureAttempts = _28[0],
2334
+ setIdFrontCaptureAttempts = _28[1];
2327
2335
  var _29 = React.useState([]),
2328
- selfieCaptureAttempts = _29[0],
2329
- setSelfieCaptureAttempts = _29[1];
2336
+ idBackCaptureAttempts = _29[0],
2337
+ setIdBackCaptureAttempts = _29[1];
2338
+ var _30 = React.useState([]),
2339
+ selfieCaptureAttempts = _30[0],
2340
+ setSelfieCaptureAttempts = _30[1];
2330
2341
  var logIdFrontCaptureAttempt = React.useCallback(function (attempt) {
2331
2342
  setIdFrontCaptureAttempts(function (attempts) {
2332
2343
  return __spreadArray(__spreadArray([], attempts, true), [attempt], false);
@@ -2452,6 +2463,7 @@
2452
2463
  idFrontImage: idFrontImage,
2453
2464
  idBackImage: idBackImage,
2454
2465
  passportImage: passportImage,
2466
+ idBarcodeImage: idBarcodeImage,
2455
2467
  selfieImage: selfieImage
2456
2468
  };
2457
2469
  _a = signatureVideoUrl;
@@ -2557,6 +2569,9 @@
2557
2569
  if (documents.passportImage) {
2558
2570
  submissionRequest.customerData.idData.idImageFront = documents.passportImage;
2559
2571
  }
2572
+ if (documents.idBarcodeImage) {
2573
+ submissionRequest.customerData.idData.idBarcodeImage = documents.idBarcodeImage;
2574
+ }
2560
2575
  if (documents.idFrontIrImage) {
2561
2576
  submissionRequest.customerData.idData.idFrontIrImage = documents.idFrontIrImage;
2562
2577
  }
@@ -2645,7 +2660,7 @@
2645
2660
  }
2646
2661
  });
2647
2662
  });
2648
- }, [additionalDocuments, bypassAgeValidation, bypassNameMatching, cardData, clientRequestID, companyId, customerDataMatchConfig, deduplicationEnabled, deduplicationSynchronous, documentServiceUrl, enrollmentId, expectedAudioText, geolocationResult, idBackCaptureAttempts, idBackImage, idBackImageRequired, idBackIrImage, idBackUvImage, idCaptureVideoAudioStartsAt, idCaptureVideoAudioUrl, idCaptureVideoIdBackImage, idCaptureVideoIdFrontImage, idCaptureVideoUrl, idCardForFaceMatch, idData, idFrontCaptureAttempts, idFrontImage, idFrontIrImage, idFrontUvImage, idImageResolutionCheck, jobId, manualReviewRequired, needImmediateResponse, passportImage, personalData, selfieCaptureAttempts, selfieImage, signatureData, signatureVideoUrl, uploadDocument, verifyIdWithExternalDatabases, webhooksClientTraceId, webhooksEnabled, webhooksFireOnReview, webhooksFireOnReviewURL, webhooksSendInputImages, webhooksSendProcessedImages, webhooksStripSpecialCharacters, webhooksURL]);
2663
+ }, [additionalDocuments, bypassAgeValidation, bypassNameMatching, cardData, clientRequestID, companyId, customerDataMatchConfig, deduplicationEnabled, deduplicationSynchronous, documentServiceUrl, enrollmentId, expectedAudioText, geolocationResult, idBackCaptureAttempts, idBackImage, idBackImageRequired, idBackIrImage, idBackUvImage, idBarcodeImage, idCaptureVideoAudioStartsAt, idCaptureVideoAudioUrl, idCaptureVideoIdBackImage, idCaptureVideoIdFrontImage, idCaptureVideoUrl, idCardForFaceMatch, idData, idFrontCaptureAttempts, idFrontImage, idFrontIrImage, idFrontUvImage, idImageResolutionCheck, jobId, manualReviewRequired, needImmediateResponse, passportImage, personalData, selfieCaptureAttempts, selfieImage, signatureData, signatureVideoUrl, uploadDocument, verifyIdWithExternalDatabases, webhooksClientTraceId, webhooksEnabled, webhooksFireOnReview, webhooksFireOnReviewURL, webhooksSendInputImages, webhooksSendProcessedImages, webhooksStripSpecialCharacters, webhooksURL]);
2649
2664
  var defaultOnSubmit = React.useCallback(function () {
2650
2665
  return __awaiter(void 0, void 0, void 0, function () {
2651
2666
  var submissionResponse_1, payload, host, endpoint, response, statusMessage, submissionResponse_2, e_1, err;
@@ -2923,6 +2938,7 @@
2923
2938
  idFrontUvImage: idFrontUvImage,
2924
2939
  idBackUvImage: idBackUvImage,
2925
2940
  passportImage: passportImage,
2941
+ idBarcodeImage: idBarcodeImage,
2926
2942
  selfieImage: selfieImage,
2927
2943
  signatureData: signatureData,
2928
2944
  signatureVideoUrl: signatureVideoUrl,
@@ -2939,6 +2955,7 @@
2939
2955
  setIdBackIrImage: setIdBackIrImage,
2940
2956
  setIdFrontUvImage: setIdFrontUvImage,
2941
2957
  setIdBackUvImage: setIdBackUvImage,
2958
+ setIdBarcodeImage: setIdBarcodeImage,
2942
2959
  setSelfieImage: setSelfieImage,
2943
2960
  setSignatureData: setSignatureData,
2944
2961
  setSignatureVideoUrl: setSignatureVideoUrl,
@@ -2957,7 +2974,7 @@
2957
2974
  checkLiveness: checkLiveness,
2958
2975
  retryLocationAccess: retryLocationAccess
2959
2976
  };
2960
- }, [additionalDocuments, checkLiveness, environment, idBackImage, idBackIrImage, idBackUvImage, idCaptureVideoAudioStartsAt, idCaptureVideoAudioUrl, idCaptureVideoIdBackImage, idCaptureVideoIdFrontImage, idCaptureVideoUrl, idFrontImage, idFrontIrImage, idFrontUvImage, livenessCheckRequest, logIdBackCaptureAttempt, logIdFrontCaptureAttempt, logSelfieCaptureAttempt, passportImage, retryLocationAccess, selfieImage, signatureData, signatureVideoUrl, submissionError, submissionRequest, submissionResponse, submissionStatus, submit, uploadDocument]);
2977
+ }, [additionalDocuments, checkLiveness, environment, idBackImage, idBackIrImage, idBackUvImage, idCaptureVideoAudioStartsAt, idCaptureVideoAudioUrl, idCaptureVideoIdBackImage, idCaptureVideoIdFrontImage, idCaptureVideoUrl, idFrontImage, idFrontIrImage, idFrontUvImage, livenessCheckRequest, logIdBackCaptureAttempt, logIdFrontCaptureAttempt, logSelfieCaptureAttempt, idBarcodeImage, passportImage, retryLocationAccess, selfieImage, signatureData, signatureVideoUrl, submissionError, submissionRequest, submissionResponse, submissionStatus, submit, uploadDocument]);
2961
2978
  return /*#__PURE__*/React.createElement(SubmissionContext.Provider, {
2962
2979
  value: value
2963
2980
  }, geolocationRequired && geolocationBlocked ? ( /*#__PURE__*/React.createElement(GeolocationAccessDeniedOverlay, null)) : children, submissionError && ( /*#__PURE__*/React.createElement(SubmissionErrorOverlay, {
@@ -8075,97 +8092,6 @@
8075
8092
  });
8076
8093
  }
8077
8094
 
8078
- function getFrameDimensions(frame) {
8079
- var frameWidth = frame.width,
8080
- frameHeight = frame.height;
8081
- if (frame instanceof HTMLImageElement) {
8082
- frameWidth = frame.naturalWidth;
8083
- frameHeight = frame.naturalHeight;
8084
- }
8085
- if (frame instanceof HTMLVideoElement) {
8086
- frameWidth = frame.videoWidth;
8087
- frameHeight = frame.videoHeight;
8088
- }
8089
- return [frameWidth, frameHeight];
8090
- }
8091
-
8092
- var InvisibleCanvas = styled.canvas(templateObject_1$N || (templateObject_1$N = __makeTemplateObject(["\n display: none;\n"], ["\n display: none;\n"])));
8093
- function drawToCanvas(canvas, frame, width, height) {
8094
- if (!canvas) return;
8095
- var ctx = canvas.getContext('2d');
8096
- if (!ctx) return;
8097
- if (!width || !height) {
8098
- var _a = getFrameDimensions(frame),
8099
- frameWidth = _a[0],
8100
- frameHeight = _a[1];
8101
- width || (width = frameWidth);
8102
- height || (height = frameHeight);
8103
- }
8104
- canvas.width = width;
8105
- canvas.height = height;
8106
- ctx.drawImage(frame, 0, 0, width, height);
8107
- }
8108
- function clearCanvas(canvas) {
8109
- var _a;
8110
- (_a = canvas === null || canvas === void 0 ? void 0 : canvas.getContext('2d')) === null || _a === void 0 ? void 0 : _a.clearRect(0, 0, canvas === null || canvas === void 0 ? void 0 : canvas.width, canvas === null || canvas === void 0 ? void 0 : canvas.height);
8111
- }
8112
- var templateObject_1$N;
8113
-
8114
- function cropToShoulders(rawCanvas, cropCanvas, resizeCanvas, frame, face, quality, maxHeight) {
8115
- var _a;
8116
- if (quality === void 0) {
8117
- quality = 0.92;
8118
- }
8119
- if (!rawCanvas || !cropCanvas || !resizeCanvas) return '';
8120
- var rawCtx = rawCanvas.getContext('2d');
8121
- var cropCtx = cropCanvas.getContext('2d');
8122
- var resizeCtx = resizeCanvas.getContext('2d');
8123
- if (!rawCtx || !cropCtx || !resizeCtx) throw new Error('could not get 2d context');
8124
- rawCanvas.width = frame.width;
8125
- rawCanvas.height = frame.height;
8126
- rawCtx.putImageData(frame, 0, 0);
8127
- if (frame.height > frame.width) {
8128
- cropCanvas.width = frame.width;
8129
- cropCanvas.height = frame.height;
8130
- cropCtx.drawImage(rawCanvas, 0, 0, cropCanvas.width, cropCanvas.height);
8131
- } else {
8132
- var _b = (_a = face === null || face === void 0 ? void 0 : face.box) !== null && _a !== void 0 ? _a : {
8133
- xMin: 0,
8134
- width: frame.width
8135
- },
8136
- xMin = _b.xMin,
8137
- width = _b.width;
8138
- var desiredWidth = frame.height * 0.6;
8139
- var faceCenterX = xMin + width / 2;
8140
- var xPos = Math.max(0, faceCenterX - desiredWidth / 2);
8141
- cropCanvas.width = desiredWidth;
8142
- cropCanvas.height = frame.height;
8143
- cropCtx.drawImage(rawCanvas, xPos, 0, cropCanvas.width, cropCanvas.height, 0, 0, cropCanvas.width, cropCanvas.height);
8144
- }
8145
- resizeCanvas.height = maxHeight !== null && maxHeight !== void 0 ? maxHeight : cropCanvas.height;
8146
- resizeCanvas.width = cropCanvas.width * (resizeCanvas.height / cropCanvas.height);
8147
- resizeCtx === null || resizeCtx === void 0 ? void 0 : resizeCtx.drawImage(cropCanvas, 0, 0, resizeCanvas.width, resizeCanvas.height);
8148
- var dataURL = resizeCanvas.toDataURL('image/jpeg', quality);
8149
- log('cropToShoulders size', new TextEncoder().encode(dataURL).length);
8150
- clearCanvas(rawCanvas);
8151
- clearCanvas(cropCanvas);
8152
- clearCanvas(resizeCanvas);
8153
- return dataURL;
8154
- }
8155
- function cropToDetectedObjectBox(frame, box, canvas) {
8156
- canvas || (canvas = document.createElement('canvas'));
8157
- var ctx = canvas.getContext('2d');
8158
- if (!ctx) throw new Error('could not get 2d context');
8159
- var xMin = box.xMin,
8160
- yMin = box.yMin,
8161
- width = box.width,
8162
- height = box.height;
8163
- canvas.width = width;
8164
- canvas.height = height;
8165
- ctx.drawImage(frame, xMin, yMin, width, height, 0, 0, width, height);
8166
- return canvas;
8167
- }
8168
-
8169
8095
  var defaultImageSegmenterModelPath = 'https://websdk-cdn-dev.idmission.com/assets/models/selfiesegmenter20240524/selfie_segmenter.tflite';
8170
8096
  var imageSegmenterModelSizeInBytes = 256440.32;
8171
8097
  // The idea here is that we globally set a cache key based on the time at page load. That way our built-in speed test
@@ -8295,6 +8221,192 @@
8295
8221
  });
8296
8222
  }
8297
8223
 
8224
+ var DEFAULT_CDN_URL = 'https://websdk-cdn-dev.idmission.com/assets';
8225
+
8226
+ var defaultDocumentDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/DocumentDetector/DocumentDetector-20250815_115859.tflite");
8227
+
8228
+ var defaultFocusModelPath = "".concat(DEFAULT_CDN_URL, "/models/Focus/Focus-20241008_102708.tflite");
8229
+
8230
+ var defaultFaceDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/blazeface20240207/blaze_face_short_range.tflite");
8231
+
8232
+ var defaultBarcodeReadabilityModelPath = "".concat(DEFAULT_CDN_URL, "/models/BarcodeReadability/BarcodeReadability-20250815_120417.tflite");
8233
+
8234
+ var defaultModelPaths = {
8235
+ documentDetector: defaultDocumentDetectorModelPath,
8236
+ focus: defaultFocusModelPath,
8237
+ faceDetection: defaultFaceDetectorModelPath,
8238
+ barcodeReadability: defaultBarcodeReadabilityModelPath
8239
+ };
8240
+
8241
+ var preloadModels = function preloadModels(_a) {
8242
+ return __awaiter(void 0, [_a], void 0, function (_b) {
8243
+ var preloadTasks;
8244
+ var _c = _b.documentDetectionModel,
8245
+ documentDetectionModel = _c === void 0 ? true : _c,
8246
+ _d = _b.focusModel,
8247
+ focusModel = _d === void 0 ? true : _d,
8248
+ _e = _b.faceDetectionModel,
8249
+ faceDetectionModel = _e === void 0 ? true : _e,
8250
+ _f = _b.barcodeReadabilityModel,
8251
+ barcodeReadabilityModel = _f === void 0 ? true : _f;
8252
+ return __generator(this, function (_g) {
8253
+ switch (_g.label) {
8254
+ case 0:
8255
+ return [4 /*yield*/, probeModelCapabilities()];
8256
+ case 1:
8257
+ _g.sent();
8258
+ preloadTasks = [];
8259
+ if (documentDetectionModel) {
8260
+ preloadTasks.push(preloadDocumentDetectorDependencies);
8261
+ }
8262
+ if (focusModel) {
8263
+ preloadTasks.push(preloadFocusModelDependencies);
8264
+ }
8265
+ if (faceDetectionModel) {
8266
+ preloadTasks.push(preloadFaceDetectorDependencies);
8267
+ }
8268
+ if (barcodeReadabilityModel) {
8269
+ preloadTasks.push(preloadBarcodeReadabilityModelDependencies);
8270
+ }
8271
+ return [4 /*yield*/, Promise.all(preloadTasks)];
8272
+ case 2:
8273
+ _g.sent();
8274
+ return [2 /*return*/];
8275
+ }
8276
+ });
8277
+ });
8278
+ };
8279
+ var progressByUrl = {};
8280
+ var progressByUseCase = {
8281
+ visionRuntime: {
8282
+ loaded: 0,
8283
+ total: 0
8284
+ },
8285
+ documentDetector: {
8286
+ loaded: 0,
8287
+ total: 0
8288
+ },
8289
+ focus: {
8290
+ loaded: 0,
8291
+ total: 0
8292
+ },
8293
+ faceDetection: {
8294
+ loaded: 0,
8295
+ total: 0
8296
+ },
8297
+ barcodeReadability: {
8298
+ loaded: 0,
8299
+ total: 0
8300
+ }
8301
+ };
8302
+ function preloadDependency(url) {
8303
+ return __awaiter(this, void 0, void 0, function () {
8304
+ return __generator(this, function (_a) {
8305
+ return [2 /*return*/, new Promise(function (resolve, reject) {
8306
+ var req = new XMLHttpRequest();
8307
+ req.addEventListener('progress', function (event) {
8308
+ if (!event.lengthComputable) return;
8309
+ progressByUrl[url] = event;
8310
+ document.dispatchEvent(new CustomEvent('idmission.preloadProgress', {
8311
+ detail: {
8312
+ url: url,
8313
+ loaded: event.loaded,
8314
+ total: event.total
8315
+ }
8316
+ }));
8317
+ });
8318
+ req.addEventListener('loadend', function () {
8319
+ resolve(req.readyState === 4 && req.status === 200);
8320
+ });
8321
+ req.addEventListener('error', reject);
8322
+ req.open('GET', url, true);
8323
+ req.send();
8324
+ })];
8325
+ });
8326
+ });
8327
+ }
8328
+ var modelsPreloading = {
8329
+ documentDetector: false,
8330
+ focus: false,
8331
+ faceDetection: false,
8332
+ barcodeReadability: false
8333
+ };
8334
+ var preloadDocumentDetectorDependencies = function preloadDocumentDetectorDependencies() {
8335
+ return preloadModelDependencies('documentDetector');
8336
+ };
8337
+ var preloadFocusModelDependencies = function preloadFocusModelDependencies() {
8338
+ return preloadModelDependencies('focus');
8339
+ };
8340
+ var preloadFaceDetectorDependencies = function preloadFaceDetectorDependencies() {
8341
+ return preloadModelDependencies('faceDetection');
8342
+ };
8343
+ var preloadBarcodeReadabilityModelDependencies = function preloadBarcodeReadabilityModelDependencies() {
8344
+ return preloadModelDependencies('barcodeReadability');
8345
+ };
8346
+ function preloadModelDependencies(model) {
8347
+ return __awaiter(this, void 0, void 0, function () {
8348
+ function handleModelDownloadProgress(event) {
8349
+ var detail = event.detail;
8350
+ if (!dependencies.includes(detail.url)) return;
8351
+ progressByUseCase[model] = sumUpProgressForDependencies(dependencies);
8352
+ document.dispatchEvent(new CustomEvent("idmission.preloadProgress.".concat(model), {
8353
+ detail: progressByUseCase[model]
8354
+ }));
8355
+ }
8356
+ var dependencies;
8357
+ return __generator(this, function (_a) {
8358
+ switch (_a.label) {
8359
+ case 0:
8360
+ if (modelsPreloading[model]) return [2 /*return*/, new Promise(function (resolve) {
8361
+ var i = setInterval(function () {
8362
+ if (!modelsPreloading[model]) {
8363
+ clearInterval(i);
8364
+ resolve();
8365
+ }
8366
+ }, 100);
8367
+ })];
8368
+ modelsPreloading[model] = true;
8369
+ return [4 /*yield*/, probeModelCapabilities()];
8370
+ case 1:
8371
+ _a.sent();
8372
+ if (modelCapabilities.delegate === 'NONE') {
8373
+ throw new Error("No available delegate for ".concat(model, " model."));
8374
+ }
8375
+ dependencies = [defaultModelPaths[model]];
8376
+ document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
8377
+ _a.label = 2;
8378
+ case 2:
8379
+ _a.trys.push([2,, 4, 5]);
8380
+ return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
8381
+ case 3:
8382
+ _a.sent();
8383
+ return [3 /*break*/, 5];
8384
+ case 4:
8385
+ document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
8386
+ modelsPreloading[model] = false;
8387
+ return [7 /*endfinally*/];
8388
+ case 5:
8389
+ return [2 /*return*/];
8390
+ }
8391
+ });
8392
+ });
8393
+ }
8394
+ function progressToPercentage(progress) {
8395
+ return progress.total > 0 ? Math.round(100.0 * progress.loaded / progress.total) : 0;
8396
+ }
8397
+ function sumUpProgressForDependencies(dependencies) {
8398
+ return dependencies.reduce(function (result, dependency) {
8399
+ var dependencyProgress = progressByUrl[dependency];
8400
+ if (!dependencyProgress) return result;
8401
+ result.loaded += dependencyProgress.loaded;
8402
+ result.total += dependencyProgress.total;
8403
+ return result;
8404
+ }, {
8405
+ loaded: 0,
8406
+ total: 0
8407
+ });
8408
+ }
8409
+
8298
8410
  function convertBoundingBox(box) {
8299
8411
  var _a, _b, _c, _d, _e, _f, _g, _h;
8300
8412
  return {
@@ -8349,53 +8461,50 @@
8349
8461
  return sum / len;
8350
8462
  }
8351
8463
 
8352
- var DEFAULT_CDN_URL = 'https://websdk-cdn-dev.idmission.com/assets';
8353
-
8354
- var defaultDocumentDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/DocumentDetector/DocumentDetector-20250815_115859.tflite");
8355
-
8356
- var defaultFocusModelPath = "".concat(DEFAULT_CDN_URL, "/models/Focus/Focus-20241008_102708.tflite");
8357
-
8358
- var defaultFaceDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/blazeface20240207/blaze_face_short_range.tflite");
8359
-
8360
- var defaultFocusModelLoadTimeoutMs = 45000;
8361
- var defaultFocusThresholds = {
8362
- idCardFront: {
8363
- desktop: 0,
8364
- mobile: 0.3
8365
- },
8366
- idCardBack: {
8367
- desktop: 0,
8368
- mobile: 0.3
8369
- },
8370
- passport: {
8371
- desktop: 0,
8372
- mobile: 0.3
8373
- },
8374
- singlePage: {
8375
- desktop: 0,
8376
- mobile: 0.3
8464
+ var defaultDocumentDetectionScoreThreshold = 0.1;
8465
+ var defaultDocumentDetectionModelLoadTimeoutMs = 45000;
8466
+ var defaultDocumentDetectionThresholds = {
8467
+ idCardFront: 0.6,
8468
+ idCardBack: 0.6,
8469
+ passport: 0.4,
8470
+ singlePage: 0.4,
8471
+ stability: {
8472
+ idCardFront: 0.85,
8473
+ idCardBack: 0.85,
8474
+ passport: 0.5,
8475
+ singlePage: 0.5
8377
8476
  }
8378
8477
  };
8379
- var classifier = null;
8380
- var classifierSettings = null;
8381
- function loadFocusModel() {
8382
- return __awaiter(this, arguments, void 0, function (modelAssetPath) {
8478
+ var documentTypeDisplayNames = {
8479
+ idCardFront: 'ID card front',
8480
+ idCardBack: 'ID card back',
8481
+ passport: 'Passport',
8482
+ singlePage: 'Single page',
8483
+ none: 'None'
8484
+ };
8485
+ var detector$1 = null;
8486
+ var detectorSettings$1 = null;
8487
+ function loadDocumentDetector() {
8488
+ return __awaiter(this, arguments, void 0, function (modelAssetPath, scoreThreshold) {
8383
8489
  var _a, _b;
8384
8490
  if (modelAssetPath === void 0) {
8385
- modelAssetPath = defaultFocusModelPath;
8491
+ modelAssetPath = defaultDocumentDetectorModelPath;
8492
+ }
8493
+ if (scoreThreshold === void 0) {
8494
+ scoreThreshold = defaultDocumentDetectionScoreThreshold;
8386
8495
  }
8387
8496
  return __generator(this, function (_c) {
8388
8497
  switch (_c.label) {
8389
8498
  case 0:
8390
- if (classifier && (classifierSettings === null || classifierSettings === void 0 ? void 0 : classifierSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier];
8391
- closeFocusModel();
8392
- return [4 /*yield*/, preloadFocusModelDependencies()];
8499
+ if (detector$1 && (detectorSettings$1 === null || detectorSettings$1 === void 0 ? void 0 : detectorSettings$1.modelAssetPath) === modelAssetPath && (detectorSettings$1 === null || detectorSettings$1 === void 0 ? void 0 : detectorSettings$1.scoreThreshold) === scoreThreshold) return [2 /*return*/, detector$1];
8500
+ closeDocumentDetector();
8501
+ return [4 /*yield*/, preloadDocumentDetectorDependencies()];
8393
8502
  case 1:
8394
8503
  _c.sent();
8395
8504
  if (modelCapabilities.delegate === 'NONE') {
8396
- throw new Error('No available delegate for focus detector.');
8505
+ throw new Error('No available delegate for document detector.');
8397
8506
  }
8398
- _b = (_a = Ua).createFromOptions;
8507
+ _b = (_a = lh).createFromOptions;
8399
8508
  return [4 /*yield*/, ao.forVisionTasks(visionTasksBasePath)];
8400
8509
  case 2:
8401
8510
  return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
@@ -8404,44 +8513,48 @@
8404
8513
  delegate: modelCapabilities.delegate
8405
8514
  },
8406
8515
  // canvas: document.createElement('canvas'),
8516
+ scoreThreshold: scoreThreshold,
8407
8517
  runningMode: 'VIDEO'
8408
8518
  }])];
8409
8519
  case 3:
8410
- classifier = _c.sent();
8411
- classifierSettings = {
8412
- modelAssetPath: modelAssetPath
8520
+ detector$1 = _c.sent();
8521
+ detectorSettings$1 = {
8522
+ modelAssetPath: modelAssetPath,
8523
+ scoreThreshold: scoreThreshold
8413
8524
  };
8414
- return [2 /*return*/, classifier];
8525
+ return [2 /*return*/, detector$1];
8415
8526
  }
8416
8527
  });
8417
8528
  });
8418
8529
  }
8419
- function closeFocusModel() {
8420
- classifier === null || classifier === void 0 ? void 0 : classifier.close();
8421
- classifier = null;
8422
- classifierSettings = null;
8530
+ function closeDocumentDetector() {
8531
+ detector$1 === null || detector$1 === void 0 ? void 0 : detector$1.close();
8532
+ detector$1 = null;
8533
+ detectorSettings$1 = null;
8423
8534
  }
8424
- function useLoadFocusModel(_a) {
8425
- var _b = _a.modelPath,
8426
- modelPath = _b === void 0 ? defaultFocusModelPath : _b,
8427
- _c = _a.modelLoadTimeoutMs,
8428
- modelLoadTimeoutMs = _c === void 0 ? defaultFocusModelLoadTimeoutMs : _c,
8535
+ function useLoadDocumentDetector(_a) {
8536
+ var _b = _a.shouldLoadModels,
8537
+ shouldLoadModels = _b === void 0 ? true : _b,
8538
+ _c = _a.modelPath,
8539
+ modelPath = _c === void 0 ? defaultDocumentDetectorModelPath : _c,
8540
+ _d = _a.modelLoadTimeoutMs,
8541
+ modelLoadTimeoutMs = _d === void 0 ? defaultDocumentDetectionModelLoadTimeoutMs : _d,
8542
+ _e = _a.scoreThreshold,
8543
+ scoreThreshold = _e === void 0 ? defaultDocumentDetectionScoreThreshold : _e,
8429
8544
  onModelError = _a.onModelError,
8430
- videoRef = _a.videoRef,
8431
- _d = _a.shouldLoadModels,
8432
- shouldLoadModels = _d === void 0 ? true : _d;
8433
- var _e = React.useState('not-started'),
8434
- modelLoadState = _e[0],
8435
- setModelLoadState = _e[1];
8436
- var _f = React.useState(0),
8437
- modelDownloadProgress = _f[0],
8438
- setModelDownloadProgress = _f[1];
8545
+ videoRef = _a.videoRef;
8546
+ var _f = React.useState('not-started'),
8547
+ modelLoadState = _f[0],
8548
+ setModelLoadState = _f[1];
8439
8549
  var _g = React.useState(null),
8440
8550
  modelWarmingStartedAt = _g[0],
8441
8551
  setModelWarmingStartedAt = _g[1];
8442
- var _h = React.useState(null),
8443
- modelError = _h[0],
8444
- setModelError = _h[1];
8552
+ var _h = React.useState(0),
8553
+ modelDownloadProgress = _h[0],
8554
+ setModelDownloadProgress = _h[1];
8555
+ var _j = React.useState(null),
8556
+ modelError = _j[0],
8557
+ setModelError = _j[1];
8445
8558
  React.useEffect(function loadModel() {
8446
8559
  var _this = this;
8447
8560
  if (!shouldLoadModels) return;
@@ -8450,21 +8563,24 @@
8450
8563
  function handleDownloadProgress(event) {
8451
8564
  setModelDownloadProgress(progressToPercentage(event.detail));
8452
8565
  }
8453
- document.addEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
8566
+ document.addEventListener('idmission.preloadProgress.documentDetector', handleDownloadProgress);
8454
8567
  var modelLoadTimeout = setTimeout(function () {
8455
8568
  setModelError(new Error('Model loading time limit exceeded.'));
8456
8569
  }, modelLoadTimeoutMs);
8457
8570
  var cancelVideoReady = function cancelVideoReady() {};
8458
- loadFocusModel(modelPath).then(function (loadedModel) {
8571
+ loadDocumentDetector(modelPath, scoreThreshold).then(function (model) {
8459
8572
  return __awaiter(_this, void 0, void 0, function () {
8460
8573
  var _a, videoReady, cancel, cancelled;
8461
8574
  return __generator(this, function (_b) {
8462
8575
  switch (_b.label) {
8463
8576
  case 0:
8464
8577
  setModelDownloadProgress(100);
8465
- clearTimeout(modelLoadTimeout);
8466
8578
  setModelLoadState('warming');
8467
- setModelWarmingStartedAt(new Date().getTime());
8579
+ setModelWarmingStartedAt(performance.now());
8580
+ clearTimeout(modelLoadTimeout);
8581
+ return [4 /*yield*/, testDocumentDetectionAgainstKnownImage(model)];
8582
+ case 1:
8583
+ _b.sent();
8468
8584
  _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
8469
8585
  cancelled = false;
8470
8586
  cancelVideoReady = function cancelVideoReady() {
@@ -8472,11 +8588,11 @@
8472
8588
  cancel();
8473
8589
  };
8474
8590
  return [4 /*yield*/, videoReady];
8475
- case 1:
8591
+ case 2:
8476
8592
  _b.sent();
8477
8593
  setTimeout(function () {
8478
8594
  if (cancelled) return;
8479
- loadedModel.classifyForVideo(videoRef.current, performance.now());
8595
+ model.detectForVideo(videoRef.current, performance.now());
8480
8596
  setModelLoadState('ready');
8481
8597
  }, 500);
8482
8598
  return [2 /*return*/];
@@ -8490,13 +8606,13 @@
8490
8606
  clearTimeout(modelLoadTimeout);
8491
8607
  });
8492
8608
  return function () {
8493
- log('unloading focus model');
8609
+ log('unloading document detection model');
8494
8610
  cancelVideoReady();
8495
- closeFocusModel();
8611
+ closeDocumentDetector();
8496
8612
  clearTimeout(modelLoadTimeout);
8497
- document.removeEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
8613
+ document.removeEventListener('idmission.preloadProgress.documentDetector', handleDownloadProgress);
8498
8614
  };
8499
- }, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
8615
+ }, [shouldLoadModels, modelLoadTimeoutMs, modelPath, scoreThreshold, videoRef]);
8500
8616
  React.useEffect(function handleModelError() {
8501
8617
  if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
8502
8618
  }, [modelError, onModelError]);
@@ -8506,185 +8622,41 @@
8506
8622
  modelLoadState: modelLoadState,
8507
8623
  modelDownloadProgress: modelDownloadProgress,
8508
8624
  modelWarmingStartedAt: modelWarmingStartedAt,
8509
- modelError: modelError
8625
+ modelError: modelError,
8626
+ setModelError: setModelError
8510
8627
  };
8511
8628
  }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
8512
8629
  }
8513
- var lastFocusPredictionAt = 0;
8514
- var lastFocusPredictionTime = 0;
8515
- function setLastFocusPredictionAt(time) {
8516
- lastFocusPredictionTime = time - lastFocusPredictionAt;
8517
- lastFocusPredictionAt = time;
8518
- }
8519
- function makeFocusModelPrediction(imageData, cropCanvas, rotateCanvas, box) {
8520
- var _a, _b, _c, _d, _e;
8521
- if (!classifier) return null;
8522
- var startedAt = new Date();
8523
- var image = cropIfNecessary(imageData, cropCanvas, rotateCanvas, box);
8524
- var result = classifier.classifyForVideo(image, performance.now());
8525
- var score = (_e = (_d = (_c = (_b = (_a = result === null || result === void 0 ? void 0 : result.classifications) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.categories) === null || _c === void 0 ? void 0 : _c.find(function (c) {
8526
- return c.categoryName === 'focused';
8527
- })) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
8528
- var predictionTime = new Date().getTime() - startedAt.getTime();
8529
- return {
8530
- score: score,
8531
- predictionTime: predictionTime
8532
- };
8533
- }
8534
- function cropIfNecessary(imageData, cropCanvas, rotateCanvas, box) {
8535
- if (!box) return imageData;
8536
- var cropped = cropToDetectedObjectBox(imageData, box, cropCanvas);
8537
- var _a = [box.width, box.height],
8538
- bw = _a[0],
8539
- bh = _a[1];
8540
- if (bh <= bw) return cropped;
8541
- var ctx = rotateCanvas.getContext('2d');
8542
- if (!ctx) return cropped;
8543
- rotateCanvas.width = bh;
8544
- rotateCanvas.height = bw;
8545
- ctx.clearRect(0, 0, rotateCanvas.width, rotateCanvas.height);
8546
- ctx.translate(rotateCanvas.width / 2, rotateCanvas.height / 2);
8547
- ctx.rotate(1.5708); // 90 deg in radians
8548
- ctx.drawImage(cropped, -bw / 2, -bh / 2);
8549
- return rotateCanvas;
8550
- }
8551
-
8552
- var defaultSelfieCaptureModelLoadTimeoutMs = 45000;
8553
- var detector$1 = null;
8554
- var detectorSettings$1 = null;
8555
- function loadFaceDetector() {
8556
- return __awaiter(this, arguments, void 0, function (modelAssetPath) {
8557
- var _a, _b;
8558
- if (modelAssetPath === void 0) {
8559
- modelAssetPath = defaultFaceDetectorModelPath;
8560
- }
8561
- return __generator(this, function (_c) {
8562
- switch (_c.label) {
8563
- case 0:
8564
- if (detector$1 && (detectorSettings$1 === null || detectorSettings$1 === void 0 ? void 0 : detectorSettings$1.modelAssetPath) === modelAssetPath) return [2 /*return*/, detector$1];
8565
- closeFaceDetector();
8566
- return [4 /*yield*/, preloadFaceDetectorDependencies()];
8567
- case 1:
8568
- _c.sent();
8569
- if (modelCapabilities.delegate === 'NONE') {
8570
- throw new Error('No available delegate for face detector.');
8571
- }
8572
- _b = (_a = ya).createFromOptions;
8573
- return [4 /*yield*/, ao.forVisionTasks(visionTasksBasePath)];
8574
- case 2:
8575
- return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
8576
- // canvas: document.createElement('canvas'),
8577
- baseOptions: {
8578
- modelAssetPath: modelAssetPath,
8579
- delegate: modelCapabilities.delegate
8580
- },
8581
- runningMode: 'VIDEO'
8582
- }])];
8583
- case 3:
8584
- detector$1 = _c.sent();
8585
- detectorSettings$1 = {
8586
- modelAssetPath: modelAssetPath
8587
- };
8588
- return [2 /*return*/, detector$1];
8630
+ function makeDocumentDetectorPrediction(frame) {
8631
+ return __awaiter(this, void 0, void 0, function () {
8632
+ var startedAt, prediction, time, frameWidth, frameHeight;
8633
+ return __generator(this, function (_a) {
8634
+ if (!detector$1) return [2 /*return*/, null];
8635
+ startedAt = performance.now();
8636
+ // Detectors can throw errors, for example when using custom URLs that
8637
+ // contain a model that doesn't provide the expected output.
8638
+ try {
8639
+ prediction = detector$1.detectForVideo(frame, performance.now());
8640
+ time = performance.now() - startedAt;
8641
+ frameWidth = frame.width;
8642
+ frameHeight = frame.height;
8643
+ return [2 /*return*/, _assign(_assign({}, prediction), {
8644
+ time: time,
8645
+ frameWidth: frameWidth,
8646
+ frameHeight: frameHeight
8647
+ })];
8648
+ } catch (e) {
8649
+ error('caught object detection error', e);
8589
8650
  }
8651
+ return [2 /*return*/, null];
8590
8652
  });
8591
8653
  });
8592
8654
  }
8593
- function closeFaceDetector() {
8594
- detector$1 === null || detector$1 === void 0 ? void 0 : detector$1.close();
8595
- detector$1 = null;
8596
- detectorSettings$1 = null;
8597
- }
8598
- function useLoadFaceDetector(_a) {
8599
- var onModelError = _a.onModelError,
8600
- _b = _a.modelLoadTimeoutMs,
8601
- modelLoadTimeoutMs = _b === void 0 ? defaultSelfieCaptureModelLoadTimeoutMs : _b,
8602
- videoRef = _a.videoRef;
8603
- var _c = React.useState('not-started'),
8604
- modelLoadState = _c[0],
8605
- setModelLoadState = _c[1];
8606
- var _d = React.useState(0),
8607
- modelDownloadProgress = _d[0],
8608
- setModelDownloadProgress = _d[1];
8609
- var _e = React.useState(null),
8610
- modelWarmingStartedAt = _e[0],
8611
- setModelWarmingStartedAt = _e[1];
8612
- var _f = React.useState(null),
8613
- modelError = _f[0],
8614
- setModelError = _f[1];
8615
- React.useEffect(function loadModel() {
8616
- var _this = this;
8617
- setModelLoadState('downloading');
8618
- setModelWarmingStartedAt(null);
8619
- var modelLoadTimeout = setTimeout(function () {
8620
- setModelError(new Error('Model loading time limit exceeded.'));
8621
- }, modelLoadTimeoutMs);
8622
- function handleDownloadProgress(event) {
8623
- setModelDownloadProgress(progressToPercentage(event.detail));
8624
- }
8625
- document.addEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
8626
- var cancelVideoReady = function cancelVideoReady() {};
8627
- loadFaceDetector().then(function (model) {
8628
- return __awaiter(_this, void 0, void 0, function () {
8629
- var _a, videoReady, cancel, cancelled;
8630
- return __generator(this, function (_b) {
8631
- switch (_b.label) {
8632
- case 0:
8633
- setModelDownloadProgress(100);
8634
- clearTimeout(modelLoadTimeout);
8635
- setModelLoadState('warming');
8636
- setModelWarmingStartedAt(new Date().getTime());
8637
- return [4 /*yield*/, testFaceDetectionAgainstKnownImage(model)];
8638
- case 1:
8639
- _b.sent();
8640
- _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
8641
- cancelled = false;
8642
- cancelVideoReady = function cancelVideoReady() {
8643
- cancelled = true;
8644
- cancel();
8645
- };
8646
- return [4 /*yield*/, videoReady];
8647
- case 2:
8648
- _b.sent();
8649
- if (cancelled) return [2 /*return*/];
8650
- model.detectForVideo(videoRef.current, performance.now());
8651
- setModelLoadState('ready');
8652
- return [2 /*return*/];
8653
- }
8654
- });
8655
- });
8656
- })["catch"](function (e) {
8657
- setModelError(e);
8658
- setModelLoadState('error');
8659
- })["finally"](function () {
8660
- clearTimeout(modelLoadTimeout);
8661
- });
8662
- return function () {
8663
- log('unloading face detection model');
8664
- cancelVideoReady();
8665
- closeFaceDetector();
8666
- clearTimeout(modelLoadTimeout);
8667
- document.removeEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
8668
- };
8669
- }, [modelLoadTimeoutMs, videoRef]);
8670
- React.useEffect(function handleModelError() {
8671
- if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
8672
- }, [modelError, onModelError]);
8673
- return React.useMemo(function () {
8674
- return {
8675
- ready: modelLoadState === 'ready',
8676
- modelLoadState: modelLoadState,
8677
- modelDownloadProgress: modelDownloadProgress,
8678
- modelWarmingStartedAt: modelWarmingStartedAt,
8679
- modelError: modelError
8680
- };
8681
- }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
8682
- }
8683
- var lastFaceDetectionAt = 0;
8684
- var lastFaceDetectionTime = 0;
8685
- function setLastFaceDetectionAt(time) {
8686
- lastFaceDetectionTime = time - lastFaceDetectionAt;
8687
- lastFaceDetectionAt = time;
8655
+ var lastDetectionAt = 0;
8656
+ var lastDetectionTime = 0;
8657
+ function setLastDetectionAt(time) {
8658
+ lastDetectionTime = time - lastDetectionAt;
8659
+ lastDetectionAt = time;
8688
8660
  }
8689
8661
  var framesNeededSamples$1 = [];
8690
8662
  function trackFramesNeeded$1(value, bufferLength) {
@@ -8694,818 +8666,293 @@
8694
8666
  framesNeededSamples$1.unshift(value);
8695
8667
  if (framesNeededSamples$1.length > bufferLength) framesNeededSamples$1.length = bufferLength;
8696
8668
  }
8697
- var lastNFaces = [];
8669
+ var lastNBoxes = [];
8698
8670
  var lastNPairs$1 = [];
8699
- function trackFace(face, framesNeeded) {
8671
+ function trackBox(box, framesNeeded) {
8700
8672
  if (framesNeeded === void 0) {
8701
8673
  framesNeeded = 12;
8702
8674
  }
8703
- lastNFaces.unshift(face);
8704
- if (lastNFaces.length > framesNeeded) lastNFaces.length = framesNeeded;
8705
- if (lastNFaces.length > 1) {
8706
- var lastFace = lastNFaces[1];
8707
- var iou = calculateIoU(face.box, lastFace.box);
8675
+ lastNBoxes.unshift(box);
8676
+ if (lastNBoxes.length > framesNeeded) lastNBoxes.length = framesNeeded;
8677
+ if (lastNBoxes.length > 1) {
8678
+ var lastBox = lastNBoxes[1];
8679
+ var iou = calculateIoU(box, lastBox);
8708
8680
  lastNPairs$1.unshift({
8709
- a: face,
8710
- b: lastFace,
8681
+ a: box,
8682
+ b: lastBox,
8711
8683
  iou: iou
8712
8684
  });
8713
8685
  if (lastNPairs$1.length > framesNeeded - 1) lastNPairs$1.length = framesNeeded - 1;
8714
8686
  }
8715
8687
  }
8716
- function makeFaceDetectorPrediction(imageData) {
8717
- if (!detector$1) return null;
8718
- var prediction = detector$1.detectForVideo(imageData, performance.now());
8719
- var faces = prediction.detections.map(function (d) {
8720
- return {
8721
- box: convertBoundingBox(d.boundingBox),
8722
- keypoints: d.keypoints.map(function (k) {
8723
- var _a;
8724
- return _assign(_assign({}, k), {
8725
- x: k.x * imageData.width,
8726
- y: k.y * imageData.height,
8727
- name: (_a = k.label) !== null && _a !== void 0 ? _a : ''
8728
- });
8729
- })
8730
- };
8688
+ var defaultDocumentDetectionBoundaries = {
8689
+ top: 20,
8690
+ bottom: 20,
8691
+ left: 20,
8692
+ right: 20
8693
+ };
8694
+ function processDocumentDetectorPrediction(prediction, thresholds, boundaries) {
8695
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
8696
+ if (boundaries === void 0) {
8697
+ boundaries = defaultDocumentDetectionBoundaries;
8698
+ }
8699
+ var detections = prediction.detections,
8700
+ frameWidth = prediction.frameWidth,
8701
+ frameHeight = prediction.frameHeight,
8702
+ time = prediction.time;
8703
+ var boundaryTop = (_a = boundaries.top) !== null && _a !== void 0 ? _a : 20;
8704
+ var boundaryLeft = (_b = boundaries.left) !== null && _b !== void 0 ? _b : 20;
8705
+ var boundaryRight = (_c = boundaries.right) !== null && _c !== void 0 ? _c : 20;
8706
+ var boundaryBottom = (_d = boundaries.bottom) !== null && _d !== void 0 ? _d : 20;
8707
+ var frameWidth80Pct = frameWidth * 0.8;
8708
+ var detectedObjects = applyNonMaxSuppression(detections.flatMap(function (d) {
8709
+ return d.categories.map(function (category) {
8710
+ return {
8711
+ label: category === null || category === void 0 ? void 0 : category.categoryName,
8712
+ score: category === null || category === void 0 ? void 0 : category.score,
8713
+ box: convertBoundingBox(d.boundingBox)
8714
+ };
8715
+ });
8716
+ }), function (obj) {
8717
+ var _a = obj.box,
8718
+ xMin = _a.xMin,
8719
+ yMin = _a.yMin,
8720
+ width = _a.width,
8721
+ height = _a.height;
8722
+ return yMin > boundaryTop &&
8723
+ // Is it valid top edge of ID detected?
8724
+ yMin + height + boundaryBottom < frameHeight && (
8725
+ // Is it valid bottom edge less than max video height
8726
+ xMin > boundaryLeft || xMin + width > frameWidth80Pct) &&
8727
+ // If either the left side visible or if not, right edge of ID should be more than 80% of width.
8728
+ xMin + width + boundaryRight < frameWidth // Valid right edge if it's less than video width.
8729
+ ;
8731
8730
  });
8732
- return _assign(_assign({}, prediction), {
8733
- faces: faces
8731
+ var allZero = detections.length > 0 && !detections.some(function (_a) {
8732
+ var boundingBox = _a.boundingBox;
8733
+ return Object.values(boundingBox !== null && boundingBox !== void 0 ? boundingBox : {}).some(function (n) {
8734
+ return n > 0;
8735
+ });
8734
8736
  });
8735
- }
8736
- function processFaceDetectorPrediction(_a) {
8737
- var faces = _a.faces,
8738
- videoWidth = _a.videoWidth,
8739
- videoHeight = _a.videoHeight,
8740
- _b = _a.requireVerticalFaceCentering,
8741
- requireVerticalFaceCentering = _b === void 0 ? true : _b,
8742
- _c = _a.stabilityThreshold,
8743
- stabilityThreshold = _c === void 0 ? 0.7 : _c;
8744
- var face = faces[0];
8745
- var faceNotDetected = faces.length === 0;
8746
- var faceNotCentered = false,
8747
- faceLookingAway = false,
8748
- faceTooClose = false,
8749
- faceTooFar = false;
8750
- if (face) {
8751
- // calculate centroids
8752
- var vCX = videoWidth / 2;
8753
- var vCY = videoHeight / 2;
8754
- var fCX = (face.box.xMin + face.box.xMax) / 2;
8755
- var fCY = (face.box.yMin + face.box.yMax) / 2;
8756
- // calculate thresholds
8757
- var vTX = videoWidth * 0.125;
8758
- var vTY = videoHeight * 0.125;
8759
- var fTW = face.box.width * 0.2;
8760
- var fTH = face.box.height * 0.2;
8761
- var nose = face.keypoints[2]; //.find((k) => k.name === 'noseTip')
8762
- if (nose) {
8763
- faceLookingAway = Math.abs(fCX - nose.x) > fTW || Math.abs(fCY - nose.y) > fTH;
8764
- var faceNotCenteredHorizontally = Math.abs(vCX - fCX) > vTX;
8765
- var faceNotCenteredVertically = Math.abs(vCY + 50 - fCY) > vTY;
8766
- faceNotCentered = faceNotCenteredHorizontally || requireVerticalFaceCentering && faceNotCenteredVertically;
8767
- }
8768
- var isMobile = videoWidth < videoHeight;
8769
- var tooCloseMultiple = 1.5;
8770
- var tooFarMultiple = isMobile ? 6 : 7;
8771
- faceTooClose = face.box.width > videoWidth / tooCloseMultiple;
8772
- faceTooFar = face.box.width < videoWidth / tooFarMultiple;
8737
+ var bestIdCardFront = detectedObjects.find(function (obj) {
8738
+ return obj.label === 'Document';
8739
+ });
8740
+ var bestIdCardBack = detectedObjects.find(function (obj) {
8741
+ return obj.label === 'Document back';
8742
+ });
8743
+ var bestPassportPage = detectedObjects.find(function (obj) {
8744
+ return obj.label === 'Passport page';
8745
+ });
8746
+ var bestSinglePage = detectedObjects.find(function (obj) {
8747
+ return obj.label === 'Single page';
8748
+ });
8749
+ var idCardFrontDetectionScore = (_e = bestIdCardFront === null || bestIdCardFront === void 0 ? void 0 : bestIdCardFront.score) !== null && _e !== void 0 ? _e : 0;
8750
+ var idCardBackDetectionScore = (_f = bestIdCardBack === null || bestIdCardBack === void 0 ? void 0 : bestIdCardBack.score) !== null && _f !== void 0 ? _f : 0;
8751
+ var passportDetectionScore = (_g = bestPassportPage === null || bestPassportPage === void 0 ? void 0 : bestPassportPage.score) !== null && _g !== void 0 ? _g : 0;
8752
+ var singlePageDetectionScore = (_h = bestSinglePage === null || bestSinglePage === void 0 ? void 0 : bestSinglePage.score) !== null && _h !== void 0 ? _h : 0;
8753
+ var idCardFrontDetectionThresholdMet = idCardFrontDetectionScore >= ((_j = thresholds.idCardFront) !== null && _j !== void 0 ? _j : 0);
8754
+ var idCardBackDetectionThresholdMet = idCardBackDetectionScore >= ((_k = thresholds.idCardBack) !== null && _k !== void 0 ? _k : 0);
8755
+ var passportDetectionThresholdMet = passportDetectionScore >= ((_l = thresholds.passport) !== null && _l !== void 0 ? _l : 0);
8756
+ var singlePageDetectionThresholdMet = singlePageDetectionScore >= ((_m = thresholds.singlePage) !== null && _m !== void 0 ? _m : 0);
8757
+ var bestDocument = singlePageDetectionThresholdMet ? bestSinglePage : passportDetectionThresholdMet ? bestPassportPage : idCardBackDetectionThresholdMet ? bestIdCardBack : bestIdCardFront;
8758
+ var detectionThreshold = singlePageDetectionThresholdMet ? thresholds.singlePage : passportDetectionThresholdMet ? thresholds.passport : idCardBackDetectionThresholdMet ? thresholds.idCardBack : thresholds.idCardFront;
8759
+ var detectionScore = (_o = bestDocument === null || bestDocument === void 0 ? void 0 : bestDocument.score) !== null && _o !== void 0 ? _o : 0;
8760
+ var detectionThresholdMet = detectionScore >= (detectionThreshold !== null && detectionThreshold !== void 0 ? detectionThreshold : 0);
8761
+ var detectedDocumentType = 'none';
8762
+ if (singlePageDetectionThresholdMet) {
8763
+ detectedDocumentType = 'singlePage';
8764
+ } else if (passportDetectionThresholdMet) {
8765
+ detectedDocumentType = 'passport';
8766
+ } else if (idCardBackDetectionThresholdMet) {
8767
+ detectedDocumentType = 'idCardBack';
8768
+ } else if (detectionThresholdMet) {
8769
+ detectedDocumentType = 'idCardFront';
8773
8770
  }
8774
- var faceInGuides = !faceNotDetected && !faceNotCentered && !faceLookingAway && !faceTooClose && !faceTooFar;
8775
- if (lastFaceDetectionTime > 0) {
8776
- trackFramesNeeded$1(500 / lastFaceDetectionTime);
8771
+ var documentInBounds = !!bestDocument;
8772
+ if (lastDetectionTime > 0) {
8773
+ trackFramesNeeded$1(1000 / lastDetectionTime);
8777
8774
  }
8778
- var faceIsStable = false;
8779
- if (faceInGuides) {
8780
- var framesNeeded = Math.ceil(average(framesNeededSamples$1));
8781
- trackFace(face, framesNeeded);
8782
- faceIsStable = lastNFaces.length >= framesNeeded && !lastNPairs$1.some(function (pair) {
8783
- return pair.iou < stabilityThreshold;
8775
+ var documentIsStable = false;
8776
+ var documentTooClose = false;
8777
+ if (bestDocument) {
8778
+ var _q = [bestDocument.box.width / frameWidth, bestDocument.box.height / frameHeight],
8779
+ docWidth = _q[0],
8780
+ docHeight = _q[1];
8781
+ documentTooClose = docWidth > 0.85 || docHeight > 0.85;
8782
+ if (detectionThresholdMet && documentInBounds && !documentTooClose) {
8783
+ var thresholdSet = (_p = thresholds.stability) !== null && _p !== void 0 ? _p : defaultDocumentDetectionThresholds.stability;
8784
+ var threshold_1 = thresholdSet[detectedDocumentType];
8785
+ var framesNeeded = Math.ceil(average(framesNeededSamples$1));
8786
+ trackBox(bestDocument.box, framesNeeded);
8787
+ documentIsStable = lastNBoxes.length >= framesNeeded && !lastNPairs$1.some(function (pair) {
8788
+ return pair.iou < threshold_1;
8789
+ });
8790
+ }
8791
+ }
8792
+ var bestPDF417;
8793
+ if (detectedObjects.length > 0) {
8794
+ bestPDF417 = detectedObjects.find(function (obj) {
8795
+ return obj.label === 'PDF417';
8784
8796
  });
8785
8797
  }
8786
- var faceReady = faceInGuides && faceIsStable;
8787
8798
  return {
8788
- face: face,
8789
- faceNotDetected: faceNotDetected,
8790
- faceNotCentered: faceNotCentered,
8791
- faceLookingAway: faceLookingAway,
8792
- faceTooClose: faceTooClose,
8793
- faceTooFar: faceTooFar,
8794
- faceReady: faceReady,
8795
- faceReadyAt: faceReady ? new Date() : null,
8796
- faceIsStable: faceIsStable
8797
- };
8798
- }
8799
- function testFaceDetectionAgainstKnownImage(detector) {
8800
- return new Promise(function (resolve, reject) {
8801
- var img = new Image();
8802
- img.crossOrigin = 'anonymous';
8803
- img.onload = function () {
8804
- var prediction = detector.detectForVideo(img, performance.now());
8805
- if (prediction.detections.length > 0) {
8806
- debug('face detection test result', prediction.detections);
8807
- resolve(void 0);
8808
- } else {
8809
- warn('face detection test failed');
8810
- reject(new Error('testFaceDetectionAgainstKnownImage failed to predict'));
8811
- }
8812
- };
8813
- img.onerror = function () {
8814
- return reject(new Error('testFaceDetectionAgainstKnownImage failed to load image'));
8815
- };
8816
- img.src = "".concat(DEFAULT_CDN_URL, "/head-test.jpg");
8817
- });
8818
- }
8819
-
8820
- var preloadModels = function preloadModels(_a) {
8821
- return __awaiter(void 0, [_a], void 0, function (_b) {
8822
- var preloadTasks;
8823
- var _c = _b.documentDetectionModel,
8824
- documentDetectionModel = _c === void 0 ? true : _c,
8825
- _d = _b.focusModel,
8826
- focusModel = _d === void 0 ? true : _d,
8827
- _e = _b.faceDetectionModel,
8828
- faceDetectionModel = _e === void 0 ? true : _e;
8829
- return __generator(this, function (_f) {
8830
- switch (_f.label) {
8831
- case 0:
8832
- return [4 /*yield*/, probeModelCapabilities()];
8833
- case 1:
8834
- _f.sent();
8835
- preloadTasks = [];
8836
- if (documentDetectionModel) {
8837
- preloadTasks.push(preloadDocumentDetectorDependencies);
8838
- }
8839
- if (focusModel) {
8840
- preloadTasks.push(preloadFocusModelDependencies);
8841
- }
8842
- if (faceDetectionModel) {
8843
- preloadTasks.push(preloadFaceDetectorDependencies);
8844
- }
8845
- return [4 /*yield*/, Promise.all(preloadTasks)];
8846
- case 2:
8847
- _f.sent();
8848
- return [2 /*return*/];
8849
- }
8850
- });
8851
- });
8852
- };
8853
- var progressByUrl = {};
8854
- var progressByUseCase = {
8855
- visionRuntime: {
8856
- loaded: 0,
8857
- total: 0
8858
- },
8859
- documentDetection: {
8860
- loaded: 0,
8861
- total: 0
8862
- },
8863
- focus: {
8864
- loaded: 0,
8865
- total: 0
8866
- },
8867
- faceDetection: {
8868
- loaded: 0,
8869
- total: 0
8870
- }
8871
- };
8872
- function preloadDependency(url) {
8873
- return __awaiter(this, void 0, void 0, function () {
8874
- return __generator(this, function (_a) {
8875
- return [2 /*return*/, new Promise(function (resolve, reject) {
8876
- var req = new XMLHttpRequest();
8877
- req.addEventListener('progress', function (event) {
8878
- if (!event.lengthComputable) return;
8879
- progressByUrl[url] = event;
8880
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress', {
8881
- detail: {
8882
- url: url,
8883
- loaded: event.loaded,
8884
- total: event.total
8885
- }
8886
- }));
8887
- });
8888
- req.addEventListener('loadend', function () {
8889
- resolve(req.readyState === 4 && req.status === 200);
8890
- });
8891
- req.addEventListener('error', reject);
8892
- req.open('GET', url, true);
8893
- req.send();
8894
- })];
8895
- });
8896
- });
8799
+ prediction: prediction,
8800
+ detectedObjects: detectedObjects,
8801
+ detectionScore: detectionScore,
8802
+ detectionTime: time,
8803
+ detectionThresholdMet: detectionThresholdMet,
8804
+ detectedDocumentType: detectedDocumentType,
8805
+ idCardFrontDetectionScore: idCardFrontDetectionScore,
8806
+ idCardFrontDetectionThresholdMet: idCardFrontDetectionThresholdMet,
8807
+ idCardBackDetectionScore: idCardBackDetectionScore,
8808
+ idCardBackDetectionThresholdMet: idCardBackDetectionThresholdMet,
8809
+ passportDetectionScore: passportDetectionScore,
8810
+ passportDetectionThresholdMet: passportDetectionThresholdMet,
8811
+ singlePageDetectionScore: singlePageDetectionScore,
8812
+ singlePageDetectionThresholdMet: singlePageDetectionThresholdMet,
8813
+ bestDocument: bestDocument,
8814
+ bestPDF417: bestPDF417,
8815
+ documentInBounds: documentInBounds,
8816
+ documentTooClose: documentTooClose,
8817
+ documentIsStable: documentIsStable,
8818
+ frameWidth: frameWidth,
8819
+ frameHeight: frameHeight,
8820
+ allZero: allZero
8821
+ };
8897
8822
  }
8898
- var documentDetectorPreloading = false,
8899
- focusModelPreloading = false,
8900
- faceDetectorPreloading = false;
8901
- function preloadDocumentDetectorDependencies() {
8902
- return __awaiter(this, void 0, void 0, function () {
8903
- function handleDownloadProgress(event) {
8904
- var detail = event.detail;
8905
- if (!dependencies.includes(detail.url)) return;
8906
- progressByUseCase.documentDetection = sumUpProgressForDependencies(dependencies);
8907
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.documentDetection', {
8908
- detail: progressByUseCase.documentDetection
8909
- }));
8823
+ function applyNonMaxSuppression(detectedObjects, isGoodBox) {
8824
+ var maxes = {};
8825
+ detectedObjects.forEach(function (obj, i) {
8826
+ if (obj) {
8827
+ if (!maxes[obj.label]) maxes[obj.label] = [0, -1];
8828
+ if (obj.score > maxes[obj.label][0] && (isGoodBox === null || isGoodBox === void 0 ? void 0 : isGoodBox(obj))) maxes[obj.label] = [obj.score, i];
8910
8829
  }
8911
- var dependencies;
8912
- return __generator(this, function (_a) {
8913
- switch (_a.label) {
8914
- case 0:
8915
- if (documentDetectorPreloading) return [2 /*return*/, new Promise(function (resolve) {
8916
- var i = setInterval(function () {
8917
- if (!documentDetectorPreloading) {
8918
- clearInterval(i);
8919
- resolve();
8920
- }
8921
- }, 100);
8922
- })];
8923
- documentDetectorPreloading = true;
8924
- return [4 /*yield*/, probeModelCapabilities()];
8925
- case 1:
8926
- _a.sent();
8927
- if (modelCapabilities.delegate === 'NONE') {
8928
- throw new Error('No available delegate for document detector.');
8929
- }
8930
- dependencies = [defaultDocumentDetectorModelPath];
8931
- document.addEventListener('idmission.preloadProgress', handleDownloadProgress);
8932
- _a.label = 2;
8933
- case 2:
8934
- _a.trys.push([2,, 4, 5]);
8935
- return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
8936
- case 3:
8937
- _a.sent();
8938
- return [3 /*break*/, 5];
8939
- case 4:
8940
- document.removeEventListener('idmission.preloadProgress', handleDownloadProgress);
8941
- documentDetectorPreloading = false;
8942
- return [7 /*endfinally*/];
8943
- case 5:
8944
- return [2 /*return*/];
8945
- }
8946
- });
8947
8830
  });
8948
- }
8949
- function preloadFocusModelDependencies() {
8950
- return __awaiter(this, void 0, void 0, function () {
8951
- function handleModelDownloadProgress(event) {
8952
- var detail = event.detail;
8953
- if (!dependencies.includes(detail.url)) return;
8954
- progressByUseCase.focus = sumUpProgressForDependencies(dependencies);
8955
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.focus', {
8956
- detail: progressByUseCase.focus
8957
- }));
8958
- }
8959
- var dependencies;
8960
- return __generator(this, function (_a) {
8961
- switch (_a.label) {
8962
- case 0:
8963
- if (focusModelPreloading) return [2 /*return*/, new Promise(function (resolve) {
8964
- var i = setInterval(function () {
8965
- if (!focusModelPreloading) {
8966
- clearInterval(i);
8967
- resolve();
8968
- }
8969
- }, 100);
8970
- })];
8971
- focusModelPreloading = true;
8972
- return [4 /*yield*/, probeModelCapabilities()];
8973
- case 1:
8974
- _a.sent();
8975
- if (modelCapabilities.delegate === 'NONE') {
8976
- throw new Error('No available delegate for document detector.');
8977
- }
8978
- dependencies = [defaultFocusModelPath];
8979
- document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
8980
- _a.label = 2;
8981
- case 2:
8982
- _a.trys.push([2,, 4, 5]);
8983
- return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
8984
- case 3:
8985
- _a.sent();
8986
- return [3 /*break*/, 5];
8987
- case 4:
8988
- document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
8989
- focusModelPreloading = false;
8990
- return [7 /*endfinally*/];
8991
- case 5:
8992
- return [2 /*return*/];
8993
- }
8994
- });
8831
+ return Object.keys(maxes).map(function (label) {
8832
+ return detectedObjects[maxes[label][1]];
8833
+ }).filter(function (obj) {
8834
+ return !!obj;
8995
8835
  });
8996
8836
  }
8997
- function preloadFaceDetectorDependencies() {
8998
- return __awaiter(this, void 0, void 0, function () {
8999
- function handleModelDownloadProgress(event) {
9000
- var detail = event.detail;
9001
- if (!dependencies.includes(detail.url)) return;
9002
- progressByUseCase.faceDetection = sumUpProgressForDependencies(dependencies);
9003
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.faceDetection', {
9004
- detail: progressByUseCase.faceDetection
9005
- }));
9006
- }
9007
- var dependencies;
9008
- return __generator(this, function (_a) {
9009
- switch (_a.label) {
9010
- case 0:
9011
- if (faceDetectorPreloading) return [2 /*return*/, new Promise(function (resolve) {
9012
- var i = setInterval(function () {
9013
- if (!faceDetectorPreloading) {
9014
- clearInterval(i);
9015
- resolve();
9016
- }
9017
- }, 100);
9018
- })];
9019
- faceDetectorPreloading = true;
9020
- return [4 /*yield*/, probeModelCapabilities()];
9021
- case 1:
9022
- _a.sent();
9023
- if (modelCapabilities.delegate === 'NONE') {
9024
- throw new Error('No available delegate for document detector.');
9025
- }
9026
- dependencies = [defaultFaceDetectorModelPath];
9027
- document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
9028
- _a.label = 2;
9029
- case 2:
9030
- _a.trys.push([2,, 4, 5]);
9031
- return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
9032
- case 3:
9033
- _a.sent();
9034
- return [3 /*break*/, 5];
9035
- case 4:
9036
- document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
9037
- faceDetectorPreloading = false;
9038
- return [7 /*endfinally*/];
9039
- case 5:
9040
- return [2 /*return*/];
8837
+ function testDocumentDetectionAgainstKnownImage(detector) {
8838
+ return new Promise(function (resolve, reject) {
8839
+ var img = new Image();
8840
+ img.crossOrigin = 'anonymous';
8841
+ img.onload = function () {
8842
+ var prediction = detector.detectForVideo(img, performance.now());
8843
+ if (prediction.detections.length > 0) {
8844
+ debug('document detection test result', prediction.detections);
8845
+ resolve(void 0);
8846
+ } else {
8847
+ warn('document detection test failed');
8848
+ reject(new Error('testDocumentDetectionAgainstKnownImage failed to predict'));
9041
8849
  }
9042
- });
9043
- });
9044
- }
9045
- function progressToPercentage(progress) {
9046
- return progress.total > 0 ? Math.round(100.0 * progress.loaded / progress.total) : 0;
9047
- }
9048
- function sumUpProgressForDependencies(dependencies) {
9049
- return dependencies.reduce(function (result, dependency) {
9050
- var dependencyProgress = progressByUrl[dependency];
9051
- if (!dependencyProgress) return result;
9052
- result.loaded += dependencyProgress.loaded;
9053
- result.total += dependencyProgress.total;
9054
- return result;
9055
- }, {
9056
- loaded: 0,
9057
- total: 0
8850
+ };
8851
+ img.onerror = function () {
8852
+ return reject(new Error('testDocumentDetectionAgainstKnownImage failed to load image'));
8853
+ };
8854
+ img.src = "".concat(DEFAULT_CDN_URL, "/id-card-test.jpg");
9058
8855
  });
9059
8856
  }
9060
8857
 
9061
- var defaultDocumentDetectionScoreThreshold = 0.1;
9062
- var defaultDocumentDetectionModelLoadTimeoutMs = 45000;
9063
- var defaultDocumentDetectionThresholds = {
9064
- idCardFront: 0.6,
9065
- idCardBack: 0.6,
9066
- passport: 0.4,
9067
- singlePage: 0.4,
9068
- stability: {
9069
- idCardFront: 0.85,
9070
- idCardBack: 0.85,
9071
- passport: 0.5,
9072
- singlePage: 0.5
8858
+ function getFrameDimensions(frame) {
8859
+ var frameWidth = frame.width,
8860
+ frameHeight = frame.height;
8861
+ if (frame instanceof HTMLImageElement) {
8862
+ frameWidth = frame.naturalWidth;
8863
+ frameHeight = frame.naturalHeight;
9073
8864
  }
9074
- };
9075
- var documentTypeDisplayNames = {
9076
- idCardFront: 'ID card front',
9077
- idCardBack: 'ID card back',
9078
- passport: 'Passport',
9079
- singlePage: 'Single page',
9080
- none: 'None'
9081
- };
9082
- var detector = null;
9083
- var detectorSettings = null;
9084
- function loadDocumentDetector() {
9085
- return __awaiter(this, arguments, void 0, function (modelAssetPath, scoreThreshold) {
9086
- var _a, _b;
9087
- if (modelAssetPath === void 0) {
9088
- modelAssetPath = defaultDocumentDetectorModelPath;
9089
- }
9090
- if (scoreThreshold === void 0) {
9091
- scoreThreshold = defaultDocumentDetectionScoreThreshold;
9092
- }
9093
- return __generator(this, function (_c) {
9094
- switch (_c.label) {
9095
- case 0:
9096
- if (detector && (detectorSettings === null || detectorSettings === void 0 ? void 0 : detectorSettings.modelAssetPath) === modelAssetPath && (detectorSettings === null || detectorSettings === void 0 ? void 0 : detectorSettings.scoreThreshold) === scoreThreshold) return [2 /*return*/, detector];
9097
- closeDocumentDetector();
9098
- return [4 /*yield*/, preloadDocumentDetectorDependencies()];
9099
- case 1:
9100
- _c.sent();
9101
- if (modelCapabilities.delegate === 'NONE') {
9102
- throw new Error('No available delegate for document detector.');
9103
- }
9104
- _b = (_a = lh).createFromOptions;
9105
- return [4 /*yield*/, ao.forVisionTasks(visionTasksBasePath)];
9106
- case 2:
9107
- return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
9108
- baseOptions: {
9109
- modelAssetPath: modelAssetPath,
9110
- delegate: modelCapabilities.delegate
9111
- },
9112
- // canvas: document.createElement('canvas'),
9113
- scoreThreshold: scoreThreshold,
9114
- runningMode: 'VIDEO'
9115
- }])];
9116
- case 3:
9117
- detector = _c.sent();
9118
- detectorSettings = {
9119
- modelAssetPath: modelAssetPath,
9120
- scoreThreshold: scoreThreshold
9121
- };
9122
- return [2 /*return*/, detector];
9123
- }
9124
- });
9125
- });
8865
+ if (frame instanceof HTMLVideoElement) {
8866
+ frameWidth = frame.videoWidth;
8867
+ frameHeight = frame.videoHeight;
8868
+ }
8869
+ return [frameWidth, frameHeight];
9126
8870
  }
9127
- function closeDocumentDetector() {
9128
- detector === null || detector === void 0 ? void 0 : detector.close();
9129
- detector = null;
9130
- detectorSettings = null;
8871
+
8872
+ var InvisibleCanvasContainer = styled.div(templateObject_1$N || (templateObject_1$N = __makeTemplateObject(["\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n"], ["\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n"])));
8873
+ var InvisibleCanvas = styled.canvas(templateObject_2$G || (templateObject_2$G = __makeTemplateObject(["\n display: none;\n"], ["\n display: none;\n"])));
8874
+ function drawToCanvas(canvas, frame, width, height) {
8875
+ if (!canvas) return;
8876
+ var ctx = canvas.getContext('2d');
8877
+ if (!ctx) return;
8878
+ if (!width || !height) {
8879
+ var _a = getFrameDimensions(frame),
8880
+ frameWidth = _a[0],
8881
+ frameHeight = _a[1];
8882
+ width || (width = frameWidth);
8883
+ height || (height = frameHeight);
8884
+ }
8885
+ canvas.width = width;
8886
+ canvas.height = height;
8887
+ ctx.drawImage(frame, 0, 0, width, height);
9131
8888
  }
9132
- function useLoadDocumentDetector(_a) {
9133
- var _b = _a.shouldLoadModels,
9134
- shouldLoadModels = _b === void 0 ? true : _b,
9135
- _c = _a.modelPath,
9136
- modelPath = _c === void 0 ? defaultDocumentDetectorModelPath : _c,
9137
- _d = _a.modelLoadTimeoutMs,
9138
- modelLoadTimeoutMs = _d === void 0 ? defaultDocumentDetectionModelLoadTimeoutMs : _d,
9139
- _e = _a.scoreThreshold,
9140
- scoreThreshold = _e === void 0 ? defaultDocumentDetectionScoreThreshold : _e,
9141
- onModelError = _a.onModelError,
9142
- videoRef = _a.videoRef;
9143
- var _f = React.useState('not-started'),
9144
- modelLoadState = _f[0],
9145
- setModelLoadState = _f[1];
9146
- var _g = React.useState(null),
9147
- modelWarmingStartedAt = _g[0],
9148
- setModelWarmingStartedAt = _g[1];
9149
- var _h = React.useState(0),
9150
- modelDownloadProgress = _h[0],
9151
- setModelDownloadProgress = _h[1];
9152
- var _j = React.useState(null),
9153
- modelError = _j[0],
9154
- setModelError = _j[1];
9155
- React.useEffect(function loadModel() {
9156
- var _this = this;
9157
- if (!shouldLoadModels) return;
9158
- setModelLoadState('downloading');
9159
- setModelWarmingStartedAt(null);
9160
- function handleDownloadProgress(event) {
9161
- setModelDownloadProgress(progressToPercentage(event.detail));
9162
- }
9163
- document.addEventListener('idmission.preloadProgress.documentDetection', handleDownloadProgress);
9164
- var modelLoadTimeout = setTimeout(function () {
9165
- setModelError(new Error('Model loading time limit exceeded.'));
9166
- }, modelLoadTimeoutMs);
9167
- var cancelVideoReady = function cancelVideoReady() {};
9168
- loadDocumentDetector(modelPath, scoreThreshold).then(function (model) {
9169
- return __awaiter(_this, void 0, void 0, function () {
9170
- var _a, videoReady, cancel, cancelled;
9171
- return __generator(this, function (_b) {
9172
- switch (_b.label) {
8889
+ function clearCanvas(canvas) {
8890
+ var _a;
8891
+ (_a = canvas === null || canvas === void 0 ? void 0 : canvas.getContext('2d')) === null || _a === void 0 ? void 0 : _a.clearRect(0, 0, canvas === null || canvas === void 0 ? void 0 : canvas.width, canvas === null || canvas === void 0 ? void 0 : canvas.height);
8892
+ }
8893
+ var templateObject_1$N, templateObject_2$G;
8894
+
8895
+ function useFrameLoop(fn, options) {
8896
+ if (options === void 0) {
8897
+ options = {};
8898
+ }
8899
+ var _a = React.useState(false),
8900
+ running = _a[0],
8901
+ setRunning = _a[1];
8902
+ var startedAtRef = React.useRef(null);
8903
+ var loopId = React.useRef(0);
8904
+ var frameId = React.useRef(0);
8905
+ React.useEffect(function runFrameLoop() {
8906
+ if (!running) return;
8907
+ var timer;
8908
+ var currentLoopId = loopId.current;
8909
+ function hotLoop() {
8910
+ return __awaiter(this, void 0, void 0, function () {
8911
+ var start, timeRunning, took, amountToThrottle;
8912
+ var _a, _b, _c;
8913
+ return __generator(this, function (_d) {
8914
+ switch (_d.label) {
9173
8915
  case 0:
9174
- setModelDownloadProgress(100);
9175
- setModelLoadState('warming');
9176
- setModelWarmingStartedAt(new Date().getTime());
9177
- clearTimeout(modelLoadTimeout);
9178
- return [4 /*yield*/, testDocumentDetectionAgainstKnownImage(model)];
8916
+ if (currentLoopId !== loopId.current) return [2 /*return*/];
8917
+ start = new Date().getTime();
8918
+ timeRunning = start - ((_b = (_a = startedAtRef.current) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0);
8919
+ return [4 /*yield*/, fn(frameId.current, timeRunning)];
9179
8920
  case 1:
9180
- _b.sent();
9181
- _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
9182
- cancelled = false;
9183
- cancelVideoReady = function cancelVideoReady() {
9184
- cancelled = true;
9185
- cancel();
9186
- };
9187
- return [4 /*yield*/, videoReady];
9188
- case 2:
9189
- _b.sent();
9190
- setTimeout(function () {
9191
- if (cancelled) return;
9192
- model.detectForVideo(videoRef.current, performance.now());
9193
- setModelLoadState('ready');
9194
- }, 500);
8921
+ _d.sent();
8922
+ took = new Date().getTime() - start;
8923
+ amountToThrottle = Math.max(((_c = options.throttleMs) !== null && _c !== void 0 ? _c : 0) - took, 0);
8924
+ timer = setTimeout(function () {
8925
+ frameId.current = requestAnimationFrame(hotLoop);
8926
+ }, amountToThrottle);
9195
8927
  return [2 /*return*/];
9196
8928
  }
9197
8929
  });
9198
8930
  });
9199
- })["catch"](function (e) {
9200
- setModelError(e);
9201
- setModelLoadState('error');
9202
- })["finally"](function () {
9203
- clearTimeout(modelLoadTimeout);
9204
- });
8931
+ }
8932
+ void hotLoop();
9205
8933
  return function () {
9206
- log('unloading document detection model');
9207
- cancelVideoReady();
9208
- closeDocumentDetector();
9209
- clearTimeout(modelLoadTimeout);
9210
- document.removeEventListener('idmission.preloadProgress.documentDetection', handleDownloadProgress);
9211
- };
9212
- }, [shouldLoadModels, modelLoadTimeoutMs, modelPath, scoreThreshold, videoRef]);
9213
- React.useEffect(function handleModelError() {
9214
- if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
9215
- }, [modelError, onModelError]);
9216
- return React.useMemo(function () {
9217
- return {
9218
- ready: modelLoadState === 'ready',
9219
- modelLoadState: modelLoadState,
9220
- modelDownloadProgress: modelDownloadProgress,
9221
- modelWarmingStartedAt: modelWarmingStartedAt,
9222
- modelError: modelError,
9223
- setModelError: setModelError
8934
+ loopId.current += 1;
8935
+ if (frameId.current) cancelAnimationFrame(frameId.current);
8936
+ if (timer) clearTimeout(timer);
9224
8937
  };
9225
- }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
9226
- }
9227
- function makeDocumentDetectorPrediction(frame) {
9228
- return __awaiter(this, void 0, void 0, function () {
9229
- var startedAt, prediction, time, frameWidth, frameHeight;
9230
- return __generator(this, function (_a) {
9231
- if (!detector) return [2 /*return*/, null];
9232
- startedAt = new Date();
9233
- // Detectors can throw errors, for example when using custom URLs that
9234
- // contain a model that doesn't provide the expected output.
9235
- try {
9236
- prediction = detector.detectForVideo(frame, performance.now());
9237
- time = new Date().getTime() - startedAt.getTime();
9238
- frameWidth = frame.width;
9239
- frameHeight = frame.height;
9240
- return [2 /*return*/, _assign(_assign({}, prediction), {
9241
- time: time,
9242
- frameWidth: frameWidth,
9243
- frameHeight: frameHeight
9244
- })];
9245
- } catch (e) {
9246
- error('caught object detection error', e);
9247
- }
9248
- return [2 /*return*/, null];
9249
- });
9250
- });
9251
- }
9252
- var lastDetectionAt = 0;
9253
- var lastDetectionTime = 0;
9254
- function setLastDetectionAt(time) {
9255
- lastDetectionTime = time - lastDetectionAt;
9256
- lastDetectionAt = time;
9257
- }
9258
- var framesNeededSamples = [];
9259
- function trackFramesNeeded(value, bufferLength) {
9260
- if (bufferLength === void 0) {
9261
- bufferLength = 25;
9262
- }
9263
- framesNeededSamples.unshift(value);
9264
- if (framesNeededSamples.length > bufferLength) framesNeededSamples.length = bufferLength;
9265
- }
9266
- var lastNBoxes = [];
9267
- var lastNPairs = [];
9268
- function trackBox(box, framesNeeded) {
9269
- if (framesNeeded === void 0) {
9270
- framesNeeded = 12;
9271
- }
9272
- lastNBoxes.unshift(box);
9273
- if (lastNBoxes.length > framesNeeded) lastNBoxes.length = framesNeeded;
9274
- if (lastNBoxes.length > 1) {
9275
- var lastBox = lastNBoxes[1];
9276
- var iou = calculateIoU(box, lastBox);
9277
- lastNPairs.unshift({
9278
- a: box,
9279
- b: lastBox,
9280
- iou: iou
9281
- });
9282
- if (lastNPairs.length > framesNeeded - 1) lastNPairs.length = framesNeeded - 1;
9283
- }
9284
- }
9285
- var defaultDocumentDetectionBoundaries = {
9286
- top: 20,
9287
- bottom: 20,
9288
- left: 20,
9289
- right: 20
9290
- };
9291
- function processDocumentDetectorPrediction(prediction, thresholds, boundaries) {
9292
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
9293
- if (boundaries === void 0) {
9294
- boundaries = defaultDocumentDetectionBoundaries;
9295
- }
9296
- var detections = prediction.detections,
9297
- frameWidth = prediction.frameWidth,
9298
- frameHeight = prediction.frameHeight,
9299
- time = prediction.time;
9300
- var boundaryTop = (_a = boundaries.top) !== null && _a !== void 0 ? _a : 20;
9301
- var boundaryLeft = (_b = boundaries.left) !== null && _b !== void 0 ? _b : 20;
9302
- var boundaryRight = (_c = boundaries.right) !== null && _c !== void 0 ? _c : 20;
9303
- var boundaryBottom = (_d = boundaries.bottom) !== null && _d !== void 0 ? _d : 20;
9304
- var frameWidth80Pct = frameWidth * 0.8;
9305
- var detectedObjects = applyNonMaxSuppression(detections.flatMap(function (d) {
9306
- return d.categories.map(function (category) {
9307
- return {
9308
- label: category === null || category === void 0 ? void 0 : category.categoryName,
9309
- score: category === null || category === void 0 ? void 0 : category.score,
9310
- box: convertBoundingBox(d.boundingBox)
9311
- };
9312
- });
9313
- }), function (obj) {
9314
- var _a = obj.box,
9315
- xMin = _a.xMin,
9316
- yMin = _a.yMin,
9317
- width = _a.width,
9318
- height = _a.height;
9319
- return yMin > boundaryTop &&
9320
- // Is it valid top edge of ID detected?
9321
- yMin + height + boundaryBottom < frameHeight && (
9322
- // Is it valid bottom edge less than max video height
9323
- xMin > boundaryLeft || xMin + width > frameWidth80Pct) &&
9324
- // If either the left side visible or if not, right edge of ID should be more than 80% of width.
9325
- xMin + width + boundaryRight < frameWidth // Valid right edge if it's less than video width.
9326
- ;
9327
- });
9328
- var allZero = detections.length > 0 && !detections.some(function (_a) {
9329
- var boundingBox = _a.boundingBox;
9330
- return Object.values(boundingBox !== null && boundingBox !== void 0 ? boundingBox : {}).some(function (n) {
9331
- return n > 0;
9332
- });
9333
- });
9334
- var bestIdCardFront = detectedObjects.find(function (obj) {
9335
- return obj.label === 'Document';
9336
- });
9337
- var bestIdCardBack = detectedObjects.find(function (obj) {
9338
- return obj.label === 'Document back';
9339
- });
9340
- var bestPassportPage = detectedObjects.find(function (obj) {
9341
- return obj.label === 'Passport page';
9342
- });
9343
- var bestSinglePage = detectedObjects.find(function (obj) {
9344
- return obj.label === 'Single page';
9345
- });
9346
- var idCardFrontDetectionScore = (_e = bestIdCardFront === null || bestIdCardFront === void 0 ? void 0 : bestIdCardFront.score) !== null && _e !== void 0 ? _e : 0;
9347
- var idCardBackDetectionScore = (_f = bestIdCardBack === null || bestIdCardBack === void 0 ? void 0 : bestIdCardBack.score) !== null && _f !== void 0 ? _f : 0;
9348
- var passportDetectionScore = (_g = bestPassportPage === null || bestPassportPage === void 0 ? void 0 : bestPassportPage.score) !== null && _g !== void 0 ? _g : 0;
9349
- var singlePageDetectionScore = (_h = bestSinglePage === null || bestSinglePage === void 0 ? void 0 : bestSinglePage.score) !== null && _h !== void 0 ? _h : 0;
9350
- var idCardFrontDetectionThresholdMet = idCardFrontDetectionScore >= ((_j = thresholds.idCardFront) !== null && _j !== void 0 ? _j : 0);
9351
- var idCardBackDetectionThresholdMet = idCardBackDetectionScore >= ((_k = thresholds.idCardBack) !== null && _k !== void 0 ? _k : 0);
9352
- var passportDetectionThresholdMet = passportDetectionScore >= ((_l = thresholds.passport) !== null && _l !== void 0 ? _l : 0);
9353
- var singlePageDetectionThresholdMet = singlePageDetectionScore >= ((_m = thresholds.singlePage) !== null && _m !== void 0 ? _m : 0);
9354
- var bestDocument = singlePageDetectionThresholdMet ? bestSinglePage : passportDetectionThresholdMet ? bestPassportPage : idCardBackDetectionThresholdMet ? bestIdCardBack : bestIdCardFront;
9355
- var detectionThreshold = singlePageDetectionThresholdMet ? thresholds.singlePage : passportDetectionThresholdMet ? thresholds.passport : idCardBackDetectionThresholdMet ? thresholds.idCardBack : thresholds.idCardFront;
9356
- var detectionScore = (_o = bestDocument === null || bestDocument === void 0 ? void 0 : bestDocument.score) !== null && _o !== void 0 ? _o : 0;
9357
- var detectionThresholdMet = detectionScore >= (detectionThreshold !== null && detectionThreshold !== void 0 ? detectionThreshold : 0);
9358
- var detectedDocumentType = 'none';
9359
- if (singlePageDetectionThresholdMet) {
9360
- detectedDocumentType = 'singlePage';
9361
- } else if (passportDetectionThresholdMet) {
9362
- detectedDocumentType = 'passport';
9363
- } else if (idCardBackDetectionThresholdMet) {
9364
- detectedDocumentType = 'idCardBack';
9365
- } else if (detectionThresholdMet) {
9366
- detectedDocumentType = 'idCardFront';
9367
- }
9368
- var documentInBounds = !!bestDocument;
9369
- if (lastDetectionTime > 0) {
9370
- trackFramesNeeded(1000 / lastDetectionTime);
9371
- }
9372
- var documentIsStable = false;
9373
- var documentTooClose = false;
9374
- if (bestDocument) {
9375
- var _q = [bestDocument.box.width / frameWidth, bestDocument.box.height / frameHeight],
9376
- docWidth = _q[0],
9377
- docHeight = _q[1];
9378
- documentTooClose = docWidth > 0.85 || docHeight > 0.85;
9379
- if (detectionThresholdMet && documentInBounds && !documentTooClose) {
9380
- var thresholdSet = (_p = thresholds.stability) !== null && _p !== void 0 ? _p : defaultDocumentDetectionThresholds.stability;
9381
- var threshold_1 = thresholdSet[detectedDocumentType];
9382
- var framesNeeded = Math.ceil(average(framesNeededSamples));
9383
- trackBox(bestDocument.box, framesNeeded);
9384
- documentIsStable = lastNBoxes.length >= framesNeeded && !lastNPairs.some(function (pair) {
9385
- return pair.iou < threshold_1;
9386
- });
9387
- }
9388
- }
9389
- return {
9390
- prediction: prediction,
9391
- detectedObjects: detectedObjects,
9392
- detectionScore: detectionScore,
9393
- detectionTime: time,
9394
- detectionThresholdMet: detectionThresholdMet,
9395
- detectedDocumentType: detectedDocumentType,
9396
- idCardFrontDetectionScore: idCardFrontDetectionScore,
9397
- idCardFrontDetectionThresholdMet: idCardFrontDetectionThresholdMet,
9398
- idCardBackDetectionScore: idCardBackDetectionScore,
9399
- idCardBackDetectionThresholdMet: idCardBackDetectionThresholdMet,
9400
- passportDetectionScore: passportDetectionScore,
9401
- passportDetectionThresholdMet: passportDetectionThresholdMet,
9402
- singlePageDetectionScore: singlePageDetectionScore,
9403
- singlePageDetectionThresholdMet: singlePageDetectionThresholdMet,
9404
- bestDocument: bestDocument,
9405
- documentInBounds: documentInBounds,
9406
- documentTooClose: documentTooClose,
9407
- documentIsStable: documentIsStable,
9408
- frameWidth: frameWidth,
9409
- frameHeight: frameHeight,
9410
- allZero: allZero
9411
- };
9412
- }
9413
- function applyNonMaxSuppression(detectedObjects, isGoodBox) {
9414
- var maxes = {};
9415
- detectedObjects.forEach(function (obj, i) {
9416
- if (obj) {
9417
- if (!maxes[obj.label]) maxes[obj.label] = [0, -1];
9418
- if (obj.score > maxes[obj.label][0] && (isGoodBox === null || isGoodBox === void 0 ? void 0 : isGoodBox(obj))) maxes[obj.label] = [obj.score, i];
9419
- }
9420
- });
9421
- return Object.keys(maxes).map(function (label) {
9422
- return detectedObjects[maxes[label][1]];
9423
- }).filter(function (obj) {
9424
- return !!obj;
9425
- });
9426
- }
9427
- function testDocumentDetectionAgainstKnownImage(detector) {
9428
- return new Promise(function (resolve, reject) {
9429
- var img = new Image();
9430
- img.crossOrigin = 'anonymous';
9431
- img.onload = function () {
9432
- var prediction = detector.detectForVideo(img, performance.now());
9433
- if (prediction.detections.length > 0) {
9434
- debug('document detection test result', prediction.detections);
9435
- resolve(void 0);
9436
- } else {
9437
- warn('document detection test failed');
9438
- reject(new Error('testDocumentDetectionAgainstKnownImage failed to predict'));
9439
- }
9440
- };
9441
- img.onerror = function () {
9442
- return reject(new Error('testDocumentDetectionAgainstKnownImage failed to load image'));
9443
- };
9444
- img.src = "".concat(DEFAULT_CDN_URL, "/id-card-test.jpg");
9445
- });
9446
- }
9447
-
9448
- function useFrameLoop(fn, options) {
9449
- if (options === void 0) {
9450
- options = {};
9451
- }
9452
- var _a = React.useState(false),
9453
- running = _a[0],
9454
- setRunning = _a[1];
9455
- var startedAtRef = React.useRef(null);
9456
- var loopId = React.useRef(0);
9457
- var frameId = React.useRef(0);
9458
- React.useEffect(function runFrameLoop() {
9459
- if (!running) return;
9460
- var timer;
9461
- var currentLoopId = loopId.current;
9462
- function hotLoop() {
9463
- return __awaiter(this, void 0, void 0, function () {
9464
- var start, timeRunning, took, amountToThrottle;
9465
- var _a, _b, _c;
9466
- return __generator(this, function (_d) {
9467
- switch (_d.label) {
9468
- case 0:
9469
- if (currentLoopId !== loopId.current) return [2 /*return*/];
9470
- start = new Date().getTime();
9471
- timeRunning = start - ((_b = (_a = startedAtRef.current) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0);
9472
- return [4 /*yield*/, fn(frameId.current, timeRunning)];
9473
- case 1:
9474
- _d.sent();
9475
- took = new Date().getTime() - start;
9476
- amountToThrottle = Math.max(((_c = options.throttleMs) !== null && _c !== void 0 ? _c : 0) - took, 0);
9477
- timer = setTimeout(function () {
9478
- frameId.current = requestAnimationFrame(hotLoop);
9479
- }, amountToThrottle);
9480
- return [2 /*return*/];
9481
- }
9482
- });
9483
- });
9484
- }
9485
- void hotLoop();
9486
- return function () {
9487
- loopId.current += 1;
9488
- if (frameId.current) cancelAnimationFrame(frameId.current);
9489
- if (timer) clearTimeout(timer);
9490
- };
9491
- }, [fn, running, options.throttleMs]);
9492
- var start = React.useCallback(function () {
9493
- startedAtRef.current = new Date();
9494
- setRunning(true);
9495
- }, []);
9496
- var stop = React.useCallback(function () {
9497
- loopId.current += 1; // force the loop to stop immediately.
9498
- setRunning(false);
9499
- startedAtRef.current = null;
9500
- }, []);
9501
- React.useEffect(function startAutomatically() {
9502
- if (options.autoStart) start();
9503
- return stop;
9504
- }, [options.autoStart, start, stop]);
9505
- return {
9506
- start: start,
9507
- stop: stop
9508
- };
8938
+ }, [fn, running, options.throttleMs]);
8939
+ var start = React.useCallback(function () {
8940
+ startedAtRef.current = new Date();
8941
+ setRunning(true);
8942
+ }, []);
8943
+ var stop = React.useCallback(function () {
8944
+ loopId.current += 1; // force the loop to stop immediately.
8945
+ setRunning(false);
8946
+ startedAtRef.current = null;
8947
+ }, []);
8948
+ React.useEffect(function startAutomatically() {
8949
+ if (options.autoStart) start();
8950
+ return stop;
8951
+ }, [options.autoStart, start, stop]);
8952
+ return {
8953
+ start: start,
8954
+ stop: stop
8955
+ };
9509
8956
  }
9510
8957
 
9511
8958
  var createStoreImpl = function createStoreImpl(createState) {
@@ -14256,13 +13703,278 @@
14256
13703
  }), children);
14257
13704
  }
14258
13705
 
14259
- var FocusModelContext = /*#__PURE__*/React.createContext({
14260
- loadFocusModel: function loadFocusModel() {
14261
- return null;
14262
- },
14263
- focusModelState: 'not-started',
14264
- focusModelDownloadProgress: 0,
14265
- focusModelWarmingStartedAt: null,
13706
+ function cropToShoulders(rawCanvas, cropCanvas, resizeCanvas, frame, face, quality, maxHeight) {
13707
+ var _a;
13708
+ if (quality === void 0) {
13709
+ quality = 0.92;
13710
+ }
13711
+ if (!rawCanvas || !cropCanvas || !resizeCanvas) return '';
13712
+ var rawCtx = rawCanvas.getContext('2d');
13713
+ var cropCtx = cropCanvas.getContext('2d');
13714
+ var resizeCtx = resizeCanvas.getContext('2d');
13715
+ if (!rawCtx || !cropCtx || !resizeCtx) throw new Error('could not get 2d context');
13716
+ rawCanvas.width = frame.width;
13717
+ rawCanvas.height = frame.height;
13718
+ rawCtx.putImageData(frame, 0, 0);
13719
+ if (frame.height > frame.width) {
13720
+ cropCanvas.width = frame.width;
13721
+ cropCanvas.height = frame.height;
13722
+ cropCtx.drawImage(rawCanvas, 0, 0, cropCanvas.width, cropCanvas.height);
13723
+ } else {
13724
+ var _b = (_a = face === null || face === void 0 ? void 0 : face.box) !== null && _a !== void 0 ? _a : {
13725
+ xMin: 0,
13726
+ width: frame.width
13727
+ },
13728
+ xMin = _b.xMin,
13729
+ width = _b.width;
13730
+ var desiredWidth = frame.height * 0.6;
13731
+ var faceCenterX = xMin + width / 2;
13732
+ var xPos = Math.max(0, faceCenterX - desiredWidth / 2);
13733
+ cropCanvas.width = desiredWidth;
13734
+ cropCanvas.height = frame.height;
13735
+ cropCtx.drawImage(rawCanvas, xPos, 0, cropCanvas.width, cropCanvas.height, 0, 0, cropCanvas.width, cropCanvas.height);
13736
+ }
13737
+ resizeCanvas.height = maxHeight !== null && maxHeight !== void 0 ? maxHeight : cropCanvas.height;
13738
+ resizeCanvas.width = cropCanvas.width * (resizeCanvas.height / cropCanvas.height);
13739
+ resizeCtx === null || resizeCtx === void 0 ? void 0 : resizeCtx.drawImage(cropCanvas, 0, 0, resizeCanvas.width, resizeCanvas.height);
13740
+ var dataURL = resizeCanvas.toDataURL('image/jpeg', quality);
13741
+ log('cropToShoulders size', new TextEncoder().encode(dataURL).length);
13742
+ clearCanvas(rawCanvas);
13743
+ clearCanvas(cropCanvas);
13744
+ clearCanvas(resizeCanvas);
13745
+ return dataURL;
13746
+ }
13747
+ function cropToDetectedObjectBox(frame, box, canvas, padding) {
13748
+ if (padding === void 0) {
13749
+ padding = 0;
13750
+ }
13751
+ canvas || (canvas = document.createElement('canvas'));
13752
+ var ctx = canvas.getContext('2d');
13753
+ if (!ctx) throw new Error('could not get 2d context');
13754
+ var xMin = box.xMin,
13755
+ yMin = box.yMin,
13756
+ width = box.width,
13757
+ height = box.height;
13758
+ canvas.width = width + padding * 2;
13759
+ canvas.height = height + padding * 2;
13760
+ ctx.drawImage(frame, xMin - padding, yMin - padding, width + padding * 2, height + padding * 2, 0, 0, canvas.width, canvas.height);
13761
+ return canvas;
13762
+ }
13763
+ function cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box, padding) {
13764
+ if (padding === void 0) {
13765
+ padding = 0;
13766
+ }
13767
+ if (!box) return imageData;
13768
+ var cropped = cropToDetectedObjectBox(imageData, box, cropCanvas, padding);
13769
+ var _a = [box.width, box.height],
13770
+ bw = _a[0],
13771
+ bh = _a[1];
13772
+ if (bh <= bw) return cropped;
13773
+ var ctx = rotateCanvas.getContext('2d');
13774
+ if (!ctx) return cropped;
13775
+ rotateCanvas.width = bh;
13776
+ rotateCanvas.height = bw;
13777
+ ctx.clearRect(0, 0, rotateCanvas.width, rotateCanvas.height);
13778
+ ctx.translate(rotateCanvas.width / 2, rotateCanvas.height / 2);
13779
+ ctx.rotate(1.5708); // 90 deg in radians
13780
+ ctx.drawImage(cropped, -bw / 2, -bh / 2);
13781
+ return rotateCanvas;
13782
+ }
13783
+ function resizeIfNecessary(imageData, resizeCanvas, maxWidth) {
13784
+ var width = imageData.width,
13785
+ height = imageData.height;
13786
+ if (width <= maxWidth) return imageData;
13787
+ var resizeCtx = resizeCanvas.getContext('2d');
13788
+ if (!resizeCtx) return imageData;
13789
+ var scale = maxWidth / width;
13790
+ resizeCanvas.width = maxWidth;
13791
+ resizeCanvas.height = height * scale;
13792
+ resizeCtx.drawImage(imageData, 0, 0, resizeCanvas.width, resizeCanvas.height);
13793
+ return resizeCanvas;
13794
+ }
13795
+
13796
+ var defaultFocusModelLoadTimeoutMs = 45000;
13797
+ var defaultFocusThresholds = {
13798
+ idCardFront: {
13799
+ desktop: 0,
13800
+ mobile: 0.3
13801
+ },
13802
+ idCardBack: {
13803
+ desktop: 0,
13804
+ mobile: 0.3
13805
+ },
13806
+ passport: {
13807
+ desktop: 0,
13808
+ mobile: 0.3
13809
+ },
13810
+ singlePage: {
13811
+ desktop: 0,
13812
+ mobile: 0.3
13813
+ }
13814
+ };
13815
+ var classifier$1 = null;
13816
+ var classifierSettings$1 = null;
13817
+ function loadFocusModel() {
13818
+ return __awaiter(this, arguments, void 0, function (modelAssetPath) {
13819
+ var _a, _b;
13820
+ if (modelAssetPath === void 0) {
13821
+ modelAssetPath = defaultFocusModelPath;
13822
+ }
13823
+ return __generator(this, function (_c) {
13824
+ switch (_c.label) {
13825
+ case 0:
13826
+ if (classifier$1 && (classifierSettings$1 === null || classifierSettings$1 === void 0 ? void 0 : classifierSettings$1.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier$1];
13827
+ closeFocusModel();
13828
+ return [4 /*yield*/, preloadFocusModelDependencies()];
13829
+ case 1:
13830
+ _c.sent();
13831
+ if (modelCapabilities.delegate === 'NONE') {
13832
+ throw new Error('No available delegate for focus detector.');
13833
+ }
13834
+ _b = (_a = Ua).createFromOptions;
13835
+ return [4 /*yield*/, ao.forVisionTasks(visionTasksBasePath)];
13836
+ case 2:
13837
+ return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
13838
+ baseOptions: {
13839
+ modelAssetPath: modelAssetPath,
13840
+ delegate: modelCapabilities.delegate
13841
+ },
13842
+ // canvas: document.createElement('canvas'),
13843
+ runningMode: 'VIDEO'
13844
+ }])];
13845
+ case 3:
13846
+ classifier$1 = _c.sent();
13847
+ classifierSettings$1 = {
13848
+ modelAssetPath: modelAssetPath
13849
+ };
13850
+ return [2 /*return*/, classifier$1];
13851
+ }
13852
+ });
13853
+ });
13854
+ }
13855
+ function closeFocusModel() {
13856
+ classifier$1 === null || classifier$1 === void 0 ? void 0 : classifier$1.close();
13857
+ classifier$1 = null;
13858
+ classifierSettings$1 = null;
13859
+ }
13860
+ function useLoadFocusModel(_a) {
13861
+ var _b = _a.modelPath,
13862
+ modelPath = _b === void 0 ? defaultFocusModelPath : _b,
13863
+ _c = _a.modelLoadTimeoutMs,
13864
+ modelLoadTimeoutMs = _c === void 0 ? defaultFocusModelLoadTimeoutMs : _c,
13865
+ onModelError = _a.onModelError,
13866
+ videoRef = _a.videoRef,
13867
+ _d = _a.shouldLoadModels,
13868
+ shouldLoadModels = _d === void 0 ? true : _d;
13869
+ var _e = React.useState('not-started'),
13870
+ modelLoadState = _e[0],
13871
+ setModelLoadState = _e[1];
13872
+ var _f = React.useState(0),
13873
+ modelDownloadProgress = _f[0],
13874
+ setModelDownloadProgress = _f[1];
13875
+ var _g = React.useState(null),
13876
+ modelWarmingStartedAt = _g[0],
13877
+ setModelWarmingStartedAt = _g[1];
13878
+ var _h = React.useState(null),
13879
+ modelError = _h[0],
13880
+ setModelError = _h[1];
13881
+ React.useEffect(function loadModel() {
13882
+ var _this = this;
13883
+ if (!shouldLoadModels) return;
13884
+ setModelLoadState('downloading');
13885
+ setModelWarmingStartedAt(null);
13886
+ function handleDownloadProgress(event) {
13887
+ setModelDownloadProgress(progressToPercentage(event.detail));
13888
+ }
13889
+ document.addEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
13890
+ var modelLoadTimeout = setTimeout(function () {
13891
+ setModelError(new Error('Model loading time limit exceeded.'));
13892
+ }, modelLoadTimeoutMs);
13893
+ var cancelVideoReady = function cancelVideoReady() {};
13894
+ loadFocusModel(modelPath).then(function (loadedModel) {
13895
+ return __awaiter(_this, void 0, void 0, function () {
13896
+ var _a, videoReady, cancel, cancelled;
13897
+ return __generator(this, function (_b) {
13898
+ switch (_b.label) {
13899
+ case 0:
13900
+ setModelDownloadProgress(100);
13901
+ clearTimeout(modelLoadTimeout);
13902
+ setModelLoadState('warming');
13903
+ setModelWarmingStartedAt(performance.now());
13904
+ _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
13905
+ cancelled = false;
13906
+ cancelVideoReady = function cancelVideoReady() {
13907
+ cancelled = true;
13908
+ cancel();
13909
+ };
13910
+ return [4 /*yield*/, videoReady];
13911
+ case 1:
13912
+ _b.sent();
13913
+ setTimeout(function () {
13914
+ if (cancelled) return;
13915
+ loadedModel.classifyForVideo(videoRef.current, performance.now());
13916
+ setModelLoadState('ready');
13917
+ }, 500);
13918
+ return [2 /*return*/];
13919
+ }
13920
+ });
13921
+ });
13922
+ })["catch"](function (e) {
13923
+ setModelError(e);
13924
+ setModelLoadState('error');
13925
+ })["finally"](function () {
13926
+ clearTimeout(modelLoadTimeout);
13927
+ });
13928
+ return function () {
13929
+ log('unloading focus model');
13930
+ cancelVideoReady();
13931
+ closeFocusModel();
13932
+ clearTimeout(modelLoadTimeout);
13933
+ document.removeEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
13934
+ };
13935
+ }, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
13936
+ React.useEffect(function handleModelError() {
13937
+ if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
13938
+ }, [modelError, onModelError]);
13939
+ return React.useMemo(function () {
13940
+ return {
13941
+ ready: modelLoadState === 'ready',
13942
+ modelLoadState: modelLoadState,
13943
+ modelDownloadProgress: modelDownloadProgress,
13944
+ modelWarmingStartedAt: modelWarmingStartedAt,
13945
+ modelError: modelError
13946
+ };
13947
+ }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
13948
+ }
13949
+ var lastFocusPredictionAt = 0;
13950
+ var lastFocusPredictionTime = 0;
13951
+ function setLastFocusPredictionAt(time) {
13952
+ lastFocusPredictionTime = time - lastFocusPredictionAt;
13953
+ lastFocusPredictionAt = time;
13954
+ }
13955
+ function makeFocusModelPrediction(imageData, cropCanvas, rotateCanvas, box) {
13956
+ var _a, _b, _c, _d, _e;
13957
+ if (!classifier$1) return null;
13958
+ var startedAt = performance.now();
13959
+ var image = cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box);
13960
+ var result = classifier$1.classifyForVideo(image, performance.now());
13961
+ var score = (_e = (_d = (_c = (_b = (_a = result === null || result === void 0 ? void 0 : result.classifications) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.categories) === null || _c === void 0 ? void 0 : _c.find(function (c) {
13962
+ return c.categoryName === 'focused';
13963
+ })) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
13964
+ var predictionTime = performance.now() - startedAt;
13965
+ return {
13966
+ score: score,
13967
+ predictionTime: predictionTime
13968
+ };
13969
+ }
13970
+
13971
+ var FocusModelContext = /*#__PURE__*/React.createContext({
13972
+ loadFocusModel: function loadFocusModel() {
13973
+ return null;
13974
+ },
13975
+ focusModelState: 'not-started',
13976
+ focusModelDownloadProgress: 0,
13977
+ focusModelWarmingStartedAt: null,
14266
13978
  focusModelError: null,
14267
13979
  focusThresholds: {},
14268
13980
  setFocusThresholds: function setFocusThresholds() {
@@ -14330,7 +14042,7 @@
14330
14042
  }, [focusThresholds, load, makeFocusPrediction, modelDownloadProgress, modelError, modelLoadState, modelWarmingStartedAt]);
14331
14043
  return /*#__PURE__*/React.createElement(FocusModelContext.Provider, {
14332
14044
  value: value
14333
- }, /*#__PURE__*/React.createElement(InvisibleCanvas, {
14045
+ }, /*#__PURE__*/React.createElement(InvisibleCanvasContainer, null, /*#__PURE__*/React.createElement(InvisibleCanvas, {
14334
14046
  ref: rotateCanvas,
14335
14047
  style: showCanvases ? {
14336
14048
  display: 'block'
@@ -14340,7 +14052,7 @@
14340
14052
  style: showCanvases ? {
14341
14053
  display: 'block'
14342
14054
  } : undefined
14343
- }), children);
14055
+ })), children);
14344
14056
  }
14345
14057
 
14346
14058
  function _isNavigatorDefined() {
@@ -14375,23 +14087,276 @@
14375
14087
  return false;
14376
14088
  }
14377
14089
 
14378
- var onMobile = isMobile();
14379
- var defaultIdCaptureThresholds = {
14380
- detection: defaultDocumentDetectionThresholds,
14381
- focus: defaultFocusThresholds
14382
- };
14383
- var IdCaptureModelsContext = /*#__PURE__*/React.createContext({
14384
- ready: false,
14385
- start: function start() {
14386
- return null;
14387
- },
14388
- stop: function stop() {
14389
- return null;
14390
- },
14391
- load: function load() {
14392
- return null;
14393
- },
14394
- modelDownloadProgress: 0,
14090
+ var defaultBarcodeReadabilityModelLoadTimeoutMs = 45000;
14091
+ var classifier = null;
14092
+ var classifierSettings = null;
14093
+ function loadBarcodeReadabilityModel() {
14094
+ return __awaiter(this, arguments, void 0, function (modelAssetPath) {
14095
+ var _a, _b;
14096
+ if (modelAssetPath === void 0) {
14097
+ modelAssetPath = defaultBarcodeReadabilityModelPath;
14098
+ }
14099
+ return __generator(this, function (_c) {
14100
+ switch (_c.label) {
14101
+ case 0:
14102
+ if (classifier && (classifierSettings === null || classifierSettings === void 0 ? void 0 : classifierSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier];
14103
+ closeBarcodeReadabilityModel();
14104
+ return [4 /*yield*/, preloadBarcodeReadabilityModelDependencies()];
14105
+ case 1:
14106
+ _c.sent();
14107
+ if (modelCapabilities.delegate === 'NONE') {
14108
+ throw new Error('No available delegate for barcode readability model.');
14109
+ }
14110
+ _b = (_a = Ua).createFromOptions;
14111
+ return [4 /*yield*/, ao.forVisionTasks(visionTasksBasePath)];
14112
+ case 2:
14113
+ return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
14114
+ baseOptions: {
14115
+ modelAssetPath: modelAssetPath,
14116
+ delegate: 'CPU'
14117
+ },
14118
+ runningMode: 'VIDEO',
14119
+ maxResults: 1
14120
+ }])];
14121
+ case 3:
14122
+ classifier = _c.sent();
14123
+ classifierSettings = {
14124
+ modelAssetPath: modelAssetPath
14125
+ };
14126
+ return [2 /*return*/, classifier];
14127
+ }
14128
+ });
14129
+ });
14130
+ }
14131
+ function closeBarcodeReadabilityModel() {
14132
+ classifier === null || classifier === void 0 ? void 0 : classifier.close();
14133
+ classifier = null;
14134
+ classifierSettings = null;
14135
+ }
14136
+ function useLoadBarcodeReadabilityModel(_a) {
14137
+ var _b = _a.modelPath,
14138
+ modelPath = _b === void 0 ? defaultBarcodeReadabilityModelPath : _b,
14139
+ _c = _a.modelLoadTimeoutMs,
14140
+ modelLoadTimeoutMs = _c === void 0 ? defaultBarcodeReadabilityModelLoadTimeoutMs : _c,
14141
+ onModelError = _a.onModelError,
14142
+ videoRef = _a.videoRef,
14143
+ _d = _a.shouldLoadModels,
14144
+ shouldLoadModels = _d === void 0 ? true : _d;
14145
+ var _e = React.useState('not-started'),
14146
+ modelLoadState = _e[0],
14147
+ setModelLoadState = _e[1];
14148
+ var _f = React.useState(0),
14149
+ modelDownloadProgress = _f[0],
14150
+ setModelDownloadProgress = _f[1];
14151
+ var _g = React.useState(null),
14152
+ modelWarmingStartedAt = _g[0],
14153
+ setModelWarmingStartedAt = _g[1];
14154
+ var _h = React.useState(null),
14155
+ modelError = _h[0],
14156
+ setModelError = _h[1];
14157
+ React.useEffect(function loadModel() {
14158
+ var _this = this;
14159
+ if (!shouldLoadModels) return;
14160
+ setModelLoadState('downloading');
14161
+ setModelWarmingStartedAt(null);
14162
+ function handleDownloadProgress(event) {
14163
+ setModelDownloadProgress(progressToPercentage(event.detail));
14164
+ }
14165
+ document.addEventListener('idmission.preloadProgress.barcodeReadability', handleDownloadProgress);
14166
+ var modelLoadTimeout = setTimeout(function () {
14167
+ setModelError(new Error('Model loading time limit exceeded.'));
14168
+ }, modelLoadTimeoutMs);
14169
+ var cancelVideoReady = function cancelVideoReady() {};
14170
+ loadBarcodeReadabilityModel(modelPath).then(function (loadedModel) {
14171
+ return __awaiter(_this, void 0, void 0, function () {
14172
+ var _a, videoReady, cancel, cancelled;
14173
+ return __generator(this, function (_b) {
14174
+ switch (_b.label) {
14175
+ case 0:
14176
+ setModelDownloadProgress(100);
14177
+ clearTimeout(modelLoadTimeout);
14178
+ setModelLoadState('warming');
14179
+ setModelWarmingStartedAt(new Date().getTime());
14180
+ _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
14181
+ cancelled = false;
14182
+ cancelVideoReady = function cancelVideoReady() {
14183
+ cancelled = true;
14184
+ cancel();
14185
+ };
14186
+ return [4 /*yield*/, videoReady];
14187
+ case 1:
14188
+ _b.sent();
14189
+ setTimeout(function () {
14190
+ if (cancelled) return;
14191
+ loadedModel.classifyForVideo(videoRef.current, performance.now());
14192
+ setModelLoadState('ready');
14193
+ }, 500);
14194
+ return [2 /*return*/];
14195
+ }
14196
+ });
14197
+ });
14198
+ })["catch"](function (e) {
14199
+ setModelError(e);
14200
+ setModelLoadState('error');
14201
+ })["finally"](function () {
14202
+ clearTimeout(modelLoadTimeout);
14203
+ });
14204
+ return function () {
14205
+ log('unloading barcode readability model');
14206
+ cancelVideoReady();
14207
+ closeBarcodeReadabilityModel();
14208
+ clearTimeout(modelLoadTimeout);
14209
+ document.removeEventListener('idmission.preloadProgress.barcodeReadability', handleDownloadProgress);
14210
+ };
14211
+ }, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
14212
+ React.useEffect(function handleModelError() {
14213
+ if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
14214
+ }, [modelError, onModelError]);
14215
+ return React.useMemo(function () {
14216
+ return {
14217
+ ready: modelLoadState === 'ready',
14218
+ modelLoadState: modelLoadState,
14219
+ modelDownloadProgress: modelDownloadProgress,
14220
+ modelWarmingStartedAt: modelWarmingStartedAt,
14221
+ modelError: modelError
14222
+ };
14223
+ }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
14224
+ }
14225
+ var lastBarcodeReadabilityPredictionAt = 0;
14226
+ var lastBarcodeReadabilityPredictionTime = 0;
14227
+ function setLastBarcodeReadabilityPredictionAt(time) {
14228
+ lastBarcodeReadabilityPredictionTime = time - lastBarcodeReadabilityPredictionAt;
14229
+ lastBarcodeReadabilityPredictionAt = time;
14230
+ }
14231
+ function makeBarcodeReadabilityModelPrediction(imageData, cropCanvas, rotateCanvas, resizeCanvas, box) {
14232
+ var _a, _b, _c, _d, _e;
14233
+ if (!classifier) return null;
14234
+ var startedAt = performance.now();
14235
+ var image = cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box);
14236
+ var resized = resizeIfNecessary(image, resizeCanvas, 500);
14237
+ var result = classifier.classifyForVideo(resized, performance.now());
14238
+ var score = (_e = (_d = (_c = (_b = (_a = result === null || result === void 0 ? void 0 : result.classifications) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.categories) === null || _c === void 0 ? void 0 : _c.find(function (c) {
14239
+ return c.categoryName === 'blurry';
14240
+ })) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
14241
+ debug('barcode prediction', "".concat(performance.now() - startedAt, "ms"), score);
14242
+ var predictionTime = performance.now() - startedAt;
14243
+ return {
14244
+ score: score,
14245
+ predictionTime: predictionTime
14246
+ };
14247
+ }
14248
+
14249
+ var BarcodeReadabilityModelContext = /*#__PURE__*/React.createContext({
14250
+ loadBarcodeReadabilityModel: function loadBarcodeReadabilityModel() {
14251
+ return null;
14252
+ },
14253
+ barcodeReadabilityModelState: 'not-started',
14254
+ barcodeReadabilityModelDownloadProgress: 0,
14255
+ barcodeReadabilityModelWarmingStartedAt: null,
14256
+ barcodeReadabilityModelError: null,
14257
+ barcodeReadabilityThresholds: {},
14258
+ setBarcodeReadabilityThresholds: function setBarcodeReadabilityThresholds() {
14259
+ return null;
14260
+ },
14261
+ makeBarcodeReadabilityPrediction: function makeBarcodeReadabilityPrediction() {
14262
+ return null;
14263
+ },
14264
+ barcodeReadabilityPredictionTime: 0
14265
+ });
14266
+ function BarcodeReadabilityModelProvider(_a) {
14267
+ var children = _a.children,
14268
+ _b = _a.barcodeReadabilityModelPath,
14269
+ barcodeReadabilityModelPath = _b === void 0 ? defaultBarcodeReadabilityModelPath : _b,
14270
+ _c = _a.barcodeReadabilityModelLoadTimeoutMs,
14271
+ barcodeReadabilityModelLoadTimeoutMs = _c === void 0 ? defaultBarcodeReadabilityModelLoadTimeoutMs : _c,
14272
+ onBarcodeReadabilityModelError = _a.onBarcodeReadabilityModelError,
14273
+ _d = _a.showCanvases,
14274
+ showCanvases = _d === void 0 ? false : _d,
14275
+ _e = _a.shouldLoadModels,
14276
+ shouldLoadModelsProp = _e === void 0 ? true : _e;
14277
+ var cropCanvas = React.useRef(null);
14278
+ var rotateCanvas = React.useRef(null);
14279
+ var resizeCanvas = React.useRef(null);
14280
+ var _f = React.useState({}),
14281
+ barcodeReadabilityThresholds = _f[0],
14282
+ setBarcodeReadabilityThresholds = _f[1];
14283
+ var videoRef = useCameraStore().videoRef;
14284
+ var _g = React.useState(shouldLoadModelsProp),
14285
+ shouldLoadModels = _g[0],
14286
+ setShouldLoadModels = _g[1];
14287
+ var load = React.useCallback(function () {
14288
+ return setShouldLoadModels(true);
14289
+ }, []);
14290
+ var _h = useLoadBarcodeReadabilityModel({
14291
+ modelPath: barcodeReadabilityModelPath,
14292
+ modelLoadTimeoutMs: barcodeReadabilityModelLoadTimeoutMs,
14293
+ onModelError: onBarcodeReadabilityModelError,
14294
+ videoRef: videoRef,
14295
+ shouldLoadModels: shouldLoadModels
14296
+ }),
14297
+ ready = _h.ready,
14298
+ modelLoadState = _h.modelLoadState,
14299
+ modelDownloadProgress = _h.modelDownloadProgress,
14300
+ modelWarmingStartedAt = _h.modelWarmingStartedAt,
14301
+ modelError = _h.modelError;
14302
+ var makeBarcodeReadabilityPrediction = React.useCallback(function (imageData, box) {
14303
+ if (!ready) return null;
14304
+ var prediction = makeBarcodeReadabilityModelPrediction(imageData, cropCanvas.current, rotateCanvas.current, resizeCanvas.current, box);
14305
+ if (!prediction) return null;
14306
+ setLastBarcodeReadabilityPredictionAt(prediction.predictionTime);
14307
+ return prediction;
14308
+ }, [ready]);
14309
+ var value = React.useMemo(function () {
14310
+ return {
14311
+ loadBarcodeReadabilityModel: load,
14312
+ barcodeReadabilityModelState: modelLoadState,
14313
+ barcodeReadabilityModelDownloadProgress: modelDownloadProgress,
14314
+ barcodeReadabilityModelWarmingStartedAt: modelWarmingStartedAt,
14315
+ barcodeReadabilityModelError: modelError,
14316
+ makeBarcodeReadabilityPrediction: makeBarcodeReadabilityPrediction,
14317
+ barcodeReadabilityPredictionTime: lastBarcodeReadabilityPredictionTime,
14318
+ barcodeReadabilityThresholds: barcodeReadabilityThresholds,
14319
+ setBarcodeReadabilityThresholds: setBarcodeReadabilityThresholds
14320
+ };
14321
+ }, [barcodeReadabilityThresholds, load, makeBarcodeReadabilityPrediction, modelDownloadProgress, modelError, modelLoadState, modelWarmingStartedAt]);
14322
+ return /*#__PURE__*/React.createElement(BarcodeReadabilityModelContext.Provider, {
14323
+ value: value
14324
+ }, /*#__PURE__*/React.createElement(InvisibleCanvasContainer, null, /*#__PURE__*/React.createElement(InvisibleCanvas, {
14325
+ ref: rotateCanvas
14326
+ }), /*#__PURE__*/React.createElement(InvisibleCanvas, {
14327
+ ref: cropCanvas
14328
+ }), /*#__PURE__*/React.createElement(InvisibleCanvas, {
14329
+ ref: resizeCanvas,
14330
+ style: showCanvases ? {
14331
+ display: 'block'
14332
+ } : undefined
14333
+ })), children);
14334
+ }
14335
+ function useBarcodeReadabilityModelContext() {
14336
+ var context = React.useContext(BarcodeReadabilityModelContext);
14337
+ if (!context) {
14338
+ throw new Error('useBarcodeReadabilityModelContext must be used within an BarcodeReadabilityModelProvider');
14339
+ }
14340
+ return context;
14341
+ }
14342
+
14343
+ var onMobile = isMobile();
14344
+ var defaultIdCaptureThresholds = {
14345
+ detection: defaultDocumentDetectionThresholds,
14346
+ focus: defaultFocusThresholds
14347
+ };
14348
+ var IdCaptureModelsContext = /*#__PURE__*/React.createContext({
14349
+ ready: false,
14350
+ start: function start() {
14351
+ return null;
14352
+ },
14353
+ stop: function stop() {
14354
+ return null;
14355
+ },
14356
+ load: function load() {
14357
+ return null;
14358
+ },
14359
+ modelDownloadProgress: 0,
14395
14360
  modelLoadState: 'not-started',
14396
14361
  modelWarmingStartedAt: null,
14397
14362
  modelError: null,
@@ -14408,6 +14373,7 @@
14408
14373
  },
14409
14374
  detectionTime: 0,
14410
14375
  focusPredictionTime: 0,
14376
+ barcodeReadabilityPredictionTime: 0,
14411
14377
  bestFrameDetails: {
14412
14378
  current: null
14413
14379
  },
@@ -14417,55 +14383,78 @@
14417
14383
  resetBestFrame: function resetBestFrame() {
14418
14384
  return null;
14419
14385
  },
14386
+ bestBarcodeDetails: {
14387
+ current: null
14388
+ },
14389
+ getBestBarcode: function getBestBarcode() {
14390
+ return null;
14391
+ },
14420
14392
  requiredDocumentType: 'none',
14421
14393
  setRequiredDocumentType: function setRequiredDocumentType() {
14422
14394
  return null;
14423
14395
  }
14424
14396
  });
14425
14397
  function IdCaptureModelsProviderInner(_a) {
14398
+ var _b;
14426
14399
  var children = _a.children,
14427
14400
  onModelError = _a.onModelError,
14428
- _b = _a.allowSinglePageIdCapture,
14429
- allowSinglePageIdCapture = _b === void 0 ? false : _b;
14430
- var _c = React.useContext(DocumentDetectionModelContext),
14431
- documentDetectionModelState = _c.documentDetectionModelState,
14432
- documentDetectionModelDownloadProgress = _c.documentDetectionModelDownloadProgress,
14433
- documentDetectionModelWarmingStartedAt = _c.documentDetectionModelWarmingStartedAt,
14434
- startDocumentDetection = _c.startDocumentDetection,
14435
- stopDocumentDetection = _c.stopDocumentDetection,
14436
- loadDocumentDetectionModel = _c.loadDocumentDetectionModel,
14437
- lastPredictionCanvas = _c.documentDetectionLastPredictionCanvas,
14438
- clearDocumentDetectionLastPredictionCanvas = _c.clearDocumentDetectionLastPredictionCanvas,
14439
- onDocumentDetected = _c.onDocumentDetected,
14440
- detectionTime = _c.detectionTime,
14441
- documentDetectionThresholds = _c.documentDetectionThresholds,
14442
- setDocumentDetectionThresholds = _c.setDocumentDetectionThresholds,
14443
- documentDetectionBoundaries = _c.documentDetectionBoundaries,
14444
- setDocumentDetectionBoundaries = _c.setDocumentDetectionBoundaries,
14445
- documentDetectionModelError = _c.documentDetectionModelError;
14446
- var _d = React.useContext(FocusModelContext),
14447
- loadFocusModel = _d.loadFocusModel,
14448
- focusModelState = _d.focusModelState,
14449
- focusModelDownloadProgress = _d.focusModelDownloadProgress,
14450
- focusModelWarmingStartedAt = _d.focusModelWarmingStartedAt,
14451
- makeFocusPrediction = _d.makeFocusPrediction,
14452
- focusThresholds = _d.focusThresholds,
14453
- setFocusThresholds = _d.setFocusThresholds,
14454
- focusPredictionTime = _d.focusPredictionTime,
14455
- focusModelError = _d.focusModelError;
14401
+ _c = _a.allowSinglePageIdCapture,
14402
+ allowSinglePageIdCapture = _c === void 0 ? false : _c,
14403
+ _d = _a.enableBarcodeReadabilityModel,
14404
+ enableBarcodeReadabilityModel = _d === void 0 ? true : _d;
14405
+ var _e = React.useContext(DocumentDetectionModelContext),
14406
+ documentDetectionModelState = _e.documentDetectionModelState,
14407
+ documentDetectionModelDownloadProgress = _e.documentDetectionModelDownloadProgress,
14408
+ documentDetectionModelWarmingStartedAt = _e.documentDetectionModelWarmingStartedAt,
14409
+ startDocumentDetection = _e.startDocumentDetection,
14410
+ stopDocumentDetection = _e.stopDocumentDetection,
14411
+ loadDocumentDetectionModel = _e.loadDocumentDetectionModel,
14412
+ lastPredictionCanvas = _e.documentDetectionLastPredictionCanvas,
14413
+ clearDocumentDetectionLastPredictionCanvas = _e.clearDocumentDetectionLastPredictionCanvas,
14414
+ onDocumentDetected = _e.onDocumentDetected,
14415
+ detectionTime = _e.detectionTime,
14416
+ documentDetectionThresholds = _e.documentDetectionThresholds,
14417
+ setDocumentDetectionThresholds = _e.setDocumentDetectionThresholds,
14418
+ documentDetectionBoundaries = _e.documentDetectionBoundaries,
14419
+ setDocumentDetectionBoundaries = _e.setDocumentDetectionBoundaries,
14420
+ documentDetectionModelError = _e.documentDetectionModelError;
14421
+ var _f = React.useContext(FocusModelContext),
14422
+ loadFocusModel = _f.loadFocusModel,
14423
+ focusModelState = _f.focusModelState,
14424
+ focusModelDownloadProgress = _f.focusModelDownloadProgress,
14425
+ focusModelWarmingStartedAt = _f.focusModelWarmingStartedAt,
14426
+ makeFocusPrediction = _f.makeFocusPrediction,
14427
+ focusThresholds = _f.focusThresholds,
14428
+ setFocusThresholds = _f.setFocusThresholds,
14429
+ focusPredictionTime = _f.focusPredictionTime,
14430
+ focusModelError = _f.focusModelError;
14431
+ var _g = useBarcodeReadabilityModelContext(),
14432
+ loadBarcodeReadabilityModel = _g.loadBarcodeReadabilityModel,
14433
+ barcodeReadabilityModelState = _g.barcodeReadabilityModelState,
14434
+ barcodeReadabilityModelDownloadProgress = _g.barcodeReadabilityModelDownloadProgress,
14435
+ barcodeReadabilityModelWarmingStartedAt = _g.barcodeReadabilityModelWarmingStartedAt,
14436
+ makeBarcodeReadabilityPrediction = _g.makeBarcodeReadabilityPrediction,
14437
+ barcodeReadabilityThresholds = _g.barcodeReadabilityThresholds,
14438
+ setBarcodeReadabilityThresholds = _g.setBarcodeReadabilityThresholds,
14439
+ barcodeReadabilityPredictionTime = _g.barcodeReadabilityPredictionTime,
14440
+ barcodeReadabilityModelError = _g.barcodeReadabilityModelError;
14456
14441
  var onPredictionHandler = React.useRef();
14457
14442
  var bestFrameDetails = React.useRef(null);
14443
+ var bestBarcodeDetails = React.useRef(null);
14458
14444
  var bestPredictionCanvas = React.useRef(null);
14445
+ var bestBarcodeCanvas = React.useRef(null);
14459
14446
  var bestFocusScore = React.useRef(0);
14447
+ var bestBarcodeScore = React.useRef(0);
14460
14448
  var stopDetection = React.useRef(0);
14461
- var _e = React.useState('none'),
14462
- requiredDocumentType = _e[0],
14463
- setRequiredDocumentType = _e[1];
14449
+ var _h = React.useState('none'),
14450
+ requiredDocumentType = _h[0],
14451
+ setRequiredDocumentType = _h[1];
14464
14452
  var thresholds = React.useMemo(function () {
14465
14453
  return _assign(_assign({}, documentDetectionThresholds), {
14466
- focus: focusThresholds
14454
+ focus: focusThresholds,
14455
+ barcodeReadability: barcodeReadabilityThresholds
14467
14456
  });
14468
- }, [documentDetectionThresholds, focusThresholds]);
14457
+ }, [documentDetectionThresholds, focusThresholds, barcodeReadabilityThresholds]);
14469
14458
  var setThresholds = React.useCallback(function (thresholds) {
14470
14459
  if (thresholds.detection) {
14471
14460
  setDocumentDetectionThresholds(thresholds.detection);
@@ -14473,17 +14462,20 @@
14473
14462
  if (thresholds.focus) {
14474
14463
  setFocusThresholds(thresholds.focus);
14475
14464
  }
14476
- }, [setDocumentDetectionThresholds, setFocusThresholds]);
14465
+ if (thresholds.barcodeReadability) {
14466
+ setBarcodeReadabilityThresholds(thresholds.barcodeReadability);
14467
+ }
14468
+ }, [setBarcodeReadabilityThresholds, setDocumentDetectionThresholds, setFocusThresholds]);
14477
14469
  React.useEffect(function handleDetections() {
14478
14470
  var _this = this;
14479
14471
  onDocumentDetected(function (prediction) {
14480
14472
  return __awaiter(_this, void 0, void 0, function () {
14481
- var stopDetectionAtStart, focusPredictionTime, focusScore, focusThresholdMet, isSinglePage, isRequiredDocumentType, focusPrediction, focusThresholdSet, focusThreshold;
14482
- var _a, _b, _c, _d, _e, _f, _g;
14483
- return __generator(this, function (_h) {
14473
+ var stopDetectionAtStart, focusPredictionTime, focusScore, focusThresholdMet, pdf417PredictionTime, pdf417PredictionScore, pdf417PredictionThresholdMet, isSinglePage, isRequiredDocumentType, focusPrediction, focusThresholdSet, focusThreshold, pdf417Prediction, barcodeReadabilityThresholdSet, barcodeReadabilityThreshold;
14474
+ var _a, _b, _c, _d, _e, _f, _g, _h;
14475
+ return __generator(this, function (_j) {
14484
14476
  if (!lastPredictionCanvas.current) return [2 /*return*/];
14485
14477
  stopDetectionAtStart = stopDetection.current;
14486
- focusPredictionTime = 0, focusScore = 0, focusThresholdMet = false;
14478
+ focusPredictionTime = 0, focusScore = 0, focusThresholdMet = false, pdf417PredictionTime = 0, pdf417PredictionScore = 0, pdf417PredictionThresholdMet = false;
14487
14479
  isSinglePage = prediction.detectedDocumentType === 'singlePage';
14488
14480
  if (!allowSinglePageIdCapture && isSinglePage) {
14489
14481
  prediction.detectedDocumentType = 'passport';
@@ -14502,28 +14494,51 @@
14502
14494
  focusThresholdSet = (_d = thresholds.focus) === null || _d === void 0 ? void 0 : _d[prediction.detectedDocumentType];
14503
14495
  focusThreshold = (_e = onMobile ? focusThresholdSet === null || focusThresholdSet === void 0 ? void 0 : focusThresholdSet.mobile : focusThresholdSet === null || focusThresholdSet === void 0 ? void 0 : focusThresholdSet.desktop) !== null && _e !== void 0 ? _e : 0;
14504
14496
  focusThresholdMet = focusScore >= focusThreshold;
14505
- if (bestFocusScore.current <= focusScore && stopDetectionAtStart === stopDetection.current) {
14506
- bestFocusScore.current = focusScore;
14507
- drawToCanvas(bestPredictionCanvas.current, lastPredictionCanvas.current);
14508
- bestFrameDetails.current = {
14509
- boundingBox: (_f = prediction.bestDocument) === null || _f === void 0 ? void 0 : _f.box,
14510
- documentType: prediction.detectedDocumentType,
14511
- detectionScore: prediction.detectionScore,
14512
- focusScore: focusScore
14513
- };
14497
+ if (stopDetectionAtStart === stopDetection.current) {
14498
+ if (bestFocusScore.current <= focusScore) {
14499
+ bestFocusScore.current = focusScore;
14500
+ drawToCanvas(bestPredictionCanvas.current, lastPredictionCanvas.current);
14501
+ bestFrameDetails.current = {
14502
+ boundingBox: (_f = prediction.bestDocument) === null || _f === void 0 ? void 0 : _f.box,
14503
+ documentType: prediction.detectedDocumentType,
14504
+ detectionScore: prediction.detectionScore,
14505
+ focusScore: focusScore
14506
+ };
14507
+ }
14508
+ if (enableBarcodeReadabilityModel && prediction.bestPDF417) {
14509
+ pdf417Prediction = makeBarcodeReadabilityPrediction(lastPredictionCanvas.current, prediction.bestPDF417.box);
14510
+ if (pdf417Prediction) {
14511
+ pdf417PredictionTime = pdf417Prediction.predictionTime;
14512
+ pdf417PredictionScore = pdf417Prediction.score;
14513
+ if (bestBarcodeScore.current <= pdf417Prediction.score) {
14514
+ bestBarcodeScore.current = pdf417Prediction.score;
14515
+ bestBarcodeDetails.current = {
14516
+ boundingBox: prediction.bestPDF417.box,
14517
+ score: pdf417Prediction.score
14518
+ };
14519
+ drawToCanvas(bestBarcodeCanvas.current, cropToDetectedObjectBox(lastPredictionCanvas.current, prediction.bestPDF417.box, undefined, 16));
14520
+ barcodeReadabilityThresholdSet = barcodeReadabilityThresholds[prediction.detectedDocumentType];
14521
+ barcodeReadabilityThreshold = (_g = onMobile ? barcodeReadabilityThresholdSet === null || barcodeReadabilityThresholdSet === void 0 ? void 0 : barcodeReadabilityThresholdSet.mobile : barcodeReadabilityThresholdSet === null || barcodeReadabilityThresholdSet === void 0 ? void 0 : barcodeReadabilityThresholdSet.desktop) !== null && _g !== void 0 ? _g : 0;
14522
+ pdf417PredictionThresholdMet = pdf417PredictionScore >= barcodeReadabilityThreshold;
14523
+ }
14524
+ }
14525
+ }
14514
14526
  }
14515
14527
  }
14516
- (_g = onPredictionHandler.current) === null || _g === void 0 ? void 0 : _g.call(onPredictionHandler, _assign(_assign({}, prediction), {
14528
+ (_h = onPredictionHandler.current) === null || _h === void 0 ? void 0 : _h.call(onPredictionHandler, _assign(_assign({}, prediction), {
14517
14529
  focusScore: focusScore,
14518
14530
  focusPredictionTime: focusPredictionTime,
14519
- focusThresholdMet: focusThresholdMet
14531
+ focusThresholdMet: focusThresholdMet,
14532
+ pdf417PredictionTime: pdf417PredictionTime,
14533
+ pdf417PredictionScore: pdf417PredictionScore,
14534
+ pdf417PredictionThresholdMet: pdf417PredictionThresholdMet
14520
14535
  }));
14521
14536
  return [2 /*return*/];
14522
14537
  });
14523
14538
  });
14524
14539
  });
14525
- }, [allowSinglePageIdCapture, lastPredictionCanvas, makeFocusPrediction, onDocumentDetected, requiredDocumentType, thresholds.focus]);
14526
- var modelError = documentDetectionModelError !== null && documentDetectionModelError !== void 0 ? documentDetectionModelError : focusModelError;
14540
+ }, [allowSinglePageIdCapture, barcodeReadabilityThresholds, enableBarcodeReadabilityModel, lastPredictionCanvas, makeBarcodeReadabilityPrediction, makeFocusPrediction, onDocumentDetected, requiredDocumentType, thresholds.focus]);
14541
+ var modelError = (_b = documentDetectionModelError !== null && documentDetectionModelError !== void 0 ? documentDetectionModelError : focusModelError) !== null && _b !== void 0 ? _b : barcodeReadabilityModelError;
14527
14542
  React.useEffect(function handleModelErrors() {
14528
14543
  if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
14529
14544
  }, [modelError, onModelError]);
@@ -14536,9 +14551,15 @@
14536
14551
  canvas: bestPredictionCanvas.current
14537
14552
  });
14538
14553
  }, []);
14539
- var _f = React.useState(0),
14540
- canvasKey = _f[0],
14541
- setCanvasKey = _f[1];
14554
+ var getBestBarcode = React.useCallback(function () {
14555
+ if (!bestBarcodeDetails.current || !bestBarcodeCanvas.current) return null;
14556
+ return _assign(_assign({}, bestBarcodeDetails.current), {
14557
+ canvas: bestBarcodeCanvas.current
14558
+ });
14559
+ }, []);
14560
+ var _j = React.useState(0),
14561
+ canvasKey = _j[0],
14562
+ setCanvasKey = _j[1];
14542
14563
  var resetBestFrame = React.useCallback(function () {
14543
14564
  stopDetection.current += 1;
14544
14565
  setCanvasKey(function (n) {
@@ -14554,16 +14575,45 @@
14554
14575
  var load = React.useCallback(function () {
14555
14576
  loadDocumentDetectionModel();
14556
14577
  loadFocusModel();
14557
- }, [loadDocumentDetectionModel, loadFocusModel]);
14558
- var ready = documentDetectionModelState === 'ready' && focusModelState === 'ready';
14559
- var modelLoadState = ready ? 'ready' : documentDetectionModelState === 'warming' || focusModelState === 'warming' ? 'warming' : focusModelState === 'downloading' || documentDetectionModelState === 'downloading' ? 'downloading' : 'not-started';
14560
- var modelWarmingStartedAt = !documentDetectionModelWarmingStartedAt && !focusModelWarmingStartedAt ? null : Math.min.apply(Math, [documentDetectionModelWarmingStartedAt, focusModelWarmingStartedAt].filter(function (v) {
14561
- return v !== null;
14562
- }));
14578
+ if (enableBarcodeReadabilityModel) loadBarcodeReadabilityModel();
14579
+ }, [enableBarcodeReadabilityModel, loadBarcodeReadabilityModel, loadDocumentDetectionModel, loadFocusModel]);
14580
+ var _k = React.useMemo(function () {
14581
+ var modelStates = [documentDetectionModelState, focusModelState];
14582
+ var modelWarmingStartedAts = [documentDetectionModelWarmingStartedAt, focusModelWarmingStartedAt];
14583
+ var modelDownloadProgresses = [documentDetectionModelDownloadProgress, focusModelDownloadProgress];
14584
+ if (enableBarcodeReadabilityModel) {
14585
+ modelStates.push(barcodeReadabilityModelState);
14586
+ modelWarmingStartedAts.push(barcodeReadabilityModelWarmingStartedAt);
14587
+ modelDownloadProgresses.push(barcodeReadabilityModelDownloadProgress);
14588
+ }
14589
+ var ready = modelStates.every(function (state) {
14590
+ return state === 'ready';
14591
+ });
14592
+ return {
14593
+ ready: ready,
14594
+ modelLoadState: ready ? 'ready' : modelStates.some(function (state) {
14595
+ return state === 'warming';
14596
+ }) ? 'warming' : modelStates.some(function (state) {
14597
+ return state === 'downloading';
14598
+ }) ? 'downloading' : 'not-started',
14599
+ modelWarmingStartedAt: modelWarmingStartedAts.every(function (v) {
14600
+ return v === null;
14601
+ }) ? null : Math.min.apply(Math, modelWarmingStartedAts.filter(function (v) {
14602
+ return v !== null;
14603
+ })),
14604
+ modelDownloadProgress: modelDownloadProgresses.reduce(function (a, b) {
14605
+ return a + b;
14606
+ }, 0) / modelDownloadProgresses.length
14607
+ };
14608
+ }, [barcodeReadabilityModelDownloadProgress, barcodeReadabilityModelState, barcodeReadabilityModelWarmingStartedAt, documentDetectionModelDownloadProgress, documentDetectionModelState, documentDetectionModelWarmingStartedAt, enableBarcodeReadabilityModel, focusModelDownloadProgress, focusModelState, focusModelWarmingStartedAt]),
14609
+ ready = _k.ready,
14610
+ modelLoadState = _k.modelLoadState,
14611
+ modelWarmingStartedAt = _k.modelWarmingStartedAt,
14612
+ modelDownloadProgress = _k.modelDownloadProgress;
14563
14613
  var value = React.useMemo(function () {
14564
14614
  return {
14565
14615
  ready: ready,
14566
- modelDownloadProgress: (documentDetectionModelDownloadProgress + focusModelDownloadProgress) / 2,
14616
+ modelDownloadProgress: modelDownloadProgress,
14567
14617
  modelLoadState: modelLoadState,
14568
14618
  modelWarmingStartedAt: modelWarmingStartedAt,
14569
14619
  modelError: modelError,
@@ -14577,24 +14627,32 @@
14577
14627
  onPredictionMade: onPredictionMade,
14578
14628
  detectionTime: detectionTime,
14579
14629
  focusPredictionTime: focusPredictionTime,
14630
+ barcodeReadabilityPredictionTime: barcodeReadabilityPredictionTime,
14580
14631
  getBestFrame: getBestFrame,
14581
14632
  resetBestFrame: resetBestFrame,
14582
14633
  bestFrameDetails: bestFrameDetails,
14634
+ bestBarcodeDetails: bestBarcodeDetails,
14635
+ getBestBarcode: getBestBarcode,
14583
14636
  requiredDocumentType: requiredDocumentType,
14584
14637
  setRequiredDocumentType: setRequiredDocumentType
14585
14638
  };
14586
- }, [detectionTime, documentDetectionBoundaries, documentDetectionModelDownloadProgress, focusModelDownloadProgress, focusPredictionTime, getBestFrame, load, modelLoadState, modelError, modelWarmingStartedAt, onPredictionMade, ready, requiredDocumentType, resetBestFrame, setDocumentDetectionBoundaries, setThresholds, startDocumentDetection, stopDocumentDetection, thresholds]);
14639
+ }, [ready, modelDownloadProgress, modelLoadState, modelWarmingStartedAt, modelError, startDocumentDetection, stopDocumentDetection, load, thresholds, setThresholds, documentDetectionBoundaries, setDocumentDetectionBoundaries, onPredictionMade, detectionTime, focusPredictionTime, barcodeReadabilityPredictionTime, getBestFrame, resetBestFrame, getBestBarcode, requiredDocumentType]);
14587
14640
  return /*#__PURE__*/React.createElement(IdCaptureModelsContext.Provider, {
14588
14641
  value: value
14589
14642
  }, /*#__PURE__*/React.createElement(InvisibleCanvas, {
14590
- key: canvasKey,
14643
+ key: "bf-".concat(canvasKey),
14591
14644
  ref: bestPredictionCanvas
14645
+ }), /*#__PURE__*/React.createElement(InvisibleCanvas, {
14646
+ key: "bb-".concat(canvasKey),
14647
+ ref: bestBarcodeCanvas
14592
14648
  }), children);
14593
14649
  }
14594
14650
  function IdCaptureModelsProvider(_a) {
14595
14651
  var children = _a.children,
14596
14652
  props = __rest(_a, ["children"]);
14597
- return /*#__PURE__*/React.createElement(DocumentDetectionModelProvider, _assign({}, props), /*#__PURE__*/React.createElement(FocusModelProvider, _assign({}, props), /*#__PURE__*/React.createElement(IdCaptureModelsProviderInner, _assign({}, props), children)));
14653
+ return /*#__PURE__*/React.createElement(DocumentDetectionModelProvider, _assign({}, props), /*#__PURE__*/React.createElement(FocusModelProvider, _assign({}, props), /*#__PURE__*/React.createElement(BarcodeReadabilityModelProvider, _assign({}, props, {
14654
+ shouldLoadModels: props.enableBarcodeReadabilityModel
14655
+ }), /*#__PURE__*/React.createElement(IdCaptureModelsProviderInner, _assign({}, props), children))));
14598
14656
  }
14599
14657
  function useIdCaptureModelsContext() {
14600
14658
  var context = React.useContext(IdCaptureModelsContext);
@@ -14687,7 +14745,7 @@
14687
14745
  });
14688
14746
  }
14689
14747
 
14690
- var CapturedDocumentTypeValues = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'selfie', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
14748
+ var CapturedDocumentTypeValues = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'selfie', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage', 'idBarcodeImage'];
14691
14749
 
14692
14750
  var acceptedDocumentTypesForIdCaptureRequirementOption = {
14693
14751
  idCardFront: ['idCardFront'],
@@ -15053,6 +15111,7 @@
15053
15111
  capturing: false,
15054
15112
  captureFailed: false,
15055
15113
  imageUrl: null,
15114
+ idBarcodeImage: null,
15056
15115
  captureState: 'initializing',
15057
15116
  capturedDocuments: {},
15058
15117
  captureRequirement: 'idCardOrPassport',
@@ -15332,6 +15391,17 @@
15332
15391
  }
15333
15392
  return newState;
15334
15393
  }
15394
+ case 'barcodeCaptured':
15395
+ return _reducer(state, {
15396
+ type: 'documentCaptured',
15397
+ payload: {
15398
+ imageData: action.payload.imageUrl,
15399
+ documentType: 'idBarcodeImage',
15400
+ width: 0,
15401
+ height: 0,
15402
+ barcodeReadabilityScore: action.payload.barcodeReadabilityScore
15403
+ }
15404
+ });
15335
15405
  case 'flipRequestCompleted':
15336
15406
  return _assign(_assign({}, state), {
15337
15407
  captureState: 'capturing',
@@ -15823,12 +15893,13 @@
15823
15893
  height = _q === void 0 ? 1 : _q;
15824
15894
  var state = useIdCaptureStore();
15825
15895
  var isRearFacing = useCameraStore().isRearFacing;
15826
- var _r = React.useContext(IdCaptureModelsContext),
15896
+ var _r = useIdCaptureModelsContext(),
15827
15897
  modelsReady = _r.ready,
15828
15898
  setThresholds = _r.setThresholds,
15829
15899
  detectionTime = _r.detectionTime,
15830
15900
  focusPredictionTime = _r.focusPredictionTime,
15831
- getBestFrame = _r.getBestFrame;
15901
+ getBestFrame = _r.getBestFrame,
15902
+ getBestBarcode = _r.getBestBarcode;
15832
15903
  React.useEffect(function () {
15833
15904
  return dispatchIdCaptureAction({
15834
15905
  type: 'captureInitialized'
@@ -15867,6 +15938,16 @@
15867
15938
  });
15868
15939
  return;
15869
15940
  }
15941
+ var bestBarcode = getBestBarcode();
15942
+ if (bestBarcode) {
15943
+ dispatchIdCaptureAction({
15944
+ type: 'barcodeCaptured',
15945
+ payload: {
15946
+ imageUrl: bestBarcode.canvas.toDataURL('image/jpeg', 0.95),
15947
+ barcodeReadabilityScore: bestBarcode.score
15948
+ }
15949
+ });
15950
+ }
15870
15951
  var canvas = bestFrame.canvas,
15871
15952
  documentType = bestFrame.documentType,
15872
15953
  boundingBox = bestFrame.boundingBox,
@@ -15883,21 +15964,22 @@
15883
15964
  });
15884
15965
  var capturedDocumentType = documentType;
15885
15966
  setTimeout(function () {
15886
- var _a;
15887
- var captureTime = new Date().getTime() - ((_a = state.captureStartedAt) !== null && _a !== void 0 ? _a : new Date()).getTime();
15967
+ var _a, _b;
15968
+ var captureTime = performance.now() - ((_a = state.captureStartedAt) !== null && _a !== void 0 ? _a : new Date()).getTime();
15888
15969
  var metadata = {
15889
15970
  autoCapture: 'Y',
15890
15971
  captureTime: captureTime,
15891
15972
  boundingBox: boundingBox,
15892
15973
  bestDetectionScore: detectionScore,
15893
- bestFocusScore: focusScore
15974
+ bestFocusScore: focusScore,
15975
+ bestBarcodeScore: (_b = bestBarcode === null || bestBarcode === void 0 ? void 0 : bestBarcode.score) !== null && _b !== void 0 ? _b : 0
15894
15976
  };
15895
15977
  onCapture === null || onCapture === void 0 ? void 0 : onCapture(imageUrl, width, height, capturedDocumentType, metadata);
15896
15978
  dispatchIdCaptureAction({
15897
15979
  type: 'captured'
15898
15980
  });
15899
15981
  }, 0);
15900
- }, [getBestFrame, onCapture, shouldCapture, state.captureStartedAt, state.requestedDocumentType]);
15982
+ }, [getBestBarcode, getBestFrame, onCapture, shouldCapture, state.captureStartedAt, state.requestedDocumentType]);
15901
15983
  var theme = styled.useTheme();
15902
15984
  colors.guideBoxUnsatisfiedColor || (colors.guideBoxUnsatisfiedColor = (_d = (_c = (_b = theme.idCapture) === null || _b === void 0 ? void 0 : _b.guideBox) === null || _c === void 0 ? void 0 : _c.unsatisfiedColor) !== null && _d !== void 0 ? _d : 'white');
15903
15985
  colors.guideBoxSatisfiedColor || (colors.guideBoxSatisfiedColor = (_g = (_f = (_e = theme.idCapture) === null || _e === void 0 ? void 0 : _e.guideBox) === null || _f === void 0 ? void 0 : _f.satisfiedColor) !== null && _g !== void 0 ? _g : 'green');
@@ -17050,7 +17132,7 @@
17050
17132
  var FlexCard = styled(Card)(templateObject_2$y || (templateObject_2$y = __makeTemplateObject(["\n display: flex;\n flex-direction: column;\n"], ["\n display: flex;\n flex-direction: column;\n"])));
17051
17133
  var templateObject_1$E, templateObject_2$y;
17052
17134
 
17053
- var imageDisplayOrder = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
17135
+ var imageDisplayOrder = ['idCardFront', 'idCardBack', 'idBarcodeImage', 'passport', 'singlePage', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
17054
17136
  var IdCaptureSuccess = function IdCaptureSuccess(_a) {
17055
17137
  var capturedDocuments = _a.capturedDocuments,
17056
17138
  onSubmitClick = _a.onSubmitClick,
@@ -17092,7 +17174,7 @@
17092
17174
  image: doc,
17093
17175
  className: classNames.image,
17094
17176
  alt: doc.documentType
17095
- }), debugMode && ( /*#__PURE__*/React.createElement(DebugPre, null, "Document Type: ".concat(doc.documentType, "\nDetection Score: ").concat(doc.detectionScore, "\nFocus Score: ").concat(doc.focusScore, "\nBounding Box: ").concat(JSON.stringify(doc.boundingBox)))));
17177
+ }), debugMode && ( /*#__PURE__*/React.createElement(DebugPre, null, name === 'idBarcodeImage' ? "Document Type: ".concat(doc.documentType, "\nReadability Score: ").concat(doc.barcodeReadabilityScore) : "Document Type: ".concat(doc.documentType, "\nDetection Score: ").concat(doc.detectionScore, "\nFocus Score: ").concat(doc.focusScore, "\nBounding Box: ").concat(JSON.stringify(doc.boundingBox)))));
17096
17178
  }))), /*#__PURE__*/React.createElement(ButtonsColumn, {
17097
17179
  className: classNames.buttonsRow
17098
17180
  }, /*#__PURE__*/React.createElement(WideButton, {
@@ -19704,7 +19786,7 @@
19704
19786
  var _5 = React.useState(false),
19705
19787
  overlayDismissed = _5[0],
19706
19788
  setOverlayDismissed = _5[1];
19707
- var _6 = React.useContext(SubmissionContext),
19789
+ var _6 = useSubmissionContext(),
19708
19790
  submissionStatus = _6.submissionStatus,
19709
19791
  setIdFrontImage = _6.setIdFrontImage,
19710
19792
  setIdBackImage = _6.setIdBackImage,
@@ -19713,6 +19795,7 @@
19713
19795
  setIdBackIrImage = _6.setIdBackIrImage,
19714
19796
  setIdFrontUvImage = _6.setIdFrontUvImage,
19715
19797
  setIdBackUvImage = _6.setIdBackUvImage,
19798
+ setIdBarcodeImage = _6.setIdBarcodeImage,
19716
19799
  logIdFrontCaptureAttempt = _6.logIdFrontCaptureAttempt,
19717
19800
  logIdBackCaptureAttempt = _6.logIdBackCaptureAttempt;
19718
19801
  var _7 = useIdCaptureModelsContext(),
@@ -19803,7 +19886,7 @@
19803
19886
  });
19804
19887
  }, [logCaptureMetadata, onDocumentCaptured]);
19805
19888
  var onSubmitClick = React.useCallback(function () {
19806
- var _a, _b, _c, _d, _e, _f, _g, _h;
19889
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
19807
19890
  var docs = state.capturedDocuments;
19808
19891
  var submission = {
19809
19892
  idFrontImage: maybeDataUrlToBase64Sync((_a = docs.idCardFront) === null || _a === void 0 ? void 0 : _a.imageData),
@@ -19813,7 +19896,8 @@
19813
19896
  idFrontIrImage: maybeDataUrlToBase64Sync((_e = docs.idFrontIrImage) === null || _e === void 0 ? void 0 : _e.imageData),
19814
19897
  idBackIrImage: maybeDataUrlToBase64Sync((_f = docs.idBackIrImage) === null || _f === void 0 ? void 0 : _f.imageData),
19815
19898
  idFrontUvImage: maybeDataUrlToBase64Sync((_g = docs.idFrontUvImage) === null || _g === void 0 ? void 0 : _g.imageData),
19816
- idBackUvImage: maybeDataUrlToBase64Sync((_h = docs.idBackUvImage) === null || _h === void 0 ? void 0 : _h.imageData)
19899
+ idBackUvImage: maybeDataUrlToBase64Sync((_h = docs.idBackUvImage) === null || _h === void 0 ? void 0 : _h.imageData),
19900
+ idBarcodeImage: maybeDataUrlToBase64Sync((_j = docs.idBarcodeImage) === null || _j === void 0 ? void 0 : _j.imageData)
19817
19901
  };
19818
19902
  if (submission.idFrontImage) setIdFrontImage(submission.idFrontImage);
19819
19903
  if (submission.idBackImage) setIdBackImage(submission.idBackImage);
@@ -19823,11 +19907,12 @@
19823
19907
  if (submission.idBackIrImage) setIdBackIrImage(submission.idBackIrImage);
19824
19908
  if (submission.idFrontUvImage) setIdFrontUvImage(submission.idFrontUvImage);
19825
19909
  if (submission.idBackUvImage) setIdBackUvImage(submission.idBackUvImage);
19910
+ if (submission.idBarcodeImage) setIdBarcodeImage(submission.idBarcodeImage);
19826
19911
  if (releaseCameraAccessOnExit) releaseCameraAccess();
19827
19912
  setTimeout(function () {
19828
19913
  return onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(submission);
19829
19914
  }, 0);
19830
- }, [onSuccess, releaseCameraAccess, releaseCameraAccessOnExit, setIdBackImage, setIdBackIrImage, setIdBackUvImage, setIdFrontImage, setIdFrontIrImage, setIdFrontUvImage, setPassportImage, state.capturedDocuments]);
19915
+ }, [onSuccess, releaseCameraAccess, releaseCameraAccessOnExit, setIdBarcodeImage, setIdBackImage, setIdBackIrImage, setIdBackUvImage, setIdFrontImage, setIdFrontIrImage, setIdFrontUvImage, setPassportImage, state.capturedDocuments]);
19831
19916
  var showSuccessScreen = useShowSuccessScreen(skipSuccessScreen, state.captureState === 'complete', onSubmitClick);
19832
19917
  var onRetryClick = React.useCallback(function () {
19833
19918
  return dispatchIdCaptureAction({
@@ -20671,6 +20756,274 @@
20671
20756
  };
20672
20757
  var templateObject_1$o, templateObject_2$l;
20673
20758
 
20759
+ var defaultSelfieCaptureModelLoadTimeoutMs = 45000;
20760
+ var detector = null;
20761
+ var detectorSettings = null;
20762
+ function loadFaceDetector() {
20763
+ return __awaiter(this, arguments, void 0, function (modelAssetPath) {
20764
+ var _a, _b;
20765
+ if (modelAssetPath === void 0) {
20766
+ modelAssetPath = defaultFaceDetectorModelPath;
20767
+ }
20768
+ return __generator(this, function (_c) {
20769
+ switch (_c.label) {
20770
+ case 0:
20771
+ if (detector && (detectorSettings === null || detectorSettings === void 0 ? void 0 : detectorSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, detector];
20772
+ closeFaceDetector();
20773
+ return [4 /*yield*/, preloadFaceDetectorDependencies()];
20774
+ case 1:
20775
+ _c.sent();
20776
+ if (modelCapabilities.delegate === 'NONE') {
20777
+ throw new Error('No available delegate for face detector.');
20778
+ }
20779
+ _b = (_a = ya).createFromOptions;
20780
+ return [4 /*yield*/, ao.forVisionTasks(visionTasksBasePath)];
20781
+ case 2:
20782
+ return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
20783
+ // canvas: document.createElement('canvas'),
20784
+ baseOptions: {
20785
+ modelAssetPath: modelAssetPath,
20786
+ delegate: modelCapabilities.delegate
20787
+ },
20788
+ runningMode: 'VIDEO'
20789
+ }])];
20790
+ case 3:
20791
+ detector = _c.sent();
20792
+ detectorSettings = {
20793
+ modelAssetPath: modelAssetPath
20794
+ };
20795
+ return [2 /*return*/, detector];
20796
+ }
20797
+ });
20798
+ });
20799
+ }
20800
+ function closeFaceDetector() {
20801
+ detector === null || detector === void 0 ? void 0 : detector.close();
20802
+ detector = null;
20803
+ detectorSettings = null;
20804
+ }
20805
+ function useLoadFaceDetector(_a) {
20806
+ var onModelError = _a.onModelError,
20807
+ _b = _a.modelLoadTimeoutMs,
20808
+ modelLoadTimeoutMs = _b === void 0 ? defaultSelfieCaptureModelLoadTimeoutMs : _b,
20809
+ videoRef = _a.videoRef;
20810
+ var _c = React.useState('not-started'),
20811
+ modelLoadState = _c[0],
20812
+ setModelLoadState = _c[1];
20813
+ var _d = React.useState(0),
20814
+ modelDownloadProgress = _d[0],
20815
+ setModelDownloadProgress = _d[1];
20816
+ var _e = React.useState(null),
20817
+ modelWarmingStartedAt = _e[0],
20818
+ setModelWarmingStartedAt = _e[1];
20819
+ var _f = React.useState(null),
20820
+ modelError = _f[0],
20821
+ setModelError = _f[1];
20822
+ React.useEffect(function loadModel() {
20823
+ var _this = this;
20824
+ setModelLoadState('downloading');
20825
+ setModelWarmingStartedAt(null);
20826
+ var modelLoadTimeout = setTimeout(function () {
20827
+ setModelError(new Error('Model loading time limit exceeded.'));
20828
+ }, modelLoadTimeoutMs);
20829
+ function handleDownloadProgress(event) {
20830
+ setModelDownloadProgress(progressToPercentage(event.detail));
20831
+ }
20832
+ document.addEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
20833
+ var cancelVideoReady = function cancelVideoReady() {};
20834
+ loadFaceDetector().then(function (model) {
20835
+ return __awaiter(_this, void 0, void 0, function () {
20836
+ var _a, videoReady, cancel, cancelled;
20837
+ return __generator(this, function (_b) {
20838
+ switch (_b.label) {
20839
+ case 0:
20840
+ setModelDownloadProgress(100);
20841
+ clearTimeout(modelLoadTimeout);
20842
+ setModelLoadState('warming');
20843
+ setModelWarmingStartedAt(performance.now());
20844
+ return [4 /*yield*/, testFaceDetectionAgainstKnownImage(model)];
20845
+ case 1:
20846
+ _b.sent();
20847
+ _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
20848
+ cancelled = false;
20849
+ cancelVideoReady = function cancelVideoReady() {
20850
+ cancelled = true;
20851
+ cancel();
20852
+ };
20853
+ return [4 /*yield*/, videoReady];
20854
+ case 2:
20855
+ _b.sent();
20856
+ if (cancelled) return [2 /*return*/];
20857
+ model.detectForVideo(videoRef.current, performance.now());
20858
+ setModelLoadState('ready');
20859
+ return [2 /*return*/];
20860
+ }
20861
+ });
20862
+ });
20863
+ })["catch"](function (e) {
20864
+ setModelError(e);
20865
+ setModelLoadState('error');
20866
+ })["finally"](function () {
20867
+ clearTimeout(modelLoadTimeout);
20868
+ });
20869
+ return function () {
20870
+ log('unloading face detection model');
20871
+ cancelVideoReady();
20872
+ closeFaceDetector();
20873
+ clearTimeout(modelLoadTimeout);
20874
+ document.removeEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
20875
+ };
20876
+ }, [modelLoadTimeoutMs, videoRef]);
20877
+ React.useEffect(function handleModelError() {
20878
+ if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
20879
+ }, [modelError, onModelError]);
20880
+ return React.useMemo(function () {
20881
+ return {
20882
+ ready: modelLoadState === 'ready',
20883
+ modelLoadState: modelLoadState,
20884
+ modelDownloadProgress: modelDownloadProgress,
20885
+ modelWarmingStartedAt: modelWarmingStartedAt,
20886
+ modelError: modelError
20887
+ };
20888
+ }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
20889
+ }
20890
+ var lastFaceDetectionAt = 0;
20891
+ var lastFaceDetectionTime = 0;
20892
+ function setLastFaceDetectionAt(time) {
20893
+ lastFaceDetectionTime = time - lastFaceDetectionAt;
20894
+ lastFaceDetectionAt = time;
20895
+ }
20896
+ var framesNeededSamples = [];
20897
+ function trackFramesNeeded(value, bufferLength) {
20898
+ if (bufferLength === void 0) {
20899
+ bufferLength = 25;
20900
+ }
20901
+ framesNeededSamples.unshift(value);
20902
+ if (framesNeededSamples.length > bufferLength) framesNeededSamples.length = bufferLength;
20903
+ }
20904
+ var lastNFaces = [];
20905
+ var lastNPairs = [];
20906
+ function trackFace(face, framesNeeded) {
20907
+ if (framesNeeded === void 0) {
20908
+ framesNeeded = 12;
20909
+ }
20910
+ lastNFaces.unshift(face);
20911
+ if (lastNFaces.length > framesNeeded) lastNFaces.length = framesNeeded;
20912
+ if (lastNFaces.length > 1) {
20913
+ var lastFace = lastNFaces[1];
20914
+ var iou = calculateIoU(face.box, lastFace.box);
20915
+ lastNPairs.unshift({
20916
+ a: face,
20917
+ b: lastFace,
20918
+ iou: iou
20919
+ });
20920
+ if (lastNPairs.length > framesNeeded - 1) lastNPairs.length = framesNeeded - 1;
20921
+ }
20922
+ }
20923
+ function makeFaceDetectorPrediction(imageData) {
20924
+ if (!detector) return null;
20925
+ var prediction = detector.detectForVideo(imageData, performance.now());
20926
+ var faces = prediction.detections.map(function (d) {
20927
+ return {
20928
+ box: convertBoundingBox(d.boundingBox),
20929
+ keypoints: d.keypoints.map(function (k) {
20930
+ var _a;
20931
+ return _assign(_assign({}, k), {
20932
+ x: k.x * imageData.width,
20933
+ y: k.y * imageData.height,
20934
+ name: (_a = k.label) !== null && _a !== void 0 ? _a : ''
20935
+ });
20936
+ })
20937
+ };
20938
+ });
20939
+ return _assign(_assign({}, prediction), {
20940
+ faces: faces
20941
+ });
20942
+ }
20943
+ function processFaceDetectorPrediction(_a) {
20944
+ var faces = _a.faces,
20945
+ videoWidth = _a.videoWidth,
20946
+ videoHeight = _a.videoHeight,
20947
+ _b = _a.requireVerticalFaceCentering,
20948
+ requireVerticalFaceCentering = _b === void 0 ? true : _b,
20949
+ _c = _a.stabilityThreshold,
20950
+ stabilityThreshold = _c === void 0 ? 0.7 : _c;
20951
+ var face = faces[0];
20952
+ var faceNotDetected = faces.length === 0;
20953
+ var faceNotCentered = false,
20954
+ faceLookingAway = false,
20955
+ faceTooClose = false,
20956
+ faceTooFar = false;
20957
+ if (face) {
20958
+ // calculate centroids
20959
+ var vCX = videoWidth / 2;
20960
+ var vCY = videoHeight / 2;
20961
+ var fCX = (face.box.xMin + face.box.xMax) / 2;
20962
+ var fCY = (face.box.yMin + face.box.yMax) / 2;
20963
+ // calculate thresholds
20964
+ var vTX = videoWidth * 0.125;
20965
+ var vTY = videoHeight * 0.125;
20966
+ var fTW = face.box.width * 0.2;
20967
+ var fTH = face.box.height * 0.2;
20968
+ var nose = face.keypoints[2]; //.find((k) => k.name === 'noseTip')
20969
+ if (nose) {
20970
+ faceLookingAway = Math.abs(fCX - nose.x) > fTW || Math.abs(fCY - nose.y) > fTH;
20971
+ var faceNotCenteredHorizontally = Math.abs(vCX - fCX) > vTX;
20972
+ var faceNotCenteredVertically = Math.abs(vCY + 50 - fCY) > vTY;
20973
+ faceNotCentered = faceNotCenteredHorizontally || requireVerticalFaceCentering && faceNotCenteredVertically;
20974
+ }
20975
+ var isMobile = videoWidth < videoHeight;
20976
+ var tooCloseMultiple = 1.5;
20977
+ var tooFarMultiple = isMobile ? 6 : 7;
20978
+ faceTooClose = face.box.width > videoWidth / tooCloseMultiple;
20979
+ faceTooFar = face.box.width < videoWidth / tooFarMultiple;
20980
+ }
20981
+ var faceInGuides = !faceNotDetected && !faceNotCentered && !faceLookingAway && !faceTooClose && !faceTooFar;
20982
+ if (lastFaceDetectionTime > 0) {
20983
+ trackFramesNeeded(500 / lastFaceDetectionTime);
20984
+ }
20985
+ var faceIsStable = false;
20986
+ if (faceInGuides) {
20987
+ var framesNeeded = Math.ceil(average(framesNeededSamples));
20988
+ trackFace(face, framesNeeded);
20989
+ faceIsStable = lastNFaces.length >= framesNeeded && !lastNPairs.some(function (pair) {
20990
+ return pair.iou < stabilityThreshold;
20991
+ });
20992
+ }
20993
+ var faceReady = faceInGuides && faceIsStable;
20994
+ return {
20995
+ face: face,
20996
+ faceNotDetected: faceNotDetected,
20997
+ faceNotCentered: faceNotCentered,
20998
+ faceLookingAway: faceLookingAway,
20999
+ faceTooClose: faceTooClose,
21000
+ faceTooFar: faceTooFar,
21001
+ faceReady: faceReady,
21002
+ faceReadyAt: faceReady ? new Date() : null,
21003
+ faceIsStable: faceIsStable
21004
+ };
21005
+ }
21006
+ function testFaceDetectionAgainstKnownImage(detector) {
21007
+ return new Promise(function (resolve, reject) {
21008
+ var img = new Image();
21009
+ img.crossOrigin = 'anonymous';
21010
+ img.onload = function () {
21011
+ var prediction = detector.detectForVideo(img, performance.now());
21012
+ if (prediction.detections.length > 0) {
21013
+ debug('face detection test result', prediction.detections);
21014
+ resolve(void 0);
21015
+ } else {
21016
+ warn('face detection test failed');
21017
+ reject(new Error('testFaceDetectionAgainstKnownImage failed to predict'));
21018
+ }
21019
+ };
21020
+ img.onerror = function () {
21021
+ return reject(new Error('testFaceDetectionAgainstKnownImage failed to load image'));
21022
+ };
21023
+ img.src = "".concat(DEFAULT_CDN_URL, "/head-test.jpg");
21024
+ });
21025
+ }
21026
+
20674
21027
  var SelfieGuidanceModelsContext = /*#__PURE__*/React.createContext({
20675
21028
  start: function start() {
20676
21029
  return null;