@exige/web-scanner-sdk 0.2.0

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 (37) hide show
  1. package/README.md +288 -0
  2. package/dist/assets/document-worker-QjcJjl9-.js +2 -0
  3. package/dist/assets/document-worker-QjcJjl9-.js.map +1 -0
  4. package/dist/assets/ort.min-CA5AZ7mL.js +2937 -0
  5. package/dist/assets/ort.min-CA5AZ7mL.js.map +1 -0
  6. package/dist/components/ScannerCameraOverlay.d.ts +36 -0
  7. package/dist/components/scanner-camera-overlay.css +2 -0
  8. package/dist/finder-Clo7f2gN.js +1447 -0
  9. package/dist/finder-Clo7f2gN.js.map +1 -0
  10. package/dist/index.d.ts +20 -0
  11. package/dist/live-overlay-geometry.d.ts +11 -0
  12. package/dist/react.d.ts +2 -0
  13. package/dist/react.js +448 -0
  14. package/dist/react.js.map +1 -0
  15. package/dist/scanner-sdk.js +921 -0
  16. package/dist/scanner-sdk.js.map +1 -0
  17. package/dist/sdk/camera.d.ts +142 -0
  18. package/dist/sdk/detect.d.ts +3 -0
  19. package/dist/sdk/display-quad.d.ts +23 -0
  20. package/dist/sdk/document-analysis.d.ts +14 -0
  21. package/dist/sdk/document-geometry.d.ts +21 -0
  22. package/dist/sdk/field-model.d.ts +4 -0
  23. package/dist/sdk/finder-simulator.d.ts +17 -0
  24. package/dist/sdk/finder.d.ts +166 -0
  25. package/dist/sdk/frame-geometry.d.ts +6 -0
  26. package/dist/sdk/image.d.ts +18 -0
  27. package/dist/sdk/license-codec.d.ts +2 -0
  28. package/dist/sdk/license-public-key.d.ts +9 -0
  29. package/dist/sdk/license-runtime.d.ts +2 -0
  30. package/dist/sdk/license.d.ts +76 -0
  31. package/dist/sdk/lighting.d.ts +22 -0
  32. package/dist/sdk/ocr.d.ts +75 -0
  33. package/dist/sdk/programmatic-redaction.d.ts +102 -0
  34. package/dist/sdk/redact.d.ts +12 -0
  35. package/dist/sdk/scan.d.ts +32 -0
  36. package/dist/sdk/types.d.ts +92 -0
  37. package/package.json +74 -0
package/dist/react.js ADDED
@@ -0,0 +1,448 @@
1
+ import { A as e, E as t, T as n, v as r, y as i } from "./finder-Clo7f2gN.js";
2
+ import { useEffect as a, useRef as o, useState as s } from "react";
3
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
4
+ //#region src/sdk/display-quad.ts
5
+ function u(e) {
6
+ return [
7
+ e.topLeft,
8
+ e.topRight,
9
+ e.bottomRight,
10
+ e.bottomLeft
11
+ ];
12
+ }
13
+ function d(e) {
14
+ let [t, n, r, i] = e;
15
+ return {
16
+ topLeft: t,
17
+ topRight: n,
18
+ bottomRight: r,
19
+ bottomLeft: i,
20
+ edges: {
21
+ top: {
22
+ start: t,
23
+ end: n
24
+ },
25
+ right: {
26
+ start: n,
27
+ end: r
28
+ },
29
+ bottom: {
30
+ start: r,
31
+ end: i
32
+ },
33
+ left: {
34
+ start: i,
35
+ end: t
36
+ }
37
+ }
38
+ };
39
+ }
40
+ function f(e) {
41
+ return d(u(e).map((e) => ({ ...e })));
42
+ }
43
+ var p = class {
44
+ current;
45
+ target;
46
+ response;
47
+ snapDistance;
48
+ constructor(e = {}) {
49
+ this.response = e.response ?? 14, this.snapDistance = e.snapDistance ?? .1;
50
+ }
51
+ setTarget(e, t, n) {
52
+ let r = Math.max(1, Math.hypot(t, n)), i = !this.current || u(e).some((e, t) => {
53
+ let n = u(this.current)[t];
54
+ return Math.hypot(e.x - n.x, e.y - n.y) / r > this.snapDistance;
55
+ });
56
+ return this.target = f(e), i && (this.current = f(e)), {
57
+ quad: this.current,
58
+ snapped: i
59
+ };
60
+ }
61
+ step(e) {
62
+ if (!this.current || !this.target) return this.current;
63
+ let t = 1 - Math.exp(-this.response * Math.max(0, e) / 1e3);
64
+ return this.current = d(u(this.current).map((e, n) => {
65
+ let r = u(this.target)[n];
66
+ return {
67
+ x: e.x + (r.x - e.x) * t,
68
+ y: e.y + (r.y - e.y) * t
69
+ };
70
+ })), this.current;
71
+ }
72
+ clear() {
73
+ this.current = void 0, this.target = void 0;
74
+ }
75
+ getCurrent() {
76
+ return this.current;
77
+ }
78
+ };
79
+ //#endregion
80
+ //#region src/live-overlay-geometry.ts
81
+ function ee(e, t, n, r, i) {
82
+ let a = Math.max(1, e), o = Math.max(1, t), s = Math.max(1, n), c = Math.max(1, r), l = s / a, u = c / o, d = i === "cover" ? Math.max(l, u) : Math.min(l, u), f = (s - a * d) / 2, p = (c - o * d) / 2;
83
+ if (i === "contain") return {
84
+ viewBox: `0 0 ${a} ${o}`,
85
+ preserveAspectRatio: "xMidYMid meet",
86
+ scale: d,
87
+ offsetX: f,
88
+ offsetY: p
89
+ };
90
+ let ee = s / d, m = c / d;
91
+ return {
92
+ viewBox: `${-f / d} ${-p / d} ${ee} ${m}`,
93
+ preserveAspectRatio: "none",
94
+ scale: d,
95
+ offsetX: f,
96
+ offsetY: p
97
+ };
98
+ }
99
+ //#endregion
100
+ //#region src/components/ScannerCameraOverlay.tsx
101
+ function m({ open: u, autoCapture: d = "defaultOn", torch: f = "defaultOff", cameraOptions: m, onCapture: h, onClose: te, onError: g, onSettings: _, onFinderStatus: v, className: ne = "", title: re = "Scan a document", previewFit: y = "cover", detector: b = "classical", modelUrl: x, ortWasmPaths: ie, detectionIntervalMs: ae }) {
102
+ let S = o(null), C = o(void 0), w = o(void 0), T = o(void 0), E = o(void 0), D = o({}), O = o(new p()), k = o(!1), A = o({
103
+ onCapture: h,
104
+ onError: g,
105
+ onSettings: _,
106
+ onFinderStatus: v
107
+ }), [j, M] = s("starting"), [N, oe] = s(), [P, F] = s(), [I, se] = s({
108
+ width: 1,
109
+ height: 1
110
+ }), [L, ce] = s(), [R, z] = s(), [B, V] = s(""), [H, le] = s(0), [U, W] = s(), [G, K] = s(), [q, J] = s("idle");
111
+ if (a(() => {
112
+ A.current = {
113
+ onCapture: h,
114
+ onError: g,
115
+ onSettings: _,
116
+ onFinderStatus: v
117
+ };
118
+ }, [
119
+ h,
120
+ g,
121
+ _,
122
+ v
123
+ ]), a(() => {
124
+ if (!u) return;
125
+ let e = document.body.style.overflow;
126
+ return document.body.style.overflow = "hidden", () => {
127
+ document.body.style.overflow = e;
128
+ };
129
+ }, [u]), a(() => {
130
+ if (!u) return;
131
+ let e = S.current;
132
+ if (!e) return;
133
+ let t = () => {
134
+ let t = e.getBoundingClientRect();
135
+ se({
136
+ width: t.width,
137
+ height: t.height
138
+ });
139
+ };
140
+ if (t(), typeof ResizeObserver > "u") return window.addEventListener("resize", t), () => window.removeEventListener("resize", t);
141
+ let n = new ResizeObserver(t);
142
+ return n.observe(e), () => n.disconnect();
143
+ }, [u]), a(() => {
144
+ if (!u) return;
145
+ let e = window.setInterval(() => {
146
+ let e = C.current?.getDiagnostics();
147
+ e && W(e);
148
+ }, 500);
149
+ return () => window.clearInterval(e);
150
+ }, [u, H]), a(() => {
151
+ if (!u) return;
152
+ let e = 0, t = performance.now(), n = (r) => {
153
+ let i = O.current.step(r - t);
154
+ t = r, i && F(i), e = requestAnimationFrame(n);
155
+ };
156
+ return e = requestAnimationFrame(n), () => cancelAnimationFrame(e);
157
+ }, [u]), a(() => {
158
+ if (!u) return;
159
+ let t = S.current;
160
+ if (!t) return;
161
+ let n = !1, r = () => {
162
+ w.current?.stop(), w.current = void 0, C.current?.stop(), C.current = void 0, E.current = void 0, T.current = void 0, D.current = {};
163
+ };
164
+ return (async () => {
165
+ r(), k.current = !1, M("starting"), V(""), oe(void 0), z(void 0), K(void 0), J("idle");
166
+ try {
167
+ let r = await e(t, {
168
+ ...m,
169
+ torch: f
170
+ });
171
+ if (n) {
172
+ r.stop();
173
+ return;
174
+ }
175
+ C.current = r;
176
+ let a = r.getSettings();
177
+ ce(a), A.current.onSettings?.(a), console.info("[ScannerCameraOverlay] camera settings", a), w.current = await i({
178
+ source: t,
179
+ autoCapture: d,
180
+ intervalMs: ae,
181
+ detection: {
182
+ detector: b,
183
+ modelUrl: x,
184
+ ortWasmPaths: ie
185
+ },
186
+ onStatus: (e) => {
187
+ if (T.current = e, oe(e), A.current.onFinderStatus?.(e), e.quad && e.sourceWidth && e.sourceHeight) {
188
+ let t = O.current.setTarget(e.quad, e.sourceWidth, e.sourceHeight);
189
+ F(t.quad);
190
+ } else O.current.clear(), F(void 0);
191
+ e.state !== "captured" && !k.current && M("ready");
192
+ },
193
+ captureFrame: async () => {
194
+ M("capturing"), D.current = {
195
+ quad: O.current.getCurrent(),
196
+ sourceWidth: T.current?.sourceWidth,
197
+ sourceHeight: T.current?.sourceHeight
198
+ };
199
+ let e = await r.capturePhoto();
200
+ if (E.current = e, z(e.method), K(e.diagnostics), W(e.diagnostics), e.luminance <= 10) throw Error(`The captured frame was blank (luminance ${e.luminance.toFixed(1)} via ${e.method}). Keep the scanner visible while capturing and retake.`);
201
+ return e.frame;
202
+ },
203
+ onCaptureError: (e) => {
204
+ k.current = !0, M("error"), V(e.message);
205
+ let t = C.current?.getDiagnostics();
206
+ t && W(t), A.current.onError?.(e);
207
+ },
208
+ onCapture: async (e) => {
209
+ let t = E.current;
210
+ await new Promise((e) => window.setTimeout(e, 140)), await A.current.onCapture({
211
+ ...e,
212
+ method: t?.method ?? "video-frame",
213
+ settings: t?.settings ?? r.getSettings(),
214
+ fallbackReason: t?.fallbackReason,
215
+ luminance: t?.luminance,
216
+ diagnostics: t?.diagnostics,
217
+ displayedQuad: D.current.quad,
218
+ displaySourceWidth: D.current.sourceWidth,
219
+ displaySourceHeight: D.current.sourceHeight
220
+ });
221
+ }
222
+ });
223
+ } catch (e) {
224
+ if (n) return;
225
+ r();
226
+ let t = e instanceof Error ? e : /* @__PURE__ */ Error("Camera access failed.");
227
+ V(t.message), M("error"), A.current.onError?.(t);
228
+ }
229
+ })(), () => {
230
+ n = !0, r();
231
+ };
232
+ }, [
233
+ u,
234
+ d,
235
+ f,
236
+ m,
237
+ b,
238
+ x,
239
+ ie,
240
+ ae,
241
+ H
242
+ ]), !u) return null;
243
+ let Y = () => {
244
+ w.current?.stop(), C.current?.stop(), te();
245
+ }, ue = async () => {
246
+ try {
247
+ await w.current?.capture();
248
+ } catch (e) {
249
+ let t = e instanceof Error ? e : /* @__PURE__ */ Error("Could not capture the camera frame.");
250
+ k.current = !0, V(t.message);
251
+ let n = C.current?.getDiagnostics();
252
+ n && W(n), E.current?.diagnostics && K(E.current.diagnostics), M("error"), g?.(t);
253
+ }
254
+ }, de = () => {
255
+ k.current = !1, V(""), K(void 0), J("idle");
256
+ let e = C.current;
257
+ M(e ? "ready" : "starting"), e || le((e) => e + 1);
258
+ }, fe = async (e) => {
259
+ let t = C.current;
260
+ t && (await t.setTorch(e), W(t.getDiagnostics()));
261
+ }, pe = async () => {
262
+ let e = C.current?.getDiagnostics() ?? U, n = t({
263
+ error: B || void 0,
264
+ captureMethod: R,
265
+ luminance: E.current?.luminance,
266
+ fallbackReason: E.current?.fallbackReason,
267
+ shutter: G ?? E.current?.diagnostics,
268
+ live: e,
269
+ finder: N ? {
270
+ state: N.state,
271
+ confidence: N.confidence,
272
+ stableFrames: N.stableFrames,
273
+ requiredStableFrames: N.requiredStableFrames,
274
+ detector: N.detector,
275
+ modelStatus: N.modelStatus,
276
+ sourceWidth: N.sourceWidth,
277
+ sourceHeight: N.sourceHeight
278
+ } : void 0
279
+ });
280
+ try {
281
+ if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(n);
282
+ else {
283
+ let e = document.createElement("textarea");
284
+ e.value = n, e.setAttribute("readonly", ""), e.style.position = "fixed", e.style.left = "-9999px", document.body.append(e), e.select();
285
+ let t = document.execCommand("copy");
286
+ if (e.remove(), !t) throw Error("Clipboard copy is unavailable.");
287
+ }
288
+ J("copied");
289
+ } catch {
290
+ J("failed");
291
+ }
292
+ }, X = L?.width, Z = L?.height, Q = U?.engine ?? n(), $ = U, me = N?.sourceWidth && N.sourceHeight ? ee(N.sourceWidth, N.sourceHeight, I.width, I.height, y) : void 0, he = N?.modelStatus === "fallback" ? "classical fallback" : N?.modelStatus === "failed" ? "ML failed" : N?.detector === "ml" ? `ML ${N.modelProvider ?? ""}`.trim() : b === "ml" || b === "auto" ? "ML loading" : "classical", ge = N ? r(N.guidance, N.lighting) : void 0;
293
+ return /* @__PURE__ */ l("div", {
294
+ className: `scanner-camera-overlay ${N?.state === "captured" ? "is-captured" : ""} ${ne}`.trim(),
295
+ role: "dialog",
296
+ "aria-modal": "true",
297
+ "aria-label": re,
298
+ children: [
299
+ /* @__PURE__ */ c("video", {
300
+ ref: S,
301
+ className: "scanner-camera-overlay__video",
302
+ muted: !0,
303
+ autoPlay: !0,
304
+ playsInline: !0,
305
+ style: { objectFit: y },
306
+ "aria-label": "Rear camera preview"
307
+ }),
308
+ P && N?.sourceWidth && N.sourceHeight && /* @__PURE__ */ c("svg", {
309
+ className: `scanner-camera-overlay__quad ${N.state}`,
310
+ viewBox: me?.viewBox,
311
+ preserveAspectRatio: me?.preserveAspectRatio,
312
+ "aria-label": `${N.state} document boundary`,
313
+ children: /* @__PURE__ */ c("polygon", { points: `${P.topLeft.x},${P.topLeft.y} ${P.topRight.x},${P.topRight.y} ${P.bottomRight.x},${P.bottomRight.y} ${P.bottomLeft.x},${P.bottomLeft.y}` })
314
+ }),
315
+ /* @__PURE__ */ l("div", {
316
+ className: "scanner-camera-overlay__topbar",
317
+ children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("strong", { children: re }), /* @__PURE__ */ l("span", {
318
+ "aria-live": "polite",
319
+ children: [
320
+ j === "starting" && "Starting rear camera…",
321
+ j === "ready" && (ge ?? "Place the document in the frame"),
322
+ j === "capturing" && "Capturing full resolution…",
323
+ j === "error" && "Camera unavailable"
324
+ ]
325
+ })] }), /* @__PURE__ */ c("button", {
326
+ type: "button",
327
+ onClick: Y,
328
+ "aria-label": "Close camera",
329
+ children: "×"
330
+ })]
331
+ }),
332
+ j === "error" ? /* @__PURE__ */ l("div", {
333
+ className: "scanner-camera-overlay__message",
334
+ role: "alert",
335
+ children: [
336
+ /* @__PURE__ */ c("strong", { children: U ? "Capture failed" : "Could not open the camera" }),
337
+ /* @__PURE__ */ c("p", { children: B }),
338
+ /* @__PURE__ */ l("div", { children: [
339
+ /* @__PURE__ */ c("button", {
340
+ type: "button",
341
+ onClick: de,
342
+ children: "Try again"
343
+ }),
344
+ /* @__PURE__ */ c("button", {
345
+ type: "button",
346
+ onClick: () => void pe(),
347
+ children: q === "copied" ? "Copied" : q === "failed" ? "Copy failed" : "Copy report"
348
+ }),
349
+ /* @__PURE__ */ c("button", {
350
+ type: "button",
351
+ onClick: Y,
352
+ children: "Cancel"
353
+ })
354
+ ] })
355
+ ]
356
+ }) : j === "starting" ? /* @__PURE__ */ l("div", {
357
+ className: "scanner-camera-overlay__message",
358
+ "aria-live": "polite",
359
+ children: [
360
+ /* @__PURE__ */ c("span", { className: "scanner-camera-overlay__spinner" }),
361
+ /* @__PURE__ */ c("strong", { children: "Requesting the highest practical resolution" }),
362
+ /* @__PURE__ */ c("p", { children: "Allow camera access to continue." })
363
+ ]
364
+ }) : null,
365
+ /* @__PURE__ */ l("div", {
366
+ className: "scanner-camera-overlay__status",
367
+ "aria-live": "polite",
368
+ children: [
369
+ /* @__PURE__ */ c("span", { className: N?.state ?? "detecting" }),
370
+ N?.state ?? "detecting",
371
+ N ? ` · ${Math.round(N.confidence * 100)}% · ${N.stableFrames}/${N.requiredStableFrames}` : "",
372
+ ` · ${he}`,
373
+ N?.inferenceMs === void 0 ? "" : ` · ${Math.round(N.inferenceMs)}ms`,
374
+ X && Z ? ` · ${X}×${Z}` : ""
375
+ ]
376
+ }),
377
+ /* @__PURE__ */ l("dl", {
378
+ className: "scanner-camera-overlay__diagnostics",
379
+ "aria-label": "Camera diagnostics",
380
+ children: [
381
+ /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("dt", { children: "engine" }), /* @__PURE__ */ l("dd", { children: [
382
+ Q.engine,
383
+ "/",
384
+ Q.browser,
385
+ Q.iosWebKit ? " ios" : ""
386
+ ] })] }),
387
+ /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("dt", { children: "video" }), /* @__PURE__ */ c("dd", { children: $ ? `${$.videoWidth}×${$.videoHeight} rs${$.readyState}${$.paused ? " paused" : ""}${$.rendered ? "" : " hidden"}` : "starting" })] }),
388
+ /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("dt", { children: "track" }), /* @__PURE__ */ c("dd", { children: $ ? `${$.trackReadyState}${$.trackMuted ? " muted" : ""}${$.trackEnabled ? "" : " disabled"}` : "—" })] }),
389
+ /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("dt", { children: "torch" }), /* @__PURE__ */ c("dd", { children: $ ? `${$.torch.mode} · ${$.torch.supported ? $.torch.on ? "on" : "off" : "unsupported"}` : "starting" })] }),
390
+ /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("dt", { children: "luma" }), /* @__PURE__ */ c("dd", { children: $ ? `live ${$.liveLuminance.toFixed(1)} · mirror ${$.mirrorLuminance.toFixed(1)}${Number.isFinite($.mirrorAgeMs) ? ` (${Math.round($.mirrorAgeMs)}ms)` : " (none)"}` : "—" })] }),
391
+ /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("dt", { children: "path" }), /* @__PURE__ */ c("dd", { children: R ?? "video-frame / live-mirror" })] }),
392
+ G ? /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("dt", { children: "shutter" }), /* @__PURE__ */ c("dd", { children: `live ${G.liveLuminance.toFixed(1)} · mirror ${G.mirrorLuminance.toFixed(1)}${Number.isFinite(G.mirrorAgeMs) ? ` (${Math.round(G.mirrorAgeMs)}ms)` : " (none)"}` })] }) : null,
393
+ /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("dt", { children: "share" }), /* @__PURE__ */ c("dd", { children: /* @__PURE__ */ c("button", {
394
+ type: "button",
395
+ className: "scanner-camera-overlay__copy",
396
+ onClick: () => void pe(),
397
+ children: q === "copied" ? "Copied report" : q === "failed" ? "Copy failed" : "Copy report"
398
+ }) })] })
399
+ ]
400
+ }),
401
+ /* @__PURE__ */ l("div", {
402
+ className: "scanner-camera-overlay__controls",
403
+ children: [
404
+ /* @__PURE__ */ c("button", {
405
+ type: "button",
406
+ className: "scanner-camera-overlay__cancel",
407
+ onClick: Y,
408
+ children: "Cancel"
409
+ }),
410
+ /* @__PURE__ */ l("div", {
411
+ className: "scanner-camera-overlay__capture",
412
+ children: [/* @__PURE__ */ c("button", {
413
+ type: "button",
414
+ className: "scanner-camera-overlay__shutter",
415
+ onClick: () => void ue(),
416
+ disabled: j !== "ready",
417
+ "aria-label": "Capture full-resolution photo",
418
+ children: /* @__PURE__ */ c("span", {})
419
+ }), /* @__PURE__ */ l("div", {
420
+ className: "scanner-camera-overlay__toggles",
421
+ children: [N?.autoCapture.visible && /* @__PURE__ */ l("label", { children: [/* @__PURE__ */ c("input", {
422
+ type: "checkbox",
423
+ checked: N.autoCapture.checked,
424
+ onChange: (e) => w.current?.setAutoCapture(e.target.checked)
425
+ }), "Auto-capture"] }), U?.torch.visible && /* @__PURE__ */ l("label", {
426
+ title: U.torch.automatic ? "Torch is controlled automatically from scene brightness" : void 0,
427
+ children: [/* @__PURE__ */ c("input", {
428
+ type: "checkbox",
429
+ checked: U.torch.on,
430
+ disabled: !U.torch.mutable,
431
+ onChange: (e) => void fe(e.target.checked)
432
+ }), U.torch.automatic ? "Auto torch" : "Torch"]
433
+ })]
434
+ })]
435
+ }),
436
+ /* @__PURE__ */ l("div", {
437
+ className: "scanner-camera-overlay__quality",
438
+ children: [/* @__PURE__ */ c("span", { children: R === "live-mirror" ? "Mirror" : "Camera" }), /* @__PURE__ */ c("strong", { children: X && Z ? `${X} × ${Z}` : "Measuring…" })]
439
+ })
440
+ ]
441
+ })
442
+ ]
443
+ });
444
+ }
445
+ //#endregion
446
+ export { m as ScannerCameraOverlay };
447
+
448
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","names":[],"sources":["../src/sdk/display-quad.ts","../src/live-overlay-geometry.ts","../src/components/ScannerCameraOverlay.tsx"],"sourcesContent":["import type { DocumentQuad, Point } from './types'\n\nfunction points(quad: DocumentQuad) {\n return [quad.topLeft, quad.topRight, quad.bottomRight, quad.bottomLeft]\n}\n\nfunction withPoints(next: Point[]): DocumentQuad {\n const [topLeft, topRight, bottomRight, bottomLeft] = next\n return {\n topLeft,\n topRight,\n bottomRight,\n bottomLeft,\n edges: {\n top: { start: topLeft, end: topRight },\n right: { start: topRight, end: bottomRight },\n bottom: { start: bottomRight, end: bottomLeft },\n left: { start: bottomLeft, end: topLeft },\n },\n }\n}\n\nfunction cloneQuad(quad: DocumentQuad) {\n return withPoints(points(quad).map((point) => ({ ...point })))\n}\n\nexport interface QuadDisplaySmootherOptions {\n response?: number\n snapDistance?: number\n}\n\n/**\n * Smooths only the displayed quad. Detector stability must continue to use raw\n * detections and must never consume this animated output.\n */\nexport class QuadDisplaySmoother {\n private current?: DocumentQuad\n private target?: DocumentQuad\n private readonly response: number\n private readonly snapDistance: number\n\n constructor(options: QuadDisplaySmootherOptions = {}) {\n this.response = options.response ?? 14\n this.snapDistance = options.snapDistance ?? 0.1\n }\n\n setTarget(quad: DocumentQuad, frameWidth: number, frameHeight: number) {\n const diagonal = Math.max(1, Math.hypot(frameWidth, frameHeight))\n const shouldSnap = !this.current || points(quad).some((point, index) => {\n const previous = points(this.current!)[index]\n return Math.hypot(point.x - previous.x, point.y - previous.y) / diagonal > this.snapDistance\n })\n this.target = cloneQuad(quad)\n if (shouldSnap) this.current = cloneQuad(quad)\n return { quad: this.current, snapped: shouldSnap }\n }\n\n step(deltaMs: number) {\n if (!this.current || !this.target) return this.current\n const alpha = 1 - Math.exp(-this.response * Math.max(0, deltaMs) / 1000)\n this.current = withPoints(points(this.current).map((point, index) => {\n const target = points(this.target!)[index]\n return {\n x: point.x + (target.x - point.x) * alpha,\n y: point.y + (target.y - point.y) * alpha,\n }\n }))\n return this.current\n }\n\n clear() {\n this.current = undefined\n this.target = undefined\n }\n\n getCurrent() {\n return this.current\n }\n}\n","import type { Point } from './sdk/types'\n\nexport type LivePreviewFit = 'contain' | 'cover'\n\nexport interface LiveOverlayTransform {\n viewBox: string\n preserveAspectRatio: 'none' | 'xMidYMid meet'\n scale: number\n offsetX: number\n offsetY: number\n}\n\nexport function liveOverlayTransform(\n sourceWidth: number,\n sourceHeight: number,\n renderedWidth: number,\n renderedHeight: number,\n fit: LivePreviewFit,\n): LiveOverlayTransform {\n const safeSourceWidth = Math.max(1, sourceWidth)\n const safeSourceHeight = Math.max(1, sourceHeight)\n const safeRenderedWidth = Math.max(1, renderedWidth)\n const safeRenderedHeight = Math.max(1, renderedHeight)\n const widthScale = safeRenderedWidth / safeSourceWidth\n const heightScale = safeRenderedHeight / safeSourceHeight\n const scale = fit === 'cover'\n ? Math.max(widthScale, heightScale)\n : Math.min(widthScale, heightScale)\n const offsetX = (safeRenderedWidth - safeSourceWidth * scale) / 2\n const offsetY = (safeRenderedHeight - safeSourceHeight * scale) / 2\n if (fit === 'contain') {\n return {\n viewBox: `0 0 ${safeSourceWidth} ${safeSourceHeight}`,\n preserveAspectRatio: 'xMidYMid meet',\n scale,\n offsetX,\n offsetY,\n }\n }\n const visibleWidth = safeRenderedWidth / scale\n const visibleHeight = safeRenderedHeight / scale\n return {\n viewBox: `${-offsetX / scale} ${-offsetY / scale} ${visibleWidth} ${visibleHeight}`,\n preserveAspectRatio: 'none',\n scale,\n offsetX,\n offsetY,\n }\n}\n\nexport function mapLiveSourcePoint(point: Point, transform: LiveOverlayTransform): Point {\n return {\n x: transform.offsetX + point.x * transform.scale,\n y: transform.offsetY + point.y * transform.scale,\n }\n}\n","import { useEffect, useRef, useState } from 'react'\nimport {\n detectBrowserEngine,\n formatCaptureDiagnosticsReport,\n NEAR_BLACK_LUMINANCE,\n startCamera,\n type CameraDiagnostics,\n type CameraOptions,\n type CameraPhoto,\n type CameraSession,\n type TorchMode,\n} from '../sdk/camera'\nimport {\n selectFinderHint,\n startFinder,\n type AutoCaptureMode,\n type FinderCapture,\n type FinderSession,\n type FinderStatus,\n} from '../sdk/finder'\nimport { QuadDisplaySmoother } from '../sdk/display-quad'\nimport type { DocumentQuad } from '../sdk/types'\nimport type { DocumentDetectorMode } from '../sdk/types'\nimport {\n liveOverlayTransform,\n type LivePreviewFit,\n} from '../live-overlay-geometry'\nimport './scanner-camera-overlay.css'\n\nexport interface ScannerCameraOverlayCapture extends FinderCapture {\n method: CameraPhoto['method']\n settings: MediaTrackSettings\n fallbackReason?: CameraPhoto['fallbackReason']\n luminance?: number\n diagnostics?: CameraDiagnostics\n displayedQuad?: DocumentQuad\n displaySourceWidth?: number\n displaySourceHeight?: number\n}\n\nexport interface ScannerCameraOverlayProps {\n open: boolean\n autoCapture?: AutoCaptureMode\n /** Camera torch policy. Defaults to `defaultOff`. */\n torch?: TorchMode\n cameraOptions?: CameraOptions\n onCapture: (capture: ScannerCameraOverlayCapture) => void | Promise<void>\n onClose: () => void\n onError?: (error: Error) => void\n onSettings?: (settings: MediaTrackSettings) => void\n onFinderStatus?: (status: FinderStatus) => void\n className?: string\n title?: string\n previewFit?: LivePreviewFit\n detector?: DocumentDetectorMode\n modelUrl?: string\n ortWasmPaths?: string\n detectionIntervalMs?: number\n}\n\ntype OverlayPhase = 'starting' | 'ready' | 'capturing' | 'error'\n\nexport function ScannerCameraOverlay({\n open,\n autoCapture = 'defaultOn',\n torch = 'defaultOff',\n cameraOptions,\n onCapture,\n onClose,\n onError,\n onSettings,\n onFinderStatus,\n className = '',\n title = 'Scan a document',\n previewFit = 'cover',\n detector = 'classical',\n modelUrl,\n ortWasmPaths,\n detectionIntervalMs,\n}: ScannerCameraOverlayProps) {\n const videoRef = useRef<HTMLVideoElement>(null)\n const cameraRef = useRef<CameraSession | undefined>(undefined)\n const finderRef = useRef<FinderSession | undefined>(undefined)\n const finderStatusRef = useRef<FinderStatus | undefined>(undefined)\n const latestPhotoRef = useRef<CameraPhoto | undefined>(undefined)\n const capturedDisplayRef = useRef<{\n quad?: DocumentQuad\n sourceWidth?: number\n sourceHeight?: number\n }>({})\n const displaySmootherRef = useRef(new QuadDisplaySmoother())\n // Finder ticks continue after a failed capture, so the error must survive\n // the status updates that would otherwise restore the \"ready\" phase.\n const captureErrorRef = useRef(false)\n const callbacksRef = useRef({ onCapture, onError, onSettings, onFinderStatus })\n const [phase, setPhase] = useState<OverlayPhase>('starting')\n const [finderStatus, setFinderStatus] = useState<FinderStatus>()\n const [displayQuad, setDisplayQuad] = useState<DocumentQuad>()\n const [previewSize, setPreviewSize] = useState({ width: 1, height: 1 })\n const [settings, setSettings] = useState<MediaTrackSettings>()\n const [captureMethod, setCaptureMethod] = useState<CameraPhoto['method']>()\n const [error, setError] = useState('')\n const [attempt, setAttempt] = useState(0)\n const [diagnostics, setDiagnostics] = useState<CameraDiagnostics>()\n const [shutterDiagnostics, setShutterDiagnostics] = useState<CameraDiagnostics>()\n const [copyState, setCopyState] = useState<'idle' | 'copied' | 'failed'>('idle')\n\n useEffect(() => {\n callbacksRef.current = { onCapture, onError, onSettings, onFinderStatus }\n }, [onCapture, onError, onSettings, onFinderStatus])\n\n useEffect(() => {\n if (!open) return\n const previousOverflow = document.body.style.overflow\n document.body.style.overflow = 'hidden'\n return () => {\n document.body.style.overflow = previousOverflow\n }\n }, [open])\n\n useEffect(() => {\n if (!open) return\n const video = videoRef.current\n if (!video) return\n const updateSize = () => {\n const bounds = video.getBoundingClientRect()\n setPreviewSize({ width: bounds.width, height: bounds.height })\n }\n updateSize()\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', updateSize)\n return () => window.removeEventListener('resize', updateSize)\n }\n const observer = new ResizeObserver(updateSize)\n observer.observe(video)\n return () => observer.disconnect()\n }, [open])\n\n useEffect(() => {\n if (!open) return\n const poll = window.setInterval(() => {\n const current = cameraRef.current?.getDiagnostics()\n if (current) setDiagnostics(current)\n }, 500)\n return () => window.clearInterval(poll)\n }, [open, attempt])\n\n useEffect(() => {\n if (!open) return\n let animationFrame = 0\n let previousTime = performance.now()\n const animate = (time: number) => {\n const next = displaySmootherRef.current.step(time - previousTime)\n previousTime = time\n if (next) setDisplayQuad(next)\n animationFrame = requestAnimationFrame(animate)\n }\n animationFrame = requestAnimationFrame(animate)\n return () => cancelAnimationFrame(animationFrame)\n }, [open])\n\n useEffect(() => {\n if (!open) return\n const video = videoRef.current\n if (!video) return\n let cancelled = false\n\n const stop = () => {\n finderRef.current?.stop()\n finderRef.current = undefined\n cameraRef.current?.stop()\n cameraRef.current = undefined\n latestPhotoRef.current = undefined\n finderStatusRef.current = undefined\n capturedDisplayRef.current = {}\n }\n\n const start = async () => {\n stop()\n captureErrorRef.current = false\n setPhase('starting')\n setError('')\n setFinderStatus(undefined)\n setCaptureMethod(undefined)\n setShutterDiagnostics(undefined)\n setCopyState('idle')\n try {\n const camera = await startCamera(video, { ...cameraOptions, torch })\n if (cancelled) {\n camera.stop()\n return\n }\n cameraRef.current = camera\n const actualSettings = camera.getSettings()\n setSettings(actualSettings)\n callbacksRef.current.onSettings?.(actualSettings)\n console.info('[ScannerCameraOverlay] camera settings', actualSettings)\n finderRef.current = await startFinder({\n source: video,\n autoCapture,\n intervalMs: detectionIntervalMs,\n detection: {\n detector,\n modelUrl,\n ortWasmPaths,\n },\n onStatus: (status) => {\n finderStatusRef.current = status\n setFinderStatus(status)\n callbacksRef.current.onFinderStatus?.(status)\n if (status.quad && status.sourceWidth && status.sourceHeight) {\n const update = displaySmootherRef.current.setTarget(\n status.quad,\n status.sourceWidth,\n status.sourceHeight,\n )\n setDisplayQuad(update.quad)\n } else {\n displaySmootherRef.current.clear()\n setDisplayQuad(undefined)\n }\n if (status.state !== 'captured' && !captureErrorRef.current) setPhase('ready')\n },\n captureFrame: async () => {\n setPhase('capturing')\n capturedDisplayRef.current = {\n quad: displaySmootherRef.current.getCurrent(),\n sourceWidth: finderStatusRef.current?.sourceWidth,\n sourceHeight: finderStatusRef.current?.sourceHeight,\n }\n const photo = await camera.capturePhoto()\n latestPhotoRef.current = photo\n setCaptureMethod(photo.method)\n setShutterDiagnostics(photo.diagnostics)\n setDiagnostics(photo.diagnostics)\n if (photo.luminance <= NEAR_BLACK_LUMINANCE) {\n throw new Error(\n `The captured frame was blank (luminance ${photo.luminance.toFixed(1)} via ${photo.method}). Keep the scanner visible while capturing and retake.`,\n )\n }\n return photo.frame\n },\n onCaptureError: (captureError) => {\n captureErrorRef.current = true\n setPhase('error')\n setError(captureError.message)\n const live = cameraRef.current?.getDiagnostics()\n if (live) setDiagnostics(live)\n callbacksRef.current.onError?.(captureError)\n },\n onCapture: async (capture) => {\n const photo = latestPhotoRef.current\n // Finder has already copied the final frame and emitted its\n // captured state. Let shutter/flash feedback paint before the host\n // dismisses this overlay and starts crop/OCR work.\n await new Promise((resolve) => window.setTimeout(resolve, 140))\n await callbacksRef.current.onCapture({\n ...capture,\n method: photo?.method ?? 'video-frame',\n settings: photo?.settings ?? camera.getSettings(),\n fallbackReason: photo?.fallbackReason,\n luminance: photo?.luminance,\n diagnostics: photo?.diagnostics,\n displayedQuad: capturedDisplayRef.current.quad,\n displaySourceWidth: capturedDisplayRef.current.sourceWidth,\n displaySourceHeight: capturedDisplayRef.current.sourceHeight,\n })\n },\n })\n } catch (cause) {\n if (cancelled) return\n stop()\n const nextError = cause instanceof Error ? cause : new Error('Camera access failed.')\n setError(nextError.message)\n setPhase('error')\n callbacksRef.current.onError?.(nextError)\n }\n }\n\n void start()\n return () => {\n cancelled = true\n stop()\n }\n }, [\n open,\n autoCapture,\n torch,\n cameraOptions,\n detector,\n modelUrl,\n ortWasmPaths,\n detectionIntervalMs,\n attempt,\n ])\n\n if (!open) return null\n\n const close = () => {\n finderRef.current?.stop()\n cameraRef.current?.stop()\n onClose()\n }\n const capture = async () => {\n try {\n await finderRef.current?.capture()\n } catch (cause) {\n const nextError = cause instanceof Error ? cause : new Error('Could not capture the camera frame.')\n captureErrorRef.current = true\n setError(nextError.message)\n const live = cameraRef.current?.getDiagnostics()\n if (live) setDiagnostics(live)\n if (latestPhotoRef.current?.diagnostics) setShutterDiagnostics(latestPhotoRef.current.diagnostics)\n setPhase('error')\n onError?.(nextError)\n }\n }\n const retry = () => {\n captureErrorRef.current = false\n setError('')\n setShutterDiagnostics(undefined)\n setCopyState('idle')\n const liveCamera = cameraRef.current\n setPhase(liveCamera ? 'ready' : 'starting')\n if (!liveCamera) setAttempt((value) => value + 1)\n }\n const setTorch = async (enabled: boolean) => {\n const camera = cameraRef.current\n if (!camera) return\n await camera.setTorch(enabled)\n setDiagnostics(camera.getDiagnostics())\n }\n const copyReport = async () => {\n const live = cameraRef.current?.getDiagnostics() ?? diagnostics\n const report = formatCaptureDiagnosticsReport({\n error: error || undefined,\n captureMethod,\n luminance: latestPhotoRef.current?.luminance,\n fallbackReason: latestPhotoRef.current?.fallbackReason,\n shutter: shutterDiagnostics ?? latestPhotoRef.current?.diagnostics,\n live,\n finder: finderStatus\n ? {\n state: finderStatus.state,\n confidence: finderStatus.confidence,\n stableFrames: finderStatus.stableFrames,\n requiredStableFrames: finderStatus.requiredStableFrames,\n detector: finderStatus.detector,\n modelStatus: finderStatus.modelStatus,\n sourceWidth: finderStatus.sourceWidth,\n sourceHeight: finderStatus.sourceHeight,\n }\n : undefined,\n })\n try {\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(report)\n } else {\n const field = document.createElement('textarea')\n field.value = report\n field.setAttribute('readonly', '')\n field.style.position = 'fixed'\n field.style.left = '-9999px'\n document.body.append(field)\n field.select()\n const copied = document.execCommand('copy')\n field.remove()\n if (!copied) throw new Error('Clipboard copy is unavailable.')\n }\n setCopyState('copied')\n } catch {\n setCopyState('failed')\n }\n }\n const width = settings?.width\n const height = settings?.height\n const engine = diagnostics?.engine ?? detectBrowserEngine()\n const liveDiagnostics = diagnostics\n const overlayTransform = finderStatus?.sourceWidth && finderStatus.sourceHeight\n ? liveOverlayTransform(\n finderStatus.sourceWidth,\n finderStatus.sourceHeight,\n previewSize.width,\n previewSize.height,\n previewFit,\n )\n : undefined\n const detectorStatus = finderStatus?.modelStatus === 'fallback'\n ? 'classical fallback'\n : finderStatus?.modelStatus === 'failed'\n ? 'ML failed'\n : finderStatus?.detector === 'ml'\n ? `ML ${finderStatus.modelProvider ?? ''}`.trim()\n : detector === 'ml' || detector === 'auto'\n ? 'ML loading'\n : 'classical'\n const guidanceHint = finderStatus\n ? selectFinderHint(finderStatus.guidance, finderStatus.lighting)\n : undefined\n\n return (\n <div\n className={`scanner-camera-overlay ${finderStatus?.state === 'captured' ? 'is-captured' : ''} ${className}`.trim()}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n >\n <video\n ref={videoRef}\n className=\"scanner-camera-overlay__video\"\n muted\n autoPlay\n playsInline\n style={{ objectFit: previewFit }}\n aria-label=\"Rear camera preview\"\n />\n\n {displayQuad && finderStatus?.sourceWidth && finderStatus.sourceHeight && (\n <svg\n className={`scanner-camera-overlay__quad ${finderStatus.state}`}\n viewBox={overlayTransform?.viewBox}\n preserveAspectRatio={overlayTransform?.preserveAspectRatio}\n aria-label={`${finderStatus.state} document boundary`}\n >\n <polygon points={`${displayQuad.topLeft.x},${displayQuad.topLeft.y} ${displayQuad.topRight.x},${displayQuad.topRight.y} ${displayQuad.bottomRight.x},${displayQuad.bottomRight.y} ${displayQuad.bottomLeft.x},${displayQuad.bottomLeft.y}`} />\n </svg>\n )}\n\n <div className=\"scanner-camera-overlay__topbar\">\n <div>\n <strong>{title}</strong>\n <span aria-live=\"polite\">\n {phase === 'starting' && 'Starting rear camera…'}\n {phase === 'ready' && (guidanceHint ?? 'Place the document in the frame')}\n {phase === 'capturing' && 'Capturing full resolution…'}\n {phase === 'error' && 'Camera unavailable'}\n </span>\n </div>\n <button type=\"button\" onClick={close} aria-label=\"Close camera\">×</button>\n </div>\n\n {phase === 'error' ? (\n <div className=\"scanner-camera-overlay__message\" role=\"alert\">\n <strong>{diagnostics ? 'Capture failed' : 'Could not open the camera'}</strong>\n <p>{error}</p>\n <div>\n <button type=\"button\" onClick={retry}>Try again</button>\n <button type=\"button\" onClick={() => void copyReport()}>\n {copyState === 'copied' ? 'Copied' : copyState === 'failed' ? 'Copy failed' : 'Copy report'}\n </button>\n <button type=\"button\" onClick={close}>Cancel</button>\n </div>\n </div>\n ) : phase === 'starting' ? (\n <div className=\"scanner-camera-overlay__message\" aria-live=\"polite\">\n <span className=\"scanner-camera-overlay__spinner\" />\n <strong>Requesting the highest practical resolution</strong>\n <p>Allow camera access to continue.</p>\n </div>\n ) : null}\n\n <div className=\"scanner-camera-overlay__status\" aria-live=\"polite\">\n <span className={finderStatus?.state ?? 'detecting'} />\n {finderStatus?.state ?? 'detecting'}\n {finderStatus ? ` · ${Math.round(finderStatus.confidence * 100)}% · ${finderStatus.stableFrames}/${finderStatus.requiredStableFrames}` : ''}\n {` · ${detectorStatus}`}\n {finderStatus?.inferenceMs !== undefined ? ` · ${Math.round(finderStatus.inferenceMs)}ms` : ''}\n {width && height ? ` · ${width}×${height}` : ''}\n </div>\n\n <dl className=\"scanner-camera-overlay__diagnostics\" aria-label=\"Camera diagnostics\">\n <div>\n <dt>engine</dt>\n <dd>{engine.engine}/{engine.browser}{engine.iosWebKit ? ' ios' : ''}</dd>\n </div>\n <div>\n <dt>video</dt>\n <dd>\n {liveDiagnostics\n ? `${liveDiagnostics.videoWidth}×${liveDiagnostics.videoHeight} rs${liveDiagnostics.readyState}${liveDiagnostics.paused ? ' paused' : ''}${liveDiagnostics.rendered ? '' : ' hidden'}`\n : 'starting'}\n </dd>\n </div>\n <div>\n <dt>track</dt>\n <dd>\n {liveDiagnostics\n ? `${liveDiagnostics.trackReadyState}${liveDiagnostics.trackMuted ? ' muted' : ''}${liveDiagnostics.trackEnabled ? '' : ' disabled'}`\n : '—'}\n </dd>\n </div>\n <div>\n <dt>torch</dt>\n <dd>\n {liveDiagnostics\n ? `${liveDiagnostics.torch.mode} · ${liveDiagnostics.torch.supported ? (liveDiagnostics.torch.on ? 'on' : 'off') : 'unsupported'}`\n : 'starting'}\n </dd>\n </div>\n <div>\n <dt>luma</dt>\n <dd>\n {liveDiagnostics\n ? `live ${liveDiagnostics.liveLuminance.toFixed(1)} · mirror ${liveDiagnostics.mirrorLuminance.toFixed(1)}${Number.isFinite(liveDiagnostics.mirrorAgeMs) ? ` (${Math.round(liveDiagnostics.mirrorAgeMs)}ms)` : ' (none)'}`\n : '—'}\n </dd>\n </div>\n <div>\n <dt>path</dt>\n <dd>\n {captureMethod ?? 'video-frame / live-mirror'}\n </dd>\n </div>\n {shutterDiagnostics ? (\n <div>\n <dt>shutter</dt>\n <dd>\n {`live ${shutterDiagnostics.liveLuminance.toFixed(1)} · mirror ${shutterDiagnostics.mirrorLuminance.toFixed(1)}${Number.isFinite(shutterDiagnostics.mirrorAgeMs) ? ` (${Math.round(shutterDiagnostics.mirrorAgeMs)}ms)` : ' (none)'}`}\n </dd>\n </div>\n ) : null}\n <div>\n <dt>share</dt>\n <dd>\n <button\n type=\"button\"\n className=\"scanner-camera-overlay__copy\"\n onClick={() => void copyReport()}\n >\n {copyState === 'copied' ? 'Copied report' : copyState === 'failed' ? 'Copy failed' : 'Copy report'}\n </button>\n </dd>\n </div>\n </dl>\n\n <div className=\"scanner-camera-overlay__controls\">\n <button type=\"button\" className=\"scanner-camera-overlay__cancel\" onClick={close}>Cancel</button>\n <div className=\"scanner-camera-overlay__capture\">\n <button\n type=\"button\"\n className=\"scanner-camera-overlay__shutter\"\n onClick={() => void capture()}\n disabled={phase !== 'ready'}\n aria-label=\"Capture full-resolution photo\"\n >\n <span />\n </button>\n <div className=\"scanner-camera-overlay__toggles\">\n {finderStatus?.autoCapture.visible && (\n <label>\n <input\n type=\"checkbox\"\n checked={finderStatus.autoCapture.checked}\n onChange={(event) => finderRef.current?.setAutoCapture(event.target.checked)}\n />\n Auto-capture\n </label>\n )}\n {diagnostics?.torch.visible && (\n <label title={diagnostics.torch.automatic ? 'Torch is controlled automatically from scene brightness' : undefined}>\n <input\n type=\"checkbox\"\n checked={diagnostics.torch.on}\n disabled={!diagnostics.torch.mutable}\n onChange={(event) => void setTorch(event.target.checked)}\n />\n {diagnostics.torch.automatic ? 'Auto torch' : 'Torch'}\n </label>\n )}\n </div>\n </div>\n <div className=\"scanner-camera-overlay__quality\">\n <span>{captureMethod === 'live-mirror' ? 'Mirror' : 'Camera'}</span>\n <strong>{width && height ? `${width} × ${height}` : 'Measuring…'}</strong>\n </div>\n </div>\n </div>\n )\n}\n"],"mappings":";;;;AAEA,SAAS,EAAO,GAAoB;CAClC,OAAO;EAAC,EAAK;EAAS,EAAK;EAAU,EAAK;EAAa,EAAK;CAAU;AACxE;AAEA,SAAS,EAAW,GAA6B;CAC/C,IAAM,CAAC,GAAS,GAAU,GAAa,KAAc;CACrD,OAAO;EACL;EACA;EACA;EACA;EACA,OAAO;GACL,KAAK;IAAE,OAAO;IAAS,KAAK;GAAS;GACrC,OAAO;IAAE,OAAO;IAAU,KAAK;GAAY;GAC3C,QAAQ;IAAE,OAAO;IAAa,KAAK;GAAW;GAC9C,MAAM;IAAE,OAAO;IAAY,KAAK;GAAQ;EAC1C;CACF;AACF;AAEA,SAAS,EAAU,GAAoB;CACrC,OAAO,EAAW,EAAO,CAAI,CAAC,CAAC,KAAK,OAAW,EAAE,GAAG,EAAM,EAAE,CAAC;AAC/D;AAWA,IAAa,IAAb,MAAiC;CAC/B;CACA;CACA;CACA;CAEA,YAAY,IAAsC,CAAC,GAAG;EAEpD,AADA,KAAK,WAAW,EAAQ,YAAY,IACpC,KAAK,eAAe,EAAQ,gBAAgB;CAC9C;CAEA,UAAU,GAAoB,GAAoB,GAAqB;EACrE,IAAM,IAAW,KAAK,IAAI,GAAG,KAAK,MAAM,GAAY,CAAW,CAAC,GAC1D,IAAa,CAAC,KAAK,WAAW,EAAO,CAAI,CAAC,CAAC,MAAM,GAAO,MAAU;GACtE,IAAM,IAAW,EAAO,KAAK,OAAQ,CAAC,CAAC;GACvC,OAAO,KAAK,MAAM,EAAM,IAAI,EAAS,GAAG,EAAM,IAAI,EAAS,CAAC,IAAI,IAAW,KAAK;EAClF,CAAC;EAGD,OAFA,KAAK,SAAS,EAAU,CAAI,GACxB,MAAY,KAAK,UAAU,EAAU,CAAI,IACtC;GAAE,MAAM,KAAK;GAAS,SAAS;EAAW;CACnD;CAEA,KAAK,GAAiB;EACpB,IAAI,CAAC,KAAK,WAAW,CAAC,KAAK,QAAQ,OAAO,KAAK;EAC/C,IAAM,IAAQ,IAAI,KAAK,IAAI,CAAC,KAAK,WAAW,KAAK,IAAI,GAAG,CAAO,IAAI,GAAI;EAQvE,OAPA,KAAK,UAAU,EAAW,EAAO,KAAK,OAAO,CAAC,CAAC,KAAK,GAAO,MAAU;GACnE,IAAM,IAAS,EAAO,KAAK,MAAO,CAAC,CAAC;GACpC,OAAO;IACL,GAAG,EAAM,KAAK,EAAO,IAAI,EAAM,KAAK;IACpC,GAAG,EAAM,KAAK,EAAO,IAAI,EAAM,KAAK;GACtC;EACF,CAAC,CAAC,GACK,KAAK;CACd;CAEA,QAAQ;EAEN,AADA,KAAK,UAAU,KAAA,GACf,KAAK,SAAS,KAAA;CAChB;CAEA,aAAa;EACX,OAAO,KAAK;CACd;AACF;;;AClEA,SAAgB,GACd,GACA,GACA,GACA,GACA,GACsB;CACtB,IAAM,IAAkB,KAAK,IAAI,GAAG,CAAW,GACzC,IAAmB,KAAK,IAAI,GAAG,CAAY,GAC3C,IAAoB,KAAK,IAAI,GAAG,CAAa,GAC7C,IAAqB,KAAK,IAAI,GAAG,CAAc,GAC/C,IAAa,IAAoB,GACjC,IAAc,IAAqB,GACnC,IAAQ,MAAQ,UAClB,KAAK,IAAI,GAAY,CAAW,IAChC,KAAK,IAAI,GAAY,CAAW,GAC9B,KAAW,IAAoB,IAAkB,KAAS,GAC1D,KAAW,IAAqB,IAAmB,KAAS;CAClE,IAAI,MAAQ,WACV,OAAO;EACL,SAAS,OAAO,EAAgB,GAAG;EACnC,qBAAqB;EACrB;EACA;EACA;CACF;CAEF,IAAM,KAAe,IAAoB,GACnC,IAAgB,IAAqB;CAC3C,OAAO;EACL,SAAS,GAAG,CAAC,IAAU,EAAM,GAAG,CAAC,IAAU,EAAM,GAAG,GAAa,GAAG;EACpE,qBAAqB;EACrB;EACA;EACA;CACF;AACF;;;ACcA,SAAgB,EAAqB,EACnC,SACA,iBAAc,aACd,WAAQ,cACR,kBACA,cACA,aACA,YACA,eACA,mBACA,gBAAY,IACZ,YAAQ,mBACR,gBAAa,SACb,cAAW,aACX,aACA,kBACA,2BAC4B;CAC5B,IAAM,IAAW,EAAyB,IAAI,GACxC,IAAY,EAAkC,KAAA,CAAS,GACvD,IAAY,EAAkC,KAAA,CAAS,GACvD,IAAkB,EAAiC,KAAA,CAAS,GAC5D,IAAiB,EAAgC,KAAA,CAAS,GAC1D,IAAqB,EAIxB,CAAC,CAAC,GACC,IAAqB,EAAO,IAAI,EAAoB,CAAC,GAGrD,IAAkB,EAAO,EAAK,GAC9B,IAAe,EAAO;EAAE;EAAW;EAAS;EAAY;CAAe,CAAC,GACxE,CAAC,GAAO,KAAY,EAAuB,UAAU,GACrD,CAAC,GAAc,MAAmB,EAAuB,GACzD,CAAC,GAAa,KAAkB,EAAuB,GACvD,CAAC,GAAa,MAAkB,EAAS;EAAE,OAAO;EAAG,QAAQ;CAAE,CAAC,GAChE,CAAC,GAAU,MAAe,EAA6B,GACvD,CAAC,GAAe,KAAoB,EAAgC,GACpE,CAAC,GAAO,KAAY,EAAS,EAAE,GAC/B,CAAC,GAAS,MAAc,EAAS,CAAC,GAClC,CAAC,GAAa,KAAkB,EAA4B,GAC5D,CAAC,GAAoB,KAAyB,EAA4B,GAC1E,CAAC,GAAW,KAAgB,EAAuC,MAAM;CA+L/E,IA7LA,QAAgB;EACd,EAAa,UAAU;GAAE;GAAW;GAAS;GAAY;EAAe;CAC1E,GAAG;EAAC;EAAW;EAAS;EAAY;CAAc,CAAC,GAEnD,QAAgB;EACd,IAAI,CAAC,GAAM;EACX,IAAM,IAAmB,SAAS,KAAK,MAAM;EAE7C,OADA,SAAS,KAAK,MAAM,WAAW,gBAClB;GACX,SAAS,KAAK,MAAM,WAAW;EACjC;CACF,GAAG,CAAC,CAAI,CAAC,GAET,QAAgB;EACd,IAAI,CAAC,GAAM;EACX,IAAM,IAAQ,EAAS;EACvB,IAAI,CAAC,GAAO;EACZ,IAAM,UAAmB;GACvB,IAAM,IAAS,EAAM,sBAAsB;GAC3C,GAAe;IAAE,OAAO,EAAO;IAAO,QAAQ,EAAO;GAAO,CAAC;EAC/D;EAEA,IADA,EAAW,GACP,OAAO,iBAAmB,KAE5B,OADA,OAAO,iBAAiB,UAAU,CAAU,SAC/B,OAAO,oBAAoB,UAAU,CAAU;EAE9D,IAAM,IAAW,IAAI,eAAe,CAAU;EAE9C,OADA,EAAS,QAAQ,CAAK,SACT,EAAS,WAAW;CACnC,GAAG,CAAC,CAAI,CAAC,GAET,QAAgB;EACd,IAAI,CAAC,GAAM;EACX,IAAM,IAAO,OAAO,kBAAkB;GACpC,IAAM,IAAU,EAAU,SAAS,eAAe;GAClD,AAAI,KAAS,EAAe,CAAO;EACrC,GAAG,GAAG;EACN,aAAa,OAAO,cAAc,CAAI;CACxC,GAAG,CAAC,GAAM,CAAO,CAAC,GAElB,QAAgB;EACd,IAAI,CAAC,GAAM;EACX,IAAI,IAAiB,GACjB,IAAe,YAAY,IAAI,GAC7B,KAAW,MAAiB;GAChC,IAAM,IAAO,EAAmB,QAAQ,KAAK,IAAO,CAAY;GAGhE,AAFA,IAAe,GACX,KAAM,EAAe,CAAI,GAC7B,IAAiB,sBAAsB,CAAO;EAChD;EAEA,OADA,IAAiB,sBAAsB,CAAO,SACjC,qBAAqB,CAAc;CAClD,GAAG,CAAC,CAAI,CAAC,GAET,QAAgB;EACd,IAAI,CAAC,GAAM;EACX,IAAM,IAAQ,EAAS;EACvB,IAAI,CAAC,GAAO;EACZ,IAAI,IAAY,IAEV,UAAa;GAOjB,AANA,EAAU,SAAS,KAAK,GACxB,EAAU,UAAU,KAAA,GACpB,EAAU,SAAS,KAAK,GACxB,EAAU,UAAU,KAAA,GACpB,EAAe,UAAU,KAAA,GACzB,EAAgB,UAAU,KAAA,GAC1B,EAAmB,UAAU,CAAC;EAChC;EAyGA,QADA,YAtG0B;GAQxB,AAPA,EAAK,GACL,EAAgB,UAAU,IAC1B,EAAS,UAAU,GACnB,EAAS,EAAE,GACX,GAAgB,KAAA,CAAS,GACzB,EAAiB,KAAA,CAAS,GAC1B,EAAsB,KAAA,CAAS,GAC/B,EAAa,MAAM;GACnB,IAAI;IACF,IAAM,IAAS,MAAM,EAAY,GAAO;KAAE,GAAG;KAAe;IAAM,CAAC;IACnE,IAAI,GAAW;KACb,EAAO,KAAK;KACZ;IACF;IACA,EAAU,UAAU;IACpB,IAAM,IAAiB,EAAO,YAAY;IAI1C,AAHA,GAAY,CAAc,GAC1B,EAAa,QAAQ,aAAa,CAAc,GAChD,QAAQ,KAAK,0CAA0C,CAAc,GACrE,EAAU,UAAU,MAAM,EAAY;KACpC,QAAQ;KACR;KACA,YAAY;KACZ,WAAW;MACT;MACA;MACA;KACF;KACA,WAAW,MAAW;MAIpB,IAHA,EAAgB,UAAU,GAC1B,GAAgB,CAAM,GACtB,EAAa,QAAQ,iBAAiB,CAAM,GACxC,EAAO,QAAQ,EAAO,eAAe,EAAO,cAAc;OAC5D,IAAM,IAAS,EAAmB,QAAQ,UACxC,EAAO,MACP,EAAO,aACP,EAAO,YACT;OACA,EAAe,EAAO,IAAI;MAC5B,OAEE,AADA,EAAmB,QAAQ,MAAM,GACjC,EAAe,KAAA,CAAS;MAE1B,AAAI,EAAO,UAAU,cAAc,CAAC,EAAgB,WAAS,EAAS,OAAO;KAC/E;KACA,cAAc,YAAY;MAExB,AADA,EAAS,WAAW,GACpB,EAAmB,UAAU;OAC3B,MAAM,EAAmB,QAAQ,WAAW;OAC5C,aAAa,EAAgB,SAAS;OACtC,cAAc,EAAgB,SAAS;MACzC;MACA,IAAM,IAAQ,MAAM,EAAO,aAAa;MAKxC,IAJA,EAAe,UAAU,GACzB,EAAiB,EAAM,MAAM,GAC7B,EAAsB,EAAM,WAAW,GACvC,EAAe,EAAM,WAAW,GAC5B,EAAM,aAAA,IACR,MAAU,MACR,2CAA2C,EAAM,UAAU,QAAQ,CAAC,EAAE,OAAO,EAAM,OAAO,wDAC5F;MAEF,OAAO,EAAM;KACf;KACA,iBAAiB,MAAiB;MAGhC,AAFA,EAAgB,UAAU,IAC1B,EAAS,OAAO,GAChB,EAAS,EAAa,OAAO;MAC7B,IAAM,IAAO,EAAU,SAAS,eAAe;MAE/C,AADI,KAAM,EAAe,CAAI,GAC7B,EAAa,QAAQ,UAAU,CAAY;KAC7C;KACA,WAAW,OAAO,MAAY;MAC5B,IAAM,IAAQ,EAAe;MAK7B,AADA,MAAM,IAAI,SAAS,MAAY,OAAO,WAAW,GAAS,GAAG,CAAC,GAC9D,MAAM,EAAa,QAAQ,UAAU;OACnC,GAAG;OACH,QAAQ,GAAO,UAAU;OACzB,UAAU,GAAO,YAAY,EAAO,YAAY;OAChD,gBAAgB,GAAO;OACvB,WAAW,GAAO;OAClB,aAAa,GAAO;OACpB,eAAe,EAAmB,QAAQ;OAC1C,oBAAoB,EAAmB,QAAQ;OAC/C,qBAAqB,EAAmB,QAAQ;MAClD,CAAC;KACH;IACF,CAAC;GACH,SAAS,GAAO;IACd,IAAI,GAAW;IACf,EAAK;IACL,IAAM,IAAY,aAAiB,QAAQ,IAAQ,gBAAI,MAAM,uBAAuB;IAGpF,AAFA,EAAS,EAAU,OAAO,GAC1B,EAAS,OAAO,GAChB,EAAa,QAAQ,UAAU,CAAS;GAC1C;EACF,EAEK,CAAM,SACE;GAEX,AADA,IAAY,IACZ,EAAK;EACP;CACF,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,GAEG,CAAC,GAAM,OAAO;CAElB,IAAM,UAAc;EAGlB,AAFA,EAAU,SAAS,KAAK,GACxB,EAAU,SAAS,KAAK,GACxB,GAAQ;CACV,GACM,KAAU,YAAY;EAC1B,IAAI;GACF,MAAM,EAAU,SAAS,QAAQ;EACnC,SAAS,GAAO;GACd,IAAM,IAAY,aAAiB,QAAQ,IAAQ,gBAAI,MAAM,qCAAqC;GAElG,AADA,EAAgB,UAAU,IAC1B,EAAS,EAAU,OAAO;GAC1B,IAAM,IAAO,EAAU,SAAS,eAAe;GAI/C,AAHI,KAAM,EAAe,CAAI,GACzB,EAAe,SAAS,eAAa,EAAsB,EAAe,QAAQ,WAAW,GACjG,EAAS,OAAO,GAChB,IAAU,CAAS;EACrB;CACF,GACM,WAAc;EAIlB,AAHA,EAAgB,UAAU,IAC1B,EAAS,EAAE,GACX,EAAsB,KAAA,CAAS,GAC/B,EAAa,MAAM;EACnB,IAAM,IAAa,EAAU;EAE7B,AADA,EAAS,IAAa,UAAU,UAAU,GACrC,KAAY,IAAY,MAAU,IAAQ,CAAC;CAClD,GACM,KAAW,OAAO,MAAqB;EAC3C,IAAM,IAAS,EAAU;EACpB,MACL,MAAM,EAAO,SAAS,CAAO,GAC7B,EAAe,EAAO,eAAe,CAAC;CACxC,GACM,KAAa,YAAY;EAC7B,IAAM,IAAO,EAAU,SAAS,eAAe,KAAK,GAC9C,IAAS,EAA+B;GAC5C,OAAO,KAAS,KAAA;GAChB;GACA,WAAW,EAAe,SAAS;GACnC,gBAAgB,EAAe,SAAS;GACxC,SAAS,KAAsB,EAAe,SAAS;GACvD;GACA,QAAQ,IACJ;IACA,OAAO,EAAa;IACpB,YAAY,EAAa;IACzB,cAAc,EAAa;IAC3B,sBAAsB,EAAa;IACnC,UAAU,EAAa;IACvB,aAAa,EAAa;IAC1B,aAAa,EAAa;IAC1B,cAAc,EAAa;GAC7B,IACE,KAAA;EACN,CAAC;EACD,IAAI;GACF,IAAI,UAAU,WAAW,WACvB,MAAM,UAAU,UAAU,UAAU,CAAM;QACrC;IACL,IAAM,IAAQ,SAAS,cAAc,UAAU;IAM/C,AALA,EAAM,QAAQ,GACd,EAAM,aAAa,YAAY,EAAE,GACjC,EAAM,MAAM,WAAW,SACvB,EAAM,MAAM,OAAO,WACnB,SAAS,KAAK,OAAO,CAAK,GAC1B,EAAM,OAAO;IACb,IAAM,IAAS,SAAS,YAAY,MAAM;IAE1C,IADA,EAAM,OAAO,GACT,CAAC,GAAQ,MAAU,MAAM,gCAAgC;GAC/D;GACA,EAAa,QAAQ;EACvB,QAAQ;GACN,EAAa,QAAQ;EACvB;CACF,GACM,IAAQ,GAAU,OAClB,IAAS,GAAU,QACnB,IAAS,GAAa,UAAU,EAAoB,GACpD,IAAkB,GAClB,KAAmB,GAAc,eAAe,EAAa,eAC/D,GACA,EAAa,aACb,EAAa,cACb,EAAY,OACZ,EAAY,QACZ,CACF,IACE,KAAA,GACE,KAAiB,GAAc,gBAAgB,aACjD,uBACA,GAAc,gBAAgB,WAC5B,cACA,GAAc,aAAa,OACzB,MAAM,EAAa,iBAAiB,KAAK,KAAK,IAC9C,MAAa,QAAQ,MAAa,SAChC,eACA,aACJ,KAAe,IACjB,EAAiB,EAAa,UAAU,EAAa,QAAQ,IAC7D,KAAA;CAEJ,OACE,kBAAC,OAAD;EACE,WAAW,0BAA0B,GAAc,UAAU,aAAa,gBAAgB,GAAG,GAAG,KAAY,KAAK;EACjH,MAAK;EACL,cAAW;EACX,cAAY;EAJd,UAAA;GAME,kBAAC,SAAD;IACE,KAAK;IACL,WAAU;IACV,OAAA;IACA,UAAA;IACA,aAAA;IACA,OAAO,EAAE,WAAW,EAAW;IAC/B,cAAW;GACZ,CAAA;GAEA,KAAe,GAAc,eAAe,EAAa,gBACxD,kBAAC,OAAD;IACE,WAAW,gCAAgC,EAAa;IACxD,SAAS,IAAkB;IAC3B,qBAAqB,IAAkB;IACvC,cAAY,GAAG,EAAa,MAAM;IAElC,UAAA,kBAAC,WAAD,EAAS,QAAQ,GAAG,EAAY,QAAQ,EAAE,GAAG,EAAY,QAAQ,EAAE,GAAG,EAAY,SAAS,EAAE,GAAG,EAAY,SAAS,EAAE,GAAG,EAAY,YAAY,EAAE,GAAG,EAAY,YAAY,EAAE,GAAG,EAAY,WAAW,EAAE,GAAG,EAAY,WAAW,IAAM,CAAA;GAC1O,CAAA;GAGP,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,UAAD,EAAA,UAAS,GAAc,CAAA,GACvB,kBAAC,QAAD;KAAM,aAAU;KAAhB,UAAA;MACG,MAAU,cAAc;MACxB,MAAU,YAAY,MAAgB;MACtC,MAAU,eAAe;MACzB,MAAU,WAAW;KAClB;IACH,CAAA,CAAA,EAAA,CAAA,GACL,kBAAC,UAAD;KAAQ,MAAK;KAAS,SAAS;KAAO,cAAW;KAAe,UAAA;IAAS,CAAA,CACtE;;GAEJ,MAAU,UACT,kBAAC,OAAD;IAAK,WAAU;IAAkC,MAAK;IAAtD,UAAA;KACE,kBAAC,UAAD,EAAA,UAAS,IAAc,mBAAmB,4BAAoC,CAAA;KAC9E,kBAAC,KAAD,EAAA,UAAI,EAAS,CAAA;KACb,kBAAC,OAAD,EAAA,UAAA;MACE,kBAAC,UAAD;OAAQ,MAAK;OAAS,SAAS;OAAO,UAAA;MAAiB,CAAA;MACvD,kBAAC,UAAD;OAAQ,MAAK;OAAS,eAAe,KAAK,GAAW;OAClD,UAAA,MAAc,WAAW,WAAW,MAAc,WAAW,gBAAgB;MACxE,CAAA;MACR,kBAAC,UAAD;OAAQ,MAAK;OAAS,SAAS;OAAO,UAAA;MAAc,CAAA;KACjD,EAAA,CAAA;IACF;GACH,CAAA,IAAA,MAAU,aACZ,kBAAC,OAAD;IAAK,WAAU;IAAkC,aAAU;IAA3D,UAAA;KACE,kBAAC,QAAD,EAAM,WAAU,kCAAmC,CAAA;KACnD,kBAAC,UAAD,EAAA,UAAQ,8CAAmD,CAAA;KAC3D,kBAAC,KAAD,EAAA,UAAG,mCAAmC,CAAA;IACnC;GACH,CAAA,IAAA;GAEJ,kBAAC,OAAD;IAAK,WAAU;IAAiC,aAAU;IAA1D,UAAA;KACE,kBAAC,QAAD,EAAM,WAAW,GAAc,SAAS,YAAc,CAAA;KACrD,GAAc,SAAS;KACvB,IAAe,MAAM,KAAK,MAAM,EAAa,aAAa,GAAG,EAAE,MAAM,EAAa,aAAa,GAAG,EAAa,yBAAyB;KACxI,MAAM;KACN,GAAc,gBAAgB,KAAA,IAA6D,KAAjD,MAAM,KAAK,MAAM,EAAa,WAAW,EAAE;KACrF,KAAS,IAAS,MAAM,EAAM,GAAG,MAAW;IAC1C;;GAEL,kBAAC,MAAD;IAAI,WAAU;IAAsC,cAAW;IAA/D,UAAA;KACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,SAAU,CAAA,GACd,kBAAC,MAAD,EAAA,UAAA;MAAK,EAAO;MAAO;MAAE,EAAO;MAAS,EAAO,YAAY,SAAS;KAAO,EAAA,CAAA,CACrE,EAAA,CAAA;KACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,QAAS,CAAA,GACb,kBAAC,MAAD,EAAA,UACG,IACG,GAAG,EAAgB,WAAW,GAAG,EAAgB,YAAY,KAAK,EAAgB,aAAa,EAAgB,SAAS,YAAY,KAAK,EAAgB,WAAW,KAAK,cACzK,WACF,CAAA,CACD,EAAA,CAAA;KACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,QAAS,CAAA,GACb,kBAAC,MAAD,EAAA,UACG,IACG,GAAG,EAAgB,kBAAkB,EAAgB,aAAa,WAAW,KAAK,EAAgB,eAAe,KAAK,gBACtH,IACF,CAAA,CACD,EAAA,CAAA;KACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,QAAS,CAAA,GACb,kBAAC,MAAD,EAAA,UACG,IACG,GAAG,EAAgB,MAAM,KAAK,KAAK,EAAgB,MAAM,YAAa,EAAgB,MAAM,KAAK,OAAO,QAAS,kBACjH,WACF,CAAA,CACD,EAAA,CAAA;KACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,OAAQ,CAAA,GACZ,kBAAC,MAAD,EAAA,UACG,IACG,QAAQ,EAAgB,cAAc,QAAQ,CAAC,EAAE,YAAY,EAAgB,gBAAgB,QAAQ,CAAC,IAAI,OAAO,SAAS,EAAgB,WAAW,IAAI,KAAK,KAAK,MAAM,EAAgB,WAAW,EAAE,OAAO,cAC7M,IACF,CAAA,CACD,EAAA,CAAA;KACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,OAAQ,CAAA,GACZ,kBAAC,MAAD,EAAA,UACG,KAAiB,4BAChB,CAAA,CACD,EAAA,CAAA;KACJ,IACC,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,UAAW,CAAA,GACf,kBAAC,MAAD,EAAA,UACG,QAAQ,EAAmB,cAAc,QAAQ,CAAC,EAAE,YAAY,EAAmB,gBAAgB,QAAQ,CAAC,IAAI,OAAO,SAAS,EAAmB,WAAW,IAAI,KAAK,KAAK,MAAM,EAAmB,WAAW,EAAE,OAAO,YACxN,CAAA,CACD,EAAA,CAAA,IACH;KACJ,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,QAAS,CAAA,GACb,kBAAC,MAAD,EAAA,UACE,kBAAC,UAAD;MACE,MAAK;MACL,WAAU;MACV,eAAe,KAAK,GAAW;MAE9B,UAAA,MAAc,WAAW,kBAAkB,MAAc,WAAW,gBAAgB;KAC/E,CAAA,EACN,CAAA,CACD,EAAA,CAAA;IACH;;GAEJ,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,kBAAC,UAAD;MAAQ,MAAK;MAAS,WAAU;MAAiC,SAAS;MAAO,UAAA;KAAc,CAAA;KAC/F,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC,UAAD;OACE,MAAK;OACL,WAAU;OACV,eAAe,KAAK,GAAQ;OAC5B,UAAU,MAAU;OACpB,cAAW;OAEX,UAAA,kBAAC,QAAD,CAAO,CAAA;MACD,CAAA,GACR,kBAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACG,GAAc,YAAY,WACzB,kBAAC,SAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QACE,MAAK;QACL,SAAS,EAAa,YAAY;QAClC,WAAW,MAAU,EAAU,SAAS,eAAe,EAAM,OAAO,OAAO;OAC5E,CAAA,GAAC,cAEG,EAAA,CAAA,GAER,GAAa,MAAM,WAClB,kBAAC,SAAD;QAAO,OAAO,EAAY,MAAM,YAAY,4DAA4D,KAAA;QAAxG,UAAA,CACE,kBAAC,SAAD;SACE,MAAK;SACL,SAAS,EAAY,MAAM;SAC3B,UAAU,CAAC,EAAY,MAAM;SAC7B,WAAW,MAAU,KAAK,GAAS,EAAM,OAAO,OAAO;QACxD,CAAA,GACA,EAAY,MAAM,YAAY,eAAe,OACzC;OAEN,CAAA,CAAA;MACF,CAAA,CAAA;;KACL,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC,QAAD,EAAA,UAAO,MAAkB,gBAAgB,WAAW,SAAe,CAAA,GACnE,kBAAC,UAAD,EAAA,UAAS,KAAS,IAAS,GAAG,EAAM,KAAK,MAAW,aAAqB,CAAA,CACtE;;IACF;;EACF;;AAET"}