@inpageedit/core 0.14.2 → 0.14.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/{BasePlugin-YOi2_vUo.js → BasePlugin-DD7l-5Xw.js} +2 -2
  2. package/dist/{BasePlugin-YOi2_vUo.js.map → BasePlugin-DD7l-5Xw.js.map} +1 -1
  3. package/dist/{PluginPrefSync-jTNlRQE-.js → PluginPrefSync-CbFuuC19.js} +3 -3
  4. package/dist/{PluginPrefSync-jTNlRQE-.js.map → PluginPrefSync-CbFuuC19.js.map} +1 -1
  5. package/dist/{PluginStoreApp-CGNxKXAN.js → PluginStoreApp-qiSVtnBy.js} +2 -2
  6. package/dist/{PluginStoreApp-CGNxKXAN.js.map → PluginStoreApp-qiSVtnBy.js.map} +1 -1
  7. package/dist/Preferences-C10tZMl1.js +2701 -0
  8. package/dist/Preferences-C10tZMl1.js.map +1 -0
  9. package/dist/{index-3NZkG2a3.js → index-BXNyXvre.js} +3 -3
  10. package/dist/{index-3NZkG2a3.js.map → index-BXNyXvre.js.map} +1 -1
  11. package/dist/{index-Dclp60EO.js → index-BanevHQ2.js} +3 -3
  12. package/dist/{index-Dclp60EO.js.map → index-BanevHQ2.js.map} +1 -1
  13. package/dist/index-BjDTD66_.js +491 -0
  14. package/dist/index-BjDTD66_.js.map +1 -0
  15. package/dist/{index-D97lUU3h.js → index-BpQ6VGMz.js} +55 -55
  16. package/dist/index-BpQ6VGMz.js.map +1 -0
  17. package/dist/{index-D-fW3ESK.js → index-CnR6CqkM.js} +2 -2
  18. package/dist/{index-D-fW3ESK.js.map → index-CnR6CqkM.js.map} +1 -1
  19. package/dist/{index-DELHsLHS.js → index-DKCZDN-Q.js} +4 -4
  20. package/dist/{index-DELHsLHS.js.map → index-DKCZDN-Q.js.map} +1 -1
  21. package/dist/{index-BBNseJXG.js → index-DVOc6fB6.js} +3 -3
  22. package/dist/{index-BBNseJXG.js.map → index-DVOc6fB6.js.map} +1 -1
  23. package/dist/{index-D6zFqL2u.js → index-De25v1_Q.js} +3 -3
  24. package/dist/{index-D6zFqL2u.js.map → index-De25v1_Q.js.map} +1 -1
  25. package/dist/{index-BrYKe18j.js → index-DensW9qt.js} +3 -3
  26. package/dist/{index-BrYKe18j.js.map → index-DensW9qt.js.map} +1 -1
  27. package/dist/{index-QtEF2mzS.js → index-DrIf5j8O.js} +4 -4
  28. package/dist/{index-QtEF2mzS.js.map → index-DrIf5j8O.js.map} +1 -1
  29. package/dist/index-MgXERLzL.js +3090 -0
  30. package/dist/index-MgXERLzL.js.map +1 -0
  31. package/dist/{index-DmLoihN1.js → index-WfXtYVMt.js} +134 -131
  32. package/dist/index-WfXtYVMt.js.map +1 -0
  33. package/dist/index.d.ts +15 -8
  34. package/dist/index.js +5 -5
  35. package/dist/models/index.js +7 -503
  36. package/dist/models/index.js.map +1 -1
  37. package/dist/plugins/index.js +10 -10
  38. package/dist/services/index.js +1 -1
  39. package/lib/index.umd.js +11 -11
  40. package/lib/index.umd.js.map +1 -1
  41. package/package.json +1 -1
  42. package/dist/Preferences-BF2fcXrn.js +0 -1539
  43. package/dist/Preferences-BF2fcXrn.js.map +0 -1
  44. package/dist/index-C3m6ng6b.js +0 -4245
  45. package/dist/index-C3m6ng6b.js.map +0 -1
  46. package/dist/index-D97lUU3h.js.map +0 -1
  47. package/dist/index-DmLoihN1.js.map +0 -1
@@ -0,0 +1,3090 @@
1
+ import { u as it, c as st, a as nt } from "./index-BjDTD66_.js";
2
+ import { G as rt, c as C, q as pe, I as H, S as p, d as xe, i as ot, p as T, R as at, E as ke, j as lt, U as ct } from "./Preferences-C10tZMl1.js";
3
+ import { j as $, P as ht } from "./index-CM_6yF2v.js";
4
+ var Ee = /* @__PURE__ */ ((s) => (s[s.debug = -1] = "debug", s[s.log = 0] = "log", s[s.info = 1] = "info", s[s.warn = 2] = "warn", s[s.error = 3] = "error", s[s.silent = 4] = "silent", s))(Ee || {});
5
+ const V = globalThis || window, Z = Symbol.for("__IPE_LOGGER_COLOR_MAP__");
6
+ V[Z] || (V[Z] = /* @__PURE__ */ new Map());
7
+ const X = V[Z];
8
+ function M(s) {
9
+ let e = 2166136261;
10
+ for (let t = 0; t < s.length; t++)
11
+ e ^= s.charCodeAt(t), e = (e >>> 0) * 16777619;
12
+ return e >>> 0;
13
+ }
14
+ const me = [
15
+ [350, 360],
16
+ [0, 15],
17
+ [15, 30],
18
+ [200, 230],
19
+ [230, 250],
20
+ [250, 280],
21
+ [280, 310],
22
+ [310, 330],
23
+ [140, 160],
24
+ [160, 180]
25
+ ];
26
+ function dt(s, e) {
27
+ const t = me.length, i = M(s) % t, [n, r] = me[i], o = r - n, a = M(s + ":" + e), c = n + a % (o || 1), l = M(s + ":s"), h = M(s + ":l");
28
+ let d, f;
29
+ if (e === "name")
30
+ d = 62 + l % 18, f = 30 + h % 12;
31
+ else {
32
+ const u = c >= 0 && c < 50 || c > 330 && c < 360, g = c >= 200 && c <= 300;
33
+ d = 55 + l % 20, g ? f = 55 + h % 8 : u ? f = 48 + h % 6 : f = 50 + h % 8, d < 60 && (d += 5);
34
+ }
35
+ return `hsl(${c}, ${d}%, ${f}%)`;
36
+ }
37
+ function B(s, e) {
38
+ if (e)
39
+ return X.set(s, e), e;
40
+ const t = X.get(s);
41
+ if (t) return t;
42
+ const i = s.startsWith("name:") ? "name" : "group", n = dt(s, i);
43
+ return X.set(s, n), n;
44
+ }
45
+ class te {
46
+ /**
47
+ * Note: constructor returns a callable Proxy so that you can do `logger('group')`.
48
+ */
49
+ constructor(e = {}) {
50
+ this._custom = (t) => {
51
+ if (!this._enabled(t.level)) return we;
52
+ const [i, n] = this._prefix(t.label);
53
+ return this._consoleMethod(t.method).bind(console, i, ...n);
54
+ }, this._name = e.name, this._nameColor = e.color, this._groupPath = e._groupPath ? [...e._groupPath] : [], this._dynamicLevels = { ...e._dynamicLevels }, this._levelRef = e._levelRef ?? {
55
+ value: e.level ?? 1
56
+ /* info */
57
+ }, this._name && B(`name:${this._name}`, this._nameColor), this._installBuiltinLevels();
58
+ for (const t of Object.keys(this._dynamicLevels))
59
+ this._installLevelGetter(t, this._dynamicLevels[t]);
60
+ return ft(this);
61
+ }
62
+ // ---------- public API ----------
63
+ get level() {
64
+ return this._levelRef.value;
65
+ }
66
+ set level(e) {
67
+ this._levelRef.value = e;
68
+ }
69
+ /** Create a sub-logger with a group label */
70
+ group(e, t) {
71
+ return e && B(`group:${e}`, t?.color), new te({
72
+ name: this._name,
73
+ color: this._nameColor,
74
+ _groupPath: [...this._groupPath, e],
75
+ _dynamicLevels: this._dynamicLevels,
76
+ _levelRef: this._levelRef
77
+ });
78
+ }
79
+ /** Define a custom level, e.g. logger.defineLevel('success', { level: info, label: '✅', method: 'info' }) */
80
+ defineLevel(e, t) {
81
+ this._dynamicLevels[e] = { ...t }, this._installLevelGetter(e, t);
82
+ }
83
+ // Built-in level getters
84
+ get debug() {
85
+ return this._method("debug");
86
+ }
87
+ get log() {
88
+ return this._method("log");
89
+ }
90
+ get info() {
91
+ return this._method("info");
92
+ }
93
+ get warn() {
94
+ return this._method("warn");
95
+ }
96
+ get error() {
97
+ return this._method("error");
98
+ }
99
+ // ---------- internals ----------
100
+ _installBuiltinLevels() {
101
+ }
102
+ _installLevelGetter(e, t) {
103
+ Object.defineProperty(this, e, {
104
+ configurable: !0,
105
+ enumerable: !1,
106
+ get: () => this._custom(t)
107
+ });
108
+ }
109
+ _method(e) {
110
+ const t = ut[e];
111
+ if (!this._enabled(t.level)) return we;
112
+ const [i, n] = this._prefix(t.label);
113
+ return this._consoleMethod(e).bind(console, i, ...n);
114
+ }
115
+ _consoleMethod(e) {
116
+ return (console[e] || console.log).bind(console);
117
+ }
118
+ _enabled(e) {
119
+ return e >= this._levelRef.value && this._levelRef.value !== 4;
120
+ }
121
+ _prefix(e) {
122
+ const t = [];
123
+ let i = "";
124
+ if (this._name) {
125
+ const n = B(`name:${this._name}`, this._nameColor);
126
+ i += `%c${this._name}%c`, t.push(
127
+ `background:${n}; color:#fff; padding:1px 4px; border-radius:2px; font-weight:700;`,
128
+ ye
129
+ );
130
+ }
131
+ if (e && (i += ` ${e}`), this._groupPath.length) {
132
+ const n = this._groupPath.join("/"), r = B(`group:${n}`);
133
+ i += ` %c${n}%c`, t.push(`color:${r}; text-decoration: underline;`, ye);
134
+ }
135
+ return [i, t];
136
+ }
137
+ }
138
+ const we = () => {
139
+ }, ye = "color:inherit; background:transparent; text-decoration:none;", ut = {
140
+ debug: { level: -1, label: "", method: "debug" },
141
+ log: { level: 0, label: "", method: "log" },
142
+ info: { level: 1, label: "[I]", method: "info" },
143
+ warn: { level: 2, label: "[W]", method: "warn" },
144
+ error: { level: 3, label: "[E]", method: "error" }
145
+ };
146
+ function ft(s) {
147
+ const e = function(t, i) {
148
+ return s.group(t, i);
149
+ };
150
+ return new Proxy(e, {
151
+ get(t, i, n) {
152
+ return s[i];
153
+ },
154
+ set(t, i, n) {
155
+ return s[i] = n, !0;
156
+ },
157
+ apply(t, i, n) {
158
+ return s.group(n[0], n[1]);
159
+ },
160
+ has(t, i) {
161
+ return i in s;
162
+ }
163
+ });
164
+ }
165
+ function gt(s) {
166
+ return new te(s);
167
+ }
168
+ class pt {
169
+ constructor(e, t = {}) {
170
+ this.ctx = e, location?.href && t?.baseURL?.toString()?.startsWith("/") && (t.baseURL = new URL(t.baseURL, location.origin));
171
+ const i = new rt({
172
+ baseURL: t.baseURL.toString(),
173
+ fexiosConfigs: {
174
+ headers: {
175
+ "x-api-user-agent": `InPageEdit-NEXT ${e.version}`,
176
+ ...t.headers
177
+ },
178
+ ...t
179
+ },
180
+ throwOnApiError: !0
181
+ });
182
+ e.set("api", i);
183
+ }
184
+ }
185
+ var mt = Object.create, ie = Object.defineProperty, wt = Object.getOwnPropertyDescriptor, Ce = (s, e) => (e = Symbol[s]) ? e : Symbol.for("Symbol." + s), Ie = (s) => {
186
+ throw TypeError(s);
187
+ }, yt = (s, e, t) => e in s ? ie(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t, bt = (s, e) => ie(s, "name", { value: e, configurable: !0 }), vt = (s) => [, , , mt(s?.[Ce("metadata")] ?? null)], _t = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], Le = (s) => s !== void 0 && typeof s != "function" ? Ie("Function expected") : s, $t = (s, e, t, i, n) => ({ kind: _t[s], name: e, metadata: i, addInitializer: (r) => t._ ? Ie("Already initialized") : n.push(Le(r || null)) }), St = (s, e) => yt(e, Ce("metadata"), s[3]), xt = (s, e, t, i) => {
188
+ for (var n = 0, r = s[e >> 1], o = r && r.length; n < o; n++) r[n].call(t);
189
+ return i;
190
+ }, kt = (s, e, t, i, n, r) => {
191
+ var o, a, c, l = e & 7, h = !1, d = 0, f = s[d] || (s[d] = []), u = l && (n = n.prototype, l < 5 && (l > 3 || !h) && wt(n, t));
192
+ bt(n, t);
193
+ for (var g = i.length - 1; g >= 0; g--)
194
+ c = $t(l, t, a = {}, s[3], f), o = (0, i[g])(n, c), a._ = 1, Le(o) && (n = o);
195
+ return St(s, n), u && ie(n, t, u), h ? l ^ 4 ? r : u : n;
196
+ }, Pe, se, Ae;
197
+ Pe = [H(["wiki", "wikiTitle"])];
198
+ class N extends (Ae = C) {
199
+ constructor(e) {
200
+ super(e, "currentPage", !1), this.ctx = e, this.url = new URL(window.location.href), this.isMainPage = void 0, this.wikiTitle = void 0;
201
+ }
202
+ get logger() {
203
+ return this.ctx.logger("CURRENT_PAGE");
204
+ }
205
+ async start() {
206
+ await this.#e(), this.#i(), window.addEventListener("popstate", this.#t.bind(this)), this.logger.info("initialized", this.wikiTitle);
207
+ }
208
+ stop() {
209
+ window.removeEventListener("popstate", this.#t.bind(this));
210
+ }
211
+ async #e() {
212
+ await this.#n(), await this.#s();
213
+ }
214
+ #i() {
215
+ const e = Symbol.for("InPageEdit.CurrentPageService.UrlChangeListenerInstalled");
216
+ if (window[e])
217
+ return;
218
+ const t = history.pushState, i = history.replaceState;
219
+ history.pushState = function(n, r, o) {
220
+ t.apply(this, [n, r, o]), window.dispatchEvent(new PopStateEvent("popstate", { state: n }));
221
+ }, history.replaceState = function(n, r, o) {
222
+ i.apply(this, [n, r, o]), window.dispatchEvent(new PopStateEvent("popstate", { state: n }));
223
+ }, window[e] = !0;
224
+ }
225
+ async #t(e) {
226
+ const t = this.url, i = new URL(window.location.href);
227
+ this.url = i, (t.pathname !== i.pathname || t.searchParams.get("title") !== i.searchParams.get("title") || t.searchParams.get("curid") !== i.searchParams.get("curid")) && (await this.#e(), this.logger.info("location changed", i, this.wikiTitle));
228
+ }
229
+ get params() {
230
+ return this.url.searchParams;
231
+ }
232
+ get canonicalUrl() {
233
+ const e = (pe('link[rel="alternate"][hreflang="x-default"]') || pe('link[rel="canonical"]'))?.href;
234
+ let t = null;
235
+ return e && (t = new URL(e, location.origin)), Reflect.defineProperty(this, "canonicalUrl", {
236
+ get: () => t
237
+ }), t;
238
+ }
239
+ async #s() {
240
+ const t = this.wikiTitle?.getMainDBKey() === this.ctx.wiki.mainPageName;
241
+ return Reflect.defineProperty(this, "isMainPage", {
242
+ get: () => t
243
+ }), t;
244
+ }
245
+ async #n() {
246
+ let e = null;
247
+ return this.canonicalUrl ? e = await this.ctx.wikiTitle.newTitleFromUrl(this.canonicalUrl) : e = await this.ctx.wikiTitle.newTitleFromUrl(this.url), Object.freeze(e), Reflect.defineProperty(this, "wikiTitle", {
248
+ get: () => e
249
+ }), e;
250
+ }
251
+ get wikiAction() {
252
+ return this.params.get("action") || "view";
253
+ }
254
+ }
255
+ se = vt(Ae);
256
+ N = kt(se, 0, "CurrentPageService", Pe, N);
257
+ xt(se, 1, N);
258
+ class Et extends C {
259
+ constructor(e) {
260
+ super(e, "resourceLoader", !0), this.ctx = e;
261
+ }
262
+ stop() {
263
+ this.removeAll();
264
+ }
265
+ loadScript(e, t) {
266
+ if (!e)
267
+ return Promise.resolve(null);
268
+ const i = `script:${e}`, n = document.querySelector(`[data-ipe="${i}"]`);
269
+ return n ? Promise.resolve(n) : new Promise((o, a) => {
270
+ const c = document.createElement("script");
271
+ c.src = e, c.dataset.ipe = i, t && Object.entries(t).forEach(([l, h]) => {
272
+ typeof h > "u" || h === !1 || h === null ? c.removeAttribute(l) : c.setAttribute(l, h);
273
+ }), document.body.appendChild(c), c.onload = () => o(c), c.onerror = (l) => a(l);
274
+ });
275
+ }
276
+ loadStyle(e, t) {
277
+ if (!e)
278
+ return Promise.resolve(null);
279
+ const i = `style:${e}`, n = document.querySelector(`[data-ipe="${i}"]`);
280
+ return n ? Promise.resolve(n) : new Promise((o, a) => {
281
+ const c = document.createElement("link");
282
+ c.rel = "stylesheet", c.href = e, c.dataset.ipe = i, t && Object.entries(t).forEach(([h, d]) => {
283
+ typeof d > "u" || d === !1 || d === null ? c.removeAttribute(h) : c.setAttribute(h, d);
284
+ }), (document.querySelector('meta[name="ipe-styles"]') || (() => {
285
+ const h = document.createElement("meta");
286
+ return h.id = "ipe-styles", h.name = "ipe-styles", document.head.insertAdjacentElement("afterbegin", h), h;
287
+ })()).before(c), c.onload = () => o(c), c.onerror = (h) => a(h);
288
+ });
289
+ }
290
+ removeStyle(e) {
291
+ const t = `style:${e}`, i = document.querySelector(`[data-ipe="${t}"]`);
292
+ i && i.remove();
293
+ }
294
+ removeScript(e) {
295
+ const t = `script:${e}`, i = document.querySelector(`[data-ipe="${t}"]`);
296
+ i && i.remove();
297
+ }
298
+ removeAll() {
299
+ document.querySelectorAll("[data-ipe]").forEach((e) => {
300
+ e.remove();
301
+ });
302
+ }
303
+ resolveImportPath(e) {
304
+ return e.startsWith("http") || e.startsWith("//") ? e : import.meta.resolve(e);
305
+ }
306
+ }
307
+ const W = Object.keys;
308
+ function Ct(s) {
309
+ return typeof s == "boolean";
310
+ }
311
+ function It(s) {
312
+ return s && typeof s.nodeType == "number";
313
+ }
314
+ function ne(s) {
315
+ return typeof s == "string";
316
+ }
317
+ function De(s) {
318
+ return typeof s == "number";
319
+ }
320
+ function L(s) {
321
+ return typeof s == "object" ? s !== null : R(s);
322
+ }
323
+ function R(s) {
324
+ return typeof s == "function";
325
+ }
326
+ function Lt(s) {
327
+ return !!(s && s.isComponent);
328
+ }
329
+ function Pt(s) {
330
+ return L(s) && typeof s.length == "number" && typeof s.nodeType != "number";
331
+ }
332
+ function J(s, e) {
333
+ if (s)
334
+ for (const t of W(s))
335
+ e(s[t], t);
336
+ }
337
+ function At(s) {
338
+ return L(s) && "current" in s;
339
+ }
340
+ const Q = {
341
+ animationIterationCount: 0,
342
+ borderImageOutset: 0,
343
+ borderImageSlice: 0,
344
+ borderImageWidth: 0,
345
+ boxFlex: 0,
346
+ boxFlexGroup: 0,
347
+ boxOrdinalGroup: 0,
348
+ columnCount: 0,
349
+ columns: 0,
350
+ flex: 0,
351
+ flexGrow: 0,
352
+ flexPositive: 0,
353
+ flexShrink: 0,
354
+ flexNegative: 0,
355
+ flexOrder: 0,
356
+ gridArea: 0,
357
+ gridRow: 0,
358
+ gridRowEnd: 0,
359
+ gridRowSpan: 0,
360
+ gridRowStart: 0,
361
+ gridColumn: 0,
362
+ gridColumnEnd: 0,
363
+ gridColumnSpan: 0,
364
+ gridColumnStart: 0,
365
+ fontWeight: 0,
366
+ lineClamp: 0,
367
+ lineHeight: 0,
368
+ opacity: 0,
369
+ order: 0,
370
+ orphans: 0,
371
+ tabSize: 0,
372
+ widows: 0,
373
+ zIndex: 0,
374
+ zoom: 0,
375
+ // SVG-related properties
376
+ fillOpacity: 0,
377
+ floodOpacity: 0,
378
+ stopOpacity: 0,
379
+ strokeDasharray: 0,
380
+ strokeDashoffset: 0,
381
+ strokeMiterlimit: 0,
382
+ strokeOpacity: 0,
383
+ strokeWidth: 0
384
+ };
385
+ function Dt(s, e) {
386
+ return s + e.charAt(0).toUpperCase() + e.substring(1);
387
+ }
388
+ const Tt = ["Webkit", "ms", "Moz", "O"];
389
+ W(Q).forEach((s) => {
390
+ Tt.forEach((e) => {
391
+ Q[Dt(e, s)] = 0;
392
+ });
393
+ });
394
+ const Rt = Symbol.for("jsx-dom:type");
395
+ var Te = /* @__PURE__ */ (function(s) {
396
+ return s.ShadowRoot = "ShadowRoot", s;
397
+ })(Te || {});
398
+ function Mt(s) {
399
+ return s != null && s[Rt] === Te.ShadowRoot;
400
+ }
401
+ const Bt = "http://www.w3.org/2000/svg", Ot = "http://www.w3.org/1999/xlink", Nt = "http://www.w3.org/XML/1998/namespace";
402
+ function Re(s) {
403
+ return !Ct(s) && s != null;
404
+ }
405
+ function ee(s) {
406
+ return Array.isArray(s) ? s.map(ee).filter(Boolean).join(" ") : L(s) ? Symbol.iterator in s ? ee(Array.from(s)) : W(s).filter((e) => s[e]).join(" ") : Re(s) ? "" + s : "";
407
+ }
408
+ const Ut = {
409
+ animate: 0,
410
+ circle: 0,
411
+ clipPath: 0,
412
+ defs: 0,
413
+ desc: 0,
414
+ ellipse: 0,
415
+ feBlend: 0,
416
+ feColorMatrix: 0,
417
+ feComponentTransfer: 0,
418
+ feComposite: 0,
419
+ feConvolveMatrix: 0,
420
+ feDiffuseLighting: 0,
421
+ feDisplacementMap: 0,
422
+ feDistantLight: 0,
423
+ feFlood: 0,
424
+ feFuncA: 0,
425
+ feFuncB: 0,
426
+ feFuncG: 0,
427
+ feFuncR: 0,
428
+ feGaussianBlur: 0,
429
+ feImage: 0,
430
+ feMerge: 0,
431
+ feMergeNode: 0,
432
+ feMorphology: 0,
433
+ feOffset: 0,
434
+ fePointLight: 0,
435
+ feSpecularLighting: 0,
436
+ feSpotLight: 0,
437
+ feTile: 0,
438
+ feTurbulence: 0,
439
+ filter: 0,
440
+ foreignObject: 0,
441
+ g: 0,
442
+ image: 0,
443
+ line: 0,
444
+ linearGradient: 0,
445
+ marker: 0,
446
+ mask: 0,
447
+ metadata: 0,
448
+ path: 0,
449
+ pattern: 0,
450
+ polygon: 0,
451
+ polyline: 0,
452
+ radialGradient: 0,
453
+ rect: 0,
454
+ stop: 0,
455
+ svg: 0,
456
+ switch: 0,
457
+ symbol: 0,
458
+ text: 0,
459
+ textPath: 0,
460
+ tspan: 0,
461
+ use: 0,
462
+ view: 0
463
+ }, jt = /^(a(ll|t|u)|base[FP]|c(al|lipPathU|on)|di|ed|ex|filter[RU]|g(lyphR|r)|ke|l(en|im)|ma(rker[HUW]|s)|n|pat|pr|point[^e]|re[^n]|s[puy]|st[^or]|ta|textL|vi|xC|y|z)/;
464
+ function Ft(s) {
465
+ const e = document.createDocumentFragment();
466
+ return q(s.children, e), e;
467
+ }
468
+ function zt(s, e, t) {
469
+ e = {
470
+ ...e,
471
+ children: t
472
+ };
473
+ const i = new s(e), n = i.render();
474
+ return "ref" in e && re(e.ref, i), n;
475
+ }
476
+ function m(s, e) {
477
+ let { children: t, ...i } = e;
478
+ !i.namespaceURI && Ut[s] === 0 && (i = {
479
+ ...i,
480
+ namespaceURI: Bt
481
+ });
482
+ let n;
483
+ if (ne(s)) {
484
+ if (n = i.namespaceURI ? document.createElementNS(i.namespaceURI, s) : document.createElement(s), Wt(i, n), q(t, n), n instanceof window.HTMLSelectElement && i.value != null)
485
+ if (i.multiple === !0 && Array.isArray(i.value)) {
486
+ const r = i.value.map((o) => String(o));
487
+ n.querySelectorAll("option").forEach(
488
+ (o) => o.selected = r.includes(o.value)
489
+ );
490
+ } else
491
+ n.value = i.value;
492
+ re(i.ref, n);
493
+ } else if (R(s))
494
+ L(s.defaultProps) && (i = {
495
+ ...s.defaultProps,
496
+ ...i
497
+ }), n = Lt(s) ? zt(s, i, t) : s({
498
+ ...i,
499
+ children: t
500
+ });
501
+ else
502
+ throw new TypeError(`Invalid JSX element type: ${s}`);
503
+ return n;
504
+ }
505
+ function re(s, e) {
506
+ At(s) ? s.current = e : R(s) && s(e);
507
+ }
508
+ function q(s, e) {
509
+ if (Pt(s))
510
+ Kt(s, e);
511
+ else if (ne(s) || De(s))
512
+ Y(document.createTextNode(s), e);
513
+ else if (s === null)
514
+ Y(document.createComment(""), e);
515
+ else if (It(s))
516
+ Y(s, e);
517
+ else if (Mt(s)) {
518
+ const t = e.attachShadow(s.attr);
519
+ q(s.children, t), re(s.ref, t);
520
+ }
521
+ }
522
+ function Kt(s, e) {
523
+ for (const t of [...s])
524
+ q(t, e);
525
+ return e;
526
+ }
527
+ function Y(s, e) {
528
+ e instanceof window.HTMLTemplateElement ? e.content.appendChild(s) : e.appendChild(s);
529
+ }
530
+ function O(s, e) {
531
+ return s.replace(/[A-Z]/g, (t) => e + t.toLowerCase());
532
+ }
533
+ function Me(s, e) {
534
+ e == null || e === !1 || (Array.isArray(e) ? e.forEach((t) => Me(s, t)) : ne(e) ? s.setAttribute("style", e) : L(e) && J(e, (t, i) => {
535
+ i.indexOf("-") === 0 ? s.style.setProperty(i, t) : De(t) && Q[i] !== 0 ? s.style[i] = t + "px" : s.style[i] = t;
536
+ }));
537
+ }
538
+ function Ht(s, e, t) {
539
+ switch (s) {
540
+ case "xlinkActuate":
541
+ case "xlinkArcrole":
542
+ case "xlinkHref":
543
+ case "xlinkRole":
544
+ case "xlinkShow":
545
+ case "xlinkTitle":
546
+ case "xlinkType":
547
+ be(t, Ot, O(s, ":"), e);
548
+ return;
549
+ case "xmlnsXlink":
550
+ A(t, O(s, ":"), e);
551
+ return;
552
+ case "xmlBase":
553
+ case "xmlLang":
554
+ case "xmlSpace":
555
+ be(t, Nt, O(s, ":"), e);
556
+ return;
557
+ }
558
+ switch (s) {
559
+ case "htmlFor":
560
+ A(t, "for", e);
561
+ return;
562
+ case "dataset":
563
+ J(e, (i, n) => {
564
+ i != null && (t.dataset[n] = i);
565
+ });
566
+ return;
567
+ case "innerHTML":
568
+ case "innerText":
569
+ case "textContent":
570
+ Re(e) && (t[s] = e);
571
+ return;
572
+ case "dangerouslySetInnerHTML":
573
+ L(e) && (t.innerHTML = e.__html);
574
+ return;
575
+ case "value":
576
+ if (e == null || t instanceof window.HTMLSelectElement)
577
+ return;
578
+ if (t instanceof window.HTMLTextAreaElement) {
579
+ t.value = e;
580
+ return;
581
+ }
582
+ break;
583
+ case "spellCheck":
584
+ t.spellcheck = e;
585
+ return;
586
+ case "class":
587
+ case "className":
588
+ R(e) ? e(t) : A(t, "class", ee(e));
589
+ return;
590
+ case "ref":
591
+ case "namespaceURI":
592
+ return;
593
+ case "style":
594
+ Me(t, e);
595
+ return;
596
+ case "on":
597
+ case "onCapture":
598
+ J(e, (i, n) => {
599
+ t.addEventListener(n, i, s === "onCapture");
600
+ });
601
+ return;
602
+ }
603
+ if (R(e)) {
604
+ if (s[0] === "o" && s[1] === "n") {
605
+ let i = s.toLowerCase();
606
+ const n = i.endsWith("capture");
607
+ if (i === "ondoubleclick" ? i = "ondblclick" : n && i === "ondoubleclickcapture" && (i = "ondblclickcapture"), !n && t[i] === null)
608
+ t[i] = e;
609
+ else if (n)
610
+ t.addEventListener(
611
+ i.substring(2, i.length - 7),
612
+ e,
613
+ !0
614
+ );
615
+ else {
616
+ let r;
617
+ i in window ? r = i.substring(2) : r = i[2] + s.slice(3), t.addEventListener(r, e);
618
+ }
619
+ }
620
+ } else L(e) ? t[s] = e : e === !0 ? A(t, s, "") : e !== !1 && e != null && (t instanceof SVGElement && !jt.test(s) ? A(t, O(s, "-"), e) : A(t, s, e));
621
+ }
622
+ function A(s, e, t) {
623
+ s.setAttribute(e, t);
624
+ }
625
+ function be(s, e, t, i) {
626
+ s.setAttributeNS(e, t, i);
627
+ }
628
+ function Wt(s, e) {
629
+ for (const t of W(s))
630
+ Ht(t, s[t], e);
631
+ return e;
632
+ }
633
+ var oe = /* @__PURE__ */ ((s) => (s.Init = "modal.init", s.BeforeShow = "modal.beforeShow", s.Show = "modal.show", s.BeforeClose = "modal.beforeClose", s.Close = "modal.close", s.Destroy = "modal.destroy", s.ToastShow = "toast.show", s.ToastClose = "toast.close", s))(oe || {});
634
+ let qt = 0;
635
+ const ve = (s) => `${s}-${++qt}`;
636
+ function D(s) {
637
+ return s instanceof Node ? s : document.createTextNode(String(s));
638
+ }
639
+ function x(s, e) {
640
+ if (!s) throw new Error(`${e ?? "Element"} not found`);
641
+ return s;
642
+ }
643
+ function _e(s) {
644
+ const e = [
645
+ "a[href]",
646
+ "button:not([disabled])",
647
+ "input:not([disabled])",
648
+ "select:not([disabled])",
649
+ "textarea:not([disabled])",
650
+ '[tabindex]:not([tabindex="-1"])'
651
+ ].join(",");
652
+ return Array.from(s.querySelectorAll(e)).filter(
653
+ (t) => !!(t.offsetWidth || t.offsetHeight || t.getClientRects().length)
654
+ );
655
+ }
656
+ function v(s, e = {}) {
657
+ const t = document.createElement(s);
658
+ if (e.className && (t.className = e.className), e.html != null && (t.innerHTML = e.html), e.text != null && (t.textContent = e.text), e.attrs)
659
+ for (const [i, n] of Object.entries(e.attrs)) t.setAttribute(i, n);
660
+ return t;
661
+ }
662
+ const Gt = typeof navigator < "u" && /Mac|iPhone|iPad|iPod/i.test(navigator.platform), Be = ["ctrl", "alt", "shift", "meta"];
663
+ function Xt(s) {
664
+ if (!s) return null;
665
+ const e = String(s).trim().toLowerCase().split(/[+\-\s]+/g).filter(Boolean), t = [];
666
+ let i = null;
667
+ const n = (o) => {
668
+ t.includes(o) || t.push(o);
669
+ };
670
+ for (const o of e) {
671
+ let a = o;
672
+ if (a === "control" || a === "ctrl") {
673
+ n("ctrl");
674
+ continue;
675
+ }
676
+ if (a === "alt" || a === "option") {
677
+ n("alt");
678
+ continue;
679
+ }
680
+ if (a === "shift") {
681
+ n("shift");
682
+ continue;
683
+ }
684
+ if (a === "meta" || a === "cmd" || a === "command" || a === "super") {
685
+ n("meta");
686
+ continue;
687
+ }
688
+ if (a === "mod") {
689
+ n(Gt ? "meta" : "ctrl");
690
+ continue;
691
+ }
692
+ a === "esc" && (a = "escape"), a === "return" && (a = "enter"), (a === "space" || a === "spacebar") && (a = "space"), i = a;
693
+ }
694
+ const r = Be.filter((o) => t.includes(o));
695
+ return !i || i === "" ? r.length ? r.join("+") : null : r.length ? `${r.join("+")}+${i}` : i;
696
+ }
697
+ function Yt(s) {
698
+ const e = [];
699
+ s.ctrlKey && e.push("ctrl"), s.altKey && e.push("alt"), s.shiftKey && e.push("shift"), s.metaKey && e.push("meta");
700
+ let t = s.key;
701
+ t === " " && (t = "space");
702
+ const i = (t.length, t.toLowerCase()), n = Be.filter((r) => e.includes(r));
703
+ return n.length ? `${n.join("+")}+${i}` : i;
704
+ }
705
+ class Vt {
706
+ constructor() {
707
+ this.zBase = 1e3, this.stack = [];
708
+ }
709
+ push(e) {
710
+ this.stack.push(e), this.syncZ();
711
+ }
712
+ remove(e) {
713
+ this.stack = this.stack.filter((t) => t !== e), this.syncZ();
714
+ }
715
+ top() {
716
+ return this.stack[this.stack.length - 1];
717
+ }
718
+ closeAll(e, t) {
719
+ const i = new Set((Array.isArray(t) ? t : t ? [t] : []).map(String)), n = new Set((Array.isArray(e) ? e : e ? [e] : []).map(String));
720
+ [...this.stack].reverse().forEach((r) => {
721
+ const o = r.modalId, a = n.size ? n.has(r.pluginName) : !0, c = i.has(o);
722
+ a && !c && r.close();
723
+ });
724
+ }
725
+ removeAll() {
726
+ [...this.stack].forEach((e) => e.destroy()), this.stack = [];
727
+ }
728
+ syncZ() {
729
+ this.stack.forEach((e, t) => e.setZIndex(this.zBase + t * 2));
730
+ }
731
+ lockBodyScroll() {
732
+ document.body.classList.add("ipe-modal-no-scroll");
733
+ }
734
+ unlockBodyScroll() {
735
+ document.body.classList.remove("ipe-modal-no-scroll");
736
+ }
737
+ }
738
+ const _ = new Vt();
739
+ class U {
740
+ constructor(e = {}) {
741
+ this.backdropId = ve("ipe-modal-backdrop"), this.modalId = ve("ipe-modal"), this.numberId = this.modalId.split("-")[1], this._isDestroyed = !1, this.pluginName = "normalModal", this.buttonElsLeft = [], this.buttonElsRight = [], this.keyMap = /* @__PURE__ */ new Map(), this.isOpen = !1, this.isToast = !1, this.isDragging = !1, this.dragStartX = 0, this.dragStartY = 0, this.modalStartX = 0, this.modalStartY = 0, this.Event = oe, this._hooks = [], this.startCloseTimer = (t) => {
742
+ this.stopCloseTimer(), this.closeTimer = window.setTimeout(() => this.close(), t);
743
+ }, this.stopCloseTimer = () => {
744
+ this.closeTimer && window.clearTimeout(this.closeTimer), this.closeTimer = void 0;
745
+ }, this.onDragMove = (t) => {
746
+ if (!this.isDragging) return;
747
+ t.preventDefault();
748
+ const i = t.clientX - this.dragStartX, n = t.clientY - this.dragStartY, r = this.get$modal(), o = this.modalStartX + i, a = this.modalStartY + n;
749
+ r.style.left = `${o}px`, r.style.top = `${a}px`;
750
+ }, this.onDragEnd = () => {
751
+ if (!this.isDragging) return;
752
+ this.isDragging = !1, document.removeEventListener("pointermove", this.onDragMove), document.removeEventListener("pointerup", this.onDragEnd);
753
+ const t = this.get$modal(), i = this.get$window();
754
+ t.classList.remove("is-dragging"), i.style.animation = "none", requestAnimationFrame(() => {
755
+ this.applyAnimation(!0);
756
+ });
757
+ }, this.options = { ...U.DEFAULT_OPTIONS, ...e }, this.options.backdrop === !1 && e.bodyScroll === void 0 && (this.options.bodyScroll = !0);
758
+ }
759
+ get isDestroyed() {
760
+ return this._isDestroyed;
761
+ }
762
+ static {
763
+ this.DEFAULT_OPTIONS = {
764
+ className: "",
765
+ sizeClass: "auto",
766
+ center: !0,
767
+ fitScreen: !1,
768
+ closeIcon: !0,
769
+ bodyScroll: !1,
770
+ outSideClose: !0,
771
+ backdrop: !0,
772
+ animation: {
773
+ show: "ipe-modal-fade-in",
774
+ hide: "ipe-modal-fade-out"
775
+ },
776
+ animationSpeed: 200
777
+ };
778
+ }
779
+ static extends(e = {}) {
780
+ return class extends this {
781
+ constructor(t = {}) {
782
+ super({ ...e, ...t });
783
+ }
784
+ };
785
+ }
786
+ // ------------------------------ lifecycle ------------------------------ //
787
+ init() {
788
+ if (this.$modal) return this;
789
+ const e = this.options.backdrop !== !1;
790
+ let t;
791
+ e && (t = v("div", {
792
+ className: "ipe-modal-backdrop",
793
+ attrs: { id: this.backdropId, "data-modal-id": this.modalId }
794
+ }));
795
+ const i = v("div", {
796
+ className: "ipe-modal-modal",
797
+ attrs: { id: this.modalId, role: "dialog", "aria-modal": "true", tabindex: "-1" }
798
+ });
799
+ if (i.modal = this, !e) {
800
+ i.classList.add("no-backdrop");
801
+ const u = window.pageYOffset || document.documentElement.scrollTop, g = window.pageXOffset || document.documentElement.scrollLeft, b = window.innerWidth;
802
+ i.style.top = `${u + 60}px`, this.once("modal.show", () => {
803
+ i.style.left = `${g + b / 2 - i.offsetWidth / 2}px`;
804
+ });
805
+ }
806
+ const n = v("div", {
807
+ className: `ipe-modal-modal__window size--${this.options.sizeClass || "auto"} plugin--${this.pluginName}`
808
+ });
809
+ n.modal = this;
810
+ const r = v("div", { className: "ipe-modal-modal__header" }), o = `${this.modalId}-title`, a = v("h2", {
811
+ className: "ipe-modal-modal__title",
812
+ attrs: { id: o, role: "heading", "aria-level": "2" }
813
+ });
814
+ i.setAttribute("aria-labelledby", o);
815
+ const c = v("div", { className: "ipe-modal-modal__icons" });
816
+ if (this.options.closeIcon) {
817
+ const u = v("button", {
818
+ className: "ipe-modal-modal__close",
819
+ attrs: { type: "button", "aria-label": "Close" },
820
+ html: "&times;"
821
+ });
822
+ u.addEventListener("click", () => {
823
+ let g = !0;
824
+ typeof this.options.onClickClose == "function" ? this.options.onClickClose(this) === !1 && (g = !1) : this.options.onClickClose === !1 && (g = !1), g && this.close();
825
+ }), c.appendChild(u);
826
+ }
827
+ r.append(a, c), this.options.draggable && e && (this.options.draggable = !1), this.options.draggable && (r.style.cursor = "move", r.style.userSelect = "none", r.addEventListener("pointerdown", this.onDragStart.bind(this)), i.classList.add("is-draggable"));
828
+ const l = v("div", { className: "ipe-modal-modal__content" }), h = v("div", { className: "ipe-modal-modal__footer" }), d = v("div", {
829
+ className: "ipe-modal-modal__buttons ipe-modal-modal__buttons--left"
830
+ }), f = v("div", {
831
+ className: "ipe-modal-modal__buttons ipe-modal-modal__buttons--right"
832
+ });
833
+ return h.append(d, f), n.append(r, l, h), i.appendChild(n), this.$backdrop = t, this.$modal = i, this.$window = n, this.$header = r, this.$title = a, this.$icons = c, this.$content = l, this.$footer = h, this.$buttonsLeft = d, this.$buttonsRight = f, this.options.title && this.setTitle(this.options.title), this.options.content && this.setContent(this.options.content), this.options.buttons?.length ? this.setButtons(this.options.buttons) : h.style.display = "none", this.options.center && this.$modal.classList.add("is-centered"), this.options.fitScreen && this.$modal.classList.add("is-fullscreen"), this.options.iconButtons && this.$header.classList.add("has-icon-buttons"), this.options.className && this.$window.classList.add(...this.options.className.split(/[\s\.#+]+/g).filter(Boolean)), typeof this.options.fixedHeight == "number" ? this.$window.style.height = `${Math.max(0, this.options.fixedHeight)}px` : this.options.fixedHeight === !0 && this.$window.classList.add("is-fixed-height"), t && t.addEventListener("pointerdown", (u) => {
834
+ this.options.outSideClose && u.target === t && this.close();
835
+ }), this.options.draggable && n.addEventListener("pointerdown", (u) => {
836
+ u.target && n.contains(u.target) && this.bringToFront();
837
+ }), this.onKeyDown = this.onKeyDown.bind(this), this.emit(
838
+ "modal.init"
839
+ /* Init */
840
+ ), this;
841
+ }
842
+ show() {
843
+ if (this.$modal || this.init(), !this.$modal) throw new Error("Failed to initialize modal");
844
+ if (this.isOpen) return this;
845
+ {
846
+ const i = this.emit("modal.beforeShow", !0), n = this.options.beforeShow ? this.options.beforeShow(this) !== !1 : !0;
847
+ if (!i || !n) return this;
848
+ }
849
+ this.lastFocused = document.activeElement ?? null, this.$backdrop && document.body.appendChild(this.$backdrop), document.body.appendChild(this.$modal), this.shouldLockBodyOnOpen() && _.lockBodyScroll(), requestAnimationFrame(() => {
850
+ this.$backdrop?.classList.add("is-open"), this.$modal.classList.add("is-open"), this.applyAnimation(!0), this.focusFirst();
851
+ }), document.addEventListener("keydown", this.onKeyDown), _.push(this), this.isOpen = !0, this.options.onShow?.(this), this.emit(
852
+ "modal.show"
853
+ /* Show */
854
+ );
855
+ const e = typeof this.options.closeAfter == "number" ? this.options.closeAfter : this.options.closeAfter?.time, t = typeof this.options.closeAfter == "number" ? !0 : this.options.closeAfter?.resetOnHover;
856
+ return e && (this.startCloseTimer(e), t && (this.$window?.addEventListener("mouseenter", this.stopCloseTimer), this.$window?.addEventListener("mouseleave", () => this.startCloseTimer(e)))), this;
857
+ }
858
+ close() {
859
+ if (!this.isOpen) return this;
860
+ {
861
+ const r = this.emit("modal.beforeClose", !0), o = this.options.beforeClose ? this.options.beforeClose(this) !== !1 : !0;
862
+ if (!r || !o) return this;
863
+ }
864
+ if (this.isToast) {
865
+ this.applyAnimation(!1), this.emit(
866
+ "modal.close"
867
+ /* Close */
868
+ ), this.emit(
869
+ "toast.close"
870
+ /* ToastClose */
871
+ );
872
+ const r = this.isAnimationDisabled() ? 0 : this.options.animationSpeed ?? 200;
873
+ let o = !1;
874
+ const a = () => {
875
+ o || (o = !0, this.destroy(), this.options.onClose?.(this));
876
+ }, c = (l, h) => {
877
+ const d = () => {
878
+ l.removeEventListener(h, d), a();
879
+ };
880
+ l.addEventListener(h, d, { once: !0 });
881
+ };
882
+ return r > 0 && this.$window ? (c(this.$window, "transitionend"), c(this.$window, "animationend"), window.setTimeout(a, r + 20)) : window.setTimeout(a, r), this;
883
+ }
884
+ this.applyAnimation(!1), this.$backdrop?.classList.remove("is-open"), this.$modal?.classList.remove("is-open"), this.emit(
885
+ "modal.close"
886
+ /* Close */
887
+ );
888
+ const e = this.isAnimationDisabled() ? 0 : this.options.animationSpeed ?? 200;
889
+ let t = !1;
890
+ const i = () => {
891
+ t || (t = !0, this.destroy(), this.options.onClose?.(this));
892
+ }, n = (r, o) => {
893
+ const a = () => {
894
+ r.removeEventListener(o, a), i();
895
+ };
896
+ r.addEventListener(o, a, { once: !0 });
897
+ };
898
+ return e > 0 && this.$window ? (n(this.$window, "transitionend"), n(this.$window, "animationend"), window.setTimeout(i, e + 20)) : window.setTimeout(i, e), this;
899
+ }
900
+ /** Immediately removes DOM and listeners */
901
+ destroy() {
902
+ if (this._isDestroyed) return this;
903
+ if (this.stopCloseTimer(), document.removeEventListener("keydown", this.onKeyDown), this.isDragging && this.onDragEnd(), this.$window?.removeEventListener("mouseenter", this.stopCloseTimer), this.isToast) {
904
+ this.$window?.parentElement && this.$window.parentElement.removeChild(this.$window);
905
+ const e = I.indexOf(this);
906
+ e !== -1 && I.splice(e, 1);
907
+ } else
908
+ this.$backdrop?.parentElement && this.$backdrop.parentElement.removeChild(this.$backdrop), this.$modal?.parentElement && this.$modal.parentElement.removeChild(this.$modal), _.remove(this), this.shouldUnlockBodyOnClose() && _.unlockBodyScroll();
909
+ return this.isOpen = !1, this.lastFocused?.focus?.(), this.emit(
910
+ "modal.destroy"
911
+ /* Destroy */
912
+ ), this._isDestroyed = !0, this;
913
+ }
914
+ // ------------------------------ getters ------------------------------- //
915
+ get$backdrop() {
916
+ return this.$backdrop;
917
+ }
918
+ get$modal() {
919
+ return x(this.$modal, "modal");
920
+ }
921
+ get$window() {
922
+ return x(this.$window, "window");
923
+ }
924
+ get$header() {
925
+ return x(this.$header, "header");
926
+ }
927
+ get$title() {
928
+ return x(this.$title, "title");
929
+ }
930
+ get$content() {
931
+ return x(this.$content, "content");
932
+ }
933
+ get$icons() {
934
+ return x(this.$icons, "icons");
935
+ }
936
+ get$buttons(e) {
937
+ return e === "leftButtons" ? x(this.$buttonsLeft, "leftButtons") : e === "rightButtons" ? x(this.$buttonsRight, "rightButtons") : x(this.$footer, "buttons");
938
+ }
939
+ // ------------------------------ content ------------------------------- //
940
+ setTitle(e) {
941
+ const t = this.get$title();
942
+ return t.innerHTML = "", t.append(D(e)), this;
943
+ }
944
+ setContent(e, t = "replace") {
945
+ const i = this.get$content();
946
+ return t === "replace" ? (i.innerHTML = "", i.append(D(e))) : t === "append" ? i.append(D(e)) : i.prepend(D(e)), this;
947
+ }
948
+ setIcons(e) {
949
+ const t = this.get$icons();
950
+ t.innerHTML = "";
951
+ for (const i of e) {
952
+ const n = v("button", {
953
+ className: `ipe-modal-modal__icon ${i.className}`,
954
+ attrs: { type: "button" }
955
+ });
956
+ n.addEventListener("click", i.method), t.appendChild(n);
957
+ }
958
+ return this;
959
+ }
960
+ setButtons(e, t) {
961
+ const i = this.$buttonsLeft, n = this.$buttonsRight;
962
+ [i, n].forEach((o) => o.innerHTML = ""), this.buttonElsLeft = [], this.buttonElsRight = [], this.keyMap.clear();
963
+ const r = t ?? this.$footer;
964
+ if (r === this.$footer)
965
+ e.forEach((o) => this.addButton(o)), e.length === 0 && (this.$footer.style.display = "none");
966
+ else {
967
+ r.innerHTML = "";
968
+ for (const o of e) {
969
+ const a = this.generateButton(o);
970
+ r.appendChild(a);
971
+ }
972
+ }
973
+ return this;
974
+ }
975
+ generateButton(e) {
976
+ const t = e.type ?? "button", i = t === "link" ? v("a") : v("button", { attrs: { type: "button" } });
977
+ e.id && (i.id = e.id), i.className = `ipe-modal-btn ${e.className ?? ""}`.trim();
978
+ const n = D(e.label ?? "OK");
979
+ if (i.append(n), t === "link" && e.href && (i.href = e.href), e.method && i.addEventListener("click", (r) => {
980
+ if (i._ipe_tmpDisabled) {
981
+ r.preventDefault(), r.stopPropagation();
982
+ return;
983
+ }
984
+ e.method.call(i, r, this);
985
+ }), typeof e.closeAfter == "number" && e.closeAfter >= 0 && i.addEventListener("click", () => {
986
+ window.setTimeout(() => this.close(), e.closeAfter);
987
+ }), typeof e.enableAfter == "number" && e.enableAfter > 0) {
988
+ t === "button" && i.setAttribute("disabled", "true"), i._ipe_tmpDisabled = !0, i.setAttribute("aria-disabled", "true");
989
+ const r = () => {
990
+ t === "button" && i.removeAttribute("disabled"), delete i._ipe_tmpDisabled, i.removeAttribute("aria-disabled");
991
+ };
992
+ window.setTimeout(r, e.enableAfter);
993
+ }
994
+ if (e.keyPress) {
995
+ const r = String(e.keyPress).split(/[\,\|]+/g).map((o) => o.trim()).filter(Boolean);
996
+ for (const o of r) {
997
+ const a = Xt(o);
998
+ a && this.keyMap.set(a, i);
999
+ }
1000
+ }
1001
+ return i;
1002
+ }
1003
+ /** Dynamically add button(s) into footer. Supports insertion index per side. */
1004
+ addButton(e, t) {
1005
+ this.$footer && (this.$footer.style.display = "");
1006
+ const i = e.side ?? "right", n = i === "left" ? this.$buttonsLeft : this.$buttonsRight, r = i === "left" ? this.buttonElsLeft : this.buttonElsRight, o = this.generateButton(e), a = Math.max(0, Math.min(t ?? r.length, r.length));
1007
+ return a >= n.children.length ? n.appendChild(o) : n.insertBefore(o, n.children[a]), r.splice(a, 0, o), this;
1008
+ }
1009
+ /** Remove button by element / id / global index (left first, then right). */
1010
+ removeButton(e) {
1011
+ const t = this.buttonElsLeft, i = this.buttonElsRight, n = [...t, ...i];
1012
+ let r = null;
1013
+ if (e === "*")
1014
+ return n.forEach((a) => {
1015
+ this.keyMap.delete(a.id), a.parentElement?.removeChild(a);
1016
+ }), this.$footer && (this.$footer.style.display = "none"), this;
1017
+ if (typeof e == "number" ? r = n[e] ?? null : typeof e == "string" ? r = n.find((a) => a.id === e) ?? null : e instanceof HTMLElement && (r = n.find((a) => a === e) ?? null), !r) return this;
1018
+ for (const [a, c] of this.keyMap.entries()) c === r && this.keyMap.delete(a);
1019
+ let o = t.indexOf(r);
1020
+ return o !== -1 ? (t.splice(o, 1), r.parentElement?.removeChild(r)) : (o = i.indexOf(r), o !== -1 && (i.splice(o, 1), r.parentElement?.removeChild(r))), t.length === 0 && i.length === 0 && this.$footer && (this.$footer.style.display = "none"), this;
1021
+ }
1022
+ changePreviewState() {
1023
+ return this.get$modal().classList.toggle("is-fullscreen"), this;
1024
+ }
1025
+ setModalHeight(e, t = "height") {
1026
+ const i = this.get$window(), n = Math.max(0, window.innerHeight - e);
1027
+ return i.style[t] = `${n}px`, n;
1028
+ }
1029
+ setOptions(e, t) {
1030
+ return typeof e == "string" ? this.options[e] = t : Object.assign(this.options, e), this;
1031
+ }
1032
+ setPluginName(e) {
1033
+ return this.$window && (this.$window.className = this.$window.className.replace(
1034
+ `plugin--${this.pluginName}`,
1035
+ `plugin--${e}`
1036
+ )), this.pluginName = e, this;
1037
+ }
1038
+ // ------------------------------ helpers ------------------------------- //
1039
+ applyAnimation(e) {
1040
+ const t = this.get$modal(), i = this.get$window(), n = this.$backdrop, r = this.options.modalAnimation ?? this.options.animation, o = typeof r == "string" ? r : r && (e ? r.show : r.hide), a = this.options.backdropAnimation ?? this.options.animation, c = typeof a == "string" ? a : a && (e ? a.show : a.hide);
1041
+ !o || o === !1 ? (t.style.transition = "none", i.style.animation = "none", i.style.removeProperty("--ipe-modal-anim")) : (t.style.removeProperty("transition"), i.style.setProperty("--ipe-modal-anim", o)), n && (!c || c === !1 ? n.style.transition = "none" : n.style.removeProperty("transition"));
1042
+ }
1043
+ on(e, t) {
1044
+ return this._hooks.push({ type: e, listener: t }), () => this.off(e, t);
1045
+ }
1046
+ off(e, t) {
1047
+ return this._hooks = this._hooks.filter(
1048
+ (i) => i.type !== e && (t ? i.listener !== t : !0)
1049
+ ), this;
1050
+ }
1051
+ once(e, t) {
1052
+ const i = this.on(e, (n) => (i(), t(n)));
1053
+ return i;
1054
+ }
1055
+ emit(e, t) {
1056
+ const i = this._hooks.filter((a) => a.type === e);
1057
+ let n = !0;
1058
+ for (const a of i) {
1059
+ const c = new CustomEvent(e, { detail: this, cancelable: t }), l = a.listener(c);
1060
+ if (c.defaultPrevented && (n = !1), l === !1 && (n = !1), !n) break;
1061
+ }
1062
+ const r = this.$modal ?? document.body, o = new CustomEvent(e, { detail: this, cancelable: t });
1063
+ return (!r.dispatchEvent(o) || o.defaultPrevented) && (n = !1), n;
1064
+ }
1065
+ focusFirst() {
1066
+ const e = this.get$modal(), t = _e(e);
1067
+ t.length ? t[0].focus() : e.focus({ preventScroll: !0 });
1068
+ }
1069
+ onKeyDown(e) {
1070
+ if (_.top() !== this) return;
1071
+ if (e.key === "Escape") {
1072
+ e.preventDefault(), this.close();
1073
+ return;
1074
+ }
1075
+ const t = this.get$modal();
1076
+ if (!t.contains(document.activeElement)) return;
1077
+ if (e.key === "Tab") {
1078
+ const a = _e(t);
1079
+ if (!a.length) return;
1080
+ const c = a[0], l = a[a.length - 1], h = document.activeElement;
1081
+ e.shiftKey && h === c ? (e.preventDefault(), l.focus()) : !e.shiftKey && h === l && (e.preventDefault(), c.focus());
1082
+ }
1083
+ const i = e.ctrlKey || e.altKey || e.metaKey, n = e.target;
1084
+ if (!i && (n && ["INPUT", "TEXTAREA"].includes(n.tagName) || n.contentEditable === "true"))
1085
+ return;
1086
+ const r = Yt(e), o = this.keyMap.get(r);
1087
+ if (o) {
1088
+ e.preventDefault(), o.click();
1089
+ return;
1090
+ }
1091
+ }
1092
+ setZIndex(e) {
1093
+ this.$backdrop && (this.$backdrop.style.zIndex = String(e)), this.$modal && (this.$modal.style.zIndex = String(e + 1));
1094
+ }
1095
+ /** Bring this modal to the top of the stack. */
1096
+ bringToFront() {
1097
+ return _.remove(this), _.push(this), this;
1098
+ }
1099
+ isAnimationDisabled() {
1100
+ const e = this.options.modalAnimation ?? this.options.animation;
1101
+ return e === !1 || e == null;
1102
+ }
1103
+ shouldLockBodyOnOpen() {
1104
+ return this.options.backdrop === !1 || this.options.bodyScroll !== !1 ? !1 : !_.stack.some(
1105
+ (e) => e !== this && e.options.backdrop !== !1 && e.options.bodyScroll === !1
1106
+ );
1107
+ }
1108
+ shouldUnlockBodyOnClose() {
1109
+ return this.options.backdrop === !1 || this.options.bodyScroll !== !1 ? !1 : !_.stack.some(
1110
+ (e) => e !== this && e.options.backdrop !== !1 && e.options.bodyScroll === !1
1111
+ );
1112
+ }
1113
+ // ------------------------------ drag handlers ------------------------------- //
1114
+ onDragStart(e) {
1115
+ if (this.options.backdrop !== !1 || !this.options.draggable) return;
1116
+ e.preventDefault(), this.isDragging = !0, this.bringToFront(), this.dragStartX = e.clientX, this.dragStartY = e.clientY;
1117
+ const t = this.get$modal(), i = t.getBoundingClientRect();
1118
+ this.modalStartX = i.left + window.pageXOffset, this.modalStartY = i.top + window.pageYOffset, t.style.transform = "none", t.style.left = `${this.modalStartX}px`, t.style.top = `${this.modalStartY}px`, document.addEventListener("pointermove", this.onDragMove), document.addEventListener("pointerup", this.onDragEnd), t.classList.add("is-dragging");
1119
+ }
1120
+ // ------------------------------ toast ------------------------------- //
1121
+ /** Show as toast (no backdrop, container stack). */
1122
+ showToast(e) {
1123
+ this.$window || this.init();
1124
+ const t = Zt(e.position ?? "top right"), i = this.get$window();
1125
+ this.isToast = !0, i.style.pointerEvents = "auto", this.applyAnimation(!0), t.appendChild(i);
1126
+ const n = (typeof this.options.closeAfter == "number" ? this.options.closeAfter : this.options.closeAfter?.time) ?? 3e3, r = (typeof this.options.closeAfter == "number" ? !0 : this.options.closeAfter?.resetOnHover) ?? !0;
1127
+ return n > 0 && (this.startCloseTimer(n), r && (i.addEventListener("mouseenter", this.stopCloseTimer), i.addEventListener("mouseleave", () => this.startCloseTimer(n)))), this.isOpen = !0, this.options.onShow?.(this), I.push(this), this.emit(
1128
+ "toast.show"
1129
+ /* ToastShow */
1130
+ ), this.emit(
1131
+ "modal.show"
1132
+ /* Show */
1133
+ ), this;
1134
+ }
1135
+ // ------------------------------ static helpers --------------------------- //
1136
+ static show(e, t) {
1137
+ return new this(e).init().show();
1138
+ }
1139
+ static createObject(e, t) {
1140
+ return new this(e);
1141
+ }
1142
+ static close(e) {
1143
+ if (!e) {
1144
+ const r = _.top();
1145
+ return r?.close(), r;
1146
+ }
1147
+ const t = typeof e == "string" ? e : e.id, i = _.stack.find((r) => r.modalId === t);
1148
+ if (i)
1149
+ return i.close(), i;
1150
+ const n = I.find((r) => r.modalId === t);
1151
+ return n?.close(), n;
1152
+ }
1153
+ static closeAll(e, t) {
1154
+ const i = new Set((Array.isArray(t) ? t : t ? [t] : []).map(String)), n = new Set((Array.isArray(e) ? e : e ? [e] : []).map(String));
1155
+ return _.closeAll(e, t), [...I].forEach((r) => {
1156
+ const o = r.modalId, a = n.size ? n.has(r.pluginName) : !0, c = i.has(o);
1157
+ a && !c && r.close();
1158
+ }), _.top() ?? new U();
1159
+ }
1160
+ static removeAll() {
1161
+ _.removeAll(), [...I].forEach((e) => e.destroy());
1162
+ }
1163
+ static dialog(e, t) {
1164
+ const i = new this({
1165
+ sizeClass: "dialog",
1166
+ buttons: [
1167
+ {
1168
+ label: "OK",
1169
+ className: "is-primary is-ghost",
1170
+ method: (n, r) => {
1171
+ t?.(n, r), n.defaultPrevented || i.close();
1172
+ },
1173
+ keyPress: "Enter"
1174
+ }
1175
+ ],
1176
+ ...e
1177
+ });
1178
+ return i.init().show();
1179
+ }
1180
+ static confirm(e, t) {
1181
+ e.title ??= "Confirm", e.content ??= "Are you sure you want to perform this action?";
1182
+ const i = e.okBtn ?? { label: "OK", className: "is-primary is-ghost" }, n = e.cancelBtn ?? { label: "Cancel", className: "is-danger is-ghost" };
1183
+ return new this({
1184
+ sizeClass: "dialog",
1185
+ ...e,
1186
+ buttons: [
1187
+ {
1188
+ label: n.label,
1189
+ className: n.className,
1190
+ keyPress: "n",
1191
+ method: (r, o) => {
1192
+ t?.(!1, o, r), o.close();
1193
+ }
1194
+ },
1195
+ {
1196
+ label: i.label,
1197
+ className: i.className,
1198
+ keyPress: "y",
1199
+ method: (r, o) => {
1200
+ t?.(!0, o, r), r.defaultPrevented || o.close();
1201
+ }
1202
+ }
1203
+ ]
1204
+ }).init().show();
1205
+ }
1206
+ static getDefaultNotifyIcon(e) {
1207
+ switch (e) {
1208
+ case "success":
1209
+ return /* @__PURE__ */ m(
1210
+ "svg",
1211
+ {
1212
+ xmlns: "http://www.w3.org/2000/svg",
1213
+ width: "24",
1214
+ height: "24",
1215
+ viewBox: "0 0 24 24",
1216
+ fill: "currentColor",
1217
+ class: "icon icon-tabler icons-tabler-filled icon-tabler-circle-check",
1218
+ children: [
1219
+ /* @__PURE__ */ m("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
1220
+ /* @__PURE__ */ m("path", { d: "M17 3.34a10 10 0 1 1 -14.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 14.995 -8.336zm-1.293 5.953a1 1 0 0 0 -1.32 -.083l-.094 .083l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.403 1.403l.083 .094l2 2l.094 .083a1 1 0 0 0 1.226 0l.094 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z" })
1221
+ ]
1222
+ }
1223
+ );
1224
+ case "error":
1225
+ return /* @__PURE__ */ m(
1226
+ "svg",
1227
+ {
1228
+ xmlns: "http://www.w3.org/2000/svg",
1229
+ width: "24",
1230
+ height: "24",
1231
+ viewBox: "0 0 24 24",
1232
+ fill: "currentColor",
1233
+ class: "icon icon-tabler icons-tabler-filled icon-tabler-alert-triangle",
1234
+ children: [
1235
+ /* @__PURE__ */ m("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
1236
+ /* @__PURE__ */ m("path", { d: "M12 1.67c.955 0 1.845 .467 2.39 1.247l.105 .16l8.114 13.548a2.914 2.914 0 0 1 -2.307 4.363l-.195 .008h-16.225a2.914 2.914 0 0 1 -2.582 -4.2l.099 -.185l8.11 -13.538a2.914 2.914 0 0 1 2.491 -1.403zm.01 13.33l-.127 .007a1 1 0 0 0 0 1.986l.117 .007l.127 -.007a1 1 0 0 0 0 -1.986l-.117 -.007zm-.01 -7a1 1 0 0 0 -.993 .883l-.007 .117v4l.007 .117a1 1 0 0 0 1.986 0l.007 -.117v-4l-.007 -.117a1 1 0 0 0 -.993 -.883z" })
1237
+ ]
1238
+ }
1239
+ );
1240
+ case "warning":
1241
+ return /* @__PURE__ */ m(
1242
+ "svg",
1243
+ {
1244
+ xmlns: "http://www.w3.org/2000/svg",
1245
+ width: "24",
1246
+ height: "24",
1247
+ viewBox: "0 0 24 24",
1248
+ fill: "currentColor",
1249
+ class: "icon icon-tabler icons-tabler-filled icon-tabler-alert-circle",
1250
+ children: [
1251
+ /* @__PURE__ */ m("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
1252
+ /* @__PURE__ */ m("path", { d: "M12 2c5.523 0 10 4.477 10 10a10 10 0 0 1 -19.995 .324l-.005 -.324l.004 -.28c.148 -5.393 4.566 -9.72 9.996 -9.72zm.01 13l-.127 .007a1 1 0 0 0 0 1.986l.117 .007l.127 -.007a1 1 0 0 0 0 -1.986l-.117 -.007zm-.01 -8a1 1 0 0 0 -.993 .883l-.007 .117v4l.007 .117a1 1 0 0 0 1.986 0l.007 -.117v-4l-.007 -.117a1 1 0 0 0 -.993 -.883z" })
1253
+ ]
1254
+ }
1255
+ );
1256
+ case "info":
1257
+ return /* @__PURE__ */ m(
1258
+ "svg",
1259
+ {
1260
+ xmlns: "http://www.w3.org/2000/svg",
1261
+ width: "24",
1262
+ height: "24",
1263
+ viewBox: "0 0 24 24",
1264
+ fill: "currentColor",
1265
+ class: "icon icon-tabler icons-tabler-filled icon-tabler-info-circle",
1266
+ children: [
1267
+ /* @__PURE__ */ m("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
1268
+ /* @__PURE__ */ m("path", { d: "M12 2c5.523 0 10 4.477 10 10a10 10 0 0 1 -19.995 .324l-.005 -.324l.004 -.28c.148 -5.393 4.566 -9.72 9.996 -9.72zm0 9h-1l-.117 .007a1 1 0 0 0 0 1.986l.117 .007v3l.007 .117a1 1 0 0 0 .876 .876l.117 .007h1l.117 -.007a1 1 0 0 0 .876 -.876l.007 -.117l-.007 -.117a1 1 0 0 0 -.764 -.857l-.112 -.02l-.117 -.006v-3l-.007 -.117a1 1 0 0 0 -.876 -.876l-.117 -.007zm.01 -3l-.127 .007a1 1 0 0 0 0 1.986l.117 .007l.127 -.007a1 1 0 0 0 0 -1.986l-.117 -.007z" })
1269
+ ]
1270
+ }
1271
+ );
1272
+ case "dialog":
1273
+ return /* @__PURE__ */ m(
1274
+ "svg",
1275
+ {
1276
+ xmlns: "http://www.w3.org/2000/svg",
1277
+ width: "24",
1278
+ height: "24",
1279
+ viewBox: "0 0 24 24",
1280
+ fill: "none",
1281
+ stroke: "currentColor",
1282
+ "stroke-width": "2",
1283
+ "stroke-linecap": "round",
1284
+ "stroke-linejoin": "round",
1285
+ class: "icon icon-tabler icons-tabler-outline icon-tabler-message-dots",
1286
+ children: [
1287
+ /* @__PURE__ */ m("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
1288
+ /* @__PURE__ */ m("path", { d: "M12 11v.01" }),
1289
+ /* @__PURE__ */ m("path", { d: "M8 11v.01" }),
1290
+ /* @__PURE__ */ m("path", { d: "M16 11v.01" }),
1291
+ /* @__PURE__ */ m("path", { d: "M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3z" })
1292
+ ]
1293
+ }
1294
+ );
1295
+ case "confirm":
1296
+ return /* @__PURE__ */ m(
1297
+ "svg",
1298
+ {
1299
+ xmlns: "http://www.w3.org/2000/svg",
1300
+ width: "24",
1301
+ height: "24",
1302
+ viewBox: "0 0 24 24",
1303
+ fill: "currentColor",
1304
+ class: "icon icon-tabler icons-tabler-filled icon-tabler-copy-check",
1305
+ children: [
1306
+ /* @__PURE__ */ m("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
1307
+ /* @__PURE__ */ m("path", { d: "M18.333 6a3.667 3.667 0 0 1 3.667 3.667v8.666a3.667 3.667 0 0 1 -3.667 3.667h-8.666a3.667 3.667 0 0 1 -3.667 -3.667v-8.666a3.667 3.667 0 0 1 3.667 -3.667zm-3.333 -4c1.094 0 1.828 .533 2.374 1.514a1 1 0 1 1 -1.748 .972c-.221 -.398 -.342 -.486 -.626 -.486h-10c-.548 0 -1 .452 -1 1v9.998c0 .32 .154 .618 .407 .805l.1 .065a1 1 0 1 1 -.99 1.738a3 3 0 0 1 -1.517 -2.606v-10c0 -1.652 1.348 -3 3 -3zm1.293 9.293l-3.293 3.292l-1.293 -1.292a1 1 0 0 0 -1.414 1.414l2 2a1 1 0 0 0 1.414 0l4 -4a1 1 0 0 0 -1.414 -1.414" })
1308
+ ]
1309
+ }
1310
+ );
1311
+ default:
1312
+ return null;
1313
+ }
1314
+ }
1315
+ static notify(e, t, i) {
1316
+ if (t?.overrideOther && [...I].forEach((a) => a.close()), typeof t.title > "u") {
1317
+ const a = e || "Notification";
1318
+ t.title = a[0].toUpperCase() + a.slice(1).toLowerCase();
1319
+ }
1320
+ const n = t.icon ?? this.getDefaultNotifyIcon(e);
1321
+ n && (n instanceof Element && n.classList.add("ipe-modal-notify-icon"), t.title = /* @__PURE__ */ m(Ft, { children: [
1322
+ n,
1323
+ t.title
1324
+ ] })), e === "confirm" && (typeof t.closeAfter > "u" && (t.closeAfter = 0), t.okBtn || (t.okBtn = { label: "OK" })), t.okBtn && (typeof t.okBtn != "object" && (t.okBtn = { label: "OK" }), t.okBtn.label ??= "OK", t.okBtn.className ??= "is-primary is-text ok-btn", t.okBtn.method = (a, c) => {
1325
+ i?.(!0, c, a), c.close();
1326
+ }), t.cancelBtn && (typeof t.cancelBtn != "object" && (t.cancelBtn = { label: "Cancel" }), t.cancelBtn.label ??= "Cancel", t.cancelBtn.className ??= "is-danger is-text cancel-btn", t.cancelBtn.method = (a, c) => {
1327
+ i?.(!1, c, a), c.close();
1328
+ }), t.buttons = [t.cancelBtn, t.okBtn, ...t.buttons ?? []].filter(
1329
+ Boolean
1330
+ );
1331
+ const r = `is-notify type-${e || "default"} ${t.className ?? ""}`, o = new this({
1332
+ ...t,
1333
+ className: r,
1334
+ sizeClass: "auto",
1335
+ center: !1,
1336
+ fitScreen: !1,
1337
+ closeIcon: !0,
1338
+ outSideClose: !1,
1339
+ bodyScroll: !0,
1340
+ buttons: t.buttons ?? []
1341
+ });
1342
+ return o.setPluginName("toast"), o.showToast({
1343
+ position: t.position ?? "top right"
1344
+ });
1345
+ }
1346
+ }
1347
+ const I = [];
1348
+ function Zt(s = "top right") {
1349
+ const e = "ipe-modal-toast-container", t = `${e}-${s.replace(/[\s-\.|\/]+/g, "-")}`;
1350
+ let i = document.getElementById(t);
1351
+ return i || (i = v("div", {
1352
+ className: `${e} ${s}`,
1353
+ attrs: { id: t, "data-position": s }
1354
+ }), document.body.appendChild(i)), i;
1355
+ }
1356
+ class y extends U {
1357
+ constructor(e = {}) {
1358
+ e.className ||= "", e.className += " theme-ipe", e.modalAnimation ||= {
1359
+ show: "ipe-modal-fade-in",
1360
+ hide: "ipe-modal-fade-out"
1361
+ }, super(e);
1362
+ }
1363
+ setLoadingState(e) {
1364
+ if (this.get$window().classList.toggle("loading", e), e) {
1365
+ const t = this.get$window().querySelectorAll(
1366
+ "input:not([disabled]),button:not([disabled])"
1367
+ );
1368
+ this._tmpDisabledActiveInputs = t, t.forEach((i) => {
1369
+ i.disabled = !0;
1370
+ }), this.get$content().append(
1371
+ /* @__PURE__ */ $(
1372
+ "div",
1373
+ {
1374
+ id: "ipe-modalLoadingWrapper",
1375
+ style: {
1376
+ position: "absolute",
1377
+ top: 0,
1378
+ left: 0,
1379
+ right: 0,
1380
+ bottom: 0,
1381
+ display: "flex",
1382
+ justifyContent: "center",
1383
+ alignItems: "center",
1384
+ backgroundColor: "rgba(255, 255, 255, 0.5)",
1385
+ zIndex: 2e3
1386
+ },
1387
+ children: /* @__PURE__ */ $(ht, { style: { width: "80%", maxWidth: "800px" } })
1388
+ }
1389
+ )
1390
+ );
1391
+ } else {
1392
+ this.get$window().querySelector("#ipe-modalLoadingWrapper")?.remove();
1393
+ const t = this._tmpDisabledActiveInputs;
1394
+ t && t.forEach((i) => {
1395
+ i.disabled = !1;
1396
+ });
1397
+ }
1398
+ }
1399
+ }
1400
+ class Jt {
1401
+ constructor(e) {
1402
+ this.ctx = e, this.IPEModal = y, this.IPEModalEvent = oe, this.show = y.show.bind(y), this.createObject = y.createObject.bind(y), this.close = y.close.bind(y), this.closeAll = y.closeAll.bind(y), this.removeAll = y.removeAll.bind(y), this.dialog = y.dialog.bind(y), this.confirm = y.confirm.bind(y), this.notify = y.notify.bind(y), e.set("modal", this), e.on("dispose", () => {
1403
+ y.closeAll();
1404
+ });
1405
+ }
1406
+ }
1407
+ const Oe = (s) => {
1408
+ if (!s)
1409
+ return new URLSearchParams();
1410
+ if (s instanceof URLSearchParams)
1411
+ return s;
1412
+ if (typeof s != "object" || s?.constructor !== Object)
1413
+ throw new TypeError("only plain object is supported");
1414
+ const e = new URLSearchParams();
1415
+ for (const [t, i] of Object.entries(s))
1416
+ if (i != null) {
1417
+ if (Array.isArray(i)) {
1418
+ for (const n of i)
1419
+ e.append(t, n?.toString());
1420
+ continue;
1421
+ }
1422
+ if (typeof i == "object" && i !== null && i.constructor === Object) {
1423
+ for (const [n, r] of Object.entries(i))
1424
+ r != null && e.set(`${t}[${n}]`, r?.toString());
1425
+ continue;
1426
+ }
1427
+ e.set(t, i?.toString());
1428
+ }
1429
+ return e;
1430
+ }, Ne = (s, e, t) => {
1431
+ const i = typeof s == "string" ? new URL(s, window?.location?.origin) : new URL(s), n = new URLSearchParams(i.search), r = Oe(e);
1432
+ for (const [o, a] of r.entries())
1433
+ n.set(o, a);
1434
+ return i.search = n.toString(), i.hash = "", i;
1435
+ };
1436
+ var Qt = Object.create, ae = Object.defineProperty, ei = Object.getOwnPropertyDescriptor, Ue = (s, e) => (e = Symbol[s]) ? e : Symbol.for("Symbol." + s), je = (s) => {
1437
+ throw TypeError(s);
1438
+ }, ti = (s, e, t) => e in s ? ae(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t, ii = (s, e) => ae(s, "name", { value: e, configurable: !0 }), si = (s) => [, , , Qt(s?.[Ue("metadata")] ?? null)], ni = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], Fe = (s) => s !== void 0 && typeof s != "function" ? je("Function expected") : s, ri = (s, e, t, i, n) => ({ kind: ni[s], name: e, metadata: i, addInitializer: (r) => t._ ? je("Already initialized") : n.push(Fe(r || null)) }), oi = (s, e) => ti(e, Ue("metadata"), s[3]), ai = (s, e, t, i) => {
1439
+ for (var n = 0, r = s[e >> 1], o = r && r.length; n < o; n++) r[n].call(t);
1440
+ return i;
1441
+ }, li = (s, e, t, i, n, r) => {
1442
+ var o, a, c, l = e & 7, h = !1, d = 0, f = s[d] || (s[d] = []), u = l && (n = n.prototype, l < 5 && (l > 3 || !h) && ei(n, t));
1443
+ ii(n, t);
1444
+ for (var g = i.length - 1; g >= 0; g--)
1445
+ c = ri(l, t, a = {}, s[3], f), o = (0, i[g])(n, c), a._ = 1, Fe(o) && (n = o);
1446
+ return oi(s, n), u && ae(n, t, u), h ? l ^ 4 ? r : u : n;
1447
+ }, ze, le, Ke;
1448
+ ze = [H(["api", "storage"])];
1449
+ class j extends (Ke = C) {
1450
+ constructor(e) {
1451
+ super(e, "wiki", !1), this.ctx = e, this._data = {}, this.CACHE_VERSION = 3, this.CACHE_TTL = {
1452
+ siteinfo: 1e3 * 60 * 60 * 24 * 3,
1453
+ // 3 days
1454
+ userinfo: 1e3 * 60 * 30
1455
+ // 30 minutes
1456
+ }, this.QUERY_DATA = {
1457
+ siteinfo: {
1458
+ meta: "siteinfo",
1459
+ siprop: "general|specialpagealiases|namespacealiases|namespaces|magicwords"
1460
+ },
1461
+ userinfo: { meta: "userinfo", uiprop: "groups|rights|blockinfo|options" }
1462
+ }, this.CACHE_DB = void 0, this.mwConfig = {
1463
+ get: ((t, i) => window?.mw?.config?.get?.(t, i) ?? i),
1464
+ has: ((t) => window?.mw?.config?.exists?.(t) ?? !1),
1465
+ get values() {
1466
+ return window?.mw?.config?.values || {};
1467
+ }
1468
+ }, this.CACHE_DB = e.storage.createDatabase(
1469
+ "wiki-metadata",
1470
+ 1 / 0,
1471
+ this.CACHE_VERSION
1472
+ );
1473
+ }
1474
+ get logger() {
1475
+ return this.ctx.logger("WIKI_METADATA");
1476
+ }
1477
+ get api() {
1478
+ return this.ctx.api;
1479
+ }
1480
+ async start() {
1481
+ await Promise.all(
1482
+ Object.keys(this.QUERY_DATA).map((e) => this.initData(e))
1483
+ ), this.ctx.on("clear-cache", this.onClearCache.bind(this)), this.ctx.set("getUrl", this.getUrl.bind(this)), this.ctx.set("getSciprtUrl", this.getSciprtUrl.bind(this)), this.ctx.set("getMainpageUrl", this.getMainpageUrl.bind(this)), this.ctx.inject(["preferences", "$"], (e) => {
1484
+ const t = e.$;
1485
+ e.preferences.registerCustomConfig(
1486
+ "WikiMetadataService",
1487
+ p.object({
1488
+ WikiMetadataService: p.const(
1489
+ /* @__PURE__ */ $("div", { children: [
1490
+ /* @__PURE__ */ $("h3", { children: t`Wiki Informations` }),
1491
+ /* @__PURE__ */ $("ul", { children: [
1492
+ /* @__PURE__ */ $("li", { children: [
1493
+ /* @__PURE__ */ $("strong", { children: [
1494
+ t`Site`,
1495
+ ":"
1496
+ ] }),
1497
+ " ",
1498
+ this.general.sitename,
1499
+ " (",
1500
+ this.landingPageUrl,
1501
+ ")"
1502
+ ] }),
1503
+ /* @__PURE__ */ $("li", { children: [
1504
+ /* @__PURE__ */ $("strong", { children: t`User` }),
1505
+ ": ",
1506
+ this.userInfo.name,
1507
+ " (ID: ",
1508
+ this.userInfo.id,
1509
+ ")"
1510
+ ] }),
1511
+ /* @__PURE__ */ $("li", { children: [
1512
+ /* @__PURE__ */ $("strong", { children: t`Groups` }),
1513
+ ": ",
1514
+ this.userGroups.join(", ") || "None"
1515
+ ] })
1516
+ ] }),
1517
+ /* @__PURE__ */ $("div", { children: [
1518
+ /* @__PURE__ */ $("p", { style: { fontStyle: "italic" }, children: t`If the information shown above is incorrect (for example, the user is not you), click the button below.` }),
1519
+ /* @__PURE__ */ $(
1520
+ "button",
1521
+ {
1522
+ className: "btn danger",
1523
+ onClick: async (i) => {
1524
+ i.preventDefault(), await e.serial("clear-cache") || window.location.reload();
1525
+ },
1526
+ children: [
1527
+ "🧹 ",
1528
+ t`Clear caches & Reload`
1529
+ ]
1530
+ }
1531
+ )
1532
+ ] })
1533
+ ] })
1534
+ ).role("raw-html")
1535
+ }).description("WikiMetadataService"),
1536
+ "about"
1537
+ );
1538
+ }), this.logger.info("All initialized", this._data);
1539
+ }
1540
+ async initData(e, t = !1) {
1541
+ const i = t ? null : await this.fetchFromCache(e);
1542
+ if (i)
1543
+ return this._data[e] = i, this.logger.debug("Using cached", e, i), i;
1544
+ {
1545
+ const n = await this.fetchFromApi(e);
1546
+ return this.saveToCache(e, n), this._data[e] = n, this.logger.debug("Fetched from API", e, n), n;
1547
+ }
1548
+ }
1549
+ getCacheKey(e) {
1550
+ return `${e}:${new URL(this.ctx.api.config.baseURL).pathname.replace(/^\//, "")}`;
1551
+ }
1552
+ async fetchFromApi(e) {
1553
+ return this.api.get({
1554
+ action: "query",
1555
+ ...this.QUERY_DATA[e]
1556
+ }).then(({ data: t }) => {
1557
+ if (typeof t?.query != "object" || t.query === null)
1558
+ throw new Error("Invalid query data", { cause: t });
1559
+ return e === "siteinfo" ? t.query : t.query?.[e] || t.query;
1560
+ }).catch((t) => (this.logger.error("Failed to fetch", t), Promise.reject(t)));
1561
+ }
1562
+ async fetchFromCache(e) {
1563
+ const t = this.getCacheKey(e);
1564
+ return await this.CACHE_DB.get(t, this.CACHE_TTL[e]);
1565
+ }
1566
+ async saveToCache(e, t) {
1567
+ const i = this.getCacheKey(e);
1568
+ return this.CACHE_DB.set(i, t);
1569
+ }
1570
+ async invalidateCache(e) {
1571
+ const t = this.getCacheKey(e);
1572
+ return this.CACHE_DB.delete(t);
1573
+ }
1574
+ async onClearCache() {
1575
+ await this.CACHE_DB.clear();
1576
+ }
1577
+ // ====== shortcuts ======
1578
+ get _raw() {
1579
+ return this._data;
1580
+ }
1581
+ // siteInfo
1582
+ get siteInfo() {
1583
+ return this._data.siteinfo;
1584
+ }
1585
+ get general() {
1586
+ return this.siteInfo.general;
1587
+ }
1588
+ get specialPageAliases() {
1589
+ return this.siteInfo.specialpagealiases;
1590
+ }
1591
+ get namespaceAliases() {
1592
+ return this.siteInfo.namespacealiases;
1593
+ }
1594
+ get namespaces() {
1595
+ return this.siteInfo.namespaces;
1596
+ }
1597
+ get namespaceMap() {
1598
+ const e = Object.values(this.namespaces).map((t) => ({
1599
+ id: t.id,
1600
+ canonical: t.canonical,
1601
+ aliases: this.namespaceAliases.filter((i) => i.id === t.id).map((i) => i.alias)
1602
+ })).sort((t, i) => t.id - i.id);
1603
+ return Reflect.defineProperty(this, "namespaceMap", {
1604
+ get: () => e
1605
+ }), e;
1606
+ }
1607
+ get magicWords() {
1608
+ return this.siteInfo.magicwords;
1609
+ }
1610
+ // userInfo
1611
+ get userInfo() {
1612
+ return this._data.userinfo;
1613
+ }
1614
+ get userOptions() {
1615
+ return this.userInfo.options;
1616
+ }
1617
+ get isUserBlocked() {
1618
+ return this.userInfo.blockedbyid && this.userInfo.blockexpiry && new Date(this.userInfo.blockexpiry).getTime() > Date.now();
1619
+ }
1620
+ get userGroups() {
1621
+ return this.userInfo.groups;
1622
+ }
1623
+ get userRights() {
1624
+ return this.userInfo.rights;
1625
+ }
1626
+ /**
1627
+ * Base URL, without trailing slash
1628
+ * @example "https://mediawiki.org"
1629
+ */
1630
+ get baseUrl() {
1631
+ const e = this.general.server;
1632
+ return e.startsWith("//") ? `${window?.location?.protocol || "https:"}//${e.slice(2)}` : e;
1633
+ }
1634
+ /**
1635
+ * Home page URL of this wiki
1636
+ * @description Generally same as the Mainpage URL,
1637
+ * but after MediaWiki 1.34,
1638
+ * it can be set to the website root directory.
1639
+ * @example "https://mediawiki.org/wiki/Main_Page" (In most cases)
1640
+ * @example "https://mediawiki.org/" ($wgMainPageIsDomainRoot = true)
1641
+ */
1642
+ get landingPageUrl() {
1643
+ return this.general.base;
1644
+ }
1645
+ get mainPageName() {
1646
+ return this.general.mainpage;
1647
+ }
1648
+ /**
1649
+ * Exact Mainpage URL of this wiki
1650
+ * @example "https://mediawiki.org/wiki/Main_Page"
1651
+ */
1652
+ get mainPageUrl() {
1653
+ return this.getUrl(this.mainPageName);
1654
+ }
1655
+ /**
1656
+ * Article path, with the $1 placeholder
1657
+ * @example "/wiki/$1"
1658
+ */
1659
+ get articlePath() {
1660
+ return this.general.articlepath;
1661
+ }
1662
+ /**
1663
+ * Script path, without trailing slash
1664
+ * @example "/w"
1665
+ */
1666
+ get scriptPath() {
1667
+ return this.general.scriptpath;
1668
+ }
1669
+ /**
1670
+ * Article base URL, with the $1 placeholder
1671
+ * @example "https://mediawiki.org/wiki/$1"
1672
+ */
1673
+ get articleBaseUrl() {
1674
+ return `${this.baseUrl}${this.articlePath}`;
1675
+ }
1676
+ /**
1677
+ * Script base URL, without trailing slash
1678
+ * @example "https://mediawiki.org/w"
1679
+ */
1680
+ get scriptBaseUrl() {
1681
+ return `${this.baseUrl}${this.scriptPath}`;
1682
+ }
1683
+ // utils
1684
+ getSciprtUrl(e = "index") {
1685
+ return `${this.scriptBaseUrl}/${e.replace(/\.php$/, "")}.php`;
1686
+ }
1687
+ /** Get mainpage URL */
1688
+ getMainpageUrl(e) {
1689
+ return Ne(this.siteInfo.general.base, e).toString();
1690
+ }
1691
+ getUrl(e, t) {
1692
+ const i = Oe(t);
1693
+ let n;
1694
+ return typeof e == "string" && e !== "" ? n = new URL(`${this.articleBaseUrl.replace("$1", e)}`) : typeof e == "number" ? (i.set("curid", e.toString()), n = new URL(this.getSciprtUrl("index"))) : n = new URL(this.getSciprtUrl("index")), n.search = i.toString(), n.toString();
1695
+ }
1696
+ hasRight(e) {
1697
+ return this.userRights.includes(e);
1698
+ }
1699
+ hasAnyRight(...e) {
1700
+ return e.some((t) => this.hasRight(t));
1701
+ }
1702
+ hasEveryRights(...e) {
1703
+ return e.every((t) => this.hasRight(t));
1704
+ }
1705
+ inGroup(e) {
1706
+ return this.userGroups.includes(e);
1707
+ }
1708
+ inAnyGroup(...e) {
1709
+ return this.userGroups.some((t) => e.includes(t));
1710
+ }
1711
+ getBlockInfo() {
1712
+ return this.isUserBlocked ? {
1713
+ blockid: this.userInfo.blockid,
1714
+ blockedby: this.userInfo.blockedbyid,
1715
+ blockedbyid: this.userInfo.blockedbyid,
1716
+ blockreason: this.userInfo.blockreason,
1717
+ blockedtimestamp: this.userInfo.blockedtimestamp,
1718
+ blockexpiry: this.userInfo.blockexpiry
1719
+ } : null;
1720
+ }
1721
+ }
1722
+ le = si(Ke);
1723
+ j = li(le, 0, "WikiMetadataService", ze, j);
1724
+ ai(le, 1, j);
1725
+ const ci = (() => {
1726
+ const s = Symbol.for("IPE.GlobalMemoryStorage");
1727
+ return s in globalThis || (globalThis[s] = it()), globalThis[s];
1728
+ })();
1729
+ class hi {
1730
+ constructor(e, t, i = 1 / 0, n, r = "localStorage") {
1731
+ this.dbName = e, this.storeName = t, this.ttl = i, this.version = n, this.engine = r, typeof i != "number" && (this.ttl = Number(i)), (isNaN(this.ttl) || this.ttl <= 0) && (this.ttl = 1 / 0), this.engine === "localStorage" && "localStorage" in window ? this.db = window.localStorage : this.engine === "sessionStorage" && "sessionStorage" in window ? this.db = window.sessionStorage : this.db = ci;
1732
+ }
1733
+ // Key builder
1734
+ makeKey(e) {
1735
+ return `${this.dbName ? this.dbName + ":" : ""}${this.storeName ? this.storeName + "/" : ""}${e}`;
1736
+ }
1737
+ // Internal load & validation
1738
+ load(e) {
1739
+ const t = this.getRaw(e);
1740
+ if (t === null) return null;
1741
+ let i;
1742
+ try {
1743
+ i = JSON.parse(t);
1744
+ } catch {
1745
+ return this.deleteSync(e), null;
1746
+ }
1747
+ const n = i;
1748
+ return typeof n.time != "number" || !("value" in n) ? (this.deleteSync(e), null) : typeof this.version < "u" && typeof this.version < "u" && n.version !== this.version ? (this.deleteSync(e), null) : n;
1749
+ }
1750
+ getRaw(e) {
1751
+ const t = this.makeKey(e);
1752
+ return this.db.getItem(t);
1753
+ }
1754
+ setRaw(e, t) {
1755
+ const i = this.makeKey(e);
1756
+ try {
1757
+ this.db.setItem(i, t);
1758
+ } catch {
1759
+ }
1760
+ }
1761
+ deleteSync(e) {
1762
+ const t = this.makeKey(e);
1763
+ this.db.removeItem(t);
1764
+ }
1765
+ isExpired(e, t = this.ttl) {
1766
+ return e ? Date.now() - e.time > t : !1;
1767
+ }
1768
+ async get(e, t = this.ttl, i) {
1769
+ const n = this.load(e), r = this.isExpired(n, t);
1770
+ if (!n || r) {
1771
+ if (typeof i == "function") {
1772
+ const o = await i();
1773
+ return await this.set(e, o), o;
1774
+ }
1775
+ return null;
1776
+ }
1777
+ return n.value;
1778
+ }
1779
+ async set(e, t) {
1780
+ const i = Date.now();
1781
+ if (typeof e == "string") {
1782
+ const o = e, a = t;
1783
+ if (a === null || typeof a > "u") {
1784
+ await this.delete(o);
1785
+ return;
1786
+ }
1787
+ const c = { time: i, value: a, version: this.version };
1788
+ return this.setRaw(o, JSON.stringify(c)), c;
1789
+ }
1790
+ const n = e, r = {};
1791
+ for (const [o, a] of Object.entries(n)) {
1792
+ if (a === null || typeof a > "u") {
1793
+ this.deleteSync(o);
1794
+ continue;
1795
+ }
1796
+ const c = { time: i, value: a, version: this.version };
1797
+ this.setRaw(o, JSON.stringify(c)), r[o] = c;
1798
+ }
1799
+ return r;
1800
+ }
1801
+ async has(e, t = this.ttl) {
1802
+ const i = this.load(e);
1803
+ return i !== null && !this.isExpired(i, t);
1804
+ }
1805
+ async delete(e) {
1806
+ this.deleteSync(e);
1807
+ }
1808
+ async updatedAt(e) {
1809
+ const t = this.load(e);
1810
+ return t ? t.time : 0;
1811
+ }
1812
+ async clear() {
1813
+ const e = this.makeKey(""), t = [];
1814
+ for (let i = 0; i < this.db.length; i++) {
1815
+ const n = this.db.key(i);
1816
+ n && n.startsWith(e) && t.push(n);
1817
+ }
1818
+ for (const i of t) this.db.removeItem(i);
1819
+ return this;
1820
+ }
1821
+ // Async generators
1822
+ async *keys() {
1823
+ const e = this.makeKey("");
1824
+ for (let t = 0; t < this.db.length; t++) {
1825
+ const i = this.db.key(t);
1826
+ i && i.startsWith(e) && (yield i.slice(e.length));
1827
+ }
1828
+ }
1829
+ async *values() {
1830
+ for await (const e of this.keys()) {
1831
+ const t = this.load(e);
1832
+ if (t) {
1833
+ if (this.isExpired(t)) {
1834
+ this.deleteSync(e);
1835
+ continue;
1836
+ }
1837
+ yield t;
1838
+ }
1839
+ }
1840
+ }
1841
+ async *entries() {
1842
+ for await (const e of this.keys()) {
1843
+ const t = this.load(e);
1844
+ if (t) {
1845
+ if (this.isExpired(t)) {
1846
+ this.deleteSync(e);
1847
+ continue;
1848
+ }
1849
+ yield [e, t];
1850
+ }
1851
+ }
1852
+ }
1853
+ }
1854
+ var w;
1855
+ ((s) => {
1856
+ s.cache = /* @__PURE__ */ new Map(), s.defaults = Object.freeze({ iterBatch: 100, retry: { attempts: 3, baseDelayMs: 16 } }), s.sleep = (l) => new Promise((h) => setTimeout(h, l));
1857
+ function e(l) {
1858
+ const h = l?.name ?? "";
1859
+ return h === "AbortError" || h === "InvalidStateError" || h === "TransactionInactiveError" || h === "UnknownError";
1860
+ }
1861
+ s.shouldReconnect = e;
1862
+ async function t(l, h, d) {
1863
+ const f = Math.max(1, l.attempts);
1864
+ for (let u = 0; u < f; u++)
1865
+ try {
1866
+ return await h(u);
1867
+ } catch (g) {
1868
+ if (u === f - 1) throw g;
1869
+ await d?.(g, u);
1870
+ const b = l.baseDelayMs * Math.pow(2, u) + Math.floor(Math.random() * 10);
1871
+ await (0, s.sleep)(b);
1872
+ }
1873
+ throw new Error("withRetry exhausted unexpectedly");
1874
+ }
1875
+ s.withRetry = t;
1876
+ function i(l, h, d) {
1877
+ return new Promise((f, u) => {
1878
+ const g = indexedDB.open(l, h);
1879
+ g.onupgradeneeded = () => {
1880
+ try {
1881
+ const b = g.result, S = g.transaction;
1882
+ d?.(b, S);
1883
+ } catch (b) {
1884
+ u(b);
1885
+ }
1886
+ }, g.onerror = () => u(g.error), g.onblocked = () => {
1887
+ }, g.onsuccess = () => {
1888
+ const b = g.result;
1889
+ b.onversionchange = () => {
1890
+ try {
1891
+ b.close();
1892
+ } finally {
1893
+ s.cache.delete(l);
1894
+ }
1895
+ }, f(b);
1896
+ };
1897
+ });
1898
+ }
1899
+ async function n(l, h, d) {
1900
+ let f = !l.objectStoreNames.contains(h), u = [];
1901
+ if (!f && d?.indexes?.length) {
1902
+ const S = l.transaction(h, "readonly"), G = S.objectStore(h), P = new Set(Array.from(G.indexNames));
1903
+ u = (d.indexes || []).filter((k) => !P.has(k.name)), await new Promise((k, ge) => {
1904
+ S.oncomplete = () => k(), S.onabort = () => ge(S.error), S.onerror = () => ge(S.error);
1905
+ });
1906
+ }
1907
+ if (!f && u.length === 0) return l;
1908
+ const g = l.version + 1;
1909
+ l.close();
1910
+ const b = await i(l.name, g, (S, G) => {
1911
+ let P;
1912
+ S.objectStoreNames.contains(h) ? P = G.objectStore(h) : P = S.createObjectStore(h, {
1913
+ keyPath: d?.keyPath ?? void 0,
1914
+ autoIncrement: !!d?.autoIncrement
1915
+ });
1916
+ for (const k of u)
1917
+ P.indexNames.contains(k.name) || P.createIndex(k.name, k.keyPath, k.options);
1918
+ });
1919
+ return b.onversionchange = () => {
1920
+ try {
1921
+ b.close();
1922
+ } finally {
1923
+ s.cache.delete(b.name);
1924
+ }
1925
+ }, b;
1926
+ }
1927
+ async function r(l, h, d) {
1928
+ let f = s.cache.get(l);
1929
+ return f ? (f = f.then((u) => n(u, h, d)), s.cache.set(l, f)) : (f = (async () => {
1930
+ const u = await i(l);
1931
+ return n(u, h, d);
1932
+ })(), s.cache.set(l, f)), f;
1933
+ }
1934
+ s.getDB = r;
1935
+ async function o(l) {
1936
+ const h = s.cache.get(l);
1937
+ if (s.cache.delete(l), h)
1938
+ try {
1939
+ (await h).close();
1940
+ } catch {
1941
+ }
1942
+ }
1943
+ s.closeConnection = o;
1944
+ function a(l) {
1945
+ return new Promise((h, d) => {
1946
+ l.onsuccess = () => h(l.result), l.onerror = () => d(l.error);
1947
+ });
1948
+ }
1949
+ s.asyncRequest = a;
1950
+ function c(l) {
1951
+ return new Promise((h, d) => {
1952
+ l.oncomplete = () => h(), l.onabort = () => d(l.error ?? new DOMException("Aborted", "AbortError")), l.onerror = () => d(l.error ?? new DOMException("TransactionError", "UnknownError"));
1953
+ });
1954
+ }
1955
+ s.waitTx = c;
1956
+ })(w || (w = {}));
1957
+ class di {
1958
+ constructor(e, t, i = {}) {
1959
+ this.dbName = e, this.storeName = t, this.options = i;
1960
+ }
1961
+ get _iterBatch() {
1962
+ return this.options.iterBatch ?? w.defaults.iterBatch;
1963
+ }
1964
+ get _retryCfg() {
1965
+ const e = this.options.retry ?? w.defaults.retry;
1966
+ return { attempts: e.attempts ?? 3, baseDelayMs: e.baseDelayMs ?? 16 };
1967
+ }
1968
+ async _withStore(e, t) {
1969
+ const i = this._retryCfg;
1970
+ return w.withRetry(
1971
+ i,
1972
+ async () => {
1973
+ const n = await w.getDB(this.dbName, this.storeName, this.options.ensure);
1974
+ try {
1975
+ const r = n.transaction(this.storeName, e), o = r.objectStore(this.storeName), a = await t(o);
1976
+ return await w.waitTx(r), a;
1977
+ } catch (r) {
1978
+ throw r;
1979
+ }
1980
+ },
1981
+ async (n) => {
1982
+ w.shouldReconnect(n) && await w.closeConnection(this.dbName);
1983
+ }
1984
+ );
1985
+ }
1986
+ async get(e) {
1987
+ return this._withStore("readonly", async (t) => {
1988
+ const i = await w.asyncRequest(t.get(e));
1989
+ return i === void 0 ? void 0 : i;
1990
+ });
1991
+ }
1992
+ async set(e, t) {
1993
+ return await this._withStore("readwrite", async (i) => {
1994
+ const n = this.options.ensure?.keyPath != null ? i.put(t) : i.put(t, e);
1995
+ await w.asyncRequest(n);
1996
+ }), this;
1997
+ }
1998
+ async delete(e) {
1999
+ return this._withStore("readwrite", async (t) => {
2000
+ const i = await w.asyncRequest(t.get(e)) !== void 0;
2001
+ return await w.asyncRequest(t.delete(e)), i;
2002
+ });
2003
+ }
2004
+ async clear() {
2005
+ await this._withStore("readwrite", async (e) => {
2006
+ await w.asyncRequest(e.clear());
2007
+ });
2008
+ }
2009
+ async has(e) {
2010
+ return await this.get(e) !== void 0;
2011
+ }
2012
+ async count() {
2013
+ return this._withStore("readonly", async (e) => await w.asyncRequest(e.count()) ?? 0);
2014
+ }
2015
+ async *_iterateEntries() {
2016
+ let e = null, t = !1;
2017
+ const i = Math.max(1, this._iterBatch);
2018
+ for (; !t; ) {
2019
+ const n = await this._withStore("readonly", async (r) => {
2020
+ const o = [], a = e === null ? void 0 : IDBKeyRange.lowerBound(e, !0);
2021
+ return await new Promise((c, l) => {
2022
+ const h = r.openCursor(a);
2023
+ h.onerror = () => l(h.error), h.onsuccess = () => {
2024
+ const d = h.result;
2025
+ if (!d) {
2026
+ t = !0, c();
2027
+ return;
2028
+ }
2029
+ o.push([d.key, d.value]), e = d.key, o.length >= i ? c() : d.continue();
2030
+ };
2031
+ }), o;
2032
+ });
2033
+ for (const r of n) yield r;
2034
+ if (n.length === 0) break;
2035
+ }
2036
+ }
2037
+ entries() {
2038
+ return this._iterateEntries();
2039
+ }
2040
+ async *keys() {
2041
+ for await (const [e] of this.entries()) yield e;
2042
+ }
2043
+ async *values() {
2044
+ for await (const [, e] of this.entries()) yield e;
2045
+ }
2046
+ [Symbol.asyncIterator]() {
2047
+ return this.entries()[Symbol.asyncIterator]();
2048
+ }
2049
+ async forEach(e) {
2050
+ for await (const [t, i] of this.entries())
2051
+ await e(i, t, this);
2052
+ }
2053
+ async getMany(e) {
2054
+ const t = /* @__PURE__ */ new Map();
2055
+ for await (const i of e) t.set(i, void 0);
2056
+ return await this._withStore("readonly", async (i) => {
2057
+ await Promise.all(
2058
+ t.keys().map(async (n) => {
2059
+ const r = await w.asyncRequest(i.get(n));
2060
+ t.set(n, r === void 0 ? void 0 : r);
2061
+ })
2062
+ );
2063
+ }), t;
2064
+ }
2065
+ async setMany(e) {
2066
+ const t = this.options.ensure?.keyPath != null;
2067
+ return await this._withStore("readwrite", async (i) => {
2068
+ for await (const [n, r] of e) {
2069
+ const o = t ? i.put(r) : i.put(r, n);
2070
+ await w.asyncRequest(o);
2071
+ }
2072
+ }), this;
2073
+ }
2074
+ async deleteMany(e) {
2075
+ let t = 0;
2076
+ return await this._withStore("readwrite", async (i) => {
2077
+ for await (const n of e)
2078
+ await w.asyncRequest(i.get(n)) !== void 0 && t++, await w.asyncRequest(i.delete(n));
2079
+ }), t;
2080
+ }
2081
+ async disconnect() {
2082
+ await w.closeConnection(this.dbName);
2083
+ }
2084
+ }
2085
+ class ui {
2086
+ constructor(e, t, i = 1 / 0, n) {
2087
+ this.dbName = e, this.storeName = t, this.ttl = i, this.version = n, this.db = new di(e, t), this.keys = this.db.keys.bind(this.db), this.values = this.db.values.bind(this.db), this.entries = this.db.entries.bind(this.db), typeof this.ttl != "number" && (this.ttl = Number(this.ttl)), (isNaN(this.ttl) || this.ttl <= 0) && (this.ttl = 1 / 0), this._clearExpiredEntries().catch(() => {
2088
+ });
2089
+ }
2090
+ async _clearExpiredEntries() {
2091
+ if (this.ttl === 1 / 0) return;
2092
+ const e = Date.now(), t = [];
2093
+ for await (const [i, n] of this.db.entries())
2094
+ typeof n.time == "number" && e - n.time > this.ttl && t.push(i);
2095
+ t.length > 0 && await this.db.deleteMany(t);
2096
+ }
2097
+ async get(e, t = this.ttl, i) {
2098
+ const n = await this.loadFromDB(e), r = this.checkIfExpired(n, t);
2099
+ if (!n || r) {
2100
+ if (typeof i == "function") {
2101
+ const o = await i();
2102
+ return await this.set(e, o), o;
2103
+ }
2104
+ return null;
2105
+ }
2106
+ return n.value;
2107
+ }
2108
+ async set(e, t) {
2109
+ const i = Date.now();
2110
+ if (typeof e == "string") {
2111
+ const c = e, l = t;
2112
+ if (l === null || typeof l > "u")
2113
+ return this.delete(c);
2114
+ const h = {
2115
+ time: i,
2116
+ value: l,
2117
+ version: this.version
2118
+ };
2119
+ return await this.db.set(c, h), h;
2120
+ }
2121
+ const n = e, r = [], o = [], a = {};
2122
+ for (const [c, l] of Object.entries(n))
2123
+ if (l === null || typeof l > "u")
2124
+ o.push(c);
2125
+ else {
2126
+ const h = { time: i, value: l, version: this.version };
2127
+ r.push([c, h]), a[c] = h;
2128
+ }
2129
+ return r.length > 0 && await this.db.setMany(r), o.length > 0 && await this.db.deleteMany(o), a;
2130
+ }
2131
+ async has(e, t = this.ttl) {
2132
+ const i = await this.loadFromDB(e), n = this.checkIfExpired(i, t);
2133
+ return i !== null && !n;
2134
+ }
2135
+ async delete(e) {
2136
+ await this.db.delete(e);
2137
+ }
2138
+ async updatedAt(e) {
2139
+ const t = await this.loadFromDB(e);
2140
+ return t ? t.time : 0;
2141
+ }
2142
+ async loadFromDB(e) {
2143
+ const t = await this.db.get(e);
2144
+ if (t === void 0)
2145
+ return null;
2146
+ if (typeof t.time != "number" || typeof t.value > "u") {
2147
+ try {
2148
+ await this.delete(e);
2149
+ } catch {
2150
+ }
2151
+ return null;
2152
+ }
2153
+ if (typeof this.version < "u" && typeof this.version < "u" && t.version !== this.version) {
2154
+ try {
2155
+ await this.delete(e);
2156
+ } catch {
2157
+ }
2158
+ return null;
2159
+ }
2160
+ return t;
2161
+ }
2162
+ checkIfExpired(e, t = this.ttl) {
2163
+ return e ? Date.now() - e.time > t : !1;
2164
+ }
2165
+ /**
2166
+ * [DANGER] Use with caution!
2167
+ * Delete all data from the database.
2168
+ */
2169
+ async clear() {
2170
+ return await this.db.clear(), this;
2171
+ }
2172
+ }
2173
+ class fi extends C {
2174
+ constructor(e, t) {
2175
+ super(e, "storage", !1), this.config = t, this.kv = this.createDatabase("key-val", 0, 1, "indexedDB"), this.simpleKV = this.createDatabase("~", 0, 1, "localStorage"), this.memoryKV = this.createDatabase("~", 0, 1, "memory");
2176
+ }
2177
+ createDatabase(e, t, i, n = "indexedDB") {
2178
+ const r = "indexedDB" in window && window.indexedDB !== null;
2179
+ switch (n === "indexedDB" && !r && (n = "localStorage"), n) {
2180
+ case "indexedDB":
2181
+ return new ui(this.config.dbName, e, t, i);
2182
+ case "localStorage":
2183
+ case "sessionStorage":
2184
+ case "memory":
2185
+ return new hi(this.config.dbName, e, t, i, n);
2186
+ default:
2187
+ throw new Error(`Unsupported storage engine: ${n}`);
2188
+ }
2189
+ }
2190
+ }
2191
+ class gi extends C {
2192
+ constructor(e) {
2193
+ super(e, "wikiPage", !0), this.ctx = e, this.WikiPage = st(this.ctx.api);
2194
+ }
2195
+ static {
2196
+ this.inject = ["api"];
2197
+ }
2198
+ async createInstance(e, t = !1) {
2199
+ return await this.WikiPage.newFromApi(e);
2200
+ }
2201
+ async newFromTitle(e, t = !1, i, n = !1) {
2202
+ return this.createInstance({ titles: e.toString(), converttitles: t, rvsection: i }, n);
2203
+ }
2204
+ async newFromPageId(e, t, i = !1) {
2205
+ return this.createInstance({ pageids: e, rvsection: t }, i);
2206
+ }
2207
+ async newFromRevision(e, t, i = !1) {
2208
+ return await this.createInstance({ revids: e, rvsection: t }, i);
2209
+ }
2210
+ newBlankPage(e = {}) {
2211
+ return this.WikiPage.newBlankPage(e);
2212
+ }
2213
+ }
2214
+ class ce extends C {
2215
+ constructor(e) {
2216
+ super(e, "wikiTitle", !0), this.ctx = e, this.logger = this.ctx.logger("WikiTitleService"), this._cachedTitles = /* @__PURE__ */ new Map(), this.wiki = this.ctx.wiki, this.wikiBaseUrl = this.wiki.baseUrl, this.wikiArticlePath = this.wiki.articlePath.replace("$1", ""), this.wikiArticleBaseUrl = this.wiki.articleBaseUrl.replace("$1", ""), this.wikiIndexPhpUrl = this.wiki.getSciprtUrl("index.php"), this.Title = nt(this.ctx.wiki.siteInfo);
2217
+ }
2218
+ static {
2219
+ this.inject = ["wiki", "wikiPage"];
2220
+ }
2221
+ newTitle(e, t) {
2222
+ return new this.Title(e, t);
2223
+ }
2224
+ newMainPageTitle() {
2225
+ return this.newTitle(this.ctx.wiki.mainPageName);
2226
+ }
2227
+ async newTitleFromUrl(e) {
2228
+ const t = this.parseWikiLink(e);
2229
+ return t?.title ? t.title : t?.pageId ? this.newTitleFromPageId(t.pageId) : null;
2230
+ }
2231
+ async newTitleFromAnyId(e, t = !1) {
2232
+ const { title: i, pageId: n, revId: r } = e ?? {};
2233
+ if (typeof i == "string")
2234
+ return this.newTitle(i);
2235
+ let o, a;
2236
+ if (r ? (o = parseInt(r.toString(), 10), a = "revid") : n && (o = parseInt(n.toString(), 10), a = "pageid"), !o || !a || isNaN(o) || o <= 0)
2237
+ throw new Error("Invalid id or kind", { cause: e });
2238
+ if (!t && this._cachedTitles.has(`${a}:${o}`))
2239
+ return await this._cachedTitles.get(`${a}:${o}`);
2240
+ const { promise: c, resolve: l, reject: h } = xe();
2241
+ this._cachedTitles.set(`${a}:${o}`, c);
2242
+ try {
2243
+ const { wikiPage: d } = this.ctx;
2244
+ let f = null;
2245
+ if (a === "pageid")
2246
+ f = await d.newFromPageId(o);
2247
+ else if (a === "revid")
2248
+ f = await d.newFromRevision(o);
2249
+ else
2250
+ throw new Error(`Invalid kind: ${a}`);
2251
+ l(this.newTitle(f.title));
2252
+ } catch (d) {
2253
+ this._cachedTitles.delete(`${a}:${o}`), h(d);
2254
+ }
2255
+ return c;
2256
+ }
2257
+ async newTitleFromPageId(e) {
2258
+ return this.newTitleFromAnyId({ pageId: e });
2259
+ }
2260
+ async newTitleFromRevision(e) {
2261
+ return this.newTitleFromAnyId({ revId: e });
2262
+ }
2263
+ /**
2264
+ * Resolve **special** special pages to it's real target
2265
+ *
2266
+ * If target is self or cannot be resolved, return null
2267
+ * @example
2268
+ * ```
2269
+ * Special:MyPage -> User:<username>
2270
+ * Special:Edit/Page_Title -> Page_Title
2271
+ * Special:NewSection/Page_Title -> Page_Title (section=new)
2272
+ * ```
2273
+ */
2274
+ resolveSpecialPageTarget(e) {
2275
+ const t = typeof e == "string" ? this.newTitle(e) : e;
2276
+ if (!t || t.getNamespaceId() !== -1)
2277
+ return null;
2278
+ let i, n, r = "view";
2279
+ const o = t.getMainDBKey().split("/").slice(1).join("/") || "";
2280
+ if (t.isSpecial("edit") && o)
2281
+ i = o, r = "edit";
2282
+ else if (t.isSpecial("talkpage") && o) {
2283
+ const a = t.newTitle(o).getTalkPage();
2284
+ if (!a)
2285
+ return null;
2286
+ i = a.getPrefixedDBKey();
2287
+ } else if (t.isSpecial("mypage"))
2288
+ i = t.newTitle(this.ctx.wiki.userInfo.name, 2).getPrefixedDBKey() + (o ? `/${o}` : "");
2289
+ else if (t.isSpecial("mytalk"))
2290
+ i = t.newTitle(this.ctx.wiki.userInfo.name, 3).getPrefixedDBKey() + (o ? `/${o}` : "");
2291
+ else if (t.isSpecial("newsection") && o)
2292
+ i = o, n = "new", r = "edit";
2293
+ else
2294
+ return null;
2295
+ return {
2296
+ title: new this.Title(i),
2297
+ section: n,
2298
+ action: r
2299
+ };
2300
+ }
2301
+ isWikiLink(e) {
2302
+ return e.startsWith(this.wikiArticleBaseUrl) || e.startsWith(this.wikiIndexPhpUrl) || // Some servers allow index.php to be omitted
2303
+ e.startsWith(`${this.wikiBaseUrl}/?`) || // It's the landing page
2304
+ e === this.ctx.wiki.landingPageUrl;
2305
+ }
2306
+ static {
2307
+ this.REG_SKIPPED_HREF = /^(#|javascript:|vbscript:|file:)/i;
2308
+ }
2309
+ validateHrefAttr(e) {
2310
+ return typeof e != "string" ? !1 : !ce.REG_SKIPPED_HREF.test(e);
2311
+ }
2312
+ parseWikiLink(e) {
2313
+ if (!e || typeof e == "string" && !this.validateHrefAttr(e))
2314
+ return null;
2315
+ const t = Ne(e);
2316
+ if (!this.isWikiLink(t.toString()))
2317
+ return null;
2318
+ const i = t.searchParams, n = t.hash.replace("#", ""), r = i.get("action") || "view", o = i.get("title") || "", a = parseInt(i.get("curid") || "0", 10), c = parseInt(i.get("oldid") || "0", 10);
2319
+ let l = o || (() => {
2320
+ try {
2321
+ return decodeURIComponent(t.pathname.substring(this.wikiArticlePath.length));
2322
+ } catch (u) {
2323
+ return this.logger.error("parseLink", t, u), "";
2324
+ }
2325
+ })();
2326
+ l.endsWith("index.php") && (l = "");
2327
+ let h, d, f;
2328
+ if (c)
2329
+ f = c;
2330
+ else if (a)
2331
+ d = a;
2332
+ else if (l)
2333
+ h = this.newTitle(l);
2334
+ else if (t.origin + t.pathname === this.ctx.wiki.landingPageUrl)
2335
+ h = this.newMainPageTitle();
2336
+ else
2337
+ return null;
2338
+ return {
2339
+ title: h,
2340
+ pageId: d,
2341
+ revId: f,
2342
+ url: t,
2343
+ params: i,
2344
+ hash: n,
2345
+ action: r
2346
+ };
2347
+ }
2348
+ }
2349
+ var pi = Object.create, he = Object.defineProperty, mi = Object.getOwnPropertyDescriptor, He = (s, e) => (e = Symbol[s]) ? e : Symbol.for("Symbol." + s), We = (s) => {
2350
+ throw TypeError(s);
2351
+ }, wi = (s, e, t) => e in s ? he(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t, yi = (s, e) => he(s, "name", { value: e, configurable: !0 }), bi = (s) => [, , , pi(s?.[He("metadata")] ?? null)], vi = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], qe = (s) => s !== void 0 && typeof s != "function" ? We("Function expected") : s, _i = (s, e, t, i, n) => ({ kind: vi[s], name: e, metadata: i, addInitializer: (r) => t._ ? We("Already initialized") : n.push(qe(r || null)) }), $i = (s, e) => wi(e, He("metadata"), s[3]), Si = (s, e, t, i) => {
2352
+ for (var n = 0, r = s[e >> 1], o = r && r.length; n < o; n++) r[n].call(t);
2353
+ return i;
2354
+ }, xi = (s, e, t, i, n, r) => {
2355
+ var o, a, c, l = e & 7, h = !1, d = 0, f = s[d] || (s[d] = []), u = l && (n = n.prototype, l < 5 && (l > 3 || !h) && mi(n, t));
2356
+ yi(n, t);
2357
+ for (var g = i.length - 1; g >= 0; g--)
2358
+ c = _i(l, t, a = {}, s[3], f), o = (0, i[g])(n, c), a._ = 1, qe(o) && (n = o);
2359
+ return $i(s, n), u && he(n, t, u), h ? l ^ 4 ? r : u : n;
2360
+ }, Ge, de, Xe;
2361
+ Ge = [H(["storage", "wiki"])];
2362
+ class F extends (Xe = C) {
2363
+ constructor(e) {
2364
+ super(e, "preferences", !0), this.ctx = e, this.db = void 0, this.customRegistries = [], this.categoryDefinitions = [], this._defaultPreferences = {}, e.set("prefs", this), this.db = e.storage.createDatabase(`preferences:${e.wiki.userInfo.id}`, 1 / 0);
2365
+ try {
2366
+ this._migrageFromLegacyMasterDB();
2367
+ } catch {
2368
+ }
2369
+ }
2370
+ get logger() {
2371
+ return this.ctx.logger("PREFERENCES");
2372
+ }
2373
+ async start() {
2374
+ }
2375
+ async get(e, t) {
2376
+ if (!e)
2377
+ return this.getAll();
2378
+ t ??= () => {
2379
+ const n = this.defaultOf(e);
2380
+ return this.logger.debug(e, `(fallback value: ${n})`), n;
2381
+ };
2382
+ const i = await this.db.get(e, void 0);
2383
+ return i !== null ? i : await ot(t);
2384
+ }
2385
+ /**
2386
+ * 获取全部注册的配置项以及最终生效的值
2387
+ * 未保存的配置项将使用默认值
2388
+ */
2389
+ async getAll() {
2390
+ const e = this.loadDefaultConfigs();
2391
+ for await (const [t, i] of this.db.entries())
2392
+ t !== "_touched" && t in e && (e[t] = i.value);
2393
+ return e;
2394
+ }
2395
+ async set(e, t) {
2396
+ return (await this.setMany({ [e]: t }))[e];
2397
+ }
2398
+ async setMany(e) {
2399
+ const t = this.loadDefaultConfigs(), i = {};
2400
+ for (const [n, r] of Object.entries(e))
2401
+ r === t[n] || r === void 0 ? i[n] = void 0 : i[n] = r;
2402
+ return await this.db.set(i), this.ctx.emit("preferences/changed", { ctx: this.ctx, input: e, changes: i }), i;
2403
+ }
2404
+ defaultOf(e) {
2405
+ return this._defaultPreferences[e] ??= this.loadDefaultConfigs()[e];
2406
+ }
2407
+ /**
2408
+ * Get exportable configurations
2409
+ * - exclude values that are the same as the default value
2410
+ * - exclude invalid or undefined values
2411
+ * - sort by keys
2412
+ */
2413
+ async getExportableRecord(e) {
2414
+ e ??= await this.getAll();
2415
+ const t = this.loadDefaultConfigs(), i = {};
2416
+ return Object.entries(t).sort(([n], [r]) => n.localeCompare(r)).forEach(([n, r]) => {
2417
+ const o = e[n];
2418
+ o !== void 0 && o !== r && (i[n] = o);
2419
+ }), i;
2420
+ }
2421
+ loadDefaultConfigs() {
2422
+ const e = {};
2423
+ return this.getConfigRegistries().forEach((t) => {
2424
+ try {
2425
+ const i = t.schema({});
2426
+ Object.entries(i).forEach(([n, r]) => {
2427
+ e[n] = r;
2428
+ });
2429
+ } catch {
2430
+ }
2431
+ }), Object.entries(e).forEach(([t, i]) => {
2432
+ this._defaultPreferences[t] = i;
2433
+ }), e;
2434
+ }
2435
+ registerCustomConfig(e, t, i) {
2436
+ const n = {
2437
+ name: e,
2438
+ schema: t,
2439
+ category: i || "general"
2440
+ }, r = this.customRegistries.findIndex((o) => o.name === e);
2441
+ return r >= 0 ? this.customRegistries[r] = n : this.customRegistries.push(n), this;
2442
+ }
2443
+ getConfigRegistries(e) {
2444
+ return Array.from(this.ctx.registry.entries()).map(([t]) => t === null ? {
2445
+ name: "@root",
2446
+ schema: K?.PreferencesSchema || null
2447
+ } : {
2448
+ name: t.name,
2449
+ schema: t?.PreferencesSchema || null
2450
+ }).filter((t) => t.schema !== null).map((t) => ({
2451
+ ...t,
2452
+ category: t.schema.meta.category || "general"
2453
+ })).concat(this.customRegistries).filter((t) => !e || t.category === e);
2454
+ }
2455
+ getAllSchema() {
2456
+ return new p(
2457
+ p.intersect(this.getConfigRegistries().map((e) => e.schema))
2458
+ );
2459
+ }
2460
+ defineCategory(e) {
2461
+ const t = this.categoryDefinitions.findIndex((i) => i.name === e.name);
2462
+ return t < 0 ? this.categoryDefinitions.push(e) : this.categoryDefinitions[t] = e, this.categoryDefinitions.sort((i, n) => (i.index ?? 0) - (n.index ?? 0)), this;
2463
+ }
2464
+ getConfigCategories() {
2465
+ return this.categoryDefinitions;
2466
+ }
2467
+ async _migrageFromLegacyMasterDB() {
2468
+ const e = this.ctx.storage.createDatabase("preferences", 1 / 0);
2469
+ let t = 0;
2470
+ for await (const [i, n] of e.entries())
2471
+ i !== "_touched" && (await this.db.set(i, n.value), t++);
2472
+ return t && this.logger.info(`Migrated ${t} preferences from master DB`), await e.clear(), await e?.db?.disconnect?.(), t;
2473
+ }
2474
+ }
2475
+ de = bi(Xe);
2476
+ F = xi(de, 0, "PreferencesService", Ge, F);
2477
+ Si(de, 1, F);
2478
+ const Ye = "", Ve = "", ki = /\\\{/g, Ei = /\\\}/g, Ci = new RegExp(Ye, "g"), Ii = new RegExp(Ve, "g");
2479
+ function $e(s) {
2480
+ const e = s ? { ...s } : void 0;
2481
+ return (i, ...n) => Li(e, i, ...n);
2482
+ }
2483
+ function Li(s, e, ...t) {
2484
+ if (!e) return "";
2485
+ let i = String(e).replace(ki, Ye).replace(Ei, Ve), n = {}, r = [];
2486
+ t.length === 1 && Array.isArray(t[0]) ? r = t[0] : t.length === 1 && Pi(t[0]) ? n = t[0] : t.length > 0 && (r = t);
2487
+ const o = /* @__PURE__ */ Object.create(null);
2488
+ if (r && r.length)
2489
+ for (let a = 0; a < r.length; a++)
2490
+ o[`$${a + 1}`] = r[a];
2491
+ if (n && Object.keys(n).length)
2492
+ for (const a of Object.keys(n)) o[a] = n[a];
2493
+ if (s && Object.keys(s).length)
2494
+ for (const a of Object.keys(s))
2495
+ typeof o[a] > "u" && (o[a] = s[a]);
2496
+ return i = i.replace(/\{\{\s*([\s\S]*?)\s*\}\}/g, (a, c) => {
2497
+ const l = String(c).trim();
2498
+ if (!l) return "";
2499
+ try {
2500
+ const h = Ai(l, o);
2501
+ return h == null ? "" : String(h);
2502
+ } catch {
2503
+ return "";
2504
+ }
2505
+ }), i.replace(Ci, "{").replace(Ii, "}");
2506
+ }
2507
+ function Pi(s) {
2508
+ return typeof s == "object" && s !== null && s.constructor === Object;
2509
+ }
2510
+ const Ai = Di();
2511
+ function Di() {
2512
+ const s = /* @__PURE__ */ new Set([
2513
+ "eval",
2514
+ "Object",
2515
+ "Array",
2516
+ "String",
2517
+ "Number",
2518
+ "Boolean",
2519
+ "Date",
2520
+ "Math",
2521
+ "JSON",
2522
+ "undefined",
2523
+ "null",
2524
+ "true",
2525
+ "false",
2526
+ "NaN",
2527
+ "Infinity",
2528
+ "isNaN",
2529
+ "isFinite",
2530
+ "parseInt",
2531
+ "parseFloat"
2532
+ ]), e = new Function(
2533
+ "__expr__",
2534
+ "ctx",
2535
+ `
2536
+ try {
2537
+ with (ctx) {
2538
+ return (eval(__expr__));
2539
+ }
2540
+ } catch (e) {
2541
+ throw e;
2542
+ }
2543
+ `
2544
+ );
2545
+ return (t, i) => {
2546
+ const n = new Proxy(i, {
2547
+ has: (r, o) => typeof o == "symbol" ? o in r : !(typeof o == "string" && (s.has(o) || o === "__expr__")),
2548
+ get: (r, o) => {
2549
+ if (o in r)
2550
+ return r[o];
2551
+ }
2552
+ });
2553
+ return e(t, n);
2554
+ };
2555
+ }
2556
+ function E(s, e) {
2557
+ let t = s[0] ?? "";
2558
+ for (let i = 0; i < e.length; i++)
2559
+ t += String(e[i]) + (s[i + 1] ?? "");
2560
+ return t;
2561
+ }
2562
+ class Ti {
2563
+ constructor(e, t) {
2564
+ this.languages = /* @__PURE__ */ new Map(), this.currentLanguage = "en", this.missingKeys = /* @__PURE__ */ new Map(), this.usedKeys = /* @__PURE__ */ new Set();
2565
+ const i = t?.language || "en";
2566
+ this.currentLanguage = i, this.interpolate = $e(t?.globals), e && Object.keys(e).length && this.setLanguageData(i, e);
2567
+ }
2568
+ setGlobals(e) {
2569
+ return this.interpolate = $e(e), this;
2570
+ }
2571
+ set(e, t) {
2572
+ const i = this.currentLanguage, n = this.ensureLanguageMap(i);
2573
+ if (typeof e == "string" && typeof t == "string")
2574
+ n.set(e, t);
2575
+ else if (typeof e == "object") {
2576
+ const r = this.toStringRecord(e);
2577
+ for (const [o, a] of Object.entries(r))
2578
+ n.set(o, a);
2579
+ }
2580
+ return this;
2581
+ }
2582
+ setLanguageData(e, t) {
2583
+ e = T(e).toLowerCase();
2584
+ const i = this.ensureLanguageMap(e), n = this.toStringRecord(t);
2585
+ for (const [r, o] of Object.entries(n))
2586
+ i.set(r, o);
2587
+ return this;
2588
+ }
2589
+ setLanguage(e) {
2590
+ return e = T(e).toLowerCase(), this.currentLanguage = e, this;
2591
+ }
2592
+ getLanguage() {
2593
+ return this.currentLanguage;
2594
+ }
2595
+ hasLanguage(e) {
2596
+ e = T(e).toLowerCase();
2597
+ const t = this.languages.get(e);
2598
+ return t && Object.keys(t).length > 0;
2599
+ }
2600
+ toStringRecord(e, t) {
2601
+ const i = {};
2602
+ for (const [n, r] of Object.entries(e)) {
2603
+ const o = t ? `${t}.${n}` : n;
2604
+ if (r && typeof r == "object" && !Array.isArray(r)) {
2605
+ const a = this.toStringRecord(r, o);
2606
+ for (const [c, l] of Object.entries(a))
2607
+ i[c] = String(l);
2608
+ } else
2609
+ i[o] = String(r);
2610
+ }
2611
+ return i;
2612
+ }
2613
+ has(e) {
2614
+ const t = this.resolveLanguageOrder(this.currentLanguage);
2615
+ for (const i of t)
2616
+ if (this.languages.get(i)?.has(e)) return !0;
2617
+ return !1;
2618
+ }
2619
+ get(e) {
2620
+ this.recordUsedKey(e);
2621
+ const t = this.resolveLanguageOrder(this.currentLanguage), i = [];
2622
+ for (const n of t) {
2623
+ const o = this.languages.get(n)?.get(e);
2624
+ if (typeof o < "u")
2625
+ return i.length && this.recordMissing(e, i), o;
2626
+ i.push(n);
2627
+ }
2628
+ i.length && this.recordMissing(e, i);
2629
+ }
2630
+ translate(e, ...t) {
2631
+ if (!e)
2632
+ return "";
2633
+ if (this.currentLanguage === "qqx")
2634
+ return `⧼${e}⧽`;
2635
+ const i = this.get(e);
2636
+ return typeof i > "u" ? this.interpolate(e, ...t) : this.interpolate(i, ...t);
2637
+ }
2638
+ $(...e) {
2639
+ if (Array.isArray(e[0]) && e[0]?.raw) {
2640
+ const n = e[0], r = e.slice(1), o = E(n, r);
2641
+ return this.translate(o);
2642
+ }
2643
+ const i = e;
2644
+ return (n, ...r) => {
2645
+ const o = E(n, r);
2646
+ return this.translate(o, ...i);
2647
+ };
2648
+ }
2649
+ /**
2650
+ * [payload as template] Return the raw message without interpolation
2651
+ * @example
2652
+ * ```
2653
+ * i18n.rawMsg('Hello, {{ name }}')
2654
+ * // good: "你好,{{ name }}"
2655
+ * // missing: "Hello, {{ name }}"
2656
+ * ```
2657
+ */
2658
+ translateRaw(e) {
2659
+ return e ? this.currentLanguage === "qqx" ? `⧼${e}⧽` : this.get(e) ?? e : "";
2660
+ }
2661
+ $raw(...e) {
2662
+ if (Array.isArray(e[0]) && e[0]?.raw) {
2663
+ const i = e[0], n = e.slice(1), r = E(i, n);
2664
+ return this.translateRaw(r);
2665
+ }
2666
+ return (i, ...n) => {
2667
+ const r = E(i, n);
2668
+ return this.translateRaw(r);
2669
+ };
2670
+ }
2671
+ message(e, ...t) {
2672
+ if (!e)
2673
+ return "";
2674
+ if (this.currentLanguage === "qqx")
2675
+ return `⧼${e}⧽`;
2676
+ const i = this.get(e);
2677
+ return typeof i > "u" ? `(${e})` : this.interpolate(i, ...t);
2678
+ }
2679
+ $$(...e) {
2680
+ if (Array.isArray(e[0]) && e[0]?.raw) {
2681
+ const n = e[0], r = e.slice(1), o = E(n, r);
2682
+ return this.message(o);
2683
+ }
2684
+ const i = e;
2685
+ return (n, ...r) => {
2686
+ const o = E(n, r);
2687
+ return this.message(o, ...i);
2688
+ };
2689
+ }
2690
+ /**
2691
+ * [payload as key] Return the raw message without interpolation
2692
+ * @example
2693
+ * ```
2694
+ * i18n.rawMsg('greeting')
2695
+ * // good: "你好,{{ name }}"
2696
+ * // missing: "(greeting)"
2697
+ * ```
2698
+ */
2699
+ messageRaw(e) {
2700
+ return e ? this.currentLanguage === "qqx" ? `⧼${e}⧽` : this.get(e) ?? `(${e})` : "";
2701
+ }
2702
+ $$raw(...e) {
2703
+ if (Array.isArray(e[0]) && e[0].raw) {
2704
+ const i = e[0], n = e.slice(1), r = E(i, n);
2705
+ return this.messageRaw(r);
2706
+ }
2707
+ return (i, ...n) => {
2708
+ const r = E(i, n);
2709
+ return this.messageRaw(r);
2710
+ };
2711
+ }
2712
+ getAvailableLanguages() {
2713
+ return Array.from(this.languages.keys());
2714
+ }
2715
+ ensureLanguageMap(e) {
2716
+ let t = this.languages.get(e);
2717
+ return t || (t = /* @__PURE__ */ new Map(), this.languages.set(e, t)), t;
2718
+ }
2719
+ resolveLanguageOrder(e) {
2720
+ const t = e;
2721
+ return t === "en" ? ["en"] : [t, "en"];
2722
+ }
2723
+ /**
2724
+ * 获取缺失键报告:
2725
+ * { foo: ['zh', 'zh-hans', 'en'] }
2726
+ */
2727
+ getMissingReport() {
2728
+ return Object.fromEntries(this.missingKeys.entries());
2729
+ }
2730
+ /**
2731
+ * 清空缺失键记录
2732
+ */
2733
+ clearMissingReport() {
2734
+ this.missingKeys.clear();
2735
+ }
2736
+ recordMissing(e, t) {
2737
+ if (!t.length) return;
2738
+ const i = this.missingKeys.get(e) || [];
2739
+ for (const n of t)
2740
+ i.includes(n) || i.push(n);
2741
+ this.missingKeys.set(e, i);
2742
+ }
2743
+ recordUsedKey(e) {
2744
+ this.usedKeys.add(e);
2745
+ }
2746
+ getUsedKeys() {
2747
+ return Array.from(this.usedKeys);
2748
+ }
2749
+ generateBlankKeyRecord() {
2750
+ const e = {};
2751
+ for (const t of this.getUsedKeys())
2752
+ e[t] = "";
2753
+ return e;
2754
+ }
2755
+ }
2756
+ var Ri = Object.create, ue = Object.defineProperty, Mi = Object.getOwnPropertyDescriptor, Ze = (s, e) => (e = Symbol[s]) ? e : Symbol.for("Symbol." + s), Je = (s) => {
2757
+ throw TypeError(s);
2758
+ }, Bi = (s, e, t) => e in s ? ue(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t, Oi = (s, e) => ue(s, "name", { value: e, configurable: !0 }), Ni = (s) => [, , , Ri(s?.[Ze("metadata")] ?? null)], Ui = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], Qe = (s) => s !== void 0 && typeof s != "function" ? Je("Function expected") : s, ji = (s, e, t, i, n) => ({ kind: Ui[s], name: e, metadata: i, addInitializer: (r) => t._ ? Je("Already initialized") : n.push(Qe(r || null)) }), Fi = (s, e) => Bi(e, Ze("metadata"), s[3]), zi = (s, e, t, i) => {
2759
+ for (var n = 0, r = s[e >> 1], o = r && r.length; n < o; n++) r[n].call(t);
2760
+ return i;
2761
+ }, Ki = (s, e, t, i, n, r) => {
2762
+ var o, a, c, l = e & 7, h = !1, d = 0, f = s[d] || (s[d] = []), u = l && (n = n.prototype, l < 5 && (l > 3 || !h) && Mi(n, t));
2763
+ Oi(n, t);
2764
+ for (var g = i.length - 1; g >= 0; g--)
2765
+ c = ji(l, t, a = {}, s[3], f), o = (0, i[g])(n, c), a._ = 1, Qe(o) && (n = o);
2766
+ return Fi(s, n), u && ue(n, t, u), h ? l ^ 4 ? r : u : n;
2767
+ }, et, fe, tt;
2768
+ const Se = new p(
2769
+ p.object({
2770
+ manifest_version: p.const(1).required(),
2771
+ base_language: p.string().required(),
2772
+ last_modified: p.string().required(),
2773
+ languages: p.dict(
2774
+ p.object({
2775
+ file: p.string().required(),
2776
+ fallback: p.string(),
2777
+ iso_name: p.string(),
2778
+ endonym: p.string(),
2779
+ data: p.transform(
2780
+ p.dict(p.any()).default({}),
2781
+ (s) => Object.keys(s).length > 0 ? s : void 0
2782
+ )
2783
+ })
2784
+ ).required()
2785
+ })
2786
+ );
2787
+ et = [H(["wiki", "preferences"]), at(
2788
+ p.object({
2789
+ "i18n.index_url": p.string().description("I18n index URL (DO NOT CHANGE THIS) ").default(
2790
+ ke.I18N_INDEX_URL
2791
+ )
2792
+ }).description("").extra("category", "general")
2793
+ )];
2794
+ class z extends (tt = C) {
2795
+ constructor(e) {
2796
+ super(e, "i18n", !1), this.ctx = e, this.logger = void 0, this._indexUrl = void 0, this._indexCache = null, this.manager = void 0, this.i18nIndexDB = void 0, this.i18nDataDB = void 0, this.$ = void 0, this.$raw = void 0, this.$$ = void 0, this.$$raw = void 0, this.logger = this.ctx.logger("I18nService"), this.manager = new Ti(
2797
+ {},
2798
+ {
2799
+ language: "",
2800
+ globals: {
2801
+ getUrl: (...t) => e.wiki.getUrl(...t)
2802
+ }
2803
+ }
2804
+ ), this.i18nIndexDB = e.storage.createDatabase(
2805
+ "i18n-index",
2806
+ 1e3 * 60 * 60 * 24 * 3,
2807
+ // 3 days
2808
+ this.ctx.version,
2809
+ "indexedDB"
2810
+ ), this.i18nDataDB = e.storage.createDatabase(
2811
+ "i18n-data",
2812
+ 1e3 * 60 * 60 * 24 * 3,
2813
+ // 3 days
2814
+ this.ctx.version,
2815
+ "indexedDB"
2816
+ ), this.$ = this.manager.$.bind(this.manager), this.$raw = this.manager.$raw.bind(this.manager), this.$$ = this.manager.$$.bind(this.manager), this.$$raw = this.manager.$$raw.bind(this.manager);
2817
+ }
2818
+ async start() {
2819
+ this.ctx.preferences.registerCustomConfig(
2820
+ "language",
2821
+ p.object({
2822
+ language: p.union([
2823
+ "@user",
2824
+ "@site",
2825
+ p.string().description("Custom language code")
2826
+ ]).description("UI language").default("@user")
2827
+ }).description("UI language")
2828
+ ), this.ctx.on("clear-cache", this.onClearCache.bind(this));
2829
+ const e = this._indexUrl = await this.ctx.preferences.get("i18n.index_url") || "";
2830
+ if (!e) {
2831
+ this.logger.error("I18n index URL is not set"), this.setupShortcuts();
2832
+ return;
2833
+ }
2834
+ let t = null;
2835
+ try {
2836
+ t = await this.getI18nIndex(e);
2837
+ } catch (r) {
2838
+ this.logger.error("Failed to fetch i18n index", r), this.setupShortcuts();
2839
+ return;
2840
+ }
2841
+ this._indexCache = t, Object.entries(t.languages).forEach(([r, o]) => {
2842
+ o.data && Object.keys(o.data).length > 0 && this.manager.setLanguageData(r, o.data);
2843
+ });
2844
+ const i = await this.ctx.preferences.get("language"), n = this.normalizeLanguageCode(i);
2845
+ this.logger.debug("Settings", { prefer: i, normalized: n });
2846
+ try {
2847
+ await this.switchLanguage(n), this.logger.info(`Initialized for language: ${this.language}`);
2848
+ } catch (r) {
2849
+ this.logger.error("Failed to fetch i18n index", r), this.manager.setLanguage("en");
2850
+ }
2851
+ this.ctx.preferences.registerCustomConfig(
2852
+ "language",
2853
+ p.object({
2854
+ language: p.union([
2855
+ p.const("@user").description(this.$`Same as your personal language`),
2856
+ p.const("@site").description(this.$`Same as the site language`),
2857
+ ...this.getAvailableLanguageCodes().map(
2858
+ ({ code: r, endonym: o, iso_name: a }) => p.const(r).description(o || a || r)
2859
+ )
2860
+ ]).default("@user")
2861
+ }).description(this.$`InPageEdit UI language`)
2862
+ ), this.setupShortcuts(), this.ctx.on("preferences/changed", async ({ changes: r }) => {
2863
+ if (!("language" in r)) return;
2864
+ const o = this.normalizeLanguageCode(await this.ctx.preferences.get("language"));
2865
+ o && o !== this.language && await this.switchLanguage(o);
2866
+ });
2867
+ }
2868
+ setupShortcuts() {
2869
+ if (!this.manager) throw new Error("I18nManager is not initialized");
2870
+ this.ctx.set("$", this.manager.$.bind(this.manager)), this.ctx.set("$raw", this.manager.$raw.bind(this.manager)), this.ctx.set("$$", this.manager.$$.bind(this.manager)), this.ctx.set("$$raw", this.manager.$$raw.bind(this.manager));
2871
+ }
2872
+ normalizeLanguageCode(e) {
2873
+ return !e || typeof e != "string" ? "en" : (e === "@user" && (e = this.ctx.wiki.userInfo.options.language || "en"), e === "@site" && (e = this.ctx.wiki.siteInfo.general.lang || "en"), T(String(e)).toLowerCase());
2874
+ }
2875
+ get language() {
2876
+ return this.manager.getLanguage();
2877
+ }
2878
+ /**
2879
+ * 主动设置偏好值(会触发 preferences/changed,从而热切换)
2880
+ */
2881
+ async setLanguagePreference(e) {
2882
+ await this.ctx.preferences.set("language", e);
2883
+ }
2884
+ /**
2885
+ * 直接切换到具体语言(不修改偏好值)
2886
+ */
2887
+ async switchLanguage(e) {
2888
+ const t = this.normalizeLanguageCode(e);
2889
+ await this.ensureLanguageLoaded(t), this.manager.setLanguage(t), this.ctx.emit("i18n/changed", { ctx: this.ctx, language: t });
2890
+ }
2891
+ /**
2892
+ * 为指定语言注册(或合并)消息。
2893
+ * - 推荐加命名空间避免冲突:{ myPlugin: { key: 'value' } }
2894
+ * - 若 language 为当前语言,将立即可用;必要时你可以手动触发 UI 刷新或监听 i18n/changed。
2895
+ */
2896
+ async registerMessages(e, t, i) {
2897
+ const n = i?.namespace ? { [i.namespace]: t } : t;
2898
+ this.manager.setLanguageData(e, n), e === this.language && this.ctx.emit("i18n/changed", { ctx: this.ctx, language: this.language });
2899
+ }
2900
+ /**
2901
+ * 列出可用语言与文件(来源于 index.json)
2902
+ */
2903
+ getAvailableLanguageCodes() {
2904
+ if (!this._indexCache) throw new Error("I18n index is not loaded");
2905
+ return Object.entries(this._indexCache.languages).filter(([e, t]) => !t.fallback).reduce(
2906
+ (e, [t, i]) => (e.push({ code: t, ...i }), e),
2907
+ []
2908
+ );
2909
+ }
2910
+ findLanguageMeta(e, t) {
2911
+ const i = T(String(t)).toLowerCase(), n = e.languages[i];
2912
+ if (n)
2913
+ return {
2914
+ code: i,
2915
+ ...n
2916
+ };
2917
+ {
2918
+ const r = e.languages.en;
2919
+ if (r)
2920
+ return {
2921
+ code: "en",
2922
+ ...r
2923
+ };
2924
+ }
2925
+ }
2926
+ async getI18nIndex(e, t = !1) {
2927
+ if (!t) {
2928
+ const n = await this.i18nIndexDB.get(e);
2929
+ if (n)
2930
+ try {
2931
+ return Se(n);
2932
+ } catch (r) {
2933
+ this.logger.error("Failed to parse cached i18n index", r), this.i18nIndexDB.delete(e);
2934
+ }
2935
+ }
2936
+ const i = await this.fetchI18nIndex(e);
2937
+ return this.i18nIndexDB.set(e, i), i;
2938
+ }
2939
+ async fetchI18nIndex(e) {
2940
+ const t = await fetch(e).then((i) => i.json());
2941
+ return Se(t);
2942
+ }
2943
+ async ensureLanguageLoaded(e) {
2944
+ if (!this.manager || !this._indexCache) throw new Error("I18nManager is not initialized");
2945
+ if (this.manager.hasLanguage(e))
2946
+ return this.logger.debug("Language already loaded", e);
2947
+ const t = await this.getLanguageData(e);
2948
+ this.manager.setLanguageData(e, t), this.logger.debug("Language data ensured", e, t);
2949
+ }
2950
+ async getLanguageData(e, t = !1) {
2951
+ if (!this._indexCache) throw new Error("I18n index is not loaded");
2952
+ const i = this.findLanguageMeta(this._indexCache, e);
2953
+ if (!i) return {};
2954
+ const n = `${this._indexUrl}#${i.file}`;
2955
+ if (!t) {
2956
+ const o = await this.i18nDataDB.get(n);
2957
+ if (o && Object.keys(o).length > 0)
2958
+ return this.logger.debug("Using cached language data", e, o), o;
2959
+ }
2960
+ const r = i.data || await fetch(new URL(i.file, this._indexUrl).toString()).then((o) => o.json());
2961
+ return this.i18nDataDB.set(n, r), this.logger.debug("Language data fetched", e, i.file, r), r;
2962
+ }
2963
+ /**
2964
+ * 获取缺失键报告,形如:
2965
+ * { foo: ['zh', 'zh-hans', 'en'] }
2966
+ */
2967
+ getMissingReport() {
2968
+ return this.manager.getMissingReport();
2969
+ }
2970
+ /**
2971
+ * 清空缺失键记录
2972
+ */
2973
+ clearMissingReport() {
2974
+ this.manager.clearMissingReport();
2975
+ }
2976
+ async onClearCache() {
2977
+ await this.i18nIndexDB.clear(), await this.i18nDataDB.clear();
2978
+ }
2979
+ }
2980
+ fe = Ni(tt);
2981
+ z = Ki(fe, 0, "I18nService", et, z);
2982
+ zi(fe, 1, z);
2983
+ class K extends lt {
2984
+ constructor(e) {
2985
+ super({
2986
+ name: "InPageEdit"
2987
+ }), this.version = "0.14.3", this.Endpoints = ke, this.schema = p, this.config = ct(K.DEFAULT_CONFIG, e), this.logger = gt({
2988
+ name: "IPE",
2989
+ color: "#33aaff",
2990
+ level: this.config.logLevel
2991
+ }), this.#e();
2992
+ }
2993
+ static {
2994
+ this.DEFAULT_CONFIG = {
2995
+ apiConfigs: {},
2996
+ legacyPreferences: {},
2997
+ logLevel: Ee.info,
2998
+ storageNamespace: "InPageEdit",
2999
+ autoloadStyles: !0,
3000
+ autoInstallCorePlugins: !0
3001
+ };
3002
+ }
3003
+ async #e() {
3004
+ await this.#i(), this.config.autoInstallCorePlugins && this.#s(), this.#n();
3005
+ }
3006
+ async #i() {
3007
+ this.plugin(z), this.plugin(pt, this.config.apiConfigs), this.plugin(N), this.plugin(Et), this.plugin(Jt), this.plugin(F), this.plugin(fi, { dbName: this.config.storageNamespace }), this.plugin(j), this.plugin(gi), this.plugin(ce), this.#t([
3008
+ "i18n",
3009
+ "$",
3010
+ "$$",
3011
+ "api",
3012
+ "currentPage",
3013
+ "resourceLoader",
3014
+ "modal",
3015
+ "preferences",
3016
+ "storage",
3017
+ "wikiPage",
3018
+ "wikiTitle",
3019
+ // WikiMetadataService
3020
+ "wiki",
3021
+ "getUrl",
3022
+ "getSciprtUrl",
3023
+ "getMainpageUrl"
3024
+ ]);
3025
+ }
3026
+ #t(e) {
3027
+ if (!Array.isArray(e) || e.length === 0) return this;
3028
+ for (const t of e) {
3029
+ const i = this[K.internal][t];
3030
+ i?.type === "service" && (i.builtin = !0);
3031
+ }
3032
+ return this;
3033
+ }
3034
+ // TODO: 这里不应该硬编码,暂时先这样
3035
+ async #s() {
3036
+ [
3037
+ import("./index-BanevHQ2.js").then(({ PluginAnalytics: t }) => t),
3038
+ import("./index-DVOc6fB6.js").then(
3039
+ ({ PluginInArticleLinks: t }) => t
3040
+ ),
3041
+ import("./index-DrIf5j8O.js").then(({ PluginPluginStore: t }) => t),
3042
+ import("./index-DKCZDN-Q.js").then(
3043
+ ({ PluginPreferencesUI: t }) => t
3044
+ ),
3045
+ import("./index-WfXtYVMt.js").then(({ PluginQuickEdit: t }) => t),
3046
+ import("./index-DensW9qt.js").then(({ PluginQuickMove: t }) => t),
3047
+ import("./index-BXNyXvre.js").then(
3048
+ ({ PluginQuickPreview: t }) => t
3049
+ ),
3050
+ import("./index-BpQ6VGMz.js").then(({ PluginQuickDiff: t }) => t),
3051
+ import("./index-De25v1_Q.js").then(
3052
+ ({ PluginQuickRedirect: t }) => t
3053
+ ),
3054
+ import("./index-CnR6CqkM.js").then(({ PluginToolbox: t }) => t)
3055
+ ].forEach(async (t) => {
3056
+ this.plugin(await t);
3057
+ });
3058
+ }
3059
+ // TODO: 应该抽象到 PluginTheme 中去,暂时先硬编码
3060
+ async #n() {
3061
+ this.inject(["resourceLoader"], (e) => {
3062
+ this.config.autoloadStyles && e.resourceLoader.loadStyle(import.meta.resolve("./style.css"));
3063
+ });
3064
+ }
3065
+ async withInject(e) {
3066
+ const { promise: t, resolve: i } = xe();
3067
+ return this.inject(e, (n) => {
3068
+ i(n);
3069
+ }), t;
3070
+ }
3071
+ }
3072
+ export {
3073
+ Ee as $,
3074
+ pt as A,
3075
+ N as C,
3076
+ K as I,
3077
+ Jt as M,
3078
+ U as N,
3079
+ oe as P,
3080
+ Et as R,
3081
+ gt as S,
3082
+ j as W,
3083
+ fi as a,
3084
+ y as b,
3085
+ F as c,
3086
+ gi as d,
3087
+ ce as e,
3088
+ te as m
3089
+ };
3090
+ //# sourceMappingURL=index-MgXERLzL.js.map