@jaak.ai/stamps 2.5.6 → 2.5.7-dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/cjs/{index-D6NBn_qu.js → index-BcFBOmM6.js} +30 -4
  2. package/dist/cjs/index-BcFBOmM6.js.map +1 -0
  3. package/dist/cjs/jaak-stamps-webcomponent.cjs.js +2 -2
  4. package/dist/cjs/jaak-stamps.cjs.entry.js +124 -40
  5. package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -1
  6. package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -1
  7. package/dist/cjs/loader.cjs.js +2 -2
  8. package/dist/collection/collection-manifest.json +1 -1
  9. package/dist/collection/components/{my-component/my-component.js → jaak-stamps/jaak-stamps.js} +88 -34
  10. package/dist/collection/components/jaak-stamps/jaak-stamps.js.map +1 -0
  11. package/dist/collection/components/jaak-stamps/watermark-fallback.js.map +1 -0
  12. package/dist/collection/services/DetectionService.js +41 -6
  13. package/dist/collection/services/DetectionService.js.map +1 -1
  14. package/dist/components/index.js +20 -2
  15. package/dist/components/index.js.map +1 -1
  16. package/dist/components/jaak-stamps.js +126 -39
  17. package/dist/components/jaak-stamps.js.map +1 -1
  18. package/dist/esm/{index-BCfAsrzL.js → index-Cb0ILUvS.js} +30 -4
  19. package/dist/esm/index-Cb0ILUvS.js.map +1 -0
  20. package/dist/esm/jaak-stamps-webcomponent.js +3 -3
  21. package/dist/esm/jaak-stamps.entry.js +124 -40
  22. package/dist/esm/jaak-stamps.entry.js.map +1 -1
  23. package/dist/esm/loader.js +3 -3
  24. package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +1 -1
  25. package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -1
  26. package/dist/jaak-stamps-webcomponent/{p-5724f34b.entry.js → p-268577ba.entry.js} +3 -3
  27. package/dist/jaak-stamps-webcomponent/p-268577ba.entry.js.map +1 -0
  28. package/dist/jaak-stamps-webcomponent/p-Cb0ILUvS.js +3 -0
  29. package/dist/jaak-stamps-webcomponent/p-Cb0ILUvS.js.map +1 -0
  30. package/dist/types/components/{my-component/my-component.d.ts → jaak-stamps/jaak-stamps.d.ts} +5 -0
  31. package/dist/types/services/DetectionService.d.ts +5 -0
  32. package/package.json +4 -4
  33. package/dist/cjs/index-D6NBn_qu.js.map +0 -1
  34. package/dist/collection/components/my-component/my-component.js.map +0 -1
  35. package/dist/collection/components/my-component/watermark-fallback.js.map +0 -1
  36. package/dist/collection/utils/utils.js +0 -4
  37. package/dist/collection/utils/utils.js.map +0 -1
  38. package/dist/esm/index-BCfAsrzL.js.map +0 -1
  39. package/dist/jaak-stamps-webcomponent/p-5724f34b.entry.js.map +0 -1
  40. package/dist/jaak-stamps-webcomponent/p-BCfAsrzL.js +0 -3
  41. package/dist/jaak-stamps-webcomponent/p-BCfAsrzL.js.map +0 -1
  42. package/dist/types/utils/utils.d.ts +0 -1
  43. /package/dist/collection/components/{my-component/my-component.css → jaak-stamps/jaak-stamps.css} +0 -0
  44. /package/dist/collection/components/{my-component → jaak-stamps}/watermark-fallback.js +0 -0
  45. /package/dist/types/components/{my-component → jaak-stamps}/watermark-fallback.d.ts +0 -0
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-D6NBn_qu.js');
3
+ var index = require('./index-BcFBOmM6.js');
4
4
 
5
5
  class EventBusService {
6
6
  events = new Map();
@@ -824,7 +824,7 @@ class DetectionService {
824
824
  try {
825
825
  const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);
826
826
  try {
827
- this.session = await window.ort.InferenceSession.create(this.MODEL_PATH, sessionOptions);
827
+ this.session = await this.createSession(this.MODEL_PATH, sessionOptions);
828
828
  this.detectFloat16Support();
829
829
  }
830
830
  catch (error) {
@@ -839,7 +839,7 @@ class DetectionService {
839
839
  if (isFloat16Error) {
840
840
  this.useFloat16 = false;
841
841
  try {
842
- this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, sessionOptions);
842
+ this.session = await this.createSession(this.MODEL_PATH_FP32, sessionOptions);
843
843
  }
844
844
  catch (fp32Error) {
845
845
  // Intentar con opciones minimas de WASM
@@ -848,7 +848,7 @@ class DetectionService {
848
848
  graphOptimizationLevel: 'all',
849
849
  logSeverityLevel: this.debug ? 2 : 4,
850
850
  };
851
- this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, wasmOptions);
851
+ this.session = await this.createSession(this.MODEL_PATH_FP32, wasmOptions);
852
852
  }
853
853
  }
854
854
  else if (isMemoryError) {
@@ -867,7 +867,7 @@ class DetectionService {
867
867
  };
868
868
  this.useFloat16 = false;
869
869
  try {
870
- this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, fallbackOptions);
870
+ this.session = await this.createSession(this.MODEL_PATH_FP32, fallbackOptions);
871
871
  }
872
872
  catch (fallbackError) {
873
873
  throw new Error(`no available backend found. ERR: [wasm] RangeError: Out of memory`);
@@ -908,7 +908,7 @@ class DetectionService {
908
908
  // Load model
909
909
  const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);
910
910
  try {
911
- this.mobileNetSession = await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, sessionOptions);
911
+ this.mobileNetSession = await this.createSession(this.MOBILENET_MODEL_PATH, sessionOptions);
912
912
  }
913
913
  catch (error) {
914
914
  // Múltiples tipos de errores de memoria que pueden ocurrir
@@ -932,7 +932,7 @@ class DetectionService {
932
932
  sessionLogVerbosityLevel: 0,
933
933
  };
934
934
  try {
935
- this.mobileNetSession = await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, fallbackOptions);
935
+ this.mobileNetSession = await this.createSession(this.MOBILENET_MODEL_PATH, fallbackOptions);
936
936
  }
937
937
  catch (fallbackError) {
938
938
  throw new Error(`no available backend found. ERR: [wasm] RangeError: Out of memory`);
@@ -1124,6 +1124,41 @@ class DetectionService {
1124
1124
  areAllSidesAligned(alignment) {
1125
1125
  return alignment.top && alignment.right && alignment.bottom && alignment.left;
1126
1126
  }
1127
+ // Reference counter so concurrent sessions share one filter and the last
1128
+ // one to finish restores the original console.warn.
1129
+ static _ortWarnActiveCount = 0;
1130
+ static _originalWarn = null;
1131
+ static _acquireWarnFilter() {
1132
+ if (DetectionService._ortWarnActiveCount === 0) {
1133
+ DetectionService._originalWarn = console.warn;
1134
+ console.warn = (...args) => {
1135
+ const msg = typeof args[0] === 'string' ? args[0] : '';
1136
+ if (!msg.includes('removing requested execution provider')) {
1137
+ DetectionService._originalWarn.apply(console, args);
1138
+ }
1139
+ };
1140
+ }
1141
+ DetectionService._ortWarnActiveCount++;
1142
+ }
1143
+ static _releaseWarnFilter() {
1144
+ DetectionService._ortWarnActiveCount--;
1145
+ if (DetectionService._ortWarnActiveCount === 0 && DetectionService._originalWarn) {
1146
+ console.warn = DetectionService._originalWarn;
1147
+ DetectionService._originalWarn = null;
1148
+ }
1149
+ }
1150
+ async createSession(modelPath, options) {
1151
+ // Keep the filter active for the full await: ORT may emit
1152
+ // "removing requested execution provider" during async resolution,
1153
+ // not only in the synchronous preamble of create().
1154
+ DetectionService._acquireWarnFilter();
1155
+ try {
1156
+ return await window.ort.InferenceSession.create(modelPath, options);
1157
+ }
1158
+ finally {
1159
+ DetectionService._releaseWarnFilter();
1160
+ }
1161
+ }
1127
1162
  cleanup() {
1128
1163
  this.cleanupCanvasPool();
1129
1164
  if (this.session) {
@@ -18634,7 +18669,7 @@ class LicenseValidationService {
18634
18669
  }
18635
18670
  }
18636
18671
 
18637
- const myComponentCss = ":host{display:block;width:100%;height:100%;font-family:system-ui, -apple-system, sans-serif;color:#1a1a1a}.detector-container{display:flex;flex-direction:column;align-items:center;width:100%;height:100%}h1{font-size:24px;font-weight:500;color:#333;margin:0 0 24px 0}.video-container{position:relative;width:100%;height:100%;background-color:#000;border:none;border-radius:8px;overflow:hidden}video,.detection-overlay{position:absolute;width:100%;height:100%;border-radius:8px}video.mirror,.detection-overlay.mirror{transform:rotateY(180deg)}.detection-overlay{z-index:1;pointer-events:none}video{z-index:0}video::-webkit-media-controls{display:none !important}video::-webkit-media-controls-panel{display:none !important}video::-webkit-media-controls-play-button{display:none !important}video::-webkit-media-controls-start-playback-button{display:none !important}video::-webkit-media-controls-enclosure{display:none !important}.detection-box{transition:opacity 0.2s ease}.status{margin-top:16px;font-size:12px;color:#666}.overlay-mask{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10;display:block;pointer-events:none}.card-outline{position:absolute;top:var(--mask-center-y, 50%);left:var(--mask-center-x, 50%);transform:translate(-50%, -50%);width:var(--mask-width, 88%);height:var(--mask-height, 55%);border:none;border-radius:4px;background:transparent;opacity:0.8}.side{position:absolute;background:#999;transition:background-color 0.3s ease;border-radius:1px}.side-top.aligned{border-left-color:#28a745;border-top-color:#28a745}.side-right.aligned{border-right-color:#28a745;border-top-color:#28a745}.side-bottom.aligned{border-left-color:#28a745;border-bottom-color:#28a745}.side-left.aligned{border-right-color:#28a745;border-bottom-color:#28a745}.side-top{top:-3px;left:-3px;width:30px;height:30px;border-left:6px solid #ffffff;border-top:6px solid #ffffff;background:transparent}.side-right{top:-3px;right:-3px;width:30px;height:30px;border-right:6px solid #ffffff;border-top:6px solid #ffffff;background:transparent}.side-bottom{bottom:-3px;left:-3px;width:30px;height:30px;border-left:6px solid #ffffff;border-bottom:6px solid #ffffff;background:transparent}.side-left{bottom:-3px;right:-3px;width:30px;height:30px;border-right:6px solid #ffffff;border-bottom:6px solid #ffffff;background:transparent}.guide-text{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;border:1px solid rgba(255, 255, 255, 0.1);color:#ffffff;font-size:12px;font-weight:500;text-align:center;white-space:normal;padding:13px;max-width:300px;z-index:20;height:fit-content;width:fit-content;animation:slideInFromTopCentered 0.3s ease-out}.quality-indicator{position:absolute;top:20px;right:20px;display:flex;align-items:center;gap:8px;background:rgba(0, 0, 0, 0.8);padding:8px 12px;border-radius:20px;z-index:25;transition:all 0.3s ease}.quality-indicator.warning{background:rgba(255, 152, 0, 0.9)}.quality-indicator.good{background:rgba(76, 175, 80, 0.9)}.quality-score{color:#fff;font-size:12px;font-weight:600;min-width:30px;text-align:center}.quality-status{width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;color:#fff;transition:all 0.3s ease}.quality-status.ready{background:#4CAF50}.quality-status.not-ready{background:#f44336}.card-outline.quality-warning{animation:qualityWarning 1s ease-in-out infinite alternate}@keyframes qualityWarning{0%{box-shadow:0 0 0 3px rgba(255, 152, 0, 0.6)}100%{box-shadow:0 0 0 6px rgba(255, 152, 0, 0.3)}}.capture-animation{position:absolute;top:0;left:0;width:100%;height:100%;background:#fff;opacity:0;z-index:30;pointer-events:none;animation:captureFlash 0.6s ease-out}@keyframes captureFlash{0%{opacity:0}15%{opacity:0.8}30%{opacity:0}45%{opacity:0.4}60%{opacity:0}100%{opacity:0}}.card-outline.capturing{animation:pulseGreen 0.6s ease-out}@keyframes pulseGreen{0%{border-color:#28a745;box-shadow:0 0 0 4px rgba(40, 167, 69, 0)}50%{border-color:#28a745;box-shadow:0 0 0 8px rgba(40, 167, 69, 0.6)}100%{border-color:#28a745;box-shadow:0 0 0 4px rgba(40, 167, 69, 0)}}.flip-animation{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);z-index:35;pointer-events:none;opacity:0;animation:showFlipInstruction 3s ease-in-out;display:flex;flex-direction:column;align-items:center;justify-content:center}.id-card-icon{width:80px;height:50px;background:linear-gradient(135deg, #6c757d 0%, #495057 100%);border-radius:8px;position:relative;animation:flipCard 2s ease-in-out infinite;box-shadow:0 4px 12px rgba(0, 0, 0, 0.3)}.id-card-icon::before{content:'';position:absolute;top:8px;left:8px;width:16px;height:12px;background:rgba(255, 255, 255, 0.9);border-radius:2px}.id-card-icon::after{content:'';position:absolute;top:25px;left:8px;width:64px;height:3px;background:rgba(255, 255, 255, 0.7);border-radius:1px;box-shadow:0 6px 0 rgba(255, 255, 255, 0.7), 0 12px 0 rgba(255, 255, 255, 0.7)}.flip-text{margin-top:12px;color:#fff;font-size:14px;font-weight:600;text-align:center;background:rgba(128, 128, 128, 0.8);padding:12px 20px;border-radius:20px;max-width:300px}@keyframes showFlipInstruction{0%{opacity:0;transform:translate(-50%, -50%) scale(0.8)}15%{opacity:1;transform:translate(-50%, -50%) scale(1)}85%{opacity:1;transform:translate(-50%, -50%) scale(1)}100%{opacity:0;transform:translate(-50%, -50%) scale(0.8)}}@keyframes flipCard{0%{transform:rotateY(0deg)}50%{transform:rotateY(180deg)}100%{transform:rotateY(360deg)}}.success-animation{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);z-index:35;pointer-events:none;opacity:0;animation:showSuccessMessage 3s ease-in-out;display:flex;flex-direction:column;align-items:center;justify-content:center}.check-icon{width:80px;height:80px;background:linear-gradient(135deg, #6c757d 0%, #495057 100%);border-radius:50%;position:relative;animation:bounceSuccess 0.6s ease-out;box-shadow:0 4px 16px rgba(108, 117, 125, 0.4);display:flex;align-items:center;justify-content:center}.check-icon::before{content:'';position:absolute;width:20px;height:35px;border:4px solid #fff;border-top:none;border-left:none;transform:rotate(45deg);}.success-text{margin-top:16px;color:#fff;font-size:14px;font-weight:600;text-align:center;background:rgba(128, 128, 128, 0.8);padding:12px 20px;border-radius:20px;max-width:300px;animation:fadeInUp 0.5s ease-out 0.4s both}@keyframes showSuccessMessage{0%{opacity:0;transform:translate(-50%, -50%) scale(0.5)}15%{opacity:1;transform:translate(-50%, -50%) scale(1)}85%{opacity:1;transform:translate(-50%, -50%) scale(1)}100%{opacity:0;transform:translate(-50%, -50%) scale(0.9)}}@keyframes bounceSuccess{0%{transform:scale(0)}50%{transform:scale(1.1)}100%{transform:scale(1)}}@keyframes drawCheck{0%{width:0;height:0}50%{width:20px;height:0}100%{width:20px;height:35px}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}100%{opacity:1;transform:translateY(0)}}.skip-section{position:absolute;bottom:20px;left:50%;transform:translateX(-50%);z-index:25;display:flex;flex-direction:column;align-items:center;width:100%;max-width:300px}.back-capture-section{position:absolute;bottom:20px;left:50%;transform:translateX(-50%);z-index:25;display:flex;flex-direction:column;align-items:center;width:100%;max-width:320px}.back-capture-buttons{display:flex;gap:12px;align-items:center;justify-content:center;flex-wrap:wrap}.capture-button{pointer-events:auto;background:#fff;color:#333;border:none;border-radius:25px;padding:12px 24px;font-size:14px;font-weight:600;cursor:pointer;transition:all 0.3s ease}.capture-button:hover{background:#f8f9fa}.capture-button:active{background:#e9ecef;transform:translateY(1px)}.capture-button:disabled,.capture-button.primary-button:disabled{cursor:not-allowed !important;transform:none !important;opacity:0.7 !important;transition:none !important}@media (max-width: 480px){.back-capture-section{bottom:16px;max-width:300px}.back-capture-buttons{flex-direction:column;gap:8px;width:100%}.capture-button,.back-capture-buttons .skip-button{width:100%;max-width:200px;padding:10px 20px;font-size:13px}.capture-button:disabled,.capture-button.primary-button:disabled,.skip-button:disabled{opacity:0.7 !important;cursor:not-allowed !important}}.skip-explanation{background:rgba(0, 0, 0, 0.5);color:#ffffff;padding:10px 16px;border-radius:8px;font-size:14px;font-weight:500;text-align:center;margin-bottom:12px;box-shadow:0 2px 8px rgba(0, 0, 0, 0.2);backdrop-filter:blur(12px);border:1px solid rgba(255, 255, 255, 0.1);animation:fadeIn 0.3s ease-in-out}@keyframes fadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.guide-text.performance-warning-text{animation:gentlePulse 2s ease-in-out infinite;background:rgba(255, 107, 107, 0.3);border:1px solid rgba(255, 107, 107, 0.5)}@keyframes gentlePulse{0%,100%{transform:translate(-50%, -50%) scale(1);background:rgba(255, 107, 107, 0.3)}50%{transform:translate(-50%, -50%) scale(1.02);background:rgba(255, 107, 107, 0.4)}}.skip-button{pointer-events:auto;background:#fff;color:#333;border:none;border-radius:25px;padding:12px 24px;font-size:14px;font-weight:600;cursor:pointer;transition:all 0.3s ease}.skip-button:hover{background:#f8f9fa}.skip-button:active{background:#e9ecef;transform:translateY(1px)}.skip-button:disabled{cursor:not-allowed !important;transform:none !important;opacity:0.7 !important;transition:none !important}.camera-controls{position:absolute;top:16px;right:16px;z-index:25;display:flex;gap:8px;pointer-events:auto;animation:slideInFromTop 0.3s ease-out}.camera-selector-button{height:32px;padding:0 10px;border:none;border-radius:8px;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(12px);color:#ffffff;font-size:12px;font-weight:500;cursor:pointer;transition:all 0.2s ease;display:flex;align-items:center;justify-content:center;border:1px solid rgba(255, 255, 255, 0.1);white-space:nowrap;min-width:fit-content}.camera-selector-button:hover{background:rgba(0, 0, 0, 0.8);border-color:rgba(255, 255, 255, 0.2);transform:translateY(-1px)}.camera-selector-button:active{transform:translateY(0);background:rgba(0, 0, 0, 0.9)}.camera-selector-button:disabled,.camera-selector-button.loading{opacity:0.7;cursor:not-allowed;pointer-events:none}.camera-selector-button:disabled:hover,.camera-selector-button.loading:hover{transform:none;background:rgba(0, 0, 0, 0.6);border-color:rgba(255, 255, 255, 0.1)}.button-spinner{width:16px;height:16px;border:2px solid rgba(0, 0, 0, 0.2);border-top:2px solid #333333;border-radius:50%;animation:spin 1s linear infinite;display:inline-block;margin-right:8px;vertical-align:middle}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.camera-selector-dropdown{position:absolute;top:56px;right:16px;z-index:30;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;min-width:260px;max-width:300px;border:1px solid rgba(255, 255, 255, 0.1);overflow:hidden;pointer-events:auto;animation:slideInFromTop 0.3s ease-out}@keyframes slideInFromTop{0%{opacity:0;transform:translateY(-8px) scale(0.95)}100%{opacity:1;transform:translateY(0) scale(1)}}@keyframes slideInFromTopCentered{0%{opacity:0;transform:translate(-50%, -50%) translateY(-8px) scale(0.95)}100%{opacity:1;transform:translate(-50%, -50%) translateY(0) scale(1)}}.camera-selector-header{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;border-bottom:1px solid rgba(255, 255, 255, 0.1)}.camera-selector-header span{font-weight:500;color:#ffffff;font-size:13px;opacity:0.9}.close-selector{width:20px;height:20px;border:none;background:none;color:rgba(255, 255, 255, 0.7);font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:all 0.2s ease}.close-selector:hover{background:rgba(255, 255, 255, 0.1);color:#ffffff}.camera-list{padding:4px 0;max-height:240px;overflow-y:auto}.camera-option{width:100%;padding:8px 12px;border:none;background:none;text-align:left;cursor:pointer;transition:all 0.2s ease;display:flex;justify-content:flex-start;align-items:center;gap:8px;color:rgba(255, 255, 255, 0.9)}.camera-option:hover{background:rgba(255, 255, 255, 0.08)}.camera-option.selected{background:rgba(255, 255, 255, 0.12);color:#ffffff}.camera-label{font-size:13px;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-right:0;font-weight:400;display:flex;align-items:center;gap:6px}.camera-label .autofocus-icon{font-size:12px;color:#ffffff !important;opacity:0.8;flex-shrink:0}.selected-indicator{font-size:14px;color:#ffffff;opacity:0.9;flex-shrink:0}.device-info{padding:6px 12px;border-top:1px solid rgba(255, 255, 255, 0.1);background:rgba(255, 255, 255, 0.05)}.device-info small{color:rgba(255, 255, 255, 0.6);font-size:11px;text-transform:capitalize;font-weight:400}@media (max-width: 480px){.camera-controls{top:12px;right:12px;gap:6px}.camera-selector-button{height:36px;padding:0 12px;font-size:11px;border-radius:6px}.camera-selector-dropdown{right:12px;top:48px;min-width:240px;max-width:calc(100vw - 24px)}.camera-selector-header{padding:6px 10px}.camera-option{padding:6px 10px}.device-info{padding:4px 10px}}.watermark{position:absolute;bottom:12px;right:12px;z-index:15;pointer-events:none;opacity:0.7}.watermark img{height:24px;width:auto;filter:drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3))}.component-status{position:absolute;top:16px;left:16px;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;border:1px solid rgba(255, 255, 255, 0.1);display:flex;align-items:center;gap:6px;padding:6px 10px;z-index:40;height:32px;width:fit-content;animation:slideInFromTop 0.3s ease-out}.status-spinner{width:16px;height:16px;border:1px solid rgba(255, 255, 255, 0.3);border-top:1px solid #ffffff;border-radius:50%;animation:statusSpin 1s linear infinite;flex-shrink:0}.status-content{display:flex;flex-direction:column;gap:1px}.status-message{color:#ffffff;font-size:12px;font-weight:500;margin:0}.status-description{color:rgba(255, 255, 255, 0.7);font-size:10px;line-height:1.2;margin:0}@keyframes statusSpin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@media (max-width: 480px){.component-status{top:12px;left:12px;padding:4px 8px;gap:4px;height:28px;border-radius:8px}.status-spinner{width:14px;height:14px}.status-message{font-size:11px}.status-description{font-size:9px}.guide-text{font-size:11px;padding:4px 8px;border-radius:8px}}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0, 0, 0, 0.85);backdrop-filter:blur(4px);display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:30;border-radius:8px}.loading-spinner{width:50px;height:50px;border:3px solid rgba(255, 255, 255, 0.15);border-top:3px solid #28a745;border-radius:50%;animation:spin 1s ease-in-out infinite;margin-bottom:16px}.loading-text{color:#ffffff;font-size:14px;font-weight:500;text-align:center;opacity:0.9;margin-bottom:4px}.loading-description{color:rgba(255, 255, 255, 0.7);font-size:12px;text-align:center;opacity:0.8}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.performance-monitor{position:absolute;top:70px;left:16px;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;border:1px solid rgba(255, 255, 255, 0.1);z-index:35;width:fit-content;animation:slideInFromTop 0.3s ease-out;transition:all 0.3s ease}@keyframes slideInFromLeft{0%{opacity:0;transform:translateX(-20px) scale(0.95)}100%{opacity:1;transform:translateX(0) scale(1)}}.performance-expanded{padding:6px 10px}.metrics-row{display:flex;gap:8px;margin-bottom:4px}.metrics-row:last-child{margin-bottom:0}.metric-compact{display:flex;flex-direction:column;align-items:center;gap:2px;min-width:50px}.metric-label{font-size:9px;color:rgba(255, 255, 255, 0.6);font-weight:500;text-transform:uppercase;letter-spacing:0.3px}.metric-value{font-size:10px;font-weight:600;font-family:'Monaco', 'Menlo', 'Consolas', monospace;padding:2px 4px;border-radius:3px;text-align:center;white-space:nowrap}.metric-value.good{color:#4ade80;background:rgba(74, 222, 128, 0.1);border:1px solid rgba(74, 222, 128, 0.2)}.metric-value.warning{color:#fbbf24;background:rgba(251, 191, 36, 0.1);border:1px solid rgba(251, 191, 36, 0.2)}.metric-value.danger{color:#f87171;background:rgba(248, 113, 113, 0.1);border:1px solid rgba(248, 113, 113, 0.2)}@media (max-width: 480px){.performance-monitor{top:60px;left:12px;width:fit-content}.performance-expanded{padding:4px 8px}.metrics-row{gap:6px;margin-bottom:3px}.metric-compact{min-width:45px;gap:1px}.metric-label{font-size:8px}.metric-value{font-size:9px;padding:1px 3px}}.quality-monitor{position:absolute;top:200px;left:16px;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;border:1px solid rgba(255, 255, 255, 0.1);z-index:35;width:fit-content;animation:slideInFromLeft 0.3s ease-out;transition:all 0.3s ease}.quality-text{padding:6px 10px;font-size:11px;color:white;font-family:'Monaco', 'Menlo', 'Consolas', monospace;line-height:1.4}.quality-fail{color:#ff9999}@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.7}}.metric-value.danger{animation:pulse 2s infinite}@media (max-width: 480px){.quality-monitor{top:160px;left:12px}.quality-text{padding:4px 8px;font-size:10px}}.manual-capture-section{position:absolute;bottom:20px;left:50%;transform:translateX(-50%);z-index:25;display:flex;flex-direction:column;align-items:center;width:100%;max-width:300px}.manual-capture-button{pointer-events:auto;background:#fff;color:#333;border:none;border-radius:25px;padding:12px 24px;font-size:14px;font-weight:600;cursor:pointer;transition:all 0.3s ease}.manual-capture-button:hover{background:#f8f9fa}.manual-capture-button:active{background:#e9ecef;transform:translateY(1px)}.manual-capture-button:disabled{cursor:not-allowed !important;transform:none !important;opacity:0.7 !important;transition:none !important}@media (max-width: 480px){.manual-capture-section{bottom:16px;max-width:280px}.manual-capture-button{padding:10px 20px;font-size:13px}.manual-capture-button:disabled{opacity:0.7 !important;cursor:not-allowed !important}}.license-error-container{display:flex;align-items:center;justify-content:center;padding:40px 20px;height:100%;width:100%;background:#f5f7fa;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif}.license-error-card{background:#ffffff;border-radius:8px;box-shadow:0 2px 12px rgba(0, 0, 0, 0.1);max-width:480px;width:100%;padding:48px 32px;text-align:center}.license-error-icon{color:#dc3545;margin-bottom:24px}.license-error-title{color:#2c3e50;font-size:24px;font-weight:600;margin:0 0 16px 0}.license-error-message{color:#495057;font-size:16px;line-height:1.6;margin:0 0 24px 0}.license-error-help{color:#6c757d;font-size:14px;margin:0 0 32px 0}.license-error-help a{color:#007bff;text-decoration:none;font-weight:500}.license-error-help a:hover{text-decoration:underline}.license-error-footer{color:#adb5bd;font-size:12px;font-weight:500;padding-top:24px;border-top:1px solid #e9ecef}@media (max-width: 640px){.license-error-card{padding:32px 24px}.license-error-title{font-size:20px}.license-error-message{font-size:14px}}";
18672
+ const jaakStampsCss = ":host{display:block;width:100%;height:100%;font-family:system-ui, -apple-system, sans-serif;color:#1a1a1a}.detector-container{display:flex;flex-direction:column;align-items:center;width:100%;height:100%}h1{font-size:24px;font-weight:500;color:#333;margin:0 0 24px 0}.video-container{position:relative;width:100%;height:100%;background-color:#000;border:none;border-radius:8px;overflow:hidden}video,.detection-overlay{position:absolute;width:100%;height:100%;border-radius:8px}video.mirror,.detection-overlay.mirror{transform:rotateY(180deg)}.detection-overlay{z-index:1;pointer-events:none}video{z-index:0}video::-webkit-media-controls{display:none !important}video::-webkit-media-controls-panel{display:none !important}video::-webkit-media-controls-play-button{display:none !important}video::-webkit-media-controls-start-playback-button{display:none !important}video::-webkit-media-controls-enclosure{display:none !important}.detection-box{transition:opacity 0.2s ease}.status{margin-top:16px;font-size:12px;color:#666}.overlay-mask{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10;display:block;pointer-events:none}.card-outline{position:absolute;top:var(--mask-center-y, 50%);left:var(--mask-center-x, 50%);transform:translate(-50%, -50%);width:var(--mask-width, 88%);height:var(--mask-height, 55%);border:none;border-radius:4px;background:transparent;opacity:0.8}.side{position:absolute;background:#999;transition:background-color 0.3s ease;border-radius:1px}.side-top.aligned{border-left-color:#28a745;border-top-color:#28a745}.side-right.aligned{border-right-color:#28a745;border-top-color:#28a745}.side-bottom.aligned{border-left-color:#28a745;border-bottom-color:#28a745}.side-left.aligned{border-right-color:#28a745;border-bottom-color:#28a745}.side-top{top:-3px;left:-3px;width:30px;height:30px;border-left:6px solid #ffffff;border-top:6px solid #ffffff;background:transparent}.side-right{top:-3px;right:-3px;width:30px;height:30px;border-right:6px solid #ffffff;border-top:6px solid #ffffff;background:transparent}.side-bottom{bottom:-3px;left:-3px;width:30px;height:30px;border-left:6px solid #ffffff;border-bottom:6px solid #ffffff;background:transparent}.side-left{bottom:-3px;right:-3px;width:30px;height:30px;border-right:6px solid #ffffff;border-bottom:6px solid #ffffff;background:transparent}.guide-text{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;border:1px solid rgba(255, 255, 255, 0.1);color:#ffffff;font-size:12px;font-weight:500;text-align:center;white-space:normal;padding:13px;max-width:300px;z-index:20;height:fit-content;width:fit-content;animation:slideInFromTopCentered 0.3s ease-out}.quality-indicator{position:absolute;top:20px;right:20px;display:flex;align-items:center;gap:8px;background:rgba(0, 0, 0, 0.8);padding:8px 12px;border-radius:20px;z-index:25;transition:all 0.3s ease}.quality-indicator.warning{background:rgba(255, 152, 0, 0.9)}.quality-indicator.good{background:rgba(76, 175, 80, 0.9)}.quality-score{color:#fff;font-size:12px;font-weight:600;min-width:30px;text-align:center}.quality-status{width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;color:#fff;transition:all 0.3s ease}.quality-status.ready{background:#4CAF50}.quality-status.not-ready{background:#f44336}.card-outline.quality-warning{animation:qualityWarning 1s ease-in-out infinite alternate}@keyframes qualityWarning{0%{box-shadow:0 0 0 3px rgba(255, 152, 0, 0.6)}100%{box-shadow:0 0 0 6px rgba(255, 152, 0, 0.3)}}.capture-animation{position:absolute;top:0;left:0;width:100%;height:100%;background:#fff;opacity:0;z-index:30;pointer-events:none;animation:captureFlash 0.6s ease-out}@keyframes captureFlash{0%{opacity:0}15%{opacity:0.8}30%{opacity:0}45%{opacity:0.4}60%{opacity:0}100%{opacity:0}}.card-outline.capturing{animation:pulseGreen 0.6s ease-out}@keyframes pulseGreen{0%{border-color:#28a745;box-shadow:0 0 0 4px rgba(40, 167, 69, 0)}50%{border-color:#28a745;box-shadow:0 0 0 8px rgba(40, 167, 69, 0.6)}100%{border-color:#28a745;box-shadow:0 0 0 4px rgba(40, 167, 69, 0)}}.flip-animation{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);z-index:35;pointer-events:none;opacity:0;animation:showFlipInstruction 3s ease-in-out;display:flex;flex-direction:column;align-items:center;justify-content:center}.id-card-icon{width:80px;height:50px;background:linear-gradient(135deg, #6c757d 0%, #495057 100%);border-radius:8px;position:relative;animation:flipCard 2s ease-in-out infinite;box-shadow:0 4px 12px rgba(0, 0, 0, 0.3)}.id-card-icon::before{content:'';position:absolute;top:8px;left:8px;width:16px;height:12px;background:rgba(255, 255, 255, 0.9);border-radius:2px}.id-card-icon::after{content:'';position:absolute;top:25px;left:8px;width:64px;height:3px;background:rgba(255, 255, 255, 0.7);border-radius:1px;box-shadow:0 6px 0 rgba(255, 255, 255, 0.7), 0 12px 0 rgba(255, 255, 255, 0.7)}.flip-text{margin-top:12px;color:#fff;font-size:14px;font-weight:600;text-align:center;background:rgba(128, 128, 128, 0.8);padding:12px 20px;border-radius:20px;max-width:300px}@keyframes showFlipInstruction{0%{opacity:0;transform:translate(-50%, -50%) scale(0.8)}15%{opacity:1;transform:translate(-50%, -50%) scale(1)}85%{opacity:1;transform:translate(-50%, -50%) scale(1)}100%{opacity:0;transform:translate(-50%, -50%) scale(0.8)}}@keyframes flipCard{0%{transform:rotateY(0deg)}50%{transform:rotateY(180deg)}100%{transform:rotateY(360deg)}}.success-animation{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);z-index:35;pointer-events:none;opacity:0;animation:showSuccessMessage 3s ease-in-out;display:flex;flex-direction:column;align-items:center;justify-content:center}.check-icon{width:80px;height:80px;background:linear-gradient(135deg, #6c757d 0%, #495057 100%);border-radius:50%;position:relative;animation:bounceSuccess 0.6s ease-out;box-shadow:0 4px 16px rgba(108, 117, 125, 0.4);display:flex;align-items:center;justify-content:center}.check-icon::before{content:'';position:absolute;width:20px;height:35px;border:4px solid #fff;border-top:none;border-left:none;transform:rotate(45deg);}.success-text{margin-top:16px;color:#fff;font-size:14px;font-weight:600;text-align:center;background:rgba(128, 128, 128, 0.8);padding:12px 20px;border-radius:20px;max-width:300px;animation:fadeInUp 0.5s ease-out 0.4s both}@keyframes showSuccessMessage{0%{opacity:0;transform:translate(-50%, -50%) scale(0.5)}15%{opacity:1;transform:translate(-50%, -50%) scale(1)}85%{opacity:1;transform:translate(-50%, -50%) scale(1)}100%{opacity:0;transform:translate(-50%, -50%) scale(0.9)}}@keyframes bounceSuccess{0%{transform:scale(0)}50%{transform:scale(1.1)}100%{transform:scale(1)}}@keyframes drawCheck{0%{width:0;height:0}50%{width:20px;height:0}100%{width:20px;height:35px}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}100%{opacity:1;transform:translateY(0)}}.skip-section{position:absolute;bottom:20px;left:50%;transform:translateX(-50%);z-index:25;display:flex;flex-direction:column;align-items:center;width:100%;max-width:300px}.back-capture-section{position:absolute;bottom:20px;left:50%;transform:translateX(-50%);z-index:25;display:flex;flex-direction:column;align-items:center;width:100%;max-width:320px}.back-capture-buttons{display:flex;gap:12px;align-items:center;justify-content:center;flex-wrap:wrap}.capture-button{pointer-events:auto;background:#fff;color:#333;border:none;border-radius:25px;padding:12px 24px;font-size:14px;font-weight:600;cursor:pointer;transition:all 0.3s ease}.capture-button:hover{background:#f8f9fa}.capture-button:active{background:#e9ecef;transform:translateY(1px)}.capture-button:disabled,.capture-button.primary-button:disabled{cursor:not-allowed !important;transform:none !important;opacity:0.7 !important;transition:none !important}@media (max-width: 480px){.back-capture-section{bottom:16px;max-width:300px}.back-capture-buttons{flex-direction:column;gap:8px;width:100%}.capture-button,.back-capture-buttons .skip-button{width:100%;max-width:200px;padding:10px 20px;font-size:13px}.capture-button:disabled,.capture-button.primary-button:disabled,.skip-button:disabled{opacity:0.7 !important;cursor:not-allowed !important}}.skip-explanation{background:rgba(0, 0, 0, 0.5);color:#ffffff;padding:10px 16px;border-radius:8px;font-size:14px;font-weight:500;text-align:center;margin-bottom:12px;box-shadow:0 2px 8px rgba(0, 0, 0, 0.2);backdrop-filter:blur(12px);border:1px solid rgba(255, 255, 255, 0.1);animation:fadeIn 0.3s ease-in-out}@keyframes fadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.guide-text.performance-warning-text{animation:gentlePulse 2s ease-in-out infinite;background:rgba(255, 107, 107, 0.3);border:1px solid rgba(255, 107, 107, 0.5)}@keyframes gentlePulse{0%,100%{transform:translate(-50%, -50%) scale(1);background:rgba(255, 107, 107, 0.3)}50%{transform:translate(-50%, -50%) scale(1.02);background:rgba(255, 107, 107, 0.4)}}.skip-button{pointer-events:auto;background:#fff;color:#333;border:none;border-radius:25px;padding:12px 24px;font-size:14px;font-weight:600;cursor:pointer;transition:all 0.3s ease}.skip-button:hover{background:#f8f9fa}.skip-button:active{background:#e9ecef;transform:translateY(1px)}.skip-button:disabled{cursor:not-allowed !important;transform:none !important;opacity:0.7 !important;transition:none !important}.camera-controls{position:absolute;top:16px;right:16px;z-index:25;display:flex;gap:8px;pointer-events:auto;animation:slideInFromTop 0.3s ease-out}.camera-selector-button{height:32px;padding:0 10px;border:none;border-radius:8px;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(12px);color:#ffffff;font-size:12px;font-weight:500;cursor:pointer;transition:all 0.2s ease;display:flex;align-items:center;justify-content:center;border:1px solid rgba(255, 255, 255, 0.1);white-space:nowrap;min-width:fit-content}.camera-selector-button:hover{background:rgba(0, 0, 0, 0.8);border-color:rgba(255, 255, 255, 0.2);transform:translateY(-1px)}.camera-selector-button:active{transform:translateY(0);background:rgba(0, 0, 0, 0.9)}.camera-selector-button:disabled,.camera-selector-button.loading{opacity:0.7;cursor:not-allowed;pointer-events:none}.camera-selector-button:disabled:hover,.camera-selector-button.loading:hover{transform:none;background:rgba(0, 0, 0, 0.6);border-color:rgba(255, 255, 255, 0.1)}.button-spinner{width:16px;height:16px;border:2px solid rgba(0, 0, 0, 0.2);border-top:2px solid #333333;border-radius:50%;animation:spin 1s linear infinite;display:inline-block;margin-right:8px;vertical-align:middle}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.camera-selector-dropdown{position:absolute;top:56px;right:16px;z-index:30;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;min-width:260px;max-width:300px;border:1px solid rgba(255, 255, 255, 0.1);overflow:hidden;pointer-events:auto;animation:slideInFromTop 0.3s ease-out}@keyframes slideInFromTop{0%{opacity:0;transform:translateY(-8px) scale(0.95)}100%{opacity:1;transform:translateY(0) scale(1)}}@keyframes slideInFromTopCentered{0%{opacity:0;transform:translate(-50%, -50%) translateY(-8px) scale(0.95)}100%{opacity:1;transform:translate(-50%, -50%) translateY(0) scale(1)}}.camera-selector-header{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;border-bottom:1px solid rgba(255, 255, 255, 0.1)}.camera-selector-header span{font-weight:500;color:#ffffff;font-size:13px;opacity:0.9}.close-selector{width:20px;height:20px;border:none;background:none;color:rgba(255, 255, 255, 0.7);font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:all 0.2s ease}.close-selector:hover{background:rgba(255, 255, 255, 0.1);color:#ffffff}.camera-list{padding:4px 0;max-height:240px;overflow-y:auto}.camera-option{width:100%;padding:8px 12px;border:none;background:none;text-align:left;cursor:pointer;transition:all 0.2s ease;display:flex;justify-content:flex-start;align-items:center;gap:8px;color:rgba(255, 255, 255, 0.9)}.camera-option:hover{background:rgba(255, 255, 255, 0.08)}.camera-option.selected{background:rgba(255, 255, 255, 0.12);color:#ffffff}.camera-label{font-size:13px;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-right:0;font-weight:400;display:flex;align-items:center;gap:6px}.camera-label .autofocus-icon{font-size:12px;color:#ffffff !important;opacity:0.8;flex-shrink:0}.selected-indicator{font-size:14px;color:#ffffff;opacity:0.9;flex-shrink:0}.device-info{padding:6px 12px;border-top:1px solid rgba(255, 255, 255, 0.1);background:rgba(255, 255, 255, 0.05)}.device-info small{color:rgba(255, 255, 255, 0.6);font-size:11px;text-transform:capitalize;font-weight:400}@media (max-width: 480px){.camera-controls{top:12px;right:12px;gap:6px}.camera-selector-button{height:36px;padding:0 12px;font-size:11px;border-radius:6px}.camera-selector-dropdown{right:12px;top:48px;min-width:240px;max-width:calc(100vw - 24px)}.camera-selector-header{padding:6px 10px}.camera-option{padding:6px 10px}.device-info{padding:4px 10px}}.watermark{position:absolute;bottom:12px;right:12px;z-index:15;pointer-events:none;opacity:0.7}.watermark img{height:24px;width:auto;filter:drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3))}.component-status{position:absolute;top:16px;left:16px;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;border:1px solid rgba(255, 255, 255, 0.1);display:flex;align-items:center;gap:6px;padding:6px 10px;z-index:40;height:32px;width:fit-content;animation:slideInFromTop 0.3s ease-out}.status-spinner{width:16px;height:16px;border:1px solid rgba(255, 255, 255, 0.3);border-top:1px solid #ffffff;border-radius:50%;animation:statusSpin 1s linear infinite;flex-shrink:0}.status-content{display:flex;flex-direction:column;gap:1px}.status-message{color:#ffffff;font-size:12px;font-weight:500;margin:0}.status-description{color:rgba(255, 255, 255, 0.7);font-size:10px;line-height:1.2;margin:0}@keyframes statusSpin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@media (max-width: 480px){.component-status{top:12px;left:12px;padding:4px 8px;gap:4px;height:28px;border-radius:8px}.status-spinner{width:14px;height:14px}.status-message{font-size:11px}.status-description{font-size:9px}.guide-text{font-size:11px;padding:4px 8px;border-radius:8px}}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0, 0, 0, 0.85);backdrop-filter:blur(4px);display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:30;border-radius:8px}.loading-spinner{width:50px;height:50px;border:3px solid rgba(255, 255, 255, 0.15);border-top:3px solid #28a745;border-radius:50%;animation:spin 1s ease-in-out infinite;margin-bottom:16px}.loading-text{color:#ffffff;font-size:14px;font-weight:500;text-align:center;opacity:0.9;margin-bottom:4px}.loading-description{color:rgba(255, 255, 255, 0.7);font-size:12px;text-align:center;opacity:0.8}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.performance-monitor{position:absolute;top:70px;left:16px;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;border:1px solid rgba(255, 255, 255, 0.1);z-index:35;width:fit-content;animation:slideInFromTop 0.3s ease-out;transition:all 0.3s ease}@keyframes slideInFromLeft{0%{opacity:0;transform:translateX(-20px) scale(0.95)}100%{opacity:1;transform:translateX(0) scale(1)}}.performance-expanded{padding:6px 10px}.metrics-row{display:flex;gap:8px;margin-bottom:4px}.metrics-row:last-child{margin-bottom:0}.metric-compact{display:flex;flex-direction:column;align-items:center;gap:2px;min-width:50px}.metric-label{font-size:9px;color:rgba(255, 255, 255, 0.6);font-weight:500;text-transform:uppercase;letter-spacing:0.3px}.metric-value{font-size:10px;font-weight:600;font-family:'Monaco', 'Menlo', 'Consolas', monospace;padding:2px 4px;border-radius:3px;text-align:center;white-space:nowrap}.metric-value.good{color:#4ade80;background:rgba(74, 222, 128, 0.1);border:1px solid rgba(74, 222, 128, 0.2)}.metric-value.warning{color:#fbbf24;background:rgba(251, 191, 36, 0.1);border:1px solid rgba(251, 191, 36, 0.2)}.metric-value.danger{color:#f87171;background:rgba(248, 113, 113, 0.1);border:1px solid rgba(248, 113, 113, 0.2)}@media (max-width: 480px){.performance-monitor{top:60px;left:12px;width:fit-content}.performance-expanded{padding:4px 8px}.metrics-row{gap:6px;margin-bottom:3px}.metric-compact{min-width:45px;gap:1px}.metric-label{font-size:8px}.metric-value{font-size:9px;padding:1px 3px}}.quality-monitor{position:absolute;top:200px;left:16px;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;border:1px solid rgba(255, 255, 255, 0.1);z-index:35;width:fit-content;animation:slideInFromLeft 0.3s ease-out;transition:all 0.3s ease}.quality-text{padding:6px 10px;font-size:11px;color:white;font-family:'Monaco', 'Menlo', 'Consolas', monospace;line-height:1.4}.quality-fail{color:#ff9999}@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.7}}.metric-value.danger{animation:pulse 2s infinite}@media (max-width: 480px){.quality-monitor{top:160px;left:12px}.quality-text{padding:4px 8px;font-size:10px}}.manual-capture-section{position:absolute;bottom:20px;left:50%;transform:translateX(-50%);z-index:25;display:flex;flex-direction:column;align-items:center;width:100%;max-width:300px}.manual-capture-button{pointer-events:auto;background:#fff;color:#333;border:none;border-radius:25px;padding:12px 24px;font-size:14px;font-weight:600;cursor:pointer;transition:all 0.3s ease}.manual-capture-button:hover{background:#f8f9fa}.manual-capture-button:active{background:#e9ecef;transform:translateY(1px)}.manual-capture-button:disabled{cursor:not-allowed !important;transform:none !important;opacity:0.7 !important;transition:none !important}@media (max-width: 480px){.manual-capture-section{bottom:16px;max-width:280px}.manual-capture-button{padding:10px 20px;font-size:13px}.manual-capture-button:disabled{opacity:0.7 !important;cursor:not-allowed !important}}.license-error-container{display:flex;align-items:center;justify-content:center;padding:40px 20px;height:100%;width:100%;background:#f5f7fa;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif}.license-error-card{background:#ffffff;border-radius:8px;box-shadow:0 2px 12px rgba(0, 0, 0, 0.1);max-width:480px;width:100%;padding:48px 32px;text-align:center}.license-error-icon{color:#dc3545;margin-bottom:24px}.license-error-title{color:#2c3e50;font-size:24px;font-weight:600;margin:0 0 16px 0}.license-error-message{color:#495057;font-size:16px;line-height:1.6;margin:0 0 24px 0}.license-error-help{color:#6c757d;font-size:14px;margin:0 0 32px 0}.license-error-help a{color:#007bff;text-decoration:none;font-weight:500}.license-error-help a:hover{text-decoration:underline}.license-error-footer{color:#adb5bd;font-size:12px;font-weight:500;padding-top:24px;border-top:1px solid #e9ecef}@media (max-width: 640px){.license-error-card{padding:32px 24px}.license-error-title{font-size:20px}.license-error-message{font-size:14px}}";
18638
18673
 
18639
18674
  const JaakStamps = class {
18640
18675
  constructor(hostRef) {
@@ -18664,7 +18699,7 @@ const JaakStamps = class {
18664
18699
  propagateTraceHeaderCorsUrls; // Comma-separated URLs or regex patterns
18665
18700
  metricsExportIntervalMillis = 60000; // Export metrics every 60 seconds
18666
18701
  license; // License key for validation
18667
- licenseEnvironment = 'prod'; // Environment for license validation
18702
+ licenseEnvironment = 'prod';
18668
18703
  traceId; // Optional trace ID for tracking
18669
18704
  appId = 'jaak-stamps-web'; // Application ID for license validation
18670
18705
  captureCompleted;
@@ -18712,6 +18747,8 @@ const JaakStamps = class {
18712
18747
  licenseValid = true; // License validation status
18713
18748
  licenseError = null; // License validation error message
18714
18749
  classificationDisabled = false; // Classification disabled at runtime due to errors
18750
+ _initialized = false;
18751
+ _initializing = false;
18715
18752
  // Services
18716
18753
  licenseValidationService = null;
18717
18754
  serviceContainer;
@@ -18781,8 +18818,10 @@ const JaakStamps = class {
18781
18818
  canvasPool = [];
18782
18819
  MAX_CANVAS_POOL_SIZE = 3;
18783
18820
  async componentWillLoad() {
18821
+ // Yield one microtask so attributes set synchronously after innerHTML are reflected as props
18822
+ await Promise.resolve();
18784
18823
  if (this.debug) {
18785
- console.log('[JAAK-DEBUG] componentWillLoad() - Props at initialization:');
18824
+ console.log('[JAAK-DEBUG] componentWillLoad() - Props after microtask yield:');
18786
18825
  console.log('[JAAK-DEBUG] useDocumentDetector:', this.useDocumentDetector, '(type:', typeof this.useDocumentDetector, ')');
18787
18826
  console.log('[JAAK-DEBUG] useDocumentClassification:', this.useDocumentClassification);
18788
18827
  console.log('[JAAK-DEBUG] debug:', this.debug);
@@ -18794,32 +18833,64 @@ const JaakStamps = class {
18794
18833
  console.log('[JAAK-DEBUG] preferredCamera:', this.preferredCamera);
18795
18834
  console.log('[JAAK-DEBUG] appId:', this.appId);
18796
18835
  }
18797
- // License is required - always validate
18798
- // Wait a bit to ensure props are set from attributes
18799
- await new Promise(resolve => setTimeout(resolve, 50));
18800
- if (this.debug) {
18801
- console.log('[JAAK-DEBUG] Props AFTER 50ms wait:');
18802
- console.log('[JAAK-DEBUG] useDocumentDetector:', this.useDocumentDetector, '(type:', typeof this.useDocumentDetector, ')');
18836
+ if (!this.license) {
18837
+ // No license yet show blocking UI; @Watch('license') triggers init when it arrives
18838
+ this.licenseValid = false;
18839
+ this.licenseError = 'Se requiere una licencia para continuar. Por favor, proporcione una licencia usando el atributo "license".';
18840
+ this.updateStatus('Licencia requerida', 'Proporcione una licencia para continuar', 'error');
18803
18841
  }
18804
- this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18805
- await this.validateLicense();
18806
- // If license validation failed, stop initialization
18807
- if (!this.licenseValid) {
18808
- if (this.debug) {
18809
- console.error('[JAAK-DEBUG] License validation FAILED. Stopping initialization.');
18810
- }
18842
+ else {
18843
+ // License present — pre-set the first status synchronously so the initial render
18844
+ // already shows it, preventing a state change inside componentDidLoad that Stencil
18845
+ // would flag as an extra re-render.
18846
+ this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18847
+ }
18848
+ // Heavy initialization is deferred to componentDidLoad so the first render is not blocked
18849
+ }
18850
+ async componentDidLoad() {
18851
+ // License absent at mount time — @Watch('license') handles initialization when it arrives
18852
+ if (!this.license || this._initialized || this._initializing) {
18811
18853
  return;
18812
18854
  }
18813
- if (this.debug) {
18814
- console.log('[JAAK-DEBUG] License validation OK');
18855
+ await this.validateAndInitialize();
18856
+ }
18857
+ async onLicenseChanged(newLicense) {
18858
+ if (!newLicense || this._initialized || this._initializing) {
18859
+ return;
18815
18860
  }
18861
+ // Set status synchronously before the async work so the UI updates immediately
18862
+ this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18863
+ await this.validateAndInitialize();
18816
18864
  }
18817
- async componentDidLoad() {
18865
+ async onLicenseEnvironmentChanged() {
18866
+ // Always recreate the service so the correct environment URL is used from now on.
18867
+ this.licenseValidationService = new LicenseValidationService(this.licenseEnvironment);
18868
+ // If a license is present but the component never finished initializing
18869
+ // (e.g. first validate ran against the wrong env and failed, or license arrived
18870
+ // before licenseEnvironment was set), retry the full init flow now.
18871
+ if (this.license && !this._initialized && !this._initializing) {
18872
+ this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18873
+ await this.validateAndInitialize();
18874
+ }
18875
+ }
18876
+ async validateAndInitialize() {
18877
+ if (this._initialized || this._initializing) {
18878
+ return;
18879
+ }
18880
+ this._initializing = true;
18818
18881
  try {
18819
- // If license validation failed, stop initialization
18882
+ // Status was already set synchronously by the caller (componentWillLoad or @Watch)
18883
+ // to avoid a state change inside componentDidLoad that Stencil warns about.
18884
+ await this.validateLicense();
18820
18885
  if (!this.licenseValid) {
18886
+ if (this.debug) {
18887
+ console.error('[JAAK-DEBUG] License validation FAILED. Stopping initialization.');
18888
+ }
18821
18889
  return;
18822
18890
  }
18891
+ if (this.debug) {
18892
+ console.log('[JAAK-DEBUG] License validation OK');
18893
+ }
18823
18894
  this.updateStatus('Preparando capturador...', 'Configurando herramientas de captura', 'initializing');
18824
18895
  await this.initializeServices();
18825
18896
  this.updateStatus('Preparando funciones...', 'Configurando herramientas de trabajo', 'initializing');
@@ -18829,9 +18900,14 @@ const JaakStamps = class {
18829
18900
  if (this.debug) {
18830
18901
  this.initializePerformanceMonitor();
18831
18902
  }
18903
+ this._initialized = true;
18832
18904
  }
18833
18905
  catch (error) {
18834
- this.updateStatus('Error de inicialización', error.message, 'error');
18906
+ const errorMessage = error instanceof Error ? error.message : String(error);
18907
+ this.updateStatus('Error de inicialización', errorMessage, 'error');
18908
+ }
18909
+ finally {
18910
+ this._initializing = false;
18835
18911
  }
18836
18912
  }
18837
18913
  async initializeServices() {
@@ -18881,14 +18957,14 @@ const JaakStamps = class {
18881
18957
  }
18882
18958
  async validateLicense() {
18883
18959
  if (!this.license) {
18884
- console.error('❌ No license provided for JAAK Stamps component');
18885
18960
  this.licenseError = 'Este componente requiere una licencia válida. Por favor, proporcione una licencia usando el atributo "license".';
18886
18961
  this.licenseValid = false;
18887
18962
  this.updateStatus('Error de licencia', 'Licencia no proporcionada', 'error');
18888
18963
  return;
18889
18964
  }
18890
18965
  try {
18891
- console.log('🔑 Validating license for JAAK Stamps...');
18966
+ if (this.debug)
18967
+ console.log('[jaak-stamps] validating license...');
18892
18968
  // Initialize license validation service
18893
18969
  this.licenseValidationService = new LicenseValidationService(this.licenseEnvironment);
18894
18970
  // Validate the license, passing traceId and appId if provided
@@ -18896,18 +18972,21 @@ const JaakStamps = class {
18896
18972
  if (response && response.access_token) {
18897
18973
  this.licenseValid = true;
18898
18974
  this.licenseError = null;
18899
- console.log('✅ License validated successfully for JAAK Stamps');
18975
+ if (this.debug)
18976
+ console.log('[jaak-stamps] license validated successfully');
18900
18977
  // Emit the traceId (either provided or generated)
18901
18978
  if (response.traceId) {
18902
18979
  this.traceIdGenerated.emit({ traceId: response.traceId });
18903
- console.log('📋 TraceId:', response.traceId);
18980
+ if (this.debug)
18981
+ console.log('[jaak-stamps] traceId:', response.traceId);
18904
18982
  }
18905
18983
  }
18906
18984
  else {
18907
18985
  this.licenseValid = false;
18908
18986
  this.licenseError = 'La licencia proporcionada no es válida. Por favor, verifique su licencia e intente nuevamente.';
18909
18987
  this.updateStatus('Error de licencia', 'Licencia inválida', 'error');
18910
- console.error('❌ Invalid license for JAAK Stamps');
18988
+ if (this.debug)
18989
+ console.error('[jaak-stamps] invalid license');
18911
18990
  }
18912
18991
  }
18913
18992
  catch (error) {
@@ -18915,7 +18994,8 @@ const JaakStamps = class {
18915
18994
  const licenseError = error;
18916
18995
  this.licenseError = licenseError.error_description || 'Error al validar la licencia. Por favor, verifique su conexión e intente nuevamente.';
18917
18996
  this.updateStatus('Error de licencia', 'Fallo en la validación', 'error');
18918
- console.error('❌ License validation failed for JAAK Stamps:', error);
18997
+ if (this.debug)
18998
+ console.error('[jaak-stamps] license validation failed:', error);
18919
18999
  }
18920
19000
  }
18921
19001
  async setupEventListeners() {
@@ -20201,7 +20281,7 @@ const JaakStamps = class {
20201
20281
  isCapturing: false
20202
20282
  };
20203
20283
  const cameraInfo = this.cameraInfoWithAutofocus;
20204
- return (index.h("div", { key: 'a4f5254bb0f5198cfea553fb46d8841c4a410853', class: "detector-container" }, !this.licenseValid && this.licenseError && (index.h("div", { key: '48353567b7c23df1b44e035cd6b52dd692b338a6', class: "license-error-container" }, index.h("div", { key: '8a520b2cb936cae9ed64c513ae9e583f62d31b99', class: "license-error-card" }, index.h("svg", { key: 'dccdda293c28bd5d1e76bbff0060859a394a800c', class: "license-error-icon", width: "64", height: "64", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { key: '09015453d8230c523abe8e5b4b800b4a55a81202', d: "M12 22C12 22 20 18 20 12V5L12 2L4 5V12C4 18 12 22 12 22Z", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), index.h("path", { key: '5f9fd50412d21de2274e124c02dcc8e971fd23ee', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), index.h("circle", { key: 'e534af1f29c6382c2c47623129a94d3aac3ec71e', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), index.h("h2", { key: '6ed105bb6e16d8ce7419bc64a0f69e7e2d7ed0ac', class: "license-error-title" }, "Licencia Requerida"), index.h("p", { key: 'c1d7e06b03a4af316e28836eb7a0f3729993ca1f', class: "license-error-message" }, this.licenseError), index.h("p", { key: '349ae281248b56524460cb18f36300e69c11ab5e', class: "license-error-help" }, "Contacte a soporte: ", index.h("a", { key: '62546d77296d220338953c3bd1820946164ff96c', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), index.h("div", { key: 'b45ac9c2d9b9d65e4156d07a067e6c9214da8113', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (index.h("div", { key: '77c274b14b69fe4220f71ef789de8c4943833fee', class: "video-container" }, index.h("video", { key: 'e036a408939aa5875e36a1f038bed98bfbfba134', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: {
20284
+ return (index.h("div", { key: '831ee76dee1c7f852e4c3d1d6c5ccc31f5b2633f', class: "detector-container" }, !this.licenseValid && this.licenseError && (index.h("div", { key: '65244e91e43e6bb589c56c4e33ccb4841a6049dc', class: "license-error-container" }, index.h("div", { key: '0c7e0c47c2d2186183f935969d15b6ec4e285475', class: "license-error-card" }, index.h("svg", { key: '45a1eebecf7c36ef63ea88697265a3579fbc1c5a', class: "license-error-icon", width: "64", height: "64", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { key: '24f1d5a4ae9627336c4a0a8293df137f20b21161', d: "M12 22C12 22 20 18 20 12V5L12 2L4 5V12C4 18 12 22 12 22Z", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), index.h("path", { key: '3717c8724487846702c58ba895384e6f8d19f638', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), index.h("circle", { key: '82b0527d2241b370f842d66fa6d2f3e06042568e', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), index.h("h2", { key: '2ff63e9ca1f37e68a4516f79d609c0111d6bc7b1', class: "license-error-title" }, "Licencia Requerida"), index.h("p", { key: '151ac9130f685016f9d3568474ce2dda955509dc', class: "license-error-message" }, this.licenseError), index.h("p", { key: '022fd22a1b627442e8161971b86173ab9f134ba0', class: "license-error-help" }, "Contacte a soporte: ", index.h("a", { key: '4a4fd93259895d8909d888f64d55cc88b6b85f8f', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), index.h("div", { key: '6fb9b5e305d83ec1bc2296accd0d60b1f3c832ca', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (index.h("div", { key: 'd81a43d70a7277fc9ff13b6906c851d8b69a2f01', class: "video-container" }, index.h("video", { key: 'dcb6c1224c91d9eae41f3ebcdf65516cec5dfcb7', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: {
20205
20285
  // Keep the element rendered (display: block) so the browser
20206
20286
  // loads stream metadata and fires 'loadedmetadata'. Hiding it
20207
20287
  // with display:none prevents metadata loading in Chrome and
@@ -20210,7 +20290,7 @@ const JaakStamps = class {
20210
20290
  // render context alive.
20211
20291
  opacity: captureState.isVideoActive ? '1' : '0',
20212
20292
  visibility: captureState.isVideoActive ? 'visible' : 'hidden',
20213
- } }), index.h("div", { key: '9389f1495814409aa849ce409a28cb578761df76', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index$1) => (index.h("div", { key: index$1, class: "detection-box", style: {
20293
+ } }), index.h("div", { key: '0535a299fe2e94e991d76c494c2067eca1617c58', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index$1) => (index.h("div", { key: index$1, class: "detection-box", style: {
20214
20294
  position: 'absolute',
20215
20295
  left: `${box.x}px`,
20216
20296
  top: `${box.y}px`,
@@ -20219,9 +20299,9 @@ const JaakStamps = class {
20219
20299
  border: '2px solid #32406C',
20220
20300
  pointerEvents: 'none',
20221
20301
  boxSizing: 'border-box'
20222
- } })))), this.isMaskReady && (index.h("div", { key: '8050beb9a72279f3a2d54884fe598eca8b1929af', class: "overlay-mask" }, index.h("div", { key: '25028f1c5bab6b457563c098899c7645083be3a0', class: "card-outline" }, index.h("div", { key: 'd125b627160c671f1be837d1f957704d016dcf47', class: "side side-top" }), index.h("div", { key: '78ed55f578fcadba60e80c50315f4a82bbe9c15c', class: "side side-right" }), index.h("div", { key: '263d29d0844bfa88d68698d71630fd9b08debc26', class: "side side-bottom" }), index.h("div", { key: '18e528b4d877699add45d9b4e1e029a2bb993582', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '7e09980601c146cd48f80a04640a8a7d635e14d4', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '102e95d211e79d5c5d8e13ae717cb8913eae7ea1', class: "back-capture-section" }, index.h("div", { key: 'cde593bf62825392df6e950585e9950351bac430', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (index.h("button", { key: '823b35d70e2bb1cf242e01578e921c8a091c7639', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (index.h("span", { key: 'b6f6e82f515cd588eeca60e7abe220d89b40cfe8', class: "button-spinner" })), "Capturar Reverso")), index.h("button", { key: '7d91e6b780958a36df9a859fb02d8224b0de46dc', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (index.h("span", { key: '0d5bce58452c7f7b5e197dfa0eff959971357b3c', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
20302
+ } })))), this.isMaskReady && (index.h("div", { key: '625041af12b0ea65deb22ffbf7161fda8fd23bd2', class: "overlay-mask" }, index.h("div", { key: '37f6df4fb029c14ca81ccdb7a7fedb30a2c2832e', class: "card-outline" }, index.h("div", { key: '91a5fee25260fc2304f6b79c8bcd6b74688562d4', class: "side side-top" }), index.h("div", { key: '7c62e4cb1120495b985b1d4d8482bbf0ffe86745', class: "side side-right" }), index.h("div", { key: '4536e2835e2a3fd572bbec5076d45f854d262e32', class: "side side-bottom" }), index.h("div", { key: '150d7800a958dcd9e7bbd52a5725c240badc0fe5', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: 'a266cbc2fd63215b863b55a291f36ff464453c9b', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: 'b7f7de8ecccd6a7929569184b724ae4b6ab55c34', class: "back-capture-section" }, index.h("div", { key: '3ac3ffcd9ae3a8b841b4f56cc3567da68a92ed4e', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (index.h("button", { key: 'ad1dcfed7e27036f188e5ddce9ada28b15d24aad', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (index.h("span", { key: '06d97ebbaf4f57e0c090a98732b1227fb6f6f8b2', class: "button-spinner" })), "Capturar Reverso")), index.h("button", { key: 'c018d29db7bb2369744ca8ad5aa87bff2c6d15dd', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (index.h("span", { key: 'faf0c7995f2cecaf5d4df8ff6d3bb92364e36806', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
20223
20303
  ? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
20224
- : 'Saltar reverso')))), captureState.isVideoActive && (index.h("div", { key: 'e8fc7f2bb1a0ca8235a82ed368717205c7b63ad8', class: "camera-controls" }, index.h("button", { key: '691e4a97f2804666db5e32236619196d616227f7', class: `camera-selector-button ${this.isSwitchingCamera ? 'loading' : ''}`, onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara", disabled: this.isSwitchingCamera }, this.isSwitchingCamera ? (index.h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (index.h("div", { key: '80233723131262f516574a4dd2bb125970f7aeea', class: "camera-selector-dropdown" }, index.h("div", { key: 'c9284a77cd9f2d3e600924c9e5f38614f3d06dc4', class: "camera-selector-header" }, index.h("span", { key: '92a495d2b605a73a067791442a8c8617706d96bf' }, "Seleccionar C\u00E1mara"), index.h("button", { key: 'dc06382c154443ea9928740d53546dc2ab3ce662', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), index.h("div", { key: 'b520d0940ef51dc1a46641adaf834e105a16c964', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (index.h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, index.h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`, camera.hasAutofocus && (index.h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (index.h("span", { class: "selected-indicator" }, "\u2713")))))), index.h("div", { key: '7df8908982af0142d5c02d9b09827f44e697cbb5', class: "device-info" }, index.h("small", { key: '5669aa375b7aa6cd98d36e5a77eb217e549a5d4d' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '40ed9bde6c2a0afadd8b949ce0cba59344b09379', class: "manual-capture-section" }, index.h("button", { key: 'f394d0a578888782a0a569e721f06bb642ebfbd4', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (index.h("span", { key: 'ec5ee370a578705ccc3a562763c906701a1e4da4', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (index.h("div", { key: '60520ec5cdd2632ac9cd645a5d8d820298b7388b', class: "capture-animation" })), captureState.showFlipAnimation && (index.h("div", { key: 'af3647bc1dd4e58630bf06bae37d7e5cd522c900', class: "flip-animation" }, index.h("div", { key: 'e974ee4fc12ebdef1cdcef288951abb0b98b368a', class: "id-card-icon" }), index.h("div", { key: 'd80764bf0e01069d4fa1367b250215024c8e41ee', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (index.h("div", { key: '07956e4e03dee2ebe64d5eeb1d0c6559dbd8c944', class: "success-animation" }, index.h("div", { key: 'd8cb39f4f7ad3adc9c16b2226b75d14b788636f6', class: "check-icon" }), index.h("div", { key: '9e3ddbac4946cd585de7c406d55915f532a390ed', class: "success-text" }, "\u00A1Proceso completado!"))), index.h("div", { key: 'b1ba412c9c4664eda9c024c3fa22e53f11acae4f', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (index.h("div", { key: 'b466904829c87bcb050500c9f24f507a6d42d56d', class: "status-spinner" })), index.h("div", { key: '3dcfe509f83adf031fadd2fa322a110456e5993b', class: "status-content" }, index.h("div", { key: '3a6c820251b30c0cbd63538b23872ac1191b5213', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (index.h("div", { key: 'a7c35a8a773d852035a35e77fb99cf475307a5f7', class: "status-description" }, this.currentStatus.description)))), this.debug && (index.h("div", { key: 'd581099e2e1aedc1aea88a4c26af59a118042070', class: "performance-monitor" }, index.h("div", { key: '18bf5ba4feb6515a454d0769fe8eb02fd37ef167', class: "performance-expanded" }, index.h("div", { key: '7765f916c26556046b8326befc796f9188aeca3f', class: "metrics-row" }, index.h("div", { key: '9533109a7a762a7d8a95f12f45dddb6833fa7326', class: "metric-compact" }, index.h("span", { key: 'c236d06e692694a58519e86f133f39a5184a485f', class: "metric-label" }, "FPS"), index.h("span", { key: '4a7b53c89c4822dc03c6683f6d6895f96458b95d', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), index.h("div", { key: 'd362ceb5edf7585fc7c05da7367a6affee83b942', class: "metric-compact" }, index.h("span", { key: '08779e8da11b1593f7d91b409b36184ed405dee6', class: "metric-label" }, "MEM"), index.h("span", { key: '64c15bcbaeca6760e578e4ff9386583938c0be87', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), index.h("div", { key: '1ef4f7a5aaae9ed9131bd45c7a4c227ad6419d93', class: "metrics-row" }, index.h("div", { key: 'c5d5ab2a81f7c8f5145253ece37e43981c68ccb8', class: "metric-compact" }, index.h("span", { key: '7ba45cae45b336c52adf1eb4588851be20475f4e', class: "metric-label" }, "INF"), index.h("span", { key: '1341edaafa1de81b304605378a8b1262f2f8a084', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), index.h("div", { key: '4c6edc10f88b776825a5a07643864fef4295c295', class: "metric-compact" }, index.h("span", { key: '7d58a7250a133b84f001a5313dce606fcd9eda82', class: "metric-label" }, "FRAME"), index.h("span", { key: 'de6a8e8475cd893546b939d5e3a7045a9d7df6dc', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), index.h("div", { key: 'a26794337b9fd17fc9bc6718461c5251b57c1949', class: "metrics-row" }, index.h("div", { key: 'd790ac359b04532a5e7aa44e2a2952522c1ceb64', class: "metric-compact" }, index.h("span", { key: '581c72f166de867bbbfe3bb654cdf89e94cfc27b', class: "metric-label" }, "DET"), index.h("span", { key: '8d478a6d5e84151504e2dd136e2b1ff1e26e0853', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), index.h("div", { key: 'bb7f6dad291a79b5f683e51e07558ca73c22ad98', class: "metric-compact" }, index.h("span", { key: '1d2626fb63026ce3eb9d0696501b08c0ddf4be09', class: "metric-label" }, "RATE"), index.h("span", { key: '8f8a67276ad40ce3fe9acab86c2a807f426d2a23', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), index.h("div", { key: 'a9ae57be92d04f8d5d7eae801c0a0ae7c548f770', class: "watermark" }, index.h("img", { key: 'c9cd4510dfff2265e3ae5d213845e7b5d8f9a343', src: "https://static.jaak.ai/commons/powered-by-jaak.png", alt: "Powered by Jaak", onError: (e) => {
20304
+ : 'Saltar reverso')))), captureState.isVideoActive && (index.h("div", { key: '7000fa21f319e3c1fd2290710a60a4e4bd44d25b', class: "camera-controls" }, index.h("button", { key: '643aef1a72365b8b2d6e340fff4c837dba96a3fb', class: `camera-selector-button ${this.isSwitchingCamera ? 'loading' : ''}`, onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara", disabled: this.isSwitchingCamera }, this.isSwitchingCamera ? (index.h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (index.h("div", { key: '76e6765fc5264de81eeeab184d23c3ba23cd0976', class: "camera-selector-dropdown" }, index.h("div", { key: '0a9eb0ffc9a2a8ec5a632e0dc1e367a4f89c0499', class: "camera-selector-header" }, index.h("span", { key: 'ad09fc0efb7cda425853a156d310da57ddfa1906' }, "Seleccionar C\u00E1mara"), index.h("button", { key: '2ebaff48a49b56e6b65cd93c96048e3050ad92a4', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), index.h("div", { key: 'fbb80070332766d85f9a91856d90251928490a5f', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (index.h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, index.h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`, camera.hasAutofocus && (index.h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (index.h("span", { class: "selected-indicator" }, "\u2713")))))), index.h("div", { key: '8ce8fbefe3cacf05f34f216de2b9539fd0f4c405', class: "device-info" }, index.h("small", { key: 'dec43734808a18f5a0b2c6dc8555b62d5bc4eafa' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '3560ead8bf670c71c94457689cc7280127e6bb26', class: "manual-capture-section" }, index.h("button", { key: 'bb642fddb0bdd3014b600869f0c9fb892f40454c', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (index.h("span", { key: '2bcfd2b481e43684bf38584598747e68277ab18a', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (index.h("div", { key: '7c6ac830d622ff91de6f03273b11bdebf64b335e', class: "capture-animation" })), captureState.showFlipAnimation && (index.h("div", { key: '8a6b470eaafc34aadc6192553e38ccadf5755272', class: "flip-animation" }, index.h("div", { key: '965bc9d8858447eb44cc860df814fa54fc7ab697', class: "id-card-icon" }), index.h("div", { key: '2a4ff10eb928f88501e25112597efc345a6c587a', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (index.h("div", { key: 'a599c61bb9dd4b910abdb1a5cb271484184a1ecd', class: "success-animation" }, index.h("div", { key: 'ce0d1f0f824e4ef2d3f24521246fde546bcb479a', class: "check-icon" }), index.h("div", { key: '752859c69c65130cd065f1fa6d15269ce7789035', class: "success-text" }, "\u00A1Proceso completado!"))), index.h("div", { key: '421768cd2d6aa9ab491861fb0cae305470b1456b', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (index.h("div", { key: '81374800169c2b4e331cf8f876085c3420700423', class: "status-spinner" })), index.h("div", { key: 'f13c794c2c8c71bed1cae401f7e1104edfcad428', class: "status-content" }, index.h("div", { key: 'e662075d24c9400eb6e6b97e785f8453ea2c350b', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (index.h("div", { key: '42e03d32e3697b4095c190a670c04dd1a09d5f9d', class: "status-description" }, this.currentStatus.description)))), this.debug && (index.h("div", { key: 'cda6b3292ef939bbc1f0f0176ef55b8c8fc37929', class: "performance-monitor" }, index.h("div", { key: 'bc149a754f6e65f1870f2ce151f502694a2a8e52', class: "performance-expanded" }, index.h("div", { key: '30d7519b0ea3c72997363840dad433fbeef64569', class: "metrics-row" }, index.h("div", { key: 'da4101538afc21090ceb59f5d48ca4d48abc41e0', class: "metric-compact" }, index.h("span", { key: '8150ece409d7e62f61d79507d3a332042af5934a', class: "metric-label" }, "FPS"), index.h("span", { key: '0b07ac0de7f294f8d253e0c57931c52345918914', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), index.h("div", { key: '7242ad6791000c0d6cd86cfe5043c961f57ea754', class: "metric-compact" }, index.h("span", { key: '5499d7e3fac025933916b3efbd2b511128515ff8', class: "metric-label" }, "MEM"), index.h("span", { key: '885851d31aa1b639e8e2352b4c6813ee2b45b953', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), index.h("div", { key: '14e3bda4caab1b182cb772e2da4cea4d3c342d00', class: "metrics-row" }, index.h("div", { key: 'be33011987e3cfa6b499fa618aba0575f6253992', class: "metric-compact" }, index.h("span", { key: '111dd593ba724adbd148a9bba5728db6f569b88d', class: "metric-label" }, "INF"), index.h("span", { key: '104680823cc990a0181a7a770c50ad43241856f8', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), index.h("div", { key: '006e6417a404a9296170bc1c20660716a9eca169', class: "metric-compact" }, index.h("span", { key: '2f5e7c8cfcd99e22b0c5399a05eb84816e6c3133', class: "metric-label" }, "FRAME"), index.h("span", { key: '3cedfc835bf282e513aef93e3e96a0154a62193b', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), index.h("div", { key: '21ba720f1a3a4a5a900bf75602a0286a779b7cd0', class: "metrics-row" }, index.h("div", { key: 'b1bcdabe6feeee08068d70e280772a15f1ff9a1a', class: "metric-compact" }, index.h("span", { key: 'b9686f5946d878366b6b282a677b4e10eed7e3f3', class: "metric-label" }, "DET"), index.h("span", { key: 'fd6cf1adac9dd90936f64e6da93a9ea16bc060d1', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), index.h("div", { key: 'a4f796a8b19f3689f68a9213df7335b93d3947ad', class: "metric-compact" }, index.h("span", { key: 'abdec7d8b8cfc53cb635ba513d01e95e68ceb703', class: "metric-label" }, "RATE"), index.h("span", { key: '8fa1b3a30ad7dfcc77ee86c022e085b779a9ced7', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), index.h("div", { key: 'f9d1c4fd872a7d7bfd06b0b31ad557941de5067d', class: "watermark" }, index.h("img", { key: 'e9ea47bbc2eca4bde520198924e417e94f4e228f', src: "https://static.jaak.ai/commons/powered-by-jaak.png", alt: "Powered by Jaak", onError: (e) => {
20225
20305
  const img = e.target;
20226
20306
  img.onerror = null;
20227
20307
  img.src = POWERED_BY_JAAK_FALLBACK;
@@ -20769,7 +20849,7 @@ const JaakStamps = class {
20769
20849
  await this.tracingService.flush();
20770
20850
  }
20771
20851
  catch (error) {
20772
- console.error('[my-component] Failed to flush traces:', error);
20852
+ console.error('[jaak-stamps] Failed to flush traces:', error);
20773
20853
  }
20774
20854
  }
20775
20855
  this.captureCompleted.emit(finalImages);
@@ -21042,8 +21122,12 @@ const JaakStamps = class {
21042
21122
  // If pool is full, let the canvas be garbage collected
21043
21123
  }
21044
21124
  static get assetsDirs() { return ["../../assets"]; }
21125
+ static get watchers() { return {
21126
+ "license": ["onLicenseChanged"],
21127
+ "licenseEnvironment": ["onLicenseEnvironmentChanged"]
21128
+ }; }
21045
21129
  };
21046
- JaakStamps.style = myComponentCss;
21130
+ JaakStamps.style = jaakStampsCss;
21047
21131
 
21048
21132
  exports.jaak_stamps = JaakStamps;
21049
21133
  //# sourceMappingURL=jaak-stamps.entry.cjs.js.map