@jaak.ai/stamps 2.0.0-dev.49 → 2.0.0-dev.50

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.
@@ -0,0 +1,2 @@
1
+ import{r as e,c as t,a as i,h as s}from"./p-BP1Q4KOg.js";class a{debugMode;constructor(e=false){this.debugMode=e}setDebugMode(e){this.debugMode=e}info(...e){if(this.debugMode){console.log(`[JAAK-STAMPS] [INFO] [${(new Date).toLocaleTimeString()}]`,...e)}}warn(...e){if(this.debugMode){console.warn(`[JAAK-STAMPS] [WARN] [${(new Date).toLocaleTimeString()}]`,...e)}}error(...e){if(this.debugMode){console.error(`[JAAK-STAMPS] [ERROR] [${(new Date).toLocaleTimeString()}]`,...e)}}debug(...e){if(this.debugMode){console.debug(`[JAAK-STAMPS] [DEBUG] [${(new Date).toLocaleTimeString()}]`,...e)}}state(e,t){if(this.debugMode){console.log(`[JAAK-STAMPS] [STATE] [${(new Date).toLocaleTimeString()}] ${e}`,t||"")}}performance(e,t){if(this.debugMode){console.log(`[JAAK-STAMPS] [PERF] [${(new Date).toLocaleTimeString()}] ${e}: ${t}ms`)}}}class o{events=new Map;on(e,t){if(!this.events.has(e)){this.events.set(e,[])}this.events.get(e).push(t)}off(e,t){const i=this.events.get(e);if(i){const e=i.indexOf(t);if(e>-1){i.splice(e,1)}}}emit(e,t){const i=this.events.get(e);if(i){i.forEach((i=>{try{i(t)}catch(t){console.error(`Error in event callback for ${e}:`,t)}}))}}once(e,t){const i=s=>{t(s);this.off(e,i)};this.on(e,i)}clear(){this.events.clear()}}class r{eventBus;captureState={step:"front",isCapturing:false,isDetectionPaused:false,isVideoActive:false,isLoading:false,showFlipAnimation:false,showSuccessAnimation:false,bestScore:0,hasScreenshotTaken:false};capturedImages={front:{fullFrame:null,cropped:null},back:{fullFrame:null,cropped:null},metadata:{totalImages:0,processCompleted:false,backCaptureSkipped:false}};constructor(e){this.eventBus=e}getCaptureState(){return{...this.captureState}}updateCaptureState(e){const t={...this.captureState};this.captureState={...this.captureState,...e};this.eventBus.emit("state-changed",{previous:t,current:this.captureState,changes:e})}getCapturedImages(){return JSON.parse(JSON.stringify(this.capturedImages))}setCapturedImages(e){this.capturedImages={...this.capturedImages,...e,metadata:{...this.capturedImages.metadata,...e.metadata}};let t=0;if(this.capturedImages.front.fullFrame&&this.capturedImages.front.cropped){t+=2}if(this.capturedImages.back.fullFrame&&this.capturedImages.back.cropped){t+=2}this.capturedImages.metadata.totalImages=t}reset(){this.captureState={step:"front",isCapturing:false,isDetectionPaused:false,isVideoActive:false,isLoading:false,showFlipAnimation:false,showSuccessAnimation:false,bestScore:0,hasScreenshotTaken:false};this.capturedImages={front:{fullFrame:null,cropped:null},back:{fullFrame:null,cropped:null},metadata:{totalImages:0,processCompleted:false,backCaptureSkipped:false}};this.eventBus.emit("state-changed",{previous:null,current:this.captureState,changes:{reset:true}})}isProcessCompleted(){return this.captureState.step==="completed"}canProceedToBack(){return this.captureState.step==="front"&&this.capturedImages.front.fullFrame!==null&&this.capturedImages.front.cropped!==null}}class n{logger;eventBus;availableCameras=[];selectedCameraId=null;deviceType="desktop";preferredCameraFacing=null;preferredCamera="auto";constructor(e,t,i="auto"){this.logger=e;this.eventBus=t;this.preferredCamera=i}async detectDeviceType(){const e=navigator.userAgent;const t=/Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(e);const i=/iPad|Android/i.test(e)&&window.innerWidth>=768;if(i){this.deviceType="tablet"}else if(t){this.deviceType="mobile"}else{this.deviceType="desktop"}this.logger.state("DISPOSITIVO_DETECTADO",{deviceType:this.deviceType,userAgent:navigator.userAgent,screenDimensions:{width:window.innerWidth,height:window.innerHeight}});return this.deviceType}async enumerateDevices(){try{const e=await this.checkCameraPermission();if(e==="denied"){this.logger.error("Permiso de cámara denegado por el usuario");return[]}if(e==="prompt"){const e=await navigator.mediaDevices.getUserMedia({video:true});e.getTracks().forEach((e=>e.stop()))}const t=await navigator.mediaDevices.enumerateDevices();this.availableCameras=t.filter((e=>e.kind==="videoinput"));this.logger.state("CAMARAS_DETECTADAS",{count:this.availableCameras.length,cameras:this.availableCameras.map((e=>({id:e.deviceId,label:e.label||"Unknown Camera"})))});this.setInitialCameraPreference();this.eventBus.emit("camera-changed",this.selectedCameraId);return this.availableCameras}catch(e){this.logger.error("Error al enumerar cámaras disponibles:",e);this.handleCameraPermissionError(e);return[]}}getAvailableCameras(){return[...this.availableCameras]}isMultipleCamerasAvailable(){return this.availableCameras.length>1}getSelectedCameraId(){return this.selectedCameraId}async setSelectedCamera(e){const t=this.availableCameras.find((t=>t.deviceId===e));if(!t){throw new Error(`Camera with ID ${e} not found`)}this.selectedCameraId=e;this.updatePreferredFacing(t);this.savePreference();this.eventBus.emit("camera-changed",e)}getPreferredFacing(){return this.preferredCameraFacing}async setupCamera(e){const t=e||await this.getMaxResolution();const i=await navigator.mediaDevices.getUserMedia({video:t,audio:false});return i}async switchCamera(e){const t=this.availableCameras.find((t=>t.deviceId===e));if(!t){this.logger.warn("Cámara seleccionada no encontrada, re-enumerando dispositivos...");await this.enumerateDevices();return}await this.setSelectedCamera(e);this.logger.state("CAMARA_CAMBIADA",{label:t.label,deviceId:t.deviceId})}async flipToNextCamera(){if(!this.isMultipleCamerasAvailable())return;const e=this.availableCameras.findIndex((e=>e.deviceId===this.selectedCameraId));const t=(e+1)%this.availableCameras.length;const i=this.availableCameras[t];await this.switchCamera(i.deviceId)}savePreference(){try{const e={cameraId:this.selectedCameraId,facing:this.preferredCameraFacing,timestamp:Date.now()};localStorage.setItem("jaak-stamps-camera-preference",JSON.stringify(e));this.logger.state("PREFERENCIA_CAMARA_GUARDADA",e)}catch(e){this.logger.warn("Error al guardar preferencia de cámara:",e)}}loadPreference(){try{const e=localStorage.getItem("jaak-stamps-camera-preference");if(e){const t=JSON.parse(e);const i=this.availableCameras.some((e=>e.deviceId===t.cameraId));if(i){this.selectedCameraId=t.cameraId;this.preferredCameraFacing=t.facing;this.logger.state("PREFERENCIA_CAMARA_CARGADA",t)}}}catch(e){this.logger.warn("Error al cargar preferencia de cámara:",e)}}isRearCamera(e){const t=e.getVideoTracks()[0];if(!t)return false;const i=t.getSettings();return i.facingMode==="environment"}getCameraInfo(){return{availableCameras:this.availableCameras.map((e=>({id:e.deviceId,label:e.label||"Unknown Camera",selected:e.deviceId===this.selectedCameraId}))),selectedCameraId:this.selectedCameraId,deviceType:this.deviceType,isMultipleCamerasAvailable:this.isMultipleCamerasAvailable(),preferredFacing:this.preferredCameraFacing}}async checkCameraPermission(){try{if(!navigator.permissions){return"prompt"}const e=await navigator.permissions.query({name:"camera"});return e.state}catch(e){this.logger.warn("No se pudo verificar permisos de cámara:",e);return"prompt"}}handleCameraPermissionError(e){this.availableCameras=[];this.eventBus.emit("error",new Error(`Camera permission error: ${e.message}`))}setInitialCameraPreference(){if(this.availableCameras.length===0)return;if(this.preferredCamera==="front"){this.selectFrontCamera()}else if(this.preferredCamera==="back"){this.selectBackCamera()}else{this.selectAutoCamera()}}selectFrontCamera(){this.preferredCameraFacing="user";const e=this.availableCameras.find((e=>e.label.toLowerCase().includes("front")||e.label.toLowerCase().includes("user")||e.label.toLowerCase().includes("selfie")||!e.label.toLowerCase().includes("back")&&!e.label.toLowerCase().includes("rear")));this.selectedCameraId=e?e.deviceId:this.availableCameras[0].deviceId;this.logger.state("CAMARA_FRONTAL_SELECCIONADA",{label:e?.label||this.availableCameras[0].label,deviceId:this.selectedCameraId})}selectBackCamera(){this.preferredCameraFacing="environment";const e=this.availableCameras.find((e=>e.label.toLowerCase().includes("back")||e.label.toLowerCase().includes("rear")||e.label.toLowerCase().includes("environment")));this.selectedCameraId=e?e.deviceId:this.availableCameras[0].deviceId;this.logger.state("CAMARA_TRASERA_SELECCIONADA",{label:e?.label||this.availableCameras[0].label,deviceId:this.selectedCameraId})}selectAutoCamera(){if(this.deviceType==="mobile"||this.deviceType==="tablet"){this.selectBackCamera();this.logger.state("CAMARA_AUTO_SELECCIONADA_MOBILE",{type:"rear"})}else{this.selectedCameraId=this.availableCameras[0].deviceId;this.logger.state("CAMARA_AUTO_SELECCIONADA_DESKTOP",{label:this.availableCameras[0].label,deviceId:this.selectedCameraId})}}updatePreferredFacing(e){const t=e.label.toLowerCase().includes("back")||e.label.toLowerCase().includes("rear")||e.label.toLowerCase().includes("environment");this.preferredCameraFacing=t?"environment":"user"}async getMaxResolution(){try{const e={};if(this.selectedCameraId){e.deviceId={exact:this.selectedCameraId}}else if(this.preferredCameraFacing){e.facingMode=this.preferredCameraFacing}else{e.facingMode="environment"}const t=await navigator.mediaDevices.getUserMedia({video:e});const i=t.getVideoTracks()[0];const s=i.getCapabilities();t.getTracks().forEach((e=>e.stop()));const a={...e};this.applyAdvancedCameraSettings(a,s);if(s.width&&s.height){const e=Math.min(s.width.max,1920);const t=Math.min(s.height.max,1080);const i=/iPad|Android/i.test(navigator.userAgent)&&window.innerWidth>=768;if(i){a.width={ideal:Math.min(e,1280)};a.height={ideal:Math.min(t,720)}}else{a.width={ideal:e};a.height={ideal:t}}}this.logger.state("CONFIGURACION_CAMARA_OPTIMIZADA",{constraints:a,capabilities:this.getCapabilitiesSummary(s)});return a}catch(e){this.logger.warn("No se pudieron obtener capacidades de cámara, usando configuración de respaldo");const t=/iPad|Android/i.test(navigator.userAgent)&&window.innerWidth>=768;const i={width:{ideal:t?1280:1920},height:{ideal:t?720:1080}};this.applyBasicFocusSettings(i);if(this.selectedCameraId){i.deviceId={exact:this.selectedCameraId}}else if(this.preferredCameraFacing){i.facingMode=this.preferredCameraFacing}else{i.facingMode="environment"}return i}}applyAdvancedCameraSettings(e,t){if(t.frameRate){e.frameRate={ideal:30,min:15,max:60}}if(t.width&&t.height){e.width={ideal:Math.min(1920,t.width.max||1920),min:640};e.height={ideal:Math.min(1080,t.height.max||1080),min:480}}const i=[];const s={};if(t.focusMode){if(t.focusMode.includes("continuous")){s.focusMode="continuous"}else if(t.focusMode.includes("single-shot")){s.focusMode="single-shot"}}if(t.focusDistance){s.focusDistance={ideal:.4,min:.2,max:1}}if(t.zoom){s.zoom={ideal:1,min:t.zoom.min,max:Math.min(t.zoom.max,3)}}if(Object.keys(s).length>0){i.push(s)}if(i.length>0){e.advanced=i}}applyBasicFocusSettings(e){const t={focusMode:"continuous",exposureMode:"continuous",whiteBalanceMode:"continuous"};if(!e.advanced){e.advanced=[]}e.advanced.push(t);e.frameRate={ideal:30}}getCapabilitiesSummary(e){return{hasAutoFocus:!!e.focusMode,hasFocusDistance:!!e.focusDistance,hasExposureControl:!!e.exposureMode,hasWhiteBalance:!!e.whiteBalanceMode,hasZoom:!!e.zoom,hasTorch:e.torch!==undefined,hasImageControls:!!(e.brightness||e.contrast||e.saturation||e.sharpness),resolutionRange:e.width&&e.height?`${e.width.min}x${e.height.min} - ${e.width.max}x${e.height.max}`:"unknown"}}async setTorchEnabled(e,t){try{if(!t){this.logger.warn("No hay stream disponible para controlar el flash");return false}const i=t.getVideoTracks()[0];if(!i){this.logger.warn("No hay track de video disponible");return false}const s=i.getCapabilities();if(s.torch===undefined){this.logger.warn("El dispositivo no soporta control de flash");return false}await i.applyConstraints({advanced:[{torch:e}]});this.logger.state("FLASH_CONTROLADO",{enabled:e});return true}catch(e){this.logger.error("Error al controlar el flash:",e);return false}}async focusAtPoint(e,t,i){try{if(!i){this.logger.warn("No hay stream disponible para enfocar");return false}const s=i.getVideoTracks()[0];if(!s){this.logger.warn("No hay track de video disponible");return false}const a=s.getCapabilities();if(!a.focusMode||!a.focusMode.includes("single-shot")){this.logger.warn("El dispositivo no soporta enfoque manual");return false}await s.applyConstraints({advanced:[{focusMode:"single-shot"}]});setTimeout((async()=>{try{await s.applyConstraints({advanced:[{focusMode:"continuous"}]})}catch(e){this.logger.warn("Error al volver a enfoque continuo:",e)}}),1e3);this.logger.state("ENFOQUE_MANUAL_ACTIVADO",{x:e,y:t});return true}catch(e){this.logger.error("Error al enfocar manualmente:",e);return false}}}class c{getDeviceInfo(){const e=navigator;const t=e.deviceMemory||e.hardwareConcurrency||4;const i=e.connection||e.mozConnection||e.webkitConnection;const s=i&&(i.effectiveType==="slow-2g"||i.effectiveType==="2g");return{estimatedRAM:t,isLowMemory:true,isSlowConnection:s}}getSessionOptions(e){return{executionProviders:["wasm"],graphOptimizationLevel:"basic",logSeverityLevel:4,logVerbosityLevel:0,enableCpuMemArena:false,enableMemPattern:false,executionMode:"sequential",interOpNumThreads:1,intraOpNumThreads:1}}shouldUseSequentialLoading(){return true}}class d{getDeviceInfo(){const e=navigator;const t=e.deviceMemory||e.hardwareConcurrency||4;const i=e.connection||e.mozConnection||e.webkitConnection;const s=i&&(i.effectiveType==="slow-2g"||i.effectiveType==="2g");return{estimatedRAM:t,isLowMemory:false,isSlowConnection:s}}getSessionOptions(e){return{executionProviders:["webgl","wasm"],graphOptimizationLevel:"all",logSeverityLevel:e?2:4,logVerbosityLevel:0,enableCpuMemArena:true,enableMemPattern:true,executionMode:"parallel",interOpNumThreads:2,intraOpNumThreads:2}}shouldUseSequentialLoading(){return false}}class l{static createStrategy(){const e=navigator;const t=e.deviceMemory||e.hardwareConcurrency||4;const i=t<=4;if(i){return new c}else{return new d}}}class h{logger;debug;useDocumentClassification;session;mobileNetSession;mobileNetClassMap;modelLoaded=false;deviceStrategy;MODEL_PATH="https://storage.googleapis.com/jaak-static/web/component/stamps/ddmyp-v2.onnx";MOBILENET_MODEL_PATH="https://storage.googleapis.com/jaak-static/web/component/stamps/squeezenet.onnx";MOBILENET_CLASSES_PATH="https://storage.googleapis.com/jaak-static/web/component/stamps/cdmmp-v1.json";INPUT_SIZE=320;CONFIDENCE_THRESHOLD=.6;preprocessCanvas;preprocessCtx;captureCanvas;constructor(e,t=false,i=false){this.logger=e;this.debug=t;this.useDocumentClassification=i;this.deviceStrategy=l.createStrategy();this.initializeCanvasPool()}async loadModel(){if(this.modelLoaded||this.session){this.logger.state("MODELO_YA_PRECARGADO",{sessionExists:!!this.session,modelPreloaded:this.modelLoaded});return}try{this.logger.state("PRECARGANDO_MODELO_DETECCION",{modelPath:this.MODEL_PATH});const e=this.deviceStrategy.getSessionOptions(this.debug);try{this.session=await window.ort.InferenceSession.create(this.MODEL_PATH,e)}catch(e){if(e.message.includes("failed to allocate a buffer")){this.logger.warn("Fallo en asignación de buffer durante precarga, intentando con configuración mínima");const e={executionProviders:["wasm"],graphOptimizationLevel:"disabled",logSeverityLevel:4,enableCpuMemArena:false,enableMemPattern:false,executionMode:"sequential",interOpNumThreads:1,intraOpNumThreads:1};this.session=await window.ort.InferenceSession.create(this.MODEL_PATH,e)}else{throw e}}this.modelLoaded=true;this.logger.state("MODELO_DETECCION_CARGADO_EXITOSAMENTE",{sessionCreated:!!this.session})}catch(e){this.logger.error("Error al precargar modelo de detección:",e);throw e}}async loadClassificationModel(){if(!this.useDocumentClassification){return}try{this.logger.state("CARGANDO_MODELO_MOBILENET",{path:this.MOBILENET_MODEL_PATH});try{const e=await fetch(this.MOBILENET_CLASSES_PATH);if(e.ok){this.mobileNetClassMap=await e.json();this.logger.state("CLASES_MOBILENET_CARGADAS",{classCount:Object.keys(this.mobileNetClassMap).length})}}catch(e){this.logger.warn("No se pudo cargar el mapa de clases de MobileNet, usando clasificación básica");this.mobileNetClassMap={0:"document",1:"id_card",2:"passport",3:"license",4:"other"}}const e=this.deviceStrategy.getSessionOptions(this.debug);try{this.mobileNetSession=await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH,e)}catch(e){if(e.message.includes("failed to allocate a buffer")){this.logger.warn("Fallo en asignación de buffer de MobileNet, intentando con configuración mínima");const e={executionProviders:["wasm"],graphOptimizationLevel:"disabled",logSeverityLevel:4,enableCpuMemArena:false,enableMemPattern:false,executionMode:"sequential",interOpNumThreads:1,intraOpNumThreads:1};this.mobileNetSession=await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH,e)}else{throw e}}this.logger.state("MODELO_MOBILENET_CARGADO_EXITOSAMENTE",{sessionCreated:!!this.mobileNetSession})}catch(e){this.logger.error("Error al cargar modelo MobileNet:",e);throw e}}isModelLoaded(){return this.modelLoaded&&!!this.session}preprocess(e){if(!this.preprocessCanvas||!this.preprocessCtx){this.initializeCanvasPool()}this.preprocessCtx.clearRect(0,0,this.INPUT_SIZE,this.INPUT_SIZE);this.preprocessCtx.drawImage(e,0,0,this.INPUT_SIZE,this.INPUT_SIZE);const t=this.preprocessCtx.getImageData(0,0,this.INPUT_SIZE,this.INPUT_SIZE);const[i,s,a]=[[],[],[]];const{data:o}=t;for(let e=0;e<o.length;e+=4){i.push(o[e]/255);s.push(o[e+1]/255);a.push(o[e+2]/255)}const r=new Float32Array(i.concat(s,a));const n=new Uint16Array(r.length);for(let e=0;e<r.length;e++){n[e]=this.float32ToFloat16(r[e])}return new window.ort.Tensor("float16",n,[1,3,this.INPUT_SIZE,this.INPUT_SIZE])}async runInference(e){if(!this.session){throw new Error("Detection model not loaded")}const t={[this.session.inputNames[0]]:e};const i=await this.session.run(t);const s=i[this.session.outputNames[0]].data;const a=[];for(let e=0;e<s.length;e+=6){const[t,i,o,r,n,c]=s.slice(e,e+6);if(n>this.CONFIDENCE_THRESHOLD){a.push({x:t,y:i,w:o-t,h:r-i,score:n,classId:c})}}return a}async classifyDocument(e){if(!this.mobileNetSession||!this.mobileNetClassMap){this.logger.warn("Modelo MobileNet no está cargado, saltando clasificación");return null}try{this.logger.state("CLASIFICANDO_DOCUMENTO",{timestamp:Date.now()});const t=this.preprocessMobileNet(e);const i={[this.mobileNetSession.inputNames[0]]:t};const s=await this.mobileNetSession.run(i);const a=s[Object.keys(s)[0]].data;const o=a.reduce(((e,t,i,s)=>t>s[e]?i:e),0);const r=a[o];const n=this.mobileNetClassMap[o.toString()]||"unknown";this.logger.state("DOCUMENTO_CLASIFICADO",{class:n,confidence:r.toFixed(3),classIndex:o,timestamp:Date.now(),results:s});return{class:n,confidence:r,classIndex:o}}catch(e){this.logger.error("Error al clasificar documento:",e);return null}}checkSideAlignment(e,t){const{INPUT_SIZE:i,ID1_ASPECT_RATIO:s,shouldMirrorVideo:a,alignmentTolerance:o,maskSize:r,videoRef:n}=t;if(!n){return{top:false,right:false,bottom:false,left:false}}const c=n.videoWidth;const d=n.videoHeight;if(c===0||d===0){return{top:false,right:false,bottom:false,left:false}}const l=c/d;const h=1;let f,p;if(l>h){f=i;p=i/l}else{p=i;f=i*l}const u=p*s;let m,b;const g=r/100;if(u<=f){b=p*g;m=b*s}else{m=f*g;b=m/s}const x=m*(i/f);const y=b*(i/p);const w=i/2;const v=i/2;const A=w-x/2;const k=w+x/2;const C=v-y/2;const E=v+y/2;let M=e.x;let S=e.x+e.w;const D=e.y;const I=e.y+e.h;if(a){const e=M;const t=S;M=i-t;S=i-e}const T=o;const O=Math.abs(D-C)<=T;const P=Math.abs(S-k)<=T;const N=Math.abs(I-E)<=T;const R=Math.abs(M-A)<=T;return{top:O&&R,right:O&&P,bottom:N&&R,left:N&&P}}isCardInFrame(e){const t=e.x+e.w/2;const i=e.y+e.h/2;const s=this.INPUT_SIZE/2;const a=this.INPUT_SIZE/2;const o=40;const r=30;const n=Math.abs(t-s)<o&&Math.abs(i-a)<r;const c=e.w>150&&e.w<300&&e.h>90&&e.h<200;return n&&c}areAllSidesAligned(e){return e.top&&e.right&&e.bottom&&e.left}cleanup(){this.cleanupCanvasPool();if(this.session){this.session.release?.();this.session=undefined}if(this.mobileNetSession){this.mobileNetSession.release?.();this.mobileNetSession=undefined}this.mobileNetClassMap=undefined;this.modelLoaded=false;this.logger.state("DETECCION_SERVICE_LIMPIADO",{timestamp:Date.now()})}initializeCanvasPool(){this.preprocessCanvas=document.createElement("canvas");this.preprocessCanvas.width=this.INPUT_SIZE;this.preprocessCanvas.height=this.INPUT_SIZE;this.preprocessCtx=this.preprocessCanvas.getContext("2d",{alpha:false,willReadFrequently:true});this.captureCanvas=document.createElement("canvas");this.logger.state("CANVAS_POOL_INICIALIZADO",{preprocessCanvasSize:this.INPUT_SIZE})}cleanupCanvasPool(){if(this.preprocessCanvas){this.preprocessCtx=undefined;this.preprocessCanvas=undefined}if(this.captureCanvas){this.captureCanvas=undefined}}float32ToFloat16(e){const t=new ArrayBuffer(4);const i=new DataView(t);i.setFloat32(0,e,true);const s=i.getUint32(0,true);const a=s>>31&1;const o=s>>23&255;const r=s&8388607;let n=o-127+15;if(o===0){n=0}else if(o===255){n=31}else if(n>=31){n=31;return a<<15|n<<10}else if(n<=0){return a<<15}return a<<15|n<<10|r>>13}preprocessMobileNet(e){const t=document.createElement("canvas");t.width=224;t.height=224;const i=t.getContext("2d");i.drawImage(e,0,0,224,224);const s=i.getImageData(0,0,224,224);const a=s.data;const o=224*224;const r=new Float32Array(3*o);for(let e=0;e<o;e++){r[e]=a[e*4+0]/255;r[o+e]=a[e*4+1]/255;r[2*o+e]=a[e*4+2]/255}return new window.ort.Tensor("float32",r,[1,3,224,224])}}class f{services=new Map;constructor(e){this.initializeServices(e)}initializeServices(e){const t=new o;const i=new a(e.debug);const s=new r(t);const c=new n(i,t,e.preferredCamera);const d=new h(i,e.debug,e.useDocumentClassification);this.services.set("eventBus",t);this.services.set("logger",i);this.services.set("stateManager",s);this.services.set("cameraService",c);this.services.set("detectionService",d)}get(e){const t=this.services.get(e);if(!t){throw new Error(`Service ${e} not found`)}return t}getLogger(){return this.get("logger")}getEventBus(){return this.get("eventBus")}getStateManager(){return this.get("stateManager")}getCameraService(){return this.get("cameraService")}getDetectionService(){return this.get("detectionService")}updateConfig(e){if(e.debug!==undefined){const t=this.services.get("logger");t.setDebugMode(e.debug)}}cleanup(){this.getDetectionService().cleanup();this.getEventBus().clear();this.services.clear()}}const p=":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:#333;border:1px solid #e0e0e0;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}.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%);color:#fff;font-size:14px;font-weight:600;text-align:center;white-space:normal;background:rgba(128, 128, 128, 0.8);padding:12px 20px;border-radius:20px;max-width:300px;z-index:20}.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);animation:drawCheck 0.4s ease-out 0.2s both}.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}.skip-explanation{background-color:rgba(0, 0, 0, 0.7);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(4px);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)}}.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)}.camera-controls{position:absolute;top:16px;right:16px;z-index:25;display:flex;gap:8px;pointer-events:auto}.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(255, 255, 255, 0.3);border-top:2px solid #ffffff;border-radius:50%;animation:spin 1s linear infinite}@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)}}.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:space-between;align-items:center;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:8px;font-weight:400}.selected-indicator{font-size:14px;color:#ffffff;opacity:0.9}.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}}.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:slideInFromLeft 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}}";const u=class{constructor(i){e(this,i);this.captureCompleted=t(this,"captureCompleted");this.isReady=t(this,"isReady")}get el(){return i(this)}debug=false;alignmentTolerance=15;maskSize=80;cropMargin=20;useDocumentClassification=false;preferredCamera="auto";captureDelay=1500;enableBackDocumentTimer=false;backDocumentTimerDuration=20;captureCompleted;isReady;detectionBoxes=[];sideAlignment={top:false,right:false,bottom:false,left:false};isMaskReady=false;shouldMirrorVideo=true;showCameraSelector=false;isSwitchingCamera=false;hasDocumentDetected=false;currentStatus={message:"Inicializando componente...",description:"Configurando servicios y cargando recursos",type:"initializing",isInitialized:false};performanceData={fps:0,inferenceTime:0,memoryUsage:0,onnxLoadTime:0,frameProcessingTime:0,totalDetections:0,successfulDetections:0,detectionRate:0};backDocumentTimerRemaining=0;serviceContainer;logger;eventBus;stateManager;cameraService;detectionService;videoRef;detectionContainer;videoStream;animationId;lastDetectedBox;startTime;hasScreenshotTaken=false;alignmentStartTime;alignmentTimer;backDocumentTimer;performanceMetrics={fps:0,inferenceTime:0,memoryUsage:0,cpuUsage:0,onnxLoadTime:0,frameProcessingTime:0,totalDetections:0,successfulDetections:0,detectionRate:0,lastUpdateTime:0};performanceUpdateInterval;frameSkipCounter=0;FRAME_SKIP=2;consecutiveFailures=0;MAX_FAILURES=30;lastInferenceTime=0;MIN_INFERENCE_INTERVAL=50;async componentDidLoad(){this.updateStatus("Iniciando servicios...","Configurando módulos internos","initializing");await this.initializeServices();this.updateStatus("Configurando eventos...","Preparando comunicación entre servicios","initializing");await this.setupEventListeners();this.updateStatus("Inicializando cámara...","Detectando dispositivos disponibles","initializing");await this.initializeComponent();if(this.debug){this.initializePerformanceMonitor()}}async initializeServices(){const e={debug:this.debug,alignmentTolerance:this.alignmentTolerance,maskSize:this.maskSize,cropMargin:this.cropMargin,useDocumentClassification:this.useDocumentClassification,preferredCamera:this.preferredCamera,captureDelay:this.captureDelay};this.serviceContainer=new f(e);this.logger=this.serviceContainer.getLogger();this.eventBus=this.serviceContainer.getEventBus();this.stateManager=this.serviceContainer.getStateManager();this.cameraService=this.serviceContainer.getCameraService();this.detectionService=this.serviceContainer.getDetectionService();this.logger.state("SERVICIOS_INICIALIZADOS",{timestamp:Date.now()})}async setupEventListeners(){this.eventBus.on("state-changed",(e=>{this.handleStateChange(e)}));this.eventBus.on("camera-changed",(e=>{this.logger.state("CAMARA_CAMBIADA_EVENT",{cameraId:e})}));this.eventBus.on("error",(e=>{this.logger.error("Error en servicio:",e)}))}async initializeComponent(){this.logger.state("COMPONENTE_INICIALIZANDO",{debug:this.debug,maskSize:this.maskSize,cropMargin:this.cropMargin,useDocumentClassification:this.useDocumentClassification,preferredCamera:this.preferredCamera,captureDelay:this.captureDelay});this.validateProps();if(this.debug){this.stateManager.updateCaptureState({isLoading:true});await new Promise((e=>setTimeout(e,500)))}this.updateStatus("Detectando cámaras...","Buscando dispositivos de captura","initializing");await this.cameraService.detectDeviceType();await this.cameraService.enumerateDevices();this.updateStatus("Cargando modelo IA...","Preparando reconocimiento de documentos","initializing");await this.loadOnnxRuntime();this.initializeResizeObserver()}validateProps(){if(this.maskSize<50||this.maskSize>100){this.logger.warn(`Propiedad maskSize inválida. Valor: ${this.maskSize}, esperado: 50-100. Usando valor por defecto: 90`);this.maskSize=90}if(this.cropMargin<0||this.cropMargin>100){this.logger.warn(`Propiedad cropMargin inválida. Valor: ${this.cropMargin}, esperado: 0-100. Usando valor por defecto: 0`);this.cropMargin=0}const e=["auto","front","back"];if(!e.includes(this.preferredCamera)){this.logger.warn(`Propiedad preferredCamera inválida. Valor: ${this.preferredCamera}, esperado: ${e.join(", ")}. Usando valor por defecto: 'auto'`);this.preferredCamera="auto"}if(this.captureDelay<0||this.captureDelay>1e4){this.logger.warn(`Propiedad captureDelay inválida. Valor: ${this.captureDelay}, esperado: 0-10000. Usando valor por defecto: 1500`);this.captureDelay=1500}}async loadOnnxRuntime(){if(!window.ort){this.updateStatus("Descargando librerías...","Obteniendo recursos de reconocimiento","initializing");const e=document.createElement("script");e.src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js";document.head.appendChild(e);await new Promise((t=>{e.onload=()=>{setTimeout((()=>{this.finalizeInitialization();t(undefined)}),300)}}))}else{setTimeout((()=>{this.finalizeInitialization()}),300)}}finalizeInitialization(){this.stateManager.updateCaptureState({isLoading:false});this.currentStatus={message:"Listo para capturar",description:"",type:"ready",isInitialized:true};this.emitReadyEvent()}updateStatus(e,t,i="loading"){this.currentStatus={message:e,description:t,type:i,isInitialized:this.currentStatus.isInitialized}}emitReadyEvent(){const e=!!window.ort&&this.detectionService.isModelLoaded();this.isReady.emit(e);this.logger.state("COMPONENTE_LISTO",{ortLibraryLoaded:!!window.ort,modelPreloaded:this.detectionService.isModelLoaded(),isReady:e})}handleStateChange(e){}initializeResizeObserver(){if("ResizeObserver"in window&&this.detectionContainer){const e=new ResizeObserver((()=>{this.handleResize()}));e.observe(this.detectionContainer.parentElement)}}handleResize(){if(this.detectionContainer){const e=this.detectionContainer.parentElement;const t=e.getBoundingClientRect();this.updateMaskDimensions(t);this.logger.debug("Container redimensionado:",{width:t.width,height:t.height})}}updateMaskDimensions(e){if(!this.videoRef)return;const t=this.videoRef.videoWidth;const i=this.videoRef.videoHeight;if(t===0||i===0)return;const s=t/i;const a=e.width/e.height;let o,r;let n=0,c=0;if(s>a){o=e.width;r=e.width/s;c=(e.height-r)/2}else{r=e.height;o=e.height*s;n=(e.width-o)/2}const d=85.6/53.98;const l=r*d;let h,f;const p=this.maskSize/100;if(l<=o){f=r*p;h=f*d}else{h=o*p;f=h/d}const u=h/e.width*100;const m=f/e.height*100;const b=n+o/2;const g=c+r/2;const x=b/e.width*100;const y=g/e.height*100;this.el.style.setProperty("--mask-width",`${u}%`);this.el.style.setProperty("--mask-height",`${m}%`);this.el.style.setProperty("--mask-center-x",`${x}%`);this.el.style.setProperty("--mask-center-y",`${y}%`);this.isMaskReady=true;this.logger.state("DIMENSIONES_MASCARA_ACTUALIZADAS",{video:{width:t,height:i},displayed:{width:o,height:r},mask:{widthPercent:u,heightPercent:m},center:{x,y},offset:{x:n,y:c}})}async getCapturedImages(){const e=this.stateManager.getCaptureState();if(e.step!=="completed"){throw new Error("El proceso de captura no ha sido completado")}return this.stateManager.getCapturedImages()}async isProcessCompleted(){return this.stateManager.isProcessCompleted()}async startCapture(){await this.startDetection()}async stopCapture(){this.exitSession()}async resetCapture(){this.resetDetection()}async skipBackCapture(){const e=this.stateManager.getCaptureState();const t=this.stateManager.getCapturedImages();if(e.step==="back"&&t.front.fullFrame){this.completeProcess(true)}}async getStatus(){const e=this.stateManager.getCaptureState();const t=this.stateManager.getCapturedImages();return{isVideoActive:e.isVideoActive,captureStep:e.step,hasImages:!!(t.front.fullFrame||t.back.fullFrame),isProcessCompleted:this.stateManager.isProcessCompleted(),isModelPreloaded:this.detectionService.isModelLoaded()}}async preloadModel(){if(this.detectionService.isModelLoaded()){this.logger.state("MODELO_YA_PRECARGADO");this.updateStatus("Modelos ya cargados","","ready");return{success:true,message:"Model already loaded"}}try{const e=performance.now();this.updateStatus("Descargando modelo de detección...","Obteniendo red neuronal para reconocimiento de documentos","loading");this.stateManager.updateCaptureState({isLoading:true});await this.detectionService.loadModel();this.updateStatus("Cargando clasificador...","Preparando modelo de clasificación de tipos de documento","loading");await this.detectionService.loadClassificationModel();const t=performance.now();const i=t-e;if(this.debug){this.recordOnnxPerformance(i,0)}this.updateStatus("Optimizando modelos...","Configurando parámetros de rendimiento","loading");await new Promise((e=>setTimeout(e,300)));this.updateStatus("Modelos precargados","","ready");this.stateManager.updateCaptureState({isLoading:false});this.emitReadyEvent();this.logger.state("MODELOS_PRECARGADOS_EXITOSAMENTE",{loadTime:Math.round(i)});return{success:true,message:"Models preloaded successfully"}}catch(e){this.logger.error("Error al precargar modelos:",e);this.updateStatus("Error al cargar modelos","No se pudieron descargar los recursos necesarios","error");this.stateManager.updateCaptureState({isLoading:false});return{success:false,error:e.message}}}async getCameraInfo(){return this.cameraService.getCameraInfo()}async setPreferredCamera(e){this.preferredCamera=e;this.serviceContainer.updateConfig({preferredCamera:e});await this.cameraService.enumerateDevices();const t=this.stateManager.getCaptureState();if(t.isVideoActive){const e=this.cameraService.getSelectedCameraId();if(e){await this.cameraService.switchCamera(e)}}return{success:true,selectedCamera:this.cameraService.getSelectedCameraId(),availableCameras:this.cameraService.getAvailableCameras().length}}async setCaptureDelay(e){if(e<0||e>1e4){throw new Error("Capture delay must be between 0 and 10000 milliseconds")}this.captureDelay=e;this.serviceContainer.updateConfig({captureDelay:e});return{success:true,captureDelay:this.captureDelay}}async getCaptureDelay(){return this.captureDelay}async setTorchEnabled(e){const t=await this.cameraService.setTorchEnabled(e,this.videoStream);return{success:t,enabled:t?e:false}}async focusAtPoint(e,t){const i=await this.cameraService.focusAtPoint(e,t,this.videoStream);return{success:i,coordinates:{x:e,y:t}}}async startDetection(){this.logger.state("INICIANDO_DETECCION");try{if(!this.detectionService.isModelLoaded()){const e=performance.now();this.updateStatus("Cargando modelo de detección...","Descargando red neuronal para reconocimiento","loading");this.stateManager.updateCaptureState({isLoading:true});await this.detectionService.loadModel();this.updateStatus("Cargando clasificador...","Preparando modelo de clasificación de documentos","loading");await this.detectionService.loadClassificationModel();const t=performance.now();const i=t-e;if(this.debug){this.recordOnnxPerformance(i,0)}this.logger.state("MODELOS_CARGADOS_EN_DETECCION",{loadTime:Math.round(i)})}this.updateStatus("Detectando cámaras...","Buscando dispositivos de captura disponibles","loading");await this.cameraService.enumerateDevices();this.updateStatus("Configurando cámara...","Estableciendo resolución y parámetros óptimos","loading");const e=await this.cameraService.setupCamera();this.updateStatus("Captura activa","Buscando documento en el marco de captura","active");await this.initializeVideoStream(e);if(this.detectionContainer){const e=this.detectionContainer.parentElement;const t=e.getBoundingClientRect();this.updateMaskDimensions(t)}this.startTime=Date.now();this.stateManager.updateCaptureState({isLoading:false});this.detectFrame()}catch(e){this.logger.error("Error al inicializar detección:",e);this.updateStatus("Error al iniciar captura","No se pudo completar la inicialización","error");this.stateManager.updateCaptureState({isLoading:false})}}async initializeVideoStream(e){if(this.videoRef){this.videoRef.srcObject=e;this.videoStream=e;const t=this.cameraService.isRearCamera(e);this.shouldMirrorVideo=!t;this.logger.state("CAMARA_CONFIGURADA",{isRearCamera:t,shouldMirrorVideo:this.shouldMirrorVideo});return new Promise((e=>{this.videoRef.onloadedmetadata=async()=>{await this.videoRef.play();this.stateManager.updateCaptureState({isVideoActive:true});e()}}))}else{throw new Error("Video element not available")}}async detectFrame(){try{const e=performance.now();const t=this.stateManager.getCaptureState();if(!this.videoRef||!this.detectionContainer||!this.detectionService.isModelLoaded())return;if(t.isDetectionPaused){if(t.step!=="completed"){this.animationId=requestAnimationFrame((()=>this.detectFrame()))}return}this.frameSkipCounter++;if(this.frameSkipCounter<=this.FRAME_SKIP){if(t.step!=="completed"){this.animationId=requestAnimationFrame((()=>this.detectFrame()))}return}this.frameSkipCounter=0;const i=Date.now();if(i-this.lastInferenceTime<this.MIN_INFERENCE_INTERVAL){if(t.step!=="completed"){this.animationId=requestAnimationFrame((()=>this.detectFrame()))}return}this.lastInferenceTime=i;const s=performance.now();const a=this.detectionService.preprocess(this.videoRef);const o=await this.detectionService.runInference(a);const r=performance.now()-s;if(this.debug){this.recordOnnxPerformance(0,r)}if(this.startTime&&Date.now()-this.startTime<5e3){o.forEach((e=>{const i=this.detectionService.isCardInFrame(e);const s=i?e.score*1.2:e.score;if(s>t.bestScore){this.stateManager.updateCaptureState({bestScore:s})}}))}const n=this.hasDocumentDetected;this.hasDocumentDetected=o.length>0;if(!n&&this.hasDocumentDetected&&t.step==="back"&&this.enableBackDocumentTimer){this.startBackDocumentTimer()}if(o.length===0){this.consecutiveFailures++}else{this.consecutiveFailures=0}if(this.debug){this.updateDetectionBoxes(o)}else{this.detectionBoxes=[]}this.updateMaskColor(o);if(this.debug){const t=performance.now();const i=t-e;this.recordFrameProcessing(i,o.length)}if(t.step!=="completed"){if(this.consecutiveFailures>this.MAX_FAILURES){setTimeout((()=>this.detectFrame()),200)}else{this.animationId=requestAnimationFrame((()=>this.detectFrame()))}}}catch(e){this.logger.error("Error en inferencia de modelo:",e);const t=this.stateManager.getCaptureState();if(t.step!=="completed"){setTimeout((()=>this.detectFrame()),100)}}}disconnectedCallback(){this.cleanup()}cleanup(){if(this.animationId){cancelAnimationFrame(this.animationId)}if(this.videoStream){this.videoStream.getTracks().forEach((e=>e.stop()))}if(this.alignmentTimer){clearTimeout(this.alignmentTimer);this.alignmentTimer=undefined}if(this.performanceUpdateInterval){clearInterval(this.performanceUpdateInterval);this.performanceUpdateInterval=undefined}this.detectionBoxes=[];this.alignmentStartTime=undefined;this.hasDocumentDetected=false;this.serviceContainer?.cleanup()}render(){const e=this.stateManager?.getCaptureState()||{isVideoActive:false,showFlipAnimation:false,showSuccessAnimation:false,step:"front",isCapturing:false};const t=this.cameraService?.getCameraInfo()||{availableCameras:[],selectedCameraId:null,deviceType:"desktop"};return s("div",{key:"9d4d77042218ab3d0bc4fb1ce879db09dc3e78b4",class:"detector-container"},s("div",{key:"51ac8ccb1275637282b038ad8364d19f14ef61b1",class:"video-container"},s("video",{key:"a34f0481da20ec5b7b62b21aa275ec5f6dfec5d1",ref:e=>this.videoRef=e,autoplay:true,muted:true,playsinline:true,class:this.shouldMirrorVideo?"mirror":"",style:{display:e.isVideoActive?"block":"none"}}),s("div",{key:"43b71dfe3eaf20ffa66a4139e24b1af6a2074631",ref:e=>this.detectionContainer=e,class:`detection-overlay ${this.shouldMirrorVideo?"mirror":""}`},this.debug&&this.detectionBoxes.map(((e,t)=>s("div",{key:t,class:"detection-box",style:{position:"absolute",left:`${e.x}px`,top:`${e.y}px`,width:`${e.w}px`,height:`${e.h}px`,border:"2px solid #32406C",pointerEvents:"none",boxSizing:"border-box"}})))),this.isMaskReady&&s("div",{key:"c2596f8cabb227e3ea3b082495f52b141cb1690f",class:"overlay-mask"},s("div",{key:"ba1ea39b5df1cd312a9bd9410b7225a29cfb8a29",class:"card-outline"},s("div",{key:"6ce4d4d969d5f3fbcf75a4eb285f61d434c5633b",class:"side side-top"}),s("div",{key:"36653ecc4fcda25dfc84bc4d1f4c4c5dfb71ced7",class:"side side-right"}),s("div",{key:"8b108fa8fb370b229a0d1a77cb1ff044319a8f75",class:"side side-bottom"}),s("div",{key:"a7aa3b45c065a50445aafd5c3ccefb57b0c9c769",class:"side side-left"}),!e.showFlipAnimation&&!e.showSuccessAnimation&&s("div",{key:"b94b92273e12a019238e11ae57f21e140f13c3f1",class:"guide-text"},"Alinee su identificación con el marco")),e.step==="back"&&!e.showFlipAnimation&&!e.showSuccessAnimation&&s("div",{key:"144c3741003ec0cc148bb6ce92012d7b3cd110c8",class:"skip-section"},s("div",{key:"f0a984a6b75afa374c5d47da9d53e39f98071da0",class:"skip-explanation"},"Si tu documento no tiene lado trasero, da clic en el botón para continuar con el proceso"),s("button",{key:"57ac30d776e30709aab6e0a621cef889da3cc677",class:"skip-button",onClick:()=>this.skipBackCapture(),type:"button"},this.enableBackDocumentTimer&&this.backDocumentTimerRemaining>0?`Saltar reverso (${this.backDocumentTimerRemaining}s)`:"Saltar reverso")),e.isVideoActive&&s("div",{key:"bd45628707e0169317ed3dd4247e1056d7046104",class:"camera-controls"},s("button",{key:"e750fbf4d5d76d9e9596823bb2b86801ef19e485",class:`camera-selector-button ${this.isSwitchingCamera?"loading":""}`,onClick:()=>this.toggleCameraSelector(),type:"button",title:"Seleccionar cámara",disabled:this.isSwitchingCamera},this.isSwitchingCamera?s("div",{class:"button-spinner"}):"Cámaras")),this.showCameraSelector&&t.availableCameras.length>0&&s("div",{key:"40ada780a8ea13aeeaee9cb39bc6496f69f2679d",class:"camera-selector-dropdown"},s("div",{key:"3a920bb02ba024f0359513f10544bf0528ecee6d",class:"camera-selector-header"},s("span",{key:"e5efd478a602b13821ba53cb9a7a59d1b4a71178"},"Seleccionar Cámara"),s("button",{key:"2df6cc11e162be74862029e33815927e3fa8f2f8",class:"close-selector",onClick:()=>this.toggleCameraSelector(),type:"button"},"×")),s("div",{key:"06934642dff134c9e1a6872f935a5892a9c7b835",class:"camera-list"},t.availableCameras.map((e=>s("button",{key:e.id,class:`camera-option ${t.selectedCameraId===e.id?"selected":""}`,onClick:()=>this.handleCameraSwitch(e.id),type:"button"},s("span",{class:"camera-label"},e.label||`Cámara ${t.availableCameras.indexOf(e)+1}`),t.selectedCameraId===e.id&&s("span",{class:"selected-indicator"},"✓"))))),s("div",{key:"8d5ede287c2efb0ebe418bee8dc7fb310443c991",class:"device-info"},s("small",{key:"b7dd10565113694b09f01ab28ffa29262ae1d2bc"},"Dispositivo: ",t.deviceType)))),e.isCapturing&&s("div",{key:"2f9e549e6c0c56d4db5835e58361fb17bba6cf90",class:"capture-animation"}),e.showFlipAnimation&&s("div",{key:"a6ef0ed127f23e9d764896ed743ca8d8454851a6",class:"flip-animation"},s("div",{key:"0b04411f88a634bb3243b00ca2d5a45fd6962dea",class:"id-card-icon"}),s("div",{key:"9327be58879b407cea87f455989406e58302e9d1",class:"flip-text"},"¡Voltea tu identificación!")),e.showSuccessAnimation&&s("div",{key:"bd268578b5003e99256e3340b4a9a6fb7656be64",class:"success-animation"},s("div",{key:"064e0a5b9851de14bc6829f028e7ea7161fd1633",class:"check-icon"}),s("div",{key:"bdcd94a8806399e396e218a359c10b11d05f38d6",class:"success-text"},"¡Proceso completado!")),s("div",{key:"3d9af617376c16e44e065873919c3d90ff46110a",class:`component-status status-${this.currentStatus.type}`},(this.currentStatus.type==="loading"||this.currentStatus.type==="initializing")&&s("div",{key:"be7b56decfd6f12dcca46b2a9456480e3d5ac00e",class:"status-spinner"}),s("div",{key:"5fe9850883cb749cebaa18c3e9c13ca21325e373",class:"status-content"},s("div",{key:"43fdb50691e4b98e56126af1a129f625061128bf",class:"status-message"},this.currentStatus.message),this.currentStatus.description&&s("div",{key:"b76cbfa4a0349421fcd535d3fd8bf40c89ca3aef",class:"status-description"},this.currentStatus.description))),this.debug&&s("div",{key:"eddefb464af0487ab9ab2a0f76dccbb6a2092e51",class:"performance-monitor"},s("div",{key:"7b7d93b56cb4cd4fbb1bdde89c6150b282fa805e",class:"performance-expanded"},s("div",{key:"f302e8b9d985fb8cad53c4c4e0d37a3bf5a63261",class:"metrics-row"},s("div",{key:"e8d8f2420ee8643a7f454d38065c75b5be598f77",class:"metric-compact"},s("span",{key:"6e52eb5bb06e0df57e61774de38c31349f45e22b",class:"metric-label"},"FPS"),s("span",{key:"6636f9cea20c49b49c17db86188e2f6b214c45c3",class:`metric-value ${this.performanceData.fps<15?"warning":this.performanceData.fps<10?"danger":"good"}`},this.performanceData.fps)),s("div",{key:"afa1d9dec05b14256a1b1fcec8638b8c21a56e37",class:"metric-compact"},s("span",{key:"9c55e30f5d01582648bacc1fb38ca1990485a591",class:"metric-label"},"MEM"),s("span",{key:"ca263601e8715027f95ffb2d5413a643dc570cf2",class:`metric-value ${this.performanceData.memoryUsage>100?"warning":this.performanceData.memoryUsage>200?"danger":"good"}`},this.performanceData.memoryUsage,"MB"))),s("div",{key:"03caf19961fd01b7781484d49d8121b1e78c161f",class:"metrics-row"},s("div",{key:"bffb08f01f703411f7c8605e4f8d95b1c37b5c0f",class:"metric-compact"},s("span",{key:"9b92279b3253cc669412733facb3751f4344d69f",class:"metric-label"},"INF"),s("span",{key:"3234d4150e2e1479e3b552767af8123e69911d6c",class:`metric-value ${this.performanceData.inferenceTime>100?"warning":this.performanceData.inferenceTime>200?"danger":"good"}`},this.performanceData.inferenceTime,"ms")),s("div",{key:"77082d2669db53f19fb50b3bbfa1ebefb0b86ff4",class:"metric-compact"},s("span",{key:"cc6ef96c72c800ba36dab2a388f1de863b2dacd5",class:"metric-label"},"FRAME"),s("span",{key:"e2bb4b7351869a76e810f8bbf20d805154495e35",class:`metric-value ${this.performanceData.frameProcessingTime>50?"warning":this.performanceData.frameProcessingTime>100?"danger":"good"}`},this.performanceData.frameProcessingTime,"ms"))),s("div",{key:"5700d7ef839fa77686299d79445203090dc8079f",class:"metrics-row"},s("div",{key:"a2999a035fccb7f250c01b084075490678513c87",class:"metric-compact"},s("span",{key:"3677d58665996fa5969507dbaff9e956b2ea54ee",class:"metric-label"},"DET"),s("span",{key:"c584312438b339c82a3bdc33f00fb985ff2a6f55",class:"metric-value good"},this.performanceData.successfulDetections,"/",this.performanceData.totalDetections)),s("div",{key:"58866219f213bf8607083f30be2d5ca5d0515cea",class:"metric-compact"},s("span",{key:"d90b450051331347f219b6c0f197536d0dcee9b7",class:"metric-label"},"RATE"),s("span",{key:"f6e6cd7948e06014e5a0416e4e81394fa36ec61d",class:`metric-value ${this.performanceData.detectionRate<30?"danger":this.performanceData.detectionRate<60?"warning":"good"}`},this.performanceData.detectionRate,"%"))))),s("div",{key:"c1d0194f181a0082cc1aa5452de382908da61b65",class:"watermark"},s("img",{key:"e04d35f3c79a2b4a3922ab5b0f102220171fa7c0",src:"https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png",alt:"Powered by Jaak"}))))}updateDetectionBoxes(e){if(!this.videoRef||!this.detectionContainer)return;const t=this.videoRef.videoWidth;const i=this.videoRef.videoHeight;const s=this.detectionContainer.parentElement;const a=s.getBoundingClientRect();const o=a.width;const r=a.height;if(t===0||i===0)return;const n=t/i;const c=o/r;let d,l;let h=0,f=0;if(n>c){d=o;l=o/n;f=(r-l)/2}else{l=r;d=r*n;h=(o-d)/2}const p=320;const u=d/p;const m=l/p;this.detectionBoxes=e.map((e=>({x:e.x*u+h,y:e.y*m+f,w:e.w*u,h:e.h*m,score:e.score})))}updateMaskColor(e){const t=this.el.shadowRoot?.querySelector(".card-outline");const i=this.el.shadowRoot?.querySelectorAll(".corner");const s=this.el.shadowRoot?.querySelector(".side-top");const a=this.el.shadowRoot?.querySelector(".side-right");const o=this.el.shadowRoot?.querySelector(".side-bottom");const r=this.el.shadowRoot?.querySelector(".side-left");let n=null;let c={top:false,right:false,bottom:false,left:false};if(e.length>0){n=e.reduce(((e,t)=>t.score>e.score?t:e));const t={INPUT_SIZE:320,ID1_ASPECT_RATIO:85.6/53.98,shouldMirrorVideo:this.shouldMirrorVideo,alignmentTolerance:this.alignmentTolerance,maskSize:this.maskSize,videoRef:this.videoRef};c=this.detectionService.checkSideAlignment(n,t);this.sideAlignment=c}else{this.sideAlignment={top:false,right:false,bottom:false,left:false}}s?.classList.toggle("aligned",c.top);a?.classList.toggle("aligned",c.right);o?.classList.toggle("aligned",c.bottom);r?.classList.toggle("aligned",c.left);const d=this.detectionService.areAllSidesAligned(c);const l=this.stateManager.getCaptureState();if(l.step==="back"&&this.enableBackDocumentTimer&&n){const e=c.top||c.right||c.bottom||c.left;if(e){this.startBackDocumentTimer()}}if(d&&n){t?.classList.add("perfect-match");i?.forEach((e=>e.classList.add("perfect-match")));this.logger.state("CAPTURE_EVALUATION",{allSidesAligned:true,hasScreenshotTaken:this.hasScreenshotTaken,captureDelay:this.captureDelay,alignmentStartTime:this.alignmentStartTime});if(!this.hasScreenshotTaken){const e=Date.now();if(!this.alignmentStartTime){this.alignmentStartTime=e;this.logger.state("ALIGNMENT_TIMER_STARTED",{startTime:e})}const t=e-this.alignmentStartTime;this.logger.state("ALIGNMENT_DURATION_CHECK",{alignmentDuration:t,captureDelay:this.captureDelay,readyToCapture:t>=this.captureDelay});if(t>=this.captureDelay){this.logger.state("TRIGGERING_CAPTURE",{alignmentDuration:t,captureDelay:this.captureDelay});this.lastDetectedBox=n;this.takeScreenshot().catch((e=>{this.logger.error("Error al tomar captura de pantalla:",e)}));this.hasScreenshotTaken=true;this.alignmentStartTime=undefined;setTimeout((()=>{this.hasScreenshotTaken=false}),2e3)}}}else{t?.classList.remove("perfect-match");i?.forEach((e=>e.classList.remove("perfect-match")));if(this.alignmentStartTime){this.alignmentStartTime=undefined}if(this.alignmentTimer){clearTimeout(this.alignmentTimer);this.alignmentTimer=undefined}}}async takeScreenshot(){if(!this.videoRef||!this.lastDetectedBox)return;this.logger.state("INICIANDO_CAPTURA",{captureStep:this.stateManager.getCaptureState().step,detectedBox:this.lastDetectedBox,videoResolution:{width:this.videoRef.videoWidth,height:this.videoRef.videoHeight}});this.stateManager.updateCaptureState({isCapturing:true});this.triggerCaptureAnimation();const e=document.createElement("canvas");e.width=this.videoRef.videoWidth;e.height=this.videoRef.videoHeight;const t=e.getContext("2d",{alpha:false});t.drawImage(this.videoRef,0,0,e.width,e.height);const i=320;const s=this.videoRef.videoWidth/i;const a=this.videoRef.videoHeight/i;const o=Math.max(0,this.lastDetectedBox.x*s-this.cropMargin);const r=Math.max(0,this.lastDetectedBox.y*a-this.cropMargin);const n=Math.min(this.lastDetectedBox.w*s+2*this.cropMargin,this.videoRef.videoWidth-o);const c=Math.min(this.lastDetectedBox.h*a+2*this.cropMargin,this.videoRef.videoHeight-r);const d=document.createElement("canvas");d.width=n;d.height=c;const l=d.getContext("2d",{alpha:false});l.drawImage(this.videoRef,o,r,n,c,0,0,n,c);const h=this.stateManager.getCaptureState();if(h.step==="front"){this.stateManager.setCapturedImages({front:{fullFrame:e.toDataURL("image/png"),cropped:d.toDataURL("image/png")}});if(this.useDocumentClassification){const e=await this.detectionService.classifyDocument(d);if(e&&e.class==="passport"){this.logger.state("PASAPORTE_DETECTADO_SALTANDO_REVERSO",{classification:e?.class});this.completeProcess(true);return}}this.stateManager.updateCaptureState({step:"back",isDetectionPaused:true,showFlipAnimation:true});setTimeout((()=>{this.stateManager.updateCaptureState({showFlipAnimation:false,isDetectionPaused:false});this.startBackDocumentTimer()}),3e3)}else if(h.step==="back"){this.stateManager.setCapturedImages({back:{fullFrame:e.toDataURL("image/png"),cropped:d.toDataURL("image/png")}});this.completeProcess(false)}}triggerCaptureAnimation(){const e=this.el.shadowRoot?.querySelector(".card-outline");e?.classList.add("capturing");setTimeout((()=>{this.stateManager.updateCaptureState({isCapturing:false});e?.classList.remove("capturing")}),600)}completeProcess(e=false){this.stateManager.updateCaptureState({step:"completed",showSuccessAnimation:true});const t=this.stateManager.getCapturedImages();t.metadata.processCompleted=true;t.metadata.backCaptureSkipped=e;this.stateManager.setCapturedImages(t);this.stopDetection();this.updateStatus("Proceso completado",`${t.metadata.totalImages} imágenes capturadas exitosamente`,"ready");const i={...t,timestamp:(new Date).toISOString()};this.captureCompleted.emit(i);setTimeout((()=>{this.stateManager.updateCaptureState({showSuccessAnimation:false})}),3e3);this.logger.state("PROCESO_COMPLETADO",{skippedBack:e,totalImages:t.metadata.totalImages,timestamp:(new Date).toISOString()})}stopDetection(){if(this.animationId){cancelAnimationFrame(this.animationId);this.animationId=undefined}this.clearBackDocumentTimer();this.detectionBoxes=[];this.logger.state("DETECTOR_DETENIDO",{timestamp:Date.now()})}startBackDocumentTimer(){if(!this.enableBackDocumentTimer)return;if(this.backDocumentTimer){clearInterval(this.backDocumentTimer)}this.backDocumentTimerRemaining=this.backDocumentTimerDuration;this.backDocumentTimer=window.setInterval((()=>{this.backDocumentTimerRemaining--;if(this.backDocumentTimerRemaining<=0){this.clearBackDocumentTimer();this.skipBackCapture()}}),1e3)}clearBackDocumentTimer(){if(this.backDocumentTimer){clearInterval(this.backDocumentTimer);this.backDocumentTimer=undefined}this.backDocumentTimerRemaining=0}toggleCameraSelector(){if(this.isSwitchingCamera)return;this.showCameraSelector=!this.showCameraSelector}async handleCameraSwitch(e){if(this.isSwitchingCamera)return;try{this.showCameraSelector=false;this.isSwitchingCamera=true;this.logger.state("INICIANDO_CAMBIO_CAMARA",{from:this.cameraService.getSelectedCameraId(),to:e});if(this.videoStream){this.videoStream.getTracks().forEach((e=>e.stop()))}await this.cameraService.switchCamera(e);const t=await this.cameraService.setupCamera();await this.initializeVideoStream(t);this.logger.state("CAMBIO_CAMARA_EXITOSO",{newCameraId:e,isRearCamera:this.cameraService.isRearCamera(t)})}catch(e){this.logger.error("Error al cambiar cámara:",e);try{const e=await this.cameraService.setupCamera();await this.initializeVideoStream(e)}catch(e){this.logger.error("Error al restaurar cámara anterior:",e);this.updateStatus("Error al cambiar cámara","No se pudo completar el cambio de dispositivo","error")}}finally{this.isSwitchingCamera=false}}resetDetection(){const e=this.stateManager.getCaptureState();const t=e.isVideoActive;this.stateManager.reset();if(t){this.stateManager.updateCaptureState({isVideoActive:true})}this.hasScreenshotTaken=false;this.startTime=Date.now();this.frameSkipCounter=0;this.consecutiveFailures=0;this.lastInferenceTime=0;this.detectionBoxes=[];this.alignmentStartTime=undefined;this.hasDocumentDetected=false;if(this.alignmentTimer){clearTimeout(this.alignmentTimer);this.alignmentTimer=undefined}if(t&&this.detectionService.isModelLoaded()){this.updateStatus("Captura reiniciada","Buscando documento en el marco de captura","active");this.detectFrame()}else{this.updateStatus("Listo para capturar","","ready")}}exitSession(){if(this.videoStream){this.videoStream.getTracks().forEach((e=>e.stop()));this.videoStream=undefined;this.stateManager.updateCaptureState({isVideoActive:false,isLoading:false})}this.isMaskReady=false;this.updateStatus("Sesión finalizada","","ready");this.detectionBoxes=[];this.cleanup()}initializePerformanceMonitor(){this.performanceMetrics.lastUpdateTime=performance.now();this.performanceUpdateInterval=window.setInterval((()=>{this.updatePerformanceMetrics()}),500);this.logger.debug("Monitor de performance inicializado")}updatePerformanceMetrics(){const e=performance.now();const t=e-this.performanceMetrics.lastUpdateTime;if(t>0){this.performanceMetrics.fps=Math.round(1e3/(t/this.frameSkipCounter||1))}if("memory"in performance){const e=performance.memory;this.performanceMetrics.memoryUsage=Math.round(e.usedJSHeapSize/1048576)}if(this.performanceMetrics.totalDetections>0){this.performanceMetrics.successfulDetections=this.performanceMetrics.successfulDetections;const e=this.performanceMetrics.successfulDetections/this.performanceMetrics.totalDetections*100;this.performanceMetrics.detectionRate=Math.round(e)}this.performanceData={fps:this.performanceMetrics.fps,inferenceTime:this.performanceMetrics.inferenceTime,memoryUsage:this.performanceMetrics.memoryUsage,onnxLoadTime:this.performanceMetrics.onnxLoadTime,frameProcessingTime:this.performanceMetrics.frameProcessingTime,totalDetections:this.performanceMetrics.totalDetections,successfulDetections:this.performanceMetrics.successfulDetections,detectionRate:this.performanceMetrics.detectionRate};this.performanceMetrics.lastUpdateTime=e}recordOnnxPerformance(e,t){this.performanceMetrics.onnxLoadTime=Math.round(e);this.performanceMetrics.inferenceTime=Math.round(t)}recordFrameProcessing(e,t){this.performanceMetrics.frameProcessingTime=Math.round(e);this.performanceMetrics.totalDetections++;if(t>0){this.performanceMetrics.successfulDetections++}}};u.style=p;export{u as jaak_stamps};
2
+ //# sourceMappingURL=p-6514d12b.entry.js.map