@wildwinter/app-shell 0.36.0 → 0.38.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
@@ -193,11 +193,29 @@ declare function mountPaneShell(host: HTMLElement, opts: PaneShellOptions): Pane
193
193
 
194
194
  /** A compact list row: a single `.set-rowline` (inline controls) plus, when
195
195
  * `details` are given, a disclosure that reveals a `.set-details` panel below,
196
- * so a list scans like a table with secondary fields tucked away. */
196
+ * so a list scans like a table with secondary fields tucked away. `name` is
197
+ * what the row declares (a property's name, a field's), stamped on it as
198
+ * `data-name` so `revealRow` can land on it. */
197
199
  declare function expandableRow(opts: {
198
200
  line: HTMLElement[];
199
201
  details?: HTMLElement[];
202
+ name?: string;
200
203
  }): HTMLElement;
204
+ /**
205
+ * Land on one row of a list by the `name` it was built with: open its details
206
+ * (an enum's values sit behind the disclosure, and they are usually what the
207
+ * jump was for), bring it to the middle of its scroller, and light it for a
208
+ * moment (`.set-row.landed` in settings.css). "Go to definition" in both apps
209
+ * used to open the page a property is declared on and stop there, with the
210
+ * declaration below the fold and nothing marking it (Storyletter, 2026-09-14).
211
+ *
212
+ * Returns false when no row carries the name, so a host whose page fills in
213
+ * asynchronously can ask again on a later frame; asking again is the host's,
214
+ * since only the host knows what opens on its own time. The row is matched by
215
+ * reading the stamp rather than by an attribute selector, so a name needs no
216
+ * escaping.
217
+ */
218
+ declare function revealRow(within: ParentNode, name: string): boolean;
201
219
  /** After a "+ Add" re-renders a list, bring the new (last) row into view and
202
220
  * focus its name input (`.set-name`, else the first input). */
203
221
  declare function focusNewRow(listEl: HTMLElement | null | undefined): void;
@@ -785,6 +803,25 @@ interface StaleBarOptions {
785
803
  }
786
804
  declare function staleBar(opts: StaleBarOptions): HTMLElement;
787
805
 
806
+ /** What the remark is about. `info` is the plain case; `ok` says a thing you
807
+ * asked for happened; `error` says it did not. */
808
+ type ToastKind = "info" | "ok" | "error";
809
+ interface ToastOptions {
810
+ /** How long it stays, in ms, before the exit plays. Defaults to 4000, or
811
+ * 7000 for an error. */
812
+ duration?: number;
813
+ }
814
+ /**
815
+ * Show a toast. Replaces any toast already showing.
816
+ *
817
+ * `message` is shown as written; a newline breaks the line ("Bundle
818
+ * published\n<path>"), and a long unbroken token such as a path wraps inside
819
+ * the card rather than spilling past it.
820
+ */
821
+ declare function toast(message: string, kind?: ToastKind, opts?: ToastOptions): void;
822
+ /** Dismiss the current toast now, if any. Plays the exit. */
823
+ declare function dismissToast(): void;
824
+
788
825
  interface StepperItem {
789
826
  /**
790
827
  * One word for what kind of thing this is: "error", "comment", "resolved".
@@ -881,4 +918,4 @@ declare function historyNav(onBack: () => void, onForward: () => void): {
881
918
  set(canBack: boolean, canForward: boolean): void;
882
919
  };
883
920
 
884
- 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 NavHistory, type NavHistoryOptions, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButton, type PinButtonOptions, type PropertyRefOptions, RESERVED_PROPERTY_NAMES, 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, bindPropertyName, bindPropertyRef, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createNavHistory, createSaveController, dupGuard, el, expandableRow, firstIllegalPropertyName, focusNewRow, foldVc, gameIdify, hideTip, historyNav, icon, iconBtn, iconSvg, initTooltips, isCaseOnlyPropertyName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, propertyRefProblem, renderStepperBar, revalidatePropertyRefs, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
921
+ 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 NavHistory, type NavHistoryOptions, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButton, type PinButtonOptions, type PropertyRefOptions, RESERVED_PROPERTY_NAMES, 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 ToastKind, type ToastOptions, type TooltipOptions, type VcMap, askIdentity, bindPropertyName, bindPropertyRef, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createNavHistory, createSaveController, dismissToast, dupGuard, el, expandableRow, firstIllegalPropertyName, focusNewRow, foldVc, gameIdify, hideTip, historyNav, icon, iconBtn, iconSvg, initTooltips, isCaseOnlyPropertyName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, propertyRefProblem, renderStepperBar, revalidatePropertyRefs, revealRow, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, toast, vcBadgeFor };
package/dist/index.d.ts CHANGED
@@ -193,11 +193,29 @@ declare function mountPaneShell(host: HTMLElement, opts: PaneShellOptions): Pane
193
193
 
194
194
  /** A compact list row: a single `.set-rowline` (inline controls) plus, when
195
195
  * `details` are given, a disclosure that reveals a `.set-details` panel below,
196
- * so a list scans like a table with secondary fields tucked away. */
196
+ * so a list scans like a table with secondary fields tucked away. `name` is
197
+ * what the row declares (a property's name, a field's), stamped on it as
198
+ * `data-name` so `revealRow` can land on it. */
197
199
  declare function expandableRow(opts: {
198
200
  line: HTMLElement[];
199
201
  details?: HTMLElement[];
202
+ name?: string;
200
203
  }): HTMLElement;
204
+ /**
205
+ * Land on one row of a list by the `name` it was built with: open its details
206
+ * (an enum's values sit behind the disclosure, and they are usually what the
207
+ * jump was for), bring it to the middle of its scroller, and light it for a
208
+ * moment (`.set-row.landed` in settings.css). "Go to definition" in both apps
209
+ * used to open the page a property is declared on and stop there, with the
210
+ * declaration below the fold and nothing marking it (Storyletter, 2026-09-14).
211
+ *
212
+ * Returns false when no row carries the name, so a host whose page fills in
213
+ * asynchronously can ask again on a later frame; asking again is the host's,
214
+ * since only the host knows what opens on its own time. The row is matched by
215
+ * reading the stamp rather than by an attribute selector, so a name needs no
216
+ * escaping.
217
+ */
218
+ declare function revealRow(within: ParentNode, name: string): boolean;
201
219
  /** After a "+ Add" re-renders a list, bring the new (last) row into view and
202
220
  * focus its name input (`.set-name`, else the first input). */
203
221
  declare function focusNewRow(listEl: HTMLElement | null | undefined): void;
@@ -785,6 +803,25 @@ interface StaleBarOptions {
785
803
  }
786
804
  declare function staleBar(opts: StaleBarOptions): HTMLElement;
787
805
 
806
+ /** What the remark is about. `info` is the plain case; `ok` says a thing you
807
+ * asked for happened; `error` says it did not. */
808
+ type ToastKind = "info" | "ok" | "error";
809
+ interface ToastOptions {
810
+ /** How long it stays, in ms, before the exit plays. Defaults to 4000, or
811
+ * 7000 for an error. */
812
+ duration?: number;
813
+ }
814
+ /**
815
+ * Show a toast. Replaces any toast already showing.
816
+ *
817
+ * `message` is shown as written; a newline breaks the line ("Bundle
818
+ * published\n<path>"), and a long unbroken token such as a path wraps inside
819
+ * the card rather than spilling past it.
820
+ */
821
+ declare function toast(message: string, kind?: ToastKind, opts?: ToastOptions): void;
822
+ /** Dismiss the current toast now, if any. Plays the exit. */
823
+ declare function dismissToast(): void;
824
+
788
825
  interface StepperItem {
789
826
  /**
790
827
  * One word for what kind of thing this is: "error", "comment", "resolved".
@@ -881,4 +918,4 @@ declare function historyNav(onBack: () => void, onForward: () => void): {
881
918
  set(canBack: boolean, canForward: boolean): void;
882
919
  };
883
920
 
884
- 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 NavHistory, type NavHistoryOptions, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButton, type PinButtonOptions, type PropertyRefOptions, RESERVED_PROPERTY_NAMES, 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, bindPropertyName, bindPropertyRef, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createNavHistory, createSaveController, dupGuard, el, expandableRow, firstIllegalPropertyName, focusNewRow, foldVc, gameIdify, hideTip, historyNav, icon, iconBtn, iconSvg, initTooltips, isCaseOnlyPropertyName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, propertyRefProblem, renderStepperBar, revalidatePropertyRefs, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
921
+ 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 NavHistory, type NavHistoryOptions, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButton, type PinButtonOptions, type PropertyRefOptions, RESERVED_PROPERTY_NAMES, 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 ToastKind, type ToastOptions, type TooltipOptions, type VcMap, askIdentity, bindPropertyName, bindPropertyRef, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createNavHistory, createSaveController, dismissToast, dupGuard, el, expandableRow, firstIllegalPropertyName, focusNewRow, foldVc, gameIdify, hideTip, historyNav, icon, iconBtn, iconSvg, initTooltips, isCaseOnlyPropertyName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, propertyRefProblem, renderStepperBar, revalidatePropertyRefs, revealRow, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, toast, vcBadgeFor };
package/dist/index.js CHANGED
@@ -152,23 +152,23 @@ function initTooltips(opts = {}) {
152
152
 
153
153
  // src/dom.ts
154
154
  function el(tag, classNameOrProps, ...children) {
155
- const node = document.createElement(tag);
155
+ const node2 = document.createElement(tag);
156
156
  const props = typeof classNameOrProps === "string" ? { className: classNameOrProps } : classNameOrProps ?? {};
157
- if (props.className) node.className = props.className;
158
- if (props.text !== void 0 && props.text !== null) node.textContent = props.text;
159
- if (props.title !== void 0) node.title = props.title;
157
+ if (props.className) node2.className = props.className;
158
+ if (props.text !== void 0 && props.text !== null) node2.textContent = props.text;
159
+ if (props.title !== void 0) node2.title = props.title;
160
160
  if (props.tip !== void 0) {
161
- node.dataset["tip"] = props.tip;
162
- node.setAttribute("aria-label", props.tip);
161
+ node2.dataset["tip"] = props.tip;
162
+ node2.setAttribute("aria-label", props.tip);
163
163
  ensureTooltipHost();
164
164
  }
165
- if (props.onClick) node.addEventListener("click", props.onClick);
165
+ if (props.onClick) node2.addEventListener("click", props.onClick);
166
166
  for (const child of children) {
167
167
  if (child === null || child === void 0) continue;
168
- node.append(child);
168
+ node2.append(child);
169
169
  }
170
170
  checkTooltipHost();
171
- return node;
171
+ return node2;
172
172
  }
173
173
  function iconBtn(glyph, title, onClick, disabled = false, danger = false) {
174
174
  const b = el("button", `shell-icon${danger ? " danger" : ""}`);
@@ -200,7 +200,7 @@ function tagChips(holder, onChange) {
200
200
  const wrap = el("div", "shell-tags");
201
201
  const input = el("input", "shell-tag-input");
202
202
  input.type = "text";
203
- input.placeholder = "add value";
203
+ input.placeholder = "Add value";
204
204
  input.spellcheck = false;
205
205
  const makeChip = (v) => {
206
206
  const chip = el("span", "shell-tag", v);
@@ -470,6 +470,7 @@ function mountPaneShell(host, opts) {
470
470
  // src/settings.ts
471
471
  function expandableRow(opts) {
472
472
  const row = el("div", "set-row");
473
+ if (opts.name !== void 0) row.dataset.name = opts.name;
473
474
  const line = el("div", "set-rowline");
474
475
  if (opts.details && opts.details.length) {
475
476
  const details = el("div", "set-details");
@@ -495,6 +496,19 @@ function expandableRow(opts) {
495
496
  }
496
497
  return row;
497
498
  }
499
+ function revealRow(within, name) {
500
+ const row = [...within.querySelectorAll(".set-row")].find((r) => r.dataset.name === name);
501
+ if (!row) return false;
502
+ const toggle = row.querySelector(".set-rowline > .set-expand");
503
+ if (toggle && toggle.getAttribute("aria-expanded") !== "true") toggle.click();
504
+ const still = typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
505
+ row.scrollIntoView({ block: "center", behavior: still ? "auto" : "smooth" });
506
+ row.classList.remove("landed");
507
+ void row.offsetWidth;
508
+ row.classList.add("landed");
509
+ row.addEventListener("animationend", () => row.classList.remove("landed"), { once: true });
510
+ return true;
511
+ }
498
512
  function focusNewRow(listEl) {
499
513
  const last = listEl?.lastElementChild;
500
514
  if (!(last instanceof HTMLElement)) return;
@@ -664,14 +678,14 @@ function closeWithExit(element, done) {
664
678
  if (fired) return;
665
679
  fired = true;
666
680
  element.removeEventListener("animationend", onEnd);
667
- clearTimeout(timer2);
681
+ clearTimeout(timer3);
668
682
  done();
669
683
  };
670
684
  const onEnd = (e) => {
671
685
  if (e.target === element) finish();
672
686
  };
673
687
  element.addEventListener("animationend", onEnd);
674
- const timer2 = setTimeout(finish, seconds * 1e3 + 120);
688
+ const timer3 = setTimeout(finish, seconds * 1e3 + 120);
675
689
  }
676
690
 
677
691
  // src/confirm.ts
@@ -1511,7 +1525,7 @@ function createSaveController(opts) {
1511
1525
  let auto = true;
1512
1526
  let dirty = false;
1513
1527
  let dirtySince = 0;
1514
- let timer2;
1528
+ let timer3;
1515
1529
  let inFlight;
1516
1530
  const setStatus = (next) => {
1517
1531
  if (next === status) return;
@@ -1519,17 +1533,17 @@ function createSaveController(opts) {
1519
1533
  opts.onStatus?.(status);
1520
1534
  };
1521
1535
  const clearTimer = () => {
1522
- if (timer2 === void 0) return;
1523
- clearTimeout(timer2);
1524
- timer2 = void 0;
1536
+ if (timer3 === void 0) return;
1537
+ clearTimeout(timer3);
1538
+ timer3 = void 0;
1525
1539
  };
1526
1540
  const arm = () => {
1527
1541
  clearTimer();
1528
1542
  if (!auto) return;
1529
1543
  const deadline = dirtySince + maxWaitMs;
1530
1544
  const wait = Math.max(0, Math.min(delayMs, deadline - Date.now()));
1531
- timer2 = setTimeout(() => {
1532
- timer2 = void 0;
1545
+ timer3 = setTimeout(() => {
1546
+ timer3 = void 0;
1533
1547
  void run();
1534
1548
  }, wait);
1535
1549
  };
@@ -1603,13 +1617,13 @@ var WORDS = {
1603
1617
  unsaved: "Unsaved"
1604
1618
  };
1605
1619
  function saveIndicator(initial = "saved") {
1606
- const node = el("span");
1620
+ const node2 = el("span");
1607
1621
  const set = (status) => {
1608
- node.className = `savestat ${status}`;
1609
- node.textContent = WORDS[status];
1622
+ node2.className = `savestat ${status}`;
1623
+ node2.textContent = WORDS[status];
1610
1624
  };
1611
1625
  set(initial);
1612
- return { el: node, set };
1626
+ return { el: node2, set };
1613
1627
  }
1614
1628
 
1615
1629
  // src/stale.ts
@@ -1630,6 +1644,43 @@ function staleBar(opts) {
1630
1644
  );
1631
1645
  }
1632
1646
 
1647
+ // src/toast.ts
1648
+ var DURATION = { info: 4e3, ok: 4e3, error: 7e3 };
1649
+ var node;
1650
+ var timer2 = 0;
1651
+ var seq = 0;
1652
+ function mount() {
1653
+ if (node && node.isConnected) return node;
1654
+ node = el("div", { className: "shell-toast" });
1655
+ node.setAttribute("role", "status");
1656
+ node.setAttribute("aria-live", "polite");
1657
+ node.hidden = true;
1658
+ document.body.append(node);
1659
+ return node;
1660
+ }
1661
+ function toast(message, kind = "info", opts = {}) {
1662
+ const t = mount();
1663
+ const id = ++seq;
1664
+ t.textContent = message;
1665
+ t.className = `shell-toast ${kind}`;
1666
+ t.hidden = false;
1667
+ window.clearTimeout(timer2);
1668
+ timer2 = window.setTimeout(() => {
1669
+ closeWithExit(t, () => {
1670
+ if (seq === id) t.hidden = true;
1671
+ });
1672
+ }, opts.duration ?? DURATION[kind]);
1673
+ }
1674
+ function dismissToast() {
1675
+ if (!node || node.hidden) return;
1676
+ window.clearTimeout(timer2);
1677
+ const id = seq;
1678
+ const t = node;
1679
+ closeWithExit(t, () => {
1680
+ if (seq === id) t.hidden = true;
1681
+ });
1682
+ }
1683
+
1633
1684
  // src/stepper.ts
1634
1685
  function renderStepperBar(host, opts) {
1635
1686
  const { items } = opts;
@@ -1752,6 +1803,6 @@ function historyNav(onBack, onForward) {
1752
1803
  };
1753
1804
  }
1754
1805
 
1755
- export { PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, RESERVED_PROPERTY_NAMES, askIdentity, bindPropertyName, bindPropertyRef, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createNavHistory, createSaveController, dupGuard, el, expandableRow, firstIllegalPropertyName, focusNewRow, foldVc, gameIdify, hideTip, historyNav, icon, iconBtn, iconSvg, initTooltips, isCaseOnlyPropertyName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, propertyRefProblem, renderStepperBar, revalidatePropertyRefs, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
1806
+ export { PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, RESERVED_PROPERTY_NAMES, askIdentity, bindPropertyName, bindPropertyRef, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createNavHistory, createSaveController, dismissToast, dupGuard, el, expandableRow, firstIllegalPropertyName, focusNewRow, foldVc, gameIdify, hideTip, historyNav, icon, iconBtn, iconSvg, initTooltips, isCaseOnlyPropertyName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, propertyRefProblem, renderStepperBar, revalidatePropertyRefs, revealRow, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, toast, vcBadgeFor };
1756
1807
  //# sourceMappingURL=index.js.map
1757
1808
  //# sourceMappingURL=index.js.map