@jaak.ai/stamps 2.0.0 → 2.1.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -1
- package/dist/cjs/jaak-stamps-webcomponent.cjs.js +1 -1
- package/dist/cjs/jaak-stamps.cjs.entry.js +759 -623
- 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 +178 -11
- package/dist/collection/components/my-component/my-component.js +566 -250
- package/dist/collection/components/my-component/my-component.js.map +1 -1
- package/dist/collection/services/CameraService.js +156 -344
- package/dist/collection/services/CameraService.js.map +1 -1
- package/dist/collection/services/DetectionService.js +68 -38
- package/dist/collection/services/DetectionService.js.map +1 -1
- package/dist/collection/services/EventBusService.js +1 -1
- package/dist/collection/services/EventBusService.js.map +1 -1
- package/dist/collection/services/ServiceContainer.js +4 -13
- package/dist/collection/services/ServiceContainer.js.map +1 -1
- package/dist/collection/services/interfaces/ICameraService.js.map +1 -1
- package/dist/collection/types/component-types.js.map +1 -1
- package/dist/components/jaak-stamps.js +763 -626
- 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 +759 -623
- 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-41e88688.entry.js +2 -0
- package/dist/jaak-stamps-webcomponent/p-41e88688.entry.js.map +1 -0
- package/dist/types/components/my-component/my-component.d.ts +68 -17
- package/dist/types/components.d.ts +14 -8
- package/dist/types/services/CameraService.d.ts +12 -14
- package/dist/types/services/DetectionService.d.ts +10 -3
- package/dist/types/services/ServiceContainer.d.ts +1 -2
- package/dist/types/services/interfaces/ICameraService.d.ts +3 -12
- package/dist/types/types/component-types.d.ts +3 -0
- package/package.json +2 -2
- package/dist/collection/services/LoggerService.js +0 -40
- package/dist/collection/services/LoggerService.js.map +0 -1
- package/dist/collection/services/interfaces/ILogger.js +0 -2
- package/dist/collection/services/interfaces/ILogger.js.map +0 -1
- package/dist/jaak-stamps-webcomponent/p-2264b5b4.entry.js +0 -2
- package/dist/jaak-stamps-webcomponent/p-2264b5b4.entry.js.map +0 -1
- package/dist/types/services/LoggerService.d.ts +0 -12
- package/dist/types/services/interfaces/ILogger.d.ts +0 -8
|
@@ -7,6 +7,7 @@ export declare class JaakStamps {
|
|
|
7
7
|
maskSize: number;
|
|
8
8
|
cropMargin: number;
|
|
9
9
|
useDocumentClassification: boolean;
|
|
10
|
+
useDocumentDetector: boolean;
|
|
10
11
|
preferredCamera: 'auto' | 'front' | 'back';
|
|
11
12
|
captureDelay: number;
|
|
12
13
|
enableBackDocumentTimer: boolean;
|
|
@@ -31,6 +32,18 @@ export declare class JaakStamps {
|
|
|
31
32
|
showCameraSelector: boolean;
|
|
32
33
|
isSwitchingCamera: boolean;
|
|
33
34
|
hasDocumentDetected: boolean;
|
|
35
|
+
cameraInfoWithAutofocus: {
|
|
36
|
+
availableCameras: Array<{
|
|
37
|
+
id: string;
|
|
38
|
+
label: string;
|
|
39
|
+
selected: boolean;
|
|
40
|
+
hasAutofocus: boolean;
|
|
41
|
+
}>;
|
|
42
|
+
selectedCameraId: string | null;
|
|
43
|
+
deviceType: string;
|
|
44
|
+
isMultipleCamerasAvailable: boolean;
|
|
45
|
+
preferredFacing: 'environment' | 'user' | null;
|
|
46
|
+
};
|
|
34
47
|
currentStatus: {
|
|
35
48
|
message: string;
|
|
36
49
|
description?: string;
|
|
@@ -48,8 +61,8 @@ export declare class JaakStamps {
|
|
|
48
61
|
detectionRate: number;
|
|
49
62
|
};
|
|
50
63
|
backDocumentTimerRemaining: number;
|
|
64
|
+
showManualCaptureButton: boolean;
|
|
51
65
|
private serviceContainer;
|
|
52
|
-
private logger;
|
|
53
66
|
private eventBus;
|
|
54
67
|
private stateManager;
|
|
55
68
|
private cameraService;
|
|
@@ -67,11 +80,16 @@ export declare class JaakStamps {
|
|
|
67
80
|
private performanceMetrics;
|
|
68
81
|
private performanceUpdateInterval?;
|
|
69
82
|
private frameSkipCounter;
|
|
70
|
-
private readonly
|
|
83
|
+
private readonly BASE_FRAME_SKIP;
|
|
84
|
+
private readonly MAX_FRAME_SKIP;
|
|
71
85
|
private consecutiveFailures;
|
|
72
86
|
private readonly MAX_FAILURES;
|
|
73
87
|
private lastInferenceTime;
|
|
74
88
|
private readonly MIN_INFERENCE_INTERVAL;
|
|
89
|
+
private performanceHistory;
|
|
90
|
+
private readonly PERFORMANCE_HISTORY_SIZE;
|
|
91
|
+
private canvasPool;
|
|
92
|
+
private readonly MAX_CANVAS_POOL_SIZE;
|
|
75
93
|
componentDidLoad(): Promise<void>;
|
|
76
94
|
private initializeServices;
|
|
77
95
|
private setupEventListeners;
|
|
@@ -81,16 +99,43 @@ export declare class JaakStamps {
|
|
|
81
99
|
private finalizeInitialization;
|
|
82
100
|
private updateStatus;
|
|
83
101
|
private emitReadyEvent;
|
|
102
|
+
private checkCameraPermissions;
|
|
84
103
|
private handleStateChange;
|
|
85
104
|
private initializeResizeObserver;
|
|
86
105
|
private handleResize;
|
|
106
|
+
private getGuideText;
|
|
87
107
|
private updateMaskDimensions;
|
|
108
|
+
private isComponentReady;
|
|
88
109
|
getCapturedImages(): Promise<CapturedImagesResponse>;
|
|
89
110
|
isProcessCompleted(): Promise<boolean>;
|
|
90
|
-
startCapture(): Promise<
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
111
|
+
startCapture(): Promise<{
|
|
112
|
+
success: boolean;
|
|
113
|
+
error?: undefined;
|
|
114
|
+
} | {
|
|
115
|
+
success: boolean;
|
|
116
|
+
error: any;
|
|
117
|
+
}>;
|
|
118
|
+
stopCapture(): Promise<{
|
|
119
|
+
success: boolean;
|
|
120
|
+
error?: undefined;
|
|
121
|
+
} | {
|
|
122
|
+
success: boolean;
|
|
123
|
+
error: any;
|
|
124
|
+
}>;
|
|
125
|
+
resetCapture(): Promise<{
|
|
126
|
+
success: boolean;
|
|
127
|
+
error?: undefined;
|
|
128
|
+
} | {
|
|
129
|
+
success: boolean;
|
|
130
|
+
error: any;
|
|
131
|
+
}>;
|
|
132
|
+
skipBackCapture(): Promise<{
|
|
133
|
+
success: boolean;
|
|
134
|
+
error?: undefined;
|
|
135
|
+
} | {
|
|
136
|
+
success: boolean;
|
|
137
|
+
error: any;
|
|
138
|
+
}>;
|
|
94
139
|
getStatus(): Promise<StatusResponse>;
|
|
95
140
|
preloadModel(): Promise<{
|
|
96
141
|
success: boolean;
|
|
@@ -106,23 +151,23 @@ export declare class JaakStamps {
|
|
|
106
151
|
success: boolean;
|
|
107
152
|
selectedCamera: string;
|
|
108
153
|
availableCameras: number;
|
|
154
|
+
error?: undefined;
|
|
155
|
+
} | {
|
|
156
|
+
success: boolean;
|
|
157
|
+
error: any;
|
|
158
|
+
selectedCamera: any;
|
|
159
|
+
availableCameras: number;
|
|
109
160
|
}>;
|
|
110
161
|
setCaptureDelay(delay: number): Promise<{
|
|
111
162
|
success: boolean;
|
|
163
|
+
error: string;
|
|
112
164
|
captureDelay: number;
|
|
113
|
-
}
|
|
114
|
-
getCaptureDelay(): Promise<number>;
|
|
115
|
-
setTorchEnabled(enabled: boolean): Promise<{
|
|
116
|
-
success: boolean;
|
|
117
|
-
enabled: boolean;
|
|
118
|
-
}>;
|
|
119
|
-
focusAtPoint(x: number, y: number): Promise<{
|
|
165
|
+
} | {
|
|
120
166
|
success: boolean;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
y: number;
|
|
124
|
-
};
|
|
167
|
+
captureDelay: number;
|
|
168
|
+
error?: undefined;
|
|
125
169
|
}>;
|
|
170
|
+
getCaptureDelay(): Promise<number>;
|
|
126
171
|
private startDetection;
|
|
127
172
|
private initializeVideoStream;
|
|
128
173
|
private detectFrame;
|
|
@@ -131,6 +176,8 @@ export declare class JaakStamps {
|
|
|
131
176
|
render(): any;
|
|
132
177
|
private updateDetectionBoxes;
|
|
133
178
|
private updateMaskColor;
|
|
179
|
+
private takeManualScreenshot;
|
|
180
|
+
private takeScreenshotWithMaskCoordinates;
|
|
134
181
|
private takeScreenshot;
|
|
135
182
|
private triggerCaptureAnimation;
|
|
136
183
|
private completeProcess;
|
|
@@ -138,6 +185,7 @@ export declare class JaakStamps {
|
|
|
138
185
|
private startBackDocumentTimer;
|
|
139
186
|
private clearBackDocumentTimer;
|
|
140
187
|
private toggleCameraSelector;
|
|
188
|
+
private updateCameraInfoWithAutofocus;
|
|
141
189
|
private handleCameraSwitch;
|
|
142
190
|
private resetDetection;
|
|
143
191
|
private exitSession;
|
|
@@ -145,4 +193,7 @@ export declare class JaakStamps {
|
|
|
145
193
|
private updatePerformanceMetrics;
|
|
146
194
|
private recordOnnxPerformance;
|
|
147
195
|
private recordFrameProcessing;
|
|
196
|
+
private getAdaptiveFrameSkip;
|
|
197
|
+
private getPooledCanvas;
|
|
198
|
+
private returnCanvasToPool;
|
|
148
199
|
}
|
|
@@ -33,7 +33,6 @@ export namespace Components {
|
|
|
33
33
|
* @default false
|
|
34
34
|
*/
|
|
35
35
|
"enableBackDocumentTimer": boolean;
|
|
36
|
-
"focusAtPoint": (x: number, y: number) => Promise<{ success: boolean; coordinates: { x: number; y: number; }; }>;
|
|
37
36
|
"getCameraInfo": () => Promise<CameraInfoResponse>;
|
|
38
37
|
"getCaptureDelay": () => Promise<number>;
|
|
39
38
|
"getCapturedImages": () => Promise<CapturedImagesResponse>;
|
|
@@ -48,17 +47,20 @@ export namespace Components {
|
|
|
48
47
|
*/
|
|
49
48
|
"preferredCamera": 'auto' | 'front' | 'back';
|
|
50
49
|
"preloadModel": () => Promise<{ success: boolean; message: string; error?: undefined; } | { success: boolean; error: any; message?: undefined; }>;
|
|
51
|
-
"resetCapture": () => Promise<
|
|
52
|
-
"setCaptureDelay": (delay: number) => Promise<{ success: boolean; captureDelay: number; }>;
|
|
53
|
-
"setPreferredCamera": (camera: "auto" | "front" | "back") => Promise<{ success: boolean; selectedCamera: string; availableCameras: number; }>;
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"stopCapture": () => Promise<void>;
|
|
50
|
+
"resetCapture": () => Promise<{ success: boolean; error?: undefined; } | { success: boolean; error: any; }>;
|
|
51
|
+
"setCaptureDelay": (delay: number) => Promise<{ success: boolean; error: string; captureDelay: number; } | { success: boolean; captureDelay: number; error?: undefined; }>;
|
|
52
|
+
"setPreferredCamera": (camera: "auto" | "front" | "back") => Promise<{ success: boolean; selectedCamera: string; availableCameras: number; error?: undefined; } | { success: boolean; error: any; selectedCamera: any; availableCameras: number; }>;
|
|
53
|
+
"skipBackCapture": () => Promise<{ success: boolean; error?: undefined; } | { success: boolean; error: any; }>;
|
|
54
|
+
"startCapture": () => Promise<{ success: boolean; error?: undefined; } | { success: boolean; error: any; }>;
|
|
55
|
+
"stopCapture": () => Promise<{ success: boolean; error?: undefined; } | { success: boolean; error: any; }>;
|
|
58
56
|
/**
|
|
59
57
|
* @default false
|
|
60
58
|
*/
|
|
61
59
|
"useDocumentClassification": boolean;
|
|
60
|
+
/**
|
|
61
|
+
* @default true
|
|
62
|
+
*/
|
|
63
|
+
"useDocumentDetector": boolean;
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
66
|
export interface JaakStampsCustomEvent<T> extends CustomEvent<T> {
|
|
@@ -128,6 +130,10 @@ declare namespace LocalJSX {
|
|
|
128
130
|
* @default false
|
|
129
131
|
*/
|
|
130
132
|
"useDocumentClassification"?: boolean;
|
|
133
|
+
/**
|
|
134
|
+
* @default true
|
|
135
|
+
*/
|
|
136
|
+
"useDocumentDetector"?: boolean;
|
|
131
137
|
}
|
|
132
138
|
interface IntrinsicElements {
|
|
133
139
|
"jaak-stamps": JaakStamps;
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { ICameraService, CameraInfo } from './interfaces/ICameraService';
|
|
2
|
-
import { ILogger } from './interfaces/ILogger';
|
|
3
2
|
import { IEventBus } from './interfaces/IEventBus';
|
|
4
3
|
export declare class CameraService implements ICameraService {
|
|
5
|
-
private logger;
|
|
6
4
|
private eventBus;
|
|
7
5
|
private availableCameras;
|
|
8
6
|
private selectedCameraId;
|
|
9
7
|
private deviceType;
|
|
10
8
|
private preferredCameraFacing;
|
|
11
9
|
private preferredCamera;
|
|
12
|
-
private
|
|
13
|
-
|
|
10
|
+
private static cameraCapabilitiesCache;
|
|
11
|
+
private static deviceEnumerationCache;
|
|
12
|
+
private static readonly CACHE_DURATION;
|
|
13
|
+
private currentStreamPromise?;
|
|
14
|
+
private lastStreamConstraints?;
|
|
15
|
+
constructor(eventBus: IEventBus, preferredCamera?: 'auto' | 'front' | 'back');
|
|
14
16
|
detectDeviceType(): Promise<'mobile' | 'desktop' | 'tablet'>;
|
|
15
17
|
enumerateDevices(): Promise<MediaDeviceInfo[]>;
|
|
16
18
|
getAvailableCameras(): MediaDeviceInfo[];
|
|
@@ -20,28 +22,24 @@ export declare class CameraService implements ICameraService {
|
|
|
20
22
|
getPreferredFacing(): 'environment' | 'user' | null;
|
|
21
23
|
setupCamera(constraints?: MediaTrackConstraints): Promise<MediaStream>;
|
|
22
24
|
switchCamera(cameraId: string): Promise<void>;
|
|
23
|
-
flipToNextCamera(): Promise<void>;
|
|
24
|
-
savePreference(): void;
|
|
25
|
-
loadPreference(): void;
|
|
26
25
|
isRearCamera(stream: MediaStream): boolean;
|
|
27
|
-
getCameraInfo(): {
|
|
26
|
+
getCameraInfo(): Promise<{
|
|
28
27
|
availableCameras: CameraInfo[];
|
|
29
28
|
selectedCameraId: string | null;
|
|
30
29
|
deviceType: string;
|
|
31
30
|
isMultipleCamerasAvailable: boolean;
|
|
32
31
|
preferredFacing: 'environment' | 'user' | null;
|
|
33
|
-
}
|
|
32
|
+
}>;
|
|
34
33
|
private checkCameraPermission;
|
|
35
34
|
private handleCameraPermissionError;
|
|
36
35
|
private setInitialCameraPreference;
|
|
36
|
+
private checkCameraAutofocus;
|
|
37
37
|
private selectFrontCamera;
|
|
38
38
|
private selectBackCamera;
|
|
39
39
|
private selectAutoCamera;
|
|
40
40
|
private updatePreferredFacing;
|
|
41
41
|
private getMaxResolution;
|
|
42
|
-
private
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
setTorchEnabled(enabled: boolean, stream?: MediaStream): Promise<boolean>;
|
|
46
|
-
focusAtPoint(x: number, y: number, stream?: MediaStream): Promise<boolean>;
|
|
42
|
+
private constraintsEqual;
|
|
43
|
+
static clearCaches(): void;
|
|
44
|
+
invalidateDeviceCache(): void;
|
|
47
45
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { IDetectionService, DetectionBox, SideAlignment, ClassificationResult } from './interfaces/IDetectionService';
|
|
2
|
-
import { ILogger } from './interfaces/ILogger';
|
|
3
2
|
export declare class DetectionService implements IDetectionService {
|
|
4
|
-
private logger;
|
|
5
3
|
private debug;
|
|
6
4
|
private useDocumentClassification;
|
|
5
|
+
private useDocumentDetector;
|
|
7
6
|
private session?;
|
|
8
7
|
private mobileNetSession?;
|
|
9
8
|
private mobileNetClassMap?;
|
|
@@ -17,7 +16,9 @@ export declare class DetectionService implements IDetectionService {
|
|
|
17
16
|
private preprocessCanvas?;
|
|
18
17
|
private preprocessCtx?;
|
|
19
18
|
private captureCanvas?;
|
|
20
|
-
|
|
19
|
+
private static canvasPool;
|
|
20
|
+
private static readonly MAX_POOL_SIZE;
|
|
21
|
+
constructor(debug?: boolean, useDocumentClassification?: boolean, useDocumentDetector?: boolean);
|
|
21
22
|
loadModel(): Promise<void>;
|
|
22
23
|
loadClassificationModel(): Promise<void>;
|
|
23
24
|
isModelLoaded(): boolean;
|
|
@@ -32,4 +33,10 @@ export declare class DetectionService implements IDetectionService {
|
|
|
32
33
|
private cleanupCanvasPool;
|
|
33
34
|
private float32ToFloat16;
|
|
34
35
|
private preprocessMobileNet;
|
|
36
|
+
private getCanvas;
|
|
37
|
+
private returnCanvas;
|
|
38
|
+
static clearCanvasPools(): void;
|
|
39
|
+
getPoolStats(): {
|
|
40
|
+
[key: string]: number;
|
|
41
|
+
};
|
|
35
42
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ILogger } from './interfaces/ILogger';
|
|
2
1
|
import { ICameraService } from './interfaces/ICameraService';
|
|
3
2
|
import { IDetectionService } from './interfaces/IDetectionService';
|
|
4
3
|
import { IStateManager } from './interfaces/IStateManager';
|
|
@@ -9,6 +8,7 @@ export interface ComponentConfig {
|
|
|
9
8
|
maskSize: number;
|
|
10
9
|
cropMargin: number;
|
|
11
10
|
useDocumentClassification: boolean;
|
|
11
|
+
useDocumentDetector: boolean;
|
|
12
12
|
preferredCamera: 'auto' | 'front' | 'back';
|
|
13
13
|
captureDelay: number;
|
|
14
14
|
}
|
|
@@ -17,7 +17,6 @@ export declare class ServiceContainer {
|
|
|
17
17
|
constructor(config: ComponentConfig);
|
|
18
18
|
private initializeServices;
|
|
19
19
|
get<T>(serviceName: string): T;
|
|
20
|
-
getLogger(): ILogger;
|
|
21
20
|
getEventBus(): IEventBus;
|
|
22
21
|
getStateManager(): IStateManager;
|
|
23
22
|
getCameraService(): ICameraService;
|
|
@@ -2,11 +2,7 @@ export interface CameraInfo {
|
|
|
2
2
|
id: string;
|
|
3
3
|
label: string;
|
|
4
4
|
selected: boolean;
|
|
5
|
-
|
|
6
|
-
export interface CameraPreference {
|
|
7
|
-
cameraId: string;
|
|
8
|
-
facing: 'environment' | 'user' | null;
|
|
9
|
-
timestamp: number;
|
|
5
|
+
hasAutofocus: boolean;
|
|
10
6
|
}
|
|
11
7
|
export interface ICameraService {
|
|
12
8
|
detectDeviceType(): Promise<'mobile' | 'desktop' | 'tablet'>;
|
|
@@ -18,17 +14,12 @@ export interface ICameraService {
|
|
|
18
14
|
getPreferredFacing(): 'environment' | 'user' | null;
|
|
19
15
|
setupCamera(constraints?: MediaTrackConstraints): Promise<MediaStream>;
|
|
20
16
|
switchCamera(cameraId: string): Promise<void>;
|
|
21
|
-
flipToNextCamera(): Promise<void>;
|
|
22
|
-
savePreference(): void;
|
|
23
|
-
loadPreference(): void;
|
|
24
17
|
isRearCamera(stream: MediaStream): boolean;
|
|
25
|
-
|
|
26
|
-
focusAtPoint(x: number, y: number, stream?: MediaStream): Promise<boolean>;
|
|
27
|
-
getCameraInfo(): {
|
|
18
|
+
getCameraInfo(): Promise<{
|
|
28
19
|
availableCameras: CameraInfo[];
|
|
29
20
|
selectedCameraId: string | null;
|
|
30
21
|
deviceType: string;
|
|
31
22
|
isMultipleCamerasAvailable: boolean;
|
|
32
23
|
preferredFacing: 'environment' | 'user' | null;
|
|
33
|
-
}
|
|
24
|
+
}>;
|
|
34
25
|
}
|
|
@@ -11,6 +11,7 @@ export interface CameraInfoResponse {
|
|
|
11
11
|
deviceType: string;
|
|
12
12
|
isMultipleCamerasAvailable: boolean;
|
|
13
13
|
preferredFacing: 'environment' | 'user' | null;
|
|
14
|
+
error?: string;
|
|
14
15
|
}
|
|
15
16
|
export interface CapturedImagesResponse {
|
|
16
17
|
front: {
|
|
@@ -33,4 +34,6 @@ export interface StatusResponse {
|
|
|
33
34
|
hasImages: boolean;
|
|
34
35
|
isProcessCompleted: boolean;
|
|
35
36
|
isModelPreloaded: boolean;
|
|
37
|
+
componentStatus?: 'initializing' | 'loading' | 'ready' | 'error';
|
|
38
|
+
componentMessage?: string;
|
|
36
39
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jaak.ai/stamps",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.1.0-dev.2",
|
|
4
4
|
"description": "Jaak Document Identifier",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@semantic-release/changelog": "^6.0.3",
|
|
52
52
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
53
53
|
"@semantic-release/git": "^10.0.1",
|
|
54
|
-
"@semantic-release/github": "^11.0.
|
|
54
|
+
"@semantic-release/github": "^11.0.4",
|
|
55
55
|
"@semantic-release/npm": "^12.0.2",
|
|
56
56
|
"@semantic-release/release-notes-generator": "^14.0.3",
|
|
57
57
|
"semantic-release": "^24.2.7"
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
export class LoggerService {
|
|
2
|
-
debugMode;
|
|
3
|
-
constructor(debug = false) {
|
|
4
|
-
this.debugMode = debug;
|
|
5
|
-
}
|
|
6
|
-
setDebugMode(debug) {
|
|
7
|
-
this.debugMode = debug;
|
|
8
|
-
}
|
|
9
|
-
info(...args) {
|
|
10
|
-
if (this.debugMode) {
|
|
11
|
-
console.log(`[JAAK-STAMPS] [INFO] [${new Date().toLocaleTimeString()}]`, ...args);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
warn(...args) {
|
|
15
|
-
if (this.debugMode) {
|
|
16
|
-
console.warn(`[JAAK-STAMPS] [WARN] [${new Date().toLocaleTimeString()}]`, ...args);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
error(...args) {
|
|
20
|
-
if (this.debugMode) {
|
|
21
|
-
console.error(`[JAAK-STAMPS] [ERROR] [${new Date().toLocaleTimeString()}]`, ...args);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
debug(...args) {
|
|
25
|
-
if (this.debugMode) {
|
|
26
|
-
console.debug(`[JAAK-STAMPS] [DEBUG] [${new Date().toLocaleTimeString()}]`, ...args);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
state(state, data) {
|
|
30
|
-
if (this.debugMode) {
|
|
31
|
-
console.log(`[JAAK-STAMPS] [STATE] [${new Date().toLocaleTimeString()}] ${state}`, data || '');
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
performance(operation, duration) {
|
|
35
|
-
if (this.debugMode) {
|
|
36
|
-
console.log(`[JAAK-STAMPS] [PERF] [${new Date().toLocaleTimeString()}] ${operation}: ${duration}ms`);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
//# sourceMappingURL=LoggerService.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LoggerService.js","sourceRoot":"","sources":["../../src/services/LoggerService.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAa;IAChB,SAAS,CAAU;IAE3B,YAAY,QAAiB,KAAK;QAChC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAED,YAAY,CAAC,KAAc;QACzB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAED,IAAI,CAAC,GAAG,IAAW;QACjB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAG,IAAW;QACjB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO,CAAC,IAAI,CAAC,yBAAyB,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,IAAW;QAClB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO,CAAC,KAAK,CAAC,0BAA0B,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,IAAW;QAClB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO,CAAC,KAAK,CAAC,0BAA0B,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAa,EAAE,IAAU;QAC7B,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,KAAK,KAAK,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;IAED,WAAW,CAAC,SAAiB,EAAE,QAAgB;QAC7C,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,KAAK,SAAS,KAAK,QAAQ,IAAI,CAAC,CAAC;QACvG,CAAC;IACH,CAAC;CACF","sourcesContent":["import { ILogger } from './interfaces/ILogger';\n\nexport class LoggerService implements ILogger {\n private debugMode: boolean;\n \n constructor(debug: boolean = false) {\n this.debugMode = debug;\n }\n\n setDebugMode(debug: boolean): void {\n this.debugMode = debug;\n }\n\n info(...args: any[]): void {\n if (this.debugMode) {\n console.log(`[JAAK-STAMPS] [INFO] [${new Date().toLocaleTimeString()}]`, ...args);\n }\n }\n\n warn(...args: any[]): void {\n if (this.debugMode) {\n console.warn(`[JAAK-STAMPS] [WARN] [${new Date().toLocaleTimeString()}]`, ...args);\n }\n }\n\n error(...args: any[]): void {\n if (this.debugMode) {\n console.error(`[JAAK-STAMPS] [ERROR] [${new Date().toLocaleTimeString()}]`, ...args);\n }\n }\n\n debug(...args: any[]): void {\n if (this.debugMode) {\n console.debug(`[JAAK-STAMPS] [DEBUG] [${new Date().toLocaleTimeString()}]`, ...args);\n }\n }\n\n state(state: string, data?: any): void {\n if (this.debugMode) {\n console.log(`[JAAK-STAMPS] [STATE] [${new Date().toLocaleTimeString()}] ${state}`, data || '');\n }\n }\n\n performance(operation: string, duration: number): void {\n if (this.debugMode) {\n console.log(`[JAAK-STAMPS] [PERF] [${new Date().toLocaleTimeString()}] ${operation}: ${duration}ms`);\n }\n }\n}"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ILogger.js","sourceRoot":"","sources":["../../../src/services/interfaces/ILogger.ts"],"names":[],"mappings":"","sourcesContent":["export interface ILogger {\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n debug(...args: any[]): void;\n state(state: string, data?: any): void;\n performance(operation: string, duration: number): void;\n}"]}
|
|
@@ -1,2 +0,0 @@
|
|
|
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";isManuallySelected=false;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.logger.state("PREFERENCIA_INICIAL_APLICADA",{selectedCameraId:this.selectedCameraId,preferredCameraFacing:this.preferredCameraFacing,preferredCamera:this.preferredCamera});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.isManuallySelected=true;this.savePreference();this.eventBus.emit("camera-changed",e)}getPreferredFacing(){return this.preferredCameraFacing}async setupCamera(e){try{const t=e||await this.getMaxResolution();const i=await navigator.mediaDevices.getUserMedia({video:t,audio:false});return i}catch(e){this.logger.error("Error en setupCamera, intentando con restricciones básicas:",e);const t={width:{ideal:1280},height:{ideal:720}};if(this.deviceType!=="desktop"&&this.preferredCameraFacing){t.facingMode=this.preferredCameraFacing}this.logger.state("USANDO_RESTRICCIONES_BASICAS",{constraints:t});return await navigator.mediaDevices.getUserMedia({video:t,audio:false})}}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,isManuallySelected:this.isManuallySelected})}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;localStorage.removeItem("jaak-stamps-camera-preference");this.logger.state("APLICANDO_PREFERENCIA_INICIAL",{preferredCamera:this.preferredCamera,availableCamerasCount:this.availableCameras.length});this.isManuallySelected=false;if(this.preferredCamera==="front"){this.selectFrontCamera()}else if(this.preferredCamera==="back"){this.selectBackCamera()}else{this.selectAutoCamera()}}selectFrontCamera(){this.preferredCameraFacing="user";this.logger.state("BUSCANDO_CAMARA_FRONTAL",{availableCameras:this.availableCameras.map((e=>({id:e.deviceId,label:e.label})))});const e=this.availableCameras.find((e=>{const t=e.label.toLowerCase();return t.includes("front")||t.includes("user")||t.includes("selfie")||t.includes("frontal")||!t.includes("back")&&!t.includes("rear")&&!t.includes("environment")}));this.selectedCameraId=e?e.deviceId:this.availableCameras[0].deviceId;this.logger.state("CAMARA_FRONTAL_SELECCIONADA",{found:!!e,label:e?.label||this.availableCameras[0].label,deviceId:this.selectedCameraId})}selectBackCamera(){this.preferredCameraFacing="environment";this.logger.state("BUSCANDO_CAMARA_TRASERA",{availableCameras:this.availableCameras.map((e=>({id:e.deviceId,label:e.label})))});let e=this.availableCameras.find((e=>{const t=e.label.toLowerCase();return t.includes("back")||t.includes("rear")||t.includes("environment")||t.includes("trasera")||t.includes("posterior")}));if(!e&&this.availableCameras.length>1){e=this.availableCameras[this.availableCameras.length-1];this.logger.state("USANDO_ULTIMA_CAMARA_COMO_TRASERA",{label:e.label,deviceId:e.deviceId})}this.selectedCameraId=e?e.deviceId:this.availableCameras[0].deviceId;this.logger.state("CAMARA_TRASERA_SELECCIONADA",{found:!!e,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.selectFrontCamera();this.logger.state("CAMARA_AUTO_SELECCIONADA_DESKTOP",{type:"front",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{if(!this.deviceType||this.deviceType==="desktop"){await this.detectDeviceType()}const e={};this.logger.state("CONFIGURANDO_CONSTRAINS_CAMARA",{selectedCameraId:this.selectedCameraId,preferredCameraFacing:this.preferredCameraFacing,preferredCamera:this.preferredCamera,deviceType:this.deviceType,isManuallySelected:this.isManuallySelected});if(this.isManuallySelected&&this.selectedCameraId){e.deviceId={exact:this.selectedCameraId};this.logger.state("USANDO_CAMARA_MANUAL",{deviceId:this.selectedCameraId})}else if(this.preferredCameraFacing){const t=this.deviceType==="desktop"?{ideal:this.preferredCameraFacing}:{exact:this.preferredCameraFacing};e.facingMode=t;this.logger.state("USANDO_FACING_CONSTRAINT",{facingMode:this.preferredCameraFacing,constraintType:this.deviceType==="desktop"?"ideal":"exact"})}else if(this.selectedCameraId){e.deviceId={exact:this.selectedCameraId};this.logger.state("USANDO_CAMARA_SELECCIONADA",{deviceId:this.selectedCameraId})}else{if(this.preferredCamera==="front"){e.facingMode="user"}else if(this.preferredCamera==="back"){e.facingMode="environment"}else{e.facingMode=this.deviceType==="mobile"||this.deviceType==="tablet"?"environment":"user"}this.logger.state("USANDO_PREFERENCIA_CONFIGURADA",{facingMode:e.facingMode,preferredCamera:this.preferredCamera,deviceType:this.deviceType})}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");if(!this.deviceType||this.deviceType==="desktop"){await this.detectDeviceType()}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.isManuallySelected&&this.selectedCameraId){i.deviceId={exact:this.selectedCameraId}}else if(this.preferredCameraFacing){const e=this.deviceType==="desktop"?{ideal:this.preferredCameraFacing}:{exact:this.preferredCameraFacing};i.facingMode=e}else if(this.selectedCameraId){i.deviceId={exact:this.selectedCameraId}}else{if(this.preferredCamera==="front"){i.facingMode="user"}else if(this.preferredCamera==="back"){i.facingMode="environment"}else{i.facingMode=this.deviceType==="mobile"||this.deviceType==="tablet"?"environment":"user"}}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_new_fp32.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 m=p*s;let u,b;const g=r/100;if(m<=f){b=p*g;u=b*s}else{u=f*g;b=u/s}const x=u*(i/f);const y=b*(i/p);const w=i/2;const A=i/2;const v=w-x/2;const C=w+x/2;const k=A-y/2;const E=A+y/2;let I=e.x;let S=e.x+e.w;const M=e.y;const D=e.y+e.h;if(a){const e=I;const t=S;I=i-t;S=i-e}const T=o;const O=Math.abs(M-k)<=T;const N=Math.abs(S-C)<=T;const _=Math.abs(D-E)<=T;const R=Math.abs(I-v)<=T;return{top:O&&R,right:O&&N,bottom:_&&R,left:_&&N}}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(0, 0, 0, 0.25);backdrop-filter:blur(12px);padding:12px 20px;border-radius:8px;max-width:300px;z-index:20;border:1px solid rgba(255, 255, 255, 0.1)}.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:rgba(0, 0, 0, 0.5);color:#ffffff;padding:10px 16px;border-radius:8px;font-size:14px;font-weight:500;text-align:center;margin-bottom:12px;box-shadow:0 2px 8px rgba(0, 0, 0, 0.2);backdrop-filter:blur(12px);border:1px solid rgba(255, 255, 255, 0.1);animation:fadeIn 0.3s ease-in-out}@keyframes fadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.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 m=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=90;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 m=h/e.width*100;const u=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",`${m}%`);this.el.style.setProperty("--mask-height",`${u}%`);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:m,heightPercent:u},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 m=d/p;const u=l/p;this.detectionBoxes=e.map((e=>({x:e.x*m+h,y:e.y*u+f,w:e.w*m,h:e.h*u,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",`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++}}};m.style=p;export{m as jaak_stamps};
|
|
2
|
-
//# sourceMappingURL=p-2264b5b4.entry.js.map
|