idmission-web-sdk 2.3.124 → 2.3.125

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.
@@ -211,7 +211,7 @@
211
211
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
212
212
  };
213
213
 
214
- var webSdkVersion = '2.3.124';
214
+ var webSdkVersion = '2.3.125';
215
215
 
216
216
  function getPlatform() {
217
217
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -24283,6 +24283,9 @@
24283
24283
 
24284
24284
  var signatureRecorder = null;
24285
24285
  var signatureChunks = [];
24286
+ var ondataavailableInvocations = [];
24287
+ var ondataavailableStartTime;
24288
+ var lastCalculatedVideoChunkRate;
24286
24289
  var videoSignatureInitialState = {
24287
24290
  startRecording: function startRecording() {
24288
24291
  return null;
@@ -24307,6 +24310,10 @@
24307
24310
  signatureValid: false,
24308
24311
  supportsRequestVideoFrameCallback: undefined,
24309
24312
  supportsRoundRect: undefined,
24313
+ nullChunksReceived: 0,
24314
+ timesSignatureCleared: 0,
24315
+ finalChunkReceived: false,
24316
+ requestDataInterval: undefined,
24310
24317
  onSignatureVideoCaptured: function onSignatureVideoCaptured() {
24311
24318
  return null;
24312
24319
  }
@@ -24319,8 +24326,11 @@
24319
24326
  captureAudio = false;
24320
24327
  }
24321
24328
  if (!camera) throw new Error('Camera not found');
24322
- // set our flag and clear whatever we have recorded so far.
24329
+ // clear whatever we have recorded so far.
24323
24330
  signatureChunks = [];
24331
+ ondataavailableInvocations = [];
24332
+ ondataavailableStartTime = undefined;
24333
+ lastCalculatedVideoChunkRate = undefined;
24324
24334
  // start recording from the output canvas to capture the signature
24325
24335
  var outputStream = (_a = get().outputCanvas.current) === null || _a === void 0 ? void 0 : _a.captureStream(24);
24326
24336
  if (!outputStream) throw new Error('outputStream not found');
@@ -24338,77 +24348,123 @@
24338
24348
  recordingStartedAt: e.timeStamp
24339
24349
  });
24340
24350
  };
24341
- var hasFirstChunk = false;
24342
24351
  signatureRecorder.ondataavailable = function (event) {
24352
+ var now = performance.now();
24343
24353
  signatureChunks.push(event.data);
24344
- if (!hasFirstChunk) {
24345
- hasFirstChunk = true;
24346
- set({
24347
- firstChunkReceivedAt: performance.now(),
24348
- lastChunkReceivedAt: performance.now()
24354
+ trackVideoChunkRate(now);
24355
+ if (event.data.size > 0) {
24356
+ set(function (state) {
24357
+ var _a;
24358
+ return {
24359
+ firstChunkReceivedAt: (_a = state.firstChunkReceivedAt) !== null && _a !== void 0 ? _a : now,
24360
+ lastChunkReceivedAt: now
24361
+ };
24349
24362
  });
24350
24363
  } else {
24351
- set({
24352
- lastChunkReceivedAt: performance.now()
24364
+ set(function (state) {
24365
+ var _a;
24366
+ return {
24367
+ nullChunksReceived: state.nullChunksReceived + 1,
24368
+ firstNullChunkReceivedAt: (_a = state.firstNullChunkReceivedAt) !== null && _a !== void 0 ? _a : now,
24369
+ lastNullChunkReceivedAt: now
24370
+ };
24353
24371
  });
24354
24372
  }
24355
24373
  };
24356
- signatureRecorder.start(250);
24374
+ signatureRecorder.start();
24375
+ var interval = setInterval(function () {
24376
+ return signatureRecorder === null || signatureRecorder === void 0 ? void 0 : signatureRecorder.requestData();
24377
+ }, 250);
24357
24378
  set({
24379
+ requestDataInterval: interval,
24358
24380
  recordingStartRequestedAt: performance.now()
24359
24381
  });
24360
24382
  },
24361
24383
  stopRecording: function stopRecording(signatureData, imageUrl) {
24362
24384
  return __awaiter(this, void 0, void 0, function () {
24363
- var _this = this;
24364
- return __generator(this, function (_a) {
24365
- switch (_a.label) {
24385
+ function processVideo() {
24386
+ return __awaiter(this, void 0, void 0, function () {
24387
+ var recordingStoppedAt, mimeType, blob, _a, onSignatureVideoCaptured, recordingStartRequestedAt, recordingStartedAt, firstChunkReceivedAt, signatureStartedAt, signatureEndedAt, acceptClickedAt, clearClickedAt, recordingStopRequestedAt, lastChunkReceivedAt, supportsRequestVideoFrameCallback, supportsRoundRect, nullChunksReceived, firstNullChunkReceivedAt, lastNullChunkReceivedAt, timesSignatureCleared, metadata;
24388
+ return __generator(this, function (_b) {
24389
+ if (get().recordingStoppedAt) return [2 /*return*/];
24390
+ recordingStoppedAt = performance.now();
24391
+ set({
24392
+ recordingStoppedAt: recordingStoppedAt
24393
+ });
24394
+ mimeType = inferBlobType(signatureChunks[0]) || (signatureRecorder === null || signatureRecorder === void 0 ? void 0 : signatureRecorder.mimeType) || 'video/mp4';
24395
+ blob = new Blob(signatureChunks, {
24396
+ type: mimeType
24397
+ });
24398
+ signatureChunks = [];
24399
+ signatureRecorder = null;
24400
+ _a = get(), onSignatureVideoCaptured = _a.onSignatureVideoCaptured, recordingStartRequestedAt = _a.recordingStartRequestedAt, recordingStartedAt = _a.recordingStartedAt, firstChunkReceivedAt = _a.firstChunkReceivedAt, signatureStartedAt = _a.signatureStartedAt, signatureEndedAt = _a.signatureEndedAt, acceptClickedAt = _a.acceptClickedAt, clearClickedAt = _a.clearClickedAt, recordingStopRequestedAt = _a.recordingStopRequestedAt, lastChunkReceivedAt = _a.lastChunkReceivedAt, supportsRequestVideoFrameCallback = _a.supportsRequestVideoFrameCallback, supportsRoundRect = _a.supportsRoundRect, nullChunksReceived = _a.nullChunksReceived, firstNullChunkReceivedAt = _a.firstNullChunkReceivedAt, lastNullChunkReceivedAt = _a.lastNullChunkReceivedAt, timesSignatureCleared = _a.timesSignatureCleared;
24401
+ metadata = {
24402
+ mimeType: mimeType,
24403
+ browserFeatures: {
24404
+ supportsRoundRect: supportsRoundRect,
24405
+ supportsRequestVideoFrameCallback: supportsRequestVideoFrameCallback
24406
+ },
24407
+ diagnostics: {
24408
+ nullChunksReceived: nullChunksReceived,
24409
+ firstNullChunkReceivedAt: firstNullChunkReceivedAt ? Math.ceil(firstNullChunkReceivedAt) : 0,
24410
+ lastNullChunkReceivedAt: lastNullChunkReceivedAt ? Math.ceil(lastNullChunkReceivedAt) : 0,
24411
+ finalChunkReceived: finalChunkReceived,
24412
+ finalChunkTimedOut: timedOut,
24413
+ finalChunkWaitedMs: Math.ceil(waitedMs),
24414
+ videoChunkRate: lastCalculatedVideoChunkRate,
24415
+ timesSignatureCleared: timesSignatureCleared
24416
+ },
24417
+ timingData: {
24418
+ recordingStartRequestedAt: recordingStartRequestedAt ? Math.ceil(recordingStartRequestedAt) : 0,
24419
+ recordingStartedAt: recordingStartedAt ? Math.ceil(recordingStartedAt) : 0,
24420
+ firstChunkReceivedAt: firstChunkReceivedAt ? Math.ceil(firstChunkReceivedAt) : 0,
24421
+ signatureStartedAt: signatureStartedAt ? Math.ceil(signatureStartedAt) : 0,
24422
+ signatureEndedAt: signatureEndedAt ? Math.ceil(signatureEndedAt) : 0,
24423
+ acceptClickedAt: acceptClickedAt ? Math.ceil(acceptClickedAt) : 0,
24424
+ clearClickedAt: clearClickedAt ? Math.ceil(clearClickedAt) : 0,
24425
+ recordingStopRequestedAt: recordingStopRequestedAt ? Math.ceil(recordingStopRequestedAt) : 0,
24426
+ recordingStoppedAt: Math.ceil(recordingStoppedAt),
24427
+ lastChunkReceivedAt: lastChunkReceivedAt ? Math.ceil(lastChunkReceivedAt) : 0
24428
+ }
24429
+ };
24430
+ debug('signature video metadata', metadata);
24431
+ onSignatureVideoCaptured(blob, signatureData !== null && signatureData !== void 0 ? signatureData : null, imageUrl !== null && imageUrl !== void 0 ? imageUrl : null, metadata);
24432
+ return [2 /*return*/];
24433
+ });
24434
+ });
24435
+ }
24436
+ var _a, recordingStartedAt, recordingStopRequestedAt, isRecording, _b, finalChunkReceived, timedOut, waitedMs;
24437
+ return __generator(this, function (_c) {
24438
+ switch (_c.label) {
24366
24439
  case 0:
24440
+ _a = get(), recordingStartedAt = _a.recordingStartedAt, recordingStopRequestedAt = _a.recordingStopRequestedAt;
24441
+ isRecording = !!recordingStartedAt && !recordingStopRequestedAt;
24442
+ if (!isRecording) return [2 /*return*/];
24367
24443
  set({
24368
- recordingStopRequestedAt: performance.now()
24444
+ recordingStopRequestedAt: performance.now(),
24445
+ recordingStoppedAt: undefined
24369
24446
  });
24370
- if (!signatureRecorder) return [2 /*return*/];
24371
- return [4 /*yield*/, waitForOneMoreChunk()];
24447
+ clearInterval(get().requestDataInterval);
24448
+ return [4 /*yield*/, waitForOneMoreChunk()
24449
+ // this represents the time that it is safe to release the camera access
24450
+ ];
24372
24451
  case 1:
24373
- _a.sent();
24374
- signatureRecorder.onstop = function () {
24375
- return __awaiter(_this, void 0, void 0, function () {
24376
- var recordingStoppedAt, mimeType, blob, _a, onSignatureVideoCaptured, recordingStartRequestedAt, recordingStartedAt, firstChunkReceivedAt, signatureStartedAt, signatureEndedAt, acceptClickedAt, recordingStopRequestedAt, lastChunkReceivedAt, supportsRequestVideoFrameCallback, supportsRoundRect;
24377
- return __generator(this, function (_b) {
24378
- recordingStoppedAt = performance.now();
24379
- set({
24380
- recordingStoppedAt: recordingStoppedAt
24381
- });
24382
- mimeType = inferBlobType(signatureChunks[0]) || (signatureRecorder === null || signatureRecorder === void 0 ? void 0 : signatureRecorder.mimeType) || 'video/mp4';
24383
- blob = new Blob(signatureChunks, {
24384
- type: mimeType
24385
- });
24386
- signatureChunks = [];
24387
- signatureRecorder = null;
24388
- _a = get(), onSignatureVideoCaptured = _a.onSignatureVideoCaptured, recordingStartRequestedAt = _a.recordingStartRequestedAt, recordingStartedAt = _a.recordingStartedAt, firstChunkReceivedAt = _a.firstChunkReceivedAt, signatureStartedAt = _a.signatureStartedAt, signatureEndedAt = _a.signatureEndedAt, acceptClickedAt = _a.acceptClickedAt, recordingStopRequestedAt = _a.recordingStopRequestedAt, lastChunkReceivedAt = _a.lastChunkReceivedAt, supportsRequestVideoFrameCallback = _a.supportsRequestVideoFrameCallback, supportsRoundRect = _a.supportsRoundRect;
24389
- onSignatureVideoCaptured(blob, signatureData !== null && signatureData !== void 0 ? signatureData : null, imageUrl !== null && imageUrl !== void 0 ? imageUrl : null, {
24390
- mimeType: mimeType,
24391
- browserFeatures: {
24392
- supportsRoundRect: supportsRoundRect,
24393
- supportsRequestVideoFrameCallback: supportsRequestVideoFrameCallback
24394
- },
24395
- timingData: {
24396
- recordingStartRequestedAt: recordingStartRequestedAt ? Math.ceil(recordingStartRequestedAt) : 0,
24397
- recordingStartedAt: recordingStartedAt ? Math.ceil(recordingStartedAt) : 0,
24398
- firstChunkReceivedAt: firstChunkReceivedAt ? Math.ceil(firstChunkReceivedAt) : 0,
24399
- signatureStartedAt: signatureStartedAt ? Math.ceil(signatureStartedAt) : 0,
24400
- signatureEndedAt: signatureEndedAt ? Math.ceil(signatureEndedAt) : 0,
24401
- acceptClickedAt: acceptClickedAt ? Math.ceil(acceptClickedAt) : 0,
24402
- recordingStopRequestedAt: recordingStopRequestedAt ? Math.ceil(recordingStopRequestedAt) : 0,
24403
- recordingStoppedAt: Math.ceil(recordingStoppedAt),
24404
- lastChunkReceivedAt: lastChunkReceivedAt ? Math.ceil(lastChunkReceivedAt) : 0
24405
- }
24406
- });
24407
- return [2 /*return*/];
24408
- });
24409
- });
24410
- };
24452
+ _b = _c.sent(), finalChunkReceived = _b.finalChunkReceived, timedOut = _b.timedOut, waitedMs = _b.waitedMs;
24453
+ // this represents the time that it is safe to release the camera access
24454
+ set({
24455
+ finalChunkReceived: true
24456
+ });
24457
+ if (!signatureRecorder) return [3 /*break*/, 2];
24458
+ signatureRecorder.onstop = processVideo;
24411
24459
  signatureRecorder.stop();
24460
+ return [3 /*break*/, 4];
24461
+ case 2:
24462
+ warn('signature recorder not found, processing video immediately');
24463
+ return [4 /*yield*/, processVideo()];
24464
+ case 3:
24465
+ _c.sent();
24466
+ _c.label = 4;
24467
+ case 4:
24412
24468
  return [2 /*return*/];
24413
24469
  }
24414
24470
  });
@@ -24416,6 +24472,9 @@
24416
24472
  },
24417
24473
  clearRecordedData: function clearRecordedData() {
24418
24474
  signatureChunks = [];
24475
+ ondataavailableInvocations = [];
24476
+ ondataavailableStartTime = undefined;
24477
+ lastCalculatedVideoChunkRate = undefined;
24419
24478
  signatureRecorder === null || signatureRecorder === void 0 ? void 0 : signatureRecorder.stop();
24420
24479
  signatureRecorder = null;
24421
24480
  set({
@@ -24430,8 +24489,13 @@
24430
24489
  signatureStartedAt: undefined,
24431
24490
  signatureEndedAt: undefined,
24432
24491
  acceptClickedAt: undefined,
24492
+ // Note: clearClickedAt is intentionally preserved for telemetry metadata
24433
24493
  supportsRequestVideoFrameCallback: undefined,
24434
- supportsRoundRect: undefined
24494
+ supportsRoundRect: undefined,
24495
+ nullChunksReceived: 0,
24496
+ firstNullChunkReceivedAt: undefined,
24497
+ lastNullChunkReceivedAt: undefined,
24498
+ finalChunkReceived: false
24435
24499
  });
24436
24500
  }
24437
24501
  });
@@ -24441,11 +24505,11 @@
24441
24505
  * @param delayMs - The delay in milliseconds before the first check -- this is used to make sure we get at least one extra second of video.
24442
24506
  * @param checkEveryMs - The interval in milliseconds between checks after the initial delay has passed.
24443
24507
  * @param timeoutMs - The maximum time in milliseconds to wait for the chunk -- this is used to prevent infinite loops.
24444
- * @returns A promise that resolves when the delay has passed and at least one chunk has been received received.
24508
+ * @returns A promise that resolves when the delay has passed and at least one chunk has been received received. The return value is the number of milliseconds that we waited, whether we received a chunk, and whether we timed out.
24445
24509
  */
24446
24510
  function waitForOneMoreChunk(delayMs, checkEveryMs, timeoutMs) {
24447
24511
  if (delayMs === void 0) {
24448
- delayMs = 1000;
24512
+ delayMs = 250;
24449
24513
  }
24450
24514
  if (checkEveryMs === void 0) {
24451
24515
  checkEveryMs = 100;
@@ -24453,29 +24517,44 @@
24453
24517
  if (timeoutMs === void 0) {
24454
24518
  timeoutMs = 3000;
24455
24519
  }
24456
- var start = performance.now();
24457
24520
  return new Promise(function (resolve) {
24458
- var initialLastChunkReceivedAt = useVideoSignatureStore.getState().lastChunkReceivedAt;
24459
- function gotAChunk() {
24521
+ var _a;
24522
+ var start = performance.now();
24523
+ var initialLastChunkReceivedAt = (_a = useVideoSignatureStore.getState().lastChunkReceivedAt) !== null && _a !== void 0 ? _a : start;
24524
+ signatureRecorder === null || signatureRecorder === void 0 ? void 0 : signatureRecorder.requestData();
24525
+ function checkForChunk() {
24460
24526
  var lastChunkReceivedAt = useVideoSignatureStore.getState().lastChunkReceivedAt;
24461
- return performance.now() - start > timeoutMs || !lastChunkReceivedAt || !initialLastChunkReceivedAt || lastChunkReceivedAt > initialLastChunkReceivedAt;
24527
+ var waitedMs = performance.now() - start;
24528
+ var timedOut = waitedMs > timeoutMs;
24529
+ var finalChunkReceived = !!lastChunkReceivedAt && !!initialLastChunkReceivedAt && lastChunkReceivedAt > initialLastChunkReceivedAt;
24530
+ return {
24531
+ waitedMs: waitedMs,
24532
+ finalChunkReceived: finalChunkReceived,
24533
+ timedOut: timedOut
24534
+ };
24462
24535
  }
24463
24536
  setTimeout(function () {
24464
- if (gotAChunk()) return resolve(); // check immediately
24537
+ // check immediately
24538
+ var result = checkForChunk();
24539
+ if (result.finalChunkReceived || result.timedOut) return resolve(result);
24465
24540
  // otherwise, check on a configured interval
24466
24541
  var interval = setInterval(function () {
24467
- if (gotAChunk()) {
24542
+ var result = checkForChunk();
24543
+ if (result.finalChunkReceived || result.timedOut) {
24468
24544
  clearInterval(interval);
24469
- resolve();
24545
+ resolve(result);
24470
24546
  }
24471
24547
  }, checkEveryMs);
24472
24548
  }, delayMs);
24473
24549
  });
24474
24550
  }
24475
24551
  function VideoSignatureContextProvider(_a) {
24476
- var _b, _c;
24477
24552
  var children = _a.children;
24478
- var videoRef = useCameraStore().videoRef;
24553
+ var _b = useCameraStore(),
24554
+ videoRef = _b.videoRef,
24555
+ videoWidth = _b.videoWidth,
24556
+ videoHeight = _b.videoHeight,
24557
+ releaseCameraAccess = _b.releaseCameraAccess;
24479
24558
  var outputCanvas = React.useRef(null);
24480
24559
  React.useEffect(function () {
24481
24560
  return useVideoSignatureStore.setState({
@@ -24483,18 +24562,13 @@
24483
24562
  });
24484
24563
  }, []);
24485
24564
  var drawOutputFrame = React.useCallback(function () {
24486
- if (!outputCanvas.current || !videoRef.current) return;
24565
+ if (!outputCanvas.current) return;
24487
24566
  var ctx = outputCanvas.current.getContext('2d');
24488
24567
  if (!ctx) return;
24489
- var _a = [videoRef.current.videoWidth, videoRef.current.videoHeight],
24568
+ var _a = [outputCanvas.current.width, outputCanvas.current.height],
24490
24569
  w = _a[0],
24491
24570
  h = _a[1];
24492
24571
  var isPortrait = w < h;
24493
- // Only update canvas dimensions if they changed (setting dimensions clears the canvas!)
24494
- if (outputCanvas.current.width !== w || outputCanvas.current.height !== h) {
24495
- outputCanvas.current.width = w;
24496
- outputCanvas.current.height = h;
24497
- }
24498
24572
  var rect = [w * (isPortrait ? 0.02 : 0.15),
24499
24573
  // x
24500
24574
  h * (isPortrait ? 0.15 : 0.25),
@@ -24503,7 +24577,9 @@
24503
24577
  // width
24504
24578
  h * (isPortrait ? 0.7 : 0.5) // height
24505
24579
  ];
24506
- ctx.drawImage(videoRef.current, 0, 0, w, h);
24580
+ if (videoRef.current) {
24581
+ ctx.drawImage(videoRef.current, 0, 0, w, h);
24582
+ }
24507
24583
  ctx.beginPath();
24508
24584
  ctx.fillStyle = 'rgba(255,255,255,0.5)';
24509
24585
  var supportsRoundRect = typeof ctx.roundRect === 'function';
@@ -24525,11 +24601,15 @@
24525
24601
  ctx.drawImage.apply(ctx, __spreadArray([signatureCanvas], rect, false));
24526
24602
  }
24527
24603
  }, [videoRef]);
24528
- useVideoFrameLoop(videoRef, drawOutputFrame);
24604
+ var finalChunkReceived = useVideoSignatureStore().finalChunkReceived;
24605
+ React.useEffect(function () {
24606
+ if (finalChunkReceived) releaseCameraAccess();
24607
+ }, [finalChunkReceived, releaseCameraAccess]);
24608
+ useVideoFrameLoop(videoRef, drawOutputFrame, !finalChunkReceived);
24529
24609
  return /*#__PURE__*/React.createElement(React.Fragment, null, children, /*#__PURE__*/React.createElement(InvisibleCanvas, {
24530
24610
  ref: outputCanvas,
24531
- width: (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.videoWidth,
24532
- height: (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.videoHeight
24611
+ width: videoWidth,
24612
+ height: videoHeight
24533
24613
  }));
24534
24614
  }
24535
24615
  function requestVideoFrameCallback(video, onFrame) {
@@ -24549,8 +24629,11 @@
24549
24629
  };
24550
24630
  }
24551
24631
  }
24552
- function videoFrameLoop(video, onFrame) {
24553
- if (!video) return;
24632
+ function videoFrameLoop(video, onFrame, running) {
24633
+ if (running === void 0) {
24634
+ running = true;
24635
+ }
24636
+ if (!video || !running) return;
24554
24637
  var cancelFn;
24555
24638
  var canceled = false;
24556
24639
  function onFrameRecursive() {
@@ -24571,10 +24654,51 @@
24571
24654
  if (cancelFn !== undefined) cancelFn();
24572
24655
  };
24573
24656
  }
24574
- function useVideoFrameLoop(ref, onFrame) {
24657
+ function useVideoFrameLoop(ref, onFrame, running) {
24658
+ if (running === void 0) {
24659
+ running = true;
24660
+ }
24575
24661
  React.useEffect(function () {
24576
- return videoFrameLoop(ref.current, onFrame);
24577
- }, [onFrame, ref]);
24662
+ return videoFrameLoop(ref.current, onFrame, running);
24663
+ }, [onFrame, ref, running]);
24664
+ }
24665
+ function calculateAndStoreOndataavailableRate() {
24666
+ if (ondataavailableInvocations.length < 2 || !ondataavailableStartTime) {
24667
+ lastCalculatedVideoChunkRate = {
24668
+ averageRate: 0,
24669
+ minRate: 0,
24670
+ maxRate: 0,
24671
+ totalChunksReceived: ondataavailableInvocations.length,
24672
+ recordingDurationMs: 0
24673
+ };
24674
+ return;
24675
+ }
24676
+ var totalDuration = ondataavailableInvocations[ondataavailableInvocations.length - 1] - ondataavailableStartTime;
24677
+ var averageRate = (ondataavailableInvocations.length - 1) / (totalDuration / 1000); // invocations per second
24678
+ // Calculate rates for each interval between invocations
24679
+ var rates = [];
24680
+ for (var i = 1; i < ondataavailableInvocations.length; i++) {
24681
+ var intervalMs = ondataavailableInvocations[i] - ondataavailableInvocations[i - 1];
24682
+ var rate = 1000 / intervalMs; // invocations per second for this interval
24683
+ rates.push(rate);
24684
+ }
24685
+ var minRate = Math.min.apply(Math, rates);
24686
+ var maxRate = Math.max.apply(Math, rates);
24687
+ lastCalculatedVideoChunkRate = {
24688
+ averageRate: Math.round(averageRate * 100) / 100,
24689
+ // Round to 2 decimal places
24690
+ minRate: Math.round(minRate * 100) / 100,
24691
+ maxRate: Math.round(maxRate * 100) / 100,
24692
+ totalChunksReceived: ondataavailableInvocations.length,
24693
+ recordingDurationMs: Math.round(totalDuration)
24694
+ };
24695
+ }
24696
+ function trackVideoChunkRate(now) {
24697
+ // Track ondataavailable invocations for rate calculation
24698
+ ondataavailableStartTime !== null && ondataavailableStartTime !== void 0 ? ondataavailableStartTime : ondataavailableStartTime = now;
24699
+ ondataavailableInvocations.push(now);
24700
+ // Calculate and store the current rate
24701
+ calculateAndStoreOndataavailableRate();
24578
24702
  }
24579
24703
 
24580
24704
  function VideoSignaturePad(_a) {
@@ -25512,13 +25636,18 @@
25512
25636
  });
25513
25637
  }, []);
25514
25638
  var onClearBtnClicked = React.useCallback(function () {
25515
- var _a, _b;
25639
+ var _a;
25640
+ var _b = useVideoSignatureStore.getState(),
25641
+ timesSignatureCleared = _b.timesSignatureCleared,
25642
+ signaturePad = _b.signaturePad;
25516
25643
  useVideoSignatureStore.setState({
25644
+ clearClickedAt: performance.now(),
25645
+ timesSignatureCleared: timesSignatureCleared + 1,
25517
25646
  signatureStartedAt: undefined,
25518
25647
  signaturePadEmpty: true,
25519
25648
  signatureValid: false
25520
25649
  });
25521
- (_b = (_a = useVideoSignatureStore.getState().signaturePad) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.clear();
25650
+ (_a = signaturePad.current) === null || _a === void 0 ? void 0 : _a.clear();
25522
25651
  if (restartVideoOnSignaturePadCleared) {
25523
25652
  setTimeout(function () {
25524
25653
  useVideoSignatureStore.getState().clearRecordedData();