@jaak.ai/stamps 2.5.7-dev.4 → 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.
@@ -18749,6 +18749,8 @@ const JaakStamps = class {
18749
18749
  classificationDisabled = false; // Classification disabled at runtime due to errors
18750
18750
  _initialized = false;
18751
18751
  _initializing = false;
18752
+ _pendingEnvironmentRetry = false;
18753
+ _pendingInit = null;
18752
18754
  // Services
18753
18755
  licenseValidationService = null;
18754
18756
  serviceContainer;
@@ -18818,17 +18820,21 @@ const JaakStamps = class {
18818
18820
  canvasPool = [];
18819
18821
  MAX_CANVAS_POOL_SIZE = 3;
18820
18822
  async componentWillLoad() {
18821
- // Use setTimeout(0) instead of Promise.resolve() so Angular's synchronous change-detection
18822
- // cycle (which sets property bindings like licenseEnvironment) finishes before we read props.
18823
- // A microtask yield is not enough when the consuming framework defers its first CD cycle.
18824
- await new Promise(resolve => setTimeout(resolve, 0));
18823
+ // @Watch handlers fire synchronously when Angular sets properties, which happens
18824
+ // BEFORE componentWillLoad (Stencil schedules componentWillLoad as a microtask after
18825
+ // connectedCallback, while Angular sets props synchronously in that same call stack).
18826
+ // @Watch('license') defers init to a macrotask so @Watch('licenseEnvironment') fires
18827
+ // first. By the time we resume here, init may already be in progress.
18828
+ await new Promise(resolve => setTimeout(resolve, 50));
18825
18829
  if (this.debug) {
18826
- console.log('[JAAK-DEBUG] componentWillLoad() - Props after microtask yield:');
18830
+ console.log('[JAAK-DEBUG] componentWillLoad() - Props after yield:');
18831
+ console.log('[JAAK-DEBUG] license:', this.license ? this.license.substring(0, 8) + '...' : 'EMPTY');
18832
+ console.log('[JAAK-DEBUG] licenseEnvironment:', this.licenseEnvironment);
18833
+ console.log('[JAAK-DEBUG] _initializing:', this._initializing);
18834
+ console.log('[JAAK-DEBUG] _initialized:', this._initialized);
18827
18835
  console.log('[JAAK-DEBUG] useDocumentDetector:', this.useDocumentDetector, '(type:', typeof this.useDocumentDetector, ')');
18828
18836
  console.log('[JAAK-DEBUG] useDocumentClassification:', this.useDocumentClassification);
18829
18837
  console.log('[JAAK-DEBUG] debug:', this.debug);
18830
- console.log('[JAAK-DEBUG] license:', this.license ? this.license.substring(0, 8) + '...' : 'EMPTY');
18831
- console.log('[JAAK-DEBUG] licenseEnvironment:', this.licenseEnvironment);
18832
18838
  console.log('[JAAK-DEBUG] alignmentTolerance:', this.alignmentTolerance);
18833
18839
  console.log('[JAAK-DEBUG] maskSize:', this.maskSize);
18834
18840
  console.log('[JAAK-DEBUG] captureDelay:', this.captureDelay);
@@ -18836,41 +18842,67 @@ const JaakStamps = class {
18836
18842
  console.log('[JAAK-DEBUG] appId:', this.appId);
18837
18843
  }
18838
18844
  if (!this.license) {
18839
- // No license yet — show blocking UI; @Watch('license') triggers init when it arrives
18840
- this.licenseValid = false;
18841
- this.licenseError = 'Se requiere una licencia para continuar. Por favor, proporcione una licencia usando el atributo "license".';
18842
- this.updateStatus('Licencia requerida', 'Proporcione una licencia para continuar', 'error');
18845
+ if (!this._initialized && !this._initializing) {
18846
+ // No license and init not started — show blocking error UI
18847
+ this.licenseValid = false;
18848
+ this.licenseError = 'Se requiere una licencia para continuar. Por favor, proporcione una licencia usando el atributo "license".';
18849
+ this.updateStatus('Licencia requerida', 'Proporcione una licencia para continuar', 'error');
18850
+ }
18843
18851
  }
18844
- else {
18845
- // License present pre-set the first status synchronously so the initial render
18846
- // already shows it, preventing a state change inside componentDidLoad that Stencil
18847
- // would flag as an extra re-render.
18852
+ else if (!this._initialized && !this._initializing) {
18853
+ // License present but init hasn't started yet (no @Watch fired) — set initial status
18854
+ // so the first render already shows it without a redundant state change in componentDidLoad
18848
18855
  this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18849
18856
  }
18850
18857
  // Heavy initialization is deferred to componentDidLoad so the first render is not blocked
18851
18858
  }
18852
18859
  async componentDidLoad() {
18853
- // License absent at mount time — @Watch('license') handles initialization when it arrives
18854
- if (!this.license || this._initialized || this._initializing) {
18860
+ // If @Watch('license') already scheduled or started init, let it proceed
18861
+ if (!this.license || this._initialized || this._initializing || this._pendingInit !== null) {
18855
18862
  return;
18856
18863
  }
18857
18864
  await this.validateAndInitialize();
18858
18865
  }
18859
- async onLicenseChanged(newLicense) {
18866
+ onLicenseChanged(newLicense) {
18860
18867
  if (!newLicense || this._initialized || this._initializing) {
18861
18868
  return;
18862
18869
  }
18863
- // Set status synchronously before the async work so the UI updates immediately
18864
- this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18865
- await this.validateAndInitialize();
18870
+ // Defer init by one macrotask (setTimeout 0) so @Watch('licenseEnvironment') fires
18871
+ // first. Angular applies [license] before [licenseEnvironment] in template order,
18872
+ // meaning a synchronous start here would use the Stencil default "prod" for the env.
18873
+ if (this._pendingInit !== null)
18874
+ clearTimeout(this._pendingInit);
18875
+ this._pendingInit = setTimeout(async () => {
18876
+ this._pendingInit = null;
18877
+ if (!this._initialized && !this._initializing && this.license) {
18878
+ this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18879
+ await this.validateAndInitialize();
18880
+ }
18881
+ }, 0);
18866
18882
  }
18867
18883
  async onLicenseEnvironmentChanged() {
18868
- // Always recreate the service so the correct environment URL is used from now on.
18884
+ // Always recreate the service so the correct environment URL is ready.
18869
18885
  this.licenseValidationService = new LicenseValidationService(this.licenseEnvironment);
18870
- // If a license is present but the component never finished initializing
18871
- // (e.g. first validate ran against the wrong env and failed, or license arrived
18872
- // before licenseEnvironment was set), retry the full init flow now.
18873
- if (this.license && !this._initialized && !this._initializing) {
18886
+ if (this._initializing) {
18887
+ // Validation is already in-flight with the wrong environment.
18888
+ // Flag a retry so validateAndInitialize restarts once the current attempt ends.
18889
+ this._pendingEnvironmentRetry = true;
18890
+ return;
18891
+ }
18892
+ // If @Watch('license') already scheduled a deferred init, that init will read
18893
+ // this.licenseEnvironment at fire time (after this handler returns), so the
18894
+ // correct URL will be used — no need to trigger a second init here.
18895
+ if (this._pendingInit !== null) {
18896
+ return;
18897
+ }
18898
+ if (this._initialized) {
18899
+ // Component was fully initialized with the wrong env URL (e.g. Ionic animation
18900
+ // delayed Angular's CD past the initial validateAndInitialize() cycle).
18901
+ // Re-validate the license only — services and camera are already running.
18902
+ await this.validateLicense();
18903
+ return;
18904
+ }
18905
+ if (this.license) {
18874
18906
  this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18875
18907
  await this.validateAndInitialize();
18876
18908
  }
@@ -18910,6 +18942,22 @@ const JaakStamps = class {
18910
18942
  }
18911
18943
  finally {
18912
18944
  this._initializing = false;
18945
+ if (this._pendingEnvironmentRetry && this.license) {
18946
+ this._pendingEnvironmentRetry = false;
18947
+ if (this._initialized) {
18948
+ // Already fully initialized with wrong env URL — re-validate only the license.
18949
+ // Services and camera are already running and don't depend on the env URL.
18950
+ await this.validateLicense();
18951
+ }
18952
+ else {
18953
+ // Not yet initialized — full retry with the correct environment.
18954
+ this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
18955
+ await this.validateAndInitialize();
18956
+ }
18957
+ }
18958
+ else {
18959
+ this._pendingEnvironmentRetry = false;
18960
+ }
18913
18961
  }
18914
18962
  }
18915
18963
  async initializeServices() {
@@ -20283,7 +20331,7 @@ const JaakStamps = class {
20283
20331
  isCapturing: false
20284
20332
  };
20285
20333
  const cameraInfo = this.cameraInfoWithAutofocus;
20286
- return (index.h("div", { key: 'ebb920fee5499ae979cb60332342b2f0758fb497', class: "detector-container" }, !this.licenseValid && this.licenseError && (index.h("div", { key: 'c5f912119d581b52c66e72b67241a72b976ec44e', class: "license-error-container" }, index.h("div", { key: '19ab81fde436b79252b45b44e772ab303e19405e', class: "license-error-card" }, index.h("svg", { key: '68ab28d6649949dcfd4c13d2dc8e77486b242da5', class: "license-error-icon", width: "64", height: "64", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { key: '19e0e5aa75368a125a65932d116467f65a4ffffc', d: "M12 22C12 22 20 18 20 12V5L12 2L4 5V12C4 18 12 22 12 22Z", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), index.h("path", { key: 'b5aee63abfc96b7851d59d5ccb19f872de0fed66', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), index.h("circle", { key: '5d25fedbe498d583a96ec0c5c3b91872b3cdf111', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), index.h("h2", { key: '679c39266afc7c3c987a3da02510a739d4f34679', class: "license-error-title" }, "Licencia Requerida"), index.h("p", { key: '38069563654e3aa16784e77c2539620fcf2b60f6', class: "license-error-message" }, this.licenseError), index.h("p", { key: '3fcd6403a7c39e3ed6e63699d051607f348b5ea2', class: "license-error-help" }, "Contacte a soporte: ", index.h("a", { key: '328e62a4d4a70ec06eb73aa6bb90a2b7912dfdc4', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), index.h("div", { key: 'c16315263a11d06d1cd9a6aff673f1a8cd609d05', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (index.h("div", { key: 'c7baf6eca897342a564c8dfe3c3e81091bb881ef', class: "video-container" }, index.h("video", { key: '3ea8f97b026f2e53dbee64c0cd2976d9a84c47db', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: {
20334
+ return (index.h("div", { key: 'c0a28d9fd8a66fc8589c0111508ea959f07c143f', class: "detector-container" }, !this.licenseValid && this.licenseError && (index.h("div", { key: '1d0162e9d56c65f646884d12a3c73f4ed7e4c1fc', class: "license-error-container" }, index.h("div", { key: 'a50de01af3d60f4dbe2d17c9d059f79ad0fc8191', class: "license-error-card" }, index.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" }, index.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" }), index.h("path", { key: '1ff3c700981b50ed670a499054ceb7b4afc12bc2', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), index.h("circle", { key: 'f0adaa57bc3a218eedf92478f577a381fdb29268', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), index.h("h2", { key: '076e4aaf687e47d2553ba264af3de5ff67b03c60', class: "license-error-title" }, "Licencia Requerida"), index.h("p", { key: '607d2793649698c5686ee98af1e4c48921cba094', class: "license-error-message" }, this.licenseError), index.h("p", { key: '2d5eef84366fabdfea2106e7e5a198ab085c3a01', class: "license-error-help" }, "Contacte a soporte: ", index.h("a", { key: '91d7d22d72f78ae52bc8ddc0955b3ac559474579', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), index.h("div", { key: '0ccf2e04602f740b6dd8551068c044d17691ba38', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (index.h("div", { key: '339a6066a03d820c74cfd77ce7d582d2282dbf05', class: "video-container" }, index.h("video", { key: '680e86ddef25468ea253febbbc2a5b895b9be955', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: {
20287
20335
  // Keep the element rendered (display: block) so the browser
20288
20336
  // loads stream metadata and fires 'loadedmetadata'. Hiding it
20289
20337
  // with display:none prevents metadata loading in Chrome and
@@ -20292,7 +20340,7 @@ const JaakStamps = class {
20292
20340
  // render context alive.
20293
20341
  opacity: captureState.isVideoActive ? '1' : '0',
20294
20342
  visibility: captureState.isVideoActive ? 'visible' : 'hidden',
20295
- } }), index.h("div", { key: '03150c4c1d5b5978b7a1742760b56135873c754d', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index$1) => (index.h("div", { key: index$1, class: "detection-box", style: {
20343
+ } }), index.h("div", { key: '521004bb615866dcf160086009810a543fe26a24', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index$1) => (index.h("div", { key: index$1, class: "detection-box", style: {
20296
20344
  position: 'absolute',
20297
20345
  left: `${box.x}px`,
20298
20346
  top: `${box.y}px`,
@@ -20301,9 +20349,9 @@ const JaakStamps = class {
20301
20349
  border: '2px solid #32406C',
20302
20350
  pointerEvents: 'none',
20303
20351
  boxSizing: 'border-box'
20304
- } })))), this.isMaskReady && (index.h("div", { key: '96d73c2ff335d9dc7acf443c7b6e62613d2d3ed7', class: "overlay-mask" }, index.h("div", { key: 'cac27d59a12131f3d93ea763fcf7c00987861926', class: "card-outline" }, index.h("div", { key: '29b40014f26a20f7ec1aaa7dd1a154f834b40d2b', class: "side side-top" }), index.h("div", { key: 'cb31796ea1d74cfb68b4e74f7a0abbef873f67c3', class: "side side-right" }), index.h("div", { key: 'ec596a1ff9f6e51243359145a2f8a9ea5ceca61d', class: "side side-bottom" }), index.h("div", { key: '20e19a59cc88e6fab27452c828187b8916126211', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: 'd03cd5a33364b1b6cb368c998e3cb05373c284c9', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: 'd4b4760cbda1af33f4e4e037c6d0222e9f5966f0', class: "back-capture-section" }, index.h("div", { key: '318ffc4138982564b23e84b399533034b42b9ec7', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (index.h("button", { key: '33e12aae5d1981a56f5706ad840c46ea46686a8c', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (index.h("span", { key: '5e2d871d21c972c2ae929b06a971ecea5291ae09', class: "button-spinner" })), "Capturar Reverso")), index.h("button", { key: 'cd5e64d18b99893f973b8279a18ebe6058705be2', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (index.h("span", { key: 'aa41d6aae7440fa35941734398e26b7ec5c87dd6', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
20352
+ } })))), this.isMaskReady && (index.h("div", { key: '7b4657df6b922001c726e004c326fe2bc5b20e65', class: "overlay-mask" }, index.h("div", { key: 'c5075a15c4cb994f5628df2be55c0b01077f20f3', class: "card-outline" }, index.h("div", { key: '5028c29cb564a77d7e29ea8fa5877da2d93659e3', class: "side side-top" }), index.h("div", { key: 'e8ce9c8bf2e771ad7862e5127a7d137755f85038', class: "side side-right" }), index.h("div", { key: '351b74462df5ae239fa0519a4cbd994b5e5c5bac', class: "side side-bottom" }), index.h("div", { key: 'e0e8bbe59c665db264ed6174d18cb258dfaddc30', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '6e995dbe5753cdbb54773c519389aa0822c3913a', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: 'e1a10fcb0e57765247aea911eb24d2c079cde8ee', class: "back-capture-section" }, index.h("div", { key: '3da2aacdce5badcab9017ea5316a124690773b55', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (index.h("button", { key: 'e04c02cfa13728d7a771243167e9c94c92e3c934', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (index.h("span", { key: '47759f79990eb34c69e39b2b9f6d71e6c2d8bb33', class: "button-spinner" })), "Capturar Reverso")), index.h("button", { key: 'e41860634d1df34bfa30c2559fc85322088888ee', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (index.h("span", { key: '44358375377638cd7a7c0699fba5739f38230727', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
20305
20353
  ? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
20306
- : 'Saltar reverso')))), captureState.isVideoActive && (index.h("div", { key: '67dd6532dbba68518b1e63f3b7a4274c7c4752ee', class: "camera-controls" }, index.h("button", { key: '263a995b82253189b0dd38166b4922fd05116359', class: `camera-selector-button ${this.isSwitchingCamera ? 'loading' : ''}`, onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara", disabled: this.isSwitchingCamera }, this.isSwitchingCamera ? (index.h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (index.h("div", { key: '26b730e85d5e8b6343bc5f7b9fb7d8e17caa7020', class: "camera-selector-dropdown" }, index.h("div", { key: 'c738e36131f87fb1aac2d872b9e53d2e3c315056', class: "camera-selector-header" }, index.h("span", { key: 'b5fd2cfa2700bca4b27cec3a8ebfe1ece6fe111a' }, "Seleccionar C\u00E1mara"), index.h("button", { key: '5d11e0227a6727733fee1c204635146c5c748ae9', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), index.h("div", { key: '190a36537e7650d37c8ed8d891a1c97fd4303869', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (index.h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, index.h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`, camera.hasAutofocus && (index.h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (index.h("span", { class: "selected-indicator" }, "\u2713")))))), index.h("div", { key: '51405091e987752df5b85891ee9805b26d9e5fb8', class: "device-info" }, index.h("small", { key: '95c3e242217b722b584966946f4809aa61fb2b54' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '577cc09e5ffdaeef0de4c06dbb82d299e48716d6', class: "manual-capture-section" }, index.h("button", { key: 'bf1fd11171e13c4c52b83d076d6cb3c79a225a84', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (index.h("span", { key: 'cbf77eb7cb791bb298de3cbbafd9955535e32c15', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (index.h("div", { key: 'bdd3793d2ce5ba351308fb64aa5a31bfa8dd85a1', class: "capture-animation" })), captureState.showFlipAnimation && (index.h("div", { key: '0f9df69e3a1002967c407505b965c14061c47365', class: "flip-animation" }, index.h("div", { key: '1384d5b75bd5e1f3584b93711a39825ae5a9b9a0', class: "id-card-icon" }), index.h("div", { key: 'aa4912fe5a4ec46ca69793a454a8c51632381fcd', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (index.h("div", { key: '5e95f8b372b49719dd601367e9c7ba6dfbd13e30', class: "success-animation" }, index.h("div", { key: '72085304ac5fe6e2777f009a2091a39381fbc219', class: "check-icon" }), index.h("div", { key: '1476720f83274b7002365eb8c911f6dce0b84772', class: "success-text" }, "\u00A1Proceso completado!"))), index.h("div", { key: '68c3f77eb5fa1f442e9c77bcc8207189fd8126e4', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (index.h("div", { key: '22bd3df4eca189c0100795befb31408ee4399461', class: "status-spinner" })), index.h("div", { key: '84c5b65b1b9f3f92704589d791e817a75e2e677d', class: "status-content" }, index.h("div", { key: 'a474e0cc716fff4f76cfb98dd0e7783eb4521db9', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (index.h("div", { key: '5255fe7ddb68f84b7a33ecede21af80c4ef9c476', class: "status-description" }, this.currentStatus.description)))), this.debug && (index.h("div", { key: 'a4e3a44c7896d3861980cca96329cf88a1cb6693', class: "performance-monitor" }, index.h("div", { key: '145ec7a322e316bf9989ea72e7ca877eb9630016', class: "performance-expanded" }, index.h("div", { key: '5bafabe9b0c82ac4682c474dafe7ecbe9be33896', class: "metrics-row" }, index.h("div", { key: '2c30946e8340f20887ba3a2c769fd731388a1fc8', class: "metric-compact" }, index.h("span", { key: '82b3b0679c93b88f0f0d88b1cd43479f01dbbd75', class: "metric-label" }, "FPS"), index.h("span", { key: '9af03b3dda821a0b8fbaec5be7127dd41d897b5d', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), index.h("div", { key: '2d0cc36e696b72f9d616b16e8e75c9bc977dd984', class: "metric-compact" }, index.h("span", { key: '624beadfa8641dbd690059fc7606cadc413ac247', class: "metric-label" }, "MEM"), index.h("span", { key: '30bd599357c1cbe7b945d2b72c1723ba7f361982', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), index.h("div", { key: '661a150fca2411a1565cda581b105dd15a17a3d5', class: "metrics-row" }, index.h("div", { key: '82a8101abcbdebe1a32314d866a10d7be42b3e2f', class: "metric-compact" }, index.h("span", { key: '5abfae37ed5ec1f1bb14785f55a61bc1364aab40', class: "metric-label" }, "INF"), index.h("span", { key: '481df1d1fa0e1603bea786de8f20351f2cd9f949', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), index.h("div", { key: 'bfd657acb2cf6686e47c2ae4a348bf6ddfd11a66', class: "metric-compact" }, index.h("span", { key: '8dd9dfd72ae9183dce9985cca81c6ce6f80bc072', class: "metric-label" }, "FRAME"), index.h("span", { key: '09bff194b73d48d5e7c400d6132eab3741cd30f7', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), index.h("div", { key: 'ad18e77ee79c7cec2257f30ed70cf1fd4289548e', class: "metrics-row" }, index.h("div", { key: 'ca2614b32424d8ccaa5e0823a740dfefc17a1ed5', class: "metric-compact" }, index.h("span", { key: 'd4b78f37d0b23bdcc35133417960d5a744f4a7df', class: "metric-label" }, "DET"), index.h("span", { key: 'c8b52e13d51f737e7e6cd1985abf570db27ccb0e', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), index.h("div", { key: '018d1bb321178b969fa868f1cf5eecba4bfdaa1f', class: "metric-compact" }, index.h("span", { key: '19b475406a767cf7fe417fd7c7dad980f54536b9', class: "metric-label" }, "RATE"), index.h("span", { key: '5994ed1ad88e07a597d82e1246cbe90c66d58214', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), index.h("div", { key: 'f07bd04ef68386e02f0b8d468bff1547986196e5', class: "watermark" }, index.h("img", { key: '009735bf081ace290d1a8e1805dd5d27201898c4', src: "https://static.jaak.ai/commons/powered-by-jaak.png", alt: "Powered by Jaak", onError: (e) => {
20354
+ : 'Saltar reverso')))), captureState.isVideoActive && (index.h("div", { key: '2f3d35c91e490da2cb458f317fb2a7ece836ca01', class: "camera-controls" }, index.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 ? (index.h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (index.h("div", { key: '1873af9e9d2ff2761e750713606a3b06295fb2f7', class: "camera-selector-dropdown" }, index.h("div", { key: 'df3f445f7ff51efe298f070c56dbfdd217397ea0', class: "camera-selector-header" }, index.h("span", { key: 'f9f33b0c4ed4bf62e18020f54b90f6ce09e923aa' }, "Seleccionar C\u00E1mara"), index.h("button", { key: '28c29c4c82557c80e42b3f524041ab8e160cfce1', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), index.h("div", { key: '95d06551595ca0b7d23ed16c8c4ead633f98ed2f', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (index.h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, index.h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`, camera.hasAutofocus && (index.h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (index.h("span", { class: "selected-indicator" }, "\u2713")))))), index.h("div", { key: '6844114f4fa6e6a49d1194c4eaac71db4e2c2030', class: "device-info" }, index.h("small", { key: 'db82272ae5d253dd59fb42326e11ca1d50c70e3e' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '04bc5e0a469478dab6a5e1e957fa830be15555bc', class: "manual-capture-section" }, index.h("button", { key: '4fae0d4ca89e718a69143d6167dc3f295bc2fafa', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (index.h("span", { key: '5cb26e80c3216ce4940cf24ff1c18e0664a45eb7', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (index.h("div", { key: 'c4e99932aca8940f339aa80d1c9659223d026395', class: "capture-animation" })), captureState.showFlipAnimation && (index.h("div", { key: '4102bccccbae2163e7bb520761d871e07a30e34d', class: "flip-animation" }, index.h("div", { key: '1f9cd0f6d54f643251d24553fe6022f9045a50d6', class: "id-card-icon" }), index.h("div", { key: '1fba0dd3d1b25a1b39f3bda66c8706fd43bf996d', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (index.h("div", { key: '08a0df4e7f7dbf5134cc89d2e300c04825b00495', class: "success-animation" }, index.h("div", { key: 'f94b29abea00c8293da5420981215f929fda19c3', class: "check-icon" }), index.h("div", { key: '01380c7e83e147bf841540178ba56d705c7f3258', class: "success-text" }, "\u00A1Proceso completado!"))), index.h("div", { key: '37d9824236643701b13de9d54adf83662625e6d5', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (index.h("div", { key: '37d6da93b822edf62161a1657887ae1050d16e29', class: "status-spinner" })), index.h("div", { key: '6275ed024cbbeb436b7f04e0dd3bb7cfed1a6a9d', class: "status-content" }, index.h("div", { key: '9c983c432febd71eff737e395e3104711bf8b994', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (index.h("div", { key: '721704c457c378f9563cd28e1e52fa35c68636d8', class: "status-description" }, this.currentStatus.description)))), this.debug && (index.h("div", { key: '0e0ed8e26c2ce73601a88ea74f97da447ad957a3', class: "performance-monitor" }, index.h("div", { key: 'ce46a8da032a38c4c7e6afaf706af5a7ba258f74', class: "performance-expanded" }, index.h("div", { key: '50566325fd8e54d9b5146c95a7965b262b5cbe7e', class: "metrics-row" }, index.h("div", { key: '2c255f1ab96cc0fb3e454b58a37dfe22f6df8ef2', class: "metric-compact" }, index.h("span", { key: '151e4bbf19f362bf32bb4ec838c5ff858ae5c8e6', class: "metric-label" }, "FPS"), index.h("span", { key: '4dcf58fd6d13106ca1fdb28331aebf6ff71c7886', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), index.h("div", { key: '58d0745fb27b0b216fd3865e8fac4731811536c8', class: "metric-compact" }, index.h("span", { key: '0c16975cb5f84351fbad0b6daa6a8d1214f3226e', class: "metric-label" }, "MEM"), index.h("span", { key: 'cf8edc14a7ad690c80dfaeae4f2eaa0b07f88ca3', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), index.h("div", { key: 'c50c14ac229f3a71fc37b256fd5caab77f0c43b2', class: "metrics-row" }, index.h("div", { key: 'b67d2719f42ae342c791d64a52e702af4d54bdbb', class: "metric-compact" }, index.h("span", { key: 'c2ecf87d853dc935b1dad5dd77adee52d1c56404', class: "metric-label" }, "INF"), index.h("span", { key: '86cad05a1846ed3e4e73175acd9a6acabbecb801', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), index.h("div", { key: '82268593f3edea53553b35d4a7ef4c4677ab56c6', class: "metric-compact" }, index.h("span", { key: '937ff57182396d280cb753818b62829d73f7ca4d', class: "metric-label" }, "FRAME"), index.h("span", { key: '6f605b44484ed9e916f16fd50c91e7eb55d45172', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), index.h("div", { key: '5c3c1bd6bde1d43338be02d3f711314fc7c9603c', class: "metrics-row" }, index.h("div", { key: 'bfa796075c5be71dbd8f78471ad2243392561edd', class: "metric-compact" }, index.h("span", { key: '9c2a2999f7026c96f24ef049c2779b1b63b7759a', class: "metric-label" }, "DET"), index.h("span", { key: '5ea705bcde4f534d23d23cf1bfbdbf228d394b22', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), index.h("div", { key: 'cd73965baaed7267be05bf6a8990707b94ad3761', class: "metric-compact" }, index.h("span", { key: 'f7ddd8f95353e21c776c31298c4508e0ee9fffc3', class: "metric-label" }, "RATE"), index.h("span", { key: '2388af4b2ec742889a01b922a44f0d169e747b56', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), index.h("div", { key: '822ae802489dc1621a2edebfb513c0966ea1d4b8', class: "watermark" }, index.h("img", { key: 'bc98d9afb9cb8336bfac25d3f1af3a09f49aafb3', src: "https://static.jaak.ai/commons/powered-by-jaak.png", alt: "Powered by Jaak", onError: (e) => {
20307
20355
  const img = e.target;
20308
20356
  img.onerror = null;
20309
20357
  img.src = POWERED_BY_JAAK_FALLBACK;