@jaak.ai/stamps 2.5.7 → 2.5.8-dev.1

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 +195 -74
  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} +140 -36
  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 +60 -38
  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 +197 -73
  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 +195 -74
  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-63c2c085.entry.js → p-474f6bec.entry.js} +3 -3
  27. package/dist/jaak-stamps-webcomponent/p-474f6bec.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} +7 -0
  31. package/dist/types/services/DetectionService.d.ts +5 -4
  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-63c2c085.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();
@@ -796,15 +796,6 @@ class DetectionService {
796
796
  INPUT_SIZE = 320;
797
797
  CONFIDENCE_THRESHOLD = 0.6;
798
798
  useFloat16 = true;
799
- // Hoisted views for float32->float16 bit-twiddling. A fresh ArrayBuffer
800
- // per call was costing ~614K allocations per frame.
801
- _f32View = new Float32Array(1);
802
- _u32View = new Uint32Array(this._f32View.buffer);
803
- // Pre-allocated tensor buffers reused across frames. Same shape every time
804
- // (3 * INPUT_SIZE * INPUT_SIZE), and runInference is awaited before the next
805
- // preprocess runs, so reuse is safe.
806
- _tensorF32 = new Float32Array(3 * 320 * 320);
807
- _tensorF16 = new Uint16Array(3 * 320 * 320);
808
799
  // Canvas pool for optimization
809
800
  preprocessCanvas;
810
801
  preprocessCtx;
@@ -831,7 +822,7 @@ class DetectionService {
831
822
  try {
832
823
  const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);
833
824
  try {
834
- this.session = await window.ort.InferenceSession.create(this.MODEL_PATH, sessionOptions);
825
+ this.session = await this.createSession(this.MODEL_PATH, sessionOptions);
835
826
  this.detectFloat16Support();
836
827
  }
837
828
  catch (error) {
@@ -846,7 +837,7 @@ class DetectionService {
846
837
  if (isFloat16Error) {
847
838
  this.useFloat16 = false;
848
839
  try {
849
- this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, sessionOptions);
840
+ this.session = await this.createSession(this.MODEL_PATH_FP32, sessionOptions);
850
841
  }
851
842
  catch (fp32Error) {
852
843
  // Intentar con opciones minimas de WASM
@@ -855,7 +846,7 @@ class DetectionService {
855
846
  graphOptimizationLevel: 'all',
856
847
  logSeverityLevel: this.debug ? 2 : 4,
857
848
  };
858
- this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, wasmOptions);
849
+ this.session = await this.createSession(this.MODEL_PATH_FP32, wasmOptions);
859
850
  }
860
851
  }
861
852
  else if (isMemoryError) {
@@ -874,7 +865,7 @@ class DetectionService {
874
865
  };
875
866
  this.useFloat16 = false;
876
867
  try {
877
- this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, fallbackOptions);
868
+ this.session = await this.createSession(this.MODEL_PATH_FP32, fallbackOptions);
878
869
  }
879
870
  catch (fallbackError) {
880
871
  throw new Error(`no available backend found. ERR: [wasm] RangeError: Out of memory`);
@@ -915,7 +906,7 @@ class DetectionService {
915
906
  // Load model
916
907
  const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);
917
908
  try {
918
- this.mobileNetSession = await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, sessionOptions);
909
+ this.mobileNetSession = await this.createSession(this.MOBILENET_MODEL_PATH, sessionOptions);
919
910
  }
920
911
  catch (error) {
921
912
  // Múltiples tipos de errores de memoria que pueden ocurrir
@@ -939,7 +930,7 @@ class DetectionService {
939
930
  sessionLogVerbosityLevel: 0,
940
931
  };
941
932
  try {
942
- this.mobileNetSession = await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, fallbackOptions);
933
+ this.mobileNetSession = await this.createSession(this.MOBILENET_MODEL_PATH, fallbackOptions);
943
934
  }
944
935
  catch (fallbackError) {
945
936
  throw new Error(`no available backend found. ERR: [wasm] RangeError: Out of memory`);
@@ -965,31 +956,25 @@ class DetectionService {
965
956
  if (!this.preprocessCanvas || !this.preprocessCtx) {
966
957
  this.initializeCanvasPool();
967
958
  }
968
- const SIZE = this.INPUT_SIZE;
969
- this.preprocessCtx.clearRect(0, 0, SIZE, SIZE);
970
- this.preprocessCtx.drawImage(video, 0, 0, SIZE, SIZE);
971
- const imageData = this.preprocessCtx.getImageData(0, 0, SIZE, SIZE);
959
+ this.preprocessCtx.clearRect(0, 0, this.INPUT_SIZE, this.INPUT_SIZE);
960
+ this.preprocessCtx.drawImage(video, 0, 0, this.INPUT_SIZE, this.INPUT_SIZE);
961
+ const imageData = this.preprocessCtx.getImageData(0, 0, this.INPUT_SIZE, this.INPUT_SIZE);
962
+ const [R, G, B] = [[], [], []];
972
963
  const { data } = imageData;
973
- const pixels = SIZE * SIZE;
974
- const gOffset = pixels;
975
- const bOffset = pixels * 2;
976
- const inv255 = 1 / 255;
964
+ for (let i = 0; i < data.length; i += 4) {
965
+ R.push(data[i] / 255);
966
+ G.push(data[i + 1] / 255);
967
+ B.push(data[i + 2] / 255);
968
+ }
969
+ const transposedData = new Float32Array(R.concat(G, B));
977
970
  if (this.useFloat16) {
978
- const out = this._tensorF16;
979
- for (let i = 0, p = 0; i < data.length; i += 4, p++) {
980
- out[p] = this.float32ToFloat16(data[i] * inv255);
981
- out[gOffset + p] = this.float32ToFloat16(data[i + 1] * inv255);
982
- out[bOffset + p] = this.float32ToFloat16(data[i + 2] * inv255);
971
+ const float16Data = new Uint16Array(transposedData.length);
972
+ for (let i = 0; i < transposedData.length; i++) {
973
+ float16Data[i] = this.float32ToFloat16(transposedData[i]);
983
974
  }
984
- return new window.ort.Tensor("float16", out, [1, 3, SIZE, SIZE]);
985
- }
986
- const out = this._tensorF32;
987
- for (let i = 0, p = 0; i < data.length; i += 4, p++) {
988
- out[p] = data[i] * inv255;
989
- out[gOffset + p] = data[i + 1] * inv255;
990
- out[bOffset + p] = data[i + 2] * inv255;
975
+ return new window.ort.Tensor("float16", float16Data, [1, 3, this.INPUT_SIZE, this.INPUT_SIZE]);
991
976
  }
992
- return new window.ort.Tensor("float32", out, [1, 3, SIZE, SIZE]);
977
+ return new window.ort.Tensor("float32", transposedData, [1, 3, this.INPUT_SIZE, this.INPUT_SIZE]);
993
978
  }
994
979
  async runInference(inputTensor) {
995
980
  if (!this.useDocumentDetector) {
@@ -1137,6 +1122,41 @@ class DetectionService {
1137
1122
  areAllSidesAligned(alignment) {
1138
1123
  return alignment.top && alignment.right && alignment.bottom && alignment.left;
1139
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
+ }
1140
1160
  cleanup() {
1141
1161
  this.cleanupCanvasPool();
1142
1162
  if (this.session) {
@@ -1181,8 +1201,10 @@ class DetectionService {
1181
1201
  }
1182
1202
  }
1183
1203
  float32ToFloat16(value) {
1184
- this._f32View[0] = value;
1185
- const f = this._u32View[0];
1204
+ const buffer = new ArrayBuffer(4);
1205
+ const view = new DataView(buffer);
1206
+ view.setFloat32(0, value, true);
1207
+ const f = view.getUint32(0, true);
1186
1208
  const sign = (f >> 31) & 0x1;
1187
1209
  const exp = (f >> 23) & 0xFF;
1188
1210
  const frac = f & 0x7FFFFF;
@@ -18645,7 +18667,7 @@ class LicenseValidationService {
18645
18667
  }
18646
18668
  }
18647
18669
 
18648
- 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}}";
18649
18671
 
18650
18672
  const JaakStamps = class {
18651
18673
  constructor(hostRef) {
@@ -18675,7 +18697,7 @@ const JaakStamps = class {
18675
18697
  propagateTraceHeaderCorsUrls; // Comma-separated URLs or regex patterns
18676
18698
  metricsExportIntervalMillis = 60000; // Export metrics every 60 seconds
18677
18699
  license; // License key for validation
18678
- licenseEnvironment = 'prod'; // Environment for license validation
18700
+ licenseEnvironment = 'prod';
18679
18701
  traceId; // Optional trace ID for tracking
18680
18702
  appId = 'jaak-stamps-web'; // Application ID for license validation
18681
18703
  captureCompleted;
@@ -18723,6 +18745,10 @@ const JaakStamps = class {
18723
18745
  licenseValid = true; // License validation status
18724
18746
  licenseError = null; // License validation error message
18725
18747
  classificationDisabled = false; // Classification disabled at runtime due to errors
18748
+ _initialized = false;
18749
+ _initializing = false;
18750
+ _pendingEnvironmentRetry = false;
18751
+ _pendingInit = null;
18726
18752
  // Services
18727
18753
  licenseValidationService = null;
18728
18754
  serviceContainer;
@@ -18792,45 +18818,111 @@ const JaakStamps = class {
18792
18818
  canvasPool = [];
18793
18819
  MAX_CANVAS_POOL_SIZE = 3;
18794
18820
  async componentWillLoad() {
18821
+ // @Watch handlers fire synchronously when Angular sets properties, which happens
18822
+ // BEFORE componentWillLoad (Stencil schedules componentWillLoad as a microtask after
18823
+ // connectedCallback, while Angular sets props synchronously in that same call stack).
18824
+ // @Watch('license') defers init to a macrotask so @Watch('licenseEnvironment') fires
18825
+ // first. By the time we resume here, init may already be in progress.
18826
+ await new Promise(resolve => setTimeout(resolve, 50));
18795
18827
  if (this.debug) {
18796
- console.log('[JAAK-DEBUG] componentWillLoad() - Props at initialization:');
18828
+ console.log('[JAAK-DEBUG] componentWillLoad() - Props after yield:');
18829
+ console.log('[JAAK-DEBUG] license:', this.license ? this.license.substring(0, 8) + '...' : 'EMPTY');
18830
+ console.log('[JAAK-DEBUG] licenseEnvironment:', this.licenseEnvironment);
18831
+ console.log('[JAAK-DEBUG] _initializing:', this._initializing);
18832
+ console.log('[JAAK-DEBUG] _initialized:', this._initialized);
18797
18833
  console.log('[JAAK-DEBUG] useDocumentDetector:', this.useDocumentDetector, '(type:', typeof this.useDocumentDetector, ')');
18798
18834
  console.log('[JAAK-DEBUG] useDocumentClassification:', this.useDocumentClassification);
18799
18835
  console.log('[JAAK-DEBUG] debug:', this.debug);
18800
- console.log('[JAAK-DEBUG] license:', this.license ? this.license.substring(0, 8) + '...' : 'EMPTY');
18801
- console.log('[JAAK-DEBUG] licenseEnvironment:', this.licenseEnvironment);
18802
18836
  console.log('[JAAK-DEBUG] alignmentTolerance:', this.alignmentTolerance);
18803
18837
  console.log('[JAAK-DEBUG] maskSize:', this.maskSize);
18804
18838
  console.log('[JAAK-DEBUG] captureDelay:', this.captureDelay);
18805
18839
  console.log('[JAAK-DEBUG] preferredCamera:', this.preferredCamera);
18806
18840
  console.log('[JAAK-DEBUG] appId:', this.appId);
18807
18841
  }
18808
- // License is required - always validate
18809
- // Wait a bit to ensure props are set from attributes
18810
- await new Promise(resolve => setTimeout(resolve, 50));
18811
- if (this.debug) {
18812
- console.log('[JAAK-DEBUG] Props AFTER 50ms wait:');
18813
- console.log('[JAAK-DEBUG] useDocumentDetector:', this.useDocumentDetector, '(type:', typeof this.useDocumentDetector, ')');
18814
- }
18815
- this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18816
- await this.validateLicense();
18817
- // If license validation failed, stop initialization
18818
- if (!this.licenseValid) {
18819
- if (this.debug) {
18820
- console.error('[JAAK-DEBUG] License validation FAILED. Stopping initialization.');
18842
+ if (!this.license) {
18843
+ if (!this._initialized && !this._initializing) {
18844
+ // No license and init not started — show blocking error UI
18845
+ this.licenseValid = false;
18846
+ this.licenseError = 'Se requiere una licencia para continuar. Por favor, proporcione una licencia usando el atributo "license".';
18847
+ this.updateStatus('Licencia requerida', 'Proporcione una licencia para continuar', 'error');
18821
18848
  }
18822
- return;
18823
18849
  }
18824
- if (this.debug) {
18825
- console.log('[JAAK-DEBUG] License validation OK');
18850
+ else if (!this._initialized && !this._initializing) {
18851
+ // License present but init hasn't started yet (no @Watch fired) — set initial status
18852
+ // so the first render already shows it without a redundant state change in componentDidLoad
18853
+ this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18826
18854
  }
18855
+ // Heavy initialization is deferred to componentDidLoad so the first render is not blocked
18827
18856
  }
18828
18857
  async componentDidLoad() {
18858
+ // If @Watch('license') already scheduled or started init, let it proceed
18859
+ if (!this.license || this._initialized || this._initializing || this._pendingInit !== null) {
18860
+ return;
18861
+ }
18862
+ await this.validateAndInitialize();
18863
+ }
18864
+ onLicenseChanged(newLicense) {
18865
+ if (!newLicense || this._initialized || this._initializing) {
18866
+ return;
18867
+ }
18868
+ // Defer init by one macrotask (setTimeout 0) so @Watch('licenseEnvironment') fires
18869
+ // first. Angular applies [license] before [licenseEnvironment] in template order,
18870
+ // meaning a synchronous start here would use the Stencil default "prod" for the env.
18871
+ if (this._pendingInit !== null)
18872
+ clearTimeout(this._pendingInit);
18873
+ this._pendingInit = setTimeout(async () => {
18874
+ this._pendingInit = null;
18875
+ if (!this._initialized && !this._initializing && this.license) {
18876
+ this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18877
+ await this.validateAndInitialize();
18878
+ }
18879
+ }, 0);
18880
+ }
18881
+ async onLicenseEnvironmentChanged() {
18882
+ // Always recreate the service so the correct environment URL is ready.
18883
+ this.licenseValidationService = new LicenseValidationService(this.licenseEnvironment);
18884
+ if (this._initializing) {
18885
+ // Validation is already in-flight with the wrong environment.
18886
+ // Flag a retry so validateAndInitialize restarts once the current attempt ends.
18887
+ this._pendingEnvironmentRetry = true;
18888
+ return;
18889
+ }
18890
+ // If @Watch('license') already scheduled a deferred init, that init will read
18891
+ // this.licenseEnvironment at fire time (after this handler returns), so the
18892
+ // correct URL will be used — no need to trigger a second init here.
18893
+ if (this._pendingInit !== null) {
18894
+ return;
18895
+ }
18896
+ if (this._initialized) {
18897
+ // Component was fully initialized with the wrong env URL (e.g. Ionic animation
18898
+ // delayed Angular's CD past the initial validateAndInitialize() cycle).
18899
+ // Re-validate the license only — services and camera are already running.
18900
+ await this.validateLicense();
18901
+ return;
18902
+ }
18903
+ if (this.license) {
18904
+ this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18905
+ await this.validateAndInitialize();
18906
+ }
18907
+ }
18908
+ async validateAndInitialize() {
18909
+ if (this._initialized || this._initializing) {
18910
+ return;
18911
+ }
18912
+ this._initializing = true;
18829
18913
  try {
18830
- // If license validation failed, stop initialization
18914
+ // Status was already set synchronously by the caller (componentWillLoad or @Watch)
18915
+ // to avoid a state change inside componentDidLoad that Stencil warns about.
18916
+ await this.validateLicense();
18831
18917
  if (!this.licenseValid) {
18918
+ if (this.debug) {
18919
+ console.error('[JAAK-DEBUG] License validation FAILED. Stopping initialization.');
18920
+ }
18832
18921
  return;
18833
18922
  }
18923
+ if (this.debug) {
18924
+ console.log('[JAAK-DEBUG] License validation OK');
18925
+ }
18834
18926
  this.updateStatus('Preparando capturador...', 'Configurando herramientas de captura', 'initializing');
18835
18927
  await this.initializeServices();
18836
18928
  this.updateStatus('Preparando funciones...', 'Configurando herramientas de trabajo', 'initializing');
@@ -18840,9 +18932,30 @@ const JaakStamps = class {
18840
18932
  if (this.debug) {
18841
18933
  this.initializePerformanceMonitor();
18842
18934
  }
18935
+ this._initialized = true;
18843
18936
  }
18844
18937
  catch (error) {
18845
- this.updateStatus('Error de inicialización', error.message, 'error');
18938
+ const errorMessage = error instanceof Error ? error.message : String(error);
18939
+ this.updateStatus('Error de inicialización', errorMessage, 'error');
18940
+ }
18941
+ finally {
18942
+ this._initializing = false;
18943
+ if (this._pendingEnvironmentRetry && this.license) {
18944
+ this._pendingEnvironmentRetry = false;
18945
+ if (this._initialized) {
18946
+ // Already fully initialized with wrong env URL — re-validate only the license.
18947
+ // Services and camera are already running and don't depend on the env URL.
18948
+ await this.validateLicense();
18949
+ }
18950
+ else {
18951
+ // Not yet initialized — full retry with the correct environment.
18952
+ this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18953
+ await this.validateAndInitialize();
18954
+ }
18955
+ }
18956
+ else {
18957
+ this._pendingEnvironmentRetry = false;
18958
+ }
18846
18959
  }
18847
18960
  }
18848
18961
  async initializeServices() {
@@ -18892,14 +19005,14 @@ const JaakStamps = class {
18892
19005
  }
18893
19006
  async validateLicense() {
18894
19007
  if (!this.license) {
18895
- console.error('❌ No license provided for JAAK Stamps component');
18896
19008
  this.licenseError = 'Este componente requiere una licencia válida. Por favor, proporcione una licencia usando el atributo "license".';
18897
19009
  this.licenseValid = false;
18898
19010
  this.updateStatus('Error de licencia', 'Licencia no proporcionada', 'error');
18899
19011
  return;
18900
19012
  }
18901
19013
  try {
18902
- console.log('🔑 Validating license for JAAK Stamps...');
19014
+ if (this.debug)
19015
+ console.log('[jaak-stamps] validating license...');
18903
19016
  // Initialize license validation service
18904
19017
  this.licenseValidationService = new LicenseValidationService(this.licenseEnvironment);
18905
19018
  // Validate the license, passing traceId and appId if provided
@@ -18907,18 +19020,21 @@ const JaakStamps = class {
18907
19020
  if (response && response.access_token) {
18908
19021
  this.licenseValid = true;
18909
19022
  this.licenseError = null;
18910
- console.log('✅ License validated successfully for JAAK Stamps');
19023
+ if (this.debug)
19024
+ console.log('[jaak-stamps] license validated successfully');
18911
19025
  // Emit the traceId (either provided or generated)
18912
19026
  if (response.traceId) {
18913
19027
  this.traceIdGenerated.emit({ traceId: response.traceId });
18914
- console.log('📋 TraceId:', response.traceId);
19028
+ if (this.debug)
19029
+ console.log('[jaak-stamps] traceId:', response.traceId);
18915
19030
  }
18916
19031
  }
18917
19032
  else {
18918
19033
  this.licenseValid = false;
18919
19034
  this.licenseError = 'La licencia proporcionada no es válida. Por favor, verifique su licencia e intente nuevamente.';
18920
19035
  this.updateStatus('Error de licencia', 'Licencia inválida', 'error');
18921
- console.error('❌ Invalid license for JAAK Stamps');
19036
+ if (this.debug)
19037
+ console.error('[jaak-stamps] invalid license');
18922
19038
  }
18923
19039
  }
18924
19040
  catch (error) {
@@ -18926,7 +19042,8 @@ const JaakStamps = class {
18926
19042
  const licenseError = error;
18927
19043
  this.licenseError = licenseError.error_description || 'Error al validar la licencia. Por favor, verifique su conexión e intente nuevamente.';
18928
19044
  this.updateStatus('Error de licencia', 'Fallo en la validación', 'error');
18929
- console.error('❌ License validation failed for JAAK Stamps:', error);
19045
+ if (this.debug)
19046
+ console.error('[jaak-stamps] license validation failed:', error);
18930
19047
  }
18931
19048
  }
18932
19049
  async setupEventListeners() {
@@ -20212,7 +20329,7 @@ const JaakStamps = class {
20212
20329
  isCapturing: false
20213
20330
  };
20214
20331
  const cameraInfo = this.cameraInfoWithAutofocus;
20215
- 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: {
20332
+ return (h("div", { key: 'c0a28d9fd8a66fc8589c0111508ea959f07c143f', class: "detector-container" }, !this.licenseValid && this.licenseError && (h("div", { key: '1d0162e9d56c65f646884d12a3c73f4ed7e4c1fc', class: "license-error-container" }, h("div", { key: 'a50de01af3d60f4dbe2d17c9d059f79ad0fc8191', class: "license-error-card" }, h("svg", { key: '1dd6b599a3ca9bf818aec832638bab23b4ae4074', 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: 'c7175baf6b409428d820326e24522c7dd0b28811', 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: '1ff3c700981b50ed670a499054ceb7b4afc12bc2', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), h("circle", { key: 'f0adaa57bc3a218eedf92478f577a381fdb29268', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), h("h2", { key: '076e4aaf687e47d2553ba264af3de5ff67b03c60', class: "license-error-title" }, "Licencia Requerida"), h("p", { key: '607d2793649698c5686ee98af1e4c48921cba094', class: "license-error-message" }, this.licenseError), h("p", { key: '2d5eef84366fabdfea2106e7e5a198ab085c3a01', class: "license-error-help" }, "Contacte a soporte: ", h("a", { key: '91d7d22d72f78ae52bc8ddc0955b3ac559474579', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), h("div", { key: '0ccf2e04602f740b6dd8551068c044d17691ba38', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (h("div", { key: '339a6066a03d820c74cfd77ce7d582d2282dbf05', class: "video-container" }, h("video", { key: '680e86ddef25468ea253febbbc2a5b895b9be955', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: {
20216
20333
  // Keep the element rendered (display: block) so the browser
20217
20334
  // loads stream metadata and fires 'loadedmetadata'. Hiding it
20218
20335
  // with display:none prevents metadata loading in Chrome and
@@ -20221,7 +20338,7 @@ const JaakStamps = class {
20221
20338
  // render context alive.
20222
20339
  opacity: captureState.isVideoActive ? '1' : '0',
20223
20340
  visibility: captureState.isVideoActive ? 'visible' : 'hidden',
20224
- } }), 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: {
20341
+ } }), h("div", { key: '521004bb615866dcf160086009810a543fe26a24', 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: {
20225
20342
  position: 'absolute',
20226
20343
  left: `${box.x}px`,
20227
20344
  top: `${box.y}px`,
@@ -20230,9 +20347,9 @@ const JaakStamps = class {
20230
20347
  border: '2px solid #32406C',
20231
20348
  pointerEvents: 'none',
20232
20349
  boxSizing: 'border-box'
20233
- } })))), 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
20350
+ } })))), this.isMaskReady && (h("div", { key: '7b4657df6b922001c726e004c326fe2bc5b20e65', class: "overlay-mask" }, h("div", { key: 'c5075a15c4cb994f5628df2be55c0b01077f20f3', class: "card-outline" }, h("div", { key: '5028c29cb564a77d7e29ea8fa5877da2d93659e3', class: "side side-top" }), h("div", { key: 'e8ce9c8bf2e771ad7862e5127a7d137755f85038', class: "side side-right" }), h("div", { key: '351b74462df5ae239fa0519a4cbd994b5e5c5bac', class: "side side-bottom" }), h("div", { key: 'e0e8bbe59c665db264ed6174d18cb258dfaddc30', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '6e995dbe5753cdbb54773c519389aa0822c3913a', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'e1a10fcb0e57765247aea911eb24d2c079cde8ee', class: "back-capture-section" }, h("div", { key: '3da2aacdce5badcab9017ea5316a124690773b55', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (h("button", { key: 'e04c02cfa13728d7a771243167e9c94c92e3c934', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (h("span", { key: '47759f79990eb34c69e39b2b9f6d71e6c2d8bb33', class: "button-spinner" })), "Capturar Reverso")), h("button", { key: 'e41860634d1df34bfa30c2559fc85322088888ee', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (h("span", { key: '44358375377638cd7a7c0699fba5739f38230727', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
20234
20351
  ? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
20235
- : '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) => {
20352
+ : 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '2f3d35c91e490da2cb458f317fb2a7ece836ca01', class: "camera-controls" }, h("button", { key: '21718e9ab6932bb8bd88ca16cc820081b1ed6469', 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: '1873af9e9d2ff2761e750713606a3b06295fb2f7', class: "camera-selector-dropdown" }, h("div", { key: 'df3f445f7ff51efe298f070c56dbfdd217397ea0', class: "camera-selector-header" }, h("span", { key: 'f9f33b0c4ed4bf62e18020f54b90f6ce09e923aa' }, "Seleccionar C\u00E1mara"), h("button", { key: '28c29c4c82557c80e42b3f524041ab8e160cfce1', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: '95d06551595ca0b7d23ed16c8c4ead633f98ed2f', 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: '6844114f4fa6e6a49d1194c4eaac71db4e2c2030', class: "device-info" }, h("small", { key: 'db82272ae5d253dd59fb42326e11ca1d50c70e3e' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '04bc5e0a469478dab6a5e1e957fa830be15555bc', class: "manual-capture-section" }, h("button", { key: '4fae0d4ca89e718a69143d6167dc3f295bc2fafa', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (h("span", { key: '5cb26e80c3216ce4940cf24ff1c18e0664a45eb7', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (h("div", { key: 'c4e99932aca8940f339aa80d1c9659223d026395', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: '4102bccccbae2163e7bb520761d871e07a30e34d', class: "flip-animation" }, h("div", { key: '1f9cd0f6d54f643251d24553fe6022f9045a50d6', class: "id-card-icon" }), h("div", { key: '1fba0dd3d1b25a1b39f3bda66c8706fd43bf996d', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: '08a0df4e7f7dbf5134cc89d2e300c04825b00495', class: "success-animation" }, h("div", { key: 'f94b29abea00c8293da5420981215f929fda19c3', class: "check-icon" }), h("div", { key: '01380c7e83e147bf841540178ba56d705c7f3258', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: '37d9824236643701b13de9d54adf83662625e6d5', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: '37d6da93b822edf62161a1657887ae1050d16e29', class: "status-spinner" })), h("div", { key: '6275ed024cbbeb436b7f04e0dd3bb7cfed1a6a9d', class: "status-content" }, h("div", { key: '9c983c432febd71eff737e395e3104711bf8b994', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: '721704c457c378f9563cd28e1e52fa35c68636d8', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: '0e0ed8e26c2ce73601a88ea74f97da447ad957a3', class: "performance-monitor" }, h("div", { key: 'ce46a8da032a38c4c7e6afaf706af5a7ba258f74', class: "performance-expanded" }, h("div", { key: '50566325fd8e54d9b5146c95a7965b262b5cbe7e', class: "metrics-row" }, h("div", { key: '2c255f1ab96cc0fb3e454b58a37dfe22f6df8ef2', class: "metric-compact" }, h("span", { key: '151e4bbf19f362bf32bb4ec838c5ff858ae5c8e6', class: "metric-label" }, "FPS"), h("span", { key: '4dcf58fd6d13106ca1fdb28331aebf6ff71c7886', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: '58d0745fb27b0b216fd3865e8fac4731811536c8', class: "metric-compact" }, h("span", { key: '0c16975cb5f84351fbad0b6daa6a8d1214f3226e', class: "metric-label" }, "MEM"), h("span", { key: 'cf8edc14a7ad690c80dfaeae4f2eaa0b07f88ca3', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: 'c50c14ac229f3a71fc37b256fd5caab77f0c43b2', class: "metrics-row" }, h("div", { key: 'b67d2719f42ae342c791d64a52e702af4d54bdbb', class: "metric-compact" }, h("span", { key: 'c2ecf87d853dc935b1dad5dd77adee52d1c56404', class: "metric-label" }, "INF"), h("span", { key: '86cad05a1846ed3e4e73175acd9a6acabbecb801', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '82268593f3edea53553b35d4a7ef4c4677ab56c6', class: "metric-compact" }, h("span", { key: '937ff57182396d280cb753818b62829d73f7ca4d', class: "metric-label" }, "FRAME"), h("span", { key: '6f605b44484ed9e916f16fd50c91e7eb55d45172', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: '5c3c1bd6bde1d43338be02d3f711314fc7c9603c', class: "metrics-row" }, h("div", { key: 'bfa796075c5be71dbd8f78471ad2243392561edd', class: "metric-compact" }, h("span", { key: '9c2a2999f7026c96f24ef049c2779b1b63b7759a', class: "metric-label" }, "DET"), h("span", { key: '5ea705bcde4f534d23d23cf1bfbdbf228d394b22', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: 'cd73965baaed7267be05bf6a8990707b94ad3761', class: "metric-compact" }, h("span", { key: 'f7ddd8f95353e21c776c31298c4508e0ee9fffc3', class: "metric-label" }, "RATE"), h("span", { key: '2388af4b2ec742889a01b922a44f0d169e747b56', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: '822ae802489dc1621a2edebfb513c0966ea1d4b8', class: "watermark" }, h("img", { key: 'bc98d9afb9cb8336bfac25d3f1af3a09f49aafb3', src: "https://static.jaak.ai/commons/powered-by-jaak.png", alt: "Powered by Jaak", onError: (e) => {
20236
20353
  const img = e.target;
20237
20354
  img.onerror = null;
20238
20355
  img.src = POWERED_BY_JAAK_FALLBACK;
@@ -20780,7 +20897,7 @@ const JaakStamps = class {
20780
20897
  await this.tracingService.flush();
20781
20898
  }
20782
20899
  catch (error) {
20783
- console.error('[my-component] Failed to flush traces:', error);
20900
+ console.error('[jaak-stamps] Failed to flush traces:', error);
20784
20901
  }
20785
20902
  }
20786
20903
  this.captureCompleted.emit(finalImages);
@@ -21053,8 +21170,12 @@ const JaakStamps = class {
21053
21170
  // If pool is full, let the canvas be garbage collected
21054
21171
  }
21055
21172
  static get assetsDirs() { return ["../../assets"]; }
21173
+ static get watchers() { return {
21174
+ "license": ["onLicenseChanged"],
21175
+ "licenseEnvironment": ["onLicenseEnvironmentChanged"]
21176
+ }; }
21056
21177
  };
21057
- JaakStamps.style = myComponentCss;
21178
+ JaakStamps.style = jaakStampsCss;
21058
21179
 
21059
21180
  export { JaakStamps as jaak_stamps };
21060
21181
  //# sourceMappingURL=jaak-stamps.entry.js.map