@exige/web-scanner-sdk 0.2.27 → 0.2.29

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.
@@ -1,1484 +0,0 @@
1
- //#region src/sdk/errors.ts
2
- var e = class extends Error {
3
- code;
4
- constructor(e, t) {
5
- super(t), this.name = "ScannerError", this.code = e;
6
- }
7
- };
8
- function t() {
9
- return new e("canvas", "Canvas 2D is unavailable in this browser.");
10
- }
11
- //#endregion
12
- //#region src/sdk/license-codec.ts
13
- function n(e) {
14
- let t = e.replaceAll("-", "+").replaceAll("_", "/"), n = t + "=".repeat((4 - t.length % 4) % 4), r = atob(n), i = new Uint8Array(r.length);
15
- for (let e = 0; e < r.length; e += 1) i[e] = r.charCodeAt(e);
16
- return i;
17
- }
18
- //#endregion
19
- //#region src/sdk/license-public-key.ts
20
- var r = "uFpA_UXGk-1AjjG31cFP6cqXOQX0w2TnuR7Bl-msZ6I";
21
- //#endregion
22
- //#region src/sdk/license-runtime.ts
23
- function i() {
24
- return n(r);
25
- }
26
- //#endregion
27
- //#region src/sdk/license.ts
28
- var a = [
29
- "localhost",
30
- "127.0.0.1",
31
- "exige-scanner-sdk.vercel.app",
32
- "*.localhost",
33
- "*.exige.io",
34
- "*.ngrok.io",
35
- "*.ngrok.app",
36
- "*.ngrok.dev",
37
- "*.ngrok-free.app",
38
- "*.ngrok-free.dev"
39
- ], o = class extends Error {
40
- code;
41
- constructor(e, t) {
42
- super(t), this.name = "LicenseError", this.code = e;
43
- }
44
- }, s, c;
45
- function l(e) {
46
- return e.trim().toLowerCase().replace(/\.$/u, "");
47
- }
48
- function u() {
49
- let e = globalThis.location?.hostname;
50
- if (typeof e == "string") return l(e) || void 0;
51
- }
52
- function d() {
53
- return Math.floor(Date.now() / 1e3);
54
- }
55
- function f(e, t) {
56
- let n = l(t);
57
- if (n.startsWith("*.")) {
58
- let t = n.slice(2), r = t === "localhost";
59
- return !t.includes(".") && !r || t.startsWith(".") || t.includes("*") ? !1 : e === t || e.endsWith(`.${t}`);
60
- }
61
- return e === n;
62
- }
63
- function p(e) {
64
- let t = l(e);
65
- return !t || t.includes("*") ? !1 : a.some((e) => f(t, e));
66
- }
67
- function m(e) {
68
- return {
69
- customerId: "dev",
70
- domains: [e],
71
- exp: 4102444800,
72
- features: {
73
- scan: !0,
74
- ocr: !0,
75
- redaction: !0,
76
- vehicles: !0,
77
- torch: !0
78
- }
79
- };
80
- }
81
- function h(e) {
82
- return {
83
- customerId: e.customerId,
84
- domains: [...e.domains],
85
- exp: e.exp,
86
- features: { ...e.features }
87
- };
88
- }
89
- function g(e = "This license key is not a signed payload.") {
90
- return new o("malformed", e);
91
- }
92
- function _(e) {
93
- if (!e || typeof e != "object" || Array.isArray(e)) throw g();
94
- let t = e;
95
- if (typeof t.customerId != "string" || t.customerId.trim() === "" || t.customerId.length > 200) throw g("This license key is missing a customer id.");
96
- if (!Array.isArray(t.domains) || t.domains.some((e) => typeof e != "string")) throw g("This license key is missing a domain list.");
97
- if (typeof t.exp != "number" || !Number.isSafeInteger(t.exp) || t.exp <= 0) throw g("This license key is missing a Unix expiry.");
98
- if (!t.features || typeof t.features != "object" || Array.isArray(t.features)) throw g("This license key is missing feature flags.");
99
- let n = t.features, r = [...new Set(t.domains.map((e) => l(e)).filter(Boolean))].sort();
100
- return {
101
- customerId: t.customerId.trim(),
102
- domains: r,
103
- exp: t.exp,
104
- features: {
105
- scan: n.scan === !0,
106
- ocr: n.ocr === !0,
107
- redaction: n.redaction === !0,
108
- vehicles: n.vehicles === !0,
109
- torch: n.torch === !0
110
- }
111
- };
112
- }
113
- async function v(e, t) {
114
- let r = e.trim().split(".");
115
- if (r.length !== 2 || !r[0] || !r[1]) throw g();
116
- let i, a;
117
- try {
118
- i = n(r[0]), a = n(r[1]);
119
- } catch {
120
- throw g();
121
- }
122
- let s, c = !1;
123
- try {
124
- s = await crypto.subtle.importKey("raw", t.publicKey, { name: "Ed25519" }, !1, ["verify"]), c = await crypto.subtle.verify("Ed25519", s, a, i);
125
- } catch {
126
- c = !1;
127
- }
128
- if (!c) throw new o("invalid-signature", "This license key signature does not match the SDK public key.");
129
- let u;
130
- try {
131
- u = JSON.parse(new TextDecoder().decode(i));
132
- } catch {
133
- throw g();
134
- }
135
- let d = _(u);
136
- if (d.exp <= t.now) throw new o("expired", "This license key has expired.");
137
- let f = l(t.hostname);
138
- if (!f || !d.domains.includes(f)) throw new o("domain", `This license key is not valid for ${f || "this host"}.`);
139
- return d;
140
- }
141
- async function y(e) {
142
- let t = u();
143
- if (!t) throw new o("domain", "The license check requires a browser hostname.");
144
- let n = await v(e, {
145
- publicKey: i(),
146
- hostname: t,
147
- now: d()
148
- });
149
- return s = e.trim(), c = n, h(n);
150
- }
151
- function b() {
152
- let e = u();
153
- return c && e && c.domains.includes(e) && c.exp > d() ? h(c) : !s && e && p(e) ? h(m(e)) : null;
154
- }
155
- async function x(e) {
156
- let t = u();
157
- if (!t) throw new o("domain", "The license check requires a browser hostname.");
158
- if (!s) {
159
- if (p(t)) return h(m(t));
160
- throw new o("missing", "A license key is required. Call setLicenseKey() before using the scanner SDK.");
161
- }
162
- let n = await v(s, {
163
- publicKey: i(),
164
- hostname: t,
165
- now: d()
166
- });
167
- if (c = n, !n.features[e]) throw new o("feature", `This license key does not include the ${e} feature.`);
168
- return h(n);
169
- }
170
- //#endregion
171
- //#region src/sdk/model-download.ts
172
- var S = Symbol.for("exige.web-scanner-sdk.model-downloads");
173
- function C() {
174
- let e = globalThis;
175
- return e[S] || (e[S] = {
176
- active: /* @__PURE__ */ new Map(),
177
- listeners: /* @__PURE__ */ new Set(),
178
- cache: /* @__PURE__ */ new Map(),
179
- inflight: /* @__PURE__ */ new Map()
180
- }), e[S];
181
- }
182
- var w = C().active, T = C().listeners, E = C().cache, D = C().inflight;
183
- function ee(e) {
184
- let t = Number(e.headers.get("content-length"));
185
- return Number.isFinite(t) && t > 0 ? t : null;
186
- }
187
- function te() {
188
- if (w.size === 0) return {
189
- downloading: !1,
190
- loaded: 0,
191
- total: null
192
- };
193
- let e = 0, t = 0, n = !0;
194
- for (let r of w.values()) e += r.loaded, r.total == null ? n = !1 : t += r.total;
195
- return {
196
- downloading: !0,
197
- loaded: e,
198
- total: n ? t : null
199
- };
200
- }
201
- function O() {
202
- let e = te();
203
- for (let t of T) t(e);
204
- }
205
- function ne(e) {
206
- return e(te()), T.add(e), () => {
207
- T.delete(e);
208
- };
209
- }
210
- function k(e, t) {
211
- t.done ? w.delete(e) : w.set(e, {
212
- loaded: t.loaded,
213
- total: t.total
214
- }), O();
215
- }
216
- async function re(e, t) {
217
- let n = ee(e);
218
- if (!e.body) {
219
- let r = await e.arrayBuffer();
220
- return t?.({
221
- loaded: r.byteLength,
222
- total: n ?? r.byteLength
223
- }), r;
224
- }
225
- let r = e.body.getReader(), i = [], a = 0;
226
- for (;;) {
227
- let { done: e, value: o } = await r.read();
228
- if (e) break;
229
- o?.byteLength && (i.push(o), a += o.byteLength, t?.({
230
- loaded: a,
231
- total: n
232
- }));
233
- }
234
- let o = new Uint8Array(a), s = 0;
235
- for (let e of i) o.set(e, s), s += e.byteLength;
236
- return a === 0 && t?.({
237
- loaded: 0,
238
- total: n
239
- }), o.buffer;
240
- }
241
- async function ie(t, n) {
242
- let r = E.get(t);
243
- if (r) return r.slice(0);
244
- let i = D.get(t);
245
- if (i) return i.then((e) => e.slice(0));
246
- let a = (async () => {
247
- k(t, {
248
- loaded: 0,
249
- total: null
250
- });
251
- let r = await fetch(t, { cache: n?.cache });
252
- if (!r.ok) throw new e("model-http", `Model request failed with HTTP ${r.status}.`);
253
- return re(r, (e) => k(t, e));
254
- })();
255
- D.set(t, a);
256
- try {
257
- let e = await a;
258
- return E.set(t, e), e.slice(0);
259
- } finally {
260
- D.delete(t), w.has(t) && (w.delete(t), O());
261
- }
262
- }
263
- //#endregion
264
- //#region src/sdk/ort-runtime.ts
265
- var ae = new URL("./assets/ort-wasm-simd-threaded.jsep.wasm", import.meta.url), oe = new URL("./assets/ort-wasm-simd-threaded.jsep.mjs", import.meta.url);
266
- function se() {
267
- return {
268
- wasm: ae.href,
269
- mjs: oe.href
270
- };
271
- }
272
- function ce(e) {
273
- return typeof e == "string" ? e.trim() || se() : e?.wasm.trim() && e.mjs.trim() ? {
274
- wasm: e.wasm.trim(),
275
- mjs: e.mjs.trim()
276
- } : se();
277
- }
278
- //#endregion
279
- //#region src/sdk/image.ts
280
- function le(e, t, n) {
281
- let r = n ? Math.min(1, n / Math.max(e, t)) : 1;
282
- return {
283
- width: Math.max(1, Math.round(e * r)),
284
- height: Math.max(1, Math.round(t * r))
285
- };
286
- }
287
- async function ue(e) {
288
- let t = URL.createObjectURL(e);
289
- try {
290
- let e = new Image();
291
- return e.src = t, await e.decode(), e;
292
- } finally {
293
- URL.revokeObjectURL(t);
294
- }
295
- }
296
- async function A(e, n = {}) {
297
- if (e instanceof HTMLCanvasElement && n.cloneCanvas === !1 && !n.maxDimension) return e;
298
- let r = document.createElement("canvas"), i = r.getContext("2d", { willReadFrequently: !0 });
299
- if (!i) throw t();
300
- if (e instanceof Blob) {
301
- if ("createImageBitmap" in window) try {
302
- let t = await createImageBitmap(e), a = le(t.width, t.height, n.maxDimension);
303
- return r.width = a.width, r.height = a.height, i.drawImage(t, 0, 0, a.width, a.height), t.close(), r;
304
- } catch {}
305
- e = await ue(e);
306
- }
307
- let a = e instanceof HTMLImageElement ? e.naturalWidth : e.width, o = e instanceof HTMLImageElement ? e.naturalHeight : e.height;
308
- if (!a || !o) throw Error("The image has no readable dimensions.");
309
- let s = le(a, o, n.maxDimension);
310
- return r.width = s.width, r.height = s.height, i.drawImage(e, 0, 0, s.width, s.height), r;
311
- }
312
- function de(e, t = "image/png", n = .92) {
313
- return new Promise((r, i) => e.toBlob((e) => e ? r(e) : i(/* @__PURE__ */ Error("Could not encode the image.")), t, n));
314
- }
315
- function fe(e, t, n) {
316
- let r = Math.max(0, Math.min(t, e.x)), i = Math.max(0, Math.min(n, e.y));
317
- return {
318
- x: r,
319
- y: i,
320
- width: Math.max(0, Math.min(t - r, e.width)),
321
- height: Math.max(0, Math.min(n - i, e.height))
322
- };
323
- }
324
- //#endregion
325
- //#region src/sdk/scan.ts
326
- var pe = "https://exige-scanner-sdk.vercel.app/models/docaligner-lcnet100-f4117b78.onnx", me = 1280;
327
- function he(e, t, n) {
328
- if (n) return n;
329
- let r = Math.max(e, t), i = r / Math.max(1, Math.min(e, t)), a = ye() ? 560 : 900;
330
- return i >= 1.6 ? Math.min(r, Math.max(a, me)) : a;
331
- }
332
- function j(e) {
333
- return e?.trim() || "https://exige-scanner-sdk.vercel.app/models/docaligner-lcnet100-f4117b78.onnx";
334
- }
335
- var ge = 3, M, _e = 0, N = /* @__PURE__ */ new Map();
336
- function P(e, t) {
337
- return Math.hypot(e.x - t.x, e.y - t.y);
338
- }
339
- function F(e) {
340
- return {
341
- ...e,
342
- edges: {
343
- top: {
344
- start: e.topLeft,
345
- end: e.topRight
346
- },
347
- right: {
348
- start: e.topRight,
349
- end: e.bottomRight
350
- },
351
- bottom: {
352
- start: e.bottomRight,
353
- end: e.bottomLeft
354
- },
355
- left: {
356
- start: e.bottomLeft,
357
- end: e.topLeft
358
- }
359
- }
360
- };
361
- }
362
- function ve(e, t) {
363
- let n = (e) => ({
364
- x: e.x / t,
365
- y: e.y / t
366
- });
367
- return {
368
- topLeft: n(e.topLeft),
369
- topRight: n(e.topRight),
370
- bottomRight: n(e.bottomRight),
371
- bottomLeft: n(e.bottomLeft)
372
- };
373
- }
374
- function ye() {
375
- return typeof navigator > "u" ? !1 : navigator.maxTouchPoints > 0 || navigator.hardwareConcurrency <= 4 || typeof matchMedia == "function" && matchMedia("(pointer: coarse)").matches;
376
- }
377
- function be(t, n, r, i) {
378
- return new Promise((a, o) => {
379
- M || (M = new Worker(new URL("./assets/document-worker.js", import.meta.url), { type: "module" }), M.onmessage = (t) => {
380
- if (t.data.download?.url) {
381
- k(t.data.download.url, t.data.download);
382
- return;
383
- }
384
- let n = N.get(t.data.id);
385
- n && (N.delete(t.data.id), t.data.error ? n.reject(t.data.errorCode ? new e(t.data.errorCode, t.data.error) : Error(t.data.error)) : t.data.result ? n.resolve(t.data.result) : n.reject(/* @__PURE__ */ Error("The document worker returned no result.")));
386
- }, M.onerror = () => {
387
- let t = new e("worker", "The document worker could not start.");
388
- for (let e of N.values()) e.reject(t);
389
- N.clear(), M?.terminate(), M = void 0;
390
- });
391
- let s = ++_e;
392
- N.set(s, {
393
- resolve: a,
394
- reject: o
395
- });
396
- let c = t.slice().buffer;
397
- M.postMessage({
398
- id: s,
399
- pixels: c,
400
- width: n,
401
- height: r,
402
- modelUrl: j(i.modelUrl),
403
- heatmapThreshold: i.heatmapThreshold,
404
- cacheModel: i.cacheModel,
405
- ortWasmPaths: ce(i.ortWasmPaths)
406
- }, [c]);
407
- });
408
- }
409
- async function I(n, r) {
410
- let { width: i, height: a } = n, o = r.minDimension ?? 360;
411
- if (Math.min(i, a) < o) return {
412
- status: "low-quality",
413
- confidence: 0,
414
- message: `Use an image at least ${o}px on its shortest side.`,
415
- sourceWidth: i,
416
- sourceHeight: a
417
- };
418
- let s = he(i, a, r.maxAnalysisDimension), c = Math.min(1, s / Math.max(i, a)), l = document.createElement("canvas");
419
- l.width = Math.max(1, Math.round(i * c)), l.height = Math.max(1, Math.round(a * c));
420
- let u = l.getContext("2d", { willReadFrequently: !0 });
421
- if (!u) throw t();
422
- u.drawImage(n, 0, 0, l.width, l.height);
423
- let d = u.getImageData(0, 0, l.width, l.height).data, f;
424
- if (r.useWorker !== !1 && typeof Worker < "u") try {
425
- f = await be(d, l.width, l.height, r);
426
- } catch (t) {
427
- if (t instanceof e && (t.code === "worker" || t.code === "model-http")) throw t;
428
- f = {
429
- sharpness: 20,
430
- detector: "ml",
431
- modelStatus: "failed",
432
- modelError: t instanceof Error ? t.message : "Document worker failed."
433
- };
434
- }
435
- else f = {
436
- sharpness: 20,
437
- detector: "ml",
438
- modelStatus: "failed",
439
- modelError: "ML detection requires a Web Worker."
440
- };
441
- let { sharpness: p, candidate: m, detector: h, modelStatus: g, modelProvider: _, modelError: v, modelNote: y, inferenceMs: b } = f, x = {
442
- detector: h,
443
- modelStatus: g,
444
- modelProvider: _,
445
- modelError: v,
446
- modelNote: y,
447
- inferenceMs: b
448
- };
449
- if (p < ge) return {
450
- status: "low-quality",
451
- confidence: Math.min(.3, p / 18),
452
- message: "The image is too soft or dark to resolve four document edges.",
453
- sourceWidth: i,
454
- sourceHeight: a,
455
- ...x
456
- };
457
- if (!m) return {
458
- status: "no-document",
459
- confidence: 0,
460
- message: "No document corners found. Place all four edges on a contrasting surface.",
461
- sourceWidth: i,
462
- sourceHeight: a,
463
- ...x
464
- };
465
- let S = ve(m.corners, c), C = F(S), w = r.minConfidence ?? .58;
466
- return m.confidence < w ? {
467
- status: "low-confidence",
468
- quad: C,
469
- corners: S,
470
- confidence: m.confidence,
471
- message: "Four possible corners were found, but the geometry is not reliable enough to crop.",
472
- sourceWidth: i,
473
- sourceHeight: a,
474
- ...x
475
- } : {
476
- status: "success",
477
- quad: C,
478
- corners: S,
479
- confidence: m.confidence,
480
- message: "Four document edges detected.",
481
- sourceWidth: i,
482
- sourceHeight: a,
483
- ...x
484
- };
485
- }
486
- function xe(e, t) {
487
- let n = Math.max(1, Math.round(Math.max(P(e.topLeft, e.topRight), P(e.bottomLeft, e.bottomRight)))), r = Math.max(1, Math.round(Math.max(P(e.topLeft, e.bottomLeft), P(e.topRight, e.bottomRight)))), i = Math.min(1, t / Math.max(n, r));
488
- return {
489
- width: Math.max(1, Math.round(n * i)),
490
- height: Math.max(1, Math.round(r * i))
491
- };
492
- }
493
- function Se(e, t, n, r, i) {
494
- let a = Math.max(0, Math.min(t - 1, r)), o = Math.max(0, Math.min(n - 1, i)), s = Math.floor(a), c = Math.floor(o), l = Math.min(t - 1, s + 1), u = Math.min(n - 1, c + 1), d = a - s, f = o - c, p = c * t, m = u * t, h = (t) => {
495
- let n = e[(p + s) * 4 + t] * (1 - d) + e[(p + l) * 4 + t] * d, r = e[(m + s) * 4 + t] * (1 - d) + e[(m + l) * 4 + t] * d;
496
- return Math.round(n * (1 - f) + r * f);
497
- };
498
- return [
499
- h(0),
500
- h(1),
501
- h(2),
502
- 255
503
- ];
504
- }
505
- function L(e, n, r) {
506
- let { width: i, height: a } = xe(n, r), o = e.getContext("2d", { willReadFrequently: !0 });
507
- if (!o) throw t();
508
- let s = o.getImageData(0, 0, e.width, e.height), c = document.createElement("canvas");
509
- c.width = i, c.height = a;
510
- let l = c.getContext("2d");
511
- if (!l) throw t();
512
- let u = l.createImageData(i, a), { topLeft: d, topRight: f, bottomRight: p, bottomLeft: m } = n, h = f.x - p.x, g = m.x - p.x, _ = f.y - p.y, v = m.y - p.y, y = d.x - f.x + p.x - m.x, b = d.y - f.y + p.y - m.y, x = h * v - g * _, S = Math.abs(x) < 1e-4 ? 0 : (y * v - g * b) / x, C = Math.abs(x) < 1e-4 ? 0 : (h * b - y * _) / x, w = f.x - d.x + S * f.x, T = m.x - d.x + C * m.x, E = f.y - d.y + S * f.y, D = m.y - d.y + C * m.y;
513
- for (let t = 0; t < a; t += 1) {
514
- let n = t / Math.max(1, a - 1);
515
- for (let r = 0; r < i; r += 1) {
516
- let a = r / Math.max(1, i - 1), o = S * a + C * n + 1, c = (w * a + T * n + d.x) / o, l = (E * a + D * n + d.y) / o, [f, p, m, h] = Se(s.data, e.width, e.height, c, l), g = (t * i + r) * 4;
517
- u.data[g] = f, u.data[g + 1] = p, u.data[g + 2] = m, u.data[g + 3] = h;
518
- }
519
- }
520
- return l.putImageData(u, 0, 0), c;
521
- }
522
- async function R(e, t = {}) {
523
- return await x("scan"), I(await A(e, { cloneCanvas: !1 }), t);
524
- }
525
- async function Ce(e, t, n = {}) {
526
- await x("scan");
527
- let r = await A(e, { cloneCanvas: !1 }), i = n.maxOutputDimension ?? 4096;
528
- return {
529
- status: "success",
530
- corners: t,
531
- quad: F(t),
532
- confidence: 1,
533
- message: "Captured with the document edges shown in the finder.",
534
- sourceWidth: r.width,
535
- sourceHeight: r.height,
536
- canvas: L(r, t, i)
537
- };
538
- }
539
- async function z(e, t = {}) {
540
- await x("scan");
541
- let n = await A(e, { cloneCanvas: !1 }), r = await I(n, t);
542
- if (r.status !== "success" || !r.corners) return r;
543
- let i = t.maxOutputDimension ?? 4096;
544
- return {
545
- ...r,
546
- canvas: L(n, r.corners, i),
547
- message: "Four document edges detected and perspective-corrected."
548
- };
549
- }
550
- function B(e) {
551
- return e.status === "success" ? e.message : e.status === "low-quality" ? e.message.includes("shortest side") ? `${e.message} Take another photo.` : "That photo is too soft or dark to find a document. Take another photo in better light." : e.status === "low-confidence" ? "The page edges were not clear enough to crop. Take another photo with the whole page in frame." : `No document was found in that photo. Take another photo with the whole page in frame.${e.modelStatus === "failed" && e.modelError ? ` (${e.modelError})` : ""}`;
552
- }
553
- async function we(e, t = {}) {
554
- let n = await z(e, t);
555
- return n.status === "success" ? n : {
556
- ...n,
557
- message: B(n)
558
- };
559
- }
560
- //#endregion
561
- //#region src/sdk/camera.ts
562
- function V(e, t) {
563
- let { engine: n } = t;
564
- return [
565
- `${e}:`,
566
- ` engine: ${n.engine}/${n.browser}${n.iosWebKit ? " ios-webkit" : ""}`,
567
- ` ua: ${n.userAgent}`,
568
- ` video: ${t.videoWidth}x${t.videoHeight} readyState=${t.readyState}${t.paused ? " paused" : ""}${t.rendered ? "" : " hidden"}${t.connected ? "" : " disconnected"}`,
569
- ` track: ${t.trackReadyState}${t.trackEnabled ? "" : " disabled"}${t.trackMuted ? " muted" : ""}`,
570
- ` liveLuma: ${t.liveLuminance.toFixed(1)}`,
571
- ` mirrorLuma: ${t.mirrorLuminance.toFixed(1)}`,
572
- ` mirrorAgeMs: ${Number.isFinite(t.mirrorAgeMs) ? Math.round(t.mirrorAgeMs) : "none"}`,
573
- ` hasImageCapture: ${t.hasImageCapture}${t.engine.iosWebKit ? " (skipped on webkit)" : " (still capture)"}`,
574
- ` torch: ${t.torch.mode} supported=${t.torch.supported} on=${t.torch.on}`
575
- ].join("\n");
576
- }
577
- function Te(e) {
578
- let t = ["Exige scanner capture report", `time: ${e.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString()}`];
579
- if (e.error && t.push(`error: ${e.error}`), e.captureMethod && t.push(`method: ${e.captureMethod}`), e.luminance !== void 0 && t.push(`luminance: ${e.luminance.toFixed(1)}`), e.fallbackReason && t.push(`fallback: ${e.fallbackReason}`), e.shutter && t.push(V("shutter", e.shutter)), e.live && t.push(V("live", e.live)), e.finder) {
580
- let n = e.finder;
581
- t.push([
582
- "finder:",
583
- ` state: ${n.state ?? "unknown"}`,
584
- ` confidence: ${n.confidence === void 0 ? "—" : n.confidence.toFixed(3)}`,
585
- ` stable: ${n.stableFrames ?? "—"}/${n.requiredStableFrames ?? "—"}`,
586
- ` detector: ${n.detector ?? "—"} ${n.modelStatus ?? ""}`.trim(),
587
- ` modelError: ${n.modelError ?? "—"}`,
588
- ` provider: ${n.modelProvider ?? "—"}`,
589
- ` note: ${n.modelNote ?? "—"}`,
590
- ` inferenceMs: ${n.inferenceMs === void 0 ? "—" : Math.round(n.inferenceMs)}`,
591
- ` source: ${n.sourceWidth ?? "—"}x${n.sourceHeight ?? "—"}`
592
- ].join("\n"));
593
- }
594
- return `${t.join("\n")}\n`;
595
- }
596
- function H(e = typeof navigator > "u" ? "" : navigator.userAgent, t = typeof navigator > "u" ? 0 : navigator.maxTouchPoints) {
597
- let n = /CriOS|Chrome/i.test(e) ? "chrome" : /EdgiOS|Edg/i.test(e) ? "edge" : /FxiOS|Firefox/i.test(e) ? "firefox" : /Safari/i.test(e) ? "safari" : "unknown", r = /iPhone|iPad|iPod/i.test(e) || /Macintosh/i.test(e) && t > 1, i = /CriOS|EdgiOS|FxiOS|OPiOS|Mercury/i.test(e), a = r || i;
598
- return {
599
- engine: a || /AppleWebKit/i.test(e) && !/Chrome|Chromium|Edg/i.test(e) ? "webkit" : /Chrome|Chromium|Edg/i.test(e) ? "blink" : /Gecko\//i.test(e) ? "gecko" : "unknown",
600
- browser: n,
601
- iosWebKit: a,
602
- userAgent: e
603
- };
604
- }
605
- function U(e) {
606
- return /Android/i.test(e.userAgent) && !e.iosWebKit;
607
- }
608
- function Ee(e = "auto", t = H()) {
609
- return e === "system-camera" || e !== "live" && U(t);
610
- }
611
- function De(e, t) {
612
- return t && !e.iosWebKit;
613
- }
614
- function W(e, t) {
615
- if (!e || !Number.isFinite(e)) return;
616
- let n = t?.max;
617
- if (!n || !Number.isFinite(n)) return Math.round(e);
618
- let r = t?.min && Number.isFinite(t.min) ? t.min : 1, i = t?.step && t.step > 0 ? t.step : 1, a = r + Math.round((Math.min(n, Math.max(r, e)) - r) / i) * i;
619
- return Math.round(Math.min(n, Math.max(r, a)));
620
- }
621
- function Oe(e) {
622
- let t = W(e?.imageWidth?.max ?? 0, e?.imageWidth), n = W(e?.imageHeight?.max ?? 0, e?.imageHeight);
623
- if (t && n) return t >= n ? { imageWidth: t } : { imageHeight: n };
624
- if (t) return { imageWidth: t };
625
- if (n) return { imageHeight: n };
626
- }
627
- function ke(e, t) {
628
- return !e.width || !e.height || !t.width || !t.height ? !1 : e.width * e.height > t.width * t.height * 1.15;
629
- }
630
- function Ae(e, t) {
631
- if (!e.width || !e.height || !t.width || !t.height) return !1;
632
- let n = e.width / e.height / (t.width / t.height);
633
- return n > .97 && n < 1.03;
634
- }
635
- var je = 10, G = class {
636
- on = !1;
637
- darkCount = 0;
638
- brightCount = 0;
639
- turnOnLuminance;
640
- turnOffLuminance;
641
- darkSamples;
642
- brightSamples;
643
- constructor(e = {}) {
644
- this.turnOnLuminance = e.turnOnLuminance ?? 62, this.turnOffLuminance = e.turnOffLuminance ?? 155, this.darkSamples = e.darkSamples ?? 3, this.brightSamples = e.brightSamples ?? 8;
645
- }
646
- update(e) {
647
- if (!Number.isFinite(e) || e <= 10) {
648
- this.darkCount = 0, this.brightCount = 0;
649
- return;
650
- }
651
- if (!this.on) return this.brightCount = 0, this.darkCount = e <= this.turnOnLuminance ? this.darkCount + 1 : 0, this.darkCount < this.darkSamples ? void 0 : (this.darkCount = 0, this.on = !0, !0);
652
- if (this.darkCount = 0, this.brightCount = e >= this.turnOffLuminance ? this.brightCount + 1 : 0, !(this.brightCount < this.brightSamples)) return this.brightCount = 0, this.on = !1, !1;
653
- }
654
- getState() {
655
- return this.on;
656
- }
657
- };
658
- function K(e, t) {
659
- return t ? e === "alwaysOn" || e === "alwaysOff" ? {
660
- mode: e,
661
- supported: !0,
662
- on: e === "alwaysOn",
663
- visible: !1,
664
- mutable: !1,
665
- automatic: !1
666
- } : {
667
- mode: e,
668
- supported: !0,
669
- on: e === "defaultOn",
670
- visible: !0,
671
- mutable: e !== "auto",
672
- automatic: e === "auto"
673
- } : {
674
- mode: e,
675
- supported: !1,
676
- on: !1,
677
- visible: !1,
678
- mutable: !1,
679
- automatic: e === "auto"
680
- };
681
- }
682
- function q(e) {
683
- let t = Math.floor(e.length / 4);
684
- if (!t) return 0;
685
- let n = 0;
686
- for (let r = 0; r < t * 4; r += 4) n += e[r] * .299 + e[r + 1] * .587 + e[r + 2] * .114;
687
- return n / t;
688
- }
689
- function Me(e, t = 10) {
690
- if (e.length < 4) return !0;
691
- let n = Math.floor(e.length / 4), r = 0;
692
- for (let i = 0; i < n * 4; i += 4) e[i] * .299 + e[i + 1] * .587 + e[i + 2] * .114 > t * 2 && (r += 1);
693
- return q(e) <= t && r / n < .01;
694
- }
695
- function Ne(e, t, n) {
696
- if (!t || !n) return 0;
697
- let r = document.createElement("canvas");
698
- r.width = Math.min(32, t), r.height = Math.min(32, n);
699
- let i = r.getContext("2d", { willReadFrequently: !0 });
700
- return i ? (i.drawImage(e, 0, 0, r.width, r.height), q(i.getImageData(0, 0, r.width, r.height).data)) : 0;
701
- }
702
- function Pe(e) {
703
- return Ne(e, e.width, e.height);
704
- }
705
- function Fe(e, t = 120) {
706
- let n = document.createElement("canvas"), r = n.getContext("2d"), i = typeof e.requestVideoFrameCallback == "function", a = !0, o = 0, s = 0, c = 0, l = 0, u = 0, d = () => {
707
- a && (o = i ? e.requestVideoFrameCallback(f) : requestAnimationFrame(f));
708
- };
709
- function f() {
710
- if (!a) return;
711
- let { videoWidth: i, videoHeight: o } = e, f = performance.now();
712
- r && i && o && f - s >= t && (s = f, l = Ne(e, i, o), l > 10 && ((n.width !== i || n.height !== o) && (n.width = i, n.height = o), r.drawImage(e, 0, 0, i, o), u = l, c = f)), d();
713
- }
714
- return d(), {
715
- stop() {
716
- a = !1, i ? e.cancelVideoFrameCallback?.(o) : cancelAnimationFrame(o);
717
- },
718
- getFrame: () => c ? n : void 0,
719
- getLiveLuminance: () => l,
720
- getMirrorLuminance: () => u,
721
- getMirrorAgeMs: () => c ? performance.now() - c : Infinity
722
- };
723
- }
724
- function Ie(e) {
725
- let t = document.createElement("canvas");
726
- return t.width = e.width, t.height = e.height, t.getContext("2d")?.drawImage(e, 0, 0), t;
727
- }
728
- function Le(e) {
729
- return e.engine === "blink";
730
- }
731
- function J(e = {}, t = H()) {
732
- let n = { ideal: e.idealWidth ?? 3840 }, r = { ideal: e.idealHeight ?? 2160 };
733
- e.maxWidth && (n.max = e.maxWidth), e.maxHeight && (r.max = e.maxHeight);
734
- let i = {
735
- facingMode: { ideal: e.facingMode ?? "environment" },
736
- width: n,
737
- height: r,
738
- frameRate: {
739
- ideal: e.maxFrameRate ?? 30,
740
- max: e.maxFrameRate ?? 30
741
- }
742
- };
743
- return Le(t) && (i.resizeMode = { ideal: "none" }), {
744
- audio: !1,
745
- video: i
746
- };
747
- }
748
- function Re(e, t, n) {
749
- let r = n ? Math.min(1, n / Math.max(e, t)) : 1;
750
- return {
751
- width: Math.max(1, Math.round(e * r)),
752
- height: Math.max(1, Math.round(t * r))
753
- };
754
- }
755
- var ze = 4096;
756
- function Be(e, t) {
757
- let n = e.width, r = e.height, i = t?.width?.max, a = t?.height?.max;
758
- if (!n || !r || !i || !a) return;
759
- let o = Math.min(i / n, a / r);
760
- if (!(o <= 1.05)) return {
761
- width: { ideal: Math.round(n * o) },
762
- height: { ideal: Math.round(r * o) }
763
- };
764
- }
765
- async function Ve(e) {
766
- let t = Be(e.getSettings(), typeof e.getCapabilities == "function" ? e.getCapabilities() : void 0);
767
- if (t) try {
768
- await e.applyConstraints(t);
769
- } catch {}
770
- }
771
- async function He(e) {
772
- try {
773
- return await createImageBitmap(e, {
774
- imageOrientation: "from-image",
775
- colorSpaceConversion: "none"
776
- });
777
- } catch {
778
- return await createImageBitmap(e);
779
- }
780
- }
781
- async function Ue(e) {
782
- try {
783
- await e.applyConstraints({ advanced: [{ pointsOfInterest: [{
784
- x: .5,
785
- y: .5
786
- }] }] }), await new Promise((e) => window.setTimeout(e, 180));
787
- } catch {}
788
- }
789
- async function We(e) {
790
- let n = await He(e), r = Re(n.width, n.height, ze), i = document.createElement("canvas");
791
- i.width = r.width, i.height = r.height;
792
- let a = i.getContext("2d");
793
- if (!a) throw n.close?.(), t();
794
- return a.imageSmoothingEnabled = r.width !== n.width || r.height !== n.height, a.imageSmoothingQuality = "high", a.drawImage(n, 0, 0, i.width, i.height), n.close?.(), i;
795
- }
796
- async function Ge(e) {
797
- let t = globalThis.ImageCapture;
798
- if (!t) return;
799
- await Ue(e);
800
- let n = new t(e), r = n.getPhotoCapabilities ? await n.getPhotoCapabilities() : void 0, i = Oe(r), a;
801
- try {
802
- a = await n.takePhoto(i);
803
- } catch {
804
- a = await n.takePhoto();
805
- }
806
- return {
807
- frame: await We(a),
808
- requested: i,
809
- photoMax: {
810
- width: r?.imageWidth?.max,
811
- height: r?.imageHeight?.max
812
- }
813
- };
814
- }
815
- function Y(e, n) {
816
- if (!e.videoWidth || !e.videoHeight) throw Error("The camera is not ready to capture a frame.");
817
- let r = Re(e.videoWidth, e.videoHeight, n), i = document.createElement("canvas");
818
- i.width = r.width, i.height = r.height;
819
- let a = i.getContext("2d");
820
- if (!a) throw t();
821
- return a.drawImage(e, 0, 0, i.width, i.height), i;
822
- }
823
- function Ke(e) {
824
- let t = H();
825
- return e.idealWidth || e.idealHeight || e.maxWidth || e.maxHeight ? [J(e, t)] : [
826
- J({
827
- ...e,
828
- idealWidth: 3840,
829
- idealHeight: 2160
830
- }, t),
831
- J({
832
- ...e,
833
- idealWidth: 2560,
834
- idealHeight: 1440
835
- }, t),
836
- J({
837
- ...e,
838
- idealWidth: 1920,
839
- idealHeight: 1080
840
- }, t)
841
- ];
842
- }
843
- async function qe(t, n = {}) {
844
- await x("scan");
845
- let r = n.torch ?? "alwaysOff";
846
- if (r !== "alwaysOff" && await x("torch"), !window.isSecureContext && location.hostname !== "localhost") throw new e("secure-context", "Camera access requires HTTPS.");
847
- if (!navigator.mediaDevices?.getUserMedia) throw Error("Live camera access is unavailable. Use the native camera picker instead.");
848
- t.muted = !0, t.autoplay = !0, t.playsInline = !0, t.setAttribute("playsinline", "");
849
- let i, a;
850
- for (let e of Ke(n)) try {
851
- i = await navigator.mediaDevices.getUserMedia(e);
852
- break;
853
- } catch (e) {
854
- if (a = e, !(e instanceof DOMException) || e.name !== "OverconstrainedError") throw e;
855
- }
856
- if (!i) throw a ?? /* @__PURE__ */ Error("No rear camera resolution is available.");
857
- t.srcObject = i, await t.play();
858
- let o = i.getVideoTracks()[0];
859
- if (!o) {
860
- for (let e of i.getTracks()) e.stop();
861
- throw Error("The camera did not provide a video track.");
862
- }
863
- await Ve(o);
864
- let s = Fe(t), c = "ImageCapture" in globalThis, l = K(r, (typeof o.getCapabilities == "function" ? o.getCapabilities() : void 0)?.torch === !0), u = !1, d = async (e) => {
865
- if (!l.supported || o.readyState !== "live") return !1;
866
- try {
867
- return await o.applyConstraints({ advanced: [{ torch: e }] }), l = {
868
- ...l,
869
- on: e
870
- }, !0;
871
- } catch {
872
- return l = {
873
- ...l,
874
- supported: !1,
875
- on: !1,
876
- visible: !1,
877
- mutable: !1
878
- }, !1;
879
- }
880
- };
881
- l.on && await d(!0);
882
- let f = r === "auto" && l.supported ? new G() : void 0, p = f ? window.setInterval(() => {
883
- if (u || !l.supported) return;
884
- let e = f.update(s.getLiveLuminance());
885
- e !== void 0 && e !== l.on && (u = !0, d(e).finally(() => {
886
- u = !1;
887
- }));
888
- }, 350) : 0, m = () => {
889
- let e = t.getBoundingClientRect();
890
- return {
891
- videoWidth: t.videoWidth,
892
- videoHeight: t.videoHeight,
893
- readyState: t.readyState,
894
- paused: t.paused,
895
- connected: t.isConnected,
896
- rendered: e.width > 0 && e.height > 0,
897
- trackReadyState: o.readyState ?? "missing",
898
- trackEnabled: o.enabled,
899
- trackMuted: o.muted,
900
- liveLuminance: s.getLiveLuminance(),
901
- mirrorLuminance: s.getMirrorLuminance(),
902
- mirrorAgeMs: s.getMirrorAgeMs(),
903
- hasImageCapture: c,
904
- torchMode: l.mode,
905
- torchSupported: l.supported,
906
- torchOn: l.on,
907
- torch: { ...l },
908
- engine: H()
909
- };
910
- };
911
- return {
912
- stream: i,
913
- get torchMode() {
914
- return l.mode;
915
- },
916
- get torchSupported() {
917
- return l.supported;
918
- },
919
- get torchOn() {
920
- return l.on;
921
- },
922
- capture: (e) => Y(t, e),
923
- async capturePhoto() {
924
- let e, n = 0;
925
- try {
926
- e = Y(t), n = Pe(e);
927
- } catch {
928
- e = void 0;
929
- }
930
- let r = s.getFrame(), i, a = !1, l = !1, u, d;
931
- if (De(H(), c)) try {
932
- let e = await Ge(o);
933
- i = e?.frame, u = e?.requested, d = e?.photoMax;
934
- } catch {
935
- a = !0, i = void 0;
936
- }
937
- let f = {
938
- width: t.videoWidth,
939
- height: t.videoHeight
940
- }, p = i ? Pe(i) : 0, h = !!(i && p > 10 && ke(i, f));
941
- if (i && p > 10 && !h && (l = !0), h && i) return console.info("[exige-scanner] capture", {
942
- method: "image-capture",
943
- frame: `${i.width}×${i.height}`,
944
- video: `${t.videoWidth}×${t.videoHeight}`,
945
- photoMax: d ? `${d.width ?? "—"}×${d.height ?? "—"}` : void 0,
946
- photoRequest: u,
947
- aspectMatch: Ae(i, f)
948
- }), {
949
- frame: i,
950
- method: "image-capture",
951
- settings: o.getSettings(),
952
- luminance: p,
953
- diagnostics: m()
954
- };
955
- let g = e && n > 10 ? e : void 0, _ = g ?? (r ? Ie(r) : void 0);
956
- if (!_) throw Error("The camera preview produced no visible pixels. Keep the scanner on screen, wait for the preview, and retake.");
957
- let v = l ? "image-capture-preview-size" : i ? "image-capture-empty" : a ? "image-capture-failed" : g ? void 0 : "video-frame-empty";
958
- return console.info("[exige-scanner] capture", {
959
- method: g ? "video-frame" : "live-mirror",
960
- frame: `${_.width}×${_.height}`,
961
- video: `${t.videoWidth}×${t.videoHeight}`,
962
- photoMax: d ? `${d.width ?? "—"}×${d.height ?? "—"}` : void 0,
963
- photoRequest: u,
964
- fallbackReason: v
965
- }), {
966
- frame: _,
967
- method: g ? "video-frame" : "live-mirror",
968
- settings: o.getSettings(),
969
- fallbackReason: v,
970
- luminance: g ? n : s.getMirrorLuminance(),
971
- diagnostics: m()
972
- };
973
- },
974
- getSettings: () => o.getSettings(),
975
- getDiagnostics: m,
976
- getTorchStatus: () => ({ ...l }),
977
- async setTorch(e) {
978
- return l.mutable ? d(e) : !1;
979
- },
980
- stop() {
981
- p && window.clearInterval(p), s.stop();
982
- for (let e of i.getTracks()) e.stop();
983
- t.srcObject === i && (t.srcObject = null);
984
- }
985
- };
986
- }
987
- function Je() {
988
- let e = typeof navigator > "u" ? void 0 : navigator.userActivation;
989
- return !e || e.isActive;
990
- }
991
- async function Ye() {
992
- let e = document.createElement("input");
993
- return e.type = "file", e.accept = "image/*", e.capture = "environment", e.setAttribute("capture", "environment"), We(await new Promise((t, n) => {
994
- e.addEventListener("change", () => {
995
- let r = e.files?.[0];
996
- r ? t(r) : n(/* @__PURE__ */ Error("No photo was selected."));
997
- }, { once: !0 }), e.addEventListener("cancel", () => {
998
- n(/* @__PURE__ */ Error("No photo was selected."));
999
- }, { once: !0 }), e.click();
1000
- }));
1001
- }
1002
- //#endregion
1003
- //#region src/sdk/lighting.ts
1004
- function Xe(e, t) {
1005
- if (!e.length) return 0;
1006
- let n = [...e].sort((e, t) => e - t);
1007
- return n[Math.min(n.length - 1, Math.floor(n.length * t))];
1008
- }
1009
- function Ze(e, t, n, r = 12) {
1010
- if (!t || !n || e.length < t * n) return {
1011
- strong: !1,
1012
- strength: 0,
1013
- darkness: 0,
1014
- areaRatio: 0
1015
- };
1016
- let i = Math.min(r, t), a = Math.min(r, n), o = [];
1017
- for (let r = 0; r < a; r += 1) {
1018
- let s = Math.floor(r * n / a), c = Math.max(s + 1, Math.floor((r + 1) * n / a));
1019
- for (let n = 0; n < i; n += 1) {
1020
- let r = Math.floor(n * t / i), a = Math.max(r + 1, Math.floor((n + 1) * t / i)), l = 0, u = 0, d = 0;
1021
- for (let n = s; n < c; n += 1) for (let i = r; i < a; i += 1) {
1022
- let r = e[n * t + i];
1023
- l += r, u += r * r, d += 1;
1024
- }
1025
- let f = l / d;
1026
- o.push({
1027
- mean: f,
1028
- deviation: Math.sqrt(Math.max(0, u / d - f * f))
1029
- });
1030
- }
1031
- }
1032
- let s = Xe(o.map((e) => e.mean), .8), c = o.map((e) => s - e.mean >= 24 && e.mean >= 35), l = new Uint8Array(o.length), u = [];
1033
- for (let e = 0; e < o.length; e += 1) {
1034
- if (!c[e] || l[e]) continue;
1035
- let t = [], n = [e];
1036
- for (l[e] = 1; n.length;) {
1037
- let e = n.shift();
1038
- t.push(e);
1039
- let r = Math.floor(e / i), o = e % i;
1040
- for (let [e, t] of [
1041
- [o - 1, r],
1042
- [o + 1, r],
1043
- [o, r - 1],
1044
- [o, r + 1]
1045
- ]) {
1046
- if (e < 0 || e >= i || t < 0 || t >= a) continue;
1047
- let r = t * i + e;
1048
- c[r] && !l[r] && (l[r] = 1, n.push(r));
1049
- }
1050
- }
1051
- u.push(t);
1052
- }
1053
- let d = {
1054
- strong: !1,
1055
- strength: 0,
1056
- darkness: 0,
1057
- areaRatio: 0
1058
- };
1059
- for (let e of u) {
1060
- let t = e.length / o.length;
1061
- if (t < .06 || t > .75) continue;
1062
- let n = e.reduce((e, t) => e + s - o[t].mean, 0) / e.length, r = e.filter((e) => o[e].deviation >= 9).length / e.length;
1063
- if (r < .08 && n < 42) continue;
1064
- let c = e.map((e) => e % i), l = e.map((e) => Math.floor(e / i)), u = Math.min(...c), f = Math.max(...c), p = Math.min(...l), m = Math.max(...l), h = Math.max(0, u - 1) / i, g = Math.max(0, p - 1) / a, _ = Math.min(i, f + 1 + 1) / i, v = Math.min(a, m + 1 + 1) / a, y = n * Math.sqrt(t) * (.75 + Math.min(.25, r));
1065
- y > d.strength && (d = {
1066
- strong: y >= 10,
1067
- strength: y,
1068
- darkness: n,
1069
- areaRatio: t,
1070
- region: {
1071
- x: h,
1072
- y: g,
1073
- width: _ - h,
1074
- height: v - g
1075
- }
1076
- });
1077
- }
1078
- return d;
1079
- }
1080
- function Qe(e, t, n, r, i, a, o) {
1081
- let s = Math.max(0, a - o), c = Math.min(r, a + o + 1), l = Math.max(0, i - o), u = Math.min(n, i + o + 1), d = Math.max(1, (u - l) * (c - s));
1082
- return (e[c * t + u] - e[s * t + u] - e[c * t + l] + e[s * t + l]) / d;
1083
- }
1084
- function $e(e, t, n) {
1085
- let r = t + 1, i = new Uint32Array((t + 1) * (n + 1));
1086
- for (let a = 1; a <= n; a += 1) {
1087
- let n = 0;
1088
- for (let o = 1; o <= t; o += 1) n += e[(a - 1) * t + o - 1], i[a * r + o] = i[(a - 1) * r + o] + n;
1089
- }
1090
- return {
1091
- integral: i,
1092
- stride: r
1093
- };
1094
- }
1095
- function et(e, t, n, r = Math.max(12, Math.round(Math.max(t, n) / 32))) {
1096
- let { integral: i, stride: a } = $e(e, t, n), o = new Uint8Array(e.length);
1097
- for (let s = 0; s < n; s += 1) for (let c = 0; c < t; c += 1) {
1098
- let l = Qe(i, a, t, n, c, s, r);
1099
- o[s * t + c] = Math.max(0, Math.min(255, Math.round(e[s * t + c] * 235 / Math.max(24, l))));
1100
- }
1101
- return o;
1102
- }
1103
- function tt(e, t, n, r = Math.max(8, Math.round(Math.max(t, n) / 64)), i = .12) {
1104
- let { integral: a, stride: o } = $e(e, t, n), s = new Uint8Array(e.length), c = 1 - i;
1105
- for (let i = 0; i < n; i += 1) for (let l = 0; l < t; l += 1) {
1106
- let u = Qe(a, o, t, n, l, i, r);
1107
- s[i * t + l] = e[i * t + l] < u * c ? 0 : 255;
1108
- }
1109
- return s;
1110
- }
1111
- function nt(e, t, n) {
1112
- let r = [
1113
- e.topLeft,
1114
- e.topRight,
1115
- e.bottomRight,
1116
- e.bottomLeft
1117
- ], i = Math.max(0, Math.min(...r.map((e) => e.x))), a = Math.max(0, Math.min(...r.map((e) => e.y))), o = Math.min(t, Math.max(...r.map((e) => e.x))), s = Math.min(n, Math.max(...r.map((e) => e.y)));
1118
- return {
1119
- left: i,
1120
- top: a,
1121
- width: o - i,
1122
- height: s - a
1123
- };
1124
- }
1125
- function rt(e, t) {
1126
- let n = nt(t, e.width, e.height);
1127
- if (n.width <= 0 || n.height <= 0) return {
1128
- strong: !1,
1129
- strength: 0,
1130
- darkness: 0,
1131
- areaRatio: 0
1132
- };
1133
- let r = document.createElement("canvas");
1134
- r.width = 60, r.height = 60;
1135
- let i = r.getContext("2d", { willReadFrequently: !0 });
1136
- if (!i) return {
1137
- strong: !1,
1138
- strength: 0,
1139
- darkness: 0,
1140
- areaRatio: 0
1141
- };
1142
- i.drawImage(e, n.left, n.top, n.width, n.height, 0, 0, r.width, r.height);
1143
- let a = i.getImageData(0, 0, r.width, r.height).data, o = new Uint8Array(r.width * r.height);
1144
- for (let e = 0, t = 0; e < o.length; e += 1, t += 4) o[e] = Math.round(a[t] * .299 + a[t + 1] * .587 + a[t + 2] * .114);
1145
- return Ze(o, r.width, r.height);
1146
- }
1147
- //#endregion
1148
- //#region src/sdk/finder.ts
1149
- function it(e, t) {
1150
- return t.castShadow && (e.reason === "hold-still" || e.reason === "ready") ? t.hint ?? e.hint : e.hint;
1151
- }
1152
- async function at(e, t) {
1153
- let n = await e();
1154
- return t(), n;
1155
- }
1156
- function ot(e) {
1157
- return e === "alwaysOn" || e === "only" ? {
1158
- visible: !1,
1159
- checked: !0,
1160
- mutable: !1
1161
- } : e === "alwaysOff" ? {
1162
- visible: !1,
1163
- checked: !1,
1164
- mutable: !1
1165
- } : {
1166
- visible: !0,
1167
- checked: e === "defaultOn",
1168
- mutable: !0
1169
- };
1170
- }
1171
- function X(e) {
1172
- return [
1173
- e.topLeft,
1174
- e.topRight,
1175
- e.bottomRight,
1176
- e.bottomLeft
1177
- ];
1178
- }
1179
- function st(e, t) {
1180
- let n = e.status === "success" && e.modelStatus !== "failed", r = {
1181
- status: e.status,
1182
- confidence: Number(e.confidence.toFixed(3)),
1183
- source: `${e.sourceWidth}×${e.sourceHeight}`
1184
- };
1185
- t?.width && t?.height && (r.video = `${t.width}×${t.height}`), e.modelStatus && (r.modelStatus = e.modelStatus), e.modelProvider && (r.provider = e.modelProvider), e.modelError && (r.modelError = e.modelError), e.modelNote && (r.modelNote = e.modelNote), e.inferenceMs !== void 0 && (r.inferenceMs = Math.round(e.inferenceMs)), !n && e.message && (r.message = e.message);
1186
- let i = n ? "document found" : e.modelStatus === "failed" ? "document not found (ML failed)" : `document not found (${e.status})`;
1187
- return {
1188
- level: n ? "info" : "warn",
1189
- key: [
1190
- i,
1191
- r.modelStatus ?? "",
1192
- r.modelError ?? "",
1193
- r.provider ?? "",
1194
- r.modelNote ?? "",
1195
- r.source,
1196
- r.video ?? ""
1197
- ].join("|"),
1198
- summary: i,
1199
- detail: r
1200
- };
1201
- }
1202
- function ct(e) {
1203
- let t = 0;
1204
- for (let n = 0; n < e.length; n += 1) {
1205
- let r = e[n], i = e[(n + 1) % e.length];
1206
- t += r.x * i.y - i.x * r.y;
1207
- }
1208
- return Math.abs(t) / 2;
1209
- }
1210
- function Z(e, t) {
1211
- return Math.hypot(e.x - t.x, e.y - t.y);
1212
- }
1213
- var Q = {
1214
- widthFill: 0,
1215
- heightFill: 0,
1216
- limitingFill: 0,
1217
- areaFill: 0,
1218
- aspectRatio: 1
1219
- };
1220
- function lt(e, t, n) {
1221
- let r = X(e), i = r.map(({ x: e }) => e), a = r.map(({ y: e }) => e), o = (Math.max(...i) - Math.min(...i)) / Math.max(1, t), s = (Math.max(...a) - Math.min(...a)) / Math.max(1, n), [c, l, u, d] = r, f = Math.max(Z(c, l), Z(d, u)), p = Math.max(Z(c, d), Z(l, u));
1222
- return {
1223
- widthFill: o,
1224
- heightFill: s,
1225
- limitingFill: Math.max(o, s),
1226
- areaFill: ct(r) / Math.max(1, t * n),
1227
- aspectRatio: Math.max(f, p) / Math.max(1, Math.min(f, p))
1228
- };
1229
- }
1230
- function ut(e, t, n, r = {}) {
1231
- let i = t ? r.exitFillRatio ?? .64 : r.minFillRatio ?? .72, a = r.highAspectRatio ?? 2.2;
1232
- if (e.aspectRatio < a) return i;
1233
- let o = t ? r.highAspectExitFillRatio : r.highAspectFillRatio;
1234
- return Math.min(o ?? i + .08, 1 - n * 2);
1235
- }
1236
- function dt(e, t, n = {}) {
1237
- let r = n.confidenceThreshold ?? .72;
1238
- if (e.status !== "success" || !e.quad || e.confidence < r || !e.sourceWidth || !e.sourceHeight) return {
1239
- hint: "Place the document in the frame",
1240
- reason: "place-document",
1241
- fillRatio: 0,
1242
- fill: Q,
1243
- readyForAutoCapture: !1
1244
- };
1245
- let i = X(e.quad), a = lt(e.quad, e.sourceWidth, e.sourceHeight), o = a.limitingFill, s = t.previouslyReady ? n.exitEdgeMarginRatio ?? .005 : n.edgeMarginRatio ?? .015, c = e.sourceWidth * s, l = e.sourceHeight * s;
1246
- if (i.some(({ x: t, y: n }) => t <= c || t >= e.sourceWidth - c || n <= l || n >= e.sourceHeight - l)) return {
1247
- hint: "Move farther away",
1248
- reason: "move-farther-away",
1249
- fillRatio: o,
1250
- fill: a,
1251
- readyForAutoCapture: !1
1252
- };
1253
- let [u, d, f, p] = i, m = Z(u, d), h = Z(d, f), g = Z(f, p), _ = Z(p, u);
1254
- return Math.min(Math.min(m, g) / Math.max(1, Math.max(m, g)), Math.min(_, h) / Math.max(1, Math.max(_, h))) < (t.previouslyReady ? n.exitMinPerspectiveRatio ?? .4 : n.minPerspectiveRatio ?? .48) ? {
1255
- hint: "Hold the camera straight",
1256
- reason: "straighten-camera",
1257
- fillRatio: o,
1258
- fill: a,
1259
- readyForAutoCapture: !1
1260
- } : o < ut(a, t.previouslyReady === !0, s, n) ? {
1261
- hint: "Move closer",
1262
- reason: "move-closer",
1263
- fillRatio: o,
1264
- fill: a,
1265
- readyForAutoCapture: !1
1266
- } : {
1267
- hint: "Hold still",
1268
- reason: t.ready ? "ready" : "hold-still",
1269
- fillRatio: o,
1270
- fill: a,
1271
- readyForAutoCapture: t.ready
1272
- };
1273
- }
1274
- var $ = class {
1275
- previous;
1276
- count = 0;
1277
- ready = !1;
1278
- options;
1279
- constructor(e) {
1280
- this.options = e;
1281
- }
1282
- reset() {
1283
- this.previous = void 0, this.count = 0, this.ready = !1;
1284
- }
1285
- update(e) {
1286
- if (e.status !== "success" || !e.quad || e.confidence < this.options.confidenceThreshold) return this.reset(), {
1287
- stableFrames: 0,
1288
- ready: !1,
1289
- movement: Infinity
1290
- };
1291
- let t = Math.hypot(e.sourceWidth, e.sourceHeight), n = this.previous ? Math.max(...X(e.quad).map((e, n) => {
1292
- let r = X(this.previous)[n];
1293
- return Math.hypot(e.x - r.x, e.y - r.y) / Math.max(1, t);
1294
- })) : Infinity, r = this.options.exitCornerTolerance ?? Math.max(this.options.cornerTolerance, .036);
1295
- return this.ready && this.previous && n <= r ? this.count = Math.max(this.options.stableFrames, this.count + 1) : (this.ready = !1, this.count = this.previous && n <= this.options.cornerTolerance ? this.count + 1 : 1, this.count >= this.options.stableFrames && (this.ready = !0)), this.previous = e.quad, {
1296
- stableFrames: this.count,
1297
- ready: this.ready,
1298
- movement: n
1299
- };
1300
- }
1301
- };
1302
- function ft(e, n) {
1303
- let r = Math.min(1, n / Math.max(e.width, e.height)), i = document.createElement("canvas");
1304
- i.width = Math.max(1, Math.round(e.width * r)), i.height = Math.max(1, Math.round(e.height * r));
1305
- let a = i.getContext("2d");
1306
- if (!a) throw t();
1307
- return a.drawImage(e, 0, 0, i.width, i.height), i;
1308
- }
1309
- function pt() {
1310
- let e = window.AudioContext ?? window.webkitAudioContext;
1311
- if (!e) return;
1312
- let t = new e(), n = Math.round(t.sampleRate * .09), r = t.createBuffer(1, n, t.sampleRate), i = r.getChannelData(0);
1313
- for (let e = 0; e < n; e += 1) {
1314
- let n = Math.exp(-e / (t.sampleRate * .018));
1315
- i[e] = (Math.random() * 2 - 1) * n;
1316
- }
1317
- let a = t.createBufferSource(), o = t.createBiquadFilter(), s = t.createGain();
1318
- o.type = "bandpass", o.frequency.value = 1400, s.gain.value = .42, a.buffer = r, a.connect(o).connect(s).connect(t.destination), a.start(), a.onended = () => void t.close();
1319
- }
1320
- async function mt(e) {
1321
- let t = document.createElement("video");
1322
- return t.muted = !0, t.autoplay = !0, t.playsInline = !0, t.srcObject = e, await t.play(), t;
1323
- }
1324
- async function ht(t) {
1325
- await x("scan");
1326
- let n = ot(t.autoCapture), r = new $({
1327
- stableFrames: t.stableFrames ?? 4,
1328
- confidenceThreshold: t.confidenceThreshold ?? .72,
1329
- cornerTolerance: t.cornerTolerance ?? .024,
1330
- exitCornerTolerance: t.exitCornerTolerance ?? .036
1331
- }), i = t.maxFrameDimension ?? 1600, a = t.intervalMs ?? 140, o = {
1332
- minDimension: 220,
1333
- maxAnalysisDimension: 520,
1334
- ...t.detection
1335
- }, s = typeof MediaStream < "u" && t.source instanceof MediaStream ? await mt(t.source) : t.source, c = !0, l = !1, u = !1, d = 0, f, p = "", m = 0, h = {
1336
- state: "detecting",
1337
- confidence: 0,
1338
- guidance: {
1339
- hint: "Place the document in the frame",
1340
- reason: "place-document",
1341
- fillRatio: 0,
1342
- fill: Q,
1343
- readyForAutoCapture: !1
1344
- },
1345
- lighting: {
1346
- castShadow: !1,
1347
- strength: 0
1348
- },
1349
- stableFrames: 0,
1350
- requiredStableFrames: t.stableFrames ?? 4,
1351
- autoCapture: { ...n }
1352
- }, g = () => s instanceof HTMLCanvasElement ? ft(s, i) : Y(s, i), _ = (e) => {
1353
- h = e, t.onStatus?.(e);
1354
- }, v = (e) => {
1355
- let t = st(e, s instanceof HTMLVideoElement ? {
1356
- width: s.videoWidth,
1357
- height: s.videoHeight
1358
- } : {
1359
- width: s.width,
1360
- height: s.height
1361
- }), n = performance.now();
1362
- t.key === p && n - m < 2e3 || (p = t.key, m = n, console[t.level](`[exige-scanner] ${t.summary}`, t.detail));
1363
- }, y = () => {
1364
- c = !1, window.clearTimeout(d), s instanceof HTMLVideoElement && s !== t.source && (s.srcObject = null);
1365
- }, b = async (e = "manual") => {
1366
- if (l) throw Error("A finder capture is already in progress.");
1367
- l = !0;
1368
- let n;
1369
- try {
1370
- n = await at(t.captureFrame ?? g, () => {
1371
- _({
1372
- ...h,
1373
- state: "captured"
1374
- }), t.playShutterSound !== !1 && pt(), y();
1375
- });
1376
- } catch (e) {
1377
- throw l = !1, e instanceof Error ? e : /* @__PURE__ */ Error("The camera frame could not be captured.");
1378
- }
1379
- let r = {
1380
- frame: n,
1381
- detection: f,
1382
- reason: e
1383
- };
1384
- return await t.onCapture?.(r), r;
1385
- }, S = async () => {
1386
- if (c && !l) {
1387
- try {
1388
- let e = g(), i = await R(e, o);
1389
- f = i, v(i);
1390
- let a = i.quad ? rt(e, i.quad) : {
1391
- strong: !1,
1392
- strength: 0
1393
- }, s = a.strong ? {
1394
- castShadow: !0,
1395
- strength: a.strength,
1396
- hint: "Tilt to move the shadow off the page"
1397
- } : {
1398
- castShadow: !1,
1399
- strength: a.strength
1400
- }, c = r.update(i), l = dt(i, {
1401
- ...c,
1402
- previouslyReady: u
1403
- }, {
1404
- confidenceThreshold: t.confidenceThreshold ?? .72,
1405
- ...t.guidance
1406
- });
1407
- u = l.readyForAutoCapture;
1408
- let d = i.status !== "success" || l.reason === "place-document" ? "seeking" : l.readyForAutoCapture ? "ready" : "unstable";
1409
- if (_({
1410
- state: d,
1411
- confidence: i.confidence,
1412
- quad: i.quad,
1413
- guidance: l,
1414
- lighting: s,
1415
- stableFrames: c.stableFrames,
1416
- requiredStableFrames: h.requiredStableFrames,
1417
- autoCapture: { ...n },
1418
- sourceWidth: i.sourceWidth,
1419
- sourceHeight: i.sourceHeight,
1420
- detector: i.detector,
1421
- modelStatus: i.modelStatus,
1422
- modelProvider: i.modelProvider,
1423
- modelError: i.modelError,
1424
- modelNote: i.modelNote,
1425
- inferenceMs: i.inferenceMs
1426
- }), l.readyForAutoCapture && n.checked) try {
1427
- await b("auto");
1428
- return;
1429
- } catch (e) {
1430
- r.reset(), u = !1, t.onCaptureError?.(e instanceof Error ? e : /* @__PURE__ */ Error("Automatic capture failed."));
1431
- }
1432
- } catch (t) {
1433
- r.reset(), u = !1;
1434
- let i = t instanceof e ? {
1435
- detector: "ml",
1436
- modelStatus: "failed",
1437
- modelError: t.message
1438
- } : { modelError: t instanceof Error ? t.message : "Finder tick failed." };
1439
- v({
1440
- status: "no-document",
1441
- confidence: 0,
1442
- message: i.modelError ?? "Finder tick failed.",
1443
- sourceWidth: 0,
1444
- sourceHeight: 0,
1445
- ...i
1446
- }), _({
1447
- state: "seeking",
1448
- confidence: 0,
1449
- guidance: {
1450
- hint: "Place the document in the frame",
1451
- reason: "place-document",
1452
- fillRatio: 0,
1453
- fill: Q,
1454
- readyForAutoCapture: !1
1455
- },
1456
- lighting: {
1457
- castShadow: !1,
1458
- strength: 0
1459
- },
1460
- stableFrames: 0,
1461
- requiredStableFrames: h.requiredStableFrames,
1462
- autoCapture: { ...n },
1463
- ...i
1464
- });
1465
- }
1466
- c && (d = window.setTimeout(() => void S(), a));
1467
- }
1468
- };
1469
- return t.onStatus?.(h), S(), {
1470
- stop: y,
1471
- capture: () => b("manual"),
1472
- setAutoCapture(e) {
1473
- return !n.mutable || l ? !1 : (n.checked = e, _({
1474
- ...h,
1475
- autoCapture: { ...n }
1476
- }), !0);
1477
- },
1478
- getStatus: () => h
1479
- };
1480
- }
1481
- //#endregion
1482
- export { z as A, x as B, Ee as C, Ce as D, pe as E, A as F, y as H, ie as I, ne as L, B as M, de as N, R as O, fe as P, a as R, Ye as S, K as T, e as U, b as V, t as W, Je as _, dt as a, q as b, tt as c, G as d, je as f, Te as g, H as h, lt as i, we as j, j as k, Ze as l, Y as m, ot as n, it as o, ze as p, ut as r, ht as s, $ as t, et as u, U as v, qe as w, J as x, Me as y, o as z };
1483
-
1484
- //# sourceMappingURL=finder-BlN89ZeT.js.map