@scanfit/browser 0.1.0-alpha.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.
@@ -0,0 +1,1456 @@
1
+ class $ extends Error {
2
+ constructor(e, n, o) {
3
+ super(n, o), this.code = e, this.name = "ScanError";
4
+ }
5
+ code;
6
+ }
7
+ const xt = [
8
+ { x: 0, y: 0 },
9
+ { x: 1, y: 0 },
10
+ { x: 1, y: 1 },
11
+ { x: 0, y: 1 }
12
+ ], wt = (t) => t.map((e) => ({ ...e }));
13
+ function V(t) {
14
+ if (t?.aborted)
15
+ throw new DOMException("Operation cancelled", "AbortError");
16
+ }
17
+ function ht(t) {
18
+ if (!Array.isArray(t) || t.length !== 4 || t.some(
19
+ (n) => !n || !Number.isFinite(n.x) || !Number.isFinite(n.y) || n.x < 0 || n.x > 1 || n.y < 0 || n.y > 1
20
+ ))
21
+ throw new $(
22
+ "INVALID_CORNERS",
23
+ "Keep all four corners inside the image."
24
+ );
25
+ let e = 0;
26
+ for (let n = 0; n < 4; n++) {
27
+ const o = t[n], i = t[(n + 1) % 4], a = t[(n + 2) % 4];
28
+ if ((i.x - o.x) * (a.y - i.y) - (i.y - o.y) * (a.x - i.x) <= 1e-5)
29
+ throw new $(
30
+ "INVALID_CORNERS",
31
+ "Corners must form a clockwise, non-crossing document outline."
32
+ );
33
+ e += o.x * i.y - i.x * o.y;
34
+ }
35
+ if (e < 0.01)
36
+ throw new $("INVALID_CORNERS", "Select a larger document area.");
37
+ }
38
+ function rt(t, e, n = 2400, o = 4e6) {
39
+ const i = Math.min(
40
+ 1,
41
+ n / Math.max(t, e),
42
+ Math.sqrt(o / (t * e))
43
+ );
44
+ return {
45
+ width: Math.max(1, Math.floor(t * i)),
46
+ height: Math.max(1, Math.floor(e * i))
47
+ };
48
+ }
49
+ function Mt(t) {
50
+ const [e, n, o, i] = t, a = n.x - o.x, c = i.x - o.x, r = e.x - n.x + o.x - i.x, l = n.y - o.y, f = i.y - o.y, s = e.y - n.y + o.y - i.y, h = a * f - c * l, d = Math.abs(r) + Math.abs(s) < 1e-12 ? 0 : (r * f - c * s) / h, p = Math.abs(r) + Math.abs(s) < 1e-12 ? 0 : (a * s - r * l) / h;
51
+ return [
52
+ n.x - e.x + d * n.x,
53
+ i.x - e.x + p * i.x,
54
+ e.x,
55
+ n.y - e.y + d * n.y,
56
+ i.y - e.y + p * i.y,
57
+ e.y,
58
+ d,
59
+ p
60
+ ];
61
+ }
62
+ function bt(t, e) {
63
+ ht(e.corners);
64
+ const n = e.corners.map((h) => ({
65
+ x: h.x * (t.width - 1),
66
+ y: h.y * (t.height - 1)
67
+ })), o = (h, d) => Math.hypot(n[h].x - n[d].x, n[h].y - n[d].y), i = rt(
68
+ Math.max(o(0, 1), o(3, 2)) + 1,
69
+ Math.max(o(0, 3), o(1, 2)) + 1
70
+ ), a = e.rotation === 90 || e.rotation === 270, c = a ? i.height : i.width, r = a ? i.width : i.height, l = new Uint8ClampedArray(c * r * 4), f = Mt(n), s = t.data;
71
+ for (let h = 0; h < r; h++)
72
+ for (let d = 0; d < c; d++) {
73
+ const p = c > 1 ? d / (c - 1) : 0, y = r > 1 ? h / (r - 1) : 0;
74
+ let m = p, x = y;
75
+ e.rotation === 90 ? (m = y, x = 1 - p) : e.rotation === 180 ? (m = 1 - p, x = 1 - y) : e.rotation === 270 && (m = 1 - y, x = p);
76
+ const b = f[6] * m + f[7] * x + 1, u = Math.max(
77
+ 0,
78
+ Math.min(t.width - 1, (f[0] * m + f[1] * x + f[2]) / b)
79
+ ), g = Math.max(
80
+ 0,
81
+ Math.min(t.height - 1, (f[3] * m + f[4] * x + f[5]) / b)
82
+ ), C = Math.floor(u), P = Math.floor(g), T = Math.min(C + 1, t.width - 1), U = Math.min(P + 1, t.height - 1), I = u - C, w = g - P, S = (P * t.width + C) * 4, A = (P * t.width + T) * 4, M = (U * t.width + C) * 4, F = (U * t.width + T) * 4, E = (1 - I) * (1 - w), v = I * (1 - w), N = (1 - I) * w, j = I * w, O = s[S + 3] / 255, B = s[A + 3] / 255, L = s[M + 3] / 255, at = s[F + 3] / 255, k = (h * c + d) * 4;
83
+ for (let D = 0; D < 3; D++)
84
+ l[k + D] = (s[S + D] * O + 255 * (1 - O)) * E + (s[A + D] * B + 255 * (1 - B)) * v + (s[M + D] * L + 255 * (1 - L)) * N + (s[F + D] * at + 255 * (1 - at)) * j;
85
+ if (e.filter === "grayscale") {
86
+ const D = 0.2126 * l[k] + 0.7152 * l[k + 1] + 0.0722 * l[k + 2];
87
+ l[k] = l[k + 1] = l[k + 2] = D;
88
+ } else if (e.filter === "contrast")
89
+ for (let D = 0; D < 3; D++)
90
+ l[k + D] = (l[k + D] - 128) * 1.15 + 128;
91
+ l[k + 3] = 255;
92
+ }
93
+ return new ImageData(l, c, r);
94
+ }
95
+ const It = 0.5, R = (t, e = 0, n = 1) => Math.max(e, Math.min(n, t)), ut = () => typeof performance > "u" ? Date.now() : performance.now();
96
+ function Ut(t) {
97
+ const e = new Uint8Array(t.width * t.height);
98
+ for (let n = 0, o = 0; o < e.length; o++, n += 4) {
99
+ const i = t.data[n + 3] / 255, a = 77 * t.data[n] + 150 * t.data[n + 1] + 29 * t.data[n + 2] >> 8;
100
+ e[o] = Math.round(a * i + 255 * (1 - i));
101
+ }
102
+ return e;
103
+ }
104
+ function St(t, e, n) {
105
+ const o = Math.max(e, n) >= 600 ? 2 : 1, i = o * 2 + 1, a = new Uint8Array(t.length), c = new Uint8Array(t.length);
106
+ for (let r = 0; r < n; r++) {
107
+ const l = r * e;
108
+ for (let f = 0; f < e; f++) {
109
+ let s = 0;
110
+ for (let h = -o; h <= o; h++)
111
+ s += t[l + Math.max(0, Math.min(e - 1, f + h))];
112
+ a[l + f] = Math.round(s / i);
113
+ }
114
+ }
115
+ for (let r = 0; r < n; r++)
116
+ for (let l = 0; l < e; l++) {
117
+ let f = 0;
118
+ for (let s = -o; s <= o; s++)
119
+ f += a[Math.max(0, Math.min(n - 1, r + s)) * e + l];
120
+ c[r * e + l] = Math.round(f / i);
121
+ }
122
+ return c;
123
+ }
124
+ function At(t, e, n) {
125
+ const o = new Uint16Array(t.length), i = new Uint32Array(2041);
126
+ let a = 0;
127
+ for (let f = 1; f < n - 1; f++)
128
+ for (let s = 1; s < e - 1; s++) {
129
+ const h = f * e + s, d = -t[h - e - 1] + t[h - e + 1] - 2 * t[h - 1] + 2 * t[h + 1] - t[h + e - 1] + t[h + e + 1], p = -t[h - e - 1] - 2 * t[h - e] - t[h - e + 1] + t[h + e - 1] + 2 * t[h + e] + t[h + e + 1], y = Math.min(2040, Math.abs(d) + Math.abs(p));
130
+ o[h] = y, y && (i[y]++, a++);
131
+ }
132
+ let c = 0;
133
+ const r = a * 0.82;
134
+ let l = 0;
135
+ for (let f = 1; f < i.length; f++)
136
+ if (c += i[f], c >= r) {
137
+ l = f;
138
+ break;
139
+ }
140
+ return {
141
+ magnitude: o,
142
+ threshold: Math.round(R(l || 24, 24, 600)),
143
+ nonzero: a
144
+ };
145
+ }
146
+ function Ft(t, e, n, o) {
147
+ const i = new Uint8Array(t.length), a = new Int32Array(t.length), c = o * 0.42;
148
+ let r = 0, l = 0, f = 0;
149
+ for (let d = 0; d < t.length; d++)
150
+ t[d] >= o ? (i[d] = 2, a[l++] = d, f++) : t[d] >= c && (i[d] = 1);
151
+ for (; r < l; ) {
152
+ const d = a[r++], p = d % e, y = Math.floor(d / e);
153
+ for (let m = -1; m <= 1; m++)
154
+ for (let x = -1; x <= 1; x++) {
155
+ if (!x && !m || p + x < 0 || p + x >= e || y + m < 0 || y + m >= n)
156
+ continue;
157
+ const b = d + m * e + x;
158
+ i[b] === 1 && (i[b] = 2, a[l++] = b);
159
+ }
160
+ }
161
+ const s = new Uint8Array(i.length);
162
+ let h = 0;
163
+ for (let d = 0; d < i.length; d++)
164
+ i[d] === 2 && (s[d] = 1, h++);
165
+ return { binary: s, density: h / s.length, strong: f };
166
+ }
167
+ function Ct(t, e, n) {
168
+ const o = new Uint8Array(t.length);
169
+ for (let i = 1; i < n - 1; i++)
170
+ for (let a = 1; a < e - 1; a++) {
171
+ const c = i * e + a;
172
+ (t[c] || t[c - 1] || t[c + 1] || t[c - e] || t[c + e] || t[c - e - 1] || t[c - e + 1] || t[c + e - 1] || t[c + e + 1]) && (o[c] = 1);
173
+ }
174
+ return o;
175
+ }
176
+ function Pt(t) {
177
+ const e = new Uint32Array(256);
178
+ for (const r of t) e[r]++;
179
+ let n = 0;
180
+ for (let r = 0; r < 256; r++) n += r * e[r];
181
+ let o = 0, i = 0, a = -1, c = 127;
182
+ for (let r = 0; r < 255; r++) {
183
+ o += e[r], i += r * e[r];
184
+ const l = t.length - o;
185
+ if (!o || !l) continue;
186
+ const f = i / o - (n - i) / l, s = o * l * f * f;
187
+ s > a && (a = s, c = r);
188
+ }
189
+ return c;
190
+ }
191
+ function vt(t, e, n) {
192
+ const o = new Uint32Array(256);
193
+ let i = 0;
194
+ const a = (s) => {
195
+ o[s]++, i++;
196
+ };
197
+ for (let s = 0; s < e; s++)
198
+ a(t[s]), a(t[(n - 1) * e + s]);
199
+ for (let s = 1; s < n - 1; s++)
200
+ a(t[s * e]), a(t[s * e + e - 1]);
201
+ let c = 0, r = 127;
202
+ for (let s = 0; s < o.length; s++)
203
+ if (c += o[s], c >= i / 2) {
204
+ r = s;
205
+ break;
206
+ }
207
+ const l = new Uint32Array(256);
208
+ for (let s = 0; s < o.length; s++)
209
+ l[Math.abs(s - r)] += o[s];
210
+ c = 0;
211
+ let f = 0;
212
+ for (let s = 0; s < l.length; s++)
213
+ if (c += l[s], c >= i / 2) {
214
+ f = s;
215
+ break;
216
+ }
217
+ return { median: r, deviation: f };
218
+ }
219
+ function Et(t, e, n) {
220
+ const o = Pt(t), i = vt(t, e, n), a = new Uint8Array(t.length), c = new Uint8Array(t.length), r = new Uint8Array(t.length), l = Math.max(16, i.deviation * 2.5);
221
+ for (let f = 0; f < t.length; f++)
222
+ a[f] = t[f] > o ? 1 : 0, c[f] = t[f] <= o ? 1 : 0, r[f] = Math.abs(t[f] - i.median) >= l ? 1 : 0;
223
+ return { bright: a, dark: c, contrast: r };
224
+ }
225
+ function Nt(t, e, n, o, i) {
226
+ const a = new Uint8Array(t.length), c = new Int32Array(t.length), r = [], l = o ? Math.max(64, t.length * 0.025) : Math.max(40, (e + n) * 0.06);
227
+ for (let f = 0; f < t.length; f++) {
228
+ if (!t[f] || a[f]) continue;
229
+ let s = 0, h = 0, d = 0, p = 0, y = e, m = n, x = 0, b = 0, u = 0;
230
+ const g = [], C = new Array(8), P = [
231
+ 1 / 0,
232
+ -1 / 0,
233
+ 1 / 0,
234
+ -1 / 0,
235
+ 1 / 0,
236
+ -1 / 0,
237
+ 1 / 0,
238
+ -1 / 0
239
+ ];
240
+ for (c[h++] = f, a[f] = 1; s < h; ) {
241
+ const U = c[s++], I = U % e, w = Math.floor(U / e);
242
+ d++, y = Math.min(y, I), m = Math.min(m, w), x = Math.max(x, I), b = Math.max(b, w), (I === 0 || I === e - 1 || w === 0 || w === n - 1) && u++;
243
+ const S = [I + w, I + w, I - w, I - w, I, I, w, w];
244
+ for (let M = 0; M < 8; M++)
245
+ (M % 2 ? S[M] > P[M] : S[M] < P[M]) && (P[M] = S[M], C[M] = { x: I, y: w });
246
+ let A = !1;
247
+ for (let M = -1; M <= 1; M++)
248
+ for (let F = -1; F <= 1; F++) {
249
+ if (!F && !M) continue;
250
+ const E = I + F, v = w + M;
251
+ if (E < 0 || E >= e || v < 0 || v >= n) {
252
+ A = !0;
253
+ continue;
254
+ }
255
+ const N = v * e + E;
256
+ t[N] ? a[N] || (a[N] = 1, c[h++] = N) : A = !0;
257
+ }
258
+ if (A)
259
+ if (p++, g.length < 2048) g.push({ x: I, y: w });
260
+ else {
261
+ const M = (Math.imul(p, 2654435761) >>> 0) % p | 0;
262
+ M < g.length && (g[M] = { x: I, y: w });
263
+ }
264
+ }
265
+ const T = (x - y + 1) * (b - m + 1);
266
+ if (d >= l && T >= t.length * 0.055 && d < t.length * 0.985) {
267
+ for (const U of C) U && g.push(U);
268
+ r.push({ count: d, boundsArea: T, touches: u, boundary: g });
269
+ }
270
+ }
271
+ return r.sort(
272
+ (f, s) => s.boundsArea * Math.min(1, s.count / l) - f.boundsArea * Math.min(1, f.count / l)
273
+ ).slice(0, i);
274
+ }
275
+ const X = (t, e, n) => (e.x - t.x) * (n.y - t.y) - (e.y - t.y) * (n.x - t.x);
276
+ function Tt(t) {
277
+ const e = [...t].sort((i, a) => i.x - a.x || i.y - a.y).filter(
278
+ (i, a, c) => !a || i.x !== c[a - 1].x || i.y !== c[a - 1].y
279
+ );
280
+ if (e.length <= 4) return e;
281
+ const n = [], o = [];
282
+ for (const i of e) {
283
+ for (; n.length >= 2 && X(n.at(-2), n.at(-1), i) <= 0; )
284
+ n.pop();
285
+ n.push(i);
286
+ }
287
+ for (let i = e.length - 1; i >= 0; i--) {
288
+ const a = e[i];
289
+ for (; o.length >= 2 && X(o.at(-2), o.at(-1), a) <= 0; )
290
+ o.pop();
291
+ o.push(a);
292
+ }
293
+ return n.pop(), o.pop(), [...n, ...o];
294
+ }
295
+ function $t(t) {
296
+ const e = [...t];
297
+ for (; e.length > 4; ) {
298
+ let n = 0, o = 1 / 0;
299
+ for (let i = 0; i < e.length; i++) {
300
+ const a = e[(i + e.length - 1) % e.length], c = e[i], r = e[(i + 1) % e.length], l = Math.abs(X(a, c, r));
301
+ l < o && (o = l, n = i);
302
+ }
303
+ e.splice(n, 1);
304
+ }
305
+ return e;
306
+ }
307
+ function Z(t, e) {
308
+ const n = Math.abs(t - e) % Math.PI;
309
+ return Math.min(n, Math.PI - n);
310
+ }
311
+ function q(t, e) {
312
+ const n = Math.cos(t.theta), o = Math.sin(t.theta), i = Math.cos(e.theta), a = Math.sin(e.theta), c = n * a - o * i;
313
+ return Math.abs(c) < 0.08 ? null : {
314
+ x: (t.rho * a - o * e.rho) / c,
315
+ y: (n * e.rho - t.rho * i) / c
316
+ };
317
+ }
318
+ function Dt(t, e, n, o) {
319
+ const i = [];
320
+ let a = 0;
321
+ for (let u = 1; u < o - 1; u++)
322
+ for (let g = 1; g < n - 1; g++)
323
+ if (!(t[u * n + g] < e))
324
+ if (a++, i.length < 5e3) i.push({ x: g, y: u });
325
+ else {
326
+ const C = (Math.imul(a, 2246822519) >>> 0) % a | 0;
327
+ C < i.length && (i[C] = { x: g, y: u });
328
+ }
329
+ if (i.length < 24) return [];
330
+ const c = 90, r = 2, l = Math.hypot(n, o), f = Math.ceil(l * 2 / r) + 1, s = new Uint16Array(c * f), h = new Float32Array(c), d = new Float32Array(c);
331
+ for (let u = 0; u < c; u++) {
332
+ const g = u * Math.PI / c;
333
+ h[u] = Math.cos(g), d[u] = Math.sin(g);
334
+ }
335
+ for (const u of i)
336
+ for (let g = 0; g < c; g++) {
337
+ const C = Math.round(
338
+ (u.x * h[g] + u.y * d[g] + l) / r
339
+ ), P = g * f + C;
340
+ s[P] < 65535 && s[P]++;
341
+ }
342
+ const p = Math.max(10, Math.round(Math.min(n, o) * 0.055)), y = [];
343
+ for (let u = 0; u < c; u++)
344
+ for (let g = 1; g < f - 1; g++) {
345
+ const C = s[u * f + g];
346
+ C < p || y.push({
347
+ theta: u * Math.PI / c,
348
+ rho: g * r - l,
349
+ votes: C
350
+ });
351
+ }
352
+ y.sort((u, g) => g.votes - u.votes);
353
+ const m = [];
354
+ for (const u of y)
355
+ if (!m.some(
356
+ (g) => Z(u.theta, g.theta) < 4 * Math.PI / c && Math.abs(u.rho - g.rho) < r * 5
357
+ ) && (m.push(u), m.length >= 28))
358
+ break;
359
+ const x = [];
360
+ for (let u = 0; u < m.length; u++)
361
+ for (let g = u + 1; g < m.length; g++) {
362
+ const C = Math.abs(m[u].rho - m[g].rho), P = Z(m[u].theta, m[g].theta);
363
+ P <= 16 * Math.PI / 180 && C >= Math.min(n, o) * 0.16 && x.push({
364
+ lines: [m[u], m[g]],
365
+ score: m[u].votes + m[g].votes - P * 180 / Math.PI
366
+ });
367
+ }
368
+ x.sort((u, g) => g.score - u.score);
369
+ const b = [];
370
+ for (let u = 0; u < Math.min(16, x.length); u++)
371
+ for (let g = u + 1; g < Math.min(16, x.length); g++) {
372
+ if (Z(
373
+ x[u].lines[0].theta,
374
+ x[g].lines[0].theta
375
+ ) < 38 * Math.PI / 180) continue;
376
+ const [P, T] = x[u].lines, [U, I] = x[g].lines, w = [
377
+ q(P, U),
378
+ q(T, U),
379
+ q(T, I),
380
+ q(P, I)
381
+ ];
382
+ w.some(
383
+ (S) => !S || S.x < -n * 0.03 || S.x > n * 1.03 || S.y < -o * 0.03 || S.y > o * 1.03
384
+ ) || b.push({
385
+ points: w,
386
+ source: "hough-lines",
387
+ score: x[u].score + x[g].score
388
+ });
389
+ }
390
+ return b.sort((u, g) => g.score - u.score).slice(0, 20).map(({ points: u, source: g }) => ({ points: u, source: g }));
391
+ }
392
+ function Rt(t) {
393
+ return t.length < 4 ? [] : [
394
+ (n) => n.x + n.y,
395
+ (n) => -(n.x - n.y),
396
+ (n) => -(n.x + n.y),
397
+ (n) => n.x - n.y
398
+ ].map(
399
+ (n) => t.reduce(
400
+ (o, i) => n(i) < n(o) ? i : o
401
+ )
402
+ );
403
+ }
404
+ function Ot(t, e, n) {
405
+ if (t.length !== 4 || new Set(t.map((r) => `${r.x},${r.y}`)).size !== 4)
406
+ return null;
407
+ const o = t.reduce(
408
+ (r, l) => ({
409
+ x: r.x + l.x / 4,
410
+ y: r.y + l.y / 4
411
+ }),
412
+ { x: 0, y: 0 }
413
+ );
414
+ let i = [...t].sort(
415
+ (r, l) => Math.atan2(r.y - o.y, r.x - o.x) - Math.atan2(l.y - o.y, l.x - o.x)
416
+ ), a = 0;
417
+ for (let r = 1; r < 4; r++)
418
+ i[r].x + i[r].y < i[a].x + i[a].y && (a = r);
419
+ i = [...i.slice(a), ...i.slice(0, a)], X(i[0], i[1], i[2]) < 0 && (i = [i[0], i[3], i[2], i[1]]);
420
+ const c = i.map((r) => ({
421
+ x: R(r.x / Math.max(1, e - 1)),
422
+ y: R(r.y / Math.max(1, n - 1))
423
+ }));
424
+ try {
425
+ return ht(c), c;
426
+ } catch {
427
+ return null;
428
+ }
429
+ }
430
+ function jt(t) {
431
+ let e = 0;
432
+ for (let n = 0; n < 4; n++) {
433
+ const o = t[n], i = t[(n + 1) % 4];
434
+ e += o.x * i.y - i.x * o.y;
435
+ }
436
+ return Math.abs(e) / 2;
437
+ }
438
+ function tt(t, e, n, o, i) {
439
+ const a = Math.max(0, Math.min(e - 1, Math.round(o))), c = Math.max(0, Math.min(n - 1, Math.round(i)));
440
+ return t[c * e + a];
441
+ }
442
+ function Lt(t, e, n, o, i, a) {
443
+ const c = jt(t);
444
+ if (c < 0.055 || c > 0.985) return null;
445
+ const r = t.map((U) => ({
446
+ x: U.x * (i - 1),
447
+ y: U.y * (a - 1)
448
+ })), l = r.map((U, I) => {
449
+ const w = r[(I + 1) % 4];
450
+ return {
451
+ dx: w.x - U.x,
452
+ dy: w.y - U.y,
453
+ length: Math.hypot(w.x - U.x, w.y - U.y)
454
+ };
455
+ }), f = Math.hypot(i, a), s = Math.min(...l.map((U) => U.length)) / f;
456
+ if (s < 0.055) return null;
457
+ let h = 0;
458
+ for (let U = 0; U < 4; U++) {
459
+ const I = r[(U + 3) % 4], w = r[U], S = r[(U + 1) % 4], A = I.x - w.x, M = I.y - w.y, F = S.x - w.x, E = S.y - w.y, v = Math.abs(
460
+ (A * F + M * E) / Math.max(1, Math.hypot(A, M) * Math.hypot(F, E))
461
+ );
462
+ h += 1 - R(v / 0.72);
463
+ }
464
+ h /= 4;
465
+ let d = 0, p = 0, y = 0, m = 0;
466
+ for (let U = 0; U < 4; U++) {
467
+ const I = r[U], w = l[U], S = Math.max(12, Math.min(180, Math.round(w.length / 2))), A = -w.dy / Math.max(1, w.length), M = w.dx / Math.max(1, w.length);
468
+ for (let F = 1; F < S; F++) {
469
+ const E = F / S, v = I.x + w.dx * E, N = I.y + w.dy * E;
470
+ let j = 0;
471
+ for (let L = -2; L <= 2; L++)
472
+ j = Math.max(
473
+ j,
474
+ tt(
475
+ n,
476
+ i,
477
+ a,
478
+ v + A * L,
479
+ N + M * L
480
+ )
481
+ );
482
+ d += j >= o * 0.7 ? 1 : 0, p += R(j / Math.max(1, o * 1.8));
483
+ const O = tt(
484
+ e,
485
+ i,
486
+ a,
487
+ v + A * 4,
488
+ N + M * 4
489
+ ), B = tt(
490
+ e,
491
+ i,
492
+ a,
493
+ v - A * 4,
494
+ N - M * 4
495
+ );
496
+ y += R(Math.abs(O - B) / 48), m++;
497
+ }
498
+ }
499
+ const x = m ? 0.67 * (d / m) + 0.33 * (p / m) : 0;
500
+ y = m ? y / m : 0;
501
+ const b = R((c - 0.055) / 0.3) * R((0.985 - c) / 0.08), u = R((s - 0.055) / 0.18), g = 0.72 * h + 0.28 * u, C = t.reduce(
502
+ (U, I) => U + R(
503
+ Math.min(I.x, I.y, 1 - I.x, 1 - I.y) / 0.025
504
+ ),
505
+ 0
506
+ ) / 4, T = (0.43 * x + 0.2 * y + 0.15 * b + 0.17 * g + 0.05 * u) * (0.56 + 0.44 * C);
507
+ return {
508
+ score: T,
509
+ confidence: R((T - 0.3) / 0.55),
510
+ coverage: c,
511
+ edgeSupport: x,
512
+ contrast: y,
513
+ rectangularity: g
514
+ };
515
+ }
516
+ function W(t, e, n, o, i, a, c) {
517
+ return {
518
+ engine: "scanfit-classical",
519
+ confidence: e,
520
+ candidateCount: n,
521
+ edgeThreshold: o,
522
+ edgeDensity: i,
523
+ durationMs: Math.max(0, ut() - t),
524
+ coverage: a?.coverage ?? 0,
525
+ edgeSupport: a?.edgeSupport ?? 0,
526
+ contrast: a?.contrast ?? 0,
527
+ rectangularity: a?.rectangularity ?? 0,
528
+ fallbackReason: c
529
+ };
530
+ }
531
+ function kt(t, e = {}) {
532
+ const n = ut(), o = t.width, i = t.height;
533
+ if (!Number.isSafeInteger(o) || !Number.isSafeInteger(i) || o < 32 || i < 32 || t.data.length !== o * i * 4)
534
+ return {
535
+ corners: null,
536
+ confidence: 0,
537
+ diagnostics: W(
538
+ n,
539
+ 0,
540
+ 0,
541
+ 0,
542
+ 0,
543
+ void 0,
544
+ "invalid-image"
545
+ )
546
+ };
547
+ const a = St(Ut(t), o, i), c = At(a, o, i), r = Ft(
548
+ c.magnitude,
549
+ o,
550
+ i,
551
+ c.threshold
552
+ );
553
+ if (c.nonzero < t.width + t.height || r.strong < 8)
554
+ return {
555
+ corners: null,
556
+ confidence: 0,
557
+ diagnostics: W(
558
+ n,
559
+ 0,
560
+ 0,
561
+ c.threshold,
562
+ r.density,
563
+ void 0,
564
+ "uniform-image"
565
+ )
566
+ };
567
+ const l = Et(a, o, i), f = [
568
+ {
569
+ binary: Ct(r.binary, o, i),
570
+ source: "edges",
571
+ filled: !1
572
+ },
573
+ { binary: l.bright, source: "bright-region", filled: !0 },
574
+ { binary: l.dark, source: "dark-region", filled: !0 },
575
+ { binary: l.contrast, source: "border-contrast", filled: !0 }
576
+ ], s = Math.max(
577
+ 1,
578
+ Math.min(
579
+ 16,
580
+ Number.isSafeInteger(e.maxComponents) ? e.maxComponents : 8
581
+ )
582
+ ), h = [];
583
+ h.push(
584
+ ...Dt(
585
+ c.magnitude,
586
+ c.threshold,
587
+ o,
588
+ i
589
+ )
590
+ );
591
+ for (const b of f)
592
+ for (const u of Nt(
593
+ b.binary,
594
+ o,
595
+ i,
596
+ b.filled,
597
+ s
598
+ )) {
599
+ if (u.touches > u.count * 0.45 && u.boundsArea > o * i * 0.9)
600
+ continue;
601
+ const g = Tt(u.boundary);
602
+ g.length >= 4 && (h.push({ points: $t(g), source: b.source }), h.push({ points: Rt(g), source: b.source }));
603
+ }
604
+ const d = Math.max(
605
+ 1,
606
+ Math.min(
607
+ 64,
608
+ Number.isSafeInteger(e.maxCandidates) ? e.maxCandidates : 24
609
+ )
610
+ ), p = /* @__PURE__ */ new Map();
611
+ for (const b of h) {
612
+ const u = Ot(b.points, o, i);
613
+ if (!u) continue;
614
+ const g = u.map(
615
+ (C) => `${Math.round(C.x * 40)},${Math.round(C.y * 40)}`
616
+ ).join(";");
617
+ if (p.has(g) || p.set(g, { quad: u, source: b.source }), p.size >= d) break;
618
+ }
619
+ let y;
620
+ for (const b of p.values()) {
621
+ const u = Lt(
622
+ b.quad,
623
+ a,
624
+ c.magnitude,
625
+ c.threshold,
626
+ o,
627
+ i
628
+ );
629
+ u && (!y || u.score > y.metrics.score) && (y = { ...b, metrics: u });
630
+ }
631
+ const m = y?.metrics.confidence ?? 0, x = R(
632
+ Number.isFinite(e.minConfidence) ? e.minConfidence : It,
633
+ 0.15,
634
+ 0.95
635
+ );
636
+ return !y || m < x || y.metrics.edgeSupport < 0.28 ? {
637
+ corners: null,
638
+ confidence: m,
639
+ diagnostics: W(
640
+ n,
641
+ m,
642
+ p.size,
643
+ c.threshold,
644
+ r.density,
645
+ y?.metrics,
646
+ y ? "low-confidence" : "no-candidate"
647
+ )
648
+ } : {
649
+ corners: y.quad,
650
+ confidence: m,
651
+ diagnostics: {
652
+ ...W(
653
+ n,
654
+ m,
655
+ p.size,
656
+ c.threshold,
657
+ r.density,
658
+ y.metrics
659
+ ),
660
+ source: y.source
661
+ }
662
+ };
663
+ }
664
+ function zt(t = {}) {
665
+ return {
666
+ async detect(e) {
667
+ return kt(e, t);
668
+ }
669
+ };
670
+ }
671
+ var Bt = [
672
+ 278,
673
+ 278,
674
+ 355,
675
+ 556,
676
+ 556,
677
+ 889,
678
+ 667,
679
+ 191,
680
+ 333,
681
+ 333,
682
+ 389,
683
+ 584,
684
+ 278,
685
+ 333,
686
+ 278,
687
+ 278,
688
+ 556,
689
+ 556,
690
+ 556,
691
+ 556,
692
+ 556,
693
+ 556,
694
+ 556,
695
+ 556,
696
+ 556,
697
+ 556,
698
+ 278,
699
+ 278,
700
+ 584,
701
+ 584,
702
+ 584,
703
+ 556,
704
+ 1015,
705
+ 667,
706
+ 667,
707
+ 722,
708
+ 722,
709
+ 667,
710
+ 611,
711
+ 778,
712
+ 722,
713
+ 278,
714
+ 500,
715
+ 667,
716
+ 556,
717
+ 833,
718
+ 722,
719
+ 778,
720
+ 667,
721
+ 778,
722
+ 722,
723
+ 667,
724
+ 611,
725
+ 722,
726
+ 667,
727
+ 944,
728
+ 667,
729
+ 667,
730
+ 611,
731
+ 278,
732
+ 278,
733
+ 278,
734
+ 469,
735
+ 556,
736
+ 333,
737
+ 556,
738
+ 556,
739
+ 500,
740
+ 556,
741
+ 556,
742
+ 278,
743
+ 556,
744
+ 556,
745
+ 222,
746
+ 222,
747
+ 500,
748
+ 222,
749
+ 833,
750
+ 556,
751
+ 556,
752
+ 556,
753
+ 556,
754
+ 333,
755
+ 500,
756
+ 278,
757
+ 556,
758
+ 500,
759
+ 722,
760
+ 500,
761
+ 500,
762
+ 500,
763
+ 334,
764
+ 260,
765
+ 334,
766
+ 584
767
+ ], _t = /* @__PURE__ */ new Map([
768
+ [8364, 128],
769
+ [8218, 130],
770
+ [402, 131],
771
+ [8222, 132],
772
+ [8230, 133],
773
+ [8224, 134],
774
+ [8225, 135],
775
+ [710, 136],
776
+ [8240, 137],
777
+ [352, 138],
778
+ [8249, 139],
779
+ [338, 140],
780
+ [381, 142],
781
+ [8216, 145],
782
+ [8217, 146],
783
+ [8220, 147],
784
+ [8221, 148],
785
+ [8226, 149],
786
+ [8211, 150],
787
+ [8212, 151],
788
+ [732, 152],
789
+ [8482, 153],
790
+ [353, 154],
791
+ [8250, 155],
792
+ [339, 156],
793
+ [382, 158],
794
+ [376, 159]
795
+ ]);
796
+ class dt {
797
+ value;
798
+ constructor(e) {
799
+ this.value = e;
800
+ }
801
+ }
802
+ function st(t, e) {
803
+ G("Text size", e);
804
+ let n = 0;
805
+ for (const o of t) {
806
+ const i = gt(o);
807
+ n += i >= 32 && i <= 126 ? Bt[i - 32] : 556;
808
+ }
809
+ return n * e / 1e3;
810
+ }
811
+ function _(t, ...e) {
812
+ if (e.some((n) => !Number.isFinite(n)))
813
+ throw new TypeError(`${t} values must be finite numbers`);
814
+ }
815
+ function G(t, ...e) {
816
+ if (_(t, ...e), e.some((n) => n <= 0))
817
+ throw new RangeError(`${t} values must be greater than zero`);
818
+ }
819
+ function gt(t) {
820
+ const e = t.codePointAt(0), n = e <= 127 || e >= 160 && e <= 255 ? e : _t.get(e);
821
+ if (n === void 0)
822
+ throw new TypeError(`Unsupported character U+${e.toString(16).toUpperCase().padStart(4, "0")}; Helvetica text is limited to WinAnsi`);
823
+ return n;
824
+ }
825
+ function H(t) {
826
+ return !t || t === "none" || (t = t.replace(/^#/, ""), t.length === 3 && (t = t[0] + t[0] + t[1] + t[1] + t[2] + t[2]), !/^[0-9a-fA-F]{6}$/.test(t)) ? null : [parseInt(t.slice(0, 2), 16) / 255, parseInt(t.slice(2, 4), 16) / 255, parseInt(t.slice(4, 6), 16) / 255];
827
+ }
828
+ function J(t, e) {
829
+ return t ? `${t[0].toFixed(3)} ${t[1].toFixed(3)} ${t[2].toFixed(3)} ${e}` : "";
830
+ }
831
+ function Gt(t) {
832
+ if (t.length < 2 || t[0] !== 255 || t[1] !== 216)
833
+ throw new Error("Invalid JPEG: missing SOI marker");
834
+ let e = 2;
835
+ for (; e < t.length - 1; ) {
836
+ if (t[e] !== 255) {
837
+ e++;
838
+ continue;
839
+ }
840
+ const n = t[e + 1];
841
+ if (n === 218)
842
+ break;
843
+ if (n >= 192 && n <= 207 && ![196, 200, 204].includes(n)) {
844
+ if (e + 9 >= t.length)
845
+ break;
846
+ const a = t[e + 5] << 8 | t[e + 6], c = t[e + 7] << 8 | t[e + 8], r = t[e + 9];
847
+ if (c && a)
848
+ return { width: c, height: a, colorSpace: r === 1 ? "/DeviceGray" : r === 4 ? "/DeviceCMYK" : "/DeviceRGB" };
849
+ }
850
+ if (e + 3 >= t.length)
851
+ break;
852
+ const i = t[e + 2] << 8 | t[e + 3];
853
+ e += 2 + i;
854
+ }
855
+ throw new Error("Invalid JPEG: no valid SOF marker found");
856
+ }
857
+ function mt(t) {
858
+ let e = "(";
859
+ for (const n of t) {
860
+ const o = gt(n);
861
+ o === 92 || o === 40 || o === 41 ? e += "\\" + String.fromCharCode(o) : o === 13 ? e += "\\r" : o === 10 ? e += "\\n" : o < 32 || o >= 127 ? e += `\\${o.toString(8).padStart(3, "0")}` : e += String.fromCharCode(o);
862
+ }
863
+ return e + ")";
864
+ }
865
+ function Y(t) {
866
+ return t == null ? "null" : typeof t == "boolean" ? t ? "true" : "false" : typeof t == "number" ? Number.isInteger(t) ? String(t) : t.toFixed(4).replace(/\.?0+$/, "") : typeof t == "string" ? t : t instanceof dt ? mt(t.value) : Array.isArray(t) ? "[" + t.map(Y).join(" ") + "]" : t instanceof pt ? `${t.id} 0 R` : typeof t == "object" ? `<<
867
+ ` + Object.entries(t).filter(([n, o]) => o !== void 0).map(([n, o]) => `/${n} ${Y(o)}`).join(`
868
+ `) + `
869
+ >>` : String(t);
870
+ }
871
+ class pt {
872
+ id;
873
+ constructor(e) {
874
+ this.id = e;
875
+ }
876
+ }
877
+ function Qt() {
878
+ const t = [], e = [];
879
+ let n = 1;
880
+ function o(s, h = null) {
881
+ const d = n++;
882
+ return t.push({ id: d, dict: s, stream: h }), new pt(d);
883
+ }
884
+ function i(s, h, d) {
885
+ let p, y, m;
886
+ if (typeof s == "function" ? (p = 612, y = 792, m = s) : (p = s, y = h, m = d), G("Page dimensions", p, y), typeof m != "function")
887
+ throw new TypeError("page() requires a callback");
888
+ const x = [], b = [], u = [];
889
+ let g = 0;
890
+ m({
891
+ text(S, A, M, F, E = {}) {
892
+ _("Text coordinates", A, M), G("Text size", F);
893
+ const { align: v = "left", width: N, color: j = "#000000" } = E;
894
+ let O = A;
895
+ if (v !== "left" && N !== void 0) {
896
+ _("Text width", N);
897
+ const L = st(S, F);
898
+ v === "center" && (O = A + (N - L) / 2), v === "right" && (O = A + N - L);
899
+ }
900
+ const B = J(H(j), "rg") || "0.000 0.000 0.000 rg";
901
+ x.push(B, "BT", `/F1 ${F} Tf`, `${O.toFixed(2)} ${M.toFixed(2)} Td`, `${mt(S)} Tj`, "ET");
902
+ },
903
+ rect(S, A, M, F, E) {
904
+ _("Rectangle coordinates", S, A), G("Rectangle dimensions", M, F);
905
+ const v = J(H(E), "rg");
906
+ v && x.push(v, `${S.toFixed(2)} ${A.toFixed(2)} ${M.toFixed(2)} ${F.toFixed(2)} re`, "f");
907
+ },
908
+ line(S, A, M, F, E, v = 1) {
909
+ _("Line coordinates", S, A, M, F), G("Line width", v);
910
+ const N = J(H(E), "RG");
911
+ N && x.push(`${v.toFixed(2)} w`, N, `${S.toFixed(2)} ${A.toFixed(2)} m`, `${M.toFixed(2)} ${F.toFixed(2)} l`, "S");
912
+ },
913
+ image(S, A, M, F, E) {
914
+ _("Image coordinates", A, M), G("Image dimensions", F, E);
915
+ const { width: v, height: N, colorSpace: j } = Gt(S), O = `/Im${g++}`, B = o({
916
+ Type: "/XObject",
917
+ Subtype: "/Image",
918
+ Width: v,
919
+ Height: N,
920
+ ColorSpace: j,
921
+ BitsPerComponent: 8,
922
+ Filter: "/DCTDecode",
923
+ Length: S.length
924
+ }, S);
925
+ b.push({ name: O, ref: B }), x.push("q", `${F.toFixed(2)} 0 0 ${E.toFixed(2)} ${A.toFixed(2)} ${M.toFixed(2)} cm`, `${O} Do`, "Q");
926
+ },
927
+ link(S, A, M, F, E, v = {}) {
928
+ if (_("Link coordinates", A, M), G("Link dimensions", F, E), u.push({ url: S, rect: [A, M, A + F, M + E] }), v.underline) {
929
+ const N = J(H(v.underline), "RG");
930
+ N && x.push("0.75 w", N, `${A.toFixed(2)} ${(M + 2).toFixed(2)} m`, `${(A + F).toFixed(2)} ${(M + 2).toFixed(2)} l`, "S");
931
+ }
932
+ }
933
+ });
934
+ const P = x.join(`
935
+ `), T = new TextEncoder().encode(P), U = o({ Length: T.length }, T), I = {};
936
+ for (const S of b)
937
+ I[S.name.slice(1)] = S.ref;
938
+ const w = u.map((S) => o({
939
+ Type: "/Annot",
940
+ Subtype: "/Link",
941
+ Rect: S.rect,
942
+ Border: [0, 0, 0],
943
+ A: { Type: "/Action", S: "/URI", URI: new dt(S.url) }
944
+ }));
945
+ e.push(o({
946
+ Type: "/Page",
947
+ Parent: null,
948
+ MediaBox: [0, 0, p, y],
949
+ Contents: U,
950
+ Resources: { Font: { F1: null }, XObject: Object.keys(I).length > 0 ? I : void 0 },
951
+ Annots: w.length > 0 ? w : void 0
952
+ }));
953
+ }
954
+ let a = !1;
955
+ function c() {
956
+ if (!e.length)
957
+ throw new Error("PDF must have at least one page");
958
+ if (a)
959
+ throw new Error("build() can only be called once");
960
+ a = !0;
961
+ const s = o({ Type: "/Font", Subtype: "/Type1", BaseFont: "/Helvetica", Encoding: "/WinAnsiEncoding" }), h = o({ Type: "/Pages", Kids: e, Count: e.length });
962
+ for (const d of t)
963
+ if (d.dict.Type === "/Page") {
964
+ d.dict.Parent = h;
965
+ const p = d.dict.Resources;
966
+ p?.Font && (p.Font.F1 = s);
967
+ }
968
+ return o({ Type: "/Catalog", Pages: h });
969
+ }
970
+ function* r(s) {
971
+ const h = new TextEncoder(), d = [];
972
+ let p = 0;
973
+ const y = h.encode(`%PDF-1.4
974
+ %ÿÿÿÿ
975
+ `);
976
+ p += y.length, yield y;
977
+ for (const b of t) {
978
+ d[b.id] = p;
979
+ const u = `${b.id} 0 obj
980
+ ${Y(b.dict)}
981
+ `;
982
+ if (b.stream) {
983
+ const g = h.encode(u + `stream
984
+ `), C = b.stream, P = h.encode(`
985
+ endstream
986
+ endobj
987
+ `);
988
+ p += g.length, yield g, p += C.length, yield C, p += P.length, b.stream = null, yield P;
989
+ } else {
990
+ const g = h.encode(u + `endobj
991
+ `);
992
+ p += g.length, yield g;
993
+ }
994
+ }
995
+ const m = p;
996
+ let x = `xref
997
+ 0 ${t.length + 1}
998
+ 0000000000 65535 f
999
+ `;
1000
+ for (let b = 1; b <= t.length; b++)
1001
+ x += String(d[b]).padStart(10, "0") + ` 00000 n
1002
+ `;
1003
+ x += `trailer
1004
+ ${Y({ Size: t.length + 1, Root: s })}
1005
+ `, x += `startxref
1006
+ ${m}
1007
+ %%EOF
1008
+ `, yield h.encode(x);
1009
+ }
1010
+ function l() {
1011
+ const s = [];
1012
+ let h = 0;
1013
+ for (const y of r(c()))
1014
+ s.push(y), h += y.length;
1015
+ const d = new Uint8Array(h);
1016
+ let p = 0;
1017
+ for (const y of s)
1018
+ d.set(y, p), p += y.length;
1019
+ return d;
1020
+ }
1021
+ function f() {
1022
+ const s = r(c());
1023
+ return new ReadableStream({
1024
+ pull(h) {
1025
+ const { done: d, value: p } = s.next();
1026
+ d ? h.close() : h.enqueue(p);
1027
+ }
1028
+ });
1029
+ }
1030
+ return { page: i, build: l, buildStream: f, measureText: st };
1031
+ }
1032
+ function Vt(t) {
1033
+ if (!Number.isSafeInteger(t.maxBytes) || t.maxBytes < 1)
1034
+ throw new $(
1035
+ "INVALID_INPUT",
1036
+ "maxBytes must be a positive integer number of bytes."
1037
+ );
1038
+ const e = t.minQuality ?? 0.65, n = t.minLongEdge ?? 1600;
1039
+ if (!Number.isFinite(e) || e < 0.1 || e > 0.9)
1040
+ throw new $(
1041
+ "INVALID_INPUT",
1042
+ "minQuality must be between 0.1 and 0.9."
1043
+ );
1044
+ if (!Number.isSafeInteger(n) || n < 128 || n > 2400)
1045
+ throw new $(
1046
+ "INVALID_INPUT",
1047
+ "minLongEdge must be an integer between 128 and 2400."
1048
+ );
1049
+ if (t.pageSize && !["a4", "letter", "image"].includes(t.pageSize))
1050
+ throw new $("INVALID_INPUT", "Unknown PDF page size.");
1051
+ }
1052
+ async function ct(t, e = "a4") {
1053
+ if (!t.length)
1054
+ throw new $(
1055
+ "INVALID_INPUT",
1056
+ "Add at least one page before exporting."
1057
+ );
1058
+ const n = Qt();
1059
+ for (const o of t) {
1060
+ const i = new Uint8Array(await o.jpeg.arrayBuffer());
1061
+ if (o.jpeg.type !== "image/jpeg" || i[0] !== 255 || i[1] !== 216)
1062
+ throw new $(
1063
+ "PROCESSING_FAILED",
1064
+ "The browser did not produce a valid JPEG."
1065
+ );
1066
+ const a = e === "a4" ? [595.28, 841.89] : e === "letter" ? [612, 792] : [o.width * 0.75, o.height * 0.75], c = Math.min(a[0] / o.width, a[1] / o.height), r = o.width * c, l = o.height * c;
1067
+ n.page(
1068
+ a[0],
1069
+ a[1],
1070
+ (f) => f.image(i, (a[0] - r) / 2, (a[1] - l) / 2, r, l)
1071
+ );
1072
+ }
1073
+ return new Response(n.buildStream(), {
1074
+ headers: { "Content-Type": "application/pdf" }
1075
+ }).blob();
1076
+ }
1077
+ async function qt(t, e, n, o) {
1078
+ if (Vt(n), !t.length)
1079
+ throw new $(
1080
+ "INVALID_INPUT",
1081
+ "Add at least one page before exporting."
1082
+ );
1083
+ const i = t.map(() => 0), a = n.pageSize ?? "a4", c = async (s, h, d) => {
1084
+ if (V(n.signal), i[s] >= 12)
1085
+ throw new $(
1086
+ "PROCESSING_FAILED",
1087
+ "Encoding attempt limit reached."
1088
+ );
1089
+ i[s]++;
1090
+ const p = await e.encode(s, h, d);
1091
+ return V(n.signal), p;
1092
+ }, r = [];
1093
+ for (let s = 0; s < t.length; s++)
1094
+ r.push(await c(s, 2400, 0.9)), o?.((s + 1) / t.length * 0.35);
1095
+ let l = await ct(r, a);
1096
+ if (V(n.signal), l.size > n.maxBytes) {
1097
+ const s = r.map((m) => m.jpeg.size);
1098
+ let h = Math.max(
1099
+ 0,
1100
+ n.maxBytes - (l.size - s.reduce((m, x) => m + x, 0)) - 1024
1101
+ ), d = s.reduce((m, x) => m + x, 0);
1102
+ const p = n.minQuality ?? 0.65, y = [
1103
+ ...new Set(
1104
+ [0.9, 0.8, 0.7, p].filter((m) => m >= p)
1105
+ )
1106
+ ];
1107
+ for (let m = 0; m < t.length; m++) {
1108
+ const x = Math.max(
1109
+ 0,
1110
+ Math.floor(h * s[m] / d)
1111
+ ), b = r[m], u = Math.max(b.width, b.height), g = Math.min(u, n.minLongEdge ?? 1600), C = [
1112
+ .../* @__PURE__ */ new Set([u, Math.round((u + g) / 2), g])
1113
+ ];
1114
+ let P = b, T = b.jpeg.size <= x;
1115
+ t: for (const U of C)
1116
+ for (const I of y) {
1117
+ if (T) break t;
1118
+ if (U === u && I === 0.9) continue;
1119
+ const w = await c(m, U, I);
1120
+ if (w.jpeg.size < P.jpeg.size && (P = w), w.jpeg.size <= x) {
1121
+ P = w, T = !0;
1122
+ break t;
1123
+ }
1124
+ }
1125
+ r[m] = P, h -= P.jpeg.size, d -= s[m], o?.(0.35 + (m + 1) / t.length * 0.6);
1126
+ }
1127
+ l = await ct(r, a);
1128
+ }
1129
+ V(n.signal);
1130
+ const f = {
1131
+ bytes: l.size,
1132
+ maxBytes: n.maxBytes,
1133
+ pageSize: a,
1134
+ limits: {
1135
+ minQuality: n.minQuality ?? 0.65,
1136
+ minLongEdge: n.minLongEdge ?? 1600,
1137
+ maxEncodesPerPage: 12
1138
+ },
1139
+ pages: r.map(
1140
+ (s, h) => ({
1141
+ id: s.id,
1142
+ imageBytes: s.jpeg.size,
1143
+ width: s.width,
1144
+ height: s.height,
1145
+ quality: s.quality,
1146
+ attempts: i[h],
1147
+ warnings: s.warnings,
1148
+ preview: s.jpeg
1149
+ })
1150
+ )
1151
+ };
1152
+ return o?.(1), {
1153
+ status: l.size <= n.maxBytes ? "ready" : "cannot-fit",
1154
+ blob: l,
1155
+ report: f
1156
+ };
1157
+ }
1158
+ const z = () => new $(
1159
+ "INVALID_INPUT",
1160
+ "The image header is incomplete or invalid. Choose another photo."
1161
+ );
1162
+ function et(t, e, n) {
1163
+ try {
1164
+ if (e + 8 > n) return;
1165
+ const o = t.getUint32(e) === 1165519206 && t.getUint16(e + 4) === 0, i = e + (o ? 6 : 0);
1166
+ if (i + 8 > n) return;
1167
+ const a = t.getUint16(i) === 18761;
1168
+ if (!a && t.getUint16(i) !== 19789 || t.getUint16(i + 2, a) !== 42)
1169
+ return;
1170
+ const c = i + t.getUint32(i + 4, a);
1171
+ if (c < i || c + 2 > n) return;
1172
+ const r = Math.min(t.getUint16(c, a), 256);
1173
+ for (let l = 0; l < r; l++) {
1174
+ const f = c + 2 + l * 12;
1175
+ if (f + 12 > n) return;
1176
+ if (t.getUint16(f, a) === 274 && t.getUint16(f + 2, a) === 3 && t.getUint32(f + 4, a) === 1) {
1177
+ const s = t.getUint16(f + 8, a);
1178
+ return s >= 1 && s <= 8 ? s : void 0;
1179
+ }
1180
+ }
1181
+ } catch {
1182
+ }
1183
+ }
1184
+ function Wt(t) {
1185
+ const e = new DataView(t.buffer, t.byteOffset, t.byteLength);
1186
+ let n = 0, o = 0, i = 1, a = !1, c = "";
1187
+ const r = (l) => {
1188
+ !a && l !== void 0 && (i = l, a = !0);
1189
+ };
1190
+ if (t.length >= 24 && e.getUint32(0) === 2303741511 && e.getUint32(4) === 218765834) {
1191
+ if (e.getUint32(12) !== 1229472850 || e.getUint32(8) !== 13) throw z();
1192
+ n = e.getUint32(16), o = e.getUint32(20), c = "image/png";
1193
+ for (let l = 8; l + 12 <= t.length; ) {
1194
+ const f = e.getUint32(l), s = e.getUint32(l + 4), h = l + 8;
1195
+ if (h + f + 4 > t.length) throw z();
1196
+ if (s === 1633899596)
1197
+ throw new $(
1198
+ "UNSUPPORTED_FORMAT",
1199
+ "Animated PNG is not supported. Choose a still photo."
1200
+ );
1201
+ s === 1700284774 && r(et(e, h, h + f)), l = h + f + 4;
1202
+ }
1203
+ } else if (t.length >= 4 && e.getUint16(0) === 65496) {
1204
+ c = "image/jpeg";
1205
+ let l = 2;
1206
+ for (; l + 3 < t.length; ) {
1207
+ if (t[l++] !== 255) throw z();
1208
+ for (; t[l] === 255; ) l++;
1209
+ const f = t[l++];
1210
+ if (f === 218 || f === 217) break;
1211
+ if (f === 1 || f >= 208 && f <= 215) continue;
1212
+ if (l + 2 > t.length) throw z();
1213
+ const s = e.getUint16(l);
1214
+ if (s < 2 || l + s > t.length) throw z();
1215
+ if (f === 225 && s >= 8 && e.getUint32(l + 2) === 1165519206 && e.getUint16(l + 6) === 0 && r(et(e, l + 2, l + s)), f >= 192 && f <= 207 && ![196, 200, 204].includes(f)) {
1216
+ if (s < 8) throw z();
1217
+ const h = e.getUint16(l + 3), d = e.getUint16(l + 5);
1218
+ if (n && n !== d || o && o !== h) throw z();
1219
+ o = h, n = d;
1220
+ }
1221
+ l += s;
1222
+ }
1223
+ } else if (t.length >= 30 && e.getUint32(0) === 1380533830 && e.getUint32(8) === 1464156752) {
1224
+ c = "image/webp";
1225
+ for (let l = 12; l + 8 <= t.length; ) {
1226
+ const f = e.getUint32(l), s = e.getUint32(l + 4, !0), h = l + 8;
1227
+ if (h + s > t.length) throw z();
1228
+ if (f === 1448097880 && s >= 10) {
1229
+ if (t[h] & 2)
1230
+ throw new $(
1231
+ "UNSUPPORTED_FORMAT",
1232
+ "Animated WebP is not supported. Choose a still photo."
1233
+ );
1234
+ n = Math.max(
1235
+ n,
1236
+ 1 + t[h + 4] + (t[h + 5] << 8) + (t[h + 6] << 16)
1237
+ ), o = Math.max(
1238
+ o,
1239
+ 1 + t[h + 7] + (t[h + 8] << 8) + (t[h + 9] << 16)
1240
+ );
1241
+ }
1242
+ if (f === 1448097824 && s >= 10 && t[h + 3] === 157 && t[h + 4] === 1 && t[h + 5] === 42 && (n = Math.max(n, e.getUint16(h + 6, !0) & 16383), o = Math.max(o, e.getUint16(h + 8, !0) & 16383)), f === 1448097868 && s >= 5 && t[h] === 47) {
1243
+ const d = e.getUint32(h + 1, !0);
1244
+ n = Math.max(n, (d & 16383) + 1), o = Math.max(o, (d >>> 14 & 16383) + 1);
1245
+ }
1246
+ f === 1163413830 && r(et(e, h, h + s)), l = h + s + (s & 1);
1247
+ }
1248
+ } else
1249
+ throw new $(
1250
+ "UNSUPPORTED_FORMAT",
1251
+ "Choose a JPEG, PNG, or WebP photo. PDF and HEIC imports are not included in this beta."
1252
+ );
1253
+ if (!n || !o || !Number.isSafeInteger(n * o)) throw z();
1254
+ return { width: n, height: o, orientation: i, mime: c };
1255
+ }
1256
+ async function Ht(t) {
1257
+ const e = new Uint8Array(await t.arrayBuffer());
1258
+ if (e.length < 4 || e[0] !== 255 || e[1] !== 216)
1259
+ return t;
1260
+ const n = [];
1261
+ let o = 2, i = 0, a = !1;
1262
+ for (; o + 3 < e.length && e[o] === 255; ) {
1263
+ const c = o;
1264
+ for (; e[o] === 255; ) o++;
1265
+ const r = e[o++];
1266
+ if (r === 218 || r === 217) break;
1267
+ if (r === 1 || r >= 208 && r <= 215) continue;
1268
+ if (o + 2 > e.length) break;
1269
+ const l = e[o] << 8 | e[o + 1];
1270
+ if (l < 2 || o + l > e.length) break;
1271
+ const f = o + l;
1272
+ r === 225 && (n.push(e.slice(i, c)), i = f, a = !0), o = f;
1273
+ }
1274
+ return a ? (n.push(e.slice(i)), new Blob(n, { type: "image/jpeg" })) : t;
1275
+ }
1276
+ const Q = self;
1277
+ let Jt = 0;
1278
+ const ot = /* @__PURE__ */ new Map();
1279
+ function yt(t) {
1280
+ return new Promise((e, n) => {
1281
+ const o = ++Jt;
1282
+ ot.set(o, { resolve: e, reject: n }), Q.postMessage(
1283
+ { type: "bridge", id: o, action: t },
1284
+ t.kind === "encode" ? [t.buffer] : []
1285
+ );
1286
+ });
1287
+ }
1288
+ let nt, lt;
1289
+ async function it(t, e, n = 2400, o) {
1290
+ const i = e.orientation >= 5, a = rt(
1291
+ o?.width ?? (i ? e.height : e.width),
1292
+ o?.height ?? (i ? e.width : e.height),
1293
+ n
1294
+ );
1295
+ if (typeof OffscreenCanvas < "u" && typeof createImageBitmap == "function") {
1296
+ let r, l;
1297
+ try {
1298
+ const f = {
1299
+ imageOrientation: "from-image",
1300
+ resizeWidth: a.width,
1301
+ resizeHeight: a.height,
1302
+ resizeQuality: "high"
1303
+ };
1304
+ r = o ? await createImageBitmap(
1305
+ t,
1306
+ o.x,
1307
+ o.y,
1308
+ o.width,
1309
+ o.height,
1310
+ f
1311
+ ) : await createImageBitmap(t, f), l = new OffscreenCanvas(a.width, a.height);
1312
+ const s = l.getContext("2d", { willReadFrequently: !0 });
1313
+ return s.drawImage(r, 0, 0, a.width, a.height), s.getImageData(0, 0, a.width, a.height);
1314
+ } catch {
1315
+ } finally {
1316
+ r?.close(), l && (l.width = l.height = 0);
1317
+ }
1318
+ }
1319
+ const c = await yt({ kind: "decode", blob: t, ...a, region: o });
1320
+ return new ImageData(
1321
+ new Uint8ClampedArray(c.buffer),
1322
+ c.width,
1323
+ c.height
1324
+ );
1325
+ }
1326
+ async function K(t, e, n) {
1327
+ const o = rt(t.width, t.height, e);
1328
+ if (typeof OffscreenCanvas < "u") {
1329
+ const i = new OffscreenCanvas(t.width, t.height), a = new OffscreenCanvas(o.width, o.height);
1330
+ try {
1331
+ i.getContext("2d").putImageData(t, 0, 0);
1332
+ const c = a.getContext("2d");
1333
+ c.fillStyle = "#fff", c.fillRect(0, 0, a.width, a.height), c.drawImage(i, 0, 0, a.width, a.height);
1334
+ const r = await a.convertToBlob({ type: "image/jpeg", quality: n });
1335
+ if (r.type === "image/jpeg")
1336
+ return { blob: await Ht(r), ...o };
1337
+ } catch {
1338
+ } finally {
1339
+ i.width = i.height = a.width = a.height = 0;
1340
+ }
1341
+ }
1342
+ return yt({
1343
+ kind: "encode",
1344
+ buffer: t.data.slice().buffer,
1345
+ width: t.width,
1346
+ height: t.height,
1347
+ quality: n,
1348
+ longEdge: e
1349
+ });
1350
+ }
1351
+ function Kt(t) {
1352
+ const { width: e, height: n, data: o } = t;
1353
+ let i = 0, a = 0, c = 0;
1354
+ const r = (f) => 0.2126 * o[f] + 0.7152 * o[f + 1] + 0.0722 * o[f + 2];
1355
+ for (let f = 1; f < n - 1; f += 3)
1356
+ for (let s = 1; s < e - 1; s += 3) {
1357
+ const h = (f * e + s) * 4, d = r(h);
1358
+ i += d;
1359
+ const p = r(h - 4) + r(h + 4) + r(h - e * 4) + r(h + e * 4) - 4 * d;
1360
+ a += p * p, c++;
1361
+ }
1362
+ const l = [];
1363
+ return c && i / c < 55 && l.push("possibly-dark"), c && a / c < 12 && l.push("possibly-blurry"), l;
1364
+ }
1365
+ async function ft(t) {
1366
+ const e = Wt(
1367
+ new Uint8Array(await t.source.arrayBuffer())
1368
+ ), n = t.edits.corners.map((r) => ({
1369
+ x: r.x * (t.width - 1),
1370
+ y: r.y * (t.height - 1)
1371
+ })), o = Math.floor(Math.min(...n.map((r) => r.x))), i = Math.floor(Math.min(...n.map((r) => r.y))), a = {
1372
+ x: o,
1373
+ y: i,
1374
+ width: Math.ceil(Math.max(...n.map((r) => r.x))) - o + 1,
1375
+ height: Math.ceil(Math.max(...n.map((r) => r.y))) - i + 1
1376
+ }, c = n.map((r) => ({
1377
+ x: (r.x - o) / Math.max(1, a.width - 1),
1378
+ y: (r.y - i) / Math.max(1, a.height - 1)
1379
+ }));
1380
+ return bt(await it(t.source, e, 2400, a), {
1381
+ ...t.edits,
1382
+ corners: c
1383
+ });
1384
+ }
1385
+ async function Xt(t, e) {
1386
+ if (t.kind === "analyze") {
1387
+ const i = await it(t.blob, t.header, 1200), a = await it(t.blob, t.header, 800);
1388
+ let c = wt(xt), r;
1389
+ const l = Kt(a);
1390
+ if (t.options.detector !== "none")
1391
+ try {
1392
+ (!nt || lt !== t.options.detectorModule) && (nt = t.options.detectorModule ? await (await import(
1393
+ /* @vite-ignore */
1394
+ t.options.detectorModule
1395
+ )).createDetector(t.options.detectorOptions) : zt(t.options.detectorOptions), lt = t.options.detectorModule);
1396
+ const y = await nt.detect(a);
1397
+ r = y.diagnostics, y.corners ? c = y.corners : l.push("manual-crop");
1398
+ } catch {
1399
+ l.push("detection-unavailable", "manual-crop");
1400
+ }
1401
+ else l.push("manual-crop");
1402
+ const f = await K(i, 1200, 0.88), s = await K(i, 256, 0.75), h = t.header.orientation >= 5, d = h ? t.header.height : t.header.width, p = h ? t.header.width : t.header.height;
1403
+ return Math.max(d, p) < 1600 && l.push("low-resolution"), {
1404
+ preview: f.blob,
1405
+ thumbnail: s.blob,
1406
+ width: d,
1407
+ height: p,
1408
+ corners: c,
1409
+ warnings: l,
1410
+ detection: r
1411
+ };
1412
+ }
1413
+ if (t.kind === "render")
1414
+ return (await K(await ft(t.page), 1200, 0.88)).blob;
1415
+ let n = -1, o = null;
1416
+ try {
1417
+ return await qt(
1418
+ t.pages,
1419
+ {
1420
+ async encode(i, a, c) {
1421
+ n !== i && (o = null, o = await ft(t.pages[i]), n = i);
1422
+ const r = await K(o, a, c), l = t.pages[i];
1423
+ return {
1424
+ id: l.id,
1425
+ jpeg: r.blob,
1426
+ width: r.width,
1427
+ height: r.height,
1428
+ quality: c,
1429
+ warnings: l.warnings
1430
+ };
1431
+ }
1432
+ },
1433
+ t.options,
1434
+ (i) => Q.postMessage({ type: "progress", id: e, value: i })
1435
+ );
1436
+ } finally {
1437
+ o = null;
1438
+ }
1439
+ }
1440
+ Q.onmessage = (t) => {
1441
+ const e = t.data;
1442
+ if (e.type === "bridge-result") {
1443
+ const n = ot.get(e.id);
1444
+ n && (ot.delete(e.id), e.error ? n.reject(new Error(e.error)) : n.resolve(e.result));
1445
+ return;
1446
+ }
1447
+ Xt(e.task, e.id).then((n) => Q.postMessage({ id: e.id, result: n })).catch(
1448
+ (n) => Q.postMessage({
1449
+ id: e.id,
1450
+ error: {
1451
+ code: n.code ?? "PROCESSING_FAILED",
1452
+ message: n.message ?? "Document processing failed."
1453
+ }
1454
+ })
1455
+ );
1456
+ };