bc-deeplib 1.1.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/deeplib.js CHANGED
@@ -28,7 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  // node_modules/.pnpm/bondage-club-mod-sdk@1.2.0/node_modules/bondage-club-mod-sdk/dist/bcmodsdk.js
29
29
  var require_bcmodsdk = __commonJS({
30
30
  "node_modules/.pnpm/bondage-club-mod-sdk@1.2.0/node_modules/bondage-club-mod-sdk/dist/bcmodsdk.js"(exports) {
31
- var bcModSdk = function() {
31
+ var bcModSdk = (function() {
32
32
  "use strict";
33
33
  const o = "1.2.0";
34
34
  function e(o2) {
@@ -44,7 +44,7 @@ var require_bcmodsdk = __commonJS({
44
44
  __name(n, "n");
45
45
  function r(o2) {
46
46
  const e2 = /* @__PURE__ */ new Set();
47
- return o2.filter((o3) => !e2.has(o3) && e2.add(o3));
47
+ return o2.filter(((o3) => !e2.has(o3) && e2.add(o3)));
48
48
  }
49
49
  __name(r, "r");
50
50
  const i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set();
@@ -67,13 +67,13 @@ Patch2:
67
67
  ${a2}`), t2.set(e3, a2), n2.add(r3.name);
68
68
  }
69
69
  }
70
- e2.sort((o3, e3) => e3.priority - o3.priority);
71
- const r2 = function(o3, e3) {
70
+ e2.sort(((o3, e3) => e3.priority - o3.priority));
71
+ const r2 = (function(o3, e3) {
72
72
  if (0 === e3.size) return o3;
73
73
  let t3 = o3.toString().replaceAll("\r\n", "\n");
74
74
  for (const [n3, r3] of e3.entries()) t3.includes(n3) || c(`ModSDK: Patching ${o3.name}: Patch ${n3} not applied`), t3 = t3.replaceAll(n3, r3);
75
75
  return (0, eval)(`(${t3})`);
76
- }(o2.original, t2);
76
+ })(o2.original, t2);
77
77
  let i2 = /* @__PURE__ */ __name(function(e3) {
78
78
  var t3, i3;
79
79
  const a2 = null === (i3 = (t3 = m.errorReporterHooks).hookChainExit) || void 0 === i3 ? void 0 : i3.call(t3, o2.name, n2), c2 = r2.apply(this, e3);
@@ -102,7 +102,7 @@ ${a2}`), t2.set(e3, a2), n2.add(r3.name);
102
102
  for (let t2 = 0; t2 < a2.length - 1; t2++) if (e3 = e3[a2[t2]], !n(e3)) throw new Error(`ModSDK: Function ${o2} to be patched not found; ${a2.slice(0, t2 + 1).join(".")} is not object`);
103
103
  const c2 = e3[a2[a2.length - 1]];
104
104
  if ("function" != typeof c2) throw new Error(`ModSDK: Function ${o2} to be patched not found`);
105
- const l2 = function(o3) {
105
+ const l2 = (function(o3) {
106
106
  let e4 = -1;
107
107
  for (const n2 of t.encode(o3)) {
108
108
  let o4 = 255 & (e4 ^ n2);
@@ -110,13 +110,13 @@ ${a2}`), t2.set(e3, a2), n2.add(r3.name);
110
110
  e4 = e4 >>> 8 ^ o4;
111
111
  }
112
112
  return ((-1 ^ e4) >>> 0).toString(16).padStart(8, "0").toUpperCase();
113
- }(c2.toString().replaceAll("\r\n", "\n")), d2 = { name: o2, original: c2, originalHash: l2 };
113
+ })(c2.toString().replaceAll("\r\n", "\n")), d2 = { name: o2, original: c2, originalHash: l2 };
114
114
  r2 = Object.assign(Object.assign({}, d2), { precomputed: s(d2), router: /* @__PURE__ */ __name(() => {
115
- }, "router"), context: e3, contextProperty: a2[a2.length - 1] }), r2.router = /* @__PURE__ */ function(o3) {
115
+ }, "router"), context: e3, contextProperty: a2[a2.length - 1] }), r2.router = /* @__PURE__ */ (function(o3) {
116
116
  return function(...e4) {
117
117
  return o3.precomputed.enter.apply(this, [e4]);
118
118
  };
119
- }(r2), i.set(o2, r2), e3[r2.contextProperty] = r2.router;
119
+ })(r2), i.set(o2, r2), e3[r2.contextProperty] = r2.router;
120
120
  }
121
121
  return r2;
122
122
  }
@@ -127,7 +127,7 @@ ${a2}`), t2.set(e3, a2), n2.add(r3.name);
127
127
  __name(d, "d");
128
128
  function p() {
129
129
  const o2 = /* @__PURE__ */ new Map();
130
- for (const [e2, t2] of i) o2.set(e2, { name: e2, original: t2.original, originalHash: t2.originalHash, sdkEntrypoint: t2.router, currentEntrypoint: t2.context[t2.contextProperty], hookedByMods: r(t2.precomputed.hooks.map((o3) => o3.mod)), patchedByMods: Array.from(t2.precomputed.patchesSources) });
130
+ for (const [e2, t2] of i) o2.set(e2, { name: e2, original: t2.original, originalHash: t2.originalHash, sdkEntrypoint: t2.router, currentEntrypoint: t2.context[t2.contextProperty], hookedByMods: r(t2.precomputed.hooks.map(((o3) => o3.mod))), patchedByMods: Array.from(t2.precomputed.patchesSources) });
131
131
  return o2;
132
132
  }
133
133
  __name(p, "p");
@@ -152,7 +152,7 @@ Was the mod loaded multiple times?`), u(a2));
152
152
  g2.loaded || e(`Mod ${r2} attempted to call SDK function after being unloaded`);
153
153
  const s3 = t3(...n2);
154
154
  return null == c3 || c3(), s3;
155
- }, "s"), p2 = { unload: s2("unload", () => u(g2)), hookFunction: s2("hookFunction", (o3, t3, n2) => {
155
+ }, "s"), p2 = { unload: s2("unload", (() => u(g2))), hookFunction: s2("hookFunction", ((o3, t3, n2) => {
156
156
  "string" == typeof o3 && o3 || e(`Mod ${r2} failed to patch a function: Expected function name string, got ${typeof o3}`);
157
157
  const i3 = l(o3), a3 = c2(i3);
158
158
  "number" != typeof t3 && e(`Mod ${r2} failed to hook function '${o3}': Expected priority number, got ${typeof t3}`), "function" != typeof n2 && e(`Mod ${r2} failed to hook function '${o3}': Expected hook function, got ${typeof n2}`);
@@ -161,24 +161,24 @@ Was the mod loaded multiple times?`), u(a2));
161
161
  const o4 = a3.hooks.indexOf(s3);
162
162
  o4 >= 0 && (a3.hooks.splice(o4, 1), d());
163
163
  };
164
- }), patchFunction: s2("patchFunction", (o3, t3) => {
164
+ })), patchFunction: s2("patchFunction", ((o3, t3) => {
165
165
  "string" == typeof o3 && o3 || e(`Mod ${r2} failed to patch a function: Expected function name string, got ${typeof o3}`);
166
166
  const i3 = l(o3), a3 = c2(i3);
167
167
  n(t3) || e(`Mod ${r2} failed to patch function '${o3}': Expected patches object, got ${typeof t3}`);
168
168
  for (const [n2, i4] of Object.entries(t3)) "string" == typeof i4 ? a3.patches.set(n2, i4) : null === i4 ? a3.patches.delete(n2) : e(`Mod ${r2} failed to patch function '${o3}': Invalid format of patch '${n2}'`);
169
169
  d();
170
- }), removePatches: s2("removePatches", (o3) => {
170
+ })), removePatches: s2("removePatches", ((o3) => {
171
171
  "string" == typeof o3 && o3 || e(`Mod ${r2} failed to patch a function: Expected function name string, got ${typeof o3}`);
172
172
  const t3 = l(o3);
173
173
  c2(t3).patches.clear(), d();
174
- }), callOriginal: s2("callOriginal", (o3, t3, n2) => {
174
+ })), callOriginal: s2("callOriginal", ((o3, t3, n2) => {
175
175
  "string" == typeof o3 && o3 || e(`Mod ${r2} failed to call a function: Expected function name string, got ${typeof o3}`);
176
176
  const i3 = l(o3);
177
177
  return Array.isArray(t3) || e(`Mod ${r2} failed to call a function: Expected args array, got ${typeof t3}`), i3.original.apply(null != n2 ? n2 : globalThis, t3);
178
- }), getOriginalHash: s2("getOriginalHash", (o3) => {
178
+ })), getOriginalHash: s2("getOriginalHash", ((o3) => {
179
179
  "string" == typeof o3 && o3 || e(`Mod ${r2} failed to get hash: Expected function name string, got ${typeof o3}`);
180
180
  return l(o3).originalHash;
181
- }) }, g2 = { name: o2.name, fullName: o2.fullName, version: o2.version, repository: o2.repository, allowReplace: i2, api: p2, loaded: true, patching: /* @__PURE__ */ new Map() };
181
+ })) }, g2 = { name: o2.name, fullName: o2.fullName, version: o2.version, repository: o2.repository, allowReplace: i2, api: p2, loaded: true, patching: /* @__PURE__ */ new Map() };
182
182
  return f.set(o2.name, g2), Object.freeze(p2);
183
183
  }
184
184
  __name(g, "g");
@@ -189,13 +189,13 @@ Was the mod loaded multiple times?`), u(a2));
189
189
  }
190
190
  __name(h, "h");
191
191
  let m;
192
- const y = void 0 === window.bcModSdk ? window.bcModSdk = function() {
192
+ const y = void 0 === window.bcModSdk ? window.bcModSdk = (function() {
193
193
  const e2 = { version: o, apiVersion: 1, registerMod: g, getModsInfo: h, getPatchingInfo: p, errorReporterHooks: Object.seal({ apiEndpointEnter: null, hookEnter: null, hookChainExit: null }) };
194
194
  return m = e2, Object.freeze(e2);
195
- }() : (n(window.bcModSdk) || e("Failed to init Mod SDK: Name already in use"), 1 !== window.bcModSdk.apiVersion && e(`Failed to init Mod SDK: Different version already loaded ('1.2.0' vs '${window.bcModSdk.version}')`), window.bcModSdk.version !== o && alert(`Mod SDK warning: Loading different but compatible versions ('1.2.0' vs '${window.bcModSdk.version}')
195
+ })() : (n(window.bcModSdk) || e("Failed to init Mod SDK: Name already in use"), 1 !== window.bcModSdk.apiVersion && e(`Failed to init Mod SDK: Different version already loaded ('1.2.0' vs '${window.bcModSdk.version}')`), window.bcModSdk.version !== o && alert(`Mod SDK warning: Loading different but compatible versions ('1.2.0' vs '${window.bcModSdk.version}')
196
196
  One of mods you are using is using an old version of SDK. It will work for now but please inform author to update`), window.bcModSdk);
197
197
  return "undefined" != typeof exports && (Object.defineProperty(exports, "__esModule", { value: true }), exports.default = y), y;
198
- }();
198
+ })();
199
199
  }
200
200
  });
201
201
 
@@ -297,12 +297,13 @@ var BaseModule = class {
297
297
  };
298
298
 
299
299
  // src/base/base_subscreen.ts
300
- function setSubscreen(subscreen) {
300
+ async function setSubscreen(subscreen) {
301
301
  if (!GUI.instance) {
302
302
  throw new Error("Attempt to set subscreen before init");
303
303
  }
304
- GUI.instance.currentSubscreen = subscreen;
305
- return GUI.instance.currentSubscreen;
304
+ const screenName = typeof subscreen === "string" ? subscreen : subscreen?.options.name;
305
+ const screenId = `${BaseSubscreen.id}_${screenName}`;
306
+ await CommonSetScreen(...["DeepLibMod", `${screenId}`]);
306
307
  }
307
308
  __name(setSubscreen, "setSubscreen");
308
309
  var BaseSubscreen = class _BaseSubscreen {
@@ -317,28 +318,36 @@ var BaseSubscreen = class _BaseSubscreen {
317
318
  options;
318
319
  /** Reference to the module this subscreen belongs to. */
319
320
  module;
320
- constructor(subscreenOptions, module) {
321
+ /** Identifier for internal use to avoid screen name collisions. */
322
+ static id = CommonGenerateUniqueID();
323
+ /** Optional configuration flags for a BaseSubscreen instance. */
324
+ static subscreenOptions = {
325
+ drawCharacter: true,
326
+ name: "UNKNOWN",
327
+ icon: "",
328
+ background: "Sheet"
329
+ };
330
+ constructor(module) {
321
331
  if (module) this.module = module;
322
- this.options = subscreenOptions || {};
323
- }
324
- /**
325
- * Logical name of this subscreen.
326
- * Used for localization key resolution in `load()`.
327
- * Subclasses should override this with a meaningful identifier.
328
- */
329
- get name() {
330
- return "UNKNOWN";
331
- }
332
- /**
333
- * Path to or Base64 data for an icon representing this subscreen.
334
- * Defaults to empty string (no icon).
335
- */
336
- get icon() {
337
- return "";
332
+ const ctor = this.constructor;
333
+ this.options = {
334
+ ..._BaseSubscreen.subscreenOptions,
335
+ ...ctor.subscreenOptions
336
+ };
337
+ const screenName = this.options.name;
338
+ const screenId = `${_BaseSubscreen.id}_${screenName}`;
339
+ exportToGlobal(`${screenId}Load`, this.load.bind(this));
340
+ exportToGlobal(`${screenId}Run`, this.run.bind(this));
341
+ exportToGlobal(`${screenId}Click`, this.click.bind(this));
342
+ exportToGlobal(`${screenId}Exit`, this.exit.bind(this));
343
+ exportToGlobal(`${screenId}Unload`, this.unload.bind(this));
344
+ exportToGlobal(`${screenId}Resize`, this.resize.bind(this));
345
+ exportToGlobal(`${screenId}Background`, this.options.background);
346
+ CommonCSVCache[ScreenFileGetTranslation("DeepLibMod", screenId)] = [];
338
347
  }
339
348
  /** Changes the currently active subscreen. */
340
- setSubscreen(screen) {
341
- return setSubscreen(screen);
349
+ async setSubscreen(screen) {
350
+ return await setSubscreen(screen);
342
351
  }
343
352
  /** Gets this subscreen's settings object from its parent module. */
344
353
  get settings() {
@@ -361,6 +370,12 @@ var BaseSubscreen = class _BaseSubscreen {
361
370
  get currentPage() {
362
371
  return this.pageStructure[Math.min(_BaseSubscreen.currentPage - 1, this.pageStructure.length - 1)];
363
372
  }
373
+ getPageLabel() {
374
+ return CommonStringPartitionReplace(getText("settings.page.label"), {
375
+ $currentPage$: `${_BaseSubscreen.currentPage}`,
376
+ $totalPages$: `${this.pageStructure.length}`
377
+ }).join("");
378
+ }
364
379
  /**
365
380
  * Changes the visible page in a multi-page subscreen.
366
381
  * Automatically wraps around when going past the first or last page.
@@ -371,7 +386,7 @@ var BaseSubscreen = class _BaseSubscreen {
371
386
  if (page < 1) page = totalPages;
372
387
  _BaseSubscreen.currentPage = page;
373
388
  this.managePageElementsVisibility();
374
- setLabel(`${_BaseSubscreen.currentPage} of ${this.pageStructure.length}`);
389
+ setLabel(this.getPageLabel());
375
390
  }
376
391
  /**
377
392
  * Updates the DOM to show only elements belonging to the current page.
@@ -407,8 +422,8 @@ var BaseSubscreen = class _BaseSubscreen {
407
422
  if (!module.settings || !Object.keys(module.settings).length) module.registerDefaultSettings();
408
423
  }
409
424
  _BaseSubscreen.currentPage = 1;
410
- layout.createSubscreen();
411
- const settingsElement = layout.createSettingsDiv();
425
+ layout.getSubscreen();
426
+ const settingsElement = layout.getSettingsDiv();
412
427
  layout.appendToSubscreen(settingsElement);
413
428
  const menu = ElementMenu.Create("deeplib-nav-menu", []);
414
429
  layout.appendToSubscreen(menu);
@@ -419,24 +434,50 @@ var BaseSubscreen = class _BaseSubscreen {
419
434
  initialNextTooltip: getText("settings.button.next_button_hint"),
420
435
  back: /* @__PURE__ */ __name(({ setLabel }) => this.changePage(_BaseSubscreen.currentPage - 1, setLabel), "back"),
421
436
  initialPrevTooltip: getText("settings.button.prev_button_hint"),
422
- initialLabel: `${_BaseSubscreen.currentPage} of ${this.pageStructure.length}`
437
+ initialLabel: this.getPageLabel()
423
438
  });
424
439
  ElementMenu.PrependItem(menu, backNext);
425
440
  }
441
+ if (this.options.help) {
442
+ const onClick = this.options.help.onClick;
443
+ let action = /* @__PURE__ */ __name(() => {
444
+ }, "action");
445
+ if (typeof onClick === "string" || onClick instanceof URL) {
446
+ action = /* @__PURE__ */ __name(() => window.open(onClick, "_blank"), "action");
447
+ } else if (typeof onClick === "function") {
448
+ action = onClick;
449
+ } else if (onClick instanceof _BaseSubscreen) {
450
+ action = /* @__PURE__ */ __name(async () => await this.setSubscreen(onClick), "action");
451
+ }
452
+ this.options.help.tooltip ??= getText("settings.button.help_button_hint");
453
+ this.options.help.icon ??= `${PUBLIC_URL}/dl_images/bookmark.svg`;
454
+ const helpButton = advElement.createButton({
455
+ id: "deeplib-help",
456
+ size: [90, 90],
457
+ onClick: action,
458
+ options: {
459
+ image: this.options.help.icon,
460
+ tooltip: this.options.help.tooltip
461
+ }
462
+ });
463
+ ElementMenu.AppendButton(menu, helpButton);
464
+ }
426
465
  const subscreenTitle = advElement.createLabel({
427
466
  id: "deeplib-subscreen-title",
428
- label: getText(`${this.name}.title`).replace("$ModVersion", ModSdkManager.ModInfo.version)
467
+ label: getText(`${this.options.name}.title`).replace("$ModVersion", ModSdkManager.ModInfo.version)
429
468
  });
430
469
  layout.appendToSubscreen(subscreenTitle);
431
- if (this.name !== "mainmenu") {
470
+ if (this.options.name !== "mainmenu") {
432
471
  const exitButton = advElement.createButton({
433
472
  id: "deeplib-exit",
434
473
  size: [90, 90],
435
- image: `${PUBLIC_URL}/dl_images/exit.svg`,
436
474
  onClick: /* @__PURE__ */ __name(() => {
437
475
  this.exit();
438
476
  }, "onClick"),
439
- tooltip: getText("settings.button.back_button_hint")
477
+ options: {
478
+ image: `${PUBLIC_URL}/dl_images/exit.svg`,
479
+ tooltip: getText("settings.button.back_button_hint")
480
+ }
440
481
  });
441
482
  ElementMenu.AppendButton(menu, exitButton);
442
483
  }
@@ -491,21 +532,29 @@ var BaseSubscreen = class _BaseSubscreen {
491
532
  exit() {
492
533
  CharacterAppearanceForceUpCharacter = -1;
493
534
  CharacterLoadCanvas(Player);
494
- setSubscreen("mainmenu");
495
- modStorage.save();
535
+ const returnScreen = typeof this.options.returnScreen === "function" ? this.options.returnScreen() : this.options.returnScreen;
536
+ if (returnScreen instanceof _BaseSubscreen || !returnScreen) {
537
+ setSubscreen(returnScreen ?? "mainmenu").then(() => {
538
+ modStorage.save();
539
+ });
540
+ } else if (Array.isArray(returnScreen)) {
541
+ CommonSetScreen(...returnScreen).then(() => {
542
+ modStorage.save();
543
+ });
544
+ }
496
545
  }
497
546
  /**
498
547
  * Called when the window is resized.
499
548
  * Also checks for overflow in the settings div and applies styling accordingly.
500
549
  */
501
- resize(onLoad = false) {
550
+ resize(_onLoad = false) {
502
551
  const offset = this.options.drawCharacter ? 0 : 380;
503
552
  const subscreen = layout.getSubscreen();
504
553
  const settingsDiv = layout.getSettingsDiv();
505
554
  ElementSetPosition(subscreen || "", 0, 0);
506
555
  ElementSetSize(subscreen || "", 2e3, 1e3);
507
556
  ElementSetFontSize(subscreen || "", "auto");
508
- if (this.name === "mainmenu") {
557
+ if (this.options.name === "mainmenu") {
509
558
  ElementSetPosition(settingsDiv || "", 530 - offset, 170);
510
559
  ElementSetSize(settingsDiv || "", 600 + offset, 660);
511
560
  } else {
@@ -519,9 +568,10 @@ var BaseSubscreen = class _BaseSubscreen {
519
568
  ElementSetPosition(advElement.getTooltip() || "", 250, 850);
520
569
  ElementSetSize(advElement.getTooltip() || "", 1500, 70);
521
570
  _BaseSubscreen.currentElements.forEach((item) => {
571
+ const element = item[0];
522
572
  const options = item[1];
523
- domUtil.autoSetPosition(options.id, options.position);
524
- domUtil.autoSetSize(options.id, options.size);
573
+ domUtil.autoSetPosition(options.id ?? element.id, options.position);
574
+ domUtil.autoSetSize(options.id ?? element.id, options.size);
525
575
  });
526
576
  if (settingsDiv) {
527
577
  if (domUtil.hasOverflow(settingsDiv)?.vertical) {
@@ -548,6 +598,7 @@ var styles_default = `.deeplib-subscreen,
548
598
  --deeplib-background-color: var(--tmd-main, white);
549
599
  --deeplib-element-color: var(--tmd-element, white);
550
600
  --deeplib-element-hover-color: var(--tmd-element-hover, cyan);
601
+ --deeplib-accent-color: var(--tmd-accent, #FFFF88);
551
602
  --deeplib-blocked-color: var(--tmd-blocked, red);
552
603
  --deeplib-text-color: var(--tmd-text, black);
553
604
  --deeplib-icon-color: var(--tmd-accent, black);
@@ -635,7 +686,6 @@ var styles_default = `.deeplib-subscreen,
635
686
  grid-auto-rows: min-content;
636
687
  padding: min(1dvh, 0.5dvw);
637
688
  gap: 0.3em;
638
- overflow-y: scroll;
639
689
  }
640
690
 
641
691
  .deeplib-misc {
@@ -655,6 +705,7 @@ var styles_default = `.deeplib-subscreen,
655
705
  padding: min(1vh, 0.5vw);
656
706
  font-size: 0.8em;
657
707
  border: min(0.2vh, 0.1vw) solid var(--deeplib-border-color);
708
+ z-index: 1;
658
709
  }
659
710
 
660
711
  .deeplib-overflow-box {
@@ -672,14 +723,14 @@ var styles_default = `.deeplib-subscreen,
672
723
  border-radius: min(1dvh, 0.5dvw);
673
724
  border: min(0.2vh, 0.1vw) solid var(--deeplib-border-color);
674
725
  }
675
- .deeplib-prev-next .deeplib-prev-next-button {
676
- height: 100%;
677
- aspect-ratio: 1;
678
- }
679
726
  .deeplib-prev-next .deeplib-prev-next-button:hover {
680
727
  background-color: var(--deeplib-element-hover-color);
681
728
  border-radius: var(--deeplib-border-radius);
682
729
  }
730
+ .deeplib-prev-next .deeplib-prev-next-button {
731
+ height: 100%;
732
+ aspect-ratio: 1;
733
+ }
683
734
  .deeplib-prev-next .deeplib-prev-next-label {
684
735
  white-space: nowrap;
685
736
  }
@@ -690,6 +741,25 @@ var styles_default = `.deeplib-subscreen,
690
741
  gap: min(2dvh, 1dvw);
691
742
  }
692
743
 
744
+ #deeplib-storage-meter {
745
+ position: absolute;
746
+ top: 0px;
747
+ left: 0px;
748
+ width: 100%;
749
+ height: 100%;
750
+ overflow: hidden;
751
+ background-color: var(--deeplib-element-color);
752
+ border: var(--deeplib-border-width) solid var(--deeplib-border-color);
753
+ border-radius: var(--deeplib-border-radius);
754
+ z-index: -1;
755
+ }
756
+
757
+ #deeplib-storage-bar {
758
+ height: 100%;
759
+ width: 0%;
760
+ background: var(--deeplib-accent-color);
761
+ }
762
+
693
763
  .deeplib-checkbox-container {
694
764
  display: flex;
695
765
  flex-direction: row;
@@ -829,6 +899,12 @@ input[type=number] {
829
899
  .deeplib-modal .deeplib-modal-button-container .deeplib-button .button-label {
830
900
  display: contents;
831
901
  }
902
+ .deeplib-modal .deeplib-modal-prompt-container {
903
+ display: flex;
904
+ flex-direction: column;
905
+ justify-content: center;
906
+ align-items: center;
907
+ }
832
908
 
833
909
  .deeplib-modal-blocker {
834
910
  z-index: 1000;
@@ -839,12 +915,13 @@ input[type=number] {
839
915
  height: 100dvh;
840
916
  background-color: rgba(0, 0, 0, 0.5);
841
917
  }
842
- /*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VSb290IjoiL21lZGlhL05WTUUvU3R1ZmYvQ29kZS9CQy9CQy1EZWVwTGliL3NyYy9zdHlsZXMiLCJzb3VyY2VzIjpbInZhcnMuc2NzcyIsImJ1dHRvbnMuc2NzcyIsImVsZW1lbnRzLnNjc3MiLCJpbnB1dHMuc2NzcyIsIm1lc3NhZ2VzLnNjc3MiLCJtb2RhbC5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7RUFFRTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7OztBQ2JGO0VBQ0U7RUFDQTtFQUNBOzs7QUFHRjtBQUFBO0VBRUU7OztBQUdGO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUVBO0VBQ0E7RUFDQTs7O0FBR0Y7RUFDRTs7O0FBR0Y7RUFDRTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7OztBQzNDRjtFQUNFO0VBQ0E7RUFDQTs7O0FBR0Y7RUFDRTtFQUNBOzs7QUFHRjtFQUNFOzs7QUFHRjtFQUNFO0VBQ0E7RUFDQTs7O0FBR0Y7RUFDRTtFQUNBOzs7QUFHRjtFQUNFO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOzs7QUFHRjtFQUNFOzs7QUFHRjtFQUNFO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTs7QUFFQTtFQU1FO0VBQ0E7O0FBTkE7RUFDRTtFQUNBOztBQU9KO0VBQ0U7OztBQUlKO0VBQ0U7RUFDQTtFQUNBOzs7QUN0RkY7RUFDRTtFQUNBO0VBQ0E7RUFDQTs7O0FBR0Y7RUFDRTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTs7O0FBR0Y7RUFDRTtFQUNBO0VBQ0E7RUFDQTs7O0FBR0Y7RUFDRTs7O0FBR0Y7RUFDRTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOzs7QUFJRjtFQUNFO0VBQ0E7RUFDQTtFQUNBOzs7QUFHRjtFQUNFO0VBQ0E7OztBQUdGO0FBQUE7RUFFRTtFQUNBOzs7QUFHRjtFQUNFO0VBQ0E7OztBQzdERjtFQUNFO0VBQ0E7OztBQUdGO0FBQUE7RUFFRTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOzs7QUFHRjtBQUFBO0VBRUU7OztBQUdGO0VBQ0U7RUFDQTtFQUNBOzs7QUM3QkY7RUFDRTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOztBQUVBO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7O0FBR0Y7RUFDRTs7QUFHRjtFQUNFO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7O0FBRUE7RUFDRTtFQUNBO0VBQ0E7RUFDQTs7QUFFQTtFQUNFOzs7QUFNUjtFQUNFO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBIiwic291cmNlc0NvbnRlbnQiOlsiLmRlZXBsaWItc3Vic2NyZWVuLFxuLmRlZXBsaWItbW9kYWwge1xuICAtLWRlZXBsaWItYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tdG1kLW1haW4sIHdoaXRlKTtcbiAgLS1kZWVwbGliLWVsZW1lbnQtY29sb3I6IHZhcigtLXRtZC1lbGVtZW50LCB3aGl0ZSk7XG4gIC0tZGVlcGxpYi1lbGVtZW50LWhvdmVyLWNvbG9yOiB2YXIoLS10bWQtZWxlbWVudC1ob3ZlciwgY3lhbik7XG4gIC0tZGVlcGxpYi1ibG9ja2VkLWNvbG9yOiB2YXIoLS10bWQtYmxvY2tlZCwgcmVkKTtcbiAgLS1kZWVwbGliLXRleHQtY29sb3I6IHZhcigtLXRtZC10ZXh0LCBibGFjayk7XG4gIC0tZGVlcGxpYi1pY29uLWNvbG9yOiB2YXIoLS10bWQtYWNjZW50LCBibGFjayk7XG4gIC0tZGVlcGxpYi1pY29uLWhvdmVyLWNvbG9yOiB2YXIoLS10bWQtYWNjZW50LWhvdmVyLCBibGFjayk7XG4gIC0tZGVlcGxpYi1ib3JkZXItY29sb3I6IHZhcigtLXRtZC1hY2NlbnQsIGJsYWNrKTtcbiAgLS1kZWVwbGliLWJvcmRlci13aWR0aDogbWluKDAuMnZoLCAwLjF2dyk7XG4gIC0tZGVlcGxpYi1ib3JkZXItd2lkdGg6IG1pbigwLjJkdmgsIDAuMWR2dyk7XG4gIC0tZGVlcGxpYi1ib3JkZXItcmFkaXVzOiBtaW4oMXZoLCAwLjV2dyk7XG4gIC0tZGVlcGxpYi1ib3JkZXItcmFkaXVzOiBtaW4oMWR2aCwgMC41ZHZ3KTtcbn1cbiIsIi5kZWVwbGliLWJ1dHRvbiB7XG4gIGNvbG9yOiB2YXIoLS1kZWVwbGliLXRleHQtY29sb3IpO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xufVxuXG4uZGVlcGxpYi1idXR0b24uYnV0dG9uLXN0eWxpbmcsXG4uZGVlcGxpYi1idXR0b24uYnV0dG9uLXN0eWxpbmc6OmJlZm9yZSB7XG4gIGJvcmRlci1yYWRpdXM6IG1pbigxLjBkdmgsIDAuNWR2dyk7XG59XG5cbi5kZWVwbGliLWJ1dHRvbiBpbWcge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMCU7XG4gIGxlZnQ6IDAlO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBsZWZ0O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1kZWVwbGliLWljb24tY29sb3IpO1xuICBiYWNrZ3JvdW5kLWJsZW5kLW1vZGU6IG11bHRpcGx5O1xuICBiYWNrZ3JvdW5kLXNpemU6IGNvbnRhaW47XG4gIG1hc2stcG9zaXRpb246IGxlZnQ7XG4gIG1hc2stc2l6ZTogY29udGFpbjtcbiAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcbiAgbWFzay1yZXBlYXQ6IG5vLXJlcGVhdDtcbiAgY29sb3I6IHRyYW5zcGFyZW50O1xuXG4gIGJhY2tncm91bmQtaW1hZ2U6IHZhcigtLWltYWdlKTtcbiAgbWFzay1pbWFnZTogdmFyKC0taW1hZ2UpO1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cblxuLmRlZXBsaWItYnV0dG9uOmhvdmVyIGltZyB7XG4gIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWRlZXBsaWItaWNvbi1ob3Zlci1jb2xvcik7XG59XG5cbi5kZWVwbGliLWJ1dHRvbiAuYnV0dG9uLWxhYmVsIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQgIWltcG9ydGFudDtcbiAgY29sb3I6IHZhcigtLWRlZXBsaWItdGV4dC1jb2xvcik7XG4gIGZvbnQtc2l6ZTogbWluKDMuNmR2aCwgMS44ZHZ3KTtcbn1cblxuLmRlZXBsaWItYnV0dG9uIC5idXR0b24tdG9vbHRpcCB7XG4gIGJvcmRlci1yYWRpdXM6IG1pbigxLjBkdmgsIDAuNWR2dyk7XG59XG4iLCIjZGVlcGxpYi1wYWdlLWxhYmVsIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG59XG5cbiNkZWVwbGliLXN1YnNjcmVlbi10aXRsZSB7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG4gIGNvbG9yOiB2YXIoLS1kZWVwbGliLXRleHQtY29sb3IpO1xufVxuXG4uZGVlcGxpYi10ZXh0IHtcbiAgY29sb3I6IHZhcigtLWRlZXBsaWItdGV4dC1jb2xvcik7XG59XG5cbi5kZWVwbGliLXN1YnNjcmVlbiB7XG4gIHBhZGRpbmc6IDA7XG4gIG1hcmdpbjogMDtcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG5cbi5kZWVwbGliLXN1YnNjcmVlbiAqIHtcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgcG9pbnRlci1ldmVudHM6IGFsbDtcbn1cblxuLmRlZXBsaWItc2V0dGluZ3Mge1xuICBkaXNwbGF5OiBncmlkO1xuICBncmlkLWF1dG8tcm93czogbWluLWNvbnRlbnQ7XG4gIHBhZGRpbmc6IG1pbigxLjBkdmgsIDAuNWR2dyk7XG4gIGdhcDogMC4zZW07XG4gIG92ZXJmbG93LXk6IHNjcm9sbDtcbn1cblxuLmRlZXBsaWItbWlzYyB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW4tcmV2ZXJzZTtcbiAgZ2FwOiBtaW4oMXZoLCAwLjV2dyk7XG59XG5cbi5kZWVwbGliLXRvb2x0aXAge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1kZWVwbGliLWVsZW1lbnQtY29sb3IpO1xuICBjb2xvcjogdmFyKC0tZGVlcGxpYi10ZXh0LWNvbG9yKTtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIGJvcmRlci1yYWRpdXM6IG1pbigxLjBkdmgsIDAuNWR2dyk7XG4gIHBhZGRpbmc6IG1pbigxdmgsIDAuNXZ3KTtcbiAgZm9udC1zaXplOiAwLjhlbTtcbiAgYm9yZGVyOiBtaW4oMC4ydmgsIDAuMXZ3KSBzb2xpZCB2YXIoLS1kZWVwbGliLWJvcmRlci1jb2xvcik7XG59XG5cbi5kZWVwbGliLW92ZXJmbG93LWJveCB7XG4gIGJvcmRlcjogdmFyKC0tZGVlcGxpYi1ib3JkZXItY29sb3IpIHNvbGlkIHZhcigtLWRlZXBsaWItYm9yZGVyLXdpZHRoKTtcbn1cblxuLmRlZXBsaWItcHJldi1uZXh0IHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICBnYXA6IG1pbigyZHZoLCAxZHZ3KTtcbiAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tZGVlcGxpYi1lbGVtZW50LWNvbG9yKTtcbiAgY29sb3I6IHZhcigtLWRlZXBsaWItdGV4dC1jb2xvcik7XG4gIGJvcmRlci1yYWRpdXM6IG1pbigxLjBkdmgsIDAuNWR2dyk7XG4gIGJvcmRlcjogbWluKDAuMnZoLCAwLjF2dykgc29saWQgdmFyKC0tZGVlcGxpYi1ib3JkZXItY29sb3IpO1xuXG4gIC5kZWVwbGliLXByZXYtbmV4dC1idXR0b24ge1xuICAgICY6aG92ZXIge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tZGVlcGxpYi1lbGVtZW50LWhvdmVyLWNvbG9yKTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLWRlZXBsaWItYm9yZGVyLXJhZGl1cyk7XG4gICAgfVxuICAgIFxuICAgIGhlaWdodDogMTAwJTtcbiAgICBhc3BlY3QtcmF0aW86IDE7XG4gIH1cblxuICAuZGVlcGxpYi1wcmV2LW5leHQtbGFiZWwge1xuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIH1cbn1cblxuI2RlZXBsaWItbmF2LW1lbnUge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICBnYXA6IG1pbigyZHZoLCAxZHZ3KTtcbn0iLCIuZGVlcGxpYi1jaGVja2JveC1jb250YWluZXIge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDAuM2VtO1xufVxuXG4uZGVlcGxpYi1jaGVja2JveC1jb250YWluZXIgaW5wdXQuZGVlcGxpYi1pbnB1dCB7XG4gIHdpZHRoOiBtaW4oNXZoLCAyLjV2dyk7XG4gIGhlaWdodDogbWluKDV2aCwgMi41dncpO1xuICBib3JkZXItcmFkaXVzOiBtaW4oMS4wZHZoLCAwLjVkdncpO1xufVxuXG4uZGVlcGxpYi1jaGVja2JveC1jb250YWluZXIgaW5wdXQuZGVlcGxpYi1pbnB1dFt0eXBlPVwiY2hlY2tib3hcIl06Y2hlY2tlZDo6YmVmb3JlIHtcbiAgd2lkdGg6IDgwJTtcbiAgaGVpZ2h0OiA4MCU7XG59XG5cbi5kZWVwbGliLWlucHV0LWNvbnRhaW5lciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogMC4zZW07XG59XG5cbi5kZWVwbGliLWlucHV0LWNvbnRhaW5lcjpoYXMobGFiZWwuZGVlcGxpYi10ZXh0KSB7XG4gIG1hcmdpbi10b3A6IG1pbigxdmgsIDAuNXZ3KTtcbn1cblxuLmRlZXBsaWItaW5wdXQtY29udGFpbmVyIGlucHV0LmRlZXBsaWItaW5wdXQge1xuICBmb250LXNpemU6IDAuNmVtO1xuICBwYWRkaW5nOiA1cHggMDtcbiAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gIG91dGxpbmU6IG5vbmU7XG4gIHBhZGRpbmctbGVmdDogbWluKDF2aCwgMC41dncpO1xuICBwYWRkaW5nLXJpZ2h0OiBtaW4oMXZoLCAwLjV2dyk7XG4gIG1pbi1oZWlnaHQ6IG1pbig1ZHZoLCAyLjVkdncpO1xuICBib3JkZXItcmFkaXVzOiBtaW4oMS4wZHZoLCAwLjVkdncpO1xufVxuXG5cbi5kZWVwbGliLWlucHV0LWNvbnRhaW5lciBpbnB1dC5kZWVwbGliLWlucHV0W3R5cGU9XCJjb2xvclwiXSB7XG4gIHBhZGRpbmc6IDBweDtcbiAgd2lkdGg6IG1pbig1dmgsIDIuNXZ3KTtcbiAgaGVpZ2h0OiBtaW4oNXZoLCAyLjV2dyk7XG4gIGJvcmRlci1yYWRpdXM6IDBweDtcbn1cblxuLmRlZXBsaWItaW5wdXQtY29udGFpbmVyIGlucHV0LmRlZXBsaWItaW5wdXRbdHlwZT1cImNvbG9yXCJdOmRpc2FibGVkIHtcbiAgYm9yZGVyOiB2YXIoLS1kZWVwbGliLWJsb2NrZWQtY29sb3IpIHNvbGlkIHZhcigtLWRlZXBsaWItYm9yZGVyLXdpZHRoKTtcbiAgY3Vyc29yOiBub3QtYWxsb3dlZDtcbn1cblxuaW5wdXQ6Oi13ZWJraXQtb3V0ZXItc3Bpbi1idXR0b24sXG5pbnB1dDo6LXdlYmtpdC1pbm5lci1zcGluLWJ1dHRvbiB7XG4gIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcbiAgbWFyZ2luOiAwO1xufVxuXG5pbnB1dFt0eXBlPW51bWJlcl0ge1xuICBhcHBlYXJhbmNlOiB0ZXh0ZmllbGQ7XG4gIC1tb3otYXBwZWFyYW5jZTogdGV4dGZpZWxkO1xufVxuIiwiLmRlZXBsaWItaGlnaGxpZ2h0LXRleHQge1xuICBmb250LXdlaWdodDogYm9sZDtcbiAgY29sb3I6IHJnYigyMDMsIDE4NSwgMjMpO1xufVxuXG4jVGV4dEFyZWFDaGF0TG9nW2RhdGEtY29sb3J0aGVtZT0nZGFyayddIGRpdi5DaGF0TWVzc2FnZS5kZWVwbGliLW1lc3NhZ2UsXG4jVGV4dEFyZWFDaGF0TG9nW2RhdGEtY29sb3J0aGVtZT0nZGFyazInXSBkaXYuQ2hhdE1lc3NhZ2UuZGVlcGxpYi1tZXNzYWdlIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tZGVlcGxpYi1lbGVtZW50LWNvbG9yKTtcbiAgYm9yZGVyOiBtaW4oMC4yZHZoLCAwLjFkdncpIHNvbGlkIHZhcigtLWRlZXBsaWItYm9yZGVyLWNvbG9yKTtcbiAgY29sb3I6IHZhcigtLWRlZXBsaWItdGV4dC1jb2xvcik7XG59XG5cbiNUZXh0QXJlYUNoYXRMb2cgZGl2LkNoYXRNZXNzYWdlLmRlZXBsaWItbWVzc2FnZSB7XG4gIGJhY2tncm91bmQtY29sb3I6ICNlZWU7XG4gIGJvcmRlcjogbWluKDAuMmR2aCwgMC4xZHZ3KSBzb2xpZCAjNDQwMTcxO1xuICBjb2xvcjogIzExMTtcbiAgcGFkZGluZy1sZWZ0OiBtaW4oMC42ZHZoLCAwLjNkdncpO1xuICBkaXNwbGF5OiBibG9jaztcbiAgd2hpdGUtc3BhY2U6IG5vcm1hbDtcbn1cblxuI1RleHRBcmVhQ2hhdExvZ1tkYXRhLWNvbG9ydGhlbWU9J2RhcmsnXSBkaXYuQ2hhdE1lc3NhZ2UuZGVlcGxpYi1tZXNzYWdlIGEsXG4jVGV4dEFyZWFDaGF0TG9nW2RhdGEtY29sb3J0aGVtZT0nZGFyazInXSBkaXYuQ2hhdE1lc3NhZ2UuZGVlcGxpYi1tZXNzYWdlIGEge1xuICBjb2xvcjogdmFyKC0tZGVlcGxpYi10ZXh0LWNvbG9yKTtcbn1cblxuI1RleHRBcmVhQ2hhdExvZyBkaXYuQ2hhdE1lc3NhZ2UuZGVlcGxpYi1tZXNzYWdlIGEge1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xuICBjb2xvcjogIzExMTtcbn1cbiIsIi5kZWVwbGliLW1vZGFsIHtcbiAgcG9zaXRpb246IGZpeGVkO1xuICB0b3A6IDEwJTtcbiAgbGVmdDogNTAlO1xuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTUwJSk7XG4gIHotaW5kZXg6IDEwMDE7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDAuNWVtO1xuICB3aWR0aDogbWF4KDUwZHZ3LCAyNWR2aCk7XG4gIGZvbnQtc2l6ZTogbWluKDRkdmgsIDJkdncpO1xuICBwYWRkaW5nOiBtaW4oMmR2aCwgMWR2dyk7XG4gIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWRlZXBsaWItZWxlbWVudC1jb2xvcik7XG4gIGJvcmRlci1yYWRpdXM6IG1pbigxLjJkdmgsIDAuNmR2dyk7XG4gIGJvcmRlcjogbWluKDAuMmR2aCwgMC4xZHZ3KSBzb2xpZCB2YXIoLS1kZWVwbGliLWJvcmRlci1jb2xvcik7XG4gIGNvbG9yOiB2YXIoLS1kZWVwbGliLXRleHQtY29sb3IpO1xuXG4gIC5kZWVwbGliLW1vZGFsLWlucHV0IHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBmb250LXNpemU6IG1pbigyLjZkdmgsIDEuOGR2dyk7XG4gICAgYm9yZGVyLXJhZGl1czogbWluKDEuMGR2aCwgMC41ZHZ3KTtcbiAgICBwYWRkaW5nOiBtaW4oMWR2aCwgMC41ZHZ3KTtcbiAgfVxuXG4gIGlucHV0LmRlZXBsaWItbW9kYWwtaW5wdXQge1xuICAgIG1heC13aWR0aDogbWF4KDUwZHZoLCAyNWR2dyk7XG4gIH1cblxuICAuZGVlcGxpYi1tb2RhbC1idXR0b24tY29udGFpbmVyIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gICAganVzdGlmeS1jb250ZW50OiBmbGV4LWVuZDtcbiAgICBnYXA6IDAuNWVtO1xuICAgIHdpZHRoOiAxMDAlO1xuXG4gICAgLmRlZXBsaWItYnV0dG9uIHtcbiAgICAgIGZvbnQtc2l6ZTogMC44ZW07XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgd2lkdGg6IGF1dG87XG4gICAgICBwYWRkaW5nOiBtaW4oMC40dmgsIDAuMnZ3KSBtaW4oMnZoLCAxdncpO1xuXG4gICAgICAuYnV0dG9uLWxhYmVsIHtcbiAgICAgICAgZGlzcGxheTogY29udGVudHM7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi5kZWVwbGliLW1vZGFsLWJsb2NrZXIge1xuICB6LWluZGV4OiAxMDAwO1xuICBwb3NpdGlvbjogZml4ZWQ7XG4gIHRvcDogMDtcbiAgbGVmdDogMDtcbiAgd2lkdGg6IDEwMGR2dztcbiAgaGVpZ2h0OiAxMDBkdmg7XG4gIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41KTtcbn1cbiJdfQ== */`;
918
+ /*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VSb290IjoiL21lZGlhL05WTUUvU3R1ZmYvQ29kZS9CQy9CQy1EZWVwTGliL3NyYy9zdHlsZXMiLCJzb3VyY2VzIjpbInZhcnMuc2NzcyIsImJ1dHRvbnMuc2NzcyIsImVsZW1lbnRzLnNjc3MiLCJpbnB1dHMuc2NzcyIsIm1lc3NhZ2VzLnNjc3MiLCJtb2RhbC5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7RUFFRTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTs7O0FDZEY7RUFDRTtFQUNBO0VBQ0E7OztBQUdGO0FBQUE7RUFFRTs7O0FBR0Y7RUFDRTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBRUE7RUFDQTtFQUNBOzs7QUFHRjtFQUNFOzs7QUFHRjtFQUNFO0VBQ0E7RUFDQTs7O0FBR0Y7RUFDRTs7O0FDM0NGO0VBQ0U7RUFDQTtFQUNBOzs7QUFHRjtFQUNFO0VBQ0E7OztBQUdGO0VBQ0U7OztBQUdGO0VBQ0U7RUFDQTtFQUNBOzs7QUFHRjtFQUNFO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7OztBQUdGO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOztBQUdFO0VBQ0U7RUFDQTs7QUFISjtFQU1FO0VBQ0E7O0FBR0Y7RUFDRTs7O0FBSUo7RUFDRTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTtFQUNBOzs7QUN6R0Y7RUFDRTtFQUNBO0VBQ0E7RUFDQTs7O0FBR0Y7RUFDRTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTs7O0FBR0Y7RUFDRTtFQUNBO0VBQ0E7RUFDQTs7O0FBR0Y7RUFDRTs7O0FBR0Y7RUFDRTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOzs7QUFJRjtFQUNFO0VBQ0E7RUFDQTtFQUNBOzs7QUFHRjtFQUNFO0VBQ0E7OztBQUdGO0FBQUE7RUFFRTtFQUNBOzs7QUFHRjtFQUNFO0VBQ0E7OztBQzdERjtFQUNFO0VBQ0E7OztBQUdGO0FBQUE7RUFFRTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOzs7QUFHRjtBQUFBO0VBRUU7OztBQUdGO0VBQ0U7RUFDQTtFQUNBOzs7QUM3QkY7RUFDRTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOztBQUVBO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7O0FBR0Y7RUFDRTs7QUFHRjtFQUNFO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7O0FBRUE7RUFDRTtFQUNBO0VBQ0E7RUFDQTs7QUFFQTtFQUNFOztBQUtOO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7OztBQUlKO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0EiLCJzb3VyY2VzQ29udGVudCI6WyIuZGVlcGxpYi1zdWJzY3JlZW4sXG4uZGVlcGxpYi1tb2RhbCB7XG4gIC0tZGVlcGxpYi1iYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS10bWQtbWFpbiwgd2hpdGUpO1xuICAtLWRlZXBsaWItZWxlbWVudC1jb2xvcjogdmFyKC0tdG1kLWVsZW1lbnQsIHdoaXRlKTtcbiAgLS1kZWVwbGliLWVsZW1lbnQtaG92ZXItY29sb3I6IHZhcigtLXRtZC1lbGVtZW50LWhvdmVyLCBjeWFuKTtcbiAgLS1kZWVwbGliLWFjY2VudC1jb2xvcjogdmFyKC0tdG1kLWFjY2VudCwgI0ZGRkY4OCk7XG4gIC0tZGVlcGxpYi1ibG9ja2VkLWNvbG9yOiB2YXIoLS10bWQtYmxvY2tlZCwgcmVkKTtcbiAgLS1kZWVwbGliLXRleHQtY29sb3I6IHZhcigtLXRtZC10ZXh0LCBibGFjayk7XG4gIC0tZGVlcGxpYi1pY29uLWNvbG9yOiB2YXIoLS10bWQtYWNjZW50LCBibGFjayk7XG4gIC0tZGVlcGxpYi1pY29uLWhvdmVyLWNvbG9yOiB2YXIoLS10bWQtYWNjZW50LWhvdmVyLCBibGFjayk7XG4gIC0tZGVlcGxpYi1ib3JkZXItY29sb3I6IHZhcigtLXRtZC1hY2NlbnQsIGJsYWNrKTtcbiAgLS1kZWVwbGliLWJvcmRlci13aWR0aDogbWluKDAuMnZoLCAwLjF2dyk7XG4gIC0tZGVlcGxpYi1ib3JkZXItd2lkdGg6IG1pbigwLjJkdmgsIDAuMWR2dyk7XG4gIC0tZGVlcGxpYi1ib3JkZXItcmFkaXVzOiBtaW4oMXZoLCAwLjV2dyk7XG4gIC0tZGVlcGxpYi1ib3JkZXItcmFkaXVzOiBtaW4oMWR2aCwgMC41ZHZ3KTtcbn1cbiIsIi5kZWVwbGliLWJ1dHRvbiB7XG4gIGNvbG9yOiB2YXIoLS1kZWVwbGliLXRleHQtY29sb3IpO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xufVxuXG4uZGVlcGxpYi1idXR0b24uYnV0dG9uLXN0eWxpbmcsXG4uZGVlcGxpYi1idXR0b24uYnV0dG9uLXN0eWxpbmc6OmJlZm9yZSB7XG4gIGJvcmRlci1yYWRpdXM6IG1pbigxLjBkdmgsIDAuNWR2dyk7XG59XG5cbi5kZWVwbGliLWJ1dHRvbiBpbWcge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMCU7XG4gIGxlZnQ6IDAlO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBsZWZ0O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1kZWVwbGliLWljb24tY29sb3IpO1xuICBiYWNrZ3JvdW5kLWJsZW5kLW1vZGU6IG11bHRpcGx5O1xuICBiYWNrZ3JvdW5kLXNpemU6IGNvbnRhaW47XG4gIG1hc2stcG9zaXRpb246IGxlZnQ7XG4gIG1hc2stc2l6ZTogY29udGFpbjtcbiAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcbiAgbWFzay1yZXBlYXQ6IG5vLXJlcGVhdDtcbiAgY29sb3I6IHRyYW5zcGFyZW50O1xuXG4gIGJhY2tncm91bmQtaW1hZ2U6IHZhcigtLWltYWdlKTtcbiAgbWFzay1pbWFnZTogdmFyKC0taW1hZ2UpO1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cblxuLmRlZXBsaWItYnV0dG9uOmhvdmVyIGltZyB7XG4gIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWRlZXBsaWItaWNvbi1ob3Zlci1jb2xvcik7XG59XG5cbi5kZWVwbGliLWJ1dHRvbiAuYnV0dG9uLWxhYmVsIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQgIWltcG9ydGFudDtcbiAgY29sb3I6IHZhcigtLWRlZXBsaWItdGV4dC1jb2xvcik7XG4gIGZvbnQtc2l6ZTogbWluKDMuNmR2aCwgMS44ZHZ3KTtcbn1cblxuLmRlZXBsaWItYnV0dG9uIC5idXR0b24tdG9vbHRpcCB7XG4gIGJvcmRlci1yYWRpdXM6IG1pbigxLjBkdmgsIDAuNWR2dyk7XG59XG4iLCIjZGVlcGxpYi1wYWdlLWxhYmVsIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG59XG5cbiNkZWVwbGliLXN1YnNjcmVlbi10aXRsZSB7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG4gIGNvbG9yOiB2YXIoLS1kZWVwbGliLXRleHQtY29sb3IpO1xufVxuXG4uZGVlcGxpYi10ZXh0IHtcbiAgY29sb3I6IHZhcigtLWRlZXBsaWItdGV4dC1jb2xvcik7XG59XG5cbi5kZWVwbGliLXN1YnNjcmVlbiB7XG4gIHBhZGRpbmc6IDA7XG4gIG1hcmdpbjogMDtcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG5cbi5kZWVwbGliLXN1YnNjcmVlbiAqIHtcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgcG9pbnRlci1ldmVudHM6IGFsbDtcbn1cblxuLmRlZXBsaWItc2V0dGluZ3Mge1xuICBkaXNwbGF5OiBncmlkO1xuICBncmlkLWF1dG8tcm93czogbWluLWNvbnRlbnQ7XG4gIHBhZGRpbmc6IG1pbigxLjBkdmgsIDAuNWR2dyk7XG4gIGdhcDogMC4zZW07XG59XG5cbi5kZWVwbGliLW1pc2Mge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uLXJldmVyc2U7XG4gIGdhcDogbWluKDF2aCwgMC41dncpO1xufVxuXG4uZGVlcGxpYi10b29sdGlwIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tZGVlcGxpYi1lbGVtZW50LWNvbG9yKTtcbiAgY29sb3I6IHZhcigtLWRlZXBsaWItdGV4dC1jb2xvcik7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICBib3JkZXItcmFkaXVzOiBtaW4oMS4wZHZoLCAwLjVkdncpO1xuICBwYWRkaW5nOiBtaW4oMXZoLCAwLjV2dyk7XG4gIGZvbnQtc2l6ZTogMC44ZW07XG4gIGJvcmRlcjogbWluKDAuMnZoLCAwLjF2dykgc29saWQgdmFyKC0tZGVlcGxpYi1ib3JkZXItY29sb3IpO1xuICB6LWluZGV4OiAxO1xufVxuXG4uZGVlcGxpYi1vdmVyZmxvdy1ib3gge1xuICBib3JkZXI6IHZhcigtLWRlZXBsaWItYm9yZGVyLWNvbG9yKSBzb2xpZCB2YXIoLS1kZWVwbGliLWJvcmRlci13aWR0aCk7XG59XG5cbi5kZWVwbGliLXByZXYtbmV4dCB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgZ2FwOiBtaW4oMmR2aCwgMWR2dyk7XG4gIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWRlZXBsaWItZWxlbWVudC1jb2xvcik7XG4gIGNvbG9yOiB2YXIoLS1kZWVwbGliLXRleHQtY29sb3IpO1xuICBib3JkZXItcmFkaXVzOiBtaW4oMS4wZHZoLCAwLjVkdncpO1xuICBib3JkZXI6IG1pbigwLjJ2aCwgMC4xdncpIHNvbGlkIHZhcigtLWRlZXBsaWItYm9yZGVyLWNvbG9yKTtcblxuICAuZGVlcGxpYi1wcmV2LW5leHQtYnV0dG9uIHtcbiAgICAmOmhvdmVyIHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWRlZXBsaWItZWxlbWVudC1ob3Zlci1jb2xvcik7XG4gICAgICBib3JkZXItcmFkaXVzOiB2YXIoLS1kZWVwbGliLWJvcmRlci1yYWRpdXMpO1xuICAgIH1cbiAgICBcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgYXNwZWN0LXJhdGlvOiAxO1xuICB9XG5cbiAgLmRlZXBsaWItcHJldi1uZXh0LWxhYmVsIHtcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICB9XG59XG5cbiNkZWVwbGliLW5hdi1tZW51IHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgZ2FwOiBtaW4oMmR2aCwgMWR2dyk7XG59XG5cbiNkZWVwbGliLXN0b3JhZ2UtbWV0ZXIge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMHB4O1xuICBsZWZ0OiAwcHg7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWRlZXBsaWItZWxlbWVudC1jb2xvcik7XG4gIGJvcmRlcjogdmFyKC0tZGVlcGxpYi1ib3JkZXItd2lkdGgpIHNvbGlkIHZhcigtLWRlZXBsaWItYm9yZGVyLWNvbG9yKTtcbiAgYm9yZGVyLXJhZGl1czogdmFyKC0tZGVlcGxpYi1ib3JkZXItcmFkaXVzKTtcbiAgei1pbmRleDogLTE7XG59XG5cbiNkZWVwbGliLXN0b3JhZ2UtYmFyIHtcbiAgaGVpZ2h0OiAxMDAlO1xuICB3aWR0aDogMCU7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRlZXBsaWItYWNjZW50LWNvbG9yKTtcbn1cbiIsIi5kZWVwbGliLWNoZWNrYm94LWNvbnRhaW5lciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogMC4zZW07XG59XG5cbi5kZWVwbGliLWNoZWNrYm94LWNvbnRhaW5lciBpbnB1dC5kZWVwbGliLWlucHV0IHtcbiAgd2lkdGg6IG1pbig1dmgsIDIuNXZ3KTtcbiAgaGVpZ2h0OiBtaW4oNXZoLCAyLjV2dyk7XG4gIGJvcmRlci1yYWRpdXM6IG1pbigxLjBkdmgsIDAuNWR2dyk7XG59XG5cbi5kZWVwbGliLWNoZWNrYm94LWNvbnRhaW5lciBpbnB1dC5kZWVwbGliLWlucHV0W3R5cGU9XCJjaGVja2JveFwiXTpjaGVja2VkOjpiZWZvcmUge1xuICB3aWR0aDogODAlO1xuICBoZWlnaHQ6IDgwJTtcbn1cblxuLmRlZXBsaWItaW5wdXQtY29udGFpbmVyIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiAwLjNlbTtcbn1cblxuLmRlZXBsaWItaW5wdXQtY29udGFpbmVyOmhhcyhsYWJlbC5kZWVwbGliLXRleHQpIHtcbiAgbWFyZ2luLXRvcDogbWluKDF2aCwgMC41dncpO1xufVxuXG4uZGVlcGxpYi1pbnB1dC1jb250YWluZXIgaW5wdXQuZGVlcGxpYi1pbnB1dCB7XG4gIGZvbnQtc2l6ZTogMC42ZW07XG4gIHBhZGRpbmc6IDVweCAwO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgb3V0bGluZTogbm9uZTtcbiAgcGFkZGluZy1sZWZ0OiBtaW4oMXZoLCAwLjV2dyk7XG4gIHBhZGRpbmctcmlnaHQ6IG1pbigxdmgsIDAuNXZ3KTtcbiAgbWluLWhlaWdodDogbWluKDVkdmgsIDIuNWR2dyk7XG4gIGJvcmRlci1yYWRpdXM6IG1pbigxLjBkdmgsIDAuNWR2dyk7XG59XG5cblxuLmRlZXBsaWItaW5wdXQtY29udGFpbmVyIGlucHV0LmRlZXBsaWItaW5wdXRbdHlwZT1cImNvbG9yXCJdIHtcbiAgcGFkZGluZzogMHB4O1xuICB3aWR0aDogbWluKDV2aCwgMi41dncpO1xuICBoZWlnaHQ6IG1pbig1dmgsIDIuNXZ3KTtcbiAgYm9yZGVyLXJhZGl1czogMHB4O1xufVxuXG4uZGVlcGxpYi1pbnB1dC1jb250YWluZXIgaW5wdXQuZGVlcGxpYi1pbnB1dFt0eXBlPVwiY29sb3JcIl06ZGlzYWJsZWQge1xuICBib3JkZXI6IHZhcigtLWRlZXBsaWItYmxvY2tlZC1jb2xvcikgc29saWQgdmFyKC0tZGVlcGxpYi1ib3JkZXItd2lkdGgpO1xuICBjdXJzb3I6IG5vdC1hbGxvd2VkO1xufVxuXG5pbnB1dDo6LXdlYmtpdC1vdXRlci1zcGluLWJ1dHRvbixcbmlucHV0Ojotd2Via2l0LWlubmVyLXNwaW4tYnV0dG9uIHtcbiAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lO1xuICBtYXJnaW46IDA7XG59XG5cbmlucHV0W3R5cGU9bnVtYmVyXSB7XG4gIGFwcGVhcmFuY2U6IHRleHRmaWVsZDtcbiAgLW1vei1hcHBlYXJhbmNlOiB0ZXh0ZmllbGQ7XG59XG4iLCIuZGVlcGxpYi1oaWdobGlnaHQtdGV4dCB7XG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xuICBjb2xvcjogcmdiKDIwMywgMTg1LCAyMyk7XG59XG5cbiNUZXh0QXJlYUNoYXRMb2dbZGF0YS1jb2xvcnRoZW1lPSdkYXJrJ10gZGl2LkNoYXRNZXNzYWdlLmRlZXBsaWItbWVzc2FnZSxcbiNUZXh0QXJlYUNoYXRMb2dbZGF0YS1jb2xvcnRoZW1lPSdkYXJrMiddIGRpdi5DaGF0TWVzc2FnZS5kZWVwbGliLW1lc3NhZ2Uge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1kZWVwbGliLWVsZW1lbnQtY29sb3IpO1xuICBib3JkZXI6IG1pbigwLjJkdmgsIDAuMWR2dykgc29saWQgdmFyKC0tZGVlcGxpYi1ib3JkZXItY29sb3IpO1xuICBjb2xvcjogdmFyKC0tZGVlcGxpYi10ZXh0LWNvbG9yKTtcbn1cblxuI1RleHRBcmVhQ2hhdExvZyBkaXYuQ2hhdE1lc3NhZ2UuZGVlcGxpYi1tZXNzYWdlIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2VlZTtcbiAgYm9yZGVyOiBtaW4oMC4yZHZoLCAwLjFkdncpIHNvbGlkICM0NDAxNzE7XG4gIGNvbG9yOiAjMTExO1xuICBwYWRkaW5nLWxlZnQ6IG1pbigwLjZkdmgsIDAuM2R2dyk7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICB3aGl0ZS1zcGFjZTogbm9ybWFsO1xufVxuXG4jVGV4dEFyZWFDaGF0TG9nW2RhdGEtY29sb3J0aGVtZT0nZGFyayddIGRpdi5DaGF0TWVzc2FnZS5kZWVwbGliLW1lc3NhZ2UgYSxcbiNUZXh0QXJlYUNoYXRMb2dbZGF0YS1jb2xvcnRoZW1lPSdkYXJrMiddIGRpdi5DaGF0TWVzc2FnZS5kZWVwbGliLW1lc3NhZ2UgYSB7XG4gIGNvbG9yOiB2YXIoLS1kZWVwbGliLXRleHQtY29sb3IpO1xufVxuXG4jVGV4dEFyZWFDaGF0TG9nIGRpdi5DaGF0TWVzc2FnZS5kZWVwbGliLW1lc3NhZ2UgYSB7XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XG4gIGNvbG9yOiAjMTExO1xufVxuIiwiLmRlZXBsaWItbW9kYWwge1xuICBwb3NpdGlvbjogZml4ZWQ7XG4gIHRvcDogMTAlO1xuICBsZWZ0OiA1MCU7XG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNTAlKTtcbiAgei1pbmRleDogMTAwMTtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogMC41ZW07XG4gIHdpZHRoOiBtYXgoNTBkdncsIDI1ZHZoKTtcbiAgZm9udC1zaXplOiBtaW4oNGR2aCwgMmR2dyk7XG4gIHBhZGRpbmc6IG1pbigyZHZoLCAxZHZ3KTtcbiAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tZGVlcGxpYi1lbGVtZW50LWNvbG9yKTtcbiAgYm9yZGVyLXJhZGl1czogbWluKDEuMmR2aCwgMC42ZHZ3KTtcbiAgYm9yZGVyOiBtaW4oMC4yZHZoLCAwLjFkdncpIHNvbGlkIHZhcigtLWRlZXBsaWItYm9yZGVyLWNvbG9yKTtcbiAgY29sb3I6IHZhcigtLWRlZXBsaWItdGV4dC1jb2xvcik7XG5cbiAgLmRlZXBsaWItbW9kYWwtaW5wdXQge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGZvbnQtc2l6ZTogbWluKDIuNmR2aCwgMS44ZHZ3KTtcbiAgICBib3JkZXItcmFkaXVzOiBtaW4oMS4wZHZoLCAwLjVkdncpO1xuICAgIHBhZGRpbmc6IG1pbigxZHZoLCAwLjVkdncpO1xuICB9XG5cbiAgaW5wdXQuZGVlcGxpYi1tb2RhbC1pbnB1dCB7XG4gICAgbWF4LXdpZHRoOiBtYXgoNTBkdmgsIDI1ZHZ3KTtcbiAgfVxuXG4gIC5kZWVwbGliLW1vZGFsLWJ1dHRvbi1jb250YWluZXIge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xuICAgIGdhcDogMC41ZW07XG4gICAgd2lkdGg6IDEwMCU7XG5cbiAgICAuZGVlcGxpYi1idXR0b24ge1xuICAgICAgZm9udC1zaXplOiAwLjhlbTtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICB3aWR0aDogYXV0bztcbiAgICAgIHBhZGRpbmc6IG1pbigwLjR2aCwgMC4ydncpIG1pbigydmgsIDF2dyk7XG5cbiAgICAgIC5idXR0b24tbGFiZWwge1xuICAgICAgICBkaXNwbGF5OiBjb250ZW50cztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAuZGVlcGxpYi1tb2RhbC1wcm9tcHQtY29udGFpbmVyIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgfVxufVxuXG4uZGVlcGxpYi1tb2RhbC1ibG9ja2VyIHtcbiAgei1pbmRleDogMTAwMDtcbiAgcG9zaXRpb246IGZpeGVkO1xuICB0b3A6IDA7XG4gIGxlZnQ6IDA7XG4gIHdpZHRoOiAxMDBkdnc7XG4gIGhlaWdodDogMTAwZHZoO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNSk7XG59XG4iXX0= */`;
843
919
 
844
920
  // src/base/initialization.ts
845
921
  var modStorage;
922
+ var sdk;
846
923
  function initMod(options) {
847
- const sdk = new ModSdkManager(options.modInfo.info, options.modInfo.options);
924
+ sdk = new ModSdkManager(options.modInfo.info, options.modInfo.options);
848
925
  const MOD_NAME = ModSdkManager.ModInfo.name;
849
926
  modStorage = new ModStorage(ModSdkManager.ModInfo.name);
850
927
  Style.injectInline("deeplib-style", styles_default);
@@ -865,7 +942,6 @@ function initMod(options) {
865
942
  deepLibLogger.debug(`Already logged in, initing ${MOD_NAME}`);
866
943
  init(options);
867
944
  }
868
- return { sdk };
869
945
  }
870
946
  __name(initMod, "initMod");
871
947
  async function init(options) {
@@ -886,7 +962,6 @@ async function init(options) {
886
962
  await options.initFunction?.();
887
963
  if (options.mainMenuOptions)
888
964
  MainMenu.setOptions(options.mainMenuOptions);
889
- VersionModule.checkVersionUpdate();
890
965
  for (const m of modules()) {
891
966
  if (m.defaultSettings && hasGetter(m, "defaultSettings") && m.settings && hasSetter(m, "settings")) {
892
967
  if (Object.entries(m.defaultSettings).length === 0) continue;
@@ -964,8 +1039,6 @@ var GUI = class _GUI extends BaseModule {
964
1039
  _subscreens;
965
1040
  /** The mod's main menu screen. */
966
1041
  _mainMenu;
967
- /** The currently active subscreen, or `null` if none is active. */
968
- _currentSubscreen = null;
969
1042
  /** Options defining how the mod's settings button is displayed and behaves. */
970
1043
  _modButtonOptions;
971
1044
  /** Returns all registered subscreens. */
@@ -976,38 +1049,12 @@ var GUI = class _GUI extends BaseModule {
976
1049
  get mainMenu() {
977
1050
  return this._mainMenu;
978
1051
  }
979
- /** Returns the currently active subscreen. */
980
- get currentSubscreen() {
981
- return this._currentSubscreen;
982
- }
983
- /**
984
- * Sets the current subscreen.
985
- * Accepts either a `BaseSubscreen` instance or the `name` of a subscreen.
986
- *
987
- * @throws If a string is provided but no subscreen with that name exists.
988
- */
989
- set currentSubscreen(subscreen) {
990
- if (this._currentSubscreen) {
991
- this._currentSubscreen.unload();
992
- }
993
- if (typeof subscreen === "string") {
994
- const scr = this._subscreens?.find((s) => s.name === subscreen);
995
- if (!scr) throw `Failed to find screen name ${subscreen}`;
996
- this._currentSubscreen = scr;
997
- } else {
998
- this._currentSubscreen = subscreen;
999
- }
1000
- if (this._currentSubscreen) {
1001
- this._currentSubscreen.load();
1002
- this._currentSubscreen.resize(true);
1003
- }
1004
- }
1005
1052
  /**
1006
1053
  * Creates the GUI instance and initializes the main menu.
1007
1054
  *
1008
1055
  * @throws If another `GUI` instance already exists.
1009
1056
  */
1010
- constructor(modButtonOptions) {
1057
+ constructor(guiOptions = null) {
1011
1058
  super();
1012
1059
  if (_GUI.instance) {
1013
1060
  throw new Error("Duplicate initialization");
@@ -1015,9 +1062,9 @@ var GUI = class _GUI extends BaseModule {
1015
1062
  for (const module of modules()) {
1016
1063
  if (!module.settingsScreen) continue;
1017
1064
  }
1018
- this._mainMenu = new MainMenu(this);
1065
+ this._mainMenu = guiOptions?.mainMenu ? new guiOptions.mainMenu(this) : new MainMenu(this);
1019
1066
  this._subscreens = [this._mainMenu];
1020
- this._modButtonOptions = modButtonOptions;
1067
+ this._modButtonOptions = guiOptions;
1021
1068
  _GUI.instance = this;
1022
1069
  }
1023
1070
  /**
@@ -1028,43 +1075,25 @@ var GUI = class _GUI extends BaseModule {
1028
1075
  * - Sets up the main menu and its subscreens.
1029
1076
  */
1030
1077
  load() {
1078
+ if (!this._modButtonOptions) return;
1031
1079
  for (const module of modules()) {
1032
1080
  if (!module.settingsScreen) continue;
1033
- this._subscreens.push(new module.settingsScreen({}, module));
1081
+ this._subscreens.push(new module.settingsScreen(module));
1034
1082
  }
1035
1083
  this._mainMenu.subscreens = this._subscreens;
1036
1084
  PreferenceRegisterExtensionSetting({
1037
- Identifier: this._modButtonOptions.Identifier,
1038
- ButtonText: this._modButtonOptions.ButtonText,
1039
- Image: this._modButtonOptions.Image,
1040
- load: /* @__PURE__ */ __name(() => {
1041
- setSubscreen(new MainMenu(this));
1085
+ Identifier: this._modButtonOptions.identifier,
1086
+ ButtonText: this._modButtonOptions.buttonText,
1087
+ Image: this._modButtonOptions.image,
1088
+ load: /* @__PURE__ */ __name(async () => {
1089
+ await setSubscreen(this._mainMenu);
1042
1090
  }, "load"),
1043
1091
  run: /* @__PURE__ */ __name(() => {
1044
- if (this._currentSubscreen) {
1045
- this._currentSubscreen.run();
1046
- const newCanvasPosition = [MainCanvas.canvas.offsetLeft, MainCanvas.canvas.offsetTop, MainCanvas.canvas.clientWidth, MainCanvas.canvas.clientHeight];
1047
- if (!CommonArraysEqual(newCanvasPosition, DrawCanvasPosition)) {
1048
- DrawCanvasPosition = newCanvasPosition;
1049
- this._currentSubscreen.resize(false);
1050
- }
1051
- }
1052
1092
  }, "run"),
1053
1093
  click: /* @__PURE__ */ __name(() => {
1054
- if (this._currentSubscreen) {
1055
- this._currentSubscreen.click();
1056
- }
1057
1094
  }, "click"),
1058
1095
  exit: /* @__PURE__ */ __name(() => {
1059
- if (this._currentSubscreen) {
1060
- this._currentSubscreen.exit();
1061
- }
1062
- }, "exit"),
1063
- unload: /* @__PURE__ */ __name(() => {
1064
- if (this._currentSubscreen) {
1065
- this._currentSubscreen.unload();
1066
- }
1067
- }, "unload")
1096
+ }, "exit")
1068
1097
  });
1069
1098
  }
1070
1099
  };
@@ -1077,29 +1106,38 @@ var VersionModule = class _VersionModule extends BaseModule {
1077
1106
  /** Whether the current session is running a new version compared to stored data */
1078
1107
  static isItNewVersion = false;
1079
1108
  /** The current mod version (retrieved from `ModSdkManager.ModInfo.version`) */
1080
- static Version;
1109
+ static version;
1081
1110
  /** Message to display when a new version is detected */
1082
- static NewVersionMessage = "";
1111
+ static newVersionMessage = "";
1083
1112
  /** List of registered migration handlers, sorted by version */
1084
- static Migrators = [];
1113
+ static migrators = [];
1114
+ /** Optional lifecycle hook. Runs before each migration */
1115
+ static beforeEach;
1116
+ /** Optional lifecycle hook. Runs after each migration */
1117
+ static afterEach;
1118
+ /** Optional lifecycle hook. Runs before all migrations */
1119
+ static beforeAll;
1120
+ /** Optional lifecycle hook. Runs after all migrations */
1121
+ static afterAll;
1122
+ constructor(options) {
1123
+ super();
1124
+ _VersionModule.newVersionMessage = options.newVersionMessage;
1125
+ _VersionModule.beforeEach = options.beforeEach;
1126
+ _VersionModule.afterEach = options.afterEach;
1127
+ _VersionModule.beforeAll = options.beforeAll;
1128
+ _VersionModule.afterAll = options.afterAll;
1129
+ }
1085
1130
  /**
1086
1131
  * Initializes the module on load:
1087
1132
  * - Stores the current mod version.
1088
1133
  * - Hooks into `ChatRoomSync` to show a "new version" message when applicable.
1089
1134
  */
1090
1135
  load() {
1091
- _VersionModule.Version = ModSdkManager.ModInfo.version;
1092
- ModSdkManager.prototype.hookFunction(
1093
- "ChatRoomSync",
1094
- HookPriority.Observe,
1095
- (args, next) => {
1096
- next(args);
1097
- if (modStorage.playerStorage.GlobalModule.doShowNewVersionMessage && _VersionModule.isItNewVersion) {
1098
- _VersionModule.sendNewVersionMessage();
1099
- }
1100
- },
1101
- "VersionModule"
1102
- );
1136
+ _VersionModule.version = ModSdkManager.ModInfo.version;
1137
+ _VersionModule.checkVersionUpdate();
1138
+ if (modStorage.playerStorage.GlobalModule.doShowNewVersionMessage && _VersionModule.isItNewVersion) {
1139
+ _VersionModule.sendNewVersionMessage();
1140
+ }
1103
1141
  }
1104
1142
  /**
1105
1143
  * Checks if the stored version differs from the current version.
@@ -1110,9 +1148,9 @@ var VersionModule = class _VersionModule extends BaseModule {
1110
1148
  * - Saves `modStorage`.
1111
1149
  */
1112
1150
  static checkVersionUpdate() {
1113
- const PreviousVersion = _VersionModule.loadVersion();
1114
- const CurrentVersion = _VersionModule.Version;
1115
- if (_VersionModule.isNewVersion(PreviousVersion, CurrentVersion)) {
1151
+ const previousVersion = _VersionModule.loadVersion();
1152
+ const currentVersion = _VersionModule.version;
1153
+ if (_VersionModule.isNewVersion(previousVersion, currentVersion)) {
1116
1154
  _VersionModule.isItNewVersion = true;
1117
1155
  _VersionModule.checkVersionMigration();
1118
1156
  _VersionModule.saveVersion();
@@ -1124,29 +1162,58 @@ var VersionModule = class _VersionModule extends BaseModule {
1124
1162
  * is newer than the previously stored version.
1125
1163
  */
1126
1164
  static checkVersionMigration() {
1127
- const PreviousVersion = _VersionModule.loadVersion();
1128
- for (const migrator of _VersionModule.Migrators) {
1129
- if (_VersionModule.isNewVersion(PreviousVersion, migrator.MigrationVersion)) {
1130
- migrator.Migrate();
1131
- deepLibLogger.info(`Migrating ${ModSdkManager.ModInfo.name} from ${PreviousVersion} to ${migrator.MigrationVersion} with ${migrator.constructor.name}`);
1132
- }
1165
+ const previousVersion = _VersionModule.loadVersion();
1166
+ const toMigrate = _VersionModule.migrators.filter(
1167
+ (m) => _VersionModule.isNewVersion(previousVersion, m.migrationVersion)
1168
+ );
1169
+ if (!toMigrate.length) return;
1170
+ _VersionModule.beforeAll?.();
1171
+ for (const migrator of toMigrate) {
1172
+ _VersionModule.beforeEach?.();
1173
+ migrator.migrate();
1174
+ deepLibLogger.info(
1175
+ `Migrating ${ModSdkManager.ModInfo.name} from ${previousVersion} to ${migrator.migrationVersion} with ${migrator.constructor.name}`
1176
+ );
1177
+ _VersionModule.afterEach?.();
1133
1178
  }
1179
+ _VersionModule.afterAll?.();
1134
1180
  }
1135
1181
  /**
1136
1182
  * Registers a new migrator for handling version-specific changes.
1137
1183
  * Migrators are sorted by their `MigrationVersion` in ascending order.
1138
1184
  */
1139
1185
  static registerMigrator(migrator) {
1140
- _VersionModule.Migrators.push(migrator);
1141
- _VersionModule.Migrators.sort((a, b) => a.MigrationVersion.localeCompare(b.MigrationVersion));
1142
- }
1143
- /** Sets the message that will be displayed when a new version is detected. */
1144
- static setNewVersionMessage(newVersionMessage) {
1145
- _VersionModule.NewVersionMessage = newVersionMessage;
1186
+ _VersionModule.migrators.push(migrator);
1187
+ _VersionModule.migrators.sort((a, b) => a.migrationVersion.localeCompare(b.migrationVersion));
1146
1188
  }
1147
1189
  /** Sends the currently configured "new version" message to the local player. */
1148
1190
  static sendNewVersionMessage() {
1149
- sendLocalMessage("deeplib-new-version", _VersionModule.NewVersionMessage);
1191
+ const beepLogLength = FriendListBeepLog.push({
1192
+ MemberNumber: Player.MemberNumber,
1193
+ MemberName: ModSdkManager.ModInfo.name,
1194
+ ChatRoomName: getText("module.version.version_update"),
1195
+ ChatRoomSpace: "X",
1196
+ Private: false,
1197
+ Sent: false,
1198
+ Time: /* @__PURE__ */ new Date(),
1199
+ Message: _VersionModule.newVersionMessage
1200
+ });
1201
+ const beepIdx = beepLogLength - 1;
1202
+ const title = CommonStringPartitionReplace(getText("module.version.new_version_toast_title"), {
1203
+ $modName$: ModSdkManager.ModInfo.name,
1204
+ $modVersion$: _VersionModule.version
1205
+ }).join("");
1206
+ const data = FriendListBeepLog[beepIdx];
1207
+ ServerShowBeep(_VersionModule.newVersionMessage, 1e4, {
1208
+ memberNumber: data.MemberNumber,
1209
+ memberName: data.MemberName,
1210
+ chatRoomName: data.ChatRoomName,
1211
+ ...data.Message && {
1212
+ onClick: /* @__PURE__ */ __name(() => {
1213
+ FriendListShowBeep(beepIdx);
1214
+ }, "onClick")
1215
+ }
1216
+ }, title);
1150
1217
  }
1151
1218
  /**
1152
1219
  * Determines if a given `candidate` version is newer than the `current` version.
@@ -1171,7 +1238,7 @@ var VersionModule = class _VersionModule extends BaseModule {
1171
1238
  /** Saves the current mod version into persistent player storage. */
1172
1239
  static saveVersion() {
1173
1240
  if (modStorage.playerStorage) {
1174
- Player[ModSdkManager.ModInfo.name].Version = _VersionModule.Version;
1241
+ Player[ModSdkManager.ModInfo.name].Version = _VersionModule.version;
1175
1242
  }
1176
1243
  }
1177
1244
  /** Loads the stored mod version from persistent player storage. */
@@ -1185,9 +1252,9 @@ var GuiDebug = class extends BaseSubscreen {
1185
1252
  static {
1186
1253
  __name(this, "GuiDebug");
1187
1254
  }
1188
- get name() {
1189
- return "debug";
1190
- }
1255
+ static subscreenOptions = {
1256
+ name: "debug"
1257
+ };
1191
1258
  get pageStructure() {
1192
1259
  return [
1193
1260
  [
@@ -1396,6 +1463,7 @@ function hasSetter(obj, prop) {
1396
1463
  return false;
1397
1464
  }
1398
1465
  __name(hasSetter, "hasSetter");
1466
+ var byteToKB = /* @__PURE__ */ __name((nByte) => Math.round(nByte / 100) / 10, "byteToKB");
1399
1467
 
1400
1468
  // src/utilities/elements/elements.ts
1401
1469
  var advElement = {
@@ -1410,19 +1478,23 @@ var advElement = {
1410
1478
  createBackNext: elementPrevNext
1411
1479
  };
1412
1480
  function elementCreateButton(options) {
1481
+ options.id ??= ElementGenerateID();
1413
1482
  const elem = document.getElementById(options.id);
1414
1483
  if (elem) return elem;
1415
1484
  options.type = "button";
1485
+ let image = void 0;
1486
+ if (options.options?.image) {
1487
+ image = options.options.image;
1488
+ options.options.image = void 0;
1489
+ }
1416
1490
  const disabled = typeof options?.disabled === "function" ? options?.disabled() : options?.disabled;
1417
1491
  const button = ElementButton.Create(
1418
- options.htmlOptions?.id ?? options.id,
1419
- options.htmlOptions?.onClick ?? options?.onClick ?? (() => {
1492
+ options.id,
1493
+ options?.onClick ?? (() => {
1420
1494
  }),
1421
1495
  deepMerge({
1422
- tooltip: options.tooltip,
1423
- label: options.label,
1424
1496
  labelPosition: "center"
1425
- }, options.htmlOptions?.options),
1497
+ }, options.options),
1426
1498
  deepMerge({
1427
1499
  button: {
1428
1500
  classList: ["deeplib-button"],
@@ -1430,7 +1502,7 @@ function elementCreateButton(options) {
1430
1502
  disabled
1431
1503
  },
1432
1504
  children: [
1433
- options.image ? {
1505
+ image ? {
1434
1506
  tag: "img",
1435
1507
  attributes: {
1436
1508
  id: `${options.id}-image`,
@@ -1441,12 +1513,12 @@ function elementCreateButton(options) {
1441
1513
  // 1x1 transparent image to get rid of broken image
1442
1514
  },
1443
1515
  style: {
1444
- "--image": `url("${options.image}")`
1516
+ "--image": `url("${image}")`
1445
1517
  }
1446
1518
  } : void 0
1447
1519
  ]
1448
1520
  }
1449
- }, options.htmlOptions?.htmlOptions ?? {})
1521
+ }, options.htmlOptions ?? {})
1450
1522
  );
1451
1523
  BaseSubscreen.currentElements.push([button, options]);
1452
1524
  return button;
@@ -1639,7 +1711,6 @@ function elementPrevNext(options) {
1639
1711
  children: [
1640
1712
  advElement.createButton({
1641
1713
  id: `deeplib-prev-next-${options.id}-prev-button`,
1642
- image: `${PUBLIC_URL}/dl_images/arrow_left.svg`,
1643
1714
  onClick: /* @__PURE__ */ __name(() => {
1644
1715
  options.back({
1645
1716
  setLabel,
@@ -1647,16 +1718,15 @@ function elementPrevNext(options) {
1647
1718
  setNextTooltip
1648
1719
  });
1649
1720
  }, "onClick"),
1650
- tooltip: options.initialPrevTooltip,
1651
1721
  htmlOptions: {
1652
- htmlOptions: {
1653
- button: {
1654
- classList: ["deeplib-prev-next-button"]
1655
- }
1656
- },
1657
- options: {
1658
- noStyling: true
1722
+ button: {
1723
+ classList: ["deeplib-prev-next-button"]
1659
1724
  }
1725
+ },
1726
+ options: {
1727
+ noStyling: true,
1728
+ image: `${PUBLIC_URL}/dl_images/arrow_left.svg`,
1729
+ tooltip: options.initialPrevTooltip
1660
1730
  }
1661
1731
  }),
1662
1732
  advElement.createLabel({
@@ -1668,7 +1738,6 @@ function elementPrevNext(options) {
1668
1738
  }),
1669
1739
  advElement.createButton({
1670
1740
  id: `deeplib-prev-next-${options.id}-next-button`,
1671
- image: `${PUBLIC_URL}/dl_images/arrow_right.svg`,
1672
1741
  onClick: /* @__PURE__ */ __name(() => {
1673
1742
  options.next({
1674
1743
  setLabel,
@@ -1676,16 +1745,15 @@ function elementPrevNext(options) {
1676
1745
  setNextTooltip
1677
1746
  });
1678
1747
  }, "onClick"),
1679
- tooltip: options.initialNextTooltip,
1680
1748
  htmlOptions: {
1681
- htmlOptions: {
1682
- button: {
1683
- classList: ["deeplib-prev-next-button"]
1684
- }
1685
- },
1686
- options: {
1687
- noStyling: true
1749
+ button: {
1750
+ classList: ["deeplib-prev-next-button"]
1688
1751
  }
1752
+ },
1753
+ options: {
1754
+ noStyling: true,
1755
+ image: `${PUBLIC_URL}/dl_images/arrow_right.svg`,
1756
+ tooltip: options.initialNextTooltip
1689
1757
  }
1690
1758
  })
1691
1759
  ]
@@ -1699,6 +1767,7 @@ var Modal = class _Modal {
1699
1767
  opts ??= {};
1700
1768
  opts.closeOnBackdrop ??= true;
1701
1769
  const promptId = `modal-prompt-${Date.now()}`;
1770
+ const prompt = (CommonIsArray(opts.prompt) ? opts.prompt : [opts.prompt]).filter((i) => i != null) ?? [""];
1702
1771
  this.dialog = ElementCreate({
1703
1772
  tag: "dialog",
1704
1773
  classList: ["deeplib-modal"],
@@ -1711,7 +1780,13 @@ var Modal = class _Modal {
1711
1780
  fontFamily: CommonGetFontName()
1712
1781
  },
1713
1782
  children: [
1714
- opts.prompt,
1783
+ {
1784
+ tag: "div",
1785
+ classList: ["deeplib-modal-prompt-container"],
1786
+ children: [
1787
+ ...prompt
1788
+ ]
1789
+ },
1715
1790
  {
1716
1791
  tag: "div",
1717
1792
  classList: ["deeplib-modal-prompt"],
@@ -1754,22 +1829,39 @@ var Modal = class _Modal {
1754
1829
  * Shows a simple alert modal with a single "OK" button.
1755
1830
  */
1756
1831
  static async alert(msg, timeoutMs) {
1757
- await new _Modal({ prompt: msg, buttons: [{ action: "close", text: "OK" }], timeoutMs }).show();
1832
+ await new _Modal({
1833
+ prompt: msg,
1834
+ buttons: [{ action: "close", text: getText("modal.button.ok") }],
1835
+ timeoutMs,
1836
+ escapeAction: "close"
1837
+ }).show();
1758
1838
  }
1759
1839
  /**
1760
1840
  * Shows a confirmation modal with "Cancel" and "OK" buttons.
1761
1841
  * Returns true if "OK" is clicked.
1762
1842
  */
1763
1843
  static async confirm(msg) {
1764
- const [action] = await new _Modal({ prompt: msg, buttons: [{ text: "Cancel", action: "cancel" }, { text: "OK", action: "ok" }] }).show();
1765
- return action === "ok";
1844
+ const [action] = await new _Modal({
1845
+ prompt: msg,
1846
+ buttons: [{ text: getText("modal.button.decline"), action: "decline" }, { text: getText("modal.button.confirm"), action: "confirm" }],
1847
+ escapeAction: "decline",
1848
+ enterAction: "confirm"
1849
+ }).show();
1850
+ return action === "confirm";
1766
1851
  }
1767
1852
  /**
1768
1853
  * Shows a prompt modal with an input field and "Submit"/"Cancel" buttons.
1769
1854
  * Returns the input value if submitted, otherwise null.
1770
1855
  */
1771
1856
  static async prompt(msg, defaultValue = "") {
1772
- const [action, value] = await new _Modal({ prompt: msg, timeoutMs: 0, input: { type: "input", defaultValue }, buttons: [{ text: "Cancel", action: "cancel" }, { text: "Submit", action: "submit" }] }).show();
1857
+ const [action, value] = await new _Modal({
1858
+ prompt: msg,
1859
+ timeoutMs: 0,
1860
+ input: { type: "input", defaultValue },
1861
+ buttons: [{ text: getText("modal.button.cancel"), action: "cancel" }, { text: getText("modal.button.submit"), action: "submit" }],
1862
+ escapeAction: "cancel",
1863
+ enterAction: "submit"
1864
+ }).show();
1773
1865
  return action === "submit" ? value : null;
1774
1866
  }
1775
1867
  /** Creates the input element for the modal, applying configuration and validation. */
@@ -1794,10 +1886,12 @@ var Modal = class _Modal {
1794
1886
  const btns = this.opts.buttons ? [...this.opts.buttons] : [];
1795
1887
  btns.forEach((b) => {
1796
1888
  const btn = advElement.createButton({
1797
- label: b.text,
1798
1889
  id: `deeplib-modal-${b.action}`,
1799
- disabled: b.disabled,
1800
- onClick: /* @__PURE__ */ __name(() => this.close(b.action), "onClick")
1890
+ onClick: /* @__PURE__ */ __name(() => this.close(b.action), "onClick"),
1891
+ options: {
1892
+ disabled: b.disabled,
1893
+ label: b.text
1894
+ }
1801
1895
  });
1802
1896
  container.append(btn);
1803
1897
  });
@@ -1837,7 +1931,12 @@ var Modal = class _Modal {
1837
1931
  }
1838
1932
  } else if (e.key === "Escape") {
1839
1933
  e.stopPropagation();
1840
- this.close("close");
1934
+ this.close(this.opts.escapeAction ?? "close");
1935
+ } else if (e.key === "Enter") {
1936
+ if (elements.some((el) => el === document.activeElement) && document.activeElement !== this.inputEl) return;
1937
+ e.preventDefault();
1938
+ e.stopPropagation();
1939
+ this.close(this.opts.enterAction ?? "submit");
1841
1940
  }
1842
1941
  });
1843
1942
  window.requestAnimationFrame(() => {
@@ -1885,15 +1984,15 @@ var MainMenu = class _MainMenu extends BaseSubscreen {
1885
1984
  }
1886
1985
  subscreens = [];
1887
1986
  static options = {};
1888
- get name() {
1889
- return "mainmenu";
1890
- }
1987
+ static subscreenOptions = {
1988
+ name: "mainmenu"
1989
+ };
1891
1990
  constructor(module) {
1892
- super({ drawCharacter: true }, module);
1991
+ super(module);
1893
1992
  this.subscreens = module.subscreens;
1894
1993
  }
1895
1994
  load() {
1896
- if (!GUI.instance?.currentSubscreen) {
1995
+ if (!GUI.instance || CurrentModule !== "DeepLibMod") {
1897
1996
  this.setSubscreen(this);
1898
1997
  return;
1899
1998
  }
@@ -1901,87 +2000,139 @@ var MainMenu = class _MainMenu extends BaseSubscreen {
1901
2000
  const exitButton = advElement.createButton({
1902
2001
  id: "exit",
1903
2002
  size: [90, 90],
1904
- image: `${PUBLIC_URL}/dl_images/exit.svg`,
1905
2003
  onClick: /* @__PURE__ */ __name(() => {
1906
2004
  this.exit();
1907
2005
  }, "onClick"),
1908
- tooltip: getText("settings.button.back_button_hint")
2006
+ options: {
2007
+ image: `${PUBLIC_URL}/dl_images/exit.svg`,
2008
+ tooltip: getText("settings.button.back_button_hint")
2009
+ }
1909
2010
  });
1910
2011
  const menu = document.getElementById("deeplib-nav-menu");
1911
2012
  if (menu) {
1912
2013
  ElementMenu.AppendButton(menu, exitButton);
1913
2014
  }
1914
2015
  for (const screen of this.subscreens) {
1915
- if (screen.name == "mainmenu") continue;
2016
+ if (screen.options.name == "mainmenu") continue;
1916
2017
  const button = advElement.createButton({
1917
- id: `${screen.name}-button`,
1918
- image: screen.icon,
1919
- label: getText(`mainmenu.button.${screen.name}`),
2018
+ id: `${screen.options.name}-button`,
1920
2019
  onClick: /* @__PURE__ */ __name(() => {
1921
2020
  this.setSubscreen(screen);
1922
2021
  }, "onClick"),
1923
- size: [null, 90]
2022
+ size: [null, 90],
2023
+ options: {
2024
+ image: screen.options.icon,
2025
+ label: getText(`mainmenu.button.${screen.options.name}`)
2026
+ }
1924
2027
  });
1925
2028
  layout.appendToSettingsDiv(button);
1926
2029
  }
1927
- const miscDiv = layout.createMiscDiv();
2030
+ const miscDiv = layout.getMiscDiv();
1928
2031
  layout.appendToSubscreen(miscDiv);
1929
2032
  if (_MainMenu.options.wikiLink) {
1930
2033
  const wikiButton = advElement.createButton({
1931
2034
  id: "deeplib-wiki-button",
1932
- image: `${PUBLIC_URL}/dl_images/notebook.svg`,
1933
- label: getText("mainmenu.button.wiki"),
1934
2035
  onClick: /* @__PURE__ */ __name(() => {
1935
2036
  window.open(_MainMenu.options.wikiLink, "_blank");
1936
2037
  }, "onClick"),
1937
- size: [null, 80]
2038
+ size: [null, 80],
2039
+ options: {
2040
+ image: `${PUBLIC_URL}/dl_images/notebook.svg`,
2041
+ label: getText("mainmenu.button.wiki")
2042
+ }
1938
2043
  });
1939
2044
  layout.appendToMiscDiv(wikiButton);
1940
2045
  }
1941
2046
  if (_MainMenu.options.repoLink) {
1942
2047
  const repoButton = advElement.createButton({
1943
2048
  id: "deeplib-repo-button",
1944
- image: `${PUBLIC_URL}/dl_images/git.svg`,
1945
- label: getText("mainmenu.button.repo"),
1946
2049
  onClick: /* @__PURE__ */ __name(() => {
1947
2050
  window.open(_MainMenu.options.repoLink, "_blank");
1948
2051
  }, "onClick"),
1949
- size: [null, 80]
2052
+ size: [null, 80],
2053
+ options: {
2054
+ image: `${PUBLIC_URL}/dl_images/git.svg`,
2055
+ label: getText("mainmenu.button.repo")
2056
+ }
1950
2057
  });
1951
2058
  layout.appendToMiscDiv(repoButton);
1952
2059
  }
1953
2060
  if (_MainMenu.options.resetSubscreen) {
1954
2061
  const resetButton = advElement.createButton({
1955
2062
  id: "deeplib-reset-button",
1956
- image: `${PUBLIC_URL}/dl_images/trash_bin.svg`,
1957
- label: getText("mainmenu.button.reset"),
1958
2063
  onClick: /* @__PURE__ */ __name(() => {
1959
2064
  this.setSubscreen(_MainMenu.options.resetSubscreen);
1960
2065
  }, "onClick"),
1961
- size: [null, 80]
2066
+ size: [null, 80],
2067
+ options: {
2068
+ image: `${PUBLIC_URL}/dl_images/trash_bin.svg`,
2069
+ label: getText("mainmenu.button.reset")
2070
+ }
1962
2071
  });
1963
2072
  layout.appendToMiscDiv(resetButton);
1964
2073
  }
1965
2074
  if (_MainMenu.options.importExportSubscreen) {
1966
2075
  const importExportButton = advElement.createButton({
1967
2076
  id: "deeplib-import-export-button",
1968
- image: `${PUBLIC_URL}/dl_images/transfer.svg`,
1969
- label: getText("mainmenu.button.import_export"),
1970
2077
  onClick: /* @__PURE__ */ __name(() => {
1971
2078
  this.setSubscreen(_MainMenu.options.importExportSubscreen);
1972
2079
  }, "onClick"),
1973
- size: [null, 80]
2080
+ size: [null, 80],
2081
+ options: {
2082
+ image: `${PUBLIC_URL}/dl_images/transfer.svg`,
2083
+ label: getText("mainmenu.button.import_export")
2084
+ }
1974
2085
  });
1975
2086
  layout.appendToMiscDiv(importExportButton);
1976
2087
  }
2088
+ if (_MainMenu.options.storageFullnessIndicator) {
2089
+ const maxStorageCapacityKB = 180;
2090
+ const currentStorageCapacityKB = byteToKB(ModStorage.measureSize(Player.OnlineSettings));
2091
+ const fullness = (currentStorageCapacityKB / maxStorageCapacityKB * 100).toFixed(1);
2092
+ const storageFullnessWrapper = advElement.createButton({
2093
+ id: CommonGenerateUniqueID(),
2094
+ size: [null, 80],
2095
+ options: {
2096
+ tooltipPosition: "left",
2097
+ noStyling: true,
2098
+ tooltip: CommonStringPartitionReplace(getText("mainmenu.meter.storage_hint"), {
2099
+ $percentage$: `${fullness}`
2100
+ }).join(""),
2101
+ label: CommonStringPartitionReplace(getText("mainmenu.meter.storage_label"), {
2102
+ $currentCapacity$: `${currentStorageCapacityKB}`,
2103
+ $maxCapacity$: `${maxStorageCapacityKB}`
2104
+ }).join("")
2105
+ },
2106
+ htmlOptions: {
2107
+ button: {
2108
+ children: [
2109
+ {
2110
+ tag: "div",
2111
+ attributes: { id: "deeplib-storage-meter" },
2112
+ children: [
2113
+ {
2114
+ tag: "div",
2115
+ attributes: { id: "deeplib-storage-bar" },
2116
+ style: { width: `${fullness}%` }
2117
+ }
2118
+ ]
2119
+ }
2120
+ ]
2121
+ }
2122
+ }
2123
+ });
2124
+ layout.appendToMiscDiv(storageFullnessWrapper);
2125
+ }
1977
2126
  if (IS_DEBUG) {
1978
2127
  const debugButton = advElement.createButton({
1979
2128
  id: "deeplib-debug-button",
1980
- image: `${PUBLIC_URL}/dl_images/bug.svg`,
1981
2129
  onClick: /* @__PURE__ */ __name(() => {
1982
2130
  this.setSubscreen(new GuiDebug());
1983
2131
  }, "onClick"),
1984
- size: [90, 90]
2132
+ size: [90, 90],
2133
+ options: {
2134
+ image: `${PUBLIC_URL}/dl_images/bug.svg`
2135
+ }
1985
2136
  });
1986
2137
  if (menu) {
1987
2138
  ElementMenu.PrependItem(menu, debugButton);
@@ -1996,8 +2147,17 @@ var MainMenu = class _MainMenu extends BaseSubscreen {
1996
2147
  exit() {
1997
2148
  CharacterAppearanceForceUpCharacter = -1;
1998
2149
  CharacterLoadCanvas(Player);
1999
- this.setSubscreen(null);
2000
- PreferenceSubscreenExtensionsClear();
2150
+ const returnScreen = typeof this.options.returnScreen === "function" ? this.options.returnScreen() : this.options.returnScreen;
2151
+ if (!returnScreen) {
2152
+ PreferenceOpenSubscreen("Extensions").then(() => {
2153
+ PreferenceSubscreenExtensionsClear();
2154
+ });
2155
+ } else if (returnScreen instanceof BaseSubscreen) {
2156
+ setSubscreen(returnScreen ?? null).then(() => {
2157
+ });
2158
+ } else if (Array.isArray(returnScreen)) {
2159
+ CommonSetScreen(...returnScreen);
2160
+ }
2001
2161
  }
2002
2162
  resize() {
2003
2163
  super.resize();
@@ -2008,6 +2168,18 @@ var MainMenu = class _MainMenu extends BaseSubscreen {
2008
2168
  _MainMenu.options = mainMenuOptions;
2009
2169
  }
2010
2170
  };
2171
+ async function PreferenceOpenSubscreen(subscreen, page = 1) {
2172
+ if (CurrentModule !== "Character" || CurrentScreen !== "Preference") {
2173
+ await CommonSetScreen("Character", "Preference");
2174
+ }
2175
+ PreferenceSubscreen?.unload?.();
2176
+ PreferenceSubscreen = PreferenceSubscreens.find((s) => s.name === subscreen) ?? null;
2177
+ if (!CommonIsNonNegativeInteger(page)) page = 1;
2178
+ PreferencePageCurrent = page;
2179
+ PreferenceMessage = "";
2180
+ PreferenceSubscreen?.load?.();
2181
+ }
2182
+ __name(PreferenceOpenSubscreen, "PreferenceOpenSubscreen");
2011
2183
 
2012
2184
  // src/screens/import_export.ts
2013
2185
  var GuiImportExport = class extends BaseSubscreen {
@@ -2015,11 +2187,11 @@ var GuiImportExport = class extends BaseSubscreen {
2015
2187
  __name(this, "GuiImportExport");
2016
2188
  }
2017
2189
  importExportOptions;
2018
- get name() {
2019
- return "import-export";
2020
- }
2190
+ static subscreenOptions = {
2191
+ name: "import-export"
2192
+ };
2021
2193
  constructor(importExportOptions) {
2022
- super({ drawCharacter: true });
2194
+ super();
2023
2195
  this.importExportOptions = importExportOptions;
2024
2196
  }
2025
2197
  load() {
@@ -2027,41 +2199,49 @@ var GuiImportExport = class extends BaseSubscreen {
2027
2199
  const importFromFileButton = advElement.createButton({
2028
2200
  id: "deeplib-import-file-button",
2029
2201
  size: [600, 90],
2030
- image: `${PUBLIC_URL}/dl_images/file_import.svg`,
2031
2202
  onClick: /* @__PURE__ */ __name(() => {
2032
2203
  this.dataImport("file");
2033
2204
  }, "onClick"),
2034
- label: getText("import-export.button.import_file")
2205
+ options: {
2206
+ image: `${PUBLIC_URL}/dl_images/file_import.svg`,
2207
+ label: getText("import-export.button.import_file")
2208
+ }
2035
2209
  });
2036
2210
  layout.appendToSettingsDiv(importFromFileButton);
2037
2211
  const exportToFileButton = advElement.createButton({
2038
2212
  id: "deeplib-export-file-button",
2039
2213
  size: [600, 90],
2040
- image: `${PUBLIC_URL}/dl_images/file_export.svg`,
2041
2214
  onClick: /* @__PURE__ */ __name(() => {
2042
2215
  this.dataExport("file");
2043
2216
  }, "onClick"),
2044
- label: getText("import-export.button.export_file")
2217
+ options: {
2218
+ image: `${PUBLIC_URL}/dl_images/file_export.svg`,
2219
+ label: getText("import-export.button.export_file")
2220
+ }
2045
2221
  });
2046
2222
  layout.appendToSettingsDiv(exportToFileButton);
2047
2223
  const importFromClipboardButton = advElement.createButton({
2048
2224
  id: "deeplib-import-clipboard-button",
2049
2225
  size: [600, 90],
2050
- image: `${PUBLIC_URL}/dl_images/clipboard_import.svg`,
2051
2226
  onClick: /* @__PURE__ */ __name(() => {
2052
2227
  this.dataImport("clipboard");
2053
2228
  }, "onClick"),
2054
- label: getText("import-export.button.import_clipboard")
2229
+ options: {
2230
+ image: `${PUBLIC_URL}/dl_images/clipboard_import.svg`,
2231
+ label: getText("import-export.button.import_clipboard")
2232
+ }
2055
2233
  });
2056
2234
  layout.appendToSettingsDiv(importFromClipboardButton);
2057
2235
  const exportToClipboardButton = advElement.createButton({
2058
2236
  id: "deeplib-export-clipboard-button",
2059
2237
  size: [600, 90],
2060
- image: `${PUBLIC_URL}/dl_images/clipboard_export.svg`,
2061
2238
  onClick: /* @__PURE__ */ __name(() => {
2062
2239
  this.dataExport("clipboard");
2063
2240
  }, "onClick"),
2064
- label: getText("import-export.button.export_clipboard")
2241
+ options: {
2242
+ image: `${PUBLIC_URL}/dl_images/clipboard_export.svg`,
2243
+ label: getText("import-export.button.export_clipboard")
2244
+ }
2065
2245
  });
2066
2246
  layout.appendToSettingsDiv(exportToClipboardButton);
2067
2247
  }
@@ -2284,6 +2464,19 @@ var ModStorage = class _ModStorage {
2284
2464
  static dataCompress(object) {
2285
2465
  return LZString.compressToBase64(JSON.stringify(object));
2286
2466
  }
2467
+ static measureSize(data) {
2468
+ try {
2469
+ if (typeof data !== "string") {
2470
+ data = JSON.stringify(data) || "";
2471
+ }
2472
+ if (typeof data === "string") {
2473
+ return new TextEncoder().encode(data).byteLength;
2474
+ }
2475
+ throw new Error();
2476
+ } catch {
2477
+ return NaN;
2478
+ }
2479
+ }
2287
2480
  };
2288
2481
 
2289
2482
  // src/utilities/elements/helpers.ts
@@ -2373,34 +2566,28 @@ __name(hasOverflow, "hasOverflow");
2373
2566
 
2374
2567
  // src/utilities/elements/layout.ts
2375
2568
  var layout = {
2376
- createSubscreen: elementCreateSubscreenDiv,
2377
2569
  getSubscreen: elementGetSubscreenDiv,
2378
2570
  appendToSubscreen: elementAppendToSubscreenDiv,
2379
2571
  removeSubscreen: elementRemoveSubscreenDiv,
2380
- createSettingsDiv: elementCreateSettingsDiv,
2381
2572
  getSettingsDiv: elementGetSettingsDiv,
2382
2573
  appendToSettingsDiv: elementAppendToSettingsDiv,
2383
2574
  removeSettingsDiv: elementRemoveSettingsDiv,
2384
- createMiscDiv: elementCreateMiscDiv,
2385
2575
  getMiscDiv: elementGetMiscDiv,
2386
2576
  appendToMiscDiv: elementAppendToMiscDiv,
2387
2577
  removeMiscDiv: elementRemoveMiscDiv
2388
2578
  };
2389
- function elementCreateSubscreenDiv() {
2390
- const subscreenDiv = elementGetSubscreenDiv();
2579
+ function elementGetSubscreenDiv() {
2580
+ const subscreenDiv = ElementWrap("deeplib-subscreen");
2391
2581
  if (subscreenDiv) {
2392
- console.error("Subscreen already exists");
2393
2582
  return subscreenDiv;
2394
2583
  }
2395
- const div = document.createElement("div");
2396
- div.id = "deeplib-subscreen";
2397
- div.classList.add("deeplib-subscreen", "HideOnPopup");
2584
+ const div = ElementCreate({
2585
+ tag: "div",
2586
+ classList: ["deeplib-subscreen", "HideOnPopup"],
2587
+ attributes: { id: "deeplib-subscreen" }
2588
+ });
2398
2589
  return document.body.appendChild(div);
2399
2590
  }
2400
- __name(elementCreateSubscreenDiv, "elementCreateSubscreenDiv");
2401
- function elementGetSubscreenDiv() {
2402
- return document.getElementById("deeplib-subscreen") ?? void 0;
2403
- }
2404
2591
  __name(elementGetSubscreenDiv, "elementGetSubscreenDiv");
2405
2592
  function elementRemoveSubscreenDiv() {
2406
2593
  return elementGetSubscreenDiv()?.remove();
@@ -2410,21 +2597,18 @@ function elementAppendToSubscreenDiv(...element) {
2410
2597
  return elementGetSubscreenDiv()?.append(...element);
2411
2598
  }
2412
2599
  __name(elementAppendToSubscreenDiv, "elementAppendToSubscreenDiv");
2413
- function elementCreateSettingsDiv() {
2414
- const settingsDiv = elementGetSettingsDiv();
2600
+ function elementGetSettingsDiv() {
2601
+ const settingsDiv = ElementWrap("deeplib-settings");
2415
2602
  if (settingsDiv) {
2416
- console.error("Settings screen already exists");
2417
2603
  return settingsDiv;
2418
2604
  }
2419
- const div = document.createElement("div");
2420
- div.id = "deeplib-settings";
2421
- div.classList.add("deeplib-settings");
2605
+ const div = ElementCreate({
2606
+ tag: "div",
2607
+ classList: ["deeplib-settings", "scroll-box"],
2608
+ attributes: { id: "deeplib-settings" }
2609
+ });
2422
2610
  return div;
2423
2611
  }
2424
- __name(elementCreateSettingsDiv, "elementCreateSettingsDiv");
2425
- function elementGetSettingsDiv() {
2426
- return document.getElementById("deeplib-settings") ?? void 0;
2427
- }
2428
2612
  __name(elementGetSettingsDiv, "elementGetSettingsDiv");
2429
2613
  function elementAppendToSettingsDiv(...element) {
2430
2614
  return elementGetSettingsDiv()?.append(...element);
@@ -2434,21 +2618,18 @@ function elementRemoveSettingsDiv() {
2434
2618
  return elementGetSettingsDiv()?.remove();
2435
2619
  }
2436
2620
  __name(elementRemoveSettingsDiv, "elementRemoveSettingsDiv");
2437
- function elementCreateMiscDiv() {
2438
- const miscDiv = elementGetMiscDiv();
2621
+ function elementGetMiscDiv() {
2622
+ const miscDiv = ElementWrap("deeplib-misc");
2439
2623
  if (miscDiv) {
2440
- console.error("Settings screen already exists");
2441
2624
  return miscDiv;
2442
2625
  }
2443
- const div = document.createElement("div");
2444
- div.id = "deeplib-misc";
2445
- div.classList.add("deeplib-misc");
2626
+ const div = ElementCreate({
2627
+ tag: "div",
2628
+ classList: ["deeplib-misc"],
2629
+ attributes: { id: "deeplib-misc" }
2630
+ });
2446
2631
  return div;
2447
2632
  }
2448
- __name(elementCreateMiscDiv, "elementCreateMiscDiv");
2449
- function elementGetMiscDiv() {
2450
- return document.getElementById("deeplib-misc");
2451
- }
2452
2633
  __name(elementGetMiscDiv, "elementGetMiscDiv");
2453
2634
  function elementAppendToMiscDiv(...element) {
2454
2635
  return elementGetMiscDiv()?.append(...element);
@@ -2803,10 +2984,71 @@ var Localization = class _Localization {
2803
2984
  var getText = /* @__PURE__ */ __name((srcTag) => {
2804
2985
  return Localization.getTextMod(srcTag) || Localization.getTextLib(srcTag) || srcTag;
2805
2986
  }, "getText");
2987
+
2988
+ // src/utilities/event_channel.ts
2989
+ var EventChannel = class {
2990
+ constructor(channelName) {
2991
+ this.channelName = channelName;
2992
+ ModSdkManager.prototype.hookFunction("ChatRoomMessageProcessHidden", 0, (args, next) => {
2993
+ if (!this.isChannelMessage(args[0])) {
2994
+ return next(args);
2995
+ }
2996
+ const [message, sender] = args;
2997
+ const { type, data } = message.Dictionary[0];
2998
+ const listeners = this.listeners[type];
2999
+ if (listeners) {
3000
+ listeners.forEach((listener) => listener(data, sender));
3001
+ }
3002
+ return next(args);
3003
+ }, `EventChannel-${channelName}`);
3004
+ }
3005
+ static {
3006
+ __name(this, "EventChannel");
3007
+ }
3008
+ listeners = {};
3009
+ unload() {
3010
+ Object.keys(this.listeners).forEach((key) => delete this.listeners[key]);
3011
+ ModSdkManager.prototype.removeHookByModule("ChatRoomMessageProcessHidden", `EventChannel-${this.channelName}`);
3012
+ }
3013
+ sendEvent(type, data, target = null) {
3014
+ const packet = {
3015
+ Type: "Hidden",
3016
+ Content: this.channelName,
3017
+ Sender: Player.MemberNumber,
3018
+ ...target ? { Target: target } : {},
3019
+ Dictionary: [
3020
+ {
3021
+ type,
3022
+ data
3023
+ }
3024
+ ]
3025
+ };
3026
+ ServerSend("ChatRoomChat", packet);
3027
+ }
3028
+ registerListener(event, listener) {
3029
+ const listeners = this.listeners[event] ?? [];
3030
+ listeners.push(listener);
3031
+ this.listeners[event] = listeners;
3032
+ return () => this.unregisterListener(event, listener);
3033
+ }
3034
+ unregisterListener(event, listener) {
3035
+ const listeners = this.listeners[event];
3036
+ if (listeners) {
3037
+ const index = listeners.indexOf(listener);
3038
+ if (index !== -1) {
3039
+ listeners.splice(index, 1);
3040
+ }
3041
+ }
3042
+ }
3043
+ isChannelMessage(message) {
3044
+ return message && message.Type === "Hidden" && message.Content === this.channelName && message.Sender && message.Sender !== Player.MemberNumber && message.Dictionary && !!message.Dictionary[0]?.data && !!message.Dictionary[0]?.type || false;
3045
+ }
3046
+ };
2806
3047
  export {
2807
3048
  BaseMigrator2 as BaseMigrator,
2808
3049
  BaseModule,
2809
3050
  BaseSubscreen,
3051
+ EventChannel,
2810
3052
  GUI,
2811
3053
  GuiDebug,
2812
3054
  GuiImportExport,
@@ -2820,6 +3062,7 @@ export {
2820
3062
  Style,
2821
3063
  VersionModule,
2822
3064
  advElement,
3065
+ byteToKB,
2823
3066
  deepLibLogger,
2824
3067
  deepMerge,
2825
3068
  deepMergeMatchingProperties,
@@ -2836,6 +3079,7 @@ export {
2836
3079
  modules,
2837
3080
  modulesMap,
2838
3081
  registerModule,
3082
+ sdk,
2839
3083
  sendActionMessage,
2840
3084
  sendLocalMessage,
2841
3085
  setSubscreen,