@wildwinter/app-shell 0.17.0 → 0.19.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/index.d.cts CHANGED
@@ -237,6 +237,16 @@ interface ConfirmOptions {
237
237
  /** Resolves true on confirm; false on Cancel / Esc / backdrop. */
238
238
  declare function confirmDialog(opts: ConfirmOptions): Promise<boolean>;
239
239
 
240
+ /**
241
+ * Play the close animation on `element`, then run `done` exactly once.
242
+ *
243
+ * `done` does the real teardown: remove the node, drop listeners, unmount
244
+ * whatever was inside it. Under `prefers-reduced-motion` the duration reads 0
245
+ * and `done` runs synchronously, so reduced motion means instant rather than
246
+ * an invisible wait.
247
+ */
248
+ declare function closeWithExit(element: HTMLElement, done: () => void): void;
249
+
240
250
  interface AboutOptions {
241
251
  /** The product's name, large. */
242
252
  appName: string;
@@ -452,6 +462,19 @@ interface CommentsOptions {
452
462
  deleteMessage?: (threadId: string, index: number) => void;
453
463
  /** Where the panel sits: "centre" for a point on a canvas (see anchored.ts). */
454
464
  prefer?: "left" | "below" | "centre";
465
+ /**
466
+ * The text a thread is pinned to, shown above it as a quotation.
467
+ *
468
+ * A callback rather than a field on `Comment`, because resolving an anchor is
469
+ * the APP's half of the seam and this is only that resolution rendered: an app
470
+ * that pins threads to a span of prose can quote it, one that pins them to a
471
+ * whole card has nothing to quote and passes nothing. Keeping it out of the
472
+ * thread type also means no change to what is written to disk, which matters
473
+ * for files living in version control.
474
+ *
475
+ * Return undefined (or "") for a thread with no quotable anchor.
476
+ */
477
+ quoteFor?: (thread: Comment) => string | undefined;
455
478
  }
456
479
  declare function openComments(opts: CommentsOptions): void;
457
480
 
@@ -570,4 +593,81 @@ interface SaveController {
570
593
  }
571
594
  declare function createSaveController(opts: SaveControllerOptions): SaveController;
572
595
 
573
- export { type AboutOptions, type AnchoredPanel, type AnchoredPanelOptions, type Child, type Comment, type CommentMessage, type CommentsOptions, type ConfirmOptions, type DocLine, type DupGuard, type ElProps, type GameIdEditorOptions, type IconName, type IconSvgName, type Identity, type IdentityOptions, type JobProgressOptions, type JobProgressView, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButtonOptions, type SaveController, type SaveControllerOptions, type SaveStatus, type SettingsDialog, type SettingsDialogOptions, type SettingsSection, type SettingsSectionHandle, type ShardVc, type TipRect, type TooltipOptions, type VcMap, askIdentity, closeAnchoredPanel, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isValidGameId, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, showAbout, tagChips, tipAt, tipBold, vcBadgeFor };
596
+ interface SaveIndicator {
597
+ /** Put it in the topbar. */
598
+ readonly el: HTMLElement;
599
+ /** Wire straight to the controller's `onStatus`. */
600
+ set(status: SaveStatus): void;
601
+ }
602
+ declare function saveIndicator(initial?: SaveStatus): SaveIndicator;
603
+
604
+ interface StaleBarOptions {
605
+ /**
606
+ * What went out of date, as a capitalised noun phrase: "The project", "The
607
+ * scene". Written into "<subject> changed in the editor."
608
+ */
609
+ subject: string;
610
+ /** Start again from the current source. */
611
+ onRestart: () => void;
612
+ /** The button, when "Restart" is not the app's word for it. */
613
+ restartLabel?: string;
614
+ /**
615
+ * The rest of the sentence, for an app whose session is not a PLAY: the
616
+ * default is "Restart to play the new version."
617
+ */
618
+ advice?: string;
619
+ }
620
+ declare function staleBar(opts: StaleBarOptions): HTMLElement;
621
+
622
+ interface StepperItem {
623
+ /**
624
+ * One word for what kind of thing this is: "error", "comment", "resolved".
625
+ * Absent when the bar carries one kind of thing only.
626
+ */
627
+ kind?: string;
628
+ /** An extra class on the kind chip, so an app can colour its own kinds
629
+ * (Storyletter's `sev-error`, and `done` for a resolved thread). */
630
+ kindClass?: string;
631
+ /** Where it is, in the app's own address. Set in the mono face. */
632
+ where?: string;
633
+ /** The entry itself, in one line. Overflow is clipped, not wrapped: the bar
634
+ * is one row high and stays that way however long the sentence is. */
635
+ text: string;
636
+ }
637
+ /** How loud the count is. The app picks; the palette supplies the value. */
638
+ type StepperTone = "danger" | "warn" | "accent" | "muted";
639
+ interface StepperBarOptions {
640
+ items: StepperItem[];
641
+ /** Which one is current. Clamped, so a shrinking list cannot point off the end. */
642
+ at: number;
643
+ tone?: StepperTone;
644
+ /** Go to another index. The bar wraps, so this is always in range. */
645
+ onStep: (next: number) => void;
646
+ /** Take me to what the current entry is about. */
647
+ onGo: (index: number) => void;
648
+ /** What the three controls say they do. Keyboard shortcuts belong in here. */
649
+ tips?: {
650
+ prev?: string;
651
+ next?: string;
652
+ go?: string;
653
+ };
654
+ /**
655
+ * What to say when the list is empty.
656
+ *
657
+ * Absent hides the bar, which is right for an AMBIENT bar: no problems, no
658
+ * problems bar. Present keeps it up, which is right for a MODE: entering the
659
+ * walk and seeing nothing at all reads as a broken command rather than as
660
+ * "there is no feedback".
661
+ */
662
+ empty?: string;
663
+ /** Leave the mode. Drawn as the last control, hard right. */
664
+ onClose?: () => void;
665
+ closeTip?: string;
666
+ /** The right-hand end before the close: a quick fix, say. Nulls are skipped,
667
+ * so a caller can pass a conditional straight in. */
668
+ actions?: (HTMLElement | null | undefined)[];
669
+ }
670
+ /** Draw (or hide) the bar in `host`. Idempotent: call it again with new state. */
671
+ declare function renderStepperBar(host: HTMLElement, opts: StepperBarOptions): void;
672
+
673
+ export { type AboutOptions, type AnchoredPanel, type AnchoredPanelOptions, type Child, type Comment, type CommentMessage, type CommentsOptions, type ConfirmOptions, type DocLine, type DupGuard, type ElProps, type GameIdEditorOptions, type IconName, type IconSvgName, type Identity, type IdentityOptions, type JobProgressOptions, type JobProgressView, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButtonOptions, type SaveController, type SaveControllerOptions, type SaveIndicator, type SaveStatus, type SettingsDialog, type SettingsDialogOptions, type SettingsSection, type SettingsSectionHandle, type ShardVc, type StaleBarOptions, type StepperBarOptions, type StepperItem, type StepperTone, type TipRect, type TooltipOptions, type VcMap, askIdentity, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isValidGameId, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, renderStepperBar, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
package/dist/index.d.ts CHANGED
@@ -237,6 +237,16 @@ interface ConfirmOptions {
237
237
  /** Resolves true on confirm; false on Cancel / Esc / backdrop. */
238
238
  declare function confirmDialog(opts: ConfirmOptions): Promise<boolean>;
239
239
 
240
+ /**
241
+ * Play the close animation on `element`, then run `done` exactly once.
242
+ *
243
+ * `done` does the real teardown: remove the node, drop listeners, unmount
244
+ * whatever was inside it. Under `prefers-reduced-motion` the duration reads 0
245
+ * and `done` runs synchronously, so reduced motion means instant rather than
246
+ * an invisible wait.
247
+ */
248
+ declare function closeWithExit(element: HTMLElement, done: () => void): void;
249
+
240
250
  interface AboutOptions {
241
251
  /** The product's name, large. */
242
252
  appName: string;
@@ -452,6 +462,19 @@ interface CommentsOptions {
452
462
  deleteMessage?: (threadId: string, index: number) => void;
453
463
  /** Where the panel sits: "centre" for a point on a canvas (see anchored.ts). */
454
464
  prefer?: "left" | "below" | "centre";
465
+ /**
466
+ * The text a thread is pinned to, shown above it as a quotation.
467
+ *
468
+ * A callback rather than a field on `Comment`, because resolving an anchor is
469
+ * the APP's half of the seam and this is only that resolution rendered: an app
470
+ * that pins threads to a span of prose can quote it, one that pins them to a
471
+ * whole card has nothing to quote and passes nothing. Keeping it out of the
472
+ * thread type also means no change to what is written to disk, which matters
473
+ * for files living in version control.
474
+ *
475
+ * Return undefined (or "") for a thread with no quotable anchor.
476
+ */
477
+ quoteFor?: (thread: Comment) => string | undefined;
455
478
  }
456
479
  declare function openComments(opts: CommentsOptions): void;
457
480
 
@@ -570,4 +593,81 @@ interface SaveController {
570
593
  }
571
594
  declare function createSaveController(opts: SaveControllerOptions): SaveController;
572
595
 
573
- export { type AboutOptions, type AnchoredPanel, type AnchoredPanelOptions, type Child, type Comment, type CommentMessage, type CommentsOptions, type ConfirmOptions, type DocLine, type DupGuard, type ElProps, type GameIdEditorOptions, type IconName, type IconSvgName, type Identity, type IdentityOptions, type JobProgressOptions, type JobProgressView, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButtonOptions, type SaveController, type SaveControllerOptions, type SaveStatus, type SettingsDialog, type SettingsDialogOptions, type SettingsSection, type SettingsSectionHandle, type ShardVc, type TipRect, type TooltipOptions, type VcMap, askIdentity, closeAnchoredPanel, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isValidGameId, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, showAbout, tagChips, tipAt, tipBold, vcBadgeFor };
596
+ interface SaveIndicator {
597
+ /** Put it in the topbar. */
598
+ readonly el: HTMLElement;
599
+ /** Wire straight to the controller's `onStatus`. */
600
+ set(status: SaveStatus): void;
601
+ }
602
+ declare function saveIndicator(initial?: SaveStatus): SaveIndicator;
603
+
604
+ interface StaleBarOptions {
605
+ /**
606
+ * What went out of date, as a capitalised noun phrase: "The project", "The
607
+ * scene". Written into "<subject> changed in the editor."
608
+ */
609
+ subject: string;
610
+ /** Start again from the current source. */
611
+ onRestart: () => void;
612
+ /** The button, when "Restart" is not the app's word for it. */
613
+ restartLabel?: string;
614
+ /**
615
+ * The rest of the sentence, for an app whose session is not a PLAY: the
616
+ * default is "Restart to play the new version."
617
+ */
618
+ advice?: string;
619
+ }
620
+ declare function staleBar(opts: StaleBarOptions): HTMLElement;
621
+
622
+ interface StepperItem {
623
+ /**
624
+ * One word for what kind of thing this is: "error", "comment", "resolved".
625
+ * Absent when the bar carries one kind of thing only.
626
+ */
627
+ kind?: string;
628
+ /** An extra class on the kind chip, so an app can colour its own kinds
629
+ * (Storyletter's `sev-error`, and `done` for a resolved thread). */
630
+ kindClass?: string;
631
+ /** Where it is, in the app's own address. Set in the mono face. */
632
+ where?: string;
633
+ /** The entry itself, in one line. Overflow is clipped, not wrapped: the bar
634
+ * is one row high and stays that way however long the sentence is. */
635
+ text: string;
636
+ }
637
+ /** How loud the count is. The app picks; the palette supplies the value. */
638
+ type StepperTone = "danger" | "warn" | "accent" | "muted";
639
+ interface StepperBarOptions {
640
+ items: StepperItem[];
641
+ /** Which one is current. Clamped, so a shrinking list cannot point off the end. */
642
+ at: number;
643
+ tone?: StepperTone;
644
+ /** Go to another index. The bar wraps, so this is always in range. */
645
+ onStep: (next: number) => void;
646
+ /** Take me to what the current entry is about. */
647
+ onGo: (index: number) => void;
648
+ /** What the three controls say they do. Keyboard shortcuts belong in here. */
649
+ tips?: {
650
+ prev?: string;
651
+ next?: string;
652
+ go?: string;
653
+ };
654
+ /**
655
+ * What to say when the list is empty.
656
+ *
657
+ * Absent hides the bar, which is right for an AMBIENT bar: no problems, no
658
+ * problems bar. Present keeps it up, which is right for a MODE: entering the
659
+ * walk and seeing nothing at all reads as a broken command rather than as
660
+ * "there is no feedback".
661
+ */
662
+ empty?: string;
663
+ /** Leave the mode. Drawn as the last control, hard right. */
664
+ onClose?: () => void;
665
+ closeTip?: string;
666
+ /** The right-hand end before the close: a quick fix, say. Nulls are skipped,
667
+ * so a caller can pass a conditional straight in. */
668
+ actions?: (HTMLElement | null | undefined)[];
669
+ }
670
+ /** Draw (or hide) the bar in `host`. Idempotent: call it again with new state. */
671
+ declare function renderStepperBar(host: HTMLElement, opts: StepperBarOptions): void;
672
+
673
+ export { type AboutOptions, type AnchoredPanel, type AnchoredPanelOptions, type Child, type Comment, type CommentMessage, type CommentsOptions, type ConfirmOptions, type DocLine, type DupGuard, type ElProps, type GameIdEditorOptions, type IconName, type IconSvgName, type Identity, type IdentityOptions, type JobProgressOptions, type JobProgressView, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButtonOptions, type SaveController, type SaveControllerOptions, type SaveIndicator, type SaveStatus, type SettingsDialog, type SettingsDialogOptions, type SettingsSection, type SettingsSectionHandle, type ShardVc, type StaleBarOptions, type StepperBarOptions, type StepperItem, type StepperTone, type TipRect, type TooltipOptions, type VcMap, askIdentity, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isValidGameId, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, renderStepperBar, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
package/dist/index.js CHANGED
@@ -476,6 +476,29 @@ function pinButton(opts) {
476
476
  return b;
477
477
  }
478
478
 
479
+ // src/exit.ts
480
+ function closeWithExit(element, done) {
481
+ element.classList.add("closing");
482
+ const seconds = parseFloat(getComputedStyle(element).animationDuration) || 0;
483
+ if (seconds === 0) {
484
+ done();
485
+ return;
486
+ }
487
+ let fired = false;
488
+ const finish = () => {
489
+ if (fired) return;
490
+ fired = true;
491
+ element.removeEventListener("animationend", onEnd);
492
+ clearTimeout(timer2);
493
+ done();
494
+ };
495
+ const onEnd = (e) => {
496
+ if (e.target === element) finish();
497
+ };
498
+ element.addEventListener("animationend", onEnd);
499
+ const timer2 = setTimeout(finish, seconds * 1e3 + 120);
500
+ }
501
+
479
502
  // src/confirm.ts
480
503
  function confirmDialog(opts) {
481
504
  return new Promise((resolve) => {
@@ -497,21 +520,9 @@ function confirmDialog(opts) {
497
520
  if (done) return;
498
521
  done = true;
499
522
  resolve(ok);
500
- dlg.classList.add("closing");
501
- const dur = parseFloat(getComputedStyle(dlg).animationDuration) || 0;
502
- const teardown = () => {
523
+ closeWithExit(dlg, () => {
503
524
  dlg.close();
504
525
  dlg.remove();
505
- };
506
- if (dur === 0) {
507
- teardown();
508
- return;
509
- }
510
- const timer2 = setTimeout(teardown, dur * 1e3 + 120);
511
- dlg.addEventListener("animationend", (e) => {
512
- if (e.target !== dlg) return;
513
- clearTimeout(timer2);
514
- teardown();
515
526
  });
516
527
  };
517
528
  cancel.addEventListener("click", () => finish(false));
@@ -604,8 +615,10 @@ function openAnchoredPanel(opts) {
604
615
  if (current?.panel === panel) current = null;
605
616
  document.removeEventListener("pointerdown", onDown, true);
606
617
  document.removeEventListener("keydown", onKey, true);
607
- panel.remove();
608
- opts.onClose?.();
618
+ closeWithExit(panel, () => {
619
+ opts.onClose?.();
620
+ panel.remove();
621
+ });
609
622
  };
610
623
  closeBtn.addEventListener("click", close);
611
624
  const onDown = (e) => {
@@ -1025,6 +1038,10 @@ function openComments(opts) {
1025
1038
  }
1026
1039
  const thread = open;
1027
1040
  if (thread) {
1041
+ const quote = opts.quoteFor?.(thread);
1042
+ if (quote !== void 0 && quote !== "") {
1043
+ body.append(el("blockquote", { className: "shell-cmt-quote", text: quote }));
1044
+ }
1028
1045
  const list = el("div", { className: `shell-cmt-list${thread.resolved === true ? " resolved" : ""}` });
1029
1046
  thread.messages.forEach((message, index) => {
1030
1047
  const head = el(
@@ -1373,6 +1390,99 @@ function createSaveController(opts) {
1373
1390
  };
1374
1391
  }
1375
1392
 
1376
- export { PALETTE, PALETTE_SIZE, askIdentity, closeAnchoredPanel, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isValidGameId, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, showAbout, tagChips, tipAt, tipBold, vcBadgeFor };
1393
+ // src/save-view.ts
1394
+ var WORDS = {
1395
+ saved: "Saved",
1396
+ saving: "Saving\u2026",
1397
+ unsaved: "Unsaved"
1398
+ };
1399
+ function saveIndicator(initial = "saved") {
1400
+ const node = el("span");
1401
+ const set = (status) => {
1402
+ node.className = `savestat ${status}`;
1403
+ node.textContent = WORDS[status];
1404
+ };
1405
+ set(initial);
1406
+ return { el: node, set };
1407
+ }
1408
+
1409
+ // src/stale.ts
1410
+ function staleBar(opts) {
1411
+ const label2 = opts.restartLabel ?? "Restart";
1412
+ return el(
1413
+ "div",
1414
+ { className: "stale-bar" },
1415
+ el("span", {
1416
+ className: "stale-bar-msg",
1417
+ text: `${opts.subject} changed in the editor. ${opts.advice ?? "Restart to play the new version."}`
1418
+ }),
1419
+ el("button", {
1420
+ className: "stale-bar-go",
1421
+ text: `${icon.restart} ${label2}`,
1422
+ onClick: () => opts.onRestart()
1423
+ })
1424
+ );
1425
+ }
1426
+
1427
+ // src/stepper.ts
1428
+ function renderStepperBar(host, opts) {
1429
+ const { items } = opts;
1430
+ const close = opts.onClose === void 0 ? null : el("button", {
1431
+ className: "stepbar-nav stepbar-close",
1432
+ text: icon.close,
1433
+ tip: opts.closeTip ?? "Close",
1434
+ onClick: opts.onClose
1435
+ });
1436
+ const actions = (opts.actions ?? []).filter((a) => a !== null && a !== void 0);
1437
+ if (items.length === 0) {
1438
+ if (opts.empty === void 0) {
1439
+ host.hidden = true;
1440
+ host.replaceChildren();
1441
+ return;
1442
+ }
1443
+ host.hidden = false;
1444
+ host.replaceChildren(
1445
+ el("span", { className: "stepbar-count muted", text: "0" }),
1446
+ el("span", { className: "stepbar-empty", text: opts.empty }),
1447
+ ...actions,
1448
+ ...close ? [close] : []
1449
+ );
1450
+ return;
1451
+ }
1452
+ host.hidden = false;
1453
+ const index = Math.min(Math.max(opts.at, 0), items.length - 1);
1454
+ const item = items[index];
1455
+ const step = (delta) => opts.onStep((index + delta + items.length) % items.length);
1456
+ const nav = items.length > 1 ? [
1457
+ el("button", {
1458
+ className: "stepbar-nav",
1459
+ text: icon.back,
1460
+ tip: opts.tips?.prev ?? "Previous",
1461
+ onClick: () => step(-1)
1462
+ }),
1463
+ el("span", { className: "stepbar-of", text: `${index + 1}/${items.length}` }),
1464
+ el("button", {
1465
+ className: "stepbar-nav",
1466
+ text: icon.forward,
1467
+ tip: opts.tips?.next ?? "Next",
1468
+ onClick: () => step(1)
1469
+ })
1470
+ ] : [];
1471
+ host.replaceChildren(
1472
+ el("span", { className: `stepbar-count ${opts.tone ?? "muted"}`, text: String(items.length) }),
1473
+ ...nav,
1474
+ el(
1475
+ "button",
1476
+ { className: "stepbar-cur", tip: opts.tips?.go ?? "Go to this", onClick: () => opts.onGo(index) },
1477
+ item.kind === void 0 ? null : el("span", { className: `stepbar-cat${item.kindClass ? ` ${item.kindClass}` : ""}`, text: item.kind }),
1478
+ item.where === void 0 ? null : el("span", { className: "stepbar-where", text: item.where }),
1479
+ el("span", { className: "stepbar-msg", text: item.text })
1480
+ ),
1481
+ ...actions,
1482
+ ...close ? [close] : []
1483
+ );
1484
+ }
1485
+
1486
+ export { PALETTE, PALETTE_SIZE, askIdentity, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isValidGameId, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, renderStepperBar, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
1377
1487
  //# sourceMappingURL=index.js.map
1378
1488
  //# sourceMappingURL=index.js.map