idmission-web-sdk 2.3.92 → 2.3.94

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.
@@ -17,6 +17,7 @@ var middleware = require('zustand/middleware');
17
17
  var shallow = require('zustand/react/shallow');
18
18
  var cn = require('clsx');
19
19
  var SignatureCanvas = require('react-signature-canvas');
20
+ var mediaInfoFactory = require('mediainfo.js');
20
21
  var server = require('react-dom/server');
21
22
 
22
23
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
@@ -48,6 +49,7 @@ var LanguageDetector__default = /*#__PURE__*/_interopDefaultCompat(LanguageDetec
48
49
  var i18n__default = /*#__PURE__*/_interopDefaultCompat(i18n);
49
50
  var cn__default = /*#__PURE__*/_interopDefaultCompat(cn);
50
51
  var SignatureCanvas__default = /*#__PURE__*/_interopDefaultCompat(SignatureCanvas);
52
+ var mediaInfoFactory__default = /*#__PURE__*/_interopDefaultCompat(mediaInfoFactory);
51
53
 
52
54
  /******************************************************************************
53
55
  Copyright (c) Microsoft Corporation.
@@ -236,7 +238,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
236
238
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
237
239
  };
238
240
 
239
- var webSdkVersion = '2.3.92';
241
+ var webSdkVersion = '2.3.94';
240
242
 
241
243
  function getPlatform() {
242
244
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -1184,10 +1186,7 @@ var SubmissionContext = /*#__PURE__*/React.createContext({
1184
1186
  setIdCaptureVideoUrl: function setIdCaptureVideoUrl() {
1185
1187
  return null;
1186
1188
  },
1187
- setSignatureStartTimestamp: function setSignatureStartTimestamp() {
1188
- return null;
1189
- },
1190
- setSignatureEndTimestamp: function setSignatureEndTimestamp() {
1189
+ setSignatureVideoMetadata: function setSignatureVideoMetadata() {
1191
1190
  return null;
1192
1191
  },
1193
1192
  setIdCaptureVideoIdFrontImage: function setIdCaptureVideoIdFrontImage() {
@@ -1357,50 +1356,47 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1357
1356
  signatureVideoUrl = _17[0],
1358
1357
  setSignatureVideoUrl = _17[1];
1359
1358
  var _18 = React.useState(null),
1360
- signatureStartTimestamp = _18[0],
1361
- setSignatureStartTimestamp = _18[1];
1359
+ signatureVideoMetadata = _18[0],
1360
+ setSignatureVideoMetadata = _18[1];
1362
1361
  var _19 = React.useState(null),
1363
- signatureEndTimestamp = _19[0],
1364
- setSignatureEndTimestamp = _19[1];
1362
+ idCaptureVideoUrl = _19[0],
1363
+ setIdCaptureVideoUrl = _19[1];
1365
1364
  var _20 = React.useState(null),
1366
- idCaptureVideoUrl = _20[0],
1367
- setIdCaptureVideoUrl = _20[1];
1365
+ idCaptureVideoIdFrontImage = _20[0],
1366
+ setIdCaptureVideoIdFrontImage = _20[1];
1368
1367
  var _21 = React.useState(null),
1369
- idCaptureVideoIdFrontImage = _21[0],
1370
- setIdCaptureVideoIdFrontImage = _21[1];
1368
+ idCaptureVideoIdBackImage = _21[0],
1369
+ setIdCaptureVideoIdBackImage = _21[1];
1371
1370
  var _22 = React.useState(null),
1372
- idCaptureVideoIdBackImage = _22[0],
1373
- setIdCaptureVideoIdBackImage = _22[1];
1371
+ idCaptureVideoAudioUrl = _22[0],
1372
+ setIdCaptureVideoAudioUrl = _22[1];
1374
1373
  var _23 = React.useState(null),
1375
- idCaptureVideoAudioUrl = _23[0],
1376
- setIdCaptureVideoAudioUrl = _23[1];
1374
+ idCaptureVideoAudioStartsAt = _23[0],
1375
+ setIdCaptureVideoAudioStartsAt = _23[1];
1377
1376
  var _24 = React.useState(null),
1378
- idCaptureVideoAudioStartsAt = _24[0],
1379
- setIdCaptureVideoAudioStartsAt = _24[1];
1377
+ expectedAudioText = _24[0],
1378
+ setExpectedAudioText = _24[1];
1380
1379
  var _25 = React.useState(null),
1381
- expectedAudioText = _25[0],
1382
- setExpectedAudioText = _25[1];
1380
+ additionalDocuments = _25[0],
1381
+ setAdditionalDocuments = _25[1];
1383
1382
  var _26 = React.useState(null),
1384
- additionalDocuments = _26[0],
1385
- setAdditionalDocuments = _26[1];
1386
- var _27 = React.useState(null),
1387
- geolocationResult = _27[0],
1388
- setGeolocationResult = _27[1];
1389
- var _28 = React.useState(0),
1390
- geolocationAttempts = _28[0],
1391
- setGeolocationAttempts = _28[1];
1392
- var _29 = React.useState(false),
1393
- geolocationBlocked = _29[0],
1394
- setGeolocationBlocked = _29[1];
1383
+ geolocationResult = _26[0],
1384
+ setGeolocationResult = _26[1];
1385
+ var _27 = React.useState(0),
1386
+ geolocationAttempts = _27[0],
1387
+ setGeolocationAttempts = _27[1];
1388
+ var _28 = React.useState(false),
1389
+ geolocationBlocked = _28[0],
1390
+ setGeolocationBlocked = _28[1];
1391
+ var _29 = React.useState([]),
1392
+ idFrontCaptureAttempts = _29[0],
1393
+ setIdFrontCaptureAttempts = _29[1];
1395
1394
  var _30 = React.useState([]),
1396
- idFrontCaptureAttempts = _30[0],
1397
- setIdFrontCaptureAttempts = _30[1];
1395
+ idBackCaptureAttempts = _30[0],
1396
+ setIdBackCaptureAttempts = _30[1];
1398
1397
  var _31 = React.useState([]),
1399
- idBackCaptureAttempts = _31[0],
1400
- setIdBackCaptureAttempts = _31[1];
1401
- var _32 = React.useState([]),
1402
- selfieCaptureAttempts = _32[0],
1403
- setSelfieCaptureAttempts = _32[1];
1398
+ selfieCaptureAttempts = _31[0],
1399
+ setSelfieCaptureAttempts = _31[1];
1404
1400
  var logIdFrontCaptureAttempt = React.useCallback(function (attempt) {
1405
1401
  setIdFrontCaptureAttempts(function (attempts) {
1406
1402
  return __spreadArray(__spreadArray([], attempts, true), [attempt], false);
@@ -1497,19 +1493,22 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1497
1493
  var buildSubmissionPayload = React.useCallback(function () {
1498
1494
  return __awaiter(void 0, void 0, void 0, function () {
1499
1495
  function uploadIfPossible(src_1, filename_1) {
1500
- return __awaiter(this, arguments, void 0, function (src, filename, filetype) {
1496
+ return __awaiter(this, arguments, void 0, function (src, filename, filetype, metadata) {
1501
1497
  if (filetype === void 0) {
1502
1498
  filetype = 'image/jpeg';
1503
1499
  }
1500
+ if (metadata === void 0) {
1501
+ metadata = {};
1502
+ }
1504
1503
  return __generator(this, function (_a) {
1505
1504
  switch (_a.label) {
1506
1505
  case 0:
1507
1506
  if (!documentServiceUrl) return [2 /*return*/, src];
1508
1507
  if (!src.startsWith('data:')) src = "data:".concat(filetype, ";base64,").concat(src);
1509
- return [4 /*yield*/, uploadDocument(src, {
1508
+ return [4 /*yield*/, uploadDocument(src, _assign({
1510
1509
  filename: filename,
1511
1510
  filetype: filetype
1512
- })];
1511
+ }, metadata))];
1513
1512
  case 1:
1514
1513
  return [2 /*return*/, _a.sent()];
1515
1514
  }
@@ -1518,9 +1517,9 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1518
1517
  }
1519
1518
  var documents, _a, _b, _c, submissionRequest, onBeforeSubmitResult;
1520
1519
  var _d;
1521
- var _e, _f, _g, _h;
1522
- return __generator(this, function (_j) {
1523
- switch (_j.label) {
1520
+ var _e, _f, _g, _h, _j;
1521
+ return __generator(this, function (_k) {
1522
+ switch (_k.label) {
1524
1523
  case 0:
1525
1524
  _d = {
1526
1525
  idFrontImage: idFrontImage,
@@ -1533,24 +1532,24 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1533
1532
  if (!_a) return [3 /*break*/, 2];
1534
1533
  return [4 /*yield*/, videoDataUrlToB64(signatureVideoUrl)];
1535
1534
  case 1:
1536
- _a = _j.sent();
1537
- _j.label = 2;
1535
+ _a = _k.sent();
1536
+ _k.label = 2;
1538
1537
  case 2:
1539
1538
  _d.signatureVideo = _a;
1540
1539
  _b = idCaptureVideoUrl;
1541
1540
  if (!_b) return [3 /*break*/, 4];
1542
1541
  return [4 /*yield*/, videoDataUrlToB64(idCaptureVideoUrl)];
1543
1542
  case 3:
1544
- _b = _j.sent();
1545
- _j.label = 4;
1543
+ _b = _k.sent();
1544
+ _k.label = 4;
1546
1545
  case 4:
1547
1546
  _d.idCaptureVideo = _b;
1548
1547
  _c = idCaptureVideoAudioUrl;
1549
1548
  if (!_c) return [3 /*break*/, 6];
1550
1549
  return [4 /*yield*/, videoDataUrlToB64(idCaptureVideoAudioUrl)];
1551
1550
  case 5:
1552
- _c = _j.sent();
1553
- _j.label = 6;
1551
+ _c = _k.sent();
1552
+ _k.label = 6;
1554
1553
  case 6:
1555
1554
  documents = (_d.idCaptureVideoAudio = _c, _d.idCaptureVideoIdFrontImage = idCaptureVideoIdFrontImage, _d.idCaptureVideoIdBackImage = idCaptureVideoIdBackImage, _d.idFrontIrImage = idFrontIrImage, _d.idBackIrImage = idBackIrImage, _d.idFrontUvImage = idFrontUvImage, _d.idBackUvImage = idBackUvImage, _d);
1556
1555
  if (signatureData) {
@@ -1559,15 +1558,18 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1559
1558
  if (!documentServiceUrl) return [3 /*break*/, 8];
1560
1559
  return [4 /*yield*/, Promise.all(Object.keys(documents).map(function (k) {
1561
1560
  return __awaiter(void 0, void 0, void 0, function () {
1562
- var filetype, _a, _b;
1561
+ var filetype, metadata, _a, _b;
1563
1562
  return __generator(this, function (_c) {
1564
1563
  switch (_c.label) {
1565
1564
  case 0:
1566
1565
  if (!documents[k]) return [3 /*break*/, 2];
1567
1566
  filetype = k.endsWith('Video') ? 'video/mp4' : k.endsWith('Audio') ? 'audio/mp4' : 'image/jpeg';
1567
+ metadata = k === 'signatureVideo' ? {
1568
+ filemetadata: JSON.stringify(signatureVideoMetadata)
1569
+ } : {};
1568
1570
  _a = documents;
1569
1571
  _b = k;
1570
- return [4 /*yield*/, uploadIfPossible(documents[k], k, filetype)];
1572
+ return [4 /*yield*/, uploadIfPossible(documents[k], k, filetype, metadata)];
1571
1573
  case 1:
1572
1574
  _a[_b] = _c.sent();
1573
1575
  _c.label = 2;
@@ -1580,8 +1582,8 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1580
1582
  throw new NetworkError(e.message);
1581
1583
  })];
1582
1584
  case 7:
1583
- _j.sent();
1584
- _j.label = 8;
1585
+ _k.sent();
1586
+ _k.label = 8;
1585
1587
  case 8:
1586
1588
  submissionRequest = {
1587
1589
  securityData: {
@@ -1681,11 +1683,9 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1681
1683
  submissionRequest.customerData.signatureData.signatureVideo = documents.signatureVideo;
1682
1684
  }
1683
1685
  }
1684
- if (signatureStartTimestamp) {
1685
- submissionRequest.customerData.signatureStartTimestamp = signatureStartTimestamp;
1686
- }
1687
- if (signatureEndTimestamp) {
1688
- submissionRequest.customerData.signatureEndTimestamp = signatureEndTimestamp;
1686
+ if (signatureVideoMetadata) {
1687
+ (_g = submissionRequest.customerData).signatureData || (_g.signatureData = {});
1688
+ submissionRequest.customerData.signatureData.signatureVideoMetadata = signatureVideoMetadata;
1689
1689
  }
1690
1690
  if (additionalDocuments) {
1691
1691
  submissionRequest.customerData.additionalDocuments = additionalDocuments.map(function (d) {
@@ -1697,11 +1697,11 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1697
1697
  });
1698
1698
  }
1699
1699
  if (documents.idCaptureVideo) {
1700
- (_g = submissionRequest.customerData).biometricData || (_g.biometricData = {});
1700
+ (_h = submissionRequest.customerData).biometricData || (_h.biometricData = {});
1701
1701
  submissionRequest.customerData.biometricData.videoData = documents.idCaptureVideo;
1702
1702
  }
1703
1703
  if (documents.idCaptureVideoAudio) {
1704
- (_h = submissionRequest.customerData).biometricData || (_h.biometricData = {});
1704
+ (_j = submissionRequest.customerData).biometricData || (_j.biometricData = {});
1705
1705
  submissionRequest.customerData.biometricData.voiceData = documents.idCaptureVideoAudio;
1706
1706
  submissionRequest.customerData.biometricData.voiceStartTime = idCaptureVideoAudioStartsAt !== null && idCaptureVideoAudioStartsAt !== void 0 ? idCaptureVideoAudioStartsAt : undefined;
1707
1707
  submissionRequest.customerData.biometricData.expectedAudioText = expectedAudioText !== null && expectedAudioText !== void 0 ? expectedAudioText : undefined;
@@ -1721,15 +1721,15 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1721
1721
  if (!onBeforeSubmit.current) return [3 /*break*/, 10];
1722
1722
  return [4 /*yield*/, onBeforeSubmit.current(submissionRequest)];
1723
1723
  case 9:
1724
- onBeforeSubmitResult = _j.sent();
1724
+ onBeforeSubmitResult = _k.sent();
1725
1725
  if (onBeforeSubmitResult) submissionRequest = onBeforeSubmitResult;
1726
- _j.label = 10;
1726
+ _k.label = 10;
1727
1727
  case 10:
1728
1728
  return [2 /*return*/, submissionRequest];
1729
1729
  }
1730
1730
  });
1731
1731
  });
1732
- }, [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]);
1732
+ }, [additionalDocuments, bypassAgeValidation, bypassNameMatching, cardData, clientRequestID, companyId, customerDataMatchConfig, deduplicationEnabled, deduplicationSynchronous, documentServiceUrl, enrollmentId, expectedAudioText, geolocationResult, idBackCaptureAttempts, idBackImage, idBackImageRequired, idBackIrImage, idBackUvImage, idBarcodeImage, idCaptureVideoAudioStartsAt, idCaptureVideoAudioUrl, idCaptureVideoIdBackImage, idCaptureVideoIdFrontImage, idCaptureVideoUrl, idCardForFaceMatch, idData, idFrontCaptureAttempts, idFrontImage, idFrontIrImage, idFrontUvImage, idImageResolutionCheck, jobId, manualReviewRequired, needImmediateResponse, passportImage, personalData, selfieCaptureAttempts, selfieImage, signatureData, signatureVideoUrl, signatureVideoMetadata, uploadDocument, verifyIdWithExternalDatabases, webhooksClientTraceId, webhooksEnabled, webhooksFireOnReview, webhooksFireOnReviewURL, webhooksSendInputImages, webhooksSendProcessedImages, webhooksStripSpecialCharacters, webhooksURL]);
1733
1733
  var defaultOnSubmit = React.useCallback(function () {
1734
1734
  return __awaiter(void 0, void 0, void 0, function () {
1735
1735
  var submissionResponse_1, payload, host, endpoint, response, statusMessage, submissionResponse_2, e_1, err;
@@ -2028,8 +2028,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
2028
2028
  setSelfieImage: setSelfieImage,
2029
2029
  setSignatureData: setSignatureData,
2030
2030
  setSignatureVideoUrl: setSignatureVideoUrl,
2031
- setSignatureStartTimestamp: setSignatureStartTimestamp,
2032
- setSignatureEndTimestamp: setSignatureEndTimestamp,
2031
+ setSignatureVideoMetadata: setSignatureVideoMetadata,
2033
2032
  setIdCaptureVideoUrl: setIdCaptureVideoUrl,
2034
2033
  setIdCaptureVideoIdFrontImage: setIdCaptureVideoIdFrontImage,
2035
2034
  setIdCaptureVideoIdBackImage: setIdCaptureVideoIdBackImage,
@@ -14329,194 +14328,23 @@ function inferBlobType(blobPart) {
14329
14328
  return t.length > 0 ? t : undefined;
14330
14329
  }
14331
14330
 
14332
- var videoRecorder = null;
14333
- var audioRecorder = null;
14334
- var videoChunks = [];
14335
- var audioChunks = [];
14336
- function setVideoRecorder(recorder) {
14337
- videoRecorder = recorder;
14338
- }
14339
- function setAudioRecorder(recorder) {
14340
- audioRecorder = recorder;
14341
- }
14342
- function clearVideoChunks() {
14343
- videoChunks = [];
14344
- }
14345
- function clearAudioChunks() {
14346
- audioChunks = [];
14347
- }
14348
- var initialState$2 = {
14349
- videoUrl: null,
14350
- audioUrl: null,
14351
- isRecordingVideo: false,
14352
- isRecordingAudio: false,
14353
- videoRecordingStopped: false,
14354
- audioRecordingStopped: false,
14355
- videoRecordingIntentionallyStopped: false,
14356
- audioRecordingIntentionallyStopped: false,
14357
- mergeAVStreams: false
14358
- };
14359
- var useVideoRecorderStore = zustand.create()(middleware.devtools(function (set, get) {
14360
- return _assign(_assign({}, initialState$2), {
14361
- startRecordingVideo: function startRecordingVideo(captureAudio) {
14362
- var _a, _b, _c;
14363
- if (captureAudio === void 0) {
14364
- captureAudio = false;
14365
- }
14366
- if (!camera) throw new Error('Camera not found');
14367
- var _d = get(),
14368
- mergeAVStreams = _d.mergeAVStreams,
14369
- startRecordingAudio = _d.startRecordingAudio;
14370
- var videoStream = mergeAVStreams ? new MediaStream(__spreadArray(__spreadArray([], (_b = (_a = camera === null || camera === void 0 ? void 0 : camera.stream) === null || _a === void 0 ? void 0 : _a.getTracks()) !== null && _b !== void 0 ? _b : [], true), captureAudio ? (_c = audioStream === null || audioStream === void 0 ? void 0 : audioStream.getTracks()) !== null && _c !== void 0 ? _c : [] : [], true)) : camera.stream;
14371
- if (!videoStream) return;
14372
- clearVideoChunks();
14373
- videoRecorder = null;
14374
- set({
14375
- isRecordingVideo: true,
14376
- videoRecordingStopped: false,
14377
- videoRecordingIntentionallyStopped: false
14378
- });
14379
- videoRecorder = new MediaRecorder(videoStream, {
14380
- videoBitsPerSecond: 270000,
14381
- audioBitsPerSecond: 32000
14382
- });
14383
- videoRecorder.ondataavailable = function (e) {
14384
- videoChunks.push(e.data);
14385
- };
14386
- videoRecorder.onstop = function () {
14387
- set({
14388
- videoRecordingStopped: true
14389
- });
14390
- };
14391
- videoRecorder.start(100);
14392
- setTimeout(function () {
14393
- if (!videoRecorder || videoRecorder.state === 'inactive') {
14394
- log('media recorder is inactive!');
14395
- // TODO: figure out what to do here
14331
+ function makeReadChunk(file) {
14332
+ var _this = this;
14333
+ return function (chunkSize, offset) {
14334
+ return __awaiter(_this, void 0, void 0, function () {
14335
+ var _a;
14336
+ return __generator(this, function (_b) {
14337
+ switch (_b.label) {
14338
+ case 0:
14339
+ _a = Uint8Array.bind;
14340
+ return [4 /*yield*/, file.slice(offset, offset + chunkSize).arrayBuffer()];
14341
+ case 1:
14342
+ return [2 /*return*/, new (_a.apply(Uint8Array, [void 0, _b.sent()]))()];
14396
14343
  }
14397
- }, 100);
14398
- if (captureAudio && !mergeAVStreams) {
14399
- startRecordingAudio();
14400
- }
14401
- },
14402
- stopRecordingVideo: function stopRecordingVideo() {
14403
- set({
14404
- videoRecordingIntentionallyStopped: true
14405
14344
  });
14406
- if ((videoRecorder === null || videoRecorder === void 0 ? void 0 : videoRecorder.state) !== 'inactive') {
14407
- videoRecorder === null || videoRecorder === void 0 ? void 0 : videoRecorder.stop(); // if you call this while state === 'inactive', an exception is thrown.
14408
- }
14409
- },
14410
- startRecordingAudio: function startRecordingAudio() {
14411
- if (get().mergeAVStreams) return;
14412
- if (!audioStream) return;
14413
- clearAudioChunks();
14414
- set({
14415
- isRecordingAudio: true,
14416
- audioRecordingStopped: false,
14417
- audioRecordingIntentionallyStopped: false
14418
- });
14419
- var audioRecorder = new MediaRecorder(audioStream, {
14420
- audioBitsPerSecond: 32000
14421
- });
14422
- setAudioRecorder(audioRecorder);
14423
- audioRecorder.ondataavailable = function (e) {
14424
- audioChunks.push(e.data);
14425
- };
14426
- audioRecorder.onstop = function () {
14427
- set({
14428
- audioRecordingStopped: true
14429
- });
14430
- };
14431
- audioRecorder.start(100);
14432
- },
14433
- stopRecordingAudio: function stopRecordingAudio() {
14434
- set({
14435
- audioRecordingIntentionallyStopped: true
14436
- });
14437
- if ((audioRecorder === null || audioRecorder === void 0 ? void 0 : audioRecorder.state) !== 'inactive') {
14438
- audioRecorder === null || audioRecorder === void 0 ? void 0 : audioRecorder.stop(); // if you call this while state === 'inactive', an exception is thrown.
14439
- }
14440
- },
14441
- stopRecording: function stopRecording() {
14442
- get().stopRecordingVideo();
14443
- get().stopRecordingAudio();
14444
- },
14445
- clearRecordedData: function clearRecordedData() {
14446
- clearVideoChunks();
14447
- clearAudioChunks();
14448
- }
14449
- });
14450
- }));
14451
- var useVideoRecorder = function useVideoRecorder(mergeAVStreams) {
14452
- if (mergeAVStreams === void 0) {
14453
- mergeAVStreams = false;
14454
- }
14455
- React.useEffect(function () {
14456
- return useVideoRecorderStore.setState({
14457
- mergeAVStreams: mergeAVStreams
14458
- });
14459
- }, [mergeAVStreams]);
14460
- React.useEffect(function () {
14461
- // clear recorded data when the component is mounted
14462
- useVideoRecorderStore.getState().clearRecordedData();
14463
- }, []);
14464
- var processVideo = React.useCallback(function () {
14465
- var inferredType = inferBlobType(videoChunks[0]) || (videoRecorder === null || videoRecorder === void 0 ? void 0 : videoRecorder.mimeType) || 'video/mp4';
14466
- var videoBlob = new Blob(videoChunks, {
14467
- type: inferredType
14468
- });
14469
- useVideoRecorderStore.setState({
14470
- videoUrl: URL.createObjectURL(videoBlob),
14471
- isRecordingVideo: false
14472
14345
  });
14473
- clearVideoChunks();
14474
- setVideoRecorder(null);
14475
- }, []);
14476
- var processAudio = React.useCallback(function () {
14477
- var inferredType = inferBlobType(audioChunks[0]) || (audioRecorder === null || audioRecorder === void 0 ? void 0 : audioRecorder.mimeType) || 'audio/mp4';
14478
- var audioBlob = new Blob(audioChunks, {
14479
- type: inferredType
14480
- });
14481
- useVideoRecorderStore.setState({
14482
- audioUrl: URL.createObjectURL(audioBlob),
14483
- isRecordingAudio: false
14484
- });
14485
- clearAudioChunks();
14486
- setAudioRecorder(null);
14487
- }, []);
14488
- var _a = useVideoRecorderStore(),
14489
- videoUrl = _a.videoUrl,
14490
- audioUrl = _a.audioUrl,
14491
- isRecordingVideo = _a.isRecordingVideo,
14492
- isRecordingAudio = _a.isRecordingAudio,
14493
- videoRecordingStopped = _a.videoRecordingStopped,
14494
- videoRecordingIntentionallyStopped = _a.videoRecordingIntentionallyStopped,
14495
- audioRecordingStopped = _a.audioRecordingStopped,
14496
- audioRecordingIntentionallyStopped = _a.audioRecordingIntentionallyStopped;
14497
- React.useEffect(function () {
14498
- if (videoRecordingStopped && videoRecordingIntentionallyStopped) {
14499
- processVideo();
14500
- }
14501
- }, [processVideo, videoRecordingIntentionallyStopped, videoRecordingStopped]);
14502
- React.useEffect(function () {
14503
- if (audioRecordingStopped && audioRecordingIntentionallyStopped) {
14504
- processAudio();
14505
- }
14506
- }, [audioRecordingIntentionallyStopped, audioRecordingStopped, processAudio]);
14507
- return React.useMemo(function () {
14508
- return {
14509
- isRecordingVideo: isRecordingVideo,
14510
- isRecordingAudio: isRecordingAudio,
14511
- videoRecordingUnintentionallyStopped: videoRecordingStopped && !videoRecordingIntentionallyStopped,
14512
- audioRecordingUnintentionallyStopped: audioRecordingStopped && !audioRecordingIntentionallyStopped,
14513
- videoUrl: videoUrl,
14514
- audioUrl: audioUrl
14515
- };
14516
- }, [audioRecordingIntentionallyStopped, audioRecordingStopped, audioUrl, isRecordingAudio, isRecordingVideo, videoRecordingIntentionallyStopped, videoRecordingStopped, videoUrl]);
14517
- };
14518
-
14519
- var RECORDING_TIMESTAMP_PADDING_MS = 1000;
14346
+ };
14347
+ }
14520
14348
  var signatureRecorder = null;
14521
14349
  var signatureChunks = [];
14522
14350
  var videoSignatureInitialState = {
@@ -14544,27 +14372,31 @@ var videoSignatureInitialState = {
14544
14372
  var useVideoSignatureStore = zustand.create()(middleware.devtools(function (set, get) {
14545
14373
  return _assign(_assign({}, videoSignatureInitialState), {
14546
14374
  startRecording: function startRecording(captureAudio) {
14547
- var _a;
14375
+ var _a, _b;
14548
14376
  if (captureAudio === void 0) {
14549
14377
  captureAudio = false;
14550
14378
  }
14551
14379
  if (!camera) throw new Error('Camera not found');
14552
14380
  // set our flag and clear whatever we have recorded so far.
14553
- set({
14554
- recordingStartedAt: performance.now()
14555
- });
14556
14381
  signatureChunks = [];
14557
- // start recording video and audio
14558
- useVideoRecorderStore.getState().startRecordingVideo(captureAudio);
14382
+ var outputCanvas = get().outputCanvas;
14559
14383
  // start recording from the output canvas to capture the signature
14560
- var videoStream = get().outputCanvas.current.captureStream(24); // fps
14561
- var tracks = [videoStream.getVideoTracks()[0]];
14562
- var audioTrack = (_a = audioStream === null || audioStream === void 0 ? void 0 : audioStream.getAudioTracks()) === null || _a === void 0 ? void 0 : _a[0];
14563
- if (audioTrack) tracks.push(audioTrack);
14384
+ var outputStream = (_a = outputCanvas.current) === null || _a === void 0 ? void 0 : _a.captureStream(24);
14385
+ if (!outputStream) throw new Error('outputStream not found');
14386
+ var tracks = [outputStream.getVideoTracks()[0]];
14387
+ if (captureAudio) {
14388
+ var audioTrack = (_b = audioStream === null || audioStream === void 0 ? void 0 : audioStream.getAudioTracks()) === null || _b === void 0 ? void 0 : _b[0];
14389
+ if (audioTrack) tracks.push(audioTrack);
14390
+ }
14564
14391
  signatureRecorder = new MediaRecorder(new MediaStream(tracks), {
14565
- videoBitsPerSecond: 270000,
14392
+ videoBitsPerSecond: 650000,
14566
14393
  audioBitsPerSecond: 32000
14567
14394
  });
14395
+ signatureRecorder.onstart = function () {
14396
+ set({
14397
+ recordingStartedAt: performance.now()
14398
+ });
14399
+ };
14568
14400
  var hasFirstChunk = false;
14569
14401
  signatureRecorder.ondataavailable = function (event) {
14570
14402
  signatureChunks.push(event.data);
@@ -14583,39 +14415,101 @@ var useVideoSignatureStore = zustand.create()(middleware.devtools(function (set,
14583
14415
  signatureRecorder.start(100);
14584
14416
  },
14585
14417
  stopRecording: function stopRecording(signatureData, imageUrl) {
14586
- set({
14587
- firstChunkReceivedAt: undefined,
14588
- recordingStoppedAt: performance.now()
14589
- });
14590
14418
  waitForOneMoreChunk().then(function () {
14591
14419
  if (!signatureRecorder) return;
14592
14420
  signatureRecorder.stop();
14593
14421
  signatureRecorder.onstop = function () {
14594
- var inferredType = inferBlobType(signatureChunks[0]) || (signatureRecorder === null || signatureRecorder === void 0 ? void 0 : signatureRecorder.mimeType) || 'video/mp4';
14595
- var blob = new Blob(signatureChunks, {
14596
- type: inferredType
14422
+ return __awaiter(void 0, void 0, void 0, function () {
14423
+ var recordingStoppedAt, inferredType, blob, _a, onSignatureVideoCaptured, recordingStartedAt, firstChunkReceivedAt, signatureStartedAt, signatureEndedAt, lastChunkReceivedAt, mediaInfo;
14424
+ var _b;
14425
+ return __generator(this, function (_c) {
14426
+ switch (_c.label) {
14427
+ case 0:
14428
+ recordingStoppedAt = performance.now();
14429
+ set({
14430
+ recordingStoppedAt: recordingStoppedAt
14431
+ });
14432
+ inferredType = inferBlobType(signatureChunks[0]) || (signatureRecorder === null || signatureRecorder === void 0 ? void 0 : signatureRecorder.mimeType) || 'video/mp4';
14433
+ blob = new Blob(signatureChunks, {
14434
+ type: inferredType
14435
+ });
14436
+ signatureChunks = [];
14437
+ signatureRecorder = null;
14438
+ if (!signatureData) return [2 /*return*/];
14439
+ _a = get(), onSignatureVideoCaptured = _a.onSignatureVideoCaptured, recordingStartedAt = _a.recordingStartedAt, firstChunkReceivedAt = _a.firstChunkReceivedAt, signatureStartedAt = _a.signatureStartedAt, signatureEndedAt = _a.signatureEndedAt, lastChunkReceivedAt = _a.lastChunkReceivedAt;
14440
+ return [4 /*yield*/, (_b = get().mediaInfo) === null || _b === void 0 ? void 0 : _b.analyzeData(blob.size, makeReadChunk(blob))
14441
+ // const endMs = Math.min(
14442
+ // signatureEndedAt ?? Infinity,
14443
+ // lastChunkReceivedAt ?? Infinity,
14444
+ // )
14445
+ // const signatureStartTimestamp =
14446
+ // signatureStartedAt && recordingStartedAt
14447
+ // ? formatTimestamp(
14448
+ // Math.max(
14449
+ // 0,
14450
+ // signatureStartedAt -
14451
+ // recordingStartedAt -
14452
+ // RECORDING_TIMESTAMP_PADDING_MS,
14453
+ // ),
14454
+ // )
14455
+ // : undefined
14456
+ // const signatureEndTimestamp =
14457
+ // endMs !== Infinity && recordingStartedAt
14458
+ // ? formatTimestamp(
14459
+ // Math.min(
14460
+ // endMs - recordingStartedAt + RECORDING_TIMESTAMP_PADDING_MS,
14461
+ // lastChunkReceivedAt ?? Infinity,
14462
+ // ),
14463
+ // )
14464
+ // : undefined
14465
+ ];
14466
+ case 1:
14467
+ mediaInfo = _c.sent();
14468
+ // const endMs = Math.min(
14469
+ // signatureEndedAt ?? Infinity,
14470
+ // lastChunkReceivedAt ?? Infinity,
14471
+ // )
14472
+ // const signatureStartTimestamp =
14473
+ // signatureStartedAt && recordingStartedAt
14474
+ // ? formatTimestamp(
14475
+ // Math.max(
14476
+ // 0,
14477
+ // signatureStartedAt -
14478
+ // recordingStartedAt -
14479
+ // RECORDING_TIMESTAMP_PADDING_MS,
14480
+ // ),
14481
+ // )
14482
+ // : undefined
14483
+ // const signatureEndTimestamp =
14484
+ // endMs !== Infinity && recordingStartedAt
14485
+ // ? formatTimestamp(
14486
+ // Math.min(
14487
+ // endMs - recordingStartedAt + RECORDING_TIMESTAMP_PADDING_MS,
14488
+ // lastChunkReceivedAt ?? Infinity,
14489
+ // ),
14490
+ // )
14491
+ // : undefined
14492
+ onSignatureVideoCaptured(blob, signatureData, imageUrl !== null && imageUrl !== void 0 ? imageUrl : null, {
14493
+ mediaInfo: mediaInfo,
14494
+ mimeType: inferredType,
14495
+ timingData: {
14496
+ recordingStartedAt: recordingStartedAt,
14497
+ firstChunkReceivedAt: firstChunkReceivedAt,
14498
+ signatureStartedAt: signatureStartedAt,
14499
+ signatureEndedAt: signatureEndedAt,
14500
+ recordingStoppedAt: recordingStoppedAt,
14501
+ lastChunkReceivedAt: lastChunkReceivedAt
14502
+ }
14503
+ });
14504
+ return [2 /*return*/];
14505
+ }
14506
+ });
14597
14507
  });
14598
- signatureChunks = [];
14599
- signatureRecorder = null;
14600
- if (!signatureData) return;
14601
- var _a = get(),
14602
- onSignatureVideoCaptured = _a.onSignatureVideoCaptured,
14603
- recordingStartedAt = _a.recordingStartedAt,
14604
- signatureStartedAt = _a.signatureStartedAt,
14605
- signatureEndedAt = _a.signatureEndedAt,
14606
- lastChunkReceivedAt = _a.lastChunkReceivedAt;
14607
- var endMs = Math.min(signatureEndedAt !== null && signatureEndedAt !== void 0 ? signatureEndedAt : Infinity, lastChunkReceivedAt !== null && lastChunkReceivedAt !== void 0 ? lastChunkReceivedAt : Infinity);
14608
- var signatureStartTimestamp = signatureStartedAt && recordingStartedAt ? formatTimestamp(Math.max(0, signatureStartedAt - recordingStartedAt - RECORDING_TIMESTAMP_PADDING_MS)) : undefined;
14609
- var signatureEndTimestamp = endMs !== Infinity && recordingStartedAt ? formatTimestamp(Math.min(endMs - recordingStartedAt + RECORDING_TIMESTAMP_PADDING_MS, lastChunkReceivedAt !== null && lastChunkReceivedAt !== void 0 ? lastChunkReceivedAt : Infinity)) : undefined;
14610
- onSignatureVideoCaptured(blob, signatureData, imageUrl !== null && imageUrl !== void 0 ? imageUrl : null, signatureStartTimestamp, signatureEndTimestamp);
14611
14508
  };
14612
- useVideoRecorderStore.getState().stopRecording();
14613
14509
  });
14614
14510
  },
14615
14511
  clearRecordedData: function clearRecordedData() {
14616
14512
  signatureChunks = [];
14617
- useVideoRecorderStore.getState().stopRecordingVideo();
14618
- useVideoRecorderStore.getState().clearRecordedData();
14619
14513
  signatureRecorder === null || signatureRecorder === void 0 ? void 0 : signatureRecorder.stop();
14620
14514
  signatureRecorder = null;
14621
14515
  set({
@@ -14657,75 +14551,180 @@ function waitForOneMoreChunk(timeoutMs) {
14657
14551
  }
14658
14552
  function VideoSignatureContextProvider(_a) {
14659
14553
  var _this = this;
14660
- var _b, _c;
14554
+ var _b, _c, _d, _e;
14661
14555
  var children = _a.children,
14662
- _d = _a.captureAudio,
14663
- captureAudio = _d === void 0 ? false : _d;
14556
+ _f = _a.captureMediaInfo,
14557
+ captureMediaInfo = _f === void 0 ? false : _f;
14664
14558
  var videoRef = useCameraStore().videoRef;
14665
- useVideoRecorder(captureAudio);
14666
14559
  var outputCanvas = React.useRef(null);
14667
14560
  React.useEffect(function () {
14668
14561
  return useVideoSignatureStore.setState({
14669
14562
  outputCanvas: outputCanvas
14670
14563
  });
14671
14564
  }, []);
14565
+ var signatureVideoRef = React.useRef(null);
14566
+ var frameCheckCanvas = React.useRef(null);
14672
14567
  React.useEffect(function () {
14673
- // clear recorded data when the component is mounted
14674
- useVideoSignatureStore.getState().clearRecordedData();
14675
- }, []);
14676
- var _e = useVideoSignatureStore(shallow.useShallow(function (state) {
14677
- return {
14678
- recordingStartedAt: state.recordingStartedAt,
14679
- recordingStoppedAt: state.recordingStoppedAt
14680
- };
14681
- })),
14682
- recordingStartedAt = _e.recordingStartedAt,
14683
- recordingStoppedAt = _e.recordingStoppedAt;
14684
- useFrameLoop(React.useCallback(function () {
14568
+ if (!captureMediaInfo) return;
14569
+ mediaInfoFactory__default.default({
14570
+ format: 'object',
14571
+ full: true,
14572
+ locateFile: function locateFile(filename) {
14573
+ return "".concat(DEFAULT_CDN_URL, "/").concat(filename);
14574
+ }
14575
+ }).then(function (mediaInfo) {
14576
+ useVideoSignatureStore.setState({
14577
+ mediaInfo: mediaInfo
14578
+ });
14579
+ })["catch"](function (e) {
14580
+ warn('error loading mediaInfo', e);
14581
+ });
14582
+ return function () {
14583
+ var mediaInfo = useVideoSignatureStore.getState().mediaInfo;
14584
+ if (mediaInfo) {
14585
+ mediaInfo.close();
14586
+ useVideoSignatureStore.setState({
14587
+ mediaInfo: undefined
14588
+ });
14589
+ }
14590
+ };
14591
+ }, [captureMediaInfo]);
14592
+ var signaturePadEmpty = useVideoSignatureStore().signaturePadEmpty;
14593
+ var blankCheckPassed = React.useRef(false);
14594
+ React.useEffect(function () {
14595
+ if (signaturePadEmpty) blankCheckPassed.current = false;
14596
+ }, [signaturePadEmpty]);
14597
+ var drawOutputFrame = React.useCallback(function () {
14685
14598
  return __awaiter(_this, void 0, void 0, function () {
14686
- var signaturePad, ctx, _a, w, h, isPortrait, rect;
14599
+ var ctx, _a, w, h, isPortrait, rect;
14687
14600
  return __generator(this, function (_b) {
14688
- signaturePad = useVideoSignatureStore.getState().signaturePad;
14689
- if (!outputCanvas.current || !signaturePad.current || !videoRef.current) return [2 /*return*/];
14601
+ if (!outputCanvas.current || !signatureVideoRef.current || !videoRef.current) return [2 /*return*/];
14690
14602
  ctx = outputCanvas.current.getContext('2d');
14691
14603
  if (!ctx) return [2 /*return*/];
14692
14604
  _a = [videoRef.current.videoWidth, videoRef.current.videoHeight], w = _a[0], h = _a[1];
14693
14605
  isPortrait = w < h;
14694
14606
  outputCanvas.current.width = w;
14695
14607
  outputCanvas.current.height = h;
14696
- rect = [w * (isPortrait ? 0.02 : 0.15), h * (isPortrait ? 0.15 : 0.25), w * (isPortrait ? 0.96 : 0.7), h * (isPortrait ? 0.7 : 0.5)];
14697
- // draw the current video frame
14608
+ rect = [w * (isPortrait ? 0.02 : 0.15),
14609
+ // x
14610
+ h * (isPortrait ? 0.15 : 0.25),
14611
+ // y
14612
+ w * (isPortrait ? 0.96 : 0.7),
14613
+ // width
14614
+ h * (isPortrait ? 0.7 : 0.5) // height
14615
+ ];
14698
14616
  ctx.drawImage(videoRef.current, 0, 0, w, h);
14699
- // draw a semi-transparent white rectangle over the video to simulate a signature pad
14700
14617
  ctx.beginPath();
14701
14618
  ctx.fillStyle = 'rgba(255,255,255,0.5)';
14702
- ctx.roundRect.apply(ctx, __spreadArray(__spreadArray([], rect, false), [16], false));
14619
+ if (typeof ctx.roundRect === 'function') {
14620
+ ctx.roundRect.apply(ctx, __spreadArray(__spreadArray([], rect, false), [16], false));
14621
+ } else if (typeof ctx.rect === 'function') {
14622
+ ctx.rect.apply(ctx, rect);
14623
+ }
14703
14624
  ctx.fill();
14704
- // draw whatever the user has drawn on the signature pad
14705
- ctx.drawImage.apply(ctx, __spreadArray([signaturePad.current.getCanvas()], rect, false));
14625
+ if (signatureVideoRef.current && blankCheckPassed.current) {
14626
+ ctx.drawImage.apply(ctx, __spreadArray([signatureVideoRef.current], rect, false));
14627
+ }
14706
14628
  return [2 /*return*/];
14707
14629
  });
14708
14630
  });
14709
- }, [videoRef]), {
14710
- autoStart: !!recordingStartedAt && !recordingStoppedAt,
14711
- throttleMs: 1000 / 24
14712
- });
14713
- return /*#__PURE__*/React__namespace.default.createElement(React__namespace.default.Fragment, null, children, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
14714
- ref: outputCanvas,
14631
+ }, [videoRef, outputCanvas]);
14632
+ React.useEffect(function () {
14633
+ if (!signatureVideoRef.current) return;
14634
+ var video = signatureVideoRef.current;
14635
+ function onFrame() {
14636
+ blankCheckPassed.current || (blankCheckPassed.current = !isVideoBlank(signatureVideoRef.current, frameCheckCanvas.current));
14637
+ drawOutputFrame();
14638
+ video.requestVideoFrameCallback(onFrame);
14639
+ }
14640
+ function onPlay() {
14641
+ video.requestVideoFrameCallback(onFrame);
14642
+ }
14643
+ video.addEventListener('play', onPlay);
14644
+ return function () {
14645
+ video.removeEventListener('play', onPlay);
14646
+ };
14647
+ }, [drawOutputFrame]);
14648
+ React.useEffect(function () {
14649
+ if (!videoRef.current) return;
14650
+ var video = videoRef.current;
14651
+ function onFrame() {
14652
+ drawOutputFrame();
14653
+ video.requestVideoFrameCallback(onFrame);
14654
+ }
14655
+ function onPlay() {
14656
+ video.requestVideoFrameCallback(onFrame);
14657
+ }
14658
+ video.addEventListener('play', onPlay);
14659
+ return function () {
14660
+ video.removeEventListener('play', onPlay);
14661
+ };
14662
+ }, [drawOutputFrame, videoRef]);
14663
+ var _g = useVideoSignatureStore(),
14664
+ signaturePad = _g.signaturePad,
14665
+ recordingStartedAt = _g.recordingStartedAt;
14666
+ React.useEffect(function () {
14667
+ var _a;
14668
+ if (!signaturePad.current || !recordingStartedAt) return;
14669
+ (_a = signatureVideoRef.current).srcObject || (_a.srcObject = signaturePad.current.getCanvas().captureStream(24));
14670
+ }, [recordingStartedAt, signaturePad]);
14671
+ return /*#__PURE__*/React__namespace.default.createElement(React__namespace.default.Fragment, null, children, /*#__PURE__*/React__namespace.default.createElement("video", {
14672
+ ref: signatureVideoRef,
14673
+ autoPlay: true,
14674
+ playsInline: true,
14675
+ muted: true,
14676
+ style: {
14677
+ display: 'none'
14678
+ // position: 'absolute',
14679
+ // top: 0,
14680
+ // left: 0,
14681
+ // width: '100%',
14682
+ // height: '100%',
14683
+ // zIndex: 1000,
14684
+ // pointerEvents: 'none',
14685
+ // opacity: 0.5,
14686
+ }
14687
+ }), /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
14688
+ ref: frameCheckCanvas,
14715
14689
  width: (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.videoWidth,
14716
14690
  height: (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.videoHeight
14691
+ }), /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
14692
+ ref: outputCanvas,
14693
+ width: (_d = videoRef.current) === null || _d === void 0 ? void 0 : _d.videoWidth,
14694
+ height: (_e = videoRef.current) === null || _e === void 0 ? void 0 : _e.videoHeight
14717
14695
  }));
14718
14696
  }
14719
- function formatTimestamp(durationMs) {
14720
- // should be in the format of 00:00:00:00 (hh:mm:ss:cs)
14721
- var hours = Math.floor(durationMs / 3600000);
14722
- var minutes = Math.floor(durationMs % 3600000 / 60000);
14723
- var seconds = Math.floor(durationMs % 60000 / 1000);
14724
- var milliseconds = durationMs % 1000;
14725
- // Convert milliseconds to centiseconds (1/100th of a second)
14726
- var centiseconds = Math.floor(milliseconds / 10);
14727
- var csString = centiseconds.toString().padStart(2, '0');
14728
- return "".concat(hours.toString().padStart(2, '0'), ":") + "".concat(minutes.toString().padStart(2, '0'), ":") + "".concat(seconds.toString().padStart(2, '0'), ":") + "".concat(csString);
14697
+ // function formatTimestamp(durationMs: number): string {
14698
+ // // should be in the format of 00:00:00:00 (hh:mm:ss:cs)
14699
+ // const hours = Math.floor(durationMs / 3600000)
14700
+ // const minutes = Math.floor((durationMs % 3600000) / 60000)
14701
+ // const seconds = Math.floor((durationMs % 60000) / 1000)
14702
+ // const milliseconds = durationMs % 1000
14703
+ // // Convert milliseconds to centiseconds (1/100th of a second)
14704
+ // const centiseconds = Math.floor(milliseconds / 10)
14705
+ // const csString = centiseconds.toString().padStart(2, '0')
14706
+ // return (
14707
+ // `${hours.toString().padStart(2, '0')}:` +
14708
+ // `${minutes.toString().padStart(2, '0')}:` +
14709
+ // `${seconds.toString().padStart(2, '0')}:` +
14710
+ // `${csString}`
14711
+ // )
14712
+ // }
14713
+ function isVideoBlank(video, canvas) {
14714
+ if (!video || !canvas) return true;
14715
+ var ctx2 = canvas.getContext('2d');
14716
+ if (!ctx2) return true;
14717
+ ctx2.drawImage(video, 0, 0, canvas.width, canvas.height);
14718
+ return isCanvasBlank(canvas);
14719
+ }
14720
+ function isCanvasBlank(canvas) {
14721
+ var context = canvas.getContext('2d');
14722
+ if (!context) return true;
14723
+ var pixelBuffer = new Uint32Array(context.getImageData(0, 0, canvas.width, canvas.height).data.buffer);
14724
+ var result = !pixelBuffer.some(function (color) {
14725
+ return color !== 0;
14726
+ });
14727
+ return result;
14729
14728
  }
14730
14729
 
14731
14730
  function VideoSignaturePad(_a) {
@@ -15065,8 +15064,8 @@ var AssetSelectorOption = styled__default.default.div(templateObject_4$3 || (tem
15065
15064
  var templateObject_1$8, templateObject_2$8, templateObject_3$7, templateObject_4$3;
15066
15065
 
15067
15066
  var assetSelectorOpts$1 = [{
15068
- value: 'video',
15069
- label: 'Video'
15067
+ value: 'signatureVideo',
15068
+ label: 'Signature Video'
15070
15069
  }, {
15071
15070
  value: 'selfieImage',
15072
15071
  label: 'Selfie Image'
@@ -15081,7 +15080,7 @@ var VideoSignatureSuccess = function VideoSignatureSuccess(_a) {
15081
15080
  _d = _a.verbiage,
15082
15081
  rawVerbiage = _d === void 0 ? {} : _d;
15083
15082
  var ctx = useSubmissionContext();
15084
- var _e = React.useState('video'),
15083
+ var _e = React.useState('signatureVideo'),
15085
15084
  displayedAsset = _e[0],
15086
15085
  setDisplayedAsset = _e[1];
15087
15086
  var verbiage = useTranslations(rawVerbiage, {
@@ -15119,7 +15118,7 @@ var VideoSignatureSuccess = function VideoSignatureSuccess(_a) {
15119
15118
  }, option.label));
15120
15119
  })), /*#__PURE__*/React__namespace.default.createElement(OverlayImageContainer, {
15121
15120
  className: classNames.videoContainer
15122
- }, displayedAsset === 'video' && ctx.signatureVideoUrl && ( /*#__PURE__*/React__namespace.default.createElement(StyledVideo, {
15121
+ }, displayedAsset === 'signatureVideo' && ctx.signatureVideoUrl && ( /*#__PURE__*/React__namespace.default.createElement(StyledVideo, {
15123
15122
  className: classNames.video,
15124
15123
  src: ctx.signatureVideoUrl,
15125
15124
  poster: ctx.signatureVideoUrl + '#t=0.1',
@@ -15346,59 +15345,60 @@ var VideoSignatureWizard = function VideoSignatureWizard(_a) {
15346
15345
  skipSuccessScreen = _c === void 0 ? false : _c,
15347
15346
  _d = _a.captureAudio,
15348
15347
  captureAudio = _d === void 0 ? false : _d,
15349
- _e = _a.minSignaturePadPoints,
15350
- minSignaturePadPoints = _e === void 0 ? DEFAULT_MIN_SIGNATURE_PAD_POINTS : _e,
15351
- _f = _a.headTrackingDisabled,
15352
- headTrackingDisabled = _f === void 0 ? false : _f,
15353
- _g = _a.headTrackingBoundaryPercentage,
15354
- headTrackingBoundaryPercentage = _g === void 0 ? DEFAULT_HEAD_TRACKING_BOUNDARY_PERCENTAGE : _g,
15355
- _h = _a.headTrackingBoundaryType,
15356
- headTrackingBoundaryType = _h === void 0 ? DEFAULT_HEAD_TRACKING_BOUNDARY_TYPE : _h,
15357
- _j = _a.allowSignatureAfterLivenessCheckFailure,
15358
- allowSignatureAfterLivenessCheckFailure = _j === void 0 ? false : _j,
15359
- _k = _a.restartVideoOnSignaturePadCleared,
15360
- restartVideoOnSignaturePadCleared = _k === void 0 ? true : _k,
15361
- _l = _a.skipLivenessValidation,
15362
- skipLivenessValidation = _l === void 0 ? false : _l,
15363
- _m = _a.allowManualSelfieCaptureOnLoadingError,
15364
- allowManualSelfieCaptureOnLoadingError = _m === void 0 ? false : _m,
15348
+ _e = _a.captureMediaInfo,
15349
+ captureMediaInfo = _e === void 0 ? false : _e,
15350
+ _f = _a.minSignaturePadPoints,
15351
+ minSignaturePadPoints = _f === void 0 ? DEFAULT_MIN_SIGNATURE_PAD_POINTS : _f,
15352
+ _g = _a.headTrackingDisabled,
15353
+ headTrackingDisabled = _g === void 0 ? false : _g,
15354
+ _h = _a.headTrackingBoundaryPercentage,
15355
+ headTrackingBoundaryPercentage = _h === void 0 ? DEFAULT_HEAD_TRACKING_BOUNDARY_PERCENTAGE : _h,
15356
+ _j = _a.headTrackingBoundaryType,
15357
+ headTrackingBoundaryType = _j === void 0 ? DEFAULT_HEAD_TRACKING_BOUNDARY_TYPE : _j,
15358
+ _k = _a.allowSignatureAfterLivenessCheckFailure,
15359
+ allowSignatureAfterLivenessCheckFailure = _k === void 0 ? false : _k,
15360
+ _l = _a.restartVideoOnSignaturePadCleared,
15361
+ restartVideoOnSignaturePadCleared = _l === void 0 ? true : _l,
15362
+ _m = _a.skipLivenessValidation,
15363
+ skipLivenessValidation = _m === void 0 ? false : _m,
15364
+ _o = _a.allowManualSelfieCaptureOnLoadingError,
15365
+ allowManualSelfieCaptureOnLoadingError = _o === void 0 ? false : _o,
15365
15366
  faceLivenessProps = _a.faceLivenessProps,
15366
15367
  guidesComponent = _a.guidesComponent,
15367
- _o = _a.showFaceGuideThenSignaturePad,
15368
- showFaceGuideThenSignaturePad = _o === void 0 ? false : _o,
15369
- _p = _a.assets,
15370
- assets = _p === void 0 ? {} : _p,
15371
- _q = _a.classNames,
15372
- classNames = _q === void 0 ? {} : _q,
15373
- _r = _a.colors,
15374
- colors = _r === void 0 ? {} : _r,
15375
- _s = _a.verbiage,
15376
- verbiage = _s === void 0 ? {} : _s,
15377
- _t = _a.debugMode,
15378
- debugMode = _t === void 0 ? false : _t;
15379
- var _u = useSubmissionContext(),
15380
- selfieImage = _u.selfieImage,
15381
- setSelfieImage = _u.setSelfieImage,
15382
- setSignatureData = _u.setSignatureData,
15383
- setSignatureVideoUrl = _u.setSignatureVideoUrl,
15384
- setSignatureStartTimestamp = _u.setSignatureStartTimestamp,
15385
- setSignatureEndTimestamp = _u.setSignatureEndTimestamp,
15386
- logSelfieCaptureAttempt = _u.logSelfieCaptureAttempt,
15387
- uploadDocument = _u.uploadDocument;
15368
+ _p = _a.showFaceGuideThenSignaturePad,
15369
+ showFaceGuideThenSignaturePad = _p === void 0 ? false : _p,
15370
+ _q = _a.assets,
15371
+ assets = _q === void 0 ? {} : _q,
15372
+ _r = _a.classNames,
15373
+ classNames = _r === void 0 ? {} : _r,
15374
+ _s = _a.colors,
15375
+ colors = _s === void 0 ? {} : _s,
15376
+ _t = _a.verbiage,
15377
+ verbiage = _t === void 0 ? {} : _t,
15378
+ _u = _a.debugMode,
15379
+ debugMode = _u === void 0 ? false : _u;
15380
+ var _v = useSubmissionContext(),
15381
+ selfieImage = _v.selfieImage,
15382
+ setSelfieImage = _v.setSelfieImage,
15383
+ setSignatureData = _v.setSignatureData,
15384
+ setSignatureVideoUrl = _v.setSignatureVideoUrl,
15385
+ setSignatureVideoMetadata = _v.setSignatureVideoMetadata,
15386
+ logSelfieCaptureAttempt = _v.logSelfieCaptureAttempt,
15387
+ uploadDocument = _v.uploadDocument;
15388
15388
  var cameraAccessDenied = useCameraStore(shallow.useShallow(function (state) {
15389
15389
  return {
15390
15390
  cameraAccessDenied: state.cameraAccessDenied
15391
15391
  };
15392
15392
  })).cameraAccessDenied;
15393
- var _v = React.useState(skipLivenessValidation ? 'CAPTURING_SELFIE' : 'CHECKING_LIVENESS'),
15394
- captureState = _v[0],
15395
- setCaptureState = _v[1];
15393
+ var _w = React.useState(skipLivenessValidation ? 'CAPTURING_SELFIE' : 'CHECKING_LIVENESS'),
15394
+ captureState = _w[0],
15395
+ setCaptureState = _w[1];
15396
15396
  var operationStartedAt = React.useRef();
15397
15397
  var captureStartedAt = React.useRef();
15398
15398
  var captureEndedAt = React.useRef();
15399
- var _w = useSelfieGuidanceModelsContext(),
15400
- start = _w.start,
15401
- stop = _w.stop;
15399
+ var _x = useSelfieGuidanceModelsContext(),
15400
+ start = _x.start,
15401
+ stop = _x.stop;
15402
15402
  React.useEffect(function () {
15403
15403
  operationStartedAt.current = new Date();
15404
15404
  }, []);
@@ -15442,25 +15442,24 @@ var VideoSignatureWizard = function VideoSignatureWizard(_a) {
15442
15442
  filetype: 'image/jpeg'
15443
15443
  }).then(onSelfieCaptured);
15444
15444
  }, [logCaptureMetadata, onSelfieCaptured, setSelfieImage, uploadDocument]);
15445
- var onSignatureCaptureCompleted = React.useCallback(function (videoData, signatureData, signatureImageData, signatureStartTimestamp, signatureEndTimestamp) {
15445
+ var onSignatureCaptureCompleted = React.useCallback(function (videoData, signatureData, signatureImageData, metadata) {
15446
15446
  setSignatureData(signatureData);
15447
15447
  setSignatureVideoUrl(URL.createObjectURL(videoData));
15448
- if (signatureStartTimestamp) setSignatureStartTimestamp(signatureStartTimestamp);
15449
- if (signatureEndTimestamp) setSignatureEndTimestamp(signatureEndTimestamp);
15448
+ setSignatureVideoMetadata(metadata);
15450
15449
  setCaptureState('SUCCESS');
15451
- onVideoCaptured === null || onVideoCaptured === void 0 ? void 0 : onVideoCaptured(videoData, signatureData, signatureImageData, signatureStartTimestamp, signatureEndTimestamp);
15452
- }, [onVideoCaptured, setSignatureData, setSignatureEndTimestamp, setSignatureStartTimestamp, setSignatureVideoUrl]);
15453
- var _x = React.useState(true),
15454
- showLoadingOverlay = _x[0],
15455
- setShowLoadingOverlay = _x[1];
15450
+ onVideoCaptured === null || onVideoCaptured === void 0 ? void 0 : onVideoCaptured(videoData, signatureData, signatureImageData, metadata);
15451
+ }, [onVideoCaptured, setSignatureData, setSignatureVideoMetadata, setSignatureVideoUrl]);
15452
+ var _y = React.useState(true),
15453
+ showLoadingOverlay = _y[0],
15454
+ setShowLoadingOverlay = _y[1];
15456
15455
  var onSignatureCaptureFacesNotDetected = React.useCallback(function () {
15457
15456
  setShowLoadingOverlay(false);
15458
15457
  setCaptureState(skipLivenessValidation ? 'CAPTURING_SELFIE' : 'CHECKING_LIVENESS');
15459
15458
  useVideoSignatureStore.getState().clearRecordedData();
15460
15459
  }, [skipLivenessValidation]);
15461
- var _y = React.useState(0),
15462
- attempt = _y[0],
15463
- setAttempt = _y[1];
15460
+ var _z = React.useState(0),
15461
+ attempt = _z[0],
15462
+ setAttempt = _z[1];
15464
15463
  var onRetry = React.useCallback(function () {
15465
15464
  onRetryClicked === null || onRetryClicked === void 0 ? void 0 : onRetryClicked();
15466
15465
  setAttempt(function (n) {
@@ -15509,7 +15508,7 @@ var VideoSignatureWizard = function VideoSignatureWizard(_a) {
15509
15508
  }, [faceLivenessOnLoadingOverlayDismissed, onLoadingOverlayDismissed]);
15510
15509
  return /*#__PURE__*/React__namespace.default.createElement(VideoSignatureContextProvider, {
15511
15510
  key: "video-signature-context-".concat(attempt),
15512
- captureAudio: captureAudio
15511
+ captureMediaInfo: captureMediaInfo
15513
15512
  }, /*#__PURE__*/React__namespace.default.createElement(CameraVideoTag, {
15514
15513
  className: classNames.cameraFeed
15515
15514
  }), function () {
@@ -15806,6 +15805,196 @@ var IdCardGuideInstructionsContainer = styled__default.default.div(templateObjec
15806
15805
  var IdCardGuideInstructions = styled__default.default(GuidanceMessage)(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n align-content: center;\n padding: 8px 12px;\n font-weight: bold;\n font-size: 18px;\n"], ["\n align-content: center;\n padding: 8px 12px;\n font-weight: bold;\n font-size: 18px;\n"])));
15807
15806
  var templateObject_1$7, templateObject_2$7, templateObject_3$6, templateObject_4$2, templateObject_5$2, templateObject_6$1, templateObject_7, templateObject_8;
15808
15807
 
15808
+ var videoRecorder = null;
15809
+ var audioRecorder = null;
15810
+ var videoChunks = [];
15811
+ var audioChunks = [];
15812
+ function setVideoRecorder(recorder) {
15813
+ videoRecorder = recorder;
15814
+ }
15815
+ function setAudioRecorder(recorder) {
15816
+ audioRecorder = recorder;
15817
+ }
15818
+ function clearVideoChunks() {
15819
+ videoChunks = [];
15820
+ }
15821
+ function clearAudioChunks() {
15822
+ audioChunks = [];
15823
+ }
15824
+ var initialState$2 = {
15825
+ videoUrl: null,
15826
+ audioUrl: null,
15827
+ isRecordingVideo: false,
15828
+ isRecordingAudio: false,
15829
+ videoRecordingStopped: false,
15830
+ audioRecordingStopped: false,
15831
+ videoRecordingIntentionallyStopped: false,
15832
+ audioRecordingIntentionallyStopped: false,
15833
+ mergeAVStreams: false,
15834
+ onVideoCaptured: function onVideoCaptured() {}
15835
+ };
15836
+ var useVideoRecorderStore = zustand.create()(middleware.devtools(function (set, get) {
15837
+ return _assign(_assign({}, initialState$2), {
15838
+ startRecordingVideo: function startRecordingVideo(captureAudio) {
15839
+ var _a, _b, _c;
15840
+ if (captureAudio === void 0) {
15841
+ captureAudio = false;
15842
+ }
15843
+ if (!camera) throw new Error('Camera not found');
15844
+ var _d = get(),
15845
+ mergeAVStreams = _d.mergeAVStreams,
15846
+ startRecordingAudio = _d.startRecordingAudio;
15847
+ var videoStream = mergeAVStreams ? new MediaStream(__spreadArray(__spreadArray([], (_b = (_a = camera === null || camera === void 0 ? void 0 : camera.stream) === null || _a === void 0 ? void 0 : _a.getTracks()) !== null && _b !== void 0 ? _b : [], true), captureAudio ? (_c = audioStream === null || audioStream === void 0 ? void 0 : audioStream.getTracks()) !== null && _c !== void 0 ? _c : [] : [], true)) : camera.stream;
15848
+ if (!videoStream) return;
15849
+ clearVideoChunks();
15850
+ videoRecorder = null;
15851
+ set({
15852
+ isRecordingVideo: true,
15853
+ videoRecordingStopped: false,
15854
+ videoRecordingIntentionallyStopped: false
15855
+ });
15856
+ videoRecorder = new MediaRecorder(videoStream, {
15857
+ videoBitsPerSecond: 270000,
15858
+ audioBitsPerSecond: 32000
15859
+ });
15860
+ videoRecorder.ondataavailable = function (e) {
15861
+ videoChunks.push(e.data);
15862
+ };
15863
+ videoRecorder.onstop = function () {
15864
+ set({
15865
+ videoRecordingStopped: true
15866
+ });
15867
+ };
15868
+ videoRecorder.start(100);
15869
+ setTimeout(function () {
15870
+ if (!videoRecorder || videoRecorder.state === 'inactive') {
15871
+ log('media recorder is inactive!');
15872
+ // TODO: figure out what to do here
15873
+ }
15874
+ }, 100);
15875
+ if (captureAudio && !mergeAVStreams) {
15876
+ startRecordingAudio();
15877
+ }
15878
+ },
15879
+ stopRecordingVideo: function stopRecordingVideo() {
15880
+ set({
15881
+ videoRecordingIntentionallyStopped: true
15882
+ });
15883
+ if (videoRecorder && videoRecorder.state !== 'inactive') {
15884
+ videoRecorder.stop();
15885
+ }
15886
+ },
15887
+ startRecordingAudio: function startRecordingAudio() {
15888
+ if (get().mergeAVStreams) return;
15889
+ if (!audioStream) return;
15890
+ clearAudioChunks();
15891
+ set({
15892
+ isRecordingAudio: true,
15893
+ audioRecordingStopped: false,
15894
+ audioRecordingIntentionallyStopped: false
15895
+ });
15896
+ var audioRecorder = new MediaRecorder(audioStream, {
15897
+ audioBitsPerSecond: 32000
15898
+ });
15899
+ setAudioRecorder(audioRecorder);
15900
+ audioRecorder.ondataavailable = function (e) {
15901
+ audioChunks.push(e.data);
15902
+ };
15903
+ audioRecorder.onstop = function () {
15904
+ set({
15905
+ audioRecordingStopped: true
15906
+ });
15907
+ };
15908
+ audioRecorder.start(100);
15909
+ },
15910
+ stopRecordingAudio: function stopRecordingAudio() {
15911
+ set({
15912
+ audioRecordingIntentionallyStopped: true
15913
+ });
15914
+ if ((audioRecorder === null || audioRecorder === void 0 ? void 0 : audioRecorder.state) !== 'inactive') {
15915
+ audioRecorder === null || audioRecorder === void 0 ? void 0 : audioRecorder.stop(); // if you call this while state === 'inactive', an exception is thrown.
15916
+ }
15917
+ },
15918
+ stopRecording: function stopRecording() {
15919
+ get().stopRecordingVideo();
15920
+ get().stopRecordingAudio();
15921
+ },
15922
+ clearRecordedData: function clearRecordedData() {
15923
+ clearVideoChunks();
15924
+ clearAudioChunks();
15925
+ }
15926
+ });
15927
+ }));
15928
+ var useVideoRecorder = function useVideoRecorder(mergeAVStreams) {
15929
+ if (mergeAVStreams === void 0) {
15930
+ mergeAVStreams = false;
15931
+ }
15932
+ React.useEffect(function () {
15933
+ return useVideoRecorderStore.setState({
15934
+ mergeAVStreams: mergeAVStreams
15935
+ });
15936
+ }, [mergeAVStreams]);
15937
+ React.useEffect(function () {
15938
+ // clear recorded data when the component is mounted
15939
+ useVideoRecorderStore.getState().clearRecordedData();
15940
+ }, []);
15941
+ var processVideo = React.useCallback(function () {
15942
+ var inferredType = inferBlobType(videoChunks[0]) || (videoRecorder === null || videoRecorder === void 0 ? void 0 : videoRecorder.mimeType) || 'video/mp4';
15943
+ var videoBlob = new Blob(videoChunks, {
15944
+ type: inferredType
15945
+ });
15946
+ var videoUrl = URL.createObjectURL(videoBlob);
15947
+ useVideoRecorderStore.setState({
15948
+ videoUrl: videoUrl,
15949
+ isRecordingVideo: false
15950
+ });
15951
+ clearVideoChunks();
15952
+ setVideoRecorder(null);
15953
+ useVideoRecorderStore.getState().onVideoCaptured(videoUrl);
15954
+ }, []);
15955
+ var processAudio = React.useCallback(function () {
15956
+ var inferredType = inferBlobType(audioChunks[0]) || (audioRecorder === null || audioRecorder === void 0 ? void 0 : audioRecorder.mimeType) || 'audio/mp4';
15957
+ var audioBlob = new Blob(audioChunks, {
15958
+ type: inferredType
15959
+ });
15960
+ useVideoRecorderStore.setState({
15961
+ audioUrl: URL.createObjectURL(audioBlob),
15962
+ isRecordingAudio: false
15963
+ });
15964
+ clearAudioChunks();
15965
+ setAudioRecorder(null);
15966
+ }, []);
15967
+ var _a = useVideoRecorderStore(),
15968
+ videoUrl = _a.videoUrl,
15969
+ audioUrl = _a.audioUrl,
15970
+ isRecordingVideo = _a.isRecordingVideo,
15971
+ isRecordingAudio = _a.isRecordingAudio,
15972
+ videoRecordingStopped = _a.videoRecordingStopped,
15973
+ videoRecordingIntentionallyStopped = _a.videoRecordingIntentionallyStopped,
15974
+ audioRecordingStopped = _a.audioRecordingStopped,
15975
+ audioRecordingIntentionallyStopped = _a.audioRecordingIntentionallyStopped;
15976
+ React.useEffect(function () {
15977
+ if (videoRecordingStopped && videoRecordingIntentionallyStopped) {
15978
+ processVideo();
15979
+ }
15980
+ }, [processVideo, videoRecordingIntentionallyStopped, videoRecordingStopped]);
15981
+ React.useEffect(function () {
15982
+ if (audioRecordingStopped && audioRecordingIntentionallyStopped) {
15983
+ processAudio();
15984
+ }
15985
+ }, [audioRecordingIntentionallyStopped, audioRecordingStopped, processAudio]);
15986
+ return React.useMemo(function () {
15987
+ return {
15988
+ isRecordingVideo: isRecordingVideo,
15989
+ isRecordingAudio: isRecordingAudio,
15990
+ videoRecordingUnintentionallyStopped: videoRecordingStopped && !videoRecordingIntentionallyStopped,
15991
+ audioRecordingUnintentionallyStopped: audioRecordingStopped && !audioRecordingIntentionallyStopped,
15992
+ videoUrl: videoUrl,
15993
+ audioUrl: audioUrl
15994
+ };
15995
+ }, [audioRecordingIntentionallyStopped, audioRecordingStopped, audioUrl, isRecordingAudio, isRecordingVideo, videoRecordingIntentionallyStopped, videoRecordingStopped, videoUrl]);
15996
+ };
15997
+
15809
15998
  var ReadTextPrompt = function ReadTextPrompt(_a) {
15810
15999
  var onComplete = _a.onComplete,
15811
16000
  _b = _a.durationMs,