@jaak.ai/stamps 2.5.7-dev.4 → 2.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/cjs/{index-BcFBOmM6.js → index-D6NBn_qu.js} +4 -30
  2. package/dist/cjs/index-D6NBn_qu.js.map +1 -0
  3. package/dist/cjs/jaak-stamps-webcomponent.cjs.js +2 -2
  4. package/dist/cjs/jaak-stamps.cjs.entry.js +72 -145
  5. package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -1
  6. package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -1
  7. package/dist/cjs/loader.cjs.js +2 -2
  8. package/dist/collection/collection-manifest.json +1 -1
  9. package/dist/collection/components/{jaak-stamps/jaak-stamps.js → my-component/my-component.js} +34 -90
  10. package/dist/collection/components/my-component/my-component.js.map +1 -0
  11. package/dist/collection/components/my-component/watermark-fallback.js.map +1 -0
  12. package/dist/collection/services/DetectionService.js +38 -60
  13. package/dist/collection/services/DetectionService.js.map +1 -1
  14. package/dist/collection/utils/utils.js +4 -0
  15. package/dist/collection/utils/utils.js.map +1 -0
  16. package/dist/components/index.js +2 -20
  17. package/dist/components/index.js.map +1 -1
  18. package/dist/components/jaak-stamps.js +71 -147
  19. package/dist/components/jaak-stamps.js.map +1 -1
  20. package/dist/esm/{index-Cb0ILUvS.js → index-BCfAsrzL.js} +4 -30
  21. package/dist/esm/index-BCfAsrzL.js.map +1 -0
  22. package/dist/esm/jaak-stamps-webcomponent.js +3 -3
  23. package/dist/esm/jaak-stamps.entry.js +72 -145
  24. package/dist/esm/jaak-stamps.entry.js.map +1 -1
  25. package/dist/esm/loader.js +3 -3
  26. package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +1 -1
  27. package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -1
  28. package/dist/jaak-stamps-webcomponent/{p-9afd846d.entry.js → p-63c2c085.entry.js} +3 -3
  29. package/dist/jaak-stamps-webcomponent/p-63c2c085.entry.js.map +1 -0
  30. package/dist/jaak-stamps-webcomponent/p-BCfAsrzL.js +3 -0
  31. package/dist/jaak-stamps-webcomponent/p-BCfAsrzL.js.map +1 -0
  32. package/dist/types/components/{jaak-stamps/jaak-stamps.d.ts → my-component/my-component.d.ts} +0 -5
  33. package/dist/types/services/DetectionService.d.ts +4 -5
  34. package/dist/types/utils/utils.d.ts +1 -0
  35. package/package.json +4 -4
  36. package/dist/cjs/index-BcFBOmM6.js.map +0 -1
  37. package/dist/collection/components/jaak-stamps/jaak-stamps.js.map +0 -1
  38. package/dist/collection/components/jaak-stamps/watermark-fallback.js.map +0 -1
  39. package/dist/esm/index-Cb0ILUvS.js.map +0 -1
  40. package/dist/jaak-stamps-webcomponent/p-9afd846d.entry.js.map +0 -1
  41. package/dist/jaak-stamps-webcomponent/p-Cb0ILUvS.js +0 -3
  42. package/dist/jaak-stamps-webcomponent/p-Cb0ILUvS.js.map +0 -1
  43. /package/dist/collection/components/{jaak-stamps/jaak-stamps.css → my-component/my-component.css} +0 -0
  44. /package/dist/collection/components/{jaak-stamps → my-component}/watermark-fallback.js +0 -0
  45. /package/dist/types/components/{jaak-stamps → my-component}/watermark-fallback.d.ts +0 -0
@@ -15,6 +15,15 @@ export class DetectionService {
15
15
  INPUT_SIZE = 320;
16
16
  CONFIDENCE_THRESHOLD = 0.6;
17
17
  useFloat16 = true;
18
+ // Hoisted views for float32->float16 bit-twiddling. A fresh ArrayBuffer
19
+ // per call was costing ~614K allocations per frame.
20
+ _f32View = new Float32Array(1);
21
+ _u32View = new Uint32Array(this._f32View.buffer);
22
+ // Pre-allocated tensor buffers reused across frames. Same shape every time
23
+ // (3 * INPUT_SIZE * INPUT_SIZE), and runInference is awaited before the next
24
+ // preprocess runs, so reuse is safe.
25
+ _tensorF32 = new Float32Array(3 * 320 * 320);
26
+ _tensorF16 = new Uint16Array(3 * 320 * 320);
18
27
  // Canvas pool for optimization
19
28
  preprocessCanvas;
20
29
  preprocessCtx;
@@ -41,7 +50,7 @@ export class DetectionService {
41
50
  try {
42
51
  const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);
43
52
  try {
44
- this.session = await this.createSession(this.MODEL_PATH, sessionOptions);
53
+ this.session = await window.ort.InferenceSession.create(this.MODEL_PATH, sessionOptions);
45
54
  this.detectFloat16Support();
46
55
  }
47
56
  catch (error) {
@@ -56,7 +65,7 @@ export class DetectionService {
56
65
  if (isFloat16Error) {
57
66
  this.useFloat16 = false;
58
67
  try {
59
- this.session = await this.createSession(this.MODEL_PATH_FP32, sessionOptions);
68
+ this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, sessionOptions);
60
69
  }
61
70
  catch (fp32Error) {
62
71
  // Intentar con opciones minimas de WASM
@@ -65,7 +74,7 @@ export class DetectionService {
65
74
  graphOptimizationLevel: 'all',
66
75
  logSeverityLevel: this.debug ? 2 : 4,
67
76
  };
68
- this.session = await this.createSession(this.MODEL_PATH_FP32, wasmOptions);
77
+ this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, wasmOptions);
69
78
  }
70
79
  }
71
80
  else if (isMemoryError) {
@@ -84,7 +93,7 @@ export class DetectionService {
84
93
  };
85
94
  this.useFloat16 = false;
86
95
  try {
87
- this.session = await this.createSession(this.MODEL_PATH_FP32, fallbackOptions);
96
+ this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, fallbackOptions);
88
97
  }
89
98
  catch (fallbackError) {
90
99
  throw new Error(`no available backend found. ERR: [wasm] RangeError: Out of memory`);
@@ -125,7 +134,7 @@ export class DetectionService {
125
134
  // Load model
126
135
  const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);
127
136
  try {
128
- this.mobileNetSession = await this.createSession(this.MOBILENET_MODEL_PATH, sessionOptions);
137
+ this.mobileNetSession = await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, sessionOptions);
129
138
  }
130
139
  catch (error) {
131
140
  // Múltiples tipos de errores de memoria que pueden ocurrir
@@ -149,7 +158,7 @@ export class DetectionService {
149
158
  sessionLogVerbosityLevel: 0,
150
159
  };
151
160
  try {
152
- this.mobileNetSession = await this.createSession(this.MOBILENET_MODEL_PATH, fallbackOptions);
161
+ this.mobileNetSession = await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, fallbackOptions);
153
162
  }
154
163
  catch (fallbackError) {
155
164
  throw new Error(`no available backend found. ERR: [wasm] RangeError: Out of memory`);
@@ -175,25 +184,31 @@ export class DetectionService {
175
184
  if (!this.preprocessCanvas || !this.preprocessCtx) {
176
185
  this.initializeCanvasPool();
177
186
  }
178
- this.preprocessCtx.clearRect(0, 0, this.INPUT_SIZE, this.INPUT_SIZE);
179
- this.preprocessCtx.drawImage(video, 0, 0, this.INPUT_SIZE, this.INPUT_SIZE);
180
- const imageData = this.preprocessCtx.getImageData(0, 0, this.INPUT_SIZE, this.INPUT_SIZE);
181
- const [R, G, B] = [[], [], []];
187
+ const SIZE = this.INPUT_SIZE;
188
+ this.preprocessCtx.clearRect(0, 0, SIZE, SIZE);
189
+ this.preprocessCtx.drawImage(video, 0, 0, SIZE, SIZE);
190
+ const imageData = this.preprocessCtx.getImageData(0, 0, SIZE, SIZE);
182
191
  const { data } = imageData;
183
- for (let i = 0; i < data.length; i += 4) {
184
- R.push(data[i] / 255);
185
- G.push(data[i + 1] / 255);
186
- B.push(data[i + 2] / 255);
187
- }
188
- const transposedData = new Float32Array(R.concat(G, B));
192
+ const pixels = SIZE * SIZE;
193
+ const gOffset = pixels;
194
+ const bOffset = pixels * 2;
195
+ const inv255 = 1 / 255;
189
196
  if (this.useFloat16) {
190
- const float16Data = new Uint16Array(transposedData.length);
191
- for (let i = 0; i < transposedData.length; i++) {
192
- float16Data[i] = this.float32ToFloat16(transposedData[i]);
197
+ const out = this._tensorF16;
198
+ for (let i = 0, p = 0; i < data.length; i += 4, p++) {
199
+ out[p] = this.float32ToFloat16(data[i] * inv255);
200
+ out[gOffset + p] = this.float32ToFloat16(data[i + 1] * inv255);
201
+ out[bOffset + p] = this.float32ToFloat16(data[i + 2] * inv255);
193
202
  }
194
- return new window.ort.Tensor("float16", float16Data, [1, 3, this.INPUT_SIZE, this.INPUT_SIZE]);
203
+ return new window.ort.Tensor("float16", out, [1, 3, SIZE, SIZE]);
204
+ }
205
+ const out = this._tensorF32;
206
+ for (let i = 0, p = 0; i < data.length; i += 4, p++) {
207
+ out[p] = data[i] * inv255;
208
+ out[gOffset + p] = data[i + 1] * inv255;
209
+ out[bOffset + p] = data[i + 2] * inv255;
195
210
  }
196
- return new window.ort.Tensor("float32", transposedData, [1, 3, this.INPUT_SIZE, this.INPUT_SIZE]);
211
+ return new window.ort.Tensor("float32", out, [1, 3, SIZE, SIZE]);
197
212
  }
198
213
  async runInference(inputTensor) {
199
214
  if (!this.useDocumentDetector) {
@@ -341,41 +356,6 @@ export class DetectionService {
341
356
  areAllSidesAligned(alignment) {
342
357
  return alignment.top && alignment.right && alignment.bottom && alignment.left;
343
358
  }
344
- // Reference counter so concurrent sessions share one filter and the last
345
- // one to finish restores the original console.warn.
346
- static _ortWarnActiveCount = 0;
347
- static _originalWarn = null;
348
- static _acquireWarnFilter() {
349
- if (DetectionService._ortWarnActiveCount === 0) {
350
- DetectionService._originalWarn = console.warn;
351
- console.warn = (...args) => {
352
- const msg = typeof args[0] === 'string' ? args[0] : '';
353
- if (!msg.includes('removing requested execution provider')) {
354
- DetectionService._originalWarn.apply(console, args);
355
- }
356
- };
357
- }
358
- DetectionService._ortWarnActiveCount++;
359
- }
360
- static _releaseWarnFilter() {
361
- DetectionService._ortWarnActiveCount--;
362
- if (DetectionService._ortWarnActiveCount === 0 && DetectionService._originalWarn) {
363
- console.warn = DetectionService._originalWarn;
364
- DetectionService._originalWarn = null;
365
- }
366
- }
367
- async createSession(modelPath, options) {
368
- // Keep the filter active for the full await: ORT may emit
369
- // "removing requested execution provider" during async resolution,
370
- // not only in the synchronous preamble of create().
371
- DetectionService._acquireWarnFilter();
372
- try {
373
- return await window.ort.InferenceSession.create(modelPath, options);
374
- }
375
- finally {
376
- DetectionService._releaseWarnFilter();
377
- }
378
- }
379
359
  cleanup() {
380
360
  this.cleanupCanvasPool();
381
361
  if (this.session) {
@@ -420,10 +400,8 @@ export class DetectionService {
420
400
  }
421
401
  }
422
402
  float32ToFloat16(value) {
423
- const buffer = new ArrayBuffer(4);
424
- const view = new DataView(buffer);
425
- view.setFloat32(0, value, true);
426
- const f = view.getUint32(0, true);
403
+ this._f32View[0] = value;
404
+ const f = this._u32View[0];
427
405
  const sign = (f >> 31) & 0x1;
428
406
  const exp = (f >> 23) & 0xFF;
429
407
  const frac = f & 0x7FFFFF;
@@ -1 +1 @@
1
- {"version":3,"file":"DetectionService.js","sourceRoot":"","sources":["../../src/services/DetectionService.ts"],"names":[],"mappings":"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","sourcesContent":["import { IDetectionService, DetectionBox, SideAlignment, ClassificationResult } from './interfaces/IDetectionService';\nimport { IDeviceStrategy } from './strategies/IDeviceStrategy';\nimport { DeviceStrategyFactory } from './factories/DeviceStrategyFactory';\n\nexport class DetectionService implements IDetectionService {\n private session?: any;\n private mobileNetSession?: any;\n private mobileNetClassMap?: any;\n private modelLoaded: boolean = false;\n private deviceStrategy: IDeviceStrategy;\n\n private readonly MODEL_PATH = \"https://static.jaak.ai/web/component/stamps/ddmyp-v2.onnx\";\n private readonly MODEL_PATH_FP32 = \"https://static.jaak.ai/web/component/stamps/ddmyp-v2-fp32.onnx\";\n private readonly MOBILENET_MODEL_PATH = \"https://static.jaak.ai/web/component/stamps/squeezenet_new_fp32.onnx\";\n private readonly MOBILENET_CLASSES_PATH = \"https://static.jaak.ai/web/component/stamps/cdmmp-v1.json\";\n private readonly INPUT_SIZE = 320;\n private readonly CONFIDENCE_THRESHOLD = 0.6;\n private useFloat16: boolean = true;\n\n // Canvas pool for optimization\n private preprocessCanvas?: HTMLCanvasElement;\n private preprocessCtx?: CanvasRenderingContext2D;\n private captureCanvas?: HTMLCanvasElement;\n \n // Static canvas pool for reuse across instances\n private static canvasPool = new Map<string, HTMLCanvasElement[]>();\n private static readonly MAX_POOL_SIZE = 5;\n\n constructor(\n private debug: boolean = false,\n private useDocumentClassification: boolean = false,\n private useDocumentDetector: boolean = true\n ) {\n this.deviceStrategy = DeviceStrategyFactory.createStrategy();\n this.initializeCanvasPool();\n }\n\n async loadModel(): Promise<void> {\n if (this.modelLoaded || this.session) {\n return;\n }\n\n if (!this.useDocumentDetector) {\n // Skip loading the detection model but mark as \"loaded\" for compatibility\n this.modelLoaded = true;\n return;\n }\n\n try {\n\n const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);\n\n try {\n this.session = await this.createSession(this.MODEL_PATH, sessionOptions);\n this.detectFloat16Support();\n } catch (error) {\n const errorMsg = error.message || '';\n const isMemoryError = errorMsg.includes('failed to allocate a buffer') ||\n errorMsg.includes('Out of memory') ||\n errorMsg.includes('RangeError: Out of memory') ||\n errorMsg.includes('no available backend found');\n const isFloat16Error = errorMsg.includes('unsupported data type') ||\n errorMsg.includes('FLOAT16') ||\n errorMsg.includes('float16');\n\n if (isFloat16Error) {\n this.useFloat16 = false;\n try {\n this.session = await this.createSession(this.MODEL_PATH_FP32, sessionOptions);\n } catch (fp32Error) {\n // Intentar con opciones minimas de WASM\n const wasmOptions = {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'all',\n logSeverityLevel: this.debug ? 2 : 4,\n };\n this.session = await this.createSession(this.MODEL_PATH_FP32, wasmOptions);\n }\n } else if (isMemoryError) {\n const fallbackOptions = {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'disabled',\n logSeverityLevel: 4,\n enableCpuMemArena: false,\n enableMemPattern: false,\n executionMode: 'sequential',\n interOpNumThreads: 1,\n intraOpNumThreads: 1,\n enableProfiling: false,\n sessionLogSeverityLevel: 4,\n sessionLogVerbosityLevel: 0,\n };\n\n this.useFloat16 = false;\n\n try {\n this.session = await this.createSession(this.MODEL_PATH_FP32, fallbackOptions);\n } catch (fallbackError) {\n throw new Error(`no available backend found. ERR: [wasm] RangeError: Out of memory`);\n }\n } else {\n throw error;\n }\n }\n\n this.modelLoaded = true;\n } catch (error) {\n throw error;\n }\n }\n\n async loadClassificationModel(): Promise<void> {\n if (!this.useDocumentClassification) {\n return;\n }\n\n try {\n\n // Try to load class map (optional - SqueezeNet may not need it for basic classification)\n try {\n const classResponse = await fetch(this.MOBILENET_CLASSES_PATH);\n if (classResponse.ok) {\n this.mobileNetClassMap = await classResponse.json();\n }\n } catch (error) {\n // Create a basic class map for document types\n this.mobileNetClassMap = {\n \"0\": \"document\",\n \"1\": \"id_card\",\n \"2\": \"passport\",\n \"3\": \"license\",\n \"4\": \"other\"\n };\n }\n\n // Load model\n const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);\n try {\n this.mobileNetSession = await this.createSession(this.MOBILENET_MODEL_PATH, sessionOptions);\n } catch (error) {\n // Múltiples tipos de errores de memoria que pueden ocurrir\n const isMemoryError = error.message.includes('failed to allocate a buffer') ||\n error.message.includes('Out of memory') ||\n error.message.includes('RangeError: Out of memory') ||\n error.message.includes('no available backend found');\n \n if (isMemoryError) {\n const fallbackOptions = {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'disabled',\n logSeverityLevel: 4,\n enableCpuMemArena: false,\n enableMemPattern: false,\n executionMode: 'sequential',\n interOpNumThreads: 1,\n intraOpNumThreads: 1,\n // Configuraciones adicionales para dispositivos con poca memoria\n enableProfiling: false,\n sessionLogSeverityLevel: 4,\n sessionLogVerbosityLevel: 0,\n };\n \n try {\n this.mobileNetSession = await this.createSession(this.MOBILENET_MODEL_PATH, fallbackOptions);\n } catch (fallbackError) {\n throw new Error(`no available backend found. ERR: [wasm] RangeError: Out of memory`);\n }\n } else {\n throw error;\n }\n }\n\n } catch (error) {\n throw error;\n }\n }\n\n isModelLoaded(): boolean {\n if (!this.useDocumentDetector) {\n // If detector is disabled, consider it \"loaded\" for compatibility\n return this.modelLoaded;\n }\n return this.modelLoaded && !!this.session;\n }\n\n preprocess(video: HTMLVideoElement): any {\n if (!this.preprocessCanvas || !this.preprocessCtx) {\n this.initializeCanvasPool();\n }\n\n this.preprocessCtx!.clearRect(0, 0, this.INPUT_SIZE, this.INPUT_SIZE);\n this.preprocessCtx!.drawImage(video, 0, 0, this.INPUT_SIZE, this.INPUT_SIZE);\n\n const imageData = this.preprocessCtx!.getImageData(0, 0, this.INPUT_SIZE, this.INPUT_SIZE);\n const [R, G, B] = [[], [], []] as number[][];\n const { data } = imageData;\n\n for (let i = 0; i < data.length; i += 4) {\n R.push(data[i] / 255);\n G.push(data[i + 1] / 255);\n B.push(data[i + 2] / 255);\n }\n\n const transposedData = new Float32Array(R.concat(G, B));\n\n if (this.useFloat16) {\n const float16Data = new Uint16Array(transposedData.length);\n for (let i = 0; i < transposedData.length; i++) {\n float16Data[i] = this.float32ToFloat16(transposedData[i]);\n }\n return new (window as any).ort.Tensor(\"float16\", float16Data, [1, 3, this.INPUT_SIZE, this.INPUT_SIZE]);\n }\n\n return new (window as any).ort.Tensor(\"float32\", transposedData, [1, 3, this.INPUT_SIZE, this.INPUT_SIZE]);\n }\n\n async runInference(inputTensor: any): Promise<DetectionBox[]> {\n if (!this.useDocumentDetector) {\n // Return empty array when document detector is disabled\n return [];\n }\n\n if (!this.session) {\n throw new Error('Detection model not loaded');\n }\n\n const feeds = { [this.session.inputNames[0]]: inputTensor };\n const results = await this.session.run(feeds);\n const output = results[this.session.outputNames[0]].data;\n\n const detections: DetectionBox[] = [];\n for (let i = 0; i < output.length; i += 6) {\n const [x1, y1, x2, y2, score, classId] = output.slice(i, i + 6);\n if (score > this.CONFIDENCE_THRESHOLD) {\n detections.push({\n x: x1,\n y: y1,\n w: x2 - x1,\n h: y2 - y1,\n score,\n classId\n });\n }\n }\n\n return detections;\n }\n\n async classifyDocument(canvas: HTMLCanvasElement): Promise<ClassificationResult | null> {\n if (!this.mobileNetSession || !this.mobileNetClassMap) {\n return null;\n }\n\n try {\n\n const inputTensor = this.preprocessMobileNet(canvas);\n const feeds = { [this.mobileNetSession.inputNames[0]]: inputTensor };\n const results = await this.mobileNetSession.run(feeds);\n const output = results[Object.keys(results)[0]].data;\n\n const maxIdx = output.reduce((bestIdx: number, val: number, idx: number, arr: number[]) =>\n val > arr[bestIdx] ? idx : bestIdx, 0);\n const confidence = output[maxIdx];\n\n const className = this.mobileNetClassMap[maxIdx.toString()] || \"unknown\";\n\n\n return {\n class: className,\n confidence: confidence,\n classIndex: maxIdx\n };\n\n } catch (error) {\n return null;\n }\n }\n\n checkSideAlignment(box: DetectionBox, maskConfig: any): SideAlignment {\n const { INPUT_SIZE, ID1_ASPECT_RATIO, shouldMirrorVideo, alignmentTolerance, maskSize, videoRef } = maskConfig;\n\n if (!videoRef) {\n return { top: false, right: false, bottom: false, left: false };\n }\n\n // Get video dimensions to calculate actual mask boundaries in model space\n const videoWidth = videoRef.videoWidth;\n const videoHeight = videoRef.videoHeight;\n\n if (videoWidth === 0 || videoHeight === 0) {\n return { top: false, right: false, bottom: false, left: false };\n }\n\n // Calculate video aspect ratio\n const videoAspectRatio = videoWidth / videoHeight;\n\n // The model sees video stretched to 320x320, but we need to calculate where\n // the mask should be in this distorted space to match the visual mask\n\n // In the visual display, we calculate mask size based on the limiting dimension\n // We need to replicate this logic but account for the distortion in model space\n\n // Calculate the \"display\" dimensions (what the visual mask calculations use)\n const containerAspectRatio = 1; // Assume square container for simplicity\n let displayedVideoWidth, displayedVideoHeight;\n\n if (videoAspectRatio > containerAspectRatio) {\n // Video is wider - letterboxed in display\n displayedVideoWidth = INPUT_SIZE;\n displayedVideoHeight = INPUT_SIZE / videoAspectRatio;\n } else {\n // Video is taller - pillarboxed in display\n displayedVideoHeight = INPUT_SIZE;\n displayedVideoWidth = INPUT_SIZE * videoAspectRatio;\n }\n\n // Calculate mask dimensions using the same logic as updateMaskDimensions\n const maxWidthByHeight = displayedVideoHeight * ID1_ASPECT_RATIO;\n\n let visualMaskWidth, visualMaskHeight;\n const sizeRatio = maskSize / 100;\n\n if (maxWidthByHeight <= displayedVideoWidth) {\n // Video height is the limiting factor\n visualMaskHeight = displayedVideoHeight * sizeRatio;\n visualMaskWidth = visualMaskHeight * ID1_ASPECT_RATIO;\n } else {\n // Video width is the limiting factor\n visualMaskWidth = displayedVideoWidth * sizeRatio;\n visualMaskHeight = visualMaskWidth / ID1_ASPECT_RATIO;\n }\n\n // Now map these visual mask dimensions to the distorted model space\n // The model stretches video to 320x320, so we need to apply the inverse transformation\n const modelMaskWidth = visualMaskWidth * (INPUT_SIZE / displayedVideoWidth);\n const modelMaskHeight = visualMaskHeight * (INPUT_SIZE / displayedVideoHeight);\n\n // Calculate mask boundaries in model coordinate system (always centered in 320x320)\n const maskCenterX = INPUT_SIZE / 2;\n const maskCenterY = INPUT_SIZE / 2;\n const maskLeft = maskCenterX - (modelMaskWidth / 2);\n const maskRight = maskCenterX + (modelMaskWidth / 2);\n const maskTop = maskCenterY - (modelMaskHeight / 2);\n const maskBottom = maskCenterY + (modelMaskHeight / 2);\n\n // Obtener las coordenadas del documento detectado\n let docLeft = box.x;\n let docRight = box.x + box.w;\n const docTop = box.y;\n const docBottom = box.y + box.h;\n\n // Si el video está en modo mirror, invertir las coordenadas horizontales\n if (shouldMirrorVideo) {\n const originalDocLeft = docLeft;\n const originalDocRight = docRight;\n docLeft = INPUT_SIZE - originalDocRight;\n docRight = INPUT_SIZE - originalDocLeft;\n }\n\n // Tolerancia para considerar que un lado está alineado (en píxeles)\n const tolerance = alignmentTolerance;\n\n // Verificar alineación de esquinas más estricta\n // Una esquina está alineada solo si AMBOS bordes que la forman están alineados\n const topAligned = Math.abs(docTop - maskTop) <= tolerance;\n const rightAligned = Math.abs(docRight - maskRight) <= tolerance;\n const bottomAligned = Math.abs(docBottom - maskBottom) <= tolerance;\n const leftAligned = Math.abs(docLeft - maskLeft) <= tolerance;\n\n return {\n top: topAligned && leftAligned, // Esquina superior izquierda: borde top Y left alineados\n right: topAligned && rightAligned, // Esquina superior derecha: borde top Y right alineados\n bottom: bottomAligned && leftAligned, // Esquina inferior izquierda: borde bottom Y left alineados\n left: bottomAligned && rightAligned // Esquina inferior derecha: borde bottom Y right alineados\n };\n }\n\n isCardInFrame(box: DetectionBox): boolean {\n const cardCenterX = box.x + box.w / 2;\n const cardCenterY = box.y + box.h / 2;\n const frameCenterX = this.INPUT_SIZE / 2;\n const frameCenterY = this.INPUT_SIZE / 2;\n const toleranceX = 40;\n const toleranceY = 30;\n\n const isCentered = Math.abs(cardCenterX - frameCenterX) < toleranceX &&\n Math.abs(cardCenterY - frameCenterY) < toleranceY;\n const isGoodSize = box.w > 150 && box.w < 300 && box.h > 90 && box.h < 200;\n\n return isCentered && isGoodSize;\n }\n\n areAllSidesAligned(alignment: SideAlignment): boolean {\n return alignment.top && alignment.right && alignment.bottom && alignment.left;\n }\n\n // Reference counter so concurrent sessions share one filter and the last\n // one to finish restores the original console.warn.\n private static _ortWarnActiveCount = 0;\n private static _originalWarn: typeof console.warn | null = null;\n\n private static _acquireWarnFilter(): void {\n if (DetectionService._ortWarnActiveCount === 0) {\n DetectionService._originalWarn = console.warn;\n console.warn = (...args: any[]) => {\n const msg = typeof args[0] === 'string' ? args[0] : '';\n if (!msg.includes('removing requested execution provider')) {\n DetectionService._originalWarn!.apply(console, args);\n }\n };\n }\n DetectionService._ortWarnActiveCount++;\n }\n\n private static _releaseWarnFilter(): void {\n DetectionService._ortWarnActiveCount--;\n if (DetectionService._ortWarnActiveCount === 0 && DetectionService._originalWarn) {\n console.warn = DetectionService._originalWarn;\n DetectionService._originalWarn = null;\n }\n }\n\n private async createSession(modelPath: string, options: any): Promise<any> {\n // Keep the filter active for the full await: ORT may emit\n // \"removing requested execution provider\" during async resolution,\n // not only in the synchronous preamble of create().\n DetectionService._acquireWarnFilter();\n try {\n return await (window as any).ort.InferenceSession.create(modelPath, options);\n } finally {\n DetectionService._releaseWarnFilter();\n }\n }\n\n cleanup(): void {\n this.cleanupCanvasPool();\n\n if (this.session) {\n this.session.release?.();\n this.session = undefined;\n }\n if (this.mobileNetSession) {\n this.mobileNetSession.release?.();\n this.mobileNetSession = undefined;\n }\n this.mobileNetClassMap = undefined;\n this.modelLoaded = false;\n\n }\n\n private initializeCanvasPool(): void {\n this.preprocessCanvas = document.createElement('canvas');\n this.preprocessCanvas.width = this.INPUT_SIZE;\n this.preprocessCanvas.height = this.INPUT_SIZE;\n this.preprocessCtx = this.preprocessCanvas.getContext('2d', {\n alpha: false,\n willReadFrequently: true\n })!;\n\n this.captureCanvas = document.createElement('canvas');\n\n }\n\n private cleanupCanvasPool(): void {\n if (this.preprocessCanvas) {\n this.preprocessCtx = undefined;\n this.preprocessCanvas = undefined;\n }\n if (this.captureCanvas) {\n this.captureCanvas = undefined;\n }\n }\n\n private detectFloat16Support(): void {\n try {\n // Verificar si el backend actual soporta float16 intentando crear un tensor pequeno\n const testData = new Uint16Array([0]);\n new (window as any).ort.Tensor(\"float16\", testData, [1]);\n this.useFloat16 = true;\n } catch {\n this.useFloat16 = false;\n }\n }\n\n private float32ToFloat16(value: number): number {\n const buffer = new ArrayBuffer(4);\n const view = new DataView(buffer);\n view.setFloat32(0, value, true);\n\n const f = view.getUint32(0, true);\n const sign = (f >> 31) & 0x1;\n const exp = (f >> 23) & 0xFF;\n const frac = f & 0x7FFFFF;\n\n let newExp = exp - 127 + 15;\n\n if (exp === 0) {\n newExp = 0;\n } else if (exp === 0xFF) {\n newExp = 0x1F;\n } else if (newExp >= 0x1F) {\n newExp = 0x1F;\n return (sign << 15) | (newExp << 10);\n } else if (newExp <= 0) {\n return (sign << 15);\n }\n\n return (sign << 15) | (newExp << 10) | (frac >> 13);\n }\n\n private preprocessMobileNet(canvas: HTMLCanvasElement): any {\n // Use pooled canvas instead of creating new one\n const tempCanvas = this.getCanvas(224, 224);\n const tempCtx = tempCanvas.getContext('2d')!;\n\n // Clear canvas before use\n tempCtx.clearRect(0, 0, 224, 224);\n \n // Resize image to 224x224 for SqueezeNet (using MobileNet interface)\n tempCtx.drawImage(canvas, 0, 0, 224, 224);\n\n const imageData = tempCtx.getImageData(0, 0, 224, 224);\n const data = imageData.data;\n const hw = 224 * 224;\n const arr = new Float32Array(3 * hw);\n\n // SqueezeNet preprocessing: normalize to [0,1] range and arrange in CHW format\n for (let i = 0; i < hw; i++) {\n // Red channel\n arr[i] = data[i * 4 + 0] / 255.0;\n // Green channel\n arr[hw + i] = data[i * 4 + 1] / 255.0;\n // Blue channel\n arr[2 * hw + i] = data[i * 4 + 2] / 255.0;\n }\n\n // Return canvas to pool after use\n this.returnCanvas(tempCanvas);\n\n return new (window as any).ort.Tensor('float32', arr, [1, 3, 224, 224]);\n }\n\n // Canvas pool management methods for optimization\n private getCanvas(width: number, height: number): HTMLCanvasElement {\n const key = `${width}x${height}`;\n if (!DetectionService.canvasPool.has(key)) {\n DetectionService.canvasPool.set(key, []);\n }\n const pool = DetectionService.canvasPool.get(key)!;\n \n let canvas = pool.pop();\n if (!canvas) {\n canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n } else {\n // Clear the canvas before reuse\n const ctx = canvas.getContext('2d')!;\n ctx.clearRect(0, 0, width, height);\n }\n \n return canvas;\n }\n\n private returnCanvas(canvas: HTMLCanvasElement): void {\n const key = `${canvas.width}x${canvas.height}`;\n if (!DetectionService.canvasPool.has(key)) {\n DetectionService.canvasPool.set(key, []);\n }\n const pool = DetectionService.canvasPool.get(key)!;\n \n // Only return to pool if not at max capacity\n if (pool.length < DetectionService.MAX_POOL_SIZE) {\n pool.push(canvas);\n }\n }\n\n // Static method to clear all canvas pools (useful for memory management)\n public static clearCanvasPools(): void {\n DetectionService.canvasPool.clear();\n }\n\n // Method to get pool statistics for debugging\n public getPoolStats(): { [key: string]: number } {\n const stats: { [key: string]: number } = {};\n DetectionService.canvasPool.forEach((pool, key) => {\n stats[key] = pool.length;\n });\n return stats;\n }\n\n}\n"]}
1
+ {"version":3,"file":"DetectionService.js","sourceRoot":"","sources":["../../src/services/DetectionService.ts"],"names":[],"mappings":"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","sourcesContent":["import { IDetectionService, DetectionBox, SideAlignment, ClassificationResult } from './interfaces/IDetectionService';\nimport { IDeviceStrategy } from './strategies/IDeviceStrategy';\nimport { DeviceStrategyFactory } from './factories/DeviceStrategyFactory';\n\nexport class DetectionService implements IDetectionService {\n private session?: any;\n private mobileNetSession?: any;\n private mobileNetClassMap?: any;\n private modelLoaded: boolean = false;\n private deviceStrategy: IDeviceStrategy;\n\n private readonly MODEL_PATH = \"https://static.jaak.ai/web/component/stamps/ddmyp-v2.onnx\";\n private readonly MODEL_PATH_FP32 = \"https://static.jaak.ai/web/component/stamps/ddmyp-v2-fp32.onnx\";\n private readonly MOBILENET_MODEL_PATH = \"https://static.jaak.ai/web/component/stamps/squeezenet_new_fp32.onnx\";\n private readonly MOBILENET_CLASSES_PATH = \"https://static.jaak.ai/web/component/stamps/cdmmp-v1.json\";\n private readonly INPUT_SIZE = 320;\n private readonly CONFIDENCE_THRESHOLD = 0.6;\n private useFloat16: boolean = true;\n\n // Hoisted views for float32->float16 bit-twiddling. A fresh ArrayBuffer\n // per call was costing ~614K allocations per frame.\n private readonly _f32View = new Float32Array(1);\n private readonly _u32View = new Uint32Array(this._f32View.buffer);\n\n // Pre-allocated tensor buffers reused across frames. Same shape every time\n // (3 * INPUT_SIZE * INPUT_SIZE), and runInference is awaited before the next\n // preprocess runs, so reuse is safe.\n private readonly _tensorF32 = new Float32Array(3 * 320 * 320);\n private readonly _tensorF16 = new Uint16Array(3 * 320 * 320);\n\n // Canvas pool for optimization\n private preprocessCanvas?: HTMLCanvasElement;\n private preprocessCtx?: CanvasRenderingContext2D;\n private captureCanvas?: HTMLCanvasElement;\n \n // Static canvas pool for reuse across instances\n private static canvasPool = new Map<string, HTMLCanvasElement[]>();\n private static readonly MAX_POOL_SIZE = 5;\n\n constructor(\n private debug: boolean = false,\n private useDocumentClassification: boolean = false,\n private useDocumentDetector: boolean = true\n ) {\n this.deviceStrategy = DeviceStrategyFactory.createStrategy();\n this.initializeCanvasPool();\n }\n\n async loadModel(): Promise<void> {\n if (this.modelLoaded || this.session) {\n return;\n }\n\n if (!this.useDocumentDetector) {\n // Skip loading the detection model but mark as \"loaded\" for compatibility\n this.modelLoaded = true;\n return;\n }\n\n try {\n\n const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);\n\n try {\n this.session = await (window as any).ort.InferenceSession.create(this.MODEL_PATH, sessionOptions);\n this.detectFloat16Support();\n } catch (error) {\n const errorMsg = error.message || '';\n const isMemoryError = errorMsg.includes('failed to allocate a buffer') ||\n errorMsg.includes('Out of memory') ||\n errorMsg.includes('RangeError: Out of memory') ||\n errorMsg.includes('no available backend found');\n const isFloat16Error = errorMsg.includes('unsupported data type') ||\n errorMsg.includes('FLOAT16') ||\n errorMsg.includes('float16');\n\n if (isFloat16Error) {\n this.useFloat16 = false;\n try {\n this.session = await (window as any).ort.InferenceSession.create(this.MODEL_PATH_FP32, sessionOptions);\n } catch (fp32Error) {\n // Intentar con opciones minimas de WASM\n const wasmOptions = {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'all',\n logSeverityLevel: this.debug ? 2 : 4,\n };\n this.session = await (window as any).ort.InferenceSession.create(this.MODEL_PATH_FP32, wasmOptions);\n }\n } else if (isMemoryError) {\n const fallbackOptions = {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'disabled',\n logSeverityLevel: 4,\n enableCpuMemArena: false,\n enableMemPattern: false,\n executionMode: 'sequential',\n interOpNumThreads: 1,\n intraOpNumThreads: 1,\n enableProfiling: false,\n sessionLogSeverityLevel: 4,\n sessionLogVerbosityLevel: 0,\n };\n\n this.useFloat16 = false;\n\n try {\n this.session = await (window as any).ort.InferenceSession.create(this.MODEL_PATH_FP32, fallbackOptions);\n } catch (fallbackError) {\n throw new Error(`no available backend found. ERR: [wasm] RangeError: Out of memory`);\n }\n } else {\n throw error;\n }\n }\n\n this.modelLoaded = true;\n } catch (error) {\n throw error;\n }\n }\n\n async loadClassificationModel(): Promise<void> {\n if (!this.useDocumentClassification) {\n return;\n }\n\n try {\n\n // Try to load class map (optional - SqueezeNet may not need it for basic classification)\n try {\n const classResponse = await fetch(this.MOBILENET_CLASSES_PATH);\n if (classResponse.ok) {\n this.mobileNetClassMap = await classResponse.json();\n }\n } catch (error) {\n // Create a basic class map for document types\n this.mobileNetClassMap = {\n \"0\": \"document\",\n \"1\": \"id_card\",\n \"2\": \"passport\",\n \"3\": \"license\",\n \"4\": \"other\"\n };\n }\n\n // Load model\n const sessionOptions = this.deviceStrategy.getSessionOptions(this.debug);\n try {\n this.mobileNetSession = await (window as any).ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, sessionOptions);\n } catch (error) {\n // Múltiples tipos de errores de memoria que pueden ocurrir\n const isMemoryError = error.message.includes('failed to allocate a buffer') ||\n error.message.includes('Out of memory') ||\n error.message.includes('RangeError: Out of memory') ||\n error.message.includes('no available backend found');\n \n if (isMemoryError) {\n const fallbackOptions = {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'disabled',\n logSeverityLevel: 4,\n enableCpuMemArena: false,\n enableMemPattern: false,\n executionMode: 'sequential',\n interOpNumThreads: 1,\n intraOpNumThreads: 1,\n // Configuraciones adicionales para dispositivos con poca memoria\n enableProfiling: false,\n sessionLogSeverityLevel: 4,\n sessionLogVerbosityLevel: 0,\n };\n \n try {\n this.mobileNetSession = await (window as any).ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, fallbackOptions);\n } catch (fallbackError) {\n throw new Error(`no available backend found. ERR: [wasm] RangeError: Out of memory`);\n }\n } else {\n throw error;\n }\n }\n\n } catch (error) {\n throw error;\n }\n }\n\n isModelLoaded(): boolean {\n if (!this.useDocumentDetector) {\n // If detector is disabled, consider it \"loaded\" for compatibility\n return this.modelLoaded;\n }\n return this.modelLoaded && !!this.session;\n }\n\n preprocess(video: HTMLVideoElement): any {\n if (!this.preprocessCanvas || !this.preprocessCtx) {\n this.initializeCanvasPool();\n }\n\n const SIZE = this.INPUT_SIZE;\n this.preprocessCtx!.clearRect(0, 0, SIZE, SIZE);\n this.preprocessCtx!.drawImage(video, 0, 0, SIZE, SIZE);\n\n const imageData = this.preprocessCtx!.getImageData(0, 0, SIZE, SIZE);\n const { data } = imageData;\n const pixels = SIZE * SIZE;\n const gOffset = pixels;\n const bOffset = pixels * 2;\n const inv255 = 1 / 255;\n\n if (this.useFloat16) {\n const out = this._tensorF16;\n for (let i = 0, p = 0; i < data.length; i += 4, p++) {\n out[p] = this.float32ToFloat16(data[i] * inv255);\n out[gOffset + p] = this.float32ToFloat16(data[i + 1] * inv255);\n out[bOffset + p] = this.float32ToFloat16(data[i + 2] * inv255);\n }\n return new (window as any).ort.Tensor(\"float16\", out, [1, 3, SIZE, SIZE]);\n }\n\n const out = this._tensorF32;\n for (let i = 0, p = 0; i < data.length; i += 4, p++) {\n out[p] = data[i] * inv255;\n out[gOffset + p] = data[i + 1] * inv255;\n out[bOffset + p] = data[i + 2] * inv255;\n }\n return new (window as any).ort.Tensor(\"float32\", out, [1, 3, SIZE, SIZE]);\n }\n\n async runInference(inputTensor: any): Promise<DetectionBox[]> {\n if (!this.useDocumentDetector) {\n // Return empty array when document detector is disabled\n return [];\n }\n\n if (!this.session) {\n throw new Error('Detection model not loaded');\n }\n\n const feeds = { [this.session.inputNames[0]]: inputTensor };\n const results = await this.session.run(feeds);\n const output = results[this.session.outputNames[0]].data;\n\n const detections: DetectionBox[] = [];\n for (let i = 0; i < output.length; i += 6) {\n const [x1, y1, x2, y2, score, classId] = output.slice(i, i + 6);\n if (score > this.CONFIDENCE_THRESHOLD) {\n detections.push({\n x: x1,\n y: y1,\n w: x2 - x1,\n h: y2 - y1,\n score,\n classId\n });\n }\n }\n\n return detections;\n }\n\n async classifyDocument(canvas: HTMLCanvasElement): Promise<ClassificationResult | null> {\n if (!this.mobileNetSession || !this.mobileNetClassMap) {\n return null;\n }\n\n try {\n\n const inputTensor = this.preprocessMobileNet(canvas);\n const feeds = { [this.mobileNetSession.inputNames[0]]: inputTensor };\n const results = await this.mobileNetSession.run(feeds);\n const output = results[Object.keys(results)[0]].data;\n\n const maxIdx = output.reduce((bestIdx: number, val: number, idx: number, arr: number[]) =>\n val > arr[bestIdx] ? idx : bestIdx, 0);\n const confidence = output[maxIdx];\n\n const className = this.mobileNetClassMap[maxIdx.toString()] || \"unknown\";\n\n\n return {\n class: className,\n confidence: confidence,\n classIndex: maxIdx\n };\n\n } catch (error) {\n return null;\n }\n }\n\n checkSideAlignment(box: DetectionBox, maskConfig: any): SideAlignment {\n const { INPUT_SIZE, ID1_ASPECT_RATIO, shouldMirrorVideo, alignmentTolerance, maskSize, videoRef } = maskConfig;\n\n if (!videoRef) {\n return { top: false, right: false, bottom: false, left: false };\n }\n\n // Get video dimensions to calculate actual mask boundaries in model space\n const videoWidth = videoRef.videoWidth;\n const videoHeight = videoRef.videoHeight;\n\n if (videoWidth === 0 || videoHeight === 0) {\n return { top: false, right: false, bottom: false, left: false };\n }\n\n // Calculate video aspect ratio\n const videoAspectRatio = videoWidth / videoHeight;\n\n // The model sees video stretched to 320x320, but we need to calculate where\n // the mask should be in this distorted space to match the visual mask\n\n // In the visual display, we calculate mask size based on the limiting dimension\n // We need to replicate this logic but account for the distortion in model space\n\n // Calculate the \"display\" dimensions (what the visual mask calculations use)\n const containerAspectRatio = 1; // Assume square container for simplicity\n let displayedVideoWidth, displayedVideoHeight;\n\n if (videoAspectRatio > containerAspectRatio) {\n // Video is wider - letterboxed in display\n displayedVideoWidth = INPUT_SIZE;\n displayedVideoHeight = INPUT_SIZE / videoAspectRatio;\n } else {\n // Video is taller - pillarboxed in display\n displayedVideoHeight = INPUT_SIZE;\n displayedVideoWidth = INPUT_SIZE * videoAspectRatio;\n }\n\n // Calculate mask dimensions using the same logic as updateMaskDimensions\n const maxWidthByHeight = displayedVideoHeight * ID1_ASPECT_RATIO;\n\n let visualMaskWidth, visualMaskHeight;\n const sizeRatio = maskSize / 100;\n\n if (maxWidthByHeight <= displayedVideoWidth) {\n // Video height is the limiting factor\n visualMaskHeight = displayedVideoHeight * sizeRatio;\n visualMaskWidth = visualMaskHeight * ID1_ASPECT_RATIO;\n } else {\n // Video width is the limiting factor\n visualMaskWidth = displayedVideoWidth * sizeRatio;\n visualMaskHeight = visualMaskWidth / ID1_ASPECT_RATIO;\n }\n\n // Now map these visual mask dimensions to the distorted model space\n // The model stretches video to 320x320, so we need to apply the inverse transformation\n const modelMaskWidth = visualMaskWidth * (INPUT_SIZE / displayedVideoWidth);\n const modelMaskHeight = visualMaskHeight * (INPUT_SIZE / displayedVideoHeight);\n\n // Calculate mask boundaries in model coordinate system (always centered in 320x320)\n const maskCenterX = INPUT_SIZE / 2;\n const maskCenterY = INPUT_SIZE / 2;\n const maskLeft = maskCenterX - (modelMaskWidth / 2);\n const maskRight = maskCenterX + (modelMaskWidth / 2);\n const maskTop = maskCenterY - (modelMaskHeight / 2);\n const maskBottom = maskCenterY + (modelMaskHeight / 2);\n\n // Obtener las coordenadas del documento detectado\n let docLeft = box.x;\n let docRight = box.x + box.w;\n const docTop = box.y;\n const docBottom = box.y + box.h;\n\n // Si el video está en modo mirror, invertir las coordenadas horizontales\n if (shouldMirrorVideo) {\n const originalDocLeft = docLeft;\n const originalDocRight = docRight;\n docLeft = INPUT_SIZE - originalDocRight;\n docRight = INPUT_SIZE - originalDocLeft;\n }\n\n // Tolerancia para considerar que un lado está alineado (en píxeles)\n const tolerance = alignmentTolerance;\n\n // Verificar alineación de esquinas más estricta\n // Una esquina está alineada solo si AMBOS bordes que la forman están alineados\n const topAligned = Math.abs(docTop - maskTop) <= tolerance;\n const rightAligned = Math.abs(docRight - maskRight) <= tolerance;\n const bottomAligned = Math.abs(docBottom - maskBottom) <= tolerance;\n const leftAligned = Math.abs(docLeft - maskLeft) <= tolerance;\n\n return {\n top: topAligned && leftAligned, // Esquina superior izquierda: borde top Y left alineados\n right: topAligned && rightAligned, // Esquina superior derecha: borde top Y right alineados\n bottom: bottomAligned && leftAligned, // Esquina inferior izquierda: borde bottom Y left alineados\n left: bottomAligned && rightAligned // Esquina inferior derecha: borde bottom Y right alineados\n };\n }\n\n isCardInFrame(box: DetectionBox): boolean {\n const cardCenterX = box.x + box.w / 2;\n const cardCenterY = box.y + box.h / 2;\n const frameCenterX = this.INPUT_SIZE / 2;\n const frameCenterY = this.INPUT_SIZE / 2;\n const toleranceX = 40;\n const toleranceY = 30;\n\n const isCentered = Math.abs(cardCenterX - frameCenterX) < toleranceX &&\n Math.abs(cardCenterY - frameCenterY) < toleranceY;\n const isGoodSize = box.w > 150 && box.w < 300 && box.h > 90 && box.h < 200;\n\n return isCentered && isGoodSize;\n }\n\n areAllSidesAligned(alignment: SideAlignment): boolean {\n return alignment.top && alignment.right && alignment.bottom && alignment.left;\n }\n\n cleanup(): void {\n this.cleanupCanvasPool();\n\n if (this.session) {\n this.session.release?.();\n this.session = undefined;\n }\n if (this.mobileNetSession) {\n this.mobileNetSession.release?.();\n this.mobileNetSession = undefined;\n }\n this.mobileNetClassMap = undefined;\n this.modelLoaded = false;\n\n }\n\n private initializeCanvasPool(): void {\n this.preprocessCanvas = document.createElement('canvas');\n this.preprocessCanvas.width = this.INPUT_SIZE;\n this.preprocessCanvas.height = this.INPUT_SIZE;\n this.preprocessCtx = this.preprocessCanvas.getContext('2d', {\n alpha: false,\n willReadFrequently: true\n })!;\n\n this.captureCanvas = document.createElement('canvas');\n\n }\n\n private cleanupCanvasPool(): void {\n if (this.preprocessCanvas) {\n this.preprocessCtx = undefined;\n this.preprocessCanvas = undefined;\n }\n if (this.captureCanvas) {\n this.captureCanvas = undefined;\n }\n }\n\n private detectFloat16Support(): void {\n try {\n // Verificar si el backend actual soporta float16 intentando crear un tensor pequeno\n const testData = new Uint16Array([0]);\n new (window as any).ort.Tensor(\"float16\", testData, [1]);\n this.useFloat16 = true;\n } catch {\n this.useFloat16 = false;\n }\n }\n\n private float32ToFloat16(value: number): number {\n this._f32View[0] = value;\n const f = this._u32View[0];\n const sign = (f >> 31) & 0x1;\n const exp = (f >> 23) & 0xFF;\n const frac = f & 0x7FFFFF;\n\n let newExp = exp - 127 + 15;\n\n if (exp === 0) {\n newExp = 0;\n } else if (exp === 0xFF) {\n newExp = 0x1F;\n } else if (newExp >= 0x1F) {\n newExp = 0x1F;\n return (sign << 15) | (newExp << 10);\n } else if (newExp <= 0) {\n return (sign << 15);\n }\n\n return (sign << 15) | (newExp << 10) | (frac >> 13);\n }\n\n private preprocessMobileNet(canvas: HTMLCanvasElement): any {\n // Use pooled canvas instead of creating new one\n const tempCanvas = this.getCanvas(224, 224);\n const tempCtx = tempCanvas.getContext('2d')!;\n\n // Clear canvas before use\n tempCtx.clearRect(0, 0, 224, 224);\n \n // Resize image to 224x224 for SqueezeNet (using MobileNet interface)\n tempCtx.drawImage(canvas, 0, 0, 224, 224);\n\n const imageData = tempCtx.getImageData(0, 0, 224, 224);\n const data = imageData.data;\n const hw = 224 * 224;\n const arr = new Float32Array(3 * hw);\n\n // SqueezeNet preprocessing: normalize to [0,1] range and arrange in CHW format\n for (let i = 0; i < hw; i++) {\n // Red channel\n arr[i] = data[i * 4 + 0] / 255.0;\n // Green channel\n arr[hw + i] = data[i * 4 + 1] / 255.0;\n // Blue channel\n arr[2 * hw + i] = data[i * 4 + 2] / 255.0;\n }\n\n // Return canvas to pool after use\n this.returnCanvas(tempCanvas);\n\n return new (window as any).ort.Tensor('float32', arr, [1, 3, 224, 224]);\n }\n\n // Canvas pool management methods for optimization\n private getCanvas(width: number, height: number): HTMLCanvasElement {\n const key = `${width}x${height}`;\n if (!DetectionService.canvasPool.has(key)) {\n DetectionService.canvasPool.set(key, []);\n }\n const pool = DetectionService.canvasPool.get(key)!;\n \n let canvas = pool.pop();\n if (!canvas) {\n canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n } else {\n // Clear the canvas before reuse\n const ctx = canvas.getContext('2d')!;\n ctx.clearRect(0, 0, width, height);\n }\n \n return canvas;\n }\n\n private returnCanvas(canvas: HTMLCanvasElement): void {\n const key = `${canvas.width}x${canvas.height}`;\n if (!DetectionService.canvasPool.has(key)) {\n DetectionService.canvasPool.set(key, []);\n }\n const pool = DetectionService.canvasPool.get(key)!;\n \n // Only return to pool if not at max capacity\n if (pool.length < DetectionService.MAX_POOL_SIZE) {\n pool.push(canvas);\n }\n }\n\n // Static method to clear all canvas pools (useful for memory management)\n public static clearCanvasPools(): void {\n DetectionService.canvasPool.clear();\n }\n\n // Method to get pool statistics for debugging\n public getPoolStats(): { [key: string]: number } {\n const stats: { [key: string]: number } = {};\n DetectionService.canvasPool.forEach((pool, key) => {\n stats[key] = pool.length;\n });\n return stats;\n }\n\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export function format(first, middle, last) {
2
+ return (first || '') + (middle ? ` ${middle}` : '') + (last ? ` ${last}` : '');
3
+ }
4
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,MAAM,CAAC,KAAc,EAAE,MAAe,EAAE,IAAa;IACnE,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACjF,CAAC","sourcesContent":["export function format(first?: string, middle?: string, last?: string): string {\n return (first || '') + (middle ? ` ${middle}` : '') + (last ? ` ${last}` : '');\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  const NAMESPACE = 'jaak-stamps-webcomponent';
2
- const BUILD = /* jaak-stamps-webcomponent */ { hydratedSelectorName: "hydrated", lazyLoad: false, updatable: true};
2
+ const BUILD = /* jaak-stamps-webcomponent */ { hydratedSelectorName: "hydrated", lazyLoad: false, updatable: true, watchCallback: false };
3
3
 
4
4
  /*
5
5
  Stencil Client Platform v4.36.3 | MIT Licensed | https://stenciljs.com
@@ -1006,18 +1006,6 @@ var setValue = (ref, propName, newVal, cmpMeta) => {
1006
1006
  if (didValueChange) {
1007
1007
  hostRef.$instanceValues$.set(propName, newVal);
1008
1008
  {
1009
- if (cmpMeta.$watchers$ && flags & 128 /* isWatchReady */) {
1010
- const watchMethods = cmpMeta.$watchers$[propName];
1011
- if (watchMethods) {
1012
- watchMethods.map((watchMethodName) => {
1013
- try {
1014
- instance[watchMethodName](newVal, oldVal, propName);
1015
- } catch (e) {
1016
- consoleError(e, elm);
1017
- }
1018
- });
1019
- }
1020
- }
1021
1009
  if ((flags & (2 /* hasRendered */ | 16 /* isQueuedForUpdate */)) === 2 /* hasRendered */) {
1022
1010
  if (instance.componentShouldUpdate) {
1023
1011
  if (instance.componentShouldUpdate(newVal, oldVal, propName) === false) {
@@ -1034,10 +1022,7 @@ var setValue = (ref, propName, newVal, cmpMeta) => {
1034
1022
  var proxyComponent = (Cstr, cmpMeta, flags) => {
1035
1023
  var _a, _b;
1036
1024
  const prototype = Cstr.prototype;
1037
- if (cmpMeta.$members$ || (cmpMeta.$watchers$ || Cstr.watchers)) {
1038
- if (Cstr.watchers && !cmpMeta.$watchers$) {
1039
- cmpMeta.$watchers$ = Cstr.watchers;
1040
- }
1025
+ if (cmpMeta.$members$ || BUILD.watchCallback) {
1041
1026
  const members = Object.entries((_a = cmpMeta.$members$) != null ? _a : {});
1042
1027
  members.map(([memberName, [memberFlags]]) => {
1043
1028
  if ((memberFlags & 31 /* Prop */ || memberFlags & 32 /* State */)) {
@@ -1226,9 +1211,6 @@ var proxyCustomElement = (Cstr, compactMeta) => {
1226
1211
  {
1227
1212
  cmpMeta.$members$ = compactMeta[2];
1228
1213
  }
1229
- {
1230
- cmpMeta.$watchers$ = Cstr.$watchers$;
1231
- }
1232
1214
  const originalConnectedCallback = Cstr.prototype.connectedCallback;
1233
1215
  const originalDisconnectedCallback = Cstr.prototype.disconnectedCallback;
1234
1216
  Object.assign(Cstr.prototype, {