@adoptai/genui-components 0.1.56 → 0.1.58

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.
Files changed (52) hide show
  1. package/dist/builders/BuilderForm.d.ts.map +1 -1
  2. package/dist/composites/decision-card/resolver.cjs +634 -0
  3. package/dist/composites/decision-card/resolver.cjs.map +1 -0
  4. package/dist/composites/decision-card/resolver.d.ts +13 -0
  5. package/dist/composites/decision-card/resolver.d.ts.map +1 -0
  6. package/dist/composites/decision-card/resolver.js +627 -0
  7. package/dist/composites/decision-card/resolver.js.map +1 -0
  8. package/dist/composites/document-field-extraction/FieldAuditLog.d.ts +27 -0
  9. package/dist/composites/document-field-extraction/FieldAuditLog.d.ts.map +1 -0
  10. package/dist/composites/document-field-extraction/FieldDetail.d.ts +22 -0
  11. package/dist/composites/document-field-extraction/FieldDetail.d.ts.map +1 -0
  12. package/dist/composites/document-field-extraction/FieldDetails.d.ts +18 -0
  13. package/dist/composites/document-field-extraction/FieldDetails.d.ts.map +1 -0
  14. package/dist/composites/document-field-extraction/bboxTransform.d.ts +25 -0
  15. package/dist/composites/document-field-extraction/bboxTransform.d.ts.map +1 -0
  16. package/dist/composites/document-field-extraction/fieldLabels.d.ts +2 -0
  17. package/dist/composites/document-field-extraction/fieldLabels.d.ts.map +1 -0
  18. package/dist/composites/document-field-extraction/resolver.d.ts +16 -0
  19. package/dist/composites/document-field-extraction/resolver.d.ts.map +1 -0
  20. package/dist/composites/workflow-stepper/resolver.cjs +4 -1
  21. package/dist/composites/workflow-stepper/resolver.cjs.map +1 -1
  22. package/dist/composites/workflow-stepper/resolver.js +4 -1
  23. package/dist/composites/workflow-stepper/resolver.js.map +1 -1
  24. package/dist/index.cjs +2735 -382
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.ts +7 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +2530 -183
  29. package/dist/index.js.map +1 -1
  30. package/dist/renderer.cjs +2410 -178
  31. package/dist/renderer.cjs.map +1 -1
  32. package/dist/renderer.js +2267 -35
  33. package/dist/renderer.js.map +1 -1
  34. package/dist/resolver.cjs +2409 -177
  35. package/dist/resolver.cjs.map +1 -1
  36. package/dist/resolver.d.ts.map +1 -1
  37. package/dist/resolver.js +2267 -35
  38. package/dist/resolver.js.map +1 -1
  39. package/dist/schemas/decision-card.d.ts +149 -0
  40. package/dist/schemas/decision-card.d.ts.map +1 -0
  41. package/dist/schemas/document-field-extraction.d.ts +258 -0
  42. package/dist/schemas/document-field-extraction.d.ts.map +1 -0
  43. package/dist/schemas/index.cjs +283 -1
  44. package/dist/schemas/index.cjs.map +1 -1
  45. package/dist/schemas/index.d.ts +407 -0
  46. package/dist/schemas/index.d.ts.map +1 -1
  47. package/dist/schemas/index.js +283 -1
  48. package/dist/schemas/index.js.map +1 -1
  49. package/dist/shared/InteractionContext.d.ts +10 -0
  50. package/dist/shared/InteractionContext.d.ts.map +1 -1
  51. package/dist/tool-definitions.json +359 -3
  52. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var React41 = require('react');
4
+ var React45 = require('react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var dagre = require('@dagrejs/dagre');
7
7
  var reactDom = require('react-dom');
@@ -37,7 +37,7 @@ function _interopNamespace(e) {
37
37
  return Object.freeze(n);
38
38
  }
39
39
 
40
- var React41__default = /*#__PURE__*/_interopDefault(React41);
40
+ var React45__default = /*#__PURE__*/_interopDefault(React45);
41
41
  var dagre__default = /*#__PURE__*/_interopDefault(dagre);
42
42
  var XLSX__namespace = /*#__PURE__*/_interopNamespace(XLSX);
43
43
  var Papa__default = /*#__PURE__*/_interopDefault(Papa);
@@ -111,14 +111,14 @@ var init_theme = __esm({
111
111
  }
112
112
  });
113
113
  function GenUIThemeProvider({ colors, children }) {
114
- const merged = React41.useMemo(
114
+ const merged = React45.useMemo(
115
115
  () => colors ? __spreadValues(__spreadValues({}, exports.DEFAULT_TOKENS), colors) : exports.DEFAULT_TOKENS,
116
116
  [colors]
117
117
  );
118
118
  return /* @__PURE__ */ jsxRuntime.jsx(GenUIThemeContext.Provider, { value: merged, children });
119
119
  }
120
120
  function useTheme() {
121
- return React41.useContext(GenUIThemeContext);
121
+ return React45.useContext(GenUIThemeContext);
122
122
  }
123
123
  exports.DEFAULT_TOKENS = void 0; var GenUIThemeContext;
124
124
  var init_ThemeContext = __esm({
@@ -134,7 +134,7 @@ var init_ThemeContext = __esm({
134
134
  SECONDARY: exports.SECONDARY,
135
135
  CHART_PALETTE: [...exports.CHART_PALETTE]
136
136
  };
137
- GenUIThemeContext = React41.createContext(exports.DEFAULT_TOKENS);
137
+ GenUIThemeContext = React45.createContext(exports.DEFAULT_TOKENS);
138
138
  }
139
139
  });
140
140
  function renderInline(text) {
@@ -864,11 +864,11 @@ async function getMermaid(t) {
864
864
  }
865
865
  function MermaidFallback({ diagram, title }) {
866
866
  const tokens = useTheme();
867
- const [svg, setSvg] = React41.useState("");
868
- const [err, setErr] = React41.useState(false);
869
- const [full, setFull] = React41.useState(false);
870
- const idRef = React41.useRef(0);
871
- React41.useEffect(() => {
867
+ const [svg, setSvg] = React45.useState("");
868
+ const [err, setErr] = React45.useState(false);
869
+ const [full, setFull] = React45.useState(false);
870
+ const idRef = React45.useRef(0);
871
+ React45.useEffect(() => {
872
872
  const id = ++renderSeq;
873
873
  idRef.current = id;
874
874
  setErr(false);
@@ -937,7 +937,7 @@ function FullscreenModalInner({ nodes, edges, title, onClose }) {
937
937
  ] }) });
938
938
  }
939
939
  function FullscreenModal({ nodes, edges, title, onClose }) {
940
- React41.useEffect(() => {
940
+ React45.useEffect(() => {
941
941
  const h = (e) => {
942
942
  if (e.key === "Escape") onClose();
943
943
  };
@@ -950,8 +950,8 @@ function FullscreenModal({ nodes, edges, title, onClose }) {
950
950
  );
951
951
  }
952
952
  function usePrefersReducedMotion() {
953
- const [reduced, setReduced] = React41.useState(false);
954
- React41.useEffect(() => {
953
+ const [reduced, setReduced] = React45.useState(false);
954
+ React45.useEffect(() => {
955
955
  var _a2;
956
956
  if (typeof matchMedia === "undefined") return;
957
957
  const mq = matchMedia("(prefers-reduced-motion: reduce)");
@@ -995,9 +995,9 @@ function topoOrder(nodeIds, edges) {
995
995
  }
996
996
  function useAutoplay(order, enabled) {
997
997
  const reduced = usePrefersReducedMotion();
998
- const [step, setStep] = React41.useState(0);
998
+ const [step, setStep] = React45.useState(0);
999
999
  const key = order.join("|");
1000
- React41.useEffect(() => {
1000
+ React45.useEffect(() => {
1001
1001
  if (!enabled || reduced || order.length === 0) {
1002
1002
  setStep(0);
1003
1003
  return;
@@ -1019,7 +1019,7 @@ function useAutoplay(order, enabled) {
1019
1019
  timer = setTimeout(tick, 850);
1020
1020
  return () => clearTimeout(timer);
1021
1021
  }, [enabled, reduced, key]);
1022
- return React41.useMemo(() => {
1022
+ return React45.useMemo(() => {
1023
1023
  const m = {};
1024
1024
  order.forEach((id, i) => {
1025
1025
  m[id] = i < step ? "done" : i === step ? "active" : "pending";
@@ -1041,13 +1041,13 @@ function resolveStates(nodes, nodeStates) {
1041
1041
  }
1042
1042
  function Inner({ diagram, title, autoplay, nodeStates }) {
1043
1043
  const tokens = useTheme();
1044
- const [full, setFull] = React41.useState(false);
1045
- const [focused, setFocused] = React41.useState(false);
1046
- const [boxW, setBoxW] = React41.useState(640);
1047
- const containerRef = React41.useRef(null);
1048
- const parsed = React41.useMemo(() => parseMermaidFlow(diagram), [diagram]);
1049
- const layout = React41.useMemo(() => parsed ? computeLayout(parsed) : null, [parsed]);
1050
- const themedEdges = React41.useMemo(
1044
+ const [full, setFull] = React45.useState(false);
1045
+ const [focused, setFocused] = React45.useState(false);
1046
+ const [boxW, setBoxW] = React45.useState(640);
1047
+ const containerRef = React45.useRef(null);
1048
+ const parsed = React45.useMemo(() => parseMermaidFlow(diagram), [diagram]);
1049
+ const layout = React45.useMemo(() => parsed ? computeLayout(parsed) : null, [parsed]);
1050
+ const themedEdges = React45.useMemo(
1051
1051
  () => {
1052
1052
  var _a2;
1053
1053
  return ((_a2 = layout == null ? void 0 : layout.edges) != null ? _a2 : []).map((e) => __spreadProps(__spreadValues({}, e), {
@@ -1059,7 +1059,7 @@ function Inner({ diagram, title, autoplay, nodeStates }) {
1059
1059
  },
1060
1060
  [layout, tokens.ACCENT, tokens.MUTED]
1061
1061
  );
1062
- const order = React41.useMemo(
1062
+ const order = React45.useMemo(
1063
1063
  () => {
1064
1064
  var _a2, _b;
1065
1065
  return topoOrder(((_a2 = layout == null ? void 0 : layout.nodes) != null ? _a2 : []).map((n) => n.id), (_b = layout == null ? void 0 : layout.edges) != null ? _b : []);
@@ -1067,19 +1067,19 @@ function Inner({ diagram, title, autoplay, nodeStates }) {
1067
1067
  [layout]
1068
1068
  );
1069
1069
  const autoStatus = useAutoplay(order, !!autoplay);
1070
- const staticStatus = React41.useMemo(() => {
1070
+ const staticStatus = React45.useMemo(() => {
1071
1071
  var _a2;
1072
1072
  return resolveStates((_a2 = layout == null ? void 0 : layout.nodes) != null ? _a2 : [], nodeStates);
1073
1073
  }, [layout, nodeStates]);
1074
1074
  const statusMap = autoplay ? autoStatus : staticStatus;
1075
- const displayNodes = React41.useMemo(
1075
+ const displayNodes = React45.useMemo(
1076
1076
  () => {
1077
1077
  var _a2;
1078
1078
  return ((_a2 = layout == null ? void 0 : layout.nodes) != null ? _a2 : []).map((n) => __spreadProps(__spreadValues({}, n), { data: __spreadProps(__spreadValues({}, n.data), { status: statusMap[n.id] }) }));
1079
1079
  },
1080
1080
  [layout, statusMap]
1081
1081
  );
1082
- const displayEdges = React41.useMemo(
1082
+ const displayEdges = React45.useMemo(
1083
1083
  () => themedEdges.map((e) => {
1084
1084
  const ss = statusMap[e.source];
1085
1085
  const ts = statusMap[e.target];
@@ -1099,13 +1099,13 @@ function Inner({ diagram, title, autoplay, nodeStates }) {
1099
1099
  const [nodes, setNodes, onNC] = react.useNodesState(displayNodes);
1100
1100
  const [edges, setEdges, onEC] = react.useEdgesState(displayEdges);
1101
1101
  const rf = react.useReactFlow();
1102
- React41.useEffect(() => {
1102
+ React45.useEffect(() => {
1103
1103
  setNodes(displayNodes);
1104
1104
  }, [displayNodes, setNodes]);
1105
- React41.useEffect(() => {
1105
+ React45.useEffect(() => {
1106
1106
  setEdges(displayEdges);
1107
1107
  }, [displayEdges, setEdges]);
1108
- React41.useEffect(() => {
1108
+ React45.useEffect(() => {
1109
1109
  const id = requestAnimationFrame(() => {
1110
1110
  try {
1111
1111
  rf.fitView({ padding: 0.1 });
@@ -1114,14 +1114,14 @@ function Inner({ diagram, title, autoplay, nodeStates }) {
1114
1114
  });
1115
1115
  return () => cancelAnimationFrame(id);
1116
1116
  }, [layout, rf]);
1117
- const handleClickOutside = React41.useCallback((e) => {
1117
+ const handleClickOutside = React45.useCallback((e) => {
1118
1118
  if (containerRef.current && !containerRef.current.contains(e.target)) setFocused(false);
1119
1119
  }, []);
1120
- React41.useEffect(() => {
1120
+ React45.useEffect(() => {
1121
1121
  document.addEventListener("mousedown", handleClickOutside);
1122
1122
  return () => document.removeEventListener("mousedown", handleClickOutside);
1123
1123
  }, [handleClickOutside]);
1124
- React41.useEffect(() => {
1124
+ React45.useEffect(() => {
1125
1125
  const el = containerRef.current;
1126
1126
  if (!el) return;
1127
1127
  let raf = 0;
@@ -1280,15 +1280,15 @@ __export(PdfViewer_exports, {
1280
1280
  PdfViewer: () => PdfViewer
1281
1281
  });
1282
1282
  function PdfViewer({ url, base64, onLoadSuccess }) {
1283
- const [numPages, setNumPages] = React41.useState(0);
1284
- const [currentPage, setCurrentPage] = React41.useState(1);
1285
- const [loading, setLoading] = React41.useState(true);
1286
- const handleLoad = React41.useCallback(({ numPages: n }) => {
1283
+ const [numPages, setNumPages] = React45.useState(0);
1284
+ const [currentPage, setCurrentPage] = React45.useState(1);
1285
+ const [loading, setLoading] = React45.useState(true);
1286
+ const handleLoad = React45.useCallback(({ numPages: n }) => {
1287
1287
  setNumPages(n);
1288
1288
  setLoading(false);
1289
1289
  onLoadSuccess == null ? void 0 : onLoadSuccess(n);
1290
1290
  }, [onLoadSuccess]);
1291
- React41.useEffect(() => {
1291
+ React45.useEffect(() => {
1292
1292
  if (numPages <= 1) return;
1293
1293
  const handler = (e) => {
1294
1294
  var _a2;
@@ -1384,13 +1384,13 @@ __export(ExcelViewer_exports, {
1384
1384
  ExcelViewer: () => ExcelViewer
1385
1385
  });
1386
1386
  function ExcelViewer({ url, base64, onLoadSuccess }) {
1387
- const [sheetNames, setSheetNames] = React41.useState([]);
1388
- const [activeSheet, setActiveSheet] = React41.useState(0);
1389
- const [data, setData] = React41.useState([]);
1390
- const [loading, setLoading] = React41.useState(true);
1391
- const [error, setError] = React41.useState(null);
1392
- const wbRef = React41.useRef(null);
1393
- React41.useEffect(() => {
1387
+ const [sheetNames, setSheetNames] = React45.useState([]);
1388
+ const [activeSheet, setActiveSheet] = React45.useState(0);
1389
+ const [data, setData] = React45.useState([]);
1390
+ const [loading, setLoading] = React45.useState(true);
1391
+ const [error, setError] = React45.useState(null);
1392
+ const wbRef = React45.useRef(null);
1393
+ React45.useEffect(() => {
1394
1394
  let cancelled = false;
1395
1395
  setLoading(true);
1396
1396
  setError(null);
@@ -1448,7 +1448,7 @@ function ExcelViewer({ url, base64, onLoadSuccess }) {
1448
1448
  const rows = XLSX__namespace.utils.sheet_to_json(wbRef.current.Sheets[wbRef.current.SheetNames[idx]], { header: 1 });
1449
1449
  setData(rows);
1450
1450
  };
1451
- React41.useEffect(() => {
1451
+ React45.useEffect(() => {
1452
1452
  if (sheetNames.length <= 1) return;
1453
1453
  const handler = (e) => {
1454
1454
  var _a2;
@@ -1573,10 +1573,10 @@ __export(CsvViewer_exports, {
1573
1573
  });
1574
1574
  function CsvViewer({ url, base64, delimiter, maxRows }) {
1575
1575
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2 } = useTheme();
1576
- const [rows, setRows] = React41.useState([]);
1577
- const [loading, setLoading] = React41.useState(true);
1578
- const [error, setError] = React41.useState(null);
1579
- React41.useEffect(() => {
1576
+ const [rows, setRows] = React45.useState([]);
1577
+ const [loading, setLoading] = React45.useState(true);
1578
+ const [error, setError] = React45.useState(null);
1579
+ React45.useEffect(() => {
1580
1580
  let cancelled = false;
1581
1581
  setLoading(true);
1582
1582
  setError(null);
@@ -1695,10 +1695,10 @@ __export(TextViewer_exports, {
1695
1695
  });
1696
1696
  function TextViewer({ url, base64, markdown = false, maxLines }) {
1697
1697
  const { MUTED: MUTED2 } = useTheme();
1698
- const [text, setText] = React41.useState("");
1699
- const [loading, setLoading] = React41.useState(true);
1700
- const [error, setError] = React41.useState(null);
1701
- React41.useEffect(() => {
1698
+ const [text, setText] = React45.useState("");
1699
+ const [loading, setLoading] = React45.useState(true);
1700
+ const [error, setError] = React45.useState(null);
1701
+ React45.useEffect(() => {
1702
1702
  let cancelled = false;
1703
1703
  setLoading(true);
1704
1704
  setError(null);
@@ -1796,10 +1796,10 @@ function sanitize(html) {
1796
1796
  }
1797
1797
  function DocxViewer({ url, base64 }) {
1798
1798
  const { MUTED: MUTED2, BORDER: BORDER4 } = useTheme();
1799
- const [html, setHtml] = React41.useState("");
1800
- const [loading, setLoading] = React41.useState(true);
1801
- const [error, setError] = React41.useState(null);
1802
- React41.useEffect(() => {
1799
+ const [html, setHtml] = React45.useState("");
1800
+ const [loading, setLoading] = React45.useState(true);
1801
+ const [error, setError] = React45.useState(null);
1802
+ React45.useEffect(() => {
1803
1803
  let cancelled = false;
1804
1804
  setLoading(true);
1805
1805
  setError(null);
@@ -5315,6 +5315,286 @@ var workflowStepperTool = {
5315
5315
  required: ["type", "title", "steps"]
5316
5316
  }
5317
5317
  };
5318
+ var bbox = zod.z.tuple([zod.z.number(), zod.z.number(), zod.z.number(), zod.z.number()]);
5319
+ var fieldSchema = zod.z.object({
5320
+ field_key: zod.z.string(),
5321
+ label: zod.z.string(),
5322
+ value: zod.z.string(),
5323
+ page: zod.z.number(),
5324
+ // 0-indexed, matches PageDimension.page
5325
+ bbox: bbox.nullable().optional(),
5326
+ confidence: zod.z.number().optional(),
5327
+ confidence_tier: zod.z.enum(["green", "amber", "red"]).optional(),
5328
+ badge: zod.z.enum(["SC", "CN", "AB", "SW"]).optional(),
5329
+ state: zod.z.enum(["ok", "corrected", "missing", "warn"]).optional(),
5330
+ entity_type: zod.z.string().optional(),
5331
+ is_primary: zod.z.boolean().optional(),
5332
+ // Set after a human correction (extractor output, or an optimistic in-card
5333
+ // edit) so the editable field card can show old → new and who changed it.
5334
+ previous_value: zod.z.string().nullable().optional(),
5335
+ corrected_by: zod.z.string().nullable().optional()
5336
+ });
5337
+ var pageSchema = zod.z.object({
5338
+ page: zod.z.number(),
5339
+ // 0-indexed
5340
+ imageUrl: zod.z.string().optional(),
5341
+ // host-resolved from the durable image_ref
5342
+ width_pt: zod.z.number(),
5343
+ height_pt: zod.z.number()
5344
+ });
5345
+ var summaryStatSchema = zod.z.object({
5346
+ field_key: zod.z.string(),
5347
+ label: zod.z.string(),
5348
+ value: zod.z.string(),
5349
+ caption: zod.z.string().nullable().optional()
5350
+ });
5351
+ var summaryFactSchema = zod.z.object({
5352
+ field_key: zod.z.string(),
5353
+ label: zod.z.string(),
5354
+ value: zod.z.string(),
5355
+ badge: zod.z.string().nullable().optional()
5356
+ });
5357
+ var summarySchema = zod.z.object({
5358
+ display_name: zod.z.string().nullable().optional(),
5359
+ short_name: zod.z.string().nullable().optional(),
5360
+ organization: zod.z.string().nullable().optional(),
5361
+ domain: zod.z.string().nullable().optional(),
5362
+ domain_group: zod.z.string().nullable().optional(),
5363
+ tax_year: zod.z.union([zod.z.string(), zod.z.number()]).nullable().optional(),
5364
+ crumbs: zod.z.array(zod.z.string()).optional(),
5365
+ tags: zod.z.array(zod.z.string()).optional(),
5366
+ stats: zod.z.array(summaryStatSchema).optional(),
5367
+ facts: zod.z.array(summaryFactSchema).optional()
5368
+ });
5369
+ var documentFieldExtractionSchema = zod.z.object({
5370
+ type: zod.z.literal("document-field-extraction"),
5371
+ doc_type: zod.z.string().optional(),
5372
+ // Original uploaded filename (e.g. "2024_gl.pdf"); preferred over doc_type for
5373
+ // the card title since doc_type is often the "generic_fallback" schema name.
5374
+ file_name: zod.z.string().optional(),
5375
+ // Server-side token; resolved by the host into pages/fields before render.
5376
+ payload_ref: zod.z.string().optional(),
5377
+ // Present for persisted workstream docs; absent for pre-existing cards.
5378
+ store_id: zod.z.string().optional(),
5379
+ doc_id: zod.z.string().optional(),
5380
+ pages: zod.z.array(pageSchema).max(100).optional(),
5381
+ fields: zod.z.array(fieldSchema).max(1e3).optional(),
5382
+ // Page-count metadata for the Details tab ("N of M pages extracted").
5383
+ page_count: zod.z.number().optional(),
5384
+ pages_processed: zod.z.number().optional(),
5385
+ // Deterministic document summary for the Details tab.
5386
+ summary: summarySchema.nullable().optional()
5387
+ });
5388
+ var documentFieldExtractionTool = {
5389
+ name: "render_document_field_extraction",
5390
+ description: "Render extracted document fields as an interactive overlay on the page image(s) \u2014 colored bounding boxes per field plus a synced field-card list. Use after the extract_document tool returns; pass the returned payload_ref (the host expands it). For invoices, statements, tax forms, receipts, KYC/loan docs, POs where the user wants to SEE where each value sits on the page.",
5391
+ input_schema: {
5392
+ type: "object",
5393
+ properties: {
5394
+ type: { type: "string", enum: ["document-field-extraction"] },
5395
+ doc_type: { type: "string" },
5396
+ file_name: {
5397
+ type: "string",
5398
+ description: "Original uploaded filename; shown as the card title."
5399
+ },
5400
+ payload_ref: {
5401
+ type: "string",
5402
+ description: "Durable store key returned by extract_document; the GenUI host expands it into pages/fields at render time. Pass this verbatim \u2014 do NOT hand-build pages/fields."
5403
+ },
5404
+ store_id: {
5405
+ type: "string",
5406
+ description: "Docstore store id; present for persisted workstream docs. The host uses this to open the editable viewer."
5407
+ },
5408
+ doc_id: {
5409
+ type: "string",
5410
+ description: "Docstore document id; present for persisted workstream docs. Required for the editable viewer."
5411
+ },
5412
+ pages: {
5413
+ type: "array",
5414
+ items: {
5415
+ type: "object",
5416
+ properties: {
5417
+ page: { type: "number", description: "0-indexed page number" },
5418
+ imageUrl: { type: "string" },
5419
+ width_pt: { type: "number" },
5420
+ height_pt: { type: "number" }
5421
+ },
5422
+ required: ["page", "width_pt", "height_pt"]
5423
+ }
5424
+ },
5425
+ fields: {
5426
+ type: "array",
5427
+ items: {
5428
+ type: "object",
5429
+ properties: {
5430
+ field_key: { type: "string" },
5431
+ label: { type: "string" },
5432
+ value: { type: "string" },
5433
+ page: { type: "number", description: "0-indexed page number" },
5434
+ bbox: {
5435
+ type: "array",
5436
+ items: { type: "number" },
5437
+ description: "[x0,y0,x1,y1] PDF points, origin bottom-left; null if unlocated"
5438
+ },
5439
+ confidence: { type: "number" },
5440
+ confidence_tier: { type: "string", enum: ["green", "amber", "red"] },
5441
+ badge: { type: "string", enum: ["SC", "CN", "AB", "SW"] },
5442
+ state: { type: "string", enum: ["ok", "corrected", "missing", "warn"] },
5443
+ entity_type: { type: "string" },
5444
+ is_primary: { type: "boolean" }
5445
+ },
5446
+ required: ["field_key", "label", "value", "page"]
5447
+ }
5448
+ },
5449
+ page_count: { type: "number" },
5450
+ pages_processed: { type: "number" },
5451
+ summary: {
5452
+ type: "object",
5453
+ description: "Deterministic document summary for the Details tab (display_name, organization, domain, stats, facts, tags). Produced by the extractor \u2014 pass through verbatim.",
5454
+ properties: {
5455
+ display_name: { type: "string" },
5456
+ short_name: { type: "string" },
5457
+ organization: { type: "string" },
5458
+ domain: { type: "string" },
5459
+ domain_group: { type: "string" },
5460
+ tax_year: { type: "string" },
5461
+ crumbs: { type: "array", items: { type: "string" } },
5462
+ tags: { type: "array", items: { type: "string" } },
5463
+ stats: {
5464
+ type: "array",
5465
+ items: {
5466
+ type: "object",
5467
+ properties: {
5468
+ field_key: { type: "string" },
5469
+ label: { type: "string" },
5470
+ value: { type: "string" },
5471
+ caption: { type: "string" }
5472
+ },
5473
+ required: ["field_key", "label", "value"]
5474
+ }
5475
+ },
5476
+ facts: {
5477
+ type: "array",
5478
+ items: {
5479
+ type: "object",
5480
+ properties: {
5481
+ field_key: { type: "string" },
5482
+ label: { type: "string" },
5483
+ value: { type: "string" },
5484
+ badge: { type: "string" }
5485
+ },
5486
+ required: ["field_key", "label", "value"]
5487
+ }
5488
+ }
5489
+ }
5490
+ }
5491
+ },
5492
+ required: ["type"]
5493
+ }
5494
+ };
5495
+ var decisionCardSchema = zod.z.object({
5496
+ type: zod.z.literal("decision-card"),
5497
+ id: zod.z.string().optional(),
5498
+ decision_type: zod.z.string().optional(),
5499
+ title: zod.z.string(),
5500
+ question: zod.z.string(),
5501
+ amount: zod.z.number().optional(),
5502
+ currency: zod.z.string().optional(),
5503
+ amount_label: zod.z.string().optional(),
5504
+ severity: zod.z.enum(["low", "medium", "high"]).optional(),
5505
+ flags: zod.z.array(
5506
+ zod.z.object({
5507
+ field: zod.z.string().optional(),
5508
+ issue: zod.z.string(),
5509
+ severity: zod.z.enum(["low", "medium", "high"]).optional()
5510
+ })
5511
+ ).max(6).optional(),
5512
+ options: zod.z.array(
5513
+ zod.z.object({
5514
+ id: zod.z.string().optional(),
5515
+ label: zod.z.string(),
5516
+ recommended: zod.z.boolean().optional()
5517
+ })
5518
+ ).min(1).max(5),
5519
+ source: zod.z.object({
5520
+ label: zod.z.string().optional(),
5521
+ url: zod.z.string().optional()
5522
+ }).optional(),
5523
+ resolved: zod.z.object({
5524
+ option: zod.z.string()
5525
+ }).optional()
5526
+ });
5527
+ var decisionCardTool = {
5528
+ name: "render_decision_card",
5529
+ description: "Render an inline human-in-the-loop (HITL) decision card \u2014 a single judgment the agent needs from the user, resolved in-thread. Shows a titled question with an optional dollar amount at stake, optional data-quality flags, and 2-5 mutually-exclusive resolution options (the first or `recommended` one renders as the primary action), plus an optional 'view source' link. Use for inline approve/choose decisions the user resolves directly in the conversation. NOT for handing off to an external review portal (use escalation-card) and NOT for collecting multiple typed fields (use render_builder).",
5530
+ input_schema: {
5531
+ type: "object",
5532
+ properties: {
5533
+ type: { type: "string", enum: ["decision-card"] },
5534
+ id: { type: "string", description: "Stable id for update-in-place rendering" },
5535
+ decision_type: {
5536
+ type: "string",
5537
+ description: "Short category shown in the eyebrow, e.g. 'Cross-check', 'Allocation', 'Reserve'"
5538
+ },
5539
+ title: { type: "string", description: "The decision headline, e.g. 'AR reserve adequacy'" },
5540
+ question: { type: "string", description: "The full question / context the user must judge" },
5541
+ amount: { type: "number", description: "Dollar value at stake, e.g. 27100" },
5542
+ currency: { type: "string", description: "ISO currency code; defaults to USD" },
5543
+ amount_label: { type: "string", description: "Caption above the amount, e.g. 'At stake'" },
5544
+ severity: {
5545
+ type: "string",
5546
+ enum: ["low", "medium", "high"],
5547
+ description: "Severity of the decision; tints the accent rail"
5548
+ },
5549
+ flags: {
5550
+ type: "array",
5551
+ maxItems: 6,
5552
+ description: "Optional data-quality flags surfaced on the card",
5553
+ items: {
5554
+ type: "object",
5555
+ properties: {
5556
+ field: { type: "string" },
5557
+ issue: { type: "string" },
5558
+ severity: { type: "string", enum: ["low", "medium", "high"] }
5559
+ },
5560
+ required: ["issue"]
5561
+ }
5562
+ },
5563
+ options: {
5564
+ type: "array",
5565
+ minItems: 1,
5566
+ maxItems: 5,
5567
+ description: "Mutually-exclusive resolution choices; mark one `recommended` to make it primary",
5568
+ items: {
5569
+ type: "object",
5570
+ properties: {
5571
+ id: { type: "string" },
5572
+ label: { type: "string" },
5573
+ recommended: { type: "boolean" }
5574
+ },
5575
+ required: ["label"]
5576
+ }
5577
+ },
5578
+ source: {
5579
+ type: "object",
5580
+ description: "Optional provenance link for the figure",
5581
+ properties: {
5582
+ label: { type: "string" },
5583
+ url: { type: "string" }
5584
+ }
5585
+ },
5586
+ resolved: {
5587
+ type: "object",
5588
+ description: "Pre-resolved state for transcript replay",
5589
+ properties: {
5590
+ option: { type: "string" }
5591
+ },
5592
+ required: ["option"]
5593
+ }
5594
+ },
5595
+ required: ["type", "title", "question", "options"]
5596
+ }
5597
+ };
5318
5598
 
5319
5599
  // src/schemas/buildRenderUITool.ts
5320
5600
  function buildRenderUITool(selectedSchemas) {
@@ -5433,7 +5713,9 @@ var schemaRegistry = {
5433
5713
  "connect-integration": { schema: connectIntegrationSchema, tool: connectIntegrationTool },
5434
5714
  "integrations-list": { schema: integrationsListSchema, tool: integrationsListTool },
5435
5715
  "pipeline-preview": { schema: pipelinePreviewSchema, tool: pipelinePreviewTool },
5436
- "workflow-stepper": { schema: workflowStepperSchema, tool: workflowStepperTool }
5716
+ "workflow-stepper": { schema: workflowStepperSchema, tool: workflowStepperTool },
5717
+ "document-field-extraction": { schema: documentFieldExtractionSchema, tool: documentFieldExtractionTool },
5718
+ "decision-card": { schema: decisionCardSchema, tool: decisionCardTool }
5437
5719
  };
5438
5720
 
5439
5721
  // src/shared/ColumnSettingsPanel.tsx
@@ -5485,16 +5767,16 @@ init_theme();
5485
5767
  var DOT_COLOR = "#aaaaaa";
5486
5768
  var DOT_HOVER = "#555555";
5487
5769
  function ComponentActions({ children, onDownloadCSV, columnConfig, filename = "component" }) {
5488
- const [open, setOpen] = React41.useState(false);
5489
- const [view, setView] = React41.useState("main");
5490
- const contentRef = React41.useRef(null);
5491
- const menuRef = React41.useRef(null);
5492
- const btnRef = React41.useRef(null);
5493
- const close = React41.useCallback(() => {
5770
+ const [open, setOpen] = React45.useState(false);
5771
+ const [view, setView] = React45.useState("main");
5772
+ const contentRef = React45.useRef(null);
5773
+ const menuRef = React45.useRef(null);
5774
+ const btnRef = React45.useRef(null);
5775
+ const close = React45.useCallback(() => {
5494
5776
  setOpen(false);
5495
5777
  setView("main");
5496
5778
  }, []);
5497
- React41.useEffect(() => {
5779
+ React45.useEffect(() => {
5498
5780
  if (!open) return;
5499
5781
  const handler = (e) => {
5500
5782
  var _a2, _b;
@@ -5505,7 +5787,7 @@ function ComponentActions({ children, onDownloadCSV, columnConfig, filename = "c
5505
5787
  document.addEventListener("mousedown", handler);
5506
5788
  return () => document.removeEventListener("mousedown", handler);
5507
5789
  }, [open, close]);
5508
- const handleDownloadPNG = React41.useCallback(async () => {
5790
+ const handleDownloadPNG = React45.useCallback(async () => {
5509
5791
  if (!contentRef.current) return;
5510
5792
  try {
5511
5793
  const url = await htmlToImage.toPng(contentRef.current, { backgroundColor: "white", pixelRatio: 2 });
@@ -5517,7 +5799,7 @@ function ComponentActions({ children, onDownloadCSV, columnConfig, filename = "c
5517
5799
  }
5518
5800
  close();
5519
5801
  }, [filename, close]);
5520
- const handleCSV = React41.useCallback(() => {
5802
+ const handleCSV = React45.useCallback(() => {
5521
5803
  onDownloadCSV == null ? void 0 : onDownloadCSV();
5522
5804
  close();
5523
5805
  }, [onDownloadCSV, close]);
@@ -5629,12 +5911,12 @@ function MenuButton({ label, onClick }) {
5629
5911
  );
5630
5912
  }
5631
5913
  function useColumnVisibility(columns) {
5632
- const [hidden, setHidden] = React41.useState(/* @__PURE__ */ new Set());
5633
- const visibleColumns = React41.useMemo(
5914
+ const [hidden, setHidden] = React45.useState(/* @__PURE__ */ new Set());
5915
+ const visibleColumns = React45.useMemo(
5634
5916
  () => columns.filter((c) => !hidden.has(c.key)),
5635
5917
  [columns, hidden]
5636
5918
  );
5637
- const toggle = React41.useCallback((key) => {
5919
+ const toggle = React45.useCallback((key) => {
5638
5920
  setHidden((prev) => {
5639
5921
  const next = new Set(prev);
5640
5922
  if (next.has(key)) next.delete(key);
@@ -5642,8 +5924,8 @@ function useColumnVisibility(columns) {
5642
5924
  return next;
5643
5925
  });
5644
5926
  }, []);
5645
- const showAll = React41.useCallback(() => setHidden(/* @__PURE__ */ new Set()), []);
5646
- const hideAll = React41.useCallback(
5927
+ const showAll = React45.useCallback(() => setHidden(/* @__PURE__ */ new Set()), []);
5928
+ const hideAll = React45.useCallback(
5647
5929
  () => setHidden(new Set(columns.map((c) => c.key))),
5648
5930
  [columns]
5649
5931
  );
@@ -5894,9 +6176,9 @@ function AlertResolver(p) {
5894
6176
  // src/composites/stat-grid/resolver.tsx
5895
6177
  init_Markdown();
5896
6178
  function FitText({ children, max = 22, min = 13, title, className, style }) {
5897
- const ref = React41.useRef(null);
5898
- const [size, setSize] = React41.useState(max);
5899
- React41.useLayoutEffect(() => {
6179
+ const ref = React45.useRef(null);
6180
+ const [size, setSize] = React45.useState(max);
6181
+ React45.useLayoutEffect(() => {
5900
6182
  const el = ref.current;
5901
6183
  if (!el) return void 0;
5902
6184
  const fit = () => {
@@ -5988,7 +6270,7 @@ init_ThemeContext();
5988
6270
  function TabsPanelResolver(p) {
5989
6271
  var _a2;
5990
6272
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, ACCENT: ACCENT2 } = useTheme();
5991
- const [activeIdx, setActiveIdx] = React41.useState(0);
6273
+ const [activeIdx, setActiveIdx] = React45.useState(0);
5992
6274
  const activeTab = p.tabs[activeIdx];
5993
6275
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: "tabs-panel", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "0" }, children: [
5994
6276
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -6146,17 +6428,17 @@ function SparklineTableResolver(p) {
6146
6428
  // src/composites/heatmap-table/resolver.tsx
6147
6429
  init_theme();
6148
6430
  init_ThemeContext();
6149
- function heatColor(z59) {
6150
- const clamped = Math.max(-3, Math.min(3, z59));
6431
+ function heatColor(z61) {
6432
+ const clamped = Math.max(-3, Math.min(3, z61));
6151
6433
  const abs = Math.abs(clamped);
6152
6434
  const lightness = 95 - abs * 8;
6153
6435
  const hue = clamped >= 0 ? 142 : 0;
6154
6436
  return `hsl(${hue} 60% ${lightness}%)`;
6155
6437
  }
6156
- function heatTextColor(z59) {
6157
- const abs = Math.abs(z59);
6158
- if (abs > 2) return z59 >= 0 ? "#14532d" : "#7f1d1d";
6159
- if (abs > 1) return z59 >= 0 ? "#166534" : "#991b1b";
6438
+ function heatTextColor(z61) {
6439
+ const abs = Math.abs(z61);
6440
+ if (abs > 2) return z61 >= 0 ? "#14532d" : "#7f1d1d";
6441
+ if (abs > 1) return z61 >= 0 ? "#166534" : "#991b1b";
6160
6442
  return "var(--foreground)";
6161
6443
  }
6162
6444
  var th2 = {
@@ -6254,7 +6536,7 @@ var thStyle2 = {
6254
6536
  function ScreenerTableResolver(p) {
6255
6537
  var _a2, _b, _c, _d, _e, _f;
6256
6538
  const { ACCENT: ACCENT2, BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2 } = useTheme();
6257
- const [activeFilters, setActiveFilters] = React41.useState(new Set((_a2 = p.activeFilters) != null ? _a2 : []));
6539
+ const [activeFilters, setActiveFilters] = React45.useState(new Set((_a2 = p.activeFilters) != null ? _a2 : []));
6258
6540
  const { visibleColumns, hidden, toggle, showAll, hideAll, allColumns } = useColumnVisibility((_b = p.columns) != null ? _b : []);
6259
6541
  const toggleFilter = (f) => setActiveFilters((prev) => {
6260
6542
  const next = new Set(prev);
@@ -6324,7 +6606,7 @@ var th3 = {
6324
6606
  };
6325
6607
  function GroupRows({ group, columns, depth }) {
6326
6608
  var _a2, _b;
6327
- const [open, setOpen] = React41.useState(true);
6609
+ const [open, setOpen] = React45.useState(true);
6328
6610
  const indent = depth * 14;
6329
6611
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6330
6612
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -6429,7 +6711,7 @@ var dotColor = {
6429
6711
  function NewsFeedResolver(p) {
6430
6712
  var _a2, _b;
6431
6713
  const { ACCENT: ACCENT2, MUTED: MUTED2 } = useTheme();
6432
- const [filter, setFilter] = React41.useState(null);
6714
+ const [filter, setFilter] = React45.useState(null);
6433
6715
  const sentiments = ["positive", "neutral", "negative"].filter(
6434
6716
  (s) => {
6435
6717
  var _a3;
@@ -6471,9 +6753,9 @@ function NewsFeedResolver(p) {
6471
6753
  ] }) });
6472
6754
  }
6473
6755
  function useSeriesToggle(seriesKeys) {
6474
- const [hidden, setHidden] = React41.useState(/* @__PURE__ */ new Set());
6475
- const isVisible = React41.useCallback((key) => !hidden.has(key), [hidden]);
6476
- const toggle = React41.useCallback((key) => {
6756
+ const [hidden, setHidden] = React45.useState(/* @__PURE__ */ new Set());
6757
+ const isVisible = React45.useCallback((key) => !hidden.has(key), [hidden]);
6758
+ const toggle = React45.useCallback((key) => {
6477
6759
  setHidden((prev) => {
6478
6760
  const next = new Set(prev);
6479
6761
  if (next.has(key)) next.delete(key);
@@ -6481,7 +6763,7 @@ function useSeriesToggle(seriesKeys) {
6481
6763
  return next;
6482
6764
  });
6483
6765
  }, []);
6484
- const showAll = React41.useCallback(() => setHidden(/* @__PURE__ */ new Set()), []);
6766
+ const showAll = React45.useCallback(() => setHidden(/* @__PURE__ */ new Set()), []);
6485
6767
  return { hidden, isVisible, toggle, showAll, allKeys: seriesKeys };
6486
6768
  }
6487
6769
 
@@ -6790,7 +7072,7 @@ function WaterfallChartResolver(p) {
6790
7072
  ] }) });
6791
7073
  }
6792
7074
  init_ThemeContext();
6793
- var FlowGraph2 = React41__default.default.lazy(
7075
+ var FlowGraph2 = React45__default.default.lazy(
6794
7076
  () => Promise.resolve().then(() => (init_FlowGraph(), FlowGraph_exports)).then((m) => ({ default: m.FlowGraph }))
6795
7077
  );
6796
7078
  function FlowCanvasRenderer({
@@ -6831,7 +7113,7 @@ function FlowCanvasRenderer({
6831
7113
  overflow: "hidden",
6832
7114
  background: "#ffffff",
6833
7115
  position: "relative"
6834
- }, diagram ? {} : { height: "320px" }), children: diagram ? /* @__PURE__ */ jsxRuntime.jsx(React41.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(FlowGraph2, { diagram, title, autoplay, nodeStates }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
7116
+ }, diagram ? {} : { height: "320px" }), children: diagram ? /* @__PURE__ */ jsxRuntime.jsx(React45.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(FlowGraph2, { diagram, title, autoplay, nodeStates }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
6835
7117
  position: "absolute",
6836
7118
  inset: 0,
6837
7119
  display: "flex",
@@ -7064,7 +7346,7 @@ function TrialBalanceResolver(p) {
7064
7346
  gDebit += a.debit;
7065
7347
  gCredit += a.credit;
7066
7348
  });
7067
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
7349
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
7068
7350
  /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: 4, style: {
7069
7351
  padding: "8px 12px",
7070
7352
  fontSize: "12px",
@@ -7601,7 +7883,7 @@ function ItemRow({ item }) {
7601
7883
  ] });
7602
7884
  }
7603
7885
  function Section({ section }) {
7604
- const [open, setOpen] = React41.useState(true);
7886
+ const [open, setOpen] = React45.useState(true);
7605
7887
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7606
7888
  /* @__PURE__ */ jsxRuntime.jsxs(
7607
7889
  "button",
@@ -7723,7 +8005,7 @@ function ReconciliationViewResolver(p) {
7723
8005
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, ACCENT: ACCENT2 } = useTheme();
7724
8006
  const sourceA = (_a2 = p.sourceA) != null ? _a2 : { label: "Source A" };
7725
8007
  const sourceB = (_b = p.sourceB) != null ? _b : { label: "Source B" };
7726
- const [activeTab, setActiveTab] = React41.useState("matched");
8008
+ const [activeTab, setActiveTab] = React45.useState("matched");
7727
8009
  const balanceA = (_d = (_c = p.summary) == null ? void 0 : _c.balanceA) != null ? _d : 0;
7728
8010
  const balanceB = (_f = (_e = p.summary) == null ? void 0 : _e.balanceB) != null ? _f : 0;
7729
8011
  const difference = (_h = (_g = p.summary) == null ? void 0 : _g.difference) != null ? _h : balanceA - balanceB;
@@ -8366,7 +8648,7 @@ function ChangesView({ changes }) {
8366
8648
  }
8367
8649
  function EventCard({ event }) {
8368
8650
  var _a2;
8369
- const [showChanges, setShowChanges] = React41.useState(false);
8651
+ const [showChanges, setShowChanges] = React45.useState(false);
8370
8652
  const ac = (_a2 = actionConfig[event.action]) != null ? _a2 : actionConfig.commented;
8371
8653
  const hasChanges = event.changes && event.changes.length > 0;
8372
8654
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "12px", position: "relative" }, children: [
@@ -8424,23 +8706,23 @@ function AuditTrailResolver(p) {
8424
8706
  }
8425
8707
  init_Markdown();
8426
8708
  function useFullscreen(ref) {
8427
- const [isFullscreen, setIsFullscreen] = React41.useState(false);
8428
- React41.useEffect(() => {
8709
+ const [isFullscreen, setIsFullscreen] = React45.useState(false);
8710
+ React45.useEffect(() => {
8429
8711
  const handler = () => {
8430
8712
  setIsFullscreen(!!document.fullscreenElement);
8431
8713
  };
8432
8714
  document.addEventListener("fullscreenchange", handler);
8433
8715
  return () => document.removeEventListener("fullscreenchange", handler);
8434
8716
  }, []);
8435
- const enter = React41.useCallback(() => {
8717
+ const enter = React45.useCallback(() => {
8436
8718
  var _a2, _b;
8437
8719
  (_b = (_a2 = ref.current) == null ? void 0 : _a2.requestFullscreen) == null ? void 0 : _b.call(_a2);
8438
8720
  }, [ref]);
8439
- const exit = React41.useCallback(() => {
8721
+ const exit = React45.useCallback(() => {
8440
8722
  var _a2;
8441
8723
  if (document.fullscreenElement) (_a2 = document.exitFullscreen) == null ? void 0 : _a2.call(document);
8442
8724
  }, []);
8443
- const toggle = React41.useCallback(() => {
8725
+ const toggle = React45.useCallback(() => {
8444
8726
  if (isFullscreen) exit();
8445
8727
  else enter();
8446
8728
  }, [isFullscreen, enter, exit]);
@@ -8450,10 +8732,10 @@ function useFullscreen(ref) {
8450
8732
  // src/composites/document-preview/resolver.tsx
8451
8733
  init_theme();
8452
8734
  init_ThemeContext();
8453
- var PdfViewer2 = React41__default.default.lazy(
8735
+ var PdfViewer2 = React45__default.default.lazy(
8454
8736
  () => Promise.resolve().then(() => (init_PdfViewer(), PdfViewer_exports)).then((m) => ({ default: m.PdfViewer }))
8455
8737
  );
8456
- var ExcelViewer2 = React41__default.default.lazy(
8738
+ var ExcelViewer2 = React45__default.default.lazy(
8457
8739
  () => Promise.resolve().then(() => (init_ExcelViewer(), ExcelViewer_exports)).then((m) => ({ default: m.ExcelViewer }))
8458
8740
  );
8459
8741
  var highlightColors = {
@@ -8503,8 +8785,8 @@ function DownloadIcon() {
8503
8785
  function DocumentPreviewResolver(p) {
8504
8786
  var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
8505
8787
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, ACCENT: ACCENT2 } = useTheme();
8506
- const [currentPage, setCurrentPage] = React41.useState(0);
8507
- const containerRef = React41.useRef(null);
8788
+ const [currentPage, setCurrentPage] = React45.useState(0);
8789
+ const containerRef = React45.useRef(null);
8508
8790
  const { isFullscreen, toggle } = useFullscreen(containerRef);
8509
8791
  const hasRealFile = !!(((_a2 = p.source) == null ? void 0 : _a2.url) || ((_b = p.source) == null ? void 0 : _b.base64));
8510
8792
  const isPdf = p.documentType === "pdf";
@@ -8512,9 +8794,9 @@ function DocumentPreviewResolver(p) {
8512
8794
  const totalPages = ((_c = p.pages) != null ? _c : []).length;
8513
8795
  const page = p.pages[currentPage];
8514
8796
  const pageHighlights = ((_d = p.highlights) != null ? _d : []).filter((h) => h.pageIndex === currentPage);
8515
- const handlePdfLoad = React41.useCallback(() => {
8797
+ const handlePdfLoad = React45.useCallback(() => {
8516
8798
  }, []);
8517
- const handleExcelLoad = React41.useCallback(() => {
8799
+ const handleExcelLoad = React45.useCallback(() => {
8518
8800
  }, []);
8519
8801
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_e = p.title) != null ? _e : "document-preview", children: /* @__PURE__ */ jsxRuntime.jsxs(
8520
8802
  "div",
@@ -8627,7 +8909,7 @@ function DocumentPreviewResolver(p) {
8627
8909
  display: "flex",
8628
8910
  flexDirection: "column"
8629
8911
  }, children: [
8630
- hasRealFile && isPdf ? /* @__PURE__ */ jsxRuntime.jsx(React41.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(PdfViewer2, { url: (_q = p.source) == null ? void 0 : _q.url, base64: (_r = p.source) == null ? void 0 : _r.base64, onLoadSuccess: handlePdfLoad }) }) : hasRealFile && isExcel ? /* @__PURE__ */ jsxRuntime.jsx(React41.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(ExcelViewer2, { url: (_s = p.source) == null ? void 0 : _s.url, base64: (_t = p.source) == null ? void 0 : _t.base64, onLoadSuccess: handleExcelLoad }) }) : (page == null ? void 0 : page.imageUrl) ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "20px" }, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: page.imageUrl, alt: page.label, style: { maxWidth: "100%", borderRadius: "4px" } }) }) : (page == null ? void 0 : page.content) ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontFamily: "var(--font-sans, system-ui)", fontSize: "13px", color: "var(--foreground)", lineHeight: 1.6, margin: 0, padding: "20px" }, children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { content: page.content }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "120px", color: MUTED2, fontSize: "13px" }, children: [
8912
+ hasRealFile && isPdf ? /* @__PURE__ */ jsxRuntime.jsx(React45.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(PdfViewer2, { url: (_q = p.source) == null ? void 0 : _q.url, base64: (_r = p.source) == null ? void 0 : _r.base64, onLoadSuccess: handlePdfLoad }) }) : hasRealFile && isExcel ? /* @__PURE__ */ jsxRuntime.jsx(React45.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(ExcelViewer2, { url: (_s = p.source) == null ? void 0 : _s.url, base64: (_t = p.source) == null ? void 0 : _t.base64, onLoadSuccess: handleExcelLoad }) }) : (page == null ? void 0 : page.imageUrl) ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "20px" }, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: page.imageUrl, alt: page.label, style: { maxWidth: "100%", borderRadius: "4px" } }) }) : (page == null ? void 0 : page.content) ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontFamily: "var(--font-sans, system-ui)", fontSize: "13px", color: "var(--foreground)", lineHeight: 1.6, margin: 0, padding: "20px" }, children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { content: page.content }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "120px", color: MUTED2, fontSize: "13px" }, children: [
8631
8913
  "No content available for ",
8632
8914
  (_u = page == null ? void 0 : page.label) != null ? _u : "this page"
8633
8915
  ] }),
@@ -8690,7 +8972,7 @@ function ConfidenceBar({ confidence, height = 6 }) {
8690
8972
  }
8691
8973
  function StepCard({ step, isLast }) {
8692
8974
  var _a2;
8693
- const [expanded, setExpanded] = React41.useState(false);
8975
+ const [expanded, setExpanded] = React45.useState(false);
8694
8976
  const cfg = stepTypeConfig[step.stepType];
8695
8977
  const detail = (_a2 = step.detail) != null ? _a2 : "";
8696
8978
  const isLong = detail.length > 100;
@@ -9195,7 +9477,7 @@ function ExampleRow({ example }) {
9195
9477
  );
9196
9478
  }
9197
9479
  function PartSection({ part, defaultOpen }) {
9198
- const [open, setOpen] = React41.useState(defaultOpen);
9480
+ const [open, setOpen] = React45.useState(defaultOpen);
9199
9481
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9200
9482
  /* @__PURE__ */ jsxRuntime.jsxs(
9201
9483
  "button",
@@ -9325,7 +9607,7 @@ function EngagementPipelineResolver(p) {
9325
9607
  const defaultActive = phases.findIndex(
9326
9608
  (ph) => ph.status === "in-progress" || ph.status === "blocked"
9327
9609
  );
9328
- const [activeIdx, setActiveIdx] = React41.useState(defaultActive >= 0 ? defaultActive : 0);
9610
+ const [activeIdx, setActiveIdx] = React45.useState(defaultActive >= 0 ? defaultActive : 0);
9329
9611
  const activePhase = phases[activeIdx];
9330
9612
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_b = p.title) != null ? _b : "engagement-pipeline", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "12px" }, children: [
9331
9613
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
@@ -9409,7 +9691,7 @@ function EngagementPipelineResolver(p) {
9409
9691
  const color = (_a3 = statusColor2[phase.status]) != null ? _a3 : "#d6d3d1";
9410
9692
  const isCurrent = i === activeIdx;
9411
9693
  const size = isCurrent ? 28 : 20;
9412
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
9694
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
9413
9695
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(
9414
9696
  "div",
9415
9697
  {
@@ -9716,7 +9998,7 @@ function Avatar({ name, avatar, hovered }) {
9716
9998
  function EntityCardGridResolver(p) {
9717
9999
  var _a2, _b;
9718
10000
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2 } = useTheme();
9719
- const [hoveredId, setHoveredId] = React41.useState(null);
10001
+ const [hoveredId, setHoveredId] = React45.useState(null);
9720
10002
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_a2 = p.title) != null ? _a2 : "entity-card-grid", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "10px" }, children: [
9721
10003
  p.title && /* @__PURE__ */ jsxRuntime.jsx(
9722
10004
  "p",
@@ -9972,7 +10254,7 @@ function StepRow({ step }) {
9972
10254
  function JobTrackerResolver(p) {
9973
10255
  var _a2, _b, _c, _d, _e, _f, _g;
9974
10256
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, PAPER: PAPER2 } = useTheme();
9975
- const [stepsOpen, setStepsOpen] = React41.useState(true);
10257
+ const [stepsOpen, setStepsOpen] = React45.useState(true);
9976
10258
  const barColor = (_a2 = statusColors2[p.status]) != null ? _a2 : MUTED2;
9977
10259
  const badge = (_b = statusBadgeConfig[p.status]) != null ? _b : statusBadgeConfig.queued;
9978
10260
  const progress = (_c = p.progress) != null ? _c : p.status === "completed" ? 100 : 0;
@@ -10412,7 +10694,7 @@ function CitationCard({
10412
10694
  );
10413
10695
  }
10414
10696
  function FollowUpItem({ text }) {
10415
- const [hovered, setHovered] = React41.useState(false);
10697
+ const [hovered, setHovered] = React45.useState(false);
10416
10698
  return /* @__PURE__ */ jsxRuntime.jsxs(
10417
10699
  "span",
10418
10700
  {
@@ -10437,7 +10719,7 @@ function CitationMarker({
10437
10719
  index,
10438
10720
  onClick
10439
10721
  }) {
10440
- const [hovered, setHovered] = React41.useState(false);
10722
+ const [hovered, setHovered] = React45.useState(false);
10441
10723
  return /* @__PURE__ */ jsxRuntime.jsx(
10442
10724
  "sup",
10443
10725
  {
@@ -10466,7 +10748,7 @@ function CitationMarker({
10466
10748
  function CitedAnswerResolver(p) {
10467
10749
  var _a2, _b, _c, _d, _e;
10468
10750
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, SECONDARY: SECONDARY2 } = useTheme();
10469
- const [expandedIds, setExpandedIds] = React41.useState(/* @__PURE__ */ new Set());
10751
+ const [expandedIds, setExpandedIds] = React45.useState(/* @__PURE__ */ new Set());
10470
10752
  const toggleCitation = (id) => {
10471
10753
  setExpandedIds((prev) => {
10472
10754
  const next = new Set(prev);
@@ -10770,7 +11052,7 @@ function TransactionFeedResolver(p) {
10770
11052
  var _a2, _b, _c, _d, _e;
10771
11053
  const { BORDER: BORDER4, MUTED: MUTED2 } = useTheme();
10772
11054
  const currency = (_a2 = p.currency) != null ? _a2 : "USD";
10773
- const [hoveredIndex, setHoveredIndex] = React41.useState(null);
11055
+ const [hoveredIndex, setHoveredIndex] = React45.useState(null);
10774
11056
  const hasBalance = ((_b = p.transactions) != null ? _b : []).some((tx) => tx.balance != null);
10775
11057
  const totalInflows = p.transactions.filter((tx) => tx.amount > 0 && tx.status !== "reversed").reduce((sum, tx) => sum + tx.amount, 0);
10776
11058
  const totalOutflows = p.transactions.filter((tx) => tx.amount < 0 && tx.status !== "reversed").reduce((sum, tx) => sum + tx.amount, 0);
@@ -10927,7 +11209,7 @@ function formatDate2(dateStr) {
10927
11209
  }
10928
11210
  function FileRow({ item }) {
10929
11211
  var _a2;
10930
- const [hovered, setHovered] = React41.useState(false);
11212
+ const [hovered, setHovered] = React45.useState(false);
10931
11213
  const cfg = getDocConfig(item.docType);
10932
11214
  return /* @__PURE__ */ jsxRuntime.jsxs(
10933
11215
  "div",
@@ -11003,8 +11285,8 @@ function FileRow({ item }) {
11003
11285
  );
11004
11286
  }
11005
11287
  function GroupSection({ groupName, items }) {
11006
- const [open, setOpen] = React41.useState(true);
11007
- const [headerHovered, setHeaderHovered] = React41.useState(false);
11288
+ const [open, setOpen] = React45.useState(true);
11289
+ const [headerHovered, setHeaderHovered] = React45.useState(false);
11008
11290
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11009
11291
  /* @__PURE__ */ jsxRuntime.jsxs(
11010
11292
  "button",
@@ -11193,15 +11475,15 @@ function isExpirySoon(expiresAt) {
11193
11475
 
11194
11476
  // src/shared/viewers/PreviewHost.tsx
11195
11477
  init_ThemeContext();
11196
- var PdfViewer3 = React41.lazy(
11478
+ var PdfViewer3 = React45.lazy(
11197
11479
  () => Promise.resolve().then(() => (init_PdfViewer(), PdfViewer_exports)).then((m) => ({ default: m.PdfViewer }))
11198
11480
  );
11199
- var ExcelViewer3 = React41.lazy(
11481
+ var ExcelViewer3 = React45.lazy(
11200
11482
  () => Promise.resolve().then(() => (init_ExcelViewer(), ExcelViewer_exports)).then((m) => ({ default: m.ExcelViewer }))
11201
11483
  );
11202
- var CsvViewer2 = React41.lazy(() => Promise.resolve().then(() => (init_CsvViewer(), CsvViewer_exports)).then((m) => ({ default: m.CsvViewer })));
11203
- var TextViewer2 = React41.lazy(() => Promise.resolve().then(() => (init_TextViewer(), TextViewer_exports)).then((m) => ({ default: m.TextViewer })));
11204
- var DocxViewer2 = React41.lazy(() => Promise.resolve().then(() => (init_DocxViewer(), DocxViewer_exports)).then((m) => ({ default: m.DocxViewer })));
11484
+ var CsvViewer2 = React45.lazy(() => Promise.resolve().then(() => (init_CsvViewer(), CsvViewer_exports)).then((m) => ({ default: m.CsvViewer })));
11485
+ var TextViewer2 = React45.lazy(() => Promise.resolve().then(() => (init_TextViewer(), TextViewer_exports)).then((m) => ({ default: m.TextViewer })));
11486
+ var DocxViewer2 = React45.lazy(() => Promise.resolve().then(() => (init_DocxViewer(), DocxViewer_exports)).then((m) => ({ default: m.DocxViewer })));
11205
11487
  var PEEK_ROWS = 20;
11206
11488
  var PEEK_LINES = 40;
11207
11489
  function PreviewHost({ kind, source, mode = "full" }) {
@@ -11231,7 +11513,7 @@ function PreviewHost({ kind, source, mode = "full" }) {
11231
11513
  default:
11232
11514
  return null;
11233
11515
  }
11234
- return /* @__PURE__ */ jsxRuntime.jsx(React41.Suspense, { fallback, children: viewer });
11516
+ return /* @__PURE__ */ jsxRuntime.jsx(React45.Suspense, { fallback, children: viewer });
11235
11517
  }
11236
11518
 
11237
11519
  // src/shared/PreviewModal.tsx
@@ -11247,7 +11529,7 @@ function PreviewModal({
11247
11529
  onDownload
11248
11530
  }) {
11249
11531
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2 } = useTheme();
11250
- React41.useEffect(() => {
11532
+ React45.useEffect(() => {
11251
11533
  if (!open) return;
11252
11534
  const onKey = (e) => {
11253
11535
  if (e.key === "Escape") onClose();
@@ -11420,17 +11702,17 @@ function FileCard({
11420
11702
  previewDisabled = false
11421
11703
  }) {
11422
11704
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2 } = useTheme();
11423
- const [cardHover, setCardHover] = React41.useState(false);
11424
- const [btnHover, setBtnHover] = React41.useState(false);
11425
- const [pvHover, setPvHover] = React41.useState(false);
11705
+ const [cardHover, setCardHover] = React45.useState(false);
11706
+ const [btnHover, setBtnHover] = React45.useState(false);
11707
+ const [pvHover, setPvHover] = React45.useState(false);
11426
11708
  const previewKind = previewKindFor(fileType, filename);
11427
11709
  const canPreview = !previewDisabled && previewKind !== null && (!!previewUrl || !!fetchPreviewBlob);
11428
- const [peekOpen, setPeekOpen] = React41.useState(false);
11429
- const [modalOpen, setModalOpen] = React41.useState(false);
11430
- const [source, setSource] = React41.useState(previewUrl ? { url: previewUrl } : null);
11431
- const [pvLoading, setPvLoading] = React41.useState(false);
11432
- const [pvError, setPvError] = React41.useState(null);
11433
- const ensureSource = React41.useCallback(async () => {
11710
+ const [peekOpen, setPeekOpen] = React45.useState(false);
11711
+ const [modalOpen, setModalOpen] = React45.useState(false);
11712
+ const [source, setSource] = React45.useState(previewUrl ? { url: previewUrl } : null);
11713
+ const [pvLoading, setPvLoading] = React45.useState(false);
11714
+ const [pvError, setPvError] = React45.useState(null);
11715
+ const ensureSource = React45.useCallback(async () => {
11434
11716
  if (source) return source;
11435
11717
  if (previewUrl) {
11436
11718
  const s = { url: previewUrl };
@@ -11452,7 +11734,7 @@ function FileCard({
11452
11734
  setPvLoading(false);
11453
11735
  }
11454
11736
  }, [source, previewUrl, fetchPreviewBlob]);
11455
- const togglePeek = React41.useCallback(async () => {
11737
+ const togglePeek = React45.useCallback(async () => {
11456
11738
  if (peekOpen) {
11457
11739
  setPeekOpen(false);
11458
11740
  return;
@@ -11460,7 +11742,7 @@ function FileCard({
11460
11742
  setPeekOpen(true);
11461
11743
  await ensureSource();
11462
11744
  }, [peekOpen, ensureSource]);
11463
- const openModal = React41.useCallback(async () => {
11745
+ const openModal = React45.useCallback(async () => {
11464
11746
  const s = await ensureSource();
11465
11747
  if (s) setModalOpen(true);
11466
11748
  }, [ensureSource]);
@@ -11575,7 +11857,7 @@ function FileCard({
11575
11857
  whiteSpace: "nowrap"
11576
11858
  },
11577
11859
  children: [
11578
- metaTokens.map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
11860
+ metaTokens.map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
11579
11861
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#c4c4c4" }, children: "\xB7" }),
11580
11862
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: t })
11581
11863
  ] }, i)),
@@ -11919,7 +12201,7 @@ function ServiceCard({ item, isHovered, onHover, onLeave: onLeave2 }) {
11919
12201
  function OpsDashboardResolver(p) {
11920
12202
  var _a2, _b, _c;
11921
12203
  const { BORDER: BORDER4, MUTED: MUTED2 } = useTheme();
11922
- const [hoveredId, setHoveredId] = React41.useState(null);
12204
+ const [hoveredId, setHoveredId] = React45.useState(null);
11923
12205
  const hasRunning = ((_a2 = p.items) != null ? _a2 : []).some((item) => item.state === "running");
11924
12206
  return /* @__PURE__ */ jsxRuntime.jsxs(ComponentActions, { filename: (_b = p.title) != null ? _b : "ops-dashboard", children: [
11925
12207
  hasRunning && /* @__PURE__ */ jsxRuntime.jsx("style", { children: PULSE_KEYFRAMES }),
@@ -11972,8 +12254,8 @@ function formatDate3(value) {
11972
12254
  }
11973
12255
  }
11974
12256
  function CopyButton({ value, rowHovered }) {
11975
- const [copied, setCopied] = React41.useState(false);
11976
- const [btnHovered, setBtnHovered] = React41.useState(false);
12257
+ const [copied, setCopied] = React45.useState(false);
12258
+ const [btnHovered, setBtnHovered] = React45.useState(false);
11977
12259
  const handleCopy = () => {
11978
12260
  navigator.clipboard.writeText(value).then(() => {
11979
12261
  setCopied(true);
@@ -12065,7 +12347,7 @@ function ValueCell({ item }) {
12065
12347
  }
12066
12348
  }
12067
12349
  function KVRow({ item, isLast, index }) {
12068
- const [hovered, setHovered] = React41.useState(false);
12350
+ const [hovered, setHovered] = React45.useState(false);
12069
12351
  const altBg = index % 2 === 1 ? "#fcfcfc" : "white";
12070
12352
  return /* @__PURE__ */ jsxRuntime.jsxs(
12071
12353
  "div",
@@ -12150,7 +12432,7 @@ function KeyValueListResolver(p) {
12150
12432
  var _a4;
12151
12433
  return sum + ((_a4 = g.items) != null ? _a4 : []).length;
12152
12434
  }, 0);
12153
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12435
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12154
12436
  /* @__PURE__ */ jsxRuntime.jsxs(
12155
12437
  "div",
12156
12438
  {
@@ -12328,7 +12610,7 @@ function BalanceSheetResolver(p) {
12328
12610
  /* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
12329
12611
  ((_p = p.sections) != null ? _p : []).map((section) => {
12330
12612
  var _a3;
12331
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12613
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12332
12614
  /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan, style: {
12333
12615
  padding: "8px 12px",
12334
12616
  fontSize: "12px",
@@ -12341,7 +12623,7 @@ function BalanceSheetResolver(p) {
12341
12623
  }, children: (_a3 = categoryLabels2[section.category]) != null ? _a3 : section.category }) }),
12342
12624
  section.subsections.map((sub, si) => {
12343
12625
  var _a4;
12344
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12626
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12345
12627
  /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan, style: {
12346
12628
  padding: "6px 10px 6px 24px",
12347
12629
  fontSize: "12px",
@@ -12517,7 +12799,7 @@ function IncomeStatementResolver(p) {
12517
12799
  textAlign: "left",
12518
12800
  whiteSpace: "nowrap"
12519
12801
  }, children: "\xA0" }),
12520
- periods.map((period) => /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12802
+ periods.map((period) => /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12521
12803
  /* @__PURE__ */ jsxRuntime.jsx("th", { style: {
12522
12804
  fontSize: "11px",
12523
12805
  fontWeight: 500,
@@ -12548,7 +12830,7 @@ function IncomeStatementResolver(p) {
12548
12830
  sections.map((section, si) => {
12549
12831
  var _a3;
12550
12832
  const isSubtotal = section.sectionType === "subtotal";
12551
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12833
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12552
12834
  /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: colCount, style: {
12553
12835
  padding: "8px 12px",
12554
12836
  fontSize: "12px",
@@ -12579,7 +12861,7 @@ function IncomeStatementResolver(p) {
12579
12861
  var _a5;
12580
12862
  const val = (_a5 = amounts[pi]) != null ? _a5 : 0;
12581
12863
  const isNeg = val < 0;
12582
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12864
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12583
12865
  /* @__PURE__ */ jsxRuntime.jsx("td", { style: {
12584
12866
  padding: "6px 10px",
12585
12867
  fontSize: "13px",
@@ -12614,7 +12896,7 @@ function IncomeStatementResolver(p) {
12614
12896
  var _a3;
12615
12897
  const val = (_a3 = grossProfit[pi]) != null ? _a3 : 0;
12616
12898
  const isNeg = val < 0;
12617
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12899
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12618
12900
  /* @__PURE__ */ jsxRuntime.jsx("td", { style: {
12619
12901
  padding: "8px 10px",
12620
12902
  fontSize: "12px",
@@ -12649,7 +12931,7 @@ function IncomeStatementResolver(p) {
12649
12931
  var _a3;
12650
12932
  const val = (_a3 = operatingIncome[pi]) != null ? _a3 : 0;
12651
12933
  const isNeg = val < 0;
12652
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12934
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12653
12935
  /* @__PURE__ */ jsxRuntime.jsx("td", { style: {
12654
12936
  padding: "8px 10px",
12655
12937
  fontSize: "12px",
@@ -12683,7 +12965,7 @@ function IncomeStatementResolver(p) {
12683
12965
  var _a3;
12684
12966
  const val = (_a3 = netIncome[pi]) != null ? _a3 : 0;
12685
12967
  const isNeg = val < 0;
12686
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12968
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12687
12969
  /* @__PURE__ */ jsxRuntime.jsx("td", { style: {
12688
12970
  padding: "10px 10px",
12689
12971
  fontSize: "13px",
@@ -12903,7 +13185,7 @@ function CashFlowStatementResolver(p) {
12903
13185
  /* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
12904
13186
  activities.map((activity, ai) => {
12905
13187
  var _a3, _b2, _c2;
12906
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
13188
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12907
13189
  ai > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
12908
13190
  "td",
12909
13191
  {
@@ -15316,8 +15598,8 @@ var PRIORITY_STYLES = {
15316
15598
  function EscalationCardResolver(p) {
15317
15599
  var _a2, _b, _c, _d;
15318
15600
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
15319
- const [cardHovered, setCardHovered] = React41.useState(false);
15320
- const [btnHovered, setBtnHovered] = React41.useState(false);
15601
+ const [cardHovered, setCardHovered] = React45.useState(false);
15602
+ const [btnHovered, setBtnHovered] = React45.useState(false);
15321
15603
  const priorityStyle = p.priority ? PRIORITY_STYLES[p.priority] : null;
15322
15604
  const railColor = (_a2 = priorityStyle == null ? void 0 : priorityStyle.color) != null ? _a2 : ACCENT2;
15323
15605
  const iconBg = (_b = priorityStyle == null ? void 0 : priorityStyle.bg) != null ? _b : "#fff2ec";
@@ -16164,9 +16446,9 @@ var CONNECTED_GREEN = "#15803d";
16164
16446
  function ConnectIntegrationResolver(p) {
16165
16447
  var _a2;
16166
16448
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
16167
- const [cardHovered, setCardHovered] = React41.useState(false);
16168
- const [btnHovered, setBtnHovered] = React41.useState(false);
16169
- const [imgFailed, setImgFailed] = React41.useState(false);
16449
+ const [cardHovered, setCardHovered] = React45.useState(false);
16450
+ const [btnHovered, setBtnHovered] = React45.useState(false);
16451
+ const [imgFailed, setImgFailed] = React45.useState(false);
16170
16452
  const name = (p.integrationName || "Integration").trim();
16171
16453
  const initial = name.charAt(0).toUpperCase();
16172
16454
  const iconSrc = p.iconUrl || brandIconUrl(name);
@@ -16328,9 +16610,9 @@ function IntegrationsListResolver(p) {
16328
16610
  var _a2, _b;
16329
16611
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
16330
16612
  const integrations = Array.isArray(p.integrations) ? p.integrations : [];
16331
- const [rowHover, setRowHover] = React41.useState(null);
16332
- const [btnHover, setBtnHover] = React41.useState(null);
16333
- const [failed, setFailed] = React41.useState({});
16613
+ const [rowHover, setRowHover] = React45.useState(null);
16614
+ const [btnHover, setBtnHover] = React45.useState(null);
16615
+ const [failed, setFailed] = React45.useState({});
16334
16616
  const connectedCount = integrations.filter((i) => i.status === "connected").length;
16335
16617
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_a2 = p.title) != null ? _a2 : "integrations", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "11px" }, children: [
16336
16618
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [
@@ -16813,13 +17095,13 @@ var ellipsis = {
16813
17095
  function PipelinePreviewResolver(p) {
16814
17096
  var _a2, _b, _c, _d, _e, _f, _g;
16815
17097
  const { MUTED: MUTED2, PAPER: PAPER2, BORDER: BORDER4, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
16816
- const [btnHovered, setBtnHovered] = React41.useState(false);
17098
+ const [btnHovered, setBtnHovered] = React45.useState(false);
16817
17099
  const stateCfg = STATE_CONFIG[(_a2 = p.state) != null ? _a2 : "draft"];
16818
17100
  const destinations = (_b = p.destinations) != null ? _b : [];
16819
17101
  const steps = (_c = p.steps) != null ? _c : [];
16820
17102
  const workstreams = (_d = p.workstreams) != null ? _d : [];
16821
17103
  const scheduleLabel = p.schedule ? p.schedule.type === "manual" ? "Manual" : (_f = (_e = p.schedule.label) != null ? _e : p.schedule.cron) != null ? _f : "Scheduled" : null;
16822
- const { nodes, edges, viewBox, vbW, vbH } = React41.useMemo(() => {
17104
+ const { nodes, edges, viewBox, vbW, vbH } = React45.useMemo(() => {
16823
17105
  const res = layoutGraph(steps);
16824
17106
  const b = layoutBounds(res.nodes);
16825
17107
  const pad = 24;
@@ -16833,7 +17115,7 @@ function PipelinePreviewResolver(p) {
16833
17115
  vbH: h
16834
17116
  };
16835
17117
  }, [steps]);
16836
- const nodeMap = React41.useMemo(() => {
17118
+ const nodeMap = React45.useMemo(() => {
16837
17119
  const m = {};
16838
17120
  nodes.forEach((n) => m[n.id] = n);
16839
17121
  return m;
@@ -17204,14 +17486,17 @@ function PipelinePreviewResolver(p) {
17204
17486
  init_ThemeContext();
17205
17487
  var DEFAULT_INTERACTION = {
17206
17488
  selectedStepId: null,
17207
- onStepSelect: void 0
17489
+ onStepSelect: void 0,
17490
+ resolvedDecisions: void 0,
17491
+ onDecisionResolve: void 0,
17492
+ onDecisionSource: void 0
17208
17493
  };
17209
- var GenUIInteractionContext = React41.createContext(DEFAULT_INTERACTION);
17494
+ var GenUIInteractionContext = React45.createContext(DEFAULT_INTERACTION);
17210
17495
  function GenUIInteractionProvider({ value, children }) {
17211
17496
  return /* @__PURE__ */ jsxRuntime.jsx(GenUIInteractionContext.Provider, { value, children });
17212
17497
  }
17213
17498
  function useGenUIInteraction() {
17214
- return React41.useContext(GenUIInteractionContext);
17499
+ return React45.useContext(GenUIInteractionContext);
17215
17500
  }
17216
17501
  var STATUS_COLORS3 = {
17217
17502
  done: "#15803d",
@@ -17340,8 +17625,8 @@ var CARD_MIN = 132;
17340
17625
  var CARD_GAP = 16;
17341
17626
  var AUTO_COMPACT_BELOW = 360;
17342
17627
  function useContainerWidth(ref) {
17343
- const [w, setW] = React41__default.default.useState(0);
17344
- React41__default.default.useLayoutEffect(() => {
17628
+ const [w, setW] = React45__default.default.useState(0);
17629
+ React45__default.default.useLayoutEffect(() => {
17345
17630
  const el = ref.current;
17346
17631
  if (!el || typeof ResizeObserver === "undefined") return;
17347
17632
  const ro = new ResizeObserver((entries) => {
@@ -17442,15 +17727,15 @@ function WorkflowStepperRenderer({
17442
17727
  const interactive = typeof onSelectStep === "function";
17443
17728
  const statusColor3 = (s) => s === "active" ? ACCENT2 : STATUS_COLORS3[s];
17444
17729
  const doneCount = steps.filter((s) => s.status === "done").length;
17445
- const rootRef = React41__default.default.useRef(null);
17730
+ const rootRef = React45__default.default.useRef(null);
17446
17731
  const containerW = useContainerWidth(rootRef);
17447
17732
  let resolved = density === "auto" ? "full" : density;
17448
17733
  if (density === "auto" && containerW > 0) {
17449
17734
  const needed = steps.length * CARD_MIN + Math.max(0, steps.length - 1) * CARD_GAP;
17450
17735
  resolved = containerW < AUTO_COMPACT_BELOW || needed > containerW * 1.6 ? "compact" : "full";
17451
17736
  }
17452
- const scrollerRef = React41__default.default.useRef(null);
17453
- React41__default.default.useEffect(() => {
17737
+ const scrollerRef = React45__default.default.useRef(null);
17738
+ React45__default.default.useEffect(() => {
17454
17739
  if (resolved !== "full" || loading) return;
17455
17740
  const sc = scrollerRef.current;
17456
17741
  if (!sc) return;
@@ -17461,11 +17746,11 @@ function WorkflowStepperRenderer({
17461
17746
  el.scrollIntoView({ inline: "center", block: "nearest", behavior: "smooth" });
17462
17747
  }
17463
17748
  }, [resolved, loading, selectedStep, activeStepId]);
17464
- const [edges, setEdges] = React41__default.default.useState({
17749
+ const [edges, setEdges] = React45__default.default.useState({
17465
17750
  left: false,
17466
17751
  right: false
17467
17752
  });
17468
- const updateEdges = React41__default.default.useCallback(() => {
17753
+ const updateEdges = React45__default.default.useCallback(() => {
17469
17754
  const sc = scrollerRef.current;
17470
17755
  if (!sc) return;
17471
17756
  const max = sc.scrollWidth - sc.clientWidth;
@@ -17474,7 +17759,7 @@ function WorkflowStepperRenderer({
17474
17759
  const right = sl < max - 1;
17475
17760
  setEdges((prev) => prev.left === left && prev.right === right ? prev : { left, right });
17476
17761
  }, []);
17477
- React41__default.default.useLayoutEffect(() => {
17762
+ React45__default.default.useLayoutEffect(() => {
17478
17763
  if (resolved !== "full" || loading) return;
17479
17764
  updateEdges();
17480
17765
  const sc = scrollerRef.current;
@@ -17530,7 +17815,7 @@ function WorkflowStepperRenderer({
17530
17815
  const reached = s.status !== "pending";
17531
17816
  const clickable = interactive && reached;
17532
17817
  const size = act ? 11 : done ? 9 : 8;
17533
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
17818
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
17534
17819
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(
17535
17820
  "span",
17536
17821
  {
@@ -17673,7 +17958,7 @@ function WorkflowStepperRenderer({
17673
17958
  const color = statusColor3(step.status);
17674
17959
  const humans = ((_a3 = step.assignees) != null ? _a3 : []).filter((a) => a.kind === "human");
17675
17960
  const roleCaption = humans.map((h) => h.role).filter(Boolean).slice(0, 2).join(" \xB7 ");
17676
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
17961
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
17677
17962
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(
17678
17963
  "div",
17679
17964
  {
@@ -17926,144 +18211,2202 @@ function WorkflowStepperResolver(p) {
17926
18211
  )
17927
18212
  ] }) });
17928
18213
  }
17929
- function resolveUI(rawPayload) {
17930
- const payload = coercePayload(rawPayload);
17931
- switch (payload.type) {
17932
- case "data-table":
17933
- return /* @__PURE__ */ jsxRuntime.jsx(DataTableResolver, __spreadValues({}, payload));
17934
- case "status-card":
17935
- return /* @__PURE__ */ jsxRuntime.jsx(StatusCardResolver, __spreadValues({}, payload));
17936
- case "alert":
17937
- return /* @__PURE__ */ jsxRuntime.jsx(AlertResolver, __spreadValues({}, payload));
17938
- case "stat-grid":
17939
- return /* @__PURE__ */ jsxRuntime.jsx(StatGridResolver, __spreadValues({}, payload));
17940
- case "tabs-panel":
17941
- return /* @__PURE__ */ jsxRuntime.jsx(TabsPanelResolver, __spreadValues({}, payload));
17942
- case "sparkline-table":
17943
- return /* @__PURE__ */ jsxRuntime.jsx(SparklineTableResolver, __spreadValues({}, payload));
17944
- case "heatmap-table":
17945
- return /* @__PURE__ */ jsxRuntime.jsx(HeatmapTableResolver, __spreadValues({}, payload));
17946
- case "screener-table":
17947
- return /* @__PURE__ */ jsxRuntime.jsx(ScreenerTableResolver, __spreadValues({}, payload));
17948
- case "grouped-table":
17949
- return /* @__PURE__ */ jsxRuntime.jsx(GroupedTableResolver, __spreadValues({}, payload));
17950
- case "news-feed":
17951
- return /* @__PURE__ */ jsxRuntime.jsx(NewsFeedResolver, __spreadValues({}, payload));
17952
- case "area-chart":
17953
- return /* @__PURE__ */ jsxRuntime.jsx(AreaChartResolver, __spreadValues({}, payload));
17954
- case "allocation-donut":
17955
- return /* @__PURE__ */ jsxRuntime.jsx(AllocationDonutResolver, __spreadValues({}, payload));
17956
- case "waterfall-chart":
17957
- return /* @__PURE__ */ jsxRuntime.jsx(WaterfallChartResolver, __spreadValues({}, payload));
17958
- case "flow-canvas":
17959
- return /* @__PURE__ */ jsxRuntime.jsx(FlowCanvasResolver, __spreadValues({}, payload));
17960
- case "trial-balance":
17961
- return /* @__PURE__ */ jsxRuntime.jsx(TrialBalanceResolver, __spreadValues({}, payload));
17962
- case "journal-entry":
17963
- return /* @__PURE__ */ jsxRuntime.jsx(JournalEntryResolver, __spreadValues({}, payload));
17964
- case "aging-report":
17965
- return /* @__PURE__ */ jsxRuntime.jsx(AgingReportResolver, __spreadValues({}, payload));
17966
- case "variance-analysis":
17967
- return /* @__PURE__ */ jsxRuntime.jsx(VarianceAnalysisResolver, __spreadValues({}, payload));
17968
- case "stacked-breakdown":
17969
- return /* @__PURE__ */ jsxRuntime.jsx(StackedBreakdownResolver, __spreadValues({}, payload));
17970
- case "comparative-bar-chart":
17971
- return /* @__PURE__ */ jsxRuntime.jsx(ComparativeBarChartResolver, __spreadValues({}, payload));
17972
- case "compliance-checklist":
17973
- return /* @__PURE__ */ jsxRuntime.jsx(ComplianceChecklistResolver, __spreadValues({}, payload));
17974
- case "reconciliation-view":
17975
- return /* @__PURE__ */ jsxRuntime.jsx(ReconciliationViewResolver, __spreadValues({}, payload));
17976
- case "audit-trail":
17977
- return /* @__PURE__ */ jsxRuntime.jsx(AuditTrailResolver, __spreadValues({}, payload));
17978
- case "document-preview":
17979
- return /* @__PURE__ */ jsxRuntime.jsx(DocumentPreviewResolver, __spreadValues({}, payload));
17980
- case "provenance-chain":
17981
- return /* @__PURE__ */ jsxRuntime.jsx(ProvenanceChainResolver, __spreadValues({}, payload));
17982
- case "search-results":
17983
- return /* @__PURE__ */ jsxRuntime.jsx(SearchResultsResolver, __spreadValues({}, payload));
17984
- case "legal-test-result":
17985
- return /* @__PURE__ */ jsxRuntime.jsx(LegalTestResultResolver, __spreadValues({}, payload));
17986
- case "engagement-pipeline":
17987
- return /* @__PURE__ */ jsxRuntime.jsx(EngagementPipelineResolver, __spreadValues({}, payload));
17988
- case "entity-card-grid":
17989
- return /* @__PURE__ */ jsxRuntime.jsx(EntityCardGridResolver, __spreadValues({}, payload));
17990
- case "job-tracker":
17991
- return /* @__PURE__ */ jsxRuntime.jsx(JobTrackerResolver, __spreadValues({}, payload));
17992
- case "cited-answer":
17993
- return /* @__PURE__ */ jsxRuntime.jsx(CitedAnswerResolver, __spreadValues({}, payload));
17994
- case "transaction-feed":
17995
- return /* @__PURE__ */ jsxRuntime.jsx(TransactionFeedResolver, __spreadValues({}, payload));
17996
- case "file-browser":
17997
- return /* @__PURE__ */ jsxRuntime.jsx(FileBrowserResolver, __spreadValues({}, payload));
17998
- case "download-card":
17999
- return /* @__PURE__ */ jsxRuntime.jsx(DownloadCardResolver, __spreadValues({}, payload));
18000
- case "ops-dashboard":
18001
- return /* @__PURE__ */ jsxRuntime.jsx(OpsDashboardResolver, __spreadValues({}, payload));
18002
- case "key-value-list":
18003
- return /* @__PURE__ */ jsxRuntime.jsx(KeyValueListResolver, __spreadValues({}, payload));
18004
- case "balance-sheet":
18005
- return /* @__PURE__ */ jsxRuntime.jsx(BalanceSheetResolver, __spreadValues({}, payload));
18006
- case "income-statement":
18007
- return /* @__PURE__ */ jsxRuntime.jsx(IncomeStatementResolver, __spreadValues({}, payload));
18008
- case "cash-flow-statement":
18009
- return /* @__PURE__ */ jsxRuntime.jsx(CashFlowStatementResolver, __spreadValues({}, payload));
18010
- case "general-ledger":
18011
- return /* @__PURE__ */ jsxRuntime.jsx(GeneralLedgerResolver, __spreadValues({}, payload));
18012
- case "chart-of-accounts":
18013
- return /* @__PURE__ */ jsxRuntime.jsx(ChartOfAccountsResolver, __spreadValues({}, payload));
18014
- case "invoice-detail":
18015
- return /* @__PURE__ */ jsxRuntime.jsx(InvoiceDetailResolver, __spreadValues({}, payload));
18016
- case "amortization-table":
18017
- return /* @__PURE__ */ jsxRuntime.jsx(AmortizationTableResolver, __spreadValues({}, payload));
18018
- case "depreciation-schedule":
18019
- return /* @__PURE__ */ jsxRuntime.jsx(DepreciationScheduleResolver, __spreadValues({}, payload));
18020
- case "escalation-card":
18021
- return /* @__PURE__ */ jsxRuntime.jsx(EscalationCardResolver, __spreadValues({}, payload));
18022
- case "line-chart":
18023
- return /* @__PURE__ */ jsxRuntime.jsx(LineChartResolver, __spreadValues({}, payload));
18024
- case "combo-chart":
18025
- return /* @__PURE__ */ jsxRuntime.jsx(ComboChartResolver, __spreadValues({}, payload));
18026
- case "gauge-chart":
18027
- return /* @__PURE__ */ jsxRuntime.jsx(GaugeChartResolver, __spreadValues({}, payload));
18028
- case "treemap-chart":
18029
- return /* @__PURE__ */ jsxRuntime.jsx(TreemapChartResolver, __spreadValues({}, payload));
18030
- case "radar-chart":
18031
- return /* @__PURE__ */ jsxRuntime.jsx(RadarChartResolver, __spreadValues({}, payload));
18032
- case "funnel-chart":
18033
- return /* @__PURE__ */ jsxRuntime.jsx(FunnelChartResolver, __spreadValues({}, payload));
18034
- case "bullet-chart":
18035
- return /* @__PURE__ */ jsxRuntime.jsx(BulletChartResolver, __spreadValues({}, payload));
18036
- case "scatter-chart":
18037
- return /* @__PURE__ */ jsxRuntime.jsx(ScatterChartResolver, __spreadValues({}, payload));
18038
- case "connect-integration":
18039
- return /* @__PURE__ */ jsxRuntime.jsx(ConnectIntegrationResolver, __spreadValues({}, payload));
18040
- case "integrations-list":
18041
- return /* @__PURE__ */ jsxRuntime.jsx(IntegrationsListResolver, __spreadValues({}, payload));
18042
- case "pipeline-preview":
18043
- return /* @__PURE__ */ jsxRuntime.jsx(PipelinePreviewResolver, __spreadValues({}, payload));
18044
- case "workflow-stepper":
18045
- return /* @__PURE__ */ jsxRuntime.jsx(WorkflowStepperResolver, __spreadValues({}, payload));
18046
- default: {
18047
- return /* @__PURE__ */ jsxRuntime.jsx(
18048
- "div",
18049
- {
18050
- role: "alert",
18051
- style: {
18052
- padding: "12px 16px",
18053
- border: "1px solid #dc2626",
18054
- borderRadius: "8px",
18055
- background: "#fef2f2",
18056
- color: "#dc2626",
18057
- fontSize: "13px",
18058
- fontWeight: 600
18059
- },
18060
- children: "Unknown UI type"
18061
- }
18062
- );
18063
- }
18064
- }
18065
- }
18066
- function InlineSpinner() {
18214
+ init_ThemeContext();
18215
+
18216
+ // src/composites/document-field-extraction/bboxTransform.ts
18217
+ function bboxToRect(bbox2, page, px) {
18218
+ if (!bbox2 || bbox2.length !== 4) return null;
18219
+ const { wPts, hPts } = page;
18220
+ const { wPx, hPx } = px;
18221
+ if (!wPts || !hPts || !wPx || !hPx) return null;
18222
+ const [x0, y0, x1, y1] = bbox2;
18223
+ const sx = wPx / wPts;
18224
+ const sy = hPx / hPts;
18225
+ return {
18226
+ left: x0 * sx,
18227
+ width: (x1 - x0) * sx,
18228
+ // Flip Y: the box's TOP in screen space is the page height minus its upper
18229
+ // PDF-point edge (y1), because PDF y grows upward from the bottom.
18230
+ top: (hPts - y1) * sy,
18231
+ height: (y1 - y0) * sy
18232
+ };
18233
+ }
18234
+
18235
+ // src/composites/document-field-extraction/FieldDetail.tsx
18236
+ init_ThemeContext();
18237
+
18238
+ // src/composites/document-field-extraction/fieldLabels.ts
18239
+ var LABEL_DISPLAY = {
18240
+ "employer identification number": "Employer ID (EIN)",
18241
+ "company or business name": "Company Name",
18242
+ "total revenue": "Total Revenue",
18243
+ "net income": "Net Income",
18244
+ "tax year": "Tax Year",
18245
+ "invoice number": "Invoice Number",
18246
+ "invoice date": "Invoice Date",
18247
+ "total amount due": "Total Amount Due",
18248
+ "vendor name": "Vendor Name",
18249
+ "receipt total": "Receipt Total",
18250
+ "transaction date": "Transaction Date",
18251
+ "merchant name": "Merchant Name"
18252
+ };
18253
+ function prettyLabel(label) {
18254
+ var _a2;
18255
+ return (_a2 = LABEL_DISPLAY[label]) != null ? _a2 : label.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
18256
+ }
18257
+ var TIER_COLORS = {
18258
+ green: "#15803d",
18259
+ amber: "#f59e0b",
18260
+ red: "#dc2626"
18261
+ };
18262
+ var BADGE_TITLE = {
18263
+ SC: "High confidence",
18264
+ CN: "Medium confidence",
18265
+ AB: "Low confidence",
18266
+ SW: "Very low confidence"
18267
+ };
18268
+ var BADGE_STYLE = {
18269
+ SC: { bg: "#dcfce7", fg: "#15803d" },
18270
+ CN: { bg: "#eff6ff", fg: "#0364ff" },
18271
+ AB: { bg: "#fff7ed", fg: "#92400e" },
18272
+ SW: { bg: "#fef2f2", fg: "#dc2626" }
18273
+ };
18274
+ var STATE_DOT = {
18275
+ ok: "#15803d",
18276
+ corrected: "#0364ff",
18277
+ missing: "#dc2626",
18278
+ warn: "#f59e0b"
18279
+ };
18280
+ function hexToRgba(hex, alpha) {
18281
+ const h = hex.replace("#", "");
18282
+ const r = parseInt(h.slice(0, 2), 16);
18283
+ const g = parseInt(h.slice(2, 4), 16);
18284
+ const b = parseInt(h.slice(4, 6), 16);
18285
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
18286
+ }
18287
+ function badgeStyle(f) {
18288
+ var _a2, _b;
18289
+ return (_b = BADGE_STYLE[(_a2 = f.badge) != null ? _a2 : ""]) != null ? _b : { bg: "#f6f6f6", fg: "#777777" };
18290
+ }
18291
+ function dotColor2(f) {
18292
+ var _a2, _b;
18293
+ return (_b = STATE_DOT[(_a2 = f.state) != null ? _a2 : "ok"]) != null ? _b : "#15803d";
18294
+ }
18295
+ function fieldColor(f, secondary) {
18296
+ var _a2, _b;
18297
+ if (f.state === "corrected") return secondary;
18298
+ return (_b = TIER_COLORS[(_a2 = f.confidence_tier) != null ? _a2 : "amber"]) != null ? _b : TIER_COLORS.amber;
18299
+ }
18300
+ function confidenceLabel(f) {
18301
+ var _a2;
18302
+ if (typeof f.confidence === "number" && !Number.isNaN(f.confidence)) {
18303
+ return `${Math.round(f.confidence * 100)}%`;
18304
+ }
18305
+ return (_a2 = f.badge) != null ? _a2 : "\u2014";
18306
+ }
18307
+ function FieldDetail({
18308
+ field,
18309
+ selected,
18310
+ onSelect,
18311
+ onSave,
18312
+ correctionCount = 0,
18313
+ cardRef
18314
+ }) {
18315
+ var _a2, _b, _c, _d;
18316
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
18317
+ const [editing, setEditing] = React45__default.default.useState(false);
18318
+ const [draft, setDraft] = React45__default.default.useState("");
18319
+ const [saving, setSaving] = React45__default.default.useState(false);
18320
+ const [saveError, setSaveError] = React45__default.default.useState(null);
18321
+ const textareaRef = React45__default.default.useRef(null);
18322
+ const color = fieldColor(field, SECONDARY2);
18323
+ const corrected = field.state === "corrected";
18324
+ const startEdit = (e) => {
18325
+ e.stopPropagation();
18326
+ setDraft(field.value || "");
18327
+ setSaveError(null);
18328
+ setEditing(true);
18329
+ setTimeout(() => {
18330
+ var _a3, _b2;
18331
+ (_a3 = textareaRef.current) == null ? void 0 : _a3.focus();
18332
+ (_b2 = textareaRef.current) == null ? void 0 : _b2.select();
18333
+ }, 0);
18334
+ };
18335
+ const cancelEdit = (e) => {
18336
+ e.stopPropagation();
18337
+ setEditing(false);
18338
+ setSaveError(null);
18339
+ };
18340
+ const save = async (e) => {
18341
+ var _a3, _b2;
18342
+ e.stopPropagation();
18343
+ if (!onSave || draft === field.value) {
18344
+ setEditing(false);
18345
+ return;
18346
+ }
18347
+ setSaving(true);
18348
+ setSaveError(null);
18349
+ try {
18350
+ await onSave(field.field_key, draft);
18351
+ setEditing(false);
18352
+ } catch (err) {
18353
+ const msg = ((_b2 = (_a3 = err == null ? void 0 : err.response) == null ? void 0 : _a3.data) == null ? void 0 : _b2.detail) || "Save failed. Try again.";
18354
+ setSaveError(msg);
18355
+ } finally {
18356
+ setSaving(false);
18357
+ }
18358
+ };
18359
+ const handleKeyDown = (e) => {
18360
+ if (e.key === "Escape") cancelEdit(e);
18361
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) void save(e);
18362
+ };
18363
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18364
+ "div",
18365
+ {
18366
+ ref: cardRef,
18367
+ "data-testid": "field-card",
18368
+ "data-field-key": field.field_key,
18369
+ "data-selected": selected ? "true" : "false",
18370
+ role: "button",
18371
+ tabIndex: 0,
18372
+ onClick: () => !editing && onSelect(selected ? null : field.field_key),
18373
+ onKeyDown: (e) => {
18374
+ if (!editing && e.key === "Enter") onSelect(selected ? null : field.field_key);
18375
+ },
18376
+ style: {
18377
+ display: "flex",
18378
+ flexDirection: "column",
18379
+ gap: "4px",
18380
+ padding: "8px 10px",
18381
+ borderRadius: "0.5rem",
18382
+ border: `1px solid ${selected ? color : BORDER4}`,
18383
+ background: selected ? hexToRgba(color, 0.06) : "white",
18384
+ cursor: editing ? "default" : "pointer",
18385
+ transition: "background 0.15s, border-color 0.15s"
18386
+ },
18387
+ children: [
18388
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", minWidth: 0 }, children: [
18389
+ /* @__PURE__ */ jsxRuntime.jsx(
18390
+ "span",
18391
+ {
18392
+ title: (_c = (_b = BADGE_TITLE[(_a2 = field.badge) != null ? _a2 : ""]) != null ? _b : field.badge) != null ? _c : "",
18393
+ style: {
18394
+ fontSize: "10px",
18395
+ fontWeight: 700,
18396
+ padding: "2px 6px",
18397
+ borderRadius: "4px",
18398
+ flexShrink: 0,
18399
+ letterSpacing: "0.02em",
18400
+ minWidth: "34px",
18401
+ textAlign: "center",
18402
+ fontVariantNumeric: "tabular-nums",
18403
+ background: badgeStyle(field).bg,
18404
+ color: badgeStyle(field).fg
18405
+ },
18406
+ children: confidenceLabel(field)
18407
+ }
18408
+ ),
18409
+ /* @__PURE__ */ jsxRuntime.jsx(
18410
+ "span",
18411
+ {
18412
+ title: prettyLabel(field.label),
18413
+ style: {
18414
+ fontSize: "12.5px",
18415
+ fontWeight: 600,
18416
+ color: "var(--foreground)",
18417
+ flex: 1,
18418
+ minWidth: 0,
18419
+ whiteSpace: "nowrap",
18420
+ overflow: "hidden",
18421
+ textOverflow: "ellipsis"
18422
+ },
18423
+ children: prettyLabel(field.label)
18424
+ }
18425
+ ),
18426
+ field.is_primary && /* @__PURE__ */ jsxRuntime.jsx(
18427
+ "span",
18428
+ {
18429
+ style: {
18430
+ fontSize: "9px",
18431
+ fontWeight: 600,
18432
+ textTransform: "uppercase",
18433
+ letterSpacing: "0.04em",
18434
+ color: MUTED2,
18435
+ flexShrink: 0
18436
+ },
18437
+ children: "Primary"
18438
+ }
18439
+ ),
18440
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "11px", color: MUTED2, flexShrink: 0 }, children: [
18441
+ "p.",
18442
+ field.page + 1
18443
+ ] }),
18444
+ !editing && onSave && /* @__PURE__ */ jsxRuntime.jsx(
18445
+ "button",
18446
+ {
18447
+ type: "button",
18448
+ onClick: startEdit,
18449
+ title: "Edit value",
18450
+ "aria-label": "Edit value",
18451
+ style: {
18452
+ border: `1px solid ${BORDER4}`,
18453
+ borderRadius: "6px",
18454
+ background: "white",
18455
+ cursor: "pointer",
18456
+ padding: "3px 5px",
18457
+ lineHeight: 1,
18458
+ flexShrink: 0,
18459
+ display: "inline-flex",
18460
+ alignItems: "center",
18461
+ justifyContent: "center"
18462
+ },
18463
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: MUTED2, strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
18464
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
18465
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
18466
+ ] })
18467
+ }
18468
+ )
18469
+ ] }),
18470
+ editing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { onClick: (e) => e.stopPropagation(), style: { display: "flex", flexDirection: "column", gap: "5px" }, children: [
18471
+ /* @__PURE__ */ jsxRuntime.jsx(
18472
+ "textarea",
18473
+ {
18474
+ ref: textareaRef,
18475
+ value: draft,
18476
+ onChange: (e) => setDraft(e.target.value),
18477
+ onKeyDown: handleKeyDown,
18478
+ rows: 3,
18479
+ placeholder: "Enter value\u2026",
18480
+ style: {
18481
+ width: "100%",
18482
+ boxSizing: "border-box",
18483
+ resize: "vertical",
18484
+ fontSize: "13px",
18485
+ fontFamily: "var(--font-sans)",
18486
+ color: "var(--foreground)",
18487
+ padding: "6px 8px",
18488
+ borderRadius: "0.4rem",
18489
+ border: `1px solid ${BORDER4}`
18490
+ }
18491
+ }
18492
+ ),
18493
+ saveError && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: TIER_COLORS.red }, children: saveError }),
18494
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "6px" }, children: [
18495
+ /* @__PURE__ */ jsxRuntime.jsx(
18496
+ "button",
18497
+ {
18498
+ type: "button",
18499
+ onClick: save,
18500
+ disabled: saving,
18501
+ title: "Save (\u2318\u21B5)",
18502
+ style: {
18503
+ display: "inline-flex",
18504
+ alignItems: "center",
18505
+ gap: "4px",
18506
+ fontSize: "11px",
18507
+ fontWeight: 600,
18508
+ padding: "4px 10px",
18509
+ borderRadius: "0.4rem",
18510
+ border: "none",
18511
+ background: "var(--foreground)",
18512
+ color: "white",
18513
+ cursor: saving ? "default" : "pointer",
18514
+ opacity: saving ? 0.7 : 1
18515
+ },
18516
+ children: saving ? "Saving\u2026" : "Save"
18517
+ }
18518
+ ),
18519
+ /* @__PURE__ */ jsxRuntime.jsx(
18520
+ "button",
18521
+ {
18522
+ type: "button",
18523
+ onClick: cancelEdit,
18524
+ disabled: saving,
18525
+ title: "Cancel (Esc)",
18526
+ style: {
18527
+ fontSize: "11px",
18528
+ fontWeight: 600,
18529
+ padding: "4px 10px",
18530
+ borderRadius: "0.4rem",
18531
+ border: `1px solid ${BORDER4}`,
18532
+ background: "white",
18533
+ color: MUTED2,
18534
+ cursor: saving ? "default" : "pointer"
18535
+ },
18536
+ children: "Cancel"
18537
+ }
18538
+ )
18539
+ ] })
18540
+ ] }) : corrected ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "2px", paddingLeft: "2px" }, children: [
18541
+ field.previous_value != null && field.previous_value !== "" && /* @__PURE__ */ jsxRuntime.jsx(
18542
+ "span",
18543
+ {
18544
+ style: {
18545
+ fontSize: "11.5px",
18546
+ color: MUTED2,
18547
+ textDecoration: "line-through",
18548
+ fontFamily: "ui-monospace, 'Cascadia Code', monospace",
18549
+ wordBreak: "break-word"
18550
+ },
18551
+ children: field.previous_value
18552
+ }
18553
+ ),
18554
+ /* @__PURE__ */ jsxRuntime.jsx(
18555
+ "span",
18556
+ {
18557
+ style: {
18558
+ fontSize: "12.5px",
18559
+ fontWeight: 600,
18560
+ color: "var(--foreground)",
18561
+ fontFamily: "ui-monospace, 'Cascadia Code', monospace",
18562
+ wordBreak: "break-word"
18563
+ },
18564
+ children: field.value || "\u2014"
18565
+ }
18566
+ ),
18567
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
18568
+ field.corrected_by && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: SECONDARY2 }, title: `Corrected by ${field.corrected_by}`, children: field.corrected_by }),
18569
+ correctionCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
18570
+ "span",
18571
+ {
18572
+ style: {
18573
+ fontSize: "10.5px",
18574
+ fontWeight: 600,
18575
+ color: MUTED2,
18576
+ background: PAPER2,
18577
+ borderRadius: "9999px",
18578
+ padding: "1px 7px"
18579
+ },
18580
+ children: [
18581
+ correctionCount,
18582
+ " ",
18583
+ correctionCount === 1 ? "event" : "events"
18584
+ ]
18585
+ }
18586
+ )
18587
+ ] })
18588
+ ] }) : (
18589
+ // Bottom row: monospace value + right-edge validation dot (file explorer).
18590
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", paddingLeft: "2px" }, children: [
18591
+ /* @__PURE__ */ jsxRuntime.jsx(
18592
+ "span",
18593
+ {
18594
+ style: {
18595
+ fontSize: "12.5px",
18596
+ color: MUTED2,
18597
+ fontFamily: "ui-monospace, 'Cascadia Code', monospace",
18598
+ flex: 1,
18599
+ minWidth: 0,
18600
+ whiteSpace: "nowrap",
18601
+ overflow: "hidden",
18602
+ textOverflow: "ellipsis"
18603
+ },
18604
+ title: field.value || "\u2014",
18605
+ children: field.value || "\u2014"
18606
+ }
18607
+ ),
18608
+ /* @__PURE__ */ jsxRuntime.jsx(
18609
+ "span",
18610
+ {
18611
+ title: (_d = field.state) != null ? _d : "ok",
18612
+ style: {
18613
+ width: "8px",
18614
+ height: "8px",
18615
+ borderRadius: "9999px",
18616
+ flexShrink: 0,
18617
+ background: dotColor2(field)
18618
+ }
18619
+ }
18620
+ )
18621
+ ] })
18622
+ )
18623
+ ]
18624
+ }
18625
+ );
18626
+ }
18627
+
18628
+ // src/composites/document-field-extraction/FieldDetails.tsx
18629
+ init_ThemeContext();
18630
+ var BADGE_DOT = {
18631
+ // gen-ui semantic dot colors
18632
+ ok: "#15803d",
18633
+ green: "#15803d",
18634
+ warn: "#f59e0b",
18635
+ amber: "#f59e0b",
18636
+ missing: "#dc2626",
18637
+ red: "#dc2626",
18638
+ corrected: "#0364ff"
18639
+ };
18640
+ function FieldDetails({
18641
+ summary,
18642
+ fileName,
18643
+ pageCount,
18644
+ pagesProcessed
18645
+ }) {
18646
+ var _a2, _b, _c, _d, _e, _f;
18647
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
18648
+ if (!summary) {
18649
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18650
+ "div",
18651
+ {
18652
+ style: {
18653
+ height: "100%",
18654
+ display: "flex",
18655
+ flexDirection: "column",
18656
+ alignItems: "center",
18657
+ justifyContent: "center",
18658
+ gap: "6px",
18659
+ color: MUTED2,
18660
+ textAlign: "center",
18661
+ padding: "24px"
18662
+ },
18663
+ children: [
18664
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "26px", lineHeight: 1 }, children: "\u{1F4C4}" }),
18665
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "14px", fontWeight: 600, color: "var(--foreground)" }, children: "No summary yet" }),
18666
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12px", maxWidth: "280px" }, children: "This document has no extracted summary." })
18667
+ ]
18668
+ }
18669
+ );
18670
+ }
18671
+ const header = buildHeader(summary);
18672
+ const crumb = buildCrumbLine(summary);
18673
+ const facts = buildFacts(summary, fileName, pageCount, pagesProcessed);
18674
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "100%", overflowY: "auto", paddingRight: "4px" }, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "14px" }, children: [
18675
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { style: { display: "flex", flexDirection: "column", gap: "3px" }, children: [
18676
+ /* @__PURE__ */ jsxRuntime.jsx(
18677
+ "h2",
18678
+ {
18679
+ title: header.title,
18680
+ style: {
18681
+ margin: 0,
18682
+ fontFamily: "var(--font-serif)",
18683
+ fontSize: "20px",
18684
+ fontWeight: 400,
18685
+ letterSpacing: "-0.01em",
18686
+ color: "var(--foreground)",
18687
+ overflow: "hidden",
18688
+ textOverflow: "ellipsis",
18689
+ whiteSpace: "nowrap"
18690
+ },
18691
+ children: header.title
18692
+ }
18693
+ ),
18694
+ header.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12px", color: MUTED2 }, children: header.subtitle })
18695
+ ] }),
18696
+ (summary.domain || summary.display_name || summary.domain_group || ((_b = (_a2 = summary.tags) == null ? void 0 : _a2.length) != null ? _b : 0) > 0) && /* @__PURE__ */ jsxRuntime.jsxs(
18697
+ "section",
18698
+ {
18699
+ style: {
18700
+ display: "flex",
18701
+ flexDirection: "column",
18702
+ gap: "6px",
18703
+ padding: "12px 14px",
18704
+ borderRadius: "0.75rem",
18705
+ border: `1px solid ${BORDER4}`,
18706
+ background: PAPER2
18707
+ },
18708
+ children: [
18709
+ summary.domain_group && /* @__PURE__ */ jsxRuntime.jsx(
18710
+ "span",
18711
+ {
18712
+ style: {
18713
+ fontSize: "10px",
18714
+ fontWeight: 600,
18715
+ textTransform: "uppercase",
18716
+ letterSpacing: "0.06em",
18717
+ color: MUTED2
18718
+ },
18719
+ children: summary.domain_group
18720
+ }
18721
+ ),
18722
+ /* @__PURE__ */ jsxRuntime.jsx(
18723
+ "h3",
18724
+ {
18725
+ style: {
18726
+ margin: 0,
18727
+ fontSize: "14px",
18728
+ fontWeight: 600,
18729
+ color: "var(--foreground)"
18730
+ },
18731
+ children: summary.domain || summary.display_name
18732
+ }
18733
+ ),
18734
+ crumb && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12px", color: MUTED2 }, children: crumb }),
18735
+ ((_d = (_c = summary.tags) == null ? void 0 : _c.length) != null ? _d : 0) > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: "5px", marginTop: "2px" }, children: summary.tags.map((t) => /* @__PURE__ */ jsxRuntime.jsx(
18736
+ "span",
18737
+ {
18738
+ style: {
18739
+ fontSize: "10px",
18740
+ fontWeight: 600,
18741
+ padding: "2px 8px",
18742
+ borderRadius: "9999px",
18743
+ background: "white",
18744
+ border: `1px solid ${BORDER4}`,
18745
+ color: MUTED2
18746
+ },
18747
+ children: t
18748
+ },
18749
+ t
18750
+ )) })
18751
+ ]
18752
+ }
18753
+ ),
18754
+ ((_f = (_e = summary.stats) == null ? void 0 : _e.length) != null ? _f : 0) > 0 && /* @__PURE__ */ jsxRuntime.jsx(
18755
+ "div",
18756
+ {
18757
+ style: {
18758
+ display: "grid",
18759
+ gridTemplateColumns: "repeat(auto-fit, minmax(130px, 1fr))",
18760
+ gap: "8px"
18761
+ },
18762
+ children: summary.stats.map((s) => /* @__PURE__ */ jsxRuntime.jsxs(
18763
+ "div",
18764
+ {
18765
+ style: {
18766
+ display: "flex",
18767
+ flexDirection: "column",
18768
+ gap: "2px",
18769
+ padding: "10px 12px",
18770
+ borderRadius: "0.6rem",
18771
+ border: `1px solid ${BORDER4}`,
18772
+ background: "white"
18773
+ },
18774
+ children: [
18775
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: MUTED2 }, children: s.label }),
18776
+ /* @__PURE__ */ jsxRuntime.jsx(
18777
+ "span",
18778
+ {
18779
+ title: s.value,
18780
+ style: {
18781
+ fontSize: "15px",
18782
+ fontWeight: 600,
18783
+ color: "var(--foreground)",
18784
+ overflow: "hidden",
18785
+ textOverflow: "ellipsis",
18786
+ whiteSpace: "nowrap"
18787
+ },
18788
+ children: s.value
18789
+ }
18790
+ ),
18791
+ s.caption && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "10px", color: MUTED2 }, children: s.caption })
18792
+ ]
18793
+ },
18794
+ s.field_key
18795
+ ))
18796
+ }
18797
+ ),
18798
+ facts.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
18799
+ /* @__PURE__ */ jsxRuntime.jsxs(
18800
+ "div",
18801
+ {
18802
+ style: {
18803
+ display: "flex",
18804
+ alignItems: "center",
18805
+ gap: "6px",
18806
+ fontSize: "11px",
18807
+ fontWeight: 600,
18808
+ textTransform: "uppercase",
18809
+ letterSpacing: "0.04em",
18810
+ color: MUTED2
18811
+ },
18812
+ children: [
18813
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u25A4" }),
18814
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Document details" })
18815
+ ]
18816
+ }
18817
+ ),
18818
+ /* @__PURE__ */ jsxRuntime.jsx(
18819
+ "dl",
18820
+ {
18821
+ style: {
18822
+ margin: 0,
18823
+ display: "grid",
18824
+ gridTemplateColumns: "minmax(110px, auto) 1fr",
18825
+ rowGap: "6px",
18826
+ columnGap: "14px"
18827
+ },
18828
+ children: facts.map((f) => {
18829
+ var _a3;
18830
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
18831
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { style: { fontSize: "12px", color: MUTED2 }, children: f.label }),
18832
+ /* @__PURE__ */ jsxRuntime.jsxs(
18833
+ "dd",
18834
+ {
18835
+ title: typeof f.value === "string" ? f.value : void 0,
18836
+ style: {
18837
+ margin: 0,
18838
+ fontSize: "12px",
18839
+ color: "var(--foreground)",
18840
+ display: "flex",
18841
+ alignItems: "center",
18842
+ gap: "6px",
18843
+ wordBreak: "break-word"
18844
+ },
18845
+ children: [
18846
+ f.badge && /* @__PURE__ */ jsxRuntime.jsx(
18847
+ "span",
18848
+ {
18849
+ style: {
18850
+ width: "7px",
18851
+ height: "7px",
18852
+ borderRadius: "9999px",
18853
+ flexShrink: 0,
18854
+ background: (_a3 = BADGE_DOT[f.badge]) != null ? _a3 : SECONDARY2
18855
+ }
18856
+ }
18857
+ ),
18858
+ f.value
18859
+ ]
18860
+ }
18861
+ )
18862
+ ] }, f.key);
18863
+ })
18864
+ }
18865
+ )
18866
+ ] })
18867
+ ] }) });
18868
+ }
18869
+ function buildHeader(summary) {
18870
+ const form = [summary.short_name, summary.display_name].filter(Boolean);
18871
+ const title = summary.organization || form.shift() || summary.domain || "Document";
18872
+ const parts = summary.organization ? [...form] : form;
18873
+ if (summary.tax_year) parts.push(`TY ${summary.tax_year}`);
18874
+ return { title, subtitle: parts.join(" \xB7 ") };
18875
+ }
18876
+ function buildCrumbLine(summary) {
18877
+ const parts = [...summary.crumbs || [], summary.short_name].filter(Boolean);
18878
+ if (parts.length > 0) return parts.join(" \xB7 ");
18879
+ return summary.domain && summary.display_name ? summary.display_name : "";
18880
+ }
18881
+ function buildFacts(summary, fileName, pageCount, pagesProcessed) {
18882
+ const rows = [];
18883
+ if (fileName) rows.push({ key: "file", label: "File", value: fileName });
18884
+ if (summary.display_name) {
18885
+ rows.push({ key: "doctype", label: "Document type", value: summary.display_name });
18886
+ }
18887
+ if (summary.tax_year != null && summary.tax_year !== "") {
18888
+ rows.push({ key: "year", label: "Tax year", value: String(summary.tax_year) });
18889
+ }
18890
+ for (const f of summary.facts || []) {
18891
+ rows.push({ key: f.field_key, label: f.label, value: f.value, badge: f.badge });
18892
+ }
18893
+ if (pageCount) {
18894
+ rows.push({
18895
+ key: "pages",
18896
+ label: "Pages processed",
18897
+ value: `${pagesProcessed != null ? pagesProcessed : pageCount} / ${pageCount}`
18898
+ });
18899
+ }
18900
+ return rows;
18901
+ }
18902
+
18903
+ // src/composites/document-field-extraction/FieldAuditLog.tsx
18904
+ init_ThemeContext();
18905
+ function initials(name) {
18906
+ return name.trim().split(/\s+/).slice(0, 2).map((w) => {
18907
+ var _a2;
18908
+ return ((_a2 = w[0]) != null ? _a2 : "").toUpperCase();
18909
+ }).join("");
18910
+ }
18911
+ function formatTs(ts) {
18912
+ if (!ts) return "\u2014";
18913
+ const d = new Date(ts);
18914
+ if (Number.isNaN(d.getTime())) return ts;
18915
+ return d.toLocaleString(void 0, {
18916
+ month: "short",
18917
+ day: "numeric",
18918
+ hour: "2-digit",
18919
+ minute: "2-digit"
18920
+ });
18921
+ }
18922
+ function FieldAuditLog({
18923
+ events = [],
18924
+ loading = false,
18925
+ fields = []
18926
+ }) {
18927
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
18928
+ const fieldLabelMap = React45__default.default.useMemo(() => {
18929
+ var _a2;
18930
+ const map = {};
18931
+ for (const f of fields) map[f.field_key] = (_a2 = f.label) != null ? _a2 : f.field_key;
18932
+ return map;
18933
+ }, [fields]);
18934
+ if (loading) {
18935
+ return /* @__PURE__ */ jsxRuntime.jsx(
18936
+ "div",
18937
+ {
18938
+ style: {
18939
+ flex: 1,
18940
+ display: "flex",
18941
+ alignItems: "center",
18942
+ justifyContent: "center",
18943
+ padding: "32px 20px",
18944
+ fontSize: "13px",
18945
+ color: MUTED2
18946
+ },
18947
+ children: "Loading audit trail\u2026"
18948
+ }
18949
+ );
18950
+ }
18951
+ if (events.length === 0) {
18952
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18953
+ "div",
18954
+ {
18955
+ style: {
18956
+ flex: 1,
18957
+ display: "flex",
18958
+ flexDirection: "column",
18959
+ alignItems: "center",
18960
+ justifyContent: "center",
18961
+ gap: "6px",
18962
+ padding: "32px 20px",
18963
+ textAlign: "center"
18964
+ },
18965
+ children: [
18966
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "13.5px", fontWeight: 600, color: "var(--foreground)" }, children: "No changes yet" }),
18967
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12px", color: MUTED2, maxWidth: "240px", lineHeight: 1.5 }, children: "Field corrections will appear here." })
18968
+ ]
18969
+ }
18970
+ );
18971
+ }
18972
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0, overflow: "hidden" }, children: [
18973
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "8px 14px 6px", flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
18974
+ "span",
18975
+ {
18976
+ style: {
18977
+ fontSize: "11.5px",
18978
+ fontWeight: 600,
18979
+ color: MUTED2,
18980
+ textTransform: "uppercase",
18981
+ letterSpacing: "0.04em"
18982
+ },
18983
+ children: [
18984
+ events.length,
18985
+ " ",
18986
+ events.length === 1 ? "change" : "changes"
18987
+ ]
18988
+ }
18989
+ ) }),
18990
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { style: { listStyle: "none", margin: 0, padding: "0 0 16px", overflowY: "auto", flex: 1, minHeight: 0 }, children: events.map((ev) => {
18991
+ var _a2, _b;
18992
+ const rawLabel = (_a2 = fieldLabelMap[ev.field_key]) != null ? _a2 : ev.field_key;
18993
+ const label = prettyLabel(rawLabel);
18994
+ const isAI = ev.actor_type === "system" || ev.event_type === "ai_corrected" || ev.event_type === "ai_extracted";
18995
+ const actor = isAI ? "AI" : ev.actor_name || "Unknown";
18996
+ const eventLabel = isAI ? "Re-extracted" : "Corrected";
18997
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18998
+ "li",
18999
+ {
19000
+ "data-testid": "audit-row",
19001
+ style: { display: "flex", gap: "10px", padding: "10px 14px", borderBottom: `1px solid ${BORDER4}` },
19002
+ children: [
19003
+ /* @__PURE__ */ jsxRuntime.jsx(
19004
+ "div",
19005
+ {
19006
+ title: isAI ? "AI extraction" : actor,
19007
+ style: {
19008
+ flexShrink: 0,
19009
+ width: "28px",
19010
+ height: "28px",
19011
+ borderRadius: "50%",
19012
+ background: isAI ? "#dcfce7" : "#eff6ff",
19013
+ color: isAI ? "#15803d" : SECONDARY2,
19014
+ fontSize: "10.5px",
19015
+ fontWeight: 700,
19016
+ display: "flex",
19017
+ alignItems: "center",
19018
+ justifyContent: "center",
19019
+ marginTop: "1px"
19020
+ },
19021
+ children: isAI ? "\u2728" : initials(actor)
19022
+ }
19023
+ ),
19024
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "3px", flex: 1, minWidth: 0 }, children: [
19025
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: "6px", flexWrap: "wrap" }, children: [
19026
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "12.5px", fontWeight: 600, color: isAI ? "#15803d" : "var(--foreground)" }, children: actor }),
19027
+ /* @__PURE__ */ jsxRuntime.jsx(
19028
+ "span",
19029
+ {
19030
+ style: {
19031
+ fontSize: "10.5px",
19032
+ fontWeight: 600,
19033
+ color: MUTED2,
19034
+ background: PAPER2,
19035
+ borderRadius: "4px",
19036
+ padding: "1px 6px",
19037
+ whiteSpace: "nowrap",
19038
+ flexShrink: 0
19039
+ },
19040
+ children: eventLabel
19041
+ }
19042
+ ),
19043
+ /* @__PURE__ */ jsxRuntime.jsx(
19044
+ "span",
19045
+ {
19046
+ style: {
19047
+ fontSize: "12px",
19048
+ color: MUTED2,
19049
+ flex: 1,
19050
+ minWidth: 0,
19051
+ whiteSpace: "nowrap",
19052
+ overflow: "hidden",
19053
+ textOverflow: "ellipsis"
19054
+ },
19055
+ children: label
19056
+ }
19057
+ ),
19058
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: MUTED2, flexShrink: 0 }, children: formatTs(ev.created_at) })
19059
+ ] }),
19060
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
19061
+ ev.previous_value != null && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19062
+ /* @__PURE__ */ jsxRuntime.jsx(
19063
+ "span",
19064
+ {
19065
+ style: {
19066
+ fontSize: "12px",
19067
+ fontFamily: "ui-monospace, monospace",
19068
+ color: MUTED2,
19069
+ textDecoration: "line-through"
19070
+ },
19071
+ children: ev.previous_value
19072
+ }
19073
+ ),
19074
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: BORDER4 }, children: "\u2192" })
19075
+ ] }),
19076
+ /* @__PURE__ */ jsxRuntime.jsx(
19077
+ "span",
19078
+ {
19079
+ style: {
19080
+ fontSize: "12px",
19081
+ fontFamily: "ui-monospace, monospace",
19082
+ fontWeight: 600,
19083
+ color: "var(--foreground)"
19084
+ },
19085
+ children: (_b = ev.new_value) != null ? _b : "\u2014"
19086
+ }
19087
+ )
19088
+ ] }),
19089
+ ev.reason && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { margin: "2px 0 0", fontSize: "11.5px", color: MUTED2, fontStyle: "italic" }, children: [
19090
+ "\u201C",
19091
+ ev.reason,
19092
+ "\u201D"
19093
+ ] })
19094
+ ] })
19095
+ ]
19096
+ },
19097
+ ev.id
19098
+ );
19099
+ }) })
19100
+ ] });
19101
+ }
19102
+ var TIER_COLORS2 = {
19103
+ green: "#15803d",
19104
+ amber: "#f59e0b",
19105
+ red: "#dc2626"
19106
+ };
19107
+ function fieldColor2(f, secondary) {
19108
+ var _a2, _b;
19109
+ if (f.state === "corrected") return secondary;
19110
+ return (_b = TIER_COLORS2[(_a2 = f.confidence_tier) != null ? _a2 : "amber"]) != null ? _b : TIER_COLORS2.amber;
19111
+ }
19112
+ function hexToRgba2(hex, alpha) {
19113
+ const h = hex.replace("#", "");
19114
+ const r = parseInt(h.slice(0, 2), 16);
19115
+ const g = parseInt(h.slice(2, 4), 16);
19116
+ const b = parseInt(h.slice(4, 6), 16);
19117
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
19118
+ }
19119
+ function PageOverlay({
19120
+ page,
19121
+ fields,
19122
+ selectedKey,
19123
+ onSelect,
19124
+ secondary
19125
+ }) {
19126
+ const { PAPER: PAPER2, MUTED: MUTED2 } = useTheme();
19127
+ const imgRef = React45__default.default.useRef(null);
19128
+ const selectedBoxRef = React45__default.default.useRef(null);
19129
+ const [px, setPx] = React45__default.default.useState(null);
19130
+ React45__default.default.useEffect(() => {
19131
+ const el = imgRef.current;
19132
+ if (!el) return;
19133
+ const measure = () => {
19134
+ if (el.clientWidth && el.clientHeight) {
19135
+ setPx({ wPx: el.clientWidth, hPx: el.clientHeight });
19136
+ }
19137
+ };
19138
+ measure();
19139
+ if (typeof ResizeObserver === "undefined") return;
19140
+ const ro = new ResizeObserver(measure);
19141
+ ro.observe(el);
19142
+ return () => ro.disconnect();
19143
+ }, [page.imageUrl]);
19144
+ React45__default.default.useEffect(() => {
19145
+ if (!selectedKey) return;
19146
+ if (!fields.some((f) => f.field_key === selectedKey && f.bbox)) return;
19147
+ const el = selectedBoxRef.current;
19148
+ if (el && typeof el.scrollIntoView === "function") {
19149
+ el.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" });
19150
+ }
19151
+ }, [selectedKey, fields, px]);
19152
+ const pagePts = { wPts: page.width_pt, hPts: page.height_pt };
19153
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", width: "100%", lineHeight: 0 }, children: [
19154
+ page.imageUrl ? /* @__PURE__ */ jsxRuntime.jsx(
19155
+ "img",
19156
+ {
19157
+ ref: imgRef,
19158
+ src: page.imageUrl,
19159
+ alt: `Page ${page.page + 1}`,
19160
+ onLoad: () => {
19161
+ const el = imgRef.current;
19162
+ if (el && el.clientWidth && el.clientHeight) {
19163
+ setPx({ wPx: el.clientWidth, hPx: el.clientHeight });
19164
+ }
19165
+ },
19166
+ style: { display: "block", width: "100%", height: "auto" }
19167
+ }
19168
+ ) : (
19169
+ // No resolved image (host couldn't resolve the raster) — keep the
19170
+ // aspect box so cards still make sense, but show nothing to overlay on.
19171
+ /* @__PURE__ */ jsxRuntime.jsxs(
19172
+ "div",
19173
+ {
19174
+ style: {
19175
+ width: "100%",
19176
+ aspectRatio: `${page.width_pt} / ${page.height_pt}`,
19177
+ background: PAPER2,
19178
+ display: "flex",
19179
+ alignItems: "center",
19180
+ justifyContent: "center",
19181
+ fontSize: "12px",
19182
+ color: MUTED2,
19183
+ lineHeight: 1.4
19184
+ },
19185
+ children: [
19186
+ "Page ",
19187
+ page.page + 1,
19188
+ " image unavailable"
19189
+ ]
19190
+ }
19191
+ )
19192
+ ),
19193
+ px && page.imageUrl && fields.map((f) => {
19194
+ var _a2;
19195
+ const rect = bboxToRect((_a2 = f.bbox) != null ? _a2 : null, pagePts, px);
19196
+ if (!rect) return null;
19197
+ const color = fieldColor2(f, secondary);
19198
+ const selected = selectedKey === f.field_key;
19199
+ return /* @__PURE__ */ jsxRuntime.jsx(
19200
+ "div",
19201
+ {
19202
+ ref: selected ? selectedBoxRef : null,
19203
+ "data-testid": "bbox-rect",
19204
+ "data-field-key": f.field_key,
19205
+ "data-selected": selected ? "true" : "false",
19206
+ onClick: () => onSelect(selected ? null : f.field_key),
19207
+ title: `${f.label}: ${f.value}`,
19208
+ style: {
19209
+ position: "absolute",
19210
+ left: `${rect.left}px`,
19211
+ top: `${rect.top}px`,
19212
+ width: `${rect.width}px`,
19213
+ height: `${rect.height}px`,
19214
+ border: `1px solid ${color}`,
19215
+ background: hexToRgba2(color, selected ? 0.28 : 0.12),
19216
+ boxShadow: selected ? `0 0 0 2px ${hexToRgba2(color, 0.5)}` : "none",
19217
+ borderRadius: "2px",
19218
+ cursor: "pointer",
19219
+ transition: "background 0.15s, box-shadow 0.15s"
19220
+ }
19221
+ },
19222
+ f.field_key
19223
+ );
19224
+ })
19225
+ ] });
19226
+ }
19227
+ function ExtractionDetail({
19228
+ pages,
19229
+ orderedFields,
19230
+ fieldsByPage,
19231
+ selectedKey,
19232
+ setSelectedKey,
19233
+ onFieldSave,
19234
+ correctionCounts,
19235
+ tab,
19236
+ setTab,
19237
+ editable,
19238
+ summary,
19239
+ fileName,
19240
+ pageCount,
19241
+ pagesProcessed,
19242
+ auditEvents,
19243
+ auditLoading
19244
+ }) {
19245
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
19246
+ const selectedCardRef = React45__default.default.useRef(null);
19247
+ React45__default.default.useEffect(() => {
19248
+ if (!selectedKey || tab !== "fields") return;
19249
+ const el = selectedCardRef.current;
19250
+ if (el && typeof el.scrollIntoView === "function") {
19251
+ el.scrollIntoView({ behavior: "smooth", block: "nearest" });
19252
+ }
19253
+ }, [selectedKey, tab]);
19254
+ const tabs = [
19255
+ { key: "details", label: "Details" },
19256
+ { key: "fields", label: "Fields", count: orderedFields.length }
19257
+ ];
19258
+ if (editable) tabs.push({ key: "audit", label: "Audit Trails", count: (auditEvents == null ? void 0 : auditEvents.length) || void 0 });
19259
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19260
+ "div",
19261
+ {
19262
+ style: {
19263
+ display: "grid",
19264
+ gridTemplateColumns: "minmax(0, 3fr) minmax(260px, 1fr)",
19265
+ gap: "12px",
19266
+ height: "100%",
19267
+ minHeight: 0
19268
+ },
19269
+ children: [
19270
+ /* @__PURE__ */ jsxRuntime.jsx(
19271
+ "div",
19272
+ {
19273
+ style: {
19274
+ display: "flex",
19275
+ flexDirection: "column",
19276
+ gap: "10px",
19277
+ borderRadius: "0.75rem",
19278
+ border: `1px solid ${BORDER4}`,
19279
+ overflowY: "auto",
19280
+ minHeight: 0
19281
+ },
19282
+ children: pages.map((pg) => /* @__PURE__ */ jsxRuntime.jsx(
19283
+ PageOverlay,
19284
+ {
19285
+ page: pg,
19286
+ fields: fieldsByPage(pg.page),
19287
+ selectedKey,
19288
+ onSelect: (key) => {
19289
+ setSelectedKey(key);
19290
+ if (key) setTab("fields");
19291
+ },
19292
+ secondary: SECONDARY2
19293
+ },
19294
+ pg.page
19295
+ ))
19296
+ }
19297
+ ),
19298
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", minWidth: 0, minHeight: 0 }, children: [
19299
+ /* @__PURE__ */ jsxRuntime.jsx(
19300
+ "div",
19301
+ {
19302
+ style: {
19303
+ display: "flex",
19304
+ gap: "16px",
19305
+ borderBottom: `1px solid ${BORDER4}`,
19306
+ flexShrink: 0,
19307
+ marginBottom: "10px"
19308
+ },
19309
+ children: tabs.map((t) => {
19310
+ const active = tab === t.key;
19311
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19312
+ "button",
19313
+ {
19314
+ type: "button",
19315
+ onClick: () => setTab(t.key),
19316
+ "data-testid": `tab-${t.key}`,
19317
+ style: {
19318
+ appearance: "none",
19319
+ background: "transparent",
19320
+ borderTop: "none",
19321
+ borderLeft: "none",
19322
+ borderRight: "none",
19323
+ borderBottom: `2px solid ${active ? SECONDARY2 : "transparent"}`,
19324
+ padding: "6px 2px",
19325
+ marginBottom: "-1px",
19326
+ cursor: "pointer",
19327
+ fontSize: "13px",
19328
+ fontWeight: 600,
19329
+ color: active ? SECONDARY2 : MUTED2,
19330
+ display: "inline-flex",
19331
+ alignItems: "center",
19332
+ gap: "6px"
19333
+ },
19334
+ children: [
19335
+ t.label,
19336
+ typeof t.count === "number" && /* @__PURE__ */ jsxRuntime.jsx(
19337
+ "span",
19338
+ {
19339
+ style: {
19340
+ fontSize: "11px",
19341
+ fontWeight: 600,
19342
+ padding: "1px 7px",
19343
+ borderRadius: "9999px",
19344
+ background: active ? "#eff6ff" : PAPER2,
19345
+ color: active ? SECONDARY2 : MUTED2
19346
+ },
19347
+ children: t.count
19348
+ }
19349
+ )
19350
+ ]
19351
+ },
19352
+ t.key
19353
+ );
19354
+ })
19355
+ }
19356
+ ),
19357
+ tab === "details" ? /* @__PURE__ */ jsxRuntime.jsx(
19358
+ FieldDetails,
19359
+ {
19360
+ summary,
19361
+ fileName,
19362
+ pageCount,
19363
+ pagesProcessed
19364
+ }
19365
+ ) : tab === "audit" ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { minHeight: 0, overflowY: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsx(
19366
+ FieldAuditLog,
19367
+ {
19368
+ events: auditEvents != null ? auditEvents : [],
19369
+ loading: auditLoading != null ? auditLoading : false,
19370
+ fields: orderedFields.map((f) => ({ field_key: f.field_key, label: f.label }))
19371
+ }
19372
+ ) }) : /* @__PURE__ */ jsxRuntime.jsxs(
19373
+ "div",
19374
+ {
19375
+ style: {
19376
+ display: "flex",
19377
+ flexDirection: "column",
19378
+ minHeight: 0,
19379
+ overflowY: "auto",
19380
+ paddingRight: "4px"
19381
+ },
19382
+ children: [
19383
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "12px", color: MUTED2, padding: "0 0 8px 2px", flexShrink: 0 }, children: [
19384
+ orderedFields.length,
19385
+ " extracted"
19386
+ ] }),
19387
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: orderedFields.map((f) => {
19388
+ var _a2;
19389
+ const selected = selectedKey === f.field_key;
19390
+ return /* @__PURE__ */ jsxRuntime.jsx(
19391
+ FieldDetail,
19392
+ {
19393
+ field: f,
19394
+ selected,
19395
+ onSelect: setSelectedKey,
19396
+ onSave: onFieldSave,
19397
+ correctionCount: (_a2 = correctionCounts == null ? void 0 : correctionCounts[f.field_key]) != null ? _a2 : 0,
19398
+ cardRef: selected ? selectedCardRef : void 0
19399
+ },
19400
+ f.field_key
19401
+ );
19402
+ }) })
19403
+ ]
19404
+ }
19405
+ )
19406
+ ] })
19407
+ ]
19408
+ }
19409
+ );
19410
+ }
19411
+ function ExtractionModal({
19412
+ open,
19413
+ onClose,
19414
+ title,
19415
+ children
19416
+ }) {
19417
+ const { BORDER: BORDER4, MUTED: MUTED2 } = useTheme();
19418
+ React45__default.default.useEffect(() => {
19419
+ if (!open) return;
19420
+ const onKey = (e) => {
19421
+ if (e.key === "Escape") onClose();
19422
+ };
19423
+ window.addEventListener("keydown", onKey);
19424
+ const prev = document.body.style.overflow;
19425
+ document.body.style.overflow = "hidden";
19426
+ return () => {
19427
+ window.removeEventListener("keydown", onKey);
19428
+ document.body.style.overflow = prev;
19429
+ };
19430
+ }, [open, onClose]);
19431
+ if (!open || typeof document === "undefined") return null;
19432
+ return reactDom.createPortal(
19433
+ /* @__PURE__ */ jsxRuntime.jsx(
19434
+ "div",
19435
+ {
19436
+ role: "dialog",
19437
+ "aria-modal": "true",
19438
+ "aria-label": title,
19439
+ onClick: onClose,
19440
+ style: {
19441
+ position: "fixed",
19442
+ inset: 0,
19443
+ zIndex: 2147483e3,
19444
+ background: "rgba(0,0,0,0.5)",
19445
+ display: "flex",
19446
+ alignItems: "center",
19447
+ justifyContent: "center",
19448
+ padding: "4vh 4vw",
19449
+ backdropFilter: "blur(2px)"
19450
+ },
19451
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
19452
+ "div",
19453
+ {
19454
+ onClick: (e) => e.stopPropagation(),
19455
+ style: {
19456
+ width: "90vw",
19457
+ height: "90vh",
19458
+ background: "white",
19459
+ borderRadius: "0.875rem",
19460
+ border: `1px solid ${BORDER4}`,
19461
+ boxShadow: "0 20px 60px rgba(0,0,0,0.30)",
19462
+ display: "flex",
19463
+ flexDirection: "column",
19464
+ overflow: "hidden"
19465
+ },
19466
+ children: [
19467
+ /* @__PURE__ */ jsxRuntime.jsxs(
19468
+ "div",
19469
+ {
19470
+ style: {
19471
+ display: "flex",
19472
+ alignItems: "center",
19473
+ gap: "10px",
19474
+ padding: "11px 16px",
19475
+ borderBottom: `1px solid ${BORDER4}`,
19476
+ flexShrink: 0
19477
+ },
19478
+ children: [
19479
+ /* @__PURE__ */ jsxRuntime.jsx(
19480
+ "span",
19481
+ {
19482
+ style: {
19483
+ flex: 1,
19484
+ minWidth: 0,
19485
+ fontFamily: "var(--font-serif)",
19486
+ fontSize: "16px",
19487
+ fontWeight: 400,
19488
+ letterSpacing: "-0.01em",
19489
+ color: "var(--foreground)",
19490
+ overflow: "hidden",
19491
+ textOverflow: "ellipsis",
19492
+ whiteSpace: "nowrap"
19493
+ },
19494
+ children: title
19495
+ }
19496
+ ),
19497
+ /* @__PURE__ */ jsxRuntime.jsx(
19498
+ "button",
19499
+ {
19500
+ type: "button",
19501
+ "aria-label": "Close",
19502
+ onClick: onClose,
19503
+ style: {
19504
+ border: `1px solid ${BORDER4}`,
19505
+ borderRadius: "8px",
19506
+ background: "white",
19507
+ cursor: "pointer",
19508
+ padding: "5px 9px",
19509
+ fontSize: "13px",
19510
+ color: MUTED2,
19511
+ lineHeight: 1
19512
+ },
19513
+ children: "\u2715"
19514
+ }
19515
+ )
19516
+ ]
19517
+ }
19518
+ ),
19519
+ /* @__PURE__ */ jsxRuntime.jsx(
19520
+ "div",
19521
+ {
19522
+ style: {
19523
+ flex: 1,
19524
+ minHeight: 0,
19525
+ overflow: "hidden",
19526
+ display: "flex",
19527
+ flexDirection: "column",
19528
+ padding: "14px 16px"
19529
+ },
19530
+ children
19531
+ }
19532
+ )
19533
+ ]
19534
+ }
19535
+ )
19536
+ }
19537
+ ),
19538
+ document.body
19539
+ );
19540
+ }
19541
+ function DocumentFieldExtractionResolver(p) {
19542
+ var _a2, _b;
19543
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2 } = useTheme();
19544
+ const [selectedKey, setSelectedKey] = React45__default.default.useState(null);
19545
+ const [open, setOpen] = React45__default.default.useState(false);
19546
+ const [tab, setTab] = React45__default.default.useState("fields");
19547
+ const pages = (_a2 = p.pages) != null ? _a2 : [];
19548
+ const fields = (_b = p.fields) != null ? _b : [];
19549
+ const editable = typeof p.onFieldSave === "function";
19550
+ const onLoadAudit = p.onLoadAudit;
19551
+ React45__default.default.useEffect(() => {
19552
+ if (tab === "audit" && onLoadAudit) {
19553
+ onLoadAudit();
19554
+ }
19555
+ }, [tab, onLoadAudit]);
19556
+ const correctionCounts = React45__default.default.useMemo(() => {
19557
+ var _a3, _b2;
19558
+ const counts = {};
19559
+ for (const ev of (_a3 = p.auditEvents) != null ? _a3 : []) {
19560
+ const human = ev.actor_type !== "system" && ev.event_type !== "ai_extracted";
19561
+ if (human) counts[ev.field_key] = ((_b2 = counts[ev.field_key]) != null ? _b2 : 0) + 1;
19562
+ }
19563
+ return counts;
19564
+ }, [p.auditEvents]);
19565
+ const orderedFields = [...fields].sort((a, b) => {
19566
+ var _a3, _b2;
19567
+ if (!!a.is_primary !== !!b.is_primary) return a.is_primary ? -1 : 1;
19568
+ return ((_a3 = b.confidence) != null ? _a3 : 0) - ((_b2 = a.confidence) != null ? _b2 : 0);
19569
+ });
19570
+ const fieldsByPage = (pageNo) => fields.filter((f) => f.page === pageNo);
19571
+ const csvCols = [
19572
+ { key: "label", label: "Field" },
19573
+ { key: "value", label: "Value" },
19574
+ { key: "page", label: "Page" },
19575
+ { key: "confidence", label: "Confidence" },
19576
+ { key: "badge", label: "Badge" },
19577
+ { key: "state", label: "State" }
19578
+ ];
19579
+ const csvRows = orderedFields.map((f) => {
19580
+ var _a3, _b2, _c;
19581
+ return {
19582
+ label: f.label,
19583
+ value: f.value,
19584
+ page: f.page + 1,
19585
+ confidence: (_a3 = f.confidence) != null ? _a3 : "",
19586
+ badge: (_b2 = f.badge) != null ? _b2 : "",
19587
+ state: (_c = f.state) != null ? _c : ""
19588
+ };
19589
+ });
19590
+ const title = p.file_name || (p.doc_type ? `${p.doc_type} \u2014 extracted fields` : "Extracted fields");
19591
+ const tierCounts = fields.reduce(
19592
+ (acc, f) => {
19593
+ var _a3;
19594
+ const t = (_a3 = f.confidence_tier) != null ? _a3 : "amber";
19595
+ if (t === "green") acc.high += 1;
19596
+ else if (t === "red") acc.low += 1;
19597
+ else acc.med += 1;
19598
+ return acc;
19599
+ },
19600
+ { high: 0, med: 0, low: 0 }
19601
+ );
19602
+ const chips = [
19603
+ { n: tierCounts.high, label: "high", color: TIER_COLORS2.green },
19604
+ { n: tierCounts.med, label: "medium", color: TIER_COLORS2.amber },
19605
+ { n: tierCounts.low, label: "low", color: TIER_COLORS2.red }
19606
+ ].filter((c) => c.n > 0);
19607
+ const thumb = pages.find((pg) => pg.imageUrl);
19608
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19609
+ ComponentActions,
19610
+ {
19611
+ filename: "document-fields",
19612
+ onDownloadCSV: () => downloadCSV(csvCols, csvRows, "document-fields"),
19613
+ children: [
19614
+ /* @__PURE__ */ jsxRuntime.jsxs(
19615
+ "div",
19616
+ {
19617
+ role: "button",
19618
+ tabIndex: 0,
19619
+ onClick: () => setOpen(true),
19620
+ onKeyDown: (e) => {
19621
+ if (e.key === "Enter" || e.key === " ") {
19622
+ e.preventDefault();
19623
+ setOpen(true);
19624
+ }
19625
+ },
19626
+ style: {
19627
+ display: "flex",
19628
+ alignItems: "stretch",
19629
+ gap: "12px",
19630
+ padding: "12px",
19631
+ width: "100%",
19632
+ maxWidth: "440px",
19633
+ borderRadius: "0.75rem",
19634
+ border: `1px solid ${BORDER4}`,
19635
+ background: "white",
19636
+ cursor: "pointer",
19637
+ textAlign: "left",
19638
+ boxShadow: "0 1px 2px rgba(0,0,0,0.03), 0 4px 12px rgba(0,0,0,0.05)"
19639
+ },
19640
+ children: [
19641
+ /* @__PURE__ */ jsxRuntime.jsx(
19642
+ "div",
19643
+ {
19644
+ style: {
19645
+ width: "64px",
19646
+ flexShrink: 0,
19647
+ borderRadius: "0.5rem",
19648
+ border: `1px solid ${BORDER4}`,
19649
+ background: PAPER2,
19650
+ overflow: "hidden",
19651
+ display: "flex",
19652
+ alignItems: "center",
19653
+ justifyContent: "center"
19654
+ },
19655
+ children: (thumb == null ? void 0 : thumb.imageUrl) ? /* @__PURE__ */ jsxRuntime.jsx(
19656
+ "img",
19657
+ {
19658
+ src: thumb.imageUrl,
19659
+ alt: "Document preview",
19660
+ style: { width: "100%", height: "auto", display: "block" }
19661
+ }
19662
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "22px", lineHeight: 1, padding: "16px 0" }, children: "\u{1F4C4}" })
19663
+ }
19664
+ ),
19665
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "6px" }, children: [
19666
+ /* @__PURE__ */ jsxRuntime.jsx(
19667
+ "p",
19668
+ {
19669
+ style: {
19670
+ fontFamily: "var(--font-serif)",
19671
+ fontSize: "15px",
19672
+ fontWeight: 400,
19673
+ color: "var(--foreground)",
19674
+ letterSpacing: "-0.01em",
19675
+ margin: 0,
19676
+ overflow: "hidden",
19677
+ textOverflow: "ellipsis",
19678
+ whiteSpace: "nowrap"
19679
+ },
19680
+ children: p.file_name || p.doc_type || "Document"
19681
+ }
19682
+ ),
19683
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "12px", color: MUTED2 }, children: [
19684
+ fields.length,
19685
+ " field",
19686
+ fields.length === 1 ? "" : "s",
19687
+ " extracted \xB7 ",
19688
+ pages.length,
19689
+ " page",
19690
+ pages.length === 1 ? "" : "s"
19691
+ ] }),
19692
+ chips.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: "5px" }, children: chips.map((c) => /* @__PURE__ */ jsxRuntime.jsxs(
19693
+ "span",
19694
+ {
19695
+ style: {
19696
+ display: "inline-flex",
19697
+ alignItems: "center",
19698
+ gap: "4px",
19699
+ fontSize: "10px",
19700
+ fontWeight: 600,
19701
+ padding: "2px 7px",
19702
+ borderRadius: "9999px",
19703
+ background: hexToRgba2(c.color, 0.12),
19704
+ color: c.color
19705
+ },
19706
+ children: [
19707
+ /* @__PURE__ */ jsxRuntime.jsx(
19708
+ "span",
19709
+ {
19710
+ style: {
19711
+ width: "6px",
19712
+ height: "6px",
19713
+ borderRadius: "9999px",
19714
+ background: c.color
19715
+ }
19716
+ }
19717
+ ),
19718
+ c.n,
19719
+ " ",
19720
+ c.label
19721
+ ]
19722
+ },
19723
+ c.label
19724
+ )) }),
19725
+ /* @__PURE__ */ jsxRuntime.jsx(
19726
+ "span",
19727
+ {
19728
+ style: {
19729
+ marginTop: "2px",
19730
+ alignSelf: "flex-start",
19731
+ fontSize: "12px",
19732
+ fontWeight: 600,
19733
+ padding: "6px 12px",
19734
+ borderRadius: "0.5rem",
19735
+ background: "var(--foreground)",
19736
+ color: "white"
19737
+ },
19738
+ children: "View & edit fields"
19739
+ }
19740
+ )
19741
+ ] })
19742
+ ]
19743
+ }
19744
+ ),
19745
+ /* @__PURE__ */ jsxRuntime.jsx(ExtractionModal, { open, onClose: () => setOpen(false), title, children: /* @__PURE__ */ jsxRuntime.jsx(
19746
+ ExtractionDetail,
19747
+ {
19748
+ pages,
19749
+ orderedFields,
19750
+ fieldsByPage,
19751
+ selectedKey,
19752
+ setSelectedKey,
19753
+ onFieldSave: p.onFieldSave,
19754
+ correctionCounts,
19755
+ tab,
19756
+ setTab,
19757
+ editable,
19758
+ summary: p.summary,
19759
+ fileName: p.file_name,
19760
+ pageCount: p.page_count,
19761
+ pagesProcessed: p.pages_processed,
19762
+ auditEvents: p.auditEvents,
19763
+ auditLoading: p.auditLoading
19764
+ }
19765
+ ) })
19766
+ ]
19767
+ }
19768
+ );
19769
+ }
19770
+ function DocumentFieldExtractionSkeleton() {
19771
+ const { BORDER: BORDER4, PAPER: PAPER2 } = useTheme();
19772
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19773
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
19774
+ @keyframes dfeSkeletonPulse {
19775
+ 0%, 100% { opacity: 1; }
19776
+ 50% { opacity: 0.45; }
19777
+ }
19778
+ ` }),
19779
+ /* @__PURE__ */ jsxRuntime.jsxs(
19780
+ "div",
19781
+ {
19782
+ "aria-busy": "true",
19783
+ "aria-label": "Loading extracted document",
19784
+ style: {
19785
+ display: "flex",
19786
+ alignItems: "stretch",
19787
+ gap: "12px",
19788
+ padding: "12px",
19789
+ width: "100%",
19790
+ maxWidth: "440px",
19791
+ borderRadius: "0.75rem",
19792
+ border: `1px solid ${BORDER4}`,
19793
+ background: "white",
19794
+ boxShadow: "0 1px 2px rgba(0,0,0,0.03), 0 4px 12px rgba(0,0,0,0.05)"
19795
+ },
19796
+ children: [
19797
+ /* @__PURE__ */ jsxRuntime.jsx(
19798
+ "div",
19799
+ {
19800
+ style: {
19801
+ width: "64px",
19802
+ flexShrink: 0,
19803
+ borderRadius: "0.5rem",
19804
+ border: `1px solid ${BORDER4}`,
19805
+ background: PAPER2,
19806
+ minHeight: "82px",
19807
+ animation: "dfeSkeletonPulse 1.6s ease-in-out infinite"
19808
+ }
19809
+ }
19810
+ ),
19811
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "8px", paddingTop: "2px" }, children: [
19812
+ /* @__PURE__ */ jsxRuntime.jsx(
19813
+ "div",
19814
+ {
19815
+ style: {
19816
+ height: "14px",
19817
+ width: "65%",
19818
+ borderRadius: "4px",
19819
+ background: PAPER2,
19820
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.08s infinite"
19821
+ }
19822
+ }
19823
+ ),
19824
+ /* @__PURE__ */ jsxRuntime.jsx(
19825
+ "div",
19826
+ {
19827
+ style: {
19828
+ height: "11px",
19829
+ width: "45%",
19830
+ borderRadius: "4px",
19831
+ background: PAPER2,
19832
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.14s infinite"
19833
+ }
19834
+ }
19835
+ ),
19836
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "5px" }, children: [
19837
+ /* @__PURE__ */ jsxRuntime.jsx(
19838
+ "div",
19839
+ {
19840
+ style: {
19841
+ height: "18px",
19842
+ width: "66px",
19843
+ borderRadius: "9999px",
19844
+ background: PAPER2,
19845
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.2s infinite"
19846
+ }
19847
+ }
19848
+ ),
19849
+ /* @__PURE__ */ jsxRuntime.jsx(
19850
+ "div",
19851
+ {
19852
+ style: {
19853
+ height: "18px",
19854
+ width: "56px",
19855
+ borderRadius: "9999px",
19856
+ background: PAPER2,
19857
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.25s infinite"
19858
+ }
19859
+ }
19860
+ )
19861
+ ] }),
19862
+ /* @__PURE__ */ jsxRuntime.jsx(
19863
+ "div",
19864
+ {
19865
+ style: {
19866
+ height: "28px",
19867
+ width: "122px",
19868
+ borderRadius: "0.5rem",
19869
+ background: PAPER2,
19870
+ marginTop: "2px",
19871
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.3s infinite"
19872
+ }
19873
+ }
19874
+ )
19875
+ ] })
19876
+ ]
19877
+ }
19878
+ )
19879
+ ] });
19880
+ }
19881
+ init_ThemeContext();
19882
+ var SEVERITY_COLORS = {
19883
+ high: { color: "#dc2626", bg: "#fef2f2" },
19884
+ medium: { color: "#f59e0b", bg: "#fff7ed" },
19885
+ low: { color: "#777777", bg: "#f2f2f2" }
19886
+ };
19887
+ var GREEN3 = "#15803d";
19888
+ var GREEN_SOFT = "#dcfce7";
19889
+ var STACK_BELOW = 380;
19890
+ function formatAmount2(amount, currency = "USD") {
19891
+ var _a2, _b;
19892
+ const abs = Math.abs(amount);
19893
+ const sign = amount < 0 ? "-" : "";
19894
+ let body;
19895
+ if (abs >= 1e6) body = `${(abs / 1e6).toFixed(abs >= 1e7 ? 0 : 1)}M`;
19896
+ else if (abs >= 1e3) body = `${(abs / 1e3).toFixed(abs >= 1e4 ? 0 : 1)}K`;
19897
+ else body = `${abs}`;
19898
+ let symbol = "$";
19899
+ try {
19900
+ const parts = new Intl.NumberFormat("en-US", {
19901
+ style: "currency",
19902
+ currency,
19903
+ maximumFractionDigits: 0
19904
+ }).formatToParts(0);
19905
+ symbol = (_b = (_a2 = parts.find((p) => p.type === "currency")) == null ? void 0 : _a2.value) != null ? _b : "$";
19906
+ } catch (e) {
19907
+ symbol = "$";
19908
+ }
19909
+ return `${sign}${symbol}${body}`;
19910
+ }
19911
+ function useContainerWidth2(ref) {
19912
+ const [w, setW] = React45__default.default.useState(0);
19913
+ React45__default.default.useLayoutEffect(() => {
19914
+ const el = ref.current;
19915
+ if (!el || typeof ResizeObserver === "undefined") return;
19916
+ const ro = new ResizeObserver((entries) => {
19917
+ var _a2;
19918
+ const cr = (_a2 = entries[0]) == null ? void 0 : _a2.contentRect;
19919
+ if (cr) setW(cr.width);
19920
+ });
19921
+ ro.observe(el);
19922
+ setW(el.getBoundingClientRect().width);
19923
+ return () => ro.disconnect();
19924
+ }, [ref]);
19925
+ return w;
19926
+ }
19927
+ var KEYFRAMES2 = `
19928
+ @keyframes dcRise{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
19929
+ .dc-rise{animation:dcRise 0.28s cubic-bezier(0.22,1,0.36,1) both}
19930
+ @media (prefers-reduced-motion: reduce){
19931
+ .dc-rise{animation:none !important;opacity:1 !important;transform:none !important}
19932
+ }`;
19933
+ function SparkCheck({ size, color }) {
19934
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
19935
+ "path",
19936
+ {
19937
+ d: "M5 13l4 4L19 7",
19938
+ stroke: color,
19939
+ strokeWidth: 2.5,
19940
+ strokeLinecap: "round",
19941
+ strokeLinejoin: "round"
19942
+ }
19943
+ ) });
19944
+ }
19945
+ function FlagPill({ flag }) {
19946
+ var _a2;
19947
+ const sev = (_a2 = flag.severity) != null ? _a2 : "medium";
19948
+ const { color, bg } = SEVERITY_COLORS[sev];
19949
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19950
+ "span",
19951
+ {
19952
+ style: {
19953
+ display: "inline-flex",
19954
+ alignItems: "center",
19955
+ gap: 5,
19956
+ fontSize: 11,
19957
+ fontWeight: 600,
19958
+ padding: "3px 9px",
19959
+ borderRadius: 9999,
19960
+ background: bg,
19961
+ color,
19962
+ lineHeight: 1.2
19963
+ },
19964
+ children: [
19965
+ /* @__PURE__ */ jsxRuntime.jsx(
19966
+ "span",
19967
+ {
19968
+ "aria-hidden": "true",
19969
+ style: { width: 6, height: 6, borderRadius: "50%", background: color, flexShrink: 0 }
19970
+ }
19971
+ ),
19972
+ flag.field ? `${flag.field}: ${flag.issue}` : flag.issue
19973
+ ]
19974
+ }
19975
+ );
19976
+ }
19977
+ function DecisionCardRenderer({
19978
+ data,
19979
+ resolved = null,
19980
+ onResolve,
19981
+ onOpenSource
19982
+ }) {
19983
+ var _a2, _b;
19984
+ const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
19985
+ const rootRef = React45__default.default.useRef(null);
19986
+ const width = useContainerWidth2(rootRef);
19987
+ const stacked = width > 0 && width < STACK_BELOW;
19988
+ const options = (_a2 = data.options) != null ? _a2 : [];
19989
+ const recommendedIdx = Math.max(
19990
+ 0,
19991
+ options.findIndex((o) => o.recommended)
19992
+ );
19993
+ const railColor = data.severity ? SEVERITY_COLORS[data.severity].color : ACCENT2;
19994
+ const isResolved = Boolean(resolved);
19995
+ const amountNode = typeof data.amount === "number" ? /* @__PURE__ */ jsxRuntime.jsxs(
19996
+ "div",
19997
+ {
19998
+ style: {
19999
+ display: "flex",
20000
+ flexDirection: "column",
20001
+ alignItems: stacked ? "flex-start" : "flex-end",
20002
+ gap: 1,
20003
+ flexShrink: 0
20004
+ },
20005
+ children: [
20006
+ data.amount_label && /* @__PURE__ */ jsxRuntime.jsx(
20007
+ "span",
20008
+ {
20009
+ style: {
20010
+ fontSize: 10,
20011
+ textTransform: "uppercase",
20012
+ letterSpacing: "0.07em",
20013
+ fontWeight: 700,
20014
+ color: MUTED2
20015
+ },
20016
+ children: data.amount_label
20017
+ }
20018
+ ),
20019
+ /* @__PURE__ */ jsxRuntime.jsx(
20020
+ "span",
20021
+ {
20022
+ style: {
20023
+ fontSize: 18,
20024
+ fontWeight: 700,
20025
+ color: "var(--foreground)",
20026
+ fontVariantNumeric: "tabular-nums",
20027
+ letterSpacing: "-0.01em",
20028
+ lineHeight: 1.1
20029
+ },
20030
+ children: formatAmount2(data.amount, data.currency)
20031
+ }
20032
+ )
20033
+ ]
20034
+ }
20035
+ ) : null;
20036
+ return /* @__PURE__ */ jsxRuntime.jsxs(
20037
+ "div",
20038
+ {
20039
+ ref: rootRef,
20040
+ className: "dc-rise",
20041
+ "data-testid": "decision-card",
20042
+ "data-resolved": isResolved || void 0,
20043
+ style: {
20044
+ position: "relative",
20045
+ width: "100%",
20046
+ minWidth: 0,
20047
+ boxSizing: "border-box",
20048
+ borderRadius: "0.75rem",
20049
+ border: `1px solid ${isResolved ? GREEN_SOFT : BORDER4}`,
20050
+ background: isResolved ? "#f6fef9" : "white",
20051
+ boxShadow: "0 1px 2px rgba(0,0,0,0.03), 0 4px 12px rgba(0,0,0,0.04)",
20052
+ padding: "16px 18px 16px 20px",
20053
+ display: "flex",
20054
+ flexDirection: "column",
20055
+ gap: 12,
20056
+ overflow: "hidden"
20057
+ },
20058
+ children: [
20059
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: KEYFRAMES2 }),
20060
+ /* @__PURE__ */ jsxRuntime.jsx(
20061
+ "div",
20062
+ {
20063
+ "aria-hidden": "true",
20064
+ style: {
20065
+ position: "absolute",
20066
+ top: 0,
20067
+ left: 0,
20068
+ bottom: 0,
20069
+ width: 4,
20070
+ background: isResolved ? GREEN3 : railColor
20071
+ }
20072
+ }
20073
+ ),
20074
+ /* @__PURE__ */ jsxRuntime.jsxs(
20075
+ "div",
20076
+ {
20077
+ style: {
20078
+ display: "flex",
20079
+ flexDirection: stacked ? "column" : "row",
20080
+ alignItems: stacked ? "flex-start" : "flex-start",
20081
+ justifyContent: "space-between",
20082
+ gap: stacked ? 6 : 12
20083
+ },
20084
+ children: [
20085
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { minWidth: 0, display: "flex", flexDirection: "column", gap: 4 }, children: [
20086
+ /* @__PURE__ */ jsxRuntime.jsx(
20087
+ "span",
20088
+ {
20089
+ style: {
20090
+ fontSize: 10.5,
20091
+ textTransform: "uppercase",
20092
+ letterSpacing: "0.07em",
20093
+ fontWeight: 700,
20094
+ color: ACCENT2
20095
+ },
20096
+ children: data.decision_type ? `Decision needs you \xB7 ${data.decision_type}` : "Decision needs you"
20097
+ }
20098
+ ),
20099
+ /* @__PURE__ */ jsxRuntime.jsx(
20100
+ "p",
20101
+ {
20102
+ style: {
20103
+ fontFamily: "var(--font-serif)",
20104
+ fontSize: 17,
20105
+ fontWeight: 400,
20106
+ color: "var(--foreground)",
20107
+ letterSpacing: "-0.01em",
20108
+ margin: 0,
20109
+ lineHeight: 1.2
20110
+ },
20111
+ children: data.title
20112
+ }
20113
+ )
20114
+ ] }),
20115
+ amountNode
20116
+ ]
20117
+ }
20118
+ ),
20119
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: 13, lineHeight: 1.5, color: MUTED2, margin: 0 }, children: data.question }),
20120
+ data.flags && data.flags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 }, children: data.flags.map((flag, i) => {
20121
+ var _a3;
20122
+ return /* @__PURE__ */ jsxRuntime.jsx(FlagPill, { flag }, `${(_a3 = flag.field) != null ? _a3 : "flag"}-${i}`);
20123
+ }) }),
20124
+ isResolved ? /* @__PURE__ */ jsxRuntime.jsxs(
20125
+ "div",
20126
+ {
20127
+ style: {
20128
+ display: "inline-flex",
20129
+ alignItems: "center",
20130
+ gap: 7,
20131
+ fontSize: 13,
20132
+ fontWeight: 600,
20133
+ color: GREEN3
20134
+ },
20135
+ children: [
20136
+ /* @__PURE__ */ jsxRuntime.jsx(SparkCheck, { size: 16, color: GREEN3 }),
20137
+ "Resolved \xB7 ",
20138
+ resolved
20139
+ ]
20140
+ }
20141
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
20142
+ /* @__PURE__ */ jsxRuntime.jsx(
20143
+ "div",
20144
+ {
20145
+ style: {
20146
+ display: "flex",
20147
+ flexDirection: stacked ? "column" : "row",
20148
+ flexWrap: stacked ? "nowrap" : "wrap",
20149
+ gap: 8
20150
+ },
20151
+ children: options.map((opt, idx) => {
20152
+ var _a3;
20153
+ const primary = idx === recommendedIdx;
20154
+ return /* @__PURE__ */ jsxRuntime.jsx(
20155
+ "button",
20156
+ {
20157
+ type: "button",
20158
+ onClick: () => onResolve == null ? void 0 : onResolve(opt.label),
20159
+ style: {
20160
+ width: stacked ? "100%" : "auto",
20161
+ textAlign: stacked ? "left" : "center",
20162
+ border: `1px solid ${primary ? ACCENT2 : BORDER4}`,
20163
+ background: primary ? ACCENT2 : "white",
20164
+ color: primary ? "white" : "var(--foreground)",
20165
+ borderRadius: 8,
20166
+ fontSize: 13,
20167
+ fontWeight: 600,
20168
+ padding: "9px 14px",
20169
+ cursor: "pointer",
20170
+ transition: "background 0.15s, border-color 0.15s, color 0.15s"
20171
+ },
20172
+ onMouseEnter: (e) => {
20173
+ if (primary) {
20174
+ e.currentTarget.style.background = ACCENT_SOFT2;
20175
+ } else {
20176
+ e.currentTarget.style.borderColor = ACCENT2;
20177
+ e.currentTarget.style.background = "#fafafa";
20178
+ }
20179
+ },
20180
+ onMouseLeave: (e) => {
20181
+ if (primary) {
20182
+ e.currentTarget.style.background = ACCENT2;
20183
+ } else {
20184
+ e.currentTarget.style.borderColor = BORDER4;
20185
+ e.currentTarget.style.background = "white";
20186
+ }
20187
+ },
20188
+ children: opt.label
20189
+ },
20190
+ (_a3 = opt.id) != null ? _a3 : opt.label
20191
+ );
20192
+ })
20193
+ }
20194
+ ),
20195
+ data.source && /* @__PURE__ */ jsxRuntime.jsxs(
20196
+ "button",
20197
+ {
20198
+ type: "button",
20199
+ onClick: onOpenSource,
20200
+ style: {
20201
+ alignSelf: "flex-start",
20202
+ display: "inline-flex",
20203
+ alignItems: "center",
20204
+ gap: 5,
20205
+ border: "none",
20206
+ background: "none",
20207
+ padding: 0,
20208
+ cursor: "pointer",
20209
+ fontSize: 12,
20210
+ fontWeight: 600,
20211
+ color: MUTED2,
20212
+ transition: "color 0.15s"
20213
+ },
20214
+ onMouseEnter: (e) => e.currentTarget.style.color = ACCENT2,
20215
+ onMouseLeave: (e) => e.currentTarget.style.color = MUTED2,
20216
+ children: [
20217
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 13, height: 13, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
20218
+ "path",
20219
+ {
20220
+ d: "M14 3v4a1 1 0 001 1h4M5 4a1 1 0 011-1h8l5 5v11a1 1 0 01-1 1H6a1 1 0 01-1-1V4z",
20221
+ stroke: "currentColor",
20222
+ strokeWidth: 1.8,
20223
+ strokeLinecap: "round",
20224
+ strokeLinejoin: "round"
20225
+ }
20226
+ ) }),
20227
+ (_b = data.source.label) != null ? _b : "View source for this figure"
20228
+ ]
20229
+ }
20230
+ )
20231
+ ] })
20232
+ ]
20233
+ }
20234
+ );
20235
+ }
20236
+ function DecisionCardResolver(p) {
20237
+ var _a2, _b, _c, _d;
20238
+ const { resolvedDecisions, onDecisionResolve, onDecisionSource } = useGenUIInteraction();
20239
+ const decisionId = (_a2 = p.id) != null ? _a2 : p.title;
20240
+ const hostResolved = resolvedDecisions == null ? void 0 : resolvedDecisions[decisionId];
20241
+ const initial = (_c = hostResolved != null ? hostResolved : (_b = p.resolved) == null ? void 0 : _b.option) != null ? _c : null;
20242
+ const [localResolved, setLocalResolved] = React45__default.default.useState(initial);
20243
+ React45__default.default.useEffect(() => {
20244
+ if (hostResolved !== void 0) setLocalResolved(hostResolved);
20245
+ }, [hostResolved]);
20246
+ const resolved = hostResolved != null ? hostResolved : localResolved;
20247
+ const handleResolve = (option) => {
20248
+ setLocalResolved(option);
20249
+ onDecisionResolve == null ? void 0 : onDecisionResolve(decisionId, option);
20250
+ };
20251
+ const handleSource = () => {
20252
+ var _a3;
20253
+ onDecisionSource == null ? void 0 : onDecisionSource(decisionId, p.source);
20254
+ if (!onDecisionSource && ((_a3 = p.source) == null ? void 0 : _a3.url) && typeof window !== "undefined") {
20255
+ window.open(p.source.url, "_blank", "noopener,noreferrer");
20256
+ }
20257
+ };
20258
+ return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_d = p.title) != null ? _d : "decision-card", children: /* @__PURE__ */ jsxRuntime.jsx(
20259
+ DecisionCardRenderer,
20260
+ {
20261
+ data: p,
20262
+ resolved,
20263
+ onResolve: handleResolve,
20264
+ onOpenSource: handleSource
20265
+ }
20266
+ ) });
20267
+ }
20268
+ function resolveUI(rawPayload) {
20269
+ const payload = coercePayload(rawPayload);
20270
+ switch (payload.type) {
20271
+ case "data-table":
20272
+ return /* @__PURE__ */ jsxRuntime.jsx(DataTableResolver, __spreadValues({}, payload));
20273
+ case "status-card":
20274
+ return /* @__PURE__ */ jsxRuntime.jsx(StatusCardResolver, __spreadValues({}, payload));
20275
+ case "alert":
20276
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertResolver, __spreadValues({}, payload));
20277
+ case "stat-grid":
20278
+ return /* @__PURE__ */ jsxRuntime.jsx(StatGridResolver, __spreadValues({}, payload));
20279
+ case "tabs-panel":
20280
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsPanelResolver, __spreadValues({}, payload));
20281
+ case "sparkline-table":
20282
+ return /* @__PURE__ */ jsxRuntime.jsx(SparklineTableResolver, __spreadValues({}, payload));
20283
+ case "heatmap-table":
20284
+ return /* @__PURE__ */ jsxRuntime.jsx(HeatmapTableResolver, __spreadValues({}, payload));
20285
+ case "screener-table":
20286
+ return /* @__PURE__ */ jsxRuntime.jsx(ScreenerTableResolver, __spreadValues({}, payload));
20287
+ case "grouped-table":
20288
+ return /* @__PURE__ */ jsxRuntime.jsx(GroupedTableResolver, __spreadValues({}, payload));
20289
+ case "news-feed":
20290
+ return /* @__PURE__ */ jsxRuntime.jsx(NewsFeedResolver, __spreadValues({}, payload));
20291
+ case "area-chart":
20292
+ return /* @__PURE__ */ jsxRuntime.jsx(AreaChartResolver, __spreadValues({}, payload));
20293
+ case "allocation-donut":
20294
+ return /* @__PURE__ */ jsxRuntime.jsx(AllocationDonutResolver, __spreadValues({}, payload));
20295
+ case "waterfall-chart":
20296
+ return /* @__PURE__ */ jsxRuntime.jsx(WaterfallChartResolver, __spreadValues({}, payload));
20297
+ case "flow-canvas":
20298
+ return /* @__PURE__ */ jsxRuntime.jsx(FlowCanvasResolver, __spreadValues({}, payload));
20299
+ case "trial-balance":
20300
+ return /* @__PURE__ */ jsxRuntime.jsx(TrialBalanceResolver, __spreadValues({}, payload));
20301
+ case "journal-entry":
20302
+ return /* @__PURE__ */ jsxRuntime.jsx(JournalEntryResolver, __spreadValues({}, payload));
20303
+ case "aging-report":
20304
+ return /* @__PURE__ */ jsxRuntime.jsx(AgingReportResolver, __spreadValues({}, payload));
20305
+ case "variance-analysis":
20306
+ return /* @__PURE__ */ jsxRuntime.jsx(VarianceAnalysisResolver, __spreadValues({}, payload));
20307
+ case "stacked-breakdown":
20308
+ return /* @__PURE__ */ jsxRuntime.jsx(StackedBreakdownResolver, __spreadValues({}, payload));
20309
+ case "comparative-bar-chart":
20310
+ return /* @__PURE__ */ jsxRuntime.jsx(ComparativeBarChartResolver, __spreadValues({}, payload));
20311
+ case "compliance-checklist":
20312
+ return /* @__PURE__ */ jsxRuntime.jsx(ComplianceChecklistResolver, __spreadValues({}, payload));
20313
+ case "reconciliation-view":
20314
+ return /* @__PURE__ */ jsxRuntime.jsx(ReconciliationViewResolver, __spreadValues({}, payload));
20315
+ case "audit-trail":
20316
+ return /* @__PURE__ */ jsxRuntime.jsx(AuditTrailResolver, __spreadValues({}, payload));
20317
+ case "document-preview":
20318
+ return /* @__PURE__ */ jsxRuntime.jsx(DocumentPreviewResolver, __spreadValues({}, payload));
20319
+ case "provenance-chain":
20320
+ return /* @__PURE__ */ jsxRuntime.jsx(ProvenanceChainResolver, __spreadValues({}, payload));
20321
+ case "search-results":
20322
+ return /* @__PURE__ */ jsxRuntime.jsx(SearchResultsResolver, __spreadValues({}, payload));
20323
+ case "legal-test-result":
20324
+ return /* @__PURE__ */ jsxRuntime.jsx(LegalTestResultResolver, __spreadValues({}, payload));
20325
+ case "engagement-pipeline":
20326
+ return /* @__PURE__ */ jsxRuntime.jsx(EngagementPipelineResolver, __spreadValues({}, payload));
20327
+ case "entity-card-grid":
20328
+ return /* @__PURE__ */ jsxRuntime.jsx(EntityCardGridResolver, __spreadValues({}, payload));
20329
+ case "job-tracker":
20330
+ return /* @__PURE__ */ jsxRuntime.jsx(JobTrackerResolver, __spreadValues({}, payload));
20331
+ case "cited-answer":
20332
+ return /* @__PURE__ */ jsxRuntime.jsx(CitedAnswerResolver, __spreadValues({}, payload));
20333
+ case "transaction-feed":
20334
+ return /* @__PURE__ */ jsxRuntime.jsx(TransactionFeedResolver, __spreadValues({}, payload));
20335
+ case "file-browser":
20336
+ return /* @__PURE__ */ jsxRuntime.jsx(FileBrowserResolver, __spreadValues({}, payload));
20337
+ case "download-card":
20338
+ return /* @__PURE__ */ jsxRuntime.jsx(DownloadCardResolver, __spreadValues({}, payload));
20339
+ case "ops-dashboard":
20340
+ return /* @__PURE__ */ jsxRuntime.jsx(OpsDashboardResolver, __spreadValues({}, payload));
20341
+ case "key-value-list":
20342
+ return /* @__PURE__ */ jsxRuntime.jsx(KeyValueListResolver, __spreadValues({}, payload));
20343
+ case "balance-sheet":
20344
+ return /* @__PURE__ */ jsxRuntime.jsx(BalanceSheetResolver, __spreadValues({}, payload));
20345
+ case "income-statement":
20346
+ return /* @__PURE__ */ jsxRuntime.jsx(IncomeStatementResolver, __spreadValues({}, payload));
20347
+ case "cash-flow-statement":
20348
+ return /* @__PURE__ */ jsxRuntime.jsx(CashFlowStatementResolver, __spreadValues({}, payload));
20349
+ case "general-ledger":
20350
+ return /* @__PURE__ */ jsxRuntime.jsx(GeneralLedgerResolver, __spreadValues({}, payload));
20351
+ case "chart-of-accounts":
20352
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartOfAccountsResolver, __spreadValues({}, payload));
20353
+ case "invoice-detail":
20354
+ return /* @__PURE__ */ jsxRuntime.jsx(InvoiceDetailResolver, __spreadValues({}, payload));
20355
+ case "amortization-table":
20356
+ return /* @__PURE__ */ jsxRuntime.jsx(AmortizationTableResolver, __spreadValues({}, payload));
20357
+ case "depreciation-schedule":
20358
+ return /* @__PURE__ */ jsxRuntime.jsx(DepreciationScheduleResolver, __spreadValues({}, payload));
20359
+ case "escalation-card":
20360
+ return /* @__PURE__ */ jsxRuntime.jsx(EscalationCardResolver, __spreadValues({}, payload));
20361
+ case "line-chart":
20362
+ return /* @__PURE__ */ jsxRuntime.jsx(LineChartResolver, __spreadValues({}, payload));
20363
+ case "combo-chart":
20364
+ return /* @__PURE__ */ jsxRuntime.jsx(ComboChartResolver, __spreadValues({}, payload));
20365
+ case "gauge-chart":
20366
+ return /* @__PURE__ */ jsxRuntime.jsx(GaugeChartResolver, __spreadValues({}, payload));
20367
+ case "treemap-chart":
20368
+ return /* @__PURE__ */ jsxRuntime.jsx(TreemapChartResolver, __spreadValues({}, payload));
20369
+ case "radar-chart":
20370
+ return /* @__PURE__ */ jsxRuntime.jsx(RadarChartResolver, __spreadValues({}, payload));
20371
+ case "funnel-chart":
20372
+ return /* @__PURE__ */ jsxRuntime.jsx(FunnelChartResolver, __spreadValues({}, payload));
20373
+ case "bullet-chart":
20374
+ return /* @__PURE__ */ jsxRuntime.jsx(BulletChartResolver, __spreadValues({}, payload));
20375
+ case "scatter-chart":
20376
+ return /* @__PURE__ */ jsxRuntime.jsx(ScatterChartResolver, __spreadValues({}, payload));
20377
+ case "connect-integration":
20378
+ return /* @__PURE__ */ jsxRuntime.jsx(ConnectIntegrationResolver, __spreadValues({}, payload));
20379
+ case "integrations-list":
20380
+ return /* @__PURE__ */ jsxRuntime.jsx(IntegrationsListResolver, __spreadValues({}, payload));
20381
+ case "pipeline-preview":
20382
+ return /* @__PURE__ */ jsxRuntime.jsx(PipelinePreviewResolver, __spreadValues({}, payload));
20383
+ case "workflow-stepper":
20384
+ return /* @__PURE__ */ jsxRuntime.jsx(WorkflowStepperResolver, __spreadValues({}, payload));
20385
+ case "document-field-extraction":
20386
+ return /* @__PURE__ */ jsxRuntime.jsx(DocumentFieldExtractionResolver, __spreadValues({}, payload));
20387
+ case "decision-card":
20388
+ return /* @__PURE__ */ jsxRuntime.jsx(DecisionCardResolver, __spreadValues({}, payload));
20389
+ default: {
20390
+ return /* @__PURE__ */ jsxRuntime.jsx(
20391
+ "div",
20392
+ {
20393
+ role: "alert",
20394
+ style: {
20395
+ padding: "12px 16px",
20396
+ border: "1px solid #dc2626",
20397
+ borderRadius: "8px",
20398
+ background: "#fef2f2",
20399
+ color: "#dc2626",
20400
+ fontSize: "13px",
20401
+ fontWeight: 600
20402
+ },
20403
+ children: "Unknown UI type"
20404
+ }
20405
+ );
20406
+ }
20407
+ }
20408
+ }
20409
+ function InlineSpinner() {
18067
20410
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18068
20411
  /* @__PURE__ */ jsxRuntime.jsx("style", { children: `@keyframes genui-spin{to{transform:rotate(360deg)}}` }),
18069
20412
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -18084,7 +20427,7 @@ function InlineSpinner() {
18084
20427
  }
18085
20428
  function GenUIRenderer({ payload }) {
18086
20429
  return /* @__PURE__ */ jsxRuntime.jsx(
18087
- React41.Suspense,
20430
+ React45.Suspense,
18088
20431
  {
18089
20432
  fallback: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", padding: "8px 0" }, children: [
18090
20433
  /* @__PURE__ */ jsxRuntime.jsx(InlineSpinner, {}),
@@ -18225,7 +20568,7 @@ var INPUT_ERROR = { borderColor: "#dc2626" };
18225
20568
  var SELECT_EXTRA = { cursor: "pointer" };
18226
20569
  function useInputBase() {
18227
20570
  const { BORDER: BORDER4 } = useTheme();
18228
- return React41.useMemo(() => ({
20571
+ return React45.useMemo(() => ({
18229
20572
  font: "inherit",
18230
20573
  fontSize: "13px",
18231
20574
  padding: "7px 10px",
@@ -18306,7 +20649,7 @@ function SelectField({ field, value, onChange, disabled, error }) {
18306
20649
  }
18307
20650
  function MultiSelectField({ field, value, onChange, disabled }) {
18308
20651
  const { MUTED: MUTED2, ACCENT: ACCENT2, BORDER: BORDER4 } = useTheme();
18309
- const [hovered, setHovered] = React41.useState(null);
20652
+ const [hovered, setHovered] = React45.useState(null);
18310
20653
  const options = field.options || [];
18311
20654
  const selected = Array.isArray(value) ? value : [];
18312
20655
  const toggle = (optValue) => {
@@ -18423,8 +20766,8 @@ function DocGlyph({ color }) {
18423
20766
  }
18424
20767
  function FileUploadField({ field, value, onChange, disabled, onFileUpload, error, dense }) {
18425
20768
  const { MUTED: MUTED2, ACCENT: ACCENT2, BORDER: BORDER4, PAPER: PAPER2 } = useTheme();
18426
- const keyRef = React41__default.default.useRef(0);
18427
- const [entries, setEntries] = React41.useState(() => {
20769
+ const keyRef = React45__default.default.useRef(0);
20770
+ const [entries, setEntries] = React45.useState(() => {
18428
20771
  const arr = Array.isArray(value) ? value : value && typeof value === "object" ? [value] : [];
18429
20772
  return arr.map((item) => {
18430
20773
  var _a2, _b;
@@ -18432,11 +20775,11 @@ function FileUploadField({ field, value, onChange, disabled, onFileUpload, error
18432
20775
  return { key: keyRef.current += 1, name: (_b = (_a2 = r.filename) != null ? _a2 : r.name) != null ? _b : "file", size: r.size, status: "done", result: r };
18433
20776
  });
18434
20777
  });
18435
- const entriesRef = React41__default.default.useRef(entries);
20778
+ const entriesRef = React45__default.default.useRef(entries);
18436
20779
  entriesRef.current = entries;
18437
- const [dragOver, setDragOver] = React41.useState(false);
18438
- const inputRef = React41__default.default.useRef(null);
18439
- React41__default.default.useEffect(() => {
20780
+ const [dragOver, setDragOver] = React45.useState(false);
20781
+ const inputRef = React45__default.default.useRef(null);
20782
+ React45__default.default.useEffect(() => {
18440
20783
  ensureFileUploadKeyframes();
18441
20784
  }, []);
18442
20785
  const interactive = !disabled;
@@ -18567,24 +20910,24 @@ function EntityPickerField({ field, value, onChange, disabled, error, onEntitySe
18567
20910
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, PAPER: PAPER2 } = useTheme();
18568
20911
  const base = useInputBase();
18569
20912
  const source = field.source || "";
18570
- const [open, setOpen] = React41.useState(false);
18571
- const [query, setQuery] = React41.useState("");
18572
- const [results, setResults] = React41.useState([]);
18573
- const [loading, setLoading] = React41.useState(false);
18574
- const [err, setErr] = React41.useState(null);
18575
- const [hi, setHi] = React41.useState(0);
18576
- const [selectedLabel, setSelectedLabel] = React41.useState(null);
18577
- const [creating, setCreating] = React41.useState(false);
18578
- const [createVals, setCreateVals] = React41.useState({});
18579
- const [createBusy, setCreateBusy] = React41.useState(false);
18580
- const boxRef = React41.useRef(null);
18581
- const seq = React41.useRef(0);
20913
+ const [open, setOpen] = React45.useState(false);
20914
+ const [query, setQuery] = React45.useState("");
20915
+ const [results, setResults] = React45.useState([]);
20916
+ const [loading, setLoading] = React45.useState(false);
20917
+ const [err, setErr] = React45.useState(null);
20918
+ const [hi, setHi] = React45.useState(0);
20919
+ const [selectedLabel, setSelectedLabel] = React45.useState(null);
20920
+ const [creating, setCreating] = React45.useState(false);
20921
+ const [createVals, setCreateVals] = React45.useState({});
20922
+ const [createBusy, setCreateBusy] = React45.useState(false);
20923
+ const boxRef = React45.useRef(null);
20924
+ const seq = React45.useRef(0);
18582
20925
  const allowCreate = !!field.allow_create && !!onEntityCreate;
18583
- const createFields = React41.useMemo(
20926
+ const createFields = React45.useMemo(
18584
20927
  () => field.create_fields && field.create_fields.length ? field.create_fields : [{ name: "name", label: "Name", field_type: "text", required: true, placeholder: "" }],
18585
20928
  [field.create_fields]
18586
20929
  );
18587
- const runSearch = React41.useCallback(
20930
+ const runSearch = React45.useCallback(
18588
20931
  (q) => {
18589
20932
  if (!onEntitySearch || !source) return;
18590
20933
  const my = ++seq.current;
@@ -18606,12 +20949,12 @@ function EntityPickerField({ field, value, onChange, disabled, error, onEntitySe
18606
20949
  },
18607
20950
  [onEntitySearch, source]
18608
20951
  );
18609
- React41.useEffect(() => {
20952
+ React45.useEffect(() => {
18610
20953
  if (!open || creating) return;
18611
20954
  const id = setTimeout(() => runSearch(query), 200);
18612
20955
  return () => clearTimeout(id);
18613
20956
  }, [open, creating, query, runSearch]);
18614
- React41.useEffect(() => {
20957
+ React45.useEffect(() => {
18615
20958
  if (!open) return;
18616
20959
  const onDoc = (e) => {
18617
20960
  if (boxRef.current && !boxRef.current.contains(e.target)) {
@@ -18626,7 +20969,7 @@ function EntityPickerField({ field, value, onChange, disabled, error, onEntitySe
18626
20969
  if (disabled) return;
18627
20970
  setOpen(true);
18628
20971
  };
18629
- const select = React41.useCallback((opt) => {
20972
+ const select = React45.useCallback((opt) => {
18630
20973
  onChange({ value: opt.value, label: opt.label });
18631
20974
  setSelectedLabel(opt.label);
18632
20975
  setQuery("");
@@ -18640,14 +20983,14 @@ function EntityPickerField({ field, value, onChange, disabled, error, onEntitySe
18640
20983
  const otherRequired = createFields.filter((f) => f !== nameField && f.required);
18641
20984
  const showCreateRow = allowCreate && !creating && query.trim().length > 0;
18642
20985
  const totalRows = results.length + (showCreateRow ? 1 : 0);
18643
- const beginCreate = React41.useCallback(() => {
20986
+ const beginCreate = React45.useCallback(() => {
18644
20987
  const init = {};
18645
20988
  if (nameField && query.trim()) init[nameField.name] = query.trim();
18646
20989
  setCreateVals(init);
18647
20990
  setErr(null);
18648
20991
  setCreating(true);
18649
20992
  }, [nameField, query]);
18650
- const submitCreate = React41.useCallback((vals) => {
20993
+ const submitCreate = React45.useCallback((vals) => {
18651
20994
  if (!onEntityCreate || !source) return;
18652
20995
  const payload = vals || createVals;
18653
20996
  for (const f of createFields) {
@@ -18660,7 +21003,7 @@ function EntityPickerField({ field, value, onChange, disabled, error, onEntitySe
18660
21003
  setErr(null);
18661
21004
  onEntityCreate(source, payload).then((opt) => select(opt)).catch(() => setErr("Couldn't create \u2014 you may not have permission")).finally(() => setCreateBusy(false));
18662
21005
  }, [onEntityCreate, source, createFields, createVals, select]);
18663
- const handleCreateRow = React41.useCallback(() => {
21006
+ const handleCreateRow = React45.useCallback(() => {
18664
21007
  const q = query.trim();
18665
21008
  if (!q || !nameField) return;
18666
21009
  if (otherRequired.length === 0) {
@@ -18842,11 +21185,11 @@ function _fileExt(path, type) {
18842
21185
  function FileMapField({ field, value, onChange, disabled }) {
18843
21186
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, PAPER: PAPER2 } = useTheme();
18844
21187
  const cfg = field.file_map || null;
18845
- const categories = React41.useMemo(() => (cfg == null ? void 0 : cfg.categories) || [], [cfg]);
18846
- const fileList = React41.useMemo(() => (cfg == null ? void 0 : cfg.files) || [], [cfg]);
21188
+ const categories = React45.useMemo(() => (cfg == null ? void 0 : cfg.categories) || [], [cfg]);
21189
+ const fileList = React45.useMemo(() => (cfg == null ? void 0 : cfg.files) || [], [cfg]);
18847
21190
  const suggestions = (cfg == null ? void 0 : cfg.suggestions) || {};
18848
21191
  const confidence = (cfg == null ? void 0 : cfg.confidence) || {};
18849
- const initial = React41.useMemo(() => {
21192
+ const initial = React45.useMemo(() => {
18850
21193
  const a = {};
18851
21194
  if (value && typeof value === "object" && !Array.isArray(value)) {
18852
21195
  for (const [grp, paths] of Object.entries(value))
@@ -18858,15 +21201,15 @@ function FileMapField({ field, value, onChange, disabled }) {
18858
21201
  for (const f of fileList) if (!(f.path in a)) a[f.path] = _FILEMAP_UNASSIGNED;
18859
21202
  return a;
18860
21203
  }, []);
18861
- const [assignment, setAssignment] = React41.useState(initial);
18862
- const [collapsed, setCollapsed] = React41.useState({});
18863
- const [menuFor, setMenuFor] = React41.useState(null);
18864
- const boardRef = React41.useRef(null);
18865
- const fileByPath = React41.useMemo(
21204
+ const [assignment, setAssignment] = React45.useState(initial);
21205
+ const [collapsed, setCollapsed] = React45.useState({});
21206
+ const [menuFor, setMenuFor] = React45.useState(null);
21207
+ const boardRef = React45.useRef(null);
21208
+ const fileByPath = React45.useMemo(
18866
21209
  () => Object.fromEntries(fileList.map((f) => [f.path, f])),
18867
21210
  [fileList]
18868
21211
  );
18869
- const groupFrom = React41.useCallback((a) => {
21212
+ const groupFrom = React45.useCallback((a) => {
18870
21213
  const g = { [_FILEMAP_UNASSIGNED]: [] };
18871
21214
  for (const c of categories) g[c.id] = [];
18872
21215
  for (const f of fileList) {
@@ -18876,16 +21219,16 @@ function FileMapField({ field, value, onChange, disabled }) {
18876
21219
  }
18877
21220
  return g;
18878
21221
  }, [categories, fileList]);
18879
- const grouped = React41.useMemo(() => groupFrom(assignment), [assignment, groupFrom]);
18880
- const emit = React41.useCallback((g) => onChange(g), [onChange]);
18881
- const emittedRef = React41.useRef(false);
18882
- React41.useEffect(() => {
21222
+ const grouped = React45.useMemo(() => groupFrom(assignment), [assignment, groupFrom]);
21223
+ const emit = React45.useCallback((g) => onChange(g), [onChange]);
21224
+ const emittedRef = React45.useRef(false);
21225
+ React45.useEffect(() => {
18883
21226
  if (!emittedRef.current) {
18884
21227
  emittedRef.current = true;
18885
21228
  emit(grouped);
18886
21229
  }
18887
21230
  }, [grouped, emit]);
18888
- React41.useEffect(() => {
21231
+ React45.useEffect(() => {
18889
21232
  if (!menuFor) return;
18890
21233
  const onDoc = (e) => {
18891
21234
  if (boardRef.current && !boardRef.current.contains(e.target)) setMenuFor(null);
@@ -18893,7 +21236,7 @@ function FileMapField({ field, value, onChange, disabled }) {
18893
21236
  document.addEventListener("mousedown", onDoc);
18894
21237
  return () => document.removeEventListener("mousedown", onDoc);
18895
21238
  }, [menuFor]);
18896
- const move = React41.useCallback((path, grp) => {
21239
+ const move = React45.useCallback((path, grp) => {
18897
21240
  setMenuFor(null);
18898
21241
  setAssignment((prev) => {
18899
21242
  const next = __spreadProps(__spreadValues({}, prev), { [path]: grp });
@@ -19043,7 +21386,7 @@ function FieldRenderer({ field, value, onChange, disabled, error, onFileUpload,
19043
21386
  ] });
19044
21387
  }
19045
21388
  init_ThemeContext();
19046
- var SlotErrorBoundary = class extends React41__default.default.Component {
21389
+ var SlotErrorBoundary = class extends React45__default.default.Component {
19047
21390
  constructor(props) {
19048
21391
  super(props);
19049
21392
  this.state = { hasError: false };
@@ -19128,7 +21471,7 @@ function BuilderRecap({ builder, state }) {
19128
21471
  return String(value);
19129
21472
  };
19130
21473
  const decisionField = (b) => (b.fields || []).find((f) => f.field_type === "select") || (b.fields || [])[0];
19131
- const rows = React41.useMemo(
21474
+ const rows = React45.useMemo(
19132
21475
  () => blocks.map((b) => {
19133
21476
  const df = decisionField(b);
19134
21477
  const decision = df ? display(df, state.getValue(b.id, df.name)) : "";
@@ -19138,7 +21481,7 @@ function BuilderRecap({ builder, state }) {
19138
21481
  // eslint-disable-next-line react-hooks/exhaustive-deps
19139
21482
  [blocks, state.values]
19140
21483
  );
19141
- const counts = React41.useMemo(() => {
21484
+ const counts = React45.useMemo(() => {
19142
21485
  const m = /* @__PURE__ */ new Map();
19143
21486
  for (const r of rows) {
19144
21487
  const k = r.decision || "\u2014";
@@ -19276,7 +21619,7 @@ function isRequiredMissing(fieldType, v) {
19276
21619
  }
19277
21620
  function useBuilderState(blocks) {
19278
21621
  const isMultiBlock = blocks.length > 1;
19279
- const [values, setValues] = React41.useState(() => {
21622
+ const [values, setValues] = React45.useState(() => {
19280
21623
  const init = {};
19281
21624
  for (const block of blocks) {
19282
21625
  for (const field of block.fields || []) {
@@ -19285,17 +21628,17 @@ function useBuilderState(blocks) {
19285
21628
  }
19286
21629
  return init;
19287
21630
  });
19288
- const [errors, setErrors] = React41.useState({});
19289
- const [currentBlock, setCurrentBlock] = React41.useState(0);
19290
- const getValue = React41.useCallback(
21631
+ const [errors, setErrors] = React45.useState({});
21632
+ const [currentBlock, setCurrentBlock] = React45.useState(0);
21633
+ const getValue = React45.useCallback(
19291
21634
  (blockId, name) => values[fieldKey(blockId, name)],
19292
21635
  [values]
19293
21636
  );
19294
- const getError = React41.useCallback(
21637
+ const getError = React45.useCallback(
19295
21638
  (blockId, name) => errors[fieldKey(blockId, name)],
19296
21639
  [errors]
19297
21640
  );
19298
- const setFieldValue = React41.useCallback((blockId, name, value) => {
21641
+ const setFieldValue = React45.useCallback((blockId, name, value) => {
19299
21642
  const k = fieldKey(blockId, name);
19300
21643
  setValues((prev) => __spreadProps(__spreadValues({}, prev), { [k]: value }));
19301
21644
  setErrors((prev) => {
@@ -19305,7 +21648,7 @@ function useBuilderState(blocks) {
19305
21648
  return next;
19306
21649
  });
19307
21650
  }, []);
19308
- const validateBlock = React41.useCallback(
21651
+ const validateBlock = React45.useCallback(
19309
21652
  (blockIdx) => {
19310
21653
  const block = blocks[blockIdx];
19311
21654
  if (!block) return true;
@@ -19339,7 +21682,7 @@ function useBuilderState(blocks) {
19339
21682
  },
19340
21683
  [blocks, values]
19341
21684
  );
19342
- const validateAllDetailed = React41.useCallback(() => {
21685
+ const validateAllDetailed = React45.useCallback(() => {
19343
21686
  let firstBlockIndex = -1;
19344
21687
  let firstKey = null;
19345
21688
  let firstBlockId = null;
@@ -19367,7 +21710,7 @@ function useBuilderState(blocks) {
19367
21710
  if (firstBlockIndex >= 0) setCurrentBlock(firstBlockIndex);
19368
21711
  return { firstKey, firstBlockId, firstName, firstBlockIndex, failingKeys };
19369
21712
  }, [blocks, values]);
19370
- const validateAll = React41.useCallback(
21713
+ const validateAll = React45.useCallback(
19371
21714
  () => validateAllDetailed().failingKeys.length === 0,
19372
21715
  [validateAllDetailed]
19373
21716
  );
@@ -19400,7 +21743,7 @@ function BlockForm({
19400
21743
  }) {
19401
21744
  var _a2;
19402
21745
  const t = useTheme();
19403
- const S4 = React41.useMemo(() => makeStyles(t), [t]);
21746
+ const S4 = React45.useMemo(() => makeStyles(t), [t]);
19404
21747
  const block = builder.blocks[0];
19405
21748
  const isEscalation = variant === "escalation";
19406
21749
  const errorCount = ((block == null ? void 0 : block.fields) || []).reduce(
@@ -19541,7 +21884,7 @@ init_ThemeContext();
19541
21884
  function StepperBuilder({ builder, state, onSubmit, onCancel, disabled, onFileUpload, onEntitySearch, onEntityCreate, dense }) {
19542
21885
  var _a2;
19543
21886
  const t = useTheme();
19544
- const S4 = React41.useMemo(() => makeStyles2(t), [t]);
21887
+ const S4 = React45.useMemo(() => makeStyles2(t), [t]);
19545
21888
  const { blocks } = builder;
19546
21889
  const total = blocks.length;
19547
21890
  const idx = Math.min(Math.max(state.currentBlock, 0), Math.max(total - 1, 0));
@@ -19740,7 +22083,7 @@ function BuilderFormResolver({
19740
22083
  `[BuilderForm] builder "${builder.builder_id}" declared builder_kind="${declaredKind}" with ${blockCount} blocks; rendering as stepper to avoid dropping blocks.`
19741
22084
  );
19742
22085
  }
19743
- const buildSubmission = React41.useCallback(() => {
22086
+ const buildSubmission = React45.useCallback(() => {
19744
22087
  const blocks = (builder.blocks || []).map((b) => ({
19745
22088
  id: b.id,
19746
22089
  title: b.title,
@@ -19752,7 +22095,7 @@ function BuilderFormResolver({
19752
22095
  blocks
19753
22096
  }, blocks.length === 1 ? { values: blocks[0].values } : {});
19754
22097
  }, [builder, kind, state.getValue]);
19755
- const handleSubmit = React41.useCallback(() => {
22098
+ const handleSubmit = React45.useCallback(() => {
19756
22099
  if (disabled) return;
19757
22100
  const failure = state.validateAllDetailed();
19758
22101
  if (failure.failingKeys.length > 0) {
@@ -19761,11 +22104,15 @@ function BuilderFormResolver({
19761
22104
  }
19762
22105
  onSubmit(buildSubmission());
19763
22106
  }, [disabled, state.validateAllDetailed, onSubmit, buildSubmission, onValidationError]);
19764
- React41.useEffect(() => {
19765
- if (!onChange) return;
19766
- onChange(buildSubmission());
19767
- }, [onChange, state.values]);
19768
- React41.useEffect(() => {
22107
+ const onChangeRef = React45.useRef(onChange);
22108
+ React45.useEffect(() => {
22109
+ onChangeRef.current = onChange;
22110
+ });
22111
+ React45.useEffect(() => {
22112
+ var _a3;
22113
+ (_a3 = onChangeRef.current) == null ? void 0 : _a3.call(onChangeRef, buildSubmission());
22114
+ }, [state.values]);
22115
+ React45.useEffect(() => {
19769
22116
  if (!submitRef) return;
19770
22117
  submitRef.current = handleSubmit;
19771
22118
  return () => {
@@ -19824,7 +22171,7 @@ function BuilderFormResolver({
19824
22171
  }
19825
22172
  }
19826
22173
  function resolveBuilder(payload, callbacks) {
19827
- return React41__default.default.createElement(BuilderFormResolver, __spreadValues({
22174
+ return React45__default.default.createElement(BuilderFormResolver, __spreadValues({
19828
22175
  builder: payload
19829
22176
  }, callbacks));
19830
22177
  }
@@ -19846,9 +22193,15 @@ exports.ComponentActions = ComponentActions;
19846
22193
  exports.ContextSlot = ContextSlot;
19847
22194
  exports.DEFAULT_INTERACTION = DEFAULT_INTERACTION;
19848
22195
  exports.DataTableResolver = DataTableResolver;
22196
+ exports.DecisionCardRenderer = DecisionCardRenderer;
22197
+ exports.DecisionCardResolver = DecisionCardResolver;
22198
+ exports.DocumentFieldExtractionResolver = DocumentFieldExtractionResolver;
22199
+ exports.DocumentFieldExtractionSkeleton = DocumentFieldExtractionSkeleton;
19849
22200
  exports.DocumentPreviewResolver = DocumentPreviewResolver;
19850
22201
  exports.EngagementPipelineResolver = EngagementPipelineResolver;
19851
22202
  exports.FIELD_REGISTRY = FIELD_REGISTRY;
22203
+ exports.FieldAuditLog = FieldAuditLog;
22204
+ exports.FieldDetails = FieldDetails;
19852
22205
  exports.FieldRenderer = FieldRenderer;
19853
22206
  exports.FileCard = FileCard;
19854
22207
  exports.FitText = FitText;