@jaak.ai/stamps 2.5.3 → 2.5.4-dev.2

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 (31) hide show
  1. package/dist/cjs/{index-D6NBn_qu.js → index-ucw61xdq.js} +9 -2
  2. package/dist/cjs/{index-D6NBn_qu.js.map → index-ucw61xdq.js.map} +1 -1
  3. package/dist/cjs/jaak-stamps-webcomponent.cjs.js +1 -1
  4. package/dist/cjs/jaak-stamps.cjs.entry.js +295 -31
  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 +1 -1
  8. package/dist/collection/assets/powered-by-jaak.png +0 -0
  9. package/dist/collection/components/my-component/my-component.js +295 -13
  10. package/dist/collection/components/my-component/my-component.js.map +1 -1
  11. package/dist/collection/services/DetectionService.js +0 -18
  12. package/dist/collection/services/DetectionService.js.map +1 -1
  13. package/dist/components/jaak-stamps.js +295 -31
  14. package/dist/components/jaak-stamps.js.map +1 -1
  15. package/dist/esm/{index-BCfAsrzL.js → index-CqdAwiLj.js} +9 -3
  16. package/dist/esm/{index-BCfAsrzL.js.map → index-CqdAwiLj.js.map} +1 -1
  17. package/dist/esm/jaak-stamps-webcomponent.js +2 -2
  18. package/dist/esm/jaak-stamps.entry.js +295 -31
  19. package/dist/esm/jaak-stamps.entry.js.map +1 -1
  20. package/dist/esm/loader.js +2 -2
  21. package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +1 -1
  22. package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -1
  23. package/dist/jaak-stamps-webcomponent/p-178aea65.entry.js +7 -0
  24. package/dist/jaak-stamps-webcomponent/p-178aea65.entry.js.map +1 -0
  25. package/dist/jaak-stamps-webcomponent/p-CqdAwiLj.js +3 -0
  26. package/dist/jaak-stamps-webcomponent/{p-BCfAsrzL.js.map → p-CqdAwiLj.js.map} +1 -1
  27. package/dist/types/components/my-component/my-component.d.ts +10 -0
  28. package/package.json +1 -1
  29. package/dist/jaak-stamps-webcomponent/p-BCfAsrzL.js +0 -3
  30. package/dist/jaak-stamps-webcomponent/p-adece4d2.entry.js +0 -7
  31. package/dist/jaak-stamps-webcomponent/p-adece4d2.entry.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { p as promiseResolve, b as bootstrapLazy } from './index-BCfAsrzL.js';
2
- export { s as setNonce } from './index-BCfAsrzL.js';
1
+ import { p as promiseResolve, b as bootstrapLazy } from './index-CqdAwiLj.js';
2
+ export { s as setNonce } from './index-CqdAwiLj.js';
3
3
  import { g as globalScripts } from './app-globals-DQuL1Twl.js';
4
4
 
5
5
  /*
@@ -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, a as getAssetPath } from './index-CqdAwiLj.js';
2
2
 
3
3
  class EventBusService {
4
4
  events = new Map();
@@ -835,24 +835,12 @@ class DetectionService {
835
835
  errorMsg.includes('FLOAT16') ||
836
836
  errorMsg.includes('float16');
837
837
  if (isFloat16Error) {
838
- // El modelo fp16 no es compatible con este backend.
839
- // Cargar el modelo fp32 que funciona en cualquier backend.
840
- if (this.debug) {
841
- console.log('[JAAK-DEBUG] float16 model not supported, loading fp32 model:', this.MODEL_PATH_FP32);
842
- }
843
838
  this.useFloat16 = false;
844
839
  try {
845
840
  this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, sessionOptions);
846
- if (this.debug) {
847
- console.log('[JAAK-DEBUG] fp32 model loaded successfully');
848
- }
849
841
  }
850
842
  catch (fp32Error) {
851
843
  // Intentar con opciones minimas de WASM
852
- if (this.debug) {
853
- console.log('[JAAK-DEBUG] fp32 model failed with default options:', fp32Error.message);
854
- console.log('[JAAK-DEBUG] Retrying fp32 model with WASM fallback options');
855
- }
856
844
  const wasmOptions = {
857
845
  executionProviders: ['wasm'],
858
846
  graphOptimizationLevel: 'all',
@@ -887,9 +875,6 @@ class DetectionService {
887
875
  throw error;
888
876
  }
889
877
  }
890
- if (this.debug) {
891
- console.log('[JAAK-DEBUG] Model loaded. useFloat16:', this.useFloat16);
892
- }
893
878
  this.modelLoaded = true;
894
879
  }
895
880
  catch (error) {
@@ -1178,9 +1163,6 @@ class DetectionService {
1178
1163
  }
1179
1164
  catch {
1180
1165
  this.useFloat16 = false;
1181
- if (this.debug) {
1182
- console.log('[JAAK-DEBUG] float16 not supported by current backend, using float32');
1183
- }
1184
1166
  }
1185
1167
  }
1186
1168
  float32ToFloat16(value) {
@@ -18779,6 +18761,18 @@ const JaakStamps = class {
18779
18761
  processedFramesCount = 0; // Contador total de frames procesados
18780
18762
  hasAutoSwitchedToManual = false;
18781
18763
  _manualModeLoggedOnce = false;
18764
+ VIDEO_DIAGNOSTIC_EVENTS = [
18765
+ 'loadstart',
18766
+ 'loadedmetadata',
18767
+ 'loadeddata',
18768
+ 'canplay',
18769
+ 'playing',
18770
+ 'pause',
18771
+ 'stalled',
18772
+ 'suspend',
18773
+ 'abort',
18774
+ 'emptied',
18775
+ ];
18782
18776
  // Canvas pool for optimized screenshot capture
18783
18777
  canvasPool = [];
18784
18778
  MAX_CANVAS_POOL_SIZE = 3;
@@ -19507,6 +19501,130 @@ const JaakStamps = class {
19507
19501
  memoryMB: deviceMemory ? deviceMemory * 1024 : null
19508
19502
  };
19509
19503
  }
19504
+ debugLog(message, details) {
19505
+ if (!this.debug) {
19506
+ return;
19507
+ }
19508
+ if (typeof details === 'undefined') {
19509
+ console.log(`[jaak-stamps][diag] ${message}`);
19510
+ return;
19511
+ }
19512
+ console.log(`[jaak-stamps][diag] ${message}`, details);
19513
+ }
19514
+ debugWarn(message, details) {
19515
+ if (!this.debug) {
19516
+ return;
19517
+ }
19518
+ if (typeof details === 'undefined') {
19519
+ console.warn(`[jaak-stamps][diag] ${message}`);
19520
+ return;
19521
+ }
19522
+ console.warn(`[jaak-stamps][diag] ${message}`, details);
19523
+ }
19524
+ summarizeId(id) {
19525
+ if (!id) {
19526
+ return null;
19527
+ }
19528
+ return id.length <= 8 ? id : `${id.slice(0, 8)}...`;
19529
+ }
19530
+ getCameraDevicesSnapshot() {
19531
+ return this.cameraService.getAvailableCameras().map(camera => ({
19532
+ label: camera.label || '(sin label)',
19533
+ deviceId: this.summarizeId(camera.deviceId),
19534
+ groupId: this.summarizeId(camera.groupId),
19535
+ kind: camera.kind,
19536
+ }));
19537
+ }
19538
+ sanitizeTrackSettings(settings) {
19539
+ if (!settings) {
19540
+ return null;
19541
+ }
19542
+ return {
19543
+ ...settings,
19544
+ deviceId: this.summarizeId(settings.deviceId),
19545
+ groupId: this.summarizeId(settings.groupId),
19546
+ };
19547
+ }
19548
+ sanitizeTrackConstraints(track) {
19549
+ if (!track) {
19550
+ return null;
19551
+ }
19552
+ const constraints = track.getConstraints ? track.getConstraints() : {};
19553
+ const sanitizedConstraints = { ...constraints };
19554
+ if (typeof sanitizedConstraints.deviceId === 'string') {
19555
+ sanitizedConstraints.deviceId = this.summarizeId(sanitizedConstraints.deviceId);
19556
+ }
19557
+ return sanitizedConstraints;
19558
+ }
19559
+ getStreamSnapshot(stream) {
19560
+ if (!stream) {
19561
+ return { hasStream: false };
19562
+ }
19563
+ const videoTrack = stream.getVideoTracks()[0];
19564
+ if (!videoTrack) {
19565
+ return {
19566
+ hasStream: true,
19567
+ streamActive: stream.active,
19568
+ trackCount: stream.getTracks().length,
19569
+ hasVideoTrack: false,
19570
+ };
19571
+ }
19572
+ return {
19573
+ hasStream: true,
19574
+ streamActive: stream.active,
19575
+ trackCount: stream.getTracks().length,
19576
+ trackLabel: videoTrack.label || '(sin label)',
19577
+ trackEnabled: videoTrack.enabled,
19578
+ trackMuted: videoTrack.muted,
19579
+ trackReadyState: videoTrack.readyState,
19580
+ settings: this.sanitizeTrackSettings(videoTrack.getSettings ? videoTrack.getSettings() : undefined),
19581
+ constraints: this.sanitizeTrackConstraints(videoTrack),
19582
+ };
19583
+ }
19584
+ getVideoElementSnapshot() {
19585
+ if (!this.videoRef) {
19586
+ return { hasVideoRef: false };
19587
+ }
19588
+ const computedStyle = this.el.ownerDocument?.defaultView?.getComputedStyle(this.videoRef);
19589
+ return {
19590
+ hasVideoRef: true,
19591
+ isConnected: this.videoRef.isConnected,
19592
+ readyState: this.videoRef.readyState,
19593
+ networkState: this.videoRef.networkState,
19594
+ paused: this.videoRef.paused,
19595
+ muted: this.videoRef.muted,
19596
+ autoplay: this.videoRef.autoplay,
19597
+ playsInline: this.videoRef.playsInline,
19598
+ currentTime: Number.isFinite(this.videoRef.currentTime)
19599
+ ? Number(this.videoRef.currentTime.toFixed(3))
19600
+ : this.videoRef.currentTime,
19601
+ videoWidth: this.videoRef.videoWidth,
19602
+ videoHeight: this.videoRef.videoHeight,
19603
+ clientWidth: this.videoRef.clientWidth,
19604
+ clientHeight: this.videoRef.clientHeight,
19605
+ hasSrcObject: !!this.videoRef.srcObject,
19606
+ display: computedStyle?.display ?? 'unknown',
19607
+ visibility: computedStyle?.visibility ?? 'unknown',
19608
+ };
19609
+ }
19610
+ attachVideoDiagnosticListeners() {
19611
+ if (!this.debug || !this.videoRef) {
19612
+ return () => undefined;
19613
+ }
19614
+ const video = this.videoRef;
19615
+ const listeners = this.VIDEO_DIAGNOSTIC_EVENTS.map(eventName => {
19616
+ const handler = () => {
19617
+ this.debugLog(`video event "${eventName}"`, this.getVideoElementSnapshot());
19618
+ };
19619
+ video.addEventListener(eventName, handler);
19620
+ return { eventName, handler };
19621
+ });
19622
+ return () => {
19623
+ listeners.forEach(({ eventName, handler }) => {
19624
+ video.removeEventListener(eventName, handler);
19625
+ });
19626
+ };
19627
+ }
19510
19628
  // DETECTION METHODS
19511
19629
  async startDetection() {
19512
19630
  try {
@@ -19593,12 +19711,19 @@ const JaakStamps = class {
19593
19711
  this.updateStatus('Configurando cámara...', 'Buscando dispositivos disponibles', 'loading');
19594
19712
  try {
19595
19713
  await this.cameraService.enumerateDevices();
19714
+ this.debugLog('step 2/5 enumerateDevices()', {
19715
+ cameras: this.getCameraDevicesSnapshot(),
19716
+ selectedCameraId: this.summarizeId(this.cameraService.getSelectedCameraId() || undefined),
19717
+ });
19596
19718
  }
19597
19719
  catch (enumerateError) {
19598
19720
  throw new Error(`Error al enumerar dispositivos: ${enumerateError.message}`);
19599
19721
  }
19600
19722
  try {
19601
19723
  await this.updateCameraInfoWithAutofocus();
19724
+ this.debugLog('step 2/5 updateCameraInfoWithAutofocus()', {
19725
+ cameraInfo: this.cameraInfoWithAutofocus,
19726
+ });
19602
19727
  }
19603
19728
  catch (cameraInfoError) {
19604
19729
  throw new Error(`Error al actualizar información de cámara: ${cameraInfoError.message}`);
@@ -19608,6 +19733,10 @@ const JaakStamps = class {
19608
19733
  let stream;
19609
19734
  try {
19610
19735
  stream = await this.cameraService.setupCamera();
19736
+ this.debugLog('step 3/5 setupCamera() resolved', {
19737
+ stream: this.getStreamSnapshot(stream),
19738
+ videoRef: this.getVideoElementSnapshot(),
19739
+ });
19611
19740
  }
19612
19741
  catch (setupError) {
19613
19742
  throw new Error(`Error al configurar cámara: ${setupError.message}`);
@@ -19620,7 +19749,15 @@ const JaakStamps = class {
19620
19749
  this.updateStatus('Captura activa', 'Posicione su documento y use el botón para capturar', 'active');
19621
19750
  }
19622
19751
  try {
19752
+ this.debugLog('step 4/5 initializeVideoStream() start', {
19753
+ stream: this.getStreamSnapshot(stream),
19754
+ videoRef: this.getVideoElementSnapshot(),
19755
+ });
19623
19756
  await this.initializeVideoStream(stream);
19757
+ this.debugLog('step 4/5 initializeVideoStream() completed', {
19758
+ stream: this.getStreamSnapshot(stream),
19759
+ videoRef: this.getVideoElementSnapshot(),
19760
+ });
19624
19761
  }
19625
19762
  catch (videoError) {
19626
19763
  throw new Error(`Error al inicializar video: ${videoError.message}`);
@@ -19638,9 +19775,19 @@ const JaakStamps = class {
19638
19775
  if (!this.useDocumentDetector) {
19639
19776
  this.showManualCaptureButton = true;
19640
19777
  }
19778
+ this.debugLog('step 5/5 capture loop ready', {
19779
+ videoRef: this.getVideoElementSnapshot(),
19780
+ stream: this.getStreamSnapshot(this.videoStream),
19781
+ useDocumentDetector: this.useDocumentDetector,
19782
+ });
19641
19783
  this.detectFrame();
19642
19784
  }
19643
19785
  catch (err) {
19786
+ this.debugWarn('startDetection() failed', {
19787
+ error: err instanceof Error ? err.message : String(err),
19788
+ videoRef: this.getVideoElementSnapshot(),
19789
+ stream: this.getStreamSnapshot(this.videoStream),
19790
+ });
19644
19791
  console.error('[jaak-stamps] Error al preparar captura:', err);
19645
19792
  this.updateStatus('Error al iniciar', 'No se pudo preparar la captura', 'error');
19646
19793
  this.stateManager.updateCaptureState({ isLoading: false });
@@ -19650,11 +19797,93 @@ const JaakStamps = class {
19650
19797
  if (!this.videoRef) {
19651
19798
  throw new Error('Video element not available');
19652
19799
  }
19800
+ const detachVideoDiagnosticListeners = this.attachVideoDiagnosticListeners();
19801
+ this.debugLog('initializeVideoStream() pre-assign', {
19802
+ stream: this.getStreamSnapshot(stream),
19803
+ videoRef: this.getVideoElementSnapshot(),
19804
+ });
19653
19805
  this.videoRef.srcObject = stream;
19654
19806
  this.videoStream = stream;
19807
+ this.debugLog('initializeVideoStream() post-srcObject assignment', {
19808
+ stream: this.getStreamSnapshot(stream),
19809
+ videoRef: this.getVideoElementSnapshot(),
19810
+ });
19655
19811
  const isRear = this.cameraService.isRearCamera(stream);
19656
19812
  this.shouldMirrorVideo = !isRear;
19657
19813
  const LOAD_METADATA_TIMEOUT_MS = 10000;
19814
+ // Diagnostic instrumentation: when the timeout fires we need enough
19815
+ // context to distinguish between "OS muted the track", "permission
19816
+ // revoked mid-flight", "device never produced frames" and other modes
19817
+ // that all surface as the same generic timeout error.
19818
+ const track = stream.getVideoTracks()[0];
19819
+ const waitStart = performance.now();
19820
+ const trackEvents = [];
19821
+ const recordTrackEvent = (event) => {
19822
+ trackEvents.push({
19823
+ at: Math.round(performance.now() - waitStart),
19824
+ event,
19825
+ state: track?.readyState,
19826
+ });
19827
+ };
19828
+ const onTrackMute = () => recordTrackEvent('mute');
19829
+ const onTrackUnmute = () => recordTrackEvent('unmute');
19830
+ const onTrackEnded = () => recordTrackEvent('ended');
19831
+ if (track) {
19832
+ track.addEventListener('mute', onTrackMute);
19833
+ track.addEventListener('unmute', onTrackUnmute);
19834
+ track.addEventListener('ended', onTrackEnded);
19835
+ }
19836
+ const cleanupTrackListeners = () => {
19837
+ if (!track)
19838
+ return;
19839
+ track.removeEventListener('mute', onTrackMute);
19840
+ track.removeEventListener('unmute', onTrackUnmute);
19841
+ track.removeEventListener('ended', onTrackEnded);
19842
+ };
19843
+ const captureDiagnostics = () => {
19844
+ const settings = track?.getSettings?.();
19845
+ const computed = this.videoRef ? getComputedStyle(this.videoRef) : null;
19846
+ return {
19847
+ reason: 'VIDEO_METADATA_TIMEOUT',
19848
+ waitedMs: Math.round(performance.now() - waitStart),
19849
+ stream: {
19850
+ videoTrackCount: stream.getVideoTracks().length,
19851
+ audioTrackCount: stream.getAudioTracks().length,
19852
+ },
19853
+ track: track ? {
19854
+ readyState: track.readyState,
19855
+ muted: track.muted,
19856
+ enabled: track.enabled,
19857
+ label: track.label,
19858
+ kind: track.kind,
19859
+ settings: settings ? {
19860
+ width: settings.width,
19861
+ height: settings.height,
19862
+ frameRate: settings.frameRate,
19863
+ deviceId: settings.deviceId,
19864
+ facingMode: settings.facingMode,
19865
+ } : null,
19866
+ } : null,
19867
+ video: this.videoRef ? {
19868
+ readyState: this.videoRef.readyState,
19869
+ networkState: this.videoRef.networkState,
19870
+ error: this.videoRef.error ? { code: this.videoRef.error.code, message: this.videoRef.error.message } : null,
19871
+ paused: this.videoRef.paused,
19872
+ offsetWidth: this.videoRef.offsetWidth,
19873
+ offsetHeight: this.videoRef.offsetHeight,
19874
+ videoWidth: this.videoRef.videoWidth,
19875
+ videoHeight: this.videoRef.videoHeight,
19876
+ display: computed?.display,
19877
+ visibility: computed?.visibility,
19878
+ } : null,
19879
+ document: {
19880
+ visibilityState: document.visibilityState,
19881
+ hasFocus: document.hasFocus(),
19882
+ },
19883
+ trackEvents,
19884
+ userAgent: navigator.userAgent,
19885
+ };
19886
+ };
19658
19887
  const finalizeStreamInitialization = async () => {
19659
19888
  try {
19660
19889
  await this.videoRef.play();
@@ -19669,24 +19898,39 @@ const JaakStamps = class {
19669
19898
  const rect = container.getBoundingClientRect();
19670
19899
  this.updateMaskDimensions(rect);
19671
19900
  }
19901
+ this.debugLog('initializeVideoStream() finalized after play()', {
19902
+ stream: this.getStreamSnapshot(stream),
19903
+ videoRef: this.getVideoElementSnapshot(),
19904
+ });
19672
19905
  };
19673
19906
  // If metadata is already available (readyState >= HAVE_METADATA = 1),
19674
19907
  // the 'loadedmetadata' event will not fire again. Handle both cases.
19675
19908
  if (this.videoRef.readyState >= 1) {
19676
- if (this.debug) {
19677
- console.log('[JAAK-DEBUG] Video metadata already available (readyState:', this.videoRef.readyState, '), skipping event wait');
19678
- }
19909
+ this.debugLog('video metadata already available, skipping event wait', this.getVideoElementSnapshot());
19910
+ cleanupTrackListeners();
19679
19911
  await finalizeStreamInitialization();
19912
+ detachVideoDiagnosticListeners();
19680
19913
  return;
19681
19914
  }
19682
19915
  return new Promise((resolve, reject) => {
19683
19916
  let settled = false;
19917
+ const cleanup = () => {
19918
+ this.videoRef.onloadedmetadata = null;
19919
+ this.videoRef.onerror = null;
19920
+ detachVideoDiagnosticListeners();
19921
+ };
19684
19922
  const timeoutId = setTimeout(() => {
19685
19923
  if (settled)
19686
19924
  return;
19687
19925
  settled = true;
19688
- this.videoRef.onloadedmetadata = null;
19689
- this.videoRef.onerror = null;
19926
+ const diagnostics = captureDiagnostics();
19927
+ this.debugWarn(`initializeVideoStream() timeout after ${LOAD_METADATA_TIMEOUT_MS}ms`, {
19928
+ videoRef: this.getVideoElementSnapshot(),
19929
+ stream: this.getStreamSnapshot(stream),
19930
+ });
19931
+ console.error('[jaak-stamps] Video metadata timeout diagnostics (json):', JSON.stringify(diagnostics));
19932
+ cleanup();
19933
+ cleanupTrackListeners();
19690
19934
  reject(new Error(`Video metadata load timeout after ${LOAD_METADATA_TIMEOUT_MS}ms`));
19691
19935
  }, LOAD_METADATA_TIMEOUT_MS);
19692
19936
  this.videoRef.onloadedmetadata = async () => {
@@ -19694,13 +19938,18 @@ const JaakStamps = class {
19694
19938
  return;
19695
19939
  settled = true;
19696
19940
  clearTimeout(timeoutId);
19697
- this.videoRef.onloadedmetadata = null;
19698
- this.videoRef.onerror = null;
19941
+ this.debugLog('initializeVideoStream() onloadedmetadata fired', {
19942
+ videoRef: this.getVideoElementSnapshot(),
19943
+ stream: this.getStreamSnapshot(stream),
19944
+ });
19945
+ cleanupTrackListeners();
19699
19946
  try {
19700
19947
  await finalizeStreamInitialization();
19948
+ cleanup();
19701
19949
  resolve();
19702
19950
  }
19703
19951
  catch (err) {
19952
+ cleanup();
19704
19953
  reject(err);
19705
19954
  }
19706
19955
  };
@@ -19709,8 +19958,13 @@ const JaakStamps = class {
19709
19958
  return;
19710
19959
  settled = true;
19711
19960
  clearTimeout(timeoutId);
19712
- this.videoRef.onloadedmetadata = null;
19713
- this.videoRef.onerror = null;
19961
+ this.debugWarn('initializeVideoStream() video element emitted error', {
19962
+ event,
19963
+ videoRef: this.getVideoElementSnapshot(),
19964
+ stream: this.getStreamSnapshot(stream),
19965
+ });
19966
+ cleanup();
19967
+ cleanupTrackListeners();
19714
19968
  reject(new Error(`Video element error: ${event}`));
19715
19969
  };
19716
19970
  });
@@ -19935,7 +20189,16 @@ const JaakStamps = class {
19935
20189
  isCapturing: false
19936
20190
  };
19937
20191
  const cameraInfo = this.cameraInfoWithAutofocus;
19938
- return (h("div", { key: 'd9e8fef8a096429937860396347148e6bdd06340', class: "detector-container" }, !this.licenseValid && this.licenseError && (h("div", { key: '7eb2f885adab60a4b8b1667bf0a362510d537794', class: "license-error-container" }, h("div", { key: 'af1079677131e33d5cc7698d4da03b2ba012c4bf', class: "license-error-card" }, h("svg", { key: 'f968e7c76c710dd8a4b6b407a026346d524740fe', 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: '39f44307ef8a1ef1fb786dc925fb753f647aa94c', 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: '64fe021fadc616f46e69b35a7950ad503f55028a', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), h("circle", { key: 'aa86c48652cce218d24f78f49c0f32f8485184ca', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), h("h2", { key: 'b49877aa248f90ef207cc26a294f3f7f4f5f8e03', class: "license-error-title" }, "Licencia Requerida"), h("p", { key: 'fe929456590ae3ee78804613072df9c873732f99', class: "license-error-message" }, this.licenseError), h("p", { key: '1177a85cdd98a3dfd120043ce58256a33095d720', class: "license-error-help" }, "Contacte a soporte: ", h("a", { key: 'd5fe21ac8932ab88907e59775d459597cbd3b51f', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), h("div", { key: '3b764654f555dae41581f5d855548b8f3382e0f2', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (h("div", { key: '4051657a840db456841fdea943409f75c4c72985', class: "video-container" }, h("video", { key: 'aa7fb4da7f721a511f4e8bbd9d2727ff2a3c350f', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), h("div", { key: 'a9f5839bd5f7543f5e3e37701c95c3528d233161', 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: {
20192
+ return (h("div", { key: '20689d87a0b2f3ec851837a57f97b4bb79ecf10a', class: "detector-container" }, !this.licenseValid && this.licenseError && (h("div", { key: '3dccc3f6fd3ed0db2c2e7034d5cb0940625bade1', class: "license-error-container" }, h("div", { key: '5f39d0762dc5fea0f5d5402cd61f696090e96865', class: "license-error-card" }, h("svg", { key: '34d8290684decfe194328eba1b4af1b582f02518', 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: '2cc8b54522b550f127c1b05a6f8069b78156f84a', 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: 'b3c7918292661cfc92fbc0d3ec237acb80364fa5', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), h("circle", { key: '86a258f69cdf26588436cba2056bdf7c92d08244', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), h("h2", { key: '06e4fbde528663e485ae9a3b04945e6c95595ab2', class: "license-error-title" }, "Licencia Requerida"), h("p", { key: '7466b075c8cf31d67535512e4bdaa1473e89ed47', class: "license-error-message" }, this.licenseError), h("p", { key: 'ba4d06029ef7e896e51ad5c6e2dd72a9a162ef08', class: "license-error-help" }, "Contacte a soporte: ", h("a", { key: '177832433d66cf581743d8774a055405fa1f83fc', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), h("div", { key: 'ce1b33ae5289689c3e07cbb2a68f4411aa3ed2d2', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (h("div", { key: '394ee2b3c487c9673c1df3b483900720beb42ea5', class: "video-container" }, h("video", { key: '50ba3fb80f05ed35bdc58f9d75538d083cd7af32', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: {
20193
+ // Keep the element rendered (display: block) so the browser
20194
+ // loads stream metadata and fires 'loadedmetadata'. Hiding it
20195
+ // with display:none prevents metadata loading in Chrome and
20196
+ // causes initializeVideoStream to hang waiting for the event.
20197
+ // Use opacity + visibility to hide visually while keeping the
20198
+ // render context alive.
20199
+ opacity: captureState.isVideoActive ? '1' : '0',
20200
+ visibility: captureState.isVideoActive ? 'visible' : 'hidden',
20201
+ } }), h("div", { key: 'a4ff51674115afeeb2c36aedbbbdf3769bf0af96', 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: {
19939
20202
  position: 'absolute',
19940
20203
  left: `${box.x}px`,
19941
20204
  top: `${box.y}px`,
@@ -19944,9 +20207,9 @@ const JaakStamps = class {
19944
20207
  border: '2px solid #32406C',
19945
20208
  pointerEvents: 'none',
19946
20209
  boxSizing: 'border-box'
19947
- } })))), this.isMaskReady && (h("div", { key: 'ad737b47a608ba2d6e43a8c41aee15ea00012966', class: "overlay-mask" }, h("div", { key: '70c5b2591dd75742eae22e444eab4d4368fc659d', class: "card-outline" }, h("div", { key: '0962f587354f4b300f6f6a1f5b9652441c3aeb5c', class: "side side-top" }), h("div", { key: '955d5346898f560e1e3fc854c4c339074613116c', class: "side side-right" }), h("div", { key: '0388ccc214b045e392c07e6e8fffe2c8d67d3582', class: "side side-bottom" }), h("div", { key: '718600bfad1eff4298628402190ffb34b7988afa', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '70603563d303912248bf60e1d39e06d78b3adbaf', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'a3639b10d52b29da6f0490356f7cdae789d62f88', class: "back-capture-section" }, h("div", { key: 'dd430526d6e096396d10367fd216b1c6568ce19b', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (h("button", { key: '04b0afd7e6adc890287749add773910445ff5255', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (h("span", { key: '69022991921cbc04ab20dee2148bb95d5dd371f8', class: "button-spinner" })), "Capturar Reverso")), h("button", { key: 'dd698341642e875e8f252746db747ca77b2f37b0', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (h("span", { key: 'c33706bf76eeb1ca401ea3df042e858e23d3a929', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
20210
+ } })))), this.isMaskReady && (h("div", { key: '6c4e710e25971692bd933486f05a231b56150e5a', class: "overlay-mask" }, h("div", { key: 'd7ec408535cd68a5a9c12e51061f3fd61745b566', class: "card-outline" }, h("div", { key: '0e4c6066cf35cdb13843e54500db8e94603203fa', class: "side side-top" }), h("div", { key: '0c61ebf0940a01b09d509675d021051ac433ba1b', class: "side side-right" }), h("div", { key: 'e1c113fa666ba1ab0b77bac98ac4b08d99bea3af', class: "side side-bottom" }), h("div", { key: '666527c49665fe1d9d04a5d3620686b7471b8d44', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '71eae3c5e89eeaffd95bc32d7ed9139a5b741cc6', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'b4d6abc22c58eabd5afb6f440701f5b909bf949e', class: "back-capture-section" }, h("div", { key: '6d4bf99ff92829efb64d6dbc7d2d14c16b7c691c', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (h("button", { key: 'f8965079e936e32722b5eb1f8dfb63a84160aa5d', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (h("span", { key: '7defab9f244899e188659fd07bf114897737bd48', class: "button-spinner" })), "Capturar Reverso")), h("button", { key: 'd5a501876ce24f25d21df5e8d47183e80be602f3', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (h("span", { key: '54e08bed19e50abdd5f5faf9e0a21d8c2cb6a368', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
19948
20211
  ? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
19949
- : 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: 'f9c95646d564518b75d7511ef69049e82760c687', class: "camera-controls" }, h("button", { key: 'ff21667ee09360e13e0b7fa190eb58d4e9ab2955', 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: '1f5d7ced9311037a22402797075862c66b541201', class: "camera-selector-dropdown" }, h("div", { key: '38ccad6dfb46613519efac337a68ad8ed68ca585', class: "camera-selector-header" }, h("span", { key: 'efd67097b98bf82455703888a0294bba18084b58' }, "Seleccionar C\u00E1mara"), h("button", { key: 'efea962578d1ff9f4dc76e40f98b6763ab32fabd', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: 'dc7fcc35ea20505547b9980f0793aab21635815f', 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: '450b9819604b9490c17759eb53468832abdf239c', class: "device-info" }, h("small", { key: '9423cb4f0f6eb767b9a9bf86412dcc74c40e3c9b' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'fc02b6ac27b7d239d07ea5df46136b5941a09020', class: "manual-capture-section" }, h("button", { key: '0e8bc7d6b2c44b66f62083bb9682880109ce1b50', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (h("span", { key: 'd4067363057c004774322ae6ac4c6aac8ac4c1a7', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (h("div", { key: '79a88a6cf21fb0d8c2883c44fe181dc34773dae6', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: '2e8f2d1441ea6ae7e62d6cb22fb8afb25308ae5b', class: "flip-animation" }, h("div", { key: '449282679041e4ad1b1f48e26185b1ab1ab3be60', class: "id-card-icon" }), h("div", { key: 'eac0b9728eefcde854ddb1675811f91ee3161176', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: '521094652be1010ebb740ef3278649bc0077fbfa', class: "success-animation" }, h("div", { key: 'e9b425d4c039f7267ecb7e3005506f07706f9054', class: "check-icon" }), h("div", { key: '4859b32d3219e325afa326651f21ce3663d9c0b8', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: '8fff23c16b531dda94a087a3ef3fe4ef0b6a51e4', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: 'e7139e242d3be20012efe25d808990fc9631492f', class: "status-spinner" })), h("div", { key: '935075ef8c1a7321e445578cdf918471e0f6e01c', class: "status-content" }, h("div", { key: '0f4910657f11df16d6cec635fdeb3864888ed55c', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: 'c362a69bed2503ecb4456b183876a5ea0645cc71', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: '04d2a4d664742ca110f562fa599b118fa5e7a282', class: "performance-monitor" }, h("div", { key: '30c37005f87500d487e23cb87dd66973ce30bcfa', class: "performance-expanded" }, h("div", { key: '647c87a140f7ea8b39348402e0355b3b15ac9616', class: "metrics-row" }, h("div", { key: '99f886b025473adcd69b42aca61f7aa8158d13cf', class: "metric-compact" }, h("span", { key: '69215c74430c502fa51402e1fcf46d31b89b34f2', class: "metric-label" }, "FPS"), h("span", { key: '27283246a143119a4a8f0e63a8ee335f76868c46', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: '6843f5f79d3e54643c6515e509364b4fa3fc032f', class: "metric-compact" }, h("span", { key: '20e83d94bf0a76e89a47b3d682e5c5c27ee94792', class: "metric-label" }, "MEM"), h("span", { key: '68922415fd8ba5ebf797f52026ecd0cf2abf861e', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: 'be6bb0a65bfc5bd16d6948f347756732918f80d1', class: "metrics-row" }, h("div", { key: 'c07a3723b79743697230a11267a6b2c8a847a86b', class: "metric-compact" }, h("span", { key: '2f2c75418ed31ba22f80112f6c02bdc32a1bc7e3', class: "metric-label" }, "INF"), h("span", { key: '788aa1a4220f0150c5ce77127d75be64104591c1', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '23bdf32e7ee8533c3327b271bd0cec93551f7c8e', class: "metric-compact" }, h("span", { key: '1d63525671ef0e99072d472f6bbe45919694ca98', class: "metric-label" }, "FRAME"), h("span", { key: '834f075061da75860a481142defddcd3973a2641', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: '2767844f849c3a8217dce6d44180b5db604284d9', class: "metrics-row" }, h("div", { key: '78e4ae2297c867c7036186bb9871800b57e6cd50', class: "metric-compact" }, h("span", { key: '9fd42d1a4c18ead68ee81bc72dddb98dcd09952c', class: "metric-label" }, "DET"), h("span", { key: '0e3c0bbf718b21c3c20ae2e68c6f1e8f5dea0624', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: '41be4df95b8745706e9b98d28cefb758e9e6b65f', class: "metric-compact" }, h("span", { key: '520b7e3d4841c0865c3643c5db33f0a762e550e7', class: "metric-label" }, "RATE"), h("span", { key: 'fe56fdd018002bce4e0efc5059cbc6562edee17f', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: '3c7b83cf7bfd1f42198edd1029f03b7c68f7766f', class: "watermark" }, h("img", { key: '5684517b58bafeffdbe6533c4dcc3ef36bec0b6c', src: "https://static.jaak.ai/commons/powered-by-jaak.png", alt: "Powered by Jaak" }))))));
20212
+ : 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '85998cae72d19792d41f94b3fa08fd7054e25c5e', class: "camera-controls" }, h("button", { key: 'fe0471dad8bdc5b45327da52af8b47f94fe2531a', 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: 'de26a8eda76aeec8e7095f793750b2336e2ff6c6', class: "camera-selector-dropdown" }, h("div", { key: '9b4085d7be39ab227a33d02b55dd46e96a68d330', class: "camera-selector-header" }, h("span", { key: '84104fb85d91ccd258c78365cad2e66b62d787b0' }, "Seleccionar C\u00E1mara"), h("button", { key: 'ad1d2b52e64ab8f0028e2cb083f495c2b432c054', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: 'e9f56e92ed01afac36ad0986dc78bfc816e60520', 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: '6fa215b5f99d33272cd96a27b2295c95113bc257', class: "device-info" }, h("small", { key: 'f8399e02a4f2a288c09df9065e138ab8def9be5f' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '4a169ae520fd5ca67716f0fe190889ace448044e', class: "manual-capture-section" }, h("button", { key: '7d7808f0d1017f6eb4c701a8582152905a228e85', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (h("span", { key: '89ee5a34898a8ba78777177001fa4406531dac3e', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (h("div", { key: '0711e1cb5619acbade20f63f6d46bdfdf827ed12', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: '720c0b1dcdb85646b4973ae15abeaef0f3a91a95', class: "flip-animation" }, h("div", { key: 'a31a9500ee6f2f35f762e2f5135219ed869c6188', class: "id-card-icon" }), h("div", { key: '7237f4284d4a5b8fb471d8a568a9c3dd2eae6409', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: '94a28257187330f5aaca2302840300460f288f71', class: "success-animation" }, h("div", { key: 'ef9d9072507faac3ae29c31b87c9439f67576c14', class: "check-icon" }), h("div", { key: '7f1c077a2b3b67ebba5d12c9b69ff943b74936e9', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: 'b9cae83d9d9717728a27bd969293fe28702befe3', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: '59382426b18de9f04dcfb179acd9a49b68af45ed', class: "status-spinner" })), h("div", { key: 'baa1972a55d439a95b3f91f38f91d9f35eecd7bd', class: "status-content" }, h("div", { key: '3fac24107d04a2b0abcbe6a3a0bff6d395c096b6', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: '196c12a4fc3e8f213b17bdd366da9e61c594a0b1', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: 'd5c36522d3bd46f434b19e8323a30f441d69c67c', class: "performance-monitor" }, h("div", { key: 'ccc8ae6b27be8d5d89e2722319cfc66a92c3a32f', class: "performance-expanded" }, h("div", { key: 'd7bed7384567663fafe4fa49dd24da4bdd05c9a3', class: "metrics-row" }, h("div", { key: 'a4409744d7d9e8a6288caf077ba5ebdc6aaa5371', class: "metric-compact" }, h("span", { key: '939e03d6aa0138c2b0c1cce16bebf158b9b74bd6', class: "metric-label" }, "FPS"), h("span", { key: '76c20f96b11725d41493b627e7a6b0fb0d594d60', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: 'fafe6b165149f1f590a0b7e26b4001b09a5c70c5', class: "metric-compact" }, h("span", { key: 'a7e99f9c05aced0cb951297ce3a6011500445421', class: "metric-label" }, "MEM"), h("span", { key: '68bd733671a9664c4533e0b24b04ad0422053f77', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: 'a53f1ac37527de249425529aff022858c8d924c5', class: "metrics-row" }, h("div", { key: '2213e3646b22056999d29107bb32e43c61dd202f', class: "metric-compact" }, h("span", { key: '31d84002498094f88f71858a91828f42b7157d23', class: "metric-label" }, "INF"), h("span", { key: 'f0ed4e90a338a05bd5193992e7f004df9d31239a', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '1288cf2f5a119f146886c08f8b7f036425ead78e', class: "metric-compact" }, h("span", { key: 'db75cca343f7c6ea588e9b62da04fc5d444604a6', class: "metric-label" }, "FRAME"), h("span", { key: '40aee793f30a9cf175be6372981ce7b7be82ed07', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: 'd193a9b4c56c6a712213a779dbc6ee161b82e828', class: "metrics-row" }, h("div", { key: '89d060083973e1931232aac0d0c0f813b8aab7ef', class: "metric-compact" }, h("span", { key: '35808d7a448e3f4c6dc27b2b325adf628b9aee16', class: "metric-label" }, "DET"), h("span", { key: 'b60da4f5a4d56e738a65fd0bc480626d4839a048', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: 'da779be083f58be8e914d062379b565fdbf7333d', class: "metric-compact" }, h("span", { key: '44645db15818eab212bc5b966213dda67f461d14', class: "metric-label" }, "RATE"), h("span", { key: '39209bdf5a5fa7c74718492218ff4fa404e94879', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: 'bb0fb66ffefa86eb6e4b72215acb930c81cb6b01', class: "watermark" }, h("img", { key: '93a1812ab9a1c91c4a81cdc939ef8410170dd6b9', src: "https://static.jaak.ai/commons/powered-by-jaak.png", alt: "Powered by Jaak", onError: (e) => { e.target.src = getAssetPath('/assets/powered-by-jaak.png'); } }))))));
19950
20213
  }
19951
20214
  // Utility methods
19952
20215
  updateDetectionBoxes(boxes) {
@@ -20762,6 +21025,7 @@ const JaakStamps = class {
20762
21025
  }
20763
21026
  // If pool is full, let the canvas be garbage collected
20764
21027
  }
21028
+ static get assetsDirs() { return ["../../assets"]; }
20765
21029
  };
20766
21030
  JaakStamps.style = myComponentCss;
20767
21031