image-pii-redactor 0.1.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,2017 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2019 Google LLC
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ */
6
+ const B = globalThis, Q = B.ShadowRoot && (B.ShadyCSS === void 0 || B.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, tt = Symbol(), ot = /* @__PURE__ */ new WeakMap();
7
+ let bt = class {
8
+ constructor(t, r, s) {
9
+ if (this._$cssResult$ = !0, s !== tt) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");
10
+ this.cssText = t, this.t = r;
11
+ }
12
+ get styleSheet() {
13
+ let t = this.o;
14
+ const r = this.t;
15
+ if (Q && t === void 0) {
16
+ const s = r !== void 0 && r.length === 1;
17
+ s && (t = ot.get(r)), t === void 0 && ((this.o = t = new CSSStyleSheet()).replaceSync(this.cssText), s && ot.set(r, t));
18
+ }
19
+ return t;
20
+ }
21
+ toString() {
22
+ return this.cssText;
23
+ }
24
+ };
25
+ const Pt = (e) => new bt(typeof e == "string" ? e : e + "", void 0, tt), Tt = (e, ...t) => {
26
+ const r = e.length === 1 ? e[0] : t.reduce((s, i, n) => s + ((o) => {
27
+ if (o._$cssResult$ === !0) return o.cssText;
28
+ if (typeof o == "number") return o;
29
+ throw Error("Value passed to 'css' function must be a 'css' function result: " + o + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.");
30
+ })(i) + e[n + 1], e[0]);
31
+ return new bt(r, e, tt);
32
+ }, Ot = (e, t) => {
33
+ if (Q) e.adoptedStyleSheets = t.map((r) => r instanceof CSSStyleSheet ? r : r.styleSheet);
34
+ else for (const r of t) {
35
+ const s = document.createElement("style"), i = B.litNonce;
36
+ i !== void 0 && s.setAttribute("nonce", i), s.textContent = r.cssText, e.appendChild(s);
37
+ }
38
+ }, at = Q ? (e) => e : (e) => e instanceof CSSStyleSheet ? ((t) => {
39
+ let r = "";
40
+ for (const s of t.cssRules) r += s.cssText;
41
+ return Pt(r);
42
+ })(e) : e;
43
+ /**
44
+ * @license
45
+ * Copyright 2017 Google LLC
46
+ * SPDX-License-Identifier: BSD-3-Clause
47
+ */
48
+ const { is: Rt, defineProperty: Ut, getOwnPropertyDescriptor: Dt, getOwnPropertyNames: zt, getOwnPropertySymbols: Nt, getPrototypeOf: Ht } = Object, q = globalThis, lt = q.trustedTypes, It = lt ? lt.emptyScript : "", Lt = q.reactiveElementPolyfillSupport, O = (e, t) => e, j = { toAttribute(e, t) {
49
+ switch (t) {
50
+ case Boolean:
51
+ e = e ? It : null;
52
+ break;
53
+ case Object:
54
+ case Array:
55
+ e = e == null ? e : JSON.stringify(e);
56
+ }
57
+ return e;
58
+ }, fromAttribute(e, t) {
59
+ let r = e;
60
+ switch (t) {
61
+ case Boolean:
62
+ r = e !== null;
63
+ break;
64
+ case Number:
65
+ r = e === null ? null : Number(e);
66
+ break;
67
+ case Object:
68
+ case Array:
69
+ try {
70
+ r = JSON.parse(e);
71
+ } catch {
72
+ r = null;
73
+ }
74
+ }
75
+ return r;
76
+ } }, et = (e, t) => !Rt(e, t), ct = { attribute: !0, type: String, converter: j, reflect: !1, useDefault: !1, hasChanged: et };
77
+ Symbol.metadata ??= Symbol("metadata"), q.litPropertyMetadata ??= /* @__PURE__ */ new WeakMap();
78
+ let M = class extends HTMLElement {
79
+ static addInitializer(t) {
80
+ this._$Ei(), (this.l ??= []).push(t);
81
+ }
82
+ static get observedAttributes() {
83
+ return this.finalize(), this._$Eh && [...this._$Eh.keys()];
84
+ }
85
+ static createProperty(t, r = ct) {
86
+ if (r.state && (r.attribute = !1), this._$Ei(), this.prototype.hasOwnProperty(t) && ((r = Object.create(r)).wrapped = !0), this.elementProperties.set(t, r), !r.noAccessor) {
87
+ const s = Symbol(), i = this.getPropertyDescriptor(t, s, r);
88
+ i !== void 0 && Ut(this.prototype, t, i);
89
+ }
90
+ }
91
+ static getPropertyDescriptor(t, r, s) {
92
+ const { get: i, set: n } = Dt(this.prototype, t) ?? { get() {
93
+ return this[r];
94
+ }, set(o) {
95
+ this[r] = o;
96
+ } };
97
+ return { get: i, set(o) {
98
+ const a = i?.call(this);
99
+ n?.call(this, o), this.requestUpdate(t, a, s);
100
+ }, configurable: !0, enumerable: !0 };
101
+ }
102
+ static getPropertyOptions(t) {
103
+ return this.elementProperties.get(t) ?? ct;
104
+ }
105
+ static _$Ei() {
106
+ if (this.hasOwnProperty(O("elementProperties"))) return;
107
+ const t = Ht(this);
108
+ t.finalize(), t.l !== void 0 && (this.l = [...t.l]), this.elementProperties = new Map(t.elementProperties);
109
+ }
110
+ static finalize() {
111
+ if (this.hasOwnProperty(O("finalized"))) return;
112
+ if (this.finalized = !0, this._$Ei(), this.hasOwnProperty(O("properties"))) {
113
+ const r = this.properties, s = [...zt(r), ...Nt(r)];
114
+ for (const i of s) this.createProperty(i, r[i]);
115
+ }
116
+ const t = this[Symbol.metadata];
117
+ if (t !== null) {
118
+ const r = litPropertyMetadata.get(t);
119
+ if (r !== void 0) for (const [s, i] of r) this.elementProperties.set(s, i);
120
+ }
121
+ this._$Eh = /* @__PURE__ */ new Map();
122
+ for (const [r, s] of this.elementProperties) {
123
+ const i = this._$Eu(r, s);
124
+ i !== void 0 && this._$Eh.set(i, r);
125
+ }
126
+ this.elementStyles = this.finalizeStyles(this.styles);
127
+ }
128
+ static finalizeStyles(t) {
129
+ const r = [];
130
+ if (Array.isArray(t)) {
131
+ const s = new Set(t.flat(1 / 0).reverse());
132
+ for (const i of s) r.unshift(at(i));
133
+ } else t !== void 0 && r.push(at(t));
134
+ return r;
135
+ }
136
+ static _$Eu(t, r) {
137
+ const s = r.attribute;
138
+ return s === !1 ? void 0 : typeof s == "string" ? s : typeof t == "string" ? t.toLowerCase() : void 0;
139
+ }
140
+ constructor() {
141
+ super(), this._$Ep = void 0, this.isUpdatePending = !1, this.hasUpdated = !1, this._$Em = null, this._$Ev();
142
+ }
143
+ _$Ev() {
144
+ this._$ES = new Promise((t) => this.enableUpdating = t), this._$AL = /* @__PURE__ */ new Map(), this._$E_(), this.requestUpdate(), this.constructor.l?.forEach((t) => t(this));
145
+ }
146
+ addController(t) {
147
+ (this._$EO ??= /* @__PURE__ */ new Set()).add(t), this.renderRoot !== void 0 && this.isConnected && t.hostConnected?.();
148
+ }
149
+ removeController(t) {
150
+ this._$EO?.delete(t);
151
+ }
152
+ _$E_() {
153
+ const t = /* @__PURE__ */ new Map(), r = this.constructor.elementProperties;
154
+ for (const s of r.keys()) this.hasOwnProperty(s) && (t.set(s, this[s]), delete this[s]);
155
+ t.size > 0 && (this._$Ep = t);
156
+ }
157
+ createRenderRoot() {
158
+ const t = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions);
159
+ return Ot(t, this.constructor.elementStyles), t;
160
+ }
161
+ connectedCallback() {
162
+ this.renderRoot ??= this.createRenderRoot(), this.enableUpdating(!0), this._$EO?.forEach((t) => t.hostConnected?.());
163
+ }
164
+ enableUpdating(t) {
165
+ }
166
+ disconnectedCallback() {
167
+ this._$EO?.forEach((t) => t.hostDisconnected?.());
168
+ }
169
+ attributeChangedCallback(t, r, s) {
170
+ this._$AK(t, s);
171
+ }
172
+ _$ET(t, r) {
173
+ const s = this.constructor.elementProperties.get(t), i = this.constructor._$Eu(t, s);
174
+ if (i !== void 0 && s.reflect === !0) {
175
+ const n = (s.converter?.toAttribute !== void 0 ? s.converter : j).toAttribute(r, s.type);
176
+ this._$Em = t, n == null ? this.removeAttribute(i) : this.setAttribute(i, n), this._$Em = null;
177
+ }
178
+ }
179
+ _$AK(t, r) {
180
+ const s = this.constructor, i = s._$Eh.get(t);
181
+ if (i !== void 0 && this._$Em !== i) {
182
+ const n = s.getPropertyOptions(i), o = typeof n.converter == "function" ? { fromAttribute: n.converter } : n.converter?.fromAttribute !== void 0 ? n.converter : j;
183
+ this._$Em = i;
184
+ const a = o.fromAttribute(r, n.type);
185
+ this[i] = a ?? this._$Ej?.get(i) ?? a, this._$Em = null;
186
+ }
187
+ }
188
+ requestUpdate(t, r, s, i = !1, n) {
189
+ if (t !== void 0) {
190
+ const o = this.constructor;
191
+ if (i === !1 && (n = this[t]), s ??= o.getPropertyOptions(t), !((s.hasChanged ?? et)(n, r) || s.useDefault && s.reflect && n === this._$Ej?.get(t) && !this.hasAttribute(o._$Eu(t, s)))) return;
192
+ this.C(t, r, s);
193
+ }
194
+ this.isUpdatePending === !1 && (this._$ES = this._$EP());
195
+ }
196
+ C(t, r, { useDefault: s, reflect: i, wrapped: n }, o) {
197
+ s && !(this._$Ej ??= /* @__PURE__ */ new Map()).has(t) && (this._$Ej.set(t, o ?? r ?? this[t]), n !== !0 || o !== void 0) || (this._$AL.has(t) || (this.hasUpdated || s || (r = void 0), this._$AL.set(t, r)), i === !0 && this._$Em !== t && (this._$Eq ??= /* @__PURE__ */ new Set()).add(t));
198
+ }
199
+ async _$EP() {
200
+ this.isUpdatePending = !0;
201
+ try {
202
+ await this._$ES;
203
+ } catch (r) {
204
+ Promise.reject(r);
205
+ }
206
+ const t = this.scheduleUpdate();
207
+ return t != null && await t, !this.isUpdatePending;
208
+ }
209
+ scheduleUpdate() {
210
+ return this.performUpdate();
211
+ }
212
+ performUpdate() {
213
+ if (!this.isUpdatePending) return;
214
+ if (!this.hasUpdated) {
215
+ if (this.renderRoot ??= this.createRenderRoot(), this._$Ep) {
216
+ for (const [i, n] of this._$Ep) this[i] = n;
217
+ this._$Ep = void 0;
218
+ }
219
+ const s = this.constructor.elementProperties;
220
+ if (s.size > 0) for (const [i, n] of s) {
221
+ const { wrapped: o } = n, a = this[i];
222
+ o !== !0 || this._$AL.has(i) || a === void 0 || this.C(i, void 0, n, a);
223
+ }
224
+ }
225
+ let t = !1;
226
+ const r = this._$AL;
227
+ try {
228
+ t = this.shouldUpdate(r), t ? (this.willUpdate(r), this._$EO?.forEach((s) => s.hostUpdate?.()), this.update(r)) : this._$EM();
229
+ } catch (s) {
230
+ throw t = !1, this._$EM(), s;
231
+ }
232
+ t && this._$AE(r);
233
+ }
234
+ willUpdate(t) {
235
+ }
236
+ _$AE(t) {
237
+ this._$EO?.forEach((r) => r.hostUpdated?.()), this.hasUpdated || (this.hasUpdated = !0, this.firstUpdated(t)), this.updated(t);
238
+ }
239
+ _$EM() {
240
+ this._$AL = /* @__PURE__ */ new Map(), this.isUpdatePending = !1;
241
+ }
242
+ get updateComplete() {
243
+ return this.getUpdateComplete();
244
+ }
245
+ getUpdateComplete() {
246
+ return this._$ES;
247
+ }
248
+ shouldUpdate(t) {
249
+ return !0;
250
+ }
251
+ update(t) {
252
+ this._$Eq &&= this._$Eq.forEach((r) => this._$ET(r, this[r])), this._$EM();
253
+ }
254
+ updated(t) {
255
+ }
256
+ firstUpdated(t) {
257
+ }
258
+ };
259
+ M.elementStyles = [], M.shadowRootOptions = { mode: "open" }, M[O("elementProperties")] = /* @__PURE__ */ new Map(), M[O("finalized")] = /* @__PURE__ */ new Map(), Lt?.({ ReactiveElement: M }), (q.reactiveElementVersions ??= []).push("2.1.2");
260
+ /**
261
+ * @license
262
+ * Copyright 2017 Google LLC
263
+ * SPDX-License-Identifier: BSD-3-Clause
264
+ */
265
+ const rt = globalThis, dt = (e) => e, F = rt.trustedTypes, ht = F ? F.createPolicy("lit-html", { createHTML: (e) => e }) : void 0, yt = "$lit$", w = `lit$${Math.random().toFixed(9).slice(2)}$`, wt = "?" + w, Wt = `<${wt}>`, S = document, U = () => S.createComment(""), D = (e) => e === null || typeof e != "object" && typeof e != "function", st = Array.isArray, Bt = (e) => st(e) || typeof e?.[Symbol.iterator] == "function", G = `[
266
+ \f\r]`, P = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, pt = /-->/g, ut = />/g, x = RegExp(`>|${G}(?:([^\\s"'>=/]+)(${G}*=${G}*(?:[^
267
+ \f\r"'\`<>=]|("|')|))|$)`, "g"), gt = /'/g, ft = /"/g, $t = /^(?:script|style|textarea|title)$/i, xt = (e) => (t, ...r) => ({ _$litType$: e, strings: t, values: r }), _ = xt(1), z = xt(2), C = Symbol.for("lit-noChange"), g = Symbol.for("lit-nothing"), mt = /* @__PURE__ */ new WeakMap(), A = S.createTreeWalker(S, 129);
268
+ function _t(e, t) {
269
+ if (!st(e) || !e.hasOwnProperty("raw")) throw Error("invalid template strings array");
270
+ return ht !== void 0 ? ht.createHTML(t) : t;
271
+ }
272
+ const jt = (e, t) => {
273
+ const r = e.length - 1, s = [];
274
+ let i, n = t === 2 ? "<svg>" : t === 3 ? "<math>" : "", o = P;
275
+ for (let a = 0; a < r; a++) {
276
+ const l = e[a];
277
+ let d, h, c = -1, p = 0;
278
+ for (; p < l.length && (o.lastIndex = p, h = o.exec(l), h !== null); ) p = o.lastIndex, o === P ? h[1] === "!--" ? o = pt : h[1] !== void 0 ? o = ut : h[2] !== void 0 ? ($t.test(h[2]) && (i = RegExp("</" + h[2], "g")), o = x) : h[3] !== void 0 && (o = x) : o === x ? h[0] === ">" ? (o = i ?? P, c = -1) : h[1] === void 0 ? c = -2 : (c = o.lastIndex - h[2].length, d = h[1], o = h[3] === void 0 ? x : h[3] === '"' ? ft : gt) : o === ft || o === gt ? o = x : o === pt || o === ut ? o = P : (o = x, i = void 0);
279
+ const u = o === x && e[a + 1].startsWith("/>") ? " " : "";
280
+ n += o === P ? l + Wt : c >= 0 ? (s.push(d), l.slice(0, c) + yt + l.slice(c) + w + u) : l + w + (c === -2 ? a : u);
281
+ }
282
+ return [_t(e, n + (e[r] || "<?>") + (t === 2 ? "</svg>" : t === 3 ? "</math>" : "")), s];
283
+ };
284
+ class N {
285
+ constructor({ strings: t, _$litType$: r }, s) {
286
+ let i;
287
+ this.parts = [];
288
+ let n = 0, o = 0;
289
+ const a = t.length - 1, l = this.parts, [d, h] = jt(t, r);
290
+ if (this.el = N.createElement(d, s), A.currentNode = this.el.content, r === 2 || r === 3) {
291
+ const c = this.el.content.firstChild;
292
+ c.replaceWith(...c.childNodes);
293
+ }
294
+ for (; (i = A.nextNode()) !== null && l.length < a; ) {
295
+ if (i.nodeType === 1) {
296
+ if (i.hasAttributes()) for (const c of i.getAttributeNames()) if (c.endsWith(yt)) {
297
+ const p = h[o++], u = i.getAttribute(c).split(w), b = /([.?@])?(.*)/.exec(p);
298
+ l.push({ type: 1, index: n, name: b[2], strings: u, ctor: b[1] === "." ? qt : b[1] === "?" ? Zt : b[1] === "@" ? Vt : Z }), i.removeAttribute(c);
299
+ } else c.startsWith(w) && (l.push({ type: 6, index: n }), i.removeAttribute(c));
300
+ if ($t.test(i.tagName)) {
301
+ const c = i.textContent.split(w), p = c.length - 1;
302
+ if (p > 0) {
303
+ i.textContent = F ? F.emptyScript : "";
304
+ for (let u = 0; u < p; u++) i.append(c[u], U()), A.nextNode(), l.push({ type: 2, index: ++n });
305
+ i.append(c[p], U());
306
+ }
307
+ }
308
+ } else if (i.nodeType === 8) if (i.data === wt) l.push({ type: 2, index: n });
309
+ else {
310
+ let c = -1;
311
+ for (; (c = i.data.indexOf(w, c + 1)) !== -1; ) l.push({ type: 7, index: n }), c += w.length - 1;
312
+ }
313
+ n++;
314
+ }
315
+ }
316
+ static createElement(t, r) {
317
+ const s = S.createElement("template");
318
+ return s.innerHTML = t, s;
319
+ }
320
+ }
321
+ function k(e, t, r = e, s) {
322
+ if (t === C) return t;
323
+ let i = s !== void 0 ? r._$Co?.[s] : r._$Cl;
324
+ const n = D(t) ? void 0 : t._$litDirective$;
325
+ return i?.constructor !== n && (i?._$AO?.(!1), n === void 0 ? i = void 0 : (i = new n(e), i._$AT(e, r, s)), s !== void 0 ? (r._$Co ??= [])[s] = i : r._$Cl = i), i !== void 0 && (t = k(e, i._$AS(e, t.values), i, s)), t;
326
+ }
327
+ class Ft {
328
+ constructor(t, r) {
329
+ this._$AV = [], this._$AN = void 0, this._$AD = t, this._$AM = r;
330
+ }
331
+ get parentNode() {
332
+ return this._$AM.parentNode;
333
+ }
334
+ get _$AU() {
335
+ return this._$AM._$AU;
336
+ }
337
+ u(t) {
338
+ const { el: { content: r }, parts: s } = this._$AD, i = (t?.creationScope ?? S).importNode(r, !0);
339
+ A.currentNode = i;
340
+ let n = A.nextNode(), o = 0, a = 0, l = s[0];
341
+ for (; l !== void 0; ) {
342
+ if (o === l.index) {
343
+ let d;
344
+ l.type === 2 ? d = new H(n, n.nextSibling, this, t) : l.type === 1 ? d = new l.ctor(n, l.name, l.strings, this, t) : l.type === 6 && (d = new Gt(n, this, t)), this._$AV.push(d), l = s[++a];
345
+ }
346
+ o !== l?.index && (n = A.nextNode(), o++);
347
+ }
348
+ return A.currentNode = S, i;
349
+ }
350
+ p(t) {
351
+ let r = 0;
352
+ for (const s of this._$AV) s !== void 0 && (s.strings !== void 0 ? (s._$AI(t, s, r), r += s.strings.length - 2) : s._$AI(t[r])), r++;
353
+ }
354
+ }
355
+ class H {
356
+ get _$AU() {
357
+ return this._$AM?._$AU ?? this._$Cv;
358
+ }
359
+ constructor(t, r, s, i) {
360
+ this.type = 2, this._$AH = g, this._$AN = void 0, this._$AA = t, this._$AB = r, this._$AM = s, this.options = i, this._$Cv = i?.isConnected ?? !0;
361
+ }
362
+ get parentNode() {
363
+ let t = this._$AA.parentNode;
364
+ const r = this._$AM;
365
+ return r !== void 0 && t?.nodeType === 11 && (t = r.parentNode), t;
366
+ }
367
+ get startNode() {
368
+ return this._$AA;
369
+ }
370
+ get endNode() {
371
+ return this._$AB;
372
+ }
373
+ _$AI(t, r = this) {
374
+ t = k(this, t, r), D(t) ? t === g || t == null || t === "" ? (this._$AH !== g && this._$AR(), this._$AH = g) : t !== this._$AH && t !== C && this._(t) : t._$litType$ !== void 0 ? this.$(t) : t.nodeType !== void 0 ? this.T(t) : Bt(t) ? this.k(t) : this._(t);
375
+ }
376
+ O(t) {
377
+ return this._$AA.parentNode.insertBefore(t, this._$AB);
378
+ }
379
+ T(t) {
380
+ this._$AH !== t && (this._$AR(), this._$AH = this.O(t));
381
+ }
382
+ _(t) {
383
+ this._$AH !== g && D(this._$AH) ? this._$AA.nextSibling.data = t : this.T(S.createTextNode(t)), this._$AH = t;
384
+ }
385
+ $(t) {
386
+ const { values: r, _$litType$: s } = t, i = typeof s == "number" ? this._$AC(t) : (s.el === void 0 && (s.el = N.createElement(_t(s.h, s.h[0]), this.options)), s);
387
+ if (this._$AH?._$AD === i) this._$AH.p(r);
388
+ else {
389
+ const n = new Ft(i, this), o = n.u(this.options);
390
+ n.p(r), this.T(o), this._$AH = n;
391
+ }
392
+ }
393
+ _$AC(t) {
394
+ let r = mt.get(t.strings);
395
+ return r === void 0 && mt.set(t.strings, r = new N(t)), r;
396
+ }
397
+ k(t) {
398
+ st(this._$AH) || (this._$AH = [], this._$AR());
399
+ const r = this._$AH;
400
+ let s, i = 0;
401
+ for (const n of t) i === r.length ? r.push(s = new H(this.O(U()), this.O(U()), this, this.options)) : s = r[i], s._$AI(n), i++;
402
+ i < r.length && (this._$AR(s && s._$AB.nextSibling, i), r.length = i);
403
+ }
404
+ _$AR(t = this._$AA.nextSibling, r) {
405
+ for (this._$AP?.(!1, !0, r); t !== this._$AB; ) {
406
+ const s = dt(t).nextSibling;
407
+ dt(t).remove(), t = s;
408
+ }
409
+ }
410
+ setConnected(t) {
411
+ this._$AM === void 0 && (this._$Cv = t, this._$AP?.(t));
412
+ }
413
+ }
414
+ class Z {
415
+ get tagName() {
416
+ return this.element.tagName;
417
+ }
418
+ get _$AU() {
419
+ return this._$AM._$AU;
420
+ }
421
+ constructor(t, r, s, i, n) {
422
+ this.type = 1, this._$AH = g, this._$AN = void 0, this.element = t, this.name = r, this._$AM = i, this.options = n, s.length > 2 || s[0] !== "" || s[1] !== "" ? (this._$AH = Array(s.length - 1).fill(new String()), this.strings = s) : this._$AH = g;
423
+ }
424
+ _$AI(t, r = this, s, i) {
425
+ const n = this.strings;
426
+ let o = !1;
427
+ if (n === void 0) t = k(this, t, r, 0), o = !D(t) || t !== this._$AH && t !== C, o && (this._$AH = t);
428
+ else {
429
+ const a = t;
430
+ let l, d;
431
+ for (t = n[0], l = 0; l < n.length - 1; l++) d = k(this, a[s + l], r, l), d === C && (d = this._$AH[l]), o ||= !D(d) || d !== this._$AH[l], d === g ? t = g : t !== g && (t += (d ?? "") + n[l + 1]), this._$AH[l] = d;
432
+ }
433
+ o && !i && this.j(t);
434
+ }
435
+ j(t) {
436
+ t === g ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, t ?? "");
437
+ }
438
+ }
439
+ class qt extends Z {
440
+ constructor() {
441
+ super(...arguments), this.type = 3;
442
+ }
443
+ j(t) {
444
+ this.element[this.name] = t === g ? void 0 : t;
445
+ }
446
+ }
447
+ class Zt extends Z {
448
+ constructor() {
449
+ super(...arguments), this.type = 4;
450
+ }
451
+ j(t) {
452
+ this.element.toggleAttribute(this.name, !!t && t !== g);
453
+ }
454
+ }
455
+ class Vt extends Z {
456
+ constructor(t, r, s, i, n) {
457
+ super(t, r, s, i, n), this.type = 5;
458
+ }
459
+ _$AI(t, r = this) {
460
+ if ((t = k(this, t, r, 0) ?? g) === C) return;
461
+ const s = this._$AH, i = t === g && s !== g || t.capture !== s.capture || t.once !== s.once || t.passive !== s.passive, n = t !== g && (s === g || i);
462
+ i && this.element.removeEventListener(this.name, this, s), n && this.element.addEventListener(this.name, this, t), this._$AH = t;
463
+ }
464
+ handleEvent(t) {
465
+ typeof this._$AH == "function" ? this._$AH.call(this.options?.host ?? this.element, t) : this._$AH.handleEvent(t);
466
+ }
467
+ }
468
+ class Gt {
469
+ constructor(t, r, s) {
470
+ this.element = t, this.type = 6, this._$AN = void 0, this._$AM = r, this.options = s;
471
+ }
472
+ get _$AU() {
473
+ return this._$AM._$AU;
474
+ }
475
+ _$AI(t) {
476
+ k(this, t);
477
+ }
478
+ }
479
+ const Kt = rt.litHtmlPolyfillSupport;
480
+ Kt?.(N, H), (rt.litHtmlVersions ??= []).push("3.3.2");
481
+ const Jt = (e, t, r) => {
482
+ const s = r?.renderBefore ?? t;
483
+ let i = s._$litPart$;
484
+ if (i === void 0) {
485
+ const n = r?.renderBefore ?? null;
486
+ s._$litPart$ = i = new H(t.insertBefore(U(), n), n, void 0, r ?? {});
487
+ }
488
+ return i._$AI(e), i;
489
+ };
490
+ /**
491
+ * @license
492
+ * Copyright 2017 Google LLC
493
+ * SPDX-License-Identifier: BSD-3-Clause
494
+ */
495
+ const it = globalThis;
496
+ class R extends M {
497
+ constructor() {
498
+ super(...arguments), this.renderOptions = { host: this }, this._$Do = void 0;
499
+ }
500
+ createRenderRoot() {
501
+ const t = super.createRenderRoot();
502
+ return this.renderOptions.renderBefore ??= t.firstChild, t;
503
+ }
504
+ update(t) {
505
+ const r = this.render();
506
+ this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(t), this._$Do = Jt(r, this.renderRoot, this.renderOptions);
507
+ }
508
+ connectedCallback() {
509
+ super.connectedCallback(), this._$Do?.setConnected(!0);
510
+ }
511
+ disconnectedCallback() {
512
+ super.disconnectedCallback(), this._$Do?.setConnected(!1);
513
+ }
514
+ render() {
515
+ return C;
516
+ }
517
+ }
518
+ R._$litElement$ = !0, R.finalized = !0, it.litElementHydrateSupport?.({ LitElement: R });
519
+ const Yt = it.litElementPolyfillSupport;
520
+ Yt?.({ LitElement: R });
521
+ (it.litElementVersions ??= []).push("4.2.2");
522
+ /**
523
+ * @license
524
+ * Copyright 2017 Google LLC
525
+ * SPDX-License-Identifier: BSD-3-Clause
526
+ */
527
+ const Xt = (e) => (t, r) => {
528
+ r !== void 0 ? r.addInitializer(() => {
529
+ customElements.define(e, t);
530
+ }) : customElements.define(e, t);
531
+ };
532
+ /**
533
+ * @license
534
+ * Copyright 2017 Google LLC
535
+ * SPDX-License-Identifier: BSD-3-Clause
536
+ */
537
+ const Qt = { attribute: !0, type: String, converter: j, reflect: !1, hasChanged: et }, te = (e = Qt, t, r) => {
538
+ const { kind: s, metadata: i } = r;
539
+ let n = globalThis.litPropertyMetadata.get(i);
540
+ if (n === void 0 && globalThis.litPropertyMetadata.set(i, n = /* @__PURE__ */ new Map()), s === "setter" && ((e = Object.create(e)).wrapped = !0), n.set(r.name, e), s === "accessor") {
541
+ const { name: o } = r;
542
+ return { set(a) {
543
+ const l = t.get.call(this);
544
+ t.set.call(this, a), this.requestUpdate(o, l, e, !0, a);
545
+ }, init(a) {
546
+ return a !== void 0 && this.C(o, void 0, e, a), a;
547
+ } };
548
+ }
549
+ if (s === "setter") {
550
+ const { name: o } = r;
551
+ return function(a) {
552
+ const l = this[o];
553
+ t.call(this, a), this.requestUpdate(o, l, e, !0, a);
554
+ };
555
+ }
556
+ throw Error("Unsupported decorator location: " + s);
557
+ };
558
+ function I(e) {
559
+ return (t, r) => typeof r == "object" ? te(e, t, r) : ((s, i, n) => {
560
+ const o = i.hasOwnProperty(n);
561
+ return i.constructor.createProperty(n, s), o ? Object.getOwnPropertyDescriptor(i, n) : void 0;
562
+ })(e, t, r);
563
+ }
564
+ /**
565
+ * @license
566
+ * Copyright 2017 Google LLC
567
+ * SPDX-License-Identifier: BSD-3-Clause
568
+ */
569
+ function y(e) {
570
+ return I({ ...e, state: !0, attribute: !1 });
571
+ }
572
+ /**
573
+ * @license
574
+ * Copyright 2017 Google LLC
575
+ * SPDX-License-Identifier: BSD-3-Clause
576
+ */
577
+ const ee = (e, t, r) => (r.configurable = !0, r.enumerable = !0, Reflect.decorate && typeof t != "object" && Object.defineProperty(e, t, r), r);
578
+ /**
579
+ * @license
580
+ * Copyright 2017 Google LLC
581
+ * SPDX-License-Identifier: BSD-3-Clause
582
+ */
583
+ function re(e, t) {
584
+ return (r, s, i) => {
585
+ const n = (o) => o.renderRoot?.querySelector(e) ?? null;
586
+ return ee(r, s, { get() {
587
+ return n(this);
588
+ } });
589
+ };
590
+ }
591
+ const se = Tt`
592
+ :host {
593
+ display: block;
594
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
595
+ "Helvetica Neue", Arial, sans-serif;
596
+ color: #1a1a2e;
597
+ --accent: #0060df; /* Mozilla blue */
598
+ --accent-hover: #0250bb;
599
+ --danger: #d73a49;
600
+ --success: #2da44e;
601
+ --bg: #ffffff;
602
+ --bg-secondary: #f6f8fa;
603
+ --border: #d0d7de;
604
+ --text: #1a1a2e;
605
+ --text-secondary: #656d76;
606
+ --redaction-fill: rgba(0, 0, 0, 0.75);
607
+ --redaction-stroke: #ff3b3b;
608
+ --radius: 8px;
609
+ --max-width: 100%;
610
+ container-type: inline-size;
611
+ }
612
+
613
+ * {
614
+ box-sizing: border-box;
615
+ }
616
+
617
+ .container {
618
+ max-width: var(--max-width);
619
+ margin: 0 auto;
620
+ }
621
+
622
+ /* --- Trust banner --- */
623
+ .trust-banner {
624
+ display: flex;
625
+ align-items: center;
626
+ gap: 8px;
627
+ padding: 10px 14px;
628
+ background: #e8f5e9;
629
+ border: 1px solid #a5d6a7;
630
+ border-radius: var(--radius);
631
+ font-size: 13px;
632
+ color: #2e7d32;
633
+ margin-bottom: 12px;
634
+ }
635
+
636
+ .trust-banner .shield-icon {
637
+ flex-shrink: 0;
638
+ width: 18px;
639
+ height: 18px;
640
+ }
641
+
642
+ .trust-banner .network-count {
643
+ margin-left: auto;
644
+ font-variant-numeric: tabular-nums;
645
+ font-weight: 600;
646
+ white-space: nowrap;
647
+ }
648
+
649
+ /* --- Drop zone --- */
650
+ .dropzone {
651
+ display: flex;
652
+ flex-direction: column;
653
+ align-items: center;
654
+ justify-content: center;
655
+ gap: 16px;
656
+ min-height: 240px;
657
+ padding: 32px 24px;
658
+ border: 2px dashed var(--border);
659
+ border-radius: var(--radius);
660
+ background: var(--bg-secondary);
661
+ cursor: pointer;
662
+ transition: border-color 0.2s, background 0.2s;
663
+ text-align: center;
664
+ -webkit-tap-highlight-color: transparent;
665
+ }
666
+
667
+ .dropzone.dragover {
668
+ border-color: var(--accent);
669
+ background: #f0f6ff;
670
+ }
671
+
672
+ .dropzone-icon {
673
+ width: 48px;
674
+ height: 48px;
675
+ color: var(--text-secondary);
676
+ }
677
+
678
+ .dropzone-text {
679
+ font-size: 16px;
680
+ color: var(--text-secondary);
681
+ }
682
+
683
+ .dropzone-text strong {
684
+ color: var(--accent);
685
+ }
686
+
687
+ .dropzone-hint {
688
+ font-size: 13px;
689
+ color: var(--text-secondary);
690
+ }
691
+
692
+ .file-input {
693
+ display: none;
694
+ }
695
+
696
+ /* --- Progress --- */
697
+ .progress-container {
698
+ padding: 32px 24px;
699
+ text-align: center;
700
+ }
701
+
702
+ .progress-bar-track {
703
+ width: 100%;
704
+ height: 6px;
705
+ background: var(--bg-secondary);
706
+ border-radius: 3px;
707
+ overflow: hidden;
708
+ margin: 16px 0;
709
+ }
710
+
711
+ .progress-bar-fill {
712
+ height: 100%;
713
+ background: var(--accent);
714
+ border-radius: 3px;
715
+ transition: width 0.3s ease;
716
+ }
717
+
718
+ .progress-message {
719
+ font-size: 14px;
720
+ color: var(--text-secondary);
721
+ margin: 8px 0;
722
+ }
723
+
724
+ .progress-phase {
725
+ font-size: 16px;
726
+ font-weight: 600;
727
+ color: var(--text);
728
+ margin-bottom: 4px;
729
+ }
730
+
731
+ /* --- Editor / review --- */
732
+ .editor {
733
+ display: flex;
734
+ flex-direction: column;
735
+ gap: 12px;
736
+ }
737
+
738
+ .viewport {
739
+ position: relative;
740
+ overflow: auto;
741
+ -webkit-overflow-scrolling: touch;
742
+ background: #e5e5e5;
743
+ border-radius: var(--radius);
744
+ border: 1px solid var(--border);
745
+ /* On mobile, constrain height to viewport */
746
+ max-height: 60vh;
747
+ max-height: 60dvh;
748
+ touch-action: pan-x pan-y;
749
+ }
750
+
751
+ .viewport-inner {
752
+ position: relative;
753
+ display: inline-block;
754
+ /* Scale image to fit viewport width on mobile */
755
+ width: 100%;
756
+ }
757
+
758
+ .viewport img {
759
+ display: block;
760
+ width: 100%;
761
+ height: auto;
762
+ user-select: none;
763
+ -webkit-user-select: none;
764
+ pointer-events: none;
765
+ }
766
+
767
+ .viewport svg {
768
+ position: absolute;
769
+ top: 0;
770
+ left: 0;
771
+ width: 100%;
772
+ height: 100%;
773
+ }
774
+
775
+ .viewport svg rect.redaction-box {
776
+ fill: var(--redaction-fill);
777
+ stroke: var(--redaction-stroke);
778
+ stroke-width: 2;
779
+ cursor: pointer;
780
+ transition: fill 0.15s;
781
+ }
782
+
783
+ .viewport svg rect.redaction-box:hover,
784
+ .viewport svg rect.redaction-box.active {
785
+ fill: rgba(255, 59, 59, 0.4);
786
+ stroke-width: 3;
787
+ }
788
+
789
+ .viewport svg rect.redaction-box.disabled {
790
+ fill: rgba(0, 0, 0, 0.15);
791
+ stroke: #999;
792
+ stroke-dasharray: 4 2;
793
+ }
794
+
795
+ .viewport svg rect.drawing {
796
+ fill: rgba(0, 96, 223, 0.2);
797
+ stroke: var(--accent);
798
+ stroke-width: 2;
799
+ stroke-dasharray: 6 3;
800
+ }
801
+
802
+ /* --- Toolbar --- */
803
+ .toolbar {
804
+ display: flex;
805
+ flex-wrap: wrap;
806
+ gap: 8px;
807
+ padding: 8px 0;
808
+ }
809
+
810
+ .toolbar button {
811
+ display: inline-flex;
812
+ align-items: center;
813
+ gap: 6px;
814
+ padding: 8px 16px;
815
+ font-size: 14px;
816
+ font-weight: 500;
817
+ border: 1px solid var(--border);
818
+ border-radius: var(--radius);
819
+ background: var(--bg);
820
+ color: var(--text);
821
+ cursor: pointer;
822
+ transition: background 0.15s, border-color 0.15s;
823
+ -webkit-tap-highlight-color: transparent;
824
+ /* Touch-friendly minimum size */
825
+ min-height: 44px;
826
+ min-width: 44px;
827
+ }
828
+
829
+ .toolbar button:hover {
830
+ background: var(--bg-secondary);
831
+ border-color: var(--accent);
832
+ }
833
+
834
+ .toolbar button:active {
835
+ background: #e8e8e8;
836
+ }
837
+
838
+ .toolbar button.primary {
839
+ background: var(--success);
840
+ color: white;
841
+ border-color: var(--success);
842
+ }
843
+
844
+ .toolbar button.primary:hover {
845
+ background: #278c41;
846
+ }
847
+
848
+ .toolbar button.danger {
849
+ color: var(--danger);
850
+ border-color: var(--danger);
851
+ }
852
+
853
+ .toolbar button.danger:hover {
854
+ background: #fff5f5;
855
+ }
856
+
857
+ .toolbar button.active {
858
+ background: var(--accent);
859
+ color: white;
860
+ border-color: var(--accent);
861
+ }
862
+
863
+ .toolbar .spacer {
864
+ flex: 1;
865
+ }
866
+
867
+ /* --- Entity list (bottom sheet on mobile, sidebar on desktop) --- */
868
+ .entity-list {
869
+ border: 1px solid var(--border);
870
+ border-radius: var(--radius);
871
+ background: var(--bg);
872
+ max-height: 200px;
873
+ overflow-y: auto;
874
+ -webkit-overflow-scrolling: touch;
875
+ }
876
+
877
+ .entity-list-header {
878
+ position: sticky;
879
+ top: 0;
880
+ padding: 10px 14px;
881
+ font-size: 13px;
882
+ font-weight: 600;
883
+ color: var(--text-secondary);
884
+ background: var(--bg-secondary);
885
+ border-bottom: 1px solid var(--border);
886
+ }
887
+
888
+ .entity-item {
889
+ display: flex;
890
+ align-items: center;
891
+ gap: 10px;
892
+ padding: 10px 14px;
893
+ border-bottom: 1px solid var(--border);
894
+ font-size: 14px;
895
+ min-height: 44px; /* Touch target */
896
+ }
897
+
898
+ .entity-item:last-child {
899
+ border-bottom: none;
900
+ }
901
+
902
+ .entity-item input[type="checkbox"] {
903
+ width: 18px;
904
+ height: 18px;
905
+ flex-shrink: 0;
906
+ accent-color: var(--accent);
907
+ }
908
+
909
+ .entity-label {
910
+ display: inline-block;
911
+ padding: 2px 8px;
912
+ font-size: 11px;
913
+ font-weight: 600;
914
+ text-transform: uppercase;
915
+ border-radius: 4px;
916
+ background: #eef1f5;
917
+ color: var(--text-secondary);
918
+ white-space: nowrap;
919
+ }
920
+
921
+ .entity-text {
922
+ flex: 1;
923
+ overflow: hidden;
924
+ text-overflow: ellipsis;
925
+ white-space: nowrap;
926
+ color: var(--text);
927
+ }
928
+
929
+ .entity-source {
930
+ font-size: 11px;
931
+ color: var(--text-secondary);
932
+ }
933
+
934
+ /* --- Error state --- */
935
+ .error {
936
+ padding: 24px;
937
+ text-align: center;
938
+ color: var(--danger);
939
+ }
940
+
941
+ .error button {
942
+ margin-top: 12px;
943
+ padding: 8px 16px;
944
+ border: 1px solid var(--danger);
945
+ border-radius: var(--radius);
946
+ background: var(--bg);
947
+ color: var(--danger);
948
+ cursor: pointer;
949
+ min-height: 44px;
950
+ }
951
+
952
+ /* --- Responsive --- */
953
+ @container (min-width: 640px) {
954
+ .editor {
955
+ display: grid;
956
+ grid-template-columns: 1fr 260px;
957
+ grid-template-rows: auto 1fr;
958
+ gap: 12px;
959
+ }
960
+
961
+ .toolbar {
962
+ grid-column: 1 / -1;
963
+ }
964
+
965
+ .viewport {
966
+ max-height: 70vh;
967
+ }
968
+
969
+ .entity-list {
970
+ max-height: none;
971
+ grid-row: 2;
972
+ grid-column: 2;
973
+ }
974
+ }
975
+
976
+ /* --- Reduced motion --- */
977
+ @media (prefers-reduced-motion: reduce) {
978
+ .progress-bar-fill {
979
+ transition: none;
980
+ }
981
+ }
982
+ `, ie = z`
983
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
984
+ stroke-linecap="round" stroke-linejoin="round" class="shield-icon">
985
+ <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
986
+ <path d="m9 12 2 2 4-4"/>
987
+ </svg>
988
+ `, ne = z`
989
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
990
+ stroke-linecap="round" stroke-linejoin="round" class="dropzone-icon">
991
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
992
+ <polyline points="17 8 12 3 7 8"/>
993
+ <line x1="12" y1="3" x2="12" y2="15"/>
994
+ </svg>
995
+ `;
996
+ z`
997
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
998
+ stroke-linecap="round" stroke-linejoin="round" style="width:18px;height:18px">
999
+ <path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/>
1000
+ <circle cx="12" cy="13" r="3"/>
1001
+ </svg>
1002
+ `;
1003
+ const oe = 128;
1004
+ function ae(e) {
1005
+ const t = Math.floor(e.length / 4);
1006
+ if (t === 0) return 255;
1007
+ let r = 0;
1008
+ for (let s = 0; s < t; s++) {
1009
+ const i = e[s * 4], n = e[s * 4 + 1], o = e[s * 4 + 2];
1010
+ r += 0.299 * i + 0.587 * n + 0.114 * o;
1011
+ }
1012
+ return r / t;
1013
+ }
1014
+ function le(e) {
1015
+ return ae(e) < oe;
1016
+ }
1017
+ async function ce(e) {
1018
+ let t, r;
1019
+ try {
1020
+ const s = await createImageBitmap(e), { width: i, height: n } = s;
1021
+ if (typeof OffscreenCanvas < "u" ? (t = new OffscreenCanvas(i, n), r = t.getContext("2d")) : (t = document.createElement("canvas"), t.width = i, t.height = n, r = t.getContext("2d")), !r)
1022
+ return s.close(), e;
1023
+ r.drawImage(s, 0, 0), s.close();
1024
+ const o = Math.min(i * n, 1024), a = Math.ceil(Math.sqrt(o * i / n)), l = Math.ceil(Math.sqrt(o * n / i)), d = r.getImageData(0, 0, a, l);
1025
+ if (!le(d.data))
1026
+ return await vt(t, r, i, n, 1.2);
1027
+ const c = r.getImageData(0, 0, i, n), p = c.data;
1028
+ for (let u = 0; u < p.length; u += 4)
1029
+ p[u] = 255 - p[u], p[u + 1] = 255 - p[u + 1], p[u + 2] = 255 - p[u + 2];
1030
+ return r.putImageData(c, 0, 0), await vt(t, r, i, n, 1.5);
1031
+ } catch {
1032
+ return e;
1033
+ }
1034
+ }
1035
+ async function vt(e, t, r, s, i) {
1036
+ const n = t.getImageData(0, 0, r, s), o = n.data;
1037
+ for (let a = 0; a < o.length; a += 4)
1038
+ o[a] = K((o[a] - 128) * i + 128), o[a + 1] = K((o[a + 1] - 128) * i + 128), o[a + 2] = K((o[a + 2] - 128) * i + 128);
1039
+ return t.putImageData(n, 0, 0), e instanceof OffscreenCanvas ? e.convertToBlob({ type: "image/png" }) : await new Promise((a, l) => {
1040
+ e.toBlob((d) => {
1041
+ d ? a(d) : l(new Error("toBlob returned null"));
1042
+ }, "image/png");
1043
+ });
1044
+ }
1045
+ function K(e) {
1046
+ return Math.max(0, Math.min(255, Math.round(e)));
1047
+ }
1048
+ async function de(e, t = "eng", r) {
1049
+ const i = await (await import("./index-Br2RPwqy.js").then((v) => v.i)).createWorker(t, void 0, {
1050
+ logger: (v) => {
1051
+ r?.({
1052
+ phase: "ocr",
1053
+ progress: v.progress,
1054
+ message: v.status
1055
+ });
1056
+ }
1057
+ });
1058
+ let n, o = 0, a = 0;
1059
+ if (e instanceof ImageBitmap) {
1060
+ o = e.width, a = e.height;
1061
+ const v = new OffscreenCanvas(e.width, e.height);
1062
+ v.getContext("2d").drawImage(e, 0, 0), n = await v.convertToBlob({ type: "image/png" });
1063
+ } else if (e instanceof Blob) {
1064
+ try {
1065
+ const v = await createImageBitmap(e);
1066
+ o = v.width, a = v.height, v.close();
1067
+ } catch {
1068
+ }
1069
+ n = e;
1070
+ } else {
1071
+ o = e.naturalWidth, a = e.naturalHeight;
1072
+ const v = new OffscreenCanvas(e.naturalWidth, e.naturalHeight);
1073
+ v.getContext("2d").drawImage(e, 0, 0), n = await v.convertToBlob({ type: "image/png" });
1074
+ }
1075
+ const l = await ce(n);
1076
+ let d;
1077
+ try {
1078
+ d = await i.recognize(l);
1079
+ } finally {
1080
+ await i.terminate();
1081
+ }
1082
+ const h = [];
1083
+ let c = "", p = 0;
1084
+ const u = d.data.lines ?? [];
1085
+ for (let v = 0; v < u.length; v++) {
1086
+ const V = u[v].words ?? [];
1087
+ for (let L = 0; L < V.length; L++) {
1088
+ const E = V[L], W = E.text, Ct = p, kt = p + W.length;
1089
+ h.push({
1090
+ text: W,
1091
+ bbox: {
1092
+ x0: E.bbox.x0,
1093
+ y0: E.bbox.y0,
1094
+ x1: E.bbox.x1,
1095
+ y1: E.bbox.y1
1096
+ },
1097
+ confidence: E.confidence,
1098
+ charStart: Ct,
1099
+ charEnd: kt,
1100
+ lineIndex: v
1101
+ }), c += W, p += W.length, L < V.length - 1 && (c += " ", p += 1);
1102
+ }
1103
+ v < u.length - 1 && (c += `
1104
+ `, p += 1);
1105
+ }
1106
+ const b = d.data, Et = b.imageWidth ?? o, Mt = b.imageHeight ?? a;
1107
+ return { fullText: c, words: h, imageWidth: Et, imageHeight: Mt };
1108
+ }
1109
+ function he(e, t, r) {
1110
+ return e.filter((s) => s.charStart < r && s.charEnd > t);
1111
+ }
1112
+ let $ = null, Y = null;
1113
+ async function pe(e, t, r = 0.7, s) {
1114
+ const i = await St(t, s);
1115
+ s?.({
1116
+ phase: "detecting",
1117
+ progress: 0,
1118
+ message: "Running PII detection..."
1119
+ });
1120
+ let n;
1121
+ try {
1122
+ n = await i(e, {
1123
+ aggregation_strategy: "first"
1124
+ });
1125
+ } catch {
1126
+ try {
1127
+ n = await i(e, {
1128
+ aggregation_strategy: "simple"
1129
+ });
1130
+ } catch {
1131
+ n = await i(e);
1132
+ }
1133
+ }
1134
+ return s?.({
1135
+ phase: "detecting",
1136
+ progress: 1,
1137
+ message: "PII detection complete."
1138
+ }), n.length > 0 && n[0].entity_group != null ? ue(n, e, r) : ge(n, e, r);
1139
+ }
1140
+ function ue(e, t, r) {
1141
+ let s = 0;
1142
+ const i = [];
1143
+ for (const n of e) {
1144
+ if (n.score < r) continue;
1145
+ const o = n.entity_group ?? n.entity ?? "UNKNOWN", a = n.word ?? "";
1146
+ let l = n.start, d = n.end;
1147
+ if (l == null || d == null) {
1148
+ const c = X(t, a, i.length > 0 ? i[i.length - 1].end ?? 0 : 0);
1149
+ if (c)
1150
+ l = c.start, d = c.end;
1151
+ else
1152
+ continue;
1153
+ }
1154
+ const h = t.slice(l, d);
1155
+ i.push({
1156
+ id: `ner-${s++}`,
1157
+ label: At(o),
1158
+ text: h || a,
1159
+ start: l,
1160
+ end: d,
1161
+ score: n.score,
1162
+ source: "ner"
1163
+ });
1164
+ }
1165
+ return i;
1166
+ }
1167
+ function ge(e, t, r) {
1168
+ const s = [];
1169
+ let i = 0, n = [], o = "";
1170
+ for (const a of e) {
1171
+ const l = a.entity ?? "";
1172
+ if (l === "O" || l === "") {
1173
+ if (n.length > 0) {
1174
+ const c = J(n, o, t, i++, r);
1175
+ c && s.push(c), n = [], o = "";
1176
+ }
1177
+ continue;
1178
+ }
1179
+ const d = l.substring(0, 2), h = l.includes("-") ? l.substring(2) : l;
1180
+ if (d === "B-" || h !== o) {
1181
+ if (n.length > 0) {
1182
+ const c = J(n, o, t, i++, r);
1183
+ c && s.push(c);
1184
+ }
1185
+ n = [a], o = h;
1186
+ } else
1187
+ n.push(a);
1188
+ }
1189
+ if (n.length > 0) {
1190
+ const a = J(n, o, t, i++, r);
1191
+ a && s.push(a);
1192
+ }
1193
+ return s;
1194
+ }
1195
+ function J(e, t, r, s, i) {
1196
+ if (e.length === 0) return null;
1197
+ const n = e.reduce((c, p) => c + p.score, 0) / e.length;
1198
+ if (n < i) return null;
1199
+ const o = e.find((c) => c.start != null), a = [...e].reverse().find((c) => c.end != null);
1200
+ let l, d, h;
1201
+ if (o?.start != null && a?.end != null)
1202
+ l = o.start, d = a.end, h = r.slice(l, d);
1203
+ else {
1204
+ const c = e.map((u) => {
1205
+ let b = u.word ?? "";
1206
+ return b.startsWith("##") && (b = b.slice(2)), b = b.replace(/^▁/, ""), b;
1207
+ }).join(""), p = X(r, c, 0);
1208
+ if (p)
1209
+ l = p.start, d = p.end;
1210
+ else {
1211
+ const u = e[0].word?.replace(/^▁/, "").replace(/^##/, "") ?? "", b = X(r, u, 0);
1212
+ if (!b) return null;
1213
+ l = b.start, d = l + c.length;
1214
+ }
1215
+ h = r.slice(l, d);
1216
+ }
1217
+ return {
1218
+ id: `ner-${s}`,
1219
+ label: At(t),
1220
+ text: h,
1221
+ start: l,
1222
+ end: d,
1223
+ score: n,
1224
+ source: "ner"
1225
+ };
1226
+ }
1227
+ function X(e, t, r) {
1228
+ if (!t || t.length === 0) return null;
1229
+ let s = e.indexOf(t, r);
1230
+ if (s !== -1) return { start: s, end: s + t.length };
1231
+ const i = e.toLowerCase(), n = t.toLowerCase();
1232
+ return s = i.indexOf(n, r), s !== -1 ? { start: s, end: s + t.length } : r > 0 && (s = i.indexOf(n, 0), s !== -1) ? { start: s, end: s + t.length } : null;
1233
+ }
1234
+ function At(e) {
1235
+ return e.startsWith("B-") || e.startsWith("I-") ? e.substring(2) : e;
1236
+ }
1237
+ async function St(e, t) {
1238
+ if ($ && Y === e)
1239
+ return $;
1240
+ t?.({
1241
+ phase: "loading",
1242
+ progress: 0,
1243
+ message: "Loading PII detection model..."
1244
+ });
1245
+ const { pipeline: r, env: s } = await import("./transformers-D4eH6I53.js");
1246
+ return s.allowLocalModels = !1, $ = await r(
1247
+ "token-classification",
1248
+ e,
1249
+ {
1250
+ progress_callback: (n) => {
1251
+ n.status === "progress" && n.total && t?.({
1252
+ phase: "loading",
1253
+ progress: n.loaded / n.total,
1254
+ message: `Downloading model: ${Math.round(n.loaded / n.total * 100)}%`
1255
+ });
1256
+ },
1257
+ // Try WebGPU first, falls back to WASM automatically
1258
+ device: "auto",
1259
+ dtype: "q8"
1260
+ // Quantized for smaller download + faster inference
1261
+ }
1262
+ ), Y = e, t?.({
1263
+ phase: "loading",
1264
+ progress: 1,
1265
+ message: "Model loaded."
1266
+ }), $;
1267
+ }
1268
+ async function fe(e, t) {
1269
+ await St(e, t);
1270
+ }
1271
+ async function me() {
1272
+ if ($) {
1273
+ try {
1274
+ typeof $.dispose == "function" && await $.dispose();
1275
+ } catch {
1276
+ }
1277
+ $ = null, Y = null;
1278
+ }
1279
+ }
1280
+ const ve = [
1281
+ // Email addresses
1282
+ {
1283
+ label: "EMAIL",
1284
+ pattern: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g
1285
+ },
1286
+ // Phone numbers (various formats)
1287
+ {
1288
+ label: "TELEPHONENUM",
1289
+ pattern: /(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}(?:\s*(?:ext|x)\.?\s*\d{1,5})?/g
1290
+ },
1291
+ // International phone numbers
1292
+ {
1293
+ label: "TELEPHONENUM",
1294
+ pattern: /\+\d{1,3}[-.\s]?\d{1,4}[-.\s]?\d{1,4}[-.\s]?\d{1,9}/g
1295
+ },
1296
+ // Social Security Numbers (US)
1297
+ {
1298
+ label: "SSN",
1299
+ pattern: /\b\d{3}[-.\s]?\d{2}[-.\s]?\d{4}\b/g
1300
+ },
1301
+ // Credit card numbers (basic — 13-19 digits with optional separators)
1302
+ {
1303
+ label: "CREDITCARD",
1304
+ pattern: /\b(?:\d{4}[-.\s]?){3,4}\d{1,4}\b/g
1305
+ },
1306
+ // IP addresses (v4)
1307
+ {
1308
+ label: "IP_ADDRESS",
1309
+ pattern: /\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b/g
1310
+ },
1311
+ // Dates (various formats — these often contain birth dates)
1312
+ {
1313
+ label: "DATE",
1314
+ pattern: /\b(?:\d{1,2}[/.-]\d{1,2}[/.-]\d{2,4}|\d{4}[/.-]\d{1,2}[/.-]\d{1,2})\b/g
1315
+ },
1316
+ // URLs with paths (may contain identifying query params)
1317
+ {
1318
+ label: "URL",
1319
+ pattern: /https?:\/\/[^\s<>"{}|\\^`[\]]+/g
1320
+ },
1321
+ // Street addresses (basic US pattern)
1322
+ {
1323
+ label: "STREET",
1324
+ pattern: /\b\d{1,5}\s+[\w\s]{1,30}(?:street|st|avenue|ave|road|rd|drive|dr|lane|ln|boulevard|blvd|court|ct|way|place|pl)\.?\b/gi
1325
+ },
1326
+ // Zip codes (US)
1327
+ {
1328
+ label: "ZIPCODE",
1329
+ pattern: /\b\d{5}(?:-\d{4})?\b/g
1330
+ },
1331
+ // Usernames / handles (@mentions)
1332
+ {
1333
+ label: "USERNAME",
1334
+ pattern: /@[a-zA-Z0-9_]{2,30}\b/g
1335
+ }
1336
+ ];
1337
+ let be = 0;
1338
+ function ye(e) {
1339
+ const t = [];
1340
+ for (const { label: r, pattern: s } of ve) {
1341
+ s.lastIndex = 0;
1342
+ let i;
1343
+ for (; (i = s.exec(e)) !== null; )
1344
+ t.push({
1345
+ id: `regex-${be++}`,
1346
+ label: r,
1347
+ text: i[0],
1348
+ start: i.index,
1349
+ end: i.index + i[0].length,
1350
+ score: 1,
1351
+ source: "regex"
1352
+ });
1353
+ }
1354
+ return t.sort((r, s) => r.start - s.start || s.end - r.end), we(t);
1355
+ }
1356
+ function we(e) {
1357
+ const t = [];
1358
+ for (const r of e) {
1359
+ const s = t[t.length - 1];
1360
+ if (!(s && r.start >= s.start && r.end <= s.end)) {
1361
+ if (s && r.start < s.end) {
1362
+ r.end - r.start > s.end - s.start && (t[t.length - 1] = r);
1363
+ continue;
1364
+ }
1365
+ t.push(r);
1366
+ }
1367
+ }
1368
+ return t;
1369
+ }
1370
+ let $e = 0;
1371
+ function xe(e, t, r = 0, s = 0) {
1372
+ const i = [];
1373
+ for (const n of e) {
1374
+ if (n.start == null || n.end == null)
1375
+ continue;
1376
+ let a = he(t, n.start, n.end);
1377
+ if (a.length === 0 && n.text && (a = _e(t, n.text)), a.length === 0)
1378
+ continue;
1379
+ const l = Ae(a);
1380
+ for (const d of l.values()) {
1381
+ const h = Se(d.map((c) => c.bbox));
1382
+ i.push({
1383
+ id: `redact-${$e++}`,
1384
+ bbox: Ee(h, 2, r, s),
1385
+ source: "auto",
1386
+ entityId: n.id,
1387
+ enabled: !0,
1388
+ label: n.label
1389
+ });
1390
+ }
1391
+ }
1392
+ return i;
1393
+ }
1394
+ function _e(e, t) {
1395
+ const r = t.toLowerCase().trim();
1396
+ if (!r) return [];
1397
+ const s = r.split(/\s+/);
1398
+ for (let n = 0; n <= e.length - s.length; n++) {
1399
+ let o = !0;
1400
+ for (let a = 0; a < s.length; a++)
1401
+ if (!e[n + a].text.toLowerCase().includes(s[a]) && !s[a].includes(e[n + a].text.toLowerCase())) {
1402
+ o = !1;
1403
+ break;
1404
+ }
1405
+ if (o)
1406
+ return e.slice(n, n + s.length);
1407
+ }
1408
+ return e.filter((n) => {
1409
+ const o = n.text.toLowerCase();
1410
+ return o === r || r.includes(o) || o.includes(r);
1411
+ });
1412
+ }
1413
+ function Ae(e) {
1414
+ const t = /* @__PURE__ */ new Map();
1415
+ for (const r of e) {
1416
+ const s = t.get(r.lineIndex) ?? [];
1417
+ s.push(r), t.set(r.lineIndex, s);
1418
+ }
1419
+ return t;
1420
+ }
1421
+ function Se(e) {
1422
+ return {
1423
+ x0: Math.min(...e.map((t) => t.x0)),
1424
+ y0: Math.min(...e.map((t) => t.y0)),
1425
+ x1: Math.max(...e.map((t) => t.x1)),
1426
+ y1: Math.max(...e.map((t) => t.y1))
1427
+ };
1428
+ }
1429
+ function Ee(e, t, r = 0, s = 0) {
1430
+ const i = e.x1 + t, n = e.y1 + t;
1431
+ return {
1432
+ x0: Math.max(0, e.x0 - t),
1433
+ y0: Math.max(0, e.y0 - t),
1434
+ x1: r > 0 ? Math.min(r, i) : i,
1435
+ y1: s > 0 ? Math.min(s, n) : n
1436
+ };
1437
+ }
1438
+ function Me(e, t) {
1439
+ const r = [...e, ...t];
1440
+ r.sort((i, n) => i.start - n.start || n.end - i.end);
1441
+ const s = [];
1442
+ for (const i of r) {
1443
+ const n = s[s.length - 1];
1444
+ if (!n) {
1445
+ s.push(i);
1446
+ continue;
1447
+ }
1448
+ if (i.start < n.end) {
1449
+ const o = n.source === "ner" ? n.score + 0.1 : n.score;
1450
+ (i.source === "ner" ? i.score + 0.1 : i.score) > o && (s[s.length - 1] = i);
1451
+ continue;
1452
+ }
1453
+ s.push(i);
1454
+ }
1455
+ return s;
1456
+ }
1457
+ async function Ce(e, t) {
1458
+ const r = e instanceof HTMLImageElement ? e.naturalWidth : e.width, s = e instanceof HTMLImageElement ? e.naturalHeight : e.height, i = ke(r, s), n = Pe(i);
1459
+ n.drawImage(e, 0, 0, r, s), n.fillStyle = "#000000";
1460
+ const o = [];
1461
+ for (const l of t) {
1462
+ if (!l.enabled) continue;
1463
+ const { x0: d, y0: h, x1: c, y1: p } = l.bbox;
1464
+ n.fillRect(d, h, c - d, p - h), o.push({
1465
+ label: l.label ?? "UNKNOWN",
1466
+ bbox: l.bbox,
1467
+ source: l.source
1468
+ });
1469
+ }
1470
+ return {
1471
+ blob: await Te(i),
1472
+ entities: o,
1473
+ width: r,
1474
+ height: s
1475
+ };
1476
+ }
1477
+ function He(e, t, r = {
1478
+ fill: "rgba(0, 0, 0, 0.7)",
1479
+ stroke: "#ff3333",
1480
+ lineWidth: 2
1481
+ }) {
1482
+ for (const s of t) {
1483
+ if (!s.enabled) continue;
1484
+ const { x0: i, y0: n, x1: o, y1: a } = s.bbox, l = o - i, d = a - n;
1485
+ e.fillStyle = r.fill, e.fillRect(i, n, l, d), e.strokeStyle = r.stroke, e.lineWidth = r.lineWidth, e.strokeRect(i, n, l, d);
1486
+ }
1487
+ }
1488
+ function ke(e, t) {
1489
+ if (typeof OffscreenCanvas < "u")
1490
+ return new OffscreenCanvas(e, t);
1491
+ const r = document.createElement("canvas");
1492
+ return r.width = e, r.height = t, r;
1493
+ }
1494
+ function Pe(e) {
1495
+ const t = e.getContext("2d");
1496
+ if (!t) throw new Error("Could not get 2D canvas context");
1497
+ return t;
1498
+ }
1499
+ async function Te(e) {
1500
+ return e instanceof OffscreenCanvas ? e.convertToBlob({ type: "image/png" }) : new Promise((t, r) => {
1501
+ e.toBlob(
1502
+ (s) => {
1503
+ s ? t(s) : r(new Error("Canvas toBlob failed"));
1504
+ },
1505
+ "image/png"
1506
+ );
1507
+ });
1508
+ }
1509
+ async function Oe(e, t, r) {
1510
+ const s = { ...t }, i = Re(s.memoryMode);
1511
+ r?.({ phase: "ocr", progress: 0, message: "Starting OCR..." });
1512
+ const n = await de(e, s.lang, r);
1513
+ if (!n.fullText.trim())
1514
+ return { ocr: n, entities: [], redactions: [] };
1515
+ r?.({
1516
+ phase: "detecting",
1517
+ progress: 0,
1518
+ message: "Detecting personal information..."
1519
+ });
1520
+ const o = s.useRegex ? ye(n.fullText) : [];
1521
+ i === "low" && await me();
1522
+ const a = await pe(n.fullText, s.nerModel, s.minConfidence, r), l = Me(a, o), d = xe(l, n.words, n.imageWidth, n.imageHeight);
1523
+ return r?.({
1524
+ phase: "reviewing",
1525
+ progress: 1,
1526
+ message: `Found ${d.length} items to redact.`
1527
+ }), { ocr: n, entities: l, redactions: d };
1528
+ }
1529
+ function Re(e) {
1530
+ if (e === "low") return "low";
1531
+ if (e === "normal") return "normal";
1532
+ const t = navigator.deviceMemory;
1533
+ return t !== void 0 && t < 4 ? "low" : "normal";
1534
+ }
1535
+ const T = {
1536
+ lang: "eng",
1537
+ nerModel: "onnx-community/multilang-pii-ner-ONNX",
1538
+ maxFileSize: 20 * 1024 * 1024,
1539
+ acceptedTypes: ["image/png", "image/jpeg", "image/webp"],
1540
+ minConfidence: 0.7,
1541
+ useRegex: !0,
1542
+ memoryMode: "auto"
1543
+ };
1544
+ var Ue = Object.defineProperty, De = Object.getOwnPropertyDescriptor, m = (e, t, r, s) => {
1545
+ for (var i = s > 1 ? void 0 : s ? De(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1546
+ (o = e[n]) && (i = (s ? o(t, r, i) : o(i)) || i);
1547
+ return s && i && Ue(t, r, i), i;
1548
+ };
1549
+ let f = class extends R {
1550
+ constructor() {
1551
+ super(...arguments), this.lang = T.lang, this.nerModel = T.nerModel, this.maxFileSize = T.maxFileSize, this.minConfidence = T.minConfidence, this.phase = "idle", this.progress = 0, this.progressMessage = "", this.errorMessage = "", this.imageUrl = "", this.imageWidth = 0, this.imageHeight = 0, this.redactions = [], this.entities = [], this.ocrResult = null, this.dragOver = !1, this.isDrawing = !1, this.drawMode = !1, this.drawStart = null, this.drawCurrent = null, this.networkRequestCount = 0, this.imageFile = null, this.imageElement = null, this.undoStack = [];
1552
+ }
1553
+ // --- Public methods ---
1554
+ /** Pre-load AI models. Call this to warm up the cache ahead of time. */
1555
+ async preload() {
1556
+ await fe(this.nerModel, (e) => this.handleProgress(e));
1557
+ }
1558
+ /** Reset to the initial idle state. */
1559
+ reset() {
1560
+ this.phase = "idle", this.progress = 0, this.progressMessage = "", this.errorMessage = "", this.redactions = [], this.entities = [], this.ocrResult = null, this.imageFile = null, this.undoStack = [], this.drawMode = !1, this.imageUrl && (URL.revokeObjectURL(this.imageUrl), this.imageUrl = ""), this.imageElement = null;
1561
+ }
1562
+ disconnectedCallback() {
1563
+ super.disconnectedCallback(), this.imageUrl && URL.revokeObjectURL(this.imageUrl);
1564
+ }
1565
+ // --- Rendering ---
1566
+ render() {
1567
+ return _`
1568
+ <div class="container">
1569
+ ${this.renderTrustBanner()}
1570
+ ${this.phase === "idle" ? this.renderDropZone() : g}
1571
+ ${this.phase === "loading" || this.phase === "ocr" || this.phase === "detecting" ? this.renderProgress() : g}
1572
+ ${this.phase === "reviewing" ? this.renderEditor() : g}
1573
+ ${this.phase === "exporting" ? this.renderProgress() : g}
1574
+ ${this.errorMessage ? this.renderError() : g}
1575
+ </div>
1576
+ `;
1577
+ }
1578
+ renderTrustBanner() {
1579
+ return _`
1580
+ <div class="trust-banner">
1581
+ ${ie}
1582
+ <span>Your data never leaves your device. All processing happens in
1583
+ your browser.</span>
1584
+ <span class="network-count"
1585
+ >Network: ${this.networkRequestCount} requests</span
1586
+ >
1587
+ </div>
1588
+ `;
1589
+ }
1590
+ renderDropZone() {
1591
+ return _`
1592
+ <div
1593
+ class="dropzone ${this.dragOver ? "dragover" : ""}"
1594
+ @click=${this.handleDropZoneClick}
1595
+ @dragover=${this.handleDragOver}
1596
+ @dragleave=${this.handleDragLeave}
1597
+ @drop=${this.handleDrop}
1598
+ >
1599
+ ${ne}
1600
+ <div class="dropzone-text">
1601
+ <strong>Choose a screenshot</strong> or drag it here
1602
+ </div>
1603
+ <div class="dropzone-hint">
1604
+ PNG, JPG, or WebP up to
1605
+ ${Math.round(this.maxFileSize / 1024 / 1024)}MB
1606
+ </div>
1607
+ <input
1608
+ class="file-input"
1609
+ type="file"
1610
+ accept="image/png,image/jpeg,image/webp"
1611
+ capture="environment"
1612
+ @change=${this.handleFileSelect}
1613
+ />
1614
+ </div>
1615
+ `;
1616
+ }
1617
+ renderProgress() {
1618
+ return _`
1619
+ <div class="progress-container">
1620
+ <div class="progress-phase">
1621
+ ${{
1622
+ loading: "Loading AI models",
1623
+ ocr: "Reading text from image",
1624
+ detecting: "Detecting personal information",
1625
+ exporting: "Preparing redacted image"
1626
+ }[this.phase] ?? "Processing..."}
1627
+ </div>
1628
+ <div class="progress-bar-track">
1629
+ <div
1630
+ class="progress-bar-fill"
1631
+ style="width: ${Math.round(this.progress * 100)}%"
1632
+ ></div>
1633
+ </div>
1634
+ <div class="progress-message">${this.progressMessage}</div>
1635
+ </div>
1636
+ `;
1637
+ }
1638
+ renderEditor() {
1639
+ const e = `0 0 ${this.imageWidth} ${this.imageHeight}`;
1640
+ return _`
1641
+ <div class="editor">
1642
+ <div class="toolbar">
1643
+ <button
1644
+ class="${this.drawMode ? "active" : ""}"
1645
+ @click=${this.toggleDrawMode}
1646
+ title="Draw a redaction box manually"
1647
+ >
1648
+ ${this.drawMode ? "Drawing..." : "+ Add box"}
1649
+ </button>
1650
+ <button
1651
+ @click=${this.handleUndo}
1652
+ ?disabled=${this.undoStack.length === 0}
1653
+ >
1654
+ Undo
1655
+ </button>
1656
+ <button
1657
+ @click=${this.handleSelectAll}
1658
+ >
1659
+ Select all
1660
+ </button>
1661
+ <button
1662
+ @click=${this.handleDeselectAll}
1663
+ >
1664
+ Deselect all
1665
+ </button>
1666
+ <span class="spacer"></span>
1667
+ <button class="danger" @click=${this.handleCancel}>Cancel</button>
1668
+ <button class="primary" @click=${this.handleConfirm}>
1669
+ Confirm &amp; redact
1670
+ </button>
1671
+ </div>
1672
+
1673
+ <div class="viewport">
1674
+ <div class="viewport-inner">
1675
+ <img
1676
+ src=${this.imageUrl}
1677
+ alt="Screenshot to redact"
1678
+ @load=${this.handleImageLoad}
1679
+ />
1680
+ <svg
1681
+ viewBox=${e}
1682
+ preserveAspectRatio="xMidYMid meet"
1683
+ xmlns="http://www.w3.org/2000/svg"
1684
+ @pointerdown=${this.handleSvgPointerDown}
1685
+ @pointermove=${this.handleSvgPointerMove}
1686
+ @pointerup=${this.handleSvgPointerUp}
1687
+ >
1688
+ ${this.redactions.map(
1689
+ (t) => z`
1690
+ <rect
1691
+ class="redaction-box ${t.enabled ? "" : "disabled"}"
1692
+ x=${t.bbox.x0}
1693
+ y=${t.bbox.y0}
1694
+ width=${t.bbox.x1 - t.bbox.x0}
1695
+ height=${t.bbox.y1 - t.bbox.y0}
1696
+ data-id=${t.id}
1697
+ @click=${(r) => this.handleRedactionClick(r, t.id)}
1698
+ >
1699
+ <title>${t.label ?? "Redaction"}: ${t.enabled ? "enabled" : "disabled"}</title>
1700
+ </rect>
1701
+ `
1702
+ )}
1703
+ ${this.isDrawing && this.drawStart && this.drawCurrent ? z`
1704
+ <rect
1705
+ class="drawing"
1706
+ x=${Math.min(this.drawStart.x, this.drawCurrent.x)}
1707
+ y=${Math.min(this.drawStart.y, this.drawCurrent.y)}
1708
+ width=${Math.abs(this.drawCurrent.x - this.drawStart.x)}
1709
+ height=${Math.abs(this.drawCurrent.y - this.drawStart.y)}
1710
+ />
1711
+ ` : g}
1712
+ </svg>
1713
+ </div>
1714
+ </div>
1715
+
1716
+ <div class="entity-list">
1717
+ <div class="entity-list-header">
1718
+ Detected items (${this.redactions.filter((t) => t.enabled).length}
1719
+ / ${this.redactions.length})
1720
+ </div>
1721
+ ${this.redactions.map(
1722
+ (t) => _`
1723
+ <label class="entity-item">
1724
+ <input
1725
+ type="checkbox"
1726
+ .checked=${t.enabled}
1727
+ @change=${(r) => this.handleToggleRedaction(
1728
+ t.id,
1729
+ r.target.checked
1730
+ )}
1731
+ />
1732
+ <span class="entity-label">${t.label ?? "manual"}</span>
1733
+ <span class="entity-text"
1734
+ >${this.getRedactionText(t)}</span
1735
+ >
1736
+ <span class="entity-source">${t.source}</span>
1737
+ </label>
1738
+ `
1739
+ )}
1740
+ </div>
1741
+ </div>
1742
+ `;
1743
+ }
1744
+ renderError() {
1745
+ return _`
1746
+ <div class="error">
1747
+ <p>${this.errorMessage}</p>
1748
+ <button @click=${this.reset}>Try again</button>
1749
+ </div>
1750
+ `;
1751
+ }
1752
+ // --- File handling ---
1753
+ handleDropZoneClick() {
1754
+ this.fileInput?.click();
1755
+ }
1756
+ handleDragOver(e) {
1757
+ e.preventDefault(), this.dragOver = !0;
1758
+ }
1759
+ handleDragLeave() {
1760
+ this.dragOver = !1;
1761
+ }
1762
+ handleDrop(e) {
1763
+ e.preventDefault(), this.dragOver = !1;
1764
+ const t = e.dataTransfer?.files[0];
1765
+ t && this.processFile(t);
1766
+ }
1767
+ handleFileSelect(e) {
1768
+ const t = e.target, r = t.files?.[0];
1769
+ r && this.processFile(r), t.value = "";
1770
+ }
1771
+ async processFile(e) {
1772
+ if (!T.acceptedTypes.includes(e.type)) {
1773
+ this.errorMessage = `Unsupported file type: ${e.type}. Please use PNG, JPEG, or WebP.`;
1774
+ return;
1775
+ }
1776
+ if (e.size > this.maxFileSize) {
1777
+ this.errorMessage = `File too large (${Math.round(e.size / 1024 / 1024)}MB). Maximum is ${Math.round(this.maxFileSize / 1024 / 1024)}MB.`;
1778
+ return;
1779
+ }
1780
+ this.errorMessage = "", this.imageFile = e, this.imageUrl = URL.createObjectURL(e), this.phase = "loading";
1781
+ try {
1782
+ const t = await this.loadImage(this.imageUrl);
1783
+ this.imageElement = t, this.imageWidth = t.naturalWidth, this.imageHeight = t.naturalHeight;
1784
+ const r = {
1785
+ lang: this.lang,
1786
+ nerModel: this.nerModel,
1787
+ minConfidence: this.minConfidence
1788
+ }, s = await Oe(
1789
+ e,
1790
+ r,
1791
+ (i) => this.handleProgress(i)
1792
+ );
1793
+ this.ocrResult = s.ocr, this.entities = s.entities, this.redactions = s.redactions, this.undoStack = [], this.phase = "reviewing";
1794
+ } catch (t) {
1795
+ console.error("Pipeline error:", t), this.errorMessage = t instanceof Error ? t.message : "An unexpected error occurred.", this.phase = "idle";
1796
+ }
1797
+ }
1798
+ loadImage(e) {
1799
+ return new Promise((t, r) => {
1800
+ const s = new Image();
1801
+ s.onload = () => t(s), s.onerror = () => r(new Error("Failed to load image")), s.src = e;
1802
+ });
1803
+ }
1804
+ // --- Progress ---
1805
+ handleProgress(e) {
1806
+ this.phase = e.phase, this.progress = e.progress, this.progressMessage = e.message;
1807
+ }
1808
+ // --- Redaction editing ---
1809
+ handleRedactionClick(e, t) {
1810
+ if (e.stopPropagation(), this.drawMode) return;
1811
+ this.redactions.find((s) => s.id === t) && (this.pushUndo(), this.redactions = this.redactions.map(
1812
+ (s) => s.id === t ? { ...s, enabled: !s.enabled } : s
1813
+ ));
1814
+ }
1815
+ handleToggleRedaction(e, t) {
1816
+ this.pushUndo(), this.redactions = this.redactions.map(
1817
+ (r) => r.id === e ? { ...r, enabled: t } : r
1818
+ );
1819
+ }
1820
+ handleSelectAll() {
1821
+ this.pushUndo(), this.redactions = this.redactions.map((e) => ({ ...e, enabled: !0 }));
1822
+ }
1823
+ handleDeselectAll() {
1824
+ this.pushUndo(), this.redactions = this.redactions.map((e) => ({ ...e, enabled: !1 }));
1825
+ }
1826
+ handleUndo() {
1827
+ const e = this.undoStack.pop();
1828
+ e && (this.redactions = e, this.undoStack = [...this.undoStack]);
1829
+ }
1830
+ pushUndo() {
1831
+ this.undoStack = [...this.undoStack, [...this.redactions]];
1832
+ }
1833
+ // --- Drawing manual boxes ---
1834
+ toggleDrawMode() {
1835
+ this.drawMode = !this.drawMode, this.isDrawing = !1, this.drawStart = null, this.drawCurrent = null;
1836
+ }
1837
+ svgPointFromEvent(e) {
1838
+ const t = e.currentTarget ?? this.renderRoot.querySelector("svg");
1839
+ if (!t) return { x: 0, y: 0 };
1840
+ const r = t.createSVGPoint();
1841
+ r.x = e.clientX, r.y = e.clientY;
1842
+ const s = t.getScreenCTM();
1843
+ if (!s) return { x: 0, y: 0 };
1844
+ const i = r.matrixTransform(s.inverse());
1845
+ return { x: i.x, y: i.y };
1846
+ }
1847
+ handleSvgPointerDown(e) {
1848
+ if (!this.drawMode) return;
1849
+ const t = this.svgPointFromEvent(e);
1850
+ this.drawStart = t, this.drawCurrent = t, this.isDrawing = !0, e.currentTarget.setPointerCapture(e.pointerId), e.preventDefault();
1851
+ }
1852
+ handleSvgPointerMove(e) {
1853
+ !this.isDrawing || !this.drawStart || (this.drawCurrent = this.svgPointFromEvent(e), e.preventDefault());
1854
+ }
1855
+ handleSvgPointerUp(e) {
1856
+ if (!this.isDrawing || !this.drawStart || !this.drawCurrent) return;
1857
+ const t = Math.min(this.drawStart.x, this.drawCurrent.x), r = Math.min(this.drawStart.y, this.drawCurrent.y), s = Math.max(this.drawStart.x, this.drawCurrent.x), i = Math.max(this.drawStart.y, this.drawCurrent.y);
1858
+ if (s - t > 10 && i - r > 10) {
1859
+ this.pushUndo();
1860
+ const n = {
1861
+ id: `manual-${Date.now()}`,
1862
+ bbox: { x0: t, y0: r, x1: s, y1: i },
1863
+ source: "manual",
1864
+ enabled: !0,
1865
+ label: "MANUAL"
1866
+ };
1867
+ this.redactions = [...this.redactions, n];
1868
+ }
1869
+ this.isDrawing = !1, this.drawStart = null, this.drawCurrent = null, this.drawMode = !1;
1870
+ }
1871
+ // --- Actions ---
1872
+ async handleConfirm() {
1873
+ if (this.imageElement) {
1874
+ this.phase = "exporting", this.progress = 0.5, this.progressMessage = "Rendering redacted image...";
1875
+ try {
1876
+ const e = await Ce(
1877
+ this.imageElement,
1878
+ this.redactions
1879
+ );
1880
+ this.dispatchEvent(
1881
+ new CustomEvent("redaction-complete", {
1882
+ detail: e,
1883
+ bubbles: !0,
1884
+ composed: !0
1885
+ })
1886
+ ), this.progress = 1, this.progressMessage = "Done.";
1887
+ } catch (e) {
1888
+ console.error("Export error:", e), this.errorMessage = e instanceof Error ? e.message : "Failed to export redacted image.", this.phase = "reviewing";
1889
+ }
1890
+ }
1891
+ }
1892
+ handleCancel() {
1893
+ this.dispatchEvent(
1894
+ new CustomEvent("redaction-cancel", {
1895
+ bubbles: !0,
1896
+ composed: !0
1897
+ })
1898
+ ), this.reset();
1899
+ }
1900
+ // --- Helpers ---
1901
+ getRedactionText(e) {
1902
+ return e.source === "manual" ? "(manually drawn)" : !e.entityId || !this.ocrResult ? "" : this.entities.find((r) => r.id === e.entityId)?.text ?? "";
1903
+ }
1904
+ handleImageLoad(e) {
1905
+ const t = e.target;
1906
+ this.imageWidth = t.naturalWidth, this.imageHeight = t.naturalHeight;
1907
+ }
1908
+ };
1909
+ f.styles = se;
1910
+ m([
1911
+ I({ type: String })
1912
+ ], f.prototype, "lang", 2);
1913
+ m([
1914
+ I({ type: String, attribute: "ner-model" })
1915
+ ], f.prototype, "nerModel", 2);
1916
+ m([
1917
+ I({ type: Number, attribute: "max-file-size" })
1918
+ ], f.prototype, "maxFileSize", 2);
1919
+ m([
1920
+ I({ type: Number, attribute: "min-confidence" })
1921
+ ], f.prototype, "minConfidence", 2);
1922
+ m([
1923
+ y()
1924
+ ], f.prototype, "phase", 2);
1925
+ m([
1926
+ y()
1927
+ ], f.prototype, "progress", 2);
1928
+ m([
1929
+ y()
1930
+ ], f.prototype, "progressMessage", 2);
1931
+ m([
1932
+ y()
1933
+ ], f.prototype, "errorMessage", 2);
1934
+ m([
1935
+ y()
1936
+ ], f.prototype, "imageUrl", 2);
1937
+ m([
1938
+ y()
1939
+ ], f.prototype, "imageWidth", 2);
1940
+ m([
1941
+ y()
1942
+ ], f.prototype, "imageHeight", 2);
1943
+ m([
1944
+ y()
1945
+ ], f.prototype, "redactions", 2);
1946
+ m([
1947
+ y()
1948
+ ], f.prototype, "entities", 2);
1949
+ m([
1950
+ y()
1951
+ ], f.prototype, "ocrResult", 2);
1952
+ m([
1953
+ y()
1954
+ ], f.prototype, "dragOver", 2);
1955
+ m([
1956
+ y()
1957
+ ], f.prototype, "isDrawing", 2);
1958
+ m([
1959
+ y()
1960
+ ], f.prototype, "drawMode", 2);
1961
+ m([
1962
+ y()
1963
+ ], f.prototype, "drawStart", 2);
1964
+ m([
1965
+ y()
1966
+ ], f.prototype, "drawCurrent", 2);
1967
+ m([
1968
+ y()
1969
+ ], f.prototype, "networkRequestCount", 2);
1970
+ m([
1971
+ re(".file-input")
1972
+ ], f.prototype, "fileInput", 2);
1973
+ f = m([
1974
+ Xt("pii-redactor")
1975
+ ], f);
1976
+ async function Ie(e = {}) {
1977
+ if (!("serviceWorker" in navigator) || !navigator.serviceWorker)
1978
+ return null;
1979
+ const t = e.swPath ?? "/pii-redactor-sw.js", r = {};
1980
+ e.scope && (r.scope = e.scope);
1981
+ try {
1982
+ return await navigator.serviceWorker.register(t, r);
1983
+ } catch {
1984
+ return null;
1985
+ }
1986
+ }
1987
+ async function Le() {
1988
+ if (!("serviceWorker" in navigator) || !navigator.serviceWorker)
1989
+ return !1;
1990
+ try {
1991
+ const e = await navigator.serviceWorker.getRegistrations();
1992
+ return (await Promise.all(e.map((r) => r.unregister()))).some(Boolean);
1993
+ } catch {
1994
+ return !1;
1995
+ }
1996
+ }
1997
+ export {
1998
+ oe as DARK_THRESHOLD,
1999
+ T as DEFAULT_CONFIG,
2000
+ f as PiiRedactor,
2001
+ Oe as analyzeImage,
2002
+ ae as computeAverageLuminance,
2003
+ pe as detectPiiNer,
2004
+ ye as detectPiiRegex,
2005
+ He as drawRedactionPreview,
2006
+ xe as entitiesToRedactions,
2007
+ le as isDarkBackground,
2008
+ Me as mergeEntities,
2009
+ fe as preloadNerModel,
2010
+ ce as preprocessForOcr,
2011
+ Ie as registerServiceWorker,
2012
+ me as releaseNerModel,
2013
+ Ce as renderRedactedImage,
2014
+ de as runOcr,
2015
+ Le as unregisterServiceWorker
2016
+ };
2017
+ //# sourceMappingURL=image-pii-redactor.js.map