idmission-web-sdk 2.3.89 → 2.3.90

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 +1971 -1490
  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 +1972 -1491
  39. package/dist/sdk2.esm.js.map +1 -1
  40. package/dist/sdk2.umd.development.js +2434 -1953
  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 +3 -3
package/dist/sdk2.esm.js CHANGED
@@ -7,7 +7,7 @@ import { createPortal } from 'react-dom';
7
7
  import { useTranslation, initReactI18next } from 'react-i18next';
8
8
  import { Upload } from 'tus-js-client';
9
9
  import SparkMD5 from 'spark-md5';
10
- import { ImageSegmenter, FilesetResolver, ImageClassifier, FaceDetector, ObjectDetector } from '@mediapipe/tasks-vision';
10
+ import { ImageSegmenter, FilesetResolver, ObjectDetector, ImageClassifier, FaceDetector } from '@mediapipe/tasks-vision';
11
11
  import { useStore, createStore, create } from 'zustand';
12
12
  import LanguageDetector from 'i18next-browser-languagedetector';
13
13
  import i18n from 'i18next';
@@ -205,7 +205,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
205
205
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
206
206
  };
207
207
 
208
- var webSdkVersion = '2.3.89';
208
+ var webSdkVersion = '2.3.90';
209
209
 
210
210
  function getPlatform() {
211
211
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -466,27 +466,27 @@ var GuidanceMessageContainer = function GuidanceMessageContainer(props) {
466
466
  if (!portalLocation) return element;
467
467
  return /*#__PURE__*/createPortal(element, portalLocation);
468
468
  };
469
- 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) {
469
+ 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) {
470
470
  var _a, _b, _c, _d, _e, _f;
471
471
  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';
472
472
  }, function (props) {
473
473
  var _a, _b, _c, _d, _e, _f;
474
474
  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';
475
475
  });
476
- var templateObject_1$P, templateObject_2$I;
476
+ var templateObject_1$P, templateObject_2$J;
477
477
 
478
478
  var wavesAnimation = keyframes(templateObject_1$O || (templateObject_1$O = __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"])));
479
- var progressBarAnimation = 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"])));
479
+ var progressBarAnimation = 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"])));
480
480
  var dualRingSpinnerAnimation = 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"])));
481
481
  var progressBorderAnimation = keyframes(templateObject_4$o || (templateObject_4$o = __makeTemplateObject(["\n to {\n stroke-dashoffset: 0;\n }\n"], ["\n to {\n stroke-dashoffset: 0;\n }\n"])));
482
- var templateObject_1$O, templateObject_2$H, templateObject_3$u, templateObject_4$o;
482
+ var templateObject_1$O, templateObject_2$I, templateObject_3$u, templateObject_4$o;
483
483
 
484
484
  var OverlayContainer = 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\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) {
485
485
  return props.theme.background ? "".concat(props.theme.background) : "white";
486
486
  }, function (props) {
487
487
  return props.theme.textColor ? "color: ".concat(props.theme.textColor, ";") : "";
488
488
  });
489
- 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) {
489
+ 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) {
490
490
  var _a;
491
491
  return (_a = props.theme.textAlign) !== null && _a !== void 0 ? _a : 'center';
492
492
  }, function (props) {
@@ -534,7 +534,7 @@ var LoadingOverlayLoadingListItem = styled.li(templateObject_19 || (templateObje
534
534
  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"])));
535
535
  var LoadingOverlayCustomLoadingGraphic = styled.img(templateObject_21 || (templateObject_21 = __makeTemplateObject(["\n transform-style: preserve-3d;\n"], ["\n transform-style: preserve-3d;\n"])));
536
536
  var LoadingOverlayContinueButtonContainer = styled.div(templateObject_22 || (templateObject_22 = __makeTemplateObject(["\n display: flex;\n"], ["\n display: flex;\n"])));
537
- var templateObject_1$N, templateObject_2$G, templateObject_3$t, templateObject_4$n, templateObject_5$f, 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;
537
+ var templateObject_1$N, templateObject_2$H, templateObject_3$t, templateObject_4$n, templateObject_5$f, 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;
538
538
 
539
539
  var GeolocationAccessDeniedOverlay = function GeolocationAccessDeniedOverlay(_a) {
540
540
  var accessBlockedImageUrl = _a.accessBlockedImageUrl;
@@ -1103,6 +1103,11 @@ var SubmissionContext = /*#__PURE__*/createContext({
1103
1103
  idFrontImage: null,
1104
1104
  idBackImage: null,
1105
1105
  passportImage: null,
1106
+ idFrontIrImage: null,
1107
+ idBackIrImage: null,
1108
+ idFrontUvImage: null,
1109
+ idBackUvImage: null,
1110
+ idBarcodeImage: null,
1106
1111
  selfieImage: null,
1107
1112
  signatureData: null,
1108
1113
  signatureVideoUrl: null,
@@ -1133,6 +1138,9 @@ var SubmissionContext = /*#__PURE__*/createContext({
1133
1138
  setIdBackUvImage: function setIdBackUvImage() {
1134
1139
  return null;
1135
1140
  },
1141
+ setIdBarcodeImage: function setIdBarcodeImage() {
1142
+ return null;
1143
+ },
1136
1144
  setSelfieImage: function setSelfieImage() {
1137
1145
  return null;
1138
1146
  },
@@ -1306,59 +1314,62 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1306
1314
  passportImage = _13[0],
1307
1315
  setPassportImage = _13[1];
1308
1316
  var _14 = useState(null),
1309
- selfieImage = _14[0],
1310
- setSelfieImage = _14[1];
1317
+ idBarcodeImage = _14[0],
1318
+ setIdBarcodeImage = _14[1];
1311
1319
  var _15 = useState(null),
1312
- signatureData = _15[0],
1313
- setSignatureData = _15[1];
1320
+ selfieImage = _15[0],
1321
+ setSelfieImage = _15[1];
1314
1322
  var _16 = useState(null),
1315
- signatureVideoUrl = _16[0],
1316
- setSignatureVideoUrl = _16[1];
1323
+ signatureData = _16[0],
1324
+ setSignatureData = _16[1];
1317
1325
  var _17 = useState(null),
1318
- signatureStartTimestamp = _17[0],
1319
- setSignatureStartTimestamp = _17[1];
1326
+ signatureVideoUrl = _17[0],
1327
+ setSignatureVideoUrl = _17[1];
1320
1328
  var _18 = useState(null),
1321
- signatureEndTimestamp = _18[0],
1322
- setSignatureEndTimestamp = _18[1];
1329
+ signatureStartTimestamp = _18[0],
1330
+ setSignatureStartTimestamp = _18[1];
1323
1331
  var _19 = useState(null),
1324
- idCaptureVideoUrl = _19[0],
1325
- setIdCaptureVideoUrl = _19[1];
1332
+ signatureEndTimestamp = _19[0],
1333
+ setSignatureEndTimestamp = _19[1];
1326
1334
  var _20 = useState(null),
1327
- idCaptureVideoIdFrontImage = _20[0],
1328
- setIdCaptureVideoIdFrontImage = _20[1];
1335
+ idCaptureVideoUrl = _20[0],
1336
+ setIdCaptureVideoUrl = _20[1];
1329
1337
  var _21 = useState(null),
1330
- idCaptureVideoIdBackImage = _21[0],
1331
- setIdCaptureVideoIdBackImage = _21[1];
1338
+ idCaptureVideoIdFrontImage = _21[0],
1339
+ setIdCaptureVideoIdFrontImage = _21[1];
1332
1340
  var _22 = useState(null),
1333
- idCaptureVideoAudioUrl = _22[0],
1334
- setIdCaptureVideoAudioUrl = _22[1];
1341
+ idCaptureVideoIdBackImage = _22[0],
1342
+ setIdCaptureVideoIdBackImage = _22[1];
1335
1343
  var _23 = useState(null),
1336
- idCaptureVideoAudioStartsAt = _23[0],
1337
- setIdCaptureVideoAudioStartsAt = _23[1];
1344
+ idCaptureVideoAudioUrl = _23[0],
1345
+ setIdCaptureVideoAudioUrl = _23[1];
1338
1346
  var _24 = useState(null),
1339
- expectedAudioText = _24[0],
1340
- setExpectedAudioText = _24[1];
1347
+ idCaptureVideoAudioStartsAt = _24[0],
1348
+ setIdCaptureVideoAudioStartsAt = _24[1];
1341
1349
  var _25 = useState(null),
1342
- additionalDocuments = _25[0],
1343
- setAdditionalDocuments = _25[1];
1350
+ expectedAudioText = _25[0],
1351
+ setExpectedAudioText = _25[1];
1344
1352
  var _26 = useState(null),
1345
- geolocationResult = _26[0],
1346
- setGeolocationResult = _26[1];
1347
- var _27 = useState(0),
1348
- geolocationAttempts = _27[0],
1349
- setGeolocationAttempts = _27[1];
1350
- var _28 = useState(false),
1351
- geolocationBlocked = _28[0],
1352
- setGeolocationBlocked = _28[1];
1353
- var _29 = useState([]),
1354
- idFrontCaptureAttempts = _29[0],
1355
- setIdFrontCaptureAttempts = _29[1];
1353
+ additionalDocuments = _26[0],
1354
+ setAdditionalDocuments = _26[1];
1355
+ var _27 = useState(null),
1356
+ geolocationResult = _27[0],
1357
+ setGeolocationResult = _27[1];
1358
+ var _28 = useState(0),
1359
+ geolocationAttempts = _28[0],
1360
+ setGeolocationAttempts = _28[1];
1361
+ var _29 = useState(false),
1362
+ geolocationBlocked = _29[0],
1363
+ setGeolocationBlocked = _29[1];
1356
1364
  var _30 = useState([]),
1357
- idBackCaptureAttempts = _30[0],
1358
- setIdBackCaptureAttempts = _30[1];
1365
+ idFrontCaptureAttempts = _30[0],
1366
+ setIdFrontCaptureAttempts = _30[1];
1359
1367
  var _31 = useState([]),
1360
- selfieCaptureAttempts = _31[0],
1361
- setSelfieCaptureAttempts = _31[1];
1368
+ idBackCaptureAttempts = _31[0],
1369
+ setIdBackCaptureAttempts = _31[1];
1370
+ var _32 = useState([]),
1371
+ selfieCaptureAttempts = _32[0],
1372
+ setSelfieCaptureAttempts = _32[1];
1362
1373
  var logIdFrontCaptureAttempt = useCallback(function (attempt) {
1363
1374
  setIdFrontCaptureAttempts(function (attempts) {
1364
1375
  return __spreadArray(__spreadArray([], attempts, true), [attempt], false);
@@ -1484,6 +1495,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1484
1495
  idFrontImage: idFrontImage,
1485
1496
  idBackImage: idBackImage,
1486
1497
  passportImage: passportImage,
1498
+ idBarcodeImage: idBarcodeImage,
1487
1499
  selfieImage: selfieImage
1488
1500
  };
1489
1501
  _a = signatureVideoUrl;
@@ -1589,6 +1601,9 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1589
1601
  if (documents.passportImage) {
1590
1602
  submissionRequest.customerData.idData.idImageFront = documents.passportImage;
1591
1603
  }
1604
+ if (documents.idBarcodeImage) {
1605
+ submissionRequest.customerData.idData.idBarcodeImage = documents.idBarcodeImage;
1606
+ }
1592
1607
  if (documents.idFrontIrImage) {
1593
1608
  submissionRequest.customerData.idData.idFrontIrImage = documents.idFrontIrImage;
1594
1609
  }
@@ -1683,7 +1698,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1683
1698
  }
1684
1699
  });
1685
1700
  });
1686
- }, [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, signatureEndTimestamp, signatureStartTimestamp, signatureVideoUrl, uploadDocument, verifyIdWithExternalDatabases, webhooksClientTraceId, webhooksEnabled, webhooksFireOnReview, webhooksFireOnReviewURL, webhooksSendInputImages, webhooksSendProcessedImages, webhooksStripSpecialCharacters, webhooksURL]);
1701
+ }, [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, signatureEndTimestamp, signatureStartTimestamp, signatureVideoUrl, uploadDocument, verifyIdWithExternalDatabases, webhooksClientTraceId, webhooksEnabled, webhooksFireOnReview, webhooksFireOnReviewURL, webhooksSendInputImages, webhooksSendProcessedImages, webhooksStripSpecialCharacters, webhooksURL]);
1687
1702
  var defaultOnSubmit = useCallback(function () {
1688
1703
  return __awaiter(void 0, void 0, void 0, function () {
1689
1704
  var submissionResponse_1, payload, host, endpoint, response, statusMessage, submissionResponse_2, e_1, err;
@@ -1961,6 +1976,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1961
1976
  idFrontUvImage: idFrontUvImage,
1962
1977
  idBackUvImage: idBackUvImage,
1963
1978
  passportImage: passportImage,
1979
+ idBarcodeImage: idBarcodeImage,
1964
1980
  selfieImage: selfieImage,
1965
1981
  signatureData: signatureData,
1966
1982
  signatureVideoUrl: signatureVideoUrl,
@@ -1977,6 +1993,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1977
1993
  setIdBackIrImage: setIdBackIrImage,
1978
1994
  setIdFrontUvImage: setIdFrontUvImage,
1979
1995
  setIdBackUvImage: setIdBackUvImage,
1996
+ setIdBarcodeImage: setIdBarcodeImage,
1980
1997
  setSelfieImage: setSelfieImage,
1981
1998
  setSignatureData: setSignatureData,
1982
1999
  setSignatureVideoUrl: setSignatureVideoUrl,
@@ -1997,7 +2014,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1997
2014
  checkLiveness: checkLiveness,
1998
2015
  retryLocationAccess: retryLocationAccess
1999
2016
  };
2000
- }, [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]);
2017
+ }, [additionalDocuments, checkLiveness, environment, idBackImage, idBackIrImage, idBackUvImage, idBarcodeImage, idCaptureVideoAudioStartsAt, idCaptureVideoAudioUrl, idCaptureVideoIdBackImage, idCaptureVideoIdFrontImage, idCaptureVideoUrl, idFrontImage, idFrontIrImage, idFrontUvImage, livenessCheckRequest, logIdBackCaptureAttempt, logIdFrontCaptureAttempt, logSelfieCaptureAttempt, passportImage, retryLocationAccess, selfieImage, signatureData, signatureVideoUrl, submissionError, submissionRequest, submissionResponse, submissionStatus, submit, uploadDocument]);
2001
2018
  return /*#__PURE__*/React__default.createElement(SubmissionContext.Provider, {
2002
2019
  value: value
2003
2020
  }, geolocationRequired && geolocationBlocked ? ( /*#__PURE__*/React__default.createElement(GeolocationAccessDeniedOverlay, null)) : children, submissionError && ( /*#__PURE__*/React__default.createElement(SubmissionErrorOverlay, {
@@ -2191,97 +2208,6 @@ function preloadVisionRuntime() {
2191
2208
  });
2192
2209
  }
2193
2210
 
2194
- function getFrameDimensions(frame) {
2195
- var frameWidth = frame.width,
2196
- frameHeight = frame.height;
2197
- if (frame instanceof HTMLImageElement) {
2198
- frameWidth = frame.naturalWidth;
2199
- frameHeight = frame.naturalHeight;
2200
- }
2201
- if (frame instanceof HTMLVideoElement) {
2202
- frameWidth = frame.videoWidth;
2203
- frameHeight = frame.videoHeight;
2204
- }
2205
- return [frameWidth, frameHeight];
2206
- }
2207
-
2208
- var InvisibleCanvas = styled.canvas(templateObject_1$M || (templateObject_1$M = __makeTemplateObject(["\n display: none;\n"], ["\n display: none;\n"])));
2209
- function drawToCanvas(canvas, frame, width, height) {
2210
- if (!canvas) return;
2211
- var ctx = canvas.getContext('2d');
2212
- if (!ctx) return;
2213
- if (!width || !height) {
2214
- var _a = getFrameDimensions(frame),
2215
- frameWidth = _a[0],
2216
- frameHeight = _a[1];
2217
- width || (width = frameWidth);
2218
- height || (height = frameHeight);
2219
- }
2220
- canvas.width = width;
2221
- canvas.height = height;
2222
- ctx.drawImage(frame, 0, 0, width, height);
2223
- }
2224
- function clearCanvas(canvas) {
2225
- var _a;
2226
- (_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);
2227
- }
2228
- var templateObject_1$M;
2229
-
2230
- function cropToShoulders(rawCanvas, cropCanvas, resizeCanvas, frame, face, quality, maxHeight) {
2231
- var _a;
2232
- if (quality === void 0) {
2233
- quality = 0.92;
2234
- }
2235
- if (!rawCanvas || !cropCanvas || !resizeCanvas) return '';
2236
- var rawCtx = rawCanvas.getContext('2d');
2237
- var cropCtx = cropCanvas.getContext('2d');
2238
- var resizeCtx = resizeCanvas.getContext('2d');
2239
- if (!rawCtx || !cropCtx || !resizeCtx) throw new Error('could not get 2d context');
2240
- rawCanvas.width = frame.width;
2241
- rawCanvas.height = frame.height;
2242
- rawCtx.putImageData(frame, 0, 0);
2243
- if (frame.height > frame.width) {
2244
- cropCanvas.width = frame.width;
2245
- cropCanvas.height = frame.height;
2246
- cropCtx.drawImage(rawCanvas, 0, 0, cropCanvas.width, cropCanvas.height);
2247
- } else {
2248
- var _b = (_a = face === null || face === void 0 ? void 0 : face.box) !== null && _a !== void 0 ? _a : {
2249
- xMin: 0,
2250
- width: frame.width
2251
- },
2252
- xMin = _b.xMin,
2253
- width = _b.width;
2254
- var desiredWidth = frame.height * 0.6;
2255
- var faceCenterX = xMin + width / 2;
2256
- var xPos = Math.max(0, faceCenterX - desiredWidth / 2);
2257
- cropCanvas.width = desiredWidth;
2258
- cropCanvas.height = frame.height;
2259
- cropCtx.drawImage(rawCanvas, xPos, 0, cropCanvas.width, cropCanvas.height, 0, 0, cropCanvas.width, cropCanvas.height);
2260
- }
2261
- resizeCanvas.height = maxHeight !== null && maxHeight !== void 0 ? maxHeight : cropCanvas.height;
2262
- resizeCanvas.width = cropCanvas.width * (resizeCanvas.height / cropCanvas.height);
2263
- resizeCtx === null || resizeCtx === void 0 ? void 0 : resizeCtx.drawImage(cropCanvas, 0, 0, resizeCanvas.width, resizeCanvas.height);
2264
- var dataURL = resizeCanvas.toDataURL('image/jpeg', quality);
2265
- log('cropToShoulders size', new TextEncoder().encode(dataURL).length);
2266
- clearCanvas(rawCanvas);
2267
- clearCanvas(cropCanvas);
2268
- clearCanvas(resizeCanvas);
2269
- return dataURL;
2270
- }
2271
- function cropToDetectedObjectBox(frame, box, canvas) {
2272
- canvas || (canvas = document.createElement('canvas'));
2273
- var ctx = canvas.getContext('2d');
2274
- if (!ctx) throw new Error('could not get 2d context');
2275
- var xMin = box.xMin,
2276
- yMin = box.yMin,
2277
- width = box.width,
2278
- height = box.height;
2279
- canvas.width = width;
2280
- canvas.height = height;
2281
- ctx.drawImage(frame, xMin, yMin, width, height, 0, 0, width, height);
2282
- return canvas;
2283
- }
2284
-
2285
2211
  var defaultImageSegmenterModelPath = 'https://websdk-cdn-dev.idmission.com/assets/models/selfiesegmenter20240524/selfie_segmenter.tflite';
2286
2212
  var imageSegmenterModelSizeInBytes = 256440.32;
2287
2213
  // 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
@@ -2411,6 +2337,192 @@ function giveUpAfter(maxTime) {
2411
2337
  });
2412
2338
  }
2413
2339
 
2340
+ var DEFAULT_CDN_URL = 'https://websdk-cdn-dev.idmission.com/assets';
2341
+
2342
+ var defaultDocumentDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/DocumentDetector/DocumentDetector-20250815_115859.tflite");
2343
+
2344
+ var defaultFocusModelPath = "".concat(DEFAULT_CDN_URL, "/models/Focus/Focus-20241008_102708.tflite");
2345
+
2346
+ var defaultFaceDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/FaceDetector/FaceDetector-20250820_154546.tflite");
2347
+
2348
+ var defaultBarcodeReadabilityModelPath = "".concat(DEFAULT_CDN_URL, "/models/BarcodeReadability/BarcodeReadability-20250815_120417.tflite");
2349
+
2350
+ var defaultModelPaths = {
2351
+ documentDetector: defaultDocumentDetectorModelPath,
2352
+ focus: defaultFocusModelPath,
2353
+ faceDetection: defaultFaceDetectorModelPath,
2354
+ barcodeReadability: defaultBarcodeReadabilityModelPath
2355
+ };
2356
+
2357
+ var preloadModels = function preloadModels(_a) {
2358
+ return __awaiter(void 0, [_a], void 0, function (_b) {
2359
+ var preloadTasks;
2360
+ var _c = _b.documentDetectionModel,
2361
+ documentDetectionModel = _c === void 0 ? true : _c,
2362
+ _d = _b.focusModel,
2363
+ focusModel = _d === void 0 ? true : _d,
2364
+ _e = _b.faceDetectionModel,
2365
+ faceDetectionModel = _e === void 0 ? true : _e,
2366
+ _f = _b.barcodeReadabilityModel,
2367
+ barcodeReadabilityModel = _f === void 0 ? true : _f;
2368
+ return __generator(this, function (_g) {
2369
+ switch (_g.label) {
2370
+ case 0:
2371
+ return [4 /*yield*/, probeModelCapabilities()];
2372
+ case 1:
2373
+ _g.sent();
2374
+ preloadTasks = [];
2375
+ if (documentDetectionModel) {
2376
+ preloadTasks.push(preloadDocumentDetectorDependencies);
2377
+ }
2378
+ if (focusModel) {
2379
+ preloadTasks.push(preloadFocusModelDependencies);
2380
+ }
2381
+ if (faceDetectionModel) {
2382
+ preloadTasks.push(preloadFaceDetectorDependencies);
2383
+ }
2384
+ if (barcodeReadabilityModel) {
2385
+ preloadTasks.push(preloadBarcodeReadabilityModelDependencies);
2386
+ }
2387
+ return [4 /*yield*/, Promise.all(preloadTasks)];
2388
+ case 2:
2389
+ _g.sent();
2390
+ return [2 /*return*/];
2391
+ }
2392
+ });
2393
+ });
2394
+ };
2395
+ var progressByUrl = {};
2396
+ var progressByUseCase = {
2397
+ visionRuntime: {
2398
+ loaded: 0,
2399
+ total: 0
2400
+ },
2401
+ documentDetector: {
2402
+ loaded: 0,
2403
+ total: 0
2404
+ },
2405
+ focus: {
2406
+ loaded: 0,
2407
+ total: 0
2408
+ },
2409
+ faceDetection: {
2410
+ loaded: 0,
2411
+ total: 0
2412
+ },
2413
+ barcodeReadability: {
2414
+ loaded: 0,
2415
+ total: 0
2416
+ }
2417
+ };
2418
+ function preloadDependency(url) {
2419
+ return __awaiter(this, void 0, void 0, function () {
2420
+ return __generator(this, function (_a) {
2421
+ return [2 /*return*/, new Promise(function (resolve, reject) {
2422
+ var req = new XMLHttpRequest();
2423
+ req.addEventListener('progress', function (event) {
2424
+ if (!event.lengthComputable) return;
2425
+ progressByUrl[url] = event;
2426
+ document.dispatchEvent(new CustomEvent('idmission.preloadProgress', {
2427
+ detail: {
2428
+ url: url,
2429
+ loaded: event.loaded,
2430
+ total: event.total
2431
+ }
2432
+ }));
2433
+ });
2434
+ req.addEventListener('loadend', function () {
2435
+ resolve(req.readyState === 4 && req.status === 200);
2436
+ });
2437
+ req.addEventListener('error', reject);
2438
+ req.open('GET', url, true);
2439
+ req.send();
2440
+ })];
2441
+ });
2442
+ });
2443
+ }
2444
+ var modelsPreloading = {
2445
+ documentDetector: false,
2446
+ focus: false,
2447
+ faceDetection: false,
2448
+ barcodeReadability: false
2449
+ };
2450
+ var preloadDocumentDetectorDependencies = function preloadDocumentDetectorDependencies() {
2451
+ return preloadModelDependencies('documentDetector');
2452
+ };
2453
+ var preloadFocusModelDependencies = function preloadFocusModelDependencies() {
2454
+ return preloadModelDependencies('focus');
2455
+ };
2456
+ var preloadFaceDetectorDependencies = function preloadFaceDetectorDependencies() {
2457
+ return preloadModelDependencies('faceDetection');
2458
+ };
2459
+ var preloadBarcodeReadabilityModelDependencies = function preloadBarcodeReadabilityModelDependencies() {
2460
+ return preloadModelDependencies('barcodeReadability');
2461
+ };
2462
+ function preloadModelDependencies(model) {
2463
+ return __awaiter(this, void 0, void 0, function () {
2464
+ function handleModelDownloadProgress(event) {
2465
+ var detail = event.detail;
2466
+ if (!dependencies.includes(detail.url)) return;
2467
+ progressByUseCase[model] = sumUpProgressForDependencies(dependencies);
2468
+ document.dispatchEvent(new CustomEvent("idmission.preloadProgress.".concat(model), {
2469
+ detail: progressByUseCase[model]
2470
+ }));
2471
+ }
2472
+ var dependencies;
2473
+ return __generator(this, function (_a) {
2474
+ switch (_a.label) {
2475
+ case 0:
2476
+ if (modelsPreloading[model]) return [2 /*return*/, new Promise(function (resolve) {
2477
+ var i = setInterval(function () {
2478
+ if (!modelsPreloading[model]) {
2479
+ clearInterval(i);
2480
+ resolve();
2481
+ }
2482
+ }, 100);
2483
+ })];
2484
+ modelsPreloading[model] = true;
2485
+ return [4 /*yield*/, probeModelCapabilities()];
2486
+ case 1:
2487
+ _a.sent();
2488
+ if (modelCapabilities.delegate === 'NONE') {
2489
+ throw new Error("No available delegate for ".concat(model, " model."));
2490
+ }
2491
+ dependencies = [defaultModelPaths[model]];
2492
+ document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
2493
+ _a.label = 2;
2494
+ case 2:
2495
+ _a.trys.push([2,, 4, 5]);
2496
+ return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
2497
+ case 3:
2498
+ _a.sent();
2499
+ return [3 /*break*/, 5];
2500
+ case 4:
2501
+ document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
2502
+ modelsPreloading[model] = false;
2503
+ return [7 /*endfinally*/];
2504
+ case 5:
2505
+ return [2 /*return*/];
2506
+ }
2507
+ });
2508
+ });
2509
+ }
2510
+ function progressToPercentage(progress) {
2511
+ return progress.total > 0 ? Math.round(100.0 * progress.loaded / progress.total) : 0;
2512
+ }
2513
+ function sumUpProgressForDependencies(dependencies) {
2514
+ return dependencies.reduce(function (result, dependency) {
2515
+ var dependencyProgress = progressByUrl[dependency];
2516
+ if (!dependencyProgress) return result;
2517
+ result.loaded += dependencyProgress.loaded;
2518
+ result.total += dependencyProgress.total;
2519
+ return result;
2520
+ }, {
2521
+ loaded: 0,
2522
+ total: 0
2523
+ });
2524
+ }
2525
+
2414
2526
  function convertBoundingBox(box) {
2415
2527
  var _a, _b, _c, _d, _e, _f, _g, _h;
2416
2528
  return {
@@ -2465,53 +2577,50 @@ function average(arr) {
2465
2577
  return sum / len;
2466
2578
  }
2467
2579
 
2468
- var DEFAULT_CDN_URL = 'https://websdk-cdn-dev.idmission.com/assets';
2469
-
2470
- var defaultDocumentDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/DocumentDetector/DocumentDetector-20250815_115859.tflite");
2471
-
2472
- var defaultFocusModelPath = "".concat(DEFAULT_CDN_URL, "/models/Focus/Focus-20241008_102708.tflite");
2473
-
2474
- var defaultFaceDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/FaceDetector/FaceDetector-20250820_154546.tflite");
2475
-
2476
- var defaultFocusModelLoadTimeoutMs = 45000;
2477
- var defaultFocusThresholds = {
2478
- idCardFront: {
2479
- desktop: 0,
2480
- mobile: 0.3
2481
- },
2482
- idCardBack: {
2483
- desktop: 0,
2484
- mobile: 0.3
2485
- },
2486
- passport: {
2487
- desktop: 0,
2488
- mobile: 0.3
2489
- },
2490
- singlePage: {
2491
- desktop: 0,
2492
- mobile: 0.3
2580
+ var defaultDocumentDetectionScoreThreshold = 0.1;
2581
+ var defaultDocumentDetectionModelLoadTimeoutMs = 45000;
2582
+ var defaultDocumentDetectionThresholds = {
2583
+ idCardFront: 0.6,
2584
+ idCardBack: 0.6,
2585
+ passport: 0.4,
2586
+ singlePage: 0.4,
2587
+ stability: {
2588
+ idCardFront: 0.85,
2589
+ idCardBack: 0.85,
2590
+ passport: 0.5,
2591
+ singlePage: 0.5
2493
2592
  }
2494
2593
  };
2495
- var classifier = null;
2496
- var classifierSettings = null;
2497
- function loadFocusModel() {
2498
- return __awaiter(this, arguments, void 0, function (modelAssetPath) {
2594
+ var documentTypeDisplayNames = {
2595
+ idCardFront: 'ID card front',
2596
+ idCardBack: 'ID card back',
2597
+ passport: 'Passport',
2598
+ singlePage: 'Single page',
2599
+ none: 'None'
2600
+ };
2601
+ var detector$1 = null;
2602
+ var detectorSettings$1 = null;
2603
+ function loadDocumentDetector() {
2604
+ return __awaiter(this, arguments, void 0, function (modelAssetPath, scoreThreshold) {
2499
2605
  var _a, _b;
2500
2606
  if (modelAssetPath === void 0) {
2501
- modelAssetPath = defaultFocusModelPath;
2607
+ modelAssetPath = defaultDocumentDetectorModelPath;
2608
+ }
2609
+ if (scoreThreshold === void 0) {
2610
+ scoreThreshold = defaultDocumentDetectionScoreThreshold;
2502
2611
  }
2503
2612
  return __generator(this, function (_c) {
2504
2613
  switch (_c.label) {
2505
2614
  case 0:
2506
- if (classifier && (classifierSettings === null || classifierSettings === void 0 ? void 0 : classifierSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier];
2507
- closeFocusModel();
2508
- return [4 /*yield*/, preloadFocusModelDependencies()];
2615
+ 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];
2616
+ closeDocumentDetector();
2617
+ return [4 /*yield*/, preloadDocumentDetectorDependencies()];
2509
2618
  case 1:
2510
2619
  _c.sent();
2511
2620
  if (modelCapabilities.delegate === 'NONE') {
2512
- throw new Error('No available delegate for focus detector.');
2621
+ throw new Error('No available delegate for document detector.');
2513
2622
  }
2514
- _b = (_a = ImageClassifier).createFromOptions;
2623
+ _b = (_a = ObjectDetector).createFromOptions;
2515
2624
  return [4 /*yield*/, FilesetResolver.forVisionTasks(visionTasksBasePath)];
2516
2625
  case 2:
2517
2626
  return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
@@ -2520,44 +2629,48 @@ function loadFocusModel() {
2520
2629
  delegate: modelCapabilities.delegate
2521
2630
  },
2522
2631
  // canvas: document.createElement('canvas'),
2632
+ scoreThreshold: scoreThreshold,
2523
2633
  runningMode: 'VIDEO'
2524
2634
  }])];
2525
2635
  case 3:
2526
- classifier = _c.sent();
2527
- classifierSettings = {
2528
- modelAssetPath: modelAssetPath
2636
+ detector$1 = _c.sent();
2637
+ detectorSettings$1 = {
2638
+ modelAssetPath: modelAssetPath,
2639
+ scoreThreshold: scoreThreshold
2529
2640
  };
2530
- return [2 /*return*/, classifier];
2641
+ return [2 /*return*/, detector$1];
2531
2642
  }
2532
2643
  });
2533
2644
  });
2534
2645
  }
2535
- function closeFocusModel() {
2536
- classifier === null || classifier === void 0 ? void 0 : classifier.close();
2537
- classifier = null;
2538
- classifierSettings = null;
2646
+ function closeDocumentDetector() {
2647
+ detector$1 === null || detector$1 === void 0 ? void 0 : detector$1.close();
2648
+ detector$1 = null;
2649
+ detectorSettings$1 = null;
2539
2650
  }
2540
- function useLoadFocusModel(_a) {
2541
- var _b = _a.modelPath,
2542
- modelPath = _b === void 0 ? defaultFocusModelPath : _b,
2543
- _c = _a.modelLoadTimeoutMs,
2544
- modelLoadTimeoutMs = _c === void 0 ? defaultFocusModelLoadTimeoutMs : _c,
2651
+ function useLoadDocumentDetector(_a) {
2652
+ var _b = _a.shouldLoadModels,
2653
+ shouldLoadModels = _b === void 0 ? true : _b,
2654
+ _c = _a.modelPath,
2655
+ modelPath = _c === void 0 ? defaultDocumentDetectorModelPath : _c,
2656
+ _d = _a.modelLoadTimeoutMs,
2657
+ modelLoadTimeoutMs = _d === void 0 ? defaultDocumentDetectionModelLoadTimeoutMs : _d,
2658
+ _e = _a.scoreThreshold,
2659
+ scoreThreshold = _e === void 0 ? defaultDocumentDetectionScoreThreshold : _e,
2545
2660
  onModelError = _a.onModelError,
2546
- videoRef = _a.videoRef,
2547
- _d = _a.shouldLoadModels,
2548
- shouldLoadModels = _d === void 0 ? true : _d;
2549
- var _e = useState('not-started'),
2550
- modelLoadState = _e[0],
2551
- setModelLoadState = _e[1];
2552
- var _f = useState(0),
2553
- modelDownloadProgress = _f[0],
2554
- setModelDownloadProgress = _f[1];
2661
+ videoRef = _a.videoRef;
2662
+ var _f = useState('not-started'),
2663
+ modelLoadState = _f[0],
2664
+ setModelLoadState = _f[1];
2555
2665
  var _g = useState(null),
2556
2666
  modelWarmingStartedAt = _g[0],
2557
2667
  setModelWarmingStartedAt = _g[1];
2558
- var _h = useState(null),
2559
- modelError = _h[0],
2560
- setModelError = _h[1];
2668
+ var _h = useState(0),
2669
+ modelDownloadProgress = _h[0],
2670
+ setModelDownloadProgress = _h[1];
2671
+ var _j = useState(null),
2672
+ modelError = _j[0],
2673
+ setModelError = _j[1];
2561
2674
  useEffect(function loadModel() {
2562
2675
  var _this = this;
2563
2676
  if (!shouldLoadModels) return;
@@ -2566,21 +2679,24 @@ function useLoadFocusModel(_a) {
2566
2679
  function handleDownloadProgress(event) {
2567
2680
  setModelDownloadProgress(progressToPercentage(event.detail));
2568
2681
  }
2569
- document.addEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
2682
+ document.addEventListener('idmission.preloadProgress.documentDetector', handleDownloadProgress);
2570
2683
  var modelLoadTimeout = setTimeout(function () {
2571
2684
  setModelError(new Error('Model loading time limit exceeded.'));
2572
2685
  }, modelLoadTimeoutMs);
2573
2686
  var cancelVideoReady = function cancelVideoReady() {};
2574
- loadFocusModel(modelPath).then(function (loadedModel) {
2687
+ loadDocumentDetector(modelPath, scoreThreshold).then(function (model) {
2575
2688
  return __awaiter(_this, void 0, void 0, function () {
2576
2689
  var _a, videoReady, cancel, cancelled;
2577
2690
  return __generator(this, function (_b) {
2578
2691
  switch (_b.label) {
2579
2692
  case 0:
2580
2693
  setModelDownloadProgress(100);
2581
- clearTimeout(modelLoadTimeout);
2582
2694
  setModelLoadState('warming');
2583
- setModelWarmingStartedAt(new Date().getTime());
2695
+ setModelWarmingStartedAt(performance.now());
2696
+ clearTimeout(modelLoadTimeout);
2697
+ return [4 /*yield*/, testDocumentDetectionAgainstKnownImage(model)];
2698
+ case 1:
2699
+ _b.sent();
2584
2700
  _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
2585
2701
  cancelled = false;
2586
2702
  cancelVideoReady = function cancelVideoReady() {
@@ -2588,11 +2704,11 @@ function useLoadFocusModel(_a) {
2588
2704
  cancel();
2589
2705
  };
2590
2706
  return [4 /*yield*/, videoReady];
2591
- case 1:
2707
+ case 2:
2592
2708
  _b.sent();
2593
2709
  setTimeout(function () {
2594
2710
  if (cancelled) return;
2595
- loadedModel.classifyForVideo(videoRef.current, performance.now());
2711
+ model.detectForVideo(videoRef.current, performance.now());
2596
2712
  setModelLoadState('ready');
2597
2713
  }, 500);
2598
2714
  return [2 /*return*/];
@@ -2606,13 +2722,13 @@ function useLoadFocusModel(_a) {
2606
2722
  clearTimeout(modelLoadTimeout);
2607
2723
  });
2608
2724
  return function () {
2609
- log('unloading focus model');
2725
+ log('unloading document detection model');
2610
2726
  cancelVideoReady();
2611
- closeFocusModel();
2727
+ closeDocumentDetector();
2612
2728
  clearTimeout(modelLoadTimeout);
2613
- document.removeEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
2729
+ document.removeEventListener('idmission.preloadProgress.documentDetector', handleDownloadProgress);
2614
2730
  };
2615
- }, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
2731
+ }, [shouldLoadModels, modelLoadTimeoutMs, modelPath, scoreThreshold, videoRef]);
2616
2732
  useEffect(function handleModelError() {
2617
2733
  if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
2618
2734
  }, [modelError, onModelError]);
@@ -2622,185 +2738,41 @@ function useLoadFocusModel(_a) {
2622
2738
  modelLoadState: modelLoadState,
2623
2739
  modelDownloadProgress: modelDownloadProgress,
2624
2740
  modelWarmingStartedAt: modelWarmingStartedAt,
2625
- modelError: modelError
2741
+ modelError: modelError,
2742
+ setModelError: setModelError
2626
2743
  };
2627
2744
  }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
2628
2745
  }
2629
- var lastFocusPredictionAt = 0;
2630
- var lastFocusPredictionTime = 0;
2631
- function setLastFocusPredictionAt(time) {
2632
- lastFocusPredictionTime = time - lastFocusPredictionAt;
2633
- lastFocusPredictionAt = time;
2634
- }
2635
- function makeFocusModelPrediction(imageData, cropCanvas, rotateCanvas, box) {
2636
- var _a, _b, _c, _d, _e;
2637
- if (!classifier) return null;
2638
- var startedAt = new Date();
2639
- var image = cropIfNecessary(imageData, cropCanvas, rotateCanvas, box);
2640
- var result = classifier.classifyForVideo(image, performance.now());
2641
- 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) {
2642
- return c.categoryName === 'focused';
2643
- })) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
2644
- var predictionTime = new Date().getTime() - startedAt.getTime();
2645
- return {
2646
- score: score,
2647
- predictionTime: predictionTime
2648
- };
2649
- }
2650
- function cropIfNecessary(imageData, cropCanvas, rotateCanvas, box) {
2651
- if (!box) return imageData;
2652
- var cropped = cropToDetectedObjectBox(imageData, box, cropCanvas);
2653
- var _a = [box.width, box.height],
2654
- bw = _a[0],
2655
- bh = _a[1];
2656
- if (bh <= bw) return cropped;
2657
- var ctx = rotateCanvas.getContext('2d');
2658
- if (!ctx) return cropped;
2659
- rotateCanvas.width = bh;
2660
- rotateCanvas.height = bw;
2661
- ctx.clearRect(0, 0, rotateCanvas.width, rotateCanvas.height);
2662
- ctx.translate(rotateCanvas.width / 2, rotateCanvas.height / 2);
2663
- ctx.rotate(1.5708); // 90 deg in radians
2664
- ctx.drawImage(cropped, -bw / 2, -bh / 2);
2665
- return rotateCanvas;
2666
- }
2667
-
2668
- var defaultSelfieCaptureModelLoadTimeoutMs = 45000;
2669
- var detector$1 = null;
2670
- var detectorSettings$1 = null;
2671
- function loadFaceDetector() {
2672
- return __awaiter(this, arguments, void 0, function (modelAssetPath) {
2673
- var _a, _b;
2674
- if (modelAssetPath === void 0) {
2675
- modelAssetPath = defaultFaceDetectorModelPath;
2676
- }
2677
- return __generator(this, function (_c) {
2678
- switch (_c.label) {
2679
- case 0:
2680
- if (detector$1 && (detectorSettings$1 === null || detectorSettings$1 === void 0 ? void 0 : detectorSettings$1.modelAssetPath) === modelAssetPath) return [2 /*return*/, detector$1];
2681
- closeFaceDetector();
2682
- return [4 /*yield*/, preloadFaceDetectorDependencies()];
2683
- case 1:
2684
- _c.sent();
2685
- if (modelCapabilities.delegate === 'NONE') {
2686
- throw new Error('No available delegate for face detector.');
2687
- }
2688
- _b = (_a = FaceDetector).createFromOptions;
2689
- return [4 /*yield*/, FilesetResolver.forVisionTasks(visionTasksBasePath)];
2690
- case 2:
2691
- return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
2692
- // canvas: document.createElement('canvas'),
2693
- baseOptions: {
2694
- modelAssetPath: modelAssetPath,
2695
- delegate: modelCapabilities.delegate
2696
- },
2697
- runningMode: 'VIDEO'
2698
- }])];
2699
- case 3:
2700
- detector$1 = _c.sent();
2701
- detectorSettings$1 = {
2702
- modelAssetPath: modelAssetPath
2703
- };
2704
- return [2 /*return*/, detector$1];
2746
+ function makeDocumentDetectorPrediction(frame) {
2747
+ return __awaiter(this, void 0, void 0, function () {
2748
+ var startedAt, prediction, time, frameWidth, frameHeight;
2749
+ return __generator(this, function (_a) {
2750
+ if (!detector$1) return [2 /*return*/, null];
2751
+ startedAt = performance.now();
2752
+ // Detectors can throw errors, for example when using custom URLs that
2753
+ // contain a model that doesn't provide the expected output.
2754
+ try {
2755
+ prediction = detector$1.detectForVideo(frame, performance.now());
2756
+ time = performance.now() - startedAt;
2757
+ frameWidth = frame.width;
2758
+ frameHeight = frame.height;
2759
+ return [2 /*return*/, _assign(_assign({}, prediction), {
2760
+ time: time,
2761
+ frameWidth: frameWidth,
2762
+ frameHeight: frameHeight
2763
+ })];
2764
+ } catch (e) {
2765
+ error('caught object detection error', e);
2705
2766
  }
2767
+ return [2 /*return*/, null];
2706
2768
  });
2707
2769
  });
2708
2770
  }
2709
- function closeFaceDetector() {
2710
- detector$1 === null || detector$1 === void 0 ? void 0 : detector$1.close();
2711
- detector$1 = null;
2712
- detectorSettings$1 = null;
2713
- }
2714
- function useLoadFaceDetector(_a) {
2715
- var onModelError = _a.onModelError,
2716
- _b = _a.modelLoadTimeoutMs,
2717
- modelLoadTimeoutMs = _b === void 0 ? defaultSelfieCaptureModelLoadTimeoutMs : _b,
2718
- videoRef = _a.videoRef;
2719
- var _c = useState('not-started'),
2720
- modelLoadState = _c[0],
2721
- setModelLoadState = _c[1];
2722
- var _d = useState(0),
2723
- modelDownloadProgress = _d[0],
2724
- setModelDownloadProgress = _d[1];
2725
- var _e = useState(null),
2726
- modelWarmingStartedAt = _e[0],
2727
- setModelWarmingStartedAt = _e[1];
2728
- var _f = useState(null),
2729
- modelError = _f[0],
2730
- setModelError = _f[1];
2731
- useEffect(function loadModel() {
2732
- var _this = this;
2733
- setModelLoadState('downloading');
2734
- setModelWarmingStartedAt(null);
2735
- var modelLoadTimeout = setTimeout(function () {
2736
- setModelError(new Error('Model loading time limit exceeded.'));
2737
- }, modelLoadTimeoutMs);
2738
- function handleDownloadProgress(event) {
2739
- setModelDownloadProgress(progressToPercentage(event.detail));
2740
- }
2741
- document.addEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
2742
- var cancelVideoReady = function cancelVideoReady() {};
2743
- loadFaceDetector().then(function (model) {
2744
- return __awaiter(_this, void 0, void 0, function () {
2745
- var _a, videoReady, cancel, cancelled;
2746
- return __generator(this, function (_b) {
2747
- switch (_b.label) {
2748
- case 0:
2749
- setModelDownloadProgress(100);
2750
- clearTimeout(modelLoadTimeout);
2751
- setModelLoadState('warming');
2752
- setModelWarmingStartedAt(new Date().getTime());
2753
- return [4 /*yield*/, testFaceDetectionAgainstKnownImage(model)];
2754
- case 1:
2755
- _b.sent();
2756
- _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
2757
- cancelled = false;
2758
- cancelVideoReady = function cancelVideoReady() {
2759
- cancelled = true;
2760
- cancel();
2761
- };
2762
- return [4 /*yield*/, videoReady];
2763
- case 2:
2764
- _b.sent();
2765
- if (cancelled) return [2 /*return*/];
2766
- model.detectForVideo(videoRef.current, performance.now());
2767
- setModelLoadState('ready');
2768
- return [2 /*return*/];
2769
- }
2770
- });
2771
- });
2772
- })["catch"](function (e) {
2773
- setModelError(e);
2774
- setModelLoadState('error');
2775
- })["finally"](function () {
2776
- clearTimeout(modelLoadTimeout);
2777
- });
2778
- return function () {
2779
- log('unloading face detection model');
2780
- cancelVideoReady();
2781
- closeFaceDetector();
2782
- clearTimeout(modelLoadTimeout);
2783
- document.removeEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
2784
- };
2785
- }, [modelLoadTimeoutMs, videoRef]);
2786
- useEffect(function handleModelError() {
2787
- if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
2788
- }, [modelError, onModelError]);
2789
- return useMemo(function () {
2790
- return {
2791
- ready: modelLoadState === 'ready',
2792
- modelLoadState: modelLoadState,
2793
- modelDownloadProgress: modelDownloadProgress,
2794
- modelWarmingStartedAt: modelWarmingStartedAt,
2795
- modelError: modelError
2796
- };
2797
- }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
2798
- }
2799
- var lastFaceDetectionAt = 0;
2800
- var lastFaceDetectionTime = 0;
2801
- function setLastFaceDetectionAt(time) {
2802
- lastFaceDetectionTime = time - lastFaceDetectionAt;
2803
- lastFaceDetectionAt = time;
2771
+ var lastDetectionAt = 0;
2772
+ var lastDetectionTime = 0;
2773
+ function setLastDetectionAt(time) {
2774
+ lastDetectionTime = time - lastDetectionAt;
2775
+ lastDetectionAt = time;
2804
2776
  }
2805
2777
  var framesNeededSamples$1 = [];
2806
2778
  function trackFramesNeeded$1(value, bufferLength) {
@@ -2810,970 +2782,375 @@ function trackFramesNeeded$1(value, bufferLength) {
2810
2782
  framesNeededSamples$1.unshift(value);
2811
2783
  if (framesNeededSamples$1.length > bufferLength) framesNeededSamples$1.length = bufferLength;
2812
2784
  }
2813
- var lastNFaces = [];
2814
- var lastNFacePairs = [];
2815
- var lastNNoses = [];
2816
- var lastNNosePairs = [];
2817
- function trackFace(face, framesNeeded, frameWidth, frameHeight) {
2785
+ var lastNBoxes = [];
2786
+ var lastNPairs = [];
2787
+ function trackBox(box, framesNeeded) {
2818
2788
  if (framesNeeded === void 0) {
2819
2789
  framesNeeded = 12;
2820
2790
  }
2821
- var nose = face.keypoints[2];
2822
- if (!nose) return;
2823
- lastNFaces.unshift(face);
2824
- lastNNoses.unshift(nose);
2825
- if (lastNFaces.length > framesNeeded) lastNFaces.length = framesNeeded;
2826
- if (lastNNoses.length > framesNeeded) lastNNoses.length = framesNeeded;
2827
- if (lastNFaces.length > 1) {
2828
- var lastFace = lastNFaces[1];
2829
- var iou = calculateIoU(face.box, lastFace.box);
2830
- lastNFacePairs.unshift({
2831
- a: face,
2832
- b: lastFace,
2791
+ lastNBoxes.unshift(box);
2792
+ if (lastNBoxes.length > framesNeeded) lastNBoxes.length = framesNeeded;
2793
+ if (lastNBoxes.length > 1) {
2794
+ var lastBox = lastNBoxes[1];
2795
+ var iou = calculateIoU(box, lastBox);
2796
+ lastNPairs.unshift({
2797
+ a: box,
2798
+ b: lastBox,
2833
2799
  iou: iou
2834
2800
  });
2835
- if (lastNFacePairs.length > framesNeeded - 1) lastNFacePairs.length = framesNeeded - 1;
2801
+ if (lastNPairs.length > framesNeeded - 1) lastNPairs.length = framesNeeded - 1;
2836
2802
  }
2837
- if (lastNNoses.length > 1) {
2838
- var lastNose = lastNNoses[1];
2839
- var noseDistance = Math.sqrt(Math.pow((nose.x - lastNose.x) / frameWidth, 2) + Math.pow((nose.y - lastNose.y) / frameHeight, 2));
2840
- lastNNosePairs.unshift({
2841
- a: nose,
2842
- b: lastNose,
2843
- distance: noseDistance
2803
+ }
2804
+ var defaultDocumentDetectionBoundaries = {
2805
+ top: 20,
2806
+ bottom: 20,
2807
+ left: 20,
2808
+ right: 20
2809
+ };
2810
+ function processDocumentDetectorPrediction(prediction, thresholds, boundaries) {
2811
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
2812
+ if (boundaries === void 0) {
2813
+ boundaries = defaultDocumentDetectionBoundaries;
2814
+ }
2815
+ var detections = prediction.detections,
2816
+ frameWidth = prediction.frameWidth,
2817
+ frameHeight = prediction.frameHeight,
2818
+ time = prediction.time;
2819
+ var boundaryTop = (_a = boundaries.top) !== null && _a !== void 0 ? _a : 20;
2820
+ var boundaryLeft = (_b = boundaries.left) !== null && _b !== void 0 ? _b : 20;
2821
+ var boundaryRight = (_c = boundaries.right) !== null && _c !== void 0 ? _c : 20;
2822
+ var boundaryBottom = (_d = boundaries.bottom) !== null && _d !== void 0 ? _d : 20;
2823
+ var frameWidth80Pct = frameWidth * 0.8;
2824
+ var detectedObjects = applyNonMaxSuppression(detections.flatMap(function (d) {
2825
+ return d.categories.map(function (category) {
2826
+ return {
2827
+ label: category === null || category === void 0 ? void 0 : category.categoryName,
2828
+ score: category === null || category === void 0 ? void 0 : category.score,
2829
+ box: convertBoundingBox(d.boundingBox)
2830
+ };
2831
+ });
2832
+ }), function (obj) {
2833
+ var _a = obj.box,
2834
+ xMin = _a.xMin,
2835
+ yMin = _a.yMin,
2836
+ width = _a.width,
2837
+ height = _a.height;
2838
+ return yMin > boundaryTop &&
2839
+ // Is it valid top edge of ID detected?
2840
+ yMin + height + boundaryBottom < frameHeight && (
2841
+ // Is it valid bottom edge less than max video height
2842
+ xMin > boundaryLeft || xMin + width > frameWidth80Pct) &&
2843
+ // If either the left side visible or if not, right edge of ID should be more than 80% of width.
2844
+ xMin + width + boundaryRight < frameWidth // Valid right edge if it's less than video width.
2845
+ ;
2846
+ });
2847
+ var allZero = detections.length > 0 && !detections.some(function (_a) {
2848
+ var boundingBox = _a.boundingBox;
2849
+ return Object.values(boundingBox !== null && boundingBox !== void 0 ? boundingBox : {}).some(function (n) {
2850
+ return n > 0;
2851
+ });
2852
+ });
2853
+ var bestIdCardFront = detectedObjects.find(function (obj) {
2854
+ return obj.label === 'Document';
2855
+ });
2856
+ var bestIdCardBack = detectedObjects.find(function (obj) {
2857
+ return obj.label === 'Document back';
2858
+ });
2859
+ var bestPassportPage = detectedObjects.find(function (obj) {
2860
+ return obj.label === 'Passport page';
2861
+ });
2862
+ var bestSinglePage = detectedObjects.find(function (obj) {
2863
+ return obj.label === 'Single page';
2864
+ });
2865
+ var idCardFrontDetectionScore = (_e = bestIdCardFront === null || bestIdCardFront === void 0 ? void 0 : bestIdCardFront.score) !== null && _e !== void 0 ? _e : 0;
2866
+ var idCardBackDetectionScore = (_f = bestIdCardBack === null || bestIdCardBack === void 0 ? void 0 : bestIdCardBack.score) !== null && _f !== void 0 ? _f : 0;
2867
+ var passportDetectionScore = (_g = bestPassportPage === null || bestPassportPage === void 0 ? void 0 : bestPassportPage.score) !== null && _g !== void 0 ? _g : 0;
2868
+ var singlePageDetectionScore = (_h = bestSinglePage === null || bestSinglePage === void 0 ? void 0 : bestSinglePage.score) !== null && _h !== void 0 ? _h : 0;
2869
+ var idCardFrontDetectionThresholdMet = idCardFrontDetectionScore >= ((_j = thresholds.idCardFront) !== null && _j !== void 0 ? _j : 0);
2870
+ var idCardBackDetectionThresholdMet = idCardBackDetectionScore >= ((_k = thresholds.idCardBack) !== null && _k !== void 0 ? _k : 0);
2871
+ var passportDetectionThresholdMet = passportDetectionScore >= ((_l = thresholds.passport) !== null && _l !== void 0 ? _l : 0);
2872
+ var singlePageDetectionThresholdMet = singlePageDetectionScore >= ((_m = thresholds.singlePage) !== null && _m !== void 0 ? _m : 0);
2873
+ var bestDocument = singlePageDetectionThresholdMet ? bestSinglePage : passportDetectionThresholdMet ? bestPassportPage : idCardBackDetectionThresholdMet ? bestIdCardBack : bestIdCardFront;
2874
+ var detectionThreshold = singlePageDetectionThresholdMet ? thresholds.singlePage : passportDetectionThresholdMet ? thresholds.passport : idCardBackDetectionThresholdMet ? thresholds.idCardBack : thresholds.idCardFront;
2875
+ var detectionScore = (_o = bestDocument === null || bestDocument === void 0 ? void 0 : bestDocument.score) !== null && _o !== void 0 ? _o : 0;
2876
+ var detectionThresholdMet = detectionScore >= (detectionThreshold !== null && detectionThreshold !== void 0 ? detectionThreshold : 0);
2877
+ var detectedDocumentType = 'none';
2878
+ if (singlePageDetectionThresholdMet) {
2879
+ detectedDocumentType = 'singlePage';
2880
+ } else if (passportDetectionThresholdMet) {
2881
+ detectedDocumentType = 'passport';
2882
+ } else if (idCardBackDetectionThresholdMet) {
2883
+ detectedDocumentType = 'idCardBack';
2884
+ } else if (detectionThresholdMet) {
2885
+ detectedDocumentType = 'idCardFront';
2886
+ }
2887
+ var documentInBounds = !!bestDocument;
2888
+ if (lastDetectionTime > 0) {
2889
+ trackFramesNeeded$1(1000 / lastDetectionTime);
2890
+ }
2891
+ var documentIsStable = false;
2892
+ var documentTooClose = false;
2893
+ if (bestDocument) {
2894
+ var _q = [bestDocument.box.width / frameWidth, bestDocument.box.height / frameHeight],
2895
+ docWidth = _q[0],
2896
+ docHeight = _q[1];
2897
+ documentTooClose = docWidth > 0.85 || docHeight > 0.85;
2898
+ if (detectionThresholdMet && documentInBounds && !documentTooClose) {
2899
+ var thresholdSet = (_p = thresholds.stability) !== null && _p !== void 0 ? _p : defaultDocumentDetectionThresholds.stability;
2900
+ var threshold_1 = thresholdSet[detectedDocumentType];
2901
+ var framesNeeded = Math.ceil(average(framesNeededSamples$1));
2902
+ trackBox(bestDocument.box, framesNeeded);
2903
+ documentIsStable = lastNBoxes.length >= framesNeeded && !lastNPairs.some(function (pair) {
2904
+ return pair.iou < threshold_1;
2905
+ });
2906
+ }
2907
+ }
2908
+ var bestPDF417;
2909
+ if (detectedObjects.length > 0) {
2910
+ bestPDF417 = detectedObjects.find(function (obj) {
2911
+ return obj.label === 'PDF417';
2844
2912
  });
2845
- if (lastNNosePairs.length > framesNeeded - 1) lastNNosePairs.length = framesNeeded - 1;
2846
2913
  }
2914
+ return {
2915
+ prediction: prediction,
2916
+ detectedObjects: detectedObjects,
2917
+ detectionScore: detectionScore,
2918
+ detectionTime: time,
2919
+ detectionThresholdMet: detectionThresholdMet,
2920
+ detectedDocumentType: detectedDocumentType,
2921
+ idCardFrontDetectionScore: idCardFrontDetectionScore,
2922
+ idCardFrontDetectionThresholdMet: idCardFrontDetectionThresholdMet,
2923
+ idCardBackDetectionScore: idCardBackDetectionScore,
2924
+ idCardBackDetectionThresholdMet: idCardBackDetectionThresholdMet,
2925
+ passportDetectionScore: passportDetectionScore,
2926
+ passportDetectionThresholdMet: passportDetectionThresholdMet,
2927
+ singlePageDetectionScore: singlePageDetectionScore,
2928
+ singlePageDetectionThresholdMet: singlePageDetectionThresholdMet,
2929
+ bestDocument: bestDocument,
2930
+ bestPDF417: bestPDF417,
2931
+ documentInBounds: documentInBounds,
2932
+ documentTooClose: documentTooClose,
2933
+ documentIsStable: documentIsStable,
2934
+ frameWidth: frameWidth,
2935
+ frameHeight: frameHeight,
2936
+ allZero: allZero
2937
+ };
2847
2938
  }
2848
- function makeFaceDetectorPrediction(imageData) {
2849
- if (!detector$1) return null;
2850
- var prediction = detector$1.detectForVideo(imageData, performance.now());
2851
- var faces = prediction.detections.map(function (d) {
2852
- return {
2853
- box: convertBoundingBox(d.boundingBox),
2854
- keypoints: d.keypoints.map(function (k) {
2855
- var _a;
2856
- return _assign(_assign({}, k), {
2857
- x: k.x * imageData.width,
2858
- y: k.y * imageData.height,
2859
- name: (_a = k.label) !== null && _a !== void 0 ? _a : ''
2860
- });
2861
- })
2862
- };
2939
+ function applyNonMaxSuppression(detectedObjects, isGoodBox) {
2940
+ var maxes = {};
2941
+ detectedObjects.forEach(function (obj, i) {
2942
+ if (obj) {
2943
+ if (!maxes[obj.label]) maxes[obj.label] = [0, -1];
2944
+ if (obj.score > maxes[obj.label][0] && (isGoodBox === null || isGoodBox === void 0 ? void 0 : isGoodBox(obj))) maxes[obj.label] = [obj.score, i];
2945
+ }
2863
2946
  });
2864
- return _assign(_assign({}, prediction), {
2865
- faces: faces
2947
+ return Object.keys(maxes).map(function (label) {
2948
+ return detectedObjects[maxes[label][1]];
2949
+ }).filter(function (obj) {
2950
+ return !!obj;
2866
2951
  });
2867
2952
  }
2868
- function processFaceDetectorPrediction(_a) {
2869
- var faces = _a.faces,
2870
- videoWidth = _a.videoWidth,
2871
- videoHeight = _a.videoHeight,
2872
- _b = _a.requireVerticalFaceCentering,
2873
- requireVerticalFaceCentering = _b === void 0 ? true : _b,
2874
- _c = _a.stabilityThreshold,
2875
- stabilityThreshold = _c === void 0 ? 0.7 : _c,
2876
- _d = _a.noseDistanceThreshold,
2877
- noseDistanceThreshold = _d === void 0 ? 0.025 : _d,
2878
- _e = _a.xBoundary,
2879
- xBoundary = _e === void 0 ? 0.01 : _e,
2880
- // this represents the edge that the sides of the face box should not cross -- 1% of video width
2881
- _f = _a.yBoundary,
2882
- // this represents the edge that the sides of the face box should not cross -- 1% of video width
2883
- yBoundary = _f === void 0 ? 0.01 : _f,
2884
- // this represents the edge that the top or bottom of the face box should not cross -- 1% of video height
2885
- _g = _a.xCentroidBoundary,
2886
- // this represents the edge that the top or bottom of the face box should not cross -- 1% of video height
2887
- xCentroidBoundary = _g === void 0 ? 0.125 : _g,
2888
- // this represents the edge that the centroid of the face should not cross -- 12.5% of video width
2889
- _h = _a.yCentroidBoundary,
2890
- // this represents the edge that the centroid of the face should not cross -- 12.5% of video width
2891
- yCentroidBoundary = _h === void 0 ? 0.125 : _h,
2892
- // this represents the edge that the centroid of the face should not cross -- 12.5% of video height
2893
- _j = _a.foreheadRatio,
2894
- // this represents the edge that the centroid of the face should not cross -- 12.5% of video height
2895
- foreheadRatio = _j === void 0 ? 0.275 : _j,
2896
- // we found that the bounding box ends at the brow and misses the forehead. this ratio represents how much we should extend the box to include the forehead.
2897
- _k = _a.noseTrackingThreshold,
2898
- // we found that the bounding box ends at the brow and misses the forehead. this ratio represents how much we should extend the box to include the forehead.
2899
- noseTrackingThreshold = _k === void 0 ? 0.2 : _k,
2900
- // this represents the maximum distance that the nose can be from the center of the face box -- 20% of the face box width or height
2901
- minCaptureBrightnessThreshold = _a.minCaptureBrightnessThreshold,
2902
- minCaptureRangeThreshold = _a.minCaptureRangeThreshold,
2903
- minCaptureVarianceThreshold = _a.minCaptureVarianceThreshold,
2904
- brightness = _a.brightness,
2905
- range = _a.range,
2906
- variance = _a.variance;
2907
- var face = faces[0];
2908
- var faceNotDetected = faces.length === 0;
2909
- var faceNotCentered = false,
2910
- faceLookingAway = false,
2911
- faceTooClose = false,
2912
- faceTooFar = false,
2913
- faceVisibilityTooLow = false;
2914
- var hasAnyThreshold = minCaptureBrightnessThreshold !== undefined || minCaptureRangeThreshold !== undefined || minCaptureVarianceThreshold !== undefined;
2915
- if (hasAnyThreshold) {
2916
- var tooDark = minCaptureBrightnessThreshold !== undefined && brightness !== undefined && brightness < minCaptureBrightnessThreshold;
2917
- var tooLowRange = minCaptureRangeThreshold !== undefined && range !== undefined && range < minCaptureRangeThreshold;
2918
- var tooLowVariance = minCaptureVarianceThreshold !== undefined && variance !== undefined && variance < minCaptureVarianceThreshold;
2919
- faceVisibilityTooLow = !!(tooDark || tooLowRange || tooLowVariance);
2920
- }
2921
- if (face && !faceVisibilityTooLow) {
2922
- // calculate frame centroids
2923
- var frameCX = videoWidth / 2;
2924
- var frameCY = videoHeight / 2;
2925
- // calculate head bounding box, with forehead extension
2926
- var foreheadSize = face.box.height * foreheadRatio;
2927
- var headXMin = face.box.xMin;
2928
- var headXMax = face.box.xMax;
2929
- var headYMin = face.box.yMin - foreheadSize;
2930
- var headYMax = face.box.yMax;
2931
- // calculate head centroids
2932
- var headCX = (headXMin + headXMax) / 2;
2933
- var headCY = (headYMin + headYMax) / 2;
2934
- // calculate thresholds
2935
- var vTX = videoWidth * xBoundary;
2936
- var vTY = videoHeight * yBoundary;
2937
- var vCTX = videoWidth * xCentroidBoundary;
2938
- var vCTY = videoHeight * yCentroidBoundary;
2939
- var faceNotCenteredHorizontally = Math.abs(frameCX - headCX) > vCTX;
2940
- var faceNotCenteredVertically = Math.abs(frameCY - headCY) > vCTY;
2941
- var faceViolatesHorizontalBoundary = headXMin < vTX || headXMax > videoWidth - vTX;
2942
- var faceViolatesVerticalBoundary = headYMin < vTY || headYMax > videoHeight - vTY;
2943
- faceNotCentered = faceViolatesHorizontalBoundary || faceViolatesVerticalBoundary || faceNotCenteredHorizontally || requireVerticalFaceCentering && faceNotCenteredVertically;
2944
- var isMobile = videoWidth < videoHeight;
2945
- var tooCloseMultiple = 1.5;
2946
- var tooFarMultiple = isMobile ? 6 : 7;
2947
- faceTooClose = face.box.width > videoWidth / tooCloseMultiple;
2948
- faceTooFar = face.box.width < videoWidth / tooFarMultiple;
2949
- var nose = face.keypoints[2];
2950
- var fTW = face.box.width * noseTrackingThreshold;
2951
- var fTH = face.box.height * noseTrackingThreshold;
2952
- faceLookingAway = !nose || Math.abs(headCX - nose.x) > fTW || Math.abs(headCY - nose.y) > fTH;
2953
- }
2954
- var faceInGuides = !faceNotDetected && !faceNotCentered && !faceLookingAway && !faceTooClose && !faceTooFar;
2955
- if (lastFaceDetectionTime > 0) {
2956
- trackFramesNeeded$1(500 / lastFaceDetectionTime);
2957
- }
2958
- var faceIsStable = false,
2959
- noseIsStable = false;
2960
- if (faceInGuides && !faceVisibilityTooLow) {
2961
- var framesNeeded = Math.max(Math.ceil(average(framesNeededSamples$1)), 5);
2962
- trackFace(face, framesNeeded, videoWidth, videoHeight);
2963
- faceIsStable = lastNFaces.length >= framesNeeded && !lastNFacePairs.some(function (pair) {
2964
- return pair.iou < stabilityThreshold;
2965
- });
2966
- noseIsStable = lastNNoses.length >= framesNeeded && !lastNNosePairs.some(function (pair) {
2967
- return pair.distance > noseDistanceThreshold;
2968
- });
2969
- }
2970
- var faceReady = faceInGuides && faceIsStable && noseIsStable && !faceVisibilityTooLow;
2971
- return {
2972
- face: face,
2973
- faceNotDetected: faceNotDetected,
2974
- faceNotCentered: faceNotCentered,
2975
- faceLookingAway: faceLookingAway,
2976
- faceTooClose: faceTooClose,
2977
- faceTooFar: faceTooFar,
2978
- faceReady: faceReady,
2979
- faceReadyAt: faceReady ? new Date() : null,
2980
- faceIsStable: faceIsStable,
2981
- noseIsStable: noseIsStable,
2982
- faceVisibilityTooLow: faceVisibilityTooLow
2983
- };
2984
- }
2985
- function testFaceDetectionAgainstKnownImage(detector) {
2953
+ function testDocumentDetectionAgainstKnownImage(detector) {
2986
2954
  return new Promise(function (resolve, reject) {
2987
2955
  var img = new Image();
2988
2956
  img.crossOrigin = 'anonymous';
2989
2957
  img.onload = function () {
2990
2958
  var prediction = detector.detectForVideo(img, performance.now());
2991
2959
  if (prediction.detections.length > 0) {
2992
- debug('face detection test result', prediction.detections);
2960
+ debug('document detection test result', prediction.detections);
2993
2961
  resolve(void 0);
2994
2962
  } else {
2995
- warn('face detection test failed');
2996
- reject(new Error('testFaceDetectionAgainstKnownImage failed to predict'));
2963
+ warn('document detection test failed');
2964
+ reject(new Error('testDocumentDetectionAgainstKnownImage failed to predict'));
2997
2965
  }
2998
2966
  };
2999
2967
  img.onerror = function () {
3000
- return reject(new Error('testFaceDetectionAgainstKnownImage failed to load image'));
2968
+ return reject(new Error('testDocumentDetectionAgainstKnownImage failed to load image'));
3001
2969
  };
3002
- img.src = "".concat(DEFAULT_CDN_URL, "/head-test.jpg");
2970
+ img.src = "".concat(DEFAULT_CDN_URL, "/id-card-test.jpg");
3003
2971
  });
3004
2972
  }
3005
2973
 
3006
- var preloadModels = function preloadModels(_a) {
3007
- return __awaiter(void 0, [_a], void 0, function (_b) {
3008
- var preloadTasks;
3009
- var _c = _b.documentDetectionModel,
3010
- documentDetectionModel = _c === void 0 ? true : _c,
3011
- _d = _b.focusModel,
3012
- focusModel = _d === void 0 ? true : _d,
3013
- _e = _b.faceDetectionModel,
3014
- faceDetectionModel = _e === void 0 ? true : _e;
3015
- return __generator(this, function (_f) {
3016
- switch (_f.label) {
3017
- case 0:
3018
- return [4 /*yield*/, probeModelCapabilities()];
3019
- case 1:
3020
- _f.sent();
3021
- preloadTasks = [];
3022
- if (documentDetectionModel) {
3023
- preloadTasks.push(preloadDocumentDetectorDependencies);
3024
- }
3025
- if (focusModel) {
3026
- preloadTasks.push(preloadFocusModelDependencies);
3027
- }
3028
- if (faceDetectionModel) {
3029
- preloadTasks.push(preloadFaceDetectorDependencies);
3030
- }
3031
- return [4 /*yield*/, Promise.all(preloadTasks)];
3032
- case 2:
3033
- _f.sent();
3034
- return [2 /*return*/];
3035
- }
3036
- });
3037
- });
3038
- };
3039
- var progressByUrl = {};
3040
- var progressByUseCase = {
3041
- visionRuntime: {
3042
- loaded: 0,
3043
- total: 0
3044
- },
3045
- documentDetection: {
3046
- loaded: 0,
3047
- total: 0
3048
- },
3049
- focus: {
3050
- loaded: 0,
3051
- total: 0
3052
- },
3053
- faceDetection: {
3054
- loaded: 0,
3055
- total: 0
2974
+ function getFrameDimensions(frame) {
2975
+ var frameWidth = frame.width,
2976
+ frameHeight = frame.height;
2977
+ if (frame instanceof HTMLImageElement) {
2978
+ frameWidth = frame.naturalWidth;
2979
+ frameHeight = frame.naturalHeight;
3056
2980
  }
3057
- };
3058
- function preloadDependency(url) {
3059
- return __awaiter(this, void 0, void 0, function () {
3060
- return __generator(this, function (_a) {
3061
- return [2 /*return*/, new Promise(function (resolve, reject) {
3062
- var req = new XMLHttpRequest();
3063
- req.addEventListener('progress', function (event) {
3064
- if (!event.lengthComputable) return;
3065
- progressByUrl[url] = event;
3066
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress', {
3067
- detail: {
3068
- url: url,
3069
- loaded: event.loaded,
3070
- total: event.total
3071
- }
3072
- }));
3073
- });
3074
- req.addEventListener('loadend', function () {
3075
- resolve(req.readyState === 4 && req.status === 200);
3076
- });
3077
- req.addEventListener('error', reject);
3078
- req.open('GET', url, true);
3079
- req.send();
3080
- })];
3081
- });
3082
- });
2981
+ if (frame instanceof HTMLVideoElement) {
2982
+ frameWidth = frame.videoWidth;
2983
+ frameHeight = frame.videoHeight;
2984
+ }
2985
+ return [frameWidth, frameHeight];
3083
2986
  }
3084
- var documentDetectorPreloading = false,
3085
- focusModelPreloading = false,
3086
- faceDetectorPreloading = false;
3087
- function preloadDocumentDetectorDependencies() {
3088
- return __awaiter(this, void 0, void 0, function () {
3089
- function handleDownloadProgress(event) {
3090
- var detail = event.detail;
3091
- if (!dependencies.includes(detail.url)) return;
3092
- progressByUseCase.documentDetection = sumUpProgressForDependencies(dependencies);
3093
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.documentDetection', {
3094
- detail: progressByUseCase.documentDetection
3095
- }));
3096
- }
3097
- var dependencies;
3098
- return __generator(this, function (_a) {
3099
- switch (_a.label) {
3100
- case 0:
3101
- if (documentDetectorPreloading) return [2 /*return*/, new Promise(function (resolve) {
3102
- var i = setInterval(function () {
3103
- if (!documentDetectorPreloading) {
3104
- clearInterval(i);
3105
- resolve();
3106
- }
3107
- }, 100);
3108
- })];
3109
- documentDetectorPreloading = true;
3110
- return [4 /*yield*/, probeModelCapabilities()];
3111
- case 1:
3112
- _a.sent();
3113
- if (modelCapabilities.delegate === 'NONE') {
3114
- throw new Error('No available delegate for document detector.');
3115
- }
3116
- dependencies = [defaultDocumentDetectorModelPath];
3117
- document.addEventListener('idmission.preloadProgress', handleDownloadProgress);
3118
- _a.label = 2;
3119
- case 2:
3120
- _a.trys.push([2,, 4, 5]);
3121
- return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
3122
- case 3:
3123
- _a.sent();
3124
- return [3 /*break*/, 5];
3125
- case 4:
3126
- document.removeEventListener('idmission.preloadProgress', handleDownloadProgress);
3127
- documentDetectorPreloading = false;
3128
- return [7 /*endfinally*/];
3129
- case 5:
3130
- return [2 /*return*/];
3131
- }
3132
- });
3133
- });
2987
+
2988
+ var InvisibleCanvasContainer = styled.div(templateObject_1$M || (templateObject_1$M = __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 pointer-events: none;\n user-select: none;\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 pointer-events: none;\n user-select: none;\n"])));
2989
+ var InvisibleCanvas = styled.canvas(templateObject_2$G || (templateObject_2$G = __makeTemplateObject(["\n display: none;\n"], ["\n display: none;\n"])));
2990
+ function drawToCanvas(canvas, frame, width, height) {
2991
+ if (!canvas) return;
2992
+ var ctx = canvas.getContext('2d');
2993
+ if (!ctx) return;
2994
+ if (!width || !height) {
2995
+ var _a = getFrameDimensions(frame),
2996
+ frameWidth = _a[0],
2997
+ frameHeight = _a[1];
2998
+ width || (width = frameWidth);
2999
+ height || (height = frameHeight);
3000
+ }
3001
+ canvas.width = width;
3002
+ canvas.height = height;
3003
+ ctx.drawImage(frame, 0, 0, width, height);
3134
3004
  }
3135
- function preloadFocusModelDependencies() {
3136
- return __awaiter(this, void 0, void 0, function () {
3137
- function handleModelDownloadProgress(event) {
3138
- var detail = event.detail;
3139
- if (!dependencies.includes(detail.url)) return;
3140
- progressByUseCase.focus = sumUpProgressForDependencies(dependencies);
3141
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.focus', {
3142
- detail: progressByUseCase.focus
3143
- }));
3144
- }
3145
- var dependencies;
3146
- return __generator(this, function (_a) {
3147
- switch (_a.label) {
3148
- case 0:
3149
- if (focusModelPreloading) return [2 /*return*/, new Promise(function (resolve) {
3150
- var i = setInterval(function () {
3151
- if (!focusModelPreloading) {
3152
- clearInterval(i);
3153
- resolve();
3154
- }
3155
- }, 100);
3156
- })];
3157
- focusModelPreloading = true;
3158
- return [4 /*yield*/, probeModelCapabilities()];
3159
- case 1:
3160
- _a.sent();
3161
- if (modelCapabilities.delegate === 'NONE') {
3162
- throw new Error('No available delegate for document detector.');
3005
+ function clearCanvas(canvas) {
3006
+ var _a;
3007
+ (_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);
3008
+ }
3009
+ var templateObject_1$M, templateObject_2$G;
3010
+
3011
+ function useFrameLoop(fn, options) {
3012
+ if (options === void 0) {
3013
+ options = {};
3014
+ }
3015
+ var _a = useState(false),
3016
+ running = _a[0],
3017
+ setRunning = _a[1];
3018
+ var startedAtRef = useRef(null);
3019
+ var loopId = useRef(0);
3020
+ var frameId = useRef(0);
3021
+ useEffect(function runFrameLoop() {
3022
+ if (!running) return;
3023
+ var timer;
3024
+ var currentLoopId = loopId.current;
3025
+ function hotLoop() {
3026
+ return __awaiter(this, void 0, void 0, function () {
3027
+ var start, timeRunning, took, amountToThrottle;
3028
+ var _a, _b, _c;
3029
+ return __generator(this, function (_d) {
3030
+ switch (_d.label) {
3031
+ case 0:
3032
+ if (currentLoopId !== loopId.current) return [2 /*return*/];
3033
+ start = new Date().getTime();
3034
+ timeRunning = start - ((_b = (_a = startedAtRef.current) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0);
3035
+ return [4 /*yield*/, fn(frameId.current, timeRunning)];
3036
+ case 1:
3037
+ _d.sent();
3038
+ took = new Date().getTime() - start;
3039
+ amountToThrottle = Math.max(((_c = options.throttleMs) !== null && _c !== void 0 ? _c : 0) - took, 0);
3040
+ timer = setTimeout(function () {
3041
+ frameId.current = requestAnimationFrame(hotLoop);
3042
+ }, amountToThrottle);
3043
+ return [2 /*return*/];
3163
3044
  }
3164
- dependencies = [defaultFocusModelPath];
3165
- document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
3166
- _a.label = 2;
3167
- case 2:
3168
- _a.trys.push([2,, 4, 5]);
3169
- return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
3170
- case 3:
3171
- _a.sent();
3172
- return [3 /*break*/, 5];
3173
- case 4:
3174
- document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
3175
- focusModelPreloading = false;
3176
- return [7 /*endfinally*/];
3177
- case 5:
3178
- return [2 /*return*/];
3179
- }
3180
- });
3181
- });
3045
+ });
3046
+ });
3047
+ }
3048
+ void hotLoop();
3049
+ return function () {
3050
+ loopId.current += 1;
3051
+ if (frameId.current) cancelAnimationFrame(frameId.current);
3052
+ if (timer) clearTimeout(timer);
3053
+ };
3054
+ }, [fn, running, options.throttleMs]);
3055
+ var start = useCallback(function () {
3056
+ startedAtRef.current = new Date();
3057
+ setRunning(true);
3058
+ }, []);
3059
+ var stop = useCallback(function () {
3060
+ loopId.current += 1; // force the loop to stop immediately.
3061
+ setRunning(false);
3062
+ startedAtRef.current = null;
3063
+ }, []);
3064
+ useEffect(function startAutomatically() {
3065
+ if (options.autoStart) start();
3066
+ return stop;
3067
+ }, [options.autoStart, start, stop]);
3068
+ return {
3069
+ start: start,
3070
+ stop: stop
3071
+ };
3182
3072
  }
3183
- function preloadFaceDetectorDependencies() {
3184
- return __awaiter(this, void 0, void 0, function () {
3185
- function handleModelDownloadProgress(event) {
3186
- var detail = event.detail;
3187
- if (!dependencies.includes(detail.url)) return;
3188
- progressByUseCase.faceDetection = sumUpProgressForDependencies(dependencies);
3189
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.faceDetection', {
3190
- detail: progressByUseCase.faceDetection
3191
- }));
3073
+
3074
+ function listAvailableCameras(facingMode_1) {
3075
+ return __awaiter(this, arguments, void 0, function (facingMode, requestMicAccess) {
3076
+ var cameraEnumerationStream, allDevices, allowedVideoDevices;
3077
+ if (requestMicAccess === void 0) {
3078
+ requestMicAccess = false;
3192
3079
  }
3193
- var dependencies;
3194
3080
  return __generator(this, function (_a) {
3195
3081
  switch (_a.label) {
3196
3082
  case 0:
3197
- if (faceDetectorPreloading) return [2 /*return*/, new Promise(function (resolve) {
3198
- var i = setInterval(function () {
3199
- if (!faceDetectorPreloading) {
3200
- clearInterval(i);
3201
- resolve();
3083
+ return [4 /*yield*/, navigator.mediaDevices.getUserMedia({
3084
+ video: {
3085
+ facingMode: {
3086
+ exact: facingMode
3202
3087
  }
3203
- }, 100);
3204
- })];
3205
- faceDetectorPreloading = true;
3206
- return [4 /*yield*/, probeModelCapabilities()];
3088
+ },
3089
+ audio: requestMicAccess
3090
+ })
3091
+ // This lists all available cameras attached to the user's device.
3092
+ ];
3207
3093
  case 1:
3208
- _a.sent();
3209
- if (modelCapabilities.delegate === 'NONE') {
3210
- throw new Error('No available delegate for document detector.');
3211
- }
3212
- dependencies = [defaultFaceDetectorModelPath];
3213
- document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
3214
- _a.label = 2;
3094
+ cameraEnumerationStream = _a.sent();
3095
+ return [4 /*yield*/, navigator.mediaDevices.enumerateDevices()];
3215
3096
  case 2:
3216
- _a.trys.push([2,, 4, 5]);
3217
- return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
3218
- case 3:
3219
- _a.sent();
3220
- return [3 /*break*/, 5];
3221
- case 4:
3222
- document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
3223
- faceDetectorPreloading = false;
3224
- return [7 /*endfinally*/];
3225
- case 5:
3226
- return [2 /*return*/];
3097
+ allDevices = _a.sent();
3098
+ allowedVideoDevices = allDevices.filter(function (_a) {
3099
+ var kind = _a.kind,
3100
+ label = _a.label;
3101
+ return kind === 'videoinput' && !label.toLowerCase().includes('virtual');
3102
+ });
3103
+ // Release the access to the user's camera that we obtained for enumeration purposes.
3104
+ cameraEnumerationStream.getVideoTracks().forEach(function (track) {
3105
+ track.enabled = false;
3106
+ track.stop();
3107
+ });
3108
+ cameraEnumerationStream = null;
3109
+ return [2 /*return*/, allowedVideoDevices];
3227
3110
  }
3228
3111
  });
3229
3112
  });
3230
3113
  }
3231
- function progressToPercentage(progress) {
3232
- return progress.total > 0 ? Math.round(100.0 * progress.loaded / progress.total) : 0;
3233
- }
3234
- function sumUpProgressForDependencies(dependencies) {
3235
- return dependencies.reduce(function (result, dependency) {
3236
- var dependencyProgress = progressByUrl[dependency];
3237
- if (!dependencyProgress) return result;
3238
- result.loaded += dependencyProgress.loaded;
3239
- result.total += dependencyProgress.total;
3240
- return result;
3241
- }, {
3242
- loaded: 0,
3243
- total: 0
3114
+ var frontCameraLabels = ['front', 'avant', 'anteriore', 'cameraaanvoorzijde', 'kamerapåframsidan', 'forsidekamera', 'kamerapåforsiden', 'aparatprzedni', 'etukamera', 'kameradepan', 'ÖnKamera', 'cameramặttrước', 'camerăfață', 'prednákamera', 'prednjakamera', 'előlapikamera', 'přednífotoaparát', 'μπροστινήκάμερα', 'переднякамера', 'передняякамера', 'преднакамера', 'алдыңғыкамера', 'מצלמה קדמית', 'الكاميرا الأمامية', 'फ़्रंटकैमरा', '前置相机', '前置鏡頭', '前面カメラ', '전면카메라', 'กล้องด้านหน้า'].map(function (s) {
3115
+ return s.toLocaleLowerCase().split(' ').join('');
3116
+ });
3117
+ var rearCameraLabels = ['back', 'rear', 'posterior', 'trasera', 'traseira', 'arrière', 'rückkamera', 'fotocamera(posteriore)', 'cameraaanachterzijde', 'kamerapåbaksidan', 'kamerapåbaksiden', 'bagsidekamera', 'aparattylny', 'takakamera', 'arkakamera', 'kamerabelakang', 'cameramặtsau', 'camerăspate', 'stražnjakamera', 'zadnákamera', 'hátoldalikamera', 'zadnífotoaparát', 'πίσωκάμερα', 'заднякамера', 'Задняякамера', 'заднакамера', 'артқыкамера', 'מצלמה אחורית', 'الكاميرا الخلفية', 'बैककैमरा', '后置相机', '後置鏡頭', '背面カメラ', '후면카메라', 'กล้องด้านหลัง'].map(function (s) {
3118
+ return s.toLocaleLowerCase().split(' ').join('');
3119
+ });
3120
+ var backUltraWideCameraLabels = ['backdualwidecamera', 'backultrawidecamera', 'ultraampliaposterior', 'ultra-angulartraseira', 'ultragrandeangulartraseira', 'ultragrandangle', 'ultragranangular', 'ultra-weitwinkelkamera', 'ultra-grandangolo', 'ultrabredecameraaanachterzijde', 'ultravidvinkelkamerapåbaksidan', 'ultravidvinkelkameraetpåbagsiden', 'ultravidvinkelkamerabak', 'ultragenişkameraarkayüzü', 'ultralaajakulmainentakakamera', 'tylnyaparatultraszerokokątny', 'cameracựcrộngmặtsau', 'camerăcuobiectivultra‑superangularspate', 'ultraszéleslátószögűkamera', 'kameraultralebarbelakang', 'stražnjaultraširokakamera', 'zadníultraširokoúhlýfotoaparát', 'ultraširokouhlá', 'πίσωυπερευρείακάμερα', 'заднянадширококутнакамера', 'Задняясверхширокоугольнаякамера', 'Задна свръх широкоъгълна камера', 'артқыультракеңбұрыштыкамера', 'מצלמה אולטרה רחבה אחורית', 'كاميرا خلفية عريضة جدًا', 'बैकअल्ट्रावाइडकैमरा', '后置超广角相机', '後置超廣角鏡頭相機', '背面超広角カメラ', '후면울트라와이드카메라', 'กล้องด้านหลังอัลตร้าไวด์'].map(function (s) {
3121
+ return s.toLocaleLowerCase().split(' ').join('');
3122
+ });
3123
+ var cameraLabelMatches = function cameraLabelMatches(labelOrDevice, labelSetOrLabel) {
3124
+ var label = labelOrDevice instanceof MediaDeviceInfo ? getDeviceLabel(labelOrDevice) : labelOrDevice;
3125
+ var labelSet = typeof labelSetOrLabel === 'string' ? [labelSetOrLabel] : labelSetOrLabel;
3126
+ return labelSet.some(function (l) {
3127
+ return label.includes(l);
3244
3128
  });
3245
- }
3246
-
3247
- var defaultDocumentDetectionScoreThreshold = 0.1;
3248
- var defaultDocumentDetectionModelLoadTimeoutMs = 45000;
3249
- var defaultDocumentDetectionThresholds = {
3250
- idCardFront: 0.6,
3251
- idCardBack: 0.6,
3252
- passport: 0.4,
3253
- singlePage: 0.4,
3254
- stability: {
3255
- idCardFront: 0.85,
3256
- idCardBack: 0.85,
3257
- passport: 0.5,
3258
- singlePage: 0.5
3259
- }
3260
3129
  };
3261
- var documentTypeDisplayNames = {
3262
- idCardFront: 'ID card front',
3263
- idCardBack: 'ID card back',
3264
- passport: 'Passport',
3265
- singlePage: 'Single page',
3266
- none: 'None'
3130
+ var getDeviceLabel = function getDeviceLabel(deviceInfo) {
3131
+ return deviceInfo.label.toLocaleLowerCase().split(' ').join('');
3267
3132
  };
3268
- var detector = null;
3269
- var detectorSettings = null;
3270
- function loadDocumentDetector() {
3271
- return __awaiter(this, arguments, void 0, function (modelAssetPath, scoreThreshold) {
3272
- var _a, _b;
3273
- if (modelAssetPath === void 0) {
3274
- modelAssetPath = defaultDocumentDetectorModelPath;
3275
- }
3276
- if (scoreThreshold === void 0) {
3277
- scoreThreshold = defaultDocumentDetectionScoreThreshold;
3278
- }
3279
- return __generator(this, function (_c) {
3280
- switch (_c.label) {
3281
- case 0:
3282
- 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];
3283
- closeDocumentDetector();
3284
- return [4 /*yield*/, preloadDocumentDetectorDependencies()];
3285
- case 1:
3286
- _c.sent();
3287
- if (modelCapabilities.delegate === 'NONE') {
3288
- throw new Error('No available delegate for document detector.');
3289
- }
3290
- _b = (_a = ObjectDetector).createFromOptions;
3291
- return [4 /*yield*/, FilesetResolver.forVisionTasks(visionTasksBasePath)];
3292
- case 2:
3293
- return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
3294
- baseOptions: {
3295
- modelAssetPath: modelAssetPath,
3296
- delegate: modelCapabilities.delegate
3297
- },
3298
- // canvas: document.createElement('canvas'),
3299
- scoreThreshold: scoreThreshold,
3300
- runningMode: 'VIDEO'
3301
- }])];
3302
- case 3:
3303
- detector = _c.sent();
3304
- detectorSettings = {
3305
- modelAssetPath: modelAssetPath,
3306
- scoreThreshold: scoreThreshold
3307
- };
3308
- return [2 /*return*/, detector];
3309
- }
3310
- });
3311
- });
3312
- }
3313
- function closeDocumentDetector() {
3314
- detector === null || detector === void 0 ? void 0 : detector.close();
3315
- detector = null;
3316
- detectorSettings = null;
3317
- }
3318
- function useLoadDocumentDetector(_a) {
3319
- var _b = _a.shouldLoadModels,
3320
- shouldLoadModels = _b === void 0 ? true : _b,
3321
- _c = _a.modelPath,
3322
- modelPath = _c === void 0 ? defaultDocumentDetectorModelPath : _c,
3323
- _d = _a.modelLoadTimeoutMs,
3324
- modelLoadTimeoutMs = _d === void 0 ? defaultDocumentDetectionModelLoadTimeoutMs : _d,
3325
- _e = _a.scoreThreshold,
3326
- scoreThreshold = _e === void 0 ? defaultDocumentDetectionScoreThreshold : _e,
3327
- onModelError = _a.onModelError,
3328
- videoRef = _a.videoRef;
3329
- var _f = useState('not-started'),
3330
- modelLoadState = _f[0],
3331
- setModelLoadState = _f[1];
3332
- var _g = useState(null),
3333
- modelWarmingStartedAt = _g[0],
3334
- setModelWarmingStartedAt = _g[1];
3335
- var _h = useState(0),
3336
- modelDownloadProgress = _h[0],
3337
- setModelDownloadProgress = _h[1];
3338
- var _j = useState(null),
3339
- modelError = _j[0],
3340
- setModelError = _j[1];
3341
- useEffect(function loadModel() {
3342
- var _this = this;
3343
- if (!shouldLoadModels) return;
3344
- setModelLoadState('downloading');
3345
- setModelWarmingStartedAt(null);
3346
- function handleDownloadProgress(event) {
3347
- setModelDownloadProgress(progressToPercentage(event.detail));
3348
- }
3349
- document.addEventListener('idmission.preloadProgress.documentDetection', handleDownloadProgress);
3350
- var modelLoadTimeout = setTimeout(function () {
3351
- setModelError(new Error('Model loading time limit exceeded.'));
3352
- }, modelLoadTimeoutMs);
3353
- var cancelVideoReady = function cancelVideoReady() {};
3354
- loadDocumentDetector(modelPath, scoreThreshold).then(function (model) {
3355
- return __awaiter(_this, void 0, void 0, function () {
3356
- var _a, videoReady, cancel, cancelled;
3357
- return __generator(this, function (_b) {
3358
- switch (_b.label) {
3359
- case 0:
3360
- setModelDownloadProgress(100);
3361
- setModelLoadState('warming');
3362
- setModelWarmingStartedAt(new Date().getTime());
3363
- clearTimeout(modelLoadTimeout);
3364
- return [4 /*yield*/, testDocumentDetectionAgainstKnownImage(model)];
3365
- case 1:
3366
- _b.sent();
3367
- _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
3368
- cancelled = false;
3369
- cancelVideoReady = function cancelVideoReady() {
3370
- cancelled = true;
3371
- cancel();
3372
- };
3373
- return [4 /*yield*/, videoReady];
3374
- case 2:
3375
- _b.sent();
3376
- setTimeout(function () {
3377
- if (cancelled) return;
3378
- model.detectForVideo(videoRef.current, performance.now());
3379
- setModelLoadState('ready');
3380
- }, 500);
3381
- return [2 /*return*/];
3382
- }
3383
- });
3384
- });
3385
- })["catch"](function (e) {
3386
- setModelError(e);
3387
- setModelLoadState('error');
3388
- })["finally"](function () {
3389
- clearTimeout(modelLoadTimeout);
3390
- });
3391
- return function () {
3392
- log('unloading document detection model');
3393
- cancelVideoReady();
3394
- closeDocumentDetector();
3395
- clearTimeout(modelLoadTimeout);
3396
- document.removeEventListener('idmission.preloadProgress.documentDetection', handleDownloadProgress);
3397
- };
3398
- }, [shouldLoadModels, modelLoadTimeoutMs, modelPath, scoreThreshold, videoRef]);
3399
- useEffect(function handleModelError() {
3400
- if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
3401
- }, [modelError, onModelError]);
3402
- return useMemo(function () {
3403
- return {
3404
- ready: modelLoadState === 'ready',
3405
- modelLoadState: modelLoadState,
3406
- modelDownloadProgress: modelDownloadProgress,
3407
- modelWarmingStartedAt: modelWarmingStartedAt,
3408
- modelError: modelError,
3409
- setModelError: setModelError
3410
- };
3411
- }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
3412
- }
3413
- function makeDocumentDetectorPrediction(frame) {
3414
- return __awaiter(this, void 0, void 0, function () {
3415
- var startedAt, prediction, time, frameWidth, frameHeight;
3416
- return __generator(this, function (_a) {
3417
- if (!detector) return [2 /*return*/, null];
3418
- startedAt = new Date();
3419
- // Detectors can throw errors, for example when using custom URLs that
3420
- // contain a model that doesn't provide the expected output.
3421
- try {
3422
- prediction = detector.detectForVideo(frame, performance.now());
3423
- time = new Date().getTime() - startedAt.getTime();
3424
- frameWidth = frame.width;
3425
- frameHeight = frame.height;
3426
- return [2 /*return*/, _assign(_assign({}, prediction), {
3427
- time: time,
3428
- frameWidth: frameWidth,
3429
- frameHeight: frameHeight
3430
- })];
3431
- } catch (e) {
3432
- error('caught object detection error', e);
3433
- }
3434
- return [2 /*return*/, null];
3435
- });
3436
- });
3437
- }
3438
- var lastDetectionAt = 0;
3439
- var lastDetectionTime = 0;
3440
- function setLastDetectionAt(time) {
3441
- lastDetectionTime = time - lastDetectionAt;
3442
- lastDetectionAt = time;
3443
- }
3444
- var framesNeededSamples = [];
3445
- function trackFramesNeeded(value, bufferLength) {
3446
- if (bufferLength === void 0) {
3447
- bufferLength = 25;
3448
- }
3449
- framesNeededSamples.unshift(value);
3450
- if (framesNeededSamples.length > bufferLength) framesNeededSamples.length = bufferLength;
3451
- }
3452
- var lastNBoxes = [];
3453
- var lastNPairs = [];
3454
- function trackBox(box, framesNeeded) {
3455
- if (framesNeeded === void 0) {
3456
- framesNeeded = 12;
3457
- }
3458
- lastNBoxes.unshift(box);
3459
- if (lastNBoxes.length > framesNeeded) lastNBoxes.length = framesNeeded;
3460
- if (lastNBoxes.length > 1) {
3461
- var lastBox = lastNBoxes[1];
3462
- var iou = calculateIoU(box, lastBox);
3463
- lastNPairs.unshift({
3464
- a: box,
3465
- b: lastBox,
3466
- iou: iou
3467
- });
3468
- if (lastNPairs.length > framesNeeded - 1) lastNPairs.length = framesNeeded - 1;
3469
- }
3470
- }
3471
- var defaultDocumentDetectionBoundaries = {
3472
- top: 20,
3473
- bottom: 20,
3474
- left: 20,
3475
- right: 20
3476
- };
3477
- function processDocumentDetectorPrediction(prediction, thresholds, boundaries) {
3478
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
3479
- if (boundaries === void 0) {
3480
- boundaries = defaultDocumentDetectionBoundaries;
3481
- }
3482
- var detections = prediction.detections,
3483
- frameWidth = prediction.frameWidth,
3484
- frameHeight = prediction.frameHeight,
3485
- time = prediction.time;
3486
- var boundaryTop = (_a = boundaries.top) !== null && _a !== void 0 ? _a : 20;
3487
- var boundaryLeft = (_b = boundaries.left) !== null && _b !== void 0 ? _b : 20;
3488
- var boundaryRight = (_c = boundaries.right) !== null && _c !== void 0 ? _c : 20;
3489
- var boundaryBottom = (_d = boundaries.bottom) !== null && _d !== void 0 ? _d : 20;
3490
- var frameWidth80Pct = frameWidth * 0.8;
3491
- var detectedObjects = applyNonMaxSuppression(detections.flatMap(function (d) {
3492
- return d.categories.map(function (category) {
3493
- return {
3494
- label: category === null || category === void 0 ? void 0 : category.categoryName,
3495
- score: category === null || category === void 0 ? void 0 : category.score,
3496
- box: convertBoundingBox(d.boundingBox)
3497
- };
3498
- });
3499
- }), function (obj) {
3500
- var _a = obj.box,
3501
- xMin = _a.xMin,
3502
- yMin = _a.yMin,
3503
- width = _a.width,
3504
- height = _a.height;
3505
- return yMin > boundaryTop &&
3506
- // Is it valid top edge of ID detected?
3507
- yMin + height + boundaryBottom < frameHeight && (
3508
- // Is it valid bottom edge less than max video height
3509
- xMin > boundaryLeft || xMin + width > frameWidth80Pct) &&
3510
- // If either the left side visible or if not, right edge of ID should be more than 80% of width.
3511
- xMin + width + boundaryRight < frameWidth // Valid right edge if it's less than video width.
3512
- ;
3513
- });
3514
- var allZero = detections.length > 0 && !detections.some(function (_a) {
3515
- var boundingBox = _a.boundingBox;
3516
- return Object.values(boundingBox !== null && boundingBox !== void 0 ? boundingBox : {}).some(function (n) {
3517
- return n > 0;
3518
- });
3519
- });
3520
- var bestIdCardFront = detectedObjects.find(function (obj) {
3521
- return obj.label === 'Document';
3522
- });
3523
- var bestIdCardBack = detectedObjects.find(function (obj) {
3524
- return obj.label === 'Document back';
3525
- });
3526
- var bestPassportPage = detectedObjects.find(function (obj) {
3527
- return obj.label === 'Passport page';
3528
- });
3529
- var bestSinglePage = detectedObjects.find(function (obj) {
3530
- return obj.label === 'Single page';
3531
- });
3532
- var idCardFrontDetectionScore = (_e = bestIdCardFront === null || bestIdCardFront === void 0 ? void 0 : bestIdCardFront.score) !== null && _e !== void 0 ? _e : 0;
3533
- var idCardBackDetectionScore = (_f = bestIdCardBack === null || bestIdCardBack === void 0 ? void 0 : bestIdCardBack.score) !== null && _f !== void 0 ? _f : 0;
3534
- var passportDetectionScore = (_g = bestPassportPage === null || bestPassportPage === void 0 ? void 0 : bestPassportPage.score) !== null && _g !== void 0 ? _g : 0;
3535
- var singlePageDetectionScore = (_h = bestSinglePage === null || bestSinglePage === void 0 ? void 0 : bestSinglePage.score) !== null && _h !== void 0 ? _h : 0;
3536
- var idCardFrontDetectionThresholdMet = idCardFrontDetectionScore >= ((_j = thresholds.idCardFront) !== null && _j !== void 0 ? _j : 0);
3537
- var idCardBackDetectionThresholdMet = idCardBackDetectionScore >= ((_k = thresholds.idCardBack) !== null && _k !== void 0 ? _k : 0);
3538
- var passportDetectionThresholdMet = passportDetectionScore >= ((_l = thresholds.passport) !== null && _l !== void 0 ? _l : 0);
3539
- var singlePageDetectionThresholdMet = singlePageDetectionScore >= ((_m = thresholds.singlePage) !== null && _m !== void 0 ? _m : 0);
3540
- var bestDocument = singlePageDetectionThresholdMet ? bestSinglePage : passportDetectionThresholdMet ? bestPassportPage : idCardBackDetectionThresholdMet ? bestIdCardBack : bestIdCardFront;
3541
- var detectionThreshold = singlePageDetectionThresholdMet ? thresholds.singlePage : passportDetectionThresholdMet ? thresholds.passport : idCardBackDetectionThresholdMet ? thresholds.idCardBack : thresholds.idCardFront;
3542
- var detectionScore = (_o = bestDocument === null || bestDocument === void 0 ? void 0 : bestDocument.score) !== null && _o !== void 0 ? _o : 0;
3543
- var detectionThresholdMet = detectionScore >= (detectionThreshold !== null && detectionThreshold !== void 0 ? detectionThreshold : 0);
3544
- var detectedDocumentType = 'none';
3545
- if (singlePageDetectionThresholdMet) {
3546
- detectedDocumentType = 'singlePage';
3547
- } else if (passportDetectionThresholdMet) {
3548
- detectedDocumentType = 'passport';
3549
- } else if (idCardBackDetectionThresholdMet) {
3550
- detectedDocumentType = 'idCardBack';
3551
- } else if (detectionThresholdMet) {
3552
- detectedDocumentType = 'idCardFront';
3553
- }
3554
- var documentInBounds = !!bestDocument;
3555
- if (lastDetectionTime > 0) {
3556
- trackFramesNeeded(1000 / lastDetectionTime);
3557
- }
3558
- var documentIsStable = false;
3559
- var documentTooClose = false;
3560
- if (bestDocument) {
3561
- var _q = [bestDocument.box.width / frameWidth, bestDocument.box.height / frameHeight],
3562
- docWidth = _q[0],
3563
- docHeight = _q[1];
3564
- documentTooClose = docWidth > 0.85 || docHeight > 0.85;
3565
- if (detectionThresholdMet && documentInBounds && !documentTooClose) {
3566
- var thresholdSet = (_p = thresholds.stability) !== null && _p !== void 0 ? _p : defaultDocumentDetectionThresholds.stability;
3567
- var threshold_1 = thresholdSet[detectedDocumentType];
3568
- var framesNeeded = Math.ceil(average(framesNeededSamples));
3569
- trackBox(bestDocument.box, framesNeeded);
3570
- documentIsStable = lastNBoxes.length >= framesNeeded && !lastNPairs.some(function (pair) {
3571
- return pair.iou < threshold_1;
3572
- });
3573
- }
3574
- }
3575
- return {
3576
- prediction: prediction,
3577
- detectedObjects: detectedObjects,
3578
- detectionScore: detectionScore,
3579
- detectionTime: time,
3580
- detectionThresholdMet: detectionThresholdMet,
3581
- detectedDocumentType: detectedDocumentType,
3582
- idCardFrontDetectionScore: idCardFrontDetectionScore,
3583
- idCardFrontDetectionThresholdMet: idCardFrontDetectionThresholdMet,
3584
- idCardBackDetectionScore: idCardBackDetectionScore,
3585
- idCardBackDetectionThresholdMet: idCardBackDetectionThresholdMet,
3586
- passportDetectionScore: passportDetectionScore,
3587
- passportDetectionThresholdMet: passportDetectionThresholdMet,
3588
- singlePageDetectionScore: singlePageDetectionScore,
3589
- singlePageDetectionThresholdMet: singlePageDetectionThresholdMet,
3590
- bestDocument: bestDocument,
3591
- documentInBounds: documentInBounds,
3592
- documentTooClose: documentTooClose,
3593
- documentIsStable: documentIsStable,
3594
- frameWidth: frameWidth,
3595
- frameHeight: frameHeight,
3596
- allZero: allZero
3597
- };
3598
- }
3599
- function applyNonMaxSuppression(detectedObjects, isGoodBox) {
3600
- var maxes = {};
3601
- detectedObjects.forEach(function (obj, i) {
3602
- if (obj) {
3603
- if (!maxes[obj.label]) maxes[obj.label] = [0, -1];
3604
- if (obj.score > maxes[obj.label][0] && (isGoodBox === null || isGoodBox === void 0 ? void 0 : isGoodBox(obj))) maxes[obj.label] = [obj.score, i];
3605
- }
3606
- });
3607
- return Object.keys(maxes).map(function (label) {
3608
- return detectedObjects[maxes[label][1]];
3609
- }).filter(function (obj) {
3610
- return !!obj;
3611
- });
3612
- }
3613
- function testDocumentDetectionAgainstKnownImage(detector) {
3614
- return new Promise(function (resolve, reject) {
3615
- var img = new Image();
3616
- img.crossOrigin = 'anonymous';
3617
- img.onload = function () {
3618
- var prediction = detector.detectForVideo(img, performance.now());
3619
- if (prediction.detections.length > 0) {
3620
- debug('document detection test result', prediction.detections);
3621
- resolve(void 0);
3622
- } else {
3623
- warn('document detection test failed');
3624
- reject(new Error('testDocumentDetectionAgainstKnownImage failed to predict'));
3625
- }
3626
- };
3627
- img.onerror = function () {
3628
- return reject(new Error('testDocumentDetectionAgainstKnownImage failed to load image'));
3629
- };
3630
- img.src = "".concat(DEFAULT_CDN_URL, "/id-card-test.jpg");
3631
- });
3632
- }
3633
-
3634
- function useFrameLoop(fn, options) {
3635
- if (options === void 0) {
3636
- options = {};
3637
- }
3638
- var _a = useState(false),
3639
- running = _a[0],
3640
- setRunning = _a[1];
3641
- var startedAtRef = useRef(null);
3642
- var loopId = useRef(0);
3643
- var frameId = useRef(0);
3644
- useEffect(function runFrameLoop() {
3645
- if (!running) return;
3646
- var timer;
3647
- var currentLoopId = loopId.current;
3648
- function hotLoop() {
3649
- return __awaiter(this, void 0, void 0, function () {
3650
- var start, timeRunning, took, amountToThrottle;
3651
- var _a, _b, _c;
3652
- return __generator(this, function (_d) {
3653
- switch (_d.label) {
3654
- case 0:
3655
- if (currentLoopId !== loopId.current) return [2 /*return*/];
3656
- start = new Date().getTime();
3657
- timeRunning = start - ((_b = (_a = startedAtRef.current) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0);
3658
- return [4 /*yield*/, fn(frameId.current, timeRunning)];
3659
- case 1:
3660
- _d.sent();
3661
- took = new Date().getTime() - start;
3662
- amountToThrottle = Math.max(((_c = options.throttleMs) !== null && _c !== void 0 ? _c : 0) - took, 0);
3663
- timer = setTimeout(function () {
3664
- frameId.current = requestAnimationFrame(hotLoop);
3665
- }, amountToThrottle);
3666
- return [2 /*return*/];
3667
- }
3668
- });
3669
- });
3670
- }
3671
- void hotLoop();
3672
- return function () {
3673
- loopId.current += 1;
3674
- if (frameId.current) cancelAnimationFrame(frameId.current);
3675
- if (timer) clearTimeout(timer);
3676
- };
3677
- }, [fn, running, options.throttleMs]);
3678
- var start = useCallback(function () {
3679
- startedAtRef.current = new Date();
3680
- setRunning(true);
3681
- }, []);
3682
- var stop = useCallback(function () {
3683
- loopId.current += 1; // force the loop to stop immediately.
3684
- setRunning(false);
3685
- startedAtRef.current = null;
3686
- }, []);
3687
- useEffect(function startAutomatically() {
3688
- if (options.autoStart) start();
3689
- return stop;
3690
- }, [options.autoStart, start, stop]);
3691
- return {
3692
- start: start,
3693
- stop: stop
3694
- };
3695
- }
3696
-
3697
- function listAvailableCameras(facingMode_1) {
3698
- return __awaiter(this, arguments, void 0, function (facingMode, requestMicAccess) {
3699
- var cameraEnumerationStream, allDevices, allowedVideoDevices;
3700
- if (requestMicAccess === void 0) {
3701
- requestMicAccess = false;
3702
- }
3703
- return __generator(this, function (_a) {
3704
- switch (_a.label) {
3705
- case 0:
3706
- return [4 /*yield*/, navigator.mediaDevices.getUserMedia({
3707
- video: {
3708
- facingMode: {
3709
- exact: facingMode
3710
- }
3711
- },
3712
- audio: requestMicAccess
3713
- })
3714
- // This lists all available cameras attached to the user's device.
3715
- ];
3716
- case 1:
3717
- cameraEnumerationStream = _a.sent();
3718
- return [4 /*yield*/, navigator.mediaDevices.enumerateDevices()];
3719
- case 2:
3720
- allDevices = _a.sent();
3721
- allowedVideoDevices = allDevices.filter(function (_a) {
3722
- var kind = _a.kind,
3723
- label = _a.label;
3724
- return kind === 'videoinput' && !label.toLowerCase().includes('virtual');
3725
- });
3726
- // Release the access to the user's camera that we obtained for enumeration purposes.
3727
- cameraEnumerationStream.getVideoTracks().forEach(function (track) {
3728
- track.enabled = false;
3729
- track.stop();
3730
- });
3731
- cameraEnumerationStream = null;
3732
- return [2 /*return*/, allowedVideoDevices];
3733
- }
3734
- });
3735
- });
3736
- }
3737
- var frontCameraLabels = ['front', 'avant', 'anteriore', 'cameraaanvoorzijde', 'kamerapåframsidan', 'forsidekamera', 'kamerapåforsiden', 'aparatprzedni', 'etukamera', 'kameradepan', 'ÖnKamera', 'cameramặttrước', 'camerăfață', 'prednákamera', 'prednjakamera', 'előlapikamera', 'přednífotoaparát', 'μπροστινήκάμερα', 'переднякамера', 'передняякамера', 'преднакамера', 'алдыңғыкамера', 'מצלמה קדמית', 'الكاميرا الأمامية', 'फ़्रंटकैमरा', '前置相机', '前置鏡頭', '前面カメラ', '전면카메라', 'กล้องด้านหน้า'].map(function (s) {
3738
- return s.toLocaleLowerCase().split(' ').join('');
3739
- });
3740
- var rearCameraLabels = ['back', 'rear', 'posterior', 'trasera', 'traseira', 'arrière', 'rückkamera', 'fotocamera(posteriore)', 'cameraaanachterzijde', 'kamerapåbaksidan', 'kamerapåbaksiden', 'bagsidekamera', 'aparattylny', 'takakamera', 'arkakamera', 'kamerabelakang', 'cameramặtsau', 'camerăspate', 'stražnjakamera', 'zadnákamera', 'hátoldalikamera', 'zadnífotoaparát', 'πίσωκάμερα', 'заднякамера', 'Задняякамера', 'заднакамера', 'артқыкамера', 'מצלמה אחורית', 'الكاميرا الخلفية', 'बैककैमरा', '后置相机', '後置鏡頭', '背面カメラ', '후면카메라', 'กล้องด้านหลัง'].map(function (s) {
3741
- return s.toLocaleLowerCase().split(' ').join('');
3742
- });
3743
- var backUltraWideCameraLabels = ['backdualwidecamera', 'backultrawidecamera', 'ultraampliaposterior', 'ultra-angulartraseira', 'ultragrandeangulartraseira', 'ultragrandangle', 'ultragranangular', 'ultra-weitwinkelkamera', 'ultra-grandangolo', 'ultrabredecameraaanachterzijde', 'ultravidvinkelkamerapåbaksidan', 'ultravidvinkelkameraetpåbagsiden', 'ultravidvinkelkamerabak', 'ultragenişkameraarkayüzü', 'ultralaajakulmainentakakamera', 'tylnyaparatultraszerokokątny', 'cameracựcrộngmặtsau', 'camerăcuobiectivultra‑superangularspate', 'ultraszéleslátószögűkamera', 'kameraultralebarbelakang', 'stražnjaultraširokakamera', 'zadníultraširokoúhlýfotoaparát', 'ultraširokouhlá', 'πίσωυπερευρείακάμερα', 'заднянадширококутнакамера', 'Задняясверхширокоугольнаякамера', 'Задна свръх широкоъгълна камера', 'артқыультракеңбұрыштыкамера', 'מצלמה אולטרה רחבה אחורית', 'كاميرا خلفية عريضة جدًا', 'बैकअल्ट्रावाइडकैमरा', '后置超广角相机', '後置超廣角鏡頭相機', '背面超広角カメラ', '후면울트라와이드카메라', 'กล้องด้านหลังอัลตร้าไวด์'].map(function (s) {
3744
- return s.toLocaleLowerCase().split(' ').join('');
3745
- });
3746
- var cameraLabelMatches = function cameraLabelMatches(labelOrDevice, labelSetOrLabel) {
3747
- var label = labelOrDevice instanceof MediaDeviceInfo ? getDeviceLabel(labelOrDevice) : labelOrDevice;
3748
- var labelSet = typeof labelSetOrLabel === 'string' ? [labelSetOrLabel] : labelSetOrLabel;
3749
- return labelSet.some(function (l) {
3750
- return label.includes(l);
3751
- });
3752
- };
3753
- var getDeviceLabel = function getDeviceLabel(deviceInfo) {
3754
- return deviceInfo.label.toLocaleLowerCase().split(' ').join('');
3755
- };
3756
- var currentCamera;
3757
- function obtainCameraAccess(stream, deviceLabel, video) {
3758
- releaseCameraAccess();
3759
- log('obtaining camera access...');
3760
- var _a = stream.getVideoTracks()[0].getSettings(),
3761
- width = _a.width,
3762
- height = _a.height;
3763
- log('camera dimensions', width, height);
3764
- var label = deviceLabel.toLocaleLowerCase().split(' ').join('');
3765
- log('camera label', label);
3766
- var isRearFacing = cameraLabelMatches(label, __spreadArray(__spreadArray(__spreadArray([], rearCameraLabels, true), backUltraWideCameraLabels, true), ['iphone'], false));
3767
- log('is rear facing?', isRearFacing);
3768
- var release = function release() {
3769
- stream.getTracks().forEach(function (track) {
3770
- track.enabled = false;
3771
- track.stop();
3772
- });
3773
- if (video) {
3774
- video.pause();
3775
- video.srcObject = null;
3776
- video.src = '';
3133
+ var currentCamera;
3134
+ function obtainCameraAccess(stream, deviceLabel, video) {
3135
+ releaseCameraAccess();
3136
+ log('obtaining camera access...');
3137
+ var _a = stream.getVideoTracks()[0].getSettings(),
3138
+ width = _a.width,
3139
+ height = _a.height;
3140
+ log('camera dimensions', width, height);
3141
+ var label = deviceLabel.toLocaleLowerCase().split(' ').join('');
3142
+ log('camera label', label);
3143
+ var isRearFacing = cameraLabelMatches(label, __spreadArray(__spreadArray(__spreadArray([], rearCameraLabels, true), backUltraWideCameraLabels, true), ['iphone'], false));
3144
+ log('is rear facing?', isRearFacing);
3145
+ var release = function release() {
3146
+ stream.getTracks().forEach(function (track) {
3147
+ track.enabled = false;
3148
+ track.stop();
3149
+ });
3150
+ if (video) {
3151
+ video.pause();
3152
+ video.srcObject = null;
3153
+ video.src = '';
3777
3154
  }
3778
3155
  };
3779
3156
  width || (width = 0);
@@ -5578,29 +4955,294 @@ function DocumentDetectionModelProvider(_a) {
5578
4955
  }, []);
5579
4956
  var value = useMemo(function () {
5580
4957
  return {
5581
- startDocumentDetection: start,
5582
- stopDocumentDetection: stop,
5583
- loadDocumentDetectionModel: load,
5584
- documentDetectionModelState: modelLoadState,
5585
- documentDetectionModelWarmingStartedAt: modelWarmingStartedAt,
5586
- documentDetectionModelError: modelError,
5587
- documentDetectionModelDownloadProgress: modelDownloadProgress,
5588
- onDocumentDetected: onDocumentDetected,
5589
- detectionTime: lastDetectionTime,
5590
- documentDetectionThresholds: documentDetectionThresholds,
5591
- setDocumentDetectionThresholds: setDocumentDetectionThresholds,
5592
- documentDetectionBoundaries: documentDetectionBoundaries,
5593
- setDocumentDetectionBoundaries: setDocumentDetectionBoundaries,
5594
- documentDetectionLastPredictionCanvas: lastPredictionCanvas,
5595
- clearDocumentDetectionLastPredictionCanvas: clearDocumentDetectionLastPredictionCanvas
4958
+ startDocumentDetection: start,
4959
+ stopDocumentDetection: stop,
4960
+ loadDocumentDetectionModel: load,
4961
+ documentDetectionModelState: modelLoadState,
4962
+ documentDetectionModelWarmingStartedAt: modelWarmingStartedAt,
4963
+ documentDetectionModelError: modelError,
4964
+ documentDetectionModelDownloadProgress: modelDownloadProgress,
4965
+ onDocumentDetected: onDocumentDetected,
4966
+ detectionTime: lastDetectionTime,
4967
+ documentDetectionThresholds: documentDetectionThresholds,
4968
+ setDocumentDetectionThresholds: setDocumentDetectionThresholds,
4969
+ documentDetectionBoundaries: documentDetectionBoundaries,
4970
+ setDocumentDetectionBoundaries: setDocumentDetectionBoundaries,
4971
+ documentDetectionLastPredictionCanvas: lastPredictionCanvas,
4972
+ clearDocumentDetectionLastPredictionCanvas: clearDocumentDetectionLastPredictionCanvas
4973
+ };
4974
+ }, [start, stop, load, modelLoadState, modelWarmingStartedAt, modelError, modelDownloadProgress, onDocumentDetected, documentDetectionThresholds, documentDetectionBoundaries, clearDocumentDetectionLastPredictionCanvas]);
4975
+ return /*#__PURE__*/React.createElement(DocumentDetectionModelContext.Provider, {
4976
+ value: value
4977
+ }, /*#__PURE__*/React.createElement(InvisibleCanvas, {
4978
+ key: canvasKey,
4979
+ ref: lastPredictionCanvas
4980
+ }), children);
4981
+ }
4982
+
4983
+ function cropToShoulders(rawCanvas, cropCanvas, resizeCanvas, frame, face, quality, maxHeight) {
4984
+ var _a;
4985
+ if (quality === void 0) {
4986
+ quality = 0.92;
4987
+ }
4988
+ if (!rawCanvas || !cropCanvas || !resizeCanvas) return '';
4989
+ var rawCtx = rawCanvas.getContext('2d');
4990
+ var cropCtx = cropCanvas.getContext('2d');
4991
+ var resizeCtx = resizeCanvas.getContext('2d');
4992
+ if (!rawCtx || !cropCtx || !resizeCtx) throw new Error('could not get 2d context');
4993
+ rawCanvas.width = frame.width;
4994
+ rawCanvas.height = frame.height;
4995
+ rawCtx.putImageData(frame, 0, 0);
4996
+ if (frame.height > frame.width) {
4997
+ cropCanvas.width = frame.width;
4998
+ cropCanvas.height = frame.height;
4999
+ cropCtx.drawImage(rawCanvas, 0, 0, cropCanvas.width, cropCanvas.height);
5000
+ } else {
5001
+ var _b = (_a = face === null || face === void 0 ? void 0 : face.box) !== null && _a !== void 0 ? _a : {
5002
+ xMin: 0,
5003
+ width: frame.width
5004
+ },
5005
+ xMin = _b.xMin,
5006
+ width = _b.width;
5007
+ var desiredWidth = frame.height * 0.6;
5008
+ var faceCenterX = xMin + width / 2;
5009
+ var xPos = Math.max(0, faceCenterX - desiredWidth / 2);
5010
+ cropCanvas.width = desiredWidth;
5011
+ cropCanvas.height = frame.height;
5012
+ cropCtx.drawImage(rawCanvas, xPos, 0, cropCanvas.width, cropCanvas.height, 0, 0, cropCanvas.width, cropCanvas.height);
5013
+ }
5014
+ resizeCanvas.height = maxHeight !== null && maxHeight !== void 0 ? maxHeight : cropCanvas.height;
5015
+ resizeCanvas.width = cropCanvas.width * (resizeCanvas.height / cropCanvas.height);
5016
+ resizeCtx === null || resizeCtx === void 0 ? void 0 : resizeCtx.drawImage(cropCanvas, 0, 0, resizeCanvas.width, resizeCanvas.height);
5017
+ var dataURL = resizeCanvas.toDataURL('image/jpeg', quality);
5018
+ log('cropToShoulders size', new TextEncoder().encode(dataURL).length);
5019
+ clearCanvas(rawCanvas);
5020
+ clearCanvas(cropCanvas);
5021
+ clearCanvas(resizeCanvas);
5022
+ return dataURL;
5023
+ }
5024
+ function cropToDetectedObjectBox(frame, box, canvas, padding) {
5025
+ if (padding === void 0) {
5026
+ padding = 0;
5027
+ }
5028
+ canvas || (canvas = document.createElement('canvas'));
5029
+ var ctx = canvas.getContext('2d');
5030
+ if (!ctx) throw new Error('could not get 2d context');
5031
+ var xMin = box.xMin,
5032
+ yMin = box.yMin,
5033
+ width = box.width,
5034
+ height = box.height;
5035
+ canvas.width = width + padding * 2;
5036
+ canvas.height = height + padding * 2;
5037
+ ctx.drawImage(frame, xMin - padding, yMin - padding, width + padding * 2, height + padding * 2, 0, 0, canvas.width, canvas.height);
5038
+ return canvas;
5039
+ }
5040
+ function cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box, padding) {
5041
+ if (padding === void 0) {
5042
+ padding = 0;
5043
+ }
5044
+ if (!box) return imageData;
5045
+ var cropped = cropToDetectedObjectBox(imageData, box, cropCanvas, padding);
5046
+ var _a = [box.width, box.height],
5047
+ bw = _a[0],
5048
+ bh = _a[1];
5049
+ if (bh <= bw) return cropped;
5050
+ var ctx = rotateCanvas.getContext('2d');
5051
+ if (!ctx) return cropped;
5052
+ rotateCanvas.width = bh;
5053
+ rotateCanvas.height = bw;
5054
+ ctx.clearRect(0, 0, rotateCanvas.width, rotateCanvas.height);
5055
+ ctx.translate(rotateCanvas.width / 2, rotateCanvas.height / 2);
5056
+ ctx.rotate(1.5708); // 90 deg in radians
5057
+ ctx.drawImage(cropped, -bw / 2, -bh / 2);
5058
+ return rotateCanvas;
5059
+ }
5060
+ function resizeIfNecessary(imageData, resizeCanvas, maxWidth) {
5061
+ var width = imageData.width,
5062
+ height = imageData.height;
5063
+ if (width <= maxWidth) return imageData;
5064
+ var resizeCtx = resizeCanvas.getContext('2d');
5065
+ if (!resizeCtx) return imageData;
5066
+ var scale = maxWidth / width;
5067
+ resizeCanvas.width = maxWidth;
5068
+ resizeCanvas.height = height * scale;
5069
+ resizeCtx.drawImage(imageData, 0, 0, resizeCanvas.width, resizeCanvas.height);
5070
+ return resizeCanvas;
5071
+ }
5072
+
5073
+ var defaultFocusModelLoadTimeoutMs = 45000;
5074
+ var defaultFocusThresholds = {
5075
+ idCardFront: {
5076
+ desktop: 0,
5077
+ mobile: 0.3
5078
+ },
5079
+ idCardBack: {
5080
+ desktop: 0,
5081
+ mobile: 0.3
5082
+ },
5083
+ passport: {
5084
+ desktop: 0,
5085
+ mobile: 0.3
5086
+ },
5087
+ singlePage: {
5088
+ desktop: 0,
5089
+ mobile: 0.3
5090
+ }
5091
+ };
5092
+ var classifier$1 = null;
5093
+ var classifierSettings$1 = null;
5094
+ function loadFocusModel() {
5095
+ return __awaiter(this, arguments, void 0, function (modelAssetPath) {
5096
+ var _a, _b;
5097
+ if (modelAssetPath === void 0) {
5098
+ modelAssetPath = defaultFocusModelPath;
5099
+ }
5100
+ return __generator(this, function (_c) {
5101
+ switch (_c.label) {
5102
+ case 0:
5103
+ if (classifier$1 && (classifierSettings$1 === null || classifierSettings$1 === void 0 ? void 0 : classifierSettings$1.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier$1];
5104
+ closeFocusModel();
5105
+ return [4 /*yield*/, preloadFocusModelDependencies()];
5106
+ case 1:
5107
+ _c.sent();
5108
+ if (modelCapabilities.delegate === 'NONE') {
5109
+ throw new Error('No available delegate for focus detector.');
5110
+ }
5111
+ _b = (_a = ImageClassifier).createFromOptions;
5112
+ return [4 /*yield*/, FilesetResolver.forVisionTasks(visionTasksBasePath)];
5113
+ case 2:
5114
+ return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
5115
+ baseOptions: {
5116
+ modelAssetPath: modelAssetPath,
5117
+ delegate: modelCapabilities.delegate
5118
+ },
5119
+ // canvas: document.createElement('canvas'),
5120
+ runningMode: 'VIDEO'
5121
+ }])];
5122
+ case 3:
5123
+ classifier$1 = _c.sent();
5124
+ classifierSettings$1 = {
5125
+ modelAssetPath: modelAssetPath
5126
+ };
5127
+ return [2 /*return*/, classifier$1];
5128
+ }
5129
+ });
5130
+ });
5131
+ }
5132
+ function closeFocusModel() {
5133
+ classifier$1 === null || classifier$1 === void 0 ? void 0 : classifier$1.close();
5134
+ classifier$1 = null;
5135
+ classifierSettings$1 = null;
5136
+ }
5137
+ function useLoadFocusModel(_a) {
5138
+ var _b = _a.modelPath,
5139
+ modelPath = _b === void 0 ? defaultFocusModelPath : _b,
5140
+ _c = _a.modelLoadTimeoutMs,
5141
+ modelLoadTimeoutMs = _c === void 0 ? defaultFocusModelLoadTimeoutMs : _c,
5142
+ onModelError = _a.onModelError,
5143
+ videoRef = _a.videoRef,
5144
+ _d = _a.shouldLoadModels,
5145
+ shouldLoadModels = _d === void 0 ? true : _d;
5146
+ var _e = useState('not-started'),
5147
+ modelLoadState = _e[0],
5148
+ setModelLoadState = _e[1];
5149
+ var _f = useState(0),
5150
+ modelDownloadProgress = _f[0],
5151
+ setModelDownloadProgress = _f[1];
5152
+ var _g = useState(null),
5153
+ modelWarmingStartedAt = _g[0],
5154
+ setModelWarmingStartedAt = _g[1];
5155
+ var _h = useState(null),
5156
+ modelError = _h[0],
5157
+ setModelError = _h[1];
5158
+ useEffect(function loadModel() {
5159
+ var _this = this;
5160
+ if (!shouldLoadModels) return;
5161
+ setModelLoadState('downloading');
5162
+ setModelWarmingStartedAt(null);
5163
+ function handleDownloadProgress(event) {
5164
+ setModelDownloadProgress(progressToPercentage(event.detail));
5165
+ }
5166
+ document.addEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
5167
+ var modelLoadTimeout = setTimeout(function () {
5168
+ setModelError(new Error('Model loading time limit exceeded.'));
5169
+ }, modelLoadTimeoutMs);
5170
+ var cancelVideoReady = function cancelVideoReady() {};
5171
+ loadFocusModel(modelPath).then(function (loadedModel) {
5172
+ return __awaiter(_this, void 0, void 0, function () {
5173
+ var _a, videoReady, cancel, cancelled;
5174
+ return __generator(this, function (_b) {
5175
+ switch (_b.label) {
5176
+ case 0:
5177
+ setModelDownloadProgress(100);
5178
+ clearTimeout(modelLoadTimeout);
5179
+ setModelLoadState('warming');
5180
+ setModelWarmingStartedAt(performance.now());
5181
+ _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
5182
+ cancelled = false;
5183
+ cancelVideoReady = function cancelVideoReady() {
5184
+ cancelled = true;
5185
+ cancel();
5186
+ };
5187
+ return [4 /*yield*/, videoReady];
5188
+ case 1:
5189
+ _b.sent();
5190
+ setTimeout(function () {
5191
+ if (cancelled) return;
5192
+ loadedModel.classifyForVideo(videoRef.current, performance.now());
5193
+ setModelLoadState('ready');
5194
+ }, 500);
5195
+ return [2 /*return*/];
5196
+ }
5197
+ });
5198
+ });
5199
+ })["catch"](function (e) {
5200
+ setModelError(e);
5201
+ setModelLoadState('error');
5202
+ })["finally"](function () {
5203
+ clearTimeout(modelLoadTimeout);
5204
+ });
5205
+ return function () {
5206
+ log('unloading focus model');
5207
+ cancelVideoReady();
5208
+ closeFocusModel();
5209
+ clearTimeout(modelLoadTimeout);
5210
+ document.removeEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
5211
+ };
5212
+ }, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
5213
+ useEffect(function handleModelError() {
5214
+ if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
5215
+ }, [modelError, onModelError]);
5216
+ return useMemo(function () {
5217
+ return {
5218
+ ready: modelLoadState === 'ready',
5219
+ modelLoadState: modelLoadState,
5220
+ modelDownloadProgress: modelDownloadProgress,
5221
+ modelWarmingStartedAt: modelWarmingStartedAt,
5222
+ modelError: modelError
5596
5223
  };
5597
- }, [start, stop, load, modelLoadState, modelWarmingStartedAt, modelError, modelDownloadProgress, onDocumentDetected, documentDetectionThresholds, documentDetectionBoundaries, clearDocumentDetectionLastPredictionCanvas]);
5598
- return /*#__PURE__*/React.createElement(DocumentDetectionModelContext.Provider, {
5599
- value: value
5600
- }, /*#__PURE__*/React.createElement(InvisibleCanvas, {
5601
- key: canvasKey,
5602
- ref: lastPredictionCanvas
5603
- }), children);
5224
+ }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
5225
+ }
5226
+ var lastFocusPredictionAt = 0;
5227
+ var lastFocusPredictionTime = 0;
5228
+ function setLastFocusPredictionAt(time) {
5229
+ lastFocusPredictionTime = time - lastFocusPredictionAt;
5230
+ lastFocusPredictionAt = time;
5231
+ }
5232
+ function makeFocusModelPrediction(imageData, cropCanvas, rotateCanvas, box) {
5233
+ var _a, _b, _c, _d, _e;
5234
+ if (!classifier$1) return null;
5235
+ var startedAt = performance.now();
5236
+ var image = cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box);
5237
+ var result = classifier$1.classifyForVideo(image, performance.now());
5238
+ 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) {
5239
+ return c.categoryName === 'focused';
5240
+ })) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
5241
+ var predictionTime = performance.now() - startedAt;
5242
+ return {
5243
+ score: score,
5244
+ predictionTime: predictionTime
5245
+ };
5604
5246
  }
5605
5247
 
5606
5248
  var FocusModelContext = /*#__PURE__*/createContext({
@@ -5677,52 +5319,424 @@ function FocusModelProvider(_a) {
5677
5319
  }, [focusThresholds, load, makeFocusPrediction, modelDownloadProgress, modelError, modelLoadState, modelWarmingStartedAt]);
5678
5320
  return /*#__PURE__*/React__default.createElement(FocusModelContext.Provider, {
5679
5321
  value: value
5680
- }, /*#__PURE__*/React__default.createElement(InvisibleCanvas, {
5322
+ }, /*#__PURE__*/React__default.createElement(InvisibleCanvasContainer, null, /*#__PURE__*/React__default.createElement(InvisibleCanvas, {
5681
5323
  ref: rotateCanvas,
5682
5324
  style: showCanvases ? {
5683
5325
  display: 'block'
5684
5326
  } : undefined
5685
5327
  }), /*#__PURE__*/React__default.createElement(InvisibleCanvas, {
5686
- ref: cropCanvas,
5328
+ ref: cropCanvas,
5329
+ style: showCanvases ? {
5330
+ display: 'block'
5331
+ } : undefined
5332
+ })), children);
5333
+ }
5334
+
5335
+ function _isNavigatorDefined() {
5336
+ return typeof navigator !== 'undefined' && navigator != null;
5337
+ }
5338
+ var isMobileCache;
5339
+ function isMobile() {
5340
+ if (isMobileCache !== undefined) return isMobileCache;
5341
+ isMobileCache = evaluateIsMobile();
5342
+ return isMobileCache;
5343
+ }
5344
+ function evaluateIsMobile(nav) {
5345
+ if (nav || _isNavigatorDefined()) {
5346
+ if (!nav) {
5347
+ nav = navigator;
5348
+ }
5349
+ if (nav.product === 'ReactNative') {
5350
+ return true;
5351
+ }
5352
+ var a = nav.userAgent || nav.vendor || (
5353
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5354
+ // @ts-ignore
5355
+ typeof window !== 'undefined' ? window.opera : '');
5356
+ if (!a) {
5357
+ var navAny = nav;
5358
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5359
+ // @ts-ignore
5360
+ return navAny.userAgentData && navAny.userAgentData.mobile;
5361
+ }
5362
+ return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4));
5363
+ }
5364
+ return false;
5365
+ }
5366
+
5367
+ var defaultBarcodeReadabilityModelLoadTimeoutMs = 45000;
5368
+ var classifier = null;
5369
+ var classifierSettings = null;
5370
+ function loadBarcodeReadabilityModel() {
5371
+ return __awaiter(this, arguments, void 0, function (modelAssetPath) {
5372
+ var _a, _b;
5373
+ if (modelAssetPath === void 0) {
5374
+ modelAssetPath = defaultBarcodeReadabilityModelPath;
5375
+ }
5376
+ return __generator(this, function (_c) {
5377
+ switch (_c.label) {
5378
+ case 0:
5379
+ if (classifier && (classifierSettings === null || classifierSettings === void 0 ? void 0 : classifierSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier];
5380
+ closeBarcodeReadabilityModel();
5381
+ return [4 /*yield*/, preloadBarcodeReadabilityModelDependencies()];
5382
+ case 1:
5383
+ _c.sent();
5384
+ if (modelCapabilities.delegate === 'NONE') {
5385
+ throw new Error('No available delegate for barcode readability model.');
5386
+ }
5387
+ _b = (_a = ImageClassifier).createFromOptions;
5388
+ return [4 /*yield*/, FilesetResolver.forVisionTasks(visionTasksBasePath)];
5389
+ case 2:
5390
+ return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
5391
+ baseOptions: {
5392
+ modelAssetPath: modelAssetPath,
5393
+ delegate: 'CPU'
5394
+ },
5395
+ runningMode: 'VIDEO',
5396
+ maxResults: 1
5397
+ }])];
5398
+ case 3:
5399
+ classifier = _c.sent();
5400
+ classifierSettings = {
5401
+ modelAssetPath: modelAssetPath
5402
+ };
5403
+ return [2 /*return*/, classifier];
5404
+ }
5405
+ });
5406
+ });
5407
+ }
5408
+ function closeBarcodeReadabilityModel() {
5409
+ classifier === null || classifier === void 0 ? void 0 : classifier.close();
5410
+ classifier = null;
5411
+ classifierSettings = null;
5412
+ }
5413
+ function useLoadBarcodeReadabilityModel(_a) {
5414
+ var _b = _a.modelPath,
5415
+ modelPath = _b === void 0 ? defaultBarcodeReadabilityModelPath : _b,
5416
+ _c = _a.modelLoadTimeoutMs,
5417
+ modelLoadTimeoutMs = _c === void 0 ? defaultBarcodeReadabilityModelLoadTimeoutMs : _c,
5418
+ onModelError = _a.onModelError,
5419
+ videoRef = _a.videoRef,
5420
+ _d = _a.shouldLoadModels,
5421
+ shouldLoadModels = _d === void 0 ? true : _d;
5422
+ var _e = useState('not-started'),
5423
+ modelLoadState = _e[0],
5424
+ setModelLoadState = _e[1];
5425
+ var _f = useState(0),
5426
+ modelDownloadProgress = _f[0],
5427
+ setModelDownloadProgress = _f[1];
5428
+ var _g = useState(null),
5429
+ modelWarmingStartedAt = _g[0],
5430
+ setModelWarmingStartedAt = _g[1];
5431
+ var _h = useState(null),
5432
+ modelError = _h[0],
5433
+ setModelError = _h[1];
5434
+ useEffect(function loadModel() {
5435
+ var _this = this;
5436
+ if (!shouldLoadModels) return;
5437
+ setModelLoadState('downloading');
5438
+ setModelWarmingStartedAt(null);
5439
+ function handleDownloadProgress(event) {
5440
+ setModelDownloadProgress(progressToPercentage(event.detail));
5441
+ }
5442
+ document.addEventListener('idmission.preloadProgress.barcodeReadability', handleDownloadProgress);
5443
+ var modelLoadTimeout = setTimeout(function () {
5444
+ setModelError(new Error('Model loading time limit exceeded.'));
5445
+ }, modelLoadTimeoutMs);
5446
+ var cancelVideoReady = function cancelVideoReady() {};
5447
+ loadBarcodeReadabilityModel(modelPath).then(function (loadedModel) {
5448
+ return __awaiter(_this, void 0, void 0, function () {
5449
+ var _a, videoReady, cancel, cancelled;
5450
+ return __generator(this, function (_b) {
5451
+ switch (_b.label) {
5452
+ case 0:
5453
+ setModelDownloadProgress(100);
5454
+ clearTimeout(modelLoadTimeout);
5455
+ setModelLoadState('warming');
5456
+ setModelWarmingStartedAt(new Date().getTime());
5457
+ _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
5458
+ cancelled = false;
5459
+ cancelVideoReady = function cancelVideoReady() {
5460
+ cancelled = true;
5461
+ cancel();
5462
+ };
5463
+ return [4 /*yield*/, videoReady];
5464
+ case 1:
5465
+ _b.sent();
5466
+ setTimeout(function () {
5467
+ if (cancelled) return;
5468
+ loadedModel.classifyForVideo(videoRef.current, performance.now());
5469
+ setModelLoadState('ready');
5470
+ }, 500);
5471
+ return [2 /*return*/];
5472
+ }
5473
+ });
5474
+ });
5475
+ })["catch"](function (e) {
5476
+ setModelError(e);
5477
+ setModelLoadState('error');
5478
+ })["finally"](function () {
5479
+ clearTimeout(modelLoadTimeout);
5480
+ });
5481
+ return function () {
5482
+ log('unloading barcode readability model');
5483
+ cancelVideoReady();
5484
+ closeBarcodeReadabilityModel();
5485
+ clearTimeout(modelLoadTimeout);
5486
+ document.removeEventListener('idmission.preloadProgress.barcodeReadability', handleDownloadProgress);
5487
+ };
5488
+ }, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
5489
+ useEffect(function handleModelError() {
5490
+ if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
5491
+ }, [modelError, onModelError]);
5492
+ return useMemo(function () {
5493
+ return {
5494
+ ready: modelLoadState === 'ready',
5495
+ modelLoadState: modelLoadState,
5496
+ modelDownloadProgress: modelDownloadProgress,
5497
+ modelWarmingStartedAt: modelWarmingStartedAt,
5498
+ modelError: modelError
5499
+ };
5500
+ }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
5501
+ }
5502
+ var lastBarcodeReadabilityPredictionAt = 0;
5503
+ var lastBarcodeReadabilityPredictionTime = 0;
5504
+ function setLastBarcodeReadabilityPredictionAt(time) {
5505
+ lastBarcodeReadabilityPredictionTime = time - lastBarcodeReadabilityPredictionAt;
5506
+ lastBarcodeReadabilityPredictionAt = time;
5507
+ }
5508
+ function makeBarcodeReadabilityModelPrediction(imageData, cropCanvas, rotateCanvas, resizeCanvas, box) {
5509
+ var _a, _b, _c, _d, _e;
5510
+ if (!classifier) return null;
5511
+ var startedAt = performance.now();
5512
+ var image = cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box);
5513
+ var resized = resizeIfNecessary(image, resizeCanvas, 500);
5514
+ var result = classifier.classifyForVideo(resized, performance.now());
5515
+ 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) {
5516
+ return c.categoryName === 'blurry';
5517
+ })) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
5518
+ debug('barcode prediction', "".concat(performance.now() - startedAt, "ms"), score);
5519
+ var predictionTime = performance.now() - startedAt;
5520
+ return {
5521
+ score: score,
5522
+ predictionTime: predictionTime
5523
+ };
5524
+ }
5525
+
5526
+ var BarcodeReadabilityModelContext = /*#__PURE__*/createContext({
5527
+ loadBarcodeReadabilityModel: function loadBarcodeReadabilityModel() {
5528
+ return null;
5529
+ },
5530
+ barcodeReadabilityModelState: 'not-started',
5531
+ barcodeReadabilityModelDownloadProgress: 0,
5532
+ barcodeReadabilityModelWarmingStartedAt: null,
5533
+ barcodeReadabilityModelError: null,
5534
+ barcodeReadabilityThresholds: {},
5535
+ setBarcodeReadabilityThresholds: function setBarcodeReadabilityThresholds() {
5536
+ return null;
5537
+ },
5538
+ makeBarcodeReadabilityPrediction: function makeBarcodeReadabilityPrediction() {
5539
+ return null;
5540
+ },
5541
+ barcodeReadabilityPredictionTime: 0
5542
+ });
5543
+ function BarcodeReadabilityModelProvider(_a) {
5544
+ var children = _a.children,
5545
+ _b = _a.barcodeReadabilityModelPath,
5546
+ barcodeReadabilityModelPath = _b === void 0 ? defaultBarcodeReadabilityModelPath : _b,
5547
+ _c = _a.barcodeReadabilityModelLoadTimeoutMs,
5548
+ barcodeReadabilityModelLoadTimeoutMs = _c === void 0 ? defaultBarcodeReadabilityModelLoadTimeoutMs : _c,
5549
+ onBarcodeReadabilityModelError = _a.onBarcodeReadabilityModelError,
5550
+ _d = _a.showCanvases,
5551
+ showCanvases = _d === void 0 ? false : _d,
5552
+ _e = _a.shouldLoadModels,
5553
+ shouldLoadModelsProp = _e === void 0 ? true : _e;
5554
+ var cropCanvas = useRef(null);
5555
+ var rotateCanvas = useRef(null);
5556
+ var resizeCanvas = useRef(null);
5557
+ var _f = useState({}),
5558
+ barcodeReadabilityThresholds = _f[0],
5559
+ setBarcodeReadabilityThresholds = _f[1];
5560
+ var videoRef = useCameraStore().videoRef;
5561
+ var _g = useState(shouldLoadModelsProp),
5562
+ shouldLoadModels = _g[0],
5563
+ setShouldLoadModels = _g[1];
5564
+ var load = useCallback(function () {
5565
+ return setShouldLoadModels(true);
5566
+ }, []);
5567
+ var _h = useLoadBarcodeReadabilityModel({
5568
+ modelPath: barcodeReadabilityModelPath,
5569
+ modelLoadTimeoutMs: barcodeReadabilityModelLoadTimeoutMs,
5570
+ onModelError: onBarcodeReadabilityModelError,
5571
+ videoRef: videoRef,
5572
+ shouldLoadModels: shouldLoadModels
5573
+ }),
5574
+ ready = _h.ready,
5575
+ modelLoadState = _h.modelLoadState,
5576
+ modelDownloadProgress = _h.modelDownloadProgress,
5577
+ modelWarmingStartedAt = _h.modelWarmingStartedAt,
5578
+ modelError = _h.modelError;
5579
+ var makeBarcodeReadabilityPrediction = useCallback(function (imageData, box) {
5580
+ if (!ready) return null;
5581
+ var prediction = makeBarcodeReadabilityModelPrediction(imageData, cropCanvas.current, rotateCanvas.current, resizeCanvas.current, box);
5582
+ if (!prediction) return null;
5583
+ setLastBarcodeReadabilityPredictionAt(prediction.predictionTime);
5584
+ return prediction;
5585
+ }, [ready]);
5586
+ var value = useMemo(function () {
5587
+ return {
5588
+ loadBarcodeReadabilityModel: load,
5589
+ barcodeReadabilityModelState: modelLoadState,
5590
+ barcodeReadabilityModelDownloadProgress: modelDownloadProgress,
5591
+ barcodeReadabilityModelWarmingStartedAt: modelWarmingStartedAt,
5592
+ barcodeReadabilityModelError: modelError,
5593
+ makeBarcodeReadabilityPrediction: makeBarcodeReadabilityPrediction,
5594
+ barcodeReadabilityPredictionTime: lastBarcodeReadabilityPredictionTime,
5595
+ barcodeReadabilityThresholds: barcodeReadabilityThresholds,
5596
+ setBarcodeReadabilityThresholds: setBarcodeReadabilityThresholds
5597
+ };
5598
+ }, [barcodeReadabilityThresholds, load, makeBarcodeReadabilityPrediction, modelDownloadProgress, modelError, modelLoadState, modelWarmingStartedAt]);
5599
+ return /*#__PURE__*/React__default.createElement(BarcodeReadabilityModelContext.Provider, {
5600
+ value: value
5601
+ }, /*#__PURE__*/React__default.createElement(InvisibleCanvasContainer, null, /*#__PURE__*/React__default.createElement(InvisibleCanvas, {
5602
+ ref: rotateCanvas
5603
+ }), /*#__PURE__*/React__default.createElement(InvisibleCanvas, {
5604
+ ref: cropCanvas
5605
+ }), /*#__PURE__*/React__default.createElement(InvisibleCanvas, {
5606
+ ref: resizeCanvas,
5687
5607
  style: showCanvases ? {
5688
5608
  display: 'block'
5689
5609
  } : undefined
5690
- }), children);
5691
- }
5692
-
5693
- function _isNavigatorDefined() {
5694
- return typeof navigator !== 'undefined' && navigator != null;
5610
+ })), children);
5695
5611
  }
5696
- var isMobileCache;
5697
- function isMobile() {
5698
- if (isMobileCache !== undefined) return isMobileCache;
5699
- isMobileCache = evaluateIsMobile();
5700
- return isMobileCache;
5701
- }
5702
- function evaluateIsMobile(nav) {
5703
- if (nav || _isNavigatorDefined()) {
5704
- if (!nav) {
5705
- nav = navigator;
5706
- }
5707
- if (nav.product === 'ReactNative') {
5708
- return true;
5709
- }
5710
- var a = nav.userAgent || nav.vendor || (
5711
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5712
- // @ts-ignore
5713
- typeof window !== 'undefined' ? window.opera : '');
5714
- if (!a) {
5715
- var navAny = nav;
5716
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5717
- // @ts-ignore
5718
- return navAny.userAgentData && navAny.userAgentData.mobile;
5719
- }
5720
- return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4));
5612
+ function useBarcodeReadabilityModelContext() {
5613
+ var context = useContext(BarcodeReadabilityModelContext);
5614
+ if (!context) {
5615
+ throw new Error('useBarcodeReadabilityModelContext must be used within a BarcodeReadabilityModelProvider');
5721
5616
  }
5722
- return false;
5617
+ return context;
5723
5618
  }
5724
5619
 
5725
5620
  var onMobile = isMobile();
5621
+ /**
5622
+ * Analyzes barcode readability for a detected document
5623
+ * @param prediction The document detection prediction
5624
+ * @param lastPredictionCanvas The canvas containing the original frame
5625
+ * @param croppedDocumentCanvas Canvas for storing cropped document
5626
+ * @param bestBarcodeCanvas Canvas for storing best barcode crop
5627
+ * @param currentBestBarcodeScore Current best barcode score
5628
+ * @param documentDetectionThresholds Thresholds for document detection
5629
+ * @param makeBarcodeReadabilityPrediction Function to make barcode readability predictions
5630
+ * @param barcodeReadabilityThresholds Thresholds for barcode readability
5631
+ * @returns Object containing barcode analysis results
5632
+ */
5633
+ function analyzeBarcodeReadability(prediction, lastPredictionCanvas, croppedDocumentCanvas, bestBarcodeCanvas, currentBestBarcodeScore, documentDetectionThresholds, makeBarcodeReadabilityPrediction, barcodeReadabilityThreshold) {
5634
+ return __awaiter(this, void 0, void 0, function () {
5635
+ var pdf417PredictionTime, pdf417PredictionScore, pdf417PredictionThresholdMet, newBestBarcodeScore, newBestBarcodeDetails, documentCroppedPrediction, processedCroppedPrediction, pdf417Prediction;
5636
+ var _a;
5637
+ return __generator(this, function (_b) {
5638
+ switch (_b.label) {
5639
+ case 0:
5640
+ pdf417PredictionTime = 0;
5641
+ pdf417PredictionScore = 0;
5642
+ pdf417PredictionThresholdMet = false;
5643
+ if (!prediction.bestDocument || !((_a = prediction.bestPDF417) === null || _a === void 0 ? void 0 : _a.box) || !bestBarcodeCanvas) {
5644
+ return [2 /*return*/, {
5645
+ pdf417PredictionTime: pdf417PredictionTime,
5646
+ pdf417PredictionScore: pdf417PredictionScore,
5647
+ pdf417PredictionThresholdMet: pdf417PredictionThresholdMet,
5648
+ newBestBarcodeScore: newBestBarcodeScore,
5649
+ newBestBarcodeDetails: newBestBarcodeDetails
5650
+ }];
5651
+ }
5652
+ /**
5653
+ * Step 1: Crop the full frame to just the document area
5654
+ * This removes background noise and focuses analysis on the document
5655
+ */
5656
+ cropToDetectedObjectBox(lastPredictionCanvas, prediction.bestDocument.box, croppedDocumentCanvas);
5657
+ return [4 /*yield*/, makeDocumentDetectorPrediction(croppedDocumentCanvas)];
5658
+ case 1:
5659
+ documentCroppedPrediction = _b.sent();
5660
+ if (!documentCroppedPrediction) {
5661
+ // error occurred during prediction (error logged by callee)
5662
+ return [2 /*return*/, {
5663
+ pdf417PredictionTime: pdf417PredictionTime,
5664
+ pdf417PredictionScore: pdf417PredictionScore,
5665
+ pdf417PredictionThresholdMet: pdf417PredictionThresholdMet,
5666
+ newBestBarcodeScore: newBestBarcodeScore,
5667
+ newBestBarcodeDetails: newBestBarcodeDetails
5668
+ }];
5669
+ }
5670
+ processedCroppedPrediction = processDocumentDetectorPrediction(documentCroppedPrediction, documentDetectionThresholds);
5671
+ if (processedCroppedPrediction.bestPDF417) {
5672
+ pdf417Prediction = makeBarcodeReadabilityPrediction(croppedDocumentCanvas, processedCroppedPrediction.bestPDF417.box);
5673
+ if (pdf417Prediction) {
5674
+ pdf417PredictionTime = pdf417Prediction.predictionTime;
5675
+ pdf417PredictionScore = pdf417Prediction.score;
5676
+ if (pdf417Prediction.score > currentBestBarcodeScore) {
5677
+ /**
5678
+ * Step 5: Update best barcode
5679
+ */
5680
+ newBestBarcodeScore = pdf417Prediction.score;
5681
+ newBestBarcodeDetails = {
5682
+ boundingBox: prediction.bestPDF417.box,
5683
+ score: pdf417Prediction.score
5684
+ };
5685
+ if (pdf417PredictionScore >= barcodeReadabilityThreshold) {
5686
+ pdf417PredictionThresholdMet = true;
5687
+ }
5688
+ cropToDetectedObjectBox(croppedDocumentCanvas, processedCroppedPrediction.bestPDF417.box, bestBarcodeCanvas, 16);
5689
+ }
5690
+ }
5691
+ }
5692
+ return [2 /*return*/, {
5693
+ pdf417PredictionTime: pdf417PredictionTime,
5694
+ pdf417PredictionScore: pdf417PredictionScore,
5695
+ pdf417PredictionThresholdMet: pdf417PredictionThresholdMet,
5696
+ newBestBarcodeScore: newBestBarcodeScore,
5697
+ newBestBarcodeDetails: newBestBarcodeDetails
5698
+ }];
5699
+ }
5700
+ });
5701
+ });
5702
+ }
5703
+ /**
5704
+ * Calculates the barcode readability threshold for a given document type
5705
+ * @param detectedDocumentType The type of document detected
5706
+ * @param barcodeReadabilityThresholds The threshold configuration object
5707
+ * @returns The appropriate threshold value for the current platform (mobile/desktop)
5708
+ */
5709
+ function calculateBarcodeReadabilityThreshold(detectedDocumentType, barcodeReadabilityThresholds) {
5710
+ var barcodeReadabilityThresholdSet = detectedDocumentType in barcodeReadabilityThresholds ? barcodeReadabilityThresholds[detectedDocumentType] : undefined;
5711
+ if (barcodeReadabilityThresholdSet) {
5712
+ return onMobile ? barcodeReadabilityThresholdSet.mobile || 0 : barcodeReadabilityThresholdSet.desktop || 0;
5713
+ }
5714
+ return 0;
5715
+ }
5716
+ /**
5717
+ * Hook that calculates the barcode readability threshold for a given document type
5718
+ */
5719
+ function useBarcodeReadabilityThreshold() {
5720
+ var barcodeReadabilityThresholds = useBarcodeReadabilityModelContext().barcodeReadabilityThresholds;
5721
+ return useCallback(function (detectedDocumentType) {
5722
+ return calculateBarcodeReadabilityThreshold(detectedDocumentType, barcodeReadabilityThresholds);
5723
+ }, [barcodeReadabilityThresholds]);
5724
+ }
5725
+ function useBarcodeReadabilityAnalysis() {
5726
+ var _this = this;
5727
+ var documentDetectionThresholds = useContext(DocumentDetectionModelContext).documentDetectionThresholds;
5728
+ var makeBarcodeReadabilityPrediction = useBarcodeReadabilityModelContext().makeBarcodeReadabilityPrediction;
5729
+ var getBarcodeReadabilityThreshold = useBarcodeReadabilityThreshold();
5730
+ return useCallback(function (prediction, lastPredictionCanvas, croppedDocumentCanvas, bestBarcodeCanvas, currentBestBarcodeScore) {
5731
+ return __awaiter(_this, void 0, void 0, function () {
5732
+ var barcodeReadabilityThreshold;
5733
+ return __generator(this, function (_a) {
5734
+ barcodeReadabilityThreshold = getBarcodeReadabilityThreshold(prediction.detectedDocumentType);
5735
+ return [2 /*return*/, analyzeBarcodeReadability(prediction, lastPredictionCanvas, croppedDocumentCanvas, bestBarcodeCanvas, currentBestBarcodeScore, documentDetectionThresholds, makeBarcodeReadabilityPrediction, barcodeReadabilityThreshold)];
5736
+ });
5737
+ });
5738
+ }, [documentDetectionThresholds, makeBarcodeReadabilityPrediction, getBarcodeReadabilityThreshold]);
5739
+ }
5726
5740
  var defaultIdCaptureThresholds = {
5727
5741
  detection: defaultDocumentDetectionThresholds,
5728
5742
  focus: defaultFocusThresholds
@@ -5755,6 +5769,7 @@ var IdCaptureModelsContext = /*#__PURE__*/createContext({
5755
5769
  },
5756
5770
  detectionTime: 0,
5757
5771
  focusPredictionTime: 0,
5772
+ barcodeReadabilityPredictionTime: 0,
5758
5773
  bestFrameDetails: {
5759
5774
  current: null
5760
5775
  },
@@ -5764,55 +5779,80 @@ var IdCaptureModelsContext = /*#__PURE__*/createContext({
5764
5779
  resetBestFrame: function resetBestFrame() {
5765
5780
  return null;
5766
5781
  },
5782
+ bestBarcodeDetails: {
5783
+ current: null
5784
+ },
5785
+ getBestBarcode: function getBestBarcode() {
5786
+ return null;
5787
+ },
5767
5788
  requiredDocumentType: 'none',
5768
5789
  setRequiredDocumentType: function setRequiredDocumentType() {
5769
5790
  return null;
5770
5791
  }
5771
5792
  });
5772
5793
  function IdCaptureModelsProviderInner(_a) {
5794
+ var _b;
5773
5795
  var children = _a.children,
5774
5796
  onModelError = _a.onModelError,
5775
- _b = _a.allowSinglePageIdCapture,
5776
- allowSinglePageIdCapture = _b === void 0 ? false : _b;
5777
- var _c = useContext(DocumentDetectionModelContext),
5778
- documentDetectionModelState = _c.documentDetectionModelState,
5779
- documentDetectionModelDownloadProgress = _c.documentDetectionModelDownloadProgress,
5780
- documentDetectionModelWarmingStartedAt = _c.documentDetectionModelWarmingStartedAt,
5781
- startDocumentDetection = _c.startDocumentDetection,
5782
- stopDocumentDetection = _c.stopDocumentDetection,
5783
- loadDocumentDetectionModel = _c.loadDocumentDetectionModel,
5784
- lastPredictionCanvas = _c.documentDetectionLastPredictionCanvas,
5785
- clearDocumentDetectionLastPredictionCanvas = _c.clearDocumentDetectionLastPredictionCanvas,
5786
- onDocumentDetected = _c.onDocumentDetected,
5787
- detectionTime = _c.detectionTime,
5788
- documentDetectionThresholds = _c.documentDetectionThresholds,
5789
- setDocumentDetectionThresholds = _c.setDocumentDetectionThresholds,
5790
- documentDetectionBoundaries = _c.documentDetectionBoundaries,
5791
- setDocumentDetectionBoundaries = _c.setDocumentDetectionBoundaries,
5792
- documentDetectionModelError = _c.documentDetectionModelError;
5793
- var _d = useContext(FocusModelContext),
5794
- loadFocusModel = _d.loadFocusModel,
5795
- focusModelState = _d.focusModelState,
5796
- focusModelDownloadProgress = _d.focusModelDownloadProgress,
5797
- focusModelWarmingStartedAt = _d.focusModelWarmingStartedAt,
5798
- makeFocusPrediction = _d.makeFocusPrediction,
5799
- focusThresholds = _d.focusThresholds,
5800
- setFocusThresholds = _d.setFocusThresholds,
5801
- focusPredictionTime = _d.focusPredictionTime,
5802
- focusModelError = _d.focusModelError;
5797
+ _c = _a.allowSinglePageIdCapture,
5798
+ allowSinglePageIdCapture = _c === void 0 ? false : _c,
5799
+ _d = _a.enableBarcodeReadabilityModel,
5800
+ enableBarcodeReadabilityModel = _d === void 0 ? true : _d;
5801
+ var _e = useContext(DocumentDetectionModelContext),
5802
+ documentDetectionModelState = _e.documentDetectionModelState,
5803
+ documentDetectionModelDownloadProgress = _e.documentDetectionModelDownloadProgress,
5804
+ documentDetectionModelWarmingStartedAt = _e.documentDetectionModelWarmingStartedAt,
5805
+ startDocumentDetection = _e.startDocumentDetection,
5806
+ stopDocumentDetection = _e.stopDocumentDetection,
5807
+ loadDocumentDetectionModel = _e.loadDocumentDetectionModel,
5808
+ lastPredictionCanvas = _e.documentDetectionLastPredictionCanvas,
5809
+ clearDocumentDetectionLastPredictionCanvas = _e.clearDocumentDetectionLastPredictionCanvas,
5810
+ onDocumentDetected = _e.onDocumentDetected,
5811
+ detectionTime = _e.detectionTime,
5812
+ documentDetectionThresholds = _e.documentDetectionThresholds,
5813
+ setDocumentDetectionThresholds = _e.setDocumentDetectionThresholds,
5814
+ documentDetectionBoundaries = _e.documentDetectionBoundaries,
5815
+ setDocumentDetectionBoundaries = _e.setDocumentDetectionBoundaries,
5816
+ documentDetectionModelError = _e.documentDetectionModelError;
5817
+ var _f = useContext(FocusModelContext),
5818
+ loadFocusModel = _f.loadFocusModel,
5819
+ focusModelState = _f.focusModelState,
5820
+ focusModelDownloadProgress = _f.focusModelDownloadProgress,
5821
+ focusModelWarmingStartedAt = _f.focusModelWarmingStartedAt,
5822
+ makeFocusPrediction = _f.makeFocusPrediction,
5823
+ focusThresholds = _f.focusThresholds,
5824
+ setFocusThresholds = _f.setFocusThresholds,
5825
+ focusPredictionTime = _f.focusPredictionTime,
5826
+ focusModelError = _f.focusModelError;
5827
+ var _g = useBarcodeReadabilityModelContext(),
5828
+ loadBarcodeReadabilityModel = _g.loadBarcodeReadabilityModel,
5829
+ barcodeReadabilityModelState = _g.barcodeReadabilityModelState,
5830
+ barcodeReadabilityModelDownloadProgress = _g.barcodeReadabilityModelDownloadProgress,
5831
+ barcodeReadabilityModelWarmingStartedAt = _g.barcodeReadabilityModelWarmingStartedAt,
5832
+ makeBarcodeReadabilityPrediction = _g.makeBarcodeReadabilityPrediction,
5833
+ barcodeReadabilityThresholds = _g.barcodeReadabilityThresholds,
5834
+ setBarcodeReadabilityThresholds = _g.setBarcodeReadabilityThresholds,
5835
+ barcodeReadabilityPredictionTime = _g.barcodeReadabilityPredictionTime,
5836
+ barcodeReadabilityModelError = _g.barcodeReadabilityModelError;
5803
5837
  var onPredictionHandler = useRef();
5804
5838
  var bestFrameDetails = useRef(null);
5839
+ var bestBarcodeDetails = useRef(null);
5805
5840
  var bestPredictionCanvas = useRef(null);
5841
+ var bestBarcodeCanvas = useRef(null);
5842
+ var croppedDocumentCanvas = useRef(null);
5806
5843
  var bestFocusScore = useRef(0);
5844
+ var bestBarcodeScore = useRef(0);
5807
5845
  var stopDetection = useRef(0);
5808
- var _e = useState('none'),
5809
- requiredDocumentType = _e[0],
5810
- setRequiredDocumentType = _e[1];
5846
+ var analyzeBarcodeReadability = useBarcodeReadabilityAnalysis();
5847
+ var _h = useState('none'),
5848
+ requiredDocumentType = _h[0],
5849
+ setRequiredDocumentType = _h[1];
5811
5850
  var thresholds = useMemo(function () {
5812
5851
  return _assign(_assign({}, documentDetectionThresholds), {
5813
- focus: focusThresholds
5852
+ focus: focusThresholds,
5853
+ barcodeReadability: barcodeReadabilityThresholds
5814
5854
  });
5815
- }, [documentDetectionThresholds, focusThresholds]);
5855
+ }, [documentDetectionThresholds, focusThresholds, barcodeReadabilityThresholds]);
5816
5856
  var setThresholds = useCallback(function (thresholds) {
5817
5857
  if (thresholds.detection) {
5818
5858
  setDocumentDetectionThresholds(thresholds.detection);
@@ -5820,57 +5860,87 @@ function IdCaptureModelsProviderInner(_a) {
5820
5860
  if (thresholds.focus) {
5821
5861
  setFocusThresholds(thresholds.focus);
5822
5862
  }
5823
- }, [setDocumentDetectionThresholds, setFocusThresholds]);
5863
+ if (thresholds.barcodeReadability) {
5864
+ setBarcodeReadabilityThresholds(thresholds.barcodeReadability);
5865
+ }
5866
+ }, [setBarcodeReadabilityThresholds, setDocumentDetectionThresholds, setFocusThresholds]);
5824
5867
  useEffect(function handleDetections() {
5825
5868
  var _this = this;
5826
5869
  onDocumentDetected(function (prediction) {
5827
5870
  return __awaiter(_this, void 0, void 0, function () {
5828
- var stopDetectionAtStart, focusPredictionTime, focusScore, focusThresholdMet, isSinglePage, isRequiredDocumentType, focusPrediction, focusThresholdSet, focusThreshold;
5871
+ var stopDetectionAtStart, focusPredictionTime, focusScore, focusThresholdMet, pdf417PredictionTime, pdf417PredictionScore, pdf417PredictionThresholdMet, isSinglePage, isRequiredDocumentType, focusPrediction, focusThresholdSet, focusThreshold, barcodeAnalysisResult;
5829
5872
  var _a, _b, _c, _d, _e, _f, _g;
5830
5873
  return __generator(this, function (_h) {
5831
- if (!lastPredictionCanvas.current) return [2 /*return*/];
5832
- stopDetectionAtStart = stopDetection.current;
5833
- focusPredictionTime = 0, focusScore = 0, focusThresholdMet = false;
5834
- isSinglePage = prediction.detectedDocumentType === 'singlePage';
5835
- if (!allowSinglePageIdCapture && isSinglePage) {
5836
- prediction.detectedDocumentType = 'passport';
5837
- prediction.passportDetectionScore = prediction.singlePageDetectionScore;
5838
- prediction.passportDetectionThresholdMet = prediction.singlePageDetectionThresholdMet;
5839
- prediction.singlePageDetectionScore = 0;
5840
- prediction.singlePageDetectionThresholdMet = false;
5841
- }
5842
- isRequiredDocumentType = requiredDocumentType === 'none' || prediction.detectedDocumentType === requiredDocumentType || ((_a = requiredDocumentType.includes) === null || _a === void 0 ? void 0 : _a.call(requiredDocumentType, prediction.detectedDocumentType)) || allowSinglePageIdCapture && isSinglePage && ((_b = requiredDocumentType.includes) === null || _b === void 0 ? void 0 : _b.call(requiredDocumentType, 'idCardFront'));
5843
- if (isRequiredDocumentType && prediction.detectedDocumentType !== 'none' && prediction.detectionThresholdMet && prediction.documentInBounds && !prediction.documentTooClose && prediction.documentIsStable) {
5844
- focusPrediction = makeFocusPrediction(lastPredictionCanvas.current, (_c = prediction.bestDocument) === null || _c === void 0 ? void 0 : _c.box);
5845
- if (focusPrediction) {
5846
- focusScore = focusPrediction.score;
5847
- focusPredictionTime = focusPrediction.predictionTime;
5848
- }
5849
- focusThresholdSet = (_d = thresholds.focus) === null || _d === void 0 ? void 0 : _d[prediction.detectedDocumentType];
5850
- 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;
5851
- focusThresholdMet = focusScore >= focusThreshold;
5852
- if (bestFocusScore.current <= focusScore && stopDetectionAtStart === stopDetection.current) {
5853
- bestFocusScore.current = focusScore;
5854
- drawToCanvas(bestPredictionCanvas.current, lastPredictionCanvas.current);
5855
- bestFrameDetails.current = {
5856
- boundingBox: (_f = prediction.bestDocument) === null || _f === void 0 ? void 0 : _f.box,
5857
- documentType: prediction.detectedDocumentType,
5858
- detectionScore: prediction.detectionScore,
5859
- focusScore: focusScore
5860
- };
5861
- }
5874
+ switch (_h.label) {
5875
+ case 0:
5876
+ if (!lastPredictionCanvas.current) return [2 /*return*/];
5877
+ stopDetectionAtStart = stopDetection.current;
5878
+ focusPredictionTime = 0, focusScore = 0, focusThresholdMet = false, pdf417PredictionTime = 0, pdf417PredictionScore = 0, pdf417PredictionThresholdMet = false;
5879
+ isSinglePage = prediction.detectedDocumentType === 'singlePage';
5880
+ if (!allowSinglePageIdCapture && isSinglePage) {
5881
+ prediction.detectedDocumentType = 'passport';
5882
+ prediction.passportDetectionScore = prediction.singlePageDetectionScore;
5883
+ prediction.passportDetectionThresholdMet = prediction.singlePageDetectionThresholdMet;
5884
+ prediction.singlePageDetectionScore = 0;
5885
+ prediction.singlePageDetectionThresholdMet = false;
5886
+ }
5887
+ isRequiredDocumentType = requiredDocumentType === 'none' || prediction.detectedDocumentType === requiredDocumentType || ((_a = requiredDocumentType.includes) === null || _a === void 0 ? void 0 : _a.call(requiredDocumentType, prediction.detectedDocumentType)) || allowSinglePageIdCapture && isSinglePage && ((_b = requiredDocumentType.includes) === null || _b === void 0 ? void 0 : _b.call(requiredDocumentType, 'idCardFront'));
5888
+ if (!(isRequiredDocumentType && prediction.detectedDocumentType !== 'none' && prediction.detectionThresholdMet && prediction.documentInBounds && !prediction.documentTooClose && prediction.documentIsStable)) return [3 /*break*/, 2];
5889
+ focusPrediction = makeFocusPrediction(lastPredictionCanvas.current, (_c = prediction.bestDocument) === null || _c === void 0 ? void 0 : _c.box);
5890
+ if (focusPrediction) {
5891
+ focusScore = focusPrediction.score;
5892
+ focusPredictionTime = focusPrediction.predictionTime;
5893
+ }
5894
+ focusThresholdSet = (_d = thresholds.focus) === null || _d === void 0 ? void 0 : _d[prediction.detectedDocumentType];
5895
+ 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;
5896
+ focusThresholdMet = focusScore >= focusThreshold;
5897
+ if (!(stopDetectionAtStart === stopDetection.current)) return [3 /*break*/, 2];
5898
+ if (bestFocusScore.current <= focusScore) {
5899
+ bestFocusScore.current = focusScore;
5900
+ drawToCanvas(bestPredictionCanvas.current, lastPredictionCanvas.current);
5901
+ bestFrameDetails.current = {
5902
+ boundingBox: (_f = prediction.bestDocument) === null || _f === void 0 ? void 0 : _f.box,
5903
+ documentType: prediction.detectedDocumentType,
5904
+ detectionScore: prediction.detectionScore,
5905
+ focusScore: focusScore
5906
+ };
5907
+ }
5908
+ if (!(enableBarcodeReadabilityModel && prediction.bestDocument && prediction.bestPDF417 && croppedDocumentCanvas.current)) return [3 /*break*/, 2];
5909
+ return [4 /*yield*/, analyzeBarcodeReadability(prediction, lastPredictionCanvas.current, croppedDocumentCanvas.current, bestBarcodeCanvas.current, bestBarcodeScore.current)];
5910
+ case 1:
5911
+ barcodeAnalysisResult = _h.sent();
5912
+ pdf417PredictionTime = barcodeAnalysisResult.pdf417PredictionTime;
5913
+ pdf417PredictionScore = barcodeAnalysisResult.pdf417PredictionScore;
5914
+ pdf417PredictionThresholdMet = barcodeAnalysisResult.pdf417PredictionThresholdMet;
5915
+ if (barcodeAnalysisResult.newBestBarcodeScore) {
5916
+ bestBarcodeScore.current = barcodeAnalysisResult.newBestBarcodeScore;
5917
+ }
5918
+ if (barcodeAnalysisResult.newBestBarcodeDetails) {
5919
+ bestBarcodeDetails.current = barcodeAnalysisResult.newBestBarcodeDetails;
5920
+ }
5921
+ _h.label = 2;
5922
+ case 2:
5923
+ /**
5924
+ * @note
5925
+ * This should ALWAYS be called.
5926
+ * Do not return early from this function unless
5927
+ * lastPredictionCanvas.current is not set
5928
+ */
5929
+ (_g = onPredictionHandler.current) === null || _g === void 0 ? void 0 : _g.call(onPredictionHandler, _assign(_assign({}, prediction), {
5930
+ focusScore: focusScore,
5931
+ focusPredictionTime: focusPredictionTime,
5932
+ focusThresholdMet: focusThresholdMet,
5933
+ pdf417PredictionTime: pdf417PredictionTime,
5934
+ pdf417PredictionScore: pdf417PredictionScore,
5935
+ pdf417PredictionThresholdMet: pdf417PredictionThresholdMet
5936
+ }));
5937
+ return [2 /*return*/];
5862
5938
  }
5863
- (_g = onPredictionHandler.current) === null || _g === void 0 ? void 0 : _g.call(onPredictionHandler, _assign(_assign({}, prediction), {
5864
- focusScore: focusScore,
5865
- focusPredictionTime: focusPredictionTime,
5866
- focusThresholdMet: focusThresholdMet
5867
- }));
5868
- return [2 /*return*/];
5869
5939
  });
5870
5940
  });
5871
5941
  });
5872
- }, [allowSinglePageIdCapture, lastPredictionCanvas, makeFocusPrediction, onDocumentDetected, requiredDocumentType, thresholds.focus]);
5873
- var modelError = documentDetectionModelError !== null && documentDetectionModelError !== void 0 ? documentDetectionModelError : focusModelError;
5942
+ }, [allowSinglePageIdCapture, analyzeBarcodeReadability, barcodeReadabilityThresholds, enableBarcodeReadabilityModel, lastPredictionCanvas, makeBarcodeReadabilityPrediction, makeFocusPrediction, onDocumentDetected, requiredDocumentType, thresholds.focus]);
5943
+ var modelError = (_b = documentDetectionModelError !== null && documentDetectionModelError !== void 0 ? documentDetectionModelError : focusModelError) !== null && _b !== void 0 ? _b : barcodeReadabilityModelError;
5874
5944
  useEffect(function handleModelErrors() {
5875
5945
  if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
5876
5946
  }, [modelError, onModelError]);
@@ -5883,9 +5953,15 @@ function IdCaptureModelsProviderInner(_a) {
5883
5953
  canvas: bestPredictionCanvas.current
5884
5954
  });
5885
5955
  }, []);
5886
- var _f = useState(0),
5887
- canvasKey = _f[0],
5888
- setCanvasKey = _f[1];
5956
+ var getBestBarcode = useCallback(function () {
5957
+ if (!bestBarcodeDetails.current || !bestBarcodeCanvas.current) return null;
5958
+ return _assign(_assign({}, bestBarcodeDetails.current), {
5959
+ canvas: bestBarcodeCanvas.current
5960
+ });
5961
+ }, []);
5962
+ var _j = useState(0),
5963
+ canvasKey = _j[0],
5964
+ setCanvasKey = _j[1];
5889
5965
  var resetBestFrame = useCallback(function () {
5890
5966
  stopDetection.current += 1;
5891
5967
  setCanvasKey(function (n) {
@@ -5901,16 +5977,45 @@ function IdCaptureModelsProviderInner(_a) {
5901
5977
  var load = useCallback(function () {
5902
5978
  loadDocumentDetectionModel();
5903
5979
  loadFocusModel();
5904
- }, [loadDocumentDetectionModel, loadFocusModel]);
5905
- var ready = documentDetectionModelState === 'ready' && focusModelState === 'ready';
5906
- var modelLoadState = ready ? 'ready' : documentDetectionModelState === 'warming' || focusModelState === 'warming' ? 'warming' : focusModelState === 'downloading' || documentDetectionModelState === 'downloading' ? 'downloading' : 'not-started';
5907
- var modelWarmingStartedAt = !documentDetectionModelWarmingStartedAt && !focusModelWarmingStartedAt ? null : Math.min.apply(Math, [documentDetectionModelWarmingStartedAt, focusModelWarmingStartedAt].filter(function (v) {
5908
- return v !== null;
5909
- }));
5980
+ if (enableBarcodeReadabilityModel) loadBarcodeReadabilityModel();
5981
+ }, [enableBarcodeReadabilityModel, loadBarcodeReadabilityModel, loadDocumentDetectionModel, loadFocusModel]);
5982
+ var _k = useMemo(function () {
5983
+ var modelStates = [documentDetectionModelState, focusModelState];
5984
+ var modelWarmingStartedAts = [documentDetectionModelWarmingStartedAt, focusModelWarmingStartedAt];
5985
+ var modelDownloadProgresses = [documentDetectionModelDownloadProgress, focusModelDownloadProgress];
5986
+ if (enableBarcodeReadabilityModel) {
5987
+ modelStates.push(barcodeReadabilityModelState);
5988
+ modelWarmingStartedAts.push(barcodeReadabilityModelWarmingStartedAt);
5989
+ modelDownloadProgresses.push(barcodeReadabilityModelDownloadProgress);
5990
+ }
5991
+ var ready = modelStates.every(function (state) {
5992
+ return state === 'ready';
5993
+ });
5994
+ return {
5995
+ ready: ready,
5996
+ modelLoadState: ready ? 'ready' : modelStates.some(function (state) {
5997
+ return state === 'warming';
5998
+ }) ? 'warming' : modelStates.some(function (state) {
5999
+ return state === 'downloading';
6000
+ }) ? 'downloading' : 'not-started',
6001
+ modelWarmingStartedAt: modelWarmingStartedAts.every(function (v) {
6002
+ return v === null;
6003
+ }) ? null : Math.min.apply(Math, modelWarmingStartedAts.filter(function (v) {
6004
+ return v !== null;
6005
+ })),
6006
+ modelDownloadProgress: modelDownloadProgresses.reduce(function (a, b) {
6007
+ return a + b;
6008
+ }, 0) / modelDownloadProgresses.length
6009
+ };
6010
+ }, [barcodeReadabilityModelDownloadProgress, barcodeReadabilityModelState, barcodeReadabilityModelWarmingStartedAt, documentDetectionModelDownloadProgress, documentDetectionModelState, documentDetectionModelWarmingStartedAt, enableBarcodeReadabilityModel, focusModelDownloadProgress, focusModelState, focusModelWarmingStartedAt]),
6011
+ ready = _k.ready,
6012
+ modelLoadState = _k.modelLoadState,
6013
+ modelWarmingStartedAt = _k.modelWarmingStartedAt,
6014
+ modelDownloadProgress = _k.modelDownloadProgress;
5910
6015
  var value = useMemo(function () {
5911
6016
  return {
5912
6017
  ready: ready,
5913
- modelDownloadProgress: (documentDetectionModelDownloadProgress + focusModelDownloadProgress) / 2,
6018
+ modelDownloadProgress: modelDownloadProgress,
5914
6019
  modelLoadState: modelLoadState,
5915
6020
  modelWarmingStartedAt: modelWarmingStartedAt,
5916
6021
  modelError: modelError,
@@ -5924,24 +6029,35 @@ function IdCaptureModelsProviderInner(_a) {
5924
6029
  onPredictionMade: onPredictionMade,
5925
6030
  detectionTime: detectionTime,
5926
6031
  focusPredictionTime: focusPredictionTime,
6032
+ barcodeReadabilityPredictionTime: barcodeReadabilityPredictionTime,
5927
6033
  getBestFrame: getBestFrame,
5928
6034
  resetBestFrame: resetBestFrame,
5929
6035
  bestFrameDetails: bestFrameDetails,
6036
+ bestBarcodeDetails: bestBarcodeDetails,
6037
+ getBestBarcode: getBestBarcode,
5930
6038
  requiredDocumentType: requiredDocumentType,
5931
6039
  setRequiredDocumentType: setRequiredDocumentType
5932
6040
  };
5933
- }, [detectionTime, documentDetectionBoundaries, documentDetectionModelDownloadProgress, focusModelDownloadProgress, focusPredictionTime, getBestFrame, load, modelLoadState, modelError, modelWarmingStartedAt, onPredictionMade, ready, requiredDocumentType, resetBestFrame, setDocumentDetectionBoundaries, setThresholds, startDocumentDetection, stopDocumentDetection, thresholds]);
6041
+ }, [ready, modelDownloadProgress, modelLoadState, modelWarmingStartedAt, modelError, startDocumentDetection, stopDocumentDetection, load, thresholds, setThresholds, documentDetectionBoundaries, setDocumentDetectionBoundaries, onPredictionMade, detectionTime, focusPredictionTime, barcodeReadabilityPredictionTime, getBestFrame, resetBestFrame, getBestBarcode, requiredDocumentType]);
5934
6042
  return /*#__PURE__*/React__default.createElement(IdCaptureModelsContext.Provider, {
5935
6043
  value: value
5936
- }, /*#__PURE__*/React__default.createElement(InvisibleCanvas, {
5937
- key: canvasKey,
6044
+ }, /*#__PURE__*/React__default.createElement(InvisibleCanvasContainer, null, /*#__PURE__*/React__default.createElement(InvisibleCanvas, {
6045
+ key: "bf-".concat(canvasKey),
5938
6046
  ref: bestPredictionCanvas
5939
- }), children);
6047
+ }), /*#__PURE__*/React__default.createElement(InvisibleCanvas, {
6048
+ key: "bb-".concat(canvasKey),
6049
+ ref: bestBarcodeCanvas
6050
+ }), /*#__PURE__*/React__default.createElement(InvisibleCanvas, {
6051
+ key: "cd-".concat(canvasKey),
6052
+ ref: croppedDocumentCanvas
6053
+ })), children);
5940
6054
  }
5941
6055
  function IdCaptureModelsProvider(_a) {
5942
6056
  var children = _a.children,
5943
6057
  props = __rest(_a, ["children"]);
5944
- return /*#__PURE__*/React__default.createElement(DocumentDetectionModelProvider, _assign({}, props), /*#__PURE__*/React__default.createElement(FocusModelProvider, _assign({}, props), /*#__PURE__*/React__default.createElement(IdCaptureModelsProviderInner, _assign({}, props), children)));
6058
+ return /*#__PURE__*/React__default.createElement(DocumentDetectionModelProvider, _assign({}, props), /*#__PURE__*/React__default.createElement(FocusModelProvider, _assign({}, props), /*#__PURE__*/React__default.createElement(BarcodeReadabilityModelProvider, _assign({}, props, {
6059
+ shouldLoadModels: props.enableBarcodeReadabilityModel
6060
+ }), /*#__PURE__*/React__default.createElement(IdCaptureModelsProviderInner, _assign({}, props), children))));
5945
6061
  }
5946
6062
  function useIdCaptureModelsContext() {
5947
6063
  var context = useContext(IdCaptureModelsContext);
@@ -5951,7 +6067,7 @@ function useIdCaptureModelsContext() {
5951
6067
  return context;
5952
6068
  }
5953
6069
 
5954
- var CapturedDocumentTypeValues = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'selfie', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
6070
+ var CapturedDocumentTypeValues = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'selfie', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage', 'idBarcodeImage'];
5955
6071
 
5956
6072
  var acceptedDocumentTypesForIdCaptureRequirementOption = {
5957
6073
  idCardFront: ['idCardFront'],
@@ -6037,6 +6153,7 @@ var initialState$5 = {
6037
6153
  capturing: false,
6038
6154
  captureFailed: false,
6039
6155
  imageUrl: null,
6156
+ idBarcodeImage: null,
6040
6157
  captureState: 'initializing',
6041
6158
  capturedDocuments: {},
6042
6159
  captureRequirement: 'idCardOrPassport',
@@ -6316,6 +6433,17 @@ var _reducer = function reducer(state, action) {
6316
6433
  }
6317
6434
  return newState;
6318
6435
  }
6436
+ case 'barcodeCaptured':
6437
+ return _reducer(state, {
6438
+ type: 'documentCaptured',
6439
+ payload: {
6440
+ imageData: action.payload.imageUrl,
6441
+ documentType: 'idBarcodeImage',
6442
+ width: 0,
6443
+ height: 0,
6444
+ barcodeReadabilityScore: action.payload.barcodeReadabilityScore
6445
+ }
6446
+ });
6319
6447
  case 'flipRequestCompleted':
6320
6448
  return _assign(_assign({}, state), {
6321
6449
  captureState: 'capturing',
@@ -6807,12 +6935,13 @@ var IdCapture = function IdCapture(_a) {
6807
6935
  height = _q === void 0 ? 1 : _q;
6808
6936
  var state = useIdCaptureStore();
6809
6937
  var isRearFacing = useCameraStore().isRearFacing;
6810
- var _r = useContext(IdCaptureModelsContext),
6938
+ var _r = useIdCaptureModelsContext(),
6811
6939
  modelsReady = _r.ready,
6812
6940
  setThresholds = _r.setThresholds,
6813
6941
  detectionTime = _r.detectionTime,
6814
6942
  focusPredictionTime = _r.focusPredictionTime,
6815
- getBestFrame = _r.getBestFrame;
6943
+ getBestFrame = _r.getBestFrame,
6944
+ getBestBarcode = _r.getBestBarcode;
6816
6945
  useEffect(function () {
6817
6946
  return dispatchIdCaptureAction({
6818
6947
  type: 'captureInitialized'
@@ -6851,6 +6980,16 @@ var IdCapture = function IdCapture(_a) {
6851
6980
  });
6852
6981
  return;
6853
6982
  }
6983
+ var bestBarcode = getBestBarcode();
6984
+ if (bestBarcode) {
6985
+ dispatchIdCaptureAction({
6986
+ type: 'barcodeCaptured',
6987
+ payload: {
6988
+ imageUrl: bestBarcode.canvas.toDataURL('image/jpeg', 0.95),
6989
+ barcodeReadabilityScore: bestBarcode.score
6990
+ }
6991
+ });
6992
+ }
6854
6993
  var canvas = bestFrame.canvas,
6855
6994
  documentType = bestFrame.documentType,
6856
6995
  boundingBox = bestFrame.boundingBox,
@@ -6867,21 +7006,22 @@ var IdCapture = function IdCapture(_a) {
6867
7006
  });
6868
7007
  var capturedDocumentType = documentType;
6869
7008
  setTimeout(function () {
6870
- var _a;
6871
- var captureTime = new Date().getTime() - ((_a = state.captureStartedAt) !== null && _a !== void 0 ? _a : new Date()).getTime();
7009
+ var _a, _b;
7010
+ var captureTime = performance.now() - ((_a = state.captureStartedAt) !== null && _a !== void 0 ? _a : new Date()).getTime();
6872
7011
  var metadata = {
6873
7012
  autoCapture: 'Y',
6874
7013
  captureTime: captureTime,
6875
7014
  boundingBox: boundingBox,
6876
7015
  bestDetectionScore: detectionScore,
6877
- bestFocusScore: focusScore
7016
+ bestFocusScore: focusScore,
7017
+ bestBarcodeScore: (_b = bestBarcode === null || bestBarcode === void 0 ? void 0 : bestBarcode.score) !== null && _b !== void 0 ? _b : 0
6878
7018
  };
6879
7019
  onCapture === null || onCapture === void 0 ? void 0 : onCapture(imageUrl, width, height, capturedDocumentType, metadata);
6880
7020
  dispatchIdCaptureAction({
6881
7021
  type: 'captured'
6882
7022
  });
6883
7023
  }, 0);
6884
- }, [getBestFrame, onCapture, shouldCapture, state.captureStartedAt, state.requestedDocumentType]);
7024
+ }, [getBestBarcode, getBestFrame, onCapture, shouldCapture, state.captureStartedAt, state.requestedDocumentType]);
6885
7025
  var theme = useTheme();
6886
7026
  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');
6887
7027
  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');
@@ -7681,7 +7821,7 @@ var IdCaptureLoadingOverlayDefault = function IdCaptureLoadingOverlayDefault(_a)
7681
7821
  };
7682
7822
  }, [ready]);
7683
7823
  var imageRef = useRef(null);
7684
- var timeSinceWarmingStarted = modelWarmingStartedAt ? new Date().getTime() - modelWarmingStartedAt : 0;
7824
+ var timeSinceWarmingStarted = modelWarmingStartedAt ? performance.now() - modelWarmingStartedAt : 0;
7685
7825
  var warmingProgress = timeSinceWarmingStarted / 5000.0;
7686
7826
  var modelLoadProgress = modelsReady ? 100 : modelDownloadProgress * 0.5 + warmingProgress * 49.0;
7687
7827
  useLoadProgressHooks({
@@ -8019,7 +8159,7 @@ var Card = styled.div(templateObject_1$D || (templateObject_1$D = __makeTemplate
8019
8159
  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"])));
8020
8160
  var templateObject_1$D, templateObject_2$y;
8021
8161
 
8022
- var imageDisplayOrder = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
8162
+ var imageDisplayOrder = ['idCardFront', 'idCardBack', 'idBarcodeImage', 'passport', 'singlePage', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
8023
8163
  var IdCaptureSuccess = function IdCaptureSuccess(_a) {
8024
8164
  var capturedDocuments = _a.capturedDocuments,
8025
8165
  onSubmitClick = _a.onSubmitClick,
@@ -8061,7 +8201,7 @@ var IdCaptureSuccess = function IdCaptureSuccess(_a) {
8061
8201
  image: doc,
8062
8202
  className: classNames.image,
8063
8203
  alt: doc.documentType
8064
- }), debugMode && ( /*#__PURE__*/React__default.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)))));
8204
+ }), debugMode && ( /*#__PURE__*/React__default.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)))));
8065
8205
  }))), /*#__PURE__*/React__default.createElement(ButtonsColumn, {
8066
8206
  className: classNames.buttonsRow
8067
8207
  }, /*#__PURE__*/React__default.createElement(WideButton, {
@@ -10683,7 +10823,7 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
10683
10823
  var _6 = useState(false),
10684
10824
  overlayDismissed = _6[0],
10685
10825
  setOverlayDismissed = _6[1];
10686
- var _7 = useContext(SubmissionContext),
10826
+ var _7 = useSubmissionContext(),
10687
10827
  submissionStatus = _7.submissionStatus,
10688
10828
  setIdFrontImage = _7.setIdFrontImage,
10689
10829
  setIdBackImage = _7.setIdBackImage,
@@ -10692,6 +10832,7 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
10692
10832
  setIdBackIrImage = _7.setIdBackIrImage,
10693
10833
  setIdFrontUvImage = _7.setIdFrontUvImage,
10694
10834
  setIdBackUvImage = _7.setIdBackUvImage,
10835
+ setIdBarcodeImage = _7.setIdBarcodeImage,
10695
10836
  logIdFrontCaptureAttempt = _7.logIdFrontCaptureAttempt,
10696
10837
  logIdBackCaptureAttempt = _7.logIdBackCaptureAttempt;
10697
10838
  var _8 = useIdCaptureModelsContext(),
@@ -10792,7 +10933,7 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
10792
10933
  });
10793
10934
  }, [logCaptureMetadata, onDocumentCaptured]);
10794
10935
  var onSubmitClick = useCallback(function () {
10795
- var _a, _b, _c, _d, _e, _f, _g, _h;
10936
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
10796
10937
  var docs = state.capturedDocuments;
10797
10938
  var submission = {
10798
10939
  idFrontImage: maybeDataUrlToBase64Sync((_a = docs.idCardFront) === null || _a === void 0 ? void 0 : _a.imageData),
@@ -10802,7 +10943,8 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
10802
10943
  idFrontIrImage: maybeDataUrlToBase64Sync((_e = docs.idFrontIrImage) === null || _e === void 0 ? void 0 : _e.imageData),
10803
10944
  idBackIrImage: maybeDataUrlToBase64Sync((_f = docs.idBackIrImage) === null || _f === void 0 ? void 0 : _f.imageData),
10804
10945
  idFrontUvImage: maybeDataUrlToBase64Sync((_g = docs.idFrontUvImage) === null || _g === void 0 ? void 0 : _g.imageData),
10805
- idBackUvImage: maybeDataUrlToBase64Sync((_h = docs.idBackUvImage) === null || _h === void 0 ? void 0 : _h.imageData)
10946
+ idBackUvImage: maybeDataUrlToBase64Sync((_h = docs.idBackUvImage) === null || _h === void 0 ? void 0 : _h.imageData),
10947
+ idBarcodeImage: maybeDataUrlToBase64Sync((_j = docs.idBarcodeImage) === null || _j === void 0 ? void 0 : _j.imageData)
10806
10948
  };
10807
10949
  if (submission.idFrontImage) setIdFrontImage(submission.idFrontImage);
10808
10950
  if (submission.idBackImage) setIdBackImage(submission.idBackImage);
@@ -10812,11 +10954,12 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
10812
10954
  if (submission.idBackIrImage) setIdBackIrImage(submission.idBackIrImage);
10813
10955
  if (submission.idFrontUvImage) setIdFrontUvImage(submission.idFrontUvImage);
10814
10956
  if (submission.idBackUvImage) setIdBackUvImage(submission.idBackUvImage);
10957
+ if (submission.idBarcodeImage) setIdBarcodeImage(submission.idBarcodeImage);
10815
10958
  if (releaseCameraAccessOnExit) releaseCameraAccess();
10816
10959
  setTimeout(function () {
10817
10960
  return onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(submission);
10818
10961
  }, 0);
10819
- }, [onSuccess, releaseCameraAccess, releaseCameraAccessOnExit, setIdBackImage, setIdBackIrImage, setIdBackUvImage, setIdFrontImage, setIdFrontIrImage, setIdFrontUvImage, setPassportImage, state.capturedDocuments]);
10962
+ }, [onSuccess, releaseCameraAccess, releaseCameraAccessOnExit, setIdBarcodeImage, setIdBackImage, setIdBackIrImage, setIdBackUvImage, setIdFrontImage, setIdFrontIrImage, setIdFrontUvImage, setPassportImage, state.capturedDocuments]);
10820
10963
  var showSuccessScreen = useShowSuccessScreen(skipSuccessScreen, state.captureState === 'complete', onSubmitClick);
10821
10964
  var onRetryClick = useCallback(function () {
10822
10965
  return dispatchIdCaptureAction({
@@ -11625,40 +11768,378 @@ function SelfieCaptureAnimatedMaskWithStatus(_a) {
11625
11768
  });
11626
11769
  }, 250);
11627
11770
  return function () {
11628
- clearInterval(interval);
11771
+ clearInterval(interval);
11772
+ };
11773
+ }, [status]);
11774
+ return /*#__PURE__*/React__default.createElement(SelfieCaptureAnimatedMask, _assign({}, props, {
11775
+ frame: frame,
11776
+ status: status
11777
+ }));
11778
+ }
11779
+ var templateObject_1$o, templateObject_2$m, templateObject_3$g;
11780
+
11781
+ var FaceCaptureGuideContainer = styled.div(templateObject_1$n || (templateObject_1$n = __makeTemplateObject(["\n position: absolute;\n z-index: 1000;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n box-sizing: border-box;\n"], ["\n position: absolute;\n z-index: 1000;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n box-sizing: border-box;\n"])));
11782
+ var FaceCaptureGuideInner = styled.div(templateObject_2$l || (templateObject_2$l = __makeTemplateObject(["\n position: relative;\n height: 60%;\n"], ["\n position: relative;\n height: 60%;\n"])));
11783
+ var FaceCaptureGuideOverlay = function FaceCaptureGuideOverlay(_a) {
11784
+ var _b = _a.classNames,
11785
+ classNames = _b === void 0 ? {} : _b,
11786
+ _c = _a.status,
11787
+ status = _c === void 0 ? 'ready' : _c,
11788
+ _d = _a.borderWidth,
11789
+ borderWidth = _d === void 0 ? 5 : _d,
11790
+ _e = _a.borderColor,
11791
+ borderColor = _e === void 0 ? 'white' : _e,
11792
+ _f = _a.borderOpacity,
11793
+ borderOpacity = _f === void 0 ? 0.8 : _f;
11794
+ return /*#__PURE__*/React__default.createElement(FaceCaptureGuideContainer, {
11795
+ className: classNames.container
11796
+ }, /*#__PURE__*/React__default.createElement(FaceCaptureGuideInner, null, /*#__PURE__*/React__default.createElement(SelfieCaptureAnimatedMaskWithStatus, {
11797
+ status: status,
11798
+ borderColor: borderColor,
11799
+ borderWidth: borderWidth,
11800
+ borderOpacity: borderOpacity,
11801
+ verticalAlign: "center"
11802
+ })));
11803
+ };
11804
+ var templateObject_1$n, templateObject_2$l;
11805
+
11806
+ var defaultSelfieCaptureModelLoadTimeoutMs = 45000;
11807
+ var detector = null;
11808
+ var detectorSettings = null;
11809
+ function loadFaceDetector() {
11810
+ return __awaiter(this, arguments, void 0, function (modelAssetPath) {
11811
+ var _a, _b;
11812
+ if (modelAssetPath === void 0) {
11813
+ modelAssetPath = defaultFaceDetectorModelPath;
11814
+ }
11815
+ return __generator(this, function (_c) {
11816
+ switch (_c.label) {
11817
+ case 0:
11818
+ if (detector && (detectorSettings === null || detectorSettings === void 0 ? void 0 : detectorSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, detector];
11819
+ closeFaceDetector();
11820
+ return [4 /*yield*/, preloadFaceDetectorDependencies()];
11821
+ case 1:
11822
+ _c.sent();
11823
+ if (modelCapabilities.delegate === 'NONE') {
11824
+ throw new Error('No available delegate for face detector.');
11825
+ }
11826
+ _b = (_a = FaceDetector).createFromOptions;
11827
+ return [4 /*yield*/, FilesetResolver.forVisionTasks(visionTasksBasePath)];
11828
+ case 2:
11829
+ return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
11830
+ // canvas: document.createElement('canvas'),
11831
+ baseOptions: {
11832
+ modelAssetPath: modelAssetPath,
11833
+ delegate: modelCapabilities.delegate
11834
+ },
11835
+ runningMode: 'VIDEO'
11836
+ }])];
11837
+ case 3:
11838
+ detector = _c.sent();
11839
+ detectorSettings = {
11840
+ modelAssetPath: modelAssetPath
11841
+ };
11842
+ return [2 /*return*/, detector];
11843
+ }
11844
+ });
11845
+ });
11846
+ }
11847
+ function closeFaceDetector() {
11848
+ detector === null || detector === void 0 ? void 0 : detector.close();
11849
+ detector = null;
11850
+ detectorSettings = null;
11851
+ }
11852
+ function useLoadFaceDetector(_a) {
11853
+ var onModelError = _a.onModelError,
11854
+ _b = _a.modelLoadTimeoutMs,
11855
+ modelLoadTimeoutMs = _b === void 0 ? defaultSelfieCaptureModelLoadTimeoutMs : _b,
11856
+ videoRef = _a.videoRef;
11857
+ var _c = useState('not-started'),
11858
+ modelLoadState = _c[0],
11859
+ setModelLoadState = _c[1];
11860
+ var _d = useState(0),
11861
+ modelDownloadProgress = _d[0],
11862
+ setModelDownloadProgress = _d[1];
11863
+ var _e = useState(null),
11864
+ modelWarmingStartedAt = _e[0],
11865
+ setModelWarmingStartedAt = _e[1];
11866
+ var _f = useState(null),
11867
+ modelError = _f[0],
11868
+ setModelError = _f[1];
11869
+ useEffect(function loadModel() {
11870
+ var _this = this;
11871
+ setModelLoadState('downloading');
11872
+ setModelWarmingStartedAt(null);
11873
+ var modelLoadTimeout = setTimeout(function () {
11874
+ setModelError(new Error('Model loading time limit exceeded.'));
11875
+ }, modelLoadTimeoutMs);
11876
+ function handleDownloadProgress(event) {
11877
+ setModelDownloadProgress(progressToPercentage(event.detail));
11878
+ }
11879
+ document.addEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
11880
+ var cancelVideoReady = function cancelVideoReady() {};
11881
+ loadFaceDetector().then(function (model) {
11882
+ return __awaiter(_this, void 0, void 0, function () {
11883
+ var _a, videoReady, cancel, cancelled;
11884
+ return __generator(this, function (_b) {
11885
+ switch (_b.label) {
11886
+ case 0:
11887
+ setModelDownloadProgress(100);
11888
+ clearTimeout(modelLoadTimeout);
11889
+ setModelLoadState('warming');
11890
+ setModelWarmingStartedAt(performance.now());
11891
+ return [4 /*yield*/, testFaceDetectionAgainstKnownImage(model)];
11892
+ case 1:
11893
+ _b.sent();
11894
+ _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
11895
+ cancelled = false;
11896
+ cancelVideoReady = function cancelVideoReady() {
11897
+ cancelled = true;
11898
+ cancel();
11899
+ };
11900
+ return [4 /*yield*/, videoReady];
11901
+ case 2:
11902
+ _b.sent();
11903
+ if (cancelled) return [2 /*return*/];
11904
+ model.detectForVideo(videoRef.current, performance.now());
11905
+ setModelLoadState('ready');
11906
+ return [2 /*return*/];
11907
+ }
11908
+ });
11909
+ });
11910
+ })["catch"](function (e) {
11911
+ setModelError(e);
11912
+ setModelLoadState('error');
11913
+ })["finally"](function () {
11914
+ clearTimeout(modelLoadTimeout);
11915
+ });
11916
+ return function () {
11917
+ log('unloading face detection model');
11918
+ cancelVideoReady();
11919
+ closeFaceDetector();
11920
+ clearTimeout(modelLoadTimeout);
11921
+ document.removeEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
11629
11922
  };
11630
- }, [status]);
11631
- return /*#__PURE__*/React__default.createElement(SelfieCaptureAnimatedMask, _assign({}, props, {
11632
- frame: frame,
11633
- status: status
11634
- }));
11923
+ }, [modelLoadTimeoutMs, videoRef]);
11924
+ useEffect(function handleModelError() {
11925
+ if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
11926
+ }, [modelError, onModelError]);
11927
+ return useMemo(function () {
11928
+ return {
11929
+ ready: modelLoadState === 'ready',
11930
+ modelLoadState: modelLoadState,
11931
+ modelDownloadProgress: modelDownloadProgress,
11932
+ modelWarmingStartedAt: modelWarmingStartedAt,
11933
+ modelError: modelError
11934
+ };
11935
+ }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
11936
+ }
11937
+ var lastFaceDetectionAt = 0;
11938
+ var lastFaceDetectionTime = 0;
11939
+ function setLastFaceDetectionAt(time) {
11940
+ lastFaceDetectionTime = time - lastFaceDetectionAt;
11941
+ lastFaceDetectionAt = time;
11942
+ }
11943
+ var framesNeededSamples = [];
11944
+ function trackFramesNeeded(value, bufferLength) {
11945
+ if (bufferLength === void 0) {
11946
+ bufferLength = 25;
11947
+ }
11948
+ framesNeededSamples.unshift(value);
11949
+ if (framesNeededSamples.length > bufferLength) framesNeededSamples.length = bufferLength;
11950
+ }
11951
+ var lastNFaces = [];
11952
+ var lastNFacePairs = [];
11953
+ var lastNNoses = [];
11954
+ var lastNNosePairs = [];
11955
+ function trackFace(face, framesNeeded, frameWidth, frameHeight) {
11956
+ if (framesNeeded === void 0) {
11957
+ framesNeeded = 12;
11958
+ }
11959
+ var nose = face.keypoints[2];
11960
+ if (!nose) return;
11961
+ lastNFaces.unshift(face);
11962
+ lastNNoses.unshift(nose);
11963
+ if (lastNFaces.length > framesNeeded) lastNFaces.length = framesNeeded;
11964
+ if (lastNNoses.length > framesNeeded) lastNNoses.length = framesNeeded;
11965
+ if (lastNFaces.length > 1) {
11966
+ var lastFace = lastNFaces[1];
11967
+ var iou = calculateIoU(face.box, lastFace.box);
11968
+ lastNFacePairs.unshift({
11969
+ a: face,
11970
+ b: lastFace,
11971
+ iou: iou
11972
+ });
11973
+ if (lastNFacePairs.length > framesNeeded - 1) lastNFacePairs.length = framesNeeded - 1;
11974
+ }
11975
+ if (lastNNoses.length > 1) {
11976
+ var lastNose = lastNNoses[1];
11977
+ var noseDistance = Math.sqrt(Math.pow((nose.x - lastNose.x) / frameWidth, 2) + Math.pow((nose.y - lastNose.y) / frameHeight, 2));
11978
+ lastNNosePairs.unshift({
11979
+ a: nose,
11980
+ b: lastNose,
11981
+ distance: noseDistance
11982
+ });
11983
+ if (lastNNosePairs.length > framesNeeded - 1) lastNNosePairs.length = framesNeeded - 1;
11984
+ }
11985
+ }
11986
+ function makeFaceDetectorPrediction(imageData) {
11987
+ if (!detector) return null;
11988
+ var prediction = detector.detectForVideo(imageData, performance.now());
11989
+ var faces = prediction.detections.map(function (d) {
11990
+ return {
11991
+ box: convertBoundingBox(d.boundingBox),
11992
+ keypoints: d.keypoints.map(function (k) {
11993
+ var _a;
11994
+ return _assign(_assign({}, k), {
11995
+ x: k.x * imageData.width,
11996
+ y: k.y * imageData.height,
11997
+ name: (_a = k.label) !== null && _a !== void 0 ? _a : ''
11998
+ });
11999
+ })
12000
+ };
12001
+ });
12002
+ return _assign(_assign({}, prediction), {
12003
+ faces: faces
12004
+ });
12005
+ }
12006
+ function processFaceDetectorPrediction(_a) {
12007
+ var faces = _a.faces,
12008
+ videoWidth = _a.videoWidth,
12009
+ videoHeight = _a.videoHeight,
12010
+ _b = _a.requireVerticalFaceCentering,
12011
+ requireVerticalFaceCentering = _b === void 0 ? true : _b,
12012
+ _c = _a.stabilityThreshold,
12013
+ stabilityThreshold = _c === void 0 ? 0.7 : _c,
12014
+ _d = _a.noseDistanceThreshold,
12015
+ noseDistanceThreshold = _d === void 0 ? 0.025 : _d,
12016
+ _e = _a.xBoundary,
12017
+ xBoundary = _e === void 0 ? 0.01 : _e,
12018
+ // this represents the edge that the sides of the face box should not cross -- 1% of video width
12019
+ _f = _a.yBoundary,
12020
+ // this represents the edge that the sides of the face box should not cross -- 1% of video width
12021
+ yBoundary = _f === void 0 ? 0.01 : _f,
12022
+ // this represents the edge that the top or bottom of the face box should not cross -- 1% of video height
12023
+ _g = _a.xCentroidBoundary,
12024
+ // this represents the edge that the top or bottom of the face box should not cross -- 1% of video height
12025
+ xCentroidBoundary = _g === void 0 ? 0.125 : _g,
12026
+ // this represents the edge that the centroid of the face should not cross -- 12.5% of video width
12027
+ _h = _a.yCentroidBoundary,
12028
+ // this represents the edge that the centroid of the face should not cross -- 12.5% of video width
12029
+ yCentroidBoundary = _h === void 0 ? 0.125 : _h,
12030
+ // this represents the edge that the centroid of the face should not cross -- 12.5% of video height
12031
+ _j = _a.foreheadRatio,
12032
+ // this represents the edge that the centroid of the face should not cross -- 12.5% of video height
12033
+ foreheadRatio = _j === void 0 ? 0.275 : _j,
12034
+ // we found that the bounding box ends at the brow and misses the forehead. this ratio represents how much we should extend the box to include the forehead.
12035
+ _k = _a.noseTrackingThreshold,
12036
+ // we found that the bounding box ends at the brow and misses the forehead. this ratio represents how much we should extend the box to include the forehead.
12037
+ noseTrackingThreshold = _k === void 0 ? 0.2 : _k,
12038
+ // this represents the maximum distance that the nose can be from the center of the face box -- 20% of the face box width or height
12039
+ minCaptureBrightnessThreshold = _a.minCaptureBrightnessThreshold,
12040
+ minCaptureRangeThreshold = _a.minCaptureRangeThreshold,
12041
+ minCaptureVarianceThreshold = _a.minCaptureVarianceThreshold,
12042
+ brightness = _a.brightness,
12043
+ range = _a.range,
12044
+ variance = _a.variance;
12045
+ var face = faces[0];
12046
+ var faceNotDetected = faces.length === 0;
12047
+ var faceNotCentered = false,
12048
+ faceLookingAway = false,
12049
+ faceTooClose = false,
12050
+ faceTooFar = false,
12051
+ faceVisibilityTooLow = false;
12052
+ var hasAnyThreshold = minCaptureBrightnessThreshold !== undefined || minCaptureRangeThreshold !== undefined || minCaptureVarianceThreshold !== undefined;
12053
+ if (hasAnyThreshold) {
12054
+ var tooDark = minCaptureBrightnessThreshold !== undefined && brightness !== undefined && brightness < minCaptureBrightnessThreshold;
12055
+ var tooLowRange = minCaptureRangeThreshold !== undefined && range !== undefined && range < minCaptureRangeThreshold;
12056
+ var tooLowVariance = minCaptureVarianceThreshold !== undefined && variance !== undefined && variance < minCaptureVarianceThreshold;
12057
+ faceVisibilityTooLow = !!(tooDark || tooLowRange || tooLowVariance);
12058
+ }
12059
+ if (face && !faceVisibilityTooLow) {
12060
+ // calculate frame centroids
12061
+ var frameCX = videoWidth / 2;
12062
+ var frameCY = videoHeight / 2;
12063
+ // calculate head bounding box, with forehead extension
12064
+ var foreheadSize = face.box.height * foreheadRatio;
12065
+ var headXMin = face.box.xMin;
12066
+ var headXMax = face.box.xMax;
12067
+ var headYMin = face.box.yMin - foreheadSize;
12068
+ var headYMax = face.box.yMax;
12069
+ // calculate head centroids
12070
+ var headCX = (headXMin + headXMax) / 2;
12071
+ var headCY = (headYMin + headYMax) / 2;
12072
+ // calculate thresholds
12073
+ var vTX = videoWidth * xBoundary;
12074
+ var vTY = videoHeight * yBoundary;
12075
+ var vCTX = videoWidth * xCentroidBoundary;
12076
+ var vCTY = videoHeight * yCentroidBoundary;
12077
+ var faceNotCenteredHorizontally = Math.abs(frameCX - headCX) > vCTX;
12078
+ var faceNotCenteredVertically = Math.abs(frameCY - headCY) > vCTY;
12079
+ var faceViolatesHorizontalBoundary = headXMin < vTX || headXMax > videoWidth - vTX;
12080
+ var faceViolatesVerticalBoundary = headYMin < vTY || headYMax > videoHeight - vTY;
12081
+ faceNotCentered = faceViolatesHorizontalBoundary || faceViolatesVerticalBoundary || faceNotCenteredHorizontally || requireVerticalFaceCentering && faceNotCenteredVertically;
12082
+ var isMobile = videoWidth < videoHeight;
12083
+ var tooCloseMultiple = 1.5;
12084
+ var tooFarMultiple = isMobile ? 6 : 7;
12085
+ faceTooClose = face.box.width > videoWidth / tooCloseMultiple;
12086
+ faceTooFar = face.box.width < videoWidth / tooFarMultiple;
12087
+ var nose = face.keypoints[2];
12088
+ var fTW = face.box.width * noseTrackingThreshold;
12089
+ var fTH = face.box.height * noseTrackingThreshold;
12090
+ faceLookingAway = !nose || Math.abs(headCX - nose.x) > fTW || Math.abs(headCY - nose.y) > fTH;
12091
+ }
12092
+ var faceInGuides = !faceNotDetected && !faceNotCentered && !faceLookingAway && !faceTooClose && !faceTooFar;
12093
+ if (lastFaceDetectionTime > 0) {
12094
+ trackFramesNeeded(500 / lastFaceDetectionTime);
12095
+ }
12096
+ var faceIsStable = false,
12097
+ noseIsStable = false;
12098
+ if (faceInGuides && !faceVisibilityTooLow) {
12099
+ var framesNeeded = Math.max(Math.ceil(average(framesNeededSamples)), 5);
12100
+ trackFace(face, framesNeeded, videoWidth, videoHeight);
12101
+ faceIsStable = lastNFaces.length >= framesNeeded && !lastNFacePairs.some(function (pair) {
12102
+ return pair.iou < stabilityThreshold;
12103
+ });
12104
+ noseIsStable = lastNNoses.length >= framesNeeded && !lastNNosePairs.some(function (pair) {
12105
+ return pair.distance > noseDistanceThreshold;
12106
+ });
12107
+ }
12108
+ var faceReady = faceInGuides && faceIsStable && noseIsStable && !faceVisibilityTooLow;
12109
+ return {
12110
+ face: face,
12111
+ faceNotDetected: faceNotDetected,
12112
+ faceNotCentered: faceNotCentered,
12113
+ faceLookingAway: faceLookingAway,
12114
+ faceTooClose: faceTooClose,
12115
+ faceTooFar: faceTooFar,
12116
+ faceReady: faceReady,
12117
+ faceReadyAt: faceReady ? new Date() : null,
12118
+ faceIsStable: faceIsStable,
12119
+ noseIsStable: noseIsStable,
12120
+ faceVisibilityTooLow: faceVisibilityTooLow
12121
+ };
12122
+ }
12123
+ function testFaceDetectionAgainstKnownImage(detector) {
12124
+ return new Promise(function (resolve, reject) {
12125
+ var img = new Image();
12126
+ img.crossOrigin = 'anonymous';
12127
+ img.onload = function () {
12128
+ var prediction = detector.detectForVideo(img, performance.now());
12129
+ if (prediction.detections.length > 0) {
12130
+ debug('face detection test result', prediction.detections);
12131
+ resolve(void 0);
12132
+ } else {
12133
+ warn('face detection test failed');
12134
+ reject(new Error('testFaceDetectionAgainstKnownImage failed to predict'));
12135
+ }
12136
+ };
12137
+ img.onerror = function () {
12138
+ return reject(new Error('testFaceDetectionAgainstKnownImage failed to load image'));
12139
+ };
12140
+ img.src = "".concat(DEFAULT_CDN_URL, "/head-test.jpg");
12141
+ });
11635
12142
  }
11636
- var templateObject_1$o, templateObject_2$m, templateObject_3$g;
11637
-
11638
- var FaceCaptureGuideContainer = styled.div(templateObject_1$n || (templateObject_1$n = __makeTemplateObject(["\n position: absolute;\n z-index: 1000;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n box-sizing: border-box;\n"], ["\n position: absolute;\n z-index: 1000;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n box-sizing: border-box;\n"])));
11639
- var FaceCaptureGuideInner = styled.div(templateObject_2$l || (templateObject_2$l = __makeTemplateObject(["\n position: relative;\n height: 60%;\n"], ["\n position: relative;\n height: 60%;\n"])));
11640
- var FaceCaptureGuideOverlay = function FaceCaptureGuideOverlay(_a) {
11641
- var _b = _a.classNames,
11642
- classNames = _b === void 0 ? {} : _b,
11643
- _c = _a.status,
11644
- status = _c === void 0 ? 'ready' : _c,
11645
- _d = _a.borderWidth,
11646
- borderWidth = _d === void 0 ? 5 : _d,
11647
- _e = _a.borderColor,
11648
- borderColor = _e === void 0 ? 'white' : _e,
11649
- _f = _a.borderOpacity,
11650
- borderOpacity = _f === void 0 ? 0.8 : _f;
11651
- return /*#__PURE__*/React__default.createElement(FaceCaptureGuideContainer, {
11652
- className: classNames.container
11653
- }, /*#__PURE__*/React__default.createElement(FaceCaptureGuideInner, null, /*#__PURE__*/React__default.createElement(SelfieCaptureAnimatedMaskWithStatus, {
11654
- status: status,
11655
- borderColor: borderColor,
11656
- borderWidth: borderWidth,
11657
- borderOpacity: borderOpacity,
11658
- verticalAlign: "center"
11659
- })));
11660
- };
11661
- var templateObject_1$n, templateObject_2$l;
11662
12143
 
11663
12144
  function detectBrightnessAndContrast(frame, brightnessAverager) {
11664
12145
  var ctx = frame.getContext('2d');
@@ -12952,7 +13433,7 @@ var SelfieCaptureLoadingOverlayDefault = function SelfieCaptureLoadingOverlayDef
12952
13433
  });
12953
13434
  }, 3000);
12954
13435
  }, []);
12955
- var timeSinceWarmingStarted = modelWarmingStartedAt ? new Date().getTime() - modelWarmingStartedAt : 0;
13436
+ var timeSinceWarmingStarted = modelWarmingStartedAt ? performance.now() - modelWarmingStartedAt : 0;
12956
13437
  var warmingProgress = timeSinceWarmingStarted / 5000.0;
12957
13438
  var _o = useState(false),
12958
13439
  overrideModelsReady = _o[0],