@ai-matrx/records-ui 0.109.1 → 0.109.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
@@ -5287,7 +5287,7 @@ function EntityReferencePicker({
5287
5287
  }) {
5288
5288
  const allowed = allowedKindsOf(field2);
5289
5289
  const kinds = useEntityReferenceKinds();
5290
- const labelOfKind = (token) => kinds.data?.find((k) => k.token === token)?.label ?? token.replace(/_/g, " ");
5290
+ const labelOfKind = (token2) => kinds.data?.find((k) => k.token === token2)?.label ?? token2.replace(/_/g, " ");
5291
5291
  const [open, setOpen] = useState15(false);
5292
5292
  const [search, setSearch] = useState15("");
5293
5293
  const [only, setOnly] = useState15(null);
@@ -5301,18 +5301,18 @@ function EntityReferencePicker({
5301
5301
  picked: refs.some((x) => x.token === r.token && x.id === r.id),
5302
5302
  attrs: { "data-entity-reference-candidate": `${r.token}:${r.id}` }
5303
5303
  }));
5304
- const kindChoice = allowed.length > 1 ? allowed.length <= 4 ? /* @__PURE__ */ jsx18("div", { className: "mb-1 flex flex-wrap gap-1", role: "group", "aria-label": `Which kind \u2014 ${field2.label}`, children: [null, ...allowed].map((token) => /* @__PURE__ */ jsx18(
5304
+ const kindChoice = allowed.length > 1 ? allowed.length <= 4 ? /* @__PURE__ */ jsx18("div", { className: "mb-1 flex flex-wrap gap-1", role: "group", "aria-label": `Which kind \u2014 ${field2.label}`, children: [null, ...allowed].map((token2) => /* @__PURE__ */ jsx18(
5305
5305
  Button10,
5306
5306
  {
5307
5307
  type: "button",
5308
5308
  size: "sm",
5309
- variant: only === token ? "secondary" : "ghost",
5309
+ variant: only === token2 ? "secondary" : "ghost",
5310
5310
  className: "h-6 px-2 text-[11px]",
5311
- "aria-pressed": only === token,
5312
- onClick: () => setOnly(token),
5313
- children: token ? labelOfKind(token) : "Any"
5311
+ "aria-pressed": only === token2,
5312
+ onClick: () => setOnly(token2),
5313
+ children: token2 ? labelOfKind(token2) : "Any"
5314
5314
  },
5315
- token ?? "any"
5315
+ token2 ?? "any"
5316
5316
  )) }) : /* @__PURE__ */ jsx18(
5317
5317
  PickOne,
5318
5318
  {
@@ -5320,7 +5320,7 @@ function EntityReferencePicker({
5320
5320
  className: "mb-1 w-full",
5321
5321
  value: only ?? "",
5322
5322
  onChange: (picked) => setOnly(picked || null),
5323
- options: [{ value: "", label: "Any kind" }, ...allowed.map((token) => ({ value: token, label: labelOfKind(token) }))]
5323
+ options: [{ value: "", label: "Any kind" }, ...allowed.map((token2) => ({ value: token2, label: labelOfKind(token2) }))]
5324
5324
  }
5325
5325
  ) : null;
5326
5326
  const notice = /* @__PURE__ */ jsxs16(Fragment5, { children: [
@@ -5364,9 +5364,9 @@ function Chips({
5364
5364
  picker
5365
5365
  }) {
5366
5366
  const refs = useMemo10(() => entityRefsOf(value), [value]);
5367
- const labelOf = (token, refId, own3) => {
5367
+ const labelOf = (token2, refId, own3) => {
5368
5368
  if (own3) return own3;
5369
- const read = words2?.data?.find((w) => w.token === token && w.id === refId)?.label;
5369
+ const read = words2?.data?.find((w) => w.token === token2 && w.id === refId)?.label;
5370
5370
  if (read) return read;
5371
5371
  if (words2 === null) return "A linked item (its name is read when you are signed in)";
5372
5372
  if (words2.loading) return "Reading\u2026";
@@ -7308,9 +7308,9 @@ var PAGE_VIEW_SPELLINGS = {
7308
7308
  };
7309
7309
  function pageViewFromParam(raw) {
7310
7310
  if (typeof raw !== "string") return null;
7311
- const token = raw.trim().toLowerCase();
7312
- if (token === "") return null;
7313
- return PAGE_VIEW_SPELLINGS[token] ?? null;
7311
+ const token2 = raw.trim().toLowerCase();
7312
+ if (token2 === "") return null;
7313
+ return PAGE_VIEW_SPELLINGS[token2] ?? null;
7314
7314
  }
7315
7315
  function unknownViewLine(raw) {
7316
7316
  return `The link asked for a view called \u201C${raw}\u201D, which this table has no view for, so you are looking at ${PAGE_VIEW_LABEL.grid}. The views this table has are ${PAGE_VIEWS.map((v) => PAGE_VIEW_LABEL[v]).join(", ")} \u2014 pick one above and the address follows it.`;
@@ -9960,7 +9960,7 @@ function useWholeTableCount(args) {
9960
9960
  }
9961
9961
 
9962
9962
  // src/Grid.tsx
9963
- import { useCallback as useCallback27, useEffect as useEffect51, useMemo as useMemo36, useRef as useRef36, useState as useState61 } from "react";
9963
+ import { useCallback as useCallback28, useEffect as useEffect52, useMemo as useMemo36, useRef as useRef37, useState as useState61 } from "react";
9964
9964
  import {
9965
9965
  useFields as useFields8,
9966
9966
  useRecordPage,
@@ -9970,7 +9970,7 @@ import {
9970
9970
  } from "@ai-matrx/records/react";
9971
9971
  import { asPermissionLevel, relationNameIndexOf as relationNameIndexOf2, relationNamesIn as relationNamesIn2 } from "@ai-matrx/records";
9972
9972
  import { MatrxDataTable as MatrxDataTable2, MatrxTableCardShowMore, tableStyleIsEmpty as tableStyleIsEmpty2, useMatrxTableCard } from "@ai-matrx/design-system/data-table";
9973
- import { announceRecordChanged as announceRecordChanged4 } from "@ai-matrx/records/core";
9973
+ import { announceRecordChanged as announceRecordChanged4, predictWriteRefusals as predictWriteRefusals2 } from "@ai-matrx/records/core";
9974
9974
 
9975
9975
  // src/archiveWords.ts
9976
9976
  import { formatCount } from "@ai-matrx/kit/format";
@@ -10165,10 +10165,10 @@ function entityReferenceSpec(input) {
10165
10165
  const seen = /* @__PURE__ */ new Set();
10166
10166
  const allowed = [];
10167
10167
  for (const raw of input.allowedTypes) {
10168
- const token = raw.trim().toLowerCase();
10169
- if (!token || seen.has(token)) continue;
10170
- seen.add(token);
10171
- allowed.push(token);
10168
+ const token2 = raw.trim().toLowerCase();
10169
+ if (!token2 || seen.has(token2)) continue;
10170
+ seen.add(token2);
10171
+ allowed.push(token2);
10172
10172
  }
10173
10173
  return {
10174
10174
  label: input.label,
@@ -10205,26 +10205,26 @@ function EntityReferenceKindPicker({ value, onChange, locked = false, className
10205
10205
  }
10206
10206
  return [...byCategory.entries()].sort(([a], [b]) => a.localeCompare(b));
10207
10207
  }, [data, query]);
10208
- const toggle = (token, on) => {
10208
+ const toggle = (token2, on) => {
10209
10209
  if (locked) return;
10210
- if (on) onChange(chosen.has(token) ? [...value] : [...value, token]);
10211
- else onChange(value.filter((t) => t !== token));
10210
+ if (on) onChange(chosen.has(token2) ? [...value] : [...value, token2]);
10211
+ else onChange(value.filter((t) => t !== token2));
10212
10212
  };
10213
10213
  return /* @__PURE__ */ jsxs30("div", { className: cn22("flex flex-col gap-2", className), children: [
10214
10214
  /* @__PURE__ */ jsx35(Label4, { className: "text-xs", children: "What it points at" }),
10215
- value.length > 0 ? /* @__PURE__ */ jsx35("div", { className: "flex flex-wrap gap-1", "aria-label": "Chosen kinds", children: value.map((token) => /* @__PURE__ */ jsxs30(Badge6, { variant: "secondary", className: "gap-1 text-[11px]", children: [
10216
- labelOf.get(token) ?? token,
10215
+ value.length > 0 ? /* @__PURE__ */ jsx35("div", { className: "flex flex-wrap gap-1", "aria-label": "Chosen kinds", children: value.map((token2) => /* @__PURE__ */ jsxs30(Badge6, { variant: "secondary", className: "gap-1 text-[11px]", children: [
10216
+ labelOf.get(token2) ?? token2,
10217
10217
  locked ? null : /* @__PURE__ */ jsx35(
10218
10218
  "button",
10219
10219
  {
10220
10220
  type: "button",
10221
10221
  className: "ml-0.5 rounded-sm px-0.5 opacity-70 hover:opacity-100",
10222
- "aria-label": `Remove ${labelOf.get(token) ?? token}`,
10223
- onClick: () => toggle(token, false),
10222
+ "aria-label": `Remove ${labelOf.get(token2) ?? token2}`,
10223
+ onClick: () => toggle(token2, false),
10224
10224
  children: "\xD7"
10225
10225
  }
10226
10226
  )
10227
- ] }, token)) }) : null,
10227
+ ] }, token2)) }) : null,
10228
10228
  locked ? /* @__PURE__ */ jsx35("p", { className: "text-[11px] text-muted-foreground", children: "The kinds an existing column points at are kept as they are; add a new column to point at others." }) : error ? /* @__PURE__ */ jsx35(RefusalNotice, { error }) : loading ? /* @__PURE__ */ jsx35(Skeleton3, { className: "h-24 w-full" }) : /* @__PURE__ */ jsxs30(Fragment10, { children: [
10229
10229
  /* @__PURE__ */ jsx35(
10230
10230
  BasicInput7,
@@ -11628,9 +11628,9 @@ function withUnique(rules, on) {
11628
11628
  var UNIQUE_LABEL = "Every value must be different";
11629
11629
  var DEFAULT_LABEL = "New records start with";
11630
11630
  function keyFor(label) {
11631
- const token = label.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 48);
11632
- if (token === "") return "";
11633
- return /^[a-z]/.test(token) ? token : `f_${token}`;
11631
+ const token2 = label.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 48);
11632
+ if (token2 === "") return "";
11633
+ return /^[a-z]/.test(token2) ? token2 : `f_${token2}`;
11634
11634
  }
11635
11635
  var COLUMN_DID_NOT_LAND_SENTENCE = "The store accepted this column and the table does not have it yet. Nothing was lost \u2014 your record values are untouched \u2014 but the column is not there, so this panel is staying open.";
11636
11636
  var COLUMN_DID_NOT_LAND_REMEDY = "Press Save again; if it keeps happening, tell us, because the store and the table disagree and that is ours to fix.";
@@ -16518,14 +16518,14 @@ function CustomFieldsSection({
16518
16518
 
16519
16519
  // src/StandardRecordForm.tsx
16520
16520
  import { jsx as jsx56, jsxs as jsxs51 } from "react/jsx-runtime";
16521
- function standardTokenOf(token) {
16522
- return token.startsWith("entity:") ? token.slice("entity:".length) : token;
16521
+ function standardTokenOf(token2) {
16522
+ return token2.startsWith("entity:") ? token2.slice("entity:".length) : token2;
16523
16523
  }
16524
16524
  function isEmpty(value) {
16525
16525
  return value === null || value === void 0 || typeof value === "string" && value.trim() === "";
16526
16526
  }
16527
- function StandardRecordForm({ token, recordId, columns, onSaved, className, custom, children }) {
16528
- const entityToken = standardTokenOf(token);
16527
+ function StandardRecordForm({ token: token2, recordId, columns, onSaved, className, custom, children }) {
16528
+ const entityToken = standardTokenOf(token2);
16529
16529
  const client = useRecordsClient27();
16530
16530
  const read = useEntityRecord2(entityToken, recordId);
16531
16531
  const [cellKey, setCellKey] = useState46(null);
@@ -16665,7 +16665,8 @@ function CustomRecordForm({
16665
16665
  onSaved,
16666
16666
  onCancel,
16667
16667
  className,
16668
- initial
16668
+ initial,
16669
+ focusFirstRequired
16669
16670
  }) {
16670
16671
  const host = useRecordsUi();
16671
16672
  const fields = useFields4(tableId, recordType);
@@ -16699,6 +16700,15 @@ function CustomRecordForm({
16699
16700
  }
16700
16701
  if (Object.keys(starts).length > 0) setDraft((held) => ({ ...starts, ...held }));
16701
16702
  }, [recordId, fields.data]);
16703
+ const focusedFirst = useRef28(false);
16704
+ useEffect38(() => {
16705
+ if (!focusFirstRequired || recordId || focusedFirst.current || !fields.data) return;
16706
+ focusedFirst.current = true;
16707
+ const first = fields.data.find((f) => f.required && (draft[f.key] === void 0 || draft[f.key] === null || draft[f.key] === ""));
16708
+ if (!first) return;
16709
+ const t = setTimeout(() => globalThis.document?.getElementById(`field-${first.id}`)?.focus(), 0);
16710
+ return () => clearTimeout(t);
16711
+ }, [focusFirstRequired, recordId, fields.data]);
16702
16712
  const [changed, setChanged] = useState47({});
16703
16713
  const [answered, setAnswered] = useState47(null);
16704
16714
  const formRows = useMemo24(
@@ -17065,9 +17075,18 @@ function NewRecordControl({
17065
17075
  noun,
17066
17076
  busy,
17067
17077
  onAdd,
17068
- onCreated
17078
+ onCreated,
17079
+ ask
17069
17080
  }) {
17070
17081
  const [formOpen, setFormOpen] = useState48(false);
17082
+ const [formInitial, setFormInitial] = useState48({});
17083
+ const seenAsk = useRef29(0);
17084
+ useEffect39(() => {
17085
+ if (!ask || ask.n === seenAsk.current) return;
17086
+ seenAsk.current = ask.n;
17087
+ setFormInitial(ask.initial);
17088
+ setFormOpen(true);
17089
+ }, [ask]);
17071
17090
  return /* @__PURE__ */ jsxs53(Fragment16, { children: [
17072
17091
  /* @__PURE__ */ jsxs53("div", { className: "inline-flex shrink-0", "data-records-new-record": "", children: [
17073
17092
  /* @__PURE__ */ jsx58(Button32, { size: "sm", className: "rounded-r-none", disabled: busy, onClick: onAdd, children: busy ? "Adding\u2026" : "New record" }),
@@ -17098,6 +17117,8 @@ function NewRecordControl({
17098
17117
  RecordForm,
17099
17118
  {
17100
17119
  tableId,
17120
+ initial: formInitial,
17121
+ focusFirstRequired: true,
17101
17122
  onSaved: (id) => {
17102
17123
  setFormOpen(false);
17103
17124
  onCreated(id);
@@ -17604,9 +17625,9 @@ function useDrill(args) {
17604
17625
  return { config, def };
17605
17626
  }
17606
17627
  function useAddressDrill(args) {
17607
- const { token, startWindow, prefix, ...rest } = args;
17608
- const active = (args.enabled ?? true) && token !== null;
17609
- const source = useMemo26(() => active && token ? { kind: "entity", token } : null, [active, token]);
17628
+ const { token: token2, startWindow, prefix, ...rest } = args;
17629
+ const active = (args.enabled ?? true) && token2 !== null;
17630
+ const source = useMemo26(() => active && token2 ? { kind: "entity", token: token2 } : null, [active, token2]);
17610
17631
  const fallback = useMemo26(
17611
17632
  () => ({ by: [], across: null, show: [], where: [], ...startWindow ? { window: startWindow } : {} }),
17612
17633
  [startWindow]
@@ -18594,8 +18615,10 @@ function ReverseCell({ held, column, rowId, tableId }) {
18594
18615
  },
18595
18616
  [held]
18596
18617
  );
18597
- const answer = useSyncExternalStore3(subscribe, () => held.answers?.[column.key]?.[rowId]);
18598
- const reading = useSyncExternalStore3(subscribe, () => held.reading);
18618
+ const readAnswer = () => held.answers?.[column.key]?.[rowId];
18619
+ const readReading = () => held.reading;
18620
+ const answer = useSyncExternalStore3(subscribe, readAnswer, readAnswer);
18621
+ const reading = useSyncExternalStore3(subscribe, readReading, readReading);
18599
18622
  return /* @__PURE__ */ jsx61(ReverseLinkChips, { column, answer, loading: reading, clamp: { tableId, recordId: rowId } });
18600
18623
  }
18601
18624
  var EMPTY_COLUMNS = [];
@@ -21828,6 +21851,108 @@ function useEditKeepsTheView(args) {
21828
21851
  }, []);
21829
21852
  }
21830
21853
 
21854
+ // src/gridRowMove.ts
21855
+ import { useCallback as useCallback25, useEffect as useEffect49, useLayoutEffect as useLayoutEffect5, useRef as useRef34 } from "react";
21856
+ var WATCH_MS2 = 15e3;
21857
+ function token(el, name, fallback) {
21858
+ const read = getComputedStyle(el).getPropertyValue(name).trim();
21859
+ return read === "" ? fallback : read;
21860
+ }
21861
+ function milliseconds(value) {
21862
+ const n = parseFloat(value);
21863
+ if (Number.isNaN(n)) return 0;
21864
+ return value.endsWith("ms") ? n : n * 1e3;
21865
+ }
21866
+ var rowEl = (box, rowId) => box.querySelector(`tr[data-row-id="${CSS.escape(rowId)}"]`);
21867
+ function scrollerOf(el) {
21868
+ for (let up = el.parentElement; up; up = up.parentElement) {
21869
+ const { overflowY } = getComputedStyle(up);
21870
+ if ((overflowY === "auto" || overflowY === "scroll") && up.scrollHeight > up.clientHeight) return up;
21871
+ }
21872
+ return null;
21873
+ }
21874
+ function bringIntoView(box, rowId, index, ids) {
21875
+ const el = rowEl(box, rowId);
21876
+ if (el) {
21877
+ const scroller2 = scrollerOf(el);
21878
+ if (!scroller2) return;
21879
+ const row = el.getBoundingClientRect();
21880
+ const view = scroller2.getBoundingClientRect();
21881
+ const head = box.querySelector("thead")?.getBoundingClientRect().height ?? 0;
21882
+ if (row.top < view.top + head) scroller2.scrollTop -= view.top + head - row.top;
21883
+ else if (row.bottom > view.bottom) scroller2.scrollTop += row.bottom - view.bottom;
21884
+ return;
21885
+ }
21886
+ const any = box.querySelector("tr[data-row-id]");
21887
+ if (!any) return;
21888
+ const scroller = scrollerOf(any);
21889
+ const at = ids.indexOf(any.getAttribute("data-row-id") ?? "");
21890
+ if (!scroller || at === -1) return;
21891
+ scroller.scrollTop += (index - at) * any.getBoundingClientRect().height;
21892
+ }
21893
+ function useRowFollowsItsMove(args) {
21894
+ const held = useRef34(null);
21895
+ const latest = useRef34(args);
21896
+ latest.current = args;
21897
+ const lastIds = useRef34(args.rowIds);
21898
+ const frame = useRef34(0);
21899
+ useEffect49(() => () => cancelAnimationFrame(frame.current), []);
21900
+ const noteWrite = useCallback25((rowId) => {
21901
+ const box = latest.current.box.current;
21902
+ if (!box) return;
21903
+ const el = rowEl(box, rowId);
21904
+ const index = latest.current.rowIds.indexOf(rowId);
21905
+ if (!el || index === -1) {
21906
+ held.current = null;
21907
+ return;
21908
+ }
21909
+ held.current = { rowId, top: el.getBoundingClientRect().top, index, at: Date.now() };
21910
+ }, []);
21911
+ useLayoutEffect5(() => {
21912
+ if (args.rowIds === lastIds.current) return;
21913
+ lastIds.current = args.rowIds;
21914
+ const pending = held.current;
21915
+ if (!pending) return;
21916
+ const box = args.box.current;
21917
+ if (!box) return;
21918
+ if (Date.now() - pending.at > WATCH_MS2) {
21919
+ held.current = null;
21920
+ return;
21921
+ }
21922
+ const index = args.rowIds.indexOf(pending.rowId);
21923
+ if (index === -1) {
21924
+ held.current = null;
21925
+ return;
21926
+ }
21927
+ if (index === pending.index) return;
21928
+ held.current = null;
21929
+ const el = rowEl(box, pending.rowId);
21930
+ if (!el) {
21931
+ bringIntoView(box, pending.rowId, index, args.rowIds);
21932
+ frame.current = requestAnimationFrame(() => {
21933
+ const landed = rowEl(box, pending.rowId);
21934
+ if (landed) bringIntoView(box, pending.rowId, index, latest.current.rowIds);
21935
+ });
21936
+ return;
21937
+ }
21938
+ bringIntoView(box, pending.rowId, index, args.rowIds);
21939
+ const calm = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
21940
+ if (calm || typeof el.animate !== "function") return;
21941
+ const ms = milliseconds(token(el, "--matrx-motion-duration-slow", "300ms"));
21942
+ if (ms <= 0) return;
21943
+ const ease = token(el, "--matrx-motion-ease-panel", "ease-in-out");
21944
+ const jump = pending.top - el.getBoundingClientRect().top;
21945
+ if (jump !== 0) el.animate([{ transform: `translateY(${jump}px)` }, { transform: "translateY(0)" }], { duration: ms, easing: ease });
21946
+ for (const cell2 of Array.from(el.children)) {
21947
+ cell2.animate(
21948
+ [{ backgroundColor: "hsl(var(--primary) / 0.16)" }, { backgroundColor: "hsl(var(--primary) / 0)" }],
21949
+ { duration: ms * 2, easing: ease }
21950
+ );
21951
+ }
21952
+ }, [args.rowIds, args.box]);
21953
+ return { noteWrite };
21954
+ }
21955
+
21831
21956
  // src/gridHeldKeys.ts
21832
21957
  function isHeldKey(e) {
21833
21958
  if (e.metaKey || e.ctrlKey || e.altKey) return false;
@@ -21921,7 +22046,7 @@ function holdKeys() {
21921
22046
 
21922
22047
  // src/gridAssist.tsx
21923
22048
  import { copyText } from "@ai-matrx/kit/clipboard";
21924
- import { useCallback as useCallback25, useEffect as useEffect49, useMemo as useMemo33, useRef as useRef34, useState as useState58 } from "react";
22049
+ import { useCallback as useCallback26, useEffect as useEffect50, useMemo as useMemo33, useRef as useRef35, useState as useState58 } from "react";
21925
22050
  import { tableKindSlug, wholeValueOf as wholeValueOf4 } from "@ai-matrx/records/core";
21926
22051
  import { useContentTransferCapabilities } from "@ai-matrx/alchemy/react/workspace";
21927
22052
 
@@ -21999,21 +22124,21 @@ function useGridAssist(args) {
21999
22124
  const reference = useContentTransferCapabilities().reference;
22000
22125
  const [cursor, setCursor] = useState58(null);
22001
22126
  const [whole, setWhole] = useState58(null);
22002
- const say2 = useCallback25(
22127
+ const say2 = useCallback26(
22003
22128
  (ok, message) => ok ? host.notify?.success(message) : host.notify?.error(message),
22004
22129
  [host.notify]
22005
22130
  );
22006
- const rowOf = useCallback25((rowId) => rows.find((r) => r.id === rowId), [rows]);
22007
- const titleOf = useCallback25(
22131
+ const rowOf = useCallback26((rowId) => rows.find((r) => r.id === rowId), [rows]);
22132
+ const titleOf = useCallback26(
22008
22133
  (row) => row ? recordNameIn(table, row.document ?? {}) : "",
22009
22134
  [table]
22010
22135
  );
22011
- const fieldOf2 = useCallback25((key) => fields.find((f) => f.key === key), [fields]);
22136
+ const fieldOf2 = useCallback26((key) => fields.find((f) => f.key === key), [fields]);
22012
22137
  const onGridContext = host.onGridContext;
22013
- const lastKey = useRef34("");
22138
+ const lastKey = useRef35("");
22014
22139
  const editingAt = editing.editing;
22015
22140
  const draft = editing.draft;
22016
- useEffect49(() => {
22141
+ useEffect50(() => {
22017
22142
  if (!enabled || !onGridContext) return;
22018
22143
  const snapshot = gridContextSnapshot({
22019
22144
  tableId,
@@ -22034,7 +22159,7 @@ function useGridAssist(args) {
22034
22159
  lastKey.current = key;
22035
22160
  onGridContext(snapshot);
22036
22161
  });
22037
- const copyReference = useCallback25(
22162
+ const copyReference = useCallback26(
22038
22163
  (ref, what) => {
22039
22164
  if (!reference) return;
22040
22165
  void (async () => {
@@ -22049,7 +22174,7 @@ function useGridAssist(args) {
22049
22174
  },
22050
22175
  [reference, say2]
22051
22176
  );
22052
- const copyRecordReference = useCallback25(
22177
+ const copyRecordReference = useCallback26(
22053
22178
  (rowId) => {
22054
22179
  void (async () => {
22055
22180
  const text2 = JSON.stringify({ __kind: tableKindSlug(tableId), _record_id: rowId });
@@ -22095,14 +22220,14 @@ function useGridAssist(args) {
22095
22220
  }),
22096
22221
  [tableId, name, titleOf]
22097
22222
  );
22098
- const refItem = useCallback25(
22223
+ const refItem = useCallback26(
22099
22224
  (id, label, ref, what) => {
22100
22225
  if (!reference || !reference.supports(ref)) return [];
22101
22226
  return [{ id, label, icon: "link", onSelect: () => copyReference(ref, what) }];
22102
22227
  },
22103
22228
  [reference, copyReference]
22104
22229
  );
22105
- const openWhole = useCallback25(
22230
+ const openWhole = useCallback26(
22106
22231
  (rowId, key) => {
22107
22232
  const row = rowOf(rowId);
22108
22233
  if (!row) return;
@@ -22113,7 +22238,7 @@ function useGridAssist(args) {
22113
22238
  },
22114
22239
  [rowOf, fieldOf2, titleOf, editing]
22115
22240
  );
22116
- const cellItems = useCallback25(
22241
+ const cellItems = useCallback26(
22117
22242
  (rowId, columnId2) => {
22118
22243
  const row = rowOf(rowId);
22119
22244
  const field2 = fieldOf2(columnId2);
@@ -22142,7 +22267,7 @@ function useGridAssist(args) {
22142
22267
  },
22143
22268
  [rowOf, fieldOf2, openWhole, host.cleanText, editing, args, refItem, refFor]
22144
22269
  );
22145
- const rowItems = useCallback25(
22270
+ const rowItems = useCallback26(
22146
22271
  (rowId) => {
22147
22272
  const row = rowOf(rowId);
22148
22273
  const askAgent = args.askAgent;
@@ -22164,11 +22289,11 @@ function useGridAssist(args) {
22164
22289
  },
22165
22290
  [rowOf, args, fields, refItem, refFor, copyRecordReference]
22166
22291
  );
22167
- const tableItems = useCallback25(
22292
+ const tableItems = useCallback26(
22168
22293
  () => refItem("table-reference", "Copy table reference", refFor.table(), "The table"),
22169
22294
  [refItem, refFor]
22170
22295
  );
22171
- const onKeyDownCapture = useCallback25(
22296
+ const onKeyDownCapture = useCallback26(
22172
22297
  (event) => {
22173
22298
  if (!enabled || event.key !== "Enter" || !event.shiftKey || event.metaKey || event.ctrlKey || event.altKey) return;
22174
22299
  const target = event.target;
@@ -22202,7 +22327,7 @@ function useGridAssist(args) {
22202
22327
  }
22203
22328
 
22204
22329
  // src/gridBulk.tsx
22205
- import { useCallback as useCallback26, useMemo as useMemo34, useState as useState59 } from "react";
22330
+ import { useCallback as useCallback27, useMemo as useMemo34, useState as useState59 } from "react";
22206
22331
  import { useRecordsClient as useRecordsClient37 } from "@ai-matrx/records/react";
22207
22332
  import { announceRecordChanged as announceRecordChanged3 } from "@ai-matrx/records/core";
22208
22333
  import {
@@ -22261,7 +22386,7 @@ function useGridBulk(args) {
22261
22386
  const { tableId, rows, fields, noun, nounPlural, reload, forget, pushUndo: pushUndo2, versions } = args;
22262
22387
  const [busy, setBusy] = useState59(false);
22263
22388
  const [refusal4, setRefusal] = useState59(null);
22264
- const send = useCallback26(
22389
+ const send = useCallback27(
22265
22390
  async (changes) => {
22266
22391
  setBusy(true);
22267
22392
  setRefusal(null);
@@ -22285,7 +22410,7 @@ function useGridBulk(args) {
22285
22410
  },
22286
22411
  [client, tableId, versions, reload]
22287
22412
  );
22288
- const apply = useCallback26(
22413
+ const apply = useCallback27(
22289
22414
  async (plan) => {
22290
22415
  if (plan.changes.length === 0) return true;
22291
22416
  const done = await send(plan.changes);
@@ -22298,7 +22423,7 @@ function useGridBulk(args) {
22298
22423
  },
22299
22424
  [send, forget, pushUndo2, reload]
22300
22425
  );
22301
- const duplicate = useCallback26(
22426
+ const duplicate = useCallback27(
22302
22427
  async (ids) => {
22303
22428
  const changes = planDuplicates(ids, rows, fields);
22304
22429
  if (changes.length === 0) return true;
@@ -22311,7 +22436,7 @@ function useGridBulk(args) {
22311
22436
  },
22312
22437
  [send, rows, fields, pushUndo2, reload, noun, nounPlural]
22313
22438
  );
22314
- const archive = useCallback26(
22439
+ const archive = useCallback27(
22315
22440
  async (ids) => {
22316
22441
  const onPage = new Set(rows.map((r) => r.id));
22317
22442
  const targets = ids.filter((id) => onPage.has(id));
@@ -22441,7 +22566,7 @@ function BulkActions({
22441
22566
  }
22442
22567
 
22443
22568
  // src/handOrder.tsx
22444
- import { useEffect as useEffect50, useMemo as useMemo35, useRef as useRef35, useState as useState60 } from "react";
22569
+ import { useEffect as useEffect51, useMemo as useMemo35, useRef as useRef36, useState as useState60 } from "react";
22445
22570
  import { useRecordsClient as useRecordsClient38 } from "@ai-matrx/records/react";
22446
22571
  import { stableFilterKey as stableFilterKey2 } from "@ai-matrx/records";
22447
22572
  import { Button as Button41, ConfirmDialog as ConfirmDialog4, Popover as Popover7, PopoverContent as PopoverContent7, PopoverTrigger as PopoverTrigger7, cn as cn35 } from "@ai-matrx/design-system";
@@ -22561,14 +22686,14 @@ function useHandOrderRows(args) {
22561
22686
  const { viewId, active, page, pageSize } = args;
22562
22687
  const filter = args.filter && Object.keys(args.filter).length > 0 ? args.filter : null;
22563
22688
  const filterKey = filter ? stableFilterKey2(filter) : "";
22564
- const filterNow = useRef35(filter);
22689
+ const filterNow = useRef36(filter);
22565
22690
  filterNow.current = filter;
22566
22691
  const [answer, setAnswer] = useState60(null);
22567
22692
  const [tick, setTick] = useState60(0);
22568
22693
  const limit = Math.max(1, Math.min(pageSize, DOOR_PAGE_MAX));
22569
22694
  const offset = Math.max(0, page) * limit;
22570
22695
  const key = `${viewId ?? ""}:${limit}:${offset}:${filterKey}`;
22571
- useEffect50(() => {
22696
+ useEffect51(() => {
22572
22697
  if (!active || !viewId) return;
22573
22698
  let cancelled = false;
22574
22699
  void client.readInViewOrder({ view_id: viewId, filter: filterNow.current, limit, offset }).then((result) => {
@@ -22607,7 +22732,7 @@ function HandOrderDialog({
22607
22732
  const [dragging, setDragging] = useState60(null);
22608
22733
  const [busy, setBusy] = useState60(false);
22609
22734
  const [refused, setRefused] = useState60(null);
22610
- useEffect50(() => {
22735
+ useEffect51(() => {
22611
22736
  if (open) {
22612
22737
  setList([...items]);
22613
22738
  setRefused(null);
@@ -22802,7 +22927,7 @@ function GridBody({
22802
22927
  const rights = useTableRights(table.data);
22803
22928
  const [heldOrder, setHeldOrder] = useState61(null);
22804
22929
  const sortsKey = JSON.stringify(viewOrder?.sorts ?? []);
22805
- useEffect51(() => {
22930
+ useEffect52(() => {
22806
22931
  setHeldOrder(null);
22807
22932
  }, [viewOrder?.viewId, viewOrder?.order, sortsKey]);
22808
22933
  const viewId = viewOrder?.viewId ?? null;
@@ -22819,7 +22944,7 @@ function GridBody({
22819
22944
  const openingSort = manual ? null : viewSort ?? defaultSort;
22820
22945
  const openingKey = openingSort ? `${openingSort.id}:${openingSort.direction}` : "none";
22821
22946
  const address = useViewAddress();
22822
- const addressSeed = useRef36(address?.initial ?? null);
22947
+ const addressSeed = useRef37(address?.initial ?? null);
22823
22948
  const [query, setQuery] = useState61(() => ({
22824
22949
  page: addressSeed.current?.page ?? 1,
22825
22950
  pageSize,
@@ -22829,7 +22954,7 @@ function GridBody({
22829
22954
  sort: addressSeed.current?.sort ? { id: addressSeed.current.sort.field, direction: addressSeed.current.sort.direction } : openingSort
22830
22955
  }));
22831
22956
  const [seatedOn, setSeatedOn] = useState61(openingKey);
22832
- useEffect51(() => {
22957
+ useEffect52(() => {
22833
22958
  const seed = addressSeed.current;
22834
22959
  if (seed && fields.data) addressSeed.current = null;
22835
22960
  setQuery((held) => ({
@@ -22841,8 +22966,8 @@ function GridBody({
22841
22966
  }, [openingKey]);
22842
22967
  const columnSort = query.sort;
22843
22968
  const overrideKey = sortOverride ? `${sortOverride.field}:${sortOverride.direction}` : "";
22844
- const overrideSeen = useRef36(overrideKey);
22845
- useEffect51(() => {
22969
+ const overrideSeen = useRef37(overrideKey);
22970
+ useEffect52(() => {
22846
22971
  if (overrideSeen.current === overrideKey) return;
22847
22972
  overrideSeen.current = overrideKey;
22848
22973
  setQuery((held) => ({
@@ -22851,8 +22976,8 @@ function GridBody({
22851
22976
  page: 1
22852
22977
  }));
22853
22978
  }, [overrideKey]);
22854
- const overrideSearchSeen = useRef36(void 0);
22855
- useEffect51(() => {
22979
+ const overrideSearchSeen = useRef37(void 0);
22980
+ useEffect52(() => {
22856
22981
  if (searchOverride === void 0) return;
22857
22982
  const wanted = searchOverride ?? "";
22858
22983
  if (overrideSearchSeen.current === wanted) return;
@@ -22860,7 +22985,7 @@ function GridBody({
22860
22985
  setQuery((held) => held.search === wanted ? held : { ...held, search: wanted, page: 1 });
22861
22986
  }, [searchOverride]);
22862
22987
  const reportQuery = address?.report;
22863
- useEffect51(() => {
22988
+ useEffect52(() => {
22864
22989
  if (!reportQuery) return;
22865
22990
  const sort = query.sort && `${query.sort.id}:${query.sort.direction}` !== openingKey ? { field: query.sort.id, direction: query.sort.direction } : null;
22866
22991
  reportQuery({
@@ -22871,13 +22996,13 @@ function GridBody({
22871
22996
  });
22872
22997
  }, [reportQuery, query.sort, query.columnFilters, query.search, query.page, openingKey]);
22873
22998
  const liveKeys = useMemo36(() => fields.data ? new Set(fields.data.map((f) => f.key)) : null, [fields.data]);
22874
- useEffect51(() => {
22999
+ useEffect52(() => {
22875
23000
  if (!liveKeys) return;
22876
23001
  setQuery((held) => withoutGoneColumns(held, liveKeys, openingSort));
22877
23002
  }, [liveKeys]);
22878
23003
  const resetEpoch = address?.resetEpoch ?? 0;
22879
- const resetSeen = useRef36(resetEpoch);
22880
- useEffect51(() => {
23004
+ const resetSeen = useRef37(resetEpoch);
23005
+ useEffect52(() => {
22881
23006
  if (resetSeen.current === resetEpoch) return;
22882
23007
  resetSeen.current = resetEpoch;
22883
23008
  addressSeed.current = null;
@@ -22885,7 +23010,7 @@ function GridBody({
22885
23010
  }, [resetEpoch]);
22886
23011
  const [page, setPage] = useState61(0);
22887
23012
  const [searchTerm, setSearchTerm] = useState61("");
22888
- useEffect51(() => {
23013
+ useEffect52(() => {
22889
23014
  if (!storePaged) return;
22890
23015
  const wanted = query.search.trim();
22891
23016
  if (wanted === searchTerm) return;
@@ -22928,7 +23053,7 @@ function GridBody({
22928
23053
  page: classicInCard ? 0 : page,
22929
23054
  ...readFilter ? { filter: readFilter } : {}
22930
23055
  });
22931
- const pageAskedFor = useRef36(null);
23056
+ const pageAskedFor = useRef37(null);
22932
23057
  if (fields.data && !table.loading) pageAskedFor.current = tableId;
22933
23058
  const pageAsked = !storePaged || Boolean(fields.data) && pageAskedFor.current === tableId;
22934
23059
  const serverRead = useRecordPage(storePaged && pageAsked ? tableId : null, {
@@ -22953,14 +23078,14 @@ function GridBody({
22953
23078
  const [appendedRows, setAppendedRows] = useState61([]);
22954
23079
  const [appending, setAppending] = useState61(false);
22955
23080
  const askKey2 = JSON.stringify([tableId, searchTerm, pageSort, readFilter ?? null, viewId]);
22956
- useEffect51(() => setAppendedRows([]), [askKey2]);
23081
+ useEffect52(() => setAppendedRows([]), [askKey2]);
22957
23082
  const pageRows = useMemo36(() => {
22958
23083
  if (manual && !storePaged) return hand.rows ?? [];
22959
23084
  if (!embeddedMore || appendedRows.length === 0) return storeRows;
22960
23085
  const seen = new Set(storeRows.map((row) => row.id));
22961
23086
  return [...storeRows, ...appendedRows.filter((row) => !seen.has(row.id))];
22962
23087
  }, [manual, storePaged, hand.rows, storeRows, embeddedMore, appendedRows]);
22963
- const showMoreRows = useCallback27(async () => {
23088
+ const showMoreRows = useCallback28(async () => {
22964
23089
  if (appending || !embeddedMore) return;
22965
23090
  setAppending(true);
22966
23091
  const asked3 = await client.listPage({
@@ -22984,10 +23109,10 @@ function GridBody({
22984
23109
  const rows = added.rows;
22985
23110
  const rowIds = useMemo36(() => rows.map((row) => row.id), [rows]);
22986
23111
  const countedButNotReturned = !records.error && !records.loading && rows.length === 0 && typeof records.data?.total === "number" && records.data.total > 0 && (storePaged ? query.page <= 1 : page <= 0);
22987
- const reReads = useRef36(0);
22988
- const reloadRecords = useRef36(records.reload);
23112
+ const reReads = useRef37(0);
23113
+ const reloadRecords = useRef37(records.reload);
22989
23114
  reloadRecords.current = records.reload;
22990
- useEffect51(() => {
23115
+ useEffect52(() => {
22991
23116
  if (!countedButNotReturned) {
22992
23117
  reReads.current = 0;
22993
23118
  return;
@@ -23001,18 +23126,19 @@ function GridBody({
23001
23126
  }, [countedButNotReturned]);
23002
23127
  const askPerRow = Boolean(editable) && !host.rights && rights.known && !rights.write && rows.length > 0;
23003
23128
  const rowRights = useRowRights(rowIds, askPerRow);
23004
- const mayWriteRow = useCallback27(
23129
+ const mayWriteRow = useCallback28(
23005
23130
  (rowId) => askPerRow ? rowRights(rowId)?.write ?? false : rights.write,
23006
23131
  [askPerRow, rowRights, rights.write]
23007
23132
  );
23008
- const whyNotRow = useCallback27(
23133
+ const whyNotRow = useCallback28(
23009
23134
  (rowId) => askPerRow ? rowRights(rowId)?.why("write") ?? rights.why("write") : rights.why("write"),
23010
23135
  [askPerRow, rowRights, rights]
23011
23136
  );
23012
23137
  const canWrite = Boolean(editable) && (rights.write || askPerRow && rowIds.some(mayWriteRow));
23013
23138
  const readOnly = !editable || Boolean(host.rights) && !rights.write && !rights.structure;
23014
- const pushWritten = useRef36(null);
23015
- const sheetController = useRef36(null);
23139
+ const gridBox = useRef37(null);
23140
+ const pushWritten = useRef37(null);
23141
+ const sheetController = useRef37(null);
23016
23142
  const versions = useRecordVersions(client, rows);
23017
23143
  const editing = useGridEditing({
23018
23144
  tableId,
@@ -23034,7 +23160,7 @@ function GridBody({
23034
23160
  onEnded: (exit, from, how) => sheetController.current?.endEdit(exit, { rowId: from.rowId, columnId: from.key }, how)
23035
23161
  } : {}
23036
23162
  });
23037
- const editingNow = useRef36(editing);
23163
+ const editingNow = useRef37(editing);
23038
23164
  editingNow.current = editing;
23039
23165
  const editingHandle = useMemo36(
23040
23166
  () => new Proxy({}, {
@@ -23042,7 +23168,7 @@ function GridBody({
23042
23168
  }),
23043
23169
  []
23044
23170
  );
23045
- const rowVersion = useCallback27((row) => editingNow.current.rowSignature(row.id), []);
23171
+ const rowVersion = useCallback28((row) => editingNow.current.rowSignature(row.id), []);
23046
23172
  const undo = useGridUndo({
23047
23173
  tableId,
23048
23174
  reload: records.reload,
@@ -23059,6 +23185,7 @@ function GridBody({
23059
23185
  sort: sortedField ? { key: sortedField.key, name: fieldName(sortedField) } : null,
23060
23186
  say: (line) => undo.say(line, false, true)
23061
23187
  });
23188
+ const rowMove = useRowFollowsItsMove({ box: gridBox, rowIds });
23062
23189
  pushWritten.current = (write) => {
23063
23190
  const field2 = (fields.data ?? []).find((f) => f.key === write.key);
23064
23191
  const name = changedRecordName(table.data, rows.find((r) => r.id === write.rowId)?.document ?? {}, write.key, write.after);
@@ -23066,6 +23193,7 @@ function GridBody({
23066
23193
  label: `Changed ${field2 ? fieldName(field2) : humanizeIdentifier10(write.key)} on ${name}`,
23067
23194
  cells: [{ rowId: write.rowId, key: write.key, before: write.before ?? null, after: write.after ?? null, version: write.version }]
23068
23195
  });
23196
+ rowMove.noteWrite(write.rowId);
23069
23197
  noteWriteForView(write, name);
23070
23198
  };
23071
23199
  const storeLayout = useStoreGridLayout(tableId);
@@ -23159,7 +23287,7 @@ function GridBody({
23159
23287
  const groupFacts = useGroupFacts({ tableId, groupKey: rowGroupKey, chosen: chosenSummaries, filter: readFilter, version: summaryVersion });
23160
23288
  const groupLabel2 = useGroupLabel(fields.data ?? [], rowGroupKey);
23161
23289
  const [duplicated, setDuplicated] = useState61(null);
23162
- const duplicate = useCallback27(
23290
+ const duplicate = useCallback28(
23163
23291
  async (row) => {
23164
23292
  const document2 = row.document ?? {};
23165
23293
  const data = {};
@@ -23199,7 +23327,7 @@ function GridBody({
23199
23327
  );
23200
23328
  const recordIds = useMemo36(() => rows.map((r) => r.id), [rows]);
23201
23329
  const { cells: enrichCells, refresh: refreshEnrich } = useEnrichCells(tableId, recordIds);
23202
- const pinCell = useCallback27(
23330
+ const pinCell = useCallback28(
23203
23331
  async (recordId, fieldKey, pinned) => {
23204
23332
  const answered = await client.enrichPin({ record_id: recordId, field_key: fieldKey, pinned });
23205
23333
  if (!answered.ok) {
@@ -23215,9 +23343,9 @@ function GridBody({
23215
23343
  const [deleting, setDeleting] = useState61(null);
23216
23344
  const [deleteBusy, setDeleteBusy] = useState61(false);
23217
23345
  const [archived, setArchived] = useState61(null);
23218
- const choiceOptions = useRef36(/* @__PURE__ */ new Map());
23219
- const relationNames = useRef36(/* @__PURE__ */ new Map());
23220
- const loadRelationNames = useCallback27(
23346
+ const choiceOptions = useRef37(/* @__PURE__ */ new Map());
23347
+ const relationNames = useRef37(/* @__PURE__ */ new Map());
23348
+ const loadRelationNames = useCallback28(
23221
23349
  async (fieldList, wanted) => {
23222
23350
  relationNames.current = /* @__PURE__ */ new Map();
23223
23351
  await Promise.all(
@@ -23231,7 +23359,7 @@ function GridBody({
23231
23359
  },
23232
23360
  [client]
23233
23361
  );
23234
- const loadChoiceOptions = useCallback27(
23362
+ const loadChoiceOptions = useCallback28(
23235
23363
  async (fieldList) => {
23236
23364
  const wanted = fieldList.filter(
23237
23365
  (f) => (editorKindFor(f) === "select" || editorKindFor(f) === "multi_select") && !choiceOptions.current.has(f.key)
@@ -23249,7 +23377,7 @@ function GridBody({
23249
23377
  () => ordered.filter((f) => fieldIsEditable(f)).map((f) => f.key),
23250
23378
  [ordered]
23251
23379
  );
23252
- const receivePastePlan = useCallback27(
23380
+ const receivePastePlan = useCallback28(
23253
23381
  async (pasted) => {
23254
23382
  const fieldList = fields.data ?? [];
23255
23383
  const sheetPlan = pasteOntoFieldsOnly(pasted, fieldList);
@@ -23354,7 +23482,7 @@ function GridBody({
23354
23482
  event.stopPropagation();
23355
23483
  setPastedSource({ name: "what you pasted", parsed: { headers: shape.headers, rows: shape.rows }, text: text2 });
23356
23484
  };
23357
- const addPastedOptions = useCallback27(
23485
+ const addPastedOptions = useCallback28(
23358
23486
  async (fieldKey, words2) => {
23359
23487
  const field2 = (fields.data ?? []).find((f) => f.key === fieldKey);
23360
23488
  if (!field2) throw new Error(`This table has no column called ${fieldKey}.`);
@@ -23378,7 +23506,7 @@ function GridBody({
23378
23506
  },
23379
23507
  [client, fields.data, loadChoiceOptions]
23380
23508
  );
23381
- const applyPasteAsOne = useCallback27(
23509
+ const applyPasteAsOne = useCallback28(
23382
23510
  async (plan) => {
23383
23511
  const byId = new Map(rows.map((r) => [r.id, r]));
23384
23512
  const updates = plan.rows.filter((row) => row.recordId !== null).map((row) => ({ row, document: documentOf(row) })).filter((c) => Object.keys(c.document).length > 0);
@@ -23443,9 +23571,9 @@ function GridBody({
23443
23571
  },
23444
23572
  [rows, client, tableId, editing, undo, records, versions, fields.data]
23445
23573
  );
23446
- const pasteAtOnce = useRef36(applyPasteAsOne);
23574
+ const pasteAtOnce = useRef37(applyPasteAsOne);
23447
23575
  pasteAtOnce.current = applyPasteAsOne;
23448
- const writeRange = useCallback27(
23576
+ const writeRange = useCallback28(
23449
23577
  async (patches, intent) => {
23450
23578
  if (patches.length === 0) return;
23451
23579
  const byId = new Map(rows.map((r) => [r.id, r]));
@@ -23466,7 +23594,7 @@ function GridBody({
23466
23594
  },
23467
23595
  [rows, bulk, noun, nounPlural]
23468
23596
  );
23469
- const applyPaste = useCallback27(async () => {
23597
+ const applyPaste = useCallback28(async () => {
23470
23598
  const held = pastePlan;
23471
23599
  if (!held) return { written: 0, readBack: 0, missing: 0, refusals: [] };
23472
23600
  if (merged) {
@@ -23547,8 +23675,8 @@ function GridBody({
23547
23675
  return { written, readBack, missing, refusals };
23548
23676
  }, [pastePlan, client, tableId, records, merged, applyPasteAsOne, versions, fields.data]);
23549
23677
  const columnIds = useMemo36(() => ordered.map((field2) => field2.key), [ordered]);
23550
- const lookWrites = useRef36(null);
23551
- const writeLook = useCallback27(
23678
+ const lookWrites = useRef37(null);
23679
+ const writeLook = useCallback28(
23552
23680
  (next) => {
23553
23681
  if (!onPresentationChange) return;
23554
23682
  const held = lookWrites.current?.base === presentation ? lookWrites.current : null;
@@ -23569,7 +23697,7 @@ function GridBody({
23569
23697
  },
23570
23698
  [onPresentationChange, presentation]
23571
23699
  );
23572
- const chooseSummary = useCallback27(
23700
+ const chooseSummary = useCallback28(
23573
23701
  (key, op2) => {
23574
23702
  const next = { ...chosenSummaries };
23575
23703
  if (op2 === null) delete next[key];
@@ -23580,7 +23708,7 @@ function GridBody({
23580
23708
  },
23581
23709
  [chosenSummaries, presentation, writeLook]
23582
23710
  );
23583
- const handToAgent = useCallback27(
23711
+ const handToAgent = useCallback28(
23584
23712
  (action3, row) => host.runAgentAction?.({
23585
23713
  tableId,
23586
23714
  recordId: row.id,
@@ -23619,14 +23747,14 @@ function GridBody({
23619
23747
  total: typeof records.data?.total === "number" ? records.data.total : null,
23620
23748
  search: searchTerm
23621
23749
  });
23622
- const followRef = useRef36({ openRecordId, onOpenRecord, onCloseRecord });
23750
+ const followRef = useRef37({ openRecordId, onOpenRecord, onCloseRecord });
23623
23751
  followRef.current = { openRecordId, onOpenRecord, onCloseRecord };
23624
- const toggleRecord = useCallback27((rowId) => {
23752
+ const toggleRecord = useCallback28((rowId) => {
23625
23753
  const { openRecordId: open, onOpenRecord: openIt, onCloseRecord: closeIt } = followRef.current;
23626
23754
  if (open === rowId && closeIt) closeIt();
23627
23755
  else openIt?.(rowId);
23628
23756
  }, []);
23629
- const followSelection = useCallback27(
23757
+ const followSelection = useCallback28(
23630
23758
  (selection) => {
23631
23759
  assist.onSelectionChange(selection);
23632
23760
  const { openRecordId: open, onOpenRecord: openIt } = followRef.current;
@@ -23636,7 +23764,7 @@ function GridBody({
23636
23764
  },
23637
23765
  [assist.onSelectionChange]
23638
23766
  );
23639
- const addRowRef = useRef36(() => void 0);
23767
+ const addRowRef = useRef37(() => void 0);
23640
23768
  const valueFacets = useStoreValueFacets(merged && storePaged, {
23641
23769
  client,
23642
23770
  tableId,
@@ -23689,13 +23817,26 @@ function GridBody({
23689
23817
  });
23690
23818
  const [addRefused, setAddRefused] = useState61(null);
23691
23819
  const mayAddRow = merged && !readOnly && rights.write;
23692
- const addRowHere = useCallback27(async (values) => {
23820
+ const formHosted = !embedded && !readOnly && rights.write;
23821
+ const [formAsk, setFormAsk] = useState61(null);
23822
+ const addRowHere = useCallback28(async (values) => {
23693
23823
  setAddRefused(null);
23824
+ if (formHosted && fields.data) {
23825
+ const wouldRefuse = predictWriteRefusals2({ fields: fields.data, document: values ?? {} });
23826
+ if (wouldRefuse.length > 0) {
23827
+ setFormAsk((held) => ({ n: (held?.n ?? 0) + 1, initial: { ...values ?? {} } }));
23828
+ return;
23829
+ }
23830
+ }
23694
23831
  const hold = holdKeys();
23695
23832
  sheetController.current?.focusGrid();
23696
23833
  const done = await added.add(values);
23697
23834
  if ("error" in done) {
23698
23835
  hold.release();
23836
+ if (formHosted && done.error.code === "refused_by_rule") {
23837
+ setFormAsk((held) => ({ n: (held?.n ?? 0) + 1, initial: { ...values ?? {} } }));
23838
+ return;
23839
+ }
23699
23840
  setAddRefused(done.error);
23700
23841
  return;
23701
23842
  }
@@ -23718,21 +23859,21 @@ function GridBody({
23718
23859
  } finally {
23719
23860
  hold.release();
23720
23861
  }
23721
- }, [added, controls.columns, columnIds, fields.data, editing, records, undo]);
23862
+ }, [added, controls.columns, columnIds, fields.data, editing, records, undo, formHosted]);
23722
23863
  addRowRef.current = () => void addRowHere();
23723
- const addFromTemplateRef = useRef36(() => void 0);
23864
+ const addFromTemplateRef = useRef37(() => void 0);
23724
23865
  addFromTemplateRef.current = (values) => void addRowHere(values);
23725
- const formCreatedRef = useRef36(() => void 0);
23866
+ const formCreatedRef = useRef37(() => void 0);
23726
23867
  formCreatedRef.current = (id) => {
23727
23868
  added.pin({ id, document: {}, level: "editor", hidden: {} });
23728
23869
  undo.push({ label: "Added a record", cells: [], created: [id] });
23729
23870
  records.reload();
23730
23871
  };
23731
23872
  const labels = useRecordLabels(ordered);
23732
- const labelsNow = useRef36(labels);
23873
+ const labelsNow = useRef37(labels);
23733
23874
  labelsNow.current = labels;
23734
- const labelFor = useCallback27((field2, id) => labelsNow.current(field2, id), []);
23735
- useEffect51(() => {
23875
+ const labelFor = useCallback28((field2, id) => labelsNow.current(field2, id), []);
23876
+ useEffect52(() => {
23736
23877
  for (const field2 of ordered) {
23737
23878
  if (!pointsAtRecords(field2)) continue;
23738
23879
  for (const row of rows) for (const id of idsOf(row.document?.[field2.key])) labels(field2, id);
@@ -23780,7 +23921,7 @@ function GridBody({
23780
23921
  pinCell
23781
23922
  ]
23782
23923
  );
23783
- const footerNow = useRef36({
23924
+ const footerNow = useRef37({
23784
23925
  summaryCell: () => null,
23785
23926
  addLine: () => null,
23786
23927
  choose: () => void 0,
@@ -23809,7 +23950,7 @@ function GridBody({
23809
23950
  },
23810
23951
  addLine: () => /* @__PURE__ */ jsx72(AddRowLine, { onAdd: () => footerNow.current.add(), busy: added.busy, label: newRowLabel ?? "Add row" })
23811
23952
  };
23812
- const addColumnNow = useRef36(controls.addColumn);
23953
+ const addColumnNow = useRef37(controls.addColumn);
23813
23954
  addColumnNow.current = controls.addColumn;
23814
23955
  const rowIdsOnScreen = useMemo36(() => rows.map((row) => row.id), [rows]);
23815
23956
  const reverseGridColumns = useReverseGridColumns(tableId, rowIdsOnScreen);
@@ -23838,7 +23979,7 @@ function GridBody({
23838
23979
  ),
23839
23980
  [fieldColumns, reverseGridColumns, onOpenRecord, table.data, merged, mayAddRow, hrefForRecord]
23840
23981
  );
23841
- const isRowSelectable = useCallback27((row) => row.id !== SUMMARY_ROW.id && mayWriteRow(row.id), [mayWriteRow]);
23982
+ const isRowSelectable = useCallback28((row) => row.id !== SUMMARY_ROW.id && mayWriteRow(row.id), [mayWriteRow]);
23842
23983
  const copyConfig = useMemo36(
23843
23984
  () => table.data ? gridCopyConfig({
23844
23985
  tableId,
@@ -23861,7 +24002,7 @@ function GridBody({
23861
24002
  },
23862
24003
  [paint]
23863
24004
  );
23864
- const rowActionsNow = useRef36({ runner, handToAgent, host, table: table.data, duplicate });
24005
+ const rowActionsNow = useRef37({ runner, handToAgent, host, table: table.data, duplicate });
23865
24006
  rowActionsNow.current = { runner, handToAgent, host, table: table.data, duplicate };
23866
24007
  const offersRowActions = !embedded && (canWrite || Boolean(host.talkToRecord) || Boolean(!readOnly && host.runAgentAction && tableActions2.agent.length > 0));
23867
24008
  const hasTalk = Boolean(host.talkToRecord);
@@ -23871,7 +24012,7 @@ function GridBody({
23871
24012
  () => /* @__PURE__ */ jsx72(ActionsHeaderControls, { ...mayManageActions ? { onAddColumn: () => addColumnNow.current() } : {} }),
23872
24013
  [mayManageActions]
23873
24014
  );
23874
- const rowActions = useCallback27(
24015
+ const rowActions = useCallback28(
23875
24016
  (row) => /* @__PURE__ */ jsxs65(Fragment25, { children: [
23876
24017
  canWrite && mayWriteRow(row.id) ? tableActions2.runnable.map((action3) => /* @__PURE__ */ jsx72(
23877
24018
  ActionButton,
@@ -23937,8 +24078,8 @@ function GridBody({
23937
24078
  // eslint-disable-next-line react-hooks/exhaustive-deps -- `hasTalk`/`hasAgent` stand for the host ports the JSX reads; handlers run through `rowActionsNow`.
23938
24079
  [canWrite, mayWriteRow, tableActions2.runnable, tableActions2.agent, runner.busy, hasTalk, hasAgent, editable, rights.write, readOnly]
23939
24080
  );
23940
- const headerHeld = useRef36(/* @__PURE__ */ new Map());
23941
- const menuLatest = useRef36(/* @__PURE__ */ new Map());
24081
+ const headerHeld = useRef37(/* @__PURE__ */ new Map());
24082
+ const menuLatest = useRef37(/* @__PURE__ */ new Map());
23942
24083
  const addColumnDef = useMemo36(() => addColumnColumn(() => addColumnNow.current()), []);
23943
24084
  const drawnColumns = useMemo36(
23944
24085
  () => {
@@ -23952,7 +24093,7 @@ function GridBody({
23952
24093
  },
23953
24094
  [bodyColumns, controls.headerMenuFor, controls.filterFor, merged, rights.structure, readOnly, addColumnDef]
23954
24095
  );
23955
- const columnsHeld = useRef36(null);
24096
+ const columnsHeld = useRef37(null);
23956
24097
  const columns = columnsHeld.current !== null && sameColumns(columnsHeld.current, drawnColumns) ? columnsHeld.current : drawnColumns;
23957
24098
  columnsHeld.current = columns;
23958
24099
  const tableColumns = useMemo36(
@@ -23966,7 +24107,7 @@ function GridBody({
23966
24107
  null
23967
24108
  );
23968
24109
  const [localWidths, setLocalWidths] = useState61(null);
23969
- const changeLayout = useCallback27(
24110
+ const changeLayout = useCallback28(
23970
24111
  (patch) => {
23971
24112
  setLocalLook((held) => ({ ...held ?? {}, ...patch }));
23972
24113
  const next = { ...presentation };
@@ -24089,7 +24230,7 @@ function GridBody({
24089
24230
  }),
24090
24231
  [storePaged, coverageTotal]
24091
24232
  );
24092
- const sheetNow = useRef36({ merged, writeRange, editing, fields: fields.data ?? [], rows, mayWriteRow, notify: host.notify });
24233
+ const sheetNow = useRef37({ merged, writeRange, editing, fields: fields.data ?? [], rows, mayWriteRow, notify: host.notify });
24093
24234
  sheetNow.current = { merged, writeRange, editing, fields: fields.data ?? [], rows, mayWriteRow, notify: host.notify };
24094
24235
  const hasNotify = Boolean(host.notify);
24095
24236
  const readOnlyReason = !editable || !rights.known || rights.write ? "Editing is off here, so this table can be copied but not changed." : rights.why("write");
@@ -24288,7 +24429,8 @@ function GridBody({
24288
24429
  noun,
24289
24430
  busy: added.busy,
24290
24431
  onAdd: () => addRowRef.current(),
24291
- onCreated: (id) => formCreatedRef.current(id)
24432
+ onCreated: (id) => formCreatedRef.current(id),
24433
+ ask: formAsk
24292
24434
  }
24293
24435
  )
24294
24436
  } : {},
@@ -24386,12 +24528,13 @@ function GridBody({
24386
24528
  tableId,
24387
24529
  noun,
24388
24530
  embedded,
24531
+ formAsk,
24389
24532
  searchOverride,
24390
24533
  onSearchChange,
24391
24534
  searchBox
24392
24535
  ]
24393
24536
  );
24394
- const labelOfField = useCallback27(
24537
+ const labelOfField = useCallback28(
24395
24538
  (key) => {
24396
24539
  const held = (fields.data ?? []).find((f) => f.key === key);
24397
24540
  return held ? fieldName(held) : humanizeIdentifier10(key);
@@ -24400,7 +24543,7 @@ function GridBody({
24400
24543
  );
24401
24544
  const rowMemoryKey = `${tableId}:${embedded ? "embedded" : "page"}:${openingKey}`;
24402
24545
  const rowsAnswered = Boolean(records.data) && !records.loading && !table.loading && !fields.loading;
24403
- useEffect51(() => {
24546
+ useEffect52(() => {
24404
24547
  if (rowsAnswered) {
24405
24548
  rememberRowCount(rowMemoryKey, rows.length);
24406
24549
  if (!embedded) rememberRowCount(`${tableId}:page:last`, rows.length);
@@ -24582,6 +24725,7 @@ function GridBody({
24582
24725
  /* @__PURE__ */ jsx72(
24583
24726
  "div",
24584
24727
  {
24728
+ ref: gridBox,
24585
24729
  className: "contents",
24586
24730
  "data-records-grid-wrap": look.wrap ? "on" : "off",
24587
24731
  "data-records-grid-fit": look.fit,
@@ -24885,7 +25029,7 @@ import { MatrxDataTable as MatrxDataTable3 } from "@ai-matrx/design-system/data-
24885
25029
  import { useRecordsClient as useRecordsClient40 } from "@ai-matrx/records/react";
24886
25030
 
24887
25031
  // ../entity-data/src/react/index.tsx
24888
- import { createContext as createContext8, createElement, useContext as useContext8, useMemo as useMemo37, useRef as useRef37 } from "react";
25032
+ import { createContext as createContext8, createElement, useContext as useContext8, useMemo as useMemo37, useRef as useRef38 } from "react";
24889
25033
  import { useQuery } from "@tanstack/react-query";
24890
25034
  import {
24891
25035
  dataKeys,
@@ -25055,12 +25199,12 @@ var DEFAULT_MAX_ORG_TOPICS = 20;
25055
25199
  function entityNoticeKey(notice) {
25056
25200
  return notice.id ?? (notice.at ? `${notice.organization_id ?? ""}:${notice.entity_type ?? ""}:${notice.at}` : void 0);
25057
25201
  }
25058
- function entityOrgTopic(organizationId, token) {
25059
- return entityOrgChannel.topic({ organizationId, token });
25202
+ function entityOrgTopic(organizationId, token2) {
25203
+ return entityOrgChannel.topic({ organizationId, token: token2 });
25060
25204
  }
25061
- function entityOrgChannelSpec(organizationId, token, onNotice, onBackfill) {
25205
+ function entityOrgChannelSpec(organizationId, token2, onNotice, onBackfill) {
25062
25206
  return {
25063
- topic: entityOrgTopic(organizationId, token),
25207
+ topic: entityOrgTopic(organizationId, token2),
25064
25208
  // Database Broadcast is authorized by RLS on realtime.messages; the manager awaits setAuth() first.
25065
25209
  private: true,
25066
25210
  // The sender is Postgres: no Matrx envelope. Our own write is known by the op id it carried.
@@ -25099,11 +25243,11 @@ function createEntityRealtime(options = {}) {
25099
25243
  const batchMs = options.batchMs ?? DEFAULT_BATCH_MS;
25100
25244
  const maxWaitMs = options.maxWaitMs ?? DEFAULT_MAX_WAIT_MS;
25101
25245
  const channels = /* @__PURE__ */ new Map();
25102
- const open = (organizationId, token) => {
25246
+ const open = (organizationId, token2) => {
25103
25247
  const channel = { listeners: /* @__PURE__ */ new Set(), stop: null };
25104
25248
  const spec = entityOrgChannelSpec(
25105
25249
  organizationId,
25106
- token,
25250
+ token2,
25107
25251
  (notice) => {
25108
25252
  for (const listener of channel.listeners) listener.notice(notice);
25109
25253
  },
@@ -25120,7 +25264,7 @@ function createEntityRealtime(options = {}) {
25120
25264
  return channel;
25121
25265
  };
25122
25266
  return {
25123
- subscribe({ token, organizationIds }, sink) {
25267
+ subscribe({ token: token2, organizationIds }, sink) {
25124
25268
  let timer = null;
25125
25269
  let firstAt = 0;
25126
25270
  let pending = /* @__PURE__ */ new Set();
@@ -25144,7 +25288,7 @@ function createEntityRealtime(options = {}) {
25144
25288
  };
25145
25289
  const listener = {
25146
25290
  notice(notice) {
25147
- if (notice.entity_type && notice.entity_type !== token) return;
25291
+ if (notice.entity_type && notice.entity_type !== token2) return;
25148
25292
  if (notice.ids == null) wholeList = true;
25149
25293
  else for (const id of notice.ids) pending.add(id);
25150
25294
  nudge();
@@ -25155,8 +25299,8 @@ function createEntityRealtime(options = {}) {
25155
25299
  }
25156
25300
  };
25157
25301
  const keys = [...new Set(organizationIds)].map((org) => {
25158
- const key = entityOrgTopic(org, token);
25159
- const channel = channels.get(key) ?? open(org, token);
25302
+ const key = entityOrgTopic(org, token2);
25303
+ const channel = channels.get(key) ?? open(org, token2);
25160
25304
  channels.set(key, channel);
25161
25305
  channel.listeners.add(listener);
25162
25306
  return key;
@@ -25368,7 +25512,7 @@ function createEntityDataPort(options) {
25368
25512
  }
25369
25513
  return held2;
25370
25514
  }
25371
- function getCoalesced(alias, token, id) {
25515
+ function getCoalesced(alias, token2, id) {
25372
25516
  return new Promise((resolve) => {
25373
25517
  let batch = gets.get(alias);
25374
25518
  if (!batch) {
@@ -25377,7 +25521,7 @@ function createEntityDataPort(options) {
25377
25521
  const asked3 = batch;
25378
25522
  queueMicrotask(() => {
25379
25523
  gets.delete(alias);
25380
- void flushGets(alias, token, asked3);
25524
+ void flushGets(alias, token2, asked3);
25381
25525
  });
25382
25526
  }
25383
25527
  const waiting = batch.get(id) ?? [];
@@ -25385,8 +25529,8 @@ function createEntityDataPort(options) {
25385
25529
  batch.set(id, waiting);
25386
25530
  });
25387
25531
  }
25388
- async function flushGets(alias, token, asked3) {
25389
- const answer = await client.get({ token, ids: [...asked3.keys()] });
25532
+ async function flushGets(alias, token2, asked3) {
25533
+ const answer = await client.get({ token: token2, ids: [...asked3.keys()] });
25390
25534
  if (answer.ok) hold(alias, answer.data.rows);
25391
25535
  const byId = new Map(answer.ok ? answer.data.rows.map((r) => [r.id, r]) : []);
25392
25536
  for (const [id, waiting] of asked3) {
@@ -25459,6 +25603,7 @@ function createEntityDataPort(options) {
25459
25603
  customKeys = new Set(shape.data.columns.filter((c) => c.origin === "custom").map((c) => c.key));
25460
25604
  }
25461
25605
  const wire = toWire(q, customKeys);
25606
+ if (binding.organizationId) wire.scope = { ...wire.scope, organization_id: binding.organizationId };
25462
25607
  const answer = await client.list({ token: binding.token, ...wire, after: cursor ?? null });
25463
25608
  if (!answer.ok) return answer;
25464
25609
  const { data } = answer;
@@ -25483,7 +25628,7 @@ function createEntityDataPort(options) {
25483
25628
  async create(alias, values) {
25484
25629
  const binding = bindingOf(alias);
25485
25630
  if (!binding) return noSuchAlias(alias);
25486
- const organizationId = activeOrganization();
25631
+ const organizationId = binding.organizationId ?? activeOrganization();
25487
25632
  if (!organizationId) {
25488
25633
  return refusal2(
25489
25634
  "organization_required",
@@ -25565,7 +25710,7 @@ function createEntityDataPort(options) {
25565
25710
  var ENTITY_PORT_KEY = "entity-data";
25566
25711
  var EntityScopeContext = createContext8(null);
25567
25712
  function EntityDataProvider({ dataSource, client, activeOrganizationId, realtime, portKey = ENTITY_PORT_KEY, children }) {
25568
- const active = useRef37(activeOrganizationId);
25713
+ const active = useRef38(activeOrganizationId);
25569
25714
  active.current = activeOrganizationId;
25570
25715
  const scope = useMemo37(() => {
25571
25716
  const bound2 = client ?? createEntityClient({ dataSource });
@@ -25593,20 +25738,20 @@ function useEntityScope() {
25593
25738
  }
25594
25739
  return scope;
25595
25740
  }
25596
- function useEntityList(token, query = {}) {
25597
- return useDataRows(token, query, useEntityScope());
25741
+ function useEntityList(token2, query = {}) {
25742
+ return useDataRows(token2, query, useEntityScope());
25598
25743
  }
25599
- function useEntityColumns(token) {
25600
- return useDataColumns(token, useEntityScope());
25744
+ function useEntityColumns(token2) {
25745
+ return useDataColumns(token2, useEntityScope());
25601
25746
  }
25602
- function useEntityType(token) {
25747
+ function useEntityType(token2) {
25603
25748
  const scope = useEntityScope();
25604
25749
  const qc = useRecordsQueryClient();
25605
25750
  const q = useQuery(
25606
25751
  {
25607
- queryKey: [...dataKeys.alias(scope.portKey, token), "type"],
25752
+ queryKey: [...dataKeys.alias(scope.portKey, token2), "type"],
25608
25753
  queryFn: async () => {
25609
- const answer = await scope.port.describe(token);
25754
+ const answer = await scope.port.describe(token2);
25610
25755
  if (!answer.ok) throw Object.assign(new Error(answer.error.message), { error: answer.error });
25611
25756
  return answer.data;
25612
25757
  },
@@ -25617,8 +25762,8 @@ function useEntityType(token) {
25617
25762
  const failed = q.error;
25618
25763
  return { data: q.data, loading: q.isPending, error: failed ? failed.error ?? { code: "internal", message: failed.message } : null, refresh: () => void q.refetch() };
25619
25764
  }
25620
- function useEntityWrite(token) {
25621
- return useDataMutations(token, useEntityScope());
25765
+ function useEntityWrite(token2) {
25766
+ return useDataMutations(token2, useEntityScope());
25622
25767
  }
25623
25768
 
25624
25769
  // src/entityTable.tsx
@@ -25670,17 +25815,17 @@ function editTypeOf(column) {
25670
25815
  if (column.type === "checkbox" || column.type === "boolean") return "boolean";
25671
25816
  return false;
25672
25817
  }
25673
- function useEntityTable(token, options = {}) {
25818
+ function useEntityTable(token2, options = {}) {
25674
25819
  const search = (options.search ?? "").trim();
25675
- const type = useEntityType(token);
25676
- const columns = useEntityColumns(token);
25677
- const list = useEntityList(token, { ...options.pageSize ? { pageSize: options.pageSize } : {}, ...search ? { search } : {} });
25678
- const write = useEntityWrite(token);
25820
+ const type = useEntityType(token2);
25821
+ const columns = useEntityColumns(token2);
25822
+ const list = useEntityList(token2, { ...options.pageSize ? { pageSize: options.pageSize } : {}, ...search ? { search } : {} });
25823
+ const write = useEntityWrite(token2);
25679
25824
  const shown4 = useMemo38(() => entityShownColumns(columns.data ?? []), [columns.data]);
25680
25825
  const refused = list.error ?? columns.error ?? type.error;
25681
25826
  const name = entityNameColumn(shown4);
25682
25827
  return {
25683
- token,
25828
+ token: token2,
25684
25829
  label: type.data?.label ?? null,
25685
25830
  columns: shown4,
25686
25831
  rows: list.rows,
@@ -25871,7 +26016,7 @@ function ConnectedRecordsTableCard({
25871
26016
 
25872
26017
  // src/ExportMenu.tsx
25873
26018
  import { downloadFile as downloadFile2 } from "@ai-matrx/kit/download";
25874
- import { useEffect as useEffect52, useState as useState62 } from "react";
26019
+ import { useEffect as useEffect53, useState as useState62 } from "react";
25875
26020
  import { useFields as useFields10, useRecords as useRecords6, useRecordsClient as useRecordsClient41, useTable as useTable8 } from "@ai-matrx/records/react";
25876
26021
  import { exportCsv, exportXlsx, wholeValueOf as wholeValueOf5, withWholeValues } from "@ai-matrx/records/core";
25877
26022
 
@@ -25980,7 +26125,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
25980
26125
  const page = useRecords6(view ? null : tableId, { pageSize: 500 });
25981
26126
  const viewKey = view ? JSON.stringify([view.filter ?? null, view.sorts ?? [], view.viewId ?? null]) : "";
25982
26127
  const [viewRead, setViewRead] = useState62(null);
25983
- useEffect52(() => {
26128
+ useEffect53(() => {
25984
26129
  if (!view || !fields.data) return;
25985
26130
  let live = true;
25986
26131
  void readViewRows(client, tableId, fields.data, view).then((read) => {
@@ -26061,7 +26206,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
26061
26206
  }
26062
26207
 
26063
26208
  // src/ImportNotice.tsx
26064
- import { useCallback as useCallback28, useEffect as useEffect53, useMemo as useMemo39, useState as useState63 } from "react";
26209
+ import { useCallback as useCallback29, useEffect as useEffect54, useMemo as useMemo39, useState as useState63 } from "react";
26065
26210
  import { useRecordsClient as useRecordsClient42 } from "@ai-matrx/records/react";
26066
26211
  import { Button as Button45, cn as cn38 } from "@ai-matrx/design-system";
26067
26212
  import { jsx as jsx76, jsxs as jsxs68 } from "react/jsx-runtime";
@@ -26092,7 +26237,7 @@ function ImportNotice({ tableId, onOpenImport, epoch = 0, className }) {
26092
26237
  const [problem, setProblem] = useState63(null);
26093
26238
  const [report, setReport] = useState63(null);
26094
26239
  const [dismissed, setDismissed] = useState63(null);
26095
- useEffect53(() => {
26240
+ useEffect54(() => {
26096
26241
  let live = true;
26097
26242
  void client.imports({ table_id: tableId, limit: 5 }).then((answered) => {
26098
26243
  if (!live) return;
@@ -26107,7 +26252,7 @@ function ImportNotice({ tableId, onOpenImport, epoch = 0, className }) {
26107
26252
  }, [client, tableId, epoch]);
26108
26253
  const run = useMemo39(() => runs ? runToNotice(runs) : null, [runs]);
26109
26254
  const shown4 = run && !wasDismissed(run.import_id) && dismissed !== run.import_id ? run : null;
26110
- useEffect53(() => {
26255
+ useEffect54(() => {
26111
26256
  if (!shown4 || report?.import_id === shown4.import_id) return;
26112
26257
  let live = true;
26113
26258
  void client.importReport({ import_id: shown4.import_id, state: "refused", limit: 500 }).then((answered) => {
@@ -26118,7 +26263,7 @@ function ImportNotice({ tableId, onOpenImport, epoch = 0, className }) {
26118
26263
  live = false;
26119
26264
  };
26120
26265
  }, [client, shown4, report]);
26121
- const dismiss = useCallback28(() => {
26266
+ const dismiss = useCallback29(() => {
26122
26267
  if (!shown4) return;
26123
26268
  remember(shown4.import_id);
26124
26269
  setDismissed(shown4.import_id);
@@ -26181,7 +26326,7 @@ import {
26181
26326
  } from "@ai-matrx/design-system";
26182
26327
 
26183
26328
  // src/TablesHome.tsx
26184
- import { useCallback as useCallback32, useEffect as useEffect58, useState as useState68 } from "react";
26329
+ import { useCallback as useCallback33, useEffect as useEffect59, useState as useState68 } from "react";
26185
26330
  import { useRecordsClient as useRecordsClient47, useTables as useTables2 } from "@ai-matrx/records/react";
26186
26331
  import { withTableFacts } from "@ai-matrx/records/core";
26187
26332
  import { withTablePlacement as withTablePlacement2 } from "@ai-matrx/records";
@@ -26366,7 +26511,7 @@ function fieldsForNewColumns(columns) {
26366
26511
 
26367
26512
  // src/BookingSlots.tsx
26368
26513
  import { copyText as copyText3 } from "@ai-matrx/kit/clipboard";
26369
- import { useCallback as useCallback31, useEffect as useEffect56, useMemo as useMemo41, useState as useState66 } from "react";
26514
+ import { useCallback as useCallback32, useEffect as useEffect57, useMemo as useMemo41, useState as useState66 } from "react";
26370
26515
  import { useRecordsClient as useRecordsClient45, useMyLevels as useMyLevels2 } from "@ai-matrx/records/react";
26371
26516
  import { bookingPath as bookingPath2 } from "@ai-matrx/records";
26372
26517
  import { Badge as Badge11, Button as Button49, Skeleton as Skeleton7, cn as cn41 } from "@ai-matrx/design-system";
@@ -26374,7 +26519,7 @@ import { Badge as Badge11, Button as Button49, Skeleton as Skeleton7, cn as cn41
26374
26519
  // src/BookingBuilder.tsx
26375
26520
  import { copyText as copyText2 } from "@ai-matrx/kit/clipboard";
26376
26521
  import { ErrorBox as ErrorBox3 } from "@ai-matrx/design-system";
26377
- import { useCallback as useCallback29, useEffect as useEffect54, useMemo as useMemo40, useRef as useRef38, useState as useState64 } from "react";
26522
+ import { useCallback as useCallback30, useEffect as useEffect55, useMemo as useMemo40, useRef as useRef39, useState as useState64 } from "react";
26378
26523
  import { useFields as useFields11, useRecordsClient as useRecordsClient43, useTable as useTable9 } from "@ai-matrx/records/react";
26379
26524
  import { formatDurationMinutes } from "@ai-matrx/kit/format";
26380
26525
  import {
@@ -26511,7 +26656,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, startNew, classN
26511
26656
  const [confirmation, setConfirmation] = useState64("");
26512
26657
  const [offer, setOffer] = useState64(null);
26513
26658
  const [formId, setFormId] = useState64(bookingId ?? null);
26514
- const madeRef = useRef38(null);
26659
+ const madeRef = useRef39(null);
26515
26660
  const publicOrigin = host.publicOrigin ?? (typeof window === "undefined" ? "" : window.location.origin);
26516
26661
  const askable = useMemo40(
26517
26662
  () => askableFields(fields.data ?? [], STORE_ANSWERS_THESE),
@@ -26522,7 +26667,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, startNew, classN
26522
26667
  () => whyNotAskable(fields.data ?? [], STORE_ANSWERS_THESE),
26523
26668
  [fields.data]
26524
26669
  );
26525
- const load = useCallback29(async () => {
26670
+ const load = useCallback30(async () => {
26526
26671
  const answered = await client.bookings({ table_id: tableId });
26527
26672
  if (!answered.ok) {
26528
26673
  setError(answered.error);
@@ -26547,19 +26692,19 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, startNew, classN
26547
26692
  }
26548
26693
  setLoaded(true);
26549
26694
  }, [client, tableId, bookingId, startNew]);
26550
- useEffect54(() => {
26695
+ useEffect55(() => {
26551
26696
  void load();
26552
26697
  }, [load]);
26553
- useEffect54(() => {
26698
+ useEffect55(() => {
26554
26699
  if (title !== "" || !table.data) return;
26555
26700
  setTitle(existing?.title ?? `Book a ${minutes}-minute ${singularNoun(table.data, "appointment")}`);
26556
26701
  }, [table.data, existing]);
26557
- useEffect54(() => {
26702
+ useEffect55(() => {
26558
26703
  if (!existing) return;
26559
26704
  setMinutes(existing.slot_minutes);
26560
26705
  if (existing.timezone && existing.timezone !== "UTC") setTimezone(existing.timezone);
26561
26706
  }, [existing]);
26562
- useEffect54(() => {
26707
+ useEffect55(() => {
26563
26708
  if (!offer) return;
26564
26709
  setWindows(draftWindows(offer));
26565
26710
  setMinutes(offer.slot_minutes);
@@ -26569,7 +26714,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, startNew, classN
26569
26714
  setDays(offer.days);
26570
26715
  if (offer.timezone && offer.timezone !== "UTC") setTimezone(offer.timezone);
26571
26716
  }, [offer]);
26572
- const availability = useCallback29(
26717
+ const availability = useCallback30(
26573
26718
  () => ({
26574
26719
  timezone,
26575
26720
  slot_minutes: minutes,
@@ -26581,8 +26726,8 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, startNew, classN
26581
26726
  }),
26582
26727
  [timezone, minutes, buffer, lead, perDay, days, windows]
26583
26728
  );
26584
- const startedAsking = useRef38(false);
26585
- useEffect54(() => {
26729
+ const startedAsking = useRef39(false);
26730
+ useEffect55(() => {
26586
26731
  if (startedAsking.current || !loaded || existing || formId || !fields.data) return;
26587
26732
  startedAsking.current = true;
26588
26733
  if (asked3.length > 0) return;
@@ -26610,7 +26755,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, startNew, classN
26610
26755
  setWhoAdded(true);
26611
26756
  }
26612
26757
  const [whoAdded, setWhoAdded] = useState64(false);
26613
- useEffect54(() => {
26758
+ useEffect55(() => {
26614
26759
  if (!whoAdded) return;
26615
26760
  const who = askable.filter((f) => isWhoField(f)).map((f) => f.key);
26616
26761
  if (who.length === 0) return;
@@ -26919,7 +27064,7 @@ function BuildOrAsk({
26919
27064
  }
26920
27065
 
26921
27066
  // src/BuiltOnArchive.tsx
26922
- import { useCallback as useCallback30, useEffect as useEffect55, useState as useState65 } from "react";
27067
+ import { useCallback as useCallback31, useEffect as useEffect56, useState as useState65 } from "react";
26923
27068
  import {
26924
27069
  archivedWhen,
26925
27070
  BUILT_KIND_WORD
@@ -27329,7 +27474,7 @@ function ArchivedBuiltOn({ tableId, onRestored }) {
27329
27474
  const [restoring, setRestoring] = useState65(null);
27330
27475
  const [refusal4, setRefusal] = useState65(null);
27331
27476
  const [said2, setSaid] = useState65(null);
27332
- const read = useCallback30(async () => {
27477
+ const read = useCallback31(async () => {
27333
27478
  const [forms, checklists] = await Promise.all([
27334
27479
  client.formsArchived({ table_id: tableId }),
27335
27480
  client.checklistTemplatesArchived({ about_table_id: tableId })
@@ -27339,7 +27484,7 @@ function ArchivedBuiltOn({ tableId, onRestored }) {
27339
27484
  setError(null);
27340
27485
  setThings(archivedThings(forms.data, checklists.data));
27341
27486
  }, [client, tableId]);
27342
- useEffect55(() => {
27487
+ useEffect56(() => {
27343
27488
  void read();
27344
27489
  }, [read]);
27345
27490
  const restore = async (thing) => {
@@ -27421,7 +27566,7 @@ function BookingSlots({ tableId, activeBookingId, className }) {
27421
27566
  const [building, setBuilding] = useState66(false);
27422
27567
  const [archivedSaid, setArchivedSaid] = useState66(null);
27423
27568
  const [changing, setChanging] = useState66(null);
27424
- const load = useCallback31(async () => {
27569
+ const load = useCallback32(async () => {
27425
27570
  const answered = await client.bookings(tableId ? { table_id: tableId } : {});
27426
27571
  if (!answered.ok) {
27427
27572
  setError(answered.error);
@@ -27431,7 +27576,7 @@ function BookingSlots({ tableId, activeBookingId, className }) {
27431
27576
  setError(null);
27432
27577
  setPages(answered.data);
27433
27578
  }, [client, tableId]);
27434
- useEffect56(() => {
27579
+ useEffect57(() => {
27435
27580
  void load();
27436
27581
  }, [load]);
27437
27582
  const subjectIds = useMemo41(
@@ -27450,7 +27595,7 @@ function BookingSlots({ tableId, activeBookingId, className }) {
27450
27595
  const levels = useMyLevels2(subjectIds);
27451
27596
  const levelsKnown = !levels.loading && Boolean(levels.data);
27452
27597
  const mayBuildHere = levelsKnown && Boolean(tableId) && levels.data?.[tableId] === "admin";
27453
- const toggle = useCallback31(
27598
+ const toggle = useCallback32(
27454
27599
  async (page) => {
27455
27600
  setBusy(page.form_id);
27456
27601
  const wanted = page.published_at === null || page.closed_at !== null;
@@ -27464,7 +27609,7 @@ function BookingSlots({ tableId, activeBookingId, className }) {
27464
27609
  },
27465
27610
  [client, load]
27466
27611
  );
27467
- const copy = useCallback31(async (url, formId) => {
27612
+ const copy = useCallback32(async (url, formId) => {
27468
27613
  if (await copyText3(url)) {
27469
27614
  setCopied(formId);
27470
27615
  setShown(null);
@@ -27648,7 +27793,7 @@ function nextInWords(page) {
27648
27793
  }
27649
27794
 
27650
27795
  // src/WhereItLives.tsx
27651
- import { useEffect as useEffect57, useState as useState67 } from "react";
27796
+ import { useEffect as useEffect58, useState as useState67 } from "react";
27652
27797
  import { moveConsequence } from "@ai-matrx/records";
27653
27798
  import { useRecordsClient as useRecordsClient46 } from "@ai-matrx/records/react";
27654
27799
  import { Button as Button50, ErrorBox as ErrorBox4, Popover as Popover8, PopoverContent as PopoverContent8, PopoverTrigger as PopoverTrigger8 } from "@ai-matrx/design-system";
@@ -27660,7 +27805,7 @@ function WhereItLives({ tableId, knownOrganizationName, onMoved, variant = "head
27660
27805
  const [attempt, setAttempt] = useState67(0);
27661
27806
  const [open, setOpen] = useState67(false);
27662
27807
  const [armed, setArmed] = useState67(variant === "anchor" ? false : variant !== "row" || !knownOrganizationName);
27663
- useEffect57(() => {
27808
+ useEffect58(() => {
27664
27809
  if (openAsked <= 0) return;
27665
27810
  setArmed(true);
27666
27811
  setOpen(true);
@@ -27668,7 +27813,7 @@ function WhereItLives({ tableId, knownOrganizationName, onMoved, variant = "head
27668
27813
  const [choosing, setChoosing] = useState67(null);
27669
27814
  const [moving, setMoving] = useState67(false);
27670
27815
  const [said2, setSaid] = useState67(null);
27671
- useEffect57(() => {
27816
+ useEffect58(() => {
27672
27817
  if (!armed) return;
27673
27818
  let alive = true;
27674
27819
  setAnswer(null);
@@ -27925,7 +28070,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
27925
28070
  const tables = useTables2();
27926
28071
  const me = client.config.actor.user_id ?? null;
27927
28072
  const [facts, setFacts] = useState68({ phase: "reading" });
27928
- useEffect58(() => {
28073
+ useEffect59(() => {
27929
28074
  let alive = true;
27930
28075
  void client.tableFacts().then((answered) => {
27931
28076
  if (!alive) return;
@@ -27943,7 +28088,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
27943
28088
  const keptCount = listed.filter((t) => laneFor(t) === "app").length;
27944
28089
  const [askedName, setAskedName] = useState68(null);
27945
28090
  const firstTableId = listed[0]?.id ?? null;
27946
- useEffect58(() => {
28091
+ useEffect59(() => {
27947
28092
  if (organizationName || !firstTableId) return;
27948
28093
  let alive = true;
27949
28094
  void client.tableHome({ table_id: firstTableId }).then((answered) => {
@@ -27964,12 +28109,12 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
27964
28109
  const [error, setError] = useState68(null);
27965
28110
  const [importInto, setImportInto] = useState68(null);
27966
28111
  const createAsked = askedBy?.create ?? 0;
27967
- useEffect58(() => {
28112
+ useEffect59(() => {
27968
28113
  if (createAsked > 0) setCreating(true);
27969
28114
  }, [createAsked]);
27970
28115
  const hostButtons = askedBy !== void 0;
27971
28116
  const [boards, setBoards] = useState68(null);
27972
- useEffect58(() => {
28117
+ useEffect59(() => {
27973
28118
  if (makingOnly) return;
27974
28119
  let cancelled = false;
27975
28120
  void client.dashboards({}).then((result) => {
@@ -27980,7 +28125,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
27980
28125
  cancelled = true;
27981
28126
  };
27982
28127
  }, [client, makingOnly]);
27983
- const create = useCallback32(
28128
+ const create = useCallback33(
27984
28129
  async (mode) => {
27985
28130
  const trimmed = name.trim();
27986
28131
  if (!trimmed) return;
@@ -28632,7 +28777,7 @@ function SaveToTable({ source, shapeIndex = 0, onOpenTable, onSaved, onClose, cl
28632
28777
  }
28633
28778
 
28634
28779
  // src/StageRules.tsx
28635
- import { useCallback as useCallback33, useEffect as useEffect59, useMemo as useMemo43, useState as useState70 } from "react";
28780
+ import { useCallback as useCallback34, useEffect as useEffect60, useMemo as useMemo43, useState as useState70 } from "react";
28636
28781
  import { useFields as useFields12, useRecordsClient as useRecordsClient49, useTable as useTable10 } from "@ai-matrx/records/react";
28637
28782
  import { BasicInput as BasicInput17, BasicTextarea as BasicTextarea8, Button as Button53, Separator as Separator7, Skeleton as Skeleton9, cn as cn44 } from "@ai-matrx/design-system";
28638
28783
  import { jsx as jsx87, jsxs as jsxs78 } from "react/jsx-runtime";
@@ -28680,14 +28825,14 @@ function StageRulesSection({ tableId, stage, className }) {
28680
28825
  const [preview, setPreview] = useState70(null);
28681
28826
  const [previewError, setPreviewError] = useState70(null);
28682
28827
  const [saving, setSaving] = useState70(false);
28683
- const load = useCallback33(async () => {
28828
+ const load = useCallback34(async () => {
28684
28829
  const [read, mode] = await Promise.all([client.pipelineRead({ table_id: tableId }), client.stageRuleEnforcement()]);
28685
28830
  if (!read.ok) setError(read.error);
28686
28831
  else setPipeline(read.data);
28687
28832
  if (mode.ok) setEnforcement(mode.data);
28688
28833
  setAsked(true);
28689
28834
  }, [client, tableId]);
28690
- useEffect59(() => {
28835
+ useEffect60(() => {
28691
28836
  void load();
28692
28837
  }, [load]);
28693
28838
  const stages = pipeline?.stages ?? [];
@@ -28698,7 +28843,7 @@ function StageRulesSection({ tableId, stage, className }) {
28698
28843
  () => (fields.data ?? []).map((f) => ({ id: String(f.id), key: f.key, label: fieldName(f), field: f })),
28699
28844
  [fields.data]
28700
28845
  );
28701
- useEffect59(() => {
28846
+ useEffect60(() => {
28702
28847
  if (!draft || !stageKey || !draft.demands || Object.keys(draft.demands).length === 0) {
28703
28848
  setPreview(null);
28704
28849
  setPreviewError(null);
@@ -28920,7 +29065,7 @@ function Clause({
28920
29065
  }
28921
29066
 
28922
29067
  // src/TableRename.tsx
28923
- import { useCallback as useCallback34, useEffect as useEffect60, useRef as useRef39, useState as useState71 } from "react";
29068
+ import { useCallback as useCallback35, useEffect as useEffect61, useRef as useRef40, useState as useState71 } from "react";
28924
29069
  import { tableShapeChanged as tableShapeChanged7, useRecordsClient as useRecordsClient50 } from "@ai-matrx/records/react";
28925
29070
  import {
28926
29071
  Button as Button54,
@@ -28942,8 +29087,8 @@ function tableNameProblem(typed2) {
28942
29087
  }
28943
29088
  function useRenameFromMenu() {
28944
29089
  const [open, setOpen] = useState71(false);
28945
- const asked3 = useRef39(false);
28946
- const ask = useCallback34(() => {
29090
+ const asked3 = useRef40(false);
29091
+ const ask = useCallback35(() => {
28947
29092
  asked3.current = true;
28948
29093
  window.setTimeout(() => setOpen(true), 0);
28949
29094
  window.setTimeout(() => asked3.current = false, 2e3);
@@ -28968,9 +29113,9 @@ function TableRenameDialog({
28968
29113
  const [typed2, setTyped] = useState71(name);
28969
29114
  const [busy, setBusy] = useState71(false);
28970
29115
  const [refused, setRefused] = useState71(null);
28971
- const box = useRef39(null);
28972
- const openedAt = useRef39(null);
28973
- useEffect60(() => {
29116
+ const box = useRef40(null);
29117
+ const openedAt = useRef40(null);
29118
+ useEffect61(() => {
28974
29119
  if (!open) return;
28975
29120
  openedAt.current = readTableVersionNow(client, tableId);
28976
29121
  setTyped(name);
@@ -29061,7 +29206,7 @@ function TableRenameDialog({
29061
29206
  }
29062
29207
 
29063
29208
  // src/TableSettings.tsx
29064
- import { useEffect as useEffect64, useMemo as useMemo45, useRef as useRef40, useState as useState76 } from "react";
29209
+ import { useEffect as useEffect65, useMemo as useMemo45, useRef as useRef41, useState as useState76 } from "react";
29065
29210
 
29066
29211
  // src/ArchiveDeliberately.tsx
29067
29212
  import { useState as useState72 } from "react";
@@ -29186,7 +29331,7 @@ function announceTableArchived({ notify, client, tableId, name, onRestored }) {
29186
29331
  }
29187
29332
 
29188
29333
  // src/TableFoundation.tsx
29189
- import { useEffect as useEffect61, useState as useState73 } from "react";
29334
+ import { useEffect as useEffect62, useState as useState73 } from "react";
29190
29335
  import { tableShapeChanged as tableShapeChanged8, useRecordsClient as useRecordsClient52 } from "@ai-matrx/records/react";
29191
29336
  import { Switch as Switch2 } from "@ai-matrx/design-system";
29192
29337
  import { jsx as jsx90, jsxs as jsxs81 } from "react/jsx-runtime";
@@ -29199,7 +29344,7 @@ function TableFoundationSwitch({ tableId, table }) {
29199
29344
  const [pending, setPending] = useState73(null);
29200
29345
  const [refused, setRefused] = useState73(null);
29201
29346
  const on = pending ?? stored;
29202
- useEffect61(() => {
29347
+ useEffect62(() => {
29203
29348
  if (pending !== null && stored === pending) setPending(null);
29204
29349
  }, [stored, pending]);
29205
29350
  const change = async (next) => {
@@ -29237,7 +29382,7 @@ function TableFoundationSwitch({ tableId, table }) {
29237
29382
  }
29238
29383
 
29239
29384
  // src/RowControls.tsx
29240
- import { useCallback as useCallback35, useEffect as useEffect62, useState as useState74 } from "react";
29385
+ import { useCallback as useCallback36, useEffect as useEffect63, useState as useState74 } from "react";
29241
29386
  import {
29242
29387
  isShownTo,
29243
29388
  SHOWN_TO_LABEL
@@ -29288,14 +29433,14 @@ function NewRowsDefaults({ tableId }) {
29288
29433
  const [error, setError] = useState74(null);
29289
29434
  const [busy, setBusy] = useState74(false);
29290
29435
  const [applied, setApplied] = useState74(null);
29291
- const read = useCallback35(async () => {
29436
+ const read = useCallback36(async () => {
29292
29437
  const answer = await client.tableRowDefaults({ table_id: tableId });
29293
29438
  if (answer.ok) {
29294
29439
  setD(answer.data);
29295
29440
  setError(null);
29296
29441
  } else setError(answer.error);
29297
29442
  }, [client, tableId]);
29298
- useEffect62(() => {
29443
+ useEffect63(() => {
29299
29444
  void read();
29300
29445
  }, [read]);
29301
29446
  const set = async (patch) => {
@@ -29369,14 +29514,14 @@ function RowShownTo({ recordId }) {
29369
29514
  const client = useRecordsClient53();
29370
29515
  const [c, setC] = useState74(null);
29371
29516
  const [error, setError] = useState74(null);
29372
- const read = useCallback35(async () => {
29517
+ const read = useCallback36(async () => {
29373
29518
  const answer = await client.recordRowControls({ record_id: recordId });
29374
29519
  if (answer.ok) {
29375
29520
  setC(answer.data);
29376
29521
  setError(null);
29377
29522
  } else setError(answer.error);
29378
29523
  }, [client, recordId]);
29379
- useEffect62(() => {
29524
+ useEffect63(() => {
29380
29525
  setC(null);
29381
29526
  void read();
29382
29527
  }, [read]);
@@ -29410,7 +29555,7 @@ function RowShownTo({ recordId }) {
29410
29555
  }
29411
29556
 
29412
29557
  // src/ColumnsAtOnce.tsx
29413
- import { useEffect as useEffect63, useMemo as useMemo44, useState as useState75 } from "react";
29558
+ import { useEffect as useEffect64, useMemo as useMemo44, useState as useState75 } from "react";
29414
29559
  import { useFieldMutation as useFieldMutation3 } from "@ai-matrx/records/react";
29415
29560
  import { Badge as Badge12, BasicInput as BasicInput18, Button as Button57, Checkbox as Checkbox10, cn as cn45 } from "@ai-matrx/design-system";
29416
29561
  import { jsx as jsx92, jsxs as jsxs83 } from "react/jsx-runtime";
@@ -29444,10 +29589,10 @@ function ColumnsAtOnce({
29444
29589
  const shape = useFieldMutation3();
29445
29590
  const savedSignature = JSON.stringify(rows.map((f) => [f.id, f.label, f.sort]));
29446
29591
  const [draft, setDraft] = useState75(() => draftOf3(rows));
29447
- useEffect63(() => setDraft(draftOf3(rows)), [savedSignature]);
29592
+ useEffect64(() => setDraft(draftOf3(rows)), [savedSignature]);
29448
29593
  const hiddenSignature = JSON.stringify(look?.hidden ?? []);
29449
29594
  const [hidden, setHidden] = useState75(() => [...look?.hidden ?? []]);
29450
- useEffect63(() => setHidden([...look?.hidden ?? []]), [hiddenSignature]);
29595
+ useEffect64(() => setHidden([...look?.hidden ?? []]), [hiddenSignature]);
29451
29596
  const [dragging, setDragging] = useState75(null);
29452
29597
  const [saving, setSaving] = useState75(false);
29453
29598
  const byId = useMemo44(() => new Map(rows.map((f) => [f.id, f])), [rows]);
@@ -29597,9 +29742,9 @@ function TableSettings(props) {
29597
29742
  const client = useRecordsClient54();
29598
29743
  const table = useTable11(props.tableId);
29599
29744
  const fields = useFields13(props.tableId);
29600
- const now = useRef40({ table: table.data ?? null, fields: fields.data ?? [] });
29745
+ const now = useRef41({ table: table.data ?? null, fields: fields.data ?? [] });
29601
29746
  now.current = { table: table.data ?? null, fields: fields.data ?? [] };
29602
- const slots = useRef40({ details: { current: null }, rowActions: { current: null } }).current;
29747
+ const slots = useRef41({ details: { current: null }, rowActions: { current: null } }).current;
29603
29748
  const agent = useMemo45(
29604
29749
  () => buildTableSettingsAgent(props.tableId, () => now.current, client, slots),
29605
29750
  [props.tableId, client, slots]
@@ -29623,7 +29768,7 @@ function TableSettingsPanel({
29623
29768
  const archive = useTableArchive(tableId);
29624
29769
  const client = useRecordsClient54();
29625
29770
  const ui = useRecordsUi();
29626
- useEffect64(() => {
29771
+ useEffect65(() => {
29627
29772
  let live = true;
29628
29773
  void archive.preview().then((answer) => {
29629
29774
  if (live && answer?.in_progress) setAskingToDelete(true);
@@ -29632,10 +29777,10 @@ function TableSettingsPanel({
29632
29777
  live = false;
29633
29778
  };
29634
29779
  }, [tableId]);
29635
- const askToArchiveRef = useRef40(null);
29636
- const archiveAskedSeen = useRef40(0);
29780
+ const askToArchiveRef = useRef41(null);
29781
+ const archiveAskedSeen = useRef41(0);
29637
29782
  const panelReady = Boolean(table.data && fields.data && rights.structure);
29638
- useEffect64(() => {
29783
+ useEffect65(() => {
29639
29784
  const ask = askToArchiveRef.current;
29640
29785
  if (!panelReady || !ask || archiveAsked <= archiveAskedSeen.current) return;
29641
29786
  archiveAskedSeen.current = archiveAsked;
@@ -29819,12 +29964,12 @@ function TableSettingsPanel({
29819
29964
  }
29820
29965
 
29821
29966
  // src/Peek.tsx
29822
- import { useEffect as useEffect68, useState as useState80 } from "react";
29967
+ import { useEffect as useEffect69, useState as useState80 } from "react";
29823
29968
  import { useFields as useFields15, useRecord as useRecord3, useRecordsClient as useRecordsClient58, useTable as useTable14 } from "@ai-matrx/records/react";
29824
29969
  import { AlchemyMenu as AlchemyMenu2 } from "@ai-matrx/alchemy/react";
29825
29970
 
29826
29971
  // src/RecordChat.tsx
29827
- import { useEffect as useEffect65, useMemo as useMemo46, useState as useState77 } from "react";
29972
+ import { useEffect as useEffect66, useMemo as useMemo46, useState as useState77 } from "react";
29828
29973
  import { useRecordsClient as useRecordsClient55 } from "@ai-matrx/records/react";
29829
29974
  import { Skeleton as Skeleton10, cn as cn47 } from "@ai-matrx/design-system";
29830
29975
  import { jsx as jsx94, jsxs as jsxs85 } from "react/jsx-runtime";
@@ -29834,7 +29979,7 @@ function RecordChat({ tableId, recordId, className }) {
29834
29979
  const host = useRecordsUi();
29835
29980
  const [scope, setScope] = useState77(null);
29836
29981
  const [error, setError] = useState77(null);
29837
- useEffect65(() => {
29982
+ useEffect66(() => {
29838
29983
  let cancelled = false;
29839
29984
  setScope(null);
29840
29985
  setError(null);
@@ -29951,7 +30096,7 @@ function entriesFor(scope) {
29951
30096
  import { Button as Button61, Separator as Separator9, Skeleton as Skeleton11, cn as cn49 } from "@ai-matrx/design-system";
29952
30097
 
29953
30098
  // src/recordInPlace.tsx
29954
- import { useMemo as useMemo47, useRef as useRef41 } from "react";
30099
+ import { useMemo as useMemo47, useRef as useRef42 } from "react";
29955
30100
  import { useRecordsClient as useRecordsClient56, useTable as useTable12 } from "@ai-matrx/records/react";
29956
30101
  import { humanizeIdentifier as humanizeIdentifier11 } from "@ai-matrx/kit/text-case";
29957
30102
  import { jsx as jsx95, jsxs as jsxs86 } from "react/jsx-runtime";
@@ -29975,7 +30120,7 @@ function RecordFieldsInPlace({
29975
30120
  );
29976
30121
  const rows = useMemo47(() => [row], [row]);
29977
30122
  const versions = useRecordVersions(client, rows);
29978
- const pushWritten = useRef41(null);
30123
+ const pushWritten = useRef42(null);
29979
30124
  const editing = useGridEditing({
29980
30125
  tableId,
29981
30126
  fields,
@@ -30048,7 +30193,7 @@ function RecordFieldsInPlace({
30048
30193
 
30049
30194
  // src/ShareControl.tsx
30050
30195
  import { copyText as copyText4 } from "@ai-matrx/kit/clipboard";
30051
- import { useEffect as useEffect66, useState as useState78 } from "react";
30196
+ import { useEffect as useEffect67, useState as useState78 } from "react";
30052
30197
  import { Button as Button59, Popover as Popover9, PopoverContent as PopoverContent9, PopoverTrigger as PopoverTrigger9 } from "@ai-matrx/design-system";
30053
30198
  import { Fragment as Fragment35, jsx as jsx96, jsxs as jsxs87 } from "react/jsx-runtime";
30054
30199
  function useCanShare() {
@@ -30071,7 +30216,7 @@ function ShareControl({
30071
30216
  }) {
30072
30217
  const host = useRecordsUi();
30073
30218
  const [open, setOpen] = useState78(initiallyOpen);
30074
- useEffect66(() => {
30219
+ useEffect67(() => {
30075
30220
  if (initiallyOpen) setOpen(true);
30076
30221
  }, [initiallyOpen]);
30077
30222
  const asked3 = useRecordRights(may === void 0 ? subjectId : null);
@@ -30135,7 +30280,7 @@ function ShareForSomebodyElse({
30135
30280
  }
30136
30281
 
30137
30282
  // src/RecordBody.tsx
30138
- import { useEffect as useEffect67, useRef as useRef42, useState as useState79 } from "react";
30283
+ import { useEffect as useEffect68, useRef as useRef43, useState as useState79 } from "react";
30139
30284
  import { Button as Button60, cn as cn48 } from "@ai-matrx/design-system";
30140
30285
  import { newerKindOf as newerKindOf5 } from "@ai-matrx/records";
30141
30286
  import { tableShapeChanged as tableShapeChanged10, useFieldMutation as useFieldMutation5, useFields as useFields14, useRecord as useRecord2, useRecordsClient as useRecordsClient57, useTable as useTable13 } from "@ai-matrx/records/react";
@@ -30172,9 +30317,9 @@ function BodyEditor({ tableId, recordId, field: field2 }) {
30172
30317
  const raw = record.data?.document?.[field2.key];
30173
30318
  const stored = typeof raw === "string" ? raw : "";
30174
30319
  const [saving, setSaving] = useState79({ phase: "idle" });
30175
- const lastSaved = useRef42(null);
30176
- const waiting = useRef42(null);
30177
- const timer = useRef42(null);
30320
+ const lastSaved = useRef43(null);
30321
+ const waiting = useRef43(null);
30322
+ const timer = useRef43(null);
30178
30323
  if (lastSaved.current === null && record.data) lastSaved.current = stored;
30179
30324
  const write = async () => {
30180
30325
  if (timer.current) clearTimeout(timer.current);
@@ -30195,9 +30340,9 @@ function BodyEditor({ tableId, recordId, field: field2 }) {
30195
30340
  setSaving({ phase: "refused", error: answered.error });
30196
30341
  }
30197
30342
  };
30198
- const writeRef = useRef42(write);
30343
+ const writeRef = useRef43(write);
30199
30344
  writeRef.current = write;
30200
- useEffect67(
30345
+ useEffect68(
30201
30346
  () => () => {
30202
30347
  if (waiting.current !== null) void writeRef.current();
30203
30348
  },
@@ -30260,7 +30405,7 @@ function Peek({ tableId, recordId, onClose, className, onPage = false }) {
30260
30405
  const shownFieldCount = (fields.data ?? []).filter(
30261
30406
  (field2) => !onPage || !drawnBelowOnPage(field2, onPage ? bodyFieldOf(fields.data ?? [])?.key : void 0)
30262
30407
  ).length;
30263
- useEffect68(() => {
30408
+ useEffect69(() => {
30264
30409
  if (fields.data) rememberRowCount(peekMemoryKey, shownFieldCount);
30265
30410
  }, [fields.data, peekMemoryKey, shownFieldCount]);
30266
30411
  if (record.error) return /* @__PURE__ */ jsx98(RefusalNotice, { error: record.error, className });
@@ -30389,7 +30534,7 @@ function computedInPlainWords(row, field2) {
30389
30534
  }
30390
30535
 
30391
30536
  // src/systemTable.ts
30392
- import { useEffect as useEffect69, useMemo as useMemo48, useState as useState81 } from "react";
30537
+ import { useEffect as useEffect70, useMemo as useMemo48, useState as useState81 } from "react";
30393
30538
  import { useRecordsClient as useRecordsClient59 } from "@ai-matrx/records/react";
30394
30539
  var inFlight = /* @__PURE__ */ new Map();
30395
30540
  async function ensureSystemTable(client, spec) {
@@ -30522,7 +30667,7 @@ function useSystemTable(spec) {
30522
30667
  const [state, setState] = useState81({ tableId: null, loading: true, error: null });
30523
30668
  const slug = spec.slug;
30524
30669
  const stable = useMemo48(() => spec, [slug]);
30525
- useEffect69(() => {
30670
+ useEffect70(() => {
30526
30671
  let cancelled = false;
30527
30672
  setState({ tableId: null, loading: true, error: null });
30528
30673
  void ensureSystemTable(client, stable).then((result) => {
@@ -30539,7 +30684,7 @@ function useSystemTable(spec) {
30539
30684
  }
30540
30685
 
30541
30686
  // src/ViewSwitcher.tsx
30542
- import { useEffect as useEffect76, useMemo as useMemo56, useState as useState89 } from "react";
30687
+ import { useEffect as useEffect77, useMemo as useMemo56, useState as useState89 } from "react";
30543
30688
  import { mayDrag as mayDrag4, useFields as useFields18, useRecordPage as useRecordPage2, useRecordsClient as useRecordsClient64, useTable as useTable17 } from "@ai-matrx/records/react";
30544
30689
  import { newerKindOf as newerKindOf6, stableFilterKey as stableFilterKey4 } from "@ai-matrx/records";
30545
30690
  import { Button as Button67, Select as Select16, SelectContent as SelectContent16, SelectItem as SelectItem16, SelectTrigger as SelectTrigger16, SelectValue as SelectValue16, cn as cn55 } from "@ai-matrx/design-system";
@@ -30553,7 +30698,7 @@ import {
30553
30698
  import { formatCount as formatCount4 } from "@ai-matrx/kit/format";
30554
30699
 
30555
30700
  // src/recordMoves.tsx
30556
- import { useCallback as useCallback36, useEffect as useEffect70, useMemo as useMemo49, useRef as useRef43, useState as useState82 } from "react";
30701
+ import { useCallback as useCallback37, useEffect as useEffect71, useMemo as useMemo49, useRef as useRef44, useState as useState82 } from "react";
30557
30702
  import { useRecordsClient as useRecordsClient60 } from "@ai-matrx/records/react";
30558
30703
  import { Button as Button62 } from "@ai-matrx/design-system";
30559
30704
  import { Fragment as Fragment38, jsx as jsx99, jsxs as jsxs90 } from "react/jsx-runtime";
@@ -30570,8 +30715,8 @@ function useRecordMoves({
30570
30715
  const [refused, setRefused] = useState82(null);
30571
30716
  const versions = useRecordVersions(client, rows);
30572
30717
  const [stale, setStale] = useState82(null);
30573
- const reload = useCallback36(() => onMoved?.(), [onMoved]);
30574
- const forget = useCallback36(() => void 0, []);
30718
+ const reload = useCallback37(() => onMoved?.(), [onMoved]);
30719
+ const forget = useCallback37(() => void 0, []);
30575
30720
  const undo = useGridUndo({
30576
30721
  tableId,
30577
30722
  reload,
@@ -30580,7 +30725,7 @@ function useRecordMoves({
30580
30725
  for (const v of written) versions.wrote(v.id, v.version);
30581
30726
  }
30582
30727
  });
30583
- const move = useCallback36(
30728
+ const move = useCallback37(
30584
30729
  async ({ recordId, patch, before, label }) => {
30585
30730
  setRefused(null);
30586
30731
  setStale(null);
@@ -30617,7 +30762,7 @@ function useRecordMoves({
30617
30762
  },
30618
30763
  [client, undo, onMoved, versions]
30619
30764
  );
30620
- const create = useCallback36(
30765
+ const create = useCallback37(
30621
30766
  async ({ tableId: table, data, label }) => {
30622
30767
  setRefused(null);
30623
30768
  const written = await client.recordWrite({ table_id: table, data });
@@ -30632,9 +30777,9 @@ function useRecordMoves({
30632
30777
  [client, undo, onMoved]
30633
30778
  );
30634
30779
  const offering = Boolean(undo.notice);
30635
- const undoRef = useRef43(undo);
30780
+ const undoRef = useRef44(undo);
30636
30781
  undoRef.current = undo;
30637
- useEffect70(() => {
30782
+ useEffect71(() => {
30638
30783
  if (!offering || typeof document === "undefined") return;
30639
30784
  const onKey = (event) => {
30640
30785
  const which = undoKey(event);
@@ -30645,7 +30790,7 @@ function useRecordMoves({
30645
30790
  document.addEventListener("keydown", onKey);
30646
30791
  return () => document.removeEventListener("keydown", onKey);
30647
30792
  }, [offering]);
30648
- const onKeyDown = useCallback36(
30793
+ const onKeyDown = useCallback37(
30649
30794
  (event) => {
30650
30795
  if (offering) return;
30651
30796
  const which = undoKey(event);
@@ -30655,7 +30800,7 @@ function useRecordMoves({
30655
30800
  },
30656
30801
  [undo, offering]
30657
30802
  );
30658
- const reloadStale = useCallback36(async () => {
30803
+ const reloadStale = useCallback37(async () => {
30659
30804
  const id = stale?.id ?? null;
30660
30805
  setStale(null);
30661
30806
  setRefused(null);
@@ -30700,7 +30845,7 @@ function MoveRefusedBadge({ refused }) {
30700
30845
  }
30701
30846
 
30702
30847
  // src/Pipeline.tsx
30703
- import { useCallback as useCallback38, useEffect as useEffect71, useMemo as useMemo51, useRef as useRef44, useState as useState84 } from "react";
30848
+ import { useCallback as useCallback39, useEffect as useEffect72, useMemo as useMemo51, useRef as useRef45, useState as useState84 } from "react";
30704
30849
  import {
30705
30850
  mayDrag,
30706
30851
  useFields as useFields17,
@@ -30762,7 +30907,7 @@ function CardDates({ record, fields }) {
30762
30907
 
30763
30908
  // src/RecordActionMenu.tsx
30764
30909
  import { copyText as copyText5 } from "@ai-matrx/kit/clipboard";
30765
- import { useCallback as useCallback37, useMemo as useMemo50, useState as useState83 } from "react";
30910
+ import { useCallback as useCallback38, useMemo as useMemo50, useState as useState83 } from "react";
30766
30911
  import { useFields as useFields16, useRecordsClient as useRecordsClient61, useTable as useTable15 } from "@ai-matrx/records/react";
30767
30912
  import {
30768
30913
  ContextMenu,
@@ -30956,7 +31101,7 @@ function ObjectActionContextMenuItems({ actions }) {
30956
31101
  }
30957
31102
  function RecordActionMenu({ tableId, row, name, onOpenRecord, onChanged, children, className }) {
30958
31103
  const [merging, setMerging] = useState83(false);
30959
- const openMerge = useCallback37(() => setMerging(true), []);
31104
+ const openMerge = useCallback38(() => setMerging(true), []);
30960
31105
  const actionHost = useRecordActionHost({ tableId, row, onOpenRecord, onChanged, onMerge: openMerge });
30961
31106
  const rights = useMemo50(() => whatYouMayDo(row.level || null, true), [row.level]);
30962
31107
  const actions = useMemo50(
@@ -31052,21 +31197,21 @@ function PipelineBoard({
31052
31197
  const [waiting, setWaiting] = useState84(/* @__PURE__ */ new Map());
31053
31198
  const [dragging, setDragging] = useState84(null);
31054
31199
  const [over, setOver] = useState84(null);
31055
- const alive = useRef44(true);
31200
+ const alive = useRef45(true);
31056
31201
  const [selected, setSelected] = useState84(/* @__PURE__ */ new Set());
31057
- const anchor = useRef44(null);
31202
+ const anchor = useRef45(null);
31058
31203
  const [batch, setBatch] = useState84(/* @__PURE__ */ new Map());
31059
31204
  const [batchSaid, setBatchSaid] = useState84(null);
31060
31205
  const [batchError, setBatchError] = useState84(null);
31061
31206
  const [moving, setMoving] = useState84(false);
31062
- useEffect71(() => {
31207
+ useEffect72(() => {
31063
31208
  alive.current = true;
31064
31209
  return () => {
31065
31210
  alive.current = false;
31066
31211
  };
31067
31212
  }, []);
31068
31213
  const filterKey = stableFilterKey3(filter);
31069
- const reload = useCallback38(async () => {
31214
+ const reload = useCallback39(async () => {
31070
31215
  setLoading(true);
31071
31216
  const [read, board, held] = await Promise.all([
31072
31217
  client.pipelineRead({ table_id: tableId }),
@@ -31084,11 +31229,11 @@ function PipelineBoard({
31084
31229
  setWaiting(held.ok ? new Map((held.data ?? []).map((p) => [p.record_id, p])) : /* @__PURE__ */ new Map());
31085
31230
  setColumns(board.ok ? board.data ?? [] : []);
31086
31231
  }, [client, tableId, measure, filterKey]);
31087
- useEffect71(() => {
31232
+ useEffect72(() => {
31088
31233
  void reload();
31089
31234
  }, [reload]);
31090
31235
  const versions = useRecordVersions(client, rows, (r) => mayDrag(r.level));
31091
- const versionsRef = useRef44(versions);
31236
+ const versionsRef = useRef45(versions);
31092
31237
  versionsRef.current = versions;
31093
31238
  const drawnVersion = (id) => versionsRef.current.seen(id);
31094
31239
  const stageKey = definition?.stage_field ?? null;
@@ -31120,7 +31265,7 @@ function PipelineBoard({
31120
31265
  () => all.filter((f) => ["number", "currency", "percentage"].includes(String(f.type ?? ""))),
31121
31266
  [all]
31122
31267
  );
31123
- const drop = useCallback38(
31268
+ const drop = useCallback39(
31124
31269
  async (recordId, to) => {
31125
31270
  setOver(null);
31126
31271
  setDragging(null);
@@ -31160,7 +31305,7 @@ function PipelineBoard({
31160
31305
  },
31161
31306
  [client, onMoved, reload]
31162
31307
  );
31163
- const askForApproval = useCallback38(
31308
+ const askForApproval = useCallback39(
31164
31309
  async (recordId, to) => {
31165
31310
  const moved = await movePipelineCardAt(client, { record_id: recordId, to, version: await drawnVersion(recordId) });
31166
31311
  if (!alive.current) return;
@@ -31175,7 +31320,7 @@ function PipelineBoard({
31175
31320
  },
31176
31321
  [client, onMoved, reload]
31177
31322
  );
31178
- const moveWith = useCallback38(
31323
+ const moveWith = useCallback39(
31179
31324
  async (recordId, to, also) => {
31180
31325
  const moved = await movePipelineCardAt(client, { record_id: recordId, to, also, version: await drawnVersion(recordId) });
31181
31326
  if (!alive.current) return;
@@ -31744,7 +31889,7 @@ function CardFieldsInline({ row, fields }) {
31744
31889
  }
31745
31890
 
31746
31891
  // src/CalendarView.tsx
31747
- import { useEffect as useEffect72, useMemo as useMemo53, useRef as useRef45, useState as useState85 } from "react";
31892
+ import { useEffect as useEffect73, useMemo as useMemo53, useRef as useRef46, useState as useState85 } from "react";
31748
31893
  import { mayDrag as mayDrag2 } from "@ai-matrx/records/react";
31749
31894
  import { Button as Button64, Select as Select13, SelectContent as SelectContent13, SelectItem as SelectItem13, SelectTrigger as SelectTrigger13, SelectValue as SelectValue13, cn as cn52 } from "@ai-matrx/design-system";
31750
31895
  import { CHOICE_CHIP_CLASS as CHOICE_CHIP_CLASS2 } from "@ai-matrx/design-system/data-table";
@@ -32025,7 +32170,7 @@ function useNarrow() {
32025
32170
  const query = "(max-width: 639px)";
32026
32171
  const read = () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(query).matches;
32027
32172
  const [narrow, setNarrow] = useState85(read);
32028
- useEffect72(() => {
32173
+ useEffect73(() => {
32029
32174
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
32030
32175
  const list = window.matchMedia(query);
32031
32176
  const on = () => setNarrow(list.matches);
@@ -32095,9 +32240,9 @@ function CalendarView({
32095
32240
  const colorKey = colorPick !== void 0 ? colorPick : style?.colorBy?.field ?? choiceFields[0]?.key ?? null;
32096
32241
  const colorOf = useRowColorBy(all, colorKey, style);
32097
32242
  const [placedOver, setPlacedOver] = useState85(() => /* @__PURE__ */ new Map());
32098
- useEffect72(() => setPlacedOver(/* @__PURE__ */ new Map()), [rows]);
32243
+ useEffect73(() => setPlacedOver(/* @__PURE__ */ new Map()), [rows]);
32099
32244
  const undoneCount = moves.undo.depth.forward;
32100
- useEffect72(() => {
32245
+ useEffect73(() => {
32101
32246
  if (undoneCount > 0) setPlacedOver(/* @__PURE__ */ new Map());
32102
32247
  }, [undoneCount]);
32103
32248
  const startOf = (row) => placedOver.has(row.id) ? placedOver.get(row.id).start : (row.document ?? {})[dateField.key];
@@ -32124,9 +32269,9 @@ function CalendarView({
32124
32269
  }, [rows, dateField.key, endField?.key, placedOver, defaultMinutes]);
32125
32270
  const titleOf = (row) => cardWords(row, titleField, labels).text;
32126
32271
  const rowById = (id) => rows.find((r) => r.id === id);
32127
- const frame = useRef45(null);
32272
+ const frame = useRef46(null);
32128
32273
  const [focusOn, setFocusOn] = useState85(null);
32129
- useEffect72(() => {
32274
+ useEffect73(() => {
32130
32275
  if (!focusOn) return;
32131
32276
  const button = frame.current?.querySelector(`[data-calendar-card="${focusOn}"] button`);
32132
32277
  button?.focus({ preventScroll: true });
@@ -32173,10 +32318,10 @@ function CalendarView({
32173
32318
  const made = await moves.create({ tableId, data, label: `New record on ${where}` });
32174
32319
  if (made) onOpenRecord?.(made);
32175
32320
  };
32176
- const grabOffset = useRef45(0);
32321
+ const grabOffset = useRef46(0);
32177
32322
  const [resizing, setResizing] = useState85(null);
32178
32323
  const [ghost, setGhost] = useState85(null);
32179
- useEffect72(() => {
32324
+ useEffect73(() => {
32180
32325
  if (!ghost || typeof document === "undefined") return;
32181
32326
  const clear = () => setGhost(null);
32182
32327
  document.addEventListener("dragend", clear);
@@ -32723,13 +32868,13 @@ function WeekHours({
32723
32868
  render,
32724
32869
  overlay
32725
32870
  }) {
32726
- const frame = useRef45(null);
32727
- useEffect72(() => {
32871
+ const frame = useRef46(null);
32872
+ useEffect73(() => {
32728
32873
  if (frame.current) frame.current.scrollTop = 7 * HOUR_PX;
32729
32874
  }, []);
32730
32875
  usePersonTimeZone();
32731
32876
  const [now, setNow] = useState85(() => personWallNow());
32732
- useEffect72(() => {
32877
+ useEffect73(() => {
32733
32878
  const timer = setInterval(() => setNow(personWallNow()), 6e4);
32734
32879
  return () => clearInterval(timer);
32735
32880
  }, []);
@@ -32771,7 +32916,7 @@ function weekHeading(first) {
32771
32916
  }
32772
32917
 
32773
32918
  // src/TimelineView.tsx
32774
- import { useEffect as useEffect73, useMemo as useMemo54, useRef as useRef46, useState as useState86 } from "react";
32919
+ import { useEffect as useEffect74, useMemo as useMemo54, useRef as useRef47, useState as useState86 } from "react";
32775
32920
  import { mayDrag as mayDrag3 } from "@ai-matrx/records/react";
32776
32921
  import { Button as Button65, Select as Select14, SelectContent as SelectContent14, SelectItem as SelectItem14, SelectTrigger as SelectTrigger14, SelectValue as SelectValue14, cn as cn53 } from "@ai-matrx/design-system";
32777
32922
  import { CHOICE_CHIP_CLASS as CHOICE_CHIP_CLASS3 } from "@ai-matrx/design-system/data-table";
@@ -32896,7 +33041,7 @@ function TimelineView({
32896
33041
  const dates = useMemo54(() => offerableFields(fields, "date", { far: farFields }), [fields, farFields]);
32897
33042
  const has = (list, key) => key && list.some((f) => f.key === key) ? key : null;
32898
33043
  const [picked, setPicked] = useState86({});
32899
- useEffect73(() => setPicked({}), [startKey, endKey, groupKey, colorKey]);
33044
+ useEffect74(() => setPicked({}), [startKey, endKey, groupKey, colorKey]);
32900
33045
  const named = (key) => key && fields.some((f) => f.key === key) ? key : null;
32901
33046
  const startChosen = "startKey" in picked ? picked.startKey ?? null : has(dates, startKey) ?? named(startKey) ?? onlyCandidate(dates);
32902
33047
  const endCandidates = useMemo54(() => dates.filter((f) => f.key !== startChosen), [dates, startChosen]);
@@ -32925,9 +33070,9 @@ function TimelineView({
32925
33070
  const titleOf = (row) => cardWords(row, titleField, labels).text;
32926
33071
  const groupOptions = useChoiceOptions(fields, groupField && isChoiceField(groupField) ? [groupField.key] : []).get(groupField?.key ?? "");
32927
33072
  const [placedOver, setPlacedOver] = useState86(() => /* @__PURE__ */ new Map());
32928
- useEffect73(() => setPlacedOver(/* @__PURE__ */ new Map()), [rows]);
33073
+ useEffect74(() => setPlacedOver(/* @__PURE__ */ new Map()), [rows]);
32929
33074
  const undoneCount = moves.undo.depth.forward;
32930
- useEffect73(() => {
33075
+ useEffect74(() => {
32931
33076
  if (undoneCount > 0) setPlacedOver(/* @__PURE__ */ new Map());
32932
33077
  }, [undoneCount]);
32933
33078
  const startOf = (row) => placedOver.has(row.id) ? placedOver.get(row.id).start : startField ? (row.document ?? {})[startField.key] : null;
@@ -33026,10 +33171,10 @@ function TimelineView({
33026
33171
  const width = days * px;
33027
33172
  const scale = useMemo54(() => scaleOf(from, days, zoom), [from, days, zoom]);
33028
33173
  const xOf = (day) => daysBetween(from, day) * px;
33029
- const scroller = useRef46(null);
33174
+ const scroller = useRef47(null);
33030
33175
  const grouped = Boolean(groupField);
33031
33176
  const [scrollX, setScrollX] = useState86(0);
33032
- const frame = useRef46(null);
33177
+ const frame = useRef47(null);
33033
33178
  const onScroll = () => {
33034
33179
  if (frame.current !== null) return;
33035
33180
  frame.current = requestAnimationFrame(() => {
@@ -33037,7 +33182,7 @@ function TimelineView({
33037
33182
  setScrollX(scroller.current?.scrollLeft ?? 0);
33038
33183
  });
33039
33184
  };
33040
- useEffect73(() => {
33185
+ useEffect74(() => {
33041
33186
  const el = scroller.current;
33042
33187
  if (!el) return;
33043
33188
  const label = el.querySelector("[data-timeline-label]")?.offsetWidth ?? 0;
@@ -33424,7 +33569,7 @@ function TimelineView({
33424
33569
  }
33425
33570
 
33426
33571
  // src/ViewNeeds.tsx
33427
- import { useEffect as useEffect74, useState as useState87 } from "react";
33572
+ import { useEffect as useEffect75, useState as useState87 } from "react";
33428
33573
  import { useFieldMutation as useFieldMutation6, useRecordsClient as useRecordsClient63, useTable as useTable16 } from "@ai-matrx/records/react";
33429
33574
  import { BasicInput as BasicInput19, Button as Button66, Label as Label17 } from "@ai-matrx/design-system";
33430
33575
  import { jsx as jsx106, jsxs as jsxs97 } from "react/jsx-runtime";
@@ -33445,7 +33590,7 @@ function useAskedColumnLands(layout, tableId, fields, chosen, offerable, onMade)
33445
33590
  const wanted = askedFor.get(askKey(tableId, layout));
33446
33591
  const landed = wanted && !chosen ? offerable(fields).find((f) => fieldName(f).trim().toLowerCase() === wanted.trim().toLowerCase()) : void 0;
33447
33592
  const key = landed?.key ?? null;
33448
- useEffect74(() => {
33593
+ useEffect75(() => {
33449
33594
  if (!key) return;
33450
33595
  askedFor.delete(askKey(tableId, layout));
33451
33596
  onMade(key);
@@ -33557,7 +33702,7 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
33557
33702
  }
33558
33703
 
33559
33704
  // src/GalleryCover.tsx
33560
- import { useEffect as useEffect75, useState as useState88 } from "react";
33705
+ import { useEffect as useEffect76, useState as useState88 } from "react";
33561
33706
  import { useOptionalRecordsClient as useOptionalRecordsClient10 } from "@ai-matrx/records/react";
33562
33707
  import { Fragment as Fragment43, jsx as jsx107 } from "react/jsx-runtime";
33563
33708
  function isImageAddress(value) {
@@ -33579,7 +33724,7 @@ function FileCover({ recordId }) {
33579
33724
  const client = useOptionalRecordsClient10();
33580
33725
  const host = useRecordsUi();
33581
33726
  const [read, setRead] = useState88(null);
33582
- useEffect75(() => {
33727
+ useEffect76(() => {
33583
33728
  let cancelled = false;
33584
33729
  if (!client) {
33585
33730
  setRead({ fileId: recordId, name: "" });
@@ -33796,7 +33941,7 @@ function useViewRecords(view, pageSize = 200, filter, viewId) {
33796
33941
  const client = useRecordsClient64();
33797
33942
  const [limit, setLimit] = useState89(pageSize);
33798
33943
  const questionKey = `${view.subject}|${stableFilterKey4(filter ?? null)}|${JSON.stringify(view.sorts ?? [])}`;
33799
- useEffect76(() => {
33944
+ useEffect77(() => {
33800
33945
  setLimit(pageSize);
33801
33946
  }, [questionKey, pageSize]);
33802
33947
  const storeSort = useMemo56(
@@ -33814,7 +33959,7 @@ function useViewRecords(view, pageSize = 200, filter, viewId) {
33814
33959
  error: null
33815
33960
  });
33816
33961
  const ruleId = view.ruleId ?? null;
33817
- useEffect76(() => {
33962
+ useEffect77(() => {
33818
33963
  if (!ruleId) return;
33819
33964
  let cancelled = false;
33820
33965
  setRuled({ rows: [], loading: true, error: null });
@@ -33927,7 +34072,7 @@ function ViewSwitcher({
33927
34072
  const pageSize = pageSizeAsked ?? (embedded ? EMBEDDED_PAGE_SIZE : 200);
33928
34073
  const [layout, setLayout] = useState89(view.layout);
33929
34074
  const [local, setLocal] = useState89({});
33930
- useEffect76(() => {
34075
+ useEffect77(() => {
33931
34076
  setLayout(view.layout);
33932
34077
  setLocal({});
33933
34078
  }, [view.layout, view.name, view.subject]);
@@ -34023,7 +34168,7 @@ function useFarFields(all) {
34023
34168
  const client = useRecordsClient64();
34024
34169
  const targets = lookupTargets(all).sort().join(",");
34025
34170
  const [far, setFar] = useState89(() => /* @__PURE__ */ new Map());
34026
- useEffect76(() => {
34171
+ useEffect77(() => {
34027
34172
  let cancelled = false;
34028
34173
  const ids = targets ? targets.split(",") : [];
34029
34174
  if (ids.length === 0) {
@@ -34062,7 +34207,7 @@ function useStageField(tableId) {
34062
34207
  asked: false,
34063
34208
  key: null
34064
34209
  });
34065
- useEffect76(() => {
34210
+ useEffect77(() => {
34066
34211
  let cancelled = false;
34067
34212
  setStage({ asked: false, key: null });
34068
34213
  void client.tableStageField({ table_id: tableId }).then((r) => {
@@ -34862,7 +35007,7 @@ function boardDefaultGroupField(eligible) {
34862
35007
  }
34863
35008
 
34864
35009
  // src/ArchivedView.tsx
34865
- import { useCallback as useCallback39, useEffect as useEffect77, useState as useState90 } from "react";
35010
+ import { useCallback as useCallback40, useEffect as useEffect78, useState as useState90 } from "react";
34866
35011
  import {
34867
35012
  ARCHIVE_LANES,
34868
35013
  ARCHIVE_LANE_LABEL,
@@ -34900,10 +35045,10 @@ function ArchivedView({
34900
35045
  const [error, setError] = useState90(null);
34901
35046
  const [restoring, setRestoring] = useState90(null);
34902
35047
  const [refusal4, setRefusal] = useState90(null);
34903
- useEffect77(() => {
35048
+ useEffect78(() => {
34904
35049
  if (laneFromHost) setLane(laneFromHost);
34905
35050
  }, [laneFromHost]);
34906
- const read = useCallback39(async () => {
35051
+ const read = useCallback40(async () => {
34907
35052
  setLoading(true);
34908
35053
  const answer = await client.listArchived({ table_id: tableId, lane, limit: pageSize });
34909
35054
  if (answer.ok) {
@@ -34915,7 +35060,7 @@ function ArchivedView({
34915
35060
  }
34916
35061
  setLoading(false);
34917
35062
  }, [client, tableId, lane, pageSize]);
34918
- useEffect77(() => {
35063
+ useEffect78(() => {
34919
35064
  void read();
34920
35065
  }, [read]);
34921
35066
  const pick = (next) => {
@@ -35006,7 +35151,7 @@ function RetiredColumns({ tableId, mayRestore, whyNot }) {
35006
35151
  const [error, setError] = useState90(null);
35007
35152
  const [restoring, setRestoring] = useState90(null);
35008
35153
  const [refusal4, setRefusal] = useState90(null);
35009
- const read = useCallback39(async () => {
35154
+ const read = useCallback40(async () => {
35010
35155
  const answer = await client.fieldsRetired({ table_id: tableId });
35011
35156
  if (answer.ok) {
35012
35157
  setRows(answer.data);
@@ -35016,7 +35161,7 @@ function RetiredColumns({ tableId, mayRestore, whyNot }) {
35016
35161
  setError(answer.error);
35017
35162
  }
35018
35163
  }, [client, tableId]);
35019
- useEffect77(() => {
35164
+ useEffect78(() => {
35020
35165
  void read();
35021
35166
  }, [read]);
35022
35167
  const restore = async (fieldId) => {
@@ -35061,7 +35206,7 @@ function RetiredColumns({ tableId, mayRestore, whyNot }) {
35061
35206
  }
35062
35207
 
35063
35208
  // src/ArchivedDisclosure.tsx
35064
- import { useCallback as useCallback40, useEffect as useEffect78, useState as useState91 } from "react";
35209
+ import { useCallback as useCallback41, useEffect as useEffect79, useState as useState91 } from "react";
35065
35210
  import {
35066
35211
  emptyPortalArchiveLine,
35067
35212
  portalConfirmLine,
@@ -35120,7 +35265,7 @@ function ArchivedPortals({
35120
35265
  const [restoring, setRestoring] = useState91(null);
35121
35266
  const [refusal4, setRefusal] = useState91(null);
35122
35267
  const [said2, setSaid] = useState91(null);
35123
- const read = useCallback40(async () => {
35268
+ const read = useCallback41(async () => {
35124
35269
  const answered = await client.listPortals({ archived: "archived" });
35125
35270
  if (answered.ok) {
35126
35271
  setRows(answered.data);
@@ -35130,7 +35275,7 @@ function ArchivedPortals({
35130
35275
  setError(answered.error);
35131
35276
  }
35132
35277
  }, [client]);
35133
- useEffect78(() => {
35278
+ useEffect79(() => {
35134
35279
  void read();
35135
35280
  }, [read, refreshToken]);
35136
35281
  const restore = async (portal) => {
@@ -35246,15 +35391,15 @@ function ArchivedPortals({
35246
35391
  }
35247
35392
 
35248
35393
  // src/ViewBar.tsx
35249
- import { useCallback as useCallback42, useEffect as useEffect79, useRef as useRef48, useState as useState92 } from "react";
35394
+ import { useCallback as useCallback43, useEffect as useEffect80, useRef as useRef49, useState as useState92 } from "react";
35250
35395
  import { useRecordsClient as useRecordsClient67 } from "@ai-matrx/records/react";
35251
35396
  import { Badge as Badge14, Button as Button70, Input as Input6, Popover as Popover10, PopoverContent as PopoverContent10, PopoverTrigger as PopoverTrigger10, Skeleton as Skeleton15, cn as cn58 } from "@ai-matrx/design-system";
35252
35397
 
35253
35398
  // src/seedOnce.ts
35254
- import { useCallback as useCallback41, useRef as useRef47 } from "react";
35399
+ import { useCallback as useCallback42, useRef as useRef48 } from "react";
35255
35400
  function useSeedGuard() {
35256
- const claimed = useRef47(/* @__PURE__ */ new Set());
35257
- return useCallback41((name) => {
35401
+ const claimed = useRef48(/* @__PURE__ */ new Set());
35402
+ return useCallback42((name) => {
35258
35403
  if (claimed.current.has(name)) return false;
35259
35404
  claimed.current.add(name);
35260
35405
  return true;
@@ -35311,18 +35456,18 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
35311
35456
  if (!initialViews || initialViews.length === 0) return activeViewId ?? null;
35312
35457
  return (initialViews.find((v) => v.id === activeViewId) ?? defaultViewOf(initialViews) ?? initialViews[0]).id;
35313
35458
  });
35314
- const readOnMount = useRef48(initialViews === void 0);
35459
+ const readOnMount = useRef49(initialViews === void 0);
35315
35460
  const [naming, setNaming] = useState92(false);
35316
35461
  const [draftName, setDraftName] = useState92("");
35317
35462
  const [open, setOpen] = useState92(false);
35318
35463
  const [renaming, setRenaming] = useState92(null);
35319
35464
  const seedKey = JSON.stringify(seed ?? []);
35320
- const readViews = useCallback42(async () => {
35465
+ const readViews = useCallback43(async () => {
35321
35466
  const result = await client.views({ table_id: tableId });
35322
35467
  if (!result.ok) return result;
35323
35468
  return { ok: true, data: result.data.map(viewFromRow).filter((v) => v.subject === tableId) };
35324
35469
  }, [client, tableId]);
35325
- const load = useCallback42(async () => {
35470
+ const load = useCallback43(async () => {
35326
35471
  const result = await readViews();
35327
35472
  if (!result.ok) {
35328
35473
  setUnavailable(true);
@@ -35357,14 +35502,14 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
35357
35502
  setViews(mine);
35358
35503
  onViews?.(mine);
35359
35504
  }, [client, readViews, tableId, seedKey]);
35360
- useEffect79(() => {
35505
+ useEffect80(() => {
35361
35506
  if (!readOnMount.current) {
35362
35507
  readOnMount.current = true;
35363
35508
  return;
35364
35509
  }
35365
35510
  void load();
35366
35511
  }, [load]);
35367
- useEffect79(() => {
35512
+ useEffect80(() => {
35368
35513
  if (!views || views.length === 0) return;
35369
35514
  const chosen = views.find((v) => v.id === (activeViewId ?? active)) ?? defaultViewOf(views) ?? views[0];
35370
35515
  if (chosen.id !== active) setActive(chosen.id);
@@ -35579,7 +35724,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
35579
35724
  }
35580
35725
 
35581
35726
  // src/ProposalRow.tsx
35582
- import { useEffect as useEffect80, useRef as useRef49, useState as useState93 } from "react";
35727
+ import { useEffect as useEffect81, useRef as useRef50, useState as useState93 } from "react";
35583
35728
  import { useRecordsClient as useRecordsClient68 } from "@ai-matrx/records/react";
35584
35729
  import { Badge as Badge15, Button as Button71, cn as cn59 } from "@ai-matrx/design-system";
35585
35730
  import { jsx as jsx113, jsxs as jsxs103 } from "react/jsx-runtime";
@@ -35597,9 +35742,9 @@ function ProposalRow({
35597
35742
  const [settled, setSettled] = useState93(outcome ?? null);
35598
35743
  const [busy, setBusy] = useState93(false);
35599
35744
  const [confirming, setConfirming] = useState93(false);
35600
- const drawnVersion = useRef49(null);
35745
+ const drawnVersion = useRef50(null);
35601
35746
  const needsVersion = change.act === "update" && Boolean(change.record) && change.version === void 0 && !onApply && !settled;
35602
- useEffect80(() => {
35747
+ useEffect81(() => {
35603
35748
  if (needsVersion && change.record && !drawnVersion.current) drawnVersion.current = readVersionNow(client, change.record);
35604
35749
  }, [needsVersion, change.record, client]);
35605
35750
  async function applyThroughTheStore() {
@@ -35687,14 +35832,14 @@ function ProposalRow({
35687
35832
  }
35688
35833
 
35689
35834
  // src/ActionInbox.tsx
35690
- import { useCallback as useCallback44, useEffect as useEffect82, useMemo as useMemo58, useRef as useRef50, useState as useState95 } from "react";
35835
+ import { useCallback as useCallback45, useEffect as useEffect83, useMemo as useMemo58, useRef as useRef51, useState as useState95 } from "react";
35691
35836
  import { useRecordsClient as useRecordsClient70 } from "@ai-matrx/records/react";
35692
35837
  import { Badge as Badge17, Button as Button73, Checkbox as Checkbox11, Skeleton as Skeleton17, cn as cn61 } from "@ai-matrx/design-system";
35693
35838
  import { toggleSelection as toggleSelection2 } from "@ai-matrx/design-system/data-table";
35694
35839
  import { formatAbsoluteDate, formatDurationMs } from "@ai-matrx/kit/format";
35695
35840
 
35696
35841
  // src/ChecklistRunner.tsx
35697
- import { useCallback as useCallback43, useEffect as useEffect81, useMemo as useMemo57, useState as useState94 } from "react";
35842
+ import { useCallback as useCallback44, useEffect as useEffect82, useMemo as useMemo57, useState as useState94 } from "react";
35698
35843
  import { useRecordsClient as useRecordsClient69, useTable as useTable20 } from "@ai-matrx/records/react";
35699
35844
  import { Badge as Badge16, BasicInput as BasicInput21, BasicTextarea as BasicTextarea9, Button as Button72, Skeleton as Skeleton16, cn as cn60 } from "@ai-matrx/design-system";
35700
35845
  import { humanizeIdentifier as humanizeIdentifier13 } from "@ai-matrx/kit/text-case";
@@ -35722,7 +35867,7 @@ function ChecklistRunner({
35722
35867
  const [busy, setBusy] = useState94(null);
35723
35868
  const [said2, setSaid] = useState94(null);
35724
35869
  const mayStart = offerToStart ?? Boolean(recordId);
35725
- const loadRuns = useCallback43(async () => {
35870
+ const loadRuns = useCallback44(async () => {
35726
35871
  if (runId) {
35727
35872
  setRuns(null);
35728
35873
  return;
@@ -35744,13 +35889,13 @@ function ChecklistRunner({
35744
35889
  (held) => held && answered.data.some((r) => r.run_id === held) ? held : answered.data[0]?.run_id ?? null
35745
35890
  );
35746
35891
  }, [client, includeClosed, recordId, runId, tableId]);
35747
- useEffect81(() => {
35892
+ useEffect82(() => {
35748
35893
  void loadRuns();
35749
35894
  }, [loadRuns]);
35750
- useEffect81(() => {
35895
+ useEffect82(() => {
35751
35896
  if (runId) setActiveId(runId);
35752
35897
  }, [runId]);
35753
- const loadSteps = useCallback43(async () => {
35898
+ const loadSteps = useCallback44(async () => {
35754
35899
  if (!activeId) {
35755
35900
  setSteps(null);
35756
35901
  return;
@@ -35764,10 +35909,10 @@ function ChecklistRunner({
35764
35909
  setError(null);
35765
35910
  setSteps(answered.data);
35766
35911
  }, [client, activeId]);
35767
- useEffect81(() => {
35912
+ useEffect82(() => {
35768
35913
  void loadSteps();
35769
35914
  }, [loadSteps]);
35770
- useEffect81(() => {
35915
+ useEffect82(() => {
35771
35916
  if (!mayStart || !tableId) return;
35772
35917
  let cancelled = false;
35773
35918
  void client.checklistTemplates({ about_table_id: tableId, limit: 50 }).then((answered) => {
@@ -35778,7 +35923,7 @@ function ChecklistRunner({
35778
35923
  cancelled = true;
35779
35924
  };
35780
35925
  }, [client, mayStart, tableId]);
35781
- const start = useCallback43(
35926
+ const start = useCallback44(
35782
35927
  async (templateId) => {
35783
35928
  setBusy(templateId);
35784
35929
  setSaid(null);
@@ -35798,7 +35943,7 @@ function ChecklistRunner({
35798
35943
  },
35799
35944
  [client, loadRuns, recordId]
35800
35945
  );
35801
- const complete = useCallback43(
35946
+ const complete = useCallback44(
35802
35947
  async (step2, evidence) => {
35803
35948
  setBusy(step2.step_id);
35804
35949
  setSaid(null);
@@ -35815,7 +35960,7 @@ function ChecklistRunner({
35815
35960
  },
35816
35961
  [client, loadSteps, loadRuns]
35817
35962
  );
35818
- const assign = useCallback43(
35963
+ const assign = useCallback44(
35819
35964
  async (step2, userId) => {
35820
35965
  setBusy(step2.step_id);
35821
35966
  const answered = await client.workAssign({ record_id: step2.step_id, user_id: userId });
@@ -35901,7 +36046,7 @@ function StepRow({
35901
36046
  const host = useRecordsUi();
35902
36047
  const [members, setMembers] = useState94(null);
35903
36048
  const unassigned = !step2.finished && !step2.assignee_user_id && Boolean(step2.role);
35904
- useEffect81(() => {
36049
+ useEffect82(() => {
35905
36050
  if (!unassigned || !onAssign || !host.members || members !== null) return;
35906
36051
  let alive = true;
35907
36052
  void host.members().then((roster) => {
@@ -36008,7 +36153,7 @@ function useMyChecklistSteps(limit = 25) {
36008
36153
  const [steps, setSteps] = useState94([]);
36009
36154
  const [loading, setLoading] = useState94(true);
36010
36155
  const [error, setError] = useState94(null);
36011
- const refresh = useCallback43(async () => {
36156
+ const refresh = useCallback44(async () => {
36012
36157
  if (!me) {
36013
36158
  setSteps([]);
36014
36159
  setLoading(false);
@@ -36036,7 +36181,7 @@ function useMyChecklistSteps(limit = 25) {
36036
36181
  setSteps(held);
36037
36182
  setLoading(false);
36038
36183
  }, [client, limit, me]);
36039
- useEffect81(() => {
36184
+ useEffect82(() => {
36040
36185
  void refresh();
36041
36186
  }, [refresh]);
36042
36187
  return { steps, loading, error, refresh };
@@ -36049,13 +36194,13 @@ function MyChecklistSteps({
36049
36194
  }) {
36050
36195
  const client = useRecordsClient69();
36051
36196
  const { steps: held, loading, error, refresh } = useMyChecklistSteps();
36052
- useEffect81(() => {
36197
+ useEffect82(() => {
36053
36198
  onSteps?.(held.map((s) => s.step_id));
36054
36199
  }, [held, onSteps]);
36055
36200
  const steps = onlyIds ? held.filter((s) => onlyIds.has(s.step_id)) : held;
36056
36201
  const [busy, setBusy] = useState94(null);
36057
36202
  const [refusal4, setRefusal] = useState94(null);
36058
- const complete = useCallback43(
36203
+ const complete = useCallback44(
36059
36204
  async (step2, evidence) => {
36060
36205
  setBusy(step2.step_id);
36061
36206
  const answered = await client.checklistStepComplete({ step_id: step2.step_id, evidence });
@@ -36104,7 +36249,7 @@ function ChecklistsPanel({ tableId, onOpenRecord, className }) {
36104
36249
  const [editing, setEditing] = useState94(null);
36105
36250
  const [openRun, setOpenRun] = useState94(null);
36106
36251
  const [archivedSaid, setArchivedSaid] = useState94(null);
36107
- const load = useCallback43(async () => {
36252
+ const load = useCallback44(async () => {
36108
36253
  const [t, r] = await Promise.all([
36109
36254
  client.checklistTemplates({ about_table_id: tableId, limit: 100 }),
36110
36255
  client.checklistRuns({ about_table_id: tableId, includeClosed: true, limit: 100 })
@@ -36118,7 +36263,7 @@ function ChecklistsPanel({ tableId, onOpenRecord, className }) {
36118
36263
  if (!r.ok) setRuns([]);
36119
36264
  else setRuns(r.data);
36120
36265
  }, [client, tableId]);
36121
- useEffect81(() => {
36266
+ useEffect82(() => {
36122
36267
  void load();
36123
36268
  }, [load]);
36124
36269
  if (templates === null) return /* @__PURE__ */ jsx114(Skeleton16, { className: cn60("h-40 w-full", className) });
@@ -36281,7 +36426,7 @@ function ChecklistTemplateEditor({
36281
36426
  const [error, setError] = useState94(null);
36282
36427
  const [busy, setBusy] = useState94(false);
36283
36428
  const [loading, setLoading] = useState94(Boolean(templateId));
36284
- useEffect81(() => {
36429
+ useEffect82(() => {
36285
36430
  if (!templateId) return;
36286
36431
  let cancelled = false;
36287
36432
  void client.checklistTemplateShape({ template_id: templateId }).then((answered) => {
@@ -36318,8 +36463,8 @@ function ChecklistTemplateEditor({
36318
36463
  }),
36319
36464
  [aboutTableId, name, rows]
36320
36465
  );
36321
- useEffect81(() => setSaved(false), [spec]);
36322
- useEffect81(() => {
36466
+ useEffect82(() => setSaved(false), [spec]);
36467
+ useEffect82(() => {
36323
36468
  if (spec.steps.length === 0 || spec.name.length === 0) {
36324
36469
  setRefusal(null);
36325
36470
  return;
@@ -36333,7 +36478,7 @@ function ChecklistTemplateEditor({
36333
36478
  cancelled = true;
36334
36479
  };
36335
36480
  }, [client, spec]);
36336
- const save = useCallback43(async () => {
36481
+ const save = useCallback44(async () => {
36337
36482
  setBusy(true);
36338
36483
  setSaved(false);
36339
36484
  const answered = await client.checklistDeclare({
@@ -36589,9 +36734,9 @@ function ActionInbox({
36589
36734
  const [outcome, setOutcome] = useState95({});
36590
36735
  const [busy, setBusy] = useState95(null);
36591
36736
  const [cursor, setCursor] = useState95(0);
36592
- const listRef = useRef50(null);
36737
+ const listRef = useRef51(null);
36593
36738
  const [selected, setSelected] = useState95(/* @__PURE__ */ new Set());
36594
- const anchor = useRef50(null);
36739
+ const anchor = useRef51(null);
36595
36740
  const [deciding, setDeciding] = useState95(false);
36596
36741
  const [batchSaid, setBatchSaid] = useState95(null);
36597
36742
  const [view, setView] = useState95("inbox");
@@ -36600,8 +36745,8 @@ function ActionInbox({
36600
36745
  const [pickAt, setPickAt] = useState95("");
36601
36746
  const [said2, setSaid] = useState95(null);
36602
36747
  const [stepIds, setStepIds] = useState95(/* @__PURE__ */ new Set());
36603
- const onSteps = useCallback44((ids) => setStepIds(new Set(ids)), []);
36604
- const load = useCallback44(async () => {
36748
+ const onSteps = useCallback45((ids) => setStepIds(new Set(ids)), []);
36749
+ const load = useCallback45(async () => {
36605
36750
  const [result, counted] = await Promise.all([
36606
36751
  client.workInbox({ limit: 200, includeDecided: view === "inbox" && showDecided, view }),
36607
36752
  client.inboxCounts()
@@ -36615,7 +36760,7 @@ function ActionInbox({
36615
36760
  setError(null);
36616
36761
  setItems(result.data);
36617
36762
  }, [client, showDecided, view]);
36618
- useEffect82(() => {
36763
+ useEffect83(() => {
36619
36764
  void load();
36620
36765
  }, [load]);
36621
36766
  const narrowed = useMemo58(() => {
@@ -36630,15 +36775,15 @@ function ActionInbox({
36630
36775
  const groups = useMemo58(() => groupInbox(narrowed, groupBy), [narrowed, groupBy]);
36631
36776
  const shown4 = useMemo58(() => groups.flatMap((g) => g.items), [groups]);
36632
36777
  const elsewhere = (items?.length ?? 0) - narrowed.length;
36633
- useEffect82(() => {
36778
+ useEffect83(() => {
36634
36779
  if (cursor >= shown4.length) setCursor(Math.max(0, shown4.length - 1));
36635
36780
  }, [shown4.length, cursor]);
36636
- useEffect82(() => {
36781
+ useEffect83(() => {
36637
36782
  const list = listRef.current;
36638
36783
  const el = list?.querySelector(`[data-row="${cursor}"]`);
36639
36784
  if (list && el) scrollWithinList(list, el);
36640
36785
  }, [cursor, shown4.length]);
36641
- const commitOne = useCallback44(
36786
+ const commitOne = useCallback45(
36642
36787
  async (item, approve, madeAtOnce = null) => {
36643
36788
  if (item.kind === "assignment") return;
36644
36789
  setBusy(item.item_id);
@@ -36655,16 +36800,16 @@ function ActionInbox({
36655
36800
  [client, load]
36656
36801
  );
36657
36802
  const [held, setHeld] = useState95({});
36658
- const holds2 = useRef50(/* @__PURE__ */ new Map());
36659
- const lastHold = useRef50(null);
36660
- const holdSeq = useRef50(0);
36803
+ const holds2 = useRef51(/* @__PURE__ */ new Map());
36804
+ const lastHold = useRef51(null);
36805
+ const holdSeq = useRef51(0);
36661
36806
  const [, tick] = useState95(0);
36662
- useEffect82(() => {
36807
+ useEffect83(() => {
36663
36808
  if (Object.keys(held).length === 0) return;
36664
36809
  const t = setInterval(() => tick((n) => n + 1), 250);
36665
36810
  return () => clearInterval(t);
36666
36811
  }, [held]);
36667
- const startHold = useCallback44((items2, approve, seconds, commit) => {
36812
+ const startHold = useCallback45((items2, approve, seconds, commit) => {
36668
36813
  const hold = holdSeq.current += 1;
36669
36814
  const until = Date.now() + seconds * 1e3;
36670
36815
  const ids = items2.map((i) => i.item_id);
@@ -36691,7 +36836,7 @@ function ActionInbox({
36691
36836
  return next;
36692
36837
  });
36693
36838
  }, []);
36694
- const undoHold = useCallback44((hold) => {
36839
+ const undoHold = useCallback45((hold) => {
36695
36840
  const entry = holds2.current.get(hold);
36696
36841
  if (!entry) return;
36697
36842
  clearTimeout(entry.timer);
@@ -36704,7 +36849,7 @@ function ActionInbox({
36704
36849
  });
36705
36850
  setSaid({ text: entry.ids.length === 1 ? "Undone. It is waiting on you again, exactly as it was." : `Undone. All ${entry.ids.length} are waiting on you again, exactly as they were.`, undo: null });
36706
36851
  }, []);
36707
- useEffect82(() => {
36852
+ useEffect83(() => {
36708
36853
  const flush = () => {
36709
36854
  for (const entry of [...holds2.current.values()]) entry.commit();
36710
36855
  };
@@ -36714,8 +36859,8 @@ function ActionInbox({
36714
36859
  flush();
36715
36860
  };
36716
36861
  }, []);
36717
- const resumed = useRef50(false);
36718
- useEffect82(() => {
36862
+ const resumed = useRef51(false);
36863
+ useEffect83(() => {
36719
36864
  if (resumed.current || items === null || view !== "inbox") return;
36720
36865
  resumed.current = true;
36721
36866
  const kept = readHolds();
@@ -36738,7 +36883,7 @@ function ActionInbox({
36738
36883
  }
36739
36884
  if (gone.length > 0) forgetHolds(gone);
36740
36885
  }, [items, view, startHold, commitOne]);
36741
- const decide = useCallback44(
36886
+ const decide = useCallback45(
36742
36887
  async (item, approve) => {
36743
36888
  if (item.kind === "assignment" || held[item.item_id]) return;
36744
36889
  const seconds = item.undo_seconds ?? 0;
@@ -36751,11 +36896,11 @@ function ActionInbox({
36751
36896
  },
36752
36897
  [commitOne, startHold, held, shown4.length]
36753
36898
  );
36754
- const decidable = useCallback44(
36899
+ const decidable = useCallback45(
36755
36900
  (item) => item.actionable && item.kind !== "assignment" && !outcome[item.item_id] && !held[item.item_id],
36756
36901
  [outcome, held]
36757
36902
  );
36758
- const select = useCallback44(
36903
+ const select = useCallback45(
36759
36904
  (index, shift) => {
36760
36905
  const { next, anchor: at } = toggleSelection2({
36761
36906
  order: shown4,
@@ -36771,7 +36916,7 @@ function ActionInbox({
36771
36916
  },
36772
36917
  [shown4, selected, decidable]
36773
36918
  );
36774
- const commitMany = useCallback44(
36919
+ const commitMany = useCallback45(
36775
36920
  async (chosen, approve) => {
36776
36921
  if (chosen.length === 0) return;
36777
36922
  setDeciding(true);
@@ -36798,7 +36943,7 @@ function ActionInbox({
36798
36943
  },
36799
36944
  [client, load]
36800
36945
  );
36801
- const decideSelected = useCallback44(
36946
+ const decideSelected = useCallback45(
36802
36947
  async (approve) => {
36803
36948
  const chosen = shown4.filter((i) => selected.has(i.item_id) && decidable(i));
36804
36949
  if (chosen.length === 0) return;
@@ -36814,7 +36959,7 @@ function ActionInbox({
36814
36959
  },
36815
36960
  [shown4, selected, decidable, startHold, commitMany]
36816
36961
  );
36817
- const snooze = useCallback44(
36962
+ const snooze = useCallback45(
36818
36963
  async (itemId, title, until) => {
36819
36964
  setSnoozing(null);
36820
36965
  const result = await client.inboxSnooze({ item_id: itemId, until: until.toISOString() });
@@ -36835,7 +36980,7 @@ function ActionInbox({
36835
36980
  },
36836
36981
  [client, load]
36837
36982
  );
36838
- const unsnooze = useCallback44(
36983
+ const unsnooze = useCallback45(
36839
36984
  async (itemId) => {
36840
36985
  const result = await client.inboxUnsnooze({ item_id: itemId });
36841
36986
  if (!result.ok) {
@@ -36847,7 +36992,7 @@ function ActionInbox({
36847
36992
  },
36848
36993
  [client, load]
36849
36994
  );
36850
- const clearItem = useCallback44(
36995
+ const clearItem = useCallback45(
36851
36996
  async (itemId) => {
36852
36997
  const result = await client.inboxClear({ item_id: itemId });
36853
36998
  if (!result.ok) {
@@ -36867,7 +37012,7 @@ function ActionInbox({
36867
37012
  },
36868
37013
  [client, load]
36869
37014
  );
36870
- const unclear = useCallback44(
37015
+ const unclear = useCallback45(
36871
37016
  async (itemId) => {
36872
37017
  const result = await client.inboxUnclear({ item_id: itemId });
36873
37018
  if (!result.ok) {
@@ -36879,22 +37024,22 @@ function ActionInbox({
36879
37024
  },
36880
37025
  [client, load]
36881
37026
  );
36882
- const clearable = useCallback44(
37027
+ const clearable = useCallback45(
36883
37028
  (item) => item.kind === "assignment" && view === "inbox",
36884
37029
  [view]
36885
37030
  );
36886
- const snoozable = useCallback44(
37031
+ const snoozable = useCallback45(
36887
37032
  (item) => view === "inbox" && (item.kind === "assignment" || item.state === "pending") && !outcome[item.item_id],
36888
37033
  [view, outcome]
36889
37034
  );
36890
- const open = useCallback44(
37035
+ const open = useCallback45(
36891
37036
  (item) => {
36892
37037
  if (!onOpenRecord || !item.subject_id) return;
36893
37038
  onOpenRecord(item.subject_id, item.table_id ?? tableId ?? item.subject_id);
36894
37039
  },
36895
37040
  [onOpenRecord, tableId]
36896
37041
  );
36897
- const onKeyDown = useCallback44(
37042
+ const onKeyDown = useCallback45(
36898
37043
  (event) => {
36899
37044
  const item = shown4[cursor];
36900
37045
  const key = event.key;
@@ -37335,7 +37480,7 @@ function ActionInbox({
37335
37480
  }
37336
37481
 
37337
37482
  // src/HistoryPanel.tsx
37338
- import { useCallback as useCallback45, useEffect as useEffect83, useRef as useRef51, useState as useState96 } from "react";
37483
+ import { useCallback as useCallback46, useEffect as useEffect84, useRef as useRef52, useState as useState96 } from "react";
37339
37484
  import {
37340
37485
  useFields as useFields20,
37341
37486
  useRecordChangeRevision,
@@ -37355,11 +37500,11 @@ function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
37355
37500
  const [error, setError] = useState96(null);
37356
37501
  const [open, setOpen] = useState96(null);
37357
37502
  const [pending, setPending] = useState96({ phase: "idle" });
37358
- const seenAtPreview = useRef51(null);
37503
+ const seenAtPreview = useRef52(null);
37359
37504
  const [said2, setSaid] = useState96(null);
37360
- const listRef = useRef51(null);
37505
+ const listRef = useRef52(null);
37361
37506
  const changed = useRecordChangeRevision(recordId);
37362
- const load = useCallback45(async () => {
37507
+ const load = useCallback46(async () => {
37363
37508
  const answered = await client.recordHistory({ record_id: recordId });
37364
37509
  if (!answered.ok) {
37365
37510
  setError(answered.error);
@@ -37368,7 +37513,7 @@ function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
37368
37513
  setError(null);
37369
37514
  setEntries(answered.data);
37370
37515
  }, [client, recordId, changed]);
37371
- useEffect83(() => {
37516
+ useEffect84(() => {
37372
37517
  void load();
37373
37518
  }, [load]);
37374
37519
  if (error) return /* @__PURE__ */ jsx116(RefusalNotice, { error, className });
@@ -37651,7 +37796,7 @@ function say(value, field2) {
37651
37796
  }
37652
37797
 
37653
37798
  // src/CommentThread.tsx
37654
- import { useCallback as useCallback46, useEffect as useEffect84, useMemo as useMemo59, useRef as useRef52, useState as useState97 } from "react";
37799
+ import { useCallback as useCallback47, useEffect as useEffect85, useMemo as useMemo59, useRef as useRef53, useState as useState97 } from "react";
37655
37800
  import {
37656
37801
  useFields as useFields21,
37657
37802
  useRecordsClient as useRecordsClient72,
@@ -37675,8 +37820,8 @@ function CommentThread({ tableId, recordId, fieldKey, className }) {
37675
37820
  const [people, setPeople] = useState97([]);
37676
37821
  const [mentionQuery, setMentionQuery] = useState97(null);
37677
37822
  const [picked, setPicked] = useState97([]);
37678
- const box = useRef52(null);
37679
- const load = useCallback46(async () => {
37823
+ const box = useRef53(null);
37824
+ const load = useCallback47(async () => {
37680
37825
  const answered = await client.commentThread({ record_id: recordId, include_resolved: showResolved });
37681
37826
  if (!answered.ok) {
37682
37827
  setError(answered.error);
@@ -37689,10 +37834,10 @@ function CommentThread({ tableId, recordId, fieldKey, className }) {
37689
37834
  mayResolve: answered.data.may_resolve
37690
37835
  });
37691
37836
  }, [client, recordId, showResolved]);
37692
- useEffect84(() => {
37837
+ useEffect85(() => {
37693
37838
  void load();
37694
37839
  }, [load]);
37695
- useEffect84(() => {
37840
+ useEffect85(() => {
37696
37841
  let alive = true;
37697
37842
  if (!host.members) return;
37698
37843
  void host.members().then((roster) => {
@@ -37895,7 +38040,7 @@ function Line({
37895
38040
  }
37896
38041
 
37897
38042
  // src/FieldHistoryPanel.tsx
37898
- import { useCallback as useCallback47, useEffect as useEffect85, useRef as useRef53, useState as useState98 } from "react";
38043
+ import { useCallback as useCallback48, useEffect as useEffect86, useRef as useRef54, useState as useState98 } from "react";
37899
38044
  import {
37900
38045
  useFields as useFields22,
37901
38046
  useRecordsClient as useRecordsClient73,
@@ -37919,9 +38064,9 @@ function FieldHistoryPanel({
37919
38064
  const [rows, setRows] = useState98(null);
37920
38065
  const [error, setError] = useState98(null);
37921
38066
  const [pending, setPending] = useState98({ phase: "idle" });
37922
- const seenAtPreview = useRef53(null);
38067
+ const seenAtPreview = useRef54(null);
37923
38068
  const [said2, setSaid] = useState98(null);
37924
- const load = useCallback47(async () => {
38069
+ const load = useCallback48(async () => {
37925
38070
  const answered = await client.fieldHistory(
37926
38071
  recordId ? { table_id: tableId, field_key: fieldKey, record_id: recordId } : { table_id: tableId, field_key: fieldKey }
37927
38072
  );
@@ -37932,7 +38077,7 @@ function FieldHistoryPanel({
37932
38077
  setError(null);
37933
38078
  setRows(answered.data);
37934
38079
  }, [client, tableId, fieldKey, recordId]);
37935
- useEffect85(() => {
38080
+ useEffect86(() => {
37936
38081
  void load();
37937
38082
  }, [load]);
37938
38083
  const label = (fields.data ?? []).find((f) => f.key === fieldKey)?.label || humanizeIdentifier16(fieldKey);
@@ -38327,7 +38472,7 @@ function submissionStamp(args) {
38327
38472
  }
38328
38473
 
38329
38474
  // src/FormResultsPanel.tsx
38330
- import { useEffect as useEffect89, useMemo as useMemo62, useState as useState102 } from "react";
38475
+ import { useEffect as useEffect90, useMemo as useMemo62, useState as useState102 } from "react";
38331
38476
  import { useFields as useFields23, useOptionalRecordsClient as useOptionalRecordsClient13 } from "@ai-matrx/records/react";
38332
38477
  import { Button as Button77, Skeleton as Skeleton21, cn as cn67 } from "@ai-matrx/design-system";
38333
38478
 
@@ -38356,7 +38501,7 @@ import { cn as cn66 } from "@ai-matrx/design-system";
38356
38501
  import { formatCount as formatCount5 } from "@ai-matrx/kit/format";
38357
38502
 
38358
38503
  // src/linkWords.ts
38359
- import { useEffect as useEffect86, useMemo as useMemo60, useState as useState99 } from "react";
38504
+ import { useEffect as useEffect87, useMemo as useMemo60, useState as useState99 } from "react";
38360
38505
  import { useOptionalRecordsClient as useOptionalRecordsClient11 } from "@ai-matrx/records/react";
38361
38506
 
38362
38507
  // src/charts.ts
@@ -38574,7 +38719,7 @@ function useLinkGroupNamer(block, tableId) {
38574
38719
  const [named, setNamed] = useState99({});
38575
38720
  const [choices, setChoices] = useState99([]);
38576
38721
  const labels = useRecordLabels(choices);
38577
- useEffect86(() => {
38722
+ useEffect87(() => {
38578
38723
  if (!client || groupBy.length === 0 || rows.length === 0) return;
38579
38724
  let cancelled = false;
38580
38725
  void (async () => {
@@ -38617,7 +38762,7 @@ function useLinkGroupNamer(block, tableId) {
38617
38762
  }
38618
38763
 
38619
38764
  // src/measureWords.ts
38620
- import { useEffect as useEffect87, useState as useState100 } from "react";
38765
+ import { useEffect as useEffect88, useState as useState100 } from "react";
38621
38766
  import { useOptionalRecordsClient as useOptionalRecordsClient12 } from "@ai-matrx/records/react";
38622
38767
  import { humanizeIdentifier as humanizeIdentifier17 } from "@ai-matrx/kit/text-case";
38623
38768
  var OP_WORD = { sum: "Total", avg: "Average", min: "Lowest", max: "Highest" };
@@ -38636,7 +38781,7 @@ function useMeasureWords(key, tableId) {
38636
38781
  const client = useOptionalRecordsClient12();
38637
38782
  const [fields, setFields] = useState100(null);
38638
38783
  const needs = key !== "count";
38639
- useEffect87(() => {
38784
+ useEffect88(() => {
38640
38785
  if (!client || !tableId || !needs) return;
38641
38786
  let cancelled = false;
38642
38787
  void client.fields({ table_id: tableId }).then((result) => {
@@ -38651,17 +38796,17 @@ function useMeasureWords(key, tableId) {
38651
38796
 
38652
38797
  // src/chartFrame.tsx
38653
38798
  import {
38654
- useEffect as useEffect88,
38799
+ useEffect as useEffect89,
38655
38800
  useId as useId4,
38656
- useRef as useRef54,
38801
+ useRef as useRef55,
38657
38802
  useState as useState101
38658
38803
  } from "react";
38659
38804
  import { cn as cn65 } from "@ai-matrx/design-system";
38660
38805
  import { jsx as jsx119, jsxs as jsxs109 } from "react/jsx-runtime";
38661
38806
  function useMeasuredWidth(fallback = 480) {
38662
- const ref = useRef54(null);
38807
+ const ref = useRef55(null);
38663
38808
  const [width, setWidth] = useState101(fallback);
38664
- useEffect88(() => {
38809
+ useEffect89(() => {
38665
38810
  const node = ref.current;
38666
38811
  if (!node) return;
38667
38812
  const apply = () => {
@@ -39293,7 +39438,7 @@ function FormResultsPanel({ form, className }) {
39293
39438
  const [results, setResults] = useState102(null);
39294
39439
  const [error, setError] = useState102(null);
39295
39440
  const [round, setRound] = useState102(0);
39296
- useEffect89(() => {
39441
+ useEffect90(() => {
39297
39442
  if (!client) {
39298
39443
  setError(refusal("not_supported", "Results are read from the record store, and this screen has none.", "Open the form inside the app."));
39299
39444
  return;
@@ -39391,7 +39536,7 @@ function FormResultsPanel({ form, className }) {
39391
39536
  }
39392
39537
 
39393
39538
  // src/PortalBuilder.tsx
39394
- import { useCallback as useCallback48, useEffect as useEffect90, useMemo as useMemo63, useRef as useRef55, useState as useState103 } from "react";
39539
+ import { useCallback as useCallback49, useEffect as useEffect91, useMemo as useMemo63, useRef as useRef56, useState as useState103 } from "react";
39395
39540
  import { useRecordsClient as useRecordsClient74, useTables as useTables4 } from "@ai-matrx/records/react";
39396
39541
  import { BasicInput as BasicInput22, Button as Button78, Checkbox as Checkbox12, Label as Label18, Separator as Separator10, Skeleton as Skeleton22, cn as cn68 } from "@ai-matrx/design-system";
39397
39542
  import { Fragment as Fragment49, jsx as jsx122, jsxs as jsxs112 } from "react/jsx-runtime";
@@ -39412,7 +39557,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
39412
39557
  const [inviteRecordId, setInviteRecordId] = useState103("");
39413
39558
  const [inviting, setInviting] = useState103(false);
39414
39559
  const [invitationSaid, setInvitationSaid] = useState103(null);
39415
- const loadFields = useCallback48(
39560
+ const loadFields = useCallback49(
39416
39561
  async (id, fresh = false) => {
39417
39562
  if (fieldsByTable[id] && !fresh) return;
39418
39563
  const answered = await client.fields({ table_id: id });
@@ -39424,7 +39569,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
39424
39569
  },
39425
39570
  [client, fieldsByTable]
39426
39571
  );
39427
- useEffect90(() => {
39572
+ useEffect91(() => {
39428
39573
  if (!portalId) return;
39429
39574
  void (async () => {
39430
39575
  const answered = await client.portalCard({ portal_id: portalId });
@@ -39438,7 +39583,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
39438
39583
  setClientTableId(answered.data.client_table_id);
39439
39584
  })();
39440
39585
  }, [client, portalId]);
39441
- useEffect90(() => {
39586
+ useEffect91(() => {
39442
39587
  if (!tableId) return;
39443
39588
  setExposures(
39444
39589
  (prev) => prev[tableId] ? prev : {
@@ -39451,7 +39596,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
39451
39596
  const cameFromPeople = Boolean(
39452
39597
  tableId && (fieldsByTable[tableId] ?? []).some((f) => editorKindFor(f) === "email")
39453
39598
  );
39454
- useEffect90(() => {
39599
+ useEffect91(() => {
39455
39600
  if (!tableId || portalId || clientTableId !== null || !cameFromPeople) return;
39456
39601
  setClientTableId(tableId);
39457
39602
  setExposures((prev) => {
@@ -39460,13 +39605,13 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
39460
39605
  });
39461
39606
  }, [tableId, portalId, clientTableId, cameFromPeople]);
39462
39607
  const ticked = useMemo63(() => Object.values(exposures).filter((e) => e.on), [exposures]);
39463
- const tiesTo = useCallback48(
39608
+ const tiesTo = useCallback49(
39464
39609
  (id) => (fieldsByTable[id] ?? []).filter(
39465
39610
  (f) => f.type === "relation" && f.relation_target === clientTableId
39466
39611
  ),
39467
39612
  [fieldsByTable, clientTableId]
39468
39613
  );
39469
- useEffect90(() => {
39614
+ useEffect91(() => {
39470
39615
  for (const e of Object.values(exposures)) {
39471
39616
  if (!e.on || e.namesVia.trim() !== "") continue;
39472
39617
  const ties = tiesTo(e.tableId);
@@ -39481,7 +39626,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
39481
39626
  if (on) void loadFields(t.id);
39482
39627
  }
39483
39628
  const [linking, setLinking] = useState103(null);
39484
- const linkingNow = useRef55(null);
39629
+ const linkingNow = useRef56(null);
39485
39630
  async function addLinkBack(id) {
39486
39631
  const clients = (tables.data ?? []).find((t) => t.id === clientTableId);
39487
39632
  if (!clientTableId || !clients) return;
@@ -39508,8 +39653,8 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
39508
39653
  linkingNow.current = null;
39509
39654
  setLinking(null);
39510
39655
  }
39511
- const autoLinked = useRef55(/* @__PURE__ */ new Set());
39512
- useEffect90(() => {
39656
+ const autoLinked = useRef56(/* @__PURE__ */ new Set());
39657
+ useEffect91(() => {
39513
39658
  if (linking !== null || !clientTableId) return;
39514
39659
  for (const e of Object.values(exposures)) {
39515
39660
  if (!e.on || !fieldsByTable[e.tableId] || autoLinked.current.has(e.tableId)) continue;
@@ -39783,7 +39928,7 @@ function clientNoun(table) {
39783
39928
 
39784
39929
  // src/PortalsPanel.tsx
39785
39930
  import { copyText as copyText6 } from "@ai-matrx/kit/clipboard";
39786
- import { useCallback as useCallback49, useEffect as useEffect92, useMemo as useMemo65, useState as useState105 } from "react";
39931
+ import { useCallback as useCallback50, useEffect as useEffect93, useMemo as useMemo65, useState as useState105 } from "react";
39787
39932
  import { useRecordsClient as useRecordsClient76 } from "@ai-matrx/records/react";
39788
39933
  import {
39789
39934
  portalArchiveConsequence,
@@ -39794,7 +39939,7 @@ import {
39794
39939
  import { Badge as Badge21, BasicInput as BasicInput24, Button as Button80, Separator as Separator11, Skeleton as Skeleton23, cn as cn72 } from "@ai-matrx/design-system";
39795
39940
 
39796
39941
  // src/PortalLookEditor.tsx
39797
- import { useEffect as useEffect91, useMemo as useMemo64, useState as useState104 } from "react";
39942
+ import { useEffect as useEffect92, useMemo as useMemo64, useState as useState104 } from "react";
39798
39943
  import { useRecordsClient as useRecordsClient75 } from "@ai-matrx/records/react";
39799
39944
  import { BasicInput as BasicInput23, Button as Button79, cn as cn71 } from "@ai-matrx/design-system";
39800
39945
 
@@ -39919,7 +40064,7 @@ function PortalLookEditor({ card, onSaved, className }) {
39919
40064
  const [said2, setSaid] = useState104(null);
39920
40065
  const [formsError, setFormsError] = useState104(null);
39921
40066
  const [formsUnread, setFormsUnread] = useState104(false);
39922
- useEffect91(() => {
40067
+ useEffect92(() => {
39923
40068
  let cancelled = false;
39924
40069
  void (async () => {
39925
40070
  try {
@@ -40169,13 +40314,13 @@ function PortalsPanel({ tableId, activePortalId, className }) {
40169
40314
  const [exposures, setExposures] = useState105([]);
40170
40315
  const [listError, setListError] = useState105(null);
40171
40316
  const [openId, setOpenId] = useState105(activePortalId ?? null);
40172
- useEffect92(() => {
40317
+ useEffect93(() => {
40173
40318
  if (activePortalId) setOpenId(activePortalId);
40174
40319
  }, [activePortalId]);
40175
40320
  const [building, setBuilding] = useState105(false);
40176
40321
  const [adding, setAdding] = useState105(null);
40177
40322
  const [archiveToken, setArchiveToken] = useState105(0);
40178
- const load = useCallback49(async () => {
40323
+ const load = useCallback50(async () => {
40179
40324
  const [answered, mapped] = await Promise.all([client.portals(), client.portalTables()]);
40180
40325
  if (!answered.ok) {
40181
40326
  setListError(answered.error);
@@ -40187,7 +40332,7 @@ function PortalsPanel({ tableId, activePortalId, className }) {
40187
40332
  setPortals(answered.data);
40188
40333
  setExposures(mapped.ok ? mapped.data : []);
40189
40334
  }, [client]);
40190
- useEffect92(() => {
40335
+ useEffect93(() => {
40191
40336
  void load();
40192
40337
  }, [load]);
40193
40338
  if (portals === null) return /* @__PURE__ */ jsx126(Skeleton23, { className: cn72("h-32 w-full", className) });
@@ -40452,7 +40597,7 @@ function PortalDetail({
40452
40597
  const client = useRecordsClient76();
40453
40598
  const [card, setCard] = useState105(null);
40454
40599
  const [error, setError] = useState105(null);
40455
- const load = useCallback49(async () => {
40600
+ const load = useCallback50(async () => {
40456
40601
  const answered = await client.portalCard({ portal_id: portalId });
40457
40602
  if (!answered.ok) {
40458
40603
  setError(answered.error);
@@ -40462,10 +40607,10 @@ function PortalDetail({
40462
40607
  setError(null);
40463
40608
  setCard(answered.data);
40464
40609
  }, [client, portalId]);
40465
- useEffect92(() => {
40610
+ useEffect93(() => {
40466
40611
  void load();
40467
40612
  }, [load]);
40468
- const revoke = useCallback49(
40613
+ const revoke = useCallback50(
40469
40614
  async (person) => {
40470
40615
  const answered = await client.portalRevoke({
40471
40616
  portal_id: portalId,
@@ -40478,7 +40623,7 @@ function PortalDetail({
40478
40623
  },
40479
40624
  [client, load, onChanged, portalId]
40480
40625
  );
40481
- const preview = useCallback49(
40626
+ const preview = useCallback50(
40482
40627
  async (person, subject) => {
40483
40628
  const answered = await client.portalPreview({
40484
40629
  portal_id: portalId,
@@ -40584,7 +40729,7 @@ function People({
40584
40729
  const [said2, setSaid] = useState105(null);
40585
40730
  const [error, setError] = useState105(null);
40586
40731
  const [previewing, setPreviewing] = useState105(null);
40587
- const revoke = useCallback49(
40732
+ const revoke = useCallback50(
40588
40733
  async (person) => {
40589
40734
  setBusy(true);
40590
40735
  const answered = await onRevoke(person);
@@ -40670,7 +40815,7 @@ function Preview({
40670
40815
  const [which, setWhich] = useState105(first?.table_id ?? null);
40671
40816
  const [rows, setRows] = useState105(null);
40672
40817
  const [error, setError] = useState105(null);
40673
- useEffect92(() => {
40818
+ useEffect93(() => {
40674
40819
  if (!which) return;
40675
40820
  let cancelled = false;
40676
40821
  setRows(null);
@@ -40716,7 +40861,7 @@ function Invite({ card, onInvited }) {
40716
40861
  const [busy, setBusy] = useState105(false);
40717
40862
  const [said2, setSaid] = useState105(null);
40718
40863
  const [error, setError] = useState105(null);
40719
- useEffect92(() => {
40864
+ useEffect93(() => {
40720
40865
  let cancelled = false;
40721
40866
  void client.list({ table_id: card.client_table_id, limit: 200 }).then((answered) => {
40722
40867
  if (cancelled) return;
@@ -40739,7 +40884,7 @@ function Invite({ card, onInvited }) {
40739
40884
  const needle = search.trim().toLowerCase();
40740
40885
  return needle === "" ? all.slice(0, 25) : all.filter((o) => o.name.toLowerCase().includes(needle)).slice(0, 25);
40741
40886
  }, [rows, clientTable, search]);
40742
- const send = useCallback49(async () => {
40887
+ const send = useCallback50(async () => {
40743
40888
  if (!picked) return;
40744
40889
  setBusy(true);
40745
40890
  const answered = await client.portalInvite({
@@ -40927,7 +41072,7 @@ function FormLookFrame({ look, title, children, contained = false, showOwnerHead
40927
41072
  }
40928
41073
 
40929
41074
  // src/DigestScheduler.tsx
40930
- import { useCallback as useCallback50, useEffect as useEffect93, useMemo as useMemo66, useState as useState106 } from "react";
41075
+ import { useCallback as useCallback51, useEffect as useEffect94, useMemo as useMemo66, useState as useState106 } from "react";
40931
41076
  import { useRecordsClient as useRecordsClient77, useTable as useTable24 } from "@ai-matrx/records/react";
40932
41077
  import { hasQuietHours } from "@ai-matrx/records";
40933
41078
  import { BasicInput as BasicInput25, Button as Button81, Checkbox as Checkbox13, Label as Label19, Separator as Separator12, Skeleton as Skeleton24, cn as cn74 } from "@ai-matrx/design-system";
@@ -41025,7 +41170,7 @@ function DigestScheduler({
41025
41170
  const [outcomes, setOutcomes] = useState106(null);
41026
41171
  const [preview, setPreview] = useState106(null);
41027
41172
  const [previewing, setPreviewing] = useState106(false);
41028
- const load = useCallback50(async () => {
41173
+ const load = useCallback51(async () => {
41029
41174
  const [saved, offered] = await Promise.all([
41030
41175
  // The store's own door onto `platform.saved_view`, narrowed in SQL to
41031
41176
  // Tables this person can already open — never a grant on the table behind it.
@@ -41044,7 +41189,7 @@ function DigestScheduler({
41044
41189
  setMembers([]);
41045
41190
  }
41046
41191
  }, [client, tableId, host]);
41047
- useEffect93(() => {
41192
+ useEffect94(() => {
41048
41193
  void load();
41049
41194
  }, [load]);
41050
41195
  const schedule = useMemo66(() => {
@@ -41299,13 +41444,13 @@ function DigestScheduler({
41299
41444
  }
41300
41445
 
41301
41446
  // src/SubscriptionsPanel.tsx
41302
- import { useCallback as useCallback52, useEffect as useEffect95, useState as useState108 } from "react";
41447
+ import { useCallback as useCallback53, useEffect as useEffect96, useState as useState108 } from "react";
41303
41448
  import { useRecordsClient as useRecordsClient79 } from "@ai-matrx/records/react";
41304
41449
  import { hasQuietHours as hasQuietHours2 } from "@ai-matrx/records";
41305
41450
  import { Badge as Badge22, Button as Button83, Skeleton as Skeleton26, Switch as Switch4, cn as cn76 } from "@ai-matrx/design-system";
41306
41451
 
41307
41452
  // src/WebhooksPanel.tsx
41308
- import { useCallback as useCallback51, useEffect as useEffect94, useState as useState107 } from "react";
41453
+ import { useCallback as useCallback52, useEffect as useEffect95, useState as useState107 } from "react";
41309
41454
  import { useRecordsClient as useRecordsClient78, useTable as useTable25 } from "@ai-matrx/records/react";
41310
41455
  import { BasicInput as BasicInput26, Button as Button82, Checkbox as Checkbox14, ConfirmDialog as ConfirmDialog7, Label as Label20, Skeleton as Skeleton25, cn as cn75 } from "@ai-matrx/design-system";
41311
41456
  import { jsx as jsx129, jsxs as jsxs119 } from "react/jsx-runtime";
@@ -41339,7 +41484,7 @@ function WebhooksPanel({ tableId, className }) {
41339
41484
  const [declared2, setDeclared] = useState107(null);
41340
41485
  const [stopping, setStopping] = useState107(null);
41341
41486
  const [readRefused, setReadRefused] = useState107(null);
41342
- const load = useCallback51(async () => {
41487
+ const load = useCallback52(async () => {
41343
41488
  const answered = await client.tableWebhooks({ table_id: tableId });
41344
41489
  if (!answered.ok) {
41345
41490
  setReadRefused(answered.error);
@@ -41351,7 +41496,7 @@ function WebhooksPanel({ tableId, className }) {
41351
41496
  setError(null);
41352
41497
  setHooks(answered.data ?? []);
41353
41498
  }, [client, tableId]);
41354
- useEffect94(() => {
41499
+ useEffect95(() => {
41355
41500
  void load();
41356
41501
  }, [load]);
41357
41502
  const declare2 = async () => {
@@ -41529,7 +41674,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
41529
41674
  const [scheduling, setScheduling] = useState108(false);
41530
41675
  const [changing, setChanging] = useState108(null);
41531
41676
  const host = useRecordsUi();
41532
- const load = useCallback52(async () => {
41677
+ const load = useCallback53(async () => {
41533
41678
  const answered = await client.subscriptions({ table_id: tableId });
41534
41679
  if (!answered.ok) {
41535
41680
  setError(answered.error);
@@ -41539,10 +41684,10 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
41539
41684
  setError(null);
41540
41685
  setRows(answered.data);
41541
41686
  }, [client, tableId]);
41542
- useEffect95(() => {
41687
+ useEffect96(() => {
41543
41688
  void load();
41544
41689
  }, [load]);
41545
- const flip = useCallback52(
41690
+ const flip = useCallback53(
41546
41691
  async (subscription, on) => {
41547
41692
  setBusy(subscription.rule_id);
41548
41693
  const answered = await client.subscriptionMute({
@@ -41558,7 +41703,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
41558
41703
  },
41559
41704
  [client, load]
41560
41705
  );
41561
- const showOne = useCallback52(
41706
+ const showOne = useCallback53(
41562
41707
  async (subscription) => {
41563
41708
  setBusy(subscription.rule_id);
41564
41709
  const answered = await client.subscriptionPreview({ rule_id: subscription.rule_id });
@@ -41730,7 +41875,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
41730
41875
  // src/FormBuilder.tsx
41731
41876
  import { copyText as copyText7 } from "@ai-matrx/kit/clipboard";
41732
41877
  import { ErrorBox as ErrorBox7 } from "@ai-matrx/design-system";
41733
- import { useCallback as useCallback54, useEffect as useEffect97, useMemo as useMemo68, useRef as useRef57, useState as useState111 } from "react";
41878
+ import { useCallback as useCallback55, useEffect as useEffect98, useMemo as useMemo68, useRef as useRef58, useState as useState111 } from "react";
41734
41879
  import { DndContext, KeyboardSensor, PointerSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
41735
41880
  import { SortableContext, arrayMove, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
41736
41881
  import { CSS as CSS2 } from "@dnd-kit/utilities";
@@ -41999,7 +42144,7 @@ function EmbedSnippets({ url, label }) {
41999
42144
  }
42000
42145
 
42001
42146
  // src/FormRunner.tsx
42002
- import { useCallback as useCallback53, useEffect as useEffect96, useMemo as useMemo67, useRef as useRef56, useState as useState110 } from "react";
42147
+ import { useCallback as useCallback54, useEffect as useEffect97, useMemo as useMemo67, useRef as useRef57, useState as useState110 } from "react";
42003
42148
  import { useFields as useFields24, useOptionalRecordsClient as useOptionalRecordsClient14 } from "@ai-matrx/records/react";
42004
42149
  import { Button as Button85, Label as Label22, Progress, Skeleton as Skeleton27, cn as cn77, formThemeClasses } from "@ai-matrx/design-system";
42005
42150
  import { humanizeIdentifier as humanizeIdentifier18 } from "@ai-matrx/kit/text-case";
@@ -42017,7 +42162,7 @@ function ConnectedFormRunner(props) {
42017
42162
  const client = useOptionalRecordsClient14();
42018
42163
  const fields = useFields24(props.form.subject);
42019
42164
  const { form, className } = props;
42020
- const submit = useCallback53(
42165
+ const submit = useCallback54(
42021
42166
  async (values) => {
42022
42167
  if (!client) {
42023
42168
  const said2 = "This form cannot send answers from here, so nothing was sent.";
@@ -42047,7 +42192,7 @@ function ConnectedFormRunner(props) {
42047
42192
  },
42048
42193
  [client, form]
42049
42194
  );
42050
- const whichAsked = useCallback53(
42195
+ const whichAsked = useCallback54(
42051
42196
  async (values) => {
42052
42197
  if (!client) {
42053
42198
  return { ok: false, message: "This preview cannot ask the store which questions come next, so all of them are shown." };
@@ -42116,11 +42261,11 @@ function FormStage({
42116
42261
  const routes = formRoutes(form);
42117
42262
  const [routeKnown, setRouteKnown] = useState110(() => !routes || !whichAsked);
42118
42263
  const [stopped, setStopped] = useState110(null);
42119
- const answersRef = useRef56(answers);
42264
+ const answersRef = useRef57(answers);
42120
42265
  answersRef.current = answers;
42121
42266
  const choose = autoAdvance ?? form.autoAdvance ?? true;
42122
- const decoy = useRef56("");
42123
- const stage = useRef56(null);
42267
+ const decoy = useRef57("");
42268
+ const stage = useRef57(null);
42124
42269
  const questions = useMemo67(() => {
42125
42270
  const byKey = new Map((fields ?? []).map((f) => [f.key, f]));
42126
42271
  return (form.questions ?? []).map((q) => {
@@ -42138,7 +42283,7 @@ function FormStage({
42138
42283
  };
42139
42284
  });
42140
42285
  }, [fields, form.questions]);
42141
- useEffect96(() => {
42286
+ useEffect97(() => {
42142
42287
  if (!whichAsked) return;
42143
42288
  if (!routes) return;
42144
42289
  let cancelled = false;
@@ -42183,19 +42328,19 @@ function FormStage({
42183
42328
  };
42184
42329
  }, [whichAsked, questions, answers]);
42185
42330
  const live = questions.filter((q) => !hidden[q.key]);
42186
- const told = useRef56(answers);
42187
- useEffect96(() => {
42331
+ const told = useRef57(answers);
42332
+ useEffect97(() => {
42188
42333
  if (told.current === answers) return;
42189
42334
  told.current = answers;
42190
42335
  onAnswersChange?.(answers);
42191
42336
  }, [answers, onAnswersChange]);
42192
- const resumeAt = useRef56(
42337
+ const resumeAt = useRef57(
42193
42338
  resumed && initialAnswers && Object.keys(initialAnswers).length > 0 ? questions.find((q) => {
42194
42339
  const v = initialAnswers[q.key];
42195
42340
  return v === void 0 || v === null || v === "";
42196
42341
  })?.key ?? null : null
42197
42342
  );
42198
- useEffect96(() => {
42343
+ useEffect97(() => {
42199
42344
  const key = resumeAt.current;
42200
42345
  if (!key) return;
42201
42346
  const i = live.findIndex((q) => q.key === key);
@@ -42221,7 +42366,7 @@ function FormStage({
42221
42366
  box?.querySelector("[role='radio'][aria-checked='true'], input:not([tabindex='-1']), textarea, select, [role='combobox'], [role='radio'], [role='checkbox']")?.focus();
42222
42367
  }, 0);
42223
42368
  };
42224
- const submit = useCallback53(async () => {
42369
+ const submit = useCallback54(async () => {
42225
42370
  for (const q of live) {
42226
42371
  const say2 = refusalFor(q);
42227
42372
  if (say2) {
@@ -42303,10 +42448,10 @@ function FormStage({
42303
42448
  if (stillMissing) refuse(stillMissing, refusalFor(stillMissing));
42304
42449
  else void submit();
42305
42450
  }
42306
- const routing = useRef56(false);
42451
+ const routing = useRef57(false);
42307
42452
  const [routingNow, setRoutingNow] = useState110(false);
42308
- const typedAhead = useRef56("");
42309
- useEffect96(() => {
42453
+ const typedAhead = useRef57("");
42454
+ useEffect97(() => {
42310
42455
  if (!routingNow) return;
42311
42456
  const hold = (event) => {
42312
42457
  if (!routing.current || event.metaKey || event.ctrlKey || event.altKey || event.isComposing) return;
@@ -42319,7 +42464,7 @@ function FormStage({
42319
42464
  window.addEventListener("keydown", hold, true);
42320
42465
  return () => window.removeEventListener("keydown", hold, true);
42321
42466
  }, [routingNow]);
42322
- const pourTypedAhead = useCallback53(() => {
42467
+ const pourTypedAhead = useCallback54(() => {
42323
42468
  const held = typedAhead.current;
42324
42469
  if (!held || routing.current) return;
42325
42470
  const q = live[Math.min(at, Math.max(live.length - 1, 0))];
@@ -42336,12 +42481,12 @@ function FormStage({
42336
42481
  }
42337
42482
  for (const key of held) target.dispatchEvent(new KeyboardEvent("keydown", { key, bubbles: true, cancelable: true }));
42338
42483
  }, [live, at]);
42339
- useEffect96(() => {
42484
+ useEffect97(() => {
42340
42485
  if (!routingNow) pourTypedAhead();
42341
42486
  }, [routingNow, at, pourTypedAhead]);
42342
- const advanceRef = useRef56(advance);
42487
+ const advanceRef = useRef57(advance);
42343
42488
  advanceRef.current = advance;
42344
- const chosen = useCallback53(() => {
42489
+ const chosen = useCallback54(() => {
42345
42490
  if (!oneAtATime || !choose) return;
42346
42491
  window.setTimeout(() => void advanceRef.current(), 450);
42347
42492
  }, [oneAtATime, choose]);
@@ -42361,23 +42506,23 @@ function FormStage({
42361
42506
  if (event.shiftKey) retreat();
42362
42507
  else advance();
42363
42508
  }
42364
- useEffect96(() => {
42509
+ useEffect97(() => {
42365
42510
  const input = stage.current?.querySelector("[role='radio'][aria-checked='true']") ?? stage.current?.querySelector(
42366
42511
  "input:not([tabindex='-1']), textarea, select, [role='combobox'], [role='radio'], [role='checkbox']"
42367
42512
  );
42368
42513
  input?.focus();
42369
42514
  pourTypedAhead();
42370
42515
  }, [index, done, started]);
42371
- const startTold = useRef56(false);
42372
- useEffect96(() => {
42516
+ const startTold = useRef57(false);
42517
+ useEffect97(() => {
42373
42518
  if (startTold.current || !onStart) return;
42374
42519
  if (Object.values(answers).some((v) => v !== void 0 && v !== null && v !== "")) {
42375
42520
  startTold.current = true;
42376
42521
  onStart();
42377
42522
  }
42378
42523
  }, [answers, onStart]);
42379
- const shownTold = useRef56(/* @__PURE__ */ new Set());
42380
- useEffect96(() => {
42524
+ const shownTold = useRef57(/* @__PURE__ */ new Set());
42525
+ useEffect97(() => {
42381
42526
  if (!onQuestionShown || !started || done) return;
42382
42527
  for (const q of oneAtATime ? current ? [current] : [] : live) {
42383
42528
  if (shownTold.current.has(q.key)) continue;
@@ -42561,7 +42706,7 @@ function ThankYou({
42561
42706
  const title = rawTitle ? pipe(rawTitle) : rawTitle;
42562
42707
  const body = rawBody ? pipe(rawBody) : rawBody;
42563
42708
  const going = redirect !== null && done !== "preview";
42564
- useEffect96(() => {
42709
+ useEffect97(() => {
42565
42710
  if (!going || !redirect) return;
42566
42711
  const timer = window.setTimeout(() => window.location.assign(redirect), REDIRECT_AFTER_MS);
42567
42712
  return () => window.clearTimeout(timer);
@@ -42577,7 +42722,10 @@ function ThankYou({
42577
42722
  ),
42578
42723
  ending?.pictureUrl ? /* @__PURE__ */ jsx132("img", { src: ending.pictureUrl, alt: "", className: "mb-3 max-h-48 w-full rounded-md object-cover" }) : null,
42579
42724
  /* @__PURE__ */ jsx132("h2", { className: "text-2xl font-semibold", "data-records-form-ending": ending?.id ?? "", children: title || "Thank you" }),
42580
- body ? /* @__PURE__ */ jsx132("p", { className: "mt-2 text-base text-muted-foreground", children: authored(host, body, "form-thank-you") }) : null,
42725
+ body ? /* @__PURE__ */ jsxs122(Fragment53, { children: [
42726
+ done === "preview" ? /* @__PURE__ */ jsx132("p", { className: "mt-2 text-xs uppercase tracking-wide text-muted-foreground", children: "After a real send, people read:" }) : null,
42727
+ /* @__PURE__ */ jsx132("p", { className: "mt-2 text-base text-muted-foreground", children: authored(host, body, "form-thank-you") })
42728
+ ] }) : null,
42581
42729
  going ? /* @__PURE__ */ jsxs122("p", { className: "mt-4 flex flex-wrap items-center gap-3 text-sm", children: [
42582
42730
  /* @__PURE__ */ jsx132(
42583
42731
  "a",
@@ -42751,10 +42899,10 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42751
42899
  const [restoredAt, setRestoredAt] = useState111(null);
42752
42900
  const [showResults, setShowResults] = useState111(false);
42753
42901
  const [adding, setAdding] = useState111(false);
42754
- const keysBeforeAdd = useRef57(null);
42902
+ const keysBeforeAdd = useRef58(null);
42755
42903
  const [makeOnMount, setMakeOnMount] = useState111("waiting");
42756
42904
  const publicOrigin = host.publicOrigin ?? (typeof window === "undefined" ? "" : window.location.origin);
42757
- const load = useCallback54(async () => {
42905
+ const load = useCallback55(async () => {
42758
42906
  const answered = await client.forms({ table_id: tableId });
42759
42907
  if (!answered.ok) {
42760
42908
  setError(answered.error);
@@ -42781,10 +42929,10 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42781
42929
  setError(null);
42782
42930
  setForms(mine);
42783
42931
  }, [client, tableId, seed, claimSeed]);
42784
- useEffect97(() => {
42932
+ useEffect98(() => {
42785
42933
  void load();
42786
42934
  }, [load]);
42787
- useEffect97(() => {
42935
+ useEffect98(() => {
42788
42936
  let cancelled = false;
42789
42937
  Promise.resolve().then(() => client.formKnobs()).then((r) => {
42790
42938
  if (!cancelled && r.ok) setOrgKnobs(r.data);
@@ -42793,7 +42941,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42793
42941
  cancelled = true;
42794
42942
  };
42795
42943
  }, [client]);
42796
- useEffect97(() => {
42944
+ useEffect98(() => {
42797
42945
  if (!forms || forms.length === 0) return;
42798
42946
  if (createOnMount && makeOnMount !== "made") return;
42799
42947
  const chosen = forms.find((f) => f.id === (activeFormId ?? activeId)) ?? forms[0];
@@ -42817,7 +42965,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42817
42965
  );
42818
42966
  const stored = useMemo68(() => draft ? (forms ?? []).find((f) => f.id === draft.id) ?? null : null, [draft, forms]);
42819
42967
  const dirty = Boolean(draft && stored && !sameForm(draft, stored));
42820
- useEffect97(() => {
42968
+ useEffect98(() => {
42821
42969
  if (!draft || !stored) return;
42822
42970
  const timer = window.setTimeout(() => {
42823
42971
  if (sameForm(draft, stored)) dropKeptDraft(draft.id);
@@ -42826,7 +42974,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42826
42974
  return () => window.clearTimeout(timer);
42827
42975
  }, [draft, stored]);
42828
42976
  const lookKey = draft ? JSON.stringify(formLookDocument(draft.look ?? null)) : null;
42829
- useEffect97(() => {
42977
+ useEffect98(() => {
42830
42978
  if (lookKey === null) return;
42831
42979
  let cancelled = false;
42832
42980
  const timer = window.setTimeout(() => {
@@ -42843,7 +42991,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42843
42991
  window.clearTimeout(timer);
42844
42992
  };
42845
42993
  }, [client, lookKey]);
42846
- useEffect97(() => {
42994
+ useEffect98(() => {
42847
42995
  const before = keysBeforeAdd.current;
42848
42996
  if (!before || !fields.data) return;
42849
42997
  const made = askableFields(fields.data).filter((f) => !before.has(f.key));
@@ -42954,14 +43102,14 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42954
43102
  return true;
42955
43103
  }
42956
43104
  const [started, setStarted] = useState111(false);
42957
- useEffect97(() => {
43105
+ useEffect98(() => {
42958
43106
  if (!startWithOne || started || forms === null || forms.length > 0) return;
42959
43107
  if (askableFields(fields.data ?? []).length === 0) return;
42960
43108
  if (!table.data && !table.error) return;
42961
43109
  setStarted(true);
42962
43110
  void create(table.data?.name?.trim() ? `${table.data.name.trim()} form` : "Form 1");
42963
43111
  }, [startWithOne, started, forms, fields.data, create, table.data, table.error]);
42964
- useEffect97(() => {
43112
+ useEffect98(() => {
42965
43113
  if (!createOnMount || makeOnMount !== "waiting" || forms === null) return;
42966
43114
  if (!table.data && !table.error) return;
42967
43115
  if (askableFields(fields.data ?? []).length === 0) {
@@ -43552,8 +43700,8 @@ function NotifyOnAnswer({
43552
43700
  const [error, setError] = useState111(null);
43553
43701
  const [said2, setSaid] = useState111(null);
43554
43702
  const [url, setUrl] = useState111(notify?.webhookUrl ?? "");
43555
- useEffect97(() => setUrl(notify?.webhookUrl ?? ""), [notify?.webhookUrl]);
43556
- useEffect97(() => {
43703
+ useEffect98(() => setUrl(notify?.webhookUrl ?? ""), [notify?.webhookUrl]);
43704
+ useEffect98(() => {
43557
43705
  let cancelled = false;
43558
43706
  void client.subscriptions({ table_id: tableId }).then((r) => {
43559
43707
  if (!cancelled && r.ok) setSubs(r.data);
@@ -43684,7 +43832,7 @@ function NotifyOnAnswer({
43684
43832
  }
43685
43833
 
43686
43834
  // src/DocTemplate.tsx
43687
- import { useCallback as useCallback55, useEffect as useEffect98, useState as useState112 } from "react";
43835
+ import { useCallback as useCallback56, useEffect as useEffect99, useState as useState112 } from "react";
43688
43836
  import { useFields as useFields26, useRecordsClient as useRecordsClient81, useTable as useTable27 } from "@ai-matrx/records/react";
43689
43837
  import { BasicInput as BasicInput29, BasicTextarea as BasicTextarea12, Button as Button87, Label as Label24, Skeleton as Skeleton29, cn as cn79 } from "@ai-matrx/design-system";
43690
43838
  import { jsx as jsx134, jsxs as jsxs124 } from "react/jsx-runtime";
@@ -43701,7 +43849,7 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
43701
43849
  const [draftBody, setDraftBody] = useState112("");
43702
43850
  const [unresolved, setUnresolved] = useState112([]);
43703
43851
  const [saving, setSaving] = useState112(false);
43704
- const load = useCallback55(async () => {
43852
+ const load = useCallback56(async () => {
43705
43853
  const held = await client.docTemplates({ table_id: tableId });
43706
43854
  if (!held.ok) {
43707
43855
  setError(held.error);
@@ -43732,10 +43880,10 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
43732
43880
  setError(null);
43733
43881
  setTemplates(rows);
43734
43882
  }, [client, tableId, seed, fields.data]);
43735
- useEffect98(() => {
43883
+ useEffect99(() => {
43736
43884
  void load();
43737
43885
  }, [load]);
43738
- useEffect98(() => {
43886
+ useEffect99(() => {
43739
43887
  if (!templates || templates.length === 0) return;
43740
43888
  const chosen = templates.find((t) => t.id === (activeTemplateId ?? activeId)) ?? templates[0];
43741
43889
  if (chosen.id !== activeId) setActiveId(chosen.id);
@@ -43743,7 +43891,7 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
43743
43891
  setDraftBody(chosen.body);
43744
43892
  onActiveTemplate?.(chosen);
43745
43893
  }, [templates, activeTemplateId]);
43746
- useEffect98(() => {
43894
+ useEffect99(() => {
43747
43895
  let cancelled = false;
43748
43896
  if (draftBody.trim() === "") {
43749
43897
  setUnresolved([]);
@@ -43854,21 +44002,21 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
43854
44002
  onChange: (e) => setDraftBody(e.target.value)
43855
44003
  }
43856
44004
  ),
43857
- unresolved.length > 0 ? /* @__PURE__ */ jsx134("ul", { className: "flex flex-col gap-0.5 rounded border border-dashed px-2 py-1 text-xs", children: unresolved.map((token) => /* @__PURE__ */ jsxs124("li", { className: "flex items-baseline gap-1", children: [
43858
- /* @__PURE__ */ jsx134("code", { className: "text-destructive", children: token.raw }),
44005
+ unresolved.length > 0 ? /* @__PURE__ */ jsx134("ul", { className: "flex flex-col gap-0.5 rounded border border-dashed px-2 py-1 text-xs", children: unresolved.map((token2) => /* @__PURE__ */ jsxs124("li", { className: "flex items-baseline gap-1", children: [
44006
+ /* @__PURE__ */ jsx134("code", { className: "text-destructive", children: token2.raw }),
43859
44007
  /* @__PURE__ */ jsx134("span", { "aria-hidden": "true", children: "\u2014" }),
43860
44008
  /* @__PURE__ */ jsx134(
43861
44009
  RefusalLine,
43862
44010
  {
43863
- error: refusal("invalid_argument", token.why, "Change it to a Field this table has, or take it out.")
44011
+ error: refusal("invalid_argument", token2.why, "Change it to a Field this table has, or take it out.")
43864
44012
  }
43865
44013
  )
43866
- ] }, token.raw)) }) : draftBody.trim() !== "" ? /* @__PURE__ */ jsx134("p", { className: "text-xs text-muted-foreground", children: "Every token in this body points at a Field this table can answer." }) : null
44014
+ ] }, token2.raw)) }) : draftBody.trim() !== "" ? /* @__PURE__ */ jsx134("p", { className: "text-xs text-muted-foreground", children: "Every token in this body points at a Field this table can answer." }) : null
43867
44015
  ] });
43868
44016
  }
43869
44017
 
43870
44018
  // src/DocRender.tsx
43871
- import { useCallback as useCallback56, useEffect as useEffect99, useRef as useRef58, useState as useState113 } from "react";
44019
+ import { useCallback as useCallback57, useEffect as useEffect100, useRef as useRef59, useState as useState113 } from "react";
43872
44020
  import { useRecordsClient as useRecordsClient82 } from "@ai-matrx/records/react";
43873
44021
  import { Button as Button88, Skeleton as Skeleton30, cn as cn80 } from "@ai-matrx/design-system";
43874
44022
  import { jsx as jsx135, jsxs as jsxs125 } from "react/jsx-runtime";
@@ -43879,8 +44027,8 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
43879
44027
  const [showing, setShowing] = useState113(null);
43880
44028
  const [error, setError] = useState113(null);
43881
44029
  const [busy, setBusy] = useState113(null);
43882
- const paper = useRef58(null);
43883
- const load = useCallback56(async () => {
44030
+ const paper = useRef59(null);
44031
+ const load = useCallback57(async () => {
43884
44032
  const [body, held] = await Promise.all([
43885
44033
  client.docRenderBody({ template_id: templateId, record_id: recordId }),
43886
44034
  client.docRenders({ record_id: recordId })
@@ -43897,7 +44045,7 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
43897
44045
  setPreview(body.data);
43898
44046
  setRenders(held.data.filter((r) => r.template_id === templateId));
43899
44047
  }, [client, templateId, recordId]);
43900
- useEffect99(() => {
44048
+ useEffect100(() => {
43901
44049
  void load();
43902
44050
  }, [load]);
43903
44051
  async function freeze() {
@@ -43984,7 +44132,7 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
43984
44132
  }
43985
44133
 
43986
44134
  // src/SignBlock.tsx
43987
- import { useCallback as useCallback57, useEffect as useEffect100, useState as useState114 } from "react";
44135
+ import { useCallback as useCallback58, useEffect as useEffect101, useState as useState114 } from "react";
43988
44136
  import { useFields as useFields27, useRecordsClient as useRecordsClient83 } from "@ai-matrx/records/react";
43989
44137
  import { BasicInput as BasicInput30, Button as Button89, Skeleton as Skeleton31, cn as cn81 } from "@ai-matrx/design-system";
43990
44138
  import { useTable as useTable28 } from "@ai-matrx/records/react";
@@ -43999,7 +44147,7 @@ function SignBlock({ tableId, recordId, render, className }) {
43999
44147
  const [error, setError] = useState114(null);
44000
44148
  const [name, setName] = useState114("");
44001
44149
  const [busy, setBusy] = useState114(false);
44002
- const load = useCallback57(async () => {
44150
+ const load = useCallback58(async () => {
44003
44151
  const held = await client.docSignatures({ record_id: recordId });
44004
44152
  if (!held.ok) {
44005
44153
  setError(held.error);
@@ -44014,7 +44162,7 @@ function SignBlock({ tableId, recordId, render, className }) {
44014
44162
  }
44015
44163
  setVerdicts(answers);
44016
44164
  }, [client, recordId]);
44017
- useEffect100(() => {
44165
+ useEffect101(() => {
44018
44166
  void load();
44019
44167
  }, [load]);
44020
44168
  async function sign(field2) {
@@ -44135,7 +44283,7 @@ function SignBlock({ tableId, recordId, render, className }) {
44135
44283
  }
44136
44284
 
44137
44285
  // src/NotifyRuleEditor.tsx
44138
- import { useCallback as useCallback58, useEffect as useEffect101, useState as useState115 } from "react";
44286
+ import { useCallback as useCallback59, useEffect as useEffect102, useState as useState115 } from "react";
44139
44287
  import { useRecordsClient as useRecordsClient84, useTable as useTable29 } from "@ai-matrx/records/react";
44140
44288
  import { hasQuietHours as hasQuietHours3 } from "@ai-matrx/records";
44141
44289
  import { Button as Button90, Skeleton as Skeleton32, cn as cn82 } from "@ai-matrx/design-system";
@@ -44153,7 +44301,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
44153
44301
  const [error, setError] = useState115(null);
44154
44302
  const [busy, setBusy] = useState115(false);
44155
44303
  const [stopping, setStopping] = useState115(null);
44156
- const load = useCallback58(async () => {
44304
+ const load = useCallback59(async () => {
44157
44305
  const [held, offered] = await Promise.all([
44158
44306
  // THE PERSON'S OWN DOOR, not the notifier's. It answers what is addressed
44159
44307
  // to them plus — only where they hold admin on this Table — anyone's over
@@ -44181,10 +44329,10 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
44181
44329
  }
44182
44330
  setViews(listed.data.map((v) => ({ id: v.view_id, name: v.name })));
44183
44331
  }, [client, host, tableId]);
44184
- useEffect101(() => {
44332
+ useEffect102(() => {
44185
44333
  void load();
44186
44334
  }, [load]);
44187
- const write = useCallback58(
44335
+ const write = useCallback59(
44188
44336
  async (spec) => {
44189
44337
  const declared2 = await client.subscriptionDeclare({
44190
44338
  table_id: tableId,
@@ -44209,7 +44357,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
44209
44357
  },
44210
44358
  [client, tableId]
44211
44359
  );
44212
- useEffect101(() => {
44360
+ useEffect102(() => {
44213
44361
  if (!subscriptions || !seed || seed.length === 0) return;
44214
44362
  const missing = seed.filter((s) => !subscriptions.some((held) => held.name === s.name));
44215
44363
  if (missing.length === 0) return;
@@ -44390,7 +44538,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
44390
44538
  }
44391
44539
 
44392
44540
  // src/DashboardCanvas.tsx
44393
- import { useCallback as useCallback59, useEffect as useEffect103, useMemo as useMemo71, useState as useState118 } from "react";
44541
+ import { useCallback as useCallback60, useEffect as useEffect104, useMemo as useMemo71, useState as useState118 } from "react";
44394
44542
  import { useFields as useFields30, useRecordsClient as useRecordsClient86, useTable as useTable31 } from "@ai-matrx/records/react";
44395
44543
  import {
44396
44544
  BasicInput as BasicInput31,
@@ -44570,12 +44718,12 @@ import {
44570
44718
  } from "@ai-matrx/design-system";
44571
44719
 
44572
44720
  // src/TablePickers.tsx
44573
- import { useEffect as useEffect102, useMemo as useMemo69, useState as useState116 } from "react";
44721
+ import { useEffect as useEffect103, useMemo as useMemo69, useState as useState116 } from "react";
44574
44722
  import { RecordsProvider as RecordsProvider2, useFields as useFields28, useRecords as useRecords7, useTable as useTable30 } from "@ai-matrx/records/react";
44575
44723
  import { Button as Button91, CreatablePicker as CreatablePicker2 } from "@ai-matrx/design-system";
44576
44724
 
44577
44725
  // src/RecordsMount.tsx
44578
- import { useRef as useRef59 } from "react";
44726
+ import { useRef as useRef60 } from "react";
44579
44727
  import { RecordsProvider } from "@ai-matrx/records/react";
44580
44728
  import { jsx as jsx139 } from "react/jsx-runtime";
44581
44729
  var STORE_DECIDES_REASON = "This host offers exactly what the record store says this person may do: the level comes back with the table on the read door, so a control they cannot use is never drawn in the first place.";
@@ -44593,7 +44741,7 @@ function RecordsMount({
44593
44741
  return /* @__PURE__ */ jsx139(RecordsProvider, { config, children: /* @__PURE__ */ jsx139(RecordsUiProvider, { value: bound2, children: /* @__PURE__ */ jsx139(RecordLabelProvider, { children }) }) });
44594
44742
  }
44595
44743
  function useShallowStableHost(host) {
44596
- const held = useRef59(null);
44744
+ const held = useRef60(null);
44597
44745
  const next = host ?? {};
44598
44746
  const previous = held.current;
44599
44747
  if (previous !== null && sameParts(previous, next)) return previous;
@@ -44691,7 +44839,7 @@ function readTablesAnywhere(dataSource) {
44691
44839
  }
44692
44840
  function useTablesAnywhere(dataSource) {
44693
44841
  const [state, setState] = useState116({ loading: true, error: null, rows: [] });
44694
- useEffect102(() => {
44842
+ useEffect103(() => {
44695
44843
  let live = true;
44696
44844
  void readTablesAnywhere(dataSource).then((result) => {
44697
44845
  if (live) setState(result);
@@ -45102,7 +45250,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
45102
45250
  ...filter ? { filter } : {},
45103
45251
  ...grain ? { grain } : {}
45104
45252
  });
45105
- const load = useCallback59(async () => {
45253
+ const load = useCallback60(async () => {
45106
45254
  const answered = await client.dashboards({ table_id: tableId });
45107
45255
  if (!answered.ok) {
45108
45256
  setError(answered.error);
@@ -45115,10 +45263,10 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
45115
45263
  return read;
45116
45264
  }, [client, tableId]);
45117
45265
  const [notKept, setNotKept] = useState118(null);
45118
- useEffect103(() => {
45266
+ useEffect104(() => {
45119
45267
  void load();
45120
45268
  }, [load]);
45121
- useEffect103(() => {
45269
+ useEffect104(() => {
45122
45270
  if (!boards || boards.length === 0) return;
45123
45271
  if (createOnMount && madeOnMount !== "done") return;
45124
45272
  const chosen = boards.find((d) => d.id === (activeDashboardId ?? activeId)) ?? boards[0];
@@ -45126,7 +45274,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
45126
45274
  }, [boards, activeDashboardId, madeOnMount]);
45127
45275
  const board = useMemo71(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
45128
45276
  const filterKey = JSON.stringify(filter ?? {});
45129
- useEffect103(() => {
45277
+ useEffect104(() => {
45130
45278
  if (!activeId) {
45131
45279
  setRun(null);
45132
45280
  return;
@@ -45144,7 +45292,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
45144
45292
  cancelled = true;
45145
45293
  };
45146
45294
  }, [client, activeId, filterKey, grain]);
45147
- const declare2 = useCallback59(
45295
+ const declare2 = useCallback60(
45148
45296
  async (next, blocks) => {
45149
45297
  const written = await client.dashboardDeclare(
45150
45298
  // Every block leaves with its own id — kept, or minted here (v6 lane 11).
@@ -45196,12 +45344,12 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
45196
45344
  ]
45197
45345
  );
45198
45346
  }
45199
- useEffect103(() => {
45347
+ useEffect104(() => {
45200
45348
  if (!createOnMount || madeOnMount !== "waiting" || boards === null || !fields.data) return;
45201
45349
  setMadeOnMount("making");
45202
45350
  void create().then(() => setMadeOnMount("done"));
45203
45351
  }, [createOnMount, madeOnMount, boards, fields.data]);
45204
- const refresh = useCallback59(async () => {
45352
+ const refresh = useCallback60(async () => {
45205
45353
  if (!activeId) return;
45206
45354
  setRunning(true);
45207
45355
  const again = await client.dashboardRun(runArgs(activeId));
@@ -45644,7 +45792,7 @@ function TargetControl({
45644
45792
  const [mode, setMode] = useState118(saved);
45645
45793
  const savedValue = block.target && "value" in block.target && typeof block.target.value === "number" ? block.target.value : null;
45646
45794
  const [draft, setDraft] = useState118(savedValue === null ? "" : String(savedValue));
45647
- useEffect103(() => {
45795
+ useEffect104(() => {
45648
45796
  setMode(saved);
45649
45797
  setDraft(savedValue === null ? "" : String(savedValue));
45650
45798
  }, [saved, savedValue]);
@@ -45712,7 +45860,7 @@ function TargetControl({
45712
45860
 
45713
45861
  // src/QuestionPanel.tsx
45714
45862
  import { copyText as copyText8 } from "@ai-matrx/kit/clipboard";
45715
- import { useEffect as useEffect104, useMemo as useMemo72, useRef as useRef60, useState as useState119 } from "react";
45863
+ import { useEffect as useEffect105, useMemo as useMemo72, useRef as useRef61, useState as useState119 } from "react";
45716
45864
  import { Badge as Badge23, BasicInput as BasicInput32, Button as Button94, Checkbox as Checkbox16, Label as Label25, Skeleton as Skeleton34, cn as cn85 } from "@ai-matrx/design-system";
45717
45865
  import { useFields as useFields31, useRecordsClient as useRecordsClient87 } from "@ai-matrx/records/react";
45718
45866
 
@@ -46131,7 +46279,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46131
46279
  const me = client.config.actor?.user_id ?? null;
46132
46280
  const [hidden, setHidden] = useState119(null);
46133
46281
  const [related, setRelated] = useState119({});
46134
- useEffect104(() => {
46282
+ useEffect105(() => {
46135
46283
  if (all.length === 0) {
46136
46284
  if (!fields.loading) setHidden(/* @__PURE__ */ new Set());
46137
46285
  return;
@@ -46164,8 +46312,8 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46164
46312
  const [saveError, setSaveError] = useState119(null);
46165
46313
  const [saving, setSaving] = useState119(false);
46166
46314
  const [linkMissed, setLinkMissed] = useState119(false);
46167
- const openedFromLink = useRef60(false);
46168
- useEffect104(() => {
46315
+ const openedFromLink = useRef61(false);
46316
+ useEffect105(() => {
46169
46317
  let live = true;
46170
46318
  void questionsOf(client, tableId).then((answer2) => {
46171
46319
  if (!live) return;
@@ -46188,7 +46336,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46188
46336
  setShared(q ? q.shared : true);
46189
46337
  setSaveError(null);
46190
46338
  };
46191
- useEffect104(() => {
46339
+ useEffect105(() => {
46192
46340
  if (!draft) return;
46193
46341
  open(null);
46194
46342
  setSpec(draft);
@@ -46197,7 +46345,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46197
46345
  const [answer, setAnswer] = useState119(null);
46198
46346
  const [asking, setAsking] = useState119(false);
46199
46347
  const specKey = JSON.stringify(spec);
46200
- useEffect104(() => {
46348
+ useEffect105(() => {
46201
46349
  if (all.length === 0) return;
46202
46350
  let live = true;
46203
46351
  setAsking(true);
@@ -46937,7 +47085,7 @@ function TableAsk({ tableId, onOpenInQuestions }) {
46937
47085
  }
46938
47086
 
46939
47087
  // src/PageScreen.tsx
46940
- import { useCallback as useCallback60, useEffect as useEffect105, useMemo as useMemo73, useState as useState121 } from "react";
47088
+ import { useCallback as useCallback61, useEffect as useEffect106, useMemo as useMemo73, useState as useState121 } from "react";
46941
47089
  import {
46942
47090
  useFields as useFields33,
46943
47091
  useRecordPage as useRecordPage3,
@@ -46975,7 +47123,7 @@ function PageScreen({
46975
47123
  const [mine, setMine] = useState121({});
46976
47124
  const [making, setMaking] = useState121("waiting");
46977
47125
  const id = page?.id ?? pageId ?? null;
46978
- const load = useCallback60(
47126
+ const load = useCallback61(
46979
47127
  async (want) => {
46980
47128
  const answered = await client.dashboards({ table_id: null });
46981
47129
  if (!answered.ok) {
@@ -46994,7 +47142,7 @@ function PageScreen({
46994
47142
  },
46995
47143
  [client]
46996
47144
  );
46997
- useEffect105(() => {
47145
+ useEffect106(() => {
46998
47146
  if (!newOnTable || pageId || making !== "waiting") return;
46999
47147
  setMaking("making");
47000
47148
  void client.dashboardDeclare({
@@ -47014,11 +47162,11 @@ function PageScreen({
47014
47162
  onCreated?.(made.data);
47015
47163
  });
47016
47164
  }, [client, newOnTable, pageId, making, load, onCreated]);
47017
- useEffect105(() => {
47165
+ useEffect106(() => {
47018
47166
  if (!pageId) return;
47019
47167
  void load(pageId);
47020
47168
  }, [pageId, load]);
47021
- useEffect105(() => {
47169
+ useEffect106(() => {
47022
47170
  if (!id) return;
47023
47171
  let live = true;
47024
47172
  void client.myLevels({ ids: [id], subject: "record" }).then((answered) => {
@@ -47030,7 +47178,7 @@ function PageScreen({
47030
47178
  }, [client, id]);
47031
47179
  const canEdit = level !== null && EDIT_LEVELS.has(level);
47032
47180
  const chartKey = page ? JSON.stringify(page.blocks.map((b) => b.id)) + page.version : "";
47033
- useEffect105(() => {
47181
+ useEffect106(() => {
47034
47182
  if (!page || page.blocks.length === 0) {
47035
47183
  setRun(null);
47036
47184
  return;
@@ -47049,7 +47197,7 @@ function PageScreen({
47049
47197
  () => page ? pageBlocksOf(page.presentation, page.blocks.map((b) => b.id ?? "").filter(Boolean)) : [],
47050
47198
  [page]
47051
47199
  );
47052
- const save = useCallback60(
47200
+ const save = useCallback61(
47053
47201
  async (next) => {
47054
47202
  if (!page) return;
47055
47203
  const charts = withBlockIds(next.charts ?? page.blocks);
@@ -47073,7 +47221,7 @@ function PageScreen({
47073
47221
  },
47074
47222
  [client, page, blocks, load]
47075
47223
  );
47076
- const archive = useCallback60(async () => {
47224
+ const archive = useCallback61(async () => {
47077
47225
  if (!page) return;
47078
47226
  setAskingToArchive(false);
47079
47227
  const gone = await client.dashboardDelete({ dashboard_id: page.id });
@@ -47276,7 +47424,7 @@ function AppletBlockView({ block }) {
47276
47424
  function AppletPick({ value, onChange }) {
47277
47425
  const host = useRecordsUi();
47278
47426
  const [options, setOptions] = useState121(null);
47279
- useEffect105(() => {
47427
+ useEffect106(() => {
47280
47428
  let live = true;
47281
47429
  host.applets?.list().then((apps) => live && setOptions(apps.map((a) => ({ value: a.id, label: a.name })))).catch(() => live && setOptions([]));
47282
47430
  return () => {
@@ -47313,7 +47461,7 @@ function ListBlockView({
47313
47461
  const fields = useFields33(block.table_id);
47314
47462
  const all = useMemo73(() => onePerKey3(fields.data ?? []), [fields.data]);
47315
47463
  const [view, setView] = useState121(block.view_id ? "reading" : null);
47316
- useEffect105(() => {
47464
+ useEffect106(() => {
47317
47465
  if (!block.view_id) {
47318
47466
  setView(null);
47319
47467
  return;
@@ -47331,7 +47479,7 @@ function ListBlockView({
47331
47479
  }, [client, block.table_id, block.view_id]);
47332
47480
  const meField = block.me_field ? all.find((f) => f.key === block.me_field) : void 0;
47333
47481
  const [me, setMe] = useState121(null);
47334
- useEffect105(() => {
47482
+ useEffect106(() => {
47335
47483
  if (!mine || !meField?.relation_target || !viewerUserId) {
47336
47484
  setMe(null);
47337
47485
  return;
@@ -47361,12 +47509,12 @@ function ListBlockView({
47361
47509
  ...sort.length > 0 ? { sort } : {}
47362
47510
  });
47363
47511
  const reload = page.reload;
47364
- useEffect105(() => onRecordChanged(() => reload()), [reload]);
47512
+ useEffect106(() => onRecordChanged(() => reload()), [reload]);
47365
47513
  const rows = nobodyIsMe ? [] : page.data?.rows ?? [];
47366
47514
  const columns = block.columns && block.columns.length > 0 ? block.columns.map((k) => all.find((f) => f.key === k)).filter((f) => !!f) : [...all].sort((a, b) => (a.sort ?? 100) - (b.sort ?? 100)).slice(0, DEFAULT_COLUMNS);
47367
47515
  const firstId = rows[0]?.id ?? null;
47368
47516
  const stillThere = selected !== null && rows.some((r) => r.id === selected);
47369
- useEffect105(() => {
47517
+ useEffect106(() => {
47370
47518
  if (page.loading || waiting) return;
47371
47519
  if (!stillThere) onSelect(firstId);
47372
47520
  }, [firstId, stillThere, page.loading, waiting]);
@@ -47433,7 +47581,7 @@ function ActionButton2({ block, recordId }) {
47433
47581
  const [running, setRunning] = useState121(false);
47434
47582
  const [done, setDone] = useState121(null);
47435
47583
  const [error, setError] = useState121(null);
47436
- useEffect105(() => {
47584
+ useEffect106(() => {
47437
47585
  setDone(null);
47438
47586
  setError(null);
47439
47587
  setAsking(false);
@@ -47474,7 +47622,7 @@ function FormBlockView({ block }) {
47474
47622
  const client = useRecordsClient89();
47475
47623
  const [form, setForm] = useState121("reading");
47476
47624
  const [sent, setSent] = useState121(0);
47477
- useEffect105(() => {
47625
+ useEffect106(() => {
47478
47626
  if (!block.form_id) {
47479
47627
  setForm(null);
47480
47628
  return;
@@ -47602,7 +47750,7 @@ function ListSettings({ block, onChange }) {
47602
47750
  const [views, setViews] = useState121([]);
47603
47751
  const fields = useFields33(block.table_id);
47604
47752
  const all = onePerKey3(fields.data ?? []);
47605
- useEffect105(() => {
47753
+ useEffect106(() => {
47606
47754
  let live = true;
47607
47755
  void client.views({ table_id: block.table_id }).then((answered) => {
47608
47756
  if (live) setViews(answered.ok ? answered.data : []);
@@ -47679,7 +47827,7 @@ function ActionPicker({ tableId, value, onChange }) {
47679
47827
  function FormPicker({ tableId, value, onChange }) {
47680
47828
  const client = useRecordsClient89();
47681
47829
  const [forms, setForms] = useState121([]);
47682
- useEffect105(() => {
47830
+ useEffect106(() => {
47683
47831
  let live = true;
47684
47832
  void client.forms({ table_id: tableId }).then((answered) => {
47685
47833
  if (live) setForms(answered.ok ? answered.data : []);
@@ -47725,7 +47873,7 @@ function onePerKey3(all) {
47725
47873
 
47726
47874
  // src/FormsPanel.tsx
47727
47875
  import { copyText as copyText9 } from "@ai-matrx/kit/clipboard";
47728
- import { useCallback as useCallback61, useEffect as useEffect106, useState as useState122 } from "react";
47876
+ import { useCallback as useCallback62, useEffect as useEffect107, useState as useState122 } from "react";
47729
47877
  import { useRecordsClient as useRecordsClient90, useTable as useTable33 } from "@ai-matrx/records/react";
47730
47878
  import { publicFormPath as publicFormPath2 } from "@ai-matrx/records";
47731
47879
  import { Badge as Badge24, Button as Button97, Skeleton as Skeleton37, cn as cn87 } from "@ai-matrx/design-system";
@@ -47750,10 +47898,10 @@ function FormsPanel({ tableId, activeFormId, className }) {
47750
47898
  const [archivedSaid, setArchivedSaid] = useState122(null);
47751
47899
  const linked = activeFormId && forms !== null ? forms.find((f) => f.form_id === activeFormId) ?? null : null;
47752
47900
  const linkedMissing = Boolean(activeFormId) && forms !== null && linked === null;
47753
- useEffect106(() => {
47901
+ useEffect107(() => {
47754
47902
  if (linked && rights.structure) setBuilding(true);
47755
47903
  }, [linked, rights.structure]);
47756
- const load = useCallback61(async () => {
47904
+ const load = useCallback62(async () => {
47757
47905
  const answered = await client.forms({ table_id: tableId });
47758
47906
  if (!answered.ok) {
47759
47907
  setError(answered.error);
@@ -47763,10 +47911,10 @@ function FormsPanel({ tableId, activeFormId, className }) {
47763
47911
  setError(null);
47764
47912
  setForms(answered.data);
47765
47913
  }, [client, tableId]);
47766
- useEffect106(() => {
47914
+ useEffect107(() => {
47767
47915
  void load();
47768
47916
  }, [load]);
47769
- const toggle = useCallback61(
47917
+ const toggle = useCallback62(
47770
47918
  async (form) => {
47771
47919
  setBusy(form.form_id);
47772
47920
  const wanted = form.published_at === null || form.closed_at !== null;
@@ -47781,7 +47929,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
47781
47929
  [client, load]
47782
47930
  );
47783
47931
  const [shown4, setShown] = useState122(null);
47784
- const copy = useCallback61(async (url, formId) => {
47932
+ const copy = useCallback62(async (url, formId) => {
47785
47933
  if (await copyText9(url)) {
47786
47934
  setCopied(formId);
47787
47935
  setShown(null);
@@ -47908,12 +48056,12 @@ function FormsPanel({ tableId, activeFormId, className }) {
47908
48056
  }
47909
48057
 
47910
48058
  // src/CaptureSheet.tsx
47911
- import { useCallback as useCallback63, useEffect as useEffect108, useRef as useRef62, useState as useState124 } from "react";
48059
+ import { useCallback as useCallback64, useEffect as useEffect109, useRef as useRef63, useState as useState124 } from "react";
47912
48060
  import { useFields as useFields34, useRecordsClient as useRecordsClient92, useTable as useTable34 } from "@ai-matrx/records/react";
47913
48061
  import { Button as Button99, Input as Input8, Skeleton as Skeleton39, Textarea as Textarea7, cn as cn89 } from "@ai-matrx/design-system";
47914
48062
 
47915
48063
  // src/CaptureRun.tsx
47916
- import { useCallback as useCallback62, useEffect as useEffect107, useMemo as useMemo74, useRef as useRef61, useState as useState123 } from "react";
48064
+ import { useCallback as useCallback63, useEffect as useEffect108, useMemo as useMemo74, useRef as useRef62, useState as useState123 } from "react";
47917
48065
  import {
47918
48066
  coerceTypedAnswer as coerceTypedAnswer3,
47919
48067
  coercionLabel,
@@ -47971,8 +48119,8 @@ function CaptureRun({ sheetId, face: given, className }) {
47971
48119
  const [items, setItems] = useState123([]);
47972
48120
  const [lastSynced, setLastSynced] = useState123(null);
47973
48121
  const [sending, setSending] = useState123(false);
47974
- const queueRef = useRef61(null);
47975
- useEffect107(() => {
48122
+ const queueRef = useRef62(null);
48123
+ useEffect108(() => {
47976
48124
  const q2 = openCaptureQueue({
47977
48125
  onChange: (c, all) => {
47978
48126
  setCounts(c);
@@ -48010,7 +48158,7 @@ function CaptureRun({ sheetId, face: given, className }) {
48010
48158
  void q2.sync().then(() => void q2.lastSyncedAt().then(setLastSynced));
48011
48159
  return () => q2.dispose();
48012
48160
  }, [client, host]);
48013
- useEffect107(() => {
48161
+ useEffect108(() => {
48014
48162
  if (given !== void 0) return;
48015
48163
  let cancelled = false;
48016
48164
  void client.captureOpen({ sheet_id: sheetId }).then((res) => {
@@ -48032,11 +48180,11 @@ function CaptureRun({ sheetId, face: given, className }) {
48032
48180
  required: f.required
48033
48181
  }));
48034
48182
  }, [face]);
48035
- const fieldOf2 = useCallback62(
48183
+ const fieldOf2 = useCallback63(
48036
48184
  (key) => (face?.fields ?? []).find((f) => f.key === key),
48037
48185
  [face]
48038
48186
  );
48039
- const sync = useCallback62(async () => {
48187
+ const sync = useCallback63(async () => {
48040
48188
  const q2 = queueRef.current;
48041
48189
  if (!q2) return;
48042
48190
  setSending(true);
@@ -48049,7 +48197,7 @@ function CaptureRun({ sheetId, face: given, className }) {
48049
48197
  setSending(false);
48050
48198
  }
48051
48199
  }, []);
48052
- const answered = useCallback62(
48200
+ const answered = useCallback63(
48053
48201
  (key) => {
48054
48202
  if (files[key]) return true;
48055
48203
  const v = answers[key];
@@ -48351,8 +48499,8 @@ function AdHocCaptureSheet({
48351
48499
  const [error, setError] = useState124(null);
48352
48500
  const [uploadError, setUploadError] = useState124(null);
48353
48501
  const [flushing, setFlushing] = useState124(false);
48354
- const queue = useRef62([]);
48355
- const keep = useCallback63(
48502
+ const queue = useRef63([]);
48503
+ const keep = useCallback64(
48356
48504
  async (next) => {
48357
48505
  queue.current = next;
48358
48506
  setPending(next);
@@ -48360,7 +48508,7 @@ function AdHocCaptureSheet({
48360
48508
  },
48361
48509
  [host]
48362
48510
  );
48363
- useEffect108(() => {
48511
+ useEffect109(() => {
48364
48512
  let cancelled = false;
48365
48513
  void (async () => {
48366
48514
  const held = host.captureQueue ? await host.captureQueue.load() : [];
@@ -48372,7 +48520,7 @@ function AdHocCaptureSheet({
48372
48520
  cancelled = true;
48373
48521
  };
48374
48522
  }, [host]);
48375
- const resolved = useCallback63(() => {
48523
+ const resolved = useCallback64(() => {
48376
48524
  const all = fields.data ?? [];
48377
48525
  return {
48378
48526
  reading: readingField ?? all.find((f) => f.type === "range")?.key ?? null,
@@ -48380,7 +48528,7 @@ function AdHocCaptureSheet({
48380
48528
  attachment: attachmentField ?? all.find((f) => f.format === "file" || f.format === "image")?.key ?? null
48381
48529
  };
48382
48530
  }, [attachmentField, fields.data, noteField, readingField, table.data]);
48383
- const flush = useCallback63(async () => {
48531
+ const flush = useCallback64(async () => {
48384
48532
  if (flushing || queue.current.length === 0) return;
48385
48533
  setFlushing(true);
48386
48534
  const left = [];
@@ -48539,7 +48687,7 @@ function AdHocCaptureSheet({
48539
48687
  }
48540
48688
 
48541
48689
  // src/PortalShell.tsx
48542
- import { useCallback as useCallback64, useEffect as useEffect109, useState as useState125 } from "react";
48690
+ import { useCallback as useCallback65, useEffect as useEffect110, useState as useState125 } from "react";
48543
48691
  import { useRecordsClient as useRecordsClient93 } from "@ai-matrx/records/react";
48544
48692
  import { Button as Button100, Skeleton as Skeleton40, cn as cn90 } from "@ai-matrx/design-system";
48545
48693
  import { jsx as jsx149, jsxs as jsxs138 } from "react/jsx-runtime";
@@ -48550,7 +48698,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
48550
48698
  const [error, setError] = useState125(null);
48551
48699
  const [open, setOpen] = useState125(null);
48552
48700
  const [sending, setSending] = useState125(false);
48553
- const load = useCallback64(async () => {
48701
+ const load = useCallback65(async () => {
48554
48702
  const who = await client.externalPrincipalCard();
48555
48703
  if (!who.ok) {
48556
48704
  setError(who.error);
@@ -48565,7 +48713,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
48565
48713
  }
48566
48714
  setReach(reached.data.map((row) => row.resource_id));
48567
48715
  }, [client, resourceType]);
48568
- useEffect109(() => {
48716
+ useEffect110(() => {
48569
48717
  void load();
48570
48718
  }, [load]);
48571
48719
  if (error) {
@@ -48625,7 +48773,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
48625
48773
  function PortalRow({ tableId, recordId }) {
48626
48774
  const client = useRecordsClient93();
48627
48775
  const [title, setTitle] = useState125(null);
48628
- useEffect109(() => {
48776
+ useEffect110(() => {
48629
48777
  let cancelled = false;
48630
48778
  void client.recordRead({ record_id: recordId }).then((answered) => {
48631
48779
  if (cancelled) return;
@@ -48645,7 +48793,7 @@ function PortalRow({ tableId, recordId }) {
48645
48793
  }
48646
48794
 
48647
48795
  // src/PublicViewPage.tsx
48648
- import { useCallback as useCallback65, useEffect as useEffect110, useState as useState126 } from "react";
48796
+ import { useCallback as useCallback66, useEffect as useEffect111, useState as useState126 } from "react";
48649
48797
  import { useRecordsClient as useRecordsClient94 } from "@ai-matrx/records/react";
48650
48798
  import { Skeleton as Skeleton41, cn as cn91 } from "@ai-matrx/design-system";
48651
48799
 
@@ -48669,7 +48817,7 @@ function PublicViewPage({ slug, className }) {
48669
48817
  const [error, setError] = useState126(null);
48670
48818
  const [plan, setPlan] = useState126(null);
48671
48819
  const [gap, setGap] = useState126(null);
48672
- const load = useCallback65(async () => {
48820
+ const load = useCallback66(async () => {
48673
48821
  const notice = await client.worldPublishGapNotice();
48674
48822
  if (notice.ok) setGap(notice.data);
48675
48823
  const resolved = await client.resolvePublishBindingKind({ slug });
@@ -48719,7 +48867,7 @@ function PublicViewPage({ slug, className }) {
48719
48867
  }
48720
48868
  setRows([{ id: chosen.recordId, document: read.data.document, level: "viewer", hidden: read.data.hidden }]);
48721
48869
  }, [client, slug]);
48722
- useEffect110(() => {
48870
+ useEffect111(() => {
48723
48871
  void load();
48724
48872
  }, [load]);
48725
48873
  if (error) return /* @__PURE__ */ jsx150(RefusalNotice, { error, className });
@@ -48757,7 +48905,7 @@ function PublicRow({ row, fields }) {
48757
48905
 
48758
48906
  // src/EmbedFrame.tsx
48759
48907
  import { copyText as copyText10 } from "@ai-matrx/kit/clipboard";
48760
- import { useCallback as useCallback66, useEffect as useEffect111, useState as useState127 } from "react";
48908
+ import { useCallback as useCallback67, useEffect as useEffect112, useState as useState127 } from "react";
48761
48909
  import { useRecordsClient as useRecordsClient95 } from "@ai-matrx/records/react";
48762
48910
  import { Button as Button101, Input as Input9, Skeleton as Skeleton42, Textarea as Textarea8, cn as cn92 } from "@ai-matrx/design-system";
48763
48911
  import { useTable as useTable35 } from "@ai-matrx/records/react";
@@ -48781,7 +48929,7 @@ function EmbedFrame({
48781
48929
  const [busy, setBusy] = useState127(false);
48782
48930
  const mode = formId ? "write" : "read";
48783
48931
  const parsed = origins.split(/[\s,]+/).map((o) => o.trim()).filter((o) => o.length > 0);
48784
- const issue = useCallback66(async () => {
48932
+ const issue = useCallback67(async () => {
48785
48933
  setBusy(true);
48786
48934
  setError(null);
48787
48935
  const minted = await client.anonTokenIssue({
@@ -48800,7 +48948,7 @@ function EmbedFrame({
48800
48948
  setTokenId(minted.data.token_id);
48801
48949
  host.notify?.success("Embed token issued. Copy it now \u2014 it is never shown again.");
48802
48950
  }, [client, formId, host, mode, parsed, recordId, savedViewId]);
48803
- const revoke = useCallback66(async () => {
48951
+ const revoke = useCallback67(async () => {
48804
48952
  if (!tokenId) return;
48805
48953
  setBusy(true);
48806
48954
  const done = await client.anonTokenRevoke({ token_id: tokenId });
@@ -48870,7 +49018,7 @@ function useEmbedHandshake(args) {
48870
49018
  const [loading, setLoading] = useState127(true);
48871
49019
  const origin = args.origin ?? (typeof location === "undefined" ? "" : location.origin);
48872
49020
  const { secret, requiredMode } = args;
48873
- useEffect111(() => {
49021
+ useEffect112(() => {
48874
49022
  let cancelled = false;
48875
49023
  setLoading(true);
48876
49024
  setError(null);
@@ -48893,7 +49041,7 @@ function useEmbedHandshake(args) {
48893
49041
 
48894
49042
  // src/TablePage.tsx
48895
49043
  import { copyText as copyText12 } from "@ai-matrx/kit/clipboard";
48896
- import { useCallback as useCallback68, useEffect as useEffect114, useMemo as useMemo78, useRef as useRef63, useState as useState134 } from "react";
49044
+ import { useCallback as useCallback69, useEffect as useEffect115, useMemo as useMemo78, useRef as useRef64, useState as useState134 } from "react";
48897
49045
  import { archivedByLine as archivedByLine2 } from "@ai-matrx/records";
48898
49046
  import { useFields as useFields37, useRecordsClient as useRecordsClient97, useSeededAnswer, useTable as useTable36 } from "@ai-matrx/records/react";
48899
49047
  import {
@@ -49117,7 +49265,7 @@ function BreakDownDialog({
49117
49265
 
49118
49266
  // src/TableReference.tsx
49119
49267
  import { copyText as copyText11 } from "@ai-matrx/kit/clipboard";
49120
- import { useCallback as useCallback67, useMemo as useMemo76, useState as useState130 } from "react";
49268
+ import { useCallback as useCallback68, useMemo as useMemo76, useState as useState130 } from "react";
49121
49269
  import { useContentTransferCapabilities as useContentTransferCapabilities2 } from "@ai-matrx/alchemy/react/workspace";
49122
49270
  import { Button as Button104, Dialog as Dialog15, DialogContent as DialogContent15, DialogHeader as DialogHeader15, DialogTitle as DialogTitle15 } from "@ai-matrx/design-system";
49123
49271
  import { jsx as jsx154, jsxs as jsxs143 } from "react/jsx-runtime";
@@ -49150,7 +49298,7 @@ function TableReferenceDialog({
49150
49298
  () => tableReferenceChoices(table.id, tableName(table)).filter((c) => port?.supports(c.reference)),
49151
49299
  [table, port]
49152
49300
  );
49153
- const copy = useCallback67(
49301
+ const copy = useCallback68(
49154
49302
  async (choice) => {
49155
49303
  if (!port) return;
49156
49304
  try {
@@ -49276,7 +49424,7 @@ function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated
49276
49424
  }
49277
49425
 
49278
49426
  // src/ViewFilter.tsx
49279
- import { useEffect as useEffect112, useMemo as useMemo77, useState as useState132 } from "react";
49427
+ import { useEffect as useEffect113, useMemo as useMemo77, useState as useState132 } from "react";
49280
49428
  import { Button as Button106, Popover as Popover13, PopoverContent as PopoverContent13, PopoverTrigger as PopoverTrigger13 } from "@ai-matrx/design-system";
49281
49429
  import { useFields as useFields36 } from "@ai-matrx/records/react";
49282
49430
  import { jsx as jsx156, jsxs as jsxs145 } from "react/jsx-runtime";
@@ -49294,7 +49442,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
49294
49442
  const saved = view?.where ?? null;
49295
49443
  const [draft, setDraft] = useState132(saved);
49296
49444
  const savedKey = JSON.stringify(saved);
49297
- useEffect112(() => {
49445
+ useEffect113(() => {
49298
49446
  setDraft(saved);
49299
49447
  }, [view?.id, savedKey]);
49300
49448
  const conditionFields = useMemo77(
@@ -49469,7 +49617,7 @@ function phoneTableActions(actions) {
49469
49617
  }
49470
49618
 
49471
49619
  // src/toolbarFit.ts
49472
- import { useEffect as useEffect113, useState as useState133 } from "react";
49620
+ import { useEffect as useEffect114, useState as useState133 } from "react";
49473
49621
  var FOLDED_GUESS = { look: 104, chooser: 96, tools: 120 };
49474
49622
  var SLOT_MIN = 36;
49475
49623
  function toolbarFold(input) {
@@ -49527,7 +49675,7 @@ function rowNeeds(row) {
49527
49675
  }
49528
49676
  function useToolbarFit(row) {
49529
49677
  const [fold, setFold] = useState133(0);
49530
- useEffect113(() => {
49678
+ useEffect114(() => {
49531
49679
  if (!row) return;
49532
49680
  const widths = {
49533
49681
  look: { full: null, folded: null },
@@ -49612,7 +49760,7 @@ function clippedEnds(scrollLeft, clientWidth, scrollWidth) {
49612
49760
  }
49613
49761
  function useSlotScroll(slot) {
49614
49762
  const [ends, setEnds] = useState133("none");
49615
- useEffect113(() => {
49763
+ useEffect114(() => {
49616
49764
  if (!slot) return;
49617
49765
  let pending = 0;
49618
49766
  const read = () => {
@@ -49740,7 +49888,7 @@ function TableNotHere({
49740
49888
  const [archived, setArchived] = useState134({ phase: "asking" });
49741
49889
  const [restoring, setRestoring] = useState134(false);
49742
49890
  const [refusal4, setRefusal] = useState134(null);
49743
- useEffect114(() => {
49891
+ useEffect115(() => {
49744
49892
  let alive = true;
49745
49893
  void client.tableArchived({ table_id: tableId }).then((answered) => {
49746
49894
  if (!alive) return;
@@ -49850,9 +49998,9 @@ var RAIL_SPELLINGS = {
49850
49998
  };
49851
49999
  function railFromParam(raw) {
49852
50000
  if (typeof raw !== "string") return null;
49853
- const token = raw.trim().toLowerCase();
49854
- if (token === "") return null;
49855
- return RAIL_SPELLINGS[token] ?? null;
50001
+ const token2 = raw.trim().toLowerCase();
50002
+ if (token2 === "") return null;
50003
+ return RAIL_SPELLINGS[token2] ?? null;
49856
50004
  }
49857
50005
  function unknownRailLine(raw) {
49858
50006
  return `The link asked to open \u201C${raw}\u201D on this table, which is not something a table has, so you are looking at its records. A table opens Forms, Bookings, Checklists, Notifications, Portals, Settings, Import, Inbox and Share \u2014 each is in the table's menu.`;
@@ -49960,8 +50108,8 @@ function TablePage({
49960
50108
  return seededViews.find((v) => v.id === asked3) ?? defaultViewOf(seededViews) ?? seededViews[0];
49961
50109
  });
49962
50110
  const [looks, setLooks] = useState134(() => seededViews ? seededOpening?.looks : void 0);
49963
- const looksSeededFor = useRef63(seededViews && seededOpening ? tableId : null);
49964
- useEffect114(() => {
50111
+ const looksSeededFor = useRef64(seededViews && seededOpening ? tableId : null);
50112
+ useEffect115(() => {
49965
50113
  if (looksSeededFor.current === tableId) {
49966
50114
  looksSeededFor.current = null;
49967
50115
  return;
@@ -49987,7 +50135,7 @@ function TablePage({
49987
50135
  const opened = questionsFromLink ? { ...openedByPackage, main: "questions" } : openedByPackage;
49988
50136
  const [views, setViews] = useState134(() => seededViews);
49989
50137
  const [pickedViewId, setPickedViewId] = useState134(savedFromLink);
49990
- const viewSeen = useRef63(null);
50138
+ const viewSeen = useRef64(null);
49991
50139
  const [viewLinkMissed, setViewLinkMissed] = useState134(false);
49992
50140
  const railAsked = typeof activeRail === "string" ? activeRail.trim() : "";
49993
50141
  const railUnknown = railAsked !== "" && railFromParam(railAsked) === null ? railAsked : null;
@@ -50040,7 +50188,7 @@ function TablePage({
50040
50188
  const skeletonFace = skeletonLayoutFor(
50041
50189
  faceUnknown && !layoutFromLink ? rememberedFace ?? shownLayout : shownLayout
50042
50190
  );
50043
- useEffect114(() => {
50191
+ useEffect115(() => {
50044
50192
  if (embedded || faceUnknown || main !== "records" || opened.layout || !table.data) return;
50045
50193
  rememberLayout(tableId, shownLayout);
50046
50194
  }, [embedded, faceUnknown, main, shownLayout, tableId, table.data !== void 0]);
@@ -50058,9 +50206,9 @@ function TablePage({
50058
50206
  lookDiffers: view ? lookDiffers(view, look) : false
50059
50207
  };
50060
50208
  const shownSignature = JSON.stringify(shownReport);
50061
- const reportRef = useRef63(onShownViewChange);
50209
+ const reportRef = useRef64(onShownViewChange);
50062
50210
  reportRef.current = onShownViewChange;
50063
- useEffect114(() => {
50211
+ useEffect115(() => {
50064
50212
  reportRef.current?.(JSON.parse(shownSignature));
50065
50213
  }, [shownSignature]);
50066
50214
  const pickLayout = (next) => {
@@ -50069,18 +50217,18 @@ function TablePage({
50069
50217
  onViewChanged?.(addressForView(view, next));
50070
50218
  void patchView({ layout: next });
50071
50219
  };
50072
- useEffect114(() => {
50220
+ useEffect115(() => {
50073
50221
  if (!activeRecordId) return;
50074
50222
  setOpenRecord(activeRecordId);
50075
50223
  setSurface((now) => ({ ...now, rail: "record" }));
50076
50224
  }, [activeRecordId]);
50077
- useEffect114(() => {
50225
+ useEffect115(() => {
50078
50226
  if (activeRecordId) return;
50079
50227
  const named = railFromParam(activeRail);
50080
50228
  if (named === null || named === "share") return;
50081
50229
  setSurface((now) => ({ ...now, rail: named }));
50082
50230
  }, [activeRail, activeRecordId]);
50083
- useEffect114(() => {
50231
+ useEffect115(() => {
50084
50232
  const named = pageViewFromParam(activeView);
50085
50233
  if (named === null) return;
50086
50234
  const isLayout = named !== "dashboards" && named !== "archived";
@@ -50088,7 +50236,7 @@ function TablePage({
50088
50236
  setSurface((now) => ({ ...now, main: isLayout ? "records" : named }));
50089
50237
  }, [activeView]);
50090
50238
  const [viewSaveRefused, setViewSaveRefused] = useState134(null);
50091
- const patchView = useCallback68(
50239
+ const patchView = useCallback69(
50092
50240
  async (asked3) => {
50093
50241
  const current = view;
50094
50242
  if (!current) return;
@@ -50104,10 +50252,10 @@ function TablePage({
50104
50252
  },
50105
50253
  [client, tableId, view, looks]
50106
50254
  );
50107
- const arrival = useRef63(viewAddress ?? null);
50255
+ const arrival = useRef64(viewAddress ?? null);
50108
50256
  const [gridQuery, setGridQuery] = useState134(null);
50109
50257
  const [addressResetEpoch, setAddressResetEpoch] = useState134(0);
50110
- const reportGrid = useCallback68((q) => {
50258
+ const reportGrid = useCallback69((q) => {
50111
50259
  const next = { sort: q.sort, filters: q.filters, search: q.search, page: q.page };
50112
50260
  setGridQuery((held) => sameViewAddress(held, next) ? held : next);
50113
50261
  }, []);
@@ -50115,8 +50263,8 @@ function TablePage({
50115
50263
  () => ({ initial: arrival.current, report: reportGrid, resetEpoch: addressResetEpoch }),
50116
50264
  [reportGrid, addressResetEpoch]
50117
50265
  );
50118
- const hiddenApplied = useRef63(false);
50119
- useEffect114(() => {
50266
+ const hiddenApplied = useRef64(false);
50267
+ useEffect115(() => {
50120
50268
  const hidden = arrival.current?.hidden;
50121
50269
  if (hiddenApplied.current || !view || !looks || !hidden || hidden.length === 0) return;
50122
50270
  hiddenApplied.current = true;
@@ -50136,10 +50284,10 @@ function TablePage({
50136
50284
  const gridPending = !isViewAddressEmpty({ ...arrival.current ?? {}, hidden: [] });
50137
50285
  const addressReady = Boolean(view && looks) && (gridQuery !== null || !gridPending);
50138
50286
  const addressSignature = JSON.stringify(viewAddressToParams(addressNow));
50139
- const addressReportRef = useRef63(onViewAddressChange);
50287
+ const addressReportRef = useRef64(onViewAddressChange);
50140
50288
  addressReportRef.current = onViewAddressChange;
50141
- const addressSent = useRef63(null);
50142
- useEffect114(() => {
50289
+ const addressSent = useRef64(null);
50290
+ useEffect115(() => {
50143
50291
  if (!addressReady) return;
50144
50292
  if (addressSent.current === null && addressSignature === JSON.stringify(viewAddressToParams(arrival.current))) {
50145
50293
  addressSent.current = addressSignature;
@@ -50367,14 +50515,14 @@ function TablePage({
50367
50515
  }
50368
50516
  });
50369
50517
  const openedEntry = ACTION_PRESS.find((entry) => entry.press.main !== void 0 && entry.press.main === main) ?? ACTION_PRESS.find((entry) => entry.press.rail !== void 0 && entry.press.rail === rail) ?? null;
50370
- const actionsRef = useRef63(actions);
50518
+ const actionsRef = useRef64(actions);
50371
50519
  actionsRef.current = actions;
50372
- const onActionsRef = useRef63(onActions);
50520
+ const onActionsRef = useRef64(onActions);
50373
50521
  onActionsRef.current = onActions;
50374
- useEffect114(() => {
50522
+ useEffect115(() => {
50375
50523
  onActionsRef.current?.(actionsRef.current);
50376
50524
  });
50377
- useEffect114(() => {
50525
+ useEffect115(() => {
50378
50526
  const onKey = (event) => {
50379
50527
  const asked3 = objectActionForKey(actionsRef.current, event);
50380
50528
  if (!asked3) return;
@@ -50901,7 +51049,7 @@ function usePublicReadOnly(client, organizationId, tableId, table, rights) {
50901
51049
  const readOnly = rights.known && rights.read && !rights.write;
50902
51050
  const marked = table?.published_to_web;
50903
51051
  const [isPublic, setIsPublic] = useState134(false);
50904
- useEffect114(() => {
51052
+ useEffect115(() => {
50905
51053
  if (!readOnly || !table) {
50906
51054
  setIsPublic(false);
50907
51055
  return;
@@ -50927,7 +51075,7 @@ function usePublicReadOnly(client, organizationId, tableId, table, rights) {
50927
51075
  import { formatCount as formatCount7 } from "@ai-matrx/kit/format";
50928
51076
  import { TapTargetSearchGroup as TapTargetSearchGroup2, TooltipProvider } from "@ai-matrx/design-system";
50929
51077
  import { MatrxTableCardShowMore as MatrxTableCardShowMore3 } from "@ai-matrx/design-system/data-table";
50930
- import { useEffect as useEffect115, useMemo as useMemo79, useState as useState135 } from "react";
51078
+ import { useEffect as useEffect116, useMemo as useMemo79, useState as useState135 } from "react";
50931
51079
  import { Button as Button108, ErrorBox as ErrorBox9, Input as Input12, cn as cn95 } from "@ai-matrx/design-system";
50932
51080
  import { useRecordsClient as useRecordsClient98 } from "@ai-matrx/records/react";
50933
51081
  import { Fragment as Fragment67, jsx as jsx159, jsxs as jsxs148 } from "react/jsx-runtime";
@@ -51014,7 +51162,7 @@ function EntityChartBlock({ source, kind, by, measure, title, where, organizatio
51014
51162
  const m = measure ?? { op: "count" };
51015
51163
  const ask = JSON.stringify([source.token, by ?? null, m, where ?? null, organization ?? null]);
51016
51164
  const [block, setBlock] = useState135(null);
51017
- useEffect115(() => {
51165
+ useEffect116(() => {
51018
51166
  let cancelled = false;
51019
51167
  const question = {
51020
51168
  ...by ? { by: [by] } : {},
@@ -51082,7 +51230,7 @@ function EntityTablePageBody({
51082
51230
  const term = searchOverride ?? typed2;
51083
51231
  const entity = useEntityTable(source.token, { pageSize, search: term });
51084
51232
  const [layout, setLayout] = useState135(opened);
51085
- useEffect115(() => setLayout(opened), [opened]);
51233
+ useEffect116(() => setLayout(opened), [opened]);
51086
51234
  const choose = (next) => {
51087
51235
  setLayout(next);
51088
51236
  onLayoutChange?.(next);
@@ -51208,7 +51356,7 @@ function TablePage2(props) {
51208
51356
  }
51209
51357
 
51210
51358
  // src/DataBindingPicker.tsx
51211
- import { useEffect as useEffect116, useMemo as useMemo80 } from "react";
51359
+ import { useEffect as useEffect117, useMemo as useMemo80 } from "react";
51212
51360
  import { isEntityReferenceConfig } from "@ai-matrx/records";
51213
51361
  import { useFields as useFields38, useTable as useTable37 } from "@ai-matrx/records/react";
51214
51362
  import { BasicInput as BasicInput35, Button as Button109, CreatablePicker as CreatablePicker3, cn as cn96 } from "@ai-matrx/design-system";
@@ -51258,11 +51406,11 @@ function defaultBindingTemplate(table, fields) {
51258
51406
  if (!first) return "- {name}";
51259
51407
  const declared2 = table?.title_field;
51260
51408
  const title = (declared2 ? fields.find((f) => f.key === declared2 || f.id === declared2) : void 0) ?? fields.find((f) => NAME_LIKE.test(f.key)) ?? first;
51261
- const token = (f) => bindingPlaceholdersFor(f)[0]?.token ?? `{${f.key}}`;
51409
+ const token2 = (f) => bindingPlaceholdersFor(f)[0]?.token ?? `{${f.key}}`;
51262
51410
  const rest = fields.filter((f) => f.id !== title.id);
51263
51411
  const [a, b] = [...rest.filter((f) => DESCRIPTIVE.test(f.key)), ...rest.filter((f) => !DESCRIPTIVE.test(f.key))];
51264
- if (!a) return `- ${token(title)}`;
51265
- return b ? `- ${token(title)}: ${token(a)} (${token(b)})` : `- ${token(title)}: ${token(a)}`;
51412
+ if (!a) return `- ${token2(title)}`;
51413
+ return b ? `- ${token2(title)}: ${token2(a)} (${token2(b)})` : `- ${token2(title)}: ${token2(a)}`;
51266
51414
  }
51267
51415
  function DataBindingPicker({ dataSource, userId, binding, onChange, disabled, defaultRowLimit = null }) {
51268
51416
  const tables = useTablesAnywhere(dataSource);
@@ -51304,7 +51452,7 @@ function BindingDetails({
51304
51452
  const fields = useFields38(tableId);
51305
51453
  const fieldList = useMemo80(() => fields.data ?? [], [fields.data]);
51306
51454
  const shape = binding.semantic_type;
51307
- useEffect116(() => {
51455
+ useEffect117(() => {
51308
51456
  if (disabled || shape === "value" || binding.transform || fields.loading || fieldList.length === 0) return;
51309
51457
  onChange({
51310
51458
  ...binding,
@@ -51526,7 +51674,7 @@ function RecordNameWords({ tableId, recordId }) {
51526
51674
  }
51527
51675
 
51528
51676
  // src/HeldChangeDecision.tsx
51529
- import { useEffect as useEffect117, useState as useState136 } from "react";
51677
+ import { useEffect as useEffect118, useState as useState136 } from "react";
51530
51678
  import { RecordsProvider as RecordsProvider3, useRecordsClient as useRecordsClient99 } from "@ai-matrx/records/react";
51531
51679
  import { Button as Button110 } from "@ai-matrx/design-system";
51532
51680
  import { jsx as jsx163, jsxs as jsxs151 } from "react/jsx-runtime";
@@ -51538,7 +51686,7 @@ function Decision({ approvalId, onDecided }) {
51538
51686
  const [may, setMay] = useState136(null);
51539
51687
  const [busy, setBusy] = useState136(null);
51540
51688
  const [error, setError] = useState136(null);
51541
- useEffect117(() => {
51689
+ useEffect118(() => {
51542
51690
  let live = true;
51543
51691
  void client.workApprovalMayDecide({ approval_id: approvalId }).then((res) => {
51544
51692
  if (!live) return;
@@ -51571,7 +51719,7 @@ function Decision({ approvalId, onDecided }) {
51571
51719
  }
51572
51720
 
51573
51721
  // src/TemplatePreview.tsx
51574
- import { useEffect as useEffect118, useMemo as useMemo81, useState as useState137 } from "react";
51722
+ import { useEffect as useEffect119, useMemo as useMemo81, useState as useState137 } from "react";
51575
51723
  import { templatePreview } from "@ai-matrx/records/memory";
51576
51724
  import { useRecordsClient as useRecordsClient100 } from "@ai-matrx/records/react";
51577
51725
  import { jsx as jsx164, jsxs as jsxs152 } from "react/jsx-runtime";
@@ -51622,7 +51770,7 @@ function PreviewForms({ preview, booking }) {
51622
51770
  const client = useRecordsClient100();
51623
51771
  const [forms, setForms] = useState137(null);
51624
51772
  const [pages, setPages] = useState137([]);
51625
- useEffect118(() => {
51773
+ useEffect119(() => {
51626
51774
  let gone = false;
51627
51775
  void client.forms().then((answered) => {
51628
51776
  if (!gone) setForms(answered.ok ? answered.data.map(formFromSummary) : []);