@jaak.ai/stamps 2.1.0-dev.3 → 2.1.0-dev.4
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.
- package/dist/cjs/jaak-stamps-webcomponent.cjs.js +1 -1
- package/dist/cjs/jaak-stamps.cjs.entry.js +192 -45
- package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -1
- package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/my-component/my-component.css +19 -0
- package/dist/collection/components/my-component/my-component.js +193 -51
- package/dist/collection/components/my-component/my-component.js.map +1 -1
- package/dist/components/jaak-stamps.js +194 -46
- package/dist/components/jaak-stamps.js.map +1 -1
- package/dist/esm/jaak-stamps-webcomponent.js +1 -1
- package/dist/esm/jaak-stamps.entry.js +192 -45
- package/dist/esm/jaak-stamps.entry.js.map +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -1
- package/dist/jaak-stamps-webcomponent/p-091d609b.entry.js +2 -0
- package/dist/jaak-stamps-webcomponent/p-091d609b.entry.js.map +1 -0
- package/dist/types/components/my-component/my-component.d.ts +11 -2
- package/package.json +1 -1
- package/dist/jaak-stamps-webcomponent/p-4b2f9fb3.entry.js +0 -2
- package/dist/jaak-stamps-webcomponent/p-4b2f9fb3.entry.js.map +0 -1
package/dist/cjs/loader.cjs.js
CHANGED
|
@@ -5,7 +5,7 @@ var index = require('./index-BfhtOB0D.js');
|
|
|
5
5
|
const defineCustomElements = async (win, options) => {
|
|
6
6
|
if (typeof window === 'undefined') return undefined;
|
|
7
7
|
await index.globalScripts();
|
|
8
|
-
return index.bootstrapLazy([["jaak-stamps.cjs",[[1,"jaak-stamps",{"debug":[4],"alignmentTolerance":[2,"alignment-tolerance"],"maskSize":[2,"mask-size"],"cropMargin":[2,"crop-margin"],"useDocumentClassification":[4,"use-document-classification"],"useDocumentDetector":[4,"use-document-detector"],"preferredCamera":[1,"preferred-camera"],"captureDelay":[2,"capture-delay"],"enableBackDocumentTimer":[4,"enable-back-document-timer"],"backDocumentTimerDuration":[2,"back-document-timer-duration"],"detectionBoxes":[32],"sideAlignment":[32],"isMaskReady":[32],"shouldMirrorVideo":[32],"showCameraSelector":[32],"isSwitchingCamera":[32],"hasDocumentDetected":[32],"cameraInfoWithAutofocus":[32],"currentStatus":[32],"performanceData":[32],"backDocumentTimerRemaining":[32],"showManualCaptureButton":[32],"
|
|
8
|
+
return index.bootstrapLazy([["jaak-stamps.cjs",[[1,"jaak-stamps",{"debug":[4],"alignmentTolerance":[2,"alignment-tolerance"],"maskSize":[2,"mask-size"],"cropMargin":[2,"crop-margin"],"useDocumentClassification":[4,"use-document-classification"],"useDocumentDetector":[4,"use-document-detector"],"preferredCamera":[1,"preferred-camera"],"captureDelay":[2,"capture-delay"],"enableBackDocumentTimer":[4,"enable-back-document-timer"],"backDocumentTimerDuration":[2,"back-document-timer-duration"],"detectionBoxes":[32],"sideAlignment":[32],"isMaskReady":[32],"shouldMirrorVideo":[32],"showCameraSelector":[32],"isSwitchingCamera":[32],"hasDocumentDetected":[32],"cameraInfoWithAutofocus":[32],"currentStatus":[32],"performanceData":[32],"backDocumentTimerRemaining":[32],"showManualCaptureButton":[32],"performanceDegradedMode":[32],"showPerformanceMessage":[32],"getCapturedImages":[64],"isProcessCompleted":[64],"startCapture":[64],"stopCapture":[64],"resetCapture":[64],"skipBackCapture":[64],"getStatus":[64],"preloadModel":[64],"getCameraInfo":[64],"setPreferredCamera":[64],"setCaptureDelay":[64],"getCaptureDelay":[64]}]]]], options);
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
exports.setNonce = index.setNonce;
|
|
@@ -621,6 +621,25 @@ video {
|
|
|
621
621
|
to { opacity: 1; transform: translateY(0); }
|
|
622
622
|
}
|
|
623
623
|
|
|
624
|
+
/* Performance warning animation for guide-text */
|
|
625
|
+
.guide-text.performance-warning-text {
|
|
626
|
+
animation: gentlePulse 2s ease-in-out infinite;
|
|
627
|
+
background: rgba(255, 107, 107, 0.3);
|
|
628
|
+
border: 1px solid rgba(255, 107, 107, 0.5);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
@keyframes gentlePulse {
|
|
632
|
+
0%, 100% {
|
|
633
|
+
transform: translate(-50%, -50%) scale(1);
|
|
634
|
+
background: rgba(255, 107, 107, 0.3);
|
|
635
|
+
}
|
|
636
|
+
50% {
|
|
637
|
+
transform: translate(-50%, -50%) scale(1.02);
|
|
638
|
+
background: rgba(255, 107, 107, 0.4);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
|
|
624
643
|
/* Botón para saltar reverso */
|
|
625
644
|
.skip-button {
|
|
626
645
|
pointer-events: auto;
|
|
@@ -49,7 +49,8 @@ export class JaakStamps {
|
|
|
49
49
|
};
|
|
50
50
|
backDocumentTimerRemaining = 0;
|
|
51
51
|
showManualCaptureButton = false;
|
|
52
|
-
|
|
52
|
+
performanceDegradedMode = false; // Auto-switched to manual mode due to performance
|
|
53
|
+
showPerformanceMessage = false; // Show performance message temporarily
|
|
53
54
|
// Services
|
|
54
55
|
serviceContainer;
|
|
55
56
|
eventBus;
|
|
@@ -73,7 +74,6 @@ export class JaakStamps {
|
|
|
73
74
|
fps: 0,
|
|
74
75
|
inferenceTime: 0,
|
|
75
76
|
memoryUsage: 0,
|
|
76
|
-
cpuUsage: 0,
|
|
77
77
|
onnxLoadTime: 0,
|
|
78
78
|
frameProcessingTime: 0,
|
|
79
79
|
totalDetections: 0,
|
|
@@ -92,6 +92,12 @@ export class JaakStamps {
|
|
|
92
92
|
MIN_INFERENCE_INTERVAL = 50;
|
|
93
93
|
performanceHistory = [];
|
|
94
94
|
PERFORMANCE_HISTORY_SIZE = 10;
|
|
95
|
+
// Sistema simplificado de monitoreo de rendimiento
|
|
96
|
+
PERFORMANCE_THRESHOLD_MS = 2000; // Umbral único para todos los frames
|
|
97
|
+
SLOW_FRAMES_TO_TRIGGER = 2; // Cuántos frames lentos consecutivos antes de cambiar
|
|
98
|
+
slowFrameCount = 0; // Contador de frames consecutivos lentos
|
|
99
|
+
processedFramesCount = 0; // Contador total de frames procesados
|
|
100
|
+
hasAutoSwitchedToManual = false;
|
|
95
101
|
// Canvas pool for optimized screenshot capture
|
|
96
102
|
canvasPool = [];
|
|
97
103
|
MAX_CANVAS_POOL_SIZE = 3;
|
|
@@ -124,14 +130,8 @@ export class JaakStamps {
|
|
|
124
130
|
this.detectionService = this.serviceContainer.getDetectionService();
|
|
125
131
|
}
|
|
126
132
|
async setupEventListeners() {
|
|
127
|
-
this.eventBus.on('state-changed', (
|
|
128
|
-
this.handleStateChange(
|
|
129
|
-
});
|
|
130
|
-
this.eventBus.on('camera-changed', () => {
|
|
131
|
-
// Camera changed event
|
|
132
|
-
});
|
|
133
|
-
this.eventBus.on('error', () => {
|
|
134
|
-
// Handle service errors
|
|
133
|
+
this.eventBus.on('state-changed', () => {
|
|
134
|
+
this.handleStateChange();
|
|
135
135
|
});
|
|
136
136
|
}
|
|
137
137
|
async initializeComponent() {
|
|
@@ -238,13 +238,8 @@ export class JaakStamps {
|
|
|
238
238
|
return false;
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
|
-
handleStateChange(
|
|
242
|
-
//
|
|
243
|
-
// This is where the component updates its internal state based on service state changes
|
|
244
|
-
if (data.changes.isLoading !== undefined) {
|
|
245
|
-
// Force re-render when loading state changes
|
|
246
|
-
// Note: Stencil automatically re-renders when @State changes
|
|
247
|
-
}
|
|
241
|
+
handleStateChange() {
|
|
242
|
+
// Handle state changes from StateManager if needed
|
|
248
243
|
}
|
|
249
244
|
initializeResizeObserver() {
|
|
250
245
|
if ('ResizeObserver' in window && this.detectionContainer) {
|
|
@@ -261,13 +256,14 @@ export class JaakStamps {
|
|
|
261
256
|
this.updateMaskDimensions(rect);
|
|
262
257
|
}
|
|
263
258
|
}
|
|
264
|
-
triggerRerender() {
|
|
265
|
-
this.captureStateVersion = this.captureStateVersion + 1;
|
|
266
|
-
}
|
|
267
259
|
getGuideText(step) {
|
|
268
260
|
if (step === 'completed') {
|
|
269
261
|
return 'Proceso completado';
|
|
270
262
|
}
|
|
263
|
+
// Check if we should show performance message
|
|
264
|
+
if (this.showPerformanceMessage && step === 'front') {
|
|
265
|
+
return 'Modo manual activado por rendimiento. Use el botón para capturar.';
|
|
266
|
+
}
|
|
271
267
|
if (step === 'front') {
|
|
272
268
|
// Para el frente, si el detector manual está activo, mostrar instrucciones de captura manual
|
|
273
269
|
if (this.showManualCaptureButton) {
|
|
@@ -497,9 +493,23 @@ export class JaakStamps {
|
|
|
497
493
|
if (this.stateManager) {
|
|
498
494
|
this.stateManager.updateCaptureState({ isLoading: true });
|
|
499
495
|
}
|
|
500
|
-
|
|
496
|
+
try {
|
|
497
|
+
await this.detectionService.loadModel();
|
|
498
|
+
}
|
|
499
|
+
catch (modelError) {
|
|
500
|
+
console.error('Error cargando modelo de detección:', modelError);
|
|
501
|
+
this.switchToManualModeWithError('Error al cargar modelo de detección');
|
|
502
|
+
throw modelError;
|
|
503
|
+
}
|
|
501
504
|
this.updateStatus('Optimizando detección...', 'Configurando reconocimiento de documentos', 'loading');
|
|
502
|
-
|
|
505
|
+
try {
|
|
506
|
+
await this.detectionService.loadClassificationModel();
|
|
507
|
+
}
|
|
508
|
+
catch (classificationError) {
|
|
509
|
+
console.error('Error cargando modelo de clasificación:', classificationError);
|
|
510
|
+
this.switchToManualModeWithError('Error al cargar modelo de clasificación');
|
|
511
|
+
throw classificationError;
|
|
512
|
+
}
|
|
503
513
|
const loadEndTime = performance.now();
|
|
504
514
|
const loadTime = loadEndTime - loadStartTime;
|
|
505
515
|
// Record ONNX load time
|
|
@@ -616,9 +626,23 @@ export class JaakStamps {
|
|
|
616
626
|
const loadStartTime = performance.now();
|
|
617
627
|
this.updateStatus('Preparando reconocimiento...', 'Configurando detección de documentos', 'loading');
|
|
618
628
|
this.stateManager.updateCaptureState({ isLoading: true });
|
|
619
|
-
|
|
629
|
+
try {
|
|
630
|
+
await this.detectionService.loadModel();
|
|
631
|
+
}
|
|
632
|
+
catch (modelError) {
|
|
633
|
+
console.error('Error cargando modelo de detección:', modelError);
|
|
634
|
+
this.switchToManualModeWithError('Error al cargar modelo de detección');
|
|
635
|
+
throw modelError;
|
|
636
|
+
}
|
|
620
637
|
this.updateStatus('Optimizando detección...', 'Configurando reconocimiento de documentos', 'loading');
|
|
621
|
-
|
|
638
|
+
try {
|
|
639
|
+
await this.detectionService.loadClassificationModel();
|
|
640
|
+
}
|
|
641
|
+
catch (classificationError) {
|
|
642
|
+
console.error('Error cargando modelo de clasificación:', classificationError);
|
|
643
|
+
this.switchToManualModeWithError('Error al cargar modelo de clasificación');
|
|
644
|
+
throw classificationError;
|
|
645
|
+
}
|
|
622
646
|
const loadEndTime = performance.now();
|
|
623
647
|
const loadTime = loadEndTime - loadStartTime;
|
|
624
648
|
// Record ONNX load time
|
|
@@ -633,9 +657,9 @@ export class JaakStamps {
|
|
|
633
657
|
// Paso 3: Configurar cámara seleccionada
|
|
634
658
|
this.updateStatus('Ajustando cámara...', 'Configurando calidad de imagen', 'loading');
|
|
635
659
|
const stream = await this.cameraService.setupCamera();
|
|
636
|
-
// Paso 4: Inicializar video y
|
|
660
|
+
// Paso 4: Inicializar video y mostrar estado de análisis inicial
|
|
637
661
|
if (this.useDocumentDetector) {
|
|
638
|
-
this.updateStatus('
|
|
662
|
+
this.updateStatus('Analizando estabilidad...', 'Evaluando rendimiento del sistema', 'loading');
|
|
639
663
|
}
|
|
640
664
|
else {
|
|
641
665
|
this.updateStatus('Captura activa', 'Posicione su documento y use el botón para capturar', 'active');
|
|
@@ -685,8 +709,8 @@ export class JaakStamps {
|
|
|
685
709
|
const captureState = this.stateManager.getCaptureState();
|
|
686
710
|
if (!this.videoRef || !this.detectionContainer || !this.detectionService.isModelLoaded())
|
|
687
711
|
return;
|
|
688
|
-
// Show manual capture button when document detector is disabled
|
|
689
|
-
if (!this.useDocumentDetector) {
|
|
712
|
+
// Show manual capture button when document detector is disabled or performance is degraded
|
|
713
|
+
if (!this.useDocumentDetector || this.performanceDegradedMode) {
|
|
690
714
|
this.showManualCaptureButton = true;
|
|
691
715
|
// Continue the loop for UI updates but skip detection logic
|
|
692
716
|
if (captureState.step !== 'completed') {
|
|
@@ -694,7 +718,7 @@ export class JaakStamps {
|
|
|
694
718
|
}
|
|
695
719
|
return;
|
|
696
720
|
}
|
|
697
|
-
else {
|
|
721
|
+
else if (!this.performanceDegradedMode) {
|
|
698
722
|
this.showManualCaptureButton = false;
|
|
699
723
|
}
|
|
700
724
|
if (captureState.isDetectionPaused) {
|
|
@@ -724,10 +748,29 @@ export class JaakStamps {
|
|
|
724
748
|
this.lastInferenceTime = currentTime;
|
|
725
749
|
// Measure preprocessing and inference time
|
|
726
750
|
const inferenceStartTime = performance.now();
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
751
|
+
let inputTensor;
|
|
752
|
+
let detections;
|
|
753
|
+
let inferenceTime;
|
|
754
|
+
try {
|
|
755
|
+
inputTensor = this.detectionService.preprocess(this.videoRef);
|
|
756
|
+
}
|
|
757
|
+
catch (preprocessError) {
|
|
758
|
+
console.error('Error en preprocesamiento:', preprocessError);
|
|
759
|
+
this.switchToManualModeWithError('Error al procesar imagen');
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
try {
|
|
763
|
+
// Standard detection without timeout (timeout is handled by frame counting)
|
|
764
|
+
detections = await this.detectionService.runInference(inputTensor);
|
|
765
|
+
inferenceTime = performance.now() - inferenceStartTime;
|
|
766
|
+
}
|
|
767
|
+
catch (inferenceError) {
|
|
768
|
+
console.error('Error en inferencia ONNX:', inferenceError);
|
|
769
|
+
this.switchToManualModeWithError('Error en detección automática');
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
// Increment frame count
|
|
773
|
+
this.processedFramesCount++;
|
|
731
774
|
// Record ONNX performance metrics
|
|
732
775
|
if (this.debug) {
|
|
733
776
|
this.recordOnnxPerformance(0, inferenceTime);
|
|
@@ -766,9 +809,30 @@ export class JaakStamps {
|
|
|
766
809
|
}
|
|
767
810
|
this.updateMaskColor(detections);
|
|
768
811
|
// Record frame processing metrics
|
|
812
|
+
const frameEndTime = performance.now();
|
|
813
|
+
const totalFrameTime = frameEndTime - frameStartTime;
|
|
814
|
+
// Sistema simplificado: Verificar rendimiento de cada frame (solo si no se ha cambiado a manual)
|
|
815
|
+
if (this.useDocumentDetector && !this.hasAutoSwitchedToManual) {
|
|
816
|
+
// Verificar si el frame es lento
|
|
817
|
+
if (totalFrameTime >= this.PERFORMANCE_THRESHOLD_MS) {
|
|
818
|
+
this.slowFrameCount++;
|
|
819
|
+
// Si tenemos suficientes frames lentos consecutivos, cambiar a manual
|
|
820
|
+
if (this.slowFrameCount >= this.SLOW_FRAMES_TO_TRIGGER) {
|
|
821
|
+
this.switchToManualMode();
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
else {
|
|
825
|
+
// Frame rápido, reiniciar contador
|
|
826
|
+
if (this.slowFrameCount > 0) {
|
|
827
|
+
this.slowFrameCount = 0;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
// Cambiar mensaje de estado después de analizar los primeros 2 frames
|
|
831
|
+
if (this.processedFramesCount === 2) {
|
|
832
|
+
this.updateStatus('Captura activa', 'Buscando documento en el marco de captura', 'active');
|
|
833
|
+
}
|
|
834
|
+
}
|
|
769
835
|
if (this.debug) {
|
|
770
|
-
const frameEndTime = performance.now();
|
|
771
|
-
const totalFrameTime = frameEndTime - frameStartTime;
|
|
772
836
|
this.recordFrameProcessing(totalFrameTime, detections.length);
|
|
773
837
|
}
|
|
774
838
|
// Continue detection loop
|
|
@@ -804,6 +868,8 @@ export class JaakStamps {
|
|
|
804
868
|
clearTimeout(this.alignmentTimer);
|
|
805
869
|
this.alignmentTimer = undefined;
|
|
806
870
|
}
|
|
871
|
+
// Liberar recursos de ONNX al limpiar el componente
|
|
872
|
+
this.releaseOnnxResources();
|
|
807
873
|
if (this.performanceUpdateInterval) {
|
|
808
874
|
clearInterval(this.performanceUpdateInterval);
|
|
809
875
|
this.performanceUpdateInterval = undefined;
|
|
@@ -825,7 +891,7 @@ export class JaakStamps {
|
|
|
825
891
|
isCapturing: false
|
|
826
892
|
};
|
|
827
893
|
const cameraInfo = this.cameraInfoWithAutofocus;
|
|
828
|
-
return (h("div", { key: '
|
|
894
|
+
return (h("div", { key: '79f84b34f4c6641f0afce6825e9a916c5f1ce1fc', class: "detector-container" }, h("div", { key: '1784b74d259071b2c2f879d67bda08cdaf011c76', class: "video-container" }, h("video", { key: '48704208b83a9adfd6511266e1848dab8c583b2c', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), h("div", { key: 'b55b96ef64557caee6b0e0c401a96c6b20e3785f', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index) => (h("div", { key: index, class: "detection-box", style: {
|
|
829
895
|
position: 'absolute',
|
|
830
896
|
left: `${box.x}px`,
|
|
831
897
|
top: `${box.y}px`,
|
|
@@ -834,9 +900,9 @@ export class JaakStamps {
|
|
|
834
900
|
border: '2px solid #32406C',
|
|
835
901
|
pointerEvents: 'none',
|
|
836
902
|
boxSizing: 'border-box'
|
|
837
|
-
} })))), this.isMaskReady && (h("div", { key: '
|
|
903
|
+
} })))), this.isMaskReady && (h("div", { key: 'd398db06f067890474b9ab3fef67fe9712a81948', class: "overlay-mask" }, h("div", { key: 'c328eef8a3da4f01aecc2c163b5c3baadee2ab7a', class: "card-outline" }, h("div", { key: 'e022c6746096b1b35d4e74295d9872092234fa3e', class: "side side-top" }), h("div", { key: '709bd54e7619572b499e8d044ead38e0baab546e', class: "side side-right" }), h("div", { key: '330de7072bbb208fad6f10a160c9794438d0dd76', class: "side side-bottom" }), h("div", { key: 'a12f18f2c2200ee74809f3bed3ee1218ced498ca', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'fb049290c464fa7137c174b2a2fcb5f8e1620f5d', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '7d027c1dfb1ea855b8d49d5b8934c81be2b73d65', class: "back-capture-section" }, h("div", { key: 'cb2f5cbd36d0fa66782a37dc8b00226a35997629', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode) && (h("button", { key: '5cee5c2176f23849eb9494505e66e27ca5bbdf6b', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: captureState.isCapturing }, captureState.isCapturing ? 'Capturando...' : 'Capturar Reverso')), h("button", { key: '24b4171ed4a56fad56a61a9daa4529de618a5f94', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button" }, this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
|
|
838
904
|
? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
|
|
839
|
-
: 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '
|
|
905
|
+
: 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: 'f0b8bfed998c950e30de0e43662a1965374c6180', class: "camera-controls" }, h("button", { key: '7c795a9aa31249f2d42bc45e6d77fba633b7400f', class: `camera-selector-button ${this.isSwitchingCamera ? 'loading' : ''}`, onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara", disabled: this.isSwitchingCamera }, this.isSwitchingCamera ? (h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (h("div", { key: '97ffdf5203e6d7ed1139b7d88088761c1f2adb80', class: "camera-selector-dropdown" }, h("div", { key: '0ba533fa51f946abdcc535e07c86f31fd0d1d4bb', class: "camera-selector-header" }, h("span", { key: '244b13d266e69326a81228e9b0679fd8264ea91d' }, "Seleccionar C\u00E1mara"), h("button", { key: '975c809b348f39bccb6887d710909a58a7222a88', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: '40df0a7ac0bda961362af72b5a03d448bc4481db', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`, camera.hasAutofocus && (h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (h("span", { class: "selected-indicator" }, "\u2713")))))), h("div", { key: 'ea50280fbc4e96feea026c8ff6dc590ff5e76a59', class: "device-info" }, h("small", { key: '19209e350b073e2cc5d3e713c69da863cf98e92e' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '6a91d0c3d72b9bdbf9f0b6d9d33aff440cb3bcb5', class: "manual-capture-section" }, h("button", { key: '6474971d1a21f45dfeee90b9c39d5fd7e9f142fa', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: captureState.isCapturing }, captureState.isCapturing ? 'Capturando...' : 'Capturar Frente'))))), captureState.isCapturing && (h("div", { key: '0f2cb967caa746f34f442ed17edbeeeea3be1e2d', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: 'a1a6c67d34b27639d4ca6ab3cf790d184aab64bc', class: "flip-animation" }, h("div", { key: '4b2d5fe6d18bb77d6515312f53fd189ed2af9db6', class: "id-card-icon" }), h("div", { key: '27bd058bd46ecea5ee7bf174a0aa45de519190bf', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: 'd155e5d2f926c33183f83dabf887bb785d856b14', class: "success-animation" }, h("div", { key: 'e57b7c8d6685146ac2215f52a92ff23e3fbd2d97', class: "check-icon" }), h("div", { key: '0e3de74b19434f49919b4ef78f91dd89c7a80799', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: '8401bf78d349be4900de4e0a23a9fddfafcacc4f', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: '2b55d22272cd78aa39fd15dd9bdf2317a0737b9f', class: "status-spinner" })), h("div", { key: '10dfb478b8803f70c787c9d9412d517de1bcf852', class: "status-content" }, h("div", { key: '4cf6feb47ad6c2099219bb73eb0d46e3cbfb2bc3', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: 'e32df69c147070853977ceae6ec45d8c389e1905', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: '52a1512ef7b93ecef95cb727c7639661506a7f8d', class: "performance-monitor" }, h("div", { key: 'b7dfdeb4453c507338d4156e99a70c8ed8cb5436', class: "performance-expanded" }, h("div", { key: '79baa5412635f433400b127353c940d4bd1449c4', class: "metrics-row" }, h("div", { key: '12f8d4f530ddea03cbe61bbbf00eb761d55e48b2', class: "metric-compact" }, h("span", { key: '3f8d1d37bbb38424ad8def6c2b7f4aa4dfd35876', class: "metric-label" }, "FPS"), h("span", { key: '3010d0633a058f703c19776d19c88c753085af01', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: 'e5564951b463363ab4965a08f9f8ed37ff202ba2', class: "metric-compact" }, h("span", { key: '2b69e25dd1db6f9239c3de12af10a1ce261158c9', class: "metric-label" }, "MEM"), h("span", { key: '0e0189eb3f91ed5accc197224c55688ea7e93372', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: '174c09dbf46186a14d8534a8584c262ba79873fe', class: "metrics-row" }, h("div", { key: '7af195560eeacfd310544d607feee9c3f87327b9', class: "metric-compact" }, h("span", { key: 'fc8a27ca7484635685acab3b7aa0a0fd4fa9021b', class: "metric-label" }, "INF"), h("span", { key: 'bd3ba0e8dd1bf1f21652a986558ccef732572cbc', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '16109503ddd7bd856d6f82a385bece73f1bacc05', class: "metric-compact" }, h("span", { key: '9328438dd8e9c1f0f715f6cfa28baaca27c4244f', class: "metric-label" }, "FRAME"), h("span", { key: '8fa3cf73868bc0cbdaaad3cc6bb48b25a809617c', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: 'dc616be04663364254c38b1f2e96f15ccd52a495', class: "metrics-row" }, h("div", { key: '1fa771776e4dc3b0b86c9a195a6d518aa4e7df5f', class: "metric-compact" }, h("span", { key: '2f5fb1713ab76b0c84677f9df06f53ac83065cee', class: "metric-label" }, "DET"), h("span", { key: 'fd83bda90479a6101593e9b06c7c3fd10da70b67', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: '7c7f811a14caa371ac08e7945387f58c30039f9f', class: "metric-compact" }, h("span", { key: '872b9fa154731d48edf6d08b942bdcea4771fd6c', class: "metric-label" }, "RATE"), h("span", { key: '77f9b485a575735159dfbfd846dc2fd2a3dd3413', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: 'b7ab14e0f956ffb7a6658e6d97a26fe49be94a7f', class: "watermark" }, h("img", { key: '3f3807001884966bdf6e1a045d009859f8dcd0f3', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" })))));
|
|
840
906
|
}
|
|
841
907
|
// Utility methods
|
|
842
908
|
updateDetectionBoxes(boxes) {
|
|
@@ -1024,12 +1090,18 @@ export class JaakStamps {
|
|
|
1024
1090
|
});
|
|
1025
1091
|
// Check if document classification is enabled (independent of detector)
|
|
1026
1092
|
if (this.useDocumentClassification) {
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1093
|
+
try {
|
|
1094
|
+
const classification = await this.detectionService.classifyDocument(croppedCanvas);
|
|
1095
|
+
if (classification && classification.class === 'passport') {
|
|
1096
|
+
this.completeProcess(true);
|
|
1097
|
+
this.returnCanvasToPool(captureCanvas);
|
|
1098
|
+
this.returnCanvasToPool(croppedCanvas);
|
|
1099
|
+
return;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
catch (classifyError) {
|
|
1103
|
+
console.error('Error clasificando documento:', classifyError);
|
|
1104
|
+
// No cambiar a manual aquí, solo registrar el error y continuar
|
|
1033
1105
|
}
|
|
1034
1106
|
}
|
|
1035
1107
|
this.stateManager.updateCaptureState({
|
|
@@ -1037,13 +1109,11 @@ export class JaakStamps {
|
|
|
1037
1109
|
isDetectionPaused: true,
|
|
1038
1110
|
showFlipAnimation: true
|
|
1039
1111
|
});
|
|
1040
|
-
this.triggerRerender();
|
|
1041
1112
|
setTimeout(() => {
|
|
1042
1113
|
this.stateManager.updateCaptureState({
|
|
1043
1114
|
showFlipAnimation: false,
|
|
1044
1115
|
isDetectionPaused: false
|
|
1045
1116
|
});
|
|
1046
|
-
this.triggerRerender();
|
|
1047
1117
|
this.startBackDocumentTimer();
|
|
1048
1118
|
}, 3000);
|
|
1049
1119
|
}
|
|
@@ -1093,10 +1163,16 @@ export class JaakStamps {
|
|
|
1093
1163
|
});
|
|
1094
1164
|
// Check if document classification is enabled
|
|
1095
1165
|
if (this.useDocumentClassification) {
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1166
|
+
try {
|
|
1167
|
+
const classification = await this.detectionService.classifyDocument(croppedCanvas);
|
|
1168
|
+
if (classification && classification.class === 'passport') {
|
|
1169
|
+
this.completeProcess(true);
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
catch (classifyError) {
|
|
1174
|
+
console.error('Error clasificando documento:', classifyError);
|
|
1175
|
+
// No cambiar a manual aquí, solo registrar el error y continuar
|
|
1100
1176
|
}
|
|
1101
1177
|
}
|
|
1102
1178
|
this.stateManager.updateCaptureState({
|
|
@@ -1133,6 +1209,64 @@ export class JaakStamps {
|
|
|
1133
1209
|
cardOutline?.classList.remove('capturing');
|
|
1134
1210
|
}, 600);
|
|
1135
1211
|
}
|
|
1212
|
+
// Método simplificado para cambio a modo manual
|
|
1213
|
+
switchToManualMode() {
|
|
1214
|
+
// Only switch if detector is enabled and not already switched
|
|
1215
|
+
if (!this.useDocumentDetector || this.hasAutoSwitchedToManual) {
|
|
1216
|
+
return;
|
|
1217
|
+
}
|
|
1218
|
+
// Detener todo el monitoreo de performance
|
|
1219
|
+
this.stopPerformanceMonitoring();
|
|
1220
|
+
// Liberar recursos de ONNX
|
|
1221
|
+
this.releaseOnnxResources();
|
|
1222
|
+
this.hasAutoSwitchedToManual = true;
|
|
1223
|
+
this.performanceDegradedMode = true;
|
|
1224
|
+
this.showManualCaptureButton = true;
|
|
1225
|
+
this.showPerformanceMessage = true;
|
|
1226
|
+
// Hide performance message after 5 seconds
|
|
1227
|
+
setTimeout(() => {
|
|
1228
|
+
this.showPerformanceMessage = false;
|
|
1229
|
+
}, 5000);
|
|
1230
|
+
}
|
|
1231
|
+
// Método para cambiar a modo manual por errores de ONNX
|
|
1232
|
+
switchToManualModeWithError(errorMessage) {
|
|
1233
|
+
console.error(`[ONNX Error] ${errorMessage}`);
|
|
1234
|
+
// Solo cambiar si el detector está habilitado y no se ha cambiado ya
|
|
1235
|
+
if (!this.useDocumentDetector || this.hasAutoSwitchedToManual) {
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
// Liberar recursos de ONNX inmediatamente
|
|
1239
|
+
this.releaseOnnxResources();
|
|
1240
|
+
// Cambiar a modo manual
|
|
1241
|
+
this.hasAutoSwitchedToManual = true;
|
|
1242
|
+
this.performanceDegradedMode = true;
|
|
1243
|
+
this.showManualCaptureButton = true;
|
|
1244
|
+
this.useDocumentDetector = false; // Desactivar detector automático
|
|
1245
|
+
// Actualizar el estado con mensaje de error
|
|
1246
|
+
this.updateStatus('Modo manual activado', errorMessage, 'error');
|
|
1247
|
+
// Ocultar mensaje después de 5 segundos
|
|
1248
|
+
setTimeout(() => {
|
|
1249
|
+
this.updateStatus('Captura manual', 'Use el botón para capturar', 'ready');
|
|
1250
|
+
}, 5000);
|
|
1251
|
+
}
|
|
1252
|
+
stopPerformanceMonitoring() {
|
|
1253
|
+
// Nota: No necesitamos limpiar más variables porque ya no se usarán
|
|
1254
|
+
// El sistema automáticamente saltará la lógica de performance una vez que hasAutoSwitchedToManual = true
|
|
1255
|
+
}
|
|
1256
|
+
// Método para liberar recursos de ONNX cuando se cambia a modo manual
|
|
1257
|
+
releaseOnnxResources() {
|
|
1258
|
+
console.log('[ONNX] Liberando recursos de modelos ONNX...');
|
|
1259
|
+
try {
|
|
1260
|
+
// Liberar recursos del servicio de detección
|
|
1261
|
+
if (this.detectionService) {
|
|
1262
|
+
this.detectionService.cleanup();
|
|
1263
|
+
console.log('[ONNX] Recursos de ONNX liberados exitosamente');
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
catch (error) {
|
|
1267
|
+
console.error('[ONNX] Error al liberar recursos:', error);
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1136
1270
|
completeProcess(skippedBack = false) {
|
|
1137
1271
|
this.stateManager.updateCaptureState({
|
|
1138
1272
|
step: 'completed',
|
|
@@ -1246,6 +1380,13 @@ export class JaakStamps {
|
|
|
1246
1380
|
this.detectionBoxes = [];
|
|
1247
1381
|
this.alignmentStartTime = undefined;
|
|
1248
1382
|
this.hasDocumentDetected = false;
|
|
1383
|
+
// Reset sistema simplificado
|
|
1384
|
+
this.processedFramesCount = 0;
|
|
1385
|
+
this.slowFrameCount = 0;
|
|
1386
|
+
// Reset performance degradation state
|
|
1387
|
+
this.hasAutoSwitchedToManual = false;
|
|
1388
|
+
this.performanceDegradedMode = false;
|
|
1389
|
+
this.showPerformanceMessage = false;
|
|
1249
1390
|
if (this.alignmentTimer) {
|
|
1250
1391
|
clearTimeout(this.alignmentTimer);
|
|
1251
1392
|
this.alignmentTimer = undefined;
|
|
@@ -1609,7 +1750,8 @@ export class JaakStamps {
|
|
|
1609
1750
|
"performanceData": {},
|
|
1610
1751
|
"backDocumentTimerRemaining": {},
|
|
1611
1752
|
"showManualCaptureButton": {},
|
|
1612
|
-
"
|
|
1753
|
+
"performanceDegradedMode": {},
|
|
1754
|
+
"showPerformanceMessage": {}
|
|
1613
1755
|
};
|
|
1614
1756
|
}
|
|
1615
1757
|
static get events() {
|