@jaak.ai/stamps 2.0.0-dev.45 → 2.0.0-dev.47

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.
@@ -5,7 +5,7 @@ var index = require('./index-BfhtOB0D.js');
5
5
  const defineCustomElements = async (win, options) => {
6
6
  if (typeof window === 'undefined') return undefined;
7
7
  await index.globalScripts();
8
- return index.bootstrapLazy([["jaak-stamps.cjs",[[1,"jaak-stamps",{"debug":[4],"alignmentTolerance":[2,"alignment-tolerance"],"maskSize":[2,"mask-size"],"cropMargin":[2,"crop-margin"],"useDocumentClassification":[4,"use-document-classification"],"preferredCamera":[1,"preferred-camera"],"captureDelay":[2,"capture-delay"],"detectionBoxes":[32],"sideAlignment":[32],"isMaskReady":[32],"shouldMirrorVideo":[32],"showCameraSelector":[32],"isSwitchingCamera":[32],"hasDocumentDetected":[32],"currentStatus":[32],"performanceData":[32],"getCapturedImages":[64],"isProcessCompleted":[64],"startCapture":[64],"stopCapture":[64],"resetCapture":[64],"skipBackCapture":[64],"getStatus":[64],"preloadModel":[64],"getCameraInfo":[64],"setPreferredCamera":[64],"setCaptureDelay":[64],"getCaptureDelay":[64],"setTorchEnabled":[64],"focusAtPoint":[64]}]]]], options);
8
+ return index.bootstrapLazy([["jaak-stamps.cjs",[[1,"jaak-stamps",{"debug":[4],"alignmentTolerance":[2,"alignment-tolerance"],"maskSize":[2,"mask-size"],"cropMargin":[2,"crop-margin"],"useDocumentClassification":[4,"use-document-classification"],"preferredCamera":[1,"preferred-camera"],"captureDelay":[2,"capture-delay"],"enableBackDocumentTimer":[4,"enable-back-document-timer"],"backDocumentTimerDuration":[2,"back-document-timer-duration"],"detectionBoxes":[32],"sideAlignment":[32],"isMaskReady":[32],"shouldMirrorVideo":[32],"showCameraSelector":[32],"isSwitchingCamera":[32],"hasDocumentDetected":[32],"currentStatus":[32],"performanceData":[32],"backDocumentTimerRemaining":[32],"getCapturedImages":[64],"isProcessCompleted":[64],"startCapture":[64],"stopCapture":[64],"resetCapture":[64],"skipBackCapture":[64],"getStatus":[64],"preloadModel":[64],"getCameraInfo":[64],"setPreferredCamera":[64],"setCaptureDelay":[64],"getCaptureDelay":[64],"setTorchEnabled":[64],"focusAtPoint":[64]}]]]], options);
9
9
  };
10
10
 
11
11
  exports.setNonce = index.setNonce;
@@ -507,13 +507,42 @@ video {
507
507
  }
508
508
  }
509
509
 
510
- /* Bot\u00f3n para saltar reverso */
511
- .skip-button {
510
+ /* Sección para saltar reverso */
511
+ .skip-section {
512
512
  position: absolute;
513
513
  bottom: 20px;
514
514
  left: 50%;
515
515
  transform: translateX(-50%);
516
516
  z-index: 25;
517
+ display: flex;
518
+ flex-direction: column;
519
+ align-items: center;
520
+ width: 100%;
521
+ max-width: 300px;
522
+ }
523
+
524
+ .skip-explanation {
525
+ background-color: rgba(0, 0, 0, 0.7);
526
+ color: #ffffff;
527
+ padding: 10px 16px;
528
+ border-radius: 8px;
529
+ font-size: 14px;
530
+ font-weight: 500;
531
+ text-align: center;
532
+ margin-bottom: 12px;
533
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
534
+ backdrop-filter: blur(4px);
535
+ border: 1px solid rgba(255, 255, 255, 0.1);
536
+ animation: fadeIn 0.3s ease-in-out;
537
+ }
538
+
539
+ @keyframes fadeIn {
540
+ from { opacity: 0; transform: translateY(10px); }
541
+ to { opacity: 1; transform: translateY(0); }
542
+ }
543
+
544
+ /* Botón para saltar reverso */
545
+ .skip-button {
517
546
  pointer-events: auto;
518
547
  background: #fff;
519
548
  color: #333;
@@ -532,7 +561,7 @@ video {
532
561
 
533
562
  .skip-button:active {
534
563
  background: #e9ecef;
535
- transform: translateX(-50%) translateY(0);
564
+ transform: translateY(1px);
536
565
  }
537
566
 
538
567
  /* Camera controls */
@@ -734,29 +763,29 @@ video {
734
763
  right: 12px;
735
764
  gap: 6px;
736
765
  }
737
-
766
+
738
767
  .camera-selector-button {
739
768
  height: 36px;
740
769
  padding: 0 12px;
741
770
  font-size: 11px;
742
771
  border-radius: 6px;
743
772
  }
744
-
773
+
745
774
  .camera-selector-dropdown {
746
775
  right: 12px;
747
776
  top: 48px;
748
777
  min-width: 240px;
749
778
  max-width: calc(100vw - 24px);
750
779
  }
751
-
780
+
752
781
  .camera-selector-header {
753
782
  padding: 6px 10px;
754
783
  }
755
-
784
+
756
785
  .camera-option {
757
786
  padding: 6px 10px;
758
787
  }
759
-
788
+
760
789
  .device-info {
761
790
  padding: 4px 10px;
762
791
  }
@@ -847,16 +876,16 @@ video {
847
876
  height: 28px;
848
877
  border-radius: 8px;
849
878
  }
850
-
879
+
851
880
  .status-spinner {
852
881
  width: 14px;
853
882
  height: 14px;
854
883
  }
855
-
884
+
856
885
  .status-message {
857
886
  font-size: 11px;
858
887
  }
859
-
888
+
860
889
  .status-description {
861
890
  font-size: 9px;
862
891
  }
@@ -1006,25 +1035,25 @@ video {
1006
1035
  left: 12px;
1007
1036
  width: fit-content;
1008
1037
  }
1009
-
1038
+
1010
1039
  .performance-expanded {
1011
1040
  padding: 4px 8px;
1012
1041
  }
1013
-
1042
+
1014
1043
  .metrics-row {
1015
1044
  gap: 6px;
1016
1045
  margin-bottom: 3px;
1017
1046
  }
1018
-
1047
+
1019
1048
  .metric-compact {
1020
1049
  min-width: 45px;
1021
1050
  gap: 1px;
1022
1051
  }
1023
-
1052
+
1024
1053
  .metric-label {
1025
1054
  font-size: 8px;
1026
1055
  }
1027
-
1056
+
1028
1057
  .metric-value {
1029
1058
  font-size: 9px;
1030
1059
  padding: 1px 3px;
@@ -1078,10 +1107,9 @@ video {
1078
1107
  top: 160px;
1079
1108
  left: 12px;
1080
1109
  }
1081
-
1110
+
1082
1111
  .quality-text {
1083
1112
  padding: 4px 8px;
1084
1113
  font-size: 10px;
1085
1114
  }
1086
1115
  }
1087
-
@@ -9,6 +9,8 @@ export class JaakStamps {
9
9
  useDocumentClassification = false;
10
10
  preferredCamera = 'auto';
11
11
  captureDelay = 1500;
12
+ enableBackDocumentTimer = false;
13
+ backDocumentTimerDuration = 20;
12
14
  captureCompleted;
13
15
  isReady;
14
16
  // State derived from services
@@ -37,6 +39,7 @@ export class JaakStamps {
37
39
  successfulDetections: 0,
38
40
  detectionRate: 0
39
41
  };
42
+ backDocumentTimerRemaining = 0;
40
43
  // Services
41
44
  serviceContainer;
42
45
  logger;
@@ -55,6 +58,7 @@ export class JaakStamps {
55
58
  hasScreenshotTaken = false;
56
59
  alignmentStartTime;
57
60
  alignmentTimer;
61
+ backDocumentTimer;
58
62
  // Performance monitoring
59
63
  performanceMetrics = {
60
64
  fps: 0,
@@ -526,7 +530,13 @@ export class JaakStamps {
526
530
  });
527
531
  }
528
532
  // Update document detection state
533
+ const wasDocumentDetected = this.hasDocumentDetected;
529
534
  this.hasDocumentDetected = detections.length > 0;
535
+ // Restart timer if document detected during back capture
536
+ if (!wasDocumentDetected && this.hasDocumentDetected &&
537
+ captureState.step === 'back' && this.enableBackDocumentTimer) {
538
+ this.startBackDocumentTimer();
539
+ }
530
540
  // Adaptive frame rate
531
541
  if (detections.length === 0) {
532
542
  this.consecutiveFailures++;
@@ -607,7 +617,7 @@ export class JaakStamps {
607
617
  deviceType: 'desktop',
608
618
  preferredFacing: null
609
619
  };
610
- return (h("div", { key: '7af79a0ff25b51790a9477cd7b338a0584172fc2', class: "detector-container" }, h("div", { key: 'ebf6a3811e0e599f29e98325b975a645e3bfb5e0', class: "video-container" }, h("video", { key: '5208fc9574fa78b1149be5839bc26d04bf9bcdfc', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), h("div", { key: 'b507c786eccbd21acdd884ef50bc6ec280b9d437', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index) => (h("div", { key: index, class: "detection-box", style: {
620
+ return (h("div", { key: '9d4d77042218ab3d0bc4fb1ce879db09dc3e78b4', class: "detector-container" }, h("div", { key: '51ac8ccb1275637282b038ad8364d19f14ef61b1', class: "video-container" }, h("video", { key: 'a34f0481da20ec5b7b62b21aa275ec5f6dfec5d1', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), h("div", { key: '43b71dfe3eaf20ffa66a4139e24b1af6a2074631', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index) => (h("div", { key: index, class: "detection-box", style: {
611
621
  position: 'absolute',
612
622
  left: `${box.x}px`,
613
623
  top: `${box.y}px`,
@@ -616,7 +626,9 @@ export class JaakStamps {
616
626
  border: '2px solid #32406C',
617
627
  pointerEvents: 'none',
618
628
  boxSizing: 'border-box'
619
- } })))), this.isMaskReady && (h("div", { key: '53066c626b23daae351ea9a80409e8882434b0dd', class: "overlay-mask" }, h("div", { key: '77bb4048d43e328e57a5c7e1909e0a59c8957217', class: "card-outline" }, h("div", { key: 'ea0f2610d903f985286856ab69f8be24fd42148e', class: "side side-top" }), h("div", { key: 'dc671111ef4adf33aa41f4457fdf344ede23eb80', class: "side side-right" }), h("div", { key: '2475ec41577dca92b425542c8861c570ed7ecd3b', class: "side side-bottom" }), h("div", { key: 'a06171c8eb1bd6353a6464485604560d73ac04b7', class: "side side-left" }), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'ecfd98f36d457fe7282b26f6a0efef5361380c76', class: "guide-text" }, "Alinee su identificaci\u00F3n con el marco"))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("button", { key: 'f3c7b66500110437e9e4a7442cb327f2fdc6d71f', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button" }, "Saltar reverso")), captureState.isVideoActive && (h("div", { key: 'b5b2a8dfc6dbcf381c32c4caa562c27ced2e3e56', class: "camera-controls" }, h("button", { key: '6b40d4649dfa22c5ea8ca90cacce35cd0ca53ff3', class: `camera-selector-button ${this.isSwitchingCamera ? 'loading' : ''}`, onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara", disabled: this.isSwitchingCamera }, this.isSwitchingCamera ? (h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (h("div", { key: '41feec90287510b08bd1090ad15586b323007c30', class: "camera-selector-dropdown" }, h("div", { key: '8310ebe3db842c463ad428b973f841053315a76f', class: "camera-selector-header" }, h("span", { key: '6693bdfa33643dfe73798d4f25b0c2d9de7aac7c' }, "Seleccionar C\u00E1mara"), h("button", { key: '8552d45e1482c570d7ff85588d4404eec7c369d7', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: '5333ec0e5fb2c50a07a7c0b7d4dfb1bb4ee0df1c', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`), cameraInfo.selectedCameraId === camera.id && (h("span", { class: "selected-indicator" }, "\u2713")))))), h("div", { key: '8adf70b0e632c56a4784dec44621688809a3ff56', class: "device-info" }, h("small", { key: '2ea23922386ecda4a9011b50faba5efe4b4e60bb' }, "Dispositivo: ", cameraInfo.deviceType)))))), captureState.isCapturing && (h("div", { key: '8e693db67fe1e6ae8f11082b8993682b6d19b11d', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: '474489ed7848cdc163c492a5e19f5f13231e17b3', class: "flip-animation" }, h("div", { key: 'a9bd24ca21330882f001b7811077630eb1c30f50', class: "id-card-icon" }), h("div", { key: 'ffadb660a61e0f5e3e29bdc473d987e87dc4ad8a', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: 'd2522ee33aa159d49f040a293775892fb1cb81b5', class: "success-animation" }, h("div", { key: 'e7f899fac58bc9a3d51cf2cb89ee33bb320b241f', class: "check-icon" }), h("div", { key: 'd5d0ee1f37dbc659ca625ad03cbce325be0cf0a6', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: '425d347666032c3982a660ebee13b47670b996cb', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: '4d396fa107872f9a1e526fd59dc4edf279a05792', class: "status-spinner" })), h("div", { key: '232e9ae24c8cf5ef8ac0e3442e45a920799c724d', class: "status-content" }, h("div", { key: 'fe9dc0ca6d8e8276052bac7d2d44f1c7c9730364', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: '6910c7ac78fd89e6fa1165446ec6d46fb356035c', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: '7282b8afaf03da53b01a23d04babd772528c3c14', class: "performance-monitor" }, h("div", { key: 'b582b3124fed13387cd70a02a34ab2bb541f3bfc', class: "performance-expanded" }, h("div", { key: '764bac2d61224b9a5f306f50934d410e1bd27787', class: "metrics-row" }, h("div", { key: '261563f8314a9f6069b1ac6362eb9c38936a9dc7', class: "metric-compact" }, h("span", { key: '4feea98eff86620c1bc90eb65d9799102423109d', class: "metric-label" }, "FPS"), h("span", { key: 'eb15f13b27b8aa50701ad3d11c4cf87200010b67', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: '0813c35c2c33286f2276bfb5adce59b32c7bb597', class: "metric-compact" }, h("span", { key: '201e7bcb556e63b141e42a3ffc3419eb4284bfa8', class: "metric-label" }, "MEM"), h("span", { key: '4f6703cbe0128440d0f2f22f631035ab85422c64', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: '6343c361c93138b9ea66e8ae8acd361b93333f8c', class: "metrics-row" }, h("div", { key: 'd3c81fe597004bf380fae2d32f3a8314317e7769', class: "metric-compact" }, h("span", { key: 'fce572af3e200a611974dceef4da02f6aecedffc', class: "metric-label" }, "INF"), h("span", { key: '18dd78d54dcecfb70ddf59b782f87f8c6f208b0f', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '4c31ebfd835b017fd3e41b23d6bd9b19add511aa', class: "metric-compact" }, h("span", { key: '66b1a380b9479a8fc1e8c2385cb72aa4158dc74e', class: "metric-label" }, "FRAME"), h("span", { key: '3c6e41f7f11123c524d3a9df409345929d63f352', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: '3b522e2cdfe4bd9f1dd6eb0f91ee3577dc43e490', class: "metrics-row" }, h("div", { key: 'fa1e6f687b43aa2582b8b3426feb03a16c6493fc', class: "metric-compact" }, h("span", { key: 'a9355091e71a33a6a0d7cc6c11171dcda2e51b22', class: "metric-label" }, "DET"), h("span", { key: 'beca5a7ccf4853675cf8366bcf577ebfbd46c4f0', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: '4b07fc9b3d35f99bc6e77c8726192cde0476a787', class: "metric-compact" }, h("span", { key: 'a1674b538f45328ee0afb00e582c07e0b4ccf553', class: "metric-label" }, "RATE"), h("span", { key: 'fd384a5137bc3df6c939d3d698a3ef80e9087030', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: 'ebbaf15a0ad96e4da5bbf746c32d7a4abb51b973', class: "watermark" }, h("img", { key: '8e7d274b529d1f7020ec4a7225579792763f871a', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" })))));
629
+ } })))), this.isMaskReady && (h("div", { key: 'c2596f8cabb227e3ea3b082495f52b141cb1690f', class: "overlay-mask" }, h("div", { key: 'ba1ea39b5df1cd312a9bd9410b7225a29cfb8a29', class: "card-outline" }, h("div", { key: '6ce4d4d969d5f3fbcf75a4eb285f61d434c5633b', class: "side side-top" }), h("div", { key: '36653ecc4fcda25dfc84bc4d1f4c4c5dfb71ced7', class: "side side-right" }), h("div", { key: '8b108fa8fb370b229a0d1a77cb1ff044319a8f75', class: "side side-bottom" }), h("div", { key: 'a7aa3b45c065a50445aafd5c3ccefb57b0c9c769', class: "side side-left" }), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'b94b92273e12a019238e11ae57f21e140f13c3f1', class: "guide-text" }, "Alinee su identificaci\u00F3n con el marco"))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '144c3741003ec0cc148bb6ce92012d7b3cd110c8', class: "skip-section" }, h("div", { key: 'f0a984a6b75afa374c5d47da9d53e39f98071da0', class: "skip-explanation" }, "Si tu documento no tiene lado trasero, da clic en el bot\u00F3n para continuar con el proceso"), h("button", { key: '57ac30d776e30709aab6e0a621cef889da3cc677', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button" }, this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
630
+ ? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
631
+ : 'Saltar reverso'))), captureState.isVideoActive && (h("div", { key: 'bd45628707e0169317ed3dd4247e1056d7046104', class: "camera-controls" }, h("button", { key: 'e750fbf4d5d76d9e9596823bb2b86801ef19e485', class: `camera-selector-button ${this.isSwitchingCamera ? 'loading' : ''}`, onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara", disabled: this.isSwitchingCamera }, this.isSwitchingCamera ? (h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (h("div", { key: '40ada780a8ea13aeeaee9cb39bc6496f69f2679d', class: "camera-selector-dropdown" }, h("div", { key: '3a920bb02ba024f0359513f10544bf0528ecee6d', class: "camera-selector-header" }, h("span", { key: 'e5efd478a602b13821ba53cb9a7a59d1b4a71178' }, "Seleccionar C\u00E1mara"), h("button", { key: '2df6cc11e162be74862029e33815927e3fa8f2f8', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: '06934642dff134c9e1a6872f935a5892a9c7b835', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`), cameraInfo.selectedCameraId === camera.id && (h("span", { class: "selected-indicator" }, "\u2713")))))), h("div", { key: '8d5ede287c2efb0ebe418bee8dc7fb310443c991', class: "device-info" }, h("small", { key: 'b7dd10565113694b09f01ab28ffa29262ae1d2bc' }, "Dispositivo: ", cameraInfo.deviceType)))))), captureState.isCapturing && (h("div", { key: '2f9e549e6c0c56d4db5835e58361fb17bba6cf90', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: 'a6ef0ed127f23e9d764896ed743ca8d8454851a6', class: "flip-animation" }, h("div", { key: '0b04411f88a634bb3243b00ca2d5a45fd6962dea', class: "id-card-icon" }), h("div", { key: '9327be58879b407cea87f455989406e58302e9d1', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: 'bd268578b5003e99256e3340b4a9a6fb7656be64', class: "success-animation" }, h("div", { key: '064e0a5b9851de14bc6829f028e7ea7161fd1633', class: "check-icon" }), h("div", { key: 'bdcd94a8806399e396e218a359c10b11d05f38d6', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: '3d9af617376c16e44e065873919c3d90ff46110a', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: 'be7b56decfd6f12dcca46b2a9456480e3d5ac00e', class: "status-spinner" })), h("div", { key: '5fe9850883cb749cebaa18c3e9c13ca21325e373', class: "status-content" }, h("div", { key: '43fdb50691e4b98e56126af1a129f625061128bf', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: 'b76cbfa4a0349421fcd535d3fd8bf40c89ca3aef', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: 'eddefb464af0487ab9ab2a0f76dccbb6a2092e51', class: "performance-monitor" }, h("div", { key: '7b7d93b56cb4cd4fbb1bdde89c6150b282fa805e', class: "performance-expanded" }, h("div", { key: 'f302e8b9d985fb8cad53c4c4e0d37a3bf5a63261', class: "metrics-row" }, h("div", { key: 'e8d8f2420ee8643a7f454d38065c75b5be598f77', class: "metric-compact" }, h("span", { key: '6e52eb5bb06e0df57e61774de38c31349f45e22b', class: "metric-label" }, "FPS"), h("span", { key: '6636f9cea20c49b49c17db86188e2f6b214c45c3', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: 'afa1d9dec05b14256a1b1fcec8638b8c21a56e37', class: "metric-compact" }, h("span", { key: '9c55e30f5d01582648bacc1fb38ca1990485a591', class: "metric-label" }, "MEM"), h("span", { key: 'ca263601e8715027f95ffb2d5413a643dc570cf2', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: '03caf19961fd01b7781484d49d8121b1e78c161f', class: "metrics-row" }, h("div", { key: 'bffb08f01f703411f7c8605e4f8d95b1c37b5c0f', class: "metric-compact" }, h("span", { key: '9b92279b3253cc669412733facb3751f4344d69f', class: "metric-label" }, "INF"), h("span", { key: '3234d4150e2e1479e3b552767af8123e69911d6c', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '77082d2669db53f19fb50b3bbfa1ebefb0b86ff4', class: "metric-compact" }, h("span", { key: 'cc6ef96c72c800ba36dab2a388f1de863b2dacd5', class: "metric-label" }, "FRAME"), h("span", { key: 'e2bb4b7351869a76e810f8bbf20d805154495e35', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: '5700d7ef839fa77686299d79445203090dc8079f', class: "metrics-row" }, h("div", { key: 'a2999a035fccb7f250c01b084075490678513c87', class: "metric-compact" }, h("span", { key: '3677d58665996fa5969507dbaff9e956b2ea54ee', class: "metric-label" }, "DET"), h("span", { key: 'c584312438b339c82a3bdc33f00fb985ff2a6f55', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: '58866219f213bf8607083f30be2d5ca5d0515cea', class: "metric-compact" }, h("span", { key: 'd90b450051331347f219b6c0f197536d0dcee9b7', class: "metric-label" }, "RATE"), h("span", { key: 'f6e6cd7948e06014e5a0416e4e81394fa36ec61d', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: 'c1d0194f181a0082cc1aa5452de382908da61b65', class: "watermark" }, h("img", { key: 'e04d35f3c79a2b4a3922ab5b0f102220171fa7c0', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" })))));
620
632
  }
621
633
  // Utility methods
622
634
  updateDetectionBoxes(boxes) {
@@ -685,6 +697,15 @@ export class JaakStamps {
685
697
  bottomSide?.classList.toggle('aligned', currentAlignment.bottom);
686
698
  leftSide?.classList.toggle('aligned', currentAlignment.left);
687
699
  const allSidesAligned = this.detectionService.areAllSidesAligned(currentAlignment);
700
+ // Restart back document timer if any border is aligned during back capture
701
+ const captureState = this.stateManager.getCaptureState();
702
+ if (captureState.step === 'back' && this.enableBackDocumentTimer && bestBox) {
703
+ const anyBorderAligned = currentAlignment.top || currentAlignment.right ||
704
+ currentAlignment.bottom || currentAlignment.left;
705
+ if (anyBorderAligned) {
706
+ this.startBackDocumentTimer();
707
+ }
708
+ }
688
709
  if (allSidesAligned && bestBox) {
689
710
  cardOutline?.classList.add('perfect-match');
690
711
  corners?.forEach(corner => corner.classList.add('perfect-match'));
@@ -799,6 +820,7 @@ export class JaakStamps {
799
820
  showFlipAnimation: false,
800
821
  isDetectionPaused: false
801
822
  });
823
+ this.startBackDocumentTimer();
802
824
  }, 3000);
803
825
  }
804
826
  else if (captureState.step === 'back') {
@@ -849,9 +871,32 @@ export class JaakStamps {
849
871
  cancelAnimationFrame(this.animationId);
850
872
  this.animationId = undefined;
851
873
  }
874
+ this.clearBackDocumentTimer();
852
875
  this.detectionBoxes = [];
853
876
  this.logger.state('DETECTOR_DETENIDO', { timestamp: Date.now() });
854
877
  }
878
+ startBackDocumentTimer() {
879
+ if (!this.enableBackDocumentTimer)
880
+ return;
881
+ if (this.backDocumentTimer) {
882
+ clearInterval(this.backDocumentTimer);
883
+ }
884
+ this.backDocumentTimerRemaining = this.backDocumentTimerDuration;
885
+ this.backDocumentTimer = window.setInterval(() => {
886
+ this.backDocumentTimerRemaining--;
887
+ if (this.backDocumentTimerRemaining <= 0) {
888
+ this.clearBackDocumentTimer();
889
+ this.skipBackCapture();
890
+ }
891
+ }, 1000);
892
+ }
893
+ clearBackDocumentTimer() {
894
+ if (this.backDocumentTimer) {
895
+ clearInterval(this.backDocumentTimer);
896
+ this.backDocumentTimer = undefined;
897
+ }
898
+ this.backDocumentTimerRemaining = 0;
899
+ }
855
900
  toggleCameraSelector() {
856
901
  if (this.isSwitchingCamera)
857
902
  return; // Don't toggle if switching camera
@@ -1141,6 +1186,46 @@ export class JaakStamps {
1141
1186
  "setter": false,
1142
1187
  "reflect": false,
1143
1188
  "defaultValue": "1500"
1189
+ },
1190
+ "enableBackDocumentTimer": {
1191
+ "type": "boolean",
1192
+ "attribute": "enable-back-document-timer",
1193
+ "mutable": false,
1194
+ "complexType": {
1195
+ "original": "boolean",
1196
+ "resolved": "boolean",
1197
+ "references": {}
1198
+ },
1199
+ "required": false,
1200
+ "optional": false,
1201
+ "docs": {
1202
+ "tags": [],
1203
+ "text": ""
1204
+ },
1205
+ "getter": false,
1206
+ "setter": false,
1207
+ "reflect": false,
1208
+ "defaultValue": "false"
1209
+ },
1210
+ "backDocumentTimerDuration": {
1211
+ "type": "number",
1212
+ "attribute": "back-document-timer-duration",
1213
+ "mutable": false,
1214
+ "complexType": {
1215
+ "original": "number",
1216
+ "resolved": "number",
1217
+ "references": {}
1218
+ },
1219
+ "required": false,
1220
+ "optional": false,
1221
+ "docs": {
1222
+ "tags": [],
1223
+ "text": ""
1224
+ },
1225
+ "getter": false,
1226
+ "setter": false,
1227
+ "reflect": false,
1228
+ "defaultValue": "20"
1144
1229
  }
1145
1230
  };
1146
1231
  }
@@ -1154,7 +1239,8 @@ export class JaakStamps {
1154
1239
  "isSwitchingCamera": {},
1155
1240
  "hasDocumentDetected": {},
1156
1241
  "currentStatus": {},
1157
- "performanceData": {}
1242
+ "performanceData": {},
1243
+ "backDocumentTimerRemaining": {}
1158
1244
  };
1159
1245
  }
1160
1246
  static get events() {