@jaak.ai/stamps 2.0.0-dev.44 → 2.0.0-dev.46

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;
@@ -3,12 +3,14 @@ import { ServiceContainer } from "../../services/ServiceContainer";
3
3
  export class JaakStamps {
4
4
  el;
5
5
  debug = false;
6
- alignmentTolerance = 20;
6
+ alignmentTolerance = 15;
7
7
  maskSize = 80;
8
8
  cropMargin = 20;
9
9
  useDocumentClassification = false;
10
10
  preferredCamera = 'auto';
11
- captureDelay = 1000;
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,
@@ -152,8 +156,8 @@ export class JaakStamps {
152
156
  this.preferredCamera = 'auto';
153
157
  }
154
158
  if (this.captureDelay < 0 || this.captureDelay > 10000) {
155
- this.logger.warn(`Propiedad captureDelay inválida. Valor: ${this.captureDelay}, esperado: 0-10000. Usando valor por defecto: 1000`);
156
- this.captureDelay = 1000;
159
+ this.logger.warn(`Propiedad captureDelay inválida. Valor: ${this.captureDelay}, esperado: 0-10000. Usando valor por defecto: 1500`);
160
+ this.captureDelay = 1500;
157
161
  }
158
162
  }
159
163
  async loadOnnxRuntime() {
@@ -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("button", { key: 'c035db562697dc47104e2eca0bdf5edb9ddf2c5c', 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: '89f12b3d8a62f432c7dc9681103f58aaa62e825d', class: "camera-controls" }, h("button", { key: '3b33078be683b917d6305b625626064d68ad96d0', 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: 'cfb3a8d6b54819f547f14216ed8f7125a3e8204f', class: "camera-selector-dropdown" }, h("div", { key: '55fdca0391d4168e6213cc13a984331192cc0418', class: "camera-selector-header" }, h("span", { key: '514afcdfae390b12e62cec48952c3a2b2776ff13' }, "Seleccionar C\u00E1mara"), h("button", { key: '4b024517f86bdf88f3e6ff7ef0265203dabddb77', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: '6847609f0b1dfeca5684222c81b1c286e97a5338', 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: '64b10c71389ce687afbe797d6ea4375fc6e3445f', class: "device-info" }, h("small", { key: '0084017f0934ce4f63fe609e731540e1e1b49813' }, "Dispositivo: ", cameraInfo.deviceType)))))), captureState.isCapturing && (h("div", { key: 'fb6e41f1a26a258a8a8b1a7f91ac20da0e7f1574', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: '63e516f170c04dadfdf7ced2b930d017b313dfd3', class: "flip-animation" }, h("div", { key: 'fa3676adb192dec0f5389080659775e3ecc265b6', class: "id-card-icon" }), h("div", { key: '2c4cddefeac476bf642470f6404c5b3e9de26b00', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: '1486f5d26ba46b9acfbb82b5649071584cd9fc3e', class: "success-animation" }, h("div", { key: '0fadba687d56a9e143128568a39504b3fb1a5c4f', class: "check-icon" }), h("div", { key: 'b7302f6a559ff5ede1e49bef3efe0bd1f2ebe5dc', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: '08c9b49216719ac6c63bee3a0d9de5944af806be', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: '78bd1edfa9cc6c1525c927e2200bd239f153fa05', class: "status-spinner" })), h("div", { key: '38cc19e3cedbee2b2492cf896f3816c20f43f76c', class: "status-content" }, h("div", { key: '92280665b0f23d882ea64a9ef7316b679d33aa24', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: 'e2608bffb1430d565ea48ec4f3020320dd6df942', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: '70540ce4120a5e58477d27b9ada583d1bd08d173', class: "performance-monitor" }, h("div", { key: '9748bd765097226c6b83cfb11014addf50bc689a', class: "performance-expanded" }, h("div", { key: '232b42e1711cfc3fc5273570d342ca76dd9bd600', class: "metrics-row" }, h("div", { key: '582de2674be443604bc7ea1d0febac35f0b4d98c', class: "metric-compact" }, h("span", { key: 'd7814f7e32ca27bcd1262bf70d23e0f20de8f4fe', class: "metric-label" }, "FPS"), h("span", { key: '80d35b145b152d40a587b2f367dbb90d8410a51c', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: 'e34ab4ac393d65626e07f363de76bb4db0a6eb89', class: "metric-compact" }, h("span", { key: '47d544db4edd3f4ac9d84bdcafb3f24ecffdb53e', class: "metric-label" }, "MEM"), h("span", { key: 'd0d8d0e6bc2a868fdb6d9cfa8c7227e5a67c59db', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: '5b4d97625bf3ce6ff4b3f58c86f0b54b9426c3e1', class: "metrics-row" }, h("div", { key: 'a7523a1e08c6134d0660f7bda36036ce58c68f06', class: "metric-compact" }, h("span", { key: '7554b3f17b50e40aa03418beaa840a1b4ca54473', class: "metric-label" }, "INF"), h("span", { key: 'a3f0e2895bb9b889b927003257861998526460bf', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '43f4cc28e109d349049bb270710df4a31c8be775', class: "metric-compact" }, h("span", { key: '788fd432fafb1885ca6b090bf2c5f109de2a62f5', class: "metric-label" }, "FRAME"), h("span", { key: 'de30f8ea0068724999ea4e2541525131f7feff0e', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: 'ca1f57a73a26f3af81bb237e16ed2799ab20bcc5', class: "metrics-row" }, h("div", { key: '4ebc8c75f9e9a713e484774ecb33f277a93aae6a', class: "metric-compact" }, h("span", { key: 'b5e3342b69dc7066ef13959c4002ad77cd9602be', class: "metric-label" }, "DET"), h("span", { key: '3cddca746d3a028cbac6a2c716710e9f4e3cc9c3', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: '4896bcb120733c89a018b804c222209795585750', class: "metric-compact" }, h("span", { key: '512196bbf3ba72dbceebdd51c3a6cd6080d4ec57', class: "metric-label" }, "RATE"), h("span", { key: '78c2478d921ee99d8d990a573b2c90e2d593faf0', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: 'f2ebe3ed19749fe1db059b1cdca27283373c89da', class: "watermark" }, h("img", { key: 'e18b9458221d2f912e6d5280801476c0e35deb9c', 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
@@ -1040,7 +1085,7 @@ export class JaakStamps {
1040
1085
  "getter": false,
1041
1086
  "setter": false,
1042
1087
  "reflect": false,
1043
- "defaultValue": "20"
1088
+ "defaultValue": "15"
1044
1089
  },
1045
1090
  "maskSize": {
1046
1091
  "type": "number",
@@ -1140,7 +1185,47 @@ export class JaakStamps {
1140
1185
  "getter": false,
1141
1186
  "setter": false,
1142
1187
  "reflect": false,
1143
- "defaultValue": "1000"
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() {