@flytedan/flytebot-design-system 0.51.2 → 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.js CHANGED
@@ -1123,7 +1123,60 @@ function LoadingRegion({
1123
1123
  }
1124
1124
 
1125
1125
  // src/components/loading/JobTray.tsx
1126
+ import * as React10 from "react";
1127
+
1128
+ // src/kits/cornerStack.tsx
1126
1129
  import * as React9 from "react";
1130
+ import { createPortal as createPortal4 } from "react-dom";
1131
+ var SLOTS = ["jobs", "toasts"];
1132
+ var references = /* @__PURE__ */ new Map();
1133
+ var host = null;
1134
+ var slotElements = /* @__PURE__ */ new Map();
1135
+ function createHost() {
1136
+ const stack = document.createElement("div");
1137
+ stack.className = "fd-corner-stack";
1138
+ stack.style.zIndex = String(OVERLAY_CEILING);
1139
+ for (const slot of SLOTS) {
1140
+ const element = document.createElement("div");
1141
+ element.className = "fd-corner-stack-slot";
1142
+ element.dataset.cornerStackSlot = slot;
1143
+ stack.appendChild(element);
1144
+ slotElements.set(slot, element);
1145
+ }
1146
+ document.body.appendChild(stack);
1147
+ return stack;
1148
+ }
1149
+ function acquire(slot) {
1150
+ host ??= createHost();
1151
+ references.set(slot, (references.get(slot) ?? 0) + 1);
1152
+ return slotElements.get(slot);
1153
+ }
1154
+ function release(slot) {
1155
+ const remaining = (references.get(slot) ?? 1) - 1;
1156
+ if (remaining > 0) references.set(slot, remaining);
1157
+ else references.delete(slot);
1158
+ if (references.size === 0 && host) {
1159
+ host.remove();
1160
+ host = null;
1161
+ slotElements.clear();
1162
+ }
1163
+ }
1164
+ var useSlotEffect = typeof document === "undefined" ? React9.useEffect : React9.useLayoutEffect;
1165
+ function useCornerStackSlot(slot) {
1166
+ const [element, setElement] = React9.useState(null);
1167
+ useSlotEffect(() => {
1168
+ setElement(acquire(slot));
1169
+ return () => {
1170
+ release(slot);
1171
+ setElement(null);
1172
+ };
1173
+ }, [slot]);
1174
+ return element;
1175
+ }
1176
+ function CornerStackPortal({ slot, children }) {
1177
+ const element = useCornerStackSlot(slot);
1178
+ return element ? createPortal4(children, element) : null;
1179
+ }
1127
1180
 
1128
1181
  // src/components/loading/ProgressBar.tsx
1129
1182
  import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
@@ -1167,9 +1220,9 @@ function announcementFor(job) {
1167
1220
  return title + ": in progress";
1168
1221
  }
1169
1222
  function JobTray({ jobs: jobs2, onDismiss, className = "" }) {
1170
- const [announcement, setAnnouncement] = React9.useState("");
1171
- const prevStatuses = React9.useRef({});
1172
- React9.useEffect(() => {
1223
+ const [announcement, setAnnouncement] = React10.useState("");
1224
+ const prevStatuses = React10.useRef({});
1225
+ React10.useEffect(() => {
1173
1226
  let next = "";
1174
1227
  for (const job of jobs2) {
1175
1228
  if (prevStatuses.current[job.id] !== job.status) {
@@ -1182,10 +1235,10 @@ function JobTray({ jobs: jobs2, onDismiss, className = "" }) {
1182
1235
  if (next) setAnnouncement(next);
1183
1236
  }, [jobs2]);
1184
1237
  if (jobs2.length === 0) return null;
1185
- return /* @__PURE__ */ jsxs11("div", { className: ["fd-job-tray", className].filter(Boolean).join(" "), children: [
1238
+ return /* @__PURE__ */ jsx15(CornerStackPortal, { slot: "jobs", children: /* @__PURE__ */ jsxs11("div", { className: ["fd-job-tray", className].filter(Boolean).join(" "), children: [
1186
1239
  /* @__PURE__ */ jsx15("span", { className: "fd-sr", role: "status", "aria-live": "polite", children: announcement }),
1187
1240
  jobs2.map((job) => /* @__PURE__ */ jsx15(JobCard, { job, onDismiss }, job.id))
1188
- ] });
1241
+ ] }) });
1189
1242
  }
1190
1243
  function JobCard({ job, onDismiss }) {
1191
1244
  const title = textOf(job.title) || "Job";
@@ -1220,7 +1273,7 @@ function JobCard({ job, onDismiss }) {
1220
1273
  }
1221
1274
 
1222
1275
  // src/components/loading/PhasedProgress.tsx
1223
- import * as React10 from "react";
1276
+ import * as React11 from "react";
1224
1277
  import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
1225
1278
  var ICON = {
1226
1279
  pending: "ph-circle",
@@ -1233,9 +1286,9 @@ function textOf2(node) {
1233
1286
  return "";
1234
1287
  }
1235
1288
  function PhasedProgress({ phases, summary, className = "" }) {
1236
- const [announcement, setAnnouncement] = React10.useState("");
1237
- const prevStatuses = React10.useRef({});
1238
- React10.useEffect(() => {
1289
+ const [announcement, setAnnouncement] = React11.useState("");
1290
+ const prevStatuses = React11.useRef({});
1291
+ React11.useEffect(() => {
1239
1292
  let next = "";
1240
1293
  for (const phase of phases) {
1241
1294
  if (prevStatuses.current[phase.id] !== phase.status) {
@@ -1305,12 +1358,12 @@ function Spinner({ size = "md", label = "Loading", className = "", style, ...res
1305
1358
  }
1306
1359
 
1307
1360
  // src/components/navigation/SidebarNav.tsx
1308
- import * as React11 from "react";
1361
+ import * as React12 from "react";
1309
1362
  import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
1310
1363
  function Tip({ label, children }) {
1311
1364
  return /* @__PURE__ */ jsx19("span", { title: label, style: { display: "inline-flex", flex: "none" }, children });
1312
1365
  }
1313
- var SidebarNav = React11.forwardRef(function SidebarNav2({ brand, groups = [], current: current2, onNavigate, footer, open: open2 = false, className = "", ...rest }, ref) {
1366
+ var SidebarNav = React12.forwardRef(function SidebarNav2({ brand, groups = [], current: current2, onNavigate, footer, open: open2 = false, className = "", ...rest }, ref) {
1314
1367
  return /* @__PURE__ */ jsxs13(
1315
1368
  "nav",
1316
1369
  {
@@ -1349,13 +1402,13 @@ var SidebarNav = React11.forwardRef(function SidebarNav2({ brand, groups = [], c
1349
1402
  });
1350
1403
 
1351
1404
  // src/components/navigation/Topbar.tsx
1352
- import * as React12 from "react";
1405
+ import * as React13 from "react";
1353
1406
  import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
1354
1407
  function useIsNarrow(breakpoint) {
1355
- const [narrow, setNarrow] = React12.useState(
1408
+ const [narrow, setNarrow] = React13.useState(
1356
1409
  () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
1357
1410
  );
1358
- React12.useEffect(() => {
1411
+ React13.useEffect(() => {
1359
1412
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1360
1413
  const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
1361
1414
  const apply = () => setNarrow(mq.matches);
@@ -1376,11 +1429,11 @@ function Topbar({
1376
1429
  ...rest
1377
1430
  }) {
1378
1431
  const narrow = useIsNarrow(overflowBreakpoint);
1379
- const [moreOpen, setMoreOpen] = React12.useState(false);
1380
- const moreRef = React12.useRef(null);
1432
+ const [moreOpen, setMoreOpen] = React13.useState(false);
1433
+ const moreRef = React13.useRef(null);
1381
1434
  return /* @__PURE__ */ jsxs14("header", { className: ["fd-topbar", narrow ? "is-narrow" : "", className].filter(Boolean).join(" "), ...rest, children: [
1382
1435
  onMenu ? /* @__PURE__ */ jsx20("button", { type: "button", className: "fd-btn-icon", "aria-label": "Menu", onClick: onMenu, children: /* @__PURE__ */ jsx20("i", { className: "ph ph-list" }) }) : null,
1383
- /* @__PURE__ */ jsx20("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ jsxs14(React12.Fragment, { children: [
1436
+ /* @__PURE__ */ jsx20("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ jsxs14(React13.Fragment, { children: [
1384
1437
  i > 0 ? /* @__PURE__ */ jsx20("i", { className: "ph ph-caret-right", style: { fontSize: 11, opacity: 0.6 }, "aria-hidden": "true" }) : null,
1385
1438
  i === crumbs.length - 1 ? (
1386
1439
  // MP-141: the current crumb mixes a static route label with (usually) a
@@ -1433,25 +1486,25 @@ function Topbar({
1433
1486
  }
1434
1487
 
1435
1488
  // src/kits/useResponsiveRail.ts
1436
- import * as React13 from "react";
1489
+ import * as React14 from "react";
1437
1490
  function matchesBreakpoint(breakpoint) {
1438
1491
  return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches;
1439
1492
  }
1440
1493
  function useResponsiveRail(options = {}) {
1441
1494
  const { breakpoint = 1024, initialOpen = true, onPersist } = options;
1442
- const navRef = React13.useRef(null);
1443
- const [overlay, setOverlay] = React13.useState(() => matchesBreakpoint(breakpoint));
1444
- const [open2, setOpenRaw] = React13.useState(() => matchesBreakpoint(breakpoint) ? false : initialOpen);
1445
- const setOpen = React13.useCallback(
1495
+ const navRef = React14.useRef(null);
1496
+ const [overlay, setOverlay] = React14.useState(() => matchesBreakpoint(breakpoint));
1497
+ const [open2, setOpenRaw] = React14.useState(() => matchesBreakpoint(breakpoint) ? false : initialOpen);
1498
+ const setOpen = React14.useCallback(
1446
1499
  (value) => {
1447
1500
  setOpenRaw(value);
1448
1501
  if (!matchesBreakpoint(breakpoint)) onPersist?.(value);
1449
1502
  },
1450
1503
  [breakpoint, onPersist]
1451
1504
  );
1452
- const toggle = React13.useCallback(() => setOpen(!open2), [open2, setOpen]);
1453
- const close2 = React13.useCallback(() => setOpenRaw(false), []);
1454
- React13.useEffect(() => {
1505
+ const toggle = React14.useCallback(() => setOpen(!open2), [open2, setOpen]);
1506
+ const close2 = React14.useCallback(() => setOpenRaw(false), []);
1507
+ React14.useEffect(() => {
1455
1508
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1456
1509
  const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
1457
1510
  const handler = (e) => {
@@ -1462,7 +1515,7 @@ function useResponsiveRail(options = {}) {
1462
1515
  return () => mq.removeEventListener("change", handler);
1463
1516
  }, [breakpoint]);
1464
1517
  const layer = useStackedLayer({ active: overlay && open2, containerRef: navRef, trap: true, onEscape: close2 });
1465
- React13.useEffect(() => {
1518
+ React14.useEffect(() => {
1466
1519
  if (!overlay || !open2) return;
1467
1520
  const previousOverflow = document.body.style.overflow;
1468
1521
  document.body.style.overflow = "hidden";
@@ -1820,15 +1873,15 @@ function Toast({ title, children, tone = "success", onUndo, onDismiss, className
1820
1873
  }
1821
1874
 
1822
1875
  // src/components/feedback/ToastProvider.tsx
1823
- import * as React14 from "react";
1876
+ import * as React15 from "react";
1824
1877
  import { jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
1825
1878
  var DEFAULT_TOAST_DURATION_MS = 5e3;
1826
- var ToastContext = React14.createContext(null);
1879
+ var ToastContext = React15.createContext(null);
1827
1880
  function ToastProvider({ children }) {
1828
- const [items, setItems] = React14.useState([]);
1829
- const timers = React14.useRef(/* @__PURE__ */ new Map());
1830
- const nextId = React14.useRef(1);
1831
- const dismiss = React14.useCallback((id) => {
1881
+ const [items, setItems] = React15.useState([]);
1882
+ const timers = React15.useRef(/* @__PURE__ */ new Map());
1883
+ const nextId = React15.useRef(1);
1884
+ const dismiss = React15.useCallback((id) => {
1832
1885
  setItems((current2) => current2.filter((item) => item.id !== id));
1833
1886
  const timer = timers.current.get(id);
1834
1887
  if (timer !== void 0) {
@@ -1836,7 +1889,7 @@ function ToastProvider({ children }) {
1836
1889
  timers.current.delete(id);
1837
1890
  }
1838
1891
  }, []);
1839
- const show = React14.useCallback(
1892
+ const show = React15.useCallback(
1840
1893
  (title, options = {}) => {
1841
1894
  const { tone = "success", duration = DEFAULT_TOAST_DURATION_MS } = options;
1842
1895
  const id = nextId.current++;
@@ -1845,38 +1898,38 @@ function ToastProvider({ children }) {
1845
1898
  },
1846
1899
  [dismiss]
1847
1900
  );
1848
- React14.useEffect(() => {
1901
+ React15.useEffect(() => {
1849
1902
  const pending = timers.current;
1850
1903
  return () => {
1851
1904
  pending.forEach(clearTimeout);
1852
1905
  pending.clear();
1853
1906
  };
1854
1907
  }, []);
1855
- const api = React14.useMemo(() => ({ show }), [show]);
1908
+ const api = React15.useMemo(() => ({ show }), [show]);
1856
1909
  return /* @__PURE__ */ jsxs25(ToastContext.Provider, { value: api, children: [
1857
1910
  children,
1858
- /* @__PURE__ */ jsx32("div", { className: "fd-toast-region", "aria-live": "polite", style: { zIndex: OVERLAY_CEILING }, children: items.map((item) => /* @__PURE__ */ jsx32(Toast, { title: item.title, tone: item.tone, onDismiss: () => dismiss(item.id) }, item.id)) })
1911
+ /* @__PURE__ */ jsx32(CornerStackPortal, { slot: "toasts", children: /* @__PURE__ */ jsx32("div", { className: "fd-toast-region", "aria-live": "polite", children: items.map((item) => /* @__PURE__ */ jsx32(Toast, { title: item.title, tone: item.tone, onDismiss: () => dismiss(item.id) }, item.id)) }) })
1859
1912
  ] });
1860
1913
  }
1861
1914
  function useToast() {
1862
- const api = React14.useContext(ToastContext);
1915
+ const api = React15.useContext(ToastContext);
1863
1916
  if (!api) throw new Error("useToast must be used inside a <ToastProvider>");
1864
1917
  return api;
1865
1918
  }
1866
1919
 
1867
1920
  // src/components/feedback/Tooltip.tsx
1868
- import * as React15 from "react";
1921
+ import * as React16 from "react";
1869
1922
  import { jsx as jsx33, jsxs as jsxs26 } from "react/jsx-runtime";
1870
1923
  var CLOSE_DELAY_MS = 120;
1871
1924
  function Tooltip({ label, placement = "top", children, className = "" }) {
1872
- const anchorRef = React15.useRef(null);
1873
- const bubbleRef = React15.useRef(null);
1874
- const [reason, setReason] = React15.useState(null);
1875
- const closeTimer = React15.useRef(null);
1876
- const id = React15.useId();
1925
+ const anchorRef = React16.useRef(null);
1926
+ const bubbleRef = React16.useRef(null);
1927
+ const [reason, setReason] = React16.useState(null);
1928
+ const closeTimer = React16.useRef(null);
1929
+ const id = React16.useId();
1877
1930
  const descId = id + "-desc";
1878
1931
  const open2 = reason != null;
1879
- const cancelClose = React15.useCallback(() => {
1932
+ const cancelClose = React16.useCallback(() => {
1880
1933
  if (closeTimer.current) {
1881
1934
  clearTimeout(closeTimer.current);
1882
1935
  closeTimer.current = null;
@@ -1886,7 +1939,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1886
1939
  cancelClose();
1887
1940
  setReason(why);
1888
1941
  };
1889
- const hide = React15.useCallback(() => {
1942
+ const hide = React16.useCallback(() => {
1890
1943
  cancelClose();
1891
1944
  setReason(null);
1892
1945
  }, [cancelClose]);
@@ -1901,7 +1954,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1901
1954
  setReason((r) => r === "hover" ? null : r);
1902
1955
  }, CLOSE_DELAY_MS);
1903
1956
  };
1904
- React15.useEffect(() => cancelClose, [cancelClose]);
1957
+ React16.useEffect(() => cancelClose, [cancelClose]);
1905
1958
  const pos = usePopoverPosition(open2, anchorRef, {
1906
1959
  placement: placement === "bottom" ? "bottom-center" : "top-center",
1907
1960
  offset: 8,
@@ -1912,7 +1965,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1912
1965
  });
1913
1966
  const layer = useStackedLayer({ active: open2, containerRef: bubbleRef, onEscape: hide, returnFocus: false });
1914
1967
  const zIndex = useLayerZIndex(layer);
1915
- React15.useEffect(() => {
1968
+ React16.useEffect(() => {
1916
1969
  if (!open2) return;
1917
1970
  const away = (e) => {
1918
1971
  const t = e.target;
@@ -1933,7 +1986,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1933
1986
  }
1934
1987
  if (keyboard) show("focus");
1935
1988
  };
1936
- const described = React15.isValidElement(children) ? React15.cloneElement(children, {
1989
+ const described = React16.isValidElement(children) ? React16.cloneElement(children, {
1937
1990
  "aria-describedby": [children.props["aria-describedby"], descId].filter(Boolean).join(" ")
1938
1991
  }) : children;
1939
1992
  return /* @__PURE__ */ jsxs26(
@@ -1941,7 +1994,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1941
1994
  {
1942
1995
  ref: anchorRef,
1943
1996
  className: "fd-tooltip-anchor",
1944
- "aria-describedby": React15.isValidElement(children) ? void 0 : descId,
1997
+ "aria-describedby": React16.isValidElement(children) ? void 0 : descId,
1945
1998
  onPointerEnter: (e) => {
1946
1999
  if (isMouse(e)) hover();
1947
2000
  },
@@ -1985,16 +2038,16 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1985
2038
  }
1986
2039
 
1987
2040
  // src/components/data/AnimNum.tsx
1988
- import * as React16 from "react";
2041
+ import * as React17 from "react";
1989
2042
  import { Fragment as Fragment6, jsx as jsx34 } from "react/jsx-runtime";
1990
2043
  function shouldSkipEasing() {
1991
2044
  if (typeof document !== "undefined" && document.hidden) return true;
1992
2045
  return window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
1993
2046
  }
1994
2047
  function AnimNum({ value, format, duration = 550 }) {
1995
- const [display, setDisplay] = React16.useState(value);
1996
- const prev = React16.useRef(value);
1997
- React16.useEffect(() => {
2048
+ const [display, setDisplay] = React17.useState(value);
2049
+ const prev = React17.useRef(value);
2050
+ React17.useEffect(() => {
1998
2051
  const from = prev.current;
1999
2052
  const to = value;
2000
2053
  prev.current = to;
@@ -2022,14 +2075,14 @@ function AnimNum({ value, format, duration = 550 }) {
2022
2075
  }
2023
2076
 
2024
2077
  // src/components/data/TrendChart.tsx
2025
- import * as React19 from "react";
2078
+ import * as React20 from "react";
2026
2079
 
2027
2080
  // src/components/useMeasuredWidth.ts
2028
- import * as React17 from "react";
2081
+ import * as React18 from "react";
2029
2082
  function useMeasuredWidth(fallback) {
2030
- const [element, setElement] = React17.useState(null);
2031
- const [width, setWidth] = React17.useState(fallback);
2032
- React17.useLayoutEffect(() => {
2083
+ const [element, setElement] = React18.useState(null);
2084
+ const [width, setWidth] = React18.useState(fallback);
2085
+ React18.useLayoutEffect(() => {
2033
2086
  if (!element || typeof ResizeObserver === "undefined") return;
2034
2087
  const measure = () => {
2035
2088
  const measured = Math.round(element.getBoundingClientRect().width);
@@ -2044,7 +2097,7 @@ function useMeasuredWidth(fallback) {
2044
2097
  }
2045
2098
 
2046
2099
  // src/components/data/SegmentedMeter.tsx
2047
- import * as React18 from "react";
2100
+ import * as React19 from "react";
2048
2101
 
2049
2102
  // src/kits/files.ts
2050
2103
  function formatBytes(n) {
@@ -2249,7 +2302,7 @@ function SegmentedMeter({
2249
2302
  const pct = safeTotal ? Math.min(100, Math.round(used / safeTotal * 100)) : 0;
2250
2303
  const w = (v) => safeTotal ? Math.max(0, Math.min(100, Number(v) / safeTotal * 100)) : 0;
2251
2304
  const fill = (s, i) => s.color || (s.variant ? VARIANT_FILL[s.variant] : void 0) || CHART[i % CHART.length];
2252
- const generatedId = React18.useId();
2305
+ const generatedId = React19.useId();
2253
2306
  const uid2 = id || generatedId;
2254
2307
  return /* @__PURE__ */ jsxs27("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
2255
2308
  label || showTotal ? /* @__PURE__ */ jsxs27("div", { className: "fd-segmeter-head", children: [
@@ -2400,8 +2453,8 @@ function TrendChart({
2400
2453
  onRetry,
2401
2454
  className = ""
2402
2455
  }) {
2403
- const [activeId, setActiveId] = React19.useState(null);
2404
- const [pointTip, setPointTip] = React19.useState(null);
2456
+ const [activeId, setActiveId] = React20.useState(null);
2457
+ const [pointTip, setPointTip] = React20.useState(null);
2405
2458
  const isEmpty = state === "ready" && (!categories.length || !series.length || series.every((s) => !s.values.length));
2406
2459
  const effectiveState = isEmpty ? "empty" : state;
2407
2460
  const [plotRef, VBW] = useMeasuredWidth(INITIAL_WIDTH);
@@ -2515,7 +2568,7 @@ function TrendChart({
2515
2568
  }
2516
2569
 
2517
2570
  // src/components/data/DonutChart.tsx
2518
- import * as React20 from "react";
2571
+ import * as React21 from "react";
2519
2572
  import { jsx as jsx38, jsxs as jsxs30 } from "react/jsx-runtime";
2520
2573
  function DonutChart({
2521
2574
  segments,
@@ -2530,7 +2583,7 @@ function DonutChart({
2530
2583
  onRetry,
2531
2584
  className = ""
2532
2585
  }) {
2533
- const [activeId, setActiveId] = React20.useState(null);
2586
+ const [activeId, setActiveId] = React21.useState(null);
2534
2587
  const items = segments.filter((s) => Number(s.value) > 0);
2535
2588
  const total = items.reduce((n, s) => n + Number(s.value), 0);
2536
2589
  const isEmpty = state === "ready" && (!items.length || total <= 0);
@@ -2622,7 +2675,7 @@ function DonutChart({
2622
2675
  }
2623
2676
 
2624
2677
  // src/components/data/BarList.tsx
2625
- import * as React21 from "react";
2678
+ import * as React22 from "react";
2626
2679
  import { jsx as jsx39, jsxs as jsxs31 } from "react/jsx-runtime";
2627
2680
  function BarList({
2628
2681
  rows,
@@ -2637,7 +2690,7 @@ function BarList({
2637
2690
  onRetry,
2638
2691
  className = ""
2639
2692
  }) {
2640
- const ordered = React21.useMemo(() => {
2693
+ const ordered = React22.useMemo(() => {
2641
2694
  const list = sort ? [...rows].sort((a, b) => Number(b.value) - Number(a.value)) : rows;
2642
2695
  return maxRows ? list.slice(0, maxRows) : list;
2643
2696
  }, [rows, sort, maxRows]);
@@ -2779,7 +2832,7 @@ function FunnelChart({
2779
2832
  }
2780
2833
 
2781
2834
  // src/components/data/Clamp.tsx
2782
- import * as React22 from "react";
2835
+ import * as React23 from "react";
2783
2836
  import { jsx as jsx41, jsxs as jsxs33 } from "react/jsx-runtime";
2784
2837
  function Clamp({
2785
2838
  children,
@@ -2791,16 +2844,16 @@ function Clamp({
2791
2844
  onToggle,
2792
2845
  className = ""
2793
2846
  }) {
2794
- const [open2, setOpen] = React22.useState(false);
2795
- const [overflows, setOverflows] = React22.useState(false);
2796
- const bodyRef = React22.useRef(null);
2797
- const charClamped = React22.useMemo(() => {
2847
+ const [open2, setOpen] = React23.useState(false);
2848
+ const [overflows, setOverflows] = React23.useState(false);
2849
+ const bodyRef = React23.useRef(null);
2850
+ const charClamped = React23.useMemo(() => {
2798
2851
  if (open2 || !maxChars || typeof text !== "string" || text.length <= maxChars) return null;
2799
2852
  const cut = text.slice(0, maxChars);
2800
2853
  const at = cut.lastIndexOf(" ");
2801
2854
  return (at > maxChars * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
2802
2855
  }, [text, maxChars, open2]);
2803
- React22.useLayoutEffect(() => {
2856
+ React23.useLayoutEffect(() => {
2804
2857
  const node = bodyRef.current;
2805
2858
  if (maxChars || !node || !maxHeight) return;
2806
2859
  const measure = () => {
@@ -2939,16 +2992,16 @@ function DataTable({
2939
2992
  }
2940
2993
 
2941
2994
  // src/components/data/FilterBar.tsx
2942
- import * as React28 from "react";
2995
+ import * as React29 from "react";
2943
2996
 
2944
2997
  // src/components/forms/NumberInput.tsx
2945
- import * as React25 from "react";
2998
+ import * as React26 from "react";
2946
2999
 
2947
3000
  // src/components/forms/field.tsx
2948
- import * as React23 from "react";
3001
+ import * as React24 from "react";
2949
3002
  import { jsx as jsx44, jsxs as jsxs36 } from "react/jsx-runtime";
2950
3003
  function useFieldId(id) {
2951
- const generated = React23.useId();
3004
+ const generated = React24.useId();
2952
3005
  return id || generated;
2953
3006
  }
2954
3007
  function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
@@ -2967,10 +3020,10 @@ function HiddenFieldLabel({ id, children }) {
2967
3020
  }
2968
3021
 
2969
3022
  // src/components/useLatest.ts
2970
- import * as React24 from "react";
3023
+ import * as React25 from "react";
2971
3024
  function useLatest(value) {
2972
- const ref = React24.useRef(value);
2973
- React24.useInsertionEffect(() => {
3025
+ const ref = React25.useRef(value);
3026
+ React25.useInsertionEffect(() => {
2974
3027
  ref.current = value;
2975
3028
  });
2976
3029
  return ref;
@@ -3053,20 +3106,20 @@ function NumberInput({
3053
3106
  const n = typeof v === "number" ? v : parseNumberText(v);
3054
3107
  return n == null || Number.isNaN(n) ? null : n;
3055
3108
  };
3056
- const [text, setText] = React25.useState(() => toText(value));
3057
- const [editing, setEditing] = React25.useState(false);
3109
+ const [text, setText] = React26.useState(() => toText(value));
3110
+ const [editing, setEditing] = React26.useState(false);
3058
3111
  const parsed = parseNumberText(text);
3059
3112
  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;
3060
3113
  const valid = invalidMessage == null;
3061
- const committedRef = React25.useRef(toNumber(value));
3114
+ const committedRef = React26.useRef(toNumber(value));
3062
3115
  const onChangeRef = useLatest(onChange);
3063
3116
  const onValidityChangeRef = useLatest(onValidityChange);
3064
- const focusedRef = React25.useRef(false);
3065
- React25.useEffect(() => {
3117
+ const focusedRef = React26.useRef(false);
3118
+ React26.useEffect(() => {
3066
3119
  committedRef.current = toNumber(value);
3067
3120
  if (!focusedRef.current) setText(toText(value));
3068
3121
  }, [value]);
3069
- React25.useLayoutEffect(() => {
3122
+ React26.useLayoutEffect(() => {
3070
3123
  onValidityChangeRef.current?.(valid);
3071
3124
  }, [valid, onValidityChangeRef]);
3072
3125
  const fire = (n) => {
@@ -3082,26 +3135,26 @@ function NumberInput({
3082
3135
  return true;
3083
3136
  };
3084
3137
  const bumpRef = useLatest(bump);
3085
- const holdTimer = React25.useRef(null);
3086
- const release = () => {
3138
+ const holdTimer = React26.useRef(null);
3139
+ const release2 = () => {
3087
3140
  if (holdTimer.current) clearTimeout(holdTimer.current);
3088
3141
  holdTimer.current = null;
3089
3142
  };
3090
3143
  const hold = (direction) => {
3091
- release();
3144
+ release2();
3092
3145
  bump(direction, step);
3093
3146
  let repeats = 0;
3094
3147
  const tick = () => {
3095
3148
  repeats++;
3096
3149
  if (!bumpRef.current(direction, repeats > HOLD_BIG_AFTER ? big : step)) {
3097
- release();
3150
+ release2();
3098
3151
  return;
3099
3152
  }
3100
3153
  holdTimer.current = setTimeout(tick, holdInterval(repeats));
3101
3154
  };
3102
3155
  holdTimer.current = setTimeout(tick, HOLD_DELAY_MS);
3103
3156
  };
3104
- React25.useEffect(() => () => {
3157
+ React26.useEffect(() => () => {
3105
3158
  if (holdTimer.current) clearTimeout(holdTimer.current);
3106
3159
  }, []);
3107
3160
  const current2 = committedRef.current;
@@ -3167,9 +3220,9 @@ function NumberInput({
3167
3220
  "aria-label": stepperName("Decrease"),
3168
3221
  disabled: disabled || noRange || current2 != null && current2 <= lo,
3169
3222
  onPointerDown: () => hold(-1),
3170
- onPointerUp: release,
3171
- onPointerLeave: release,
3172
- onPointerCancel: release,
3223
+ onPointerUp: release2,
3224
+ onPointerLeave: release2,
3225
+ onPointerCancel: release2,
3173
3226
  onClick: (e) => {
3174
3227
  if (e.detail === 0) bump(-1, step);
3175
3228
  },
@@ -3184,9 +3237,9 @@ function NumberInput({
3184
3237
  "aria-label": stepperName("Increase"),
3185
3238
  disabled: disabled || noRange || current2 != null && current2 >= hi,
3186
3239
  onPointerDown: () => hold(1),
3187
- onPointerUp: release,
3188
- onPointerLeave: release,
3189
- onPointerCancel: release,
3240
+ onPointerUp: release2,
3241
+ onPointerLeave: release2,
3242
+ onPointerCancel: release2,
3190
3243
  onClick: (e) => {
3191
3244
  if (e.detail === 0) bump(1, step);
3192
3245
  },
@@ -3204,7 +3257,7 @@ function NumberInput({
3204
3257
  }
3205
3258
 
3206
3259
  // src/components/forms/DatePicker.tsx
3207
- import * as React26 from "react";
3260
+ import * as React27 from "react";
3208
3261
  import { jsx as jsx46, jsxs as jsxs38 } from "react/jsx-runtime";
3209
3262
  var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
3210
3263
  var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
@@ -3237,10 +3290,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3237
3290
  const today = /* @__PURE__ */ new Date();
3238
3291
  const sel = range ? value || {} : { start: value, end: value };
3239
3292
  const anchor = parse(sel.start) || parse(initialMonth) || today;
3240
- const [vy, setVy] = React26.useState(anchor.getFullYear());
3241
- const [vm, setVm] = React26.useState(anchor.getMonth());
3242
- const [mode2, setMode] = React26.useState("days");
3243
- const [hover, setHover] = React26.useState(null);
3293
+ const [vy, setVy] = React27.useState(anchor.getFullYear());
3294
+ const [vm, setVm] = React27.useState(anchor.getMonth());
3295
+ const [mode2, setMode] = React27.useState("days");
3296
+ const [hover, setHover] = React27.useState(null);
3244
3297
  const s = parse(sel.start), e = parse(sel.end);
3245
3298
  const hoverEnd = range && s && !e && hover ? parse(hover) : null;
3246
3299
  const inRange = (d) => {
@@ -3251,12 +3304,12 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3251
3304
  const isEnd = (d) => !!e && iso(d) === iso(e);
3252
3305
  const isEdge = (d) => isStart(d) || isEnd(d);
3253
3306
  const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;
3254
- const [activeDate, setActiveDate] = React26.useState(() => {
3307
+ const [activeDate, setActiveDate] = React27.useState(() => {
3255
3308
  if (s) return s;
3256
3309
  if (sameMonth(today, anchor.getFullYear(), anchor.getMonth())) return today;
3257
3310
  return new Date(anchor.getFullYear(), anchor.getMonth(), 1);
3258
3311
  });
3259
- const calRef = React26.useRef(null);
3312
+ const calRef = React27.useRef(null);
3260
3313
  const pageToShow = (y, m) => {
3261
3314
  const idx = y * 12 + m, firstIdx = vy * 12 + vm, secondIdx = firstIdx + 1;
3262
3315
  if (idx === firstIdx || months > 1 && idx === secondIdx) return;
@@ -3273,7 +3326,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3273
3326
  setActiveDate(next);
3274
3327
  pageToShow(next.getFullYear(), next.getMonth());
3275
3328
  };
3276
- React26.useEffect(() => {
3329
+ React27.useEffect(() => {
3277
3330
  const el = calRef.current?.querySelector('[data-iso="' + iso(activeDate) + '"]');
3278
3331
  if (el) el.focus({ preventScroll: true });
3279
3332
  }, [activeDate, vy, vm]);
@@ -3466,9 +3519,9 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3466
3519
  }
3467
3520
  function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, "aria-label": hiddenLabel, ...rest }) {
3468
3521
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
3469
- const [open2, setOpen] = React26.useState(false);
3470
- const rootRef = React26.useRef(null);
3471
- const boxRef = React26.useRef(null);
3522
+ const [open2, setOpen] = React27.useState(false);
3523
+ const rootRef = React27.useRef(null);
3524
+ const boxRef = React27.useRef(null);
3472
3525
  const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
3473
3526
  const toggle = () => {
3474
3527
  if (!disabled) setOpen(!open2);
@@ -3557,9 +3610,9 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
3557
3610
  }
3558
3611
 
3559
3612
  // src/components/forms/listbox.ts
3560
- import * as React27 from "react";
3613
+ import * as React28 from "react";
3561
3614
  function useListboxNav({ count, onSelect }) {
3562
- const [active, setActive] = React27.useState(-1);
3615
+ const [active, setActive] = React28.useState(-1);
3563
3616
  return {
3564
3617
  active,
3565
3618
  setActive,
@@ -3572,7 +3625,7 @@ function useListboxNav({ count, onSelect }) {
3572
3625
  };
3573
3626
  }
3574
3627
  function useListboxScrollIntoView(active, listRef, enabled) {
3575
- React27.useEffect(() => {
3628
+ React28.useEffect(() => {
3576
3629
  if (!enabled || active < 0 || !listRef.current) return;
3577
3630
  const list = listRef.current;
3578
3631
  const el = list.querySelector('[data-i="' + active + '"]');
@@ -3785,13 +3838,13 @@ function MultiSelectPanel({
3785
3838
  onClose
3786
3839
  }) {
3787
3840
  const allowedOps = operatorsFor(field);
3788
- const [draftOperator, setDraftOperator] = React28.useState(value?.operator ?? allowedOps[0]);
3841
+ const [draftOperator, setDraftOperator] = React29.useState(value?.operator ?? allowedOps[0]);
3789
3842
  const operator = allowedOps.length === 1 ? allowedOps[0] : value?.operator ?? draftOperator;
3790
3843
  const selected = value?.values ?? [];
3791
3844
  const selectedRef = useLatest(selected);
3792
3845
  const operatorRef = useLatest(operator);
3793
- const mountedRef = React28.useRef(true);
3794
- React28.useEffect(() => {
3846
+ const mountedRef = React29.useRef(true);
3847
+ React29.useEffect(() => {
3795
3848
  mountedRef.current = true;
3796
3849
  return () => {
3797
3850
  mountedRef.current = false;
@@ -3805,20 +3858,20 @@ function MultiSelectPanel({
3805
3858
  if (selectedRef.current.length > 0) commit(selectedRef.current, op);
3806
3859
  else setDraftOperator(op);
3807
3860
  };
3808
- const [mode2, setMode] = React28.useState("search");
3809
- const [query, setQuery] = React28.useState("");
3810
- const [asyncState, setAsyncState] = React28.useState(
3861
+ const [mode2, setMode] = React29.useState("search");
3862
+ const [query, setQuery] = React29.useState("");
3863
+ const [asyncState, setAsyncState] = React29.useState(
3811
3864
  { options: null, loading: !!field.loadOptions, error: false }
3812
3865
  );
3813
- const [retryTick, setRetryTick] = React28.useState(0);
3814
- const inputRef = React28.useRef(null);
3815
- const listRef = React28.useRef(null);
3816
- const listId = React28.useId();
3866
+ const [retryTick, setRetryTick] = React29.useState(0);
3867
+ const inputRef = React29.useRef(null);
3868
+ const listRef = React29.useRef(null);
3869
+ const listId = React29.useId();
3817
3870
  const loadOptionsRef = useLatest(field.loadOptions);
3818
- React28.useEffect(() => {
3871
+ React29.useEffect(() => {
3819
3872
  inputRef.current?.focus();
3820
3873
  }, []);
3821
- React28.useEffect(() => {
3874
+ React29.useEffect(() => {
3822
3875
  const load = loadOptionsRef.current;
3823
3876
  if (!load) return;
3824
3877
  const controller = new AbortController();
@@ -3851,17 +3904,17 @@ function MultiSelectPanel({
3851
3904
  };
3852
3905
  const nav = useListboxNav({ count: options.length, onSelect: (i) => toggle(options[i]) });
3853
3906
  useListboxScrollIntoView(nav.active, listRef, hasListbox);
3854
- React28.useEffect(() => {
3907
+ React29.useEffect(() => {
3855
3908
  nav.setActive(0);
3856
3909
  }, [query, options.length]);
3857
3910
  const activeId = hasListbox && options[nav.active] ? listId + "-opt-" + nav.active : void 0;
3858
3911
  const liveMessage = showLoading ? "Loading\u2026" : showError ? "Couldn't load options." : options.length === 0 ? "No matches" : atLimit ? "Limit reached: at most " + field.maxValues + " values" : "";
3859
- const [pasteText, setPasteText] = React28.useState("");
3860
- const [pasteLoading, setPasteLoading] = React28.useState(false);
3861
- const [unmatchedTokens, setUnmatchedTokens] = React28.useState([]);
3862
- const [pasteError, setPasteError] = React28.useState(null);
3863
- const pasteWrapRef = React28.useRef(null);
3864
- React28.useEffect(() => {
3912
+ const [pasteText, setPasteText] = React29.useState("");
3913
+ const [pasteLoading, setPasteLoading] = React29.useState(false);
3914
+ const [unmatchedTokens, setUnmatchedTokens] = React29.useState([]);
3915
+ const [pasteError, setPasteError] = React29.useState(null);
3916
+ const pasteWrapRef = React29.useRef(null);
3917
+ React29.useEffect(() => {
3865
3918
  if (mode2 === "paste") pasteWrapRef.current?.querySelector("textarea")?.focus();
3866
3919
  }, [mode2]);
3867
3920
  const doResolve = () => {
@@ -4034,8 +4087,8 @@ function MultiSelectPanel({
4034
4087
  );
4035
4088
  }
4036
4089
  function useTextValidity(onFlip) {
4037
- const invalidRef = React28.useRef(/* @__PURE__ */ new Set());
4038
- const [, rerender] = React28.useReducer((n) => n + 1, 0);
4090
+ const invalidRef = React29.useRef(/* @__PURE__ */ new Set());
4091
+ const [, rerender] = React29.useReducer((n) => n + 1, 0);
4039
4092
  const onFlipRef = useLatest(onFlip);
4040
4093
  const record = (name, valid) => {
4041
4094
  const invalid = invalidRef.current;
@@ -4078,15 +4131,15 @@ function sameValue(a, b) {
4078
4131
  return true;
4079
4132
  }
4080
4133
  function useReseedFromProps(value, applies, reseed) {
4081
- const seen = React28.useRef(value);
4082
- React28.useLayoutEffect(() => {
4134
+ const seen = React29.useRef(value);
4135
+ React29.useLayoutEffect(() => {
4083
4136
  if (seen.current === value) return;
4084
4137
  seen.current = value;
4085
4138
  if (!sameValue(value, applies())) reseed(value);
4086
4139
  }, [value, applies, reseed]);
4087
4140
  }
4088
4141
  function usePreserveFocusAcrossRemount(seed, fields) {
4089
- const pendingName = React28.useRef(null);
4142
+ const pendingName = React29.useRef(null);
4090
4143
  const fieldsRef = useLatest(fields);
4091
4144
  const capture = () => {
4092
4145
  const active = document.activeElement;
@@ -4099,7 +4152,7 @@ function usePreserveFocusAcrossRemount(seed, fields) {
4099
4152
  }
4100
4153
  }
4101
4154
  };
4102
- React28.useLayoutEffect(() => {
4155
+ React29.useLayoutEffect(() => {
4103
4156
  const name = pendingName.current;
4104
4157
  if (!name) return;
4105
4158
  pendingName.current = null;
@@ -4115,14 +4168,14 @@ function RangePanel({
4115
4168
  onCommit,
4116
4169
  onClose
4117
4170
  }) {
4118
- const [draft, setDraft] = React28.useState(() => rangeDraft(value));
4119
- const [seed, setSeed] = React28.useState(0);
4120
- const minId = React28.useId();
4121
- const maxId = React28.useId();
4122
- const minWrapRef = React28.useRef(null);
4123
- const maxWrapRef = React28.useRef(null);
4171
+ const [draft, setDraft] = React29.useState(() => rangeDraft(value));
4172
+ const [seed, setSeed] = React29.useState(0);
4173
+ const minId = React29.useId();
4174
+ const maxId = React29.useId();
4175
+ const minWrapRef = React29.useRef(null);
4176
+ const maxWrapRef = React29.useRef(null);
4124
4177
  const preserveFocus = usePreserveFocusAcrossRemount(seed, { min: minWrapRef, max: maxWrapRef });
4125
- const draftRef = React28.useRef(draft);
4178
+ const draftRef = React29.useRef(draft);
4126
4179
  const shown = () => {
4127
4180
  const { min, max } = draftRef.current;
4128
4181
  return applicable(field, min == null && max == null ? void 0 : { min, max }, validity.allValid());
@@ -4214,15 +4267,15 @@ function DatePanel({
4214
4267
  onClose
4215
4268
  }) {
4216
4269
  const maxDays = effectiveMaxDays(field);
4217
- const [initial] = React28.useState(() => dateDraft(field, value));
4218
- const [kind, setKind] = React28.useState(initial.kind);
4219
- const [daysDraft, setDaysDraft] = React28.useState(initial.days);
4220
- const daysRef = React28.useRef(daysDraft);
4221
- const daysConfirmed = React28.useRef(value?.kind === "withinDays");
4222
- const [between, setBetween] = React28.useState(initial.between);
4223
- const [seed, setSeed] = React28.useState(0);
4224
- const daysId = React28.useId();
4225
- const daysWrapRef = React28.useRef(null);
4270
+ const [initial] = React29.useState(() => dateDraft(field, value));
4271
+ const [kind, setKind] = React29.useState(initial.kind);
4272
+ const [daysDraft, setDaysDraft] = React29.useState(initial.days);
4273
+ const daysRef = React29.useRef(daysDraft);
4274
+ const daysConfirmed = React29.useRef(value?.kind === "withinDays");
4275
+ const [between, setBetween] = React29.useState(initial.between);
4276
+ const [seed, setSeed] = React29.useState(0);
4277
+ const daysId = React29.useId();
4278
+ const daysWrapRef = React29.useRef(null);
4226
4279
  const preserveFocus = usePreserveFocusAcrossRemount(seed, { days: daysWrapRef });
4227
4280
  const shownWithinDays = () => {
4228
4281
  const days = daysRef.current;
@@ -4334,11 +4387,11 @@ function DatePanel({
4334
4387
  );
4335
4388
  }
4336
4389
  function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", actions, onClearAll, showActiveCount = false, className = "", ...rest }) {
4337
- const [panel, setPanel] = React28.useState(null);
4338
- const editAnchorRef = React28.useRef(null);
4339
- const addAnchorRef = React28.useRef(null);
4340
- const textInputRef = React28.useRef(null);
4341
- const optionsRef = React28.useRef(null);
4390
+ const [panel, setPanel] = React29.useState(null);
4391
+ const editAnchorRef = React29.useRef(null);
4392
+ const addAnchorRef = React29.useRef(null);
4393
+ const textInputRef = React29.useRef(null);
4394
+ const optionsRef = React29.useRef(null);
4342
4395
  if (process.env.NODE_ENV !== "production") {
4343
4396
  for (const f of fields) assertValidFieldDefinition(f);
4344
4397
  }
@@ -4361,7 +4414,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
4361
4414
  const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
4362
4415
  const startEditing = (key) => setPanel({ kind: "edit", key });
4363
4416
  const closeEditing = () => setPanel(null);
4364
- React28.useEffect(() => {
4417
+ React29.useEffect(() => {
4365
4418
  if (!panel || panel.kind !== "edit") return;
4366
4419
  if (editingField?.type === "text") {
4367
4420
  textInputRef.current?.focus();
@@ -4470,8 +4523,10 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
4470
4523
  removeField(field);
4471
4524
  closeEditing();
4472
4525
  };
4473
- const chipText = field.label + (set ? ": " + chipLabel(field, value) : "");
4474
- const chip = /* @__PURE__ */ jsx49(Tag, { icon: field.icon, selected: true, onClick: toggleOrClose, onRemove: remove, title: chipText, "aria-label": chipText, children: /* @__PURE__ */ jsx49(MiddleEllipsis, { text: chipText }) });
4526
+ const valueText = set ? chipLabel(field, value) : "";
4527
+ const chipText = set ? field.label + ": " + valueText : field.label;
4528
+ const paintedText = field.icon && set ? valueText : chipText;
4529
+ const chip = /* @__PURE__ */ jsx49(Tag, { icon: field.icon, selected: true, onClick: toggleOrClose, onRemove: remove, title: chipText, "aria-label": chipText, children: /* @__PURE__ */ jsx49(MiddleEllipsis, { text: paintedText }) });
4475
4530
  if (field.type === "text") {
4476
4531
  return /* @__PURE__ */ jsx49("span", { className: "fd-filterbar-chip", children: chip }, field.key);
4477
4532
  }
@@ -4589,10 +4644,10 @@ function StatTile({ label, value, sub, delta, invert = false, loading = false, c
4589
4644
  }
4590
4645
 
4591
4646
  // src/components/data/CodeBlock.tsx
4592
- import * as React30 from "react";
4647
+ import * as React31 from "react";
4593
4648
 
4594
4649
  // src/kits/clipboard.ts
4595
- import * as React29 from "react";
4650
+ import * as React30 from "react";
4596
4651
  var COPIED_FEEDBACK_MS = 1600;
4597
4652
  function copyThroughSelection(text) {
4598
4653
  const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
@@ -4622,17 +4677,17 @@ async function copyToClipboard(text) {
4622
4677
  return copyThroughSelection(text);
4623
4678
  }
4624
4679
  function useCopyToClipboard() {
4625
- const [copied, setCopied] = React29.useState(false);
4626
- const timer = React29.useRef(null);
4627
- const mounted = React29.useRef(true);
4628
- React29.useEffect(() => {
4680
+ const [copied, setCopied] = React30.useState(false);
4681
+ const timer = React30.useRef(null);
4682
+ const mounted = React30.useRef(true);
4683
+ React30.useEffect(() => {
4629
4684
  mounted.current = true;
4630
4685
  return () => {
4631
4686
  mounted.current = false;
4632
4687
  if (timer.current) clearTimeout(timer.current);
4633
4688
  };
4634
4689
  }, []);
4635
- const copy = React29.useCallback(async (text) => {
4690
+ const copy = React30.useCallback(async (text) => {
4636
4691
  const ok = await copyToClipboard(text);
4637
4692
  if (ok && mounted.current) {
4638
4693
  setCopied(true);
@@ -4800,7 +4855,7 @@ function tokenize(src, lang) {
4800
4855
  return out;
4801
4856
  }
4802
4857
  function Highlighted({ code, lang }) {
4803
- const toks = React30.useMemo(() => tokenize(code, lang), [code, lang]);
4858
+ const toks = React31.useMemo(() => tokenize(code, lang), [code, lang]);
4804
4859
  return /* @__PURE__ */ jsx51(Fragment7, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ jsx51("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
4805
4860
  }
4806
4861
  function CodeBlock({
@@ -4814,8 +4869,8 @@ function CodeBlock({
4814
4869
  actions,
4815
4870
  className = ""
4816
4871
  }) {
4817
- const [wrap, setWrap] = React30.useState(!!wrapDefault);
4818
- const [open2, setOpen] = React30.useState(false);
4872
+ const [wrap, setWrap] = React31.useState(!!wrapDefault);
4873
+ const [open2, setOpen] = React31.useState(false);
4819
4874
  const [copied, copy] = useCopyToClipboard();
4820
4875
  const body = String(code).replace(/\n$/, "");
4821
4876
  const lines = body.split("\n");
@@ -4844,7 +4899,7 @@ function CodeBlock({
4844
4899
  ] });
4845
4900
  }
4846
4901
  function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
4847
- const [open2, setOpen] = React30.useState(false);
4902
+ const [open2, setOpen] = React31.useState(false);
4848
4903
  const [copied, copy] = useCopyToClipboard();
4849
4904
  const raw = String(diff).replace(/\n$/, "");
4850
4905
  const all = raw.split("\n").map((line) => {
@@ -4890,7 +4945,7 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
4890
4945
  }
4891
4946
 
4892
4947
  // src/components/data/Markdown.tsx
4893
- import * as React31 from "react";
4948
+ import * as React32 from "react";
4894
4949
  import { jsx as jsx52, jsxs as jsxs44 } from "react/jsx-runtime";
4895
4950
  var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
4896
4951
  var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
@@ -4929,7 +4984,7 @@ function inlineNodes(src, ctx, keyBase) {
4929
4984
  const href = safeHref(g(2));
4930
4985
  out.push(href ? /* @__PURE__ */ jsx52("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__ */ jsx52("span", { children: g(1) }, key()));
4931
4986
  } else if (kind === "cite") {
4932
- out.push(ctx.renderCitation ? /* @__PURE__ */ jsx52(React31.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ jsx52("sup", { className: "fd-md-cite", children: g(1) }, key()));
4987
+ out.push(ctx.renderCitation ? /* @__PURE__ */ jsx52(React32.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ jsx52("sup", { className: "fd-md-cite", children: g(1) }, key()));
4933
4988
  } else if (kind === "strongem") out.push(/* @__PURE__ */ jsx52("strong", { children: /* @__PURE__ */ jsx52("em", { children: inlineNodes(g(1), ctx, key()) }) }, key()));
4934
4989
  else if (kind === "strong") out.push(/* @__PURE__ */ jsx52("strong", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
4935
4990
  else if (kind === "em") out.push(/* @__PURE__ */ jsx52("em", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
@@ -5094,7 +5149,7 @@ function Markdown({
5094
5149
  onLinkClick
5095
5150
  }) {
5096
5151
  const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
5097
- const blocks = React31.useMemo(() => parseBlocks(source), [source]);
5152
+ const blocks = React32.useMemo(() => parseBlocks(source), [source]);
5098
5153
  return /* @__PURE__ */ jsx52("div", { className: ["fd-md", className].filter(Boolean).join(" "), children: renderBlocks(blocks, ctx, "b") });
5099
5154
  }
5100
5155
  function MarkdownInline({ source = "", className = "", onLinkClick }) {
@@ -5208,7 +5263,7 @@ function Pagination({
5208
5263
  }
5209
5264
 
5210
5265
  // src/components/data/RelativeTime.tsx
5211
- import * as React32 from "react";
5266
+ import * as React33 from "react";
5212
5267
  import { jsxs as jsxs47 } from "react/jsx-runtime";
5213
5268
  var MIN = 6e4;
5214
5269
  var HOUR = 36e5;
@@ -5260,9 +5315,9 @@ function formatDuration(ms) {
5260
5315
  return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
5261
5316
  }
5262
5317
  function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
5263
- const [, force] = React32.useState(0);
5318
+ const [, force] = React33.useState(0);
5264
5319
  const t = value instanceof Date ? value.getTime() : Date.parse(value);
5265
- React32.useEffect(() => {
5320
+ React33.useEffect(() => {
5266
5321
  if (!refresh2 || !t || isNaN(t)) return;
5267
5322
  const abs = Math.abs(t - Date.now());
5268
5323
  if (abs > DAY) return;
@@ -5278,7 +5333,7 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
5278
5333
  }
5279
5334
 
5280
5335
  // src/components/data/ScoreMeter.tsx
5281
- import * as React33 from "react";
5336
+ import * as React34 from "react";
5282
5337
  import { jsx as jsx55, jsxs as jsxs48 } from "react/jsx-runtime";
5283
5338
  function ScoreMeter({
5284
5339
  score,
@@ -5293,10 +5348,10 @@ function ScoreMeter({
5293
5348
  breakdownWidth = 280,
5294
5349
  className = ""
5295
5350
  }) {
5296
- const [open2, setOpen] = React33.useState(false);
5297
- const ref = React33.useRef(null);
5351
+ const [open2, setOpen] = React34.useState(false);
5352
+ const ref = React34.useRef(null);
5298
5353
  const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
5299
- const body = /* @__PURE__ */ jsxs48(React33.Fragment, { children: [
5354
+ const body = /* @__PURE__ */ jsxs48(React34.Fragment, { children: [
5300
5355
  /* @__PURE__ */ jsx55("span", { className: "fd-scoremeter-rail", style: { width }, "aria-hidden": "true", children: /* @__PURE__ */ jsx55(SegmentedMeter, { total: 100, segments, height, showTotal: false, showPercent: false, legend: false }) }),
5301
5356
  showScore ? /* @__PURE__ */ jsx55("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
5302
5357
  ] });
@@ -5315,7 +5370,7 @@ function ScoreMeter({
5315
5370
  }
5316
5371
  );
5317
5372
  }
5318
- return /* @__PURE__ */ jsxs48(React33.Fragment, { children: [
5373
+ return /* @__PURE__ */ jsxs48(React34.Fragment, { children: [
5319
5374
  /* @__PURE__ */ jsx55(
5320
5375
  "button",
5321
5376
  {
@@ -5346,14 +5401,14 @@ function ScoreMeter({
5346
5401
  }
5347
5402
 
5348
5403
  // src/components/actions/inlinePanel.tsx
5349
- import * as React34 from "react";
5404
+ import * as React35 from "react";
5350
5405
  import { jsx as jsx56 } from "react/jsx-runtime";
5351
5406
  function useInlinePanel() {
5352
- const [open2, setOpen] = React34.useState(false);
5353
- const ref = React34.useRef(null);
5407
+ const [open2, setOpen] = React35.useState(false);
5408
+ const ref = React35.useRef(null);
5354
5409
  const layer = useStackedLayer({ active: open2, containerRef: ref, onEscape: () => setOpen(false) });
5355
5410
  const zIndex = useLayerZIndex(layer);
5356
- React34.useEffect(() => {
5411
+ React35.useEffect(() => {
5357
5412
  if (!open2) return;
5358
5413
  const away = (e) => {
5359
5414
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -5419,7 +5474,7 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
5419
5474
  }
5420
5475
 
5421
5476
  // src/components/data/StepList.tsx
5422
- import * as React35 from "react";
5477
+ import * as React36 from "react";
5423
5478
  import { jsx as jsx58, jsxs as jsxs50 } from "react/jsx-runtime";
5424
5479
  var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
5425
5480
  function StepList({
@@ -5432,9 +5487,9 @@ function StepList({
5432
5487
  dense = false,
5433
5488
  className = ""
5434
5489
  }) {
5435
- const [openState, setOpenState] = React35.useState(defaultOpen);
5490
+ const [openState, setOpenState] = React36.useState(defaultOpen);
5436
5491
  const open2 = openProp == null ? openState : openProp;
5437
- const [expanded, setExpanded] = React35.useState({});
5492
+ const [expanded, setExpanded] = React36.useState({});
5438
5493
  if (!steps.length) return null;
5439
5494
  const running = steps.some((s) => s.status === "running");
5440
5495
  const failed = steps.filter((s) => s.status === "error").length;
@@ -5492,7 +5547,7 @@ function StepList({
5492
5547
  }
5493
5548
 
5494
5549
  // src/components/data/VirtualList.tsx
5495
- import * as React36 from "react";
5550
+ import * as React37 from "react";
5496
5551
  import { jsx as jsx59, jsxs as jsxs51 } from "react/jsx-runtime";
5497
5552
  var VIRTUAL_LIST_BUFFER_ROWS = 20;
5498
5553
  var VIRTUAL_LIST_ROW_GAP = 6;
@@ -5544,35 +5599,35 @@ function VirtualList({
5544
5599
  className = "",
5545
5600
  style
5546
5601
  }) {
5547
- const [scrollTop, setScrollTop] = React36.useState(0);
5548
- const loaded = React36.useMemo(
5602
+ const [scrollTop, setScrollTop] = React37.useState(0);
5603
+ const loaded = React37.useMemo(
5549
5604
  () => ({ firstItemIndex, count: items.length }),
5550
5605
  [firstItemIndex, items.length]
5551
5606
  );
5552
5607
  const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
5553
5608
  const bandKey = firstItemIndex + ":" + items.length;
5554
- const win = React36.useMemo(
5609
+ const win = React37.useMemo(
5555
5610
  () => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
5556
5611
  [scrollTop, height, itemHeight, total, loaded]
5557
5612
  );
5558
- const need = React36.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
5613
+ const need = React37.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
5559
5614
  const wantStart = need.start && hasMore?.start !== false;
5560
5615
  const wantEnd = need.end && hasMore?.end !== false;
5561
5616
  const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
5562
5617
  const askKey = bandKey + "@" + bucket2;
5563
- const asked = React36.useRef({ start: null, end: null });
5564
- React36.useEffect(() => {
5618
+ const asked = React37.useRef({ start: null, end: null });
5619
+ React37.useEffect(() => {
5565
5620
  if (loading || !wantStart || asked.current.start === askKey) return;
5566
5621
  asked.current.start = askKey;
5567
5622
  onNeedMore("start", win);
5568
5623
  }, [wantStart, loading, askKey, onNeedMore, win]);
5569
- React36.useEffect(() => {
5624
+ React37.useEffect(() => {
5570
5625
  if (loading || !wantEnd || asked.current.end === askKey) return;
5571
5626
  asked.current.end = askKey;
5572
5627
  onNeedMore("end", win);
5573
5628
  }, [wantEnd, loading, askKey, onNeedMore, win]);
5574
- const lastKeysRef = React36.useRef(null);
5575
- const newKeys = React36.useMemo(() => {
5629
+ const lastKeysRef = React37.useRef(null);
5630
+ const newKeys = React37.useMemo(() => {
5576
5631
  const prev = lastKeysRef.current;
5577
5632
  if (!prev) return /* @__PURE__ */ new Set();
5578
5633
  const fresh = /* @__PURE__ */ new Set();
@@ -5582,7 +5637,7 @@ function VirtualList({
5582
5637
  }
5583
5638
  return fresh;
5584
5639
  }, [items]);
5585
- React36.useEffect(() => {
5640
+ React37.useEffect(() => {
5586
5641
  lastKeysRef.current = new Set(items.map(keyOf));
5587
5642
  }, [items]);
5588
5643
  const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
@@ -5627,7 +5682,7 @@ function VirtualList({
5627
5682
  }
5628
5683
 
5629
5684
  // src/components/data/EntityRow.tsx
5630
- import * as React37 from "react";
5685
+ import * as React38 from "react";
5631
5686
  import { jsx as jsx60, jsxs as jsxs52 } from "react/jsx-runtime";
5632
5687
  var ENTITY_ROW_METRIC_WIDTH = 74;
5633
5688
  var METRIC_TONE_COLOR = {
@@ -5640,7 +5695,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
5640
5695
  const key = m.id || m.label || i;
5641
5696
  const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
5642
5697
  const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
5643
- const content = /* @__PURE__ */ jsxs52(React37.Fragment, { children: [
5698
+ const content = /* @__PURE__ */ jsxs52(React38.Fragment, { children: [
5644
5699
  m.icon ? /* @__PURE__ */ jsx60("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
5645
5700
  /* @__PURE__ */ jsx60("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
5646
5701
  /* @__PURE__ */ jsx60("span", { className: "fd-sr", children: " " + m.label })
@@ -5732,8 +5787,8 @@ function EntityRow({
5732
5787
  }
5733
5788
 
5734
5789
  // src/components/data/TransferList.tsx
5735
- import * as React38 from "react";
5736
- import { createPortal as createPortal4 } from "react-dom";
5790
+ import * as React39 from "react";
5791
+ import { createPortal as createPortal5 } from "react-dom";
5737
5792
 
5738
5793
  // src/components/forms/Input.tsx
5739
5794
  import { jsx as jsx61, jsxs as jsxs53 } from "react/jsx-runtime";
@@ -5838,12 +5893,12 @@ function TransferList({
5838
5893
  listHeight = 440,
5839
5894
  className = ""
5840
5895
  }) {
5841
- const [drag, setDrag] = React38.useState(null);
5842
- const [dragOverSide, setDragOverSide] = React38.useState(null);
5843
- const dragRef = React38.useRef(null);
5844
- const armedRef = React38.useRef(null);
5845
- const sideRefs = React38.useRef({ left: null, right: null });
5846
- const hitTestSide = React38.useCallback((x, y) => {
5896
+ const [drag, setDrag] = React39.useState(null);
5897
+ const [dragOverSide, setDragOverSide] = React39.useState(null);
5898
+ const dragRef = React39.useRef(null);
5899
+ const armedRef = React39.useRef(null);
5900
+ const sideRefs = React39.useRef({ left: null, right: null });
5901
+ const hitTestSide = React39.useCallback((x, y) => {
5847
5902
  for (const side of ["left", "right"]) {
5848
5903
  const el = sideRefs.current[side];
5849
5904
  if (!el) continue;
@@ -5852,7 +5907,7 @@ function TransferList({
5852
5907
  }
5853
5908
  return null;
5854
5909
  }, []);
5855
- const findItem = React38.useCallback(
5910
+ const findItem = React39.useCallback(
5856
5911
  (side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
5857
5912
  [left.items, right.items, keyOf]
5858
5913
  );
@@ -5874,7 +5929,7 @@ function TransferList({
5874
5929
  height: rect.height
5875
5930
  };
5876
5931
  };
5877
- React38.useEffect(() => {
5932
+ React39.useEffect(() => {
5878
5933
  const onMovePointer = (e) => {
5879
5934
  const armed = armedRef.current;
5880
5935
  if (!armed || e.pointerId !== armed.pointerId) return;
@@ -5927,7 +5982,7 @@ function TransferList({
5927
5982
  window.removeEventListener("pointercancel", endDrag);
5928
5983
  };
5929
5984
  }, [hitTestSide, findItem, onMove]);
5930
- React38.useEffect(() => {
5985
+ React39.useEffect(() => {
5931
5986
  if (!drag || typeof document === "undefined") return;
5932
5987
  const prev = document.body.style.userSelect;
5933
5988
  document.body.style.userSelect = "none";
@@ -6010,7 +6065,7 @@ function TransferList({
6010
6065
  renderSide("left", left, "right"),
6011
6066
  renderSide("right", right, "left")
6012
6067
  ] }),
6013
- drag ? createPortal4(
6068
+ drag ? createPortal5(
6014
6069
  /* @__PURE__ */ jsx63(
6015
6070
  "div",
6016
6071
  {
@@ -6035,11 +6090,11 @@ function TransferList({
6035
6090
  }
6036
6091
 
6037
6092
  // src/components/forms/Checkbox.tsx
6038
- import * as React39 from "react";
6093
+ import * as React40 from "react";
6039
6094
  import { jsx as jsx64, jsxs as jsxs55 } from "react/jsx-runtime";
6040
6095
  function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
6041
- const ref = React39.useRef(null);
6042
- React39.useEffect(() => {
6096
+ const ref = React40.useRef(null);
6097
+ React40.useEffect(() => {
6043
6098
  if (ref.current) ref.current.indeterminate = indeterminate;
6044
6099
  }, [indeterminate]);
6045
6100
  return /* @__PURE__ */ jsxs55("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
@@ -6083,7 +6138,7 @@ function Switch({ label, description, className = "", ...rest }) {
6083
6138
  }
6084
6139
 
6085
6140
  // src/components/forms/Select.tsx
6086
- import * as React40 from "react";
6141
+ import * as React41 from "react";
6087
6142
  import { jsx as jsx67, jsxs as jsxs58 } from "react/jsx-runtime";
6088
6143
  var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
6089
6144
  function Select({
@@ -6111,12 +6166,12 @@ function Select({
6111
6166
  const isOn = (v) => multiple ? vals.includes(v) : v === value;
6112
6167
  const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
6113
6168
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
6114
- const [open2, setOpen] = React40.useState(false);
6115
- const [q, setQ] = React40.useState("");
6116
- const rootRef = React40.useRef(null);
6117
- const boxRef = React40.useRef(null);
6118
- const listRef = React40.useRef(null);
6119
- const typeBuf = React40.useRef({ s: "", t: 0 });
6169
+ const [open2, setOpen] = React41.useState(false);
6170
+ const [q, setQ] = React41.useState("");
6171
+ const rootRef = React41.useRef(null);
6172
+ const boxRef = React41.useRef(null);
6173
+ const listRef = React41.useRef(null);
6174
+ const typeBuf = React41.useRef({ s: "", t: 0 });
6120
6175
  const selected = multiple ? null : opts.find((o) => o.value === value);
6121
6176
  const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
6122
6177
  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;
@@ -6252,7 +6307,7 @@ function Select({
6252
6307
  ),
6253
6308
  q ? /* @__PURE__ */ jsx67("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
6254
6309
  ] }) : void 0,
6255
- footer: multiple ? /* @__PURE__ */ jsxs58(React40.Fragment, { children: [
6310
+ footer: multiple ? /* @__PURE__ */ jsxs58(React41.Fragment, { children: [
6256
6311
  /* @__PURE__ */ jsx67(
6257
6312
  "button",
6258
6313
  {
@@ -6283,7 +6338,7 @@ function Select({
6283
6338
  'Nothing matches "',
6284
6339
  q,
6285
6340
  '".'
6286
- ] }) : groups.map((grp) => /* @__PURE__ */ jsxs58(React40.Fragment, { children: [
6341
+ ] }) : groups.map((grp) => /* @__PURE__ */ jsxs58(React41.Fragment, { children: [
6287
6342
  grp.g ? /* @__PURE__ */ jsx67("div", { className: "fd-pop-group", children: grp.g }) : null,
6288
6343
  grp.items.map(({ o, i }) => /* @__PURE__ */ jsxs58(
6289
6344
  "button",
@@ -6320,7 +6375,7 @@ function Select({
6320
6375
  }
6321
6376
 
6322
6377
  // src/components/forms/TimePicker.tsx
6323
- import * as React41 from "react";
6378
+ import * as React42 from "react";
6324
6379
  import { jsx as jsx68, jsxs as jsxs59 } from "react/jsx-runtime";
6325
6380
  var pad = (n) => String(n).padStart(2, "0");
6326
6381
  function ClockFace({ value = "09:00", onChange }) {
@@ -6329,9 +6384,9 @@ function ClockFace({ value = "09:00", onChange }) {
6329
6384
  if (isNaN(m)) m = 0;
6330
6385
  const pm = h24 >= 12;
6331
6386
  const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
6332
- const [mode2, setMode] = React41.useState("h");
6333
- const faceRef = React41.useRef(null);
6334
- const dragging = React41.useRef(false);
6387
+ const [mode2, setMode] = React42.useState("h");
6388
+ const faceRef = React42.useRef(null);
6389
+ const dragging = React42.useRef(false);
6335
6390
  const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
6336
6391
  const R = 108, NR = 80;
6337
6392
  const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
@@ -6404,9 +6459,9 @@ function ClockFace({ value = "09:00", onChange }) {
6404
6459
  }
6405
6460
  function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
6406
6461
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
6407
- const [open2, setOpen] = React41.useState(false);
6408
- const rootRef = React41.useRef(null);
6409
- const boxRef = React41.useRef(null);
6462
+ const [open2, setOpen] = React42.useState(false);
6463
+ const rootRef = React42.useRef(null);
6464
+ const boxRef = React42.useRef(null);
6410
6465
  const disp = () => {
6411
6466
  if (!value) return "";
6412
6467
  const [h, m] = value.split(":").map(Number);
@@ -6449,7 +6504,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
6449
6504
  offset: 6,
6450
6505
  width: 262,
6451
6506
  role: "presentation",
6452
- footer: /* @__PURE__ */ jsxs59(React41.Fragment, { children: [
6507
+ footer: /* @__PURE__ */ jsxs59(React42.Fragment, { children: [
6453
6508
  /* @__PURE__ */ jsx68(
6454
6509
  "button",
6455
6510
  {
@@ -6477,7 +6532,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
6477
6532
  }
6478
6533
 
6479
6534
  // src/components/forms/Slider.tsx
6480
- import * as React42 from "react";
6535
+ import * as React43 from "react";
6481
6536
  import { jsx as jsx69, jsxs as jsxs60 } from "react/jsx-runtime";
6482
6537
  function Slider({
6483
6538
  label,
@@ -6495,7 +6550,7 @@ function Slider({
6495
6550
  ...rest
6496
6551
  }) {
6497
6552
  const fieldId = useFieldId(id);
6498
- const [dragging, setDragging] = React42.useState(false);
6553
+ const [dragging, setDragging] = React43.useState(false);
6499
6554
  const v = value === void 0 ? min : Number(value);
6500
6555
  const pct = max === min ? 0 : (v - min) / (max - min) * 100;
6501
6556
  return /* @__PURE__ */ jsxs60("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
@@ -6529,7 +6584,7 @@ function Slider({
6529
6584
  }
6530
6585
 
6531
6586
  // src/components/forms/RangeSlider.tsx
6532
- import * as React43 from "react";
6587
+ import * as React44 from "react";
6533
6588
  import { jsx as jsx70, jsxs as jsxs61 } from "react/jsx-runtime";
6534
6589
  function RangeSlider({
6535
6590
  label,
@@ -6549,9 +6604,9 @@ function RangeSlider({
6549
6604
  }) {
6550
6605
  const fmt2 = format || ((v) => String(v));
6551
6606
  const [a, b] = value || [min, max];
6552
- const [drag, setDrag] = React43.useState(null);
6553
- const [focus, setFocus] = React43.useState(null);
6554
- const railRef = React43.useRef(null);
6607
+ const [drag, setDrag] = React44.useState(null);
6608
+ const [focus, setFocus] = React44.useState(null);
6609
+ const railRef = React44.useRef(null);
6555
6610
  const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
6556
6611
  const clampPair = (i, v) => {
6557
6612
  v = Math.min(max, Math.max(min, Math.round(v / step) * step));
@@ -6566,7 +6621,7 @@ function RangeSlider({
6566
6621
  const r = railRef.current.getBoundingClientRect();
6567
6622
  return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
6568
6623
  };
6569
- React43.useEffect(() => {
6624
+ React44.useEffect(() => {
6570
6625
  if (drag === null) return;
6571
6626
  const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
6572
6627
  const upH = () => setDrag(null);
@@ -6647,7 +6702,7 @@ function RangeSlider({
6647
6702
  /* @__PURE__ */ jsxs61("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
6648
6703
  /* @__PURE__ */ jsx70("span", { className: "fd-range-rail", ref: railRef }),
6649
6704
  /* @__PURE__ */ jsx70("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
6650
- marks.map((m) => /* @__PURE__ */ jsxs61(React43.Fragment, { children: [
6705
+ marks.map((m) => /* @__PURE__ */ jsxs61(React44.Fragment, { children: [
6651
6706
  /* @__PURE__ */ jsx70("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
6652
6707
  m.label ? /* @__PURE__ */ jsx70("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
6653
6708
  ] }, m.value)),
@@ -6676,7 +6731,7 @@ function RangeSlider({
6676
6731
  }
6677
6732
 
6678
6733
  // src/components/forms/Dropzone.tsx
6679
- import * as React44 from "react";
6734
+ import * as React45 from "react";
6680
6735
  import { jsx as jsx71, jsxs as jsxs62 } from "react/jsx-runtime";
6681
6736
  function Dropzone({
6682
6737
  onFiles,
@@ -6691,8 +6746,8 @@ function Dropzone({
6691
6746
  className = "",
6692
6747
  style
6693
6748
  }) {
6694
- const [over, setOver] = React44.useState(false);
6695
- const depth = React44.useRef(0);
6749
+ const [over, setOver] = React45.useState(false);
6750
+ const depth = React45.useRef(0);
6696
6751
  const has = (e) => {
6697
6752
  const dt = e.dataTransfer;
6698
6753
  if (!dt) return false;
@@ -6754,8 +6809,8 @@ function FilePickButton({
6754
6809
  className = "",
6755
6810
  children
6756
6811
  }) {
6757
- const ref = React44.useRef(null);
6758
- return /* @__PURE__ */ jsxs62(React44.Fragment, { children: [
6812
+ const ref = React45.useRef(null);
6813
+ return /* @__PURE__ */ jsxs62(React45.Fragment, { children: [
6759
6814
  /* @__PURE__ */ jsx71(
6760
6815
  "button",
6761
6816
  {
@@ -6788,10 +6843,10 @@ function FilePickButton({
6788
6843
  }
6789
6844
  function useStagedFiles(upload, opts) {
6790
6845
  const o = opts || {};
6791
- const [items, setItems] = React44.useState([]);
6792
- const controllers = React44.useRef({});
6846
+ const [items, setItems] = React45.useState([]);
6847
+ const controllers = React45.useRef({});
6793
6848
  const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
6794
- const run = React44.useCallback((att) => {
6849
+ const run = React45.useCallback((att) => {
6795
6850
  if (!upload) return;
6796
6851
  const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
6797
6852
  controllers.current[att.id] = ac;
@@ -6808,14 +6863,14 @@ function useStagedFiles(upload, opts) {
6808
6863
  delete controllers.current[att.id];
6809
6864
  });
6810
6865
  }, [upload]);
6811
- const add = React44.useCallback((files) => {
6866
+ const add = React45.useCallback((files) => {
6812
6867
  if (!upload) return [];
6813
6868
  const atts = Array.from(files).map((f) => toAttachment(f));
6814
6869
  setItems((list) => list.concat(atts));
6815
6870
  atts.forEach(run);
6816
6871
  return atts;
6817
6872
  }, [upload, run]);
6818
- const remove = React44.useCallback((att) => {
6873
+ const remove = React45.useCallback((att) => {
6819
6874
  const ac = controllers.current[att.id];
6820
6875
  if (ac) {
6821
6876
  try {
@@ -6826,10 +6881,10 @@ function useStagedFiles(upload, opts) {
6826
6881
  }
6827
6882
  setItems((list) => list.filter((f) => f.id !== att.id));
6828
6883
  }, []);
6829
- const retry = React44.useCallback((att) => {
6884
+ const retry = React45.useCallback((att) => {
6830
6885
  run(att);
6831
6886
  }, [run]);
6832
- const clear = React44.useCallback(() => {
6887
+ const clear = React45.useCallback(() => {
6833
6888
  Object.values(controllers.current).forEach((ac) => {
6834
6889
  try {
6835
6890
  ac && ac.abort();
@@ -6953,7 +7008,7 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
6953
7008
  }
6954
7009
 
6955
7010
  // src/components/forms/MarkdownEditor.tsx
6956
- import * as React45 from "react";
7011
+ import * as React46 from "react";
6957
7012
  import { jsx as jsx73, jsxs as jsxs64 } from "react/jsx-runtime";
6958
7013
  var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
6959
7014
  var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
@@ -7167,7 +7222,7 @@ function syncDom(root, value) {
7167
7222
  while (root.children.length > lines.length) root.removeChild(root.lastChild);
7168
7223
  }
7169
7224
  var LIST_CONT = RE_LI;
7170
- var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7225
+ var MarkdownEditor = React46.forwardRef(function MarkdownEditor2({
7171
7226
  value = "",
7172
7227
  onChange,
7173
7228
  onSubmit,
@@ -7186,10 +7241,10 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7186
7241
  className = "",
7187
7242
  id
7188
7243
  }, ref) {
7189
- const boxRef = React45.useRef(null);
7190
- const composing = React45.useRef(false);
7191
- const pendingCaret = React45.useRef(null);
7192
- React45.useLayoutEffect(() => {
7244
+ const boxRef = React46.useRef(null);
7245
+ const composing = React46.useRef(false);
7246
+ const pendingCaret = React46.useRef(null);
7247
+ React46.useLayoutEffect(() => {
7193
7248
  const root = boxRef.current;
7194
7249
  if (!root || composing.current) return;
7195
7250
  const active = document.activeElement === root || root.contains(document.activeElement);
@@ -7198,7 +7253,7 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7198
7253
  pendingCaret.current = null;
7199
7254
  if (active && caret != null) placeCaret(root, caret);
7200
7255
  }, [value]);
7201
- React45.useEffect(() => {
7256
+ React46.useEffect(() => {
7202
7257
  if (autoFocus && boxRef.current) boxRef.current.focus();
7203
7258
  }, [autoFocus]);
7204
7259
  const caretNow = () => {
@@ -7265,8 +7320,8 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7265
7320
  api.replaceRange(from, to, next, from + next.length);
7266
7321
  }
7267
7322
  };
7268
- React45.useImperativeHandle(ref, () => api);
7269
- const caretAtKeydown = React45.useRef(-1);
7323
+ React46.useImperativeHandle(ref, () => api);
7324
+ const caretAtKeydown = React46.useRef(-1);
7270
7325
  function detect(text, caret) {
7271
7326
  if (!onTrigger) return;
7272
7327
  const upto = text.slice(0, caret);
@@ -7419,7 +7474,7 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
7419
7474
  });
7420
7475
 
7421
7476
  // src/components/forms/CodeEditor.tsx
7422
- import * as React46 from "react";
7477
+ import * as React47 from "react";
7423
7478
  import { EditorView, keymap, lineNumbers, placeholder as cmPlaceholder, drawSelection, Decoration } from "@codemirror/view";
7424
7479
  import { EditorState, StateEffect, StateField, Compartment } from "@codemirror/state";
7425
7480
  import { defaultKeymap, history, historyKeymap, indentMore, indentLess } from "@codemirror/commands";
@@ -7523,16 +7578,16 @@ function CodeEditor({
7523
7578
  const fieldId = useFieldId(id);
7524
7579
  const descId = fieldId + "-desc";
7525
7580
  const liveId = fieldId + "-live";
7526
- const hostRef = React46.useRef(null);
7527
- const viewRef = React46.useRef(null);
7528
- const valueRef = React46.useRef(value);
7529
- const onChangeRef = React46.useRef(onChange);
7581
+ const hostRef = React47.useRef(null);
7582
+ const viewRef = React47.useRef(null);
7583
+ const valueRef = React47.useRef(value);
7584
+ const onChangeRef = React47.useRef(onChange);
7530
7585
  onChangeRef.current = onChange;
7531
- const editableCompartment = React46.useRef(new Compartment()).current;
7532
- const attributesCompartment = React46.useRef(new Compartment()).current;
7533
- const errorRef = React46.useRef(error);
7586
+ const editableCompartment = React47.useRef(new Compartment()).current;
7587
+ const attributesCompartment = React47.useRef(new Compartment()).current;
7588
+ const errorRef = React47.useRef(error);
7534
7589
  errorRef.current = error;
7535
- const diagnosticsCountRef = React46.useRef(diagnostics.length);
7590
+ const diagnosticsCountRef = React47.useRef(diagnostics.length);
7536
7591
  diagnosticsCountRef.current = diagnostics.length;
7537
7592
  function contentAttributes() {
7538
7593
  return {
@@ -7542,9 +7597,9 @@ function CodeEditor({
7542
7597
  ...label ? { "aria-label": label } : {}
7543
7598
  };
7544
7599
  }
7545
- React46.useEffect(() => {
7546
- const host = hostRef.current;
7547
- if (!host) return;
7600
+ React47.useEffect(() => {
7601
+ const host2 = hostRef.current;
7602
+ if (!host2) return;
7548
7603
  const updateListener = EditorView.updateListener.of((update) => {
7549
7604
  if (!update.docChanged) return;
7550
7605
  const next = update.state.doc.toString();
@@ -7576,7 +7631,7 @@ function CodeEditor({
7576
7631
  attributesCompartment.of(EditorView.contentAttributes.of(contentAttributes()))
7577
7632
  ]
7578
7633
  });
7579
- const view = new EditorView({ state, parent: host });
7634
+ const view = new EditorView({ state, parent: host2 });
7580
7635
  viewRef.current = view;
7581
7636
  if (autoFocus) view.focus();
7582
7637
  return () => {
@@ -7584,7 +7639,7 @@ function CodeEditor({
7584
7639
  viewRef.current = null;
7585
7640
  };
7586
7641
  }, []);
7587
- React46.useEffect(() => {
7642
+ React47.useEffect(() => {
7588
7643
  const view = viewRef.current;
7589
7644
  if (!view) return;
7590
7645
  const current2 = view.state.doc.toString();
@@ -7593,12 +7648,12 @@ function CodeEditor({
7593
7648
  }
7594
7649
  valueRef.current = value;
7595
7650
  }, [value]);
7596
- React46.useEffect(() => {
7651
+ React47.useEffect(() => {
7597
7652
  const view = viewRef.current;
7598
7653
  if (!view) return;
7599
7654
  view.dispatch({ effects: editableCompartment.reconfigure(EditorView.editable.of(!disabled)) });
7600
7655
  }, [disabled, editableCompartment]);
7601
- React46.useEffect(() => {
7656
+ React47.useEffect(() => {
7602
7657
  const view = viewRef.current;
7603
7658
  if (!view) return;
7604
7659
  view.dispatch({
@@ -7656,16 +7711,16 @@ function CodeEditor({
7656
7711
  }
7657
7712
 
7658
7713
  // src/components/platform/AccountMenu.tsx
7659
- import * as React48 from "react";
7714
+ import * as React49 from "react";
7660
7715
 
7661
7716
  // src/kits/sessionContext.tsx
7662
- import * as React47 from "react";
7663
- var SessionContext = React47.createContext(null);
7717
+ import * as React48 from "react";
7718
+ var SessionContext = React48.createContext(null);
7664
7719
  function SessionProvider({ value, children }) {
7665
- return React47.createElement(SessionContext.Provider, { value }, children);
7720
+ return React48.createElement(SessionContext.Provider, { value }, children);
7666
7721
  }
7667
7722
  function useSessionContext() {
7668
- const ctx = React47.useContext(SessionContext);
7723
+ const ctx = React48.useContext(SessionContext);
7669
7724
  if (!ctx) {
7670
7725
  throw new Error(
7671
7726
  "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."
@@ -7705,11 +7760,11 @@ function AccountMenu({
7705
7760
  ...rest
7706
7761
  }) {
7707
7762
  const { user, roles, can: can2, signOut: ctxSignOut, demo, pending } = useSessionContext();
7708
- const [open2, setOpen] = React48.useState(false);
7709
- const [switching, setSwitching] = React48.useState(false);
7710
- const [signingOut, setSigningOut] = React48.useState(false);
7711
- const [signOutError, setSignOutError] = React48.useState(null);
7712
- const ref = React48.useRef(null);
7763
+ const [open2, setOpen] = React49.useState(false);
7764
+ const [switching, setSwitching] = React49.useState(false);
7765
+ const [signingOut, setSigningOut] = React49.useState(false);
7766
+ const [signOutError, setSignOutError] = React49.useState(null);
7767
+ const ref = React49.useRef(null);
7713
7768
  const visibleLinks = links.filter((l) => !l.perm || !pending && can2(l.perm));
7714
7769
  const visibleGroups = groups.map((g) => ({ label: g.label, links: g.links.filter((l) => !l.perm || !pending && can2(l.perm)) })).filter((g) => g.links.length);
7715
7770
  const closeMenu = () => {
@@ -7834,13 +7889,13 @@ function AccountMenu({
7834
7889
  }
7835
7890
 
7836
7891
  // src/components/platform/AppSwitcher.tsx
7837
- import * as React49 from "react";
7892
+ import * as React50 from "react";
7838
7893
  import { jsx as jsx76, jsxs as jsxs67 } from "react/jsx-runtime";
7839
7894
  function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
7840
7895
  const { apps: contextApps } = useSessionContext();
7841
7896
  const apps = appsProp ?? contextApps ?? [];
7842
- const [open2, setOpen] = React49.useState(false);
7843
- const anchorRef = React49.useRef(null);
7897
+ const [open2, setOpen] = React50.useState(false);
7898
+ const anchorRef = React50.useRef(null);
7844
7899
  if (!apps.length) return null;
7845
7900
  const items = apps.map((app) => ({
7846
7901
  id: app.key,
@@ -7854,7 +7909,7 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
7854
7909
  window.location.href = app.url;
7855
7910
  }
7856
7911
  }));
7857
- return /* @__PURE__ */ jsxs67(React49.Fragment, { children: [
7912
+ return /* @__PURE__ */ jsxs67(React50.Fragment, { children: [
7858
7913
  /* @__PURE__ */ jsx76("span", { ref: anchorRef, className: ["fd-appswitch-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx76(
7859
7914
  IconButton,
7860
7915
  {
@@ -7883,10 +7938,10 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
7883
7938
  }
7884
7939
 
7885
7940
  // src/components/platform/AppearanceMenu.tsx
7886
- import * as React51 from "react";
7941
+ import * as React52 from "react";
7887
7942
 
7888
7943
  // src/kits/appearance.ts
7889
- import * as React50 from "react";
7944
+ import * as React51 from "react";
7890
7945
  var DEFAULT_STORAGE_KEY = "fd-appearance";
7891
7946
  var DEFAULT_PREFS = {
7892
7947
  theme: "system",
@@ -7981,11 +8036,11 @@ function applyPrefs(prefs, root = document.documentElement) {
7981
8036
  else root.removeAttribute("data-motion");
7982
8037
  }
7983
8038
  function useAppearancePrefs(store) {
7984
- const prefs = React50.useSyncExternalStore(store.subscribe, store.getSnapshot);
7985
- React50.useEffect(() => {
8039
+ const prefs = React51.useSyncExternalStore(store.subscribe, store.getSnapshot);
8040
+ React51.useEffect(() => {
7986
8041
  applyPrefs(prefs);
7987
8042
  }, [prefs]);
7988
- React50.useEffect(() => {
8043
+ React51.useEffect(() => {
7989
8044
  if (prefs.theme !== "system" || typeof window === "undefined" || typeof window.matchMedia !== "function") {
7990
8045
  return;
7991
8046
  }
@@ -7994,7 +8049,7 @@ function useAppearancePrefs(store) {
7994
8049
  mq.addEventListener("change", onChange);
7995
8050
  return () => mq.removeEventListener("change", onChange);
7996
8051
  }, [prefs]);
7997
- const update = React50.useCallback(
8052
+ const update = React51.useCallback(
7998
8053
  (patch) => {
7999
8054
  store.write({ ...store.getSnapshot(), ...patch });
8000
8055
  },
@@ -8017,15 +8072,15 @@ var TEXT_SCALE_OPTIONS = [
8017
8072
  { value: "xl", label: "XL" }
8018
8073
  ];
8019
8074
  function AppearanceMenu({ className = "", store: storeProp, storageKey, storage, defaults }) {
8020
- const store = React51.useMemo(
8075
+ const store = React52.useMemo(
8021
8076
  () => storeProp ?? createLocalStorageAppearanceStore({ storageKey, storage, defaults }),
8022
8077
  [storeProp, storageKey, storage, defaults]
8023
8078
  );
8024
8079
  const [prefs, update] = useAppearancePrefs(store);
8025
- const [open2, setOpen] = React51.useState(false);
8026
- const anchorRef = React51.useRef(null);
8080
+ const [open2, setOpen] = React52.useState(false);
8081
+ const anchorRef = React52.useRef(null);
8027
8082
  const patch = (p) => update(p);
8028
- return /* @__PURE__ */ jsxs68(React51.Fragment, { children: [
8083
+ return /* @__PURE__ */ jsxs68(React52.Fragment, { children: [
8029
8084
  /* @__PURE__ */ jsx77("span", { ref: anchorRef, className: ["fd-appearance-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx77(
8030
8085
  IconButton,
8031
8086
  {
@@ -8094,14 +8149,14 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
8094
8149
  }
8095
8150
 
8096
8151
  // src/components/platform/ApiSpecBrowser.tsx
8097
- import * as React52 from "react";
8152
+ import * as React53 from "react";
8098
8153
  import { jsx as jsx78, jsxs as jsxs69 } from "react/jsx-runtime";
8099
8154
  var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
8100
8155
  function Json({ obj }) {
8101
8156
  return /* @__PURE__ */ jsx78("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
8102
8157
  }
8103
8158
  function Endpoint({ s, onRequest }) {
8104
- const [tried, setTried] = React52.useState(null);
8159
+ const [tried, setTried] = React53.useState(null);
8105
8160
  const run = async () => {
8106
8161
  setTried("busy");
8107
8162
  const t0 = (window.performance || Date).now();
@@ -8174,10 +8229,10 @@ function ApiSpecBrowser({
8174
8229
  className = "",
8175
8230
  ...rest
8176
8231
  }) {
8177
- const [q, setQ] = React52.useState("");
8178
- const [method, setMethod] = React52.useState(null);
8179
- const [mod, setMod] = React52.useState(null);
8180
- const [listOnly, setListOnly] = React52.useState(false);
8232
+ const [q, setQ] = React53.useState("");
8233
+ const [method, setMethod] = React53.useState(null);
8234
+ const [mod, setMod] = React53.useState(null);
8235
+ const [listOnly, setListOnly] = React53.useState(false);
8181
8236
  const activeModule = modules && modules.find((m) => m.id === mod);
8182
8237
  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())));
8183
8238
  const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
@@ -8256,7 +8311,7 @@ function ApiSpecBrowser({
8256
8311
  }
8257
8312
 
8258
8313
  // src/components/platform/ProfilePage.tsx
8259
- import * as React53 from "react";
8314
+ import * as React54 from "react";
8260
8315
  import { jsx as jsx79, jsxs as jsxs70 } from "react/jsx-runtime";
8261
8316
  function fieldInitialValue(field, user) {
8262
8317
  if (field.value) return field.value(user);
@@ -8292,21 +8347,21 @@ function ProfilePage({
8292
8347
  }) {
8293
8348
  const { user: sessionUser, roles, permissions, saveProfile: saveProfile2 } = useSessionContext();
8294
8349
  const user = userProp || sessionUser;
8295
- const initialFieldValues = React53.useMemo(() => {
8350
+ const initialFieldValues = React54.useMemo(() => {
8296
8351
  const values2 = {};
8297
8352
  for (const field of fields) values2[field.key] = fieldInitialValue(field, user);
8298
8353
  return values2;
8299
8354
  }, [user.id, fields]);
8300
- const initialNotify = React53.useMemo(() => {
8355
+ const initialNotify = React54.useMemo(() => {
8301
8356
  const values2 = {};
8302
8357
  for (const n of notifications) values2[n.key] = !!user.notify?.[n.key];
8303
8358
  return values2;
8304
8359
  }, [user.id, notifications]);
8305
- const [values, setValues] = React53.useState(initialFieldValues);
8306
- const [notify, setNotify] = React53.useState(initialNotify);
8307
- const [saving, setSaving] = React53.useState(false);
8308
- const [saved, setSaved] = React53.useState(false);
8309
- const [prevUserId, setPrevUserId] = React53.useState(user.id);
8360
+ const [values, setValues] = React54.useState(initialFieldValues);
8361
+ const [notify, setNotify] = React54.useState(initialNotify);
8362
+ const [saving, setSaving] = React54.useState(false);
8363
+ const [saved, setSaved] = React54.useState(false);
8364
+ const [prevUserId, setPrevUserId] = React54.useState(user.id);
8310
8365
  if (user.id !== prevUserId) {
8311
8366
  setPrevUserId(user.id);
8312
8367
  setValues(initialFieldValues);
@@ -8494,11 +8549,11 @@ function ProfilePage({
8494
8549
  }
8495
8550
 
8496
8551
  // src/components/platform/SignInPage.tsx
8497
- import * as React54 from "react";
8552
+ import * as React55 from "react";
8498
8553
  import { Fragment as Fragment19, jsx as jsx80, jsxs as jsxs71 } from "react/jsx-runtime";
8499
8554
  function SignInPage({ productName, onSignIn, continueAs, error }) {
8500
- const [signingIn, setSigningIn] = React54.useState(false);
8501
- const [resuming, setResuming] = React54.useState(false);
8555
+ const [signingIn, setSigningIn] = React55.useState(false);
8556
+ const [resuming, setResuming] = React55.useState(false);
8502
8557
  function handleSignIn() {
8503
8558
  setSigningIn(true);
8504
8559
  onSignIn();
@@ -8687,10 +8742,10 @@ function GoogleGlyph() {
8687
8742
  }
8688
8743
 
8689
8744
  // src/components/platform/RoadmapTimeline.tsx
8690
- import * as React57 from "react";
8745
+ import * as React58 from "react";
8691
8746
 
8692
8747
  // src/kits/session.ts
8693
- import * as React55 from "react";
8748
+ import * as React56 from "react";
8694
8749
  var PERMISSION_CATALOG = [
8695
8750
  { group: "Plans", items: [
8696
8751
  { key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
@@ -10257,8 +10312,8 @@ function roadmap(overrides) {
10257
10312
  };
10258
10313
  }
10259
10314
  function useSession() {
10260
- const [s, setS] = React55.useState(getSession);
10261
- React55.useEffect(() => subscribe(setS), []);
10315
+ const [s, setS] = React56.useState(getSession);
10316
+ React56.useEffect(() => subscribe(setS), []);
10262
10317
  return s;
10263
10318
  }
10264
10319
  var SessionKit = {
@@ -10291,7 +10346,7 @@ var SessionKit = {
10291
10346
  };
10292
10347
  function DemoSessionProvider({ children }) {
10293
10348
  const session = useSession();
10294
- const value = React55.useMemo(
10349
+ const value = React56.useMemo(
10295
10350
  () => ({
10296
10351
  user: session.user,
10297
10352
  roles: session.roles,
@@ -10307,11 +10362,11 @@ function DemoSessionProvider({ children }) {
10307
10362
  }),
10308
10363
  [session]
10309
10364
  );
10310
- return React55.createElement(SessionProvider, { value }, children);
10365
+ return React56.createElement(SessionProvider, { value }, children);
10311
10366
  }
10312
10367
 
10313
10368
  // src/kits/runtime.ts
10314
- import * as React56 from "react";
10369
+ import * as React57 from "react";
10315
10370
  var WIRED_ENDPOINTS = [
10316
10371
  // Nothing yet. Every id below would come from a real service:
10317
10372
  // "plan.get", "placements.list", …
@@ -10482,8 +10537,8 @@ var RuntimeKit = {
10482
10537
  };
10483
10538
  RuntimeKit.declare(FEATURE_NEEDS);
10484
10539
  function useRuntimeMode() {
10485
- const [m, setM] = React56.useState(RuntimeKit.getMode());
10486
- React56.useEffect(() => RuntimeKit.subscribe(setM), []);
10540
+ const [m, setM] = React57.useState(RuntimeKit.getMode());
10541
+ React57.useEffect(() => RuntimeKit.subscribe(setM), []);
10487
10542
  return m;
10488
10543
  }
10489
10544
  function useFeatureStatus(key) {
@@ -10566,12 +10621,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
10566
10621
  }
10567
10622
  function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10568
10623
  const session = SessionKit.useSession();
10569
- const [project, setProject] = React57.useState("");
10570
- const [q, setQ] = React57.useState("");
10571
- const scrollRef = React57.useRef(null);
10572
- const nowRef = React57.useRef(null);
10573
- const rm = React57.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
10574
- const byKey = React57.useMemo(() => {
10624
+ const [project, setProject] = React58.useState("");
10625
+ const [q, setQ] = React58.useState("");
10626
+ const scrollRef = React58.useRef(null);
10627
+ const nowRef = React58.useRef(null);
10628
+ const rm = React58.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
10629
+ const byKey = React58.useMemo(() => {
10575
10630
  const m = {};
10576
10631
  rm.items.forEach((i) => {
10577
10632
  m[i.key] = i;
@@ -10580,7 +10635,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10580
10635
  }, [rm]);
10581
10636
  const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
10582
10637
  const projects = [...new Set(rm.items.map((i) => i.project))];
10583
- React57.useEffect(() => {
10638
+ React58.useEffect(() => {
10584
10639
  let raf1 = 0, raf2 = 0;
10585
10640
  const place = () => {
10586
10641
  const box = scrollRef.current, mark = nowRef.current;
@@ -10654,7 +10709,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10654
10709
  lastPhase = item.phase;
10655
10710
  const inPhase = items.filter((i) => i.phase === item.phase).length;
10656
10711
  const isBoundary = n === firstPending;
10657
- return /* @__PURE__ */ jsxs72(React57.Fragment, { children: [
10712
+ return /* @__PURE__ */ jsxs72(React58.Fragment, { children: [
10658
10713
  showPhase ? /* @__PURE__ */ jsxs72("div", { className: "fd-rm-era", children: [
10659
10714
  /* @__PURE__ */ jsxs72("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
10660
10715
  /* @__PURE__ */ jsx81("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
@@ -10698,8 +10753,8 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10698
10753
  }
10699
10754
 
10700
10755
  // src/components/platform/ComingSoon.tsx
10701
- import * as React58 from "react";
10702
- import { createPortal as createPortal5 } from "react-dom";
10756
+ import * as React59 from "react";
10757
+ import { createPortal as createPortal6 } from "react-dom";
10703
10758
  import { Fragment as Fragment21, jsx as jsx82, jsxs as jsxs73 } from "react/jsx-runtime";
10704
10759
  var BYPASS_STORE = "fd.soon.bypass.v1";
10705
10760
  function readBypassed() {
@@ -10716,8 +10771,8 @@ function writeBypassed(list) {
10716
10771
  }
10717
10772
  }
10718
10773
  function useBypass(key) {
10719
- const [on, setOn] = React58.useState(() => !!key && readBypassed().indexOf(key) >= 0);
10720
- React58.useEffect(() => {
10774
+ const [on, setOn] = React59.useState(() => !!key && readBypassed().indexOf(key) >= 0);
10775
+ React59.useEffect(() => {
10721
10776
  setOn(!!key && readBypassed().indexOf(key) >= 0);
10722
10777
  }, [key]);
10723
10778
  const set = (next) => {
@@ -10764,9 +10819,9 @@ function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onB
10764
10819
  ] });
10765
10820
  }
10766
10821
  function useHoverCard(open2) {
10767
- const anchor = React58.useRef(null);
10768
- const [pos, setPos] = React58.useState(null);
10769
- React58.useLayoutEffect(() => {
10822
+ const anchor = React59.useRef(null);
10823
+ const [pos, setPos] = React59.useState(null);
10824
+ React59.useLayoutEffect(() => {
10770
10825
  if (!open2 || !anchor.current) {
10771
10826
  setPos(null);
10772
10827
  return;
@@ -10893,12 +10948,12 @@ function ComingSoon({
10893
10948
  ] });
10894
10949
  }
10895
10950
  function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
10896
- const [open2, setOpen] = React58.useState(false);
10951
+ const [open2, setOpen] = React59.useState(false);
10897
10952
  const [anchor, pos] = useHoverCard(open2);
10898
- const hoverCardRef = React58.useRef(null);
10953
+ const hoverCardRef = React59.useRef(null);
10899
10954
  const hoverLayer = useStackedLayer({ active: open2, containerRef: hoverCardRef, returnFocus: false });
10900
10955
  const zIndex = useLayerZIndex(hoverLayer);
10901
- const close2 = React58.useRef(null);
10956
+ const close2 = React59.useRef(null);
10902
10957
  const show = () => {
10903
10958
  if (close2.current) {
10904
10959
  clearTimeout(close2.current);
@@ -10914,7 +10969,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
10914
10969
  setOpen(false);
10915
10970
  }, 140);
10916
10971
  };
10917
- React58.useEffect(() => () => {
10972
+ React59.useEffect(() => () => {
10918
10973
  if (close2.current) clearTimeout(close2.current);
10919
10974
  }, []);
10920
10975
  return /* @__PURE__ */ jsxs73(
@@ -10943,7 +10998,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
10943
10998
  children: /* @__PURE__ */ jsx82("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
10944
10999
  }
10945
11000
  ),
10946
- open2 && pos ? createPortal5(
11001
+ open2 && pos ? createPortal6(
10947
11002
  /* @__PURE__ */ jsx82(
10948
11003
  "div",
10949
11004
  {
@@ -11366,7 +11421,7 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
11366
11421
  }
11367
11422
 
11368
11423
  // src/components/planner/MixGap.tsx
11369
- import * as React59 from "react";
11424
+ import * as React60 from "react";
11370
11425
  import { Fragment as Fragment23, jsx as jsx87, jsxs as jsxs78 } from "react/jsx-runtime";
11371
11426
  var MIX_GAP_LAYOUT = {
11372
11427
  trackHeight: 30,
@@ -11381,7 +11436,7 @@ function mixGapOffset(value, max) {
11381
11436
  }
11382
11437
  function MixGap({ rows = [], loading = false, className = "" }) {
11383
11438
  const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
11384
- const [hover, setHover] = React59.useState(null);
11439
+ const [hover, setHover] = React60.useState(null);
11385
11440
  const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
11386
11441
  const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
11387
11442
  const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
@@ -11524,7 +11579,7 @@ function ChannelContribution({
11524
11579
  }
11525
11580
 
11526
11581
  // src/components/planner/BudgetReallocator.tsx
11527
- import * as React60 from "react";
11582
+ import * as React61 from "react";
11528
11583
  import { Fragment as Fragment24, jsx as jsx89, jsxs as jsxs80 } from "react/jsx-runtime";
11529
11584
  var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
11530
11585
  function BudgetReallocator({
@@ -11540,8 +11595,8 @@ function BudgetReallocator({
11540
11595
  onCancel,
11541
11596
  className = ""
11542
11597
  }) {
11543
- const [draft, setDraft] = React60.useState(spend);
11544
- React60.useEffect(() => setDraft(spend), [spend]);
11598
+ const [draft, setDraft] = React61.useState(spend);
11599
+ React61.useEffect(() => setDraft(spend), [spend]);
11545
11600
  const dirty = draft !== spend;
11546
11601
  const nextCrp = scoreFor ? scoreFor(draft) : crp;
11547
11602
  const nextBand = bandFor(nextCrp);
@@ -11556,10 +11611,10 @@ function BudgetReallocator({
11556
11611
  setDraft(spend);
11557
11612
  if (onCancel) onCancel();
11558
11613
  };
11559
- const trackRef = React60.useRef(null);
11560
- const chipRef = React60.useRef(null);
11561
- const [chipLeft, setChipLeft] = React60.useState(null);
11562
- React60.useLayoutEffect(() => {
11614
+ const trackRef = React61.useRef(null);
11615
+ const chipRef = React61.useRef(null);
11616
+ const [chipLeft, setChipLeft] = React61.useState(null);
11617
+ React61.useLayoutEffect(() => {
11563
11618
  const track = trackRef.current;
11564
11619
  if (!dirty || !track) {
11565
11620
  setChipLeft(null);
@@ -11747,7 +11802,7 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "", d
11747
11802
  }
11748
11803
 
11749
11804
  // src/components/planner/PreferenceMeter.tsx
11750
- import * as React61 from "react";
11805
+ import * as React62 from "react";
11751
11806
  import { jsx as jsx92, jsxs as jsxs83 } from "react/jsx-runtime";
11752
11807
  function preferenceScore(criteria) {
11753
11808
  const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
@@ -11777,7 +11832,7 @@ function PreferenceMeter({
11777
11832
  className = ""
11778
11833
  }) {
11779
11834
  const value = score == null ? preferenceScore(criteria) : score;
11780
- const segments = React61.useMemo(() => preferenceSegments(criteria), [criteria]);
11835
+ const segments = React62.useMemo(() => preferenceSegments(criteria), [criteria]);
11781
11836
  return /* @__PURE__ */ jsx92(
11782
11837
  ScoreMeter,
11783
11838
  {
@@ -11816,10 +11871,10 @@ function PreferenceMeter({
11816
11871
  }
11817
11872
 
11818
11873
  // src/components/chat/AgentChatPanel.tsx
11819
- import * as React67 from "react";
11874
+ import * as React68 from "react";
11820
11875
 
11821
11876
  // src/components/chat/chatEngine.ts
11822
- import * as React62 from "react";
11877
+ import * as React63 from "react";
11823
11878
  var CHAT_UNAVAILABLE = "chat_unavailable";
11824
11879
  var JOB_PENDING = ["queued", "running"];
11825
11880
  var JOB_SUCCESS = ["completed", "recovered"];
@@ -11873,22 +11928,22 @@ function useChatEngine(opts) {
11873
11928
  onClear,
11874
11929
  onFeedback
11875
11930
  } = opts || {};
11876
- const [status, setStatus] = React62.useState("idle");
11877
- const [threadId, setThreadId] = React62.useState(null);
11878
- const [messages, setMessages] = React62.useState([]);
11879
- const [queue, setQueue] = React62.useState([]);
11880
- const [fatal, setFatal] = React62.useState(null);
11881
- const [busy, setBusy] = React62.useState(false);
11882
- const [turnStartedAt, setTurnStartedAt] = React62.useState(null);
11883
- const listRef = React62.useRef([]);
11884
- const queueRef = React62.useRef([]);
11885
- const busyRef = React62.useRef(false);
11886
- const stoppedRef = React62.useRef(false);
11887
- const abortRef = React62.useRef(null);
11888
- const serverCount = React62.useRef(0);
11889
- const threadRef = React62.useRef(null);
11890
- const mounted = React62.useRef(true);
11891
- React62.useEffect(() => {
11931
+ const [status, setStatus] = React63.useState("idle");
11932
+ const [threadId, setThreadId] = React63.useState(null);
11933
+ const [messages, setMessages] = React63.useState([]);
11934
+ const [queue, setQueue] = React63.useState([]);
11935
+ const [fatal, setFatal] = React63.useState(null);
11936
+ const [busy, setBusy] = React63.useState(false);
11937
+ const [turnStartedAt, setTurnStartedAt] = React63.useState(null);
11938
+ const listRef = React63.useRef([]);
11939
+ const queueRef = React63.useRef([]);
11940
+ const busyRef = React63.useRef(false);
11941
+ const stoppedRef = React63.useRef(false);
11942
+ const abortRef = React63.useRef(null);
11943
+ const serverCount = React63.useRef(0);
11944
+ const threadRef = React63.useRef(null);
11945
+ const mounted = React63.useRef(true);
11946
+ React63.useEffect(() => {
11892
11947
  mounted.current = true;
11893
11948
  return () => {
11894
11949
  mounted.current = false;
@@ -11910,14 +11965,14 @@ function useChatEngine(opts) {
11910
11965
  }
11911
11966
  return false;
11912
11967
  };
11913
- const loadThread = React62.useCallback(async (id) => {
11968
+ const loadThread = React63.useCallback(async (id) => {
11914
11969
  const data = await apiAdapter.getThread(id);
11915
11970
  const list = [...data && data.messages || []];
11916
11971
  serverCount.current = list.length;
11917
11972
  commit(list);
11918
11973
  return list;
11919
11974
  }, [apiAdapter]);
11920
- React62.useEffect(() => {
11975
+ React63.useEffect(() => {
11921
11976
  if (!apiAdapter) {
11922
11977
  setStatus("idle");
11923
11978
  setFatal(null);
@@ -12130,7 +12185,7 @@ function useChatEngine(opts) {
12130
12185
  await dispatchTurn(turn);
12131
12186
  }
12132
12187
  }
12133
- const send = React62.useCallback((text, attachments) => {
12188
+ const send = React63.useCallback((text, attachments) => {
12134
12189
  const body = (text || "").trim();
12135
12190
  if (!body && !(attachments && attachments.length)) return;
12136
12191
  if (status === "disconnected") return;
@@ -12140,7 +12195,7 @@ function useChatEngine(opts) {
12140
12195
  stoppedRef.current = false;
12141
12196
  drain();
12142
12197
  }, [status]);
12143
- const stop = React62.useCallback(() => {
12198
+ const stop = React63.useCallback(() => {
12144
12199
  stoppedRef.current = true;
12145
12200
  const ac = abortRef.current;
12146
12201
  if (ac) {
@@ -12159,11 +12214,11 @@ function useChatEngine(opts) {
12159
12214
  store.del(STORAGE_PREFIX + threadRef.current);
12160
12215
  }
12161
12216
  }, [apiAdapter]);
12162
- const removeQueued = React62.useCallback((id) => {
12217
+ const removeQueued = React63.useCallback((id) => {
12163
12218
  queueRef.current = queueRef.current.filter((t) => t.id !== id);
12164
12219
  setQueue(queueRef.current.slice());
12165
12220
  }, []);
12166
- const retry = React62.useCallback(() => {
12221
+ const retry = React63.useCallback(() => {
12167
12222
  const list = listRef.current;
12168
12223
  let at = -1;
12169
12224
  for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
@@ -12179,19 +12234,19 @@ function useChatEngine(opts) {
12179
12234
  setQueue(queueRef.current.slice());
12180
12235
  drain();
12181
12236
  }, []);
12182
- const clear = React62.useCallback(() => {
12237
+ const clear = React63.useCallback(() => {
12183
12238
  commit([]);
12184
12239
  serverCount.current = 0;
12185
12240
  queueRef.current = [];
12186
12241
  setQueue([]);
12187
12242
  onClear && onClear();
12188
12243
  }, [onClear]);
12189
- const setFeedback = React62.useCallback((id, value) => {
12244
+ const setFeedback = React63.useCallback((id, value) => {
12190
12245
  patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
12191
12246
  const msg = listRef.current.find((m) => m.id === id);
12192
12247
  onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
12193
12248
  }, [onFeedback]);
12194
- const reload = React62.useCallback(async () => {
12249
+ const reload = React63.useCallback(async () => {
12195
12250
  if (!threadRef.current) return;
12196
12251
  setStatus("loading");
12197
12252
  try {
@@ -12229,10 +12284,10 @@ var ChatKit = {
12229
12284
  };
12230
12285
 
12231
12286
  // src/components/chat/ChatTranscript.tsx
12232
- import * as React64 from "react";
12287
+ import * as React65 from "react";
12233
12288
 
12234
12289
  // src/components/chat/ChatTurn.tsx
12235
- import * as React63 from "react";
12290
+ import * as React64 from "react";
12236
12291
  import { jsx as jsx93, jsxs as jsxs84 } from "react/jsx-runtime";
12237
12292
  function JsonView({ value }) {
12238
12293
  let text;
@@ -12269,7 +12324,7 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
12269
12324
  ] });
12270
12325
  }
12271
12326
  function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
12272
- const [open2, setOpen] = React63.useState(defaultOpen);
12327
+ const [open2, setOpen] = React64.useState(defaultOpen);
12273
12328
  if (!text) return null;
12274
12329
  return /* @__PURE__ */ jsxs84("div", { className: "fdc-think" + (open2 ? " is-open" : ""), children: [
12275
12330
  /* @__PURE__ */ jsxs84("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
@@ -12286,7 +12341,7 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
12286
12341
  ] });
12287
12342
  }
12288
12343
  function Citations({ items = [], onOpen }) {
12289
- const [open2, setOpen] = React63.useState(false);
12344
+ const [open2, setOpen] = React64.useState(false);
12290
12345
  if (!items.length) return null;
12291
12346
  return /* @__PURE__ */ jsxs84("div", { className: "fdc-cites", children: [
12292
12347
  /* @__PURE__ */ jsxs84("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
@@ -12312,7 +12367,7 @@ function clampText(text, max) {
12312
12367
  return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
12313
12368
  }
12314
12369
  function MessageBody({ message: m, ctx }) {
12315
- const [expanded, setExpanded] = React63.useState(false);
12370
+ const [expanded, setExpanded] = React64.useState(false);
12316
12371
  const isUser = m.role === "user";
12317
12372
  const raw = m.text || "";
12318
12373
  const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
@@ -12392,7 +12447,7 @@ function RunActions({ group, ctx }) {
12392
12447
  ] }),
12393
12448
  isAssistant && ctx.onRetry ? /* @__PURE__ */ jsx93("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ jsx93("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
12394
12449
  group.role === "user" && ctx.onEdit ? /* @__PURE__ */ jsx93("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ jsx93("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
12395
- isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs84(React63.Fragment, { children: [
12450
+ isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs84(React64.Fragment, { children: [
12396
12451
  /* @__PURE__ */ jsx93("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__ */ jsx93("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
12397
12452
  /* @__PURE__ */ jsx93("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__ */ jsx93("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
12398
12453
  ] }) : null,
@@ -12487,10 +12542,10 @@ function ChatTranscript({
12487
12542
  renderEmpty,
12488
12543
  className = ""
12489
12544
  }) {
12490
- const scroller = React64.useRef(null);
12491
- const stick = React64.useRef(true);
12492
- const [pill, setPill] = React64.useState(0);
12493
- const seen = React64.useRef(0);
12545
+ const scroller = React65.useRef(null);
12546
+ const stick = React65.useRef(true);
12547
+ const [pill, setPill] = React65.useState(0);
12548
+ const seen = React65.useRef(0);
12494
12549
  const toBottom = (smooth) => {
12495
12550
  const el = scroller.current;
12496
12551
  if (!el) return;
@@ -12509,7 +12564,7 @@ function ChatTranscript({
12509
12564
  seen.current = messages.length;
12510
12565
  }
12511
12566
  };
12512
- React64.useLayoutEffect(() => {
12567
+ React65.useLayoutEffect(() => {
12513
12568
  const el = scroller.current;
12514
12569
  if (!el) return;
12515
12570
  if (stick.current) {
@@ -12517,7 +12572,7 @@ function ChatTranscript({
12517
12572
  seen.current = messages.length;
12518
12573
  } else setPill(Math.max(0, messages.length - seen.current));
12519
12574
  }, [messages]);
12520
- React64.useEffect(() => {
12575
+ React65.useEffect(() => {
12521
12576
  const el = scroller.current;
12522
12577
  const inner = el && el.firstChild;
12523
12578
  if (!el || !inner || typeof ResizeObserver === "undefined") return;
@@ -12527,7 +12582,7 @@ function ChatTranscript({
12527
12582
  ro.observe(inner);
12528
12583
  return () => ro.disconnect();
12529
12584
  }, []);
12530
- const groups = React64.useMemo(() => groupMessages(messages), [messages]);
12585
+ const groups = React65.useMemo(() => groupMessages(messages), [messages]);
12531
12586
  const empty = !messages.length && status === "ready";
12532
12587
  return /* @__PURE__ */ jsxs85("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
12533
12588
  /* @__PURE__ */ jsxs85("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
@@ -12551,7 +12606,7 @@ function ChatTranscript({
12551
12606
  const prev = groups[i - 1];
12552
12607
  const k = dayKey(g.messages[0].timestamp);
12553
12608
  const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
12554
- return /* @__PURE__ */ jsxs85(React64.Fragment, { children: [
12609
+ return /* @__PURE__ */ jsxs85(React65.Fragment, { children: [
12555
12610
  showDay ? /* @__PURE__ */ jsx94("div", { className: "fdc-day", children: /* @__PURE__ */ jsx94("span", { children: dayLabel(k) }) }) : null,
12556
12611
  /* @__PURE__ */ jsx94(ChatTurn, { group: g, ctx })
12557
12612
  ] }, g.key || i);
@@ -12568,7 +12623,7 @@ function ChatTranscript({
12568
12623
  var TranscriptKit = { groupMessages };
12569
12624
 
12570
12625
  // src/components/chat/ChatComposer.tsx
12571
- import * as React65 from "react";
12626
+ import * as React66 from "react";
12572
12627
  import { jsx as jsx95, jsxs as jsxs86 } from "react/jsx-runtime";
12573
12628
  function ChatComposer({
12574
12629
  onSubmit,
@@ -12596,17 +12651,17 @@ function ChatComposer({
12596
12651
  onReject,
12597
12652
  onOpenAttachment
12598
12653
  }) {
12599
- const [text, setText] = React65.useState(draft || "");
12600
- const [trigger, setTrigger] = React65.useState(null);
12601
- const [mentionItems, setMentionItems] = React65.useState([]);
12602
- const [listening, setListening] = React65.useState(false);
12603
- const [notice, setNotice] = React65.useState(null);
12604
- const editor = React65.useRef(null);
12605
- const wrap = React65.useRef(null);
12606
- const stopVoice = React65.useRef(null);
12654
+ const [text, setText] = React66.useState(draft || "");
12655
+ const [trigger, setTrigger] = React66.useState(null);
12656
+ const [mentionItems, setMentionItems] = React66.useState([]);
12657
+ const [listening, setListening] = React66.useState(false);
12658
+ const [notice, setNotice] = React66.useState(null);
12659
+ const editor = React66.useRef(null);
12660
+ const wrap = React66.useRef(null);
12661
+ const stopVoice = React66.useRef(null);
12607
12662
  const staged = useStagedFiles(fileUploadHandler, { onError: () => {
12608
12663
  } });
12609
- React65.useEffect(() => {
12664
+ React66.useEffect(() => {
12610
12665
  if (draft != null && draft !== text) setText(draft);
12611
12666
  }, [draft]);
12612
12667
  const change = (v) => {
@@ -12642,7 +12697,7 @@ function ChatComposer({
12642
12697
  e.preventDefault();
12643
12698
  staged.add(found.files);
12644
12699
  };
12645
- React65.useEffect(() => {
12700
+ React66.useEffect(() => {
12646
12701
  if (!trigger || trigger.type !== "mention" || !mentionSources) {
12647
12702
  setMentionItems([]);
12648
12703
  return;
@@ -12660,7 +12715,7 @@ function ChatComposer({
12660
12715
  const q = (trigger.query || "").toLowerCase();
12661
12716
  setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
12662
12717
  }, [trigger, mentionSources]);
12663
- const slashItems = React65.useMemo(() => {
12718
+ const slashItems = React66.useMemo(() => {
12664
12719
  if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
12665
12720
  const q = (trigger.query || "").toLowerCase();
12666
12721
  return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
@@ -12830,12 +12885,12 @@ function ChatComposer({
12830
12885
  }
12831
12886
 
12832
12887
  // src/components/chat/ChatSessionBar.tsx
12833
- import * as React66 from "react";
12888
+ import * as React67 from "react";
12834
12889
  import { jsx as jsx96, jsxs as jsxs87 } from "react/jsx-runtime";
12835
12890
  var compact2 = meterFormats.compact;
12836
12891
  function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
12837
- const [open2, setOpen] = React66.useState(false);
12838
- const anchor = React66.useRef(null);
12892
+ const [open2, setOpen] = React67.useState(false);
12893
+ const anchor = React67.useRef(null);
12839
12894
  const stats = sessionStats || null;
12840
12895
  const cu = contextUsage || null;
12841
12896
  const limits = usageLimits || null;
@@ -12850,7 +12905,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
12850
12905
  if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
12851
12906
  if (cu) bits.push(pct + "% context");
12852
12907
  const expandable = !!(cu || limits);
12853
- return /* @__PURE__ */ jsxs87(React66.Fragment, { children: [
12908
+ return /* @__PURE__ */ jsxs87(React67.Fragment, { children: [
12854
12909
  /* @__PURE__ */ jsxs87("div", { className: "fdc-bar", children: [
12855
12910
  /* @__PURE__ */ jsxs87(
12856
12911
  "button",
@@ -12991,7 +13046,7 @@ function ModelControls({
12991
13046
  ] })
12992
13047
  });
12993
13048
  }
12994
- return /* @__PURE__ */ jsxs87(React66.Fragment, { children: [
13049
+ return /* @__PURE__ */ jsxs87(React67.Fragment, { children: [
12995
13050
  /* @__PURE__ */ jsx96(
12996
13051
  MenuButton,
12997
13052
  {
@@ -13108,11 +13163,11 @@ function AgentChatPanel({
13108
13163
  onFeedback,
13109
13164
  onEditMessage
13110
13165
  }) {
13111
- const [panelWidth, setPanelWidth] = React67.useState(width);
13112
- const [applied, setApplied] = React67.useState({});
13113
- const [draft, setDraft] = React67.useState("");
13114
- const dragging = React67.useRef(null);
13115
- React67.useEffect(() => setPanelWidth(width), [width]);
13166
+ const [panelWidth, setPanelWidth] = React68.useState(width);
13167
+ const [applied, setApplied] = React68.useState({});
13168
+ const [draft, setDraft] = React68.useState("");
13169
+ const dragging = React68.useRef(null);
13170
+ React68.useEffect(() => setPanelWidth(width), [width]);
13116
13171
  const engine = useChatEngine({
13117
13172
  contextType,
13118
13173
  contextId,
@@ -13316,7 +13371,7 @@ function AgentChatPanel({
13316
13371
  }
13317
13372
 
13318
13373
  // src/components/files/FileViewer.tsx
13319
- import * as React68 from "react";
13374
+ import * as React69 from "react";
13320
13375
  import { jsx as jsx98, jsxs as jsxs89 } from "react/jsx-runtime";
13321
13376
  function previewKindOf(file) {
13322
13377
  const mime = (file.mime || "").toLowerCase();
@@ -13373,13 +13428,13 @@ function parseDelimited(text, delimiter) {
13373
13428
  return rows;
13374
13429
  }
13375
13430
  function usePreview(file, kind, resolveUrl) {
13376
- const [state, setState] = React68.useState({ status: "loading" });
13377
- const [attempt, setAttempt] = React68.useState(0);
13378
- const resolveRef = React68.useRef(resolveUrl);
13379
- React68.useEffect(() => {
13431
+ const [state, setState] = React69.useState({ status: "loading" });
13432
+ const [attempt, setAttempt] = React69.useState(0);
13433
+ const resolveRef = React69.useRef(resolveUrl);
13434
+ React69.useEffect(() => {
13380
13435
  resolveRef.current = resolveUrl;
13381
13436
  }, [resolveUrl]);
13382
- React68.useEffect(() => {
13437
+ React69.useEffect(() => {
13383
13438
  if (kind === "none") {
13384
13439
  setState({ status: "ready" });
13385
13440
  return;
@@ -13409,7 +13464,7 @@ function usePreview(file, kind, resolveUrl) {
13409
13464
  if (ac) ac.abort();
13410
13465
  };
13411
13466
  }, [file.id, kind, attempt]);
13412
- return { ...state, retry: React68.useCallback(() => setAttempt((a) => a + 1), []) };
13467
+ return { ...state, retry: React69.useCallback(() => setAttempt((a) => a + 1), []) };
13413
13468
  }
13414
13469
  function PreviewBody({ file, kind, state }) {
13415
13470
  if (kind === "image") return /* @__PURE__ */ jsx98("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
@@ -13454,13 +13509,13 @@ function PreviewBody({ file, kind, state }) {
13454
13509
  ] });
13455
13510
  }
13456
13511
  function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", onClose, actions, className = "" }) {
13457
- const kind = React68.useMemo(() => previewKindOf(file), [file]);
13512
+ const kind = React69.useMemo(() => previewKindOf(file), [file]);
13458
13513
  const preview = usePreview(file, kind, resolveUrl);
13459
- const [tab, setTab] = React68.useState("preview");
13460
- const [downloading, setDownloading] = React68.useState(false);
13461
- const [downloadError, setDownloadError] = React68.useState(null);
13514
+ const [tab, setTab] = React69.useState("preview");
13515
+ const [downloading, setDownloading] = React69.useState(false);
13516
+ const [downloadError, setDownloadError] = React69.useState(null);
13462
13517
  const hasSide = sidePanel != null;
13463
- React68.useEffect(() => {
13518
+ React69.useEffect(() => {
13464
13519
  setTab("preview");
13465
13520
  }, [file.id]);
13466
13521
  const download = () => {
@@ -13527,7 +13582,7 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
13527
13582
  }
13528
13583
 
13529
13584
  // src/components/files/FileBrowser.tsx
13530
- import * as React69 from "react";
13585
+ import * as React70 from "react";
13531
13586
  import { Fragment as Fragment28, jsx as jsx99, jsxs as jsxs90 } from "react/jsx-runtime";
13532
13587
  function childrenOf(folders, parentId) {
13533
13588
  return folders.filter((f) => f.parentId === parentId).sort((a, b) => a.name.localeCompare(b.name));
@@ -13637,8 +13692,8 @@ function FolderPickerMenu({
13637
13692
  ] });
13638
13693
  }
13639
13694
  function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropPayload, actions, className = "" }) {
13640
- const [over, setOver] = React69.useState(false);
13641
- const dragCounter = React69.useRef(0);
13695
+ const [over, setOver] = React70.useState(false);
13696
+ const dragCounter = React70.useRef(0);
13642
13697
  const dropHandlers = isDropTarget ? {
13643
13698
  onDragEnter: (e) => {
13644
13699
  if (!hasInternalPayload(e)) return;
@@ -13686,8 +13741,8 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
13686
13741
  }
13687
13742
  function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveInto, canMove }) {
13688
13743
  const kids = childrenOf(folders, folder.id);
13689
- const [expanded, setExpanded] = React69.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
13690
- React69.useEffect(() => {
13744
+ const [expanded, setExpanded] = React70.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
13745
+ React70.useEffect(() => {
13691
13746
  if (currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId)) setExpanded(true);
13692
13747
  }, [currentFolderId, folder.id, folders]);
13693
13748
  const isCurrent = folder.id === currentFolderId;
@@ -13753,15 +13808,15 @@ function FileBrowser({
13753
13808
  const canUpload = perm.canUpload !== false && !!onUpload;
13754
13809
  const canRemoveFile = perm.canRemoveFile !== false && !!onRemoveFile;
13755
13810
  const canDeleteFolder = perm.canDeleteFolder !== false && !!onDeleteFolder;
13756
- const [createOpen, setCreateOpen] = React69.useState(false);
13757
- const [createName, setCreateName] = React69.useState("");
13758
- const [renameTarget, setRenameTarget] = React69.useState(null);
13759
- const [renameValue, setRenameValue] = React69.useState("");
13760
- const [deleteTarget, setDeleteTarget] = React69.useState(null);
13761
- const uploadInputRef = React69.useRef(null);
13762
- const crumbFolders = React69.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
13763
- const subfolders = React69.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
13764
- const currentFiles = React69.useMemo(
13811
+ const [createOpen, setCreateOpen] = React70.useState(false);
13812
+ const [createName, setCreateName] = React70.useState("");
13813
+ const [renameTarget, setRenameTarget] = React70.useState(null);
13814
+ const [renameValue, setRenameValue] = React70.useState("");
13815
+ const [deleteTarget, setDeleteTarget] = React70.useState(null);
13816
+ const uploadInputRef = React70.useRef(null);
13817
+ const crumbFolders = React70.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
13818
+ const subfolders = React70.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
13819
+ const currentFiles = React70.useMemo(
13765
13820
  () => files.filter((f) => f.folderId === currentFolderId).sort((a, b) => a.name.localeCompare(b.name)),
13766
13821
  [files, currentFolderId]
13767
13822
  );
@@ -13993,8 +14048,8 @@ function BreadcrumbCrumb({
13993
14048
  isDropTarget,
13994
14049
  onDropPayload
13995
14050
  }) {
13996
- const [over, setOver] = React69.useState(false);
13997
- const dragCounter = React69.useRef(0);
14051
+ const [over, setOver] = React70.useState(false);
14052
+ const dragCounter = React70.useRef(0);
13998
14053
  const dropHandlers = isDropTarget ? {
13999
14054
  onDragEnter: (e) => {
14000
14055
  if (!hasInternalPayload(e)) return;
@@ -14023,7 +14078,7 @@ function BreadcrumbCrumb({
14023
14078
  }
14024
14079
 
14025
14080
  // src/kits/query.ts
14026
- import * as React70 from "react";
14081
+ import * as React71 from "react";
14027
14082
  var isMultiSelectShaped = (v) => !!v && typeof v === "object" && Array.isArray(v.values);
14028
14083
  var isRangeShaped = (v) => !!v && typeof v === "object" && ("min" in v || "max" in v);
14029
14084
  var isDateShaped = (v) => !!v && typeof v === "object" && "kind" in v;
@@ -14078,22 +14133,22 @@ function compare(a, b, dir) {
14078
14133
  var API = null;
14079
14134
  var PREFS = null;
14080
14135
  function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
14081
- const [query, setQuery] = React70.useState(() => {
14136
+ const [query, setQuery] = React71.useState(() => {
14082
14137
  const store = PREFS || window.PlannerPrefs;
14083
14138
  const saved = prefsKey && store ? store.getTable(prefsKey) : {};
14084
14139
  return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
14085
14140
  });
14086
- const savePref = React70.useCallback((patch2) => {
14141
+ const savePref = React71.useCallback((patch2) => {
14087
14142
  const store = PREFS || window.PlannerPrefs;
14088
14143
  if (prefsKey && store) store.setTable(prefsKey, patch2);
14089
14144
  }, [prefsKey]);
14090
- const [res, setRes] = React70.useState(null);
14091
- const [loading, setLoading] = React70.useState(true);
14092
- const seq2 = React70.useRef(0);
14145
+ const [res, setRes] = React71.useState(null);
14146
+ const [loading, setLoading] = React71.useState(true);
14147
+ const seq2 = React71.useRef(0);
14093
14148
  const depKey = (deps || []).join("|");
14094
14149
  const paramKey = JSON.stringify(params || {});
14095
14150
  const queryKey = JSON.stringify(query);
14096
- React70.useEffect(() => {
14151
+ React71.useEffect(() => {
14097
14152
  const id = ++seq2.current;
14098
14153
  setLoading(true);
14099
14154
  const t = setTimeout(() => {
@@ -14412,12 +14467,12 @@ function createVersionStore(initialState, options) {
14412
14467
  }
14413
14468
 
14414
14469
  // src/kits/documentTitle.ts
14415
- import * as React71 from "react";
14470
+ import * as React72 from "react";
14416
14471
  function formatDocumentTitle(routeTitle, appName) {
14417
14472
  return [routeTitle, appName, "Flytedesk"].filter((part) => !!part && part.length > 0).join(" \xB7 ");
14418
14473
  }
14419
14474
  function useDocumentTitle(routeTitle, appName) {
14420
- React71.useEffect(() => {
14475
+ React72.useEffect(() => {
14421
14476
  if (typeof document === "undefined") return;
14422
14477
  document.title = formatDocumentTitle(routeTitle, appName);
14423
14478
  }, [routeTitle, appName]);
@@ -14463,6 +14518,7 @@ export {
14463
14518
  CodeEditor,
14464
14519
  Collapsible,
14465
14520
  ComingSoon,
14521
+ CornerStackPortal,
14466
14522
  CsiBadge,
14467
14523
  CsiHero,
14468
14524
  CsiMeter,
@@ -14631,6 +14687,7 @@ export {
14631
14687
  useAppearancePrefs,
14632
14688
  useChatEngine,
14633
14689
  useCopyToClipboard,
14690
+ useCornerStackSlot,
14634
14691
  useDocumentTitle,
14635
14692
  useFeatureStatus,
14636
14693
  useLayerZIndex,