@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,4 +1,4 @@
1
- import { r as registerInstance, c as createEvent, g as getElement, h } from './index-BCfAsrzL.js';
1
+ import { r as registerInstance, c as createEvent, g as getElement, h } from './index-Cb0ILUvS.js';
2
2
 
3
3
  class EventBusService {
4
4
  events = new Map();
@@ -822,7 +822,7 @@ class DetectionService {
822
822
  try {
823
823
  const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);
824
824
  try {
825
- this.session = await window.ort.InferenceSession.create(this.MODEL_PATH, sessionOptions);
825
+ this.session = await this.createSession(this.MODEL_PATH, sessionOptions);
826
826
  this.detectFloat16Support();
827
827
  }
828
828
  catch (error) {
@@ -837,7 +837,7 @@ class DetectionService {
837
837
  if (isFloat16Error) {
838
838
  this.useFloat16 = false;
839
839
  try {
840
- this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, sessionOptions);
840
+ this.session = await this.createSession(this.MODEL_PATH_FP32, sessionOptions);
841
841
  }
842
842
  catch (fp32Error) {
843
843
  // Intentar con opciones minimas de WASM
@@ -846,7 +846,7 @@ class DetectionService {
846
846
  graphOptimizationLevel: 'all',
847
847
  logSeverityLevel: this.debug ? 2 : 4,
848
848
  };
849
- this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, wasmOptions);
849
+ this.session = await this.createSession(this.MODEL_PATH_FP32, wasmOptions);
850
850
  }
851
851
  }
852
852
  else if (isMemoryError) {
@@ -865,7 +865,7 @@ class DetectionService {
865
865
  };
866
866
  this.useFloat16 = false;
867
867
  try {
868
- this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, fallbackOptions);
868
+ this.session = await this.createSession(this.MODEL_PATH_FP32, fallbackOptions);
869
869
  }
870
870
  catch (fallbackError) {
871
871
  throw new Error(`no available backend found. ERR: [wasm] RangeError: Out of memory`);
@@ -906,7 +906,7 @@ class DetectionService {
906
906
  // Load model
907
907
  const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);
908
908
  try {
909
- this.mobileNetSession = await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, sessionOptions);
909
+ this.mobileNetSession = await this.createSession(this.MOBILENET_MODEL_PATH, sessionOptions);
910
910
  }
911
911
  catch (error) {
912
912
  // Múltiples tipos de errores de memoria que pueden ocurrir
@@ -930,7 +930,7 @@ class DetectionService {
930
930
  sessionLogVerbosityLevel: 0,
931
931
  };
932
932
  try {
933
- this.mobileNetSession = await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, fallbackOptions);
933
+ this.mobileNetSession = await this.createSession(this.MOBILENET_MODEL_PATH, fallbackOptions);
934
934
  }
935
935
  catch (fallbackError) {
936
936
  throw new Error(`no available backend found. ERR: [wasm] RangeError: Out of memory`);
@@ -1122,6 +1122,41 @@ class DetectionService {
1122
1122
  areAllSidesAligned(alignment) {
1123
1123
  return alignment.top && alignment.right && alignment.bottom && alignment.left;
1124
1124
  }
1125
+ // Reference counter so concurrent sessions share one filter and the last
1126
+ // one to finish restores the original console.warn.
1127
+ static _ortWarnActiveCount = 0;
1128
+ static _originalWarn = null;
1129
+ static _acquireWarnFilter() {
1130
+ if (DetectionService._ortWarnActiveCount === 0) {
1131
+ DetectionService._originalWarn = console.warn;
1132
+ console.warn = (...args) => {
1133
+ const msg = typeof args[0] === 'string' ? args[0] : '';
1134
+ if (!msg.includes('removing requested execution provider')) {
1135
+ DetectionService._originalWarn.apply(console, args);
1136
+ }
1137
+ };
1138
+ }
1139
+ DetectionService._ortWarnActiveCount++;
1140
+ }
1141
+ static _releaseWarnFilter() {
1142
+ DetectionService._ortWarnActiveCount--;
1143
+ if (DetectionService._ortWarnActiveCount === 0 && DetectionService._originalWarn) {
1144
+ console.warn = DetectionService._originalWarn;
1145
+ DetectionService._originalWarn = null;
1146
+ }
1147
+ }
1148
+ async createSession(modelPath, options) {
1149
+ // Keep the filter active for the full await: ORT may emit
1150
+ // "removing requested execution provider" during async resolution,
1151
+ // not only in the synchronous preamble of create().
1152
+ DetectionService._acquireWarnFilter();
1153
+ try {
1154
+ return await window.ort.InferenceSession.create(modelPath, options);
1155
+ }
1156
+ finally {
1157
+ DetectionService._releaseWarnFilter();
1158
+ }
1159
+ }
1125
1160
  cleanup() {
1126
1161
  this.cleanupCanvasPool();
1127
1162
  if (this.session) {
@@ -18632,7 +18667,7 @@ class LicenseValidationService {
18632
18667
  }
18633
18668
  }
18634
18669
 
18635
- 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}}";
18670
+ 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}}";
18636
18671
 
18637
18672
  const JaakStamps = class {
18638
18673
  constructor(hostRef) {
@@ -18662,7 +18697,7 @@ const JaakStamps = class {
18662
18697
  propagateTraceHeaderCorsUrls; // Comma-separated URLs or regex patterns
18663
18698
  metricsExportIntervalMillis = 60000; // Export metrics every 60 seconds
18664
18699
  license; // License key for validation
18665
- licenseEnvironment = 'prod'; // Environment for license validation
18700
+ licenseEnvironment = 'prod';
18666
18701
  traceId; // Optional trace ID for tracking
18667
18702
  appId = 'jaak-stamps-web'; // Application ID for license validation
18668
18703
  captureCompleted;
@@ -18710,6 +18745,8 @@ const JaakStamps = class {
18710
18745
  licenseValid = true; // License validation status
18711
18746
  licenseError = null; // License validation error message
18712
18747
  classificationDisabled = false; // Classification disabled at runtime due to errors
18748
+ _initialized = false;
18749
+ _initializing = false;
18713
18750
  // Services
18714
18751
  licenseValidationService = null;
18715
18752
  serviceContainer;
@@ -18779,8 +18816,10 @@ const JaakStamps = class {
18779
18816
  canvasPool = [];
18780
18817
  MAX_CANVAS_POOL_SIZE = 3;
18781
18818
  async componentWillLoad() {
18819
+ // Yield one microtask so attributes set synchronously after innerHTML are reflected as props
18820
+ await Promise.resolve();
18782
18821
  if (this.debug) {
18783
- console.log('[JAAK-DEBUG] componentWillLoad() - Props at initialization:');
18822
+ console.log('[JAAK-DEBUG] componentWillLoad() - Props after microtask yield:');
18784
18823
  console.log('[JAAK-DEBUG] useDocumentDetector:', this.useDocumentDetector, '(type:', typeof this.useDocumentDetector, ')');
18785
18824
  console.log('[JAAK-DEBUG] useDocumentClassification:', this.useDocumentClassification);
18786
18825
  console.log('[JAAK-DEBUG] debug:', this.debug);
@@ -18792,32 +18831,64 @@ const JaakStamps = class {
18792
18831
  console.log('[JAAK-DEBUG] preferredCamera:', this.preferredCamera);
18793
18832
  console.log('[JAAK-DEBUG] appId:', this.appId);
18794
18833
  }
18795
- // License is required - always validate
18796
- // Wait a bit to ensure props are set from attributes
18797
- await new Promise(resolve => setTimeout(resolve, 50));
18798
- if (this.debug) {
18799
- console.log('[JAAK-DEBUG] Props AFTER 50ms wait:');
18800
- console.log('[JAAK-DEBUG] useDocumentDetector:', this.useDocumentDetector, '(type:', typeof this.useDocumentDetector, ')');
18834
+ if (!this.license) {
18835
+ // No license yet show blocking UI; @Watch('license') triggers init when it arrives
18836
+ this.licenseValid = false;
18837
+ this.licenseError = 'Se requiere una licencia para continuar. Por favor, proporcione una licencia usando el atributo "license".';
18838
+ this.updateStatus('Licencia requerida', 'Proporcione una licencia para continuar', 'error');
18801
18839
  }
18802
- this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18803
- await this.validateLicense();
18804
- // If license validation failed, stop initialization
18805
- if (!this.licenseValid) {
18806
- if (this.debug) {
18807
- console.error('[JAAK-DEBUG] License validation FAILED. Stopping initialization.');
18808
- }
18840
+ else {
18841
+ // License present — pre-set the first status synchronously so the initial render
18842
+ // already shows it, preventing a state change inside componentDidLoad that Stencil
18843
+ // would flag as an extra re-render.
18844
+ this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18845
+ }
18846
+ // Heavy initialization is deferred to componentDidLoad so the first render is not blocked
18847
+ }
18848
+ async componentDidLoad() {
18849
+ // License absent at mount time — @Watch('license') handles initialization when it arrives
18850
+ if (!this.license || this._initialized || this._initializing) {
18809
18851
  return;
18810
18852
  }
18811
- if (this.debug) {
18812
- console.log('[JAAK-DEBUG] License validation OK');
18853
+ await this.validateAndInitialize();
18854
+ }
18855
+ async onLicenseChanged(newLicense) {
18856
+ if (!newLicense || this._initialized || this._initializing) {
18857
+ return;
18813
18858
  }
18859
+ // Set status synchronously before the async work so the UI updates immediately
18860
+ this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18861
+ await this.validateAndInitialize();
18814
18862
  }
18815
- async componentDidLoad() {
18863
+ async onLicenseEnvironmentChanged() {
18864
+ // Always recreate the service so the correct environment URL is used from now on.
18865
+ this.licenseValidationService = new LicenseValidationService(this.licenseEnvironment);
18866
+ // If a license is present but the component never finished initializing
18867
+ // (e.g. first validate ran against the wrong env and failed, or license arrived
18868
+ // before licenseEnvironment was set), retry the full init flow now.
18869
+ if (this.license && !this._initialized && !this._initializing) {
18870
+ this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18871
+ await this.validateAndInitialize();
18872
+ }
18873
+ }
18874
+ async validateAndInitialize() {
18875
+ if (this._initialized || this._initializing) {
18876
+ return;
18877
+ }
18878
+ this._initializing = true;
18816
18879
  try {
18817
- // If license validation failed, stop initialization
18880
+ // Status was already set synchronously by the caller (componentWillLoad or @Watch)
18881
+ // to avoid a state change inside componentDidLoad that Stencil warns about.
18882
+ await this.validateLicense();
18818
18883
  if (!this.licenseValid) {
18884
+ if (this.debug) {
18885
+ console.error('[JAAK-DEBUG] License validation FAILED. Stopping initialization.');
18886
+ }
18819
18887
  return;
18820
18888
  }
18889
+ if (this.debug) {
18890
+ console.log('[JAAK-DEBUG] License validation OK');
18891
+ }
18821
18892
  this.updateStatus('Preparando capturador...', 'Configurando herramientas de captura', 'initializing');
18822
18893
  await this.initializeServices();
18823
18894
  this.updateStatus('Preparando funciones...', 'Configurando herramientas de trabajo', 'initializing');
@@ -18827,9 +18898,14 @@ const JaakStamps = class {
18827
18898
  if (this.debug) {
18828
18899
  this.initializePerformanceMonitor();
18829
18900
  }
18901
+ this._initialized = true;
18830
18902
  }
18831
18903
  catch (error) {
18832
- this.updateStatus('Error de inicialización', error.message, 'error');
18904
+ const errorMessage = error instanceof Error ? error.message : String(error);
18905
+ this.updateStatus('Error de inicialización', errorMessage, 'error');
18906
+ }
18907
+ finally {
18908
+ this._initializing = false;
18833
18909
  }
18834
18910
  }
18835
18911
  async initializeServices() {
@@ -18879,14 +18955,14 @@ const JaakStamps = class {
18879
18955
  }
18880
18956
  async validateLicense() {
18881
18957
  if (!this.license) {
18882
- console.error('❌ No license provided for JAAK Stamps component');
18883
18958
  this.licenseError = 'Este componente requiere una licencia válida. Por favor, proporcione una licencia usando el atributo "license".';
18884
18959
  this.licenseValid = false;
18885
18960
  this.updateStatus('Error de licencia', 'Licencia no proporcionada', 'error');
18886
18961
  return;
18887
18962
  }
18888
18963
  try {
18889
- console.log('🔑 Validating license for JAAK Stamps...');
18964
+ if (this.debug)
18965
+ console.log('[jaak-stamps] validating license...');
18890
18966
  // Initialize license validation service
18891
18967
  this.licenseValidationService = new LicenseValidationService(this.licenseEnvironment);
18892
18968
  // Validate the license, passing traceId and appId if provided
@@ -18894,18 +18970,21 @@ const JaakStamps = class {
18894
18970
  if (response && response.access_token) {
18895
18971
  this.licenseValid = true;
18896
18972
  this.licenseError = null;
18897
- console.log('✅ License validated successfully for JAAK Stamps');
18973
+ if (this.debug)
18974
+ console.log('[jaak-stamps] license validated successfully');
18898
18975
  // Emit the traceId (either provided or generated)
18899
18976
  if (response.traceId) {
18900
18977
  this.traceIdGenerated.emit({ traceId: response.traceId });
18901
- console.log('📋 TraceId:', response.traceId);
18978
+ if (this.debug)
18979
+ console.log('[jaak-stamps] traceId:', response.traceId);
18902
18980
  }
18903
18981
  }
18904
18982
  else {
18905
18983
  this.licenseValid = false;
18906
18984
  this.licenseError = 'La licencia proporcionada no es válida. Por favor, verifique su licencia e intente nuevamente.';
18907
18985
  this.updateStatus('Error de licencia', 'Licencia inválida', 'error');
18908
- console.error('❌ Invalid license for JAAK Stamps');
18986
+ if (this.debug)
18987
+ console.error('[jaak-stamps] invalid license');
18909
18988
  }
18910
18989
  }
18911
18990
  catch (error) {
@@ -18913,7 +18992,8 @@ const JaakStamps = class {
18913
18992
  const licenseError = error;
18914
18993
  this.licenseError = licenseError.error_description || 'Error al validar la licencia. Por favor, verifique su conexión e intente nuevamente.';
18915
18994
  this.updateStatus('Error de licencia', 'Fallo en la validación', 'error');
18916
- console.error('❌ License validation failed for JAAK Stamps:', error);
18995
+ if (this.debug)
18996
+ console.error('[jaak-stamps] license validation failed:', error);
18917
18997
  }
18918
18998
  }
18919
18999
  async setupEventListeners() {
@@ -20199,7 +20279,7 @@ const JaakStamps = class {
20199
20279
  isCapturing: false
20200
20280
  };
20201
20281
  const cameraInfo = this.cameraInfoWithAutofocus;
20202
- return (h("div", { key: 'a4f5254bb0f5198cfea553fb46d8841c4a410853', class: "detector-container" }, !this.licenseValid && this.licenseError && (h("div", { key: '48353567b7c23df1b44e035cd6b52dd692b338a6', class: "license-error-container" }, h("div", { key: '8a520b2cb936cae9ed64c513ae9e583f62d31b99', class: "license-error-card" }, 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" }, 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" }), h("path", { key: '5f9fd50412d21de2274e124c02dcc8e971fd23ee', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), h("circle", { key: 'e534af1f29c6382c2c47623129a94d3aac3ec71e', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), h("h2", { key: '6ed105bb6e16d8ce7419bc64a0f69e7e2d7ed0ac', class: "license-error-title" }, "Licencia Requerida"), h("p", { key: 'c1d7e06b03a4af316e28836eb7a0f3729993ca1f', class: "license-error-message" }, this.licenseError), h("p", { key: '349ae281248b56524460cb18f36300e69c11ab5e', class: "license-error-help" }, "Contacte a soporte: ", h("a", { key: '62546d77296d220338953c3bd1820946164ff96c', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), h("div", { key: 'b45ac9c2d9b9d65e4156d07a067e6c9214da8113', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (h("div", { key: '77c274b14b69fe4220f71ef789de8c4943833fee', class: "video-container" }, h("video", { key: 'e036a408939aa5875e36a1f038bed98bfbfba134', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: {
20282
+ return (h("div", { key: '831ee76dee1c7f852e4c3d1d6c5ccc31f5b2633f', class: "detector-container" }, !this.licenseValid && this.licenseError && (h("div", { key: '65244e91e43e6bb589c56c4e33ccb4841a6049dc', class: "license-error-container" }, h("div", { key: '0c7e0c47c2d2186183f935969d15b6ec4e285475', class: "license-error-card" }, 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" }, 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" }), h("path", { key: '3717c8724487846702c58ba895384e6f8d19f638', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), h("circle", { key: '82b0527d2241b370f842d66fa6d2f3e06042568e', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), h("h2", { key: '2ff63e9ca1f37e68a4516f79d609c0111d6bc7b1', class: "license-error-title" }, "Licencia Requerida"), h("p", { key: '151ac9130f685016f9d3568474ce2dda955509dc', class: "license-error-message" }, this.licenseError), h("p", { key: '022fd22a1b627442e8161971b86173ab9f134ba0', class: "license-error-help" }, "Contacte a soporte: ", h("a", { key: '4a4fd93259895d8909d888f64d55cc88b6b85f8f', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), h("div", { key: '6fb9b5e305d83ec1bc2296accd0d60b1f3c832ca', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (h("div", { key: 'd81a43d70a7277fc9ff13b6906c851d8b69a2f01', class: "video-container" }, h("video", { key: 'dcb6c1224c91d9eae41f3ebcdf65516cec5dfcb7', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: {
20203
20283
  // Keep the element rendered (display: block) so the browser
20204
20284
  // loads stream metadata and fires 'loadedmetadata'. Hiding it
20205
20285
  // with display:none prevents metadata loading in Chrome and
@@ -20208,7 +20288,7 @@ const JaakStamps = class {
20208
20288
  // render context alive.
20209
20289
  opacity: captureState.isVideoActive ? '1' : '0',
20210
20290
  visibility: captureState.isVideoActive ? 'visible' : 'hidden',
20211
- } }), h("div", { key: '9389f1495814409aa849ce409a28cb578761df76', 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: {
20291
+ } }), h("div", { key: '0535a299fe2e94e991d76c494c2067eca1617c58', 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: {
20212
20292
  position: 'absolute',
20213
20293
  left: `${box.x}px`,
20214
20294
  top: `${box.y}px`,
@@ -20217,9 +20297,9 @@ const JaakStamps = class {
20217
20297
  border: '2px solid #32406C',
20218
20298
  pointerEvents: 'none',
20219
20299
  boxSizing: 'border-box'
20220
- } })))), this.isMaskReady && (h("div", { key: '8050beb9a72279f3a2d54884fe598eca8b1929af', class: "overlay-mask" }, h("div", { key: '25028f1c5bab6b457563c098899c7645083be3a0', class: "card-outline" }, h("div", { key: 'd125b627160c671f1be837d1f957704d016dcf47', class: "side side-top" }), h("div", { key: '78ed55f578fcadba60e80c50315f4a82bbe9c15c', class: "side side-right" }), h("div", { key: '263d29d0844bfa88d68698d71630fd9b08debc26', class: "side side-bottom" }), h("div", { key: '18e528b4d877699add45d9b4e1e029a2bb993582', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '7e09980601c146cd48f80a04640a8a7d635e14d4', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '102e95d211e79d5c5d8e13ae717cb8913eae7ea1', class: "back-capture-section" }, h("div", { key: 'cde593bf62825392df6e950585e9950351bac430', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (h("button", { key: '823b35d70e2bb1cf242e01578e921c8a091c7639', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (h("span", { key: 'b6f6e82f515cd588eeca60e7abe220d89b40cfe8', class: "button-spinner" })), "Capturar Reverso")), h("button", { key: '7d91e6b780958a36df9a859fb02d8224b0de46dc', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (h("span", { key: '0d5bce58452c7f7b5e197dfa0eff959971357b3c', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
20300
+ } })))), this.isMaskReady && (h("div", { key: '625041af12b0ea65deb22ffbf7161fda8fd23bd2', class: "overlay-mask" }, h("div", { key: '37f6df4fb029c14ca81ccdb7a7fedb30a2c2832e', class: "card-outline" }, h("div", { key: '91a5fee25260fc2304f6b79c8bcd6b74688562d4', class: "side side-top" }), h("div", { key: '7c62e4cb1120495b985b1d4d8482bbf0ffe86745', class: "side side-right" }), h("div", { key: '4536e2835e2a3fd572bbec5076d45f854d262e32', class: "side side-bottom" }), h("div", { key: '150d7800a958dcd9e7bbd52a5725c240badc0fe5', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'a266cbc2fd63215b863b55a291f36ff464453c9b', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'b7f7de8ecccd6a7929569184b724ae4b6ab55c34', class: "back-capture-section" }, h("div", { key: '3ac3ffcd9ae3a8b841b4f56cc3567da68a92ed4e', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (h("button", { key: 'ad1dcfed7e27036f188e5ddce9ada28b15d24aad', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (h("span", { key: '06d97ebbaf4f57e0c090a98732b1227fb6f6f8b2', class: "button-spinner" })), "Capturar Reverso")), h("button", { key: 'c018d29db7bb2369744ca8ad5aa87bff2c6d15dd', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (h("span", { key: 'faf0c7995f2cecaf5d4df8ff6d3bb92364e36806', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
20221
20301
  ? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
20222
- : 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: 'e8fc7f2bb1a0ca8235a82ed368717205c7b63ad8', class: "camera-controls" }, 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 ? (h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (h("div", { key: '80233723131262f516574a4dd2bb125970f7aeea', class: "camera-selector-dropdown" }, h("div", { key: 'c9284a77cd9f2d3e600924c9e5f38614f3d06dc4', class: "camera-selector-header" }, h("span", { key: '92a495d2b605a73a067791442a8c8617706d96bf' }, "Seleccionar C\u00E1mara"), h("button", { key: 'dc06382c154443ea9928740d53546dc2ab3ce662', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: 'b520d0940ef51dc1a46641adaf834e105a16c964', 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}`, camera.hasAutofocus && (h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (h("span", { class: "selected-indicator" }, "\u2713")))))), h("div", { key: '7df8908982af0142d5c02d9b09827f44e697cbb5', class: "device-info" }, h("small", { key: '5669aa375b7aa6cd98d36e5a77eb217e549a5d4d' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '40ed9bde6c2a0afadd8b949ce0cba59344b09379', class: "manual-capture-section" }, h("button", { key: 'f394d0a578888782a0a569e721f06bb642ebfbd4', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (h("span", { key: 'ec5ee370a578705ccc3a562763c906701a1e4da4', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (h("div", { key: '60520ec5cdd2632ac9cd645a5d8d820298b7388b', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: 'af3647bc1dd4e58630bf06bae37d7e5cd522c900', class: "flip-animation" }, h("div", { key: 'e974ee4fc12ebdef1cdcef288951abb0b98b368a', class: "id-card-icon" }), h("div", { key: 'd80764bf0e01069d4fa1367b250215024c8e41ee', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: '07956e4e03dee2ebe64d5eeb1d0c6559dbd8c944', class: "success-animation" }, h("div", { key: 'd8cb39f4f7ad3adc9c16b2226b75d14b788636f6', class: "check-icon" }), h("div", { key: '9e3ddbac4946cd585de7c406d55915f532a390ed', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: 'b1ba412c9c4664eda9c024c3fa22e53f11acae4f', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: 'b466904829c87bcb050500c9f24f507a6d42d56d', class: "status-spinner" })), h("div", { key: '3dcfe509f83adf031fadd2fa322a110456e5993b', class: "status-content" }, h("div", { key: '3a6c820251b30c0cbd63538b23872ac1191b5213', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: 'a7c35a8a773d852035a35e77fb99cf475307a5f7', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: 'd581099e2e1aedc1aea88a4c26af59a118042070', class: "performance-monitor" }, h("div", { key: '18bf5ba4feb6515a454d0769fe8eb02fd37ef167', class: "performance-expanded" }, h("div", { key: '7765f916c26556046b8326befc796f9188aeca3f', class: "metrics-row" }, h("div", { key: '9533109a7a762a7d8a95f12f45dddb6833fa7326', class: "metric-compact" }, h("span", { key: 'c236d06e692694a58519e86f133f39a5184a485f', class: "metric-label" }, "FPS"), h("span", { key: '4a7b53c89c4822dc03c6683f6d6895f96458b95d', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: 'd362ceb5edf7585fc7c05da7367a6affee83b942', class: "metric-compact" }, h("span", { key: '08779e8da11b1593f7d91b409b36184ed405dee6', class: "metric-label" }, "MEM"), h("span", { key: '64c15bcbaeca6760e578e4ff9386583938c0be87', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: '1ef4f7a5aaae9ed9131bd45c7a4c227ad6419d93', class: "metrics-row" }, h("div", { key: 'c5d5ab2a81f7c8f5145253ece37e43981c68ccb8', class: "metric-compact" }, h("span", { key: '7ba45cae45b336c52adf1eb4588851be20475f4e', class: "metric-label" }, "INF"), h("span", { key: '1341edaafa1de81b304605378a8b1262f2f8a084', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '4c6edc10f88b776825a5a07643864fef4295c295', class: "metric-compact" }, h("span", { key: '7d58a7250a133b84f001a5313dce606fcd9eda82', class: "metric-label" }, "FRAME"), h("span", { key: 'de6a8e8475cd893546b939d5e3a7045a9d7df6dc', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: 'a26794337b9fd17fc9bc6718461c5251b57c1949', class: "metrics-row" }, h("div", { key: 'd790ac359b04532a5e7aa44e2a2952522c1ceb64', class: "metric-compact" }, h("span", { key: '581c72f166de867bbbfe3bb654cdf89e94cfc27b', class: "metric-label" }, "DET"), h("span", { key: '8d478a6d5e84151504e2dd136e2b1ff1e26e0853', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: 'bb7f6dad291a79b5f683e51e07558ca73c22ad98', class: "metric-compact" }, h("span", { key: '1d2626fb63026ce3eb9d0696501b08c0ddf4be09', class: "metric-label" }, "RATE"), h("span", { key: '8f8a67276ad40ce3fe9acab86c2a807f426d2a23', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: 'a9ae57be92d04f8d5d7eae801c0a0ae7c548f770', class: "watermark" }, h("img", { key: 'c9cd4510dfff2265e3ae5d213845e7b5d8f9a343', src: "https://static.jaak.ai/commons/powered-by-jaak.png", alt: "Powered by Jaak", onError: (e) => {
20302
+ : 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '7000fa21f319e3c1fd2290710a60a4e4bd44d25b', class: "camera-controls" }, 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 ? (h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (h("div", { key: '76e6765fc5264de81eeeab184d23c3ba23cd0976', class: "camera-selector-dropdown" }, h("div", { key: '0a9eb0ffc9a2a8ec5a632e0dc1e367a4f89c0499', class: "camera-selector-header" }, h("span", { key: 'ad09fc0efb7cda425853a156d310da57ddfa1906' }, "Seleccionar C\u00E1mara"), h("button", { key: '2ebaff48a49b56e6b65cd93c96048e3050ad92a4', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: 'fbb80070332766d85f9a91856d90251928490a5f', 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}`, camera.hasAutofocus && (h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (h("span", { class: "selected-indicator" }, "\u2713")))))), h("div", { key: '8ce8fbefe3cacf05f34f216de2b9539fd0f4c405', class: "device-info" }, h("small", { key: 'dec43734808a18f5a0b2c6dc8555b62d5bc4eafa' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '3560ead8bf670c71c94457689cc7280127e6bb26', class: "manual-capture-section" }, h("button", { key: 'bb642fddb0bdd3014b600869f0c9fb892f40454c', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (h("span", { key: '2bcfd2b481e43684bf38584598747e68277ab18a', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (h("div", { key: '7c6ac830d622ff91de6f03273b11bdebf64b335e', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: '8a6b470eaafc34aadc6192553e38ccadf5755272', class: "flip-animation" }, h("div", { key: '965bc9d8858447eb44cc860df814fa54fc7ab697', class: "id-card-icon" }), h("div", { key: '2a4ff10eb928f88501e25112597efc345a6c587a', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: 'a599c61bb9dd4b910abdb1a5cb271484184a1ecd', class: "success-animation" }, h("div", { key: 'ce0d1f0f824e4ef2d3f24521246fde546bcb479a', class: "check-icon" }), h("div", { key: '752859c69c65130cd065f1fa6d15269ce7789035', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: '421768cd2d6aa9ab491861fb0cae305470b1456b', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: '81374800169c2b4e331cf8f876085c3420700423', class: "status-spinner" })), h("div", { key: 'f13c794c2c8c71bed1cae401f7e1104edfcad428', class: "status-content" }, h("div", { key: 'e662075d24c9400eb6e6b97e785f8453ea2c350b', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: '42e03d32e3697b4095c190a670c04dd1a09d5f9d', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: 'cda6b3292ef939bbc1f0f0176ef55b8c8fc37929', class: "performance-monitor" }, h("div", { key: 'bc149a754f6e65f1870f2ce151f502694a2a8e52', class: "performance-expanded" }, h("div", { key: '30d7519b0ea3c72997363840dad433fbeef64569', class: "metrics-row" }, h("div", { key: 'da4101538afc21090ceb59f5d48ca4d48abc41e0', class: "metric-compact" }, h("span", { key: '8150ece409d7e62f61d79507d3a332042af5934a', class: "metric-label" }, "FPS"), h("span", { key: '0b07ac0de7f294f8d253e0c57931c52345918914', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: '7242ad6791000c0d6cd86cfe5043c961f57ea754', class: "metric-compact" }, h("span", { key: '5499d7e3fac025933916b3efbd2b511128515ff8', class: "metric-label" }, "MEM"), h("span", { key: '885851d31aa1b639e8e2352b4c6813ee2b45b953', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: '14e3bda4caab1b182cb772e2da4cea4d3c342d00', class: "metrics-row" }, h("div", { key: 'be33011987e3cfa6b499fa618aba0575f6253992', class: "metric-compact" }, h("span", { key: '111dd593ba724adbd148a9bba5728db6f569b88d', class: "metric-label" }, "INF"), h("span", { key: '104680823cc990a0181a7a770c50ad43241856f8', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '006e6417a404a9296170bc1c20660716a9eca169', class: "metric-compact" }, h("span", { key: '2f5e7c8cfcd99e22b0c5399a05eb84816e6c3133', class: "metric-label" }, "FRAME"), h("span", { key: '3cedfc835bf282e513aef93e3e96a0154a62193b', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: '21ba720f1a3a4a5a900bf75602a0286a779b7cd0', class: "metrics-row" }, h("div", { key: 'b1bcdabe6feeee08068d70e280772a15f1ff9a1a', class: "metric-compact" }, h("span", { key: 'b9686f5946d878366b6b282a677b4e10eed7e3f3', class: "metric-label" }, "DET"), h("span", { key: 'fd6cf1adac9dd90936f64e6da93a9ea16bc060d1', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: 'a4f796a8b19f3689f68a9213df7335b93d3947ad', class: "metric-compact" }, h("span", { key: 'abdec7d8b8cfc53cb635ba513d01e95e68ceb703', class: "metric-label" }, "RATE"), h("span", { key: '8fa1b3a30ad7dfcc77ee86c022e085b779a9ced7', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: 'f9d1c4fd872a7d7bfd06b0b31ad557941de5067d', class: "watermark" }, h("img", { key: 'e9ea47bbc2eca4bde520198924e417e94f4e228f', src: "https://static.jaak.ai/commons/powered-by-jaak.png", alt: "Powered by Jaak", onError: (e) => {
20223
20303
  const img = e.target;
20224
20304
  img.onerror = null;
20225
20305
  img.src = POWERED_BY_JAAK_FALLBACK;
@@ -20767,7 +20847,7 @@ const JaakStamps = class {
20767
20847
  await this.tracingService.flush();
20768
20848
  }
20769
20849
  catch (error) {
20770
- console.error('[my-component] Failed to flush traces:', error);
20850
+ console.error('[jaak-stamps] Failed to flush traces:', error);
20771
20851
  }
20772
20852
  }
20773
20853
  this.captureCompleted.emit(finalImages);
@@ -21040,8 +21120,12 @@ const JaakStamps = class {
21040
21120
  // If pool is full, let the canvas be garbage collected
21041
21121
  }
21042
21122
  static get assetsDirs() { return ["../../assets"]; }
21123
+ static get watchers() { return {
21124
+ "license": ["onLicenseChanged"],
21125
+ "licenseEnvironment": ["onLicenseEnvironmentChanged"]
21126
+ }; }
21043
21127
  };
21044
- JaakStamps.style = myComponentCss;
21128
+ JaakStamps.style = jaakStampsCss;
21045
21129
 
21046
21130
  export { JaakStamps as jaak_stamps };
21047
21131
  //# sourceMappingURL=jaak-stamps.entry.js.map