@flytedan/flytebot-design-system 0.51.3 → 0.51.4

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.cjs CHANGED
@@ -70,6 +70,7 @@ __export(index_exports, {
70
70
  CodeEditor: () => CodeEditor,
71
71
  Collapsible: () => Collapsible,
72
72
  ComingSoon: () => ComingSoon,
73
+ CornerStackPortal: () => CornerStackPortal,
73
74
  CsiBadge: () => CsiBadge,
74
75
  CsiHero: () => CsiHero,
75
76
  CsiMeter: () => CsiMeter,
@@ -238,6 +239,7 @@ __export(index_exports, {
238
239
  useAppearancePrefs: () => useAppearancePrefs,
239
240
  useChatEngine: () => useChatEngine,
240
241
  useCopyToClipboard: () => useCopyToClipboard,
242
+ useCornerStackSlot: () => useCornerStackSlot,
241
243
  useDocumentTitle: () => useDocumentTitle,
242
244
  useFeatureStatus: () => useFeatureStatus,
243
245
  useLayerZIndex: () => useLayerZIndex,
@@ -1379,7 +1381,60 @@ function LoadingRegion({
1379
1381
  }
1380
1382
 
1381
1383
  // src/components/loading/JobTray.tsx
1384
+ var React10 = __toESM(require("react"), 1);
1385
+
1386
+ // src/kits/cornerStack.tsx
1382
1387
  var React9 = __toESM(require("react"), 1);
1388
+ var import_react_dom5 = require("react-dom");
1389
+ var SLOTS = ["jobs", "toasts"];
1390
+ var references = /* @__PURE__ */ new Map();
1391
+ var host = null;
1392
+ var slotElements = /* @__PURE__ */ new Map();
1393
+ function createHost() {
1394
+ const stack = document.createElement("div");
1395
+ stack.className = "fd-corner-stack";
1396
+ stack.style.zIndex = String(OVERLAY_CEILING);
1397
+ for (const slot of SLOTS) {
1398
+ const element = document.createElement("div");
1399
+ element.className = "fd-corner-stack-slot";
1400
+ element.dataset.cornerStackSlot = slot;
1401
+ stack.appendChild(element);
1402
+ slotElements.set(slot, element);
1403
+ }
1404
+ document.body.appendChild(stack);
1405
+ return stack;
1406
+ }
1407
+ function acquire(slot) {
1408
+ host ??= createHost();
1409
+ references.set(slot, (references.get(slot) ?? 0) + 1);
1410
+ return slotElements.get(slot);
1411
+ }
1412
+ function release(slot) {
1413
+ const remaining = (references.get(slot) ?? 1) - 1;
1414
+ if (remaining > 0) references.set(slot, remaining);
1415
+ else references.delete(slot);
1416
+ if (references.size === 0 && host) {
1417
+ host.remove();
1418
+ host = null;
1419
+ slotElements.clear();
1420
+ }
1421
+ }
1422
+ var useSlotEffect = typeof document === "undefined" ? React9.useEffect : React9.useLayoutEffect;
1423
+ function useCornerStackSlot(slot) {
1424
+ const [element, setElement] = React9.useState(null);
1425
+ useSlotEffect(() => {
1426
+ setElement(acquire(slot));
1427
+ return () => {
1428
+ release(slot);
1429
+ setElement(null);
1430
+ };
1431
+ }, [slot]);
1432
+ return element;
1433
+ }
1434
+ function CornerStackPortal({ slot, children }) {
1435
+ const element = useCornerStackSlot(slot);
1436
+ return element ? (0, import_react_dom5.createPortal)(children, element) : null;
1437
+ }
1383
1438
 
1384
1439
  // src/components/loading/ProgressBar.tsx
1385
1440
  var import_jsx_runtime14 = require("react/jsx-runtime");
@@ -1423,9 +1478,9 @@ function announcementFor(job) {
1423
1478
  return title + ": in progress";
1424
1479
  }
1425
1480
  function JobTray({ jobs: jobs2, onDismiss, className = "" }) {
1426
- const [announcement, setAnnouncement] = React9.useState("");
1427
- const prevStatuses = React9.useRef({});
1428
- React9.useEffect(() => {
1481
+ const [announcement, setAnnouncement] = React10.useState("");
1482
+ const prevStatuses = React10.useRef({});
1483
+ React10.useEffect(() => {
1429
1484
  let next = "";
1430
1485
  for (const job of jobs2) {
1431
1486
  if (prevStatuses.current[job.id] !== job.status) {
@@ -1438,10 +1493,10 @@ function JobTray({ jobs: jobs2, onDismiss, className = "" }) {
1438
1493
  if (next) setAnnouncement(next);
1439
1494
  }, [jobs2]);
1440
1495
  if (jobs2.length === 0) return null;
1441
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: ["fd-job-tray", className].filter(Boolean).join(" "), children: [
1496
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CornerStackPortal, { slot: "jobs", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: ["fd-job-tray", className].filter(Boolean).join(" "), children: [
1442
1497
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "fd-sr", role: "status", "aria-live": "polite", children: announcement }),
1443
1498
  jobs2.map((job) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(JobCard, { job, onDismiss }, job.id))
1444
- ] });
1499
+ ] }) });
1445
1500
  }
1446
1501
  function JobCard({ job, onDismiss }) {
1447
1502
  const title = textOf(job.title) || "Job";
@@ -1476,7 +1531,7 @@ function JobCard({ job, onDismiss }) {
1476
1531
  }
1477
1532
 
1478
1533
  // src/components/loading/PhasedProgress.tsx
1479
- var React10 = __toESM(require("react"), 1);
1534
+ var React11 = __toESM(require("react"), 1);
1480
1535
  var import_jsx_runtime16 = require("react/jsx-runtime");
1481
1536
  var ICON = {
1482
1537
  pending: "ph-circle",
@@ -1489,9 +1544,9 @@ function textOf2(node) {
1489
1544
  return "";
1490
1545
  }
1491
1546
  function PhasedProgress({ phases, summary, className = "" }) {
1492
- const [announcement, setAnnouncement] = React10.useState("");
1493
- const prevStatuses = React10.useRef({});
1494
- React10.useEffect(() => {
1547
+ const [announcement, setAnnouncement] = React11.useState("");
1548
+ const prevStatuses = React11.useRef({});
1549
+ React11.useEffect(() => {
1495
1550
  let next = "";
1496
1551
  for (const phase of phases) {
1497
1552
  if (prevStatuses.current[phase.id] !== phase.status) {
@@ -1561,12 +1616,12 @@ function Spinner({ size = "md", label = "Loading", className = "", style, ...res
1561
1616
  }
1562
1617
 
1563
1618
  // src/components/navigation/SidebarNav.tsx
1564
- var React11 = __toESM(require("react"), 1);
1619
+ var React12 = __toESM(require("react"), 1);
1565
1620
  var import_jsx_runtime19 = require("react/jsx-runtime");
1566
1621
  function Tip({ label, children }) {
1567
1622
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { title: label, style: { display: "inline-flex", flex: "none" }, children });
1568
1623
  }
1569
- var SidebarNav = React11.forwardRef(function SidebarNav2({ brand, groups = [], current: current2, onNavigate, footer, open: open2 = false, className = "", ...rest }, ref) {
1624
+ var SidebarNav = React12.forwardRef(function SidebarNav2({ brand, groups = [], current: current2, onNavigate, footer, open: open2 = false, className = "", ...rest }, ref) {
1570
1625
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1571
1626
  "nav",
1572
1627
  {
@@ -1605,13 +1660,13 @@ var SidebarNav = React11.forwardRef(function SidebarNav2({ brand, groups = [], c
1605
1660
  });
1606
1661
 
1607
1662
  // src/components/navigation/Topbar.tsx
1608
- var React12 = __toESM(require("react"), 1);
1663
+ var React13 = __toESM(require("react"), 1);
1609
1664
  var import_jsx_runtime20 = require("react/jsx-runtime");
1610
1665
  function useIsNarrow(breakpoint) {
1611
- const [narrow, setNarrow] = React12.useState(
1666
+ const [narrow, setNarrow] = React13.useState(
1612
1667
  () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
1613
1668
  );
1614
- React12.useEffect(() => {
1669
+ React13.useEffect(() => {
1615
1670
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1616
1671
  const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
1617
1672
  const apply = () => setNarrow(mq.matches);
@@ -1632,11 +1687,11 @@ function Topbar({
1632
1687
  ...rest
1633
1688
  }) {
1634
1689
  const narrow = useIsNarrow(overflowBreakpoint);
1635
- const [moreOpen, setMoreOpen] = React12.useState(false);
1636
- const moreRef = React12.useRef(null);
1690
+ const [moreOpen, setMoreOpen] = React13.useState(false);
1691
+ const moreRef = React13.useRef(null);
1637
1692
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("header", { className: ["fd-topbar", narrow ? "is-narrow" : "", className].filter(Boolean).join(" "), ...rest, children: [
1638
1693
  onMenu ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", className: "fd-btn-icon", "aria-label": "Menu", onClick: onMenu, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("i", { className: "ph ph-list" }) }) : null,
1639
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(React12.Fragment, { children: [
1694
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(React13.Fragment, { children: [
1640
1695
  i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("i", { className: "ph ph-caret-right", style: { fontSize: 11, opacity: 0.6 }, "aria-hidden": "true" }) : null,
1641
1696
  i === crumbs.length - 1 ? (
1642
1697
  // MP-141: the current crumb mixes a static route label with (usually) a
@@ -1689,25 +1744,25 @@ function Topbar({
1689
1744
  }
1690
1745
 
1691
1746
  // src/kits/useResponsiveRail.ts
1692
- var React13 = __toESM(require("react"), 1);
1747
+ var React14 = __toESM(require("react"), 1);
1693
1748
  function matchesBreakpoint(breakpoint) {
1694
1749
  return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches;
1695
1750
  }
1696
1751
  function useResponsiveRail(options = {}) {
1697
1752
  const { breakpoint = 1024, initialOpen = true, onPersist } = options;
1698
- const navRef = React13.useRef(null);
1699
- const [overlay, setOverlay] = React13.useState(() => matchesBreakpoint(breakpoint));
1700
- const [open2, setOpenRaw] = React13.useState(() => matchesBreakpoint(breakpoint) ? false : initialOpen);
1701
- const setOpen = React13.useCallback(
1753
+ const navRef = React14.useRef(null);
1754
+ const [overlay, setOverlay] = React14.useState(() => matchesBreakpoint(breakpoint));
1755
+ const [open2, setOpenRaw] = React14.useState(() => matchesBreakpoint(breakpoint) ? false : initialOpen);
1756
+ const setOpen = React14.useCallback(
1702
1757
  (value) => {
1703
1758
  setOpenRaw(value);
1704
1759
  if (!matchesBreakpoint(breakpoint)) onPersist?.(value);
1705
1760
  },
1706
1761
  [breakpoint, onPersist]
1707
1762
  );
1708
- const toggle = React13.useCallback(() => setOpen(!open2), [open2, setOpen]);
1709
- const close2 = React13.useCallback(() => setOpenRaw(false), []);
1710
- React13.useEffect(() => {
1763
+ const toggle = React14.useCallback(() => setOpen(!open2), [open2, setOpen]);
1764
+ const close2 = React14.useCallback(() => setOpenRaw(false), []);
1765
+ React14.useEffect(() => {
1711
1766
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1712
1767
  const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
1713
1768
  const handler = (e) => {
@@ -1718,7 +1773,7 @@ function useResponsiveRail(options = {}) {
1718
1773
  return () => mq.removeEventListener("change", handler);
1719
1774
  }, [breakpoint]);
1720
1775
  const layer = useStackedLayer({ active: overlay && open2, containerRef: navRef, trap: true, onEscape: close2 });
1721
- React13.useEffect(() => {
1776
+ React14.useEffect(() => {
1722
1777
  if (!overlay || !open2) return;
1723
1778
  const previousOverflow = document.body.style.overflow;
1724
1779
  document.body.style.overflow = "hidden";
@@ -2076,15 +2131,15 @@ function Toast({ title, children, tone = "success", onUndo, onDismiss, className
2076
2131
  }
2077
2132
 
2078
2133
  // src/components/feedback/ToastProvider.tsx
2079
- var React14 = __toESM(require("react"), 1);
2134
+ var React15 = __toESM(require("react"), 1);
2080
2135
  var import_jsx_runtime32 = require("react/jsx-runtime");
2081
2136
  var DEFAULT_TOAST_DURATION_MS = 5e3;
2082
- var ToastContext = React14.createContext(null);
2137
+ var ToastContext = React15.createContext(null);
2083
2138
  function ToastProvider({ children }) {
2084
- const [items, setItems] = React14.useState([]);
2085
- const timers = React14.useRef(/* @__PURE__ */ new Map());
2086
- const nextId = React14.useRef(1);
2087
- const dismiss = React14.useCallback((id) => {
2139
+ const [items, setItems] = React15.useState([]);
2140
+ const timers = React15.useRef(/* @__PURE__ */ new Map());
2141
+ const nextId = React15.useRef(1);
2142
+ const dismiss = React15.useCallback((id) => {
2088
2143
  setItems((current2) => current2.filter((item) => item.id !== id));
2089
2144
  const timer = timers.current.get(id);
2090
2145
  if (timer !== void 0) {
@@ -2092,7 +2147,7 @@ function ToastProvider({ children }) {
2092
2147
  timers.current.delete(id);
2093
2148
  }
2094
2149
  }, []);
2095
- const show = React14.useCallback(
2150
+ const show = React15.useCallback(
2096
2151
  (title, options = {}) => {
2097
2152
  const { tone = "success", duration = DEFAULT_TOAST_DURATION_MS } = options;
2098
2153
  const id = nextId.current++;
@@ -2101,38 +2156,38 @@ function ToastProvider({ children }) {
2101
2156
  },
2102
2157
  [dismiss]
2103
2158
  );
2104
- React14.useEffect(() => {
2159
+ React15.useEffect(() => {
2105
2160
  const pending = timers.current;
2106
2161
  return () => {
2107
2162
  pending.forEach(clearTimeout);
2108
2163
  pending.clear();
2109
2164
  };
2110
2165
  }, []);
2111
- const api = React14.useMemo(() => ({ show }), [show]);
2166
+ const api = React15.useMemo(() => ({ show }), [show]);
2112
2167
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(ToastContext.Provider, { value: api, children: [
2113
2168
  children,
2114
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "fd-toast-region", "aria-live": "polite", style: { zIndex: OVERLAY_CEILING }, children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Toast, { title: item.title, tone: item.tone, onDismiss: () => dismiss(item.id) }, item.id)) })
2169
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CornerStackPortal, { slot: "toasts", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "fd-toast-region", "aria-live": "polite", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Toast, { title: item.title, tone: item.tone, onDismiss: () => dismiss(item.id) }, item.id)) }) })
2115
2170
  ] });
2116
2171
  }
2117
2172
  function useToast() {
2118
- const api = React14.useContext(ToastContext);
2173
+ const api = React15.useContext(ToastContext);
2119
2174
  if (!api) throw new Error("useToast must be used inside a <ToastProvider>");
2120
2175
  return api;
2121
2176
  }
2122
2177
 
2123
2178
  // src/components/feedback/Tooltip.tsx
2124
- var React15 = __toESM(require("react"), 1);
2179
+ var React16 = __toESM(require("react"), 1);
2125
2180
  var import_jsx_runtime33 = require("react/jsx-runtime");
2126
2181
  var CLOSE_DELAY_MS = 120;
2127
2182
  function Tooltip({ label, placement = "top", children, className = "" }) {
2128
- const anchorRef = React15.useRef(null);
2129
- const bubbleRef = React15.useRef(null);
2130
- const [reason, setReason] = React15.useState(null);
2131
- const closeTimer = React15.useRef(null);
2132
- const id = React15.useId();
2183
+ const anchorRef = React16.useRef(null);
2184
+ const bubbleRef = React16.useRef(null);
2185
+ const [reason, setReason] = React16.useState(null);
2186
+ const closeTimer = React16.useRef(null);
2187
+ const id = React16.useId();
2133
2188
  const descId = id + "-desc";
2134
2189
  const open2 = reason != null;
2135
- const cancelClose = React15.useCallback(() => {
2190
+ const cancelClose = React16.useCallback(() => {
2136
2191
  if (closeTimer.current) {
2137
2192
  clearTimeout(closeTimer.current);
2138
2193
  closeTimer.current = null;
@@ -2142,7 +2197,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
2142
2197
  cancelClose();
2143
2198
  setReason(why);
2144
2199
  };
2145
- const hide = React15.useCallback(() => {
2200
+ const hide = React16.useCallback(() => {
2146
2201
  cancelClose();
2147
2202
  setReason(null);
2148
2203
  }, [cancelClose]);
@@ -2157,7 +2212,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
2157
2212
  setReason((r) => r === "hover" ? null : r);
2158
2213
  }, CLOSE_DELAY_MS);
2159
2214
  };
2160
- React15.useEffect(() => cancelClose, [cancelClose]);
2215
+ React16.useEffect(() => cancelClose, [cancelClose]);
2161
2216
  const pos = usePopoverPosition(open2, anchorRef, {
2162
2217
  placement: placement === "bottom" ? "bottom-center" : "top-center",
2163
2218
  offset: 8,
@@ -2168,7 +2223,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
2168
2223
  });
2169
2224
  const layer = useStackedLayer({ active: open2, containerRef: bubbleRef, onEscape: hide, returnFocus: false });
2170
2225
  const zIndex = useLayerZIndex(layer);
2171
- React15.useEffect(() => {
2226
+ React16.useEffect(() => {
2172
2227
  if (!open2) return;
2173
2228
  const away = (e) => {
2174
2229
  const t = e.target;
@@ -2189,7 +2244,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
2189
2244
  }
2190
2245
  if (keyboard) show("focus");
2191
2246
  };
2192
- const described = React15.isValidElement(children) ? React15.cloneElement(children, {
2247
+ const described = React16.isValidElement(children) ? React16.cloneElement(children, {
2193
2248
  "aria-describedby": [children.props["aria-describedby"], descId].filter(Boolean).join(" ")
2194
2249
  }) : children;
2195
2250
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
@@ -2197,7 +2252,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
2197
2252
  {
2198
2253
  ref: anchorRef,
2199
2254
  className: "fd-tooltip-anchor",
2200
- "aria-describedby": React15.isValidElement(children) ? void 0 : descId,
2255
+ "aria-describedby": React16.isValidElement(children) ? void 0 : descId,
2201
2256
  onPointerEnter: (e) => {
2202
2257
  if (isMouse(e)) hover();
2203
2258
  },
@@ -2241,16 +2296,16 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
2241
2296
  }
2242
2297
 
2243
2298
  // src/components/data/AnimNum.tsx
2244
- var React16 = __toESM(require("react"), 1);
2299
+ var React17 = __toESM(require("react"), 1);
2245
2300
  var import_jsx_runtime34 = require("react/jsx-runtime");
2246
2301
  function shouldSkipEasing() {
2247
2302
  if (typeof document !== "undefined" && document.hidden) return true;
2248
2303
  return window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
2249
2304
  }
2250
2305
  function AnimNum({ value, format, duration = 550 }) {
2251
- const [display, setDisplay] = React16.useState(value);
2252
- const prev = React16.useRef(value);
2253
- React16.useEffect(() => {
2306
+ const [display, setDisplay] = React17.useState(value);
2307
+ const prev = React17.useRef(value);
2308
+ React17.useEffect(() => {
2254
2309
  const from = prev.current;
2255
2310
  const to = value;
2256
2311
  prev.current = to;
@@ -2278,14 +2333,14 @@ function AnimNum({ value, format, duration = 550 }) {
2278
2333
  }
2279
2334
 
2280
2335
  // src/components/data/TrendChart.tsx
2281
- var React19 = __toESM(require("react"), 1);
2336
+ var React20 = __toESM(require("react"), 1);
2282
2337
 
2283
2338
  // src/components/useMeasuredWidth.ts
2284
- var React17 = __toESM(require("react"), 1);
2339
+ var React18 = __toESM(require("react"), 1);
2285
2340
  function useMeasuredWidth(fallback) {
2286
- const [element, setElement] = React17.useState(null);
2287
- const [width, setWidth] = React17.useState(fallback);
2288
- React17.useLayoutEffect(() => {
2341
+ const [element, setElement] = React18.useState(null);
2342
+ const [width, setWidth] = React18.useState(fallback);
2343
+ React18.useLayoutEffect(() => {
2289
2344
  if (!element || typeof ResizeObserver === "undefined") return;
2290
2345
  const measure = () => {
2291
2346
  const measured = Math.round(element.getBoundingClientRect().width);
@@ -2300,7 +2355,7 @@ function useMeasuredWidth(fallback) {
2300
2355
  }
2301
2356
 
2302
2357
  // src/components/data/SegmentedMeter.tsx
2303
- var React18 = __toESM(require("react"), 1);
2358
+ var React19 = __toESM(require("react"), 1);
2304
2359
 
2305
2360
  // src/kits/files.ts
2306
2361
  function formatBytes(n) {
@@ -2505,7 +2560,7 @@ function SegmentedMeter({
2505
2560
  const pct = safeTotal ? Math.min(100, Math.round(used / safeTotal * 100)) : 0;
2506
2561
  const w = (v) => safeTotal ? Math.max(0, Math.min(100, Number(v) / safeTotal * 100)) : 0;
2507
2562
  const fill = (s, i) => s.color || (s.variant ? VARIANT_FILL[s.variant] : void 0) || CHART[i % CHART.length];
2508
- const generatedId = React18.useId();
2563
+ const generatedId = React19.useId();
2509
2564
  const uid2 = id || generatedId;
2510
2565
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
2511
2566
  label || showTotal ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "fd-segmeter-head", children: [
@@ -2656,8 +2711,8 @@ function TrendChart({
2656
2711
  onRetry,
2657
2712
  className = ""
2658
2713
  }) {
2659
- const [activeId, setActiveId] = React19.useState(null);
2660
- const [pointTip, setPointTip] = React19.useState(null);
2714
+ const [activeId, setActiveId] = React20.useState(null);
2715
+ const [pointTip, setPointTip] = React20.useState(null);
2661
2716
  const isEmpty = state === "ready" && (!categories.length || !series.length || series.every((s) => !s.values.length));
2662
2717
  const effectiveState = isEmpty ? "empty" : state;
2663
2718
  const [plotRef, VBW] = useMeasuredWidth(INITIAL_WIDTH);
@@ -2771,7 +2826,7 @@ function TrendChart({
2771
2826
  }
2772
2827
 
2773
2828
  // src/components/data/DonutChart.tsx
2774
- var React20 = __toESM(require("react"), 1);
2829
+ var React21 = __toESM(require("react"), 1);
2775
2830
  var import_jsx_runtime38 = require("react/jsx-runtime");
2776
2831
  function DonutChart({
2777
2832
  segments,
@@ -2786,7 +2841,7 @@ function DonutChart({
2786
2841
  onRetry,
2787
2842
  className = ""
2788
2843
  }) {
2789
- const [activeId, setActiveId] = React20.useState(null);
2844
+ const [activeId, setActiveId] = React21.useState(null);
2790
2845
  const items = segments.filter((s) => Number(s.value) > 0);
2791
2846
  const total = items.reduce((n, s) => n + Number(s.value), 0);
2792
2847
  const isEmpty = state === "ready" && (!items.length || total <= 0);
@@ -2878,7 +2933,7 @@ function DonutChart({
2878
2933
  }
2879
2934
 
2880
2935
  // src/components/data/BarList.tsx
2881
- var React21 = __toESM(require("react"), 1);
2936
+ var React22 = __toESM(require("react"), 1);
2882
2937
  var import_jsx_runtime39 = require("react/jsx-runtime");
2883
2938
  function BarList({
2884
2939
  rows,
@@ -2893,7 +2948,7 @@ function BarList({
2893
2948
  onRetry,
2894
2949
  className = ""
2895
2950
  }) {
2896
- const ordered = React21.useMemo(() => {
2951
+ const ordered = React22.useMemo(() => {
2897
2952
  const list = sort ? [...rows].sort((a, b) => Number(b.value) - Number(a.value)) : rows;
2898
2953
  return maxRows ? list.slice(0, maxRows) : list;
2899
2954
  }, [rows, sort, maxRows]);
@@ -3035,7 +3090,7 @@ function FunnelChart({
3035
3090
  }
3036
3091
 
3037
3092
  // src/components/data/Clamp.tsx
3038
- var React22 = __toESM(require("react"), 1);
3093
+ var React23 = __toESM(require("react"), 1);
3039
3094
  var import_jsx_runtime41 = require("react/jsx-runtime");
3040
3095
  function Clamp({
3041
3096
  children,
@@ -3047,16 +3102,16 @@ function Clamp({
3047
3102
  onToggle,
3048
3103
  className = ""
3049
3104
  }) {
3050
- const [open2, setOpen] = React22.useState(false);
3051
- const [overflows, setOverflows] = React22.useState(false);
3052
- const bodyRef = React22.useRef(null);
3053
- const charClamped = React22.useMemo(() => {
3105
+ const [open2, setOpen] = React23.useState(false);
3106
+ const [overflows, setOverflows] = React23.useState(false);
3107
+ const bodyRef = React23.useRef(null);
3108
+ const charClamped = React23.useMemo(() => {
3054
3109
  if (open2 || !maxChars || typeof text !== "string" || text.length <= maxChars) return null;
3055
3110
  const cut = text.slice(0, maxChars);
3056
3111
  const at = cut.lastIndexOf(" ");
3057
3112
  return (at > maxChars * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
3058
3113
  }, [text, maxChars, open2]);
3059
- React22.useLayoutEffect(() => {
3114
+ React23.useLayoutEffect(() => {
3060
3115
  const node = bodyRef.current;
3061
3116
  if (maxChars || !node || !maxHeight) return;
3062
3117
  const measure = () => {
@@ -3195,16 +3250,16 @@ function DataTable({
3195
3250
  }
3196
3251
 
3197
3252
  // src/components/data/FilterBar.tsx
3198
- var React28 = __toESM(require("react"), 1);
3253
+ var React29 = __toESM(require("react"), 1);
3199
3254
 
3200
3255
  // src/components/forms/NumberInput.tsx
3201
- var React25 = __toESM(require("react"), 1);
3256
+ var React26 = __toESM(require("react"), 1);
3202
3257
 
3203
3258
  // src/components/forms/field.tsx
3204
- var React23 = __toESM(require("react"), 1);
3259
+ var React24 = __toESM(require("react"), 1);
3205
3260
  var import_jsx_runtime44 = require("react/jsx-runtime");
3206
3261
  function useFieldId(id) {
3207
- const generated = React23.useId();
3262
+ const generated = React24.useId();
3208
3263
  return id || generated;
3209
3264
  }
3210
3265
  function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
@@ -3223,10 +3278,10 @@ function HiddenFieldLabel({ id, children }) {
3223
3278
  }
3224
3279
 
3225
3280
  // src/components/useLatest.ts
3226
- var React24 = __toESM(require("react"), 1);
3281
+ var React25 = __toESM(require("react"), 1);
3227
3282
  function useLatest(value) {
3228
- const ref = React24.useRef(value);
3229
- React24.useInsertionEffect(() => {
3283
+ const ref = React25.useRef(value);
3284
+ React25.useInsertionEffect(() => {
3230
3285
  ref.current = value;
3231
3286
  });
3232
3287
  return ref;
@@ -3309,20 +3364,20 @@ function NumberInput({
3309
3364
  const n = typeof v === "number" ? v : parseNumberText(v);
3310
3365
  return n == null || Number.isNaN(n) ? null : n;
3311
3366
  };
3312
- const [text, setText] = React25.useState(() => toText(value));
3313
- const [editing, setEditing] = React25.useState(false);
3367
+ const [text, setText] = React26.useState(() => toText(value));
3368
+ const [editing, setEditing] = React26.useState(false);
3314
3369
  const parsed = parseNumberText(text);
3315
3370
  const invalidMessage = parsed == null ? null : Number.isNaN(parsed) ? "Enter a number" : integer && !Number.isInteger(parsed) ? "Enter a whole number" : parsed < lo ? "Must be \u2265 " + lo : parsed > hi ? "Must be \u2264 " + hi : null;
3316
3371
  const valid = invalidMessage == null;
3317
- const committedRef = React25.useRef(toNumber(value));
3372
+ const committedRef = React26.useRef(toNumber(value));
3318
3373
  const onChangeRef = useLatest(onChange);
3319
3374
  const onValidityChangeRef = useLatest(onValidityChange);
3320
- const focusedRef = React25.useRef(false);
3321
- React25.useEffect(() => {
3375
+ const focusedRef = React26.useRef(false);
3376
+ React26.useEffect(() => {
3322
3377
  committedRef.current = toNumber(value);
3323
3378
  if (!focusedRef.current) setText(toText(value));
3324
3379
  }, [value]);
3325
- React25.useLayoutEffect(() => {
3380
+ React26.useLayoutEffect(() => {
3326
3381
  onValidityChangeRef.current?.(valid);
3327
3382
  }, [valid, onValidityChangeRef]);
3328
3383
  const fire = (n) => {
@@ -3338,26 +3393,26 @@ function NumberInput({
3338
3393
  return true;
3339
3394
  };
3340
3395
  const bumpRef = useLatest(bump);
3341
- const holdTimer = React25.useRef(null);
3342
- const release = () => {
3396
+ const holdTimer = React26.useRef(null);
3397
+ const release2 = () => {
3343
3398
  if (holdTimer.current) clearTimeout(holdTimer.current);
3344
3399
  holdTimer.current = null;
3345
3400
  };
3346
3401
  const hold = (direction) => {
3347
- release();
3402
+ release2();
3348
3403
  bump(direction, step);
3349
3404
  let repeats = 0;
3350
3405
  const tick = () => {
3351
3406
  repeats++;
3352
3407
  if (!bumpRef.current(direction, repeats > HOLD_BIG_AFTER ? big : step)) {
3353
- release();
3408
+ release2();
3354
3409
  return;
3355
3410
  }
3356
3411
  holdTimer.current = setTimeout(tick, holdInterval(repeats));
3357
3412
  };
3358
3413
  holdTimer.current = setTimeout(tick, HOLD_DELAY_MS);
3359
3414
  };
3360
- React25.useEffect(() => () => {
3415
+ React26.useEffect(() => () => {
3361
3416
  if (holdTimer.current) clearTimeout(holdTimer.current);
3362
3417
  }, []);
3363
3418
  const current2 = committedRef.current;
@@ -3423,9 +3478,9 @@ function NumberInput({
3423
3478
  "aria-label": stepperName("Decrease"),
3424
3479
  disabled: disabled || noRange || current2 != null && current2 <= lo,
3425
3480
  onPointerDown: () => hold(-1),
3426
- onPointerUp: release,
3427
- onPointerLeave: release,
3428
- onPointerCancel: release,
3481
+ onPointerUp: release2,
3482
+ onPointerLeave: release2,
3483
+ onPointerCancel: release2,
3429
3484
  onClick: (e) => {
3430
3485
  if (e.detail === 0) bump(-1, step);
3431
3486
  },
@@ -3440,9 +3495,9 @@ function NumberInput({
3440
3495
  "aria-label": stepperName("Increase"),
3441
3496
  disabled: disabled || noRange || current2 != null && current2 >= hi,
3442
3497
  onPointerDown: () => hold(1),
3443
- onPointerUp: release,
3444
- onPointerLeave: release,
3445
- onPointerCancel: release,
3498
+ onPointerUp: release2,
3499
+ onPointerLeave: release2,
3500
+ onPointerCancel: release2,
3446
3501
  onClick: (e) => {
3447
3502
  if (e.detail === 0) bump(1, step);
3448
3503
  },
@@ -3460,7 +3515,7 @@ function NumberInput({
3460
3515
  }
3461
3516
 
3462
3517
  // src/components/forms/DatePicker.tsx
3463
- var React26 = __toESM(require("react"), 1);
3518
+ var React27 = __toESM(require("react"), 1);
3464
3519
  var import_jsx_runtime46 = require("react/jsx-runtime");
3465
3520
  var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
3466
3521
  var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
@@ -3493,10 +3548,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3493
3548
  const today = /* @__PURE__ */ new Date();
3494
3549
  const sel = range ? value || {} : { start: value, end: value };
3495
3550
  const anchor = parse(sel.start) || parse(initialMonth) || today;
3496
- const [vy, setVy] = React26.useState(anchor.getFullYear());
3497
- const [vm, setVm] = React26.useState(anchor.getMonth());
3498
- const [mode2, setMode] = React26.useState("days");
3499
- const [hover, setHover] = React26.useState(null);
3551
+ const [vy, setVy] = React27.useState(anchor.getFullYear());
3552
+ const [vm, setVm] = React27.useState(anchor.getMonth());
3553
+ const [mode2, setMode] = React27.useState("days");
3554
+ const [hover, setHover] = React27.useState(null);
3500
3555
  const s = parse(sel.start), e = parse(sel.end);
3501
3556
  const hoverEnd = range && s && !e && hover ? parse(hover) : null;
3502
3557
  const inRange = (d) => {
@@ -3507,12 +3562,12 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3507
3562
  const isEnd = (d) => !!e && iso(d) === iso(e);
3508
3563
  const isEdge = (d) => isStart(d) || isEnd(d);
3509
3564
  const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;
3510
- const [activeDate, setActiveDate] = React26.useState(() => {
3565
+ const [activeDate, setActiveDate] = React27.useState(() => {
3511
3566
  if (s) return s;
3512
3567
  if (sameMonth(today, anchor.getFullYear(), anchor.getMonth())) return today;
3513
3568
  return new Date(anchor.getFullYear(), anchor.getMonth(), 1);
3514
3569
  });
3515
- const calRef = React26.useRef(null);
3570
+ const calRef = React27.useRef(null);
3516
3571
  const pageToShow = (y, m) => {
3517
3572
  const idx = y * 12 + m, firstIdx = vy * 12 + vm, secondIdx = firstIdx + 1;
3518
3573
  if (idx === firstIdx || months > 1 && idx === secondIdx) return;
@@ -3529,7 +3584,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3529
3584
  setActiveDate(next);
3530
3585
  pageToShow(next.getFullYear(), next.getMonth());
3531
3586
  };
3532
- React26.useEffect(() => {
3587
+ React27.useEffect(() => {
3533
3588
  const el = calRef.current?.querySelector('[data-iso="' + iso(activeDate) + '"]');
3534
3589
  if (el) el.focus({ preventScroll: true });
3535
3590
  }, [activeDate, vy, vm]);
@@ -3722,9 +3777,9 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3722
3777
  }
3723
3778
  function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, "aria-label": hiddenLabel, ...rest }) {
3724
3779
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
3725
- const [open2, setOpen] = React26.useState(false);
3726
- const rootRef = React26.useRef(null);
3727
- const boxRef = React26.useRef(null);
3780
+ const [open2, setOpen] = React27.useState(false);
3781
+ const rootRef = React27.useRef(null);
3782
+ const boxRef = React27.useRef(null);
3728
3783
  const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
3729
3784
  const toggle = () => {
3730
3785
  if (!disabled) setOpen(!open2);
@@ -3813,9 +3868,9 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
3813
3868
  }
3814
3869
 
3815
3870
  // src/components/forms/listbox.ts
3816
- var React27 = __toESM(require("react"), 1);
3871
+ var React28 = __toESM(require("react"), 1);
3817
3872
  function useListboxNav({ count, onSelect }) {
3818
- const [active, setActive] = React27.useState(-1);
3873
+ const [active, setActive] = React28.useState(-1);
3819
3874
  return {
3820
3875
  active,
3821
3876
  setActive,
@@ -3828,7 +3883,7 @@ function useListboxNav({ count, onSelect }) {
3828
3883
  };
3829
3884
  }
3830
3885
  function useListboxScrollIntoView(active, listRef, enabled) {
3831
- React27.useEffect(() => {
3886
+ React28.useEffect(() => {
3832
3887
  if (!enabled || active < 0 || !listRef.current) return;
3833
3888
  const list = listRef.current;
3834
3889
  const el = list.querySelector('[data-i="' + active + '"]');
@@ -4041,13 +4096,13 @@ function MultiSelectPanel({
4041
4096
  onClose
4042
4097
  }) {
4043
4098
  const allowedOps = operatorsFor(field);
4044
- const [draftOperator, setDraftOperator] = React28.useState(value?.operator ?? allowedOps[0]);
4099
+ const [draftOperator, setDraftOperator] = React29.useState(value?.operator ?? allowedOps[0]);
4045
4100
  const operator = allowedOps.length === 1 ? allowedOps[0] : value?.operator ?? draftOperator;
4046
4101
  const selected = value?.values ?? [];
4047
4102
  const selectedRef = useLatest(selected);
4048
4103
  const operatorRef = useLatest(operator);
4049
- const mountedRef = React28.useRef(true);
4050
- React28.useEffect(() => {
4104
+ const mountedRef = React29.useRef(true);
4105
+ React29.useEffect(() => {
4051
4106
  mountedRef.current = true;
4052
4107
  return () => {
4053
4108
  mountedRef.current = false;
@@ -4061,20 +4116,20 @@ function MultiSelectPanel({
4061
4116
  if (selectedRef.current.length > 0) commit(selectedRef.current, op);
4062
4117
  else setDraftOperator(op);
4063
4118
  };
4064
- const [mode2, setMode] = React28.useState("search");
4065
- const [query, setQuery] = React28.useState("");
4066
- const [asyncState, setAsyncState] = React28.useState(
4119
+ const [mode2, setMode] = React29.useState("search");
4120
+ const [query, setQuery] = React29.useState("");
4121
+ const [asyncState, setAsyncState] = React29.useState(
4067
4122
  { options: null, loading: !!field.loadOptions, error: false }
4068
4123
  );
4069
- const [retryTick, setRetryTick] = React28.useState(0);
4070
- const inputRef = React28.useRef(null);
4071
- const listRef = React28.useRef(null);
4072
- const listId = React28.useId();
4124
+ const [retryTick, setRetryTick] = React29.useState(0);
4125
+ const inputRef = React29.useRef(null);
4126
+ const listRef = React29.useRef(null);
4127
+ const listId = React29.useId();
4073
4128
  const loadOptionsRef = useLatest(field.loadOptions);
4074
- React28.useEffect(() => {
4129
+ React29.useEffect(() => {
4075
4130
  inputRef.current?.focus();
4076
4131
  }, []);
4077
- React28.useEffect(() => {
4132
+ React29.useEffect(() => {
4078
4133
  const load = loadOptionsRef.current;
4079
4134
  if (!load) return;
4080
4135
  const controller = new AbortController();
@@ -4107,17 +4162,17 @@ function MultiSelectPanel({
4107
4162
  };
4108
4163
  const nav = useListboxNav({ count: options.length, onSelect: (i) => toggle(options[i]) });
4109
4164
  useListboxScrollIntoView(nav.active, listRef, hasListbox);
4110
- React28.useEffect(() => {
4165
+ React29.useEffect(() => {
4111
4166
  nav.setActive(0);
4112
4167
  }, [query, options.length]);
4113
4168
  const activeId = hasListbox && options[nav.active] ? listId + "-opt-" + nav.active : void 0;
4114
4169
  const liveMessage = showLoading ? "Loading\u2026" : showError ? "Couldn't load options." : options.length === 0 ? "No matches" : atLimit ? "Limit reached: at most " + field.maxValues + " values" : "";
4115
- const [pasteText, setPasteText] = React28.useState("");
4116
- const [pasteLoading, setPasteLoading] = React28.useState(false);
4117
- const [unmatchedTokens, setUnmatchedTokens] = React28.useState([]);
4118
- const [pasteError, setPasteError] = React28.useState(null);
4119
- const pasteWrapRef = React28.useRef(null);
4120
- React28.useEffect(() => {
4170
+ const [pasteText, setPasteText] = React29.useState("");
4171
+ const [pasteLoading, setPasteLoading] = React29.useState(false);
4172
+ const [unmatchedTokens, setUnmatchedTokens] = React29.useState([]);
4173
+ const [pasteError, setPasteError] = React29.useState(null);
4174
+ const pasteWrapRef = React29.useRef(null);
4175
+ React29.useEffect(() => {
4121
4176
  if (mode2 === "paste") pasteWrapRef.current?.querySelector("textarea")?.focus();
4122
4177
  }, [mode2]);
4123
4178
  const doResolve = () => {
@@ -4290,8 +4345,8 @@ function MultiSelectPanel({
4290
4345
  );
4291
4346
  }
4292
4347
  function useTextValidity(onFlip) {
4293
- const invalidRef = React28.useRef(/* @__PURE__ */ new Set());
4294
- const [, rerender] = React28.useReducer((n) => n + 1, 0);
4348
+ const invalidRef = React29.useRef(/* @__PURE__ */ new Set());
4349
+ const [, rerender] = React29.useReducer((n) => n + 1, 0);
4295
4350
  const onFlipRef = useLatest(onFlip);
4296
4351
  const record = (name, valid) => {
4297
4352
  const invalid = invalidRef.current;
@@ -4334,15 +4389,15 @@ function sameValue(a, b) {
4334
4389
  return true;
4335
4390
  }
4336
4391
  function useReseedFromProps(value, applies, reseed) {
4337
- const seen = React28.useRef(value);
4338
- React28.useLayoutEffect(() => {
4392
+ const seen = React29.useRef(value);
4393
+ React29.useLayoutEffect(() => {
4339
4394
  if (seen.current === value) return;
4340
4395
  seen.current = value;
4341
4396
  if (!sameValue(value, applies())) reseed(value);
4342
4397
  }, [value, applies, reseed]);
4343
4398
  }
4344
4399
  function usePreserveFocusAcrossRemount(seed, fields) {
4345
- const pendingName = React28.useRef(null);
4400
+ const pendingName = React29.useRef(null);
4346
4401
  const fieldsRef = useLatest(fields);
4347
4402
  const capture = () => {
4348
4403
  const active = document.activeElement;
@@ -4355,7 +4410,7 @@ function usePreserveFocusAcrossRemount(seed, fields) {
4355
4410
  }
4356
4411
  }
4357
4412
  };
4358
- React28.useLayoutEffect(() => {
4413
+ React29.useLayoutEffect(() => {
4359
4414
  const name = pendingName.current;
4360
4415
  if (!name) return;
4361
4416
  pendingName.current = null;
@@ -4371,14 +4426,14 @@ function RangePanel({
4371
4426
  onCommit,
4372
4427
  onClose
4373
4428
  }) {
4374
- const [draft, setDraft] = React28.useState(() => rangeDraft(value));
4375
- const [seed, setSeed] = React28.useState(0);
4376
- const minId = React28.useId();
4377
- const maxId = React28.useId();
4378
- const minWrapRef = React28.useRef(null);
4379
- const maxWrapRef = React28.useRef(null);
4429
+ const [draft, setDraft] = React29.useState(() => rangeDraft(value));
4430
+ const [seed, setSeed] = React29.useState(0);
4431
+ const minId = React29.useId();
4432
+ const maxId = React29.useId();
4433
+ const minWrapRef = React29.useRef(null);
4434
+ const maxWrapRef = React29.useRef(null);
4380
4435
  const preserveFocus = usePreserveFocusAcrossRemount(seed, { min: minWrapRef, max: maxWrapRef });
4381
- const draftRef = React28.useRef(draft);
4436
+ const draftRef = React29.useRef(draft);
4382
4437
  const shown = () => {
4383
4438
  const { min, max } = draftRef.current;
4384
4439
  return applicable(field, min == null && max == null ? void 0 : { min, max }, validity.allValid());
@@ -4470,15 +4525,15 @@ function DatePanel({
4470
4525
  onClose
4471
4526
  }) {
4472
4527
  const maxDays = effectiveMaxDays(field);
4473
- const [initial] = React28.useState(() => dateDraft(field, value));
4474
- const [kind, setKind] = React28.useState(initial.kind);
4475
- const [daysDraft, setDaysDraft] = React28.useState(initial.days);
4476
- const daysRef = React28.useRef(daysDraft);
4477
- const daysConfirmed = React28.useRef(value?.kind === "withinDays");
4478
- const [between, setBetween] = React28.useState(initial.between);
4479
- const [seed, setSeed] = React28.useState(0);
4480
- const daysId = React28.useId();
4481
- const daysWrapRef = React28.useRef(null);
4528
+ const [initial] = React29.useState(() => dateDraft(field, value));
4529
+ const [kind, setKind] = React29.useState(initial.kind);
4530
+ const [daysDraft, setDaysDraft] = React29.useState(initial.days);
4531
+ const daysRef = React29.useRef(daysDraft);
4532
+ const daysConfirmed = React29.useRef(value?.kind === "withinDays");
4533
+ const [between, setBetween] = React29.useState(initial.between);
4534
+ const [seed, setSeed] = React29.useState(0);
4535
+ const daysId = React29.useId();
4536
+ const daysWrapRef = React29.useRef(null);
4482
4537
  const preserveFocus = usePreserveFocusAcrossRemount(seed, { days: daysWrapRef });
4483
4538
  const shownWithinDays = () => {
4484
4539
  const days = daysRef.current;
@@ -4590,11 +4645,11 @@ function DatePanel({
4590
4645
  );
4591
4646
  }
4592
4647
  function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", actions, onClearAll, showActiveCount = false, className = "", ...rest }) {
4593
- const [panel, setPanel] = React28.useState(null);
4594
- const editAnchorRef = React28.useRef(null);
4595
- const addAnchorRef = React28.useRef(null);
4596
- const textInputRef = React28.useRef(null);
4597
- const optionsRef = React28.useRef(null);
4648
+ const [panel, setPanel] = React29.useState(null);
4649
+ const editAnchorRef = React29.useRef(null);
4650
+ const addAnchorRef = React29.useRef(null);
4651
+ const textInputRef = React29.useRef(null);
4652
+ const optionsRef = React29.useRef(null);
4598
4653
  if (process.env.NODE_ENV !== "production") {
4599
4654
  for (const f of fields) assertValidFieldDefinition(f);
4600
4655
  }
@@ -4617,7 +4672,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
4617
4672
  const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
4618
4673
  const startEditing = (key) => setPanel({ kind: "edit", key });
4619
4674
  const closeEditing = () => setPanel(null);
4620
- React28.useEffect(() => {
4675
+ React29.useEffect(() => {
4621
4676
  if (!panel || panel.kind !== "edit") return;
4622
4677
  if (editingField?.type === "text") {
4623
4678
  textInputRef.current?.focus();
@@ -4847,10 +4902,10 @@ function StatTile({ label, value, sub, delta, invert = false, loading = false, c
4847
4902
  }
4848
4903
 
4849
4904
  // src/components/data/CodeBlock.tsx
4850
- var React30 = __toESM(require("react"), 1);
4905
+ var React31 = __toESM(require("react"), 1);
4851
4906
 
4852
4907
  // src/kits/clipboard.ts
4853
- var React29 = __toESM(require("react"), 1);
4908
+ var React30 = __toESM(require("react"), 1);
4854
4909
  var COPIED_FEEDBACK_MS = 1600;
4855
4910
  function copyThroughSelection(text) {
4856
4911
  const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
@@ -4880,17 +4935,17 @@ async function copyToClipboard(text) {
4880
4935
  return copyThroughSelection(text);
4881
4936
  }
4882
4937
  function useCopyToClipboard() {
4883
- const [copied, setCopied] = React29.useState(false);
4884
- const timer = React29.useRef(null);
4885
- const mounted = React29.useRef(true);
4886
- React29.useEffect(() => {
4938
+ const [copied, setCopied] = React30.useState(false);
4939
+ const timer = React30.useRef(null);
4940
+ const mounted = React30.useRef(true);
4941
+ React30.useEffect(() => {
4887
4942
  mounted.current = true;
4888
4943
  return () => {
4889
4944
  mounted.current = false;
4890
4945
  if (timer.current) clearTimeout(timer.current);
4891
4946
  };
4892
4947
  }, []);
4893
- const copy = React29.useCallback(async (text) => {
4948
+ const copy = React30.useCallback(async (text) => {
4894
4949
  const ok = await copyToClipboard(text);
4895
4950
  if (ok && mounted.current) {
4896
4951
  setCopied(true);
@@ -5058,7 +5113,7 @@ function tokenize(src, lang) {
5058
5113
  return out;
5059
5114
  }
5060
5115
  function Highlighted({ code, lang }) {
5061
- const toks = React30.useMemo(() => tokenize(code, lang), [code, lang]);
5116
+ const toks = React31.useMemo(() => tokenize(code, lang), [code, lang]);
5062
5117
  return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_jsx_runtime51.Fragment, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
5063
5118
  }
5064
5119
  function CodeBlock({
@@ -5072,8 +5127,8 @@ function CodeBlock({
5072
5127
  actions,
5073
5128
  className = ""
5074
5129
  }) {
5075
- const [wrap, setWrap] = React30.useState(!!wrapDefault);
5076
- const [open2, setOpen] = React30.useState(false);
5130
+ const [wrap, setWrap] = React31.useState(!!wrapDefault);
5131
+ const [open2, setOpen] = React31.useState(false);
5077
5132
  const [copied, copy] = useCopyToClipboard();
5078
5133
  const body = String(code).replace(/\n$/, "");
5079
5134
  const lines = body.split("\n");
@@ -5102,7 +5157,7 @@ function CodeBlock({
5102
5157
  ] });
5103
5158
  }
5104
5159
  function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
5105
- const [open2, setOpen] = React30.useState(false);
5160
+ const [open2, setOpen] = React31.useState(false);
5106
5161
  const [copied, copy] = useCopyToClipboard();
5107
5162
  const raw = String(diff).replace(/\n$/, "");
5108
5163
  const all = raw.split("\n").map((line) => {
@@ -5148,7 +5203,7 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
5148
5203
  }
5149
5204
 
5150
5205
  // src/components/data/Markdown.tsx
5151
- var React31 = __toESM(require("react"), 1);
5206
+ var React32 = __toESM(require("react"), 1);
5152
5207
  var import_jsx_runtime52 = require("react/jsx-runtime");
5153
5208
  var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
5154
5209
  var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
@@ -5187,7 +5242,7 @@ function inlineNodes(src, ctx, keyBase) {
5187
5242
  const href = safeHref(g(2));
5188
5243
  out.push(href ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("a", { href, title: g(3) || void 0, target: /^https?:/i.test(href) ? "_blank" : void 0, rel: "noopener noreferrer", onClick: ctx.onLinkClick, children: inlineNodes(g(1), ctx, key()) }, key()) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { children: g(1) }, key()));
5189
5244
  } else if (kind === "cite") {
5190
- out.push(ctx.renderCitation ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(React31.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("sup", { className: "fd-md-cite", children: g(1) }, key()));
5245
+ out.push(ctx.renderCitation ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(React32.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("sup", { className: "fd-md-cite", children: g(1) }, key()));
5191
5246
  } else if (kind === "strongem") out.push(/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("strong", { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("em", { children: inlineNodes(g(1), ctx, key()) }) }, key()));
5192
5247
  else if (kind === "strong") out.push(/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("strong", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
5193
5248
  else if (kind === "em") out.push(/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("em", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
@@ -5352,7 +5407,7 @@ function Markdown({
5352
5407
  onLinkClick
5353
5408
  }) {
5354
5409
  const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
5355
- const blocks = React31.useMemo(() => parseBlocks(source), [source]);
5410
+ const blocks = React32.useMemo(() => parseBlocks(source), [source]);
5356
5411
  return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: ["fd-md", className].filter(Boolean).join(" "), children: renderBlocks(blocks, ctx, "b") });
5357
5412
  }
5358
5413
  function MarkdownInline({ source = "", className = "", onLinkClick }) {
@@ -5466,7 +5521,7 @@ function Pagination({
5466
5521
  }
5467
5522
 
5468
5523
  // src/components/data/RelativeTime.tsx
5469
- var React32 = __toESM(require("react"), 1);
5524
+ var React33 = __toESM(require("react"), 1);
5470
5525
  var import_jsx_runtime55 = require("react/jsx-runtime");
5471
5526
  var MIN = 6e4;
5472
5527
  var HOUR = 36e5;
@@ -5518,9 +5573,9 @@ function formatDuration(ms) {
5518
5573
  return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
5519
5574
  }
5520
5575
  function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
5521
- const [, force] = React32.useState(0);
5576
+ const [, force] = React33.useState(0);
5522
5577
  const t = value instanceof Date ? value.getTime() : Date.parse(value);
5523
- React32.useEffect(() => {
5578
+ React33.useEffect(() => {
5524
5579
  if (!refresh2 || !t || isNaN(t)) return;
5525
5580
  const abs = Math.abs(t - Date.now());
5526
5581
  if (abs > DAY) return;
@@ -5536,7 +5591,7 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
5536
5591
  }
5537
5592
 
5538
5593
  // src/components/data/ScoreMeter.tsx
5539
- var React33 = __toESM(require("react"), 1);
5594
+ var React34 = __toESM(require("react"), 1);
5540
5595
  var import_jsx_runtime56 = require("react/jsx-runtime");
5541
5596
  function ScoreMeter({
5542
5597
  score,
@@ -5551,10 +5606,10 @@ function ScoreMeter({
5551
5606
  breakdownWidth = 280,
5552
5607
  className = ""
5553
5608
  }) {
5554
- const [open2, setOpen] = React33.useState(false);
5555
- const ref = React33.useRef(null);
5609
+ const [open2, setOpen] = React34.useState(false);
5610
+ const ref = React34.useRef(null);
5556
5611
  const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
5557
- const body = /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(React33.Fragment, { children: [
5612
+ const body = /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(React34.Fragment, { children: [
5558
5613
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "fd-scoremeter-rail", style: { width }, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SegmentedMeter, { total: 100, segments, height, showTotal: false, showPercent: false, legend: false }) }),
5559
5614
  showScore ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
5560
5615
  ] });
@@ -5573,7 +5628,7 @@ function ScoreMeter({
5573
5628
  }
5574
5629
  );
5575
5630
  }
5576
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(React33.Fragment, { children: [
5631
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(React34.Fragment, { children: [
5577
5632
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
5578
5633
  "button",
5579
5634
  {
@@ -5604,14 +5659,14 @@ function ScoreMeter({
5604
5659
  }
5605
5660
 
5606
5661
  // src/components/actions/inlinePanel.tsx
5607
- var React34 = __toESM(require("react"), 1);
5662
+ var React35 = __toESM(require("react"), 1);
5608
5663
  var import_jsx_runtime57 = require("react/jsx-runtime");
5609
5664
  function useInlinePanel() {
5610
- const [open2, setOpen] = React34.useState(false);
5611
- const ref = React34.useRef(null);
5665
+ const [open2, setOpen] = React35.useState(false);
5666
+ const ref = React35.useRef(null);
5612
5667
  const layer = useStackedLayer({ active: open2, containerRef: ref, onEscape: () => setOpen(false) });
5613
5668
  const zIndex = useLayerZIndex(layer);
5614
- React34.useEffect(() => {
5669
+ React35.useEffect(() => {
5615
5670
  if (!open2) return;
5616
5671
  const away = (e) => {
5617
5672
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -5677,7 +5732,7 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
5677
5732
  }
5678
5733
 
5679
5734
  // src/components/data/StepList.tsx
5680
- var React35 = __toESM(require("react"), 1);
5735
+ var React36 = __toESM(require("react"), 1);
5681
5736
  var import_jsx_runtime59 = require("react/jsx-runtime");
5682
5737
  var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
5683
5738
  function StepList({
@@ -5690,9 +5745,9 @@ function StepList({
5690
5745
  dense = false,
5691
5746
  className = ""
5692
5747
  }) {
5693
- const [openState, setOpenState] = React35.useState(defaultOpen);
5748
+ const [openState, setOpenState] = React36.useState(defaultOpen);
5694
5749
  const open2 = openProp == null ? openState : openProp;
5695
- const [expanded, setExpanded] = React35.useState({});
5750
+ const [expanded, setExpanded] = React36.useState({});
5696
5751
  if (!steps.length) return null;
5697
5752
  const running = steps.some((s) => s.status === "running");
5698
5753
  const failed = steps.filter((s) => s.status === "error").length;
@@ -5750,7 +5805,7 @@ function StepList({
5750
5805
  }
5751
5806
 
5752
5807
  // src/components/data/VirtualList.tsx
5753
- var React36 = __toESM(require("react"), 1);
5808
+ var React37 = __toESM(require("react"), 1);
5754
5809
  var import_jsx_runtime60 = require("react/jsx-runtime");
5755
5810
  var VIRTUAL_LIST_BUFFER_ROWS = 20;
5756
5811
  var VIRTUAL_LIST_ROW_GAP = 6;
@@ -5802,35 +5857,35 @@ function VirtualList({
5802
5857
  className = "",
5803
5858
  style
5804
5859
  }) {
5805
- const [scrollTop, setScrollTop] = React36.useState(0);
5806
- const loaded = React36.useMemo(
5860
+ const [scrollTop, setScrollTop] = React37.useState(0);
5861
+ const loaded = React37.useMemo(
5807
5862
  () => ({ firstItemIndex, count: items.length }),
5808
5863
  [firstItemIndex, items.length]
5809
5864
  );
5810
5865
  const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
5811
5866
  const bandKey = firstItemIndex + ":" + items.length;
5812
- const win = React36.useMemo(
5867
+ const win = React37.useMemo(
5813
5868
  () => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
5814
5869
  [scrollTop, height, itemHeight, total, loaded]
5815
5870
  );
5816
- const need = React36.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
5871
+ const need = React37.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
5817
5872
  const wantStart = need.start && hasMore?.start !== false;
5818
5873
  const wantEnd = need.end && hasMore?.end !== false;
5819
5874
  const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
5820
5875
  const askKey = bandKey + "@" + bucket2;
5821
- const asked = React36.useRef({ start: null, end: null });
5822
- React36.useEffect(() => {
5876
+ const asked = React37.useRef({ start: null, end: null });
5877
+ React37.useEffect(() => {
5823
5878
  if (loading || !wantStart || asked.current.start === askKey) return;
5824
5879
  asked.current.start = askKey;
5825
5880
  onNeedMore("start", win);
5826
5881
  }, [wantStart, loading, askKey, onNeedMore, win]);
5827
- React36.useEffect(() => {
5882
+ React37.useEffect(() => {
5828
5883
  if (loading || !wantEnd || asked.current.end === askKey) return;
5829
5884
  asked.current.end = askKey;
5830
5885
  onNeedMore("end", win);
5831
5886
  }, [wantEnd, loading, askKey, onNeedMore, win]);
5832
- const lastKeysRef = React36.useRef(null);
5833
- const newKeys = React36.useMemo(() => {
5887
+ const lastKeysRef = React37.useRef(null);
5888
+ const newKeys = React37.useMemo(() => {
5834
5889
  const prev = lastKeysRef.current;
5835
5890
  if (!prev) return /* @__PURE__ */ new Set();
5836
5891
  const fresh = /* @__PURE__ */ new Set();
@@ -5840,7 +5895,7 @@ function VirtualList({
5840
5895
  }
5841
5896
  return fresh;
5842
5897
  }, [items]);
5843
- React36.useEffect(() => {
5898
+ React37.useEffect(() => {
5844
5899
  lastKeysRef.current = new Set(items.map(keyOf));
5845
5900
  }, [items]);
5846
5901
  const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
@@ -5885,7 +5940,7 @@ function VirtualList({
5885
5940
  }
5886
5941
 
5887
5942
  // src/components/data/EntityRow.tsx
5888
- var React37 = __toESM(require("react"), 1);
5943
+ var React38 = __toESM(require("react"), 1);
5889
5944
  var import_jsx_runtime61 = require("react/jsx-runtime");
5890
5945
  var ENTITY_ROW_METRIC_WIDTH = 74;
5891
5946
  var METRIC_TONE_COLOR = {
@@ -5898,7 +5953,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
5898
5953
  const key = m.id || m.label || i;
5899
5954
  const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
5900
5955
  const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
5901
- const content = /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(React37.Fragment, { children: [
5956
+ const content = /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(React38.Fragment, { children: [
5902
5957
  m.icon ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
5903
5958
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
5904
5959
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "fd-sr", children: " " + m.label })
@@ -5990,8 +6045,8 @@ function EntityRow({
5990
6045
  }
5991
6046
 
5992
6047
  // src/components/data/TransferList.tsx
5993
- var React38 = __toESM(require("react"), 1);
5994
- var import_react_dom5 = require("react-dom");
6048
+ var React39 = __toESM(require("react"), 1);
6049
+ var import_react_dom6 = require("react-dom");
5995
6050
 
5996
6051
  // src/components/forms/Input.tsx
5997
6052
  var import_jsx_runtime62 = require("react/jsx-runtime");
@@ -6096,12 +6151,12 @@ function TransferList({
6096
6151
  listHeight = 440,
6097
6152
  className = ""
6098
6153
  }) {
6099
- const [drag, setDrag] = React38.useState(null);
6100
- const [dragOverSide, setDragOverSide] = React38.useState(null);
6101
- const dragRef = React38.useRef(null);
6102
- const armedRef = React38.useRef(null);
6103
- const sideRefs = React38.useRef({ left: null, right: null });
6104
- const hitTestSide = React38.useCallback((x, y) => {
6154
+ const [drag, setDrag] = React39.useState(null);
6155
+ const [dragOverSide, setDragOverSide] = React39.useState(null);
6156
+ const dragRef = React39.useRef(null);
6157
+ const armedRef = React39.useRef(null);
6158
+ const sideRefs = React39.useRef({ left: null, right: null });
6159
+ const hitTestSide = React39.useCallback((x, y) => {
6105
6160
  for (const side of ["left", "right"]) {
6106
6161
  const el = sideRefs.current[side];
6107
6162
  if (!el) continue;
@@ -6110,7 +6165,7 @@ function TransferList({
6110
6165
  }
6111
6166
  return null;
6112
6167
  }, []);
6113
- const findItem = React38.useCallback(
6168
+ const findItem = React39.useCallback(
6114
6169
  (side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
6115
6170
  [left.items, right.items, keyOf]
6116
6171
  );
@@ -6132,7 +6187,7 @@ function TransferList({
6132
6187
  height: rect.height
6133
6188
  };
6134
6189
  };
6135
- React38.useEffect(() => {
6190
+ React39.useEffect(() => {
6136
6191
  const onMovePointer = (e) => {
6137
6192
  const armed = armedRef.current;
6138
6193
  if (!armed || e.pointerId !== armed.pointerId) return;
@@ -6185,7 +6240,7 @@ function TransferList({
6185
6240
  window.removeEventListener("pointercancel", endDrag);
6186
6241
  };
6187
6242
  }, [hitTestSide, findItem, onMove]);
6188
- React38.useEffect(() => {
6243
+ React39.useEffect(() => {
6189
6244
  if (!drag || typeof document === "undefined") return;
6190
6245
  const prev = document.body.style.userSelect;
6191
6246
  document.body.style.userSelect = "none";
@@ -6268,7 +6323,7 @@ function TransferList({
6268
6323
  renderSide("left", left, "right"),
6269
6324
  renderSide("right", right, "left")
6270
6325
  ] }),
6271
- drag ? (0, import_react_dom5.createPortal)(
6326
+ drag ? (0, import_react_dom6.createPortal)(
6272
6327
  /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
6273
6328
  "div",
6274
6329
  {
@@ -6293,11 +6348,11 @@ function TransferList({
6293
6348
  }
6294
6349
 
6295
6350
  // src/components/forms/Checkbox.tsx
6296
- var React39 = __toESM(require("react"), 1);
6351
+ var React40 = __toESM(require("react"), 1);
6297
6352
  var import_jsx_runtime65 = require("react/jsx-runtime");
6298
6353
  function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
6299
- const ref = React39.useRef(null);
6300
- React39.useEffect(() => {
6354
+ const ref = React40.useRef(null);
6355
+ React40.useEffect(() => {
6301
6356
  if (ref.current) ref.current.indeterminate = indeterminate;
6302
6357
  }, [indeterminate]);
6303
6358
  return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
@@ -6341,7 +6396,7 @@ function Switch({ label, description, className = "", ...rest }) {
6341
6396
  }
6342
6397
 
6343
6398
  // src/components/forms/Select.tsx
6344
- var React40 = __toESM(require("react"), 1);
6399
+ var React41 = __toESM(require("react"), 1);
6345
6400
  var import_jsx_runtime68 = require("react/jsx-runtime");
6346
6401
  var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
6347
6402
  function Select({
@@ -6369,12 +6424,12 @@ function Select({
6369
6424
  const isOn = (v) => multiple ? vals.includes(v) : v === value;
6370
6425
  const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
6371
6426
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
6372
- const [open2, setOpen] = React40.useState(false);
6373
- const [q, setQ] = React40.useState("");
6374
- const rootRef = React40.useRef(null);
6375
- const boxRef = React40.useRef(null);
6376
- const listRef = React40.useRef(null);
6377
- const typeBuf = React40.useRef({ s: "", t: 0 });
6427
+ const [open2, setOpen] = React41.useState(false);
6428
+ const [q, setQ] = React41.useState("");
6429
+ const rootRef = React41.useRef(null);
6430
+ const boxRef = React41.useRef(null);
6431
+ const listRef = React41.useRef(null);
6432
+ const typeBuf = React41.useRef({ s: "", t: 0 });
6378
6433
  const selected = multiple ? null : opts.find((o) => o.value === value);
6379
6434
  const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
6380
6435
  const boxText = multiple ? chosen.length === 0 ? placeholder : chosen.length === 1 ? chosen[0].label : summary ? summary(chosen.map((o) => o.value)) : chosen.length + " selected" : selected ? selected.label : placeholder;
@@ -6510,7 +6565,7 @@ function Select({
6510
6565
  ),
6511
6566
  q ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
6512
6567
  ] }) : void 0,
6513
- footer: multiple ? /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(React40.Fragment, { children: [
6568
+ footer: multiple ? /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(React41.Fragment, { children: [
6514
6569
  /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6515
6570
  "button",
6516
6571
  {
@@ -6541,7 +6596,7 @@ function Select({
6541
6596
  'Nothing matches "',
6542
6597
  q,
6543
6598
  '".'
6544
- ] }) : groups.map((grp) => /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(React40.Fragment, { children: [
6599
+ ] }) : groups.map((grp) => /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(React41.Fragment, { children: [
6545
6600
  grp.g ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "fd-pop-group", children: grp.g }) : null,
6546
6601
  grp.items.map(({ o, i }) => /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
6547
6602
  "button",
@@ -6578,7 +6633,7 @@ function Select({
6578
6633
  }
6579
6634
 
6580
6635
  // src/components/forms/TimePicker.tsx
6581
- var React41 = __toESM(require("react"), 1);
6636
+ var React42 = __toESM(require("react"), 1);
6582
6637
  var import_jsx_runtime69 = require("react/jsx-runtime");
6583
6638
  var pad = (n) => String(n).padStart(2, "0");
6584
6639
  function ClockFace({ value = "09:00", onChange }) {
@@ -6587,9 +6642,9 @@ function ClockFace({ value = "09:00", onChange }) {
6587
6642
  if (isNaN(m)) m = 0;
6588
6643
  const pm = h24 >= 12;
6589
6644
  const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
6590
- const [mode2, setMode] = React41.useState("h");
6591
- const faceRef = React41.useRef(null);
6592
- const dragging = React41.useRef(false);
6645
+ const [mode2, setMode] = React42.useState("h");
6646
+ const faceRef = React42.useRef(null);
6647
+ const dragging = React42.useRef(false);
6593
6648
  const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
6594
6649
  const R = 108, NR = 80;
6595
6650
  const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
@@ -6662,9 +6717,9 @@ function ClockFace({ value = "09:00", onChange }) {
6662
6717
  }
6663
6718
  function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
6664
6719
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
6665
- const [open2, setOpen] = React41.useState(false);
6666
- const rootRef = React41.useRef(null);
6667
- const boxRef = React41.useRef(null);
6720
+ const [open2, setOpen] = React42.useState(false);
6721
+ const rootRef = React42.useRef(null);
6722
+ const boxRef = React42.useRef(null);
6668
6723
  const disp = () => {
6669
6724
  if (!value) return "";
6670
6725
  const [h, m] = value.split(":").map(Number);
@@ -6707,7 +6762,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
6707
6762
  offset: 6,
6708
6763
  width: 262,
6709
6764
  role: "presentation",
6710
- footer: /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(React41.Fragment, { children: [
6765
+ footer: /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(React42.Fragment, { children: [
6711
6766
  /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
6712
6767
  "button",
6713
6768
  {
@@ -6735,7 +6790,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
6735
6790
  }
6736
6791
 
6737
6792
  // src/components/forms/Slider.tsx
6738
- var React42 = __toESM(require("react"), 1);
6793
+ var React43 = __toESM(require("react"), 1);
6739
6794
  var import_jsx_runtime70 = require("react/jsx-runtime");
6740
6795
  function Slider({
6741
6796
  label,
@@ -6753,7 +6808,7 @@ function Slider({
6753
6808
  ...rest
6754
6809
  }) {
6755
6810
  const fieldId = useFieldId(id);
6756
- const [dragging, setDragging] = React42.useState(false);
6811
+ const [dragging, setDragging] = React43.useState(false);
6757
6812
  const v = value === void 0 ? min : Number(value);
6758
6813
  const pct = max === min ? 0 : (v - min) / (max - min) * 100;
6759
6814
  return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
@@ -6787,7 +6842,7 @@ function Slider({
6787
6842
  }
6788
6843
 
6789
6844
  // src/components/forms/RangeSlider.tsx
6790
- var React43 = __toESM(require("react"), 1);
6845
+ var React44 = __toESM(require("react"), 1);
6791
6846
  var import_jsx_runtime71 = require("react/jsx-runtime");
6792
6847
  function RangeSlider({
6793
6848
  label,
@@ -6807,9 +6862,9 @@ function RangeSlider({
6807
6862
  }) {
6808
6863
  const fmt2 = format || ((v) => String(v));
6809
6864
  const [a, b] = value || [min, max];
6810
- const [drag, setDrag] = React43.useState(null);
6811
- const [focus, setFocus] = React43.useState(null);
6812
- const railRef = React43.useRef(null);
6865
+ const [drag, setDrag] = React44.useState(null);
6866
+ const [focus, setFocus] = React44.useState(null);
6867
+ const railRef = React44.useRef(null);
6813
6868
  const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
6814
6869
  const clampPair = (i, v) => {
6815
6870
  v = Math.min(max, Math.max(min, Math.round(v / step) * step));
@@ -6824,7 +6879,7 @@ function RangeSlider({
6824
6879
  const r = railRef.current.getBoundingClientRect();
6825
6880
  return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
6826
6881
  };
6827
- React43.useEffect(() => {
6882
+ React44.useEffect(() => {
6828
6883
  if (drag === null) return;
6829
6884
  const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
6830
6885
  const upH = () => setDrag(null);
@@ -6905,7 +6960,7 @@ function RangeSlider({
6905
6960
  /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
6906
6961
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "fd-range-rail", ref: railRef }),
6907
6962
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
6908
- marks.map((m) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(React43.Fragment, { children: [
6963
+ marks.map((m) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(React44.Fragment, { children: [
6909
6964
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
6910
6965
  m.label ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
6911
6966
  ] }, m.value)),
@@ -6934,7 +6989,7 @@ function RangeSlider({
6934
6989
  }
6935
6990
 
6936
6991
  // src/components/forms/Dropzone.tsx
6937
- var React44 = __toESM(require("react"), 1);
6992
+ var React45 = __toESM(require("react"), 1);
6938
6993
  var import_jsx_runtime72 = require("react/jsx-runtime");
6939
6994
  function Dropzone({
6940
6995
  onFiles,
@@ -6949,8 +7004,8 @@ function Dropzone({
6949
7004
  className = "",
6950
7005
  style
6951
7006
  }) {
6952
- const [over, setOver] = React44.useState(false);
6953
- const depth = React44.useRef(0);
7007
+ const [over, setOver] = React45.useState(false);
7008
+ const depth = React45.useRef(0);
6954
7009
  const has = (e) => {
6955
7010
  const dt = e.dataTransfer;
6956
7011
  if (!dt) return false;
@@ -7012,8 +7067,8 @@ function FilePickButton({
7012
7067
  className = "",
7013
7068
  children
7014
7069
  }) {
7015
- const ref = React44.useRef(null);
7016
- return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(React44.Fragment, { children: [
7070
+ const ref = React45.useRef(null);
7071
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(React45.Fragment, { children: [
7017
7072
  /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
7018
7073
  "button",
7019
7074
  {
@@ -7046,10 +7101,10 @@ function FilePickButton({
7046
7101
  }
7047
7102
  function useStagedFiles(upload, opts) {
7048
7103
  const o = opts || {};
7049
- const [items, setItems] = React44.useState([]);
7050
- const controllers = React44.useRef({});
7104
+ const [items, setItems] = React45.useState([]);
7105
+ const controllers = React45.useRef({});
7051
7106
  const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
7052
- const run = React44.useCallback((att) => {
7107
+ const run = React45.useCallback((att) => {
7053
7108
  if (!upload) return;
7054
7109
  const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
7055
7110
  controllers.current[att.id] = ac;
@@ -7066,14 +7121,14 @@ function useStagedFiles(upload, opts) {
7066
7121
  delete controllers.current[att.id];
7067
7122
  });
7068
7123
  }, [upload]);
7069
- const add = React44.useCallback((files) => {
7124
+ const add = React45.useCallback((files) => {
7070
7125
  if (!upload) return [];
7071
7126
  const atts = Array.from(files).map((f) => toAttachment(f));
7072
7127
  setItems((list) => list.concat(atts));
7073
7128
  atts.forEach(run);
7074
7129
  return atts;
7075
7130
  }, [upload, run]);
7076
- const remove = React44.useCallback((att) => {
7131
+ const remove = React45.useCallback((att) => {
7077
7132
  const ac = controllers.current[att.id];
7078
7133
  if (ac) {
7079
7134
  try {
@@ -7084,10 +7139,10 @@ function useStagedFiles(upload, opts) {
7084
7139
  }
7085
7140
  setItems((list) => list.filter((f) => f.id !== att.id));
7086
7141
  }, []);
7087
- const retry = React44.useCallback((att) => {
7142
+ const retry = React45.useCallback((att) => {
7088
7143
  run(att);
7089
7144
  }, [run]);
7090
- const clear = React44.useCallback(() => {
7145
+ const clear = React45.useCallback(() => {
7091
7146
  Object.values(controllers.current).forEach((ac) => {
7092
7147
  try {
7093
7148
  ac && ac.abort();
@@ -7211,7 +7266,7 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
7211
7266
  }
7212
7267
 
7213
7268
  // src/components/forms/MarkdownEditor.tsx
7214
- var React45 = __toESM(require("react"), 1);
7269
+ var React46 = __toESM(require("react"), 1);
7215
7270
  var import_jsx_runtime74 = require("react/jsx-runtime");
7216
7271
  var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
7217
7272
  var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
@@ -7425,7 +7480,7 @@ function syncDom(root, value) {
7425
7480
  while (root.children.length > lines.length) root.removeChild(root.lastChild);
7426
7481
  }
7427
7482
  var LIST_CONT = RE_LI;
7428
- var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7483
+ var MarkdownEditor = React46.forwardRef(function MarkdownEditor2({
7429
7484
  value = "",
7430
7485
  onChange,
7431
7486
  onSubmit,
@@ -7444,10 +7499,10 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7444
7499
  className = "",
7445
7500
  id
7446
7501
  }, ref) {
7447
- const boxRef = React45.useRef(null);
7448
- const composing = React45.useRef(false);
7449
- const pendingCaret = React45.useRef(null);
7450
- React45.useLayoutEffect(() => {
7502
+ const boxRef = React46.useRef(null);
7503
+ const composing = React46.useRef(false);
7504
+ const pendingCaret = React46.useRef(null);
7505
+ React46.useLayoutEffect(() => {
7451
7506
  const root = boxRef.current;
7452
7507
  if (!root || composing.current) return;
7453
7508
  const active = document.activeElement === root || root.contains(document.activeElement);
@@ -7456,7 +7511,7 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7456
7511
  pendingCaret.current = null;
7457
7512
  if (active && caret != null) placeCaret(root, caret);
7458
7513
  }, [value]);
7459
- React45.useEffect(() => {
7514
+ React46.useEffect(() => {
7460
7515
  if (autoFocus && boxRef.current) boxRef.current.focus();
7461
7516
  }, [autoFocus]);
7462
7517
  const caretNow = () => {
@@ -7523,8 +7578,8 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7523
7578
  api.replaceRange(from, to, next, from + next.length);
7524
7579
  }
7525
7580
  };
7526
- React45.useImperativeHandle(ref, () => api);
7527
- const caretAtKeydown = React45.useRef(-1);
7581
+ React46.useImperativeHandle(ref, () => api);
7582
+ const caretAtKeydown = React46.useRef(-1);
7528
7583
  function detect(text, caret) {
7529
7584
  if (!onTrigger) return;
7530
7585
  const upto = text.slice(0, caret);
@@ -7677,7 +7732,7 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7677
7732
  });
7678
7733
 
7679
7734
  // src/components/forms/CodeEditor.tsx
7680
- var React46 = __toESM(require("react"), 1);
7735
+ var React47 = __toESM(require("react"), 1);
7681
7736
  var import_view = require("@codemirror/view");
7682
7737
  var import_state = require("@codemirror/state");
7683
7738
  var import_commands = require("@codemirror/commands");
@@ -7781,16 +7836,16 @@ function CodeEditor({
7781
7836
  const fieldId = useFieldId(id);
7782
7837
  const descId = fieldId + "-desc";
7783
7838
  const liveId = fieldId + "-live";
7784
- const hostRef = React46.useRef(null);
7785
- const viewRef = React46.useRef(null);
7786
- const valueRef = React46.useRef(value);
7787
- const onChangeRef = React46.useRef(onChange);
7839
+ const hostRef = React47.useRef(null);
7840
+ const viewRef = React47.useRef(null);
7841
+ const valueRef = React47.useRef(value);
7842
+ const onChangeRef = React47.useRef(onChange);
7788
7843
  onChangeRef.current = onChange;
7789
- const editableCompartment = React46.useRef(new import_state.Compartment()).current;
7790
- const attributesCompartment = React46.useRef(new import_state.Compartment()).current;
7791
- const errorRef = React46.useRef(error);
7844
+ const editableCompartment = React47.useRef(new import_state.Compartment()).current;
7845
+ const attributesCompartment = React47.useRef(new import_state.Compartment()).current;
7846
+ const errorRef = React47.useRef(error);
7792
7847
  errorRef.current = error;
7793
- const diagnosticsCountRef = React46.useRef(diagnostics.length);
7848
+ const diagnosticsCountRef = React47.useRef(diagnostics.length);
7794
7849
  diagnosticsCountRef.current = diagnostics.length;
7795
7850
  function contentAttributes() {
7796
7851
  return {
@@ -7800,9 +7855,9 @@ function CodeEditor({
7800
7855
  ...label ? { "aria-label": label } : {}
7801
7856
  };
7802
7857
  }
7803
- React46.useEffect(() => {
7804
- const host = hostRef.current;
7805
- if (!host) return;
7858
+ React47.useEffect(() => {
7859
+ const host2 = hostRef.current;
7860
+ if (!host2) return;
7806
7861
  const updateListener = import_view.EditorView.updateListener.of((update) => {
7807
7862
  if (!update.docChanged) return;
7808
7863
  const next = update.state.doc.toString();
@@ -7834,7 +7889,7 @@ function CodeEditor({
7834
7889
  attributesCompartment.of(import_view.EditorView.contentAttributes.of(contentAttributes()))
7835
7890
  ]
7836
7891
  });
7837
- const view = new import_view.EditorView({ state, parent: host });
7892
+ const view = new import_view.EditorView({ state, parent: host2 });
7838
7893
  viewRef.current = view;
7839
7894
  if (autoFocus) view.focus();
7840
7895
  return () => {
@@ -7842,7 +7897,7 @@ function CodeEditor({
7842
7897
  viewRef.current = null;
7843
7898
  };
7844
7899
  }, []);
7845
- React46.useEffect(() => {
7900
+ React47.useEffect(() => {
7846
7901
  const view = viewRef.current;
7847
7902
  if (!view) return;
7848
7903
  const current2 = view.state.doc.toString();
@@ -7851,12 +7906,12 @@ function CodeEditor({
7851
7906
  }
7852
7907
  valueRef.current = value;
7853
7908
  }, [value]);
7854
- React46.useEffect(() => {
7909
+ React47.useEffect(() => {
7855
7910
  const view = viewRef.current;
7856
7911
  if (!view) return;
7857
7912
  view.dispatch({ effects: editableCompartment.reconfigure(import_view.EditorView.editable.of(!disabled)) });
7858
7913
  }, [disabled, editableCompartment]);
7859
- React46.useEffect(() => {
7914
+ React47.useEffect(() => {
7860
7915
  const view = viewRef.current;
7861
7916
  if (!view) return;
7862
7917
  view.dispatch({
@@ -7914,16 +7969,16 @@ function CodeEditor({
7914
7969
  }
7915
7970
 
7916
7971
  // src/components/platform/AccountMenu.tsx
7917
- var React48 = __toESM(require("react"), 1);
7972
+ var React49 = __toESM(require("react"), 1);
7918
7973
 
7919
7974
  // src/kits/sessionContext.tsx
7920
- var React47 = __toESM(require("react"), 1);
7921
- var SessionContext = React47.createContext(null);
7975
+ var React48 = __toESM(require("react"), 1);
7976
+ var SessionContext = React48.createContext(null);
7922
7977
  function SessionProvider({ value, children }) {
7923
- return React47.createElement(SessionContext.Provider, { value }, children);
7978
+ return React48.createElement(SessionContext.Provider, { value }, children);
7924
7979
  }
7925
7980
  function useSessionContext() {
7926
- const ctx = React47.useContext(SessionContext);
7981
+ const ctx = React48.useContext(SessionContext);
7927
7982
  if (!ctx) {
7928
7983
  throw new Error(
7929
7984
  "useSessionContext() was called outside a <SessionProvider>. Wrap your app root in <SessionProvider value={...}> with your real session, or \u2014 in the docs site or a demo \u2014 in <DemoSessionProvider>, before rendering AccountMenu, Gate, ProfilePage or AppSwitcher."
@@ -7963,11 +8018,11 @@ function AccountMenu({
7963
8018
  ...rest
7964
8019
  }) {
7965
8020
  const { user, roles, can: can2, signOut: ctxSignOut, demo, pending } = useSessionContext();
7966
- const [open2, setOpen] = React48.useState(false);
7967
- const [switching, setSwitching] = React48.useState(false);
7968
- const [signingOut, setSigningOut] = React48.useState(false);
7969
- const [signOutError, setSignOutError] = React48.useState(null);
7970
- const ref = React48.useRef(null);
8021
+ const [open2, setOpen] = React49.useState(false);
8022
+ const [switching, setSwitching] = React49.useState(false);
8023
+ const [signingOut, setSigningOut] = React49.useState(false);
8024
+ const [signOutError, setSignOutError] = React49.useState(null);
8025
+ const ref = React49.useRef(null);
7971
8026
  const visibleLinks = links.filter((l) => !l.perm || !pending && can2(l.perm));
7972
8027
  const visibleGroups = groups.map((g) => ({ label: g.label, links: g.links.filter((l) => !l.perm || !pending && can2(l.perm)) })).filter((g) => g.links.length);
7973
8028
  const closeMenu = () => {
@@ -8092,13 +8147,13 @@ function AccountMenu({
8092
8147
  }
8093
8148
 
8094
8149
  // src/components/platform/AppSwitcher.tsx
8095
- var React49 = __toESM(require("react"), 1);
8150
+ var React50 = __toESM(require("react"), 1);
8096
8151
  var import_jsx_runtime77 = require("react/jsx-runtime");
8097
8152
  function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
8098
8153
  const { apps: contextApps } = useSessionContext();
8099
8154
  const apps = appsProp ?? contextApps ?? [];
8100
- const [open2, setOpen] = React49.useState(false);
8101
- const anchorRef = React49.useRef(null);
8155
+ const [open2, setOpen] = React50.useState(false);
8156
+ const anchorRef = React50.useRef(null);
8102
8157
  if (!apps.length) return null;
8103
8158
  const items = apps.map((app) => ({
8104
8159
  id: app.key,
@@ -8112,7 +8167,7 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
8112
8167
  window.location.href = app.url;
8113
8168
  }
8114
8169
  }));
8115
- return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(React49.Fragment, { children: [
8170
+ return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(React50.Fragment, { children: [
8116
8171
  /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("span", { ref: anchorRef, className: ["fd-appswitch-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
8117
8172
  IconButton,
8118
8173
  {
@@ -8141,10 +8196,10 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
8141
8196
  }
8142
8197
 
8143
8198
  // src/components/platform/AppearanceMenu.tsx
8144
- var React51 = __toESM(require("react"), 1);
8199
+ var React52 = __toESM(require("react"), 1);
8145
8200
 
8146
8201
  // src/kits/appearance.ts
8147
- var React50 = __toESM(require("react"), 1);
8202
+ var React51 = __toESM(require("react"), 1);
8148
8203
  var DEFAULT_STORAGE_KEY = "fd-appearance";
8149
8204
  var DEFAULT_PREFS = {
8150
8205
  theme: "system",
@@ -8239,11 +8294,11 @@ function applyPrefs(prefs, root = document.documentElement) {
8239
8294
  else root.removeAttribute("data-motion");
8240
8295
  }
8241
8296
  function useAppearancePrefs(store) {
8242
- const prefs = React50.useSyncExternalStore(store.subscribe, store.getSnapshot);
8243
- React50.useEffect(() => {
8297
+ const prefs = React51.useSyncExternalStore(store.subscribe, store.getSnapshot);
8298
+ React51.useEffect(() => {
8244
8299
  applyPrefs(prefs);
8245
8300
  }, [prefs]);
8246
- React50.useEffect(() => {
8301
+ React51.useEffect(() => {
8247
8302
  if (prefs.theme !== "system" || typeof window === "undefined" || typeof window.matchMedia !== "function") {
8248
8303
  return;
8249
8304
  }
@@ -8252,7 +8307,7 @@ function useAppearancePrefs(store) {
8252
8307
  mq.addEventListener("change", onChange);
8253
8308
  return () => mq.removeEventListener("change", onChange);
8254
8309
  }, [prefs]);
8255
- const update = React50.useCallback(
8310
+ const update = React51.useCallback(
8256
8311
  (patch) => {
8257
8312
  store.write({ ...store.getSnapshot(), ...patch });
8258
8313
  },
@@ -8275,15 +8330,15 @@ var TEXT_SCALE_OPTIONS = [
8275
8330
  { value: "xl", label: "XL" }
8276
8331
  ];
8277
8332
  function AppearanceMenu({ className = "", store: storeProp, storageKey, storage, defaults }) {
8278
- const store = React51.useMemo(
8333
+ const store = React52.useMemo(
8279
8334
  () => storeProp ?? createLocalStorageAppearanceStore({ storageKey, storage, defaults }),
8280
8335
  [storeProp, storageKey, storage, defaults]
8281
8336
  );
8282
8337
  const [prefs, update] = useAppearancePrefs(store);
8283
- const [open2, setOpen] = React51.useState(false);
8284
- const anchorRef = React51.useRef(null);
8338
+ const [open2, setOpen] = React52.useState(false);
8339
+ const anchorRef = React52.useRef(null);
8285
8340
  const patch = (p) => update(p);
8286
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(React51.Fragment, { children: [
8341
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(React52.Fragment, { children: [
8287
8342
  /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { ref: anchorRef, className: ["fd-appearance-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
8288
8343
  IconButton,
8289
8344
  {
@@ -8352,14 +8407,14 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
8352
8407
  }
8353
8408
 
8354
8409
  // src/components/platform/ApiSpecBrowser.tsx
8355
- var React52 = __toESM(require("react"), 1);
8410
+ var React53 = __toESM(require("react"), 1);
8356
8411
  var import_jsx_runtime79 = require("react/jsx-runtime");
8357
8412
  var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
8358
8413
  function Json({ obj }) {
8359
8414
  return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
8360
8415
  }
8361
8416
  function Endpoint({ s, onRequest }) {
8362
- const [tried, setTried] = React52.useState(null);
8417
+ const [tried, setTried] = React53.useState(null);
8363
8418
  const run = async () => {
8364
8419
  setTried("busy");
8365
8420
  const t0 = (window.performance || Date).now();
@@ -8432,10 +8487,10 @@ function ApiSpecBrowser({
8432
8487
  className = "",
8433
8488
  ...rest
8434
8489
  }) {
8435
- const [q, setQ] = React52.useState("");
8436
- const [method, setMethod] = React52.useState(null);
8437
- const [mod, setMod] = React52.useState(null);
8438
- const [listOnly, setListOnly] = React52.useState(false);
8490
+ const [q, setQ] = React53.useState("");
8491
+ const [method, setMethod] = React53.useState(null);
8492
+ const [mod, setMod] = React53.useState(null);
8493
+ const [listOnly, setListOnly] = React53.useState(false);
8439
8494
  const activeModule = modules && modules.find((m) => m.id === mod);
8440
8495
  const hits = spec.filter((s) => (!method || s.method === method) && (!listOnly || s.isList) && (!activeModule || activeModule.endpoints.indexOf(s.id) >= 0) && (!q || (s.path + " " + s.title + " " + s.purpose + " " + (s.usedBy || []).join(" ")).toLowerCase().includes(q.toLowerCase())));
8441
8496
  const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
@@ -8514,7 +8569,7 @@ function ApiSpecBrowser({
8514
8569
  }
8515
8570
 
8516
8571
  // src/components/platform/ProfilePage.tsx
8517
- var React53 = __toESM(require("react"), 1);
8572
+ var React54 = __toESM(require("react"), 1);
8518
8573
  var import_jsx_runtime80 = require("react/jsx-runtime");
8519
8574
  function fieldInitialValue(field, user) {
8520
8575
  if (field.value) return field.value(user);
@@ -8550,21 +8605,21 @@ function ProfilePage({
8550
8605
  }) {
8551
8606
  const { user: sessionUser, roles, permissions, saveProfile: saveProfile2 } = useSessionContext();
8552
8607
  const user = userProp || sessionUser;
8553
- const initialFieldValues = React53.useMemo(() => {
8608
+ const initialFieldValues = React54.useMemo(() => {
8554
8609
  const values2 = {};
8555
8610
  for (const field of fields) values2[field.key] = fieldInitialValue(field, user);
8556
8611
  return values2;
8557
8612
  }, [user.id, fields]);
8558
- const initialNotify = React53.useMemo(() => {
8613
+ const initialNotify = React54.useMemo(() => {
8559
8614
  const values2 = {};
8560
8615
  for (const n of notifications) values2[n.key] = !!user.notify?.[n.key];
8561
8616
  return values2;
8562
8617
  }, [user.id, notifications]);
8563
- const [values, setValues] = React53.useState(initialFieldValues);
8564
- const [notify, setNotify] = React53.useState(initialNotify);
8565
- const [saving, setSaving] = React53.useState(false);
8566
- const [saved, setSaved] = React53.useState(false);
8567
- const [prevUserId, setPrevUserId] = React53.useState(user.id);
8618
+ const [values, setValues] = React54.useState(initialFieldValues);
8619
+ const [notify, setNotify] = React54.useState(initialNotify);
8620
+ const [saving, setSaving] = React54.useState(false);
8621
+ const [saved, setSaved] = React54.useState(false);
8622
+ const [prevUserId, setPrevUserId] = React54.useState(user.id);
8568
8623
  if (user.id !== prevUserId) {
8569
8624
  setPrevUserId(user.id);
8570
8625
  setValues(initialFieldValues);
@@ -8752,11 +8807,11 @@ function ProfilePage({
8752
8807
  }
8753
8808
 
8754
8809
  // src/components/platform/SignInPage.tsx
8755
- var React54 = __toESM(require("react"), 1);
8810
+ var React55 = __toESM(require("react"), 1);
8756
8811
  var import_jsx_runtime81 = require("react/jsx-runtime");
8757
8812
  function SignInPage({ productName, onSignIn, continueAs, error }) {
8758
- const [signingIn, setSigningIn] = React54.useState(false);
8759
- const [resuming, setResuming] = React54.useState(false);
8813
+ const [signingIn, setSigningIn] = React55.useState(false);
8814
+ const [resuming, setResuming] = React55.useState(false);
8760
8815
  function handleSignIn() {
8761
8816
  setSigningIn(true);
8762
8817
  onSignIn();
@@ -8945,10 +9000,10 @@ function GoogleGlyph() {
8945
9000
  }
8946
9001
 
8947
9002
  // src/components/platform/RoadmapTimeline.tsx
8948
- var React57 = __toESM(require("react"), 1);
9003
+ var React58 = __toESM(require("react"), 1);
8949
9004
 
8950
9005
  // src/kits/session.ts
8951
- var React55 = __toESM(require("react"), 1);
9006
+ var React56 = __toESM(require("react"), 1);
8952
9007
  var PERMISSION_CATALOG = [
8953
9008
  { group: "Plans", items: [
8954
9009
  { key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
@@ -10515,8 +10570,8 @@ function roadmap(overrides) {
10515
10570
  };
10516
10571
  }
10517
10572
  function useSession() {
10518
- const [s, setS] = React55.useState(getSession);
10519
- React55.useEffect(() => subscribe(setS), []);
10573
+ const [s, setS] = React56.useState(getSession);
10574
+ React56.useEffect(() => subscribe(setS), []);
10520
10575
  return s;
10521
10576
  }
10522
10577
  var SessionKit = {
@@ -10549,7 +10604,7 @@ var SessionKit = {
10549
10604
  };
10550
10605
  function DemoSessionProvider({ children }) {
10551
10606
  const session = useSession();
10552
- const value = React55.useMemo(
10607
+ const value = React56.useMemo(
10553
10608
  () => ({
10554
10609
  user: session.user,
10555
10610
  roles: session.roles,
@@ -10565,11 +10620,11 @@ function DemoSessionProvider({ children }) {
10565
10620
  }),
10566
10621
  [session]
10567
10622
  );
10568
- return React55.createElement(SessionProvider, { value }, children);
10623
+ return React56.createElement(SessionProvider, { value }, children);
10569
10624
  }
10570
10625
 
10571
10626
  // src/kits/runtime.ts
10572
- var React56 = __toESM(require("react"), 1);
10627
+ var React57 = __toESM(require("react"), 1);
10573
10628
  var WIRED_ENDPOINTS = [
10574
10629
  // Nothing yet. Every id below would come from a real service:
10575
10630
  // "plan.get", "placements.list", …
@@ -10740,8 +10795,8 @@ var RuntimeKit = {
10740
10795
  };
10741
10796
  RuntimeKit.declare(FEATURE_NEEDS);
10742
10797
  function useRuntimeMode() {
10743
- const [m, setM] = React56.useState(RuntimeKit.getMode());
10744
- React56.useEffect(() => RuntimeKit.subscribe(setM), []);
10798
+ const [m, setM] = React57.useState(RuntimeKit.getMode());
10799
+ React57.useEffect(() => RuntimeKit.subscribe(setM), []);
10745
10800
  return m;
10746
10801
  }
10747
10802
  function useFeatureStatus(key) {
@@ -10824,12 +10879,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
10824
10879
  }
10825
10880
  function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10826
10881
  const session = SessionKit.useSession();
10827
- const [project, setProject] = React57.useState("");
10828
- const [q, setQ] = React57.useState("");
10829
- const scrollRef = React57.useRef(null);
10830
- const nowRef = React57.useRef(null);
10831
- const rm = React57.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
10832
- const byKey = React57.useMemo(() => {
10882
+ const [project, setProject] = React58.useState("");
10883
+ const [q, setQ] = React58.useState("");
10884
+ const scrollRef = React58.useRef(null);
10885
+ const nowRef = React58.useRef(null);
10886
+ const rm = React58.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
10887
+ const byKey = React58.useMemo(() => {
10833
10888
  const m = {};
10834
10889
  rm.items.forEach((i) => {
10835
10890
  m[i.key] = i;
@@ -10838,7 +10893,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10838
10893
  }, [rm]);
10839
10894
  const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
10840
10895
  const projects = [...new Set(rm.items.map((i) => i.project))];
10841
- React57.useEffect(() => {
10896
+ React58.useEffect(() => {
10842
10897
  let raf1 = 0, raf2 = 0;
10843
10898
  const place = () => {
10844
10899
  const box = scrollRef.current, mark = nowRef.current;
@@ -10912,7 +10967,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10912
10967
  lastPhase = item.phase;
10913
10968
  const inPhase = items.filter((i) => i.phase === item.phase).length;
10914
10969
  const isBoundary = n === firstPending;
10915
- return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(React57.Fragment, { children: [
10970
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(React58.Fragment, { children: [
10916
10971
  showPhase ? /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "fd-rm-era", children: [
10917
10972
  /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
10918
10973
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
@@ -10956,8 +11011,8 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10956
11011
  }
10957
11012
 
10958
11013
  // src/components/platform/ComingSoon.tsx
10959
- var React58 = __toESM(require("react"), 1);
10960
- var import_react_dom6 = require("react-dom");
11014
+ var React59 = __toESM(require("react"), 1);
11015
+ var import_react_dom7 = require("react-dom");
10961
11016
  var import_jsx_runtime83 = require("react/jsx-runtime");
10962
11017
  var BYPASS_STORE = "fd.soon.bypass.v1";
10963
11018
  function readBypassed() {
@@ -10974,8 +11029,8 @@ function writeBypassed(list) {
10974
11029
  }
10975
11030
  }
10976
11031
  function useBypass(key) {
10977
- const [on, setOn] = React58.useState(() => !!key && readBypassed().indexOf(key) >= 0);
10978
- React58.useEffect(() => {
11032
+ const [on, setOn] = React59.useState(() => !!key && readBypassed().indexOf(key) >= 0);
11033
+ React59.useEffect(() => {
10979
11034
  setOn(!!key && readBypassed().indexOf(key) >= 0);
10980
11035
  }, [key]);
10981
11036
  const set = (next) => {
@@ -11022,9 +11077,9 @@ function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onB
11022
11077
  ] });
11023
11078
  }
11024
11079
  function useHoverCard(open2) {
11025
- const anchor = React58.useRef(null);
11026
- const [pos, setPos] = React58.useState(null);
11027
- React58.useLayoutEffect(() => {
11080
+ const anchor = React59.useRef(null);
11081
+ const [pos, setPos] = React59.useState(null);
11082
+ React59.useLayoutEffect(() => {
11028
11083
  if (!open2 || !anchor.current) {
11029
11084
  setPos(null);
11030
11085
  return;
@@ -11151,12 +11206,12 @@ function ComingSoon({
11151
11206
  ] });
11152
11207
  }
11153
11208
  function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
11154
- const [open2, setOpen] = React58.useState(false);
11209
+ const [open2, setOpen] = React59.useState(false);
11155
11210
  const [anchor, pos] = useHoverCard(open2);
11156
- const hoverCardRef = React58.useRef(null);
11211
+ const hoverCardRef = React59.useRef(null);
11157
11212
  const hoverLayer = useStackedLayer({ active: open2, containerRef: hoverCardRef, returnFocus: false });
11158
11213
  const zIndex = useLayerZIndex(hoverLayer);
11159
- const close2 = React58.useRef(null);
11214
+ const close2 = React59.useRef(null);
11160
11215
  const show = () => {
11161
11216
  if (close2.current) {
11162
11217
  clearTimeout(close2.current);
@@ -11172,7 +11227,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
11172
11227
  setOpen(false);
11173
11228
  }, 140);
11174
11229
  };
11175
- React58.useEffect(() => () => {
11230
+ React59.useEffect(() => () => {
11176
11231
  if (close2.current) clearTimeout(close2.current);
11177
11232
  }, []);
11178
11233
  return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(
@@ -11201,7 +11256,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
11201
11256
  children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
11202
11257
  }
11203
11258
  ),
11204
- open2 && pos ? (0, import_react_dom6.createPortal)(
11259
+ open2 && pos ? (0, import_react_dom7.createPortal)(
11205
11260
  /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
11206
11261
  "div",
11207
11262
  {
@@ -11624,7 +11679,7 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
11624
11679
  }
11625
11680
 
11626
11681
  // src/components/planner/MixGap.tsx
11627
- var React59 = __toESM(require("react"), 1);
11682
+ var React60 = __toESM(require("react"), 1);
11628
11683
  var import_jsx_runtime88 = require("react/jsx-runtime");
11629
11684
  var MIX_GAP_LAYOUT = {
11630
11685
  trackHeight: 30,
@@ -11639,7 +11694,7 @@ function mixGapOffset(value, max) {
11639
11694
  }
11640
11695
  function MixGap({ rows = [], loading = false, className = "" }) {
11641
11696
  const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
11642
- const [hover, setHover] = React59.useState(null);
11697
+ const [hover, setHover] = React60.useState(null);
11643
11698
  const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
11644
11699
  const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
11645
11700
  const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
@@ -11782,7 +11837,7 @@ function ChannelContribution({
11782
11837
  }
11783
11838
 
11784
11839
  // src/components/planner/BudgetReallocator.tsx
11785
- var React60 = __toESM(require("react"), 1);
11840
+ var React61 = __toESM(require("react"), 1);
11786
11841
  var import_jsx_runtime90 = require("react/jsx-runtime");
11787
11842
  var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
11788
11843
  function BudgetReallocator({
@@ -11798,8 +11853,8 @@ function BudgetReallocator({
11798
11853
  onCancel,
11799
11854
  className = ""
11800
11855
  }) {
11801
- const [draft, setDraft] = React60.useState(spend);
11802
- React60.useEffect(() => setDraft(spend), [spend]);
11856
+ const [draft, setDraft] = React61.useState(spend);
11857
+ React61.useEffect(() => setDraft(spend), [spend]);
11803
11858
  const dirty = draft !== spend;
11804
11859
  const nextCrp = scoreFor ? scoreFor(draft) : crp;
11805
11860
  const nextBand = bandFor(nextCrp);
@@ -11814,10 +11869,10 @@ function BudgetReallocator({
11814
11869
  setDraft(spend);
11815
11870
  if (onCancel) onCancel();
11816
11871
  };
11817
- const trackRef = React60.useRef(null);
11818
- const chipRef = React60.useRef(null);
11819
- const [chipLeft, setChipLeft] = React60.useState(null);
11820
- React60.useLayoutEffect(() => {
11872
+ const trackRef = React61.useRef(null);
11873
+ const chipRef = React61.useRef(null);
11874
+ const [chipLeft, setChipLeft] = React61.useState(null);
11875
+ React61.useLayoutEffect(() => {
11821
11876
  const track = trackRef.current;
11822
11877
  if (!dirty || !track) {
11823
11878
  setChipLeft(null);
@@ -12005,7 +12060,7 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "", d
12005
12060
  }
12006
12061
 
12007
12062
  // src/components/planner/PreferenceMeter.tsx
12008
- var React61 = __toESM(require("react"), 1);
12063
+ var React62 = __toESM(require("react"), 1);
12009
12064
  var import_jsx_runtime93 = require("react/jsx-runtime");
12010
12065
  function preferenceScore(criteria) {
12011
12066
  const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
@@ -12035,7 +12090,7 @@ function PreferenceMeter({
12035
12090
  className = ""
12036
12091
  }) {
12037
12092
  const value = score == null ? preferenceScore(criteria) : score;
12038
- const segments = React61.useMemo(() => preferenceSegments(criteria), [criteria]);
12093
+ const segments = React62.useMemo(() => preferenceSegments(criteria), [criteria]);
12039
12094
  return /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
12040
12095
  ScoreMeter,
12041
12096
  {
@@ -12074,10 +12129,10 @@ function PreferenceMeter({
12074
12129
  }
12075
12130
 
12076
12131
  // src/components/chat/AgentChatPanel.tsx
12077
- var React67 = __toESM(require("react"), 1);
12132
+ var React68 = __toESM(require("react"), 1);
12078
12133
 
12079
12134
  // src/components/chat/chatEngine.ts
12080
- var React62 = __toESM(require("react"), 1);
12135
+ var React63 = __toESM(require("react"), 1);
12081
12136
  var CHAT_UNAVAILABLE = "chat_unavailable";
12082
12137
  var JOB_PENDING = ["queued", "running"];
12083
12138
  var JOB_SUCCESS = ["completed", "recovered"];
@@ -12131,22 +12186,22 @@ function useChatEngine(opts) {
12131
12186
  onClear,
12132
12187
  onFeedback
12133
12188
  } = opts || {};
12134
- const [status, setStatus] = React62.useState("idle");
12135
- const [threadId, setThreadId] = React62.useState(null);
12136
- const [messages, setMessages] = React62.useState([]);
12137
- const [queue, setQueue] = React62.useState([]);
12138
- const [fatal, setFatal] = React62.useState(null);
12139
- const [busy, setBusy] = React62.useState(false);
12140
- const [turnStartedAt, setTurnStartedAt] = React62.useState(null);
12141
- const listRef = React62.useRef([]);
12142
- const queueRef = React62.useRef([]);
12143
- const busyRef = React62.useRef(false);
12144
- const stoppedRef = React62.useRef(false);
12145
- const abortRef = React62.useRef(null);
12146
- const serverCount = React62.useRef(0);
12147
- const threadRef = React62.useRef(null);
12148
- const mounted = React62.useRef(true);
12149
- React62.useEffect(() => {
12189
+ const [status, setStatus] = React63.useState("idle");
12190
+ const [threadId, setThreadId] = React63.useState(null);
12191
+ const [messages, setMessages] = React63.useState([]);
12192
+ const [queue, setQueue] = React63.useState([]);
12193
+ const [fatal, setFatal] = React63.useState(null);
12194
+ const [busy, setBusy] = React63.useState(false);
12195
+ const [turnStartedAt, setTurnStartedAt] = React63.useState(null);
12196
+ const listRef = React63.useRef([]);
12197
+ const queueRef = React63.useRef([]);
12198
+ const busyRef = React63.useRef(false);
12199
+ const stoppedRef = React63.useRef(false);
12200
+ const abortRef = React63.useRef(null);
12201
+ const serverCount = React63.useRef(0);
12202
+ const threadRef = React63.useRef(null);
12203
+ const mounted = React63.useRef(true);
12204
+ React63.useEffect(() => {
12150
12205
  mounted.current = true;
12151
12206
  return () => {
12152
12207
  mounted.current = false;
@@ -12168,14 +12223,14 @@ function useChatEngine(opts) {
12168
12223
  }
12169
12224
  return false;
12170
12225
  };
12171
- const loadThread = React62.useCallback(async (id) => {
12226
+ const loadThread = React63.useCallback(async (id) => {
12172
12227
  const data = await apiAdapter.getThread(id);
12173
12228
  const list = [...data && data.messages || []];
12174
12229
  serverCount.current = list.length;
12175
12230
  commit(list);
12176
12231
  return list;
12177
12232
  }, [apiAdapter]);
12178
- React62.useEffect(() => {
12233
+ React63.useEffect(() => {
12179
12234
  if (!apiAdapter) {
12180
12235
  setStatus("idle");
12181
12236
  setFatal(null);
@@ -12388,7 +12443,7 @@ function useChatEngine(opts) {
12388
12443
  await dispatchTurn(turn);
12389
12444
  }
12390
12445
  }
12391
- const send = React62.useCallback((text, attachments) => {
12446
+ const send = React63.useCallback((text, attachments) => {
12392
12447
  const body = (text || "").trim();
12393
12448
  if (!body && !(attachments && attachments.length)) return;
12394
12449
  if (status === "disconnected") return;
@@ -12398,7 +12453,7 @@ function useChatEngine(opts) {
12398
12453
  stoppedRef.current = false;
12399
12454
  drain();
12400
12455
  }, [status]);
12401
- const stop = React62.useCallback(() => {
12456
+ const stop = React63.useCallback(() => {
12402
12457
  stoppedRef.current = true;
12403
12458
  const ac = abortRef.current;
12404
12459
  if (ac) {
@@ -12417,11 +12472,11 @@ function useChatEngine(opts) {
12417
12472
  store.del(STORAGE_PREFIX + threadRef.current);
12418
12473
  }
12419
12474
  }, [apiAdapter]);
12420
- const removeQueued = React62.useCallback((id) => {
12475
+ const removeQueued = React63.useCallback((id) => {
12421
12476
  queueRef.current = queueRef.current.filter((t) => t.id !== id);
12422
12477
  setQueue(queueRef.current.slice());
12423
12478
  }, []);
12424
- const retry = React62.useCallback(() => {
12479
+ const retry = React63.useCallback(() => {
12425
12480
  const list = listRef.current;
12426
12481
  let at = -1;
12427
12482
  for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
@@ -12437,19 +12492,19 @@ function useChatEngine(opts) {
12437
12492
  setQueue(queueRef.current.slice());
12438
12493
  drain();
12439
12494
  }, []);
12440
- const clear = React62.useCallback(() => {
12495
+ const clear = React63.useCallback(() => {
12441
12496
  commit([]);
12442
12497
  serverCount.current = 0;
12443
12498
  queueRef.current = [];
12444
12499
  setQueue([]);
12445
12500
  onClear && onClear();
12446
12501
  }, [onClear]);
12447
- const setFeedback = React62.useCallback((id, value) => {
12502
+ const setFeedback = React63.useCallback((id, value) => {
12448
12503
  patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
12449
12504
  const msg = listRef.current.find((m) => m.id === id);
12450
12505
  onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
12451
12506
  }, [onFeedback]);
12452
- const reload = React62.useCallback(async () => {
12507
+ const reload = React63.useCallback(async () => {
12453
12508
  if (!threadRef.current) return;
12454
12509
  setStatus("loading");
12455
12510
  try {
@@ -12487,10 +12542,10 @@ var ChatKit = {
12487
12542
  };
12488
12543
 
12489
12544
  // src/components/chat/ChatTranscript.tsx
12490
- var React64 = __toESM(require("react"), 1);
12545
+ var React65 = __toESM(require("react"), 1);
12491
12546
 
12492
12547
  // src/components/chat/ChatTurn.tsx
12493
- var React63 = __toESM(require("react"), 1);
12548
+ var React64 = __toESM(require("react"), 1);
12494
12549
  var import_jsx_runtime94 = require("react/jsx-runtime");
12495
12550
  function JsonView({ value }) {
12496
12551
  let text;
@@ -12527,7 +12582,7 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
12527
12582
  ] });
12528
12583
  }
12529
12584
  function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
12530
- const [open2, setOpen] = React63.useState(defaultOpen);
12585
+ const [open2, setOpen] = React64.useState(defaultOpen);
12531
12586
  if (!text) return null;
12532
12587
  return /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: "fdc-think" + (open2 ? " is-open" : ""), children: [
12533
12588
  /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
@@ -12544,7 +12599,7 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
12544
12599
  ] });
12545
12600
  }
12546
12601
  function Citations({ items = [], onOpen }) {
12547
- const [open2, setOpen] = React63.useState(false);
12602
+ const [open2, setOpen] = React64.useState(false);
12548
12603
  if (!items.length) return null;
12549
12604
  return /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: "fdc-cites", children: [
12550
12605
  /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
@@ -12570,7 +12625,7 @@ function clampText(text, max) {
12570
12625
  return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
12571
12626
  }
12572
12627
  function MessageBody({ message: m, ctx }) {
12573
- const [expanded, setExpanded] = React63.useState(false);
12628
+ const [expanded, setExpanded] = React64.useState(false);
12574
12629
  const isUser = m.role === "user";
12575
12630
  const raw = m.text || "";
12576
12631
  const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
@@ -12650,7 +12705,7 @@ function RunActions({ group, ctx }) {
12650
12705
  ] }),
12651
12706
  isAssistant && ctx.onRetry ? /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
12652
12707
  group.role === "user" && ctx.onEdit ? /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
12653
- isAssistant && ctx.onFeedback ? /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)(React63.Fragment, { children: [
12708
+ isAssistant && ctx.onFeedback ? /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)(React64.Fragment, { children: [
12654
12709
  /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("button", { type: "button", className: "fdc-act" + (fb === "up" ? " is-on" : ""), onClick: () => ctx.onFeedback(last.id, "up"), "aria-pressed": fb === "up", "aria-label": "Good response", children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
12655
12710
  /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("button", { type: "button", className: "fdc-act" + (fb === "down" ? " is-on" : ""), onClick: () => ctx.onFeedback(last.id, "down"), "aria-pressed": fb === "down", "aria-label": "Bad response", children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
12656
12711
  ] }) : null,
@@ -12745,10 +12800,10 @@ function ChatTranscript({
12745
12800
  renderEmpty,
12746
12801
  className = ""
12747
12802
  }) {
12748
- const scroller = React64.useRef(null);
12749
- const stick = React64.useRef(true);
12750
- const [pill, setPill] = React64.useState(0);
12751
- const seen = React64.useRef(0);
12803
+ const scroller = React65.useRef(null);
12804
+ const stick = React65.useRef(true);
12805
+ const [pill, setPill] = React65.useState(0);
12806
+ const seen = React65.useRef(0);
12752
12807
  const toBottom = (smooth) => {
12753
12808
  const el = scroller.current;
12754
12809
  if (!el) return;
@@ -12767,7 +12822,7 @@ function ChatTranscript({
12767
12822
  seen.current = messages.length;
12768
12823
  }
12769
12824
  };
12770
- React64.useLayoutEffect(() => {
12825
+ React65.useLayoutEffect(() => {
12771
12826
  const el = scroller.current;
12772
12827
  if (!el) return;
12773
12828
  if (stick.current) {
@@ -12775,7 +12830,7 @@ function ChatTranscript({
12775
12830
  seen.current = messages.length;
12776
12831
  } else setPill(Math.max(0, messages.length - seen.current));
12777
12832
  }, [messages]);
12778
- React64.useEffect(() => {
12833
+ React65.useEffect(() => {
12779
12834
  const el = scroller.current;
12780
12835
  const inner = el && el.firstChild;
12781
12836
  if (!el || !inner || typeof ResizeObserver === "undefined") return;
@@ -12785,7 +12840,7 @@ function ChatTranscript({
12785
12840
  ro.observe(inner);
12786
12841
  return () => ro.disconnect();
12787
12842
  }, []);
12788
- const groups = React64.useMemo(() => groupMessages(messages), [messages]);
12843
+ const groups = React65.useMemo(() => groupMessages(messages), [messages]);
12789
12844
  const empty = !messages.length && status === "ready";
12790
12845
  return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
12791
12846
  /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
@@ -12809,7 +12864,7 @@ function ChatTranscript({
12809
12864
  const prev = groups[i - 1];
12810
12865
  const k = dayKey(g.messages[0].timestamp);
12811
12866
  const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
12812
- return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(React64.Fragment, { children: [
12867
+ return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(React65.Fragment, { children: [
12813
12868
  showDay ? /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { className: "fdc-day", children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { children: dayLabel(k) }) }) : null,
12814
12869
  /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(ChatTurn, { group: g, ctx })
12815
12870
  ] }, g.key || i);
@@ -12826,7 +12881,7 @@ function ChatTranscript({
12826
12881
  var TranscriptKit = { groupMessages };
12827
12882
 
12828
12883
  // src/components/chat/ChatComposer.tsx
12829
- var React65 = __toESM(require("react"), 1);
12884
+ var React66 = __toESM(require("react"), 1);
12830
12885
  var import_jsx_runtime96 = require("react/jsx-runtime");
12831
12886
  function ChatComposer({
12832
12887
  onSubmit,
@@ -12854,17 +12909,17 @@ function ChatComposer({
12854
12909
  onReject,
12855
12910
  onOpenAttachment
12856
12911
  }) {
12857
- const [text, setText] = React65.useState(draft || "");
12858
- const [trigger, setTrigger] = React65.useState(null);
12859
- const [mentionItems, setMentionItems] = React65.useState([]);
12860
- const [listening, setListening] = React65.useState(false);
12861
- const [notice, setNotice] = React65.useState(null);
12862
- const editor = React65.useRef(null);
12863
- const wrap = React65.useRef(null);
12864
- const stopVoice = React65.useRef(null);
12912
+ const [text, setText] = React66.useState(draft || "");
12913
+ const [trigger, setTrigger] = React66.useState(null);
12914
+ const [mentionItems, setMentionItems] = React66.useState([]);
12915
+ const [listening, setListening] = React66.useState(false);
12916
+ const [notice, setNotice] = React66.useState(null);
12917
+ const editor = React66.useRef(null);
12918
+ const wrap = React66.useRef(null);
12919
+ const stopVoice = React66.useRef(null);
12865
12920
  const staged = useStagedFiles(fileUploadHandler, { onError: () => {
12866
12921
  } });
12867
- React65.useEffect(() => {
12922
+ React66.useEffect(() => {
12868
12923
  if (draft != null && draft !== text) setText(draft);
12869
12924
  }, [draft]);
12870
12925
  const change = (v) => {
@@ -12900,7 +12955,7 @@ function ChatComposer({
12900
12955
  e.preventDefault();
12901
12956
  staged.add(found.files);
12902
12957
  };
12903
- React65.useEffect(() => {
12958
+ React66.useEffect(() => {
12904
12959
  if (!trigger || trigger.type !== "mention" || !mentionSources) {
12905
12960
  setMentionItems([]);
12906
12961
  return;
@@ -12918,7 +12973,7 @@ function ChatComposer({
12918
12973
  const q = (trigger.query || "").toLowerCase();
12919
12974
  setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
12920
12975
  }, [trigger, mentionSources]);
12921
- const slashItems = React65.useMemo(() => {
12976
+ const slashItems = React66.useMemo(() => {
12922
12977
  if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
12923
12978
  const q = (trigger.query || "").toLowerCase();
12924
12979
  return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
@@ -13088,12 +13143,12 @@ function ChatComposer({
13088
13143
  }
13089
13144
 
13090
13145
  // src/components/chat/ChatSessionBar.tsx
13091
- var React66 = __toESM(require("react"), 1);
13146
+ var React67 = __toESM(require("react"), 1);
13092
13147
  var import_jsx_runtime97 = require("react/jsx-runtime");
13093
13148
  var compact2 = meterFormats.compact;
13094
13149
  function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
13095
- const [open2, setOpen] = React66.useState(false);
13096
- const anchor = React66.useRef(null);
13150
+ const [open2, setOpen] = React67.useState(false);
13151
+ const anchor = React67.useRef(null);
13097
13152
  const stats = sessionStats || null;
13098
13153
  const cu = contextUsage || null;
13099
13154
  const limits = usageLimits || null;
@@ -13108,7 +13163,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
13108
13163
  if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
13109
13164
  if (cu) bits.push(pct + "% context");
13110
13165
  const expandable = !!(cu || limits);
13111
- return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(React66.Fragment, { children: [
13166
+ return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(React67.Fragment, { children: [
13112
13167
  /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "fdc-bar", children: [
13113
13168
  /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(
13114
13169
  "button",
@@ -13249,7 +13304,7 @@ function ModelControls({
13249
13304
  ] })
13250
13305
  });
13251
13306
  }
13252
- return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(React66.Fragment, { children: [
13307
+ return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(React67.Fragment, { children: [
13253
13308
  /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
13254
13309
  MenuButton,
13255
13310
  {
@@ -13366,11 +13421,11 @@ function AgentChatPanel({
13366
13421
  onFeedback,
13367
13422
  onEditMessage
13368
13423
  }) {
13369
- const [panelWidth, setPanelWidth] = React67.useState(width);
13370
- const [applied, setApplied] = React67.useState({});
13371
- const [draft, setDraft] = React67.useState("");
13372
- const dragging = React67.useRef(null);
13373
- React67.useEffect(() => setPanelWidth(width), [width]);
13424
+ const [panelWidth, setPanelWidth] = React68.useState(width);
13425
+ const [applied, setApplied] = React68.useState({});
13426
+ const [draft, setDraft] = React68.useState("");
13427
+ const dragging = React68.useRef(null);
13428
+ React68.useEffect(() => setPanelWidth(width), [width]);
13374
13429
  const engine = useChatEngine({
13375
13430
  contextType,
13376
13431
  contextId,
@@ -13574,7 +13629,7 @@ function AgentChatPanel({
13574
13629
  }
13575
13630
 
13576
13631
  // src/components/files/FileViewer.tsx
13577
- var React68 = __toESM(require("react"), 1);
13632
+ var React69 = __toESM(require("react"), 1);
13578
13633
  var import_jsx_runtime99 = require("react/jsx-runtime");
13579
13634
  function previewKindOf(file) {
13580
13635
  const mime = (file.mime || "").toLowerCase();
@@ -13631,13 +13686,13 @@ function parseDelimited(text, delimiter) {
13631
13686
  return rows;
13632
13687
  }
13633
13688
  function usePreview(file, kind, resolveUrl) {
13634
- const [state, setState] = React68.useState({ status: "loading" });
13635
- const [attempt, setAttempt] = React68.useState(0);
13636
- const resolveRef = React68.useRef(resolveUrl);
13637
- React68.useEffect(() => {
13689
+ const [state, setState] = React69.useState({ status: "loading" });
13690
+ const [attempt, setAttempt] = React69.useState(0);
13691
+ const resolveRef = React69.useRef(resolveUrl);
13692
+ React69.useEffect(() => {
13638
13693
  resolveRef.current = resolveUrl;
13639
13694
  }, [resolveUrl]);
13640
- React68.useEffect(() => {
13695
+ React69.useEffect(() => {
13641
13696
  if (kind === "none") {
13642
13697
  setState({ status: "ready" });
13643
13698
  return;
@@ -13667,7 +13722,7 @@ function usePreview(file, kind, resolveUrl) {
13667
13722
  if (ac) ac.abort();
13668
13723
  };
13669
13724
  }, [file.id, kind, attempt]);
13670
- return { ...state, retry: React68.useCallback(() => setAttempt((a) => a + 1), []) };
13725
+ return { ...state, retry: React69.useCallback(() => setAttempt((a) => a + 1), []) };
13671
13726
  }
13672
13727
  function PreviewBody({ file, kind, state }) {
13673
13728
  if (kind === "image") return /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
@@ -13712,13 +13767,13 @@ function PreviewBody({ file, kind, state }) {
13712
13767
  ] });
13713
13768
  }
13714
13769
  function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", onClose, actions, className = "" }) {
13715
- const kind = React68.useMemo(() => previewKindOf(file), [file]);
13770
+ const kind = React69.useMemo(() => previewKindOf(file), [file]);
13716
13771
  const preview = usePreview(file, kind, resolveUrl);
13717
- const [tab, setTab] = React68.useState("preview");
13718
- const [downloading, setDownloading] = React68.useState(false);
13719
- const [downloadError, setDownloadError] = React68.useState(null);
13772
+ const [tab, setTab] = React69.useState("preview");
13773
+ const [downloading, setDownloading] = React69.useState(false);
13774
+ const [downloadError, setDownloadError] = React69.useState(null);
13720
13775
  const hasSide = sidePanel != null;
13721
- React68.useEffect(() => {
13776
+ React69.useEffect(() => {
13722
13777
  setTab("preview");
13723
13778
  }, [file.id]);
13724
13779
  const download = () => {
@@ -13785,7 +13840,7 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
13785
13840
  }
13786
13841
 
13787
13842
  // src/components/files/FileBrowser.tsx
13788
- var React69 = __toESM(require("react"), 1);
13843
+ var React70 = __toESM(require("react"), 1);
13789
13844
  var import_jsx_runtime100 = require("react/jsx-runtime");
13790
13845
  function childrenOf(folders, parentId) {
13791
13846
  return folders.filter((f) => f.parentId === parentId).sort((a, b) => a.name.localeCompare(b.name));
@@ -13895,8 +13950,8 @@ function FolderPickerMenu({
13895
13950
  ] });
13896
13951
  }
13897
13952
  function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropPayload, actions, className = "" }) {
13898
- const [over, setOver] = React69.useState(false);
13899
- const dragCounter = React69.useRef(0);
13953
+ const [over, setOver] = React70.useState(false);
13954
+ const dragCounter = React70.useRef(0);
13900
13955
  const dropHandlers = isDropTarget ? {
13901
13956
  onDragEnter: (e) => {
13902
13957
  if (!hasInternalPayload(e)) return;
@@ -13944,8 +13999,8 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
13944
13999
  }
13945
14000
  function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveInto, canMove }) {
13946
14001
  const kids = childrenOf(folders, folder.id);
13947
- const [expanded, setExpanded] = React69.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
13948
- React69.useEffect(() => {
14002
+ const [expanded, setExpanded] = React70.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
14003
+ React70.useEffect(() => {
13949
14004
  if (currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId)) setExpanded(true);
13950
14005
  }, [currentFolderId, folder.id, folders]);
13951
14006
  const isCurrent = folder.id === currentFolderId;
@@ -14011,15 +14066,15 @@ function FileBrowser({
14011
14066
  const canUpload = perm.canUpload !== false && !!onUpload;
14012
14067
  const canRemoveFile = perm.canRemoveFile !== false && !!onRemoveFile;
14013
14068
  const canDeleteFolder = perm.canDeleteFolder !== false && !!onDeleteFolder;
14014
- const [createOpen, setCreateOpen] = React69.useState(false);
14015
- const [createName, setCreateName] = React69.useState("");
14016
- const [renameTarget, setRenameTarget] = React69.useState(null);
14017
- const [renameValue, setRenameValue] = React69.useState("");
14018
- const [deleteTarget, setDeleteTarget] = React69.useState(null);
14019
- const uploadInputRef = React69.useRef(null);
14020
- const crumbFolders = React69.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
14021
- const subfolders = React69.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
14022
- const currentFiles = React69.useMemo(
14069
+ const [createOpen, setCreateOpen] = React70.useState(false);
14070
+ const [createName, setCreateName] = React70.useState("");
14071
+ const [renameTarget, setRenameTarget] = React70.useState(null);
14072
+ const [renameValue, setRenameValue] = React70.useState("");
14073
+ const [deleteTarget, setDeleteTarget] = React70.useState(null);
14074
+ const uploadInputRef = React70.useRef(null);
14075
+ const crumbFolders = React70.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
14076
+ const subfolders = React70.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
14077
+ const currentFiles = React70.useMemo(
14023
14078
  () => files.filter((f) => f.folderId === currentFolderId).sort((a, b) => a.name.localeCompare(b.name)),
14024
14079
  [files, currentFolderId]
14025
14080
  );
@@ -14251,8 +14306,8 @@ function BreadcrumbCrumb({
14251
14306
  isDropTarget,
14252
14307
  onDropPayload
14253
14308
  }) {
14254
- const [over, setOver] = React69.useState(false);
14255
- const dragCounter = React69.useRef(0);
14309
+ const [over, setOver] = React70.useState(false);
14310
+ const dragCounter = React70.useRef(0);
14256
14311
  const dropHandlers = isDropTarget ? {
14257
14312
  onDragEnter: (e) => {
14258
14313
  if (!hasInternalPayload(e)) return;
@@ -14281,7 +14336,7 @@ function BreadcrumbCrumb({
14281
14336
  }
14282
14337
 
14283
14338
  // src/kits/query.ts
14284
- var React70 = __toESM(require("react"), 1);
14339
+ var React71 = __toESM(require("react"), 1);
14285
14340
  var isMultiSelectShaped = (v) => !!v && typeof v === "object" && Array.isArray(v.values);
14286
14341
  var isRangeShaped = (v) => !!v && typeof v === "object" && ("min" in v || "max" in v);
14287
14342
  var isDateShaped = (v) => !!v && typeof v === "object" && "kind" in v;
@@ -14336,22 +14391,22 @@ function compare(a, b, dir) {
14336
14391
  var API = null;
14337
14392
  var PREFS = null;
14338
14393
  function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
14339
- const [query, setQuery] = React70.useState(() => {
14394
+ const [query, setQuery] = React71.useState(() => {
14340
14395
  const store = PREFS || window.PlannerPrefs;
14341
14396
  const saved = prefsKey && store ? store.getTable(prefsKey) : {};
14342
14397
  return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
14343
14398
  });
14344
- const savePref = React70.useCallback((patch2) => {
14399
+ const savePref = React71.useCallback((patch2) => {
14345
14400
  const store = PREFS || window.PlannerPrefs;
14346
14401
  if (prefsKey && store) store.setTable(prefsKey, patch2);
14347
14402
  }, [prefsKey]);
14348
- const [res, setRes] = React70.useState(null);
14349
- const [loading, setLoading] = React70.useState(true);
14350
- const seq2 = React70.useRef(0);
14403
+ const [res, setRes] = React71.useState(null);
14404
+ const [loading, setLoading] = React71.useState(true);
14405
+ const seq2 = React71.useRef(0);
14351
14406
  const depKey = (deps || []).join("|");
14352
14407
  const paramKey = JSON.stringify(params || {});
14353
14408
  const queryKey = JSON.stringify(query);
14354
- React70.useEffect(() => {
14409
+ React71.useEffect(() => {
14355
14410
  const id = ++seq2.current;
14356
14411
  setLoading(true);
14357
14412
  const t = setTimeout(() => {
@@ -14670,12 +14725,12 @@ function createVersionStore(initialState, options) {
14670
14725
  }
14671
14726
 
14672
14727
  // src/kits/documentTitle.ts
14673
- var React71 = __toESM(require("react"), 1);
14728
+ var React72 = __toESM(require("react"), 1);
14674
14729
  function formatDocumentTitle(routeTitle, appName) {
14675
14730
  return [routeTitle, appName, "Flytedesk"].filter((part) => !!part && part.length > 0).join(" \xB7 ");
14676
14731
  }
14677
14732
  function useDocumentTitle(routeTitle, appName) {
14678
- React71.useEffect(() => {
14733
+ React72.useEffect(() => {
14679
14734
  if (typeof document === "undefined") return;
14680
14735
  document.title = formatDocumentTitle(routeTitle, appName);
14681
14736
  }, [routeTitle, appName]);
@@ -14722,6 +14777,7 @@ function useDocumentTitle(routeTitle, appName) {
14722
14777
  CodeEditor,
14723
14778
  Collapsible,
14724
14779
  ComingSoon,
14780
+ CornerStackPortal,
14725
14781
  CsiBadge,
14726
14782
  CsiHero,
14727
14783
  CsiMeter,
@@ -14890,6 +14946,7 @@ function useDocumentTitle(routeTitle, appName) {
14890
14946
  useAppearancePrefs,
14891
14947
  useChatEngine,
14892
14948
  useCopyToClipboard,
14949
+ useCornerStackSlot,
14893
14950
  useDocumentTitle,
14894
14951
  useFeatureStatus,
14895
14952
  useLayerZIndex,